@fgv/ts-sudoku-lib 5.1.0-3 → 5.1.0-30
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.
- package/dist/index.browser.js.map +1 -0
- package/dist/index.js.map +1 -0
- package/dist/packlets/collections/collections.js +1 -1
- package/dist/packlets/collections/collections.js.map +1 -0
- package/dist/packlets/collections/index.js.map +1 -0
- package/dist/packlets/common/cage.js.map +1 -0
- package/dist/packlets/common/cell.js.map +1 -0
- package/dist/packlets/common/common.js.map +1 -0
- package/dist/packlets/common/converters.js.map +1 -0
- package/dist/packlets/common/ids.js.map +1 -0
- package/dist/packlets/common/index.js.map +1 -0
- package/dist/packlets/common/logging.js.map +1 -0
- package/dist/packlets/common/public.js.map +1 -0
- package/dist/packlets/common/puzzle.js +1 -1
- package/dist/packlets/common/puzzle.js.map +1 -0
- package/dist/packlets/common/puzzleDefinitions.js.map +1 -0
- package/dist/packlets/common/puzzleSession.js.map +1 -0
- package/dist/packlets/common/puzzleState.js.map +1 -0
- package/dist/packlets/files/converters.js.map +1 -0
- package/dist/packlets/files/fileTreeHelpers.js.map +1 -0
- package/dist/packlets/files/filesystem.js.map +1 -0
- package/dist/packlets/files/index.browser.js.map +1 -0
- package/dist/packlets/files/index.js.map +1 -0
- package/dist/packlets/files/model.js.map +1 -0
- package/dist/packlets/hints/baseHintProvider.js.map +1 -0
- package/dist/packlets/hints/explanations.js.map +1 -0
- package/dist/packlets/hints/hiddenSingles.js.map +1 -0
- package/dist/packlets/hints/hintRegistry.js.map +1 -0
- package/dist/packlets/hints/hints.js.map +1 -0
- package/dist/packlets/hints/index.js.map +1 -0
- package/dist/packlets/hints/interfaces.js.map +1 -0
- package/dist/packlets/hints/nakedSingles.js.map +1 -0
- package/dist/packlets/hints/puzzleSessionHints.js.map +1 -0
- package/dist/packlets/hints/types.js.map +1 -0
- package/dist/packlets/puzzles/anyPuzzle.js.map +1 -0
- package/dist/packlets/puzzles/index.js.map +1 -0
- package/dist/packlets/puzzles/internal/combinationCache.js.map +1 -0
- package/dist/packlets/puzzles/internal/combinationGenerator.js.map +1 -0
- package/dist/packlets/puzzles/internal/possibilityAnalyzer.js.map +1 -0
- package/dist/packlets/puzzles/killerCombinations.js.map +1 -0
- package/dist/packlets/puzzles/killerCombinationsTypes.js.map +1 -0
- package/dist/packlets/puzzles/killerSudokuPuzzle.js.map +1 -0
- package/dist/packlets/puzzles/sudokuPuzzle.js.map +1 -0
- package/dist/packlets/puzzles/sudokuXPuzzle.js.map +1 -0
- package/dist/ts-sudoku-lib.d.ts +8 -8
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/index.browser.d.ts.map +1 -0
- package/lib/index.browser.js.map +1 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js.map +1 -0
- package/lib/packlets/collections/collections.d.ts +1 -1
- package/lib/packlets/collections/collections.d.ts.map +1 -0
- package/lib/packlets/collections/collections.js +1 -1
- package/lib/packlets/collections/collections.js.map +1 -0
- package/lib/packlets/collections/index.d.ts.map +1 -0
- package/lib/packlets/collections/index.js.map +1 -0
- package/lib/packlets/common/cage.d.ts.map +1 -0
- package/lib/packlets/common/cage.js.map +1 -0
- package/lib/packlets/common/cell.d.ts.map +1 -0
- package/lib/packlets/common/cell.js.map +1 -0
- package/lib/packlets/common/common.d.ts +5 -5
- package/lib/packlets/common/common.d.ts.map +1 -0
- package/lib/packlets/common/common.js.map +1 -0
- package/lib/packlets/common/converters.d.ts.map +1 -0
- package/lib/packlets/common/converters.js.map +1 -0
- package/lib/packlets/common/ids.d.ts.map +1 -0
- package/lib/packlets/common/ids.js.map +1 -0
- package/lib/packlets/common/index.d.ts.map +1 -0
- package/lib/packlets/common/index.js.map +1 -0
- package/lib/packlets/common/logging.d.ts.map +1 -0
- package/lib/packlets/common/logging.js.map +1 -0
- package/lib/packlets/common/public.d.ts +1 -1
- package/lib/packlets/common/public.d.ts.map +1 -0
- package/lib/packlets/common/public.js.map +1 -0
- package/lib/packlets/common/puzzle.d.ts +1 -1
- package/lib/packlets/common/puzzle.d.ts.map +1 -0
- package/lib/packlets/common/puzzle.js +1 -1
- package/lib/packlets/common/puzzle.js.map +1 -0
- package/lib/packlets/common/puzzleDefinitions.d.ts.map +1 -0
- package/lib/packlets/common/puzzleDefinitions.js.map +1 -0
- package/lib/packlets/common/puzzleSession.d.ts.map +1 -0
- package/lib/packlets/common/puzzleSession.js.map +1 -0
- package/lib/packlets/common/puzzleState.d.ts.map +1 -0
- package/lib/packlets/common/puzzleState.js.map +1 -0
- package/lib/packlets/files/converters.d.ts.map +1 -0
- package/lib/packlets/files/converters.js.map +1 -0
- package/lib/packlets/files/fileTreeHelpers.d.ts.map +1 -0
- package/lib/packlets/files/fileTreeHelpers.js.map +1 -0
- package/lib/packlets/files/filesystem.d.ts.map +1 -0
- package/lib/packlets/files/filesystem.js.map +1 -0
- package/lib/packlets/files/index.browser.d.ts.map +1 -0
- package/lib/packlets/files/index.browser.js.map +1 -0
- package/lib/packlets/files/index.d.ts.map +1 -0
- package/lib/packlets/files/index.js.map +1 -0
- package/lib/packlets/files/model.d.ts.map +1 -0
- package/lib/packlets/files/model.js.map +1 -0
- package/lib/packlets/hints/baseHintProvider.d.ts.map +1 -0
- package/lib/packlets/hints/baseHintProvider.js.map +1 -0
- package/lib/packlets/hints/explanations.d.ts.map +1 -0
- package/lib/packlets/hints/explanations.js.map +1 -0
- package/lib/packlets/hints/hiddenSingles.d.ts.map +1 -0
- package/lib/packlets/hints/hiddenSingles.js.map +1 -0
- package/lib/packlets/hints/hintRegistry.d.ts.map +1 -0
- package/lib/packlets/hints/hintRegistry.js.map +1 -0
- package/lib/packlets/hints/hints.d.ts.map +1 -0
- package/lib/packlets/hints/hints.js.map +1 -0
- package/lib/packlets/hints/index.d.ts.map +1 -0
- package/lib/packlets/hints/index.js.map +1 -0
- package/lib/packlets/hints/interfaces.d.ts.map +1 -0
- package/lib/packlets/hints/interfaces.js.map +1 -0
- package/lib/packlets/hints/nakedSingles.d.ts.map +1 -0
- package/lib/packlets/hints/nakedSingles.js.map +1 -0
- package/lib/packlets/hints/puzzleSessionHints.d.ts.map +1 -0
- package/lib/packlets/hints/puzzleSessionHints.js.map +1 -0
- package/lib/packlets/hints/types.d.ts.map +1 -0
- package/lib/packlets/hints/types.js.map +1 -0
- package/lib/packlets/puzzles/anyPuzzle.d.ts.map +1 -0
- package/lib/packlets/puzzles/anyPuzzle.js.map +1 -0
- package/lib/packlets/puzzles/index.d.ts.map +1 -0
- package/lib/packlets/puzzles/index.js.map +1 -0
- package/lib/packlets/puzzles/internal/combinationCache.d.ts.map +1 -0
- package/lib/packlets/puzzles/internal/combinationCache.js.map +1 -0
- package/lib/packlets/puzzles/internal/combinationGenerator.d.ts.map +1 -0
- package/lib/packlets/puzzles/internal/combinationGenerator.js.map +1 -0
- package/lib/packlets/puzzles/internal/possibilityAnalyzer.d.ts.map +1 -0
- package/lib/packlets/puzzles/internal/possibilityAnalyzer.js.map +1 -0
- package/lib/packlets/puzzles/killerCombinations.d.ts.map +1 -0
- package/lib/packlets/puzzles/killerCombinations.js.map +1 -0
- package/lib/packlets/puzzles/killerCombinationsTypes.d.ts.map +1 -0
- package/lib/packlets/puzzles/killerCombinationsTypes.js.map +1 -0
- package/lib/packlets/puzzles/killerSudokuPuzzle.d.ts.map +1 -0
- package/lib/packlets/puzzles/killerSudokuPuzzle.js.map +1 -0
- package/lib/packlets/puzzles/sudokuPuzzle.d.ts.map +1 -0
- package/lib/packlets/puzzles/sudokuPuzzle.js.map +1 -0
- package/lib/packlets/puzzles/sudokuXPuzzle.d.ts.map +1 -0
- package/lib/packlets/puzzles/sudokuXPuzzle.js.map +1 -0
- package/package.json +10 -8
- package/debug_test.js +0 -88
- package/dist/test/unit/helpers/puzzleBuilders.js +0 -149
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cage.js","sourceRoot":"","sources":["../../../src/packlets/common/cage.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;;AAEH,4CAAsD;AAKtD;;GAEG;AACH,MAAa,IAAI;IAQf,YAAoB,EAAU,EAAE,IAAc,EAAE,KAAa,EAAE,KAAe;QAC5E,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;IAC3B,CAAC;IAED,IAAW,OAAO;QAChB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED,IAAW,QAAQ;QACjB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;IAC9B,CAAC;IAEM,MAAM,CAAC,MAAM,CAAC,EAAU,EAAE,IAAc,EAAE,KAAa,EAAE,KAAe;QAC7E,OAAO,IAAA,wBAAa,EAAC,GAAG,EAAE,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IAC/D,CAAC;IAEM,YAAY,CAAC,EAAU;QAC5B,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACpC,CAAC;IAEM,aAAa,CAAC,KAAa,EAAE,KAAkB,EAAE,MAAiB;;QACvE,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnC,IAAI,CAAC,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,CAAC,MAAM,CAAC,CAAA,EAAE,CAAC;gBAC9B,8DAA8D;gBAC9D,IAAI,CAAA,MAAA,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,0CAAE,KAAK,MAAK,KAAK,EAAE,CAAC;oBAC/D,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAEM,eAAe,CAAC,KAAkB;;QACvC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;QACjC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnC,8DAA8D;YAC9D,MAAM,KAAK,GAAG,MAAA,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,0CAAE,KAAK,CAAC;YAC/D,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACpB,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAEM,QAAQ,CAAC,KAAmB;QACjC,OAAO,IAAI,CAAC,QAAQ;aACjB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;;YACV,8DAA8D;YAC9D,MAAM,KAAK,GAAG,MAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,eAAe,CAAC,EAAE,EAAE,SAAS,EAAE,0CAAE,KAAK,CAAC;YAC5D,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACrC,CAAC,CAAC;aACD,IAAI,CAAC,EAAE,CAAC,CAAC;IACd,CAAC;CACF;AAjED,oBAiEC","sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2023 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Result, captureResult } from '@fgv/ts-utils';\nimport { CageId, CageType, CellId } from './common';\nimport { ICage } from './public';\nimport { PuzzleState } from './puzzleState';\n\n/**\n * @internal\n */\nexport class Cage implements ICage {\n public readonly id: CageId;\n public readonly cageType: CageType;\n public readonly total: number;\n\n protected readonly _cellIds: CellId[];\n private _values: Set<number>;\n\n private constructor(id: CageId, type: CageType, total: number, cells: CellId[]) {\n this.id = id;\n this.cageType = type;\n this.total = total;\n this._cellIds = Array.from(cells);\n this._values = new Set();\n }\n\n public get cellIds(): CellId[] {\n return Array.from(this._cellIds);\n }\n\n public get numCells(): number {\n return this._cellIds.length;\n }\n\n public static create(id: CageId, type: CageType, total: number, cells: CellId[]): Result<Cage> {\n return captureResult(() => new Cage(id, type, total, cells));\n }\n\n public containsCell(id: CellId): boolean {\n return this._cellIds.includes(id);\n }\n\n public containsValue(value: number, state: PuzzleState, ignore?: CellId[]): boolean {\n for (const cellId of this._cellIds) {\n if (!ignore?.includes(cellId)) {\n /* c8 ignore next - defense in depth, ? should never happen */\n if (state.getCellContents(cellId).orDefault()?.value === value) {\n return true;\n }\n }\n }\n return false;\n }\n\n public containedValues(state: PuzzleState): Set<number> {\n const values = new Set<number>();\n for (const cellId of this._cellIds) {\n /* c8 ignore next - defense in depth, ? should never happen */\n const value = state.getCellContents(cellId).orDefault()?.value;\n if (value !== undefined) {\n values.add(value);\n }\n }\n return values;\n }\n\n public toString(state?: PuzzleState): string {\n return this._cellIds\n .map((id) => {\n /* c8 ignore next - defense in depth, ? should never happen */\n const value = state?.getCellContents(id).orDefault()?.value;\n return value ? String(value) : '.';\n })\n .join('');\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cell.d.ts","sourceRoot":"","sources":["../../../src/packlets/common/cell.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,MAAM,EAAiB,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,MAAM,EAAiB,UAAU,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;GAEG;AACH,qBAAa,IAAK,YAAW,SAAS,EAAE,KAAK;IAC3C,SAAgB,EAAE,EAAE,MAAM,CAAC;IAC3B,SAAgB,GAAG,EAAE,MAAM,CAAC;IAC5B,SAAgB,GAAG,EAAE,MAAM,CAAC;IAC5B,SAAgB,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;IAEvC,SAAgB,SAAS,EAAE,OAAO,CAAC;IACnC,SAAgB,cAAc,CAAC,EAAE,MAAM,CAAC;gBAErB,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,IAAI,EAAE;IASnD,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO;IAQpC,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO;IASrC,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO;IASpE,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC;IAWtE,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;IAM9E,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;IAMpE,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,GAAG,MAAM;CAK7C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cell.js","sourceRoot":"","sources":["../../../src/packlets/common/cell.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2023 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Result, fail, succeed } from '@fgv/ts-utils';\nimport { Cage } from './cage';\nimport { CellId, ICellContents, ICellState } from './common';\nimport { ICell } from './public';\nimport { PuzzleState } from './puzzleState';\n\n/**\n * @internal\n */\nexport interface ICellInit {\n readonly id: CellId;\n readonly row: number;\n readonly col: number;\n readonly immutableValue?: number;\n}\n\n/**\n * @internal\n */\nexport class Cell implements ICellInit, ICell {\n public readonly id: CellId;\n public readonly row: number;\n public readonly col: number;\n public readonly cages: readonly Cage[];\n\n public readonly immutable: boolean;\n public readonly immutableValue?: number;\n\n public constructor(init: ICellInit, cages: readonly Cage[]) {\n this.id = init.id;\n this.row = init.row;\n this.col = init.col;\n this.cages = [...cages];\n this.immutableValue = init.immutableValue;\n this.immutable = init.immutableValue !== undefined;\n }\n\n public isValid(state: PuzzleState): boolean {\n if (this.immutable) {\n return true;\n }\n const cell = state.getCellContents(this.id).orDefault();\n return cell !== undefined && this.isValidValue(cell.value, state);\n }\n\n public hasValue(state: PuzzleState): boolean {\n if (this.immutable) {\n return true;\n }\n const cell = state.getCellContents(this.id).orDefault();\n /* c8 ignore next - defense in depth ? should never happen */\n return cell?.value !== undefined;\n }\n\n public isValidValue(value: number | undefined, state: PuzzleState): boolean {\n if (this.immutable) {\n return false;\n } else if (value === undefined) {\n return true;\n }\n return !this.cages.find((cage) => cage.containsValue(value, state, [this.id]));\n }\n\n public update(value: number | undefined, notes: number[]): Result<ICellState> {\n if (this.immutable) {\n return fail(`cannot set value \"${value}\" in immutable cell ${this.id}`);\n }\n return succeed({\n id: this.id,\n value,\n notes\n });\n }\n\n public updateValue(value: number | undefined, state: PuzzleState): Result<ICellState> {\n return state.getCellContents(this.id).onSuccess((contents: ICellContents) => {\n return this.update(value, contents.notes);\n });\n }\n\n public updateNotes(notes: number[], state: PuzzleState): Result<ICellState> {\n return state.getCellContents(this.id).onSuccess((contents: ICellContents) => {\n return this.update(contents.value, notes);\n });\n }\n\n public toString(state?: PuzzleState): string {\n const contents = state?.getCellContents(this.id).orDefault();\n const value = this.immutableValue ?? contents?.value;\n return value && value >= 1 && value <= 9 ? String(value) : '.';\n }\n}\n"]}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { Brand } from '@fgv/ts-utils';
|
|
2
2
|
/**
|
|
3
|
-
* Nominal identifier for a single {@
|
|
3
|
+
* Nominal identifier for a single {@link ICell | cell} in a {@link PuzzleSession | puzzle}.
|
|
4
4
|
* @public
|
|
5
5
|
*/
|
|
6
6
|
export type CellId = Brand<string, 'CellId'>;
|
|
7
7
|
/**
|
|
8
|
-
* Nominal identifier for a single {@
|
|
8
|
+
* Nominal identifier for a single {@link ICage | cage} in a {@link PuzzleSession | puzzle}.
|
|
9
9
|
* @public
|
|
10
10
|
*/
|
|
11
11
|
export type CageId = Brand<string, 'CageId'>;
|
|
12
12
|
/**
|
|
13
|
-
* Identifies the type of a {@
|
|
13
|
+
* Identifies the type of a {@link ICage | cage}.
|
|
14
14
|
* @public
|
|
15
15
|
*/
|
|
16
16
|
export type CageType = 'row' | 'column' | 'section' | 'x' | 'killer';
|
|
17
17
|
/**
|
|
18
|
-
* The row/column coordinate of a single {@
|
|
18
|
+
* The row/column coordinate of a single {@link ICell | cell} in a {@link PuzzleSession | puzzle}.
|
|
19
19
|
* @public
|
|
20
20
|
*/
|
|
21
21
|
export interface IRowColumn {
|
|
@@ -23,7 +23,7 @@ export interface IRowColumn {
|
|
|
23
23
|
col: number;
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
|
-
* The contents of a single {@
|
|
26
|
+
* The contents of a single {@link ICell | cell} in a {@link PuzzleSession | puzzle}.
|
|
27
27
|
* @public
|
|
28
28
|
*/
|
|
29
29
|
export interface ICellContents {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/packlets/common/common.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEtC;;;GAGG;AACH,MAAM,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAE7C;;;GAGG;AACH,MAAM,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAE7C;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,GAAG,GAAG,QAAQ,CAAC;AAErE;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;;;GAIG;AAEH,MAAM,WAAW,UAAW,SAAQ,aAAa;IAC/C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,eAAe,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,UAAU,EAA4C,CAAC;AAEpF;;;;GAIG;AACH;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAenG;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAWnE,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAEnE;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,aAAa,GAAG,WAAW,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/packlets/common/common.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;;AAgFH,gDAeC;AAjCD;;;GAGG;AACU,QAAA,cAAc,GAAiB,CAAC,eAAe,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;AAEpF;;;;GAIG;AACH;;;;;;GAMG;AACH,SAAgB,kBAAkB,CAAC,QAAgB,EAAE,QAAgB;IACnE,kFAAkF;IAClF,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;QAClB,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;IAC5B,CAAC;IAED,0DAA0D;IAC1D,MAAM,GAAG,GAAG,CAAC,QAAQ,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAE5C,sEAAsE;IACtE,sCAAsC;IACtC,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACvD,MAAM,GAAG,GAAG,iBAAiB,GAAG,QAAQ,GAAG,CAAC,iBAAiB,GAAG,CAAC,iBAAiB,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAE7F,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AACtB,CAAC;AAED;;;GAGG;AACU,QAAA,gBAAgB,GAA4C;IACvE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;IAClB,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;IAClB,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;IACnB,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;IACnB,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;IACpB,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;IACpB,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;IACpB,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;IACpB,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;IACpB,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;CACrB,CAAC","sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2023 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Brand } from '@fgv/ts-utils';\n\n/**\n * Nominal identifier for a single {@link ICell | cell} in a {@link PuzzleSession | puzzle}.\n * @public\n */\nexport type CellId = Brand<string, 'CellId'>;\n\n/**\n * Nominal identifier for a single {@link ICage | cage} in a {@link PuzzleSession | puzzle}.\n * @public\n */\nexport type CageId = Brand<string, 'CageId'>;\n\n/**\n * Identifies the type of a {@link ICage | cage}.\n * @public\n */\nexport type CageType = 'row' | 'column' | 'section' | 'x' | 'killer';\n\n/**\n * The row/column coordinate of a single {@link ICell | cell} in a {@link PuzzleSession | puzzle}.\n * @public\n */\nexport interface IRowColumn {\n row: number;\n col: number;\n}\n\n/**\n * The contents of a single {@link ICell | cell} in a {@link PuzzleSession | puzzle}.\n * @public\n */\nexport interface ICellContents {\n /**\n * The value of the {@link ICell | cell}, or `undefined` if no value has been assigned.\n */\n readonly value?: number;\n /**\n * Any notes associated with the {@link ICell | cell}.\n */\n readonly notes: number[];\n}\n\n/**\n * Describes the state of or a state update for a single {@link ICell |cell} in a\n * {@link PuzzleSession | puzzle}.\n * @public\n */\n\nexport interface ICellState extends ICellContents {\n readonly id: CellId;\n}\n\n/**\n * Describes the rules that apply to the puzzle.\n * @public\n */\nexport type PuzzleType = 'killer-sudoku' | 'sudoku' | 'sudoku-x';\n\n/**\n * All supported public types.\n * @public\n */\nexport const allPuzzleTypes: PuzzleType[] = ['killer-sudoku', 'sudoku', 'sudoku-x'];\n\n/**\n * The minimum and maximum possible values for a {@link ICage | cage}, by cage size in\n * {@link ICell | cells}.\n * @public\n */\n/**\n * Calculate the minimum and maximum possible totals for a cage of given size\n * @param cageSize - Number of cells in the cage\n * @param maxValue - Maximum value allowed in a cell (e.g., 9 for 9x9, 16 for 16x16)\n * @returns Object with min and max possible totals\n * @public\n */\nexport function getCageTotalBounds(cageSize: number, maxValue: number): { min: number; max: number } {\n /* c8 ignore next 3 - functional code tested but coverage intermittently missed */\n if (cageSize <= 0) {\n return { min: 0, max: 0 };\n }\n\n // Minimum is sum of first cageSize numbers (1, 2, 3, ...)\n const min = (cageSize * (cageSize + 1)) / 2;\n\n // Maximum is sum of last cageSize numbers (maxValue, maxValue-1, ...)\n // But cageSize cannot exceed maxValue\n const effectiveCageSize = Math.min(cageSize, maxValue);\n const max = effectiveCageSize * maxValue - (effectiveCageSize * (effectiveCageSize - 1)) / 2;\n\n return { min, max };\n}\n\n/**\n * Legacy array for backward compatibility - supports standard 9x9 Sudoku\n * @public\n */\nexport const totalsByCageSize: readonly { min: number; max: number }[] = [\n { min: 0, max: 0 },\n { min: 1, max: 9 },\n { min: 3, max: 17 },\n { min: 6, max: 24 },\n { min: 10, max: 30 },\n { min: 15, max: 35 },\n { min: 21, max: 39 },\n { min: 28, max: 42 },\n { min: 36, max: 44 },\n { min: 45, max: 45 }\n];\n\n/**\n * Navigation direction within a puzzle.\n * @public\n *\n */\nexport type NavigationDirection = 'down' | 'left' | 'right' | 'up';\n\n/**\n * Wrapping rules when navigating within a puzzle.\n * @public\n */\nexport type NavigationWrap = 'none' | 'wrap-around' | 'wrap-next';\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"converters.d.ts","sourceRoot":"","sources":["../../../src/packlets/common/converters.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,SAAS,EAAqC,MAAM,eAAe,CAAC;AAC7E,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAkB,MAAM,UAAU,CAAC;AAgCtE;;;GAGG;AACH,eAAO,MAAM,MAAM,EAAE,SAAS,CAAC,MAAM,CAAyC,CAAC;AAE/E;;;GAGG;AACH,eAAO,MAAM,MAAM,EAAE,SAAS,CAAC,MAAM,CAAyC,CAAC;AAE/E;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,SAAS,CAChC,UAAU,EACV,aAAa,CAAC,UAAU,CAAC,CAC+B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"converters.js","sourceRoot":"","sources":["../../../src/packlets/common/converters.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;;AAEH,4CAA6E;AAC7E,qCAAsE;AAEtE,mCAAmC;AACnC,iDAAiD;AACjD,gDAAgD;AAChD,kEAAkE;AAClE,wBAAwB;AACxB,0CAA0C;AAC1C,MAAM,YAAY,GAChB,iFAAiF,CAAC;AAEpF,SAAS,cAAc,CAAC,IAAY;IAClC,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,OAAO,IAAA,kBAAO,EAAC,IAAc,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,IAAA,eAAI,EAAC,sBAAsB,IAAI,GAAG,CAAC,CAAC;AAC7C,CAAC;AAED,mCAAmC;AACnC,2CAA2C;AAC3C,qCAAqC;AACrC,MAAM,YAAY,GAAW,wBAAwB,CAAC;AAEtD,SAAS,cAAc,CAAC,IAAY;IAClC,qBAAqB;IACrB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAA,eAAI,EAAC,sBAAsB,IAAI,sDAAsD,CAAC,CAAC;IAChG,CAAC;IAED,OAAO,IAAA,kBAAO,EAAC,IAAc,CAAC,CAAC;AACjC,CAAC;AAED;;;GAGG;AACU,QAAA,MAAM,GAAsB,qBAAU,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AAE/E;;;GAGG;AACU,QAAA,MAAM,GAAsB,qBAAU,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AAE/E;;;GAGG;AACU,QAAA,UAAU,GAGnB,qBAAU,CAAC,eAAe,CAAa,uBAAc,CAAC,CAAC","sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2023 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Converter, Converters, Result, fail, succeed } from '@fgv/ts-utils';\nimport { CageId, CellId, PuzzleType, allPuzzleTypes } from './common';\n\n// Updated to support larger grids:\n// - Row IDs: R followed by A-Z or AA-ZZ for rows\n// - Column IDs: C followed by 1-99+ for columns\n// - Section IDs: S followed by row letter(s) and column number(s)\n// - X diagonals: X1, X2\n// - Killer cages: K followed by letter(s)\nconst cageIdRegExp: RegExp =\n /^(R[A-Z]{1,2}$)|(C[0-9]{1,3}$)|(S[A-Z]{1,2}[0-9]{1,3}$)|(X[1-2]$)|(K[A-Za-z]+$)/;\n\nfunction validateCageId(from: string): Result<CageId> {\n if (cageIdRegExp.test(from)) {\n return succeed(from as CageId);\n }\n return fail(`malformed cage ID \"${from}\"`);\n}\n\n// Updated to support larger grids:\n// - Rows: A-Z for 0-25, then AA-ZZ for 26+\n// - Columns: 1-999 for any size grid\nconst cellIdRegExp: RegExp = /^[A-Z]{1,2}[0-9]{1,3}$/;\n\nfunction validateCellId(from: string): Result<CellId> {\n // Check basic format\n if (!cellIdRegExp.test(from)) {\n return fail(`malformed cell ID \"${from}\" (expected row letter(s) followed by column number)`);\n }\n\n return succeed(from as CellId);\n}\n\n/**\n * Converts an arbitrary value to a {@link CageId | CageId}.\n * @public\n */\nexport const cageId: Converter<CageId> = Converters.string.map(validateCageId);\n\n/**\n * Converts an arbitrary value to a {@link CellId | CellId}.\n * @public\n */\nexport const cellId: Converter<CellId> = Converters.string.map(validateCellId);\n\n/**\n * Converts an arbitrary value to a {@link PuzzleType | PuzzleType}.\n * @public\n */\nexport const puzzleType: Converter<\n PuzzleType,\n ReadonlyArray<PuzzleType>\n> = Converters.enumeratedValue<PuzzleType>(allPuzzleTypes);\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../../../src/packlets/common/ids.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,MAAM,EAAiB,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AA0CxC;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAyBlE;AAMD;;GAEG;AACH,qBAAa,GAAG;WACA,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;WAQ5C,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;WAezD,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;WAI9B,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;WAMjC,aAAa,CACzB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,UAAU,GAAE,MAAU,EACtB,SAAS,GAAE,MAAU,GACpB,MAAM;WASK,OAAO,CACnB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,MAAM,CAAC,MAAM,EAAE,CAAC;CAiBpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids.js","sourceRoot":"","sources":["../../../src/packlets/common/ids.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2023 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Result, fail, succeed } from '@fgv/ts-utils';\nimport { CageId, CellId, IRowColumn } from './common';\nimport * as Converters from './converters';\nimport { ICage, ICell } from './public';\n\nconst firstRowIdChar: number = 'A'.charCodeAt(0);\n\n/**\n * Convert a column index (0-based) to column letters (A-Z, AA-AZ, BA-BZ, etc.)\n * @param col - 0-based column index\n * @returns Column identifier string\n */\nfunction columnToLetters(col: number): string {\n if (col < 26) {\n // Single letter: A-Z\n return String.fromCharCode(firstRowIdChar + col);\n /* c8 ignore next 8 - functional code tested but coverage intermittently missed */\n } else {\n // Double letters: AA, AB, ..., ZZ\n const firstLetter = Math.floor(col / 26) - 1;\n const secondLetter = col % 26;\n return (\n String.fromCharCode(firstRowIdChar + firstLetter) + String.fromCharCode(firstRowIdChar + secondLetter)\n );\n }\n}\n\n/**\n * Convert a row index (0-based) to row number string (1-based with zero-padding)\n * @param row - 0-based row index\n * @param maxRow - Maximum row index (optional, for determining padding width)\n * @returns Row number string with zero-padding\n */\nfunction rowToNumber(row: number, maxRow?: number): string {\n const rowNum = row + 1;\n /* c8 ignore next 5 - functional code tested but coverage intermittently missed */\n if (maxRow !== undefined) {\n const maxRowNum = maxRow + 1;\n const width = maxRowNum.toString().length;\n return rowNum.toString().padStart(width, '0');\n }\n // Default: pad to 2 digits for grids up to 99x99\n return rowNum.toString().padStart(2, '0');\n}\n\n/**\n * Parse a cell ID string back to row/column coordinates\n * @param cellId - Cell ID string (e.g., \"A1\", \"A01\", \"AB15\")\n * @returns Row and column indices (0-based) or undefined if invalid\n * @public\n */\nexport function parseCellId(cellId: string): IRowColumn | undefined {\n const match = cellId.match(/^([A-Z]{1,2})([0-9]{1,3})$/);\n /* c8 ignore next 3 - functional code tested but coverage intermittently missed */\n if (!match) {\n return undefined;\n }\n\n const rowLetters = match[1];\n const colNumber = parseInt(match[2], 10);\n\n let row: number;\n if (rowLetters.length === 1) {\n // Single letter: A-Z maps to rows 0-25\n row = rowLetters.charCodeAt(0) - firstRowIdChar;\n /* c8 ignore next 6 - functional code tested but coverage intermittently missed */\n } else {\n // Double letters: AA-ZZ for rows 26+\n const firstLetter = rowLetters.charCodeAt(0) - firstRowIdChar;\n const secondLetter = rowLetters.charCodeAt(1) - firstRowIdChar;\n row = (firstLetter + 1) * 26 + secondLetter;\n }\n\n const col = colNumber - 1; // Convert from 1-based to 0-based\n\n return { row, col };\n}\n\nfunction isRowColumn(from: unknown): from is IRowColumn {\n return typeof from === 'object' && from !== null && 'row' in from && `col` in from;\n}\n\n/**\n * @public\n */\nexport class Ids {\n public static cageId(from: string | ICage): Result<CageId> {\n if (typeof from === 'string') {\n return Converters.cageId.convert(from);\n }\n /* c8 ignore next 2 - functional code tested but coverage intermittently missed */\n return succeed(from.id);\n }\n\n public static cellId(spec: string | IRowColumn | ICell): Result<CellId> {\n if (isRowColumn(spec)) {\n if ('id' in spec) {\n return succeed(spec.id);\n }\n // Standard sudoku convention: Letters for rows (A-I), numbers for columns (1-9)\n const rowLetter = columnToLetters(spec.row);\n // For 9x9 grids, use single digit format for backward compatibility\n // For larger grids, use zero-padding\n const colNumber = spec.col < 9 ? (spec.col + 1).toString() : rowToNumber(spec.col);\n return succeed(`${rowLetter}${colNumber}` as CellId);\n }\n return Converters.cellId.convert(spec);\n }\n\n public static rowCageId(row: number): CageId {\n return `R${columnToLetters(row)}` as CageId;\n }\n\n public static columnCageId(col: number): CageId {\n // For backward compatibility, use single digit for columns < 9\n const colNumber = col < 9 ? (col + 1).toString() : rowToNumber(col);\n return `C${colNumber}` as CageId;\n }\n\n public static sectionCageId(\n row: number,\n col: number,\n cageHeight: number = 3,\n cageWidth: number = 3\n ): CageId {\n row = Math.floor(row / cageHeight) * cageHeight;\n col = Math.floor(col / cageWidth) * cageWidth;\n // Section IDs use row letter and column number\n const rowLetter = columnToLetters(row);\n const colNumber = col < 9 ? (col + 1).toString() : rowToNumber(col);\n return `S${rowLetter}${colNumber}` as CageId;\n }\n\n public static cellIds(\n firstRow: number,\n numRows: number,\n firstCol: number,\n numCols: number\n ): Result<CellId[]> {\n const cellIds: CellId[] = [];\n for (let row = firstRow; row < firstRow + numRows; row++) {\n for (let col = firstCol; col < firstCol + numCols; col++) {\n const result = this.cellId({ row, col }).onSuccess((id) => {\n cellIds.push(id);\n return succeed(id);\n });\n\n /* c8 ignore next 3 - defense in depth should not happen */\n if (result.isFailure()) {\n return fail(result.message);\n }\n }\n }\n return succeed(cellIds);\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/packlets/common/index.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAE3C,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAE9B,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/packlets/common/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,yDAA2C;AAalC,gCAAU;AAXnB,yCAAuB;AACvB,yCAAuB;AACvB,2CAAyB;AACzB,6BAAyC;AAAhC,0FAAA,GAAG,OAAA;AAAE,kGAAA,WAAW,OAAA;AACzB,qCAAgD;AAAvC,8GAAA,mBAAmB,OAAA;AAC5B,2CAAyB;AACzB,2CAAyB;AACzB,sDAAoC;AACpC,kDAAgC;AAChC,gDAA8B","sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2023 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport * as Converters from './converters';\n\nexport * from './cage';\nexport * from './cell';\nexport * from './common';\nexport { Ids, parseCellId } from './ids';\nexport { DefaultSudokuLogger } from './logging';\nexport * from './public';\nexport * from './puzzle';\nexport * from './puzzleDefinitions';\nexport * from './puzzleSession';\nexport * from './puzzleState';\n\nexport { Converters };\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../../src/packlets/common/logging.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,OAAO,CAAC,WAAW,CAAC,OAAO,CAE3D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logging.js","sourceRoot":"","sources":["../../../src/packlets/common/logging.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;;AAEH,4CAAwC;AAExC;;;GAGG;AACU,QAAA,mBAAmB,GAAiC,IAAI,kBAAO,CAAC,WAAW,CAAC;IACvF,MAAM,EAAE,IAAI,kBAAO,CAAC,UAAU,EAAE;CACjC,CAAC,CAAC","sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2023 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Logging } from '@fgv/ts-utils';\n\n/**\n * Default no-op logger for use when diagnostic logging is not needed.\n * @public\n */\nexport const DefaultSudokuLogger: Logging.LogReporter<unknown> = new Logging.LogReporter({\n logger: new Logging.NoOpLogger()\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/packlets/common/public.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEpD;;;;GAIG;AACH,MAAM,WAAW,KAAK;IACpB;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAE5B;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAE3B;;;OAGG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;CACnC;AAED;;;;GAIG;AACH,MAAM,WAAW,KAAK;IACpB;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,KAAK,EAAE,CAAC;IAEjC;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAE5B;;OAEG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/packlets/common/public.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG","sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2023 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { CageId, CageType, CellId } from './common';\n\n/**\n * Describes the structure of a single cage in a {@link PuzzleSession | puzzle}.\n * Does not describe state.\n * @public\n */\nexport interface ICage {\n /**\n * Unique identifier for the cage.\n */\n readonly id: CageId;\n\n /**\n * The {@link CageType | type} of the cage.\n */\n readonly cageType: CageType;\n\n /**\n * The expected sum of all cells in the cage.\n */\n readonly total: number;\n\n /**\n * The number of cells in the cage.\n */\n readonly numCells: number;\n\n /**\n * The identity of each cell in the cage.\n */\n readonly cellIds: CellId[];\n\n /**\n * Determines if a supplied cell is present in the cage.\n * @param id - the identifier to be searched.\n */\n containsCell(id: CellId): boolean;\n}\n\n/**\n * Describes the structure of a single cell in a {@link PuzzleSession | puzzle}.\n * Does not describe state.\n * @public\n */\nexport interface ICell {\n /**\n * Unique identifier for the cell.\n */\n readonly id: CellId;\n\n /**\n * Row number of the cell.\n */\n readonly row: number;\n\n /**\n * Column number of the cell.\n */\n readonly col: number;\n\n /**\n * All of the {@link ICage | cages} to which this cell belongs.\n */\n readonly cages: readonly ICage[];\n\n /**\n * Indicates whether this cell is a given value (immutable).\n */\n readonly immutable: boolean;\n\n /**\n * Given value of this cell, or `undefined` if the cell is not immutable.\n */\n readonly immutableValue?: number;\n}\n"]}
|
|
@@ -54,7 +54,7 @@ export declare class Puzzle {
|
|
|
54
54
|
protected readonly _cells: Map<CellId, Cell>;
|
|
55
55
|
/**
|
|
56
56
|
* Constructs a new puzzle state.
|
|
57
|
-
* @param puzzle - {@
|
|
57
|
+
* @param puzzle - {@link IPuzzleDefinition | Puzzle definition} from which this puzzle state
|
|
58
58
|
* is to be initialized.
|
|
59
59
|
*/
|
|
60
60
|
protected constructor(puzzle: IPuzzleDefinition, extraCages?: [CageId, Cage][]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"puzzle.d.ts","sourceRoot":"","sources":["../../../src/packlets/common/puzzle.ts"],"names":[],"mappings":"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"}
|
|
@@ -36,7 +36,7 @@ const puzzleState_1 = require("./puzzleState");
|
|
|
36
36
|
class Puzzle {
|
|
37
37
|
/**
|
|
38
38
|
* Constructs a new puzzle state.
|
|
39
|
-
* @param puzzle - {@
|
|
39
|
+
* @param puzzle - {@link IPuzzleDefinition | Puzzle definition} from which this puzzle state
|
|
40
40
|
* is to be initialized.
|
|
41
41
|
*/
|
|
42
42
|
constructor(puzzle, extraCages) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"puzzle.js","sourceRoot":"","sources":["../../../src/packlets/common/puzzle.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;;AAEH,4CAAkE;AAWlE,iCAA8B;AAC9B,iCAA8B;AAC9B,+BAA4B;AAG5B,+CAA4C;AAqB5C;;;GAGG;AACH,MAAa,MAAM;IAgCjB;;;;OAIG;IACH,YAAsB,MAAyB,EAAE,UAA6B;QAC5E,6CAA6C;QAC7C,UAAU,GAAG,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,EAAE,CAAC;QAE9B,wCAAwC;QACxC,mEAAmE;QACnE,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;YACnE,MAAM,IAAI,KAAK,CACb,WAAW,MAAM,CAAC,WAAW,cAAc,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,YAAY,iBAC/E,MAAM,CAAC,KAAK,CAAC,MACf,EAAE,CACH,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;QACpB,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACxB,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC;QAEzB,MAAM,IAAI,GAAG,MAAM,CAAC,eAAe,CACjC,MAAM,CAAC,SAAS,EAChB,MAAM,CAAC,YAAY,EACnB,MAAM,CAAC,cAAc,CACtB,CAAC,OAAO,EAAE,CAAC;QACZ,MAAM,OAAO,GAAG,MAAM,CAAC,kBAAkB,CACvC,MAAM,CAAC,SAAS,EAChB,MAAM,CAAC,YAAY,EACnB,MAAM,CAAC,cAAc,CACtB,CAAC,OAAO,EAAE,CAAC;QACZ,MAAM,QAAQ,GAAG,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC;QAC9D,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,OAAO,EAAE,GAAG,QAAQ,EAAE,GAAG,UAAU,CAAC,CAAC;QAChE,IAAI,CAAC,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,CAAC,SAAS,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnC,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;QAExB,MAAM,QAAQ,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;YAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;YAC3C,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;gBAClD,MAAM,EAAE,GAAG,SAAG,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC5D,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC;gBAE/E,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;gBAC9B,iGAAiG;gBACjG,MAAM,cAAc,GAAG,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,GAAG,CAAC,CAAC;gBAC5F,IACE,cAAc,KAAK,SAAS;oBAC5B,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,cAAc,GAAG,CAAC,IAAI,cAAc,GAAG,MAAM,CAAC,QAAQ,CAAC,EACxF,CAAC;oBACD,MAAM,IAAI,KAAK,CAAC,UAAU,MAAM,CAAC,WAAW,mBAAmB,IAAI,cAAc,EAAE,EAAE,CAAC,CAAC;gBACzF,CAAC;gBACD,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;gBAC5F,MAAM,IAAI,GAAG,IAAI,WAAI,CAAC,EAAE,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;gBAC/D,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;QAED,IAAI,CAAC,YAAY,GAAG,yBAAW,CAAC,MAAM,CACpC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,EAAc,EAAE;YAChE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,cAAc,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QACxD,CAAC,CAAC,CACH,CAAC,OAAO,EAAE,CAAC;IACd,CAAC;IAED,IAAW,OAAO;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;IAED,IAAW,UAAU;QACnB,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC5B,CAAC;IAED,IAAW,IAAI;QACb,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,IAAW,IAAI;QACb,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,IAAW,QAAQ;QACjB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,IAAW,KAAK;QACd,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,IAAW,KAAK;QACd,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACO,MAAM,CAAC,eAAe,CAC9B,OAAe,EACf,OAAe,EACf,cAAsB;QAEtB,MAAM,KAAK,GAAqB,EAAE,CAAC;QACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;YACjC,MAAM,EAAE,GAAG,SAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YAC5B,MAAM,OAAO,GAAG,SAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;YAC9C,6DAA6D;YAC7D,IAAI,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;gBACxB,OAAO,IAAA,eAAI,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC/B,CAAC;YAED,MAAM,MAAM,GAAG,WAAI,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;gBACtF,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;gBACvB,OAAO,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC;YACvB,CAAC,CAAC,CAAC;YACH,6DAA6D;YAC7D,IAAI,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC;gBACvB,OAAO,IAAA,eAAI,EAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QACD,OAAO,IAAA,kBAAO,EAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IAED;;OAEG;IACO,MAAM,CAAC,kBAAkB,CACjC,OAAe,EACf,OAAe,EACf,cAAsB;QAEtB,MAAM,KAAK,GAAqB,EAAE,CAAC;QACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;YACjC,MAAM,EAAE,GAAG,SAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,OAAO,GAAG,SAAG,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAC9C,6DAA6D;YAC7D,IAAI,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;gBACxB,OAAO,IAAA,eAAI,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC/B,CAAC;YAED,MAAM,MAAM,GAAG,WAAI,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;gBACzF,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;gBACvB,OAAO,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC;YACvB,CAAC,CAAC,CAAC;YACH,6DAA6D;YAC7D,IAAI,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC;gBACvB,OAAO,IAAA,eAAI,EAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QACD,OAAO,IAAA,kBAAO,EAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IAED;;;OAGG;IACK,uBAAuB,CAAC,IAAY;QAC1C,oBAAoB;QACpB,IAAI,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,EAAE,CAAC;YAC/B,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACnC,CAAC;QACD,wCAAwC;QACxC,IAAI,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;QACrD,CAAC;QACD,wCAAwC;QACxC,IAAI,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;QACrD,CAAC;QACD,0DAA0D;QAC1D,OAAO,MAAM,CAAC,GAAG,CAAC;IACpB,CAAC;IAED;;OAEG;IACK,MAAM,CAAC,mBAAmB,CAAC,MAAyB;QAC1D,MAAM,KAAK,GAAqB,EAAE,CAAC;QACnC,MAAM,SAAS,GAAG,MAAM,CAAC,gBAAgB,CAAC;QAC1C,MAAM,UAAU,GAAG,MAAM,CAAC,iBAAiB,CAAC;QAC5C,MAAM,UAAU,GAAG,MAAM,CAAC,iBAAiB,CAAC;QAC5C,MAAM,WAAW,GAAG,MAAM,CAAC,kBAAkB,CAAC;QAE9C,KAAK,IAAI,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,WAAW,EAAE,QAAQ,EAAE,EAAE,CAAC;YAC1D,KAAK,IAAI,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,UAAU,EAAE,QAAQ,EAAE,EAAE,CAAC;gBACzD,MAAM,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;gBACvC,MAAM,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;gBACtC,MAAM,EAAE,GAAG,SAAG,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;gBACxE,MAAM,OAAO,GAAG,SAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;gBAEvE,6DAA6D;gBAC7D,IAAI,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;oBACxB,OAAO,IAAA,eAAI,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC;gBAC/B,CAAC;gBAED,MAAM,MAAM,GAAG,WAAI,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,cAAc,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;oBACjG,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;oBACvB,OAAO,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC;gBACvB,CAAC,CAAC,CAAC;gBACH,6DAA6D;gBAC7D,IAAI,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC;oBACvB,OAAO,IAAA,eAAI,EAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBAC9B,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,IAAA,kBAAO,EAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IAEM,aAAa,CAAC,KAAkB;QACrC,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YACpC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;gBACxB,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACxC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,YAAY,CAAC,KAAkB;QACpC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACxC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,aAAa,CAAC,KAAkB;QACrC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/E,CAAC;IAEM,eAAe,CAAC,KAAkB;QACvC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3E,CAAC;IAEM,eAAe,CACpB,IAAyB,EACzB,KAAkB;QAElB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;YAC3C,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,MAAM,QAAQ,GAAkB,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;gBAC1E,OAAO,IAAA,kBAAO,EAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;YACrC,CAAC;YACD,OAAO,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,QAAuB,EAAE,EAAE;gBAC1E,OAAO,IAAA,kBAAO,EAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;YACrC,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,OAAO,CAAC,IAAiC;QAC9C,MAAM,IAAI,GAAG,SAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YACrB,OAAO,IAAA,eAAI,EAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5B,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAA,eAAI,EAAC,QAAQ,IAAI,CAAC,KAAK,YAAY,CAAC,CAAC;IACrE,CAAC;IAEM,eAAe,CACpB,IAAiC,EACjC,SAA8B,EAC9B,IAAoB;QAEpB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;YAC3C,MAAM,IAAI,GACR,SAAS,KAAK,MAAM,IAAI,SAAS,KAAK,OAAO;gBAC3C,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC;gBACzC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;YAC3C,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,cAAc,CAAC,WAAsC,EAAE,KAAkB;QAC9E,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QACvE,OAAO,IAAA,qBAAU,EACf,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACpB,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,EAAE,CACvD,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE;YACtD,MAAM,IAAI,mBAAiB,EAAE,EAAE,CAAC,CAAC,EAAE,IAAK,QAAQ,CAAC,QAAQ,CAAE,CAAC;YAC5D,OAAO,IAAA,kBAAO,EAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/B,CAAC,CAAC,CACH,CACF,CACF,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE;YAC1B,OAAO,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,YAAyB,EAAE,EAAE;gBAC3F,OAAO,IAAA,kBAAO,EAAC;oBACb,IAAI,EAAE,KAAK;oBACX,EAAE,EAAE,YAAY;oBAChB,KAAK,EAAE,WAAW;iBACnB,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,YAAY,CAAC,WAAsC,EAAE,KAAkB;QAC5E,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QACvE,OAAO,IAAA,qBAAU,EACf,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACpB,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,EAAE,CACvD,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE;YACtE,MAAM,IAAI,mBAAiB,EAAE,EAAE,CAAC,CAAC,EAAE,IAAK,QAAQ,CAAC,QAAQ,CAAE,CAAC;YAC5D,OAAO,IAAA,kBAAO,EAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/B,CAAC,CAAC,CACH,CACF,CACF,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE;YAC1B,OAAO,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,YAAyB,EAAE,EAAE;gBAC3F,OAAO,IAAA,kBAAO,EAAC;oBACb,IAAI,EAAE,KAAK;oBACX,EAAE,EAAE,YAAY;oBAChB,KAAK,EAAE,WAAW;iBACnB,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,WAAW,CAAC,WAAsC,EAAE,KAAkB;QAC3E,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QACvE,OAAO,IAAA,qBAAU,EACf,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACpB,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,EAAE,CACvD,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE;YACtE,MAAM,IAAI,mBAAiB,EAAE,EAAE,CAAC,CAAC,EAAE,IAAK,QAAQ,CAAC,QAAQ,CAAE,CAAC;YAC5D,OAAO,IAAA,kBAAO,EAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/B,CAAC,CAAC,CACH,CACF,CACF,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE;YAC1B,OAAO,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,YAAyB,EAAE,EAAE;gBAC3F,OAAO,IAAA,kBAAO,EAAC;oBACb,IAAI,EAAE,KAAK;oBACX,EAAE,EAAE,YAAY;oBAChB,KAAK,EAAE,WAAW;iBACnB,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,eAAe,CACpB,IAAyB,EACzB,KAAyB,EACzB,KAAkB;QAElB,MAAM,QAAQ,GAAG,SAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE;YAC/B,MAAM,MAAM,GAAe,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;YAChD,OAAO,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,eAAe,CACpB,IAAyB,EACzB,KAAe,EACf,KAAkB;QAElB,MAAM,QAAQ,GAAG,SAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,KAAK,GAAG,SAAS,CAAC;QACxB,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE;YAC/B,MAAM,MAAM,GAAe,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;YAChD,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,GAAoB;QAChC,MAAM,EAAE,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAA,eAAI,EAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC5D,CAAC;IAEM,SAAS,CAAC,GAAoB;QACnC,MAAM,EAAE,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACjE,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAA,eAAI,EAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAC/D,CAAC;IAEM,UAAU,CAAC,IAAyB;QACzC,MAAM,EAAE,GACN,OAAO,IAAI,KAAK,QAAQ;YACtB,CAAC,CAAC,SAAG,CAAC,aAAa,CACf,IAAI,CAAC,GAAG,EACR,IAAI,CAAC,GAAG,EACR,IAAI,CAAC,UAAU,CAAC,iBAAiB,EACjC,IAAI,CAAC,UAAU,CAAC,gBAAgB,CACjC;YACH,CAAC,CAAC,IAAI,CAAC;QACX,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAA,eAAI,EAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAChE,CAAC;IAEM,OAAO,CAAC,EAAU;QACvB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAA,eAAI,EAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAC7D,CAAC;IAEM,SAAS,CAAC,KAAkB;QACjC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3E,CAAC;IAEM,QAAQ,CAAC,KAAkB;QAChC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAEO,WAAW,CACjB,OAAmB,EACnB,SAA2B,EAC3B,IAAoB;QAEpB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QAExB,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QACtB,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;YACzB,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;gBACZ,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;YAChB,CAAC;iBAAM,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC3B,GAAG,GAAG,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;gBAC1B,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;oBACzB,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC;gBAC1D,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,IAAA,eAAI,EAAC,gCAAgC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC;aAAM,IAAI,SAAS,KAAK,OAAO,EAAE,CAAC;YACjC,IAAI,GAAG,GAAG,IAAI,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;gBAC9B,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;YAChB,CAAC;iBAAM,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC3B,GAAG,GAAG,CAAC,CAAC;gBACR,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;oBACzB,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;gBAC5D,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,IAAA,eAAI,EAAC,iCAAiC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;QACD,OAAO,IAAA,kBAAO,EAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IAC/B,CAAC;IAEO,QAAQ,CAAC,OAAmB,EAAE,SAAwB,EAAE,IAAoB;QAClF,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QACtB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QAExB,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvB,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;gBACZ,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;YAChB,CAAC;iBAAM,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC3B,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;gBACvB,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;oBACzB,OAAO,IAAI,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,IAAA,eAAI,EAAC,2BAA2B,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;aAAM,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;YAChC,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;gBAC3B,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;YAChB,CAAC;iBAAM,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC3B,GAAG,GAAG,CAAC,CAAC;gBACR,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;oBACzB,OAAO,IAAI,CAAC,WAAW,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;gBAChE,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,IAAA,eAAI,EAAC,6BAA6B,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;QACD,OAAO,IAAA,kBAAO,EAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IAC/B,CAAC;CACF;AA/fD,wBA+fC","sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2023 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Result, fail, mapResults, succeed } from '@fgv/ts-utils';\nimport {\n CageId,\n CellId,\n ICellContents,\n ICellState,\n IRowColumn,\n NavigationDirection,\n NavigationWrap\n} from './common';\n\nimport { Cage } from './cage';\nimport { Cell } from './cell';\nimport { Ids } from './ids';\nimport { IPuzzleDefinition } from './puzzleDefinitions';\nimport { ICell } from './public';\nimport { PuzzleState } from './puzzleState';\n\n/**\n * Describes a single cell update.\n * @public\n */\nexport interface ICellUpdate {\n from: ICellState;\n to: ICellState;\n}\n\n/**\n * Describes a single puzzle update.\n * @public\n */\nexport interface IPuzzleUpdate {\n from: PuzzleState;\n to: PuzzleState;\n cells: ICellUpdate[];\n}\n\n/**\n * Abstract base class for all puzzles.\n * @public\n */\nexport class Puzzle {\n public readonly id?: string;\n public readonly description: string;\n public readonly type: string;\n public readonly initialState: PuzzleState;\n public readonly dimensions: IPuzzleDefinition;\n\n /**\n * @public\n */\n protected readonly _rows: Map<CageId, Cage>;\n\n /**\n * @public\n */\n protected readonly _columns: Map<CageId, Cage>;\n\n /**\n * @public\n */\n protected readonly _sections: Map<CageId, Cage>;\n\n /**\n * @public\n */\n protected readonly _cages: Map<CageId, Cage>;\n\n /**\n * @public\n */\n protected readonly _cells: Map<CellId, Cell>;\n\n /**\n * Constructs a new puzzle state.\n * @param puzzle - {@link IPuzzleDefinition | Puzzle definition} from which this puzzle state\n * is to be initialized.\n */\n protected constructor(puzzle: IPuzzleDefinition, extraCages?: [CageId, Cage][]) {\n /* c8 ignore next - ?? is defense in depth */\n extraCages = extraCages ?? [];\n\n // Validate cell count matches grid size\n /* c8 ignore next 7 - defensive test - not reachable in practice */\n if (puzzle.cells.length !== puzzle.totalRows * puzzle.totalColumns) {\n throw new Error(\n `Puzzle '${puzzle.description}\" expected ${puzzle.totalRows * puzzle.totalColumns} cells, found ${\n puzzle.cells.length\n }`\n );\n }\n\n this.id = puzzle.id;\n this.description = puzzle.description;\n this.type = puzzle.type;\n this.dimensions = puzzle;\n\n const rows = Puzzle._createRowCages(\n puzzle.totalRows,\n puzzle.totalColumns,\n puzzle.basicCageTotal\n ).orThrow();\n const columns = Puzzle._createColumnCages(\n puzzle.totalRows,\n puzzle.totalColumns,\n puzzle.basicCageTotal\n ).orThrow();\n const sections = Puzzle._createSectionCages(puzzle).orThrow();\n const cages = [...rows, ...columns, ...sections, ...extraCages];\n this._rows = new Map(rows);\n this._columns = new Map(columns);\n this._sections = new Map(sections);\n this._cages = new Map(cages);\n this._cells = new Map();\n\n const cellInit = [...puzzle.cells];\n for (let row = 0; row < this._rows.size; row++) {\n const rowCage = this.getRow(row).orThrow();\n for (let col = 0; col < this._columns.size; col++) {\n const id = Ids.cellId({ row, col }).orThrow();\n const colCage = this.getColumn(col).orThrow();\n const sectionCage = this.getSection({ row, col }).orThrow();\n const otherCages = extraCages.filter(([__key, cage]) => cage.containsCell(id));\n\n const init = cellInit.shift();\n /* c8 ignore next - defense in depth/make type check happy. undefined init should never happen */\n const immutableValue = init === '.' ? undefined : this._parseAlphanumericValue(init ?? '0');\n if (\n immutableValue !== undefined &&\n (Number.isNaN(immutableValue) || immutableValue < 1 || immutableValue > puzzle.maxValue)\n ) {\n throw new Error(`Puzzle ${puzzle.description} illegal value \"${init}\" for cell ${id}`);\n }\n const cages = [rowCage, colCage, sectionCage, ...otherCages.map(([__key, state]) => state)];\n const cell = new Cell({ id, immutableValue, row, col }, cages);\n this._cells.set(id, cell);\n }\n }\n\n this.initialState = PuzzleState.create(\n Array.from(this._cells.entries()).map(([id, state]): ICellState => {\n return { id, value: state.immutableValue, notes: [] };\n })\n ).orThrow();\n }\n\n public get numRows(): number {\n return this._rows.size;\n }\n\n public get numColumns(): number {\n return this._columns.size;\n }\n\n public get rows(): Cage[] {\n return Array.from(this._rows.values());\n }\n\n public get cols(): Cage[] {\n return Array.from(this._columns.values());\n }\n\n public get sections(): Cage[] {\n return Array.from(this._sections.values());\n }\n\n public get cages(): Cage[] {\n return Array.from(this._cages.values());\n }\n\n public get cells(): Cell[] {\n return Array.from(this._cells.values());\n }\n\n /**\n * @internal\n */\n protected static _createRowCages(\n numRows: number,\n numCols: number,\n basicCageTotal: number\n ): Result<[CageId, Cage][]> {\n const cages: [CageId, Cage][] = [];\n for (let r = 0; r < numRows; r++) {\n const id = Ids.rowCageId(r);\n const cellIds = Ids.cellIds(r, 1, 0, numCols);\n /* c8 ignore next 3 - defense in depth should never happen */\n if (cellIds.isFailure()) {\n return fail(cellIds.message);\n }\n\n const result = Cage.create(id, 'row', basicCageTotal, cellIds.value).onSuccess((cage) => {\n cages.push([id, cage]);\n return succeed(cage);\n });\n /* c8 ignore next 3 - defense in depth should never happen */\n if (result.isFailure()) {\n return fail(result.message);\n }\n }\n return succeed(cages);\n }\n\n /**\n * @internal\n */\n protected static _createColumnCages(\n numRows: number,\n numCols: number,\n basicCageTotal: number\n ): Result<[CageId, Cage][]> {\n const cages: [CageId, Cage][] = [];\n for (let c = 0; c < numCols; c++) {\n const id = Ids.columnCageId(c);\n const cellIds = Ids.cellIds(0, numRows, c, 1);\n /* c8 ignore next 3 - defense in depth should never happen */\n if (cellIds.isFailure()) {\n return fail(cellIds.message);\n }\n\n const result = Cage.create(id, 'column', basicCageTotal, cellIds.value).onSuccess((cage) => {\n cages.push([id, cage]);\n return succeed(cage);\n });\n /* c8 ignore next 3 - defense in depth should never happen */\n if (result.isFailure()) {\n return fail(result.message);\n }\n }\n return succeed(cages);\n }\n\n /**\n * Parse alphanumeric cell value (1-9, A-Z for values 10-35)\n * @internal\n */\n private _parseAlphanumericValue(char: string): number {\n // Handle digits 1-9\n if (char >= '1' && char <= '9') {\n return Number.parseInt(char, 10);\n }\n // Handle uppercase A-Z for values 10-35\n if (char >= 'A' && char <= 'Z') {\n return char.charCodeAt(0) - 'A'.charCodeAt(0) + 10;\n }\n // Handle lowercase a-z for values 10-35\n if (char >= 'a' && char <= 'z') {\n return char.charCodeAt(0) - 'a'.charCodeAt(0) + 10;\n }\n // Invalid character, return NaN to trigger error handling\n return Number.NaN;\n }\n\n /**\n * @internal\n */\n private static _createSectionCages(puzzle: IPuzzleDefinition): Result<[CageId, Cage][]> {\n const cages: [CageId, Cage][] = [];\n const cageWidth = puzzle.cageWidthInCells;\n const cageHeight = puzzle.cageHeightInCells;\n const boardWidth = puzzle.boardWidthInCages;\n const boardHeight = puzzle.boardHeightInCages;\n\n for (let boardRow = 0; boardRow < boardHeight; boardRow++) {\n for (let boardCol = 0; boardCol < boardWidth; boardCol++) {\n const startRow = boardRow * cageHeight;\n const startCol = boardCol * cageWidth;\n const id = Ids.sectionCageId(startRow, startCol, cageHeight, cageWidth);\n const cellIds = Ids.cellIds(startRow, cageHeight, startCol, cageWidth);\n\n /* c8 ignore next 3 - defense in depth should never happen */\n if (cellIds.isFailure()) {\n return fail(cellIds.message);\n }\n\n const result = Cage.create(id, 'section', puzzle.basicCageTotal, cellIds.value).onSuccess((cage) => {\n cages.push([id, cage]);\n return succeed(cage);\n });\n /* c8 ignore next 3 - defense in depth should never happen */\n if (result.isFailure()) {\n return fail(result.message);\n }\n }\n }\n return succeed(cages);\n }\n\n public checkIsSolved(state: PuzzleState): boolean {\n for (const id of this._cells.keys()) {\n if (!state.hasValue(id)) {\n return false;\n }\n }\n for (const cell of this._cells.values()) {\n if (!cell.isValid(state)) {\n return false;\n }\n }\n return true;\n }\n\n public checkIsValid(state: PuzzleState): boolean {\n for (const cell of this._cells.values()) {\n if (!cell.isValid(state)) {\n return false;\n }\n }\n return true;\n }\n\n public getEmptyCells(state: PuzzleState): Cell[] {\n return Array.from(this._cells.values()).filter((c) => !state.hasValue(c.id));\n }\n\n public getInvalidCells(state: PuzzleState): Cell[] {\n return Array.from(this._cells.values()).filter((c) => !c.isValid(state));\n }\n\n public getCellContents(\n spec: string | IRowColumn,\n state: PuzzleState\n ): Result<{ cell: Cell; contents: ICellContents }> {\n return this.getCell(spec).onSuccess((cell) => {\n if (cell.immutable) {\n const contents: ICellContents = { value: cell.immutableValue, notes: [] };\n return succeed({ cell, contents });\n }\n return state.getCellContents(cell.id).onSuccess((contents: ICellContents) => {\n return succeed({ cell, contents });\n });\n });\n }\n\n public getCell(spec: string | IRowColumn | ICell): Result<Cell> {\n const want = Ids.cellId(spec);\n if (want.isFailure()) {\n return fail(want.message);\n }\n\n const cell = this._cells.get(want.value);\n return cell ? succeed(cell) : fail(`Cell ${want.value} not found`);\n }\n\n public getCellNeighbor(\n spec: string | IRowColumn | ICell,\n direction: NavigationDirection,\n wrap: NavigationWrap\n ): Result<ICell> {\n return this.getCell(spec).onSuccess((cell) => {\n const move =\n direction === 'left' || direction === 'right'\n ? this._moveColumn(cell, direction, wrap)\n : this._moveRow(cell, direction, wrap);\n return move.onSuccess((next) => this.getCell(next));\n });\n }\n\n public updateContents(wantUpdates: ICellState[] | ICellState, state: PuzzleState): Result<IPuzzleUpdate> {\n wantUpdates = Array.isArray(wantUpdates) ? wantUpdates : [wantUpdates];\n return mapResults(\n wantUpdates.map((u) =>\n this.getCellContents(u.id, state).onSuccess((existing) =>\n existing.cell.update(u.value, u.notes).onSuccess((to) => {\n const from: ICellState = { id: u.id, ...existing.contents };\n return succeed({ from, to });\n })\n )\n )\n ).onSuccess((cellUpdates) => {\n return state.update(cellUpdates.map(({ to }) => to)).onSuccess((updatedState: PuzzleState) => {\n return succeed({\n from: state,\n to: updatedState,\n cells: cellUpdates\n });\n });\n });\n }\n\n public updateValues(wantUpdates: ICellState[] | ICellState, state: PuzzleState): Result<IPuzzleUpdate> {\n wantUpdates = Array.isArray(wantUpdates) ? wantUpdates : [wantUpdates];\n return mapResults(\n wantUpdates.map((u) =>\n this.getCellContents(u.id, state).onSuccess((existing) =>\n existing.cell.update(u.value, existing.contents.notes).onSuccess((to) => {\n const from: ICellState = { id: u.id, ...existing.contents };\n return succeed({ from, to });\n })\n )\n )\n ).onSuccess((cellUpdates) => {\n return state.update(cellUpdates.map(({ to }) => to)).onSuccess((updatedState: PuzzleState) => {\n return succeed({\n from: state,\n to: updatedState,\n cells: cellUpdates\n });\n });\n });\n }\n\n public updateNotes(wantUpdates: ICellState[] | ICellState, state: PuzzleState): Result<IPuzzleUpdate> {\n wantUpdates = Array.isArray(wantUpdates) ? wantUpdates : [wantUpdates];\n return mapResults(\n wantUpdates.map((u) =>\n this.getCellContents(u.id, state).onSuccess((existing) =>\n existing.cell.update(existing.contents.value, u.notes).onSuccess((to) => {\n const from: ICellState = { id: u.id, ...existing.contents };\n return succeed({ from, to });\n })\n )\n )\n ).onSuccess((cellUpdates) => {\n return state.update(cellUpdates.map(({ to }) => to)).onSuccess((updatedState: PuzzleState) => {\n return succeed({\n from: state,\n to: updatedState,\n cells: cellUpdates\n });\n });\n });\n }\n\n public updateCellValue(\n want: string | IRowColumn,\n value: number | undefined,\n state: PuzzleState\n ): Result<IPuzzleUpdate> {\n const idResult = Ids.cellId(want);\n const notes: number[] = [];\n return idResult.onSuccess((id) => {\n const update: ICellState = { id, value, notes };\n return this.updateValues([update], state);\n });\n }\n\n public updateCellNotes(\n want: string | IRowColumn,\n notes: number[],\n state: PuzzleState\n ): Result<IPuzzleUpdate> {\n const idResult = Ids.cellId(want);\n const value = undefined;\n return idResult.onSuccess((id) => {\n const update: ICellState = { id, value, notes };\n return this.updateNotes([update], state);\n });\n }\n\n public getRow(row: CageId | number): Result<Cage> {\n const id = typeof row === 'number' ? Ids.rowCageId(row) : row;\n const cage = this._rows.get(id);\n return cage ? succeed(cage) : fail(`Row ${id} not found`);\n }\n\n public getColumn(col: CageId | number): Result<Cage> {\n const id = typeof col === 'number' ? Ids.columnCageId(col) : col;\n const cage = this._columns.get(id);\n return cage ? succeed(cage) : fail(`Column ${id} not found`);\n }\n\n public getSection(spec: CageId | IRowColumn): Result<Cage> {\n const id =\n typeof spec === 'object'\n ? Ids.sectionCageId(\n spec.row,\n spec.col,\n this.dimensions.cageHeightInCells,\n this.dimensions.cageWidthInCells\n )\n : spec;\n const cage = this._sections.get(id);\n return cage ? succeed(cage) : fail(`Section ${id} not found`);\n }\n\n public getCage(id: CageId): Result<Cage> {\n const cage = this._cages.get(id);\n return cage ? succeed(cage) : fail(`Cage ${id} not found`);\n }\n\n public toStrings(state: PuzzleState): string[] {\n return Array.from(this._rows.values()).map((row) => row.toString(state));\n }\n\n public toString(state: PuzzleState): string {\n return this.toStrings(state).join('\\n');\n }\n\n private _moveColumn(\n current: IRowColumn,\n direction: 'left' | 'right',\n wrap: NavigationWrap\n ): Result<IRowColumn> {\n const row = current.row;\n\n let col = current.col;\n if (direction === 'left') {\n if (col > 0) {\n col = col - 1;\n } else if (wrap !== 'none') {\n col = this.numColumns - 1;\n if (wrap === 'wrap-next') {\n return this._moveRow({ row, col }, 'up', 'wrap-around');\n }\n } else {\n return fail(`cannot move left from column ${current.col}`);\n }\n } else if (direction === 'right') {\n if (col < this.numColumns - 1) {\n col = col + 1;\n } else if (wrap !== 'none') {\n col = 0;\n if (wrap === 'wrap-next') {\n return this._moveRow({ row, col }, 'down', 'wrap-around');\n }\n } else {\n return fail(`cannot move right from column ${current.col}`);\n }\n }\n return succeed({ row, col });\n }\n\n private _moveRow(current: IRowColumn, direction: 'up' | 'down', wrap: NavigationWrap): Result<IRowColumn> {\n let row = current.row;\n const col = current.col;\n\n if (direction === 'up') {\n if (row > 0) {\n row = row - 1;\n } else if (wrap !== 'none') {\n row = this.numRows - 1;\n if (wrap === 'wrap-next') {\n return this._moveColumn({ row, col }, 'left', 'wrap-around');\n }\n } else {\n return fail(`cannot move up from row ${current.row}`);\n }\n } else if (direction === 'down') {\n if (row < this.numRows - 1) {\n row = row + 1;\n } else if (wrap !== 'none') {\n row = 0;\n if (wrap === 'wrap-next') {\n return this._moveColumn({ row, col }, 'right', 'wrap-around');\n }\n } else {\n return fail(`cannot move down from row ${current.row}`);\n }\n }\n return succeed({ row, col });\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"puzzleDefinitions.d.ts","sourceRoot":"","sources":["../../../src/packlets/common/puzzleDefinitions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"puzzleDefinitions.js","sourceRoot":"","sources":["../../../src/packlets/common/puzzleDefinitions.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2023 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Result, succeed, fail, captureResult } from '@fgv/ts-utils';\nimport { PuzzleType, CageId, CellId } from './common';\nimport { ICage } from './public';\n\n/**\n * Interface for puzzle type-specific validation\n * @public\n */\nexport interface IPuzzleTypeValidator {\n /**\n * Validate the cells string for this puzzle type\n */\n validateCells(cells: string, dimensions: IPuzzleDimensions): Result<true>;\n}\n\n/**\n * Default validator for standard Sudoku puzzles\n */\nclass StandardSudokuValidator implements IPuzzleTypeValidator {\n public validateCells(cells: string, dimensions: IPuzzleDimensions): Result<true> {\n const expectedLength =\n dimensions.cageHeightInCells *\n dimensions.boardHeightInCages *\n dimensions.cageWidthInCells *\n dimensions.boardWidthInCages;\n\n if (cells.length !== expectedLength) {\n return fail(`Expected ${expectedLength} cells, got ${cells.length}`);\n }\n\n return succeed(true);\n }\n}\n\n/**\n * Validator for Killer Sudoku puzzles - understands extended format with cage definitions\n */\nclass KillerSudokuValidator implements IPuzzleTypeValidator {\n public validateCells(cells: string, dimensions: IPuzzleDimensions): Result<true> {\n const expectedBasicLength =\n dimensions.cageHeightInCells *\n dimensions.boardHeightInCages *\n dimensions.cageWidthInCells *\n dimensions.boardWidthInCages;\n\n // Killer sudoku cells format includes cage definitions, so it will be longer than basic format\n // The basic grid should be at the beginning of the string\n if (cells.length < expectedBasicLength) {\n return fail(\n `Killer sudoku cells must contain at least ${expectedBasicLength} grid cells, got ${cells.length}`\n );\n }\n\n // Find the separator between grid and cage definitions\n const separatorIndex = cells.indexOf('|');\n if (separatorIndex === -1) {\n return fail('Killer sudoku cells must contain cage definitions after \"|\" separator');\n }\n\n if (separatorIndex !== expectedBasicLength) {\n return fail(\n `Killer sudoku grid portion must be exactly ${expectedBasicLength} characters, got ${separatorIndex}`\n );\n }\n\n // Extract the basic grid portion (before the | separator)\n const gridPortion = cells.substring(0, separatorIndex);\n\n // For killer sudoku, the grid portion contains:\n // - Digits 1-9 for prefilled values\n // - '.' for empty cells\n // - Letters A-Z, a-z for cage identifiers\n const maxDigit = dimensions.cageWidthInCells * dimensions.cageHeightInCells;\n const validDigits = new Set(['.', ...Array.from({ length: maxDigit }, (__val, i) => String(i + 1))]);\n const validCageLetters = new Set([...'ABCDEFGHIJKLMNOPQRSTUVWXYZ', ...'abcdefghijklmnopqrstuvwxyz']);\n\n for (let i = 0; i < gridPortion.length; i++) {\n const char = gridPortion[i];\n if (!validDigits.has(char) && !validCageLetters.has(char)) {\n return fail(`Invalid character '${char}' at position ${i} in killer sudoku grid portion`);\n }\n }\n\n return succeed(true);\n }\n}\n\n/**\n * Validator for Sudoku X puzzles - same as standard but with diagonal constraints\n */\nclass SudokuXValidator implements IPuzzleTypeValidator {\n public validateCells(cells: string, dimensions: IPuzzleDimensions): Result<true> {\n // Sudoku X uses the same cell format as standard sudoku\n return new StandardSudokuValidator().validateCells(cells, dimensions);\n }\n}\n\n/**\n * Registry of validators for different puzzle types\n */\nconst PUZZLE_TYPE_VALIDATORS: Record<PuzzleType, IPuzzleTypeValidator> = {\n sudoku: new StandardSudokuValidator(),\n 'killer-sudoku': new KillerSudokuValidator(),\n 'sudoku-x': new SudokuXValidator()\n};\n\n/**\n * Core dimensional configuration for a puzzle grid\n * @public\n */\nexport interface IPuzzleDimensions {\n /** Width of each section/cage (e.g., 3 for standard Sudoku) */\n readonly cageWidthInCells: number;\n\n /** Height of each section/cage (e.g., 3 for standard Sudoku) */\n readonly cageHeightInCells: number;\n\n /** Number of cages horizontally (e.g., 3 for standard Sudoku) */\n readonly boardWidthInCages: number;\n\n /** Number of cages vertically (e.g., 3 for standard Sudoku) */\n readonly boardHeightInCages: number;\n}\n\n/**\n * Complete puzzle definition with derived properties\n * @public\n */\nexport interface IPuzzleDefinition extends IPuzzleDimensions {\n // Basic puzzle info\n readonly id?: string;\n readonly description: string;\n readonly type: PuzzleType;\n readonly level: number;\n readonly cells: string;\n\n // Derived properties (calculated from dimensions)\n readonly totalRows: number; // cageHeightInCells * boardHeightInCages\n readonly totalColumns: number; // cageWidthInCells * boardWidthInCages\n readonly maxValue: number; // cageWidthInCells * cageHeightInCells\n readonly totalCages: number; // boardWidthInCages * boardHeightInCages\n readonly basicCageTotal: number; // Sum of 1..maxValue\n\n // Optional cage data (for Killer Sudoku)\n readonly cages?: ICage[];\n}\n\n/**\n * Standard puzzle configurations\n * @public\n */\nexport const STANDARD_CONFIGS = {\n puzzle4x4: { cageWidthInCells: 2, cageHeightInCells: 2, boardWidthInCages: 2, boardHeightInCages: 2 },\n puzzle6x6: { cageWidthInCells: 3, cageHeightInCells: 2, boardWidthInCages: 2, boardHeightInCages: 3 },\n puzzle9x9: { cageWidthInCells: 3, cageHeightInCells: 3, boardWidthInCages: 3, boardHeightInCages: 3 },\n puzzle12x12: { cageWidthInCells: 4, cageHeightInCells: 3, boardWidthInCages: 3, boardHeightInCages: 4 }\n} as const;\n\n/**\n * Type for standard configuration names\n * @public\n */\nexport type StandardConfigName = keyof typeof STANDARD_CONFIGS;\n\n/**\n * Factory for creating and validating puzzle definitions\n * @public\n */\nexport class PuzzleDefinitionFactory {\n /**\n * Create a puzzle definition from dimensions and options\n */\n public static create(\n dimensions: IPuzzleDimensions,\n options: Partial<IPuzzleDefinition> = {}\n ): Result<IPuzzleDefinition> {\n const dimensionValidation = this.validate(dimensions);\n if (dimensionValidation.isFailure()) {\n return fail(dimensionValidation.message);\n }\n\n const totalRows = dimensions.cageHeightInCells * dimensions.boardHeightInCages;\n const totalColumns = dimensions.cageWidthInCells * dimensions.boardWidthInCages;\n const maxValue = dimensions.cageWidthInCells * dimensions.cageHeightInCells;\n const totalCages = dimensions.boardWidthInCages * dimensions.boardHeightInCages;\n const basicCageTotal = this._calculateBasicCageTotal(maxValue);\n\n // Validate cell data using type-specific validator\n if (options.cells) {\n const puzzleType = options.type ?? 'sudoku';\n const validator = PUZZLE_TYPE_VALIDATORS[puzzleType];\n if (!validator) {\n return fail(`Unknown puzzle type: ${puzzleType}`);\n }\n\n const cellValidation = validator.validateCells(options.cells, dimensions);\n if (cellValidation.isFailure()) {\n return fail(cellValidation.message);\n }\n }\n\n const puzzleDefinition: IPuzzleDefinition = {\n // Dimensions\n cageWidthInCells: dimensions.cageWidthInCells,\n cageHeightInCells: dimensions.cageHeightInCells,\n boardWidthInCages: dimensions.boardWidthInCages,\n boardHeightInCages: dimensions.boardHeightInCages,\n\n // Derived properties\n totalRows,\n totalColumns,\n maxValue,\n totalCages,\n basicCageTotal,\n\n // Default values\n id: options.id,\n description: options.description ?? `${totalRows}x${totalColumns} puzzle`,\n type: options.type ?? 'sudoku',\n level: options.level ?? 1,\n cells: options.cells ?? '.'.repeat(totalRows * totalColumns),\n cages: options.cages\n };\n\n return succeed(puzzleDefinition);\n }\n\n /**\n * Create killer sudoku puzzle definition with cage constraints\n */\n public static createKiller(\n dimensions: IPuzzleDimensions,\n description: Omit<\n IPuzzleDefinition,\n | 'cageWidthInCells'\n | 'cageHeightInCells'\n | 'boardWidthInCages'\n | 'boardHeightInCages'\n | 'totalRows'\n | 'totalColumns'\n | 'maxValue'\n | 'totalCages'\n | 'basicCageTotal'\n | 'cages'\n > & {\n killerCages: Array<{\n id: string;\n cellPositions: Array<{ row: number; col: number }>;\n sum: number;\n }>;\n }\n ): Result<IPuzzleDefinition> {\n return captureResult(() => {\n // Import needed here to avoid circular dependencies\n const { Ids } = require('./ids');\n\n // Convert killer cage format to standard cage format - creating minimal cage objects\n const cages = description.killerCages.map((killerCage): ICage => {\n const cellIds = killerCage.cellPositions.map((pos) => Ids.cellId(pos).orThrow());\n\n return {\n id: `K${killerCage.id}` as CageId,\n cellIds,\n cageType: 'killer',\n total: killerCage.sum,\n numCells: cellIds.length,\n /* c8 ignore next 1 - coverage fails when run as part of full suite */\n containsCell: (cellId: CellId) => cellIds.includes(cellId)\n };\n });\n\n // Return the result directly, not wrapped in another Result\n const result = this.create(dimensions, {\n ...description,\n cages,\n type: 'killer-sudoku'\n });\n\n if (result.isFailure()) {\n throw new Error(result.message);\n }\n return result.value;\n }).onFailure((error) => fail(`Failed to create killer sudoku: ${error}`));\n }\n\n /**\n * Validate puzzle dimensions\n */\n public static validate(dimensions: IPuzzleDimensions): Result<true> {\n // Structural validation\n if (dimensions.cageWidthInCells < 1 || dimensions.cageHeightInCells < 1) {\n return fail('Cage dimensions must be positive integers');\n }\n\n // Sudoku cages must be multi-cell (both dimensions > 1)\n if (dimensions.cageWidthInCells < 2 || dimensions.cageHeightInCells < 2) {\n return fail('Cage dimensions must be at least 2x2 for valid Sudoku puzzles');\n }\n\n if (dimensions.boardWidthInCages < 1 || dimensions.boardHeightInCages < 1) {\n return fail('Board dimensions must be positive integers');\n }\n\n // Size constraints (reasonable limits)\n const totalRows = dimensions.cageHeightInCells * dimensions.boardHeightInCages;\n const totalColumns = dimensions.cageWidthInCells * dimensions.boardWidthInCages;\n\n if (totalRows > 25 || totalColumns > 25) {\n return fail('Total grid size must not exceed 25x25');\n }\n\n // Mathematical validity - ensure cage size makes sense for Sudoku constraints\n const maxValue = dimensions.cageWidthInCells * dimensions.cageHeightInCells;\n if (maxValue < 2 || maxValue > 25) {\n return fail('Cage size must result in values between 2 and 25');\n }\n\n return succeed(true);\n }\n\n /**\n * Get a standard configuration by name\n */\n public static getStandardConfig(name: StandardConfigName): IPuzzleDimensions {\n return STANDARD_CONFIGS[name];\n }\n\n /**\n * Get all available standard configurations\n */\n public static getStandardConfigs(): Record<StandardConfigName, IPuzzleDimensions> {\n return STANDARD_CONFIGS;\n }\n\n /**\n * Get validator for a specific puzzle type\n */\n public static getValidator(puzzleType: PuzzleType): IPuzzleTypeValidator | undefined {\n return PUZZLE_TYPE_VALIDATORS[puzzleType];\n }\n\n /**\n * Register a custom validator for a puzzle type\n */\n public static registerValidator(puzzleType: PuzzleType, validator: IPuzzleTypeValidator): void {\n PUZZLE_TYPE_VALIDATORS[puzzleType] = validator;\n }\n\n /**\n * Calculate the basic cage total (sum of 1 to maxValue)\n */\n private static _calculateBasicCageTotal(maxValue: number): number {\n return (maxValue * (maxValue + 1)) / 2;\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"puzzleSession.d.ts","sourceRoot":"","sources":["../../../src/packlets/common/puzzleSession.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"puzzleSession.js","sourceRoot":"","sources":["../../../src/packlets/common/puzzleSession.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2023 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Result, captureResult, fail, succeed } from '@fgv/ts-utils';\nimport { Cage } from './cage';\nimport { Cell } from './cell';\nimport { ICellContents, ICellState, IRowColumn, NavigationDirection, NavigationWrap } from './common';\nimport { Ids } from './ids';\nimport { ICage, ICell } from './public';\nimport { ICellUpdate, Puzzle } from './puzzle';\nimport { PuzzleState } from './puzzleState';\n\ninterface IPuzzleStep {\n updates: ICellUpdate[];\n}\n\n/**\n * Represents a single puzzle session, including puzzle, current state and redo/undo.\n * @public\n */\nexport class PuzzleSession {\n /**\n * The current {@link PuzzleState | state} of this puzzle session.\n */\n public state: PuzzleState;\n\n protected readonly _puzzle: Puzzle;\n protected _nextStep: number;\n protected _numSteps: number;\n protected _steps: IPuzzleStep[];\n\n /**\n * @internal\n */\n protected constructor(puzzle: Puzzle) {\n this._puzzle = puzzle;\n this.state = puzzle.initialState;\n this._nextStep = 0;\n this._numSteps = 0;\n this._steps = [];\n }\n\n /**\n * ID of the puzzle being solved.\n */\n public get id(): string | undefined {\n return this._puzzle.id;\n }\n\n /**\n * Description of the puzzle being solved.\n */\n public get description(): string {\n return this._puzzle.description;\n }\n\n /**\n * Type of the puzzle being solved.\n */\n public get type(): string {\n return this._puzzle.type;\n }\n\n /**\n * Number of rows in the puzzle being solved.\n */\n public get numRows(): number {\n return this._puzzle.numRows;\n }\n\n /**\n * Number of columns in the puzzle being solved.\n */\n public get numColumns(): number {\n return this._puzzle.numColumns;\n }\n\n /**\n * The row {@link ICage | cages} in the puzzle being solved.\n */\n public get rows(): ICage[] {\n return this._puzzle.rows;\n }\n\n /**\n * The column {@link ICage | cages} in the puzzle being solved.\n */\n public get cols(): ICage[] {\n return this._puzzle.cols;\n }\n\n /**\n * The section {@link ICage | cages} in the puzzle being solved.\n */\n public get sections(): ICage[] {\n return this._puzzle.sections;\n }\n\n /**\n * All {@link ICage | cages} in the puzzle being solved.\n */\n public get cages(): ICage[] {\n return this._puzzle.cages;\n }\n\n /**\n * The cells {@link ICell | cells} in the puzzle being solved.\n */\n public get cells(): ICell[] {\n return this._puzzle.cells;\n }\n\n /**\n * The puzzle structure for this session.\n */\n public get puzzle(): Puzzle {\n return this._puzzle;\n }\n\n /**\n * Index of the next step in this puzzle session.\n */\n public get nextStep(): number {\n return this._nextStep;\n }\n\n /**\n * Number of steps currently elapsed in this puzzle session. Note\n * that after undo, `nextStep` will be less than `numSteps`.\n */\n public get numSteps(): number {\n return this._numSteps;\n }\n\n /***\n * Indicates whether undo is currently possible.\n */\n public get canUndo(): boolean {\n return this._nextStep > 0;\n }\n\n /**\n * Indicates whether redo is currently possible.\n */\n public get canRedo(): boolean {\n return this._nextStep < this._numSteps;\n }\n\n /**\n * Creates a new {@link PuzzleSession | puzzle session} from a supplied\n * {@link Puzzle | puzzle}.\n * @param puzzle - The {@link Puzzle | puzzle} from which the session is to be\n * initialized.\n * @returns `Success` with the requested {@link PuzzleSession | puzzle session},\n * or `Failure` with details if an error occurs.\n */\n public static create(puzzle: Puzzle): Result<PuzzleSession> {\n return captureResult(() => new PuzzleSession(puzzle));\n }\n\n /**\n * Determines if the puzzle is correctly solved.\n * @returns `true` if the puzzle is solved, `false` if the puzzle has\n * empty or invalid cells.\n */\n public checkIsSolved(): boolean {\n return this._puzzle.checkIsSolved(this.state);\n }\n\n /**\n * Determines if the puzzle is valid in its current state.\n * @returns `true` if all non-empty cells in the puzzle are valid,\n * or `false` if any cells are invalid.\n */\n public checkIsValid(): boolean {\n return this._puzzle.checkIsValid(this.state);\n }\n\n /**\n * Gets all of the currently empty {@link ICell | cells} in the puzzle.\n * @returns An array of {@link ICell | ICell} with all empty cells.\n */\n public getEmptyCells(): ICell[] {\n return this._puzzle.getEmptyCells(this.state);\n }\n\n /**\n * Gets all of the currently invalid {@link ICell | cells} in the puzzle.\n * @returns An array of {@link ICell | ICell} with all invalid cells.\n */\n public getInvalidCells(): ICell[] {\n return this._puzzle.getInvalidCells(this.state);\n }\n\n /**\n * Determines if a cell is valid.\n * @param spec - A `string` ({@link CellId | CellId}), {@link IRowColumn | RowColumn} or {@link ICell | ICell}\n * describing the cell to be tested.\n * @returns `true` if the cell value is valid, `false` if the cell value or the cell itself is invalid.\n */\n public cellIsValid(spec: string | IRowColumn | ICell): boolean {\n return this._cell(spec)?.isValid(this.state) === true;\n }\n\n /**\n * Determines if a cell has a value.\n * @param spec - A `string` ({@link CellId | CellId}), {@link IRowColumn | RowColumn} or {@link ICell | ICell}\n * describing the cell to be tested.\n * @returns `true` if the cell has a value, `false` if the cell is empty or the cell itself is invalid.\n */\n public cellHasValue(spec: string | IRowColumn | ICell): boolean {\n return this._cell(spec)?.hasValue(this.state) === true;\n }\n\n /**\n * Determines if supplied value is valid for a specific cell.\n * @param spec - A `string` ({@link CellId | CellId}), {@link IRowColumn | RowColumn} or {@link ICell | ICell}\n * describing the cell to be tested.\n * @param value - The value to be tested.\n * @returns `true` if `value` is valid for the requested cell, `false` if the value or the cell itself is invalid.\n */\n public isValidForCell(spec: string | IRowColumn | ICell, value: number): boolean {\n return this._cell(spec)?.isValidValue(value, this.state) === true;\n }\n\n /**\n * Gets the neighbor for a cell in a given direction using specified wrapping rules.\n * @param spec - A `string` ({@link CellId | CellId}), {@link IRowColumn | RowColumn} or {@link ICell | ICell}\n * describing the cell to be tested.\n * @param direction - The direction of the desired neighbor.\n * @param wrap - Wrapping rules to be applied.\n * @returns `Success` with the requested {@link ICell | cell}, or `Failure` with details if an error occurs.\n */\n public getCellNeighbor(\n spec: string | IRowColumn | ICell,\n direction: NavigationDirection,\n wrap: NavigationWrap\n ): Result<ICell> {\n return this._puzzle.getCellNeighbor(spec, direction, wrap);\n }\n\n /**\n * Gets the {@link ICellContents | contents} for a specified cell.\n * @param spec - A `string` ({@link CellId | CellId}), {@link IRowColumn | RowColumn} or {@link ICell | ICell}\n * describing the cell to be queried.\n * @returns `Success` with the {@link ICell | cell description} and {@link ICellContents | cell contents}, or\n * `Failure` with details if an error occurs.\n */\n public getCellContents(spec: string | IRowColumn): Result<{ cell: ICell; contents: ICellContents }> {\n return this._puzzle.getCellContents(spec, this.state);\n }\n\n /**\n * Updates the value of a cell.\n * @param spec - A `string`, {@link IRowColumn | row and column}, or {@link ICell | cell} identifying\n * the cell to be updated.\n * @param value - A new value for the cell.\n * @returns `Success` with `this` if the update is applied, `Failure` with details if an error occurs.\n */\n public updateCellValue(spec: string | IRowColumn | ICell, value: number | undefined): Result<this> {\n const idResult = Ids.cellId(spec);\n return idResult.onSuccess((id) => {\n const notes: number[] = [];\n const update: ICellState = { id, value, notes };\n return this._puzzle.updateValues(update, this.state).onSuccess((update) => {\n this._addMove(update.cells);\n this.state = update.to;\n return succeed(this);\n });\n });\n }\n\n /**\n * Updates the notes on a cell.\n * @param spec - A `string`, {@link IRowColumn | row and column}, or {@link ICell | cell} identifying\n * the cell to be updated.\n * @param notes - New notes for the cell.\n * @returns `Success` with `this` if the update is applied, `Failure` with details if an error occurs.\n */\n public updateCellNotes(spec: string | IRowColumn | ICell, notes: number[]): Result<this> {\n const idResult = Ids.cellId(spec);\n return idResult.onSuccess((id) => {\n const value = undefined;\n const update: ICellState = { id, value, notes };\n return this._puzzle.updateNotes(update, this.state).onSuccess((update) => {\n this._addMove(update.cells);\n this.state = update.to;\n return succeed(this);\n });\n });\n }\n\n /**\n * Updates value & notes for multiple cells.\n * @param updates - An array of {@link ICellState | cell state} objects, each describing\n * one cell to be updated.\n * @returns `Success` with `this` if the updates are applied, `Failure` with details if\n * an error occurs.\n */\n public updateCells(updates: ICellState[]): Result<this> {\n return this._puzzle.updateContents(updates, this.state).onSuccess((update) => {\n this._addMove(update.cells);\n this.state = update.to;\n return succeed(this);\n });\n }\n\n /**\n * Determines if some {@link ICage | cage} contains a specific value.\n * @param spec - A `string` ({@link CageId | CageId}) or {@link ICage | ICage}\n * indicating the cage to be tested.\n * @param value - The value to be tested.\n * @returns `true` if the cage exists and contains the specified value,\n * `false` otherwise.\n */\n public cageContainsValue(spec: string | ICage, value: number): boolean {\n return this._cage(spec)?.containsValue(value, this.state) === true;\n }\n\n /**\n * Determines the numbers currently present in some cage.\n * @param spec - A `string` ({@link CageId | CageId}) or {@link ICage | ICage}\n * indicating the cage to be tested.\n * @returns A `Set<number>` containing all numbers present in the cage.\n */\n public cageContainedValues(spec: string | ICage): Set<number> {\n return this._cage(spec)?.containedValues(this.state) ?? new Set<number>();\n }\n\n /**\n * Undo a single move in this puzzle session.\n * @returns `Success` with `this` if the undo is applied, or `Failure`\n * with details if an error occurs.\n */\n public undo(): Result<this> {\n if (!this.canUndo) {\n return fail(`nothing to undo`);\n }\n\n return this._puzzle\n .updateContents(\n this._steps[this._nextStep - 1].updates.map((u) => u.from),\n this.state\n )\n .onSuccess((update) => {\n this._nextStep--;\n this.state = update.to;\n return succeed(this);\n });\n }\n\n /**\n * Redo a single move in this puzzle session.\n * @returns `Success` with `this` if the redo is applied, or `Failure`\n * with details if an error occurs.\n */\n public redo(): Result<this> {\n if (!this.canRedo) {\n return fail('nothing to redo');\n }\n return this._puzzle\n .updateContents(\n this._steps[this._nextStep].updates.map((u) => u.to),\n this.state\n )\n .onSuccess((update) => {\n this._nextStep++;\n this.state = update.to;\n return succeed(this);\n });\n }\n\n /**\n * Gets a string representation of this puzzle, one string\n * per row.\n */\n public toStrings(): string[] {\n return this._puzzle.toStrings(this.state);\n }\n\n private _addMove(updates: ICellUpdate[]): void {\n if (this._nextStep < this._steps.length) {\n this._steps[this._nextStep++] = { updates };\n } else {\n this._steps.push({ updates });\n this._nextStep = this._steps.length;\n }\n this._numSteps = this._nextStep;\n }\n\n private _cage(spec: string | ICage): Cage | undefined {\n if (spec instanceof Cage) {\n return spec;\n }\n return Ids.cageId(spec)\n .onSuccess((id) => {\n return this._puzzle.getCage(id);\n })\n .orDefault();\n }\n\n private _cell(spec: string | IRowColumn | ICell): Cell | undefined {\n if (spec instanceof Cell) {\n return spec;\n }\n return this._puzzle.getCell(spec as string | IRowColumn).orDefault();\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"puzzleState.d.ts","sourceRoot":"","sources":["../../../src/packlets/common/puzzleState.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,MAAM,EAAiB,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE7D;;GAEG;AACH,qBAAa,WAAW;IACtB;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAEtD;;OAEG;IACH,SAAS,aAAa,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,OAAO,CAAC,EAAE,UAAU,EAAE;IAK9E;;;;OAIG;WACW,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC;IAI9D;;;;;;OAMG;IACH,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE;IAW7E;;;;;OAKG;IACI,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,aAAa,CAAC;IAKzD;;;;;OAKG;IACI,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAMpC;;;;;;OAMG;IACI,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC;CAQ1D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"puzzleState.js","sourceRoot":"","sources":["../../../src/packlets/common/puzzleState.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;;AAEH,4CAAsD;AAGtD;;GAEG;AACH,MAAa,WAAW;IAMtB;;OAEG;IACH,YAAsB,IAAgC,EAAE,OAAsB;QAC5E,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;QACpF,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,MAAM,CAAC,KAAmB;QACtC,OAAO,IAAA,kBAAO,EAAC,IAAI,WAAW,CAAC,IAAI,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;IACpD,CAAC;IAED;;;;;;OAMG;IACO,MAAM,CAAC,UAAU,CAAC,MAAqB;QAC/C,yCAAyC;QACzC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YAC1B,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;YACnC,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACI,eAAe,CAAC,EAAU;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAA,eAAI,EAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAC7D,CAAC;IAED;;;;;OAKG;IACI,QAAQ,CAAC,EAAU;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACjC,oEAAoE;QACpE,OAAO,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,KAAK,MAAK,SAAS,CAAC;IACnC,CAAC;IAED;;;;;;OAMG;IACI,MAAM,CAAC,OAAqB;QACjC,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACtD,kFAAkF;QAClF,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAC3C,OAAO,IAAA,eAAI,EAAC,oBAAoB,CAAC,CAAC;QACpC,CAAC;QACD,OAAO,IAAA,kBAAO,EAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;CACF;AA/ED,kCA+EC;AACD,kFAAkF","sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2023 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Result, fail, succeed } from '@fgv/ts-utils';\nimport { CellId, ICellContents, ICellState } from './common';\n\n/**\n * @public\n */\nexport class PuzzleState {\n /**\n * @internal\n */\n protected readonly _cells: Map<CellId, ICellContents>;\n\n /**\n * @internal\n */\n protected constructor(from: Map<CellId, ICellContents>, updates?: ICellState[]) {\n const entries = [...Array.from(from.entries()), ...PuzzleState._toEntries(updates)];\n this._cells = new Map(entries);\n }\n\n /**\n * Constructs a new {@link PuzzleState | PuzzleState}.\n * @param cells - An array of {@link ICellState | CellState} used to initialize the state.\n * @returns The new {@link PuzzleState | PuzzleState}.\n */\n public static create(cells: ICellState[]): Result<PuzzleState> {\n return succeed(new PuzzleState(new Map(), cells));\n }\n\n /**\n * Convert {@link ICellContents | CellContents} to `[`{@link CellId | CellId}`,` {@link ICellContents | CellContents}`]`\n * tuple for `Map` construction.\n * @param states - An array of {@link ICellContents | CellContents} to be converted.\n * @returns The corresponding array of `[`{@link CellId | CellId}`,` {@link ICellContents | CellContents}`]`\n * @internal\n */\n protected static _toEntries(states?: ICellState[]): [CellId, ICellContents][] {\n /* c8 ignore next 3 - defense in depth */\n if (!states) {\n return [];\n }\n return states.map((state) => {\n const { id, value, notes } = state;\n return [id, { value, notes }];\n });\n }\n\n /**\n * Gets the contents of a cell specified by {@link CellId | id}.\n * @param id - The {@link CellId | id} of the cell to be retrieved.\n * @returns A {@link ICellContents | CellContents} with the contents of\n * the requested cell.\n */\n public getCellContents(id: CellId): Result<ICellContents> {\n const cell = this._cells.get(id);\n return cell ? succeed(cell) : fail(`cell ${id} not found`);\n }\n\n /**\n * Determines if some cell has an assigned value.\n * @param id - The {@link CellId | id} of the cell to be tested.\n * @returns `true` if the cell has a value, `false` if the cell\n * is empty or invalid.\n */\n public hasValue(id: CellId): boolean {\n const cell = this._cells.get(id);\n /* c8 ignore next 1 - defense in depth, tested but coverage fails */\n return cell?.value !== undefined;\n }\n\n /**\n * Creates a new {@link PuzzleState | PuzzleState} which corresponds\n * to this state with updates applied.\n * @param updates - An array of {@link ICellState | CellState} to be\n * applied.\n * @returns A new {@link PuzzleState} with updates applied.\n */\n public update(updates: ICellState[]): Result<PuzzleState> {\n const updated = new PuzzleState(this._cells, updates);\n /* c8 ignore next 3 - functional code tested but coverage intermittently missed */\n if (updated._cells.size > this._cells.size) {\n return fail(`update added cells`);\n }\n return succeed(updated);\n }\n}\n/* c8 ignore next 7 - functional code tested but coverage intermittently missed */\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"converters.d.ts","sourceRoot":"","sources":["../../../src/packlets/files/converters.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,SAAS,EAAc,MAAM,EAAW,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAC/E,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAI7C;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,CAAC,qBAAqB,CAM9D,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,CAAC,eAAe,CAYrD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,CAAC,YAAY,CAE9C,CAAC;AAEH;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC,iBAAiB,GAAG,MAAM,CAAC,YAAY,CAAC,CAEtF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"converters.js","sourceRoot":"","sources":["../../../src/packlets/files/converters.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;;AAqDH,0CAEC;AArDD,4CAAuE;AAIvE,sCAA2D;AAE3D;;;GAGG;AACU,QAAA,oBAAoB,GAC/B,qBAAU,CAAC,YAAY,CAAwB;IAC7C,gBAAgB,EAAE,qBAAU,CAAC,MAAM;IACnC,iBAAiB,EAAE,qBAAU,CAAC,MAAM;IACpC,iBAAiB,EAAE,qBAAU,CAAC,MAAM;IACpC,kBAAkB,EAAE,qBAAU,CAAC,MAAM;CACtC,CAAC,CAAC;AAEL;;;GAGG;AACU,QAAA,cAAc,GAA+B,qBAAU,CAAC,YAAY,CAC/E;IACE,EAAE,EAAE,qBAAU,CAAC,MAAM;IACrB,WAAW,EAAE,qBAAU,CAAC,MAAM;IAC9B,IAAI,EAAE,mBAAgB,CAAC,UAAU;IACjC,KAAK,EAAE,qBAAU,CAAC,MAAM;IACxB,KAAK,EAAE,qBAAU,CAAC,KAAK,CAAC,CAAC,qBAAU,CAAC,MAAM,EAAE,qBAAU,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,kBAAO,EAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACpG,UAAU,EAAE,4BAAoB;CACjC,EACD;IACE,cAAc,EAAE,CAAC,IAAI,CAAC;CACvB,CACF,CAAC;AAEF;;;GAGG;AACU,QAAA,WAAW,GAA4B,qBAAU,CAAC,YAAY,CAAe;IACxF,OAAO,EAAE,qBAAU,CAAC,OAAO,CAAC,sBAAc,CAAC;CAC5C,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,SAAgB,eAAe,CAAC,IAAgC;IAC9D,OAAO,IAAI,CAAC,WAAW,CAAC,mBAAW,CAAC,CAAC;AACvC,CAAC","sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2023 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Converter, Converters, Result, succeed } from '@fgv/ts-utils';\nimport { IPuzzlesFile, IPuzzleFileData, IPuzzleFileDimensions } from './model';\nimport { FileTree } from '@fgv/ts-json-base';\n\nimport { Converters as CommonConverters } from '../common';\n\n/**\n * Converts puzzle file dimensions from JSON format\n * @public\n */\nexport const puzzleFileDimensions: Converter<IPuzzleFileDimensions> =\n Converters.strictObject<IPuzzleFileDimensions>({\n cageWidthInCells: Converters.number,\n cageHeightInCells: Converters.number,\n boardWidthInCages: Converters.number,\n boardHeightInCages: Converters.number\n });\n\n/**\n * Converts puzzle file data from JSON format\n * @public\n */\nexport const puzzleFileData: Converter<IPuzzleFileData> = Converters.strictObject<IPuzzleFileData>(\n {\n id: Converters.string,\n description: Converters.string,\n type: CommonConverters.puzzleType,\n level: Converters.number,\n cells: Converters.oneOf([Converters.string, Converters.stringArray.map((s) => succeed(s.join('')))]),\n dimensions: puzzleFileDimensions\n },\n {\n optionalFields: ['id']\n }\n);\n\n/**\n * Converts an arbitrary object to a {@link Files.Model.IPuzzlesFile | IPuzzlesFile}.\n * @public\n */\nexport const puzzlesFile: Converter<IPuzzlesFile> = Converters.strictObject<IPuzzlesFile>({\n puzzles: Converters.arrayOf(puzzleFileData)\n});\n\n/**\n * Loads a puzzles file from a `IFileTreeFileItem`.\n * @param file - The `IFileTreeFileItem` to load.\n * @returns `Success` with the resulting {@link Files.Model.IPuzzlesFile | IPuzzlesFile}, or `Failure` with\n * details if an error occurs.\n * @public\n */\nexport function loadPuzzlesFile(file: FileTree.IFileTreeFileItem): Result<IPuzzlesFile> {\n return file.getContents(puzzlesFile);\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileTreeHelpers.d.ts","sourceRoot":"","sources":["../../../src/packlets/files/fileTreeHelpers.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,QAAQ,EAAY,MAAM,mBAAmB,CAAC;AAEvD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,CAE3G"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileTreeHelpers.js","sourceRoot":"","sources":["../../../src/packlets/files/fileTreeHelpers.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;AAeH,0DAEC;AAbD,6CAA2C;AAC3C,oDAAuD;AAEvD;;;;;;;GAOG;AACH,SAAgB,uBAAuB,CAAC,QAA2B,EAAE,QAAgB;IACnF,OAAO,uBAAQ,CAAC,qBAAqB,CAAC,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,EAAE,wBAAW,CAAC,CAAC;AAC7F,CAAC","sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Result } from '@fgv/ts-utils';\nimport { IPuzzlesFile } from './model';\nimport { puzzlesFile } from './converters';\nimport { FileTree, JsonFile } from '@fgv/ts-json-base';\n\n/**\n * Loads a puzzles file from a {@link FileTree.FileTree | FileTree}.\n * @param fileTree - FileTree containing the file\n * @param filePath - Path within the FileTree to the puzzles file\n * @returns `Success` with the resulting file, or `Failure` with details if an\n * error occurs.\n * @public\n */\nexport function loadJsonPuzzlesFromTree(fileTree: FileTree.FileTree, filePath: string): Result<IPuzzlesFile> {\n return JsonFile.DefaultJsonTreeHelper.convertJsonFromTree(fileTree, filePath, puzzlesFile);\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem.d.ts","sourceRoot":"","sources":["../../../src/packlets/files/filesystem.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAIvC;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,CAE1E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem.js","sourceRoot":"","sources":["../../../src/packlets/files/filesystem.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;AAeH,0DAEC;AAbD,6CAA2C;AAC3C,oDAA6C;AAE7C;;;;;;;GAOG;AACH,SAAgB,uBAAuB,CAAC,IAAY;IAClD,OAAO,uBAAQ,CAAC,mBAAmB,CAAC,IAAI,EAAE,wBAAW,CAAC,CAAC;AACzD,CAAC","sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Result } from '@fgv/ts-utils';\nimport { IPuzzlesFile } from './model';\nimport { puzzlesFile } from './converters';\nimport { JsonFile } from '@fgv/ts-json-base';\n\n/**\n * Loads an arbitrary JSON file and parses it to return a validated\n * {@link Files.Model.IPuzzlesFile | IPuzzlesFile}.\n * @param path - String path to the file\n * @returns `Success` with the resulting file, or `Failure` with details if an\n * error occurs.\n * @public\n */\nexport function loadJsonPuzzlesFileSync(path: string): Result<IPuzzlesFile> {\n return JsonFile.convertJsonFileSync(path, puzzlesFile);\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.browser.d.ts","sourceRoot":"","sources":["../../../src/packlets/files/index.browser.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AAEjC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AAG7B,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.browser.js","sourceRoot":"","sources":["../../../src/packlets/files/index.browser.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,kGAAkG;AAElG,yDAA2C;AAGlC,gCAAU;AAFnB,+CAAiC;AAEZ,sBAAK;AAE1B,gDAAgD;AAChD,qDAA4D;AAAnD,0HAAA,uBAAuB,OAAA;AAEhC,yBAAyB;AACzB,mFAAmF","sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n// Browser-safe files exports - includes FileTree functions, excludes Node.js filesystem functions\n\nimport * as Converters from './converters';\nimport * as Model from './model';\n\nexport { Converters, Model };\n\n// Re-export browser-compatible FileTree helpers\nexport { loadJsonPuzzlesFromTree } from './fileTreeHelpers';\n\n// Excluded from browser:\n// - loadJsonPuzzlesFileSync (requires Node.js fs via JsonFile.convertJsonFileSync)\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/packlets/files/index.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AAEjC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AAG7B,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/packlets/files/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,yDAA2C;AAGlC,gCAAU;AAFnB,+CAAiC;AAEZ,sBAAK;AAE1B,8CAA8C;AAC9C,2CAAuD;AAA9C,qHAAA,uBAAuB,OAAA;AAChC,qDAA4D;AAAnD,0HAAA,uBAAuB,OAAA","sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport * as Converters from './converters';\nimport * as Model from './model';\n\nexport { Converters, Model };\n\n// Export both filesystem and FileTree helpers\nexport { loadJsonPuzzlesFileSync } from './filesystem';\nexport { loadJsonPuzzlesFromTree } from './fileTreeHelpers';\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/packlets/files/model.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,qBAAqB,CAAC;CACnC;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/packlets/files/model.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG","sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2023 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { PuzzleType } from '../common';\n\n/**\n * Dimensional configuration for puzzles\n * @public\n */\nexport interface IPuzzleFileDimensions {\n cageWidthInCells: number;\n cageHeightInCells: number;\n boardWidthInCages: number;\n boardHeightInCages: number;\n}\n\n/**\n * Input format for puzzle data in JSON files.\n * Contains only the essential data needed to create an IPuzzleDefinition.\n * @public\n */\nexport interface IPuzzleFileData {\n id?: string;\n description: string;\n type: PuzzleType;\n level: number;\n cells: string;\n dimensions: IPuzzleFileDimensions;\n}\n\n/**\n * Parsed file containing a collection of puzzles.\n * @public\n */\nexport interface IPuzzlesFile {\n puzzles: IPuzzleFileData[];\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseHintProvider.d.ts","sourceRoot":"","sources":["../../../src/packlets/hints/baseHintProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseHintProvider.js","sourceRoot":"","sources":["../../../src/packlets/hints/baseHintProvider.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * MIT License\n *\n * Copyright (c) 2023 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Result, fail, succeed } from '@fgv/ts-utils';\nimport { CellId, Puzzle, PuzzleState } from '../common';\nimport { IHintProvider } from './interfaces';\nimport {\n ConfidenceLevel,\n ConfidenceLevels,\n DifficultyLevel,\n ExplanationLevel,\n ICellAction,\n IHint,\n IHintExplanation,\n IHintGenerationOptions,\n IRelevantCells,\n TechniqueId\n} from './types';\n\n/**\n * Configuration for a {@link Hints.BaseHintProvider | BaseHintProvider} instance.\n * @public\n */\nexport interface IBaseHintProviderConfig {\n readonly techniqueId: TechniqueId;\n readonly techniqueName: string;\n readonly difficulty: DifficultyLevel;\n readonly priority: number;\n readonly defaultConfidence?: ConfidenceLevel;\n}\n\n/**\n * Abstract base class providing common functionality for hint providers.\n * @public\n */\nexport abstract class BaseHintProvider implements IHintProvider {\n public readonly techniqueId: TechniqueId;\n public readonly techniqueName: string;\n public readonly difficulty: DifficultyLevel;\n public readonly priority: number;\n\n protected readonly defaultConfidence: ConfidenceLevel;\n\n protected constructor(config: IBaseHintProviderConfig) {\n this.techniqueId = config.techniqueId;\n this.techniqueName = config.techniqueName;\n this.difficulty = config.difficulty;\n this.priority = config.priority;\n this.defaultConfidence = config.defaultConfidence ?? ConfidenceLevels.MEDIUM;\n }\n\n /**\n * Abstract method to be implemented by concrete providers.\n * Determines if this provider can potentially generate hints for the given puzzle.\n */\n public abstract canProvideHints(puzzle: Puzzle, state: PuzzleState): boolean;\n\n /**\n * Abstract method to be implemented by concrete providers.\n * Generates all possible hints using this technique for the given puzzle.\n */\n public abstract generateHints(\n puzzle: Puzzle,\n state: PuzzleState,\n options?: IHintGenerationOptions\n ): Result<readonly IHint[]>;\n\n /**\n * Utility method to create a hint with consistent structure.\n * @param cellActions - The actions to be performed on cells\n * @param relevantCells - The cells relevant to understanding the hint\n * @param explanations - The explanations for the hint\n * @param confidence - The confidence level for this hint\n * @returns A complete hint object\n */\n protected createHint(\n cellActions: readonly ICellAction[],\n relevantCells: IRelevantCells,\n explanations: readonly IHintExplanation[],\n confidence?: ConfidenceLevel\n ): IHint {\n /* c8 ignore next 1 - defense in depth */\n confidence = confidence ?? this.defaultConfidence;\n return {\n techniqueId: this.techniqueId,\n techniqueName: this.techniqueName,\n difficulty: this.difficulty,\n confidence,\n cellActions,\n relevantCells,\n explanations,\n priority: this.priority\n };\n }\n\n /**\n * Utility method to create cell actions.\n * @param cellId - The ID of the cell to act upon\n * @param action - The type of action to perform\n * @param value - Optional value for set-value actions\n * @param reason - Optional reason for the action\n * @returns A cell action object\n */\n protected createCellAction(\n cellId: CellId,\n action: ICellAction['action'],\n value?: number,\n reason?: string\n ): ICellAction {\n return {\n cellId,\n action,\n value,\n reason\n };\n }\n\n /**\n * Utility method to create relevant cells grouping.\n * @param primary - Primary cells that are the focus of the hint\n * @param secondary - Secondary cells that provide context\n * @param affected - Cells that will be affected by applying the hint\n * @returns A relevant cells object\n */\n protected createRelevantCells(\n primary: readonly CellId[],\n secondary: readonly CellId[] = [],\n affected: readonly CellId[] = []\n ): IRelevantCells {\n return {\n primary,\n secondary,\n affected\n };\n }\n\n /**\n * Utility method to create hint explanations.\n * @param level - The level of detail for the explanation\n * @param title - The title of the explanation\n * @param description - The main description\n * @param steps - Optional step-by-step instructions\n * @param tips - Optional tips for understanding the technique\n * @returns A hint explanation object\n */\n protected createExplanation(\n level: ExplanationLevel,\n title: string,\n description: string,\n steps?: readonly string[],\n tips?: readonly string[]\n ): IHintExplanation {\n return {\n level,\n title,\n description,\n steps,\n tips\n };\n }\n\n /**\n * Filters hints based on generation options.\n * @param hints - The hints to filter\n * @param options - The filtering options\n * @returns Filtered array of hints\n */\n protected filterHints(hints: readonly IHint[], options?: IHintGenerationOptions): readonly IHint[] {\n if (!options) {\n return hints;\n }\n\n let filtered = [...hints];\n\n // Filter by minimum confidence\n if (options.minConfidence) {\n filtered = filtered.filter((hint) => hint.confidence >= options.minConfidence!);\n }\n\n // Filter by enabled techniques\n if (options.enabledTechniques && options.enabledTechniques.length > 0) {\n filtered = filtered.filter((hint) => options.enabledTechniques!.includes(hint.techniqueId));\n }\n\n // Limit number of hints\n if (options.maxHints && options.maxHints > 0) {\n // Sort by confidence (descending) then priority (ascending)\n filtered.sort((a, b) => {\n if (a.confidence !== b.confidence) {\n return b.confidence - a.confidence;\n }\n return a.priority - b.priority;\n });\n filtered = filtered.slice(0, options.maxHints);\n }\n\n return filtered;\n }\n\n /**\n * Validates generation options for consistency.\n * @param options - The options to validate\n * @returns Result indicating validation success or failure\n */\n protected validateOptions(options?: IHintGenerationOptions): Result<void> {\n if (!options) {\n return succeed(undefined);\n }\n\n if (options.maxHints !== undefined && options.maxHints < 0) {\n return fail('maxHints cannot be negative');\n }\n\n if (options.minConfidence !== undefined && (options.minConfidence < 1 || options.minConfidence > 5)) {\n return fail('minConfidence must be between 1 and 5');\n }\n\n return succeed(undefined);\n }\n\n /**\n * Gets all empty cells in the puzzle.\n * @param puzzle - The puzzle structure\n * @param state - The puzzle state to analyze\n * @returns Array of cell IDs that are empty\n */\n protected getEmptyCells(puzzle: Puzzle, state: PuzzleState): CellId[] {\n return puzzle.getEmptyCells(state).map((cell) => cell.id);\n }\n\n /**\n * Gets the possible candidate values for a specific cell using cage-based constraints.\n * This implementation works with any puzzle variant by checking all applicable cages.\n * @param cellId - The cell to analyze\n * @param puzzle - The puzzle structure containing constraints\n * @param state - The current puzzle state\n * @returns Array of possible values for the cell\n */\n protected getCandidates(cellId: CellId, puzzle: Puzzle, state: PuzzleState): number[] {\n if (state.hasValue(cellId)) {\n return [];\n }\n\n // Get maximum value based on grid size (typically sqrt of total cells)\n const maxValue = Math.sqrt(puzzle.numRows * puzzle.numColumns);\n\n // Find all cages that contain this cell\n const applicableCages = puzzle.cages.filter((cage) => cage.containsCell(cellId));\n\n // Collect all values that are forbidden due to cage constraints\n const usedValues = new Set<number>();\n\n for (const cage of applicableCages) {\n const cageValues = cage.containedValues(state);\n cageValues.forEach((value) => usedValues.add(value));\n }\n\n // Generate candidates (values not used in any applicable cage)\n const candidates: number[] = [];\n for (let value = 1; value <= maxValue; value++) {\n if (!usedValues.has(value)) {\n candidates.push(value);\n }\n }\n\n return candidates;\n }\n}\n"]}
|