make-mp-data 3.0.4 → 3.0.6

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 (66) 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/ecommerce-schema.json +462 -0
  5. package/dungeons/{copilot.js → ecommerce.js} +77 -15
  6. package/dungeons/education-schema.json +2409 -0
  7. package/dungeons/education.js +206 -442
  8. package/dungeons/fintech-schema.json +14034 -0
  9. package/dungeons/fintech.js +110 -389
  10. package/dungeons/foobar-schema.json +403 -0
  11. package/dungeons/foobar.js +27 -4
  12. package/dungeons/food-delivery-schema.json +192 -0
  13. package/dungeons/food-delivery.js +602 -0
  14. package/dungeons/food-schema.json +1152 -0
  15. package/dungeons/food.js +150 -383
  16. package/dungeons/gaming-schema.json +1270 -0
  17. package/dungeons/gaming.js +143 -3
  18. package/dungeons/insurance-application-schema.json +204 -0
  19. package/dungeons/insurance-application.js +605 -0
  20. package/dungeons/media-schema.json +906 -0
  21. package/dungeons/media.js +221 -391
  22. package/dungeons/retention-cadence-schema.json +78 -0
  23. package/dungeons/retention-cadence.js +35 -1
  24. package/dungeons/rpg-schema.json +4526 -0
  25. package/dungeons/rpg.js +130 -388
  26. package/dungeons/sanity-schema.json +255 -0
  27. package/dungeons/sanity.js +21 -10
  28. package/dungeons/sass-schema.json +1291 -0
  29. package/dungeons/sass.js +210 -337
  30. package/dungeons/scd-schema.json +919 -0
  31. package/dungeons/scd.js +38 -10
  32. package/dungeons/simple-schema.json +608 -0
  33. package/dungeons/simple.js +48 -11
  34. package/dungeons/simplest-schema.json +1418 -0
  35. package/dungeons/simplest.js +392 -0
  36. package/dungeons/social-schema.json +1118 -0
  37. package/dungeons/social.js +124 -365
  38. package/dungeons/text-generation-schema.json +3096 -0
  39. package/dungeons/text-generation.js +71 -0
  40. package/index.js +6 -3
  41. package/lib/core/config-validator.js +18 -0
  42. package/lib/core/storage.js +5 -5
  43. package/lib/generators/events.js +4 -4
  44. package/lib/orchestrators/mixpanel-sender.js +14 -8
  45. package/lib/orchestrators/user-loop.js +14 -6
  46. package/lib/templates/soup-presets.js +188 -0
  47. package/lib/utils/utils.js +52 -6
  48. package/package.json +2 -2
  49. package/types.d.ts +20 -3
  50. package/dungeons/adspend.js +0 -117
  51. package/dungeons/anon.js +0 -128
  52. package/dungeons/benchmark-heavy.js +0 -240
  53. package/dungeons/benchmark-light.js +0 -126
  54. package/dungeons/big.js +0 -226
  55. package/dungeons/business.js +0 -391
  56. package/dungeons/complex.js +0 -428
  57. package/dungeons/experiments.js +0 -137
  58. package/dungeons/funnels.js +0 -309
  59. package/dungeons/mil.js +0 -323
  60. package/dungeons/mirror.js +0 -160
  61. package/dungeons/soup-test.js +0 -52
  62. package/dungeons/streaming.js +0 -372
  63. package/dungeons/strict-event-test.js +0 -30
  64. package/dungeons/student-teacher.js +0 -438
  65. package/dungeons/too-big-events.js +0 -203
  66. 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
+ }