@sudobility/sudojo_lib 0.0.131 → 0.0.133
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.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/hintExplanation.d.ts +2 -1
- package/dist/utils/hintExplanation.d.ts.map +1 -1
- package/dist/utils/hintExplanation.js +38 -8
- package/dist/utils/hintExplanation.js.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/localizedHint.d.ts +10 -1
- package/dist/utils/localizedHint.d.ts.map +1 -1
- package/dist/utils/localizedHint.js +11 -0
- package/dist/utils/localizedHint.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -342,7 +342,9 @@ export {
|
|
|
342
342
|
/** Get localized text for a hint step using a translation function. */
|
|
343
343
|
getLocalizedHintText,
|
|
344
344
|
/** Get localized title for a hint step using a translation function. */
|
|
345
|
-
getLocalizedHintTitle,
|
|
345
|
+
getLocalizedHintTitle,
|
|
346
|
+
/** Resolve a localized API field, falling back to the raw value. */
|
|
347
|
+
localizedField, } from './utils';
|
|
346
348
|
/** Internationalization key generation and localization utilities. */
|
|
347
349
|
export {
|
|
348
350
|
/** Get i18n key for a belt name (e.g., 'belts.1.name'). */
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -260,7 +260,9 @@ export {
|
|
|
260
260
|
/** Get localized text for a hint step using a translation function. */
|
|
261
261
|
getLocalizedHintText,
|
|
262
262
|
/** Get localized title for a hint step using a translation function. */
|
|
263
|
-
getLocalizedHintTitle,
|
|
263
|
+
getLocalizedHintTitle,
|
|
264
|
+
/** Resolve a localized API field, falling back to the raw value. */
|
|
265
|
+
localizedField, } from './utils';
|
|
264
266
|
// ============================================================================
|
|
265
267
|
// i18n Key Utilities
|
|
266
268
|
// ============================================================================
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @sudobility/sudojo_lib - Business logic library for Sudojo app\n *\n * This library provides:\n * - Game state management with useSudoku hook (ported from renderable)\n * - Board scrambling utilities\n * - Game validation (mistakes, completion)\n * - Level, technique, and learning data hooks\n * - Teaching/hint integration with solver\n * - Legacy useGame hook for backward compatibility\n *\n * ## Hook Architecture\n *\n * The hooks form a layered composition pattern:\n *\n * **Data hooks** (fetch and cache server data):\n * - `useLevels` / `useLevel` - Difficulty level data\n * - `useTechniques` / `useTechnique` - Solving technique data\n * - `useLearning` / `useLearningItem` - Learning material data\n *\n * **Game fetching hooks** (handle auth, subscription, and puzzle loading):\n * - `useLevelGame` - Fetch a random board for a specific level\n * - `useDailyGame` - Fetch today's daily puzzle\n *\n * **Game state hooks** (manage board state and user interaction):\n * - `useSudoku` - Primary game state (flat 81-cell array, modern API)\n * - `useGame` - Legacy game state (2D array, deprecated)\n * - `useBoardEntry` - Manual puzzle entry mode\n *\n * **Feature hooks** (provide specific game features):\n * - `useHint` - Solver integration for hints (matches Kotlin HintInteractor)\n * - `useGameTeaching` - Step-by-step teaching with solver\n * - `useGameTimer` - Elapsed time tracking via ref (no re-renders)\n * - `useGamePersistence` / `useAutoSave` - localStorage game save/restore\n * - `useLocalStorage` - Generic typed localStorage hook\n *\n * **Orchestration hooks** (combine multiple hooks for app-level features):\n * - `useGamePlay` - Current game management with Zustand store (daily/play slots)\n * - `useGameSession` - Server-side gamification (start/finish, points, badges)\n *\n * ## Migration Guide\n *\n * Legacy exports (prefixed with \"Legacy\" comments) use the 2D `GameBoard` type\n * from `useGame`. New code should use `useSudoku` with its flat 81-cell\n * `SudokuBoard` type. See `@deprecated` tags on legacy exports.\n */\n\n// ============================================================================\n// Legacy Types (useGame hook)\n// ============================================================================\n\n/**\n * @deprecated Use `SudokuCell` instead. Part of the legacy `useGame` 2D board API.\n */\nexport type {\n CellPosition,\n CellState,\n GameBoard,\n GameHint,\n GameMove,\n GameSettings,\n GameState,\n GameStatus,\n TeachingState,\n} from './types';\n\n/** @deprecated Use `DEFAULT_APP_SETTINGS` / `DEFAULT_PLAY_SETTINGS` instead. */\nexport { DEFAULT_GAME_SETTINGS } from './types';\n\n// ============================================================================\n// Sudoku Types (useSudoku hook - ported from renderable)\n// ============================================================================\n\n/** Core Sudoku cell and board types using flat 81-cell array representation. */\nexport type {\n /** A single cell in the Sudoku board (indexed 0-80). */\n SudokuCell,\n /** The Sudoku board containing all 81 cells. */\n SudokuBoard,\n /** Current play state including board, settings, and selection. */\n SudokuPlay,\n /** Session settings that can change during play (pencilmarking, auto-pencilmarks). */\n SudokuPlaySettings,\n /** App-level settings persisted across sessions (showErrors, display format). */\n SudokuAppSettings,\n /** Full game state including source, history, and digit mapping. */\n SudokuGameState,\n /** Display modes for Sudoku digits ('NUMERIC' | 'KANJI' | 'COLORS' | 'EMOJIS'). */\n SudokuDisplay,\n /** Source of the puzzle ('DAILY' | 'CHALLENGE' | 'LEVEL' | 'ENTERED'). */\n PlayingSource,\n} from './types';\n\n/** Default settings and cell/board helper functions for the modern Sudoku API. */\nexport {\n /** Default session play settings (pencilmarking off, auto-pencilmarks off). */\n DEFAULT_PLAY_SETTINGS,\n /** Default app settings (showErrors on, animations on, numeric display). */\n DEFAULT_APP_SETTINGS,\n /** Create an empty SudokuCell at the given index. */\n createEmptyCell,\n /** Create an empty 81-cell SudokuBoard. */\n createEmptyBoard,\n /** Check if a cell has an error (input does not match solution). */\n cellHasError,\n /** Get row index (0-8) from cell index (0-80). */\n rowOf,\n /** Get column index (0-8) from cell index (0-80). */\n columnOf,\n /** Get block index (0-8) from cell index (0-80). */\n blockOf,\n /** Get cell index (0-80) from row and column. */\n cellIndex,\n /** Get all cell indices in the same row as the given index. */\n getRowIndices,\n /** Get all cell indices in the same column as the given index. */\n getColumnIndices,\n /** Get all cell indices in the same block as the given index. */\n getBlockIndices,\n /** Get all related cell indices (same row, column, or block) excluding the cell itself. */\n getRelatedIndices,\n} from './types';\n\n// ============================================================================\n// Display types (for rendering - matches Kotlin renderable)\n// ============================================================================\n\n/** Display and hint visualization types matching the Kotlin renderable layer. */\nexport type {\n /** Highlighted area in a hint (row, column, or block). */\n HintArea,\n /** Cell display information in a hint step. */\n HintCell,\n /** Actions to perform on a cell during hint visualization. */\n HintCellActions,\n /** A single hint step with title, text, areas, cells, links, and groups. */\n DisplayHintStep,\n /** Complete display state for a single cell (colors, digit, pencilmarks). */\n CellDisplayState,\n /** Display state for a single pencilmark (digit and color). */\n PencilmarkDisplayState,\n /** UI color palette with system colors for light or dark mode. */\n UIColorPalette,\n /** Link type for chain visualization ('strong' | 'weak'). */\n LinkType,\n /** A link between two cells in a chain (display format). */\n DisplayLink,\n /** A group of cells for pattern visualization (display format). */\n DisplayCellGroup,\n} from './types';\n\n/** Theme and color enums plus predefined light/dark palettes. */\nexport { ThemeColor, SudokuColor, UIColorLight, UIColorDark } from './types';\n\n// ============================================================================\n// Progress Types (for user progress tracking)\n// ============================================================================\n\n/** Types for tracking user puzzle completion and statistics. */\nexport type {\n /** Record of a completed puzzle (id, type, time). */\n CompletedPuzzle,\n /** Computed game statistics (best times, averages). */\n GameStats,\n /** Full user progress data (completed puzzles, streak, stats). */\n UserProgress,\n} from './types';\n\nexport {\n /** Default empty user progress state. */\n DEFAULT_PROGRESS,\n /** localStorage key for progress data ('sudojo-progress'). */\n PROGRESS_STORAGE_KEY,\n} from './types';\n\n// ============================================================================\n// Settings Types (for app settings)\n// ============================================================================\n\n/** Types for application settings. */\nexport type {\n /** Digit display format ('numeric' | 'kanji' | 'emojis'). */\n DigitDisplay,\n /** Application settings (showErrors, symmetrical, display). */\n AppSettings,\n} from './types';\n\nexport {\n /** Default application settings. */\n DEFAULT_SETTINGS,\n /** localStorage key for settings ('sudojo-settings'). */\n SETTINGS_STORAGE_KEY,\n} from './types';\n\n// ============================================================================\n// Subscription Types (for subscription management)\n// ============================================================================\n\n/** Types for RevenueCat subscription management. */\nexport type {\n /** Subscription product information (price, period, trial). */\n Product,\n /** User subscription status (active, expiration, renewal). */\n Subscription,\n} from './types';\n\n/** Default inactive subscription state. */\nexport { DEFAULT_SUBSCRIPTION } from './types';\n\n// ============================================================================\n// Game Persistence Types (for saving/loading game state)\n// ============================================================================\n\n/** Types for saving and restoring game progress to localStorage. */\nexport type {\n /** Saved game state (input, pencilmarks, mode, timestamp). */\n SavedGameState,\n /** Key identifying a game to persist (type + id). */\n GamePersistenceKey,\n} from './types';\n\nexport {\n /** localStorage key prefix for game saves ('sudojo_game_'). */\n GAME_STORAGE_PREFIX,\n /** Generate a localStorage key from a GamePersistenceKey. */\n getGameStorageKey,\n} from './types';\n\n// ============================================================================\n// Current Game Types (for current game feature)\n// ============================================================================\n\n/** Types for the Zustand-backed current game store. */\nexport type {\n /** Source of the current game ('daily' | 'level' | 'entered'). */\n GameSource,\n /** Navigation metadata for resuming a game (date, level, board info). */\n CurrentGameMeta,\n /** Full current game state stored in Zustand (puzzle, progress, timing). */\n CurrentGame,\n /** Which store slot a game lives in ('daily' | 'play'). */\n GameSlot,\n} from './types';\n\n// ============================================================================\n// Legacy Utilities (useGame hook)\n// ============================================================================\n\n/**\n * @deprecated These utilities work with the legacy 2D `GameBoard` type.\n * For new code, use `useSudoku` with its flat 81-cell board and the\n * scrambler/presenter utilities below.\n */\nexport {\n /** @deprecated Clone a 2D GameBoard. Use useSudoku's immutable state instead. */\n cloneBoard,\n /** @deprecated Count filled cells in a 2D GameBoard. */\n countFilledCells,\n /** @deprecated Create a 2D GameBoard from puzzle/solution strings. */\n createGameBoard,\n /** @deprecated Get cells in a block by block index (2D API). */\n getBlockCells,\n /** @deprecated Get block index from row/col (2D API). Use blockOf() instead. */\n getBlockIndex,\n /** @deprecated Get 2D board state as string. Use cellsToStateString() instead. */\n getBoardStateString,\n /** @deprecated Get cells in a column (2D API). Use getColumnIndices() instead. */\n getColumnCells,\n /** @deprecated Get empty cells from a 2D GameBoard. */\n getEmptyCells,\n /** @deprecated Get pencilmarks string from 2D GameBoard. Use cellsToPencilmarksString() instead. */\n getPencilmarksString,\n /** @deprecated Get related cells (2D API). Use getRelatedIndices() instead. */\n getRelatedCells,\n /** @deprecated Get cells in a row (2D API). Use getRowIndices() instead. */\n getRowCells,\n /** @deprecated Check if placement is valid (2D API). */\n isValidPlacement,\n /** @deprecated Auto-remove pencilmarks (2D API). useSudoku handles this internally. */\n autoRemovePencilmarks,\n /** @deprecated Clear highlights (2D API). useSudoku handles this via presentBoard(). */\n clearHighlights,\n /** @deprecated Count mistakes (2D API). Use useSudoku's errorCount instead. */\n countMistakes,\n /** @deprecated Get incorrect cells (2D API). Use useSudoku's errorCells instead. */\n getIncorrectCells,\n /** @deprecated Get progress percentage (2D API). Use useSudoku's progress instead. */\n getProgressPercentage,\n /** @deprecated Check if board is filled (2D API). */\n isBoardFilled,\n /** @deprecated Check if cell is correct (2D API). Use cellHasError() instead. */\n isCellCorrect,\n /** @deprecated Check if game is complete (2D API). Use useSudoku's isCompleted instead. */\n isGameComplete,\n /** @deprecated Check if value is correct (2D API). */\n isValueCorrect,\n /** @deprecated Update cell errors (2D API). useSudoku handles this automatically. */\n updateCellErrors,\n /** @deprecated Update cell highlights (2D API). Use presentBoard() instead. */\n updateCellHighlights,\n /** @deprecated Validate entire game state (2D API). */\n validateGameState,\n} from './utils';\n\n// ============================================================================\n// Sudoku Utilities (useSudoku hook - ported from renderable)\n// ============================================================================\n\n/** Types for board scrambling. */\nexport type {\n /** Protocol for board scramblers (Scrambler and NonScrambler implement this). */\n ScramblerProtocol,\n /** Result of scrambling a board (cells + digit mappings). */\n SudokuScrambleResult,\n} from './utils';\n\n/** Board scrambling and puzzle string conversion utilities. */\nexport {\n /** Scrambler that permutes rows, columns, and digits to create unique puzzles. */\n Scrambler,\n /** Identity scrambler that returns the board unchanged. */\n NonScrambler,\n /** Scramble a board using a ScramblerProtocol implementation. */\n scrambleSudokuBoard,\n /** Parse an 81-character puzzle string into SudokuCell array. */\n parsePuzzleString,\n /** Convert SudokuCell array to puzzle string (given values only). */\n cellsToPuzzleString,\n /** Convert SudokuCell array to state string (given + input values). */\n cellsToStateString,\n /** Convert SudokuCell array to input-only string. */\n cellsToInputString,\n /** Convert SudokuCell array to comma-separated pencilmarks string. */\n cellsToPencilmarksString,\n} from './utils';\n\n// ============================================================================\n// Presenter utilities (for rendering - matches Kotlin renderable)\n// ============================================================================\n\n/** Options type for the presentBoard function. */\nexport type {\n /** Options for generating cell display states (cells, selection, errors, hints). */\n PresentBoardOptions,\n} from './utils';\n\n/** Board presentation and color utilities matching the Kotlin renderable layer. */\nexport {\n /** Generate display states for all 81 cells (colors, digits, pencilmarks, hints). */\n presentBoard,\n /** Process hint step areas and cells into a map of cell hints by index. */\n calculateCellHints,\n /** Convert a ThemeColor to an actual CSS color string using a palette. */\n themeColorToCSS,\n /** Get the UIColorPalette for light or dark mode. */\n getColorPalette,\n /** Get indices of cells containing a specific digit (given or input). */\n getCellsWithDigit,\n /** Get the digit to highlight based on the selected cell (given or correct input). */\n getSelectedDigit,\n /** Compute the set of cell indices with the same digit as the selected cell. */\n computeSelectedDigitCells,\n /** Convert a solver link (row/col pairs) to display format (flat indices). */\n convertSolverLink,\n /** Convert a solver cell group to display format with ThemeColor. */\n convertSolverCellGroup,\n /** Convert SudokuColor enum to ThemeColor enum. */\n sudokuColorToTheme,\n} from './utils';\n\n// ============================================================================\n// Time Utilities\n// ============================================================================\n\n/** Time formatting and parsing utilities. */\nexport {\n /** Format seconds into MM:SS or HH:MM:SS string. */\n formatTime,\n /** Parse a MM:SS or HH:MM:SS string back to total seconds. */\n parseTime,\n} from './utils';\n\n// ============================================================================\n// Progress Utilities\n// ============================================================================\n\n/** User progress calculation utilities. */\nexport {\n /** Calculate game statistics (best times, averages) from completed puzzles. */\n calculateStats,\n /** Calculate current daily streak from completion history. */\n calculateStreak,\n /** Check if a specific puzzle (by type and id) has been completed. */\n isPuzzleCompleted,\n /** Get all completed level IDs from completion history. */\n getCompletedLevelIds,\n /** Get all completed daily dates (YYYY-MM-DD) from completion history. */\n getCompletedDailyDates,\n} from './utils';\n\n// ============================================================================\n// Theme Utilities\n// ============================================================================\n\n/** Types for theme preference management. */\nexport type {\n /** Theme preference: 'light' | 'dark' | 'system'. */\n ThemePreference,\n /** Resolved theme without system option: 'light' | 'dark'. */\n ResolvedTheme,\n} from './utils';\n\n/** Theme detection and resolution utilities. */\nexport {\n /** localStorage key for theme preference ('sudojo-theme'). */\n THEME_STORAGE_KEY,\n /** Detect the system color scheme preference (light/dark). */\n getSystemTheme,\n /** Resolve a ThemePreference to an actual theme using the system theme. */\n resolveTheme,\n /** Type guard: check if a value is a valid ThemePreference. */\n isValidThemePreference,\n} from './utils';\n\n// ============================================================================\n// Subscription Utilities\n// ============================================================================\n\n/** RevenueCat subscription conversion and display utilities. */\nexport {\n /** Convert a RevenueCat package to a Product domain model. */\n convertPackageToProduct,\n /** Parse RevenueCat CustomerInfo into a Subscription domain model. */\n parseCustomerInfo,\n /** Get human-readable name for an ISO 8601 subscription period (e.g., 'P1M' -> 'Monthly'). */\n getPeriodDisplayName,\n /** Check if a subscription period is the \"best value\" option (annual plans). */\n isBestValuePlan,\n /** Get a user-friendly error message for a RevenueCat error code. */\n getRevenueCatErrorMessage,\n} from './utils';\n\n// ============================================================================\n// Technique Utilities\n// ============================================================================\n\n/** Technique display utilities. */\nexport {\n /** Get the icon URL for a solving technique by its path slug. */\n getTechniqueIconUrl,\n} from './utils';\n\n// ============================================================================\n// Hint Explanation Utilities\n// ============================================================================\n\n/** Hint explanation generation utilities for teaching users solving techniques. */\nexport {\n /** Generate a detailed explanation for a hint step based on the technique. */\n generateDetailedExplanation,\n /** Get a short action summary for a hint step (e.g., 'Place 5 in R1C3'). */\n getHintActionSummary,\n} from './utils';\n\n// ============================================================================\n// Localized Hint Utilities\n// ============================================================================\n\n/** Types for hint text localization. */\nexport type {\n /** Translation function compatible with i18next's `t` function. */\n TranslateFunction,\n} from './utils';\n\n/** Hint localization utilities. */\nexport {\n /** Get localized text for a hint step using a translation function. */\n getLocalizedHintText,\n /** Get localized title for a hint step using a translation function. */\n getLocalizedHintTitle,\n} from './utils';\n\n// ============================================================================\n// i18n Key Utilities\n// ============================================================================\n\n/** Internationalization key generation and localization utilities. */\nexport {\n /** Get i18n key for a belt name (e.g., 'belts.1.name'). */\n getBeltKey,\n /** Get localized belt name using a translation function. */\n getLocalizedBeltName,\n /** Get i18n key for a belt label (e.g., 'belts.1.label'). */\n getBeltLabelKey,\n /** Get localized belt label (e.g., 'White Belt'). */\n getLocalizedBeltLabel,\n /** Get i18n key for a level title (e.g., 'levels.3'). */\n getLevelKey,\n /** Get localized level title using a translation function. */\n getLocalizedLevelTitle,\n /** Get i18n key for a technique name (e.g., 'techniques.full-house.title'). */\n getTechniqueKey,\n /** Get localized technique name using a translation function. */\n getLocalizedTechniqueName,\n} from './utils';\n\n// ============================================================================\n// Digit Display Utilities\n// ============================================================================\n\n/** Digit display format conversion. */\nexport {\n /** Convert a digit (1-9) to its display string based on the format (numeric, kanji, emojis). */\n displayDigit,\n} from './utils';\n\n// ============================================================================\n// Share URL Utilities\n// ============================================================================\n\n/** Types for share URL building and parsing. */\nexport type { ShareUrlParams, ParsedShareParams } from './utils';\n\n/** Build a share URL from game state. */\nexport { buildShareUrl } from './utils';\n\n/** Parse share URL query parameters into game state. */\nexport { parseShareParams } from './utils';\n\n/** Derive web app URL from API base URL. */\nexport { getWebUrl } from './utils';\n\n// ============================================================================\n// Auth Utilities\n// ============================================================================\n\n/** Minimal user shape for auth checks. */\nexport type { AuthUser } from './utils';\n\n/** Check if user-specific API calls should be enabled (non-anonymous, has token). */\nexport { isAuthenticatedUser } from './utils';\n\n// ============================================================================\n// Hooks\n// ============================================================================\n\nexport {\n // Data hooks\n /** Fetch a single difficulty level by number. */\n useLevel,\n /** Fetch all difficulty levels with sorting and filtering utilities. */\n useLevels,\n /** Fetch a single solving technique by number. */\n useTechnique,\n /** Fetch all solving techniques with grouping utilities. */\n useTechniques,\n /** Fetch learning materials with filtering by technique and language. */\n useLearning,\n /** Fetch a single learning item by UUID. */\n useLearningItem,\n\n /**\n * @deprecated Use `useSudoku` instead. `useGame` uses a legacy 2D array board\n * representation, while `useSudoku` uses a flat 81-cell array consistent with\n * the Kotlin renderable layer and the rest of the codebase.\n */\n useGame,\n\n /** Primary game state hook with flat 81-cell board, pencil mode, and scrambling. */\n useSudoku,\n\n /** Teaching/hint integration with the solver API (legacy GameHint format). */\n useGameTeaching,\n\n /** Fetch a random board for a specific level with auth/subscription handling. */\n useLevelGame,\n /** Fetch today's daily puzzle with auth/subscription handling. */\n useDailyGame,\n\n /** Game timer using refs to avoid re-renders every second. */\n useGameTimer,\n\n /** Persist individual game progress to localStorage. */\n useGamePersistence,\n /** Auto-save game state with debouncing. */\n useAutoSave,\n\n /** Generic typed localStorage hook with SSR safety. */\n useLocalStorage,\n\n /** Solver hint integration matching Kotlin HintInteractor behavior. */\n useHint,\n\n /** Current game management with Zustand store (daily/play slots). */\n useGamePlay,\n\n /** Manual puzzle entry mode with solver validation. */\n useBoardEntry,\n\n /** Server-side game session management for gamification (points, badges). */\n useGameSession,\n\n /** Check whether a level is enabled for the current user's entitlements. */\n useLevelEnabled,\n /** Check whether a technique is enabled for the current user's entitlements. */\n useTechniqueEnabled,\n\n /** Convert internal user level (0-indexed) to display values (1-indexed + belt). */\n useDisplayLevel,\n\n /** Compute cumulative puzzle distribution across entitlement tiers. */\n usePuzzleDistribution,\n\n /** Shared hint step tracker for game screens (ref + state). */\n useHintStepTracker,\n\n /** Auto-hint orchestration for shared links/deep links. */\n useAutoHint,\n\n /** Progress reporting for game state persistence. */\n useProgressReporter,\n\n /** Emit a hint action event to the active SudokuGame. */\n emitHintAction,\n /** Report hint status back after processing an action. */\n reportHintStatus,\n /** Subscribe to hint status updates. */\n onHintStatus,\n /** Hook for SudokuGame to listen for external hint action events. */\n useHintActionListener,\n} from './hooks';\n\nexport type {\n // Data hook types\n /** Options for useLevel hook. */\n UseLevelOptions,\n /** Result type for useLevel hook. */\n UseLevelResult,\n /** Options for useLevels hook. */\n UseLevelsOptions,\n /** Result type for useLevels hook. */\n UseLevelsResult,\n /** Options for useTechnique hook. */\n UseTechniqueOptions,\n /** Result type for useTechnique hook. */\n UseTechniqueResult,\n /** Options for useTechniques hook. */\n UseTechniquesOptions,\n /** Result type for useTechniques hook. */\n UseTechniquesResult,\n /** Options for useLearningItem hook. */\n UseLearningItemOptions,\n /** Result type for useLearningItem hook. */\n UseLearningItemResult,\n /** Options for useLearning hook. */\n UseLearningOptions,\n /** Result type for useLearning hook. */\n UseLearningResult,\n\n // Game hook types (legacy)\n /** @deprecated Options for legacy useGame hook. Use UseSudokuOptions instead. */\n UseGameOptions,\n /** @deprecated Result type for legacy useGame hook. Use UseSudokuResult instead. */\n UseGameResult,\n\n // Sudoku hook types\n /** Options for useSudoku hook (initial app settings). */\n UseSudokuOptions,\n /** Result type for useSudoku hook (state, computed values, actions, utilities). */\n UseSudokuResult,\n\n // Teaching hook types\n /** Options for useGameTeaching hook (network client, URL, token). */\n UseGameTeachingOptions,\n /** Result type for useGameTeaching hook (teaching state, hint actions). */\n UseGameTeachingResult,\n\n // Game fetching hook types\n /** Options for useLevelGame hook (network, auth, level number). */\n UseLevelGameOptions,\n /** Result type for useLevelGame hook (board data, fetch status). */\n UseLevelGameResult,\n /** Options for useDailyGame hook (network, auth). */\n UseDailyGameOptions,\n /** Result type for useDailyGame hook (daily data, fetch status). */\n UseDailyGameResult,\n /** Status of a game fetch: 'loading' | 'success' | 'auth_required' | 'subscription_required' | 'entitlement_required' | 'error'. */\n GameFetchStatus,\n\n // Timer hook types\n /** Options for useGameTimer hook (autoStart, initialTime). */\n UseGameTimerOptions,\n /** Result type for useGameTimer hook (elapsedRef, controls). */\n UseGameTimerResult,\n\n // Persistence hook types\n /** Options for useGamePersistence hook (puzzleKey, autoSave). */\n UseGamePersistenceOptions,\n /** Result type for useGamePersistence hook (load, save, clear, hasSaved). */\n UseGamePersistenceResult,\n\n // Hint hook types\n /** Options for useHint hook (network, puzzle state, technique filter). */\n UseHintOptions,\n /** Result type for useHint hook (hint steps, navigation, apply). */\n UseHintResult,\n /** Board data returned when applying a hint (user input, pencilmarks). */\n HintBoardData,\n /** Data passed to onHintReceived callback (hint, board data, technique info). */\n HintReceivedData,\n /** Access denied error info when hint level exceeds subscription tier. */\n HintAccessError,\n\n // Game play hook types\n /** Options for useGamePlay hook (slot selection, auto-save delay). */\n UseGamePlayOptions,\n /** Result type for useGamePlay hook (current game, start, update, clear). */\n UseGamePlayResult,\n\n // Board entry hook types\n /** Options for useBoardEntry hook (network client, URL, token). */\n UseBoardEntryOptions,\n /** Result type for useBoardEntry hook (cells, validation, actions). */\n UseBoardEntryReturn,\n /** Validated puzzle data from solver (puzzle + solution strings). */\n ValidatedPuzzle,\n\n // Game session hook types\n /** Options for useGameSession hook (network, auth, userId). */\n UseGameSessionOptions,\n /** Result of starting a game session (sessionStarted, sessionId). */\n GameSessionResult,\n /** Result of finishing a game session (leveledUp, badges, points). */\n GameFinishResult,\n\n // Display level hook types\n /** Result type for useDisplayLevel hook. */\n UseDisplayLevelResult,\n\n // Hint step tracker types\n /** Result type for useHintStepTracker hook. */\n UseHintStepTrackerResult,\n\n // Auto-hint types\n /** Options for useAutoHint hook. */\n UseAutoHintOptions,\n\n // Progress reporter types\n /** Options for useProgressReporter hook. */\n UseProgressReporterOptions,\n /** Callback type for progress updates. */\n ProgressUpdateCallback,\n\n // Hint action types\n /** Status reported after a hint action is processed. */\n HintActionStatus,\n} from './hooks';\n\n// ============================================================================\n// Stores\n// ============================================================================\n\n/** Zustand store for current game state with daily/play slots and localStorage persistence. */\nexport { useGamePlayStore } from './stores/gamePlayStore';\n/** State shape for the game play Zustand store. */\nexport type { GamePlayState } from './stores/gamePlayStore';\n\n// ============================================================================\n// Config\n// ============================================================================\n\n/** Authentication provider configuration types. */\nexport type {\n /** Available auth provider types: 'google' | 'apple' | 'email'. */\n AuthProviderType,\n /** Configuration for which auth providers are enabled. */\n AuthProvidersConfig,\n} from './config';\n\n/** Default auth providers configuration (Google + Email, anonymous fallback). */\nexport { DEFAULT_AUTH_PROVIDERS } from './config';\n\n// ============================================================================\n// Entitlement Context\n// ============================================================================\n\n/** Provider that supplies entitlements to useLevelEnabled / useTechniqueEnabled. */\nexport { EntitlementProvider } from './context';\n/** React context for entitlements (for advanced use). */\nexport { EntitlementContext, useEntitlementContext } from './context';\n\n// ============================================================================\n// Entitlement Utilities (re-exported from sudojo_types)\n// ============================================================================\n\n/** Parse a comma-delimited entitlement string into an array. */\nexport { parseEntitlements } from '@sudobility/sudojo_types';\n\n/** Check if a user has the required entitlement for a level. */\nexport { hasRequiredEntitlement } from '@sudobility/sudojo_types';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @sudobility/sudojo_lib - Business logic library for Sudojo app\n *\n * This library provides:\n * - Game state management with useSudoku hook (ported from renderable)\n * - Board scrambling utilities\n * - Game validation (mistakes, completion)\n * - Level, technique, and learning data hooks\n * - Teaching/hint integration with solver\n * - Legacy useGame hook for backward compatibility\n *\n * ## Hook Architecture\n *\n * The hooks form a layered composition pattern:\n *\n * **Data hooks** (fetch and cache server data):\n * - `useLevels` / `useLevel` - Difficulty level data\n * - `useTechniques` / `useTechnique` - Solving technique data\n * - `useLearning` / `useLearningItem` - Learning material data\n *\n * **Game fetching hooks** (handle auth, subscription, and puzzle loading):\n * - `useLevelGame` - Fetch a random board for a specific level\n * - `useDailyGame` - Fetch today's daily puzzle\n *\n * **Game state hooks** (manage board state and user interaction):\n * - `useSudoku` - Primary game state (flat 81-cell array, modern API)\n * - `useGame` - Legacy game state (2D array, deprecated)\n * - `useBoardEntry` - Manual puzzle entry mode\n *\n * **Feature hooks** (provide specific game features):\n * - `useHint` - Solver integration for hints (matches Kotlin HintInteractor)\n * - `useGameTeaching` - Step-by-step teaching with solver\n * - `useGameTimer` - Elapsed time tracking via ref (no re-renders)\n * - `useGamePersistence` / `useAutoSave` - localStorage game save/restore\n * - `useLocalStorage` - Generic typed localStorage hook\n *\n * **Orchestration hooks** (combine multiple hooks for app-level features):\n * - `useGamePlay` - Current game management with Zustand store (daily/play slots)\n * - `useGameSession` - Server-side gamification (start/finish, points, badges)\n *\n * ## Migration Guide\n *\n * Legacy exports (prefixed with \"Legacy\" comments) use the 2D `GameBoard` type\n * from `useGame`. New code should use `useSudoku` with its flat 81-cell\n * `SudokuBoard` type. See `@deprecated` tags on legacy exports.\n */\n\n// ============================================================================\n// Legacy Types (useGame hook)\n// ============================================================================\n\n/**\n * @deprecated Use `SudokuCell` instead. Part of the legacy `useGame` 2D board API.\n */\nexport type {\n CellPosition,\n CellState,\n GameBoard,\n GameHint,\n GameMove,\n GameSettings,\n GameState,\n GameStatus,\n TeachingState,\n} from './types';\n\n/** @deprecated Use `DEFAULT_APP_SETTINGS` / `DEFAULT_PLAY_SETTINGS` instead. */\nexport { DEFAULT_GAME_SETTINGS } from './types';\n\n// ============================================================================\n// Sudoku Types (useSudoku hook - ported from renderable)\n// ============================================================================\n\n/** Core Sudoku cell and board types using flat 81-cell array representation. */\nexport type {\n /** A single cell in the Sudoku board (indexed 0-80). */\n SudokuCell,\n /** The Sudoku board containing all 81 cells. */\n SudokuBoard,\n /** Current play state including board, settings, and selection. */\n SudokuPlay,\n /** Session settings that can change during play (pencilmarking, auto-pencilmarks). */\n SudokuPlaySettings,\n /** App-level settings persisted across sessions (showErrors, display format). */\n SudokuAppSettings,\n /** Full game state including source, history, and digit mapping. */\n SudokuGameState,\n /** Display modes for Sudoku digits ('NUMERIC' | 'KANJI' | 'COLORS' | 'EMOJIS'). */\n SudokuDisplay,\n /** Source of the puzzle ('DAILY' | 'CHALLENGE' | 'LEVEL' | 'ENTERED'). */\n PlayingSource,\n} from './types';\n\n/** Default settings and cell/board helper functions for the modern Sudoku API. */\nexport {\n /** Default session play settings (pencilmarking off, auto-pencilmarks off). */\n DEFAULT_PLAY_SETTINGS,\n /** Default app settings (showErrors on, animations on, numeric display). */\n DEFAULT_APP_SETTINGS,\n /** Create an empty SudokuCell at the given index. */\n createEmptyCell,\n /** Create an empty 81-cell SudokuBoard. */\n createEmptyBoard,\n /** Check if a cell has an error (input does not match solution). */\n cellHasError,\n /** Get row index (0-8) from cell index (0-80). */\n rowOf,\n /** Get column index (0-8) from cell index (0-80). */\n columnOf,\n /** Get block index (0-8) from cell index (0-80). */\n blockOf,\n /** Get cell index (0-80) from row and column. */\n cellIndex,\n /** Get all cell indices in the same row as the given index. */\n getRowIndices,\n /** Get all cell indices in the same column as the given index. */\n getColumnIndices,\n /** Get all cell indices in the same block as the given index. */\n getBlockIndices,\n /** Get all related cell indices (same row, column, or block) excluding the cell itself. */\n getRelatedIndices,\n} from './types';\n\n// ============================================================================\n// Display types (for rendering - matches Kotlin renderable)\n// ============================================================================\n\n/** Display and hint visualization types matching the Kotlin renderable layer. */\nexport type {\n /** Highlighted area in a hint (row, column, or block). */\n HintArea,\n /** Cell display information in a hint step. */\n HintCell,\n /** Actions to perform on a cell during hint visualization. */\n HintCellActions,\n /** A single hint step with title, text, areas, cells, links, and groups. */\n DisplayHintStep,\n /** Complete display state for a single cell (colors, digit, pencilmarks). */\n CellDisplayState,\n /** Display state for a single pencilmark (digit and color). */\n PencilmarkDisplayState,\n /** UI color palette with system colors for light or dark mode. */\n UIColorPalette,\n /** Link type for chain visualization ('strong' | 'weak'). */\n LinkType,\n /** A link between two cells in a chain (display format). */\n DisplayLink,\n /** A group of cells for pattern visualization (display format). */\n DisplayCellGroup,\n} from './types';\n\n/** Theme and color enums plus predefined light/dark palettes. */\nexport { ThemeColor, SudokuColor, UIColorLight, UIColorDark } from './types';\n\n// ============================================================================\n// Progress Types (for user progress tracking)\n// ============================================================================\n\n/** Types for tracking user puzzle completion and statistics. */\nexport type {\n /** Record of a completed puzzle (id, type, time). */\n CompletedPuzzle,\n /** Computed game statistics (best times, averages). */\n GameStats,\n /** Full user progress data (completed puzzles, streak, stats). */\n UserProgress,\n} from './types';\n\nexport {\n /** Default empty user progress state. */\n DEFAULT_PROGRESS,\n /** localStorage key for progress data ('sudojo-progress'). */\n PROGRESS_STORAGE_KEY,\n} from './types';\n\n// ============================================================================\n// Settings Types (for app settings)\n// ============================================================================\n\n/** Types for application settings. */\nexport type {\n /** Digit display format ('numeric' | 'kanji' | 'emojis'). */\n DigitDisplay,\n /** Application settings (showErrors, symmetrical, display). */\n AppSettings,\n} from './types';\n\nexport {\n /** Default application settings. */\n DEFAULT_SETTINGS,\n /** localStorage key for settings ('sudojo-settings'). */\n SETTINGS_STORAGE_KEY,\n} from './types';\n\n// ============================================================================\n// Subscription Types (for subscription management)\n// ============================================================================\n\n/** Types for RevenueCat subscription management. */\nexport type {\n /** Subscription product information (price, period, trial). */\n Product,\n /** User subscription status (active, expiration, renewal). */\n Subscription,\n} from './types';\n\n/** Default inactive subscription state. */\nexport { DEFAULT_SUBSCRIPTION } from './types';\n\n// ============================================================================\n// Game Persistence Types (for saving/loading game state)\n// ============================================================================\n\n/** Types for saving and restoring game progress to localStorage. */\nexport type {\n /** Saved game state (input, pencilmarks, mode, timestamp). */\n SavedGameState,\n /** Key identifying a game to persist (type + id). */\n GamePersistenceKey,\n} from './types';\n\nexport {\n /** localStorage key prefix for game saves ('sudojo_game_'). */\n GAME_STORAGE_PREFIX,\n /** Generate a localStorage key from a GamePersistenceKey. */\n getGameStorageKey,\n} from './types';\n\n// ============================================================================\n// Current Game Types (for current game feature)\n// ============================================================================\n\n/** Types for the Zustand-backed current game store. */\nexport type {\n /** Source of the current game ('daily' | 'level' | 'entered'). */\n GameSource,\n /** Navigation metadata for resuming a game (date, level, board info). */\n CurrentGameMeta,\n /** Full current game state stored in Zustand (puzzle, progress, timing). */\n CurrentGame,\n /** Which store slot a game lives in ('daily' | 'play'). */\n GameSlot,\n} from './types';\n\n// ============================================================================\n// Legacy Utilities (useGame hook)\n// ============================================================================\n\n/**\n * @deprecated These utilities work with the legacy 2D `GameBoard` type.\n * For new code, use `useSudoku` with its flat 81-cell board and the\n * scrambler/presenter utilities below.\n */\nexport {\n /** @deprecated Clone a 2D GameBoard. Use useSudoku's immutable state instead. */\n cloneBoard,\n /** @deprecated Count filled cells in a 2D GameBoard. */\n countFilledCells,\n /** @deprecated Create a 2D GameBoard from puzzle/solution strings. */\n createGameBoard,\n /** @deprecated Get cells in a block by block index (2D API). */\n getBlockCells,\n /** @deprecated Get block index from row/col (2D API). Use blockOf() instead. */\n getBlockIndex,\n /** @deprecated Get 2D board state as string. Use cellsToStateString() instead. */\n getBoardStateString,\n /** @deprecated Get cells in a column (2D API). Use getColumnIndices() instead. */\n getColumnCells,\n /** @deprecated Get empty cells from a 2D GameBoard. */\n getEmptyCells,\n /** @deprecated Get pencilmarks string from 2D GameBoard. Use cellsToPencilmarksString() instead. */\n getPencilmarksString,\n /** @deprecated Get related cells (2D API). Use getRelatedIndices() instead. */\n getRelatedCells,\n /** @deprecated Get cells in a row (2D API). Use getRowIndices() instead. */\n getRowCells,\n /** @deprecated Check if placement is valid (2D API). */\n isValidPlacement,\n /** @deprecated Auto-remove pencilmarks (2D API). useSudoku handles this internally. */\n autoRemovePencilmarks,\n /** @deprecated Clear highlights (2D API). useSudoku handles this via presentBoard(). */\n clearHighlights,\n /** @deprecated Count mistakes (2D API). Use useSudoku's errorCount instead. */\n countMistakes,\n /** @deprecated Get incorrect cells (2D API). Use useSudoku's errorCells instead. */\n getIncorrectCells,\n /** @deprecated Get progress percentage (2D API). Use useSudoku's progress instead. */\n getProgressPercentage,\n /** @deprecated Check if board is filled (2D API). */\n isBoardFilled,\n /** @deprecated Check if cell is correct (2D API). Use cellHasError() instead. */\n isCellCorrect,\n /** @deprecated Check if game is complete (2D API). Use useSudoku's isCompleted instead. */\n isGameComplete,\n /** @deprecated Check if value is correct (2D API). */\n isValueCorrect,\n /** @deprecated Update cell errors (2D API). useSudoku handles this automatically. */\n updateCellErrors,\n /** @deprecated Update cell highlights (2D API). Use presentBoard() instead. */\n updateCellHighlights,\n /** @deprecated Validate entire game state (2D API). */\n validateGameState,\n} from './utils';\n\n// ============================================================================\n// Sudoku Utilities (useSudoku hook - ported from renderable)\n// ============================================================================\n\n/** Types for board scrambling. */\nexport type {\n /** Protocol for board scramblers (Scrambler and NonScrambler implement this). */\n ScramblerProtocol,\n /** Result of scrambling a board (cells + digit mappings). */\n SudokuScrambleResult,\n} from './utils';\n\n/** Board scrambling and puzzle string conversion utilities. */\nexport {\n /** Scrambler that permutes rows, columns, and digits to create unique puzzles. */\n Scrambler,\n /** Identity scrambler that returns the board unchanged. */\n NonScrambler,\n /** Scramble a board using a ScramblerProtocol implementation. */\n scrambleSudokuBoard,\n /** Parse an 81-character puzzle string into SudokuCell array. */\n parsePuzzleString,\n /** Convert SudokuCell array to puzzle string (given values only). */\n cellsToPuzzleString,\n /** Convert SudokuCell array to state string (given + input values). */\n cellsToStateString,\n /** Convert SudokuCell array to input-only string. */\n cellsToInputString,\n /** Convert SudokuCell array to comma-separated pencilmarks string. */\n cellsToPencilmarksString,\n} from './utils';\n\n// ============================================================================\n// Presenter utilities (for rendering - matches Kotlin renderable)\n// ============================================================================\n\n/** Options type for the presentBoard function. */\nexport type {\n /** Options for generating cell display states (cells, selection, errors, hints). */\n PresentBoardOptions,\n} from './utils';\n\n/** Board presentation and color utilities matching the Kotlin renderable layer. */\nexport {\n /** Generate display states for all 81 cells (colors, digits, pencilmarks, hints). */\n presentBoard,\n /** Process hint step areas and cells into a map of cell hints by index. */\n calculateCellHints,\n /** Convert a ThemeColor to an actual CSS color string using a palette. */\n themeColorToCSS,\n /** Get the UIColorPalette for light or dark mode. */\n getColorPalette,\n /** Get indices of cells containing a specific digit (given or input). */\n getCellsWithDigit,\n /** Get the digit to highlight based on the selected cell (given or correct input). */\n getSelectedDigit,\n /** Compute the set of cell indices with the same digit as the selected cell. */\n computeSelectedDigitCells,\n /** Convert a solver link (row/col pairs) to display format (flat indices). */\n convertSolverLink,\n /** Convert a solver cell group to display format with ThemeColor. */\n convertSolverCellGroup,\n /** Convert SudokuColor enum to ThemeColor enum. */\n sudokuColorToTheme,\n} from './utils';\n\n// ============================================================================\n// Time Utilities\n// ============================================================================\n\n/** Time formatting and parsing utilities. */\nexport {\n /** Format seconds into MM:SS or HH:MM:SS string. */\n formatTime,\n /** Parse a MM:SS or HH:MM:SS string back to total seconds. */\n parseTime,\n} from './utils';\n\n// ============================================================================\n// Progress Utilities\n// ============================================================================\n\n/** User progress calculation utilities. */\nexport {\n /** Calculate game statistics (best times, averages) from completed puzzles. */\n calculateStats,\n /** Calculate current daily streak from completion history. */\n calculateStreak,\n /** Check if a specific puzzle (by type and id) has been completed. */\n isPuzzleCompleted,\n /** Get all completed level IDs from completion history. */\n getCompletedLevelIds,\n /** Get all completed daily dates (YYYY-MM-DD) from completion history. */\n getCompletedDailyDates,\n} from './utils';\n\n// ============================================================================\n// Theme Utilities\n// ============================================================================\n\n/** Types for theme preference management. */\nexport type {\n /** Theme preference: 'light' | 'dark' | 'system'. */\n ThemePreference,\n /** Resolved theme without system option: 'light' | 'dark'. */\n ResolvedTheme,\n} from './utils';\n\n/** Theme detection and resolution utilities. */\nexport {\n /** localStorage key for theme preference ('sudojo-theme'). */\n THEME_STORAGE_KEY,\n /** Detect the system color scheme preference (light/dark). */\n getSystemTheme,\n /** Resolve a ThemePreference to an actual theme using the system theme. */\n resolveTheme,\n /** Type guard: check if a value is a valid ThemePreference. */\n isValidThemePreference,\n} from './utils';\n\n// ============================================================================\n// Subscription Utilities\n// ============================================================================\n\n/** RevenueCat subscription conversion and display utilities. */\nexport {\n /** Convert a RevenueCat package to a Product domain model. */\n convertPackageToProduct,\n /** Parse RevenueCat CustomerInfo into a Subscription domain model. */\n parseCustomerInfo,\n /** Get human-readable name for an ISO 8601 subscription period (e.g., 'P1M' -> 'Monthly'). */\n getPeriodDisplayName,\n /** Check if a subscription period is the \"best value\" option (annual plans). */\n isBestValuePlan,\n /** Get a user-friendly error message for a RevenueCat error code. */\n getRevenueCatErrorMessage,\n} from './utils';\n\n// ============================================================================\n// Technique Utilities\n// ============================================================================\n\n/** Technique display utilities. */\nexport {\n /** Get the icon URL for a solving technique by its path slug. */\n getTechniqueIconUrl,\n} from './utils';\n\n// ============================================================================\n// Hint Explanation Utilities\n// ============================================================================\n\n/** Hint explanation generation utilities for teaching users solving techniques. */\nexport {\n /** Generate a detailed explanation for a hint step based on the technique. */\n generateDetailedExplanation,\n /** Get a short action summary for a hint step (e.g., 'Place 5 in R1C3'). */\n getHintActionSummary,\n} from './utils';\n\n// ============================================================================\n// Localized Hint Utilities\n// ============================================================================\n\n/** Types for hint text localization. */\nexport type {\n /** Translation function compatible with i18next's `t` function. */\n TranslateFunction,\n} from './utils';\n\n/** Hint localization utilities. */\nexport {\n /** Get localized text for a hint step using a translation function. */\n getLocalizedHintText,\n /** Get localized title for a hint step using a translation function. */\n getLocalizedHintTitle,\n /** Resolve a localized API field, falling back to the raw value. */\n localizedField,\n} from './utils';\n\n// ============================================================================\n// i18n Key Utilities\n// ============================================================================\n\n/** Internationalization key generation and localization utilities. */\nexport {\n /** Get i18n key for a belt name (e.g., 'belts.1.name'). */\n getBeltKey,\n /** Get localized belt name using a translation function. */\n getLocalizedBeltName,\n /** Get i18n key for a belt label (e.g., 'belts.1.label'). */\n getBeltLabelKey,\n /** Get localized belt label (e.g., 'White Belt'). */\n getLocalizedBeltLabel,\n /** Get i18n key for a level title (e.g., 'levels.3'). */\n getLevelKey,\n /** Get localized level title using a translation function. */\n getLocalizedLevelTitle,\n /** Get i18n key for a technique name (e.g., 'techniques.full-house.title'). */\n getTechniqueKey,\n /** Get localized technique name using a translation function. */\n getLocalizedTechniqueName,\n} from './utils';\n\n// ============================================================================\n// Digit Display Utilities\n// ============================================================================\n\n/** Digit display format conversion. */\nexport {\n /** Convert a digit (1-9) to its display string based on the format (numeric, kanji, emojis). */\n displayDigit,\n} from './utils';\n\n// ============================================================================\n// Share URL Utilities\n// ============================================================================\n\n/** Types for share URL building and parsing. */\nexport type { ShareUrlParams, ParsedShareParams } from './utils';\n\n/** Build a share URL from game state. */\nexport { buildShareUrl } from './utils';\n\n/** Parse share URL query parameters into game state. */\nexport { parseShareParams } from './utils';\n\n/** Derive web app URL from API base URL. */\nexport { getWebUrl } from './utils';\n\n// ============================================================================\n// Auth Utilities\n// ============================================================================\n\n/** Minimal user shape for auth checks. */\nexport type { AuthUser } from './utils';\n\n/** Check if user-specific API calls should be enabled (non-anonymous, has token). */\nexport { isAuthenticatedUser } from './utils';\n\n// ============================================================================\n// Hooks\n// ============================================================================\n\nexport {\n // Data hooks\n /** Fetch a single difficulty level by number. */\n useLevel,\n /** Fetch all difficulty levels with sorting and filtering utilities. */\n useLevels,\n /** Fetch a single solving technique by number. */\n useTechnique,\n /** Fetch all solving techniques with grouping utilities. */\n useTechniques,\n /** Fetch learning materials with filtering by technique and language. */\n useLearning,\n /** Fetch a single learning item by UUID. */\n useLearningItem,\n\n /**\n * @deprecated Use `useSudoku` instead. `useGame` uses a legacy 2D array board\n * representation, while `useSudoku` uses a flat 81-cell array consistent with\n * the Kotlin renderable layer and the rest of the codebase.\n */\n useGame,\n\n /** Primary game state hook with flat 81-cell board, pencil mode, and scrambling. */\n useSudoku,\n\n /** Teaching/hint integration with the solver API (legacy GameHint format). */\n useGameTeaching,\n\n /** Fetch a random board for a specific level with auth/subscription handling. */\n useLevelGame,\n /** Fetch today's daily puzzle with auth/subscription handling. */\n useDailyGame,\n\n /** Game timer using refs to avoid re-renders every second. */\n useGameTimer,\n\n /** Persist individual game progress to localStorage. */\n useGamePersistence,\n /** Auto-save game state with debouncing. */\n useAutoSave,\n\n /** Generic typed localStorage hook with SSR safety. */\n useLocalStorage,\n\n /** Solver hint integration matching Kotlin HintInteractor behavior. */\n useHint,\n\n /** Current game management with Zustand store (daily/play slots). */\n useGamePlay,\n\n /** Manual puzzle entry mode with solver validation. */\n useBoardEntry,\n\n /** Server-side game session management for gamification (points, badges). */\n useGameSession,\n\n /** Check whether a level is enabled for the current user's entitlements. */\n useLevelEnabled,\n /** Check whether a technique is enabled for the current user's entitlements. */\n useTechniqueEnabled,\n\n /** Convert internal user level (0-indexed) to display values (1-indexed + belt). */\n useDisplayLevel,\n\n /** Compute cumulative puzzle distribution across entitlement tiers. */\n usePuzzleDistribution,\n\n /** Shared hint step tracker for game screens (ref + state). */\n useHintStepTracker,\n\n /** Auto-hint orchestration for shared links/deep links. */\n useAutoHint,\n\n /** Progress reporting for game state persistence. */\n useProgressReporter,\n\n /** Emit a hint action event to the active SudokuGame. */\n emitHintAction,\n /** Report hint status back after processing an action. */\n reportHintStatus,\n /** Subscribe to hint status updates. */\n onHintStatus,\n /** Hook for SudokuGame to listen for external hint action events. */\n useHintActionListener,\n} from './hooks';\n\nexport type {\n // Data hook types\n /** Options for useLevel hook. */\n UseLevelOptions,\n /** Result type for useLevel hook. */\n UseLevelResult,\n /** Options for useLevels hook. */\n UseLevelsOptions,\n /** Result type for useLevels hook. */\n UseLevelsResult,\n /** Options for useTechnique hook. */\n UseTechniqueOptions,\n /** Result type for useTechnique hook. */\n UseTechniqueResult,\n /** Options for useTechniques hook. */\n UseTechniquesOptions,\n /** Result type for useTechniques hook. */\n UseTechniquesResult,\n /** Options for useLearningItem hook. */\n UseLearningItemOptions,\n /** Result type for useLearningItem hook. */\n UseLearningItemResult,\n /** Options for useLearning hook. */\n UseLearningOptions,\n /** Result type for useLearning hook. */\n UseLearningResult,\n\n // Game hook types (legacy)\n /** @deprecated Options for legacy useGame hook. Use UseSudokuOptions instead. */\n UseGameOptions,\n /** @deprecated Result type for legacy useGame hook. Use UseSudokuResult instead. */\n UseGameResult,\n\n // Sudoku hook types\n /** Options for useSudoku hook (initial app settings). */\n UseSudokuOptions,\n /** Result type for useSudoku hook (state, computed values, actions, utilities). */\n UseSudokuResult,\n\n // Teaching hook types\n /** Options for useGameTeaching hook (network client, URL, token). */\n UseGameTeachingOptions,\n /** Result type for useGameTeaching hook (teaching state, hint actions). */\n UseGameTeachingResult,\n\n // Game fetching hook types\n /** Options for useLevelGame hook (network, auth, level number). */\n UseLevelGameOptions,\n /** Result type for useLevelGame hook (board data, fetch status). */\n UseLevelGameResult,\n /** Options for useDailyGame hook (network, auth). */\n UseDailyGameOptions,\n /** Result type for useDailyGame hook (daily data, fetch status). */\n UseDailyGameResult,\n /** Status of a game fetch: 'loading' | 'success' | 'auth_required' | 'subscription_required' | 'entitlement_required' | 'error'. */\n GameFetchStatus,\n\n // Timer hook types\n /** Options for useGameTimer hook (autoStart, initialTime). */\n UseGameTimerOptions,\n /** Result type for useGameTimer hook (elapsedRef, controls). */\n UseGameTimerResult,\n\n // Persistence hook types\n /** Options for useGamePersistence hook (puzzleKey, autoSave). */\n UseGamePersistenceOptions,\n /** Result type for useGamePersistence hook (load, save, clear, hasSaved). */\n UseGamePersistenceResult,\n\n // Hint hook types\n /** Options for useHint hook (network, puzzle state, technique filter). */\n UseHintOptions,\n /** Result type for useHint hook (hint steps, navigation, apply). */\n UseHintResult,\n /** Board data returned when applying a hint (user input, pencilmarks). */\n HintBoardData,\n /** Data passed to onHintReceived callback (hint, board data, technique info). */\n HintReceivedData,\n /** Access denied error info when hint level exceeds subscription tier. */\n HintAccessError,\n\n // Game play hook types\n /** Options for useGamePlay hook (slot selection, auto-save delay). */\n UseGamePlayOptions,\n /** Result type for useGamePlay hook (current game, start, update, clear). */\n UseGamePlayResult,\n\n // Board entry hook types\n /** Options for useBoardEntry hook (network client, URL, token). */\n UseBoardEntryOptions,\n /** Result type for useBoardEntry hook (cells, validation, actions). */\n UseBoardEntryReturn,\n /** Validated puzzle data from solver (puzzle + solution strings). */\n ValidatedPuzzle,\n\n // Game session hook types\n /** Options for useGameSession hook (network, auth, userId). */\n UseGameSessionOptions,\n /** Result of starting a game session (sessionStarted, sessionId). */\n GameSessionResult,\n /** Result of finishing a game session (leveledUp, badges, points). */\n GameFinishResult,\n\n // Display level hook types\n /** Result type for useDisplayLevel hook. */\n UseDisplayLevelResult,\n\n // Hint step tracker types\n /** Result type for useHintStepTracker hook. */\n UseHintStepTrackerResult,\n\n // Auto-hint types\n /** Options for useAutoHint hook. */\n UseAutoHintOptions,\n\n // Progress reporter types\n /** Options for useProgressReporter hook. */\n UseProgressReporterOptions,\n /** Callback type for progress updates. */\n ProgressUpdateCallback,\n\n // Hint action types\n /** Status reported after a hint action is processed. */\n HintActionStatus,\n} from './hooks';\n\n// ============================================================================\n// Stores\n// ============================================================================\n\n/** Zustand store for current game state with daily/play slots and localStorage persistence. */\nexport { useGamePlayStore } from './stores/gamePlayStore';\n/** State shape for the game play Zustand store. */\nexport type { GamePlayState } from './stores/gamePlayStore';\n\n// ============================================================================\n// Config\n// ============================================================================\n\n/** Authentication provider configuration types. */\nexport type {\n /** Available auth provider types: 'google' | 'apple' | 'email'. */\n AuthProviderType,\n /** Configuration for which auth providers are enabled. */\n AuthProvidersConfig,\n} from './config';\n\n/** Default auth providers configuration (Google + Email, anonymous fallback). */\nexport { DEFAULT_AUTH_PROVIDERS } from './config';\n\n// ============================================================================\n// Entitlement Context\n// ============================================================================\n\n/** Provider that supplies entitlements to useLevelEnabled / useTechniqueEnabled. */\nexport { EntitlementProvider } from './context';\n/** React context for entitlements (for advanced use). */\nexport { EntitlementContext, useEntitlementContext } from './context';\n\n// ============================================================================\n// Entitlement Utilities (re-exported from sudojo_types)\n// ============================================================================\n\n/** Parse a comma-delimited entitlement string into an array. */\nexport { parseEntitlements } from '@sudobility/sudojo_types';\n\n/** Check if a user has the required entitlement for a level. */\nexport { hasRequiredEntitlement } from '@sudobility/sudojo_types';\n"]}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { SolverHintStep } from '@sudobility/sudojo_types';
|
|
9
9
|
import type { DigitDisplay } from '../types/settings';
|
|
10
|
+
import type { TranslateFunction } from './localizedHint';
|
|
10
11
|
/**
|
|
11
12
|
* Generate detailed explanation for a hint
|
|
12
13
|
*
|
|
@@ -18,5 +19,5 @@ export declare function generateDetailedExplanation(hint: SolverHintStep, techni
|
|
|
18
19
|
/**
|
|
19
20
|
* Get a summary of the hint action (what to do)
|
|
20
21
|
*/
|
|
21
|
-
export declare function getHintActionSummary(hint: SolverHintStep, digitDisplay?: DigitDisplay): string;
|
|
22
|
+
export declare function getHintActionSummary(hint: SolverHintStep, digitDisplay?: DigitDisplay, t?: TranslateFunction): string;
|
|
22
23
|
//# sourceMappingURL=hintExplanation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hintExplanation.d.ts","sourceRoot":"","sources":["../../src/utils/hintExplanation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAkB,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"hintExplanation.d.ts","sourceRoot":"","sources":["../../src/utils/hintExplanation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAkB,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AA8IzD;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,cAAc,EACpB,WAAW,CAAC,EAAE,MAAM,EACpB,YAAY,CAAC,EAAE,YAAY,GAC1B,MAAM,CAgFR;AAqzBD;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,cAAc,EACpB,YAAY,CAAC,EAAE,YAAY,EAC3B,CAAC,CAAC,EAAE,iBAAiB,GACpB,MAAM,CAuDR"}
|
|
@@ -809,7 +809,7 @@ function generateGenericExplanation(hint, selectCells, removeCells) {
|
|
|
809
809
|
/**
|
|
810
810
|
* Get a summary of the hint action (what to do)
|
|
811
811
|
*/
|
|
812
|
-
export function getHintActionSummary(hint, digitDisplay) {
|
|
812
|
+
export function getHintActionSummary(hint, digitDisplay, t) {
|
|
813
813
|
_display = digitDisplay ?? 'numeric';
|
|
814
814
|
if (!hint.cells)
|
|
815
815
|
return '';
|
|
@@ -818,11 +818,28 @@ export function getHintActionSummary(hint, digitDisplay) {
|
|
|
818
818
|
if (selectCells.length > 0) {
|
|
819
819
|
if (selectCells.length === 1) {
|
|
820
820
|
const c = selectCells[0];
|
|
821
|
-
if (!c)
|
|
822
|
-
return
|
|
823
|
-
|
|
821
|
+
if (!c) {
|
|
822
|
+
return t
|
|
823
|
+
? t('hintAction.placeDigit', { defaultValue: 'Place a digit' })
|
|
824
|
+
: 'Place a digit';
|
|
825
|
+
}
|
|
826
|
+
const digit = formatDigit(c.digit);
|
|
827
|
+
const cell = cellName(c.row, c.col);
|
|
828
|
+
return t
|
|
829
|
+
? t('hintAction.placeInCell', {
|
|
830
|
+
defaultValue: `Place ${digit} in ${cell}`,
|
|
831
|
+
digit,
|
|
832
|
+
cell,
|
|
833
|
+
})
|
|
834
|
+
: `Place ${digit} in ${cell}`;
|
|
824
835
|
}
|
|
825
|
-
|
|
836
|
+
const count = String(selectCells.length);
|
|
837
|
+
return t
|
|
838
|
+
? t('hintAction.placeInCells', {
|
|
839
|
+
defaultValue: `Place digits in ${count} cells`,
|
|
840
|
+
count,
|
|
841
|
+
})
|
|
842
|
+
: `Place digits in ${selectCells.length} cells`;
|
|
826
843
|
}
|
|
827
844
|
if (removeCells.length > 0) {
|
|
828
845
|
const allDigits = new Set();
|
|
@@ -830,8 +847,21 @@ export function getHintActionSummary(hint, digitDisplay) {
|
|
|
830
847
|
for (const d of getValidDigits(c.digits))
|
|
831
848
|
allDigits.add(d);
|
|
832
849
|
});
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
850
|
+
const digits = formatDigits(Array.from(allDigits));
|
|
851
|
+
const count = String(removeCells.length);
|
|
852
|
+
const suffix = removeCells.length > 1 ? 's' : '';
|
|
853
|
+
return t
|
|
854
|
+
? t('hintAction.eliminate', {
|
|
855
|
+
defaultValue: `Eliminate ${digits} from ${count} cell${suffix}`,
|
|
856
|
+
digits,
|
|
857
|
+
count,
|
|
858
|
+
})
|
|
859
|
+
: `Eliminate ${digits} from ${count} cell${suffix}`;
|
|
860
|
+
}
|
|
861
|
+
return t
|
|
862
|
+
? t('hintAction.applyTechnique', {
|
|
863
|
+
defaultValue: 'Apply the technique',
|
|
864
|
+
})
|
|
865
|
+
: 'Apply the technique';
|
|
836
866
|
}
|
|
837
867
|
//# sourceMappingURL=hintExplanation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hintExplanation.js","sourceRoot":"","sources":["../../src/utils/hintExplanation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,EAAE,YAAY,IAAI,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjE,oFAAoF;AACpF,IAAI,QAAQ,GAAiB,SAAS,CAAC;AAEvC,8BAA8B;AAC9B,SAAS,QAAQ,CAAC,GAAW,EAAE,GAAW;IACxC,OAAO,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;AAClC,CAAC;AAED,yBAAyB;AACzB,SAAS,QAAQ,CAAC,KAA0C;IAC1D,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3D,CAAC;AAED,iDAAiD;AACjD,yDAAyD;AACzD,SAAS,WAAW,CAAC,CAAkB;IACrC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACpB,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG;QAAE,OAAO,GAAG,CAAC;IACnC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,eAAe,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,+DAA+D;AAC/D,SAAS,YAAY,CAAC,MAAyB;IAC7C,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAC/B,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC;QAC1C,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;IACvD,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAChC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACvD,OAAO,IAAI,GAAG;SACX,IAAI,EAAE;SACN,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;SACxB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;AACnB,CAAC;AAED,uDAAuD;AACvD,SAAS,kBAAkB,CAAC,MAA0B;IACpD,IAAI,CAAC,MAAM;QAAE,OAAO,GAAG,CAAC;IACxB,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG;YAAE,OAAO,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,sDAAsD;AACtD,SAAS,cAAc,CAAC,MAA0B;IAChD,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IACvB,OAAO,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;AAC5D,CAAC;AAED,sCAAsC;AACtC,SAAS,QAAQ,CAAC,GAAW,EAAE,GAAW;IACxC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AAC3D,CAAC;AAED,uCAAuC;AACvC,SAAS,eAAe,CACtB,KAA0C;IAE1C,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAE5C,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC;IACtD,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,KAAK,CAAC,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC;IACzE,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC;IACtD,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,UAAU,KAAK,CAAC,GAAG,GAAG,CAAC,EAAE,EAAE,CAAC;IAC5E,CAAC;IAED,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAC3B,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAC/D,CAAC;IACF,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAC7C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,KAAK,EAAE,EAAE,CAAC;IACjE,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,0DAA0D;AAC1D,gFAAgF;AAChF,SAAS,cAAc,CACrB,IAAoB;IAEpB,OAAO,IAAI,CAAC,KAAK;SACd,MAAM,CACL,CAAC,CAAiB,EAAE,EAAE,CACpB,CAAC,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,GAAG,CAC1E;SACA,GAAG,CAAC,CAAC,CAAiB,EAAE,EAAE,CAAC,CAAC;QAC3B,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,GAAG,EAAE,CAAC,CAAC,MAAM;QACb,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM;KACxB,CAAC,CAAC,CAAC;AACR,CAAC;AAED,uDAAuD;AACvD,sEAAsE;AACtE,SAAS,cAAc,CACrB,IAAoB;IAEpB,OAAO,IAAI,CAAC,KAAK;SACd,MAAM,CACL,CAAC,CAAiB,EAAE,EAAE,CACpB,CAAC,CAAC,OAAO,CAAC,MAAM;QAChB,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,EAAE;QACvB,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAC9C;SACA,GAAG,CAAC,CAAC,CAAiB,EAAE,EAAE,CAAC,CAAC;QAC3B,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,GAAG,EAAE,CAAC,CAAC,MAAM;QACb,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM;KACzB,CAAC,CAAC,CAAC;AACR,CAAC;AAED,2DAA2D;AAC3D,yEAAyE;AACzE,SAAS,iBAAiB,CACxB,IAAoB;IAEpB,OAAO,IAAI,CAAC,KAAK;SACd,MAAM,CACL,CAAC,CAAiB,EAAE,EAAE,CACpB,CAAC,CAAC,OAAO,CAAC,SAAS;QACnB,CAAC,CAAC,OAAO,CAAC,SAAS,KAAK,EAAE;QAC1B,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,CACjD;SACA,GAAG,CAAC,CAAC,CAAiB,EAAE,EAAE,CAAC,CAAC;QAC3B,GAAG,EAAE,CAAC,CAAC,GAAG;QACV,GAAG,EAAE,CAAC,CAAC,MAAM;QACb,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS;KAC5B,CAAC,CAAC,CAAC;AACR,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,2BAA2B,CACzC,IAAoB,EACpB,WAAoB,EACpB,YAA2B;IAE3B,QAAQ,GAAG,YAAY,IAAI,SAAS,CAAC;IACrC,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,cAAc,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAE/C,QAAQ,WAAW,EAAE,CAAC;QACpB,KAAK,WAAW,CAAC,UAAU;YACzB,OAAO,gBAAgB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAE7C,KAAK,WAAW,CAAC,aAAa;YAC5B,OAAO,mBAAmB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAEhD,KAAK,WAAW,CAAC,YAAY;YAC3B,OAAO,kBAAkB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAE/C,KAAK,WAAW,CAAC,WAAW;YAC1B,OAAO,iBAAiB,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;QAE9D,KAAK,WAAW,CAAC,UAAU;YACzB,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;QAE7D,KAAK,WAAW,CAAC,iBAAiB;YAChC,OAAO,uBAAuB,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;QAEpE,KAAK,WAAW,CAAC,aAAa;YAC5B,OAAO,mBAAmB,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;QAEhE,KAAK,WAAW,CAAC,YAAY;YAC3B,OAAO,kBAAkB,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;QAE/D,KAAK,WAAW,CAAC,WAAW;YAC1B,OAAO,iBAAiB,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;QAE9D,KAAK,WAAW,CAAC,UAAU;YACzB,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;QAE7D,KAAK,WAAW,CAAC,MAAM;YACrB,OAAO,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;QAEzD,KAAK,WAAW,CAAC,SAAS;YACxB,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;QAE7D,KAAK,WAAW,CAAC,SAAS;YACxB,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;QAE7D,KAAK,WAAW,CAAC,OAAO;YACtB,OAAO,aAAa,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;QAE1D,KAAK,WAAW,CAAC,aAAa;YAC5B,OAAO,kBAAkB,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;QAE/D,KAAK,WAAW,CAAC,SAAS;YACxB,OAAO,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;QAE7D,KAAK,WAAW,CAAC,gBAAgB;YAC/B,OAAO,sBAAsB,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;QAEnE,KAAK,WAAW,CAAC,gBAAgB;YAC/B,OAAO,sBAAsB,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;QAEnE,KAAK,WAAW,CAAC,QAAQ;YACvB,OAAO,cAAc,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;QAE3D,KAAK,WAAW,CAAC,SAAS;YACxB,OAAO,eAAe,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;QAE5D,KAAK,WAAW,CAAC,kBAAkB;YACjC,OAAO,uBAAuB,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;QAEpE,KAAK,WAAW,CAAC,gBAAgB;YAC/B,OAAO,sBAAsB,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;QAEnE,KAAK,WAAW,CAAC,SAAS,CAAC;QAC3B,KAAK,WAAW,CAAC,MAAM;YACrB,OAAO,eAAe,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;QAE5D;YACE,OAAO,0BAA0B,CAAC,IAAI,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;IACtE,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CACvB,IAAoB,EACpB,WAA+D;IAE/D,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAE/C,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAC5B,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAC5B,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEtC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK;YAAE,SAAS,GAAG,OAAO,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;aACxD,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ;YAAE,SAAS,GAAG,UAAU,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;aACnE,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;YAAE,SAAS,GAAG,SAAS,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;IACxE,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,CACL,GAAG,SAAS,qCAAqC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU;YACvF,wBAAwB,KAAK,mBAAmB,CACjD,CAAC;IACJ,CAAC;IAED,OAAO,CACL,QAAQ,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,wCAAwC;QAC5E,SAAS,KAAK,QAAQ,CACvB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAC1B,IAAoB,EACpB,WAA+D;IAE/D,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAE/C,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAC5B,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAC5B,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEtC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,SAAiB,CAAC;IACtB,IAAI,IAAI,EAAE,CAAC;QACT,SAAS;YACP,IAAI,CAAC,IAAI,KAAK,KAAK;gBACjB,CAAC,CAAC,OAAO,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE;gBACzB,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ;oBACtB,CAAC,CAAC,UAAU,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE;oBAC5B,CAAC,CAAC,SAAS,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;IACpC,CAAC;SAAM,CAAC;QACN,SAAS,GAAG,SAAS,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IACtD,CAAC;IAED,OAAO,CACL,MAAM,SAAS,WAAW,KAAK,6BAA6B,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI;QAC5F,oDAAoD,KAAK,0BAA0B,SAAS,CAAC,WAAW,EAAE,IAAI;QAC9G,SAAS,KAAK,QAAQ,CACvB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB,CACzB,IAAoB,EACpB,WAA+D;IAE/D,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAE/C,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAC5B,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAC5B,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEtC,OAAO,CACL,QAAQ,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,iCAAiC,KAAK,IAAI;QAC9E,2FAA2F;QAC3F,SAAS,KAAK,QAAQ,CACvB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CACxB,IAAoB,EACpB,cAAmE,EACnE,WAAgE;IAEhE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAEhD,MAAM,KAAK,GAAG,cAAc;SACzB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,KAAK,EAAE,IAAI,IAAI,aAAa,CAAC;IAE/C,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IACvC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACrC,KAAK,MAAM,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC;YAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IAE1D,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAC1C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CACvD,CAAC;IAEF,IAAI,WAAW,GAAG,MAAM,SAAS,YAAY,UAAU,uBAAuB,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;IAClG,WAAW,IAAI,0EAA0E,CAAC;IAC1F,WAAW,IAAI,SAAS,UAAU,8BAA8B,CAAC;IAEjE,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;QACrC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;YACvB,KAAK,MAAM,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC;gBAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QACH,WAAW,IAAI,kCAAkC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,oBAAoB,CAAC;IAC5G,CAAC;SAAM,CAAC;QACN,WAAW,IAAI,qCAAqC,CAAC;IACvD,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CACvB,IAAoB,EACpB,cAAmE,EACnE,WAAgE;IAEhE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAEhD,MAAM,KAAK,GAAG,cAAc;SACzB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,KAAK,EAAE,IAAI,IAAI,oBAAoB,CAAC;IAEtD,MAAM,UAAU,GAAG,YAAY,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAE3E,IAAI,WAAW,GAAG,SAAS,QAAQ,CAAC,KAAK,CAAC,yBAAyB,UAAU,6BAA6B,CAAC;IAC3G,WAAW,IAAI,yFAAyF,CAAC;IACzG,WAAW,IAAI,SAAS,UAAU,2BAA2B,CAAC;IAE9D,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,WAAW;aAC1B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;aACpE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC1C,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,WAAW,IAAI,aAAa,UAAU,wBAAwB,SAAS,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC;QACnH,CAAC;aAAM,CAAC;YACN,WAAW,IAAI,uDAAuD,CAAC;QACzE,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,uBAAuB,CAC9B,IAAoB,EACpB,cAAmE,EACnE,WAAgE;IAEhE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAEhD,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAC7B,MAAM,WAAW,GAAG,WAAW,CAC7B,kBAAkB,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAC9C,CAAC;IAEF,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAC3B,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAC/D,CAAC;IAEF,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACrE,MAAM,eAAe,GAAG,SAAS,CAAC,KAAK,CACrC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,KAAK,CACtC,CAAC;IAEF,IAAI,WAAW,GAAG,EAAE,CAAC;IAErB,IAAI,SAAS,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,EAAE,CAAC;QACtC,IAAI,eAAe,EAAE,CAAC;YACpB,MAAM,QAAQ,GAAG,OAAO;gBACtB,CAAC,CAAC,OAAO,KAAK,CAAC,GAAG,GAAG,CAAC,EAAE;gBACxB,CAAC,CAAC,UAAU,KAAK,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC;YAC9B,WAAW,GAAG,MAAM,QAAQ,WAAW,WAAW,6BAA6B,KAAK,WAAW,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC;YACpH,WAAW,IAAI,iBAAiB,WAAW,mCAAmC,CAAC;YAC/E,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,WAAW,IAAI,aAAa,WAAW,8BAA8B,KAAK,KAAK,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC;YACxG,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,QAAQ,GAAG,OAAO;gBACtB,CAAC,CAAC,OAAO,KAAK,CAAC,GAAG,GAAG,CAAC,EAAE;gBACxB,CAAC,CAAC,UAAU,KAAK,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC;YAC9B,WAAW,GAAG,YAAY,KAAK,WAAW,WAAW,uBAAuB,QAAQ,WAAW,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC;YACpH,WAAW,IAAI,oBAAoB,WAAW,kCAAkC,CAAC;YACjF,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,WAAW,IAAI,aAAa,WAAW,SAAS,QAAQ,CAAC,SAAS,CAAC,OAAO,QAAQ,kBAAkB,KAAK,GAAG,CAAC;YAC/G,CAAC;QACH,CAAC;IACH,CAAC;SAAM,IAAI,OAAO,EAAE,CAAC;QACnB,WAAW,GAAG,SAAS,WAAW,qBAAqB,KAAK,CAAC,GAAG,GAAG,CAAC,oBAAoB,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;QAC5G,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,WAAW,IAAI,aAAa,WAAW,SAAS,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC;QACzE,CAAC;IACH,CAAC;SAAM,IAAI,OAAO,EAAE,CAAC;QACnB,WAAW,GAAG,SAAS,WAAW,wBAAwB,KAAK,CAAC,GAAG,GAAG,CAAC,oBAAoB,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;QAC/G,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,WAAW,IAAI,aAAa,WAAW,SAAS,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC;QACzE,CAAC;IACH,CAAC;SAAM,CAAC;QACN,WAAW,GAAG,uCAAuC,WAAW,IAAI,CAAC;QACrE,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,WAAW,IAAI,aAAa,WAAW,SAAS,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC;QACzE,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAC1B,IAAoB,EACpB,cAAmE,EACnE,WAAgE;IAEhE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAEhD,MAAM,KAAK,GAAG,cAAc;SACzB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,KAAK,EAAE,IAAI,IAAI,aAAa,CAAC;IAE/C,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IACvC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACrC,KAAK,MAAM,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC;YAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IACH,MAAM,YAAY,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IAE5D,IAAI,WAAW,GAAG,MAAM,SAAS,YAAY,YAAY,6BAA6B,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;IAC1G,WAAW,IAAI,gFAAgF,CAAC;IAChG,WAAW,IAAI,SAAS,YAAY,8BAA8B,CAAC;IAEnE,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;QACrC,WAAW;aACR,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;aACnE,OAAO,CAAC,CAAC,CAAC,EAAE;YACX,KAAK,MAAM,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC;gBAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QACL,IAAI,UAAU,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YACxB,WAAW,IAAI,kCAAkC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,oBAAoB,CAAC;QAC5G,CAAC;aAAM,CAAC;YACN,WAAW,IAAI,qCAAqC,CAAC;QACvD,CAAC;IACH,CAAC;SAAM,CAAC;QACN,WAAW,IAAI,qCAAqC,CAAC;IACvD,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB,CACzB,IAAoB,EACpB,cAAmE,EACnE,WAAgE;IAEhE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAEhD,MAAM,KAAK,GAAG,cAAc;SACzB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,KAAK,EAAE,IAAI,IAAI,aAAa,CAAC;IAE/C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACrC,KAAK,MAAM,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC;YAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IACH,MAAM,YAAY,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAE3D,IAAI,WAAW,GAAG,SAAS,QAAQ,CAAC,KAAK,CAAC,yCAAyC,YAAY,IAAI,CAAC;IACpG,WAAW,IAAI,2EAA2E,CAAC;IAC3F,WAAW,IAAI,SAAS,YAAY,2BAA2B,CAAC;IAEhE,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAClC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAC7D,CAAC;QACF,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,WAAW,IAAI,aAAa,YAAY,wBAAwB,SAAS,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;QAC5J,CAAC;aAAM,CAAC;YACN,WAAW,IAAI,0CAA0C,CAAC;QAC5D,CAAC;IACH,CAAC;SAAM,CAAC;QACN,WAAW,IAAI,0CAA0C,CAAC;IAC5D,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CACxB,IAAoB,EACpB,cAAmE,EACnE,WAAgE;IAEhE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAEhD,MAAM,KAAK,GAAG,cAAc;SACzB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,KAAK,EAAE,IAAI,IAAI,aAAa,CAAC;IAE/C,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IACvC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACrC,KAAK,MAAM,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC;YAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IAE1D,IAAI,WAAW,GAAG,MAAM,SAAS,YAAY,UAAU,6BAA6B,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;IACxG,WAAW,IAAI,0DAA0D,CAAC;IAE1E,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;QACrC,WAAW;aACR,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;aACnE,OAAO,CAAC,CAAC,CAAC,EAAE;YACX,KAAK,MAAM,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC;gBAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QACL,IAAI,UAAU,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YACxB,WAAW,IAAI,kCAAkC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,oBAAoB,CAAC;QAC5G,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CACvB,IAAoB,EACpB,cAAmE,EACnE,WAAgE;IAEhE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAEhD,MAAM,KAAK,GAAG,cAAc;SACzB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,KAAK,EAAE,IAAI,IAAI,aAAa,CAAC;IAE/C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACrC,KAAK,MAAM,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC;YAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAEzD,IAAI,WAAW,GAAG,SAAS,QAAQ,CAAC,KAAK,CAAC,yCAAyC,UAAU,IAAI,CAAC;IAClG,WAAW,IAAI,wDAAwD,CAAC;IAExE,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAClC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAC7D,CAAC;QACF,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,WAAW,IAAI,aAAa,UAAU,wBAAwB,SAAS,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;QAC1J,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CACnB,IAAoB,EACpB,cAAmE,EACnE,WAAgE;IAEhE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAEhD,MAAM,KAAK,GAAG,WAAW,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACzE,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACvE,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACvE,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAErE,MAAM,UAAU,GACd,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAErE,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,IAAI,UAAU,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,WAAW,GAAG,0BAA0B,KAAK,IAAI,CAAC;QAClD,WAAW,IAAI,WAAW,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,4BAA4B,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;QAC/I,WAAW,IAAI,gCAAgC,KAAK,qCAAqC,CAAC;IAC5F,CAAC;SAAM,CAAC;QACN,WAAW,GAAG,0BAA0B,KAAK,IAAI,CAAC;QAClD,WAAW,IAAI,cAAc,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,yBAAyB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;QAC/I,WAAW,IAAI,gCAAgC,KAAK,qCAAqC,CAAC;IAC5F,CAAC;IAED,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,WAAW,IAAI,aAAa,KAAK,SAAS,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC;IACnE,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CACvB,IAAoB,EACpB,cAAmE,EACnE,WAAgE;IAEhE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAEhD,MAAM,KAAK,GAAG,WAAW,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACzE,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACvE,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACvE,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAErE,IAAI,WAAW,GAAG,6BAA6B,KAAK,IAAI,CAAC;IACzD,WAAW,IAAI,WAAW,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,KAAK,6BAA6B,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IAC1I,WAAW,IAAI,+BAA+B,KAAK,8CAA8C,CAAC;IAElG,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,WAAW,IAAI,aAAa,KAAK,uCAAuC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC;IACjG,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CACvB,IAAoB,EACpB,cAAmE,EACnE,WAAgE;IAEhE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAEhD,MAAM,KAAK,GAAG,WAAW,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACzE,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACvE,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACvE,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAErE,IAAI,WAAW,GAAG,6BAA6B,KAAK,IAAI,CAAC;IACzD,WAAW,IAAI,WAAW,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,KAAK,6BAA6B,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IAC1I,WAAW,IAAI,+BAA+B,KAAK,+BAA+B,CAAC;IAEnF,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,WAAW,IAAI,aAAa,KAAK,uCAAuC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC;IACjG,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CACvB,IAAoB,EACpB,cAAmE,EACnE,WAAgE;IAEhE,IAAI,cAAc,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAEjD,MAAM,KAAK,GAAG,WAAW,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACzE,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACvE,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACvE,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAErE,IAAI,WAAW,GAAG,sCAAsC,KAAK,IAAI,CAAC;IAClE,WAAW,IAAI,eAAe,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,KAAK,2BAA2B,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IAC5I,WAAW,IAAI,wCAAwC,KAAK,2BAA2B,CAAC;IAExF,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,WAAW,IAAI,aAAa,KAAK,SAAS,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC;IACnE,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CACpB,IAAoB,EACpB,cAAmE,EACnE,WAAgE;IAEhE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAEhD,MAAM,KAAK,GAAG,cAAc;SACzB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC1C,MAAM,MAAM,GACV,WAAW,CAAC,MAAM,GAAG,CAAC;QACpB,CAAC,CAAC,WAAW,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QACzD,CAAC,CAAC,GAAG,CAAC;IAEV,IAAI,WAAW,GAAG,yBAAyB,CAAC;IAC5C,WAAW,IAAI,qCAAqC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;IACxE,WAAW,IAAI,yEAAyE,MAAM,IAAI,CAAC;IACnG,WAAW,IAAI,+CAA+C,MAAM,gDAAgD,MAAM,IAAI,CAAC;IAC/H,WAAW,IAAI,eAAe,MAAM,oCAAoC,CAAC;IAEzE,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrE,WAAW,IAAI,aAAa,MAAM,oCAAoC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC;IAC/F,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CACrB,IAAoB,EACpB,cAAmE,EACnE,WAAgE;IAEhE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAEhD,MAAM,KAAK,GAAG,cAAc;SACzB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC1C,MAAM,MAAM,GACV,WAAW,CAAC,MAAM,GAAG,CAAC;QACpB,CAAC,CAAC,WAAW,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QACzD,CAAC,CAAC,GAAG,CAAC;IAEV,IAAI,WAAW,GAAG,0BAA0B,CAAC;IAC7C,WAAW,IAAI,oFAAoF,CAAC;IACpG,WAAW,IAAI,UAAU,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;IAC7C,WAAW,IAAI,aAAa,MAAM,uCAAuC,CAAC;IAC1E,WAAW,IAAI,mCAAmC,MAAM,IAAI,CAAC;IAE7D,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrE,WAAW,IAAI,aAAa,MAAM,mCAAmC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC;IAC9F,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CACtB,IAAoB,EACpB,cAAmE,EACnE,WAAgE;IAEhE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAEhD,MAAM,KAAK,GAAG,cAAc;SACzB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC1C,MAAM,SAAS,GACb,WAAW,CAAC,MAAM,GAAG,CAAC;QACpB,CAAC,CAAC,WAAW,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QACzD,CAAC,CAAC,GAAG,CAAC;IAEV,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACrC,KAAK,MAAM,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC;YAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,IAAI,WAAW,GAAG,2BAA2B,CAAC;IAC9C,WAAW,IAAI,cAAc,QAAQ,CAAC,KAAK,CAAC,kCAAkC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC;IACtH,WAAW,IAAI,mCAAmC,SAAS,IAAI,CAAC;IAEhE,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrE,WAAW,IAAI,aAAa,SAAS,yCAAyC,SAAS,oBAAoB,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC;IACpI,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB,CACzB,IAAoB,EACpB,cAAmE,EACnE,WAAgE;IAEhE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAEhD,MAAM,KAAK,GAAG,WAAW,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACzE,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACvE,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACvE,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAErE,IAAI,WAAW,GAAG,2BAA2B,KAAK,IAAI,CAAC;IACvD,WAAW,IAAI,oCAAoC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI;SACnG,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;SACf,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IACrB,WAAW,IAAI,uEAAuE,CAAC;IACvF,WAAW,IAAI,8EAA8E,CAAC;IAE9F,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,WAAW,IAAI,aAAa,KAAK,SAAS,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC;IACnE,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAS,sBAAsB,CAC7B,IAAoB,EACpB,cAAmE,EACnE,WAAgE;IAEhE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAEhD,MAAM,KAAK,GAAG,WAAW,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACzE,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACvE,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAErE,IAAI,WAAW,GAAG,8BAA8B,KAAK,IAAI,CAAC;IAC1D,WAAW,IAAI,0CAA0C,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IAC7F,WAAW,IAAI,uDAAuD,CAAC;IACvE,WAAW,IAAI,uDAAuD,KAAK,eAAe,CAAC;IAE3F,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,WAAW,IAAI,aAAa,KAAK,SAAS,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC;IACnE,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAS,sBAAsB,CAC7B,IAAoB,EACpB,cAAmE,EACnE,WAAgE;IAEhE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAEhD,MAAM,KAAK,GAAG,WAAW,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACzE,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACvE,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAErE,IAAI,WAAW,GAAG,8BAA8B,KAAK,IAAI,CAAC;IAC1D,WAAW,IAAI,0CAA0C,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IAC7F,WAAW,IAAI,iCAAiC,CAAC;IAEjD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,WAAW,IAAI,aAAa,KAAK,SAAS,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC;IACnE,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAS,sBAAsB,CAC7B,IAAoB,EACpB,cAAmE,EACnE,WAAgE;IAEhE,IAAI,cAAc,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAEjD,MAAM,KAAK,GAAG,WAAW,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACzE,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACvE,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAErE,IAAI,WAAW,GAAG,uCAAuC,KAAK,IAAI,CAAC;IACnE,WAAW,IAAI,qCAAqC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC;IAEpG,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,WAAW,IAAI,aAAa,KAAK,SAAS,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC;IACnE,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,uBAAuB,CAC9B,IAAoB,EACpB,cAAmE,EACnE,WAAgE;IAEhE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAEhD,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,KAAK,EAAE,IAAI,IAAI,oBAAoB,CAAC;IAEtD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACzB,KAAK,MAAM,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC;YAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC;IAChC,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC;IAE9B,IAAI,WAAW,GAAG,8BAA8B,SAAS,IAAI,CAAC;IAC9D,WAAW,IAAI,SAAS,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,mBAAmB,MAAM,gBAAgB,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC;IAC9H,WAAW,IAAI,2EAA2E,CAAC;IAC3F,WAAW,IAAI,iBAAiB,CAAC,+BAA+B,CAAC,UAAU,CAAC;IAE5E,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;QACrC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;YACtB,KAAK,MAAM,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC;gBAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QACH,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrE,WAAW,IAAI,aAAa,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,SAAS,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC;IAClG,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CACtB,IAAoB,EACpB,cAAmE,EACnE,WAAgE;IAEhE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAEhD,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAEpE,IAAI,WAAW,GAAG,8BAA8B,CAAC;IACjD,WAAW,IAAI,oEAAoE,CAAC;IACpF,WAAW,IAAI,kBAAkB,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;IACrD,WAAW,IAAI,0FAA0F,CAAC;IAE1G,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;QACrC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;YACtB,KAAK,MAAM,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC;gBAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QACH,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrE,WAAW,IAAI,aAAa,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,SAAS,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC;IAClG,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,0BAA0B,CACjC,IAAoB,EACpB,WAA+D,EAC/D,WAAgE;IAEhE,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEtB,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAChC,CAAC,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAC5D,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,UAAU,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjD,CAAC;IAED,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,YAAY,GAAG,WAAW,CAAC,GAAG,CAClC,CAAC,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAChE,CAAC;QACF,IAAI,YAAY,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,cAAc,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvD,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,6BAA6B,WAAW,CAAC,MAAM,SAAS,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,IAAoB,EACpB,YAA2B;IAE3B,QAAQ,GAAG,YAAY,IAAI,SAAS,CAAC;IACrC,IAAI,CAAC,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IAC3B,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IAEzC,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;YACzB,IAAI,CAAC,CAAC;gBAAE,OAAO,eAAe,CAAC;YAC/B,OAAO,SAAS,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;QACtE,CAAC;QACD,OAAO,mBAAmB,WAAW,CAAC,MAAM,QAAQ,CAAC;IACvD,CAAC;IAED,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;QACpC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;YACtB,KAAK,MAAM,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC;gBAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;QACH,OAAO,aAAa,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,SAAS,WAAW,CAAC,MAAM,QAAQ,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAChI,CAAC;IAED,OAAO,qBAAqB,CAAC;AAC/B,CAAC","sourcesContent":["/**\n * Generate detailed hint explanations based on the hint payload\n * Similar to tutorial explanations but for live hints\n *\n * Each explanation is designed to teach the user WHY the technique works,\n * not just WHAT to do.\n */\n\nimport type { SolverHintCell, SolverHintStep } from '@sudobility/sudojo_types';\nimport { TechniqueId } from '@sudobility/sudojo_types';\nimport type { DigitDisplay } from '../types/settings';\nimport { displayDigit as mapDigitDisplay } from './digitDisplay';\n\n// Module-level display format, set by public entry points before calling internals.\nlet _display: DigitDisplay = 'numeric';\n\n// Cell notation (R1C1 format)\nfunction cellName(row: number, col: number): string {\n return `R${row + 1}C${col + 1}`;\n}\n\n// Format a list of cells\nfunction cellList(cells: Array<{ row: number; col: number }>): string {\n return cells.map(c => cellName(c.row, c.col)).join(', ');\n}\n\n// Format digit(s) - only valid Sudoku digits 1-9\n// Uses module-level _display set by public entry points.\nfunction formatDigit(d: string | number): string {\n const s = String(d);\n if (s < '1' || s > '9') return '?';\n if (_display !== 'numeric') {\n return mapDigitDisplay(parseInt(s, 10), _display);\n }\n return s;\n}\n\n// Format multiple digits as set - only valid Sudoku digits 1-9\nfunction formatDigits(digits: string | string[]): string {\n const arr = Array.isArray(digits)\n ? digits.filter(d => d >= '1' && d <= '9')\n : digits.split('').filter(d => d >= '1' && d <= '9');\n if (arr.length === 0) return '';\n if (arr.length === 1) return formatDigit(arr[0] ?? '');\n return `{${arr\n .sort()\n .map(d => formatDigit(d))\n .join(', ')}}`;\n}\n\n// Extract first valid Sudoku digit (1-9) from a string\nfunction getFirstValidDigit(digits: string | undefined): string {\n if (!digits) return '?';\n for (const d of digits) {\n if (d >= '1' && d <= '9') return d;\n }\n return '?';\n}\n\n// Extract all valid Sudoku digits (1-9) from a string\nfunction getValidDigits(digits: string | undefined): string[] {\n if (!digits) return [];\n return digits.split('').filter(d => d >= '1' && d <= '9');\n}\n\n// Get block number (1-9) from row/col\nfunction getBlock(row: number, col: number): number {\n return Math.floor(row / 3) * 3 + Math.floor(col / 3) + 1;\n}\n\n// Determine the common house for cells\nfunction findCommonHouse(\n cells: Array<{ row: number; col: number }>\n): { type: 'row' | 'col' | 'block'; index: number; name: string } | null {\n const first = cells[0];\n if (cells.length < 2 || !first) return null;\n\n const sameRow = cells.every(c => c.row === first.row);\n if (sameRow) {\n return { type: 'row', index: first.row, name: `Row ${first.row + 1}` };\n }\n\n const sameCol = cells.every(c => c.col === first.col);\n if (sameCol) {\n return { type: 'col', index: first.col, name: `Column ${first.col + 1}` };\n }\n\n const sameBlock = cells.every(\n c => getBlock(c.row, c.col) === getBlock(first.row, first.col)\n );\n if (sameBlock) {\n const block = getBlock(first.row, first.col);\n return { type: 'block', index: block, name: `Block ${block}` };\n }\n\n return null;\n}\n\n// Extract cells that have select action (digit placement)\n// Note: select: \"0\" means no selection (placeholder), only 1-9 are valid digits\nfunction getSelectCells(\n hint: SolverHintStep\n): Array<{ row: number; col: number; digit: string }> {\n return hint.cells\n .filter(\n (c: SolverHintCell) =>\n c.actions.select && c.actions.select !== '' && c.actions.select !== '0'\n )\n .map((c: SolverHintCell) => ({\n row: c.row,\n col: c.column,\n digit: c.actions.select,\n }));\n}\n\n// Extract cells that have remove action (eliminations)\n// Note: Filter out cells where remove only contains \"0\" (placeholder)\nfunction getRemoveCells(\n hint: SolverHintStep\n): Array<{ row: number; col: number; digits: string }> {\n return hint.cells\n .filter(\n (c: SolverHintCell) =>\n c.actions.remove &&\n c.actions.remove !== '' &&\n getValidDigits(c.actions.remove).length > 0\n )\n .map((c: SolverHintCell) => ({\n row: c.row,\n col: c.column,\n digits: c.actions.remove,\n }));\n}\n\n// Extract cells that have highlight action (pattern cells)\n// Note: Filter out cells where highlight only contains \"0\" (placeholder)\nfunction getHighlightCells(\n hint: SolverHintStep\n): Array<{ row: number; col: number; digits: string }> {\n return hint.cells\n .filter(\n (c: SolverHintCell) =>\n c.actions.highlight &&\n c.actions.highlight !== '' &&\n getValidDigits(c.actions.highlight).length > 0\n )\n .map((c: SolverHintCell) => ({\n row: c.row,\n col: c.column,\n digits: c.actions.highlight,\n }));\n}\n\n/**\n * Generate detailed explanation for a hint\n *\n * @param hint - The hint step data\n * @param techniqueId - The technique ID (from SolverHints.technique)\n * @param digitDisplay - Optional digit display format\n */\nexport function generateDetailedExplanation(\n hint: SolverHintStep,\n techniqueId?: number,\n digitDisplay?: DigitDisplay\n): string {\n _display = digitDisplay ?? 'numeric';\n const selectCells = getSelectCells(hint);\n const removeCells = getRemoveCells(hint);\n const highlightCells = getHighlightCells(hint);\n\n switch (techniqueId) {\n case TechniqueId.FULL_HOUSE:\n return explainFullHouse(hint, selectCells);\n\n case TechniqueId.HIDDEN_SINGLE:\n return explainHiddenSingle(hint, selectCells);\n\n case TechniqueId.NAKED_SINGLE:\n return explainNakedSingle(hint, selectCells);\n\n case TechniqueId.HIDDEN_PAIR:\n return explainHiddenPair(hint, highlightCells, removeCells);\n\n case TechniqueId.NAKED_PAIR:\n return explainNakedPair(hint, highlightCells, removeCells);\n\n case TechniqueId.LOCKED_CANDIDATES:\n return explainLockedCandidates(hint, highlightCells, removeCells);\n\n case TechniqueId.HIDDEN_TRIPLE:\n return explainHiddenTriple(hint, highlightCells, removeCells);\n\n case TechniqueId.NAKED_TRIPLE:\n return explainNakedTriple(hint, highlightCells, removeCells);\n\n case TechniqueId.HIDDEN_QUAD:\n return explainHiddenQuad(hint, highlightCells, removeCells);\n\n case TechniqueId.NAKED_QUAD:\n return explainNakedQuad(hint, highlightCells, removeCells);\n\n case TechniqueId.X_WING:\n return explainXWing(hint, highlightCells, removeCells);\n\n case TechniqueId.SWORDFISH:\n return explainSwordfish(hint, highlightCells, removeCells);\n\n case TechniqueId.JELLYFISH:\n return explainJellyfish(hint, highlightCells, removeCells);\n\n case TechniqueId.XY_WING:\n return explainXYWing(hint, highlightCells, removeCells);\n\n case TechniqueId.FINNED_X_WING:\n return explainFinnedXWing(hint, highlightCells, removeCells);\n\n case TechniqueId.SQUIRMBAG:\n return explainSquirmbag(hint, highlightCells, removeCells);\n\n case TechniqueId.FINNED_SWORDFISH:\n return explainFinnedSwordfish(hint, highlightCells, removeCells);\n\n case TechniqueId.FINNED_JELLYFISH:\n return explainFinnedJellyfish(hint, highlightCells, removeCells);\n\n case TechniqueId.XYZ_WING:\n return explainXYZWing(hint, highlightCells, removeCells);\n\n case TechniqueId.WXYZ_WING:\n return explainWXYZWing(hint, highlightCells, removeCells);\n\n case TechniqueId.ALMOST_LOCKED_SETS:\n return explainAlmostLockedSets(hint, highlightCells, removeCells);\n\n case TechniqueId.FINNED_SQUIRMBAG:\n return explainFinnedSquirmbag(hint, highlightCells, removeCells);\n\n case TechniqueId.ALS_CHAIN:\n case TechniqueId.ALS_XZ:\n return explainALSChain(hint, highlightCells, removeCells);\n\n default:\n return generateGenericExplanation(hint, selectCells, removeCells);\n }\n}\n\n/**\n * Full House: The last empty cell in a house.\n */\nfunction explainFullHouse(\n hint: SolverHintStep,\n selectCells: Array<{ row: number; col: number; digit: string }>\n): string {\n if (selectCells.length !== 1) return hint.text;\n\n const cell = selectCells[0];\n if (!cell) return hint.text;\n const digit = formatDigit(cell.digit);\n\n const area = hint.areas?.[0];\n let houseName = '';\n if (area) {\n if (area.type === 'row') houseName = `Row ${area.index + 1}`;\n else if (area.type === 'column') houseName = `Column ${area.index + 1}`;\n else if (area.type === 'block') houseName = `Block ${area.index + 1}`;\n }\n\n if (houseName) {\n return (\n `${houseName} has 8 cells filled, leaving only ${cellName(cell.row, cell.col)} empty. ` +\n `The missing digit is ${digit} — place it here.`\n );\n }\n\n return (\n `Cell ${cellName(cell.row, cell.col)} is the only empty cell in its house. ` +\n `Place ${digit} here.`\n );\n}\n\n/**\n * Hidden Single: A digit that can only go in one cell within a house.\n */\nfunction explainHiddenSingle(\n hint: SolverHintStep,\n selectCells: Array<{ row: number; col: number; digit: string }>\n): string {\n if (selectCells.length !== 1) return hint.text;\n\n const cell = selectCells[0];\n if (!cell) return hint.text;\n const digit = formatDigit(cell.digit);\n\n const area = hint.areas?.[0];\n let houseName: string;\n if (area) {\n houseName =\n area.type === 'row'\n ? `Row ${area.index + 1}`\n : area.type === 'column'\n ? `Column ${area.index + 1}`\n : `Block ${area.index + 1}`;\n } else {\n houseName = `Block ${getBlock(cell.row, cell.col)}`;\n }\n\n return (\n `In ${houseName}, digit ${digit} can only go in one cell: ${cellName(cell.row, cell.col)}. ` +\n `Even though this cell may have other candidates, ${digit} has no other place in ${houseName.toLowerCase()}. ` +\n `Place ${digit} here.`\n );\n}\n\n/**\n * Naked Single: A cell with only one candidate remaining.\n */\nfunction explainNakedSingle(\n hint: SolverHintStep,\n selectCells: Array<{ row: number; col: number; digit: string }>\n): string {\n if (selectCells.length !== 1) return hint.text;\n\n const cell = selectCells[0];\n if (!cell) return hint.text;\n const digit = formatDigit(cell.digit);\n\n return (\n `Cell ${cellName(cell.row, cell.col)} has only one candidate left: ${digit}. ` +\n `All other digits are eliminated by numbers already placed in its row, column, and block. ` +\n `Place ${digit} here.`\n );\n}\n\n/**\n * Hidden Pair: Two digits that can only appear in exactly two cells within a house.\n */\nfunction explainHiddenPair(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 2) return hint.text;\n\n const cells = highlightCells\n .slice(0, 2)\n .map(c => ({ row: c.row, col: c.col }));\n const house = findCommonHouse(cells);\n const houseName = house?.name || 'their house';\n\n const hiddenDigits = new Set<string>();\n highlightCells.slice(0, 2).forEach(c => {\n for (const d of getValidDigits(c.digits)) hiddenDigits.add(d);\n });\n const pairDigits = formatDigits(Array.from(hiddenDigits));\n\n const eliminations = removeCells.filter(c =>\n cells.some(hc => hc.row === c.row && hc.col === c.col)\n );\n\n let explanation = `In ${houseName}, digits ${pairDigits} can ONLY appear in ${cellList(cells)}. `;\n explanation += `These form a Hidden Pair — the pair is \"hidden\" among other candidates. `;\n explanation += `Since ${pairDigits} must occupy these 2 cells, `;\n\n if (eliminations.length > 0) {\n const elimDigits = new Set<string>();\n eliminations.forEach(e => {\n for (const d of getValidDigits(e.digits)) elimDigits.add(d);\n });\n explanation += `eliminate the other candidates ${formatDigits(Array.from(elimDigits))} from these cells.`;\n } else {\n explanation += `other candidates can be eliminated.`;\n }\n\n return explanation;\n}\n\n/**\n * Naked Pair: Two cells in a house that contain exactly the same two candidates.\n */\nfunction explainNakedPair(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 2) return hint.text;\n\n const cells = highlightCells\n .slice(0, 2)\n .map(c => ({ row: c.row, col: c.col }));\n const house = findCommonHouse(cells);\n const houseName = house?.name || 'their shared house';\n\n const pairDigits = formatDigits(getValidDigits(highlightCells[0]?.digits));\n\n let explanation = `Cells ${cellList(cells)} both contain exactly ${pairDigits} as their only candidates. `;\n explanation += `This is a Naked Pair — the pair is \"naked\" because these cells show only these digits. `;\n explanation += `Since ${pairDigits} must go in these cells, `;\n\n if (removeCells.length > 0) {\n const elimCells = removeCells\n .filter(c => !cells.some(pc => pc.row === c.row && pc.col === c.col))\n .map(c => ({ row: c.row, col: c.col }));\n if (elimCells.length > 0) {\n explanation += `eliminate ${pairDigits} from other cells in ${houseName.toLowerCase()}: ${cellList(elimCells)}.`;\n } else {\n explanation += `they can be eliminated from other cells in the house.`;\n }\n }\n\n return explanation;\n}\n\n/**\n * Locked Candidates (Pointing/Claiming)\n */\nfunction explainLockedCandidates(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 2) return hint.text;\n\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n const first = cells[0];\n if (!first) return hint.text;\n const lockedDigit = formatDigit(\n getFirstValidDigit(highlightCells[0]?.digits)\n );\n\n const sameRow = cells.every(c => c.row === first.row);\n const sameCol = cells.every(c => c.col === first.col);\n const sameBlock = cells.every(\n c => getBlock(c.row, c.col) === getBlock(first.row, first.col)\n );\n\n const block = getBlock(first.row, first.col);\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n const elimInSameBlock = elimCells.every(\n c => getBlock(c.row, c.col) === block\n );\n\n let explanation = '';\n\n if (sameBlock && (sameRow || sameCol)) {\n if (elimInSameBlock) {\n const lineName = sameRow\n ? `Row ${first.row + 1}`\n : `Column ${first.col + 1}`;\n explanation = `In ${lineName}, digit ${lockedDigit} can only appear in Block ${block} (cells ${cellList(cells)}). `;\n explanation += `This \"claims\" ${lockedDigit} for this line within the block. `;\n if (elimCells.length > 0) {\n explanation += `Eliminate ${lockedDigit} from other cells in Block ${block}: ${cellList(elimCells)}.`;\n }\n } else {\n const lineName = sameRow\n ? `Row ${first.row + 1}`\n : `Column ${first.col + 1}`;\n explanation = `In Block ${block}, digit ${lockedDigit} can only appear in ${lineName} (cells ${cellList(cells)}). `;\n explanation += `This \"points\" to ${lockedDigit} being restricted to this line. `;\n if (elimCells.length > 0) {\n explanation += `Eliminate ${lockedDigit} from ${cellList(elimCells)} in ${lineName} outside Block ${block}.`;\n }\n }\n } else if (sameRow) {\n explanation = `Digit ${lockedDigit} is locked to Row ${first.row + 1} in these cells: ${cellList(cells)}. `;\n if (elimCells.length > 0) {\n explanation += `Eliminate ${lockedDigit} from ${cellList(elimCells)}.`;\n }\n } else if (sameCol) {\n explanation = `Digit ${lockedDigit} is locked to Column ${first.col + 1} in these cells: ${cellList(cells)}. `;\n if (elimCells.length > 0) {\n explanation += `Eliminate ${lockedDigit} from ${cellList(elimCells)}.`;\n }\n } else {\n explanation = `Locked Candidates pattern for digit ${lockedDigit}. `;\n if (elimCells.length > 0) {\n explanation += `Eliminate ${lockedDigit} from ${cellList(elimCells)}.`;\n }\n }\n\n return explanation;\n}\n\n/**\n * Hidden Triple: Three digits that can only appear in exactly three cells within a house.\n */\nfunction explainHiddenTriple(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 3) return hint.text;\n\n const cells = highlightCells\n .slice(0, 3)\n .map(c => ({ row: c.row, col: c.col }));\n const house = findCommonHouse(cells);\n const houseName = house?.name || 'their house';\n\n const hiddenDigits = new Set<string>();\n highlightCells.slice(0, 3).forEach(c => {\n for (const d of getValidDigits(c.digits)) hiddenDigits.add(d);\n });\n const tripleDigits = formatDigits(Array.from(hiddenDigits));\n\n let explanation = `In ${houseName}, digits ${tripleDigits} can ONLY appear in cells ${cellList(cells)}. `;\n explanation += `This is a Hidden Triple — these 3 digits are \"hidden\" among other candidates. `;\n explanation += `Since ${tripleDigits} must occupy these 3 cells, `;\n\n if (removeCells.length > 0) {\n const elimDigits = new Set<string>();\n removeCells\n .filter(c => cells.some(hc => hc.row === c.row && hc.col === c.col))\n .forEach(e => {\n for (const d of getValidDigits(e.digits)) elimDigits.add(d);\n });\n if (elimDigits.size > 0) {\n explanation += `eliminate the other candidates ${formatDigits(Array.from(elimDigits))} from these cells.`;\n } else {\n explanation += `other candidates can be eliminated.`;\n }\n } else {\n explanation += `other candidates can be eliminated.`;\n }\n\n return explanation;\n}\n\n/**\n * Naked Triple: Three cells in a house that together contain only three candidates total.\n */\nfunction explainNakedTriple(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 3) return hint.text;\n\n const cells = highlightCells\n .slice(0, 3)\n .map(c => ({ row: c.row, col: c.col }));\n const house = findCommonHouse(cells);\n const houseName = house?.name || 'their house';\n\n const nakedDigits = new Set<string>();\n highlightCells.slice(0, 3).forEach(c => {\n for (const d of getValidDigits(c.digits)) nakedDigits.add(d);\n });\n const tripleDigits = formatDigits(Array.from(nakedDigits));\n\n let explanation = `Cells ${cellList(cells)} together contain only the candidates ${tripleDigits}. `;\n explanation += `This is a Naked Triple — these 3 cells share only 3 digits between them. `;\n explanation += `Since ${tripleDigits} must go in these cells, `;\n\n if (removeCells.length > 0) {\n const elimCells = removeCells.filter(\n c => !cells.some(nc => nc.row === c.row && nc.col === c.col)\n );\n if (elimCells.length > 0) {\n explanation += `eliminate ${tripleDigits} from other cells in ${houseName.toLowerCase()}: ${cellList(elimCells.map(c => ({ row: c.row, col: c.col })))}.`;\n } else {\n explanation += `they can be eliminated from other cells.`;\n }\n } else {\n explanation += `they can be eliminated from other cells.`;\n }\n\n return explanation;\n}\n\n/**\n * Hidden Quad: Four digits that can only appear in exactly four cells within a house.\n */\nfunction explainHiddenQuad(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 4) return hint.text;\n\n const cells = highlightCells\n .slice(0, 4)\n .map(c => ({ row: c.row, col: c.col }));\n const house = findCommonHouse(cells);\n const houseName = house?.name || 'their house';\n\n const hiddenDigits = new Set<string>();\n highlightCells.slice(0, 4).forEach(c => {\n for (const d of getValidDigits(c.digits)) hiddenDigits.add(d);\n });\n const quadDigits = formatDigits(Array.from(hiddenDigits));\n\n let explanation = `In ${houseName}, digits ${quadDigits} can ONLY appear in cells ${cellList(cells)}. `;\n explanation += `This is a Hidden Quad — 4 digits restricted to 4 cells. `;\n\n if (removeCells.length > 0) {\n const elimDigits = new Set<string>();\n removeCells\n .filter(c => cells.some(hc => hc.row === c.row && hc.col === c.col))\n .forEach(e => {\n for (const d of getValidDigits(e.digits)) elimDigits.add(d);\n });\n if (elimDigits.size > 0) {\n explanation += `Eliminate the other candidates ${formatDigits(Array.from(elimDigits))} from these cells.`;\n }\n }\n\n return explanation;\n}\n\n/**\n * Naked Quad: Four cells in a house that together contain only four candidates total.\n */\nfunction explainNakedQuad(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 4) return hint.text;\n\n const cells = highlightCells\n .slice(0, 4)\n .map(c => ({ row: c.row, col: c.col }));\n const house = findCommonHouse(cells);\n const houseName = house?.name || 'their house';\n\n const nakedDigits = new Set<string>();\n highlightCells.slice(0, 4).forEach(c => {\n for (const d of getValidDigits(c.digits)) nakedDigits.add(d);\n });\n const quadDigits = formatDigits(Array.from(nakedDigits));\n\n let explanation = `Cells ${cellList(cells)} together contain only the candidates ${quadDigits}. `;\n explanation += `This is a Naked Quad — 4 cells sharing only 4 digits. `;\n\n if (removeCells.length > 0) {\n const elimCells = removeCells.filter(\n c => !cells.some(nc => nc.row === c.row && nc.col === c.col)\n );\n if (elimCells.length > 0) {\n explanation += `Eliminate ${quadDigits} from other cells in ${houseName.toLowerCase()}: ${cellList(elimCells.map(c => ({ row: c.row, col: c.col })))}.`;\n }\n }\n\n return explanation;\n}\n\n/**\n * X-Wing: A 2x2 fish pattern.\n */\nfunction explainXWing(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 4) return hint.text;\n\n const digit = formatDigit(getFirstValidDigit(highlightCells[0]?.digits));\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n const rows = [...new Set(cells.map(c => c.row))].sort((a, b) => a - b);\n const cols = [...new Set(cells.map(c => c.col))].sort((a, b) => a - b);\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n\n const elimInCols =\n elimCells.length > 0 && elimCells.every(c => cols.includes(c.col));\n\n let explanation = '';\n if (elimInCols || rows.length === 2) {\n explanation = `X-Wing found for digit ${digit}. `;\n explanation += `In Rows ${rows.map(r => r + 1).join(' and ')}, digit ${digit} appears only in Columns ${cols.map(c => c + 1).join(' and ')}. `;\n explanation += `This forms a rectangle where ${digit} must occupy two opposite corners. `;\n } else {\n explanation = `X-Wing found for digit ${digit}. `;\n explanation += `In Columns ${cols.map(c => c + 1).join(' and ')}, digit ${digit} appears only in Rows ${rows.map(r => r + 1).join(' and ')}. `;\n explanation += `This forms a rectangle where ${digit} must occupy two opposite corners. `;\n }\n\n if (elimCells.length > 0) {\n explanation += `Eliminate ${digit} from ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\n/**\n * Swordfish: A 3x3 fish pattern.\n */\nfunction explainSwordfish(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 6) return hint.text;\n\n const digit = formatDigit(getFirstValidDigit(highlightCells[0]?.digits));\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n const rows = [...new Set(cells.map(c => c.row))].sort((a, b) => a - b);\n const cols = [...new Set(cells.map(c => c.col))].sort((a, b) => a - b);\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n\n let explanation = `Swordfish found for digit ${digit}. `;\n explanation += `In Rows ${rows.map(r => r + 1).join(', ')}, digit ${digit} is restricted to Columns ${cols.map(c => c + 1).join(', ')}. `;\n explanation += `This 3×3 fish pattern means ${digit} must appear once per row in these columns. `;\n\n if (elimCells.length > 0) {\n explanation += `Eliminate ${digit} from other cells in these columns: ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\n/**\n * Jellyfish: A 4x4 fish pattern.\n */\nfunction explainJellyfish(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 8) return hint.text;\n\n const digit = formatDigit(getFirstValidDigit(highlightCells[0]?.digits));\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n const rows = [...new Set(cells.map(c => c.row))].sort((a, b) => a - b);\n const cols = [...new Set(cells.map(c => c.col))].sort((a, b) => a - b);\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n\n let explanation = `Jellyfish found for digit ${digit}. `;\n explanation += `In Rows ${rows.map(r => r + 1).join(', ')}, digit ${digit} is restricted to Columns ${cols.map(c => c + 1).join(', ')}. `;\n explanation += `This 4×4 fish pattern locks ${digit} within these intersections. `;\n\n if (elimCells.length > 0) {\n explanation += `Eliminate ${digit} from other cells in these columns: ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\n/**\n * Squirmbag: A 5x5 fish pattern.\n */\nfunction explainSquirmbag(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 10) return hint.text;\n\n const digit = formatDigit(getFirstValidDigit(highlightCells[0]?.digits));\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n const rows = [...new Set(cells.map(c => c.row))].sort((a, b) => a - b);\n const cols = [...new Set(cells.map(c => c.col))].sort((a, b) => a - b);\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n\n let explanation = `Squirmbag (5-fish) found for digit ${digit}. `;\n explanation += `Across Rows ${rows.map(r => r + 1).join(', ')}, digit ${digit} is confined to Columns ${cols.map(c => c + 1).join(', ')}. `;\n explanation += `This rare 5×5 fish pattern restricts ${digit} to these intersections. `;\n\n if (elimCells.length > 0) {\n explanation += `Eliminate ${digit} from ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\n/**\n * XY-Wing: Three cells forming a bent pattern with bivalve cells.\n */\nfunction explainXYWing(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 3) return hint.text;\n\n const cells = highlightCells\n .slice(0, 3)\n .map(c => ({ row: c.row, col: c.col }));\n const zDigit =\n removeCells.length > 0\n ? formatDigit(getFirstValidDigit(removeCells[0]?.digits))\n : '?';\n\n let explanation = `XY-Wing pattern found. `;\n explanation += `Three cells form a \"bent triple\": ${cellList(cells)}. `;\n explanation += `The pivot cell sees both wing cells, and each wing contains the digit ${zDigit}. `;\n explanation += `If the pivot takes one value, one wing gets ${zDigit}. If it takes the other, the other wing gets ${zDigit}. `;\n explanation += `Either way, ${zDigit} must appear in one of the wings. `;\n\n if (removeCells.length > 0) {\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n explanation += `Eliminate ${zDigit} from cells that see both wings: ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\n/**\n * XYZ-Wing: Similar to XY-Wing but pivot has 3 candidates (XYZ).\n */\nfunction explainXYZWing(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 3) return hint.text;\n\n const cells = highlightCells\n .slice(0, 3)\n .map(c => ({ row: c.row, col: c.col }));\n const zDigit =\n removeCells.length > 0\n ? formatDigit(getFirstValidDigit(removeCells[0]?.digits))\n : '?';\n\n let explanation = `XYZ-Wing pattern found. `;\n explanation += `The pivot cell has 3 candidates (XYZ), and two wing cells each have 2 candidates. `;\n explanation += `Cells: ${cellList(cells)}. `;\n explanation += `The digit ${zDigit} appears in all three pattern cells. `;\n explanation += `One of these cells MUST contain ${zDigit}. `;\n\n if (removeCells.length > 0) {\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n explanation += `Eliminate ${zDigit} from cells that see all three: ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\n/**\n * WXYZ-Wing: Four cells with four candidates total (WXYZ).\n */\nfunction explainWXYZWing(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 4) return hint.text;\n\n const cells = highlightCells\n .slice(0, 4)\n .map(c => ({ row: c.row, col: c.col }));\n const elimDigit =\n removeCells.length > 0\n ? formatDigit(getFirstValidDigit(removeCells[0]?.digits))\n : '?';\n\n const allDigits = new Set<string>();\n highlightCells.slice(0, 4).forEach(c => {\n for (const d of getValidDigits(c.digits)) allDigits.add(d);\n });\n\n let explanation = `WXYZ-Wing pattern found. `;\n explanation += `Four cells ${cellList(cells)} contain exactly 4 candidates: ${formatDigits(Array.from(allDigits))}. `;\n explanation += `One of these cells must contain ${elimDigit}. `;\n\n if (removeCells.length > 0) {\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n explanation += `Eliminate ${elimDigit} from cells that see all instances of ${elimDigit} in the pattern: ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\n/**\n * Finned X-Wing\n */\nfunction explainFinnedXWing(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 4) return hint.text;\n\n const digit = formatDigit(getFirstValidDigit(highlightCells[0]?.digits));\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n const rows = [...new Set(cells.map(c => c.row))].sort((a, b) => a - b);\n const cols = [...new Set(cells.map(c => c.col))].sort((a, b) => a - b);\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n\n let explanation = `Finned X-Wing for digit ${digit}. `;\n explanation += `An X-Wing pattern exists in Rows ${rows.map(r => r + 1).join(' and ')}, Columns ${cols\n .slice(0, 2)\n .map(c => c + 1)\n .join(' and ')}, `;\n explanation += `but with an extra \"fin\" candidate that breaks the perfect rectangle. `;\n explanation += `The fin limits eliminations to cells that see both the pattern and the fin. `;\n\n if (elimCells.length > 0) {\n explanation += `Eliminate ${digit} from ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\nfunction explainFinnedSwordfish(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 6) return hint.text;\n\n const digit = formatDigit(getFirstValidDigit(highlightCells[0]?.digits));\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n const rows = [...new Set(cells.map(c => c.row))].sort((a, b) => a - b);\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n\n let explanation = `Finned Swordfish for digit ${digit}. `;\n explanation += `A Swordfish pattern exists across Rows ${rows.map(r => r + 1).join(', ')}, `;\n explanation += `but with an extra \"fin\" that restricts eliminations. `;\n explanation += `Only cells seeing both the pattern and fin can have ${digit} eliminated. `;\n\n if (elimCells.length > 0) {\n explanation += `Eliminate ${digit} from ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\nfunction explainFinnedJellyfish(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 8) return hint.text;\n\n const digit = formatDigit(getFirstValidDigit(highlightCells[0]?.digits));\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n const rows = [...new Set(cells.map(c => c.row))].sort((a, b) => a - b);\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n\n let explanation = `Finned Jellyfish for digit ${digit}. `;\n explanation += `A Jellyfish pattern exists across Rows ${rows.map(r => r + 1).join(', ')}, `;\n explanation += `with an extra \"fin\" candidate. `;\n\n if (elimCells.length > 0) {\n explanation += `Eliminate ${digit} from ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\nfunction explainFinnedSquirmbag(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 10) return hint.text;\n\n const digit = formatDigit(getFirstValidDigit(highlightCells[0]?.digits));\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n const rows = [...new Set(cells.map(c => c.row))].sort((a, b) => a - b);\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n\n let explanation = `Finned Squirmbag (5-fish) for digit ${digit}. `;\n explanation += `A rare 5-fish pattern across Rows ${rows.map(r => r + 1).join(', ')}, with a fin. `;\n\n if (elimCells.length > 0) {\n explanation += `Eliminate ${digit} from ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\n/**\n * Almost Locked Sets (ALS)\n */\nfunction explainAlmostLockedSets(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 2) return hint.text;\n\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n const house = findCommonHouse(cells);\n const houseName = house?.name || 'their shared house';\n\n const alsDigits = new Set<string>();\n highlightCells.forEach(c => {\n for (const d of getValidDigits(c.digits)) alsDigits.add(d);\n });\n\n const n = highlightCells.length;\n const nPlus1 = alsDigits.size;\n\n let explanation = `Almost Locked Set (ALS) in ${houseName}. `;\n explanation += `Cells ${cellList(cells)} (${n} cells) contain ${nPlus1} candidates: ${formatDigits(Array.from(alsDigits))}. `;\n explanation += `Since there's one \"extra\" candidate, if ANY digit is removed externally, `;\n explanation += `the remaining ${n} candidates lock into these ${n} cells. `;\n\n if (removeCells.length > 0) {\n const elimDigits = new Set<string>();\n removeCells.forEach(c => {\n for (const d of getValidDigits(c.digits)) elimDigits.add(d);\n });\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n explanation += `Eliminate ${formatDigits(Array.from(elimDigits))} from ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\n/**\n * ALS-Chain (ALS-XZ)\n */\nfunction explainALSChain(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 4) return hint.text;\n\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n\n let explanation = `ALS-XZ (ALS-Chain) pattern. `;\n explanation += `Two Almost Locked Sets share a Restricted Common Candidate (RCC). `;\n explanation += `Pattern cells: ${cellList(cells)}. `;\n explanation += `The RCC can only be true in one ALS, which forces the other ALS to become fully locked. `;\n\n if (removeCells.length > 0) {\n const elimDigits = new Set<string>();\n removeCells.forEach(c => {\n for (const d of getValidDigits(c.digits)) elimDigits.add(d);\n });\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n explanation += `Eliminate ${formatDigits(Array.from(elimDigits))} from ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\n/**\n * Generic explanation for unknown or unsupported techniques.\n */\nfunction generateGenericExplanation(\n hint: SolverHintStep,\n selectCells: Array<{ row: number; col: number; digit: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n const parts: string[] = [];\n\n parts.push(hint.text);\n\n if (selectCells.length > 0) {\n const placements = selectCells.map(\n c => `${formatDigit(c.digit)} in ${cellName(c.row, c.col)}`\n );\n parts.push(`Place: ${placements.join(', ')}.`);\n }\n\n if (removeCells.length > 0) {\n const eliminations = removeCells.map(\n c => `${formatDigits(c.digits)} from ${cellName(c.row, c.col)}`\n );\n if (eliminations.length <= 5) {\n parts.push(`Eliminate: ${eliminations.join('; ')}.`);\n } else {\n parts.push(`Eliminate candidates from ${removeCells.length} cells.`);\n }\n }\n\n return parts.join(' ');\n}\n\n/**\n * Get a summary of the hint action (what to do)\n */\nexport function getHintActionSummary(\n hint: SolverHintStep,\n digitDisplay?: DigitDisplay\n): string {\n _display = digitDisplay ?? 'numeric';\n if (!hint.cells) return '';\n const selectCells = getSelectCells(hint);\n const removeCells = getRemoveCells(hint);\n\n if (selectCells.length > 0) {\n if (selectCells.length === 1) {\n const c = selectCells[0];\n if (!c) return 'Place a digit';\n return `Place ${formatDigit(c.digit)} in ${cellName(c.row, c.col)}`;\n }\n return `Place digits in ${selectCells.length} cells`;\n }\n\n if (removeCells.length > 0) {\n const allDigits = new Set<string>();\n removeCells.forEach(c => {\n for (const d of getValidDigits(c.digits)) allDigits.add(d);\n });\n return `Eliminate ${formatDigits(Array.from(allDigits))} from ${removeCells.length} cell${removeCells.length > 1 ? 's' : ''}`;\n }\n\n return 'Apply the technique';\n}\n"]}
|
|
1
|
+
{"version":3,"file":"hintExplanation.js","sourceRoot":"","sources":["../../src/utils/hintExplanation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Generate detailed hint explanations based on the hint payload\n * Similar to tutorial explanations but for live hints\n *\n * Each explanation is designed to teach the user WHY the technique works,\n * not just WHAT to do.\n */\n\nimport type { SolverHintCell, SolverHintStep } from '@sudobility/sudojo_types';\nimport { TechniqueId } from '@sudobility/sudojo_types';\nimport type { DigitDisplay } from '../types/settings';\nimport { displayDigit as mapDigitDisplay } from './digitDisplay';\nimport type { TranslateFunction } from './localizedHint';\n\n// Module-level display format, set by public entry points before calling internals.\nlet _display: DigitDisplay = 'numeric';\n\n// Cell notation (R1C1 format)\nfunction cellName(row: number, col: number): string {\n return `R${row + 1}C${col + 1}`;\n}\n\n// Format a list of cells\nfunction cellList(cells: Array<{ row: number; col: number }>): string {\n return cells.map(c => cellName(c.row, c.col)).join(', ');\n}\n\n// Format digit(s) - only valid Sudoku digits 1-9\n// Uses module-level _display set by public entry points.\nfunction formatDigit(d: string | number): string {\n const s = String(d);\n if (s < '1' || s > '9') return '?';\n if (_display !== 'numeric') {\n return mapDigitDisplay(parseInt(s, 10), _display);\n }\n return s;\n}\n\n// Format multiple digits as set - only valid Sudoku digits 1-9\nfunction formatDigits(digits: string | string[]): string {\n const arr = Array.isArray(digits)\n ? digits.filter(d => d >= '1' && d <= '9')\n : digits.split('').filter(d => d >= '1' && d <= '9');\n if (arr.length === 0) return '';\n if (arr.length === 1) return formatDigit(arr[0] ?? '');\n return `{${arr\n .sort()\n .map(d => formatDigit(d))\n .join(', ')}}`;\n}\n\n// Extract first valid Sudoku digit (1-9) from a string\nfunction getFirstValidDigit(digits: string | undefined): string {\n if (!digits) return '?';\n for (const d of digits) {\n if (d >= '1' && d <= '9') return d;\n }\n return '?';\n}\n\n// Extract all valid Sudoku digits (1-9) from a string\nfunction getValidDigits(digits: string | undefined): string[] {\n if (!digits) return [];\n return digits.split('').filter(d => d >= '1' && d <= '9');\n}\n\n// Get block number (1-9) from row/col\nfunction getBlock(row: number, col: number): number {\n return Math.floor(row / 3) * 3 + Math.floor(col / 3) + 1;\n}\n\n// Determine the common house for cells\nfunction findCommonHouse(\n cells: Array<{ row: number; col: number }>\n): { type: 'row' | 'col' | 'block'; index: number; name: string } | null {\n const first = cells[0];\n if (cells.length < 2 || !first) return null;\n\n const sameRow = cells.every(c => c.row === first.row);\n if (sameRow) {\n return { type: 'row', index: first.row, name: `Row ${first.row + 1}` };\n }\n\n const sameCol = cells.every(c => c.col === first.col);\n if (sameCol) {\n return { type: 'col', index: first.col, name: `Column ${first.col + 1}` };\n }\n\n const sameBlock = cells.every(\n c => getBlock(c.row, c.col) === getBlock(first.row, first.col)\n );\n if (sameBlock) {\n const block = getBlock(first.row, first.col);\n return { type: 'block', index: block, name: `Block ${block}` };\n }\n\n return null;\n}\n\n// Extract cells that have select action (digit placement)\n// Note: select: \"0\" means no selection (placeholder), only 1-9 are valid digits\nfunction getSelectCells(\n hint: SolverHintStep\n): Array<{ row: number; col: number; digit: string }> {\n return hint.cells\n .filter(\n (c: SolverHintCell) =>\n c.actions.select && c.actions.select !== '' && c.actions.select !== '0'\n )\n .map((c: SolverHintCell) => ({\n row: c.row,\n col: c.column,\n digit: c.actions.select,\n }));\n}\n\n// Extract cells that have remove action (eliminations)\n// Note: Filter out cells where remove only contains \"0\" (placeholder)\nfunction getRemoveCells(\n hint: SolverHintStep\n): Array<{ row: number; col: number; digits: string }> {\n return hint.cells\n .filter(\n (c: SolverHintCell) =>\n c.actions.remove &&\n c.actions.remove !== '' &&\n getValidDigits(c.actions.remove).length > 0\n )\n .map((c: SolverHintCell) => ({\n row: c.row,\n col: c.column,\n digits: c.actions.remove,\n }));\n}\n\n// Extract cells that have highlight action (pattern cells)\n// Note: Filter out cells where highlight only contains \"0\" (placeholder)\nfunction getHighlightCells(\n hint: SolverHintStep\n): Array<{ row: number; col: number; digits: string }> {\n return hint.cells\n .filter(\n (c: SolverHintCell) =>\n c.actions.highlight &&\n c.actions.highlight !== '' &&\n getValidDigits(c.actions.highlight).length > 0\n )\n .map((c: SolverHintCell) => ({\n row: c.row,\n col: c.column,\n digits: c.actions.highlight,\n }));\n}\n\n/**\n * Generate detailed explanation for a hint\n *\n * @param hint - The hint step data\n * @param techniqueId - The technique ID (from SolverHints.technique)\n * @param digitDisplay - Optional digit display format\n */\nexport function generateDetailedExplanation(\n hint: SolverHintStep,\n techniqueId?: number,\n digitDisplay?: DigitDisplay\n): string {\n _display = digitDisplay ?? 'numeric';\n const selectCells = getSelectCells(hint);\n const removeCells = getRemoveCells(hint);\n const highlightCells = getHighlightCells(hint);\n\n switch (techniqueId) {\n case TechniqueId.FULL_HOUSE:\n return explainFullHouse(hint, selectCells);\n\n case TechniqueId.HIDDEN_SINGLE:\n return explainHiddenSingle(hint, selectCells);\n\n case TechniqueId.NAKED_SINGLE:\n return explainNakedSingle(hint, selectCells);\n\n case TechniqueId.HIDDEN_PAIR:\n return explainHiddenPair(hint, highlightCells, removeCells);\n\n case TechniqueId.NAKED_PAIR:\n return explainNakedPair(hint, highlightCells, removeCells);\n\n case TechniqueId.LOCKED_CANDIDATES:\n return explainLockedCandidates(hint, highlightCells, removeCells);\n\n case TechniqueId.HIDDEN_TRIPLE:\n return explainHiddenTriple(hint, highlightCells, removeCells);\n\n case TechniqueId.NAKED_TRIPLE:\n return explainNakedTriple(hint, highlightCells, removeCells);\n\n case TechniqueId.HIDDEN_QUAD:\n return explainHiddenQuad(hint, highlightCells, removeCells);\n\n case TechniqueId.NAKED_QUAD:\n return explainNakedQuad(hint, highlightCells, removeCells);\n\n case TechniqueId.X_WING:\n return explainXWing(hint, highlightCells, removeCells);\n\n case TechniqueId.SWORDFISH:\n return explainSwordfish(hint, highlightCells, removeCells);\n\n case TechniqueId.JELLYFISH:\n return explainJellyfish(hint, highlightCells, removeCells);\n\n case TechniqueId.XY_WING:\n return explainXYWing(hint, highlightCells, removeCells);\n\n case TechniqueId.FINNED_X_WING:\n return explainFinnedXWing(hint, highlightCells, removeCells);\n\n case TechniqueId.SQUIRMBAG:\n return explainSquirmbag(hint, highlightCells, removeCells);\n\n case TechniqueId.FINNED_SWORDFISH:\n return explainFinnedSwordfish(hint, highlightCells, removeCells);\n\n case TechniqueId.FINNED_JELLYFISH:\n return explainFinnedJellyfish(hint, highlightCells, removeCells);\n\n case TechniqueId.XYZ_WING:\n return explainXYZWing(hint, highlightCells, removeCells);\n\n case TechniqueId.WXYZ_WING:\n return explainWXYZWing(hint, highlightCells, removeCells);\n\n case TechniqueId.ALMOST_LOCKED_SETS:\n return explainAlmostLockedSets(hint, highlightCells, removeCells);\n\n case TechniqueId.FINNED_SQUIRMBAG:\n return explainFinnedSquirmbag(hint, highlightCells, removeCells);\n\n case TechniqueId.ALS_CHAIN:\n case TechniqueId.ALS_XZ:\n return explainALSChain(hint, highlightCells, removeCells);\n\n default:\n return generateGenericExplanation(hint, selectCells, removeCells);\n }\n}\n\n/**\n * Full House: The last empty cell in a house.\n */\nfunction explainFullHouse(\n hint: SolverHintStep,\n selectCells: Array<{ row: number; col: number; digit: string }>\n): string {\n if (selectCells.length !== 1) return hint.text;\n\n const cell = selectCells[0];\n if (!cell) return hint.text;\n const digit = formatDigit(cell.digit);\n\n const area = hint.areas?.[0];\n let houseName = '';\n if (area) {\n if (area.type === 'row') houseName = `Row ${area.index + 1}`;\n else if (area.type === 'column') houseName = `Column ${area.index + 1}`;\n else if (area.type === 'block') houseName = `Block ${area.index + 1}`;\n }\n\n if (houseName) {\n return (\n `${houseName} has 8 cells filled, leaving only ${cellName(cell.row, cell.col)} empty. ` +\n `The missing digit is ${digit} — place it here.`\n );\n }\n\n return (\n `Cell ${cellName(cell.row, cell.col)} is the only empty cell in its house. ` +\n `Place ${digit} here.`\n );\n}\n\n/**\n * Hidden Single: A digit that can only go in one cell within a house.\n */\nfunction explainHiddenSingle(\n hint: SolverHintStep,\n selectCells: Array<{ row: number; col: number; digit: string }>\n): string {\n if (selectCells.length !== 1) return hint.text;\n\n const cell = selectCells[0];\n if (!cell) return hint.text;\n const digit = formatDigit(cell.digit);\n\n const area = hint.areas?.[0];\n let houseName: string;\n if (area) {\n houseName =\n area.type === 'row'\n ? `Row ${area.index + 1}`\n : area.type === 'column'\n ? `Column ${area.index + 1}`\n : `Block ${area.index + 1}`;\n } else {\n houseName = `Block ${getBlock(cell.row, cell.col)}`;\n }\n\n return (\n `In ${houseName}, digit ${digit} can only go in one cell: ${cellName(cell.row, cell.col)}. ` +\n `Even though this cell may have other candidates, ${digit} has no other place in ${houseName.toLowerCase()}. ` +\n `Place ${digit} here.`\n );\n}\n\n/**\n * Naked Single: A cell with only one candidate remaining.\n */\nfunction explainNakedSingle(\n hint: SolverHintStep,\n selectCells: Array<{ row: number; col: number; digit: string }>\n): string {\n if (selectCells.length !== 1) return hint.text;\n\n const cell = selectCells[0];\n if (!cell) return hint.text;\n const digit = formatDigit(cell.digit);\n\n return (\n `Cell ${cellName(cell.row, cell.col)} has only one candidate left: ${digit}. ` +\n `All other digits are eliminated by numbers already placed in its row, column, and block. ` +\n `Place ${digit} here.`\n );\n}\n\n/**\n * Hidden Pair: Two digits that can only appear in exactly two cells within a house.\n */\nfunction explainHiddenPair(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 2) return hint.text;\n\n const cells = highlightCells\n .slice(0, 2)\n .map(c => ({ row: c.row, col: c.col }));\n const house = findCommonHouse(cells);\n const houseName = house?.name || 'their house';\n\n const hiddenDigits = new Set<string>();\n highlightCells.slice(0, 2).forEach(c => {\n for (const d of getValidDigits(c.digits)) hiddenDigits.add(d);\n });\n const pairDigits = formatDigits(Array.from(hiddenDigits));\n\n const eliminations = removeCells.filter(c =>\n cells.some(hc => hc.row === c.row && hc.col === c.col)\n );\n\n let explanation = `In ${houseName}, digits ${pairDigits} can ONLY appear in ${cellList(cells)}. `;\n explanation += `These form a Hidden Pair — the pair is \"hidden\" among other candidates. `;\n explanation += `Since ${pairDigits} must occupy these 2 cells, `;\n\n if (eliminations.length > 0) {\n const elimDigits = new Set<string>();\n eliminations.forEach(e => {\n for (const d of getValidDigits(e.digits)) elimDigits.add(d);\n });\n explanation += `eliminate the other candidates ${formatDigits(Array.from(elimDigits))} from these cells.`;\n } else {\n explanation += `other candidates can be eliminated.`;\n }\n\n return explanation;\n}\n\n/**\n * Naked Pair: Two cells in a house that contain exactly the same two candidates.\n */\nfunction explainNakedPair(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 2) return hint.text;\n\n const cells = highlightCells\n .slice(0, 2)\n .map(c => ({ row: c.row, col: c.col }));\n const house = findCommonHouse(cells);\n const houseName = house?.name || 'their shared house';\n\n const pairDigits = formatDigits(getValidDigits(highlightCells[0]?.digits));\n\n let explanation = `Cells ${cellList(cells)} both contain exactly ${pairDigits} as their only candidates. `;\n explanation += `This is a Naked Pair — the pair is \"naked\" because these cells show only these digits. `;\n explanation += `Since ${pairDigits} must go in these cells, `;\n\n if (removeCells.length > 0) {\n const elimCells = removeCells\n .filter(c => !cells.some(pc => pc.row === c.row && pc.col === c.col))\n .map(c => ({ row: c.row, col: c.col }));\n if (elimCells.length > 0) {\n explanation += `eliminate ${pairDigits} from other cells in ${houseName.toLowerCase()}: ${cellList(elimCells)}.`;\n } else {\n explanation += `they can be eliminated from other cells in the house.`;\n }\n }\n\n return explanation;\n}\n\n/**\n * Locked Candidates (Pointing/Claiming)\n */\nfunction explainLockedCandidates(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 2) return hint.text;\n\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n const first = cells[0];\n if (!first) return hint.text;\n const lockedDigit = formatDigit(\n getFirstValidDigit(highlightCells[0]?.digits)\n );\n\n const sameRow = cells.every(c => c.row === first.row);\n const sameCol = cells.every(c => c.col === first.col);\n const sameBlock = cells.every(\n c => getBlock(c.row, c.col) === getBlock(first.row, first.col)\n );\n\n const block = getBlock(first.row, first.col);\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n const elimInSameBlock = elimCells.every(\n c => getBlock(c.row, c.col) === block\n );\n\n let explanation = '';\n\n if (sameBlock && (sameRow || sameCol)) {\n if (elimInSameBlock) {\n const lineName = sameRow\n ? `Row ${first.row + 1}`\n : `Column ${first.col + 1}`;\n explanation = `In ${lineName}, digit ${lockedDigit} can only appear in Block ${block} (cells ${cellList(cells)}). `;\n explanation += `This \"claims\" ${lockedDigit} for this line within the block. `;\n if (elimCells.length > 0) {\n explanation += `Eliminate ${lockedDigit} from other cells in Block ${block}: ${cellList(elimCells)}.`;\n }\n } else {\n const lineName = sameRow\n ? `Row ${first.row + 1}`\n : `Column ${first.col + 1}`;\n explanation = `In Block ${block}, digit ${lockedDigit} can only appear in ${lineName} (cells ${cellList(cells)}). `;\n explanation += `This \"points\" to ${lockedDigit} being restricted to this line. `;\n if (elimCells.length > 0) {\n explanation += `Eliminate ${lockedDigit} from ${cellList(elimCells)} in ${lineName} outside Block ${block}.`;\n }\n }\n } else if (sameRow) {\n explanation = `Digit ${lockedDigit} is locked to Row ${first.row + 1} in these cells: ${cellList(cells)}. `;\n if (elimCells.length > 0) {\n explanation += `Eliminate ${lockedDigit} from ${cellList(elimCells)}.`;\n }\n } else if (sameCol) {\n explanation = `Digit ${lockedDigit} is locked to Column ${first.col + 1} in these cells: ${cellList(cells)}. `;\n if (elimCells.length > 0) {\n explanation += `Eliminate ${lockedDigit} from ${cellList(elimCells)}.`;\n }\n } else {\n explanation = `Locked Candidates pattern for digit ${lockedDigit}. `;\n if (elimCells.length > 0) {\n explanation += `Eliminate ${lockedDigit} from ${cellList(elimCells)}.`;\n }\n }\n\n return explanation;\n}\n\n/**\n * Hidden Triple: Three digits that can only appear in exactly three cells within a house.\n */\nfunction explainHiddenTriple(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 3) return hint.text;\n\n const cells = highlightCells\n .slice(0, 3)\n .map(c => ({ row: c.row, col: c.col }));\n const house = findCommonHouse(cells);\n const houseName = house?.name || 'their house';\n\n const hiddenDigits = new Set<string>();\n highlightCells.slice(0, 3).forEach(c => {\n for (const d of getValidDigits(c.digits)) hiddenDigits.add(d);\n });\n const tripleDigits = formatDigits(Array.from(hiddenDigits));\n\n let explanation = `In ${houseName}, digits ${tripleDigits} can ONLY appear in cells ${cellList(cells)}. `;\n explanation += `This is a Hidden Triple — these 3 digits are \"hidden\" among other candidates. `;\n explanation += `Since ${tripleDigits} must occupy these 3 cells, `;\n\n if (removeCells.length > 0) {\n const elimDigits = new Set<string>();\n removeCells\n .filter(c => cells.some(hc => hc.row === c.row && hc.col === c.col))\n .forEach(e => {\n for (const d of getValidDigits(e.digits)) elimDigits.add(d);\n });\n if (elimDigits.size > 0) {\n explanation += `eliminate the other candidates ${formatDigits(Array.from(elimDigits))} from these cells.`;\n } else {\n explanation += `other candidates can be eliminated.`;\n }\n } else {\n explanation += `other candidates can be eliminated.`;\n }\n\n return explanation;\n}\n\n/**\n * Naked Triple: Three cells in a house that together contain only three candidates total.\n */\nfunction explainNakedTriple(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 3) return hint.text;\n\n const cells = highlightCells\n .slice(0, 3)\n .map(c => ({ row: c.row, col: c.col }));\n const house = findCommonHouse(cells);\n const houseName = house?.name || 'their house';\n\n const nakedDigits = new Set<string>();\n highlightCells.slice(0, 3).forEach(c => {\n for (const d of getValidDigits(c.digits)) nakedDigits.add(d);\n });\n const tripleDigits = formatDigits(Array.from(nakedDigits));\n\n let explanation = `Cells ${cellList(cells)} together contain only the candidates ${tripleDigits}. `;\n explanation += `This is a Naked Triple — these 3 cells share only 3 digits between them. `;\n explanation += `Since ${tripleDigits} must go in these cells, `;\n\n if (removeCells.length > 0) {\n const elimCells = removeCells.filter(\n c => !cells.some(nc => nc.row === c.row && nc.col === c.col)\n );\n if (elimCells.length > 0) {\n explanation += `eliminate ${tripleDigits} from other cells in ${houseName.toLowerCase()}: ${cellList(elimCells.map(c => ({ row: c.row, col: c.col })))}.`;\n } else {\n explanation += `they can be eliminated from other cells.`;\n }\n } else {\n explanation += `they can be eliminated from other cells.`;\n }\n\n return explanation;\n}\n\n/**\n * Hidden Quad: Four digits that can only appear in exactly four cells within a house.\n */\nfunction explainHiddenQuad(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 4) return hint.text;\n\n const cells = highlightCells\n .slice(0, 4)\n .map(c => ({ row: c.row, col: c.col }));\n const house = findCommonHouse(cells);\n const houseName = house?.name || 'their house';\n\n const hiddenDigits = new Set<string>();\n highlightCells.slice(0, 4).forEach(c => {\n for (const d of getValidDigits(c.digits)) hiddenDigits.add(d);\n });\n const quadDigits = formatDigits(Array.from(hiddenDigits));\n\n let explanation = `In ${houseName}, digits ${quadDigits} can ONLY appear in cells ${cellList(cells)}. `;\n explanation += `This is a Hidden Quad — 4 digits restricted to 4 cells. `;\n\n if (removeCells.length > 0) {\n const elimDigits = new Set<string>();\n removeCells\n .filter(c => cells.some(hc => hc.row === c.row && hc.col === c.col))\n .forEach(e => {\n for (const d of getValidDigits(e.digits)) elimDigits.add(d);\n });\n if (elimDigits.size > 0) {\n explanation += `Eliminate the other candidates ${formatDigits(Array.from(elimDigits))} from these cells.`;\n }\n }\n\n return explanation;\n}\n\n/**\n * Naked Quad: Four cells in a house that together contain only four candidates total.\n */\nfunction explainNakedQuad(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 4) return hint.text;\n\n const cells = highlightCells\n .slice(0, 4)\n .map(c => ({ row: c.row, col: c.col }));\n const house = findCommonHouse(cells);\n const houseName = house?.name || 'their house';\n\n const nakedDigits = new Set<string>();\n highlightCells.slice(0, 4).forEach(c => {\n for (const d of getValidDigits(c.digits)) nakedDigits.add(d);\n });\n const quadDigits = formatDigits(Array.from(nakedDigits));\n\n let explanation = `Cells ${cellList(cells)} together contain only the candidates ${quadDigits}. `;\n explanation += `This is a Naked Quad — 4 cells sharing only 4 digits. `;\n\n if (removeCells.length > 0) {\n const elimCells = removeCells.filter(\n c => !cells.some(nc => nc.row === c.row && nc.col === c.col)\n );\n if (elimCells.length > 0) {\n explanation += `Eliminate ${quadDigits} from other cells in ${houseName.toLowerCase()}: ${cellList(elimCells.map(c => ({ row: c.row, col: c.col })))}.`;\n }\n }\n\n return explanation;\n}\n\n/**\n * X-Wing: A 2x2 fish pattern.\n */\nfunction explainXWing(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 4) return hint.text;\n\n const digit = formatDigit(getFirstValidDigit(highlightCells[0]?.digits));\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n const rows = [...new Set(cells.map(c => c.row))].sort((a, b) => a - b);\n const cols = [...new Set(cells.map(c => c.col))].sort((a, b) => a - b);\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n\n const elimInCols =\n elimCells.length > 0 && elimCells.every(c => cols.includes(c.col));\n\n let explanation = '';\n if (elimInCols || rows.length === 2) {\n explanation = `X-Wing found for digit ${digit}. `;\n explanation += `In Rows ${rows.map(r => r + 1).join(' and ')}, digit ${digit} appears only in Columns ${cols.map(c => c + 1).join(' and ')}. `;\n explanation += `This forms a rectangle where ${digit} must occupy two opposite corners. `;\n } else {\n explanation = `X-Wing found for digit ${digit}. `;\n explanation += `In Columns ${cols.map(c => c + 1).join(' and ')}, digit ${digit} appears only in Rows ${rows.map(r => r + 1).join(' and ')}. `;\n explanation += `This forms a rectangle where ${digit} must occupy two opposite corners. `;\n }\n\n if (elimCells.length > 0) {\n explanation += `Eliminate ${digit} from ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\n/**\n * Swordfish: A 3x3 fish pattern.\n */\nfunction explainSwordfish(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 6) return hint.text;\n\n const digit = formatDigit(getFirstValidDigit(highlightCells[0]?.digits));\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n const rows = [...new Set(cells.map(c => c.row))].sort((a, b) => a - b);\n const cols = [...new Set(cells.map(c => c.col))].sort((a, b) => a - b);\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n\n let explanation = `Swordfish found for digit ${digit}. `;\n explanation += `In Rows ${rows.map(r => r + 1).join(', ')}, digit ${digit} is restricted to Columns ${cols.map(c => c + 1).join(', ')}. `;\n explanation += `This 3×3 fish pattern means ${digit} must appear once per row in these columns. `;\n\n if (elimCells.length > 0) {\n explanation += `Eliminate ${digit} from other cells in these columns: ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\n/**\n * Jellyfish: A 4x4 fish pattern.\n */\nfunction explainJellyfish(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 8) return hint.text;\n\n const digit = formatDigit(getFirstValidDigit(highlightCells[0]?.digits));\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n const rows = [...new Set(cells.map(c => c.row))].sort((a, b) => a - b);\n const cols = [...new Set(cells.map(c => c.col))].sort((a, b) => a - b);\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n\n let explanation = `Jellyfish found for digit ${digit}. `;\n explanation += `In Rows ${rows.map(r => r + 1).join(', ')}, digit ${digit} is restricted to Columns ${cols.map(c => c + 1).join(', ')}. `;\n explanation += `This 4×4 fish pattern locks ${digit} within these intersections. `;\n\n if (elimCells.length > 0) {\n explanation += `Eliminate ${digit} from other cells in these columns: ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\n/**\n * Squirmbag: A 5x5 fish pattern.\n */\nfunction explainSquirmbag(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 10) return hint.text;\n\n const digit = formatDigit(getFirstValidDigit(highlightCells[0]?.digits));\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n const rows = [...new Set(cells.map(c => c.row))].sort((a, b) => a - b);\n const cols = [...new Set(cells.map(c => c.col))].sort((a, b) => a - b);\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n\n let explanation = `Squirmbag (5-fish) found for digit ${digit}. `;\n explanation += `Across Rows ${rows.map(r => r + 1).join(', ')}, digit ${digit} is confined to Columns ${cols.map(c => c + 1).join(', ')}. `;\n explanation += `This rare 5×5 fish pattern restricts ${digit} to these intersections. `;\n\n if (elimCells.length > 0) {\n explanation += `Eliminate ${digit} from ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\n/**\n * XY-Wing: Three cells forming a bent pattern with bivalve cells.\n */\nfunction explainXYWing(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 3) return hint.text;\n\n const cells = highlightCells\n .slice(0, 3)\n .map(c => ({ row: c.row, col: c.col }));\n const zDigit =\n removeCells.length > 0\n ? formatDigit(getFirstValidDigit(removeCells[0]?.digits))\n : '?';\n\n let explanation = `XY-Wing pattern found. `;\n explanation += `Three cells form a \"bent triple\": ${cellList(cells)}. `;\n explanation += `The pivot cell sees both wing cells, and each wing contains the digit ${zDigit}. `;\n explanation += `If the pivot takes one value, one wing gets ${zDigit}. If it takes the other, the other wing gets ${zDigit}. `;\n explanation += `Either way, ${zDigit} must appear in one of the wings. `;\n\n if (removeCells.length > 0) {\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n explanation += `Eliminate ${zDigit} from cells that see both wings: ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\n/**\n * XYZ-Wing: Similar to XY-Wing but pivot has 3 candidates (XYZ).\n */\nfunction explainXYZWing(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 3) return hint.text;\n\n const cells = highlightCells\n .slice(0, 3)\n .map(c => ({ row: c.row, col: c.col }));\n const zDigit =\n removeCells.length > 0\n ? formatDigit(getFirstValidDigit(removeCells[0]?.digits))\n : '?';\n\n let explanation = `XYZ-Wing pattern found. `;\n explanation += `The pivot cell has 3 candidates (XYZ), and two wing cells each have 2 candidates. `;\n explanation += `Cells: ${cellList(cells)}. `;\n explanation += `The digit ${zDigit} appears in all three pattern cells. `;\n explanation += `One of these cells MUST contain ${zDigit}. `;\n\n if (removeCells.length > 0) {\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n explanation += `Eliminate ${zDigit} from cells that see all three: ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\n/**\n * WXYZ-Wing: Four cells with four candidates total (WXYZ).\n */\nfunction explainWXYZWing(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 4) return hint.text;\n\n const cells = highlightCells\n .slice(0, 4)\n .map(c => ({ row: c.row, col: c.col }));\n const elimDigit =\n removeCells.length > 0\n ? formatDigit(getFirstValidDigit(removeCells[0]?.digits))\n : '?';\n\n const allDigits = new Set<string>();\n highlightCells.slice(0, 4).forEach(c => {\n for (const d of getValidDigits(c.digits)) allDigits.add(d);\n });\n\n let explanation = `WXYZ-Wing pattern found. `;\n explanation += `Four cells ${cellList(cells)} contain exactly 4 candidates: ${formatDigits(Array.from(allDigits))}. `;\n explanation += `One of these cells must contain ${elimDigit}. `;\n\n if (removeCells.length > 0) {\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n explanation += `Eliminate ${elimDigit} from cells that see all instances of ${elimDigit} in the pattern: ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\n/**\n * Finned X-Wing\n */\nfunction explainFinnedXWing(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 4) return hint.text;\n\n const digit = formatDigit(getFirstValidDigit(highlightCells[0]?.digits));\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n const rows = [...new Set(cells.map(c => c.row))].sort((a, b) => a - b);\n const cols = [...new Set(cells.map(c => c.col))].sort((a, b) => a - b);\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n\n let explanation = `Finned X-Wing for digit ${digit}. `;\n explanation += `An X-Wing pattern exists in Rows ${rows.map(r => r + 1).join(' and ')}, Columns ${cols\n .slice(0, 2)\n .map(c => c + 1)\n .join(' and ')}, `;\n explanation += `but with an extra \"fin\" candidate that breaks the perfect rectangle. `;\n explanation += `The fin limits eliminations to cells that see both the pattern and the fin. `;\n\n if (elimCells.length > 0) {\n explanation += `Eliminate ${digit} from ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\nfunction explainFinnedSwordfish(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 6) return hint.text;\n\n const digit = formatDigit(getFirstValidDigit(highlightCells[0]?.digits));\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n const rows = [...new Set(cells.map(c => c.row))].sort((a, b) => a - b);\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n\n let explanation = `Finned Swordfish for digit ${digit}. `;\n explanation += `A Swordfish pattern exists across Rows ${rows.map(r => r + 1).join(', ')}, `;\n explanation += `but with an extra \"fin\" that restricts eliminations. `;\n explanation += `Only cells seeing both the pattern and fin can have ${digit} eliminated. `;\n\n if (elimCells.length > 0) {\n explanation += `Eliminate ${digit} from ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\nfunction explainFinnedJellyfish(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 8) return hint.text;\n\n const digit = formatDigit(getFirstValidDigit(highlightCells[0]?.digits));\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n const rows = [...new Set(cells.map(c => c.row))].sort((a, b) => a - b);\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n\n let explanation = `Finned Jellyfish for digit ${digit}. `;\n explanation += `A Jellyfish pattern exists across Rows ${rows.map(r => r + 1).join(', ')}, `;\n explanation += `with an extra \"fin\" candidate. `;\n\n if (elimCells.length > 0) {\n explanation += `Eliminate ${digit} from ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\nfunction explainFinnedSquirmbag(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 10) return hint.text;\n\n const digit = formatDigit(getFirstValidDigit(highlightCells[0]?.digits));\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n const rows = [...new Set(cells.map(c => c.row))].sort((a, b) => a - b);\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n\n let explanation = `Finned Squirmbag (5-fish) for digit ${digit}. `;\n explanation += `A rare 5-fish pattern across Rows ${rows.map(r => r + 1).join(', ')}, with a fin. `;\n\n if (elimCells.length > 0) {\n explanation += `Eliminate ${digit} from ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\n/**\n * Almost Locked Sets (ALS)\n */\nfunction explainAlmostLockedSets(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 2) return hint.text;\n\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n const house = findCommonHouse(cells);\n const houseName = house?.name || 'their shared house';\n\n const alsDigits = new Set<string>();\n highlightCells.forEach(c => {\n for (const d of getValidDigits(c.digits)) alsDigits.add(d);\n });\n\n const n = highlightCells.length;\n const nPlus1 = alsDigits.size;\n\n let explanation = `Almost Locked Set (ALS) in ${houseName}. `;\n explanation += `Cells ${cellList(cells)} (${n} cells) contain ${nPlus1} candidates: ${formatDigits(Array.from(alsDigits))}. `;\n explanation += `Since there's one \"extra\" candidate, if ANY digit is removed externally, `;\n explanation += `the remaining ${n} candidates lock into these ${n} cells. `;\n\n if (removeCells.length > 0) {\n const elimDigits = new Set<string>();\n removeCells.forEach(c => {\n for (const d of getValidDigits(c.digits)) elimDigits.add(d);\n });\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n explanation += `Eliminate ${formatDigits(Array.from(elimDigits))} from ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\n/**\n * ALS-Chain (ALS-XZ)\n */\nfunction explainALSChain(\n hint: SolverHintStep,\n highlightCells: Array<{ row: number; col: number; digits: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n if (highlightCells.length < 4) return hint.text;\n\n const cells = highlightCells.map(c => ({ row: c.row, col: c.col }));\n\n let explanation = `ALS-XZ (ALS-Chain) pattern. `;\n explanation += `Two Almost Locked Sets share a Restricted Common Candidate (RCC). `;\n explanation += `Pattern cells: ${cellList(cells)}. `;\n explanation += `The RCC can only be true in one ALS, which forces the other ALS to become fully locked. `;\n\n if (removeCells.length > 0) {\n const elimDigits = new Set<string>();\n removeCells.forEach(c => {\n for (const d of getValidDigits(c.digits)) elimDigits.add(d);\n });\n const elimCells = removeCells.map(c => ({ row: c.row, col: c.col }));\n explanation += `Eliminate ${formatDigits(Array.from(elimDigits))} from ${cellList(elimCells)}.`;\n }\n\n return explanation;\n}\n\n/**\n * Generic explanation for unknown or unsupported techniques.\n */\nfunction generateGenericExplanation(\n hint: SolverHintStep,\n selectCells: Array<{ row: number; col: number; digit: string }>,\n removeCells: Array<{ row: number; col: number; digits: string }>\n): string {\n const parts: string[] = [];\n\n parts.push(hint.text);\n\n if (selectCells.length > 0) {\n const placements = selectCells.map(\n c => `${formatDigit(c.digit)} in ${cellName(c.row, c.col)}`\n );\n parts.push(`Place: ${placements.join(', ')}.`);\n }\n\n if (removeCells.length > 0) {\n const eliminations = removeCells.map(\n c => `${formatDigits(c.digits)} from ${cellName(c.row, c.col)}`\n );\n if (eliminations.length <= 5) {\n parts.push(`Eliminate: ${eliminations.join('; ')}.`);\n } else {\n parts.push(`Eliminate candidates from ${removeCells.length} cells.`);\n }\n }\n\n return parts.join(' ');\n}\n\n/**\n * Get a summary of the hint action (what to do)\n */\nexport function getHintActionSummary(\n hint: SolverHintStep,\n digitDisplay?: DigitDisplay,\n t?: TranslateFunction\n): string {\n _display = digitDisplay ?? 'numeric';\n if (!hint.cells) return '';\n const selectCells = getSelectCells(hint);\n const removeCells = getRemoveCells(hint);\n\n if (selectCells.length > 0) {\n if (selectCells.length === 1) {\n const c = selectCells[0];\n if (!c) {\n return t\n ? t('hintAction.placeDigit', { defaultValue: 'Place a digit' })\n : 'Place a digit';\n }\n const digit = formatDigit(c.digit);\n const cell = cellName(c.row, c.col);\n return t\n ? t('hintAction.placeInCell', {\n defaultValue: `Place ${digit} in ${cell}`,\n digit,\n cell,\n })\n : `Place ${digit} in ${cell}`;\n }\n const count = String(selectCells.length);\n return t\n ? t('hintAction.placeInCells', {\n defaultValue: `Place digits in ${count} cells`,\n count,\n })\n : `Place digits in ${selectCells.length} cells`;\n }\n\n if (removeCells.length > 0) {\n const allDigits = new Set<string>();\n removeCells.forEach(c => {\n for (const d of getValidDigits(c.digits)) allDigits.add(d);\n });\n const digits = formatDigits(Array.from(allDigits));\n const count = String(removeCells.length);\n const suffix = removeCells.length > 1 ? 's' : '';\n return t\n ? t('hintAction.eliminate', {\n defaultValue: `Eliminate ${digits} from ${count} cell${suffix}`,\n digits,\n count,\n })\n : `Eliminate ${digits} from ${count} cell${suffix}`;\n }\n\n return t\n ? t('hintAction.applyTechnique', {\n defaultValue: 'Apply the technique',\n })\n : 'Apply the technique';\n}\n"]}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export { convertPackageToProduct, parseCustomerInfo, getPeriodDisplayName, isBes
|
|
|
15
15
|
export { getTechniqueIconUrl } from './technique';
|
|
16
16
|
export { generateDetailedExplanation, getHintActionSummary, } from './hintExplanation';
|
|
17
17
|
export type { TranslateFunction } from './localizedHint';
|
|
18
|
-
export { getLocalizedHintText, getLocalizedHintTitle } from './localizedHint';
|
|
18
|
+
export { getLocalizedHintText, getLocalizedHintTitle, localizedField, } from './localizedHint';
|
|
19
19
|
export { getBeltKey, getLocalizedBeltName, getBeltLabelKey, getLocalizedBeltLabel, getLevelKey, getLocalizedLevelTitle, getTechniqueKey, getLocalizedTechniqueName, } from './i18nKeys';
|
|
20
20
|
export { displayDigit } from './digitDisplay';
|
|
21
21
|
export type { ShareUrlParams, ParsedShareParams } from './shareUrl';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,gBAAgB,GACjB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAGtB,YAAY,EACV,iBAAiB,EACjB,cAAc,IAAI,oBAAoB,GACvC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,SAAS,EACT,YAAY,EACZ,aAAa,IAAI,mBAAmB,EACpC,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,yBAAyB,EACzB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAG/C,OAAO,EACL,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,sBAAsB,GACvB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGlD,OAAO,EACL,2BAA2B,EAC3B,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,gBAAgB,GACjB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAGtB,YAAY,EACV,iBAAiB,EACjB,cAAc,IAAI,oBAAoB,GACvC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,SAAS,EACT,YAAY,EACZ,aAAa,IAAI,mBAAmB,EACpC,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,yBAAyB,EACzB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAG/C,OAAO,EACL,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,sBAAsB,GACvB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGlD,OAAO,EACL,2BAA2B,EAC3B,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,GACf,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,eAAe,EACf,qBAAqB,EACrB,WAAW,EACX,sBAAsB,EACtB,eAAe,EACf,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGxE,YAAY,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC"}
|
package/dist/utils/index.js
CHANGED
|
@@ -18,7 +18,7 @@ export { convertPackageToProduct, parseCustomerInfo, getPeriodDisplayName, isBes
|
|
|
18
18
|
export { getTechniqueIconUrl } from './technique';
|
|
19
19
|
// Hint explanation utilities
|
|
20
20
|
export { generateDetailedExplanation, getHintActionSummary, } from './hintExplanation';
|
|
21
|
-
export { getLocalizedHintText, getLocalizedHintTitle } from './localizedHint';
|
|
21
|
+
export { getLocalizedHintText, getLocalizedHintTitle, localizedField, } from './localizedHint';
|
|
22
22
|
// i18n key utilities
|
|
23
23
|
export { getBeltKey, getLocalizedBeltName, getBeltLabelKey, getLocalizedBeltLabel, getLevelKey, getLocalizedLevelTitle, getTechniqueKey, getLocalizedTechniqueName, } from './i18nKeys';
|
|
24
24
|
// Digit display utilities
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,8CAA8C;AAC9C,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,gBAAgB,GACjB,MAAM,SAAS,CAAC;AAEjB,mDAAmD;AACnD,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAOtB,OAAO,EACL,SAAS,EACT,YAAY,EACZ,aAAa,IAAI,mBAAmB,EACpC,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,yBAAyB,EACzB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAE3B,iBAAiB;AACjB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAE/C,qBAAqB;AACrB,OAAO,EACL,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAIpB,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,sBAAsB,GACvB,MAAM,SAAS,CAAC;AAEjB,yBAAyB;AACzB,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC;AAExB,sBAAsB;AACtB,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,6BAA6B;AAC7B,OAAO,EACL,2BAA2B,EAC3B,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAI3B,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,8CAA8C;AAC9C,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,gBAAgB,GACjB,MAAM,SAAS,CAAC;AAEjB,mDAAmD;AACnD,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAOtB,OAAO,EACL,SAAS,EACT,YAAY,EACZ,aAAa,IAAI,mBAAmB,EACpC,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,yBAAyB,EACzB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAE3B,iBAAiB;AACjB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAE/C,qBAAqB;AACrB,OAAO,EACL,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAIpB,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,sBAAsB,GACvB,MAAM,SAAS,CAAC;AAEjB,yBAAyB;AACzB,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC;AAExB,sBAAsB;AACtB,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,6BAA6B;AAC7B,OAAO,EACL,2BAA2B,EAC3B,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,GACf,MAAM,iBAAiB,CAAC;AAEzB,qBAAqB;AACrB,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,eAAe,EACf,qBAAqB,EACrB,WAAW,EACX,sBAAsB,EACtB,eAAe,EACf,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AAEpB,0BAA0B;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAI9C,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAIxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC","sourcesContent":["/**\n * Utility exports for Sudojo library\n */\n\n// Board utilities (legacy - for useGame hook)\nexport {\n cloneBoard,\n countFilledCells,\n createGameBoard,\n getBlockCells,\n getBlockIndex,\n getBoardStateString,\n getColumnCells,\n getEmptyCells,\n getPencilmarksString,\n getRelatedCells,\n getRowCells,\n isValidPlacement,\n} from './board';\n\n// Validation utilities (legacy - for useGame hook)\nexport {\n autoRemovePencilmarks,\n clearHighlights,\n countMistakes,\n getIncorrectCells,\n getProgressPercentage,\n isBoardFilled,\n isCellCorrect,\n isGameComplete,\n isValueCorrect,\n updateCellErrors,\n updateCellHighlights,\n validateGameState,\n} from './validation';\n\n// Sudoku scrambler utilities (for useSudoku hook - ported from renderable)\nexport type {\n ScramblerProtocol,\n ScrambleResult as SudokuScrambleResult,\n} from './sudokuScrambler';\nexport {\n Scrambler,\n NonScrambler,\n scrambleBoard as scrambleSudokuBoard,\n parsePuzzleString,\n cellsToPuzzleString,\n cellsToStateString,\n cellsToInputString,\n cellsToPencilmarksString,\n} from './sudokuScrambler';\n\n// Sudoku presenter (for rendering - matches Kotlin renderable)\nexport type { PresentBoardOptions } from './sudokuPresenter';\nexport {\n presentBoard,\n calculateCellHints,\n themeColorToCSS,\n getColorPalette,\n getCellsWithDigit,\n getSelectedDigit,\n computeSelectedDigitCells,\n convertSolverLink,\n convertSolverCellGroup,\n sudokuColorToTheme,\n} from './sudokuPresenter';\n\n// Time utilities\nexport { formatTime, parseTime } from './time';\n\n// Progress utilities\nexport {\n calculateStats,\n calculateStreak,\n isPuzzleCompleted,\n getCompletedLevelIds,\n getCompletedDailyDates,\n} from './progress';\n\n// Theme utilities\nexport type { ThemePreference, ResolvedTheme } from './theme';\nexport {\n THEME_STORAGE_KEY,\n getSystemTheme,\n resolveTheme,\n isValidThemePreference,\n} from './theme';\n\n// Subscription utilities\nexport {\n convertPackageToProduct,\n parseCustomerInfo,\n getPeriodDisplayName,\n isBestValuePlan,\n getRevenueCatErrorMessage,\n} from './subscription';\n\n// Technique utilities\nexport { getTechniqueIconUrl } from './technique';\n\n// Hint explanation utilities\nexport {\n generateDetailedExplanation,\n getHintActionSummary,\n} from './hintExplanation';\n\n// Localized hint utilities\nexport type { TranslateFunction } from './localizedHint';\nexport {\n getLocalizedHintText,\n getLocalizedHintTitle,\n localizedField,\n} from './localizedHint';\n\n// i18n key utilities\nexport {\n getBeltKey,\n getLocalizedBeltName,\n getBeltLabelKey,\n getLocalizedBeltLabel,\n getLevelKey,\n getLocalizedLevelTitle,\n getTechniqueKey,\n getLocalizedTechniqueName,\n} from './i18nKeys';\n\n// Digit display utilities\nexport { displayDigit } from './digitDisplay';\n\n// Share URL utilities\nexport type { ShareUrlParams, ParsedShareParams } from './shareUrl';\nexport { buildShareUrl, parseShareParams, getWebUrl } from './shareUrl';\n\n// Auth utilities\nexport type { AuthUser } from './auth';\nexport { isAuthenticatedUser } from './auth';\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SolverHintStep } from '@sudobility/sudojo_types';
|
|
1
|
+
import type { LocalizedHint, SolverHintStep } from '@sudobility/sudojo_types';
|
|
2
2
|
/**
|
|
3
3
|
* A translation function that takes a key and interpolation values.
|
|
4
4
|
* Compatible with i18next's `t` function.
|
|
@@ -25,5 +25,14 @@ export declare function getLocalizedHintText(t: TranslateFunction, step: SolverH
|
|
|
25
25
|
* @param step - The hint step containing localization data
|
|
26
26
|
* @param keyPrefix - Optional prefix to prepend to the string key
|
|
27
27
|
*/
|
|
28
|
+
/**
|
|
29
|
+
* Resolve a localized field value using the API-provided string key.
|
|
30
|
+
* Falls back to the raw value if translation is missing.
|
|
31
|
+
*
|
|
32
|
+
* @param t - Translation function (e.g. from `useTranslation()`)
|
|
33
|
+
* @param loc - LocalizedHint from API response (stringKey + values)
|
|
34
|
+
* @param fallback - Raw value from API to use if translation is missing
|
|
35
|
+
*/
|
|
36
|
+
export declare function localizedField(t: TranslateFunction, loc: LocalizedHint | undefined, fallback: string | null | undefined): string;
|
|
28
37
|
export declare function getLocalizedHintTitle(t: TranslateFunction, step: SolverHintStep, keyPrefix?: string): string;
|
|
29
38
|
//# sourceMappingURL=localizedHint.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localizedHint.d.ts","sourceRoot":"","sources":["../../src/utils/localizedHint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"localizedHint.d.ts","sourceRoot":"","sources":["../../src/utils/localizedHint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE9E;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAC9B,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC5B,MAAM,CAAC;AA0DZ;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,CAAC,EAAE,iBAAiB,EACpB,IAAI,EAAE,cAAc,EACpB,SAAS,GAAE,MAAW,GACrB,MAAM,CAGR;AAED;;;;;;;GAOG;AACH;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,CAAC,EAAE,iBAAiB,EACpB,GAAG,EAAE,aAAa,GAAG,SAAS,EAC9B,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAClC,MAAM,CAER;AAED,wBAAgB,qBAAqB,CACnC,CAAC,EAAE,iBAAiB,EACpB,IAAI,EAAE,cAAc,EACpB,SAAS,GAAE,MAAW,GACrB,MAAM,CAGR"}
|
|
@@ -65,6 +65,17 @@ export function getLocalizedHintText(t, step, keyPrefix = '') {
|
|
|
65
65
|
* @param step - The hint step containing localization data
|
|
66
66
|
* @param keyPrefix - Optional prefix to prepend to the string key
|
|
67
67
|
*/
|
|
68
|
+
/**
|
|
69
|
+
* Resolve a localized field value using the API-provided string key.
|
|
70
|
+
* Falls back to the raw value if translation is missing.
|
|
71
|
+
*
|
|
72
|
+
* @param t - Translation function (e.g. from `useTranslation()`)
|
|
73
|
+
* @param loc - LocalizedHint from API response (stringKey + values)
|
|
74
|
+
* @param fallback - Raw value from API to use if translation is missing
|
|
75
|
+
*/
|
|
76
|
+
export function localizedField(t, loc, fallback) {
|
|
77
|
+
return resolveLocalization(t, loc, fallback ?? '');
|
|
78
|
+
}
|
|
68
79
|
export function getLocalizedHintTitle(t, step, keyPrefix = '') {
|
|
69
80
|
const loc = step.localization;
|
|
70
81
|
return resolveLocalization(t, loc?.title, step.title, keyPrefix);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localizedHint.js","sourceRoot":"","sources":["../../src/utils/localizedHint.ts"],"names":[],"mappings":"AAWA;;;GAGG;AACH,SAAS,qBAAqB,CAAC,MAAgB;IAC7C,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QAC9B,MAAM,CAAC,QAAQ,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;IACtC,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAC1B,CAAoB,EACpB,GAA8B,EAC9B,QAAgB,EAChB,YAAoB,EAAE;IAEtB,IAAI,CAAC,GAAG,EAAE,SAAS;QAAE,OAAO,QAAQ,CAAC;IAErC,MAAM,aAAa,GAAG,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;IAC1C,MAAM,UAAU,GAAG,CAAC,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAE7C,4EAA4E;IAC5E,IAAI,UAAU,KAAK,OAAO;QAAE,OAAO,QAAQ,CAAC;IAC5C,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,IAAoB;IAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,YAGJ,CAAC;IAEd,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAE3B,yDAAyD;IACzD,IAAI,GAAG,CAAC,IAAI,EAAE,SAAS;QAAE,OAAO,GAAG,CAAC,IAAI,CAAC;IAEzC,kDAAkD;IAClD,IAAI,WAAW,IAAI,GAAG,IAAK,GAAqB,CAAC,SAAS,EAAE,CAAC;QAC3D,OAAO,GAA+B,CAAC;IACzC,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,oBAAoB,CAClC,CAAoB,EACpB,IAAoB,EACpB,YAAoB,EAAE;IAEtB,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,mBAAmB,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CACnC,CAAoB,EACpB,IAAoB,EACpB,YAAoB,EAAE;IAEtB,MAAM,GAAG,GAAG,IAAI,CAAC,YAAqD,CAAC;IACvE,OAAO,mBAAmB,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;AACnE,CAAC","sourcesContent":["import type { LocalizedHint, SolverHintStep } from '@sudobility/sudojo_types';\n\n/**\n * A translation function that takes a key and interpolation values.\n * Compatible with i18next's `t` function.\n */\nexport type TranslateFunction = (\n key: string,\n values?: Record<string, string>\n) => string;\n\n/**\n * Convert localization values array to i18next interpolation object.\n * values: [\"3\", \"R1C5\"] → { value1: \"3\", value2: \"R1C5\" }\n */\nfunction valuesToInterpolation(values: string[]): Record<string, string> {\n const result: Record<string, string> = {};\n values.forEach((value, index) => {\n result[`value${index + 1}`] = value;\n });\n return result;\n}\n\n/**\n * Resolve a LocalizedHint to translated text, falling back to the raw value.\n */\nfunction resolveLocalization(\n t: TranslateFunction,\n loc: LocalizedHint | undefined,\n fallback: string,\n keyPrefix: string = ''\n): string {\n if (!loc?.stringKey) return fallback;\n\n const interpolation = valuesToInterpolation(loc.values);\n const fullKey = keyPrefix + loc.stringKey;\n const translated = t(fullKey, interpolation);\n\n // If translation returns the key itself (missing translation), use fallback\n if (translated === fullKey) return fallback;\n return translated;\n}\n\n/**\n * Extract the text LocalizedHint from a hint step's localization field.\n * Handles both the new structured format { text?: LocalizedHint }\n * and the old flat format (LocalizedHint directly) for backward compatibility.\n */\nfunction getTextLocalization(step: SolverHintStep): LocalizedHint | undefined {\n const loc = step.localization as\n | { text?: LocalizedHint; title?: LocalizedHint }\n | (LocalizedHint & { text?: never })\n | undefined;\n\n if (!loc) return undefined;\n\n // New structured format: { text: { stringKey, values } }\n if (loc.text?.stringKey) return loc.text;\n\n // Old flat format: { stringKey, values } directly\n if ('stringKey' in loc && (loc as LocalizedHint).stringKey) {\n return loc as unknown as LocalizedHint;\n }\n\n return undefined;\n}\n\n/**\n * Get localized text for a hint step using a provided translation function.\n * Returns the translated text with interpolated values,\n * or falls back to step.text if localization is unavailable.\n *\n * Handles both new structured format { text?: LocalizedHint, title?: LocalizedHint }\n * and old flat format (LocalizedHint directly) for backward compatibility.\n *\n * @param t - Translation function (e.g. from `useTranslation('hints')`)\n * @param step - The hint step containing localization data\n * @param keyPrefix - Optional prefix to prepend to the string key (e.g. 'hints.')\n */\nexport function getLocalizedHintText(\n t: TranslateFunction,\n step: SolverHintStep,\n keyPrefix: string = ''\n): string {\n const textLoc = getTextLocalization(step);\n return resolveLocalization(t, textLoc, step.text, keyPrefix);\n}\n\n/**\n * Get localized title for a hint step (technique name).\n * Returns the translated title or falls back to step.title.\n *\n * @param t - Translation function (e.g. from `useTranslation()` for common namespace)\n * @param step - The hint step containing localization data\n * @param keyPrefix - Optional prefix to prepend to the string key\n */\nexport function getLocalizedHintTitle(\n t: TranslateFunction,\n step: SolverHintStep,\n keyPrefix: string = ''\n): string {\n const loc = step.localization as { title?: LocalizedHint } | undefined;\n return resolveLocalization(t, loc?.title, step.title, keyPrefix);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"localizedHint.js","sourceRoot":"","sources":["../../src/utils/localizedHint.ts"],"names":[],"mappings":"AAWA;;;GAGG;AACH,SAAS,qBAAqB,CAAC,MAAgB;IAC7C,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QAC9B,MAAM,CAAC,QAAQ,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;IACtC,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAC1B,CAAoB,EACpB,GAA8B,EAC9B,QAAgB,EAChB,YAAoB,EAAE;IAEtB,IAAI,CAAC,GAAG,EAAE,SAAS;QAAE,OAAO,QAAQ,CAAC;IAErC,MAAM,aAAa,GAAG,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;IAC1C,MAAM,UAAU,GAAG,CAAC,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAE7C,4EAA4E;IAC5E,IAAI,UAAU,KAAK,OAAO;QAAE,OAAO,QAAQ,CAAC;IAC5C,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,IAAoB;IAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,YAGJ,CAAC;IAEd,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAE3B,yDAAyD;IACzD,IAAI,GAAG,CAAC,IAAI,EAAE,SAAS;QAAE,OAAO,GAAG,CAAC,IAAI,CAAC;IAEzC,kDAAkD;IAClD,IAAI,WAAW,IAAI,GAAG,IAAK,GAAqB,CAAC,SAAS,EAAE,CAAC;QAC3D,OAAO,GAA+B,CAAC;IACzC,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,oBAAoB,CAClC,CAAoB,EACpB,IAAoB,EACpB,YAAoB,EAAE;IAEtB,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,mBAAmB,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;;GAOG;AACH;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,CAAoB,EACpB,GAA8B,EAC9B,QAAmC;IAEnC,OAAO,mBAAmB,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,CAAoB,EACpB,IAAoB,EACpB,YAAoB,EAAE;IAEtB,MAAM,GAAG,GAAG,IAAI,CAAC,YAAqD,CAAC;IACvE,OAAO,mBAAmB,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;AACnE,CAAC","sourcesContent":["import type { LocalizedHint, SolverHintStep } from '@sudobility/sudojo_types';\n\n/**\n * A translation function that takes a key and interpolation values.\n * Compatible with i18next's `t` function.\n */\nexport type TranslateFunction = (\n key: string,\n values?: Record<string, string>\n) => string;\n\n/**\n * Convert localization values array to i18next interpolation object.\n * values: [\"3\", \"R1C5\"] → { value1: \"3\", value2: \"R1C5\" }\n */\nfunction valuesToInterpolation(values: string[]): Record<string, string> {\n const result: Record<string, string> = {};\n values.forEach((value, index) => {\n result[`value${index + 1}`] = value;\n });\n return result;\n}\n\n/**\n * Resolve a LocalizedHint to translated text, falling back to the raw value.\n */\nfunction resolveLocalization(\n t: TranslateFunction,\n loc: LocalizedHint | undefined,\n fallback: string,\n keyPrefix: string = ''\n): string {\n if (!loc?.stringKey) return fallback;\n\n const interpolation = valuesToInterpolation(loc.values);\n const fullKey = keyPrefix + loc.stringKey;\n const translated = t(fullKey, interpolation);\n\n // If translation returns the key itself (missing translation), use fallback\n if (translated === fullKey) return fallback;\n return translated;\n}\n\n/**\n * Extract the text LocalizedHint from a hint step's localization field.\n * Handles both the new structured format { text?: LocalizedHint }\n * and the old flat format (LocalizedHint directly) for backward compatibility.\n */\nfunction getTextLocalization(step: SolverHintStep): LocalizedHint | undefined {\n const loc = step.localization as\n | { text?: LocalizedHint; title?: LocalizedHint }\n | (LocalizedHint & { text?: never })\n | undefined;\n\n if (!loc) return undefined;\n\n // New structured format: { text: { stringKey, values } }\n if (loc.text?.stringKey) return loc.text;\n\n // Old flat format: { stringKey, values } directly\n if ('stringKey' in loc && (loc as LocalizedHint).stringKey) {\n return loc as unknown as LocalizedHint;\n }\n\n return undefined;\n}\n\n/**\n * Get localized text for a hint step using a provided translation function.\n * Returns the translated text with interpolated values,\n * or falls back to step.text if localization is unavailable.\n *\n * Handles both new structured format { text?: LocalizedHint, title?: LocalizedHint }\n * and old flat format (LocalizedHint directly) for backward compatibility.\n *\n * @param t - Translation function (e.g. from `useTranslation('hints')`)\n * @param step - The hint step containing localization data\n * @param keyPrefix - Optional prefix to prepend to the string key (e.g. 'hints.')\n */\nexport function getLocalizedHintText(\n t: TranslateFunction,\n step: SolverHintStep,\n keyPrefix: string = ''\n): string {\n const textLoc = getTextLocalization(step);\n return resolveLocalization(t, textLoc, step.text, keyPrefix);\n}\n\n/**\n * Get localized title for a hint step (technique name).\n * Returns the translated title or falls back to step.title.\n *\n * @param t - Translation function (e.g. from `useTranslation()` for common namespace)\n * @param step - The hint step containing localization data\n * @param keyPrefix - Optional prefix to prepend to the string key\n */\n/**\n * Resolve a localized field value using the API-provided string key.\n * Falls back to the raw value if translation is missing.\n *\n * @param t - Translation function (e.g. from `useTranslation()`)\n * @param loc - LocalizedHint from API response (stringKey + values)\n * @param fallback - Raw value from API to use if translation is missing\n */\nexport function localizedField(\n t: TranslateFunction,\n loc: LocalizedHint | undefined,\n fallback: string | null | undefined\n): string {\n return resolveLocalization(t, loc, fallback ?? '');\n}\n\nexport function getLocalizedHintTitle(\n t: TranslateFunction,\n step: SolverHintStep,\n keyPrefix: string = ''\n): string {\n const loc = step.localization as { title?: LocalizedHint } | undefined;\n return resolveLocalization(t, loc?.title, step.title, keyPrefix);\n}\n"]}
|