@sudobility/sudojo_lib 0.0.142 → 0.0.143

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -89,7 +89,7 @@ export interface HintStep {
89
89
  /**
90
90
  * Link type for chain visualization
91
91
  */
92
- export type LinkType = 'strong' | 'weak';
92
+ export type LinkType = 'strong' | 'weak' | 'conflict';
93
93
  /**
94
94
  * A link between two cells in a chain (display format)
95
95
  */
@@ -1 +1 @@
1
- {"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../../src/types/display.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../../src/types/display.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"display.js","sourceRoot":"","sources":["../../src/types/display.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,gFAAgF;AAChF,sCAAsC;AACtC,gFAAgF;AAEhF;;GAEG;AACH,MAAM,CAAN,IAAY,UAiBX;AAjBD,WAAY,UAAU;IACpB,2BAAa,CAAA;IACb,6BAAe,CAAA;IACf,6BAAe,CAAA;IACf,iDAAmC,CAAA;IACnC,+CAAiC,CAAA;IACjC,mDAAqC,CAAA;IACrC,uCAAyB,CAAA;IACzB,2DAA6C,CAAA;IAC7C,yDAA2C,CAAA;IAC3C,6DAA+C,CAAA;IAC/C,mCAAqB,CAAA;IACrB,iCAAmB,CAAA;IACnB,iCAAmB,CAAA;IACnB,qDAAuC,CAAA;IACvC,6BAAe,CAAA;IACf,mCAAqB,CAAA;AACvB,CAAC,EAjBW,UAAU,KAAV,UAAU,QAiBrB;AAED,gFAAgF;AAChF,kDAAkD;AAClD,gFAAgF;AAEhF;;GAEG;AACH,MAAM,CAAN,IAAY,WAeX;AAfD,WAAY,WAAW;IACrB,4BAAa,CAAA;IACb,8BAAe,CAAA;IACf,4BAAa,CAAA;IACb,8BAAe,CAAA;IACf,gCAAiB,CAAA;IACjB,gCAAiB,CAAA;IACjB,0BAAW,CAAA;IACX,8BAAe,CAAA;IACf,uCAAwB,CAAA;IACxB,8BAAe,CAAA;IACf,4BAAa,CAAA;IACb,gCAAiB,CAAA;IACjB,oDAAqC,CAAA;IACrC,oCAAqB,CAAA;AACvB,CAAC,EAfW,WAAW,KAAX,WAAW,QAetB;AAwJD;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAmB;IAC1C,gBAAgB,EAAE,SAAS;IAC3B,yBAAyB,EAAE,WAAW;IACtC,wBAAwB,EAAE,WAAW;IACrC,KAAK,EAAE,WAAW;IAClB,cAAc,EAAE,WAAW;IAC3B,aAAa,EAAE,WAAW;IAC1B,eAAe,EAAE,WAAW;IAC5B,UAAU,EAAE,WAAW;IACvB,WAAW,EAAE,WAAW;IACxB,YAAY,EAAE,WAAW;IACzB,YAAY,EAAE,WAAW;IACzB,SAAS,EAAE,WAAW;IACtB,YAAY,EAAE,WAAW;IACzB,UAAU,EAAE,WAAW;IACvB,KAAK,EAAE,WAAW;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAmB;IACzC,gBAAgB,EAAE,WAAW;IAC7B,yBAAyB,EAAE,WAAW;IACtC,wBAAwB,EAAE,WAAW;IACrC,KAAK,EAAE,WAAW;IAClB,cAAc,EAAE,WAAW;IAC3B,aAAa,EAAE,WAAW;IAC1B,eAAe,EAAE,WAAW;IAC5B,UAAU,EAAE,WAAW;IACvB,WAAW,EAAE,WAAW;IACxB,YAAY,EAAE,WAAW;IACzB,YAAY,EAAE,WAAW;IACzB,SAAS,EAAE,WAAW;IACtB,YAAY,EAAE,WAAW;IACzB,UAAU,EAAE,WAAW;IACvB,KAAK,EAAE,WAAW;CACnB,CAAC","sourcesContent":["/**\n * Display types for Sudoku rendering\n *\n * Matches Kotlin renderable types exactly\n */\n\n// =============================================================================\n// Theme Color (matches ThemeColor.kt)\n// =============================================================================\n\n/**\n * Theme colors for the UI - matches Kotlin ThemeColor enum\n */\nexport enum ThemeColor {\n NONE = 'NONE',\n CLEAR = 'CLEAR',\n LABEL = 'LABEL',\n LABEL_SECONDARY = 'LABEL_SECONDARY',\n LABEL_TERTIARY = 'LABEL_TERTIARY',\n LABEL_QUATERNARY = 'LABEL_QUATERNARY',\n BACKGROUND = 'BACKGROUND',\n BACKGROUND_SECONDARY = 'BACKGROUND_SECONDARY',\n BACKGROUND_TERTIARY = 'BACKGROUND_TERTIARY',\n BACKGROUND_QUATERNARY = 'BACKGROUND_QUATERNARY',\n SELECTED = 'SELECTED',\n SUCCESS = 'SUCCESS',\n WARNING = 'WARNING',\n WARNING_SECONDARY = 'WARNING_SECONDARY',\n ERROR = 'ERROR',\n DISABLED = 'DISABLED',\n}\n\n// =============================================================================\n// Sudoku Color (matches SudokuColor in Shared.kt)\n// =============================================================================\n\n/**\n * Sudoku-specific colors - matches Kotlin SudokuColor enum\n */\nexport enum SudokuColor {\n NONE = 'none',\n CLEAR = 'clear',\n BLUE = 'blue',\n GREEN = 'green',\n YELLOW = 'yellow',\n ORANGE = 'orange',\n RED = 'red',\n WHITE = 'white',\n LIGHT_GRAY = 'lightgray',\n BLACK = 'black',\n GRAY = 'gray',\n ACTION = 'action',\n SECONDARY_ACTION = 'secondary-action',\n DISABLED = 'disabled',\n}\n\n// =============================================================================\n// Hint Types (matches Hint.kt)\n// =============================================================================\n\n/**\n * Area type for highlighting - matches HintArea.Type\n */\nexport type HintAreaType = 'row' | 'column' | 'block';\n\n/**\n * Highlighted area in a hint - matches HintArea\n */\nexport interface HintArea {\n type: HintAreaType;\n color: SudokuColor | null;\n index: number;\n}\n\n/**\n * Actions to perform on a cell - matches HintCellActions\n */\nexport interface HintCellActions {\n select: number | null;\n unselect: number | null;\n add: number[] | null;\n remove: number[] | null;\n highlight: number[] | null;\n}\n\n/**\n * Cell display information in a hint - matches HintCell\n */\nexport interface HintCell {\n index: number;\n color: SudokuColor | null;\n fill: boolean;\n actions?: HintCellActions;\n}\n\n/**\n * A single hint step - matches HintStep\n */\nexport interface HintStep {\n title: string;\n text: string;\n areas?: HintArea[] | null;\n cells?: HintCell[] | null;\n links?: DisplayLink[] | null;\n groups?: DisplayCellGroup[] | null;\n digit?: number | null;\n}\n\n// =============================================================================\n// Link Types (for chain visualization)\n// =============================================================================\n\n/**\n * Link type for chain visualization\n */\nexport type LinkType = 'strong' | 'weak';\n\n/**\n * A link between two cells in a chain (display format)\n */\nexport interface DisplayLink {\n /** Start cell index (0-80) */\n fromIndex: number;\n /** End cell index (0-80) */\n toIndex: number;\n /** Link type: \"strong\" (solid line) or \"weak\" (dashed line) */\n type: LinkType;\n /** The digit this link applies to (1-9) */\n digit: number;\n}\n\n// =============================================================================\n// Cell Group Types (for pattern visualization)\n// =============================================================================\n\n/**\n * A group of cells for pattern visualization (display format)\n */\nexport interface DisplayCellGroup {\n /** Group name (e.g., \"ALS A\", \"Conjugate Pair\", \"UR Corner\") */\n name: string;\n /** Theme color for the group */\n color: ThemeColor;\n /** Array of cell indices (0-80) */\n cellIndices: number[];\n}\n\n// =============================================================================\n// Cell Display State\n// =============================================================================\n\n/**\n * Complete display state for a single cell\n */\nexport interface CellDisplayState {\n /** Cell index (0-80) */\n index: number;\n /** Background color */\n backgroundColor: ThemeColor;\n /** Border color (null for no border) */\n borderColor: ThemeColor | null;\n /** Text color */\n textColor: ThemeColor | null;\n /** The digit to display (1-9) or null */\n digit: number | null;\n /** Whether this is a given (original) digit */\n isGiven: boolean;\n /** Pencilmarks to display */\n pencilmarks: PencilmarkDisplayState[];\n}\n\n/**\n * Display state for a single pencilmark\n */\nexport interface PencilmarkDisplayState {\n /** The digit (1-9) */\n digit: number;\n /** Color of the pencilmark */\n color: ThemeColor | null;\n}\n\n// =============================================================================\n// Color Palette\n// =============================================================================\n\n/**\n * UI color palette - matches UIColorType from sudojo-web\n */\nexport interface UIColorPalette {\n systemBackground: string;\n secondarySystemBackground: string;\n tertiarySystemBackground: string;\n label: string;\n secondaryLabel: string;\n tertiaryLabel: string;\n quaternaryLabel: string;\n systemBlue: string;\n systemGreen: string;\n systemOrange: string;\n systemPurple: string;\n systemRed: string;\n systemYellow: string;\n systemGray: string;\n clear: string;\n}\n\n/**\n * Light mode color palette - matches sudojo-web UIColorLight\n */\nexport const UIColorLight: UIColorPalette = {\n systemBackground: '#FFFFFF',\n secondarySystemBackground: '#F2F2F7FF',\n tertiarySystemBackground: '#FFFFFFFF',\n label: '#000000FF',\n secondaryLabel: '#3C3C4399',\n tertiaryLabel: '#3C3C434D',\n quaternaryLabel: '#3C3C432E',\n systemBlue: '#007AFFFF',\n systemGreen: '#34C759FF',\n systemOrange: '#FF9500FF',\n systemPurple: '#AF52DEFF',\n systemRed: '#FF3B30FF',\n systemYellow: '#FFCC00FF',\n systemGray: '#8E8E93FF',\n clear: '#00000000',\n};\n\n/**\n * Dark mode color palette - matches sudojo-web UIColorDark\n */\nexport const UIColorDark: UIColorPalette = {\n systemBackground: '#000000FF',\n secondarySystemBackground: '#1C1C1EFF',\n tertiarySystemBackground: '#2C2C2EFF',\n label: '#FFFFFFFF',\n secondaryLabel: '#EBEBF599',\n tertiaryLabel: '#EBEBF54D',\n quaternaryLabel: '#EBEBF52E',\n systemBlue: '#0A84FFFF',\n systemGreen: '#30D158FF',\n systemOrange: '#FF9F0AFF',\n systemPurple: '#BF5AF2FF',\n systemRed: '#FF453AFF',\n systemYellow: '#FFD60AFF',\n systemGray: '#8E8E93FF',\n clear: '#00000000',\n};\n"]}
1
+ {"version":3,"file":"display.js","sourceRoot":"","sources":["../../src/types/display.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,gFAAgF;AAChF,sCAAsC;AACtC,gFAAgF;AAEhF;;GAEG;AACH,MAAM,CAAN,IAAY,UAiBX;AAjBD,WAAY,UAAU;IACpB,2BAAa,CAAA;IACb,6BAAe,CAAA;IACf,6BAAe,CAAA;IACf,iDAAmC,CAAA;IACnC,+CAAiC,CAAA;IACjC,mDAAqC,CAAA;IACrC,uCAAyB,CAAA;IACzB,2DAA6C,CAAA;IAC7C,yDAA2C,CAAA;IAC3C,6DAA+C,CAAA;IAC/C,mCAAqB,CAAA;IACrB,iCAAmB,CAAA;IACnB,iCAAmB,CAAA;IACnB,qDAAuC,CAAA;IACvC,6BAAe,CAAA;IACf,mCAAqB,CAAA;AACvB,CAAC,EAjBW,UAAU,KAAV,UAAU,QAiBrB;AAED,gFAAgF;AAChF,kDAAkD;AAClD,gFAAgF;AAEhF;;GAEG;AACH,MAAM,CAAN,IAAY,WAeX;AAfD,WAAY,WAAW;IACrB,4BAAa,CAAA;IACb,8BAAe,CAAA;IACf,4BAAa,CAAA;IACb,8BAAe,CAAA;IACf,gCAAiB,CAAA;IACjB,gCAAiB,CAAA;IACjB,0BAAW,CAAA;IACX,8BAAe,CAAA;IACf,uCAAwB,CAAA;IACxB,8BAAe,CAAA;IACf,4BAAa,CAAA;IACb,gCAAiB,CAAA;IACjB,oDAAqC,CAAA;IACrC,oCAAqB,CAAA;AACvB,CAAC,EAfW,WAAW,KAAX,WAAW,QAetB;AAwJD;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAmB;IAC1C,gBAAgB,EAAE,SAAS;IAC3B,yBAAyB,EAAE,WAAW;IACtC,wBAAwB,EAAE,WAAW;IACrC,KAAK,EAAE,WAAW;IAClB,cAAc,EAAE,WAAW;IAC3B,aAAa,EAAE,WAAW;IAC1B,eAAe,EAAE,WAAW;IAC5B,UAAU,EAAE,WAAW;IACvB,WAAW,EAAE,WAAW;IACxB,YAAY,EAAE,WAAW;IACzB,YAAY,EAAE,WAAW;IACzB,SAAS,EAAE,WAAW;IACtB,YAAY,EAAE,WAAW;IACzB,UAAU,EAAE,WAAW;IACvB,KAAK,EAAE,WAAW;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAmB;IACzC,gBAAgB,EAAE,WAAW;IAC7B,yBAAyB,EAAE,WAAW;IACtC,wBAAwB,EAAE,WAAW;IACrC,KAAK,EAAE,WAAW;IAClB,cAAc,EAAE,WAAW;IAC3B,aAAa,EAAE,WAAW;IAC1B,eAAe,EAAE,WAAW;IAC5B,UAAU,EAAE,WAAW;IACvB,WAAW,EAAE,WAAW;IACxB,YAAY,EAAE,WAAW;IACzB,YAAY,EAAE,WAAW;IACzB,SAAS,EAAE,WAAW;IACtB,YAAY,EAAE,WAAW;IACzB,UAAU,EAAE,WAAW;IACvB,KAAK,EAAE,WAAW;CACnB,CAAC","sourcesContent":["/**\n * Display types for Sudoku rendering\n *\n * Matches Kotlin renderable types exactly\n */\n\n// =============================================================================\n// Theme Color (matches ThemeColor.kt)\n// =============================================================================\n\n/**\n * Theme colors for the UI - matches Kotlin ThemeColor enum\n */\nexport enum ThemeColor {\n NONE = 'NONE',\n CLEAR = 'CLEAR',\n LABEL = 'LABEL',\n LABEL_SECONDARY = 'LABEL_SECONDARY',\n LABEL_TERTIARY = 'LABEL_TERTIARY',\n LABEL_QUATERNARY = 'LABEL_QUATERNARY',\n BACKGROUND = 'BACKGROUND',\n BACKGROUND_SECONDARY = 'BACKGROUND_SECONDARY',\n BACKGROUND_TERTIARY = 'BACKGROUND_TERTIARY',\n BACKGROUND_QUATERNARY = 'BACKGROUND_QUATERNARY',\n SELECTED = 'SELECTED',\n SUCCESS = 'SUCCESS',\n WARNING = 'WARNING',\n WARNING_SECONDARY = 'WARNING_SECONDARY',\n ERROR = 'ERROR',\n DISABLED = 'DISABLED',\n}\n\n// =============================================================================\n// Sudoku Color (matches SudokuColor in Shared.kt)\n// =============================================================================\n\n/**\n * Sudoku-specific colors - matches Kotlin SudokuColor enum\n */\nexport enum SudokuColor {\n NONE = 'none',\n CLEAR = 'clear',\n BLUE = 'blue',\n GREEN = 'green',\n YELLOW = 'yellow',\n ORANGE = 'orange',\n RED = 'red',\n WHITE = 'white',\n LIGHT_GRAY = 'lightgray',\n BLACK = 'black',\n GRAY = 'gray',\n ACTION = 'action',\n SECONDARY_ACTION = 'secondary-action',\n DISABLED = 'disabled',\n}\n\n// =============================================================================\n// Hint Types (matches Hint.kt)\n// =============================================================================\n\n/**\n * Area type for highlighting - matches HintArea.Type\n */\nexport type HintAreaType = 'row' | 'column' | 'block';\n\n/**\n * Highlighted area in a hint - matches HintArea\n */\nexport interface HintArea {\n type: HintAreaType;\n color: SudokuColor | null;\n index: number;\n}\n\n/**\n * Actions to perform on a cell - matches HintCellActions\n */\nexport interface HintCellActions {\n select: number | null;\n unselect: number | null;\n add: number[] | null;\n remove: number[] | null;\n highlight: number[] | null;\n}\n\n/**\n * Cell display information in a hint - matches HintCell\n */\nexport interface HintCell {\n index: number;\n color: SudokuColor | null;\n fill: boolean;\n actions?: HintCellActions;\n}\n\n/**\n * A single hint step - matches HintStep\n */\nexport interface HintStep {\n title: string;\n text: string;\n areas?: HintArea[] | null;\n cells?: HintCell[] | null;\n links?: DisplayLink[] | null;\n groups?: DisplayCellGroup[] | null;\n digit?: number | null;\n}\n\n// =============================================================================\n// Link Types (for chain visualization)\n// =============================================================================\n\n/**\n * Link type for chain visualization\n */\nexport type LinkType = 'strong' | 'weak' | 'conflict';\n\n/**\n * A link between two cells in a chain (display format)\n */\nexport interface DisplayLink {\n /** Start cell index (0-80) */\n fromIndex: number;\n /** End cell index (0-80) */\n toIndex: number;\n /** Link type: \"strong\" (solid line) or \"weak\" (dashed line) */\n type: LinkType;\n /** The digit this link applies to (1-9) */\n digit: number;\n}\n\n// =============================================================================\n// Cell Group Types (for pattern visualization)\n// =============================================================================\n\n/**\n * A group of cells for pattern visualization (display format)\n */\nexport interface DisplayCellGroup {\n /** Group name (e.g., \"ALS A\", \"Conjugate Pair\", \"UR Corner\") */\n name: string;\n /** Theme color for the group */\n color: ThemeColor;\n /** Array of cell indices (0-80) */\n cellIndices: number[];\n}\n\n// =============================================================================\n// Cell Display State\n// =============================================================================\n\n/**\n * Complete display state for a single cell\n */\nexport interface CellDisplayState {\n /** Cell index (0-80) */\n index: number;\n /** Background color */\n backgroundColor: ThemeColor;\n /** Border color (null for no border) */\n borderColor: ThemeColor | null;\n /** Text color */\n textColor: ThemeColor | null;\n /** The digit to display (1-9) or null */\n digit: number | null;\n /** Whether this is a given (original) digit */\n isGiven: boolean;\n /** Pencilmarks to display */\n pencilmarks: PencilmarkDisplayState[];\n}\n\n/**\n * Display state for a single pencilmark\n */\nexport interface PencilmarkDisplayState {\n /** The digit (1-9) */\n digit: number;\n /** Color of the pencilmark */\n color: ThemeColor | null;\n}\n\n// =============================================================================\n// Color Palette\n// =============================================================================\n\n/**\n * UI color palette - matches UIColorType from sudojo-web\n */\nexport interface UIColorPalette {\n systemBackground: string;\n secondarySystemBackground: string;\n tertiarySystemBackground: string;\n label: string;\n secondaryLabel: string;\n tertiaryLabel: string;\n quaternaryLabel: string;\n systemBlue: string;\n systemGreen: string;\n systemOrange: string;\n systemPurple: string;\n systemRed: string;\n systemYellow: string;\n systemGray: string;\n clear: string;\n}\n\n/**\n * Light mode color palette - matches sudojo-web UIColorLight\n */\nexport const UIColorLight: UIColorPalette = {\n systemBackground: '#FFFFFF',\n secondarySystemBackground: '#F2F2F7FF',\n tertiarySystemBackground: '#FFFFFFFF',\n label: '#000000FF',\n secondaryLabel: '#3C3C4399',\n tertiaryLabel: '#3C3C434D',\n quaternaryLabel: '#3C3C432E',\n systemBlue: '#007AFFFF',\n systemGreen: '#34C759FF',\n systemOrange: '#FF9500FF',\n systemPurple: '#AF52DEFF',\n systemRed: '#FF3B30FF',\n systemYellow: '#FFCC00FF',\n systemGray: '#8E8E93FF',\n clear: '#00000000',\n};\n\n/**\n * Dark mode color palette - matches sudojo-web UIColorDark\n */\nexport const UIColorDark: UIColorPalette = {\n systemBackground: '#000000FF',\n secondarySystemBackground: '#1C1C1EFF',\n tertiarySystemBackground: '#2C2C2EFF',\n label: '#FFFFFFFF',\n secondaryLabel: '#EBEBF599',\n tertiaryLabel: '#EBEBF54D',\n quaternaryLabel: '#EBEBF52E',\n systemBlue: '#0A84FFFF',\n systemGreen: '#30D158FF',\n systemOrange: '#FF9F0AFF',\n systemPurple: '#BF5AF2FF',\n systemRed: '#FF453AFF',\n systemYellow: '#FFD60AFF',\n systemGray: '#8E8E93FF',\n clear: '#00000000',\n};\n"]}
@@ -72,7 +72,7 @@ export declare function convertSolverLink(link: {
72
72
  fromCol: number;
73
73
  toRow: number;
74
74
  toCol: number;
75
- type: 'strong' | 'weak';
75
+ type: 'strong' | 'weak' | 'conflict';
76
76
  digit: number;
77
77
  }): DisplayLink;
78
78
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"sudokuPresenter.d.ts","sourceRoot":"","sources":["../../src/utils/sudokuPresenter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,QAAQ,EAEb,WAAW,EACX,UAAU,EAGV,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AA0D1B;;GAEG;AACH,iBAAS,kBAAkB,CACzB,WAAW,EAAE,WAAW,GAAG,IAAI,GAC9B,UAAU,GAAG,IAAI,CAyBnB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,cAAc,EACvB,UAAU,EAAE,UAAU,GAAG,IAAI,GAC5B,MAAM,GAAG,IAAI,CA4Bf;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,OAAO,GAAG,cAAc,CAEnE;AAMD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,QAAQ,GAAG,IAAI,GACxB,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,IAAI,CAoC9B;AAuMD,MAAM,WAAW,mBAAmB;IAClC,gCAAgC;IAChC,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,mDAAmD;IACnD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,yDAAyD;IACzD,UAAU,EAAE,OAAO,CAAC;IACpB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC3B,2EAA2E;IAC3E,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;CACzC;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,gBAAgB,EAAE,CAuF7E;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,UAAU,EAAE,EACnB,KAAK,EAAE,MAAM,GACZ,GAAG,CAAC,MAAM,CAAC,CAQb;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,UAAU,EAAE,EACnB,aAAa,EAAE,MAAM,GAAG,IAAI,GAC3B,MAAM,GAAG,IAAI,CAiBf;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,UAAU,EAAE,EACnB,aAAa,EAAE,MAAM,GAAG,IAAI,GAC3B,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAIpB;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,WAAW,CAOd;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC;CACnB,GAAG,gBAAgB,CAanB;AAED;;GAEG;AACH,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
1
+ {"version":3,"file":"sudokuPresenter.d.ts","sourceRoot":"","sources":["../../src/utils/sudokuPresenter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,QAAQ,EAEb,WAAW,EACX,UAAU,EAGV,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AA0D1B;;GAEG;AACH,iBAAS,kBAAkB,CACzB,WAAW,EAAE,WAAW,GAAG,IAAI,GAC9B,UAAU,GAAG,IAAI,CAyBnB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,cAAc,EACvB,UAAU,EAAE,UAAU,GAAG,IAAI,GAC5B,MAAM,GAAG,IAAI,CA4Bf;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,OAAO,GAAG,cAAc,CAEnE;AAMD;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,QAAQ,GAAG,IAAI,GACxB,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,IAAI,CAoC9B;AAuMD,MAAM,WAAW,mBAAmB;IAClC,gCAAgC;IAChC,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,mDAAmD;IACnD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,yDAAyD;IACzD,UAAU,EAAE,OAAO,CAAC;IACpB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC3B,2EAA2E;IAC3E,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;CACzC;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,gBAAgB,EAAE,CAuF7E;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,UAAU,EAAE,EACnB,KAAK,EAAE,MAAM,GACZ,GAAG,CAAC,MAAM,CAAC,CAQb;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,UAAU,EAAE,EACnB,aAAa,EAAE,MAAM,GAAG,IAAI,GAC3B,MAAM,GAAG,IAAI,CAiBf;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,UAAU,EAAE,EACnB,aAAa,EAAE,MAAM,GAAG,IAAI,GAC3B,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAIpB;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,WAAW,CAOd;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC;CACnB,GAAG,gBAAgB,CAanB;AAED;;GAEG;AACH,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"sudokuPresenter.js","sourceRoot":"","sources":["../../src/utils/sudokuPresenter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAOL,WAAW,EACX,UAAU,EACV,WAAW,EACX,YAAY,GAEb,MAAM,kBAAkB,CAAC;AAE1B,gFAAgF;AAChF,8CAA8C;AAC9C,gFAAgF;AAEhF;;GAEG;AACH,MAAM,KAAK;IAIT,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QACvC,MAAM,QAAQ,GAAG,KAAK,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3B,MAAM,GAAG,GAAG,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC7B,MAAM,GAAG,GAAG,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC7B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAED;;GAEG;AACH,MAAM,GAAG;IAIP,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;IAC5E,CAAC;CACF;AAED;;GAEG;AACH,MAAM,MAAM;IAIV,YAAY,KAAa;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;IAC5E,CAAC;CACF;AAED,gFAAgF;AAChF,mDAAmD;AACnD,gFAAgF;AAEhF;;GAEG;AACH,SAAS,kBAAkB,CACzB,WAA+B;IAE/B,QAAQ,WAAW,EAAE,CAAC;QACpB,KAAK,WAAW,CAAC,IAAI;YACnB,OAAO,UAAU,CAAC,QAAQ,CAAC;QAC7B,KAAK,WAAW,CAAC,KAAK;YACpB,OAAO,UAAU,CAAC,OAAO,CAAC;QAC5B,KAAK,WAAW,CAAC,MAAM;YACrB,OAAO,UAAU,CAAC,iBAAiB,CAAC;QACtC,KAAK,WAAW,CAAC,MAAM;YACrB,OAAO,UAAU,CAAC,OAAO,CAAC;QAC5B,KAAK,WAAW,CAAC,GAAG;YAClB,OAAO,UAAU,CAAC,KAAK,CAAC;QAC1B,KAAK,WAAW,CAAC,KAAK;YACpB,OAAO,UAAU,CAAC,UAAU,CAAC;QAC/B,KAAK,WAAW,CAAC,UAAU;YACzB,OAAO,UAAU,CAAC,oBAAoB,CAAC;QACzC,KAAK,WAAW,CAAC,KAAK;YACpB,OAAO,UAAU,CAAC,KAAK,CAAC;QAC1B,KAAK,WAAW,CAAC,IAAI;YACnB,OAAO,UAAU,CAAC,eAAe,CAAC;QACpC,KAAK,WAAW,CAAC,KAAK;YACpB,OAAO,UAAU,CAAC,KAAK,CAAC;QAC1B;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAuB,EACvB,UAA6B;IAE7B,QAAQ,UAAU,EAAE,CAAC;QACnB,KAAK,UAAU,CAAC,IAAI,CAAC;QACrB,KAAK,UAAU,CAAC,KAAK;YACnB,OAAO,OAAO,CAAC,KAAK,CAAC;QACvB,KAAK,UAAU,CAAC,QAAQ;YACtB,OAAO,OAAO,CAAC,YAAY,CAAC;QAC9B,KAAK,UAAU,CAAC,OAAO;YACrB,OAAO,OAAO,CAAC,UAAU,CAAC;QAC5B,KAAK,UAAU,CAAC,iBAAiB;YAC/B,OAAO,OAAO,CAAC,YAAY,CAAC;QAC9B,KAAK,UAAU,CAAC,OAAO;YACrB,OAAO,OAAO,CAAC,YAAY,CAAC;QAC9B,KAAK,UAAU,CAAC,KAAK;YACnB,OAAO,OAAO,CAAC,SAAS,CAAC;QAC3B,KAAK,UAAU,CAAC,UAAU;YACxB,OAAO,OAAO,CAAC,gBAAgB,CAAC;QAClC,KAAK,UAAU,CAAC,oBAAoB;YAClC,OAAO,OAAO,CAAC,yBAAyB,CAAC;QAC3C,KAAK,UAAU,CAAC,KAAK;YACnB,OAAO,OAAO,CAAC,KAAK,CAAC;QACvB,KAAK,UAAU,CAAC,eAAe;YAC7B,OAAO,OAAO,CAAC,cAAc,CAAC;QAChC,KAAK,UAAU,CAAC,QAAQ;YACtB,OAAO,OAAO,CAAC,UAAU,CAAC;QAC5B;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,UAAmB;IACjD,OAAO,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;AACjD,CAAC;AAED,gFAAgF;AAChF,8DAA8D;AAC9D,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,QAAyB;IAEzB,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAE3B,MAAM,SAAS,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE9C,sBAAsB;IACtB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE;QAC7B,IAAI,WAAqB,CAAC;QAE1B,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,OAAO;gBACV,WAAW,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC;gBAChD,MAAM;YACR,KAAK,KAAK;gBACR,WAAW,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC;gBAC9C,MAAM;YACR,KAAK,QAAQ;gBACX,WAAW,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC;gBACjD,MAAM;QACV,CAAC;QAED,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YAC1B,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE;gBACnB,KAAK;gBACL,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,IAAI,EAAE,IAAI,EAAE,wBAAwB;aACrC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,kCAAkC;IAClC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE;QAC7B,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,OAAO,SAAS,CAAC;AACnB,CAAC;AAWD;;;GAGG;AACH,SAAS,aAAa,CACpB,SAAiB,EACjB,cAAsB,EACtB,YAAoB,EACpB,eAAuB,EACvB,YAAqB,EACrB,aAA4B,EAC5B,kBAAiC,EACjC,gBAA+B,EAC/B,mBAAkC,EAClC,kBAAsC;IAEtC,2DAA2D;IAC3D,MAAM,sBAAsB,GAC1B,cAAc,GAAG,CAAC,KAAK,CAAC;QACtB,CAAC,CAAC,UAAU,CAAC,oBAAoB;QACjC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;IAE5B,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;QAC3B,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IACxE,CAAC;IAED,IAAI,kBAAkB,KAAK,IAAI,EAAE,CAAC;QAChC,0BAA0B;QAC1B,IAAI,kBAAkB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YACtC,0CAA0C;YAC1C,OAAO,EAAE,eAAe,EAAE,UAAU,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;QACrE,CAAC;QAED,kFAAkF;QAClF,IAAI,YAAY,GAAG,YAAY,CAAC;QAChC,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,KAAK,MAAM,gBAAgB,IAAI,kBAAkB,EAAE,CAAC;gBAClD,MAAM,IAAI,GAAG,KAAK,CAAC,gBAAgB,CAAC,CAAC;gBACrC,MAAM,IAAI,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC;gBACxC,MAAM,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;gBACzC,IACE,YAAY,KAAK,IAAI;oBACrB,eAAe,KAAK,IAAI;oBACxB,cAAc,KAAK,MAAM,EACzB,CAAC;oBACD,YAAY,GAAG,IAAI,CAAC;oBACpB,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,EAAE,eAAe,EAAE,UAAU,CAAC,eAAe,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;QAC5E,CAAC;QAED,iBAAiB;QACjB,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IACxE,CAAC;IAED,wBAAwB;IACxB,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,sDAAsD;QACtD,OAAO;YACL,eAAe,EAAE,sBAAsB;YACvC,WAAW,EAAE,UAAU,CAAC,QAAQ;SACjC,CAAC;IACJ,CAAC;IAED,IACE,kBAAkB,KAAK,cAAc;QACrC,gBAAgB,KAAK,YAAY;QACjC,mBAAmB,KAAK,eAAe,EACvC,CAAC;QACD,iDAAiD;QACjD,OAAO,EAAE,eAAe,EAAE,UAAU,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IACrE,CAAC;IAED,cAAc;IACd,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;AACxE,CAAC;AAYD;;;GAGG;AACH,SAAS,WAAW,CAClB,IAAgB,EAChB,UAAmB,EACnB,QAAyB;IAEzB,oCAAoC;IACpC,IAAI,QAAQ,EAAE,OAAO,EAAE,MAAM,IAAI,IAAI,EAAE,CAAC;QACtC,OAAO;YACL,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM;YAC9B,SAAS,EAAE,UAAU,CAAC,QAAQ;YAC9B,OAAO,EAAE,KAAK;SACf,CAAC;IACJ,CAAC;IAED,+CAA+C;IAC/C,IAAI,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI,IAAI,EAAE,CAAC;QACxC,OAAO;YACL,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,QAAQ;YAChC,SAAS,EAAE,UAAU,CAAC,KAAK;YAC3B,OAAO,EAAE,KAAK;SACf,CAAC;IACJ,CAAC;IAED,aAAa;IACb,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QACxB,IAAI,SAAqB,CAAC;QAC1B,IAAI,UAAU,EAAE,CAAC;YACf,SAAS;gBACP,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC;QACzE,CAAC;aAAM,CAAC;YACN,SAAS,GAAG,UAAU,CAAC,eAAe,CAAC;QACzC,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC1D,CAAC;IAED,mBAAmB;IACnB,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QACxB,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3E,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC1D,CAAC;AAED,gFAAgF;AAChF,sEAAsE;AACtE,gFAAgF;AAEhF;;;GAGG;AACH,SAAS,cAAc,CACrB,IAAgB,EAChB,QAAyB;IAEzB,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW;QACtC,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;QAC3B,CAAC,CAAC,IAAI,GAAG,EAAU,CAAC;IACtB,MAAM,MAAM,GAAG,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7E,MAAM,QAAQ,GAAG,QAAQ,EAAE,OAAO,EAAE,MAAM;QACxC,CAAC,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;QAClC,CAAC,CAAC,IAAI,CAAC;IACT,MAAM,YAAY,GAAG,QAAQ,EAAE,OAAO,EAAE,SAAS;QAC/C,CAAC,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC;QACrC,CAAC,CAAC,IAAI,CAAC;IAET,MAAM,MAAM,GAA6B,EAAE,CAAC;IAE5C,KAAK,IAAI,UAAU,GAAG,CAAC,EAAE,UAAU,IAAI,CAAC,EAAE,UAAU,EAAE,EAAE,CAAC;QACvD,IAAI,KAAK,GAAsB,IAAI,CAAC;QAEpC,IAAI,YAAY,EAAE,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YAClC,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC;QAC9B,CAAC;aAAM,IAAI,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YACnC,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC;QAC7B,CAAC;aAAM,IAAI,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YACrC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC;QAC3B,CAAC;aAAM,IAAI,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3C,KAAK,GAAG,UAAU,CAAC,eAAe,CAAC;QACrC,CAAC;QAED,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAmBD;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,OAA4B;IACvD,MAAM,EACJ,KAAK,EACL,aAAa,EACb,UAAU,EACV,QAAQ,GAAG,IAAI,EACf,kBAAkB,GAAG,IAAI,GAC1B,GAAG,OAAO,CAAC;IAEZ,0BAA0B;IAC1B,MAAM,SAAS,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAE/C,wCAAwC;IACxC,MAAM,aAAa,GAAG,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3E,KAAK,aAAa,CAAC,CAAC,0BAA0B;IAC9C,MAAM,kBAAkB,GACtB,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACzD,MAAM,gBAAgB,GAAG,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9E,MAAM,mBAAmB,GACvB,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAE1D,uCAAuC;IACvC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC/B,MAAM,cAAc,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QACtC,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QAClC,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC;QAEhE,yBAAyB;QACzB,MAAM,QAAQ,GAAG,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;QAE/C,kBAAkB;QAClB,MAAM,EAAE,eAAe,EAAE,WAAW,EAAE,GAAG,aAAa,CACpD,KAAK,EACL,cAAc,EACd,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,CACnB,CAAC;QAEF,+BAA+B;QAC/B,IAAI,YAAY,GAAG,eAAe,CAAC;QACnC,IAAI,gBAAgB,GAAG,WAAW,CAAC;QAEnC,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAClB,sCAAsC;gBACtC,MAAM,WAAW,GAAG,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACvD,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;oBACzB,YAAY,GAAG,WAAW,CAAC;gBAC7B,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,mBAAmB;gBACnB,MAAM,YAAY,GAAG,kBAAkB,CACrC,QAAQ,CAAC,KAAK,IAAI,WAAW,CAAC,IAAI,CACnC,CAAC;gBACF,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;oBAC1B,gBAAgB,GAAG,YAAY,CAAC;gBAClC,CAAC;YACH,CAAC;QACH,CAAC;QAED,gBAAgB;QAChB,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,WAAW,CAC/C,IAAI,EACJ,UAAU,EACV,QAAQ,CACT,CAAC;QAEF,8BAA8B;QAC9B,MAAM,WAAW,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAEzE,OAAO;YACL,KAAK;YACL,eAAe,EAAE,YAAY;YAC7B,WAAW,EAAE,gBAAgB;YAC7B,SAAS;YACT,KAAK;YACL,OAAO;YACP,WAAW;SACZ,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,gFAAgF;AAChF,2CAA2C;AAC3C,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAAmB,EACnB,KAAa;IAEb,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC5B,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;YACjD,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAAmB,EACnB,aAA4B;IAE5B,IAAI,aAAa,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAExC,MAAM,IAAI,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC;IAClC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAEvB,6BAA6B;IAC7B,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,iDAAiD;IACjD,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;QACxD,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CACvC,KAAmB,EACnB,aAA4B;IAE5B,MAAM,aAAa,GAAG,gBAAgB,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;IAC7D,IAAI,aAAa,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACxC,OAAO,iBAAiB,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;AACjD,CAAC;AAED,gFAAgF;AAChF,4BAA4B;AAC5B,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAOjC;IACC,OAAO;QACL,SAAS,EAAE,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO;QAC1C,OAAO,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK;QACpC,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAItC;IACC,8CAA8C;IAC9C,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CACjD,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,CACxB,CAAC;IAE7B,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,KAAK,EACH,kBAAkB,CAAC,WAAW,IAAI,WAAW,CAAC,IAAI,CAAC;YACnD,UAAU,CAAC,QAAQ;QACrB,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;KAC1E,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,OAAO,EAAE,kBAAkB,EAAE,CAAC","sourcesContent":["/**\n * Sudoku presenter - port of renderable/SudokuPresenter.kt\n *\n * Handles all display logic for the Sudoku board including:\n * - Cell background colors based on selection state\n * - Cell border colors for selected cells\n * - Text colors (given, input, hint actions)\n * - Hint visualization (areas, cells)\n * - Pencilmark coloring\n */\n\nimport type { SudokuCell } from '../types/sudoku';\nimport { blockOf, columnOf, rowOf } from '../types/sudoku';\nimport {\n type CellDisplayState,\n type DisplayCellGroup,\n type DisplayLink,\n type HintCell,\n type HintStep,\n type PencilmarkDisplayState,\n SudokuColor,\n ThemeColor,\n UIColorDark,\n UIColorLight,\n type UIColorPalette,\n} from '../types/display';\n\n// =============================================================================\n// Block Definition (matches PlayBoard.blocks)\n// =============================================================================\n\n/**\n * Block class - matches Kotlin Block class\n */\nclass Block {\n readonly index: number;\n readonly cellIndices: number[];\n\n constructor(index: number) {\n this.index = index;\n const blockRow = Math.floor(index / 3);\n const blockCol = index % 3;\n this.cellIndices = [];\n for (let r = 0; r < 3; r++) {\n for (let c = 0; c < 3; c++) {\n const row = blockRow * 3 + r;\n const col = blockCol * 3 + c;\n this.cellIndices.push(row * 9 + col);\n }\n }\n }\n}\n\n/**\n * Row class - matches Kotlin Row class\n */\nclass Row {\n readonly index: number;\n readonly cellIndices: number[];\n\n constructor(index: number) {\n this.index = index;\n this.cellIndices = Array.from({ length: 9 }, (_, col) => index * 9 + col);\n }\n}\n\n/**\n * Column class - matches Kotlin Column class\n */\nclass Column {\n readonly index: number;\n readonly cellIndices: number[];\n\n constructor(index: number) {\n this.index = index;\n this.cellIndices = Array.from({ length: 9 }, (_, row) => row * 9 + index);\n }\n}\n\n// =============================================================================\n// Color Conversion (matches CellPresenter.colorOf)\n// =============================================================================\n\n/**\n * Convert SudokuColor to ThemeColor - matches CellPresenter.colorOf\n */\nfunction sudokuColorToTheme(\n sudokuColor: SudokuColor | null\n): ThemeColor | null {\n switch (sudokuColor) {\n case SudokuColor.BLUE:\n return ThemeColor.SELECTED;\n case SudokuColor.GREEN:\n return ThemeColor.SUCCESS;\n case SudokuColor.YELLOW:\n return ThemeColor.WARNING_SECONDARY;\n case SudokuColor.ORANGE:\n return ThemeColor.WARNING;\n case SudokuColor.RED:\n return ThemeColor.ERROR;\n case SudokuColor.WHITE:\n return ThemeColor.BACKGROUND;\n case SudokuColor.LIGHT_GRAY:\n return ThemeColor.BACKGROUND_SECONDARY;\n case SudokuColor.BLACK:\n return ThemeColor.LABEL;\n case SudokuColor.GRAY:\n return ThemeColor.LABEL_SECONDARY;\n case SudokuColor.CLEAR:\n return ThemeColor.CLEAR;\n default:\n return null;\n }\n}\n\n/**\n * Convert ThemeColor to actual CSS color - matches RendererColor.color\n */\nexport function themeColorToCSS(\n palette: UIColorPalette,\n themeColor: ThemeColor | null\n): string | null {\n switch (themeColor) {\n case ThemeColor.NONE:\n case ThemeColor.CLEAR:\n return palette.clear;\n case ThemeColor.SELECTED:\n return palette.systemPurple;\n case ThemeColor.SUCCESS:\n return palette.systemBlue;\n case ThemeColor.WARNING_SECONDARY:\n return palette.systemYellow;\n case ThemeColor.WARNING:\n return palette.systemOrange;\n case ThemeColor.ERROR:\n return palette.systemRed;\n case ThemeColor.BACKGROUND:\n return palette.systemBackground;\n case ThemeColor.BACKGROUND_SECONDARY:\n return palette.secondarySystemBackground;\n case ThemeColor.LABEL:\n return palette.label;\n case ThemeColor.LABEL_SECONDARY:\n return palette.secondaryLabel;\n case ThemeColor.DISABLED:\n return palette.systemGray;\n default:\n return null;\n }\n}\n\n/**\n * Get the color palette for the current theme\n */\nexport function getColorPalette(isDarkMode: boolean): UIColorPalette {\n return isDarkMode ? UIColorDark : UIColorLight;\n}\n\n// =============================================================================\n// Hint Processing (matches BoardPresenter.calculateCellHints)\n// =============================================================================\n\n/**\n * Process hint areas and cells into a map of cell hints\n * Matches BoardPresenter.calculateCellHints\n */\nexport function calculateCellHints(\n hintStep: HintStep | null\n): Map<number, HintCell> | null {\n if (!hintStep) return null;\n\n const hintsCell = new Map<number, HintCell>();\n\n // Process areas first\n hintStep.areas?.forEach(area => {\n let cellIndices: number[];\n\n switch (area.type) {\n case 'block':\n cellIndices = new Block(area.index).cellIndices;\n break;\n case 'row':\n cellIndices = new Row(area.index).cellIndices;\n break;\n case 'column':\n cellIndices = new Column(area.index).cellIndices;\n break;\n }\n\n cellIndices.forEach(index => {\n hintsCell.set(index, {\n index,\n color: area.color,\n fill: true, // Areas always use fill\n });\n });\n });\n\n // Process cells (overrides areas)\n hintStep.cells?.forEach(cell => {\n hintsCell.set(cell.index, cell);\n });\n\n return hintsCell;\n}\n\n// =============================================================================\n// Cell Color Logic (matches BlockPresenter.color)\n// =============================================================================\n\ninterface CellColorResult {\n backgroundColor: ThemeColor;\n borderColor: ThemeColor | null;\n}\n\n/**\n * Determine background and border colors for a cell\n * Matches BlockPresenter.color exactly\n */\nfunction getCellColors(\n cellIndex: number,\n cellBlockIndex: number,\n cellRowIndex: number,\n cellColumnIndex: number,\n cellHasValue: boolean,\n selectedIndex: number | null,\n selectedBlockIndex: number | null,\n selectedRowIndex: number | null,\n selectedColumnIndex: number | null,\n selectedDigitCells: Set<number> | null\n): CellColorResult {\n // Default background based on block (checkerboard pattern)\n const defaultBackgroundColor =\n cellBlockIndex % 2 === 0\n ? ThemeColor.BACKGROUND_SECONDARY\n : ThemeColor.BACKGROUND;\n\n if (selectedIndex === null) {\n return { backgroundColor: defaultBackgroundColor, borderColor: null };\n }\n\n if (selectedDigitCells !== null) {\n // Digit highlighting mode\n if (selectedDigitCells.has(cellIndex)) {\n // Highlighted cells (have the same digit)\n return { backgroundColor: ThemeColor.SELECTED, borderColor: null };\n }\n\n // Check if this cell is \"impossible\" (in same row/col/block as highlighted cells)\n let isImpossible = cellHasValue;\n if (!isImpossible) {\n for (const highlightedIndex of selectedDigitCells) {\n const hRow = rowOf(highlightedIndex);\n const hCol = columnOf(highlightedIndex);\n const hBlock = blockOf(highlightedIndex);\n if (\n cellRowIndex === hRow ||\n cellColumnIndex === hCol ||\n cellBlockIndex === hBlock\n ) {\n isImpossible = true;\n break;\n }\n }\n }\n\n if (isImpossible) {\n return { backgroundColor: ThemeColor.LABEL_SECONDARY, borderColor: null };\n }\n\n // Possible cells\n return { backgroundColor: defaultBackgroundColor, borderColor: null };\n }\n\n // Normal selection mode\n if (selectedIndex === cellIndex) {\n // Selected cell: default background + SELECTED border\n return {\n backgroundColor: defaultBackgroundColor,\n borderColor: ThemeColor.SELECTED,\n };\n }\n\n if (\n selectedBlockIndex === cellBlockIndex ||\n selectedRowIndex === cellRowIndex ||\n selectedColumnIndex === cellColumnIndex\n ) {\n // Same row, column or block: SELECTED background\n return { backgroundColor: ThemeColor.SELECTED, borderColor: null };\n }\n\n // Other cells\n return { backgroundColor: defaultBackgroundColor, borderColor: null };\n}\n\n// =============================================================================\n// Cell Text Logic (matches CellPresenter.present)\n// =============================================================================\n\ninterface CellTextResult {\n digit: number | null;\n textColor: ThemeColor | null;\n isGiven: boolean;\n}\n\n/**\n * Determine what digit and color to display in a cell\n * Matches CellPresenter.present logic\n */\nfunction getCellText(\n cell: SudokuCell,\n showErrors: boolean,\n hintCell: HintCell | null\n): CellTextResult {\n // Hint select action takes priority\n if (hintCell?.actions?.select != null) {\n return {\n digit: hintCell.actions.select,\n textColor: ThemeColor.SELECTED,\n isGiven: false,\n };\n }\n\n // Hint unselect action (wrong digit to remove)\n if (hintCell?.actions?.unselect != null) {\n return {\n digit: hintCell.actions.unselect,\n textColor: ThemeColor.ERROR,\n isGiven: false,\n };\n }\n\n // User input\n if (cell.input !== null) {\n let textColor: ThemeColor;\n if (showErrors) {\n textColor =\n cell.input === cell.solution ? ThemeColor.SUCCESS : ThemeColor.ERROR;\n } else {\n textColor = ThemeColor.LABEL_SECONDARY;\n }\n return { digit: cell.input, textColor, isGiven: false };\n }\n\n // Given (original)\n if (cell.given !== null) {\n return { digit: cell.given, textColor: ThemeColor.LABEL, isGiven: true };\n }\n\n return { digit: null, textColor: null, isGiven: false };\n}\n\n// =============================================================================\n// Pencilmark Logic (matches CellPresenter.present pencilmark section)\n// =============================================================================\n\n/**\n * Get pencilmark display states\n * Matches CellPresenter.present pencilmark logic\n */\nfunction getPencilmarks(\n cell: SudokuCell,\n hintCell: HintCell | null\n): PencilmarkDisplayState[] {\n const cellPencilmarks = cell.pencilmarks\n ? new Set(cell.pencilmarks)\n : new Set<number>();\n const adding = hintCell?.actions?.add ? new Set(hintCell.actions.add) : null;\n const removing = hintCell?.actions?.remove\n ? new Set(hintCell.actions.remove)\n : null;\n const highlighting = hintCell?.actions?.highlight\n ? new Set(hintCell.actions.highlight)\n : null;\n\n const result: PencilmarkDisplayState[] = [];\n\n for (let pencilmark = 1; pencilmark <= 9; pencilmark++) {\n let color: ThemeColor | null = null;\n\n if (highlighting?.has(pencilmark)) {\n color = ThemeColor.SELECTED;\n } else if (adding?.has(pencilmark)) {\n color = ThemeColor.SUCCESS;\n } else if (removing?.has(pencilmark)) {\n color = ThemeColor.ERROR;\n } else if (cellPencilmarks.has(pencilmark)) {\n color = ThemeColor.LABEL_SECONDARY;\n }\n\n if (color !== null) {\n result.push({ digit: pencilmark, color });\n }\n }\n\n return result;\n}\n\n// =============================================================================\n// Main Presenter Function\n// =============================================================================\n\nexport interface PresentBoardOptions {\n /** The 81 cells of the board */\n cells: SudokuCell[];\n /** Currently selected cell index (0-80) or null */\n selectedIndex: number | null;\n /** Whether to show errors (compare input vs solution) */\n showErrors: boolean;\n /** Current hint step (if any) */\n hintStep?: HintStep | null;\n /** Set of cell indices with the selected digit (for digit highlighting) */\n selectedDigitCells?: Set<number> | null;\n}\n\n/**\n * Generate display states for all cells\n * This is the main presenter function that matches the Kotlin renderable behavior\n */\nexport function presentBoard(options: PresentBoardOptions): CellDisplayState[] {\n const {\n cells,\n selectedIndex,\n showErrors,\n hintStep = null,\n selectedDigitCells = null,\n } = options;\n\n // Calculate hint cell map\n const cellHints = calculateCellHints(hintStep);\n\n // Get selected cell properties (if any)\n const _selectedCell = selectedIndex !== null ? cells[selectedIndex] : null;\n void _selectedCell; // Reserved for future use\n const selectedBlockIndex =\n selectedIndex !== null ? blockOf(selectedIndex) : null;\n const selectedRowIndex = selectedIndex !== null ? rowOf(selectedIndex) : null;\n const selectedColumnIndex =\n selectedIndex !== null ? columnOf(selectedIndex) : null;\n\n // Generate display state for each cell\n return cells.map((cell, index) => {\n const cellBlockIndex = blockOf(index);\n const cellRowIndex = rowOf(index);\n const cellColumnIndex = columnOf(index);\n const cellHasValue = cell.input !== null || cell.given !== null;\n\n // Get hint for this cell\n const hintCell = cellHints?.get(index) ?? null;\n\n // Get base colors\n const { backgroundColor, borderColor } = getCellColors(\n index,\n cellBlockIndex,\n cellRowIndex,\n cellColumnIndex,\n cellHasValue,\n selectedIndex,\n selectedBlockIndex,\n selectedRowIndex,\n selectedColumnIndex,\n selectedDigitCells\n );\n\n // Apply hint colors if present\n let finalBgColor = backgroundColor;\n let finalBorderColor = borderColor;\n\n if (hintCell) {\n if (hintCell.fill) {\n // Hint uses fill: override background\n const hintBgColor = sudokuColorToTheme(hintCell.color);\n if (hintBgColor !== null) {\n finalBgColor = hintBgColor;\n }\n } else {\n // Hint uses border\n const hintBdrColor = sudokuColorToTheme(\n hintCell.color ?? SudokuColor.BLUE\n );\n if (hintBdrColor !== null) {\n finalBorderColor = hintBdrColor;\n }\n }\n }\n\n // Get text info\n const { digit, textColor, isGiven } = getCellText(\n cell,\n showErrors,\n hintCell\n );\n\n // Get pencilmarks if no digit\n const pencilmarks = digit === null ? getPencilmarks(cell, hintCell) : [];\n\n return {\n index,\n backgroundColor: finalBgColor,\n borderColor: finalBorderColor,\n textColor,\n digit,\n isGiven,\n pencilmarks,\n };\n });\n}\n\n// =============================================================================\n// Utility: Get cells with a specific digit\n// =============================================================================\n\n/**\n * Get indices of cells that contain a specific digit (given or input)\n * Used for digit highlighting mode\n */\nexport function getCellsWithDigit(\n cells: SudokuCell[],\n digit: number\n): Set<number> {\n const result = new Set<number>();\n cells.forEach((cell, index) => {\n if (cell.given === digit || cell.input === digit) {\n result.add(index);\n }\n });\n return result;\n}\n\n/**\n * Get the selected digit for digit highlighting mode\n * Matches Kotlin SudokuInteractor.selectedDigit logic:\n * - If selected cell has a given value: return given\n * - If selected cell has a CORRECT input (input === solution): return input\n * - Otherwise: return null (no digit highlighting)\n */\nexport function getSelectedDigit(\n cells: SudokuCell[],\n selectedIndex: number | null\n): number | null {\n if (selectedIndex === null) return null;\n\n const cell = cells[selectedIndex];\n if (!cell) return null;\n\n // Given value takes priority\n if (cell.given !== null) {\n return cell.given;\n }\n\n // Only correct input triggers digit highlighting\n if (cell.input !== null && cell.input === cell.solution) {\n return cell.input;\n }\n\n return null;\n}\n\n/**\n * Compute selectedDigitCells based on selected cell\n * Returns Set of cell indices that have the same digit as selected cell\n * Returns null if selected cell doesn't have a highlightable digit\n */\nexport function computeSelectedDigitCells(\n cells: SudokuCell[],\n selectedIndex: number | null\n): Set<number> | null {\n const selectedDigit = getSelectedDigit(cells, selectedIndex);\n if (selectedDigit === null) return null;\n return getCellsWithDigit(cells, selectedDigit);\n}\n\n// =============================================================================\n// Link and Group Conversion\n// =============================================================================\n\n/**\n * Convert a solver link to display link format\n * Converts row/col coordinates to flat cell index\n */\nexport function convertSolverLink(link: {\n fromRow: number;\n fromCol: number;\n toRow: number;\n toCol: number;\n type: 'strong' | 'weak';\n digit: number;\n}): DisplayLink {\n return {\n fromIndex: link.fromRow * 9 + link.fromCol,\n toIndex: link.toRow * 9 + link.toCol,\n type: link.type,\n digit: link.digit,\n };\n}\n\n/**\n * Convert a solver cell group to display format\n * Converts row/col pairs to flat cell indices and SolverColor to ThemeColor\n */\nexport function convertSolverCellGroup(group: {\n name: string;\n color: string;\n cells: number[][];\n}): DisplayCellGroup {\n // Map solver color string to SudokuColor enum\n const sudokuColor = Object.values(SudokuColor).find(\n c => c.toLowerCase() === group.color.toLowerCase()\n ) as SudokuColor | undefined;\n\n return {\n name: group.name,\n color:\n sudokuColorToTheme(sudokuColor ?? SudokuColor.BLUE) ??\n ThemeColor.SELECTED,\n cellIndices: group.cells.map(cell => (cell[0] ?? 0) * 9 + (cell[1] ?? 0)),\n };\n}\n\n/**\n * Export sudokuColorToTheme for external use\n */\nexport { sudokuColorToTheme };\n"]}
1
+ {"version":3,"file":"sudokuPresenter.js","sourceRoot":"","sources":["../../src/utils/sudokuPresenter.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Sudoku presenter - port of renderable/SudokuPresenter.kt\n *\n * Handles all display logic for the Sudoku board including:\n * - Cell background colors based on selection state\n * - Cell border colors for selected cells\n * - Text colors (given, input, hint actions)\n * - Hint visualization (areas, cells)\n * - Pencilmark coloring\n */\n\nimport type { SudokuCell } from '../types/sudoku';\nimport { blockOf, columnOf, rowOf } from '../types/sudoku';\nimport {\n type CellDisplayState,\n type DisplayCellGroup,\n type DisplayLink,\n type HintCell,\n type HintStep,\n type PencilmarkDisplayState,\n SudokuColor,\n ThemeColor,\n UIColorDark,\n UIColorLight,\n type UIColorPalette,\n} from '../types/display';\n\n// =============================================================================\n// Block Definition (matches PlayBoard.blocks)\n// =============================================================================\n\n/**\n * Block class - matches Kotlin Block class\n */\nclass Block {\n readonly index: number;\n readonly cellIndices: number[];\n\n constructor(index: number) {\n this.index = index;\n const blockRow = Math.floor(index / 3);\n const blockCol = index % 3;\n this.cellIndices = [];\n for (let r = 0; r < 3; r++) {\n for (let c = 0; c < 3; c++) {\n const row = blockRow * 3 + r;\n const col = blockCol * 3 + c;\n this.cellIndices.push(row * 9 + col);\n }\n }\n }\n}\n\n/**\n * Row class - matches Kotlin Row class\n */\nclass Row {\n readonly index: number;\n readonly cellIndices: number[];\n\n constructor(index: number) {\n this.index = index;\n this.cellIndices = Array.from({ length: 9 }, (_, col) => index * 9 + col);\n }\n}\n\n/**\n * Column class - matches Kotlin Column class\n */\nclass Column {\n readonly index: number;\n readonly cellIndices: number[];\n\n constructor(index: number) {\n this.index = index;\n this.cellIndices = Array.from({ length: 9 }, (_, row) => row * 9 + index);\n }\n}\n\n// =============================================================================\n// Color Conversion (matches CellPresenter.colorOf)\n// =============================================================================\n\n/**\n * Convert SudokuColor to ThemeColor - matches CellPresenter.colorOf\n */\nfunction sudokuColorToTheme(\n sudokuColor: SudokuColor | null\n): ThemeColor | null {\n switch (sudokuColor) {\n case SudokuColor.BLUE:\n return ThemeColor.SELECTED;\n case SudokuColor.GREEN:\n return ThemeColor.SUCCESS;\n case SudokuColor.YELLOW:\n return ThemeColor.WARNING_SECONDARY;\n case SudokuColor.ORANGE:\n return ThemeColor.WARNING;\n case SudokuColor.RED:\n return ThemeColor.ERROR;\n case SudokuColor.WHITE:\n return ThemeColor.BACKGROUND;\n case SudokuColor.LIGHT_GRAY:\n return ThemeColor.BACKGROUND_SECONDARY;\n case SudokuColor.BLACK:\n return ThemeColor.LABEL;\n case SudokuColor.GRAY:\n return ThemeColor.LABEL_SECONDARY;\n case SudokuColor.CLEAR:\n return ThemeColor.CLEAR;\n default:\n return null;\n }\n}\n\n/**\n * Convert ThemeColor to actual CSS color - matches RendererColor.color\n */\nexport function themeColorToCSS(\n palette: UIColorPalette,\n themeColor: ThemeColor | null\n): string | null {\n switch (themeColor) {\n case ThemeColor.NONE:\n case ThemeColor.CLEAR:\n return palette.clear;\n case ThemeColor.SELECTED:\n return palette.systemPurple;\n case ThemeColor.SUCCESS:\n return palette.systemBlue;\n case ThemeColor.WARNING_SECONDARY:\n return palette.systemYellow;\n case ThemeColor.WARNING:\n return palette.systemOrange;\n case ThemeColor.ERROR:\n return palette.systemRed;\n case ThemeColor.BACKGROUND:\n return palette.systemBackground;\n case ThemeColor.BACKGROUND_SECONDARY:\n return palette.secondarySystemBackground;\n case ThemeColor.LABEL:\n return palette.label;\n case ThemeColor.LABEL_SECONDARY:\n return palette.secondaryLabel;\n case ThemeColor.DISABLED:\n return palette.systemGray;\n default:\n return null;\n }\n}\n\n/**\n * Get the color palette for the current theme\n */\nexport function getColorPalette(isDarkMode: boolean): UIColorPalette {\n return isDarkMode ? UIColorDark : UIColorLight;\n}\n\n// =============================================================================\n// Hint Processing (matches BoardPresenter.calculateCellHints)\n// =============================================================================\n\n/**\n * Process hint areas and cells into a map of cell hints\n * Matches BoardPresenter.calculateCellHints\n */\nexport function calculateCellHints(\n hintStep: HintStep | null\n): Map<number, HintCell> | null {\n if (!hintStep) return null;\n\n const hintsCell = new Map<number, HintCell>();\n\n // Process areas first\n hintStep.areas?.forEach(area => {\n let cellIndices: number[];\n\n switch (area.type) {\n case 'block':\n cellIndices = new Block(area.index).cellIndices;\n break;\n case 'row':\n cellIndices = new Row(area.index).cellIndices;\n break;\n case 'column':\n cellIndices = new Column(area.index).cellIndices;\n break;\n }\n\n cellIndices.forEach(index => {\n hintsCell.set(index, {\n index,\n color: area.color,\n fill: true, // Areas always use fill\n });\n });\n });\n\n // Process cells (overrides areas)\n hintStep.cells?.forEach(cell => {\n hintsCell.set(cell.index, cell);\n });\n\n return hintsCell;\n}\n\n// =============================================================================\n// Cell Color Logic (matches BlockPresenter.color)\n// =============================================================================\n\ninterface CellColorResult {\n backgroundColor: ThemeColor;\n borderColor: ThemeColor | null;\n}\n\n/**\n * Determine background and border colors for a cell\n * Matches BlockPresenter.color exactly\n */\nfunction getCellColors(\n cellIndex: number,\n cellBlockIndex: number,\n cellRowIndex: number,\n cellColumnIndex: number,\n cellHasValue: boolean,\n selectedIndex: number | null,\n selectedBlockIndex: number | null,\n selectedRowIndex: number | null,\n selectedColumnIndex: number | null,\n selectedDigitCells: Set<number> | null\n): CellColorResult {\n // Default background based on block (checkerboard pattern)\n const defaultBackgroundColor =\n cellBlockIndex % 2 === 0\n ? ThemeColor.BACKGROUND_SECONDARY\n : ThemeColor.BACKGROUND;\n\n if (selectedIndex === null) {\n return { backgroundColor: defaultBackgroundColor, borderColor: null };\n }\n\n if (selectedDigitCells !== null) {\n // Digit highlighting mode\n if (selectedDigitCells.has(cellIndex)) {\n // Highlighted cells (have the same digit)\n return { backgroundColor: ThemeColor.SELECTED, borderColor: null };\n }\n\n // Check if this cell is \"impossible\" (in same row/col/block as highlighted cells)\n let isImpossible = cellHasValue;\n if (!isImpossible) {\n for (const highlightedIndex of selectedDigitCells) {\n const hRow = rowOf(highlightedIndex);\n const hCol = columnOf(highlightedIndex);\n const hBlock = blockOf(highlightedIndex);\n if (\n cellRowIndex === hRow ||\n cellColumnIndex === hCol ||\n cellBlockIndex === hBlock\n ) {\n isImpossible = true;\n break;\n }\n }\n }\n\n if (isImpossible) {\n return { backgroundColor: ThemeColor.LABEL_SECONDARY, borderColor: null };\n }\n\n // Possible cells\n return { backgroundColor: defaultBackgroundColor, borderColor: null };\n }\n\n // Normal selection mode\n if (selectedIndex === cellIndex) {\n // Selected cell: default background + SELECTED border\n return {\n backgroundColor: defaultBackgroundColor,\n borderColor: ThemeColor.SELECTED,\n };\n }\n\n if (\n selectedBlockIndex === cellBlockIndex ||\n selectedRowIndex === cellRowIndex ||\n selectedColumnIndex === cellColumnIndex\n ) {\n // Same row, column or block: SELECTED background\n return { backgroundColor: ThemeColor.SELECTED, borderColor: null };\n }\n\n // Other cells\n return { backgroundColor: defaultBackgroundColor, borderColor: null };\n}\n\n// =============================================================================\n// Cell Text Logic (matches CellPresenter.present)\n// =============================================================================\n\ninterface CellTextResult {\n digit: number | null;\n textColor: ThemeColor | null;\n isGiven: boolean;\n}\n\n/**\n * Determine what digit and color to display in a cell\n * Matches CellPresenter.present logic\n */\nfunction getCellText(\n cell: SudokuCell,\n showErrors: boolean,\n hintCell: HintCell | null\n): CellTextResult {\n // Hint select action takes priority\n if (hintCell?.actions?.select != null) {\n return {\n digit: hintCell.actions.select,\n textColor: ThemeColor.SELECTED,\n isGiven: false,\n };\n }\n\n // Hint unselect action (wrong digit to remove)\n if (hintCell?.actions?.unselect != null) {\n return {\n digit: hintCell.actions.unselect,\n textColor: ThemeColor.ERROR,\n isGiven: false,\n };\n }\n\n // User input\n if (cell.input !== null) {\n let textColor: ThemeColor;\n if (showErrors) {\n textColor =\n cell.input === cell.solution ? ThemeColor.SUCCESS : ThemeColor.ERROR;\n } else {\n textColor = ThemeColor.LABEL_SECONDARY;\n }\n return { digit: cell.input, textColor, isGiven: false };\n }\n\n // Given (original)\n if (cell.given !== null) {\n return { digit: cell.given, textColor: ThemeColor.LABEL, isGiven: true };\n }\n\n return { digit: null, textColor: null, isGiven: false };\n}\n\n// =============================================================================\n// Pencilmark Logic (matches CellPresenter.present pencilmark section)\n// =============================================================================\n\n/**\n * Get pencilmark display states\n * Matches CellPresenter.present pencilmark logic\n */\nfunction getPencilmarks(\n cell: SudokuCell,\n hintCell: HintCell | null\n): PencilmarkDisplayState[] {\n const cellPencilmarks = cell.pencilmarks\n ? new Set(cell.pencilmarks)\n : new Set<number>();\n const adding = hintCell?.actions?.add ? new Set(hintCell.actions.add) : null;\n const removing = hintCell?.actions?.remove\n ? new Set(hintCell.actions.remove)\n : null;\n const highlighting = hintCell?.actions?.highlight\n ? new Set(hintCell.actions.highlight)\n : null;\n\n const result: PencilmarkDisplayState[] = [];\n\n for (let pencilmark = 1; pencilmark <= 9; pencilmark++) {\n let color: ThemeColor | null = null;\n\n if (highlighting?.has(pencilmark)) {\n color = ThemeColor.SELECTED;\n } else if (adding?.has(pencilmark)) {\n color = ThemeColor.SUCCESS;\n } else if (removing?.has(pencilmark)) {\n color = ThemeColor.ERROR;\n } else if (cellPencilmarks.has(pencilmark)) {\n color = ThemeColor.LABEL_SECONDARY;\n }\n\n if (color !== null) {\n result.push({ digit: pencilmark, color });\n }\n }\n\n return result;\n}\n\n// =============================================================================\n// Main Presenter Function\n// =============================================================================\n\nexport interface PresentBoardOptions {\n /** The 81 cells of the board */\n cells: SudokuCell[];\n /** Currently selected cell index (0-80) or null */\n selectedIndex: number | null;\n /** Whether to show errors (compare input vs solution) */\n showErrors: boolean;\n /** Current hint step (if any) */\n hintStep?: HintStep | null;\n /** Set of cell indices with the selected digit (for digit highlighting) */\n selectedDigitCells?: Set<number> | null;\n}\n\n/**\n * Generate display states for all cells\n * This is the main presenter function that matches the Kotlin renderable behavior\n */\nexport function presentBoard(options: PresentBoardOptions): CellDisplayState[] {\n const {\n cells,\n selectedIndex,\n showErrors,\n hintStep = null,\n selectedDigitCells = null,\n } = options;\n\n // Calculate hint cell map\n const cellHints = calculateCellHints(hintStep);\n\n // Get selected cell properties (if any)\n const _selectedCell = selectedIndex !== null ? cells[selectedIndex] : null;\n void _selectedCell; // Reserved for future use\n const selectedBlockIndex =\n selectedIndex !== null ? blockOf(selectedIndex) : null;\n const selectedRowIndex = selectedIndex !== null ? rowOf(selectedIndex) : null;\n const selectedColumnIndex =\n selectedIndex !== null ? columnOf(selectedIndex) : null;\n\n // Generate display state for each cell\n return cells.map((cell, index) => {\n const cellBlockIndex = blockOf(index);\n const cellRowIndex = rowOf(index);\n const cellColumnIndex = columnOf(index);\n const cellHasValue = cell.input !== null || cell.given !== null;\n\n // Get hint for this cell\n const hintCell = cellHints?.get(index) ?? null;\n\n // Get base colors\n const { backgroundColor, borderColor } = getCellColors(\n index,\n cellBlockIndex,\n cellRowIndex,\n cellColumnIndex,\n cellHasValue,\n selectedIndex,\n selectedBlockIndex,\n selectedRowIndex,\n selectedColumnIndex,\n selectedDigitCells\n );\n\n // Apply hint colors if present\n let finalBgColor = backgroundColor;\n let finalBorderColor = borderColor;\n\n if (hintCell) {\n if (hintCell.fill) {\n // Hint uses fill: override background\n const hintBgColor = sudokuColorToTheme(hintCell.color);\n if (hintBgColor !== null) {\n finalBgColor = hintBgColor;\n }\n } else {\n // Hint uses border\n const hintBdrColor = sudokuColorToTheme(\n hintCell.color ?? SudokuColor.BLUE\n );\n if (hintBdrColor !== null) {\n finalBorderColor = hintBdrColor;\n }\n }\n }\n\n // Get text info\n const { digit, textColor, isGiven } = getCellText(\n cell,\n showErrors,\n hintCell\n );\n\n // Get pencilmarks if no digit\n const pencilmarks = digit === null ? getPencilmarks(cell, hintCell) : [];\n\n return {\n index,\n backgroundColor: finalBgColor,\n borderColor: finalBorderColor,\n textColor,\n digit,\n isGiven,\n pencilmarks,\n };\n });\n}\n\n// =============================================================================\n// Utility: Get cells with a specific digit\n// =============================================================================\n\n/**\n * Get indices of cells that contain a specific digit (given or input)\n * Used for digit highlighting mode\n */\nexport function getCellsWithDigit(\n cells: SudokuCell[],\n digit: number\n): Set<number> {\n const result = new Set<number>();\n cells.forEach((cell, index) => {\n if (cell.given === digit || cell.input === digit) {\n result.add(index);\n }\n });\n return result;\n}\n\n/**\n * Get the selected digit for digit highlighting mode\n * Matches Kotlin SudokuInteractor.selectedDigit logic:\n * - If selected cell has a given value: return given\n * - If selected cell has a CORRECT input (input === solution): return input\n * - Otherwise: return null (no digit highlighting)\n */\nexport function getSelectedDigit(\n cells: SudokuCell[],\n selectedIndex: number | null\n): number | null {\n if (selectedIndex === null) return null;\n\n const cell = cells[selectedIndex];\n if (!cell) return null;\n\n // Given value takes priority\n if (cell.given !== null) {\n return cell.given;\n }\n\n // Only correct input triggers digit highlighting\n if (cell.input !== null && cell.input === cell.solution) {\n return cell.input;\n }\n\n return null;\n}\n\n/**\n * Compute selectedDigitCells based on selected cell\n * Returns Set of cell indices that have the same digit as selected cell\n * Returns null if selected cell doesn't have a highlightable digit\n */\nexport function computeSelectedDigitCells(\n cells: SudokuCell[],\n selectedIndex: number | null\n): Set<number> | null {\n const selectedDigit = getSelectedDigit(cells, selectedIndex);\n if (selectedDigit === null) return null;\n return getCellsWithDigit(cells, selectedDigit);\n}\n\n// =============================================================================\n// Link and Group Conversion\n// =============================================================================\n\n/**\n * Convert a solver link to display link format\n * Converts row/col coordinates to flat cell index\n */\nexport function convertSolverLink(link: {\n fromRow: number;\n fromCol: number;\n toRow: number;\n toCol: number;\n type: 'strong' | 'weak' | 'conflict';\n digit: number;\n}): DisplayLink {\n return {\n fromIndex: link.fromRow * 9 + link.fromCol,\n toIndex: link.toRow * 9 + link.toCol,\n type: link.type,\n digit: link.digit,\n };\n}\n\n/**\n * Convert a solver cell group to display format\n * Converts row/col pairs to flat cell indices and SolverColor to ThemeColor\n */\nexport function convertSolverCellGroup(group: {\n name: string;\n color: string;\n cells: number[][];\n}): DisplayCellGroup {\n // Map solver color string to SudokuColor enum\n const sudokuColor = Object.values(SudokuColor).find(\n c => c.toLowerCase() === group.color.toLowerCase()\n ) as SudokuColor | undefined;\n\n return {\n name: group.name,\n color:\n sudokuColorToTheme(sudokuColor ?? SudokuColor.BLUE) ??\n ThemeColor.SELECTED,\n cellIndices: group.cells.map(cell => (cell[0] ?? 0) * 9 + (cell[1] ?? 0)),\n };\n}\n\n/**\n * Export sudokuColorToTheme for external use\n */\nexport { sudokuColorToTheme };\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sudobility/sudojo_lib",
3
- "version": "0.0.142",
3
+ "version": "0.0.143",
4
4
  "description": "Business logic library for Sudojo app",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",