diff --git a/diana.py b/diana.py
--- a/diana.py
+++ b/diana.py
@@ -5,9 +5,9 @@ import os
 import sgf
 
 if len(sys.argv)>1:
-  files=sys.argv[1:]
+	files=sys.argv[1:]
 else:
-  sys.exit("no input file specified")
+	sys.exit("no input file specified")
 
 movesPerDiagram=75
 minMovesPerDiagram=10
@@ -18,190 +18,190 @@ padding=15
 highNumbers=True
 
 class Svg:
-  content=""
-  footer=""
-  extension="svg"
+	content=""
+	footer=""
+	extension="svg"
 
-  padding=15
-  gridSize=28
-  highNumbers=True
-  
-  def __init__(self):
-    self.content='''<?xml version="1.0" standalone="no"?>
+	padding=15
+	gridSize=28
+	highNumbers=True
+	
+	def __init__(self):
+		self.content='''<?xml version="1.0" standalone="no"?>
 <svg width="{0}" height="{0}" version="1.1" xmlns="http://www.w3.org/2000/svg" alignment-baseline="center">
-  <defs>
-    <style type="text/css"><![CDATA[
-    text{{font-family:"DejaVu Sans";text-anchor:middle;}}
-    line{{stroke:black;stroke-width:0.7}}
-    circle{{stroke:black}}
-    .b{{fill:black}}
-    .w{{fill:white}}
-    ]]></style>
-  </defs>
-  <rect width="{0}" height="{0}" x="0" y="0" style="fill:white;stroke:white"/>\n'''.format(2*self.padding+18*self.gridSize)
-    self.footer="</svg>\n"
+	<defs>
+		<style type="text/css"><![CDATA[
+		text{{font-family:"DejaVu Sans";text-anchor:middle;}}
+		line{{stroke:black;stroke-width:0.7}}
+		circle{{stroke:black}}
+		.b{{fill:black}}
+		.w{{fill:white}}
+		]]></style>
+	</defs>
+	<rect width="{0}" height="{0}" x="0" y="0" style="fill:white;stroke:white"/>\n'''.format(2*self.padding+18*self.gridSize)
+		self.footer="</svg>\n"
 
-    grid='  <line x1="{0}" x2="{1}" y1="{2}" y2="{3}" />\n'
+		grid='  <line x1="{0}" x2="{1}" y1="{2}" y2="{3}" />\n'
 
-    # okraje desky
-    for i in (0,18):
-      self.content+='  <line x1="{0}" x2="{1}" y1="{2}" y2="{3}" style="stroke-width:1"/>\n'.format(self.padding, 18*self.gridSize+self.padding, self.gridSize*i+self.padding, self.gridSize*i+self.padding)
-      self.content+='  <line x1="{0}" x2="{1}" y1="{2}" y2="{3}" style="stroke-width:1"/>\n'.format(self.gridSize*i+self.padding, self.gridSize*i+self.padding, self.padding, 18*self.gridSize+self.padding)
-    
-    # mřížka
-    for i in range(1,18):
-      self.content+=grid.format(padding, 18*c+padding, c*i+padding, c*i+padding)
-      self.content+=grid.format(c*i+padding, c*i+padding, padding, 18*c+padding)
+		# okraje desky
+		for i in (0,18):
+			self.content+='  <line x1="{0}" x2="{1}" y1="{2}" y2="{3}" style="stroke-width:1"/>\n'.format(self.padding, 18*self.gridSize+self.padding, self.gridSize*i+self.padding, self.gridSize*i+self.padding)
+			self.content+='  <line x1="{0}" x2="{1}" y1="{2}" y2="{3}" style="stroke-width:1"/>\n'.format(self.gridSize*i+self.padding, self.gridSize*i+self.padding, self.padding, 18*self.gridSize+self.padding)
+		
+		# mřížka
+		for i in range(1,18):
+			self.content+=grid.format(padding, 18*c+padding, c*i+padding, c*i+padding)
+			self.content+=grid.format(c*i+padding, c*i+padding, padding, 18*c+padding)
 
-    # hvězdy
-    for i in range(3):
-      for j in range(3):
-        self.content+='  <circle cx="{0}" cy="{1}" r="{2}" class="b"/>\n'.format(padding+3*c+6*i*c, padding+3*c+6*j*c, 2)
-  
-  def __str__(self):
-    return self.content+self.footer
-          
-  def drawStone(self,x,y,color):
-    self.content+='  <circle cx="{0}" cy="{1}" r="{2}" class="{3}" />\n'.format(padding+x*c, padding+y*c, c/2-1, color)
+		# hvězdy
+		for i in range(3):
+			for j in range(3):
+				self.content+='  <circle cx="{0}" cy="{1}" r="{2}" class="b"/>\n'.format(padding+3*c+6*i*c, padding+3*c+6*j*c, 2)
+	
+	def __str__(self):
+		return self.content+self.footer
+					
+	def drawStone(self,x,y,color):
+		self.content+='  <circle cx="{0}" cy="{1}" r="{2}" class="{3}" />\n'.format(padding+x*c, padding+y*c, c/2-1, color)
 
-  def getFontSize(self,text):
-    if len(text)<2: return round(0.7*c)
-    elif len(text)<3: return round(0.55*c)
-    else: return round(0.4*c)
+	def getFontSize(self,text):
+		if len(text)<2: return round(0.7*c)
+		elif len(text)<3: return round(0.55*c)
+		else: return round(0.4*c)
 
-  def writeLabel(self,x,y,label,color):
-    label=str(label)
-    fontSize=self.getFontSize(label)
-    self.content+='  <text x="{0}" y="{1}" class="{2}" font-size="{3}">{4}</text>\n'.format(padding+x*c, padding+y*c+0.35*fontSize, color, fontSize, label)
-    
-  def drawMove(self,x,y,label,color):
-    labelColor="w" if color=="b" else "b"
-    
-    if (not self.highNumbers) and isinstance(label,int) and label%100!=0: label=label%100 # dost neobratná logika
-    
-    self.drawStone(x,y,color)
-    self.writeLabel(x,y,label,labelColor)
-    
-  def getContent(self):
-    return self.content+self.footer
+	def writeLabel(self,x,y,label,color):
+		label=str(label)
+		fontSize=self.getFontSize(label)
+		self.content+='  <text x="{0}" y="{1}" class="{2}" font-size="{3}">{4}</text>\n'.format(padding+x*c, padding+y*c+0.35*fontSize, color, fontSize, label)
+		
+	def drawMove(self,x,y,label,color):
+		labelColor="w" if color=="b" else "b"
+		
+		if (not self.highNumbers) and isinstance(label,int) and label%100!=0: label=label%100 # dost neobratná logika
+		
+		self.drawStone(x,y,color)
+		self.writeLabel(x,y,label,labelColor)
+		
+	def getContent(self):
+		return self.content+self.footer
 
 
 class Tikz:
-  content=""
-  footer=""
-  extension="tex"
-  
-  highNumbers=True
-  
-  def __init__(self):
-    self.content=r'''\begin{tikzpicture}
-  \draw[step=\boardSquare,gray,very thin] (0,0) grid (18\boardSquare,18\boardSquare);
-  \draw (0,0) rectangle (18\boardSquare,18\boardSquare);
-  
-  '''
-    
-    # hvězdy
-    for i in range(3):
-      for j in range(3):
-        self.content+=r'''  \filldraw[fill=black] ({0}\boardSquare,{1}\boardSquare) circle[radius=0.04];'''.format(6*i+3, 6*j+3)+'\n'
-      self.content+='\n'
-  
-    self.footer=r'\end{tikzpicture}' '\n'
-      
-  def __str__(self):
-    return self.content+self.footer
+	content=""
+	footer=""
+	extension="tex"
+	
+	highNumbers=True
+	
+	def __init__(self):
+		self.content=r'''\begin{tikzpicture}
+	\draw[step=\boardSquare,gray,very thin] (0,0) grid (18\boardSquare,18\boardSquare);
+	\draw (0,0) rectangle (18\boardSquare,18\boardSquare);
+	
+	'''
+		
+		# hvězdy
+		for i in range(3):
+			for j in range(3):
+				self.content+=r'''  \filldraw[fill=black] ({0}\boardSquare,{1}\boardSquare) circle[radius=0.04];'''.format(6*i+3, 6*j+3)+'\n'
+			self.content+='\n'
+	
+		self.footer=r'\end{tikzpicture}' '\n'
+			
+	def __str__(self):
+		return self.content+self.footer
 
-  def drawStone(self,x,y,color):
-    fill="black" if color=="b" else "white"
-    self.content+=r'  \filldraw[draw=black,fill={0}] ({1}\boardSquare,{2}\boardSquare) circle[radius=0.5\boardSquare];'.format(fill,x,18-y)+'\n'
-  
-  def drawMove(self,x,y,label,color):
-    fill="black" if color=="b" else "white"
-    labelColor="white" if color=="b" else "black"
-    if (not self.highNumbers) and isinstance(label,int) and label%100!=0: label=label%100 # dost neobratná logika
-    
-    self.content+=r'  \filldraw[draw=black,fill={0}] ({1}\boardSquare,{2}\boardSquare) circle[radius=0.5\boardSquare] node[color={3}]{{{4}}};'.format(fill,x,18-y,labelColor,label)+'\n'
-    
-  def getContent(self):
-    return self.content+self.footer
+	def drawStone(self,x,y,color):
+		fill="black" if color=="b" else "white"
+		self.content+=r'  \filldraw[draw=black,fill={0}] ({1}\boardSquare,{2}\boardSquare) circle[radius=0.5\boardSquare];'.format(fill,x,18-y)+'\n'
+	
+	def drawMove(self,x,y,label,color):
+		fill="black" if color=="b" else "white"
+		labelColor="white" if color=="b" else "black"
+		if (not self.highNumbers) and isinstance(label,int) and label%100!=0: label=label%100 # dost neobratná logika
+		
+		self.content+=r'  \filldraw[draw=black,fill={0}] ({1}\boardSquare,{2}\boardSquare) circle[radius=0.5\boardSquare] node[color={3}]{{{4}}};'.format(fill,x,18-y,labelColor,label)+'\n'
+		
+	def getContent(self):
+		return self.content+self.footer
 
 
 def processFile(fileName):
-  shortName="".join(re.split(r'[/\\]',fileName)[-1].split('.')[:-1])
-  
-  game=go.Go()
-  global t
-  
-  record=sgf.Sgf(open(fileName,'r',encoding="utf-8").read())
-  moves=record.getMoves()
+	shortName="".join(re.split(r'[/\\]',fileName)[-1].split('.')[:-1])
+	
+	game=go.Go()
+	global t
+	
+	record=sgf.Sgf(open(fileName,'r',encoding="utf-8").read())
+	moves=record.getMoves()
 
-  localBoard=dict()
-  overlays=""
-  letters=dict()
-  letter='a'
+	localBoard=dict()
+	overlays=""
+	letters=dict()
+	letter='a'
 
-  diagramsNeeded=(len(moves)-minMovesPerDiagram)//movesPerDiagram+1
-  moveNumber=0
-  
-  for i in range(diagramsNeeded):
-    # inicializuj diagram
-    diagram=Tikz()
-    
-    for lineNumber,line in enumerate(game.board):
-      for itemNumber,item in enumerate(line):
-        if item==1: diagram.drawStone(itemNumber,lineNumber,"b")
-        if item==-1: diagram.drawStone(itemNumber,lineNumber,"w")
-      localBoard={(a,b):game.board[b][a]-1 for a in range(19) for b in range(19) if game.board[b][a]!=0}
-    
-    for j in range(movesPerDiagram):
-      # kresli tahy
-      if moveNumber>=len(moves): break
-      
-      c,(x,y)=moves[moveNumber]
-      c=c.lower()
-      
-      if not game.move(1 if c=='b' else -1,x,y):
-        print("illegal move: {0} at {1},{2}".format(moveNumber+1,x,y))
-        moveNumber+=1
-        continue
-      
-      # zapíšu tah na volný průsečík
-      if not (x,y) in localBoard:
-        localBoard[(x,y)]=moveNumber+1
-        diagram.drawMove(x,y,moveNumber+1,c)
-      # průsečík je obsazený nepopsaným kamenem
-      elif localBoard[(x,y)]<1:
-        # průsečík není popsaný ani písmenem
-        if not (x,y) in letters:
-          letters[(x,y)]=letter
-          color='b' if localBoard[(x,y)]==0 else 'w'
-          diagram.drawMove(x,y,letter,color)
-          letter=chr(ord(letter)+1)
-        overlays+="{0} = {1}\n".format(moveNumber+1,letters[(x,y)])
-      # průsečík je obsazený očíslovaným kamenem
-      else: overlays+="{0} = {1}\n".format(moveNumber+1,localBoard[(x,y)])
-      
-      moveNumber+=1
-      
-    # dokonči a ulož diagram
+	diagramsNeeded=(len(moves)-minMovesPerDiagram)//movesPerDiagram+1
+	moveNumber=0
+	
+	for i in range(diagramsNeeded):
+		# inicializuj diagram
+		diagram=Tikz()
+		
+		for lineNumber,line in enumerate(game.board):
+			for itemNumber,item in enumerate(line):
+				if item==1: diagram.drawStone(itemNumber,lineNumber,"b")
+				if item==-1: diagram.drawStone(itemNumber,lineNumber,"w")
+			localBoard={(a,b):game.board[b][a]-1 for a in range(19) for b in range(19) if game.board[b][a]!=0}
+		
+		for j in range(movesPerDiagram):
+			# kresli tahy
+			if moveNumber>=len(moves): break
+			
+			c,(x,y)=moves[moveNumber]
+			c=c.lower()
+			
+			if not game.move(1 if c=='b' else -1,x,y):
+				print("illegal move: {0} at {1},{2}".format(moveNumber+1,x,y))
+				moveNumber+=1
+				continue
+			
+			# zapíšu tah na volný průsečík
+			if not (x,y) in localBoard:
+				localBoard[(x,y)]=moveNumber+1
+				diagram.drawMove(x,y,moveNumber+1,c)
+			# průsečík je obsazený nepopsaným kamenem
+			elif localBoard[(x,y)]<1:
+				# průsečík není popsaný ani písmenem
+				if not (x,y) in letters:
+					letters[(x,y)]=letter
+					color='b' if localBoard[(x,y)]==0 else 'w'
+					diagram.drawMove(x,y,letter,color)
+					letter=chr(ord(letter)+1)
+				overlays+="{0} = {1}\n".format(moveNumber+1,letters[(x,y)])
+			# průsečík je obsazený očíslovaným kamenem
+			else: overlays+="{0} = {1}\n".format(moveNumber+1,localBoard[(x,y)])
+			
+			moveNumber+=1
+			
+		# dokonči a ulož diagram
 	# TODO rozumně pracovat s adresáři
-    t=open(os.path.join(os.path.dirname(__file__),"out","{0}-{1}.{2}".format(shortName,i+1,diagram.extension)),'w') # nový soubor
-    t.write(diagram.getContent())
-    t.close()
-      
-  notes=open(os.path.join(os.path.dirname(__file__),"out","{0}.txt".format(shortName)),'w')
-  notes.write(overlays)
-  notes.close()
-  
+		t=open(os.path.join(os.path.dirname(__file__),"out","{0}-{1}.{2}".format(shortName,i+1,diagram.extension)),'w') # nový soubor
+		t.write(diagram.getContent())
+		t.close()
+			
+	notes=open(os.path.join(os.path.dirname(__file__),"out","{0}.txt".format(shortName)),'w')
+	notes.write(overlays)
+	notes.close()
+	
 print("processing:")
 for item in files:
-  # relativně vůči work directory nebo vůči skriptu?
-  # item=os.path.join(os.path.dirname(__file__),item)
-  if os.path.isfile(item):
-    print("{0}... ".format(item),end="")
-    processFile(item)
-    print("done")
-  elif os.path.isdir(item):
-    files+=[os.path.join(item,child) for child in os.listdir(item)]
-    print("contents of the '{0}' directory added to the queue".format(item))
-  else: print("the '{0}' path could not be resolved to either a file nor a directory".format(item))
+	# relativně vůči work directory nebo vůči skriptu?
+	# item=os.path.join(os.path.dirname(__file__),item)
+	if os.path.isfile(item):
+		print("{0}... ".format(item),end="")
+		processFile(item)
+		print("done")
+	elif os.path.isdir(item):
+		files+=[os.path.join(item,child) for child in os.listdir(item)]
+		print("contents of the '{0}' directory added to the queue".format(item))
+	else: print("the '{0}' path could not be resolved to either a file nor a directory".format(item))
diff --git a/go.py b/go.py
--- a/go.py
+++ b/go.py
@@ -1,33 +1,33 @@
 class Go:
-  # 1: B, 0: _, -1: W
-  # resp. jakákoli čísla s opačnými znaménky
-  board=[[0]*19 for i in range(19)]
-  
-  def __init__(self): self.board=[[0]*19 for i in range(19)]
-  
-  def move(self,color,y,x):
-    if self.board[x][y]!=0: return False
+	# 1: B, 0: _, -1: W
+	# resp. jakákoli čísla s opačnými znaménky
+	board=[[0]*19 for i in range(19)]
+	
+	def __init__(self): self.board=[[0]*19 for i in range(19)]
+	
+	def move(self,color,y,x):
+		if self.board[x][y]!=0: return False
 
-    self.board[x][y]=color
+		self.board[x][y]=color
 
-    for i,j in ((-1,0),(1,0),(0,-1),(0,1)):
-      self.temp=[[False]*19 for i in range(19)]
-      if not self._floodFill(-color,x+i,y+j): self._remove()
-    self.temp=[[False]*19 for i in range(19)]
-    if not self._floodFill(color,x,y):
-      self.board[x][y]=0
-      return False
-    return True
+		for i,j in ((-1,0),(1,0),(0,-1),(0,1)):
+			self.temp=[[False]*19 for i in range(19)]
+			if not self._floodFill(-color,x+i,y+j): self._remove()
+		self.temp=[[False]*19 for i in range(19)]
+		if not self._floodFill(color,x,y):
+			self.board[x][y]=0
+			return False
+		return True
 
-  def _floodFill(self,color,x,y):
-    if x<0 or x>18 or y<0 or y>18: return False
-    if self.temp[x][y]: return False
-    if self.board[x][y]==0: return True
-    if self.board[x][y]!=color: return False
-    self.temp[x][y]=True
-    return self._floodFill(color,x-1,y) or self._floodFill(color,x+1,y) or self._floodFill(color,x,y-1) or self._floodFill(color,x,y+1)
-  
-  def _remove(self):
-    for i in range(19):
-      for j in range(19):
-        if self.temp[i][j]: self.board[i][j]=0
+	def _floodFill(self,color,x,y):
+		if x<0 or x>18 or y<0 or y>18: return False
+		if self.temp[x][y]: return False
+		if self.board[x][y]==0: return True
+		if self.board[x][y]!=color: return False
+		self.temp[x][y]=True
+		return self._floodFill(color,x-1,y) or self._floodFill(color,x+1,y) or self._floodFill(color,x,y-1) or self._floodFill(color,x,y+1)
+	
+	def _remove(self):
+		for i in range(19):
+			for j in range(19):
+				if self.temp[i][j]: self.board[i][j]=0
diff --git a/sgf-compresor.py b/sgf-compresor.py
deleted file mode 100755
--- a/sgf-compresor.py
+++ /dev/null
@@ -1,124 +0,0 @@
-import re
-import sys
-
-def compressValues(s):
-  vals=[]
-  indicesX=[]
-  for m in re.finditer(r"\[.*?[^\\]\]",s,flags=re.DOTALL):
-    vals.append(m.group(0)[1:-1])
-    indicesX.append(m.span())
-  i=len(indicesX)-1
-  for start,end in reversed(indicesX):
-    s=s[:start+1]+"$"+str(i)+s[end-1:]
-    i-=1
-  return s,vals
-
-s=open("c:/Users/Laman/Documents/go/EuroGoTV1-x.sgf",encoding="utf8").read()
-s,d=compressValues(s)
-
-print(s)
-print(d[:20])
-
-sys.exit(0)
-
-# # #
-
-# http://en.wikipedia.org/wiki/Recursive_descent_parser
-
-# # #
-
-import collections
-import re
-
-Token = collections.namedtuple('Token', ['typ', 'value'])
-
-def tokenize(s):
-    keywords = {'IF', 'THEN', 'ENDIF', 'FOR', 'NEXT', 'GOSUB', 'RETURN'}
-    token_specification = [
-        ('PROPID',r'[A-Z]+'), 
-        ('PROPVAL',r'\[\$\d+\]'),  
-        ('NODE',r';'),      
-        ('LPARENTHESIS',r'\('),
-        ('RPARENTHESIS',r'\)'),
-        ('SKIP',r'\s')
-    ]
-    tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification)
-    get_token = re.compile(tok_regex).match
-    line = 1
-    pos = line_start = 0
-    mo = get_token(s)
-    while mo is not None:
-        typ = mo.lastgroup
-        if typ == 'NEWLINE':
-            line_start = pos
-            line += 1
-        elif typ != 'SKIP':
-            val = mo.group(typ)
-            if typ == 'ID' and val in keywords:
-                typ = val
-            yield Token(typ, val, line, mo.start()-line_start)
-        pos = mo.end()
-        mo = get_token(s, pos)
-    if pos != len(s):
-        raise RuntimeError('Unexpected character %r on line %d' %(s[pos], line))
-
-statements = '''
-    IF quantity THEN
-        total := total + price * quantity;
-        tax := price * 0.05;
-    ENDIF;
-'''
-
-for token in tokenize(statements):
-    print(token)
-
-tokens=["list of tokens"]
-i=0
-sym
-    
-def getSym():
-  sym=token[i]
-  i+=1
-  
-def accept(s):
-  if sym==s:
-    getSym()
-    return True
-  else:
-    return False
-    
-def expect(s):
-  if accept(s):
-    return True
-  else:
-    pass # error
-    return False
-
-def propValue():
-  if accept(lbracket) and cValueType() and expect(rbracket):
-    pass
-  else:
-    pass # error
-  
-def propIdent():
-  accept(ident)
-  
-def propertyX():
-  propIdent()
-  while propValue(): pass
-
-def node():
-  accept(semicolon)
-  propertyX()
-
-def sequence():
-  while node(): pass
-
-def gameTree():
-  accept(lparenthesis)
-  sequence()
-  while gameTree(): pass
-  expect(rparenthesis)
-
-def collection():
-  while gameTree(): pass
\ No newline at end of file
diff --git a/sgf.py b/sgf.py
--- a/sgf.py
+++ b/sgf.py
@@ -2,493 +2,493 @@
 
 
 class Collection:
-  gameTrees=[]
-  
-  def export(self):
-    res=""
-    for root in gameTrees:
-      res+="({0})\n".format(root.fullExport())
-    return res
-  
+	gameTrees=[]
+	
+	def export(self):
+		res=""
+		for root in gameTrees:
+			res+="({0})\n".format(root.fullExport())
+		return res
+	
 class Node:
-  parent=None
-  children=[]
-  properties={}
-  
-  def newChild(self):
-    child=Node()
-    child.parent=self
-    self.children.append(child)
-    return child
-    
-  def addChild(self,child):
-    child.parent=self
-    self.children.append(child)
-    
-  def delChild(self,index):
-    del self.children[index]
-    
-  def setProperty(self): pass
-  def getProperty(self): pass
-  
-  def fullExport(self):
-    res=self.export()
-    if len(self.children)==1: res+=children[0].fullExport()
-    else:
-      for child in self.children:
-        res+=child.fullExport()
-    return res
-      
-  def export(self):
-    res=";"
-    for name,value in properties.items():
-      res+="{0}[{1}]".format(name,value) # !! str(value)
-    res+="\n"
-    return res
-    
+	parent=None
+	children=[]
+	properties={}
+	
+	def newChild(self):
+		child=Node()
+		child.parent=self
+		self.children.append(child)
+		return child
+		
+	def addChild(self,child):
+		child.parent=self
+		self.children.append(child)
+		
+	def delChild(self,index):
+		del self.children[index]
+		
+	def setProperty(self): pass
+	def getProperty(self): pass
+	
+	def fullExport(self):
+		res=self.export()
+		if len(self.children)==1: res+=children[0].fullExport()
+		else:
+			for child in self.children:
+				res+=child.fullExport()
+		return res
+			
+	def export(self):
+		res=";"
+		for name,value in properties.items():
+			res+="{0}[{1}]".format(name,value) # !! str(value)
+		res+="\n"
+		return res
+		
 class Property:
-  name=""
-  value=None
+	name=""
+	value=None
 
 class ListOf(Property):
-  values=[]
-  vType=None
+	values=[]
+	vType=None
 
-  def __str__(self):
-    return "["+"][".join(self.values)+"]"
-    
+	def __str__(self):
+		return "["+"][".join(self.values)+"]"
+		
 class Composed(Property):
-  value=()
-  
-  def __str__(self):
-    return self.value[0]+":"+self.value[1] # !! str(self.value[0])
+	value=()
+	
+	def __str__(self):
+		return self.value[0]+":"+self.value[1] # !! str(self.value[0])
 
 class Point(Property): # !! pass
-  row=0
-  col=0
-  
-  def __str__(self):
-    f=lambda x: chr(x+ord("a")) if x<26 else chr(x-26+ord("A"))
-    row=f(self.row)
-    col=f(self.col)
-    
-    return col+row
-    
+	row=0
+	col=0
+	
+	def __str__(self):
+		f=lambda x: chr(x+ord("a")) if x<26 else chr(x-26+ord("A"))
+		row=f(self.row)
+		col=f(self.col)
+		
+		return col+row
+		
 
-  
+	
 def skipWhitespace(str,start):
-  i=start
-  while i<len(str) and str[i].isspace(): i+=1
-  return i
+	i=start
+	while i<len(str) and str[i].isspace(): i+=1
+	return i
 
 class Collection:
-  gameTrees=[]
-  
-  def __init__(self,str):
-    self.gameTrees=[]
-    i,x=GameTree.create(str,0)
-    if x is None:
-      print("error when parsing Collection")
-      return
-    while x is not None:
-      self.gameTrees.append(x)
-      i,x=GameTree.create(str,i)
-  
+	gameTrees=[]
+	
+	def __init__(self,str):
+		self.gameTrees=[]
+		i,x=GameTree.create(str,0)
+		if x is None:
+			print("error when parsing Collection")
+			return
+		while x is not None:
+			self.gameTrees.append(x)
+			i,x=GameTree.create(str,i)
+	
 class GameTree:
-  nodes=[]
-  branches=[]
-    
-  def create(str,start):
-    res=GameTree()
-    i=skipWhitespace(str,start)
-    if i>=len(str) or str[i]!="(":
-      # print("error when parsing GameTree")
-      return (start,None)
-    i=skipWhitespace(str,i)
-    i,x=Node.create(str,start+1)
-    if x is None:
-      # print("error when parsing GameTree")
-      return (i,None)
-    while x is not None:
-      res.nodes.append(x)
-      i=skipWhitespace(str,i)
-      i,x=Node.create(str,i)
-    i=skipWhitespace(str,i)
-    i,x=GameTree.create(str,i)
-    while x is not None:
-      res.branches.append(x)
-      i=skipWhitespace(str,i)
-      i,x=GameTree.create(str,i)
-    if str[i]!=")":
-      # print("error when parsing GameTree")
-      return (i,None)
-    return (i+1,res)
-  
+	nodes=[]
+	branches=[]
+		
+	def create(str,start):
+		res=GameTree()
+		i=skipWhitespace(str,start)
+		if i>=len(str) or str[i]!="(":
+			# print("error when parsing GameTree")
+			return (start,None)
+		i=skipWhitespace(str,i)
+		i,x=Node.create(str,start+1)
+		if x is None:
+			# print("error when parsing GameTree")
+			return (i,None)
+		while x is not None:
+			res.nodes.append(x)
+			i=skipWhitespace(str,i)
+			i,x=Node.create(str,i)
+		i=skipWhitespace(str,i)
+		i,x=GameTree.create(str,i)
+		while x is not None:
+			res.branches.append(x)
+			i=skipWhitespace(str,i)
+			i,x=GameTree.create(str,i)
+		if str[i]!=")":
+			# print("error when parsing GameTree")
+			return (i,None)
+		return (i+1,res)
+	
 class Node:
-  properties=dict()
-  
-  def create(str,start):
-    res=Node()
-    if str[start]!=";":
-      # print("error when parsing Node")
-      return (start,None)
-    i=skipWhitespace(str,start+1)
-    i,x=Property.create(str,i)
-    while x is not None:
-      if x.name in res.properties:
-        print('error: duplicate "{0}" property in node at position {1}. second value ignored'.format(x.name,start))
-      else:
-        res.properties[x.name]=x
-      i=skipWhitespace(str,i)
-      i,x=Property.create(str,i)
-    return (i,res)
-    
-  def setProperty(self,name,value):
-    self.properties[name]=value
-    # zkontrolovat typ value
-    
-  def getProperty(self,name):
-    if name in self.properties: return self.properties[name]
-    else: return None
-  
+	properties=dict()
+	
+	def create(str,start):
+		res=Node()
+		if str[start]!=";":
+			# print("error when parsing Node")
+			return (start,None)
+		i=skipWhitespace(str,start+1)
+		i,x=Property.create(str,i)
+		while x is not None:
+			if x.name in res.properties:
+				print('error: duplicate "{0}" property in node at position {1}. second value ignored'.format(x.name,start))
+			else:
+				res.properties[x.name]=x
+			i=skipWhitespace(str,i)
+			i,x=Property.create(str,i)
+		return (i,res)
+		
+	def setProperty(self,name,value):
+		self.properties[name]=value
+		# zkontrolovat typ value
+		
+	def getProperty(self,name):
+		if name in self.properties: return self.properties[name]
+		else: return None
+	
 class Property:
-  name=""
-  value=""
-  
-  def create(str,start):
-    res=Property()
-    i,x=Property.ident(str,start)
-    if x is None:
-      return (start,None)
-    res.name=x
-    i,x=PropValue.create(str,i,res.name)
-    if x is None:
-      print('error when parsing property "{0}" at position {1}'.format(res.name,i))
-      return (start,None)
-    # while x is not None: # přesunuto do PropValue.listOf
-      # res.values.append(x)
-      # i=skipWhitespace(str,i)
-      # i,x=PropValue.create(str,i,res.name)
-    res.values.append(x) # !! podezřelé
-    return (i,res)
-    
-  def ident(str,start):
-    r=re.compile(r"[A-Z]+")
-    m=r.match(str,start)
-    if m is None: return (start,None)
-    return (m.end(),m.group())
+	name=""
+	value=""
+	
+	def create(str,start):
+		res=Property()
+		i,x=Property.ident(str,start)
+		if x is None:
+			return (start,None)
+		res.name=x
+		i,x=PropValue.create(str,i,res.name)
+		if x is None:
+			print('error when parsing property "{0}" at position {1}'.format(res.name,i))
+			return (start,None)
+		# while x is not None: # přesunuto do PropValue.listOf
+			# res.values.append(x)
+			# i=skipWhitespace(str,i)
+			# i,x=PropValue.create(str,i,res.name)
+		res.values.append(x) # !! podezřelé
+		return (i,res)
+		
+	def ident(str,start):
+		r=re.compile(r"[A-Z]+")
+		m=r.match(str,start)
+		if m is None: return (start,None)
+		return (m.end(),m.group())
 
 class PropValue:
-  type=""
-  value=None
-  patterns=dict()
-  
-  def create(str,start,name):
-    if name in PropValue.patterns:
-      return PropValue.patterns[name](str,start)
-    else:
-      print('warning, unknown property "{0}" at position {1}'.format(name,start))
-      return PropValue.singleton(PropValue.anything)(str,start)
-  
-  # def singleton(str,start,vType):
-    # if str[start]!="[":
-      # return (start,None)
-    # i,x=vType(str,start+1)
-    # if x is None: return (start,None)
-    # if str[i]!="]":
-      # return (start,None)
-    # return (i+1,x)
-  
-  def choose(*vTypes):
-    def f(str,start):
-      for vType in vTypes:
-        i,x=vType(str,start)
-        if x is not None: return (i,x)
-      return (start,None)
-    return f
-  
-  def singleton(vType):
-    def f(str,start):
-      if str[start]!="[":
-        return (start,None)
-      i,x=vType(str,start+1)
-      if x is None: return (start,None)
-      if str[i]!="]":
-        return (start,None)
-      return (i+1,x)
-    return f
-    
-  # def listOf(str,start,vType,allowEmpty=False):
-    # res=[]
-    # i,x=singleton(str,start,vType)
-    # # singleton(vType) if vType not tuple else compose(vType[0],vType[1])
-    # while x!=None:
-      # res.append(x)
-      # i,x=singleton(str,i,vType)
-    # if len(res)==0 and not allowEmpty: return (start,None)
-    # return (i,res)
-    
-  def listOf(vType,allowEmpty=False):
-    def f(str,start):
-      res=[]
-      single=singleton(vType)
-      i,x=single(str,start)
-      while x!=None:
-        res.append(x)
-        i,x=single(str,i)
-      if len(res)==0 and not allowEmpty: return (start,None)
-      return (i,res)
-    return f
-    
-  # def compose(str,start,vTypeA,vTypeB):
-    # i,a=vTypeA(str,start)
-    # if a==None or str[i]!=":": return (start,None)
-    # i,b=vTypeB(str,i+1)
-    # if b==None: return start,None
-    # return (i,(a,b))
-    
-  def compose(vTypeA,vTypeB):
-    def f(str,start):
-      i,a=vTypeA(str,start)
-      # print(">",i,a)
-      if a==None or str[i]!=":": return (start,None)
-      i,b=vTypeB(str,i+1)
-      # print(">",i,b)
-      if b==None: return start,None
-      return (i,(a,b))
-    return f
-  
-  def number(str,start):
-    r=re.compile(r"(\+|-|)\d+")
-    m=r.match(str,start)
-    if m is None: return (start,None)
-    res=int(m.group(0))
-    return (m.end(),res)
-    
-  def real(str,start):
-    r=re.compile(r"(\+|-|)\d+(\.\d+)?")
-    m=r.match(str,start)
-    if m is None: return (start,None)
-    res=float(m.group(0))
-    return (m.end(),res)
-    
-  def double(str,start):
-    r=re.compile(r"1|2")
-    m=r.match(str,start)
-    if m is None: return (start,None)
-    res=int(m.group(0))
-    return (m.end(),res)
-  
-  def color(str,start):
-    r=re.compile(r"B|W")
-    m=r.match(str,start)
-    if m is None: return (start,None)
-    return (m.end(),m.group(0))
-    
-  # def simpleText(str,start):
-    # res=""
-    # esc=False
-    # lineBreak=False
-    # for c in str:
-      # if esc:
-        # res+=c
-        # esc=False
-      # elif c=="\\":
-        # esc=True
-      # elif c=="]":
-        # break
-      # else:
-        # res+=c
-    # return res
-  
-  def text(simple=True,composed=False):
-    def f(str,start):
-      res=""
-      esc=False
-      lastC=""
-      for i,c in enumerate(str[start:],start):
-        if esc:
-          if c!="\n" and c!="\r": res+=c
-          esc=False
-        elif (c=="\n" and lastC=="\r") or (c=="\r" and lastC=="\n"): pass
-        elif c=="\r" or c=="\n" and not simple:
-          res+="\n"
-        elif c.isspace():
-          res+=" "
-        elif c=="\\":
-          esc=True
-        elif c=="]" or (c==":" and composed):
-          break
-        else:
-          res+=c
-        lastC=c
-      return (i,res)
-    return f
-    
-  def empty(str,start): return (start,"")
-  
-  def anything(str,start): # přidat listOf
-    esc=False
-    for i,c in enumerate(str[start:],start):
-      if esc: esc=False
-      elif c=="\\": esc=True
-      elif c=="]": break
-    return (i,str[start:i])
-  
-  # go specific
-  def point(str,start):
-    r=re.compile(r"[a-zA-Z]{2}|") # !! limit to board size
-    m=r.match(str,start)
-    if m is None: return (start,None)
-    if m.group(0)=="": # pass, !! tt
-      return (m.end(),tuple())
-    col=m.group(0)[0]
-    row=m.group(0)[1]
-    col=ord(col) - (ord("a") if "a"<=col<="z" else ord("A")-26)
-    row=ord(row) - (ord("a") if "a"<=row<="z" else ord("A")-26)
-    return (m.end(),(col,row))
+	type=""
+	value=None
+	patterns=dict()
+	
+	def create(str,start,name):
+		if name in PropValue.patterns:
+			return PropValue.patterns[name](str,start)
+		else:
+			print('warning, unknown property "{0}" at position {1}'.format(name,start))
+			return PropValue.singleton(PropValue.anything)(str,start)
+	
+	# def singleton(str,start,vType):
+		# if str[start]!="[":
+			# return (start,None)
+		# i,x=vType(str,start+1)
+		# if x is None: return (start,None)
+		# if str[i]!="]":
+			# return (start,None)
+		# return (i+1,x)
+	
+	def choose(*vTypes):
+		def f(str,start):
+			for vType in vTypes:
+				i,x=vType(str,start)
+				if x is not None: return (i,x)
+			return (start,None)
+		return f
+	
+	def singleton(vType):
+		def f(str,start):
+			if str[start]!="[":
+				return (start,None)
+			i,x=vType(str,start+1)
+			if x is None: return (start,None)
+			if str[i]!="]":
+				return (start,None)
+			return (i+1,x)
+		return f
+		
+	# def listOf(str,start,vType,allowEmpty=False):
+		# res=[]
+		# i,x=singleton(str,start,vType)
+		# # singleton(vType) if vType not tuple else compose(vType[0],vType[1])
+		# while x!=None:
+			# res.append(x)
+			# i,x=singleton(str,i,vType)
+		# if len(res)==0 and not allowEmpty: return (start,None)
+		# return (i,res)
+		
+	def listOf(vType,allowEmpty=False):
+		def f(str,start):
+			res=[]
+			single=singleton(vType)
+			i,x=single(str,start)
+			while x!=None:
+				res.append(x)
+				i,x=single(str,i)
+			if len(res)==0 and not allowEmpty: return (start,None)
+			return (i,res)
+		return f
+		
+	# def compose(str,start,vTypeA,vTypeB):
+		# i,a=vTypeA(str,start)
+		# if a==None or str[i]!=":": return (start,None)
+		# i,b=vTypeB(str,i+1)
+		# if b==None: return start,None
+		# return (i,(a,b))
+		
+	def compose(vTypeA,vTypeB):
+		def f(str,start):
+			i,a=vTypeA(str,start)
+			# print(">",i,a)
+			if a==None or str[i]!=":": return (start,None)
+			i,b=vTypeB(str,i+1)
+			# print(">",i,b)
+			if b==None: return start,None
+			return (i,(a,b))
+		return f
+	
+	def number(str,start):
+		r=re.compile(r"(\+|-|)\d+")
+		m=r.match(str,start)
+		if m is None: return (start,None)
+		res=int(m.group(0))
+		return (m.end(),res)
+		
+	def real(str,start):
+		r=re.compile(r"(\+|-|)\d+(\.\d+)?")
+		m=r.match(str,start)
+		if m is None: return (start,None)
+		res=float(m.group(0))
+		return (m.end(),res)
+		
+	def double(str,start):
+		r=re.compile(r"1|2")
+		m=r.match(str,start)
+		if m is None: return (start,None)
+		res=int(m.group(0))
+		return (m.end(),res)
+	
+	def color(str,start):
+		r=re.compile(r"B|W")
+		m=r.match(str,start)
+		if m is None: return (start,None)
+		return (m.end(),m.group(0))
+		
+	# def simpleText(str,start):
+		# res=""
+		# esc=False
+		# lineBreak=False
+		# for c in str:
+			# if esc:
+				# res+=c
+				# esc=False
+			# elif c=="\\":
+				# esc=True
+			# elif c=="]":
+				# break
+			# else:
+				# res+=c
+		# return res
+	
+	def text(simple=True,composed=False):
+		def f(str,start):
+			res=""
+			esc=False
+			lastC=""
+			for i,c in enumerate(str[start:],start):
+				if esc:
+					if c!="\n" and c!="\r": res+=c
+					esc=False
+				elif (c=="\n" and lastC=="\r") or (c=="\r" and lastC=="\n"): pass
+				elif c=="\r" or c=="\n" and not simple:
+					res+="\n"
+				elif c.isspace():
+					res+=" "
+				elif c=="\\":
+					esc=True
+				elif c=="]" or (c==":" and composed):
+					break
+				else:
+					res+=c
+				lastC=c
+			return (i,res)
+		return f
+		
+	def empty(str,start): return (start,"")
+	
+	def anything(str,start): # přidat listOf
+		esc=False
+		for i,c in enumerate(str[start:],start):
+			if esc: esc=False
+			elif c=="\\": esc=True
+			elif c=="]": break
+		return (i,str[start:i])
+	
+	# go specific
+	def point(str,start):
+		r=re.compile(r"[a-zA-Z]{2}|") # !! limit to board size
+		m=r.match(str,start)
+		if m is None: return (start,None)
+		if m.group(0)=="": # pass, !! tt
+			return (m.end(),tuple())
+		col=m.group(0)[0]
+		row=m.group(0)[1]
+		col=ord(col) - (ord("a") if "a"<=col<="z" else ord("A")-26)
+		row=ord(row) - (ord("a") if "a"<=row<="z" else ord("A")-26)
+		return (m.end(),(col,row))
 
-  move=point
-  stone=point
-  
-  patterns={
-    "B":singleton(move),
-    "KO":singleton(empty),
-    "MN":singleton(number),
-    "W":singleton(move),
-    "AB":listOf(stone), #
-    "AE":listOf(point), #
-    "AW":listOf(stone), #
-    "PL":singleton(color),
-    "C":singleton(text(simple=False)),
-    "DM":singleton(double),
-    "GB":singleton(double),
-    "GW":singleton(double),
-    "HO":singleton(double),
-    "N":singleton(text()),
-    "UC":singleton(double),
-    "V":singleton(real),
-    "BM":singleton(double),
-    "DO":singleton(empty),
-    "IT":singleton(empty),
-    "TE":singleton(double),
-    "AR":listOf(compose(point,point)), #
-    "CR":listOf(point), #
-    "DD":listOf(point,allowEmpty=True), #
-    "LB":listOf(compose(point,text())), #
-    "LN":listOf(compose(point,point)), #
-    "MA":listOf(point), #
-    "SL":listOf(point), #
-    "SQ":listOf(point), #
-    "TR":listOf(point), #
-    "AP":singleton(compose(text(composed=True),text())), #
-    "CA":singleton(text()),
-    "FF":singleton(number),
-    "GM":singleton(number),
-    "ST":singleton(number),
-    "SZ":choose(singleton(number),singleton(compose(number,number))), #
-    "AN":singleton(text()),
-    "BR":singleton(text()),
-    "BT":singleton(text()),
-    "CP":singleton(text()),
-    "DT":singleton(text()),
-    "EV":singleton(text()),
-    "GN":singleton(text()),
-    "GC":singleton(text(simple=False)),
-    "ON":singleton(text()),
-    "OT":singleton(text()),
-    "PB":singleton(text()),
-    "PC":singleton(text()),
-    "PW":singleton(text()),
-    "RE":singleton(text()),
-    "RO":singleton(text()),
-    "RU":singleton(text()),
-    "SO":singleton(text()),
-    "TM":singleton(real),
-    "US":singleton(text()),
-    "WR":singleton(text()),
-    "WT":singleton(text()),
-    "BL":singleton(real),
-    "OB":singleton(number),
-    "OW":singleton(number),
-    "WL":singleton(real),
-    "FG":choose(singleton(empty),singleton(compose(number,text()))), #
-    "PM":singleton(number),
-    "VW":listOf(point,allowEmpty=True), #
-    
-    # go specific
-    "HA":singleton(number),
-    "KM":singleton(real),
-    "TB":listOf(point,allowEmpty=True),
-    "TW":listOf(point,allowEmpty=True)
-  }
+	move=point
+	stone=point
+	
+	patterns={
+		"B":singleton(move),
+		"KO":singleton(empty),
+		"MN":singleton(number),
+		"W":singleton(move),
+		"AB":listOf(stone), #
+		"AE":listOf(point), #
+		"AW":listOf(stone), #
+		"PL":singleton(color),
+		"C":singleton(text(simple=False)),
+		"DM":singleton(double),
+		"GB":singleton(double),
+		"GW":singleton(double),
+		"HO":singleton(double),
+		"N":singleton(text()),
+		"UC":singleton(double),
+		"V":singleton(real),
+		"BM":singleton(double),
+		"DO":singleton(empty),
+		"IT":singleton(empty),
+		"TE":singleton(double),
+		"AR":listOf(compose(point,point)), #
+		"CR":listOf(point), #
+		"DD":listOf(point,allowEmpty=True), #
+		"LB":listOf(compose(point,text())), #
+		"LN":listOf(compose(point,point)), #
+		"MA":listOf(point), #
+		"SL":listOf(point), #
+		"SQ":listOf(point), #
+		"TR":listOf(point), #
+		"AP":singleton(compose(text(composed=True),text())), #
+		"CA":singleton(text()),
+		"FF":singleton(number),
+		"GM":singleton(number),
+		"ST":singleton(number),
+		"SZ":choose(singleton(number),singleton(compose(number,number))), #
+		"AN":singleton(text()),
+		"BR":singleton(text()),
+		"BT":singleton(text()),
+		"CP":singleton(text()),
+		"DT":singleton(text()),
+		"EV":singleton(text()),
+		"GN":singleton(text()),
+		"GC":singleton(text(simple=False)),
+		"ON":singleton(text()),
+		"OT":singleton(text()),
+		"PB":singleton(text()),
+		"PC":singleton(text()),
+		"PW":singleton(text()),
+		"RE":singleton(text()),
+		"RO":singleton(text()),
+		"RU":singleton(text()),
+		"SO":singleton(text()),
+		"TM":singleton(real),
+		"US":singleton(text()),
+		"WR":singleton(text()),
+		"WT":singleton(text()),
+		"BL":singleton(real),
+		"OB":singleton(number),
+		"OW":singleton(number),
+		"WL":singleton(real),
+		"FG":choose(singleton(empty),singleton(compose(number,text()))), #
+		"PM":singleton(number),
+		"VW":listOf(point,allowEmpty=True), #
+		
+		# go specific
+		"HA":singleton(number),
+		"KM":singleton(real),
+		"TB":listOf(point,allowEmpty=True),
+		"TW":listOf(point,allowEmpty=True)
+	}
 
 """def property(str):
-  # i=propIdent(str)
-  # if i<0: return -1
-  # j=i
-  # i=propValue(str[i:])
-  # while i>=0:
-    # j+=i
-    # i=propValue(str[i:])
-  # return j
+	# i=propIdent(str)
+	# if i<0: return -1
+	# j=i
+	# i=propValue(str[i:])
+	# while i>=0:
+		# j+=i
+		# i=propValue(str[i:])
+	# return j
 
 def propIdent(str):
-  m=re.match(r"[A-Z]+",str)
-  if m is None: return -1
-  return m.end()
+	m=re.match(r"[A-Z]+",str)
+	if m is None: return -1
+	return m.end()
 
 def propValue(str):
-  i=cValueType(str[1:])
-  if str[0]=="[" and i>=0 and str[i]=="]": return i+1
-  else: return -1
+	i=cValueType(str[1:])
+	if str[0]=="[" and i>=0 and str[i]=="]": return i+1
+	else: return -1
 
 class propValue:
-  pass
+	pass
 
 def cValueType(str,start):
-  matches=[real,number,double,color,simpleText]
-  for f in matches:
-    i,x=f(str,start)
-    if x is not None: return i,x
-  return 1/0
+	matches=[real,number,double,color,simpleText]
+	for f in matches:
+		i,x=f(str,start)
+		if x is not None: return i,x
+	return 1/0
 
 def number(str,start):
-  r=re.compile(r"(\+|-|)\d+")
-  m=r.match(str,start)
-  if m is None: return (-1,None)
-  x=int(m.group(0))
-  return (m.end(),x)
+	r=re.compile(r"(\+|-|)\d+")
+	m=r.match(str,start)
+	if m is None: return (-1,None)
+	x=int(m.group(0))
+	return (m.end(),x)
 
 def real(str):
-  m=re.match(r"(\+|-|)\d+(\.\d+)?",str)
-  if m is None: return -1
-  return m.end()
+	m=re.match(r"(\+|-|)\d+(\.\d+)?",str)
+	if m is None: return -1
+	return m.end()
 
 def double(str):
-  m=re.match(r"1|2",str)
-  if m is None: return -1
-  return m.end()
-  
+	m=re.match(r"1|2",str)
+	if m is None: return -1
+	return m.end()
+	
 def color(str):
-  m=re.match(r"B|W",str)
-  if m is None: return -1
-  return m.end()
-  
+	m=re.match(r"B|W",str)
+	if m is None: return -1
+	return m.end()
+	
 def simpleText(str):
-  res=r""
-  esc=False
-  for c in str:
-    if esc:
-      res+=c
-      esc=False
-    elif c=="\\":
-      esc=True
-    elif c=="]":
-      break
-    else:
-      res+=c
-  return res"""
+	res=r""
+	esc=False
+	for c in str:
+		if esc:
+			res+=c
+			esc=False
+		elif c=="\\":
+			esc=True
+		elif c=="]":
+			break
+		else:
+			res+=c
+	return res"""
 
 sgf=open("in/1-Hora-Simara.sgf").read()
 
diff --git a/sgfParser.py b/sgfParser.py
--- a/sgfParser.py
+++ b/sgfParser.py
@@ -1,434 +1,434 @@
 import re
-  
+	
 def skipWhitespace(str,start):
-  i=start
-  while i<len(str) and str[i].isspace(): i+=1
-  return i
+	i=start
+	while i<len(str) and str[i].isspace(): i+=1
+	return i
 
 class Collection:
-  gameTrees=[]
-  
-  def __init__(self,str):
-    self.gameTrees=[]
-    i,x=GameTree.create(str,0)
-    if x is None:
-      print("error when parsing Collection")
-      return
-    while x is not None:
-      self.gameTrees.append(x)
-      i,x=GameTree.create(str,i)
-  
+	gameTrees=[]
+	
+	def __init__(self,str):
+		self.gameTrees=[]
+		i,x=GameTree.create(str,0)
+		if x is None:
+			print("error when parsing Collection")
+			return
+		while x is not None:
+			self.gameTrees.append(x)
+			i,x=GameTree.create(str,i)
+	
 class GameTree:
-  nodes=[]
-  branches=[]
-  
-  # def __init__(self,str,start):
-    # self.nodes=[]
-    # self.branches=[]
-    # if str[start]!="(":
-      # print("error when parsing GameTree")
-      # return (-1,None)
-    # i,x=Node(str,start+1)
-    # if x is None:
-      # print("error when parsing GameTree")
-      # return (-1,None)
-    # while x is not None:
-      # self.nodes.append(x)
-      # i,x=Node(str,i)
-    # if str[i]!=")":
-      # print("error when parsing GameTree")
-      # return (-1,None)
-    # return (i+1,self)
-    
-  def create(str,start):
-    res=GameTree()
-    i=skipWhitespace(str,start)
-    if i>=len(str) or str[i]!="(":
-      # print("error when parsing GameTree")
-      return (start,None)
-    i,x=Node.create(str,start+1)
-    if x is None:
-      # print("error when parsing GameTree")
-      return (i,None)
-    while x is not None:
-      res.nodes.append(x)
-      i=skipWhitespace(str,i)
-      i,x=Node.create(str,i)
-    i=skipWhitespace(str,i)
-    i,x=GameTree.create(str,i)
-    while x is not None:
-      res.branches.append(x)
-      i=skipWhitespace(str,i)
-      i,x=GameTree.create(str,i)
-    if str[i]!=")":
-      # print("error when parsing GameTree")
-      return (i,None)
-    return (i+1,res)
-  
+	nodes=[]
+	branches=[]
+	
+	# def __init__(self,str,start):
+		# self.nodes=[]
+		# self.branches=[]
+		# if str[start]!="(":
+			# print("error when parsing GameTree")
+			# return (-1,None)
+		# i,x=Node(str,start+1)
+		# if x is None:
+			# print("error when parsing GameTree")
+			# return (-1,None)
+		# while x is not None:
+			# self.nodes.append(x)
+			# i,x=Node(str,i)
+		# if str[i]!=")":
+			# print("error when parsing GameTree")
+			# return (-1,None)
+		# return (i+1,self)
+		
+	def create(str,start):
+		res=GameTree()
+		i=skipWhitespace(str,start)
+		if i>=len(str) or str[i]!="(":
+			# print("error when parsing GameTree")
+			return (start,None)
+		i,x=Node.create(str,start+1)
+		if x is None:
+			# print("error when parsing GameTree")
+			return (i,None)
+		while x is not None:
+			res.nodes.append(x)
+			i=skipWhitespace(str,i)
+			i,x=Node.create(str,i)
+		i=skipWhitespace(str,i)
+		i,x=GameTree.create(str,i)
+		while x is not None:
+			res.branches.append(x)
+			i=skipWhitespace(str,i)
+			i,x=GameTree.create(str,i)
+		if str[i]!=")":
+			# print("error when parsing GameTree")
+			return (i,None)
+		return (i+1,res)
+	
 class Node:
-  properties=dict()
-  
-  def create(str,start):
-    res=Node()
-    if str[start]!=";":
-      # print("error when parsing Node")
-      return (start,None)
-    i=skipWhitespace(str,start+1)
-    i,x=Property.create(str,start+1)
-    while x is not None:
-      if x.name in res.properties:
-        print('error: duplicate "{0}" property in node at position {1}. second value ignored'.format(x.name,start))
-      else:
-        res.properties[x.name]=x
-      i=skipWhitespace(str,i)
-      i,x=Property.create(str,i)
-    return (i,res)
-    
-  def setProperty(self,name,value):
-    self.properties[name]=value
-    # zkontrolovat typ value
-    
-  def getProperty(self,name):
-    if name in self.properties: return self.properties[name]
-    else: return None
-  
+	properties=dict()
+	
+	def create(str,start):
+		res=Node()
+		if str[start]!=";":
+			# print("error when parsing Node")
+			return (start,None)
+		i=skipWhitespace(str,start+1)
+		i,x=Property.create(str,start+1)
+		while x is not None:
+			if x.name in res.properties:
+				print('error: duplicate "{0}" property in node at position {1}. second value ignored'.format(x.name,start))
+			else:
+				res.properties[x.name]=x
+			i=skipWhitespace(str,i)
+			i,x=Property.create(str,i)
+		return (i,res)
+		
+	def setProperty(self,name,value):
+		self.properties[name]=value
+		# zkontrolovat typ value
+		
+	def getProperty(self,name):
+		if name in self.properties: return self.properties[name]
+		else: return None
+	
 class Property:
-  name=""
-  value=""
-  
-  def create(str,start):
-    res=Property()
-    i,x=Property.ident(str,start)
-    if x is None:
-      return (start,None)
-    res.name=x
-    i,x=PropValue.create(str,i,res.name)
-    if x is None:
-      print('error when parsing property "{0}" at position {1}'.format(res.name,i))
-      return (start,None)
-    # while x is not None: # přesunuto do PropValue.listOf
-      # res.values.append(x)
-      # i=skipWhitespace(str,i)
-      # i,x=PropValue.create(str,i,res.name)
-    return (i,res)
-    
-  def ident(str,start):
-    r=re.compile(r"[A-Z]+")
-    m=r.match(str,start)
-    if m is None: return (start,None)
-    return (m.end(),m.group())
+	name=""
+	value=""
+	
+	def create(str,start):
+		res=Property()
+		i,x=Property.ident(str,start)
+		if x is None:
+			return (start,None)
+		res.name=x
+		i,x=PropValue.create(str,i,res.name)
+		if x is None:
+			print('error when parsing property "{0}" at position {1}'.format(res.name,i))
+			return (start,None)
+		# while x is not None: # přesunuto do PropValue.listOf
+			# res.values.append(x)
+			# i=skipWhitespace(str,i)
+			# i,x=PropValue.create(str,i,res.name)
+		return (i,res)
+		
+	def ident(str,start):
+		r=re.compile(r"[A-Z]+")
+		m=r.match(str,start)
+		if m is None: return (start,None)
+		return (m.end(),m.group())
 
 class PropValue:
-  type=""
-  value=None
-  patterns=dict()
-  
-  def create(str,start,name):
-    if name in PropValue.patterns:
-      return PropValue.patterns[name](str,start)
-    else:
-      print('warning, unknown property "{0}" at position {1}'.format(name,start))
-      return PropValue.singleton(PropValue.anything)(str,start)
-  
-  # def singleton(str,start,vType):
-    # if str[start]!="[":
-      # return (start,None)
-    # i,x=vType(str,start+1)
-    # if x is None: return (start,None)
-    # if str[i]!="]":
-      # return (start,None)
-    # return (i+1,x)
-  
-  def choose(*vTypes):
-    def f(str,start):
-      for vType in vTypes:
-        i,x=vType(str,start)
-        if x is not None: return (i,x)
-      return (start,None)
-    return f
-  
-  def singleton(vType):
-    def f(str,start):
-      if str[start]!="[":
-        return (start,None)
-      i,x=vType(str,start+1)
-      if x is None: return (start,None)
-      if str[i]!="]":
-        return (start,None)
-      return (i+1,x)
-    return f
-    
-  # def listOf(str,start,vType,allowEmpty=False):
-    # res=[]
-    # i,x=singleton(str,start,vType)
-    # # singleton(vType) if vType not tuple else compose(vType[0],vType[1])
-    # while x!=None:
-      # res.append(x)
-      # i,x=singleton(str,i,vType)
-    # if len(res)==0 and not allowEmpty: return (start,None)
-    # return (i,res)
-    
-  def listOf(vType,allowEmpty=False):
-    def f(str,start):
-      res=[]
-      single=singleton(vType)
-      i,x=single(str,start)
-      while x!=None:
-        res.append(x)
-        i,x=single(str,i)
-      if len(res)==0 and not allowEmpty: return (start,None)
-      return (i,res)
-    return f
-    
-  # def compose(str,start,vTypeA,vTypeB):
-    # i,a=vTypeA(str,start)
-    # if a==None or str[i]!=":": return (start,None)
-    # i,b=vTypeB(str,i+1)
-    # if b==None: return start,None
-    # return (i,(a,b))
-    
-  def compose(vTypeA,vTypeB):
-    def f(str,start):
-      i,a=vTypeA(str,start)
-      # print(">",i,a)
-      if a==None or str[i]!=":": return (start,None)
-      i,b=vTypeB(str,i+1)
-      # print(">",i,b)
-      if b==None: return start,None
-      return (i,(a,b))
-    return f
-  
-  def number(str,start):
-    r=re.compile(r"(\+|-|)\d+")
-    m=r.match(str,start)
-    if m is None: return (start,None)
-    res=int(m.group(0))
-    return (m.end(),res)
-    
-  def real(str,start):
-    r=re.compile(r"(\+|-|)\d+(\.\d+)?")
-    m=r.match(str,start)
-    if m is None: return (start,None)
-    res=float(m.group(0))
-    return (m.end(),res)
-    
-  def double(str,start):
-    r=re.compile(r"1|2")
-    m=r.match(str,start)
-    if m is None: return (start,None)
-    res=int(m.group(0))
-    return (m.end(),res)
-  
-  def color(str,start):
-    r=re.compile(r"B|W")
-    m=r.match(str,start)
-    if m is None: return (start,None)
-    return (m.end(),m.group(0))
-    
-  # def simpleText(str,start):
-    # res=""
-    # esc=False
-    # lineBreak=False
-    # for c in str:
-      # if esc:
-        # res+=c
-        # esc=False
-      # elif c=="\\":
-        # esc=True
-      # elif c=="]":
-        # break
-      # else:
-        # res+=c
-    # return res
-  
-  def text(simple=True,composed=False):
-    def f(str,start):
-      res=""
-      esc=False
-      lastC=""
-      for i,c in enumerate(str[start:],start):
-        if esc:
-          if c!="\n" and c!="\r": res+=c
-          esc=False
-        elif (c=="\n" and lastC=="\r") or (c=="\r" and lastC=="\n"): pass
-        elif c=="\r" or c=="\n" and not simple:
-          res+="\n"
-        elif c.isspace():
-          res+=" "
-        elif c=="\\":
-          esc=True
-        elif c=="]" or (c==":" and composed):
-          break
-        else:
-          res+=c
-        lastC=c
-      return (i,res)
-    return f
-    
-  def empty(str,start): return (start,"")
-  
-  def anything(str,start):
-    esc=False
-    for i,c in enumerate(str[start:],start):
-      if esc: esc=False
-      elif c=="\\": esc=True
-      elif c=="]": break
-    return (i,str[start:i])
-  
-  # go specific
-  def point(str,start):
-    r=re.compile(r"[a-zA-Z]{2}|") # !! limit to board size
-    m=r.match(str,start)
-    if m is None: return (start,None)
-    if m.group(0)=="": # pass, !! tt
-      return (m.end(),tuple())
-    col=m.group(0)[0]
-    row=m.group(0)[1]
-    col=ord(col) - (ord("a") if "a"<=col<="z" else ord("A")-26)
-    row=ord(row) - (ord("a") if "a"<=row<="z" else ord("A")-26)
-    return (m.end(),(col,row))
+	type=""
+	value=None
+	patterns=dict()
+	
+	def create(str,start,name):
+		if name in PropValue.patterns:
+			return PropValue.patterns[name](str,start)
+		else:
+			print('warning, unknown property "{0}" at position {1}'.format(name,start))
+			return PropValue.singleton(PropValue.anything)(str,start)
+	
+	# def singleton(str,start,vType):
+		# if str[start]!="[":
+			# return (start,None)
+		# i,x=vType(str,start+1)
+		# if x is None: return (start,None)
+		# if str[i]!="]":
+			# return (start,None)
+		# return (i+1,x)
+	
+	def choose(*vTypes):
+		def f(str,start):
+			for vType in vTypes:
+				i,x=vType(str,start)
+				if x is not None: return (i,x)
+			return (start,None)
+		return f
+	
+	def singleton(vType):
+		def f(str,start):
+			if str[start]!="[":
+				return (start,None)
+			i,x=vType(str,start+1)
+			if x is None: return (start,None)
+			if str[i]!="]":
+				return (start,None)
+			return (i+1,x)
+		return f
+		
+	# def listOf(str,start,vType,allowEmpty=False):
+		# res=[]
+		# i,x=singleton(str,start,vType)
+		# # singleton(vType) if vType not tuple else compose(vType[0],vType[1])
+		# while x!=None:
+			# res.append(x)
+			# i,x=singleton(str,i,vType)
+		# if len(res)==0 and not allowEmpty: return (start,None)
+		# return (i,res)
+		
+	def listOf(vType,allowEmpty=False):
+		def f(str,start):
+			res=[]
+			single=singleton(vType)
+			i,x=single(str,start)
+			while x!=None:
+				res.append(x)
+				i,x=single(str,i)
+			if len(res)==0 and not allowEmpty: return (start,None)
+			return (i,res)
+		return f
+		
+	# def compose(str,start,vTypeA,vTypeB):
+		# i,a=vTypeA(str,start)
+		# if a==None or str[i]!=":": return (start,None)
+		# i,b=vTypeB(str,i+1)
+		# if b==None: return start,None
+		# return (i,(a,b))
+		
+	def compose(vTypeA,vTypeB):
+		def f(str,start):
+			i,a=vTypeA(str,start)
+			# print(">",i,a)
+			if a==None or str[i]!=":": return (start,None)
+			i,b=vTypeB(str,i+1)
+			# print(">",i,b)
+			if b==None: return start,None
+			return (i,(a,b))
+		return f
+	
+	def number(str,start):
+		r=re.compile(r"(\+|-|)\d+")
+		m=r.match(str,start)
+		if m is None: return (start,None)
+		res=int(m.group(0))
+		return (m.end(),res)
+		
+	def real(str,start):
+		r=re.compile(r"(\+|-|)\d+(\.\d+)?")
+		m=r.match(str,start)
+		if m is None: return (start,None)
+		res=float(m.group(0))
+		return (m.end(),res)
+		
+	def double(str,start):
+		r=re.compile(r"1|2")
+		m=r.match(str,start)
+		if m is None: return (start,None)
+		res=int(m.group(0))
+		return (m.end(),res)
+	
+	def color(str,start):
+		r=re.compile(r"B|W")
+		m=r.match(str,start)
+		if m is None: return (start,None)
+		return (m.end(),m.group(0))
+		
+	# def simpleText(str,start):
+		# res=""
+		# esc=False
+		# lineBreak=False
+		# for c in str:
+			# if esc:
+				# res+=c
+				# esc=False
+			# elif c=="\\":
+				# esc=True
+			# elif c=="]":
+				# break
+			# else:
+				# res+=c
+		# return res
+	
+	def text(simple=True,composed=False):
+		def f(str,start):
+			res=""
+			esc=False
+			lastC=""
+			for i,c in enumerate(str[start:],start):
+				if esc:
+					if c!="\n" and c!="\r": res+=c
+					esc=False
+				elif (c=="\n" and lastC=="\r") or (c=="\r" and lastC=="\n"): pass
+				elif c=="\r" or c=="\n" and not simple:
+					res+="\n"
+				elif c.isspace():
+					res+=" "
+				elif c=="\\":
+					esc=True
+				elif c=="]" or (c==":" and composed):
+					break
+				else:
+					res+=c
+				lastC=c
+			return (i,res)
+		return f
+		
+	def empty(str,start): return (start,"")
+	
+	def anything(str,start):
+		esc=False
+		for i,c in enumerate(str[start:],start):
+			if esc: esc=False
+			elif c=="\\": esc=True
+			elif c=="]": break
+		return (i,str[start:i])
+	
+	# go specific
+	def point(str,start):
+		r=re.compile(r"[a-zA-Z]{2}|") # !! limit to board size
+		m=r.match(str,start)
+		if m is None: return (start,None)
+		if m.group(0)=="": # pass, !! tt
+			return (m.end(),tuple())
+		col=m.group(0)[0]
+		row=m.group(0)[1]
+		col=ord(col) - (ord("a") if "a"<=col<="z" else ord("A")-26)
+		row=ord(row) - (ord("a") if "a"<=row<="z" else ord("A")-26)
+		return (m.end(),(col,row))
 
-  move=point
-  stone=point
-  
-  patterns={
-    "B":singleton(move),
-    "KO":singleton(empty),
-    "MN":singleton(number),
-    "W":singleton(move),
-    "AB":listOf(stone), #
-    "AE":listOf(point), #
-    "AW":listOf(stone), #
-    "PL":singleton(color),
-    "C":singleton(text(simple=False)),
-    "DM":singleton(double),
-    "GB":singleton(double),
-    "GW":singleton(double),
-    "HO":singleton(double),
-    "N":singleton(text()),
-    "UC":singleton(double),
-    "V":singleton(real),
-    "BM":singleton(double),
-    "DO":singleton(empty),
-    "IT":singleton(empty),
-    "TE":singleton(double),
-    "AR":listOf(compose(point,point)), #
-    "CR":listOf(point), #
-    "DD":listOf(point,allowEmpty=True), #
-    "LB":listOf(compose(point,text())), #
-    "LN":listOf(compose(point,point)), #
-    "MA":listOf(point), #
-    "SL":listOf(point), #
-    "SQ":listOf(point), #
-    "TR":listOf(point), #
-    "AP":singleton(compose(text(composed=True),text())), #
-    "CA":singleton(text()),
-    "FF":singleton(number),
-    "GM":singleton(number),
-    "ST":singleton(number),
-    "SZ":choose(singleton(number),singleton(compose(number,number))), #
-    "AN":singleton(text()),
-    "BR":singleton(text()),
-    "BT":singleton(text()),
-    "CP":singleton(text()),
-    "DT":singleton(text()),
-    "EV":singleton(text()),
-    "GN":singleton(text()),
-    "GC":singleton(text(simple=False)),
-    "ON":singleton(text()),
-    "OT":singleton(text()),
-    "PB":singleton(text()),
-    "PC":singleton(text()),
-    "PW":singleton(text()),
-    "RE":singleton(text()),
-    "RO":singleton(text()),
-    "RU":singleton(text()),
-    "SO":singleton(text()),
-    "TM":singleton(real),
-    "US":singleton(text()),
-    "WR":singleton(text()),
-    "WT":singleton(text()),
-    "BL":singleton(real),
-    "OB":singleton(number),
-    "OW":singleton(number),
-    "WL":singleton(real),
-    "FG":choose(singleton(empty),singleton(compose(number,text()))), #
-    "PM":singleton(number),
-    "VW":listOf(point,allowEmpty=True), #
-    
-    # go specific
-    "HA":singleton(number),
-    "KM":singleton(real),
-    "TB":listOf(point,allowEmpty=True),
-    "TW":listOf(point,allowEmpty=True)
-  }
+	move=point
+	stone=point
+	
+	patterns={
+		"B":singleton(move),
+		"KO":singleton(empty),
+		"MN":singleton(number),
+		"W":singleton(move),
+		"AB":listOf(stone), #
+		"AE":listOf(point), #
+		"AW":listOf(stone), #
+		"PL":singleton(color),
+		"C":singleton(text(simple=False)),
+		"DM":singleton(double),
+		"GB":singleton(double),
+		"GW":singleton(double),
+		"HO":singleton(double),
+		"N":singleton(text()),
+		"UC":singleton(double),
+		"V":singleton(real),
+		"BM":singleton(double),
+		"DO":singleton(empty),
+		"IT":singleton(empty),
+		"TE":singleton(double),
+		"AR":listOf(compose(point,point)), #
+		"CR":listOf(point), #
+		"DD":listOf(point,allowEmpty=True), #
+		"LB":listOf(compose(point,text())), #
+		"LN":listOf(compose(point,point)), #
+		"MA":listOf(point), #
+		"SL":listOf(point), #
+		"SQ":listOf(point), #
+		"TR":listOf(point), #
+		"AP":singleton(compose(text(composed=True),text())), #
+		"CA":singleton(text()),
+		"FF":singleton(number),
+		"GM":singleton(number),
+		"ST":singleton(number),
+		"SZ":choose(singleton(number),singleton(compose(number,number))), #
+		"AN":singleton(text()),
+		"BR":singleton(text()),
+		"BT":singleton(text()),
+		"CP":singleton(text()),
+		"DT":singleton(text()),
+		"EV":singleton(text()),
+		"GN":singleton(text()),
+		"GC":singleton(text(simple=False)),
+		"ON":singleton(text()),
+		"OT":singleton(text()),
+		"PB":singleton(text()),
+		"PC":singleton(text()),
+		"PW":singleton(text()),
+		"RE":singleton(text()),
+		"RO":singleton(text()),
+		"RU":singleton(text()),
+		"SO":singleton(text()),
+		"TM":singleton(real),
+		"US":singleton(text()),
+		"WR":singleton(text()),
+		"WT":singleton(text()),
+		"BL":singleton(real),
+		"OB":singleton(number),
+		"OW":singleton(number),
+		"WL":singleton(real),
+		"FG":choose(singleton(empty),singleton(compose(number,text()))), #
+		"PM":singleton(number),
+		"VW":listOf(point,allowEmpty=True), #
+		
+		# go specific
+		"HA":singleton(number),
+		"KM":singleton(real),
+		"TB":listOf(point,allowEmpty=True),
+		"TW":listOf(point,allowEmpty=True)
+	}
 
 """def property(str):
-  # i=propIdent(str)
-  # if i<0: return -1
-  # j=i
-  # i=propValue(str[i:])
-  # while i>=0:
-    # j+=i
-    # i=propValue(str[i:])
-  # return j
+	# i=propIdent(str)
+	# if i<0: return -1
+	# j=i
+	# i=propValue(str[i:])
+	# while i>=0:
+		# j+=i
+		# i=propValue(str[i:])
+	# return j
 
 def propIdent(str):
-  m=re.match(r"[A-Z]+",str)
-  if m is None: return -1
-  return m.end()
+	m=re.match(r"[A-Z]+",str)
+	if m is None: return -1
+	return m.end()
 
 def propValue(str):
-  i=cValueType(str[1:])
-  if str[0]=="[" and i>=0 and str[i]=="]": return i+1
-  else: return -1
+	i=cValueType(str[1:])
+	if str[0]=="[" and i>=0 and str[i]=="]": return i+1
+	else: return -1
 
 class propValue:
-  pass
+	pass
 
 def cValueType(str,start):
-  matches=[real,number,double,color,simpleText]
-  for f in matches:
-    i,x=f(str,start)
-    if x is not None: return i,x
-  return 1/0
+	matches=[real,number,double,color,simpleText]
+	for f in matches:
+		i,x=f(str,start)
+		if x is not None: return i,x
+	return 1/0
 
 def number(str,start):
-  r=re.compile(r"(\+|-|)\d+")
-  m=r.match(str,start)
-  if m is None: return (-1,None)
-  x=int(m.group(0))
-  return (m.end(),x)
+	r=re.compile(r"(\+|-|)\d+")
+	m=r.match(str,start)
+	if m is None: return (-1,None)
+	x=int(m.group(0))
+	return (m.end(),x)
 
 def real(str):
-  m=re.match(r"(\+|-|)\d+(\.\d+)?",str)
-  if m is None: return -1
-  return m.end()
+	m=re.match(r"(\+|-|)\d+(\.\d+)?",str)
+	if m is None: return -1
+	return m.end()
 
 def double(str):
-  m=re.match(r"1|2",str)
-  if m is None: return -1
-  return m.end()
-  
+	m=re.match(r"1|2",str)
+	if m is None: return -1
+	return m.end()
+	
 def color(str):
-  m=re.match(r"B|W",str)
-  if m is None: return -1
-  return m.end()
-  
+	m=re.match(r"B|W",str)
+	if m is None: return -1
+	return m.end()
+	
 def simpleText(str):
-  res=r""
-  esc=False
-  for c in str:
-    if esc:
-      res+=c
-      esc=False
-    elif c=="\\":
-      esc=True
-    elif c=="]":
-      break
-    else:
-      res+=c
-  return res"""
+	res=r""
+	esc=False
+	for c in str:
+		if esc:
+			res+=c
+			esc=False
+		elif c=="\\":
+			esc=True
+		elif c=="]":
+			break
+		else:
+			res+=c
+	return res"""
 
 sgf=open("in/1-Hora-Simara.sgf").read()