@datamoc/mw_games 0.12.0 → 0.13.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/dist/core/DialogueText.d.ts +47 -0
  3. package/dist/core/DialogueText.d.ts.map +1 -0
  4. package/dist/core/DialogueText.js +43 -0
  5. package/dist/core/DialogueText.js.map +1 -0
  6. package/dist/core/Twee.d.ts +67 -0
  7. package/dist/core/Twee.d.ts.map +1 -0
  8. package/dist/core/Twee.js +140 -0
  9. package/dist/core/Twee.js.map +1 -0
  10. package/dist/core/index.d.ts +4 -0
  11. package/dist/core/index.d.ts.map +1 -1
  12. package/dist/core/index.js +2 -0
  13. package/dist/core/index.js.map +1 -1
  14. package/dist/mw_games.global.js +108 -107
  15. package/dist/rpg/EventRunner.d.ts +20 -0
  16. package/dist/rpg/EventRunner.d.ts.map +1 -1
  17. package/dist/rpg/EventRunner.js +52 -11
  18. package/dist/rpg/EventRunner.js.map +1 -1
  19. package/dist/rpg/dialogue-text.d.ts +81 -0
  20. package/dist/rpg/dialogue-text.d.ts.map +1 -0
  21. package/dist/rpg/dialogue-text.js +88 -0
  22. package/dist/rpg/dialogue-text.js.map +1 -0
  23. package/dist/rpg/index.d.ts +4 -1
  24. package/dist/rpg/index.d.ts.map +1 -1
  25. package/dist/rpg/index.js +2 -0
  26. package/dist/rpg/index.js.map +1 -1
  27. package/dist/rpg/twee-events.d.ts +48 -0
  28. package/dist/rpg/twee-events.d.ts.map +1 -0
  29. package/dist/rpg/twee-events.js +35 -0
  30. package/dist/rpg/twee-events.js.map +1 -0
  31. package/dist/two-d/stage/dialogue-text.d.ts +81 -0
  32. package/dist/two-d/stage/dialogue-text.d.ts.map +1 -0
  33. package/dist/two-d/stage/dialogue-text.js +95 -0
  34. package/dist/two-d/stage/dialogue-text.js.map +1 -0
  35. package/dist/two-d/stage/index.d.ts +1 -0
  36. package/dist/two-d/stage/index.d.ts.map +1 -1
  37. package/dist/two-d/stage/index.js +1 -0
  38. package/dist/two-d/stage/index.js.map +1 -1
  39. package/dist/two-d/stage/twee.d.ts +7 -25
  40. package/dist/two-d/stage/twee.d.ts.map +1 -1
  41. package/dist/two-d/stage/twee.js +10 -162
  42. package/dist/two-d/stage/twee.js.map +1 -1
  43. package/dist/version.d.ts +1 -1
  44. package/dist/version.js +1 -1
  45. package/package.json +1 -1
@@ -6,6 +6,8 @@ export interface EventChoice {
6
6
  text: string;
7
7
  value?: unknown;
8
8
  disabled?: boolean;
9
+ /** the passage to jump to when this choice is picked, in an `EventRunner.runStory` story */
10
+ goto?: string;
9
11
  }
10
12
  /** what the runner wants shown; how it looks is the presenter's business entirely */
11
13
  export interface DialogueRequest {
@@ -70,9 +72,18 @@ export type EventCommand = {
70
72
  target: string;
71
73
  steps: MoveStep[];
72
74
  };
75
+ } | {
76
+ goto: string;
73
77
  } | {
74
78
  call: (state: EventRunnerState) => void | Promise<void>;
75
79
  };
80
+ /**
81
+ * A branching event script: named passages, the same graph shape `two-d/stage`'s
82
+ * `StoryScript` is - a passage runs until it falls off the end, a `{ goto }` command or a
83
+ * choice's own `goto` jumps to a different one. `EventRunner.runStory` follows it the same
84
+ * way `StageScript.runStory` follows a `StoryScript`.
85
+ */
86
+ export type EventStoryScript = Record<string, readonly EventCommand[]>;
76
87
  export interface EventRunnerState {
77
88
  game: GameState;
78
89
  /** whatever `ask` commands have stored, keyed by their `store` name */
@@ -106,6 +117,15 @@ export declare class EventRunner {
106
117
  constructor(options: EventRunnerOptions);
107
118
  cancel(): void;
108
119
  run(commands: readonly EventCommand[]): Promise<EventRunnerState>;
120
+ /**
121
+ * Runs a graph of passages starting at `start`, following `goto` commands and choice
122
+ * jumps until a passage runs out or the script is cancelled - the `EventCommand`
123
+ * counterpart to `StageScript.runStory`.
124
+ */
125
+ runStory(story: EventStoryScript, start: string): Promise<EventRunnerState>;
126
+ /** runs a plain list of commands, returning the passage to jump to, if any */
127
+ private runList;
128
+ /** runs one command; returns the passage to jump to, if the command jumps anywhere */
109
129
  private step;
110
130
  private speak;
111
131
  }
@@ -1 +1 @@
1
- {"version":3,"file":"EventRunner.d.ts","sourceRoot":"","sources":["../../src/rpg/EventRunner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qFAAqF;AACrF,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,wGAAwG;IACxG,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,6FAA6F;IAC7F,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAC/E,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,WAAW,QAAQ;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACX;AAED;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GACrB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GACrD;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,WAAW,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7F;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACrC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,EAAE,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,YAAY,EAAE,CAAC;IAAC,IAAI,CAAC,EAAE,YAAY,EAAE,CAAA;CAAE,GACnE;IAAE,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,QAAQ,EAAE,CAAA;KAAE,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC;AAE/D,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,SAAS,CAAC;IAChB,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,kBAAkB;IAClC,qFAAqF;IACrF,OAAO,EAAE,iBAAiB,CAAC;IAE3B,IAAI,EAAE,SAAS,CAAC;IAEhB,sFAAsF;IACtF,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,QAAQ,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrE;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,WAAW;IACvB,OAAO,CAAC,OAAO,CAAqB;IACpC,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IACjC,OAAO,CAAC,SAAS,CAAS;IAE1B,YAAY,OAAO,EAAE,kBAAkB,EAGtC;IAED,MAAM,IAAI,IAAI,CAEb;IAEK,GAAG,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAMtE;YAEa,IAAI;IAiDlB,OAAO,CAAC,KAAK;CAQb"}
1
+ {"version":3,"file":"EventRunner.d.ts","sourceRoot":"","sources":["../../src/rpg/EventRunner.ts"],"names":[],"mappings":"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"}
@@ -23,53 +23,94 @@ export class EventRunner {
23
23
  this.cancelled = true;
24
24
  }
25
25
  async run(commands) {
26
- for (const command of commands) {
26
+ const jump = await this.runList(commands);
27
+ if (jump !== undefined) {
28
+ throw new Error(`a "goto ${jump}" only runs inside runStory, not a straight run`);
29
+ }
30
+ return this.state;
31
+ }
32
+ /**
33
+ * Runs a graph of passages starting at `start`, following `goto` commands and choice
34
+ * jumps until a passage runs out or the script is cancelled - the `EventCommand`
35
+ * counterpart to `StageScript.runStory`.
36
+ */
37
+ async runStory(story, start) {
38
+ if (!Object.prototype.hasOwnProperty.call(story, start)) {
39
+ throw new Error(`this event story has no passage named "${start}"`);
40
+ }
41
+ let commands = story[start];
42
+ let index = 0;
43
+ while (index < commands.length) {
27
44
  if (this.cancelled)
28
45
  break;
29
- await this.step(command);
46
+ const jump = await this.step(commands[index]);
47
+ index++;
48
+ if (jump !== undefined) {
49
+ if (!Object.prototype.hasOwnProperty.call(story, jump)) {
50
+ throw new Error(`this event story has no passage named "${jump}"`);
51
+ }
52
+ commands = story[jump];
53
+ index = 0;
54
+ }
30
55
  }
31
56
  return this.state;
32
57
  }
58
+ /** runs a plain list of commands, returning the passage to jump to, if any */
59
+ async runList(commands) {
60
+ for (const command of commands) {
61
+ if (this.cancelled)
62
+ break;
63
+ const jump = await this.step(command);
64
+ if (jump !== undefined)
65
+ return jump;
66
+ }
67
+ return undefined;
68
+ }
69
+ /** runs one command; returns the passage to jump to, if the command jumps anywhere */
33
70
  async step(command) {
34
71
  if ('say' in command) {
35
72
  await this.speak(command.say, command.speaker, command.portrait);
36
- return;
73
+ return undefined;
37
74
  }
38
75
  if ('ask' in command) {
39
76
  const chosen = await this.speak(command.ask, command.speaker, command.portrait, command.choices);
40
77
  if (command.store)
41
78
  this.state.answers[command.store] = chosen;
42
- return;
79
+ //a MessageBox resolves with the chosen value, which defaults to the text
80
+ return command.choices.find((c) => (c.value ?? c.text) === chosen)?.goto;
43
81
  }
44
82
  if ('wait' in command) {
45
83
  await new Promise((resolve) => setTimeout(resolve, command.wait * 1000));
46
- return;
84
+ return undefined;
47
85
  }
48
86
  if ('setSwitch' in command) {
49
87
  this.state.game.setSwitch(command.setSwitch, command.value);
50
- return;
88
+ return undefined;
51
89
  }
52
90
  if ('setVariable' in command) {
53
91
  this.state.game.setVariable(command.setVariable, command.value);
54
- return;
92
+ return undefined;
55
93
  }
56
94
  if ('addVariable' in command) {
57
95
  const current = this.state.game.variable(command.addVariable);
58
96
  this.state.game.setVariable(command.addVariable, current + command.amount);
59
- return;
97
+ return undefined;
60
98
  }
61
99
  if ('if' in command) {
62
100
  const holds = conditionHolds(command.if, this.state.game);
63
- await this.run(holds ? command.then : (command.else ?? []));
64
- return;
101
+ return this.runList(holds ? command.then : (command.else ?? []));
65
102
  }
66
103
  if ('move' in command) {
67
104
  await this.options.move?.(command.move.target, command.move.steps);
68
- return;
105
+ return undefined;
106
+ }
107
+ if ('goto' in command) {
108
+ return command.goto;
69
109
  }
70
110
  if ('call' in command) {
71
111
  await command.call(this.state);
72
112
  }
113
+ return undefined;
73
114
  }
74
115
  speak(text, speaker, portrait, choices) {
75
116
  return this.options.present({ text, speaker, portrait, choices });
@@ -1 +1 @@
1
- {"version":3,"file":"EventRunner.js","sourceRoot":"","sources":["../../src/rpg/EventRunner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EventRunner.js","sourceRoot":"","sources":["../../src/rpg/EventRunner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import type { Catalog, Direction } from '../i18n/index.ts';
2
+ import type { EventCommand } from './EventRunner.ts';
3
+ /**
4
+ * A terse, line-based text format for straight (non-branching) dialogue - the format a
5
+ * text-only RPG (`core` plus `rpg`, no renderer at all) can use for its own `EventCommand`
6
+ * scripts without depending on `two-d` for anything. `two-d/stage` has its own wrapper
7
+ * around the same parsing engine (`core.parseDialogueLines`) targeting `StageCommand`
8
+ * instead - declared separately for the same reason `EventChoice` is declared separately
9
+ * from `two-d/ui`'s `Choice`: a Pixi-based visual novel that never touches `rpg`'s map
10
+ * events should not have to pull the whole module in just to parse dialogue text, and a
11
+ * text-only RPG should not have to pull in Pixi either. The actual `@id`/`-` parsing logic
12
+ * lives once in `core.parseDialogueLines`, not copied between the two - only the final
13
+ * command shape (`speaker` here, `as` in `two-d/stage`) differs.
14
+ *
15
+ * Three kinds of line:
16
+ *
17
+ * - `@id text` names who is speaking and says `text`; `@id` alone (no text) just registers
18
+ * the speaker, without saying anything yet.
19
+ * - `- text` continues the two-speaker exchange the first two `@id` lines opened,
20
+ * alternating speaker on every line: the first `-` after the two openers goes to
21
+ * whichever of them did not speak last, and so on.
22
+ * - any other non-blank line narrates, with no speaker.
23
+ *
24
+ * ```
25
+ * @alice Hello.
26
+ * @bob Hi!
27
+ * - How are you?
28
+ * - Fine, and you?
29
+ * ```
30
+ *
31
+ * The `-` shorthand is deliberately capped at two speakers: it exists for the two-character
32
+ * back-and-forth, not as a guess at which of three or more people talks next. A third
33
+ * distinct `@id` anywhere in the source is a parse error rather than a silent guess; a scene
34
+ * with more than two speakers writes `@id` on every line instead, same as it does today.
35
+ *
36
+ * Lines reach `EventCommand.say` as plain, untranslated text - a game's own translation step
37
+ * decides how that text reaches a player, the same seam MWL's own `_("...")`-marked strings
38
+ * use (the source text doubles as the catalog key). `extractDialogueCatalog` builds that
39
+ * catalog the same way MWL's `extractCatalog` does, for a game that wants a translator-ready
40
+ * file to start from.
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * import { parseDialogueText, EventRunner, GameState } from '@datamoc/mw_games/rpg';
45
+ *
46
+ * declare const game: GameState;
47
+ *
48
+ * const runner = new EventRunner({
49
+ * game,
50
+ * present: async (request) => {
51
+ * console.log(request.speaker ? `${request.speaker}: ${request.text}` : request.text);
52
+ * },
53
+ * });
54
+ * const commands = parseDialogueText(`
55
+ * @alice Hello.
56
+ * @bob Hi!
57
+ * - How are you?
58
+ * - Fine, and you?
59
+ * `);
60
+ * await runner.run(commands);
61
+ * ```
62
+ */
63
+ export declare function parseDialogueText(source: string): EventCommand[];
64
+ /**
65
+ * Collects every `say`/`ask` line's text into an identity catalog - each key mapping to
66
+ * itself, the same shape MWL's own `extractCatalog` builds from `_("...")`-marked strings -
67
+ * so a translator has real entries to work from instead of a wall of untranslated dialogue.
68
+ *
69
+ * @example
70
+ * ```ts
71
+ * import { parseDialogueText, extractDialogueCatalog } from '@datamoc/mw_games/rpg';
72
+ *
73
+ * const commands = parseDialogueText('@alice Hello.\n');
74
+ * console.log(extractDialogueCatalog(commands).messages); // { 'Hello.': 'Hello.' }
75
+ * ```
76
+ */
77
+ export declare function extractDialogueCatalog(commands: readonly EventCommand[], options?: {
78
+ locale?: string;
79
+ direction?: Direction;
80
+ }): Catalog;
81
+ //# sourceMappingURL=dialogue-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialogue-text.d.ts","sourceRoot":"","sources":["../../src/rpg/dialogue-text.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,EAAE,CAIhE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACrC,QAAQ,EAAE,SAAS,YAAY,EAAE,EACjC,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,CAAA;CAAO,GACtD,OAAO,CAOT"}
@@ -0,0 +1,88 @@
1
+ import { parseDialogueLines } from '../core/DialogueText.js';
2
+ /**
3
+ * A terse, line-based text format for straight (non-branching) dialogue - the format a
4
+ * text-only RPG (`core` plus `rpg`, no renderer at all) can use for its own `EventCommand`
5
+ * scripts without depending on `two-d` for anything. `two-d/stage` has its own wrapper
6
+ * around the same parsing engine (`core.parseDialogueLines`) targeting `StageCommand`
7
+ * instead - declared separately for the same reason `EventChoice` is declared separately
8
+ * from `two-d/ui`'s `Choice`: a Pixi-based visual novel that never touches `rpg`'s map
9
+ * events should not have to pull the whole module in just to parse dialogue text, and a
10
+ * text-only RPG should not have to pull in Pixi either. The actual `@id`/`-` parsing logic
11
+ * lives once in `core.parseDialogueLines`, not copied between the two - only the final
12
+ * command shape (`speaker` here, `as` in `two-d/stage`) differs.
13
+ *
14
+ * Three kinds of line:
15
+ *
16
+ * - `@id text` names who is speaking and says `text`; `@id` alone (no text) just registers
17
+ * the speaker, without saying anything yet.
18
+ * - `- text` continues the two-speaker exchange the first two `@id` lines opened,
19
+ * alternating speaker on every line: the first `-` after the two openers goes to
20
+ * whichever of them did not speak last, and so on.
21
+ * - any other non-blank line narrates, with no speaker.
22
+ *
23
+ * ```
24
+ * @alice Hello.
25
+ * @bob Hi!
26
+ * - How are you?
27
+ * - Fine, and you?
28
+ * ```
29
+ *
30
+ * The `-` shorthand is deliberately capped at two speakers: it exists for the two-character
31
+ * back-and-forth, not as a guess at which of three or more people talks next. A third
32
+ * distinct `@id` anywhere in the source is a parse error rather than a silent guess; a scene
33
+ * with more than two speakers writes `@id` on every line instead, same as it does today.
34
+ *
35
+ * Lines reach `EventCommand.say` as plain, untranslated text - a game's own translation step
36
+ * decides how that text reaches a player, the same seam MWL's own `_("...")`-marked strings
37
+ * use (the source text doubles as the catalog key). `extractDialogueCatalog` builds that
38
+ * catalog the same way MWL's `extractCatalog` does, for a game that wants a translator-ready
39
+ * file to start from.
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * import { parseDialogueText, EventRunner, GameState } from '@datamoc/mw_games/rpg';
44
+ *
45
+ * declare const game: GameState;
46
+ *
47
+ * const runner = new EventRunner({
48
+ * game,
49
+ * present: async (request) => {
50
+ * console.log(request.speaker ? `${request.speaker}: ${request.text}` : request.text);
51
+ * },
52
+ * });
53
+ * const commands = parseDialogueText(`
54
+ * @alice Hello.
55
+ * @bob Hi!
56
+ * - How are you?
57
+ * - Fine, and you?
58
+ * `);
59
+ * await runner.run(commands);
60
+ * ```
61
+ */
62
+ export function parseDialogueText(source) {
63
+ return parseDialogueLines(source).map((line) => line.speaker === undefined ? { say: line.text } : { say: line.text, speaker: line.speaker });
64
+ }
65
+ /**
66
+ * Collects every `say`/`ask` line's text into an identity catalog - each key mapping to
67
+ * itself, the same shape MWL's own `extractCatalog` builds from `_("...")`-marked strings -
68
+ * so a translator has real entries to work from instead of a wall of untranslated dialogue.
69
+ *
70
+ * @example
71
+ * ```ts
72
+ * import { parseDialogueText, extractDialogueCatalog } from '@datamoc/mw_games/rpg';
73
+ *
74
+ * const commands = parseDialogueText('@alice Hello.\n');
75
+ * console.log(extractDialogueCatalog(commands).messages); // { 'Hello.': 'Hello.' }
76
+ * ```
77
+ */
78
+ export function extractDialogueCatalog(commands, options = {}) {
79
+ const messages = {};
80
+ for (const command of commands) {
81
+ if ('say' in command)
82
+ messages[command.say] = command.say;
83
+ else if ('ask' in command)
84
+ messages[command.ask] = command.ask;
85
+ }
86
+ return { locale: options.locale ?? 'en', direction: options.direction ?? 'ltr', messages };
87
+ }
88
+ //# sourceMappingURL=dialogue-text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialogue-text.js","sourceRoot":"","sources":["../../src/rpg/dialogue-text.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAI7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC/C,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAC9C,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAC3F,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,sBAAsB,CACrC,QAAiC,EACjC,OAAO,GAA+C,EAAE;IAExD,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAChC,IAAI,KAAK,IAAI,OAAO;YAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;aACrD,IAAI,KAAK,IAAI,OAAO;YAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAChE,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,KAAK,EAAE,QAAQ,EAAE,CAAC;AAC5F,CAAC"}
@@ -6,7 +6,7 @@ export { GameState } from './GameState.ts';
6
6
  export { activePage, conditionHolds } from './Event.ts';
7
7
  export type { EventTrigger, EventCondition, EventPage, MapEvent } from './Event.ts';
8
8
  export { EventRunner } from './EventRunner.ts';
9
- export type { EventCommand, EventRunnerState, EventRunnerOptions, MoveStep, DialoguePresenter, DialogueRequest, EventChoice, } from './EventRunner.ts';
9
+ export type { EventCommand, EventStoryScript, EventRunnerState, EventRunnerOptions, MoveStep, DialoguePresenter, DialogueRequest, EventChoice, } from './EventRunner.ts';
10
10
  export { GridMover } from './GridMover.ts';
11
11
  export type { GridMoverOptions, Direction4 } from './GridMover.ts';
12
12
  export { MoveRouteRunner } from './MoveRoute.ts';
@@ -19,4 +19,7 @@ export { QuestLog, questsFromRows } from './Quest.ts';
19
19
  export type { QuestStage, QuestDefinition, QuestStatus, QuestMarker, QuestStageRow } from './Quest.ts';
20
20
  export { decodeMarshal, encodeMarshal, RubySymbol, hashDefaultOf, withHashDefault } from './Marshal.ts';
21
21
  export type { RubyObject, RubyUserDefined } from './Marshal.ts';
22
+ export { parseDialogueText, extractDialogueCatalog } from './dialogue-text.ts';
23
+ export { importTwee } from './twee-events.ts';
24
+ export type { EventTwineStory } from './twee-events.ts';
22
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rpg/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,EAAE,KAAK,IAAI,aAAa,EAAE,MAAM,cAAc,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACxD,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACpF,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EACX,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,QAAQ,EACR,iBAAiB,EACjB,eAAe,EACf,WAAW,GACX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACxG,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACtF,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACtD,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACvG,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACxG,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rpg/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,EAAE,KAAK,IAAI,aAAa,EAAE,MAAM,cAAc,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACxD,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACpF,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EACX,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,QAAQ,EACR,iBAAiB,EACjB,eAAe,EACf,WAAW,GACX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACxG,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACtF,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACtD,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACvG,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACxG,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/rpg/index.js CHANGED
@@ -9,4 +9,6 @@ export { FreeMover } from './FreeMover.js';
9
9
  export { aabbOverlap, circleOverlap, circleAabbOverlap, resolveAabbAgainstTiles } from './Collision.js';
10
10
  export { QuestLog, questsFromRows } from './Quest.js';
11
11
  export { decodeMarshal, encodeMarshal, RubySymbol, hashDefaultOf, withHashDefault } from './Marshal.js';
12
+ export { parseDialogueText, extractDialogueCatalog } from './dialogue-text.js';
13
+ export { importTwee } from './twee-events.js';
12
14
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rpg/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,KAAK,IAAI,aAAa,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAU/C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAExG,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rpg/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,KAAK,IAAI,aAAa,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAW/C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAExG,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAExG,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,48 @@
1
+ import type { EventStoryScript } from './EventRunner.ts';
2
+ /**
3
+ * A story imported from Twine's Twee notation, ready for `EventRunner.runStory`.
4
+ *
5
+ * The `two-d/stage` counterpart, `importTwee`, targets `StageCommand`/`StoryScript` instead -
6
+ * declared independently here for the same reason `EventChoice` already duplicates
7
+ * `two-d/ui`'s `Choice`: a text-only RPG (`core` plus `rpg`, no renderer at all) should not
8
+ * have to depend on `two-d` just to import a branching Twee story, and a Pixi-based visual
9
+ * novel that never touches map events should not have to depend on `rpg` either.
10
+ */
11
+ export interface EventTwineStory {
12
+ story: EventStoryScript;
13
+ /** `StoryData`'s start passage when the file names one, else the first passage */
14
+ start: string;
15
+ /** the `StoryTitle` passage, when the file has one */
16
+ title?: string;
17
+ }
18
+ /**
19
+ * Reads a `.twee` file into an `EventStoryScript`.
20
+ *
21
+ * The actual parsing (passages, `[[links]]`, `StoryData`/`StoryTitle`) lives once in
22
+ * `core.parseTwee` - this is a thin wrapper naming the `rpg`-specific return type, the same
23
+ * way `two-d/stage.importTwee` wraps the same engine for `StageCommand`.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * import { importTwee, EventRunner, GameState, type DialoguePresenter } from '@datamoc/mw_games/rpg';
28
+ *
29
+ * declare const present: DialoguePresenter;
30
+ *
31
+ * const story = importTwee(`:: Start
32
+ * You stand at a crossroads.
33
+ *
34
+ * [[Take the left path->Left]]
35
+ * [[Take the right path->Right]]
36
+ *
37
+ * :: Left
38
+ * The path ends at a wall.
39
+ *
40
+ * :: Right
41
+ * An open road.
42
+ * `);
43
+ * const runner = new EventRunner({ present, game: new GameState() });
44
+ * await runner.runStory(story.story, story.start);
45
+ * ```
46
+ */
47
+ export declare function importTwee(source: string): EventTwineStory;
48
+ //# sourceMappingURL=twee-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"twee-events.d.ts","sourceRoot":"","sources":["../../src/rpg/twee-events.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,gBAAgB,CAAC;IACxB,kFAAkF;IAClF,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CAG1D"}
@@ -0,0 +1,35 @@
1
+ import { parseTwee } from '../core/Twee.js';
2
+ /**
3
+ * Reads a `.twee` file into an `EventStoryScript`.
4
+ *
5
+ * The actual parsing (passages, `[[links]]`, `StoryData`/`StoryTitle`) lives once in
6
+ * `core.parseTwee` - this is a thin wrapper naming the `rpg`-specific return type, the same
7
+ * way `two-d/stage.importTwee` wraps the same engine for `StageCommand`.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * import { importTwee, EventRunner, GameState, type DialoguePresenter } from '@datamoc/mw_games/rpg';
12
+ *
13
+ * declare const present: DialoguePresenter;
14
+ *
15
+ * const story = importTwee(`:: Start
16
+ * You stand at a crossroads.
17
+ *
18
+ * [[Take the left path->Left]]
19
+ * [[Take the right path->Right]]
20
+ *
21
+ * :: Left
22
+ * The path ends at a wall.
23
+ *
24
+ * :: Right
25
+ * An open road.
26
+ * `);
27
+ * const runner = new EventRunner({ present, game: new GameState() });
28
+ * await runner.runStory(story.story, story.start);
29
+ * ```
30
+ */
31
+ export function importTwee(source) {
32
+ const { story, start, title } = parseTwee(source);
33
+ return title === undefined ? { story, start } : { story, start, title };
34
+ }
35
+ //# sourceMappingURL=twee-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"twee-events.js","sourceRoot":"","sources":["../../src/rpg/twee-events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAoB5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,UAAU,CAAC,MAAc;IACxC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAClD,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AACzE,CAAC"}
@@ -0,0 +1,81 @@
1
+ import type { Catalog, Direction } from '../../i18n/index.ts';
2
+ import type { StageCommand, StoryScript } from './script.ts';
3
+ /**
4
+ * A terse, line-based text format for straight (non-branching) dialogue - the
5
+ * counterpart to `twee.ts`'s passage graphs, for the common case of a scene
6
+ * that is just a sequence of lines. `rpg` has its own wrapper around the same
7
+ * parsing engine (`core.parseDialogueLines`) for a text-only RPG's map events
8
+ * (`rpg.parseDialogueText`, targeting `EventCommand`) - declared separately
9
+ * here for the same reason `EventChoice` is declared separately from this
10
+ * module's own `Choice`: a text-only RPG built on `core` and `rpg` alone
11
+ * should not have to depend on `two-d` (and its Pixi peer dependency) just to
12
+ * parse dialogue text, and a Pixi-based visual novel that never touches map
13
+ * events should not have to pull in `rpg` either. The actual `@id`/`-`
14
+ * parsing logic lives once in `core.parseDialogueLines`, not copied between
15
+ * the two - only the final command shape (`as` here, `speaker` in `rpg`)
16
+ * differs. Three kinds of line:
17
+ *
18
+ * - `@id text` names who is speaking and says `text`; `@id` alone (no text)
19
+ * just registers the speaker, without saying anything yet.
20
+ * - `- text` continues the two-speaker exchange the first two `@id` lines
21
+ * opened, alternating speaker on every line: the first `-` after the two
22
+ * openers goes to whichever of them did not speak last, and so on.
23
+ * - any other non-blank line narrates, with no speaker.
24
+ *
25
+ * ```
26
+ * @alice Hello.
27
+ * @bob Hi!
28
+ * - How are you?
29
+ * - Fine, and you?
30
+ * ```
31
+ *
32
+ * The `-` shorthand is deliberately capped at two speakers: it exists for the
33
+ * two-character back-and-forth, not as a guess at which of three or more
34
+ * people talks next. A third distinct `@id` anywhere in the source is a
35
+ * parse error rather than a silent guess; a scene with more than two
36
+ * speakers writes `@id` on every line instead, same as it does today.
37
+ *
38
+ * Like `twee.ts`, lines reach `StageCommand.say` as plain, untranslated
39
+ * text - a game's own translation step decides how that text reaches a
40
+ * player, the same seam MWL's own `_("...")`-marked strings use (the source
41
+ * text doubles as the catalog key). `extractDialogueCatalog` builds that
42
+ * catalog the same way MWL's `extractCatalog` does, for a game that wants a
43
+ * translator-ready file to start from.
44
+ *
45
+ * @example
46
+ * ```ts
47
+ * import { parseDialogueText, StageScript } from '@datamoc/mw_games/two-d';
48
+ *
49
+ * declare const script: StageScript;
50
+ *
51
+ * const commands = parseDialogueText(`
52
+ * @alice Hello.
53
+ * @bob Hi!
54
+ * - How are you?
55
+ * - Fine, and you?
56
+ * `);
57
+ * await script.run(commands);
58
+ * ```
59
+ */
60
+ export declare function parseDialogueText(source: string): StageCommand[];
61
+ /**
62
+ * Collects every `say`/`ask` line's text into an identity catalog - each key
63
+ * mapping to itself, the same shape MWL's own `extractCatalog` builds from
64
+ * `_("...")`-marked strings - so a translator has real entries to work from
65
+ * instead of a wall of untranslated dialogue. Accepts either a flat command
66
+ * list (`parseDialogueText`'s own output) or a `StoryScript` graph
67
+ * (`importTwee`'s), so the same extraction step covers both dialogue paths.
68
+ *
69
+ * @example
70
+ * ```ts
71
+ * import { parseDialogueText, extractDialogueCatalog } from '@datamoc/mw_games/two-d';
72
+ *
73
+ * const commands = parseDialogueText('@alice Hello.\n');
74
+ * console.log(extractDialogueCatalog(commands).messages); // { 'Hello.': 'Hello.' }
75
+ * ```
76
+ */
77
+ export declare function extractDialogueCatalog(commands: readonly StageCommand[] | StoryScript, options?: {
78
+ locale?: string;
79
+ direction?: Direction;
80
+ }): Catalog;
81
+ //# sourceMappingURL=dialogue-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialogue-text.d.ts","sourceRoot":"","sources":["../../../src/two-d/stage/dialogue-text.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,EAAE,CAIhE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CACrC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG,WAAW,EAC/C,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,CAAA;CAAO,GACtD,OAAO,CAYT"}