@pie-element/categorize 11.3.4-next.3 → 12.0.0-beta.1
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 +0 -11
- package/configure/CHANGELOG.md +0 -11
- package/configure/lib/__tests__/main.test.js +100 -0
- package/configure/lib/__tests__/utils.js +39 -0
- package/configure/lib/defaults.js +3 -6
- package/configure/lib/defaults.js.map +1 -1
- package/configure/lib/design/__tests__/builder.test.js +34 -0
- package/configure/lib/design/__tests__/buttons.test.js +36 -0
- package/configure/lib/design/__tests__/header.test.js +37 -0
- package/configure/lib/design/__tests__/index.test.js +125 -0
- package/configure/lib/design/__tests__/input-header.test.js +41 -0
- package/configure/lib/design/builder.js +16 -34
- package/configure/lib/design/builder.js.map +1 -1
- package/configure/lib/design/buttons.js +42 -96
- package/configure/lib/design/buttons.js.map +1 -1
- package/configure/lib/design/categories/RowLabel.js +34 -47
- package/configure/lib/design/categories/RowLabel.js.map +1 -1
- package/configure/lib/design/categories/__tests__/alternateResponses.test.js +93 -0
- package/configure/lib/design/categories/__tests__/category.test.js +65 -0
- package/configure/lib/design/categories/__tests__/choice-preview.test.js +52 -0
- package/configure/lib/design/categories/__tests__/droppable-placeholder.test.js +63 -0
- package/configure/lib/design/categories/__tests__/index.test.js +91 -0
- package/configure/lib/design/categories/alternateResponses.js +97 -252
- package/configure/lib/design/categories/alternateResponses.js.map +1 -1
- package/configure/lib/design/categories/category.js +136 -209
- package/configure/lib/design/categories/category.js.map +1 -1
- package/configure/lib/design/categories/choice-preview.js +62 -127
- package/configure/lib/design/categories/choice-preview.js.map +1 -1
- package/configure/lib/design/categories/droppable-placeholder.js +74 -166
- package/configure/lib/design/categories/droppable-placeholder.js.map +1 -1
- package/configure/lib/design/categories/index.js +196 -385
- package/configure/lib/design/categories/index.js.map +1 -1
- package/configure/lib/design/choices/__tests__/choice.test.js +62 -0
- package/configure/lib/design/choices/__tests__/config.test.js +66 -0
- package/configure/lib/design/choices/__tests__/index.test.js +70 -0
- package/configure/lib/design/choices/choice.js +156 -265
- package/configure/lib/design/choices/choice.js.map +1 -1
- package/configure/lib/design/choices/config.js +43 -99
- package/configure/lib/design/choices/config.js.map +1 -1
- package/configure/lib/design/choices/index.js +149 -237
- package/configure/lib/design/choices/index.js.map +1 -1
- package/configure/lib/design/header.js +58 -112
- package/configure/lib/design/header.js.map +1 -1
- package/configure/lib/design/index.js +633 -478
- package/configure/lib/design/index.js.map +1 -1
- package/configure/lib/design/input-header.js +95 -151
- package/configure/lib/design/input-header.js.map +1 -1
- package/configure/lib/design/utils.js +5 -16
- package/configure/lib/design/utils.js.map +1 -1
- package/configure/lib/index.js +121 -184
- package/configure/lib/index.js.map +1 -1
- package/configure/lib/main.js +31 -75
- package/configure/lib/main.js.map +1 -1
- package/configure/lib/utils.js +23 -33
- package/configure/lib/utils.js.map +1 -1
- package/configure/package.json +15 -15
- package/controller/CHANGELOG.md +0 -11
- package/controller/lib/__tests__/index.test.js +526 -0
- package/controller/lib/defaults.js +3 -6
- package/controller/lib/defaults.js.map +1 -1
- package/controller/lib/index.js +238 -319
- package/controller/lib/index.js.map +1 -1
- package/controller/lib/utils.js +29 -66
- package/controller/lib/utils.js.map +1 -1
- package/controller/package.json +5 -5
- package/docs/demo/.pie/.configure/package.json +10 -0
- package/docs/demo/.pie/.configure/yarn.lock +2181 -0
- package/docs/demo/.pie/.controllers/package.json +10 -0
- package/docs/demo/.pie/.controllers/yarn.lock +110 -0
- package/docs/demo/.pie/info.entry.js +89 -0
- package/docs/demo/.pie/info.webpack.config.js +119 -0
- package/docs/demo/.pie/package.json +10 -0
- package/docs/demo/.pie/yarn.lock +2190 -0
- package/docs/demo/pie.manifest.json +11 -0
- package/lib/__tests__/index.test.js +197 -0
- package/lib/categorize/__tests__/categories.test.js +138 -0
- package/lib/categorize/__tests__/category.test.js +137 -0
- package/lib/categorize/__tests__/choice.test.js +88 -0
- package/lib/categorize/__tests__/choices.test.js +118 -0
- package/lib/categorize/__tests__/droppable-placeholder.test.js +96 -0
- package/lib/categorize/__tests__/grid-content.test.js +48 -0
- package/lib/categorize/__tests__/index.test.js +152 -0
- package/lib/categorize/categories.js +107 -165
- package/lib/categorize/categories.js.map +1 -1
- package/lib/categorize/category.js +74 -124
- package/lib/categorize/category.js.map +1 -1
- package/lib/categorize/choice.js +119 -246
- package/lib/categorize/choice.js.map +1 -1
- package/lib/categorize/choices.js +67 -132
- package/lib/categorize/choices.js.map +1 -1
- package/lib/categorize/droppable-placeholder.js +47 -104
- package/lib/categorize/droppable-placeholder.js.map +1 -1
- package/lib/categorize/grid-content.js +40 -88
- package/lib/categorize/grid-content.js.map +1 -1
- package/lib/categorize/index.js +342 -318
- package/lib/categorize/index.js.map +1 -1
- package/lib/index.js +286 -307
- package/lib/index.js.map +1 -1
- package/package.json +16 -14
- package/esm/configure.js +0 -34401
- package/esm/configure.js.map +0 -1
- package/esm/controller.js +0 -1468
- package/esm/controller.js.map +0 -1
- package/esm/element.js +0 -13134
- package/esm/element.js.map +0 -1
- package/esm/package.json +0 -3
package/controller/lib/index.js
CHANGED
|
@@ -1,144 +1,110 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
-
|
|
5
4
|
Object.defineProperty(exports, "__esModule", {
|
|
6
5
|
value: true
|
|
7
6
|
});
|
|
8
7
|
exports.outcome = exports.normalize = exports.model = exports.getTotalScore = exports.getPartialScore = exports.getCorrectness = exports.createDefaultModel = exports.createCorrectResponseSession = void 0;
|
|
9
8
|
Object.defineProperty(exports, "score", {
|
|
10
9
|
enumerable: true,
|
|
11
|
-
get: function
|
|
10
|
+
get: function () {
|
|
12
11
|
return _categorize.score;
|
|
13
12
|
}
|
|
14
13
|
});
|
|
15
14
|
exports.validate = void 0;
|
|
16
|
-
|
|
17
|
-
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
18
|
-
|
|
19
|
-
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
20
|
-
|
|
21
|
-
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
22
|
-
|
|
23
|
-
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
24
|
-
|
|
25
15
|
var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));
|
|
26
|
-
|
|
27
16
|
var _categorize = require("@pie-lib/categorize");
|
|
28
|
-
|
|
29
17
|
var _feedback = require("@pie-lib/feedback");
|
|
30
|
-
|
|
31
18
|
var _controllerUtils = require("@pie-lib/controller-utils");
|
|
32
|
-
|
|
33
19
|
var _translator = _interopRequireDefault(require("@pie-lib/translator"));
|
|
34
|
-
|
|
35
20
|
var _defaults = _interopRequireDefault(require("./defaults"));
|
|
36
|
-
|
|
37
21
|
var _utils = require("./utils");
|
|
22
|
+
const {
|
|
23
|
+
translator
|
|
24
|
+
} = _translator.default;
|
|
38
25
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
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) { (0, _defineProperty2["default"])(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; }
|
|
42
|
-
|
|
43
|
-
var translator = _translator["default"].translator;
|
|
26
|
+
// eslint-disable-next-line no-console
|
|
44
27
|
|
|
45
|
-
|
|
28
|
+
const getPartialScore = (correctResponse, builtCategories) => {
|
|
46
29
|
// in the resulted best scenario we make a sum with all the correct responses
|
|
47
30
|
// and all the placements
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}, {
|
|
31
|
+
const {
|
|
32
|
+
placements,
|
|
33
|
+
score
|
|
34
|
+
} = builtCategories.reduce((acc, {
|
|
35
|
+
choices = []
|
|
36
|
+
}) => ({
|
|
37
|
+
placements: acc.placements + choices.length,
|
|
38
|
+
score: acc.score + choices.filter(ch => ch.correct).length
|
|
39
|
+
}), {
|
|
58
40
|
placements: 0,
|
|
59
41
|
score: 0
|
|
60
|
-
})
|
|
61
|
-
placements = _builtCategories$redu.placements,
|
|
62
|
-
score = _builtCategories$redu.score; // in the correct response, we make a sum of the max possible score
|
|
63
|
-
|
|
42
|
+
});
|
|
64
43
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
44
|
+
// in the correct response, we make a sum of the max possible score
|
|
45
|
+
const {
|
|
46
|
+
maxScore
|
|
47
|
+
} = correctResponse.reduce((acc, {
|
|
48
|
+
choices
|
|
49
|
+
}) => ({
|
|
50
|
+
maxScore: acc.maxScore + choices.length
|
|
51
|
+
}), {
|
|
71
52
|
maxScore: 0
|
|
72
|
-
})
|
|
73
|
-
maxScore = _correctResponse$redu.maxScore; // if there are any extra placements, we subtract from the obtained score
|
|
74
|
-
|
|
53
|
+
});
|
|
75
54
|
|
|
76
|
-
|
|
77
|
-
|
|
55
|
+
// if there are any extra placements, we subtract from the obtained score
|
|
56
|
+
const extraPlacements = placements > maxScore ? placements - maxScore : 0;
|
|
57
|
+
const totalScore = (score - extraPlacements) / maxScore;
|
|
78
58
|
return totalScore < 0 ? 0 : parseFloat(totalScore.toFixed(2));
|
|
79
59
|
};
|
|
80
|
-
|
|
81
60
|
exports.getPartialScore = getPartialScore;
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
return correctResponse.map(function (c) {
|
|
85
|
-
return c.alternateResponses;
|
|
86
|
-
}).filter(function (alternate) {
|
|
87
|
-
return alternate;
|
|
88
|
-
});
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
var getTotalScore = function getTotalScore(question, session, env) {
|
|
61
|
+
const getAlternates = correctResponse => correctResponse.map(c => c.alternateResponses).filter(alternate => alternate);
|
|
62
|
+
const getTotalScore = (question, session, env) => {
|
|
92
63
|
if (!session) {
|
|
93
64
|
return 0;
|
|
94
65
|
}
|
|
95
|
-
|
|
96
66
|
if (Object.keys(session).length === 0) {
|
|
97
67
|
return 0;
|
|
98
68
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
69
|
+
const {
|
|
70
|
+
categories,
|
|
71
|
+
choices
|
|
72
|
+
} = question || {};
|
|
73
|
+
let {
|
|
74
|
+
correctResponse
|
|
75
|
+
} = question || {};
|
|
76
|
+
let {
|
|
77
|
+
answers
|
|
78
|
+
} = session || {};
|
|
110
79
|
answers = answers || [];
|
|
111
|
-
correctResponse = correctResponse || [];
|
|
112
|
-
// so we get the best scenario and calculate the score
|
|
113
|
-
|
|
114
|
-
var _buildState = (0, _categorize.buildState)(categories, choices, answers, correctResponse),
|
|
115
|
-
builtCategories = _buildState.categories,
|
|
116
|
-
correct = _buildState.correct;
|
|
117
|
-
|
|
118
|
-
var alternates = getAlternates(correctResponse);
|
|
119
|
-
|
|
120
|
-
var enabled = _controllerUtils.partialScoring.enabled(question, env); // if there are any alternates, there will be no partial scoring!
|
|
121
|
-
|
|
80
|
+
correctResponse = correctResponse || [];
|
|
122
81
|
|
|
82
|
+
// this function is used in pie-ui/categorize as well, in order to get the best scenario
|
|
83
|
+
// so we get the best scenario and calculate the score
|
|
84
|
+
const {
|
|
85
|
+
categories: builtCategories,
|
|
86
|
+
correct
|
|
87
|
+
} = (0, _categorize.buildState)(categories, choices, answers, correctResponse);
|
|
88
|
+
const alternates = getAlternates(correctResponse);
|
|
89
|
+
const enabled = _controllerUtils.partialScoring.enabled(question, env);
|
|
90
|
+
|
|
91
|
+
// if there are any alternates, there will be no partial scoring!
|
|
123
92
|
if (enabled && !alternates.length) {
|
|
124
93
|
// we apply partial scoring
|
|
125
94
|
return getPartialScore(correctResponse, builtCategories);
|
|
126
|
-
}
|
|
127
|
-
|
|
95
|
+
}
|
|
128
96
|
|
|
97
|
+
// else we apply dichotomous
|
|
129
98
|
return correct ? 1 : 0;
|
|
130
99
|
};
|
|
131
|
-
|
|
132
100
|
exports.getTotalScore = getTotalScore;
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
return new Promise(function (resolve) {
|
|
101
|
+
const getCorrectness = (question, session, env) => {
|
|
102
|
+
return new Promise(resolve => {
|
|
136
103
|
if (env.mode === 'evaluate') {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
if (_score === 1) {
|
|
104
|
+
const score = getTotalScore(question, session, env);
|
|
105
|
+
if (score === 1) {
|
|
140
106
|
resolve('correct');
|
|
141
|
-
} else if (
|
|
107
|
+
} else if (score === 0) {
|
|
142
108
|
resolve('incorrect');
|
|
143
109
|
} else {
|
|
144
110
|
resolve('partially-correct');
|
|
@@ -148,21 +114,19 @@ var getCorrectness = function getCorrectness(question, session, env) {
|
|
|
148
114
|
}
|
|
149
115
|
});
|
|
150
116
|
};
|
|
151
|
-
|
|
152
117
|
exports.getCorrectness = getCorrectness;
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
resolve(_objectSpread(_objectSpread({}, _defaults["default"]), model));
|
|
118
|
+
const createDefaultModel = (model = {}) => new Promise(resolve => {
|
|
119
|
+
resolve({
|
|
120
|
+
..._defaults.default,
|
|
121
|
+
...model
|
|
158
122
|
});
|
|
159
|
-
};
|
|
160
|
-
|
|
123
|
+
});
|
|
161
124
|
exports.createDefaultModel = createDefaultModel;
|
|
125
|
+
const normalize = question => ({
|
|
126
|
+
..._defaults.default,
|
|
127
|
+
...question
|
|
128
|
+
});
|
|
162
129
|
|
|
163
|
-
var normalize = function normalize(question) {
|
|
164
|
-
return _objectSpread(_objectSpread({}, _defaults["default"]), question);
|
|
165
|
-
};
|
|
166
130
|
/**
|
|
167
131
|
*
|
|
168
132
|
* @param {*} question
|
|
@@ -170,148 +134,129 @@ var normalize = function normalize(question) {
|
|
|
170
134
|
* @param {*} env
|
|
171
135
|
* @param {*} updateSession - optional - a function that will set the properties passed into it on the session.
|
|
172
136
|
*/
|
|
173
|
-
|
|
174
|
-
|
|
175
137
|
exports.normalize = normalize;
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
_context.next = 17;
|
|
219
|
-
break;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
_context.next = 16;
|
|
223
|
-
return (0, _controllerUtils.getShuffledChoices)(choices, session, updateSession, 'id');
|
|
224
|
-
|
|
225
|
-
case 16:
|
|
226
|
-
choices = _context.sent;
|
|
227
|
-
|
|
228
|
-
case 17:
|
|
229
|
-
if (!note) {
|
|
230
|
-
note = translator.t('common:commonCorrectAnswerWithAlternates', {
|
|
231
|
-
lng: language
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
alternates = getAlternates(filteredCorrectResponse);
|
|
236
|
-
_getCompleteResponseD = (0, _utils.getCompleteResponseDetails)(filteredCorrectResponse, normalizedQuestion.allowAlternateEnabled ? alternates : [], normalizedQuestion.choices), responseAreasToBeFilled = _getCompleteResponseD.responseAreasToBeFilled, possibleResponses = _getCompleteResponseD.possibleResponses, hasUnplacedChoices = _getCompleteResponseD.hasUnplacedChoices;
|
|
237
|
-
out = {
|
|
238
|
-
categories: categories || [],
|
|
239
|
-
categoriesPerRow: categoriesPerRow || 2,
|
|
240
|
-
maxChoicesPerCategory: maxChoicesPerCategory,
|
|
241
|
-
correctness: answerCorrectness,
|
|
242
|
-
choices: choices || [],
|
|
243
|
-
choicesLabel: choicesLabel || '',
|
|
244
|
-
choicesPosition: choicesPosition,
|
|
245
|
-
disabled: mode !== 'gather',
|
|
246
|
-
feedback: fb,
|
|
247
|
-
lockChoiceOrder: lockChoiceOrder,
|
|
248
|
-
prompt: promptEnabled ? prompt : null,
|
|
249
|
-
rowLabels: rowLabels,
|
|
250
|
-
note: note,
|
|
251
|
-
env: env,
|
|
252
|
-
showNote: alternates && alternates.length > 0,
|
|
253
|
-
correctResponse: mode === 'evaluate' ? filteredCorrectResponse : undefined,
|
|
254
|
-
language: language,
|
|
255
|
-
extraCSSRules: extraCSSRules,
|
|
256
|
-
fontSizeFactor: fontSizeFactor,
|
|
257
|
-
minRowHeight: minRowHeight,
|
|
258
|
-
autoplayAudioEnabled: autoplayAudioEnabled,
|
|
259
|
-
completeAudioEnabled: completeAudioEnabled,
|
|
260
|
-
customAudioButton: customAudioButton,
|
|
261
|
-
possibleResponses: possibleResponses,
|
|
262
|
-
responseAreasToBeFilled: responseAreasToBeFilled,
|
|
263
|
-
hasUnplacedChoices: hasUnplacedChoices
|
|
264
|
-
};
|
|
265
|
-
|
|
266
|
-
if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {
|
|
267
|
-
out.rationale = rationaleEnabled ? rationale : null;
|
|
268
|
-
out.teacherInstructions = teacherInstructionsEnabled ? teacherInstructions : null;
|
|
269
|
-
} else {
|
|
270
|
-
out.rationale = null;
|
|
271
|
-
out.teacherInstructions = null;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
resolve(out);
|
|
275
|
-
|
|
276
|
-
case 23:
|
|
277
|
-
case "end":
|
|
278
|
-
return _context.stop();
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}, _callee);
|
|
282
|
-
}));
|
|
283
|
-
|
|
284
|
-
return function (_x) {
|
|
285
|
-
return _ref6.apply(this, arguments);
|
|
138
|
+
const model = async (question, session, env, updateSession) => {
|
|
139
|
+
const normalizedQuestion = normalize(question);
|
|
140
|
+
const answerCorrectness = await getCorrectness(normalizedQuestion, session, env);
|
|
141
|
+
const {
|
|
142
|
+
mode,
|
|
143
|
+
role
|
|
144
|
+
} = env || {};
|
|
145
|
+
const {
|
|
146
|
+
categories,
|
|
147
|
+
categoriesPerRow,
|
|
148
|
+
choicesLabel,
|
|
149
|
+
choicesPosition,
|
|
150
|
+
correctResponse,
|
|
151
|
+
feedback,
|
|
152
|
+
feedbackEnabled,
|
|
153
|
+
promptEnabled,
|
|
154
|
+
prompt,
|
|
155
|
+
rowLabels,
|
|
156
|
+
rationaleEnabled,
|
|
157
|
+
rationale,
|
|
158
|
+
teacherInstructionsEnabled,
|
|
159
|
+
teacherInstructions,
|
|
160
|
+
language,
|
|
161
|
+
maxChoicesPerCategory,
|
|
162
|
+
extraCSSRules,
|
|
163
|
+
minRowHeight,
|
|
164
|
+
fontSizeFactor,
|
|
165
|
+
autoplayAudioEnabled,
|
|
166
|
+
completeAudioEnabled,
|
|
167
|
+
customAudioButton
|
|
168
|
+
} = normalizedQuestion;
|
|
169
|
+
let {
|
|
170
|
+
choices,
|
|
171
|
+
note
|
|
172
|
+
} = normalizedQuestion;
|
|
173
|
+
let fb;
|
|
174
|
+
const lockChoiceOrder = (0, _controllerUtils.lockChoices)(normalizedQuestion, session, env);
|
|
175
|
+
const filteredCorrectResponse = correctResponse.map(response => {
|
|
176
|
+
const filteredChoices = (response.choices || []).filter(choice => choice !== 'null');
|
|
177
|
+
return {
|
|
178
|
+
...response,
|
|
179
|
+
choices: filteredChoices
|
|
286
180
|
};
|
|
287
|
-
}
|
|
181
|
+
});
|
|
182
|
+
if (mode === 'evaluate' && feedbackEnabled) {
|
|
183
|
+
fb = await (0, _feedback.getFeedbackForCorrectness)(answerCorrectness, feedback);
|
|
184
|
+
}
|
|
185
|
+
if (!lockChoiceOrder) {
|
|
186
|
+
choices = await (0, _controllerUtils.getShuffledChoices)(choices, session, updateSession, 'id');
|
|
187
|
+
}
|
|
188
|
+
if (!note) {
|
|
189
|
+
note = translator.t('common:commonCorrectAnswerWithAlternates', {
|
|
190
|
+
lng: language
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
const alternates = getAlternates(filteredCorrectResponse);
|
|
194
|
+
const {
|
|
195
|
+
responseAreasToBeFilled,
|
|
196
|
+
possibleResponses,
|
|
197
|
+
hasUnplacedChoices
|
|
198
|
+
} = (0, _utils.getCompleteResponseDetails)(filteredCorrectResponse, normalizedQuestion.allowAlternateEnabled ? alternates : [], normalizedQuestion.choices);
|
|
199
|
+
const out = {
|
|
200
|
+
categories: categories || [],
|
|
201
|
+
categoriesPerRow: categoriesPerRow || 2,
|
|
202
|
+
maxChoicesPerCategory,
|
|
203
|
+
correctness: answerCorrectness,
|
|
204
|
+
choices: choices || [],
|
|
205
|
+
choicesLabel: choicesLabel || '',
|
|
206
|
+
choicesPosition,
|
|
207
|
+
disabled: mode !== 'gather',
|
|
208
|
+
feedback: fb,
|
|
209
|
+
lockChoiceOrder,
|
|
210
|
+
prompt: promptEnabled ? prompt : null,
|
|
211
|
+
rowLabels,
|
|
212
|
+
note,
|
|
213
|
+
env,
|
|
214
|
+
showNote: alternates && alternates.length > 0,
|
|
215
|
+
correctResponse: mode === 'evaluate' ? filteredCorrectResponse : undefined,
|
|
216
|
+
language,
|
|
217
|
+
extraCSSRules,
|
|
218
|
+
fontSizeFactor,
|
|
219
|
+
minRowHeight: minRowHeight,
|
|
220
|
+
autoplayAudioEnabled,
|
|
221
|
+
completeAudioEnabled,
|
|
222
|
+
customAudioButton,
|
|
223
|
+
possibleResponses,
|
|
224
|
+
responseAreasToBeFilled,
|
|
225
|
+
hasUnplacedChoices
|
|
226
|
+
};
|
|
227
|
+
if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {
|
|
228
|
+
out.rationale = rationaleEnabled ? rationale : null;
|
|
229
|
+
out.teacherInstructions = teacherInstructionsEnabled ? teacherInstructions : null;
|
|
230
|
+
} else {
|
|
231
|
+
out.rationale = null;
|
|
232
|
+
out.teacherInstructions = null;
|
|
233
|
+
}
|
|
234
|
+
return out;
|
|
288
235
|
};
|
|
289
|
-
|
|
290
236
|
exports.model = model;
|
|
291
|
-
|
|
292
|
-
var outcome = function outcome(question, session, env) {
|
|
237
|
+
const outcome = (question, session, env) => {
|
|
293
238
|
if (env.mode !== 'evaluate') {
|
|
294
239
|
return Promise.reject(new Error('Can not call outcome when mode is not evaluate'));
|
|
295
240
|
} else {
|
|
296
|
-
return new Promise(
|
|
241
|
+
return new Promise(resolve => {
|
|
297
242
|
resolve({
|
|
298
243
|
score: getTotalScore(question, session, env),
|
|
299
|
-
empty: !session || (0, _isEmpty
|
|
244
|
+
empty: !session || (0, _isEmpty.default)(session)
|
|
300
245
|
});
|
|
301
246
|
});
|
|
302
247
|
}
|
|
303
248
|
};
|
|
304
|
-
|
|
305
249
|
exports.outcome = outcome;
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
250
|
+
const createCorrectResponseSession = (question, env) => {
|
|
251
|
+
return new Promise(resolve => {
|
|
252
|
+
const {
|
|
253
|
+
mode,
|
|
254
|
+
role
|
|
255
|
+
} = env || {};
|
|
313
256
|
if (mode !== 'evaluate' && role === 'instructor') {
|
|
314
|
-
|
|
257
|
+
const {
|
|
258
|
+
correctResponse
|
|
259
|
+
} = question;
|
|
315
260
|
resolve({
|
|
316
261
|
answers: correctResponse,
|
|
317
262
|
id: 1
|
|
@@ -320,151 +265,125 @@ var createCorrectResponseSession = function createCorrectResponseSession(questio
|
|
|
320
265
|
return resolve(null);
|
|
321
266
|
}
|
|
322
267
|
});
|
|
323
|
-
}; // remove all html tags
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
exports.createCorrectResponseSession = createCorrectResponseSession;
|
|
327
|
-
|
|
328
|
-
var getInnerText = function getInnerText(html) {
|
|
329
|
-
return (html || '').replaceAll(/<[^>]*>/g, '');
|
|
330
|
-
}; // remove all html tags except img, iframe and source tag for audio
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
var getContent = function getContent(html) {
|
|
334
|
-
return (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');
|
|
335
268
|
};
|
|
336
269
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
270
|
+
// remove all html tags
|
|
271
|
+
exports.createCorrectResponseSession = createCorrectResponseSession;
|
|
272
|
+
const getInnerText = html => (html || '').replaceAll(/<[^>]*>/g, '');
|
|
273
|
+
|
|
274
|
+
// remove all html tags except img, iframe and source tag for audio
|
|
275
|
+
const getContent = html => (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');
|
|
276
|
+
const validate = (model = {}, config = {}) => {
|
|
277
|
+
const {
|
|
278
|
+
categories,
|
|
279
|
+
choices,
|
|
280
|
+
correctResponse,
|
|
281
|
+
maxAnswerChoices
|
|
282
|
+
} = model;
|
|
283
|
+
const {
|
|
284
|
+
minChoices = 1,
|
|
285
|
+
minCategories = 1,
|
|
286
|
+
maxCategories = 12,
|
|
287
|
+
maxLengthPerChoice = 300,
|
|
288
|
+
maxLengthPerCategory = 150
|
|
289
|
+
} = config;
|
|
290
|
+
const reversedChoices = [...(choices || [])].reverse();
|
|
291
|
+
const errors = {};
|
|
292
|
+
const choicesErrors = {};
|
|
293
|
+
const categoriesErrors = {};
|
|
294
|
+
['teacherInstructions', 'prompt', 'rationale'].forEach(field => {
|
|
295
|
+
if (config[field]?.required && !getContent(model[field])) {
|
|
362
296
|
errors[field] = 'This field is required.';
|
|
363
297
|
}
|
|
364
298
|
});
|
|
365
|
-
(categories || []).forEach(
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
299
|
+
(categories || []).forEach(category => {
|
|
300
|
+
const {
|
|
301
|
+
id,
|
|
302
|
+
label
|
|
303
|
+
} = category;
|
|
369
304
|
if (getInnerText(label).length > maxLengthPerCategory) {
|
|
370
|
-
categoriesErrors[id] =
|
|
305
|
+
categoriesErrors[id] = `Category labels should be no more than ${maxLengthPerCategory} characters long.`;
|
|
371
306
|
}
|
|
372
307
|
});
|
|
373
|
-
(reversedChoices || []).forEach(
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
308
|
+
(reversedChoices || []).forEach((choice, index) => {
|
|
309
|
+
const {
|
|
310
|
+
id,
|
|
311
|
+
content
|
|
312
|
+
} = choice;
|
|
377
313
|
if (getInnerText(content).length > maxLengthPerChoice) {
|
|
378
|
-
choicesErrors[id] =
|
|
314
|
+
choicesErrors[id] = `Tokens should be no more than ${maxLengthPerChoice} characters long.`;
|
|
379
315
|
}
|
|
380
|
-
|
|
381
316
|
if (!getContent(content)) {
|
|
382
317
|
choicesErrors[id] = 'Tokens should not be empty.';
|
|
383
318
|
} else {
|
|
384
|
-
|
|
385
|
-
return c.content === content;
|
|
386
|
-
});
|
|
387
|
-
|
|
319
|
+
const identicalAnswer = reversedChoices.slice(index + 1).some(c => c.content === content);
|
|
388
320
|
if (identicalAnswer) {
|
|
389
321
|
choicesErrors[id] = 'Tokens content should be unique.';
|
|
390
322
|
}
|
|
391
323
|
}
|
|
392
324
|
});
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
325
|
+
const nbOfCategories = (categories || []).length;
|
|
326
|
+
const nbOfChoices = (choices || []).length;
|
|
396
327
|
if (nbOfCategories > maxCategories) {
|
|
397
|
-
errors.categoriesError =
|
|
328
|
+
errors.categoriesError = `No more than ${maxCategories} categories should be defined.`;
|
|
398
329
|
} else if (nbOfCategories < minCategories) {
|
|
399
|
-
errors.categoriesError =
|
|
330
|
+
errors.categoriesError = `There should be at least ${minCategories} category defined.`;
|
|
400
331
|
}
|
|
401
|
-
|
|
402
332
|
if (nbOfChoices < minChoices) {
|
|
403
|
-
errors.choicesError =
|
|
333
|
+
errors.choicesError = `There should be at least ${minChoices} choices defined.`;
|
|
404
334
|
} else if (nbOfChoices > maxAnswerChoices) {
|
|
405
|
-
errors.choicesError =
|
|
335
|
+
errors.choicesError = `No more than ${maxAnswerChoices} choices should be defined.`;
|
|
406
336
|
}
|
|
407
|
-
|
|
408
337
|
if (nbOfChoices && nbOfCategories) {
|
|
409
|
-
|
|
410
|
-
(correctResponse || []).forEach(
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
338
|
+
let hasAssociations = false;
|
|
339
|
+
(correctResponse || []).forEach(response => {
|
|
340
|
+
const {
|
|
341
|
+
choices = [],
|
|
342
|
+
alternateResponses = []
|
|
343
|
+
} = response;
|
|
416
344
|
if (choices.length) {
|
|
417
345
|
hasAssociations = true;
|
|
418
346
|
} else {
|
|
419
|
-
alternateResponses.forEach(
|
|
347
|
+
alternateResponses.forEach(alternate => {
|
|
420
348
|
if ((alternate || []).length) {
|
|
421
349
|
hasAssociations = true;
|
|
422
350
|
}
|
|
423
351
|
});
|
|
424
352
|
}
|
|
425
353
|
});
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
(correctResponse || []).forEach(
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
354
|
+
let duplicateAlternateIndex = -1;
|
|
355
|
+
let duplicateCategory = '';
|
|
356
|
+
(correctResponse || []).forEach(response => {
|
|
357
|
+
const {
|
|
358
|
+
choices = [],
|
|
359
|
+
alternateResponses = [],
|
|
360
|
+
category
|
|
361
|
+
} = response;
|
|
435
362
|
if (duplicateAlternateIndex === -1) {
|
|
436
363
|
duplicateAlternateIndex = (0, _utils.isCorrectResponseDuplicated)(choices, alternateResponses);
|
|
437
|
-
|
|
438
364
|
if (duplicateAlternateIndex === -1) {
|
|
439
365
|
duplicateAlternateIndex = (0, _utils.isAlternateDuplicated)(alternateResponses);
|
|
440
366
|
}
|
|
441
|
-
|
|
442
367
|
duplicateCategory = category;
|
|
443
368
|
}
|
|
444
369
|
});
|
|
445
|
-
|
|
446
370
|
if (duplicateAlternateIndex > -1) {
|
|
447
371
|
errors.duplicateAlternate = {
|
|
448
372
|
index: duplicateAlternateIndex,
|
|
449
373
|
category: duplicateCategory
|
|
450
374
|
};
|
|
451
375
|
}
|
|
452
|
-
|
|
453
376
|
if (!hasAssociations) {
|
|
454
377
|
errors.associationError = 'At least one token should be assigned to at least one category.';
|
|
455
378
|
}
|
|
456
379
|
}
|
|
457
|
-
|
|
458
|
-
if (!(0, _isEmpty["default"])(choicesErrors)) {
|
|
380
|
+
if (!(0, _isEmpty.default)(choicesErrors)) {
|
|
459
381
|
errors.choicesErrors = choicesErrors;
|
|
460
382
|
}
|
|
461
|
-
|
|
462
|
-
if (!(0, _isEmpty["default"])(categoriesErrors)) {
|
|
383
|
+
if (!(0, _isEmpty.default)(categoriesErrors)) {
|
|
463
384
|
errors.categoriesErrors = categoriesErrors;
|
|
464
385
|
}
|
|
465
|
-
|
|
466
386
|
return errors;
|
|
467
387
|
};
|
|
468
|
-
|
|
469
388
|
exports.validate = validate;
|
|
470
|
-
//# sourceMappingURL=index.js.map
|
|
389
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfaXNFbXB0eSIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJyZXF1aXJlIiwiX2NhdGVnb3JpemUiLCJfZmVlZGJhY2siLCJfY29udHJvbGxlclV0aWxzIiwiX3RyYW5zbGF0b3IiLCJfZGVmYXVsdHMiLCJfdXRpbHMiLCJ0cmFuc2xhdG9yIiwiVHJhbnNsYXRvciIsImdldFBhcnRpYWxTY29yZSIsImNvcnJlY3RSZXNwb25zZSIsImJ1aWx0Q2F0ZWdvcmllcyIsInBsYWNlbWVudHMiLCJzY29yZSIsInJlZHVjZSIsImFjYyIsImNob2ljZXMiLCJsZW5ndGgiLCJmaWx0ZXIiLCJjaCIsImNvcnJlY3QiLCJtYXhTY29yZSIsImV4dHJhUGxhY2VtZW50cyIsInRvdGFsU2NvcmUiLCJwYXJzZUZsb2F0IiwidG9GaXhlZCIsImV4cG9ydHMiLCJnZXRBbHRlcm5hdGVzIiwibWFwIiwiYyIsImFsdGVybmF0ZVJlc3BvbnNlcyIsImFsdGVybmF0ZSIsImdldFRvdGFsU2NvcmUiLCJxdWVzdGlvbiIsInNlc3Npb24iLCJlbnYiLCJPYmplY3QiLCJrZXlzIiwiY2F0ZWdvcmllcyIsImFuc3dlcnMiLCJidWlsZFN0YXRlIiwiYWx0ZXJuYXRlcyIsImVuYWJsZWQiLCJwYXJ0aWFsU2NvcmluZyIsImdldENvcnJlY3RuZXNzIiwiUHJvbWlzZSIsInJlc29sdmUiLCJtb2RlIiwidW5kZWZpbmVkIiwiY3JlYXRlRGVmYXVsdE1vZGVsIiwibW9kZWwiLCJkZWZhdWx0cyIsIm5vcm1hbGl6ZSIsInVwZGF0ZVNlc3Npb24iLCJub3JtYWxpemVkUXVlc3Rpb24iLCJhbnN3ZXJDb3JyZWN0bmVzcyIsInJvbGUiLCJjYXRlZ29yaWVzUGVyUm93IiwiY2hvaWNlc0xhYmVsIiwiY2hvaWNlc1Bvc2l0aW9uIiwiZmVlZGJhY2siLCJmZWVkYmFja0VuYWJsZWQiLCJwcm9tcHRFbmFibGVkIiwicHJvbXB0Iiwicm93TGFiZWxzIiwicmF0aW9uYWxlRW5hYmxlZCIsInJhdGlvbmFsZSIsInRlYWNoZXJJbnN0cnVjdGlvbnNFbmFibGVkIiwidGVhY2hlckluc3RydWN0aW9ucyIsImxhbmd1YWdlIiwibWF4Q2hvaWNlc1BlckNhdGVnb3J5IiwiZXh0cmFDU1NSdWxlcyIsIm1pblJvd0hlaWdodCIsImZvbnRTaXplRmFjdG9yIiwiYXV0b3BsYXlBdWRpb0VuYWJsZWQiLCJjb21wbGV0ZUF1ZGlvRW5hYmxlZCIsImN1c3RvbUF1ZGlvQnV0dG9uIiwibm90ZSIsImZiIiwibG9ja0Nob2ljZU9yZGVyIiwibG9ja0Nob2ljZXMiLCJmaWx0ZXJlZENvcnJlY3RSZXNwb25zZSIsInJlc3BvbnNlIiwiZmlsdGVyZWRDaG9pY2VzIiwiY2hvaWNlIiwiZ2V0RmVlZGJhY2tGb3JDb3JyZWN0bmVzcyIsImdldFNodWZmbGVkQ2hvaWNlcyIsInQiLCJsbmciLCJyZXNwb25zZUFyZWFzVG9CZUZpbGxlZCIsInBvc3NpYmxlUmVzcG9uc2VzIiwiaGFzVW5wbGFjZWRDaG9pY2VzIiwiZ2V0Q29tcGxldGVSZXNwb25zZURldGFpbHMiLCJhbGxvd0FsdGVybmF0ZUVuYWJsZWQiLCJvdXQiLCJjb3JyZWN0bmVzcyIsImRpc2FibGVkIiwic2hvd05vdGUiLCJvdXRjb21lIiwicmVqZWN0IiwiRXJyb3IiLCJlbXB0eSIsImlzRW1wdHkiLCJjcmVhdGVDb3JyZWN0UmVzcG9uc2VTZXNzaW9uIiwiaWQiLCJnZXRJbm5lclRleHQiLCJodG1sIiwicmVwbGFjZUFsbCIsImdldENvbnRlbnQiLCJyZXBsYWNlIiwidmFsaWRhdGUiLCJjb25maWciLCJtYXhBbnN3ZXJDaG9pY2VzIiwibWluQ2hvaWNlcyIsIm1pbkNhdGVnb3JpZXMiLCJtYXhDYXRlZ29yaWVzIiwibWF4TGVuZ3RoUGVyQ2hvaWNlIiwibWF4TGVuZ3RoUGVyQ2F0ZWdvcnkiLCJyZXZlcnNlZENob2ljZXMiLCJyZXZlcnNlIiwiZXJyb3JzIiwiY2hvaWNlc0Vycm9ycyIsImNhdGVnb3JpZXNFcnJvcnMiLCJmb3JFYWNoIiwiZmllbGQiLCJyZXF1aXJlZCIsImNhdGVnb3J5IiwibGFiZWwiLCJpbmRleCIsImNvbnRlbnQiLCJpZGVudGljYWxBbnN3ZXIiLCJzbGljZSIsInNvbWUiLCJuYk9mQ2F0ZWdvcmllcyIsIm5iT2ZDaG9pY2VzIiwiY2F0ZWdvcmllc0Vycm9yIiwiY2hvaWNlc0Vycm9yIiwiaGFzQXNzb2NpYXRpb25zIiwiZHVwbGljYXRlQWx0ZXJuYXRlSW5kZXgiLCJkdXBsaWNhdGVDYXRlZ29yeSIsImlzQ29ycmVjdFJlc3BvbnNlRHVwbGljYXRlZCIsImlzQWx0ZXJuYXRlRHVwbGljYXRlZCIsImR1cGxpY2F0ZUFsdGVybmF0ZSIsImFzc29jaWF0aW9uRXJyb3IiXSwic291cmNlcyI6WyIuLi9zcmMvaW5kZXguanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGlzRW1wdHkgZnJvbSAnbG9kYXNoL2lzRW1wdHknO1xuaW1wb3J0IHsgYnVpbGRTdGF0ZSwgc2NvcmUgfSBmcm9tICdAcGllLWxpYi9jYXRlZ29yaXplJztcbmltcG9ydCB7IGdldEZlZWRiYWNrRm9yQ29ycmVjdG5lc3MgfSBmcm9tICdAcGllLWxpYi9mZWVkYmFjayc7XG5pbXBvcnQgeyBsb2NrQ2hvaWNlcywgZ2V0U2h1ZmZsZWRDaG9pY2VzLCBwYXJ0aWFsU2NvcmluZyB9IGZyb20gJ0BwaWUtbGliL2NvbnRyb2xsZXItdXRpbHMnO1xuaW1wb3J0IFRyYW5zbGF0b3IgZnJvbSAnQHBpZS1saWIvdHJhbnNsYXRvcic7XG5cbmNvbnN0IHsgdHJhbnNsYXRvciB9ID0gVHJhbnNsYXRvcjtcbmltcG9ydCBkZWZhdWx0cyBmcm9tICcuL2RlZmF1bHRzJztcbmltcG9ydCB7IGdldENvbXBsZXRlUmVzcG9uc2VEZXRhaWxzLCBpc0FsdGVybmF0ZUR1cGxpY2F0ZWQsIGlzQ29ycmVjdFJlc3BvbnNlRHVwbGljYXRlZCB9IGZyb20gJy4vdXRpbHMnO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuXG5leHBvcnQgeyBzY29yZSB9O1xuXG5leHBvcnQgY29uc3QgZ2V0UGFydGlhbFNjb3JlID0gKGNvcnJlY3RSZXNwb25zZSwgYnVpbHRDYXRlZ29yaWVzKSA9PiB7XG4gIC8vIGluIHRoZSByZXN1bHRlZCBiZXN0IHNjZW5hcmlvIHdlIG1ha2UgYSBzdW0gd2l0aCBhbGwgdGhlIGNvcnJlY3QgcmVzcG9uc2VzXG4gIC8vIGFuZCBhbGwgdGhlIHBsYWNlbWVudHNcbiAgY29uc3QgeyBwbGFjZW1lbnRzLCBzY29yZSB9ID0gYnVpbHRDYXRlZ29yaWVzLnJlZHVjZShcbiAgICAoYWNjLCB7IGNob2ljZXMgPSBbXSB9KSA9PiAoe1xuICAgICAgcGxhY2VtZW50czogYWNjLnBsYWNlbWVudHMgKyBjaG9pY2VzLmxlbmd0aCxcbiAgICAgIHNjb3JlOiBhY2Muc2NvcmUgKyBjaG9pY2VzLmZpbHRlcigoY2gpID0+IGNoLmNvcnJlY3QpLmxlbmd0aCxcbiAgICB9KSxcbiAgICB7IHBsYWNlbWVudHM6IDAsIHNjb3JlOiAwIH0sXG4gICk7XG5cbiAgLy8gaW4gdGhlIGNvcnJlY3QgcmVzcG9uc2UsIHdlIG1ha2UgYSBzdW0gb2YgdGhlIG1heCBwb3NzaWJsZSBzY29yZVxuICBjb25zdCB7IG1heFNjb3JlIH0gPSBjb3JyZWN0UmVzcG9uc2UucmVkdWNlKFxuICAgIChhY2MsIHsgY2hvaWNlcyB9KSA9PiAoe1xuICAgICAgbWF4U2NvcmU6IGFjYy5tYXhTY29yZSArIGNob2ljZXMubGVuZ3RoLFxuICAgIH0pLFxuICAgIHsgbWF4U2NvcmU6IDAgfSxcbiAgKTtcblxuICAvLyBpZiB0aGVyZSBhcmUgYW55IGV4dHJhIHBsYWNlbWVudHMsIHdlIHN1YnRyYWN0IGZyb20gdGhlIG9idGFpbmVkIHNjb3JlXG4gIGNvbnN0IGV4dHJhUGxhY2VtZW50cyA9IHBsYWNlbWVudHMgPiBtYXhTY29yZSA/IHBsYWNlbWVudHMgLSBtYXhTY29yZSA6IDA7XG4gIGNvbnN0IHRvdGFsU2NvcmUgPSAoc2NvcmUgLSBleHRyYVBsYWNlbWVudHMpIC8gbWF4U2NvcmU7XG5cbiAgcmV0dXJuIHRvdGFsU2NvcmUgPCAwID8gMCA6IHBhcnNlRmxvYXQodG90YWxTY29yZS50b0ZpeGVkKDIpKTtcbn07XG5cbmNvbnN0IGdldEFsdGVybmF0ZXMgPSAoY29ycmVjdFJlc3BvbnNlKSA9PlxuICBjb3JyZWN0UmVzcG9uc2UubWFwKChjKSA9PiBjLmFsdGVybmF0ZVJlc3BvbnNlcykuZmlsdGVyKChhbHRlcm5hdGUpID0+IGFsdGVybmF0ZSk7XG5cbmV4cG9ydCBjb25zdCBnZXRUb3RhbFNjb3JlID0gKHF1ZXN0aW9uLCBzZXNzaW9uLCBlbnYpID0+IHtcbiAgaWYgKCFzZXNzaW9uKSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICBpZiAoT2JqZWN0LmtleXMoc2Vzc2lvbikubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cbiAgY29uc3QgeyBjYXRlZ29yaWVzLCBjaG9pY2VzIH0gPSBxdWVzdGlvbiB8fCB7fTtcbiAgbGV0IHsgY29ycmVjdFJlc3BvbnNlIH0gPSBxdWVzdGlvbiB8fCB7fTtcbiAgbGV0IHsgYW5zd2VycyB9ID0gc2Vzc2lvbiB8fCB7fTtcbiAgYW5zd2VycyA9IGFuc3dlcnMgfHwgW107XG4gIGNvcnJlY3RSZXNwb25zZSA9IGNvcnJlY3RSZXNwb25zZSB8fCBbXTtcblxuICAvLyB0aGlzIGZ1bmN0aW9uIGlzIHVzZWQgaW4gcGllLXVpL2NhdGVnb3JpemUgYXMgd2VsbCwgaW4gb3JkZXIgdG8gZ2V0IHRoZSBiZXN0IHNjZW5hcmlvXG4gIC8vIHNvIHdlIGdldCB0aGUgYmVzdCBzY2VuYXJpbyBhbmQgY2FsY3VsYXRlIHRoZSBzY29yZVxuICBjb25zdCB7IGNhdGVnb3JpZXM6IGJ1aWx0Q2F0ZWdvcmllcywgY29ycmVjdCB9ID0gYnVpbGRTdGF0ZShjYXRlZ29yaWVzLCBjaG9pY2VzLCBhbnN3ZXJzLCBjb3JyZWN0UmVzcG9uc2UpO1xuXG4gIGNvbnN0IGFsdGVybmF0ZXMgPSBnZXRBbHRlcm5hdGVzKGNvcnJlY3RSZXNwb25zZSk7XG4gIGNvbnN0IGVuYWJsZWQgPSBwYXJ0aWFsU2NvcmluZy5lbmFibGVkKHF1ZXN0aW9uLCBlbnYpO1xuXG4gIC8vIGlmIHRoZXJlIGFyZSBhbnkgYWx0ZXJuYXRlcywgdGhlcmUgd2lsbCBiZSBubyBwYXJ0aWFsIHNjb3JpbmchXG4gIGlmIChlbmFibGVkICYmICFhbHRlcm5hdGVzLmxlbmd0aCkge1xuICAgIC8vIHdlIGFwcGx5IHBhcnRpYWwgc2NvcmluZ1xuICAgIHJldHVybiBnZXRQYXJ0aWFsU2NvcmUoY29ycmVjdFJlc3BvbnNlLCBidWlsdENhdGVnb3JpZXMpO1xuICB9XG5cbiAgLy8gZWxzZSB3ZSBhcHBseSBkaWNob3RvbW91c1xuICByZXR1cm4gY29ycmVjdCA/IDEgOiAwO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldENvcnJlY3RuZXNzID0gKHF1ZXN0aW9uLCBzZXNzaW9uLCBlbnYpID0+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgaWYgKGVudi5tb2RlID09PSAnZXZhbHVhdGUnKSB7XG4gICAgICBjb25zdCBzY29yZSA9IGdldFRvdGFsU2NvcmUocXVlc3Rpb24sIHNlc3Npb24sIGVudik7XG4gICAgICBpZiAoc2NvcmUgPT09IDEpIHtcbiAgICAgICAgcmVzb2x2ZSgnY29ycmVjdCcpO1xuICAgICAgfSBlbHNlIGlmIChzY29yZSA9PT0gMCkge1xuICAgICAgICByZXNvbHZlKCdpbmNvcnJlY3QnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc29sdmUoJ3BhcnRpYWxseS1jb3JyZWN0Jyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc29sdmUodW5kZWZpbmVkKTtcbiAgICB9XG4gIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZURlZmF1bHRNb2RlbCA9IChtb2RlbCA9IHt9KSA9PlxuICBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgIHJlc29sdmUoe1xuICAgICAgLi4uZGVmYXVsdHMsXG4gICAgICAuLi5tb2RlbCxcbiAgICB9KTtcbiAgfSk7XG5cbmV4cG9ydCBjb25zdCBub3JtYWxpemUgPSAocXVlc3Rpb24pID0+ICh7IC4uLmRlZmF1bHRzLCAuLi5xdWVzdGlvbiB9KTtcblxuLyoqXG4gKlxuICogQHBhcmFtIHsqfSBxdWVzdGlvblxuICogQHBhcmFtIHsqfSBzZXNzaW9uXG4gKiBAcGFyYW0geyp9IGVudlxuICogQHBhcmFtIHsqfSB1cGRhdGVTZXNzaW9uIC0gb3B0aW9uYWwgLSBhIGZ1bmN0aW9uIHRoYXQgd2lsbCBzZXQgdGhlIHByb3BlcnRpZXMgcGFzc2VkIGludG8gaXQgb24gdGhlIHNlc3Npb24uXG4gKi9cbmV4cG9ydCBjb25zdCBtb2RlbCA9IGFzeW5jIChxdWVzdGlvbiwgc2Vzc2lvbiwgZW52LCB1cGRhdGVTZXNzaW9uKSA9PiB7XG4gIGNvbnN0IG5vcm1hbGl6ZWRRdWVzdGlvbiA9IG5vcm1hbGl6ZShxdWVzdGlvbik7XG4gIGNvbnN0IGFuc3dlckNvcnJlY3RuZXNzID0gYXdhaXQgZ2V0Q29ycmVjdG5lc3Mobm9ybWFsaXplZFF1ZXN0aW9uLCBzZXNzaW9uLCBlbnYpO1xuXG4gIGNvbnN0IHsgbW9kZSwgcm9sZSB9ID0gZW52IHx8IHt9O1xuXG4gIGNvbnN0IHtcbiAgICBjYXRlZ29yaWVzLFxuICAgIGNhdGVnb3JpZXNQZXJSb3csXG4gICAgY2hvaWNlc0xhYmVsLFxuICAgIGNob2ljZXNQb3NpdGlvbixcbiAgICBjb3JyZWN0UmVzcG9uc2UsXG4gICAgZmVlZGJhY2ssXG4gICAgZmVlZGJhY2tFbmFibGVkLFxuICAgIHByb21wdEVuYWJsZWQsXG4gICAgcHJvbXB0LFxuICAgIHJvd0xhYmVscyxcbiAgICByYXRpb25hbGVFbmFibGVkLFxuICAgIHJhdGlvbmFsZSxcbiAgICB0ZWFjaGVySW5zdHJ1Y3Rpb25zRW5hYmxlZCxcbiAgICB0ZWFjaGVySW5zdHJ1Y3Rpb25zLFxuICAgIGxhbmd1YWdlLFxuICAgIG1heENob2ljZXNQZXJDYXRlZ29yeSxcbiAgICBleHRyYUNTU1J1bGVzLFxuICAgIG1pblJvd0hlaWdodCxcbiAgICBmb250U2l6ZUZhY3RvcixcbiAgICBhdXRvcGxheUF1ZGlvRW5hYmxlZCxcbiAgICBjb21wbGV0ZUF1ZGlvRW5hYmxlZCxcbiAgICBjdXN0b21BdWRpb0J1dHRvbixcbiAgfSA9IG5vcm1hbGl6ZWRRdWVzdGlvbjtcbiAgbGV0IHsgY2hvaWNlcywgbm90ZSB9ID0gbm9ybWFsaXplZFF1ZXN0aW9uO1xuICBsZXQgZmI7XG5cbiAgY29uc3QgbG9ja0Nob2ljZU9yZGVyID0gbG9ja0Nob2ljZXMobm9ybWFsaXplZFF1ZXN0aW9uLCBzZXNzaW9uLCBlbnYpO1xuXG4gIGNvbnN0IGZpbHRlcmVkQ29ycmVjdFJlc3BvbnNlID0gY29ycmVjdFJlc3BvbnNlLm1hcCgocmVzcG9uc2UpID0+IHtcbiAgICBjb25zdCBmaWx0ZXJlZENob2ljZXMgPSAocmVzcG9uc2UuY2hvaWNlcyB8fCBbXSkuZmlsdGVyKChjaG9pY2UpID0+IGNob2ljZSAhPT0gJ251bGwnKTtcbiAgICByZXR1cm4geyAuLi5yZXNwb25zZSwgY2hvaWNlczogZmlsdGVyZWRDaG9pY2VzIH07XG4gIH0pO1xuXG4gIGlmIChtb2RlID09PSAnZXZhbHVhdGUnICYmIGZlZWRiYWNrRW5hYmxlZCkge1xuICAgIGZiID0gYXdhaXQgZ2V0RmVlZGJhY2tGb3JDb3JyZWN0bmVzcyhhbnN3ZXJDb3JyZWN0bmVzcywgZmVlZGJhY2spO1xuICB9XG5cbiAgaWYgKCFsb2NrQ2hvaWNlT3JkZXIpIHtcbiAgICBjaG9pY2VzID0gYXdhaXQgZ2V0U2h1ZmZsZWRDaG9pY2VzKGNob2ljZXMsIHNlc3Npb24sIHVwZGF0ZVNlc3Npb24sICdpZCcpO1xuICB9XG5cbiAgaWYgKCFub3RlKSB7XG4gICAgbm90ZSA9IHRyYW5zbGF0b3IudCgnY29tbW9uOmNvbW1vbkNvcnJlY3RBbnN3ZXJXaXRoQWx0ZXJuYXRlcycsIHsgbG5nOiBsYW5ndWFnZSB9KTtcbiAgfVxuXG4gIGNvbnN0IGFsdGVybmF0ZXMgPSBnZXRBbHRlcm5hdGVzKGZpbHRlcmVkQ29ycmVjdFJlc3BvbnNlKTtcbiAgY29uc3QgeyByZXNwb25zZUFyZWFzVG9CZUZpbGxlZCwgcG9zc2libGVSZXNwb25zZXMsIGhhc1VucGxhY2VkQ2hvaWNlcyB9ID0gZ2V0Q29tcGxldGVSZXNwb25zZURldGFpbHMoXG4gICAgZmlsdGVyZWRDb3JyZWN0UmVzcG9uc2UsXG4gICAgbm9ybWFsaXplZFF1ZXN0aW9uLmFsbG93QWx0ZXJuYXRlRW5hYmxlZCA/IGFsdGVybmF0ZXMgOiBbXSxcbiAgICBub3JtYWxpemVkUXVlc3Rpb24uY2hvaWNlcyxcbiAgKTtcbiAgY29uc3Qgb3V0ID0ge1xuICAgIGNhdGVnb3JpZXM6IGNhdGVnb3JpZXMgfHwgW10sXG4gICAgY2F0ZWdvcmllc1BlclJvdzogY2F0ZWdvcmllc1BlclJvdyB8fCAyLFxuICAgIG1heENob2ljZXNQZXJDYXRlZ29yeSxcbiAgICBjb3JyZWN0bmVzczogYW5zd2VyQ29ycmVjdG5lc3MsXG4gICAgY2hvaWNlczogY2hvaWNlcyB8fCBbXSxcbiAgICBjaG9pY2VzTGFiZWw6IGNob2ljZXNMYWJlbCB8fCAnJyxcbiAgICBjaG9pY2VzUG9zaXRpb24sXG4gICAgZGlzYWJsZWQ6IG1vZGUgIT09ICdnYXRoZXInLFxuICAgIGZlZWRiYWNrOiBmYixcbiAgICBsb2NrQ2hvaWNlT3JkZXIsXG4gICAgcHJvbXB0OiBwcm9tcHRFbmFibGVkID8gcHJvbXB0IDogbnVsbCxcbiAgICByb3dMYWJlbHMsXG4gICAgbm90ZSxcbiAgICBlbnYsXG4gICAgc2hvd05vdGU6IGFsdGVybmF0ZXMgJiYgYWx0ZXJuYXRlcy5sZW5ndGggPiAwLFxuICAgIGNvcnJlY3RSZXNwb25zZTogbW9kZSA9PT0gJ2V2YWx1YXRlJyA/IGZpbHRlcmVkQ29ycmVjdFJlc3BvbnNlIDogdW5kZWZpbmVkLFxuICAgIGxhbmd1YWdlLFxuICAgIGV4dHJhQ1NTUnVsZXMsXG4gICAgZm9udFNpemVGYWN0b3IsXG4gICAgbWluUm93SGVpZ2h0OiBtaW5Sb3dIZWlnaHQsXG4gICAgYXV0b3BsYXlBdWRpb0VuYWJsZWQsXG4gICAgY29tcGxldGVBdWRpb0VuYWJsZWQsXG4gICAgY3VzdG9tQXVkaW9CdXR0b24sXG4gICAgcG9zc2libGVSZXNwb25zZXMsXG4gICAgcmVzcG9uc2VBcmVhc1RvQmVGaWxsZWQsXG4gICAgaGFzVW5wbGFjZWRDaG9pY2VzLFxuICB9O1xuXG4gIGlmIChyb2xlID09PSAnaW5zdHJ1Y3RvcicgJiYgKG1vZGUgPT09ICd2aWV3JyB8fCBtb2RlID09PSAnZXZhbHVhdGUnKSkge1xuICAgIG91dC5yYXRpb25hbGUgPSByYXRpb25hbGVFbmFibGVkID8gcmF0aW9uYWxlIDogbnVsbDtcbiAgICBvdXQudGVhY2hlckluc3RydWN0aW9ucyA9IHRlYWNoZXJJbnN0cnVjdGlvbnNFbmFibGVkID8gdGVhY2hlckluc3RydWN0aW9ucyA6IG51bGw7XG4gIH0gZWxzZSB7XG4gICAgb3V0LnJhdGlvbmFsZSA9IG51bGw7XG4gICAgb3V0LnRlYWNoZXJJbnN0cnVjdGlvbnMgPSBudWxsO1xuICB9XG5cbiAgcmV0dXJuIG91dDtcbn07XG5cbmV4cG9ydCBjb25zdCBvdXRjb21lID0gKHF1ZXN0aW9uLCBzZXNzaW9uLCBlbnYpID0+IHtcbiAgaWYgKGVudi5tb2RlICE9PSAnZXZhbHVhdGUnKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcignQ2FuIG5vdCBjYWxsIG91dGNvbWUgd2hlbiBtb2RlIGlzIG5vdCBldmFsdWF0ZScpKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgIHJlc29sdmUoe1xuICAgICAgICBzY29yZTogZ2V0VG90YWxTY29yZShxdWVzdGlvbiwgc2Vzc2lvbiwgZW52KSxcbiAgICAgICAgZW1wdHk6ICFzZXNzaW9uIHx8IGlzRW1wdHkoc2Vzc2lvbiksXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUNvcnJlY3RSZXNwb25zZVNlc3Npb24gPSAocXVlc3Rpb24sIGVudikgPT4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICBjb25zdCB7IG1vZGUsIHJvbGUgfSA9IGVudiB8fCB7fTtcblxuICAgIGlmIChtb2RlICE9PSAnZXZhbHVhdGUnICYmIHJvbGUgPT09ICdpbnN0cnVjdG9yJykge1xuICAgICAgY29uc3QgeyBjb3JyZWN0UmVzcG9uc2UgfSA9IHF1ZXN0aW9uO1xuXG4gICAgICByZXNvbHZlKHsgYW5zd2VyczogY29ycmVjdFJlc3BvbnNlLCBpZDogMSB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJlc29sdmUobnVsbCk7XG4gICAgfVxuICB9KTtcbn07XG5cbi8vIHJlbW92ZSBhbGwgaHRtbCB0YWdzXG5jb25zdCBnZXRJbm5lclRleHQgPSAoaHRtbCkgPT4gKGh0bWwgfHwgJycpLnJlcGxhY2VBbGwoLzxbXj5dKj4vZywgJycpO1xuXG4vLyByZW1vdmUgYWxsIGh0bWwgdGFncyBleGNlcHQgaW1nLCBpZnJhbWUgYW5kIHNvdXJjZSB0YWcgZm9yIGF1ZGlvXG5jb25zdCBnZXRDb250ZW50ID0gKGh0bWwpID0+IChodG1sIHx8ICcnKS5yZXBsYWNlKC8oPCg/IWltZ3xpZnJhbWV8c291cmNlKShbXj5dKyk+KS9naSwgJycpO1xuXG5leHBvcnQgY29uc3QgdmFsaWRhdGUgPSAobW9kZWwgPSB7fSwgY29uZmlnID0ge30pID0+IHtcbiAgY29uc3QgeyBjYXRlZ29yaWVzLCBjaG9pY2VzLCBjb3JyZWN0UmVzcG9uc2UsIG1heEFuc3dlckNob2ljZXMgfSA9IG1vZGVsO1xuICBjb25zdCB7XG4gICAgbWluQ2hvaWNlcyA9IDEsXG4gICAgbWluQ2F0ZWdvcmllcyA9IDEsXG4gICAgbWF4Q2F0ZWdvcmllcyA9IDEyLFxuICAgIG1heExlbmd0aFBlckNob2ljZSA9IDMwMCxcbiAgICBtYXhMZW5ndGhQZXJDYXRlZ29yeSA9IDE1MCxcbiAgfSA9IGNvbmZpZztcbiAgY29uc3QgcmV2ZXJzZWRDaG9pY2VzID0gWy4uLihjaG9pY2VzIHx8IFtdKV0ucmV2ZXJzZSgpO1xuICBjb25zdCBlcnJvcnMgPSB7fTtcbiAgY29uc3QgY2hvaWNlc0Vycm9ycyA9IHt9O1xuICBjb25zdCBjYXRlZ29yaWVzRXJyb3JzID0ge307XG5cbiAgWyd0ZWFjaGVySW5zdHJ1Y3Rpb25zJywgJ3Byb21wdCcsICdyYXRpb25hbGUnXS5mb3JFYWNoKChmaWVsZCkgPT4ge1xuICAgIGlmIChjb25maWdbZmllbGRdPy5yZXF1aXJlZCAmJiAhZ2V0Q29udGVudChtb2RlbFtmaWVsZF0pKSB7XG4gICAgICBlcnJvcnNbZmllbGRdID0gJ1RoaXMgZmllbGQgaXMgcmVxdWlyZWQuJztcbiAgICB9XG4gIH0pO1xuXG4gIChjYXRlZ29yaWVzIHx8IFtdKS5mb3JFYWNoKChjYXRlZ29yeSkgPT4ge1xuICAgIGNvbnN0IHsgaWQsIGxhYmVsIH0gPSBjYXRlZ29yeTtcblxuICAgIGlmIChnZXRJbm5lclRleHQobGFiZWwpLmxlbmd0aCA+IG1heExlbmd0aFBlckNhdGVnb3J5KSB7XG4gICAgICBjYXRlZ29yaWVzRXJyb3JzW2lkXSA9IGBDYXRlZ29yeSBsYWJlbHMgc2hvdWxkIGJlIG5vIG1vcmUgdGhhbiAke21heExlbmd0aFBlckNhdGVnb3J5fSBjaGFyYWN0ZXJzIGxvbmcuYDtcbiAgICB9XG4gIH0pO1xuXG4gIChyZXZlcnNlZENob2ljZXMgfHwgW10pLmZvckVhY2goKGNob2ljZSwgaW5kZXgpID0+IHtcbiAgICBjb25zdCB7IGlkLCBjb250ZW50IH0gPSBjaG9pY2U7XG5cbiAgICBpZiAoZ2V0SW5uZXJUZXh0KGNvbnRlbnQpLmxlbmd0aCA+IG1heExlbmd0aFBlckNob2ljZSkge1xuICAgICAgY2hvaWNlc0Vycm9yc1tpZF0gPSBgVG9rZW5zIHNob3VsZCBiZSBubyBtb3JlIHRoYW4gJHttYXhMZW5ndGhQZXJDaG9pY2V9IGNoYXJhY3RlcnMgbG9uZy5gO1xuICAgIH1cblxuICAgIGlmICghZ2V0Q29udGVudChjb250ZW50KSkge1xuICAgICAgY2hvaWNlc0Vycm9yc1tpZF0gPSAnVG9rZW5zIHNob3VsZCBub3QgYmUgZW1wdHkuJztcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgaWRlbnRpY2FsQW5zd2VyID0gcmV2ZXJzZWRDaG9pY2VzLnNsaWNlKGluZGV4ICsgMSkuc29tZSgoYykgPT4gYy5jb250ZW50ID09PSBjb250ZW50KTtcblxuICAgICAgaWYgKGlkZW50aWNhbEFuc3dlcikge1xuICAgICAgICBjaG9pY2VzRXJyb3JzW2lkXSA9ICdUb2tlbnMgY29udGVudCBzaG91bGQgYmUgdW5pcXVlLic7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBjb25zdCBuYk9mQ2F0ZWdvcmllcyA9IChjYXRlZ29yaWVzIHx8IFtdKS5sZW5ndGg7XG4gIGNvbnN0IG5iT2ZDaG9pY2VzID0gKGNob2ljZXMgfHwgW10pLmxlbmd0aDtcblxuICBpZiAobmJPZkNhdGVnb3JpZXMgPiBtYXhDYXRlZ29yaWVzKSB7XG4gICAgZXJyb3JzLmNhdGVnb3JpZXNFcnJvciA9IGBObyBtb3JlIHRoYW4gJHttYXhDYXRlZ29yaWVzfSBjYXRlZ29yaWVzIHNob3VsZCBiZSBkZWZpbmVkLmA7XG4gIH0gZWxzZSBpZiAobmJPZkNhdGVnb3JpZXMgPCBtaW5DYXRlZ29yaWVzKSB7XG4gICAgZXJyb3JzLmNhdGVnb3JpZXNFcnJvciA9IGBUaGVyZSBzaG91bGQgYmUgYXQgbGVhc3QgJHttaW5DYXRlZ29yaWVzfSBjYXRlZ29yeSBkZWZpbmVkLmA7XG4gIH1cblxuICBpZiAobmJPZkNob2ljZXMgPCBtaW5DaG9pY2VzKSB7XG4gICAgZXJyb3JzLmNob2ljZXNFcnJvciA9IGBUaGVyZSBzaG91bGQgYmUgYXQgbGVhc3QgJHttaW5DaG9pY2VzfSBjaG9pY2VzIGRlZmluZWQuYDtcbiAgfSBlbHNlIGlmIChuYk9mQ2hvaWNlcyA+IG1heEFuc3dlckNob2ljZXMpIHtcbiAgICBlcnJvcnMuY2hvaWNlc0Vycm9yID0gYE5vIG1vcmUgdGhhbiAke21heEFuc3dlckNob2ljZXN9IGNob2ljZXMgc2hvdWxkIGJlIGRlZmluZWQuYDtcbiAgfVxuXG4gIGlmIChuYk9mQ2hvaWNlcyAmJiBuYk9mQ2F0ZWdvcmllcykge1xuICAgIGxldCBoYXNBc3NvY2lhdGlvbnMgPSBmYWxzZTtcblxuICAgIChjb3JyZWN0UmVzcG9uc2UgfHwgW10pLmZvckVhY2goKHJlc3BvbnNlKSA9PiB7XG4gICAgICBjb25zdCB7IGNob2ljZXMgPSBbXSwgYWx0ZXJuYXRlUmVzcG9uc2VzID0gW10gfSA9IHJlc3BvbnNlO1xuXG4gICAgICBpZiAoY2hvaWNlcy5sZW5ndGgpIHtcbiAgICAgICAgaGFzQXNzb2NpYXRpb25zID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFsdGVybmF0ZVJlc3BvbnNlcy5mb3JFYWNoKChhbHRlcm5hdGUpID0+IHtcbiAgICAgICAgICBpZiAoKGFsdGVybmF0ZSB8fCBbXSkubGVuZ3RoKSB7XG4gICAgICAgICAgICBoYXNBc3NvY2lhdGlvbnMgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBsZXQgZHVwbGljYXRlQWx0ZXJuYXRlSW5kZXggPSAtMTtcbiAgICBsZXQgZHVwbGljYXRlQ2F0ZWdvcnkgPSAnJztcbiAgICAoY29ycmVjdFJlc3BvbnNlIHx8IFtdKS5mb3JFYWNoKChyZXNwb25zZSkgPT4ge1xuICAgICAgY29uc3QgeyBjaG9pY2VzID0gW10sIGFsdGVybmF0ZVJlc3BvbnNlcyA9IFtdLCBjYXRlZ29yeSB9ID0gcmVzcG9uc2U7XG5cbiAgICAgIGlmIChkdXBsaWNhdGVBbHRlcm5hdGVJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgZHVwbGljYXRlQWx0ZXJuYXRlSW5kZXggPSBpc0NvcnJlY3RSZXNwb25zZUR1cGxpY2F0ZWQoY2hvaWNlcywgYWx0ZXJuYXRlUmVzcG9uc2VzKTtcblxuICAgICAgICBpZiAoZHVwbGljYXRlQWx0ZXJuYXRlSW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgZHVwbGljYXRlQWx0ZXJuYXRlSW5kZXggPSBpc0FsdGVybmF0ZUR1cGxpY2F0ZWQoYWx0ZXJuYXRlUmVzcG9uc2VzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGR1cGxpY2F0ZUNhdGVnb3J5ID0gY2F0ZWdvcnk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAoZHVwbGljYXRlQWx0ZXJuYXRlSW5kZXggPiAtMSkge1xuICAgICAgZXJyb3JzLmR1cGxpY2F0ZUFsdGVybmF0ZSA9IHsgaW5kZXg6IGR1cGxpY2F0ZUFsdGVybmF0ZUluZGV4LCBjYXRlZ29yeTogZHVwbGljYXRlQ2F0ZWdvcnkgfTtcbiAgICB9XG5cbiAgICBpZiAoIWhhc0Fzc29jaWF0aW9ucykge1xuICAgICAgZXJyb3JzLmFzc29jaWF0aW9uRXJyb3IgPSAnQXQgbGVhc3Qgb25lIHRva2VuIHNob3VsZCBiZSBhc3NpZ25lZCB0byBhdCBsZWFzdCBvbmUgY2F0ZWdvcnkuJztcbiAgICB9XG4gIH1cblxuICBpZiAoIWlzRW1wdHkoY2hvaWNlc0Vycm9ycykpIHtcbiAgICBlcnJvcnMuY2hvaWNlc0Vycm9ycyA9IGNob2ljZXNFcnJvcnM7XG4gIH1cblxuICBpZiAoIWlzRW1wdHkoY2F0ZWdvcmllc0Vycm9ycykpIHtcbiAgICBlcnJvcnMuY2F0ZWdvcmllc0Vycm9ycyA9IGNhdGVnb3JpZXNFcnJvcnM7XG4gIH1cblxuICByZXR1cm4gZXJyb3JzO1xufTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUFBQSxJQUFBQSxRQUFBLEdBQUFDLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxXQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxTQUFBLEdBQUFGLE9BQUE7QUFDQSxJQUFBRyxnQkFBQSxHQUFBSCxPQUFBO0FBQ0EsSUFBQUksV0FBQSxHQUFBTCxzQkFBQSxDQUFBQyxPQUFBO0FBR0EsSUFBQUssU0FBQSxHQUFBTixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQU0sTUFBQSxHQUFBTixPQUFBO0FBRkEsTUFBTTtFQUFFTztBQUFXLENBQUMsR0FBR0MsbUJBQVU7O0FBSWpDOztBQUlPLE1BQU1DLGVBQWUsR0FBR0EsQ0FBQ0MsZUFBZSxFQUFFQyxlQUFlLEtBQUs7RUFDbkU7RUFDQTtFQUNBLE1BQU07SUFBRUMsVUFBVTtJQUFFQztFQUFNLENBQUMsR0FBR0YsZUFBZSxDQUFDRyxNQUFNLENBQ2xELENBQUNDLEdBQUcsRUFBRTtJQUFFQyxPQUFPLEdBQUc7RUFBRyxDQUFDLE1BQU07SUFDMUJKLFVBQVUsRUFBRUcsR0FBRyxDQUFDSCxVQUFVLEdBQUdJLE9BQU8sQ0FBQ0MsTUFBTTtJQUMzQ0osS0FBSyxFQUFFRSxHQUFHLENBQUNGLEtBQUssR0FBR0csT0FBTyxDQUFDRSxNQUFNLENBQUVDLEVBQUUsSUFBS0EsRUFBRSxDQUFDQyxPQUFPLENBQUMsQ0FBQ0g7RUFDeEQsQ0FBQyxDQUFDLEVBQ0Y7SUFBRUwsVUFBVSxFQUFFLENBQUM7SUFBRUMsS0FBSyxFQUFFO0VBQUUsQ0FDNUIsQ0FBQzs7RUFFRDtFQUNBLE1BQU07SUFBRVE7RUFBUyxDQUFDLEdBQUdYLGVBQWUsQ0FBQ0ksTUFBTSxDQUN6QyxDQUFDQyxHQUFHLEVBQUU7SUFBRUM7RUFBUSxDQUFDLE1BQU07SUFDckJLLFFBQVEsRUFBRU4sR0FBRyxDQUFDTSxRQUFRLEdBQUdMLE9BQU8sQ0FBQ0M7RUFDbkMsQ0FBQyxDQUFDLEVBQ0Y7SUFBRUksUUFBUSxFQUFFO0VBQUUsQ0FDaEIsQ0FBQzs7RUFFRDtFQUNBLE1BQU1DLGVBQWUsR0FBR1YsVUFBVSxHQUFHUyxRQUFRLEdBQUdULFVBQVUsR0FBR1MsUUFBUSxHQUFHLENBQUM7RUFDekUsTUFBTUUsVUFBVSxHQUFHLENBQUNWLEtBQUssR0FBR1MsZUFBZSxJQUFJRCxRQUFRO0VBRXZELE9BQU9FLFVBQVUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHQyxVQUFVLENBQUNELFVBQVUsQ0FBQ0UsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9ELENBQUM7QUFBQ0MsT0FBQSxDQUFBakIsZUFBQSxHQUFBQSxlQUFBO0FBRUYsTUFBTWtCLGFBQWEsR0FBSWpCLGVBQWUsSUFDcENBLGVBQWUsQ0FBQ2tCLEdBQUcsQ0FBRUMsQ0FBQyxJQUFLQSxDQUFDLENBQUNDLGtCQUFrQixDQUFDLENBQUNaLE1BQU0sQ0FBRWEsU0FBUyxJQUFLQSxTQUFTLENBQUM7QUFFNUUsTUFBTUMsYUFBYSxHQUFHQSxDQUFDQyxRQUFRLEVBQUVDLE9BQU8sRUFBRUMsR0FBRyxLQUFLO0VBQ3ZELElBQUksQ0FBQ0QsT0FBTyxFQUFFO0lBQ1osT0FBTyxDQUFDO0VBQ1Y7RUFFQSxJQUFJRSxNQUFNLENBQUNDLElBQUksQ0FBQ0gsT0FBTyxDQUFDLENBQUNqQixNQUFNLEtBQUssQ0FBQyxFQUFFO0lBQ3JDLE9BQU8sQ0FBQztFQUNWO0VBQ0EsTUFBTTtJQUFFcUIsVUFBVTtJQUFFdEI7RUFBUSxDQUFDLEdBQUdpQixRQUFRLElBQUksQ0FBQyxDQUFDO0VBQzlDLElBQUk7SUFBRXZCO0VBQWdCLENBQUMsR0FBR3VCLFFBQVEsSUFBSSxDQUFDLENBQUM7RUFDeEMsSUFBSTtJQUFFTTtFQUFRLENBQUMsR0FBR0wsT0FBTyxJQUFJLENBQUMsQ0FBQztFQUMvQkssT0FBTyxHQUFHQSxPQUFPLElBQUksRUFBRTtFQUN2QjdCLGVBQWUsR0FBR0EsZUFBZSxJQUFJLEVBQUU7O0VBRXZDO0VBQ0E7RUFDQSxNQUFNO0lBQUU0QixVQUFVLEVBQUUzQixlQUFlO0lBQUVTO0VBQVEsQ0FBQyxHQUFHLElBQUFvQixzQkFBVSxFQUFDRixVQUFVLEVBQUV0QixPQUFPLEVBQUV1QixPQUFPLEVBQUU3QixlQUFlLENBQUM7RUFFMUcsTUFBTStCLFVBQVUsR0FBR2QsYUFBYSxDQUFDakIsZUFBZSxDQUFDO0VBQ2pELE1BQU1nQyxPQUFPLEdBQUdDLCtCQUFjLENBQUNELE9BQU8sQ0FBQ1QsUUFBUSxFQUFFRSxHQUFHLENBQUM7O0VBRXJEO0VBQ0EsSUFBSU8sT0FBTyxJQUFJLENBQUNELFVBQVUsQ0FBQ3hCLE1BQU0sRUFBRTtJQUNqQztJQUNBLE9BQU9SLGVBQWUsQ0FBQ0MsZUFBZSxFQUFFQyxlQUFlLENBQUM7RUFDMUQ7O0VBRUE7RUFDQSxPQUFPUyxPQUFPLEdBQUcsQ0FBQyxHQUFHLENBQUM7QUFDeEIsQ0FBQztBQUFDTSxPQUFBLENBQUFNLGFBQUEsR0FBQUEsYUFBQTtBQUVLLE1BQU1ZLGNBQWMsR0FBR0EsQ0FBQ1gsUUFBUSxFQUFFQyxPQUFPLEVBQUVDLEdBQUcsS0FBSztFQUN4RCxPQUFPLElBQUlVLE9BQU8sQ0FBRUMsT0FBTyxJQUFLO0lBQzlCLElBQUlYLEdBQUcsQ0FBQ1ksSUFBSSxLQUFLLFVBQVUsRUFBRTtNQUMzQixNQUFNbEMsS0FBSyxHQUFHbUIsYUFBYSxDQUFDQyxRQUFRLEVBQUVDLE9BQU8sRUFBRUMsR0FBRyxDQUFDO01BQ25ELElBQUl0QixLQUFLLEtBQUssQ0FBQyxFQUFFO1FBQ2ZpQyxPQUFPLENBQUMsU0FBUyxDQUFDO01BQ3BCLENBQUMsTUFBTSxJQUFJakMsS0FBSyxLQUFLLENBQUMsRUFBRTtRQUN0QmlDLE9BQU8sQ0FBQyxXQUFXLENBQUM7TUFDdEIsQ0FBQyxNQUFNO1FBQ0xBLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQztNQUM5QjtJQUNGLENBQUMsTUFBTTtNQUNMQSxPQUFPLENBQUNFLFNBQVMsQ0FBQztJQUNwQjtFQUNGLENBQUMsQ0FBQztBQUNKLENBQUM7QUFBQ3RCLE9BQUEsQ0FBQWtCLGNBQUEsR0FBQUEsY0FBQTtBQUVLLE1BQU1LLGtCQUFrQixHQUFHQSxDQUFDQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEtBQzNDLElBQUlMLE9BQU8sQ0FBRUMsT0FBTyxJQUFLO0VBQ3ZCQSxPQUFPLENBQUM7SUFDTixHQUFHSyxpQkFBUTtJQUNYLEdBQUdEO0VBQ0wsQ0FBQyxDQUFDO0FBQ0osQ0FBQyxDQUFDO0FBQUN4QixPQUFBLENBQUF1QixrQkFBQSxHQUFBQSxrQkFBQTtBQUVFLE1BQU1HLFNBQVMsR0FBSW5CLFFBQVEsS0FBTTtFQUFFLEdBQUdrQixpQkFBUTtFQUFFLEdBQUdsQjtBQUFTLENBQUMsQ0FBQzs7QUFFckU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFOQVAsT0FBQSxDQUFBMEIsU0FBQSxHQUFBQSxTQUFBO0FBT08sTUFBTUYsS0FBSyxHQUFHLE1BQUFBLENBQU9qQixRQUFRLEVBQUVDLE9BQU8sRUFBRUMsR0FBRyxFQUFFa0IsYUFBYSxLQUFLO0VBQ3BFLE1BQU1DLGtCQUFrQixHQUFHRixTQUFTLENBQUNuQixRQUFRLENBQUM7RUFDOUMsTUFBTXNCLGlCQUFpQixHQUFHLE1BQU1YLGNBQWMsQ0FBQ1Usa0JBQWtCLEVBQUVwQixPQUFPLEVBQUVDLEdBQUcsQ0FBQztFQUVoRixNQUFNO0lBQUVZLElBQUk7SUFBRVM7RUFBSyxDQUFDLEdBQUdyQixHQUFHLElBQUksQ0FBQyxDQUFDO0VBRWhDLE1BQU07SUFDSkcsVUFBVTtJQUNWbUIsZ0JBQWdCO0lBQ2hCQyxZQUFZO0lBQ1pDLGVBQWU7SUFDZmpELGVBQWU7SUFDZmtELFFBQVE7SUFDUkMsZUFBZTtJQUNmQyxhQUFhO0lBQ2JDLE1BQU07SUFDTkMsU0FBUztJQUNUQyxnQkFBZ0I7SUFDaEJDLFNBQVM7SUFDVEMsMEJBQTBCO0lBQzFCQyxtQkFBbUI7SUFDbkJDLFFBQVE7SUFDUkMscUJBQXFCO0lBQ3JCQyxhQUFhO0lBQ2JDLFlBQVk7SUFDWkMsY0FBYztJQUNkQyxvQkFBb0I7SUFDcEJDLG9CQUFvQjtJQUNwQkM7RUFDRixDQUFDLEdBQUd0QixrQkFBa0I7RUFDdEIsSUFBSTtJQUFFdEMsT0FBTztJQUFFNkQ7RUFBSyxDQUFDLEdBQUd2QixrQkFBa0I7RUFDMUMsSUFBSXdCLEVBQUU7RUFFTixNQUFNQyxlQUFlLEdBQUcsSUFBQUMsNEJBQVcsRUFBQzFCLGtCQUFrQixFQUFFcEIsT0FBTyxFQUFFQyxHQUFHLENBQUM7RUFFckUsTUFBTThDLHVCQUF1QixHQUFHdkUsZUFBZSxDQUFDa0IsR0FBRyxDQUFFc0QsUUFBUSxJQUFLO0lBQ2hFLE1BQU1DLGVBQWUsR0FBRyxDQUFDRCxRQUFRLENBQUNsRSxPQUFPLElBQUksRUFBRSxFQUFFRSxNQUFNLENBQUVrRSxNQUFNLElBQUtBLE1BQU0sS0FBSyxNQUFNLENBQUM7SUFDdEYsT0FBTztNQUFFLEdBQUdGLFFBQVE7TUFBRWxFLE9BQU8sRUFBRW1FO0lBQWdCLENBQUM7RUFDbEQsQ0FBQyxDQUFDO0VBRUYsSUFBSXBDLElBQUksS0FBSyxVQUFVLElBQUljLGVBQWUsRUFBRTtJQUMxQ2lCLEVBQUUsR0FBRyxNQUFNLElBQUFPLG1DQUF5QixFQUFDOUIsaUJBQWlCLEVBQUVLLFFBQVEsQ0FBQztFQUNuRTtFQUVBLElBQUksQ0FBQ21CLGVBQWUsRUFBRTtJQUNwQi9ELE9BQU8sR0FBRyxNQUFNLElBQUFzRSxtQ0FBa0IsRUFBQ3RFLE9BQU8sRUFBRWtCLE9BQU8sRUFBRW1CLGFBQWEsRUFBRSxJQUFJLENBQUM7RUFDM0U7RUFFQSxJQUFJLENBQUN3QixJQUFJLEVBQUU7SUFDVEEsSUFBSSxHQUFHdEUsVUFBVSxDQUFDZ0YsQ0FBQyxDQUFDLDBDQUEwQyxFQUFFO01BQUVDLEdBQUcsRUFBRW5CO0lBQVMsQ0FBQyxDQUFDO0VBQ3BGO0VBRUEsTUFBTTVCLFVBQVUsR0FBR2QsYUFBYSxDQUFDc0QsdUJBQXVCLENBQUM7RUFDekQsTUFBTTtJQUFFUSx1QkFBdUI7SUFBRUMsaUJBQWlCO0lBQUVDO0VBQW1CLENBQUMsR0FBRyxJQUFBQyxpQ0FBMEIsRUFDbkdYLHVCQUF1QixFQUN2QjNCLGtCQUFrQixDQUFDdUMscUJBQXFCLEdBQUdwRCxVQUFVLEdBQUcsRUFBRSxFQUMxRGEsa0JBQWtCLENBQUN0QyxPQUNyQixDQUFDO0VBQ0QsTUFBTThFLEdBQUcsR0FBRztJQUNWeEQsVUFBVSxFQUFFQSxVQUFVLElBQUksRUFBRTtJQUM1Qm1CLGdCQUFnQixFQUFFQSxnQkFBZ0IsSUFBSSxDQUFDO0lBQ3ZDYSxxQkFBcUI7SUFDckJ5QixXQUFXLEVBQUV4QyxpQkFBaUI7SUFDOUJ2QyxPQUFPLEVBQUVBLE9BQU8sSUFBSSxFQUFFO0lBQ3RCMEMsWUFBWSxFQUFFQSxZQUFZLElBQUksRUFBRTtJQUNoQ0MsZUFBZTtJQUNmcUMsUUFBUSxFQUFFakQsSUFBSSxLQUFLLFFBQVE7SUFDM0JhLFFBQVEsRUFBRWtCLEVBQUU7SUFDWkMsZUFBZTtJQUNmaEIsTUFBTSxFQUFFRCxhQUFhLEdBQUdDLE1BQU0sR0FBRyxJQUFJO0lBQ3JDQyxTQUFTO0lBQ1RhLElBQUk7SUFDSjFDLEdBQUc7SUFDSDhELFFBQVEsRUFBRXhELFVBQVUsSUFBSUEsVUFBVSxDQUFDeEIsTUFBTSxHQUFHLENBQUM7SUFDN0NQLGVBQWUsRUFBRXFDLElBQUksS0FBSyxVQUFVLEdBQUdrQyx1QkFBdUIsR0FBR2pDLFNBQVM7SUFDMUVxQixRQUFRO0lBQ1JFLGFBQWE7SUFDYkUsY0FBYztJQUNkRCxZQUFZLEVBQUVBLFlBQVk7SUFDMUJFLG9CQUFvQjtJQUNwQkMsb0JBQW9CO0lBQ3BCQyxpQkFBaUI7SUFDakJjLGlCQUFpQjtJQUNqQkQsdUJBQXVCO0lBQ3ZCRTtFQUNGLENBQUM7RUFFRCxJQUFJbkMsSUFBSSxLQUFLLFlBQVksS0FBS1QsSUFBSSxLQUFLLE1BQU0sSUFBSUEsSUFBSSxLQUFLLFVBQVUsQ0FBQyxFQUFFO0lBQ3JFK0MsR0FBRyxDQUFDNUIsU0FBUyxHQUFHRCxnQkFBZ0IsR0FBR0MsU0FBUyxHQUFHLElBQUk7SUFDbkQ0QixHQUFHLENBQUMxQixtQkFBbUIsR0FBR0QsMEJBQTBCLEdBQUdDLG1CQUFtQixHQUFHLElBQUk7RUFDbkYsQ0FBQyxNQUFNO0lBQ0wwQixHQUFHLENBQUM1QixTQUFTLEdBQUcsSUFBSTtJQUNwQjRCLEdBQUcsQ0FBQzFCLG1CQUFtQixHQUFHLElBQUk7RUFDaEM7RUFFQSxPQUFPMEIsR0FBRztBQUNaLENBQUM7QUFBQ3BFLE9BQUEsQ0FBQXdCLEtBQUEsR0FBQUEsS0FBQTtBQUVLLE1BQU1nRCxPQUFPLEdBQUdBLENBQUNqRSxRQUFRLEVBQUVDLE9BQU8sRUFBRUMsR0FBRyxLQUFLO0VBQ2pELElBQUlBLEdBQUcsQ0FBQ1ksSUFBSSxLQUFLLFVBQVUsRUFBRTtJQUMzQixPQUFPRixPQUFPLENBQUNzRCxNQUFNLENBQUMsSUFBSUMsS0FBSyxDQUFDLGdEQUFnRCxDQUFDLENBQUM7RUFDcEYsQ0FBQyxNQUFNO0lBQ0wsT0FBTyxJQUFJdkQsT0FBTyxDQUFFQyxPQUFPLElBQUs7TUFDOUJBLE9BQU8sQ0FBQztRQUNOakMsS0FBSyxFQUFFbUIsYUFBYSxDQUFDQyxRQUFRLEVBQUVDLE9BQU8sRUFBRUMsR0FBRyxDQUFDO1FBQzVDa0UsS0FBSyxFQUFFLENBQUNuRSxPQUFPLElBQUksSUFBQW9FLGdCQUFPLEVBQUNwRSxPQUFPO01BQ3BDLENBQUMsQ0FBQztJQUNKLENBQUMsQ0FBQztFQUNKO0FBQ0YsQ0FBQztBQUFDUixPQUFBLENBQUF3RSxPQUFBLEdBQUFBLE9BQUE7QUFFSyxNQUFNSyw0QkFBNEIsR0FBR0EsQ0FBQ3RFLFFBQVEsRUFBRUUsR0FBRyxLQUFLO0VBQzdELE9BQU8sSUFBSVUsT0FBTyxDQUFFQyxPQUFPLElBQUs7SUFDOUIsTUFBTTtNQUFFQyxJQUFJO01BQUVTO0lBQUssQ0FBQyxHQUFHckIsR0FBRyxJQUFJLENBQUMsQ0FBQztJQUVoQyxJQUFJWSxJQUFJLEtBQUssVUFBVSxJQUFJUyxJQUFJLEtBQUssWUFBWSxFQUFFO01BQ2hELE1BQU07UUFBRTlDO01BQWdCLENBQUMsR0FBR3VCLFFBQVE7TUFFcENhLE9BQU8sQ0FBQztRQUFFUCxPQUFPLEVBQUU3QixlQUFlO1FBQUU4RixFQUFFLEVBQUU7TUFBRSxDQUFDLENBQUM7SUFDOUMsQ0FBQyxNQUFNO01BQ0wsT0FBTzFELE9BQU8sQ0FBQyxJQUFJLENBQUM7SUFDdEI7RUFDRixDQUFDLENBQUM7QUFDSixDQUFDOztBQUVEO0FBQUFwQixPQUFBLENBQUE2RSw0QkFBQSxHQUFBQSw0QkFBQTtBQUNBLE1BQU1FLFlBQVksR0FBSUMsSUFBSSxJQUFLLENBQUNBLElBQUksSUFBSSxFQUFFLEVBQUVDLFVBQVUsQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDOztBQUV0RTtBQUNBLE1BQU1DLFVBQVUsR0FBSUYsSUFBSSxJQUFLLENBQUNBLElBQUksSUFBSSxFQUFFLEVBQUVHLE9BQU8sQ0FBQyxvQ0FBb0MsRUFBRSxFQUFFLENBQUM7QUFFcEYsTUFBTUMsUUFBUSxHQUFHQSxDQUFDNUQsS0FBSyxHQUFHLENBQUMsQ0FBQyxFQUFFNkQsTUFBTSxHQUFHLENBQUMsQ0FBQyxLQUFLO0VBQ25ELE1BQU07SUFBRXpFLFVBQVU7SUFBRXRCLE9BQU87SUFBRU4sZUFBZTtJQUFFc0c7RUFBaUIsQ0FBQyxHQUFHOUQsS0FBSztFQUN4RSxNQUFNO0lBQ0orRCxVQUFVLEdBQUcsQ0FBQztJQUNkQyxhQUFhLEdBQUcsQ0FBQztJQUNqQkMsYUFBYSxHQUFHLEVBQUU7SUFDbEJDLGtCQUFrQixHQUFHLEdBQUc7SUFDeEJDLG9CQUFvQixHQUFHO0VBQ3pCLENBQUMsR0FBR04sTUFBTTtFQUNWLE1BQU1PLGVBQWUsR0FBRyxDQUFDLElBQUl0RyxPQUFPLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQ3VHLE9BQU8sQ0FBQyxDQUFDO0VBQ3RELE1BQU1DLE1BQU0sR0FBRyxDQUFDLENBQUM7RUFDakIsTUFBTUMsYUFBYSxHQUFHLENBQUMsQ0FBQztFQUN4QixNQUFNQyxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7RUFFM0IsQ0FBQyxxQkFBcUIsRUFBRSxRQUFRLEVBQUUsV0FBVyxDQUFDLENBQUNDLE9BQU8sQ0FBRUMsS0FBSyxJQUFLO0lBQ2hFLElBQUliLE1BQU0sQ0FBQ2EsS0FBSyxDQUFDLEVBQUVDLFFBQVEsSUFBSSxDQUFDakIsVUFBVSxDQUFDMUQsS0FBSyxDQUFDMEUsS0FBSyxDQUFDLENBQUMsRUFBRTtNQUN4REosTUFBTSxDQUFDSSxLQUFLLENBQUMsR0FBRyx5QkFBeUI7SUFDM0M7RUFDRixDQUFDLENBQUM7RUFFRixDQUFDdEYsVUFBVSxJQUFJLEVBQUUsRUFBRXFGLE9BQU8sQ0FBRUcsUUFBUSxJQUFLO0lBQ3ZDLE1BQU07TUFBRXRCLEVBQUU7TUFBRXVCO0lBQU0sQ0FBQyxHQUFHRCxRQUFRO0lBRTlCLElBQUlyQixZQUFZLENBQUNzQixLQUFLLENBQUMsQ0FBQzlHLE1BQU0sR0FBR29HLG9CQUFvQixFQUFFO01BQ3JESyxnQkFBZ0IsQ0FBQ2xCLEVBQUUsQ0FBQyxHQUFHLDBDQUEwQ2Esb0JBQW9CLG1CQUFtQjtJQUMxRztFQUNGLENBQUMsQ0FBQztFQUVGLENBQUNDLGVBQWUsSUFBSSxFQUFFLEVBQUVLLE9BQU8sQ0FBQyxDQUFDdkMsTUFBTSxFQUFFNEMsS0FBSyxLQUFLO0lBQ2pELE1BQU07TUFBRXhCLEVBQUU7TUFBRXlCO0lBQVEsQ0FBQyxHQUFHN0MsTUFBTTtJQUU5QixJQUFJcUIsWUFBWSxDQUFDd0IsT0FBTyxDQUFDLENBQUNoSCxNQUFNLEdBQUdtRyxrQkFBa0IsRUFBRTtNQUNyREssYUFBYSxDQUFDakIsRUFBRSxDQUFDLEdBQUcsaUNBQWlDWSxrQkFBa0IsbUJBQW1CO0lBQzVGO0lBRUEsSUFBSSxDQUFDUixVQUFVLENBQUNxQixPQUFPLENBQUMsRUFBRTtNQUN4QlIsYUFBYSxDQUFDakIsRUFBRSxDQUFDLEdBQUcsNkJBQTZCO0lBQ25ELENBQUMsTUFBTTtNQUNMLE1BQU0wQixlQUFlLEdBQUdaLGVBQWUsQ0FBQ2EsS0FBSyxDQUFDSCxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUNJLElBQUksQ0FBRXZHLENBQUMsSUFBS0EsQ0FBQyxDQUFDb0csT0FBTyxLQUFLQSxPQUFPLENBQUM7TUFFM0YsSUFBSUMsZUFBZSxFQUFFO1FBQ25CVCxhQUFhLENBQUNqQixFQUFFLENBQUMsR0FBRyxrQ0FBa0M7TUFDeEQ7SUFDRjtFQUNGLENBQUMsQ0FBQztFQUVGLE1BQU02QixjQUFjLEdBQUcsQ0FBQy9GLFVBQVUsSUFBSSxFQUFFLEVBQUVyQixNQUFNO0VBQ2hELE1BQU1xSCxXQUFXLEdBQUcsQ0FBQ3RILE9BQU8sSUFBSSxFQUFFLEVBQUVDLE1BQU07RUFFMUMsSUFBSW9ILGNBQWMsR0FBR2xCLGFBQWEsRUFBRTtJQUNsQ0ssTUFBTSxDQUFDZSxlQUFlLEdBQUcsZ0JBQWdCcEIsYUFBYSxnQ0FBZ0M7RUFDeEYsQ0FBQyxNQUFNLElBQUlrQixjQUFjLEdBQUduQixhQUFhLEVBQUU7SUFDekNNLE1BQU0sQ0FBQ2UsZUFBZSxHQUFHLDRCQUE0QnJCLGFBQWEsb0JBQW9CO0VBQ3hGO0VBRUEsSUFBSW9CLFdBQVcsR0FBR3JCLFVBQVUsRUFBRTtJQUM1Qk8sTUFBTSxDQUFDZ0IsWUFBWSxHQUFHLDRCQUE0QnZCLFVBQVUsbUJBQW1CO0VBQ2pGLENBQUMsTUFBTSxJQUFJcUIsV0FBVyxHQUFHdEIsZ0JBQWdCLEVBQUU7SUFDekNRLE1BQU0sQ0FBQ2dCLFlBQVksR0FBRyxnQkFBZ0J4QixnQkFBZ0IsNkJBQTZCO0VBQ3JGO0VBRUEsSUFBSXNCLFdBQVcsSUFBSUQsY0FBYyxFQUFFO0lBQ2pDLElBQUlJLGVBQWUsR0FBRyxLQUFLO0lBRTNCLENBQUMvSCxlQUFlLElBQUksRUFBRSxFQUFFaUgsT0FBTyxDQUFFekMsUUFBUSxJQUFLO01BQzVDLE1BQU07UUFBRWxFLE9BQU8sR0FBRyxFQUFFO1FBQUVjLGtCQUFrQixHQUFHO01BQUcsQ0FBQyxHQUFHb0QsUUFBUTtNQUUxRCxJQUFJbEUsT0FBTyxDQUFDQyxNQUFNLEVBQUU7UUFDbEJ3SCxlQUFlLEdBQUcsSUFBSTtNQUN4QixDQUFDLE1BQU07UUFDTDNHLGtCQUFrQixDQUFDNkYsT0FBTyxDQUFFNUYsU0FBUyxJQUFLO1VBQ3hDLElBQUksQ0FBQ0EsU0FBUyxJQUFJLEVBQUUsRUFBRWQsTUFBTSxFQUFFO1lBQzVCd0gsZUFBZSxHQUFHLElBQUk7VUFDeEI7UUFDRixDQUFDLENBQUM7TUFDSjtJQUNGLENBQUMsQ0FBQztJQUVGLElBQUlDLHVCQUF1QixHQUFHLENBQUMsQ0FBQztJQUNoQyxJQUFJQyxpQkFBaUIsR0FBRyxFQUFFO0lBQzFCLENBQUNqSSxlQUFlLElBQUksRUFBRSxFQUFFaUgsT0FBTyxDQUFFekMsUUFBUSxJQUFLO01BQzVDLE1BQU07UUFBRWxFLE9BQU8sR0FBRyxFQUFFO1FBQUVjLGtCQUFrQixHQUFHLEVBQUU7UUFBRWdHO01BQVMsQ0FBQyxHQUFHNUMsUUFBUTtNQUVwRSxJQUFJd0QsdUJBQXVCLEtBQUssQ0FBQyxDQUFDLEVBQUU7UUFDbENBLHVCQUF1QixHQUFHLElBQUFFLGtDQUEyQixFQUFDNUgsT0FBTyxFQUFFYyxrQkFBa0IsQ0FBQztRQUVsRixJQUFJNEcsdUJBQXVCLEtBQUssQ0FBQyxDQUFDLEVBQUU7VUFDbENBLHVCQUF1QixHQUFHLElBQUFHLDRCQUFxQixFQUFDL0csa0JBQWtCLENBQUM7UUFDckU7UUFFQTZHLGlCQUFpQixHQUFHYixRQUFRO01BQzlCO0lBQ0YsQ0FBQyxDQUFDO0lBRUYsSUFBSVksdUJBQXVCLEdBQUcsQ0FBQyxDQUFDLEVBQUU7TUFDaENsQixNQUFNLENBQUNzQixrQkFBa0IsR0FBRztRQUFFZCxLQUFLLEVBQUVVLHVCQUF1QjtRQUFFWixRQUFRLEVBQUVhO01BQWtCLENBQUM7SUFDN0Y7SUFFQSxJQUFJLENBQUNGLGVBQWUsRUFBRTtNQUNwQmpCLE1BQU0sQ0FBQ3VCLGdCQUFnQixHQUFHLGlFQUFpRTtJQUM3RjtFQUNGO0VBRUEsSUFBSSxDQUFDLElBQUF6QyxnQkFBTyxFQUFDbUIsYUFBYSxDQUFDLEVBQUU7SUFDM0JELE1BQU0sQ0FBQ0MsYUFBYSxHQUFHQSxhQUFhO0VBQ3RDO0VBRUEsSUFBSSxDQUFDLElBQUFuQixnQkFBTyxFQUFDb0IsZ0JBQWdCLENBQUMsRUFBRTtJQUM5QkYsTUFBTSxDQUFDRSxnQkFBZ0IsR0FBR0EsZ0JBQWdCO0VBQzVDO0VBRUEsT0FBT0YsTUFBTTtBQUNmLENBQUM7QUFBQzlGLE9BQUEsQ0FBQW9GLFFBQUEsR0FBQUEsUUFBQSIsImlnbm9yZUxpc3QiOltdfQ==
|