@sudobility/sudojo_lib 0.0.4
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/hooks/index.d.ts +27 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +27 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/useDailyGame.d.ts +64 -0
- package/dist/hooks/useDailyGame.d.ts.map +1 -0
- package/dist/hooks/useDailyGame.js +120 -0
- package/dist/hooks/useDailyGame.js.map +1 -0
- package/dist/hooks/useGame.d.ts +104 -0
- package/dist/hooks/useGame.d.ts.map +1 -0
- package/dist/hooks/useGame.js +546 -0
- package/dist/hooks/useGame.js.map +1 -0
- package/dist/hooks/useGamePersistence.d.ts +63 -0
- package/dist/hooks/useGamePersistence.d.ts.map +1 -0
- package/dist/hooks/useGamePersistence.js +124 -0
- package/dist/hooks/useGamePersistence.js.map +1 -0
- package/dist/hooks/useGameTeaching.d.ts +89 -0
- package/dist/hooks/useGameTeaching.d.ts.map +1 -0
- package/dist/hooks/useGameTeaching.js +230 -0
- package/dist/hooks/useGameTeaching.js.map +1 -0
- package/dist/hooks/useGameTimer.d.ts +43 -0
- package/dist/hooks/useGameTimer.d.ts.map +1 -0
- package/dist/hooks/useGameTimer.js +68 -0
- package/dist/hooks/useGameTimer.js.map +1 -0
- package/dist/hooks/useHint.d.ts +105 -0
- package/dist/hooks/useHint.d.ts.map +1 -0
- package/dist/hooks/useHint.js +179 -0
- package/dist/hooks/useHint.js.map +1 -0
- package/dist/hooks/useLearning.d.ts +100 -0
- package/dist/hooks/useLearning.d.ts.map +1 -0
- package/dist/hooks/useLearning.js +127 -0
- package/dist/hooks/useLearning.js.map +1 -0
- package/dist/hooks/useLevelGame.d.ts +68 -0
- package/dist/hooks/useLevelGame.d.ts.map +1 -0
- package/dist/hooks/useLevelGame.js +128 -0
- package/dist/hooks/useLevelGame.js.map +1 -0
- package/dist/hooks/useLevels.d.ts +93 -0
- package/dist/hooks/useLevels.d.ts.map +1 -0
- package/dist/hooks/useLevels.js +98 -0
- package/dist/hooks/useLevels.js.map +1 -0
- package/dist/hooks/useLocalStorage.d.ts +26 -0
- package/dist/hooks/useLocalStorage.d.ts.map +1 -0
- package/dist/hooks/useLocalStorage.js +75 -0
- package/dist/hooks/useLocalStorage.js.map +1 -0
- package/dist/hooks/useSudoku.d.ts +125 -0
- package/dist/hooks/useSudoku.d.ts.map +1 -0
- package/dist/hooks/useSudoku.js +655 -0
- package/dist/hooks/useSudoku.js.map +1 -0
- package/dist/hooks/useTechniques.d.ts +92 -0
- package/dist/hooks/useTechniques.d.ts.map +1 -0
- package/dist/hooks/useTechniques.js +108 -0
- package/dist/hooks/useTechniques.js.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +64 -0
- package/dist/index.js.map +1 -0
- package/dist/test/setup.d.ts +2 -0
- package/dist/test/setup.d.ts.map +1 -0
- package/dist/test/setup.js +35 -0
- package/dist/test/setup.js.map +1 -0
- package/dist/types/display.d.ts +142 -0
- package/dist/types/display.d.ts.map +1 -0
- package/dist/types/display.js +94 -0
- package/dist/types/display.js.map +1 -0
- package/dist/types/game.d.ts +201 -0
- package/dist/types/game.d.ts.map +1 -0
- package/dist/types/game.js +26 -0
- package/dist/types/game.js.map +1 -0
- package/dist/types/gamePersistence.d.ts +31 -0
- package/dist/types/gamePersistence.d.ts.map +1 -0
- package/dist/types/gamePersistence.js +15 -0
- package/dist/types/gamePersistence.js.map +1 -0
- package/dist/types/index.d.ts +18 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +11 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/progress.d.ts +43 -0
- package/dist/types/progress.d.ts.map +1 -0
- package/dist/types/progress.js +19 -0
- package/dist/types/progress.js.map +1 -0
- package/dist/types/settings.d.ts +19 -0
- package/dist/types/settings.d.ts.map +1 -0
- package/dist/types/settings.js +12 -0
- package/dist/types/settings.js.map +1 -0
- package/dist/types/subscription.d.ts +27 -0
- package/dist/types/subscription.d.ts.map +1 -0
- package/dist/types/subscription.js +8 -0
- package/dist/types/subscription.js.map +1 -0
- package/dist/types/sudoku.d.ts +147 -0
- package/dist/types/sudoku.d.ts.map +1 -0
- package/dist/types/sudoku.js +125 -0
- package/dist/types/sudoku.js.map +1 -0
- package/dist/utils/auth.d.ts +25 -0
- package/dist/utils/auth.d.ts.map +1 -0
- package/dist/utils/auth.js +47 -0
- package/dist/utils/auth.js.map +1 -0
- package/dist/utils/board.d.ts +116 -0
- package/dist/utils/board.d.ts.map +1 -0
- package/dist/utils/board.js +291 -0
- package/dist/utils/board.js.map +1 -0
- package/dist/utils/index.d.ts +18 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +23 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/progress.d.ts +44 -0
- package/dist/utils/progress.d.ts.map +1 -0
- package/dist/utils/progress.js +104 -0
- package/dist/utils/progress.js.map +1 -0
- package/dist/utils/scramble.d.ts +35 -0
- package/dist/utils/scramble.d.ts.map +1 -0
- package/dist/utils/scramble.js +270 -0
- package/dist/utils/scramble.js.map +1 -0
- package/dist/utils/subscription.d.ts +82 -0
- package/dist/utils/subscription.d.ts.map +1 -0
- package/dist/utils/subscription.js +117 -0
- package/dist/utils/subscription.js.map +1 -0
- package/dist/utils/sudokuPresenter.d.ts +62 -0
- package/dist/utils/sudokuPresenter.d.ts.map +1 -0
- package/dist/utils/sudokuPresenter.js +403 -0
- package/dist/utils/sudokuPresenter.js.map +1 -0
- package/dist/utils/sudokuScrambler.d.ts +61 -0
- package/dist/utils/sudokuScrambler.d.ts.map +1 -0
- package/dist/utils/sudokuScrambler.js +223 -0
- package/dist/utils/sudokuScrambler.js.map +1 -0
- package/dist/utils/technique.d.ts +41 -0
- package/dist/utils/technique.d.ts.map +1 -0
- package/dist/utils/technique.js +106 -0
- package/dist/utils/technique.js.map +1 -0
- package/dist/utils/theme.d.ts +31 -0
- package/dist/utils/theme.d.ts.map +1 -0
- package/dist/utils/theme.js +40 -0
- package/dist/utils/theme.js.map +1 -0
- package/dist/utils/time.d.ts +22 -0
- package/dist/utils/time.d.ts.map +1 -0
- package/dist/utils/time.js +41 -0
- package/dist/utils/time.js.map +1 -0
- package/dist/utils/validation.d.ts +107 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +248 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sudoku game types - ported from renderable/sudokuschool
|
|
3
|
+
*
|
|
4
|
+
* Uses flat 81-cell array (indexed 0-80) matching Kotlin implementation
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Get row index (0-8) from cell index (0-80)
|
|
8
|
+
*/
|
|
9
|
+
export function rowOf(index) {
|
|
10
|
+
return Math.floor(index / 9);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Get column index (0-8) from cell index (0-80)
|
|
14
|
+
*/
|
|
15
|
+
export function columnOf(index) {
|
|
16
|
+
return index % 9;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get block index (0-8) from cell index (0-80)
|
|
20
|
+
*/
|
|
21
|
+
export function blockOf(index) {
|
|
22
|
+
const blockY = Math.floor(rowOf(index) / 3);
|
|
23
|
+
const blockX = Math.floor(columnOf(index) / 3);
|
|
24
|
+
return blockY * 3 + blockX;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Get cell index from row and column
|
|
28
|
+
*/
|
|
29
|
+
export function cellIndex(row, column) {
|
|
30
|
+
return row * 9 + column;
|
|
31
|
+
}
|
|
32
|
+
// =============================================================================
|
|
33
|
+
// Defaults
|
|
34
|
+
// =============================================================================
|
|
35
|
+
export const DEFAULT_PLAY_SETTINGS = {
|
|
36
|
+
pencilmarking: false,
|
|
37
|
+
autoPencilmarks: false,
|
|
38
|
+
};
|
|
39
|
+
export const DEFAULT_APP_SETTINGS = {
|
|
40
|
+
showErrors: true,
|
|
41
|
+
enableAnimations: true,
|
|
42
|
+
symmetrical: false,
|
|
43
|
+
display: 'NUMERIC',
|
|
44
|
+
};
|
|
45
|
+
// =============================================================================
|
|
46
|
+
// Helper Functions
|
|
47
|
+
// =============================================================================
|
|
48
|
+
/**
|
|
49
|
+
* Create an empty cell
|
|
50
|
+
*/
|
|
51
|
+
export function createEmptyCell(index) {
|
|
52
|
+
return {
|
|
53
|
+
index,
|
|
54
|
+
solution: null,
|
|
55
|
+
given: null,
|
|
56
|
+
input: null,
|
|
57
|
+
pencilmarks: null,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Create an empty board (81 empty cells)
|
|
62
|
+
*/
|
|
63
|
+
export function createEmptyBoard() {
|
|
64
|
+
return {
|
|
65
|
+
cells: Array.from({ length: 81 }, (_, i) => createEmptyCell(i)),
|
|
66
|
+
completed: false,
|
|
67
|
+
entering: false,
|
|
68
|
+
enteringError: null,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Check if a cell has an error (input doesn't match solution)
|
|
73
|
+
*/
|
|
74
|
+
export function cellHasError(cell) {
|
|
75
|
+
if (cell.given !== null)
|
|
76
|
+
return false; // Clue cells can't have errors
|
|
77
|
+
if (cell.input === null)
|
|
78
|
+
return false; // Empty cells can't have errors
|
|
79
|
+
if (cell.solution === null)
|
|
80
|
+
return false; // No solution to compare
|
|
81
|
+
return cell.input !== cell.solution;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get all cell indices in the same row
|
|
85
|
+
*/
|
|
86
|
+
export function getRowIndices(index) {
|
|
87
|
+
const row = rowOf(index);
|
|
88
|
+
return Array.from({ length: 9 }, (_, col) => row * 9 + col);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get all cell indices in the same column
|
|
92
|
+
*/
|
|
93
|
+
export function getColumnIndices(index) {
|
|
94
|
+
const col = columnOf(index);
|
|
95
|
+
return Array.from({ length: 9 }, (_, row) => row * 9 + col);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get all cell indices in the same block
|
|
99
|
+
*/
|
|
100
|
+
export function getBlockIndices(index) {
|
|
101
|
+
const blockIndex = blockOf(index);
|
|
102
|
+
const blockX = blockIndex % 3;
|
|
103
|
+
const blockY = Math.floor(blockIndex / 3);
|
|
104
|
+
const indices = [];
|
|
105
|
+
for (let i = 0; i < 9; i++) {
|
|
106
|
+
const cellX = i % 3;
|
|
107
|
+
const cellY = Math.floor(i / 3);
|
|
108
|
+
const x = blockX * 3 + cellX;
|
|
109
|
+
const y = blockY * 3 + cellY;
|
|
110
|
+
indices.push(y * 9 + x);
|
|
111
|
+
}
|
|
112
|
+
return indices;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get all related cell indices (same row, column, or block)
|
|
116
|
+
*/
|
|
117
|
+
export function getRelatedIndices(index) {
|
|
118
|
+
const rowIndices = getRowIndices(index);
|
|
119
|
+
const colIndices = getColumnIndices(index);
|
|
120
|
+
const blockIndices = getBlockIndices(index);
|
|
121
|
+
const allIndices = new Set([...rowIndices, ...colIndices, ...blockIndices]);
|
|
122
|
+
allIndices.delete(index); // Remove the cell itself
|
|
123
|
+
return Array.from(allIndices);
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=sudoku.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sudoku.js","sourceRoot":"","sources":["../../src/types/sudoku.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication utilities
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Get user-friendly error message from Firebase error code
|
|
6
|
+
*
|
|
7
|
+
* @param code - Firebase error code (e.g., 'auth/user-not-found')
|
|
8
|
+
* @returns User-friendly error message
|
|
9
|
+
*/
|
|
10
|
+
export declare function getFirebaseErrorMessage(code: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Extract error code from Firebase error
|
|
13
|
+
*
|
|
14
|
+
* @param error - Error object from Firebase
|
|
15
|
+
* @returns Error code string or empty string if not found
|
|
16
|
+
*/
|
|
17
|
+
export declare function getFirebaseErrorCode(error: unknown): string;
|
|
18
|
+
/**
|
|
19
|
+
* Get user-friendly message from Firebase error object
|
|
20
|
+
*
|
|
21
|
+
* @param error - Error object from Firebase
|
|
22
|
+
* @returns User-friendly error message
|
|
23
|
+
*/
|
|
24
|
+
export declare function formatFirebaseError(error: unknown): string;
|
|
25
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAeH;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI5D;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAK3D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAG1D"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication utilities
|
|
3
|
+
*/
|
|
4
|
+
/** Map of Firebase auth error codes to user-friendly messages */
|
|
5
|
+
const FIREBASE_ERROR_MESSAGES = {
|
|
6
|
+
'auth/user-not-found': 'No account found with this email',
|
|
7
|
+
'auth/wrong-password': 'Incorrect password',
|
|
8
|
+
'auth/invalid-email': 'Invalid email address',
|
|
9
|
+
'auth/invalid-credential': 'Invalid email or password',
|
|
10
|
+
'auth/email-already-in-use': 'An account with this email already exists',
|
|
11
|
+
'auth/weak-password': 'Password must be at least 6 characters',
|
|
12
|
+
'auth/too-many-requests': 'Too many attempts. Please try again later.',
|
|
13
|
+
'auth/network-request-failed': 'Network error. Please check your connection.',
|
|
14
|
+
'auth/popup-closed-by-user': 'Sign in cancelled',
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Get user-friendly error message from Firebase error code
|
|
18
|
+
*
|
|
19
|
+
* @param code - Firebase error code (e.g., 'auth/user-not-found')
|
|
20
|
+
* @returns User-friendly error message
|
|
21
|
+
*/
|
|
22
|
+
export function getFirebaseErrorMessage(code) {
|
|
23
|
+
return (FIREBASE_ERROR_MESSAGES[code] ?? 'Something went wrong. Please try again.');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Extract error code from Firebase error
|
|
27
|
+
*
|
|
28
|
+
* @param error - Error object from Firebase
|
|
29
|
+
* @returns Error code string or empty string if not found
|
|
30
|
+
*/
|
|
31
|
+
export function getFirebaseErrorCode(error) {
|
|
32
|
+
if (error && typeof error === 'object' && 'code' in error) {
|
|
33
|
+
return error.code;
|
|
34
|
+
}
|
|
35
|
+
return '';
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get user-friendly message from Firebase error object
|
|
39
|
+
*
|
|
40
|
+
* @param error - Error object from Firebase
|
|
41
|
+
* @returns User-friendly error message
|
|
42
|
+
*/
|
|
43
|
+
export function formatFirebaseError(error) {
|
|
44
|
+
const code = getFirebaseErrorCode(error);
|
|
45
|
+
return getFirebaseErrorMessage(code);
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,iEAAiE;AACjE,MAAM,uBAAuB,GAA2B;IACtD,qBAAqB,EAAE,kCAAkC;IACzD,qBAAqB,EAAE,oBAAoB;IAC3C,oBAAoB,EAAE,uBAAuB;IAC7C,yBAAyB,EAAE,2BAA2B;IACtD,2BAA2B,EAAE,2CAA2C;IACxE,oBAAoB,EAAE,wCAAwC;IAC9D,wBAAwB,EAAE,4CAA4C;IACtE,6BAA6B,EAAE,8CAA8C;IAC7E,2BAA2B,EAAE,mBAAmB;CACjD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,OAAO,CACL,uBAAuB,CAAC,IAAI,CAAC,IAAI,yCAAyC,CAC3E,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;QAC1D,OAAQ,KAA0B,CAAC,IAAI,CAAC;IAC1C,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,MAAM,IAAI,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IACzC,OAAO,uBAAuB,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Board utilities for parsing, stringifying, and manipulating Sudoku boards
|
|
3
|
+
*/
|
|
4
|
+
import type { GameBoard } from '../types';
|
|
5
|
+
/**
|
|
6
|
+
* Board size constants
|
|
7
|
+
*/
|
|
8
|
+
export declare const BOARD_SIZE = 9;
|
|
9
|
+
export declare const BLOCK_SIZE = 3;
|
|
10
|
+
export declare const TOTAL_CELLS: number;
|
|
11
|
+
/**
|
|
12
|
+
* Parses an 81-character board string into a 2D array of numbers
|
|
13
|
+
* @param boardString - 81-character string where '0' or '.' represents empty cells
|
|
14
|
+
* @returns 9x9 array of numbers (0 = empty, 1-9 = filled)
|
|
15
|
+
*/
|
|
16
|
+
export declare function parseBoardString(boardString: string): number[][];
|
|
17
|
+
/**
|
|
18
|
+
* Converts a 2D number array back to an 81-character string
|
|
19
|
+
* @param board - 9x9 array of numbers
|
|
20
|
+
* @returns 81-character string
|
|
21
|
+
*/
|
|
22
|
+
export declare function stringifyBoard(board: number[][]): string;
|
|
23
|
+
/**
|
|
24
|
+
* Creates an initial GameBoard from puzzle and solution strings
|
|
25
|
+
* @param puzzle - 81-character puzzle string
|
|
26
|
+
* @param solution - 81-character solution string
|
|
27
|
+
* @returns GameBoard with initialized cell states
|
|
28
|
+
*/
|
|
29
|
+
export declare function createGameBoard(puzzle: string, solution: string): GameBoard;
|
|
30
|
+
/**
|
|
31
|
+
* Gets the current board state as a string (user's current progress)
|
|
32
|
+
* @param board - GameBoard
|
|
33
|
+
* @returns 81-character string representing current state
|
|
34
|
+
*/
|
|
35
|
+
export declare function getBoardStateString(board: GameBoard): string;
|
|
36
|
+
/**
|
|
37
|
+
* Gets the pencilmarks as a comma-separated string for the solver API
|
|
38
|
+
* @param board - GameBoard
|
|
39
|
+
* @returns Comma-separated string of pencilmarks for each cell
|
|
40
|
+
*/
|
|
41
|
+
export declare function getPencilmarksString(board: GameBoard): string;
|
|
42
|
+
/**
|
|
43
|
+
* Gets the block index (0-8) for a cell position
|
|
44
|
+
* @param row - Row index (0-8)
|
|
45
|
+
* @param col - Column index (0-8)
|
|
46
|
+
* @returns Block index (0-8)
|
|
47
|
+
*/
|
|
48
|
+
export declare function getBlockIndex(row: number, col: number): number;
|
|
49
|
+
/**
|
|
50
|
+
* Gets all cells in the same row
|
|
51
|
+
* @param row - Row index (0-8)
|
|
52
|
+
* @returns Array of {row, column} positions
|
|
53
|
+
*/
|
|
54
|
+
export declare function getRowCells(row: number): Array<{
|
|
55
|
+
row: number;
|
|
56
|
+
column: number;
|
|
57
|
+
}>;
|
|
58
|
+
/**
|
|
59
|
+
* Gets all cells in the same column
|
|
60
|
+
* @param col - Column index (0-8)
|
|
61
|
+
* @returns Array of {row, column} positions
|
|
62
|
+
*/
|
|
63
|
+
export declare function getColumnCells(col: number): Array<{
|
|
64
|
+
row: number;
|
|
65
|
+
column: number;
|
|
66
|
+
}>;
|
|
67
|
+
/**
|
|
68
|
+
* Gets all cells in the same block
|
|
69
|
+
* @param blockIndex - Block index (0-8)
|
|
70
|
+
* @returns Array of {row, column} positions
|
|
71
|
+
*/
|
|
72
|
+
export declare function getBlockCells(blockIndex: number): Array<{
|
|
73
|
+
row: number;
|
|
74
|
+
column: number;
|
|
75
|
+
}>;
|
|
76
|
+
/**
|
|
77
|
+
* Gets all related cells (same row, column, or block)
|
|
78
|
+
* @param row - Row index
|
|
79
|
+
* @param col - Column index
|
|
80
|
+
* @returns Array of {row, column} positions (excluding the cell itself)
|
|
81
|
+
*/
|
|
82
|
+
export declare function getRelatedCells(row: number, col: number): Array<{
|
|
83
|
+
row: number;
|
|
84
|
+
column: number;
|
|
85
|
+
}>;
|
|
86
|
+
/**
|
|
87
|
+
* Checks if a value is valid for a cell position (not checking solution, just Sudoku rules)
|
|
88
|
+
* @param board - GameBoard
|
|
89
|
+
* @param row - Row index
|
|
90
|
+
* @param col - Column index
|
|
91
|
+
* @param value - Value to check (1-9)
|
|
92
|
+
* @returns true if the value doesn't conflict with existing values
|
|
93
|
+
*/
|
|
94
|
+
export declare function isValidPlacement(board: GameBoard, row: number, col: number, value: number): boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Clones a GameBoard (deep copy)
|
|
97
|
+
* @param board - GameBoard to clone
|
|
98
|
+
* @returns New GameBoard with copied values
|
|
99
|
+
*/
|
|
100
|
+
export declare function cloneBoard(board: GameBoard): GameBoard;
|
|
101
|
+
/**
|
|
102
|
+
* Gets all empty cells in the board
|
|
103
|
+
* @param board - GameBoard
|
|
104
|
+
* @returns Array of {row, column} positions
|
|
105
|
+
*/
|
|
106
|
+
export declare function getEmptyCells(board: GameBoard): Array<{
|
|
107
|
+
row: number;
|
|
108
|
+
column: number;
|
|
109
|
+
}>;
|
|
110
|
+
/**
|
|
111
|
+
* Counts the number of filled cells
|
|
112
|
+
* @param board - GameBoard
|
|
113
|
+
* @returns Number of filled cells
|
|
114
|
+
*/
|
|
115
|
+
export declare function countFilledCells(board: GameBoard): number;
|
|
116
|
+
//# sourceMappingURL=board.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board.d.ts","sourceRoot":"","sources":["../../src/utils/board.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAa,SAAS,EAAE,MAAM,UAAU,CAAC;AAErD;;GAEG;AACH,eAAO,MAAM,UAAU,IAAI,CAAC;AAC5B,eAAO,MAAM,UAAU,IAAI,CAAC;AAC5B,eAAO,MAAM,WAAW,QAA0B,CAAC;AAEnD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,CAyBhE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,CAuBxD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,CA0B3E;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAS5D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAc7D;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAI9D;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,GACV,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAMxC;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,GACV,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAMxC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,MAAM,GACjB,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAaxC;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,GACV,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA0BxC;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,EAChB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GACZ,OAAO,CA+BT;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CAOtD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,SAAS,GACf,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAUxC;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAUzD"}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Board utilities for parsing, stringifying, and manipulating Sudoku boards
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Board size constants
|
|
6
|
+
*/
|
|
7
|
+
export const BOARD_SIZE = 9;
|
|
8
|
+
export const BLOCK_SIZE = 3;
|
|
9
|
+
export const TOTAL_CELLS = BOARD_SIZE * BOARD_SIZE;
|
|
10
|
+
/**
|
|
11
|
+
* Parses an 81-character board string into a 2D array of numbers
|
|
12
|
+
* @param boardString - 81-character string where '0' or '.' represents empty cells
|
|
13
|
+
* @returns 9x9 array of numbers (0 = empty, 1-9 = filled)
|
|
14
|
+
*/
|
|
15
|
+
export function parseBoardString(boardString) {
|
|
16
|
+
if (boardString.length !== TOTAL_CELLS) {
|
|
17
|
+
throw new Error(`Invalid board string length: expected ${TOTAL_CELLS}, got ${boardString.length}`);
|
|
18
|
+
}
|
|
19
|
+
const board = [];
|
|
20
|
+
for (let row = 0; row < BOARD_SIZE; row++) {
|
|
21
|
+
const rowArray = [];
|
|
22
|
+
for (let col = 0; col < BOARD_SIZE; col++) {
|
|
23
|
+
const index = row * BOARD_SIZE + col;
|
|
24
|
+
const char = boardString[index];
|
|
25
|
+
if (char === undefined) {
|
|
26
|
+
throw new Error(`Missing character at position ${index}`);
|
|
27
|
+
}
|
|
28
|
+
const value = char === '.' ? 0 : parseInt(char, 10);
|
|
29
|
+
if (isNaN(value) || value < 0 || value > 9) {
|
|
30
|
+
throw new Error(`Invalid character at position ${index}: '${char}'`);
|
|
31
|
+
}
|
|
32
|
+
rowArray.push(value);
|
|
33
|
+
}
|
|
34
|
+
board.push(rowArray);
|
|
35
|
+
}
|
|
36
|
+
return board;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Converts a 2D number array back to an 81-character string
|
|
40
|
+
* @param board - 9x9 array of numbers
|
|
41
|
+
* @returns 81-character string
|
|
42
|
+
*/
|
|
43
|
+
export function stringifyBoard(board) {
|
|
44
|
+
if (board.length !== BOARD_SIZE) {
|
|
45
|
+
throw new Error(`Invalid board rows: expected ${BOARD_SIZE}, got ${board.length}`);
|
|
46
|
+
}
|
|
47
|
+
let result = '';
|
|
48
|
+
for (let row = 0; row < BOARD_SIZE; row++) {
|
|
49
|
+
if (board[row]?.length !== BOARD_SIZE) {
|
|
50
|
+
throw new Error(`Invalid row ${row} length: expected ${BOARD_SIZE}, got ${board[row]?.length}`);
|
|
51
|
+
}
|
|
52
|
+
for (let col = 0; col < BOARD_SIZE; col++) {
|
|
53
|
+
const value = board[row]?.[col];
|
|
54
|
+
if (value === undefined || value < 0 || value > 9) {
|
|
55
|
+
throw new Error(`Invalid value at (${row}, ${col}): ${value}`);
|
|
56
|
+
}
|
|
57
|
+
result += value.toString();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Creates an initial GameBoard from puzzle and solution strings
|
|
64
|
+
* @param puzzle - 81-character puzzle string
|
|
65
|
+
* @param solution - 81-character solution string
|
|
66
|
+
* @returns GameBoard with initialized cell states
|
|
67
|
+
*/
|
|
68
|
+
export function createGameBoard(puzzle, solution) {
|
|
69
|
+
const puzzleArray = parseBoardString(puzzle);
|
|
70
|
+
// Validate solution string (will throw if invalid)
|
|
71
|
+
parseBoardString(solution);
|
|
72
|
+
const board = [];
|
|
73
|
+
for (let row = 0; row < BOARD_SIZE; row++) {
|
|
74
|
+
const rowArray = [];
|
|
75
|
+
for (let col = 0; col < BOARD_SIZE; col++) {
|
|
76
|
+
const puzzleValue = puzzleArray[row]?.[col] ?? 0;
|
|
77
|
+
const isClue = puzzleValue !== 0;
|
|
78
|
+
rowArray.push({
|
|
79
|
+
row,
|
|
80
|
+
column: col,
|
|
81
|
+
value: isClue ? puzzleValue : null,
|
|
82
|
+
isClue,
|
|
83
|
+
isError: false,
|
|
84
|
+
pencilmarks: new Set(),
|
|
85
|
+
isSelected: false,
|
|
86
|
+
isHighlighted: false,
|
|
87
|
+
isSameValue: false,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
board.push(rowArray);
|
|
91
|
+
}
|
|
92
|
+
return board;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Gets the current board state as a string (user's current progress)
|
|
96
|
+
* @param board - GameBoard
|
|
97
|
+
* @returns 81-character string representing current state
|
|
98
|
+
*/
|
|
99
|
+
export function getBoardStateString(board) {
|
|
100
|
+
let result = '';
|
|
101
|
+
for (let row = 0; row < BOARD_SIZE; row++) {
|
|
102
|
+
for (let col = 0; col < BOARD_SIZE; col++) {
|
|
103
|
+
const cell = board[row]?.[col];
|
|
104
|
+
result += cell?.value?.toString() ?? '0';
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Gets the pencilmarks as a comma-separated string for the solver API
|
|
111
|
+
* @param board - GameBoard
|
|
112
|
+
* @returns Comma-separated string of pencilmarks for each cell
|
|
113
|
+
*/
|
|
114
|
+
export function getPencilmarksString(board) {
|
|
115
|
+
const pencilmarks = [];
|
|
116
|
+
for (let row = 0; row < BOARD_SIZE; row++) {
|
|
117
|
+
for (let col = 0; col < BOARD_SIZE; col++) {
|
|
118
|
+
const cell = board[row]?.[col];
|
|
119
|
+
if (cell && cell.pencilmarks.size > 0) {
|
|
120
|
+
const sorted = Array.from(cell.pencilmarks).sort((a, b) => a - b);
|
|
121
|
+
pencilmarks.push(sorted.join(''));
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
pencilmarks.push('');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return pencilmarks.join(',');
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Gets the block index (0-8) for a cell position
|
|
132
|
+
* @param row - Row index (0-8)
|
|
133
|
+
* @param col - Column index (0-8)
|
|
134
|
+
* @returns Block index (0-8)
|
|
135
|
+
*/
|
|
136
|
+
export function getBlockIndex(row, col) {
|
|
137
|
+
const blockRow = Math.floor(row / BLOCK_SIZE);
|
|
138
|
+
const blockCol = Math.floor(col / BLOCK_SIZE);
|
|
139
|
+
return blockRow * BLOCK_SIZE + blockCol;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Gets all cells in the same row
|
|
143
|
+
* @param row - Row index (0-8)
|
|
144
|
+
* @returns Array of {row, column} positions
|
|
145
|
+
*/
|
|
146
|
+
export function getRowCells(row) {
|
|
147
|
+
const cells = [];
|
|
148
|
+
for (let col = 0; col < BOARD_SIZE; col++) {
|
|
149
|
+
cells.push({ row, column: col });
|
|
150
|
+
}
|
|
151
|
+
return cells;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Gets all cells in the same column
|
|
155
|
+
* @param col - Column index (0-8)
|
|
156
|
+
* @returns Array of {row, column} positions
|
|
157
|
+
*/
|
|
158
|
+
export function getColumnCells(col) {
|
|
159
|
+
const cells = [];
|
|
160
|
+
for (let row = 0; row < BOARD_SIZE; row++) {
|
|
161
|
+
cells.push({ row, column: col });
|
|
162
|
+
}
|
|
163
|
+
return cells;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Gets all cells in the same block
|
|
167
|
+
* @param blockIndex - Block index (0-8)
|
|
168
|
+
* @returns Array of {row, column} positions
|
|
169
|
+
*/
|
|
170
|
+
export function getBlockCells(blockIndex) {
|
|
171
|
+
const cells = [];
|
|
172
|
+
const blockRow = Math.floor(blockIndex / BLOCK_SIZE);
|
|
173
|
+
const blockCol = blockIndex % BLOCK_SIZE;
|
|
174
|
+
const startRow = blockRow * BLOCK_SIZE;
|
|
175
|
+
const startCol = blockCol * BLOCK_SIZE;
|
|
176
|
+
for (let r = 0; r < BLOCK_SIZE; r++) {
|
|
177
|
+
for (let c = 0; c < BLOCK_SIZE; c++) {
|
|
178
|
+
cells.push({ row: startRow + r, column: startCol + c });
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return cells;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Gets all related cells (same row, column, or block)
|
|
185
|
+
* @param row - Row index
|
|
186
|
+
* @param col - Column index
|
|
187
|
+
* @returns Array of {row, column} positions (excluding the cell itself)
|
|
188
|
+
*/
|
|
189
|
+
export function getRelatedCells(row, col) {
|
|
190
|
+
const related = new Map();
|
|
191
|
+
// Add row cells
|
|
192
|
+
for (const cell of getRowCells(row)) {
|
|
193
|
+
if (cell.row !== row || cell.column !== col) {
|
|
194
|
+
related.set(`${cell.row},${cell.column}`, cell);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Add column cells
|
|
198
|
+
for (const cell of getColumnCells(col)) {
|
|
199
|
+
if (cell.row !== row || cell.column !== col) {
|
|
200
|
+
related.set(`${cell.row},${cell.column}`, cell);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// Add block cells
|
|
204
|
+
const blockIndex = getBlockIndex(row, col);
|
|
205
|
+
for (const cell of getBlockCells(blockIndex)) {
|
|
206
|
+
if (cell.row !== row || cell.column !== col) {
|
|
207
|
+
related.set(`${cell.row},${cell.column}`, cell);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return Array.from(related.values());
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Checks if a value is valid for a cell position (not checking solution, just Sudoku rules)
|
|
214
|
+
* @param board - GameBoard
|
|
215
|
+
* @param row - Row index
|
|
216
|
+
* @param col - Column index
|
|
217
|
+
* @param value - Value to check (1-9)
|
|
218
|
+
* @returns true if the value doesn't conflict with existing values
|
|
219
|
+
*/
|
|
220
|
+
export function isValidPlacement(board, row, col, value) {
|
|
221
|
+
if (value < 1 || value > 9) {
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
// Check row
|
|
225
|
+
for (let c = 0; c < BOARD_SIZE; c++) {
|
|
226
|
+
if (c !== col && board[row]?.[c]?.value === value) {
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
// Check column
|
|
231
|
+
for (let r = 0; r < BOARD_SIZE; r++) {
|
|
232
|
+
if (r !== row && board[r]?.[col]?.value === value) {
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// Check block
|
|
237
|
+
const blockStartRow = Math.floor(row / BLOCK_SIZE) * BLOCK_SIZE;
|
|
238
|
+
const blockStartCol = Math.floor(col / BLOCK_SIZE) * BLOCK_SIZE;
|
|
239
|
+
for (let r = blockStartRow; r < blockStartRow + BLOCK_SIZE; r++) {
|
|
240
|
+
for (let c = blockStartCol; c < blockStartCol + BLOCK_SIZE; c++) {
|
|
241
|
+
if ((r !== row || c !== col) && board[r]?.[c]?.value === value) {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Clones a GameBoard (deep copy)
|
|
250
|
+
* @param board - GameBoard to clone
|
|
251
|
+
* @returns New GameBoard with copied values
|
|
252
|
+
*/
|
|
253
|
+
export function cloneBoard(board) {
|
|
254
|
+
return board.map(row => row.map(cell => ({
|
|
255
|
+
...cell,
|
|
256
|
+
pencilmarks: new Set(cell.pencilmarks),
|
|
257
|
+
})));
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Gets all empty cells in the board
|
|
261
|
+
* @param board - GameBoard
|
|
262
|
+
* @returns Array of {row, column} positions
|
|
263
|
+
*/
|
|
264
|
+
export function getEmptyCells(board) {
|
|
265
|
+
const emptyCells = [];
|
|
266
|
+
for (let row = 0; row < BOARD_SIZE; row++) {
|
|
267
|
+
for (let col = 0; col < BOARD_SIZE; col++) {
|
|
268
|
+
if (board[row]?.[col]?.value === null) {
|
|
269
|
+
emptyCells.push({ row, column: col });
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return emptyCells;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Counts the number of filled cells
|
|
277
|
+
* @param board - GameBoard
|
|
278
|
+
* @returns Number of filled cells
|
|
279
|
+
*/
|
|
280
|
+
export function countFilledCells(board) {
|
|
281
|
+
let count = 0;
|
|
282
|
+
for (let row = 0; row < BOARD_SIZE; row++) {
|
|
283
|
+
for (let col = 0; col < BOARD_SIZE; col++) {
|
|
284
|
+
if (board[row]?.[col]?.value !== null) {
|
|
285
|
+
count++;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return count;
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=board.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board.js","sourceRoot":"","sources":["../../src/utils/board.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility exports for Sudojo library
|
|
3
|
+
*/
|
|
4
|
+
export { BLOCK_SIZE, BOARD_SIZE, cloneBoard, countFilledCells, createGameBoard, getBlockCells, getBlockIndex, getBoardStateString, getColumnCells, getEmptyCells, getPencilmarksString, getRelatedCells, getRowCells, isValidPlacement, parseBoardString, stringifyBoard, TOTAL_CELLS, } from './board';
|
|
5
|
+
export { noScramble, scrambleBoard } from './scramble';
|
|
6
|
+
export { autoRemovePencilmarks, clearHighlights, countMistakes, getIncorrectCells, getProgressPercentage, isBoardFilled, isCellCorrect, isGameComplete, isValueCorrect, updateCellErrors, updateCellHighlights, validateGameState, } from './validation';
|
|
7
|
+
export type { ScramblerProtocol, ScrambleResult as SudokuScrambleResult, } from './sudokuScrambler';
|
|
8
|
+
export { Scrambler, NonScrambler, scrambleBoard as scrambleSudokuBoard, parsePuzzleString, cellsToPuzzleString, cellsToStateString, cellsToInputString, cellsToPencilmarksString, } from './sudokuScrambler';
|
|
9
|
+
export type { PresentBoardOptions } from './sudokuPresenter';
|
|
10
|
+
export { presentBoard, calculateCellHints, themeColorToCSS, getColorPalette, getCellsWithDigit, getSelectedDigit, computeSelectedDigitCells, } from './sudokuPresenter';
|
|
11
|
+
export { formatTime, parseTime } from './time';
|
|
12
|
+
export { calculateStats, calculateStreak, isPuzzleCompleted, getCompletedLevelIds, getCompletedDailyDates, } from './progress';
|
|
13
|
+
export { getFirebaseErrorMessage, getFirebaseErrorCode, formatFirebaseError, } from './auth';
|
|
14
|
+
export type { ThemePreference, ResolvedTheme } from './theme';
|
|
15
|
+
export { THEME_STORAGE_KEY, getSystemTheme, resolveTheme, isValidThemePreference, } from './theme';
|
|
16
|
+
export { convertPackageToProduct, parseCustomerInfo, getPeriodDisplayName, isBestValuePlan, getRevenueCatErrorMessage, } from './subscription';
|
|
17
|
+
export { getTechniqueIconUrl, TECHNIQUE_TO_HELP_FILE, HELP_FILE_TO_TECHNIQUE, getHelpFileUrl, getTechniqueFromHelpFile, extractBodyContent, } from './technique';
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,UAAU,EACV,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,WAAW,GACZ,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGvD,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,GAC1B,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,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,QAAQ,CAAC;AAGhB,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,EACL,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,EACtB,cAAc,EACd,wBAAwB,EACxB,kBAAkB,GACnB,MAAM,aAAa,CAAC"}
|