@panelwave/player 1.0.1 → 1.2.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/README.md +66 -20
- package/fesm2022/panelwave-player.mjs +511 -167
- package/fesm2022/panelwave-player.mjs.map +1 -1
- package/index.d.ts +212 -27
- package/package.json +4 -4
- package/src/assets/i18n/de.json +26 -1
- package/src/assets/i18n/en.json +26 -1
package/index.d.ts
CHANGED
|
@@ -1603,6 +1603,31 @@ interface ExtraImage {
|
|
|
1603
1603
|
interface Paywall {
|
|
1604
1604
|
/** Array of paywall rules */
|
|
1605
1605
|
rules?: PaywallRule[];
|
|
1606
|
+
/**
|
|
1607
|
+
* Display info for the products / subscription tiers the rules reference by
|
|
1608
|
+
* id (format 1.6) — labels, descriptions and prices of the Buy / Subscribe
|
|
1609
|
+
* options (optional)
|
|
1610
|
+
*/
|
|
1611
|
+
products?: PaywallProduct[];
|
|
1612
|
+
}
|
|
1613
|
+
/**
|
|
1614
|
+
* One product or subscription tier from the host's catalogue (format 1.6).
|
|
1615
|
+
* Informational: the rules decide what unlocks what.
|
|
1616
|
+
*/
|
|
1617
|
+
interface PaywallProduct {
|
|
1618
|
+
/** Id referenced by requiredProductIds / requireEntitlement / subscriptionTiers */
|
|
1619
|
+
id: string;
|
|
1620
|
+
/** Localized product name (optional) */
|
|
1621
|
+
name?: LocalizedString;
|
|
1622
|
+
/** Localized product description (optional) */
|
|
1623
|
+
description?: LocalizedString;
|
|
1624
|
+
/** Display price (optional) */
|
|
1625
|
+
price?: {
|
|
1626
|
+
amount: number;
|
|
1627
|
+
currency: string;
|
|
1628
|
+
};
|
|
1629
|
+
/** One-time purchase or subscription tier (optional, informational) */
|
|
1630
|
+
type?: 'purchase' | 'subscription';
|
|
1606
1631
|
}
|
|
1607
1632
|
/**
|
|
1608
1633
|
* Paywall rule
|
|
@@ -1628,7 +1653,7 @@ interface PaywallRule {
|
|
|
1628
1653
|
entitlementType?: string;
|
|
1629
1654
|
/** Tiers that satisfy a subscription rule; empty/absent = any tier (optional) */
|
|
1630
1655
|
subscriptionTiers?: string[];
|
|
1631
|
-
/** Products that
|
|
1656
|
+
/** Products that unlock a purchase rule, any one suffices (format 1.6); absent = requireEntitlement key / any purchase (optional) */
|
|
1632
1657
|
requiredProductIds?: string[];
|
|
1633
1658
|
/** Embedded price for display in the paywall overlay (CMS) (optional) */
|
|
1634
1659
|
price?: {
|
|
@@ -1985,6 +2010,26 @@ interface PanelChangeEvent {
|
|
|
1985
2010
|
/** Transition used */
|
|
1986
2011
|
transition?: string;
|
|
1987
2012
|
}
|
|
2013
|
+
/**
|
|
2014
|
+
* Payload of `<pw-player-shell>`'s `(panelChange)` output.
|
|
2015
|
+
*
|
|
2016
|
+
* Panels are keyed by id in `chapter.panels`; the optional `Panel.id` of the
|
|
2017
|
+
* format is not required and is usually absent, so read the id from
|
|
2018
|
+
* `panelId`, not from `panel`.
|
|
2019
|
+
*/
|
|
2020
|
+
interface PlayerPanelChangeEvent {
|
|
2021
|
+
/** The panel that is now current (the manifest object, variants unresolved). */
|
|
2022
|
+
panel: Panel;
|
|
2023
|
+
/** The chapter the panel belongs to. */
|
|
2024
|
+
chapter: Chapter;
|
|
2025
|
+
/** Id of the current panel: its key in `chapter.panels`. */
|
|
2026
|
+
panelId: string;
|
|
2027
|
+
/**
|
|
2028
|
+
* Id of the panel that was current before this change (it may belong to
|
|
2029
|
+
* the previous chapter). Undefined for the first panel after a (re)load.
|
|
2030
|
+
*/
|
|
2031
|
+
previousPanelId?: string;
|
|
2032
|
+
}
|
|
1988
2033
|
/**
|
|
1989
2034
|
* Decision event payload
|
|
1990
2035
|
*/
|
|
@@ -2189,6 +2234,21 @@ interface PaywallGate {
|
|
|
2189
2234
|
reason: string;
|
|
2190
2235
|
/** Preview information (optional) */
|
|
2191
2236
|
preview?: PreviewInfo;
|
|
2237
|
+
/** Id of the manifest paywall rule that raised the gate (optional) */
|
|
2238
|
+
ruleId?: string;
|
|
2239
|
+
/**
|
|
2240
|
+
* Machine-readable lock reason (optional): `subscription_required`,
|
|
2241
|
+
* `purchase_required`, `age_verification_required` or
|
|
2242
|
+
* `entitlement_required`. The overlay translates it; `reason` stays the
|
|
2243
|
+
* English sentence for hosts.
|
|
2244
|
+
*/
|
|
2245
|
+
lockReason?: string;
|
|
2246
|
+
/**
|
|
2247
|
+
* What the reader can buy to pass the gate, derived from the rule
|
|
2248
|
+
* (product ids / subscription tiers, name, price). The built-in overlay
|
|
2249
|
+
* renders them as Buy / Subscribe buttons.
|
|
2250
|
+
*/
|
|
2251
|
+
options?: PurchaseInfo[];
|
|
2192
2252
|
}
|
|
2193
2253
|
/**
|
|
2194
2254
|
* Preview information for gated content
|
|
@@ -2209,8 +2269,8 @@ interface PurchaseInfo {
|
|
|
2209
2269
|
productId: string;
|
|
2210
2270
|
/** Product name */
|
|
2211
2271
|
name: string;
|
|
2212
|
-
/** Price with currency */
|
|
2213
|
-
price
|
|
2272
|
+
/** Price with currency (optional: not every rule carries one) */
|
|
2273
|
+
price?: {
|
|
2214
2274
|
amount: number;
|
|
2215
2275
|
currency: string;
|
|
2216
2276
|
};
|
|
@@ -4154,12 +4214,22 @@ declare class TrackingService {
|
|
|
4154
4214
|
* free preview.
|
|
4155
4215
|
* - Panel-scoped rules gate exactly their `targetPanelIds` — preview does NOT
|
|
4156
4216
|
* override an explicit panel gate.
|
|
4217
|
+
* - Chapter-scoped rules gate only the panels of their chapter(s) (`refId`);
|
|
4218
|
+
* their free preview counts panels WITHIN that chapter. They take
|
|
4219
|
+
* precedence over a work gate for those panels.
|
|
4220
|
+
* - Extras-scoped rules never gate panels — they gate the extras block named
|
|
4221
|
+
* by `refId` (see `isExtraLocked`).
|
|
4157
4222
|
* - A gated panel unlocks when the gating rule's requirement is satisfied by
|
|
4158
4223
|
* the reader's entitlement snapshot.
|
|
4159
4224
|
*/
|
|
4160
4225
|
|
|
4161
4226
|
type EvaluatorEntitlementType = 'free' | 'subscription' | 'purchase' | 'age_gate';
|
|
4162
|
-
|
|
4227
|
+
/**
|
|
4228
|
+
* `global` is NOT in the schema's scope enum (work | chapter | panel |
|
|
4229
|
+
* extras). It is still accepted as an alias of `work` so old manifests and
|
|
4230
|
+
* CMS-internal rules keep gating; nothing in the player emits it.
|
|
4231
|
+
*/
|
|
4232
|
+
type EvaluatorScope = 'global' | 'work' | 'chapter' | 'panel' | 'extras';
|
|
4163
4233
|
/** The rule shape the evaluator needs (a superset of the manifest rule). */
|
|
4164
4234
|
interface EvaluatorRule {
|
|
4165
4235
|
id: string;
|
|
@@ -4170,12 +4240,28 @@ interface EvaluatorRule {
|
|
|
4170
4240
|
subscriptionTiers?: string[];
|
|
4171
4241
|
/** Products that satisfy a purchase rule; empty/absent = any purchase. */
|
|
4172
4242
|
requiredProductIds?: string[];
|
|
4173
|
-
/**
|
|
4243
|
+
/**
|
|
4244
|
+
* Minimum age. For an `age_gate` rule it is the whole requirement (default
|
|
4245
|
+
* 18); on any other rule it is an extra check ON TOP OF the entitlement
|
|
4246
|
+
* (schema `ageGate`): the reader needs both.
|
|
4247
|
+
*/
|
|
4174
4248
|
minimumAge?: number;
|
|
4175
4249
|
/** Free-preview length for work/global rules (panels in reading order). */
|
|
4176
4250
|
previewPanelCount?: number;
|
|
4177
4251
|
/** Panels gated by a panel-scoped rule. */
|
|
4178
4252
|
targetPanelIds?: string[];
|
|
4253
|
+
/** Chapters (chapter scope) or extras blocks (extras scope) the rule gates — the manifest's `refId`. */
|
|
4254
|
+
targetIds?: string[];
|
|
4255
|
+
/** Reader-facing rule name and description (CMS), for purchase options. */
|
|
4256
|
+
name?: string;
|
|
4257
|
+
description?: string;
|
|
4258
|
+
/** Display price (CMS). */
|
|
4259
|
+
price?: {
|
|
4260
|
+
amount: number;
|
|
4261
|
+
currency: string;
|
|
4262
|
+
};
|
|
4263
|
+
/** The manifest's raw `requireEntitlement` key. */
|
|
4264
|
+
entitlementKey?: string;
|
|
4179
4265
|
}
|
|
4180
4266
|
/** What the reader "has" — the shape payments produce and the player consumes. */
|
|
4181
4267
|
interface EntitlementSnapshot {
|
|
@@ -4189,6 +4275,10 @@ interface EntitlementSnapshot {
|
|
|
4189
4275
|
interface PanelRef {
|
|
4190
4276
|
id: string;
|
|
4191
4277
|
index: number;
|
|
4278
|
+
/** Chapter the panel belongs to (enables chapter-scoped rules). */
|
|
4279
|
+
chapterId?: string;
|
|
4280
|
+
/** Reading-order index within its chapter (chapter-rule preview counting). */
|
|
4281
|
+
chapterIndex?: number;
|
|
4192
4282
|
}
|
|
4193
4283
|
type LockReason = 'subscription_required' | 'purchase_required' | 'age_verification_required' | null;
|
|
4194
4284
|
interface AccessDecision {
|
|
@@ -4201,7 +4291,10 @@ interface AccessDecision {
|
|
|
4201
4291
|
/** True when access exists only because the panel is inside the free preview. */
|
|
4202
4292
|
preview: boolean;
|
|
4203
4293
|
}
|
|
4204
|
-
/**
|
|
4294
|
+
/**
|
|
4295
|
+
* Does the reader's snapshot satisfy this rule's requirement? A rule with a
|
|
4296
|
+
* `minimumAge` needs the age AND its entitlement.
|
|
4297
|
+
*/
|
|
4205
4298
|
declare function satisfiesRule(rule: EvaluatorRule, entitlement: EntitlementSnapshot): boolean;
|
|
4206
4299
|
/** The active work/global rule (first one wins — mirrors the CMS content map). */
|
|
4207
4300
|
declare function findWorkGateRule(rules: EvaluatorRule[]): EvaluatorRule | null;
|
|
@@ -4209,6 +4302,8 @@ declare function findWorkGateRule(rules: EvaluatorRule[]): EvaluatorRule | null;
|
|
|
4209
4302
|
* Evaluate one panel against the rules for a given reader snapshot.
|
|
4210
4303
|
*/
|
|
4211
4304
|
declare function evaluatePanelAccess(rules: EvaluatorRule[], entitlement: EntitlementSnapshot, panel: PanelRef): AccessDecision;
|
|
4305
|
+
/** Is the extras block `extraId` locked by an extras-scoped rule? */
|
|
4306
|
+
declare function isExtraLocked(rules: EvaluatorRule[], entitlement: EntitlementSnapshot, extraId: string): boolean;
|
|
4212
4307
|
/** Evaluate a whole work (panels in reading order). */
|
|
4213
4308
|
declare function evaluateWorkAccess(rules: EvaluatorRule[], entitlement: EntitlementSnapshot, panels: PanelRef[]): AccessDecision[];
|
|
4214
4309
|
/** A snapshot with no entitlements — what an anonymous first-time reader has. */
|
|
@@ -4222,12 +4317,19 @@ declare const ANONYMOUS_READER: EntitlementSnapshot;
|
|
|
4222
4317
|
* `minimumAge` written by the CMS exporter. Prefer the CMS names and fall
|
|
4223
4318
|
* back to the originals, so a manifest from either era gates identically.
|
|
4224
4319
|
*
|
|
4225
|
-
*
|
|
4226
|
-
*
|
|
4320
|
+
* `ageGate` / `minimumAge` is an age check ON TOP OF the entitlement (schema
|
|
4321
|
+
* semantics). Only a rule that declares no entitlement at all but names an
|
|
4322
|
+
* age becomes a pure age gate; a custom marker plus an age stays a purchase
|
|
4323
|
+
* (or subscription) gate that also requires the age.
|
|
4227
4324
|
*/
|
|
4228
4325
|
declare function fromManifestRule(rule: PaywallRule, index: number): EvaluatorRule;
|
|
4229
4326
|
/** Normalise every rule in a manifest. Returns [] when the work has no paywall. */
|
|
4230
4327
|
declare function rulesFromManifest(manifest: PanelWaveManifest | null): EvaluatorRule[];
|
|
4328
|
+
/** Chapter id and within-chapter index per panel id (chapter-rule previews). */
|
|
4329
|
+
declare function chapterOrderFromManifest(manifest: PanelWaveManifest | null): Map<string, {
|
|
4330
|
+
chapterId: string;
|
|
4331
|
+
chapterIndex: number;
|
|
4332
|
+
}>;
|
|
4231
4333
|
/**
|
|
4232
4334
|
* Global reading order for preview counting: chapters in array order, and
|
|
4233
4335
|
* within a chapter the panel declaration order.
|
|
@@ -4262,11 +4364,15 @@ declare function toEntitlementStatus(decision: AccessDecision, entitlement: Enti
|
|
|
4262
4364
|
declare class PaywallService {
|
|
4263
4365
|
private rules;
|
|
4264
4366
|
private readingOrder;
|
|
4367
|
+
private chapterOrder;
|
|
4265
4368
|
private manifest;
|
|
4369
|
+
private products;
|
|
4266
4370
|
private snapshotSubject;
|
|
4267
4371
|
readonly snapshot$: Observable<EntitlementSnapshot>;
|
|
4268
4372
|
/** Load the rules and reading order from a manifest. Safe to call repeatedly. */
|
|
4269
4373
|
setManifest(manifest: PanelWaveManifest | null): void;
|
|
4374
|
+
/** `paywall.products` by id (format 1.6); the first entry wins on duplicate ids. */
|
|
4375
|
+
static productsFromManifest(manifest: PanelWaveManifest | null): Map<string, PaywallProduct>;
|
|
4270
4376
|
/** Replace what the reader owns (after sign-in, or a completed purchase). */
|
|
4271
4377
|
setSnapshot(snapshot: EntitlementSnapshot | null | undefined): void;
|
|
4272
4378
|
getSnapshot(): EntitlementSnapshot;
|
|
@@ -4282,16 +4388,34 @@ declare class PaywallService {
|
|
|
4282
4388
|
* must not be handed out as a free sample.
|
|
4283
4389
|
*/
|
|
4284
4390
|
evaluate(panelId: string): AccessDecision;
|
|
4391
|
+
/** Is this extras block locked by an extras-scoped rule the reader does not satisfy? */
|
|
4392
|
+
isExtraLocked(extraId: string): boolean;
|
|
4285
4393
|
/** Convenience: may the reader open this panel? */
|
|
4286
4394
|
canAccess(panelId: string): boolean;
|
|
4287
4395
|
/**
|
|
4288
4396
|
* Describe the gate blocking a panel, or null when it is not gated.
|
|
4289
4397
|
* The shape is the player's existing `PaywallGate`, so the overlay needs
|
|
4290
|
-
* no changes to render it.
|
|
4398
|
+
* no changes to render it. `locale` picks the language of product names
|
|
4399
|
+
* and descriptions from `paywall.products` (fallback: the work's default
|
|
4400
|
+
* locale).
|
|
4401
|
+
*/
|
|
4402
|
+
gateFor(panelId: string, locale?: LocaleCode): PaywallGate | null;
|
|
4403
|
+
/**
|
|
4404
|
+
* What the reader can buy to pass a rule: one option per required product
|
|
4405
|
+
* (purchase) or per subscription tier (subscription). Without explicit
|
|
4406
|
+
* ids, the rule's `requireEntitlement` key names the product, else the
|
|
4407
|
+
* rule id. Age gates and free rules offer nothing to buy.
|
|
4408
|
+
*
|
|
4409
|
+
* Labels (format 1.6): an option whose id has an entry in
|
|
4410
|
+
* `paywall.products` takes that entry's localized name, description and
|
|
4411
|
+
* price. Otherwise it falls back to the rule's name (a single option) or
|
|
4412
|
+
* the bare id (several options), and to the rule's description and price.
|
|
4291
4413
|
*/
|
|
4292
|
-
|
|
4414
|
+
static purchaseOptions(rule: EvaluatorRule, products?: ReadonlyMap<string, PaywallProduct>, locale?: LocaleCode, fallbackLocale?: LocaleCode): PurchaseInfo[];
|
|
4293
4415
|
/** The rule that gates a panel, for callers that need its price or name. */
|
|
4294
4416
|
ruleFor(panelId: string): EvaluatorRule | null;
|
|
4417
|
+
/** The work's default locale (product-label fallback). */
|
|
4418
|
+
private get defaultLocale();
|
|
4295
4419
|
/** Reset to a manifest-less, entitlement-less state. */
|
|
4296
4420
|
clear(): void;
|
|
4297
4421
|
/**
|
|
@@ -5345,9 +5469,10 @@ declare class PaywallOverlayComponent {
|
|
|
5345
5469
|
*/
|
|
5346
5470
|
getMessage(): string;
|
|
5347
5471
|
/**
|
|
5348
|
-
* Handle purchase option selection
|
|
5472
|
+
* Handle purchase option selection: `purchase` carries the product id,
|
|
5473
|
+
* `action` is 'subscribe' for a subscription option, else 'purchase'.
|
|
5349
5474
|
*/
|
|
5350
|
-
onPurchaseOption(
|
|
5475
|
+
onPurchaseOption(option: PurchaseInfo): void;
|
|
5351
5476
|
/**
|
|
5352
5477
|
* Handle login action
|
|
5353
5478
|
*/
|
|
@@ -5444,6 +5569,8 @@ interface AgeVerificationResult {
|
|
|
5444
5569
|
* Modal overlay for age verification
|
|
5445
5570
|
*/
|
|
5446
5571
|
declare class AgeGateComponent {
|
|
5572
|
+
/** Optional: the gate is a public component and works (in English) without ngx-translate. */
|
|
5573
|
+
private readonly translate;
|
|
5447
5574
|
/**
|
|
5448
5575
|
* Visibility state
|
|
5449
5576
|
*/
|
|
@@ -5490,6 +5617,8 @@ declare class AgeGateComponent {
|
|
|
5490
5617
|
* Get warning message
|
|
5491
5618
|
*/
|
|
5492
5619
|
getWarningMessage(): string;
|
|
5620
|
+
/** Translate an `age_gate.*` UI string (English fallback). */
|
|
5621
|
+
t(key: string, params?: Record<string, unknown>): string;
|
|
5493
5622
|
/**
|
|
5494
5623
|
* Handle verification submit
|
|
5495
5624
|
*/
|
|
@@ -5506,8 +5635,9 @@ declare class AgeGateComponent {
|
|
|
5506
5635
|
* Calculate age from birth date
|
|
5507
5636
|
*/
|
|
5508
5637
|
private calculateAge;
|
|
5638
|
+
private monthCache?;
|
|
5509
5639
|
/**
|
|
5510
|
-
*
|
|
5640
|
+
* Month options, named in the current locale (Intl; cached per locale).
|
|
5511
5641
|
*/
|
|
5512
5642
|
getMonthOptions(): {
|
|
5513
5643
|
value: string;
|
|
@@ -5537,12 +5667,18 @@ declare class AgeGateComponent {
|
|
|
5537
5667
|
interface BranchChoice {
|
|
5538
5668
|
/** The graph edge this choice traverses. */
|
|
5539
5669
|
edge: Edge;
|
|
5540
|
-
/**
|
|
5670
|
+
/**
|
|
5671
|
+
* Reader-facing label (edge label → target panel title). Empty: the
|
|
5672
|
+
* chooser shows a translated "Option N".
|
|
5673
|
+
*/
|
|
5541
5674
|
label: string;
|
|
5542
5675
|
/** Position in the offered list (0-based), stable for tracking. */
|
|
5543
5676
|
index: number;
|
|
5544
5677
|
}
|
|
5545
5678
|
declare class BranchChooserComponent {
|
|
5679
|
+
private readonly translate;
|
|
5680
|
+
/** Translate a `branch_chooser.*` UI string (English fallback). */
|
|
5681
|
+
t(key: string, params?: Record<string, unknown>): string;
|
|
5546
5682
|
/** Visible state */
|
|
5547
5683
|
visible: boolean;
|
|
5548
5684
|
/** Current locale (labels are already resolved by the shell). */
|
|
@@ -5582,7 +5718,7 @@ interface EntitlementAdapter {
|
|
|
5582
5718
|
* Player Shell Component
|
|
5583
5719
|
* Main orchestrator for the PanelWave player
|
|
5584
5720
|
*/
|
|
5585
|
-
declare class PlayerShellComponent implements OnInit, OnDestroy {
|
|
5721
|
+
declare class PlayerShellComponent implements OnInit, OnChanges, OnDestroy {
|
|
5586
5722
|
/**
|
|
5587
5723
|
* Manifest to load
|
|
5588
5724
|
*/
|
|
@@ -5614,12 +5750,16 @@ declare class PlayerShellComponent implements OnInit, OnDestroy {
|
|
|
5614
5750
|
/** Bearer token identifying the reader to `entitlementEndpoint`. */
|
|
5615
5751
|
readerToken?: string;
|
|
5616
5752
|
/**
|
|
5617
|
-
* Emitted when a reader acts on the paywall overlay
|
|
5618
|
-
*
|
|
5753
|
+
* Emitted when a reader acts on the paywall overlay: `purchase` /
|
|
5754
|
+
* `subscribe` (with the chosen option's `productId` — a product id or a
|
|
5755
|
+
* subscription tier), `login` or `dismiss`. The host owns checkout — the
|
|
5756
|
+
* player never talks to a payment provider itself; call
|
|
5757
|
+
* `refreshEntitlements()` (or pass a new `entitlementSnapshot`) afterwards.
|
|
5619
5758
|
*/
|
|
5620
5759
|
paywallAction: EventEmitter<{
|
|
5621
5760
|
action: PaywallAction;
|
|
5622
5761
|
gate: PaywallGate;
|
|
5762
|
+
productId?: string;
|
|
5623
5763
|
}>;
|
|
5624
5764
|
/**
|
|
5625
5765
|
* Emitted after the reader answers an `age_gate` rule's overlay (verified or
|
|
@@ -5711,12 +5851,10 @@ declare class PlayerShellComponent implements OnInit, OnDestroy {
|
|
|
5711
5851
|
*/
|
|
5712
5852
|
ready: EventEmitter<void>;
|
|
5713
5853
|
/**
|
|
5714
|
-
*
|
|
5854
|
+
* The current panel changed. Carries the panel's id (`panelId`, its key in
|
|
5855
|
+
* `chapter.panels`) and the id of the panel before it (`previousPanelId`).
|
|
5715
5856
|
*/
|
|
5716
|
-
panelChange: EventEmitter<
|
|
5717
|
-
panel: Panel;
|
|
5718
|
-
chapter: Chapter;
|
|
5719
|
-
}>;
|
|
5857
|
+
panelChange: EventEmitter<PlayerPanelChangeEvent>;
|
|
5720
5858
|
/**
|
|
5721
5859
|
* Chapter changed
|
|
5722
5860
|
*/
|
|
@@ -5802,6 +5940,8 @@ declare class PlayerShellComponent implements OnInit, OnDestroy {
|
|
|
5802
5940
|
*/
|
|
5803
5941
|
paywallGate: PaywallGate | null;
|
|
5804
5942
|
paywallVisible: boolean;
|
|
5943
|
+
/** Product id / tier of the overlay option the reader just picked. */
|
|
5944
|
+
paywallProductId?: string;
|
|
5805
5945
|
/** Adapter built from `entitlementEndpoint`, when the host supplied one. */
|
|
5806
5946
|
private httpEntitlement?;
|
|
5807
5947
|
/**
|
|
@@ -5969,6 +6109,8 @@ declare class PlayerShellComponent implements OnInit, OnDestroy {
|
|
|
5969
6109
|
private analyticsSessionEnded;
|
|
5970
6110
|
private workCompleteTracked;
|
|
5971
6111
|
private lastTrackedPanelId?;
|
|
6112
|
+
/** Id of the panel of the last `panelChange` emission (its `previousPanelId` source). */
|
|
6113
|
+
private lastPanelChangeId?;
|
|
5972
6114
|
/** Bound pagehide handler so add/removeEventListener match. */
|
|
5973
6115
|
private readonly onPageHide;
|
|
5974
6116
|
private readonly playerState;
|
|
@@ -5978,10 +6120,30 @@ declare class PlayerShellComponent implements OnInit, OnDestroy {
|
|
|
5978
6120
|
private readonly translationService;
|
|
5979
6121
|
private readonly canvasCamera;
|
|
5980
6122
|
private readonly paywallService;
|
|
6123
|
+
/** ngOnInit ran: later input changes are live updates, not initial values. */
|
|
6124
|
+
private initialized;
|
|
6125
|
+
/** The state subscriptions are set up once per instance, not per (re)load. */
|
|
6126
|
+
private stateSubscribed;
|
|
5981
6127
|
/**
|
|
5982
6128
|
* Initialize component
|
|
5983
6129
|
*/
|
|
5984
6130
|
ngOnInit(): void;
|
|
6131
|
+
/**
|
|
6132
|
+
* Inputs changed after init. The first round (before ngOnInit) is skipped:
|
|
6133
|
+
* ngOnInit reads every input itself, so nothing loads twice.
|
|
6134
|
+
*/
|
|
6135
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
6136
|
+
/**
|
|
6137
|
+
* Reload the work from the current `manifest` / `manifestUrl` inputs
|
|
6138
|
+
* (also the error screen's Retry). Story state of the previous load —
|
|
6139
|
+
* position, variables except persistent ones, open overlays, autoplay —
|
|
6140
|
+
* is reset; the analytics session of the previous work is closed.
|
|
6141
|
+
*/
|
|
6142
|
+
reload(): Promise<void>;
|
|
6143
|
+
/** Content locale + GUI language follow `locale`. */
|
|
6144
|
+
private applyLocale;
|
|
6145
|
+
/** Apply a changed `viewModeOverride` to the running view. */
|
|
6146
|
+
private applyViewModeOverride;
|
|
5985
6147
|
/**
|
|
5986
6148
|
* Cleanup on destroy
|
|
5987
6149
|
*/
|
|
@@ -6041,6 +6203,12 @@ declare class PlayerShellComponent implements OnInit, OnDestroy {
|
|
|
6041
6203
|
* one-time `work_complete` signal.
|
|
6042
6204
|
*/
|
|
6043
6205
|
private trackPanelView;
|
|
6206
|
+
/**
|
|
6207
|
+
* A panel's id: its key in `chapter.panels`. Panels don't reliably carry
|
|
6208
|
+
* their own id (`Panel.id` is optional in the format), so resolve it by
|
|
6209
|
+
* identity, as getCurrentPanelId() does.
|
|
6210
|
+
*/
|
|
6211
|
+
private panelIdOf;
|
|
6044
6212
|
/** An end panel (no outgoing edges) of the manifest's last chapter. */
|
|
6045
6213
|
private isEndOfWork;
|
|
6046
6214
|
/**
|
|
@@ -6069,8 +6237,11 @@ declare class PlayerShellComponent implements OnInit, OnDestroy {
|
|
|
6069
6237
|
* @param transition - Optional transition to render for this panel change
|
|
6070
6238
|
* (already resolved against the outputPresets default). Omitted for
|
|
6071
6239
|
* non-adjacent jumps (TOC, initial load), which swap instantly.
|
|
6240
|
+
* @param mutations - Variable mutations of the traversed edge. Applied only
|
|
6241
|
+
* once the navigation is allowed (after the paywall / age gate), so a
|
|
6242
|
+
* blocked attempt never changes story state.
|
|
6072
6243
|
*/
|
|
6073
|
-
navigateToPanel(chapterId: string, panelId: string, transition?: Transition, cameraMove?: CameraMove): Promise<void>;
|
|
6244
|
+
navigateToPanel(chapterId: string, panelId: string, transition?: Transition, cameraMove?: CameraMove, mutations?: Mutation[]): Promise<void>;
|
|
6074
6245
|
/**
|
|
6075
6246
|
* Rebuild the flat variable context handed to the viewport/canvas for
|
|
6076
6247
|
* hotspot visibleIf evaluation. New object identity per call so OnPush
|
|
@@ -6176,6 +6347,8 @@ declare class PlayerShellComponent implements OnInit, OnDestroy {
|
|
|
6176
6347
|
* Toolbar event handlers
|
|
6177
6348
|
*/
|
|
6178
6349
|
onToggleView(): void;
|
|
6350
|
+
/** Land the canvas camera on the current panel (entering canvas view). */
|
|
6351
|
+
private jumpCameraToCurrentPanel;
|
|
6179
6352
|
/**
|
|
6180
6353
|
* Tap on a placed panel in canvas view. Traverses the matching out-edge of
|
|
6181
6354
|
* the current panel when its condition passes (the graph still gates
|
|
@@ -6184,6 +6357,12 @@ declare class PlayerShellComponent implements OnInit, OnDestroy {
|
|
|
6184
6357
|
* state.
|
|
6185
6358
|
*/
|
|
6186
6359
|
onCanvasPanelTap(panelId: string): void;
|
|
6360
|
+
/**
|
|
6361
|
+
* The manifest actually loaded — from `manifest` or fetched via
|
|
6362
|
+
* `manifestUrl`. Everything that lists the work (ToC, thumbnails) binds to
|
|
6363
|
+
* this, never to the `manifest` input, which is unset for URL loading.
|
|
6364
|
+
*/
|
|
6365
|
+
get loadedManifest(): PanelWaveManifest | undefined;
|
|
6187
6366
|
/** Balloon defaults for the canvas stage (same source as the viewport). */
|
|
6188
6367
|
get manifestBalloonConfig(): BalloonConfig | null;
|
|
6189
6368
|
/** Manifest characters for speech-bubble styling in canvas view. */
|
|
@@ -6452,9 +6631,15 @@ declare class PlayerShellComponent implements OnInit, OnDestroy {
|
|
|
6452
6631
|
private restoreSocialState;
|
|
6453
6632
|
/** `bookmarked` is true only while the reader is ON the bookmarked panel. */
|
|
6454
6633
|
private syncBookmarkFlag;
|
|
6455
|
-
/**
|
|
6634
|
+
/**
|
|
6635
|
+
* At least two paths out of the current panel are open right now (edge
|
|
6636
|
+
* conditions evaluated exactly like the chooser does) — the toolbar shows
|
|
6637
|
+
* "Choices". A closed conditional edge does not count.
|
|
6638
|
+
*/
|
|
6456
6639
|
get hasBranchesAhead(): boolean;
|
|
6457
|
-
/** Outgoing edges whose conditions pass right now
|
|
6640
|
+
/** Outgoing edges of the current panel whose conditions pass right now. */
|
|
6641
|
+
private openEdges;
|
|
6642
|
+
/** Open outgoing edges with reader-facing labels. */
|
|
6458
6643
|
private computeBranchChoices;
|
|
6459
6644
|
private branchLabel;
|
|
6460
6645
|
private localizedText;
|
|
@@ -7185,5 +7370,5 @@ declare class PlayerComponent {
|
|
|
7185
7370
|
static ɵcmp: i0.ɵɵComponentDeclaration<PlayerComponent, "pw-player", never, {}, {}, never, never, true, never>;
|
|
7186
7371
|
}
|
|
7187
7372
|
|
|
7188
|
-
export { ANONYMOUS_READER, ActionModalComponent, AgeGateComponent, AudioEngineService, BranchChooserComponent, CANVAS_PANEL_BUDGET, CanvasCameraService, CanvasStageComponent, ComicBalloon, DEFAULT_BALLOON_CONFIG, DEFAULT_STALL_TIMEOUT_MS, DEFAULT_VIDEO_MUTED, DEFAULT_VIDEO_PLAY_MODE, DEFAULT_VIDEO_START_MODE, EntitlementError, EntitlementService, ExportService, FlowEngineService, HotspotActionService, HotspotsOverlayComponent, HttpEntitlementAdapter, ImageCacheService, ManifestService, MockEntitlementAdapter, NullEntitlementAdapter, PANEL_AUDIO_LEAVE_FADE_MS, PanelAudioService, PaywallOverlayComponent, PaywallService, PlayerComponent, PlayerEvent, PlayerService, PlayerShellComponent, PlayerStateService, PluginHostService, PluginSandboxComponent, PreloadService, PwIconComponent, RESERVED_NAMESPACES, SpeechBubblesComponent, TrackingService, TranslationService, UserGestureService, VISIBILITY_THRESHOLD, VariableStoreService, VideoControllerService, VideoLayerComponent, VideoSequencerService, VisibilityService, applyVariantOverrides, balloonConfigToRenderOptions, balloonConfigToTailOptions, busForRole, createBalloon, evaluatePanelAccess, evaluateWorkAccess, findWorkGateRule, fromManifestRule, mergeBalloonConfig, readingOrderFromManifest, resolveMuted, resolvePanelVariant, resolvePanels, resolvePlayMode, resolveStartMode, resolveVideoConfig, rulesFromManifest, satisfiesRule, selectVariant, toEntitlementStatus };
|
|
7189
|
-
export type { AccessDecision, AgeVerificationResult, AssetBase, AssetCatalogItem, AssetCatalogItemAudio, AssetCatalogItemImage, AssetCatalogItemJson, AssetCatalogItemPluginPayload, AssetCatalogItemSubtitle, AssetCatalogItemVector, AssetCatalogItemVideo, AssetCategory, AssetCommon, AssetRef, AssetReference, AssetVariant, Assets, AudioLayer, AudioRole, AudioTrack, AudioVariant, BalloonConfig, BalloonConfigOverride, BalloonOptions, BalloonRenderResult, BalloonType, Bookmark, BoundingBox, BranchChoice, BubbleStyle, BubbleTail, CameraMove, CameraMovePath, CameraState, CameraZoomProfile, CanvasBackground, CanvasCameraPolicy, CanvasDecoration, CanvasFitMode, CanvasFreeRoam, CanvasLayout, CanvasOverviewPolicy, CanvasPlacement, CanvasRevealMode, Chapter, Character$1 as Character, ContentWarning, Creator, DecisionEvent, DeepLinkTarget, DeviceVariables, Edge, EffectiveVideoConfig, EntitlementAdapter$1 as EntitlementAdapter, EntitlementContext, EntitlementErrorCode, EntitlementSnapshot, EntitlementSnapshotResponse, EntitlementStatus, EntitlementVariables, ErrorEvent$1 as ErrorEvent, EvaluatorEntitlementType, EvaluatorRule, EvaluatorScope, ExtraImage, ExtraItem, Extras, FormatView, Graph, HideBorderConfig, Hotspot, HotspotAction, HotspotCircle, HotspotGoToAction, HotspotOpenExtrasAction, HotspotOpenModalAction, HotspotPluginEventAction, HotspotPolygon, HotspotRect, HotspotSetVariablesAction, HotspotShape, HotspotUiEffect, HttpEntitlementAdapterConfig, ImageLayer, ImageVariant, JsonLogic, JsonLogicExpression, JsonValue, JsonVariant, Layer, LayerKind, LayerViewMode, LocaleCode, LocalizedString, LockReason, Meta, Mutation, MutationOperation, NavigationPath, NodeMetadata, NormalizedPoint, NormalizedRect, OutputFormat, OutputPreset, OverlayState, Page, PageLayout, Panel, PanelAudioRole, PanelAudioTrack, PanelChangeEvent, PanelPartial, PanelPlacement, PanelRef, PanelVariant, PanelWaveManifest, PanelwaveHeader, Paywall, PaywallAction, PaywallEvent, PaywallGate$1 as PaywallGate, PaywallRule, PlaybackState, PlayerError, PlayerErrorCode, PlayerEventData, PlayerOptions, PlayerPreferences, PlayerState, PlayerStatistics, PluginInstance$1 as PluginInstance, PluginLayer, PreferenceVariables, PreloadItem, PreloadPriority, PreloadSettings, PreloadStatus$1 as PreloadStatus, PreviewInfo, PurchaseInfo, ReadingProgress, ResolvedPanel, ResolvedPanelAudio, SequenceAudioTrack, SequencedVideo, SequencedVideoInfo, Settings, SpeechBubble, StagePlacement, SubtitleVariant, TailConfig, TailCurve, TailOptions, TextLayer, TextStyle, Tracking, TrackingConfig$1 as TrackingConfig, TrackingEvent, Transform, Transition, TraversalOptions, TraversalResult, UIDefaults, UISettings, UserInfo, UserVariables, VariableChangeEvent, VariableContext, VariableDefinition, VariableMutation, VariableScope, VariableStore, VariableType, VariableValidationResult, Variables, VariantContext, VectorVariant, VideoEvent, VideoLayer, VideoPlayMode, VideoPoster, VideoStartMode, VideoState, VideoStatus, VideoTrackingPayload, VideoTrigger, VideoVariant, ViewMode, ViewportState, VisibilityChange, WorldPoint, WorldRect };
|
|
7373
|
+
export { ANONYMOUS_READER, ActionModalComponent, AgeGateComponent, AudioEngineService, BranchChooserComponent, CANVAS_PANEL_BUDGET, CanvasCameraService, CanvasStageComponent, ComicBalloon, DEFAULT_BALLOON_CONFIG, DEFAULT_STALL_TIMEOUT_MS, DEFAULT_VIDEO_MUTED, DEFAULT_VIDEO_PLAY_MODE, DEFAULT_VIDEO_START_MODE, EntitlementError, EntitlementService, ExportService, FlowEngineService, HotspotActionService, HotspotsOverlayComponent, HttpEntitlementAdapter, ImageCacheService, ManifestService, MockEntitlementAdapter, NullEntitlementAdapter, PANEL_AUDIO_LEAVE_FADE_MS, PanelAudioService, PaywallOverlayComponent, PaywallService, PlayerComponent, PlayerEvent, PlayerService, PlayerShellComponent, PlayerStateService, PluginHostService, PluginSandboxComponent, PreloadService, PwIconComponent, RESERVED_NAMESPACES, SpeechBubblesComponent, TrackingService, TranslationService, UserGestureService, VISIBILITY_THRESHOLD, VariableStoreService, VideoControllerService, VideoLayerComponent, VideoSequencerService, VisibilityService, applyVariantOverrides, balloonConfigToRenderOptions, balloonConfigToTailOptions, busForRole, chapterOrderFromManifest, createBalloon, evaluatePanelAccess, evaluateWorkAccess, findWorkGateRule, fromManifestRule, isExtraLocked, mergeBalloonConfig, readingOrderFromManifest, resolveMuted, resolvePanelVariant, resolvePanels, resolvePlayMode, resolveStartMode, resolveVideoConfig, rulesFromManifest, satisfiesRule, selectVariant, toEntitlementStatus };
|
|
7374
|
+
export type { AccessDecision, AgeVerificationResult, AssetBase, AssetCatalogItem, AssetCatalogItemAudio, AssetCatalogItemImage, AssetCatalogItemJson, AssetCatalogItemPluginPayload, AssetCatalogItemSubtitle, AssetCatalogItemVector, AssetCatalogItemVideo, AssetCategory, AssetCommon, AssetRef, AssetReference, AssetVariant, Assets, AudioLayer, AudioRole, AudioTrack, AudioVariant, BalloonConfig, BalloonConfigOverride, BalloonOptions, BalloonRenderResult, BalloonType, Bookmark, BoundingBox, BranchChoice, BubbleStyle, BubbleTail, CameraMove, CameraMovePath, CameraState, CameraZoomProfile, CanvasBackground, CanvasCameraPolicy, CanvasDecoration, CanvasFitMode, CanvasFreeRoam, CanvasLayout, CanvasOverviewPolicy, CanvasPlacement, CanvasRevealMode, Chapter, Character$1 as Character, ContentWarning, Creator, DecisionEvent, DeepLinkTarget, DeviceVariables, Edge, EffectiveVideoConfig, EntitlementAdapter$1 as EntitlementAdapter, EntitlementContext, EntitlementErrorCode, EntitlementSnapshot, EntitlementSnapshotResponse, EntitlementStatus, EntitlementVariables, ErrorEvent$1 as ErrorEvent, EvaluatorEntitlementType, EvaluatorRule, EvaluatorScope, ExtraImage, ExtraItem, Extras, FormatView, Graph, HideBorderConfig, Hotspot, HotspotAction, HotspotCircle, HotspotGoToAction, HotspotOpenExtrasAction, HotspotOpenModalAction, HotspotPluginEventAction, HotspotPolygon, HotspotRect, HotspotSetVariablesAction, HotspotShape, HotspotUiEffect, HttpEntitlementAdapterConfig, ImageLayer, ImageVariant, JsonLogic, JsonLogicExpression, JsonValue, JsonVariant, Layer, LayerKind, LayerViewMode, LocaleCode, LocalizedString, LockReason, Meta, Mutation, MutationOperation, NavigationPath, NodeMetadata, NormalizedPoint, NormalizedRect, OutputFormat, OutputPreset, OverlayState, Page, PageLayout, Panel, PanelAudioRole, PanelAudioTrack, PanelChangeEvent, PanelPartial, PanelPlacement, PanelRef, PanelVariant, PanelWaveManifest, PanelwaveHeader, Paywall, PaywallAction, PaywallEvent, PaywallGate$1 as PaywallGate, PaywallProduct, PaywallRule, PlaybackState, PlayerError, PlayerErrorCode, PlayerEventData, PlayerOptions, PlayerPanelChangeEvent, PlayerPreferences, PlayerState, PlayerStatistics, PluginInstance$1 as PluginInstance, PluginLayer, PreferenceVariables, PreloadItem, PreloadPriority, PreloadSettings, PreloadStatus$1 as PreloadStatus, PreviewInfo, PurchaseInfo, ReadingProgress, ResolvedPanel, ResolvedPanelAudio, SequenceAudioTrack, SequencedVideo, SequencedVideoInfo, Settings, SpeechBubble, StagePlacement, SubtitleVariant, TailConfig, TailCurve, TailOptions, TextLayer, TextStyle, Tracking, TrackingConfig$1 as TrackingConfig, TrackingEvent, Transform, Transition, TraversalOptions, TraversalResult, UIDefaults, UISettings, UserInfo, UserVariables, VariableChangeEvent, VariableContext, VariableDefinition, VariableMutation, VariableScope, VariableStore, VariableType, VariableValidationResult, Variables, VariantContext, VectorVariant, VideoEvent, VideoLayer, VideoPlayMode, VideoPoster, VideoStartMode, VideoState, VideoStatus, VideoTrackingPayload, VideoTrigger, VideoVariant, ViewMode, ViewportState, VisibilityChange, WorldPoint, WorldRect };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@panelwave/player",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Open-source Angular library for PanelWave interactive graphic novels",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
"url": "https://github.com/panelwave/player/issues"
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|
|
22
|
-
"@angular/common": "^20.0.0",
|
|
23
|
-
"@angular/core": "^20.0.0",
|
|
24
|
-
"@ngx-translate/core": "^17.0.0",
|
|
22
|
+
"@angular/common": "^20.0.0 || ^21.0.0 || ^22.0.0",
|
|
23
|
+
"@angular/core": "^20.0.0 || ^21.0.0 || ^22.0.0",
|
|
24
|
+
"@ngx-translate/core": "^17.0.0 || ^18.0.0",
|
|
25
25
|
"rxjs": "^7.8.0"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
package/src/assets/i18n/de.json
CHANGED
|
@@ -180,7 +180,11 @@
|
|
|
180
180
|
"sign_in": "Anmelden, um fortzufahren",
|
|
181
181
|
"go_back": "Zurück",
|
|
182
182
|
"maybe_later": "Vielleicht später",
|
|
183
|
-
"secure_payment": "Sichere Zahlungsabwicklung"
|
|
183
|
+
"secure_payment": "Sichere Zahlungsabwicklung",
|
|
184
|
+
"reason_subscription_required": "Dieser Teil der Geschichte ist im Abo enthalten.",
|
|
185
|
+
"reason_purchase_required": "Dieser Teil der Geschichte ist käuflich erhältlich.",
|
|
186
|
+
"reason_age_verification_required": "Dieser Inhalt ist altersbeschränkt. Bestätige dein Alter, um fortzufahren.",
|
|
187
|
+
"reason_entitlement_required": "Für diesen Inhalt ist eine Berechtigung erforderlich."
|
|
184
188
|
},
|
|
185
189
|
"loading": {
|
|
186
190
|
"text": "PanelWave wird geladen..."
|
|
@@ -191,5 +195,26 @@
|
|
|
191
195
|
},
|
|
192
196
|
"common": {
|
|
193
197
|
"esc": "Esc"
|
|
198
|
+
},
|
|
199
|
+
"age_gate": {
|
|
200
|
+
"title": "Altersprüfung erforderlich",
|
|
201
|
+
"close": "Schließen",
|
|
202
|
+
"warning": "Dieser Inhalt ist nur für Personen ab {{age}} Jahren freigegeben.",
|
|
203
|
+
"prompt": "Bitte gib dein Geburtsdatum ein:",
|
|
204
|
+
"month": "Monat",
|
|
205
|
+
"day": "Tag",
|
|
206
|
+
"year": "Jahr",
|
|
207
|
+
"verify": "Alter bestätigen",
|
|
208
|
+
"privacy": "Deine Angaben sind privat und werden nicht gespeichert.",
|
|
209
|
+
"error_incomplete": "Bitte gib dein vollständiges Geburtsdatum ein.",
|
|
210
|
+
"error_month": "Bitte gib einen gültigen Monat ein (1-12).",
|
|
211
|
+
"error_day": "Bitte gib einen gültigen Tag ein (1-{{max}}).",
|
|
212
|
+
"error_year": "Bitte gib ein gültiges Jahr ein (1900-{{max}}).",
|
|
213
|
+
"error_too_young": "Du musst mindestens {{age}} Jahre alt sein, um diesen Inhalt zu sehen."
|
|
214
|
+
},
|
|
215
|
+
"branch_chooser": {
|
|
216
|
+
"title": "Wähle deinen Weg",
|
|
217
|
+
"close": "Schließen",
|
|
218
|
+
"option": "Option {{n}}"
|
|
194
219
|
}
|
|
195
220
|
}
|
package/src/assets/i18n/en.json
CHANGED
|
@@ -180,7 +180,11 @@
|
|
|
180
180
|
"sign_in": "Sign In to Continue",
|
|
181
181
|
"go_back": "Go Back",
|
|
182
182
|
"maybe_later": "Maybe Later",
|
|
183
|
-
"secure_payment": "Secure payment processing"
|
|
183
|
+
"secure_payment": "Secure payment processing",
|
|
184
|
+
"reason_subscription_required": "This part of the story is included with a subscription.",
|
|
185
|
+
"reason_purchase_required": "This part of the story is available to buy.",
|
|
186
|
+
"reason_age_verification_required": "This content is age-restricted. Confirm your age to continue.",
|
|
187
|
+
"reason_entitlement_required": "This content requires an entitlement to access."
|
|
184
188
|
},
|
|
185
189
|
"loading": {
|
|
186
190
|
"text": "Loading PanelWave..."
|
|
@@ -191,5 +195,26 @@
|
|
|
191
195
|
},
|
|
192
196
|
"common": {
|
|
193
197
|
"esc": "Esc"
|
|
198
|
+
},
|
|
199
|
+
"age_gate": {
|
|
200
|
+
"title": "Age Verification Required",
|
|
201
|
+
"close": "Close",
|
|
202
|
+
"warning": "This content is restricted to users {{age}} years of age or older.",
|
|
203
|
+
"prompt": "Please enter your birth date:",
|
|
204
|
+
"month": "Month",
|
|
205
|
+
"day": "Day",
|
|
206
|
+
"year": "Year",
|
|
207
|
+
"verify": "Verify Age",
|
|
208
|
+
"privacy": "Your information is private and will not be stored.",
|
|
209
|
+
"error_incomplete": "Please enter your complete birth date.",
|
|
210
|
+
"error_month": "Please enter a valid month (1-12).",
|
|
211
|
+
"error_day": "Please enter a valid day (1-{{max}}).",
|
|
212
|
+
"error_year": "Please enter a valid year (1900-{{max}}).",
|
|
213
|
+
"error_too_young": "You must be at least {{age}} years old to access this content."
|
|
214
|
+
},
|
|
215
|
+
"branch_chooser": {
|
|
216
|
+
"title": "Choose your path",
|
|
217
|
+
"close": "Close",
|
|
218
|
+
"option": "Option {{n}}"
|
|
194
219
|
}
|
|
195
220
|
}
|