@stamprally/core 0.1.0
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/LICENSE +21 -0
- package/dist/index.cjs +1375 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +372 -0
- package/dist/index.d.ts +372 -0
- package/dist/index.js +1346 -0
- package/dist/index.js.map +1 -0
- package/package.json +45 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
type StampCondition = {
|
|
2
|
+
readonly type: "instant";
|
|
3
|
+
} | {
|
|
4
|
+
readonly type: "token";
|
|
5
|
+
readonly token: string;
|
|
6
|
+
} | {
|
|
7
|
+
readonly type: "geo";
|
|
8
|
+
readonly latitude: number;
|
|
9
|
+
readonly longitude: number;
|
|
10
|
+
readonly radiusMeters: number;
|
|
11
|
+
} | {
|
|
12
|
+
readonly type: "composite";
|
|
13
|
+
readonly operator: "AND" | "OR";
|
|
14
|
+
readonly conditions: ReadonlyArray<StampCondition>;
|
|
15
|
+
} | {
|
|
16
|
+
readonly type: "time_window";
|
|
17
|
+
readonly startsAt: string;
|
|
18
|
+
readonly endsAt: string;
|
|
19
|
+
readonly condition: StampCondition;
|
|
20
|
+
};
|
|
21
|
+
type VerificationContext = {
|
|
22
|
+
readonly type: "instant";
|
|
23
|
+
} | {
|
|
24
|
+
readonly type: "token";
|
|
25
|
+
readonly token: string;
|
|
26
|
+
} | {
|
|
27
|
+
readonly type: "geo";
|
|
28
|
+
readonly currentLatitude: number;
|
|
29
|
+
readonly currentLongitude: number;
|
|
30
|
+
} | {
|
|
31
|
+
readonly type: "composite";
|
|
32
|
+
readonly contexts: ReadonlyArray<VerificationContext>;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
interface ConditionMatch {
|
|
36
|
+
readonly conditionType: StampCondition["type"];
|
|
37
|
+
readonly distanceMeters?: number;
|
|
38
|
+
}
|
|
39
|
+
interface CompositeConditionFailure {
|
|
40
|
+
readonly index: number;
|
|
41
|
+
readonly error: ConditionMismatch;
|
|
42
|
+
}
|
|
43
|
+
type ConditionMismatch = {
|
|
44
|
+
readonly code: "CONDITION_MISMATCH";
|
|
45
|
+
readonly conditionType: Exclude<StampCondition["type"], "time_window">;
|
|
46
|
+
readonly reason: "CONTEXT_TYPE_MISMATCH";
|
|
47
|
+
readonly expectedContextType: VerificationContext["type"];
|
|
48
|
+
readonly actualContextType: VerificationContext["type"];
|
|
49
|
+
} | {
|
|
50
|
+
readonly code: "CONDITION_MISMATCH";
|
|
51
|
+
readonly conditionType: "token";
|
|
52
|
+
readonly reason: "TOKEN_MISMATCH";
|
|
53
|
+
} | {
|
|
54
|
+
readonly code: "CONDITION_MISMATCH";
|
|
55
|
+
readonly conditionType: "geo";
|
|
56
|
+
readonly reason: "INVALID_GEO_INPUT";
|
|
57
|
+
} | {
|
|
58
|
+
readonly code: "CONDITION_MISMATCH";
|
|
59
|
+
readonly conditionType: "geo";
|
|
60
|
+
readonly reason: "OUTSIDE_RADIUS";
|
|
61
|
+
readonly distanceMeters: number;
|
|
62
|
+
readonly radiusMeters: number;
|
|
63
|
+
readonly differenceMeters: number;
|
|
64
|
+
} | {
|
|
65
|
+
readonly code: "CONDITION_MISMATCH";
|
|
66
|
+
readonly conditionType: "composite";
|
|
67
|
+
readonly reason: "CONTEXT_LENGTH_MISMATCH";
|
|
68
|
+
readonly expectedCount: number;
|
|
69
|
+
readonly actualCount: number;
|
|
70
|
+
} | {
|
|
71
|
+
readonly code: "CONDITION_MISMATCH";
|
|
72
|
+
readonly conditionType: "composite";
|
|
73
|
+
readonly reason: "AND_CHILD_FAILED" | "OR_ALL_FAILED";
|
|
74
|
+
readonly failures: ReadonlyArray<CompositeConditionFailure>;
|
|
75
|
+
} | {
|
|
76
|
+
readonly code: "CONDITION_MISMATCH";
|
|
77
|
+
readonly conditionType: "time_window";
|
|
78
|
+
readonly reason: "INVALID_NOW" | "INVALID_TIME_WINDOW" | "BEFORE_START" | "AFTER_END";
|
|
79
|
+
readonly now: string;
|
|
80
|
+
readonly startsAt: string;
|
|
81
|
+
readonly endsAt: string;
|
|
82
|
+
};
|
|
83
|
+
type StampError = {
|
|
84
|
+
readonly code: "STAMP_NOT_FOUND";
|
|
85
|
+
readonly stampId: string;
|
|
86
|
+
} | {
|
|
87
|
+
readonly code: "STAMP_ALREADY_ACQUIRED";
|
|
88
|
+
readonly stampId: string;
|
|
89
|
+
} | {
|
|
90
|
+
readonly code: "INVALID_ORDER";
|
|
91
|
+
readonly stampId: string;
|
|
92
|
+
readonly expectedStampId: string;
|
|
93
|
+
} | {
|
|
94
|
+
readonly code: "CONDITION_MISMATCH";
|
|
95
|
+
readonly stampId: string;
|
|
96
|
+
readonly mismatch: ConditionMismatch;
|
|
97
|
+
};
|
|
98
|
+
type Result<T, E> = {
|
|
99
|
+
readonly ok: true;
|
|
100
|
+
readonly value: T;
|
|
101
|
+
} | {
|
|
102
|
+
readonly ok: false;
|
|
103
|
+
readonly error: E;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
type SupportedLocale = "ja" | "en";
|
|
107
|
+
type LocalizedString = Record<SupportedLocale, string>;
|
|
108
|
+
type LocalizedText = string | LocalizedString;
|
|
109
|
+
type SlotShape = "circle" | "square" | "rounded";
|
|
110
|
+
type FontFamily = "system-ui" | "serif" | "rounded-sans" | "monospace" | "handwritten";
|
|
111
|
+
interface SheetTheme {
|
|
112
|
+
readonly primaryColor: string;
|
|
113
|
+
readonly backgroundColor?: string;
|
|
114
|
+
readonly backgroundImageUrl?: string;
|
|
115
|
+
readonly cardBackgroundColor: string;
|
|
116
|
+
readonly textColor: string;
|
|
117
|
+
readonly slotShape: SlotShape;
|
|
118
|
+
readonly gridColumns: number;
|
|
119
|
+
readonly unclaimedOpacity?: number;
|
|
120
|
+
readonly completedStampColor?: string;
|
|
121
|
+
readonly fontFamily?: FontFamily;
|
|
122
|
+
}
|
|
123
|
+
type ThemePresetId = "default" | "modern_dark" | "pop_candy" | "retro_craft" | "cyber";
|
|
124
|
+
interface ThemePreset {
|
|
125
|
+
readonly id: ThemePresetId;
|
|
126
|
+
readonly name: LocalizedString;
|
|
127
|
+
readonly description: LocalizedString;
|
|
128
|
+
readonly theme: SheetTheme;
|
|
129
|
+
}
|
|
130
|
+
declare const DEFAULT_SHEET_THEME: SheetTheme;
|
|
131
|
+
interface SpotItem {
|
|
132
|
+
readonly id: string;
|
|
133
|
+
readonly name: LocalizedText;
|
|
134
|
+
readonly description?: LocalizedText;
|
|
135
|
+
readonly hint?: LocalizedText;
|
|
136
|
+
readonly condition: StampCondition;
|
|
137
|
+
readonly order?: number;
|
|
138
|
+
}
|
|
139
|
+
/** @deprecated Use SpotItem instead. */
|
|
140
|
+
type StampDefinition = SpotItem;
|
|
141
|
+
interface StampRecord {
|
|
142
|
+
readonly stampId: string;
|
|
143
|
+
readonly acquiredAt: string;
|
|
144
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
145
|
+
}
|
|
146
|
+
type RewardType = "digital" | "in_person";
|
|
147
|
+
type RedemptionMethod = "manual_slide" | "staff_passcode" | "view_only";
|
|
148
|
+
type RewardStatus = "LOCKED" | "AVAILABLE" | "CONSUMED" | "EXPIRED";
|
|
149
|
+
interface RewardItem {
|
|
150
|
+
readonly id: string;
|
|
151
|
+
readonly title: LocalizedText;
|
|
152
|
+
readonly description: LocalizedText;
|
|
153
|
+
readonly type: RewardType;
|
|
154
|
+
readonly redemptionMethod: RedemptionMethod;
|
|
155
|
+
readonly requiredStampCount: number;
|
|
156
|
+
readonly digitalContentUrl?: string;
|
|
157
|
+
readonly staffPasscode?: string;
|
|
158
|
+
}
|
|
159
|
+
interface RewardState {
|
|
160
|
+
readonly rewardId: string;
|
|
161
|
+
readonly status: RewardStatus;
|
|
162
|
+
readonly unlockedAt?: string;
|
|
163
|
+
readonly consumedAt?: string;
|
|
164
|
+
readonly consumedByStaffId?: string;
|
|
165
|
+
}
|
|
166
|
+
interface StampRallyState {
|
|
167
|
+
readonly rallyId: string;
|
|
168
|
+
readonly records: ReadonlyArray<StampRecord>;
|
|
169
|
+
readonly rewards?: ReadonlyArray<RewardState>;
|
|
170
|
+
readonly updatedAt: string;
|
|
171
|
+
}
|
|
172
|
+
interface RallyConfig {
|
|
173
|
+
readonly id: string;
|
|
174
|
+
readonly title?: LocalizedText;
|
|
175
|
+
readonly description?: LocalizedText;
|
|
176
|
+
readonly stamps: ReadonlyArray<StampDefinition>;
|
|
177
|
+
readonly rewards?: ReadonlyArray<RewardItem>;
|
|
178
|
+
readonly isSequential?: boolean;
|
|
179
|
+
readonly theme?: SheetTheme;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
declare function resolveLocalizedText(text: LocalizedText | undefined, locale: SupportedLocale, fallbackLocale?: SupportedLocale): string;
|
|
183
|
+
declare function toLocalizedString(text: LocalizedText | undefined): LocalizedString;
|
|
184
|
+
|
|
185
|
+
declare const THEME_PRESETS: ReadonlyArray<ThemePreset>;
|
|
186
|
+
|
|
187
|
+
declare function calculateDistanceMeters(latitudeA: number, longitudeA: number, latitudeB: number, longitudeB: number): number;
|
|
188
|
+
declare function evaluateConditionDetailed(condition: StampCondition, context: VerificationContext, now: string): Result<ConditionMatch, ConditionMismatch>;
|
|
189
|
+
declare function evaluateCondition(condition: StampCondition, context: VerificationContext, now?: string): boolean;
|
|
190
|
+
|
|
191
|
+
interface StampRallyProgress {
|
|
192
|
+
readonly acquired: number;
|
|
193
|
+
readonly total: number;
|
|
194
|
+
readonly percentage: number;
|
|
195
|
+
readonly isCompleted: boolean;
|
|
196
|
+
/** @deprecated Use isCompleted instead. */
|
|
197
|
+
readonly isComplete: boolean;
|
|
198
|
+
readonly nextAvailableStamps: ReadonlyArray<StampDefinition>;
|
|
199
|
+
}
|
|
200
|
+
declare function calculateProgress(state: StampRallyState, config: RallyConfig): StampRallyProgress;
|
|
201
|
+
|
|
202
|
+
type StampRallyEvent = {
|
|
203
|
+
readonly type: "stampAcquired";
|
|
204
|
+
readonly record: StampRecord;
|
|
205
|
+
} | {
|
|
206
|
+
readonly type: "rallyCompleted";
|
|
207
|
+
readonly rallyId: string;
|
|
208
|
+
readonly completedAt: string;
|
|
209
|
+
};
|
|
210
|
+
interface ProcessStampValue {
|
|
211
|
+
readonly nextState: StampRallyState;
|
|
212
|
+
readonly events: ReadonlyArray<StampRallyEvent>;
|
|
213
|
+
}
|
|
214
|
+
type RewardConsumeError = {
|
|
215
|
+
readonly code: "NOT_AVAILABLE";
|
|
216
|
+
readonly rewardId: string;
|
|
217
|
+
} | {
|
|
218
|
+
readonly code: "ALREADY_CONSUMED";
|
|
219
|
+
readonly rewardId: string;
|
|
220
|
+
} | {
|
|
221
|
+
readonly code: "INVALID_PASSCODE";
|
|
222
|
+
readonly rewardId: string;
|
|
223
|
+
readonly message: string;
|
|
224
|
+
} | {
|
|
225
|
+
readonly code: "REWARD_NOT_FOUND";
|
|
226
|
+
readonly rewardId: string;
|
|
227
|
+
};
|
|
228
|
+
interface ConsumeRewardParams {
|
|
229
|
+
readonly reward: RewardItem;
|
|
230
|
+
readonly currentState: RewardState;
|
|
231
|
+
readonly inputPasscode?: string;
|
|
232
|
+
readonly staffId?: string;
|
|
233
|
+
readonly now: string;
|
|
234
|
+
}
|
|
235
|
+
type ConsumeResult = Result<RewardState, RewardConsumeError>;
|
|
236
|
+
declare function reconcileRewardStates(rewards: ReadonlyArray<RewardItem>, currentStates: ReadonlyArray<RewardState>, acquiredStampCount: number, now: string): ReadonlyArray<RewardState>;
|
|
237
|
+
declare function consumeReward(params: ConsumeRewardParams): ConsumeResult;
|
|
238
|
+
declare function processStamp(state: StampRallyState, config: RallyConfig, targetStampId: string, context: VerificationContext, now: string): Result<ProcessStampValue, StampError>;
|
|
239
|
+
|
|
240
|
+
interface StampStorage {
|
|
241
|
+
load(rallyId: string): Promise<StampRallyState | null>;
|
|
242
|
+
save(state: StampRallyState): Promise<void>;
|
|
243
|
+
remove(rallyId: string): Promise<void>;
|
|
244
|
+
}
|
|
245
|
+
interface StorageLike {
|
|
246
|
+
getItem(key: string): string | null;
|
|
247
|
+
setItem(key: string, value: string): void;
|
|
248
|
+
removeItem(key: string): void;
|
|
249
|
+
}
|
|
250
|
+
type StorageOperation = "open" | "load" | "save" | "remove";
|
|
251
|
+
type StorageAdapterErrorCode = "STORAGE_UNAVAILABLE" | "STORAGE_OPEN_FAILED" | "STORAGE_READ_FAILED" | "STORAGE_WRITE_FAILED" | "STORAGE_REMOVE_FAILED" | "STORAGE_INVALID_DATA";
|
|
252
|
+
declare class StorageAdapterError extends Error {
|
|
253
|
+
readonly code: StorageAdapterErrorCode;
|
|
254
|
+
readonly operation: StorageOperation;
|
|
255
|
+
readonly rallyId: string | undefined;
|
|
256
|
+
constructor(code: StorageAdapterErrorCode, operation: StorageOperation, message: string, options?: {
|
|
257
|
+
readonly cause?: unknown;
|
|
258
|
+
readonly rallyId?: string;
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
declare function isRewardState(value: unknown): value is RewardState;
|
|
262
|
+
declare function isStampRallyState(value: unknown): value is StampRallyState;
|
|
263
|
+
interface RallySnapshot {
|
|
264
|
+
readonly version: 1;
|
|
265
|
+
readonly rallyId: string;
|
|
266
|
+
readonly stamps: ReadonlyArray<StampRecord>;
|
|
267
|
+
readonly rewards: ReadonlyArray<RewardState>;
|
|
268
|
+
readonly exportedAt: string;
|
|
269
|
+
}
|
|
270
|
+
declare function exportProgressToken(snapshot: RallySnapshot): string;
|
|
271
|
+
declare function importProgressToken(token: string, currentRallyId: string): RallySnapshot | null;
|
|
272
|
+
declare class InMemoryStorage implements StampStorage {
|
|
273
|
+
#private;
|
|
274
|
+
load(rallyId: string): Promise<StampRallyState | null>;
|
|
275
|
+
save(state: StampRallyState): Promise<void>;
|
|
276
|
+
remove(rallyId: string): Promise<void>;
|
|
277
|
+
}
|
|
278
|
+
interface LocalStorageAdapterOptions {
|
|
279
|
+
readonly storage?: StorageLike | null;
|
|
280
|
+
readonly keyPrefix?: string;
|
|
281
|
+
readonly failureMode?: LocalStorageFailureMode;
|
|
282
|
+
readonly onWarning?: StorageWarningHandler;
|
|
283
|
+
}
|
|
284
|
+
type LocalStorageFailureMode = "fallback" | "throw";
|
|
285
|
+
type StorageWarningHandler = (error: StorageAdapterError) => void;
|
|
286
|
+
declare class LocalStorageAdapter implements StampStorage {
|
|
287
|
+
#private;
|
|
288
|
+
constructor(options?: LocalStorageAdapterOptions);
|
|
289
|
+
load(rallyId: string): Promise<StampRallyState | null>;
|
|
290
|
+
save(state: StampRallyState): Promise<void>;
|
|
291
|
+
remove(rallyId: string): Promise<void>;
|
|
292
|
+
}
|
|
293
|
+
interface IndexedDBAdapterOptions {
|
|
294
|
+
readonly indexedDB?: IDBFactory | null;
|
|
295
|
+
readonly databaseName?: string;
|
|
296
|
+
}
|
|
297
|
+
declare class IndexedDBAdapter implements StampStorage {
|
|
298
|
+
#private;
|
|
299
|
+
constructor(options?: IndexedDBAdapterOptions);
|
|
300
|
+
load(rallyId: string): Promise<StampRallyState | null>;
|
|
301
|
+
save(state: StampRallyState): Promise<void>;
|
|
302
|
+
remove(rallyId: string): Promise<void>;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
type StampRallyListener = (state: StampRallyState) => void;
|
|
306
|
+
type Clock = () => string;
|
|
307
|
+
declare class StampRallyClient {
|
|
308
|
+
#private;
|
|
309
|
+
constructor(config: RallyConfig, storage: StampStorage, clock?: Clock);
|
|
310
|
+
getState(): StampRallyState | null;
|
|
311
|
+
getConfig(): RallyConfig;
|
|
312
|
+
subscribe(listener: StampRallyListener): () => void;
|
|
313
|
+
init(): Promise<StampRallyState>;
|
|
314
|
+
initialize(): Promise<StampRallyState>;
|
|
315
|
+
acquire(stampId: string, context: VerificationContext, now?: string): Promise<Result<ProcessStampValue, StampError>>;
|
|
316
|
+
reset(now?: string): Promise<StampRallyState>;
|
|
317
|
+
restore(state: StampRallyState): Promise<StampRallyState>;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
type DetectorKind = "geolocation" | "nfc" | "qr";
|
|
321
|
+
type DetectorErrorCode = "UNSUPPORTED" | "PERMISSION_DENIED" | "POSITION_UNAVAILABLE" | "TIMEOUT" | "ABORTED" | "READ_FAILED" | "INVALID_DATA" | "NO_TOKEN";
|
|
322
|
+
interface DetectorError {
|
|
323
|
+
readonly detector: DetectorKind;
|
|
324
|
+
readonly code: DetectorErrorCode;
|
|
325
|
+
readonly message: string;
|
|
326
|
+
readonly cause?: unknown;
|
|
327
|
+
}
|
|
328
|
+
type GeoVerificationContext = Extract<VerificationContext, {
|
|
329
|
+
readonly type: "geo";
|
|
330
|
+
}>;
|
|
331
|
+
type TokenVerificationContext = Extract<VerificationContext, {
|
|
332
|
+
readonly type: "token";
|
|
333
|
+
}>;
|
|
334
|
+
type DetectorResult<T extends VerificationContext> = Result<T, DetectorError>;
|
|
335
|
+
interface PasscodeCondition {
|
|
336
|
+
readonly passcode: string;
|
|
337
|
+
readonly caseSensitive?: boolean;
|
|
338
|
+
}
|
|
339
|
+
type CheckInResult = {
|
|
340
|
+
readonly success: true;
|
|
341
|
+
} | {
|
|
342
|
+
readonly success: false;
|
|
343
|
+
readonly reason: "INVALID_PASSCODE";
|
|
344
|
+
readonly message: string;
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
interface GeoDetectorOptions {
|
|
348
|
+
readonly enableHighAccuracy?: boolean;
|
|
349
|
+
readonly timeout?: number;
|
|
350
|
+
}
|
|
351
|
+
declare function isGeolocationSupported(): boolean;
|
|
352
|
+
declare function getCurrentGeoContext(options?: GeoDetectorOptions): Promise<DetectorResult<GeoVerificationContext>>;
|
|
353
|
+
|
|
354
|
+
interface NfcDetectorOptions {
|
|
355
|
+
readonly timeout?: number;
|
|
356
|
+
readonly signal?: AbortSignal;
|
|
357
|
+
}
|
|
358
|
+
declare function isNfcSupported(): boolean;
|
|
359
|
+
declare function readNfcContext(options?: NfcDetectorOptions): Promise<DetectorResult<TokenVerificationContext>>;
|
|
360
|
+
|
|
361
|
+
declare function normalizePasscode(input: string, caseSensitive?: boolean): string;
|
|
362
|
+
declare function verifyPasscode(inputCode: string, condition: PasscodeCondition): CheckInResult;
|
|
363
|
+
|
|
364
|
+
interface QrDetectorOptions {
|
|
365
|
+
readonly timeout?: number;
|
|
366
|
+
readonly signal?: AbortSignal;
|
|
367
|
+
readonly facingMode?: "user" | "environment";
|
|
368
|
+
}
|
|
369
|
+
declare function isQrSupported(): boolean;
|
|
370
|
+
declare function readQrContext(videoElement: HTMLVideoElement, options?: QrDetectorOptions): Promise<DetectorResult<TokenVerificationContext>>;
|
|
371
|
+
|
|
372
|
+
export { type CheckInResult, type Clock, type CompositeConditionFailure, type ConditionMatch, type ConditionMismatch, type ConsumeResult, type ConsumeRewardParams, DEFAULT_SHEET_THEME, type DetectorError, type DetectorErrorCode, type DetectorKind, type DetectorResult, type FontFamily, type GeoDetectorOptions, type GeoVerificationContext, InMemoryStorage, IndexedDBAdapter, type IndexedDBAdapterOptions, LocalStorageAdapter, type LocalStorageAdapterOptions, type LocalStorageFailureMode, type LocalizedString, type LocalizedText, type NfcDetectorOptions, type PasscodeCondition, type ProcessStampValue, type QrDetectorOptions, type RallyConfig, type RallySnapshot, type RedemptionMethod, type Result, type RewardConsumeError, type RewardItem, type RewardState, type RewardStatus, type RewardType, type SheetTheme, type SlotShape, type SpotItem, type StampCondition, type StampDefinition, type StampError, StampRallyClient, type StampRallyEvent, type StampRallyListener, type StampRallyProgress, type StampRallyState, type StampRecord, type StampStorage, StorageAdapterError, type StorageAdapterErrorCode, type StorageLike, type StorageOperation, type StorageWarningHandler, type SupportedLocale, THEME_PRESETS, type ThemePreset, type ThemePresetId, type TokenVerificationContext, type VerificationContext, calculateDistanceMeters, calculateProgress, consumeReward, evaluateCondition, evaluateConditionDetailed, exportProgressToken, getCurrentGeoContext, importProgressToken, isGeolocationSupported, isNfcSupported, isQrSupported, isRewardState, isStampRallyState, normalizePasscode, processStamp, readNfcContext, readQrContext, reconcileRewardStates, resolveLocalizedText, toLocalizedString, verifyPasscode };
|