@miadi/ncp-story-studio 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.
Files changed (126) hide show
  1. package/LICENSE +21 -0
  2. package/PHASES.md +160 -0
  3. package/README.md +140 -0
  4. package/assets/PROVENANCE.json +5 -0
  5. package/assets/examples/PROVENANCE.json +26 -0
  6. package/assets/examples/anora.json +228 -0
  7. package/assets/examples/example-story.json +112 -0
  8. package/assets/examples/the-shawshank-redemption.json +2068 -0
  9. package/assets/examples/weaver_of_words__the_catalyst_of_change_251101.json +1132 -0
  10. package/assets/ncp-schema.json +794 -0
  11. package/assets/terminology.json +2919 -0
  12. package/dist/agents/adapter.d.ts +60 -0
  13. package/dist/agents/adapter.d.ts.map +1 -0
  14. package/dist/agents/adapter.js +69 -0
  15. package/dist/agents/adapter.js.map +1 -0
  16. package/dist/agents/context.d.ts +19 -0
  17. package/dist/agents/context.d.ts.map +1 -0
  18. package/dist/agents/context.js +49 -0
  19. package/dist/agents/context.js.map +1 -0
  20. package/dist/agents/index.d.ts +5 -0
  21. package/dist/agents/index.d.ts.map +1 -0
  22. package/dist/agents/index.js +7 -0
  23. package/dist/agents/index.js.map +1 -0
  24. package/dist/agents/links.d.ts +41 -0
  25. package/dist/agents/links.d.ts.map +1 -0
  26. package/dist/agents/links.js +76 -0
  27. package/dist/agents/links.js.map +1 -0
  28. package/dist/agents/personas.d.ts +16 -0
  29. package/dist/agents/personas.d.ts.map +1 -0
  30. package/dist/agents/personas.js +34 -0
  31. package/dist/agents/personas.js.map +1 -0
  32. package/dist/fixtures/index.d.ts +27 -0
  33. package/dist/fixtures/index.d.ts.map +1 -0
  34. package/dist/fixtures/index.js +69 -0
  35. package/dist/fixtures/index.js.map +1 -0
  36. package/dist/graph/index.d.ts +60 -0
  37. package/dist/graph/index.d.ts.map +1 -0
  38. package/dist/graph/index.js +97 -0
  39. package/dist/graph/index.js.map +1 -0
  40. package/dist/graph/react/index.d.ts +2 -0
  41. package/dist/graph/react/index.d.ts.map +1 -0
  42. package/dist/graph/react/index.js +5 -0
  43. package/dist/graph/react/index.js.map +1 -0
  44. package/dist/graph/react/story-graph.d.ts +17 -0
  45. package/dist/graph/react/story-graph.d.ts.map +1 -0
  46. package/dist/graph/react/story-graph.js +26 -0
  47. package/dist/graph/react/story-graph.js.map +1 -0
  48. package/dist/graph/tones.d.ts +36 -0
  49. package/dist/graph/tones.d.ts.map +1 -0
  50. package/dist/graph/tones.js +38 -0
  51. package/dist/graph/tones.js.map +1 -0
  52. package/dist/index.d.ts +33 -0
  53. package/dist/index.d.ts.map +1 -0
  54. package/dist/index.js +24 -0
  55. package/dist/index.js.map +1 -0
  56. package/dist/schema/constants.d.ts +3 -0
  57. package/dist/schema/constants.d.ts.map +1 -0
  58. package/dist/schema/constants.js +3 -0
  59. package/dist/schema/constants.js.map +1 -0
  60. package/dist/schema/extensions.d.ts +14 -0
  61. package/dist/schema/extensions.d.ts.map +1 -0
  62. package/dist/schema/extensions.js +61 -0
  63. package/dist/schema/extensions.js.map +1 -0
  64. package/dist/schema/generated-terms.d.ts +7 -0
  65. package/dist/schema/generated-terms.d.ts.map +1 -0
  66. package/dist/schema/generated-terms.js +518 -0
  67. package/dist/schema/generated-terms.js.map +1 -0
  68. package/dist/schema/generated.d.ts +64 -0
  69. package/dist/schema/generated.d.ts.map +1 -0
  70. package/dist/schema/generated.js +497 -0
  71. package/dist/schema/generated.js.map +1 -0
  72. package/dist/schema/index.d.ts +48 -0
  73. package/dist/schema/index.d.ts.map +1 -0
  74. package/dist/schema/index.js +92 -0
  75. package/dist/schema/index.js.map +1 -0
  76. package/dist/schema/normalize.d.ts +20 -0
  77. package/dist/schema/normalize.d.ts.map +1 -0
  78. package/dist/schema/normalize.js +88 -0
  79. package/dist/schema/normalize.js.map +1 -0
  80. package/dist/schema/read.d.ts +31 -0
  81. package/dist/schema/read.d.ts.map +1 -0
  82. package/dist/schema/read.js +640 -0
  83. package/dist/schema/read.js.map +1 -0
  84. package/dist/schema/terms.d.ts +11 -0
  85. package/dist/schema/terms.d.ts.map +1 -0
  86. package/dist/schema/terms.js +80 -0
  87. package/dist/schema/terms.js.map +1 -0
  88. package/dist/schema/types.d.ts +140 -0
  89. package/dist/schema/types.d.ts.map +1 -0
  90. package/dist/schema/types.js +2 -0
  91. package/dist/schema/types.js.map +1 -0
  92. package/dist/schema/validate.d.ts +54 -0
  93. package/dist/schema/validate.d.ts.map +1 -0
  94. package/dist/schema/validate.js +490 -0
  95. package/dist/schema/validate.js.map +1 -0
  96. package/dist/store/index.d.ts +76 -0
  97. package/dist/store/index.d.ts.map +1 -0
  98. package/dist/store/index.js +96 -0
  99. package/dist/store/index.js.map +1 -0
  100. package/dist/store/json.d.ts +35 -0
  101. package/dist/store/json.d.ts.map +1 -0
  102. package/dist/store/json.js +192 -0
  103. package/dist/store/json.js.map +1 -0
  104. package/dist/store/mutations.d.ts +45 -0
  105. package/dist/store/mutations.d.ts.map +1 -0
  106. package/dist/store/mutations.js +181 -0
  107. package/dist/store/mutations.js.map +1 -0
  108. package/dist/store/neon.d.ts +42 -0
  109. package/dist/store/neon.d.ts.map +1 -0
  110. package/dist/store/neon.js +167 -0
  111. package/dist/store/neon.js.map +1 -0
  112. package/dist/terminology/generated.d.ts +3 -0
  113. package/dist/terminology/generated.d.ts.map +1 -0
  114. package/dist/terminology/generated.js +2923 -0
  115. package/dist/terminology/generated.js.map +1 -0
  116. package/dist/terminology/index.d.ts +20 -0
  117. package/dist/terminology/index.d.ts.map +1 -0
  118. package/dist/terminology/index.js +71 -0
  119. package/dist/terminology/index.js.map +1 -0
  120. package/dist/terminology/types.d.ts +25 -0
  121. package/dist/terminology/types.d.ts.map +1 -0
  122. package/dist/terminology/types.js +2 -0
  123. package/dist/terminology/types.js.map +1 -0
  124. package/package.json +117 -0
  125. package/rispecs/README.rise.md +5 -0
  126. package/rispecs/RISPEC.md +9 -0
@@ -0,0 +1,60 @@
1
+ import { type LatticeContextOptions } from './context.js';
2
+ import { type LinkCheck, type MessageSegment } from './links.js';
3
+ import { type PersonaId } from './personas.js';
4
+ import type { Story } from '../schema/types.js';
5
+ export interface AgentTurn {
6
+ role: 'user' | 'agent';
7
+ content: string;
8
+ }
9
+ /** What a model implementation receives. Roles are already normalized. */
10
+ export interface AgentModelInput {
11
+ system: string;
12
+ history: {
13
+ role: 'user' | 'model';
14
+ text: string;
15
+ }[];
16
+ prompt: string;
17
+ }
18
+ export interface AgentModel {
19
+ /** Identifier for the record: which model answered. */
20
+ readonly id: string;
21
+ generate(input: AgentModelInput): Promise<string>;
22
+ }
23
+ export interface AgentRequest {
24
+ story: Story;
25
+ message: string;
26
+ history?: AgentTurn[];
27
+ /** Which personas may answer. Default: all three, in order. */
28
+ personas?: PersonaId[];
29
+ context?: LatticeContextOptions;
30
+ /** Extra instruction the host appends, e.g. a governance constraint. */
31
+ additionalInstruction?: string;
32
+ }
33
+ export interface AgentResponse {
34
+ /** Raw model text, links intact. */
35
+ text: string;
36
+ /** The same text split for rendering. */
37
+ segments: MessageSegment[];
38
+ /** Every link with whether it resolves against the story. */
39
+ links: LinkCheck[];
40
+ /** Which model produced it, and how the story was carried. */
41
+ provenance: {
42
+ model_id: string;
43
+ context_mode: 'full' | 'digest';
44
+ context_characters: number;
45
+ personas: PersonaId[];
46
+ at: string;
47
+ };
48
+ }
49
+ /** The system instruction: who is speaking, and the one output rule. */
50
+ export declare function buildSystemInstruction(personas?: PersonaId[], extra?: string): string;
51
+ /** Run one turn: build the prompt, call the model, parse what comes back. */
52
+ export declare function runAgentTurn(model: AgentModel, request: AgentRequest): Promise<AgentResponse>;
53
+ /** A model that returns a fixed reply. For tests and for offline demos. */
54
+ export declare class StaticAgentModel implements AgentModel {
55
+ private readonly reply;
56
+ readonly id: string;
57
+ constructor(reply: string, id?: string);
58
+ generate(): Promise<string>;
59
+ }
60
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/agents/adapter.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuB,KAAK,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAC9E,OAAO,EAA6C,KAAK,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3G,OAAO,EAAmC,KAAK,SAAS,EAAE,MAAM,eAAe,CAAA;AAC/E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAE/C,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,0EAA0E;AAC1E,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACnD,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,UAAU;IACzB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CAClD;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,KAAK,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,SAAS,EAAE,CAAA;IACrB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAA;IACtB,OAAO,CAAC,EAAE,qBAAqB,CAAA;IAC/B,wEAAwE;IACxE,qBAAqB,CAAC,EAAE,MAAM,CAAA;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,yCAAyC;IACzC,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B,6DAA6D;IAC7D,KAAK,EAAE,SAAS,EAAE,CAAA;IAClB,8DAA8D;IAC9D,UAAU,EAAE;QACV,QAAQ,EAAE,MAAM,CAAA;QAChB,YAAY,EAAE,MAAM,GAAG,QAAQ,CAAA;QAC/B,kBAAkB,EAAE,MAAM,CAAA;QAC1B,QAAQ,EAAE,SAAS,EAAE,CAAA;QACrB,EAAE,EAAE,MAAM,CAAA;KACX,CAAA;CACF;AAED,wEAAwE;AACxE,wBAAgB,sBAAsB,CAAC,QAAQ,GAAE,SAAS,EAA0B,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAyB5G;AAED,6EAA6E;AAC7E,wBAAsB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAwBnG;AAED,2EAA2E;AAC3E,qBAAa,gBAAiB,YAAW,UAAU;IAG/C,OAAO,CAAC,QAAQ,CAAC,KAAK;IAFxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;gBAEA,KAAK,EAAE,MAAM,EAC9B,EAAE,SAAW;IAKT,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;CAGlC"}
@@ -0,0 +1,69 @@
1
+ // Provider-neutral agent layer. The studio knows about personas, the lattice,
2
+ // and the link protocol; it knows nothing about a vendor SDK. A host implements
3
+ // `AgentModel` around whatever it already has.
4
+ import { buildLatticeContext } from './context.js';
5
+ import { checkLinks, formatLink, parseAgentMessage } from './links.js';
6
+ import { DEFAULT_PERSONA_ORDER, PERSONAS } from './personas.js';
7
+ /** The system instruction: who is speaking, and the one output rule. */
8
+ export function buildSystemInstruction(personas = DEFAULT_PERSONA_ORDER, extra) {
9
+ const roster = personas
10
+ .map((id) => {
11
+ const p = PERSONAS[id];
12
+ return `- ${p.glyph} ${p.display} — ${p.role}. Focus: ${p.focus}. Voice: ${p.voice}`;
13
+ })
14
+ .join('\n');
15
+ return [
16
+ 'You are reading a story held as a Narrative Context Protocol (NCP) lattice.',
17
+ 'The lattice separates subtext (perspectives, players, dynamics, storypoints, storybeats) from storytelling (overviews, moments).',
18
+ '',
19
+ 'You answer as these reading positions, each in its own short passage, in this order:',
20
+ roster,
21
+ '',
22
+ 'Rules:',
23
+ '- Answer directly. No preamble about what you are about to do.',
24
+ '- Never print a raw element id in prose. Reference an element with a link instead.',
25
+ `- Link syntax, exactly: ${formatLink('Beat', 'beat-id', 'what it is')}. Kinds: Beat, Player, Perspective, Point.`,
26
+ '- Only reference ids that exist in the lattice you were given.',
27
+ '- When the lattice does not say something, say that it does not, rather than inventing it.',
28
+ extra ?? '',
29
+ ]
30
+ .filter((line) => line.length > 0)
31
+ .join('\n');
32
+ }
33
+ /** Run one turn: build the prompt, call the model, parse what comes back. */
34
+ export async function runAgentTurn(model, request) {
35
+ const personas = request.personas ?? DEFAULT_PERSONA_ORDER;
36
+ const context = buildLatticeContext(request.story, request.context);
37
+ const system = buildSystemInstruction(personas, request.additionalInstruction);
38
+ const history = (request.history ?? []).map((turn) => ({
39
+ role: turn.role === 'agent' ? 'model' : 'user',
40
+ text: turn.content,
41
+ }));
42
+ const prompt = `${context.text}\n\n${request.message}`;
43
+ const text = await model.generate({ system, history, prompt });
44
+ return {
45
+ text,
46
+ segments: parseAgentMessage(text),
47
+ links: checkLinks(text, request.story),
48
+ provenance: {
49
+ model_id: model.id,
50
+ context_mode: context.mode,
51
+ context_characters: context.characters,
52
+ personas,
53
+ at: new Date().toISOString(),
54
+ },
55
+ };
56
+ }
57
+ /** A model that returns a fixed reply. For tests and for offline demos. */
58
+ export class StaticAgentModel {
59
+ reply;
60
+ id;
61
+ constructor(reply, id = 'static') {
62
+ this.reply = reply;
63
+ this.id = id;
64
+ }
65
+ async generate() {
66
+ return this.reply;
67
+ }
68
+ }
69
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/agents/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { Story } from '../schema/types.js';
2
+ export declare const CONTEXT_START = "[NCP LATTICE DATA START]";
3
+ export declare const CONTEXT_END = "[NCP LATTICE DATA END]";
4
+ export interface LatticeContextOptions {
5
+ /** `full` sends the document; `digest` sends an index of it. Default `full`. */
6
+ mode?: 'full' | 'digest';
7
+ /** Switch to a digest automatically above this many characters. Default 60000. */
8
+ digestAbove?: number;
9
+ }
10
+ export interface LatticeContext {
11
+ text: string;
12
+ mode: 'full' | 'digest';
13
+ characters: number;
14
+ }
15
+ /** A compact index: ids, titles, and counts, with no prose bodies. */
16
+ export declare function storyDigest(story: Story): string;
17
+ /** Wrap the story for the model in the markers the studio has always used. */
18
+ export declare function buildLatticeContext(story: Story, options?: LatticeContextOptions): LatticeContext;
19
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/agents/context.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAE/C,eAAO,MAAM,aAAa,6BAA6B,CAAA;AACvD,eAAO,MAAM,WAAW,2BAA2B,CAAA;AAEnD,MAAM,WAAW,qBAAqB;IACpC,gFAAgF;IAChF,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAA;IACxB,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAA;IACvB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,sEAAsE;AACtE,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAuChD;AAED,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,cAAc,CAQjG"}
@@ -0,0 +1,49 @@
1
+ // Lattice context. The agent is given the story it is talking about, either
2
+ // whole or as a digest when the document is large.
3
+ import { orderedBeats, storyCompleteness } from '../schema/index.js';
4
+ export const CONTEXT_START = '[NCP LATTICE DATA START]';
5
+ export const CONTEXT_END = '[NCP LATTICE DATA END]';
6
+ /** A compact index: ids, titles, and counts, with no prose bodies. */
7
+ export function storyDigest(story) {
8
+ const lines = [
9
+ `story: ${story.id} — ${story.title}`,
10
+ story.genre ? `genre: ${story.genre}` : undefined,
11
+ story.logline ? `logline: ${story.logline}` : undefined,
12
+ ].filter((line) => typeof line === 'string');
13
+ const completeness = storyCompleteness(story);
14
+ lines.push(`completeness: ${(completeness.overall * 100).toFixed(0)}%`);
15
+ for (const narrative of story.narratives) {
16
+ lines.push('', `narrative ${narrative.id} — ${narrative.title}`);
17
+ lines.push(` perspectives: ${narrative.subtext.perspectives
18
+ .map((p) => `${p.id}${p.author_structural_pov ? `(${p.author_structural_pov})` : ''}`)
19
+ .join(', ')}`);
20
+ lines.push(` players: ${narrative.subtext.players.map((p) => `${p.id}=${p.name} [${p.role}]`).join(', ')}`);
21
+ lines.push(` dynamics: ${narrative.subtext.dynamics.map((d) => `${d.dynamic}=${d.vector}`).join(', ')}`);
22
+ lines.push(` storypoints: ${narrative.subtext.storypoints
23
+ .map((s) => `${s.id}:${s.custom_appreciation ?? s.appreciation}`)
24
+ .join(', ')}`);
25
+ lines.push(' storybeats:');
26
+ for (const beat of orderedBeats(narrative)) {
27
+ const tones = beat.tones
28
+ ? ` tones=${beat.tones.abstraction}/${beat.tones.spatial}/${beat.tones.temporal}`
29
+ : ' tones=none';
30
+ const summary = beat.summary ? ` — ${beat.summary.slice(0, 120)}` : '';
31
+ lines.push(` ${beat.sequence}. ${beat.id} [${beat.appreciation}]${tones}${summary}`);
32
+ }
33
+ if (narrative.storytelling.moments.length > 0) {
34
+ lines.push(` moments: ${narrative.storytelling.moments.map((m) => `${m.id}${m.setting ? `@${m.setting}` : ''}`).join(', ')}`);
35
+ }
36
+ }
37
+ return lines.join('\n');
38
+ }
39
+ /** Wrap the story for the model in the markers the studio has always used. */
40
+ export function buildLatticeContext(story, options) {
41
+ const requested = options?.mode ?? 'full';
42
+ const digestAbove = options?.digestAbove ?? 60000;
43
+ const full = JSON.stringify(story, null, 2);
44
+ const mode = requested === 'digest' || full.length > digestAbove ? 'digest' : 'full';
45
+ const body = mode === 'full' ? full : storyDigest(story);
46
+ const text = `${CONTEXT_START}\n${body}\n${CONTEXT_END}`;
47
+ return { text, mode, characters: text.length };
48
+ }
49
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/agents/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export * from './links.js';
2
+ export * from './personas.js';
3
+ export * from './context.js';
4
+ export * from './adapter.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agents/index.ts"],"names":[],"mappings":"AAEA,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA"}
@@ -0,0 +1,7 @@
1
+ // `@miadi/ncp-story-studio/agents` — personas, the lattice context, the link
2
+ // protocol, and a provider-neutral turn runner.
3
+ export * from './links.js';
4
+ export * from './personas.js';
5
+ export * from './context.js';
6
+ export * from './adapter.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/agents/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,gDAAgD;AAChD,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA"}
@@ -0,0 +1,41 @@
1
+ import type { Story } from '../schema/types.js';
2
+ export declare const LINK_KINDS: readonly ["Beat", "Player", "Perspective", "Point"];
3
+ export type LinkKind = (typeof LINK_KINDS)[number];
4
+ /** The view a link of each kind opens. */
5
+ export declare const LINK_VIEW: Record<LinkKind, StudioView>;
6
+ export type StudioView = 'overview' | 'storypoints' | 'perspectives' | 'players' | 'dynamics' | 'storybeats' | 'graph';
7
+ /**
8
+ * A link never spans a line: excluding newlines keeps an unclosed opener from
9
+ * swallowing the next valid link, and keeps the scan linear.
10
+ *
11
+ * Not global on purpose — `LINK_PATTERN.test(x)` on a global regex alternates
12
+ * true/false because it carries `lastIndex`. `parseAgentMessage` builds its own
13
+ * global copy.
14
+ */
15
+ export declare const LINK_PATTERN: RegExp;
16
+ export interface TextSegment {
17
+ type: 'text';
18
+ text: string;
19
+ }
20
+ export interface LinkSegment {
21
+ type: 'link';
22
+ kind: LinkKind;
23
+ id: string;
24
+ label: string;
25
+ view: StudioView;
26
+ raw: string;
27
+ }
28
+ export type MessageSegment = TextSegment | LinkSegment;
29
+ /** Split an agent message into plain text and element links, in order. */
30
+ export declare function parseAgentMessage(message: string): MessageSegment[];
31
+ /** Write a link in the syntax the parser accepts. */
32
+ export declare function formatLink(kind: LinkKind, id: string, label: string): string;
33
+ /** Message text with every link replaced by its label. */
34
+ export declare function stripLinks(message: string): string;
35
+ export interface LinkCheck {
36
+ link: LinkSegment;
37
+ resolved: boolean;
38
+ }
39
+ /** Check every link in a message against a story, so a dangling id is visible. */
40
+ export declare function checkLinks(message: string, story: Story): LinkCheck[];
41
+ //# sourceMappingURL=links.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../../src/agents/links.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAE/C,eAAO,MAAM,UAAU,qDAAsD,CAAA;AAC7E,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAA;AAElD,0CAA0C;AAC1C,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,UAAU,CAKlD,CAAA;AAED,MAAM,MAAM,UAAU,GAClB,UAAU,GACV,aAAa,GACb,cAAc,GACd,SAAS,GACT,UAAU,GACV,YAAY,GACZ,OAAO,CAAA;AAEX;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,QAAoE,CAAA;AAE7F,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,QAAQ,CAAA;IACd,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,UAAU,CAAA;IAChB,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,WAAW,CAAA;AAEtD,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,EAAE,CAuBnE;AAED,qDAAqD;AACrD,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE5E;AAED,0DAA0D;AAC1D,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIlD;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,WAAW,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED,kFAAkF;AAClF,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,SAAS,EAAE,CAgBrE"}
@@ -0,0 +1,76 @@
1
+ export const LINK_KINDS = ['Beat', 'Player', 'Perspective', 'Point'];
2
+ /** The view a link of each kind opens. */
3
+ export const LINK_VIEW = {
4
+ Beat: 'storybeats',
5
+ Player: 'players',
6
+ Perspective: 'perspectives',
7
+ Point: 'storypoints',
8
+ };
9
+ /**
10
+ * A link never spans a line: excluding newlines keeps an unclosed opener from
11
+ * swallowing the next valid link, and keeps the scan linear.
12
+ *
13
+ * Not global on purpose — `LINK_PATTERN.test(x)` on a global regex alternates
14
+ * true/false because it carries `lastIndex`. `parseAgentMessage` builds its own
15
+ * global copy.
16
+ */
17
+ export const LINK_PATTERN = /\[\[(Beat|Player|Perspective|Point):([^|\]\n]+)\|([^\]\n]+)\]\]/;
18
+ /** Split an agent message into plain text and element links, in order. */
19
+ export function parseAgentMessage(message) {
20
+ const segments = [];
21
+ let cursor = 0;
22
+ const pattern = new RegExp(LINK_PATTERN.source, 'g');
23
+ let match = pattern.exec(message);
24
+ while (match !== null) {
25
+ if (match.index > cursor) {
26
+ segments.push({ type: 'text', text: message.slice(cursor, match.index) });
27
+ }
28
+ const kind = match[1];
29
+ segments.push({
30
+ type: 'link',
31
+ kind,
32
+ id: (match[2] ?? '').trim(),
33
+ label: (match[3] ?? '').trim(),
34
+ view: LINK_VIEW[kind],
35
+ raw: match[0],
36
+ });
37
+ cursor = match.index + match[0].length;
38
+ match = pattern.exec(message);
39
+ }
40
+ if (cursor < message.length)
41
+ segments.push({ type: 'text', text: message.slice(cursor) });
42
+ return segments;
43
+ }
44
+ /** Write a link in the syntax the parser accepts. */
45
+ export function formatLink(kind, id, label) {
46
+ return `[[${kind}:${id}|${label}]]`;
47
+ }
48
+ /** Message text with every link replaced by its label. */
49
+ export function stripLinks(message) {
50
+ return parseAgentMessage(message)
51
+ .map((segment) => (segment.type === 'text' ? segment.text : segment.label))
52
+ .join('');
53
+ }
54
+ /** Check every link in a message against a story, so a dangling id is visible. */
55
+ export function checkLinks(message, story) {
56
+ const ids = {
57
+ Beat: new Set(),
58
+ Player: new Set(),
59
+ Perspective: new Set(),
60
+ Point: new Set(),
61
+ };
62
+ for (const narrative of story.narratives) {
63
+ for (const beat of narrative.subtext.storybeats)
64
+ ids.Beat.add(beat.id);
65
+ for (const player of narrative.subtext.players)
66
+ ids.Player.add(player.id);
67
+ for (const perspective of narrative.subtext.perspectives)
68
+ ids.Perspective.add(perspective.id);
69
+ for (const storypoint of narrative.subtext.storypoints)
70
+ ids.Point.add(storypoint.id);
71
+ }
72
+ return parseAgentMessage(message)
73
+ .filter((segment) => segment.type === 'link')
74
+ .map((link) => ({ link, resolved: ids[link.kind].has(link.id) }));
75
+ }
76
+ //# sourceMappingURL=links.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"links.js","sourceRoot":"","sources":["../../src/agents/links.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export type PersonaId = 'mia' | 'miette' | 'ava8';
2
+ export interface Persona {
3
+ id: PersonaId;
4
+ glyph: string;
5
+ display: string;
6
+ role: string;
7
+ focus: string;
8
+ /** How this persona speaks, written into the system instruction. */
9
+ voice: string;
10
+ /** Accent color for this persona's messages. */
11
+ color: string;
12
+ }
13
+ export declare const PERSONAS: Record<PersonaId, Persona>;
14
+ export declare const DEFAULT_PERSONA_ORDER: PersonaId[];
15
+ export declare function persona(id: PersonaId): Persona;
16
+ //# sourceMappingURL=personas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"personas.d.ts","sourceRoot":"","sources":["../../src/agents/personas.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEjD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,SAAS,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAA;IACb,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAA;CACd;AAED,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CA4B/C,CAAA;AAED,eAAO,MAAM,qBAAqB,EAAE,SAAS,EAA8B,CAAA;AAE3E,wBAAgB,OAAO,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,CAE9C"}
@@ -0,0 +1,34 @@
1
+ export const PERSONAS = {
2
+ mia: {
3
+ id: 'mia',
4
+ glyph: '🧠',
5
+ display: 'Mia',
6
+ role: 'Recursive DevOps architect and lattice forger',
7
+ focus: 'Structure, schema, definitions, the tension between current and desired story state',
8
+ voice: 'Precise and constructive. Names what is structurally true before proposing anything.',
9
+ color: '#8b5cf6',
10
+ },
11
+ miette: {
12
+ id: 'miette',
13
+ glyph: '🌸',
14
+ display: 'Miette',
15
+ role: 'Emotional illuminator and narrative kin',
16
+ focus: 'Character depth, emotional resonance, what a beat means for the reader',
17
+ voice: 'Warm and plain. Says what a choice does for the people it touches, without inflating it.',
18
+ color: '#f472b6',
19
+ },
20
+ ava8: {
21
+ id: 'ava8',
22
+ glyph: '🎨',
23
+ display: 'Ava8',
24
+ role: 'Musical orchestra agent and threshold translator',
25
+ focus: 'Tone, atmosphere, and the musical shape of a moment: tempo, register, motif, silence',
26
+ voice: 'Sensory and musical. Hears a beat as movement, and says what it sounds like.',
27
+ color: '#06b6d4',
28
+ },
29
+ };
30
+ export const DEFAULT_PERSONA_ORDER = ['mia', 'miette', 'ava8'];
31
+ export function persona(id) {
32
+ return PERSONAS[id];
33
+ }
34
+ //# sourceMappingURL=personas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"personas.js","sourceRoot":"","sources":["../../src/agents/personas.ts"],"names":[],"mappings":"AAgBA,MAAM,CAAC,MAAM,QAAQ,GAA+B;IAClD,GAAG,EAAE;QACH,EAAE,EAAE,KAAK;QACT,KAAK,EAAE,IAAI;QACX,OAAO,EAAE,KAAK;QACd,IAAI,EAAE,+CAA+C;QACrD,KAAK,EAAE,qFAAqF;QAC5F,KAAK,EAAE,sFAAsF;QAC7F,KAAK,EAAE,SAAS;KACjB;IACD,MAAM,EAAE;QACN,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,IAAI;QACX,OAAO,EAAE,QAAQ;QACjB,IAAI,EAAE,yCAAyC;QAC/C,KAAK,EAAE,wEAAwE;QAC/E,KAAK,EAAE,0FAA0F;QACjG,KAAK,EAAE,SAAS;KACjB;IACD,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM;QACV,KAAK,EAAE,IAAI;QACX,OAAO,EAAE,MAAM;QACf,IAAI,EAAE,kDAAkD;QACxD,KAAK,EAAE,sFAAsF;QAC7F,KAAK,EAAE,8EAA8E;QACrF,KAAK,EAAE,SAAS;KACjB;CACF,CAAA;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAgB,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;AAE3E,MAAM,UAAU,OAAO,CAAC,EAAa;IACnC,OAAO,QAAQ,CAAC,EAAE,CAAC,CAAA;AACrB,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { type NcpDialect, type NcpDocument, type NormalizeNote } from '../schema/index.js';
2
+ import { MemoryStoryStore, type StoryProject } from '../store/index.js';
3
+ export interface FixtureEntry {
4
+ id: string;
5
+ title: string;
6
+ file: string;
7
+ /** Where the document came from. */
8
+ source: string;
9
+ /** What the fixture is useful for. */
10
+ note: string;
11
+ }
12
+ export declare const FIXTURES: readonly FixtureEntry[];
13
+ export declare function fixture(id: string): FixtureEntry | undefined;
14
+ export interface LoadedFixture {
15
+ entry: FixtureEntry;
16
+ document: NcpDocument;
17
+ /** Which dialect the file on disk is written in. */
18
+ dialect: NcpDialect;
19
+ /** What reading it had to adapt. */
20
+ notes: NormalizeNote[];
21
+ }
22
+ export declare function loadFixture(id: string): Promise<LoadedFixture>;
23
+ export declare function loadAllFixtures(): Promise<LoadedFixture[]>;
24
+ export declare function fixtureProject(id: string): Promise<StoryProject>;
25
+ /** A read-only store holding every bundled fixture, for a first run with no data. */
26
+ export declare function fixtureStore(): Promise<MemoryStoryStore>;
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fixtures/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAW,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACnG,OAAO,EAAE,gBAAgB,EAAc,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEnF,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAA;IACd,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAA;CACb;AAED,eAAO,MAAM,QAAQ,EAAE,SAAS,YAAY,EA6BlC,CAAA;AAIV,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAE5D;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,YAAY,CAAA;IACnB,QAAQ,EAAE,WAAW,CAAA;IACrB,oDAAoD;IACpD,OAAO,EAAE,UAAU,CAAA;IACnB,oCAAoC;IACpC,KAAK,EAAE,aAAa,EAAE,CAAA;CACvB;AAED,wBAAsB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAOpE;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAEhE;AAED,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAStE;AAED,qFAAqF;AACrF,wBAAsB,YAAY,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAG9D"}
@@ -0,0 +1,69 @@
1
+ // `@miadi/ncp-story-studio/fixtures` — the example documents that ship with the
2
+ // package. Node only: the files are read from `assets/`, so a browser consumer
3
+ // receives them from a route handler rather than importing this module.
4
+ import { readFile } from 'node:fs/promises';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { readNcp } from '../schema/index.js';
7
+ import { MemoryStoryStore, newProject } from '../store/index.js';
8
+ export const FIXTURES = [
9
+ {
10
+ id: 'catalyst-of-change',
11
+ title: 'Weaver of Words: The Catalyst of Change',
12
+ file: 'weaver_of_words__the_catalyst_of_change_251101.json',
13
+ source: 'holisticagnostic-narrative-context-protocol/examples (MIT)',
14
+ note: 'The seed narrative, written in the miadi-design dialect: 5 perspectives, 6 players, 13 storypoints, 90 beats, 23 moments.',
15
+ },
16
+ {
17
+ id: 'example-story',
18
+ title: 'Minimal example story',
19
+ file: 'example-story.json',
20
+ source: 'holisticagnostic-narrative-context-protocol/examples (MIT)',
21
+ note: 'One of each element, in the canonical `{schema_version, story}` layout.',
22
+ },
23
+ {
24
+ id: 'shawshank-redemption',
25
+ title: 'The Shawshank Redemption',
26
+ file: 'the-shawshank-redemption.json',
27
+ source: 'holisticagnostic-narrative-context-protocol/examples (MIT)',
28
+ note: 'A full storyform: 8 players, 47 storypoints, 97 beats, in the subtxt-export dialect. It does not validate clean: the export numbers some signposts and events twice inside one series, which the validator reports.',
29
+ },
30
+ {
31
+ id: 'anora',
32
+ title: 'Anora',
33
+ file: 'anora.json',
34
+ source: 'holisticagnostic-narrative-context-protocol/examples (MIT)',
35
+ note: 'Storypoints without beats, in the subtxt-export dialect: what a partially structured story looks like.',
36
+ },
37
+ ];
38
+ const ASSET_DIR = new URL('../../assets/examples/', import.meta.url);
39
+ export function fixture(id) {
40
+ return FIXTURES.find((entry) => entry.id === id);
41
+ }
42
+ export async function loadFixture(id) {
43
+ const entry = fixture(id);
44
+ if (!entry)
45
+ throw new Error(`no fixture \`${id}\`. Known: ${FIXTURES.map((f) => f.id).join(', ')}`);
46
+ const path = fileURLToPath(new URL(entry.file, ASSET_DIR));
47
+ const raw = await readFile(path, 'utf8');
48
+ const { document, dialect, notes } = readNcp(JSON.parse(raw), { fallbackId: entry.id });
49
+ return { entry, document, dialect, notes };
50
+ }
51
+ export async function loadAllFixtures() {
52
+ return Promise.all(FIXTURES.map((entry) => loadFixture(entry.id)));
53
+ }
54
+ export async function fixtureProject(id) {
55
+ const loaded = await loadFixture(id);
56
+ return {
57
+ ...newProject(loaded.document, {
58
+ projectId: loaded.entry.id,
59
+ meta: { source: loaded.entry.source, tags: ['fixture', `dialect:${loaded.dialect}`] },
60
+ }),
61
+ read_only: true,
62
+ };
63
+ }
64
+ /** A read-only store holding every bundled fixture, for a first run with no data. */
65
+ export async function fixtureStore() {
66
+ const projects = await Promise.all(FIXTURES.map((entry) => fixtureProject(entry.id)));
67
+ return new MemoryStoryStore(projects);
68
+ }
69
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/fixtures/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import type { Narrative } from '../schema/types.js';
2
+ import { type ToneRingColors } from './tones.js';
3
+ export * from './tones.js';
4
+ export interface GraphLayoutOptions {
5
+ /** Horizontal distance between beat centers. */
6
+ beatSpacing?: number;
7
+ /** Vertical center of the beat row. */
8
+ centerY?: number;
9
+ /** Radius of the innermost node circle. */
10
+ nodeRadius?: number;
11
+ /** Distance between tone rings. */
12
+ ringGap?: number;
13
+ /** Left and right padding around the beat row. */
14
+ paddingX?: number;
15
+ /** Total canvas height. */
16
+ height?: number;
17
+ /** How far a connector bows away from the straight line. */
18
+ curvature?: number;
19
+ /** Beats alternate above and below the center line by this offset. */
20
+ stagger?: number;
21
+ }
22
+ export interface GraphNode {
23
+ id: string;
24
+ sequence: number;
25
+ appreciation: string;
26
+ narrativeFunction: string;
27
+ title: string;
28
+ summary?: string;
29
+ x: number;
30
+ y: number;
31
+ radius: number;
32
+ /** Ring radii, innermost first: abstraction, spatial, temporal. */
33
+ ringRadii: [number, number, number];
34
+ ringColors: ToneRingColors;
35
+ hasTones: boolean;
36
+ perspectiveIds: string[];
37
+ }
38
+ export interface GraphLink {
39
+ id: string;
40
+ fromId: string;
41
+ toId: string;
42
+ /** SVG cubic path from one node to the next. */
43
+ path: string;
44
+ }
45
+ export interface GraphLayout {
46
+ nodes: GraphNode[];
47
+ links: GraphLink[];
48
+ width: number;
49
+ height: number;
50
+ centerY: number;
51
+ resolved: Required<GraphLayoutOptions>;
52
+ }
53
+ /** Lay a narrative's beats out as a left-to-right lattice. */
54
+ export declare function layoutNarrative(narrative: Narrative, options?: GraphLayoutOptions): GraphLayout;
55
+ /** Render a layout as a standalone SVG string, for exports and server rendering. */
56
+ export declare function layoutToSvg(layout: GraphLayout, options?: {
57
+ background?: string;
58
+ label?: boolean;
59
+ }): string;
60
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,oBAAoB,CAAA;AAC9D,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhE,cAAc,YAAY,CAAA;AAE1B,MAAM,WAAW,kBAAkB;IACjC,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,2CAA2C;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,MAAM,EAAE,MAAM,CAAA;IACd,mEAAmE;IACnE,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC,UAAU,EAAE,cAAc,CAAA;IAC1B,QAAQ,EAAE,OAAO,CAAA;IACjB,cAAc,EAAE,MAAM,EAAE,CAAA;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,SAAS,EAAE,CAAA;IAClB,KAAK,EAAE,SAAS,EAAE,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAA;CACvC;AAqBD,8DAA8D;AAC9D,wBAAgB,eAAe,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,WAAW,CA6C/F;AAED,oFAAoF;AACpF,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAwB3G"}