likec4 1.48.0 → 1.49.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.
Files changed (113) hide show
  1. package/README.md +11 -1
  2. package/__app__/src/likec4.js +5595 -4127
  3. package/__app__/src/routes/index.js +3 -153
  4. package/__app__/src/routes/projects.js +21 -1087
  5. package/__app__/src/routes/single.js +1221 -16
  6. package/__app__/src/style.css +1 -1
  7. package/__app__/src/vendors.js +3507 -894
  8. package/__app__/src/webcomponent.js +1 -1
  9. package/config/schema.json +155 -143
  10. package/dist/THIRD-PARTY-LICENSES.md +1739 -0
  11. package/dist/_chunks/GraphvizBinaryAdapter.mjs +72 -0
  12. package/dist/_chunks/filenames.mjs +14 -0
  13. package/dist/_chunks/index.d.mts +224 -129
  14. package/dist/_chunks/index2.d.mts +2033 -1908
  15. package/dist/_chunks/libs/@chevrotain/gast.mjs +1 -3969
  16. package/dist/_chunks/libs/@chevrotain/regexp-to-ast.mjs +9 -785
  17. package/dist/_chunks/libs/@chevrotain/utils.mjs +1 -37
  18. package/dist/_chunks/libs/@hono/mcp.mjs +34 -0
  19. package/dist/_chunks/libs/@hono/node-server.mjs +1 -436
  20. package/dist/_chunks/libs/@logtape/logtape.d.mts +741 -0
  21. package/dist/_chunks/libs/@logtape/logtape.mjs +6 -1354
  22. package/dist/_chunks/libs/@lume/kiwi.mjs +1 -1355
  23. package/dist/_chunks/libs/@modelcontextprotocol/sdk.d.mts +14 -14
  24. package/dist/_chunks/libs/@modelcontextprotocol/sdk.mjs +12 -25105
  25. package/dist/_chunks/libs/@msgpack/msgpack.mjs +1 -1503
  26. package/dist/_chunks/libs/@nanostores/react.mjs +1 -30
  27. package/dist/_chunks/libs/@smithy/util-base64.mjs +1 -100
  28. package/dist/_chunks/libs/ajv.mjs +1 -777
  29. package/dist/_chunks/libs/atomically.mjs +1 -362
  30. package/dist/_chunks/libs/birpc.mjs +1 -201
  31. package/dist/_chunks/libs/chevrotain-allstar.mjs +2 -850
  32. package/dist/_chunks/libs/chevrotain.mjs +55 -6229
  33. package/dist/_chunks/libs/conf.mjs +1 -2258
  34. package/dist/_chunks/libs/defu.mjs +1 -42
  35. package/dist/_chunks/libs/esm-env.mjs +1 -5
  36. package/dist/_chunks/libs/eventemitter3.mjs +1 -243
  37. package/dist/_chunks/libs/fast-equals.mjs +1 -446
  38. package/dist/_chunks/libs/find-up-simple.mjs +1 -24
  39. package/dist/_chunks/libs/get-port.mjs +1 -107
  40. package/dist/_chunks/libs/is-docker.mjs +1 -26
  41. package/dist/_chunks/libs/is-error-instance.mjs +1 -26
  42. package/dist/_chunks/libs/is-inside-container.mjs +1 -20
  43. package/dist/_chunks/libs/is-plain-obj.mjs +1 -9
  44. package/dist/_chunks/libs/isexe.mjs +1 -127
  45. package/dist/_chunks/libs/json5.mjs +14 -959
  46. package/dist/_chunks/libs/khroma.mjs +1 -605
  47. package/dist/_chunks/libs/ky.mjs +2 -807
  48. package/dist/_chunks/libs/langium.d.mts +2880 -2844
  49. package/dist/_chunks/libs/langium.mjs +32 -20351
  50. package/dist/_chunks/libs/merge-error-cause.mjs +2 -746
  51. package/dist/_chunks/libs/nanostores.mjs +1 -198
  52. package/dist/_chunks/libs/p-limit.mjs +1 -120
  53. package/dist/_chunks/libs/p-queue.mjs +1 -449
  54. package/dist/_chunks/libs/package-manager-detector.mjs +1 -559
  55. package/dist/_chunks/libs/package-up.mjs +1 -10
  56. package/dist/_chunks/libs/parse-ms.mjs +1 -36
  57. package/dist/_chunks/libs/pathe.mjs +1 -0
  58. package/dist/_chunks/libs/picomatch.mjs +1 -1673
  59. package/dist/_chunks/libs/pretty-ms.mjs +1 -80
  60. package/dist/_chunks/libs/remeda.mjs +1 -690
  61. package/dist/_chunks/libs/safe-stringify.mjs +1 -21
  62. package/dist/_chunks/libs/strip-indent.mjs +1 -15
  63. package/dist/_chunks/libs/tinyrainbow.mjs +1 -88
  64. package/dist/_chunks/libs/ts-graphviz.mjs +4 -725
  65. package/dist/_chunks/libs/ufo.mjs +1 -240
  66. package/dist/_chunks/libs/which.mjs +1 -84
  67. package/dist/_chunks/libs/word-wrap.mjs +12 -43
  68. package/dist/_chunks/node.mjs +481 -0
  69. package/dist/_chunks/plugin.mjs +98 -772
  70. package/dist/_chunks/rolldown-runtime.mjs +1 -48
  71. package/dist/_chunks/sequence-view.mjs +1 -575
  72. package/dist/cli/index.mjs +127 -1846
  73. package/dist/config/index.d.mts +2 -2
  74. package/dist/config/index.mjs +1 -6
  75. package/dist/index.d.mts +148 -7
  76. package/dist/index.mjs +1 -21
  77. package/dist/model/builder.mjs +1 -3
  78. package/dist/model/index.d.mts +57 -3
  79. package/dist/model/index.mjs +1 -5
  80. package/dist/vite-plugin/index.d.mts +4 -3
  81. package/dist/vite-plugin/index.mjs +1 -22
  82. package/dist/vite-plugin/internal.d.mts +5 -5
  83. package/dist/vite-plugin/internal.mjs +1 -68
  84. package/package.json +60 -41
  85. package/react/{index.d.ts → index.d.mts} +112 -70
  86. package/react/{index.js → index.mjs} +21361 -22064
  87. package/react/package.json +2 -5
  88. package/vite-plugin-modules.d.ts +5 -5
  89. package/dist/_chunks/LikeC4.d.mts +0 -121
  90. package/dist/_chunks/LikeC4.mjs +0 -202
  91. package/dist/_chunks/config-app.prod.d.mts +0 -18
  92. package/dist/_chunks/config-app.prod.mjs +0 -188
  93. package/dist/_chunks/config-webcomponent.prod.mjs +0 -71
  94. package/dist/_chunks/define-config.mjs +0 -409
  95. package/dist/_chunks/index3.d.mts +0 -60
  96. package/dist/_chunks/index4.d.mts +0 -1
  97. package/dist/_chunks/libs/@smithy/is-array-buffer.mjs +0 -10
  98. package/dist/_chunks/libs/hono.mjs +0 -1829
  99. package/dist/_chunks/libs/nanoid.mjs +0 -29
  100. package/dist/_chunks/model.mjs +0 -12
  101. package/dist/_chunks/module.d.mts +0 -71
  102. package/dist/_chunks/module.mjs +0 -18657
  103. package/dist/_chunks/vite-build.mjs +0 -69
  104. package/dist/_chunks/vite-dev.mjs +0 -79
  105. package/dist/_chunks/vite-preview.mjs +0 -27
  106. package/dist/language/module.d.mts +0 -5
  107. package/dist/language/module.mjs +0 -20
  108. package/dist/vite/vite-build.d.mts +0 -26
  109. package/dist/vite/vite-build.mjs +0 -27
  110. package/dist/vite/vite-dev.d.mts +0 -34
  111. package/dist/vite/vite-dev.mjs +0 -29
  112. package/dist/vite/vite-preview.d.mts +0 -20
  113. package/dist/vite/vite-preview.mjs +0 -26
@@ -1,1355 +1 @@
1
- //#region ../../node_modules/.pnpm/@lume+kiwi@0.4.4/node_modules/@lume/kiwi/dist/maptype.js
2
- function createMap() {
3
- return new IndexedMap();
4
- }
5
- var IndexedMap = class IndexedMap {
6
- index = {};
7
- array = [];
8
- /**
9
- * Returns the number of items in the array.
10
- */
11
- size() {
12
- return this.array.length;
13
- }
14
- /**
15
- * Returns true if the array is empty.
16
- */
17
- empty() {
18
- return this.array.length === 0;
19
- }
20
- /**
21
- * Returns the item at the given array index.
22
- *
23
- * @param index The integer index of the desired item.
24
- */
25
- itemAt(index) {
26
- return this.array[index];
27
- }
28
- /**
29
- * Returns true if the key is in the array, false otherwise.
30
- *
31
- * @param key The key to locate in the array.
32
- */
33
- contains(key) {
34
- return this.index[key.id()] !== void 0;
35
- }
36
- /**
37
- * Returns the pair associated with the given key, or undefined.
38
- *
39
- * @param key The key to locate in the array.
40
- */
41
- find(key) {
42
- const i = this.index[key.id()];
43
- return i === void 0 ? void 0 : this.array[i];
44
- }
45
- /**
46
- * Returns the pair associated with the key if it exists.
47
- *
48
- * If the key does not exist, a new pair will be created and
49
- * inserted using the value created by the given factory.
50
- *
51
- * @param key The key to locate in the array.
52
- * @param factory The function which creates the default value.
53
- */
54
- setDefault(key, factory) {
55
- const i = this.index[key.id()];
56
- if (i === void 0) {
57
- const pair = new Pair(key, factory());
58
- this.index[key.id()] = this.array.length;
59
- this.array.push(pair);
60
- return pair;
61
- } else return this.array[i];
62
- }
63
- /**
64
- * Insert the pair into the array and return the pair.
65
- *
66
- * This will overwrite any existing entry in the array.
67
- *
68
- * @param key The key portion of the pair.
69
- * @param value The value portion of the pair.
70
- */
71
- insert(key, value) {
72
- const pair = new Pair(key, value);
73
- const i = this.index[key.id()];
74
- if (i === void 0) {
75
- this.index[key.id()] = this.array.length;
76
- this.array.push(pair);
77
- } else this.array[i] = pair;
78
- return pair;
79
- }
80
- /**
81
- * Removes and returns the pair for the given key, or undefined.
82
- *
83
- * @param key The key to remove from the map.
84
- */
85
- erase(key) {
86
- const i = this.index[key.id()];
87
- if (i === void 0) return;
88
- this.index[key.id()] = void 0;
89
- const pair = this.array[i];
90
- const last = this.array.pop();
91
- if (pair !== last) {
92
- this.array[i] = last;
93
- this.index[last.first.id()] = i;
94
- }
95
- return pair;
96
- }
97
- /**
98
- * Create a copy of this associative array.
99
- */
100
- copy() {
101
- const copy = new IndexedMap();
102
- for (let i = 0; i < this.array.length; i++) {
103
- const pair = this.array[i].copy();
104
- copy.array[i] = pair;
105
- copy.index[pair.first.id()] = i;
106
- }
107
- return copy;
108
- }
109
- };
110
- /**
111
- * A class which defines a generic pair object.
112
- * @private
113
- */
114
- var Pair = class Pair {
115
- first;
116
- second;
117
- /**
118
- * Construct a new Pair object.
119
- *
120
- * @param first The first item of the pair.
121
- * @param second The second item of the pair.
122
- */
123
- constructor(first, second) {
124
- this.first = first;
125
- this.second = second;
126
- }
127
- /**
128
- * Create a copy of the pair.
129
- */
130
- copy() {
131
- return new Pair(this.first, this.second);
132
- }
133
- };
134
-
135
- //#endregion
136
- //#region ../../node_modules/.pnpm/@lume+kiwi@0.4.4/node_modules/@lume/kiwi/dist/variable.js
137
- /**
138
- * The primary user constraint variable.
139
- *
140
- * @class
141
- * @param {String} [name=""] The name to associated with the variable.
142
- */
143
- var Variable = class {
144
- constructor(name = "") {
145
- this._name = name;
146
- }
147
- /**
148
- * Returns the unique id number of the variable.
149
- * @private
150
- */
151
- id() {
152
- return this._id;
153
- }
154
- /**
155
- * Returns the name of the variable.
156
- *
157
- * @return {String} name of the variable
158
- */
159
- name() {
160
- return this._name;
161
- }
162
- /**
163
- * Set the name of the variable.
164
- *
165
- * @param {String} name Name of the variable
166
- */
167
- setName(name) {
168
- this._name = name;
169
- }
170
- /**
171
- * Returns the user context object of the variable.
172
- * @private
173
- */
174
- context() {
175
- return this._context;
176
- }
177
- /**
178
- * Set the user context object of the variable.
179
- * @private
180
- */
181
- setContext(context) {
182
- this._context = context;
183
- }
184
- /**
185
- * Returns the value of the variable.
186
- *
187
- * @return {Number} Calculated value
188
- */
189
- value() {
190
- return this._value;
191
- }
192
- /**
193
- * Set the value of the variable.
194
- * @private
195
- */
196
- setValue(value) {
197
- this._value = value;
198
- }
199
- /**
200
- * Creates a new Expression by adding a number, variable or expression
201
- * to the variable.
202
- *
203
- * @param {Number|Variable|Expression} value Value to add.
204
- * @return {Expression} expression
205
- */
206
- plus(value) {
207
- return new Expression(this, value);
208
- }
209
- /**
210
- * Creates a new Expression by substracting a number, variable or expression
211
- * from the variable.
212
- *
213
- * @param {Number|Variable|Expression} value Value to substract.
214
- * @return {Expression} expression
215
- */
216
- minus(value) {
217
- return new Expression(this, typeof value === "number" ? -value : [-1, value]);
218
- }
219
- /**
220
- * Creates a new Expression by multiplying with a fixed number.
221
- *
222
- * @param {Number} coefficient Coefficient to multiply with.
223
- * @return {Expression} expression
224
- */
225
- multiply(coefficient) {
226
- return new Expression([coefficient, this]);
227
- }
228
- /**
229
- * Creates a new Expression by dividing with a fixed number.
230
- *
231
- * @param {Number} coefficient Coefficient to divide by.
232
- * @return {Expression} expression
233
- */
234
- divide(coefficient) {
235
- return new Expression([1 / coefficient, this]);
236
- }
237
- /**
238
- * Returns the JSON representation of the variable.
239
- * @private
240
- */
241
- toJSON() {
242
- return {
243
- name: this._name,
244
- value: this._value
245
- };
246
- }
247
- toString() {
248
- return this._context + "[" + this._name + ":" + this._value + "]";
249
- }
250
- _name;
251
- _value = 0;
252
- _context = null;
253
- _id = VarId++;
254
- };
255
- /**
256
- * The internal variable id counter.
257
- * @private
258
- */
259
- let VarId = 0;
260
-
261
- //#endregion
262
- //#region ../../node_modules/.pnpm/@lume+kiwi@0.4.4/node_modules/@lume/kiwi/dist/expression.js
263
- /**
264
- * An expression of variable terms and a constant.
265
- *
266
- * The constructor accepts an arbitrary number of parameters,
267
- * each of which must be one of the following types:
268
- * - number
269
- * - Variable
270
- * - Expression
271
- * - 2-tuple of [number, Variable|Expression]
272
- *
273
- * The parameters are summed. The tuples are multiplied.
274
- *
275
- * @class
276
- * @param {...(number|Variable|Expression|Array)} args
277
- */
278
- var Expression = class Expression {
279
- constructor() {
280
- let parsed = parseArgs(arguments);
281
- this._terms = parsed.terms;
282
- this._constant = parsed.constant;
283
- }
284
- /**
285
- * Returns the mapping of terms in the expression.
286
- *
287
- * This *must* be treated as const.
288
- * @private
289
- */
290
- terms() {
291
- return this._terms;
292
- }
293
- /**
294
- * Returns the constant of the expression.
295
- * @private
296
- */
297
- constant() {
298
- return this._constant;
299
- }
300
- /**
301
- * Returns the computed value of the expression.
302
- *
303
- * @private
304
- * @return {Number} computed value of the expression
305
- */
306
- value() {
307
- let result = this._constant;
308
- for (let i = 0, n = this._terms.size(); i < n; i++) {
309
- let pair = this._terms.itemAt(i);
310
- result += pair.first.value() * pair.second;
311
- }
312
- return result;
313
- }
314
- /**
315
- * Creates a new Expression by adding a number, variable or expression
316
- * to the expression.
317
- *
318
- * @param {Number|Variable|Expression} value Value to add.
319
- * @return {Expression} expression
320
- */
321
- plus(value) {
322
- return new Expression(this, value);
323
- }
324
- /**
325
- * Creates a new Expression by substracting a number, variable or expression
326
- * from the expression.
327
- *
328
- * @param {Number|Variable|Expression} value Value to substract.
329
- * @return {Expression} expression
330
- */
331
- minus(value) {
332
- return new Expression(this, typeof value === "number" ? -value : [-1, value]);
333
- }
334
- /**
335
- * Creates a new Expression by multiplying with a fixed number.
336
- *
337
- * @param {Number} coefficient Coefficient to multiply with.
338
- * @return {Expression} expression
339
- */
340
- multiply(coefficient) {
341
- return new Expression([coefficient, this]);
342
- }
343
- /**
344
- * Creates a new Expression by dividing with a fixed number.
345
- *
346
- * @param {Number} coefficient Coefficient to divide by.
347
- * @return {Expression} expression
348
- */
349
- divide(coefficient) {
350
- return new Expression([1 / coefficient, this]);
351
- }
352
- isConstant() {
353
- return this._terms.size() == 0;
354
- }
355
- toString() {
356
- let result = this._terms.array.map(function(pair) {
357
- return pair.second + "*" + pair.first.toString();
358
- }).join(" + ");
359
- if (!this.isConstant() && this._constant !== 0) result += " + ";
360
- result += this._constant;
361
- return result;
362
- }
363
- _terms;
364
- _constant;
365
- };
366
- /**
367
- * An internal argument parsing function.
368
- * @private
369
- */
370
- function parseArgs(args) {
371
- let constant = 0;
372
- let factory = () => 0;
373
- let terms = createMap();
374
- for (let i = 0, n = args.length; i < n; ++i) {
375
- let item = args[i];
376
- if (typeof item === "number") constant += item;
377
- else if (item instanceof Variable) terms.setDefault(item, factory).second += 1;
378
- else if (item instanceof Expression) {
379
- constant += item.constant();
380
- let terms2 = item.terms();
381
- for (let j = 0, k = terms2.size(); j < k; j++) {
382
- let termPair = terms2.itemAt(j);
383
- terms.setDefault(termPair.first, factory).second += termPair.second;
384
- }
385
- } else if (item instanceof Array) {
386
- if (item.length !== 2) throw new Error("array must have length 2");
387
- let value = item[0];
388
- let value2 = item[1];
389
- if (typeof value !== "number") throw new Error("array item 0 must be a number");
390
- if (value2 instanceof Variable) terms.setDefault(value2, factory).second += value;
391
- else if (value2 instanceof Expression) {
392
- constant += value2.constant() * value;
393
- let terms2 = value2.terms();
394
- for (let j = 0, k = terms2.size(); j < k; j++) {
395
- let termPair = terms2.itemAt(j);
396
- terms.setDefault(termPair.first, factory).second += termPair.second * value;
397
- }
398
- } else throw new Error("array item 1 must be a variable or expression");
399
- } else throw new Error("invalid Expression argument: " + item);
400
- }
401
- return {
402
- terms,
403
- constant
404
- };
405
- }
406
-
407
- //#endregion
408
- //#region ../../node_modules/.pnpm/@lume+kiwi@0.4.4/node_modules/@lume/kiwi/dist/strength.js
409
- /**
410
- * @class Strength
411
- */
412
- var Strength = class Strength {
413
- /**
414
- * Create a new symbolic strength.
415
- *
416
- * @param a strong
417
- * @param b medium
418
- * @param c weak
419
- * @param [w] weight
420
- * @return strength
421
- */
422
- static create(a, b, c, w = 1) {
423
- let result = 0;
424
- result += Math.max(0, Math.min(1e3, a * w)) * 1e6;
425
- result += Math.max(0, Math.min(1e3, b * w)) * 1e3;
426
- result += Math.max(0, Math.min(1e3, c * w));
427
- return result;
428
- }
429
- /**
430
- * The 'required' symbolic strength.
431
- */
432
- static required = Strength.create(1e3, 1e3, 1e3);
433
- /**
434
- * The 'strong' symbolic strength.
435
- */
436
- static strong = Strength.create(1, 0, 0);
437
- /**
438
- * The 'medium' symbolic strength.
439
- */
440
- static medium = Strength.create(0, 1, 0);
441
- /**
442
- * The 'weak' symbolic strength.
443
- */
444
- static weak = Strength.create(0, 0, 1);
445
- /**
446
- * Clip a symbolic strength to the allowed min and max.
447
- * @private
448
- */
449
- static clip(value) {
450
- return Math.max(0, Math.min(Strength.required, value));
451
- }
452
- };
453
-
454
- //#endregion
455
- //#region ../../node_modules/.pnpm/@lume+kiwi@0.4.4/node_modules/@lume/kiwi/dist/constraint.js
456
- /**
457
- * An enum defining the linear constraint operators.
458
- *
459
- * |Value|Operator|Description|
460
- * |----|-----|-----|
461
- * |`Le`|<=|Less than equal|
462
- * |`Ge`|>=|Greater than equal|
463
- * |`Eq`|==|Equal|
464
- *
465
- * @enum {Number}
466
- */
467
- var Operator;
468
- (function(Operator) {
469
- Operator[Operator["Le"] = 0] = "Le";
470
- Operator[Operator["Ge"] = 1] = "Ge";
471
- Operator[Operator["Eq"] = 2] = "Eq";
472
- })(Operator || (Operator = {}));
473
- /**
474
- * A linear constraint equation.
475
- *
476
- * A constraint equation is composed of an expression, an operator,
477
- * and a strength. The RHS of the equation is implicitly zero.
478
- *
479
- * @class
480
- * @param {Expression} expression The constraint expression (LHS).
481
- * @param {Operator} operator The equation operator.
482
- * @param {Expression} [rhs] Right hand side of the expression.
483
- * @param {Number} [strength=Strength.required] The strength of the constraint.
484
- */
485
- var Constraint = class {
486
- constructor(expression, operator, rhs, strength = Strength.required) {
487
- this._operator = operator;
488
- this._strength = Strength.clip(strength);
489
- if (rhs === void 0 && expression instanceof Expression) this._expression = expression;
490
- else this._expression = expression.minus(rhs);
491
- }
492
- /**
493
- * Returns the unique id number of the constraint.
494
- * @private
495
- */
496
- id() {
497
- return this._id;
498
- }
499
- /**
500
- * Returns the expression of the constraint.
501
- *
502
- * @return {Expression} expression
503
- */
504
- expression() {
505
- return this._expression;
506
- }
507
- /**
508
- * Returns the relational operator of the constraint.
509
- *
510
- * @return {Operator} linear constraint operator
511
- */
512
- op() {
513
- return this._operator;
514
- }
515
- /**
516
- * Returns the strength of the constraint.
517
- *
518
- * @return {Number} strength
519
- */
520
- strength() {
521
- return this._strength;
522
- }
523
- toString() {
524
- return this._expression.toString() + " " + [
525
- "<=",
526
- ">=",
527
- "="
528
- ][this._operator] + " 0 (" + this._strength.toString() + ")";
529
- }
530
- _expression;
531
- _operator;
532
- _strength;
533
- _id = CnId++;
534
- };
535
- /**
536
- * The internal constraint id counter.
537
- * @private
538
- */
539
- let CnId = 0;
540
-
541
- //#endregion
542
- //#region ../../node_modules/.pnpm/@lume+kiwi@0.4.4/node_modules/@lume/kiwi/dist/solver.js
543
- /**
544
- * The constraint solver class.
545
- *
546
- * @class
547
- */
548
- var Solver = class {
549
- /**
550
- * @type {number} - The max number of solver iterations before an error
551
- * is thrown, in order to prevent infinite iteration. Default: `10,000`.
552
- */
553
- maxIterations = 1e3;
554
- /**
555
- * Construct a new Solver.
556
- */
557
- constructor() {}
558
- /**
559
- * Creates and add a constraint to the solver.
560
- *
561
- * @param {Expression|Variable} lhs Left hand side of the expression
562
- * @param {Operator} operator Operator
563
- * @param {Expression|Variable|Number} rhs Right hand side of the expression
564
- * @param {Number} [strength=Strength.required] Strength
565
- */
566
- createConstraint(lhs, operator, rhs, strength = Strength.required) {
567
- let cn = new Constraint(lhs, operator, rhs, strength);
568
- this.addConstraint(cn);
569
- return cn;
570
- }
571
- /**
572
- * Add a constraint to the solver.
573
- *
574
- * @param {Constraint} constraint Constraint to add to the solver
575
- */
576
- addConstraint(constraint) {
577
- if (this._cnMap.find(constraint) !== void 0) throw new Error("duplicate constraint");
578
- let data = this._createRow(constraint);
579
- let row = data.row;
580
- let tag = data.tag;
581
- let subject = this._chooseSubject(row, tag);
582
- if (subject.type() === SymbolType.Invalid && row.allDummies()) if (!nearZero(row.constant())) throw new Error("unsatisfiable constraint");
583
- else subject = tag.marker;
584
- if (subject.type() === SymbolType.Invalid) {
585
- if (!this._addWithArtificialVariable(row)) throw new Error("unsatisfiable constraint");
586
- } else {
587
- row.solveFor(subject);
588
- this._substitute(subject, row);
589
- this._rowMap.insert(subject, row);
590
- }
591
- this._cnMap.insert(constraint, tag);
592
- this._optimize(this._objective);
593
- }
594
- /**
595
- * Remove a constraint from the solver.
596
- *
597
- * @param {Constraint} constraint Constraint to remove from the solver
598
- */
599
- removeConstraint(constraint) {
600
- let cnPair = this._cnMap.erase(constraint);
601
- if (cnPair === void 0) throw new Error("unknown constraint");
602
- this._removeConstraintEffects(constraint, cnPair.second);
603
- let marker = cnPair.second.marker;
604
- let rowPair = this._rowMap.erase(marker);
605
- if (rowPair === void 0) {
606
- let leaving = this._getMarkerLeavingSymbol(marker);
607
- if (leaving.type() === SymbolType.Invalid) throw new Error("failed to find leaving row");
608
- rowPair = this._rowMap.erase(leaving);
609
- rowPair.second.solveForEx(leaving, marker);
610
- this._substitute(marker, rowPair.second);
611
- }
612
- this._optimize(this._objective);
613
- }
614
- /**
615
- * Test whether the solver contains the constraint.
616
- *
617
- * @param {Constraint} constraint Constraint to test for
618
- * @return {Bool} true or false
619
- */
620
- hasConstraint(constraint) {
621
- return this._cnMap.contains(constraint);
622
- }
623
- /**
624
- * Get an array of the current constraints.
625
- *
626
- * @return {Constraint[]}
627
- */
628
- getConstraints() {
629
- return this._cnMap.array.map(({ first }) => first);
630
- }
631
- /**
632
- * Add an edit variable to the solver.
633
- *
634
- * @param {Variable} variable Edit variable to add to the solver
635
- * @param {Number} strength Strength, should be less than `Strength.required`
636
- */
637
- addEditVariable(variable, strength) {
638
- if (this._editMap.find(variable) !== void 0) throw new Error("duplicate edit variable");
639
- strength = Strength.clip(strength);
640
- if (strength === Strength.required) throw new Error("bad required strength");
641
- let cn = new Constraint(new Expression(variable), Operator.Eq, void 0, strength);
642
- this.addConstraint(cn);
643
- let info = {
644
- tag: this._cnMap.find(cn).second,
645
- constraint: cn,
646
- constant: 0
647
- };
648
- this._editMap.insert(variable, info);
649
- }
650
- /**
651
- * Remove an edit variable from the solver.
652
- *
653
- * @param {Variable} variable Edit variable to remove from the solver
654
- */
655
- removeEditVariable(variable) {
656
- let editPair = this._editMap.erase(variable);
657
- if (editPair === void 0) throw new Error("unknown edit variable");
658
- this.removeConstraint(editPair.second.constraint);
659
- }
660
- /**
661
- * Test whether the solver contains the edit variable.
662
- *
663
- * @param {Variable} variable Edit variable to test for
664
- * @return {Bool} true or false
665
- */
666
- hasEditVariable(variable) {
667
- return this._editMap.contains(variable);
668
- }
669
- /**
670
- * Suggest the value of an edit variable.
671
- *
672
- * @param {Variable} variable Edit variable to suggest a value for
673
- * @param {Number} value Suggested value
674
- */
675
- suggestValue(variable, value) {
676
- let editPair = this._editMap.find(variable);
677
- if (editPair === void 0) throw new Error("unknown edit variable");
678
- let rows = this._rowMap;
679
- let info = editPair.second;
680
- let delta = value - info.constant;
681
- info.constant = value;
682
- let marker = info.tag.marker;
683
- let rowPair = rows.find(marker);
684
- if (rowPair !== void 0) {
685
- if (rowPair.second.add(-delta) < 0) this._infeasibleRows.push(marker);
686
- this._dualOptimize();
687
- return;
688
- }
689
- let other = info.tag.other;
690
- rowPair = rows.find(other);
691
- if (rowPair !== void 0) {
692
- if (rowPair.second.add(delta) < 0) this._infeasibleRows.push(other);
693
- this._dualOptimize();
694
- return;
695
- }
696
- for (let i = 0, n = rows.size(); i < n; ++i) {
697
- let rowPair = rows.itemAt(i);
698
- let row = rowPair.second;
699
- let coeff = row.coefficientFor(marker);
700
- if (coeff !== 0 && row.add(delta * coeff) < 0 && rowPair.first.type() !== SymbolType.External) this._infeasibleRows.push(rowPair.first);
701
- }
702
- this._dualOptimize();
703
- }
704
- /**
705
- * Update the values of the variables.
706
- */
707
- updateVariables() {
708
- let vars = this._varMap;
709
- let rows = this._rowMap;
710
- for (let i = 0, n = vars.size(); i < n; ++i) {
711
- let pair = vars.itemAt(i);
712
- let rowPair = rows.find(pair.second);
713
- if (rowPair !== void 0) pair.first.setValue(rowPair.second.constant());
714
- else pair.first.setValue(0);
715
- }
716
- }
717
- /**
718
- * Get the symbol for the given variable.
719
- *
720
- * If a symbol does not exist for the variable, one will be created.
721
- * @private
722
- */
723
- _getVarSymbol(variable) {
724
- let factory = () => this._makeSymbol(SymbolType.External);
725
- return this._varMap.setDefault(variable, factory).second;
726
- }
727
- /**
728
- * Create a new Row object for the given constraint.
729
- *
730
- * The terms in the constraint will be converted to cells in the row.
731
- * Any term in the constraint with a coefficient of zero is ignored.
732
- * This method uses the `_getVarSymbol` method to get the symbol for
733
- * the variables added to the row. If the symbol for a given cell
734
- * variable is basic, the cell variable will be substituted with the
735
- * basic row.
736
- *
737
- * The necessary slack and error variables will be added to the row.
738
- * If the constant for the row is negative, the sign for the row
739
- * will be inverted so the constant becomes positive.
740
- *
741
- * Returns the created Row and the tag for tracking the constraint.
742
- * @private
743
- */
744
- _createRow(constraint) {
745
- let expr = constraint.expression();
746
- let row = new Row(expr.constant());
747
- let terms = expr.terms();
748
- for (let i = 0, n = terms.size(); i < n; ++i) {
749
- let termPair = terms.itemAt(i);
750
- if (!nearZero(termPair.second)) {
751
- let symbol = this._getVarSymbol(termPair.first);
752
- let basicPair = this._rowMap.find(symbol);
753
- if (basicPair !== void 0) row.insertRow(basicPair.second, termPair.second);
754
- else row.insertSymbol(symbol, termPair.second);
755
- }
756
- }
757
- let objective = this._objective;
758
- let strength = constraint.strength();
759
- let tag = {
760
- marker: INVALID_SYMBOL,
761
- other: INVALID_SYMBOL
762
- };
763
- switch (constraint.op()) {
764
- case Operator.Le:
765
- case Operator.Ge: {
766
- let coeff = constraint.op() === Operator.Le ? 1 : -1;
767
- let slack = this._makeSymbol(SymbolType.Slack);
768
- tag.marker = slack;
769
- row.insertSymbol(slack, coeff);
770
- if (strength < Strength.required) {
771
- let error = this._makeSymbol(SymbolType.Error);
772
- tag.other = error;
773
- row.insertSymbol(error, -coeff);
774
- objective.insertSymbol(error, strength);
775
- }
776
- break;
777
- }
778
- case Operator.Eq:
779
- if (strength < Strength.required) {
780
- let errplus = this._makeSymbol(SymbolType.Error);
781
- let errminus = this._makeSymbol(SymbolType.Error);
782
- tag.marker = errplus;
783
- tag.other = errminus;
784
- row.insertSymbol(errplus, -1);
785
- row.insertSymbol(errminus, 1);
786
- objective.insertSymbol(errplus, strength);
787
- objective.insertSymbol(errminus, strength);
788
- } else {
789
- let dummy = this._makeSymbol(SymbolType.Dummy);
790
- tag.marker = dummy;
791
- row.insertSymbol(dummy);
792
- }
793
- break;
794
- }
795
- if (row.constant() < 0) row.reverseSign();
796
- return {
797
- row,
798
- tag
799
- };
800
- }
801
- /**
802
- * Choose the subject for solving for the row.
803
- *
804
- * This method will choose the best subject for using as the solve
805
- * target for the row. An invalid symbol will be returned if there
806
- * is no valid target.
807
- *
808
- * The symbols are chosen according to the following precedence:
809
- *
810
- * 1) The first symbol representing an external variable.
811
- * 2) A negative slack or error tag variable.
812
- *
813
- * If a subject cannot be found, an invalid symbol will be returned.
814
- *
815
- * @private
816
- */
817
- _chooseSubject(row, tag) {
818
- let cells = row.cells();
819
- for (let i = 0, n = cells.size(); i < n; ++i) {
820
- let pair = cells.itemAt(i);
821
- if (pair.first.type() === SymbolType.External) return pair.first;
822
- }
823
- let type = tag.marker.type();
824
- if (type === SymbolType.Slack || type === SymbolType.Error) {
825
- if (row.coefficientFor(tag.marker) < 0) return tag.marker;
826
- }
827
- type = tag.other.type();
828
- if (type === SymbolType.Slack || type === SymbolType.Error) {
829
- if (row.coefficientFor(tag.other) < 0) return tag.other;
830
- }
831
- return INVALID_SYMBOL;
832
- }
833
- /**
834
- * Add the row to the tableau using an artificial variable.
835
- *
836
- * This will return false if the constraint cannot be satisfied.
837
- *
838
- * @private
839
- */
840
- _addWithArtificialVariable(row) {
841
- let art = this._makeSymbol(SymbolType.Slack);
842
- this._rowMap.insert(art, row.copy());
843
- this._artificial = row.copy();
844
- this._optimize(this._artificial);
845
- let success = nearZero(this._artificial.constant());
846
- this._artificial = null;
847
- let pair = this._rowMap.erase(art);
848
- if (pair !== void 0) {
849
- let basicRow = pair.second;
850
- if (basicRow.isConstant()) return success;
851
- let entering = this._anyPivotableSymbol(basicRow);
852
- if (entering.type() === SymbolType.Invalid) return false;
853
- basicRow.solveForEx(art, entering);
854
- this._substitute(entering, basicRow);
855
- this._rowMap.insert(entering, basicRow);
856
- }
857
- let rows = this._rowMap;
858
- for (let i = 0, n = rows.size(); i < n; ++i) rows.itemAt(i).second.removeSymbol(art);
859
- this._objective.removeSymbol(art);
860
- return success;
861
- }
862
- /**
863
- * Substitute the parametric symbol with the given row.
864
- *
865
- * This method will substitute all instances of the parametric symbol
866
- * in the tableau and the objective function with the given row.
867
- *
868
- * @private
869
- */
870
- _substitute(symbol, row) {
871
- let rows = this._rowMap;
872
- for (let i = 0, n = rows.size(); i < n; ++i) {
873
- let pair = rows.itemAt(i);
874
- pair.second.substitute(symbol, row);
875
- if (pair.second.constant() < 0 && pair.first.type() !== SymbolType.External) this._infeasibleRows.push(pair.first);
876
- }
877
- this._objective.substitute(symbol, row);
878
- if (this._artificial) this._artificial.substitute(symbol, row);
879
- }
880
- /**
881
- * Optimize the system for the given objective function.
882
- *
883
- * This method performs iterations of Phase 2 of the simplex method
884
- * until the objective function reaches a minimum.
885
- *
886
- * @private
887
- */
888
- _optimize(objective) {
889
- let iterations = 0;
890
- while (iterations < this.maxIterations) {
891
- let entering = this._getEnteringSymbol(objective);
892
- if (entering.type() === SymbolType.Invalid) return;
893
- let leaving = this._getLeavingSymbol(entering);
894
- if (leaving.type() === SymbolType.Invalid) throw new Error("the objective is unbounded");
895
- let row = this._rowMap.erase(leaving).second;
896
- row.solveForEx(leaving, entering);
897
- this._substitute(entering, row);
898
- this._rowMap.insert(entering, row);
899
- iterations++;
900
- }
901
- throw new Error("solver iterations exceeded");
902
- }
903
- /**
904
- * Optimize the system using the dual of the simplex method.
905
- *
906
- * The current state of the system should be such that the objective
907
- * function is optimal, but not feasible. This method will perform
908
- * an iteration of the dual simplex method to make the solution both
909
- * optimal and feasible.
910
- *
911
- * @private
912
- */
913
- _dualOptimize() {
914
- let rows = this._rowMap;
915
- let infeasible = this._infeasibleRows;
916
- while (infeasible.length !== 0) {
917
- let leaving = infeasible.pop();
918
- let pair = rows.find(leaving);
919
- if (pair !== void 0 && pair.second.constant() < 0) {
920
- let entering = this._getDualEnteringSymbol(pair.second);
921
- if (entering.type() === SymbolType.Invalid) throw new Error("dual optimize failed");
922
- let row = pair.second;
923
- rows.erase(leaving);
924
- row.solveForEx(leaving, entering);
925
- this._substitute(entering, row);
926
- rows.insert(entering, row);
927
- }
928
- }
929
- }
930
- /**
931
- * Compute the entering variable for a pivot operation.
932
- *
933
- * This method will return first symbol in the objective function which
934
- * is non-dummy and has a coefficient less than zero. If no symbol meets
935
- * the criteria, it means the objective function is at a minimum, and an
936
- * invalid symbol is returned.
937
- *
938
- * @private
939
- */
940
- _getEnteringSymbol(objective) {
941
- let cells = objective.cells();
942
- for (let i = 0, n = cells.size(); i < n; ++i) {
943
- let pair = cells.itemAt(i);
944
- let symbol = pair.first;
945
- if (pair.second < 0 && symbol.type() !== SymbolType.Dummy) return symbol;
946
- }
947
- return INVALID_SYMBOL;
948
- }
949
- /**
950
- * Compute the entering symbol for the dual optimize operation.
951
- *
952
- * This method will return the symbol in the row which has a positive
953
- * coefficient and yields the minimum ratio for its respective symbol
954
- * in the objective function. The provided row *must* be infeasible.
955
- * If no symbol is found which meats the criteria, an invalid symbol
956
- * is returned.
957
- *
958
- * @private
959
- */
960
- _getDualEnteringSymbol(row) {
961
- let ratio = Number.MAX_VALUE;
962
- let entering = INVALID_SYMBOL;
963
- let cells = row.cells();
964
- for (let i = 0, n = cells.size(); i < n; ++i) {
965
- let pair = cells.itemAt(i);
966
- let symbol = pair.first;
967
- let c = pair.second;
968
- if (c > 0 && symbol.type() !== SymbolType.Dummy) {
969
- let r = this._objective.coefficientFor(symbol) / c;
970
- if (r < ratio) {
971
- ratio = r;
972
- entering = symbol;
973
- }
974
- }
975
- }
976
- return entering;
977
- }
978
- /**
979
- * Compute the symbol for pivot exit row.
980
- *
981
- * This method will return the symbol for the exit row in the row
982
- * map. If no appropriate exit symbol is found, an invalid symbol
983
- * will be returned. This indicates that the objective function is
984
- * unbounded.
985
- *
986
- * @private
987
- */
988
- _getLeavingSymbol(entering) {
989
- let ratio = Number.MAX_VALUE;
990
- let found = INVALID_SYMBOL;
991
- let rows = this._rowMap;
992
- for (let i = 0, n = rows.size(); i < n; ++i) {
993
- let pair = rows.itemAt(i);
994
- let symbol = pair.first;
995
- if (symbol.type() !== SymbolType.External) {
996
- let row = pair.second;
997
- let temp = row.coefficientFor(entering);
998
- if (temp < 0) {
999
- let temp_ratio = -row.constant() / temp;
1000
- if (temp_ratio < ratio) {
1001
- ratio = temp_ratio;
1002
- found = symbol;
1003
- }
1004
- }
1005
- }
1006
- }
1007
- return found;
1008
- }
1009
- /**
1010
- * Compute the leaving symbol for a marker variable.
1011
- *
1012
- * This method will return a symbol corresponding to a basic row
1013
- * which holds the given marker variable. The row will be chosen
1014
- * according to the following precedence:
1015
- *
1016
- * 1) The row with a restricted basic varible and a negative coefficient
1017
- * for the marker with the smallest ratio of -constant / coefficient.
1018
- *
1019
- * 2) The row with a restricted basic variable and the smallest ratio
1020
- * of constant / coefficient.
1021
- *
1022
- * 3) The last unrestricted row which contains the marker.
1023
- *
1024
- * If the marker does not exist in any row, an invalid symbol will be
1025
- * returned. This indicates an internal solver error since the marker
1026
- * *should* exist somewhere in the tableau.
1027
- *
1028
- * @private
1029
- */
1030
- _getMarkerLeavingSymbol(marker) {
1031
- let dmax = Number.MAX_VALUE;
1032
- let r1 = dmax;
1033
- let r2 = dmax;
1034
- let invalid = INVALID_SYMBOL;
1035
- let first = invalid;
1036
- let second = invalid;
1037
- let third = invalid;
1038
- let rows = this._rowMap;
1039
- for (let i = 0, n = rows.size(); i < n; ++i) {
1040
- let pair = rows.itemAt(i);
1041
- let row = pair.second;
1042
- let c = row.coefficientFor(marker);
1043
- if (c === 0) continue;
1044
- let symbol = pair.first;
1045
- if (symbol.type() === SymbolType.External) third = symbol;
1046
- else if (c < 0) {
1047
- let r = -row.constant() / c;
1048
- if (r < r1) {
1049
- r1 = r;
1050
- first = symbol;
1051
- }
1052
- } else {
1053
- let r = row.constant() / c;
1054
- if (r < r2) {
1055
- r2 = r;
1056
- second = symbol;
1057
- }
1058
- }
1059
- }
1060
- if (first !== invalid) return first;
1061
- if (second !== invalid) return second;
1062
- return third;
1063
- }
1064
- /**
1065
- * Remove the effects of a constraint on the objective function.
1066
- *
1067
- * @private
1068
- */
1069
- _removeConstraintEffects(cn, tag) {
1070
- if (tag.marker.type() === SymbolType.Error) this._removeMarkerEffects(tag.marker, cn.strength());
1071
- if (tag.other.type() === SymbolType.Error) this._removeMarkerEffects(tag.other, cn.strength());
1072
- }
1073
- /**
1074
- * Remove the effects of an error marker on the objective function.
1075
- *
1076
- * @private
1077
- */
1078
- _removeMarkerEffects(marker, strength) {
1079
- let pair = this._rowMap.find(marker);
1080
- if (pair !== void 0) this._objective.insertRow(pair.second, -strength);
1081
- else this._objective.insertSymbol(marker, -strength);
1082
- }
1083
- /**
1084
- * Get the first Slack or Error symbol in the row.
1085
- *
1086
- * If no such symbol is present, an invalid symbol will be returned.
1087
- *
1088
- * @private
1089
- */
1090
- _anyPivotableSymbol(row) {
1091
- let cells = row.cells();
1092
- for (let i = 0, n = cells.size(); i < n; ++i) {
1093
- let pair = cells.itemAt(i);
1094
- let type = pair.first.type();
1095
- if (type === SymbolType.Slack || type === SymbolType.Error) return pair.first;
1096
- }
1097
- return INVALID_SYMBOL;
1098
- }
1099
- /**
1100
- * Returns a new Symbol of the given type.
1101
- *
1102
- * @private
1103
- */
1104
- _makeSymbol(type) {
1105
- return new Symbol(type, this._idTick++);
1106
- }
1107
- _cnMap = createCnMap();
1108
- _rowMap = createRowMap();
1109
- _varMap = createVarMap();
1110
- _editMap = createEditMap();
1111
- _infeasibleRows = [];
1112
- _objective = new Row();
1113
- _artificial = null;
1114
- _idTick = 0;
1115
- };
1116
- /**
1117
- * Test whether a value is approximately zero.
1118
- * @private
1119
- */
1120
- function nearZero(value) {
1121
- let eps = 1e-8;
1122
- return value < 0 ? -value < eps : value < eps;
1123
- }
1124
- /**
1125
- * An internal function for creating a constraint map.
1126
- * @private
1127
- */
1128
- function createCnMap() {
1129
- return createMap();
1130
- }
1131
- /**
1132
- * An internal function for creating a row map.
1133
- * @private
1134
- */
1135
- function createRowMap() {
1136
- return createMap();
1137
- }
1138
- /**
1139
- * An internal function for creating a variable map.
1140
- * @private
1141
- */
1142
- function createVarMap() {
1143
- return createMap();
1144
- }
1145
- /**
1146
- * An internal function for creating an edit map.
1147
- * @private
1148
- */
1149
- function createEditMap() {
1150
- return createMap();
1151
- }
1152
- /**
1153
- * An enum defining the available symbol types.
1154
- * @private
1155
- */
1156
- var SymbolType;
1157
- (function(SymbolType) {
1158
- SymbolType[SymbolType["Invalid"] = 0] = "Invalid";
1159
- SymbolType[SymbolType["External"] = 1] = "External";
1160
- SymbolType[SymbolType["Slack"] = 2] = "Slack";
1161
- SymbolType[SymbolType["Error"] = 3] = "Error";
1162
- SymbolType[SymbolType["Dummy"] = 4] = "Dummy";
1163
- })(SymbolType || (SymbolType = {}));
1164
- /**
1165
- * An internal class representing a symbol in the solver.
1166
- * @private
1167
- */
1168
- var Symbol = class {
1169
- /**
1170
- * Construct a new Symbol
1171
- *
1172
- * @param [type] The type of the symbol.
1173
- * @param [id] The unique id number of the symbol.
1174
- */
1175
- constructor(type, id) {
1176
- this._id = id;
1177
- this._type = type;
1178
- }
1179
- /**
1180
- * Returns the unique id number of the symbol.
1181
- */
1182
- id() {
1183
- return this._id;
1184
- }
1185
- /**
1186
- * Returns the type of the symbol.
1187
- */
1188
- type() {
1189
- return this._type;
1190
- }
1191
- _id;
1192
- _type;
1193
- };
1194
- /**
1195
- * A static invalid symbol
1196
- * @private
1197
- */
1198
- let INVALID_SYMBOL = new Symbol(SymbolType.Invalid, -1);
1199
- /**
1200
- * An internal row class used by the solver.
1201
- * @private
1202
- */
1203
- var Row = class Row {
1204
- /**
1205
- * Construct a new Row.
1206
- */
1207
- constructor(constant = 0) {
1208
- this._constant = constant;
1209
- }
1210
- /**
1211
- * Returns the mapping of symbols to coefficients.
1212
- */
1213
- cells() {
1214
- return this._cellMap;
1215
- }
1216
- /**
1217
- * Returns the constant for the row.
1218
- */
1219
- constant() {
1220
- return this._constant;
1221
- }
1222
- /**
1223
- * Returns true if the row is a constant value.
1224
- */
1225
- isConstant() {
1226
- return this._cellMap.empty();
1227
- }
1228
- /**
1229
- * Returns true if the Row has all dummy symbols.
1230
- */
1231
- allDummies() {
1232
- let cells = this._cellMap;
1233
- for (let i = 0, n = cells.size(); i < n; ++i) if (cells.itemAt(i).first.type() !== SymbolType.Dummy) return false;
1234
- return true;
1235
- }
1236
- /**
1237
- * Create a copy of the row.
1238
- */
1239
- copy() {
1240
- let theCopy = new Row(this._constant);
1241
- theCopy._cellMap = this._cellMap.copy();
1242
- return theCopy;
1243
- }
1244
- /**
1245
- * Add a constant value to the row constant.
1246
- *
1247
- * Returns the new value of the constant.
1248
- */
1249
- add(value) {
1250
- return this._constant += value;
1251
- }
1252
- /**
1253
- * Insert the symbol into the row with the given coefficient.
1254
- *
1255
- * If the symbol already exists in the row, the coefficient
1256
- * will be added to the existing coefficient. If the resulting
1257
- * coefficient is zero, the symbol will be removed from the row.
1258
- */
1259
- insertSymbol(symbol, coefficient = 1) {
1260
- let pair = this._cellMap.setDefault(symbol, () => 0);
1261
- if (nearZero(pair.second += coefficient)) this._cellMap.erase(symbol);
1262
- }
1263
- /**
1264
- * Insert a row into this row with a given coefficient.
1265
- *
1266
- * The constant and the cells of the other row will be
1267
- * multiplied by the coefficient and added to this row. Any
1268
- * cell with a resulting coefficient of zero will be removed
1269
- * from the row.
1270
- */
1271
- insertRow(other, coefficient = 1) {
1272
- this._constant += other._constant * coefficient;
1273
- let cells = other._cellMap;
1274
- for (let i = 0, n = cells.size(); i < n; ++i) {
1275
- let pair = cells.itemAt(i);
1276
- this.insertSymbol(pair.first, pair.second * coefficient);
1277
- }
1278
- }
1279
- /**
1280
- * Remove a symbol from the row.
1281
- */
1282
- removeSymbol(symbol) {
1283
- this._cellMap.erase(symbol);
1284
- }
1285
- /**
1286
- * Reverse the sign of the constant and cells in the row.
1287
- */
1288
- reverseSign() {
1289
- this._constant = -this._constant;
1290
- let cells = this._cellMap;
1291
- for (let i = 0, n = cells.size(); i < n; ++i) {
1292
- let pair = cells.itemAt(i);
1293
- pair.second = -pair.second;
1294
- }
1295
- }
1296
- /**
1297
- * Solve the row for the given symbol.
1298
- *
1299
- * This method assumes the row is of the form
1300
- * a * x + b * y + c = 0 and (assuming solve for x) will modify
1301
- * the row to represent the right hand side of
1302
- * x = -b/a * y - c / a. The target symbol will be removed from
1303
- * the row, and the constant and other cells will be multiplied
1304
- * by the negative inverse of the target coefficient.
1305
- *
1306
- * The given symbol *must* exist in the row.
1307
- */
1308
- solveFor(symbol) {
1309
- let cells = this._cellMap;
1310
- let coeff = -1 / cells.erase(symbol).second;
1311
- this._constant *= coeff;
1312
- for (let i = 0, n = cells.size(); i < n; ++i) cells.itemAt(i).second *= coeff;
1313
- }
1314
- /**
1315
- * Solve the row for the given symbols.
1316
- *
1317
- * This method assumes the row is of the form
1318
- * x = b * y + c and will solve the row such that
1319
- * y = x / b - c / b. The rhs symbol will be removed from the
1320
- * row, the lhs added, and the result divided by the negative
1321
- * inverse of the rhs coefficient.
1322
- *
1323
- * The lhs symbol *must not* exist in the row, and the rhs
1324
- * symbol must* exist in the row.
1325
- */
1326
- solveForEx(lhs, rhs) {
1327
- this.insertSymbol(lhs, -1);
1328
- this.solveFor(rhs);
1329
- }
1330
- /**
1331
- * Returns the coefficient for the given symbol.
1332
- */
1333
- coefficientFor(symbol) {
1334
- let pair = this._cellMap.find(symbol);
1335
- return pair !== void 0 ? pair.second : 0;
1336
- }
1337
- /**
1338
- * Substitute a symbol with the data from another row.
1339
- *
1340
- * Given a row of the form a * x + b and a substitution of the
1341
- * form x = 3 * y + c the row will be updated to reflect the
1342
- * expression 3 * a * y + a * c + b.
1343
- *
1344
- * If the symbol does not exist in the row, this is a no-op.
1345
- */
1346
- substitute(symbol, row) {
1347
- let pair = this._cellMap.erase(symbol);
1348
- if (pair !== void 0) this.insertRow(row, pair.second);
1349
- }
1350
- _cellMap = createMap();
1351
- _constant;
1352
- };
1353
-
1354
- //#endregion
1355
- export { Variable as a, Strength as i, Constraint as n, Operator as r, Solver as t };
1
+ function createMap(){return new IndexedMap}var IndexedMap=class e{index={};array=[];size(){return this.array.length}empty(){return this.array.length===0}itemAt(e){return this.array[e]}contains(e){return this.index[e.id()]!==void 0}find(e){let t=this.index[e.id()];return t===void 0?void 0:this.array[t]}setDefault(e,t){let r=this.index[e.id()];if(r===void 0){let r=new Pair(e,t());return this.index[e.id()]=this.array.length,this.array.push(r),r}else return this.array[r]}insert(e,t){let r=new Pair(e,t),i=this.index[e.id()];return i===void 0?(this.index[e.id()]=this.array.length,this.array.push(r)):this.array[i]=r,r}erase(e){let t=this.index[e.id()];if(t===void 0)return;this.index[e.id()]=void 0;let n=this.array[t],r=this.array.pop();return n!==r&&(this.array[t]=r,this.index[r.first.id()]=t),n}copy(){let t=new e;for(let e=0;e<this.array.length;e++){let n=this.array[e].copy();t.array[e]=n,t.index[n.first.id()]=e}return t}},Pair=class e{first;second;constructor(e,t){this.first=e,this.second=t}copy(){return new e(this.first,this.second)}},Variable=class{constructor(e=``){this._name=e}id(){return this._id}name(){return this._name}setName(e){this._name=e}context(){return this._context}setContext(e){this._context=e}value(){return this._value}setValue(e){this._value=e}plus(e){return new Expression(this,e)}minus(e){return new Expression(this,typeof e==`number`?-e:[-1,e])}multiply(e){return new Expression([e,this])}divide(e){return new Expression([1/e,this])}toJSON(){return{name:this._name,value:this._value}}toString(){return this._context+`[`+this._name+`:`+this._value+`]`}_name;_value=0;_context=null;_id=VarId++};let VarId=0;var Expression=class e{constructor(){let e=parseArgs(arguments);this._terms=e.terms,this._constant=e.constant}terms(){return this._terms}constant(){return this._constant}value(){let e=this._constant;for(let t=0,n=this._terms.size();t<n;t++){let n=this._terms.itemAt(t);e+=n.first.value()*n.second}return e}plus(t){return new e(this,t)}minus(t){return new e(this,typeof t==`number`?-t:[-1,t])}multiply(t){return new e([t,this])}divide(t){return new e([1/t,this])}isConstant(){return this._terms.size()==0}toString(){let e=this._terms.array.map(function(e){return e.second+`*`+e.first.toString()}).join(` + `);return!this.isConstant()&&this._constant!==0&&(e+=` + `),e+=this._constant,e}_terms;_constant};function parseArgs(t){let n=0,i=()=>0,o=createMap();for(let e=0,s=t.length;e<s;++e){let s=t[e];if(typeof s==`number`)n+=s;else if(s instanceof Variable)o.setDefault(s,i).second+=1;else if(s instanceof Expression){n+=s.constant();let e=s.terms();for(let t=0,n=e.size();t<n;t++){let n=e.itemAt(t);o.setDefault(n.first,i).second+=n.second}}else if(s instanceof Array){if(s.length!==2)throw Error(`array must have length 2`);let e=s[0],t=s[1];if(typeof e!=`number`)throw Error(`array item 0 must be a number`);if(t instanceof Variable)o.setDefault(t,i).second+=e;else if(t instanceof Expression){n+=t.constant()*e;let r=t.terms();for(let t=0,n=r.size();t<n;t++){let n=r.itemAt(t);o.setDefault(n.first,i).second+=n.second*e}}else throw Error(`array item 1 must be a variable or expression`)}else throw Error(`invalid Expression argument: `+s)}return{terms:o,constant:n}}var Strength=class e{static create(e,t,n,r=1){let i=0;return i+=Math.max(0,Math.min(1e3,e*r))*1e6,i+=Math.max(0,Math.min(1e3,t*r))*1e3,i+=Math.max(0,Math.min(1e3,n*r)),i}static required=e.create(1e3,1e3,1e3);static strong=e.create(1,0,0);static medium=e.create(0,1,0);static weak=e.create(0,0,1);static clip(t){return Math.max(0,Math.min(e.required,t))}},Operator;(function(e){e[e.Le=0]=`Le`,e[e.Ge=1]=`Ge`,e[e.Eq=2]=`Eq`})(Operator||={});var Constraint=class{constructor(e,t,n,r=Strength.required){this._operator=t,this._strength=Strength.clip(r),n===void 0&&e instanceof Expression?this._expression=e:this._expression=e.minus(n)}id(){return this._id}expression(){return this._expression}op(){return this._operator}strength(){return this._strength}toString(){return this._expression.toString()+` `+[`<=`,`>=`,`=`][this._operator]+` 0 (`+this._strength.toString()+`)`}_expression;_operator;_strength;_id=CnId++};let CnId=0;var Solver=class{maxIterations=1e3;constructor(){}createConstraint(e,t,n,r=Strength.required){let i=new Constraint(e,t,n,r);return this.addConstraint(i),i}addConstraint(e){if(this._cnMap.find(e)!==void 0)throw Error(`duplicate constraint`);let t=this._createRow(e),n=t.row,r=t.tag,i=this._chooseSubject(n,r);if(i.type()===SymbolType.Invalid&&n.allDummies())if(nearZero(n.constant()))i=r.marker;else throw Error(`unsatisfiable constraint`);if(i.type()===SymbolType.Invalid){if(!this._addWithArtificialVariable(n))throw Error(`unsatisfiable constraint`)}else n.solveFor(i),this._substitute(i,n),this._rowMap.insert(i,n);this._cnMap.insert(e,r),this._optimize(this._objective)}removeConstraint(e){let t=this._cnMap.erase(e);if(t===void 0)throw Error(`unknown constraint`);this._removeConstraintEffects(e,t.second);let n=t.second.marker,r=this._rowMap.erase(n);if(r===void 0){let e=this._getMarkerLeavingSymbol(n);if(e.type()===SymbolType.Invalid)throw Error(`failed to find leaving row`);r=this._rowMap.erase(e),r.second.solveForEx(e,n),this._substitute(n,r.second)}this._optimize(this._objective)}hasConstraint(e){return this._cnMap.contains(e)}getConstraints(){return this._cnMap.array.map(({first:e})=>e)}addEditVariable(e,t){if(this._editMap.find(e)!==void 0)throw Error(`duplicate edit variable`);if(t=Strength.clip(t),t===Strength.required)throw Error(`bad required strength`);let n=new Constraint(new Expression(e),Operator.Eq,void 0,t);this.addConstraint(n);let r={tag:this._cnMap.find(n).second,constraint:n,constant:0};this._editMap.insert(e,r)}removeEditVariable(e){let t=this._editMap.erase(e);if(t===void 0)throw Error(`unknown edit variable`);this.removeConstraint(t.second.constraint)}hasEditVariable(e){return this._editMap.contains(e)}suggestValue(e,t){let n=this._editMap.find(e);if(n===void 0)throw Error(`unknown edit variable`);let r=this._rowMap,i=n.second,a=t-i.constant;i.constant=t;let o=i.tag.marker,s=r.find(o);if(s!==void 0){s.second.add(-a)<0&&this._infeasibleRows.push(o),this._dualOptimize();return}let c=i.tag.other;if(s=r.find(c),s!==void 0){s.second.add(a)<0&&this._infeasibleRows.push(c),this._dualOptimize();return}for(let e=0,t=r.size();e<t;++e){let t=r.itemAt(e),n=t.second,i=n.coefficientFor(o);i!==0&&n.add(a*i)<0&&t.first.type()!==SymbolType.External&&this._infeasibleRows.push(t.first)}this._dualOptimize()}updateVariables(){let e=this._varMap,t=this._rowMap;for(let n=0,r=e.size();n<r;++n){let r=e.itemAt(n),i=t.find(r.second);i===void 0?r.first.setValue(0):r.first.setValue(i.second.constant())}}_getVarSymbol(e){let t=()=>this._makeSymbol(SymbolType.External);return this._varMap.setDefault(e,t).second}_createRow(e){let t=e.expression(),n=new Row(t.constant()),r=t.terms();for(let e=0,t=r.size();e<t;++e){let t=r.itemAt(e);if(!nearZero(t.second)){let e=this._getVarSymbol(t.first),r=this._rowMap.find(e);r===void 0?n.insertSymbol(e,t.second):n.insertRow(r.second,t.second)}}let i=this._objective,a=e.strength(),o={marker:INVALID_SYMBOL,other:INVALID_SYMBOL};switch(e.op()){case Operator.Le:case Operator.Ge:{let t=e.op()===Operator.Le?1:-1,r=this._makeSymbol(SymbolType.Slack);if(o.marker=r,n.insertSymbol(r,t),a<Strength.required){let e=this._makeSymbol(SymbolType.Error);o.other=e,n.insertSymbol(e,-t),i.insertSymbol(e,a)}break}case Operator.Eq:if(a<Strength.required){let e=this._makeSymbol(SymbolType.Error),t=this._makeSymbol(SymbolType.Error);o.marker=e,o.other=t,n.insertSymbol(e,-1),n.insertSymbol(t,1),i.insertSymbol(e,a),i.insertSymbol(t,a)}else{let e=this._makeSymbol(SymbolType.Dummy);o.marker=e,n.insertSymbol(e)}break}return n.constant()<0&&n.reverseSign(),{row:n,tag:o}}_chooseSubject(e,t){let n=e.cells();for(let e=0,t=n.size();e<t;++e){let t=n.itemAt(e);if(t.first.type()===SymbolType.External)return t.first}let r=t.marker.type();return(r===SymbolType.Slack||r===SymbolType.Error)&&e.coefficientFor(t.marker)<0?t.marker:(r=t.other.type(),(r===SymbolType.Slack||r===SymbolType.Error)&&e.coefficientFor(t.other)<0?t.other:INVALID_SYMBOL)}_addWithArtificialVariable(e){let t=this._makeSymbol(SymbolType.Slack);this._rowMap.insert(t,e.copy()),this._artificial=e.copy(),this._optimize(this._artificial);let n=nearZero(this._artificial.constant());this._artificial=null;let r=this._rowMap.erase(t);if(r!==void 0){let e=r.second;if(e.isConstant())return n;let i=this._anyPivotableSymbol(e);if(i.type()===SymbolType.Invalid)return!1;e.solveForEx(t,i),this._substitute(i,e),this._rowMap.insert(i,e)}let i=this._rowMap;for(let e=0,n=i.size();e<n;++e)i.itemAt(e).second.removeSymbol(t);return this._objective.removeSymbol(t),n}_substitute(e,t){let n=this._rowMap;for(let r=0,i=n.size();r<i;++r){let i=n.itemAt(r);i.second.substitute(e,t),i.second.constant()<0&&i.first.type()!==SymbolType.External&&this._infeasibleRows.push(i.first)}this._objective.substitute(e,t),this._artificial&&this._artificial.substitute(e,t)}_optimize(e){let t=0;for(;t<this.maxIterations;){let n=this._getEnteringSymbol(e);if(n.type()===SymbolType.Invalid)return;let r=this._getLeavingSymbol(n);if(r.type()===SymbolType.Invalid)throw Error(`the objective is unbounded`);let i=this._rowMap.erase(r).second;i.solveForEx(r,n),this._substitute(n,i),this._rowMap.insert(n,i),t++}throw Error(`solver iterations exceeded`)}_dualOptimize(){let e=this._rowMap,t=this._infeasibleRows;for(;t.length!==0;){let n=t.pop(),r=e.find(n);if(r!==void 0&&r.second.constant()<0){let t=this._getDualEnteringSymbol(r.second);if(t.type()===SymbolType.Invalid)throw Error(`dual optimize failed`);let i=r.second;e.erase(n),i.solveForEx(n,t),this._substitute(t,i),e.insert(t,i)}}}_getEnteringSymbol(e){let t=e.cells();for(let e=0,n=t.size();e<n;++e){let n=t.itemAt(e),r=n.first;if(n.second<0&&r.type()!==SymbolType.Dummy)return r}return INVALID_SYMBOL}_getDualEnteringSymbol(e){let t=Number.MAX_VALUE,n=INVALID_SYMBOL,r=e.cells();for(let e=0,i=r.size();e<i;++e){let i=r.itemAt(e),a=i.first,o=i.second;if(o>0&&a.type()!==SymbolType.Dummy){let e=this._objective.coefficientFor(a)/o;e<t&&(t=e,n=a)}}return n}_getLeavingSymbol(e){let t=Number.MAX_VALUE,n=INVALID_SYMBOL,r=this._rowMap;for(let i=0,a=r.size();i<a;++i){let a=r.itemAt(i),o=a.first;if(o.type()!==SymbolType.External){let r=a.second,i=r.coefficientFor(e);if(i<0){let e=-r.constant()/i;e<t&&(t=e,n=o)}}}return n}_getMarkerLeavingSymbol(e){let t=Number.MAX_VALUE,n=t,r=t,i=INVALID_SYMBOL,a=i,o=i,s=i,c=this._rowMap;for(let t=0,i=c.size();t<i;++t){let i=c.itemAt(t),l=i.second,u=l.coefficientFor(e);if(u===0)continue;let d=i.first;if(d.type()===SymbolType.External)s=d;else if(u<0){let e=-l.constant()/u;e<n&&(n=e,a=d)}else{let e=l.constant()/u;e<r&&(r=e,o=d)}}return a===i?o===i?s:o:a}_removeConstraintEffects(e,t){t.marker.type()===SymbolType.Error&&this._removeMarkerEffects(t.marker,e.strength()),t.other.type()===SymbolType.Error&&this._removeMarkerEffects(t.other,e.strength())}_removeMarkerEffects(e,t){let n=this._rowMap.find(e);n===void 0?this._objective.insertSymbol(e,-t):this._objective.insertRow(n.second,-t)}_anyPivotableSymbol(e){let t=e.cells();for(let e=0,n=t.size();e<n;++e){let n=t.itemAt(e),r=n.first.type();if(r===SymbolType.Slack||r===SymbolType.Error)return n.first}return INVALID_SYMBOL}_makeSymbol(e){return new Symbol(e,this._idTick++)}_cnMap=createCnMap();_rowMap=createRowMap();_varMap=createVarMap();_editMap=createEditMap();_infeasibleRows=[];_objective=new Row;_artificial=null;_idTick=0};function nearZero(e){let t=1e-8;return e<0?-e<t:e<t}function createCnMap(){return createMap()}function createRowMap(){return createMap()}function createVarMap(){return createMap()}function createEditMap(){return createMap()}var SymbolType;(function(e){e[e.Invalid=0]=`Invalid`,e[e.External=1]=`External`,e[e.Slack=2]=`Slack`,e[e.Error=3]=`Error`,e[e.Dummy=4]=`Dummy`})(SymbolType||={});var Symbol=class{constructor(e,t){this._id=t,this._type=e}id(){return this._id}type(){return this._type}_id;_type};let INVALID_SYMBOL=new Symbol(SymbolType.Invalid,-1);var Row=class t{constructor(e=0){this._constant=e}cells(){return this._cellMap}constant(){return this._constant}isConstant(){return this._cellMap.empty()}allDummies(){let e=this._cellMap;for(let t=0,n=e.size();t<n;++t)if(e.itemAt(t).first.type()!==SymbolType.Dummy)return!1;return!0}copy(){let e=new t(this._constant);return e._cellMap=this._cellMap.copy(),e}add(e){return this._constant+=e}insertSymbol(e,t=1){let n=this._cellMap.setDefault(e,()=>0);nearZero(n.second+=t)&&this._cellMap.erase(e)}insertRow(e,t=1){this._constant+=e._constant*t;let n=e._cellMap;for(let e=0,r=n.size();e<r;++e){let r=n.itemAt(e);this.insertSymbol(r.first,r.second*t)}}removeSymbol(e){this._cellMap.erase(e)}reverseSign(){this._constant=-this._constant;let e=this._cellMap;for(let t=0,n=e.size();t<n;++t){let n=e.itemAt(t);n.second=-n.second}}solveFor(e){let t=this._cellMap,n=-1/t.erase(e).second;this._constant*=n;for(let e=0,r=t.size();e<r;++e)t.itemAt(e).second*=n}solveForEx(e,t){this.insertSymbol(e,-1),this.solveFor(t)}coefficientFor(e){let t=this._cellMap.find(e);return t===void 0?0:t.second}substitute(e,t){let n=this._cellMap.erase(e);n!==void 0&&this.insertRow(t,n.second)}_cellMap=createMap();_constant};export{Variable as a,Strength as i,Constraint as n,Operator as r,Solver as t};