
Property changes on: gnome-sudoku/src/lib
___________________________________________________________________
Name: svn:ignore
   - Makefile
Makefile.in
defaults.py

   + Makefile
Makefile.in
defaults.py
*.pyc



Index: gnome-sudoku/src/lib/sudoku_maker.py
===================================================================
--- gnome-sudoku/src/lib/sudoku_maker.py	(revision 6846)
+++ gnome-sudoku/src/lib/sudoku_maker.py	(working copy)
@@ -1,5 +1,5 @@
 import sys
-import os
+import os, shutil
 import os.path
 import sudoku
 import random
@@ -301,9 +301,8 @@
                                   'group_size':9},
                   puzzle_maker_args={'symmetrical':True},
                   batch_size = 5,
-                  pickle_to = os.path.join(DATA_DIR,'generated_puzzles')):
-
-        self.new_puzzles=[]
+                  pickle_to = os.path.join(DATA_DIR,'puzzles')):
+        self.new_puzzles={}
         self.pickle_to = pickle_to
         self.paused = False
         self.terminated = False
@@ -312,53 +311,179 @@
         self.batch_size = batch_size
         self.load()
         self.all_puzzles = {}
-        # names to help our users keep track of the different puzzles!
-        self.names = {}
-        # and a dictionary of how high we've counted with our
-        # different names (this may be getting absurdly complicated,
-        # but what can you do...)
-        self.top_name = {}
+        self.reread_played_list()
+
+    # Convenience methods for accessing puzzles we've created
+    
+    def reread_played_list (self):
+        played_fn = os.path.join(self.pickle_to,'finished')
+        self.played = []
+        if os.path.exists(played_fn):
+            for line in file(played_fn,'r'):
+                self.played.append(line.strip('\n'))
         
-        self.solutions_by_puzzle = {}
-        for solution,puzzles in self.puzzles_by_solution.items():
-            for p,d in puzzles:
-                self.all_puzzles[p]=d
-                self.solutions_by_puzzle[p]=solution
-                if not self.names.has_key(p):
-                    self.names[p]=self.get_puzzle_name(_('Puzzle'))
+    def load (self):
+        if not os.path.exists(self.pickle_to):
+            os.makedirs(self.pickle_to)
+        for cat in sudoku.DifficultyRating.categories:
+            if not os.path.exists(os.path.join(self.pickle_to,
+                                               cat.replace(' ','_'))):
+                shutil.copy(os.path.join(os.path.join(BASE_DIR,'puzzles'),cat.replace(' ','_')),
+                            os.path.join(self.pickle_to,cat.replace(' ','_'))
+                            )
 
+    def get_new_puzzle (self, difficulty, new=True):
+        """Return puzzle with difficulty near difficulty.
 
-        
-    def load_initial_batch (self):
-        ifi = open(os.path.join(BASE_DIR,'starter_puzzles'))
-        try:
-            self.puzzles_by_solution = pickle.load(ifi)
-        except:
-            (type, value, traceback) = sys.exc_info()
-            print 'Unable to load puzzles: %s: %s' % (str(type), str(value))
-            self.puzzles_by_solution = {}
-        ifi.close()
+        If new is True, we return only unplayed puzzles.
+        Return a tuple containing a new puzzle and difficulty object.
+        """
+        val_cat = sudoku.get_difficulty_category(difficulty)
+        if not val_cat:
+            print 'WARNING, no val cat for difficulty:',difficulty
+            if val_cat > 1: val_cat = 'very hard'
+            else: val_cat = 'easy'
+        puzzles = []
+        ifi = file(os.path.join(self.pickle_to,
+                                val_cat.replace(' ','_'))
+                   )
+        closest = 10000000000000,None
+        for l in ifi.readlines():
+            puzzle,diff = l.split('\t')
+            if new and (puzzle in self.played): continue
+            if not sudoku.is_valid_puzzle(puzzle):
+                print 'WARNING: invalid puzzle %s in file %s'%(puzzle,ifi)
+                continue
+            diff = float(diff)
+            closeness_to_target = abs(diff - difficulty)
+            if closest[0] > closeness_to_target:
+                closest = diff,puzzle
+        return closest[1],sudoku.SudokuRater(
+            sudoku.sudoku_grid_from_string(closest[1]).grid
+            ).difficulty()
 
+    def n_puzzles (self, difficulty_category=None, new=True):
+        if not difficulty_category:
+            return sum([self.n_puzzles(c,new=new) for c in sudoku.DifficultyRating.categories])
+        else:
+            path = os.path.join(self.pickle_to,
+                                difficulty_category.replace(' ','_')
+                                )
+            if os.path.exists(path):
+                ifi = file(path,'r')
+                count = 0
+                for line in ifi:
+                    if (not new) or line.split('\t')[0] not in self.played:
+                        count+=1
+                return count
+
+    def list_puzzles (self, difficulty_category=None, new=True):
+        """Return a list of all puzzles we have generated.
+        """
+        puzzle_list = []
+        if not difficulty_category:
+            for c in sudoku.DifficultyRating.categories:
+                puzzle_list.extend(self.list_puzzles(c,new=new))
+        else:
+            path = os.path.join(self.pickle_to,
+                                difficulty_category.replace(' ','_')
+                                )
+            if os.path.exists(path):
+                ifi = file(path,'r')
+                for l in ifi.readlines():
+                    puzzle = l.split('\t')[0]
+                    if (not new) or puzzle not in self.played:
+                        puzzle_list.append(puzzle)
+        return puzzle_list
+
+    def get_puzzles (self, n, levels, new=True):
+        """Return a list of n puzzles and difficulty values (as floats).
+
+        The puzzles will correspond as closely as possible to levels.
+        If new, we only return puzzles not yet played.
+        """
+        if not n: return []
+        assert(levels)
+        puzzles = []
+        # Open files to read puzzles...
+        files = dict([(l,
+                       file(os.path.join(self.pickle_to,
+                                         l.replace(' ','_')),
+                            'r')) for l in levels])
+        i = 0; il = 0
+        n_per_level = {}
+        finished = []
+        while i < n and len(finished) < len(levels):
+            if il >= len(levels): il = 0
+            lev = levels[il]
+            # skip any levels that we've exhausted
+            if lev in finished:
+                il += 1
+                continue
+            line = files[lev].readline()
+            if not line:
+                finished.append(lev)
+            else:
+                p,d = line.split('\t')
+                if sudoku.is_valid_puzzle(p):
+                    if not new or p not in self.played:
+                        puzzles.append((p,float(d)))
+                        i += 1
+                else:
+                    print 'WARNING: invalid puzzle %s in file %s'%(p,files[lev])
+            il += 1
+        if i < n:
+            print 'WARNING: Not able to provide %s puzzles in levels %s'%(n,levels)
+            print 'WARNING: Generate more puzzles if you really need this many puzzles!'
+        for fi in files.values(): fi.close()
+        return puzzles    
+
+    # End convenience methods for accessing puzzles we've created
+
+    # Methods for creating new puzzles
+
     def make_batch (self, diff_min=None, diff_max=None):
         self.new_generator = InterruptibleSudokuGenerator(**self.generator_args)
         key = self.new_generator.start_grid.to_string()        
-        while self.puzzles_by_solution.has_key(key):
-            self.new_generator = InterruptibleSudokuGenerator(**self.generator_args)
-            key = self.new_generator.start_grid.to_string()
+        #while 
+        #    self.new_generator = InterruptibleSudokuGenerator(**self.generator_args)
+        #    key = self.new_generator.start_grid.to_string()
         #print 'We have our solution grid'
-        self.puzzles_by_solution[key]=[]
+        #self.puzzles_by_solution[key]=[]
         ug = self.new_generator.unique_generator(**self.puzzle_maker_args)
+        open_files = {}
         for n in range(self.batch_size):
+            #print 'start next item...',n
             puz,diff = ug.next()
+            #print "GENERATED ",puz,diff
             if ((not diff_min or diff.value >= diff_min)
                 and
                 (not diff_max or diff.value <= diff_max)):
                 puzstring = puz.to_string()
-                self.puzzles_by_solution[key].append((puzstring,diff))
-                self.solutions_by_puzzle[puzstring]=key
-                self.all_puzzles[puzstring] = diff
-                self.names[puzstring] = self.get_puzzle_name(_('Puzzle'))
-                self.new_puzzles.append((puzstring,diff))
+                # self.puzzles_by_solution[key].append((puzstring,diff))
+                # self.solutions_by_puzzle[puzstring]=key
+                # self.all_puzzles[puzstring] = diff
+                # self.names[puzstring] = self.get_puzzle_name(_('Puzzle'))
+                self.new_puzzles[diff.value_category()] = self.new_puzzles.get(diff.value_category(),0) + 1
+                outpath = os.path.join(self.pickle_to,
+                                       diff.value_category().replace(' ','_'))
+                print 'Writing to ',os.path.join(self.pickle_to,
+                                       diff.value_category().replace(' ','_'))
+                # Read through the existing file and make sure we're
+                # not a duplicate puzzle
+                infi = file(outpath,'r')
+                l = infi.readline()
+                while l:
+                    if l==puzstring:
+                        continue
+                    l = infi.readline()
+                infi.close()
+                outfi = file(outpath,'a')
+                outfi.write(puzstring+'\t'+str(diff.value)+'\n')
+                outfi.close()
+                print 'done writing...'
+        # Close all our open files...
+        #for f in open_files.values(): f.close()
 
     def pause (self, *args):
         if hasattr(self,'new_generator'): self.new_generator.pause()
@@ -382,7 +507,7 @@
         self.terminated = False
         if hasattr(self,'new_generator'): self.new_generator.termintaed = False
         self.paused = False
-        self.new_puzzles = []
+        #self.new_puzzles = {}
         generated = 0
         while not limit or generated < limit:
             if self.terminated:
@@ -397,172 +522,12 @@
             else:
                 generated += 1
 
-    def load (self):
-        ifi = None
-        try:
-            ifi = file(self.pickle_to,'r')
-            loaded = pickle.load(ifi)
-        except:
-            (type, value, traceback) = sys.exc_info()
-            print 'Unable to load puzzles: %s: %s' % (str(type), str(value))
-            if ifi:
-                ifi.close()
-            self.load_initial_batch()
-        else:
-            ifi.close()
-            self.puzzles_by_solution= loaded['by_solution']
-            self.names = loaded['names']
-            self.top_name = loaded['metaname']
+    def get_difficulty (self, puz):
+        return sudoku.SudokuRater(puz).difficulty()
 
-    def save (self):
-        directory =  os.path.split(self.pickle_to)[0]
-        if not os.path.exists(directory):
-            os.makedirs(directory)
-        ofi = file(self.pickle_to,'w')
-	try:
-	    sys.setcheckinterval(pow(2, 31)-1)
-	    # Statements in this block are assured to run atomically. 
-	    # The following statement has been known to create thread 
-	    # race conditions where several threads modify the object
-	    # being pickled, resulting in a crash.          - Andreas  
-            pickle.dump({'by_solution':self.puzzles_by_solution,
-                         'names':self.names,
-                         'metaname':self.top_name},
-                         ofi)
-	finally:
-	    sys.setcheckinterval(100)
-        ofi.close()
-
-    def list_difficulties (self):
-        ret = self.all_puzzles.values()
-        ret.sort(lambda a,b: a.value>b.value and 1 or a.value<b.value and -1 or 0)
-        return ret
-
-    def get_difficulty_bounds (self):
-        """Return minimum and maximum difficulty puzzles"""
-        diffs=self.list_difficulties()
-        return diffs[0].value,diffs[-1].value
-
-    def get_puzzle (self,
-                    difficulty,
-                    puzzle_list=None):
-        closest = None
-        ret = None
-        if not puzzle_list: puzzle_list = self.all_puzzles.items()
-        for p,d in puzzle_list:
-            diff = abs(d.value-difficulty)
-            if closest == None or diff < closest:
-                ret = p,d
-                closest = diff
-        return ret
-
-    def get_puzzle_name (self, base_name=_("Puzzle")):
-        if not self.top_name.has_key(base_name):
-            self.top_name[base_name]=1
-        n=self.top_name[base_name]
-        self.top_name[base_name]=n+1
-        return unicode("%s %i" % (base_name, n))
         
-class SudokuTracker:
-
-    """A class to track games.
-
-    We keep track of games that have been started and abandoned, games
-    that have been completed, and games that have yet to be played.
-    """
-    
-    def __init__ (self, sudoku_maker,
-                  pickle_to=os.path.join(DATA_DIR,'games_in_progress')
-                  ):
-        self.sudoku_maker = sudoku_maker
-        self.playing = {}
-        self.finished = {}
-        self.pickle_to = pickle_to
-        self.load()
-
-    def save (self):
-        self.sudoku_maker.save()
-        ofi = file(self.pickle_to,'w')
-        pickle.dump({'playing':self.playing,
-                     'finished':self.finished},
-                   ofi)
-        ofi.close()
-
-    def load (self):
-        if os.path.exists(self.pickle_to):
-            ifi = file(self.pickle_to,'r')
-            loaded = pickle.load(ifi)
-            ifi.close()
-            for attr in 'playing','finished': setattr(self,attr,loaded[attr])
-
-    def game_from_ui (self, ui): return ui.gsd.grid.virgin.to_string()
-
-    def save_game (self, ui):
-        game = self.game_from_ui(ui)
-        jar=saver.jar_game(ui)
-        jar['solution']=self.sudoku_maker.solutions_by_puzzle.get(game,'')
-        jar['saved_at']=time.time()
-        self.playing[game]=jar
-        return game
-
-    def open_game (self, ui, game):
-        saver.open_game(ui,self.playing[game])
-
-    def get_difficulty (self, game):
-        if not self.sudoku_maker.all_puzzles.has_key(game):
-            self.sudoku_maker.all_puzzles[game]=sudoku.SudokuRater(game).difficulty()
-        return self.sudoku_maker.all_puzzles[game]
-
-    def finish_game (self, ui):
-        game = self.game_from_ui(ui)
-        if not self.finished.has_key(game):
-            self.finished[game]=[]
-        self.finished[game].append(
-            {'player':ui.player,
-             'hints':ui.gsd.hints,
-             'impossible_hints':ui.gsd.impossible_hints,
-             'auto_fills':ui.gsd.auto_fills,
-             'time':ui.timer.tot_time,
-             'finish_time':time.time()
-             })
-        if self.playing.has_key(game):
-            del self.playing[game]
-
-    def get_new_puzzle (self, difficulty, repeat_solutions=False):
-        return self.sudoku_maker.get_puzzle(
-            difficulty,
-            puzzle_list=self.list_new_puzzles(repeat_solutions=repeat_solutions)
-            )
-
-    def list_new_puzzles (self,
-                          repeat_solutions=False):
-        """List new puzzles and difficulties.
-        """
-        if not repeat_solutions:
-            keys = filter(lambda x: (not self.playing.has_key(x)
-                                     and not self.finished.has_key(x)),
-                          self.sudoku_maker.all_puzzles.keys())
-        else:
-            keys = []
-            solved = [self.solutions_by_puzzle[p] for p in self.finished.keys()]
-            solved.extend(
-                [jar['solution'] for jar in self.playing.values()]
-                )
-            for solution,puzzles in self.sudoku_maker.puzzles_by_solution.items():
-                if solution in solved: continue
-                else: keys.extend(puzzles)
-        return [(k,self.sudoku_maker.all_puzzles[k]) for k in keys]
-    
 if __name__ == '__main__':
     import time
-    for n in range(20):
-        start = time.time()
-        sg = SudokuGenerator(16)
-        result = sg.make_unique_puzzle()
-        if result: print result
-        else: print 'Failed...'
-        finish = time.time() - start
-        print finish
     #puzzles=sg.generate_puzzles(30)
     #
     #print sg.make_symmetric_puzzle()
@@ -572,9 +537,9 @@
     #    unique.append(unique_maker.next())
     #    print 'Generated Unique...'
     #unique_puzzles=filter(lambda x: sudoku.SudokuSolver(x[0].grid,verbose=False).has_unique_solution(),puzzles)
-    #sm = SudokuMaker()
+    sm = SudokuMaker()
     #st = SudokuTracker(sm)
-
+elif False:    
     usage="""Commands are:
     run: Run sudoku-maker
     len: \# of puzzles generated
Index: gnome-sudoku/src/lib/gnome_sudoku.py
===================================================================
--- gnome-sudoku/src/lib/gnome_sudoku.py	(revision 6846)
+++ gnome-sudoku/src/lib/gnome_sudoku.py	(working copy)
@@ -54,19 +54,20 @@
             '/MenuBar/Tools/ShowImpossibleImplications',
             '/MenuBar/Tools/Tracker',
             '/MenuBar/Game/PuzzleInfo',
-            '/MenuBar/Game/HighScores',
+            #'/MenuBar/Game/HighScores',
             ]
         for p in paths:
             action = ui.uimanager.get_action(p)
             if not action: action = ui.uimanager.get_widget(p)
             if not action: print 'No action at path',p
             else: action.set_sensitive(False)
-        fun(ui,*args,**kwargs)
+        ret = fun(ui,*args,**kwargs)
         for p in paths:
             action = ui.uimanager.get_action(p)
             if not action: action = ui.uimanager.get_widget(p)
             if not action: print 'No action at path',p
             else: action.set_sensitive(True)
+        return ret
     return _
 
 class UI (gconf_wrapper.GConfWrapper):
@@ -74,16 +75,17 @@
     <menubar name="MenuBar">
       <menu name="Game" action="Game">
         <menuitem action="New"/>
+        <!--<menuitem action="ByHand"/>-->
+        <!--<menuitem action="Open"/>-->
+        <!--<separator/>
+        <menuitem action="Save"/>-->
         <separator/>
         <menuitem action="PuzzleInfo"/>
-        <menuitem action="HighScores"/>
-        <!--<menuitem action="Open"/>-->
-        <!--<menuitem action="ByHand"/>-->
-        <separator/>
+        <!--<menuitem action="HighScores"/>-->
+        <separator/>        
         <menuitem action="Print"/>
         <menuitem action="PrintMany"/>
         <separator/>
-        <!--<menuitem action="Save"/>-->
         <menuitem action="Close"/>
         <!--<menuitem action="Quit"/>-->
       </menu>
@@ -123,14 +125,14 @@
       <!--<toolitem action="Quit"/>-->
       <toolitem action="New"/>
       <!--<toolitem action="Open"/>-->
-      <!--<toolitem action="Print"/>-->
+      <toolitem action="Print"/>
       <!--<toolitem action="Save"/>-->
+      <!--<separator/>-->
+      <!--<toolitem action="Clear"/>      -->
+      <!--<toolitem action="ClearNotes"/>-->
       <separator/>
-      <toolitem action="Clear"/>      
-      <toolitem action="ClearNotes"/>
-      <!--<separator/>
       <toolitem action="Undo"/>
-      <toolitem action="Redo"/>-->
+      <toolitem action="Redo"/>
       <separator/>
       <toolitem action="ShowPossible"/>
       <!--<toolitem action="AlwaysShowPossible"/>-->
@@ -155,40 +157,92 @@
                      'bg_custom_color':'',
                      'show_tracker':False,
                      'width': 700,
-                     'height': 675
+                     'height': 675,
+                     'auto_save_interval':60 # auto-save interval in seconds...
                      #'show_notes':0
                      }    
 
     @simple_debug
     def __init__ (self):
-        gtk.window_set_default_icon_name('gnome-sudoku')
-        self.w = gtk.Window()
-        self.timer = ActiveTimer(self.w)
-        self.won = False
         gconf_wrapper.GConfWrapper.__init__(self,
                                             gconf_wrapper.GConf('gnome-sudoku')
                                             )
+        self.setup_gui()
+        self.timer = ActiveTimer(self.w)
+        self.won = False
+        # add the accelerator group to our toplevel window
+        self.worker_connections=[]
+        self.timer.start_timing()
+        # setup sudoku maker...
+        self.sudoku_maker = sudoku_maker.SudokuMaker()
+        self.sudoku_tracker = saver.SudokuTracker()
+        #if not self.sudoku_tracker.playing:
+        #    self.main_actions.get_action('Open').set_sensitive(False)
+        #else:
+        #self.main_actions.get_action('Open').set_sensitive(True)
+        #if not self.sudoku_tracker.are_finished_games():
+        #    self.main_actions.get_action('HighScores').set_sensitive(False)
+        # select an easy puzzle...
+        #puz,d=self.sudoku_maker.get_new_puzzle(self.gconf['difficulty'])
+        #print 'Default to ',puz
+        #self.gsd.change_grid(puz, 9)
+        # generate puzzles while our use is working...        
+        self.show()
+        #print 'Select game!'
+        if self.select_game():
+            # If this return True, the user closed...
+            #print 'select game returned True - exit'
+            self.quit = True
+        else:
+            self.quit = False
+            # Generate puzzles in background...
+            if self.gconf['generate_puzzles_in_background']:
+                gobject.timeout_add(1000,lambda *args: self.start_worker_thread() and True)
+                
+
+    @inactivate_new_game_etc
+    def select_game (self):
+        self.tb.hide()
+        choice = game_selector.NewOrSavedGameSelector().run_swallowed_dialog(self.swallower)
+        #print "The user's choice is ",choice
+        if not choice:
+            return True
+        #print 'choice is ',choice
+        if choice[0] == game_selector.NewOrSavedGameSelector.NEW_GAME:
+            self.gsd.change_grid(choice[1],9)
+        if choice[0] == game_selector.NewOrSavedGameSelector.SAVED_GAME:
+            saver.open_game(self,choice[1])
+        if self.gconf['show_toolbar']: self.tb.show()
+
+    def show (self):
+        self.gsd.show()
+        self.w.show()
+
+    def setup_gui (self):
+        gnome.program_init('gnome-sudoku',VERSION, properties={gnome.PARAM_APP_DATADIR:APP_DATA_DIR})
         self.initialize_prefs()
-        self.player = self.gconf['player']
+        self.setup_main_window()
+        self.gsd = gsudoku.SudokuGameDisplay()
+        self.gsd.connect('puzzle-finished',self.you_win_callback)        
+        self.setup_color()
+        self.setup_actions()
+        self.setup_undo()
+        self.setup_autosave()
+        self.w.add_accel_group(self.uimanager.get_accel_group())
+        self.setup_main_boxes()        
+        self.setup_tracker_interface()
+        self.setup_toggles()        
 
-        self.cleared = [] # used for Undo memory
-        self.cleared_notes = [] # used for Undo memory
-        gnome.program_init('gnome-sudoku',VERSION, properties={gnome.PARAM_APP_DATADIR:APP_DATA_DIR})
+    def setup_main_window (self):
+        gtk.window_set_default_icon_name('gnome-sudoku')
+        self.w = gtk.Window()
         self.w.set_default_size(self.gconf['width'], self.gconf['height'])
         self.w.set_title(APPNAME_SHORT)
         self.w.connect('configure-event',self.resize_cb)
-        self.w.connect('delete-event',self.quit_cb)
-        self.vb = gtk.VBox()
+        self.w.connect('delete-event',self.quit_cb) 
         self.uimanager = gtk.UIManager()
-        if self.gconf['bg_custom_color']:
-            bgcol = self.gconf['bg_custom_color']
-        elif self.gconf['bg_black']:
-            bgcol = 'black'
-        else:
-            bgcol = None
-        self.gsd = gsudoku.SudokuGameDisplay()
-        if bgcol: self.gsd.set_bg_color(bgcol)
-        self.gsd.connect('puzzle-finished',self.you_win_callback)
+
+    def setup_actions (self):
         self.main_actions = gtk.ActionGroup('MainActions')        
         self.main_actions.add_actions([
             ('Game',None,_('_Game')),
@@ -204,12 +258,12 @@
              _('Close Sudoku'),self.quit_cb),
             #('Save',gtk.STOCK_SAVE,_('_Save'),
             # '<Control>s','Save game to play later.',
-            # self.save_game),
+            # self.save_game_cb),
             #('ByHand',gtk.STOCK_EDIT,_('_Enter custom game'),
             # None,_('Enter new puzzle by hand (use this to copy a puzzle from another source).'),
             # self.enter_game_by_hand),
-            #('Open',gtk.STOCK_OPEN,_('_Resume old game'),
-            # '<Control>r',_('Resume a previous saved game.'),
+            #('Open',gtk.STOCK_OPEN,_('Open game'),
+            # '<Control>o',_('Open a saved game from file.'),
             # self.open_game),
             ('Tools',None,_('_Tools')),
             ('View',None,_('_View')),
@@ -223,12 +277,6 @@
             ('Autofill',gtk.STOCK_REFRESH,_('Fill _all squares'),'<Control>a',
              _('Automatically fill in all squares for which there is only one valid value.'),
              self.auto_fill_cb),
-            #('ZoomIn',gtk.STOCK_ZOOM_IN,'_Increase size',
-            # '<Control>plus','Increase the size of numbers and squares',
-            # self.zoom_in_cb),
-            #('ZoomOut',gtk.STOCK_ZOOM_OUT,'_Decrease size',
-            # '<Control>minus','Decrease the size of numbers and squares.',
-            # self.zoom_out_cb),
             ('FullScreen',STOCK_FULLSCREEN,None,
              'F11',None,self.full_screen_cb),
             ('PuzzleInfo',gtk.STOCK_ABOUT,_('Puzzle _Statistics'),
@@ -240,9 +288,9 @@
              None,None,self.show_about),
             ('ShowHelp',gtk.STOCK_HELP, _('_Contents'),
              'F1',None,self.show_help),
-            ('HighScores',None,_('High _Scores'),
-             None,_('Show high scores or replay old games.'),
-             self.show_high_scores_cb),
+            #('HighScores',None,_('High _Scores'),
+            # None,_('Show high scores or replay old games.'),
+            # self.show_high_scores_cb),
             ])
         self.main_actions.add_toggle_actions([
             ('AlwaysShowPossible',
@@ -276,7 +324,7 @@
              ('Undo',gtk.STOCK_UNDO,_('_Undo'),'<Control>z',_('Undo last action')),
              ('Redo',gtk.STOCK_REDO,_('_Redo'),'<Shift><Control>z',_('Redo last action')),
              ('Clear',gtk.STOCK_CLEAR,_('_Clear'),'<Control>b',_("Clear entries you've filled in"),self.clear_cb),
-             ('ClearNotes',gtk.STOCK_CLEAR,_('Clear _Notes'),None,_("Clear notes and hints"),self.clear_notes_cb),             
+             ('ClearNotes',None,_('Clear _Notes'),None,_("Clear notes and hints"),self.clear_notes_cb),             
              # Trackers...
              ('Tracker%s',None,_('No Tracker'),'<Control>0',None,lambda *args: self.set_tracker(-1)),
              ('Generator',None,_('_Generate new puzzles'),None,_('Generate new puzzles.'),
@@ -289,6 +337,9 @@
         self.uimanager.insert_action_group(self.edit_actions,0)
         self.uimanager.add_ui_from_string(self.ui)
 
+    def setup_undo (self):
+        self.cleared = [] # used for Undo memory
+        self.cleared_notes = [] # used for Undo memory
         # Set up our UNDO stuff
         undo_widg = self.edit_actions.get_action('Undo')
         redo_widg = self.edit_actions.get_action('Redo')
@@ -304,24 +355,45 @@
                                        signal='notes-changed',
                                        pre_change_signal='value-about-to-change',
                                        )
-        # add the accelerator group to our toplevel window
-        self.w.add_accel_group(self.uimanager.get_accel_group())
-        mb = self.uimanager.get_widget('/MenuBar')
-        mb.show()
+
+    def setup_color (self):
+        # setup background colors
+        if self.gconf['bg_custom_color']:
+            bgcol = self.gconf['bg_custom_color']
+        elif self.gconf['bg_black']:
+            bgcol = 'black'
+        else:
+            bgcol = None
+        if bgcol: self.gsd.set_bg_color(bgcol)            
+
+    def setup_autosave (self):
+        gobject.timeout_add(1000*(self.gconf['auto_save_interval'] or 60), # in seconds...
+                            self.autosave)
+
+    def setup_main_boxes (self):
+        self.vb = gtk.VBox()
+        # Add menu bar and toolbar...
+        mb = self.uimanager.get_widget('/MenuBar'); mb.show()
         self.vb.pack_start(mb,fill=False,expand=False)
         self.tb = self.uimanager.get_widget('/Toolbar')
-        #self.tb.show()
         self.vb.pack_start(self.tb,fill=False,expand=False)
         self.main_area = gtk.HBox()
         self.swallower = SwappableArea(self.main_area)
         self.swallower.show()
         self.vb.pack_start(self.swallower,True,padding=12)
-
         self.main_area.pack_start(self.gsd,padding=6)
         self.main_actions.set_visible(True)
         self.game_box = gtk.VBox()
         self.main_area.show()
         self.vb.show()
+        self.game_box.show()
+        self.main_area.pack_start(self.game_box,False,padding=12)
+        self.statusbar = gtk.Statusbar(); self.statusbar.show()
+        gobject.timeout_add(500,self.update_statusbar_cb)        
+        self.vb.pack_end(self.statusbar,fill=False,expand=False)        
+        self.w.add(self.vb)
+
+    def setup_by_hand_area (self):
         # Set up area for by-hand editing...
         self.by_hand_label = gtk.Label()
         self.by_hand_label.set_alignment(0,0)
@@ -336,18 +408,9 @@
         self.by_hand_buttonbox.add(self.by_hand_cancel_button)
         self.by_hand_buttonbox.add(self.by_hand_save_button)
         self.game_box.pack_start(self.by_hand_buttonbox,False,padding=18)
-        self.game_box.show()
-        self.by_hand_widgets = [self.by_hand_label,self.by_hand_buttonbox]
-        self.main_area.pack_start(self.game_box,False,padding=12)
-        # Set up trackers
-        self.trackers = {}
-        self.setup_tracker_interface()
-        self.w.add(self.vb)
-        self.statusbar = gtk.Statusbar(); self.statusbar.show()
-        gobject.timeout_add(500,self.update_statusbar_cb)
-        self.vb.pack_end(self.statusbar,fill=False,expand=False)
-        self.worker_connections=[]
-        mb.show()
+        self.by_hand_widgets = [self.by_hand_label,self.by_hand_buttonbox]        
+
+    def setup_toggles (self):
         # sync up toggles with gconf values...
         map(lambda tpl: self.gconf_wrap_toggle(*tpl),
             [('always_show_hints',
@@ -362,50 +425,13 @@
               self.main_actions.get_action('ToggleHighlight')),
              ('show_tracker',
               self.main_actions.get_action('Tracker')),
-             ])
-        self.timer.start_timing()
-        # setup sudoku maker...
-        self.sudoku_maker = sudoku_maker.SudokuMaker()
-        self.sudoku_tracker = sudoku_maker.SudokuTracker(self.sudoku_maker)
-        #if not self.sudoku_tracker.playing:
-        #    self.main_actions.get_action('Open').set_sensitive(False)
-        #else:
-        #    self.main_actions.get_action('Open').set_sensitive(True)
+             ])        
 
-        if not self.sudoku_tracker.finished:
-            self.main_actions.get_action('HighScores').set_sensitive(False)
-        # auto-load
-        try:
-            game = self.gconf['current_game']                
-        except:
-            self.gconf['current_game']=""
-            game = ""
-        '''if game:
-            try:
-                self.sudoku_tracker.open_game(self, game)
-            except:
-                #print 'We appear to have lost ',game
-                try:
-                    self.gsd.load_game(game)
-                except:
-                    puz,d=self.sudoku_tracker.get_new_puzzle(self.gconf['difficulty'])
-        else:
-        '''
-        # select an easy puzzle...
-        puz,d=self.sudoku_tracker.get_new_puzzle(self.gconf['difficulty'])
-        #print 'Default to ',puz
-        self.gsd.change_grid(puz, 9)
-        # generate puzzles while our use is working...
-        if self.gconf['generate_puzzles_in_background']:
-            gobject.timeout_add(1000,lambda *args: self.start_worker_thread() and True)
-        self.gsd.show()
-        
-        self.w.show()
-
     @simple_debug
     def start_worker_thread (self, *args):
-        n_new_puzzles = len(self.sudoku_tracker.list_new_puzzles())
+        n_new_puzzles = self.sudoku_maker.n_puzzles(new=True)
         if n_new_puzzles < self.gconf['minimum_number_of_new_puzzles']:
+            #print 'Generate puzzles'
             self.worker = threading.Thread(target=lambda *args: self.sudoku_maker.work(limit=5))
             self.worker_connections = [
                 self.timer.connect('timing-started',self.sudoku_maker.resume),
@@ -413,7 +439,7 @@
                 ]
             self.worker.start()
         #else:
-        #    print 'We already have ',n_new_puzzles,'!'
+        #    print "Don't generate...",'We already have ',n_new_puzzles,'!'
 
     @simple_debug
     def stop_worker_thread (self, *args):
@@ -429,32 +455,34 @@
         self.gconf['difficulty']=self.gconf['difficulty']+0.1
         self.timer.finish_timing()
         self.sudoku_tracker.finish_game(self)
-        #time_string = "%s (%s active)"%(self.timer.total_time_string(),
-        #                                self.timer.active_time_string()
-        #                                )
-        #sublabel = _("You completed the puzzle in %s")%time_string
-        #sublabel += "\n"
-        #sublabel += ngettext("You got %(n)s hint","You got %(n)s hints",self.gsd.hints)%{'n':self.gsd.hints}
-        #sublabel += "\n"
-        #if self.gsd.impossible_hints:
-        #    sublabel += ngettext("You had %(n)s impossibility pointed out.",
-        #                         "You had %(n)s impossibilities pointed out.",
-        #                         self.gsd.impossible_hints)%{'c':self.gsd.impossible_hints}
-        #if self.gsd.auto_fills:
-        #    sublabel += ngettext("You used the auto-fill %(n)s time",
-        #                         "You used the auto-fill %(n)s times",
-        #                         self.gsd.auto_fills)%{'n':self.gsd.auto_fills}
-        #dialog_extras.show_message("You win!",label="You win!",
-        #                           icon=os.path.join(IMAGE_DIR,'winner2.png'),
-        #                           sublabel=sublabel
-        #                           )
-        hs = game_selector.HighScores(self.sudoku_tracker)
-        hs.highlight_newest=True
+        time_string = "%s (%s active)"%(self.timer.total_time_string(),
+                                       self.timer.active_time_string()
+                                        )
+        sublabel = _("You completed the puzzle in %s")%time_string
+        sublabel += "\n"
+        sublabel += ngettext("You got %(n)s hint","You got %(n)s hints",self.gsd.hints)%{'n':self.gsd.hints}
+        sublabel += "\n"
+        if self.gsd.impossible_hints:
+            sublabel += ngettext("You had %(n)s impossibility pointed out.",
+                                 "You had %(n)s impossibilities pointed out.",
+                                 self.gsd.impossible_hints)%{'c':self.gsd.impossible_hints}
+        if self.gsd.auto_fills:
+            sublabel += ngettext("You used the auto-fill %(n)s time",
+                                 "You used the auto-fill %(n)s times",
+                                 self.gsd.auto_fills)%{'n':self.gsd.auto_fills}
+        dialog_extras.show_message("You win!",label="You win!",
+                                   #icon=os.path.join(IMAGE_DIR,'winner2.png'),
+                                   sublabel=sublabel
+                                   )
+        # High scores is complicated and kind of unnecessary for now...
+        # If we reimplement, we should use the proper gnome-games system.
+        #hs = game_selector.HighScores(self.sudoku_tracker)
+        #hs.highlight_newest=True
         #hs.run_swallowed_dialog(self.swallower)
-        hs.run_dialog()
-        self.main_actions.get_action('HighScores').set_sensitive(True)
+        #print 'Run high scores dialog!'
+        #hs.run_dialog()
+        #self.main_actions.get_action('HighScores').set_sensitive(True)
         #self.gsd.blank_grid()
-        self.stop_game()
         self.new_cb()
 
     @simple_debug
@@ -464,28 +492,46 @@
                 self.gconf[k]
             except:
                 self.gconf[k]=v
+        self.player = self.gconf['player']
 
     @simple_debug
     @inactivate_new_game_etc
     def new_cb (self,*args):
-        gs = game_selector.NewGameSelector(self.sudoku_tracker)
-        gs.difficulty = self.gconf['difficulty']
-        ret =  gs.run_swallowed_dialog(self.swallower)
-        if ret:
-            puz,d = ret
-            self.gconf['difficulty']=d.value
-            self.stop_game()
-            self.gsd.change_grid(puz,9)
-            self.history.clear()
+        if (self.gsd.grid and self.gsd.grid.is_changed() and not self.won):
+            try:
+                if dialog_extras.getBoolean(
+                    label=_("Save this game before starting new one?"),
+                    custom_yes=_("_Save game for later"),
+                    custom_no=_("_Abandon game"),
+                    ):
+                    self.save_game()
+                else:
+                    self.sudoku_tracker.abandon_game(self)
+            except dialog_extras.UserCancelledError:
+                # User cancelled new game
+                return
+        self.do_stop()
+        self.select_game()
+
             
     @simple_debug
     def stop_game (self):
-        #if self.gsd.grid and self.gsd.grid.is_changed():
-        #    self.sudoku_tracker.save_game(self)
-        #    self.main_actions.get_action('Open').set_sensitive(True)
+       if (self.gsd.grid
+            and self.gsd.grid.is_changed()
+            and (not self.won)):
+            try:
+                if dialog_extras.getBoolean(label=_("Save game before closing?")):
+                    self.save_game(self)
+            except dialog_extras.UserCancelledError:
+                return
+            self.do_stop()
+            
+    def do_stop (self):
+        self.gsd.grid = None
         self.tracker_ui.reset()
         self.timer.reset_timer()
         self.timer.start_timing()
+        self.history.clear()        
         self.won = False
         
     @simple_debug
@@ -495,6 +541,15 @@
 
     @simple_debug
     def quit_cb (self, *args):
+        # Offer a save...
+        #try:
+        if (self.gsd.grid
+            and self.gsd.grid.is_changed()
+            and (not self.won)):
+            #and dialog_extras.getBoolean(label=_("Save game before closing?"))):
+            self.save_game(self) # autosave...
+        #except dialog_extras.UserCancelledError:
+        #    return
         if gtk.main_level() > 1:
             # If we are in an embedded mainloop, that means that one
             # of our "swallowed" dialogs is active, in which case we
@@ -526,7 +581,7 @@
             self.gconf['current_game']=''
         if not self.won:
             if not self.gsd.grid:
-                self.gconf['current_game']=''
+                self.gconf['current_game']=''            
         self.stop_worker_thread()
         # allow KeyboardInterrupts, which calls quit_cb outside the main loop
         try:
@@ -554,41 +609,16 @@
     def cancel_handmade_grid (self, *args):
         for w in self.by_hand_widgets: w.hide()
 
-    @simple_debug
-    @inactivate_new_game_etc    
-    def open_game (self, *args):
+    #def save_game_cb (self, *args):
+    #    try:
+    #        self.save_game(*args)
+    #    except dialog_extras.UserCancelledError:
+    #        pass
 
-	#disabled!
-	return;
-	
-        #game_file = dialog_extras.getFileOpen(_("Load saved game"),
-        #                        default_file=os.path.join(DATA_DIR,'games/')
-        #                        )        
-        #saver.unpickle_game(self, game_file)
-        #ifi = file(game_file,'r')
-        #self.gsd.load_game(ifi.read())
-        #ifi.close()
-        puzzl=game_selector.OldGameSelector(self.sudoku_tracker).run_swallowed_dialog(self.swallower)
-        if puzzl:
-            self.stop_game()
-            saver.open_game(self,puzzl)
-            self.history.clear()
-
     @simple_debug
     def save_game (self, *args):
-        save_to_dir=os.path.join(DATA_DIR,'games/')
-        if not os.path.exists(save_to_dir):
-            os.makedirs(save_to_dir)
-        game_number = 1
-        while os.path.exists(
-            os.path.join(save_to_dir,"game%s"%game_number)
-            ):
-            game_number+=1
-        game_loc = os.path.join(save_to_dir,
-                             "game%s"%game_number)
-        saver.pickle_game(self, game_loc)
-        return game_loc
-    
+	self.sudoku_tracker.save_game(self)
+
     @simple_debug
     def zoom_in_cb (self,*args):
         self.gh.change_font_size(multiplier=1.1)
@@ -664,6 +694,7 @@
 
     @simple_debug
     def setup_tracker_interface (self):
+        self.trackers = {}        
         self.tracker_ui = TrackerBox(self)
         self.tracker_ui.show_all()
         self.tracker_ui.hide()
@@ -702,14 +733,8 @@
         puzz = self.gsd.grid.virgin.to_string()
         if (not hasattr(self,'current_puzzle_string') or
             self.current_puzzle_string != puzz):
-            if not self.sudoku_tracker.sudoku_maker.names.has_key(puzz):
-                self.sudoku_tracker.sudoku_maker.names[puzz] = self.sudoku_tracker.sudoku_maker.get_puzzle_name(puzz)
-            self.current_puzzle_string = puzz
-            self.current_puzzle_name = self.sudoku_tracker.sudoku_maker.names[puzz]
-            if len(self.current_puzzle_name)>18: self.current_puzzle_name = self.current_puzzle_name[:17]+u'\u2026'
-            self.current_puzzle_diff = self.sudoku_tracker.get_difficulty(puzz)
-        tot_string = _("Playing ") + self.current_puzzle_name
-        tot_string += " - " + "%s"%self.current_puzzle_diff.value_string()
+            self.current_puzzle_diff = self.sudoku_maker.get_difficulty(puzz)
+	tot_string = _("Playing %(difficulty)s puzzle.")%{'difficulty':self.current_puzzle_diff.value_string()}
         tot_string += " " + "(%1.2f)"%self.current_puzzle_diff.value
         #if self.timer.tot_time or self.timer.tot_time_complete:
         #    time_string = _("%s (%s active)")%(
@@ -747,7 +772,7 @@
                                        )
             return
         puzzle = self.gsd.grid.virgin.to_string()
-        diff = self.sudoku_tracker.get_difficulty(puzzle)
+        diff = self.sudoku_maker.get_difficulty(puzzle)
         information = _("Calculated difficulty: ")
         information += diff.value_string()
         information += " (%1.2f)"%diff.value
@@ -760,15 +785,10 @@
         information += "\n"
         information += _("Amount of trial-and-error required to solve: ")
         information += str(len(diff.guesses))
-        if not self.sudoku_tracker.sudoku_maker.names.has_key(puzzle):
-            self.sudoku_tracker.sudoku_maker.names[puzzle]=self.sudoku_tracker.sudoku_maker.get_puzzle_name(
-                _('Puzzle'))
-        name = self.sudoku_tracker.sudoku_maker.names[puzzle]
         dialog_extras.show_message(parent=self.w,
-                                   title=_("Puzzle Information"),
-                                   label=_("Statistics for %s")%name,
+                                   title=_("Puzzle Statistics"),
+                                   label=_("Puzzle Statistics"),
                                    sublabel=information)
-        
 
     @simple_debug
     def toggle_generator_cb (self, toggle):
@@ -786,6 +806,23 @@
             self.gsd.change_grid(replay_game,9)
 
     @simple_debug
+    def autosave (self):
+        # this is called on a regular loop and will autosave if we
+        # have reason to...
+        if self.gsd.grid and self.gsd.grid.is_changed() and not self.won:
+            self.sudoku_tracker.save_game(self)
+    
+    def offer_to_load_autosaved_file (self):
+    	pass    
+
+    @simple_debug
+    def load_autosave (self, filename):
+        saver.unpickle_game(self,filename)
+        self.history.clear()
+        
+    #def toggle_autosave ():
+
+    @simple_debug
     def show_about (self, *args):
         about = gtk.AboutDialog()
         about.set_name(APPNAME)
@@ -956,17 +993,6 @@
         clearer.perform()
 
 
-class GamesTracker (sudoku_maker.SudokuTracker):
-
-    @simple_debug
-    def __init__ (self, sudoku_maker):
-        SudokuTracker.__init__(self, sudoku_maker)
-
-    @simple_debug
-    def build_model (self):
-        # puzzle / difficulty / % completed / game started / game finished
-        self.model = gtk.TreeModel(str, str )
-
 def start_game ():
     if options.debug: print 'Starting GNOME Sudoku in debug mode'
 
@@ -980,13 +1006,13 @@
         return
 
     u = UI()
+    if not u.quit:
+        try:
+            gtk.main()        
+        except KeyboardInterrupt:
+            # properly quit on a keyboard interrupt...
+            u.quit_cb()
 
-    try:
-        gtk.main()        
-    except KeyboardInterrupt:
-        # properly quit on a keyboard interrupt...
-        u.quit_cb()
-
 def profile_me ():
     print 'Profiling GNOME Sudoku'
     import tempfile,os.path
Index: gnome-sudoku/src/lib/sudoku_thumber.py
===================================================================
--- gnome-sudoku/src/lib/sudoku_thumber.py	(revision 0)
+++ gnome-sudoku/src/lib/sudoku_thumber.py	(revision 0)
@@ -0,0 +1,128 @@
+import cairo
+import pango
+import tempfile
+import gtk
+
+SUDOKU_SIZE = 9
+N_BOXES = 3
+FONT_SIZE = 9
+SQUARE_SIZE = 11
+THICK = 2 #SIZE/33 or 1
+BORDER = THICK*2
+THIN = 1 #SIZE/100 or 1
+PENCIL_GREY = (0.3,0.3,0.3)
+LINE_GREY = (0.4,0.4,0.4)
+SIZE = (
+    (2 * (BORDER+THICK)) # OUTER BORDER
+    +
+    ((N_BOXES - 1) * THICK) # INNER THICK LINES
+    +
+    (SQUARE_SIZE * SUDOKU_SIZE) # WHITE SPACE IN SQUARES
+    +
+    (SUDOKU_SIZE - N_BOXES - 1)
+    )
+    
+(SQUARE_SIZE * SUDOKU_SIZE) + (N_BOXES)*THICK + (SUDOKU_SIZE-N_BOXES)*THIN
+
+sudoku = [[0, 0, 2, 3, 4, 5, 6, 0, 0]]*SUDOKU_SIZE
+played = [[1,2,0,0,0,0,0,0,0,0]]+[[0,0,0,0,0,0,0,0,0,0]]*8
+
+def make_image_surface (sudoku, played, highlight_color):
+    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, SIZE, SIZE)
+    cr = cairo.Context(surface)
+    cr.set_line_width(BORDER)
+    cr.set_line_join(cairo.LINE_JOIN_ROUND)
+    cr.rectangle(BORDER*.5,
+                 BORDER*.5,
+                 (SIZE-(BORDER)),
+                 (SIZE-(BORDER)),
+        )
+    #print 'HIGHLIGHT: ',BORDER*0.5,'-',SIZE-BORDER
+    cr.set_source_rgb(1,1,1)
+    cr.fill_preserve()
+    cr.set_source_rgb(*highlight_color)
+    cr.stroke()
+    cr.set_source_rgb(*LINE_GREY)
+    cr.set_line_width(THICK)
+    #cr.set_line_join(cairo.LINE_JOIN_MITER)
+    cr.rectangle(BORDER,
+                 BORDER,
+                 (SIZE-(BORDER+2*THICK)),
+                 (SIZE-(BORDER+2*THICK)),
+        )
+    cr.stroke()
+    small_size = SIZE / float(SUDOKU_SIZE)
+    position = BORDER + THICK
+    pos = {}
+    pos[0] = position + (SQUARE_SIZE/2.0)
+    #print 'Full size=',SIZE
+    #print 'border =',BORDER
+    #print 'thin lines=',THIN
+    #print 'thick lines=',THICK
+    #print 'square size=',SQUARE_SIZE
+    last_line = 0
+    for n in range(1,SUDOKU_SIZE):
+        if n % N_BOXES == 0:
+            cr.set_line_width(THICK)
+            position += SQUARE_SIZE + last_line/2.0 + THICK/2.0
+            last_line = THICK
+            #print 'THICK',
+        else:
+            cr.set_line_width(THIN)
+            position += SQUARE_SIZE + last_line/2.0 + THIN/2.0
+            last_line = THIN
+            #print 'THIN ',
+        pos[n] = position + ((last_line + SQUARE_SIZE)/2.0)
+        #print 'draw at ',position
+        cr.move_to(BORDER,position)
+        cr.line_to(SIZE-BORDER,position)
+        cr.move_to(position,BORDER)
+        cr.line_to(position,SIZE-BORDER)
+        cr.stroke()
+    cr.set_font_size(FONT_SIZE)
+    for x in range(SUDOKU_SIZE):
+        for y in range(SUDOKU_SIZE):
+            cr.move_to(pos[x],pos[y])
+            #cr.arc(pos[x],pos[y],SQUARE_SIZE/3.0,0.1,0)
+            #cr.stroke()
+            letter = None
+            if sudoku[y][x]:
+                letter = str(sudoku[y][x])
+                cr.select_font_face("",
+                         cairo.FONT_SLANT_NORMAL,
+                         cairo.FONT_WEIGHT_BOLD)
+                         #cairo.FONT_WEIGHT_NORMAL)
+                cr.set_source_rgb(0,0,0)    
+                xbearing,ybearing,width,height,xadvance,yadvance = (
+                    cr.text_extents(letter)
+                    )                
+
+            elif played and played[y][x]:
+                cr.select_font_face("Times",
+                                    cairo.FONT_SLANT_ITALIC,
+                                    cairo.FONT_WEIGHT_NORMAL)
+                cr.set_source_rgb(*PENCIL_GREY)
+                letter = str(played[y][x])
+                xbearing,ybearing,width,height,xadvance,yadvance = (
+                    cr.text_extents(letter)
+                    )
+            if letter:
+                cr.move_to(pos[x]-(xadvance/2.0),
+                           pos[y]+(height/2.0))
+                cr.show_text(letter)
+    return surface
+
+def make_pixbuf (sudoku, played, highlight_color):
+    surf = make_image_surface(sudoku,played,highlight_color)
+    fn = tempfile.mktemp('.png')
+    surf.write_to_png(fn)
+    del surf
+    return gtk.gdk.pixbuf_new_from_file(fn)
+
+if __name__ == '__main__':
+    make_image_surface(sudoku,played,
+                       (1.0,0.5,0.5)).write_to_png(
+        '/home/tom/Desktop/test.png'
+        )
+                                               
+                   
Index: gnome-sudoku/src/lib/colors.py
===================================================================
--- gnome-sudoku/src/lib/colors.py	(revision 6846)
+++ gnome-sudoku/src/lib/colors.py	(working copy)
@@ -54,3 +54,18 @@
     h,s,v = rgb_to_hsv(r,g,b,maxval=maxval)
     h,s,v = rotate_hue (h,s,v,rotate_by=rotate_by)
     return hsv_to_rgb(h,s,v)
+
+def color_hex_to_float (hstr):
+    hstr = hstr.strip('#')
+    if len(hstr)==6:
+        r = hstr[:2]
+        g = hstr[2:4]
+        b = hstr[4:]
+        maxval = 255
+    elif len(hstr)==3:
+        r,g,b = hstr
+        maxval = 15
+    else:
+        raise ValueError('%s is not a 6 or 3 digit color string'%hstr)
+    r,g,b = int(r,16),int(g,16),int(b,16)
+    return r/float(maxval),g/float(maxval),b/float(maxval)

Property changes on: gnome-sudoku/src/lib/gtk_goodies
___________________________________________________________________
Name: svn:ignore
   - Makefile
Makefile.in

   + Makefile
Makefile.in
*.pyc


Index: gnome-sudoku/src/lib/gtk_goodies/dialog_extras.py
===================================================================
--- gnome-sudoku/src/lib/gtk_goodies/dialog_extras.py	(revision 6846)
+++ gnome-sudoku/src/lib/gtk_goodies/dialog_extras.py	(working copy)
@@ -5,6 +5,9 @@
 H_PADDING=12
 Y_PADDING=12
 
+class UserCancelledError (Exception):
+    pass
+
 class ModalDialog (gtk.Dialog):
     def __init__ (self, default=None, title="", okay=True, label=False, sublabel=False, parent=None, cancel=True, modal=True, expander=None, image=None):
         """Our basic class. We allow for a label. Possibly an expander
@@ -404,6 +407,10 @@
         if self.cancel_returns != None:
             self.ret = self.cancel_returns
             self.okcb()
+        else:
+            self.hide()
+            if self.modal: gtk.main_quit()
+            raise UserCancelledError("%s Cancelled"%self)
 
     def nocb (self, *args):
         self.ret=False
@@ -569,7 +576,7 @@
     d = BooleanDialog(*args,**kwargs)
     retval = d.run()
     if retval==None:
-        raise "getBoolean dialog cancelled!"
+        raise UserCancelledError("getBoolean dialog cancelled!")
     else:
         return retval
 
@@ -597,9 +604,12 @@
     fsd = gtk.FileChooserDialog(*args,**kwargs)
     fsd.set_default_response(gtk.RESPONSE_OK)
     if default_file:
-        path,name = os.path.split(default_file)
-        fsd.set_current_folder(path)
-        fsd.set_current_name(name)
+        if os.path.isdir(default_file):
+            fsd.set_current_folder(default_file)
+        else:
+            path,name = os.path.split(default_file)
+            fsd.set_current_folder(path)
+            fsd.set_current_name(name)
     if fsd.run() == gtk.RESPONSE_OK:
         fsd.hide()
         return fsd.get_filename()
Index: gnome-sudoku/src/lib/game_selector.py
===================================================================
--- gnome-sudoku/src/lib/game_selector.py	(revision 6846)
+++ gnome-sudoku/src/lib/game_selector.py	(working copy)
@@ -1,46 +1,169 @@
 import gtk, gobject, time
-import sudoku
+import sudoku, saver, sudoku_maker, random
+from sudoku import DifficultyRating as DR
+import sudoku_thumber
 import gnomeprint
 from gettext import gettext as _
-from timer import format_time,format_date
+from timer import format_time,format_date,format_friendly_date,format_time_compact
 from defaults import *
+from colors import color_hex_to_float
 from gtk_goodies import gconf_wrapper
 
-def _compareGameNames(model, iter1, iter2, nameColumn):
-    # Don't sort child nodes
-    if model.iter_parent(iter1) is not None or model.iter_parent(iter2) is not None:
-        return 0
+def color_from_difficulty (diff):
+    if diff < DR.easy_range[1]:
+        if diff < DR.easy_range[1]/3: c='#8ae234' # green
+        elif diff < 2*DR.easy_range[1]/3: c='#73d216'
+        else: c='#4e9a06'
+    elif diff < DR.medium_range[1]:
+        span = DR.medium_range[1] - DR.easy_range[1]
+        if diff < DR.medium_range[0]+(span/3): c='#204a87' # sky blue
+        elif diff < DR.medium_range[0]+(2*(span/3)): c='#3465a4'
+        else: c='#729fcf'
+    elif diff < DR.hard_range[1]:
+        span = DR.hard_range[1] - DR.medium_range[1]
+        if diff < DR.hard_range[0] + span/3: c='#fcaf3e' # orange
+        elif diff < DR.hard_range[0] + span*2/3: c='#f57900'
+        else: c='#ce5c00'
+    else:
+        span = DR.very_hard_range[1] - DR.hard_range[1]
+        if diff < DR.very_hard_range[0] + span/3:
+            c='#ef2929' # scarlet red
+        elif diff < DR.very_hard_range[0]+ span*2/3:
+            c='#cc0000'
+        else:
+            c='#a40000'  
+    #print 'diff=',diff,'color=',c
+    return color_hex_to_float(c)
 
-    name1 = model.get_value(iter1, nameColumn)
-    name2 = model.get_value(iter2, nameColumn)
+class NewOrSavedGameSelector (gconf_wrapper.GConfWrapper):
 
-    # Compare each word treating numbers as numbers not strings
-    words1 = name1.split()
-    words2 = name2.split()
-    for i in xrange(min(len(words1), len(words2))):
-        w1 = words1[i]
-        w2 = words2[i]
-        
-        try:
-            i1 = int(w1)
-        except ValueError:
-            i1 = None
-        try:
-            i2 = int(w2)
-        except ValueError:
-            i2 = None
+    NEW_GAME = 0
+    SAVED_GAME = 1
 
-        if i1 is None or i2 is None:
-            if w1 < w2:
-                return -1
-            elif w2 > w1:
-                return 1
+    glade_file = os.path.join(GLADE_DIR,'select_game.glade')
+    
+    def __init__ (self, sudokuMaker=None, gconf = None):
+        if gconf:
+            gconf_wrapper.GConfWrapper.__init__(self,gconf)
+        self.sudoku_maker = sudokuMaker or sudoku_maker.SudokuMaker()
+    
+    def setup_dialog (self):
+        self.glade = gtk.glade.XML(self.glade_file)
+        self.dialog = self.glade.get_widget('dialog1')
+        self.dialog.set_default_response(gtk.RESPONSE_CANCEL)
+        self.dialog.connect('close',self.close)
+        self.dialog.hide()
+        self.saved_game_view = self.glade.get_widget('savedGameIconView')
+        self.saved_game_widgets = [
+            self.saved_game_view,
+            self.glade.get_widget('savedGameLabel')
+            ]
+        self.glade.get_widget('savedGameLabel').set_mnemonic_widget(
+            self.saved_game_view
+            )
+        self.new_game_view = self.glade.get_widget('newGameIconView')
+        self.glade.get_widget('newGameLabel').set_mnemonic_widget(
+            self.new_game_view
+            )
+        self.make_new_game_model()
+        self.new_game_view.set_model(self.new_game_model)
+        self.new_game_view.set_markup_column(0)
+        self.new_game_view.set_pixbuf_column(1)
+        selected_puzzle = None
+        self.make_saved_game_model()
+        if len(self.saved_game_model)==0:
+            for w in self.saved_game_widgets: w.hide()
         else:
-            if i1 != i2:
-                return i1 - i2
+            self.saved_game_model.set_sort_column_id(2,gtk.SORT_DESCENDING)
+            self.saved_game_view.set_model(self.saved_game_model)
+            self.saved_game_view.set_markup_column(0)
+            self.saved_game_view.set_pixbuf_column(1)
+        for view in self.saved_game_view, self.new_game_view:
+            view.set_item_width(150)
+            view.set_columns(4)
+            view.set_spacing(12)
+            view.set_selection_mode(gtk.SELECTION_SINGLE)
+        self.saved_game_view.connect('item-activated',self.saved_item_activated_cb)
+        self.new_game_view.connect('item-activated',self.new_item_activated_cb)
+
+    def make_new_game_model (self):
+        # Description, Pixbuf, Puzzle (str)
+        self.new_game_model = gtk.ListStore(str,gtk.gdk.Pixbuf,str)        
+        for cat in DR.ordered_categories:
+            rng = DR.categories[cat]; label = DR.label_by_cat[cat]
+            puzzle,diff = self.sudoku_maker.get_new_puzzle(.01*random.randint(*[r*100 for r in rng]))
+            #print 'Got new puzzle for ',cat,'difficulty:',diff
+            grid = sudoku.sudoku_grid_from_string(puzzle).grid
+            self.new_game_model.append(('<b><i>'+label+'</i></b>',
+                                        sudoku_thumber.make_pixbuf(grid,
+                                                                   None,
+                                                                   color_from_difficulty(diff.value)
+                                                                   ),
+                                        puzzle
+                                        ))
+
+    def make_saved_game_model (self):
+        # Description, Image, Last-Access time (for sorting), Puzzle (jar)
+        self.saved_game_model = gtk.ListStore(str,gtk.gdk.Pixbuf,int,gobject.TYPE_PYOBJECT)
+        t = saver.SudokuTracker()
+        for g in t.list_saved_games():
+            #print 'game',g
+            game = g['game'].split('\n')[0]
+            grid = sudoku.sudoku_grid_from_string(game)
+            sr = sudoku.SudokuRater(grid.grid)
+            sdifficulty = sr.difficulty()
+            desc = "<b><i>%s</i></b>\n<span size='small'><i>Last played %s</i>\n<i>Played for %s.</i></span>"%(
+                _("%s puzzle")%sdifficulty.value_string(),
+                format_friendly_date(g['saved_at']),
+                format_time(g['timer.tot_time'],round_at=15,friendly=True)
+                )
+            #print 'Adding to saved...',g
+            self.saved_game_model.append((
+                desc,
+                sudoku_thumber.make_pixbuf(grid.grid,
+                                           sudoku.sudoku_grid_from_string(g['game'].split('\n')[1].replace(' ','')).grid,
+                                           color_from_difficulty(sdifficulty.value)
+                                           ),
+                g['saved_at'],
+                g
+                ))
+
+    def new_item_activated_cb (self, iconview, path):
+        self.play_game(iconview.get_model()[path][2])
         
-    return 0
+    def saved_item_activated_cb (self, iconview, path):
+        self.resume_game(iconview.get_model()[path][3])
 
+    def resume_game (self, jar):
+        self.puzzle = (self.SAVED_GAME, jar)
+        self.dialog.emit('response',gtk.RESPONSE_OK)
+
+    def play_game (self, puzzle):
+        self.puzzle = (self.NEW_GAME,puzzle)
+        self.dialog.emit('response',gtk.RESPONSE_OK)
+        
+    def close (self):
+        self.dialog.emit('response',gtk.RESPONSE_CLOSE)        
+
+    def handle_response (self, response):
+        #print 'handle_response',response
+        if response==gtk.RESPONSE_OK:
+            #print 'Returning ',self.puzzle
+            return self.puzzle
+        else:
+            #print 'handle_response returning',None
+            return None    
+
+    def run_swallowed_dialog (self, swallower):
+        self.setup_dialog()
+        return self.handle_response(
+            swallower.run_dialog(self.dialog)
+            )
+
+    def run_dialog (self):
+        self.setup_dialog()
+        return self.handle_response(self.dialog.run())
+
 class GameSelector (gconf_wrapper.GConfWrapper):
 
     def __init__ (self, sudoku_tracker, gconf=None):
@@ -77,443 +200,78 @@
         else:
             return None
 
-class NewGameSelector (GameSelector):
-    glade_file = os.path.join(GLADE_DIR,'new_game.glade')
-    difficulty = 0
+class GamePrinter (gconf_wrapper.GConfWrapper):
 
-    def setup_dialog (self):
-        GameSelector.setup_dialog(self)
-        self.dialog.set_default_response(gtk.RESPONSE_OK)
-        self.adj,self.hscale = self.setup_hscale('hscale1')
-        self.adj.set_value(self.difficulty)
-        
-    def setup_hscale (self, scalename):
-        hscale = self.glade.get_widget(scalename)
-        adj = hscale.get_adjustment()
-        bounds = [0.0,0.9]
-        real_bounds = self.sudoku_tracker.sudoku_maker.get_difficulty_bounds()
-        if real_bounds[1]>bounds[1]: bounds[1]=real_bounds[1]
-        if real_bounds[0]<bounds[0]: bounds[0]=real_bounds[0]
-        adj.lower,adj.upper = bounds
-        adj.step_increment = (bounds[1]-bounds[0])/20
-        adj.page_increment = adj.step_increment*10
-        return adj,hscale
-
-    def make_model (self):
-        # puzzle [0], difficulty [1], value string [2], other string
-        # [3], diff value (float) [4], game name [5]
-        self.model = gtk.TreeStore(str, gobject.TYPE_PYOBJECT, str, str, float, str)
-        self.model.set_sort_func(5, _compareGameNames, 5)
-
-    def add_puzzle_to_model (self, p, d):
-        """Add puzzle (with difficulty object d) to our treeview.
-        """
-        if not self.sudoku_tracker.sudoku_maker.names.has_key(p):
-            self.sudoku_tracker.sudoku_maker.names[p]=self.sudoku_tracker.sudoku_maker.get_puzzle_name(
-                _('Puzzle'))
-        itr = self.model.append(None,
-                                [p, # puzzle
-                                 d, # difficulty                                     
-                                 d.value_string(),
-                                 None,
-                                 d.value,
-                                 self.sudoku_tracker.sudoku_maker.names[p]
-                                 ])
-        # now we enumerate some details...
-        for label,prop in [(_('Squares instantly fillable by filling: '),
-                            d.instant_fill_fillable),
-                           (_('Squares instantly fillable by elimination: '),
-                            d.instant_elimination_fillable),
-                           (_('Number of trial-and-errors necessary to solve: '),
-                            len(d.guesses)),
-                           (_('Difficulty value: '),
-                            d.value),
-                           ]:
-            self.model.append(itr, [None,None,str(prop),None,0,label])
-
-    def setup_tree (self):
-        # puzzle / difficulty / diff value / name
-        self.make_model()
-        for puzzobj in self.sudoku_tracker.list_new_puzzles():
-            self.add_puzzle_to_model(*puzzobj)
-        self.setup_treeview_columns()
-        self.model.set_sort_column_id(5, gtk.SORT_ASCENDING)
-        
-    def setup_treeview_columns (self):
-        col0 = gtk.TreeViewColumn(_('Name'),gtk.CellRendererText(),text=5)
-        col0.set_sort_column_id(5)
-        col1 = gtk.TreeViewColumn(_("Difficulty"),gtk.CellRendererText(),text=2)
-        col1.set_sort_column_id(4)
-        #col2 = gtk.TreeViewColumn("Detail",gtk.CellRendererText(),text=3)
-        #col2.set_sort_column_id(4)
-        self.tv.append_column(col0)
-        self.tv.append_column(col1)
-        #self.tv.append_column(col2)
-        self.tv.set_model(self.model)
-        self.tv.get_selection().connect('changed',self.selection_changed_cb)
-
-    def get_puzzle (self):
-        diff = self.hscale.get_value()
-        return self.sudoku_tracker.get_new_puzzle(diff)
-        
-    def selection_changed_cb (self, selection):
-        mod,itr = selection.get_selected()
-        if itr is None:
-            return
-        while mod.iter_parent(itr):
-            itr = mod.iter_parent(itr)
-        difficulty = mod.get_value(itr,4)
-        self.adj.set_value(difficulty)
-
-
-class OldGameSelector (GameSelector):
-    glade_file = os.path.join(GLADE_DIR,'open_game.glade')
-
-    def setup_tree (self):
-        rend = gtk.CellRendererText()
-        col0 = gtk.TreeViewColumn(_('Name'),rend,text=8)
-        col0.set_sort_column_id(8)
-        self.tv.append_column(col0)
-        col1=gtk.TreeViewColumn(_("Difficulty"),rend,text=2)
-        col1.set_sort_column_id(3)
-        self.tv.append_column(col1)
-        self.tv.insert_column_with_data_func(1, # position
-                                             _('Started'),# title
-                                             gtk.CellRendererText(), # renderer,
-                                             self.cell_data_func,
-                                             4) # column
-        self.tv.get_column(1).set_sort_column_id(4)
-        self.tv.insert_column_with_data_func(2, # position
-                                             _('Last Played'),# title
-                                             gtk.CellRendererText(), # renderer,
-                                             self.cell_data_func,
-                                             5) # column
-        self.tv.get_column(2).set_sort_column_id(5)
-        col2 = gtk.TreeViewColumn(_("Status"),rend,text=6)
-        self.tv.append_column(
-            col2
-            )
-        col2.set_sort_column_id(7)
-        self.setup_model()
-        self.tv.set_model(self.model)
-        self.tv.get_selection().set_mode(gtk.SELECTION_BROWSE)
-        iter = self.model.get_iter_first()
-        if iter is not None:
-            self.tv.get_selection().select_iter(iter)
-        self.tv.get_selection().connect('changed',self.selection_changed_cb)
-        self.selection_changed_cb(self.tv.get_selection())
-
-    def selection_changed_cb (self, selection):
-        self.dialog.set_response_sensitive(gtk.RESPONSE_OK,
-                                           selection.get_selected() and True or False)
-
-    def setup_model (self):
-        self.model = gtk.TreeStore(str,# game (0)
-                                   gobject.TYPE_PYOBJECT,# jar (1)
-                                   str,# difficulty (2)
-                                   float,# diffval (3)
-                                   float,# start date (4)
-                                   float, # finish date (5)
-                                   str,# status (6)
-                                   float,# status val (7)
-                                   str) # name (8)
-        for game,jar in self.sudoku_tracker.playing.items():
-            diff = self.sudoku_tracker.get_difficulty(game)
-            if jar.has_key('printed') and jar['printed']:
-                status=_('Printed %s ago')%format_time(
-                    time.time()-jar['printed_at'],
-                    round_at=2)
-                status_val = 0
-                start_time=jar['printed_at']
-                finish_time=jar['printed_at']
-                tot_time=None
-            else:
-                start_time = jar['timer.__absolute_start_time__']
-                finish_time = jar.get('saved_at',time.time())
-                status_val = jar['timer.tot_time']
-                status = _("Played for %s")%format_time(jar['timer.tot_time'],round_at=2)
-            if not self.sudoku_tracker.sudoku_maker.names.has_key(game):
-                self.sudoku_tracker.sudoku_maker.names[game]=self.sudoku_tracker.sudoku_maker.get_puzzle_name(
-                    _('Puzzle')
-                    )
-            name = self.sudoku_tracker.sudoku_maker.names[game]
-            self.model.append(None,
-                              [game,
-                               jar,
-                               diff and diff.value_string() or None,
-                               diff and diff.value or 0,
-                               start_time,
-                               finish_time,
-                               status,
-                               status_val, # total time
-                               name
-                               ])
-        self.model.set_sort_func(8, _compareGameNames, 8)
-        self.model.set_sort_column_id(8, gtk.SORT_ASCENDING)
-
-    def cell_data_func (self, tree_column, cell, model, titer, data_col):
-        val = model.get_value(titer,data_col)
-        curtime = time.time()
-        # within 18 hours, return in form 4 hours 23 minutes ago or some such
-        if curtime - val < 18 * 60 * 60:
-            cell.set_property('text',
-                              _("%s ago")%format_time(curtime-val,round_at=1))
-            return
-        tupl=time.localtime(val)
-        if curtime - val <  7 * 24 * 60 * 60:
-            cell.set_property('text',
-                              time.strftime('%A %T',tupl))
-            return
-        else:
-            cell.set_property('text',
-                              time.strftime('%D %T',tupl))
-            return
-
-    def get_puzzle (self):
-        mod,itr = self.tv.get_selection().get_selected()
-        if itr is None:
-            return None
-        jar = mod.get_value(itr,1)
-        return jar
-    
-    
-class HighScores (GameSelector):
-    glade_file = os.path.join(GLADE_DIR,'high_scores.glade')
-
-    highlight_newest = False
-    
-    def setup_tree (self):
-        self.setup_treemodel()
-        rend = gtk.CellRendererText()        
-        rend.connect('edited',self.player_edited_cb)
-        col = gtk.TreeViewColumn(_('Player'),rend,text=0,
-                                 editable=6,
-                                 weight=6)
-        col.set_sort_column_id(0)
-        self.tv.append_column(col)
-        col2 = gtk.TreeViewColumn(_('Score'),rend,text=1)
-        col2.set_sort_column_id(2)
-        self.tv.append_column(col2)
-        col3 = gtk.TreeViewColumn(_('Date'),rend,text=3)
-        col3.set_sort_column_id(4)
-        self.tv.append_column(col3)
-        self.tv.set_model(self.model)
-
-    def run_swallowed_dialog (self, swallower):
-        self.setup_dialog()
-        swallower.swallow_dialog(self.dialog)
-        swallower.set_current_page(swallower.swallowed[self.dialog])
-        self.highlight()
-        return self.handle_response(swallower.run_dialog(self.dialog))
-
-    def run_dialog (self):
-        self.setup_dialog()
-        self.dialog.show()
-        self.highlight()
-        ret = self.dialog.run()
-        self.dialog.hide()
-        if ret==0:
-            return self.get_puzzle()
-
-    def setup_treemodel (self):
-        # Name, Score, Score (float), Date, Date(float), Puzzle (str), Highlighted, Finisher (PYOBJ), Number
-        self.model = gtk.TreeStore(str,str, float, str, float,str,int,gobject.TYPE_PYOBJECT)
-        most_recent = (None,None)
-        for game,finishers in self.sudoku_tracker.finished.items():
-            for finisher in finishers:
-                try:
-                    name = self.sudoku_tracker.sudoku_maker.names[game]
-                except KeyError:
-                    name = _('Not in database')
-                try:
-                    puzzle = self.sudoku_tracker.sudoku_maker.all_puzzles[game]
-                except KeyError:
-                    difficulty = _('Unknown difficulty')
-                else:
-                    difficulty = '%s (%f)' % (puzzle.value_string(), puzzle.value)
-                
-                score=self.calculate_score(game,finisher)
-                finish_time = finisher['finish_time']           
-                itr=self.model.append(None,
-                                  [finisher['player'],
-                                   str(int(score)),
-                                   score,
-                                   #time.strftime("%H:%M %A ",time.localtime(finisher['finish_time'])),
-                                   format_date(finisher['finish_time']),
-                                   finish_time,
-                                   game,
-                                   0,
-                                   finisher,
-                                   ])
-                if finish_time > most_recent[0]: most_recent = (finish_time,itr)
-
-                for label,detail in [(_('Puzzle'), name),
-                                     (_('Difficulty'), difficulty),
-                                     (_('Hints'),'hints'),
-                                     (_('Warnings about unfillable squares'),
-                                      'impossible_hints'),
-                                     (_('Auto-fills'),'auto_fills'),
-                                     (_('Finished in'),format_time(finisher['time']))]:
-                    if finisher.has_key(detail):
-                        detail = finisher[detail]
-                    self.model.append(itr,
-                                      [label, detail, 0, None, 0,None,0,None])
-        self.model.set_sort_func(0, _compareGameNames, 0)
-        self.model.set_sort_column_id(2, gtk.SORT_DESCENDING)
-        
-        if self.highlight_newest:
-            itr = most_recent[1]
-            if itr:
-                self.model.set_value(itr,6,1)
-                self.highlight_path = self.model.get_path(itr)
-            else:
-                print 'We are supposed to highlight newest, but there is no newest!'
-
-    def highlight (self):
-        if hasattr(self,'highlight_path'):
-            self.glade.get_widget('replay').hide()
-            self.tv.expand_row(self.highlight_path,True)
-            def start_editing ():
-                self.tv.set_cursor(self.highlight_path,
-                                   focus_column=self.tv.get_column(0),
-                                   start_editing=True)
-            gobject.idle_add(start_editing)
-
-    def calculate_score (self, puzzl, finisher):
-        diff = self.sudoku_tracker.get_difficulty(puzzl)
-        time_bonus = (60*60*3.5/(finisher['auto_fills']+1))/finisher['time']
-        if time_bonus < 1: time_bonus = 1
-        score = diff.value * 100
-        if score <= 10: score = 5 # minimum score of 5
-        score = score * time_bonus
-        score = score - finisher['auto_fills']*10
-        score = score - finisher['impossible_hints']*0.5
-        score = score - finisher['hints']*0.5
-        if score < 0: score = 0
-        return score
-
-    def player_edited_cb (self, renderer, path_string, text):
-        self.model[path_string][0]=text
-        self.model[path_string][7]['player']=text
-        
-    def get_puzzle (self):
-        mod,itr = self.tv.get_selection().get_selected()
-        if not itr:
-            return None
-        while mod.iter_parent(itr):
-            itr = mod.iter_parent(itr)
-            if not itr: return None
-        return mod.get_value(itr,5)
-
-class GamePrinter (NewGameSelector):
-
     glade_file = os.path.join(GLADE_DIR,'print_games.glade')
 
     initial_prefs = {'sudokus_per_page':2,
                      'print_multiple_sudokus_to_print':4,
                      'print_minimum_difficulty':0,
-                     'print_maximum_difficulty':0.9}
+                     'print_maximum_difficulty':0.9,
+                     'print_easy':True,
+                     'print_medium':True,
+                     'print_hard':True,
+                     'print_very_hard':True,
+                     }
 
-    def __init__ (self, sudoku_tracker, gconf):
-        self.gconf = gconf # we'll need gconf to store printing settings...
-        GameSelector.__init__(self,sudoku_tracker,gconf)
-
-    def setup_dialog (self):
-        GameSelector.setup_dialog(self)
-        widgs = ['sudokusToPrintSpinButton',
-                 'sudokusPerPageSpinButton',
-                 'labelGamesToggle',
-                 'markAsPlayedToggle',
-                 'includeOldGamesToggle']        
-        for w in widgs: setattr(self,w,self.glade.get_widget(w))
-        # sync up our widgets with gconf keys
-        for n,t in [('mark_printed_as_played','markAsPlayedToggle'),
-                    ('label_games','labelGamesToggle'),
-                    ('print_already_played_games','includeOldGamesToggle')
-                    ]:
-            self.gconf_wrap_toggle(n,getattr(self,t))
-        self.min_adj,self.min_scale = self.setup_hscale('minimumScale')
-        self.max_adj,self.max_scale = self.setup_hscale('maximumScale')
-        for n,a in [('print_multiple_minimum_difficulty',self.min_adj),
-                    ('print_multiple_maximum_difficulty',self.max_adj),
-                    ('print_multiple_sudokus_to_print',self.sudokusToPrintSpinButton.get_adjustment()),
-                    ('sudokus_per_page',self.sudokusPerPageSpinButton.get_adjustment())]:
-            self.gconf_wrap_adjustment(n,a)
+    def __init__ (self, sudoku_maker, gconf):
+        gconf_wrapper.GConfWrapper.__init__(self,gconf)
+        self.sudoku_maker = sudoku_maker
+        self.glade = gtk.glade.XML(self.glade_file)
+        # Set up toggles...
+        for key,wname in [('mark_printed_as_played','markAsPlayedToggle'),
+                          ('print_already_played_games','includeOldGamesToggle'),
+                          ('print_easy','easyCheckButton'),
+                          ('print_medium','mediumCheckButton'),
+                          ('print_hard','hardCheckButton'),
+                          ('print_very_hard','very_hardCheckButton'),                          
+                          ]:
+            setattr(self,wname,self.glade.get_widget(wname))
+            try: assert(getattr(self,wname))
+            except: raise AssertionError('Widget %s does not exist'%wname)
+            self.gconf_wrap_toggle(key,getattr(self,wname))
+        self.sudokusToPrintSpinButton = self.glade.get_widget('sudokusToPrintSpinButton')
+        self.sudokusPerPageSpinButton = self.glade.get_widget('sudokusPerPageSpinButton')
+        for key,widg in [('print_multiple_sudokus_to_print',self.sudokusToPrintSpinButton.get_adjustment()),
+                         ('sudokus_per_page',self.sudokusPerPageSpinButton.get_adjustment())
+                         ]:
+            self.gconf_wrap_adjustment(key,widg)
+        self.dialog = self.glade.get_widget('dialog')
         self.dialog.set_default_response(gtk.RESPONSE_OK)
-        if self.gconf['print_already_played_games']:
-            self.tv.set_model(self.model)
-        else:
-            self.tv.set_model(self.new_model)
-        self.includeOldGamesToggle.connect('toggled',self.include_old_games_toggle_cb)
-        self.max = self.max_adj.get_value()
-        self.min = self.min_adj.get_value()
-        self.last_adjusted = 1
-        self.min_adj.connect('value-changed',self.difficulty_val_changed,0)
-        self.max_adj.connect('value-changed',self.difficulty_val_changed,1)
-        self.changing_spin_internally = False
-        self.changing_difficulty_internally = False
-        self.sudokusToPrintSpinButton.connect('focus-out-event',self.spin_changed_cb)
-        self.sudokusToPrintSpinButton.get_adjustment().upper = len(self.tv.get_model())
-
-    def spin_changed_cb (self, *args):
-        #if not self.changing_spin_internally:
-        self.auto_select_puzzles()
-
-    def include_old_games_toggle_cb (self, tog, *args):
-        if tog.get_active(): self.tv.set_model(self.model)
-        else: self.tv.set_model(self.new_model)
-        self.sudokusToPrintSpinButton.get_adjustment().upper = len(self.tv.get_model())
-        self.auto_select_puzzles()
-
-    def setup_tree (self):
-        self.make_model()
-        for puzzobj in self.sudoku_tracker.sudoku_maker.all_puzzles.items():
-            self.add_puzzle_to_model(*puzzobj)
-        fm = self.model.filter_new()
-        def include_puzzle_at_itr (mod, itr):
-            puz=mod.get_value(itr, 0)
-            if not self.sudoku_tracker.playing.has_key(puz) and not self.sudoku_tracker.finished.has_key(puz):
-                return True
-        fm.set_visible_func(include_puzzle_at_itr)
-        self.new_model = gtk.TreeModelSort(fm)
-        self.model.set_sort_column_id(4,gtk.SORT_ASCENDING)
-        self.new_model.set_sort_column_id(4,gtk.SORT_ASCENDING)
-        self.setup_treeview_columns()
-        self.tv.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
-
-    def run_dialog (self):
-        self.setup_dialog()
-        self.auto_select_puzzles()
         self.dialog.connect('response',self.response_cb)
-        self.dialog.show()
 
-    def run_swallowed_dialog (self, swallower):
-        # This is broken... tell anyone who calls us not to use it!
-        raise NotImplementedError
-        self.setup_dialog()
-        self.auto_select_puzzles()
-        response = swallower.run_dialog(self.dialog)
-        return self.handle_response(response)
-    
     def response_cb (self, dialog, response):
-        if response == gtk.RESPONSE_ACCEPT or response == gtk.RESPONSE_OK:
-            mod,rr = self.tv.get_selection().get_selected_rows()
-            sudokus = []
-            labelp = self.labelGamesToggle.get_active() or None # None rather than False
-            for path in rr:
-                grid = mod[path][0]
-                difficulty = mod[path][2]
-                name = mod[path][5]
-                label = labelp and "%s (%s)"%(name,difficulty)                
-                grid = sudoku.SudokuGrid(grid)
-                sudokus.append((grid,label)) # puzzle, difficulty (value string)
-            from printing import SudokuPrinter
-            sp = SudokuPrinter(sudokus,sudokus_per_page=self.sudokusPerPageSpinButton.get_adjustment().get_value(), dialog_parent=self.dialog)
-            self.sudokus_printed = sudokus
-            sp.run()
-            sp.dialog.connect('response',self.print_dialog_response_cb)
-        else:
+        if response not in (gtk.RESPONSE_ACCEPT, gtk.RESPONSE_OK):
             self.dialog.hide()
+            return
+        # Otherwise, we're printing!
+        levels = []
+        for cat in DR.categories:
+            if getattr(self,
+                       cat.replace(' ','_')+'CheckButton'
+                       ).get_active():
+                levels.append(cat)
+        if not levels:
+            levels = DR.categories.keys()
+        nsudokus = self.sudokusToPrintSpinButton.get_adjustment().get_value()
+        sudokus = self.sudoku_maker.get_puzzles(
+            nsudokus,
+            levels,
+            new=not self.includeOldGamesToggle.get_active()
+            )
+        # Convert floating point difficulty into a label string
+        sudokus.sort(cmp=lambda a,b: cmp(a[1],b[1]))
+        sudokus = [(sudoku.sudoku_grid_from_string(puzzle),
+                    "%s (%.2f)"%(sudoku.get_difficulty_category_name(d),d)
+                    ) for puzzle,d in sudokus]
+        from printing import SudokuPrinter
+        sp = SudokuPrinter(sudokus,
+                           sudokus_per_page=self.sudokusPerPageSpinButton.get_adjustment().get_value(),
+                           dialog_parent=self.dialog)
+        self.sudokus_printed = sudokus
+        sp.run()
+        sp.dialog.connect('response',
+                          self.print_dialog_response_cb)
 
     def print_dialog_response_cb (self, dialog, response):
         if response == gnomeprint.ui.DIALOG_RESPONSE_CANCEL:
@@ -528,130 +286,34 @@
                     jar['game']=sud.to_string()
                     jar['printed']=True
                     jar['printed_at']=time.time()
-                    self.sudoku_tracker.playing[sud.to_string()] = jar
+                    tracker = saver.SudokuTracker()
+                    tracker.finish_jar(jar)
             self.dialog.hide()
 
-    def difficulty_val_changed (self, adj, typ):
-        self.last_adjusted = typ
-        self.max = self.max_adj.get_value()
-        self.min = self.min_adj.get_value()
-        if not self.changing_difficulty_internally: self.auto_select_puzzles()
+    def run_dialog (self):
+        #self.setup_dialog()
+        self.dialog.show()
 
-    def auto_select_puzzles (self,*args):
-        mod = self.tv.get_model()
-        lower = []
-        higher = []
-        possible = []
-        for row in mod:
-            diff = row[1]
-            n = diff.value
-            if self.min <= n <= self.max:
-                possible.append((row,n))
-            elif n < self.min:
-                lower.append((row,n))
-            else:
-                higher.append((row,n))
-        row_sorter = lambda a,b: a[1]>b[1] and 1 or a[1]<b[1] and -1 or 0
-        nsudokus = self.sudokusToPrintSpinButton.get_adjustment().get_value()
-        if not possible and not lower and not higher:
-            return
-        if len(possible) < nsudokus:
-            print 'Only %d puzzles have a difficulty between %d and %d'%(len(possible), self.min, self.max)
-            print "We'll have to fudge a bit..."
-            choices = possible # start with everything we've got...
-            lower.sort(row_sorter)
-            higher.sort(row_sorter)
-            higher.reverse()
-            # First priority, we last nudged higher and move to the lower end
-            if self.last_adjusted == 1 and lower:
-                while len(choices)<nsudokus and lower:
-                    choices.append(lower.pop())
-            # Otherwise, try moving higher...
-            if self.last_adjusted == 0 and higher:
-                while len(choices)<nsudokus and higher:
-                    choices.append(higher.pop())
-            # If we still don't have enough, nudge as necessary in both directions...
-            just_tried = 0
-            while len(choices) < nsudokus and (higher or lower):
-                if just_tried and lower:
-                    print 'Nudging lower'
-                    choices.append(lower.pop())
-                    just_tried = 0
-                elif higher:
-                    print 'Nudging higher'
-                    choices.append(higher.pop())
-                    just_tried = 1
-                else:
-                    print 'Nudging lower'
-                    choices.append(lower.pop())
-        else: # len(possible) >= nsudokus
-            if nsudokus ==1:
-                middle = len(possible)/2
-                choices = [possible[middle]]
-            else:
-                # get an even distribution of numbers...
-                # for example, 2 of 12 items will give us 0 and 12,
-                # 3 of 12 will give us 0,6,12, 4 of 12 will give us
-                # 0,4,8,12, etc.
-                spacer = (len(possible)-1)/float(nsudokus-1)
-                indices = [n*spacer for n in range(nsudokus)]
-                choices = [possible[int(n)] for n in indices]
-        if choices:
-            self.tv.get_selection().unselect_all()
-            #print 'Selecting ',len(choices),'choices.'
-        for c in choices:
-            try:
-                self.tv.get_selection().select_iter(c[0].iter)
-            except:
-                print "That's funny",c,'must be an iter(?)'
-                self.tv.get_selection().select_iter(c)
-                #print 'selected ',choices
-
-    def selection_changed_cb (self, selection):
-        mod,rows = selection.get_selected_rows()
-        count = 0
-        new_max = None
-        new_min = None
-        for path in rows:
-            if not mod[path][0]: # if there's no puzzle...
-                parent = mod[path].parent
-                if parent and not parent.path in rows:
-                    # then we select the parent...
-                    selection.select_path(parent.path)
-                    # and we stop handling because we should be called
-                    # again as a result of our selection
-                    break
-            else:
-                difficulty = mod[path][4]
-                if difficulty < self.min:
-                    if new_min == None or difficulty < new_min:
-                        new_min = difficulty
-                if difficulty > self.max:
-                    if new_max == None or difficulty > new_max:
-                        new_max = difficulty
-                count += 1
-        if count > 1:
-            self.dialog.set_response_sensitive(gtk.RESPONSE_OK,
-                                               selection.get_selected_rows() and True or False)
-            self.changing_spin_internally = True
-            self.sudokusToPrintSpinButton.get_adjustment().set_value(count)
-            self.changing_spin_internally = False
-            if new_min != None:
-                self.min_adj.set_value(new_min)
-            if new_max:
-                self.max_adj.set_value(new_max)
-
-if __name__ == '__main__':
-    try:
-        IMAGE_DIR='/usr/share/gnome-sudoku/'
-        import defaults
-        from gnome_sudoku import sudoku_maker
-        st = sudoku_maker.SudokuTracker(sudoku_maker.SudokuMaker(pickle_to='/tmp/foo'))
-        hs=HighScores(st)
-        hs.highlight_newest=True
-        hs.run_dialog()
-        st.save()
-    except:
-        import sys
-        print 'path was ',sys.path
-        raise
+# if __name__ == '__main__':
+#     try:
+#         IMAGE_DIR='/usr/share/gnome-sudoku/'
+#         import defaults
+#         from gnome_sudoku import sudoku_maker
+#         st = sudoku_maker.SudokuTracker(sudoku_maker.SudokuMaker(pickle_to='/tmp/foo'))
+#         hs=HighScores(st)
+#         hs.highlight_newest=True
+#         hs.run_dialog()
+#         st.save()
+#     except:
+#         import sys
+#         print 'path was ',sys.path
+#         raise
+#
+#if __name__ == '__main__':
+#    gs = NewOrSavedGameSelector()
+#    print 'DIALOG RETURNS:',gs.run_dialog()
+#
+#    import saver; sudoku_maker = sudoku_maker.SudokuMaker()
+#    gs = GamePrinter(sudoku_maker,gconf_wrapper.GConf('gnome-sudoku'))
+#    gs.run_dialog()
+#    gtk.main()
Index: gnome-sudoku/src/lib/sudoku.py
===================================================================
--- gnome-sudoku/src/lib/sudoku.py	(revision 6846)
+++ gnome-sudoku/src/lib/sudoku.py	(working copy)
@@ -4,6 +4,8 @@
 import re
 from gettext import gettext as _
 
+
+
 GROUP_SIZE = 9
 
 TYPE_ROW = 0
@@ -204,6 +206,47 @@
         """Output our grid as a string."""
         return " ".join([" ".join([str(x) for x in row]) for row in self.grid])
 
+def is_valid_puzzle (p):
+    """Check puzzle for basic validity.
+    
+    This does not check for solvability or ensure a unique
+    solution -- it merely checks well-formedness. This should
+    provide some protection again file corruption, etc. (i.e. if
+    we use this function to check puzzles before handing them out
+    to the rest of the app, we'll prevent tracebacks related to
+    corrupted puzzles).
+    """
+    try:
+        sudoku_grid_from_string(p)
+    except:
+        return False
+    else:
+        return True
+
+def sudoku_grid_from_string (s):
+    """Given an 81 character string, return a grid."""
+    s=s.replace(' ','')
+    assert(len(s)<=GROUP_SIZE**2)
+    grid = []
+    i = 0
+    for x in range(GROUP_SIZE):
+        row = []
+        for y in range(GROUP_SIZE): 
+            if len(s) <= i: n = 0
+            else: n = s[i]
+            try:
+                n = int(n)
+            except:
+                n = n or 0
+            if n in digit_set:
+                row.append(n)
+            else:
+                row.append(0)
+            i += 1
+        grid.append(row)
+    return SudokuGrid(grid)
+    
+
 class SudokuSolver (SudokuGrid):
     """A SudokuGrid that can solve itself."""
     def __init__ (self, grid=False, verbose=False,group_size=9):        
@@ -605,19 +648,30 @@
         return True
 
     def is_changed (self):
-        return 1 in self.grid!=self.virgin.grid
+        return (self.grid!=self.virgin.grid)
 
 class DifficultyRating:
-
+    
     very_hard = _('Very Hard')
     hard = _('Hard')
     medium = _('Medium')
     easy = _('Easy')
 
-    very_hard_range = [0.75,None]
-    hard_range = [0.6,0.75]
-    medium_range = [0.45,0.6]
-    easy_range = [0,0.45]
+    very_hard_range = (0.75,10)
+    hard_range = (0.6,0.75)
+    medium_range = (0.45,0.6)
+    easy_range = (-10,0.45)
+
+    categories = {'very hard':very_hard_range,
+                  'hard':hard_range,
+                  'medium':medium_range,
+                  'easy':easy_range}
+
+    ordered_categories = ['easy','medium','hard','very hard']
+    label_by_cat = {'easy':easy,
+                    'medium':medium,
+                    'hard':hard,
+                    'very hard':very_hard}
     
     def __init__ (self,
                   fill_must_fillables,
@@ -685,9 +739,29 @@
         if self.value > self.very_hard_range[0]: return _(self.very_hard)
         elif self.value > self.hard_range[0]: return _(self.hard)
         elif self.value > self.medium_range[0]: return _(self.medium)
-        #elif self.value > 0.3: return "Medium"
         else: return _(self.easy)
 
+    def value_category (self):
+        """Get category string, without i18n or capitalization
+
+        For use in categorizing category.
+        """
+        if self.value > self.very_hard_range[0]: return 'very hard'
+        elif self.value > self.hard_range[0]: return 'hard'
+        elif self.value > self.medium_range[0]: return 'medium'
+        else: return 'easy'
+
+def get_difficulty_category_name (diff_float):
+    return DifficultyRating.label_by_cat.get(
+        get_difficulty_category(diff_float),
+        '?'
+        )
+
+def get_difficulty_category (diff_float):
+    for category,range in DifficultyRating.categories.items():
+        if range[0] <= diff_float < range[1]:
+            return category
+
 class SudokuRater (SudokuSolver):
 
     def __init__ (self, grid=False, verbose=False, group_size=9):
Index: gnome-sudoku/src/lib/timer.py
===================================================================
--- gnome-sudoku/src/lib/timer.py	(revision 6846)
+++ gnome-sudoku/src/lib/timer.py	(working copy)
@@ -5,7 +5,15 @@
 from gettext import ngettext
 from defaults import *
 
-def format_time (time, round_at=None):
+def format_time (time, round_at=None, friendly=False):
+    """Format a time for display to the user.
+
+    If round_at, we round all times to some number of seconds.
+
+    If friendly, we don't bother showing the user more than two
+    units. i.e. 3 days 2 hours, or 2 minutes 30 seconds, but not 3
+    days, 4 hours, 2 minutes and 3 seconds...
+    """
     time = int(time)
     time_strings = []
     units = [(int(365.25*24*60*60),
@@ -32,6 +40,8 @@
             else:
                 time_strings.append(unit_formatter(time_covered))
                 time = time - time_covered * divisor
+    if friendly and len(time_strings)>2:
+        time_stings = time_strings[:2]
     if len(time_strings)>2:
         # Translators... this is a messay way of concatenating
         # lists. In English we do lists this way: 1, 2, 3, 4, 5
@@ -41,8 +51,15 @@
         # ", " and " and " with the same string.
         return _(" and ").join([_(", ").join(time_strings[0:-1]),time_strings[-1]])
     else:
-        return _(" and ").join(time_strings)
+        return _(" ").join(time_strings)
 
+def format_time_compact (tim):
+    tim = int(tim)
+    hours = tim / (60*60)
+    minutes = (tim % (60*60)) / 60
+    seconds = ((tim % (60*60)) % 60)
+    return "%d:%02d:%02d"%(hours,minutes,seconds)
+
 def format_date (tim):
     lt = time.localtime(tim)
     hours = int(time.strftime("%H",lt))
@@ -59,6 +76,32 @@
     else:
         return time.strftime("%A %B %d %R %p",lt)
 
+def format_friendly_date (tim):
+    lt = time.localtime(tim)
+    hours = int(time.strftime("%H",lt))
+    minutes = int(time.strftime("%M",lt))
+    diff = time.time() - tim
+    ct = time.localtime(); chour=ct[3]; cmin=ct[4]
+    to_yesterday = chour*60*60+cmin*60
+    if diff < to_yesterday:
+        # Then we're today
+        if diff < (60*60): # within the hour...
+            if (int(diff) / 60):
+                m = (diff / 60)
+                return ngettext("%(n)s minute ago",
+                                "%(n)s minutes ago",m)%{'n':int(m)}
+            else: # within the minute
+                return ngettext("%(n)s second ago",
+                                "%(n)s seconds ago",
+                                int(diff))%{'n':int(diff)}
+        else:
+            return "at %(time)s"%{'time':time.strftime("%I:%M %p",lt)}
+    elif diff < to_yesterday + (60*60*24):
+        return _("yesterday at %s")%time.strftime("%I:%M %p",lt)
+    elif diff < to_yesterday + (60*60*24)*6:
+        return time.strftime("%A %I:%M %p",lt)
+    else:
+        return time.strftime("%B%e",lt)
 
 class ActiveTimer (gobject.GObject):
     """A timer to keep track of how much time a window is active."""
Index: gnome-sudoku/src/lib/saver.py
===================================================================
--- gnome-sudoku/src/lib/saver.py	(revision 6846)
+++ gnome-sudoku/src/lib/saver.py	(working copy)
@@ -1,4 +1,5 @@
-import pickle
+import pickle, types, os, os.path, sudoku
+from defaults import *
 
 SAVE_ATTRIBUTES = [('gsd.hints'),
                    ('gsd.impossible_hints'),
@@ -64,7 +65,7 @@
         
 def pickle_game (ui, target):
     close_me = False
-    if type(target)==str:
+    if type(target) in types.StringTypes:
         target = file(target,'w')
         close_me = True
     to_dump = jar_game(ui)
@@ -78,3 +79,83 @@
         close_me = True
     open_game(ui,pickle.load(target))
     if close_me: target.close()
+
+class SudokuTracker:
+
+    """A class to track games in progress and games completed.
+    """
+
+    def __init__ (self):
+        self.save_path = os.path.expanduser('~/.sudoku/saved')
+        self.finished_path = os.path.expanduser('~/.sudoku/finished')
+        if not os.path.exists(self.save_path):
+            os.makedirs(self.save_path)
+        if not os.path.exists(self.finished_path):
+            os.makedirs(self.finished_path)
+
+    def are_finished_games (self):
+        if os.listdir(self.finished_path): return True
+        else: return False
+
+    def game_from_ui (self, ui):
+        return ui.gsd.grid.virgin.to_string()
+
+    def get_filename (self, gamestring):
+        return gamestring.split('\n')[0].replace(' ','')
+
+    def save_game (self, ui):
+        game = self.game_from_ui(ui)
+        jar = jar_game(ui)
+        #jar['saved_at'] = time.time()
+        outfi = file(os.path.join(self.save_path,self.get_filename(jar['game'])),
+                     'w')
+        pickle.dump(jar,outfi)
+        outfi.close()
+
+    def finish_game (self, ui):
+        game = self.game_from_ui(ui)
+        jar  = jar_game(ui)
+        self.finish_jar(jar)
+
+    def finish_jar (self, jar):
+        self.remove_from_saved_games(jar) # 
+        outfi = file(os.path.join(self.finished_path,
+                                  self.get_filename(jar['game'])),
+                     'w'
+                     )
+        pickle.dump(jar,outfi)
+        outfi.close()
+        list_of_finished_games = os.path.join(
+            os.path.join(DATA_DIR,'puzzles'),'finished'
+            )
+        ofi = open(list_of_finished_games,'a')
+        ofi.write(jar['game'].split('\n')[0]+'\n')
+        ofi.close()
+
+    def remove_from_saved_games (self, jar):
+        previously_saved_game = os.path.join(
+            self.save_path,self.get_filename(jar['game'])
+            )
+        if os.path.exists(previously_saved_game):
+            os.remove(os.path.join(previously_saved_game))
+
+    def abandon_game (self, ui):
+        game = self.game_from_ui(ui)
+        jar  = jar_game(ui)
+        self.remove_from_saved_games(jar)
+        
+    def list_saved_games (self):
+        files = os.listdir(self.save_path)
+        games = []
+        for f in files:
+            f = os.path.join(self.save_path,f)
+            try:
+                jar = pickle.load(file(f,'r'))
+            except:
+                print 'Warning: could not read file',f
+            else:
+                jar['saved_at']=os.stat(f)[8]
+                games.append(jar)
+        return games
+        
+
Index: gnome-sudoku/src/lib/gsudoku.py
===================================================================
--- gnome-sudoku/src/lib/gsudoku.py	(revision 6846)
+++ gnome-sudoku/src/lib/gsudoku.py	(working copy)
@@ -46,7 +46,7 @@
 SPACING_FACTOR = 40 # The size of a box compared (roughly) to the size
                     # of padding -- the larger this is, the smaller
                     # the spaces
-SMALL_TO_BIG_FACTOR = 3 # The number of times wider than a small line a big line is.
+SMALL_TO_BIG_FACTOR = 3.5 # The number of times wider than a small line a big line is.
 
 class NumberSelector (gtk.EventBox):
 
@@ -465,6 +465,7 @@
         self.draw_text(cr)
         if self.draw_boxes and self.is_focus():
             self.draw_note_area_highlight_box(cr)
+        
 
     def draw_background_color (self, cr):        
         if self.read_only:
Index: gnome-sudoku/src/lib/Makefile.am
===================================================================
--- gnome-sudoku/src/lib/Makefile.am	(revision 6846)
+++ gnome-sudoku/src/lib/Makefile.am	(working copy)
@@ -16,5 +16,6 @@
 	sudoku_generator_gui.py	\
 	sudoku_labeller.py	\
 	sudoku_maker.py	\
+	sudoku_thumber.py \
 	sudoku.py	\
 	timer.py
Index: gnome-sudoku/src/lib/sudoku_generator_gui.py
===================================================================
--- gnome-sudoku/src/lib/sudoku_generator_gui.py	(revision 6846)
+++ gnome-sudoku/src/lib/sudoku_generator_gui.py	(working copy)
@@ -18,16 +18,16 @@
                      'generate_for_target':0,
                      'number_of_sudokus_to_generate':10,
                      }
-    
+
     def __init__ (self, UI, gconf):
         self.ui = UI
-        self.sudoku_tracker = self.ui.sudoku_tracker
         self.sudoku_maker = self.ui.sudoku_maker
         # Don't work in background...
         self.ui.stop_worker_thread()
         gconf_wrapper.GConfWrapper.__init__(self,gconf)
         self.glade = gtk.glade.XML(self.glade_file)
         self.generate_for_target_widgets = []
+        self.cat_to_label = {}
         for d in ['easy',
                   'medium',
                   'hard',
@@ -40,6 +40,8 @@
             gconf_setting = 'generate_target_%s'%d
             self.gconf_wrap_toggle(gconf_setting,widget)
             self.generate_for_target_widgets.append(widget)
+            self.cat_to_label[d] = getattr(self,label_widget_name)
+        self.cat_to_label['very hard'] = self.cat_to_label['veryHard']
         self.generateEndlesslyRadio = self.glade.get_widget('generateEndlesslyRadio')
         self.generateForTargetRadio = self.glade.get_widget('generateForTargetRadio')
         self.gconf_wrap_toggle('generate_endlessly',self.generateEndlesslyRadio)
@@ -95,6 +97,7 @@
 
     def generate_cb (self, *args):
         self.ngenerated = 0
+        self.generated_by_cat = {}
         self.toward_target = 0
         self.pauseButton.set_sensitive(True)
         self.stopButton.set_sensitive(True)
@@ -141,20 +144,16 @@
     def setup_base_status (self):
         """Setup basic status.
         """
-        for puzz,diff in self.sudoku_tracker.list_new_puzzles():
-            diffstr = diff.value_string()
-            if diffstr == sudoku.DifficultyRating.easy:
-                self.increment_label(self.easyLabel)
-            elif diffstr == sudoku.DifficultyRating.medium:
-                self.increment_label(self.mediumLabel)
-            elif diffstr == sudoku.DifficultyRating.hard:
-                self.increment_label(self.hardLabel)
-            else:
-                self.increment_label(self.veryHardLabel)
+        for diff,lab in [('easy',self.easyLabel),
+                         ('medium',self.mediumLabel),
+                         ('hard',self.hardLabel),
+                         ('very hard',self.veryHardLabel)]:
+            num = self.sudoku_maker.n_puzzles(diff)
+            self.increment_label(lab,num)
 
-    def increment_label (self, lab, val=1):
+    def increment_label (self, lab, val=0):
         curtext = lab.get_text()
-        if not curtext:
+        if (not curtext):
 	    lab.pcount = val
         else:
 	    lab.pcount += 1
@@ -164,41 +163,24 @@
     def update_status (self, *args):
         """Update status of our progress bar and puzzle table.
         """
-        npuzzles = len(self.sudoku_maker.new_puzzles)
+        #print 'update_status!'
+        npuzzles = sum(self.sudoku_maker.new_puzzles.values())
+        #print 'npuzzles=',npuzzles,'ngenerated=',self.ngenerated
         if npuzzles > self.ngenerated:
             # updating gui...
-            to_add = self.sudoku_maker.new_puzzles[self.ngenerated:]
-            self.ngenerated=npuzzles
-            for puzz,diff in to_add:
-                diffstr = diff.value_string()
-                if diffstr == sudoku.DifficultyRating.easy:
-                    self.increment_label(self.easyLabel)
-                    if (not self.generateForTargetRadio.get_active() or
-                        self.easyCheckButton.get_active()):
-                        self.toward_target += 1
-                elif diffstr == sudoku.DifficultyRating.medium:
-                    self.increment_label(self.mediumLabel)
-                    if (not self.generateForTargetRadio.get_active() or
-                        self.mediumCheckButton.get_active()):
-                        self.toward_target += 1
-                elif diffstr == sudoku.DifficultyRating.hard:                    
-                    self.increment_label(self.hardLabel)
-                    if (not self.generateForTargetRadio.get_active() or
-                        self.hardCheckButton.get_active()):
-                        self.toward_target += 1
-                else:
-                    self.increment_label(self.veryHardLabel)
-                    if (not self.generateForTargetRadio.get_active() or
-                        self.veryHardCheckButton.get_active()):
-                        self.toward_target += 1
-            if (self.generateForTargetRadio.get_active()
-                and
-                self.newSudokusSpinButton.get_value()<=self.toward_target):
-                self.toward_target=int(self.newSudokusSpinButton.get_value())
-                self.update_progress_bar()
-                self.stop_cb()
-                return False
-            self.update_progress_bar()
+            self.ngenerated=self.toward_target=npuzzles
+            for cat in self.sudoku_maker.new_puzzles:
+                to_add = self.sudoku_maker.new_puzzles[cat] - self.generated_by_cat.get(cat,0)
+                self.increment_label(self.cat_to_label[cat],to_add)
+                self.generated_by_cat[cat] = self.sudoku_maker.new_puzzles[cat]
+        self.update_progress_bar()
+        if (self.generateForTargetRadio.get_active()
+            and
+            self.toward_target>=int(self.newSudokusSpinButton.get_value())
+            ):
+            print 'Done!'
+            self.stop_cb()
+            return False
         if self.paused: self.prog.set_text(_('Paused'))
         elif self.generateEndlesslyRadio.get_active():
             self.prog.pulse()
Index: gnome-sudoku/data/medium
===================================================================
--- gnome-sudoku/data/medium	(revision 0)
+++ gnome-sudoku/data/medium	(revision 0)
@@ -0,0 +1,150 @@
+0 0 0 8 1 5 2 3 0 0 0 0 9 0 0 0 0 8 0 0 2 4 6 0 5 1 0 3 0 6 0 0 0 1 0 0 0 5 0 1 0 6 0 2 0 0 0 4 0 0 0 6 0 3 0 9 5 0 4 1 8 0 0 6 0 0 0 0 9 0 0 0 0 8 3 6 5 2 0 0 0	0.55
+0 1 0 4 0 0 0 3 7 2 9 0 0 7 0 5 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 8 7 1 4 0 0 5 0 0 0 9 0 0 7 2 1 3 0 0 0 0 0 0 0 6 0 0 0 0 0 0 0 0 9 0 3 0 0 8 5 4 8 0 0 0 5 0 7 0	0.528421683139
+3 0 0 5 1 2 0 0 4 2 0 0 7 0 8 0 0 6 0 1 0 0 0 0 0 0 0 0 9 0 0 0 0 0 6 2 0 2 0 9 0 6 0 8 0 5 7 0 0 0 0 0 4 0 0 0 0 0 0 0 0 5 0 1 0 0 6 0 4 0 0 9 7 0 0 1 3 5 0 0 8	0.57385620915
+0 2 0 0 5 1 4 0 0 0 0 5 0 0 0 0 7 6 0 4 0 6 9 0 0 5 0 1 0 6 0 7 8 0 0 0 0 8 0 0 0 0 0 3 0 0 0 0 1 4 0 8 0 7 0 7 0 0 8 2 0 1 0 8 6 0 0 0 0 9 0 0 0 0 2 5 1 0 0 8 0	0.489067055394
+0 0 0 0 0 1 4 9 0 0 1 5 0 2 0 3 7 0 7 4 0 6 0 0 0 0 0 1 0 6 0 0 8 2 0 9 4 0 0 2 0 9 0 0 1 2 0 9 1 0 0 8 0 7 0 0 0 0 0 2 0 1 3 0 6 1 0 3 0 9 2 0 0 9 2 5 0 0 0 0 0	0.542010582011
+0 2 0 7 0 1 4 0 0 0 1 0 0 2 0 0 7 6 0 0 0 0 9 3 0 5 2 1 0 0 0 7 0 2 0 0 0 8 0 2 0 9 0 3 0 0 0 9 0 4 0 0 0 7 5 7 0 9 8 0 0 0 0 8 6 0 0 3 0 0 2 0 0 0 2 5 0 6 0 8 0	0.485055724417
+4 0 6 0 0 0 0 2 0 0 2 0 6 8 0 1 0 5 0 1 8 0 0 0 0 0 3 0 8 0 7 0 5 3 0 0 0 0 7 0 3 0 5 0 0 0 0 3 8 0 6 0 1 0 8 0 0 0 0 0 4 7 0 6 0 1 0 7 4 0 3 0 0 4 0 0 0 0 6 0 1	0.46875
+4 0 6 1 0 0 0 0 0 3 2 0 6 0 7 0 0 5 5 1 0 0 0 0 0 0 0 2 0 4 0 0 0 3 0 0 0 6 7 9 0 2 5 8 0 0 0 3 0 0 0 2 0 7 0 0 0 0 0 0 0 7 9 6 0 0 5 0 4 0 3 2 0 0 0 0 0 8 6 0 1	0.47657920311
+0 2 0 0 9 5 0 0 7 0 4 5 0 3 2 1 6 0 0 7 0 0 6 0 0 4 0 4 9 0 0 0 0 7 0 0 0 0 3 0 0 0 2 0 0 0 0 7 0 0 0 0 9 6 0 3 0 0 7 0 0 5 0 0 6 1 3 2 0 4 7 0 7 0 0 6 5 0 0 2 0	0.554255319149
+0 0 9 0 0 0 0 0 0 4 0 6 0 5 0 9 2 0 2 5 0 9 0 4 8 0 0 8 0 7 1 0 0 0 0 0 0 3 1 4 0 5 2 7 0 0 0 0 0 0 8 4 0 1 0 0 5 8 0 6 0 4 9 0 9 8 0 4 0 6 0 5 0 0 0 0 0 0 1 0 0	0.458156028369
+0 0 0 0 0 2 8 9 3 0 0 0 0 0 3 0 0 7 0 6 7 9 0 0 0 4 2 0 0 3 0 0 0 0 8 9 9 5 0 3 0 8 0 2 6 6 8 0 0 0 0 1 0 0 2 3 0 0 0 5 9 7 0 1 0 0 2 0 0 0 0 0 5 7 9 8 0 0 0 0 0	0.452482269504
+0 7 0 0 0 0 4 1 9 0 0 9 0 0 0 0 0 2 0 0 5 0 7 9 0 0 0 7 8 3 1 0 2 0 4 0 0 0 0 8 3 4 0 0 0 0 9 0 6 0 7 8 3 1 0 0 0 7 6 0 5 0 0 3 0 0 0 0 0 1 0 0 9 6 8 0 0 0 0 7 0	0.556150793651
+2 4 0 0 0 9 7 0 1 0 0 1 0 0 6 0 4 0 0 3 6 0 0 0 2 0 0 5 0 0 9 0 0 0 1 6 0 0 0 6 0 2 0 0 0 6 9 0 0 0 7 0 0 4 0 0 3 0 0 0 6 8 0 0 5 0 8 0 0 4 0 0 8 0 2 7 0 0 0 3 5	0.469047619048
+1 0 0 0 7 6 0 9 3 0 0 6 3 0 0 0 4 0 0 0 0 4 1 0 7 0 0 0 7 0 0 9 0 4 0 0 2 0 9 0 6 0 3 0 7 0 0 3 0 5 0 0 1 0 0 0 2 0 3 7 0 0 0 0 1 0 0 0 5 6 0 0 3 4 0 6 8 0 0 0 9	0.465972222222
+1 7 0 0 3 4 0 9 0 0 0 0 0 0 0 0 2 0 5 0 6 0 0 7 0 0 0 3 0 0 1 0 0 0 8 7 0 4 7 0 5 0 3 1 0 8 2 0 0 0 9 0 0 5 0 0 0 4 0 0 9 0 3 0 6 0 0 0 0 0 0 0 0 3 0 7 9 0 0 6 1	0.458
+7 0 2 0 0 0 0 1 0 0 1 6 2 0 4 0 0 3 0 0 3 0 6 0 0 0 0 2 9 4 0 3 0 1 5 0 6 3 0 0 2 0 0 7 4 0 7 5 0 9 0 3 6 2 0 0 0 0 4 0 6 0 0 4 0 0 3 0 5 8 2 0 0 2 0 0 0 0 5 0 7	0.45395021645
+1 6 0 0 2 0 7 0 0 7 0 0 9 0 0 0 2 0 0 0 0 5 0 0 0 4 1 0 0 7 0 6 0 0 5 0 0 0 9 0 5 0 1 0 0 0 8 0 0 1 0 3 0 0 8 5 0 0 0 7 0 0 0 0 2 0 0 0 5 0 0 9 0 0 1 0 4 0 0 3 8	0.567902930403
+0 0 5 4 2 0 0 0 3 7 0 8 9 0 0 6 2 0 0 9 0 0 0 0 0 0 0 0 1 0 0 6 3 0 0 2 6 0 0 2 0 4 0 0 7 5 0 0 7 1 0 0 6 0 0 0 0 0 0 0 0 1 0 0 2 6 0 0 5 4 0 9 9 0 0 0 4 2 5 0 0	0.540476190476
+0 0 0 0 0 0 9 0 4 2 0 9 3 1 0 0 0 7 0 0 5 9 0 2 0 0 8 0 0 0 6 0 0 0 4 0 0 0 0 8 3 4 0 0 0 0 3 0 0 0 1 0 0 0 7 0 0 1 0 9 4 0 0 3 0 0 0 8 5 1 0 2 5 0 6 0 0 0 0 0 0	0.480769230769
+0 0 2 0 1 9 0 0 4 0 7 0 0 2 0 0 0 0 4 0 0 7 6 0 0 2 8 0 0 0 2 0 0 6 0 3 0 8 6 0 0 0 1 5 0 2 0 5 0 0 8 0 0 0 7 6 0 0 8 3 0 0 5 0 0 0 0 7 0 0 3 0 5 0 0 1 9 0 4 0 0	0.454081632653
+1 0 0 0 4 0 6 8 0 0 0 0 6 0 0 1 0 7 0 4 0 0 0 7 5 0 0 0 8 5 4 0 3 0 0 0 0 3 0 2 0 9 0 7 0 0 0 0 8 0 6 3 5 0 0 0 3 9 0 0 0 6 0 8 0 4 0 0 1 0 0 0 0 2 7 0 6 0 0 0 8	0.539455782313
+8 1 7 0 0 0 2 0 0 0 0 0 0 0 0 9 0 6 0 6 0 0 2 0 0 1 7 0 7 0 8 0 9 0 2 0 3 0 0 2 0 7 0 0 5 0 9 0 1 0 4 0 6 0 7 5 0 0 1 0 0 4 0 1 0 9 0 0 0 0 0 0 0 0 2 0 0 0 5 3 1	0.570408163265
+2 0 0 4 5 0 0 0 1 0 0 0 8 1 0 2 0 0 8 0 0 9 0 2 0 3 0 0 6 0 3 0 9 0 0 4 0 0 3 0 0 0 9 0 0 5 0 0 1 0 8 0 7 0 0 3 0 2 0 1 0 0 6 0 0 1 0 9 5 0 0 0 6 0 0 0 3 4 0 0 8	0.562827988338
+0 1 0 0 5 0 9 8 0 0 0 8 0 0 0 1 3 5 0 0 0 0 8 0 4 0 6 3 0 0 4 1 0 5 0 0 0 0 0 3 0 8 0 0 0 0 0 1 0 9 6 0 0 7 1 0 7 0 6 0 0 0 0 8 9 2 0 0 0 7 0 0 0 3 6 0 4 0 0 9 0	0.478571428571
+8 6 0 0 1 4 3 7 0 5 0 0 0 0 8 4 2 0 0 0 0 7 0 0 0 8 0 1 0 0 0 9 0 0 4 7 0 0 7 0 0 0 2 0 0 2 8 0 0 7 0 0 0 6 0 4 0 0 0 7 0 0 0 0 2 5 1 0 0 0 0 4 0 1 9 6 4 0 0 5 2	0.535460992908
+0 0 0 7 0 0 0 0 0 8 4 0 0 0 0 7 9 5 0 2 9 0 5 0 0 0 8 5 0 0 0 4 1 0 0 0 0 1 3 0 0 0 9 5 0 0 0 0 6 3 0 0 0 1 6 0 0 0 2 0 1 3 0 1 7 5 0 0 0 0 8 2 0 0 0 0 0 4 0 0 0	0.549299719888
+0 3 5 9 0 0 0 0 0 9 0 0 0 0 2 5 4 0 0 2 0 0 6 0 7 0 9 0 0 0 7 2 0 8 0 0 0 0 0 8 0 6 0 0 0 0 0 8 0 3 9 0 0 0 4 0 2 0 8 0 0 7 0 0 5 3 1 0 0 0 0 6 0 0 0 0 0 4 3 1 0	0.513538748833
+0 0 0 0 0 5 0 0 4 0 4 0 3 7 1 6 9 0 0 7 0 0 2 0 3 0 1 0 0 6 0 8 0 9 1 0 0 0 4 0 1 0 7 0 0 0 8 7 0 6 0 4 0 0 7 0 5 0 4 0 0 3 0 0 6 3 1 5 2 0 4 0 4 0 0 9 0 0 0 0 0	0.561594202899
+7 8 9 4 0 0 0 3 0 1 4 2 0 9 0 0 0 0 0 5 0 0 0 8 1 0 0 0 7 0 0 0 6 0 0 3 0 1 0 7 0 2 0 6 0 9 0 0 5 0 0 0 1 0 0 0 8 1 0 0 0 5 0 0 0 0 0 5 0 3 4 1 0 9 0 0 0 4 8 2 7	0.472340425532
+0 1 0 6 7 0 0 0 3 6 0 0 0 3 4 1 0 0 0 0 0 0 0 9 4 5 0 7 0 0 0 6 0 8 0 0 4 8 0 2 0 1 0 7 5 0 0 1 0 8 0 0 0 4 0 4 2 9 0 0 0 0 0 0 0 3 7 4 0 0 0 2 8 0 0 0 5 2 0 4 0	0.496048632219
+1 9 0 3 0 0 0 0 0 7 0 5 0 2 9 0 0 0 0 2 6 7 0 0 0 1 3 9 1 2 0 0 6 0 7 0 0 0 0 0 0 0 0 0 0 0 6 0 5 0 0 1 9 4 6 7 0 0 0 5 4 3 0 0 0 0 9 1 0 6 0 7 0 0 0 0 0 7 0 8 1	0.485815602837
+0 5 2 0 4 0 0 0 6 0 0 7 0 5 0 4 9 0 0 6 0 3 0 9 8 5 0 0 0 0 5 0 0 7 0 9 7 9 0 0 3 0 0 1 5 5 0 3 0 0 7 0 0 0 0 7 9 6 0 5 0 4 0 0 8 5 0 1 0 9 0 0 3 0 0 0 9 0 5 6 0	0.463257575758
+0 0 6 0 0 1 9 0 0 0 0 2 0 0 3 0 1 0 0 1 5 0 9 0 0 0 0 0 0 4 0 7 2 0 9 0 0 9 1 0 0 0 5 2 0 0 2 0 5 1 0 3 0 0 0 0 0 0 2 0 6 4 0 0 4 0 7 0 0 2 0 0 0 0 8 9 0 0 1 0 0	0.586157796452
+0 7 6 0 0 1 9 0 0 0 8 0 0 6 0 0 0 0 0 1 0 0 0 7 4 8 0 0 3 0 0 0 2 0 0 1 0 0 1 3 0 4 5 0 0 8 0 0 5 0 0 0 6 0 0 5 3 1 0 0 0 4 0 0 0 0 0 3 0 0 5 0 0 0 8 9 0 0 1 7 0	0.492156862745
+0 9 5 0 0 1 0 6 0 0 8 4 5 7 0 0 0 0 0 0 7 0 0 8 0 4 0 7 0 0 9 0 0 0 1 3 0 0 2 0 0 0 7 0 0 3 5 0 0 0 7 0 0 4 0 1 0 7 0 0 4 0 0 0 0 0 0 9 4 6 7 0 0 7 0 2 0 0 3 5 0	0.458843537415
+2 0 5 7 0 6 4 0 0 7 0 0 4 3 0 0 2 6 0 0 0 0 0 0 7 0 0 6 0 0 0 0 7 0 3 0 0 8 0 5 0 9 0 6 0 0 5 0 1 0 0 0 0 8 0 0 4 0 0 0 0 0 0 5 7 0 0 8 1 0 0 2 0 0 2 6 0 4 3 0 7	0.533624878523
+0 0 0 6 0 0 1 2 0 0 0 0 0 0 9 0 0 6 0 6 0 3 1 0 5 0 9 0 1 4 0 0 2 0 6 7 0 8 7 0 4 0 2 3 0 2 3 0 7 0 0 4 5 0 4 0 3 0 6 7 0 9 0 6 0 0 4 0 0 0 0 0 0 5 1 0 0 3 0 0 0	0.450362318841
+0 9 5 4 6 0 0 0 0 3 0 4 9 0 1 0 5 0 0 0 0 3 0 0 0 0 4 6 0 0 7 0 4 0 2 0 0 0 1 0 2 0 3 0 0 0 4 0 5 0 9 0 0 6 9 0 0 0 0 7 0 0 0 0 6 0 2 0 8 5 0 3 0 0 0 0 4 3 2 9 0	0.510416666667
+0 0 5 6 0 0 9 4 3 3 0 0 0 4 0 0 0 0 0 4 0 0 0 0 7 0 6 0 7 0 0 9 4 0 0 0 6 0 2 0 0 0 4 0 5 0 0 0 2 6 0 0 3 0 1 0 3 0 0 0 0 7 0 0 0 0 0 5 0 0 0 9 8 9 4 0 0 7 6 0 0	0.521661998133
+9 7 0 6 0 8 0 0 0 0 0 4 0 0 7 8 3 0 1 2 0 3 0 0 0 0 0 0 8 0 0 0 5 3 9 7 0 0 7 0 0 0 6 0 0 6 4 9 7 0 0 0 1 0 0 0 0 0 0 6 0 4 5 0 9 6 5 0 0 2 0 0 0 0 0 9 0 2 0 6 3	0.516565349544
+0 0 0 0 0 0 0 1 0 0 5 0 0 2 4 6 9 0 2 6 0 3 0 1 8 0 7 0 0 3 2 0 8 0 0 5 4 0 0 0 0 0 0 0 2 5 0 0 4 0 3 9 0 0 6 0 5 9 0 7 0 2 1 0 9 1 5 3 0 0 6 0 0 2 0 0 0 0 0 0 0	0.520618034448
+3 0 4 0 7 0 0 8 0 1 0 0 3 0 0 0 0 0 0 7 9 0 6 0 0 0 3 9 0 3 0 1 7 0 6 4 0 0 7 0 8 0 3 0 0 4 1 0 9 3 0 2 0 7 7 0 0 0 4 0 1 2 0 0 0 0 0 0 1 0 0 5 0 3 0 0 2 0 4 0 8	0.497463768116
+3 0 4 0 0 0 5 0 0 5 0 8 0 0 6 0 4 2 0 0 0 5 4 0 0 0 3 0 8 0 2 0 0 6 5 0 1 0 0 0 0 0 0 0 9 0 6 9 0 0 4 0 1 0 2 0 0 0 8 7 0 0 0 8 3 0 9 0 0 1 0 4 0 0 7 0 0 0 8 0 6	0.487609329446
+0 0 0 8 0 2 0 0 1 0 7 8 0 3 0 0 0 2 0 1 0 5 0 0 0 0 0 0 0 3 2 0 0 6 5 0 0 2 5 0 0 0 4 3 0 0 6 9 0 0 4 2 0 0 0 0 0 0 0 7 0 9 0 8 0 0 0 2 0 1 7 0 9 0 0 4 0 3 0 0 0	0.504248366013
+0 0 0 0 9 0 6 0 5 7 0 5 0 2 0 0 0 0 0 4 0 0 0 3 1 0 7 0 3 9 2 0 0 0 5 1 2 0 0 0 1 0 0 0 6 5 7 0 0 0 9 2 8 0 8 0 6 9 0 0 0 7 0 0 0 0 0 7 0 8 0 2 1 0 7 0 4 0 0 0 0	0.484722222222
+9 0 7 1 0 0 0 0 0 0 1 0 0 6 0 0 0 0 0 0 0 7 8 0 0 0 4 8 0 5 0 2 7 0 9 0 0 0 2 8 0 4 5 0 0 0 7 0 5 9 0 8 0 2 2 0 0 0 7 6 0 0 0 0 0 0 0 4 0 0 7 0 0 0 0 0 0 8 2 0 5	0.535574229692
+5 0 0 7 3 0 6 0 2 6 0 0 0 0 4 1 5 0 0 0 0 0 6 1 0 0 0 4 0 6 9 0 0 5 2 0 0 0 0 0 8 0 0 0 0 0 2 5 0 0 6 9 0 1 0 0 0 1 9 0 0 0 0 0 5 7 3 0 0 0 0 9 9 0 2 0 5 7 0 0 4	0.500942460317
+0 0 0 0 3 2 9 0 0 7 4 0 8 0 0 2 1 6 0 1 0 6 0 0 0 0 0 0 2 8 0 0 9 0 0 4 0 0 0 0 4 0 0 0 0 4 0 0 3 0 0 1 9 0 0 0 0 0 0 7 0 3 0 8 6 1 0 0 3 0 7 9 0 0 5 9 6 0 0 0 0	0.487333333333
+0 0 9 0 0 5 2 0 0 0 8 0 0 9 0 1 7 0 4 0 0 0 0 3 0 6 5 0 3 0 5 0 2 4 9 0 0 0 0 0 6 0 0 0 0 0 2 7 8 0 4 0 5 0 6 1 0 3 0 0 0 0 9 0 5 8 0 2 0 0 1 0 0 0 3 6 0 0 7 0 0	0.479166666667
+6 0 0 0 0 7 0 8 0 0 0 0 0 0 9 0 0 1 4 1 0 0 8 0 0 0 2 9 4 0 0 5 1 0 6 0 1 0 8 0 0 0 9 0 5 0 3 0 9 2 0 0 7 4 3 0 0 0 4 0 0 5 6 8 0 0 6 0 0 0 0 0 0 6 0 8 0 0 0 0 3	0.487074829932
+3 8 0 0 5 0 0 0 4 0 0 0 0 0 0 8 5 6 0 5 0 8 9 0 3 0 0 0 0 0 1 0 4 0 0 7 0 0 8 9 7 5 1 0 0 1 0 0 3 0 8 0 0 0 0 0 5 0 4 7 0 1 0 7 9 1 0 0 0 0 0 0 4 0 0 0 1 0 0 2 8	0.460416666667
+9 1 3 2 0 0 0 0 0 6 5 0 0 0 8 9 0 0 0 0 0 5 0 9 0 6 0 5 0 0 0 0 4 0 0 0 2 7 4 1 0 3 6 8 9 0 0 0 9 0 0 0 0 1 0 2 0 4 0 5 0 0 0 0 0 5 3 0 0 0 2 6 0 0 0 0 0 1 3 4 5	0.475177304965
+8 3 7 0 0 0 0 0 5 0 0 0 0 0 6 4 0 0 0 0 0 8 5 0 0 0 7 7 0 6 3 8 2 0 5 0 0 8 0 0 0 0 0 3 0 0 1 0 5 4 7 6 0 8 3 0 0 0 6 8 0 0 0 0 0 8 1 0 0 0 0 0 2 0 0 0 0 0 8 4 9	0.475850340136
+0 0 0 9 0 4 0 0 5 0 0 5 2 7 0 4 0 0 0 0 4 0 5 0 1 9 0 7 4 0 0 8 0 0 5 0 0 8 0 0 9 0 0 3 0 0 1 0 0 4 0 0 2 8 0 7 9 0 6 0 5 0 0 0 0 8 0 2 9 3 0 0 2 0 0 7 0 5 0 0 0	0.545486111111
+2 0 7 3 0 5 0 1 0 5 0 0 4 0 0 0 0 7 0 1 0 7 0 0 3 0 4 0 0 0 1 0 4 2 0 9 0 9 0 0 5 0 0 7 0 1 0 2 9 0 3 0 0 0 4 0 6 0 0 7 0 9 0 3 0 0 0 0 9 0 0 2 0 2 0 8 0 1 4 0 5	0.486231884058
+0 0 2 4 5 0 7 3 0 8 4 0 0 7 0 0 0 0 0 9 5 3 2 0 0 0 0 0 3 8 7 0 2 0 0 0 9 0 4 0 0 0 3 0 7 0 0 0 9 0 3 1 8 0 0 0 0 0 3 6 5 7 0 0 0 0 0 8 0 0 9 4 0 7 1 0 9 4 8 0 0	0.475132275132
+0 0 0 4 0 3 6 1 0 6 0 4 9 0 0 3 7 0 0 3 0 0 7 0 4 0 8 0 0 0 0 9 0 0 5 4 0 0 2 5 0 8 1 0 0 5 6 0 0 4 0 0 0 0 3 0 5 0 1 0 0 4 0 0 8 7 0 0 4 5 0 1 0 1 6 7 0 9 0 0 0	0.540740740741
+0 0 4 7 0 0 2 0 3 0 0 0 9 0 4 5 0 6 0 0 0 5 6 0 0 0 0 5 0 0 0 1 0 0 8 2 0 0 2 8 0 5 9 0 0 9 8 0 0 4 0 0 0 5 0 0 0 0 9 7 0 0 0 2 0 5 4 0 8 0 0 0 7 0 3 0 0 6 8 0 0	0.511273080661
+2 8 0 0 9 7 3 0 0 4 0 7 0 3 0 8 0 0 0 3 5 0 0 8 0 0 6 0 0 0 0 1 3 0 8 0 8 0 1 0 0 0 5 0 7 0 5 0 7 8 0 0 0 0 3 0 0 8 0 0 7 2 0 0 0 8 0 2 0 4 0 3 0 0 4 3 7 0 0 5 8	0.473703703704
+0 0 3 9 0 0 7 0 0 4 0 0 2 3 0 0 0 0 0 1 9 0 0 0 0 2 0 0 0 0 0 2 0 0 8 1 3 0 2 0 6 0 9 0 4 7 9 0 0 8 0 0 0 0 0 7 0 0 0 0 1 3 0 0 0 0 0 9 6 0 0 7 0 0 6 0 0 5 8 0 0	0.560851648352
+0 0 0 0 0 3 0 0 0 0 4 8 5 0 0 0 9 0 2 9 0 7 0 0 0 3 6 9 0 4 1 0 7 0 6 2 0 0 2 0 0 0 3 0 0 8 1 0 3 0 2 7 0 9 1 5 0 0 0 9 0 4 8 0 2 0 0 0 8 9 7 0 0 0 0 6 0 0 0 0 0	0.450709219858
+8 0 0 0 0 0 7 0 0 0 4 0 0 0 0 0 9 8 0 1 3 0 7 0 0 0 0 7 0 0 2 0 8 9 6 0 0 0 6 7 0 1 5 0 0 0 3 9 4 0 5 0 0 2 0 0 0 0 1 0 2 8 0 6 2 0 0 0 0 0 5 0 0 0 8 0 0 0 0 0 9	0.483613445378
+0 3 0 0 0 9 0 5 4 0 0 0 0 0 5 0 0 1 0 9 0 0 3 0 6 7 0 8 0 0 5 0 7 0 2 3 2 5 0 0 0 0 0 1 6 3 1 0 2 0 8 0 0 7 0 7 3 0 5 0 0 8 0 6 0 0 7 0 0 0 0 0 9 2 0 4 0 0 0 6 0	0.484397163121
+0 0 0 0 0 2 0 7 4 0 0 0 3 0 5 0 6 0 3 9 0 0 7 1 0 0 8 0 0 1 7 6 0 0 3 0 0 0 0 0 0 0 0 0 0 0 3 0 0 5 4 8 0 0 9 0 0 8 1 0 0 2 7 0 2 0 4 0 9 0 0 0 6 1 0 5 0 0 0 0 0	0.475490196078
+1 0 5 0 0 0 0 0 0 0 7 2 0 0 5 0 0 0 3 9 0 0 7 0 2 0 8 0 5 1 0 6 8 0 3 0 0 0 0 1 0 3 0 0 0 0 3 0 2 5 0 8 1 0 9 0 3 0 1 0 0 2 7 0 0 0 4 0 0 6 8 0 0 0 0 0 0 0 4 0 3	0.488289601555
+0 0 0 0 0 0 0 0 0 3 2 0 9 0 0 0 0 0 9 6 0 5 0 0 2 0 1 2 0 9 3 0 0 1 6 0 4 0 8 0 1 0 3 0 9 0 1 3 0 0 7 8 0 5 1 0 6 0 0 4 0 3 2 0 0 0 0 0 2 0 4 6 0 0 0 0 0 0 0 0 0	0.514523809524
+5 8 0 0 2 1 0 0 3 0 2 1 0 0 0 0 5 7 0 0 7 5 0 0 0 0 0 0 7 0 3 8 5 0 0 4 0 0 8 0 0 0 3 0 0 6 0 0 4 9 7 0 2 0 0 0 0 0 0 4 7 0 0 8 3 0 0 0 0 9 4 0 7 0 0 6 3 0 0 1 8	0.503546099291
+0 0 9 2 1 5 0 0 7 0 0 0 0 6 0 2 0 5 0 0 0 0 9 0 3 0 8 0 0 6 5 0 0 9 2 0 0 0 0 0 0 0 0 0 0 0 5 4 0 0 1 6 0 0 3 0 7 0 8 0 0 0 0 4 0 2 0 5 0 0 0 0 5 0 0 3 2 9 7 0 0	0.484640522876
+0 0 9 2 0 0 0 0 0 0 0 0 0 6 0 0 0 5 6 2 5 7 0 0 3 1 8 0 7 0 0 0 0 9 0 4 9 0 3 0 0 0 5 0 1 2 0 4 0 0 0 0 8 0 3 9 7 0 0 6 1 5 2 4 0 0 0 5 0 0 0 0 0 0 0 0 0 9 7 0 0	0.582717849044
+8 0 0 0 1 0 4 0 0 0 4 0 0 6 0 2 0 0 0 2 0 0 9 4 3 0 8 1 0 6 5 3 0 0 2 0 0 0 3 6 0 2 5 0 0 0 5 0 0 7 1 6 0 3 3 0 7 4 8 0 0 5 0 0 0 2 0 5 0 0 3 0 0 0 8 0 2 0 0 0 6	0.459259259259
+1 0 3 0 0 5 7 0 0 0 7 5 0 9 0 1 3 0 0 0 8 7 1 0 5 0 9 3 0 0 0 0 8 0 0 0 0 0 2 0 0 0 4 0 0 0 0 0 6 0 0 0 0 2 2 0 4 0 6 9 8 0 0 0 3 6 0 4 0 2 9 0 0 0 7 1 0 0 3 0 4	0.453546099291
+0 5 7 2 0 0 1 8 0 3 0 1 0 6 0 7 0 4 0 0 8 7 0 1 0 0 0 0 0 6 0 7 0 0 0 1 0 0 0 4 0 8 0 0 0 7 0 0 0 2 0 8 0 0 0 0 0 5 0 7 4 0 0 1 0 4 0 8 0 2 0 5 0 8 5 0 0 2 3 6 0	0.509219858156
+0 3 0 9 0 6 7 5 0 0 0 0 0 8 2 0 0 4 0 0 0 3 4 5 0 1 0 0 0 9 0 6 7 0 0 1 8 0 0 0 0 0 0 0 7 7 0 0 8 2 0 9 0 0 0 7 0 4 5 8 0 0 0 5 0 0 2 3 0 0 0 0 0 1 3 6 0 9 0 2 0	0.46798378926
+6 0 5 0 1 0 0 0 0 0 1 0 5 0 9 0 6 0 0 9 0 0 0 7 2 0 0 9 0 0 1 5 8 7 0 6 0 3 0 0 0 0 0 9 0 1 0 6 3 9 2 0 0 8 0 0 3 8 0 0 0 4 0 0 6 0 9 0 3 0 8 0 0 0 0 0 4 0 6 0 3	0.450354609929
+8 0 6 5 0 2 0 7 0 2 0 5 4 0 0 0 0 0 4 0 7 9 0 0 2 5 0 0 0 0 0 0 0 0 8 7 9 0 1 0 0 0 3 0 6 6 4 0 0 0 0 0 0 0 0 2 9 0 0 4 8 0 3 0 0 0 0 0 3 7 0 5 0 6 0 7 0 8 1 0 2	0.515197568389
+0 0 0 0 0 7 0 0 0 5 0 9 0 1 0 3 7 8 7 8 0 0 5 0 6 0 0 1 0 0 5 2 0 0 9 0 0 0 2 3 0 6 1 0 0 0 6 0 0 9 1 0 0 3 0 0 6 0 7 0 0 2 4 8 7 5 0 6 0 9 0 1 0 0 0 1 0 0 0 0 0	0.477862208713
+0 0 0 0 0 0 0 4 0 0 0 7 0 0 0 0 3 8 0 4 0 0 5 8 0 0 0 0 0 8 0 6 1 3 2 4 0 3 4 0 8 0 9 1 0 1 5 2 9 4 0 6 0 0 0 0 0 1 9 0 0 6 0 8 1 0 0 0 0 2 0 0 0 7 0 0 0 0 0 0 0	0.528666666667
+7 0 0 0 0 4 0 0 0 2 0 3 9 0 0 6 0 0 0 0 4 6 1 3 7 0 8 5 0 0 0 9 0 0 1 0 0 0 8 2 0 1 4 0 0 0 4 0 0 8 0 0 0 9 3 0 1 7 6 9 5 0 0 0 0 9 0 0 2 1 0 6 0 0 0 1 0 0 0 0 2	0.564741641337
+0 0 0 0 8 0 0 0 1 9 8 0 3 0 5 6 0 0 7 3 0 0 0 0 0 9 0 0 0 0 8 6 4 0 1 0 8 0 6 1 0 3 9 0 4 0 5 0 2 7 9 0 0 0 0 4 0 0 0 0 0 5 6 0 0 7 6 0 1 0 8 3 6 0 0 0 3 0 0 0 0	0.491134751773
+4 0 0 9 0 0 0 3 0 0 8 0 3 0 5 6 0 0 7 3 0 0 1 0 0 0 0 3 0 0 8 0 0 7 1 0 0 0 6 0 0 0 9 0 0 0 5 4 0 0 9 0 0 8 0 0 0 0 9 0 0 5 6 0 0 7 6 0 1 0 8 0 0 1 0 0 0 2 0 0 9	0.576050420168
+0 0 5 0 2 0 4 0 8 0 3 0 0 0 5 9 0 2 0 0 0 3 0 6 0 1 0 0 2 0 0 0 0 7 0 6 0 0 0 5 0 2 0 0 0 8 0 7 0 0 0 0 4 0 0 9 0 2 0 4 0 0 0 5 0 8 9 0 0 0 2 0 2 0 1 0 8 0 3 0 0	0.495051353875
+0 0 0 0 0 7 0 4 2 0 9 7 5 2 0 0 6 0 8 0 0 4 0 0 0 7 0 0 0 6 0 7 0 0 3 0 3 0 0 0 0 0 0 0 8 0 8 0 0 5 0 6 0 0 0 6 0 0 0 8 0 0 5 0 2 0 0 3 9 7 8 0 7 3 0 2 0 0 0 0 0	0.55116713352
+0 0 3 9 8 6 7 1 0 2 0 0 0 3 1 0 0 6 0 6 0 0 0 0 5 3 0 0 0 0 0 4 8 0 2 0 0 0 0 0 0 0 0 0 0 0 9 0 6 1 0 0 0 0 0 2 4 0 0 0 0 7 0 1 0 0 8 6 0 0 0 3 0 3 8 1 2 4 6 0 0	0.531632653061
+5 0 3 9 8 0 0 0 0 0 8 0 5 0 0 0 0 0 9 6 0 4 7 0 0 3 8 3 0 0 0 0 0 0 2 5 0 7 5 0 0 0 1 6 0 4 9 0 0 0 0 0 0 7 6 2 0 0 5 9 0 7 1 0 0 0 0 0 7 0 4 0 0 0 0 0 2 4 6 0 9	0.599290780142
+5 0 9 4 0 0 0 0 0 6 0 0 0 3 7 5 9 0 0 3 7 5 6 9 0 0 0 0 0 0 7 4 0 0 8 0 0 0 6 2 0 3 4 0 0 0 4 0 0 9 6 0 0 0 0 0 0 6 2 8 7 1 0 0 6 2 3 7 0 0 0 9 0 0 0 0 0 1 6 0 3	0.551851851852
+1 0 5 7 0 6 0 2 0 0 3 0 2 0 9 0 5 1 0 2 0 0 0 0 7 0 0 0 0 3 0 0 8 5 0 0 0 4 0 3 0 5 0 7 0 0 0 1 6 0 0 9 0 0 0 0 8 0 0 0 0 1 0 3 1 0 8 0 7 0 9 0 0 7 0 9 0 2 8 0 4	0.537993920973
+4 0 5 0 0 0 0 7 0 0 1 0 4 7 5 0 9 3 9 0 0 2 0 6 0 0 0 6 0 0 0 2 0 1 0 5 0 0 0 0 0 0 0 0 0 1 0 3 0 9 0 0 0 7 0 0 0 5 0 3 0 0 8 3 7 0 1 4 2 0 5 0 0 4 0 0 0 0 3 0 2	0.483333333333
+1 8 4 2 0 0 0 0 0 0 6 0 0 0 9 1 2 0 0 2 0 0 8 0 0 0 0 0 1 8 0 5 0 0 0 0 9 0 0 0 0 0 0 0 3 0 0 0 0 1 0 6 5 0 0 0 0 0 9 0 0 8 0 0 5 7 1 0 0 0 9 0 0 0 0 0 0 3 5 4 7	0.594923629829
+4 3 0 2 0 5 0 0 0 0 9 2 0 7 0 5 0 0 0 0 0 8 4 1 2 0 3 0 1 0 0 0 0 8 3 2 0 0 0 0 0 0 0 0 0 9 8 6 0 0 0 0 7 0 2 0 3 6 1 9 0 0 0 0 0 9 0 3 0 6 1 0 0 0 0 7 0 4 0 2 9	0.495390070922
+0 0 0 0 2 0 1 0 0 3 0 0 0 9 0 2 0 6 0 9 5 1 6 0 0 8 0 0 1 0 0 0 6 4 0 0 0 8 0 0 0 0 0 2 0 0 0 7 2 0 0 0 6 0 0 7 0 0 3 9 8 1 0 1 0 9 0 8 0 0 0 4 0 0 6 0 7 0 0 0 0	0.490522875817
+0 0 9 0 1 0 3 2 0 2 7 0 9 3 0 6 0 1 0 0 3 0 6 2 4 0 0 0 1 0 5 7 0 0 3 0 0 0 2 0 0 0 5 0 0 0 3 0 0 2 6 0 1 0 0 0 7 6 5 0 1 0 0 3 0 6 0 9 7 0 4 5 0 5 1 0 8 0 7 0 0	0.508914728682
+0 0 4 7 0 0 0 0 3 3 0 0 0 1 4 0 7 0 8 7 0 3 0 0 0 9 4 0 0 5 0 4 7 3 0 0 0 3 7 0 0 0 4 8 0 0 0 2 8 3 0 9 0 0 2 4 0 0 0 9 0 3 6 0 9 0 4 6 0 0 0 8 5 0 0 0 0 3 2 0 0	0.450740740741
+0 0 0 0 0 9 7 0 4 8 0 0 6 0 4 3 0 5 0 0 0 0 8 0 0 0 2 6 0 0 0 7 0 0 2 0 7 8 0 2 0 5 0 6 9 0 5 0 0 4 0 0 0 7 3 0 0 0 6 0 0 0 0 5 0 7 3 0 8 0 0 6 9 0 6 1 0 0 0 0 0	0.486734693878
+2 0 0 0 0 6 0 0 0 0 7 1 8 2 0 4 0 0 0 0 8 0 0 0 3 0 0 0 1 0 2 6 0 7 0 0 4 2 0 5 0 7 0 6 1 0 0 7 0 9 4 0 3 0 0 0 4 0 0 0 6 0 0 0 0 2 0 4 1 8 7 0 0 0 0 7 0 0 0 0 3	0.56156462585
+3 0 0 2 0 0 6 9 0 8 0 0 3 6 0 4 0 7 0 0 0 0 0 0 0 0 3 0 1 0 7 0 0 8 4 0 0 7 8 0 2 0 3 1 0 0 3 6 0 0 4 0 7 0 1 0 0 0 0 0 0 0 0 7 0 4 0 3 9 0 0 5 0 6 2 0 0 8 0 0 4	0.523611111111
+3 0 0 0 0 0 6 9 0 8 2 0 0 0 1 0 0 0 0 5 1 9 0 7 0 8 0 0 0 0 0 9 0 8 0 6 0 7 8 0 0 0 3 1 0 9 0 6 0 1 0 0 0 0 0 9 0 4 0 2 7 6 0 0 0 0 6 0 0 0 2 5 0 6 2 0 0 0 0 0 4	0.536005830904
+0 7 4 5 0 6 0 1 3 9 0 0 0 3 7 0 0 0 0 0 2 0 0 0 0 0 4 0 0 5 1 0 0 0 4 9 0 1 0 0 0 0 0 7 0 7 4 0 0 0 2 1 0 0 4 0 0 0 0 0 5 0 0 0 0 0 2 6 0 0 0 7 1 9 0 7 0 4 2 3 0	0.598639455782
+5 0 0 0 8 0 4 1 0 0 7 0 0 0 0 0 0 0 8 0 6 0 0 9 0 0 3 0 3 0 0 0 2 0 5 1 0 5 2 1 0 4 3 6 0 1 6 0 8 0 0 0 2 0 6 0 0 3 0 0 8 0 7 0 0 0 0 0 0 0 4 0 0 8 1 0 4 0 0 0 6	0.531438289602
+0 0 7 8 0 0 0 1 0 9 0 0 3 0 4 0 0 8 6 3 0 0 0 1 2 0 0 3 8 6 2 0 0 0 0 1 0 0 0 0 0 0 0 0 0 4 0 0 0 0 5 8 3 7 0 0 1 7 0 0 0 4 5 8 0 0 1 0 2 0 0 9 0 6 0 0 0 3 1 0 0	0.454081632653
+0 1 6 9 0 4 5 0 0 0 7 0 0 0 5 1 4 0 0 0 0 0 0 0 0 0 9 3 0 4 0 1 0 7 9 0 9 0 0 0 0 0 0 0 3 0 2 1 0 3 0 4 0 6 1 0 0 0 0 0 0 0 0 0 3 7 6 0 0 0 2 0 0 0 8 2 0 1 3 5 0	0.476044703596
+1 8 5 0 0 0 4 9 0 0 0 0 4 0 0 0 0 0 0 7 0 3 0 8 0 0 5 9 2 0 5 0 0 3 0 0 0 4 0 8 0 3 0 2 0 0 0 8 0 0 9 0 5 4 6 0 0 9 0 7 0 3 0 0 0 0 0 0 5 0 0 0 0 5 9 0 0 0 7 6 2	0.52074829932
+1 6 0 3 0 0 2 0 0 0 0 2 0 8 1 0 0 7 0 0 0 0 0 0 0 1 9 0 0 5 0 0 0 3 6 1 0 0 0 0 9 0 0 0 0 8 2 1 0 0 0 5 0 0 5 8 0 0 0 0 0 0 0 3 0 0 9 5 0 7 0 0 0 0 6 0 0 3 0 8 5	0.485302197802
+4 0 8 0 5 0 0 0 0 5 9 0 0 0 3 0 4 8 7 0 0 6 0 0 0 9 0 0 8 2 0 0 0 0 1 0 0 0 7 0 3 0 9 0 0 0 5 0 0 0 0 6 3 0 0 6 0 0 0 2 0 0 9 8 7 0 5 0 0 0 2 3 0 0 0 0 9 0 1 0 7	0.512952380952
+0 0 0 2 5 0 3 7 0 5 9 0 0 0 3 2 0 8 7 2 3 6 0 0 0 9 0 0 8 0 9 0 0 0 0 5 6 4 0 0 3 0 0 8 2 9 0 0 0 0 7 0 3 0 0 6 0 0 0 2 8 5 9 8 0 9 5 0 0 0 2 3 0 3 5 0 9 8 0 0 0	0.5
+0 0 4 8 0 7 1 0 0 8 0 2 0 0 4 0 7 0 0 0 0 2 1 0 0 0 0 0 4 0 0 0 0 7 3 0 7 0 0 4 2 3 0 0 5 0 3 1 0 0 0 0 4 0 0 0 0 0 4 1 0 0 0 0 6 0 7 0 0 8 0 4 0 0 3 9 0 6 5 0 0	0.504666666667
+0 6 8 0 2 5 7 0 3 0 0 0 0 0 0 0 0 0 0 7 1 0 0 3 9 0 0 6 1 0 3 5 0 2 0 0 0 8 0 0 0 0 0 4 0 0 0 3 0 6 4 0 9 5 0 0 7 6 0 0 5 8 0 0 0 0 0 0 0 0 0 0 8 0 6 5 3 0 4 2 0	0.583746355685
+0 0 0 0 2 0 0 1 0 0 0 9 0 0 0 0 0 4 5 0 1 0 0 3 9 0 0 6 1 0 3 0 9 2 7 8 9 0 0 0 0 0 0 0 6 7 2 3 8 0 4 0 9 5 0 0 7 6 0 0 5 0 1 1 0 0 0 0 0 6 0 0 0 9 0 0 3 0 0 0 0	0.512585034014
+0 1 0 0 0 5 0 0 0 0 0 0 0 7 2 0 6 0 0 9 6 0 0 0 0 5 2 6 8 2 0 0 0 0 4 9 0 0 5 0 4 0 6 0 0 9 7 0 0 0 0 3 2 1 8 2 0 0 0 0 4 1 0 0 5 0 8 2 0 0 0 0 0 0 0 4 0 0 0 3 0	0.466333333333
+0 5 0 0 1 4 0 3 0 0 0 2 0 7 0 0 4 0 0 1 0 0 0 8 0 0 0 0 2 9 0 4 5 3 0 0 0 0 7 0 8 0 6 0 0 0 0 1 3 6 0 5 2 0 0 0 0 4 0 0 0 6 0 0 7 0 0 2 0 8 0 0 0 9 0 8 5 0 0 1 0	0.528285714286
+8 0 6 0 0 0 0 4 0 0 9 7 0 6 0 3 0 0 0 2 0 8 0 0 5 1 6 0 0 0 4 0 3 0 0 0 4 0 0 0 0 0 0 0 2 0 0 0 1 0 9 0 0 0 7 4 1 0 0 2 0 6 0 0 0 5 0 1 0 2 3 0 0 3 0 0 0 0 7 0 1	0.5110410831
+0 0 8 0 0 0 5 0 0 0 5 0 1 0 0 0 6 7 0 2 7 5 0 0 3 0 8 7 0 0 3 0 1 0 0 0 2 1 5 0 0 0 6 8 3 0 0 0 8 0 5 0 0 9 5 0 4 0 0 9 7 3 0 8 3 0 0 0 7 0 4 0 0 0 2 0 0 0 8 0 0	0.471631205674
+0 0 0 0 0 5 0 0 4 0 0 3 4 0 0 7 9 0 0 7 0 3 1 0 5 0 0 8 0 6 1 0 0 0 0 3 2 0 0 0 0 0 0 0 9 7 0 0 0 0 3 2 0 8 0 0 5 0 3 2 0 6 0 0 8 7 0 0 6 3 0 0 3 0 0 7 0 0 0 0 0	0.482026143791
+6 8 0 4 5 0 0 7 0 0 5 0 0 0 7 4 0 0 0 0 0 1 0 2 6 5 0 1 0 0 9 4 0 0 6 0 0 0 0 0 3 0 0 0 0 0 3 0 0 1 5 0 0 7 0 1 7 5 0 4 0 0 0 0 0 5 6 0 0 0 8 0 0 6 0 0 7 1 0 2 4	0.553786375661
+5 0 1 0 7 0 0 0 0 8 0 3 1 0 4 0 0 0 7 0 0 5 0 8 0 0 0 2 0 0 0 0 0 0 3 8 0 3 8 0 0 0 7 5 0 1 7 0 0 0 0 0 0 6 0 0 0 6 0 7 0 0 1 0 0 0 2 0 1 8 0 4 0 0 0 0 9 0 6 0 5	0.531325863679
+5 0 7 6 0 0 0 0 2 0 0 0 0 7 3 8 0 1 0 2 0 9 0 0 0 7 0 0 0 0 1 6 7 5 8 9 0 0 0 0 0 0 0 0 0 6 1 9 8 5 2 0 0 0 0 6 0 0 0 1 0 3 0 1 0 4 3 2 0 0 0 0 9 0 0 0 0 6 1 0 8	0.486068895643
+0 0 0 0 0 0 0 7 0 4 0 0 0 1 0 5 0 0 0 7 0 0 6 9 0 3 8 2 5 0 0 0 6 3 0 0 6 4 0 2 0 5 0 1 9 0 0 8 9 0 0 0 5 6 7 2 0 6 5 0 0 8 0 0 0 5 0 7 0 0 0 1 0 8 0 0 0 0 0 0 0	0.480272108844
+8 9 1 0 2 0 6 7 4 4 0 0 0 1 8 5 0 0 0 7 0 0 6 0 0 0 0 0 0 0 0 0 6 3 4 0 6 0 0 0 0 0 0 0 9 0 1 8 9 0 0 0 0 0 0 0 0 0 5 0 0 8 0 0 0 5 8 7 0 0 0 1 1 8 6 0 9 0 7 2 5	0.458865248227
+2 0 7 6 0 3 4 0 0 0 1 6 8 0 0 9 0 0 4 0 0 0 7 0 5 0 0 0 2 0 0 0 0 7 0 8 0 0 9 0 0 0 3 0 0 7 0 1 0 0 0 0 9 0 0 0 5 0 4 0 0 0 9 0 0 4 0 0 7 6 3 0 0 0 2 3 0 5 1 0 7	0.476530612245
+0 4 0 0 1 5 0 9 7 0 7 2 0 9 6 4 0 0 0 0 0 7 0 0 0 0 0 0 0 4 1 3 0 0 7 0 3 1 0 6 0 2 0 5 4 0 6 0 0 7 4 2 0 0 0 0 0 0 0 7 0 0 0 0 0 9 4 6 0 5 2 0 5 3 0 9 2 0 0 4 0	0.559259259259
+0 4 3 0 0 0 0 9 0 0 0 0 0 0 0 0 0 5 6 0 0 7 4 8 1 0 2 0 0 4 1 0 9 8 0 0 0 1 0 6 0 2 0 5 0 0 0 8 5 0 4 2 0 0 4 0 1 8 5 7 0 0 9 7 0 0 0 0 0 0 0 0 0 3 0 0 0 0 7 4 0	0.460204081633
+0 0 6 1 2 0 0 0 0 0 0 0 0 7 8 0 2 0 4 0 3 5 0 9 0 0 7 0 3 5 0 8 0 0 0 2 0 0 9 0 3 0 1 0 0 7 0 0 0 5 0 6 3 0 1 0 0 2 0 5 3 0 8 0 5 0 8 4 0 0 0 0 0 0 0 0 1 7 2 0 0	0.480208333333
+0 0 6 0 0 4 5 0 3 5 0 0 3 7 0 0 2 6 4 0 3 5 0 0 0 0 0 0 0 0 4 8 0 0 7 0 0 0 9 0 3 0 1 0 0 0 1 0 0 5 2 0 0 0 0 0 0 0 0 5 3 0 8 9 5 0 0 4 3 0 0 1 3 0 4 6 0 0 2 0 0	0.467361111111
+0 0 9 0 0 0 7 8 0 0 0 0 7 0 1 3 0 0 0 3 0 2 8 9 0 0 4 0 8 0 0 0 0 0 0 7 9 2 0 5 0 7 0 3 6 5 0 0 0 0 0 0 2 0 4 0 0 6 2 8 0 7 0 0 0 8 3 0 4 0 0 0 0 9 3 0 0 0 6 0 0	0.484256559767
+0 0 0 0 0 4 8 7 0 0 7 0 6 2 0 1 5 0 0 2 0 7 0 0 9 0 6 0 6 0 9 3 0 0 4 1 1 0 0 2 0 7 0 0 5 2 3 0 0 6 1 0 9 0 6 0 7 0 0 2 0 1 0 0 8 1 0 7 6 0 2 0 0 5 2 1 0 0 0 0 0	0.536046511628
+9 1 6 0 0 4 0 7 2 8 0 0 6 2 0 0 5 0 5 0 0 0 0 8 9 3 0 0 6 0 0 0 0 2 0 0 0 0 0 2 0 7 0 0 0 0 0 5 0 0 0 0 9 0 0 9 7 8 0 0 0 0 3 0 8 0 0 7 6 0 0 9 4 5 0 1 0 0 6 8 7	0.459878419453
+0 0 0 9 0 0 0 8 2 0 6 3 0 0 1 4 0 9 9 0 8 0 0 0 0 0 0 0 0 0 6 7 0 3 0 0 0 4 6 0 5 0 2 9 0 0 0 7 0 2 3 0 0 0 0 0 0 0 0 0 7 0 1 7 0 4 3 0 0 6 2 0 6 3 0 0 0 7 0 0 0	0.506380952381
+0 3 5 6 7 0 0 0 0 4 0 0 8 2 9 5 0 0 0 8 0 0 0 3 0 6 0 0 2 0 0 0 5 8 0 7 8 0 0 2 0 6 0 0 5 3 0 1 7 0 0 0 2 0 0 4 0 9 0 0 0 7 0 0 0 2 4 8 7 0 0 6 0 0 0 0 5 2 4 9 0	0.482592592593
+0 3 0 0 7 0 9 0 2 4 7 0 0 0 9 0 0 0 0 0 9 0 0 3 0 6 0 0 2 4 0 0 0 8 3 7 0 0 7 0 0 0 1 0 0 3 5 1 0 0 0 6 2 0 0 4 0 9 0 0 2 0 0 0 0 0 4 0 0 0 5 6 7 0 8 0 5 0 0 9 0	0.598639455782
+0 8 4 2 0 0 0 0 0 9 3 0 8 4 0 0 0 0 0 5 7 0 0 0 0 0 0 6 0 0 4 0 1 7 0 0 4 0 0 0 7 0 0 0 2 0 0 5 6 0 2 0 0 9 0 0 0 0 0 0 9 8 0 0 0 0 0 2 8 0 4 7 0 0 0 0 0 3 2 1 0	0.560210622711
+0 0 7 8 6 1 0 0 0 0 0 8 0 0 3 0 0 0 5 6 0 0 9 0 0 1 0 1 0 0 0 7 0 0 8 5 0 0 0 3 4 5 0 0 0 6 3 0 0 1 0 0 0 7 0 5 0 0 2 0 0 9 8 0 0 0 6 0 0 5 0 0 0 0 0 5 3 7 1 0 0	0.595333333333
+0 4 0 0 0 1 0 0 3 0 0 0 0 5 0 0 7 9 5 6 0 0 0 2 8 0 4 1 0 0 2 7 0 0 8 0 0 8 2 0 0 0 9 6 0 0 3 0 0 1 8 0 0 7 3 0 6 1 0 0 0 9 8 4 7 0 0 8 0 0 0 0 8 0 0 5 0 0 0 4 0	0.46443768997
+0 0 0 5 0 0 0 0 6 0 0 0 8 7 0 3 0 2 2 7 0 3 0 0 0 8 1 0 0 0 0 3 4 9 0 0 7 9 3 0 5 0 6 1 4 0 0 8 7 9 0 0 0 0 9 2 0 0 0 3 0 5 7 5 0 6 0 8 7 0 0 0 3 0 0 0 0 5 0 0 0	0.597826086957
+0 0 0 9 0 0 0 6 7 0 9 0 0 0 0 2 0 8 4 6 0 0 7 8 0 0 0 3 2 0 0 9 4 0 7 0 7 0 0 6 0 3 0 0 2 0 1 0 7 8 0 0 4 3 0 0 0 8 5 0 0 1 6 5 0 1 0 0 0 0 9 0 6 7 0 0 0 9 0 0 0	0.478723404255
+0 2 4 0 0 0 0 1 7 0 0 0 3 0 1 0 0 0 3 0 0 0 0 0 9 6 5 2 0 1 0 0 0 6 5 0 0 0 0 6 3 7 0 0 0 0 9 3 0 0 0 7 0 8 5 3 9 0 0 0 0 0 1 0 0 0 5 0 2 0 0 0 8 4 0 0 0 0 5 7 0	0.526333333333
+2 0 0 0 0 6 1 4 3 0 0 4 0 0 0 6 0 0 6 0 7 0 0 8 0 2 9 1 0 0 8 0 0 2 0 0 0 0 3 0 9 0 8 0 0 0 0 5 0 0 3 0 0 1 8 3 0 5 0 0 9 0 2 0 0 6 0 0 0 4 0 0 9 4 2 6 0 0 0 0 5	0.498363095238
+5 0 4 0 0 2 0 3 0 9 0 0 0 7 3 0 0 8 6 7 0 0 0 0 0 2 0 0 0 0 0 3 0 7 8 0 0 0 5 7 0 9 2 0 0 0 4 7 0 6 0 0 0 0 0 5 0 0 0 0 0 1 4 1 0 0 4 5 0 0 0 9 0 6 0 3 0 0 5 0 2	0.472789115646
+5 8 0 0 0 0 6 3 7 0 0 0 0 0 0 0 0 0 6 0 3 5 4 0 0 0 0 0 9 0 1 0 4 7 0 5 0 1 0 7 0 9 0 4 0 8 0 7 2 0 5 0 9 0 0 0 0 0 2 6 3 0 4 0 0 0 0 0 0 0 0 0 4 6 8 0 0 0 0 7 2	0.569144800777
+0 0 0 0 1 0 0 0 0 9 0 0 0 0 3 4 0 8 6 7 0 5 0 0 0 2 1 0 0 0 1 3 0 7 8 0 0 1 5 0 0 0 2 4 0 0 4 7 0 6 5 0 0 0 7 5 0 0 0 6 0 1 4 1 0 2 4 0 0 0 0 9 0 0 0 0 9 0 0 0 0	0.47619047619
+7 8 0 3 0 0 0 5 0 9 5 6 0 0 0 0 0 0 0 0 2 0 6 5 0 0 1 0 0 3 4 0 0 5 7 0 6 0 0 0 0 0 0 0 3 0 2 5 0 0 8 1 0 0 2 0 0 5 9 0 8 0 0 0 0 0 0 0 0 4 1 7 0 3 0 0 0 4 0 2 5	0.480612244898
+2 0 0 3 6 7 5 0 0 5 0 0 8 0 0 0 6 0 3 0 0 4 5 0 7 0 0 0 9 0 5 3 0 4 0 0 0 8 0 0 0 0 0 7 0 0 0 3 0 7 4 0 5 0 0 0 1 0 2 6 0 0 5 0 3 0 0 0 5 0 0 7 0 0 2 7 8 3 0 0 1	0.59804964539
+8 0 1 0 5 6 2 0 0 0 0 0 0 0 2 3 8 1 9 0 0 0 0 3 0 0 0 3 5 0 4 7 0 0 0 0 0 0 8 0 0 0 1 0 0 0 0 0 0 6 8 0 3 7 0 0 0 6 0 0 0 0 2 6 8 7 1 0 0 0 0 0 0 0 4 5 3 0 8 0 6	0.517735665695
+3 0 0 0 0 4 0 0 5 8 4 1 7 5 3 0 6 0 0 0 0 0 1 0 0 0 0 0 0 3 0 0 0 0 8 7 0 9 8 1 0 7 5 4 0 7 5 0 0 0 0 1 0 0 0 0 0 0 7 0 0 0 0 0 3 0 2 8 1 7 9 6 2 0 0 3 0 0 0 0 8	0.562765957447
+0 0 0 0 6 4 8 1 0 0 4 0 0 5 0 0 6 2 0 0 9 0 1 0 3 0 0 0 0 3 0 4 0 6 0 7 0 0 8 1 0 7 5 0 0 7 0 4 0 3 0 1 0 0 0 0 6 0 7 0 2 0 0 4 3 0 0 8 0 0 9 0 0 1 7 3 9 0 0 0 0	0.450354609929
+0 0 0 0 4 0 3 2 0 0 0 0 3 5 7 0 8 0 0 0 0 6 0 0 4 0 0 3 5 7 0 0 6 0 4 0 6 0 0 7 0 5 0 0 3 0 8 0 9 0 0 6 7 5 0 0 8 0 0 9 0 0 0 0 9 0 5 8 1 0 0 0 0 6 4 0 7 0 0 0 0	0.459135082604
+9 0 5 0 4 0 0 2 6 0 2 6 0 5 0 9 0 0 0 3 0 6 0 0 0 5 0 3 5 0 0 0 0 0 0 9 0 0 9 0 2 0 8 0 0 1 0 0 0 0 0 0 7 5 0 1 0 0 0 9 0 3 0 0 0 3 0 8 0 7 6 0 5 6 0 0 7 0 1 0 8	0.450396825397
+0 1 0 4 0 3 0 6 0 0 3 0 0 1 7 4 0 0 2 0 0 0 0 0 3 0 0 0 7 0 0 8 0 0 0 4 0 9 2 3 5 4 7 8 0 5 0 0 0 7 0 0 3 0 0 0 3 0 0 0 0 0 5 0 0 8 5 3 0 0 4 0 0 5 0 9 0 6 0 2 0	0.577058531746
+6 0 5 9 0 0 1 0 0 0 0 0 1 0 0 0 7 3 0 7 1 3 0 0 0 0 5 0 0 9 0 1 0 0 0 4 0 4 6 2 9 3 5 1 0 7 0 0 0 4 0 6 0 0 2 0 0 0 0 1 7 3 0 1 6 0 0 0 2 0 0 0 0 0 8 0 0 9 4 0 1	0.467391304348
+0 4 9 0 6 0 0 0 2 8 0 0 2 1 0 4 9 0 1 0 0 0 4 0 0 0 0 0 0 0 0 3 5 0 8 4 0 0 8 1 0 2 3 0 0 6 3 0 4 7 0 0 0 0 0 0 0 0 8 0 0 0 1 0 8 4 0 5 1 0 0 6 7 0 0 0 2 0 9 5 0	0.573530901722
+0 6 7 0 2 0 3 0 0 0 0 3 7 0 0 0 0 0 9 2 0 1 0 3 0 0 0 4 0 2 0 3 5 0 6 0 3 0 0 0 0 0 0 0 2 0 1 0 2 4 0 9 0 3 0 0 0 5 0 8 0 3 9 0 0 0 0 0 9 2 0 0 0 0 8 0 1 0 7 5 0	0.509523809524
+0 5 0 8 4 2 0 0 1 0 0 4 0 0 0 9 0 0 8 0 0 0 5 0 0 4 0 6 0 0 4 0 0 0 1 9 0 0 7 5 0 6 8 0 0 4 3 0 0 0 9 0 0 2 0 8 0 0 9 0 0 0 6 0 0 1 0 0 0 4 0 0 5 0 0 6 8 1 0 9 0	0.467346938776
Index: gnome-sudoku/data/easy
===================================================================
--- gnome-sudoku/data/easy	(revision 0)
+++ gnome-sudoku/data/easy	(revision 0)
@@ -0,0 +1,149 @@
+0 1 0 0 4 0 5 6 0 2 3 0 6 1 5 0 8 0 0 0 0 8 0 0 1 0 0 0 5 0 0 2 0 0 0 8 6 0 0 7 8 1 0 0 5 9 0 0 0 6 0 0 2 0 0 0 6 0 0 8 0 0 0 0 8 0 4 7 3 0 5 6 0 4 5 0 9 0 0 1 0	0.300724637681
+0 1 7 0 0 2 5 6 0 0 3 4 0 1 5 0 8 0 0 0 9 0 0 0 1 4 0 4 5 0 0 0 0 6 0 0 0 2 0 7 8 1 0 9 0 0 0 8 0 0 0 0 2 1 0 9 6 0 0 0 2 0 0 0 8 0 4 7 0 9 5 0 0 4 5 2 0 0 8 1 0	0.272727272727
+0 0 7 0 4 0 0 0 3 0 0 0 6 0 0 7 0 9 0 0 0 8 3 0 0 4 0 4 5 1 0 2 0 6 7 8 6 2 0 0 0 0 0 9 5 9 7 8 0 6 0 3 2 1 0 9 0 0 5 8 0 0 0 1 0 2 0 0 3 0 0 0 3 0 0 0 9 0 8 0 0	0.283333333333
+0 0 0 0 0 9 0 5 6 5 0 0 7 8 0 1 0 0 0 0 0 5 0 3 8 0 9 6 5 0 8 0 4 7 9 2 0 2 0 0 0 0 0 6 0 3 9 7 6 0 2 0 1 8 4 0 3 1 0 5 0 0 0 0 0 5 0 4 8 0 0 1 2 1 0 3 0 0 0 0 0	0.375968992248
+7 8 0 0 0 0 0 5 0 5 0 9 7 0 0 0 2 0 0 4 0 0 2 0 0 7 9 6 0 0 0 0 0 7 9 2 0 0 4 9 0 1 5 0 0 3 9 7 0 0 0 0 0 8 4 6 0 0 9 0 0 8 0 0 7 0 0 0 8 6 0 1 0 1 0 0 0 0 0 4 5	0.292553191489
+7 0 0 4 0 9 0 0 6 5 0 9 0 8 6 1 2 0 1 4 0 0 0 0 0 0 0 6 5 0 8 0 0 0 0 0 0 2 4 9 0 1 5 6 0 0 0 0 0 0 2 0 1 8 0 0 0 0 0 0 0 8 7 0 7 5 2 4 0 6 0 1 2 0 0 3 0 7 0 0 5	0.2
+7 8 0 0 0 0 0 5 6 0 0 9 0 8 0 1 0 0 0 4 6 0 0 0 0 7 0 6 5 0 0 0 4 7 9 2 0 0 0 9 0 1 0 0 0 3 9 7 6 0 0 0 1 8 0 6 0 0 0 0 2 8 0 0 0 5 0 4 0 6 0 0 2 1 0 0 0 0 0 4 5	0.395035460993
+0 4 0 0 0 9 1 0 6 3 6 5 0 0 0 0 0 0 0 0 0 2 6 0 0 0 5 4 5 7 8 0 0 6 0 9 0 0 1 9 0 5 8 0 0 9 0 3 0 0 4 5 2 7 5 0 0 0 9 1 0 0 0 0 0 0 0 0 0 3 8 1 7 0 6 3 0 0 0 5 0	0.262962962963
+0 4 0 0 0 0 1 0 6 3 0 5 1 0 7 2 0 0 0 0 0 2 0 0 0 0 5 4 5 0 8 2 0 6 1 0 0 0 1 9 0 5 8 0 0 0 8 3 0 1 4 0 2 7 5 0 0 0 0 1 0 0 0 0 0 4 7 0 6 3 0 1 7 0 6 0 0 0 0 5 0	0.424444444444
+8 0 2 5 0 0 1 0 0 0 0 0 0 4 7 0 0 8 1 0 9 0 6 0 4 3 5 4 0 0 0 2 3 0 1 0 0 2 0 0 0 0 0 4 0 0 8 0 6 1 0 0 0 7 5 3 8 0 9 0 7 0 2 2 0 0 7 5 0 0 0 0 0 0 6 0 0 2 9 0 4	0.219259259259
+0 0 2 0 0 9 1 0 6 3 0 5 0 4 0 2 0 0 0 7 9 2 6 0 0 0 0 0 5 0 0 0 0 0 1 9 0 2 1 9 7 5 8 4 0 9 8 0 0 0 0 0 2 0 0 0 0 0 9 1 7 6 0 0 0 4 0 5 0 3 0 1 7 0 6 3 0 0 9 0 0	0.0738636363636
+8 4 0 0 3 9 1 0 0 3 6 0 1 0 0 0 0 8 1 0 9 2 0 0 0 0 0 0 5 0 8 0 0 6 0 0 0 0 1 9 0 5 8 0 0 0 0 3 0 0 4 0 2 0 0 0 0 0 0 1 7 0 2 2 0 0 0 0 6 0 8 1 0 0 6 3 8 0 0 5 4	0.325886524823
+0 0 9 0 0 5 0 7 1 5 0 0 7 0 6 0 0 0 0 0 8 4 9 0 0 3 5 0 3 0 0 1 8 2 0 0 0 9 0 3 4 2 0 6 0 0 0 2 9 6 0 0 4 0 9 2 0 0 7 4 3 0 0 0 0 0 6 0 9 0 0 2 7 6 0 8 0 0 4 0 0	0.151515151515
+6 4 0 0 0 0 8 0 1 5 0 0 7 0 0 0 2 0 2 7 0 4 9 0 0 0 0 0 3 6 5 1 8 0 9 0 0 0 0 3 0 2 0 0 0 0 5 0 9 6 7 1 4 0 0 0 0 0 7 4 0 8 6 0 8 0 0 0 9 0 0 2 7 0 1 0 0 0 0 5 9	0.0925925925926
+6 0 9 0 0 0 0 0 1 0 1 0 0 0 6 0 2 4 0 0 8 4 0 0 6 3 0 0 3 0 5 0 0 2 0 7 1 0 7 3 0 2 5 0 8 8 0 2 0 0 7 0 4 0 0 2 5 0 0 4 3 0 0 3 8 0 6 0 0 0 1 0 7 0 0 0 0 0 4 0 9	0.243650793651
+0 0 9 0 3 0 8 7 0 5 0 0 0 0 0 9 0 4 2 7 0 0 9 1 0 3 0 4 0 6 0 1 8 2 0 0 1 0 0 3 0 2 0 0 8 0 0 2 9 6 0 1 0 3 0 2 0 1 7 0 0 8 6 3 0 4 0 0 0 0 0 2 0 6 1 0 2 0 4 0 0	0.147286821705
+0 0 9 0 0 5 8 0 0 0 0 0 7 0 6 9 0 4 2 0 8 4 9 0 0 0 0 4 3 0 5 1 0 0 9 7 0 0 7 3 0 2 5 0 0 8 5 0 0 6 7 0 4 3 0 0 0 0 7 4 3 0 6 3 0 4 6 0 9 0 0 0 0 0 1 8 0 0 4 0 0	0.282945736434
+6 2 0 0 5 0 0 9 0 0 1 5 8 2 4 0 7 0 0 4 8 6 0 0 0 0 2 0 5 0 0 7 0 0 0 9 0 0 0 2 0 9 0 0 0 2 0 0 0 4 0 0 6 0 5 0 0 0 0 2 6 1 0 0 6 0 4 3 7 9 2 0 0 9 0 0 1 0 0 8 4	0.228148148148
+6 0 3 7 0 1 0 9 0 9 0 0 0 0 0 3 0 0 0 4 0 6 0 3 1 5 0 0 5 6 3 7 0 0 4 9 4 0 0 2 0 9 0 0 1 2 3 0 0 4 5 8 6 0 0 7 4 9 0 2 0 1 0 0 0 1 0 0 0 0 0 5 0 9 0 5 0 6 7 0 4	0.0691056910569
+0 7 0 0 0 3 0 2 8 0 0 9 6 0 0 1 0 0 0 1 0 0 2 9 0 6 3 0 8 4 7 0 0 0 0 6 1 6 7 0 0 0 5 8 4 9 0 0 0 0 6 2 1 0 8 3 0 2 6 0 0 7 0 0 0 1 0 0 4 8 0 0 7 4 0 3 0 0 0 5 0	0.0736434108527
+4 0 0 0 0 3 0 0 0 3 2 9 0 0 7 0 4 5 0 1 0 0 2 9 0 0 3 0 0 0 7 0 0 3 9 6 1 0 7 0 0 0 5 0 4 9 5 3 0 0 6 0 0 0 8 0 0 2 6 0 0 7 0 6 9 0 5 0 0 8 3 2 0 0 0 3 0 0 0 0 1	0.366666666667
+0 0 0 0 5 3 0 0 8 3 0 0 6 0 0 0 0 0 0 1 0 4 0 0 7 0 3 0 8 4 7 0 0 0 9 0 0 0 7 9 0 2 5 0 0 0 5 0 0 0 6 2 1 0 8 0 5 0 0 1 0 7 0 0 0 0 0 0 4 0 0 2 7 0 0 3 9 0 0 0 0	0.393744164332
+0 6 0 0 0 7 0 9 0 4 3 2 0 9 0 1 0 0 9 0 0 0 6 2 0 8 3 2 7 0 4 5 1 0 0 9 0 0 0 0 0 0 0 0 0 6 0 0 2 7 9 0 5 4 3 2 0 9 1 0 0 0 6 0 0 5 0 3 0 9 4 2 0 9 0 5 0 0 0 1 0	0.170542635659
+0 6 1 0 0 0 0 9 0 4 3 0 0 9 5 0 6 0 9 0 0 1 0 2 0 0 3 0 0 0 4 0 1 0 0 9 5 0 9 0 0 0 7 0 1 6 0 0 2 0 9 0 0 0 3 0 0 9 0 8 0 0 6 0 8 0 7 3 0 0 4 2 0 9 0 0 0 0 3 1 0	0.270212765957
+8 0 1 3 4 0 0 0 0 4 3 0 8 0 0 1 0 7 0 0 0 0 6 0 0 0 3 2 0 8 0 5 0 0 0 9 0 0 9 0 0 0 7 0 0 6 0 0 0 7 0 8 0 4 3 0 0 0 1 0 0 0 0 1 0 5 0 0 6 0 4 2 0 0 0 0 2 4 3 0 8	0.332653061224
+8 6 1 0 4 7 0 9 0 0 0 0 0 0 0 1 0 0 9 5 0 0 0 2 0 0 3 0 7 8 0 0 0 0 3 9 0 4 9 6 0 3 7 2 0 6 1 0 0 0 0 8 5 0 3 0 0 9 0 0 0 7 6 0 0 5 0 0 0 0 0 0 0 9 0 5 2 0 3 1 8	0.274074074074
+8 0 1 0 4 0 2 0 5 4 0 0 0 0 5 1 0 7 0 5 0 1 0 0 0 0 0 0 7 8 0 0 1 0 0 9 0 4 0 6 8 3 0 2 0 6 0 0 2 0 0 8 5 0 0 0 0 0 0 8 0 7 0 1 0 5 7 0 0 0 0 2 7 0 6 0 2 0 3 0 8	0.217391304348
+1 0 6 0 0 5 3 8 7 0 0 5 0 3 2 1 0 9 3 0 0 1 0 8 0 0 0 0 0 0 0 0 0 7 3 5 0 5 3 0 0 0 2 1 0 2 1 7 0 0 0 0 0 0 0 0 0 8 0 4 0 0 1 5 0 1 3 2 0 4 0 0 7 8 4 6 0 0 9 0 3	0.323643410853
+0 2 0 0 0 0 3 8 0 8 0 0 7 0 0 0 0 9 0 0 9 1 0 0 5 4 0 4 9 0 0 0 0 7 3 5 0 5 3 0 0 0 2 1 0 2 1 7 0 0 0 0 9 6 0 3 2 0 0 4 6 0 0 5 0 0 0 0 9 0 0 8 0 8 4 0 0 0 0 2 0	0.385309017224
+0 0 6 0 9 0 0 0 7 8 4 0 7 3 2 1 6 0 0 0 0 1 0 0 0 4 2 4 9 0 0 0 0 7 3 0 0 0 3 0 0 0 2 0 0 0 1 7 0 0 0 0 9 6 9 3 0 0 0 4 0 0 0 0 6 1 3 2 9 0 7 8 7 0 0 0 5 0 9 0 0	0.337407407407
+1 0 0 4 9 5 0 0 0 8 0 0 7 0 0 0 0 9 3 7 9 0 0 0 0 0 0 0 0 8 2 1 0 7 0 0 6 5 0 0 0 0 0 1 4 0 0 7 0 4 3 8 0 0 0 0 0 0 0 0 6 5 1 5 0 0 0 0 9 0 0 8 0 0 0 6 5 1 0 0 3	0.38537414966
+1 4 0 0 0 2 0 0 0 8 6 0 0 0 9 4 5 0 0 9 0 0 0 4 0 7 2 0 2 8 0 4 5 3 0 7 0 0 0 0 0 0 0 0 0 4 0 1 3 6 0 9 2 0 6 8 0 2 0 0 0 1 0 0 7 9 4 0 0 0 8 6 0 0 0 8 0 0 0 3 4	0.271111111111
+0 0 0 0 0 2 0 0 3 8 0 2 7 3 0 4 5 0 0 0 0 6 0 0 8 7 0 9 0 8 0 0 5 3 6 7 0 0 6 0 0 0 1 0 0 4 5 1 3 0 0 9 0 8 0 8 4 0 0 3 0 0 0 0 7 9 0 5 1 2 0 6 2 0 0 8 0 0 0 0 0	0.288888888889
+0 0 7 0 0 0 6 9 0 0 6 0 7 0 0 0 0 1 0 9 3 0 1 4 8 0 0 0 2 8 1 0 5 0 6 0 7 0 6 9 0 8 1 0 5 0 5 0 3 0 7 9 2 0 0 0 4 2 7 0 5 1 0 3 0 0 0 0 1 0 8 0 0 1 5 0 0 0 7 0 0	0.22519379845
+1 0 7 0 0 0 6 0 0 8 0 2 0 3 0 4 5 0 0 0 0 6 1 4 0 0 0 0 2 0 1 0 0 0 6 0 0 3 6 9 0 8 1 4 0 0 5 0 0 0 7 0 2 0 0 0 0 2 7 3 0 0 0 0 7 9 0 5 0 2 0 6 0 0 5 0 0 0 7 0 4	0.109929078014
+0 0 7 0 0 0 0 9 0 8 0 2 0 3 0 4 0 1 0 9 3 6 0 0 8 0 0 9 2 0 0 4 0 0 6 0 7 3 6 0 2 0 1 4 5 0 5 0 0 6 0 0 2 8 0 0 4 0 0 3 5 1 0 3 0 9 0 5 0 2 0 6 0 1 0 0 0 0 7 0 0	0.364393939394
+7 0 9 0 0 0 0 5 0 4 0 0 3 5 1 9 2 0 2 5 3 9 0 0 8 1 0 0 0 7 0 0 9 0 0 0 0 0 1 4 6 5 2 0 0 0 0 0 7 0 0 4 0 0 0 2 5 0 0 6 7 4 9 0 9 8 2 4 7 0 0 5 0 7 0 0 0 0 1 0 2	0.255952380952
+0 1 9 6 0 2 0 0 0 4 8 0 0 5 0 9 0 0 2 5 0 9 7 4 8 0 6 0 4 0 0 2 0 5 0 0 9 0 1 0 0 0 2 0 8 0 0 2 0 3 0 0 9 0 3 0 5 8 1 6 0 4 9 0 0 8 0 4 0 0 3 5 0 0 0 5 0 3 1 8 0	-0.00406504065041
+7 0 9 0 0 2 3 0 0 4 0 6 3 5 0 9 0 0 2 0 0 9 0 4 0 1 0 0 0 0 1 0 9 0 0 0 0 3 1 4 0 5 2 7 0 0 0 0 7 0 8 0 0 0 0 2 0 8 0 6 0 0 9 0 0 8 0 4 7 6 0 5 0 0 4 5 0 0 1 0 2	0.135185185185
+7 0 9 0 0 0 3 0 0 4 0 6 3 5 0 9 0 0 0 0 0 0 0 0 0 1 6 0 4 0 0 2 9 0 6 3 9 0 0 4 0 5 0 0 8 5 6 0 7 3 0 0 9 0 3 2 0 0 0 0 0 0 0 0 0 8 0 4 7 6 0 5 0 0 4 0 0 0 1 0 2	0.297872340426
+0 1 0 6 0 2 8 9 0 8 9 0 0 5 3 0 1 7 0 6 0 0 0 1 0 0 0 7 0 3 0 1 0 4 8 9 0 0 0 0 0 0 0 0 0 6 8 4 0 2 0 1 0 5 0 0 0 1 0 0 0 7 0 1 4 0 2 9 0 0 5 8 0 7 9 8 0 4 0 6 0	0.0116279069767
+4 0 5 0 7 0 8 9 0 0 0 2 0 5 0 6 0 0 0 0 7 9 0 0 5 4 2 0 0 3 5 0 6 4 8 9 0 0 0 3 0 8 0 0 0 6 8 4 7 0 9 1 0 0 2 3 8 0 0 5 9 0 0 0 0 6 0 9 0 3 0 0 0 7 9 0 3 0 2 0 1	0.174796747967
+0 1 5 0 0 0 0 9 0 0 9 2 4 5 3 0 0 7 0 6 0 0 8 0 5 0 0 7 0 0 5 1 0 4 8 0 0 5 0 3 0 8 0 2 0 0 8 4 0 2 9 0 0 5 0 0 8 0 6 0 0 7 0 1 0 0 2 9 7 3 5 0 0 7 0 0 0 0 2 6 0	0.186046511628
+0 1 0 0 0 2 8 0 3 8 0 2 0 0 0 0 1 7 0 6 0 9 8 0 5 4 2 0 0 3 0 1 0 0 8 9 0 0 1 0 4 0 7 0 0 6 8 0 0 2 0 1 0 0 2 3 8 0 6 5 0 7 0 1 4 0 0 0 0 3 0 8 5 0 9 8 0 0 0 6 0	0.230158730159
+6 0 2 0 0 8 0 3 0 1 0 8 0 3 6 7 0 2 7 0 0 5 0 0 8 6 0 9 2 0 0 6 0 3 0 0 0 0 1 0 0 0 6 0 0 0 0 3 0 4 0 0 1 5 0 8 9 0 0 1 0 0 6 3 0 5 6 2 0 1 0 9 0 1 0 8 0 0 5 0 3	0.279069767442
+6 0 2 7 0 0 9 0 4 0 9 0 4 3 6 7 0 0 0 3 0 0 0 0 0 0 1 0 0 0 0 6 0 0 0 8 0 0 1 2 0 3 6 0 0 8 0 0 0 4 0 0 0 0 2 0 0 0 0 0 0 7 0 0 0 5 6 2 4 0 8 0 4 0 6 0 0 9 5 0 3	0.33231292517
+6 0 0 7 0 8 9 0 0 1 0 0 0 3 6 7 5 0 7 0 4 5 0 0 0 6 1 0 2 7 0 0 0 0 4 8 0 0 1 0 0 0 6 0 0 8 6 0 0 0 0 2 1 0 2 8 0 0 0 1 4 0 6 0 7 5 6 2 0 0 0 9 0 0 6 8 0 9 0 0 3	0.12984496124
+0 5 0 0 0 8 9 0 0 0 0 0 4 3 6 7 0 0 0 3 0 0 0 0 0 6 1 9 0 7 1 0 5 3 0 8 0 0 0 0 0 0 0 0 0 8 0 3 9 0 7 2 0 5 2 8 0 0 0 0 0 7 0 0 0 5 6 2 4 0 0 0 0 0 6 8 0 0 0 2 0	0.440476190476
+0 0 0 0 0 9 8 0 0 0 0 0 2 5 3 0 0 1 1 6 0 7 0 0 2 3 0 6 9 2 0 7 0 5 0 8 0 0 1 0 0 0 9 0 0 4 0 8 0 9 0 3 6 2 0 5 6 0 0 7 0 9 3 9 0 0 5 3 2 0 0 0 0 0 4 9 0 0 0 0 0	0.324074074074
+0 2 3 0 1 9 0 0 0 0 0 9 0 5 3 6 0 0 1 6 0 7 4 0 0 0 9 0 9 0 3 0 4 0 0 8 0 3 0 0 2 0 0 4 0 4 0 0 1 0 5 0 6 0 2 0 0 0 8 7 0 9 3 0 0 7 5 3 0 4 0 0 0 0 0 9 6 0 7 2 0	0.251893939394
+0 2 0 6 0 0 0 0 0 8 4 9 0 5 0 6 7 1 0 6 5 7 4 0 0 0 9 0 0 0 0 7 4 5 0 0 0 3 1 0 0 0 9 4 0 0 0 8 1 9 0 0 0 0 2 0 0 0 8 7 1 9 0 9 1 7 0 3 0 4 8 6 0 0 0 0 0 1 0 2 0	0.100775193798
+0 0 3 0 1 0 0 5 4 0 4 0 0 5 0 0 0 1 0 6 5 7 0 0 0 0 9 0 9 0 3 7 4 5 0 0 5 0 1 8 0 6 9 0 7 0 0 8 1 9 5 0 6 0 2 0 0 0 0 7 1 9 0 9 0 0 0 3 0 0 8 0 3 8 0 0 6 0 7 0 0	0.220930232558
+0 2 0 0 0 9 8 0 0 0 4 9 2 5 0 6 7 0 1 0 5 7 4 0 2 0 0 0 0 0 3 7 0 5 1 8 0 3 0 8 0 6 0 4 0 4 7 8 0 9 5 0 0 0 0 0 6 0 8 7 1 0 3 0 1 7 0 3 2 4 8 0 0 0 4 9 0 0 0 2 0	0.0512820512821
+0 0 0 5 0 3 7 0 0 0 6 0 9 0 2 1 0 8 5 4 0 8 0 0 0 0 9 0 7 3 0 5 6 4 0 0 0 1 0 0 0 0 0 7 0 0 0 5 7 3 0 2 9 0 8 0 0 0 0 9 0 6 3 6 0 1 3 0 4 0 2 0 0 0 9 6 0 5 0 0 0	0.062962962963
+0 0 0 0 6 0 7 4 0 3 0 0 9 0 0 1 5 0 0 4 2 0 0 0 6 3 0 0 7 0 2 5 0 4 8 0 0 0 0 4 0 8 0 0 0 0 8 5 0 3 1 0 9 0 0 2 4 0 0 0 5 6 0 0 5 1 0 0 4 0 0 7 0 3 9 0 2 0 0 0 0	0.353546099291
+1 0 8 0 6 0 0 0 2 0 0 0 0 0 2 1 0 8 5 0 0 8 1 7 6 0 0 9 7 0 2 5 0 0 0 0 0 0 0 4 0 8 0 0 0 0 0 0 0 3 1 0 9 6 0 0 4 1 7 9 0 0 3 6 0 1 3 0 0 0 0 0 7 0 0 0 2 0 8 0 4	0.356028368794
+0 0 0 5 6 0 7 0 0 3 0 7 0 0 2 0 5 0 0 4 0 8 0 0 6 3 9 0 7 0 2 0 0 4 8 0 2 0 0 4 0 8 0 0 5 0 8 5 0 0 1 0 9 0 8 2 4 0 0 9 0 6 0 0 5 0 3 0 0 9 0 7 0 0 9 0 2 5 0 0 0	0.32962962963
+0 0 8 0 0 3 7 4 0 0 6 7 0 4 0 1 5 0 0 4 0 8 0 0 0 0 0 9 7 0 0 5 6 0 0 1 0 1 6 4 0 8 3 7 0 4 0 0 7 3 0 0 9 6 0 0 0 0 0 9 0 6 0 0 5 1 0 8 0 9 2 0 0 3 9 6 0 0 8 0 0	0.211240310078
+7 9 6 1 4 3 0 5 0 4 5 0 0 0 0 1 3 0 0 1 0 7 0 2 0 0 9 9 3 1 0 0 0 0 0 5 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 4 9 1 6 0 0 8 0 7 0 2 0 0 7 8 0 0 0 0 1 4 0 2 0 4 3 9 7 6 8	0.213178294574
+0 0 0 0 4 3 8 0 2 0 0 0 0 0 6 1 0 0 8 1 3 7 0 0 6 0 9 0 3 1 6 7 4 0 0 5 0 8 4 5 9 1 3 7 0 5 0 0 3 2 8 4 9 0 6 0 9 0 0 7 5 2 3 0 0 8 2 0 0 0 0 0 1 0 5 4 3 0 0 0 0	-0.00438596491228
+7 9 6 0 0 3 0 5 2 0 0 2 0 8 0 1 3 7 0 1 0 0 5 0 6 4 0 0 0 0 0 0 0 0 8 5 0 0 0 5 9 1 0 0 0 5 6 0 0 0 0 0 0 0 0 4 9 0 1 0 0 2 0 3 7 8 0 6 0 9 0 0 1 2 0 4 0 0 7 6 8	-0.0435606060606
+0 0 6 0 0 3 0 5 2 4 0 0 0 8 6 1 0 0 0 1 0 7 5 2 6 0 0 9 0 0 6 7 4 0 8 5 2 0 0 5 0 1 0 0 6 5 6 0 3 2 8 0 0 1 0 0 9 8 1 7 0 2 0 0 0 8 2 6 0 0 0 4 1 2 0 4 0 0 7 0 0	0.132478632479
+0 0 0 0 0 0 8 5 0 4 0 2 0 8 6 0 0 0 8 1 3 7 5 0 6 0 0 0 3 1 6 7 4 2 0 5 2 8 0 0 0 0 0 7 6 5 0 7 3 2 8 4 9 0 0 0 9 0 1 7 5 2 3 0 0 0 2 6 0 9 0 4 0 2 5 0 0 0 0 0 0	0.0217948717949
+4 1 5 9 3 0 0 0 0 8 0 0 5 0 0 0 0 7 0 0 7 0 0 4 1 0 0 0 0 0 0 0 0 3 6 9 2 6 0 3 0 8 0 5 1 5 3 4 0 0 0 0 0 0 0 0 6 7 0 0 2 0 0 7 0 0 0 0 2 0 0 3 0 0 0 0 9 1 7 8 6	0.159574468085
+0 0 5 0 0 7 6 2 0 0 0 0 0 1 6 9 4 7 0 9 7 0 0 0 0 3 5 0 0 0 0 0 5 0 6 9 0 0 9 0 7 0 4 0 0 5 3 0 1 0 0 0 0 0 9 8 0 0 0 0 2 1 0 7 4 1 6 8 0 0 0 0 0 5 2 4 0 0 7 0 0	0.217391304348
+4 0 5 0 0 7 0 2 0 0 2 3 5 1 0 9 4 0 0 9 0 0 0 0 1 0 0 1 0 8 2 0 0 3 6 0 0 0 0 3 0 8 0 0 0 0 3 4 0 0 9 8 0 2 0 0 6 0 0 0 0 1 0 0 4 1 0 8 2 5 9 0 0 5 0 4 0 0 7 0 6	0.316666666667
+0 0 0 0 3 0 0 2 0 0 0 3 5 0 6 9 0 7 0 0 7 8 0 4 1 0 5 0 7 0 0 0 0 0 6 9 2 0 0 3 7 8 0 0 1 5 3 0 0 0 0 0 7 0 9 0 6 7 0 3 2 0 0 7 0 1 6 0 2 5 0 0 0 5 0 0 9 0 0 0 0	0.226449275362
+4 0 0 9 0 7 0 0 0 0 2 3 5 0 6 9 0 7 0 0 0 8 2 4 1 0 0 1 7 0 0 4 0 3 6 0 0 0 0 0 0 0 0 0 0 0 3 4 0 6 0 0 7 2 0 0 6 7 5 3 0 0 0 7 0 1 6 0 2 5 9 0 0 0 0 4 0 1 0 0 6	0.307407407407
+0 7 2 3 8 5 4 0 0 0 3 9 0 1 6 0 0 0 1 0 0 2 7 0 3 0 6 7 8 0 0 0 0 6 4 0 5 0 0 0 0 0 0 0 7 0 9 4 0 0 0 0 3 1 4 0 1 0 6 3 0 0 8 0 0 0 9 2 0 1 6 0 0 0 8 5 4 1 2 7 0	0.0325203252033
+0 0 0 3 0 0 0 1 0 8 0 0 0 1 6 7 0 2 1 0 0 0 0 9 3 0 0 7 0 3 0 0 0 6 4 5 5 0 6 8 0 4 9 0 7 2 9 4 0 0 0 8 0 1 0 0 1 7 0 0 0 0 8 3 0 7 9 2 0 0 0 4 0 6 0 0 0 1 0 0 0	0.224074074074
+0 0 2 3 8 0 0 0 0 8 3 0 0 1 6 0 5 0 0 0 0 2 0 0 3 8 0 7 8 0 1 9 0 0 0 5 0 1 6 8 0 4 9 2 0 2 0 0 0 5 7 0 3 1 0 2 1 0 0 3 0 0 0 0 5 0 9 2 0 0 6 4 0 0 0 0 4 1 2 0 0	0.100775193798
+2 4 0 3 0 0 0 0 0 7 8 0 5 0 6 0 0 0 9 3 0 4 7 0 0 5 8 5 0 7 9 0 0 0 1 0 0 1 0 0 0 0 0 9 0 0 9 0 0 0 7 5 0 4 4 7 0 0 1 5 0 8 9 0 0 0 8 0 3 0 7 2 0 0 0 0 0 4 0 3 5	0.307407407407
+2 4 5 3 0 0 0 0 0 0 8 0 5 0 0 9 0 3 0 3 0 4 7 1 0 0 0 5 2 0 0 4 0 3 1 0 3 1 0 6 0 2 0 9 7 0 9 8 0 3 0 0 2 4 0 0 0 2 1 5 0 8 0 1 0 9 0 0 3 0 7 0 0 0 0 0 0 4 1 3 5	0.10162601626
+2 4 0 0 0 0 0 0 1 7 8 1 5 2 6 0 0 0 9 0 0 4 0 0 2 5 0 5 2 7 0 0 8 0 0 6 0 0 4 6 0 2 8 0 0 6 0 0 1 0 0 5 2 4 0 7 3 0 0 5 0 0 9 0 0 0 8 6 3 4 7 2 8 0 0 0 0 0 0 3 5	0.19512195122
+7 1 0 3 0 8 0 0 0 8 0 9 2 0 0 0 1 5 0 5 2 4 1 0 0 0 0 5 6 0 0 4 1 8 3 0 0 0 1 0 0 0 7 0 0 0 2 3 8 7 0 0 4 1 0 0 0 0 8 5 1 7 0 1 3 0 0 0 4 9 0 8 0 0 0 1 0 3 0 5 4	0.130081300813
+7 0 6 3 0 0 0 0 0 0 0 9 0 6 7 3 1 5 0 0 0 4 1 0 0 0 7 0 0 7 9 0 0 8 0 0 4 8 0 5 0 2 0 9 6 0 0 3 0 0 6 5 0 0 2 0 0 0 8 5 0 0 0 1 3 5 7 2 0 9 0 0 0 0 0 0 0 3 2 0 4	0.062962962963
+0 1 6 3 0 8 4 2 0 8 4 0 0 0 7 3 0 0 3 0 0 0 0 0 0 0 0 0 6 0 9 4 0 8 0 2 0 8 1 0 3 0 7 9 0 9 0 3 0 7 6 0 4 0 0 0 0 0 0 0 0 0 3 0 0 5 7 0 0 0 6 8 0 7 8 1 0 3 2 5 0	0.373106060606
+7 0 0 3 0 0 0 2 0 8 4 0 2 6 0 0 0 5 0 5 2 0 1 9 0 8 7 0 0 0 9 0 0 0 3 2 4 0 1 0 0 0 7 0 6 9 2 0 0 0 6 0 0 0 2 9 0 6 8 0 1 7 0 1 0 0 0 2 4 0 6 8 0 7 0 0 0 3 0 0 4	0.108527131783
+7 0 6 3 0 8 0 0 9 0 0 0 2 6 0 3 0 0 0 5 0 0 0 0 0 8 0 0 0 0 9 0 1 8 0 2 4 0 0 0 0 0 0 0 6 9 0 3 8 0 6 0 0 0 0 9 0 0 0 0 0 7 0 0 0 5 0 2 4 0 0 0 6 0 0 1 0 3 2 0 4	0.349673202614
+5 7 9 0 0 3 0 2 0 2 0 0 0 0 7 8 0 3 0 0 3 0 0 1 0 0 0 7 0 0 3 0 0 6 1 0 0 9 1 0 6 0 7 3 0 0 2 6 0 0 5 0 0 8 0 0 0 7 0 0 3 0 0 1 0 8 9 0 0 0 0 6 0 3 0 2 0 0 4 8 1	0.135869565217
+5 0 0 6 8 0 0 0 0 0 0 4 0 0 0 8 0 3 0 0 3 0 2 1 0 0 7 7 0 5 3 4 9 0 1 2 0 9 0 0 0 0 0 3 0 3 2 0 1 7 5 9 0 8 6 0 0 7 1 0 3 0 0 1 0 8 0 0 0 2 0 0 0 0 0 0 5 6 0 0 1	0.324074074074
+5 7 0 6 8 0 1 2 4 2 0 0 0 9 0 8 0 3 0 6 0 4 0 1 0 0 0 7 0 0 0 0 0 6 1 0 0 9 1 0 0 0 7 3 0 0 2 6 0 0 0 0 0 8 0 0 0 7 0 8 0 5 0 1 0 8 0 3 0 0 0 6 9 3 7 0 5 6 0 8 1	0.170542635659
+5 7 9 0 8 3 0 0 4 0 0 0 5 0 0 0 6 0 0 6 3 4 0 0 0 9 7 0 0 0 3 4 0 0 1 2 0 9 0 0 6 0 0 3 0 3 2 0 0 7 5 0 0 0 6 4 0 0 0 8 3 5 0 0 5 0 0 0 4 0 0 0 9 0 0 2 5 0 4 8 1	0.231060606061
+0 0 0 5 0 6 0 9 3 0 0 6 3 2 0 5 0 1 0 3 0 0 0 0 7 0 0 6 7 1 0 0 0 4 0 5 2 0 0 0 0 0 0 0 7 4 0 3 0 0 0 9 1 6 0 0 2 0 0 0 0 5 0 9 0 7 0 4 5 6 0 0 3 4 0 6 0 1 0 0 0	0.359929078014
+1 0 4 5 0 0 8 9 0 0 9 6 3 0 0 5 0 1 5 3 0 4 1 0 0 0 0 6 0 0 0 0 0 0 2 5 2 0 9 0 0 0 3 0 7 4 8 0 0 0 0 0 0 6 0 0 0 0 3 7 0 5 4 9 0 7 0 0 5 6 3 0 0 4 5 0 0 1 2 0 9	0.127906976744
+1 0 0 0 7 0 8 9 0 0 9 6 0 2 0 5 4 0 5 3 0 0 0 9 0 0 0 6 0 0 0 0 3 4 2 0 2 0 9 0 0 0 3 0 7 0 8 3 7 0 0 0 0 6 0 0 0 9 0 0 0 5 4 0 1 7 0 4 0 6 3 0 0 4 5 0 8 0 0 0 9	0.227777777778
+0 0 0 8 0 0 0 0 2 7 8 0 0 6 5 4 0 0 2 1 0 0 0 0 0 3 6 0 2 0 0 8 6 0 9 0 0 0 7 0 9 0 2 0 0 0 9 0 7 3 0 0 6 0 4 3 0 0 0 0 0 7 5 0 0 2 3 7 0 0 8 4 6 0 0 0 0 4 0 0 0	0.265972222222
+9 0 0 0 1 0 7 5 0 7 0 0 0 0 0 0 1 0 2 1 0 9 4 7 8 0 0 0 0 0 0 0 6 3 0 7 3 6 7 0 0 0 2 4 8 8 0 4 7 0 0 0 0 0 0 0 9 6 2 8 0 7 5 0 5 0 0 0 0 0 0 4 0 7 8 0 5 0 0 0 3	0.214814814815
+9 4 0 0 0 3 7 0 0 7 0 3 0 0 0 4 1 0 2 0 5 9 4 0 0 0 0 0 2 0 4 8 6 3 0 0 0 0 0 5 9 1 0 0 0 0 0 4 7 3 2 0 6 0 0 0 0 0 2 8 1 0 5 0 5 2 0 0 0 6 0 4 0 0 8 1 0 0 0 2 3	0.215909090909
+0 4 0 0 0 0 7 5 2 0 8 3 2 0 5 4 1 0 2 0 0 0 0 7 0 0 6 0 0 0 4 8 0 3 9 7 0 0 0 5 9 1 0 0 0 8 9 4 0 3 2 0 0 0 4 0 0 6 0 0 0 0 5 0 5 2 3 0 9 6 8 0 6 7 8 0 0 0 0 2 0	-0.154761904762
+9 4 0 0 1 0 0 5 0 7 8 0 0 0 0 0 0 9 0 1 5 9 0 7 8 0 0 0 0 0 4 8 0 3 0 7 0 6 0 0 9 0 0 4 0 8 0 4 0 3 2 0 0 0 0 0 9 6 0 8 1 7 0 1 0 0 0 0 0 0 8 4 0 7 0 0 5 0 0 2 3	0.36231884058
+8 6 0 0 0 9 4 7 0 0 0 0 5 3 4 0 0 0 1 0 0 8 7 0 0 0 9 0 0 1 9 8 0 7 0 0 0 0 0 7 0 2 0 0 0 0 0 7 0 4 5 3 0 0 6 0 0 0 5 1 0 0 8 0 0 0 4 9 8 0 0 0 0 9 8 2 0 0 0 4 5	0.37188449848
+0 0 5 1 0 9 4 7 3 0 0 9 5 0 0 8 0 6 1 4 0 8 0 0 2 0 0 4 0 0 0 0 0 0 6 0 0 0 6 7 0 2 5 0 0 0 8 0 0 0 0 0 0 1 0 0 4 0 0 1 0 2 8 5 0 2 0 0 8 6 0 0 3 9 8 2 0 7 1 0 0	0.367407407407
+0 0 5 1 0 9 0 7 3 0 2 9 0 0 0 8 1 0 1 4 0 0 0 6 0 0 9 0 0 0 9 8 3 0 6 0 0 0 0 0 0 0 0 0 0 0 8 0 6 4 5 0 0 0 6 0 0 3 0 0 0 2 8 0 1 2 0 0 0 6 3 0 3 9 0 2 0 7 1 0 0	0.163120567376
+0 6 5 0 2 0 0 7 0 7 2 9 5 3 0 0 0 0 0 4 0 8 0 0 2 0 9 0 5 1 0 8 0 7 0 2 0 0 0 7 0 2 0 0 0 2 0 7 0 4 0 3 9 0 6 0 4 0 0 1 0 2 0 0 0 0 0 9 8 6 3 7 0 9 0 0 6 0 1 4 0	0.18992248062
+0 0 0 0 2 0 4 7 0 0 2 9 5 0 4 8 0 0 0 4 0 8 7 0 0 0 9 0 5 0 9 8 0 0 6 0 0 0 6 7 0 2 5 0 0 0 8 0 0 4 5 0 9 0 6 0 0 0 5 1 0 2 0 0 0 2 4 0 8 6 3 0 0 9 8 0 6 0 0 0 0	0.259259259259
+9 8 5 2 4 0 1 0 0 0 0 0 7 8 1 9 0 4 0 0 0 0 0 0 0 8 0 4 0 2 8 7 9 0 0 0 0 9 0 0 0 0 0 7 0 0 0 0 1 3 2 5 0 9 0 3 0 0 0 0 0 0 0 8 0 7 5 2 6 0 0 0 0 0 4 0 9 8 7 1 5	0.22962962963
+0 8 5 0 4 0 0 0 0 3 2 6 7 0 1 0 0 0 0 0 0 9 6 0 0 0 2 4 0 2 8 0 0 0 3 1 0 9 3 0 0 0 2 7 0 6 7 0 0 0 2 5 0 9 5 0 0 0 1 7 0 0 0 0 0 0 5 0 6 4 9 3 0 0 0 0 9 0 7 1 0	0.211111111111
+0 0 0 2 0 3 0 6 0 3 2 0 7 0 0 9 5 4 0 0 1 9 6 0 3 8 0 4 5 0 0 7 0 0 0 0 1 0 0 0 0 0 0 0 8 0 0 0 0 3 0 0 4 9 0 3 9 0 1 7 8 0 0 8 1 7 0 0 6 0 9 3 0 6 0 3 0 8 0 0 0	0.393333333333
+0 8 0 0 0 0 0 6 7 3 2 6 0 0 1 0 5 0 0 0 1 0 6 5 0 0 2 0 0 0 8 7 0 0 0 1 0 9 0 0 0 0 0 7 0 6 0 0 0 3 2 0 0 0 5 0 0 4 1 0 8 0 0 0 1 0 5 0 0 4 9 3 2 6 0 0 0 0 0 1 0	0.176870748299
+0 0 0 0 0 3 0 0 7 3 0 6 0 8 1 9 5 0 7 4 1 9 0 0 3 0 2 4 0 2 8 0 0 0 0 0 1 9 0 0 5 0 0 7 8 0 0 0 0 0 2 5 0 9 5 0 9 0 0 7 8 2 6 0 1 7 5 2 0 4 0 3 2 0 0 3 0 0 0 0 0	0.166666666667
+1 0 2 0 0 0 5 9 0 0 0 0 5 0 1 7 2 0 0 8 6 9 2 0 0 0 0 0 5 0 0 0 0 2 0 7 6 4 0 0 0 0 0 1 9 8 0 1 0 0 0 0 4 0 0 0 0 0 6 2 9 5 0 0 6 5 8 0 3 0 0 0 0 3 4 0 0 0 8 0 1	0.241134751773
+0 0 2 6 0 0 5 9 8 4 0 3 0 8 0 0 2 0 5 8 0 9 2 7 0 0 4 0 0 9 0 4 0 0 0 0 0 4 7 2 5 8 3 1 0 0 0 0 0 7 0 6 0 0 7 0 0 4 6 2 0 5 3 0 6 0 0 1 0 4 0 2 2 3 4 0 0 5 8 0 0	-0.0291666666667
+0 0 2 0 0 0 5 0 0 4 0 0 0 8 0 7 2 6 5 8 0 9 2 0 0 0 4 3 5 0 1 0 6 2 0 0 0 4 7 0 5 0 3 1 0 0 0 1 3 0 9 0 4 5 7 0 0 0 6 2 0 5 3 9 6 5 0 1 0 0 0 2 0 0 4 0 0 0 8 0 0	-0.0119047619048
+0 7 2 0 3 0 0 9 8 0 0 0 5 8 1 7 0 0 0 0 6 0 0 7 1 0 0 3 0 0 0 4 6 0 0 7 6 0 0 0 0 0 0 0 9 8 0 0 3 7 0 0 0 5 0 0 8 4 0 0 9 0 0 0 0 5 8 1 3 0 0 0 2 3 0 0 9 0 8 6 0	0.124113475177
+0 3 0 7 0 0 0 0 5 0 9 0 0 6 2 8 0 0 0 5 7 8 0 3 6 1 0 0 0 0 4 7 6 0 3 0 5 7 0 0 0 0 0 8 6 0 4 0 1 8 5 0 0 0 0 6 5 9 0 7 3 2 0 0 0 9 3 5 0 0 6 0 7 0 0 0 0 8 0 5 0	0.449224806202
+0 3 0 0 0 1 2 0 0 1 0 4 5 6 2 0 0 3 0 0 7 8 4 0 0 1 0 0 0 0 4 0 0 5 3 0 5 7 1 0 3 0 4 8 6 0 4 6 0 0 5 0 0 0 0 6 0 0 1 7 3 0 0 8 0 0 3 5 4 1 0 7 0 0 3 6 0 0 0 5 0	0.28373015873
+6 0 0 7 0 0 2 0 5 1 0 4 0 6 0 0 0 3 0 5 0 0 4 0 0 0 0 9 0 2 0 7 0 5 3 0 5 0 0 2 3 9 0 0 6 0 4 6 0 8 0 7 0 2 0 0 0 0 1 0 0 2 0 8 0 0 0 5 0 1 0 7 7 0 3 0 0 8 0 0 4	0.273550724638
+6 0 0 7 0 0 0 4 0 0 9 4 0 6 0 0 7 0 2 5 7 8 0 0 0 0 9 0 0 2 0 0 0 0 3 1 5 7 0 2 0 9 0 8 6 3 4 0 0 0 0 7 0 0 4 0 0 0 0 7 3 2 8 0 2 0 0 5 0 1 6 0 0 1 0 0 0 8 0 0 4	0.268518518519
+0 3 8 0 0 0 2 4 0 1 9 0 0 6 0 0 7 0 2 5 0 8 0 3 0 0 0 0 8 0 0 7 6 0 0 1 5 7 0 0 0 0 0 8 6 3 0 0 1 8 0 0 9 0 0 0 0 9 0 7 0 2 8 0 2 0 0 5 0 0 6 7 0 1 3 0 0 0 9 5 0	0.273333333333
+0 0 0 5 0 0 0 8 4 8 5 0 0 0 7 9 1 0 0 0 6 3 0 0 0 7 5 5 0 0 9 0 0 0 0 3 7 3 8 0 5 0 1 6 9 6 0 0 0 0 3 0 0 7 1 6 0 0 0 9 7 0 0 0 8 4 7 0 0 0 5 1 3 2 0 0 0 5 0 0 0	0.379545454545
+0 7 9 0 0 1 3 8 0 0 0 3 4 2 7 0 1 0 0 0 6 0 0 0 2 0 0 5 0 0 0 0 6 8 2 3 0 0 0 2 0 4 0 0 0 6 9 2 1 0 0 0 0 7 0 0 5 0 0 0 7 0 0 0 8 0 7 3 2 6 0 0 0 2 7 6 0 0 4 9 0	0.0925925925926
+0 7 0 0 6 1 0 8 0 8 5 3 0 0 0 9 1 0 0 0 0 0 9 0 0 0 5 0 4 1 0 0 0 8 0 3 0 3 0 2 5 4 0 6 0 6 0 2 0 0 0 5 4 0 1 0 0 0 4 0 0 0 0 0 8 4 0 0 0 6 5 1 0 2 0 6 1 0 0 9 0	0.366977225673
+0 7 9 0 6 1 3 8 0 0 0 0 0 2 0 0 0 0 4 0 0 0 0 0 0 7 5 0 4 0 0 7 6 8 0 0 0 3 8 2 0 4 1 6 0 0 0 2 1 8 0 0 4 0 1 6 0 0 0 0 0 0 2 0 0 0 0 3 0 0 0 0 0 2 7 6 1 0 4 9 0	0.439716312057
+2 0 9 5 0 0 0 8 0 8 5 0 0 2 0 9 0 0 0 0 0 0 9 0 0 7 5 0 0 0 0 7 6 0 2 3 0 0 8 2 0 4 1 0 0 6 9 0 1 8 0 0 0 0 1 6 0 0 4 0 0 0 0 0 0 4 0 3 0 0 5 1 0 2 0 0 0 5 4 0 8	0.356737588652
+0 8 0 0 0 3 0 0 0 5 1 0 0 0 4 7 9 0 0 4 0 1 6 0 0 0 5 0 0 4 0 3 0 0 5 8 6 0 0 5 2 8 0 0 4 8 7 0 0 9 0 3 0 0 1 0 0 0 4 2 0 3 0 0 6 9 3 0 0 0 2 1 0 0 0 6 0 0 0 4 0	0.364130434783
+0 8 0 9 0 0 4 0 0 5 0 6 0 8 0 7 9 0 9 4 3 0 6 0 0 8 0 0 9 0 0 0 0 1 5 8 6 0 0 5 2 8 0 0 4 8 7 5 0 0 0 0 6 0 0 5 0 0 4 0 6 3 9 0 6 9 0 7 0 8 0 1 0 0 8 0 0 9 0 4 0	0.236111111111
+0 0 2 0 0 0 4 0 0 0 0 0 2 8 0 7 9 3 0 4 0 1 6 7 2 8 0 2 0 0 7 3 0 1 5 0 0 3 1 0 0 0 9 7 0 0 7 5 0 9 1 0 0 2 0 5 7 8 4 2 0 3 0 4 6 9 0 7 5 0 0 0 0 0 8 0 0 0 5 0 0	0.0934959349593
+7 0 2 0 0 0 0 1 6 0 1 6 2 0 4 7 9 0 0 0 3 0 6 0 0 8 0 2 9 0 0 3 0 1 5 0 0 0 1 5 2 8 9 0 0 0 7 5 0 9 0 0 6 2 0 5 0 0 4 0 6 0 0 0 6 9 3 0 5 8 2 0 3 2 0 0 0 0 5 0 7	0.120833333333
+1 6 5 0 0 0 0 0 0 0 4 8 0 3 1 6 0 5 2 9 0 5 7 6 0 0 1 4 0 7 0 6 3 0 0 0 6 0 0 2 0 4 0 0 7 0 0 0 7 1 0 3 0 4 8 0 0 3 9 7 0 1 6 3 0 6 1 8 0 4 7 0 0 0 0 0 0 0 5 3 8	0.0940170940171
+0 6 5 0 0 0 0 9 3 7 0 8 0 3 0 6 0 0 0 9 0 0 7 0 8 0 1 0 1 7 8 0 0 9 5 2 0 3 0 2 5 4 0 8 0 5 8 2 0 0 9 3 6 0 8 0 4 0 9 0 0 1 0 0 0 6 0 8 0 4 0 9 9 7 0 0 0 0 5 3 0	0.1125
+0 0 0 0 0 0 0 9 0 0 0 0 9 0 1 6 2 0 2 9 0 5 7 0 8 4 1 4 0 0 0 6 0 9 0 2 0 3 9 2 0 4 1 8 0 5 0 2 0 1 0 0 0 4 8 5 4 0 9 7 0 1 6 0 2 6 1 0 5 0 0 0 0 7 0 0 0 0 0 0 0	0.425968992248
+0 0 0 0 1 0 0 0 8 0 0 8 4 6 3 0 2 0 0 0 3 0 0 2 5 4 7 0 0 0 8 0 0 0 0 4 7 0 1 0 3 0 9 0 6 4 0 0 0 0 6 0 0 0 1 2 7 3 0 0 6 0 0 0 3 0 6 9 5 2 0 0 9 0 0 0 2 0 0 0 0	0.204861111111
+0 0 9 0 1 7 3 6 0 5 0 0 4 0 3 1 0 0 0 0 0 9 0 0 0 4 7 3 0 2 0 0 9 0 0 4 7 8 1 0 0 0 9 5 6 4 0 0 1 0 0 8 0 2 1 2 0 0 0 8 0 0 0 0 0 4 6 0 5 0 0 1 0 5 6 7 2 0 4 0 0	0.166666666667
+0 0 0 5 0 7 0 0 8 0 7 8 4 6 3 0 2 0 0 0 0 0 0 2 5 4 0 0 0 0 8 0 0 7 1 4 0 8 0 0 3 0 0 5 0 4 9 5 0 0 6 0 0 0 0 2 7 3 0 0 0 0 0 0 3 0 6 9 5 2 7 0 9 0 0 7 0 1 0 0 0	0.307971014493
+0 4 9 0 1 0 0 0 0 0 0 0 0 6 0 0 2 0 6 1 3 0 0 0 5 0 7 0 6 2 8 0 0 0 0 4 0 8 0 2 0 4 0 5 0 4 0 0 0 0 6 8 3 0 1 0 7 0 0 0 6 9 5 0 3 0 0 9 0 0 0 0 0 0 0 0 2 0 4 8 0	0.318707482993
+2 0 0 0 1 0 3 0 8 5 0 0 4 6 0 1 0 9 0 1 0 9 0 0 5 4 0 0 0 2 0 5 0 0 1 0 0 0 0 2 3 4 0 0 0 0 9 0 0 7 0 8 0 0 0 2 7 0 0 8 0 9 0 8 0 4 0 9 5 0 0 1 9 0 6 0 2 0 0 0 3	0.20652173913
+0 1 6 0 0 8 0 0 7 5 0 0 0 1 0 2 0 3 8 3 0 5 7 0 9 0 0 0 0 0 2 4 0 3 0 5 2 0 0 0 0 0 0 0 8 3 0 1 0 9 5 0 0 0 0 0 9 0 8 7 0 3 2 1 0 8 0 5 0 0 0 4 7 0 0 4 0 0 8 1 0	0.296296296296
+0 0 0 0 2 8 0 5 0 0 7 4 6 1 0 2 8 0 0 0 2 0 7 0 9 0 1 0 8 0 0 0 0 3 9 5 0 0 5 7 0 6 1 0 0 3 4 1 0 0 0 0 2 0 4 0 9 0 8 0 5 0 0 0 2 8 0 5 3 6 7 0 0 5 0 4 6 0 0 0 0	0.217054263566
+9 0 0 0 2 8 0 5 7 5 0 0 0 1 9 2 0 3 0 3 0 5 0 0 0 6 0 0 8 0 2 0 0 3 9 5 0 0 0 7 0 6 0 0 0 3 4 1 0 0 5 0 2 0 0 6 0 0 0 7 0 3 0 1 0 8 9 5 0 0 0 4 7 5 0 4 6 0 0 0 9	-0.0271317829457
+0 1 6 0 2 0 0 0 0 5 0 4 6 1 9 0 0 3 0 0 2 5 7 0 9 6 0 0 0 7 0 4 0 0 9 5 0 0 0 0 0 0 0 0 0 3 4 0 0 9 0 7 0 0 0 6 9 0 8 7 5 0 0 1 0 0 9 5 3 6 0 4 0 0 0 0 6 0 8 1 0	0.261111111111
+9 0 6 3 0 0 4 0 0 0 7 0 0 1 9 0 0 3 8 0 0 0 0 0 0 6 0 0 0 0 0 4 1 0 0 5 0 9 5 7 0 6 1 4 0 3 0 0 8 9 0 0 0 0 0 6 0 0 0 0 0 0 2 1 0 0 9 5 0 0 7 0 0 0 3 0 0 2 8 0 9	0.391156462585
+0 8 3 5 0 0 9 2 0 0 0 9 0 1 8 0 0 0 6 7 0 0 4 0 0 1 8 0 5 0 6 0 0 0 4 3 0 0 0 8 0 4 0 0 0 4 3 0 0 0 1 0 9 0 7 2 0 0 6 0 0 3 5 0 0 0 7 8 0 1 0 0 0 1 6 0 0 3 7 8 0	0.177777777778
+0 0 0 0 7 0 9 2 0 2 4 0 3 0 0 6 5 0 0 0 0 9 4 2 3 1 0 8 5 0 6 0 0 0 4 3 0 6 0 0 0 0 0 7 0 4 3 0 0 0 1 0 9 6 0 2 8 1 6 9 0 0 0 0 9 4 0 0 5 0 6 2 0 1 6 0 2 0 0 0 0	0.291085271318
+0 0 3 0 7 0 9 0 0 2 0 0 3 0 8 6 0 0 0 7 5 9 0 2 0 1 0 0 5 0 0 0 0 2 4 3 0 0 2 8 3 4 5 0 0 4 3 7 0 0 0 0 9 0 0 2 0 1 0 9 4 3 0 0 0 4 7 0 5 0 0 2 0 0 6 0 2 0 7 0 0	0.30303030303
+0 8 0 0 7 6 9 0 4 0 0 0 0 0 8 0 5 0 0 0 0 9 0 2 3 1 8 0 5 1 0 0 0 2 0 3 0 6 2 0 0 0 5 7 0 4 0 7 0 0 0 8 9 0 7 2 8 1 0 9 0 0 0 0 9 0 7 0 0 0 0 0 5 0 6 4 2 0 0 8 0	0.203703703704
+8 5 2 0 1 9 0 0 4 0 0 3 0 0 4 0 0 1 0 0 0 7 6 0 0 2 0 0 4 7 0 5 0 0 8 0 3 0 0 0 0 0 0 0 2 0 1 0 0 3 0 9 4 0 0 6 0 0 8 3 0 0 0 1 0 0 5 0 0 8 0 0 5 0 0 1 9 0 4 7 6	0.216312056738
+8 0 2 0 1 9 0 0 4 0 7 3 0 0 4 0 0 0 4 9 1 7 0 0 0 0 0 9 0 0 0 5 0 0 8 0 0 0 0 9 0 7 0 0 0 0 1 0 0 3 0 0 0 7 0 0 0 0 0 3 2 1 5 0 0 0 5 0 0 8 3 0 5 0 0 1 9 0 4 0 6	0.42380952381
+0 0 2 0 1 9 0 0 4 0 0 3 8 2 4 5 0 1 0 0 1 7 6 0 3 2 0 9 0 0 0 0 0 6 8 3 0 0 0 0 4 0 0 0 0 2 1 5 0 0 0 0 0 7 0 6 9 0 8 3 2 0 0 1 0 4 5 7 6 8 0 0 5 0 0 1 9 0 4 0 0	-0.130952380952
+0 0 0 0 0 0 7 0 4 6 0 3 8 2 4 5 0 0 0 9 1 7 0 0 0 0 0 9 0 0 2 5 0 6 8 0 0 8 6 9 4 7 1 5 0 0 1 5 0 3 8 0 0 7 0 0 0 0 0 3 2 1 0 0 0 4 5 7 6 8 0 9 5 0 8 0 0 0 0 0 0	-0.142857142857
+1 7 0 5 0 0 6 8 0 3 5 2 0 0 8 1 0 7 0 4 0 1 0 7 0 0 9 0 0 0 4 0 0 2 9 0 0 0 6 0 5 0 8 0 0 0 9 1 0 0 6 0 0 0 5 0 0 9 0 4 0 6 0 8 0 4 7 0 0 9 3 5 0 2 7 0 0 5 0 1 8	0.0595238095238
+0 0 9 0 0 0 0 8 3 0 5 0 6 0 8 1 0 7 6 0 0 1 0 0 5 2 0 7 0 0 0 1 3 2 0 6 4 3 0 0 0 0 0 7 1 2 0 1 8 7 0 0 0 4 0 1 3 0 0 4 0 0 2 8 0 4 7 0 1 0 3 0 9 2 0 0 0 0 4 0 0	0.149224806202
+0 7 0 0 4 2 0 0 3 0 5 2 0 0 8 0 4 7 0 0 0 1 3 0 0 2 0 7 8 0 0 0 0 0 0 6 0 0 6 2 0 9 8 0 0 2 0 0 0 0 0 0 5 4 0 1 0 0 8 4 0 0 0 8 6 0 7 0 0 9 3 0 9 0 0 3 6 0 0 1 0	0.163120567376
+1 7 9 5 4 2 0 8 0 0 0 2 6 0 0 0 0 7 0 4 8 1 0 0 5 0 0 0 0 0 0 0 0 2 0 6 0 3 0 0 0 0 0 7 0 2 0 1 0 0 0 0 0 0 0 0 3 0 0 4 7 6 0 8 0 0 0 0 1 9 0 0 0 2 0 3 6 5 4 1 8	0.417730496454
+0 0 0 0 0 0 2 5 0 0 2 3 7 0 1 9 0 0 0 6 0 0 2 8 3 0 7 6 7 0 8 0 0 4 0 3 0 0 8 2 0 7 1 0 0 2 0 5 0 0 4 0 6 8 7 0 6 3 1 0 0 4 0 0 0 9 4 0 5 6 7 0 0 8 2 0 0 0 0 0 0	0.0271317829457
+8 0 7 6 9 0 0 5 4 0 2 0 0 4 1 9 8 0 0 6 0 0 2 0 0 0 7 0 0 0 8 0 9 4 2 0 3 0 0 2 0 7 0 0 5 0 9 5 1 0 4 0 0 0 7 0 0 0 1 0 0 4 0 0 3 9 4 8 0 0 7 0 4 8 0 0 7 6 5 0 1	0.0691056910569
+0 1 7 0 0 3 0 0 0 5 0 3 0 0 1 9 0 6 9 0 0 5 2 0 0 0 0 0 0 0 8 0 0 4 2 3 3 0 0 2 0 7 0 0 5 2 9 5 0 0 4 0 0 0 0 0 0 0 1 2 0 0 9 1 0 9 4 0 0 6 0 2 0 0 0 9 0 0 5 3 0	0.402127659574
+0 0 9 0 5 0 8 0 0 3 0 0 0 1 0 2 4 9 0 1 4 9 0 0 0 0 0 7 0 0 0 2 9 0 0 4 0 4 0 5 0 6 0 8 0 5 0 0 1 4 0 0 0 3 0 0 0 0 0 1 4 5 0 4 8 1 0 9 0 0 0 7 0 0 5 0 3 0 1 0 0	0.419503546099
+2 7 9 4 0 0 8 0 0 0 5 0 0 0 7 0 0 0 0 1 0 9 0 0 0 3 5 7 0 0 3 0 0 0 0 0 0 4 3 5 7 6 9 8 0 0 0 0 0 0 8 0 0 3 9 3 0 0 0 1 0 5 0 0 0 0 6 0 0 0 2 0 0 0 5 0 0 4 1 9 8	0.416666666667
Index: gnome-sudoku/data/very_hard
===================================================================
--- gnome-sudoku/data/very_hard	(revision 0)
+++ gnome-sudoku/data/very_hard	(revision 0)
@@ -0,0 +1,21 @@
+ 0 0 0 0 0 0 7 0 9 6 7 0 0 0 2 4 8 1	0.815602836879
+0 0 4 1 0 0 3 0 0 0 7 0 0 0 8 0 0 1 0 0 0 0 0 0 7 0 9 8 0 3 0 5 9 0 0 2 0 0 9 6 0 1 5 0 0 1 0 0 8 2 0 9 0 4 6 0 1 0 0 0 0 0 0 4 0 0 3 0 0 0 9 0 0 0 8 0 0 4 2 0 0	0.954248366013
+6 0 0 2 0 0 0 0 4 2 0 8 4 5 1 6 0 0 3 0 0 0 8 0 0 1 0 1 0 0 8 6 0 3 0 0 0 0 9 0 0 0 1 0 0 0 0 6 0 1 3 0 0 8 0 1 0 0 7 0 0 0 2 0 0 2 1 4 8 5 0 3 5 0 0 0 0 2 0 0 1	0.780141843972
+0 0 9 5 4 6 0 8 0 0 0 8 0 0 0 5 0 7 2 5 0 0 0 0 0 0 0 0 4 0 6 3 0 0 0 8 0 0 0 1 0 8 0 0 0 5 0 0 0 2 4 0 1 0 0 0 0 0 0 0 0 2 6 8 0 5 0 0 0 3 0 0 0 3 0 2 8 9 7 0 0	0.882352941176
+0 1 0 7 6 0 9 0 0 0 0 7 0 0 3 0 2 0 6 8 0 0 2 0 0 0 0 0 2 0 8 0 5 0 0 9 8 0 5 0 0 0 2 0 1 9 0 0 2 0 1 0 4 0 0 0 0 0 8 0 0 9 2 0 4 0 9 0 0 7 0 0 0 0 9 0 4 2 0 8 0	0.784013605442
+9 4 0 1 0 7 0 0 8 0 0 0 0 0 3 5 0 0 0 6 0 4 8 0 0 1 0 5 0 0 8 7 0 3 0 0 0 7 0 0 0 0 0 6 0 0 0 8 0 4 9 0 0 7 0 5 0 0 3 4 0 8 0 0 0 7 5 0 0 0 0 0 3 0 0 7 0 8 0 9 5	0.843537414966
+2 0 0 3 0 1 0 4 5 0 0 0 0 0 6 0 0 2 0 5 3 0 9 0 0 0 0 9 8 0 0 0 0 7 0 3 1 0 7 0 0 0 4 0 9 3 0 5 0 0 0 0 8 6 0 0 0 0 2 0 9 6 0 4 0 0 1 0 0 0 0 0 7 9 0 6 0 5 0 0 4	0.787414965986
+0 0 3 0 0 0 1 0 0 6 8 0 0 1 3 0 0 0 9 1 0 4 0 0 0 3 0 2 6 0 0 5 1 7 0 3 0 0 1 0 0 0 2 0 0 8 0 9 6 7 0 0 1 5 0 2 0 0 0 9 0 8 4 0 0 0 2 8 0 0 7 1 0 0 8 0 0 0 6 0 0	0.780141843972
+9 0 0 3 0 0 0 0 6 0 8 0 0 0 0 0 0 7 0 0 5 2 0 8 9 0 0 0 0 8 0 0 4 0 7 3 0 9 0 0 0 0 0 4 0 7 6 0 1 0 0 2 0 0 0 0 7 8 0 1 4 0 0 1 0 0 0 0 0 0 5 0 8 0 0 0 0 9 0 0 1	0.924528301887
+8 4 6 1 0 0 0 3 0 0 5 0 0 0 2 1 0 0 0 0 0 9 4 0 0 0 0 6 1 5 0 0 0 0 4 0 0 0 3 0 0 0 6 0 0 0 8 0 0 0 0 7 1 2 0 0 0 0 2 8 0 0 0 0 0 2 3 0 0 0 6 0 0 3 0 0 0 1 4 2 7	0.862745098039
+0 0 9 1 0 8 0 4 0 0 4 0 6 0 5 7 0 8 0 0 0 0 0 0 0 1 0 8 0 0 3 0 0 0 7 0 1 0 5 7 0 2 4 0 9 0 9 0 0 0 1 0 0 2 0 6 0 0 0 0 0 0 0 9 0 3 8 0 4 0 2 0 0 5 0 2 0 6 1 0 0	0.826530612245
+0 1 4 0 6 0 3 0 0 6 2 0 0 0 4 0 0 9 0 8 0 0 5 0 6 0 0 0 6 0 2 0 0 0 0 3 0 7 0 0 1 0 0 5 0 5 0 0 0 0 9 0 6 0 0 0 6 0 2 0 0 3 0 1 0 0 5 0 0 0 9 2 0 0 7 0 9 0 4 1 0	0.83
+8 0 0 1 0 3 0 5 0 3 1 0 4 0 0 8 0 0 0 0 5 0 0 0 0 0 0 0 9 0 2 0 0 0 0 5 0 5 8 7 0 9 3 6 0 4 0 0 0 0 5 0 8 0 0 0 0 0 0 0 2 0 0 0 0 2 0 0 1 0 3 7 0 3 0 8 0 2 0 0 1	0.921568627451
+6 0 4 1 2 0 0 0 0 0 2 0 0 0 5 0 0 0 7 0 1 3 6 0 0 4 0 9 0 6 0 0 0 4 0 0 8 0 0 2 0 4 0 0 6 0 0 2 0 0 0 7 0 8 0 9 0 0 1 3 5 0 4 0 0 0 7 0 0 0 3 0 0 0 0 0 9 2 1 0 7	0.771914480078
+0 8 0 0 0 7 0 9 5 3 2 0 0 8 5 0 0 0 7 5 0 3 6 0 0 0 0 0 0 6 0 0 0 4 0 3 0 0 3 0 0 0 9 0 0 5 0 2 0 0 0 7 0 0 0 0 0 0 1 3 0 8 4 0 0 0 7 4 0 0 3 9 4 3 0 5 0 0 0 6 0	0.768707482993
+0 0 0 0 6 0 0 3 0 0 9 6 0 0 5 0 0 4 0 0 0 7 0 1 0 6 0 0 1 0 0 0 3 0 9 5 0 4 9 0 1 0 7 2 0 7 3 0 5 0 0 0 1 0 0 6 0 9 0 7 0 0 0 4 0 0 8 0 0 9 5 0 0 2 0 0 5 0 0 0 0	0.756666666667
+6 0 0 0 0 8 0 3 0 0 3 0 6 0 0 5 9 0 4 0 0 0 0 5 8 0 1 0 0 4 0 0 3 0 7 9 9 0 0 0 0 0 0 0 5 3 1 0 5 0 0 6 0 0 1 0 3 8 0 0 0 0 6 0 4 9 0 0 6 0 8 0 0 6 0 9 0 0 0 0 3	0.84693877551
+2 0 0 8 0 1 0 5 0 0 0 0 0 9 0 7 0 0 0 0 5 0 0 2 0 0 8 6 9 0 0 0 4 5 2 0 0 4 2 0 0 0 3 8 0 0 5 8 2 0 0 0 4 6 5 0 0 1 0 0 8 0 0 0 0 7 0 2 0 0 0 0 0 1 0 9 0 3 0 0 4	0.775510204082
+0 0 0 0 0 8 0 0 2 2 0 8 3 0 0 1 0 0 0 7 3 0 1 0 8 0 0 0 0 0 0 0 1 3 4 5 0 0 0 9 3 5 0 0 0 5 3 1 7 0 0 0 0 0 0 0 9 0 6 0 2 7 0 0 0 6 0 0 7 4 0 9 7 0 0 2 0 0 0 0 0	0.878333333333
+0 8 0 0 0 2 7 0 0 5 0 3 7 0 0 4 0 0 0 6 7 0 5 0 0 0 3 6 9 0 0 7 4 0 0 5 0 0 5 0 0 0 1 0 0 2 0 0 9 1 0 0 7 4 3 0 0 0 2 0 8 6 0 0 0 2 0 0 6 5 0 7 0 0 6 5 0 0 0 3 0	0.765957446809
+0 0 0 0 0 5 0 7 0 2 0 0 3 0 9 5 0 1 1 5 0 0 2 0 0 0 9 0 0 8 0 6 3 0 5 2 3 6 0 0 0 0 0 1 8 4 2 0 1 5 0 6 0 0 5 0 0 0 3 0 0 2 6 8 0 1 2 0 6 0 0 5 0 9 0 5 0 0 0 0 0	0.807407407407
Index: gnome-sudoku/data/Makefile.am
===================================================================
--- gnome-sudoku/data/Makefile.am	(revision 6846)
+++ gnome-sudoku/data/Makefile.am	(working copy)
@@ -1,3 +1,3 @@
-EXTRA_DIST = starter_puzzles
-puzzledir = $(datadir)/gnome-sudoku/
-puzzle_DATA = starter_puzzles
\ No newline at end of file
+EXTRA_DIST = easy medium hard very_hard
+puzzledir = $(datadir)/gnome-sudoku/puzzles/
+puzzle_DATA = easy medium hard very_hard
\ No newline at end of file
Index: gnome-sudoku/data/hard
===================================================================
--- gnome-sudoku/data/hard	(revision 0)
+++ gnome-sudoku/data/hard	(revision 0)
@@ -0,0 +1,147 @@
+3 5 0 0 0 9 4 0 0 0 9 0 4 0 0 0 0 3 0 4 0 8 6 0 0 9 0 4 7 0 0 1 0 9 0 0 0 3 0 6 0 4 0 2 0 0 0 2 0 3 0 0 7 4 0 6 0 0 8 2 0 4 0 7 0 0 0 0 1 0 5 0 0 0 4 7 0 0 0 8 1	0.608865248227
+0 0 6 0 0 4 0 7 0 0 0 3 0 0 0 2 0 0 7 0 0 2 0 8 1 0 0 9 0 2 8 0 1 5 0 0 0 0 0 0 0 0 0 0 0 0 0 4 7 0 5 3 0 1 0 0 1 3 0 2 0 0 8 0 0 5 0 0 0 9 0 0 0 9 0 5 0 0 6 0 0	0.600673854447
+4 0 0 3 0 0 0 0 0 0 2 0 0 7 0 0 6 0 0 7 8 5 6 0 4 0 0 9 5 0 0 4 0 1 0 8 6 0 3 0 0 0 5 0 4 7 0 4 0 5 0 0 9 6 0 0 5 0 3 7 6 4 0 0 4 0 0 8 0 0 3 0 0 0 0 0 0 6 0 0 5	0.606382978723
+0 5 2 0 0 8 9 3 0 1 0 0 4 0 0 0 5 2 0 3 0 5 0 0 8 0 0 0 0 0 0 6 5 0 0 8 0 0 0 0 8 0 0 0 0 8 0 0 9 4 0 0 0 0 0 0 9 0 0 1 0 7 0 3 7 0 0 0 4 0 0 9 0 1 6 8 0 0 5 2 0	0.685031746032
+0 1 7 0 0 3 0 0 0 5 2 0 7 0 0 0 8 0 0 0 0 0 2 0 3 0 0 0 0 0 8 5 9 0 2 3 3 0 0 2 0 7 0 0 5 2 9 0 1 3 4 0 0 0 0 0 6 0 1 0 0 0 0 0 3 0 0 0 5 0 7 2 0 0 0 9 0 0 5 3 0	0.69387755102
+3 0 4 5 1 7 2 0 9 0 0 7 0 0 4 5 0 1 0 0 0 0 2 0 4 0 0 7 0 0 0 0 0 6 0 0 0 4 1 3 0 5 8 9 0 0 0 5 0 0 0 0 0 4 0 0 3 0 6 0 0 0 0 9 0 6 1 0 0 3 0 0 5 0 2 7 4 3 9 0 6	0.691111111111
+0 0 0 0 0 0 0 0 9 3 4 0 9 0 0 5 2 0 0 0 0 0 2 1 0 0 3 8 0 0 4 1 2 0 7 0 0 7 0 5 0 9 0 1 0 0 2 0 8 7 6 0 0 4 4 0 0 2 9 0 0 0 0 0 6 3 0 0 4 0 5 2 2 0 0 0 0 0 0 0 0	0.668367346939
+6 0 9 4 0 0 0 8 0 8 0 0 9 0 0 5 0 4 0 5 0 0 0 7 9 0 0 7 0 0 6 3 2 8 9 0 0 0 0 8 0 1 0 0 0 0 6 8 5 4 9 0 0 3 0 0 4 1 0 0 0 5 0 3 0 6 0 0 8 0 0 9 0 8 0 0 0 4 7 0 6	0.677777777778
+0 1 8 0 0 0 6 4 0 6 0 0 8 0 0 0 0 3 0 0 3 5 6 1 7 9 0 4 8 0 9 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 6 0 8 1 0 6 4 1 9 2 3 0 0 1 0 0 0 0 8 0 0 9 0 3 2 0 0 0 8 1 0	0.695035460993
+0 1 0 0 2 0 0 0 4 4 0 7 0 0 0 2 0 0 0 0 9 8 4 0 3 1 0 7 0 0 1 0 0 6 0 0 3 9 0 2 0 8 0 5 1 0 0 1 0 0 4 0 0 9 0 7 5 0 8 1 9 0 0 0 0 8 0 0 0 1 0 3 1 0 0 0 9 0 0 6 0	0.708662613982
+0 9 0 0 0 3 0 1 0 2 0 8 0 0 7 3 0 0 4 0 0 0 0 0 5 8 0 0 0 4 5 0 8 0 0 0 0 8 0 9 0 1 0 7 0 0 0 0 7 0 2 4 0 0 0 4 6 0 0 0 0 0 2 0 0 9 6 0 0 8 0 1 0 2 0 3 0 0 0 5 0	0.627225334578
+0 9 0 0 7 0 2 0 0 0 6 3 0 0 0 0 0 0 0 4 7 5 1 0 3 0 9 0 2 9 0 0 0 1 0 0 0 0 0 9 0 2 0 0 0 0 0 5 0 0 0 6 9 0 1 0 4 0 8 7 9 6 0 0 0 0 0 0 0 7 2 0 0 0 2 0 3 0 0 4 0	0.702614379085
+1 0 0 4 5 9 0 0 0 8 0 3 0 7 0 9 0 0 0 0 0 0 0 8 0 0 0 5 0 8 0 0 2 6 0 0 9 0 0 0 6 0 0 0 7 0 0 7 9 0 0 1 0 5 0 0 0 2 0 0 0 0 0 0 0 6 0 8 0 2 0 4 0 0 0 5 9 4 0 0 3	0.606227106227
+0 4 0 2 0 6 3 0 0 3 2 6 0 1 0 5 0 4 1 0 0 0 4 0 0 0 0 5 0 0 0 0 4 2 0 0 7 1 0 5 0 8 0 3 6 0 0 4 7 0 0 0 0 5 0 0 0 0 3 0 0 0 1 6 0 1 0 8 0 9 5 3 0 0 3 9 0 1 0 4 0	0.628148148148
+5 7 0 1 0 0 0 4 9 4 0 0 0 0 0 7 0 0 0 9 8 4 2 0 0 0 0 9 0 0 2 0 5 4 0 0 0 6 0 0 0 0 0 9 0 0 0 4 6 0 3 0 0 5 0 0 0 0 6 2 8 5 0 0 0 6 0 0 0 0 0 4 2 5 0 0 0 4 0 6 7	0.731292517007
+1 0 0 6 0 5 0 8 0 7 5 0 0 2 0 0 6 0 0 2 0 3 0 0 5 0 0 8 9 0 7 0 0 0 5 0 0 0 3 0 0 0 8 0 0 0 1 0 0 0 8 0 7 9 0 0 1 0 0 2 0 3 0 0 4 0 0 7 0 0 1 6 0 8 0 1 0 6 0 0 5	0.618634596696
+0 3 0 9 0 0 7 0 0 0 0 5 0 0 2 0 9 4 0 0 7 0 4 5 6 0 2 0 4 0 0 6 0 2 0 1 0 0 0 0 0 0 0 0 0 7 0 1 0 2 0 0 6 0 6 0 2 4 5 0 1 0 0 5 9 0 2 0 0 4 0 0 0 0 3 0 0 9 0 2 0	0.656462585034
+0 0 0 7 0 0 0 0 5 1 0 3 8 0 4 6 0 9 0 7 0 0 0 0 1 3 0 0 0 0 4 7 0 5 0 8 0 0 0 2 0 9 0 0 0 7 0 6 0 5 8 0 0 0 0 9 7 0 0 0 0 5 0 2 0 8 5 0 3 9 0 7 4 0 0 0 0 7 0 0 0	0.64387755102
+0 7 5 4 0 6 8 0 2 8 0 0 7 0 0 1 0 0 0 4 0 0 9 0 0 7 0 0 0 1 9 0 4 0 0 0 0 0 0 0 8 0 0 0 0 0 0 0 5 0 3 6 0 0 0 1 0 0 4 0 0 8 0 0 0 4 0 0 9 0 0 1 2 0 7 3 0 1 9 5 0	0.634571428571
+1 7 0 2 9 0 3 0 0 3 0 0 0 0 8 0 7 0 0 0 6 7 3 0 9 0 0 7 9 0 0 0 0 0 3 0 0 1 2 3 0 9 7 8 0 0 8 0 0 0 0 0 2 9 0 0 7 0 1 3 2 0 0 0 4 0 6 0 0 0 0 3 0 0 1 0 4 2 0 6 7	0.623015873016
+0 0 0 9 5 0 0 4 0 9 0 8 0 0 7 0 1 2 4 0 6 0 0 0 7 0 0 5 0 0 0 6 1 8 2 0 0 8 0 0 0 0 0 6 0 0 1 2 5 8 0 0 0 9 0 0 3 0 0 0 9 0 7 7 6 0 2 0 0 1 0 4 0 9 0 0 7 5 0 0 0	0.702127659574
+0 4 7 0 6 0 5 8 0 0 0 1 0 9 4 3 6 0 0 0 0 0 0 3 4 0 1 0 6 2 0 0 0 0 0 5 0 0 0 9 5 6 0 0 0 5 0 0 0 0 0 6 3 0 2 0 4 6 0 0 0 0 0 0 7 5 3 2 0 9 0 0 0 3 8 0 4 0 2 5 0	0.75
+9 1 0 3 5 0 0 7 0 8 0 0 0 0 0 0 0 4 0 2 4 7 0 0 0 3 0 0 6 0 0 3 5 0 4 1 0 0 9 0 0 0 3 0 0 2 3 0 4 6 0 0 9 0 0 9 0 0 0 2 5 1 0 3 0 0 0 0 0 0 0 9 0 5 0 0 9 3 0 8 7	0.643617021277
+0 0 0 0 0 9 0 6 2 6 0 2 0 5 7 8 0 1 0 0 0 0 0 2 5 0 0 0 8 0 0 0 1 0 0 5 0 0 1 7 4 5 6 0 0 7 0 0 3 0 0 0 1 0 0 0 8 1 0 0 0 0 0 1 0 4 5 2 0 7 0 3 3 7 0 9 0 0 0 0 0	0.632192460317
+2 0 0 3 6 7 5 0 0 0 0 4 0 0 0 0 6 0 3 0 0 0 0 1 7 0 0 0 0 0 0 0 8 4 0 2 4 8 5 0 1 0 3 7 6 1 0 3 6 0 0 0 0 0 0 0 1 9 0 0 0 0 5 0 3 0 0 0 0 2 0 0 0 0 2 7 8 3 0 0 1	0.670138888889
+0 2 0 7 0 0 4 0 0 0 0 0 2 0 4 0 0 0 9 4 8 0 0 0 0 0 7 3 0 2 0 7 0 0 0 6 0 6 5 0 0 0 7 1 0 7 0 0 0 1 0 3 0 2 6 0 0 0 0 0 8 3 4 0 0 0 3 0 1 0 0 0 0 0 3 0 0 7 0 9 0	0.748692810458
+0 7 2 0 0 4 0 1 5 8 0 0 7 0 0 0 0 0 0 0 0 8 0 0 0 7 4 0 2 3 5 4 0 0 0 0 0 0 0 1 0 7 0 0 0 0 0 0 0 3 8 1 2 0 9 8 0 0 0 5 0 0 0 0 0 0 0 0 1 0 0 6 2 1 0 3 0 0 4 5 0	0.604038281979
+7 0 6 0 3 0 0 0 0 0 8 1 0 0 0 0 3 0 3 0 0 1 0 8 6 0 0 1 0 0 7 0 6 0 2 0 6 5 0 0 0 0 0 8 7 0 3 0 4 0 5 0 0 6 0 0 3 8 0 2 0 0 1 0 1 0 0 0 0 9 4 0 0 0 0 0 1 0 3 0 2	0.717346938776
+0 3 0 0 2 0 1 0 0 4 0 0 0 6 0 0 7 0 0 0 1 3 0 0 0 0 0 0 2 0 0 1 6 0 8 4 8 4 6 2 0 3 5 1 7 7 1 0 5 4 0 0 9 0 0 0 0 0 0 1 7 0 0 0 6 0 0 3 0 0 0 9 0 0 8 0 7 0 0 2 0	0.613475177305
+0 4 9 0 0 7 0 0 0 8 0 0 2 0 0 4 0 5 1 0 0 0 4 0 6 0 3 0 7 2 0 0 5 1 0 0 4 0 0 1 0 2 0 0 7 0 0 1 4 0 0 5 2 0 5 0 3 0 8 0 0 0 1 2 0 4 0 0 1 0 0 6 0 0 0 3 0 0 9 5 0	0.604559270517
+0 6 0 5 2 0 0 0 8 7 0 0 0 0 0 9 0 2 0 8 2 7 1 0 5 6 0 0 5 9 0 0 0 0 0 6 0 7 6 0 0 0 1 4 0 8 0 0 0 0 0 7 2 0 0 1 8 0 3 6 2 5 0 6 0 3 0 0 0 0 0 1 5 0 0 0 4 1 0 9 0	0.611111111111
+0 0 0 0 0 0 7 0 2 7 0 0 0 1 0 9 0 0 0 5 0 0 7 8 0 1 0 0 7 3 6 0 0 0 2 0 6 8 9 0 2 0 1 5 7 0 2 0 0 0 9 8 3 0 0 9 0 8 6 0 0 4 0 0 0 5 0 9 0 0 0 8 2 0 8 0 0 0 0 0 0	0.610069444444
+0 6 9 0 5 0 2 0 0 0 0 0 0 0 0 0 8 1 4 0 0 3 0 0 0 6 0 0 4 0 0 0 1 8 0 9 0 5 0 8 0 4 0 2 0 2 0 1 5 0 0 0 7 0 0 3 0 0 0 6 0 0 2 7 2 0 0 0 0 0 0 0 0 0 8 0 1 0 3 4 0	0.699346405229
+0 0 0 0 0 0 0 7 0 8 7 0 3 5 1 0 0 0 2 4 0 0 0 7 0 8 0 7 0 0 9 0 0 0 1 0 0 9 5 0 0 0 8 2 0 0 2 0 0 0 3 0 0 7 0 3 0 8 0 0 0 4 9 0 0 0 1 3 4 0 5 8 0 1 0 0 0 0 0 0 0	0.600046685341
+4 0 3 0 7 0 0 0 0 1 8 2 0 0 0 0 0 0 0 6 0 8 4 0 0 1 0 5 0 0 0 0 0 0 6 3 0 2 0 5 9 3 0 7 0 3 4 0 0 0 0 0 0 5 0 3 0 0 5 6 0 2 0 0 0 0 0 0 0 9 5 8 0 0 0 0 2 0 1 0 6	0.666575757576
+8 5 3 6 0 4 0 0 2 9 0 4 0 3 0 6 0 0 0 6 0 0 0 0 0 3 4 0 0 0 0 0 0 4 9 0 5 0 0 0 0 0 0 0 7 0 7 9 0 0 0 0 0 0 3 1 0 0 0 0 0 6 0 0 0 5 0 7 0 3 0 1 7 0 0 1 0 3 5 4 9	0.684839650146
+8 0 0 6 0 0 3 0 0 0 0 0 0 1 0 0 0 8 0 6 9 7 0 0 1 5 0 0 0 0 0 0 7 8 4 9 0 0 2 8 0 9 7 0 0 9 7 8 3 0 0 0 0 0 0 5 1 0 0 6 2 8 0 7 0 0 0 8 0 0 0 0 0 0 6 0 0 4 0 0 1	0.622238419177
+3 0 2 0 9 0 0 0 0 4 5 9 0 7 1 6 0 0 0 1 0 3 5 0 0 0 0 2 0 4 7 0 0 8 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 9 7 0 2 0 0 0 0 4 3 0 6 0 0 0 3 1 2 0 9 7 4 0 0 0 0 6 0 3 0 5	0.658283730159
+1 0 0 9 0 3 4 0 0 3 0 0 0 1 0 0 0 0 0 0 9 0 0 6 1 7 0 0 0 3 4 0 5 0 6 0 0 0 4 0 0 0 5 0 0 0 2 0 3 0 9 7 0 0 0 6 8 7 0 0 9 0 0 0 0 0 0 9 0 0 0 7 0 0 7 8 0 4 0 0 1	0.614845938375
+0 0 0 2 0 0 0 6 3 6 0 9 0 4 0 0 0 0 0 0 0 0 9 0 0 5 0 0 6 0 7 2 0 1 0 0 3 9 2 0 0 0 7 4 5 0 0 1 0 5 3 0 2 0 0 7 0 0 8 0 0 0 0 0 0 0 0 7 0 5 0 8 9 5 0 0 0 2 0 0 0	0.6156940554
+5 0 4 0 1 7 9 0 0 0 0 0 3 0 5 0 8 0 0 0 7 0 9 0 4 0 1 8 0 0 0 0 0 1 3 0 0 9 0 8 0 1 0 4 0 0 4 1 0 0 0 0 0 6 4 0 6 0 8 0 3 0 0 0 2 0 4 0 6 0 0 0 0 0 8 1 3 0 6 0 4	0.718439716312
+9 0 5 1 4 0 0 0 3 0 8 0 0 0 0 0 5 0 0 3 1 0 0 5 0 0 0 5 7 0 8 0 0 3 0 0 4 1 0 0 0 0 0 2 7 0 0 3 0 0 2 0 1 9 0 0 0 6 0 0 9 3 0 0 9 0 0 0 0 0 7 0 1 0 0 0 3 9 6 0 2	0.681729834791
+0 0 0 0 0 1 9 0 8 9 0 3 0 4 8 5 0 0 0 0 1 6 9 5 0 0 3 0 8 0 0 3 0 6 0 0 0 3 4 0 0 0 7 2 0 0 0 9 0 5 0 0 8 0 1 0 0 4 6 3 8 0 0 0 0 5 1 8 0 4 0 2 4 0 8 5 0 0 0 0 0	0.601851851852
+0 0 4 8 3 0 0 0 0 2 0 8 0 0 4 0 0 0 7 3 0 0 1 0 0 4 0 0 7 0 6 0 0 3 2 0 3 6 2 0 0 0 4 9 1 0 8 1 0 0 3 0 5 0 0 9 0 0 5 0 0 7 4 0 0 0 1 0 0 5 0 9 0 0 0 0 9 6 1 0 0	0.671833839919
+9 5 2 4 0 0 0 0 7 0 0 0 0 0 0 0 0 5 8 0 0 0 2 9 0 0 6 0 0 0 0 0 1 8 0 0 2 0 0 7 0 3 0 0 9 0 0 8 9 0 0 0 0 0 7 0 0 6 3 0 0 0 8 5 0 0 0 0 0 0 0 0 6 0 0 0 0 2 7 9 3	0.67065738245
+0 0 5 0 0 9 0 6 7 6 0 0 8 0 0 5 0 2 0 0 0 1 0 5 0 0 9 0 0 0 4 0 0 0 7 0 0 7 8 0 5 0 3 4 0 0 2 0 0 0 1 0 0 0 2 0 0 5 0 6 0 0 0 8 0 3 0 0 4 0 0 5 5 6 0 9 0 0 7 0 0	0.73
+2 0 0 0 6 0 0 0 4 7 0 0 8 2 4 0 1 3 0 0 0 0 0 0 6 0 0 8 4 0 0 7 0 0 9 0 9 0 2 0 0 0 8 0 7 0 7 0 0 5 0 0 2 6 0 0 9 0 0 0 0 0 0 6 1 0 7 4 5 0 0 9 4 0 0 0 3 0 0 0 8	0.610730482669
+0 2 0 8 0 0 0 0 0 0 9 0 5 4 0 0 0 2 7 0 5 2 9 0 8 0 0 6 0 0 0 0 4 0 0 0 0 8 1 6 0 5 3 7 0 0 0 0 1 0 0 0 0 6 0 0 3 0 6 8 9 0 7 8 0 0 0 1 7 0 5 0 0 0 0 0 0 2 0 8 0	0.660689990282
+0 0 5 0 6 4 0 0 0 0 0 1 0 2 0 0 0 7 0 6 0 1 0 0 0 5 4 8 5 7 4 3 0 0 0 0 9 0 0 0 0 0 0 0 6 0 0 0 0 9 2 5 3 8 5 2 0 0 0 3 0 8 0 3 0 0 0 4 0 2 0 0 0 0 0 2 5 0 3 0 0	0.655434078393
+1 9 0 0 0 6 0 0 0 2 0 0 0 0 0 9 0 0 0 7 6 0 0 0 0 0 4 0 1 0 5 7 8 6 9 0 7 0 0 9 0 1 0 0 5 0 6 9 3 4 2 0 7 0 6 0 0 0 0 0 5 3 0 0 0 5 0 0 0 0 0 9 0 0 0 7 0 0 0 6 8	0.65306122449
+5 7 0 0 1 0 0 4 0 0 1 3 0 8 0 0 0 0 2 8 0 3 0 0 9 0 1 8 0 0 0 0 0 0 0 0 0 0 0 7 2 9 0 0 0 0 0 0 0 0 0 0 0 5 4 0 1 0 0 7 0 3 2 0 0 0 0 3 0 6 8 0 0 2 0 0 5 0 0 1 9	0.614743589744
+0 0 0 7 2 5 3 1 0 4 2 0 0 8 1 0 0 7 0 0 0 9 0 4 0 0 8 0 6 0 0 5 0 0 0 1 0 9 7 0 0 0 5 2 0 5 0 0 0 7 0 0 9 0 6 0 0 5 0 7 0 0 0 2 0 0 8 1 0 0 4 5 0 5 8 4 6 2 0 0 0	0.622222222222
+6 0 9 0 1 0 0 0 0 0 4 0 0 0 5 0 0 0 7 1 5 9 0 0 6 4 0 9 0 0 7 6 0 4 0 0 0 8 6 5 0 4 9 7 0 0 0 4 0 9 8 0 0 6 0 6 3 0 0 9 7 1 4 0 0 0 8 0 0 0 5 0 0 0 0 0 4 0 8 0 9	0.613703703704
+0 8 9 0 0 0 0 0 0 2 0 0 0 7 6 0 0 0 0 0 5 0 0 9 2 0 3 0 1 0 9 0 0 4 0 0 0 5 7 0 4 0 9 2 0 0 0 4 0 0 8 0 5 0 4 0 6 8 0 0 5 0 0 0 0 0 7 2 0 0 0 6 0 0 0 0 0 0 7 9 0	0.660416666667
+6 5 0 7 0 2 0 9 0 0 0 0 4 1 0 2 0 0 7 0 2 5 0 0 0 0 0 0 0 0 0 0 0 5 6 2 4 0 0 1 0 5 0 0 8 5 2 3 0 0 0 0 0 0 0 0 0 0 0 4 3 0 1 0 0 4 0 7 8 0 0 0 0 7 0 2 0 1 0 4 9	0.604761904762
+2 0 0 0 0 0 6 4 0 0 0 0 7 0 8 5 0 0 0 0 0 4 2 0 0 7 0 0 0 7 1 5 2 4 0 9 0 2 0 0 0 0 0 8 0 6 0 1 9 8 4 2 0 0 0 8 0 0 4 3 0 0 0 0 0 2 8 0 5 0 0 0 0 1 6 0 0 0 0 0 4	0.672108843537
+0 0 0 0 0 9 3 0 1 2 0 0 0 1 0 0 0 9 8 0 1 5 3 0 0 7 0 0 0 0 1 0 0 0 4 0 6 0 5 0 0 0 8 0 3 0 4 0 0 0 8 0 0 0 0 2 0 0 8 5 9 0 7 5 0 0 0 2 0 0 0 6 3 0 6 9 0 0 0 0 0	0.648926237162
+0 9 0 2 0 0 7 0 0 7 0 1 0 0 9 0 2 5 0 0 8 5 0 0 0 0 0 1 0 9 0 0 0 4 6 0 0 5 7 0 0 0 3 1 0 0 6 4 0 0 0 9 0 7 0 0 0 0 0 8 5 0 0 9 7 0 6 0 0 1 0 4 0 0 3 0 0 4 0 9 0	0.667047295109
+0 6 4 2 0 0 0 0 0 5 0 1 0 0 0 8 0 4 3 0 0 0 4 9 0 2 0 0 4 0 0 9 0 0 0 0 1 3 5 0 0 0 2 6 9 0 0 0 0 2 0 0 7 0 0 7 0 3 1 0 0 0 2 4 0 6 0 0 0 9 0 3 0 0 0 0 0 4 7 8 0	0.653741496599
+0 0 0 8 0 3 9 1 0 0 1 0 9 0 0 0 3 5 0 3 0 0 5 0 0 8 0 3 0 1 0 2 0 4 9 0 0 8 0 0 0 0 0 6 0 0 9 7 0 4 0 8 0 3 0 5 0 0 1 0 0 4 0 1 2 0 0 0 5 0 7 0 0 4 6 2 0 9 0 0 0	0.637234042553
+2 0 7 6 8 0 0 0 9 0 0 1 0 0 4 0 0 0 0 8 6 0 0 0 2 0 0 1 0 8 0 5 2 0 3 0 3 0 0 0 1 0 0 0 5 0 4 0 7 3 0 1 0 2 0 0 4 0 0 0 7 2 0 0 0 0 5 0 0 8 0 0 7 0 0 0 4 3 5 0 6	0.745486111111
+8 4 0 1 0 7 0 0 2 0 0 6 0 0 0 1 0 0 0 1 7 0 2 0 0 4 3 0 0 8 0 0 2 0 0 6 0 0 0 5 0 1 0 0 0 6 0 0 9 0 0 2 0 0 2 3 0 0 5 0 6 8 0 0 0 5 0 0 0 7 0 0 7 0 0 3 0 8 0 2 5	0.636642665724
+6 1 0 0 0 4 0 0 8 4 9 0 0 0 0 5 0 0 0 0 8 0 1 0 0 4 0 0 5 0 0 2 0 8 0 0 0 6 0 0 7 0 0 2 0 0 0 9 0 6 0 0 5 0 0 3 0 0 8 0 1 0 0 0 0 7 0 0 0 0 6 3 1 0 0 9 0 0 0 8 5	0.631295787546
+0 2 3 6 0 5 9 0 0 0 7 0 8 4 0 0 3 0 8 0 0 0 0 0 7 5 0 0 0 0 0 5 8 0 0 1 0 0 0 0 0 0 0 0 0 4 0 0 3 6 0 0 0 0 0 5 4 0 0 0 0 0 7 0 8 0 0 3 1 0 4 0 0 0 7 5 0 4 6 2 0	0.633613445378
+0 0 0 1 3 2 0 9 0 0 1 0 0 7 0 2 0 3 0 0 0 5 0 0 1 4 0 0 7 0 0 0 0 9 2 4 1 0 0 0 0 0 0 0 6 9 4 6 0 0 0 0 3 0 0 8 1 0 0 3 0 0 0 2 0 4 0 6 0 0 1 0 0 6 0 7 4 1 0 0 0	0.605620343375
+0 0 7 1 6 2 4 9 0 0 0 0 0 8 0 0 7 5 0 0 0 0 4 0 2 0 0 2 6 0 0 5 3 0 0 9 0 9 0 0 0 0 0 2 0 7 0 0 2 9 0 0 1 6 0 0 8 0 3 0 0 0 0 1 7 0 0 2 0 0 0 0 0 4 9 5 1 7 8 0 0	0.656028368794
+0 0 0 0 0 5 0 0 0 0 3 0 7 0 4 5 0 1 0 5 0 0 1 0 7 0 3 1 8 0 2 0 0 0 5 0 7 4 0 0 9 0 0 3 2 0 9 0 0 0 8 0 7 4 9 0 4 0 7 0 0 1 0 5 0 1 4 0 3 0 6 0 0 0 0 9 0 0 0 0 0	0.624801587302
+0 0 0 7 0 5 8 0 0 6 0 1 2 0 0 0 0 0 0 2 0 4 0 0 0 0 9 0 0 2 0 0 0 0 0 6 9 4 6 0 0 0 2 7 5 1 0 0 0 0 0 3 0 0 7 0 0 0 0 4 0 5 0 0 0 0 0 0 9 7 0 1 0 0 9 5 0 8 0 0 0	0.647888589398
+0 0 0 3 0 8 0 5 4 8 5 0 6 9 0 0 0 0 2 0 0 0 4 0 0 8 0 6 0 0 0 0 0 7 0 1 7 2 0 0 0 0 0 4 5 3 0 5 0 0 0 0 0 2 0 7 0 0 5 0 0 0 3 0 0 0 0 8 6 0 2 9 4 6 0 9 0 3 0 0 0	0.602380952381
+0 0 8 0 0 5 0 3 4 6 7 0 0 0 3 0 9 0 1 0 0 0 0 0 0 0 0 0 5 0 0 7 0 3 0 0 0 0 3 9 0 1 5 0 0 0 0 1 0 5 0 0 4 0 0 0 0 0 0 0 0 0 3 0 9 0 8 0 0 0 1 7 3 4 0 2 0 0 6 0 0	0.649109014675
+0 2 0 0 0 0 0 0 8 4 0 0 0 0 2 0 1 0 8 5 0 7 0 0 9 0 0 0 6 0 0 9 4 3 7 5 0 4 0 0 0 0 0 8 0 7 8 5 1 2 0 0 6 0 0 0 4 0 0 6 0 9 3 0 3 0 5 0 0 0 0 1 6 0 0 0 0 0 0 5 0	0.662244897959
+0 6 0 7 0 0 0 0 2 0 0 0 5 4 0 6 8 1 0 0 0 3 0 0 0 9 0 8 0 0 0 0 5 0 0 3 0 9 7 0 0 0 2 4 0 3 0 0 4 0 0 0 0 6 0 8 0 0 0 4 0 0 0 5 4 2 0 3 1 0 0 0 1 0 0 0 0 6 0 2 0	0.605555555556
+4 0 7 2 0 0 0 0 0 0 0 0 6 3 0 1 0 0 0 2 6 7 0 0 0 4 5 0 0 0 0 9 0 2 7 0 0 7 0 4 0 3 0 6 0 0 6 9 0 7 0 0 0 0 7 5 0 0 0 2 4 8 0 0 0 8 0 4 7 0 0 0 0 0 0 0 0 8 7 0 6	0.734693877551
+0 8 7 6 0 0 0 0 5 0 0 4 8 9 0 0 0 0 2 0 0 0 0 0 9 0 8 5 0 0 3 2 0 0 9 1 0 0 1 0 0 0 8 0 0 7 9 0 0 8 1 0 0 6 1 0 5 0 0 0 0 0 9 0 0 0 0 1 8 2 0 0 8 0 0 0 0 9 1 6 0	0.695578231293
+1 0 0 0 0 0 0 2 0 0 0 0 0 2 8 0 0 6 0 0 2 0 0 9 4 5 3 0 4 0 0 3 5 6 0 2 0 0 8 0 0 0 7 0 0 6 0 1 7 9 0 0 8 0 2 1 3 9 0 0 5 0 0 9 0 0 6 5 0 0 0 0 0 7 0 0 0 0 0 0 9	0.636394557823
+0 8 0 0 0 0 0 6 0 5 0 9 0 0 4 3 0 2 4 6 0 0 0 2 7 0 0 9 0 0 7 0 0 0 4 6 0 0 6 0 0 0 2 0 0 7 2 0 0 0 1 0 0 9 0 0 5 9 0 0 0 2 8 2 0 8 4 0 0 6 0 3 0 3 0 0 0 0 0 5 0	0.613216715258
+0 8 0 1 0 0 0 7 0 0 3 0 0 4 9 1 6 0 9 0 0 7 0 0 0 3 0 2 0 0 9 0 1 3 0 0 0 9 0 0 0 0 0 1 0 0 0 7 6 0 2 0 0 9 0 7 0 0 0 5 0 0 3 0 2 9 8 1 0 0 5 0 0 4 0 0 0 6 0 9 0	0.745578231293
+0 0 0 0 2 3 4 0 8 0 0 0 0 7 4 6 9 0 0 0 0 8 9 0 0 0 7 0 0 9 3 0 0 7 4 0 0 7 0 0 4 0 0 3 0 0 8 3 0 0 7 2 0 0 5 0 0 0 1 9 0 0 0 0 9 2 4 3 0 0 0 0 3 0 6 7 5 0 0 0 0	0.618005952381
+0 0 0 7 0 0 3 0 0 1 0 0 6 0 9 0 5 0 0 5 2 4 0 0 0 0 9 0 0 0 0 9 6 1 0 5 0 6 0 0 7 0 0 8 0 8 0 5 3 4 0 0 0 0 2 0 0 0 0 7 6 4 0 0 8 0 1 0 4 0 0 3 0 0 3 0 0 8 0 0 0	0.672261904762
+0 6 2 7 0 0 0 0 0 0 9 0 0 1 0 0 0 0 8 0 5 4 0 0 6 0 2 0 8 0 0 6 0 0 0 9 4 0 0 1 0 2 0 0 6 2 0 0 0 4 0 0 3 0 9 0 8 0 0 4 3 0 5 0 0 0 0 8 0 0 9 0 0 0 0 0 0 1 8 6 0	0.67790227202
+0 2 0 0 0 0 0 0 1 0 4 6 1 0 3 0 2 8 0 0 0 8 0 5 3 0 0 0 0 4 3 0 0 8 5 0 2 0 0 0 0 0 0 0 3 0 8 5 0 0 9 2 0 0 0 0 9 4 0 6 0 0 0 4 6 0 2 0 1 9 3 0 1 0 0 0 0 0 0 4 0	0.637390670554
+6 0 0 0 8 0 0 1 0 1 0 0 0 0 4 3 0 0 0 3 5 2 1 0 0 0 0 0 5 0 3 2 0 4 6 7 0 1 7 0 0 0 8 3 0 3 6 2 0 4 7 0 9 0 0 0 0 0 9 2 6 7 0 0 0 6 4 0 0 0 0 9 0 9 0 0 7 0 0 0 3	0.622592592593
+0 0 3 0 0 2 0 9 0 5 0 0 0 6 0 0 0 0 8 2 1 9 0 4 7 0 0 0 5 4 0 1 0 0 8 9 0 0 0 0 0 0 0 0 0 1 6 0 0 5 0 4 3 0 0 0 6 7 0 3 8 1 5 0 0 0 0 9 0 0 0 3 0 1 0 4 0 0 9 0 0	0.600340136054
+0 0 6 5 0 0 3 8 9 0 8 0 0 0 0 0 0 1 0 0 0 0 8 7 0 6 5 8 0 0 0 3 0 5 9 0 0 0 0 7 0 8 0 0 0 0 3 2 0 6 0 0 0 8 7 6 0 1 9 0 0 0 0 2 0 0 0 0 0 0 3 0 9 5 4 0 0 3 6 0 0	0.687414965986
+0 0 0 3 0 0 2 1 0 0 7 8 0 2 0 0 9 0 0 2 0 0 0 9 3 0 7 0 0 7 0 1 2 0 0 0 0 3 5 0 6 0 1 4 0 0 0 0 4 3 0 7 0 0 8 0 2 7 0 0 0 6 0 0 6 0 0 8 0 9 7 0 0 5 4 0 0 6 0 0 0	0.725
+0 8 0 0 7 9 1 0 2 2 7 0 1 0 8 0 0 9 0 0 0 3 0 0 0 7 0 0 1 0 0 0 0 7 0 0 5 0 0 0 0 0 0 0 4 0 0 4 0 0 0 0 6 0 0 4 0 0 0 5 0 0 0 9 0 0 7 0 4 0 5 6 8 0 5 6 9 0 0 2 0	0.629162776222
+9 1 4 0 6 0 2 0 0 0 3 0 2 0 0 0 6 9 2 0 6 0 0 7 0 0 0 6 4 0 5 0 0 0 2 0 0 0 0 0 4 0 0 0 0 0 8 0 0 0 2 0 5 6 0 0 0 6 0 0 3 0 5 1 6 0 0 0 3 0 4 0 0 0 3 0 7 0 6 1 2	0.646759259259
+2 0 0 1 8 0 0 0 5 8 4 0 0 0 0 9 0 0 0 0 7 2 0 9 0 0 1 0 0 5 0 0 0 0 3 4 0 0 8 4 0 5 7 0 0 1 2 0 0 0 0 6 0 0 4 0 0 7 0 3 1 0 0 0 0 6 0 0 0 0 9 3 5 0 0 0 6 1 0 0 7	0.604146420473
+0 0 7 0 3 0 0 0 0 0 0 4 2 0 0 9 0 0 5 0 0 0 8 4 7 0 0 4 8 0 7 6 0 0 9 0 0 5 0 0 0 0 0 8 0 0 3 0 0 1 8 0 7 5 0 0 5 6 4 0 0 0 7 0 0 8 0 0 9 6 0 0 0 0 0 0 7 0 5 0 0	0.602567693744
+0 8 5 6 0 3 0 0 4 0 0 2 0 0 1 0 0 0 0 0 3 5 0 0 1 6 0 0 4 0 0 5 0 3 8 0 0 0 9 3 2 8 4 0 0 0 5 8 0 1 0 0 7 0 0 3 7 0 0 5 9 0 0 0 0 0 2 0 0 8 0 0 5 0 0 8 0 9 6 3 0	0.644927536232
+5 0 0 0 3 0 6 0 0 0 0 0 5 2 0 0 1 0 0 2 0 4 7 0 0 0 3 9 3 0 7 0 0 0 6 0 0 6 8 0 0 0 3 4 0 0 5 0 0 0 4 0 2 9 6 0 0 0 5 8 0 3 0 0 1 0 0 4 7 0 0 0 0 0 5 0 9 0 0 0 6	0.738095238095
+0 0 5 0 0 8 0 0 0 0 1 0 0 0 0 5 9 6 9 0 0 7 0 0 8 0 0 0 0 0 0 4 0 2 0 0 8 9 0 1 0 2 0 5 4 0 0 2 0 8 0 0 0 0 0 0 9 0 0 6 0 0 7 5 3 6 0 0 0 0 1 0 0 0 0 8 0 0 4 0 0	0.639061096137
+0 0 0 2 7 0 0 3 0 0 5 0 0 0 8 0 0 0 9 0 6 0 0 4 1 0 8 6 3 0 0 0 0 5 0 0 4 0 0 7 0 3 0 0 6 0 0 5 0 0 0 0 4 7 7 0 9 3 0 0 8 0 4 0 0 0 1 0 0 0 6 0 0 6 0 0 4 5 0 0 0	0.728758169935
+0 0 5 8 0 0 6 7 0 3 0 0 0 7 0 2 0 0 0 7 0 0 0 2 0 8 4 0 6 0 7 0 9 0 0 8 0 5 3 0 0 0 9 6 0 8 0 0 2 0 5 0 3 0 6 4 0 3 0 0 0 9 0 0 0 8 0 5 0 0 0 6 0 9 7 0 0 6 8 0 0	0.641843971631
+0 5 0 0 0 3 0 0 0 6 4 0 0 0 0 0 0 0 0 0 2 6 0 0 7 5 0 0 7 6 9 0 4 0 1 8 0 2 4 0 0 0 5 7 0 1 8 0 7 0 5 9 4 0 0 3 9 0 0 6 1 0 0 0 0 0 0 0 0 0 2 9 0 0 0 4 0 0 0 3 0	0.634062196307
+0 0 0 0 0 0 2 0 0 2 3 0 0 0 8 0 9 7 0 7 6 1 0 2 0 4 5 3 0 0 7 0 0 0 5 0 0 0 7 0 8 0 3 0 0 0 1 0 0 0 6 0 0 4 7 2 0 8 0 4 5 6 0 8 6 0 2 0 0 0 7 3 0 0 5 0 0 0 0 0 0	0.744890873016
+0 0 0 2 0 9 0 0 8 1 0 0 0 0 8 5 9 0 0 9 6 0 7 0 0 0 2 0 4 0 5 0 0 0 8 9 0 0 8 0 0 0 7 0 0 9 5 0 0 0 3 0 2 0 5 0 0 0 3 0 8 7 0 0 8 9 1 0 0 0 0 5 7 0 0 8 0 2 0 0 0	0.697278911565
+0 7 0 8 1 0 5 0 0 0 0 0 2 0 0 7 3 0 0 2 3 9 5 0 0 6 0 0 4 0 6 8 0 0 9 5 0 0 0 0 0 0 0 0 0 6 9 0 0 7 1 0 4 0 0 5 0 0 2 9 6 1 0 0 3 4 0 0 8 0 0 0 0 0 2 0 3 5 0 8 0	0.633333333333
+0 6 9 2 0 0 0 0 0 0 0 0 0 0 9 2 0 0 2 1 0 4 0 5 6 0 3 0 0 0 0 0 2 0 3 8 7 0 2 0 0 0 9 0 6 5 8 0 6 0 0 0 0 0 6 0 3 5 0 8 0 2 9 0 0 5 9 0 0 0 0 0 0 0 0 0 0 7 5 6 0	0.710884353741
+2 7 0 3 0 5 0 0 0 0 0 9 0 0 0 1 0 0 3 8 0 1 7 6 9 0 0 8 1 0 0 2 0 0 0 0 0 0 0 6 0 1 0 0 0 0 0 0 0 5 0 0 1 4 0 0 8 7 1 3 0 9 2 0 0 3 0 0 0 6 0 0 0 0 0 5 0 4 0 8 1	0.631171039845
+0 9 2 0 0 3 0 0 4 6 0 0 9 1 0 7 0 0 0 0 3 2 0 0 0 1 0 0 0 4 1 0 0 0 0 9 0 5 0 0 0 0 0 3 0 9 0 0 0 0 7 4 0 0 0 2 0 0 0 1 6 0 0 0 0 8 0 7 2 0 0 1 7 0 0 3 0 0 2 5 0	0.71568627451
+3 1 0 9 0 0 0 0 0 8 0 0 0 0 4 0 0 5 9 4 0 3 0 8 6 0 0 0 0 4 0 0 0 2 0 0 5 9 0 0 0 0 0 3 6 0 0 1 0 0 0 5 0 0 0 0 9 8 0 3 0 2 7 7 0 0 2 0 0 0 0 3 0 0 0 0 0 9 0 5 4	0.610636476813
+4 0 0 0 0 2 6 0 0 0 6 0 0 0 5 0 0 9 9 1 2 0 3 0 0 7 0 0 0 4 0 0 0 0 0 2 7 2 0 0 0 0 0 8 1 6 0 0 0 0 0 3 0 0 0 7 0 0 8 0 1 3 6 5 0 0 2 0 0 0 4 0 0 0 8 7 0 0 0 0 5	0.696078431373
+0 0 0 0 6 0 0 0 4 0 9 0 0 0 0 6 2 8 0 8 0 4 0 0 5 0 7 0 0 4 0 0 5 3 0 0 0 0 0 6 9 4 0 0 0 0 0 6 2 0 0 8 0 0 3 0 1 0 0 7 0 9 0 2 4 8 0 0 0 0 5 0 7 0 0 0 4 0 0 0 0	0.610500610501
+0 0 0 0 0 0 0 2 8 2 0 0 8 1 3 9 0 0 0 0 6 0 2 0 5 0 3 0 3 7 1 0 0 2 0 0 6 0 1 0 0 0 7 0 5 0 0 2 0 0 7 3 1 0 1 0 9 0 4 0 6 0 0 0 0 8 3 6 1 0 0 2 4 6 0 0 0 0 0 0 0	0.645744680851
+0 0 6 0 3 9 4 0 0 0 9 4 0 0 1 8 3 0 3 0 0 0 0 0 0 0 5 0 0 1 0 4 0 0 0 8 9 5 0 3 0 8 0 4 6 4 0 0 0 5 0 9 0 0 7 0 0 0 0 0 0 0 4 0 4 5 7 0 0 2 6 0 0 0 3 4 9 0 5 0 0	0.603394123607
+0 0 7 6 1 5 0 0 0 1 0 9 7 0 8 0 0 6 0 0 0 3 0 0 0 7 1 0 4 0 1 8 0 6 0 0 0 9 0 0 0 0 0 5 0 0 0 2 0 5 6 0 1 0 9 1 0 0 0 2 0 0 0 2 0 0 5 0 9 1 0 8 0 0 0 8 3 1 9 0 0	0.734042553191
+8 0 0 9 1 0 0 0 0 3 0 7 6 0 0 9 0 1 0 9 0 0 0 0 0 0 0 5 0 0 0 3 0 7 0 9 0 3 4 0 8 0 2 6 0 9 0 2 0 7 0 0 0 4 0 0 0 0 0 0 0 5 0 1 0 3 0 0 2 4 0 7 0 0 0 0 9 1 0 0 3	0.716333333333
+0 0 2 6 7 0 1 0 0 9 0 0 0 0 1 5 0 0 0 8 0 4 0 0 0 0 7 8 0 3 1 2 0 4 0 6 0 6 0 0 0 0 0 7 0 7 0 4 0 9 6 3 0 1 4 0 0 0 0 8 0 3 0 0 0 8 3 0 0 0 0 4 0 0 7 0 4 2 8 0 0	0.717021276596
+0 2 0 0 0 4 9 1 0 4 0 5 1 2 0 0 0 7 0 0 0 9 0 3 0 0 5 0 0 1 0 0 0 5 0 0 0 6 0 8 0 5 0 9 0 0 0 9 0 0 0 7 0 0 5 0 0 6 0 8 0 0 0 6 0 0 0 9 7 1 0 8 0 8 2 3 0 0 0 7 0	0.665646258503
+5 0 0 8 0 4 6 0 9 0 0 1 0 0 0 5 8 0 6 9 0 0 0 7 0 0 0 8 0 4 0 7 3 0 5 0 0 0 5 0 0 0 9 0 0 0 6 0 5 4 0 8 0 3 0 0 0 7 0 0 0 2 8 0 8 7 0 0 0 3 0 0 1 0 6 3 0 8 0 0 4	0.63829787234
+1 5 0 0 0 0 0 6 3 2 3 6 0 0 4 9 8 1 0 0 0 0 1 3 0 0 0 8 7 0 0 0 5 0 9 0 0 0 0 0 0 0 0 0 0 0 1 0 2 0 0 0 3 8 0 0 0 4 2 0 0 0 0 6 4 3 5 0 0 8 2 9 9 2 0 0 0 0 0 5 4	0.716312056738
+0 0 0 0 0 4 0 1 0 4 1 0 0 2 5 0 0 0 2 0 0 9 0 0 6 0 0 0 9 3 0 0 6 7 0 0 0 8 0 4 0 3 0 2 0 0 0 4 1 0 0 8 3 0 0 0 6 0 0 9 0 0 7 0 0 0 8 6 0 0 9 5 0 5 0 7 0 0 0 0 0	0.616713352007
+3 0 0 8 6 0 0 7 0 6 0 7 0 2 3 0 0 4 0 2 0 0 0 0 3 0 0 0 6 0 0 0 1 7 0 0 0 9 0 3 7 2 0 4 0 0 0 5 6 0 0 0 2 0 0 0 9 0 0 0 0 5 0 8 0 0 4 1 0 9 0 2 0 1 0 0 9 6 0 0 7	0.603472222222
+0 0 3 0 0 0 0 0 7 0 0 0 0 8 0 2 9 0 2 6 0 0 7 0 3 0 0 0 5 2 6 9 0 0 0 3 0 0 0 0 0 0 0 0 0 4 0 0 0 1 3 5 7 0 0 0 8 0 6 0 0 5 1 0 7 6 0 5 0 0 0 0 9 0 0 0 0 0 6 0 0	0.677657981432
+9 0 0 1 0 0 0 0 2 0 0 0 2 0 5 8 0 0 0 0 0 0 8 3 4 0 0 0 5 0 9 6 7 0 0 0 0 7 2 4 3 1 9 5 0 0 0 0 5 2 8 0 1 0 0 0 8 3 1 0 0 0 0 0 0 5 8 0 4 0 0 0 1 0 0 0 0 2 0 0 8	0.619097222222
+0 0 0 7 0 0 4 1 0 0 0 3 0 2 0 0 0 6 1 0 7 4 0 0 5 2 3 4 0 1 6 0 0 0 8 0 0 2 9 0 7 0 6 3 0 0 7 0 0 0 4 2 0 1 7 5 2 0 0 6 3 0 9 3 0 0 0 4 0 1 0 0 0 1 4 0 0 3 0 0 0	0.659090909091
+6 0 0 3 0 0 1 0 0 0 7 1 6 2 0 0 0 0 8 0 5 0 0 1 0 0 0 5 0 0 8 7 0 9 0 1 0 0 9 0 0 0 6 0 0 4 0 7 0 6 9 0 0 8 0 0 0 2 0 0 8 0 7 0 0 0 0 8 6 4 1 0 0 0 8 0 0 3 0 0 2	0.626336248785
+9 0 6 0 1 3 0 0 8 0 5 8 0 0 0 0 9 0 0 3 0 0 0 0 0 1 0 0 6 0 8 0 0 9 2 0 0 0 3 4 0 9 1 0 0 0 4 9 0 0 6 0 3 0 0 9 0 0 0 0 0 8 0 0 1 0 0 0 0 6 7 0 4 0 0 9 6 0 3 0 1	0.605442176871
+3 0 0 0 6 0 2 5 0 0 0 0 5 0 0 1 0 3 0 0 5 2 1 0 4 8 6 0 0 0 3 8 0 5 0 0 0 3 0 0 0 0 0 4 0 0 0 2 0 4 5 0 0 0 4 1 3 0 5 2 7 0 0 8 0 7 0 0 4 0 0 0 0 5 6 0 7 0 0 0 4	0.732978723404
+0 6 0 0 0 1 9 0 7 1 0 0 0 0 7 2 3 0 0 8 0 0 0 0 4 0 6 0 1 8 0 0 2 0 0 4 0 7 0 0 4 0 0 9 0 9 0 0 1 0 0 7 8 0 6 0 7 0 0 0 0 4 0 0 5 1 6 0 0 0 0 9 8 0 9 3 0 0 0 2 0	0.621527777778
+6 0 0 3 0 0 2 0 8 4 0 0 1 8 5 0 0 0 0 0 0 0 0 0 4 5 0 0 0 0 0 7 0 8 3 5 0 3 0 5 0 8 0 2 0 9 5 8 0 1 0 0 0 0 0 6 9 0 0 0 0 0 0 0 0 0 6 3 1 0 0 2 3 0 4 0 0 9 0 0 6	0.668999028183
+4 0 0 0 3 0 0 9 0 2 0 0 0 0 1 6 0 0 7 6 0 8 0 0 0 0 1 5 0 0 3 1 8 0 0 0 0 3 2 0 0 0 5 1 0 0 0 0 5 9 2 0 0 8 9 0 0 0 0 3 0 4 5 0 0 1 7 0 0 0 0 6 0 4 0 0 2 0 0 0 3	0.62789925494
+0 0 4 0 9 0 1 7 0 9 0 0 0 7 0 0 0 2 0 0 7 2 0 4 0 0 0 0 4 3 0 0 0 0 5 0 7 9 8 4 0 6 2 1 3 0 6 0 0 0 0 8 9 0 0 0 0 7 0 9 4 0 0 6 0 0 0 4 0 0 0 1 0 8 5 0 3 0 7 0 0	0.65780141844
+6 8 0 0 0 1 0 0 3 0 0 7 0 0 4 0 0 0 0 0 0 8 2 0 0 0 0 8 7 0 0 0 9 2 0 4 0 4 0 3 0 2 0 8 0 2 0 3 4 0 0 0 9 6 0 0 0 0 3 6 0 0 0 0 0 0 5 0 0 4 0 0 7 0 0 2 0 0 0 6 5	0.627987861811
+0 0 0 0 0 2 0 0 0 1 0 3 4 0 0 0 0 5 2 0 0 0 5 0 4 0 1 3 4 0 0 0 5 0 9 0 8 0 7 0 0 0 3 0 4 0 9 0 3 0 0 0 1 7 6 0 5 0 3 0 0 0 9 4 0 0 0 0 8 7 0 2 0 0 0 1 0 0 0 0 0	0.746405228758
+0 5 0 7 0 2 0 0 3 0 7 3 4 8 0 0 0 5 0 0 0 0 5 0 4 0 0 0 4 0 0 0 0 2 0 0 0 2 7 0 9 0 3 5 0 0 0 6 0 0 0 0 1 0 0 0 5 0 3 0 0 0 0 4 0 0 0 6 8 7 3 0 7 0 0 1 0 9 0 6 0	0.61353968254
+5 0 0 0 8 0 0 2 0 0 0 7 5 0 2 8 0 1 0 0 2 9 0 0 0 4 0 0 2 4 0 0 0 3 0 8 0 0 0 3 2 4 0 0 0 3 0 6 0 0 0 4 7 0 0 9 0 0 0 6 7 0 0 7 0 3 2 0 8 9 0 0 0 6 0 0 9 0 0 0 5	0.640128968254
+1 0 8 0 9 0 0 0 0 2 0 0 3 0 8 0 9 6 0 9 0 0 0 0 4 0 0 4 0 6 0 0 9 0 3 0 0 1 0 2 0 5 0 6 0 0 8 0 6 0 0 2 0 1 0 0 1 0 0 0 0 4 0 3 6 0 9 0 4 0 0 7 0 0 0 0 6 0 3 0 5	0.664285714286
+0 1 0 0 0 8 5 7 0 6 0 7 0 5 0 0 0 9 0 5 2 1 7 0 0 0 0 0 0 1 0 0 3 7 0 6 0 7 0 0 0 0 0 4 0 8 0 3 7 0 0 9 0 0 0 0 0 0 1 7 2 6 0 1 0 0 0 2 0 4 0 7 0 2 4 3 0 0 0 9 0	0.630597771023
+0 2 0 4 3 9 8 0 0 0 8 0 0 0 0 0 0 1 0 0 3 0 0 1 5 2 0 0 5 0 0 9 2 7 0 3 0 0 0 0 0 0 0 0 0 3 0 9 7 4 0 0 8 0 0 7 1 3 0 0 9 0 0 6 0 0 0 0 0 0 3 0 0 0 8 9 2 4 0 1 0	0.732993197279
+0 0 0 5 0 0 2 0 1 8 0 0 0 0 6 0 0 5 0 0 5 2 0 7 0 8 0 0 1 7 9 6 0 8 0 4 0 0 0 0 0 0 0 0 0 9 0 8 0 7 4 6 1 0 0 8 0 4 0 5 3 0 0 7 0 0 6 0 0 0 0 9 5 0 4 0 0 9 0 0 0	0.736394557823
+9 2 0 0 0 0 0 0 0 5 0 0 8 7 0 0 0 0 0 3 8 0 9 1 0 0 0 0 5 2 9 3 0 1 6 0 0 9 0 0 0 0 0 3 0 0 7 3 0 6 4 9 8 0 0 0 0 4 1 0 2 5 0 0 0 0 0 5 3 0 0 1 0 0 0 0 0 0 0 7 3	0.665484288954
+5 9 0 0 0 6 0 1 0 0 0 1 2 5 4 7 0 9 0 0 0 0 0 1 4 0 0 0 0 3 7 1 5 0 0 8 1 0 0 0 0 0 0 0 4 2 0 0 6 4 8 1 0 0 0 0 2 5 0 0 0 0 0 7 0 8 4 6 3 9 0 0 0 5 0 1 0 0 0 4 7	0.603051146384
+3 0 9 8 7 0 0 0 4 0 0 0 0 0 5 0 0 8 8 7 0 4 0 0 0 0 0 1 0 4 5 8 0 0 0 3 0 0 0 7 0 6 0 0 0 7 0 0 0 3 4 1 0 5 0 0 0 0 0 9 0 8 1 9 0 0 3 0 0 0 0 0 4 0 0 0 5 7 2 0 6	0.654761904762
+8 0 0 2 0 0 0 0 0 9 1 0 3 0 0 7 0 6 0 0 0 0 0 7 0 0 2 0 8 4 0 0 0 0 0 9 0 9 5 1 0 4 8 6 0 1 0 0 0 0 0 2 3 0 5 0 0 6 0 0 0 0 0 6 0 9 0 0 3 0 7 1 0 0 0 0 0 5 0 0 8	0.610410830999
+0 0 5 0 3 7 0 0 1 0 0 0 0 5 0 6 2 7 6 0 0 0 0 2 5 3 0 0 2 0 0 7 0 0 0 0 0 0 1 9 6 8 2 0 0 0 0 0 0 1 0 0 9 0 0 1 3 7 0 0 0 0 8 4 8 6 0 9 0 0 0 0 7 0 0 8 4 0 1 0 0	0.645833333333
+0 9 0 3 5 0 7 0 0 0 0 0 8 0 0 0 2 9 0 0 0 4 0 2 0 0 8 7 1 0 0 0 0 0 0 0 4 6 3 5 0 8 2 9 7 0 0 0 0 0 0 0 5 1 3 0 0 2 0 4 0 0 0 9 4 0 0 0 5 0 0 0 0 0 8 0 3 7 0 4 0	0.613537709456
+0 0 0 0 0 5 9 0 4 0 8 0 0 9 0 6 0 5 0 0 6 0 0 0 0 3 0 0 3 0 7 0 1 4 5 0 0 0 8 0 4 0 7 0 0 0 7 4 2 0 6 0 9 0 0 6 0 0 0 0 3 0 0 8 0 1 0 6 0 0 7 0 3 0 9 8 0 0 0 0 0	0.600142857143
+0 3 0 0 0 4 0 8 7 9 4 8 7 0 0 5 0 0 0 6 0 8 0 0 0 0 9 0 1 0 5 8 6 7 2 0 0 0 0 0 0 0 0 0 0 0 8 7 3 1 2 0 5 0 8 0 0 0 0 3 0 7 0 0 0 3 0 0 7 8 6 5 5 7 0 2 0 0 0 9 0	0.666666666667
+3 0 0 6 8 7 0 1 5 0 0 0 0 3 0 0 8 2 0 5 0 0 0 0 3 0 0 4 0 0 3 0 0 0 0 0 6 0 1 0 5 0 7 0 9 0 0 0 0 0 4 0 0 3 0 0 8 0 0 0 0 2 0 2 1 0 0 4 0 0 0 0 9 7 0 5 2 1 0 0 4	0.749333333333
+7 0 2 0 0 0 0 0 4 0 3 0 7 0 2 0 1 0 4 0 0 0 9 3 0 0 8 0 0 0 8 2 7 0 9 0 0 0 7 0 3 0 8 0 0 0 8 0 9 5 6 0 0 0 3 0 0 5 7 0 0 0 9 0 2 0 3 0 9 0 8 0 6 0 0 0 0 0 5 0 3	0.616319444444
+3 0 0 0 4 0 0 5 7 4 0 0 8 5 3 0 6 0 0 2 5 7 0 0 0 0 0 0 0 0 0 0 0 4 3 0 8 0 0 4 0 6 0 0 1 0 3 4 0 0 0 0 0 0 0 0 0 0 0 5 6 9 0 0 9 0 6 2 4 0 0 3 1 6 0 0 8 0 0 0 2	0.674489795918
+0 0 0 2 6 0 0 5 0 0 0 0 0 0 5 9 0 0 0 0 0 3 8 0 0 4 6 0 2 0 0 9 4 0 1 8 0 0 4 0 0 0 5 0 0 9 5 0 8 1 0 0 7 0 3 8 0 0 2 1 0 0 0 0 0 5 7 0 0 0 0 0 0 4 0 0 5 8 0 0 0	0.65231092437
+0 6 2 0 8 0 5 0 4 0 0 8 0 5 0 0 9 0 7 0 0 3 2 0 0 0 1 0 0 0 7 4 0 6 2 0 0 0 0 2 0 3 0 0 0 0 2 7 0 6 5 0 0 0 2 0 0 0 3 6 0 0 7 0 4 0 0 7 0 1 0 0 8 0 3 0 9 0 2 4 0	0.652482269504
+0 0 2 0 0 1 0 0 0 0 6 8 0 0 0 0 0 3 0 0 0 0 8 6 0 9 0 9 0 0 0 0 2 0 8 6 8 0 4 0 0 0 1 0 2 5 2 0 8 0 0 0 0 9 0 8 0 1 4 0 0 0 0 1 0 0 0 0 0 9 2 0 0 0 0 7 0 0 5 0 0	0.711635220126
+0 0 0 0 3 0 0 6 5 4 6 0 9 5 0 2 0 0 0 0 0 0 8 6 0 0 4 0 0 3 0 7 0 0 0 6 0 0 4 0 9 0 1 0 0 5 0 0 0 1 0 3 0 0 2 0 0 1 4 0 0 0 0 0 0 7 0 6 5 0 2 8 6 3 0 0 2 0 0 0 0	0.604619047619
Index: gnome-sudoku/glade/print_games.glade
===================================================================
--- gnome-sudoku/glade/print_games.glade	(revision 6846)
+++ gnome-sudoku/glade/print_games.glade	(working copy)
@@ -1,589 +1,289 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--*- mode: xml -*-->
 <glade-interface>
-<requires lib="gnome"/>
-
-<widget class="GtkDialog" id="dialog1">
-  <property name="visible">True</property>
-  <property name="title" translatable="yes">Print Sudokus</property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_NONE</property>
-  <property name="modal">False</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-  <property name="has_separator">False</property>
-
-  <child internal-child="vbox">
-    <widget class="GtkVBox" id="dialog-vbox1">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">0</property>
-
-      <child internal-child="action_area">
-	<widget class="GtkHButtonBox" id="dialog-action_area1">
-	  <property name="visible">True</property>
-	  <property name="layout_style">GTK_BUTTONBOX_END</property>
-
-	  <child>
-	    <widget class="GtkButton" id="cancelbutton1">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-cancel</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-6</property>
-	    </widget>
-	  </child>
-
-	  <child>
-	    <widget class="GtkButton" id="okbutton1">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-print</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-5</property>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	  <property name="pack_type">GTK_PACK_END</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkAlignment" id="alignment3">
-	  <property name="visible">True</property>
-	  <property name="xalign">0.5</property>
-	  <property name="yalign">0.5</property>
-	  <property name="xscale">1</property>
-	  <property name="yscale">1</property>
-	  <property name="top_padding">12</property>
-	  <property name="bottom_padding">12</property>
-	  <property name="left_padding">12</property>
-	  <property name="right_padding">12</property>
-
-	  <child>
-	    <widget class="GtkVBox" id="vbox1">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">0</property>
-
-	      <child>
-		<widget class="GtkLabel" id="label5">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">&lt;span size=&quot;larger&quot; weight=&quot;bold&quot;&gt;Print Games&lt;/span&gt;</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkVBox" id="vbox3">
-		  <property name="visible">True</property>
-		  <property name="homogeneous">False</property>
-		  <property name="spacing">0</property>
-
-		  <child>
-		    <widget class="GtkTable" id="table1">
-		      <property name="visible">True</property>
-		      <property name="n_rows">2</property>
-		      <property name="n_columns">2</property>
-		      <property name="homogeneous">False</property>
-		      <property name="row_spacing">0</property>
-		      <property name="column_spacing">0</property>
-
-		      <child>
-			<widget class="GtkLabel" id="label7">
-			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">_Number of sudoku to print: </property>
-			  <property name="use_underline">True</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			  <property name="mnemonic_widget">sudokusToPrintSpinButton</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">0</property>
-			  <property name="right_attach">1</property>
-			  <property name="top_attach">0</property>
-			  <property name="bottom_attach">1</property>
-			  <property name="x_options">fill</property>
-			  <property name="y_options"></property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkLabel" id="label8">
-			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">_Sudokus per page: </property>
-			  <property name="use_underline">True</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			  <property name="mnemonic_widget">sudokusPerPageSpinButton</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">0</property>
-			  <property name="right_attach">1</property>
-			  <property name="top_attach">1</property>
-			  <property name="bottom_attach">2</property>
-			  <property name="x_options">fill</property>
-			  <property name="y_options"></property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkSpinButton" id="sudokusToPrintSpinButton">
-			  <property name="visible">True</property>
-			  <property name="can_focus">True</property>
-			  <property name="climb_rate">1</property>
-			  <property name="digits">0</property>
-			  <property name="numeric">False</property>
-			  <property name="update_policy">GTK_UPDATE_ALWAYS</property>
-			  <property name="snap_to_ticks">False</property>
-			  <property name="wrap">False</property>
-			  <property name="adjustment">4 1 100 1 10 10</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">1</property>
-			  <property name="right_attach">2</property>
-			  <property name="top_attach">0</property>
-			  <property name="bottom_attach">1</property>
-			  <property name="y_options"></property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkSpinButton" id="sudokusPerPageSpinButton">
-			  <property name="visible">True</property>
-			  <property name="can_focus">True</property>
-			  <property name="climb_rate">1</property>
-			  <property name="digits">0</property>
-			  <property name="numeric">False</property>
-			  <property name="update_policy">GTK_UPDATE_ALWAYS</property>
-			  <property name="snap_to_ticks">False</property>
-			  <property name="wrap">False</property>
-			  <property name="adjustment">1 1 9 1 10 10</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">1</property>
-			  <property name="right_attach">2</property>
-			  <property name="top_attach">1</property>
-			  <property name="bottom_attach">2</property>
-			  <property name="y_options"></property>
-			</packing>
-		      </child>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">True</property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkCheckButton" id="labelGamesToggle">
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="label" translatable="yes">_Label games with difficulty and name.</property>
-		      <property name="use_underline">True</property>
-		      <property name="relief">GTK_RELIEF_NORMAL</property>
-		      <property name="focus_on_click">True</property>
-		      <property name="active">False</property>
-		      <property name="inconsistent">False</property>
-		      <property name="draw_indicator">True</property>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkCheckButton" id="markAsPlayedToggle">
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="label" translatable="yes">_Mark games as played once you've printed them.</property>
-		      <property name="use_underline">True</property>
-		      <property name="relief">GTK_RELIEF_NORMAL</property>
-		      <property name="focus_on_click">True</property>
-		      <property name="active">False</property>
-		      <property name="inconsistent">False</property>
-		      <property name="draw_indicator">True</property>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="label6">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">Choose the _level of difficulty for games</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">True</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">12</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkAlignment" id="alignment4">
-		  <property name="visible">True</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xscale">1</property>
-		  <property name="yscale">1</property>
-		  <property name="top_padding">0</property>
-		  <property name="bottom_padding">0</property>
-		  <property name="left_padding">12</property>
-		  <property name="right_padding">0</property>
-
-		  <child>
-		    <widget class="GtkTable" id="table2">
-		      <property name="visible">True</property>
-		      <property name="n_rows">3</property>
-		      <property name="n_columns">2</property>
-		      <property name="homogeneous">False</property>
-		      <property name="row_spacing">6</property>
-		      <property name="column_spacing">12</property>
-
-		      <child>
-			<widget class="GtkHBox" id="hbox2">
-			  <property name="visible">True</property>
-			  <property name="homogeneous">False</property>
-			  <property name="spacing">0</property>
-
-			  <child>
-			    <widget class="GtkLabel" id="label3">
-			      <property name="visible">True</property>
-			      <property name="label" translatable="yes">&lt;i&gt;Easy&lt;/i&gt;</property>
-			      <property name="use_underline">False</property>
-			      <property name="use_markup">True</property>
-			      <property name="justify">GTK_JUSTIFY_LEFT</property>
-			      <property name="wrap">False</property>
-			      <property name="selectable">False</property>
-			      <property name="xalign">0.5</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xpad">0</property>
-			      <property name="ypad">0</property>
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			      <property name="width_chars">-1</property>
-			      <property name="single_line_mode">False</property>
-			      <property name="angle">0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">False</property>
-			      <property name="fill">False</property>
-			    </packing>
-			  </child>
-
-			  <child>
-			    <widget class="GtkLabel" id="label4">
-			      <property name="visible">True</property>
-			      <property name="label" translatable="yes">&lt;i&gt;Hard&lt;/i&gt;</property>
-			      <property name="use_underline">False</property>
-			      <property name="use_markup">True</property>
-			      <property name="justify">GTK_JUSTIFY_RIGHT</property>
-			      <property name="wrap">False</property>
-			      <property name="selectable">False</property>
-			      <property name="xalign">1</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xpad">0</property>
-			      <property name="ypad">0</property>
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			      <property name="width_chars">-1</property>
-			      <property name="single_line_mode">False</property>
-			      <property name="angle">0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">True</property>
-			      <property name="fill">True</property>
-			    </packing>
-			  </child>
-			</widget>
-			<packing>
-			  <property name="left_attach">1</property>
-			  <property name="right_attach">2</property>
-			  <property name="top_attach">0</property>
-			  <property name="bottom_attach">1</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkHScale" id="minimumScale">
-			  <property name="visible">True</property>
-			  <property name="can_focus">True</property>
-			  <property name="draw_value">False</property>
-			  <property name="value_pos">GTK_POS_TOP</property>
-			  <property name="digits">1</property>
-			  <property name="update_policy">GTK_UPDATE_CONTINUOUS</property>
-			  <property name="inverted">False</property>
-			  <property name="adjustment">0 0 0 0 0 0</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">1</property>
-			  <property name="right_attach">2</property>
-			  <property name="top_attach">1</property>
-			  <property name="bottom_attach">2</property>
-			  <property name="x_options">fill</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkHScale" id="maximumScale">
-			  <property name="visible">True</property>
-			  <property name="can_focus">True</property>
-			  <property name="draw_value">False</property>
-			  <property name="value_pos">GTK_POS_TOP</property>
-			  <property name="digits">1</property>
-			  <property name="update_policy">GTK_UPDATE_CONTINUOUS</property>
-			  <property name="inverted">False</property>
-			  <property name="adjustment">0 0 0 0 0 0</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">1</property>
-			  <property name="right_attach">2</property>
-			  <property name="top_attach">2</property>
-			  <property name="bottom_attach">3</property>
-			  <property name="x_options">fill</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkLabel" id="label9">
-			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">_Minimum Difficulty</property>
-			  <property name="use_underline">True</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			  <property name="mnemonic_widget">minimumScale</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">0</property>
-			  <property name="right_attach">1</property>
-			  <property name="top_attach">1</property>
-			  <property name="bottom_attach">2</property>
-			  <property name="x_options">fill</property>
-			  <property name="y_options"></property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkLabel" id="label10">
-			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">Ma_ximum Difficulty</property>
-			  <property name="use_underline">True</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			  <property name="mnemonic_widget">maximumScale</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">0</property>
-			  <property name="right_attach">1</property>
-			  <property name="top_attach">2</property>
-			  <property name="bottom_attach">3</property>
-			  <property name="x_options">fill</property>
-			  <property name="y_options"></property>
-			</packing>
-		      </child>
-		    </widget>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkExpander" id="expander1">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="expanded">False</property>
-		  <property name="spacing">0</property>
-
-		  <child>
-		    <widget class="GtkScrolledWindow" id="scrolledwindow1">
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		      <property name="shadow_type">GTK_SHADOW_IN</property>
-		      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
-		      <child>
-			<widget class="GtkTreeView" id="treeview1">
-			  <property name="visible">True</property>
-			  <property name="can_focus">True</property>
-			  <property name="headers_visible">True</property>
-			  <property name="rules_hint">False</property>
-			  <property name="reorderable">False</property>
-			  <property name="enable_search">True</property>
-			  <property name="fixed_height_mode">False</property>
-			  <property name="hover_selection">False</property>
-			  <property name="hover_expand">False</property>
-			</widget>
-		      </child>
-		    </widget>
-		  </child>
-
-		  <child>
-		    <widget class="GtkLabel" id="expander">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">_Game List</property>
-		      <property name="use_underline">True</property>
-		      <property name="use_markup">False</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0.5</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		    <packing>
-		      <property name="type">label_item</property>
-		    </packing>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">True</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkCheckButton" id="includeOldGamesToggle">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="label" translatable="yes">_Include games you've already played in list of games to print</property>
-		  <property name="use_underline">True</property>
-		  <property name="relief">GTK_RELIEF_NORMAL</property>
-		  <property name="focus_on_click">True</property>
-		  <property name="active">False</property>
-		  <property name="inconsistent">False</property>
-		  <property name="draw_indicator">True</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
+  <widget class="GtkDialog" id="dialog">
+    <property name="visible">True</property>
+    <property name="title" translatable="yes">Print Sudokus</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <child>
+          <widget class="GtkVBox" id="vbox1">
+            <property name="visible">True</property>
+            <property name="border_width">12</property>
+            <property name="spacing">6</property>
+            <child>
+              <widget class="GtkLabel" id="label1">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;span size="larger" weight="bold"&gt;Print Games&lt;/span&gt;</property>
+                <property name="use_markup">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkAlignment" id="alignment2">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="left_padding">24</property>
+                <child>
+                  <widget class="GtkTable" id="table1">
+                    <property name="visible">True</property>
+                    <property name="n_rows">2</property>
+                    <property name="n_columns">2</property>
+                    <child>
+                      <widget class="GtkLabel" id="label3">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">_Number of sudoku to print: </property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">sudokusToPrintSpinButton</property>
+                      </widget>
+                      <packing>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkLabel" id="label2">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">_Sudokus per page: </property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">sudokusPerPageSpinButton</property>
+                      </widget>
+                      <packing>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkSpinButton" id="sudokusToPrintSpinButton">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="adjustment">4 1 100 1 10 10</property>
+                        <property name="climb_rate">1</property>
+                      </widget>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkSpinButton" id="sudokusPerPageSpinButton">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="adjustment">1 1 9 1 10 10</property>
+                        <property name="climb_rate">1</property>
+                      </widget>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                  </widget>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label4">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;&lt;i&gt;Levels of difficulty to print&lt;/i&gt;&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+                <property name="use_underline">True</property>
+                <property name="wrap">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkAlignment" id="alignment1">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="left_padding">24</property>
+                <child>
+                  <widget class="GtkVBox" id="vbox2">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <child>
+                      <widget class="GtkCheckButton" id="easyCheckButton">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="label" translatable="yes">_Easy</property>
+                        <property name="use_underline">True</property>
+                        <property name="response_id">0</property>
+                        <property name="draw_indicator">True</property>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkCheckButton" id="mediumCheckButton">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="label" translatable="yes">_Medium</property>
+                        <property name="use_underline">True</property>
+                        <property name="response_id">0</property>
+                        <property name="draw_indicator">True</property>
+                      </widget>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkCheckButton" id="hardCheckButton">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="label" translatable="yes">_Hard</property>
+                        <property name="use_underline">True</property>
+                        <property name="response_id">0</property>
+                        <property name="draw_indicator">True</property>
+                      </widget>
+                      <packing>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkCheckButton" id="very_hardCheckButton">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="label" translatable="yes">_Very Hard</property>
+                        <property name="use_underline">True</property>
+                        <property name="response_id">0</property>
+                        <property name="draw_indicator">True</property>
+                      </widget>
+                      <packing>
+                        <property name="position">3</property>
+                      </packing>
+                    </child>
+                  </widget>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">3</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label6">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;&lt;i&gt;Details&lt;/i&gt;&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+                <property name="use_underline">True</property>
+                <property name="wrap">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">4</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkAlignment" id="alignment3">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="left_padding">24</property>
+                <child>
+                  <widget class="GtkVBox" id="vbox3">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <child>
+                      <widget class="GtkCheckButton" id="markAsPlayedToggle">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="label" translatable="yes">_Mark games as played once you've printed them.</property>
+                        <property name="use_underline">True</property>
+                        <property name="response_id">0</property>
+                        <property name="draw_indicator">True</property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkCheckButton" id="includeOldGamesToggle">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="label" translatable="yes">_Include games you've already played in list of games to print</property>
+                        <property name="use_underline">True</property>
+                        <property name="response_id">0</property>
+                        <property name="draw_indicator">True</property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">5</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="layout_style">GTK_BUTTONBOX_END</property>
+            <child>
+              <widget class="GtkButton" id="cancelbutton1">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="label">gtk-cancel</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">-6</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkButton" id="okbutton1">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="label">gtk-print</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">-5</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
 </glade-interface>
Index: gnome-sudoku/glade/select_game.glade
===================================================================
--- gnome-sudoku/glade/select_game.glade	(revision 0)
+++ gnome-sudoku/glade/select_game.glade	(revision 0)
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.0 on Mon Oct  8 13:48:34 2007 -->
+<glade-interface>
+  <widget class="GtkDialog" id="dialog1">
+    <property name="width_request">700</property>
+    <property name="height_request">500</property>
+    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+    <property name="border_width">5</property>
+    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+        <property name="spacing">2</property>
+        <child>
+          <widget class="GtkScrolledWindow" id="scrolledwindow1">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+            <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
+            <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+            <child>
+              <widget class="GtkViewport" id="viewport1">
+                <property name="visible">True</property>
+                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                <property name="border_width">12</property>
+                <property name="resize_mode">GTK_RESIZE_QUEUE</property>
+                <property name="shadow_type">GTK_SHADOW_NONE</property>
+                <child>
+                  <widget class="GtkVBox" id="vbox1">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <child>
+                      <widget class="GtkLabel" id="newGameLabel">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">&lt;b&gt;&lt;span size="large"&gt;_New Game&lt;/span&gt;&lt;/b&gt;</property>
+                        <property name="use_markup">True</property>
+                        <property name="use_underline">True</property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkIconView" id="newGameIconView">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="selection_mode">GTK_SELECTION_NONE</property>
+                      </widget>
+                      <packing>
+                        <property name="padding">12</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkLabel" id="savedGameLabel">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="xalign">0</property>
+                        <property name="yalign">0</property>
+                        <property name="label" translatable="yes">&lt;b&gt;&lt;span size="large"&gt;_Saved Games&lt;/span&gt;&lt;/b&gt;</property>
+                        <property name="use_markup">True</property>
+                        <property name="use_underline">True</property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="padding">12</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkIconView" id="savedGameIconView">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="selection_mode">GTK_SELECTION_NONE</property>
+                      </widget>
+                      <packing>
+                        <property name="position">3</property>
+                      </packing>
+                    </child>
+                  </widget>
+                </child>
+              </widget>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+            <property name="layout_style">GTK_BUTTONBOX_END</property>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+</glade-interface>
Index: gnome-sudoku/glade/Makefile.am
===================================================================
--- gnome-sudoku/glade/Makefile.am	(revision 6846)
+++ gnome-sudoku/glade/Makefile.am	(working copy)
@@ -1,11 +1,9 @@
 
 uidir = $(datadir)/gnome-sudoku
 ui_DATA = \
-	high_scores.glade	\
-	new_game.glade		\
-	open_game.glade		\
 	print_games.glade	\
 	puzzle_generator.glade	\
+	select_game.glade \
 	tracker.glade
 
 EXTRA_DIST = $(ui_DATA)
\ No newline at end of file
