@media-quest/builder 0.0.26 → 0.0.28

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.
@@ -0,0 +1,2740 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/public-api.ts
21
+ var public_api_exports = {};
22
+ __export(public_api_exports, {
23
+ BuilderCondition: () => BuilderCondition,
24
+ BuilderConditionGroup: () => BuilderConditionGroup,
25
+ BuilderMainText: () => BuilderMainText,
26
+ BuilderOperator: () => BuilderOperator,
27
+ BuilderOption: () => BuilderOption,
28
+ BuilderPage: () => BuilderPage,
29
+ BuilderQuestion: () => BuilderQuestion,
30
+ BuilderRule: () => BuilderRule,
31
+ BuilderSchema: () => BuilderSchema,
32
+ BuilderTag: () => BuilderTag,
33
+ BuilderText: () => BuilderText,
34
+ CodeBook: () => CodeBook,
35
+ ExcludeByPageIdSelectItem: () => ExcludeByPageIdSelectItem,
36
+ ExcludeByTagSelectItem: () => ExcludeByTagSelectItem,
37
+ JumpToActionManager: () => JumpToActionManager,
38
+ JumpToPageSelectItem: () => JumpToPageSelectItem,
39
+ MultiSelectItem: () => MultiSelectItem,
40
+ OperatorSelectItem: () => OperatorSelectItem,
41
+ OptionID: () => OptionID,
42
+ PageActionManager: () => PageActionManager,
43
+ PageID: () => PageID,
44
+ PagePrefix: () => PagePrefix,
45
+ QuestionID: () => QuestionID,
46
+ RuleCustomVariable: () => RuleCustomVariable,
47
+ RuleInput: () => RuleInput,
48
+ RuleOptionSelectItem: () => RuleOptionSelectItem,
49
+ RuleQuestionVariable: () => RuleQuestionVariable,
50
+ RuleVariableOption: () => RuleVariableOption,
51
+ RuleVariableSelectItem: () => RuleVariableSelectItem,
52
+ SchemaConfig: () => SchemaConfig,
53
+ SchemaID: () => SchemaID,
54
+ SchemaPrefix: () => SchemaPrefix,
55
+ SingleSelectItem: () => SingleSelectItem,
56
+ SumScore: () => SumScore,
57
+ SumScoreVariable: () => SumScoreVariable,
58
+ SumScoreVariableID: () => SumScoreVariableID,
59
+ TagActionManager: () => TagActionManager,
60
+ TagCollection: () => TagCollection,
61
+ TagID: () => TagID,
62
+ TextID: () => TextID,
63
+ VarID: () => VarID,
64
+ _CodeBook: () => _CodeBook,
65
+ createTypedIdSingleton: () => createTypedIdSingleton
66
+ });
67
+ module.exports = __toCommonJS(public_api_exports);
68
+
69
+ // src/BuilderObject.ts
70
+ var BuilderObject = class {
71
+ originalDto;
72
+ constructor(dto) {
73
+ this.originalDto = dto;
74
+ }
75
+ };
76
+
77
+ // src/primitives/ID.ts
78
+ var ID_LENGTH = 32;
79
+ var MIN_LENGTH = 10;
80
+ var isID = (idName, id) => {
81
+ if (typeof id !== "string")
82
+ return false;
83
+ return id.length >= MIN_LENGTH;
84
+ };
85
+ var createIDByName = (idName) => {
86
+ const letters = "abcdefghijklmnopqrstuvyz";
87
+ const all = letters + letters.toUpperCase();
88
+ let result = "";
89
+ for (let i = 0; i < ID_LENGTH; i++) {
90
+ const char = all.charAt(Math.floor(Math.random() * all.length));
91
+ result += char;
92
+ }
93
+ return result;
94
+ };
95
+ var createDummyID = (idName, letter) => {
96
+ return letter.repeat(ID_LENGTH);
97
+ };
98
+ var createTypedIdSingleton = (idName) => {
99
+ const create = () => createIDByName(idName);
100
+ const is = (id) => isID(idName, id);
101
+ const validateOrThrow = (id) => {
102
+ if (!is(id)) {
103
+ throw new Error(`Invalid id: ${id}`);
104
+ }
105
+ return id;
106
+ };
107
+ const name = idName;
108
+ const validateOrCreate = (id) => {
109
+ return is(id) ? id : create();
110
+ };
111
+ const a = createDummyID(idName, "a");
112
+ const b = createDummyID(idName, "b");
113
+ const c = createDummyID(idName, "c");
114
+ const d = createDummyID(idName, "d");
115
+ const e = createDummyID(idName, "e");
116
+ const f = createDummyID(idName, "f");
117
+ const g = createDummyID(idName, "g");
118
+ const h = createDummyID(idName, "h");
119
+ const i = createDummyID(idName, "i");
120
+ const j = createDummyID(idName, "j");
121
+ const list = [a, b, c, d, e, f, g, h, i, j];
122
+ const dummy = {
123
+ a,
124
+ b,
125
+ c,
126
+ d,
127
+ e,
128
+ f,
129
+ g,
130
+ h,
131
+ i,
132
+ j,
133
+ list
134
+ };
135
+ return Object.freeze({ create, is, validateOrCreate, validateOrThrow, name, dummy });
136
+ };
137
+ var SchemaID = createTypedIdSingleton("SCHEMA");
138
+ var PageID = createTypedIdSingleton("PAGE");
139
+ var TagID = createTypedIdSingleton("TAG");
140
+ var OptionID = createTypedIdSingleton("OPTION");
141
+ var TextID = createTypedIdSingleton("TEXT");
142
+ var QuestionID = createTypedIdSingleton("QUESTION");
143
+ var SumScoreVariableID = createTypedIdSingleton("SUM_SCORE_VARIABLE");
144
+
145
+ // src/Builder-option.ts
146
+ var BuilderOption = class _BuilderOption extends BuilderObject {
147
+ objectType = "builder-question-option";
148
+ id;
149
+ value;
150
+ label = "";
151
+ _labelAudioFile = false;
152
+ get labelAudioFile() {
153
+ return this._labelAudioFile;
154
+ }
155
+ set labelAudioFile(audioFile) {
156
+ this._labelAudioFile = audioFile;
157
+ }
158
+ constructor(dto) {
159
+ super(dto);
160
+ this.id = dto.id;
161
+ this.value = dto.value;
162
+ this.label = dto.label;
163
+ }
164
+ static create(value, label) {
165
+ const id = OptionID.create();
166
+ const dto = {
167
+ id,
168
+ value,
169
+ label
170
+ };
171
+ const instance = new _BuilderOption(dto);
172
+ return instance;
173
+ }
174
+ static fromJson(dto) {
175
+ const instance = new _BuilderOption(dto);
176
+ return instance;
177
+ }
178
+ toJson() {
179
+ const dto = {
180
+ id: this.id,
181
+ value: this.value,
182
+ label: this.label
183
+ };
184
+ return dto;
185
+ }
186
+ clone() {
187
+ const dto = this.toJson();
188
+ const cloneDto = { ...dto, id: OptionID.create() };
189
+ return cloneDto;
190
+ }
191
+ };
192
+
193
+ // src/Builder-question.ts
194
+ var BuilderQuestion = class _BuilderQuestion extends BuilderObject {
195
+ objectType = "builder-question";
196
+ id;
197
+ type;
198
+ questionText = "";
199
+ options = [];
200
+ prefix = "";
201
+ static create = (type) => {
202
+ const id = QuestionID.create();
203
+ return new _BuilderQuestion({
204
+ id,
205
+ _type: type,
206
+ text: "",
207
+ options: [],
208
+ prefix: ""
209
+ });
210
+ };
211
+ static fromJson(dto) {
212
+ const question = new _BuilderQuestion(dto);
213
+ return question;
214
+ }
215
+ constructor(dto) {
216
+ super(dto);
217
+ this.id = QuestionID.validateOrCreate(dto.id);
218
+ this.type = dto._type;
219
+ this.questionText = dto.text;
220
+ this.prefix = dto.prefix;
221
+ this.options = dto.options.map((o) => BuilderOption.fromJson(o));
222
+ }
223
+ addOption(label, value, atIndex = -1) {
224
+ const option = BuilderOption.create(value, label);
225
+ if (atIndex >= 0 && atIndex < this.options.length) {
226
+ this.options.splice(atIndex, 0, option);
227
+ } else {
228
+ this.options.push(option);
229
+ }
230
+ return option;
231
+ }
232
+ deleteOption(option) {
233
+ const filtered = this.options.filter((o) => o.id !== option.id);
234
+ const didDelete = filtered.length === this.options.length - 1;
235
+ this.options = filtered;
236
+ return didDelete;
237
+ }
238
+ toJson() {
239
+ const optionsJson = this.options.map((o) => o.toJson());
240
+ const dto = {
241
+ id: this.id,
242
+ prefix: this.prefix,
243
+ _type: this.type,
244
+ text: this.questionText,
245
+ options: optionsJson
246
+ };
247
+ return dto;
248
+ }
249
+ clone() {
250
+ const cloneId = QuestionID.create();
251
+ const dto = this.toJson();
252
+ const optionsClone = this.options.map((o) => o.clone());
253
+ const clonedDto = {
254
+ ...dto,
255
+ id: cloneId,
256
+ options: optionsClone
257
+ };
258
+ return clonedDto;
259
+ }
260
+ };
261
+
262
+ // src/BuilderMainText.ts
263
+ var BuilderMainText = class _BuilderMainText extends BuilderObject {
264
+ objectType = "builder-main-text";
265
+ autoplay = false;
266
+ _audioFile = false;
267
+ autoplayDelay = 0;
268
+ text = "";
269
+ constructor(dto) {
270
+ super(dto);
271
+ this._audioFile = dto.audioFile ?? false;
272
+ this.autoplay = dto.autoplay ?? false;
273
+ this.autoplayDelay = dto.autoplayDelay ?? 0;
274
+ this.text = dto.text ?? "";
275
+ }
276
+ get autoplayDelayInSeconds() {
277
+ const delay = this.autoplayDelay;
278
+ const s = delay / 1e3;
279
+ const formatted = s.toFixed(1);
280
+ return formatted;
281
+ }
282
+ get durationTag() {
283
+ if (!this.audioFile)
284
+ return "";
285
+ const dur = this.audioFile.duration.toFixed(1);
286
+ return "dur " + dur + " s";
287
+ }
288
+ static fromJson(dto) {
289
+ const mainText = new _BuilderMainText(dto);
290
+ return mainText;
291
+ }
292
+ static create = () => {
293
+ const dto = {
294
+ autoplay: false,
295
+ autoplayDelay: 0,
296
+ audioFile: false,
297
+ text: ""
298
+ };
299
+ return new _BuilderMainText(dto);
300
+ };
301
+ clone() {
302
+ const dto = this.toJson();
303
+ const clone = JSON.parse(JSON.stringify(dto));
304
+ return clone;
305
+ }
306
+ toJson() {
307
+ const dto = {
308
+ text: this.text,
309
+ audioFile: this.audioFile,
310
+ autoplay: this.autoplay,
311
+ autoplayDelay: this.autoplayDelay
312
+ };
313
+ return dto;
314
+ }
315
+ get audioFile() {
316
+ return this._audioFile;
317
+ }
318
+ set audioFile(audioFile) {
319
+ if (audioFile === false) {
320
+ this.autoplayDelay = 0;
321
+ this.autoplay = false;
322
+ }
323
+ this._audioFile = audioFile;
324
+ }
325
+ };
326
+
327
+ // src/rulebuilder/condition/Builder-operator.ts
328
+ var BuilderOperatorSymbols = {
329
+ equal: true,
330
+ notEqual: true,
331
+ lessThan: true,
332
+ lessThanOrEqual: true,
333
+ greaterThan: true,
334
+ greaterThanOrEqual: true,
335
+ between: true,
336
+ notBetween: true,
337
+ in: true,
338
+ notIn: true,
339
+ missing: true,
340
+ notMissing: true,
341
+ contains: true,
342
+ notContains: true,
343
+ empty: true,
344
+ notEmpty: true,
345
+ startsWith: true,
346
+ endsWith: true
347
+ };
348
+ var BuilderOperator;
349
+ ((BuilderOperator2) => {
350
+ BuilderOperator2.is = (symbol) => {
351
+ if (typeof symbol !== "string") {
352
+ return false;
353
+ }
354
+ return Object.keys(BuilderOperatorSymbols).includes(symbol);
355
+ };
356
+ })(BuilderOperator || (BuilderOperator = {}));
357
+
358
+ // src/rulebuilder/SingleSelectItem.ts
359
+ var SingleSelectItem = class {
360
+ constructor(data) {
361
+ this.data = data;
362
+ this._selectLabel = this.getSelectLabel();
363
+ this._toolTip = this.getTooltip();
364
+ this._searchString = this.getSearchString();
365
+ }
366
+ _selectLabel;
367
+ _toolTip;
368
+ _searchString;
369
+ get selectLabel() {
370
+ return this._selectLabel;
371
+ }
372
+ get tooltip() {
373
+ return this._toolTip;
374
+ }
375
+ get searchString() {
376
+ return this._searchString;
377
+ }
378
+ };
379
+ var RuleVariableSelectItem = class _RuleVariableSelectItem extends SingleSelectItem {
380
+ constructor(data) {
381
+ super(data);
382
+ this.data = data;
383
+ this.options = data.options.map(RuleOptionSelectItem.create);
384
+ }
385
+ static create = (data) => {
386
+ return new _RuleVariableSelectItem(data);
387
+ };
388
+ options;
389
+ getSearchString() {
390
+ return this.data.varId + this.data.label;
391
+ }
392
+ getSelectLabel() {
393
+ return this.data.varId;
394
+ }
395
+ getTooltip() {
396
+ return this.data.label;
397
+ }
398
+ };
399
+ var RuleOptionSelectItem = class _RuleOptionSelectItem extends SingleSelectItem {
400
+ static create = (option) => {
401
+ return new _RuleOptionSelectItem(option);
402
+ };
403
+ constructor(option) {
404
+ super(option);
405
+ }
406
+ getSearchString() {
407
+ return "";
408
+ }
409
+ getSelectLabel() {
410
+ return this.data.label + "(" + this.data.value + ")";
411
+ }
412
+ getTooltip() {
413
+ return "";
414
+ }
415
+ };
416
+ var OperatorSelectItem = class _OperatorSelectItem extends SingleSelectItem {
417
+ static EQ = new _OperatorSelectItem("equal");
418
+ static NOT_EQ = new _OperatorSelectItem("notEqual");
419
+ static fromSymbol = (symbol) => {
420
+ if (symbol === "equal") {
421
+ return _OperatorSelectItem.EQ;
422
+ }
423
+ if (symbol === "notEqual") {
424
+ return _OperatorSelectItem.NOT_EQ;
425
+ }
426
+ return false;
427
+ };
428
+ constructor(operator) {
429
+ super(operator);
430
+ }
431
+ getSearchString() {
432
+ return "";
433
+ }
434
+ getSelectLabel() {
435
+ const operator = this.data;
436
+ if (operator === "equal") {
437
+ return "Equals";
438
+ }
439
+ if (operator === "notEqual") {
440
+ return "Not equals";
441
+ }
442
+ return "";
443
+ }
444
+ getTooltip() {
445
+ const operator = this.data;
446
+ if (operator === "equal") {
447
+ return "Equals";
448
+ }
449
+ if (operator === "notEqual") {
450
+ return "Not equals";
451
+ }
452
+ return "";
453
+ }
454
+ };
455
+ var JumpToPageSelectItem = class _JumpToPageSelectItem extends SingleSelectItem {
456
+ static create = (pageData) => new _JumpToPageSelectItem(pageData);
457
+ constructor(pageData) {
458
+ super(pageData);
459
+ }
460
+ getSearchString() {
461
+ return this.data.pagePrefix + this.data.mainText;
462
+ }
463
+ getSelectLabel() {
464
+ return this.data.pagePrefix + " (" + this.data.pageNumber + ")";
465
+ }
466
+ getTooltip() {
467
+ return this.data.mainText;
468
+ }
469
+ };
470
+
471
+ // src/rulebuilder/condition/Builder-condition.ts
472
+ var BuilderCondition = class _BuilderCondition extends BuilderObject {
473
+ objectType = "builder-condition";
474
+ static NUMBER_OPERATORS = [
475
+ OperatorSelectItem.EQ,
476
+ OperatorSelectItem.NOT_EQ
477
+ ];
478
+ initialDto;
479
+ name = "";
480
+ static create = (variableList) => {
481
+ const condition = new _BuilderCondition(
482
+ {
483
+ kind: "condition",
484
+ name: "",
485
+ operator: "",
486
+ variableId: "",
487
+ value: ""
488
+ },
489
+ variableList
490
+ );
491
+ return condition;
492
+ };
493
+ static fromDto = (dto, variables) => {
494
+ const _dto = {
495
+ kind: "condition",
496
+ name: dto.name ?? "",
497
+ value: dto.value ?? "",
498
+ operator: dto.operator ?? "",
499
+ variableId: dto.variableId ?? ""
500
+ };
501
+ const instance = new _BuilderCondition(_dto, variables);
502
+ return instance;
503
+ };
504
+ _variable = false;
505
+ _operator = "";
506
+ _value = false;
507
+ _variableList = [];
508
+ /**
509
+ * Can only set variables that exist in variableList.
510
+ * @param variable
511
+ */
512
+ set variable(variable) {
513
+ if (variable === this._variable) {
514
+ return;
515
+ }
516
+ this._variable = variable;
517
+ this._operator = "";
518
+ this._value = false;
519
+ }
520
+ get variable() {
521
+ return this._variable;
522
+ }
523
+ set value(variableValue) {
524
+ this._value = variableValue;
525
+ }
526
+ get value() {
527
+ return this._value;
528
+ }
529
+ validate() {
530
+ if (this._variableList.length === 0) {
531
+ return {
532
+ isValid: false,
533
+ message: "Has no variableList to check dto against."
534
+ };
535
+ }
536
+ if (!this._variable) {
537
+ return {
538
+ isValid: false,
539
+ message: "Variable has not been initialized from variableList."
540
+ };
541
+ }
542
+ if (!this._operator) {
543
+ return { isValid: false, message: "Operator has not been initialized" };
544
+ }
545
+ if (!this._value) {
546
+ return {
547
+ isValid: false,
548
+ message: "Value (RuleVariableOption) is not initialized"
549
+ };
550
+ }
551
+ return { isValid: true };
552
+ }
553
+ toEngineCondition() {
554
+ const val = this.value;
555
+ const op = this._operator;
556
+ const v = this._variable;
557
+ if (!val)
558
+ return false;
559
+ if (!op)
560
+ return false;
561
+ if (!v)
562
+ return false;
563
+ if (op === "equal") {
564
+ const engineCondition = {
565
+ kind: "numeric-condition",
566
+ value: val.value,
567
+ valueLabel: val.label,
568
+ referenceId: v.varId,
569
+ referenceLabel: v.label,
570
+ operator: "eq"
571
+ };
572
+ return engineCondition;
573
+ }
574
+ return false;
575
+ }
576
+ findVariableInUniverse(variableId) {
577
+ const v = this._variableList.find((v2) => v2.varId === variableId);
578
+ return v ?? false;
579
+ }
580
+ set operator(operator) {
581
+ if (BuilderOperator.is(operator)) {
582
+ this._operator = operator;
583
+ } else {
584
+ this._operator = "";
585
+ }
586
+ }
587
+ get operator() {
588
+ return this._operator;
589
+ }
590
+ constructor(dto, variables) {
591
+ super(dto);
592
+ this.initialDto = dto;
593
+ this.name = dto.name;
594
+ this._setVariableList(variables);
595
+ }
596
+ get variableSelectItemsInUniverse() {
597
+ return this._variableList.map(RuleVariableSelectItem.create);
598
+ }
599
+ get operatorsSelectItems() {
600
+ return this._variable ? _BuilderCondition.NUMBER_OPERATORS : [];
601
+ }
602
+ get selectValueItems() {
603
+ if (!this._variable) {
604
+ return [];
605
+ }
606
+ const opt = this._variable.options.map(RuleOptionSelectItem.create);
607
+ return opt;
608
+ }
609
+ clone() {
610
+ return this.toJson();
611
+ }
612
+ _setVariableList(variables) {
613
+ this._variableList = variables;
614
+ const v = this._variableList.find((v2) => v2.varId === this.originalDto.variableId);
615
+ if (!v) {
616
+ this._variable = false;
617
+ this._operator = "";
618
+ this._value = false;
619
+ return false;
620
+ }
621
+ this._variable = v;
622
+ const op = this.originalDto.operator;
623
+ if (!BuilderOperator.is(op)) {
624
+ return false;
625
+ }
626
+ this._operator = op;
627
+ const maybeOption = v.options.find((op2) => op2.value === this.originalDto.value);
628
+ if (!maybeOption) {
629
+ return false;
630
+ }
631
+ this._value = maybeOption;
632
+ return true;
633
+ }
634
+ toJson() {
635
+ const name = this.name;
636
+ const variableId = this._variable ? this._variable.varId : "";
637
+ const operator = this._operator ? this._operator : "";
638
+ const value = this._value ? this._value.value : "";
639
+ return {
640
+ kind: "condition",
641
+ name,
642
+ operator,
643
+ variableId,
644
+ value
645
+ };
646
+ }
647
+ };
648
+
649
+ // src/rulebuilder/condition/Builder-condition-group.ts
650
+ var ConditionGroupType = {
651
+ all: true,
652
+ any: true,
653
+ count: true
654
+ };
655
+ var BuilderConditionGroup = class _BuilderConditionGroup extends BuilderObject {
656
+ static isConditionGroupType = (value) => {
657
+ if (typeof value !== "string") {
658
+ return false;
659
+ }
660
+ const validValues = Object.keys(ConditionGroupType);
661
+ return validValues.includes(value);
662
+ };
663
+ objectType = "builder-condition-group";
664
+ _type;
665
+ name = "";
666
+ _conditions;
667
+ _variableList;
668
+ static fromDto = (dto, variableList) => {
669
+ return new _BuilderConditionGroup(dto, variableList);
670
+ };
671
+ constructor(dto, variableList) {
672
+ super(dto);
673
+ this.name = dto.name;
674
+ this._type = dto.type;
675
+ const conditionList = Array.isArray(dto.conditions) ? dto.conditions : [];
676
+ this._conditions = conditionList.map((dto2) => BuilderCondition.fromDto(dto2, variableList));
677
+ this._variableList = variableList;
678
+ }
679
+ get conditions() {
680
+ return this._conditions;
681
+ }
682
+ get conditionCount() {
683
+ return this._conditions.length;
684
+ }
685
+ addCondition() {
686
+ const newConditions = BuilderCondition.create(this._variableList);
687
+ this._conditions.push(newConditions);
688
+ return newConditions;
689
+ }
690
+ removeCondition(condition) {
691
+ const index = this._conditions.indexOf(condition);
692
+ if (index < 0) {
693
+ return false;
694
+ }
695
+ this._conditions.splice(index, 1);
696
+ return true;
697
+ }
698
+ clone() {
699
+ return this.toJson();
700
+ }
701
+ toJson() {
702
+ const conditions = [
703
+ ...this._conditions.map((c) => c.toJson())
704
+ ];
705
+ return {
706
+ name: this.name,
707
+ conditions,
708
+ type: this._type,
709
+ kind: "condition-group"
710
+ };
711
+ }
712
+ toEngineConditionComplex() {
713
+ const comp = {
714
+ kind: "complex-condition",
715
+ all: [],
716
+ some: [],
717
+ name: ""
718
+ };
719
+ const conditions = [];
720
+ this.conditions.forEach((c) => {
721
+ const maybeSimple = c.toEngineCondition();
722
+ if (maybeSimple) {
723
+ conditions.push(maybeSimple);
724
+ }
725
+ });
726
+ if (this._type === "all") {
727
+ return { ...comp, all: conditions };
728
+ }
729
+ if (this._type === "any") {
730
+ return { ...comp, some: conditions };
731
+ }
732
+ console.log("INVALID COMPLEX CONDITION. TODO IMPLEMENT range, and count.");
733
+ return false;
734
+ }
735
+ get type() {
736
+ return this._type;
737
+ }
738
+ set type(conditionGroupType) {
739
+ if (_BuilderConditionGroup.isConditionGroupType(conditionGroupType)) {
740
+ this._type = conditionGroupType;
741
+ }
742
+ }
743
+ };
744
+
745
+ // src/rulebuilder/multi-select-item.ts
746
+ var MultiSelectItem = class {
747
+ constructor(data, isSelected) {
748
+ this.data = data;
749
+ this._isSelectedInitially = isSelected;
750
+ this.isSelected = isSelected;
751
+ this._searchString = this.getSearchString();
752
+ this._toolTip = this.getTooltip();
753
+ this._selectLabel = this.getSelectLabel();
754
+ }
755
+ _isSelectedInitially;
756
+ _selectLabel;
757
+ _toolTip;
758
+ _searchString;
759
+ isSelected;
760
+ get selectLabel() {
761
+ return this._selectLabel;
762
+ }
763
+ get tooltip() {
764
+ return this._toolTip;
765
+ }
766
+ get searchString() {
767
+ return this._searchString;
768
+ }
769
+ };
770
+ var ExcludeByTagSelectItem = class _ExcludeByTagSelectItem extends MultiSelectItem {
771
+ static create = (tagData, isSelected) => {
772
+ return new _ExcludeByTagSelectItem(tagData, isSelected);
773
+ };
774
+ constructor(data, isSelected) {
775
+ super(data, isSelected);
776
+ }
777
+ getSearchString() {
778
+ return this.data.tag;
779
+ }
780
+ getSelectLabel() {
781
+ return this.data.tag + " (" + this.data.pageCount + ")";
782
+ }
783
+ getTooltip() {
784
+ return this.data.tag + " (used in " + this.data.pageCount + " pages)";
785
+ }
786
+ };
787
+ var ExcludeByPageIdSelectItem = class _ExcludeByPageIdSelectItem extends MultiSelectItem {
788
+ static create = (ruleActionPage, isSelected) => {
789
+ return new _ExcludeByPageIdSelectItem(ruleActionPage, isSelected);
790
+ };
791
+ constructor(data, isSelected) {
792
+ super(data, isSelected);
793
+ }
794
+ getSearchString() {
795
+ return this.data.pagePrefix + this.data.mainText;
796
+ }
797
+ getSelectLabel() {
798
+ return this.data.pagePrefix + " (" + this.data.pageNumber + ")";
799
+ }
800
+ getTooltip() {
801
+ return this.data.mainText;
802
+ }
803
+ };
804
+
805
+ // src/rulebuilder/tag-action-manager.ts
806
+ var TagActionManager = class {
807
+ constructor(validOptions, initialSelection) {
808
+ this.validOptions = validOptions;
809
+ this.initialSelection = initialSelection;
810
+ this._initialSelection = /* @__PURE__ */ new Set([...initialSelection]);
811
+ this.selectItems = validOptions.map((opt) => {
812
+ const isSelected = this._initialSelection.has(opt.tag);
813
+ return ExcludeByTagSelectItem.create(opt, isSelected);
814
+ });
815
+ }
816
+ _initialSelection;
817
+ selectItems;
818
+ getCurrentSelection() {
819
+ const selected = this.selectItems.filter((item) => item.isSelected).map((itm) => itm.data.tag);
820
+ return selected;
821
+ }
822
+ getEngineActions() {
823
+ const selected = this.selectItems.filter((item) => item.isSelected);
824
+ const tagActions = selected.map((s) => s.data);
825
+ return [...tagActions];
826
+ }
827
+ };
828
+
829
+ // src/rulebuilder/page-action-manager.ts
830
+ var PageActionManager = class {
831
+ constructor(validOptions, initialSelection) {
832
+ this.validOptions = validOptions;
833
+ this.initialSelection = initialSelection;
834
+ this._initialSelection = /* @__PURE__ */ new Set([...initialSelection]);
835
+ this.selectItems = validOptions.map((opt) => {
836
+ const isSelected = this._initialSelection.has(opt.pageId);
837
+ return ExcludeByPageIdSelectItem.create(opt, isSelected);
838
+ });
839
+ }
840
+ _initialSelection;
841
+ selectItems;
842
+ getCurrentSelection() {
843
+ const selected = this.selectItems.filter((item) => item.isSelected).map((itm) => itm.data.pageId);
844
+ return selected;
845
+ }
846
+ getEngineAction() {
847
+ const selectItems = this.selectItems.filter((item) => item.isSelected);
848
+ const actions = selectItems.map((item) => item.data);
849
+ return [...actions];
850
+ }
851
+ };
852
+
853
+ // src/rulebuilder/jump-to-action-manager.ts
854
+ var JumpToActionManager = class {
855
+ constructor(validOptions, initialSelection) {
856
+ this.validOptions = validOptions;
857
+ this.initialSelection = initialSelection;
858
+ this.options = validOptions.map(JumpToPageSelectItem.create);
859
+ this._selected = this.findSelected(initialSelection);
860
+ }
861
+ options;
862
+ _selected;
863
+ get selected() {
864
+ return this._selected;
865
+ }
866
+ set selected(selected) {
867
+ this._selected = this.findSelected(selected);
868
+ }
869
+ getSelectedPageId() {
870
+ return this._selected ? this._selected.data.pageId : false;
871
+ }
872
+ findSelected(value) {
873
+ if (!value)
874
+ return false;
875
+ if (value instanceof JumpToPageSelectItem) {
876
+ return this.options.find((v) => v === value) || false;
877
+ }
878
+ if (typeof value === "string") {
879
+ return this.options.find((v) => v.data.pageId === value) || false;
880
+ }
881
+ return false;
882
+ }
883
+ };
884
+
885
+ // src/rulebuilder/Builder-rule.ts
886
+ var BuilderRule = class _BuilderRule extends BuilderObject {
887
+ constructor(dto, _ruleInput) {
888
+ super(dto);
889
+ this.dto = dto;
890
+ this._ruleInput = _ruleInput;
891
+ const conditionInput = this._ruleInput.getConditionInput();
892
+ this.name = dto.name ?? "";
893
+ this._type = dto.type ?? "any";
894
+ this._conditions = dto.conditions.reduce(
895
+ (acc, curr) => {
896
+ if (curr.kind === "condition") {
897
+ const condition = BuilderCondition.fromDto(curr, conditionInput);
898
+ acc.push(condition);
899
+ }
900
+ if (curr.kind === "condition-group") {
901
+ const conditionGroup = BuilderConditionGroup.fromDto(curr, conditionInput);
902
+ acc.push(conditionGroup);
903
+ }
904
+ return acc;
905
+ },
906
+ []
907
+ );
908
+ this._pageActionManager = new PageActionManager(
909
+ _ruleInput.excludeByPageIdActions,
910
+ dto.excludePages
911
+ );
912
+ this._tagActionManager = new TagActionManager(_ruleInput.excludeByTagActions, dto.excludeTags);
913
+ this.jumpToActionManager = new JumpToActionManager(
914
+ _ruleInput.jumpToPageActions,
915
+ dto.jumpToPage
916
+ );
917
+ }
918
+ objectType = "builder-rule";
919
+ _type = "all";
920
+ name = "Rule name";
921
+ // public countNumber = 1;
922
+ _conditions = [];
923
+ _tagActionManager;
924
+ _pageActionManager;
925
+ jumpToActionManager;
926
+ static fromDto = (dto, input) => {
927
+ return new _BuilderRule(dto, input);
928
+ };
929
+ get conditions() {
930
+ return this._conditions;
931
+ }
932
+ getTagActions() {
933
+ return this._tagActionManager.selectItems;
934
+ }
935
+ getValidPageActions() {
936
+ return this._pageActionManager.selectItems;
937
+ }
938
+ get conditionCount() {
939
+ return this._conditions.length;
940
+ }
941
+ set type(type) {
942
+ if (BuilderConditionGroup.isConditionGroupType(type)) {
943
+ this._type = type;
944
+ }
945
+ }
946
+ get type() {
947
+ return this._type;
948
+ }
949
+ deleteCondition(condition) {
950
+ const index = this._conditions.indexOf(condition);
951
+ if (index < 0) {
952
+ return false;
953
+ }
954
+ this._conditions.splice(index, 1);
955
+ return true;
956
+ }
957
+ addCondition() {
958
+ const condition = BuilderCondition.create(this._ruleInput.getConditionInput());
959
+ this._conditions.push(condition);
960
+ return condition;
961
+ }
962
+ addConditionGroup() {
963
+ const dto = {
964
+ kind: "condition-group",
965
+ name: "",
966
+ type: "all",
967
+ conditions: []
968
+ };
969
+ const newGroup = BuilderConditionGroup.fromDto(dto, this._ruleInput.questionVars);
970
+ this._conditions.push(newGroup);
971
+ return newGroup;
972
+ }
973
+ clone() {
974
+ return this.toJson();
975
+ }
976
+ toJson() {
977
+ const conditions = this._conditions.map((c) => c.toJson());
978
+ const excludePages = this._pageActionManager.getCurrentSelection();
979
+ const excludeTags = this._tagActionManager.getCurrentSelection();
980
+ const jumpToPage = this.jumpToActionManager.getSelectedPageId();
981
+ const dto = {
982
+ type: this._type,
983
+ name: this.name,
984
+ conditions,
985
+ excludePages,
986
+ jumpToPage,
987
+ excludeTags
988
+ };
989
+ return dto;
990
+ }
991
+ toEngineRule() {
992
+ const conditions = [];
993
+ this._conditions.forEach((c) => {
994
+ if (c) {
995
+ if (c instanceof BuilderCondition) {
996
+ const simpleCondition = c.toEngineCondition();
997
+ if (simpleCondition) {
998
+ conditions.push(simpleCondition);
999
+ }
1000
+ }
1001
+ if (c instanceof BuilderConditionGroup) {
1002
+ const complexCondition = c.toEngineConditionComplex();
1003
+ if (complexCondition)
1004
+ conditions.push(complexCondition);
1005
+ }
1006
+ }
1007
+ });
1008
+ let all = [];
1009
+ let some = [];
1010
+ if (this.type === "all") {
1011
+ all = [...conditions];
1012
+ }
1013
+ const ruleActionList = [];
1014
+ const maybeJumpToPage = this.jumpToActionManager.selected;
1015
+ if (maybeJumpToPage) {
1016
+ ruleActionList.push({ kind: "jumpToPage", pageId: maybeJumpToPage.data.pageId });
1017
+ }
1018
+ const excludePageByIdList = this._pageActionManager.getEngineAction().map((a) => a.pageId);
1019
+ if (excludePageByIdList.length) {
1020
+ ruleActionList.push({ kind: "excludeByPageId", pageIds: [...excludePageByIdList] });
1021
+ }
1022
+ const excludeTags = this._tagActionManager.getEngineActions().map((tagA) => tagA.tag);
1023
+ if (excludeTags.length) {
1024
+ ruleActionList.push({ kind: "excludeByTag", tagIds: [...excludeTags] });
1025
+ }
1026
+ const rule = {
1027
+ description: this.name,
1028
+ all,
1029
+ some,
1030
+ onFailure: [],
1031
+ onSuccess: ruleActionList
1032
+ };
1033
+ return rule;
1034
+ }
1035
+ };
1036
+
1037
+ // src/rulebuilder/RuleInput.ts
1038
+ var RuleInput = class {
1039
+ constructor(_questionVariables, _customVariables, _pageIdActions, _tagActions, _jumpActions) {
1040
+ this._questionVariables = _questionVariables;
1041
+ this._customVariables = _customVariables;
1042
+ this._pageIdActions = _pageIdActions;
1043
+ this._tagActions = _tagActions;
1044
+ this._jumpActions = _jumpActions;
1045
+ }
1046
+ get questionVars() {
1047
+ return this._questionVariables;
1048
+ }
1049
+ getConditionInput() {
1050
+ return [...this.questionVars, ...this.customVars];
1051
+ }
1052
+ getJumpToPageOptions() {
1053
+ return this._jumpActions.map(JumpToPageSelectItem.create);
1054
+ }
1055
+ get customVars() {
1056
+ return this._customVariables;
1057
+ }
1058
+ get excludeByPageIdActions() {
1059
+ return this._pageIdActions;
1060
+ }
1061
+ get excludeByTagActions() {
1062
+ return this._tagActions;
1063
+ }
1064
+ get jumpToPageActions() {
1065
+ return this._jumpActions;
1066
+ }
1067
+ };
1068
+
1069
+ // src/rulebuilder/RuleVariable.ts
1070
+ var RuleVariableOption = class {
1071
+ constructor(label, value) {
1072
+ this.label = label;
1073
+ this.value = value;
1074
+ }
1075
+ };
1076
+ var RuleQuestionVariable = class {
1077
+ constructor(varId, label, options, pageNumber) {
1078
+ this.varId = varId;
1079
+ this.label = label;
1080
+ this.options = options;
1081
+ this.pageNumber = pageNumber;
1082
+ }
1083
+ kind = "question-variable";
1084
+ };
1085
+ var RuleCustomVariable = class {
1086
+ constructor(varId, label, options) {
1087
+ this.varId = varId;
1088
+ this.label = label;
1089
+ this.options = options;
1090
+ }
1091
+ kind = "configuration-variable";
1092
+ };
1093
+
1094
+ // src/page/Builder-page.ts
1095
+ var import_engine = require("@media-quest/engine");
1096
+
1097
+ // src/primitives/schema-prefix.ts
1098
+ var SchemaPrefix = class _SchemaPrefix {
1099
+ constructor(_value) {
1100
+ this._value = _value;
1101
+ }
1102
+ static MIN_LENGTH = 1;
1103
+ static randomLen = 5;
1104
+ static MAX_LENGTH = 16;
1105
+ static fromValue = (value) => {
1106
+ return new _SchemaPrefix(value);
1107
+ };
1108
+ static fromValueOrThrow = (value) => {
1109
+ if (!_SchemaPrefix.isValid(value))
1110
+ throw new Error("Invalid prefix");
1111
+ return new _SchemaPrefix(value);
1112
+ };
1113
+ static fromString = (value) => {
1114
+ if (!_SchemaPrefix.isValid(value))
1115
+ return false;
1116
+ return new _SchemaPrefix(value);
1117
+ };
1118
+ static castOrCreateRandom = (value) => {
1119
+ const v = _SchemaPrefix.isValid(value) ? value : createRandomPrefix(_SchemaPrefix.randomLen);
1120
+ return new _SchemaPrefix(v);
1121
+ };
1122
+ static isValid = (prefix) => {
1123
+ if (typeof prefix !== "string")
1124
+ return false;
1125
+ if (prefix.length < _SchemaPrefix.MIN_LENGTH)
1126
+ return false;
1127
+ if (prefix.length > _SchemaPrefix.MAX_LENGTH)
1128
+ return false;
1129
+ return true;
1130
+ };
1131
+ get value() {
1132
+ return this._value;
1133
+ }
1134
+ get isValid() {
1135
+ return _SchemaPrefix.isValid(this._value);
1136
+ }
1137
+ set value(value) {
1138
+ const casted = value;
1139
+ if (typeof casted === "string") {
1140
+ this._value = casted;
1141
+ }
1142
+ }
1143
+ };
1144
+
1145
+ // src/primitives/page-prefix.ts
1146
+ var createRandomPrefix = (length) => {
1147
+ const letters = "abcdefghijklmnopqrstuvyz";
1148
+ const all = letters + letters.toUpperCase();
1149
+ let result = "";
1150
+ for (let i = 0; i < length; i++) {
1151
+ const char = all.charAt(Math.floor(Math.random() * all.length));
1152
+ result += char;
1153
+ }
1154
+ return result;
1155
+ };
1156
+ var PagePrefix = class _PagePrefix {
1157
+ constructor(_value) {
1158
+ this._value = _value;
1159
+ }
1160
+ static MIN_LENGTH = 1;
1161
+ static randomLen = 5;
1162
+ static MAX_LENGTH = 16;
1163
+ static create = () => {
1164
+ const v = createRandomPrefix(_PagePrefix.randomLen);
1165
+ return new _PagePrefix(v);
1166
+ };
1167
+ static fromString = (value) => {
1168
+ if (!_PagePrefix.isValid(value))
1169
+ return false;
1170
+ return new _PagePrefix(value);
1171
+ };
1172
+ static fromStringOrThrow = (value) => {
1173
+ if (!_PagePrefix.isValid(value))
1174
+ throw new Error("Invalid prefix");
1175
+ return value;
1176
+ };
1177
+ static castOrCreateRandom = (value) => {
1178
+ const v = _PagePrefix.isValid(value) ? value : createRandomPrefix(_PagePrefix.randomLen);
1179
+ return new _PagePrefix(v);
1180
+ };
1181
+ static isValid = (prefix) => {
1182
+ if (typeof prefix !== "string")
1183
+ return false;
1184
+ if (prefix.length < SchemaPrefix.MIN_LENGTH)
1185
+ return false;
1186
+ return prefix.length <= SchemaPrefix.MAX_LENGTH;
1187
+ };
1188
+ get value() {
1189
+ return this._value;
1190
+ }
1191
+ set value(value) {
1192
+ if (!_PagePrefix.isValid(value)) {
1193
+ console.log("INVALID PREFIX", value);
1194
+ } else {
1195
+ this._value = value;
1196
+ }
1197
+ }
1198
+ };
1199
+
1200
+ // src/primitives/varID.ts
1201
+ var VarID = {
1202
+ create: (schemaPrefix, pagePrefix) => {
1203
+ const varId = schemaPrefix + "_" + pagePrefix;
1204
+ return varId;
1205
+ }
1206
+ };
1207
+
1208
+ // src/page/Builder-page.ts
1209
+ var BuilderPage = class _BuilderPage extends BuilderObject {
1210
+ objectType = "builder-page";
1211
+ id;
1212
+ _pageType;
1213
+ _prefix;
1214
+ _tags;
1215
+ _backgroundColor = "#FFFFFF";
1216
+ _includedInSumScores = /* @__PURE__ */ new Map();
1217
+ mainMedia = false;
1218
+ defaultQuestion;
1219
+ mainText;
1220
+ nextButton = BuilderOption.create(-1, "Neste");
1221
+ static create(type, _prefix) {
1222
+ const id = PageID.create();
1223
+ const mainTextDto = {
1224
+ text: "",
1225
+ audioFile: false,
1226
+ autoplay: false,
1227
+ autoplayDelay: 0
1228
+ };
1229
+ const nextButtonDto = BuilderOption.create(-1, "page-next-button-text").toJson();
1230
+ const defaultQuestionDto = BuilderQuestion.create("select-one").toJson();
1231
+ const dto = {
1232
+ _type: type,
1233
+ autoplaySequence: [],
1234
+ defaultQuestion: defaultQuestionDto,
1235
+ id,
1236
+ nextButton: nextButtonDto,
1237
+ mainText: mainTextDto,
1238
+ prefix: _prefix,
1239
+ includedInSumScores: [],
1240
+ tags: []
1241
+ };
1242
+ const page = new _BuilderPage(dto);
1243
+ return page;
1244
+ }
1245
+ static fromJson(dto) {
1246
+ const page = new _BuilderPage(dto);
1247
+ return page;
1248
+ }
1249
+ constructor(dto) {
1250
+ super(dto);
1251
+ this.id = dto.id;
1252
+ this._pageType = dto._type;
1253
+ const prefixInstance = PagePrefix.castOrCreateRandom(dto.prefix);
1254
+ this._prefix = prefixInstance;
1255
+ this.mainText = BuilderMainText.fromJson(dto.mainText);
1256
+ this.nextButton = BuilderOption.fromJson(dto.nextButton);
1257
+ this.defaultQuestion = BuilderQuestion.fromJson(dto.defaultQuestion);
1258
+ const tagList = Array.isArray(dto.tags) ? dto.tags : [];
1259
+ const sumScores = Array.isArray(dto.includedInSumScores) ? dto.includedInSumScores : [];
1260
+ sumScores.forEach((item) => {
1261
+ this._includedInSumScores.set(item.sumScoreVariableId, {
1262
+ sumScoreVariableId: item.sumScoreVariableId,
1263
+ weight: item.weight,
1264
+ name: "",
1265
+ description: ""
1266
+ });
1267
+ });
1268
+ this._tags = new Set(tagList);
1269
+ if (dto.mainMedia) {
1270
+ this.mainMedia = dto.mainMedia;
1271
+ }
1272
+ }
1273
+ addTag(tag) {
1274
+ this._tags.add(tag);
1275
+ }
1276
+ deleteTag(tag) {
1277
+ this._tags.delete(tag);
1278
+ }
1279
+ set pageType(value) {
1280
+ this._pageType = value;
1281
+ }
1282
+ get includedInSumScores() {
1283
+ return [...this._includedInSumScores.values()];
1284
+ }
1285
+ getQuestionVariables(modulePrefix, pageNumber) {
1286
+ const variables = [];
1287
+ if (this._pageType === "question") {
1288
+ const pagePrefix = this.prefix;
1289
+ const varId = VarID.create(modulePrefix.value, pagePrefix);
1290
+ const label = this.mainText.text;
1291
+ const op = this.defaultQuestion.options.map((o) => {
1292
+ const label2 = o.label;
1293
+ const value = o.value;
1294
+ return new RuleVariableOption(label2, value);
1295
+ });
1296
+ const singleVar = new RuleQuestionVariable(varId, label, op, pageNumber);
1297
+ variables.push(singleVar);
1298
+ }
1299
+ return variables;
1300
+ }
1301
+ get tags() {
1302
+ return [...this._tags];
1303
+ }
1304
+ get pageType() {
1305
+ return this._pageType;
1306
+ }
1307
+ get prefix() {
1308
+ return this._prefix.value;
1309
+ }
1310
+ set prefix(value) {
1311
+ this._prefix.value = value;
1312
+ }
1313
+ /** @internal */
1314
+ sumScoreVariableSet(sumScoreVariable, weight) {
1315
+ const { id, name, description } = sumScoreVariable;
1316
+ this._includedInSumScores.set(sumScoreVariable.id, {
1317
+ sumScoreVariableId: id,
1318
+ weight,
1319
+ name,
1320
+ description
1321
+ });
1322
+ return true;
1323
+ }
1324
+ /** @internal */
1325
+ updateRelationShips(variables) {
1326
+ variables.forEach((v) => {
1327
+ const sumScoreEntry = this._includedInSumScores.get(v.id);
1328
+ if (sumScoreEntry) {
1329
+ this.sumScoreVariableSet(v, sumScoreEntry.weight);
1330
+ }
1331
+ });
1332
+ }
1333
+ toJson() {
1334
+ const mainText = this.mainText.toJson();
1335
+ const nextButton = this.nextButton.toJson();
1336
+ const mainMedia = this.mainMedia;
1337
+ const includedInSumScores = this.includedInSumScores.map(({ sumScoreVariableId, weight }) => ({
1338
+ sumScoreVariableId,
1339
+ weight
1340
+ }));
1341
+ const dto = {
1342
+ _type: this.pageType,
1343
+ mainText,
1344
+ autoplaySequence: [],
1345
+ nextButton,
1346
+ id: this.id,
1347
+ tags: [...this.tags],
1348
+ includedInSumScores,
1349
+ prefix: this._prefix.value,
1350
+ defaultQuestion: this.defaultQuestion.toJson()
1351
+ };
1352
+ if (mainMedia) {
1353
+ dto.mainMedia = mainMedia;
1354
+ }
1355
+ return dto;
1356
+ }
1357
+ clone() {
1358
+ const dto = this.toJson();
1359
+ const defaultQuestionClone = this.defaultQuestion.clone();
1360
+ const mainTextClone = JSON.parse(JSON.stringify(this.mainText));
1361
+ const newId = PageID.create();
1362
+ const clone = {
1363
+ ...dto,
1364
+ id: newId,
1365
+ defaultQuestion: defaultQuestionClone,
1366
+ mainText: mainTextClone
1367
+ };
1368
+ return clone;
1369
+ }
1370
+ get backgroundColor() {
1371
+ return this._backgroundColor;
1372
+ }
1373
+ set backgroundColor(color) {
1374
+ if (typeof color === "string") {
1375
+ this._backgroundColor = color;
1376
+ }
1377
+ }
1378
+ /**
1379
+ * @internal
1380
+ */
1381
+ _isIncludedInSumScore(sumScoreId) {
1382
+ return this._includedInSumScores.has(sumScoreId);
1383
+ }
1384
+ /**
1385
+ * @internal
1386
+ */
1387
+ sumScoreVariableDelete(sumScoreVariableID) {
1388
+ this._includedInSumScores.delete(sumScoreVariableID);
1389
+ }
1390
+ };
1391
+
1392
+ // src/theme/AbstractThemeCompiler.ts
1393
+ var AbstractThemeCompiler = class {
1394
+ constructor(theme) {
1395
+ this.theme = theme;
1396
+ }
1397
+ };
1398
+
1399
+ // src/theme/theme-utils.ts
1400
+ var ThemeUtils;
1401
+ ((ThemeUtils2) => {
1402
+ ThemeUtils2.spaceEvenlyX = (items, options = {
1403
+ startAt: 0,
1404
+ endAt: 100,
1405
+ defaultItemWidth: 5
1406
+ }) => {
1407
+ const startAt = options?.startAt ?? 0;
1408
+ const endAt = options?.endAt ?? 100;
1409
+ const range = Math.abs(endAt - startAt);
1410
+ if (items.length === 0) {
1411
+ return [];
1412
+ }
1413
+ const marginCount = items.length + 1;
1414
+ const defaultWidth = options.defaultItemWidth ?? 150 / marginCount;
1415
+ let totalWidthOfElements = items.reduce((prev, curr) => {
1416
+ const w = curr.style.w ?? defaultWidth;
1417
+ return prev + w;
1418
+ }, 0);
1419
+ let cursor = startAt;
1420
+ const rest = Math.max(range - totalWidthOfElements, 0);
1421
+ const margin = rest / marginCount;
1422
+ items.forEach((item) => {
1423
+ cursor = cursor + margin;
1424
+ const w = item.style.w ?? defaultWidth;
1425
+ const x = cursor;
1426
+ cursor = cursor + w;
1427
+ item.style.w = w;
1428
+ item.style.x = x;
1429
+ });
1430
+ return items;
1431
+ };
1432
+ ThemeUtils2.centerY = () => ({
1433
+ y: 50,
1434
+ transform: "translate(0%, 50%)"
1435
+ });
1436
+ ThemeUtils2.centerX = () => ({
1437
+ x: 50,
1438
+ transform: "translate(-50%, 0%)"
1439
+ });
1440
+ ThemeUtils2.centerXY = () => ({
1441
+ x: 50,
1442
+ y: 50,
1443
+ transform: "translate(-50%, 50%)"
1444
+ });
1445
+ })(ThemeUtils || (ThemeUtils = {}));
1446
+
1447
+ // src/theme/icon-urls.ts
1448
+ var IconUrls = {
1449
+ ispeWhitePng: "https://firebasestorage.googleapis.com/v0/b/ispe-backend-dev.appspot.com/o/public-assets%2Fispe-hvit.png?alt=media&token=f6fe628b-2d99-472d-a2ea-e062873e2e22",
1450
+ pauseSvg: "https://firebasestorage.googleapis.com/v0/b/ispe-backend-dev.appspot.com/o/public-assets%2Fpause-24px.svg?alt=media&token=47337491-bb0d-4c56-9c89-a073ce19fad4",
1451
+ pauseCircleOutlineSvg: "https://firebasestorage.googleapis.com/v0/b/ispe-backend-dev.appspot.com/o/public-assets%2Fpause_circle_outline-24px.svg?alt=media&token=133aabc8-ab9a-4eaa-9914-4f0f82c22ee2",
1452
+ pauseCircleFilledSvg: "https://firebasestorage.googleapis.com/v0/b/ispe-backend-dev.appspot.com/o/public-assets%2Fpause_circle_filled-24px.svg?alt=media&token=af3f12c3-3199-4096-8ed2-76347b9a0a0a",
1453
+ playCircleRegular: "https://firebasestorage.googleapis.com/v0/b/ispe-backend-dev.appspot.com/o/public-assets%2Fplay-circle-regular.svg?alt=media&token=0867b690-d7fd-475c-8e91-b2d7aeca54d1",
1454
+ playArrowSvg: "https://firebasestorage.googleapis.com/v0/b/ispe-backend-dev.appspot.com/o/public-assets%2Fplay_arrow-24px.svg?alt=media&token=2fa95e1f-61f7-4a18-afb3-210eabae8227",
1455
+ playCircleOutline: "https://firebasestorage.googleapis.com/v0/b/ispe-backend-dev.appspot.com/o/public-assets%2Fplay_circle_outline-24px.svg?alt=media&token=3a9f62c5-dfa2-40ef-a50e-cf1bdd2d47f2",
1456
+ stopCircleSvg: "https://firebasestorage.googleapis.com/v0/b/ispe-backend-dev.appspot.com/o/public-assets%2Fstop_circle-24px.svg?alt=media&token=8fbc8b89-29bb-49ad-ae11-b8882ba3ca77",
1457
+ stopSvg: "https://firebasestorage.googleapis.com/v0/b/ispe-backend-dev.appspot.com/o/public-assets%2Fstop-24px.svg?alt=media&token=d2cd41f1-1331-4243-9b7a-dc0f0ccd255d",
1458
+ replayCircleSvg: "https://firebasestorage.googleapis.com/v0/b/ispe-backend-dev.appspot.com/o/public-assets%2Freplay-24px.svg?alt=media&token=3c35ccf4-b467-4e81-85d6-b36ac64738ad",
1459
+ volumeOffSvg: "https://firebasestorage.googleapis.com/v0/b/ispe-backend-dev.appspot.com/o/public-assets%2Fvolume_off-24px.svg?alt=media&token=4e41cc10-9f4b-4967-b4df-ed0682e657a9",
1460
+ volumeUpSvg: "https://firebasestorage.googleapis.com/v0/b/ispe-backend-dev.appspot.com/o/public-assets%2Fvolume_up-24px.svg?alt=media&token=551bd0a6-a515-4f87-a245-da433f4833f9"
1461
+ };
1462
+
1463
+ // src/theme/IDefaultTheme.ts
1464
+ var BuilderOptionTheme;
1465
+ ((BuilderOptionTheme2) => {
1466
+ const GREEN = "#70AD47";
1467
+ const YELLOW = "#FFC000";
1468
+ const ORANGE = "#F4902C";
1469
+ const RED = "#FF0000";
1470
+ const LIGHT_BLUE = "#42719C";
1471
+ const WHITE = "#ffffff";
1472
+ const BLUE = "#2F5597";
1473
+ const BTN_WIDTH = 18.5;
1474
+ const BTN_BORDER_WIDTH = 3;
1475
+ const BTN_BORDER_RADIUS = 10;
1476
+ const BTN_BORDER_STYLE = "solid";
1477
+ const BTN_HEIGHT = 9.2;
1478
+ const BTN_SHORT_WIDTH = 13.7;
1479
+ const FONT_WEIGHT = 600;
1480
+ const FONT_SIZE = 35;
1481
+ BuilderOptionTheme2.blueButton = () => {
1482
+ const optionTheme = {
1483
+ name: "blue-button-theme",
1484
+ normal: {
1485
+ btn: {
1486
+ css: {
1487
+ backgroundColor: BLUE,
1488
+ borderColor: BLUE,
1489
+ textColor: WHITE,
1490
+ fontSize: { _unit: "px", value: FONT_SIZE },
1491
+ borderWidth: { _unit: "px", value: BTN_BORDER_WIDTH },
1492
+ borderStyle: BTN_BORDER_STYLE,
1493
+ borderRadius: { value: BTN_BORDER_RADIUS, _unit: "px" },
1494
+ padding: { _unit: "px", value: 40 },
1495
+ h: BTN_HEIGHT,
1496
+ w: BTN_WIDTH,
1497
+ x: 10,
1498
+ y: 8,
1499
+ textAlign: "center"
1500
+ },
1501
+ cssDisabled: { opacity: 0.3, cursor: "not-allowed" },
1502
+ cssEnabled: { opacity: 1, cursor: "pointer" }
1503
+ },
1504
+ divider: {},
1505
+ text1: {
1506
+ y: 50,
1507
+ transform: "translate(0%, 50%)",
1508
+ textColor: WHITE,
1509
+ fontSize: { _unit: "px", value: FONT_SIZE },
1510
+ w: 84,
1511
+ x: 8,
1512
+ fontWeight: FONT_WEIGHT,
1513
+ textAlign: "center"
1514
+ },
1515
+ text2: {}
1516
+ },
1517
+ dontKnow: {
1518
+ btn: {
1519
+ css: {
1520
+ backgroundColor: WHITE,
1521
+ borderColor: LIGHT_BLUE,
1522
+ textColor: BLUE,
1523
+ fontSize: { _unit: "px", value: FONT_SIZE },
1524
+ borderWidth: { _unit: "px", value: BTN_BORDER_WIDTH },
1525
+ borderStyle: BTN_BORDER_STYLE,
1526
+ borderRadius: { value: BTN_BORDER_RADIUS, _unit: "px" },
1527
+ padding: { _unit: "px", value: 40 },
1528
+ h: BTN_HEIGHT,
1529
+ w: BTN_SHORT_WIDTH,
1530
+ x: 10,
1531
+ y: 8,
1532
+ textAlign: "center"
1533
+ },
1534
+ cssDisabled: { opacity: 0.3, cursor: "not-allowed" },
1535
+ cssEnabled: { opacity: 1, cursor: "pointer" }
1536
+ },
1537
+ text1: {
1538
+ y: 50,
1539
+ transform: "translate(0%, 50%)",
1540
+ textColor: BLUE,
1541
+ fontSize: { _unit: "px", value: FONT_SIZE },
1542
+ w: 84,
1543
+ x: 8,
1544
+ fontWeight: FONT_WEIGHT,
1545
+ textAlign: "center"
1546
+ },
1547
+ text2: {},
1548
+ divider: {}
1549
+ }
1550
+ };
1551
+ return optionTheme;
1552
+ };
1553
+ })(BuilderOptionTheme || (BuilderOptionTheme = {}));
1554
+ var DefaultTheme = {
1555
+ name: "default-theme",
1556
+ videoPlayer: {
1557
+ playButton: {
1558
+ iconUrl: IconUrls.playCircleRegular,
1559
+ css: { w: 5, h: 5, y: 48, x: 4 },
1560
+ cssDisabled: { opacity: 0.3, cursor: "not-allowed" },
1561
+ cssEnabled: { opacity: 0.8, cursor: "pointer" }
1562
+ },
1563
+ pauseButton: {
1564
+ iconUrl: IconUrls.pauseSvg,
1565
+ css: { w: 5, h: 5, y: 48, x: 4 },
1566
+ cssDisabled: { opacity: 0.3, cursor: "not-allowed" },
1567
+ cssEnabled: { opacity: 0.8, cursor: "pointer" }
1568
+ },
1569
+ videoElement: { css: { w: 100, h: 45, y: 55, x: 0 } }
1570
+ },
1571
+ image: { style: { h: 50, w: 100, x: 0 } },
1572
+ mainText: {
1573
+ noMedia: {
1574
+ text: {
1575
+ css: {
1576
+ w: 80,
1577
+ y: 65,
1578
+ x: 10,
1579
+ textAlign: "center",
1580
+ textColor: "black",
1581
+ fontSize: { _unit: "px", value: 40 }
1582
+ },
1583
+ cssDisabled: {},
1584
+ cssEnabled: {}
1585
+ },
1586
+ audio: {
1587
+ css: {
1588
+ h: 6,
1589
+ w: 6,
1590
+ x: 4,
1591
+ y: 32,
1592
+ cursor: "pointer",
1593
+ opacity: 0.8,
1594
+ visibility: "visible"
1595
+ },
1596
+ cssDisabled: { opacity: 0.3, cursor: "not-allowed" },
1597
+ cssEnabled: { opacity: 0.8, cursor: "pointer" }
1598
+ }
1599
+ },
1600
+ withMedia: {
1601
+ text: {
1602
+ css: {
1603
+ w: 80,
1604
+ y: 27,
1605
+ x: 10,
1606
+ textAlign: "center",
1607
+ textColor: "black",
1608
+ fontSize: { _unit: "px", value: 30 }
1609
+ },
1610
+ cssDisabled: {},
1611
+ cssEnabled: {}
1612
+ },
1613
+ audio: {
1614
+ css: {
1615
+ h: 6,
1616
+ w: 6,
1617
+ x: 4,
1618
+ y: 32,
1619
+ cursor: "pointer",
1620
+ opacity: 0.8,
1621
+ visibility: "visible"
1622
+ },
1623
+ cssDisabled: { opacity: 0.3, cursor: "not-allowed" },
1624
+ cssEnabled: { opacity: 0.8, cursor: "pointer" }
1625
+ }
1626
+ }
1627
+ },
1628
+ nextButtonTheme: BuilderOptionTheme.blueButton(),
1629
+ responseButtons: BuilderOptionTheme.blueButton()
1630
+ };
1631
+
1632
+ // src/theme/default-theme-compiler.ts
1633
+ var import_engine2 = require("@media-quest/engine");
1634
+ var DefaultThemeCompiler = class extends AbstractThemeCompiler {
1635
+ name = "Ispe default theme.";
1636
+ TAG = "[ DEFAULT_THEME_COMPILER ]: ";
1637
+ constructor() {
1638
+ super(DefaultTheme);
1639
+ }
1640
+ compileRules(source) {
1641
+ const builderSchema = BuilderSchema.fromJson(source);
1642
+ const ruleInput = builderSchema.getRuleInput();
1643
+ const pageQueRules = [];
1644
+ source.rules.forEach((rule) => {
1645
+ const engineRule = BuilderRule.fromDto(rule, ruleInput).toEngineRule();
1646
+ if (!import_engine2.Rule.isEmpty(engineRule)) {
1647
+ pageQueRules.push(engineRule);
1648
+ } else {
1649
+ console.log(this.TAG, "Throws away empty rule. " + rule.type + " " + rule.name);
1650
+ }
1651
+ });
1652
+ return pageQueRules;
1653
+ }
1654
+ compile(source) {
1655
+ const pages = source.pages.map((p) => this.compilePage(p, source.prefix));
1656
+ const rules = this.compileRules(source);
1657
+ const dto = {
1658
+ backgroundColor: source.backgroundColor,
1659
+ baseHeight: source.baseHeight,
1660
+ baseWidth: source.baseWidth,
1661
+ id: source.id,
1662
+ pageSequences: [],
1663
+ pages,
1664
+ predefinedFacts: [],
1665
+ rules
1666
+ };
1667
+ return dto;
1668
+ }
1669
+ compilePage(page, modulePrefix) {
1670
+ const tags = page.tags ?? [];
1671
+ const { nextButton, mainText, id, mainMedia, _type, prefix } = page;
1672
+ const staticElements = [];
1673
+ let initialAudioTasks = [];
1674
+ let initialVideoTaskList = [];
1675
+ const newPage = {
1676
+ background: "white",
1677
+ components: [],
1678
+ staticElements,
1679
+ id,
1680
+ prefix,
1681
+ initialTasks: [],
1682
+ tags: [...tags]
1683
+ };
1684
+ if (page.mainText.audioFile) {
1685
+ const autoPlay = page.mainText.autoplay;
1686
+ const autoPlayDelay = page.mainText.autoplayDelay;
1687
+ const res = this.compileMainTextAudio(page.mainText.audioFile, autoPlay, autoPlayDelay);
1688
+ initialAudioTasks = [...res.initialTasks];
1689
+ newPage.components.push(...res.components);
1690
+ }
1691
+ if (_type === "question") {
1692
+ const variableId = modulePrefix + "_" + page.prefix;
1693
+ const { components, question } = this.compileQuestion(id, page, variableId);
1694
+ newPage.components.push(...components);
1695
+ newPage.staticElements.push(question);
1696
+ }
1697
+ if (_type === "info-page") {
1698
+ const infoText = mainText.text;
1699
+ const nextButtonComponent = this.compileButton(nextButton, {
1700
+ kind: "next-button"
1701
+ });
1702
+ const textStyle = mainMedia ? DefaultTheme.mainText.withMedia.text.css : DefaultTheme.mainText.noMedia.text.css;
1703
+ const infoTextElement = {
1704
+ innerText: infoText,
1705
+ _tag: "p",
1706
+ style: textStyle
1707
+ };
1708
+ newPage.staticElements.push(infoTextElement);
1709
+ newPage.components.push(nextButtonComponent);
1710
+ }
1711
+ if (mainMedia && mainMedia.kind === "main-image") {
1712
+ const mainImageElement = this.compileImage(mainMedia);
1713
+ newPage.staticElements.push(mainImageElement);
1714
+ }
1715
+ if (mainMedia && mainMedia.kind === "main-video") {
1716
+ const videoOutput = this.compileVideo(mainMedia);
1717
+ newPage.videoPlayer = videoOutput.videoPlayer;
1718
+ newPage.components.push(...videoOutput.components);
1719
+ initialVideoTaskList = [...videoOutput.autoPlayTasks];
1720
+ }
1721
+ newPage.initialTasks.push(...initialVideoTaskList);
1722
+ newPage.initialTasks.push(...initialAudioTasks);
1723
+ const clone = JSON.parse(JSON.stringify(newPage));
1724
+ return clone;
1725
+ }
1726
+ compileImage(image) {
1727
+ const img = {
1728
+ _tag: "img",
1729
+ style: this.theme.image.style,
1730
+ url: image.file.downloadUrl
1731
+ };
1732
+ return img;
1733
+ }
1734
+ compileMainTextAudio(audioFile, autoPlay, autoPlayDelay) {
1735
+ const t = this.theme.mainText;
1736
+ const audioId = audioFile.id;
1737
+ const iconUrl = "https://firebasestorage.googleapis.com/v0/b/ispe-backend-dev.appspot.com/o/public-assets%2Fvolume_up-24px.svg?alt=media&token=551bd0a6-a515-4f87-a245-da433f4833f9";
1738
+ const playMainTextAudio = {
1739
+ _tag: "img",
1740
+ url: iconUrl,
1741
+ style: { ...t.withMedia.audio.css }
1742
+ };
1743
+ const task = {
1744
+ audioId,
1745
+ blockAudio: false,
1746
+ blockFormInput: false,
1747
+ blockResponseButton: false,
1748
+ blockVideo: false,
1749
+ kind: "play-audio-task",
1750
+ priority: "replace-all",
1751
+ url: audioFile.downloadUrl
1752
+ };
1753
+ let initialAudioTasks = [];
1754
+ if (autoPlay) {
1755
+ const playAudioTask = { ...task, priority: "follow-queue" };
1756
+ initialAudioTasks = [playAudioTask];
1757
+ if (autoPlayDelay > 0) {
1758
+ const delayTask = {
1759
+ kind: "delay-task",
1760
+ priority: "follow-queue",
1761
+ duration: autoPlayDelay,
1762
+ blockVideo: false,
1763
+ blockAudio: false,
1764
+ blockResponseButton: false,
1765
+ blockFormInput: false
1766
+ };
1767
+ initialAudioTasks = [delayTask, playAudioTask];
1768
+ }
1769
+ }
1770
+ const playBtn = {
1771
+ el: playMainTextAudio,
1772
+ onClick: { kind: "play-audio", task }
1773
+ };
1774
+ return { components: [playBtn], initialTasks: [...initialAudioTasks] };
1775
+ }
1776
+ compileVideo(video) {
1777
+ const t = this.theme.videoPlayer;
1778
+ const mode = video.mode;
1779
+ const components = [];
1780
+ let autoPlayTasks = [];
1781
+ let autoplayVideoTask = false;
1782
+ let autoplayDelayTask = false;
1783
+ const playButtonTask = {
1784
+ kind: "play-video-task",
1785
+ url: video.file.downloadUrl,
1786
+ videoId: video.file.id,
1787
+ blockAudio: false,
1788
+ blockFormInput: false,
1789
+ blockResponseButton: false,
1790
+ loop: mode === "gif-mode",
1791
+ blockVideo: false,
1792
+ priority: "replace-all"
1793
+ };
1794
+ if (video.mode === "autoplay" || video.mode === "gif-mode") {
1795
+ autoplayVideoTask = { ...playButtonTask, priority: "follow-queue" };
1796
+ autoPlayTasks = [autoplayVideoTask];
1797
+ if (video.preDelay > 0) {
1798
+ autoplayDelayTask = {
1799
+ kind: "delay-task",
1800
+ priority: "follow-queue",
1801
+ duration: video.preDelay,
1802
+ blockVideo: false,
1803
+ blockAudio: false,
1804
+ blockResponseButton: false,
1805
+ blockFormInput: false
1806
+ };
1807
+ autoPlayTasks = [autoplayDelayTask, autoplayVideoTask];
1808
+ }
1809
+ }
1810
+ const videoPlayer = {
1811
+ playUrl: video.file.downloadUrl,
1812
+ style: { h: 45, w: 100, x: 0, y: 55 }
1813
+ };
1814
+ const playButton = {
1815
+ el: {
1816
+ _tag: "img",
1817
+ url: t.playButton.iconUrl,
1818
+ style: { ...t.playButton.css, ...t.playButton.cssEnabled }
1819
+ },
1820
+ onClick: { kind: "play-video", task: playButtonTask },
1821
+ whenVideoPlay: { visibility: "hidden" },
1822
+ whenVideoPaused: { visibility: "visible" }
1823
+ };
1824
+ const pauseBtn = {
1825
+ el: {
1826
+ _tag: "img",
1827
+ style: {
1828
+ ...t.pauseButton.css,
1829
+ visibility: "hidden",
1830
+ ...t.pauseButton.cssEnabled
1831
+ },
1832
+ url: t.pauseButton.iconUrl
1833
+ },
1834
+ onClick: { kind: "pause-video" },
1835
+ whenVideoPlay: { visibility: "visible" },
1836
+ whenVideoPaused: { visibility: "hidden" }
1837
+ };
1838
+ if (mode !== "gif-mode") {
1839
+ components.push(playButton);
1840
+ components.push(pauseBtn);
1841
+ }
1842
+ return { videoPlayer, components, autoPlayTasks: [...autoPlayTasks] };
1843
+ }
1844
+ compileQuestion(pageId, page, variableId) {
1845
+ const q = page.defaultQuestion;
1846
+ const text = page.mainText.text;
1847
+ const questionStyle = page.mainMedia ? DefaultTheme.mainText.withMedia.text.css : DefaultTheme.mainText.noMedia.text.css;
1848
+ const question = {
1849
+ _tag: "p",
1850
+ innerText: text,
1851
+ style: questionStyle
1852
+ };
1853
+ const buttons = q.options.map((o) => {
1854
+ const btns = this.compileButton(o, {
1855
+ kind: "response-button",
1856
+ questionId: variableId,
1857
+ questionText: text
1858
+ });
1859
+ return btns;
1860
+ });
1861
+ const rootElements = buttons.map((b) => b.el);
1862
+ ThemeUtils.spaceEvenlyX(rootElements);
1863
+ return { question, components: buttons };
1864
+ }
1865
+ compileButton(buttonDto, options) {
1866
+ const { id, value, label } = buttonDto;
1867
+ const onclickAction = options.kind === "response-button" ? {
1868
+ kind: "submit-fact",
1869
+ fact: {
1870
+ kind: "numeric-fact",
1871
+ label,
1872
+ value,
1873
+ referenceId: options.questionId,
1874
+ referenceLabel: options.questionText
1875
+ }
1876
+ } : { kind: "next-page" };
1877
+ const btnStyles = value === 9 ? DefaultTheme.responseButtons.dontKnow : DefaultTheme.responseButtons.normal;
1878
+ const btn = {
1879
+ _tag: "div",
1880
+ children: [
1881
+ {
1882
+ _tag: "p",
1883
+ innerText: label,
1884
+ style: btnStyles.text1
1885
+ }
1886
+ ],
1887
+ style: { ...btnStyles.btn.css, ...btnStyles.btn.cssEnabled }
1888
+ };
1889
+ if (options.kind === "next-button") {
1890
+ btn.style.x = 50;
1891
+ btn.style.y = 8;
1892
+ btn.style.transform = "translate(-50%, 0%)";
1893
+ }
1894
+ const component = {
1895
+ el: btn,
1896
+ onClick: onclickAction
1897
+ };
1898
+ return component;
1899
+ }
1900
+ };
1901
+
1902
+ // src/Builder-schema.ts
1903
+ var import_engine5 = require("@media-quest/engine");
1904
+
1905
+ // src/code-book/codebook.ts
1906
+ var fromPage = (page, sumScoreVariables, pagePosition, modulePrefix) => {
1907
+ const variables = [];
1908
+ if (page._type !== "question") {
1909
+ return [];
1910
+ }
1911
+ const options = page.defaultQuestion.options.map((o) => {
1912
+ return { value: o.value, label: o.label };
1913
+ });
1914
+ const varId = modulePrefix + "_" + page.prefix;
1915
+ const includedInSumScores = page.includedInSumScores.filter((a) => true);
1916
+ const variable = {
1917
+ kind: "codebook-question-variable",
1918
+ label: page.mainText.text,
1919
+ pageId: page.id,
1920
+ pagePrefix: page.prefix,
1921
+ options,
1922
+ modulePrefix,
1923
+ pagePosition,
1924
+ varId,
1925
+ includedInSumScores: []
1926
+ };
1927
+ variables.push(variable);
1928
+ return variables;
1929
+ };
1930
+ var getPageVariablesFromPages = (pages, sumScoreVariables, modulePrefix) => {
1931
+ const variables = [];
1932
+ pages.forEach((page, index) => {
1933
+ const pageVariables = fromPage(page, sumScoreVariables, index, modulePrefix);
1934
+ variables.push(...pageVariables);
1935
+ });
1936
+ return variables;
1937
+ };
1938
+ var fromSchema = (schema) => {
1939
+ const modulePrefix = schema.prefix;
1940
+ const sumScoreVariables = schema.sumScoreVariables ?? [];
1941
+ const pageVariables = getPageVariablesFromPages(schema.pages, sumScoreVariables, modulePrefix);
1942
+ const vs = schema.predefinedVariables;
1943
+ const predefinedVariables = vs ? [...vs] : [];
1944
+ return { pageVariables, predefinedVariables };
1945
+ };
1946
+ var _CodeBook = {
1947
+ fromSchema
1948
+ };
1949
+ var CodeBook = Object.freeze(_CodeBook);
1950
+
1951
+ // src/schema-config.ts
1952
+ var SchemaConfig = {
1953
+ fromSchema: (schema) => {
1954
+ const variables = schema.predefinedVariables ?? [];
1955
+ return {
1956
+ schemaId: schema.id,
1957
+ schemaName: schema.name,
1958
+ schemaPrefix: schema.prefix,
1959
+ variables
1960
+ };
1961
+ }
1962
+ };
1963
+
1964
+ // src/sum-score/sum-score-variable.ts
1965
+ var import_engine3 = require("@media-quest/engine");
1966
+ var SumScoreVariable = class _SumScoreVariable extends BuilderObject {
1967
+ objectType = "builder-sum-score-variable";
1968
+ id;
1969
+ _useAvg = true;
1970
+ _name = "";
1971
+ _description = "";
1972
+ _error = "";
1973
+ _usedIn = [];
1974
+ // private _basedOn = new Map<pageId: Page>()
1975
+ get usedIn() {
1976
+ return [...this._usedIn];
1977
+ }
1978
+ // private _basedOn: Array<{ varId: string }> = [];
1979
+ static create = (data) => {
1980
+ const id = SumScoreVariableID.create();
1981
+ return new _SumScoreVariable({ id, ...data });
1982
+ };
1983
+ get hasErrors() {
1984
+ return this._error.length !== 0;
1985
+ }
1986
+ static fromDto = (dto) => {
1987
+ return new _SumScoreVariable(dto);
1988
+ };
1989
+ constructor(dto) {
1990
+ super(dto);
1991
+ this.id = dto.id;
1992
+ this._name = dto.name;
1993
+ this._useAvg = dto.useAvg;
1994
+ this._description = dto.description;
1995
+ }
1996
+ toJson() {
1997
+ const dto = {
1998
+ description: this.description,
1999
+ id: this.id,
2000
+ name: this.name,
2001
+ useAvg: this.useAvg
2002
+ };
2003
+ return dto;
2004
+ }
2005
+ clone() {
2006
+ const id = SumScoreVariableID.create();
2007
+ const dto = this.toJson();
2008
+ return { ...dto, id };
2009
+ }
2010
+ /** @internal*/
2011
+ _update(data) {
2012
+ const d = data ?? {};
2013
+ if (import_engine3.DUtil.isString(d.name)) {
2014
+ this._name = d.name;
2015
+ }
2016
+ if (import_engine3.DUtil.isString(d.description)) {
2017
+ this._description = d.description;
2018
+ }
2019
+ if (import_engine3.DUtil.isBool(d.useAvg)) {
2020
+ this._useAvg = d.useAvg;
2021
+ }
2022
+ }
2023
+ /**
2024
+ * @internal - used by sum-score-variable-collection.
2025
+ */
2026
+ _setError(error) {
2027
+ this._error = error;
2028
+ }
2029
+ /** @internal - used by sum-score-variable-collection */
2030
+ _setUsedInPages(pages) {
2031
+ this._usedIn = [...pages];
2032
+ }
2033
+ get name() {
2034
+ return this._name;
2035
+ }
2036
+ get description() {
2037
+ return this._description;
2038
+ }
2039
+ get useAvg() {
2040
+ return this._useAvg;
2041
+ }
2042
+ };
2043
+
2044
+ // src/sum-score/sum-score-variable-collection.ts
2045
+ var SumScoreVariableCollection = class _SumScoreVariableCollection {
2046
+ _all = [];
2047
+ [Symbol.iterator]() {
2048
+ const list = [...this._all];
2049
+ return list[Symbol.iterator]();
2050
+ }
2051
+ asArray() {
2052
+ return [...this._all];
2053
+ }
2054
+ static create = (variables) => {
2055
+ return new _SumScoreVariableCollection(variables);
2056
+ };
2057
+ constructor(sumScoreVariables) {
2058
+ const all = Array.isArray(sumScoreVariables) ? sumScoreVariables : [];
2059
+ this._all = all.map((dto) => SumScoreVariable.fromDto(dto));
2060
+ this.checkForErrors();
2061
+ }
2062
+ init(variables) {
2063
+ this._all = variables.map((variable) => SumScoreVariable.fromDto(variable));
2064
+ this.checkForErrors();
2065
+ }
2066
+ addNew(options) {
2067
+ const newVariable = SumScoreVariable.create({ ...options });
2068
+ this._all.push(newVariable);
2069
+ this.checkForErrors();
2070
+ return newVariable;
2071
+ }
2072
+ get size() {
2073
+ return this._all.length;
2074
+ }
2075
+ get errorsCount() {
2076
+ return this._all.filter((variable) => variable.hasErrors).length;
2077
+ }
2078
+ toJson() {
2079
+ return this._all.map((item) => item.toJson());
2080
+ }
2081
+ /**
2082
+ *
2083
+ */
2084
+ _deleteVariable(id) {
2085
+ const initialSize = this._all.length;
2086
+ this._all = this._all.filter((variable) => variable.id !== id);
2087
+ this.checkForErrors();
2088
+ return initialSize === this.size + 1;
2089
+ }
2090
+ /**
2091
+ * @internal
2092
+ */
2093
+ _updateOne(id, updates) {
2094
+ const variable = this._all.find((variable2) => variable2.id === id);
2095
+ if (variable) {
2096
+ variable._update(updates);
2097
+ this.checkForErrors();
2098
+ return true;
2099
+ } else {
2100
+ return false;
2101
+ }
2102
+ }
2103
+ /** @internal */
2104
+ _getVariableById(id) {
2105
+ return this._all.find((variable) => variable.id === id);
2106
+ }
2107
+ checkForErrors() {
2108
+ const nameMap = /* @__PURE__ */ new Map();
2109
+ this._all.forEach((v) => {
2110
+ const array = nameMap.get(v.name) ?? [];
2111
+ array.push(v);
2112
+ nameMap.set(v.name, array);
2113
+ });
2114
+ nameMap.forEach((sameNameArray) => {
2115
+ sameNameArray.forEach((sameNameItem) => {
2116
+ if (sameNameArray.length > 1) {
2117
+ sameNameItem._setError("Duplicate name");
2118
+ } else {
2119
+ sameNameItem._setError("");
2120
+ }
2121
+ });
2122
+ });
2123
+ }
2124
+ };
2125
+
2126
+ // src/tag/BuilderTag.ts
2127
+ var BuilderTag = class _BuilderTag extends BuilderObject {
2128
+ objectType = "builder-tag";
2129
+ id;
2130
+ tagText = "";
2131
+ tagDescription = "";
2132
+ static MAX_LENGTH = 20;
2133
+ static MIN_LENGTH = 1;
2134
+ static create = (tag, description = "") => {
2135
+ const id = TagID.create();
2136
+ const dto = {
2137
+ id,
2138
+ tag,
2139
+ description
2140
+ };
2141
+ return new _BuilderTag(dto);
2142
+ };
2143
+ static fromDto = (dto) => {
2144
+ return new _BuilderTag(dto);
2145
+ };
2146
+ constructor(dto) {
2147
+ const id = TagID.validateOrCreate(dto.id);
2148
+ const withId = { ...dto, id };
2149
+ super(withId);
2150
+ this.id = id;
2151
+ this.tagText = dto.tag ?? "";
2152
+ this.tagDescription = dto.description ?? "";
2153
+ }
2154
+ clone() {
2155
+ return this.toJson();
2156
+ }
2157
+ toJson() {
2158
+ return { tag: this.tagText, description: this.tagDescription, id: this.id };
2159
+ }
2160
+ };
2161
+
2162
+ // src/tag/Tag-Collection.ts
2163
+ var TagCollection = class _TagCollection {
2164
+ _tags = /* @__PURE__ */ new Set();
2165
+ static create = () => {
2166
+ return new _TagCollection([]);
2167
+ };
2168
+ [Symbol.iterator]() {
2169
+ const list = [...this._tags];
2170
+ return list[Symbol.iterator]();
2171
+ }
2172
+ constructor(initialTags) {
2173
+ initialTags.forEach((tag) => {
2174
+ this._tags.add(tag);
2175
+ });
2176
+ }
2177
+ init(tags) {
2178
+ const dtoList = Array.isArray(tags) ? tags : [];
2179
+ const all = dtoList.map(BuilderTag.fromDto);
2180
+ all.forEach((tag) => {
2181
+ this._tags.add(tag);
2182
+ });
2183
+ }
2184
+ add(tag) {
2185
+ this._tags.add(tag);
2186
+ }
2187
+ /**
2188
+ * Delete this tag from collection;
2189
+ * @param tag
2190
+ */
2191
+ delete(tag) {
2192
+ this._tags.delete(tag);
2193
+ }
2194
+ toJson() {
2195
+ const list = [...this._tags];
2196
+ const dtoList = list.map((t) => t.toJson());
2197
+ return dtoList;
2198
+ }
2199
+ deleteAll(tags) {
2200
+ const l = tags[Symbol.iterator]();
2201
+ const asList = [...tags];
2202
+ asList.forEach((t) => {
2203
+ this.delete(t);
2204
+ });
2205
+ }
2206
+ };
2207
+
2208
+ // src/page/Builder-page-collection.ts
2209
+ var import_engine4 = require("@media-quest/engine");
2210
+ var U = import_engine4.DUtil;
2211
+ var BuilderPageCollection = class _BuilderPageCollection {
2212
+ _all = [];
2213
+ static create(pages) {
2214
+ const page = new _BuilderPageCollection(pages);
2215
+ page._all = pages.map((p) => BuilderPage.fromJson(p));
2216
+ return page;
2217
+ }
2218
+ constructor(initialPages) {
2219
+ }
2220
+ /** @internal - used by Schema*/
2221
+ _init(pages) {
2222
+ this._all = pages.map(BuilderPage.fromJson);
2223
+ }
2224
+ add(type, atIndex = -1) {
2225
+ const pagePrefix = PagePrefix.create();
2226
+ const newPage = BuilderPage.create(type, pagePrefix.value);
2227
+ if (atIndex >= 0 && atIndex < this._all.length) {
2228
+ this._all.splice(atIndex, 0, newPage);
2229
+ } else {
2230
+ this._all.push(newPage);
2231
+ }
2232
+ return newPage;
2233
+ }
2234
+ deleteById(id) {
2235
+ const index = this._all.findIndex((p) => p.id === id);
2236
+ if (index !== -1) {
2237
+ this._all.splice(index, 1);
2238
+ return true;
2239
+ } else {
2240
+ return false;
2241
+ }
2242
+ }
2243
+ getPageById(pageId) {
2244
+ const maybePage = this._all.find((p) => p.id === pageId);
2245
+ return maybePage ?? false;
2246
+ }
2247
+ get size() {
2248
+ return this._all.length;
2249
+ }
2250
+ get pages() {
2251
+ return [...this._all];
2252
+ }
2253
+ toJson() {
2254
+ return this._all.map((p) => p.toJson());
2255
+ }
2256
+ [Symbol.iterator]() {
2257
+ const list = [...this._all];
2258
+ return list[Symbol.iterator]();
2259
+ }
2260
+ movePage(page, toIndex) {
2261
+ const index = this._all.indexOf(page);
2262
+ if (index < 0) {
2263
+ return false;
2264
+ }
2265
+ const isValidIndex = U.isInRange(0, this._all.length - 1);
2266
+ if (!isValidIndex(toIndex)) {
2267
+ return false;
2268
+ }
2269
+ this._all.splice(index, 1);
2270
+ this._all.splice(toIndex, 0, page);
2271
+ return true;
2272
+ }
2273
+ insertPage(page, atIndex) {
2274
+ const isValidIndex = U.isInRange(0, this._all.length - 1);
2275
+ if (!isValidIndex(atIndex)) {
2276
+ return false;
2277
+ }
2278
+ const exists = !!this._all.find((p) => p.id === page.id);
2279
+ if (exists) {
2280
+ return false;
2281
+ }
2282
+ this._all.splice(atIndex, 0, page);
2283
+ return true;
2284
+ }
2285
+ addSumScoreVariable(sumScoreVariable, pageId, weight) {
2286
+ const maybePage = this.getPageById(pageId);
2287
+ if (!maybePage)
2288
+ return false;
2289
+ maybePage.sumScoreVariableSet(sumScoreVariable, weight);
2290
+ return true;
2291
+ }
2292
+ updateRelationShips(context) {
2293
+ const { sumScoreVariables } = context;
2294
+ this._all.forEach((p) => {
2295
+ p.updateRelationShips(context.sumScoreVariables);
2296
+ });
2297
+ sumScoreVariables.forEach((v) => {
2298
+ const usedInPages = this._all.filter((p) => p._isIncludedInSumScore(v.id));
2299
+ v._setUsedInPages(usedInPages);
2300
+ });
2301
+ }
2302
+ sumScoreVariableDelete(sumScoreVariableID) {
2303
+ this._all.forEach((p) => {
2304
+ p.sumScoreVariableDelete(sumScoreVariableID);
2305
+ });
2306
+ }
2307
+ sumScoreVariableDeleteFromPage(pageId, sumScoreVariableId) {
2308
+ const maybePage = this.getPageById(pageId);
2309
+ if (!maybePage)
2310
+ return false;
2311
+ maybePage.sumScoreVariableDelete(sumScoreVariableId);
2312
+ return true;
2313
+ }
2314
+ };
2315
+
2316
+ // src/Builder-schema.ts
2317
+ var BuilderSchema = class _BuilderSchema {
2318
+ constructor(id, name, prefix) {
2319
+ this.id = id;
2320
+ this.name = name;
2321
+ this.prefix = prefix;
2322
+ this._sumScoreCollection = SumScoreVariableCollection.create([]);
2323
+ this._pageCollection = BuilderPageCollection.create([]);
2324
+ }
2325
+ prefix;
2326
+ baseHeight = 1300;
2327
+ baseWidth = 1024;
2328
+ backgroundColor = "#000000";
2329
+ _pageCollection;
2330
+ mainImage = false;
2331
+ predefinedVariables = [];
2332
+ _rules = [];
2333
+ _sumScoreCollection;
2334
+ get rules() {
2335
+ return [...this._rules];
2336
+ }
2337
+ get pages() {
2338
+ return [...this._pageCollection];
2339
+ }
2340
+ get sumScoreVariables() {
2341
+ return [...this._sumScoreCollection];
2342
+ }
2343
+ // get prefix(): SchemaPrefixValue {
2344
+ // return this._prefix.value;
2345
+ // }
2346
+ _tagCollection = TagCollection.create();
2347
+ get tags() {
2348
+ return [...this._tagCollection];
2349
+ }
2350
+ static create(id, name, prefix) {
2351
+ const schemaPrefix = SchemaPrefix.castOrCreateRandom(prefix);
2352
+ return new _BuilderSchema(id, name, schemaPrefix);
2353
+ }
2354
+ static fromJson(dto) {
2355
+ const schemaPrefix = SchemaPrefix.castOrCreateRandom(dto.prefix);
2356
+ const schema = new _BuilderSchema(dto.id, dto.name, schemaPrefix);
2357
+ const sumScoreVariables = dto.sumScoreVariables ? [...dto.sumScoreVariables] : [];
2358
+ const pagesDto = Array.isArray(dto.pages) ? dto.pages : [];
2359
+ schema._tagCollection.init(dto.tags);
2360
+ schema._sumScoreCollection.init(sumScoreVariables);
2361
+ schema.backgroundColor = dto.backgroundColor;
2362
+ schema.baseHeight = dto.baseHeight;
2363
+ schema.baseWidth = dto.baseWidth;
2364
+ schema._pageCollection._init(pagesDto);
2365
+ schema.predefinedVariables = dto.predefinedVariables ?? [];
2366
+ schema.backgroundColor = dto.backgroundColor;
2367
+ schema.mainImage = dto.mainImage ?? false;
2368
+ const rulesDto = dto.rules ?? [];
2369
+ const ruleInput = schema.getRuleInput();
2370
+ schema._rules = rulesDto.map((r) => BuilderRule.fromDto(r, ruleInput));
2371
+ schema.updateSumScoreRelations();
2372
+ return schema;
2373
+ }
2374
+ toJson() {
2375
+ const pages = this._pageCollection.toJson();
2376
+ const tags = this._tagCollection.toJson();
2377
+ const rules = this._rules.map((rule) => rule.toJson());
2378
+ const sumScoreVariables = this._sumScoreCollection.toJson();
2379
+ const dto = {
2380
+ backgroundColor: this.backgroundColor,
2381
+ baseHeight: this.baseHeight,
2382
+ baseWidth: this.baseWidth,
2383
+ id: this.id,
2384
+ name: this.name,
2385
+ pages,
2386
+ rules,
2387
+ tags,
2388
+ predefinedVariables: this.predefinedVariables,
2389
+ sumScoreVariables,
2390
+ mainImage: this.mainImage,
2391
+ prefix: this.prefix.value
2392
+ };
2393
+ return dto;
2394
+ }
2395
+ addPage(type, atIndex = -1) {
2396
+ return this._pageCollection.add(type, atIndex);
2397
+ }
2398
+ sumScoreVariableCreate(options) {
2399
+ const variable = this._sumScoreCollection.addNew(options);
2400
+ return variable;
2401
+ }
2402
+ sumScoreVariableAddToPage(sumScoreVariable, page, weight) {
2403
+ const added = this._pageCollection.addSumScoreVariable(sumScoreVariable, page.id, weight);
2404
+ this.updateSumScoreRelations();
2405
+ return added;
2406
+ }
2407
+ updateSumScoreRelations() {
2408
+ const sumScoreVariables = this._sumScoreCollection.asArray();
2409
+ this._pageCollection.updateRelationShips({ sumScoreVariables });
2410
+ }
2411
+ sumScoreVariableUpdate(id, data) {
2412
+ const didUpdate = this._sumScoreCollection._updateOne(id, data);
2413
+ this.updateSumScoreRelations();
2414
+ return didUpdate;
2415
+ }
2416
+ sumScoreVariableDeleteFromPage(pageId, sumScoreVariableId) {
2417
+ this._pageCollection.sumScoreVariableDeleteFromPage(pageId, sumScoreVariableId);
2418
+ this.updateSumScoreRelations();
2419
+ }
2420
+ insertPage(page, atIndex) {
2421
+ return this.insertPageAtIndex(page, atIndex);
2422
+ }
2423
+ insertPageAtIndex(page, atIndex) {
2424
+ return this._pageCollection.insertPage(page, atIndex);
2425
+ }
2426
+ addRule() {
2427
+ const input = this.getRuleInput();
2428
+ const count = this._rules.length + 1;
2429
+ const name = "Rule-number: " + count;
2430
+ const rule = BuilderRule.fromDto(
2431
+ {
2432
+ conditions: [],
2433
+ type: "all",
2434
+ name,
2435
+ excludeTags: [],
2436
+ jumpToPage: false,
2437
+ excludePages: []
2438
+ },
2439
+ input
2440
+ );
2441
+ this._rules.push(rule);
2442
+ return rule;
2443
+ }
2444
+ deleteRule(rule) {
2445
+ this._rules = this._rules.filter((r) => r !== rule);
2446
+ }
2447
+ movePage(page, toIndex) {
2448
+ return this._pageCollection.movePage(page, toIndex);
2449
+ }
2450
+ deletePage(page) {
2451
+ return this._pageCollection.deleteById(page.id);
2452
+ }
2453
+ reevaluateRules() {
2454
+ console.log("Reevaluationg rulesInput");
2455
+ const input = this.getRuleInput();
2456
+ const rulesDto = this._rules.map((r) => r.toJson());
2457
+ this._rules = rulesDto.map((dto) => BuilderRule.fromDto(dto, input));
2458
+ }
2459
+ getRuleInput() {
2460
+ const qVars = [];
2461
+ const cVars = [];
2462
+ const pageIdActions = [];
2463
+ const tagActions = this.tags.map((t) => {
2464
+ const tag = t.tagText;
2465
+ const pageCount = this._pageCollection.pages.reduce((count, curr) => {
2466
+ return curr.tags.includes(tag) ? count + 1 : count;
2467
+ }, 0);
2468
+ const excludeByTagDto = {
2469
+ kind: "exclude-by-tag",
2470
+ pageCount,
2471
+ tag,
2472
+ description: t.tagDescription
2473
+ };
2474
+ return excludeByTagDto;
2475
+ });
2476
+ const jumpActions = [];
2477
+ this._pageCollection.pages.forEach((page, index) => {
2478
+ const pageVariables = page.getQuestionVariables(this.prefix, index);
2479
+ qVars.push(...pageVariables);
2480
+ const mainText = page.mainText.text;
2481
+ const pagePrefix = page.prefix;
2482
+ const jumpAction = {
2483
+ kind: "jump-to-page",
2484
+ pageId: page.id,
2485
+ pagePrefix,
2486
+ pageNumber: index,
2487
+ mainText: page.mainText.text
2488
+ };
2489
+ const excludePageAction = {
2490
+ kind: "exclude-by-pageId",
2491
+ pageId: page.id,
2492
+ pagePrefix,
2493
+ pageNumber: index,
2494
+ mainText
2495
+ };
2496
+ jumpActions.push(jumpAction);
2497
+ pageIdActions.push(excludePageAction);
2498
+ });
2499
+ const ruleInput = new RuleInput(qVars, cVars, pageIdActions, tagActions, jumpActions);
2500
+ return ruleInput;
2501
+ }
2502
+ deleteTags(tags) {
2503
+ this._tagCollection.deleteAll(tags);
2504
+ }
2505
+ addTag(builderTag) {
2506
+ this._tagCollection.add(builderTag);
2507
+ }
2508
+ compile(options = { blockAutoplayQuestion: false, blockAutoplayVideo: false }) {
2509
+ const builderSchema = _BuilderSchema.fromJson(this.toJson());
2510
+ builderSchema._pageCollection.pages.forEach((p) => {
2511
+ if (options.blockAutoplayQuestion) {
2512
+ p.mainText.autoplay = false;
2513
+ }
2514
+ if (options.blockAutoplayVideo && p.mainMedia) {
2515
+ if (p.mainMedia.kind === "main-video") {
2516
+ p.mainMedia.mode = "optional";
2517
+ }
2518
+ }
2519
+ });
2520
+ const moduleDto = builderSchema.toJson();
2521
+ const imp = new DefaultThemeCompiler();
2522
+ const codebook = CodeBook.fromSchema(moduleDto);
2523
+ const schema = imp.compile(moduleDto);
2524
+ const schemaConfig = SchemaConfig.fromSchema(moduleDto);
2525
+ const output = { codebook, schema, schemaConfig };
2526
+ return output;
2527
+ }
2528
+ sumScoreVariableDelete(id) {
2529
+ const didDelete = this._sumScoreCollection._deleteVariable(id);
2530
+ const sumScoreVariables = [...this._sumScoreCollection];
2531
+ this._pageCollection.updateRelationShips({ sumScoreVariables });
2532
+ this._pageCollection.sumScoreVariableDelete(id);
2533
+ return didDelete;
2534
+ }
2535
+ };
2536
+
2537
+ // src/Builder-text.ts
2538
+ var BuilderText = class _BuilderText extends BuilderObject {
2539
+ objectType = "builder-text";
2540
+ id;
2541
+ text = "";
2542
+ name = "";
2543
+ translateRequired = false;
2544
+ // audio: {id: B}
2545
+ constructor(dto) {
2546
+ super(dto);
2547
+ this.id = dto.id;
2548
+ this.translateRequired = dto.translationRequired;
2549
+ this.name = dto.name;
2550
+ this.text = dto.text;
2551
+ }
2552
+ static create(name) {
2553
+ const id = TextID.create();
2554
+ const dto = {
2555
+ id,
2556
+ name,
2557
+ text: "",
2558
+ translationRequired: false
2559
+ };
2560
+ const instance = new _BuilderText(dto);
2561
+ return instance;
2562
+ }
2563
+ static fromJson(dto) {
2564
+ const instance = new _BuilderText(dto);
2565
+ return instance;
2566
+ }
2567
+ clone() {
2568
+ const dto = this.toJson();
2569
+ const withNewId = { ...dto, id: TextID.create() };
2570
+ return withNewId;
2571
+ }
2572
+ toJson() {
2573
+ const dto = {
2574
+ id: this.id,
2575
+ name: this.name,
2576
+ text: this.text,
2577
+ translationRequired: this.translateRequired
2578
+ };
2579
+ return dto;
2580
+ }
2581
+ };
2582
+
2583
+ // src/sum-score/sum-score.ts
2584
+ var ALLOWED_VALUES = [0, 1, 2, 3, 4, 5, 6, 7, 8];
2585
+ var isAllowedValue = (num) => {
2586
+ const notNegative = num >= 0;
2587
+ const lessThanNine = num < 9;
2588
+ return notNegative && lessThanNine;
2589
+ };
2590
+ var calculateAll = (schemaDto, answers) => {
2591
+ const vs = schemaDto.sumScoreVariables ?? [];
2592
+ const basedOnMap = /* @__PURE__ */ new Map();
2593
+ const codeBook = CodeBook.fromSchema(schemaDto);
2594
+ const pages = schemaDto.pages;
2595
+ pages.forEach((page) => {
2596
+ page.includedInSumScores.forEach((includedInScores) => {
2597
+ const variableId = includedInScores.sumScoreVariableId;
2598
+ const weight = includedInScores.weight;
2599
+ const p = codeBook.pageVariables.find((v) => v.pageId === page.id);
2600
+ if (p) {
2601
+ const currentBasedOnArray = basedOnMap.get(variableId) ?? [];
2602
+ currentBasedOnArray.push({ varId: p.varId, weight });
2603
+ basedOnMap.set(variableId, currentBasedOnArray);
2604
+ } else {
2605
+ console.error("INVALID DATA in calculate all sum-scores.");
2606
+ }
2607
+ });
2608
+ });
2609
+ const results = vs.map((v) => {
2610
+ const basedOn = basedOnMap.get(v.id) ?? [];
2611
+ return calculate(v, basedOn, answers);
2612
+ });
2613
+ return results;
2614
+ };
2615
+ var calculate = (sumScoreVariable, basedOnVariables, answers) => {
2616
+ const legalValues = [...ALLOWED_VALUES];
2617
+ let includedAnswerCount = 0;
2618
+ let skippedBy9Count = 0;
2619
+ let missingAnswerCount = 0;
2620
+ let sumScore = 0;
2621
+ const errorMessages = [];
2622
+ const basedOn = [];
2623
+ const useAvg = sumScoreVariable.useAvg;
2624
+ const basedOnEntries = basedOnVariables.map((scv) => {
2625
+ const maybeAnswer = answers.find((v) => v.varId === scv.varId);
2626
+ let result2 = { kind: "missing", varId: scv.varId };
2627
+ if (!maybeAnswer) {
2628
+ return result2;
2629
+ }
2630
+ const value = maybeAnswer.value;
2631
+ const varLabel = maybeAnswer.varLabel;
2632
+ const weight = scv.weight ?? 1;
2633
+ const varId = maybeAnswer.varId;
2634
+ result2 = {
2635
+ kind: "has-value",
2636
+ varId,
2637
+ weight,
2638
+ value,
2639
+ varLabel
2640
+ };
2641
+ return result2;
2642
+ });
2643
+ basedOnEntries.forEach((entry) => {
2644
+ if (entry.kind === "missing") {
2645
+ missingAnswerCount++;
2646
+ }
2647
+ if (entry.kind === "has-value") {
2648
+ const { varId, varLabel, weight, value } = { ...entry };
2649
+ const isAllowed = isAllowedValue(value);
2650
+ if (isAllowed) {
2651
+ basedOn.push({ varId, weight, value, varLabel });
2652
+ sumScore += entry.value * entry.weight;
2653
+ includedAnswerCount++;
2654
+ }
2655
+ if (value === 9) {
2656
+ skippedBy9Count++;
2657
+ basedOn.push({ varId, weight, value, varLabel });
2658
+ }
2659
+ }
2660
+ if (entry.kind === "invalid-variable") {
2661
+ errorMessages.push(entry.message);
2662
+ }
2663
+ });
2664
+ const avg = sumScore / includedAnswerCount;
2665
+ const result = {
2666
+ avg,
2667
+ useAvg,
2668
+ includedAnswerCount,
2669
+ skippedBy9Count,
2670
+ sumScore,
2671
+ basedOn,
2672
+ missingAnswerCount,
2673
+ errorMessages
2674
+ };
2675
+ return result;
2676
+ };
2677
+ var createVariable = () => {
2678
+ const id = SumScoreVariableID.create();
2679
+ return {
2680
+ id,
2681
+ name: "",
2682
+ useAvg: true,
2683
+ description: ""
2684
+ // basedOn: [],
2685
+ };
2686
+ };
2687
+ var SumScore = {
2688
+ ALLOWED_VALUES,
2689
+ calculate,
2690
+ calculateAll,
2691
+ isAllowedValue,
2692
+ createVariable
2693
+ };
2694
+ // Annotate the CommonJS export names for ESM import in node:
2695
+ 0 && (module.exports = {
2696
+ BuilderCondition,
2697
+ BuilderConditionGroup,
2698
+ BuilderMainText,
2699
+ BuilderOperator,
2700
+ BuilderOption,
2701
+ BuilderPage,
2702
+ BuilderQuestion,
2703
+ BuilderRule,
2704
+ BuilderSchema,
2705
+ BuilderTag,
2706
+ BuilderText,
2707
+ CodeBook,
2708
+ ExcludeByPageIdSelectItem,
2709
+ ExcludeByTagSelectItem,
2710
+ JumpToActionManager,
2711
+ JumpToPageSelectItem,
2712
+ MultiSelectItem,
2713
+ OperatorSelectItem,
2714
+ OptionID,
2715
+ PageActionManager,
2716
+ PageID,
2717
+ PagePrefix,
2718
+ QuestionID,
2719
+ RuleCustomVariable,
2720
+ RuleInput,
2721
+ RuleOptionSelectItem,
2722
+ RuleQuestionVariable,
2723
+ RuleVariableOption,
2724
+ RuleVariableSelectItem,
2725
+ SchemaConfig,
2726
+ SchemaID,
2727
+ SchemaPrefix,
2728
+ SingleSelectItem,
2729
+ SumScore,
2730
+ SumScoreVariable,
2731
+ SumScoreVariableID,
2732
+ TagActionManager,
2733
+ TagCollection,
2734
+ TagID,
2735
+ TextID,
2736
+ VarID,
2737
+ _CodeBook,
2738
+ createTypedIdSingleton
2739
+ });
2740
+ //# sourceMappingURL=public-api.js.map