@pie-element/placement-ordering 12.0.2-esm.0 → 12.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 +24 -0
- package/configure/CHANGELOG.md +19 -0
- package/configure/package.json +5 -5
- package/controller/CHANGELOG.md +19 -0
- package/controller/package.json +4 -4
- package/lib/tile.js +0 -1
- package/lib/tile.js.map +1 -1
- package/package.json +8 -25
- package/esm/configure.css +0 -847
- package/esm/configure.js +0 -4020
- package/esm/configure.js.map +0 -1
- package/esm/controller.css +0 -847
- package/esm/controller.js +0 -924
- package/esm/controller.js.map +0 -1
- package/esm/element.css +0 -847
- package/esm/element.js +0 -3108
- package/esm/element.js.map +0 -1
package/esm/controller.js
DELETED
|
@@ -1,924 +0,0 @@
|
|
|
1
|
-
import _ from 'lodash';
|
|
2
|
-
import debug from 'debug';
|
|
3
|
-
import { getFeedbackForCorrectness } from '@pie-lib/feedback';
|
|
4
|
-
import { partialScoring } from '@pie-lib/controller-utils';
|
|
5
|
-
import isEqual from 'lodash/isEqual';
|
|
6
|
-
import isEmpty from 'lodash/isEmpty';
|
|
7
|
-
import Translator from '@pie-lib/translator';
|
|
8
|
-
|
|
9
|
-
function _extends() {
|
|
10
|
-
_extends = Object.assign || function (target) {
|
|
11
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
12
|
-
var source = arguments[i];
|
|
13
|
-
|
|
14
|
-
for (var key in source) {
|
|
15
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
16
|
-
target[key] = source[key];
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return target;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
return _extends.apply(this, arguments);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
28
|
-
|
|
29
|
-
var combinatorics = {exports: {}};
|
|
30
|
-
|
|
31
|
-
/*
|
|
32
|
-
* $Id: combinatorics.js,v 0.25 2013/03/11 15:42:14 dankogai Exp dankogai $
|
|
33
|
-
*
|
|
34
|
-
* Licensed under the MIT license.
|
|
35
|
-
* http://www.opensource.org/licenses/mit-license.php
|
|
36
|
-
*
|
|
37
|
-
* References:
|
|
38
|
-
* http://www.ruby-doc.org/core-2.0/Array.html#method-i-combination
|
|
39
|
-
* http://www.ruby-doc.org/core-2.0/Array.html#method-i-permutation
|
|
40
|
-
* http://en.wikipedia.org/wiki/Factorial_number_system
|
|
41
|
-
*/
|
|
42
|
-
|
|
43
|
-
(function (module, exports) {
|
|
44
|
-
(function (root, factory) {
|
|
45
|
-
{
|
|
46
|
-
module.exports = factory();
|
|
47
|
-
}
|
|
48
|
-
}(commonjsGlobal, function () {
|
|
49
|
-
var version = "0.5.5";
|
|
50
|
-
/* combinatory arithmetics */
|
|
51
|
-
var P = function(m, n) {
|
|
52
|
-
if (n % 1 !== 0) throw new RangeError;
|
|
53
|
-
var p = 1;
|
|
54
|
-
while (n--) p *= m--;
|
|
55
|
-
return p;
|
|
56
|
-
};
|
|
57
|
-
var C = function(m, n) {
|
|
58
|
-
if (n > m) {
|
|
59
|
-
return 0;
|
|
60
|
-
}
|
|
61
|
-
return P(m, n) / P(n, n);
|
|
62
|
-
};
|
|
63
|
-
var factorial = function(n) {
|
|
64
|
-
return P(n, n);
|
|
65
|
-
};
|
|
66
|
-
var factoradic = function(n, d) {
|
|
67
|
-
var f = 1;
|
|
68
|
-
if (!d) {
|
|
69
|
-
for (d = 1; f < n; f *= ++d);
|
|
70
|
-
if (f > n) f /= d--;
|
|
71
|
-
} else {
|
|
72
|
-
f = factorial(d);
|
|
73
|
-
}
|
|
74
|
-
var result = [0];
|
|
75
|
-
for (; d; f /= d--) {
|
|
76
|
-
result[d] = Math.floor(n / f);
|
|
77
|
-
n %= f;
|
|
78
|
-
}
|
|
79
|
-
return result;
|
|
80
|
-
};
|
|
81
|
-
/* common methods */
|
|
82
|
-
var addProperties = function(dst, src) {
|
|
83
|
-
Object.keys(src).forEach(function(p) {
|
|
84
|
-
Object.defineProperty(dst, p, {
|
|
85
|
-
value: src[p],
|
|
86
|
-
configurable: p == 'next'
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
};
|
|
90
|
-
var hideProperty = function(o, p) {
|
|
91
|
-
Object.defineProperty(o, p, {
|
|
92
|
-
writable: true
|
|
93
|
-
});
|
|
94
|
-
};
|
|
95
|
-
var toArray = function(f) {
|
|
96
|
-
var e, result = [];
|
|
97
|
-
this.init();
|
|
98
|
-
while (e = this.next()) result.push(f ? f(e) : e);
|
|
99
|
-
this.init();
|
|
100
|
-
return result;
|
|
101
|
-
};
|
|
102
|
-
var common = {
|
|
103
|
-
toArray: toArray,
|
|
104
|
-
map: toArray,
|
|
105
|
-
forEach: function(f) {
|
|
106
|
-
var e;
|
|
107
|
-
this.init();
|
|
108
|
-
while (e = this.next()) f(e);
|
|
109
|
-
this.init();
|
|
110
|
-
},
|
|
111
|
-
filter: function(f) {
|
|
112
|
-
var e, result = [];
|
|
113
|
-
this.init();
|
|
114
|
-
while (e = this.next()) if (f(e)) result.push(e);
|
|
115
|
-
this.init();
|
|
116
|
-
return result;
|
|
117
|
-
},
|
|
118
|
-
find: function(f) {
|
|
119
|
-
var e, result;
|
|
120
|
-
this.init();
|
|
121
|
-
while (e = this.next()) {
|
|
122
|
-
if (f(e)) {
|
|
123
|
-
result = e;
|
|
124
|
-
break;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
this.init();
|
|
128
|
-
return result;
|
|
129
|
-
},
|
|
130
|
-
reduce: function(reducer, result) {
|
|
131
|
-
// return this.toArray().reduce(reducer, init);
|
|
132
|
-
this.init();
|
|
133
|
-
var index = 0;
|
|
134
|
-
if (arguments.length < 2) {
|
|
135
|
-
result = this.next();
|
|
136
|
-
index += 1;
|
|
137
|
-
}
|
|
138
|
-
var length = this.length;
|
|
139
|
-
while(index < length) {
|
|
140
|
-
result = reducer(result, this.next(), index, this);
|
|
141
|
-
index += 1;
|
|
142
|
-
}
|
|
143
|
-
return result;
|
|
144
|
-
},
|
|
145
|
-
lazyMap: function(f) {
|
|
146
|
-
this._lazyMap = f;
|
|
147
|
-
return this;
|
|
148
|
-
},
|
|
149
|
-
lazyFilter: function(f) {
|
|
150
|
-
Object.defineProperty(this, 'next', {
|
|
151
|
-
writable: true
|
|
152
|
-
});
|
|
153
|
-
if (typeof f !== 'function') {
|
|
154
|
-
this.next = this._next;
|
|
155
|
-
} else {
|
|
156
|
-
if (typeof (this._next) !== 'function') {
|
|
157
|
-
this._next = this.next;
|
|
158
|
-
}
|
|
159
|
-
var _next = this._next.bind(this);
|
|
160
|
-
this.next = (function() {
|
|
161
|
-
var e;
|
|
162
|
-
while (e = _next()) {
|
|
163
|
-
if (f(e))
|
|
164
|
-
return e;
|
|
165
|
-
}
|
|
166
|
-
return e;
|
|
167
|
-
}).bind(this);
|
|
168
|
-
}
|
|
169
|
-
Object.defineProperty(this, 'next', {
|
|
170
|
-
writable: false
|
|
171
|
-
});
|
|
172
|
-
return this;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
};
|
|
176
|
-
/* power set */
|
|
177
|
-
var power = function(ary, fun) {
|
|
178
|
-
var size = 1 << ary.length,
|
|
179
|
-
sizeOf = function() {
|
|
180
|
-
return size;
|
|
181
|
-
},
|
|
182
|
-
that = Object.create(ary.slice(), {
|
|
183
|
-
length: {
|
|
184
|
-
get: sizeOf
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
hideProperty(that, 'index');
|
|
188
|
-
addProperties(that, {
|
|
189
|
-
valueOf: sizeOf,
|
|
190
|
-
init: function() {
|
|
191
|
-
that.index = 0;
|
|
192
|
-
},
|
|
193
|
-
nth: function(n) {
|
|
194
|
-
if (n >= size) return;
|
|
195
|
-
var i = 0,
|
|
196
|
-
result = [];
|
|
197
|
-
for (; n; n >>>= 1, i++) if (n & 1) result.push(this[i]);
|
|
198
|
-
return (typeof (that._lazyMap) === 'function')?that._lazyMap(result):result;
|
|
199
|
-
},
|
|
200
|
-
next: function() {
|
|
201
|
-
return this.nth(this.index++);
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
addProperties(that, common);
|
|
205
|
-
that.init();
|
|
206
|
-
return (typeof (fun) === 'function') ? that.map(fun) : that;
|
|
207
|
-
};
|
|
208
|
-
/* combination */
|
|
209
|
-
var nextIndex = function(n) {
|
|
210
|
-
var smallest = n & -n,
|
|
211
|
-
ripple = n + smallest,
|
|
212
|
-
new_smallest = ripple & -ripple,
|
|
213
|
-
ones = ((new_smallest / smallest) >> 1) - 1;
|
|
214
|
-
return ripple | ones;
|
|
215
|
-
};
|
|
216
|
-
var combination = function(ary, nelem, fun) {
|
|
217
|
-
if (!nelem) nelem = ary.length;
|
|
218
|
-
if (nelem < 1) throw new RangeError;
|
|
219
|
-
if (nelem > ary.length) throw new RangeError;
|
|
220
|
-
var first = (1 << nelem) - 1,
|
|
221
|
-
size = C(ary.length, nelem),
|
|
222
|
-
maxIndex = 1 << ary.length,
|
|
223
|
-
sizeOf = function() {
|
|
224
|
-
return size;
|
|
225
|
-
},
|
|
226
|
-
that = Object.create(ary.slice(), {
|
|
227
|
-
length: {
|
|
228
|
-
get: sizeOf
|
|
229
|
-
}
|
|
230
|
-
});
|
|
231
|
-
hideProperty(that, 'index');
|
|
232
|
-
addProperties(that, {
|
|
233
|
-
valueOf: sizeOf,
|
|
234
|
-
init: function() {
|
|
235
|
-
this.index = first;
|
|
236
|
-
},
|
|
237
|
-
next: function() {
|
|
238
|
-
if (this.index >= maxIndex) return;
|
|
239
|
-
var i = 0,
|
|
240
|
-
n = this.index,
|
|
241
|
-
result = [];
|
|
242
|
-
for (; n; n >>>= 1, i++) {
|
|
243
|
-
if (n & 1) result[result.length] = this[i];
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
this.index = nextIndex(this.index);
|
|
247
|
-
return (typeof (that._lazyMap) === 'function')?that._lazyMap(result):result;
|
|
248
|
-
}
|
|
249
|
-
});
|
|
250
|
-
addProperties(that, common);
|
|
251
|
-
that.init();
|
|
252
|
-
return (typeof (fun) === 'function') ? that.map(fun) : that;
|
|
253
|
-
};
|
|
254
|
-
/* bigcombination */
|
|
255
|
-
var bigNextIndex = function(n, nelem) {
|
|
256
|
-
|
|
257
|
-
var result = n;
|
|
258
|
-
var j = nelem;
|
|
259
|
-
var i = 0;
|
|
260
|
-
for (i = result.length - 1; i >= 0; i--) {
|
|
261
|
-
if (result[i] == 1) {
|
|
262
|
-
j--;
|
|
263
|
-
} else {
|
|
264
|
-
break;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
if (j == 0) {
|
|
268
|
-
// Overflow
|
|
269
|
-
result[result.length] = 1;
|
|
270
|
-
for (var k = result.length - 2; k >= 0; k--) {
|
|
271
|
-
result[k] = (k < nelem-1)?1:0;
|
|
272
|
-
}
|
|
273
|
-
} else {
|
|
274
|
-
// Normal
|
|
275
|
-
|
|
276
|
-
// first zero after 1
|
|
277
|
-
var i1 = -1;
|
|
278
|
-
var i0 = -1;
|
|
279
|
-
for (var i = 0; i < result.length; i++) {
|
|
280
|
-
if (result[i] == 0 && i1 != -1) {
|
|
281
|
-
i0 = i;
|
|
282
|
-
}
|
|
283
|
-
if (result[i] == 1) {
|
|
284
|
-
i1 = i;
|
|
285
|
-
}
|
|
286
|
-
if (i0 != -1 && i1 != -1) {
|
|
287
|
-
result[i0] = 1;
|
|
288
|
-
result[i1] = 0;
|
|
289
|
-
break;
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
j = nelem;
|
|
294
|
-
for (var i = result.length - 1; i >= i1; i--) {
|
|
295
|
-
if (result[i] == 1)
|
|
296
|
-
j--;
|
|
297
|
-
}
|
|
298
|
-
for (var i = 0; i < i1; i++) {
|
|
299
|
-
result[i] = (i < j)?1:0;
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
return result;
|
|
304
|
-
|
|
305
|
-
};
|
|
306
|
-
var buildFirst = function(nelem) {
|
|
307
|
-
var result = [];
|
|
308
|
-
for (var i = 0; i < nelem; i++) {
|
|
309
|
-
result[i] = 1;
|
|
310
|
-
}
|
|
311
|
-
result[0] = 1;
|
|
312
|
-
return result;
|
|
313
|
-
};
|
|
314
|
-
var bigCombination = function(ary, nelem, fun) {
|
|
315
|
-
if (!nelem) nelem = ary.length;
|
|
316
|
-
if (nelem < 1) throw new RangeError;
|
|
317
|
-
if (nelem > ary.length) throw new RangeError;
|
|
318
|
-
var first = buildFirst(nelem),
|
|
319
|
-
size = C(ary.length, nelem),
|
|
320
|
-
maxIndex = ary.length,
|
|
321
|
-
sizeOf = function() {
|
|
322
|
-
return size;
|
|
323
|
-
},
|
|
324
|
-
that = Object.create(ary.slice(), {
|
|
325
|
-
length: {
|
|
326
|
-
get: sizeOf
|
|
327
|
-
}
|
|
328
|
-
});
|
|
329
|
-
hideProperty(that, 'index');
|
|
330
|
-
addProperties(that, {
|
|
331
|
-
valueOf: sizeOf,
|
|
332
|
-
init: function() {
|
|
333
|
-
this.index = first.concat();
|
|
334
|
-
},
|
|
335
|
-
next: function() {
|
|
336
|
-
if (this.index.length > maxIndex) return;
|
|
337
|
-
var i = 0,
|
|
338
|
-
n = this.index,
|
|
339
|
-
result = [];
|
|
340
|
-
for (var j = 0; j < n.length; j++, i++) {
|
|
341
|
-
if (n[j])
|
|
342
|
-
result[result.length] = this[i];
|
|
343
|
-
}
|
|
344
|
-
bigNextIndex(this.index, nelem);
|
|
345
|
-
return (typeof (that._lazyMap) === 'function')?that._lazyMap(result):result;
|
|
346
|
-
}
|
|
347
|
-
});
|
|
348
|
-
addProperties(that, common);
|
|
349
|
-
that.init();
|
|
350
|
-
return (typeof (fun) === 'function') ? that.map(fun) : that;
|
|
351
|
-
};
|
|
352
|
-
/* permutation */
|
|
353
|
-
var _permutation = function(ary) {
|
|
354
|
-
var that = ary.slice(),
|
|
355
|
-
size = factorial(that.length);
|
|
356
|
-
that.index = 0;
|
|
357
|
-
that.next = function() {
|
|
358
|
-
if (this.index >= size) return;
|
|
359
|
-
var copy = this.slice(),
|
|
360
|
-
digits = factoradic(this.index, this.length),
|
|
361
|
-
result = [],
|
|
362
|
-
i = this.length - 1;
|
|
363
|
-
for (; i >= 0; --i) result.push(copy.splice(digits[i], 1)[0]);
|
|
364
|
-
this.index++;
|
|
365
|
-
return (typeof (that._lazyMap) === 'function')?that._lazyMap(result):result;
|
|
366
|
-
};
|
|
367
|
-
return that;
|
|
368
|
-
};
|
|
369
|
-
// which is really a permutation of combination
|
|
370
|
-
var permutation = function(ary, nelem, fun) {
|
|
371
|
-
if (!nelem) nelem = ary.length;
|
|
372
|
-
if (nelem < 1) throw new RangeError;
|
|
373
|
-
if (nelem > ary.length) throw new RangeError;
|
|
374
|
-
var size = P(ary.length, nelem),
|
|
375
|
-
sizeOf = function() {
|
|
376
|
-
return size;
|
|
377
|
-
},
|
|
378
|
-
that = Object.create(ary.slice(), {
|
|
379
|
-
length: {
|
|
380
|
-
get: sizeOf
|
|
381
|
-
}
|
|
382
|
-
});
|
|
383
|
-
hideProperty(that, 'cmb');
|
|
384
|
-
hideProperty(that, 'per');
|
|
385
|
-
addProperties(that, {
|
|
386
|
-
valueOf: function() {
|
|
387
|
-
return size;
|
|
388
|
-
},
|
|
389
|
-
init: function() {
|
|
390
|
-
/* combination can only be used for less than 31 elements */
|
|
391
|
-
if (ary.length < 31) {
|
|
392
|
-
this.cmb = combination(ary, nelem);
|
|
393
|
-
} else {
|
|
394
|
-
this.cmb = bigCombination(ary, nelem);
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
this.per = _permutation(this.cmb.next());
|
|
398
|
-
},
|
|
399
|
-
next: function() {
|
|
400
|
-
var result = this.per.next();
|
|
401
|
-
if (!result) {
|
|
402
|
-
var cmb = this.cmb.next();
|
|
403
|
-
if (!cmb) return;
|
|
404
|
-
this.per = _permutation(cmb);
|
|
405
|
-
return this.next();
|
|
406
|
-
}
|
|
407
|
-
return (typeof (that._lazyMap) === 'function')?that._lazyMap(result):result;
|
|
408
|
-
}
|
|
409
|
-
});
|
|
410
|
-
addProperties(that, common);
|
|
411
|
-
that.init();
|
|
412
|
-
return (typeof (fun) === 'function') ? that.map(fun) : that;
|
|
413
|
-
};
|
|
414
|
-
|
|
415
|
-
var PC = function(m) {
|
|
416
|
-
var total = 0;
|
|
417
|
-
for (var n = 1; n <= m; n++) {
|
|
418
|
-
var p = P(m,n);
|
|
419
|
-
total += p;
|
|
420
|
-
} return total;
|
|
421
|
-
};
|
|
422
|
-
// which is really a permutation of combination
|
|
423
|
-
var permutationCombination = function(ary, fun) {
|
|
424
|
-
// if (!nelem) nelem = ary.length;
|
|
425
|
-
// if (nelem < 1) throw new RangeError;
|
|
426
|
-
// if (nelem > ary.length) throw new RangeError;
|
|
427
|
-
var size = PC(ary.length),
|
|
428
|
-
sizeOf = function() {
|
|
429
|
-
return size;
|
|
430
|
-
},
|
|
431
|
-
that = Object.create(ary.slice(), {
|
|
432
|
-
length: {
|
|
433
|
-
get: sizeOf
|
|
434
|
-
}
|
|
435
|
-
});
|
|
436
|
-
hideProperty(that, 'cmb');
|
|
437
|
-
hideProperty(that, 'per');
|
|
438
|
-
hideProperty(that, 'nelem');
|
|
439
|
-
addProperties(that, {
|
|
440
|
-
valueOf: function() {
|
|
441
|
-
return size;
|
|
442
|
-
},
|
|
443
|
-
init: function() {
|
|
444
|
-
this.nelem = 1;
|
|
445
|
-
// console.log("Starting nelem: " + this.nelem);
|
|
446
|
-
this.cmb = combination(ary, this.nelem);
|
|
447
|
-
this.per = _permutation(this.cmb.next());
|
|
448
|
-
},
|
|
449
|
-
next: function() {
|
|
450
|
-
var result = this.per.next();
|
|
451
|
-
if (!result) {
|
|
452
|
-
var cmb = this.cmb.next();
|
|
453
|
-
if (!cmb) {
|
|
454
|
-
this.nelem++;
|
|
455
|
-
// console.log("increment nelem: " + this.nelem + " vs " + ary.length);
|
|
456
|
-
if (this.nelem > ary.length) return;
|
|
457
|
-
this.cmb = combination(ary, this.nelem);
|
|
458
|
-
cmb = this.cmb.next();
|
|
459
|
-
if (!cmb) return;
|
|
460
|
-
}
|
|
461
|
-
this.per = _permutation(cmb);
|
|
462
|
-
return this.next();
|
|
463
|
-
}
|
|
464
|
-
return (typeof (that._lazyMap) === 'function')?that._lazyMap(result):result;
|
|
465
|
-
}
|
|
466
|
-
});
|
|
467
|
-
addProperties(that, common);
|
|
468
|
-
that.init();
|
|
469
|
-
return (typeof (fun) === 'function') ? that.map(fun) : that;
|
|
470
|
-
};
|
|
471
|
-
/* Cartesian Product */
|
|
472
|
-
var arraySlice = Array.prototype.slice;
|
|
473
|
-
var cartesianProduct = function() {
|
|
474
|
-
if (!arguments.length) throw new RangeError;
|
|
475
|
-
var args = arraySlice.call(arguments),
|
|
476
|
-
size = args.reduce(function(p, a) {
|
|
477
|
-
return p * a.length;
|
|
478
|
-
}, 1),
|
|
479
|
-
sizeOf = function() {
|
|
480
|
-
return size;
|
|
481
|
-
},
|
|
482
|
-
dim = args.length,
|
|
483
|
-
that = Object.create(args, {
|
|
484
|
-
length: {
|
|
485
|
-
get: sizeOf
|
|
486
|
-
}
|
|
487
|
-
});
|
|
488
|
-
if (!size) throw new RangeError;
|
|
489
|
-
hideProperty(that, 'index');
|
|
490
|
-
addProperties(that, {
|
|
491
|
-
valueOf: sizeOf,
|
|
492
|
-
dim: dim,
|
|
493
|
-
init: function() {
|
|
494
|
-
this.index = 0;
|
|
495
|
-
},
|
|
496
|
-
get: function() {
|
|
497
|
-
if (arguments.length !== this.length) return;
|
|
498
|
-
var result = [],
|
|
499
|
-
d = 0;
|
|
500
|
-
for (; d < dim; d++) {
|
|
501
|
-
var i = arguments[d];
|
|
502
|
-
if (i >= this[d].length) return;
|
|
503
|
-
result.push(this[d][i]);
|
|
504
|
-
}
|
|
505
|
-
return (typeof (that._lazyMap) === 'function')?that._lazyMap(result):result;
|
|
506
|
-
},
|
|
507
|
-
nth: function(n) {
|
|
508
|
-
var result = [],
|
|
509
|
-
d = 0;
|
|
510
|
-
for (; d < dim; d++) {
|
|
511
|
-
var l = this[d].length;
|
|
512
|
-
var i = n % l;
|
|
513
|
-
result.push(this[d][i]);
|
|
514
|
-
n -= i;
|
|
515
|
-
n /= l;
|
|
516
|
-
}
|
|
517
|
-
return (typeof (that._lazyMap) === 'function')?that._lazyMap(result):result;
|
|
518
|
-
},
|
|
519
|
-
next: function() {
|
|
520
|
-
if (this.index >= size) return;
|
|
521
|
-
var result = this.nth(this.index);
|
|
522
|
-
this.index++;
|
|
523
|
-
return result;
|
|
524
|
-
}
|
|
525
|
-
});
|
|
526
|
-
addProperties(that, common);
|
|
527
|
-
that.init();
|
|
528
|
-
return that;
|
|
529
|
-
};
|
|
530
|
-
/* baseN */
|
|
531
|
-
var baseN = function(ary, nelem, fun) {
|
|
532
|
-
if (!nelem) nelem = ary.length;
|
|
533
|
-
if (nelem < 1) throw new RangeError;
|
|
534
|
-
var base = ary.length,
|
|
535
|
-
size = Math.pow(base, nelem);
|
|
536
|
-
var sizeOf = function() {
|
|
537
|
-
return size;
|
|
538
|
-
},
|
|
539
|
-
that = Object.create(ary.slice(), {
|
|
540
|
-
length: {
|
|
541
|
-
get: sizeOf
|
|
542
|
-
}
|
|
543
|
-
});
|
|
544
|
-
hideProperty(that, 'index');
|
|
545
|
-
addProperties(that, {
|
|
546
|
-
valueOf: sizeOf,
|
|
547
|
-
init: function() {
|
|
548
|
-
that.index = 0;
|
|
549
|
-
},
|
|
550
|
-
nth: function(n) {
|
|
551
|
-
if (n >= size) return;
|
|
552
|
-
var result = [];
|
|
553
|
-
for (var i = 0; i < nelem; i++) {
|
|
554
|
-
var d = n % base;
|
|
555
|
-
result.push(ary[d]);
|
|
556
|
-
n -= d; n /= base;
|
|
557
|
-
}
|
|
558
|
-
return (typeof (that._lazyMap) === 'function')?that._lazyMap(result):result;
|
|
559
|
-
},
|
|
560
|
-
next: function() {
|
|
561
|
-
return this.nth(this.index++);
|
|
562
|
-
}
|
|
563
|
-
});
|
|
564
|
-
addProperties(that, common);
|
|
565
|
-
that.init();
|
|
566
|
-
return (typeof (fun) === 'function') ? that.map(fun) : that;
|
|
567
|
-
};
|
|
568
|
-
|
|
569
|
-
/* export */
|
|
570
|
-
var Combinatorics = Object.create(null);
|
|
571
|
-
addProperties(Combinatorics, {
|
|
572
|
-
C: C,
|
|
573
|
-
P: P,
|
|
574
|
-
factorial: factorial,
|
|
575
|
-
factoradic: factoradic,
|
|
576
|
-
cartesianProduct: cartesianProduct,
|
|
577
|
-
combination: combination,
|
|
578
|
-
bigCombination: bigCombination,
|
|
579
|
-
permutation: permutation,
|
|
580
|
-
permutationCombination: permutationCombination,
|
|
581
|
-
power: power,
|
|
582
|
-
baseN: baseN,
|
|
583
|
-
VERSION: version
|
|
584
|
-
});
|
|
585
|
-
return Combinatorics;
|
|
586
|
-
}));
|
|
587
|
-
}(combinatorics));
|
|
588
|
-
|
|
589
|
-
const log$1 = debug('pie-elements:placement-ordering:controller');
|
|
590
|
-
const illegalArgumentError = answer => new Error(`Cant score answer: ${answer} it has duplicates and allowDuplicates is false`);
|
|
591
|
-
const pairwiseCombinationScore = (correct, answer, opts) => {
|
|
592
|
-
opts = _extends({
|
|
593
|
-
allowDuplicates: false,
|
|
594
|
-
orderMustBeComplete: false
|
|
595
|
-
}, opts);
|
|
596
|
-
|
|
597
|
-
if (!opts.allowDuplicates && !_.isEqual(_.uniq(correct), correct)) {
|
|
598
|
-
throw illegalArgumentError(answer);
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
if (opts.allowDuplicates === false && answer.length !== _.uniq(answer).length) {
|
|
602
|
-
return 0;
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
answer = opts.allowDuplicates !== false ? answer : _.uniq(answer);
|
|
606
|
-
log$1('answer:', answer);
|
|
607
|
-
|
|
608
|
-
if (!Array.isArray(correct) || correct.length === 0) {
|
|
609
|
-
throw new Error('correct must be non empty an array');
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
if (correct.length === 1) {
|
|
613
|
-
return _.isEqual(correct, answer) ? 1 : 0;
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
if (!Array.isArray(answer) || answer.length < 2) {
|
|
617
|
-
return 0;
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
if (answer.length > correct.length) {
|
|
621
|
-
return 0;
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
if (correct.length !== answer.length && opts.orderMustBeComplete) {
|
|
625
|
-
return 0;
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
const correctCombo = combinatorics.exports.combination(correct, 2).toArray();
|
|
629
|
-
const answerCombo = combinatorics.exports.combination(answer, 2).toArray();
|
|
630
|
-
|
|
631
|
-
const diff = _.differenceWith(answerCombo, correctCombo, _.isEqual);
|
|
632
|
-
|
|
633
|
-
const comboLengthDiff = correctCombo.length - answerCombo.length;
|
|
634
|
-
const total = correctCombo.length;
|
|
635
|
-
const actual = total - diff.length - comboLengthDiff;
|
|
636
|
-
const n = (actual / total).toFixed(2);
|
|
637
|
-
return parseFloat(n);
|
|
638
|
-
};
|
|
639
|
-
/**
|
|
640
|
-
* Flattens the correctResponse into an array of ordered identifiers representing the
|
|
641
|
-
* correct response.
|
|
642
|
-
*/
|
|
643
|
-
|
|
644
|
-
const flattenCorrect = question => question.correctResponse ? question.correctResponse.map(r => r && r.id ? r.id : r) : [];
|
|
645
|
-
/**
|
|
646
|
-
* Returns all correct responses for this question
|
|
647
|
-
* @param question - array
|
|
648
|
-
*/
|
|
649
|
-
|
|
650
|
-
const getAllCorrectResponses = question => {
|
|
651
|
-
const alternates = (question.alternateResponses || []).map(alternate => {
|
|
652
|
-
if (Array.isArray(alternate)) {
|
|
653
|
-
return alternate;
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
return alternate.response;
|
|
657
|
-
}).filter(item => item !== undefined);
|
|
658
|
-
return [flattenCorrect(question), ...alternates];
|
|
659
|
-
};
|
|
660
|
-
/**
|
|
661
|
-
* Returns the score for a session. If weighted scoring is present in the correctResponse
|
|
662
|
-
* field for the question, this will be used. If partial scoring is present in the question
|
|
663
|
-
* model, this will be used. Otherwise the default scoring mechanism (0 for any incorrect, 1
|
|
664
|
-
* for all correct) will be used.
|
|
665
|
-
*/
|
|
666
|
-
|
|
667
|
-
const score = (question, session) => {
|
|
668
|
-
const {
|
|
669
|
-
value
|
|
670
|
-
} = session || {};
|
|
671
|
-
|
|
672
|
-
if (!value) {
|
|
673
|
-
return 0;
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
const allCorrectResponse = getAllCorrectResponses(question);
|
|
677
|
-
const allowDuplicates = (question.configure && question.configure.removeTilesAfterPlacing) !== false;
|
|
678
|
-
/**
|
|
679
|
-
* We require this to be the case - locking
|
|
680
|
-
*/
|
|
681
|
-
//const orderMustBeComplete = true;
|
|
682
|
-
|
|
683
|
-
let bestScore = 0;
|
|
684
|
-
allCorrectResponse.forEach(cr => {
|
|
685
|
-
const currentScore = pairwiseCombinationScore(cr, value, {
|
|
686
|
-
allowDuplicates
|
|
687
|
-
});
|
|
688
|
-
|
|
689
|
-
if (currentScore >= bestScore) {
|
|
690
|
-
bestScore = currentScore;
|
|
691
|
-
}
|
|
692
|
-
});
|
|
693
|
-
return bestScore;
|
|
694
|
-
};
|
|
695
|
-
|
|
696
|
-
var defaults = {
|
|
697
|
-
choiceLabel: '',
|
|
698
|
-
choiceLabelEnabled: true,
|
|
699
|
-
choices: [],
|
|
700
|
-
correctResponse: [],
|
|
701
|
-
feedbackEnabled: false,
|
|
702
|
-
numberedGuides: false,
|
|
703
|
-
orientation: 'vertical',
|
|
704
|
-
partialScoring: true,
|
|
705
|
-
placementArea: false,
|
|
706
|
-
prompt: '',
|
|
707
|
-
promptEnabled: true,
|
|
708
|
-
rationale: '',
|
|
709
|
-
rationaleEnabled: true,
|
|
710
|
-
removeTilesAfterPlacing: true,
|
|
711
|
-
scoringType: 'auto',
|
|
712
|
-
studentInstructionsEnabled: true,
|
|
713
|
-
targetLabel: '',
|
|
714
|
-
teacherInstructions: '',
|
|
715
|
-
teacherInstructionsEnabled: true,
|
|
716
|
-
toolbarEditorPosition: 'bottom'
|
|
717
|
-
};
|
|
718
|
-
|
|
719
|
-
const log = debug('@pie-element:placement-ordering:controller');
|
|
720
|
-
const {
|
|
721
|
-
translator
|
|
722
|
-
} = Translator;
|
|
723
|
-
const questionError = () => new Error('Question is missing required array: correctResponse');
|
|
724
|
-
function outcome(question, session, env) {
|
|
725
|
-
return new Promise((resolve, reject) => {
|
|
726
|
-
if (!session || _.isEmpty(session)) {
|
|
727
|
-
resolve({
|
|
728
|
-
score: 0,
|
|
729
|
-
empty: true
|
|
730
|
-
});
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
if (!question || !question.correctResponse || _.isEmpty(question.correctResponse)) {
|
|
734
|
-
reject(questionError());
|
|
735
|
-
} else {
|
|
736
|
-
try {
|
|
737
|
-
const s = score(question, session);
|
|
738
|
-
const finalScore = partialScoring.enabled(question, env || {}) ? s : s === 1 ? 1 : 0;
|
|
739
|
-
resolve({
|
|
740
|
-
score: finalScore
|
|
741
|
-
});
|
|
742
|
-
} catch (e) {
|
|
743
|
-
reject(e);
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
});
|
|
747
|
-
}
|
|
748
|
-
function createDefaultModel(model = {}) {
|
|
749
|
-
return new Promise(resolve => {
|
|
750
|
-
resolve(_extends({}, defaults, model));
|
|
751
|
-
});
|
|
752
|
-
}
|
|
753
|
-
const normalize = question => _extends({}, defaults, {
|
|
754
|
-
rationaleEnabled: true,
|
|
755
|
-
feedbackEnabled: false,
|
|
756
|
-
promptEnabled: true,
|
|
757
|
-
teacherInstructionsEnabled: true,
|
|
758
|
-
studentInstructionsEnabled: true
|
|
759
|
-
}, question);
|
|
760
|
-
/**
|
|
761
|
-
*
|
|
762
|
-
* @param {*} question
|
|
763
|
-
* @param {*} session
|
|
764
|
-
* @param {*} env
|
|
765
|
-
*/
|
|
766
|
-
|
|
767
|
-
function model(question, session, env) {
|
|
768
|
-
return new Promise(async resolve => {
|
|
769
|
-
const normalizedQuestion = normalize(question);
|
|
770
|
-
const base = {};
|
|
771
|
-
|
|
772
|
-
if (question.alternateResponses && _.every(question.alternateResponses, _.isArray)) {
|
|
773
|
-
log('Deprecated structure of alternateResponses is in use'); // eslint-disable-next-line no-console
|
|
774
|
-
|
|
775
|
-
console.error('Deprecated structure of alternateResponses is in use');
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
base.env = env;
|
|
779
|
-
base.extraCSSRules = normalizedQuestion.extraCSSRules;
|
|
780
|
-
base.outcomes = [];
|
|
781
|
-
base.completeLength = (normalizedQuestion.correctResponse || []).length;
|
|
782
|
-
base.choices = (normalizedQuestion.choices || []).filter(choice => choice.label);
|
|
783
|
-
base.note = normalizedQuestion.note;
|
|
784
|
-
base.showNote = normalizedQuestion.alternateResponses && normalizedQuestion.alternateResponses.length > 0;
|
|
785
|
-
base.language = normalizedQuestion.language;
|
|
786
|
-
log('[model] removing tileSize for the moment.');
|
|
787
|
-
base.prompt = normalizedQuestion.promptEnabled ? normalizedQuestion.prompt : null;
|
|
788
|
-
base.config = {
|
|
789
|
-
orientation: normalizedQuestion.orientation || 'vertical',
|
|
790
|
-
includeTargets: normalizedQuestion.placementArea,
|
|
791
|
-
choiceLabelEnabled: normalizedQuestion.choiceLabelEnabled,
|
|
792
|
-
targetLabel: normalizedQuestion.targetLabel,
|
|
793
|
-
choiceLabel: normalizedQuestion.choiceLabel,
|
|
794
|
-
showOrdering: normalizedQuestion.numberedGuides,
|
|
795
|
-
allowSameChoiceInTargets: !normalizedQuestion.removeTilesAfterPlacing
|
|
796
|
-
};
|
|
797
|
-
base.disabled = env.mode !== 'gather';
|
|
798
|
-
|
|
799
|
-
if (!base.note) {
|
|
800
|
-
base.note = translator.t('common:commonCorrectAnswerWithAlternates', {
|
|
801
|
-
lng: normalizedQuestion.language
|
|
802
|
-
});
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {
|
|
806
|
-
base.rationale = normalizedQuestion.rationaleEnabled ? normalizedQuestion.rationale : null;
|
|
807
|
-
base.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled ? normalizedQuestion.teacherInstructions : null;
|
|
808
|
-
} else {
|
|
809
|
-
base.rationale = null;
|
|
810
|
-
base.teacherInstructions = null;
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
if (env.mode === 'evaluate') {
|
|
814
|
-
const value = session && session.value || [];
|
|
815
|
-
const allCorrectResponses = getAllCorrectResponses(normalizedQuestion);
|
|
816
|
-
const bestSetOfResponses = allCorrectResponses.reduce((info, cr) => {
|
|
817
|
-
const currentScore = _.reduce(value, (acc, c, idx) => acc + (Array.isArray(cr) && cr[idx] === c ? 1 : 0), 0);
|
|
818
|
-
|
|
819
|
-
if (currentScore > info.score) {
|
|
820
|
-
return {
|
|
821
|
-
arr: cr,
|
|
822
|
-
score: currentScore
|
|
823
|
-
};
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
return info;
|
|
827
|
-
}, {
|
|
828
|
-
arr: [],
|
|
829
|
-
score: 0
|
|
830
|
-
});
|
|
831
|
-
base.outcomes = _.map(value, (c, idx) => {
|
|
832
|
-
return {
|
|
833
|
-
id: c,
|
|
834
|
-
outcome: bestSetOfResponses.arr[idx] === c ? 'correct' : 'incorrect'
|
|
835
|
-
};
|
|
836
|
-
});
|
|
837
|
-
const isResponseCorrect = allCorrectResponses.some(response => _.isEqual(response, value));
|
|
838
|
-
const responseScore = score(question, session);
|
|
839
|
-
const isCorrect = responseScore === 1;
|
|
840
|
-
const isPartialCorrect = !isCorrect && partialScoring.enabled(normalizedQuestion, env || {}) && responseScore !== 0;
|
|
841
|
-
base.correctness = isCorrect ? 'correct' : isPartialCorrect ? 'partial' : 'incorrect';
|
|
842
|
-
|
|
843
|
-
if (!isResponseCorrect) {
|
|
844
|
-
base.correctResponse = flattenCorrect(normalizedQuestion);
|
|
845
|
-
} // requirement made in PD-2182
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
if (!normalizedQuestion.feedback) {
|
|
849
|
-
normalizedQuestion.feedbackEnabled = false;
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
const fb = normalizedQuestion.feedbackEnabled ? getFeedbackForCorrectness(base.correctness, normalizedQuestion.feedback) : Promise.resolve(undefined);
|
|
853
|
-
fb.then(feedback => {
|
|
854
|
-
base.feedback = feedback;
|
|
855
|
-
resolve(base);
|
|
856
|
-
});
|
|
857
|
-
} else {
|
|
858
|
-
resolve(base);
|
|
859
|
-
}
|
|
860
|
-
});
|
|
861
|
-
}
|
|
862
|
-
const createCorrectResponseSession = (question, env) => {
|
|
863
|
-
return new Promise(resolve => {
|
|
864
|
-
if (env.mode !== 'evaluate' && env.role === 'instructor') {
|
|
865
|
-
resolve({
|
|
866
|
-
id: '1',
|
|
867
|
-
value: flattenCorrect(question)
|
|
868
|
-
});
|
|
869
|
-
} else {
|
|
870
|
-
resolve(null);
|
|
871
|
-
}
|
|
872
|
-
});
|
|
873
|
-
}; // remove all html tags
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
const getContent = html => (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');
|
|
877
|
-
|
|
878
|
-
const validate = (model = {}, config = {}) => {
|
|
879
|
-
const {
|
|
880
|
-
choices,
|
|
881
|
-
correctResponse
|
|
882
|
-
} = model;
|
|
883
|
-
const errors = {};
|
|
884
|
-
['teacherInstructions', 'prompt', 'rationale'].forEach(field => {
|
|
885
|
-
var _config$field;
|
|
886
|
-
|
|
887
|
-
if ((_config$field = config[field]) != null && _config$field.required && !getContent(model[field])) {
|
|
888
|
-
errors[field] = 'This field is required.';
|
|
889
|
-
}
|
|
890
|
-
});
|
|
891
|
-
const reversedChoices = [...(choices || [])].reverse();
|
|
892
|
-
const choicesErrors = {};
|
|
893
|
-
reversedChoices.forEach((choice, index) => {
|
|
894
|
-
const {
|
|
895
|
-
id,
|
|
896
|
-
label
|
|
897
|
-
} = choice;
|
|
898
|
-
|
|
899
|
-
if (!getContent(label)) {
|
|
900
|
-
choicesErrors[id] = 'Content should not be empty.';
|
|
901
|
-
} else {
|
|
902
|
-
const identicalAnswer = reversedChoices.slice(index + 1).some(c => c.label === label);
|
|
903
|
-
|
|
904
|
-
if (identicalAnswer) {
|
|
905
|
-
choicesErrors[id] = 'Content should be unique.';
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
});
|
|
909
|
-
const choicesIds = (choices || []).map(choice => choice.id);
|
|
910
|
-
const correctResponseIds = (correctResponse || []).map(response => response.id || response);
|
|
911
|
-
|
|
912
|
-
if (isEqual(choicesIds, correctResponseIds)) {
|
|
913
|
-
errors.orderError = 'The correct ordering should not be identical to the initial ordering.';
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
if (!isEmpty(choicesErrors)) {
|
|
917
|
-
errors.choicesErrors = choicesErrors;
|
|
918
|
-
}
|
|
919
|
-
|
|
920
|
-
return errors;
|
|
921
|
-
};
|
|
922
|
-
|
|
923
|
-
export { createCorrectResponseSession, createDefaultModel, model, normalize, outcome, questionError, validate };
|
|
924
|
-
//# sourceMappingURL=controller.js.map
|