diff --git a/HCube/Common.hs b/HCube/Common.hs
new file mode 100644
--- /dev/null
+++ b/HCube/Common.hs
@@ -0,0 +1,52 @@
+-----------------------------------------------------------------------------
+-- 
+-- Module      :  HCube.Common
+-- Copyright   :  (c) Todd Wegner 2013
+-- License     :  BSD-style (see the LICENSE file)
+-- 
+-- Maintainer  :  todd.w.wegner@gmail.com
+-- Stability   :  provisional
+-- Portability :  portable
+--
+-- Common utility functions that should not be exported. 
+-----------------------------------------------------------------------------
+module HCube.Common where
+
+import Control.Monad (liftM)
+import Data.List
+import HCube.Data
+
+getLine2	= liftM reverse $ f "" where
+    f rd	= getChar >>= g where
+        g '\n'	= return rd
+        g '\b'	= putStr " \b" >> if null rd then f "" else f $ tail rd
+	g ch	= f (ch:rd)
+
+-- Pretty prints two columns per screen.
+twoPagesOnOne		:: String -> [String] -> [String]
+twoPagesOnOne sp tx	= f $ splitAt (length tx `div` 2) tx where
+    f (l1, l2)		= g l1 l2
+    g (x:xs) (y:ys)	= concat [x, sp, y] : g xs ys
+    g [] []		= []
+    g xs []		= xs
+    g [] xs		= xs
+
+-- Pretty prints four columns per screen.
+fourPagesOnOne		:: String -> [String] -> [String]
+fourPagesOnOne sp 	= twoPagesOnOne sp . twoPagesOnOne sp
+
+-- Pads spaces on the right.
+padR				:: Int -> String -> String
+padR ln chs			= chs ++ (replicate f ' ') where
+    f				= ln - length chs 
+
+-- Pads spaces on the left.
+padL				:: Int -> String -> String
+padL ln chs			= (replicate f ' ') ++ chs where
+    f				= ln - length chs 
+
+prShow			:: Show a => Int -> a -> String
+prShow nm		= padR nm . show
+
+plShow			:: Show a => Int -> a -> String
+plShow nm		= padL nm . show
diff --git a/HCube/Cons.hs b/HCube/Cons.hs
new file mode 100644
--- /dev/null
+++ b/HCube/Cons.hs
@@ -0,0 +1,89 @@
+-----------------------------------------------------------------------------
+-- | 
+-- Module      :  HCube.Cons
+-- Copyright   :  (c) Todd Wegner 2013
+-- License     :  BSD-style (see the LICENSE file)
+-- 
+-- Maintainer  :  todd.w.wegner@gmail.com
+-- Stability   :  provisional
+-- Portability :  portable
+-- 
+-- Provides functions for re-constructing internal data representation
+-- of virtual cube from a physical cube.
+-----------------------------------------------------------------------------
+module HCube.Cons (realToVirtual, consOrient) where
+
+import Data.Monoid
+import Data.Maybe (mapMaybe)
+import Data.List (sort, mapAccumL)
+import HCube.Data
+import HCube.Utility
+import HCube.Lib
+import HCube.OrientGroup
+
+-- | Constructs a virtual cube from a physical cube using CubeSurf.
+realToVirtual		:: Size -> CubeSurf -> Rubik
+realToVirtual sz ci	= f $ foldr g ([],[],[],[]) $ consCubeInfo sz ci where
+    f (cr, ed, ce, hi)	= Rubik sz cr ed ce hi True LeftV []
+    g (ci, ac, ct) (cr,ed,ce,hi) = h $ length ct where
+	h 0	= (cr,ed,ce,i ci ac :hi)
+	h 1 	= (cr,ed,i ci ac :ce,hi)
+	h 2 	= (cr,i ci ac :ed,ce,hi)
+	h 3 	= (i ci ac :cr,ed,ce,hi)
+	i id ac	= Cube (getPos sz id) (k ac) (j ct)
+    j 			= m . colorTagToCubeId sz
+    k			= l . extractOrientInfo
+    l []		= mempty
+    l (hd:[])		= mempty
+    l (v1:v2:_)		= consOrient v1 v2
+    m []		= 0
+    m ls		= head ls
+
+extractOrientInfo	:: ActualCube -> [(Side,Color)]
+extractOrientInfo ac	= mapMaybe f [(UpS, up ac), (FrontS, front ac), (DownS, down ac),
+			            (BackS, back ac), (LeftS, left ac), (RightS, right ac)] where
+    f sc@(sd,cl)	| cl /= NoColor = Just sc
+			| otherwise	 = Nothing
+
+colorTagToCubeId	:: Int -> ColorTag -> [Int]
+colorTagToCubeId n ct	= mapMaybe f $ consCubeInfo n (solvedSurf n) where
+    f (a,b,c) | ct == c   = Just a
+	      | otherwise = Nothing
+
+-- | Constructs the orientaion of a cubie from the color of two of its faces.
+consOrient		:: (Side,Color) -> (Side,Color) -> Orient
+consOrient (sd1, cl1) (sd2, cl2) 
+			= orientFromVecs (g cl1, f sd1) (g cl2, f sd2) where 
+    f			= sideToVec
+    g			= f . colorToSide
+
+orientFromVecs		:: (Vec,Vec) -> (Vec,Vec) -> Orient
+orientFromVecs v1 v2	= Orient [f RightS, f BackS] where 
+    f 			= (g |*| ) . sideToVec
+    g 			= vecsToTran v1 v2
+
+orientFromSides		:: (Side,Side) -> (Side,Side) -> Orient
+orientFromSides (sf1, st1) (sf2, st2) 
+			= orientFromVecs (f sf1, f st1) (f sf2, f st2) where 
+    f			= sideToVec
+
+
+vecsToTran		:: (Vec,Vec) -> (Vec,Vec) -> Matrix
+vecsToTran v1 v2	= missingVec (f v1) (f v2) where
+	f (t1,t2)	= vecToMxElem t1 t2
+
+vecToMxElem		:: Vec -> Vec -> (Int,Vec)
+vecToMxElem v1 v2	= (vpos v1, multVec (vcomp v1) v2) where
+
+missingVec		:: (Int,Vec) -> (Int,Vec) -> Matrix
+missingVec (cl1,v1) (cl2,v2) = f $ g (cl1,cl2) where
+    f fu		= h (fu i) (fu $ minus i)
+    g (1,2)		= \s-> Matrix v1 v2 s 
+    g (2,1)		= \s-> Matrix v2 v1 s
+    g (1,3)		= \s-> Matrix v1 s v2
+    g (3,1)		= \s-> Matrix v2 s v1
+    g (2,3)		= \s-> Matrix s v1 v2
+    g (3,2)		= \s-> Matrix s v2 v1
+    g _			= \_-> Matrix (0,0,0) (0,0,0) (0,0,0)
+    h m1 m2		= if det m1 == 1 then m1 else m2
+    i			= cross v1 v2
diff --git a/HCube/Cube.hs b/HCube/Cube.hs
new file mode 100644
--- /dev/null
+++ b/HCube/Cube.hs
@@ -0,0 +1,159 @@
+-----------------------------------------------------------------------------
+-- | 
+-- Module      :  HCube.Cube
+-- Copyright   :  (c) Todd Wegner 2013
+-- License     :  BSD-style (see the LICENSE file)
+-- 
+-- Maintainer  :  todd.w.wegner@gmail.com
+-- Stability   :  provisional
+-- Portability :  portable
+-- 
+-- Executable of hcube. 
+-----------------------------------------------------------------------------
+module Main where
+
+import System.Environment (getArgs)
+import Control.Monad (foldM, (>=>))
+import Data.Maybe (fromMaybe)
+import HCube.Data
+import HCube.Lib
+import HCube.Utility
+import HCube.Cons
+import HCube.Test (runTests)
+import HCube.Theory
+import HCube.Template (render)
+import HCube.OrientGroup
+import HCube.Permutation
+
+{-
+ghci Cube.hs
+:set args 2
+-}
+
+main			:: IO ()
+main			= getArgs >>= f where
+    f args		= runTests
+			  >> putStrLn "enter 'help' for menu"
+			  >> loadCube g h
+			  >>= render
+			  >>= console
+			  >>= saveCube h
+			  >> return () where
+        g		= getCubeSize args
+	h		= show g ++ "x" ++ show g
+
+main2			:: IO ()
+main2			= getArgs >>= f where
+    f args		= runTests
+			  >> putStrLn "enter 'help' for menu"
+			  >> return ( realToVirtual 3 myCube)
+			  >>= render
+			  >>= console
+			  >> return () where
+        g		= getCubeSize args
+	h		= show g ++ "x" ++ show g
+
+getCubeSize		:: [String] -> Int 
+getCubeSize 		= f where
+    f []		= 3
+    f args		= fromMaybe 3 $ maybeRead $ head args 
+
+console			:: Rubik -> IO Rubik
+console			= doM loop f where
+   f			= (getLine >>= parseCmd ~> processCmd) >=> render 
+
+processCmd		:: Command -> Rubik -> IO Rubik
+processCmd cm rk	= f cm where
+    f (Projection pj)   = return $ rk { view = pj }
+    f Quit		= return $ rk { loop = False }
+    f (Operation ops)	= appendHis ops rk >>= return . doCubeOps ops
+    f Undo		= undo rk
+    f Help		= putStrLn help >> return rk
+    f NoCommand		= return rk
+
+appendHis		:: [Rotation] -> Rubik -> IO Rubik
+appendHis ops rk	= return $ rk { his = ops ++ (his rk) }
+
+removeLastHis		:: Rubik -> IO Rubik
+removeLastHis rk	= return $ rk { his = tail (his rk) }
+
+undo			:: Rubik -> IO Rubik
+undo rk			= f (his rk) where
+    f []		= return rk
+    f hs		= return ( doCubeOps [invOpp $ head hs] rk )
+			>>= removeLastHis
+
+help			= unlines 
+       ["l1+    rotate layer 1 clockwise",
+	"l2-    rotate layer 2 counter",
+	"h3+    rotate horizontal slab 3 clockwise",
+	"h1-    rotate horizontal slab 1 counter",
+	"v2+    rotate vertical slab 2 clockwise",
+	"v3-    rotate vertical slab 3 counter",
+	"l      left side view",
+	"r      right side view",
+	"r+     rotate whole cube clockwise 90 degrees (z axis)",
+	"r-     rotate whole cube counter clockwise 90 degrees (z axis)",
+	"r2     rotate whole cube 180 degrees",
+	"fh     flip whole cube over along horizontal axis",
+	"fv     flip whole cube over along vertical axis",
+	"u      undo last cube operation",
+	"q      quit"]
+
+parseCmd		:: String -> IO Command
+parseCmd 		= return . f where
+    f "l"		= Projection LeftV
+    f "r"		= Projection RightV
+    f "q"		= Quit
+    f "r+"		= Operation [RotateCube Layer Clockwise]
+    f "r-"		= Operation [RotateCube Layer Counter]
+    f "r2"		= Operation [RotateCube Layer Twice]
+    f "fh"		= Operation [RotateCube HSlice Twice]
+    f "fv"		= Operation [RotateCube VSlice Twice]
+    f "help"		= Help
+    f (a:b:c:[])	= verifyOp (g a) (h c) (i b)
+    f "u"		= Undo
+    f _			= NoCommand
+    g 'l'		= Layer
+    g 'h'		= HSlice
+    g 'v'		= VSlice
+    g _			= NoSlab
+    h '+'		= Clockwise
+    h '-'		= Counter
+    h '2'		= Twice
+    h _			= NoDir
+    i ch		= fromMaybe 0 $ maybeRead [ch]
+
+verifyOp		:: Slab -> Direction -> Numb -> Command 
+verifyOp 		= f where
+    f NoSlab _ _	= NoCommand
+    f _ NoDir _		= NoCommand
+    f _ _ 0		= NoCommand
+    f sl dr nm		= Operation [Rotation sl dr nm]
+
+-- On a face record cube color from left to right moving from top to bottom.
+-- Start with Top face
+-- Rotate cube so Front face comes to Top
+-- Top -> Front -> Bottom -> Back -> Top -> Left -> Top -> Right
+
+{-
+FACE IDs
+               1  2  
+               3  4  
+         1  2  1  2  1  2  
+         3  4  3  4  3  4  
+               1  2  
+               3  4  
+         4  3  1  2  4  3  
+         2  1  3  4  2  1  
+               1  2  
+               3  4   
+-}
+
+myCube	:: CubeSurf
+myCube = [(UpS,	[White,Green,Yellow,Green,White,Green,Red,White,Green]),
+	  (FrontS, 	[Blue,Blue,White,Yellow,Orange,Yellow,Red,Yellow,White]),
+	  (DownS,	[Yellow,Blue,Green,White,Yellow,Blue,White,Orange,Green]),
+	  (BackS,	[Orange,Blue,Orange,Yellow,Red,Red,Red,Orange,Blue]),
+	  (LeftS,	[Orange,White,Yellow,Red,Green,Red,Orange,Red,Red]),
+	  (RightS,	[Blue,Green,Blue,Orange,Blue,White,Green,Orange,Yellow])]
diff --git a/HCube/Data.hs b/HCube/Data.hs
new file mode 100644
--- /dev/null
+++ b/HCube/Data.hs
@@ -0,0 +1,138 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  HCube.Data
+-- Copyright   :  (c) Todd Wegner 2013
+-- License     :  BSD-style (see the LICENSE file)
+-- 
+-- Maintainer  :  todd.w.wegner@gmail.com
+-- Stability   :  provisional
+-- Portability :  portable
+-- 
+-----------------------------------------------------------------------------
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module HCube.Data where
+
+newtype TestNumb	= TestNumb Int deriving (Integral, Enum, Num, Real, Eq, Ord, Read, Show)
+
+-- | Integer type used in hcube.
+type Numb		= Int
+
+-- | Physical size of cube.  For example a value of 3 refers to original 3x3x3 Rubik's cube.
+type Size		= Numb
+
+-- | Point is used in transformations of cubies in a two dimensional plane.
+type Point		= (Numb, Numb)
+
+-- | Vector which orientation group matrices act on.
+-- Also used for calculating new cubie positions.
+type Vec		= (Numb, Numb, Numb)
+
+type Format		= String
+
+-- | String with each character representing a color of a physical cubie.
+type ColorTag		= String
+type Projection		= [(Numb,Side)]
+
+-- | Type used to specify state of physical cube.
+type CubeSurf		= [(Side,[Color])]
+
+-- | Matrices in hcube are constructed from column vectors.
+-- The third vector is often chosen as the cross product of the first two
+-- such that the determinate of the matrix is one.
+data Matrix		= Matrix Vec Vec Vec deriving Show
+
+-- | Used for simplistic processing of console commands.
+data Command = Projection View |
+	       Operation [Rotation] |
+	       Undo |
+	       Help |
+	       Quit |
+	       NoCommand
+
+-- | Left and right 3D view of cube.
+data View    = LeftV |
+	       RightV deriving (Show, Read, Eq)
+
+-- | Used by Template to map logical structure of cube to display views.
+data ViewAssociation	= Sur (Numb,Side) |
+			  Ide Numb |
+			  Ori Numb
+
+-- | Defines a rotation of an arbitrary cube slice.
+data Rotation		= Rotation Slab Direction Numb |
+			  RotateCube Slab Direction
+			  deriving (Show, Read,Eq)
+
+
+-- | Defines direction of slab movement.
+data Direction 		= Clockwise | Counter | Twice | NoDir deriving (Show, Read,Eq)
+
+-- | Defines an axis for slab movement.
+data Slab		= Layer | HSlice | VSlice | NoSlab deriving (Show, Read, Eq)
+
+-- | Sides of a cube.
+data Side		= UpS | DownS | FrontS | BackS | LeftS | RightS | NoSide
+			  deriving (Show, Read, Eq, Ord)
+
+-- | Represents the color of a cubie face.
+data Color		= White | Yellow | Orange | Red | Blue | Green | NoColor
+			  deriving (Read, Eq)
+
+instance Show Color where
+    show White		= whiteC
+    show Yellow		= yellowC
+    show Orange		= orangeC
+    show Red		= redC
+    show Blue		= blueC
+    show Green		= greenC
+    show NoColor	= ""
+
+data ActualCube		= ActualCube {
+			up :: Color,
+			front :: Color,
+			down :: Color,
+			back :: Color,
+			left :: Color,
+			right :: Color
+			} deriving (Show, Read, Eq)
+
+-- | Represents the color white. Modify if the physical cube uses a different coloring scheme
+whiteC			= "W"
+yellowC			= "Y"
+orangeC			= "O"
+redC			= "R"
+blueC			= "B"
+greenC			= "G"
+noC			= "-"
+
+-- trivial functions
+-- | Gives inverse of a cube operation.
+invOpp				:: Rotation -> Rotation
+invOpp (Rotation sb dir nm) 	= Rotation sb (invDir dir) nm
+invOpp (RotateCube sb dir)	= RotateCube sb (invDir dir)
+
+-- | Reverses direction of rotation.
+invDir			:: Direction -> Direction
+invDir Clockwise	= Counter
+invDir Counter		= Clockwise
+invDir Twice		= Twice
+
+-- | Associates a side of a solved cube to a color.
+sideToColor		:: Side -> Color
+sideToColor UpS		= White
+sideToColor DownS	= Yellow
+sideToColor FrontS	= Orange
+sideToColor BackS	= Red
+sideToColor LeftS	= Green
+sideToColor RightS	= Blue
+sideToColor NoSide	= NoColor
+
+-- | Inverse of sideToColor
+colorToSide		:: Color -> Side
+colorToSide White	= UpS	
+colorToSide Yellow	= DownS		
+colorToSide Orange	= FrontS		
+colorToSide Red		= BackS		
+colorToSide Blue	= RightS		
+colorToSide Green	= LeftS
+colorToSide NoColor	= NoSide
diff --git a/HCube/Lib.hs b/HCube/Lib.hs
new file mode 100644
--- /dev/null
+++ b/HCube/Lib.hs
@@ -0,0 +1,256 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  HCube.Lib
+-- Copyright   :  (c) Todd Wegner 2013
+-- License     :  BSD-style (see the LICENSE file)
+-- 
+-- Maintainer  :  todd.w.wegner@gmail.com
+-- Stability   :  provisional
+-- Portability :  portable
+--
+-- Exposes virtual cube functionality.
+-----------------------------------------------------------------------------
+module HCube.Lib (Rubik(..), 
+		Cube(..),
+		posToId,
+		getPos,
+		consCubeInfo,
+		solvedSurf,
+		cubeIdsOfFace,
+		cubeTypes,
+		initCube,
+		getFaceColor,
+		getCubeFromPos,
+		doCubeOps,
+		loadCube,
+		saveCube) where
+
+import Data.Monoid
+import Control.Monad (foldM)
+import Data.List (find, sort, foldl)
+import Data.Maybe (fromJust, mapMaybe)
+import Data.Char (ord, chr)
+import System.Directory (doesFileExist)
+import HCube.Data
+import HCube.Utility
+import HCube.OrientGroup
+
+-- |Vitrual Rubik's cube.
+data Rubik		= Rubik {
+			n   :: Size,
+			crn :: [Cube],
+			edg :: [Cube],
+			cnt :: [Cube],
+			hid :: [Cube],
+			loop :: Bool,
+			view :: View,
+			his :: [Rotation]
+			} deriving (Show, Read, Eq)
+
+-- |Individual cube of Rubik's cube, known as a Cubie.
+data Cube		= Cube {
+			pos :: Vec,
+			ori :: Orient,
+			cid :: Numb
+			} deriving (Show, Read, Eq)
+
+-- |Loads cube from a file.
+loadCube		:: Size -> FilePath -> IO Rubik
+loadCube sz fp		= doesFileExist fp >>= f where
+		f True  = fromFile fp
+		f False	= return g <* saveCube fp g
+		g 	= initCube sz
+
+-- |Saves cube to a file.
+saveCube		:: FilePath -> Rubik -> IO ()
+saveCube fn rb 		= writeFile fn (show $ rb {loop = True})
+
+-- |Performs a cube operation on virtual cube.
+-- Conceptually this corresponds to multiplying the cube state by an appropriate element of the permutation group.
+-- However a vector approach is used here. 
+doCubeOps			:: [Rotation] -> Rubik -> Rubik
+doCubeOps ops rk		= foldl f rk ops where
+    f rk2 (RotateCube sb dr) 	= doCubeOps g rk2 where
+	g			= map (Rotation sb dr) [1 .. i]
+    f rk3 rt 			= rk3 { crn = h crn,
+					edg = h edg,
+					cnt = h cnt,
+					hid = h hid
+						 }  where
+        h fn			= twist i rt (fn rk3)
+    i				= n rk
+
+twist			:: Size -> Rotation -> [Cube] -> [Cube] 
+twist sz rt@(Rotation sb dir nm) = map f where
+	f cb 		= g $ nm == getAxis sb (pos cb) where
+	    g False	= cb
+	    g True	= moveCube sz rt cb
+
+getCube			:: [Cube] -> Vec -> Maybe Cube
+getCube cbs ps		= f where
+	f		= find g cbs
+	g cb		= ps == pos cb
+
+-- | Color of cube id on a face is returned.
+-- This function is important for rendering.
+getFaceColor		:: Rubik -> (Numb,Side) -> String	
+getFaceColor rk (pos, sd) = f (getCubeFromPos rk pos) sd where
+    f cb		= show . sideToColor . getFaceOrientation cb
+
+-- | Returns the cubie at a given position.
+getCubeFromPos		:: Rubik -> Numb -> Cube	
+getCubeFromPos rk pos	= fromJust $ getCube cs (getPos sz pos) where
+    sz			= n rk
+    cs			= concat [crn rk, edg rk, cnt rk, hid rk] 
+
+-- transformations
+rotate			:: Size -> Rotation -> (Point -> Point)
+rotate sz rt (x,y)	= f rt where
+    f (Rotation dr _  _) 			
+			= g $ humanDir sz rt where
+    g Clockwise		= (y, sz - x + 1)
+    g Counter		= (sz - y + 1, x)
+    g Twice		= (sz - x + 1, sz -y + 1)
+
+humanDir		:: Size -> Rotation -> Direction
+humanDir sz		= f where
+    f (Rotation _ dr _)	= dr
+{-
+    f (Rotation Layer Clockwise _)	= Counter
+    f (Rotation Layer Counter _)	= Clockwise
+    f (Rotation Layer Twice _)		= Twice
+    f (Rotation HSlice Clockwise _)	= Clockwise
+    f (Rotation HSlice Counter _)	= Counter
+    f (Rotation HSlice Twice _)		= Twice
+    f (Rotation VSlice Clockwise _) 	= Clockwise
+    f (Rotation VSlice Counter _)	= Counter
+    f (Rotation VSlice Twice _)		= Twice
+-}
+
+getTwistOrient		:: Rotation -> Orient
+getTwistOrient  	= cons . f where
+    f (Rotation Layer Clockwise _)	= 'f'
+    f (Rotation Layer Counter _)	= 'l'
+    f (Rotation Layer Twice _)		= 't'
+    f (Rotation HSlice Clockwise _)	= 'r'
+    f (Rotation HSlice Counter _)	= 'g'
+    f (Rotation HSlice Twice _)		= 'k'
+    f (Rotation VSlice Clockwise _) 	= 'o'
+    f (Rotation VSlice Counter _)	= 'd'
+    f (Rotation VSlice Twice _)		= 'e'
+
+orient			:: Rotation -> Orient -> Orient
+orient	rt or		= f rt where
+    f (Rotation sb dr _)
+			= Orient $ map (g |*|) (getVec $ mempty) where 
+	g		= h |**| to or
+	h	 	= to $ getTwistOrient rt
+
+-- imlementation
+
+-- | Creates a virtual cube in solved state
+initCube 		:: Size -> Rubik
+initCube sz		= f $ cubeTypes sz where
+    f (cr,ed,ce,hi) 	= Rubik { n = sz, 
+				  crn = map g cr,
+				  edg = map g ed,
+				  cnt = map g ce,
+				  hid = map g hi,
+				  loop = True,
+				  view = LeftV,
+				  his = []}
+    g id		= Cube (getPos sz id) mempty id
+
+moveCube		:: Size -> Rotation -> Cube -> Cube
+moveCube sz rt cb	= f rt where
+	f (Rotation sb dr _) 
+			= cb { pos = apply (rotate sz rt) sb (pos cb), 
+		 	       ori = orient rt (ori cb) }
+
+apply			:: (Point -> Point) -> Slab -> Vec -> Vec
+apply fn sb (a,b,c)	= f sb where
+	f VSlice	= (a, g (b,c), h (b,c))
+	f HSlice	= (g (a,c), b, h (a,c))
+	f Layer		= (g (a,b), h (a,b), c)
+	g		= fst . fn
+	h		= snd . fn
+
+getFaceOrientation	:: Cube -> Side -> Side
+getFaceOrientation cb	= transform (ori cb) 
+
+transform		:: Orient -> Side -> Side
+transform or sd		= vecToSide $ (inverse $ to or) |*| (sideToVec sd)
+
+getAxis			:: Slab -> Vec -> Numb
+getAxis	Layer (_,_,ps)	= ps
+getAxis HSlice (_,ps,_)	= ps
+getAxis VSlice (ps,_,_)	= ps
+
+-- | Generates a tuple of cube ids corresponding to (corners, edges, centers, hidden cubies).
+cubeTypes		:: Size -> ([Int],[Int],[Int],[Int])
+cubeTypes n 		= foldr f ([],[],[],[]) $ consCubeInfo n (solvedSurf n) where
+    f (id, _, chs) (cr,ed,ce,hi) = g $ length chs where
+	g 0		 = (cr,ed,ce,id:hi)
+	g 1		 = (cr,ed,id:ce,hi)
+	g 2		 = (cr,id:ed,ce,hi)
+	g 3		 = (id:cr,ed,ce,hi)
+
+nullActCube		:: Int -> [(Int,ActualCube,ColorTag)]
+nullActCube n		= zip3 [1..] f g where
+    f			= replicate h (ActualCube NoColor NoColor NoColor NoColor NoColor NoColor)
+    g			= replicate h []
+    h			= n*n*n
+
+-- | CubeSurf representing a solved cube.
+solvedSurf		:: Int -> CubeSurf
+solvedSurf n		= map f [UpS,FrontS,DownS,BackS,LeftS,RightS] where
+    f sd		= (sd, replicate (n*n) (sideToColor sd)) 
+
+-- | Converts from a surface view of cube to a cubie view of cube. 
+consCubeInfo		:: Int -> CubeSurf -> [(Int, ActualCube, ColorTag)] 
+consCubeInfo n		= foldl f (nullActCube n) where
+    f acs (sd, cls)	= foldl g acs $ zip (cubeIdsOfFace n sd) cls where
+	g acs (pi,cl) 	= map h acs where
+	    h tu@(ci,ac,ct)
+		| ci == pi  = (ci, i sd ac cl, sort $ (head $ show cl) : ct)
+		| otherwise = tu 
+    i UpS ac cl    = ac {up = cl}
+    i FrontS ac cl = ac {front = cl}
+    i DownS ac cl  = ac {down = cl}
+    i BackS ac cl  = ac {back = cl}
+    i LeftS ac cl  = ac {left = cl}
+    i RightS ac cl = ac {right = cl} 
+
+-- | Maps a face id defined with respect to a side, to the cube id.
+cubeIdsOfFace	:: Int -> Side -> [Int]
+cubeIdsOfFace n = f where
+    f UpS	= [1 .. l]
+    f FrontS	= concat [[g x .. g x + n -1] | x <-[1..n]]
+    f DownS	= h (\s -> (n-1)*l + (s-1)*n + 1)
+    f BackS	= h j
+    f RightS	= i (\s -> reverse [ (s-1)*n + j y | y <- [1..n]])
+    f LeftS 	= i (\s -> [(s-1)*n + k y | y <- [1..n]] )
+    g ix	= ix*l - n + 1
+    h fu 	= reverse $ concat [ reverse [fu x .. fu x + n - 1] | x <- [1..n] ]
+    i fu	= concat [fu x | x <- [1..n]]
+    j ix	= (ix-1)*l + 1
+    k ix	= (ix-1)*l + n
+    l		= n*n
+
+-- | Converts a pseudo-vector representation to a cube id.
+posToId			:: Size -> Vec -> Numb
+posToId	n (a,b,c)	= a + n*(b-1) + n*n*(c-1) 
+
+-- | Converts a cube id to a pseudo-vector representation.
+getPos			:: Size -> Numb -> Vec
+getPos n id		= head [(a,b,c) | c <- [1..n],
+					  b <- [1..n],
+					  a <- [1..n],
+					  posToId n (a,b,c) == id]
+-- serialization 
+
+fromFile		:: FilePath -> IO Rubik
+fromFile fn		= readFile fn >>= return . read
+
+
+
diff --git a/HCube/OrientGroup.hs b/HCube/OrientGroup.hs
new file mode 100644
--- /dev/null
+++ b/HCube/OrientGroup.hs
@@ -0,0 +1,163 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  HCube.OrientGroup
+-- Copyright   :  (c) Todd Wegner 2013
+-- License     :  BSD-style (see the LICENSE file)
+-- 
+-- Maintainer  :  todd.w.wegner@gmail.com
+-- Stability   :  provisional
+-- Portability :  portable
+--
+-- Orientation group is used to represent orientation of cubies, and cube as a
+-- whole. 
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE MultiParamTypeClasses, FlexibleContexts #-}
+
+module HCube.OrientGroup (
+	Group(..), 
+	Orient(..),
+	cons,
+	to,
+	eid,
+	getVec,
+	vecToSide,
+	sideToVec,
+	rawToOrientNumber,
+	orientNumberToRaw,
+	rawOrientNum,
+	spanDomain,
+	vecToColor,
+	colorToVec,
+	orientChrDomain,
+) where
+
+import Data.Monoid
+import Data.List (find,sort)
+import Data.Char (ord, chr)
+import HCube.Data
+import HCube.Utility
+
+-- | List of names for elements of the orientation group.
+orientChrDomain		= ['a'..'x']
+
+-- | Two vector representation of orientation.
+getVec			:: Orient -> [Vec]
+getVec (Orient vs)	= vs
+
+-- | Logical extension of Monoid to a group.
+class Monoid a => Group a where
+    inv			:: a -> a
+
+-- | Representation of Cubie orientation.
+data Orient = Orient [Vec] deriving (Show, Read, Eq)
+
+{-
+instance Show Orient where
+    show (Orient or)	= show or
+
+instance Read Orient where
+    readsPrec _ 	= \s -> [(Orient . rd $ s, s)] 
+-}
+
+instance Monoid Orient  where
+    mempty 		= Orient [(1,0,0),(0,1,0)] 
+    mappend lhs rhs 	= from $ (to lhs |**| to rhs)
+
+instance Group Orient where
+    inv 		= from . inverse . to
+
+-- | Maps an element of the orientation group to a matrix.
+-- Orient tranformation matrix is determined by specifing, (1,0,0) goes to v1 and (0,1,0) goes to v2.
+to			:: Orient -> Matrix
+to ori			= mapVec f (getVec ori) where
+	f v1 v2		= Matrix v1 v2 g where
+	    g		= multVec (vecDet v1 v2 h) h 
+	    h		= cross v1 v2
+
+-- | Maps a matrix representation of an element of the orientation group to
+-- | a two vector representation.
+from			:: Matrix -> Orient
+from mx			= Orient $ map (mx |*|) (getVec $ mempty)
+
+-- | Gives the name of an element of the orientation group.
+eid			:: Orient -> Char
+eid 			= f . rawToOrientNumber . rawOrientNum where
+    f 0			= '-'
+    f nm		= chr $ nm - 1 + ord 'a'
+
+-- | Constructs an element of the orientation group from the name.
+cons			:: Char -> Orient
+cons 			= Orient . f . orientNumberToRaw . g where
+    f cd		= [i . j $ (h 2, h 3, h 5), j (h 7, h 11,h 13)] where
+	    h		= modNot cd
+	    i		= gateMinus cd
+	    j		= modMinus cd 17
+    g ch		= ord ch + 1 - ord 'a' 
+
+-- | Inverse of sideToVec.
+vecToSide		:: Vec -> Side
+vecToSide (1,0,0)	= RightS
+vecToSide (-1,0,0)   	= LeftS
+vecToSide (0,1,0)	= BackS
+vecToSide (0,-1,0)	= FrontS
+vecToSide (0,0,1)	= UpS
+vecToSide (0,0,-1)	= DownS
+vecToSide (0,0,0)	= NoSide
+
+-- | Associates a side to a vector.
+sideToVec		:: Side -> Vec
+sideToVec RightS	= (1,0,0)
+sideToVec LeftS		= (-1,0,0)
+sideToVec BackS		= (0,1,0)
+sideToVec FrontS	= (0,-1,0)
+sideToVec UpS		= (0,0,1)
+sideToVec DownS		= (0,0,-1)
+sideToVec NoSide	= (0,0,0)
+
+-- | Gives the color of the side identified by the vector, in a solved state.
+colorToVec		:: Color -> Vec
+colorToVec		= sideToVec . colorToSide 
+
+-- | Inverse of colorToVec.
+vecToColor		:: Vec -> Color
+vecToColor		= sideToColor . vecToSide
+
+-- | Raw number is an intermediate step in associating two vectors
+-- to an orientation. The orientation number 1 corresponds to an orientation of ''a'' and so on.
+rawToOrientNumber	:: Numb -> Numb
+rawToOrientNumber nm	= maybe 0 fst f where
+	f		= find (g nm) orientMap
+	g nm el		= nm == snd el
+
+-- | Inverse of rawToOrientNumber
+orientNumberToRaw	:: Numb -> Numb
+orientNumberToRaw nm	= maybe 0 snd f where 
+	f		= find (g nm) orientMap
+	g nm el		= nm == fst el 
+
+-- | Maps a function of orientation over orient domain.
+spanDomain 		:: (Enum a, Num a, Ord b) => (Orient -> b) -> [(a, b)]
+spanDomain fn		= zip [1..] $ sort $ f where
+	f		= [fn (Orient [a, b]) | a <- vecs, b <- vecs, a /=b, a /= minus b]
+
+{-
+[(1,-935),(2,-663),(3,-595),(4,-442),(5,-374),(6,-357),
+ (7,-55),(8,-39),(9,-35),(10,-26),(11,-22),(12,-21),
+(13,21),(14,22),(15,26),(16,35),(17,39),(18,55),
+(19,357),(20,374),(21,442),(22,595),(23,663),(24,935)] -}
+orientMap		:: [(Numb,Numb)]
+orientMap		= spanDomain rawOrientNum
+
+-- | Converts the orientation to the raw orientation number.
+rawOrientNum		:: Orient -> Numb
+rawOrientNum or		= mapVec f (getVec or) where
+    f v1 v2		=  (dot v1 (2,3,5)) 
+                           * (signDiscrim 17 $ dot v2 (7,11,13))
+
+signDiscrim		:: Numb -> Numb -> Numb
+signDiscrim sc	si
+	| si < 0	= sc * si			
+	| otherwise	= si
+
+
diff --git a/HCube/Permutation.hs b/HCube/Permutation.hs
new file mode 100644
--- /dev/null
+++ b/HCube/Permutation.hs
@@ -0,0 +1,40 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  HCube.Permutation
+-- Copyright   :  (c) Todd Wegner 2013
+-- License     :  BSD-style (see the LICENSE file)
+-- 
+-- Maintainer  :  todd.w.wegner@gmail.com
+-- Stability   :  provisional
+-- Portability :  portable
+-- 
+-- Generation of permutation representation of cube.
+-----------------------------------------------------------------------------
+module HCube.Permutation (genPerm) where
+
+import Math.Algebra.Group.PermutationGroup (Permutation, fromPairs')
+import HCube.Lib
+import HCube.Data
+
+-- | Map a cube operation to an element of the permutation group.
+genPerm 		:: Size -> (Rubik -> [Cube]) -> Rotation -> Permutation Numb
+genPerm sz fn rt	= fromPairs' . g $ doCubeOps [rt] f  where
+    f			= initCube sz
+    g rb		= map h $ fn rb
+    h (Cube ps or ci)	= (ci, posToId sz ps)
+
+-- [crn, edg, cnt, hid]
+{-	
+all = map f  [crn, edg, cnt, hid] where
+    f fu = genPerm 3 fu (Rotation Layer Clockwise 3)
+
+
+l = genPerm 3 edg (Rotation Layer Clockwise 3)
+ll = genPerm2 3 edg (Rotation Layer Clockwise 3)
+lll = toPairs l
+
+m = genPerm 3 edg (Rotation HSlice Clockwise 3)
+
+n = supp m
+-}
+
diff --git a/HCube/Template.hs b/HCube/Template.hs
new file mode 100644
--- /dev/null
+++ b/HCube/Template.hs
@@ -0,0 +1,490 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  HCube.Template
+-- Copyright   :  (c) Todd Wegner 2013
+-- License     :  BSD-style (see the LICENSE file)
+-- 
+-- Maintainer  :  todd.w.wegner@gmail.com
+-- Stability   :  provisional
+-- Portability :  portable
+-- 
+-- Console visualization of virtual cube.
+-----------------------------------------------------------------------------
+module HCube.Template (render) where
+
+import Data.Text (Text, pack, unpack, replace, splitOn)
+import Data.List (unlines)
+import HCube.Data
+import HCube.Lib (Rubik(..), Cube(..), getFaceColor, getCubeFromPos, getCubeFromPos)
+import HCube.Utility ( (~|) )
+import HCube.OrientGroup (eid)
+
+render			:: Rubik -> IO Rubik
+render rk		= f ( view rk) 
+			>>= g renderInternal where
+    f LeftV		= g renderLeft3D rk
+    f RightV		= g renderRight3D rk
+    g 			:: (Rubik -> String) -> Rubik -> IO Rubik
+    g fu rk		= (putStrLn . fu) ~| rk
+
+renderInternal		:: Rubik -> String
+renderInternal rk	= f $ n rk where
+    f 2			= projectD dTemp2x2 dProj2x2 rk
+    f 3			= projectD dTemp3x3 dProj3x3 rk
+    f 4			= projectD dTemp4x4 dProj4x4 rk
+    f 5			= projectD dTemp5x5 dProj5x5 rk
+    f _			= "size not supported"
+
+renderLeft3D		:: Rubik -> String
+renderLeft3D rk		= f $ n rk where
+    f 2			= project3D lTemp2x2 lProj2x2 rk
+    f 3			= project3D lTemp3x3 lProj3x3 rk
+    f 4			= project3D lTemp4x4 lProj4x4 rk
+    f 5			= project3D lTemp5x5 lProj5x5 rk
+    f _			= "size not supported"
+
+renderRight3D		:: Rubik -> String
+renderRight3D rk	= f $ n rk where
+    f 2			= project3D rTemp2x2 rProj2x2 rk
+    f 3			= project3D rTemp3x3 rProj3x3 rk
+    f 4			= project3D rTemp4x4 rProj4x4 rk
+    f 5			= project3D rTemp5x5 rProj5x5 rk
+    f _			= "size not supported"
+
+project3D		:: Format -> Projection -> Rubik -> String
+project3D fm pj rk	= f (map (getFaceColor rk) pj) fm where
+    f vars		= g . map unpack . splitOn (pack "%") . replace (pack "b") (pack "\\") . pack where
+        g fm		= join fm vars
+
+join				:: [String] -> [String] -> String
+join				= f [] where
+    f acc (hd1:tl1) (hd2:tl2)	= f (acc ++ hd1 ++ hd2) tl1 tl2
+    f acc (hd1:tl1) []		= f (acc ++ hd1) tl1 []
+    f acc [] (hd2:tl2)		= f (acc ++ hd2) [] tl2
+    f acc [] []			= acc
+
+projectD		:: Format -> [ViewAssociation] -> Rubik -> String
+projectD fm va rk	= f (viewToString rk va) fm where
+    f vars		= g . map unpack . splitOn (pack "%") . pack where
+        g fm		= join fm vars
+
+viewToString			:: Rubik -> [ViewAssociation] -> [String]
+viewToString rk			= map f where
+    f (Sur pr)			= getFaceColor rk pr
+    f (Ide id)			= g . cid $ getCubeFromPos rk id 
+    f (Ori or)			= [eid . ori $ getCubeFromPos rk or]
+    g nm			= pad $ show nm
+
+
+cbLayout		:: Side -> [Int] -> [ViewAssociation]
+cbLayout sd		= map f where
+    f nm		= Sur (nm,sd)	
+
+cbInternal		:: Int -> Int -> [ViewAssociation]
+cbInternal bg ed	= (map f [bg .. ed]) ++ (map g [bg .. ed]) where
+    f nm		= Ori nm
+    g nm		= Ide nm 
+
+
+lProj2x2	:: Projection
+lProj2x2	= [ (1,UpS),		(2,UpS),		(2,LeftS),
+		    (3,UpS),		(4,UpS),		(4,LeftS),
+		    (6,LeftS),		(3,FrontS),		(4,FrontS),
+		    (8,LeftS),		(7,FrontS),		(8,FrontS) ]  
+
+rProj2x2	:: Projection
+rProj2x2	= [ (1,UpS),		(2,UpS),		(1,RightS),
+		    (3,UpS),		(4,UpS),		(5,RightS),
+		    (3,RightS),		(3,FrontS),		(4,FrontS),
+		    (7,RightS),		(7,FrontS),		(8,FrontS) ]
+
+lProj3x3	:: Projection
+lProj3x3	= [ (1,UpS), 		(2,UpS), 		(3,UpS),
+		    (3,LeftS),		(4,UpS), 		(5,UpS),
+		    (6,UpS), 		(6,LeftS),		(12,LeftS),
+	  	    (7,UpS), 		(8,UpS), 		(9,UpS),
+		    (9,LeftS),	 	(15,LeftS), 		(21,LeftS),
+		    (7,FrontS), 	(8,FrontS), 		(9,FrontS),
+		    (18,LeftS),		(24,LeftS),		(16,FrontS),
+		    (17,FrontS), 	(18,FrontS),		(27,LeftS),
+		    (25,FrontS), 	(26,FrontS), 		(27,FrontS) ] 
+
+rProj3x3	:: Projection
+rProj3x3	= [ (1,UpS),		(2,UpS),		(3,UpS),
+		    (1,RightS),		(4,UpS),		(5,UpS),
+		    (6,UpS),		(10,RightS),		(4,RightS),
+		    (7,UpS),		(8,UpS),		(9,UpS),
+		    (19,RightS),	(13,RightS),		(7,RightS),
+		    (7,FrontS),		(8,FrontS),		(9,FrontS),
+		    (22,RightS),	(16,RightS),		(16,FrontS),
+		    (17,FrontS),	(18,FrontS),		(25,RightS),
+		    (25,FrontS),	(26,FrontS),		(27,FrontS) ]
+
+lProj4x4	:: Projection
+lProj4x4	= [ (1,UpS), (2,UpS), (3,UpS), (4,UpS), (4,LeftS),
+		    (5,UpS), (6,UpS), (7,UpS), (8,UpS), (8,LeftS),
+		    (9,UpS), (10,UpS), (11,UpS), (12,UpS), (12,LeftS), (24,LeftS), (36,LeftS),
+		    (13,UpS), (14,UpS), (15,UpS), (16,UpS), (16,LeftS), (28,LeftS), (40,LeftS), (52,LeftS),
+		    (13,FrontS), (14,FrontS), (15,FrontS),(16,FrontS), (32,LeftS), (44,LeftS), (56,LeftS),
+                    (29,FrontS), (30,FrontS), (31,FrontS), (32,FrontS), (48,LeftS), (60,LeftS),
+                    (45,FrontS), (46,FrontS), (47,FrontS), (48,FrontS), (64,LeftS),
+		    (61,FrontS), (62,FrontS), (63,FrontS), (64,FrontS) ]
+
+rProj4x4	:: Projection
+rProj4x4	= [ (1,UpS), (2,UpS), (3,UpS), (4,UpS), (1,RightS),
+		    (5,UpS), (6,UpS), (7,UpS), (8,UpS), (17,RightS), (5,RightS),
+		    (9,UpS), (10,UpS), (11,UpS), (12,UpS), (33,RightS), (21,RightS), (9,RightS),
+		    (13,UpS), (14,UpS), (15,UpS), (16,UpS), (49,RightS), (37,RightS), (25,RightS), (13,RightS),
+                    (13,FrontS), (14,FrontS), (15,FrontS), (16,FrontS), (53,RightS), (41,RightS), (29,RightS),
+                    (29,FrontS), (30,FrontS), (31,FrontS), (32,FrontS), (57,RightS), (45,RightS),
+                    (45,FrontS), (46,FrontS), (47,FrontS), (48,FrontS), (61,RightS),
+		    (61,FrontS), (62,FrontS), (63,FrontS), (64,FrontS) ]		    
+
+lProj5x5	:: Projection
+lProj5x5	= [ (1,UpS), (2,UpS), (3,UpS), (4,UpS), (5,UpS), (5,LeftS),
+		    (6,UpS), (7,UpS), (8,UpS), (9,UpS), (10,UpS), (10,LeftS), (30,LeftS),
+		    (11,UpS), (12,UpS), (13,UpS), (14,UpS), (15,UpS), (15,LeftS), (35,LeftS), (55,LeftS),
+		    (16,UpS), (17,UpS), (18,UpS), (19,UpS), (20,UpS), (20,LeftS), (40,LeftS), (60,LeftS), (80,LeftS),
+		    (21,UpS), (22,UpS), (23,UpS), (24,UpS), (25,UpS), (25,LeftS), (45,LeftS), (65,LeftS), (85,LeftS), (105,LeftS),
+		    (21,FrontS), (22,FrontS), (23,FrontS), (24,FrontS), (25,FrontS), (50,LeftS), (70,LeftS), (90,LeftS), (110,LeftS),
+		    (46,FrontS), (47,FrontS), (48,FrontS), (49,FrontS), (50,FrontS), (75,LeftS), (95,LeftS), (115,LeftS),
+		    (71,FrontS), (72,FrontS), (73,FrontS), (74,FrontS), (75,FrontS), (100,LeftS), (120,LeftS),
+		    (96,FrontS), (97,FrontS), (98,FrontS), (99,FrontS), (100,FrontS), (125,LeftS) ] 
+
+rProj5x5	:: Projection
+rProj5x5	= [ (1,UpS), (2,UpS), (3,UpS), (4,UpS), (5,UpS), (1,RightS),
+		    (6,UpS), (7,UpS), (8,UpS), (9,UpS), (10,UpS), (26,RightS), (6,RightS),
+		    (11,UpS), (12,UpS), (13,UpS), (14,UpS), (15,UpS), (51,RightS), (31,RightS), (11,RightS),
+                    (16,UpS), (17,UpS), (18,UpS), (19,UpS), (20,UpS), (76,RightS), (56,RightS), (36,RightS), (16,RightS),
+		    (21,UpS), (22,UpS), (23,UpS), (24,UpS), (25,UpS), (101,RightS), (81,RightS), (61,RightS), (41,RightS), (21,RightS),
+		    (21,FrontS), (22,FrontS), (23,FrontS), (24,FrontS), (25,FrontS), (106,RightS), (86,RightS), (66,RightS), (46,RightS), (46,FrontS), (47,FrontS), (48,FrontS), (49,FrontS), (50,FrontS), (111,RightS), (91,RightS), (71,RightS),
+		    (71,FrontS), (72,FrontS), (73,FrontS), (74,FrontS), (75,FrontS), (116,RightS), (96,RightS),
+		    (96,FrontS), (97,FrontS), (98,FrontS), (99,FrontS), (100,FrontS), (121,RightS),
+		    (121,FrontS), (121,FrontS), (122,FrontS), (123,FrontS), (124,FrontS), (125,FrontS) ]
+
+dProj2x2	:: [ViewAssociation]
+dProj2x2	= concat [
+ cbLayout BackS [5,6,1,2],
+ cbLayout RightS [5,1], cbLayout UpS [1,2], cbLayout LeftS [2,6], cbInternal 1 2,
+ cbLayout RightS [7,3], cbLayout UpS [3,4], cbLayout LeftS [4,8], cbInternal 3 4,
+ cbLayout FrontS [3,4,7,8], cbInternal 5 6,
+ cbLayout RightS [3,7], cbLayout DownS [7,8], cbLayout LeftS [8,4], cbInternal 7 8,
+ cbLayout RightS [1,5], cbLayout DownS [5,6], cbLayout LeftS [6,2], cbLayout BackS [5,6,1,2] ]
+	
+dProj3x3	:: [ViewAssociation]
+dProj3x3	= concat [
+ cbLayout BackS [19,20,21], cbLayout BackS [10,11,12],
+ cbLayout BackS [1,2,3], cbInternal 1 3,
+ cbLayout RightS [19,10,1], cbLayout UpS [1,2,3], cbLayout LeftS [3,12,21], cbInternal 4 6,
+ cbLayout RightS [22,13,4], cbLayout UpS [4,5,6], 
+ cbLayout LeftS [6,15,24], cbInternal 7 9,
+ cbLayout RightS [25,16,7], cbLayout UpS [7,8,9], cbLayout LeftS [9,18,27], 
+ cbLayout FrontS [7,8,9], cbInternal 10 12,
+ cbLayout FrontS [16,17,18], cbInternal 13 15,
+ cbLayout FrontS [25,26,27], cbInternal 16 18,
+ cbLayout RightS [7,16,25], cbLayout DownS [25,26,27], cbLayout LeftS [27,18,9],
+ cbLayout RightS [4,13,22], cbLayout DownS [22,23,24], cbLayout LeftS [24,15,6], cbInternal 19 21,
+ cbLayout RightS [1,10,19], cbLayout DownS [19,20,21],
+ cbLayout LeftS [21,12,3], cbInternal 22 24,
+ cbLayout BackS [19,20,21], cbInternal 25 27,
+ cbLayout BackS [10,11,12], cbLayout BackS [1,2,3]]
+
+dProj4x4	:: [ViewAssociation]
+dProj4x4	= concat [
+ cbLayout BackS [49,50,51,52], 
+ cbLayout BackS [33,34,35,36], cbInternal 1 4,
+ cbLayout BackS [17,18,19,20], cbInternal 5 8,
+ cbLayout BackS [1,2,3,4], cbInternal 9 12,
+
+ cbLayout RightS [49,33,17,1], cbLayout UpS [1,2,3,4], cbLayout LeftS [4,20,36,52], cbInternal 13 16,
+ cbLayout RightS [53,37,21,5], cbLayout UpS [5,6,7,8], cbLayout LeftS [8,24,40,56],
+ cbLayout RightS [57,41,25,9], cbLayout UpS [9,10,11,12], cbLayout LeftS [12,28,44,60], cbInternal 17 20,
+ cbLayout RightS [61,45,29,13], cbLayout UpS [13,14,15,16], cbLayout LeftS [16,32,48,64], cbInternal 21 24,
+
+ cbLayout FrontS [13,14,15,16], cbInternal 25 28,
+ cbLayout FrontS [29,30,31,32], cbInternal 29 32,
+ cbLayout FrontS [45,46,47,48], 
+ cbLayout FrontS [61,62,63,64], cbInternal 33 36,
+
+ cbLayout RightS [1,17,33,49], cbLayout DownS [61,62,63,64], cbLayout LeftS [52,36,20,4], cbInternal 37 40,
+ cbLayout RightS [5,21,37,53], cbLayout DownS [57,58,59,60], cbLayout LeftS [56,40,24,8], cbInternal 41 44,
+ cbLayout RightS [9,25,41,57], cbLayout DownS [53,54,55,56], cbLayout LeftS [60,44,28,12], cbInternal 45 48,
+ cbLayout RightS [13,29,45,61], cbLayout DownS [49,50,51,52], cbLayout LeftS [64,48,32,16],
+ 
+ cbLayout BackS [49,50,51,52], cbInternal 49 52,
+ cbLayout BackS [33,34,35,36], cbInternal 53 56,
+ cbLayout BackS [17,18,19,20], cbInternal 57 60,
+ cbLayout BackS [1,2,3,4], cbInternal 61 64] 
+
+dProj5x5	:: [ViewAssociation]
+dProj5x5	= concat [
+ cbInternal 1 5,
+ cbInternal 6 10,
+ cbLayout BackS [101,102,103,104,105], cbInternal 11 15,
+ cbLayout BackS [76,77,78,79,80], cbInternal 16 20, 
+ cbLayout BackS [51,52,53,54,55], cbInternal 21 25,
+ cbLayout BackS [26,27,28,29,30],
+ cbLayout BackS [1,2,3,4,5], cbInternal 26 30,
+
+ cbLayout RightS [101,76,51,26,1], cbLayout UpS [1,2,3,4,5], cbLayout LeftS [5,30,55,80,105], cbInternal 31 35,
+ cbLayout RightS [106,81,56,31,6], cbLayout UpS [6,7,8,9,10], cbLayout LeftS [10,35,60,85,110], cbInternal 36 40,
+ cbLayout RightS [111,86,61,36,11], cbLayout UpS [11,12,13,14,15], cbLayout LeftS [15,40,65,90,115], cbInternal 41 45,
+ cbLayout RightS [116,91,66,41,16], cbLayout UpS [16,17,18,19,20], cbLayout LeftS [20,45,70,95,120], cbInternal 46 50,
+ cbLayout LeftS [121,96,71,46,21], cbLayout UpS [21,22,23,24,25], cbLayout LeftS [25,50,75,100,125],
+
+ cbLayout FrontS [21,22,23,24,25], cbInternal 51 55,
+ cbLayout FrontS [46,47,48,49,50], cbInternal 56 60,
+ cbLayout FrontS [71,72,73,74,75], cbInternal 61 65,
+ cbLayout FrontS [96,97,98,99,100], cbInternal 66 70,
+ cbLayout FrontS [121,122,123,124,125], cbInternal 71 75,
+
+ cbLayout RightS [121,96,71,46,21], cbLayout DownS [121,122,123,124,125], cbLayout LeftS [125,100,75,50,25],
+ cbLayout RightS [116,91,66,41,16], cbLayout DownS [116,117,118,119,120], cbLayout LeftS [120,95,70,45,20], cbInternal 76 80,
+ cbLayout RightS [111,86,61,36,11], cbLayout DownS [111,112,113,114,115], cbLayout LeftS [115,90,65,40,15], cbInternal 81 85,
+ cbLayout RightS [106,81,56,31,6], cbLayout DownS [106,107,108,109,110], cbLayout LeftS [110,85,60,35,10], cbInternal 86 90,
+ cbLayout RightS [101,76,51,26,1], cbLayout DownS [101,102,103,104,105], cbLayout LeftS [105,80,55,30,5], cbInternal 91 95,
+
+ cbLayout BackS [101,102,103,104,105], cbInternal 96 100,
+ cbLayout BackS [76,77,78,79,80],
+ cbLayout BackS [51,52,53,54,55], cbInternal 101 105,
+ cbLayout BackS [26,27,28,29,30], cbInternal 106 110,
+ cbLayout BackS [1,2,3,4,5], cbInternal 111 115,
+ cbInternal 116 120,
+ cbInternal 121 125]
+ 
+lTemp2x2	:: String
+lTemp2x2	= unlines [
+	"     _____  ______",
+	"   /  %   /  %   / b",
+	"  /______/______/ % b",
+	" /  %   /   %  / b  /b",
+	"/______/______/ % b/ %b/",
+	"b   %  b    % b   /b  /",
+	" b______b _____b / %b/",
+	"  b  %   b   %  b   /",
+	"   b______b______b /"]
+
+rTemp2x2	= unlines [
+	"    ______ ______ ",
+	"   /b  %   b  %   b",
+	"  /% b______b______b",
+	" /b  /b  %   b  %   b",
+	"/% b/% b______b______b",
+	"b  /b  /  %   /  %   /",    
+	" b/% b/______/______/",
+	"  b  /   %  /   %  /",
+	"   b/______/______/"]
+
+	
+lTemp3x3	:: String
+lTemp3x3	= unlines [
+	"       _____  ______ _____",
+	"     / %    / %    / %    / b",
+	"    /_____ /_____ /______/ % b",
+	"   /  %   /  %   /  %   / b  /b",
+	"  /______/______/______/ % b/ %b",
+	" /  %   /   %  /   %  / b  /b  /b",
+	"/______/______/______/ % b/ %b/ %b",
+	"b   %  b    % b    % b   /b  /b  /",
+	" b______b _____b______b / %b/ %b/",
+	"  b  %   b   %  b   %  b   /b  /",
+	"   b______b______b______b / %b/",
+	"    b  %   b  %   b  %   b   /",
+	"     b______b______b______b /"]
+
+rTemp3x3	:: String
+rTemp3x3	= unlines [
+	"         ______ ______ ______",
+	"        /b   %  b  %   b   %  b",
+	"       /% b______b______b______b",
+	"      /b  /b  %   b  %   b  %   b",
+	"     /% b/% b______b______b______b",
+	"    /b  /b  /b  %   b  %   b  %   b",
+	"   /% b/% b/% b______b______b______b",
+	"   b  /b  /b  /  %   /  %   /  %   /",    
+	"    b/% b/% b/______/______/______/",
+	"     b  /b  /   %  /   %  /   %  /",
+	"      b/% b/______/______/______/",
+	"       b  /    % /    % /    % /",
+	"        b/______/______/______/"]
+
+lTemp4x4	:: String
+lTemp4x4	= unlines [
+	"        ___________________________",
+	"       / %    / %    / %    / %    / b",
+	"      /_____ /______/______/______/ % b",
+	"     / %    / %    / %    / %    / b  /b",
+	"    /_____ /_____ /_____ /______/ % b/ %b",
+	"   /  %   /  %   /  %   /  %   / b  /b  /b",
+	"  /______/______/______/______/ % b/ %b/ %b",
+	" /  %   /   %  /   %  /   %  / b  /b  /b  /b",
+	"/______/______/______/______/ % b/ %b/ %b/ %b",
+	"b   %  b    % b    % b   %  b   /b  /b  /b  /",
+	" b______b _____b______b______b / %b/ %b/ %b/",
+	"  b  %   b   %  b   %  b   %  b   /b  /b  /",
+	"   b______b______b______b______b / %b/ %b/",
+	"    b  %   b  %   b  %   b  %   b   /b  /",
+	"     b______b______b______b______b / %b/",
+	"      b  %   b  %   b  %   b  %   b   /",
+	"       b______b______b______b______b /"]
+
+rTemp4x4	:: String
+rTemp4x4	= unlines [
+	"         ___________________________",
+	"       /b  %   b   %  b    % b    % b",
+	"      /% b______b______b______b______b",
+	"     /b  /b   %  b  %   b   %  b   %  b",
+	"    /% b/% b______b______b______b______b",
+	"   /b  /b  /b  %   b  %   b  %   b   %  b",
+	"  /% b/% b/% b______b______b______b______b",
+	" /b  /b  /b  /b  %   b  %   b  %   b   %  b",
+	"/% b/% b/% b/% b______b______b______b______b",
+	"b  /b  /b  /b  /  %   /  %   /  %   /  %   /",    
+	" b/% b/% b/% b/______/______/______/______/",
+	"  b  /b  /b  /   %  /   %  /   %  /  %   /",
+	"   b/% b/% b/______/______/______/______/",
+	"    b  /b  /   %  /   %  /  %   /  %   /",
+	"     b/% b/______/______/______/______/",
+	"      b  /   %  /   %  /   %  /  %   /",
+	"       b/_____ /______/______/______/"]
+
+lTemp5x5	:: String
+lTemp5x5	= unlines [
+	"          ___________________________________",
+	"         /  %   /  %   /  %   /  %   /  %   / b",
+	"        /_____ /______/______/______/______/ % b",
+	"       /   %  /  %   /   %  /   %  /   %  / b  /b",
+	"      /_____ /_____ /_____ /______/______/ % b/ %b",
+	"     /   %  /  %   /  %   /  %   /  %   / b  /b  /b",
+        "    /_____ /_____ /_____ /______/______/ % b/ %b/ %b",
+        "   /  %   /  %   /  %   /  %   /  %   / b  /b  /b  /b",
+	"  /______/______/______/______/______/ % b/ %b/ %b/ %b",
+	" /  %   /  %   /  %   /  %   /  %   / b  /b  /b  /b  /b",
+	"/______/______/______/______/______/ % b/ %b/ %b/ %b/ %b",
+	"b   %  b  %   b  %   b  %   b  %   b   /b  /b  /b  /b  /",
+	" b______b _____b______b______b______b / %b/ %b/ %b/ %b/ ",
+	"  b  %   b  %   b  %   b  %   b  %   b   /b  /b  /b  /",
+	"   b______b______b______b______b______b / %b/ %b/ %b/",
+	"    b  %   b  %   b  %   b  %   b  %   b   /b  /b  /",
+        "     b______b______b______b______b______b / %b/ %b/",
+	"      b  %   b  %   b  %   b  %   b  %   b   /b  /",
+	"       b______b______b______b______b______b / %b/",
+	"        b  %   b  %   b  %   b  %   b  %   b   /",
+	"         b______b______b______b______b______b /"]
+
+rTemp5x5	:: String
+rTemp5x5	= unlines [
+	"          ___________________________________",
+	"         /b  %   b   %  b  %   b   %  b  %   b",
+	"        /% b______b______b______b______b______b",
+	"       /b  /b   %  b  %   b  %   b   %  b  %   b",
+	"      /% b/% b______b______b______b______b______b",
+	"     /b  /b  /b  %   b  %   b  %   b  %   b  %   b",
+	"    /% b/% b/% b______b______b______b______b______b",
+	"   /b  /b  /b  /b  %   b  %   b  %   b  %   b  %   b",
+	"  /% b/% b/% b/% b______b______b______b______b______b",
+	" /b  /b  /b  /b  /b  %   b  %   b  %   b  %   b  %   b",
+	"/% b/% b/% b/% b/% b______b______b______b______b______b",
+	"b  /b  /b  /b  /b  /  %   /  %   /  %   /  %   /  %   /",    
+	" b/% b/% b/% b/% b/______/______/______/______/______/",
+	"  b  /b  /b  /b  /   %  /   %  /  %   /   %  /  %   /",
+	"   b/% b/% b/% b/______/______/______/______/______/",
+	"    b  /b  /b  /   %  /   %  /  %   /  %   /  %   /",
+	"     b/% b/% b/______/______/______/______/______/",
+	"      b  /b  /   %  /   %  /  %   /  %   /  %   /",
+	"       b/% b/______/______/______/______/______/",
+	"        b  /   %  /   %  /  %   /   %  /  %   /",
+	"         b/_____ /______/______/______/______/"]
+
+
+dTemp2x2	:: String
+dTemp2x2	= unlines [
+	"      %  %",
+	"      %  %",
+	"%  %  %  %  %  %     %  %     %  %    1 2",
+	"%  %  %  %  %  %     %  %     %  %    3 4",
+	"      %  %",
+	"      %  %           %  %     %  %    5 6",
+	"%  %  %  %  %  %     %  %     %  %    7 8",
+	"%  %  %  %  %  %",
+	"      %  %",
+	"      %  %"] 
+
+dTemp3x3	:: String
+dTemp3x3	= unlines [
+	"         %  %  %",
+	"         %  %  %",
+	"         %  %  %             %  %  %    %  %  %      1  2  3",
+	"%  %  %  %  %  %  %  %  %    %  %  %    %  %  %      4  5  6",
+	"%  %  %  %  %  %  %  %  %    %  %  %    %  %  %      7  8  9",
+	"%  %  %  %  %  %  %  %  %",
+	"         %  %  %             %  %  %    %  %  %     10 11 12",
+	"         %  %  %             %  %  %    %  %  %     13 14 15",
+	"         %  %  %             %  %  %    %  %  %     16 17 18",
+	"%  %  %  %  %  %  %  %  %",
+	"%  %  %  %  %  %  %  %  %    %  %  %    %  %  %     19 20 21",
+	"%  %  %  %  %  %  %  %  %    %  %  %    %  %  %     22 23 24",
+	"         %  %  %             %  %  %    %  %  %     25 26 27",
+	"         %  %  %",
+	"         %  %  %"] 
+
+dTemp4x4	:: String
+dTemp4x4	= unlines [
+	"            %  %  %  %",
+	"            %  %  %  %                 %  %  %  %     %  %  %  %     1  2  3  4",           
+	"            %  %  %  %                 %  %  %  %     %  %  %  %     5  6  7  8",
+	"            %  %  %  %                 %  %  %  %     %  %  %  %     9 10 11 12",
+	"%  %  %  %  %  %  %  %  %  %  %  %     %  %  %  %     %  %  %  %    13 14 15 16",
+	"%  %  %  %  %  %  %  %  %  %  %  %",
+	"%  %  %  %  %  %  %  %  %  %  %  %     %  %  %  %     %  %  %  %    17 18 19 20",
+	"%  %  %  %  %  %  %  %  %  %  %  %     %  %  %  %     %  %  %  %    21 22 23 24",
+	"            %  %  %  %                 %  %  %  %     %  %  %  %    25 26 27 28",
+	"            %  %  %  %                 %  %  %  %     %  %  %  %    29 30 31 32",
+	"            %  %  %  %",
+	"            %  %  %  %                 %  %  %  %     %  %  %  %    33 34 35 36",
+	"%  %  %  %  %  %  %  %  %  %  %  %     %  %  %  %     %  %  %  %    37 38 39 40",
+	"%  %  %  %  %  %  %  %  %  %  %  %     %  %  %  %     %  %  %  %    41 42 43 44",
+	"%  %  %  %  %  %  %  %  %  %  %  %     %  %  %  %     %  %  %  %    45 46 47 48",
+	"%  %  %  %  %  %  %  %  %  %  %  %",
+	"            %  %  %  %                 %  %  %  %     %  %  %  %    49 50 51 52",
+	"            %  %  %  %                 %  %  %  %     %  %  %  %    53 54 55 56",
+	"            %  %  %  %                 %  %  %  %     %  %  %  %    57 58 59 60",
+	"            %  %  %  %                 %  %  %  %     %  %  %  %    61 62 63 64"] 
+
+
+dTemp5x5	:: String
+dTemp5x5	= unlines [
+ "                                                %  %  %  %  %    %  %  %  %  %    1   2   3   4   5",
+ "                                                %  %  %  %  %    %  %  %  %  %    6   7   8   9   10",
+ "               %  %  %  %  %                    %  %  %  %  %    %  %  %  %  %    11  12  13  14  15",
+ "               %  %  %  %  %                    %  %  %  %  %    %  %  %  %  %    16  17  18  19  20",
+ "               %  %  %  %  %                    %  %  %  %  %    %  %  %  %  %    21  22  23  24  25",
+ "               %  %  %  %  %",
+ "               %  %  %  %  %                    %  %  %  %  %    %  %  %  %  %    26  27  28  29  30",
+ "%  %  %  %  %  %  %  %  %  %  %  %  %  %  %     %  %  %  %  %    %  %  %  %  %    31  32  33  34  35",
+ "%  %  %  %  %  %  %  %  %  %  %  %  %  %  %     %  %  %  %  %    %  %  %  %  %    36  37  38  39  40",
+ "%  %  %  %  %  %  %  %  %  %  %  %  %  %  %     %  %  %  %  %    %  %  %  %  %    41  42  43  44  45",
+ "%  %  %  %  %  %  %  %  %  %  %  %  %  %  %     %  %  %  %  %    %  %  %  %  %    46  47  48  49  50",
+ "%  %  %  %  %  %  %  %  %  %  %  %  %  %  %",
+ "               %  %  %  %  %                    %  %  %  %  %    %  %  %  %  %    51  52  53  54  55",
+ "               %  %  %  %  %                    %  %  %  %  %    %  %  %  %  %    56  57  58  59  60",
+ "               %  %  %  %  %                    %  %  %  %  %    %  %  %  %  %    61  62  63  64  65",
+ "               %  %  %  %  %                    %  %  %  %  %    %  %  %  %  %    66  67  68  69  70",
+ "               %  %  %  %  %                    %  %  %  %  %    %  %  %  %  %    71  72  73  74  75",
+ "%  %  %  %  %  %  %  %  %  %  %  %  %  %  %",
+ "%  %  %  %  %  %  %  %  %  %  %  %  %  %  %     %  %  %  %  %    %  %  %  %  %    76  77  78  79  80",
+ "%  %  %  %  %  %  %  %  %  %  %  %  %  %  %     %  %  %  %  %    %  %  %  %  %    81  82  83  84  85",
+ "%  %  %  %  %  %  %  %  %  %  %  %  %  %  %     %  %  %  %  %    %  %  %  %  %    86  87  88  89  90",
+ "%  %  %  %  %  %  %  %  %  %  %  %  %  %  %     %  %  %  %  %    %  %  %  %  %    91  92  93  94  95",
+ "               %  %  %  %  %                    %  %  %  %  %    %  %  %  %  %    96  97  98  99 100",
+ "               %  %  %  %  %",
+ "               %  %  %  %  %                    %  %  %  %  %    %  %  %  %  %   101 102 103 104 105",
+ "               %  %  %  %  %                    %  %  %  %  %    %  %  %  %  %   106 107 108 109 110",
+ "               %  %  %  %  %                    %  %  %  %  %    %  %  %  %  %   111 112 113 114 115",
+ "                                                %  %  %  %  %    %  %  %  %  %   116 117 118 119 120", 
+ "                                                %  %  %  %  %    %  %  %  %  %   121 122 123 124 125"]  
+
+pad				:: String -> String
+pad (ch:[])			= "  " ++  [ch]
+pad (ch1:ch2:[])		= ' ' : [ch1,ch2]
+pad chs				= chs
diff --git a/HCube/Test.hs b/HCube/Test.hs
new file mode 100644
--- /dev/null
+++ b/HCube/Test.hs
@@ -0,0 +1,68 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  HCube.Test
+-- Copyright   :  (c) Todd Wegner 2013
+-- License     :  BSD-style (see the LICENSE file)
+-- 
+-- Maintainer  :  todd.w.wegner@gmail.com
+-- Stability   :  provisional
+-- Portability :  portable
+--
+-- Test invariants of hcube. 
+-----------------------------------------------------------------------------
+module HCube.Test (runTests)
+where
+
+import Test.QuickCheck.Test(verboseCheckWith,quickCheck,quickCheckWith, Args(..))
+import Test.QuickCheck.Arbitrary(Arbitrary, arbitrary, shrink, shrinkIntegral)
+import Test.QuickCheck.Gen(Gen,sized, choose)
+import HCube.Data (Vec, TestNumb(..) )
+import HCube.Lib (posToId, getPos, initCube)
+import HCube.OrientGroup (Orient (..), rawToOrientNumber, rawOrientNum, orientNumberToRaw)
+import HCube.Utility (mapVec, modNot, gateMinus, modMinus)
+
+-- invariants
+
+idProperty (TestNumb sz) = f where
+	f	  = [posToId sz . getPos sz $ a | a <- [1..g]] == [1..g]
+	g	  = sz*sz*sz
+
+-- 24 is a mathematical constant
+orientId 	= [f . g $ a | a <- [1..24]] == [1..24] where
+    f		= rawToOrientNumber . rawOrientNum . Orient
+    g		= h . orientNumberToRaw  where
+	h cd		= [j . k $ (i 2, i 3, i 5), k (i 7, i 11,i 13)] where
+		i	= modNot cd
+		j	= gateMinus cd
+		k	= modMinus cd 17
+
+orientProperty   :: TestNumb -> Bool	
+orientProperty _ = orientId
+
+args = Args {
+replay = Nothing,
+maxDiscardRatio=5,
+maxSuccess = 5,
+maxSize = 10,
+chatty = True
+}
+
+args2 = args {maxSuccess = 1,
+	      maxDiscardRatio = 1} 
+
+instance Arbitrary TestNumb where
+  arbitrary = arbitraryNumb
+  shrink    = shrinkIntegral
+
+arbitraryNumb   :: Gen TestNumb
+arbitraryNumb =
+  sized $ \n ->
+    let n' = toInteger n in
+      fmap fromInteger (choose (1, n'))
+
+runTests		:: IO ()
+runTests		= f where
+	f 		=  h orientProperty
+			   >> g idProperty
+	g		= quickCheckWith args
+	h 		= quickCheckWith args2
diff --git a/HCube/Theory.hs b/HCube/Theory.hs
new file mode 100644
--- /dev/null
+++ b/HCube/Theory.hs
@@ -0,0 +1,185 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  HCube.Theory
+-- Copyright   :  (c) Todd Wegner 2013
+-- License     :  BSD-style (see the LICENSE file)
+-- 
+-- Maintainer  :  todd.w.wegner@gmail.com
+-- Stability   :  provisional
+-- Portability :  portable
+-- 
+-- Module for generating tables exhibiting internals of hcube.
+-- See the design directory for output generated by these functions.
+-----------------------------------------------------------------------------
+module HCube.Theory (
+	displayColors,
+	displayOrientVecMapping,
+	displayOrientTransforms,
+	displayOrientMatrices,
+	displayColorToOrient,
+	displayOrientI,
+	displayOrientP,
+	displayColorTags,
+	displayFaceIds
+	) where
+
+import Data.Monoid ( (<>) )
+import Data.List (sort)
+import HCube.Lib (getPos, consCubeInfo, solvedSurf, cubeIdsOfFace)
+import HCube.Data (Side, Color, sideToColor,Size, Matrix)
+import HCube.Utility
+import HCube.Cons
+import HCube.OrientGroup
+import HCube.Common
+
+-- Information common Rubik cubes of all size
+
+{-
+: COLOR MAPPING
+SIDE    VECTOR   COLOR
+-}
+-- | Show mapping of cube face to vector and color.
+displayColors		:: IO ()
+displayColors		= putStrLn . unlines $ map f sides where
+    f sd		= concat [prShow 8 sd, prShow 9 $ sideToVec sd, show $ sideToColor sd]
+
+{-
+: DEFINITION OF CUBE ORIENTATION
+: RIGHT GOES TO FACE 1.
+: BACK GOES TO FACE 2.
+VECTOR 1   VECTOR 2   FACE 1	FACE 2    COLOR	RAW	ORIENT	IDS
+-}
+-- | Two vectors are required to uniquely determine cube orientation.
+-- Orientation is defined as an operation from identity orientation.
+-- Right face goes to face represented by vector 1.
+-- Back gace goes to face represented by vector 2.
+displayOrientVecMapping :: IO ()
+displayOrientVecMapping	= dispLis f $ spanDomain g where
+    f (id1,(id2,ch,v1,v2,rw, f1, f2, cl)) 
+			= concat [prShow 11 v1,
+				  prShow 11 v2,
+				  prShow 10 f1,
+				  prShow 10 f2,
+			  	  cl, 
+				  plShow 7 rw, "   ",
+				  plShow 4 id1, "   ", 
+				  [ch] ] 
+    g or@(Orient (v1:v2:[])) 
+			= (h, eid or, v1, v2, rawOrientNum or, 
+    --g v1 v2		= (h, eid $ Orient [v1,v2], v1, v2, rawOrientNum v1 v2, 
+			   vecToSide v1, vecToSide v2,
+			   i v1 ++ i v2) where
+	h		= rawToOrientNumber $ rawOrientNum or
+	i		= show . vecToColor
+
+{-
+: CUBE ORIENTATION VIEWED AS A TRANSFORMATION OF CUBE FACE
+: FROM IDENTITY ORIENTATION n
+ID  SIDE    GOES TO             ID  SIDE    GOES TO
+-}
+-- | Cube orientation can be viewed as a transformation of faces from identity position.
+displayOrientTransforms	= putStrLn . unlines . twoPagesOnOne "\t\t" $ map f g where 
+    f (oc,sf,st)	= concat [oc, "   ", i 8 sf, i 8 st] 
+    g			= map h [(or,sd) | or <- orientChrDomain, sd <- sides] 
+    h (oi,sd)		= ([oi],sd, vecToSide i) where
+	i		= (to . cons $ oi) |*| (sideToVec sd) 
+    i			= prShow
+
+{-
+: ORIENTATION TRANSFORMATION MATRICES 
+ID    COLUMN 1    COLUMN 2    COLUMN 3  DET
+a-}
+-- | Matrix representation of oriention group.
+-- Right handed coordinate system implies determinate must be one.
+displayOrientMatrices	= putStrLn . unlines $ map f g where
+    f (oc, mx)		= concat [oc, "   ", showM mx, "\t", show $ det mx] 
+    g			= map h orientChrDomain
+    h oi		= ([oi], to . cons $ oi)
+
+{-
+: CONSTRUCTION OF VIRTUAL CUBE ORIENTATION FROM PHYSICAL CUBE
+C1	Two colors on cube, one and two respectively.
+C2	Identity face position for color 1.	
+C3	Identity face position for color 2.
+C4	Calculated cube orientation.
+
+C1  C2	     C3      C4         C1  C2       C3      C4
+-}
+-- | Shows how colors on a cubie are mapped to orientation. 
+displayColorToOrient	:: IO ()
+displayColorToOrient	= writeFile "colorToOrient" $ unlines . twoPagesOnOne "\t\t"
+			. sort . map f $ map g sideColorDomain where
+    f (((fd1,cl1),(fd2,cl2)), vs) 
+			= concat [show cl1 ++ show cl2, "  ",
+			          k 9 fd1, 
+				  k 8 fd2,
+				  [eid $ Orient vs]]
+    g sc@(sc1,sc2)	= (sc, getVec $ consOrient sc1 sc2)
+    i			= "\t"
+    j			= show . vecToColor
+    k			= prShow 
+
+sideColorDomain		:: [((Side, Color), (Side, Color))] 
+sideColorDomain		= [(x,y) | x <-f, y <-f, x /=y, g x y] where
+    f			= [(sd1, sideToColor sd2) | sd1 <- sides, sd2 <-sides]
+    g (sd1,cl1) (sd2,cl2) = h (i sd1) (j cl1) (i sd2) (j cl2)
+    h v1 u1 v2 u2	  = v1 /= v2 && u1 /= u2 && v1 /= minus v2 && u1 /= minus u2
+    i			  = sideToVec
+    j			  = colorToVec
+
+{-
+: INVERSE TABLE FOR ORIENT GROUP
+-}
+-- | Displays inverses for orientation group.
+displayOrientI	= putStrLn . unlines $  twoPagesOnOne "\t\t" [g e1 | e1 <- f] where
+    f		= map cons ['a'..'x'] :: [Orient]
+    g e1	= concat ["inv ", [eid e1], " = ", [eid $ inv e1]]
+
+{-
+: MULTIPLICATION TABLE FOR ORIENT GROUP
+-}
+-- | Displays multiplication table for orientation group.
+displayOrientP	= putStrLn . unlines $ h [g e1 e2 | e1 <- f, e2 <- f] where
+    f		= map cons ['a'..'x'] :: [Orient]
+    g e1 e2	= concat [ [eid e1], " x ", [eid e2], " = ", [eid $ e1 <> e2]]
+    h		= fourPagesOnOne "\t"
+
+-- Infomation depending on size of Rubik's cube
+
+{-
+: CONSTRUCTING VIRTUAL CUBE ID FROM CUBE COLORS OF PHYSICAL CUBE
+: 	THREE COLORS MEANS CORNER CUBE
+: 	TWO COLORS MEANS EDGE CUBE
+: 	ONE COLOR MEANS CENTER CUBE
+: 	NO COLOR MEANS CUBE IS INTERNAL CUBE
+
+CUBE      CUBE       COLOR      CUBE      CUBE      COLOR
+ID        POSITION   TAG        ID        POSITION  TAG
+-}
+
+-- | Displays how coloring of cubie is used to determine cube id of cube.
+-- Cube id represents position of cubie in solved configuration.
+displayColorTags	:: Size -> IO ()
+displayColorTags n 	= putStrLn . unlines . twoPagesOnOne "\t\t" 
+			  . map f $ consCubeInfo n (solvedSurf n) where
+    f (a,b,c)		= concat [plShow 3 a, "\t", prShow 8 $ getPos n a, "\t" ++ c]
+
+{-
+: MAPPING OF FACE ID TO CUBE ID
+: FACE ID IS USED TO ENTER COLOR ON A PHYSICAL CUBE FOR LOADING
+: INTO PROGRAM
+
+RUBIKS    FACE	     CUBE       RUBIKS    FACE      CUBE
+CUBE      ID         ID         CUBE      ID        ID
+FACE
+-}
+
+-- | Displays mapping of face id to cube id.
+-- Face ids are useful when specifing the state of a physical cube.
+displayFaceIds		:: Size -> IO ()
+displayFaceIds n	= putStrLn . unlines . twoPagesOnOne "\t\t" $ concatMap f sides where
+    f sd		= map g . zip [1..] $ cubeIdsOfFace n sd where
+	g (fi, cis)	= concat [prShow 10 sd, prShow 10 fi, plShow 2 cis] 
+
+dispLis			:: (a -> String) -> [a] -> IO ()
+dispLis fu		= putStrLn . unlines . map fu  
diff --git a/HCube/Utility.hs b/HCube/Utility.hs
new file mode 100644
--- /dev/null
+++ b/HCube/Utility.hs
@@ -0,0 +1,156 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  HCube.Utility
+-- Copyright   :  (c) Todd Wegner 2013
+-- License     :  BSD-style (see the LICENSE file)
+-- 
+-- Maintainer  :  todd.w.wegner@gmail.com
+-- Stability   :  provisional
+-- Portability :  portable
+--
+-- Common utility functions, simple linear algebra. 
+-----------------------------------------------------------------------------
+module HCube.Utility where
+
+import Control.Monad (foldM, (>=>), liftM, liftM2)
+import Data.List
+import HCube.Data
+import HCube.Common(padL)
+
+-- | Multiple a matrix on the left side of a vector.
+(|*|)		:: Matrix -> Vec -> Vec
+(|*|)(Matrix (a,d,g) (b,e,h) (c,f,i)) (x,y,z) = (a*x + b*y + c*z,
+						 d*x + e*y + f*z,
+						 g*x + h*y + i*z)
+
+-- | Multiple two matrices.
+(|**|)		:: Matrix -> Matrix -> Matrix
+(|**|)(Matrix (a,d,g) (b,e,h) (c,f,i))
+      (Matrix (j,m,p) (k,n,q) (l,o,r)) = Matrix (a*j + b*m + c*p, d*j + e*m + f*p, g*j + h*m + i*p)
+						(a*k + b*n + c*q, d*k + e*n + f*q, g*k + h*n + i*q)
+						(a*l + b*l + c*r, d*l + e*o + f*r, g*l + h*o + i*r )
+
+-- | Multiple a matrix by a scalar.
+multMatrix	:: Numb -> Matrix -> Matrix
+multMatrix nm (Matrix (a,d,g) (b,e,h) (c,f,i)) = Matrix (nm*a,nm*d,nm*g)
+							(nm*b,nm*e,h)
+							(nm*c,nm*f,nm*i)
+-- | The cofactor of a matrix.
+cofactors	:: Matrix -> Matrix
+cofactors (Matrix (a,d,g) (b,e,h) (c,f,i))
+					= Matrix (e*i-f*h, c*h-b*i, b*f-c*e)
+						 (f*g-d*i, a*i-c*g, c*d-a*f)
+						 (d*h-e*g, b*g-a*h, a*e-b*d) 
+-- | Transpose of a matrix.
+transposeM	:: Matrix -> Matrix
+transposeM (Matrix (a,d,g) (b,e,h) (c,f,i))  = Matrix (a,b,c) (d,e,f) (g,h,i)
+
+-- | Inverse of a matrix.
+inverse		:: Matrix -> Matrix
+inverse mx	= multMatrix (det mx) . transposeM $ cofactors mx 
+
+-- | Display a matrix.
+showM			:: Matrix -> String
+showM (Matrix (a,d,g) (b,e,h) (c,f,i)) = concat y where
+    y		= [z a, z d, z g, "   ", z b, z e, z h, "   ", z c, z f, z i]
+    z 		= padL 3 . show
+
+doM			:: Monad m => (a -> Bool) -> (a -> m a) -> a -> m a
+doM te lp		= lp >=> \s-> if te s then doM te lp s else return s
+
+-- Inject operator
+infixl 1 ~>
+(~>)			:: Monad m => m a -> (a -> b -> m b) -> b -> m b
+(~>) op fu st		= op >>= \s -> fu s st
+
+(~|)			:: Monad m => (a -> m b) -> a -> m a
+(~|) fu a		= fu a >> return a
+
+infixl 4 <*
+(<*)			:: Monad m => m a -> m b -> m a
+(<*)			= liftM2 const
+
+concatMapM		:: Monad m => (a -> m [b]) -> [a] -> m [b]
+concatMapM bbf		= liftM concat . mapM bbf
+
+listToMaybe           :: [a] -> Maybe a
+listToMaybe []        =  Nothing
+listToMaybe (a:_)     =  Just a
+
+-- | A safe form of read.
+maybeRead :: String -> Maybe Int
+maybeRead = fmap fst . listToMaybe . reads
+
+-- | Applies a function on the domain of Side x Side.
+spanFaces 		:: (Enum a, Num a, Ord b) =>
+			   (Side -> Side -> b) -> [(a, b)]
+spanFaces fn		= zip [1..] $ sort $ f where
+	f		= [fn a b | a <- sides, b <- sides, a /=b]
+-- | List of the sides.
+sides			= [UpS,DownS,FrontS,BackS,LeftS,RightS]
+
+-- | List of the vectors.
+vecs			= [(1,0,0),(0,1,0),(0,0,1),(-1,0,0),(0,-1,0),(0,0,-1)] :: [Vec]
+
+-- | Multiple a vector by a scalar.
+multVec			:: Numb -> Vec -> Vec
+multVec nm (v1,v2,v3)	= (nm*v1, nm*v2, nm*v3)
+
+-- | Convert a function with two vector arguments to one accepting a list of vectors.
+mapVec			:: (Vec -> Vec -> a) -> [Vec] -> a
+mapVec fu (v1:v2:[]) 	= fu v1 v2
+
+-- | The determinate of a matrix.
+det			:: Matrix -> Int
+det (Matrix (a,d,g) (b,e,h) (c,f,i)) = a*e*i + b*f*g + c*d*h - c*e*g - b*d*i - a*f*h
+
+-- | Calculate the determinate of a matrix constructed by three column vectors.
+vecDet			:: Vec -> Vec -> Vec -> Int
+vecDet v1 v2 v3		= det $ Matrix v1 v2 v3
+
+-- | Multiple a matrix by a scalar.
+matrixMult		:: Matrix -> Int -> Matrix
+matrixMult (Matrix v1 v2 v3) ct = Matrix (f v1) (f v2) (f v3) where
+    f			= multVec ct
+
+-- |The cross product of two vectors.
+cross			:: Vec -> Vec -> Vec
+cross (a,b,c) (x,y,z)	= (b*z-y*c,a*z-c*x,a*y-b*x)
+
+-- |Vector multipled by scalar -1.
+minus			:: Vec -> Vec
+minus (a,b,c)		= (-a,-b,-c)
+
+-- |Vectors we are interested in only have one non zero component. 
+vcomp			:: Vec -> Int
+vcomp (vl,0,0)		= vl
+vcomp (0,vl,0)		= vl
+vcomp (0,0,vl)		= vl
+vcomp bd		= error . show $ bd
+
+-- |Position of non-zero vector component.
+vpos			:: Vec -> Int
+vpos (_,0,0)		= 1
+vpos (0,_,0)		= 2
+vpos (0,0,_)		= 3
+vpos bd			= error . show $ bd
+
+-- | The dot product of two vectors.
+dot			:: Vec -> Vec -> Numb
+dot (a,b,c) (x,y,z)     = a*x + b*y + c*z
+	
+gateMinus		:: Numb -> Vec -> Vec
+gateMinus ct		= f $ ct < 0 where
+	f True		= minus
+	f False		= id
+
+
+modMinus		:: Numb -> Numb -> Vec -> Vec
+modMinus cd ts 		= f $ cd `mod` ts where
+	f 0		= minus
+	f _		= id
+
+modNot			:: Numb -> Numb -> Numb
+modNot cd ts		= f $ cd `mod` ts where
+	f 0		= 1
+	f _		= 0 
diff --git a/HCube/store/physicalCubeExample b/HCube/store/physicalCubeExample
new file mode 100644
--- /dev/null
+++ b/HCube/store/physicalCubeExample
@@ -0,0 +1,6 @@
+[(UpS, [White,Green,Yellow,Green,White,Green,Red,White,Green]),
+          (FrontS,      [Blue,Blue,White,Yellow,Orange,Yellow,Red,Yellow,White]),
+          (DownS,       [Yellow,Blue,Green,White,Yellow,Blue,White,Orange,Green]),
+          (BackS,       [Orange,Blue,Orange,Yellow,Red,Red,Red,Orange,Blue]),
+          (LeftS,       [Orange,White,Yellow,Red,Green,Red,Orange,Red,Red]),
+          (RightS,      [Blue,Green,Blue,Orange,Blue,White,Green,Orange,Yellow])]
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+Copyright 2012-2013, Todd Wegner. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+  this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer in the
+  documentation and/or other materials provided with the distribution.
+
+This software is provided by the copyright holders "as is" and any express or
+implied warranties, including, but not limited to, the implied warranties of
+merchantability and fitness for a particular purpose are disclaimed. In no
+event shall the copyright holders be liable for any direct, indirect,
+incidental, special, exemplary, or consequential damages (including, but not
+limited to, procurement of substitute goods or services; loss of use, data,
+or profits; or business interruption) however caused and on any theory of
+liability, whether in contract, strict liability, or tort (including
+negligence or otherwise) arising in any way out of the use of this software,
+even if advised of the possibility of such damage.
diff --git a/README b/README
new file mode 100644
--- /dev/null
+++ b/README
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/design/2x2.txt b/design/2x2.txt
new file mode 100644
--- /dev/null
+++ b/design/2x2.txt
@@ -0,0 +1,89 @@
+	1	2
+	3	4
+
+	5	6
+	7	8
+
+left 2x2
+
+                   UpS
+              _____  ______  
+            /  1   /  2   / \  
+           /______/______/ 2 \  
+          /   3  /   4  / \  /\  
+         /______/______/ 4 \/ 6\  LeftS
+         \   3  \   4  \   /\  /  
+          \______\ _____\ / 8\/  
+           \  7   \  8   \   /  
+            \______\______\ /  
+
+                  FrontS
+                 
+right 2x2
+             ______ ______   
+            /\  1   \  2   \  
+           /1 \______\______\  
+          /\  /\  3   \ 4    \  
+RightS   /5 \/3 \______\______\  
+         \  /\  / 3    / 4    /      
+          \/7 \/______/______/  
+           \  /  7   /  8   /  
+            \/______/______/  
+
+               5  6  
+               1  2  
+         5  1  1  2  2  6     1  2     1  2    1   2  
+         7  3  3  4  4  8     3  4     3  4    3   4  
+               3  4  
+               7  8           5  6     5  6    5   6  
+         3  7  7  8  8  4     7  8     7  8    7   8  
+         1  5  5  6  6  2  
+               5  6  
+               1  2  
+
+FACE IDs
+               1  2  
+               3  4  
+         1  2  1  2  1  2  
+         3  4  3  4  3  4  
+               1  2  
+               3  4  
+         4  3  1  2  4  3  
+         2  1  3  4  2  1  
+               1  2  
+               3  4   
+
+: CONSTRUCTING VIRTUAL CUBE ID FROM CUBE COLORS OF PHYSICAL CUBE
+: 	THREE COLORS MEANS CORNER CUBE
+: 	TWO COLORS MEANS EDGE CUBE
+: 	ONE COLOR MEANS CENTER CUBE
+: 	NO COLOR MEANS CUBE IS INTERNAL CUBE
+
+CUBE    CUBE 		COLOR 		  CUBE	CUBE 		COLOR
+ID	POSITION	TAG		  ID	POSITION	TAG
+
+  1	(1,1,1) 	BRW		  5	(1,1,2) 	BRY
+  2	(2,1,1) 	GRW		  6	(2,1,2) 	GRY
+  3	(1,2,1) 	BOW		  7	(1,2,2) 	BOY
+  4	(2,2,1) 	GOW		  8	(2,2,2) 	GOY
+
+: MAPPING OF FACE ID TO CUBE ID
+: FACE ID IS USED TO ENTER COLOR ON A PHYSICAL CUBE FOR LOADING
+: INTO PROGRAM
+
+RUBIKS    FACE	     CUBE       RUBIKS    FACE      CUBE
+CUBE      ID         ID         CUBE      ID        ID
+FACE
+
+UpS       1          1		BackS     1          5
+UpS       2          2		BackS     2          6
+UpS       3          3		BackS     3          1
+UpS       4          4		BackS     4          2
+DownS     1          7		LeftS     1          2
+DownS     2          8		LeftS     2          6
+DownS     3          5		LeftS     3          4
+DownS     4          6		LeftS     4          8
+FrontS    1          3		RightS    1          5
+FrontS    2          4		RightS    2          1
+FrontS    3          7		RightS    3          7
+FrontS    4          8		RightS    4          3
diff --git a/design/3x3.txt b/design/3x3.txt
new file mode 100644
--- /dev/null
+++ b/design/3x3.txt
@@ -0,0 +1,158 @@
+	1       2       3
+        4       5       6
+        7       8       9
+
+        10      11      12
+        13      14      15
+        16      17      18
+
+        19      20      21
+        22      23      24
+        25      26      27
+
+
+Projection for 3x3 - Left
+
+		       UpS
+	       _____  ______ _____
+	     / 1    / 2    / 3    / \
+	    /_____ /_____ /______/ 3 \
+	   /  4   /  5   /  6   / \  /\
+	  /______/______/______/ 6 \/12\
+	 /  7   /   8  /   9  / \  /\  /\
+	/______/______/______/ 9 \/15\/21\  LeftS
+	\   7  \    8 \    9 \   /\  /\  /
+	 \______\ _____\______\ /18\/24\/
+	  \  16  \   17 \   18 \   /\  /
+	   \______\______\______\ /27\/
+	    \  25  \  26  \  27  \   /
+	     \______\______\______\ / 
+
+                     FrontS
+
+Projection for 3x3 - Right
+
+                         UpS 
+	         ______ ______ _______
+	        /\   1  \  2   \   3  \
+	       /1 \______\______\______\
+	      /\  /\  4   \  5   \  6   \
+	     /10\/4 \______\______\______\
+	    /\  /\  /\  7   \  8   \  9   \
+RightS	   /19\/13\/7 \______\______\______\
+	   \  /\  /\  /  7   /  8   /  9   /
+	    \/22\/16\/______/______/______/
+	     \  /\  /  16  /  17  /  18  /
+	      \/25\/______/______/______/
+	       \  /   25 /   26 /   27 /
+	        \/______/______/______/
+
+                         FrontS
+
+
+           BackS
+          %  %  %  
+          %  %  %  
+  RightS  %  %  %  LeftS      %  %  %    %  %  %      1   2   3  
+ %  %  %  %  %  %  %  %  %    %  %  %    %  %  %      4   5   6  
+ %  %  %  %  %  %  %  %  %    %  %  %    %  %  %      7   8   9  
+ %  %  %  %  %  %  %  %  %  
+          %  %  %             %  %  %    %  %  %     10  11  12  
+  FrontS  %  %  %  FrontS     %  %  %    %  %  %     13  14  15  
+          %  %  %             %  %  %    %  %  %     16  17  18  
+ %  %  %  %  %  %  %  %  %  
+ %  %  %  %  %  %  %  %  %    %  %  %    %  %  %     19  20  21  
+ %  %  %  %  %  %  %  %  %    %  %  %    %  %  %     22  23  24  
+          %  %  %             %  %  %    %  %  %     25  26  27  
+  RightS  %  %  %  LeftS  
+          %  %  %   
+           BackS
+
+       _____  ______ _____
+     / %    / %    / %    / \
+    /_____ /_____ /______/ % \
+   /  %   /  %   /  %   / \  /\
+  /______/______/______/ % \/ %\
+ /  %   /   %  /   %  / \  /\  /\
+/______/______/______/ % \/ %\/ %\
+\   %  \    % \    % \   /\  /\  /
+ \______\ _____\______\ / %\/ %\/
+  \  %   \   %  \   %  \   /\  /
+   \______\______\______\ / %\/
+    \  %   \  %   \  %   \   /
+     \______\______\______\ / 
+
+ 
+         ______ ______ _______
+        /\   %  \  %   \   %  \
+       /% \______\______\______\
+      /\  /\  %   \  %   \  %   \
+     /% \/% \______\______\______\
+    /\  /\  /\  %   \  %   \  %   \
+   /% \/% \/% \______\______\______\
+   \  /\  /\  /  %   /  %   /  %   /
+    \/% \/% \/______/______/______/
+     \  /\  /   %  /   %  /   %  /
+      \/% \/______/______/______/
+       \  /    % /    % /    % /
+        \/______/______/______/
+
+
+: CONSTRUCTING VIRTUAL CUBE ID FROM CUBE COLORS OF PHYSICAL CUBE
+: 	THREE COLORS MEANS CORNER CUBE
+: 	TWO COLORS MEANS EDGE CUBE
+: 	ONE COLOR MEANS CENTER CUBE
+: 	NO COLOR MEANS CUBE IS INTERNAL CUBE
+
+CUBE	CUBE 		COLOR 		CUBE	CUBE 		COLOR
+ID	POSITION	TAG		ID	POSITION	TAG
+  1	(1,1,1) 	BRW		 14	(2,2,2) 	
+  2	(2,1,1) 	RW		 15	(3,2,2) 	G
+  3	(3,1,1) 	GRW		 16	(1,3,2) 	BO
+  4	(1,2,1) 	BW		 17	(2,3,2) 	O
+  5	(2,2,1) 	W		 18	(3,3,2) 	GO
+  6	(3,2,1) 	GW		 19	(1,1,3) 	BRY
+  7	(1,3,1) 	BOW		 20	(2,1,3) 	RY
+  8	(2,3,1) 	OW		 21	(3,1,3) 	GRY
+  9	(3,3,1) 	GOW		 22	(1,2,3) 	BY
+ 10	(1,1,2) 	BR		 23	(2,2,3) 	Y
+ 11	(2,1,2) 	R		 24	(3,2,3) 	GY
+ 12	(3,1,2) 	GR		 25	(1,3,3) 	BOY
+ 13	(1,2,2) 	B		 26	(2,3,3) 	OY
+ 27	(3,3,3) 	GOY
+
+: MAPPING OF FACE ID TO CUBE ID
+: FACE ID IS USED TO ENTER COLOR ON A PHYSICAL CUBE FOR LOADING
+: INTO PROGRAM
+
+RUBIKS    FACE	     CUBE       RUBIKS    FACE      CUBE
+CUBE      ID         ID         CUBE      ID        ID
+FACE
+
+UpS       1          1		BackS     1         19
+UpS       2          2		BackS     2         20
+UpS       3          3		BackS     3         21
+UpS       4          4		BackS     4         10
+UpS       5          5		BackS     5         11
+UpS       6          6		BackS     6         12
+UpS       7          7		BackS     7          1
+UpS       8          8		BackS     8          2
+UpS       9          9		BackS     9          3
+DownS     1         25		LeftS     1          3
+DownS     2         26		LeftS     2         12
+DownS     3         27		LeftS     3         21
+DownS     4         22		LeftS     4          6
+DownS     5         23		LeftS     5         15
+DownS     6         24		LeftS     6         24
+DownS     7         19		LeftS     7          9
+DownS     8         20		LeftS     8         18
+DownS     9         21		LeftS     9         27
+FrontS    1          7		RightS    1         19
+FrontS    2          8		RightS    2         10
+FrontS    3          9		RightS    3          1
+FrontS    4         16		RightS    4         22
+FrontS    5         17		RightS    5         13
+FrontS    6         18		RightS    6          4
+FrontS    7         25		RightS    7         25
+FrontS    8         26		RightS    8         16
+FrontS    9         27		RightS    9          7
diff --git a/design/4x4.txt b/design/4x4.txt
new file mode 100644
--- /dev/null
+++ b/design/4x4.txt
@@ -0,0 +1,165 @@
+1	2	3	4
+5	6	7	8
+9	10	11	12
+13	14	15	16
+
+17	18	19	20
+21	22	23	24
+25	26	27	28
+29	30	31	32
+
+33	34	35	36
+37	38	39	40
+41	42	43	44
+45	46	47	48
+
+49	50	51	52
+53	54	55	56
+57	58	59	60
+61	62	63	64
+
+
+left 4x4
+
+                           UpS
+                 ___________________________  
+                /  1   /  2   /  3   /  4   / \  
+               /_____ /______/______/______/ 4 \  
+              /  5   /  6   /  7   /  8   / \  /\  
+             /_____ /_____ /_____ /______/ 8 \/20\  
+            /  9   /  10  /  11  /  12  / \  /\  /\  
+           /______/______/______/______/ 12\/24\/36\  
+          /  13  /  14  /  15  /  16  / \  /\  /\  /\  
+         /______/______/______/______/ 16\/28\/40\/52\     LeftS  
+         \   13 \   14 \   15 \   16 \   /\  /\  /\  /  
+          \______\ _____\______\______\ /32\/44\/56\/  
+           \  29  \  30  \  31  \ 32   \   /\  /\  /  
+            \______\______\______\______\ /48\/60\/  
+             \ 45   \ 46   \ 47   \ 48   \   /\  /  
+              \______\______\______\______\ /64\/  
+               \ 61   \ 62   \ 63   \ 64   \   /  
+                \______\______\______\______\ /  
+
+                           FrontS
+
+right 4x4
+
+			     UpS
+                  ___________________________  
+                /\  1   \  2   \  3   \  4   \  
+               /1 \______\______\______\______\  
+              /\  /\  5   \  6   \  7   \  8   \  
+             /17\/5 \______\______\______\______\  
+            /\  /\  /\  9   \ 10   \ 11   \ 12   \  
+           /33\/21\/9 \______\______\______\______\  
+          /\  /\  /\  /\ 13   \ 14   \ 15   \ 16   \  
+RightS   /49\/37\/25\/13\______\______\______\______\  
+         \  /\  /\  /\  / 13   / 14   / 15   / 16   /     
+          \/53\/41\/29\/______/______/______/______/  
+           \  /\  /\  /  29  / 30   /  31  / 32   /  
+            \/57\/45\/______/______/______/______/  
+             \  /\  /  45  /  46  /  47  /  48  /  
+              \/61\/______/______/______/______/  
+               \  /   61 /   62 /   63 /  64  /  
+                \/_____ /______/______/______/  
+
+                              FrontS
+
+: CONSTRUCTING VIRTUAL CUBE ID FROM CUBE COLORS OF PHYSICAL CUBE
+: 	THREE COLORS MEANS CORNER CUBE
+: 	TWO COLORS MEANS EDGE CUBE
+: 	ONE COLOR MEANS CENTER CUBE
+: 	NO COLOR MEANS CUBE IS INTERNAL CUBE
+
+CUBE	CUBE 		COLOR 		CUBE	CUBE 		COLOR
+ID	POSITION	TAG		ID	POSITION	TAG
+
+  1	(1,1,1) 	BRW		 33	(1,1,3) 	BR
+  2	(2,1,1) 	RW		 34	(2,1,3) 	R
+  3	(3,1,1) 	RW		 35	(3,1,3) 	R
+  4	(4,1,1) 	GRW		 36	(4,1,3) 	GR
+  5	(1,2,1) 	BW		 37	(1,2,3) 	B
+  6	(2,2,1) 	W		 38	(2,2,3) 	
+  7	(3,2,1) 	W		 39	(3,2,3) 	
+  8	(4,2,1) 	GW		 40	(4,2,3) 	G
+  9	(1,3,1) 	BW		 41	(1,3,3) 	B
+ 10	(2,3,1) 	W		 42	(2,3,3) 	
+ 11	(3,3,1) 	W		 43	(3,3,3) 	
+ 12	(4,3,1) 	GW		 44	(4,3,3) 	G
+ 13	(1,4,1) 	BOW		 45	(1,4,3) 	BO
+ 14	(2,4,1) 	OW		 46	(2,4,3) 	O
+ 15	(3,4,1) 	OW		 47	(3,4,3) 	O
+ 16	(4,4,1) 	GOW		 48	(4,4,3) 	GO
+ 17	(1,1,2) 	BR		 49	(1,1,4) 	BRY
+ 18	(2,1,2) 	R		 50	(2,1,4) 	RY
+ 19	(3,1,2) 	R		 51	(3,1,4) 	RY
+ 20	(4,1,2) 	GR		 52	(4,1,4) 	GRY
+ 21	(1,2,2) 	B		 53	(1,2,4) 	BY
+ 22	(2,2,2) 			 54	(2,2,4) 	Y
+ 23	(3,2,2) 			 55	(3,2,4) 	Y
+ 24	(4,2,2) 	G		 56	(4,2,4) 	GY
+ 25	(1,3,2) 	B		 57	(1,3,4) 	BY
+ 26	(2,3,2) 			 58	(2,3,4) 	Y
+ 27	(3,3,2) 			 59	(3,3,4) 	Y
+ 28	(4,3,2) 	G		 60	(4,3,4) 	GY
+ 29	(1,4,2) 	BO		 61	(1,4,4) 	BOY
+ 30	(2,4,2) 	O		 62	(2,4,4) 	OY
+ 31	(3,4,2) 	O		 63	(3,4,4) 	OY
+ 32	(4,4,2) 	GO		 64	(4,4,4) 	GOY
+
+: MAPPING OF FACE ID TO CUBE ID
+: FACE ID IS USED TO ENTER COLOR ON A PHYSICAL CUBE FOR LOADING
+: INTO PROGRAM
+
+RUBIKS    FACE	     CUBE       RUBIKS    FACE      CUBE
+CUBE      ID         ID         CUBE      ID        ID
+FACE
+
+UpS       1          1		BackS     1         49
+UpS       2          2		BackS     2         50
+UpS       3          3		BackS     3         51
+UpS       4          4		BackS     4         52
+UpS       5          5		BackS     5         33
+UpS       6          6		BackS     6         34
+UpS       7          7		BackS     7         35
+UpS       8          8		BackS     8         36
+UpS       9          9		BackS     9         17
+UpS       10        10		BackS     10        18
+UpS       11        11		BackS     11        19
+UpS       12        12		BackS     12        20
+UpS       13        13		BackS     13         1
+UpS       14        14		BackS     14         2
+UpS       15        15		BackS     15         3
+UpS       16        16		BackS     16         4
+DownS     1         61		LeftS     1          4
+DownS     2         62		LeftS     2         20
+DownS     3         63		LeftS     3         36
+DownS     4         64		LeftS     4         52
+DownS     5         57		LeftS     5          8
+DownS     6         58		LeftS     6         24
+DownS     7         59		LeftS     7         40
+DownS     8         60		LeftS     8         56
+DownS     9         53		LeftS     9         12
+DownS     10        54		LeftS     10        28
+DownS     11        55		LeftS     11        44
+DownS     12        56		LeftS     12        60
+DownS     13        49		LeftS     13        16
+DownS     14        50		LeftS     14        32
+DownS     15        51		LeftS     15        48
+DownS     16        52		LeftS     16        64
+FrontS    1         13		RightS    1         49
+FrontS    2         14		RightS    2         33
+FrontS    3         15		RightS    3         17
+FrontS    4         16		RightS    4          1
+FrontS    5         29		RightS    5         53
+FrontS    6         30		RightS    6         37
+FrontS    7         31		RightS    7         21
+FrontS    8         32		RightS    8          5
+FrontS    9         45		RightS    9         57
+FrontS    10        46		RightS    10        41
+FrontS    11        47		RightS    11        25
+FrontS    12        48		RightS    12         9
+FrontS    13        61		RightS    13        61
+FrontS    14        62		RightS    14        45
+FrontS    15        63		RightS    15        29
+FrontS    16        64		RightS    16        13
diff --git a/design/5x5.txt b/design/5x5.txt
new file mode 100644
--- /dev/null
+++ b/design/5x5.txt
@@ -0,0 +1,238 @@
+1	2	3	4	5
+6	7	8	9	10
+11	12	13	14	15
+16	17	18	19	20
+21	22	23	24	25
+
+26	27	28	29	30
+31	32	33	34	35
+36	37	38	39	40
+41	42	43	44	45
+46	47	48	49	50
+
+51	52	53	54	55
+56	57	58	59	60
+61	62	63	64	65
+66	67	68	69	70
+71	72	73	74	75
+
+76	77	79	79	80
+81	82	83	84	85
+86	87	88	89	90
+91	92	93	94	95
+96	97	98	99	100
+
+101	102	103	104	105
+106	107	108	109	110
+111	112	113	114	115
+116	117	118	119	120
+121	122	123	124	125
+
+left 5x5
+				UpS
+                   ___________________________________  
+                  /  1   /  2   /  3   /  4   /  5   / \  
+                 /_____ /______/______/______/______/ 5 \  
+                /  6   /  7   /  8   /  9   /  10  / \  /\  
+               /_____ /_____ /_____ /______/______/ 10\/30\  
+              /  11  /  12  /  13  /  14  /  15  / \  /\  /\  
+             /_____ /_____ /_____ /______/______/ 15\/35\/55\  
+            /  16  / 17   /  18  /  19  /  20  / \  /\  /\  /\  
+           /______/______/______/______/______/ 20\/40\/60\/80\  
+          /  21  /  22  /  23  / 24   /  25  / \  /\  /\  /\  /\  
+         /______/______/______/______/______/ 25\/45\/65\/85\/10\  LeftS 
+         \   21 \  22  \  23  \  24  \  25  \   /\  /\  /\  /\ 5/  
+          \______\ _____\______\______\______\ /50\/70\/90\/11\/   
+           \  46  \  47  \  48  \  49  \  50  \   /\  /\  /\ 0/  
+            \______\______\______\______\______\ /75\/95\/11\/  
+             \  71  \  72  \  73  \  74  \ 75   \   /\  /\ 5/  
+              \______\______\______\______\______\ /10\/12\/  
+               \  96  \  97  \  98  \  99  \ 100  \  0/\ 0/  
+                \______\______\______\______\______\ /12\/  
+                 \ 121  \ 122  \ 123  \ 124  \ 125  \  5/  
+                  \______\______\______\______\______\ /  
+
+                              FrontS
+
+right 5x5
+
+                                  UpS
+                   ___________________________________  
+                  /\  1   \  2   \  3   \  4   \  5   \  
+                 /1 \______\______\______\______\______\  
+                /\  /\  6   \  7   \  8   \  9   \ 10   \  
+               /26\/6 \______\______\______\______\______\  
+              /\  /\  /\ 11   \ 12   \ 13   \ 14   \ 15   \  
+             /51\/31\/11\______\______\______\______\______\  
+            /\  /\  /\  /\ 16   \ 17   \ 18   \ 19   \ 20   \  
+           /76\/56\/36\/16\______\______\______\______\______\  
+          /\  /\  /\  /\  /\ 21   \ 22   \ 23   \ 24   \ 25   \  
+RightS   /10\/81\/61\/41\/21\______\______\______\______\______\  
+         \ 1/\  /\  /\  /\  / 21   / 22   / 23   / 24   / 25   /  
+          \/10\/86\/66\/46\/______/______/______/______/______/  
+           \ 6/\  /\  /\  /  46  /  47  /  48  /  49  /  50  /  
+            \/11\/91\/71\/______/______/______/______/______/  
+             \ 1/\  /\  /  71  /  72  /  73  /  74  /  75  /  
+              \/11\/96\/______/______/______/______/______/  
+               \ 6/\  /  96  /  97  /  98  /  99  / 100  /  
+                \/12\/______/______/______/______/______/  
+                 \ 1/  121 /  122 /  123 /  124 /  125 /  
+                  \/_____ /______/______/______/______/  
+
+
+: CONSTRUCTING VIRTUAL CUBE ID FROM CUBE COLORS OF PHYSICAL CUBE
+: 	THREE COLORS MEANS CORNER CUBE
+: 	TWO COLORS MEANS EDGE CUBE
+: 	ONE COLOR MEANS CENTER CUBE
+: 	NO COLOR MEANS CUBE IS INTERNAL CUBE
+
+CUBE	CUBE 		COLOR 		CUBE	CUBE 		COLOR
+ID	POSITION	TAG		ID	POSITION	TAG
+
+  1	(1,1,1) 	BRW		 63	(3,3,3) 	
+  2	(2,1,1) 	RW		 64	(4,3,3) 	
+  3	(3,1,1) 	RW		 65	(5,3,3) 	G
+  4	(4,1,1) 	RW		 66	(1,4,3) 	B
+  5	(5,1,1) 	GRW		 67	(2,4,3) 	
+  6	(1,2,1) 	BW		 68	(3,4,3) 	
+  7	(2,2,1) 	W		 69	(4,4,3) 	
+  8	(3,2,1) 	W		 70	(5,4,3) 	G
+  9	(4,2,1) 	W		 71	(1,5,3) 	BO
+ 10	(5,2,1) 	GW		 72	(2,5,3) 	O
+ 11	(1,3,1) 	BW		 73	(3,5,3) 	O
+ 12	(2,3,1) 	W		 74	(4,5,3) 	O
+ 13	(3,3,1) 	W		 75	(5,5,3) 	GO
+ 14	(4,3,1) 	W		 76	(1,1,4) 	BR
+ 15	(5,3,1) 	GW		 77	(2,1,4) 	R
+ 16	(1,4,1) 	BW		 78	(3,1,4) 	R
+ 17	(2,4,1) 	W		 79	(4,1,4) 	R
+ 18	(3,4,1) 	W		 80	(5,1,4) 	GR
+ 19	(4,4,1) 	W		 81	(1,2,4) 	B
+ 20	(5,4,1) 	GW		 82	(2,2,4) 	
+ 21	(1,5,1) 	BOW		 83	(3,2,4) 	
+ 22	(2,5,1) 	OW		 84	(4,2,4) 	
+ 23	(3,5,1) 	OW		 85	(5,2,4) 	G
+ 24	(4,5,1) 	OW		 86	(1,3,4) 	B
+ 25	(5,5,1) 	GOW		 87	(2,3,4) 	
+ 26	(1,1,2) 	BR		 88	(3,3,4) 	
+ 27	(2,1,2) 	R		 89	(4,3,4) 	
+ 28	(3,1,2) 	R		 90	(5,3,4) 	G
+ 29	(4,1,2) 	R		 91	(1,4,4) 	B
+ 30	(5,1,2) 	GR		 92	(2,4,4) 	
+ 31	(1,2,2) 	B		 93	(3,4,4) 	
+ 32	(2,2,2) 			 94	(4,4,4) 	
+ 33	(3,2,2) 			 95	(5,4,4) 	G
+ 34	(4,2,2) 			 96	(1,5,4) 	BO
+ 35	(5,2,2) 	G		 97	(2,5,4) 	O
+ 36	(1,3,2) 	B		 98	(3,5,4) 	O
+ 37	(2,3,2) 			 99	(4,5,4) 	O
+ 38	(3,3,2) 			100	(5,5,4) 	GO
+ 39	(4,3,2) 			101	(1,1,5) 	BRY
+ 40	(5,3,2) 	G		102	(2,1,5) 	RY
+ 41	(1,4,2) 	B		103	(3,1,5) 	RY
+ 42	(2,4,2) 			104	(4,1,5) 	RY
+ 43	(3,4,2) 			105	(5,1,5) 	GRY
+ 44	(4,4,2) 			106	(1,2,5) 	BY
+ 45	(5,4,2) 	G		107	(2,2,5) 	Y
+ 46	(1,5,2) 	BO		108	(3,2,5) 	Y
+ 47	(2,5,2) 	O		109	(4,2,5) 	Y
+ 48	(3,5,2) 	O		110	(5,2,5) 	GY
+ 49	(4,5,2) 	O		111	(1,3,5) 	BY
+ 50	(5,5,2) 	GO		112	(2,3,5) 	Y
+ 51	(1,1,3) 	BR		113	(3,3,5) 	Y
+ 52	(2,1,3) 	R		114	(4,3,5) 	Y
+ 53	(3,1,3) 	R		115	(5,3,5) 	GY
+ 54	(4,1,3) 	R		116	(1,4,5) 	BY
+ 55	(5,1,3) 	GR		117	(2,4,5) 	Y
+ 56	(1,2,3) 	B		118	(3,4,5) 	Y
+ 57	(2,2,3) 			119	(4,4,5) 	Y
+ 58	(3,2,3) 			120	(5,4,5) 	GY
+ 59	(4,2,3) 			121	(1,5,5) 	BOY
+ 60	(5,2,3) 	G		122	(2,5,5) 	OY
+ 61	(1,3,3) 	B		123	(3,5,5) 	OY
+ 62	(2,3,3) 			124	(4,5,5) 	OY
+125	(5,5,5) 	GOY
+
+: MAPPING OF FACE ID TO CUBE ID
+: FACE ID IS USED TO ENTER COLOR ON A PHYSICAL CUBE FOR LOADING
+: INTO PROGRAM
+
+RUBIKS    FACE	     CUBE       RUBIKS    FACE      CUBE
+CUBE      ID         ID         CUBE      ID        ID
+FACE
+
+UpS       1          1		BackS     1         101
+UpS       2          2		BackS     2         102
+UpS       3          3		BackS     3         103
+UpS       4          4		BackS     4         104
+UpS       5          5		BackS     5         105
+UpS       6          6		BackS     6         76
+UpS       7          7		BackS     7         77
+UpS       8          8		BackS     8         78
+UpS       9          9		BackS     9         79
+UpS       10        10		BackS     10        80
+UpS       11        11		BackS     11        51
+UpS       12        12		BackS     12        52
+UpS       13        13		BackS     13        53
+UpS       14        14		BackS     14        54
+UpS       15        15		BackS     15        55
+UpS       16        16		BackS     16        26
+UpS       17        17		BackS     17        27
+UpS       18        18		BackS     18        28
+UpS       19        19		BackS     19        29
+UpS       20        20		BackS     20        30
+UpS       21        21		BackS     21         1
+UpS       22        22		BackS     22         2
+UpS       23        23		BackS     23         3
+UpS       24        24		BackS     24         4
+UpS       25        25		BackS     25         5
+DownS     1         121		LeftS     1          5
+DownS     2         122		LeftS     2         30
+DownS     3         123		LeftS     3         55
+DownS     4         124		LeftS     4         80
+DownS     5         125		LeftS     5         105
+DownS     6         116		LeftS     6         10
+DownS     7         117		LeftS     7         35
+DownS     8         118		LeftS     8         60
+DownS     9         119		LeftS     9         85
+DownS     10        120		LeftS     10        110
+DownS     11        111		LeftS     11        15
+DownS     12        112		LeftS     12        40
+DownS     13        113		LeftS     13        65
+DownS     14        114		LeftS     14        90
+DownS     15        115		LeftS     15        115
+DownS     16        106		LeftS     16        20
+DownS     17        107		LeftS     17        45
+DownS     18        108		LeftS     18        70
+DownS     19        109		LeftS     19        95
+DownS     20        110		LeftS     20        120
+DownS     21        101		LeftS     21        25
+DownS     22        102		LeftS     22        50
+DownS     23        103		LeftS     23        75
+DownS     24        104		LeftS     24        100
+DownS     25        105		LeftS     25        125
+FrontS    1         21		RightS    1         101
+FrontS    2         22		RightS    2         76
+FrontS    3         23		RightS    3         51
+FrontS    4         24		RightS    4         26
+FrontS    5         25		RightS    5          1
+FrontS    6         46		RightS    6         106
+FrontS    7         47		RightS    7         81
+FrontS    8         48		RightS    8         56
+FrontS    9         49		RightS    9         31
+FrontS    10        50		RightS    10         6
+FrontS    11        71		RightS    11        111
+FrontS    12        72		RightS    12        86
+FrontS    13        73		RightS    13        61
+FrontS    14        74		RightS    14        36
+FrontS    15        75		RightS    15        11
+FrontS    16        96		RightS    16        116
+FrontS    17        97		RightS    17        91
+FrontS    18        98		RightS    18        66
+FrontS    19        99		RightS    19        41
+FrontS    20        100		RightS    20        16
+FrontS    21        121		RightS    21        121
+FrontS    22        122		RightS    22        96
+FrontS    23        123		RightS    23        71
+FrontS    24        124		RightS    24        46
+FrontS    25        125		RightS    25        21
diff --git a/design/common.txt b/design/common.txt
new file mode 100644
--- /dev/null
+++ b/design/common.txt
@@ -0,0 +1,634 @@
+: CUBE AXIS
+COLOR ASSIGNMENT
+
+   R
+   | 
+B--W--G
+   |
+   O
+   |
+B--Y--G
+   |
+   R
+
+: COLOR MAPPING
+SIDE    VECTOR   COLOR
+UpS     (0,0,1)  W
+DownS   (0,0,-1) Y
+FrontS  (0,-1,0) O
+BackS   (0,1,0)  R
+LeftS   (-1,0,0) G
+RightS  (1,0,0)  B
+
+: DEFINITION OF CUBE ORIENTATION
+VECTOR 1   VECTOR 2   FACE 1	FACE 2    COLOR	RAW	ORIENT	IDS
+(0,0,1)    (0,-1,0)   UpS       FrontS    WO   -935      1   a
+(0,1,0)    (0,0,-1)   BackS     DownS     RY   -663      2   b
+(0,0,1)    (-1,0,0)   UpS       LeftS     WG   -595      3   c
+(1,0,0)    (0,0,-1)   RightS    DownS     BY   -442      4   d
+(1,0,0)    (0,-1,0)   RightS    FrontS    BO   -374      5   e
+(0,1,0)    (-1,0,0)   BackS     LeftS     RG   -357      6   f
+(0,0,-1)   (0,1,0)    DownS     BackS     YR    -55      7   g
+(0,-1,0)   (0,0,1)    FrontS    UpS       OW    -39      8   h
+(0,0,-1)   (1,0,0)    DownS     RightS    YB    -35      9   i
+(-1,0,0)   (0,0,1)    LeftS     UpS       GW    -26     10   j
+(-1,0,0)   (0,1,0)    LeftS     BackS     GR    -22     11   k
+(0,-1,0)   (1,0,0)    FrontS    RightS    OB    -21     12   l
+(0,1,0)    (1,0,0)    BackS     RightS    RB     21     13   m
+(1,0,0)    (0,1,0)    RightS    BackS     BR     22     14   n
+(1,0,0)    (0,0,1)    RightS    UpS       BW     26     15   o
+(0,0,1)    (1,0,0)    UpS       RightS    WB     35     16   p
+(0,1,0)    (0,0,1)    BackS     UpS       RW     39     17   q
+(0,0,1)    (0,1,0)    UpS       BackS     WR     55     18   r
+(0,-1,0)   (-1,0,0)   FrontS    LeftS     OG    357     19   s
+(-1,0,0)   (0,-1,0)   LeftS     FrontS    GO    374     20   t
+(-1,0,0)   (0,0,-1)   LeftS     DownS     GY    442     21   u
+(0,0,-1)   (-1,0,0)   DownS     LeftS     YG    595     22   v
+(0,-1,0)   (0,0,-1)   FrontS    DownS     OY    663     23   w
+(0,0,-1)   (0,-1,0)   DownS     FrontS    YO    935     24   x
+
+: CUBE ORIENTATION VIEWED AS A TRANSFORMATION OF CUBE FACE
+: FROM IDENTITY ORIENTATION n
+ID  SIDE    GOES TO             ID  SIDE    GOES TO
+a   UpS     RightS  		m   UpS     DownS   
+a   DownS   LeftS   		m   DownS   UpS     
+a   FrontS  BackS   		m   FrontS  LeftS   
+a   BackS   FrontS  		m   BackS   RightS  
+a   LeftS   DownS   		m   LeftS   FrontS  
+a   RightS  UpS     		m   RightS  BackS   
+b   UpS     LeftS   		n   UpS     UpS     
+b   DownS   RightS  		n   DownS   DownS   
+b   FrontS  UpS     		n   FrontS  FrontS  
+b   BackS   DownS   		n   BackS   BackS   
+b   LeftS   FrontS  		n   LeftS   LeftS   
+b   RightS  BackS   		n   RightS  RightS  
+c   UpS     FrontS  		o   UpS     FrontS  
+c   DownS   BackS   		o   DownS   BackS   
+c   FrontS  RightS  		o   FrontS  DownS   
+c   BackS   LeftS   		o   BackS   UpS     
+c   LeftS   DownS   		o   LeftS   LeftS   
+c   RightS  UpS     		o   RightS  RightS  
+d   UpS     BackS   		p   UpS     BackS   
+d   DownS   FrontS  		p   DownS   FrontS  
+d   FrontS  UpS     		p   FrontS  LeftS   
+d   BackS   DownS   		p   BackS   RightS  
+d   LeftS   LeftS   		p   LeftS   DownS   
+d   RightS  RightS  		p   RightS  UpS     
+e   UpS     DownS   		q   UpS     RightS  
+e   DownS   UpS     		q   DownS   LeftS   
+e   FrontS  BackS   		q   FrontS  DownS   
+e   BackS   FrontS  		q   BackS   UpS     
+e   LeftS   LeftS   		q   LeftS   FrontS  
+e   RightS  RightS  		q   RightS  BackS   
+f   UpS     UpS     		r   UpS     LeftS   
+f   DownS   DownS   		r   DownS   RightS  
+f   FrontS  RightS  		r   FrontS  FrontS  
+f   BackS   LeftS   		r   BackS   BackS   
+f   LeftS   FrontS  		r   LeftS   DownS   
+f   RightS  BackS   		r   RightS  UpS     
+g   UpS     RightS  		s   UpS     DownS   
+g   DownS   LeftS   		s   DownS   UpS     
+g   FrontS  FrontS  		s   FrontS  RightS  
+g   BackS   BackS   		s   BackS   LeftS   
+g   LeftS   UpS     		s   LeftS   BackS   
+g   RightS  DownS   		s   RightS  FrontS  
+h   UpS     LeftS   		t   UpS     UpS     
+h   DownS   RightS  		t   DownS   DownS   
+h   FrontS  DownS   		t   FrontS  BackS   
+h   BackS   UpS     		t   BackS   FrontS  
+h   LeftS   BackS   		t   LeftS   RightS  
+h   RightS  FrontS  		t   RightS  LeftS   
+i   UpS     FrontS  		u   UpS     FrontS  
+i   DownS   BackS   		u   DownS   BackS   
+i   FrontS  LeftS   		u   FrontS  UpS     
+i   BackS   RightS  		u   BackS   DownS   
+i   LeftS   UpS     		u   LeftS   RightS  
+i   RightS  DownS   		u   RightS  LeftS   
+j   UpS     BackS   		v   UpS     BackS   
+j   DownS   FrontS  		v   DownS   FrontS  
+j   FrontS  DownS   		v   FrontS  RightS  
+j   BackS   UpS     		v   BackS   LeftS   
+j   LeftS   RightS  		v   LeftS   UpS     
+j   RightS  LeftS   		v   RightS  DownS   
+k   UpS     DownS   		w   UpS     RightS  
+k   DownS   UpS     		w   DownS   LeftS   
+k   FrontS  FrontS  		w   FrontS  UpS     
+k   BackS   BackS   		w   BackS   DownS   
+k   LeftS   RightS  		w   LeftS   BackS   
+k   RightS  LeftS   		w   RightS  FrontS  
+l   UpS     UpS     		x   UpS     LeftS   
+l   DownS   DownS   		x   DownS   RightS  
+l   FrontS  LeftS   		x   FrontS  BackS   
+l   BackS   RightS  		x   BackS   FrontS  
+l   LeftS   BackS   		x   LeftS   UpS     
+l   RightS  FrontS  		x   RightS  DownS
+
+
+: ORIENTATION TRANSFORMATION MATRICES 
+ID    COLUMN 1    COLUMN 2    COLUMN 3  DET
+a     0  0  1     0 -1  0     1  0  0	1
+b     0  1  0     0  0 -1    -1  0  0	1
+c     0  0  1    -1  0  0     0 -1  0	1
+d     1  0  0     0  0 -1     0  1  0	1
+e     1  0  0     0 -1  0     0  0 -1	1
+f     0  1  0    -1  0  0     0  0  1	1
+g     0  0 -1     0  1  0     1  0  0	1
+h     0 -1  0     0  0  1    -1  0  0	1
+i     0  0 -1     1  0  0     0 -1  0	1
+j    -1  0  0     0  0  1     0  1  0	1
+k    -1  0  0     0  1  0     0  0 -1	1
+l     0 -1  0     1  0  0     0  0  1	1
+m     0  1  0     1  0  0     0  0 -1	1
+n     1  0  0     0  1  0     0  0  1	1
+o     1  0  0     0  0  1     0 -1  0	1
+p     0  0  1     1  0  0     0  1  0	1
+q     0  1  0     0  0  1     1  0  0	1
+r     0  0  1     0  1  0    -1  0  0	1
+s     0 -1  0    -1  0  0     0  0 -1	1
+t    -1  0  0     0 -1  0     0  0  1	1
+u    -1  0  0     0  0 -1     0 -1  0	1
+v     0  0 -1    -1  0  0     0  1  0	1
+w     0 -1  0     0  0 -1     1  0  0	1
+x     0  0 -1     0 -1  0    -1  0  0	1
+
+
+a     0  0  1     0 -1  0     1  0  0	1
+b     0  1  0     0  0 -1    -1  0  0	1
+c     0  0  1    -1  0  0     0 -1  0	1
+d     1  0  0     0  0 -1     0  1  0	1
+e     1  0  0     0 -1  0     0  0 -1	1
+f     0  1  0    -1  0  0     0  0  1	1
+g     0  0 -1     0  1  0     1  0  0	1
+h     0 -1  0     0  0  1    -1  0  0	1
+i     0  0 -1     1  0  0     0 -1  0	1
+j    -1  0  0     0  0  1     0  1  0	1
+k    -1  0  0     0  1  0     0  0 -1	1
+l     0 -1  0     1  0  0     0  0  1	1
+m     0  1  0     1  0  0     0  0 -1	1
+n     1  0  0     0  1  0     0  0  1	1
+o     1  0  0     0  0  1     0 -1  0	1
+p     0  0  1     1  0  0     0  1  0	1
+q     0  1  0     0  0  1     1  0  0	1
+r     0  0  1     0  1  0    -1  0  0	1
+s     0 -1  0    -1  0  0     0  0 -1	1
+t    -1  0  0     0 -1  0     0  0  1	1
+u    -1  0  0     0  0 -1     0 -1  0	1
+v     0  0 -1    -1  0  0     0  1  0	1
+w     0 -1  0     0  0 -1     1  0  0	1
+x     0  0 -1     0 -1  0    -1  0  0	1
+
+: INVERSE TABLE FOR ORIENT GROUP
+inv a = a		inv m = m
+inv b = i		inv n = n
+inv c = w		inv o = d
+inv d = o		inv p = q
+inv e = e		inv q = p
+inv f = l		inv r = g
+inv g = r		inv s = s
+inv h = v		inv t = t
+inv i = b		inv u = u
+inv j = j		inv v = h
+inv k = k		inv w = c
+inv l = f		inv x = x
+
+: MULTIPLICATION TABLE FOR ORIENT GROUP
+a x a = n	m x a = v	g x a = e	s x a = i
+a x b = s	m x b = o	g x b = f	s x b = j
+a x c = d	m x c = x	g x c = o	s x c = g
+a x d = c	m x d = q	g x d = v	s x d = h
+a x e = r	m x e = f	g x e = x	s x e = l
+a x f = w	m x f = e	g x f = q	s x f = k
+a x g = t	m x g = p	g x g = k	s x g = c
+a x h = m	m x h = u	g x h = l	s x h = d
+a x i = j	m x i = r	g x i = u	s x i = a
+a x j = i	m x j = w	g x j = p	s x j = b
+a x k = x	m x k = l	g x k = r	s x k = f
+a x l = q	m x l = k	g x l = w	s x l = e
+a x m = h	m x m = n	g x m = b	s x m = t
+a x n = a	m x n = m	g x n = g	s x n = s
+a x o = p	m x o = b	g x o = i	s x o = w
+a x p = o	m x p = g	g x p = d	s x p = x
+a x q = l	m x q = d	g x q = m	s x q = u
+a x r = e	m x r = i	g x r = n	s x r = v
+a x s = b	m x s = t	g x s = h	s x s = n
+a x t = g	m x t = s	g x t = a	s x t = m
+a x u = v	m x u = h	g x u = c	s x u = q
+a x v = u	m x v = a	g x v = j	s x v = r
+a x w = f	m x w = j	g x w = s	s x w = o
+a x x = k	m x x = c	g x x = t	s x x = p
+b x a = j	n x a = a	h x a = u	t x a = r
+b x b = i	n x b = b	h x b = p	t x b = w
+b x c = t	n x c = c	h x c = k	t x c = p
+b x d = m	n x d = d	h x d = l	t x d = u
+b x e = q	n x e = e	h x e = w	t x e = k
+b x f = x	n x f = f	h x f = r	t x f = l
+b x g = d	n x g = g	h x g = o	t x g = x
+b x h = c	n x h = h	h x h = v	t x h = q
+b x i = n	n x i = i	h x i = e	t x i = v
+b x j = s	n x j = j	h x j = f	t x j = o
+b x k = w	n x k = k	h x k = q	t x k = e
+b x l = r	n x l = l	h x l = x	t x l = f
+b x m = g	n x m = m	h x m = a	t x m = s
+b x n = b	n x n = n	h x n = h	t x n = t
+b x o = f	n x o = o	h x o = s	t x o = j
+b x p = k	n x p = p	h x p = t	t x p = c
+b x q = v	n x q = q	h x q = c	t x q = h
+b x r = u	n x r = r	h x r = j	t x r = a
+b x s = a	n x s = s	h x s = g	t x s = m
+b x t = h	n x t = t	h x t = b	t x t = n
+b x u = l	n x u = u	h x u = m	t x u = d
+b x v = e	n x v = v	h x v = n	t x v = i
+b x w = p	n x w = w	h x w = i	t x w = b
+b x x = o	n x x = x	h x x = d	t x x = g
+c x a = l	o x a = w	i x a = s	u x a = h
+c x b = k	o x b = r	i x b = n	u x b = g
+c x c = w	o x c = s	i x c = h	u x c = l
+c x d = r	o x d = n	i x d = g	u x d = k
+c x e = p	o x e = d	i x e = v	u x e = j
+c x f = u	o x f = c	i x f = o	u x f = i
+c x g = f	o x g = q	i x g = m	u x g = b
+c x h = e	o x h = x	i x h = t	u x h = a
+c x i = q	o x i = m	i x i = b	u x i = f
+c x j = x	o x j = t	i x j = a	u x j = e
+c x k = v	o x k = j	i x k = p	u x k = d
+c x l = o	o x l = i	i x l = u	u x l = c
+c x m = j	o x m = p	i x m = d	u x m = v
+c x n = c	o x n = o	i x n = i	u x n = u
+c x o = a	o x o = e	i x o = x	u x o = t
+c x p = h	o x p = l	i x p = w	u x p = s
+c x q = t	o x q = a	i x q = e	u x q = x
+c x r = s	o x r = h	i x r = l	u x r = w
+c x s = d	o x s = v	i x s = j	u x s = p
+c x t = i	o x t = u	i x t = c	u x t = o
+c x u = g	o x u = k	i x u = r	u x u = n
+c x v = b	o x v = f	i x v = q	u x v = m
+c x w = n	o x w = g	i x w = k	u x w = r
+c x x = m	o x x = b	i x x = f	u x x = q
+d x a = q	p x a = f	j x a = b	v x a = m
+d x b = x	p x b = e	j x b = a	v x b = t
+d x c = f	p x c = b	j x c = m	v x c = q
+d x d = e	p x d = a	j x d = t	v x d = x
+d x e = o	p x e = c	j x e = u	v x e = i
+d x f = v	p x f = d	j x f = p	v x f = j
+d x g = w	p x g = l	j x g = h	v x g = s
+d x h = r	p x h = k	j x h = g	v x h = n
+d x i = l	p x i = h	j x i = s	v x i = w
+d x j = k	p x j = g	j x j = n	v x j = r
+d x k = u	p x k = i	j x k = o	v x k = c
+d x l = p	p x l = j	j x l = v	v x l = d
+d x m = i	p x m = o	j x m = c	v x m = u
+d x n = d	p x n = p	j x n = j	v x n = v
+d x o = n	p x o = r	j x o = k	v x o = g
+d x p = m	p x p = q	j x p = f	v x p = b
+d x q = g	p x q = n	j x q = r	v x q = k
+d x r = b	p x r = m	j x r = q	v x r = f
+d x s = c	p x s = u	j x s = i	v x s = o
+d x t = j	p x t = v	j x t = d	v x t = p
+d x u = t	p x u = x	j x u = e	v x u = a
+d x v = s	p x v = w	j x v = l	v x v = h
+d x w = a	p x w = t	j x w = x	v x w = e
+d x x = h	p x x = s	j x x = w	v x x = l
+e x a = g	q x a = d	k x a = x	w x a = o
+e x b = h	q x b = c	k x b = q	w x b = v
+e x c = v	q x c = e	k x c = i	w x c = n
+e x d = o	q x d = f	k x d = j	w x d = s
+e x e = n	q x e = b	k x e = t	w x e = h
+e x f = s	q x f = a	k x f = m	w x f = g
+e x g = a	q x g = j	k x g = r	w x g = u
+e x h = b	q x h = i	k x h = w	w x h = p
+e x i = p	q x i = k	k x i = c	w x i = t
+e x j = u	q x j = l	k x j = d	w x j = m
+e x k = t	q x k = h	k x k = n	w x k = b
+e x l = m	q x l = g	k x l = s	w x l = a
+e x m = l	q x m = r	k x m = f	w x m = x
+e x n = e	q x n = q	k x n = k	w x n = w
+e x o = d	q x o = m	k x o = u	w x o = l
+e x p = i	q x p = n	k x p = v	w x p = e
+e x q = w	q x q = p	k x q = b	w x q = i
+e x r = x	q x r = o	k x r = g	w x r = d
+e x s = f	q x s = x	k x s = l	w x s = r
+e x t = k	q x t = w	k x t = e	w x t = q
+e x u = j	q x u = s	k x u = o	w x u = f
+e x v = c	q x v = t	k x v = p	w x v = k
+e x w = q	q x w = v	k x w = h	w x w = c
+e x x = r	q x x = u	k x x = a	w x x = j
+f x a = p	r x a = t	l x a = c	x x a = k
+f x b = u	r x b = m	l x b = d	x x b = l
+f x c = a	r x c = u	l x c = r	x x c = j
+f x d = b	r x d = p	l x d = w	x x d = i
+f x e = m	r x e = a	l x e = s	x x e = g
+f x f = t	r x f = b	l x f = n	x x f = h
+f x g = v	r x g = n	l x g = i	x x g = e
+f x h = o	r x h = s	l x h = j	x x h = f
+f x i = g	r x i = o	l x i = x	x x i = d
+f x j = h	r x j = v	l x j = q	x x j = c
+f x k = s	r x k = g	l x k = m	x x k = a
+f x l = n	r x l = h	l x l = t	x x l = b
+f x m = k	r x m = q	l x m = e	x x m = w
+f x n = f	r x n = r	l x n = l	x x n = x
+f x o = q	r x o = c	l x o = h	x x o = v
+f x p = r	r x p = j	l x p = a	x x p = u
+f x q = j	r x q = f	l x q = o	x x q = s
+f x r = c	r x r = k	l x r = p	x x r = t
+f x s = e	r x s = w	l x s = k	x x s = q
+f x t = l	r x t = x	l x t = f	x x t = r
+f x u = w	r x u = i	l x u = b	x x u = p
+f x v = x	r x v = d	l x v = g	x x v = o
+f x w = d	r x w = l	l x w = u	x x w = m
+f x x = i	r x x = e	l x x = v	x x x = n 
+
+: CONSTRUCTION OF VIRTUAL CUBE ORIENTATION FROM PHYSICAL CUBE
+C1	Two colors on cube, one and two respectively.
+C2	Identity face position for color 1.	
+C3	Identity face position for color 2.
+C4	Calculated cube orientation.  288 = 24 * 12 ROWS
+
+C1  C2	     C3      C4         C1  C2       C3      C4
+BO  BackS    DownS   q		RB  BackS    DownS   g
+BO  BackS    LeftS   m		RB  BackS    LeftS   k
+BO  BackS    RightS  f		RB  BackS    RightS  n
+BO  BackS    UpS     b		RB  BackS    UpS     r
+BO  DownS    BackS   x		RB  DownS    BackS   b
+BO  DownS    FrontS  g		RB  DownS    FrontS  w
+BO  DownS    LeftS   i		RB  DownS    LeftS   u
+BO  DownS    RightS  v		RB  DownS    RightS  d
+BO  FrontS   DownS   h		RB  FrontS   DownS   x
+BO  FrontS   LeftS   l		RB  FrontS   LeftS   t
+BO  FrontS   RightS  s		RB  FrontS   RightS  e
+BO  FrontS   UpS     w		RB  FrontS   UpS     a
+BO  LeftS    BackS   t		RB  LeftS    BackS   f
+BO  LeftS    DownS   j		RB  LeftS    DownS   v
+BO  LeftS    FrontS  k		RB  LeftS    FrontS  s
+BO  LeftS    UpS     u		RB  LeftS    UpS     c
+BO  RightS   BackS   e		RB  RightS   BackS   m
+BO  RightS   DownS   o		RB  RightS   DownS   i
+BO  RightS   FrontS  n		RB  RightS   FrontS  l
+BO  RightS   UpS     d		RB  RightS   UpS     p
+BO  UpS      BackS   a		RB  UpS      BackS   q
+BO  UpS      FrontS  r		RB  UpS      FrontS  h
+BO  UpS      LeftS   p		RB  UpS      LeftS   j
+BO  UpS      RightS  c		RB  UpS      RightS  o
+BR  BackS    DownS   b		RG  BackS    DownS   r
+BR  BackS    LeftS   f		RG  BackS    LeftS   n
+BR  BackS    RightS  m		RG  BackS    RightS  k
+BR  BackS    UpS     q		RG  BackS    UpS     g
+BR  DownS    BackS   g		RG  DownS    BackS   w
+BR  DownS    FrontS  x		RG  DownS    FrontS  b
+BR  DownS    LeftS   v		RG  DownS    LeftS   d
+BR  DownS    RightS  i		RG  DownS    RightS  u
+BR  FrontS   DownS   w		RG  FrontS   DownS   a
+BR  FrontS   LeftS   s		RG  FrontS   LeftS   e
+BR  FrontS   RightS  l		RG  FrontS   RightS  t
+BR  FrontS   UpS     h		RG  FrontS   UpS     x
+BR  LeftS    BackS   k		RG  LeftS    BackS   s
+BR  LeftS    DownS   u		RG  LeftS    DownS   c
+BR  LeftS    FrontS  t		RG  LeftS    FrontS  f
+BR  LeftS    UpS     j		RG  LeftS    UpS     v
+BR  RightS   BackS   n		RG  RightS   BackS   l
+BR  RightS   DownS   d		RG  RightS   DownS   p
+BR  RightS   FrontS  e		RG  RightS   FrontS  m
+BR  RightS   UpS     o		RG  RightS   UpS     i
+BR  UpS      BackS   r		RG  UpS      BackS   h
+BR  UpS      FrontS  a		RG  UpS      FrontS  q
+BR  UpS      LeftS   c		RG  UpS      LeftS   o
+BR  UpS      RightS  p		RG  UpS      RightS  j
+BW  BackS    DownS   m		RW  BackS    DownS   k
+BW  BackS    LeftS   b		RW  BackS    LeftS   r
+BW  BackS    RightS  q		RW  BackS    RightS  g
+BW  BackS    UpS     f		RW  BackS    UpS     n
+BW  DownS    BackS   v		RW  DownS    BackS   d
+BW  DownS    FrontS  i		RW  DownS    FrontS  u
+BW  DownS    LeftS   x		RW  DownS    LeftS   b
+BW  DownS    RightS  g		RW  DownS    RightS  w
+BW  FrontS   DownS   s		RW  FrontS   DownS   e
+BW  FrontS   LeftS   h		RW  FrontS   LeftS   x
+BW  FrontS   RightS  w		RW  FrontS   RightS  a
+BW  FrontS   UpS     l		RW  FrontS   UpS     t
+BW  LeftS    BackS   j		RW  LeftS    BackS   v
+BW  LeftS    DownS   k		RW  LeftS    DownS   s
+BW  LeftS    FrontS  u		RW  LeftS    FrontS  c
+BW  LeftS    UpS     t		RW  LeftS    UpS     f
+BW  RightS   BackS   d		RW  RightS   BackS   p
+BW  RightS   DownS   e		RW  RightS   DownS   m
+BW  RightS   FrontS  o		RW  RightS   FrontS  i
+BW  RightS   UpS     n		RW  RightS   UpS     l
+BW  UpS      BackS   p		RW  UpS      BackS   j
+BW  UpS      FrontS  c		RW  UpS      FrontS  o
+BW  UpS      LeftS   r		RW  UpS      LeftS   h
+BW  UpS      RightS  a		RW  UpS      RightS  q
+BY  BackS    DownS   f		RY  BackS    DownS   n
+BY  BackS    LeftS   q		RY  BackS    LeftS   g
+BY  BackS    RightS  b		RY  BackS    RightS  r
+BY  BackS    UpS     m		RY  BackS    UpS     k
+BY  DownS    BackS   i		RY  DownS    BackS   u
+BY  DownS    FrontS  v		RY  DownS    FrontS  d
+BY  DownS    LeftS   g		RY  DownS    LeftS   w
+BY  DownS    RightS  x		RY  DownS    RightS  b
+BY  FrontS   DownS   l		RY  FrontS   DownS   t
+BY  FrontS   LeftS   w		RY  FrontS   LeftS   a
+BY  FrontS   RightS  h		RY  FrontS   RightS  x
+BY  FrontS   UpS     s		RY  FrontS   UpS     e
+BY  LeftS    BackS   u		RY  LeftS    BackS   c
+BY  LeftS    DownS   t		RY  LeftS    DownS   f
+BY  LeftS    FrontS  j		RY  LeftS    FrontS  v
+BY  LeftS    UpS     k		RY  LeftS    UpS     s
+BY  RightS   BackS   o		RY  RightS   BackS   i
+BY  RightS   DownS   n		RY  RightS   DownS   l
+BY  RightS   FrontS  d		RY  RightS   FrontS  p
+BY  RightS   UpS     e		RY  RightS   UpS     m
+BY  UpS      BackS   c		RY  UpS      BackS   o
+BY  UpS      FrontS  p		RY  UpS      FrontS  j
+BY  UpS      LeftS   a		RY  UpS      LeftS   q
+BY  UpS      RightS  r		RY  UpS      RightS  h
+GO  BackS    DownS   h		WB  BackS    DownS   v
+GO  BackS    LeftS   l		WB  BackS    LeftS   j
+GO  BackS    RightS  s		WB  BackS    RightS  d
+GO  BackS    UpS     w		WB  BackS    UpS     p
+GO  DownS    BackS   a		WB  DownS    BackS   m
+GO  DownS    FrontS  r		WB  DownS    FrontS  s
+GO  DownS    LeftS   p		WB  DownS    LeftS   k
+GO  DownS    RightS  c		WB  DownS    RightS  e
+GO  FrontS   DownS   q		WB  FrontS   DownS   i
+GO  FrontS   LeftS   m		WB  FrontS   LeftS   u
+GO  FrontS   RightS  f		WB  FrontS   RightS  o
+GO  FrontS   UpS     b		WB  FrontS   UpS     c
+GO  LeftS    BackS   e		WB  LeftS    BackS   b
+GO  LeftS    DownS   o		WB  LeftS    DownS   x
+GO  LeftS    FrontS  n		WB  LeftS    FrontS  h
+GO  LeftS    UpS     d		WB  LeftS    UpS     r
+GO  RightS   BackS   t		WB  RightS   BackS   q
+GO  RightS   DownS   j		WB  RightS   DownS   g
+GO  RightS   FrontS  k		WB  RightS   FrontS  w
+GO  RightS   UpS     u		WB  RightS   UpS     a
+GO  UpS      BackS   x		WB  UpS      BackS   f
+GO  UpS      FrontS  g		WB  UpS      FrontS  l
+GO  UpS      LeftS   i		WB  UpS      LeftS   t
+GO  UpS      RightS  v		WB  UpS      RightS  n
+GR  BackS    DownS   w		WG  BackS    DownS   p
+GR  BackS    LeftS   s		WG  BackS    LeftS   d
+GR  BackS    RightS  l		WG  BackS    RightS  j
+GR  BackS    UpS     h		WG  BackS    UpS     v
+GR  DownS    BackS   r		WG  DownS    BackS   s
+GR  DownS    FrontS  a		WG  DownS    FrontS  m
+GR  DownS    LeftS   c		WG  DownS    LeftS   e
+GR  DownS    RightS  p		WG  DownS    RightS  k
+GR  FrontS   DownS   b		WG  FrontS   DownS   c
+GR  FrontS   LeftS   f		WG  FrontS   LeftS   o
+GR  FrontS   RightS  m		WG  FrontS   RightS  u
+GR  FrontS   UpS     q		WG  FrontS   UpS     i
+GR  LeftS    BackS   n		WG  LeftS    BackS   h
+GR  LeftS    DownS   d		WG  LeftS    DownS   r
+GR  LeftS    FrontS  e		WG  LeftS    FrontS  b
+GR  LeftS    UpS     o		WG  LeftS    UpS     x
+GR  RightS   BackS   k		WG  RightS   BackS   w
+GR  RightS   DownS   u		WG  RightS   DownS   a
+GR  RightS   FrontS  t		WG  RightS   FrontS  q
+GR  RightS   UpS     j		WG  RightS   UpS     g
+GR  UpS      BackS   g		WG  UpS      BackS   l
+GR  UpS      FrontS  x		WG  UpS      FrontS  f
+GR  UpS      LeftS   v		WG  UpS      LeftS   n
+GR  UpS      RightS  i		WG  UpS      RightS  t
+GW  BackS    DownS   s		WO  BackS    DownS   j
+GW  BackS    LeftS   h		WO  BackS    LeftS   p
+GW  BackS    RightS  w		WO  BackS    RightS  v
+GW  BackS    UpS     l		WO  BackS    UpS     d
+GW  DownS    BackS   p		WO  DownS    BackS   e
+GW  DownS    FrontS  c		WO  DownS    FrontS  k
+GW  DownS    LeftS   r		WO  DownS    LeftS   m
+GW  DownS    RightS  a		WO  DownS    RightS  s
+GW  FrontS   DownS   m		WO  FrontS   DownS   o
+GW  FrontS   LeftS   b		WO  FrontS   LeftS   i
+GW  FrontS   RightS  q		WO  FrontS   RightS  c
+GW  FrontS   UpS     f		WO  FrontS   UpS     u
+GW  LeftS    BackS   d		WO  LeftS    BackS   x
+GW  LeftS    DownS   e		WO  LeftS    DownS   h
+GW  LeftS    FrontS  o		WO  LeftS    FrontS  r
+GW  LeftS    UpS     n		WO  LeftS    UpS     b
+GW  RightS   BackS   j		WO  RightS   BackS   a
+GW  RightS   DownS   k		WO  RightS   DownS   q
+GW  RightS   FrontS  u		WO  RightS   FrontS  g
+GW  RightS   UpS     t		WO  RightS   UpS     w
+GW  UpS      BackS   v		WO  UpS      BackS   t
+GW  UpS      FrontS  i		WO  UpS      FrontS  n
+GW  UpS      LeftS   x		WO  UpS      LeftS   l
+GW  UpS      RightS  g		WO  UpS      RightS  f
+GY  BackS    DownS   l		WR  BackS    DownS   d
+GY  BackS    LeftS   w		WR  BackS    LeftS   v
+GY  BackS    RightS  h		WR  BackS    RightS  p
+GY  BackS    UpS     s		WR  BackS    UpS     j
+GY  DownS    BackS   c		WR  DownS    BackS   k
+GY  DownS    FrontS  p		WR  DownS    FrontS  e
+GY  DownS    LeftS   a		WR  DownS    LeftS   s
+GY  DownS    RightS  r		WR  DownS    RightS  m
+GY  FrontS   DownS   f		WR  FrontS   DownS   u
+GY  FrontS   LeftS   q		WR  FrontS   LeftS   c
+GY  FrontS   RightS  b		WR  FrontS   RightS  i
+GY  FrontS   UpS     m		WR  FrontS   UpS     o
+GY  LeftS    BackS   o		WR  LeftS    BackS   r
+GY  LeftS    DownS   n		WR  LeftS    DownS   b
+GY  LeftS    FrontS  d		WR  LeftS    FrontS  x
+GY  LeftS    UpS     e		WR  LeftS    UpS     h
+GY  RightS   BackS   u		WR  RightS   BackS   g
+GY  RightS   DownS   t		WR  RightS   DownS   w
+GY  RightS   FrontS  j		WR  RightS   FrontS  a
+GY  RightS   UpS     k		WR  RightS   UpS     q
+GY  UpS      BackS   i		WR  UpS      BackS   n
+GY  UpS      FrontS  v		WR  UpS      FrontS  t
+GY  UpS      LeftS   g		WR  UpS      LeftS   f
+GY  UpS      RightS  x		WR  UpS      RightS  l
+OB  BackS    DownS   x		YB  BackS    DownS   i
+OB  BackS    LeftS   t		YB  BackS    LeftS   u
+OB  BackS    RightS  e		YB  BackS    RightS  o
+OB  BackS    UpS     a		YB  BackS    UpS     c
+OB  DownS    BackS   q		YB  DownS    BackS   f
+OB  DownS    FrontS  h		YB  DownS    FrontS  l
+OB  DownS    LeftS   j		YB  DownS    LeftS   t
+OB  DownS    RightS  o		YB  DownS    RightS  n
+OB  FrontS   DownS   g		YB  FrontS   DownS   v
+OB  FrontS   LeftS   k		YB  FrontS   LeftS   j
+OB  FrontS   RightS  n		YB  FrontS   RightS  d
+OB  FrontS   UpS     r		YB  FrontS   UpS     p
+OB  LeftS    BackS   m		YB  LeftS    BackS   q
+OB  LeftS    DownS   i		YB  LeftS    DownS   g
+OB  LeftS    FrontS  l		YB  LeftS    FrontS  w
+OB  LeftS    UpS     p		YB  LeftS    UpS     a
+OB  RightS   BackS   f		YB  RightS   BackS   b
+OB  RightS   DownS   v		YB  RightS   DownS   x
+OB  RightS   FrontS  s		YB  RightS   FrontS  h
+OB  RightS   UpS     c		YB  RightS   UpS     r
+OB  UpS      BackS   b		YB  UpS      BackS   m
+OB  UpS      FrontS  w		YB  UpS      FrontS  s
+OB  UpS      LeftS   u		YB  UpS      LeftS   k
+OB  UpS      RightS  d		YB  UpS      RightS  e
+OG  BackS    DownS   a		YG  BackS    DownS   c
+OG  BackS    LeftS   e		YG  BackS    LeftS   o
+OG  BackS    RightS  t		YG  BackS    RightS  u
+OG  BackS    UpS     x		YG  BackS    UpS     i
+OG  DownS    BackS   h		YG  DownS    BackS   l
+OG  DownS    FrontS  q		YG  DownS    FrontS  f
+OG  DownS    LeftS   o		YG  DownS    LeftS   n
+OG  DownS    RightS  j		YG  DownS    RightS  t
+OG  FrontS   DownS   r		YG  FrontS   DownS   p
+OG  FrontS   LeftS   n		YG  FrontS   LeftS   d
+OG  FrontS   RightS  k		YG  FrontS   RightS  j
+OG  FrontS   UpS     g		YG  FrontS   UpS     v
+OG  LeftS    BackS   l		YG  LeftS    BackS   w
+OG  LeftS    DownS   p		YG  LeftS    DownS   a
+OG  LeftS    FrontS  m		YG  LeftS    FrontS  q
+OG  LeftS    UpS     i		YG  LeftS    UpS     g
+OG  RightS   BackS   s		YG  RightS   BackS   h
+OG  RightS   DownS   c		YG  RightS   DownS   r
+OG  RightS   FrontS  f		YG  RightS   FrontS  b
+OG  RightS   UpS     v		YG  RightS   UpS     x
+OG  UpS      BackS   w		YG  UpS      BackS   s
+OG  UpS      FrontS  b		YG  UpS      FrontS  m
+OG  UpS      LeftS   d		YG  UpS      LeftS   e
+OG  UpS      RightS  u		YG  UpS      RightS  k
+OW  BackS    DownS   e		YO  BackS    DownS   o
+OW  BackS    LeftS   x		YO  BackS    LeftS   i
+OW  BackS    RightS  a		YO  BackS    RightS  c
+OW  BackS    UpS     t		YO  BackS    UpS     u
+OW  DownS    BackS   j		YO  DownS    BackS   t
+OW  DownS    FrontS  o		YO  DownS    FrontS  n
+OW  DownS    LeftS   h		YO  DownS    LeftS   l
+OW  DownS    RightS  q		YO  DownS    RightS  f
+OW  FrontS   DownS   k		YO  FrontS   DownS   j
+OW  FrontS   LeftS   r		YO  FrontS   LeftS   p
+OW  FrontS   RightS  g		YO  FrontS   RightS  v
+OW  FrontS   UpS     n		YO  FrontS   UpS     d
+OW  LeftS    BackS   p		YO  LeftS    BackS   a
+OW  LeftS    DownS   m		YO  LeftS    DownS   q
+OW  LeftS    FrontS  i		YO  LeftS    FrontS  g
+OW  LeftS    UpS     l		YO  LeftS    UpS     w
+OW  RightS   BackS   v		YO  RightS   BackS   x
+OW  RightS   DownS   s		YO  RightS   DownS   h
+OW  RightS   FrontS  c		YO  RightS   FrontS  r
+OW  RightS   UpS     f		YO  RightS   UpS     b
+OW  UpS      BackS   d		YO  UpS      BackS   e
+OW  UpS      FrontS  u		YO  UpS      FrontS  k
+OW  UpS      LeftS   b		YO  UpS      LeftS   m
+OW  UpS      RightS  w		YO  UpS      RightS  s
+OY  BackS    DownS   t		YR  BackS    DownS   u
+OY  BackS    LeftS   a		YR  BackS    LeftS   c
+OY  BackS    RightS  x		YR  BackS    RightS  i
+OY  BackS    UpS     e		YR  BackS    UpS     o
+OY  DownS    BackS   o		YR  DownS    BackS   n
+OY  DownS    FrontS  j		YR  DownS    FrontS  t
+OY  DownS    LeftS   q		YR  DownS    LeftS   f
+OY  DownS    RightS  h		YR  DownS    RightS  l
+OY  FrontS   DownS   n		YR  FrontS   DownS   d
+OY  FrontS   LeftS   g		YR  FrontS   LeftS   v
+OY  FrontS   RightS  r		YR  FrontS   RightS  p
+OY  FrontS   UpS     k		YR  FrontS   UpS     j
+OY  LeftS    BackS   i		YR  LeftS    BackS   g
+OY  LeftS    DownS   l		YR  LeftS    DownS   w
+OY  LeftS    FrontS  p		YR  LeftS    FrontS  a
+OY  LeftS    UpS     m		YR  LeftS    UpS     q
+OY  RightS   BackS   c		YR  RightS   BackS   r
+OY  RightS   DownS   f		YR  RightS   DownS   b
+OY  RightS   FrontS  v		YR  RightS   FrontS  x
+OY  RightS   UpS     s		YR  RightS   UpS     h
+OY  UpS      BackS   u		YR  UpS      BackS   k
+OY  UpS      FrontS  d		YR  UpS      FrontS  e
+OY  UpS      LeftS   w		YR  UpS      LeftS   s
+OY  UpS      RightS  b		YR  UpS      RightS  m
diff --git a/hcube.cabal b/hcube.cabal
new file mode 100644
--- /dev/null
+++ b/hcube.cabal
@@ -0,0 +1,61 @@
+name:                 hcube
+version:              0.1.0
+synopsis:       Virtual Rubik's cube of arbitrary size. 
+description:	Provides virtual model of NxNxN Rubik's cube and console visualization for
+		2x2x2, 3x3x3 ,4x4x4, and 5x5x5. Console visualization is choosen in the interest
+                of portability. Virtual cube can be constructed from the state
+		of a physical cube. Support for a two phase algorithm will be given in a future release 
+                for cubes of size 3x3x3 to find the smallest number of moves which solve the cube. 
+		The Rubik's cube exhibits many non-trival aspects of group theory.
+
+		The package comes with an executable "hcube". 
+                The command ./hcube 5 will create a 5x5x5 cube.
+
+license:              BSD3 
+license-file:         LICENSE 
+author:               Todd Wegner
+maintainer:           Todd Wegner
+
+build-Type:           Simple
+cabal-Version:        >= 1.14.0
+copyright:            Copyright 2012
+stability:            experimental
+category:             Game
+
+data-dir:             HCube/store
+data-files:           physicalCubeExample
+extra-source-files:   README
+		      design/common.txt
+                      design/2x2.txt
+                      design/3x3.txt
+                      design/4x4.txt
+                      design/5x5.txt
+                      HCube/Common.hs
+library
+  exposed-modules:    HCube.Cons,
+                      HCube.Data,
+                      HCube.Lib,
+                      HCube.OrientGroup,
+                      HCube.Permutation,
+                      HCube.Template,
+                      HCube.Test,
+                      HCube.Theory,
+                      HCube.Utility
+
+  build-depends:      base >= 3 && < 5 ,
+                      directory >= 1.1.0.1, 
+                      HaskellForMaths >= 0.4.5,
+                      text >= 0.11.2.3,
+                      QuickCheck >= 2.5.1.1
+
+  default-Language:   Haskell2010 
+  default-extensions: MultiParamTypeClasses, FlexibleContexts 
+
+executable hcube
+    main-is:          HCube/Cube.hs
+    default-Language: Haskell2010 
+    build-depends:    base >= 3 && < 5 ,
+                      directory >= 1.1.0.1, 
+                      HaskellForMaths >= 0.4.5,
+                      text >= 0.11.2.3,
+                      QuickCheck >= 2.5.1.1
