marlarky 1.0.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 (274) hide show
  1. package/README.md +489 -0
  2. package/dist/adapters/faker-js-adapter.d.ts +44 -0
  3. package/dist/adapters/faker-js-adapter.d.ts.map +1 -0
  4. package/dist/adapters/faker-js-adapter.js +46 -0
  5. package/dist/adapters/faker-js-adapter.js.map +1 -0
  6. package/dist/adapters/index.d.ts +3 -0
  7. package/dist/adapters/index.d.ts.map +1 -0
  8. package/dist/adapters/index.js +3 -0
  9. package/dist/adapters/index.js.map +1 -0
  10. package/dist/adapters/simple-faker-adapter.d.ts +22 -0
  11. package/dist/adapters/simple-faker-adapter.d.ts.map +1 -0
  12. package/dist/adapters/simple-faker-adapter.js +54 -0
  13. package/dist/adapters/simple-faker-adapter.js.map +1 -0
  14. package/dist/cli.d.ts +7 -0
  15. package/dist/cli.d.ts.map +1 -0
  16. package/dist/cli.js +588 -0
  17. package/dist/cli.js.map +1 -0
  18. package/dist/defaults/index.d.ts +2 -0
  19. package/dist/defaults/index.d.ts.map +1 -0
  20. package/dist/defaults/index.js +2 -0
  21. package/dist/defaults/index.js.map +1 -0
  22. package/dist/defaults/word-lists.d.ts +22 -0
  23. package/dist/defaults/word-lists.d.ts.map +1 -0
  24. package/dist/defaults/word-lists.js +124 -0
  25. package/dist/defaults/word-lists.js.map +1 -0
  26. package/dist/generator/index.d.ts +2 -0
  27. package/dist/generator/index.d.ts.map +1 -0
  28. package/dist/generator/index.js +2 -0
  29. package/dist/generator/index.js.map +1 -0
  30. package/dist/generator/text-generator.d.ts +93 -0
  31. package/dist/generator/text-generator.d.ts.map +1 -0
  32. package/dist/generator/text-generator.js +411 -0
  33. package/dist/generator/text-generator.js.map +1 -0
  34. package/dist/generator/text-generator.test.d.ts +2 -0
  35. package/dist/generator/text-generator.test.d.ts.map +1 -0
  36. package/dist/generator/text-generator.test.js +151 -0
  37. package/dist/generator/text-generator.test.js.map +1 -0
  38. package/dist/grammar/index.d.ts +5 -0
  39. package/dist/grammar/index.d.ts.map +1 -0
  40. package/dist/grammar/index.js +3 -0
  41. package/dist/grammar/index.js.map +1 -0
  42. package/dist/grammar/phrase-builders.d.ts +72 -0
  43. package/dist/grammar/phrase-builders.d.ts.map +1 -0
  44. package/dist/grammar/phrase-builders.js +241 -0
  45. package/dist/grammar/phrase-builders.js.map +1 -0
  46. package/dist/grammar/sentence-templates.d.ts +67 -0
  47. package/dist/grammar/sentence-templates.d.ts.map +1 -0
  48. package/dist/grammar/sentence-templates.js +272 -0
  49. package/dist/grammar/sentence-templates.js.map +1 -0
  50. package/dist/index.d.ts +17 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +40 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/interfaces/faker-adapter.d.ts +25 -0
  55. package/dist/interfaces/faker-adapter.d.ts.map +1 -0
  56. package/dist/interfaces/faker-adapter.js +2 -0
  57. package/dist/interfaces/faker-adapter.js.map +1 -0
  58. package/dist/interfaces/index.d.ts +4 -0
  59. package/dist/interfaces/index.d.ts.map +1 -0
  60. package/dist/interfaces/index.js +2 -0
  61. package/dist/interfaces/index.js.map +1 -0
  62. package/dist/interfaces/lexicon-store.d.ts +39 -0
  63. package/dist/interfaces/lexicon-store.d.ts.map +1 -0
  64. package/dist/interfaces/lexicon-store.js +2 -0
  65. package/dist/interfaces/lexicon-store.js.map +1 -0
  66. package/dist/interfaces/rng.d.ts +25 -0
  67. package/dist/interfaces/rng.d.ts.map +1 -0
  68. package/dist/interfaces/rng.js +2 -0
  69. package/dist/interfaces/rng.js.map +1 -0
  70. package/dist/lexicon/index.d.ts +4 -0
  71. package/dist/lexicon/index.d.ts.map +1 -0
  72. package/dist/lexicon/index.js +4 -0
  73. package/dist/lexicon/index.js.map +1 -0
  74. package/dist/lexicon/loader.d.ts +24 -0
  75. package/dist/lexicon/loader.d.ts.map +1 -0
  76. package/dist/lexicon/loader.js +47 -0
  77. package/dist/lexicon/loader.js.map +1 -0
  78. package/dist/lexicon/store.d.ts +39 -0
  79. package/dist/lexicon/store.d.ts.map +1 -0
  80. package/dist/lexicon/store.js +291 -0
  81. package/dist/lexicon/store.js.map +1 -0
  82. package/dist/lexicon/validator.d.ts +10 -0
  83. package/dist/lexicon/validator.d.ts.map +1 -0
  84. package/dist/lexicon/validator.js +273 -0
  85. package/dist/lexicon/validator.js.map +1 -0
  86. package/dist/morphology/articles.d.ts +17 -0
  87. package/dist/morphology/articles.d.ts.map +1 -0
  88. package/dist/morphology/articles.js +66 -0
  89. package/dist/morphology/articles.js.map +1 -0
  90. package/dist/morphology/articles.test.d.ts +2 -0
  91. package/dist/morphology/articles.test.d.ts.map +1 -0
  92. package/dist/morphology/articles.test.js +56 -0
  93. package/dist/morphology/articles.test.js.map +1 -0
  94. package/dist/morphology/conjugate.d.ts +46 -0
  95. package/dist/morphology/conjugate.d.ts.map +1 -0
  96. package/dist/morphology/conjugate.js +337 -0
  97. package/dist/morphology/conjugate.js.map +1 -0
  98. package/dist/morphology/conjugate.test.d.ts +2 -0
  99. package/dist/morphology/conjugate.test.d.ts.map +1 -0
  100. package/dist/morphology/conjugate.test.js +168 -0
  101. package/dist/morphology/conjugate.test.js.map +1 -0
  102. package/dist/morphology/index.d.ts +6 -0
  103. package/dist/morphology/index.d.ts.map +1 -0
  104. package/dist/morphology/index.js +9 -0
  105. package/dist/morphology/index.js.map +1 -0
  106. package/dist/morphology/normalize.d.ts +52 -0
  107. package/dist/morphology/normalize.d.ts.map +1 -0
  108. package/dist/morphology/normalize.js +127 -0
  109. package/dist/morphology/normalize.js.map +1 -0
  110. package/dist/morphology/pluralize.d.ts +17 -0
  111. package/dist/morphology/pluralize.d.ts.map +1 -0
  112. package/dist/morphology/pluralize.js +186 -0
  113. package/dist/morphology/pluralize.js.map +1 -0
  114. package/dist/morphology/pluralize.test.d.ts +2 -0
  115. package/dist/morphology/pluralize.test.d.ts.map +1 -0
  116. package/dist/morphology/pluralize.test.js +86 -0
  117. package/dist/morphology/pluralize.test.js.map +1 -0
  118. package/dist/providers/index.d.ts +2 -0
  119. package/dist/providers/index.d.ts.map +1 -0
  120. package/dist/providers/index.js +2 -0
  121. package/dist/providers/index.js.map +1 -0
  122. package/dist/providers/word-provider.d.ts +125 -0
  123. package/dist/providers/word-provider.d.ts.map +1 -0
  124. package/dist/providers/word-provider.js +266 -0
  125. package/dist/providers/word-provider.js.map +1 -0
  126. package/dist/rng/index.d.ts +2 -0
  127. package/dist/rng/index.d.ts.map +1 -0
  128. package/dist/rng/index.js +2 -0
  129. package/dist/rng/index.js.map +1 -0
  130. package/dist/rng/seedable-rng.d.ts +19 -0
  131. package/dist/rng/seedable-rng.d.ts.map +1 -0
  132. package/dist/rng/seedable-rng.js +77 -0
  133. package/dist/rng/seedable-rng.js.map +1 -0
  134. package/dist/rng/seedable-rng.test.d.ts +2 -0
  135. package/dist/rng/seedable-rng.test.d.ts.map +1 -0
  136. package/dist/rng/seedable-rng.test.js +165 -0
  137. package/dist/rng/seedable-rng.test.js.map +1 -0
  138. package/dist/rules/index.d.ts +3 -0
  139. package/dist/rules/index.d.ts.map +1 -0
  140. package/dist/rules/index.js +2 -0
  141. package/dist/rules/index.js.map +1 -0
  142. package/dist/rules/rule-engine.d.ts +78 -0
  143. package/dist/rules/rule-engine.d.ts.map +1 -0
  144. package/dist/rules/rule-engine.js +271 -0
  145. package/dist/rules/rule-engine.js.map +1 -0
  146. package/dist/transforms/config-merge.d.ts +19 -0
  147. package/dist/transforms/config-merge.d.ts.map +1 -0
  148. package/dist/transforms/config-merge.js +88 -0
  149. package/dist/transforms/config-merge.js.map +1 -0
  150. package/dist/transforms/config-merge.test.d.ts +2 -0
  151. package/dist/transforms/config-merge.test.d.ts.map +1 -0
  152. package/dist/transforms/config-merge.test.js +91 -0
  153. package/dist/transforms/config-merge.test.js.map +1 -0
  154. package/dist/transforms/default-registry.d.ts +10 -0
  155. package/dist/transforms/default-registry.d.ts.map +1 -0
  156. package/dist/transforms/default-registry.js +17 -0
  157. package/dist/transforms/default-registry.js.map +1 -0
  158. package/dist/transforms/index.d.ts +15 -0
  159. package/dist/transforms/index.d.ts.map +1 -0
  160. package/dist/transforms/index.js +20 -0
  161. package/dist/transforms/index.js.map +1 -0
  162. package/dist/transforms/pipeline.d.ts +28 -0
  163. package/dist/transforms/pipeline.d.ts.map +1 -0
  164. package/dist/transforms/pipeline.js +176 -0
  165. package/dist/transforms/pipeline.js.map +1 -0
  166. package/dist/transforms/pipeline.test.d.ts +2 -0
  167. package/dist/transforms/pipeline.test.d.ts.map +1 -0
  168. package/dist/transforms/pipeline.test.js +175 -0
  169. package/dist/transforms/pipeline.test.js.map +1 -0
  170. package/dist/transforms/protection.d.ts +16 -0
  171. package/dist/transforms/protection.d.ts.map +1 -0
  172. package/dist/transforms/protection.js +97 -0
  173. package/dist/transforms/protection.js.map +1 -0
  174. package/dist/transforms/protection.test.d.ts +2 -0
  175. package/dist/transforms/protection.test.d.ts.map +1 -0
  176. package/dist/transforms/protection.test.js +79 -0
  177. package/dist/transforms/protection.test.js.map +1 -0
  178. package/dist/transforms/registry.d.ts +25 -0
  179. package/dist/transforms/registry.d.ts.map +1 -0
  180. package/dist/transforms/registry.js +32 -0
  181. package/dist/transforms/registry.js.map +1 -0
  182. package/dist/transforms/registry.test.d.ts +2 -0
  183. package/dist/transforms/registry.test.d.ts.map +1 -0
  184. package/dist/transforms/registry.test.js +64 -0
  185. package/dist/transforms/registry.test.js.map +1 -0
  186. package/dist/transforms/tokenizer.d.ts +26 -0
  187. package/dist/transforms/tokenizer.d.ts.map +1 -0
  188. package/dist/transforms/tokenizer.js +137 -0
  189. package/dist/transforms/tokenizer.js.map +1 -0
  190. package/dist/transforms/tokenizer.test.d.ts +2 -0
  191. package/dist/transforms/tokenizer.test.d.ts.map +1 -0
  192. package/dist/transforms/tokenizer.test.js +85 -0
  193. package/dist/transforms/tokenizer.test.js.map +1 -0
  194. package/dist/transforms/transforms/biz-jargon.d.ts +7 -0
  195. package/dist/transforms/transforms/biz-jargon.d.ts.map +1 -0
  196. package/dist/transforms/transforms/biz-jargon.js +117 -0
  197. package/dist/transforms/transforms/biz-jargon.js.map +1 -0
  198. package/dist/transforms/transforms/emoji.d.ts +7 -0
  199. package/dist/transforms/transforms/emoji.d.ts.map +1 -0
  200. package/dist/transforms/transforms/emoji.js +127 -0
  201. package/dist/transforms/transforms/emoji.js.map +1 -0
  202. package/dist/transforms/transforms/index.d.ts +17 -0
  203. package/dist/transforms/transforms/index.d.ts.map +1 -0
  204. package/dist/transforms/transforms/index.js +37 -0
  205. package/dist/transforms/transforms/index.js.map +1 -0
  206. package/dist/transforms/transforms/leet.d.ts +7 -0
  207. package/dist/transforms/transforms/leet.d.ts.map +1 -0
  208. package/dist/transforms/transforms/leet.js +109 -0
  209. package/dist/transforms/transforms/leet.js.map +1 -0
  210. package/dist/transforms/transforms/mock-case.d.ts +7 -0
  211. package/dist/transforms/transforms/mock-case.d.ts.map +1 -0
  212. package/dist/transforms/transforms/mock-case.js +116 -0
  213. package/dist/transforms/transforms/mock-case.js.map +1 -0
  214. package/dist/transforms/transforms/pig-latin.d.ts +7 -0
  215. package/dist/transforms/transforms/pig-latin.d.ts.map +1 -0
  216. package/dist/transforms/transforms/pig-latin.js +132 -0
  217. package/dist/transforms/transforms/pig-latin.js.map +1 -0
  218. package/dist/transforms/transforms/pig-latin.test.d.ts +2 -0
  219. package/dist/transforms/transforms/pig-latin.test.d.ts.map +1 -0
  220. package/dist/transforms/transforms/pig-latin.test.js +77 -0
  221. package/dist/transforms/transforms/pig-latin.test.js.map +1 -0
  222. package/dist/transforms/transforms/pirate.d.ts +7 -0
  223. package/dist/transforms/transforms/pirate.d.ts.map +1 -0
  224. package/dist/transforms/transforms/pirate.js +150 -0
  225. package/dist/transforms/transforms/pirate.js.map +1 -0
  226. package/dist/transforms/transforms/redact.d.ts +7 -0
  227. package/dist/transforms/transforms/redact.d.ts.map +1 -0
  228. package/dist/transforms/transforms/redact.js +109 -0
  229. package/dist/transforms/transforms/redact.js.map +1 -0
  230. package/dist/transforms/transforms/reverse-words.d.ts +7 -0
  231. package/dist/transforms/transforms/reverse-words.d.ts.map +1 -0
  232. package/dist/transforms/transforms/reverse-words.js +88 -0
  233. package/dist/transforms/transforms/reverse-words.js.map +1 -0
  234. package/dist/transforms/transforms/transforms.test.d.ts +11 -0
  235. package/dist/transforms/transforms/transforms.test.d.ts.map +1 -0
  236. package/dist/transforms/transforms/transforms.test.js +489 -0
  237. package/dist/transforms/transforms/transforms.test.js.map +1 -0
  238. package/dist/transforms/transforms/ubbi-dubbi.d.ts +7 -0
  239. package/dist/transforms/transforms/ubbi-dubbi.d.ts.map +1 -0
  240. package/dist/transforms/transforms/ubbi-dubbi.js +120 -0
  241. package/dist/transforms/transforms/ubbi-dubbi.js.map +1 -0
  242. package/dist/transforms/transforms/uwu.d.ts +7 -0
  243. package/dist/transforms/transforms/uwu.d.ts.map +1 -0
  244. package/dist/transforms/transforms/uwu.js +106 -0
  245. package/dist/transforms/transforms/uwu.js.map +1 -0
  246. package/dist/transforms/types.d.ts +159 -0
  247. package/dist/transforms/types.d.ts.map +1 -0
  248. package/dist/transforms/types.js +22 -0
  249. package/dist/transforms/types.js.map +1 -0
  250. package/dist/types/api.d.ts +158 -0
  251. package/dist/types/api.d.ts.map +1 -0
  252. package/dist/types/api.js +6 -0
  253. package/dist/types/api.js.map +1 -0
  254. package/dist/types/config.d.ts +86 -0
  255. package/dist/types/config.d.ts.map +1 -0
  256. package/dist/types/config.js +66 -0
  257. package/dist/types/config.js.map +1 -0
  258. package/dist/types/context.d.ts +74 -0
  259. package/dist/types/context.d.ts.map +1 -0
  260. package/dist/types/context.js +83 -0
  261. package/dist/types/context.js.map +1 -0
  262. package/dist/types/index.d.ts +7 -0
  263. package/dist/types/index.d.ts.map +1 -0
  264. package/dist/types/index.js +3 -0
  265. package/dist/types/index.js.map +1 -0
  266. package/dist/types/lexicon.d.ts +247 -0
  267. package/dist/types/lexicon.d.ts.map +1 -0
  268. package/dist/types/lexicon.js +6 -0
  269. package/dist/types/lexicon.js.map +1 -0
  270. package/examples/basic-usage.ts +48 -0
  271. package/examples/corporate-lexicon.ts +71 -0
  272. package/examples/lexicons/corporate-min.json +200 -0
  273. package/examples/with-tracing.ts +85 -0
  274. package/package.json +70 -0
package/README.md ADDED
@@ -0,0 +1,489 @@
1
+ # Marlarky
2
+
3
+ **Generate syntactically plausible English nonsense, steered by lexicons.**
4
+
5
+ Marlarky is a faker-like library and CLI that produces grammatically correct English text that sounds meaningful but isn't. Perfect for:
6
+
7
+ - Placeholder text generation (like Lorem Ipsum, but in English)
8
+ - Testing and mocking
9
+ - Creative writing prompts
10
+ - Procedural content generation
11
+ - Corporate buzzword bingo
12
+
13
+ ## Features
14
+
15
+ - **Syntactically correct** -- Proper grammar, subject-verb agreement, punctuation
16
+ - **Lexicon-driven** -- Guide output with custom vocabularies and style presets
17
+ - **Deterministic** -- Seedable RNG for reproducible output
18
+ - **Configurable** -- Control sentence types, lengths, complexity
19
+ - **Output transforms** -- Pipe text through built-in transforms (Pig Latin, leet speak, pirate, and more)
20
+ - **Traceable** -- Debug mode shows exactly how text was generated
21
+ - **Full CLI** -- Generate text, apply transforms, and validate lexicons from the command line
22
+ - **Zero dependencies** -- Works standalone or with @faker-js/faker
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ npm install marlarky
28
+ ```
29
+
30
+ ## Quick Start
31
+
32
+ ### TypeScript / JavaScript
33
+
34
+ ```typescript
35
+ import { TextGenerator, SimpleFakerAdapter } from 'marlarky';
36
+
37
+ const generator = new TextGenerator({
38
+ fakerAdapter: new SimpleFakerAdapter(),
39
+ });
40
+
41
+ generator.setSeed(42);
42
+
43
+ console.log(generator.sentence());
44
+ // "Generally, the change called."
45
+
46
+ console.log(generator.paragraph({ sentences: 3 }));
47
+ // Three sentences of plausible nonsense
48
+
49
+ console.log(generator.textBlock({ paragraphs: 2 }));
50
+ // Two paragraphs of corporate-sounding marlarky
51
+ ```
52
+
53
+ ### Command Line
54
+
55
+ ```bash
56
+ # Generate a sentence
57
+ marlarky sentence
58
+
59
+ # Generate a deterministic question
60
+ marlarky sentence --seed 42 --type question
61
+
62
+ # Generate a paragraph with a corporate lexicon
63
+ marlarky paragraph --sentences 5 --lexicon ./corp.json --archetype corporate
64
+
65
+ # Apply Pig Latin transform and output as JSON
66
+ marlarky sentence --seed 42 --transform pigLatin --json
67
+ ```
68
+
69
+ ## CLI
70
+
71
+ After installing globally (`npm install -g marlarky`) or locally, the `marlarky` command is available.
72
+
73
+ ### Commands
74
+
75
+ | Command | Description |
76
+ | ------------ | ----------------------------------------------- |
77
+ | `sentence` | Generate one or more sentences |
78
+ | `paragraph` | Generate one or more paragraphs |
79
+ | `text` | Generate a text block (multiple paragraphs) |
80
+ | `validate` | Validate a lexicon JSON file |
81
+ | `list` | List available transforms or sentence types |
82
+
83
+ ### Global Options
84
+
85
+ These options work with `sentence`, `paragraph`, and `text`:
86
+
87
+ | Option | Short | Description |
88
+ | -------------------------- | ----- | -------------------------------------------------------- |
89
+ | `--seed <n>` | `-s` | RNG seed for deterministic output |
90
+ | `--lexicon <path>` | `-l` | Path to a lexicon JSON file |
91
+ | `--archetype <name>` | `-a` | Archetype to activate from the lexicon |
92
+ | `--transform <id>` | `-x` | Apply an output transform (repeatable, comma-separated) |
93
+ | `--trace` | `-t` | Output JSON trace to stderr |
94
+ | `--json` | `-j` | Output full result as JSON to stdout |
95
+ | `--count <n>` | `-n` | Number of items to generate (default: 1) |
96
+ | `--help` | `-h` | Show help |
97
+ | `--version` | `-v` | Show version |
98
+
99
+ ### Generating Sentences
100
+
101
+ ```bash
102
+ # Random sentence
103
+ marlarky sentence
104
+
105
+ # Specific type
106
+ marlarky sentence --type question
107
+ marlarky sentence --type compound
108
+ marlarky sentence --type subordinate
109
+
110
+ # Control word count
111
+ marlarky sentence --min-words 10 --max-words 20
112
+
113
+ # Multiple sentences
114
+ marlarky sentence --count 5
115
+
116
+ # With hints (activate lexicon tags)
117
+ marlarky sentence --hints domain:tech,register:formal
118
+ ```
119
+
120
+ ### Generating Paragraphs
121
+
122
+ ```bash
123
+ # Random paragraph
124
+ marlarky paragraph
125
+
126
+ # Control sentence count
127
+ marlarky paragraph --sentences 5
128
+ marlarky paragraph --min-sentences 3 --max-sentences 8
129
+
130
+ # Multiple paragraphs
131
+ marlarky paragraph --count 3
132
+ ```
133
+
134
+ ### Generating Text Blocks
135
+
136
+ ```bash
137
+ # Random text block
138
+ marlarky text
139
+
140
+ # Control paragraph count
141
+ marlarky text --paragraphs 4
142
+ marlarky text --min-paragraphs 2 --max-paragraphs 6
143
+ ```
144
+
145
+ ### Applying Transforms
146
+
147
+ Use `--transform` (or `-x`) to pipe generated text through built-in transforms:
148
+
149
+ ```bash
150
+ # Pig Latin
151
+ marlarky sentence --seed 42 --transform pigLatin
152
+ # "Enerallygay, ethay angechay alledcay."
153
+
154
+ # Leet speak
155
+ marlarky sentence --seed 42 --transform leet
156
+
157
+ # Chain multiple transforms (comma-separated)
158
+ marlarky sentence --seed 42 --transform leet,uwu
159
+
160
+ # Or use repeated flags
161
+ marlarky sentence --seed 42 -x pirate -x mockCase
162
+ ```
163
+
164
+ Run `marlarky list transforms` to see all available transforms.
165
+
166
+ ### JSON Output
167
+
168
+ Use `--json` (or `-j`) to get structured output including metadata and trace:
169
+
170
+ ```bash
171
+ marlarky sentence --seed 42 --json
172
+ ```
173
+
174
+ ```json
175
+ {
176
+ "text": "Generally, the change called.",
177
+ "trace": { "..." : "..." },
178
+ "meta": {
179
+ "archetype": "default",
180
+ "seed": 42
181
+ }
182
+ }
183
+ ```
184
+
185
+ ### Validating Lexicons
186
+
187
+ ```bash
188
+ # Human-readable output
189
+ marlarky validate ./my-lexicon.json
190
+
191
+ # Machine-readable JSON output
192
+ marlarky validate ./my-lexicon.json --json
193
+ ```
194
+
195
+ ### Listing Available Features
196
+
197
+ ```bash
198
+ # List all output transforms
199
+ marlarky list transforms
200
+
201
+ # List all sentence types
202
+ marlarky list types
203
+
204
+ # Output as JSON
205
+ marlarky list transforms --json
206
+ ```
207
+
208
+ ## Output Transforms
209
+
210
+ Marlarky includes 10 built-in output transforms that modify generated text at the token level. All transforms are deterministic (same seed = same output) and safe to chain.
211
+
212
+ | Transform | Description |
213
+ | --------------- | ----------------------------------------- |
214
+ | `pigLatin` | Classic Pig Latin |
215
+ | `ubbiDubbi` | Ubbi Dubbi language game |
216
+ | `leet` | Leetspeak character substitution |
217
+ | `uwu` | Cute speak (w-substitution, suffixes) |
218
+ | `pirate` | Pirate speak |
219
+ | `redact` | Redact/mask words |
220
+ | `emoji` | Add emoji replacements |
221
+ | `mockCase` | rAnDoM cAsE aLtErNaTiOn |
222
+ | `reverseWords` | Reverse word order |
223
+ | `bizJargon` | Business jargon patterns |
224
+
225
+ ### Using Transforms in Code
226
+
227
+ ```typescript
228
+ const result = generator.sentence({
229
+ outputTransforms: {
230
+ enabled: true,
231
+ pipeline: [{ id: 'pigLatin' }],
232
+ },
233
+ });
234
+ ```
235
+
236
+ Transforms can also be configured at the lexicon level or per-archetype in your lexicon JSON. See the [usage guide](usage.md#output-transforms) for details.
237
+
238
+ ## Sentence Types
239
+
240
+ Marlarky generates six sentence structures:
241
+
242
+ ```typescript
243
+ // Simple declarative: "The system processes data."
244
+ generator.sentence({ type: 'simpleDeclarative' });
245
+
246
+ // Question: "Does the team deliver results?"
247
+ generator.sentence({ type: 'question' });
248
+
249
+ // Compound: "The strategy evolved, and the metrics improved."
250
+ generator.sentence({ type: 'compound' });
251
+
252
+ // Subordinate clause: "Because the pipeline scales, the throughput increases."
253
+ generator.sentence({ type: 'subordinate' });
254
+
255
+ // Intro adverbial: "Furthermore, the initiative drives innovation."
256
+ generator.sentence({ type: 'introAdverbial' });
257
+
258
+ // Interjection: "Indeed, the team delivered results."
259
+ generator.sentence({ type: 'interjection' });
260
+ ```
261
+
262
+ ## Deterministic Output
263
+
264
+ Same seed produces the same text every time:
265
+
266
+ ```typescript
267
+ generator.setSeed(12345);
268
+ const a = generator.sentence();
269
+
270
+ generator.setSeed(12345);
271
+ const b = generator.sentence();
272
+
273
+ console.log(a === b); // true
274
+ ```
275
+
276
+ From the CLI:
277
+
278
+ ```bash
279
+ marlarky sentence --seed 12345
280
+ marlarky sentence --seed 12345
281
+ # Both print the same sentence
282
+ ```
283
+
284
+ ## Custom Lexicons
285
+
286
+ Create domain-specific marlarky with JSON lexicon files:
287
+
288
+ ```json
289
+ {
290
+ "id": "lexicon.startup",
291
+ "language": "en",
292
+ "termSets": {
293
+ "noun.startup": {
294
+ "pos": "noun",
295
+ "tags": ["domain:startup"],
296
+ "terms": [
297
+ { "value": "disruptor", "weight": 5 },
298
+ { "value": "unicorn", "weight": 3 },
299
+ { "value": "pivot", "weight": 4 },
300
+ { "value": "runway", "weight": 2 }
301
+ ]
302
+ },
303
+ "verb.startup": {
304
+ "pos": "verb",
305
+ "tags": ["domain:startup"],
306
+ "terms": [
307
+ { "value": "disrupt", "weight": 5 },
308
+ { "value": "scale", "weight": 4 },
309
+ { "value": "pivot", "weight": 3 },
310
+ { "value": "iterate", "weight": 3 }
311
+ ]
312
+ }
313
+ },
314
+ "archetypes": {
315
+ "startup": {
316
+ "tags": ["domain:startup"]
317
+ }
318
+ }
319
+ }
320
+ ```
321
+
322
+ Load it in code:
323
+
324
+ ```typescript
325
+ import { TextGenerator, SimpleFakerAdapter, loadLexiconFromString } from 'marlarky';
326
+ import { readFileSync } from 'fs';
327
+
328
+ const lexicon = loadLexiconFromString(readFileSync('./startup.json', 'utf-8'));
329
+
330
+ const generator = new TextGenerator({
331
+ fakerAdapter: new SimpleFakerAdapter(),
332
+ lexicon,
333
+ });
334
+
335
+ generator.setArchetype('startup');
336
+ console.log(generator.paragraph());
337
+ ```
338
+
339
+ Or from the CLI:
340
+
341
+ ```bash
342
+ marlarky paragraph --lexicon ./startup.json --archetype startup
343
+ ```
344
+
345
+ See the [usage guide](usage.md#lexicon-schema) for the full lexicon schema reference.
346
+
347
+ ## Morphology Utilities
348
+
349
+ Marlarky exports standalone English morphology functions:
350
+
351
+ ```typescript
352
+ import {
353
+ pluralize,
354
+ singularize,
355
+ getPastTense,
356
+ getPresentParticiple,
357
+ getThirdPersonSingular,
358
+ getIndefiniteArticle,
359
+ } from 'marlarky';
360
+
361
+ pluralize('synergy'); // "synergies"
362
+ pluralize('child'); // "children"
363
+ singularize('stakeholders'); // "stakeholder"
364
+ getPastTense('leverage'); // "leveraged"
365
+ getPastTense('go'); // "went"
366
+ getPresentParticiple('run'); // "running"
367
+ getThirdPersonSingular('do'); // "does"
368
+ getIndefiniteArticle('hour'); // "an"
369
+ getIndefiniteArticle('user'); // "a"
370
+ ```
371
+
372
+ ## With @faker-js/faker
373
+
374
+ For more word variety, use the optional faker-js adapter:
375
+
376
+ ```typescript
377
+ import { TextGenerator, FakerJsAdapter } from 'marlarky';
378
+ import { faker } from '@faker-js/faker';
379
+
380
+ const generator = new TextGenerator({
381
+ fakerAdapter: new FakerJsAdapter(faker),
382
+ });
383
+ ```
384
+
385
+ `@faker-js/faker` is an optional peer dependency -- Marlarky works without it using the built-in `SimpleFakerAdapter`.
386
+
387
+ ## Configuration
388
+
389
+ Fine-tune generation behavior:
390
+
391
+ ```typescript
392
+ const generator = new TextGenerator({
393
+ fakerAdapter: new SimpleFakerAdapter(),
394
+ config: {
395
+ minWordsPerSentence: 10,
396
+ maxWordsPerSentence: 25,
397
+ minSentencesPerParagraph: 3,
398
+ maxSentencesPerParagraph: 6,
399
+ questionRate: 0.05,
400
+ compoundRate: 0.20,
401
+ subordinateClauseRate: 0.15,
402
+ maxPPChain: 2,
403
+ maxAdjectivesPerNoun: 2,
404
+ },
405
+ });
406
+ ```
407
+
408
+ See the [usage guide](usage.md#configuration) for all configuration options.
409
+
410
+ ## Tracing
411
+
412
+ Enable trace mode to see how text was generated:
413
+
414
+ ```typescript
415
+ const generator = new TextGenerator({
416
+ fakerAdapter: new SimpleFakerAdapter(),
417
+ enableTrace: true,
418
+ });
419
+
420
+ const result = generator.sentence();
421
+
422
+ console.log(result.text);
423
+ // "The robust system efficiently processes data."
424
+
425
+ console.log(result.trace.paragraphs[0].sentences[0].template);
426
+ // "simpleDeclarative"
427
+
428
+ console.log(result.trace.paragraphs[0].sentences[0].tokens);
429
+ // [{ value: "The", source: "default" }, { value: "robust", source: "adj.business" }, ...]
430
+ ```
431
+
432
+ From the CLI, use `--trace` to send trace data to stderr, or `--json` to include it in structured stdout output.
433
+
434
+ ## Examples
435
+
436
+ ```bash
437
+ # Run the basic usage example
438
+ npm run example:basic
439
+
440
+ # Run the corporate lexicon example
441
+ npm run example:corporate
442
+ ```
443
+
444
+ ## Development
445
+
446
+ ```bash
447
+ # Install dependencies
448
+ npm install
449
+
450
+ # Build
451
+ npm run build
452
+
453
+ # Run tests (watch mode)
454
+ npm test
455
+
456
+ # Run tests once
457
+ npm run test:run
458
+
459
+ # Run tests with coverage
460
+ npm run test:coverage
461
+
462
+ # Lint
463
+ npm run lint
464
+ ```
465
+
466
+ ## API Summary
467
+
468
+ For the complete API reference including all types, interfaces, and configuration options, see the [usage guide](usage.md).
469
+
470
+ | Method / Function | Description |
471
+ | ----------------------------- | ---------------------------------------- |
472
+ | `new TextGenerator(opts)` | Create a generator instance |
473
+ | `generator.sentence(opts?)` | Generate one sentence |
474
+ | `generator.paragraph(opts?)` | Generate a paragraph (2-7 sentences) |
475
+ | `generator.textBlock(opts?)` | Generate multiple paragraphs |
476
+ | `generator.setSeed(n)` | Set RNG seed for reproducibility |
477
+ | `generator.setLexicon(lex)` | Load or replace a lexicon at runtime |
478
+ | `generator.setArchetype(name)`| Activate a style preset |
479
+ | `validateLexicon(obj)` | Validate a lexicon object |
480
+ | `loadLexiconFromString(json)` | Parse a lexicon JSON string |
481
+
482
+ ## License
483
+
484
+ MIT
485
+
486
+ ---
487
+
488
+ _"Leveraging synergistic paradigms to facilitate robust deliverables across the ecosystem."_
489
+ -- marlarky
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Faker.js Adapter
3
+ * Adapts @faker-js/faker to IFakerAdapter interface
4
+ */
5
+ import type { IFakerAdapter } from '../interfaces/faker-adapter.js';
6
+ type FakerInstance = {
7
+ word: {
8
+ adjective: () => string;
9
+ adverb: () => string;
10
+ noun: () => string;
11
+ verb: () => string;
12
+ preposition: () => string;
13
+ conjunction: () => string;
14
+ interjection: () => string;
15
+ };
16
+ person: {
17
+ firstName: () => string;
18
+ lastName: () => string;
19
+ };
20
+ location: {
21
+ city: () => string;
22
+ };
23
+ number: {
24
+ int: (options: {
25
+ min: number;
26
+ max: number;
27
+ }) => number;
28
+ };
29
+ };
30
+ export declare class FakerJsAdapter implements IFakerAdapter {
31
+ private faker;
32
+ constructor(faker: FakerInstance);
33
+ adjective(): string;
34
+ adverb(): string;
35
+ noun(): string;
36
+ verb(): string;
37
+ preposition(): string;
38
+ conjunction(): string;
39
+ interjection(): string;
40
+ properNoun(): string;
41
+ number(): string;
42
+ }
43
+ export {};
44
+ //# sourceMappingURL=faker-js-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"faker-js-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/faker-js-adapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAGpE,KAAK,aAAa,GAAG;IACnB,IAAI,EAAE;QACJ,SAAS,EAAE,MAAM,MAAM,CAAC;QACxB,MAAM,EAAE,MAAM,MAAM,CAAC;QACrB,IAAI,EAAE,MAAM,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,MAAM,CAAC;QAC1B,WAAW,EAAE,MAAM,MAAM,CAAC;QAC1B,YAAY,EAAE,MAAM,MAAM,CAAC;KAC5B,CAAC;IACF,MAAM,EAAE;QACN,SAAS,EAAE,MAAM,MAAM,CAAC;QACxB,QAAQ,EAAE,MAAM,MAAM,CAAC;KACxB,CAAC;IACF,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,MAAM,CAAC;KACpB,CAAC;IACF,MAAM,EAAE;QACN,GAAG,EAAE,CAAC,OAAO,EAAE;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAA;SAAE,KAAK,MAAM,CAAC;KACxD,CAAC;CACH,CAAC;AAEF,qBAAa,cAAe,YAAW,aAAa;IAClD,OAAO,CAAC,KAAK,CAAgB;gBAEjB,KAAK,EAAE,aAAa;IAIhC,SAAS,IAAI,MAAM;IAInB,MAAM,IAAI,MAAM;IAIhB,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;IAId,WAAW,IAAI,MAAM;IAIrB,WAAW,IAAI,MAAM;IAIrB,YAAY,IAAI,MAAM;IAItB,UAAU,IAAI,MAAM;IAWpB,MAAM,IAAI,MAAM;CAIjB"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Faker.js Adapter
3
+ * Adapts @faker-js/faker to IFakerAdapter interface
4
+ */
5
+ export class FakerJsAdapter {
6
+ faker;
7
+ constructor(faker) {
8
+ this.faker = faker;
9
+ }
10
+ adjective() {
11
+ return this.faker.word.adjective();
12
+ }
13
+ adverb() {
14
+ return this.faker.word.adverb();
15
+ }
16
+ noun() {
17
+ return this.faker.word.noun();
18
+ }
19
+ verb() {
20
+ return this.faker.word.verb();
21
+ }
22
+ preposition() {
23
+ return this.faker.word.preposition();
24
+ }
25
+ conjunction() {
26
+ return this.faker.word.conjunction();
27
+ }
28
+ interjection() {
29
+ return this.faker.word.interjection();
30
+ }
31
+ properNoun() {
32
+ // Mix of first names, last names, and cities
33
+ const options = [
34
+ () => this.faker.person.firstName(),
35
+ () => this.faker.person.lastName(),
36
+ () => this.faker.location.city(),
37
+ ];
38
+ const index = this.faker.number.int({ min: 0, max: options.length - 1 });
39
+ return options[index]();
40
+ }
41
+ number() {
42
+ const num = this.faker.number.int({ min: 1, max: 100 });
43
+ return String(num);
44
+ }
45
+ }
46
+ //# sourceMappingURL=faker-js-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"faker-js-adapter.js","sourceRoot":"","sources":["../../src/adapters/faker-js-adapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA2BH,MAAM,OAAO,cAAc;IACjB,KAAK,CAAgB;IAE7B,YAAY,KAAoB;QAC9B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;IACrC,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;IAClC,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAChC,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAChC,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IACvC,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IACvC,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;IACxC,CAAC;IAED,UAAU;QACR,6CAA6C;QAC7C,MAAM,OAAO,GAAG;YACd,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,EAAE;YACnC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE;YAClC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE;SACjC,CAAC;QACF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC;QACzE,OAAO,OAAO,CAAC,KAAK,CAAE,EAAE,CAAC;IAC3B,CAAC;IAED,MAAM;QACJ,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QACxD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ export { FakerJsAdapter } from './faker-js-adapter.js';
2
+ export { SimpleFakerAdapter } from './simple-faker-adapter.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { FakerJsAdapter } from './faker-js-adapter.js';
2
+ export { SimpleFakerAdapter } from './simple-faker-adapter.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Simple Faker Adapter
3
+ * A basic implementation that uses built-in word lists when @faker-js/faker isn't available
4
+ */
5
+ import type { IFakerAdapter } from '../interfaces/faker-adapter.js';
6
+ import type { IRng } from '../interfaces/rng.js';
7
+ export declare class SimpleFakerAdapter implements IFakerAdapter {
8
+ private rng;
9
+ constructor(rng?: IRng);
10
+ adjective(): string;
11
+ adverb(): string;
12
+ noun(): string;
13
+ verb(): string;
14
+ preposition(): string;
15
+ conjunction(): string;
16
+ interjection(): string;
17
+ properNoun(): string;
18
+ number(): string;
19
+ /** Set the RNG seed */
20
+ seed(n: number): void;
21
+ }
22
+ //# sourceMappingURL=simple-faker-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simple-faker-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/simple-faker-adapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAIjD,qBAAa,kBAAmB,YAAW,aAAa;IACtD,OAAO,CAAC,GAAG,CAAO;gBAEN,GAAG,CAAC,EAAE,IAAI;IAItB,SAAS,IAAI,MAAM;IAInB,MAAM,IAAI,MAAM;IAIhB,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;IAId,WAAW,IAAI,MAAM;IAIrB,WAAW,IAAI,MAAM;IAIrB,YAAY,IAAI,MAAM;IAItB,UAAU,IAAI,MAAM;IAUpB,MAAM,IAAI,MAAM;IAQhB,uBAAuB;IACvB,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;CAGtB"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Simple Faker Adapter
3
+ * A basic implementation that uses built-in word lists when @faker-js/faker isn't available
4
+ */
5
+ import { SeedableRng } from '../rng/index.js';
6
+ import * as defaults from '../defaults/index.js';
7
+ export class SimpleFakerAdapter {
8
+ rng;
9
+ constructor(rng) {
10
+ this.rng = rng ?? new SeedableRng();
11
+ }
12
+ adjective() {
13
+ return this.rng.pick(defaults.DEFAULT_ADJECTIVES);
14
+ }
15
+ adverb() {
16
+ return this.rng.pick(defaults.DEFAULT_ADVERBS);
17
+ }
18
+ noun() {
19
+ return this.rng.pick(defaults.DEFAULT_NOUNS);
20
+ }
21
+ verb() {
22
+ return this.rng.pick(defaults.DEFAULT_VERBS);
23
+ }
24
+ preposition() {
25
+ return this.rng.pick(defaults.DEFAULT_PREPOSITIONS);
26
+ }
27
+ conjunction() {
28
+ return this.rng.pick(defaults.DEFAULT_CONJUNCTIONS);
29
+ }
30
+ interjection() {
31
+ return this.rng.pick(defaults.DEFAULT_INTERJECTIONS);
32
+ }
33
+ properNoun() {
34
+ const names = [
35
+ 'John', 'Jane', 'Alice', 'Bob', 'Charlie', 'Diana',
36
+ 'Edward', 'Fiona', 'George', 'Helen', 'Ivan', 'Julia',
37
+ 'Smith', 'Johnson', 'Williams', 'Brown', 'Jones', 'Davis',
38
+ 'London', 'Paris', 'Tokyo', 'Sydney', 'Berlin', 'Madrid',
39
+ ];
40
+ return this.rng.pick(names);
41
+ }
42
+ number() {
43
+ const numbers = [
44
+ 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten',
45
+ 'eleven', 'twelve', 'twenty', 'fifty', 'hundred',
46
+ ];
47
+ return this.rng.pick(numbers);
48
+ }
49
+ /** Set the RNG seed */
50
+ seed(n) {
51
+ this.rng.seed(n);
52
+ }
53
+ }
54
+ //# sourceMappingURL=simple-faker-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simple-faker-adapter.js","sourceRoot":"","sources":["../../src/adapters/simple-faker-adapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAC;AAEjD,MAAM,OAAO,kBAAkB;IACrB,GAAG,CAAO;IAElB,YAAY,GAAU;QACpB,IAAI,CAAC,GAAG,GAAG,GAAG,IAAI,IAAI,WAAW,EAAE,CAAC;IACtC,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IACpD,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;IACjD,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IAC/C,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC;IACtD,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC;IACtD,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC;IACvD,CAAC;IAED,UAAU;QACR,MAAM,KAAK,GAAG;YACZ,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO;YAClD,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO;YACrD,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO;YACzD,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ;SACzD,CAAC;QACF,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM;QACJ,MAAM,OAAO,GAAG;YACd,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK;YAC7E,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS;SACjD,CAAC;QACF,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAED,uBAAuB;IACvB,IAAI,CAAC,CAAS;QACZ,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC;CACF"}