fable-editor 1.3.1 → 1.4.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.
@@ -82,9 +82,14 @@ function decodePict(body) {
82
82
  kind = 'metafile';
83
83
  if (!kind)
84
84
  return null;
85
+ /* Each removal leaves a space behind. Deleting outright would glue what surrounded
86
+ it together, and Word ends the picture header with `\bliptagN{\*\blipuid …}`
87
+ hard against the payload: dropping the uid group would let the \bliptag
88
+ parameter's `\d*` run straight on into the hex and eat its leading digits
89
+ (89504e47… -> e470…), which silently corrupts every picture Word sends. */
85
90
  let hex = body
86
- .replace(/\{[^{}]*\}/g, '') // nested property groups
87
- .replace(/\\[a-z]+-?\d*\s?/gi, '') // control words
91
+ .replace(/\{[^{}]*\}/g, ' ') // nested property groups
92
+ .replace(/\\[a-z]+-?\d*\s?/gi, ' ') // control words
88
93
  .replace(/[^0-9a-fA-F]/g, '');
89
94
  if (hex.length % 2)
90
95
  hex = hex.slice(0, -1);
@@ -127,6 +132,70 @@ export function extractRtfImages(rtf) {
127
132
  return data;
128
133
  });
129
134
  }
135
+ /** CSS length -> px, so a VML shape's size survives as the <img> width/height the
136
+ * paste engine allows. Unknown units are left for the caller to skip. */
137
+ function cssPx(value) {
138
+ const m = value.match(/^\s*(-?[\d.]+)\s*(pt|px|in|cm|mm)?\s*$/i);
139
+ if (!m)
140
+ return null;
141
+ const n = parseFloat(m[1]);
142
+ if (!isFinite(n) || n <= 0)
143
+ return null;
144
+ const unit = (m[2] || 'px').toLowerCase();
145
+ const px = unit === 'pt' ? (n * 4) / 3 : unit === 'in' ? n * 96 : unit === 'cm' ? (n * 96) / 2.54 : unit === 'mm' ? (n * 96) / 25.4 : n;
146
+ return Math.round(px);
147
+ }
148
+ function attrOf(tag, name) {
149
+ const m = tag.match(new RegExp('\\s' + name + '\\s*=\\s*(?:"([^"]*)"|\'([^\']*)\'|([^\\s>]+))', 'i'));
150
+ return m ? m[1] ?? m[2] ?? m[3] ?? '' : '';
151
+ }
152
+ /** Word describes a picture twice: as a VML shape inside a downlevel-hidden
153
+ * conditional comment, and as a plain <img> fallback after it. With RelyOnVML on —
154
+ * which is what a cropped picture gets — it writes only the shape, and the paste
155
+ * engine drops conditional comments, so the picture has no tag left to land on and
156
+ * disappears. Give those shapes the <img> Word withheld, keeping the shape's size.
157
+ * Pictures that do have the fallback are recognised by their src and left alone.
158
+ *
159
+ * The shape's crop attributes are not applied: the picture appears uncropped. */
160
+ export function unwrapVmlImages(html) {
161
+ if (!/<v:imagedata\b/i.test(html))
162
+ return html;
163
+ /** The <img> Word withheld, or null when it did supply one (recognised by its src)
164
+ * and the shape is therefore only the duplicate description of the same picture.
165
+ * `sizing` is whatever markup the shape's style attribute can be read from. */
166
+ const imgFor = (imagedata, sizing) => {
167
+ const src = attrOf(imagedata, 'src');
168
+ if (!src)
169
+ return null;
170
+ const quoted = src.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
171
+ if (new RegExp('<img\\b[^>]*\\bsrc\\s*=\\s*["\']?' + quoted, 'i').test(html))
172
+ return null;
173
+ const style = (sizing.match(/<v:shape\b[^>]*\sstyle\s*=\s*(?:"([^"]*)"|'([^']*)')/i) || []).slice(1).find(Boolean) || '';
174
+ const w = cssPx((style.match(/(?:^|;)\s*width\s*:\s*([^;]+)/i) || [])[1] || '');
175
+ const h = cssPx((style.match(/(?:^|;)\s*height\s*:\s*([^;]+)/i) || [])[1] || '');
176
+ return ('<img src="' +
177
+ src.replace(/"/g, '&quot;') +
178
+ '"' +
179
+ (w ? ' width="' + w + '"' : '') +
180
+ (h ? ' height="' + h + '"' : '') +
181
+ '>');
182
+ };
183
+ /* Downlevel-hidden shape: an <img> put inside would stay inside a comment and never
184
+ reach the DOM, so the whole block has to go. */
185
+ let out = html.replace(/<!--\[if [^\]]*\]>([\s\S]*?)<!\[endif\]-->/gi, (block, inner) => {
186
+ const data = inner.match(/<v:imagedata\b[^>]*>/i);
187
+ return (data && imgFor(data[0], inner)) || block;
188
+ });
189
+ /* Live shape: with RelyOnVML on, Word writes the shape into the document itself
190
+ (bare, or inside a downlevel-revealed <![if gte vml 1]> that the parser drops),
191
+ counting on the v\:*{behavior:url(#default#VML)} rule it ships in <head>. */
192
+ out = out.replace(/<v:shape\b[^>]*>[\s\S]*?<\/v:shape\s*>/gi, (shape) => {
193
+ const data = shape.match(/<v:imagedata\b[^>]*>/i);
194
+ return (data && imgFor(data[0], shape)) || shape;
195
+ });
196
+ /* An imagedata with no shape left to take its size from. */
197
+ return out.replace(/<v:imagedata\b[^>]*>/gi, (data) => imgFor(data, '') || data);
198
+ }
130
199
  /** Rewrites unusable <img src> values in raw pasted HTML with the pictures given, in
131
200
  * document order. Images that already have a usable src are left alone and do not
132
201
  * consume a slot, so a mixed paste (webmail image + Word image) stays aligned.
@@ -136,7 +205,7 @@ export function injectImages(html, imgs) {
136
205
  return { html, injected: [] };
137
206
  const injected = [];
138
207
  let next = 0;
139
- const out = html.replace(/<img\b[^>]*>/gi, (tag) => {
208
+ const out = unwrapVmlImages(html).replace(/<img\b[^>]*>/gi, (tag) => {
140
209
  const src = (tag.match(/\ssrc\s*=\s*["']?([^"'\s>]+)/i) || [])[1] || '';
141
210
  if (USABLE_SRC.test(src))
142
211
  return tag;
@@ -186,4 +255,4 @@ export function dataUrlToFile(dataUrl, baseName) {
186
255
  return null;
187
256
  }
188
257
  }
189
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29yZC1pbWFnZS1wYXN0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb3JlL3dvcmQtaW1hZ2UtcGFzdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs4RUFTOEU7QUFNOUU7OzZEQUU2RDtBQUM3RCxNQUFNLGVBQWUsR0FBRyxFQUFFLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQUV6QyxNQUFNLFVBQVUsR0FBRyxnQ0FBZ0MsQ0FBQztBQUVwRDs7bUZBRW1GO0FBQ25GLFNBQVMsVUFBVSxDQUFDLEdBQVcsRUFBRSxPQUFlO0lBQzlDLE1BQU0sR0FBRyxHQUFtRCxFQUFFLENBQUM7SUFDL0QsTUFBTSxNQUFNLEdBQUcsS0FBSyxHQUFHLE9BQU8sQ0FBQztJQUMvQixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDVixPQUFPLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUMzQzsyQ0FDbUM7UUFDbkMsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDckMsSUFBSSxLQUFLLElBQUksV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3JDLENBQUMsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDO1lBQ25CLFNBQVM7UUFDWCxDQUFDO1FBQ0QsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQ2QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ1YsT0FBTyxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQzNCLE1BQU0sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNqQixJQUFJLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FB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LENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbEUsT0FBTyxJQUFJLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUFFLFFBQVEsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDNUYsQ0FBQztJQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDWCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogUmVjb3ZlcnMgdGhlIHBpY3R1cmVzIHRoYXQgZGVza3RvcCBXb3JkIGxlYXZlcyBvdXQgb2YgdGhlIEhUTUwgY2xpcGJvYXJkIGZsYXZvci5cbiAgIFdvcmQgd3JpdGVzIDxpbWcgc3JjPVwiZmlsZTovLy/igKYvbXNvaHRtbGNsaXAxLzAxL2NsaXBfaW1hZ2UwMDEucG5nXCI+IOKAlCBhIGxvY2FsIHRlbXBcbiAgIGZpbGUgdGhlIGJyb3dzZXIgY2Fubm90IHJlYWQg4oCUIGJ1dCB0aGUgc2FtZSBwYXN0ZSBhbHNvIGNhcnJpZXMgYSB0ZXh0L3J0ZiBmbGF2b3JcbiAgIHdpdGggZXZlcnkgcGljdHVyZSBlbWJlZGRlZCBhcyBoZXggaW5zaWRlIGEge1xccGljdH0gZ3JvdXAuIFBhaXJpbmcgdGhlIHR3byBpcyBob3dcbiAgIFRpbnlNQ0UgUG93ZXJQYXN0ZSBpbXBsZW1lbnRzIHBvd2VycGFzdGVfYWxsb3dfbG9jYWxfaW1hZ2VzLlxuXG4gICBUaGlzIHJ1bnMgb24gdGhlIFJBVyBodG1sIHN0cmluZyBCRUZPUkUgY2xlYW5QYXN0ZWRIVE1MKCkgc2VlcyBpdDogdGhlIHBhc3RlIGVuZ2luZVxuICAgYWxyZWFkeSBhbGxvd3MgZGF0YTogVVJJcywgc28gaXQgbmVlZHMgbm8gY2hhbmdlIGFuZCBpdHMgYmVoYXZpb3VyIGlzIHVuYWZmZWN0ZWQuXG4gICBBbnl0aGluZyB0aGlzIG1vZHVsZSBjYW5ub3QgcmVjb3ZlciBpcyBsZWZ0IGV4YWN0bHkgYXMgaXQgd2FzLCBhbmQgc3RpbGwgZW5kcyB1cCBvblxuICAgdGhlIGVuZ2luZSdzIGV4aXN0aW5nIFwiW2xvY2FsIGltYWdlIOKAlCBwYXN0ZSBpdCBzZXBhcmF0ZWx5XVwiIHBsYWNlaG9sZGVyLiAqL1xuXG4vKiogRGVjb2RlZCBwaWN0dXJlcyBpbiBkb2N1bWVudCBvcmRlci4gQSBzbG90IGlzIG51bGwgd2hlbiB0aGUgcGljdHVyZSBleGlzdHMgYnV0XG4gKiAgY2Fubm90IGJlIHR1cm5lZCBpbnRvIHNvbWV0aGluZyB0aGUgYnJvd3NlciBjYW4gc2hvdyAoYSB0cnVlIHZlY3RvciBtZXRhZmlsZSkuICovXG5leHBvcnQgdHlwZSBSdGZJbWFnZXMgPSAoc3RyaW5nIHwgbnVsbClbXTtcblxuLyoqIFRvdGFsIGRlY29kZWQgYnl0ZXMgd2UgYXJlIHdpbGxpbmcgdG8gaW5saW5lIGZyb20gb25lIHBhc3RlLiBBIFdvcmQgZG9jdW1lbnQgZnVsbFxuICogIG9mIGZ1bGwtcGFnZSBzY3JlZW5zaG90cyBjYW4gcnVuIHRvIHRlbnMgb2YgTUI7IHBhc3QgdGhpcyB3ZSBsZWF2ZSB0aGUgcGxhY2Vob2xkZXJzXG4gKiAgcmF0aGVyIHRoYW4gZnJlZXplIHRoZSBlZGl0b3IgYnVpbGRpbmcgYmFzZTY0IHN0cmluZ3MuICovXG5jb25zdCBNQVhfVE9UQUxfQllURVMgPSAxMCAqIDEwMjQgKiAxMDI0O1xuXG5jb25zdCBVU0FCTEVfU1JDID0gL14oaHR0cHM/OnxkYXRhOmltYWdlXFwvfGJsb2I6KS9pO1xuXG4vKiogU2NhbnMgZm9yIGB7XFxrZXl3b3JkIOKApn1gIGdyb3VwcywgdHJhY2tpbmcgYnJhY2UgZGVwdGggc28gbmVzdGVkIGdyb3VwcyBzdWNoIGFzXG4gKiAgYHtcXCpcXHBpY3Byb3Ag4oCmfWAgaW5zaWRlIGEgcGljdHVyZSBkbyBub3QgdGVybWluYXRlIHRoZSBtYXRjaCBlYXJseSAoYSBsYXp5XG4gKiAgYC9cXHtcXFxccGljdFtcXHNcXFNdKj9cXH0vYCByZWdleCBnZXRzIHRoaXMgd3JvbmcgYW5kIHRydW5jYXRlcyB0aGUgaGV4IHBheWxvYWQpLiAqL1xuZnVuY3Rpb24gZmluZEdyb3VwcyhydGY6IHN0cmluZywga2V5d29yZDogc3RyaW5nKTogeyBzdGFydDogbnVtYmVyOyBlbmQ6IG51bWJlcjsgYm9keTogc3RyaW5nIH1bXSB7XG4gIGNvbnN0IG91dDogeyBzdGFydDogbnVtYmVyOyBlbmQ6IG51bWJlcjsgYm9keTogc3RyaW5nIH1bXSA9IFtdO1xuICBjb25zdCBuZWVkbGUgPSAne1xcXFwnICsga2V5d29yZDtcbiAgbGV0IGkgPSAwO1xuICB3aGlsZSAoKGkgPSBydGYuaW5kZXhPZihuZWVkbGUsIGkpKSAhPT0gLTEpIHtcbiAgICAvKiB0aGUgY2hhciBhZnRlciB0aGUgY29udHJvbCB3b3JkIG11c3QgYmUgYSBkZWxpbWl0ZXIsIHNvIFxccGljdCBkb2VzIG5vdCBhbHNvXG4gICAgICAgbWF0Y2ggXFxwaWN0c2NhbGV4IGFuZCBmcmllbmRzICovXG4gICAgY29uc3QgYWZ0ZXIgPSBydGZbaSArIG5lZWRsZS5sZW5ndGhdO1xuICAgIGlmIChhZnRlciAmJiAvW2EtejAtOV0vaS50ZXN0KGFmdGVyKSkge1xuICAgICAgaSArPSBuZWVkbGUubGVuZ3RoO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGxldCBkZXB0aCA9IDA7XG4gICAgbGV0IGogPSBpO1xuICAgIGZvciAoOyBqIDwgcnRmLmxlbmd0aDsgaisrKSB7XG4gICAgICBjb25zdCBjID0gcnRmW2pdO1xuICAgICAgaWYgKGMgPT09ICdcXFxcJykge1xuICAgICAgICBqKys7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKGMgPT09ICd7JykgZGVwdGgrKztcbiAgICAgIGVsc2UgaWYgKGMgPT09ICd9Jykge1xuICAgICAgICBkZXB0aC0tO1xuICAgICAgICBpZiAoIWRlcHRoKSBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgb3V0LnB1c2goeyBzdGFydDogaSwgZW5kOiBqICsgMSwgYm9keTogcnRmLnNsaWNlKGkgKyBuZWVkbGUubGVuZ3RoLCBqKSB9KTtcbiAgICBpID0gaiArIDE7XG4gIH1cbiAgcmV0dXJuIG91dDtcbn1cblxuZnVuY3Rpb24gaGV4VG9CeXRlcyhoZXg6IHN0cmluZyk6IFVpbnQ4QXJyYXkge1xuICBjb25zdCBieXRlcyA9IG5ldyBVaW50OEFycmF5KGhleC5sZW5ndGggLyAyKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkrKykgYnl0ZXNbaV0gPSBwYXJzZUludChoZXguc3Vic3RyKGkgKiAyLCAyKSwgMTYpO1xuICByZXR1cm4gYnl0ZXM7XG59XG5cbmZ1bmN0aW9uIHRvQmFzZTY0KGJ5dGVzOiBVaW50OEFycmF5KTogc3RyaW5nIHtcbiAgbGV0IGJpbiA9ICcnO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSsrKSBiaW4gKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSk7XG4gIHJldHVybiBidG9hKGJpbik7XG59XG5cbmZ1bmN0aW9uIGluZGV4T2ZTaWcoYnl0ZXM6IFVpbnQ4QXJyYXksIHNpZzogbnVtYmVyW10pOiBudW1iZXIge1xuICBvdXRlcjogZm9yIChsZXQgaSA9IDA7IGkgKyBzaWcubGVuZ3RoIDw9IGJ5dGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCBzaWcubGVuZ3RoOyBqKyspIGlmIChieXRlc1tpICsgal0gIT09IHNpZ1tqXSkgY29udGludWUgb3V0ZXI7XG4gICAgcmV0dXJuIGk7XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuXG5jb25zdCBQTkdfU0lHID0gWzB4ODksIDB4NTAsIDB4NGUsIDB4NDddO1xuY29uc3QgSlBHX1NJRyA9IFsweGZmLCAweGQ4LCAweGZmXTtcblxuZnVuY3Rpb24gZGVjb2RlUGljdChib2R5OiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsIHtcbiAgbGV0IGtpbmQ6ICdpbWFnZS9wbmcnIHwgJ2ltYWdlL2pwZWcnIHwgJ21ldGFmaWxlJyB8IG51bGwgPSBudWxsO1xuICBpZiAoL1xcXFxwbmdibGlwLy50ZXN0KGJvZHkpKSBraW5kID0gJ2ltYWdlL3BuZyc7XG4gIGVsc2UgaWYgKC9cXFxcanBlZ2JsaXAvLnRlc3QoYm9keSkpIGtpbmQgPSAnaW1hZ2UvanBlZyc7XG4gIGVsc2UgaWYgKC9cXFxcd21ldGFmaWxlXFxkKi8udGVzdChib2R5KSB8fCAvXFxcXGVtZmJsaXAvLnRlc3QoYm9keSkpIGtpbmQgPSAnbWV0YWZpbGUnO1xuICBpZiAoIWtpbmQpIHJldHVybiBudWxsO1xuXG4gIGxldCBoZXggPSBib2R5XG4gICAgLnJlcGxhY2UoL1xce1tee31dKlxcfS9nLCAnJykgLy8gbmVzdGVkIHByb3BlcnR5IGdyb3Vwc1xuICAgIC5yZXBsYWNlKC9cXFxcW2Etel0rLT9cXGQqXFxzPy9naSwgJycpIC8vIGNvbnRyb2wgd29yZHNcbiAgICAucmVwbGFjZSgvW14wLTlhLWZBLUZdL2csICcnKTtcbiAgaWYgKGhleC5sZW5ndGggJSAyKSBoZXggPSBoZXguc2xpY2UoMCwgLTEpO1xuICBpZiAoIWhleCkgcmV0dXJuIG51bGw7XG5cbiAgY29uc3QgYnl0ZXMgPSBoZXhUb0J5dGVzKGhleCk7XG4gIGlmIChraW5kID09PSAnbWV0YWZpbGUnKSB7XG4gICAgLyogV29yZCB3cmFwcyBhIGJpdG1hcCBpbiBhIG1ldGFmaWxlIGZvciBjb21wYXRpYmlsaXR5OyB3aGVuIHRoZXJlIGlzIGEgcmVhbFxuICAgICAgIFBORy9KUEVHIGluc2lkZSB3ZSBjYW4gdXNlIGl0LiBBIGdlbnVpbmUgdmVjdG9yIG1ldGFmaWxlIHdlIGNhbm5vdCByZW5kZXIuICovXG4gICAgY29uc3QgcG5nID0gaW5kZXhPZlNpZyhieXRlcywgUE5HX1NJRyk7XG4gICAgaWYgKHBuZyA+PSAwKSByZXR1cm4gJ2RhdGE6aW1hZ2UvcG5nO2Jhc2U2NCwnICsgdG9CYXNlNjQoYnl0ZXMuc2xpY2UocG5nKSk7XG4gICAgY29uc3QganBnID0gaW5kZXhPZlNpZyhieXRlcywgSlBHX1NJRyk7XG4gICAgaWYgKGpwZyA+PSAwKSByZXR1cm4gJ2RhdGE6aW1hZ2UvanBlZztiYXNlNjQsJyArIHRvQmFzZTY0KGJ5dGVzLnNsaWNlKGpwZykpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiAnZGF0YTonICsga2luZCArICc7YmFzZTY0LCcgKyB0b0Jhc2U2NChieXRlcyk7XG59XG5cbi8qKiBFdmVyeSBwaWN0dXJlIGluIHRoZSBSVEYgZmxhdm9yLCBpbiBkb2N1bWVudCBvcmRlci4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0UnRmSW1hZ2VzKHJ0Zjogc3RyaW5nKTogUnRmSW1hZ2VzIHtcbiAgaWYgKCFydGYgfHwgcnRmLmluZGV4T2YoJ1xcXFxwaWN0JykgPT09IC0xKSByZXR1cm4gW107XG4gIC8qIFdvcmQgZW1pdHMge1xcKlxcc2hwcGljdHtcXHBpY3Qg4oCmfX17XFxub25zaHBwaWN0e1xccGljdCDigKZ9fSDigJQgdGhlIHNlY29uZCBncm91cCBpcyBhXG4gICAgIGxlZ2FjeSBkdXBsaWNhdGUgb2YgdGhlIGZpcnN0LiBEcm9wcGluZyBpdCBrZWVwcyBwaWN0dXJlIG9yZGVyIGFsaWduZWQgd2l0aCB0aGVcbiAgICAgPGltZz4gdGFncyBpbiB0aGUgSFRNTCBmbGF2b3IuICovXG4gIGxldCBjbGVhbmVkID0gcnRmO1xuICBmaW5kR3JvdXBzKHJ0ZiwgJ25vbnNocHBpY3QnKVxuICAgIC5yZXZlcnNlKClcbiAgICAuZm9yRWFjaCgoZykgPT4ge1xuICAgICAgY2xlYW5lZCA9IGNsZWFuZWQuc2xpY2UoMCwgZy5zdGFydCkgKyBjbGVhbmVkLnNsaWNlKGcuZW5kKTtcbiAgICB9KTtcblxuICBsZXQgYnVkZ2V0ID0gTUFYX1RPVEFMX0JZVEVTO1xuICByZXR1cm4gZmluZEdyb3VwcyhjbGVhbmVkLCAncGljdCcpLm1hcCgoZykgPT4ge1xuICAgIGlmIChidWRnZXQgPD0gMCkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgZGF0YSA9IGRlY29kZVBpY3QoZy5ib2R5KTtcbiAgICBpZiAoZGF0YSkgYnVkZ2V0IC09IGRhdGEubGVuZ3RoICogMC43NTsgLy8gYmFzZTY0IC0+IGFwcHJveGltYXRlIGJ5dGUgY291bnRcbiAgICByZXR1cm4gZGF0YTtcbiAgfSk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5qZWN0UmVzdWx0IHtcbiAgaHRtbDogc3RyaW5nO1xuICAvKiogVGhlIGRhdGEgVVJJcyB0aGlzIGNhbGwgcHV0IGludG8gdGhlIEhUTUwsIGluIHRoZSBvcmRlciB0aGV5IHdlcmUgdXNlZC4gT25seVxuICAgKiAgdGhlc2UgYXJlIGNhbmRpZGF0ZXMgZm9yIHRoZSBob3N0J3MgaW1hZ2VVcGxvYWRIYW5kbGVyIOKAlCBkYXRhIFVSSXMgdGhhdCB3ZXJlXG4gICAqICBhbHJlYWR5IGluIHRoZSBwYXN0ZWQgSFRNTCBhcmUgbGVmdCBhbG9uZSwgc28gZXhpc3RpbmcgcGFzdGUgYmVoYXZpb3VyIGlzXG4gICAqICB1bmNoYW5nZWQuICovXG4gIGluamVjdGVkOiBzdHJpbmdbXTtcbn1cblxuLyoqIFJld3JpdGVzIHVudXNhYmxlIDxpbWcgc3JjPiB2YWx1ZXMgaW4gcmF3IHBhc3RlZCBIVE1MIHdpdGggdGhlIHBpY3R1cmVzIGdpdmVuLCBpblxuICogIGRvY3VtZW50IG9yZGVyLiBJbWFnZXMgdGhhdCBhbHJlYWR5IGhhdmUgYSB1c2FibGUgc3JjIGFyZSBsZWZ0IGFsb25lIGFuZCBkbyBub3RcbiAqICBjb25zdW1lIGEgc2xvdCwgc28gYSBtaXhlZCBwYXN0ZSAod2VibWFpbCBpbWFnZSArIFdvcmQgaW1hZ2UpIHN0YXlzIGFsaWduZWQuXG4gKiAgQW55dGhpbmcgd2l0aG91dCBhIG1hdGNoaW5nIHBpY3R1cmUga2VlcHMgaXRzIG9yaWdpbmFsIHRhZy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbmplY3RJbWFnZXMoaHRtbDogc3RyaW5nLCBpbWdzOiBSdGZJbWFnZXMpOiBJbmplY3RSZXN1bHQge1xuICBpZiAoIWh0bWwgfHwgIWltZ3MubGVuZ3RoKSByZXR1cm4geyBodG1sLCBpbmplY3RlZDogW10gfTtcbiAgY29uc3QgaW5qZWN0ZWQ6IHN0cmluZ1tdID0gW107XG4gIGxldCBuZXh0ID0gMDtcbiAgY29uc3Qgb3V0ID0gaHRtbC5yZXBsYWNlKC88aW1nXFxiW14+XSo+L2dpLCAodGFnKSA9PiB7XG4gICAgY29uc3Qgc3JjID0gKHRhZy5tYXRjaCgvXFxzc3JjXFxzKj1cXHMqW1wiJ10/KFteXCInXFxzPl0rKS9pKSB8fCBbXSlbMV0gfHwgJyc7XG4gICAgaWYgKFVTQUJMRV9TUkMudGVzdChzcmMpKSByZXR1cm4gdGFnO1xuICAgIGNvbnN0IGRhdGEgPSBpbWdzW25leHQrK107XG4gICAgaWYgKCFkYXRhKSByZXR1cm4gdGFnO1xuICAgIGluamVjdGVkLnB1c2goZGF0YSk7XG4gICAgcmV0dXJuIC9cXHNzcmNcXHMqPVxccypbXCInXS9pLnRlc3QodGFnKVxuICAgICAgPyB0YWcucmVwbGFjZSgvKFxcc3NyY1xccyo9XFxzKikoW1wiJ10pW15cIiddKlxcMi9pLCAnJDFcIicgKyBkYXRhICsgJ1wiJylcbiAgICAgIDogdGFnLnJlcGxhY2UoLyhcXHNzcmNcXHMqPVxccyopW15cXHM+XSsvaSwgJyQxXCInICsgZGF0YSArICdcIicpO1xuICB9KTtcbiAgcmV0dXJuIHsgaHRtbDogb3V0LCBpbmplY3RlZCB9O1xufVxuXG4vKiogUGFpcnMgdGhlIEhUTUwgZmxhdm9yIG9mIGEgV29yZCBwYXN0ZSB3aXRoIHRoZSBwaWN0dXJlcyBpbiBpdHMgUlRGIGZsYXZvci4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbmplY3RSdGZJbWFnZXMoaHRtbDogc3RyaW5nLCBydGY6IHN0cmluZyk6IEluamVjdFJlc3VsdCB7XG4gIGlmICghaHRtbCB8fCAhcnRmKSByZXR1cm4geyBodG1sLCBpbmplY3RlZDogW10gfTtcbiAgcmV0dXJuIGluamVjdEltYWdlcyhodG1sLCBleHRyYWN0UnRmSW1hZ2VzKHJ0ZikpO1xufVxuXG4vKiogVHJ1ZSB3aGVuIHRoZSBjbGVhbmVkIEhUTUwgc3RpbGwgaG9sZHMgaW1hZ2VzIHRoZSBlbmdpbmUgY291bGQgbm90IHJlc29sdmUg4oCUIHVzZWRcbiAqICB0byBkZWNpZGUgd2hldGhlciBhIGJpdG1hcCBzaXR0aW5nIGluIHRoZSBjbGlwYm9hcmQgaXMgd29ydGggZmFsbGluZyBiYWNrIHRvLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvdW50VW5yZXNvbHZlZEltYWdlcyhodG1sOiBzdHJpbmcpOiBudW1iZXIge1xuICBjb25zdCB0YWdzID0gaHRtbC5tYXRjaCgvPGltZ1xcYltePl0qPi9naSk7XG4gIGlmICghdGFncykgcmV0dXJuIDA7XG4gIHJldHVybiB0YWdzLmZpbHRlcigodGFnKSA9PiB7XG4gICAgY29uc3Qgc3JjID0gKHRhZy5tYXRjaCgvXFxzc3JjXFxzKj1cXHMqW1wiJ10/KFteXCInXFxzPl0rKS9pKSB8fCBbXSlbMV0gfHwgJyc7XG4gICAgcmV0dXJuICFVU0FCTEVfU1JDLnRlc3Qoc3JjKTtcbiAgfSkubGVuZ3RoO1xufVxuXG4vKiogZGF0YTogVVJJIC0+IEZpbGUsIHNvIHJlY292ZXJlZCBwaWN0dXJlcyBjYW4gZ28gdGhyb3VnaCB0aGUgaG9zdCdzXG4gKiAgaW1hZ2VVcGxvYWRIYW5kbGVyIGV4YWN0bHkgbGlrZSBhIHBpY2tlZCBmaWxlIGRvZXMuIGBiYXNlTmFtZWAgZ2V0cyB0aGUgZXh0ZW5zaW9uXG4gKiAgdGhhdCBtYXRjaGVzIHRoZSBVUkkncyBNSU1FIHR5cGUuICovXG5leHBvcnQgZnVuY3Rpb24gZGF0YVVybFRvRmlsZShkYXRhVXJsOiBzdHJpbmcsIGJhc2VOYW1lOiBzdHJpbmcpOiBGaWxlIHwgbnVsbCB7XG4gIGNvbnN0IG0gPSBkYXRhVXJsLm1hdGNoKC9eZGF0YTooW147LF0rKTtiYXNlNjQsKC4qKSQvKTtcbiAgaWYgKCFtKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgZXh0ID0gKG1bMV0uc3BsaXQoJy8nKVsxXSB8fCAncG5nJykucmVwbGFjZSgvW15hLXowLTldL2dpLCAnJykgfHwgJ3BuZyc7XG4gIHRyeSB7XG4gICAgY29uc3QgYmluID0gYXRvYihtWzJdKTtcbiAgICBjb25zdCBieXRlcyA9IG5ldyBVaW50OEFycmF5KGJpbi5sZW5ndGgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYmluLmxlbmd0aDsgaSsrKSBieXRlc1tpXSA9IGJpbi5jaGFyQ29kZUF0KGkpO1xuICAgIHJldHVybiBuZXcgRmlsZShbYnl0ZXNdLCBiYXNlTmFtZSArICcuJyArIChleHQgPT09ICdqcGVnJyA/ICdqcGcnIDogZXh0KSwgeyB0eXBlOiBtWzFdIH0pO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cbiJdfQ==
258
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29yZC1pbWFnZS1wYXN0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb3JlL3dvcmQtaW1hZ2UtcGFzdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs4RUFTOEU7QUFNOUU7OzZEQUU2RDtBQUM3RCxNQUFNLGVBQWUsR0FBRyxFQUFFLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQUV6QyxNQUFNLFVBQVUsR0FBRyxnQ0FBZ0MsQ0FBQztBQUVwRDs7bUZBRW1GO0FBQ25GLFNBQVMsVUFBVSxDQUFDLEdBQVcsRUFBRSxPQUFlO0lBQzlDLE1BQU0sR0FBRyxHQUFtRCxFQUFFLENBQUM7SUFDL0QsTUFBTSxNQUFNLEdBQUcsS0FBSyxHQUFHLE9BQU8sQ0FBQztJQUMvQixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDVixPQUFPLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUMzQzsyQ0FDbUM7UUFDbkMsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDckMsSUFBSSxLQUFLLElBQUksV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3JDLENBQUMsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDO1lBQ25CLFNBQVM7UUFDWCxDQUFDO1FBQ0QsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQ2QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ1YsT0FBTyxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQzNCLE1BQU0sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNqQixJQUFJLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FB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LENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3pDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRTtZQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xFLE9BQU8sSUFBSSxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxRQUFRLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzVGLENBQUM7SUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ1gsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIFJlY292ZXJzIHRoZSBwaWN0dXJlcyB0aGF0IGRlc2t0b3AgV29yZCBsZWF2ZXMgb3V0IG9mIHRoZSBIVE1MIGNsaXBib2FyZCBmbGF2b3IuXG4gICBXb3JkIHdyaXRlcyA8aW1nIHNyYz1cImZpbGU6Ly8v4oCmL21zb2h0bWxjbGlwMS8wMS9jbGlwX2ltYWdlMDAxLnBuZ1wiPiDigJQgYSBsb2NhbCB0ZW1wXG4gICBmaWxlIHRoZSBicm93c2VyIGNhbm5vdCByZWFkIOKAlCBidXQgdGhlIHNhbWUgcGFzdGUgYWxzbyBjYXJyaWVzIGEgdGV4dC9ydGYgZmxhdm9yXG4gICB3aXRoIGV2ZXJ5IHBpY3R1cmUgZW1iZWRkZWQgYXMgaGV4IGluc2lkZSBhIHtcXHBpY3R9IGdyb3VwLiBQYWlyaW5nIHRoZSB0d28gaXMgaG93XG4gICBUaW55TUNFIFBvd2VyUGFzdGUgaW1wbGVtZW50cyBwb3dlcnBhc3RlX2FsbG93X2xvY2FsX2ltYWdlcy5cblxuICAgVGhpcyBydW5zIG9uIHRoZSBSQVcgaHRtbCBzdHJpbmcgQkVGT1JFIGNsZWFuUGFzdGVkSFRNTCgpIHNlZXMgaXQ6IHRoZSBwYXN0ZSBlbmdpbmVcbiAgIGFscmVhZHkgYWxsb3dzIGRhdGE6IFVSSXMsIHNvIGl0IG5lZWRzIG5vIGNoYW5nZSBhbmQgaXRzIGJlaGF2aW91ciBpcyB1bmFmZmVjdGVkLlxuICAgQW55dGhpbmcgdGhpcyBtb2R1bGUgY2Fubm90IHJlY292ZXIgaXMgbGVmdCBleGFjdGx5IGFzIGl0IHdhcywgYW5kIHN0aWxsIGVuZHMgdXAgb25cbiAgIHRoZSBlbmdpbmUncyBleGlzdGluZyBcIltsb2NhbCBpbWFnZSDigJQgcGFzdGUgaXQgc2VwYXJhdGVseV1cIiBwbGFjZWhvbGRlci4gKi9cblxuLyoqIERlY29kZWQgcGljdHVyZXMgaW4gZG9jdW1lbnQgb3JkZXIuIEEgc2xvdCBpcyBudWxsIHdoZW4gdGhlIHBpY3R1cmUgZXhpc3RzIGJ1dFxuICogIGNhbm5vdCBiZSB0dXJuZWQgaW50byBzb21ldGhpbmcgdGhlIGJyb3dzZXIgY2FuIHNob3cgKGEgdHJ1ZSB2ZWN0b3IgbWV0YWZpbGUpLiAqL1xuZXhwb3J0IHR5cGUgUnRmSW1hZ2VzID0gKHN0cmluZyB8IG51bGwpW107XG5cbi8qKiBUb3RhbCBkZWNvZGVkIGJ5dGVzIHdlIGFyZSB3aWxsaW5nIHRvIGlubGluZSBmcm9tIG9uZSBwYXN0ZS4gQSBXb3JkIGRvY3VtZW50IGZ1bGxcbiAqICBvZiBmdWxsLXBhZ2Ugc2NyZWVuc2hvdHMgY2FuIHJ1biB0byB0ZW5zIG9mIE1COyBwYXN0IHRoaXMgd2UgbGVhdmUgdGhlIHBsYWNlaG9sZGVyc1xuICogIHJhdGhlciB0aGFuIGZyZWV6ZSB0aGUgZWRpdG9yIGJ1aWxkaW5nIGJhc2U2NCBzdHJpbmdzLiAqL1xuY29uc3QgTUFYX1RPVEFMX0JZVEVTID0gMTAgKiAxMDI0ICogMTAyNDtcblxuY29uc3QgVVNBQkxFX1NSQyA9IC9eKGh0dHBzPzp8ZGF0YTppbWFnZVxcL3xibG9iOikvaTtcblxuLyoqIFNjYW5zIGZvciBge1xca2V5d29yZCDigKZ9YCBncm91cHMsIHRyYWNraW5nIGJyYWNlIGRlcHRoIHNvIG5lc3RlZCBncm91cHMgc3VjaCBhc1xuICogIGB7XFwqXFxwaWNwcm9wIOKApn1gIGluc2lkZSBhIHBpY3R1cmUgZG8gbm90IHRlcm1pbmF0ZSB0aGUgbWF0Y2ggZWFybHkgKGEgbGF6eVxuICogIGAvXFx7XFxcXHBpY3RbXFxzXFxTXSo/XFx9L2AgcmVnZXggZ2V0cyB0aGlzIHdyb25nIGFuZCB0cnVuY2F0ZXMgdGhlIGhleCBwYXlsb2FkKS4gKi9cbmZ1bmN0aW9uIGZpbmRHcm91cHMocnRmOiBzdHJpbmcsIGtleXdvcmQ6IHN0cmluZyk6IHsgc3RhcnQ6IG51bWJlcjsgZW5kOiBudW1iZXI7IGJvZHk6IHN0cmluZyB9W10ge1xuICBjb25zdCBvdXQ6IHsgc3RhcnQ6IG51bWJlcjsgZW5kOiBudW1iZXI7IGJvZHk6IHN0cmluZyB9W10gPSBbXTtcbiAgY29uc3QgbmVlZGxlID0gJ3tcXFxcJyArIGtleXdvcmQ7XG4gIGxldCBpID0gMDtcbiAgd2hpbGUgKChpID0gcnRmLmluZGV4T2YobmVlZGxlLCBpKSkgIT09IC0xKSB7XG4gICAgLyogdGhlIGNoYXIgYWZ0ZXIgdGhlIGNvbnRyb2wgd29yZCBtdXN0IGJlIGEgZGVsaW1pdGVyLCBzbyBcXHBpY3QgZG9lcyBub3QgYWxzb1xuICAgICAgIG1hdGNoIFxccGljdHNjYWxleCBhbmQgZnJpZW5kcyAqL1xuICAgIGNvbnN0IGFmdGVyID0gcnRmW2kgKyBuZWVkbGUubGVuZ3RoXTtcbiAgICBpZiAoYWZ0ZXIgJiYgL1thLXowLTldL2kudGVzdChhZnRlcikpIHtcbiAgICAgIGkgKz0gbmVlZGxlLmxlbmd0aDtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBsZXQgZGVwdGggPSAwO1xuICAgIGxldCBqID0gaTtcbiAgICBmb3IgKDsgaiA8IHJ0Zi5sZW5ndGg7IGorKykge1xuICAgICAgY29uc3QgYyA9IHJ0ZltqXTtcbiAgICAgIGlmIChjID09PSAnXFxcXCcpIHtcbiAgICAgICAgaisrO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChjID09PSAneycpIGRlcHRoKys7XG4gICAgICBlbHNlIGlmIChjID09PSAnfScpIHtcbiAgICAgICAgZGVwdGgtLTtcbiAgICAgICAgaWYgKCFkZXB0aCkgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIG91dC5wdXNoKHsgc3RhcnQ6IGksIGVuZDogaiArIDEsIGJvZHk6IHJ0Zi5zbGljZShpICsgbmVlZGxlLmxlbmd0aCwgaikgfSk7XG4gICAgaSA9IGogKyAxO1xuICB9XG4gIHJldHVybiBvdXQ7XG59XG5cbmZ1bmN0aW9uIGhleFRvQnl0ZXMoaGV4OiBzdHJpbmcpOiBVaW50OEFycmF5IHtcbiAgY29uc3QgYnl0ZXMgPSBuZXcgVWludDhBcnJheShoZXgubGVuZ3RoIC8gMik7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpKyspIGJ5dGVzW2ldID0gcGFyc2VJbnQoaGV4LnN1YnN0cihpICogMiwgMiksIDE2KTtcbiAgcmV0dXJuIGJ5dGVzO1xufVxuXG5mdW5jdGlvbiB0b0Jhc2U2NChieXRlczogVWludDhBcnJheSk6IHN0cmluZyB7XG4gIGxldCBiaW4gPSAnJztcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkrKykgYmluICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0pO1xuICByZXR1cm4gYnRvYShiaW4pO1xufVxuXG5mdW5jdGlvbiBpbmRleE9mU2lnKGJ5dGVzOiBVaW50OEFycmF5LCBzaWc6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgb3V0ZXI6IGZvciAobGV0IGkgPSAwOyBpICsgc2lnLmxlbmd0aCA8PSBieXRlcy5sZW5ndGg7IGkrKykge1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgc2lnLmxlbmd0aDsgaisrKSBpZiAoYnl0ZXNbaSArIGpdICE9PSBzaWdbal0pIGNvbnRpbnVlIG91dGVyO1xuICAgIHJldHVybiBpO1xuICB9XG4gIHJldHVybiAtMTtcbn1cblxuY29uc3QgUE5HX1NJRyA9IFsweDg5LCAweDUwLCAweDRlLCAweDQ3XTtcbmNvbnN0IEpQR19TSUcgPSBbMHhmZiwgMHhkOCwgMHhmZl07XG5cbmZ1bmN0aW9uIGRlY29kZVBpY3QoYm9keTogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XG4gIGxldCBraW5kOiAnaW1hZ2UvcG5nJyB8ICdpbWFnZS9qcGVnJyB8ICdtZXRhZmlsZScgfCBudWxsID0gbnVsbDtcbiAgaWYgKC9cXFxccG5nYmxpcC8udGVzdChib2R5KSkga2luZCA9ICdpbWFnZS9wbmcnO1xuICBlbHNlIGlmICgvXFxcXGpwZWdibGlwLy50ZXN0KGJvZHkpKSBraW5kID0gJ2ltYWdlL2pwZWcnO1xuICBlbHNlIGlmICgvXFxcXHdtZXRhZmlsZVxcZCovLnRlc3QoYm9keSkgfHwgL1xcXFxlbWZibGlwLy50ZXN0KGJvZHkpKSBraW5kID0gJ21ldGFmaWxlJztcbiAgaWYgKCFraW5kKSByZXR1cm4gbnVsbDtcblxuICAvKiBFYWNoIHJlbW92YWwgbGVhdmVzIGEgc3BhY2UgYmVoaW5kLiBEZWxldGluZyBvdXRyaWdodCB3b3VsZCBnbHVlIHdoYXQgc3Vycm91bmRlZFxuICAgICBpdCB0b2dldGhlciwgYW5kIFdvcmQgZW5kcyB0aGUgcGljdHVyZSBoZWFkZXIgd2l0aCBgXFxibGlwdGFnTntcXCpcXGJsaXB1aWQg4oCmfWBcbiAgICAgaGFyZCBhZ2FpbnN0IHRoZSBwYXlsb2FkOiBkcm9wcGluZyB0aGUgdWlkIGdyb3VwIHdvdWxkIGxldCB0aGUgXFxibGlwdGFnXG4gICAgIHBhcmFtZXRlcidzIGBcXGQqYCBydW4gc3RyYWlnaHQgb24gaW50byB0aGUgaGV4IGFuZCBlYXQgaXRzIGxlYWRpbmcgZGlnaXRzXG4gICAgICg4OTUwNGU0N+KApiAtPiBlNDcw4oCmKSwgd2hpY2ggc2lsZW50bHkgY29ycnVwdHMgZXZlcnkgcGljdHVyZSBXb3JkIHNlbmRzLiAqL1xuICBsZXQgaGV4ID0gYm9keVxuICAgIC5yZXBsYWNlKC9cXHtbXnt9XSpcXH0vZywgJyAnKSAvLyBuZXN0ZWQgcHJvcGVydHkgZ3JvdXBzXG4gICAgLnJlcGxhY2UoL1xcXFxbYS16XSstP1xcZCpcXHM/L2dpLCAnICcpIC8vIGNvbnRyb2wgd29yZHNcbiAgICAucmVwbGFjZSgvW14wLTlhLWZBLUZdL2csICcnKTtcbiAgaWYgKGhleC5sZW5ndGggJSAyKSBoZXggPSBoZXguc2xpY2UoMCwgLTEpO1xuICBpZiAoIWhleCkgcmV0dXJuIG51bGw7XG5cbiAgY29uc3QgYnl0ZXMgPSBoZXhUb0J5dGVzKGhleCk7XG4gIGlmIChraW5kID09PSAnbWV0YWZpbGUnKSB7XG4gICAgLyogV29yZCB3cmFwcyBhIGJpdG1hcCBpbiBhIG1ldGFmaWxlIGZvciBjb21wYXRpYmlsaXR5OyB3aGVuIHRoZXJlIGlzIGEgcmVhbFxuICAgICAgIFBORy9KUEVHIGluc2lkZSB3ZSBjYW4gdXNlIGl0LiBBIGdlbnVpbmUgdmVjdG9yIG1ldGFmaWxlIHdlIGNhbm5vdCByZW5kZXIuICovXG4gICAgY29uc3QgcG5nID0gaW5kZXhPZlNpZyhieXRlcywgUE5HX1NJRyk7XG4gICAgaWYgKHBuZyA+PSAwKSByZXR1cm4gJ2RhdGE6aW1hZ2UvcG5nO2Jhc2U2NCwnICsgdG9CYXNlNjQoYnl0ZXMuc2xpY2UocG5nKSk7XG4gICAgY29uc3QganBnID0gaW5kZXhPZlNpZyhieXRlcywgSlBHX1NJRyk7XG4gICAgaWYgKGpwZyA+PSAwKSByZXR1cm4gJ2RhdGE6aW1hZ2UvanBlZztiYXNlNjQsJyArIHRvQmFzZTY0KGJ5dGVzLnNsaWNlKGpwZykpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiAnZGF0YTonICsga2luZCArICc7YmFzZTY0LCcgKyB0b0Jhc2U2NChieXRlcyk7XG59XG5cbi8qKiBFdmVyeSBwaWN0dXJlIGluIHRoZSBSVEYgZmxhdm9yLCBpbiBkb2N1bWVudCBvcmRlci4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0UnRmSW1hZ2VzKHJ0Zjogc3RyaW5nKTogUnRmSW1hZ2VzIHtcbiAgaWYgKCFydGYgfHwgcnRmLmluZGV4T2YoJ1xcXFxwaWN0JykgPT09IC0xKSByZXR1cm4gW107XG4gIC8qIFdvcmQgZW1pdHMge1xcKlxcc2hwcGljdHtcXHBpY3Qg4oCmfX17XFxub25zaHBwaWN0e1xccGljdCDigKZ9fSDigJQgdGhlIHNlY29uZCBncm91cCBpcyBhXG4gICAgIGxlZ2FjeSBkdXBsaWNhdGUgb2YgdGhlIGZpcnN0LiBEcm9wcGluZyBpdCBrZWVwcyBwaWN0dXJlIG9yZGVyIGFsaWduZWQgd2l0aCB0aGVcbiAgICAgPGltZz4gdGFncyBpbiB0aGUgSFRNTCBmbGF2b3IuICovXG4gIGxldCBjbGVhbmVkID0gcnRmO1xuICBmaW5kR3JvdXBzKHJ0ZiwgJ25vbnNocHBpY3QnKVxuICAgIC5yZXZlcnNlKClcbiAgICAuZm9yRWFjaCgoZykgPT4ge1xuICAgICAgY2xlYW5lZCA9IGNsZWFuZWQuc2xpY2UoMCwgZy5zdGFydCkgKyBjbGVhbmVkLnNsaWNlKGcuZW5kKTtcbiAgICB9KTtcblxuICBsZXQgYnVkZ2V0ID0gTUFYX1RPVEFMX0JZVEVTO1xuICByZXR1cm4gZmluZEdyb3VwcyhjbGVhbmVkLCAncGljdCcpLm1hcCgoZykgPT4ge1xuICAgIGlmIChidWRnZXQgPD0gMCkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgZGF0YSA9IGRlY29kZVBpY3QoZy5ib2R5KTtcbiAgICBpZiAoZGF0YSkgYnVkZ2V0IC09IGRhdGEubGVuZ3RoICogMC43NTsgLy8gYmFzZTY0IC0+IGFwcHJveGltYXRlIGJ5dGUgY291bnRcbiAgICByZXR1cm4gZGF0YTtcbiAgfSk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5qZWN0UmVzdWx0IHtcbiAgaHRtbDogc3RyaW5nO1xuICAvKiogVGhlIGRhdGEgVVJJcyB0aGlzIGNhbGwgcHV0IGludG8gdGhlIEhUTUwsIGluIHRoZSBvcmRlciB0aGV5IHdlcmUgdXNlZC4gT25seVxuICAgKiAgdGhlc2UgYXJlIGNhbmRpZGF0ZXMgZm9yIHRoZSBob3N0J3MgaW1hZ2VVcGxvYWRIYW5kbGVyIOKAlCBkYXRhIFVSSXMgdGhhdCB3ZXJlXG4gICAqICBhbHJlYWR5IGluIHRoZSBwYXN0ZWQgSFRNTCBhcmUgbGVmdCBhbG9uZSwgc28gZXhpc3RpbmcgcGFzdGUgYmVoYXZpb3VyIGlzXG4gICAqICB1bmNoYW5nZWQuICovXG4gIGluamVjdGVkOiBzdHJpbmdbXTtcbn1cblxuLyoqIENTUyBsZW5ndGggLT4gcHgsIHNvIGEgVk1MIHNoYXBlJ3Mgc2l6ZSBzdXJ2aXZlcyBhcyB0aGUgPGltZz4gd2lkdGgvaGVpZ2h0IHRoZVxuICogIHBhc3RlIGVuZ2luZSBhbGxvd3MuIFVua25vd24gdW5pdHMgYXJlIGxlZnQgZm9yIHRoZSBjYWxsZXIgdG8gc2tpcC4gKi9cbmZ1bmN0aW9uIGNzc1B4KHZhbHVlOiBzdHJpbmcpOiBudW1iZXIgfCBudWxsIHtcbiAgY29uc3QgbSA9IHZhbHVlLm1hdGNoKC9eXFxzKigtP1tcXGQuXSspXFxzKihwdHxweHxpbnxjbXxtbSk/XFxzKiQvaSk7XG4gIGlmICghbSkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IG4gPSBwYXJzZUZsb2F0KG1bMV0pO1xuICBpZiAoIWlzRmluaXRlKG4pIHx8IG4gPD0gMCkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IHVuaXQgPSAobVsyXSB8fCAncHgnKS50b0xvd2VyQ2FzZSgpO1xuICBjb25zdCBweCA9XG4gICAgdW5pdCA9PT0gJ3B0JyA/IChuICogNCkgLyAzIDogdW5pdCA9PT0gJ2luJyA/IG4gKiA5NiA6IHVuaXQgPT09ICdjbScgPyAobiAqIDk2KSAvIDIuNTQgOiB1bml0ID09PSAnbW0nID8gKG4gKiA5NikgLyAyNS40IDogbjtcbiAgcmV0dXJuIE1hdGgucm91bmQocHgpO1xufVxuXG5mdW5jdGlvbiBhdHRyT2YodGFnOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IG0gPSB0YWcubWF0Y2gobmV3IFJlZ0V4cCgnXFxcXHMnICsgbmFtZSArICdcXFxccyo9XFxcXHMqKD86XCIoW15cIl0qKVwifFxcJyhbXlxcJ10qKVxcJ3woW15cXFxccz5dKykpJywgJ2knKSk7XG4gIHJldHVybiBtID8gbVsxXSA/PyBtWzJdID8/IG1bM10gPz8gJycgOiAnJztcbn1cblxuLyoqIFdvcmQgZGVzY3JpYmVzIGEgcGljdHVyZSB0d2ljZTogYXMgYSBWTUwgc2hhcGUgaW5zaWRlIGEgZG93bmxldmVsLWhpZGRlblxuICogIGNvbmRpdGlvbmFsIGNvbW1lbnQsIGFuZCBhcyBhIHBsYWluIDxpbWc+IGZhbGxiYWNrIGFmdGVyIGl0LiBXaXRoIFJlbHlPblZNTCBvbiDigJRcbiAqICB3aGljaCBpcyB3aGF0IGEgY3JvcHBlZCBwaWN0dXJlIGdldHMg4oCUIGl0IHdyaXRlcyBvbmx5IHRoZSBzaGFwZSwgYW5kIHRoZSBwYXN0ZVxuICogIGVuZ2luZSBkcm9wcyBjb25kaXRpb25hbCBjb21tZW50cywgc28gdGhlIHBpY3R1cmUgaGFzIG5vIHRhZyBsZWZ0IHRvIGxhbmQgb24gYW5kXG4gKiAgZGlzYXBwZWFycy4gR2l2ZSB0aG9zZSBzaGFwZXMgdGhlIDxpbWc+IFdvcmQgd2l0aGhlbGQsIGtlZXBpbmcgdGhlIHNoYXBlJ3Mgc2l6ZS5cbiAqICBQaWN0dXJlcyB0aGF0IGRvIGhhdmUgdGhlIGZhbGxiYWNrIGFyZSByZWNvZ25pc2VkIGJ5IHRoZWlyIHNyYyBhbmQgbGVmdCBhbG9uZS5cbiAqXG4gKiAgVGhlIHNoYXBlJ3MgY3JvcCBhdHRyaWJ1dGVzIGFyZSBub3QgYXBwbGllZDogdGhlIHBpY3R1cmUgYXBwZWFycyB1bmNyb3BwZWQuICovXG5leHBvcnQgZnVuY3Rpb24gdW53cmFwVm1sSW1hZ2VzKGh0bWw6IHN0cmluZyk6IHN0cmluZyB7XG4gIGlmICghLzx2OmltYWdlZGF0YVxcYi9pLnRlc3QoaHRtbCkpIHJldHVybiBodG1sO1xuXG4gIC8qKiBUaGUgPGltZz4gV29yZCB3aXRoaGVsZCwgb3IgbnVsbCB3aGVuIGl0IGRpZCBzdXBwbHkgb25lIChyZWNvZ25pc2VkIGJ5IGl0cyBzcmMpXG4gICAqICBhbmQgdGhlIHNoYXBlIGlzIHRoZXJlZm9yZSBvbmx5IHRoZSBkdXBsaWNhdGUgZGVzY3JpcHRpb24gb2YgdGhlIHNhbWUgcGljdHVyZS5cbiAgICogIGBzaXppbmdgIGlzIHdoYXRldmVyIG1hcmt1cCB0aGUgc2hhcGUncyBzdHlsZSBhdHRyaWJ1dGUgY2FuIGJlIHJlYWQgZnJvbS4gKi9cbiAgY29uc3QgaW1nRm9yID0gKGltYWdlZGF0YTogc3RyaW5nLCBzaXppbmc6IHN0cmluZyk6IHN0cmluZyB8IG51bGwgPT4ge1xuICAgIGNvbnN0IHNyYyA9IGF0dHJPZihpbWFnZWRhdGEsICdzcmMnKTtcbiAgICBpZiAoIXNyYykgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgcXVvdGVkID0gc3JjLnJlcGxhY2UoL1suKis/XiR7fSgpfFtcXF1cXFxcXS9nLCAnXFxcXCQmJyk7XG4gICAgaWYgKG5ldyBSZWdFeHAoJzxpbWdcXFxcYltePl0qXFxcXGJzcmNcXFxccyo9XFxcXHMqW1wiXFwnXT8nICsgcXVvdGVkLCAnaScpLnRlc3QoaHRtbCkpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IHN0eWxlID0gKHNpemluZy5tYXRjaCgvPHY6c2hhcGVcXGJbXj5dKlxcc3N0eWxlXFxzKj1cXHMqKD86XCIoW15cIl0qKVwifCcoW14nXSopJykvaSkgfHwgW10pLnNsaWNlKDEpLmZpbmQoQm9vbGVhbikgfHwgJyc7XG4gICAgY29uc3QgdyA9IGNzc1B4KChzdHlsZS5tYXRjaCgvKD86Xnw7KVxccyp3aWR0aFxccyo6XFxzKihbXjtdKykvaSkgfHwgW10pWzFdIHx8ICcnKTtcbiAgICBjb25zdCBoID0gY3NzUHgoKHN0eWxlLm1hdGNoKC8oPzpefDspXFxzKmhlaWdodFxccyo6XFxzKihbXjtdKykvaSkgfHwgW10pWzFdIHx8ICcnKTtcbiAgICByZXR1cm4gKFxuICAgICAgJzxpbWcgc3JjPVwiJyArXG4gICAgICBzcmMucmVwbGFjZSgvXCIvZywgJyZxdW90OycpICtcbiAgICAgICdcIicgK1xuICAgICAgKHcgPyAnIHdpZHRoPVwiJyArIHcgKyAnXCInIDogJycpICtcbiAgICAgIChoID8gJyBoZWlnaHQ9XCInICsgaCArICdcIicgOiAnJykgK1xuICAgICAgJz4nXG4gICAgKTtcbiAgfTtcblxuICAvKiBEb3dubGV2ZWwtaGlkZGVuIHNoYXBlOiBhbiA8aW1nPiBwdXQgaW5zaWRlIHdvdWxkIHN0YXkgaW5zaWRlIGEgY29tbWVudCBhbmQgbmV2ZXJcbiAgICAgcmVhY2ggdGhlIERPTSwgc28gdGhlIHdob2xlIGJsb2NrIGhhcyB0byBnby4gKi9cbiAgbGV0IG91dCA9IGh0bWwucmVwbGFjZSgvPCEtLVxcW2lmIFteXFxdXSpcXF0+KFtcXHNcXFNdKj8pPCFcXFtlbmRpZlxcXS0tPi9naSwgKGJsb2NrLCBpbm5lcjogc3RyaW5nKSA9PiB7XG4gICAgY29uc3QgZGF0YSA9IGlubmVyLm1hdGNoKC88djppbWFnZWRhdGFcXGJbXj5dKj4vaSk7XG4gICAgcmV0dXJuIChkYXRhICYmIGltZ0ZvcihkYXRhWzBdLCBpbm5lcikpIHx8IGJsb2NrO1xuICB9KTtcblxuICAvKiBMaXZlIHNoYXBlOiB3aXRoIFJlbHlPblZNTCBvbiwgV29yZCB3cml0ZXMgdGhlIHNoYXBlIGludG8gdGhlIGRvY3VtZW50IGl0c2VsZlxuICAgICAoYmFyZSwgb3IgaW5zaWRlIGEgZG93bmxldmVsLXJldmVhbGVkIDwhW2lmIGd0ZSB2bWwgMV0+IHRoYXQgdGhlIHBhcnNlciBkcm9wcyksXG4gICAgIGNvdW50aW5nIG9uIHRoZSB2XFw6KntiZWhhdmlvcjp1cmwoI2RlZmF1bHQjVk1MKX0gcnVsZSBpdCBzaGlwcyBpbiA8aGVhZD4uICovXG4gIG91dCA9IG91dC5yZXBsYWNlKC88djpzaGFwZVxcYltePl0qPltcXHNcXFNdKj88XFwvdjpzaGFwZVxccyo+L2dpLCAoc2hhcGUpID0+IHtcbiAgICBjb25zdCBkYXRhID0gc2hhcGUubWF0Y2goLzx2OmltYWdlZGF0YVxcYltePl0qPi9pKTtcbiAgICByZXR1cm4gKGRhdGEgJiYgaW1nRm9yKGRhdGFbMF0sIHNoYXBlKSkgfHwgc2hhcGU7XG4gIH0pO1xuXG4gIC8qIEFuIGltYWdlZGF0YSB3aXRoIG5vIHNoYXBlIGxlZnQgdG8gdGFrZSBpdHMgc2l6ZSBmcm9tLiAqL1xuICByZXR1cm4gb3V0LnJlcGxhY2UoLzx2OmltYWdlZGF0YVxcYltePl0qPi9naSwgKGRhdGEpID0+IGltZ0ZvcihkYXRhLCAnJykgfHwgZGF0YSk7XG59XG5cbi8qKiBSZXdyaXRlcyB1bnVzYWJsZSA8aW1nIHNyYz4gdmFsdWVzIGluIHJhdyBwYXN0ZWQgSFRNTCB3aXRoIHRoZSBwaWN0dXJlcyBnaXZlbiwgaW5cbiAqICBkb2N1bWVudCBvcmRlci4gSW1hZ2VzIHRoYXQgYWxyZWFkeSBoYXZlIGEgdXNhYmxlIHNyYyBhcmUgbGVmdCBhbG9uZSBhbmQgZG8gbm90XG4gKiAgY29uc3VtZSBhIHNsb3QsIHNvIGEgbWl4ZWQgcGFzdGUgKHdlYm1haWwgaW1hZ2UgKyBXb3JkIGltYWdlKSBzdGF5cyBhbGlnbmVkLlxuICogIEFueXRoaW5nIHdpdGhvdXQgYSBtYXRjaGluZyBwaWN0dXJlIGtlZXBzIGl0cyBvcmlnaW5hbCB0YWcuICovXG5leHBvcnQgZnVuY3Rpb24gaW5qZWN0SW1hZ2VzKGh0bWw6IHN0cmluZywgaW1nczogUnRmSW1hZ2VzKTogSW5qZWN0UmVzdWx0IHtcbiAgaWYgKCFodG1sIHx8ICFpbWdzLmxlbmd0aCkgcmV0dXJuIHsgaHRtbCwgaW5qZWN0ZWQ6IFtdIH07XG4gIGNvbnN0IGluamVjdGVkOiBzdHJpbmdbXSA9IFtdO1xuICBsZXQgbmV4dCA9IDA7XG4gIGNvbnN0IG91dCA9IHVud3JhcFZtbEltYWdlcyhodG1sKS5yZXBsYWNlKC88aW1nXFxiW14+XSo+L2dpLCAodGFnKSA9PiB7XG4gICAgY29uc3Qgc3JjID0gKHRhZy5tYXRjaCgvXFxzc3JjXFxzKj1cXHMqW1wiJ10/KFteXCInXFxzPl0rKS9pKSB8fCBbXSlbMV0gfHwgJyc7XG4gICAgaWYgKFVTQUJMRV9TUkMudGVzdChzcmMpKSByZXR1cm4gdGFnO1xuICAgIGNvbnN0IGRhdGEgPSBpbWdzW25leHQrK107XG4gICAgaWYgKCFkYXRhKSByZXR1cm4gdGFnO1xuICAgIGluamVjdGVkLnB1c2goZGF0YSk7XG4gICAgcmV0dXJuIC9cXHNzcmNcXHMqPVxccypbXCInXS9pLnRlc3QodGFnKVxuICAgICAgPyB0YWcucmVwbGFjZSgvKFxcc3NyY1xccyo9XFxzKikoW1wiJ10pW15cIiddKlxcMi9pLCAnJDFcIicgKyBkYXRhICsgJ1wiJylcbiAgICAgIDogdGFnLnJlcGxhY2UoLyhcXHNzcmNcXHMqPVxccyopW15cXHM+XSsvaSwgJyQxXCInICsgZGF0YSArICdcIicpO1xuICB9KTtcbiAgcmV0dXJuIHsgaHRtbDogb3V0LCBpbmplY3RlZCB9O1xufVxuXG4vKiogUGFpcnMgdGhlIEhUTUwgZmxhdm9yIG9mIGEgV29yZCBwYXN0ZSB3aXRoIHRoZSBwaWN0dXJlcyBpbiBpdHMgUlRGIGZsYXZvci4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbmplY3RSdGZJbWFnZXMoaHRtbDogc3RyaW5nLCBydGY6IHN0cmluZyk6IEluamVjdFJlc3VsdCB7XG4gIGlmICghaHRtbCB8fCAhcnRmKSByZXR1cm4geyBodG1sLCBpbmplY3RlZDogW10gfTtcbiAgcmV0dXJuIGluamVjdEltYWdlcyhodG1sLCBleHRyYWN0UnRmSW1hZ2VzKHJ0ZikpO1xufVxuXG4vKiogVHJ1ZSB3aGVuIHRoZSBjbGVhbmVkIEhUTUwgc3RpbGwgaG9sZHMgaW1hZ2VzIHRoZSBlbmdpbmUgY291bGQgbm90IHJlc29sdmUg4oCUIHVzZWRcbiAqICB0byBkZWNpZGUgd2hldGhlciBhIGJpdG1hcCBzaXR0aW5nIGluIHRoZSBjbGlwYm9hcmQgaXMgd29ydGggZmFsbGluZyBiYWNrIHRvLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvdW50VW5yZXNvbHZlZEltYWdlcyhodG1sOiBzdHJpbmcpOiBudW1iZXIge1xuICBjb25zdCB0YWdzID0gaHRtbC5tYXRjaCgvPGltZ1xcYltePl0qPi9naSk7XG4gIGlmICghdGFncykgcmV0dXJuIDA7XG4gIHJldHVybiB0YWdzLmZpbHRlcigodGFnKSA9PiB7XG4gICAgY29uc3Qgc3JjID0gKHRhZy5tYXRjaCgvXFxzc3JjXFxzKj1cXHMqW1wiJ10/KFteXCInXFxzPl0rKS9pKSB8fCBbXSlbMV0gfHwgJyc7XG4gICAgcmV0dXJuICFVU0FCTEVfU1JDLnRlc3Qoc3JjKTtcbiAgfSkubGVuZ3RoO1xufVxuXG4vKiogZGF0YTogVVJJIC0+IEZpbGUsIHNvIHJlY292ZXJlZCBwaWN0dXJlcyBjYW4gZ28gdGhyb3VnaCB0aGUgaG9zdCdzXG4gKiAgaW1hZ2VVcGxvYWRIYW5kbGVyIGV4YWN0bHkgbGlrZSBhIHBpY2tlZCBmaWxlIGRvZXMuIGBiYXNlTmFtZWAgZ2V0cyB0aGUgZXh0ZW5zaW9uXG4gKiAgdGhhdCBtYXRjaGVzIHRoZSBVUkkncyBNSU1FIHR5cGUuICovXG5leHBvcnQgZnVuY3Rpb24gZGF0YVVybFRvRmlsZShkYXRhVXJsOiBzdHJpbmcsIGJhc2VOYW1lOiBzdHJpbmcpOiBGaWxlIHwgbnVsbCB7XG4gIGNvbnN0IG0gPSBkYXRhVXJsLm1hdGNoKC9eZGF0YTooW147LF0rKTtiYXNlNjQsKC4qKSQvKTtcbiAgaWYgKCFtKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgZXh0ID0gKG1bMV0uc3BsaXQoJy8nKVsxXSB8fCAncG5nJykucmVwbGFjZSgvW15hLXowLTldL2dpLCAnJykgfHwgJ3BuZyc7XG4gIHRyeSB7XG4gICAgY29uc3QgYmluID0gYXRvYihtWzJdKTtcbiAgICBjb25zdCBieXRlcyA9IG5ldyBVaW50OEFycmF5KGJpbi5sZW5ndGgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYmluLmxlbmd0aDsgaSsrKSBieXRlc1tpXSA9IGJpbi5jaGFyQ29kZUF0KGkpO1xuICAgIHJldHVybiBuZXcgRmlsZShbYnl0ZXNdLCBiYXNlTmFtZSArICcuJyArIChleHQgPT09ICdqcGVnJyA/ICdqcGcnIDogZXh0KSwgeyB0eXBlOiBtWzFdIH0pO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cbiJdfQ==
@@ -1374,9 +1374,14 @@ function decodePict(body) {
1374
1374
  kind = 'metafile';
1375
1375
  if (!kind)
1376
1376
  return null;
1377
+ /* Each removal leaves a space behind. Deleting outright would glue what surrounded
1378
+ it together, and Word ends the picture header with `\bliptagN{\*\blipuid …}`
1379
+ hard against the payload: dropping the uid group would let the \bliptag
1380
+ parameter's `\d*` run straight on into the hex and eat its leading digits
1381
+ (89504e47… -> e470…), which silently corrupts every picture Word sends. */
1377
1382
  let hex = body
1378
- .replace(/\{[^{}]*\}/g, '') // nested property groups
1379
- .replace(/\\[a-z]+-?\d*\s?/gi, '') // control words
1383
+ .replace(/\{[^{}]*\}/g, ' ') // nested property groups
1384
+ .replace(/\\[a-z]+-?\d*\s?/gi, ' ') // control words
1380
1385
  .replace(/[^0-9a-fA-F]/g, '');
1381
1386
  if (hex.length % 2)
1382
1387
  hex = hex.slice(0, -1);
@@ -1419,6 +1424,70 @@ function extractRtfImages(rtf) {
1419
1424
  return data;
1420
1425
  });
1421
1426
  }
1427
+ /** CSS length -> px, so a VML shape's size survives as the <img> width/height the
1428
+ * paste engine allows. Unknown units are left for the caller to skip. */
1429
+ function cssPx(value) {
1430
+ const m = value.match(/^\s*(-?[\d.]+)\s*(pt|px|in|cm|mm)?\s*$/i);
1431
+ if (!m)
1432
+ return null;
1433
+ const n = parseFloat(m[1]);
1434
+ if (!isFinite(n) || n <= 0)
1435
+ return null;
1436
+ const unit = (m[2] || 'px').toLowerCase();
1437
+ const px = unit === 'pt' ? (n * 4) / 3 : unit === 'in' ? n * 96 : unit === 'cm' ? (n * 96) / 2.54 : unit === 'mm' ? (n * 96) / 25.4 : n;
1438
+ return Math.round(px);
1439
+ }
1440
+ function attrOf(tag, name) {
1441
+ const m = tag.match(new RegExp('\\s' + name + '\\s*=\\s*(?:"([^"]*)"|\'([^\']*)\'|([^\\s>]+))', 'i'));
1442
+ return m ? m[1] ?? m[2] ?? m[3] ?? '' : '';
1443
+ }
1444
+ /** Word describes a picture twice: as a VML shape inside a downlevel-hidden
1445
+ * conditional comment, and as a plain <img> fallback after it. With RelyOnVML on —
1446
+ * which is what a cropped picture gets — it writes only the shape, and the paste
1447
+ * engine drops conditional comments, so the picture has no tag left to land on and
1448
+ * disappears. Give those shapes the <img> Word withheld, keeping the shape's size.
1449
+ * Pictures that do have the fallback are recognised by their src and left alone.
1450
+ *
1451
+ * The shape's crop attributes are not applied: the picture appears uncropped. */
1452
+ function unwrapVmlImages(html) {
1453
+ if (!/<v:imagedata\b/i.test(html))
1454
+ return html;
1455
+ /** The <img> Word withheld, or null when it did supply one (recognised by its src)
1456
+ * and the shape is therefore only the duplicate description of the same picture.
1457
+ * `sizing` is whatever markup the shape's style attribute can be read from. */
1458
+ const imgFor = (imagedata, sizing) => {
1459
+ const src = attrOf(imagedata, 'src');
1460
+ if (!src)
1461
+ return null;
1462
+ const quoted = src.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1463
+ if (new RegExp('<img\\b[^>]*\\bsrc\\s*=\\s*["\']?' + quoted, 'i').test(html))
1464
+ return null;
1465
+ const style = (sizing.match(/<v:shape\b[^>]*\sstyle\s*=\s*(?:"([^"]*)"|'([^']*)')/i) || []).slice(1).find(Boolean) || '';
1466
+ const w = cssPx((style.match(/(?:^|;)\s*width\s*:\s*([^;]+)/i) || [])[1] || '');
1467
+ const h = cssPx((style.match(/(?:^|;)\s*height\s*:\s*([^;]+)/i) || [])[1] || '');
1468
+ return ('<img src="' +
1469
+ src.replace(/"/g, '&quot;') +
1470
+ '"' +
1471
+ (w ? ' width="' + w + '"' : '') +
1472
+ (h ? ' height="' + h + '"' : '') +
1473
+ '>');
1474
+ };
1475
+ /* Downlevel-hidden shape: an <img> put inside would stay inside a comment and never
1476
+ reach the DOM, so the whole block has to go. */
1477
+ let out = html.replace(/<!--\[if [^\]]*\]>([\s\S]*?)<!\[endif\]-->/gi, (block, inner) => {
1478
+ const data = inner.match(/<v:imagedata\b[^>]*>/i);
1479
+ return (data && imgFor(data[0], inner)) || block;
1480
+ });
1481
+ /* Live shape: with RelyOnVML on, Word writes the shape into the document itself
1482
+ (bare, or inside a downlevel-revealed <![if gte vml 1]> that the parser drops),
1483
+ counting on the v\:*{behavior:url(#default#VML)} rule it ships in <head>. */
1484
+ out = out.replace(/<v:shape\b[^>]*>[\s\S]*?<\/v:shape\s*>/gi, (shape) => {
1485
+ const data = shape.match(/<v:imagedata\b[^>]*>/i);
1486
+ return (data && imgFor(data[0], shape)) || shape;
1487
+ });
1488
+ /* An imagedata with no shape left to take its size from. */
1489
+ return out.replace(/<v:imagedata\b[^>]*>/gi, (data) => imgFor(data, '') || data);
1490
+ }
1422
1491
  /** Rewrites unusable <img src> values in raw pasted HTML with the pictures given, in
1423
1492
  * document order. Images that already have a usable src are left alone and do not
1424
1493
  * consume a slot, so a mixed paste (webmail image + Word image) stays aligned.
@@ -1428,7 +1497,7 @@ function injectImages(html, imgs) {
1428
1497
  return { html, injected: [] };
1429
1498
  const injected = [];
1430
1499
  let next = 0;
1431
- const out = html.replace(/<img\b[^>]*>/gi, (tag) => {
1500
+ const out = unwrapVmlImages(html).replace(/<img\b[^>]*>/gi, (tag) => {
1432
1501
  const src = (tag.match(/\ssrc\s*=\s*["']?([^"'\s>]+)/i) || [])[1] || '';
1433
1502
  if (USABLE_SRC.test(src))
1434
1503
  return tag;
@@ -2656,6 +2725,17 @@ class FableEditor {
2656
2725
  const cur = (el.getAttribute('style') || '').trim();
2657
2726
  el.setAttribute('style', cur ? cur.replace(/;?$/, '; ') + decl : decl);
2658
2727
  };
2728
+ /* Replaces the `width:` an element already carries instead of appending a
2729
+ second one and leaving it to the mail client which of the two wins.
2730
+ `max-width` / `min-width` are left alone. */
2731
+ const setWidthPx = (el, w) => {
2732
+ const kept = (el.getAttribute('style') || '')
2733
+ .split(';')
2734
+ .map((d) => d.trim())
2735
+ .filter((d) => d && !/^width\s*:/i.test(d));
2736
+ kept.push(`width:${w}px`);
2737
+ el.setAttribute('style', kept.join('; '));
2738
+ };
2659
2739
  const box = document.createElement('div');
2660
2740
  box.innerHTML = this.ed.innerHTML;
2661
2741
  let found = null;
@@ -2688,18 +2768,26 @@ class FableEditor {
2688
2768
  built from the same HTML) and make it explicit. The width attribute is what
2689
2769
  Outlook desktop follows; max-width keeps it inside narrow mobile clients.
2690
2770
  Documents saved before this existed are fixed here too, without rewriting
2691
- anything the host has stored. */
2771
+ anything the host has stored.
2772
+ The measured width overrides what the markup carries rather than only
2773
+ filling a gap: an image that `max-width:100%` is clamping, and one whose
2774
+ stored size predates a resize, are on screen at the measured width and have
2775
+ to leave at it too — that is what makes the mail match the preview.
2776
+ offsetWidth is the laid-out width, so a rotate/flip transform on the image
2777
+ cannot distort it, and a stale height attribute goes out with the old width:
2778
+ the aspect ratio then comes from the picture itself, exactly as the editor's
2779
+ `height:auto` gives it. */
2692
2780
  const liveImgs = this.ed.querySelectorAll('img');
2693
2781
  box.querySelectorAll('img').forEach((img, i) => {
2694
2782
  if (img.closest('.tpl-media'))
2695
2783
  return;
2696
2784
  const live = liveImgs[i];
2697
- const w = Math.round(live?.getBoundingClientRect().width || 0);
2698
- if (w > 0 && !img.getAttribute('width'))
2785
+ const w = Math.round(live?.offsetWidth || 0);
2786
+ if (w > 0) {
2699
2787
  img.setAttribute('width', String(w));
2700
- const style = img.getAttribute('style') || '';
2701
- if (w > 0 && !/(^|;)\s*width\s*:/i.test(style))
2702
- setStyle(img, `width:${w}px`);
2788
+ img.removeAttribute('height');
2789
+ setWidthPx(img, w);
2790
+ }
2703
2791
  if (!/max-width\s*:/i.test(img.getAttribute('style') || ''))
2704
2792
  setStyle(img, 'max-width:100%');
2705
2793
  if (!/(^|;)\s*height\s*:/i.test(img.getAttribute('style') || ''))
@@ -4538,14 +4626,18 @@ class FableEditor {
4538
4626
  image is exactly the size the user left it at — a narrower preview pane
4539
4627
  would silently shrink it and misreport what will be sent. The dialog gets
4540
4628
  a wider cap to make that width reachable; on a viewport too small for it
4541
- the image's max-width:100% scales things down rather than clipping. */
4629
+ the image's max-width:100% scales things down rather than clipping.
4630
+ box-sizing is pinned because a host page with the usual global
4631
+ border-box rule would otherwise take the 14px padding out of that width
4632
+ and preview every full-width image 28px narrower than it will be sent. */
4542
4633
  body.closest('.dlg')?.classList.add('dlg-preview');
4543
4634
  const box = document.createElement('div');
4544
4635
  box.className = 'pv-box';
4545
4636
  const w = this.contentWidth();
4546
4637
  box.style.cssText =
4547
4638
  `width:${w > 0 ? Math.round(w) : 640}px;max-width:100%;max-height:52vh;overflow:auto;` +
4548
- 'border:1px solid #e3e3e3;border-radius:6px;padding:14px;font-family:Helvetica,Arial,sans-serif;font-size:14px';
4639
+ 'box-sizing:content-box;border:1px solid #e3e3e3;border-radius:6px;padding:14px;' +
4640
+ 'font-family:Helvetica,Arial,sans-serif;font-size:14px';
4549
4641
  box.innerHTML = this.ed.innerHTML;
4550
4642
  body.appendChild(box);
4551
4643
  });
@@ -6173,11 +6265,19 @@ class FableEditor {
6173
6265
  return;
6174
6266
  this.cancelImgHide();
6175
6267
  const startX = e.clientX;
6176
- const startW = img.getBoundingClientRect().width;
6268
+ const startW = img.offsetWidth || img.getBoundingClientRect().width;
6177
6269
  const sign = corner === 'nw' || corner === 'sw' ? -1 : 1;
6270
+ /* `.earea img { max-width:100% }` clamps an image to the text column, so a drag
6271
+ past that edge would store a width the editor never renders — and a mail, which
6272
+ carries no such rule, would then go out at that unseen width. Cap the drag at
6273
+ the column so the stored size is always the size on screen. */
6274
+ const max = Math.round(this.contentWidth());
6178
6275
  this.withNoTextSelect((restore) => {
6179
6276
  const mv = (ev) => {
6180
- img.style.width = Math.max(24, Math.round(startW + sign * (ev.clientX - startX))) + 'px';
6277
+ let w = Math.max(24, Math.round(startW + sign * (ev.clientX - startX)));
6278
+ if (max > 0)
6279
+ w = Math.min(w, max);
6280
+ img.style.width = w + 'px';
6181
6281
  img.style.height = 'auto';
6182
6282
  this.positionImageHandles();
6183
6283
  };
@@ -6187,9 +6287,12 @@ class FableEditor {
6187
6287
  restore();
6188
6288
  /* mirror the final size onto the width attribute: Outlook desktop
6189
6289
  follows the attribute rather than the CSS, so without this a resized
6190
- image still goes out at its original size */
6191
- const w = parseInt(img.style.width, 10);
6290
+ image still goes out at its original size. Read it back from the laid
6291
+ out box offsetWidth ignores any rotate/flip transform — so the
6292
+ attribute, the inline width and what the user sees cannot disagree. */
6293
+ const w = Math.round(img.offsetWidth) || parseInt(img.style.width, 10);
6192
6294
  if (w > 0 && !img.closest('.tpl-media')) {
6295
+ img.style.width = w + 'px';
6193
6296
  img.setAttribute('width', String(w));
6194
6297
  img.removeAttribute('height');
6195
6298
  }