@pie-lib/math-input-mathlive 1.1.5-beta.1 → 1.1.5-beta.10
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/lib/__tests__/composites.test.js +255 -0
- package/lib/__tests__/drop-in-compat.test.js +133 -0
- package/lib/__tests__/embedded-fonts.test.js +121 -0
- package/lib/__tests__/index.test.js +118 -0
- package/lib/__tests__/input-imperative.test.js +155 -0
- package/lib/__tests__/keypad-label.test.js +231 -0
- package/lib/__tests__/keypad-render.test.js +206 -0
- package/lib/__tests__/latex-bridge.test.js +386 -0
- package/lib/__tests__/mathlive-instance.test.js +419 -0
- package/lib/__tests__/mount-race.test.js +218 -0
- package/lib/__tests__/static-prompts.test.js +405 -0
- package/lib/__tests__/tmp-markup.test.js +26 -0
- package/lib/keypad/index.js +36 -12
- package/lib/keypad/index.js.map +1 -1
- package/lib/latex-bridge.js +159 -4
- package/lib/latex-bridge.js.map +1 -1
- package/lib/mathlive-instance.js +21 -28
- package/lib/mathlive-instance.js.map +1 -1
- package/lib/mf/common-styles.js +17 -2
- package/lib/mf/common-styles.js.map +1 -1
- package/lib/mf/index.js +6 -0
- package/lib/mf/index.js.map +1 -1
- package/lib/mf/input.js +5 -0
- package/lib/mf/input.js.map +1 -1
- package/lib/mf/static.js +4 -2
- package/lib/mf/static.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/composites.test.jsx +220 -0
- package/src/__tests__/drop-in-compat.test.jsx +112 -0
- package/src/__tests__/index.test.jsx +109 -0
- package/src/__tests__/input-imperative.test.jsx +144 -0
- package/src/__tests__/keypad-label.test.jsx +284 -0
- package/src/__tests__/keypad-render.test.jsx +123 -0
- package/src/__tests__/latex-bridge.test.js +389 -0
- package/src/__tests__/mathlive-instance.test.js +418 -0
- package/src/__tests__/mount-race.test.jsx +142 -0
- package/src/__tests__/static-prompts.test.jsx +364 -0
- package/src/keypad/index.jsx +18 -3
- package/src/latex-bridge.js +171 -4
- package/src/mathlive-instance.js +27 -29
- package/src/mf/common-styles.js +19 -0
- package/src/mf/index.js +2 -0
- package/src/mf/input.jsx +5 -0
- package/src/mf/static.jsx +4 -1
- package/lib/fonts/embedded.js +0 -120
- package/lib/fonts/index.js +0 -81
- package/lib/fonts/index.js.map +0 -1
- package/scripts/generate-embedded-fonts.js +0 -94
- package/src/fonts/embedded.js +0 -116
- package/src/fonts/index.js +0 -71
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
|
|
5
|
+
var _latexBridge = require("../latex-bridge");
|
|
6
|
+
describe('latex-bridge', function () {
|
|
7
|
+
describe('toMathLive', function () {
|
|
8
|
+
it('passes plain latex through', function () {
|
|
9
|
+
expect((0, _latexBridge.toMathLive)('\\frac{1}{2}')).toEqual('\\frac{1}{2}');
|
|
10
|
+
});
|
|
11
|
+
it('handles empty/nullish', function () {
|
|
12
|
+
expect((0, _latexBridge.toMathLive)('')).toEqual('');
|
|
13
|
+
expect((0, _latexBridge.toMathLive)(undefined)).toEqual('');
|
|
14
|
+
expect((0, _latexBridge.toMathLive)(null)).toEqual('');
|
|
15
|
+
});
|
|
16
|
+
it('converts a newLine embed to a multiline environment', function () {
|
|
17
|
+
expect((0, _latexBridge.toMathLive)("a".concat(_latexBridge.NEWLINE_EMBED, "b"))).toEqual('\\displaylines{a \\\\ b}');
|
|
18
|
+
});
|
|
19
|
+
it('converts multiple newLine embeds', function () {
|
|
20
|
+
expect((0, _latexBridge.toMathLive)("a".concat(_latexBridge.NEWLINE_EMBED, "b").concat(_latexBridge.NEWLINE_EMBED, "c"))).toEqual('\\displaylines{a \\\\ b \\\\ c}');
|
|
21
|
+
});
|
|
22
|
+
it('converts MathQuill answer blocks to placeholders', function () {
|
|
23
|
+
expect((0, _latexBridge.toMathLive)('x=\\MathQuillMathField[r1]{}')).toEqual('x=\\placeholder[r1]{}');
|
|
24
|
+
});
|
|
25
|
+
it('preserves answer block content', function () {
|
|
26
|
+
expect((0, _latexBridge.toMathLive)('\\MathQuillMathField[r2]{7}')).toEqual('\\placeholder[r2]{7}');
|
|
27
|
+
});
|
|
28
|
+
it('defaults an unnamed answer block id', function () {
|
|
29
|
+
expect((0, _latexBridge.toMathLive)('\\MathQuillMathField[]{}')).toEqual("\\placeholder[".concat(_latexBridge.DEFAULT_FIELD_ID, "]{}"));
|
|
30
|
+
});
|
|
31
|
+
it('handles answer blocks and newlines together', function () {
|
|
32
|
+
expect((0, _latexBridge.toMathLive)("\\MathQuillMathField[r1]{}".concat(_latexBridge.NEWLINE_EMBED, "x"))).toEqual('\\displaylines{\\placeholder[r1]{} \\\\ x}');
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
describe('fromMathLive', function () {
|
|
36
|
+
it('passes plain latex through', function () {
|
|
37
|
+
expect((0, _latexBridge.fromMathLive)('\\frac{1}{2}')).toEqual('\\frac{1}{2}');
|
|
38
|
+
});
|
|
39
|
+
it('unwraps displaylines back to newLine embeds', function () {
|
|
40
|
+
expect((0, _latexBridge.fromMathLive)('\\displaylines{a \\\\ b}')).toEqual("a".concat(_latexBridge.NEWLINE_EMBED, "b"));
|
|
41
|
+
});
|
|
42
|
+
it('converts placeholders back to MathQuill answer blocks', function () {
|
|
43
|
+
expect((0, _latexBridge.fromMathLive)('x=\\placeholder[r1]{}')).toEqual('x=\\MathQuillMathField[r1]{}');
|
|
44
|
+
});
|
|
45
|
+
it('round-trips a newline document', function () {
|
|
46
|
+
var stored = "a".concat(_latexBridge.NEWLINE_EMBED, "b").concat(_latexBridge.NEWLINE_EMBED, "c");
|
|
47
|
+
expect((0, _latexBridge.fromMathLive)((0, _latexBridge.toMathLive)(stored))).toEqual(stored);
|
|
48
|
+
});
|
|
49
|
+
it('round-trips an answer-block document', function () {
|
|
50
|
+
var stored = 'x=\\MathQuillMathField[r1]{}+\\MathQuillMathField[r2]{3}';
|
|
51
|
+
expect((0, _latexBridge.fromMathLive)((0, _latexBridge.toMathLive)(stored))).toEqual(stored);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// MathLive serialises empty slots as \placeholder{}, which MathJax (used by
|
|
55
|
+
// @pie-lib/math-rendering for prompts/previews) renders as red error text.
|
|
56
|
+
it('strips unnamed placeholders that MathLive adds', function () {
|
|
57
|
+
expect((0, _latexBridge.fromMathLive)('\\longdiv{\\placeholder{}}')).toEqual('\\longdiv{}');
|
|
58
|
+
expect((0, _latexBridge.fromMathLive)('\\frac{\\placeholder{}}{\\placeholder{}}')).toEqual('\\frac{}{}');
|
|
59
|
+
});
|
|
60
|
+
it('keeps content inside an unnamed placeholder', function () {
|
|
61
|
+
expect((0, _latexBridge.fromMathLive)('\\sqrt{\\placeholder{7}}')).toEqual('\\sqrt{7}');
|
|
62
|
+
});
|
|
63
|
+
it('handles a bare \\placeholder with no argument', function () {
|
|
64
|
+
expect((0, _latexBridge.fromMathLive)('\\longdiv{\\placeholder}')).toEqual('\\longdiv{}');
|
|
65
|
+
});
|
|
66
|
+
it('never leaks the token \\placeholder', function () {
|
|
67
|
+
['\\longdiv{\\placeholder{}}', '\\frac{\\placeholder{}}{x}', '\\placeholder{}'].forEach(function (l) {
|
|
68
|
+
expect((0, _latexBridge.fromMathLive)(l)).not.toContain('\\placeholder');
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
it('still maps NAMED placeholders to answer blocks', function () {
|
|
72
|
+
// named ones are answer blocks and must survive
|
|
73
|
+
expect((0, _latexBridge.fromMathLive)('\\placeholder[r1]{}')).toEqual('\\MathQuillMathField[r1]{}');
|
|
74
|
+
});
|
|
75
|
+
it('round-trips answer blocks combined with newlines', function () {
|
|
76
|
+
var stored = "\\MathQuillMathField[r1]{}".concat(_latexBridge.NEWLINE_EMBED, "y");
|
|
77
|
+
expect((0, _latexBridge.fromMathLive)((0, _latexBridge.toMathLive)(stored))).toEqual(stored);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// A MathLive macro serialises from the arguments it was created with, so text
|
|
82
|
+
// typed inside its expansion never comes back out of getValue('latex').
|
|
83
|
+
// Argument-taking pie commands must therefore become native constructs before
|
|
84
|
+
// they reach a mathfield.
|
|
85
|
+
describe('toNativeCommands', function () {
|
|
86
|
+
it('expands \\longdiv to native \\enclose', function () {
|
|
87
|
+
expect((0, _latexBridge.toNativeCommands)('\\longdiv{1234}')).toEqual('\\enclose{longdiv}{1234}');
|
|
88
|
+
expect((0, _latexBridge.toNativeCommands)('\\longdiv{}')).toEqual('\\enclose{longdiv}{}');
|
|
89
|
+
});
|
|
90
|
+
it('expands \\overarc to native \\overparen', function () {
|
|
91
|
+
expect((0, _latexBridge.toNativeCommands)('\\overarc{AB}')).toEqual('\\overparen{AB}');
|
|
92
|
+
});
|
|
93
|
+
it('expands \\abs to native \\left|..\\right|', function () {
|
|
94
|
+
expect((0, _latexBridge.toNativeCommands)('\\abs{x}')).toEqual('\\left|x\\right|');
|
|
95
|
+
expect((0, _latexBridge.toNativeCommands)('\\abs{}')).toEqual('\\left|\\right|');
|
|
96
|
+
});
|
|
97
|
+
it('handles nested braces inside \\abs', function () {
|
|
98
|
+
expect((0, _latexBridge.toNativeCommands)('\\abs{\\frac{1}{2}}')).toEqual('\\left|\\frac{1}{2}\\right|');
|
|
99
|
+
});
|
|
100
|
+
it('handles several occurrences', function () {
|
|
101
|
+
expect((0, _latexBridge.toNativeCommands)('\\abs{a}+\\abs{b}')).toEqual('\\left|a\\right|+\\left|b\\right|');
|
|
102
|
+
expect((0, _latexBridge.toNativeCommands)('\\longdiv{1}\\longdiv{2}')).toEqual('\\enclose{longdiv}{1}\\enclose{longdiv}{2}');
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// `%` starts a comment in real LaTeX, so MathLive drops it and everything
|
|
106
|
+
// after it. MathQuill had no comments, so latex authored under it - or by
|
|
107
|
+
// hand - can carry a bare `%` that would silently truncate the expression.
|
|
108
|
+
it('escapes a bare % so it cannot comment out the rest of the line', function () {
|
|
109
|
+
expect((0, _latexBridge.toNativeCommands)('%')).toEqual('\\%');
|
|
110
|
+
expect((0, _latexBridge.toNativeCommands)('50%')).toEqual('50\\%');
|
|
111
|
+
expect((0, _latexBridge.toNativeCommands)('x%y')).toEqual('x\\%y');
|
|
112
|
+
expect((0, _latexBridge.toNativeCommands)('a%b%c')).toEqual('a\\%b\\%c');
|
|
113
|
+
});
|
|
114
|
+
it('leaves an already-escaped % alone', function () {
|
|
115
|
+
expect((0, _latexBridge.toNativeCommands)('\\%')).toEqual('\\%');
|
|
116
|
+
expect((0, _latexBridge.toNativeCommands)('50\\%')).toEqual('50\\%');
|
|
117
|
+
// idempotent: toMathLive may run over latex that came back out of a field
|
|
118
|
+
expect((0, _latexBridge.toNativeCommands)((0, _latexBridge.toNativeCommands)('50%'))).toEqual('50\\%');
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// `\\` is a line break, not an escape, so the `%` after it is still bare.
|
|
122
|
+
it('counts backslashes to decide whether a % is escaped', function () {
|
|
123
|
+
expect((0, _latexBridge.toNativeCommands)('a\\\\%b')).toEqual('a\\\\\\%b');
|
|
124
|
+
});
|
|
125
|
+
it('leaves other latex untouched', function () {
|
|
126
|
+
['\\frac{1}{2}', '\\pi', '\\sqrt{x}', '\\overline{AB}'].forEach(function (l) {
|
|
127
|
+
expect((0, _latexBridge.toNativeCommands)(l)).toEqual(l);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
it('handles nullish input', function () {
|
|
131
|
+
expect((0, _latexBridge.toNativeCommands)(undefined)).toEqual('');
|
|
132
|
+
expect((0, _latexBridge.toNativeCommands)('')).toEqual('');
|
|
133
|
+
});
|
|
134
|
+
it('is applied by toMathLive', function () {
|
|
135
|
+
expect((0, _latexBridge.toMathLive)('\\longdiv{5}')).toEqual('\\enclose{longdiv}{5}');
|
|
136
|
+
});
|
|
137
|
+
it('does not leave a pie macro in what reaches the field', function () {
|
|
138
|
+
['\\longdiv{7}', '\\abs{7}', '\\overarc{7}'].forEach(function (l) {
|
|
139
|
+
var out = (0, _latexBridge.toMathLive)(l);
|
|
140
|
+
expect(out).not.toMatch(/\\longdiv|\\abs|\\overarc/);
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
describe('fieldIds', function () {
|
|
145
|
+
it('returns ids in document order', function () {
|
|
146
|
+
expect((0, _latexBridge.fieldIds)('\\MathQuillMathField[r1]{}+\\MathQuillMathField[r2]{}')).toEqual(['r1', 'r2']);
|
|
147
|
+
});
|
|
148
|
+
it('returns [] when there are none', function () {
|
|
149
|
+
expect((0, _latexBridge.fieldIds)('x+y')).toEqual([]);
|
|
150
|
+
expect((0, _latexBridge.fieldIds)(undefined)).toEqual([]);
|
|
151
|
+
});
|
|
152
|
+
it('is repeatable (regex lastIndex is reset)', function () {
|
|
153
|
+
var latex = '\\MathQuillMathField[r1]{}';
|
|
154
|
+
expect((0, _latexBridge.fieldIds)(latex)).toEqual(['r1']);
|
|
155
|
+
expect((0, _latexBridge.fieldIds)(latex)).toEqual(['r1']);
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// MathQuill registered some keypad names as aliases of a different command:
|
|
160
|
+
// the divide key stored `\div`, not `\divide`. MathLive knows `\divide` only as
|
|
161
|
+
// a pie macro and serialises it under that name, so it reached storage and
|
|
162
|
+
// MathJax (which has no `\divide`) rendered it as red text.
|
|
163
|
+
describe('MathQuill command aliases', function () {
|
|
164
|
+
it('the divide and perpendicular keys insert the command MathQuill stored', function () {
|
|
165
|
+
/* eslint-disable global-require */
|
|
166
|
+
var _require = require('../keys/basic-operators'),
|
|
167
|
+
divide = _require.divide;
|
|
168
|
+
// Exported under a pre-existing misspelling.
|
|
169
|
+
var _require2 = require('../keys/geometry'),
|
|
170
|
+
perpendicular = _require2.perpindicular;
|
|
171
|
+
/* eslint-enable global-require */
|
|
172
|
+
|
|
173
|
+
expect((0, _latexBridge.keyToAction)(divide)).toEqual({
|
|
174
|
+
type: 'insert',
|
|
175
|
+
value: '\\div'
|
|
176
|
+
});
|
|
177
|
+
expect((0, _latexBridge.keyToAction)(perpendicular)).toEqual({
|
|
178
|
+
type: 'insert',
|
|
179
|
+
value: '\\perp'
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
it('stores the canonical command for latex that still carries an alias', function () {
|
|
183
|
+
// Typed into the field, or saved before the keypad resolved the alias.
|
|
184
|
+
expect((0, _latexBridge.fromMathLive)('1\\divide 6')).toEqual('1\\div 6');
|
|
185
|
+
expect((0, _latexBridge.fromMathLive)('a\\perpendicular b')).toEqual('a\\perp b');
|
|
186
|
+
});
|
|
187
|
+
it('only replaces whole command names', function () {
|
|
188
|
+
// \divideontimes is a real AMS symbol and must survive.
|
|
189
|
+
expect((0, _latexBridge.toCanonicalCommands)('a\\divideontimes b')).toEqual('a\\divideontimes b');
|
|
190
|
+
expect((0, _latexBridge.toCanonicalCommands)('\\divide\\divide')).toEqual('\\div\\div');
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// The double prime key: MathLive serialises `5''` as `5^{\doubleprime}`,
|
|
194
|
+
// which MathJax cannot render (red `\doubleprime`). MathQuill stored `5''`.
|
|
195
|
+
it('stores the double prime key as apostrophes', function () {
|
|
196
|
+
expect((0, _latexBridge.fromMathLive)('5^{\\doubleprime}')).toEqual("5''");
|
|
197
|
+
expect((0, _latexBridge.fromMathLive)('x^{\\prime}')).toEqual("x'");
|
|
198
|
+
expect((0, _latexBridge.fromMathLive)('x^{\\prime\\prime\\prime}')).toEqual("x'''");
|
|
199
|
+
expect((0, _latexBridge.fromMathLive)('\\doubleprime')).toEqual("''");
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// Typing `'` twice yields two superscript groups - a MathJax double-exponent
|
|
203
|
+
// error - so they collapse into apostrophes too.
|
|
204
|
+
it('collapses adjacent prime superscripts', function () {
|
|
205
|
+
expect((0, _latexBridge.fromMathLive)('x^{\\prime}^{\\prime}')).toEqual("x''");
|
|
206
|
+
expect((0, _latexBridge.fromMathLive)('5^{\\prime}^{\\doubleprime}')).toEqual("5'''");
|
|
207
|
+
});
|
|
208
|
+
it('leaves superscripts that hold more than primes alone', function () {
|
|
209
|
+
expect((0, _latexBridge.fromMathLive)('x^{\\prime 2}')).toEqual('x^{\\prime 2}');
|
|
210
|
+
expect((0, _latexBridge.fromMathLive)('x^{2}')).toEqual('x^{2}');
|
|
211
|
+
});
|
|
212
|
+
it('round-trips stored primes unchanged', function () {
|
|
213
|
+
expect((0, _latexBridge.fromMathLive)("12^{\\circ}30'15''")).toEqual("12^{\\circ}30'15''");
|
|
214
|
+
});
|
|
215
|
+
it('no keypad key inserts an alias name', function () {
|
|
216
|
+
/* eslint-disable global-require */
|
|
217
|
+
var fs = require('fs');
|
|
218
|
+
var path = require('path');
|
|
219
|
+
/* eslint-enable global-require */
|
|
220
|
+
var keysDir = path.resolve(__dirname, '../keys');
|
|
221
|
+
var keys = [];
|
|
222
|
+
var _collect = function collect(v) {
|
|
223
|
+
if (Array.isArray(v)) return v.forEach(_collect);
|
|
224
|
+
if (v && (0, _typeof2["default"])(v) === 'object' && (v.command || v.latex || v.write)) keys.push(v);
|
|
225
|
+
};
|
|
226
|
+
fs.readdirSync(keysDir).filter(function (f) {
|
|
227
|
+
return /\.js$/.test(f);
|
|
228
|
+
})
|
|
229
|
+
// eslint-disable-next-line global-require, import/no-dynamic-require
|
|
230
|
+
.forEach(function (f) {
|
|
231
|
+
return Object.values(require(path.join(keysDir, f))).forEach(_collect);
|
|
232
|
+
});
|
|
233
|
+
expect(keys.length).toBeGreaterThan(50);
|
|
234
|
+
keys.forEach(function (k) {
|
|
235
|
+
var action = (0, _latexBridge.keyToAction)(k);
|
|
236
|
+
var value = action && action.value || '';
|
|
237
|
+
Object.keys(_latexBridge.MATHQUILL_ALIASES).forEach(function (alias) {
|
|
238
|
+
expect(new RegExp("\\".concat(alias, "(?![a-zA-Z])")).test(value)).toBe(false);
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
describe('keyToAction', function () {
|
|
244
|
+
it('prefers latex when there is no command', function () {
|
|
245
|
+
expect((0, _latexBridge.keyToAction)({
|
|
246
|
+
latex: '\\pi',
|
|
247
|
+
write: 'p'
|
|
248
|
+
})).toEqual({
|
|
249
|
+
type: 'insert',
|
|
250
|
+
value: '\\pi'
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
it('uses write', function () {
|
|
254
|
+
expect((0, _latexBridge.keyToAction)({
|
|
255
|
+
write: 'x'
|
|
256
|
+
})).toEqual({
|
|
257
|
+
type: 'insert',
|
|
258
|
+
value: 'x'
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
it('expands commands that take arguments into placeholders', function () {
|
|
262
|
+
expect((0, _latexBridge.keyToAction)({
|
|
263
|
+
command: '\\frac'
|
|
264
|
+
})).toEqual({
|
|
265
|
+
type: 'insert',
|
|
266
|
+
value: '\\frac{#?}{#?}'
|
|
267
|
+
});
|
|
268
|
+
expect((0, _latexBridge.keyToAction)({
|
|
269
|
+
command: '\\sqrt'
|
|
270
|
+
})).toEqual({
|
|
271
|
+
type: 'insert',
|
|
272
|
+
value: '\\sqrt{#?}'
|
|
273
|
+
});
|
|
274
|
+
expect((0, _latexBridge.keyToAction)({
|
|
275
|
+
command: '^'
|
|
276
|
+
})).toEqual({
|
|
277
|
+
type: 'insert',
|
|
278
|
+
value: '^{#?}'
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// MathQuill's `/` turned the preceding expression into the numerator: type
|
|
283
|
+
// 5, press the key, get 5/_ with the caret in the denominator. `#@` is
|
|
284
|
+
// MathLive's "selection, or the item before the cursor" token, and is what
|
|
285
|
+
// MathLive binds to `/` itself.
|
|
286
|
+
it('division takes the preceding item as the numerator', function () {
|
|
287
|
+
expect((0, _latexBridge.keyToAction)({
|
|
288
|
+
command: '/'
|
|
289
|
+
})).toEqual({
|
|
290
|
+
type: 'insert',
|
|
291
|
+
value: '\\frac{#@}{#?}'
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
it('an explicit blank-over-blank fraction stays empty', function () {
|
|
295
|
+
// distinct from `/`: this key is meant to insert two empty slots
|
|
296
|
+
expect((0, _latexBridge.keyToAction)({
|
|
297
|
+
command: '\\frac'
|
|
298
|
+
})).toEqual({
|
|
299
|
+
type: 'insert',
|
|
300
|
+
value: '\\frac{#?}{#?}'
|
|
301
|
+
});
|
|
302
|
+
});
|
|
303
|
+
it('the x-over-blank key routes through division', function () {
|
|
304
|
+
// eslint-disable-next-line global-require
|
|
305
|
+
var _require3 = require('../keys/fractions'),
|
|
306
|
+
xOverBlank = _require3.xOverBlank;
|
|
307
|
+
expect(xOverBlank.command).toEqual('/');
|
|
308
|
+
expect((0, _latexBridge.keyToAction)(xOverBlank).value).toEqual('\\frac{#@}{#?}');
|
|
309
|
+
});
|
|
310
|
+
it('passes argument-less commands through', function () {
|
|
311
|
+
expect((0, _latexBridge.keyToAction)({
|
|
312
|
+
command: '\\pi'
|
|
313
|
+
})).toEqual({
|
|
314
|
+
type: 'insert',
|
|
315
|
+
value: '\\pi'
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
it('concatenates array commands (MathQuill cmd() applied them in sequence)', function () {
|
|
319
|
+
// Measured Angle
|
|
320
|
+
expect((0, _latexBridge.keyToAction)({
|
|
321
|
+
command: ['m', '\\angle']
|
|
322
|
+
})).toEqual({
|
|
323
|
+
type: 'insert',
|
|
324
|
+
value: 'm\\angle'
|
|
325
|
+
});
|
|
326
|
+
// log base n - the `_` part must still expand to a placeholder
|
|
327
|
+
expect((0, _latexBridge.keyToAction)({
|
|
328
|
+
command: ['\\log', '_']
|
|
329
|
+
})).toEqual({
|
|
330
|
+
type: 'insert',
|
|
331
|
+
value: '\\log_{#?}'
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
it('always returns a string value for insert actions', function () {
|
|
335
|
+
[{
|
|
336
|
+
command: ['m', '\\angle']
|
|
337
|
+
}, {
|
|
338
|
+
command: '\\frac'
|
|
339
|
+
}, {
|
|
340
|
+
write: 'x'
|
|
341
|
+
}, {
|
|
342
|
+
latex: '\\pi'
|
|
343
|
+
}].forEach(function (k) {
|
|
344
|
+
expect((0, _typeof2["default"])((0, _latexBridge.keyToAction)(k).value)).toBe('string');
|
|
345
|
+
});
|
|
346
|
+
});
|
|
347
|
+
it('maps keystrokes to MathLive selectors', function () {
|
|
348
|
+
expect((0, _latexBridge.keyToAction)({
|
|
349
|
+
keystroke: 'Left'
|
|
350
|
+
})).toEqual({
|
|
351
|
+
type: 'command',
|
|
352
|
+
value: 'moveToPreviousChar'
|
|
353
|
+
});
|
|
354
|
+
expect((0, _latexBridge.keyToAction)({
|
|
355
|
+
keystroke: 'Right'
|
|
356
|
+
})).toEqual({
|
|
357
|
+
type: 'command',
|
|
358
|
+
value: 'moveToNextChar'
|
|
359
|
+
});
|
|
360
|
+
expect((0, _latexBridge.keyToAction)({
|
|
361
|
+
keystroke: 'Backspace'
|
|
362
|
+
})).toEqual({
|
|
363
|
+
type: 'command',
|
|
364
|
+
value: 'deleteBackward'
|
|
365
|
+
});
|
|
366
|
+
});
|
|
367
|
+
it('returns undefined for unknown/empty input', function () {
|
|
368
|
+
expect((0, _latexBridge.keyToAction)(undefined)).toBeUndefined();
|
|
369
|
+
expect((0, _latexBridge.keyToAction)({})).toBeUndefined();
|
|
370
|
+
expect((0, _latexBridge.keyToAction)({
|
|
371
|
+
keystroke: 'Nope'
|
|
372
|
+
})).toBeUndefined();
|
|
373
|
+
});
|
|
374
|
+
it('latex wins over command only when command is absent', function () {
|
|
375
|
+
// a key with both should use the command path (matches MathInput.keypadPress)
|
|
376
|
+
expect((0, _latexBridge.keyToAction)({
|
|
377
|
+
latex: '\\frac{}{}',
|
|
378
|
+
command: '\\frac'
|
|
379
|
+
})).toEqual({
|
|
380
|
+
type: 'insert',
|
|
381
|
+
value: '\\frac{#?}{#?}'
|
|
382
|
+
});
|
|
383
|
+
});
|
|
384
|
+
});
|
|
385
|
+
});
|
|
386
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbGF0ZXhCcmlkZ2UiLCJyZXF1aXJlIiwiZGVzY3JpYmUiLCJpdCIsImV4cGVjdCIsInRvTWF0aExpdmUiLCJ0b0VxdWFsIiwidW5kZWZpbmVkIiwiY29uY2F0IiwiTkVXTElORV9FTUJFRCIsIkRFRkFVTFRfRklFTERfSUQiLCJmcm9tTWF0aExpdmUiLCJzdG9yZWQiLCJmb3JFYWNoIiwibCIsIm5vdCIsInRvQ29udGFpbiIsInRvTmF0aXZlQ29tbWFuZHMiLCJvdXQiLCJ0b01hdGNoIiwiZmllbGRJZHMiLCJsYXRleCIsIl9yZXF1aXJlIiwiZGl2aWRlIiwiX3JlcXVpcmUyIiwicGVycGVuZGljdWxhciIsInBlcnBpbmRpY3VsYXIiLCJrZXlUb0FjdGlvbiIsInR5cGUiLCJ2YWx1ZSIsInRvQ2Fub25pY2FsQ29tbWFuZHMiLCJmcyIsInBhdGgiLCJrZXlzRGlyIiwicmVzb2x2ZSIsIl9fZGlybmFtZSIsImtleXMiLCJjb2xsZWN0IiwidiIsIkFycmF5IiwiaXNBcnJheSIsIl90eXBlb2YyIiwiY29tbWFuZCIsIndyaXRlIiwicHVzaCIsInJlYWRkaXJTeW5jIiwiZmlsdGVyIiwiZiIsInRlc3QiLCJPYmplY3QiLCJ2YWx1ZXMiLCJqb2luIiwibGVuZ3RoIiwidG9CZUdyZWF0ZXJUaGFuIiwiayIsImFjdGlvbiIsIk1BVEhRVUlMTF9BTElBU0VTIiwiYWxpYXMiLCJSZWdFeHAiLCJ0b0JlIiwiX3JlcXVpcmUzIiwieE92ZXJCbGFuayIsImtleXN0cm9rZSIsInRvQmVVbmRlZmluZWQiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvX190ZXN0c19fL2xhdGV4LWJyaWRnZS50ZXN0LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIHRvTWF0aExpdmUsXG4gIGZyb21NYXRoTGl2ZSxcbiAgZmllbGRJZHMsXG4gIGtleVRvQWN0aW9uLFxuICB0b05hdGl2ZUNvbW1hbmRzLFxuICB0b0Nhbm9uaWNhbENvbW1hbmRzLFxuICBNQVRIUVVJTExfQUxJQVNFUyxcbiAgTkVXTElORV9FTUJFRCxcbiAgREVGQVVMVF9GSUVMRF9JRCxcbn0gZnJvbSAnLi4vbGF0ZXgtYnJpZGdlJztcblxuZGVzY3JpYmUoJ2xhdGV4LWJyaWRnZScsICgpID0+IHtcbiAgZGVzY3JpYmUoJ3RvTWF0aExpdmUnLCAoKSA9PiB7XG4gICAgaXQoJ3Bhc3NlcyBwbGFpbiBsYXRleCB0aHJvdWdoJywgKCkgPT4ge1xuICAgICAgZXhwZWN0KHRvTWF0aExpdmUoJ1xcXFxmcmFjezF9ezJ9JykpLnRvRXF1YWwoJ1xcXFxmcmFjezF9ezJ9Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnaGFuZGxlcyBlbXB0eS9udWxsaXNoJywgKCkgPT4ge1xuICAgICAgZXhwZWN0KHRvTWF0aExpdmUoJycpKS50b0VxdWFsKCcnKTtcbiAgICAgIGV4cGVjdCh0b01hdGhMaXZlKHVuZGVmaW5lZCkpLnRvRXF1YWwoJycpO1xuICAgICAgZXhwZWN0KHRvTWF0aExpdmUobnVsbCkpLnRvRXF1YWwoJycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2NvbnZlcnRzIGEgbmV3TGluZSBlbWJlZCB0byBhIG11bHRpbGluZSBlbnZpcm9ubWVudCcsICgpID0+IHtcbiAgICAgIGV4cGVjdCh0b01hdGhMaXZlKGBhJHtORVdMSU5FX0VNQkVEfWJgKSkudG9FcXVhbCgnXFxcXGRpc3BsYXlsaW5lc3thIFxcXFxcXFxcIGJ9Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnY29udmVydHMgbXVsdGlwbGUgbmV3TGluZSBlbWJlZHMnLCAoKSA9PiB7XG4gICAgICBleHBlY3QodG9NYXRoTGl2ZShgYSR7TkVXTElORV9FTUJFRH1iJHtORVdMSU5FX0VNQkVEfWNgKSkudG9FcXVhbCgnXFxcXGRpc3BsYXlsaW5lc3thIFxcXFxcXFxcIGIgXFxcXFxcXFwgY30nKTtcbiAgICB9KTtcblxuICAgIGl0KCdjb252ZXJ0cyBNYXRoUXVpbGwgYW5zd2VyIGJsb2NrcyB0byBwbGFjZWhvbGRlcnMnLCAoKSA9PiB7XG4gICAgICBleHBlY3QodG9NYXRoTGl2ZSgneD1cXFxcTWF0aFF1aWxsTWF0aEZpZWxkW3IxXXt9JykpLnRvRXF1YWwoJ3g9XFxcXHBsYWNlaG9sZGVyW3IxXXt9Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgncHJlc2VydmVzIGFuc3dlciBibG9jayBjb250ZW50JywgKCkgPT4ge1xuICAgICAgZXhwZWN0KHRvTWF0aExpdmUoJ1xcXFxNYXRoUXVpbGxNYXRoRmllbGRbcjJdezd9JykpLnRvRXF1YWwoJ1xcXFxwbGFjZWhvbGRlcltyMl17N30nKTtcbiAgICB9KTtcblxuICAgIGl0KCdkZWZhdWx0cyBhbiB1bm5hbWVkIGFuc3dlciBibG9jayBpZCcsICgpID0+IHtcbiAgICAgIGV4cGVjdCh0b01hdGhMaXZlKCdcXFxcTWF0aFF1aWxsTWF0aEZpZWxkW117fScpKS50b0VxdWFsKGBcXFxccGxhY2Vob2xkZXJbJHtERUZBVUxUX0ZJRUxEX0lEfV17fWApO1xuICAgIH0pO1xuXG4gICAgaXQoJ2hhbmRsZXMgYW5zd2VyIGJsb2NrcyBhbmQgbmV3bGluZXMgdG9nZXRoZXInLCAoKSA9PiB7XG4gICAgICBleHBlY3QodG9NYXRoTGl2ZShgXFxcXE1hdGhRdWlsbE1hdGhGaWVsZFtyMV17fSR7TkVXTElORV9FTUJFRH14YCkpLnRvRXF1YWwoXG4gICAgICAgICdcXFxcZGlzcGxheWxpbmVze1xcXFxwbGFjZWhvbGRlcltyMV17fSBcXFxcXFxcXCB4fScsXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZnJvbU1hdGhMaXZlJywgKCkgPT4ge1xuICAgIGl0KCdwYXNzZXMgcGxhaW4gbGF0ZXggdGhyb3VnaCcsICgpID0+IHtcbiAgICAgIGV4cGVjdChmcm9tTWF0aExpdmUoJ1xcXFxmcmFjezF9ezJ9JykpLnRvRXF1YWwoJ1xcXFxmcmFjezF9ezJ9Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgndW53cmFwcyBkaXNwbGF5bGluZXMgYmFjayB0byBuZXdMaW5lIGVtYmVkcycsICgpID0+IHtcbiAgICAgIGV4cGVjdChmcm9tTWF0aExpdmUoJ1xcXFxkaXNwbGF5bGluZXN7YSBcXFxcXFxcXCBifScpKS50b0VxdWFsKGBhJHtORVdMSU5FX0VNQkVEfWJgKTtcbiAgICB9KTtcblxuICAgIGl0KCdjb252ZXJ0cyBwbGFjZWhvbGRlcnMgYmFjayB0byBNYXRoUXVpbGwgYW5zd2VyIGJsb2NrcycsICgpID0+IHtcbiAgICAgIGV4cGVjdChmcm9tTWF0aExpdmUoJ3g9XFxcXHBsYWNlaG9sZGVyW3IxXXt9JykpLnRvRXF1YWwoJ3g9XFxcXE1hdGhRdWlsbE1hdGhGaWVsZFtyMV17fScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3JvdW5kLXRyaXBzIGEgbmV3bGluZSBkb2N1bWVudCcsICgpID0+IHtcbiAgICAgIGNvbnN0IHN0b3JlZCA9IGBhJHtORVdMSU5FX0VNQkVEfWIke05FV0xJTkVfRU1CRUR9Y2A7XG5cbiAgICAgIGV4cGVjdChmcm9tTWF0aExpdmUodG9NYXRoTGl2ZShzdG9yZWQpKSkudG9FcXVhbChzdG9yZWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3JvdW5kLXRyaXBzIGFuIGFuc3dlci1ibG9jayBkb2N1bWVudCcsICgpID0+IHtcbiAgICAgIGNvbnN0IHN0b3JlZCA9ICd4PVxcXFxNYXRoUXVpbGxNYXRoRmllbGRbcjFde30rXFxcXE1hdGhRdWlsbE1hdGhGaWVsZFtyMl17M30nO1xuXG4gICAgICBleHBlY3QoZnJvbU1hdGhMaXZlKHRvTWF0aExpdmUoc3RvcmVkKSkpLnRvRXF1YWwoc3RvcmVkKTtcbiAgICB9KTtcblxuICAgIC8vIE1hdGhMaXZlIHNlcmlhbGlzZXMgZW1wdHkgc2xvdHMgYXMgXFxwbGFjZWhvbGRlcnt9LCB3aGljaCBNYXRoSmF4ICh1c2VkIGJ5XG4gICAgLy8gQHBpZS1saWIvbWF0aC1yZW5kZXJpbmcgZm9yIHByb21wdHMvcHJldmlld3MpIHJlbmRlcnMgYXMgcmVkIGVycm9yIHRleHQuXG4gICAgaXQoJ3N0cmlwcyB1bm5hbWVkIHBsYWNlaG9sZGVycyB0aGF0IE1hdGhMaXZlIGFkZHMnLCAoKSA9PiB7XG4gICAgICBleHBlY3QoZnJvbU1hdGhMaXZlKCdcXFxcbG9uZ2RpdntcXFxccGxhY2Vob2xkZXJ7fX0nKSkudG9FcXVhbCgnXFxcXGxvbmdkaXZ7fScpO1xuICAgICAgZXhwZWN0KGZyb21NYXRoTGl2ZSgnXFxcXGZyYWN7XFxcXHBsYWNlaG9sZGVye319e1xcXFxwbGFjZWhvbGRlcnt9fScpKS50b0VxdWFsKCdcXFxcZnJhY3t9e30nKTtcbiAgICB9KTtcblxuICAgIGl0KCdrZWVwcyBjb250ZW50IGluc2lkZSBhbiB1bm5hbWVkIHBsYWNlaG9sZGVyJywgKCkgPT4ge1xuICAgICAgZXhwZWN0KGZyb21NYXRoTGl2ZSgnXFxcXHNxcnR7XFxcXHBsYWNlaG9sZGVyezd9fScpKS50b0VxdWFsKCdcXFxcc3FydHs3fScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2hhbmRsZXMgYSBiYXJlIFxcXFxwbGFjZWhvbGRlciB3aXRoIG5vIGFyZ3VtZW50JywgKCkgPT4ge1xuICAgICAgZXhwZWN0KGZyb21NYXRoTGl2ZSgnXFxcXGxvbmdkaXZ7XFxcXHBsYWNlaG9sZGVyfScpKS50b0VxdWFsKCdcXFxcbG9uZ2Rpdnt9Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnbmV2ZXIgbGVha3MgdGhlIHRva2VuIFxcXFxwbGFjZWhvbGRlcicsICgpID0+IHtcbiAgICAgIFsnXFxcXGxvbmdkaXZ7XFxcXHBsYWNlaG9sZGVye319JywgJ1xcXFxmcmFje1xcXFxwbGFjZWhvbGRlcnt9fXt4fScsICdcXFxccGxhY2Vob2xkZXJ7fSddLmZvckVhY2goKGwpID0+IHtcbiAgICAgICAgZXhwZWN0KGZyb21NYXRoTGl2ZShsKSkubm90LnRvQ29udGFpbignXFxcXHBsYWNlaG9sZGVyJyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzdGlsbCBtYXBzIE5BTUVEIHBsYWNlaG9sZGVycyB0byBhbnN3ZXIgYmxvY2tzJywgKCkgPT4ge1xuICAgICAgLy8gbmFtZWQgb25lcyBhcmUgYW5zd2VyIGJsb2NrcyBhbmQgbXVzdCBzdXJ2aXZlXG4gICAgICBleHBlY3QoZnJvbU1hdGhMaXZlKCdcXFxccGxhY2Vob2xkZXJbcjFde30nKSkudG9FcXVhbCgnXFxcXE1hdGhRdWlsbE1hdGhGaWVsZFtyMV17fScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3JvdW5kLXRyaXBzIGFuc3dlciBibG9ja3MgY29tYmluZWQgd2l0aCBuZXdsaW5lcycsICgpID0+IHtcbiAgICAgIGNvbnN0IHN0b3JlZCA9IGBcXFxcTWF0aFF1aWxsTWF0aEZpZWxkW3IxXXt9JHtORVdMSU5FX0VNQkVEfXlgO1xuXG4gICAgICBleHBlY3QoZnJvbU1hdGhMaXZlKHRvTWF0aExpdmUoc3RvcmVkKSkpLnRvRXF1YWwoc3RvcmVkKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gQSBNYXRoTGl2ZSBtYWNybyBzZXJpYWxpc2VzIGZyb20gdGhlIGFyZ3VtZW50cyBpdCB3YXMgY3JlYXRlZCB3aXRoLCBzbyB0ZXh0XG4gIC8vIHR5cGVkIGluc2lkZSBpdHMgZXhwYW5zaW9uIG5ldmVyIGNvbWVzIGJhY2sgb3V0IG9mIGdldFZhbHVlKCdsYXRleCcpLlxuICAvLyBBcmd1bWVudC10YWtpbmcgcGllIGNvbW1hbmRzIG11c3QgdGhlcmVmb3JlIGJlY29tZSBuYXRpdmUgY29uc3RydWN0cyBiZWZvcmVcbiAgLy8gdGhleSByZWFjaCBhIG1hdGhmaWVsZC5cbiAgZGVzY3JpYmUoJ3RvTmF0aXZlQ29tbWFuZHMnLCAoKSA9PiB7XG4gICAgaXQoJ2V4cGFuZHMgXFxcXGxvbmdkaXYgdG8gbmF0aXZlIFxcXFxlbmNsb3NlJywgKCkgPT4ge1xuICAgICAgZXhwZWN0KHRvTmF0aXZlQ29tbWFuZHMoJ1xcXFxsb25nZGl2ezEyMzR9JykpLnRvRXF1YWwoJ1xcXFxlbmNsb3Nle2xvbmdkaXZ9ezEyMzR9Jyk7XG4gICAgICBleHBlY3QodG9OYXRpdmVDb21tYW5kcygnXFxcXGxvbmdkaXZ7fScpKS50b0VxdWFsKCdcXFxcZW5jbG9zZXtsb25nZGl2fXt9Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnZXhwYW5kcyBcXFxcb3ZlcmFyYyB0byBuYXRpdmUgXFxcXG92ZXJwYXJlbicsICgpID0+IHtcbiAgICAgIGV4cGVjdCh0b05hdGl2ZUNvbW1hbmRzKCdcXFxcb3ZlcmFyY3tBQn0nKSkudG9FcXVhbCgnXFxcXG92ZXJwYXJlbntBQn0nKTtcbiAgICB9KTtcblxuICAgIGl0KCdleHBhbmRzIFxcXFxhYnMgdG8gbmF0aXZlIFxcXFxsZWZ0fC4uXFxcXHJpZ2h0fCcsICgpID0+IHtcbiAgICAgIGV4cGVjdCh0b05hdGl2ZUNvbW1hbmRzKCdcXFxcYWJze3h9JykpLnRvRXF1YWwoJ1xcXFxsZWZ0fHhcXFxccmlnaHR8Jyk7XG4gICAgICBleHBlY3QodG9OYXRpdmVDb21tYW5kcygnXFxcXGFic3t9JykpLnRvRXF1YWwoJ1xcXFxsZWZ0fFxcXFxyaWdodHwnKTtcbiAgICB9KTtcblxuICAgIGl0KCdoYW5kbGVzIG5lc3RlZCBicmFjZXMgaW5zaWRlIFxcXFxhYnMnLCAoKSA9PiB7XG4gICAgICBleHBlY3QodG9OYXRpdmVDb21tYW5kcygnXFxcXGFic3tcXFxcZnJhY3sxfXsyfX0nKSkudG9FcXVhbCgnXFxcXGxlZnR8XFxcXGZyYWN7MX17Mn1cXFxccmlnaHR8Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnaGFuZGxlcyBzZXZlcmFsIG9jY3VycmVuY2VzJywgKCkgPT4ge1xuICAgICAgZXhwZWN0KHRvTmF0aXZlQ29tbWFuZHMoJ1xcXFxhYnN7YX0rXFxcXGFic3tifScpKS50b0VxdWFsKCdcXFxcbGVmdHxhXFxcXHJpZ2h0fCtcXFxcbGVmdHxiXFxcXHJpZ2h0fCcpO1xuICAgICAgZXhwZWN0KHRvTmF0aXZlQ29tbWFuZHMoJ1xcXFxsb25nZGl2ezF9XFxcXGxvbmdkaXZ7Mn0nKSkudG9FcXVhbCgnXFxcXGVuY2xvc2V7bG9uZ2Rpdn17MX1cXFxcZW5jbG9zZXtsb25nZGl2fXsyfScpO1xuICAgIH0pO1xuXG4gICAgLy8gYCVgIHN0YXJ0cyBhIGNvbW1lbnQgaW4gcmVhbCBMYVRlWCwgc28gTWF0aExpdmUgZHJvcHMgaXQgYW5kIGV2ZXJ5dGhpbmdcbiAgICAvLyBhZnRlciBpdC4gTWF0aFF1aWxsIGhhZCBubyBjb21tZW50cywgc28gbGF0ZXggYXV0aG9yZWQgdW5kZXIgaXQgLSBvciBieVxuICAgIC8vIGhhbmQgLSBjYW4gY2FycnkgYSBiYXJlIGAlYCB0aGF0IHdvdWxkIHNpbGVudGx5IHRydW5jYXRlIHRoZSBleHByZXNzaW9uLlxuICAgIGl0KCdlc2NhcGVzIGEgYmFyZSAlIHNvIGl0IGNhbm5vdCBjb21tZW50IG91dCB0aGUgcmVzdCBvZiB0aGUgbGluZScsICgpID0+IHtcbiAgICAgIGV4cGVjdCh0b05hdGl2ZUNvbW1hbmRzKCclJykpLnRvRXF1YWwoJ1xcXFwlJyk7XG4gICAgICBleHBlY3QodG9OYXRpdmVDb21tYW5kcygnNTAlJykpLnRvRXF1YWwoJzUwXFxcXCUnKTtcbiAgICAgIGV4cGVjdCh0b05hdGl2ZUNvbW1hbmRzKCd4JXknKSkudG9FcXVhbCgneFxcXFwleScpO1xuICAgICAgZXhwZWN0KHRvTmF0aXZlQ29tbWFuZHMoJ2ElYiVjJykpLnRvRXF1YWwoJ2FcXFxcJWJcXFxcJWMnKTtcbiAgICB9KTtcblxuICAgIGl0KCdsZWF2ZXMgYW4gYWxyZWFkeS1lc2NhcGVkICUgYWxvbmUnLCAoKSA9PiB7XG4gICAgICBleHBlY3QodG9OYXRpdmVDb21tYW5kcygnXFxcXCUnKSkudG9FcXVhbCgnXFxcXCUnKTtcbiAgICAgIGV4cGVjdCh0b05hdGl2ZUNvbW1hbmRzKCc1MFxcXFwlJykpLnRvRXF1YWwoJzUwXFxcXCUnKTtcbiAgICAgIC8vIGlkZW1wb3RlbnQ6IHRvTWF0aExpdmUgbWF5IHJ1biBvdmVyIGxhdGV4IHRoYXQgY2FtZSBiYWNrIG91dCBvZiBhIGZpZWxkXG4gICAgICBleHBlY3QodG9OYXRpdmVDb21tYW5kcyh0b05hdGl2ZUNvbW1hbmRzKCc1MCUnKSkpLnRvRXF1YWwoJzUwXFxcXCUnKTtcbiAgICB9KTtcblxuICAgIC8vIGBcXFxcYCBpcyBhIGxpbmUgYnJlYWssIG5vdCBhbiBlc2NhcGUsIHNvIHRoZSBgJWAgYWZ0ZXIgaXQgaXMgc3RpbGwgYmFyZS5cbiAgICBpdCgnY291bnRzIGJhY2tzbGFzaGVzIHRvIGRlY2lkZSB3aGV0aGVyIGEgJSBpcyBlc2NhcGVkJywgKCkgPT4ge1xuICAgICAgZXhwZWN0KHRvTmF0aXZlQ29tbWFuZHMoJ2FcXFxcXFxcXCViJykpLnRvRXF1YWwoJ2FcXFxcXFxcXFxcXFwlYicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2xlYXZlcyBvdGhlciBsYXRleCB1bnRvdWNoZWQnLCAoKSA9PiB7XG4gICAgICBbJ1xcXFxmcmFjezF9ezJ9JywgJ1xcXFxwaScsICdcXFxcc3FydHt4fScsICdcXFxcb3ZlcmxpbmV7QUJ9J10uZm9yRWFjaCgobCkgPT4ge1xuICAgICAgICBleHBlY3QodG9OYXRpdmVDb21tYW5kcyhsKSkudG9FcXVhbChsKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2hhbmRsZXMgbnVsbGlzaCBpbnB1dCcsICgpID0+IHtcbiAgICAgIGV4cGVjdCh0b05hdGl2ZUNvbW1hbmRzKHVuZGVmaW5lZCkpLnRvRXF1YWwoJycpO1xuICAgICAgZXhwZWN0KHRvTmF0aXZlQ29tbWFuZHMoJycpKS50b0VxdWFsKCcnKTtcbiAgICB9KTtcblxuICAgIGl0KCdpcyBhcHBsaWVkIGJ5IHRvTWF0aExpdmUnLCAoKSA9PiB7XG4gICAgICBleHBlY3QodG9NYXRoTGl2ZSgnXFxcXGxvbmdkaXZ7NX0nKSkudG9FcXVhbCgnXFxcXGVuY2xvc2V7bG9uZ2Rpdn17NX0nKTtcbiAgICB9KTtcblxuICAgIGl0KCdkb2VzIG5vdCBsZWF2ZSBhIHBpZSBtYWNybyBpbiB3aGF0IHJlYWNoZXMgdGhlIGZpZWxkJywgKCkgPT4ge1xuICAgICAgWydcXFxcbG9uZ2Rpdns3fScsICdcXFxcYWJzezd9JywgJ1xcXFxvdmVyYXJjezd9J10uZm9yRWFjaCgobCkgPT4ge1xuICAgICAgICBjb25zdCBvdXQgPSB0b01hdGhMaXZlKGwpO1xuXG4gICAgICAgIGV4cGVjdChvdXQpLm5vdC50b01hdGNoKC9cXFxcbG9uZ2RpdnxcXFxcYWJzfFxcXFxvdmVyYXJjLyk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2ZpZWxkSWRzJywgKCkgPT4ge1xuICAgIGl0KCdyZXR1cm5zIGlkcyBpbiBkb2N1bWVudCBvcmRlcicsICgpID0+IHtcbiAgICAgIGV4cGVjdChmaWVsZElkcygnXFxcXE1hdGhRdWlsbE1hdGhGaWVsZFtyMV17fStcXFxcTWF0aFF1aWxsTWF0aEZpZWxkW3IyXXt9JykpLnRvRXF1YWwoWydyMScsICdyMiddKTtcbiAgICB9KTtcblxuICAgIGl0KCdyZXR1cm5zIFtdIHdoZW4gdGhlcmUgYXJlIG5vbmUnLCAoKSA9PiB7XG4gICAgICBleHBlY3QoZmllbGRJZHMoJ3greScpKS50b0VxdWFsKFtdKTtcbiAgICAgIGV4cGVjdChmaWVsZElkcyh1bmRlZmluZWQpKS50b0VxdWFsKFtdKTtcbiAgICB9KTtcblxuICAgIGl0KCdpcyByZXBlYXRhYmxlIChyZWdleCBsYXN0SW5kZXggaXMgcmVzZXQpJywgKCkgPT4ge1xuICAgICAgY29uc3QgbGF0ZXggPSAnXFxcXE1hdGhRdWlsbE1hdGhGaWVsZFtyMV17fSc7XG5cbiAgICAgIGV4cGVjdChmaWVsZElkcyhsYXRleCkpLnRvRXF1YWwoWydyMSddKTtcbiAgICAgIGV4cGVjdChmaWVsZElkcyhsYXRleCkpLnRvRXF1YWwoWydyMSddKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gTWF0aFF1aWxsIHJlZ2lzdGVyZWQgc29tZSBrZXlwYWQgbmFtZXMgYXMgYWxpYXNlcyBvZiBhIGRpZmZlcmVudCBjb21tYW5kOlxuICAvLyB0aGUgZGl2aWRlIGtleSBzdG9yZWQgYFxcZGl2YCwgbm90IGBcXGRpdmlkZWAuIE1hdGhMaXZlIGtub3dzIGBcXGRpdmlkZWAgb25seSBhc1xuICAvLyBhIHBpZSBtYWNybyBhbmQgc2VyaWFsaXNlcyBpdCB1bmRlciB0aGF0IG5hbWUsIHNvIGl0IHJlYWNoZWQgc3RvcmFnZSBhbmRcbiAgLy8gTWF0aEpheCAod2hpY2ggaGFzIG5vIGBcXGRpdmlkZWApIHJlbmRlcmVkIGl0IGFzIHJlZCB0ZXh0LlxuICBkZXNjcmliZSgnTWF0aFF1aWxsIGNvbW1hbmQgYWxpYXNlcycsICgpID0+IHtcbiAgICBpdCgndGhlIGRpdmlkZSBhbmQgcGVycGVuZGljdWxhciBrZXlzIGluc2VydCB0aGUgY29tbWFuZCBNYXRoUXVpbGwgc3RvcmVkJywgKCkgPT4ge1xuICAgICAgLyogZXNsaW50LWRpc2FibGUgZ2xvYmFsLXJlcXVpcmUgKi9cbiAgICAgIGNvbnN0IHsgZGl2aWRlIH0gPSByZXF1aXJlKCcuLi9rZXlzL2Jhc2ljLW9wZXJhdG9ycycpO1xuICAgICAgLy8gRXhwb3J0ZWQgdW5kZXIgYSBwcmUtZXhpc3RpbmcgbWlzc3BlbGxpbmcuXG4gICAgICBjb25zdCB7IHBlcnBpbmRpY3VsYXI6IHBlcnBlbmRpY3VsYXIgfSA9IHJlcXVpcmUoJy4uL2tleXMvZ2VvbWV0cnknKTtcbiAgICAgIC8qIGVzbGludC1lbmFibGUgZ2xvYmFsLXJlcXVpcmUgKi9cblxuICAgICAgZXhwZWN0KGtleVRvQWN0aW9uKGRpdmlkZSkpLnRvRXF1YWwoeyB0eXBlOiAnaW5zZXJ0JywgdmFsdWU6ICdcXFxcZGl2JyB9KTtcbiAgICAgIGV4cGVjdChrZXlUb0FjdGlvbihwZXJwZW5kaWN1bGFyKSkudG9FcXVhbCh7IHR5cGU6ICdpbnNlcnQnLCB2YWx1ZTogJ1xcXFxwZXJwJyB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzdG9yZXMgdGhlIGNhbm9uaWNhbCBjb21tYW5kIGZvciBsYXRleCB0aGF0IHN0aWxsIGNhcnJpZXMgYW4gYWxpYXMnLCAoKSA9PiB7XG4gICAgICAvLyBUeXBlZCBpbnRvIHRoZSBmaWVsZCwgb3Igc2F2ZWQgYmVmb3JlIHRoZSBrZXlwYWQgcmVzb2x2ZWQgdGhlIGFsaWFzLlxuICAgICAgZXhwZWN0KGZyb21NYXRoTGl2ZSgnMVxcXFxkaXZpZGUgNicpKS50b0VxdWFsKCcxXFxcXGRpdiA2Jyk7XG4gICAgICBleHBlY3QoZnJvbU1hdGhMaXZlKCdhXFxcXHBlcnBlbmRpY3VsYXIgYicpKS50b0VxdWFsKCdhXFxcXHBlcnAgYicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ29ubHkgcmVwbGFjZXMgd2hvbGUgY29tbWFuZCBuYW1lcycsICgpID0+IHtcbiAgICAgIC8vIFxcZGl2aWRlb250aW1lcyBpcyBhIHJlYWwgQU1TIHN5bWJvbCBhbmQgbXVzdCBzdXJ2aXZlLlxuICAgICAgZXhwZWN0KHRvQ2Fub25pY2FsQ29tbWFuZHMoJ2FcXFxcZGl2aWRlb250aW1lcyBiJykpLnRvRXF1YWwoJ2FcXFxcZGl2aWRlb250aW1lcyBiJyk7XG4gICAgICBleHBlY3QodG9DYW5vbmljYWxDb21tYW5kcygnXFxcXGRpdmlkZVxcXFxkaXZpZGUnKSkudG9FcXVhbCgnXFxcXGRpdlxcXFxkaXYnKTtcbiAgICB9KTtcblxuICAgIC8vIFRoZSBkb3VibGUgcHJpbWUga2V5OiBNYXRoTGl2ZSBzZXJpYWxpc2VzIGA1JydgIGFzIGA1XntcXGRvdWJsZXByaW1lfWAsXG4gICAgLy8gd2hpY2ggTWF0aEpheCBjYW5ub3QgcmVuZGVyIChyZWQgYFxcZG91YmxlcHJpbWVgKS4gTWF0aFF1aWxsIHN0b3JlZCBgNScnYC5cbiAgICBpdCgnc3RvcmVzIHRoZSBkb3VibGUgcHJpbWUga2V5IGFzIGFwb3N0cm9waGVzJywgKCkgPT4ge1xuICAgICAgZXhwZWN0KGZyb21NYXRoTGl2ZSgnNV57XFxcXGRvdWJsZXByaW1lfScpKS50b0VxdWFsKFwiNScnXCIpO1xuICAgICAgZXhwZWN0KGZyb21NYXRoTGl2ZSgneF57XFxcXHByaW1lfScpKS50b0VxdWFsKFwieCdcIik7XG4gICAgICBleHBlY3QoZnJvbU1hdGhMaXZlKCd4XntcXFxccHJpbWVcXFxccHJpbWVcXFxccHJpbWV9JykpLnRvRXF1YWwoXCJ4JycnXCIpO1xuICAgICAgZXhwZWN0KGZyb21NYXRoTGl2ZSgnXFxcXGRvdWJsZXByaW1lJykpLnRvRXF1YWwoXCInJ1wiKTtcbiAgICB9KTtcblxuICAgIC8vIFR5cGluZyBgJ2AgdHdpY2UgeWllbGRzIHR3byBzdXBlcnNjcmlwdCBncm91cHMgLSBhIE1hdGhKYXggZG91YmxlLWV4cG9uZW50XG4gICAgLy8gZXJyb3IgLSBzbyB0aGV5IGNvbGxhcHNlIGludG8gYXBvc3Ryb3BoZXMgdG9vLlxuICAgIGl0KCdjb2xsYXBzZXMgYWRqYWNlbnQgcHJpbWUgc3VwZXJzY3JpcHRzJywgKCkgPT4ge1xuICAgICAgZXhwZWN0KGZyb21NYXRoTGl2ZSgneF57XFxcXHByaW1lfV57XFxcXHByaW1lfScpKS50b0VxdWFsKFwieCcnXCIpO1xuICAgICAgZXhwZWN0KGZyb21NYXRoTGl2ZSgnNV57XFxcXHByaW1lfV57XFxcXGRvdWJsZXByaW1lfScpKS50b0VxdWFsKFwiNScnJ1wiKTtcbiAgICB9KTtcblxuICAgIGl0KCdsZWF2ZXMgc3VwZXJzY3JpcHRzIHRoYXQgaG9sZCBtb3JlIHRoYW4gcHJpbWVzIGFsb25lJywgKCkgPT4ge1xuICAgICAgZXhwZWN0KGZyb21NYXRoTGl2ZSgneF57XFxcXHByaW1lIDJ9JykpLnRvRXF1YWwoJ3hee1xcXFxwcmltZSAyfScpO1xuICAgICAgZXhwZWN0KGZyb21NYXRoTGl2ZSgneF57Mn0nKSkudG9FcXVhbCgneF57Mn0nKTtcbiAgICB9KTtcblxuICAgIGl0KCdyb3VuZC10cmlwcyBzdG9yZWQgcHJpbWVzIHVuY2hhbmdlZCcsICgpID0+IHtcbiAgICAgIGV4cGVjdChmcm9tTWF0aExpdmUoXCIxMl57XFxcXGNpcmN9MzAnMTUnJ1wiKSkudG9FcXVhbChcIjEyXntcXFxcY2lyY30zMCcxNScnXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ25vIGtleXBhZCBrZXkgaW5zZXJ0cyBhbiBhbGlhcyBuYW1lJywgKCkgPT4ge1xuICAgICAgLyogZXNsaW50LWRpc2FibGUgZ2xvYmFsLXJlcXVpcmUgKi9cbiAgICAgIGNvbnN0IGZzID0gcmVxdWlyZSgnZnMnKTtcbiAgICAgIGNvbnN0IHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XG4gICAgICAvKiBlc2xpbnQtZW5hYmxlIGdsb2JhbC1yZXF1aXJlICovXG4gICAgICBjb25zdCBrZXlzRGlyID0gcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4uL2tleXMnKTtcbiAgICAgIGNvbnN0IGtleXMgPSBbXTtcblxuICAgICAgY29uc3QgY29sbGVjdCA9ICh2KSA9PiB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHYpKSByZXR1cm4gdi5mb3JFYWNoKGNvbGxlY3QpO1xuICAgICAgICBpZiAodiAmJiB0eXBlb2YgdiA9PT0gJ29iamVjdCcgJiYgKHYuY29tbWFuZCB8fCB2LmxhdGV4IHx8IHYud3JpdGUpKSBrZXlzLnB1c2godik7XG4gICAgICB9O1xuXG4gICAgICBmcy5yZWFkZGlyU3luYyhrZXlzRGlyKVxuICAgICAgICAuZmlsdGVyKChmKSA9PiAvXFwuanMkLy50ZXN0KGYpKVxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZ2xvYmFsLXJlcXVpcmUsIGltcG9ydC9uby1keW5hbWljLXJlcXVpcmVcbiAgICAgICAgLmZvckVhY2goKGYpID0+IE9iamVjdC52YWx1ZXMocmVxdWlyZShwYXRoLmpvaW4oa2V5c0RpciwgZikpKS5mb3JFYWNoKGNvbGxlY3QpKTtcblxuICAgICAgZXhwZWN0KGtleXMubGVuZ3RoKS50b0JlR3JlYXRlclRoYW4oNTApO1xuXG4gICAgICBrZXlzLmZvckVhY2goKGspID0+IHtcbiAgICAgICAgY29uc3QgYWN0aW9uID0ga2V5VG9BY3Rpb24oayk7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gKGFjdGlvbiAmJiBhY3Rpb24udmFsdWUpIHx8ICcnO1xuXG4gICAgICAgIE9iamVjdC5rZXlzKE1BVEhRVUlMTF9BTElBU0VTKS5mb3JFYWNoKChhbGlhcykgPT4ge1xuICAgICAgICAgIGV4cGVjdChuZXcgUmVnRXhwKGBcXFxcJHthbGlhc30oPyFbYS16QS1aXSlgKS50ZXN0KHZhbHVlKSkudG9CZShmYWxzZSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdrZXlUb0FjdGlvbicsICgpID0+IHtcbiAgICBpdCgncHJlZmVycyBsYXRleCB3aGVuIHRoZXJlIGlzIG5vIGNvbW1hbmQnLCAoKSA9PiB7XG4gICAgICBleHBlY3Qoa2V5VG9BY3Rpb24oeyBsYXRleDogJ1xcXFxwaScsIHdyaXRlOiAncCcgfSkpLnRvRXF1YWwoeyB0eXBlOiAnaW5zZXJ0JywgdmFsdWU6ICdcXFxccGknIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3VzZXMgd3JpdGUnLCAoKSA9PiB7XG4gICAgICBleHBlY3Qoa2V5VG9BY3Rpb24oeyB3cml0ZTogJ3gnIH0pKS50b0VxdWFsKHsgdHlwZTogJ2luc2VydCcsIHZhbHVlOiAneCcgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnZXhwYW5kcyBjb21tYW5kcyB0aGF0IHRha2UgYXJndW1lbnRzIGludG8gcGxhY2Vob2xkZXJzJywgKCkgPT4ge1xuICAgICAgZXhwZWN0KGtleVRvQWN0aW9uKHsgY29tbWFuZDogJ1xcXFxmcmFjJyB9KSkudG9FcXVhbCh7IHR5cGU6ICdpbnNlcnQnLCB2YWx1ZTogJ1xcXFxmcmFjeyM/fXsjP30nIH0pO1xuICAgICAgZXhwZWN0KGtleVRvQWN0aW9uKHsgY29tbWFuZDogJ1xcXFxzcXJ0JyB9KSkudG9FcXVhbCh7IHR5cGU6ICdpbnNlcnQnLCB2YWx1ZTogJ1xcXFxzcXJ0eyM/fScgfSk7XG4gICAgICBleHBlY3Qoa2V5VG9BY3Rpb24oeyBjb21tYW5kOiAnXicgfSkpLnRvRXF1YWwoeyB0eXBlOiAnaW5zZXJ0JywgdmFsdWU6ICdeeyM/fScgfSk7XG4gICAgfSk7XG5cbiAgICAvLyBNYXRoUXVpbGwncyBgL2AgdHVybmVkIHRoZSBwcmVjZWRpbmcgZXhwcmVzc2lvbiBpbnRvIHRoZSBudW1lcmF0b3I6IHR5cGVcbiAgICAvLyA1LCBwcmVzcyB0aGUga2V5LCBnZXQgNS9fIHdpdGggdGhlIGNhcmV0IGluIHRoZSBkZW5vbWluYXRvci4gYCNAYCBpc1xuICAgIC8vIE1hdGhMaXZlJ3MgXCJzZWxlY3Rpb24sIG9yIHRoZSBpdGVtIGJlZm9yZSB0aGUgY3Vyc29yXCIgdG9rZW4sIGFuZCBpcyB3aGF0XG4gICAgLy8gTWF0aExpdmUgYmluZHMgdG8gYC9gIGl0c2VsZi5cbiAgICBpdCgnZGl2aXNpb24gdGFrZXMgdGhlIHByZWNlZGluZyBpdGVtIGFzIHRoZSBudW1lcmF0b3InLCAoKSA9PiB7XG4gICAgICBleHBlY3Qoa2V5VG9BY3Rpb24oeyBjb21tYW5kOiAnLycgfSkpLnRvRXF1YWwoeyB0eXBlOiAnaW5zZXJ0JywgdmFsdWU6ICdcXFxcZnJhY3sjQH17Iz99JyB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdhbiBleHBsaWNpdCBibGFuay1vdmVyLWJsYW5rIGZyYWN0aW9uIHN0YXlzIGVtcHR5JywgKCkgPT4ge1xuICAgICAgLy8gZGlzdGluY3QgZnJvbSBgL2A6IHRoaXMga2V5IGlzIG1lYW50IHRvIGluc2VydCB0d28gZW1wdHkgc2xvdHNcbiAgICAgIGV4cGVjdChrZXlUb0FjdGlvbih7IGNvbW1hbmQ6ICdcXFxcZnJhYycgfSkpLnRvRXF1YWwoeyB0eXBlOiAnaW5zZXJ0JywgdmFsdWU6ICdcXFxcZnJhY3sjP317Iz99JyB9KTtcbiAgICB9KTtcblxuICAgIGl0KCd0aGUgeC1vdmVyLWJsYW5rIGtleSByb3V0ZXMgdGhyb3VnaCBkaXZpc2lvbicsICgpID0+IHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBnbG9iYWwtcmVxdWlyZVxuICAgICAgY29uc3QgeyB4T3ZlckJsYW5rIH0gPSByZXF1aXJlKCcuLi9rZXlzL2ZyYWN0aW9ucycpO1xuXG4gICAgICBleHBlY3QoeE92ZXJCbGFuay5jb21tYW5kKS50b0VxdWFsKCcvJyk7XG4gICAgICBleHBlY3Qoa2V5VG9BY3Rpb24oeE92ZXJCbGFuaykudmFsdWUpLnRvRXF1YWwoJ1xcXFxmcmFjeyNAfXsjP30nKTtcbiAgICB9KTtcblxuICAgIGl0KCdwYXNzZXMgYXJndW1lbnQtbGVzcyBjb21tYW5kcyB0aHJvdWdoJywgKCkgPT4ge1xuICAgICAgZXhwZWN0KGtleVRvQWN0aW9uKHsgY29tbWFuZDogJ1xcXFxwaScgfSkpLnRvRXF1YWwoeyB0eXBlOiAnaW5zZXJ0JywgdmFsdWU6ICdcXFxccGknIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2NvbmNhdGVuYXRlcyBhcnJheSBjb21tYW5kcyAoTWF0aFF1aWxsIGNtZCgpIGFwcGxpZWQgdGhlbSBpbiBzZXF1ZW5jZSknLCAoKSA9PiB7XG4gICAgICAvLyBNZWFzdXJlZCBBbmdsZVxuICAgICAgZXhwZWN0KGtleVRvQWN0aW9uKHsgY29tbWFuZDogWydtJywgJ1xcXFxhbmdsZSddIH0pKS50b0VxdWFsKHsgdHlwZTogJ2luc2VydCcsIHZhbHVlOiAnbVxcXFxhbmdsZScgfSk7XG4gICAgICAvLyBsb2cgYmFzZSBuIC0gdGhlIGBfYCBwYXJ0IG11c3Qgc3RpbGwgZXhwYW5kIHRvIGEgcGxhY2Vob2xkZXJcbiAgICAgIGV4cGVjdChrZXlUb0FjdGlvbih7IGNvbW1hbmQ6IFsnXFxcXGxvZycsICdfJ10gfSkpLnRvRXF1YWwoeyB0eXBlOiAnaW5zZXJ0JywgdmFsdWU6ICdcXFxcbG9nX3sjP30nIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2Fsd2F5cyByZXR1cm5zIGEgc3RyaW5nIHZhbHVlIGZvciBpbnNlcnQgYWN0aW9ucycsICgpID0+IHtcbiAgICAgIFt7IGNvbW1hbmQ6IFsnbScsICdcXFxcYW5nbGUnXSB9LCB7IGNvbW1hbmQ6ICdcXFxcZnJhYycgfSwgeyB3cml0ZTogJ3gnIH0sIHsgbGF0ZXg6ICdcXFxccGknIH1dLmZvckVhY2goKGspID0+IHtcbiAgICAgICAgZXhwZWN0KHR5cGVvZiBrZXlUb0FjdGlvbihrKS52YWx1ZSkudG9CZSgnc3RyaW5nJyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdtYXBzIGtleXN0cm9rZXMgdG8gTWF0aExpdmUgc2VsZWN0b3JzJywgKCkgPT4ge1xuICAgICAgZXhwZWN0KGtleVRvQWN0aW9uKHsga2V5c3Ryb2tlOiAnTGVmdCcgfSkpLnRvRXF1YWwoeyB0eXBlOiAnY29tbWFuZCcsIHZhbHVlOiAnbW92ZVRvUHJldmlvdXNDaGFyJyB9KTtcbiAgICAgIGV4cGVjdChrZXlUb0FjdGlvbih7IGtleXN0cm9rZTogJ1JpZ2h0JyB9KSkudG9FcXVhbCh7IHR5cGU6ICdjb21tYW5kJywgdmFsdWU6ICdtb3ZlVG9OZXh0Q2hhcicgfSk7XG4gICAgICBleHBlY3Qoa2V5VG9BY3Rpb24oeyBrZXlzdHJva2U6ICdCYWNrc3BhY2UnIH0pKS50b0VxdWFsKHsgdHlwZTogJ2NvbW1hbmQnLCB2YWx1ZTogJ2RlbGV0ZUJhY2t3YXJkJyB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdyZXR1cm5zIHVuZGVmaW5lZCBmb3IgdW5rbm93bi9lbXB0eSBpbnB1dCcsICgpID0+IHtcbiAgICAgIGV4cGVjdChrZXlUb0FjdGlvbih1bmRlZmluZWQpKS50b0JlVW5kZWZpbmVkKCk7XG4gICAgICBleHBlY3Qoa2V5VG9BY3Rpb24oe30pKS50b0JlVW5kZWZpbmVkKCk7XG4gICAgICBleHBlY3Qoa2V5VG9BY3Rpb24oeyBrZXlzdHJva2U6ICdOb3BlJyB9KSkudG9CZVVuZGVmaW5lZCgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2xhdGV4IHdpbnMgb3ZlciBjb21tYW5kIG9ubHkgd2hlbiBjb21tYW5kIGlzIGFic2VudCcsICgpID0+IHtcbiAgICAgIC8vIGEga2V5IHdpdGggYm90aCBzaG91bGQgdXNlIHRoZSBjb21tYW5kIHBhdGggKG1hdGNoZXMgTWF0aElucHV0LmtleXBhZFByZXNzKVxuICAgICAgZXhwZWN0KGtleVRvQWN0aW9uKHsgbGF0ZXg6ICdcXFxcZnJhY3t9e30nLCBjb21tYW5kOiAnXFxcXGZyYWMnIH0pKS50b0VxdWFsKHtcbiAgICAgICAgdHlwZTogJ2luc2VydCcsXG4gICAgICAgIHZhbHVlOiAnXFxcXGZyYWN7Iz99eyM/fScsXG4gICAg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
|