@pie-element/image-cloze-association 8.0.1 → 8.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/configure/CHANGELOG.md +19 -0
- package/configure/package.json +3 -3
- package/controller/CHANGELOG.md +20 -0
- package/controller/lib/index.js +7 -1
- package/controller/lib/index.js.map +1 -1
- package/controller/lib/utils.js +41 -2
- package/controller/lib/utils.js.map +1 -1
- package/controller/package.json +2 -2
- package/controller/src/index.js +7 -1
- package/controller/src/utils.js +24 -0
- package/lib/index.js +44 -3
- package/lib/index.js.map +1 -1
- package/package.json +8 -25
- package/src/__tests__/index.test.js +17 -2
- package/src/index.js +40 -3
- package/esm/configure.js +0 -7714
- package/esm/configure.js.map +0 -1
- package/esm/controller.js +0 -444
- package/esm/controller.js.map +0 -1
- package/esm/element.js +0 -11333
- package/esm/element.js.map +0 -1
package/esm/controller.js
DELETED
|
@@ -1,444 +0,0 @@
|
|
|
1
|
-
import debug from 'debug';
|
|
2
|
-
import { partialScoring } from '@pie-lib/controller-utils';
|
|
3
|
-
import { shuffle, cloneDeep, isEmpty } from 'lodash';
|
|
4
|
-
|
|
5
|
-
function _defineProperty(obj, key, value) {
|
|
6
|
-
if (key in obj) {
|
|
7
|
-
Object.defineProperty(obj, key, {
|
|
8
|
-
value: value,
|
|
9
|
-
enumerable: true,
|
|
10
|
-
configurable: true,
|
|
11
|
-
writable: true
|
|
12
|
-
});
|
|
13
|
-
} else {
|
|
14
|
-
obj[key] = value;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return obj;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
21
|
-
|
|
22
|
-
var humps = {exports: {}};
|
|
23
|
-
|
|
24
|
-
(function (module) {
|
|
25
|
-
(function(global) {
|
|
26
|
-
|
|
27
|
-
var _processKeys = function(convert, obj, options) {
|
|
28
|
-
if(!_isObject(obj) || _isDate(obj) || _isRegExp(obj) || _isBoolean(obj) || _isFunction(obj)) {
|
|
29
|
-
return obj;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
var output,
|
|
33
|
-
i = 0,
|
|
34
|
-
l = 0;
|
|
35
|
-
|
|
36
|
-
if(_isArray(obj)) {
|
|
37
|
-
output = [];
|
|
38
|
-
for(l=obj.length; i<l; i++) {
|
|
39
|
-
output.push(_processKeys(convert, obj[i], options));
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
output = {};
|
|
44
|
-
for(var key in obj) {
|
|
45
|
-
if(Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
46
|
-
output[convert(key, options)] = _processKeys(convert, obj[key], options);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return output;
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
// String conversion methods
|
|
54
|
-
|
|
55
|
-
var separateWords = function(string, options) {
|
|
56
|
-
options = options || {};
|
|
57
|
-
var separator = options.separator || '_';
|
|
58
|
-
var split = options.split || /(?=[A-Z])/;
|
|
59
|
-
|
|
60
|
-
return string.split(split).join(separator);
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
var camelize = function(string) {
|
|
64
|
-
if (_isNumerical(string)) {
|
|
65
|
-
return string;
|
|
66
|
-
}
|
|
67
|
-
string = string.replace(/[\-_\s]+(.)?/g, function(match, chr) {
|
|
68
|
-
return chr ? chr.toUpperCase() : '';
|
|
69
|
-
});
|
|
70
|
-
// Ensure 1st char is always lowercase
|
|
71
|
-
return string.substr(0, 1).toLowerCase() + string.substr(1);
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
var pascalize = function(string) {
|
|
75
|
-
var camelized = camelize(string);
|
|
76
|
-
// Ensure 1st char is always uppercase
|
|
77
|
-
return camelized.substr(0, 1).toUpperCase() + camelized.substr(1);
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
var decamelize = function(string, options) {
|
|
81
|
-
return separateWords(string, options).toLowerCase();
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
// Utilities
|
|
85
|
-
// Taken from Underscore.js
|
|
86
|
-
|
|
87
|
-
var toString = Object.prototype.toString;
|
|
88
|
-
|
|
89
|
-
var _isFunction = function(obj) {
|
|
90
|
-
return typeof(obj) === 'function';
|
|
91
|
-
};
|
|
92
|
-
var _isObject = function(obj) {
|
|
93
|
-
return obj === Object(obj);
|
|
94
|
-
};
|
|
95
|
-
var _isArray = function(obj) {
|
|
96
|
-
return toString.call(obj) == '[object Array]';
|
|
97
|
-
};
|
|
98
|
-
var _isDate = function(obj) {
|
|
99
|
-
return toString.call(obj) == '[object Date]';
|
|
100
|
-
};
|
|
101
|
-
var _isRegExp = function(obj) {
|
|
102
|
-
return toString.call(obj) == '[object RegExp]';
|
|
103
|
-
};
|
|
104
|
-
var _isBoolean = function(obj) {
|
|
105
|
-
return toString.call(obj) == '[object Boolean]';
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
// Performant way to determine if obj coerces to a number
|
|
109
|
-
var _isNumerical = function(obj) {
|
|
110
|
-
obj = obj - 0;
|
|
111
|
-
return obj === obj;
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
// Sets up function which handles processing keys
|
|
115
|
-
// allowing the convert function to be modified by a callback
|
|
116
|
-
var _processor = function(convert, options) {
|
|
117
|
-
var callback = options && 'process' in options ? options.process : options;
|
|
118
|
-
|
|
119
|
-
if(typeof(callback) !== 'function') {
|
|
120
|
-
return convert;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return function(string, options) {
|
|
124
|
-
return callback(string, convert, options);
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
var humps = {
|
|
129
|
-
camelize: camelize,
|
|
130
|
-
decamelize: decamelize,
|
|
131
|
-
pascalize: pascalize,
|
|
132
|
-
depascalize: decamelize,
|
|
133
|
-
camelizeKeys: function(object, options) {
|
|
134
|
-
return _processKeys(_processor(camelize, options), object);
|
|
135
|
-
},
|
|
136
|
-
decamelizeKeys: function(object, options) {
|
|
137
|
-
return _processKeys(_processor(decamelize, options), object, options);
|
|
138
|
-
},
|
|
139
|
-
pascalizeKeys: function(object, options) {
|
|
140
|
-
return _processKeys(_processor(pascalize, options), object);
|
|
141
|
-
},
|
|
142
|
-
depascalizeKeys: function () {
|
|
143
|
-
return this.decamelizeKeys.apply(this, arguments);
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
if (module.exports) {
|
|
148
|
-
module.exports = humps;
|
|
149
|
-
} else {
|
|
150
|
-
global.humps = humps;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
})(commonjsGlobal);
|
|
154
|
-
}(humps));
|
|
155
|
-
|
|
156
|
-
var defaults = {
|
|
157
|
-
rationale: '',
|
|
158
|
-
rationaleEnabled: true,
|
|
159
|
-
studentInstructionsEnabled: true,
|
|
160
|
-
teacherInstructions: '',
|
|
161
|
-
teacherInstructionsEnabled: true
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
function ownKeys$1(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
165
|
-
|
|
166
|
-
function _objectSpread$1(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys$1(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys$1(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
167
|
-
|
|
168
|
-
// functions also used in src/utils-correctness.js
|
|
169
|
-
var getAllCorrectness = (answers, responses) => (answers || []).map(answer => _objectSpread$1(_objectSpread$1({}, answer), {}, {
|
|
170
|
-
isCorrect: (responses[answer.containerIndex] && responses[answer.containerIndex].images || []).includes(answer.value)
|
|
171
|
-
}));
|
|
172
|
-
|
|
173
|
-
var getValidAnswer = (answer, response) => (response[answer.containerIndex] && response[answer.containerIndex].images || []).filter(res => res === answer.value);
|
|
174
|
-
|
|
175
|
-
var getAllUniqueCorrectness = (answers, validResponses) => {
|
|
176
|
-
var allCorrectness = getAllCorrectness(answers, validResponses);
|
|
177
|
-
answers.forEach(answer1 => {
|
|
178
|
-
var valuesToParse = answers.filter(answer2 => answer2.value === answer1.value && answer2.containerIndex === answer1.containerIndex);
|
|
179
|
-
|
|
180
|
-
if (valuesToParse.length > 1) {
|
|
181
|
-
// point only to duplicates but first
|
|
182
|
-
valuesToParse.shift(); // mark duplicates as incorrect
|
|
183
|
-
|
|
184
|
-
valuesToParse.forEach((value, index) => {
|
|
185
|
-
allCorrectness = (allCorrectness || []).map(finalAnswer => {
|
|
186
|
-
if (finalAnswer.id === value.id) {
|
|
187
|
-
var valid = getValidAnswer(finalAnswer, validResponses);
|
|
188
|
-
return _objectSpread$1(_objectSpread$1({}, finalAnswer), {}, {
|
|
189
|
-
isCorrect: valid.length > index + 1
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
return finalAnswer;
|
|
194
|
-
});
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
});
|
|
198
|
-
return allCorrectness;
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
202
|
-
|
|
203
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
204
|
-
var log = debug('pie-elements:image-cloze-association:controller');
|
|
205
|
-
var normalize = question => _objectSpread(_objectSpread({}, defaults), question);
|
|
206
|
-
var model = (question, session, env) => {
|
|
207
|
-
var questionNormalized = normalize(question);
|
|
208
|
-
var questionCamelized = humps.exports.camelizeKeys(questionNormalized);
|
|
209
|
-
return new Promise(resolve => {
|
|
210
|
-
var shouldIncludeCorrectResponse = env.mode === 'evaluate';
|
|
211
|
-
|
|
212
|
-
var out = _objectSpread(_objectSpread({
|
|
213
|
-
disabled: env.mode !== 'gather',
|
|
214
|
-
mode: env.mode
|
|
215
|
-
}, questionCamelized), {}, {
|
|
216
|
-
responseCorrect: shouldIncludeCorrectResponse ? getScore(questionCamelized, session) === 1 : undefined,
|
|
217
|
-
validation: shouldIncludeCorrectResponse ? questionCamelized.validation : undefined
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
if (questionNormalized.shuffle) {
|
|
221
|
-
out.possibleResponses = shuffle(questionNormalized.possible_responses);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {
|
|
225
|
-
out.teacherInstructions = questionCamelized.teacherInstructionsEnabled ? questionCamelized.teacherInstructions : null;
|
|
226
|
-
out.rationale = questionCamelized.rationale ? questionCamelized.rationale : null;
|
|
227
|
-
} else {
|
|
228
|
-
out.teacherInstructions = null;
|
|
229
|
-
out.rationale = null;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
resolve(out);
|
|
233
|
-
});
|
|
234
|
-
};
|
|
235
|
-
var isResponseCorrect = (correctResponses, session) => {
|
|
236
|
-
var responses = cloneDeep(correctResponses);
|
|
237
|
-
var isCorrect = true;
|
|
238
|
-
var totalValidResponses = 0;
|
|
239
|
-
|
|
240
|
-
if (!session || isEmpty(session)) {
|
|
241
|
-
return false;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
responses.forEach(value => totalValidResponses += (value.images || []).length);
|
|
245
|
-
|
|
246
|
-
if (session.answers && totalValidResponses === session.answers.length) {
|
|
247
|
-
session.answers.forEach(answer => {
|
|
248
|
-
var _responses$answer$con;
|
|
249
|
-
|
|
250
|
-
var index = (((_responses$answer$con = responses[answer.containerIndex]) === null || _responses$answer$con === void 0 ? void 0 : _responses$answer$con.images) || []).indexOf(answer.value);
|
|
251
|
-
|
|
252
|
-
if (index >= 0) {
|
|
253
|
-
// remove response from correct responses array to ensure that duplicates are evaluated correctly
|
|
254
|
-
responses[answer.containerIndex].images.splice(index, 1);
|
|
255
|
-
} else {
|
|
256
|
-
isCorrect = false;
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
|
-
} else {
|
|
260
|
-
isCorrect = false;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
return isCorrect;
|
|
264
|
-
}; // This applies for correct responses that have empty values
|
|
265
|
-
|
|
266
|
-
var keepNonEmptyResponses = responses => {
|
|
267
|
-
var filtered = responses.filter(response => response.images && response.images.length);
|
|
268
|
-
return cloneDeep(filtered);
|
|
269
|
-
}; // This applies for items that don't support partial scoring.
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
var isDefaultOrAltResponseCorrect = (question, session) => {
|
|
273
|
-
var {
|
|
274
|
-
validation: {
|
|
275
|
-
altResponses
|
|
276
|
-
}
|
|
277
|
-
} = question;
|
|
278
|
-
var {
|
|
279
|
-
validation: {
|
|
280
|
-
validResponse: {
|
|
281
|
-
value
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
} = question;
|
|
285
|
-
var isCorrect = isResponseCorrect(value, session); // Look for correct answers in alternate responses.
|
|
286
|
-
|
|
287
|
-
if (!isCorrect && altResponses && altResponses.length) {
|
|
288
|
-
altResponses.forEach(altResponse => {
|
|
289
|
-
if (isResponseCorrect(altResponse.value, session)) {
|
|
290
|
-
isCorrect = true;
|
|
291
|
-
}
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
return isCorrect;
|
|
296
|
-
}; // Deduct only the items that exceeded the maximum valid response per container.
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
var getDeductionPerContainer = (containerIndex, answers, valid) => {
|
|
300
|
-
var totalStack = answers.filter(item => item.containerIndex === containerIndex);
|
|
301
|
-
var incorrectStack = totalStack.filter(item => !item.isCorrect);
|
|
302
|
-
var maxValid = (valid.value[containerIndex].images || []).length;
|
|
303
|
-
|
|
304
|
-
if (totalStack.length > maxValid) {
|
|
305
|
-
var ignored = totalStack.length - maxValid;
|
|
306
|
-
return incorrectStack.slice(-ignored);
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
return [];
|
|
310
|
-
};
|
|
311
|
-
|
|
312
|
-
var getPartialScore = (question, session) => {
|
|
313
|
-
var {
|
|
314
|
-
validation: {
|
|
315
|
-
validResponse
|
|
316
|
-
},
|
|
317
|
-
maxResponsePerZone
|
|
318
|
-
} = question;
|
|
319
|
-
var correctAnswers = 0;
|
|
320
|
-
var incorrectAnswers = 0;
|
|
321
|
-
var possibleResponses = 0;
|
|
322
|
-
|
|
323
|
-
if (!session || isEmpty(session)) {
|
|
324
|
-
return 0;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
validResponse.value.forEach(value => possibleResponses += (value.images || []).length);
|
|
328
|
-
|
|
329
|
-
if (session.answers && session.answers.length) {
|
|
330
|
-
var all = getAllUniqueCorrectness(session.answers, validResponse.value);
|
|
331
|
-
correctAnswers = all.filter(item => item.isCorrect).length;
|
|
332
|
-
incorrectAnswers = all.filter(item => !item.isCorrect).length; // deduction rules: https://docs.google.com/document/d/1Oprm8Qs5fg_Dwoj2pNpsfu4D63QgCZgvcqTgeaVel7I/edit
|
|
333
|
-
|
|
334
|
-
session.answers.forEach(answer => {
|
|
335
|
-
if (maxResponsePerZone > 1) {
|
|
336
|
-
var deductionList = getDeductionPerContainer(answer.containerIndex, all, validResponse);
|
|
337
|
-
|
|
338
|
-
if (deductionList.length) {
|
|
339
|
-
deductionList.forEach(item => {
|
|
340
|
-
if (item.id === answer.id) {
|
|
341
|
-
correctAnswers -= 1;
|
|
342
|
-
}
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
if (!maxResponsePerZone || maxResponsePerZone <= 1) {
|
|
349
|
-
correctAnswers -= incorrectAnswers;
|
|
350
|
-
}
|
|
351
|
-
} else {
|
|
352
|
-
correctAnswers = 0;
|
|
353
|
-
} // negative values will implicitly make the score equal to zero
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
correctAnswers = correctAnswers < 0 ? 0 : correctAnswers; // use length of validResponse since some containers can be left empty
|
|
357
|
-
|
|
358
|
-
var nonEmptyResponses = keepNonEmptyResponses(validResponse.value);
|
|
359
|
-
var denominator = maxResponsePerZone > 1 ? possibleResponses : (nonEmptyResponses || []).length;
|
|
360
|
-
var str = (correctAnswers / denominator).toFixed(2);
|
|
361
|
-
return parseFloat(str);
|
|
362
|
-
};
|
|
363
|
-
|
|
364
|
-
var getScore = function getScore(config, session) {
|
|
365
|
-
var env = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
366
|
-
var isPartialScoring = partialScoring.enabled(config, env);
|
|
367
|
-
var correct = isDefaultOrAltResponseCorrect(config, session);
|
|
368
|
-
return isPartialScoring ? getPartialScore(config, session) : correct ? 1 : 0;
|
|
369
|
-
};
|
|
370
|
-
|
|
371
|
-
var outcome = function outcome(config, session) {
|
|
372
|
-
var env = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
373
|
-
return new Promise(resolve => {
|
|
374
|
-
log('outcome...');
|
|
375
|
-
|
|
376
|
-
if (!session || isEmpty(session)) {
|
|
377
|
-
resolve({
|
|
378
|
-
score: 0,
|
|
379
|
-
empty: true
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
var configCamelized = humps.exports.camelizeKeys(config);
|
|
384
|
-
|
|
385
|
-
if (session.answers || []) {
|
|
386
|
-
var score = getScore(configCamelized, session, env);
|
|
387
|
-
resolve({
|
|
388
|
-
score
|
|
389
|
-
});
|
|
390
|
-
}
|
|
391
|
-
});
|
|
392
|
-
};
|
|
393
|
-
var createCorrectResponseSession = (question, env) => {
|
|
394
|
-
return new Promise(resolve => {
|
|
395
|
-
if (env.mode !== 'evaluate' && env.role === 'instructor') {
|
|
396
|
-
var {
|
|
397
|
-
validation: {
|
|
398
|
-
valid_response: {
|
|
399
|
-
value
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
} = question;
|
|
403
|
-
var answers = [];
|
|
404
|
-
|
|
405
|
-
if (value) {
|
|
406
|
-
value.forEach((container, i) => {
|
|
407
|
-
(container.images || []).forEach(v => {
|
|
408
|
-
answers.push({
|
|
409
|
-
value: v,
|
|
410
|
-
containerIndex: i
|
|
411
|
-
});
|
|
412
|
-
});
|
|
413
|
-
});
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
resolve({
|
|
417
|
-
answers,
|
|
418
|
-
id: '1'
|
|
419
|
-
});
|
|
420
|
-
} else {
|
|
421
|
-
resolve(null);
|
|
422
|
-
}
|
|
423
|
-
});
|
|
424
|
-
}; // remove all html tags
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
var getContent = html => (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');
|
|
428
|
-
|
|
429
|
-
var validate = function validate() {
|
|
430
|
-
var model = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
431
|
-
var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
432
|
-
var errors = {};
|
|
433
|
-
['teacherInstructions'].forEach(field => {
|
|
434
|
-
var _config$field;
|
|
435
|
-
|
|
436
|
-
if ((_config$field = config[field]) !== null && _config$field !== void 0 && _config$field.required && !getContent(model[field])) {
|
|
437
|
-
errors[field] = 'This field is required.';
|
|
438
|
-
}
|
|
439
|
-
});
|
|
440
|
-
return errors;
|
|
441
|
-
};
|
|
442
|
-
|
|
443
|
-
export { createCorrectResponseSession, getPartialScore, isResponseCorrect, model, normalize, outcome, validate };
|
|
444
|
-
//# sourceMappingURL=controller.js.map
|
package/esm/controller.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"controller.js","sources":["../../../node_modules/@babel/runtime/helpers/esm/defineProperty.js","../../../node_modules/humps/humps.js","../controller/src/defaults.js","../controller/src/utils.js","../controller/src/index.js"],"sourcesContent":["export default function _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}","// =========\n// = humps =\n// =========\n// Underscore-to-camelCase converter (and vice versa)\n// for strings and object keys\n\n// humps is copyright © 2012+ Dom Christie\n// Released under the MIT license.\n\n\n;(function(global) {\n\n var _processKeys = function(convert, obj, options) {\n if(!_isObject(obj) || _isDate(obj) || _isRegExp(obj) || _isBoolean(obj) || _isFunction(obj)) {\n return obj;\n }\n\n var output,\n i = 0,\n l = 0;\n\n if(_isArray(obj)) {\n output = [];\n for(l=obj.length; i<l; i++) {\n output.push(_processKeys(convert, obj[i], options));\n }\n }\n else {\n output = {};\n for(var key in obj) {\n if(Object.prototype.hasOwnProperty.call(obj, key)) {\n output[convert(key, options)] = _processKeys(convert, obj[key], options);\n }\n }\n }\n return output;\n };\n\n // String conversion methods\n\n var separateWords = function(string, options) {\n options = options || {};\n var separator = options.separator || '_';\n var split = options.split || /(?=[A-Z])/;\n\n return string.split(split).join(separator);\n };\n\n var camelize = function(string) {\n if (_isNumerical(string)) {\n return string;\n }\n string = string.replace(/[\\-_\\s]+(.)?/g, function(match, chr) {\n return chr ? chr.toUpperCase() : '';\n });\n // Ensure 1st char is always lowercase\n return string.substr(0, 1).toLowerCase() + string.substr(1);\n };\n\n var pascalize = function(string) {\n var camelized = camelize(string);\n // Ensure 1st char is always uppercase\n return camelized.substr(0, 1).toUpperCase() + camelized.substr(1);\n };\n\n var decamelize = function(string, options) {\n return separateWords(string, options).toLowerCase();\n };\n\n // Utilities\n // Taken from Underscore.js\n\n var toString = Object.prototype.toString;\n\n var _isFunction = function(obj) {\n return typeof(obj) === 'function';\n };\n var _isObject = function(obj) {\n return obj === Object(obj);\n };\n var _isArray = function(obj) {\n return toString.call(obj) == '[object Array]';\n };\n var _isDate = function(obj) {\n return toString.call(obj) == '[object Date]';\n };\n var _isRegExp = function(obj) {\n return toString.call(obj) == '[object RegExp]';\n };\n var _isBoolean = function(obj) {\n return toString.call(obj) == '[object Boolean]';\n };\n\n // Performant way to determine if obj coerces to a number\n var _isNumerical = function(obj) {\n obj = obj - 0;\n return obj === obj;\n };\n\n // Sets up function which handles processing keys\n // allowing the convert function to be modified by a callback\n var _processor = function(convert, options) {\n var callback = options && 'process' in options ? options.process : options;\n\n if(typeof(callback) !== 'function') {\n return convert;\n }\n\n return function(string, options) {\n return callback(string, convert, options);\n }\n };\n\n var humps = {\n camelize: camelize,\n decamelize: decamelize,\n pascalize: pascalize,\n depascalize: decamelize,\n camelizeKeys: function(object, options) {\n return _processKeys(_processor(camelize, options), object);\n },\n decamelizeKeys: function(object, options) {\n return _processKeys(_processor(decamelize, options), object, options);\n },\n pascalizeKeys: function(object, options) {\n return _processKeys(_processor(pascalize, options), object);\n },\n depascalizeKeys: function () {\n return this.decamelizeKeys.apply(this, arguments);\n }\n };\n\n if (typeof define === 'function' && define.amd) {\n define(humps);\n } else if (typeof module !== 'undefined' && module.exports) {\n module.exports = humps;\n } else {\n global.humps = humps;\n }\n\n})(this);\n","export default {\n rationale: '',\n rationaleEnabled: true,\n studentInstructionsEnabled: true,\n teacherInstructions: '',\n teacherInstructionsEnabled: true,\n};\n","// functions also used in src/utils-correctness.js\n\nconst getAllCorrectness = (answers, responses) =>\n (answers || []).map((answer) => ({\n ...answer,\n isCorrect: ((responses[answer.containerIndex] && responses[answer.containerIndex].images) || []).includes(\n answer.value,\n ),\n }));\n\nconst getValidAnswer = (answer, response) =>\n ((response[answer.containerIndex] && response[answer.containerIndex].images) || []).filter(\n (res) => res === answer.value,\n );\n\nexport const getAllUniqueCorrectness = (answers, validResponses) => {\n let allCorrectness = getAllCorrectness(answers, validResponses);\n\n answers.forEach((answer1) => {\n const valuesToParse = answers.filter(\n (answer2) => answer2.value === answer1.value && answer2.containerIndex === answer1.containerIndex,\n );\n\n if (valuesToParse.length > 1) {\n // point only to duplicates but first\n valuesToParse.shift();\n // mark duplicates as incorrect\n valuesToParse.forEach((value, index) => {\n allCorrectness = (allCorrectness || []).map((finalAnswer) => {\n if (finalAnswer.id === value.id) {\n let valid = getValidAnswer(finalAnswer, validResponses);\n return {\n ...finalAnswer,\n isCorrect: valid.length > index + 1,\n };\n }\n return finalAnswer;\n });\n });\n }\n });\n return allCorrectness;\n};\n","import debug from 'debug';\nimport { camelizeKeys } from 'humps';\nimport { partialScoring } from '@pie-lib/controller-utils';\nimport { cloneDeep, isEmpty, shuffle } from 'lodash';\n\nimport defaults from './defaults';\nimport { getAllUniqueCorrectness } from './utils';\n\nconst log = debug('pie-elements:image-cloze-association:controller');\n\nexport const normalize = (question) => ({ ...defaults, ...question });\n\nexport const model = (question, session, env) => {\n const questionNormalized = normalize(question);\n const questionCamelized = camelizeKeys(questionNormalized);\n\n return new Promise((resolve) => {\n const shouldIncludeCorrectResponse = env.mode === 'evaluate';\n\n const out = {\n disabled: env.mode !== 'gather',\n mode: env.mode,\n ...questionCamelized,\n responseCorrect: shouldIncludeCorrectResponse ? getScore(questionCamelized, session) === 1 : undefined,\n validation: shouldIncludeCorrectResponse ? questionCamelized.validation : undefined,\n };\n\n if (questionNormalized.shuffle) {\n out.possibleResponses = shuffle(questionNormalized.possible_responses);\n }\n\n if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {\n out.teacherInstructions = questionCamelized.teacherInstructionsEnabled\n ? questionCamelized.teacherInstructions\n : null;\n out.rationale = questionCamelized.rationale ? questionCamelized.rationale : null;\n } else {\n out.teacherInstructions = null;\n out.rationale = null;\n }\n\n resolve(out);\n });\n};\n\nexport const isResponseCorrect = (correctResponses, session) => {\n const responses = cloneDeep(correctResponses);\n let isCorrect = true;\n let totalValidResponses = 0;\n\n if (!session || isEmpty(session)) {\n return false;\n }\n\n responses.forEach((value) => (totalValidResponses += (value.images || []).length));\n\n if (session.answers && totalValidResponses === session.answers.length) {\n session.answers.forEach((answer) => {\n const index = (responses[answer.containerIndex]?.images || []).indexOf(answer.value);\n\n if (index >= 0) {\n // remove response from correct responses array to ensure that duplicates are evaluated correctly\n responses[answer.containerIndex].images.splice(index, 1);\n } else {\n isCorrect = false;\n }\n });\n } else {\n isCorrect = false;\n }\n\n return isCorrect;\n};\n\n// This applies for correct responses that have empty values\nconst keepNonEmptyResponses = (responses) => {\n const filtered = responses.filter((response) => response.images && response.images.length);\n return cloneDeep(filtered);\n};\n\n// This applies for items that don't support partial scoring.\nconst isDefaultOrAltResponseCorrect = (question, session) => {\n const {\n validation: { altResponses },\n } = question;\n let {\n validation: {\n validResponse: { value },\n },\n } = question;\n\n let isCorrect = isResponseCorrect(value, session);\n\n // Look for correct answers in alternate responses.\n if (!isCorrect && altResponses && altResponses.length) {\n altResponses.forEach((altResponse) => {\n if (isResponseCorrect(altResponse.value, session)) {\n isCorrect = true;\n }\n });\n }\n return isCorrect;\n};\n\n// Deduct only the items that exceeded the maximum valid response per container.\nconst getDeductionPerContainer = (containerIndex, answers, valid) => {\n const totalStack = answers.filter((item) => item.containerIndex === containerIndex);\n const incorrectStack = totalStack.filter((item) => !item.isCorrect);\n const maxValid = (valid.value[containerIndex].images || []).length;\n\n if (totalStack.length > maxValid) {\n const ignored = totalStack.length - maxValid;\n return incorrectStack.slice(-ignored);\n }\n return [];\n};\n\nexport const getPartialScore = (question, session) => {\n const {\n validation: { validResponse },\n maxResponsePerZone,\n } = question;\n let correctAnswers = 0;\n let incorrectAnswers = 0;\n let possibleResponses = 0;\n\n if (!session || isEmpty(session)) {\n return 0;\n }\n\n validResponse.value.forEach((value) => (possibleResponses += (value.images || []).length));\n\n if (session.answers && session.answers.length) {\n const all = getAllUniqueCorrectness(session.answers, validResponse.value);\n correctAnswers = all.filter((item) => item.isCorrect).length;\n incorrectAnswers = all.filter((item) => !item.isCorrect).length;\n\n // deduction rules: https://docs.google.com/document/d/1Oprm8Qs5fg_Dwoj2pNpsfu4D63QgCZgvcqTgeaVel7I/edit\n session.answers.forEach((answer) => {\n if (maxResponsePerZone > 1) {\n const deductionList = getDeductionPerContainer(answer.containerIndex, all, validResponse);\n\n if (deductionList.length) {\n deductionList.forEach((item) => {\n if (item.id === answer.id) {\n correctAnswers -= 1;\n }\n });\n }\n }\n });\n\n if (!maxResponsePerZone || maxResponsePerZone <= 1) {\n correctAnswers -= incorrectAnswers;\n }\n } else {\n correctAnswers = 0;\n }\n // negative values will implicitly make the score equal to zero\n correctAnswers = correctAnswers < 0 ? 0 : correctAnswers;\n\n // use length of validResponse since some containers can be left empty\n const nonEmptyResponses = keepNonEmptyResponses(validResponse.value);\n const denominator = maxResponsePerZone > 1 ? possibleResponses : (nonEmptyResponses || []).length;\n const str = (correctAnswers / denominator).toFixed(2);\n\n return parseFloat(str);\n};\n\nconst getScore = (config, session, env = {}) => {\n const isPartialScoring = partialScoring.enabled(config, env);\n const correct = isDefaultOrAltResponseCorrect(config, session);\n\n return isPartialScoring ? getPartialScore(config, session) : correct ? 1 : 0;\n};\n\nexport const outcome = (config, session, env = {}) => {\n return new Promise((resolve) => {\n log('outcome...');\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true });\n }\n\n const configCamelized = camelizeKeys(config);\n\n if (session.answers || []) {\n const score = getScore(configCamelized, session, env);\n resolve({ score });\n }\n });\n};\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const {\n validation: {\n valid_response: { value },\n },\n } = question;\n const answers = [];\n\n if (value) {\n value.forEach((container, i) => {\n (container.images || []).forEach((v) => {\n answers.push({\n value: v,\n containerIndex: i,\n });\n });\n });\n }\n\n resolve({\n answers,\n id: '1',\n });\n } else {\n resolve(null);\n }\n });\n};\n\n// remove all html tags\nconst getInnerText = (html) => (html || '').replaceAll(/<[^>]*>/g, '');\n\n// remove all html tags except img, iframe and source tag for audio\nconst getContent = (html) => (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');\n\nexport const validate = (model = {}, config = {}) => {\n const errors = {};\n\n ['teacherInstructions'].forEach((field) => {\n if (config[field]?.required && !getContent(model[field])) {\n errors[field] = 'This field is required.';\n }\n });\n\n return errors;\n};\n"],"names":["this","rationale","rationaleEnabled","studentInstructionsEnabled","teacherInstructions","teacherInstructionsEnabled","getAllCorrectness","answers","responses","map","answer","isCorrect","containerIndex","images","includes","value","getValidAnswer","response","filter","res","getAllUniqueCorrectness","validResponses","allCorrectness","forEach","answer1","valuesToParse","answer2","length","shift","index","finalAnswer","id","valid","_objectSpread","log","debug","normalize","question","defaults","model","session","env","questionNormalized","questionCamelized","camelizeKeys","Promise","resolve","shouldIncludeCorrectResponse","mode","out","disabled","responseCorrect","getScore","undefined","validation","shuffle","possibleResponses","possible_responses","role","isResponseCorrect","correctResponses","cloneDeep","totalValidResponses","isEmpty","indexOf","splice","keepNonEmptyResponses","filtered","isDefaultOrAltResponseCorrect","altResponses","validResponse","altResponse","getDeductionPerContainer","totalStack","item","incorrectStack","maxValid","ignored","slice","getPartialScore","maxResponsePerZone","correctAnswers","incorrectAnswers","all","deductionList","nonEmptyResponses","denominator","str","toFixed","parseFloat","config","isPartialScoring","partialScoring","enabled","correct","outcome","score","empty","configCamelized","createCorrectResponseSession","valid_response","container","i","v","push","getContent","html","replace","validate","errors","field","required"],"mappings":";;;;AAAe,SAAS,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE;AACzD,EAAE,IAAI,GAAG,IAAI,GAAG,EAAE;AAClB,IAAI,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE;AACpC,MAAM,KAAK,EAAE,KAAK;AAClB,MAAM,UAAU,EAAE,IAAI;AACtB,MAAM,YAAY,EAAE,IAAI;AACxB,MAAM,QAAQ,EAAE,IAAI;AACpB,KAAK,CAAC,CAAC;AACP,GAAG,MAAM;AACT,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AACrB,GAAG;AACH;AACA,EAAE,OAAO,GAAG,CAAC;AACb;;;;;;;ACHC,CAAC,SAAS,MAAM,EAAE;AACnB;AACA,EAAE,IAAI,YAAY,GAAG,SAAS,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE;AACrD,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE;AACjG,MAAM,OAAO,GAAG,CAAC;AACjB,KAAK;AACL;AACA,IAAI,IAAI,MAAM;AACd,QAAQ,CAAC,GAAG,CAAC;AACb,QAAQ,CAAC,GAAG,CAAC,CAAC;AACd;AACA,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE;AACtB,MAAM,MAAM,GAAG,EAAE,CAAC;AAClB,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;AAClC,QAAQ,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAC5D,OAAO;AACP,KAAK;AACL,SAAS;AACT,MAAM,MAAM,GAAG,EAAE,CAAC;AAClB,MAAM,IAAI,IAAI,GAAG,IAAI,GAAG,EAAE;AAC1B,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE;AAC3D,UAAU,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,GAAG,YAAY,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AACnF,SAAS;AACT,OAAO;AACP,KAAK;AACL,IAAI,OAAO,MAAM,CAAC;AAClB,GAAG,CAAC;AACJ;AACA;AACA;AACA,EAAE,IAAI,aAAa,GAAG,SAAS,MAAM,EAAE,OAAO,EAAE;AAChD,IAAI,OAAO,GAAG,OAAO,IAAI,EAAE,CAAC;AAC5B,IAAI,IAAI,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,GAAG,CAAC;AAC7C,IAAI,IAAI,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,WAAW,CAAC;AAC7C;AACA,IAAI,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAC/C,GAAG,CAAC;AACJ;AACA,EAAE,IAAI,QAAQ,GAAG,SAAS,MAAM,EAAE;AAClC,IAAI,IAAI,YAAY,CAAC,MAAM,CAAC,EAAE;AAC9B,MAAM,OAAO,MAAM,CAAC;AACpB,KAAK;AACL,IAAI,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,eAAe,EAAE,SAAS,KAAK,EAAE,GAAG,EAAE;AAClE,MAAM,OAAO,GAAG,GAAG,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC;AAC1C,KAAK,CAAC,CAAC;AACP;AACA,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAChE,GAAG,CAAC;AACJ;AACA,EAAE,IAAI,SAAS,GAAG,SAAS,MAAM,EAAE;AACnC,IAAI,IAAI,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;AACrC;AACA,IAAI,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACtE,GAAG,CAAC;AACJ;AACA,EAAE,IAAI,UAAU,GAAG,SAAS,MAAM,EAAE,OAAO,EAAE;AAC7C,IAAI,OAAO,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;AACxD,GAAG,CAAC;AACJ;AACA;AACA;AACA;AACA,EAAE,IAAI,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC;AAC3C;AACA,EAAE,IAAI,WAAW,GAAG,SAAS,GAAG,EAAE;AAClC,IAAI,OAAO,OAAO,GAAG,CAAC,KAAK,UAAU,CAAC;AACtC,GAAG,CAAC;AACJ,EAAE,IAAI,SAAS,GAAG,SAAS,GAAG,EAAE;AAChC,IAAI,OAAO,GAAG,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC;AAC/B,GAAG,CAAC;AACJ,EAAE,IAAI,QAAQ,GAAG,SAAS,GAAG,EAAE;AAC/B,IAAI,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,gBAAgB,CAAC;AAClD,GAAG,CAAC;AACJ,EAAE,IAAI,OAAO,GAAG,SAAS,GAAG,EAAE;AAC9B,IAAI,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,eAAe,CAAC;AACjD,GAAG,CAAC;AACJ,EAAE,IAAI,SAAS,GAAG,SAAS,GAAG,EAAE;AAChC,IAAI,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,iBAAiB,CAAC;AACnD,GAAG,CAAC;AACJ,EAAE,IAAI,UAAU,GAAG,SAAS,GAAG,EAAE;AACjC,IAAI,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,kBAAkB,CAAC;AACpD,GAAG,CAAC;AACJ;AACA;AACA,EAAE,IAAI,YAAY,GAAG,SAAS,GAAG,EAAE;AACnC,IAAI,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;AAClB,IAAI,OAAO,GAAG,KAAK,GAAG,CAAC;AACvB,GAAG,CAAC;AACJ;AACA;AACA;AACA,EAAE,IAAI,UAAU,GAAG,SAAS,OAAO,EAAE,OAAO,EAAE;AAC9C,IAAI,IAAI,QAAQ,GAAG,OAAO,IAAI,SAAS,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC;AAC/E;AACA,IAAI,GAAG,OAAO,QAAQ,CAAC,KAAK,UAAU,EAAE;AACxC,MAAM,OAAO,OAAO,CAAC;AACrB,KAAK;AACL;AACA,IAAI,OAAO,SAAS,MAAM,EAAE,OAAO,EAAE;AACrC,MAAM,OAAO,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAChD,KAAK;AACL,GAAG,CAAC;AACJ;AACA,EAAE,IAAI,KAAK,GAAG;AACd,IAAI,QAAQ,EAAE,QAAQ;AACtB,IAAI,UAAU,EAAE,UAAU;AAC1B,IAAI,SAAS,EAAE,SAAS;AACxB,IAAI,WAAW,EAAE,UAAU;AAC3B,IAAI,YAAY,EAAE,SAAS,MAAM,EAAE,OAAO,EAAE;AAC5C,MAAM,OAAO,YAAY,CAAC,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;AACjE,KAAK;AACL,IAAI,cAAc,EAAE,SAAS,MAAM,EAAE,OAAO,EAAE;AAC9C,MAAM,OAAO,YAAY,CAAC,UAAU,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAC5E,KAAK;AACL,IAAI,aAAa,EAAE,SAAS,MAAM,EAAE,OAAO,EAAE;AAC7C,MAAM,OAAO,YAAY,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;AAClE,KAAK;AACL,IAAI,eAAe,EAAE,YAAY;AACjC,MAAM,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AACxD,KAAK;AACL,GAAG,CAAC;AACJ;AACA,EAES,IAAqC,MAAM,CAAC,OAAO,EAAE;AAC9D,IAAI,MAAA,CAAA,OAAA,GAAiB,KAAK,CAAC;AAC3B,GAAG,MAAM;AACT,IAAI,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;AACzB,GAAG;AACH;AACA,CAAC,EAAEA,cAAI,CAAC,CAAA;;;AC5IR,eAAe;AACbC,EAAAA,SAAS,EAAE,EADE;AAEbC,EAAAA,gBAAgB,EAAE,IAFL;AAGbC,EAAAA,0BAA0B,EAAE,IAHf;AAIbC,EAAAA,mBAAmB,EAAE,EAJR;AAKbC,EAAAA,0BAA0B,EAAE,IAAA;AALf,CAAf;;;;;;ACAA;AAEA,IAAMC,iBAAiB,GAAG,CAACC,OAAD,EAAUC,SAAV,KACxB,CAACD,OAAO,IAAI,EAAZ,EAAgBE,GAAhB,CAAqBC,MAAD,wCACfA,MADe,CAAA,EAAA,EAAA,EAAA;AAElBC,EAAAA,SAAS,EAAE,CAAEH,SAAS,CAACE,MAAM,CAACE,cAAR,CAAT,IAAoCJ,SAAS,CAACE,MAAM,CAACE,cAAR,CAAT,CAAiCC,MAAtE,IAAiF,EAAlF,EAAsFC,QAAtF,CACTJ,MAAM,CAACK,KADE,CAAA;AAFO,CAAA,CAApB,CADF,CAAA;;AAQA,IAAMC,cAAc,GAAG,CAACN,MAAD,EAASO,QAAT,KACrB,CAAEA,QAAQ,CAACP,MAAM,CAACE,cAAR,CAAR,IAAmCK,QAAQ,CAACP,MAAM,CAACE,cAAR,CAAR,CAAgCC,MAApE,IAA+E,EAAhF,EAAoFK,MAApF,CACGC,GAAD,IAASA,GAAG,KAAKT,MAAM,CAACK,KAD1B,CADF,CAAA;;AAKO,IAAMK,uBAAuB,GAAG,CAACb,OAAD,EAAUc,cAAV,KAA6B;AAClE,EAAA,IAAIC,cAAc,GAAGhB,iBAAiB,CAACC,OAAD,EAAUc,cAAV,CAAtC,CAAA;AAEAd,EAAAA,OAAO,CAACgB,OAAR,CAAiBC,OAAD,IAAa;AAC3B,IAAMC,IAAAA,aAAa,GAAGlB,OAAO,CAACW,MAAR,CACnBQ,OAAD,IAAaA,OAAO,CAACX,KAAR,KAAkBS,OAAO,CAACT,KAA1B,IAAmCW,OAAO,CAACd,cAAR,KAA2BY,OAAO,CAACZ,cAD/D,CAAtB,CAAA;;AAIA,IAAA,IAAIa,aAAa,CAACE,MAAd,GAAuB,CAA3B,EAA8B;AAC5B;AACAF,MAAAA,aAAa,CAACG,KAAd,EAAA,CAF4B;;AAI5BH,MAAAA,aAAa,CAACF,OAAd,CAAsB,CAACR,KAAD,EAAQc,KAAR,KAAkB;AACtCP,QAAAA,cAAc,GAAG,CAACA,cAAc,IAAI,EAAnB,EAAuBb,GAAvB,CAA4BqB,WAAD,IAAiB;AAC3D,UAAA,IAAIA,WAAW,CAACC,EAAZ,KAAmBhB,KAAK,CAACgB,EAA7B,EAAiC;AAC/B,YAAA,IAAIC,KAAK,GAAGhB,cAAc,CAACc,WAAD,EAAcT,cAAd,CAA1B,CAAA;AACA,YAAA,OAAAY,eAAA,CAAAA,eAAA,CAAA,EAAA,EACKH,WADL,CAAA,EAAA,EAAA,EAAA;AAEEnB,cAAAA,SAAS,EAAEqB,KAAK,CAACL,MAAN,GAAeE,KAAK,GAAG,CAAA;AAFpC,aAAA,CAAA,CAAA;AAID,WAAA;;AACD,UAAA,OAAOC,WAAP,CAAA;AACD,SATgB,CAAjB,CAAA;AAUD,OAXD,CAAA,CAAA;AAYD,KAAA;AACF,GAtBD,CAAA,CAAA;AAuBA,EAAA,OAAOR,cAAP,CAAA;AACD,CA3BM;;;;;ACPP,IAAMY,GAAG,GAAGC,KAAK,CAAC,iDAAD,CAAjB,CAAA;AAEO,IAAMC,SAAS,GAAIC,QAAD,oCAAoBC,QAApB,CAAA,EAAiCD,QAAjC,EAAlB;AAEA,IAAME,KAAK,GAAG,CAACF,QAAD,EAAWG,OAAX,EAAoBC,GAApB,KAA4B;AAC/C,EAAA,IAAMC,kBAAkB,GAAGN,SAAS,CAACC,QAAD,CAApC,CAAA;AACA,EAAA,IAAMM,iBAAiB,GAAGC,0BAAY,CAACF,kBAAD,CAAtC,CAAA;AAEA,EAAA,OAAO,IAAIG,OAAJ,CAAaC,OAAD,IAAa;AAC9B,IAAA,IAAMC,4BAA4B,GAAGN,GAAG,CAACO,IAAJ,KAAa,UAAlD,CAAA;;AAEA,IAAA,IAAMC,GAAG,GAAA,aAAA,CAAA,aAAA,CAAA;AACPC,MAAAA,QAAQ,EAAET,GAAG,CAACO,IAAJ,KAAa,QADhB;AAEPA,MAAAA,IAAI,EAAEP,GAAG,CAACO,IAAAA;AAFH,KAAA,EAGJL,iBAHI,CAAA,EAAA,EAAA,EAAA;AAIPQ,MAAAA,eAAe,EAAEJ,4BAA4B,GAAGK,QAAQ,CAACT,iBAAD,EAAoBH,OAApB,CAAR,KAAyC,CAA5C,GAAgDa,SAJtF;AAKPC,MAAAA,UAAU,EAAEP,4BAA4B,GAAGJ,iBAAiB,CAACW,UAArB,GAAkCD,SAAAA;AALnE,KAAT,CAAA,CAAA;;AAQA,IAAIX,IAAAA,kBAAkB,CAACa,OAAvB,EAAgC;AAC9BN,MAAAA,GAAG,CAACO,iBAAJ,GAAwBD,OAAO,CAACb,kBAAkB,CAACe,kBAApB,CAA/B,CAAA;AACD,KAAA;;AAED,IAAA,IAAIhB,GAAG,CAACiB,IAAJ,KAAa,YAAb,KAA8BjB,GAAG,CAACO,IAAJ,KAAa,MAAb,IAAuBP,GAAG,CAACO,IAAJ,KAAa,UAAlE,CAAJ,EAAmF;AACjFC,MAAAA,GAAG,CAAC7C,mBAAJ,GAA0BuC,iBAAiB,CAACtC,0BAAlB,GACtBsC,iBAAiB,CAACvC,mBADI,GAEtB,IAFJ,CAAA;AAGA6C,MAAAA,GAAG,CAAChD,SAAJ,GAAgB0C,iBAAiB,CAAC1C,SAAlB,GAA8B0C,iBAAiB,CAAC1C,SAAhD,GAA4D,IAA5E,CAAA;AACD,KALD,MAKO;AACLgD,MAAAA,GAAG,CAAC7C,mBAAJ,GAA0B,IAA1B,CAAA;AACA6C,MAAAA,GAAG,CAAChD,SAAJ,GAAgB,IAAhB,CAAA;AACD,KAAA;;AAED6C,IAAAA,OAAO,CAACG,GAAD,CAAP,CAAA;AACD,GA1BM,CAAP,CAAA;AA2BD,EA/BM;IAiCMU,iBAAiB,GAAG,CAACC,gBAAD,EAAmBpB,OAAnB,KAA+B;AAC9D,EAAA,IAAMhC,SAAS,GAAGqD,SAAS,CAACD,gBAAD,CAA3B,CAAA;AACA,EAAIjD,IAAAA,SAAS,GAAG,IAAhB,CAAA;AACA,EAAImD,IAAAA,mBAAmB,GAAG,CAA1B,CAAA;;AAEA,EAAA,IAAI,CAACtB,OAAD,IAAYuB,OAAO,CAACvB,OAAD,CAAvB,EAAkC;AAChC,IAAA,OAAO,KAAP,CAAA;AACD,GAAA;;AAEDhC,EAAAA,SAAS,CAACe,OAAV,CAAmBR,KAAD,IAAY+C,mBAAmB,IAAI,CAAC/C,KAAK,CAACF,MAAN,IAAgB,EAAjB,EAAqBc,MAA1E,CAAA,CAAA;;AAEA,EAAIa,IAAAA,OAAO,CAACjC,OAAR,IAAmBuD,mBAAmB,KAAKtB,OAAO,CAACjC,OAAR,CAAgBoB,MAA/D,EAAuE;AACrEa,IAAAA,OAAO,CAACjC,OAAR,CAAgBgB,OAAhB,CAAyBb,MAAD,IAAY;AAAA,MAAA,IAAA,qBAAA,CAAA;;AAClC,MAAMmB,IAAAA,KAAK,GAAG,CAAC,CAAA,CAAA,qBAAA,GAAArB,SAAS,CAACE,MAAM,CAACE,cAAR,CAAT,gFAAkCC,MAAlC,KAA4C,EAA7C,EAAiDmD,OAAjD,CAAyDtD,MAAM,CAACK,KAAhE,CAAd,CAAA;;AAEA,MAAIc,IAAAA,KAAK,IAAI,CAAb,EAAgB;AACd;AACArB,QAAAA,SAAS,CAACE,MAAM,CAACE,cAAR,CAAT,CAAiCC,MAAjC,CAAwCoD,MAAxC,CAA+CpC,KAA/C,EAAsD,CAAtD,CAAA,CAAA;AACD,OAHD,MAGO;AACLlB,QAAAA,SAAS,GAAG,KAAZ,CAAA;AACD,OAAA;AACF,KATD,CAAA,CAAA;AAUD,GAXD,MAWO;AACLA,IAAAA,SAAS,GAAG,KAAZ,CAAA;AACD,GAAA;;AAED,EAAA,OAAOA,SAAP,CAAA;AACD;;AAGD,IAAMuD,qBAAqB,GAAI1D,SAAD,IAAe;AAC3C,EAAA,IAAM2D,QAAQ,GAAG3D,SAAS,CAACU,MAAV,CAAkBD,QAAD,IAAcA,QAAQ,CAACJ,MAAT,IAAmBI,QAAQ,CAACJ,MAAT,CAAgBc,MAAlE,CAAjB,CAAA;AACA,EAAOkC,OAAAA,SAAS,CAACM,QAAD,CAAhB,CAAA;AACD,CAHD;;;AAMA,IAAMC,6BAA6B,GAAG,CAAC/B,QAAD,EAAWG,OAAX,KAAuB;AAC3D,EAAM,IAAA;AACJc,IAAAA,UAAU,EAAE;AAAEe,MAAAA,YAAAA;AAAF,KAAA;AADR,GAAA,GAEFhC,QAFJ,CAAA;AAGA,EAAI,IAAA;AACFiB,IAAAA,UAAU,EAAE;AACVgB,MAAAA,aAAa,EAAE;AAAEvD,QAAAA,KAAAA;AAAF,OAAA;AADL,KAAA;AADV,GAAA,GAIAsB,QAJJ,CAAA;AAMA,EAAI1B,IAAAA,SAAS,GAAGgD,iBAAiB,CAAC5C,KAAD,EAAQyB,OAAR,CAAjC,CAV2D;;AAa3D,EAAI,IAAA,CAAC7B,SAAD,IAAc0D,YAAd,IAA8BA,YAAY,CAAC1C,MAA/C,EAAuD;AACrD0C,IAAAA,YAAY,CAAC9C,OAAb,CAAsBgD,WAAD,IAAiB;AACpC,MAAIZ,IAAAA,iBAAiB,CAACY,WAAW,CAACxD,KAAb,EAAoByB,OAApB,CAArB,EAAmD;AACjD7B,QAAAA,SAAS,GAAG,IAAZ,CAAA;AACD,OAAA;AACF,KAJD,CAAA,CAAA;AAKD,GAAA;;AACD,EAAA,OAAOA,SAAP,CAAA;AACD,CArBD;;;AAwBA,IAAM6D,wBAAwB,GAAG,CAAC5D,cAAD,EAAiBL,OAAjB,EAA0ByB,KAA1B,KAAoC;AACnE,EAAA,IAAMyC,UAAU,GAAGlE,OAAO,CAACW,MAAR,CAAgBwD,IAAD,IAAUA,IAAI,CAAC9D,cAAL,KAAwBA,cAAjD,CAAnB,CAAA;AACA,EAAA,IAAM+D,cAAc,GAAGF,UAAU,CAACvD,MAAX,CAAmBwD,IAAD,IAAU,CAACA,IAAI,CAAC/D,SAAlC,CAAvB,CAAA;AACA,EAAA,IAAMiE,QAAQ,GAAG,CAAC5C,KAAK,CAACjB,KAAN,CAAYH,cAAZ,CAA4BC,CAAAA,MAA5B,IAAsC,EAAvC,EAA2Cc,MAA5D,CAAA;;AAEA,EAAA,IAAI8C,UAAU,CAAC9C,MAAX,GAAoBiD,QAAxB,EAAkC;AAChC,IAAA,IAAMC,OAAO,GAAGJ,UAAU,CAAC9C,MAAX,GAAoBiD,QAApC,CAAA;AACA,IAAA,OAAOD,cAAc,CAACG,KAAf,CAAqB,CAACD,OAAtB,CAAP,CAAA;AACD,GAAA;;AACD,EAAA,OAAO,EAAP,CAAA;AACD,CAVD,CAAA;;IAYaE,eAAe,GAAG,CAAC1C,QAAD,EAAWG,OAAX,KAAuB;AACpD,EAAM,IAAA;AACJc,IAAAA,UAAU,EAAE;AAAEgB,MAAAA,aAAAA;AAAF,KADR;AAEJU,IAAAA,kBAAAA;AAFI,GAAA,GAGF3C,QAHJ,CAAA;AAIA,EAAI4C,IAAAA,cAAc,GAAG,CAArB,CAAA;AACA,EAAIC,IAAAA,gBAAgB,GAAG,CAAvB,CAAA;AACA,EAAI1B,IAAAA,iBAAiB,GAAG,CAAxB,CAAA;;AAEA,EAAA,IAAI,CAAChB,OAAD,IAAYuB,OAAO,CAACvB,OAAD,CAAvB,EAAkC;AAChC,IAAA,OAAO,CAAP,CAAA;AACD,GAAA;;AAED8B,EAAAA,aAAa,CAACvD,KAAd,CAAoBQ,OAApB,CAA6BR,KAAD,IAAYyC,iBAAiB,IAAI,CAACzC,KAAK,CAACF,MAAN,IAAgB,EAAjB,EAAqBc,MAAlF,CAAA,CAAA;;AAEA,EAAIa,IAAAA,OAAO,CAACjC,OAAR,IAAmBiC,OAAO,CAACjC,OAAR,CAAgBoB,MAAvC,EAA+C;AAC7C,IAAMwD,IAAAA,GAAG,GAAG/D,uBAAuB,CAACoB,OAAO,CAACjC,OAAT,EAAkB+D,aAAa,CAACvD,KAAhC,CAAnC,CAAA;AACAkE,IAAAA,cAAc,GAAGE,GAAG,CAACjE,MAAJ,CAAYwD,IAAD,IAAUA,IAAI,CAAC/D,SAA1B,CAAA,CAAqCgB,MAAtD,CAAA;AACAuD,IAAAA,gBAAgB,GAAGC,GAAG,CAACjE,MAAJ,CAAYwD,IAAD,IAAU,CAACA,IAAI,CAAC/D,SAA3B,CAAsCgB,CAAAA,MAAzD,CAH6C;;AAM7Ca,IAAAA,OAAO,CAACjC,OAAR,CAAgBgB,OAAhB,CAAyBb,MAAD,IAAY;AAClC,MAAIsE,IAAAA,kBAAkB,GAAG,CAAzB,EAA4B;AAC1B,QAAMI,IAAAA,aAAa,GAAGZ,wBAAwB,CAAC9D,MAAM,CAACE,cAAR,EAAwBuE,GAAxB,EAA6Bb,aAA7B,CAA9C,CAAA;;AAEA,QAAIc,IAAAA,aAAa,CAACzD,MAAlB,EAA0B;AACxByD,UAAAA,aAAa,CAAC7D,OAAd,CAAuBmD,IAAD,IAAU;AAC9B,YAAA,IAAIA,IAAI,CAAC3C,EAAL,KAAYrB,MAAM,CAACqB,EAAvB,EAA2B;AACzBkD,cAAAA,cAAc,IAAI,CAAlB,CAAA;AACD,aAAA;AACF,WAJD,CAAA,CAAA;AAKD,SAAA;AACF,OAAA;AACF,KAZD,CAAA,CAAA;;AAcA,IAAA,IAAI,CAACD,kBAAD,IAAuBA,kBAAkB,IAAI,CAAjD,EAAoD;AAClDC,MAAAA,cAAc,IAAIC,gBAAlB,CAAA;AACD,KAAA;AACF,GAvBD,MAuBO;AACLD,IAAAA,cAAc,GAAG,CAAjB,CAAA;AACD,GAxCmD;;;AA0CpDA,EAAAA,cAAc,GAAGA,cAAc,GAAG,CAAjB,GAAqB,CAArB,GAAyBA,cAA1C,CA1CoD;;AA6CpD,EAAA,IAAMI,iBAAiB,GAAGnB,qBAAqB,CAACI,aAAa,CAACvD,KAAf,CAA/C,CAAA;AACA,EAAA,IAAMuE,WAAW,GAAGN,kBAAkB,GAAG,CAArB,GAAyBxB,iBAAzB,GAA6C,CAAC6B,iBAAiB,IAAI,EAAtB,EAA0B1D,MAA3F,CAAA;AACA,EAAM4D,IAAAA,GAAG,GAAG,CAACN,cAAc,GAAGK,WAAlB,EAA+BE,OAA/B,CAAuC,CAAvC,CAAZ,CAAA;AAEA,EAAOC,OAAAA,UAAU,CAACF,GAAD,CAAjB,CAAA;AACD,EAlDM;;AAoDP,IAAMnC,QAAQ,GAAG,SAAXA,QAAW,CAACsC,MAAD,EAASlD,OAAT,EAA+B;AAAA,EAAbC,IAAAA,GAAa,uEAAP,EAAO,CAAA;AAC9C,EAAMkD,IAAAA,gBAAgB,GAAGC,cAAc,CAACC,OAAf,CAAuBH,MAAvB,EAA+BjD,GAA/B,CAAzB,CAAA;AACA,EAAA,IAAMqD,OAAO,GAAG1B,6BAA6B,CAACsB,MAAD,EAASlD,OAAT,CAA7C,CAAA;AAEA,EAAA,OAAOmD,gBAAgB,GAAGZ,eAAe,CAACW,MAAD,EAASlD,OAAT,CAAlB,GAAsCsD,OAAO,GAAG,CAAH,GAAO,CAA3E,CAAA;AACD,CALD,CAAA;;AAOO,IAAMC,OAAO,GAAG,SAAVA,OAAU,CAACL,MAAD,EAASlD,OAAT,EAA+B;AAAA,EAAbC,IAAAA,GAAa,uEAAP,EAAO,CAAA;AACpD,EAAA,OAAO,IAAII,OAAJ,CAAaC,OAAD,IAAa;AAC9BZ,IAAAA,GAAG,CAAC,YAAD,CAAH,CAAA;;AACA,IAAA,IAAI,CAACM,OAAD,IAAYuB,OAAO,CAACvB,OAAD,CAAvB,EAAkC;AAChCM,MAAAA,OAAO,CAAC;AAAEkD,QAAAA,KAAK,EAAE,CAAT;AAAYC,QAAAA,KAAK,EAAE,IAAA;AAAnB,OAAD,CAAP,CAAA;AACD,KAAA;;AAED,IAAA,IAAMC,eAAe,GAAGtD,0BAAY,CAAC8C,MAAD,CAApC,CAAA;;AAEA,IAAA,IAAIlD,OAAO,CAACjC,OAAR,IAAmB,EAAvB,EAA2B;AACzB,MAAMyF,IAAAA,KAAK,GAAG5C,QAAQ,CAAC8C,eAAD,EAAkB1D,OAAlB,EAA2BC,GAA3B,CAAtB,CAAA;AACAK,MAAAA,OAAO,CAAC;AAAEkD,QAAAA,KAAAA;AAAF,OAAD,CAAP,CAAA;AACD,KAAA;AACF,GAZM,CAAP,CAAA;AAaD,EAdM;IAgBMG,4BAA4B,GAAG,CAAC9D,QAAD,EAAWI,GAAX,KAAmB;AAC7D,EAAA,OAAO,IAAII,OAAJ,CAAaC,OAAD,IAAa;AAC9B,IAAIL,IAAAA,GAAG,CAACO,IAAJ,KAAa,UAAb,IAA2BP,GAAG,CAACiB,IAAJ,KAAa,YAA5C,EAA0D;AACxD,MAAM,IAAA;AACJJ,QAAAA,UAAU,EAAE;AACV8C,UAAAA,cAAc,EAAE;AAAErF,YAAAA,KAAAA;AAAF,WAAA;AADN,SAAA;AADR,OAAA,GAIFsB,QAJJ,CAAA;AAKA,MAAM9B,IAAAA,OAAO,GAAG,EAAhB,CAAA;;AAEA,MAAA,IAAIQ,KAAJ,EAAW;AACTA,QAAAA,KAAK,CAACQ,OAAN,CAAc,CAAC8E,SAAD,EAAYC,CAAZ,KAAkB;AAC9B,UAACD,CAAAA,SAAS,CAACxF,MAAV,IAAoB,EAArB,EAAyBU,OAAzB,CAAkCgF,CAAD,IAAO;AACtChG,YAAAA,OAAO,CAACiG,IAAR,CAAa;AACXzF,cAAAA,KAAK,EAAEwF,CADI;AAEX3F,cAAAA,cAAc,EAAE0F,CAAAA;AAFL,aAAb,CAAA,CAAA;AAID,WALD,CAAA,CAAA;AAMD,SAPD,CAAA,CAAA;AAQD,OAAA;;AAEDxD,MAAAA,OAAO,CAAC;AACNvC,QAAAA,OADM;AAENwB,QAAAA,EAAE,EAAE,GAAA;AAFE,OAAD,CAAP,CAAA;AAID,KAvBD,MAuBO;AACLe,MAAAA,OAAO,CAAC,IAAD,CAAP,CAAA;AACD,KAAA;AACF,GA3BM,CAAP,CAAA;AA4BD;;;AAMD,IAAM2D,UAAU,GAAIC,IAAD,IAAU,CAACA,IAAI,IAAI,EAAT,EAAaC,OAAb,CAAqB,oCAArB,EAA2D,EAA3D,CAA7B,CAAA;;AAEaC,IAAAA,QAAQ,GAAG,SAAXA,QAAW,GAA6B;AAAA,EAA5BrE,IAAAA,KAA4B,uEAApB,EAAoB,CAAA;AAAA,EAAhBmD,IAAAA,MAAgB,uEAAP,EAAO,CAAA;AACnD,EAAMmB,IAAAA,MAAM,GAAG,EAAf,CAAA;AAEA,EAAA,CAAC,qBAAD,CAAA,CAAwBtF,OAAxB,CAAiCuF,KAAD,IAAW;AAAA,IAAA,IAAA,aAAA,CAAA;;AACzC,IAAA,IAAI,iBAAApB,MAAM,CAACoB,KAAD,CAAN,wDAAeC,QAAf,IAA2B,CAACN,UAAU,CAAClE,KAAK,CAACuE,KAAD,CAAN,CAA1C,EAA0D;AACxDD,MAAAA,MAAM,CAACC,KAAD,CAAN,GAAgB,yBAAhB,CAAA;AACD,KAAA;AACF,GAJD,CAAA,CAAA;AAMA,EAAA,OAAOD,MAAP,CAAA;AACD;;;;"}
|