make-mp-data 3.0.4 → 3.0.5

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 (70) hide show
  1. package/README.md +46 -0
  2. package/dungeons/array-of-object-lookup-schema.json +327 -0
  3. package/dungeons/array-of-object-lookup.js +28 -8
  4. package/dungeons/capstone/capstone-ic3.js +291 -0
  5. package/dungeons/capstone/capstone-ic4.js +598 -0
  6. package/dungeons/capstone/capstone-ic5.js +668 -0
  7. package/dungeons/capstone/generate-product-lookup.js +309 -0
  8. package/dungeons/ecommerce-schema.json +462 -0
  9. package/dungeons/{copilot.js → ecommerce.js} +77 -15
  10. package/dungeons/education-schema.json +2409 -0
  11. package/dungeons/education.js +206 -442
  12. package/dungeons/fintech-schema.json +14034 -0
  13. package/dungeons/fintech.js +110 -389
  14. package/dungeons/foobar-schema.json +403 -0
  15. package/dungeons/foobar.js +27 -4
  16. package/dungeons/food-delivery-schema.json +192 -0
  17. package/dungeons/food-delivery.js +602 -0
  18. package/dungeons/food-schema.json +1152 -0
  19. package/dungeons/food.js +150 -383
  20. package/dungeons/gaming-schema.json +1270 -0
  21. package/dungeons/gaming.js +143 -3
  22. package/dungeons/insurance-application-schema.json +204 -0
  23. package/dungeons/insurance-application.js +605 -0
  24. package/dungeons/media-schema.json +906 -0
  25. package/dungeons/media.js +221 -391
  26. package/dungeons/retention-cadence-schema.json +78 -0
  27. package/dungeons/retention-cadence.js +35 -1
  28. package/dungeons/rpg-schema.json +4526 -0
  29. package/dungeons/rpg.js +130 -388
  30. package/dungeons/sanity-schema.json +255 -0
  31. package/dungeons/sanity.js +21 -10
  32. package/dungeons/sass-schema.json +1291 -0
  33. package/dungeons/sass.js +210 -337
  34. package/dungeons/scd-schema.json +919 -0
  35. package/dungeons/scd.js +38 -10
  36. package/dungeons/simple-schema.json +608 -0
  37. package/dungeons/simple.js +48 -11
  38. package/dungeons/simplest-schema.json +1418 -0
  39. package/dungeons/simplest.js +392 -0
  40. package/dungeons/social-schema.json +1118 -0
  41. package/dungeons/social.js +124 -365
  42. package/dungeons/text-generation-schema.json +3096 -0
  43. package/dungeons/text-generation.js +71 -0
  44. package/index.js +6 -3
  45. package/lib/core/config-validator.js +18 -0
  46. package/lib/core/storage.js +5 -5
  47. package/lib/generators/events.js +4 -4
  48. package/lib/orchestrators/mixpanel-sender.js +12 -7
  49. package/lib/orchestrators/user-loop.js +14 -6
  50. package/lib/templates/soup-presets.js +188 -0
  51. package/lib/utils/utils.js +52 -6
  52. package/package.json +1 -1
  53. package/types.d.ts +20 -3
  54. package/dungeons/adspend.js +0 -117
  55. package/dungeons/anon.js +0 -128
  56. package/dungeons/benchmark-heavy.js +0 -240
  57. package/dungeons/benchmark-light.js +0 -126
  58. package/dungeons/big.js +0 -226
  59. package/dungeons/business.js +0 -391
  60. package/dungeons/complex.js +0 -428
  61. package/dungeons/experiments.js +0 -137
  62. package/dungeons/funnels.js +0 -309
  63. package/dungeons/mil.js +0 -323
  64. package/dungeons/mirror.js +0 -160
  65. package/dungeons/soup-test.js +0 -52
  66. package/dungeons/streaming.js +0 -372
  67. package/dungeons/strict-event-test.js +0 -30
  68. package/dungeons/student-teacher.js +0 -438
  69. package/dungeons/too-big-events.js +0 -203
  70. package/dungeons/user-agent.js +0 -209
@@ -0,0 +1,919 @@
1
+ {
2
+ "schema": {
3
+ "token": "",
4
+ "seed": "simple is best",
5
+ "numDays": 30,
6
+ "numEvents": 50000,
7
+ "numUsers": 500,
8
+ "format": "csv",
9
+ "region": "US",
10
+ "hasAnonIds": false,
11
+ "hasSessionIds": false,
12
+ "hasAdSpend": false,
13
+ "hasLocation": true,
14
+ "hasAndroidDevices": true,
15
+ "hasIOSDevices": true,
16
+ "hasDesktopDevices": true,
17
+ "hasBrowser": true,
18
+ "hasCampaigns": true,
19
+ "isAnonymous": false,
20
+ "events": [
21
+ {
22
+ "event": "checkout",
23
+ "weight": 2,
24
+ "properties": {
25
+ "amount": [
26
+ 110,
27
+ 153,
28
+ 209,
29
+ 398,
30
+ 119,
31
+ 131,
32
+ 160,
33
+ 180,
34
+ 393,
35
+ 362,
36
+ 112,
37
+ 298,
38
+ 349,
39
+ 136,
40
+ 370,
41
+ 131,
42
+ 142,
43
+ 127,
44
+ 151,
45
+ 385,
46
+ 339,
47
+ 362,
48
+ 111,
49
+ 148,
50
+ 336,
51
+ 158,
52
+ 188,
53
+ 159,
54
+ 119,
55
+ 340,
56
+ 369,
57
+ 127,
58
+ 125,
59
+ 379,
60
+ 166,
61
+ 129,
62
+ 390,
63
+ 126,
64
+ 155,
65
+ 124,
66
+ 345,
67
+ 196,
68
+ 159,
69
+ 131,
70
+ 253,
71
+ 149,
72
+ 155,
73
+ 161,
74
+ 149,
75
+ 333
76
+ ],
77
+ "currency": [
78
+ "USD",
79
+ "CAD",
80
+ "EUR",
81
+ "BTC",
82
+ "ETH",
83
+ "JPY"
84
+ ],
85
+ "coupon": {
86
+ "functionName": "arrow",
87
+ "body": "function generateWeightedArray() {\n\t\tconst weightedArray = [];\n\n\t\t// Add each value to the array the number of times specified by its weight\n\t\tweightedItems.forEach(({ value, weight }) => {\n\t\t\tif (!weight) weight = 1;\n\t\t\tfor (let i = 0; i < weight; i++) {\n\t\t\t\tweightedArray.push(value);\n\t\t\t}\n\t\t});\n\n\t\treturn weightedArray;\n\t}"
88
+ },
89
+ "numItems": [
90
+ 5,
91
+ 5,
92
+ 4,
93
+ 3,
94
+ 5,
95
+ 5,
96
+ 6,
97
+ 3,
98
+ 5,
99
+ 4,
100
+ 9,
101
+ 3,
102
+ 8,
103
+ 8,
104
+ 7,
105
+ 3,
106
+ 8,
107
+ 4,
108
+ 6,
109
+ 9,
110
+ 7,
111
+ 5,
112
+ 8,
113
+ 4,
114
+ 4,
115
+ 5,
116
+ 5,
117
+ 3,
118
+ 5,
119
+ 5,
120
+ 4,
121
+ 4,
122
+ 3,
123
+ 6,
124
+ 1,
125
+ 1,
126
+ 5,
127
+ 5,
128
+ 6,
129
+ 5,
130
+ 6,
131
+ 7,
132
+ 4,
133
+ 4,
134
+ 2,
135
+ 3,
136
+ 2,
137
+ 5,
138
+ 8,
139
+ 3
140
+ ]
141
+ }
142
+ },
143
+ {
144
+ "event": "add to cart",
145
+ "weight": 4,
146
+ "properties": {
147
+ "amount": [
148
+ 131,
149
+ 112,
150
+ 138,
151
+ 145,
152
+ 160,
153
+ 371,
154
+ 146,
155
+ 163,
156
+ 386,
157
+ 160,
158
+ 128,
159
+ 141,
160
+ 137,
161
+ 116,
162
+ 139,
163
+ 383,
164
+ 186,
165
+ 201,
166
+ 349,
167
+ 136,
168
+ 125,
169
+ 136,
170
+ 363,
171
+ 129,
172
+ 151,
173
+ 130,
174
+ 148,
175
+ 158,
176
+ 375,
177
+ 383,
178
+ 137,
179
+ 117,
180
+ 326,
181
+ 337,
182
+ 191,
183
+ 127,
184
+ 127,
185
+ 167,
186
+ 129,
187
+ 253,
188
+ 371,
189
+ 169,
190
+ 123,
191
+ 392,
192
+ 171,
193
+ 123,
194
+ 346,
195
+ 362,
196
+ 223,
197
+ 360
198
+ ],
199
+ "rating": [
200
+ 2,
201
+ 2,
202
+ 2,
203
+ 3,
204
+ 3,
205
+ 3,
206
+ 2,
207
+ 1,
208
+ 2,
209
+ 5,
210
+ 2,
211
+ 2,
212
+ 2,
213
+ 2,
214
+ 2,
215
+ 2,
216
+ 3,
217
+ 2,
218
+ 4,
219
+ 3,
220
+ 2,
221
+ 2,
222
+ 3,
223
+ 3,
224
+ 2,
225
+ 4,
226
+ 3,
227
+ 4,
228
+ 2,
229
+ 2,
230
+ 3,
231
+ 5,
232
+ 5,
233
+ 2,
234
+ 2,
235
+ 2,
236
+ 2,
237
+ 4,
238
+ 2,
239
+ 2,
240
+ 3,
241
+ 4,
242
+ 3,
243
+ 1,
244
+ 2,
245
+ 3,
246
+ 3,
247
+ 2,
248
+ 5,
249
+ 4
250
+ ],
251
+ "reviews": [
252
+ 9,
253
+ 27,
254
+ 20,
255
+ 16,
256
+ 16,
257
+ 4,
258
+ 23,
259
+ 9,
260
+ 17,
261
+ 22,
262
+ 15,
263
+ 8,
264
+ 12,
265
+ 13,
266
+ 9,
267
+ 15,
268
+ 18,
269
+ 10,
270
+ 14,
271
+ 16,
272
+ 10,
273
+ 9,
274
+ 6,
275
+ 9,
276
+ 15,
277
+ 18,
278
+ 28,
279
+ 14,
280
+ 6,
281
+ 20,
282
+ 23,
283
+ 26,
284
+ 9,
285
+ 20,
286
+ 3,
287
+ 14,
288
+ 26,
289
+ 13,
290
+ 19,
291
+ 14,
292
+ 10,
293
+ 18,
294
+ 20,
295
+ 29,
296
+ 8,
297
+ 8,
298
+ 12,
299
+ 8,
300
+ 8,
301
+ 19
302
+ ],
303
+ "isFeaturedItem": [
304
+ true,
305
+ false,
306
+ false
307
+ ],
308
+ "itemCategory": {
309
+ "functionName": "arrow",
310
+ "body": "function () {\n\t\tconst weighted = [];\n\t\tfor (let i = 0; i < 10; i++) {\n\t\t\tconst rand = chance.d10(); // Random number between 1 and 10\n\n\t\t\t// 35% chance to favor the most chosen index\n\t\t\tif (chance.bool({ likelihood: 35 })) {\n\t\t\t\t// 50% chance to slightly alter the index\n\t\t\t\tif (chance.bool({ likelihood: 50 })) {\n\t\t\t\t\tweighted.push(items[mostChosenIndex]);\n\t\t\t\t} else {\n\t\t\t\t\tconst addOrSubtract = chance.bool({ likelihood: 50 }) ? -rand : rand;\n\t\t\t\t\tlet newIndex = mostChosenIndex + addOrSubtract;\n\n\t\t\t\t\t// Ensure newIndex is within bounds\n\t\t\t\t\tif (newIndex < 0) newIndex = 0;\n\t\t\t\t\tif (newIndex >= items.length) newIndex = items.length - 1;\n\t\t\t\t\tweighted.push(items[newIndex]);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// 25% chance to favor the second most chosen index\n\t\t\telse if (chance.bool({ likelihood: 25 })) {\n\t\t\t\tweighted.push(items[secondMostChosenIndex]);\n\t\t\t}\n\t\t\t// 15% chance to favor the third most chosen index\n\t\t\telse if (chance.bool({ likelihood: 15 })) {\n\t\t\t\tweighted.push(items[thirdMostChosenIndex]);\n\t\t\t}\n\t\t\t// Otherwise, pick a random item from the list\n\t\t\telse {\n\t\t\t\tweighted.push(chance.pickone(items));\n\t\t\t}\n\t\t}\n\t\treturn weighted;\n\t}"
311
+ },
312
+ "dateItemListed": {
313
+ "functionName": "integer",
314
+ "args": []
315
+ }
316
+ }
317
+ },
318
+ {
319
+ "event": "page view",
320
+ "weight": 10,
321
+ "properties": {
322
+ "page": {
323
+ "functionName": "arrow",
324
+ "body": "function () {\n\t\tconst weighted = [];\n\t\tfor (let i = 0; i < 10; i++) {\n\t\t\tconst rand = chance.d10(); // Random number between 1 and 10\n\n\t\t\t// 35% chance to favor the most chosen index\n\t\t\tif (chance.bool({ likelihood: 35 })) {\n\t\t\t\t// 50% chance to slightly alter the index\n\t\t\t\tif (chance.bool({ likelihood: 50 })) {\n\t\t\t\t\tweighted.push(items[mostChosenIndex]);\n\t\t\t\t} else {\n\t\t\t\t\tconst addOrSubtract = chance.bool({ likelihood: 50 }) ? -rand : rand;\n\t\t\t\t\tlet newIndex = mostChosenIndex + addOrSubtract;\n\n\t\t\t\t\t// Ensure newIndex is within bounds\n\t\t\t\t\tif (newIndex < 0) newIndex = 0;\n\t\t\t\t\tif (newIndex >= items.length) newIndex = items.length - 1;\n\t\t\t\t\tweighted.push(items[newIndex]);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// 25% chance to favor the second most chosen index\n\t\t\telse if (chance.bool({ likelihood: 25 })) {\n\t\t\t\tweighted.push(items[secondMostChosenIndex]);\n\t\t\t}\n\t\t\t// 15% chance to favor the third most chosen index\n\t\t\telse if (chance.bool({ likelihood: 15 })) {\n\t\t\t\tweighted.push(items[thirdMostChosenIndex]);\n\t\t\t}\n\t\t\t// Otherwise, pick a random item from the list\n\t\t\telse {\n\t\t\t\tweighted.push(chance.pickone(items));\n\t\t\t}\n\t\t}\n\t\treturn weighted;\n\t}"
325
+ },
326
+ "utm_source": {
327
+ "functionName": "arrow",
328
+ "body": "function () {\n\t\tconst weighted = [];\n\t\tfor (let i = 0; i < 10; i++) {\n\t\t\tconst rand = chance.d10(); // Random number between 1 and 10\n\n\t\t\t// 35% chance to favor the most chosen index\n\t\t\tif (chance.bool({ likelihood: 35 })) {\n\t\t\t\t// 50% chance to slightly alter the index\n\t\t\t\tif (chance.bool({ likelihood: 50 })) {\n\t\t\t\t\tweighted.push(items[mostChosenIndex]);\n\t\t\t\t} else {\n\t\t\t\t\tconst addOrSubtract = chance.bool({ likelihood: 50 }) ? -rand : rand;\n\t\t\t\t\tlet newIndex = mostChosenIndex + addOrSubtract;\n\n\t\t\t\t\t// Ensure newIndex is within bounds\n\t\t\t\t\tif (newIndex < 0) newIndex = 0;\n\t\t\t\t\tif (newIndex >= items.length) newIndex = items.length - 1;\n\t\t\t\t\tweighted.push(items[newIndex]);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// 25% chance to favor the second most chosen index\n\t\t\telse if (chance.bool({ likelihood: 25 })) {\n\t\t\t\tweighted.push(items[secondMostChosenIndex]);\n\t\t\t}\n\t\t\t// 15% chance to favor the third most chosen index\n\t\t\telse if (chance.bool({ likelihood: 15 })) {\n\t\t\t\tweighted.push(items[thirdMostChosenIndex]);\n\t\t\t}\n\t\t\t// Otherwise, pick a random item from the list\n\t\t\telse {\n\t\t\t\tweighted.push(chance.pickone(items));\n\t\t\t}\n\t\t}\n\t\treturn weighted;\n\t}"
329
+ }
330
+ }
331
+ },
332
+ {
333
+ "event": "watch video",
334
+ "weight": 8,
335
+ "properties": {
336
+ "videoCategory": {
337
+ "functionName": "arrow",
338
+ "body": "function () {\n\t\tconst weighted = [];\n\t\tfor (let i = 0; i < 10; i++) {\n\t\t\tconst rand = chance.d10(); // Random number between 1 and 10\n\n\t\t\t// 35% chance to favor the most chosen index\n\t\t\tif (chance.bool({ likelihood: 35 })) {\n\t\t\t\t// 50% chance to slightly alter the index\n\t\t\t\tif (chance.bool({ likelihood: 50 })) {\n\t\t\t\t\tweighted.push(items[mostChosenIndex]);\n\t\t\t\t} else {\n\t\t\t\t\tconst addOrSubtract = chance.bool({ likelihood: 50 }) ? -rand : rand;\n\t\t\t\t\tlet newIndex = mostChosenIndex + addOrSubtract;\n\n\t\t\t\t\t// Ensure newIndex is within bounds\n\t\t\t\t\tif (newIndex < 0) newIndex = 0;\n\t\t\t\t\tif (newIndex >= items.length) newIndex = items.length - 1;\n\t\t\t\t\tweighted.push(items[newIndex]);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// 25% chance to favor the second most chosen index\n\t\t\telse if (chance.bool({ likelihood: 25 })) {\n\t\t\t\tweighted.push(items[secondMostChosenIndex]);\n\t\t\t}\n\t\t\t// 15% chance to favor the third most chosen index\n\t\t\telse if (chance.bool({ likelihood: 15 })) {\n\t\t\t\tweighted.push(items[thirdMostChosenIndex]);\n\t\t\t}\n\t\t\t// Otherwise, pick a random item from the list\n\t\t\telse {\n\t\t\t\tweighted.push(chance.pickone(items));\n\t\t\t}\n\t\t}\n\t\treturn weighted;\n\t}"
339
+ },
340
+ "isFeaturedItem": [
341
+ true,
342
+ false,
343
+ false
344
+ ],
345
+ "watchTimeSec": [
346
+ 433,
347
+ 466,
348
+ 143,
349
+ 178,
350
+ 159,
351
+ 449,
352
+ 170,
353
+ 145,
354
+ 170,
355
+ 168,
356
+ 159,
357
+ 161,
358
+ 173,
359
+ 240,
360
+ 131,
361
+ 424,
362
+ 180,
363
+ 431,
364
+ 197,
365
+ 305,
366
+ 156,
367
+ 183,
368
+ 466,
369
+ 149,
370
+ 453,
371
+ 440,
372
+ 207,
373
+ 161,
374
+ 158,
375
+ 159,
376
+ 437,
377
+ 159,
378
+ 156,
379
+ 180,
380
+ 384,
381
+ 404,
382
+ 149,
383
+ 458,
384
+ 136,
385
+ 168,
386
+ 453,
387
+ 415,
388
+ 148,
389
+ 187,
390
+ 155,
391
+ 305,
392
+ 161,
393
+ 175,
394
+ 161,
395
+ 195
396
+ ],
397
+ "quality": [
398
+ "2160p",
399
+ "1440p",
400
+ "1080p",
401
+ "720p",
402
+ "480p",
403
+ "360p",
404
+ "240p"
405
+ ],
406
+ "format": [
407
+ "mp4",
408
+ "avi",
409
+ "mov",
410
+ "mpg"
411
+ ],
412
+ "uploader_id": {
413
+ "functionName": "arrow",
414
+ "body": "function () { [native code] }"
415
+ }
416
+ }
417
+ },
418
+ {
419
+ "event": "view item",
420
+ "weight": 8,
421
+ "properties": {
422
+ "isFeaturedItem": [
423
+ true,
424
+ false,
425
+ false
426
+ ],
427
+ "itemCategory": {
428
+ "functionName": "arrow",
429
+ "body": "function () {\n\t\tconst weighted = [];\n\t\tfor (let i = 0; i < 10; i++) {\n\t\t\tconst rand = chance.d10(); // Random number between 1 and 10\n\n\t\t\t// 35% chance to favor the most chosen index\n\t\t\tif (chance.bool({ likelihood: 35 })) {\n\t\t\t\t// 50% chance to slightly alter the index\n\t\t\t\tif (chance.bool({ likelihood: 50 })) {\n\t\t\t\t\tweighted.push(items[mostChosenIndex]);\n\t\t\t\t} else {\n\t\t\t\t\tconst addOrSubtract = chance.bool({ likelihood: 50 }) ? -rand : rand;\n\t\t\t\t\tlet newIndex = mostChosenIndex + addOrSubtract;\n\n\t\t\t\t\t// Ensure newIndex is within bounds\n\t\t\t\t\tif (newIndex < 0) newIndex = 0;\n\t\t\t\t\tif (newIndex >= items.length) newIndex = items.length - 1;\n\t\t\t\t\tweighted.push(items[newIndex]);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// 25% chance to favor the second most chosen index\n\t\t\telse if (chance.bool({ likelihood: 25 })) {\n\t\t\t\tweighted.push(items[secondMostChosenIndex]);\n\t\t\t}\n\t\t\t// 15% chance to favor the third most chosen index\n\t\t\telse if (chance.bool({ likelihood: 15 })) {\n\t\t\t\tweighted.push(items[thirdMostChosenIndex]);\n\t\t\t}\n\t\t\t// Otherwise, pick a random item from the list\n\t\t\telse {\n\t\t\t\tweighted.push(chance.pickone(items));\n\t\t\t}\n\t\t}\n\t\treturn weighted;\n\t}"
430
+ },
431
+ "dateItemListed": {
432
+ "functionName": "integer",
433
+ "args": []
434
+ }
435
+ }
436
+ },
437
+ {
438
+ "event": "save item",
439
+ "weight": 5,
440
+ "properties": {
441
+ "isFeaturedItem": [
442
+ true,
443
+ false,
444
+ false
445
+ ],
446
+ "itemCategory": {
447
+ "functionName": "arrow",
448
+ "body": "function () {\n\t\tconst weighted = [];\n\t\tfor (let i = 0; i < 10; i++) {\n\t\t\tconst rand = chance.d10(); // Random number between 1 and 10\n\n\t\t\t// 35% chance to favor the most chosen index\n\t\t\tif (chance.bool({ likelihood: 35 })) {\n\t\t\t\t// 50% chance to slightly alter the index\n\t\t\t\tif (chance.bool({ likelihood: 50 })) {\n\t\t\t\t\tweighted.push(items[mostChosenIndex]);\n\t\t\t\t} else {\n\t\t\t\t\tconst addOrSubtract = chance.bool({ likelihood: 50 }) ? -rand : rand;\n\t\t\t\t\tlet newIndex = mostChosenIndex + addOrSubtract;\n\n\t\t\t\t\t// Ensure newIndex is within bounds\n\t\t\t\t\tif (newIndex < 0) newIndex = 0;\n\t\t\t\t\tif (newIndex >= items.length) newIndex = items.length - 1;\n\t\t\t\t\tweighted.push(items[newIndex]);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// 25% chance to favor the second most chosen index\n\t\t\telse if (chance.bool({ likelihood: 25 })) {\n\t\t\t\tweighted.push(items[secondMostChosenIndex]);\n\t\t\t}\n\t\t\t// 15% chance to favor the third most chosen index\n\t\t\telse if (chance.bool({ likelihood: 15 })) {\n\t\t\t\tweighted.push(items[thirdMostChosenIndex]);\n\t\t\t}\n\t\t\t// Otherwise, pick a random item from the list\n\t\t\telse {\n\t\t\t\tweighted.push(chance.pickone(items));\n\t\t\t}\n\t\t}\n\t\treturn weighted;\n\t}"
449
+ },
450
+ "dateItemListed": {
451
+ "functionName": "integer",
452
+ "args": []
453
+ }
454
+ }
455
+ },
456
+ {
457
+ "event": "sign up",
458
+ "isFirstEvent": true,
459
+ "weight": 0,
460
+ "properties": {
461
+ "variants": [
462
+ "A",
463
+ "B",
464
+ "C",
465
+ "Control"
466
+ ],
467
+ "flows": [
468
+ "new",
469
+ "existing",
470
+ "loyal",
471
+ "churned"
472
+ ],
473
+ "flags": [
474
+ "on",
475
+ "off"
476
+ ],
477
+ "experiment_ids": [
478
+ "1234",
479
+ "5678",
480
+ "9012",
481
+ "3456",
482
+ "7890"
483
+ ],
484
+ "multiVariate": [
485
+ true,
486
+ false
487
+ ]
488
+ }
489
+ }
490
+ ],
491
+ "superProps": {
492
+ "platform": [
493
+ "web",
494
+ "mobile",
495
+ "web",
496
+ "mobile",
497
+ "web",
498
+ "web",
499
+ "kiosk",
500
+ "smartTV"
501
+ ],
502
+ "currentTheme": {
503
+ "functionName": "arrow",
504
+ "body": "function generateWeightedArray() {\n\t\tconst weightedArray = [];\n\n\t\t// Add each value to the array the number of times specified by its weight\n\t\tweightedItems.forEach(({ value, weight }) => {\n\t\t\tif (!weight) weight = 1;\n\t\t\tfor (let i = 0; i < weight; i++) {\n\t\t\t\tweightedArray.push(value);\n\t\t\t}\n\t\t});\n\n\t\treturn weightedArray;\n\t}"
505
+ }
506
+ },
507
+ "userProps": {
508
+ "title": {
509
+ "functionName": "arrow",
510
+ "body": "function () { [native code] }"
511
+ },
512
+ "luckyNumber": [
513
+ 317,
514
+ 311,
515
+ 170,
516
+ 315,
517
+ 146,
518
+ 313,
519
+ 167,
520
+ 146,
521
+ 153,
522
+ 185,
523
+ 129,
524
+ 174,
525
+ 231,
526
+ 184,
527
+ 328,
528
+ 297,
529
+ 146,
530
+ 253,
531
+ 140,
532
+ 152,
533
+ 165,
534
+ 147,
535
+ 314,
536
+ 305,
537
+ 127,
538
+ 122,
539
+ 144,
540
+ 335,
541
+ 314,
542
+ 148,
543
+ 154,
544
+ 311,
545
+ 158,
546
+ 144,
547
+ 309,
548
+ 152,
549
+ 311,
550
+ 136,
551
+ 145,
552
+ 231,
553
+ 162,
554
+ 145,
555
+ 331,
556
+ 331,
557
+ 136,
558
+ 162,
559
+ 144,
560
+ 138,
561
+ 142,
562
+ 117
563
+ ],
564
+ "spiritAnimal": {
565
+ "functionName": "arrow",
566
+ "body": "function () {\n\t\tconst weighted = [];\n\t\tfor (let i = 0; i < 10; i++) {\n\t\t\tconst rand = chance.d10(); // Random number between 1 and 10\n\n\t\t\t// 35% chance to favor the most chosen index\n\t\t\tif (chance.bool({ likelihood: 35 })) {\n\t\t\t\t// 50% chance to slightly alter the index\n\t\t\t\tif (chance.bool({ likelihood: 50 })) {\n\t\t\t\t\tweighted.push(items[mostChosenIndex]);\n\t\t\t\t} else {\n\t\t\t\t\tconst addOrSubtract = chance.bool({ likelihood: 50 }) ? -rand : rand;\n\t\t\t\t\tlet newIndex = mostChosenIndex + addOrSubtract;\n\n\t\t\t\t\t// Ensure newIndex is within bounds\n\t\t\t\t\tif (newIndex < 0) newIndex = 0;\n\t\t\t\t\tif (newIndex >= items.length) newIndex = items.length - 1;\n\t\t\t\t\tweighted.push(items[newIndex]);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// 25% chance to favor the second most chosen index\n\t\t\telse if (chance.bool({ likelihood: 25 })) {\n\t\t\t\tweighted.push(items[secondMostChosenIndex]);\n\t\t\t}\n\t\t\t// 15% chance to favor the third most chosen index\n\t\t\telse if (chance.bool({ likelihood: 15 })) {\n\t\t\t\tweighted.push(items[thirdMostChosenIndex]);\n\t\t\t}\n\t\t\t// Otherwise, pick a random item from the list\n\t\t\telse {\n\t\t\t\tweighted.push(chance.pickone(items));\n\t\t\t}\n\t\t}\n\t\treturn weighted;\n\t}"
567
+ }
568
+ },
569
+ "scdProps": {
570
+ "role": {
571
+ "type": "user",
572
+ "frequency": "week",
573
+ "values": [
574
+ "admin",
575
+ "collaborator",
576
+ "user",
577
+ "view only",
578
+ "no access"
579
+ ],
580
+ "timing": "fuzzy",
581
+ "max": 10
582
+ },
583
+ "NPS": {
584
+ "type": "user",
585
+ "frequency": "day",
586
+ "values": [
587
+ 6,
588
+ 3,
589
+ 3,
590
+ 5,
591
+ 5,
592
+ 4,
593
+ 6,
594
+ 5,
595
+ 3,
596
+ 9,
597
+ 4,
598
+ 8,
599
+ 5,
600
+ 6,
601
+ 7,
602
+ 3,
603
+ 5,
604
+ 7,
605
+ 3,
606
+ 5,
607
+ 5,
608
+ 3,
609
+ 5,
610
+ 5,
611
+ 3,
612
+ 5,
613
+ 5,
614
+ 5,
615
+ 4,
616
+ 5,
617
+ 5,
618
+ 6,
619
+ 8,
620
+ 9,
621
+ 7,
622
+ 5,
623
+ 5,
624
+ 6,
625
+ 5,
626
+ 9,
627
+ 5,
628
+ 4,
629
+ 5,
630
+ 5,
631
+ 7,
632
+ 4,
633
+ 3,
634
+ 4,
635
+ 6,
636
+ 6,
637
+ 2,
638
+ 6,
639
+ 6,
640
+ 6,
641
+ 5,
642
+ 6,
643
+ 5,
644
+ 4,
645
+ 3,
646
+ 3,
647
+ 2,
648
+ 3,
649
+ 3,
650
+ 4,
651
+ 5,
652
+ 1,
653
+ 7,
654
+ 3,
655
+ 6,
656
+ 5,
657
+ 5,
658
+ 8,
659
+ 5,
660
+ 2,
661
+ 9,
662
+ 2,
663
+ 4,
664
+ 2,
665
+ 5,
666
+ 6,
667
+ 5,
668
+ 8,
669
+ 6,
670
+ 5,
671
+ 2,
672
+ 3,
673
+ 6,
674
+ 5,
675
+ 5,
676
+ 6,
677
+ 6,
678
+ 3,
679
+ 3,
680
+ 6,
681
+ 3,
682
+ 5,
683
+ 4,
684
+ 8,
685
+ 5,
686
+ 5,
687
+ 5,
688
+ 5,
689
+ 4,
690
+ 6,
691
+ 5,
692
+ 5,
693
+ 6,
694
+ 6,
695
+ 4,
696
+ 7,
697
+ 3,
698
+ 9,
699
+ 6,
700
+ 4,
701
+ 5,
702
+ 5,
703
+ 6,
704
+ 6,
705
+ 7,
706
+ 5,
707
+ 6,
708
+ 5,
709
+ 3,
710
+ 5,
711
+ 4,
712
+ 4,
713
+ 5,
714
+ 8,
715
+ 4,
716
+ 6,
717
+ 6,
718
+ 5,
719
+ 6,
720
+ 5,
721
+ 6,
722
+ 5,
723
+ 7,
724
+ 4,
725
+ 1,
726
+ 5,
727
+ 5,
728
+ 8,
729
+ 5,
730
+ 6,
731
+ 7,
732
+ 5,
733
+ 10,
734
+ 6,
735
+ 3,
736
+ 5
737
+ ],
738
+ "timing": "fuzzy",
739
+ "max": 10
740
+ },
741
+ "MRR": {
742
+ "type": "company_id",
743
+ "frequency": "month",
744
+ "values": [
745
+ 6654,
746
+ 2862,
747
+ 3571,
748
+ 2527,
749
+ 2534,
750
+ 6981,
751
+ 3429,
752
+ 2845,
753
+ 2720,
754
+ 2442,
755
+ 2609,
756
+ 2279,
757
+ 7677,
758
+ 2867,
759
+ 2605,
760
+ 6859,
761
+ 6998,
762
+ 6329,
763
+ 2384,
764
+ 6926,
765
+ 2472,
766
+ 7445,
767
+ 2449,
768
+ 7529,
769
+ 2494,
770
+ 2686,
771
+ 2820,
772
+ 7322,
773
+ 2430,
774
+ 7362,
775
+ 2562,
776
+ 2916,
777
+ 2487,
778
+ 7255,
779
+ 7341,
780
+ 2906,
781
+ 7460,
782
+ 2767,
783
+ 2498,
784
+ 7439,
785
+ 2901,
786
+ 2542,
787
+ 2696,
788
+ 6468,
789
+ 7199,
790
+ 7611,
791
+ 2911,
792
+ 2262,
793
+ 7466,
794
+ 2594
795
+ ],
796
+ "timing": "fixed",
797
+ "max": 10
798
+ },
799
+ "AccountHealthScore": {
800
+ "type": "company_id",
801
+ "frequency": "week",
802
+ "values": [
803
+ 3,
804
+ 4,
805
+ 4,
806
+ 7,
807
+ 3,
808
+ 3,
809
+ 4,
810
+ 4,
811
+ 8,
812
+ 7,
813
+ 3,
814
+ 8,
815
+ 7,
816
+ 7,
817
+ 8,
818
+ 3,
819
+ 8,
820
+ 3,
821
+ 8,
822
+ 3,
823
+ 3,
824
+ 4,
825
+ 3,
826
+ 3,
827
+ 4,
828
+ 4,
829
+ 3,
830
+ 3,
831
+ 7,
832
+ 7,
833
+ 4,
834
+ 3,
835
+ 6,
836
+ 8,
837
+ 3,
838
+ 8,
839
+ 8,
840
+ 8,
841
+ 4,
842
+ 3,
843
+ 3,
844
+ 7,
845
+ 8,
846
+ 3,
847
+ 8,
848
+ 4,
849
+ 7,
850
+ 8,
851
+ 4,
852
+ 3
853
+ ],
854
+ "timing": "fixed",
855
+ "max": 40
856
+ },
857
+ "plan": {
858
+ "type": "company_id",
859
+ "frequency": "month",
860
+ "values": [
861
+ "free",
862
+ "basic",
863
+ "premium",
864
+ "enterprise"
865
+ ],
866
+ "timing": "fixed",
867
+ "max": 10
868
+ }
869
+ },
870
+ "groupKeys": [
871
+ [
872
+ "company_id",
873
+ 1000
874
+ ]
875
+ ],
876
+ "groupProps": {
877
+ "company_id": {
878
+ "name": {
879
+ "functionName": "arrow",
880
+ "body": "() => { return chance.name(); }"
881
+ },
882
+ "email": {
883
+ "functionName": "arrow",
884
+ "body": "() => { return `CSM: ${chance.pickone([\"AK\", \"Neha\", \"Rajiv\", \"Deepak\", \"Justin\", \"Hans\", \"Katie\", \"Somya\", \"Tony\", \"Kaan\"])}`; }"
885
+ },
886
+ "industry": [
887
+ "technology",
888
+ "education",
889
+ "finance",
890
+ "healthcare",
891
+ "retail",
892
+ "manufacturing",
893
+ "transportation",
894
+ "entertainment",
895
+ "media",
896
+ "real estate",
897
+ "construction",
898
+ "hospitality",
899
+ "energy",
900
+ "utilities",
901
+ "agriculture",
902
+ "other"
903
+ ],
904
+ "segment": [
905
+ "SMB",
906
+ "SMB",
907
+ "SMB",
908
+ "Mid Market",
909
+ "Mid Market",
910
+ "Enterprise"
911
+ ],
912
+ "# active users": 20
913
+ }
914
+ }
915
+ },
916
+ "hooks": "function (record, type, meta) {\n\t\t// --- user hook: classify users into spending tiers ---\n\t\tif (type === \"user\") {\n\t\t\trecord.spendTier = record.luckyNumber > 250 ? \"high_spender\" : \"budget\";\n\t\t\treturn record;\n\t\t}\n\n\t\t// --- event hook: coupon users get discounted checkout amounts ---\n\t\tif (type === \"event\") {\n\t\t\tif (record.event === \"checkout\" && record.coupon && record.coupon !== \"none\") {\n\t\t\t\tconst discountPct = parseInt(record.coupon) || 10;\n\t\t\t\trecord.amount = Math.round(record.amount * (1 - discountPct / 100));\n\t\t\t\trecord.discount_applied = true;\n\t\t\t}\n\t\t\t// weekend watchers get longer watch times\n\t\t\tif (record.event === \"watch video\" && record.time) {\n\t\t\t\tconst day = dayjs(record.time).day();\n\t\t\t\tif (day === 0 || day === 6) {\n\t\t\t\t\trecord.watchTimeSec = Math.round((record.watchTimeSec || 60) * 1.5);\n\t\t\t\t\trecord.is_weekend = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn record;\n\t\t}\n\n\t\t// --- everything hook: simulate cart abandonment ---\n\t\tif (type === \"everything\") {\n\t\t\tconst hasAddToCart = record.some(e => e.event === \"add to cart\");\n\t\t\tconst hasCheckout = record.some(e => e.event === \"checkout\");\n\t\t\t// users who added to cart but never checked out: remove checkout events (if any slipped through)\n\t\t\t// and mark them as abandoned\n\t\t\tif (hasAddToCart && !hasCheckout && record.length > 2) {\n\t\t\t\tconst lastAdd = record.filter(e => e.event === \"add to cart\").pop();\n\t\t\t\tif (lastAdd) {\n\t\t\t\t\trecord.push({\n\t\t\t\t\t\tevent: \"cart_abandoned\",\n\t\t\t\t\t\ttime: dayjs(lastAdd.time).add(30, \"minute\").toISOString(),\n\t\t\t\t\t\tuser_id: lastAdd.user_id,\n\t\t\t\t\t\tplatform: lastAdd.platform,\n\t\t\t\t\t\tamount: lastAdd.amount\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn record;\n\t\t}\n\n\t\treturn record;\n\t}",
917
+ "timestamp": "2026-04-10T01:39:07.491Z",
918
+ "version": "4.0"
919
+ }