@sudobility/sudojo_lib 0.0.162 → 0.0.164
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.
|
@@ -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;
|
|
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;AAoKD;;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// DESIGN-TOKEN EXCEPTION (intentional hardcoded color VALUES — do not migrate\n// to @sudobility/design className tokens):\n//\n// The hex literals below are an identity color palette: the source-of-truth iOS\n// UIColor system colors (light + dark). They are consumed as concrete CSS color\n// strings by `themeColorToCSS()`/`getColorPalette()` (see utils/sudokuPresenter)\n// to render the Sudoku board to a <canvas> (fillStyle/strokeStyle) and inline\n// styles. Semantic className tokens (`bg-card`, `text-foreground`, …) cannot be\n// assigned to a canvas context or used by this framework-agnostic business-logic\n// library, which emits no className/Tailwind utilities. These values are kept\n// verbatim, like a chart/category palette.\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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"techniqueWalkthrough.d.ts","sourceRoot":"","sources":["../../src/utils/techniqueWalkthrough.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC5E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAKzD,+CAA+C;AAC/C,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAID,sEAAsE;AACtE,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,MAAM,GAAG,IAAI,GAC5B,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CASrB;AAED,2EAA2E;AAC3E,wBAAgB,mBAAmB,CACjC,gBAAgB,EAAE,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,GACpC,MAAM,CAIR;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,GAAG,IAAI,EAC7B,WAAW,EAAE,MAAM,GAClB,UAAU,EAAE,CAmBd;AAID,qEAAqE;AACrE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAKlE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,UAAU,EAAE,EACnB,IAAI,EAAE,cAAc,GACnB;IAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAqD9C;AAID,qDAAqD;AACrD,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,WAAW,GAAG,IAAI,CAO5E;AAID;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,iBAAiB,EAC1B,aAAa,CAAC,EAAE,MAAM,GACrB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAYjC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,UAAU,EAAE,EAC1B,QAAQ,EAAE,WAAW,GAAG,IAAI,EAC5B,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,iBAAiB,EAC1B,aAAa,CAAC,EAAE,MAAM,GACrB,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"techniqueWalkthrough.d.ts","sourceRoot":"","sources":["../../src/utils/techniqueWalkthrough.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC5E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAKzD,+CAA+C;AAC/C,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAID,sEAAsE;AACtE,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,MAAM,GAAG,IAAI,GAC5B,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CASrB;AAED,2EAA2E;AAC3E,wBAAgB,mBAAmB,CACjC,gBAAgB,EAAE,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,GACpC,MAAM,CAIR;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,GAAG,IAAI,EAC7B,WAAW,EAAE,MAAM,GAClB,UAAU,EAAE,CAmBd;AAID,qEAAqE;AACrE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAKlE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,UAAU,EAAE,EACnB,IAAI,EAAE,cAAc,GACnB;IAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAqD9C;AAID,qDAAqD;AACrD,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,WAAW,GAAG,IAAI,CAO5E;AAID;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,iBAAiB,EAC1B,aAAa,CAAC,EAAE,MAAM,GACrB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAYjC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,UAAU,EAAE,EAC1B,QAAQ,EAAE,WAAW,GAAG,IAAI,EAC5B,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,iBAAiB,EAC1B,aAAa,CAAC,EAAE,MAAM,GACrB,eAAe,EAAE,CAuCnB"}
|
|
@@ -168,8 +168,7 @@ export function buildWalkthroughSteps(initialBoard, hintData, lookForText, resul
|
|
|
168
168
|
steps.push({ board: initialBoard, hint: null, title: '', text: lookForText });
|
|
169
169
|
// Steps 1-N: Each hint step with overlay, then apply changes
|
|
170
170
|
let currentBoard = cloneSudokuBoard(initialBoard);
|
|
171
|
-
for (
|
|
172
|
-
const hintStep = hintData.steps[i];
|
|
171
|
+
for (const hintStep of hintData.steps) {
|
|
173
172
|
const localized = localizeHintStep(hintStep, tHints, tCommon, techniquePath);
|
|
174
173
|
steps.push({
|
|
175
174
|
board: cloneSudokuBoard(currentBoard),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"techniqueWalkthrough.js","sourceRoot":"","sources":["../../src/utils/techniqueWalkthrough.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Technique walkthrough utilities.\n *\n * Shared logic for building step-by-step technique examples from\n * practice puzzle data. Used by both the web app and React Native app\n * TechniqueExample components.\n */\n\nimport type { SolverHints, SolverHintStep } from '@sudobility/sudojo_types';\nimport type { SudokuCell } from '../types/sudoku';\nimport type { TranslateFunction } from './localizedHint';\nimport { getLocalizedHintText, getLocalizedHintTitle } from './localizedHint';\n\n// ── Types ───────────────────────────────────────────────────────────────────\n\n/** A single step in a technique walkthrough */\nexport interface WalkthroughStep {\n board: SudokuCell[];\n hint: SolverHintStep | null;\n title: string;\n text: string;\n}\n\n// ── Board parsing ───────────────────────────────────────────────────────────\n\n/** Parse a comma-delimited pencilmarks string into per-cell arrays */\nexport function parsePencilmarksString(\n pencilmarksStr: string | null\n): (number[] | null)[] {\n if (!pencilmarksStr) return [];\n return pencilmarksStr.split(',').map(pm => {\n if (!pm || pm.trim() === '') return null;\n return pm\n .split('')\n .map(d => parseInt(d, 10))\n .filter(n => n >= 1 && n <= 9);\n });\n}\n\n/** Convert per-cell pencilmarks arrays back to a comma-delimited string */\nexport function pencilmarksToString(\n pencilmarksArray: (number[] | null)[]\n): string {\n return pencilmarksArray\n .map(pm => (pm && pm.length > 0 ? pm.sort((a, b) => a - b).join('') : ''))\n .join(',');\n}\n\n/**\n * Parse board, pencilmarks and solution strings into a SudokuCell array.\n * This is the format returned by the practice API.\n */\nexport function parsePracticeBoard(\n boardStr: string,\n pencilmarksStr: string | null,\n solutionStr: string\n): SudokuCell[] {\n const pencilmarksArray = parsePencilmarksString(pencilmarksStr);\n\n return Array.from({ length: 81 }, (_, index) => {\n const boardChar = boardStr[index] || '0';\n const solutionChar = solutionStr[index] || '0';\n const boardValue = parseInt(boardChar, 10);\n const solutionValue = parseInt(solutionChar, 10);\n const hasValue = boardValue >= 1 && boardValue <= 9;\n\n return {\n index,\n solution: solutionValue >= 1 && solutionValue <= 9 ? solutionValue : null,\n given: hasValue ? boardValue : null,\n input: null,\n pencilmarks:\n !hasValue && pencilmarksArray[index] ? pencilmarksArray[index] : null,\n };\n });\n}\n\n// ── Board manipulation ──────────────────────────────────────────────────────\n\n/** Deep clone a SudokuCell array (preserves pencilmarks by value) */\nexport function cloneSudokuBoard(board: SudokuCell[]): SudokuCell[] {\n return board.map(cell => ({\n ...cell,\n pencilmarks: cell.pencilmarks ? [...cell.pencilmarks] : null,\n }));\n}\n\n/**\n * Apply a hint step's actions (select / remove / add) to a board,\n * returning the new board state and serialised pencilmarks.\n */\nexport function applyHintStep(\n board: SudokuCell[],\n step: SolverHintStep\n): { board: SudokuCell[]; pencilmarks: string } {\n const newBoard = cloneSudokuBoard(board);\n\n for (const hintCell of step.cells || []) {\n const index = hintCell.row * 9 + hintCell.column;\n const cell = newBoard[index];\n if (!cell || cell.given !== null) continue;\n\n const actions = hintCell.actions;\n if (!actions) continue;\n\n // Place digit\n if (actions.select && actions.select !== '') {\n const digit = parseInt(actions.select, 10);\n if (digit >= 1 && digit <= 9) {\n cell.input = digit;\n cell.pencilmarks = null;\n }\n }\n\n // Eliminate pencilmarks\n if (actions.remove && actions.remove !== '' && cell.pencilmarks) {\n const toRemove = new Set(\n actions.remove\n .split('')\n .map(d => parseInt(d, 10))\n .filter(n => n >= 1 && n <= 9)\n );\n cell.pencilmarks = cell.pencilmarks.filter(pm => !toRemove.has(pm));\n if (cell.pencilmarks.length === 0) {\n cell.pencilmarks = null;\n }\n }\n\n // Add pencilmarks\n if (actions.add && actions.add !== '') {\n const toAdd = actions.add\n .split('')\n .map(d => parseInt(d, 10))\n .filter(n => n >= 1 && n <= 9);\n if (toAdd.length > 0) {\n const existing = new Set(cell.pencilmarks || []);\n toAdd.forEach(d => existing.add(d));\n cell.pencilmarks = Array.from(existing).sort((a, b) => a - b);\n }\n }\n }\n\n const pencilmarksStr = pencilmarksToString(\n newBoard.map(cell => cell.pencilmarks)\n );\n\n return { board: newBoard, pencilmarks: pencilmarksStr };\n}\n\n// ── Hint data parsing ───────────────────────────────────────────────────────\n\n/** Parse a hint_data JSON string into SolverHints */\nexport function parseHintData(hintDataStr: string | null): SolverHints | null {\n if (!hintDataStr) return null;\n try {\n return JSON.parse(hintDataStr) as SolverHints;\n } catch {\n return null;\n }\n}\n\n// ── Walkthrough builder ─────────────────────────────────────────────────────\n\n/**\n * Resolve localised title and text for a single hint step.\n *\n * @param step - The solver hint step\n * @param tHints - Translation function scoped to the `hints` namespace\n * @param tCommon - Translation function scoped to the default namespace\n * @param techniquePath - Optional technique path slug for title fallback\n */\nexport function localizeHintStep(\n step: SolverHintStep,\n tHints: TranslateFunction,\n tCommon: TranslateFunction,\n techniquePath?: string\n): { title: string; text: string } {\n let title = getLocalizedHintTitle(tCommon, step);\n if (title === step.title && techniquePath) {\n const translated = tCommon(`techniques.${techniquePath}.title`);\n if (translated !== `techniques.${techniquePath}.title`) {\n title = translated;\n }\n }\n return {\n title,\n text: getLocalizedHintText(tHints, step),\n };\n}\n\n/**\n * Build the full walkthrough step array from an initial board and hint data.\n *\n * - Step 0: Original board with \"Look for {technique}\" text\n * - Steps 1-N: Each hint step with overlay; board progresses after each step\n * - Final step: Result board after all steps applied, no overlay\n *\n * @param initialBoard - Parsed SudokuCell[] from practice data\n * @param hintData - Parsed SolverHints (or null)\n * @param lookForText - Already-translated \"Look for …\" string\n * @param resultText - Already-translated result text\n * @param tHints - Translation function scoped to the `hints` namespace\n * @param tCommon - Translation function scoped to the default namespace\n * @param techniquePath - Optional technique path slug for title fallback\n */\nexport function buildWalkthroughSteps(\n initialBoard: SudokuCell[],\n hintData: SolverHints | null,\n lookForText: string,\n resultText: string,\n tHints: TranslateFunction,\n tCommon: TranslateFunction,\n techniquePath?: string\n): WalkthroughStep[] {\n const steps: WalkthroughStep[] = [];\n\n if (!hintData?.steps?.length) {\n steps.push({\n board: initialBoard,\n hint: null,\n title: '',\n text: lookForText,\n });\n return steps;\n }\n\n // Step 0: Original board\n steps.push({ board: initialBoard, hint: null, title: '', text: lookForText });\n\n // Steps 1-N: Each hint step with overlay, then apply changes\n let currentBoard = cloneSudokuBoard(initialBoard);\n for (let i = 0; i < hintData.steps.length; i++) {\n const hintStep = hintData.steps[i]!;\n const localized = localizeHintStep(\n hintStep,\n tHints,\n tCommon,\n techniquePath\n );\n steps.push({\n board: cloneSudokuBoard(currentBoard),\n hint: hintStep,\n title: localized.title,\n text: localized.text,\n });\n const result = applyHintStep(currentBoard, hintStep);\n currentBoard = result.board;\n }\n\n // Final step: Result after all steps applied\n steps.push({ board: currentBoard, hint: null, title: '', text: resultText });\n\n return steps;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"techniqueWalkthrough.js","sourceRoot":"","sources":["../../src/utils/techniqueWalkthrough.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Technique walkthrough utilities.\n *\n * Shared logic for building step-by-step technique examples from\n * practice puzzle data. Used by both the web app and React Native app\n * TechniqueExample components.\n */\n\nimport type { SolverHints, SolverHintStep } from '@sudobility/sudojo_types';\nimport type { SudokuCell } from '../types/sudoku';\nimport type { TranslateFunction } from './localizedHint';\nimport { getLocalizedHintText, getLocalizedHintTitle } from './localizedHint';\n\n// ── Types ───────────────────────────────────────────────────────────────────\n\n/** A single step in a technique walkthrough */\nexport interface WalkthroughStep {\n board: SudokuCell[];\n hint: SolverHintStep | null;\n title: string;\n text: string;\n}\n\n// ── Board parsing ───────────────────────────────────────────────────────────\n\n/** Parse a comma-delimited pencilmarks string into per-cell arrays */\nexport function parsePencilmarksString(\n pencilmarksStr: string | null\n): (number[] | null)[] {\n if (!pencilmarksStr) return [];\n return pencilmarksStr.split(',').map(pm => {\n if (!pm || pm.trim() === '') return null;\n return pm\n .split('')\n .map(d => parseInt(d, 10))\n .filter(n => n >= 1 && n <= 9);\n });\n}\n\n/** Convert per-cell pencilmarks arrays back to a comma-delimited string */\nexport function pencilmarksToString(\n pencilmarksArray: (number[] | null)[]\n): string {\n return pencilmarksArray\n .map(pm => (pm && pm.length > 0 ? pm.sort((a, b) => a - b).join('') : ''))\n .join(',');\n}\n\n/**\n * Parse board, pencilmarks and solution strings into a SudokuCell array.\n * This is the format returned by the practice API.\n */\nexport function parsePracticeBoard(\n boardStr: string,\n pencilmarksStr: string | null,\n solutionStr: string\n): SudokuCell[] {\n const pencilmarksArray = parsePencilmarksString(pencilmarksStr);\n\n return Array.from({ length: 81 }, (_, index) => {\n const boardChar = boardStr[index] || '0';\n const solutionChar = solutionStr[index] || '0';\n const boardValue = parseInt(boardChar, 10);\n const solutionValue = parseInt(solutionChar, 10);\n const hasValue = boardValue >= 1 && boardValue <= 9;\n\n return {\n index,\n solution: solutionValue >= 1 && solutionValue <= 9 ? solutionValue : null,\n given: hasValue ? boardValue : null,\n input: null,\n pencilmarks:\n !hasValue && pencilmarksArray[index] ? pencilmarksArray[index] : null,\n };\n });\n}\n\n// ── Board manipulation ──────────────────────────────────────────────────────\n\n/** Deep clone a SudokuCell array (preserves pencilmarks by value) */\nexport function cloneSudokuBoard(board: SudokuCell[]): SudokuCell[] {\n return board.map(cell => ({\n ...cell,\n pencilmarks: cell.pencilmarks ? [...cell.pencilmarks] : null,\n }));\n}\n\n/**\n * Apply a hint step's actions (select / remove / add) to a board,\n * returning the new board state and serialised pencilmarks.\n */\nexport function applyHintStep(\n board: SudokuCell[],\n step: SolverHintStep\n): { board: SudokuCell[]; pencilmarks: string } {\n const newBoard = cloneSudokuBoard(board);\n\n for (const hintCell of step.cells || []) {\n const index = hintCell.row * 9 + hintCell.column;\n const cell = newBoard[index];\n if (!cell || cell.given !== null) continue;\n\n const actions = hintCell.actions;\n if (!actions) continue;\n\n // Place digit\n if (actions.select && actions.select !== '') {\n const digit = parseInt(actions.select, 10);\n if (digit >= 1 && digit <= 9) {\n cell.input = digit;\n cell.pencilmarks = null;\n }\n }\n\n // Eliminate pencilmarks\n if (actions.remove && actions.remove !== '' && cell.pencilmarks) {\n const toRemove = new Set(\n actions.remove\n .split('')\n .map(d => parseInt(d, 10))\n .filter(n => n >= 1 && n <= 9)\n );\n cell.pencilmarks = cell.pencilmarks.filter(pm => !toRemove.has(pm));\n if (cell.pencilmarks.length === 0) {\n cell.pencilmarks = null;\n }\n }\n\n // Add pencilmarks\n if (actions.add && actions.add !== '') {\n const toAdd = actions.add\n .split('')\n .map(d => parseInt(d, 10))\n .filter(n => n >= 1 && n <= 9);\n if (toAdd.length > 0) {\n const existing = new Set(cell.pencilmarks || []);\n toAdd.forEach(d => existing.add(d));\n cell.pencilmarks = Array.from(existing).sort((a, b) => a - b);\n }\n }\n }\n\n const pencilmarksStr = pencilmarksToString(\n newBoard.map(cell => cell.pencilmarks)\n );\n\n return { board: newBoard, pencilmarks: pencilmarksStr };\n}\n\n// ── Hint data parsing ───────────────────────────────────────────────────────\n\n/** Parse a hint_data JSON string into SolverHints */\nexport function parseHintData(hintDataStr: string | null): SolverHints | null {\n if (!hintDataStr) return null;\n try {\n return JSON.parse(hintDataStr) as SolverHints;\n } catch {\n return null;\n }\n}\n\n// ── Walkthrough builder ─────────────────────────────────────────────────────\n\n/**\n * Resolve localised title and text for a single hint step.\n *\n * @param step - The solver hint step\n * @param tHints - Translation function scoped to the `hints` namespace\n * @param tCommon - Translation function scoped to the default namespace\n * @param techniquePath - Optional technique path slug for title fallback\n */\nexport function localizeHintStep(\n step: SolverHintStep,\n tHints: TranslateFunction,\n tCommon: TranslateFunction,\n techniquePath?: string\n): { title: string; text: string } {\n let title = getLocalizedHintTitle(tCommon, step);\n if (title === step.title && techniquePath) {\n const translated = tCommon(`techniques.${techniquePath}.title`);\n if (translated !== `techniques.${techniquePath}.title`) {\n title = translated;\n }\n }\n return {\n title,\n text: getLocalizedHintText(tHints, step),\n };\n}\n\n/**\n * Build the full walkthrough step array from an initial board and hint data.\n *\n * - Step 0: Original board with \"Look for {technique}\" text\n * - Steps 1-N: Each hint step with overlay; board progresses after each step\n * - Final step: Result board after all steps applied, no overlay\n *\n * @param initialBoard - Parsed SudokuCell[] from practice data\n * @param hintData - Parsed SolverHints (or null)\n * @param lookForText - Already-translated \"Look for …\" string\n * @param resultText - Already-translated result text\n * @param tHints - Translation function scoped to the `hints` namespace\n * @param tCommon - Translation function scoped to the default namespace\n * @param techniquePath - Optional technique path slug for title fallback\n */\nexport function buildWalkthroughSteps(\n initialBoard: SudokuCell[],\n hintData: SolverHints | null,\n lookForText: string,\n resultText: string,\n tHints: TranslateFunction,\n tCommon: TranslateFunction,\n techniquePath?: string\n): WalkthroughStep[] {\n const steps: WalkthroughStep[] = [];\n\n if (!hintData?.steps?.length) {\n steps.push({\n board: initialBoard,\n hint: null,\n title: '',\n text: lookForText,\n });\n return steps;\n }\n\n // Step 0: Original board\n steps.push({ board: initialBoard, hint: null, title: '', text: lookForText });\n\n // Steps 1-N: Each hint step with overlay, then apply changes\n let currentBoard = cloneSudokuBoard(initialBoard);\n for (const hintStep of hintData.steps) {\n const localized = localizeHintStep(\n hintStep,\n tHints,\n tCommon,\n techniquePath\n );\n steps.push({\n board: cloneSudokuBoard(currentBoard),\n hint: hintStep,\n title: localized.title,\n text: localized.text,\n });\n const result = applyHintStep(currentBoard, hintStep);\n currentBoard = result.board;\n }\n\n // Final step: Result after all steps applied\n steps.push({ board: currentBoard, hint: null, title: '', text: resultText });\n\n return steps;\n}\n"]}
|