UNPKG

857 kBJavaScriptView Raw
1(function (global, factory) {
2typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('source-map')) :
3typeof define === 'function' && define.amd ? define(['exports', 'source-map'], factory) :
4(global = global || self, factory(global.Terser = {}, global.sourceMap));
5}(this, (function (exports, MOZ_SourceMap) { 'use strict';
6
7MOZ_SourceMap = MOZ_SourceMap && Object.prototype.hasOwnProperty.call(MOZ_SourceMap, 'default') ? MOZ_SourceMap['default'] : MOZ_SourceMap;
8
9/***********************************************************************
10
11 A JavaScript tokenizer / parser / beautifier / compressor.
12 https://github.com/mishoo/UglifyJS2
13
14 -------------------------------- (C) ---------------------------------
15
16 Author: Mihai Bazon
17 <mihai.bazon@gmail.com>
18 http://mihai.bazon.net/blog
19
20 Distributed under the BSD license:
21
22 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
23
24 Redistribution and use in source and binary forms, with or without
25 modification, are permitted provided that the following conditions
26 are met:
27
28 * Redistributions of source code must retain the above
29 copyright notice, this list of conditions and the following
30 disclaimer.
31
32 * Redistributions in binary form must reproduce the above
33 copyright notice, this list of conditions and the following
34 disclaimer in the documentation and/or other materials
35 provided with the distribution.
36
37 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
38 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
40 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
41 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
42 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
43 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
44 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
46 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
47 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 SUCH DAMAGE.
49
50 ***********************************************************************/
51
52function characters(str) {
53 return str.split("");
54}
55
56function member(name, array) {
57 return array.includes(name);
58}
59
60class DefaultsError extends Error {
61 constructor(msg, defs) {
62 super();
63
64 this.name = "DefaultsError";
65 this.message = msg;
66 this.defs = defs;
67 }
68}
69
70function defaults(args, defs, croak) {
71 if (args === true) {
72 args = {};
73 }
74
75 if (args != null && typeof args === "object") {
76 args = Object.assign({}, args);
77 }
78
79 const ret = args || {};
80
81 if (croak) for (const i in ret) if (HOP(ret, i) && !HOP(defs, i)) {
82 throw new DefaultsError("`" + i + "` is not a supported option", defs);
83 }
84
85 for (const i in defs) if (HOP(defs, i)) {
86 if (!args || !HOP(args, i)) {
87 ret[i] = defs[i];
88 } else if (i === "ecma") {
89 let ecma = args[i] | 0;
90 if (ecma > 5 && ecma < 2015) ecma += 2009;
91 ret[i] = ecma;
92 } else {
93 ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
94 }
95 }
96
97 return ret;
98}
99
100function noop() {}
101function return_false() { return false; }
102function return_true() { return true; }
103function return_this() { return this; }
104function return_null() { return null; }
105
106var MAP = (function() {
107 function MAP(a, f, backwards) {
108 var ret = [], top = [], i;
109 function doit() {
110 var val = f(a[i], i);
111 var is_last = val instanceof Last;
112 if (is_last) val = val.v;
113 if (val instanceof AtTop) {
114 val = val.v;
115 if (val instanceof Splice) {
116 top.push.apply(top, backwards ? val.v.slice().reverse() : val.v);
117 } else {
118 top.push(val);
119 }
120 } else if (val !== skip) {
121 if (val instanceof Splice) {
122 ret.push.apply(ret, backwards ? val.v.slice().reverse() : val.v);
123 } else {
124 ret.push(val);
125 }
126 }
127 return is_last;
128 }
129 if (Array.isArray(a)) {
130 if (backwards) {
131 for (i = a.length; --i >= 0;) if (doit()) break;
132 ret.reverse();
133 top.reverse();
134 } else {
135 for (i = 0; i < a.length; ++i) if (doit()) break;
136 }
137 } else {
138 for (i in a) if (HOP(a, i)) if (doit()) break;
139 }
140 return top.concat(ret);
141 }
142 MAP.at_top = function(val) { return new AtTop(val); };
143 MAP.splice = function(val) { return new Splice(val); };
144 MAP.last = function(val) { return new Last(val); };
145 var skip = MAP.skip = {};
146 function AtTop(val) { this.v = val; }
147 function Splice(val) { this.v = val; }
148 function Last(val) { this.v = val; }
149 return MAP;
150})();
151
152function make_node(ctor, orig, props) {
153 if (!props) props = {};
154 if (orig) {
155 if (!props.start) props.start = orig.start;
156 if (!props.end) props.end = orig.end;
157 }
158 return new ctor(props);
159}
160
161function push_uniq(array, el) {
162 if (!array.includes(el))
163 array.push(el);
164}
165
166function string_template(text, props) {
167 return text.replace(/{(.+?)}/g, function(str, p) {
168 return props && props[p];
169 });
170}
171
172function remove(array, el) {
173 for (var i = array.length; --i >= 0;) {
174 if (array[i] === el) array.splice(i, 1);
175 }
176}
177
178function mergeSort(array, cmp) {
179 if (array.length < 2) return array.slice();
180 function merge(a, b) {
181 var r = [], ai = 0, bi = 0, i = 0;
182 while (ai < a.length && bi < b.length) {
183 cmp(a[ai], b[bi]) <= 0
184 ? r[i++] = a[ai++]
185 : r[i++] = b[bi++];
186 }
187 if (ai < a.length) r.push.apply(r, a.slice(ai));
188 if (bi < b.length) r.push.apply(r, b.slice(bi));
189 return r;
190 }
191 function _ms(a) {
192 if (a.length <= 1)
193 return a;
194 var m = Math.floor(a.length / 2), left = a.slice(0, m), right = a.slice(m);
195 left = _ms(left);
196 right = _ms(right);
197 return merge(left, right);
198 }
199 return _ms(array);
200}
201
202function makePredicate(words) {
203 if (!Array.isArray(words)) words = words.split(" ");
204
205 return new Set(words);
206}
207
208function map_add(map, key, value) {
209 if (map.has(key)) {
210 map.get(key).push(value);
211 } else {
212 map.set(key, [ value ]);
213 }
214}
215
216function map_from_object(obj) {
217 var map = new Map();
218 for (var key in obj) {
219 if (HOP(obj, key) && key.charAt(0) === "$") {
220 map.set(key.substr(1), obj[key]);
221 }
222 }
223 return map;
224}
225
226function map_to_object(map) {
227 var obj = Object.create(null);
228 map.forEach(function (value, key) {
229 obj["$" + key] = value;
230 });
231 return obj;
232}
233
234function HOP(obj, prop) {
235 return Object.prototype.hasOwnProperty.call(obj, prop);
236}
237
238function keep_name(keep_setting, name) {
239 return keep_setting === true
240 || (keep_setting instanceof RegExp && keep_setting.test(name));
241}
242
243var lineTerminatorEscape = {
244 "\n": "n",
245 "\r": "r",
246 "\u2028": "u2028",
247 "\u2029": "u2029",
248};
249function regexp_source_fix(source) {
250 // V8 does not escape line terminators in regexp patterns in node 12
251 return source.replace(/[\n\r\u2028\u2029]/g, function (match, offset) {
252 var escaped = source[offset - 1] == "\\"
253 && (source[offset - 2] != "\\"
254 || /(?:^|[^\\])(?:\\{2})*$/.test(source.slice(0, offset - 1)));
255 return (escaped ? "" : "\\") + lineTerminatorEscape[match];
256 });
257}
258const all_flags = "gimuy";
259function sort_regexp_flags(flags) {
260 const existing_flags = new Set(flags.split(""));
261 let out = "";
262 for (const flag of all_flags) {
263 if (existing_flags.has(flag)) {
264 out += flag;
265 existing_flags.delete(flag);
266 }
267 }
268 if (existing_flags.size) {
269 // Flags Terser doesn't know about
270 existing_flags.forEach(flag => { out += flag; });
271 }
272 return out;
273}
274
275function has_annotation(node, annotation) {
276 return node._annotations & annotation;
277}
278
279function set_annotation(node, annotation) {
280 node._annotations |= annotation;
281}
282
283/***********************************************************************
284
285 A JavaScript tokenizer / parser / beautifier / compressor.
286 https://github.com/mishoo/UglifyJS2
287
288 -------------------------------- (C) ---------------------------------
289
290 Author: Mihai Bazon
291 <mihai.bazon@gmail.com>
292 http://mihai.bazon.net/blog
293
294 Distributed under the BSD license:
295
296 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
297 Parser based on parse-js (http://marijn.haverbeke.nl/parse-js/).
298
299 Redistribution and use in source and binary forms, with or without
300 modification, are permitted provided that the following conditions
301 are met:
302
303 * Redistributions of source code must retain the above
304 copyright notice, this list of conditions and the following
305 disclaimer.
306
307 * Redistributions in binary form must reproduce the above
308 copyright notice, this list of conditions and the following
309 disclaimer in the documentation and/or other materials
310 provided with the distribution.
311
312 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
313 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
314 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
315 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
316 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
317 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
318 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
319 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
320 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
321 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
322 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
323 SUCH DAMAGE.
324
325 ***********************************************************************/
326
327var KEYWORDS = "break case catch class const continue debugger default delete do else export extends finally for function if in instanceof let new return switch throw try typeof var void while with";
328var KEYWORDS_ATOM = "false null true";
329var RESERVED_WORDS = "enum implements import interface package private protected public static super this " + KEYWORDS_ATOM + " " + KEYWORDS;
330var KEYWORDS_BEFORE_EXPRESSION = "return new delete throw else case yield await";
331
332KEYWORDS = makePredicate(KEYWORDS);
333RESERVED_WORDS = makePredicate(RESERVED_WORDS);
334KEYWORDS_BEFORE_EXPRESSION = makePredicate(KEYWORDS_BEFORE_EXPRESSION);
335KEYWORDS_ATOM = makePredicate(KEYWORDS_ATOM);
336
337var OPERATOR_CHARS = makePredicate(characters("+-*&%=<>!?|~^"));
338
339var RE_NUM_LITERAL = /[0-9a-f]/i;
340var RE_HEX_NUMBER = /^0x[0-9a-f]+$/i;
341var RE_OCT_NUMBER = /^0[0-7]+$/;
342var RE_ES6_OCT_NUMBER = /^0o[0-7]+$/i;
343var RE_BIN_NUMBER = /^0b[01]+$/i;
344var RE_DEC_NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i;
345var RE_BIG_INT = /^(0[xob])?[0-9a-f]+n$/i;
346
347var OPERATORS = makePredicate([
348 "in",
349 "instanceof",
350 "typeof",
351 "new",
352 "void",
353 "delete",
354 "++",
355 "--",
356 "+",
357 "-",
358 "!",
359 "~",
360 "&",
361 "|",
362 "^",
363 "*",
364 "**",
365 "/",
366 "%",
367 ">>",
368 "<<",
369 ">>>",
370 "<",
371 ">",
372 "<=",
373 ">=",
374 "==",
375 "===",
376 "!=",
377 "!==",
378 "?",
379 "=",
380 "+=",
381 "-=",
382 "/=",
383 "*=",
384 "**=",
385 "%=",
386 ">>=",
387 "<<=",
388 ">>>=",
389 "|=",
390 "^=",
391 "&=",
392 "&&",
393 "??",
394 "||",
395]);
396
397var WHITESPACE_CHARS = makePredicate(characters(" \u00a0\n\r\t\f\u000b\u200b\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000\uFEFF"));
398
399var NEWLINE_CHARS = makePredicate(characters("\n\r\u2028\u2029"));
400
401var PUNC_AFTER_EXPRESSION = makePredicate(characters(";]),:"));
402
403var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,;:"));
404
405var PUNC_CHARS = makePredicate(characters("[]{}(),;:"));
406
407/* -----[ Tokenizer ]----- */
408
409// surrogate safe regexps adapted from https://github.com/mathiasbynens/unicode-8.0.0/tree/89b412d8a71ecca9ed593d9e9fa073ab64acfebe/Binary_Property
410var UNICODE = {
411 ID_Start: /[$A-Z_a-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]/,
412 ID_Continue: /(?:[$0-9A-Z_a-z\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B4\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF])+/,
413};
414
415function get_full_char(str, pos) {
416 if (is_surrogate_pair_head(str.charCodeAt(pos))) {
417 if (is_surrogate_pair_tail(str.charCodeAt(pos + 1))) {
418 return str.charAt(pos) + str.charAt(pos + 1);
419 }
420 } else if (is_surrogate_pair_tail(str.charCodeAt(pos))) {
421 if (is_surrogate_pair_head(str.charCodeAt(pos - 1))) {
422 return str.charAt(pos - 1) + str.charAt(pos);
423 }
424 }
425 return str.charAt(pos);
426}
427
428function get_full_char_code(str, pos) {
429 // https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Surrogates
430 if (is_surrogate_pair_head(str.charCodeAt(pos))) {
431 return 0x10000 + (str.charCodeAt(pos) - 0xd800 << 10) + str.charCodeAt(pos + 1) - 0xdc00;
432 }
433 return str.charCodeAt(pos);
434}
435
436function get_full_char_length(str) {
437 var surrogates = 0;
438
439 for (var i = 0; i < str.length; i++) {
440 if (is_surrogate_pair_head(str.charCodeAt(i)) && is_surrogate_pair_tail(str.charCodeAt(i + 1))) {
441 surrogates++;
442 i++;
443 }
444 }
445
446 return str.length - surrogates;
447}
448
449function from_char_code(code) {
450 // Based on https://github.com/mathiasbynens/String.fromCodePoint/blob/master/fromcodepoint.js
451 if (code > 0xFFFF) {
452 code -= 0x10000;
453 return (String.fromCharCode((code >> 10) + 0xD800) +
454 String.fromCharCode((code % 0x400) + 0xDC00));
455 }
456 return String.fromCharCode(code);
457}
458
459function is_surrogate_pair_head(code) {
460 return code >= 0xd800 && code <= 0xdbff;
461}
462
463function is_surrogate_pair_tail(code) {
464 return code >= 0xdc00 && code <= 0xdfff;
465}
466
467function is_digit(code) {
468 return code >= 48 && code <= 57;
469}
470
471function is_identifier_start(ch) {
472 return UNICODE.ID_Start.test(ch);
473}
474
475function is_identifier_char(ch) {
476 return UNICODE.ID_Continue.test(ch);
477}
478
479function is_basic_identifier_string(str) {
480 return /^[a-z_$][a-z0-9_$]*$/i.test(str);
481}
482
483function is_identifier_string(str, allow_surrogates) {
484 if (/^[a-z_$][a-z0-9_$]*$/i.test(str)) {
485 return true;
486 }
487 if (!allow_surrogates && /[\ud800-\udfff]/.test(str)) {
488 return false;
489 }
490 var match = UNICODE.ID_Start.exec(str);
491 if (!match || match.index !== 0) {
492 return false;
493 }
494
495 str = str.slice(match[0].length);
496 if (!str) {
497 return true;
498 }
499
500 match = UNICODE.ID_Continue.exec(str);
501 return !!match && match[0].length === str.length;
502}
503
504function parse_js_number(num, allow_e = true) {
505 if (!allow_e && num.includes("e")) {
506 return NaN;
507 }
508 if (RE_HEX_NUMBER.test(num)) {
509 return parseInt(num.substr(2), 16);
510 } else if (RE_OCT_NUMBER.test(num)) {
511 return parseInt(num.substr(1), 8);
512 } else if (RE_ES6_OCT_NUMBER.test(num)) {
513 return parseInt(num.substr(2), 8);
514 } else if (RE_BIN_NUMBER.test(num)) {
515 return parseInt(num.substr(2), 2);
516 } else if (RE_DEC_NUMBER.test(num)) {
517 return parseFloat(num);
518 } else {
519 var val = parseFloat(num);
520 if (val == num) return val;
521 }
522}
523
524class JS_Parse_Error extends Error {
525 constructor(message, filename, line, col, pos) {
526 super();
527
528 this.name = "SyntaxError";
529 this.message = message;
530 this.filename = filename;
531 this.line = line;
532 this.col = col;
533 this.pos = pos;
534 }
535}
536
537function js_error(message, filename, line, col, pos) {
538 throw new JS_Parse_Error(message, filename, line, col, pos);
539}
540
541function is_token(token, type, val) {
542 return token.type == type && (val == null || token.value == val);
543}
544
545var EX_EOF = {};
546
547function tokenizer($TEXT, filename, html5_comments, shebang) {
548 var S = {
549 text : $TEXT,
550 filename : filename,
551 pos : 0,
552 tokpos : 0,
553 line : 1,
554 tokline : 0,
555 col : 0,
556 tokcol : 0,
557 newline_before : false,
558 regex_allowed : false,
559 brace_counter : 0,
560 template_braces : [],
561 comments_before : [],
562 directives : {},
563 directive_stack : []
564 };
565
566 function peek() { return get_full_char(S.text, S.pos); }
567
568 // Used because parsing ?. involves a lookahead for a digit
569 function is_option_chain_op() {
570 const must_be_dot = S.text.charCodeAt(S.pos + 1) === 46;
571 if (!must_be_dot) return false;
572
573 const cannot_be_digit = S.text.charCodeAt(S.pos + 2);
574 return cannot_be_digit < 48 || cannot_be_digit > 57;
575 }
576
577 function next(signal_eof, in_string) {
578 var ch = get_full_char(S.text, S.pos++);
579 if (signal_eof && !ch)
580 throw EX_EOF;
581 if (NEWLINE_CHARS.has(ch)) {
582 S.newline_before = S.newline_before || !in_string;
583 ++S.line;
584 S.col = 0;
585 if (ch == "\r" && peek() == "\n") {
586 // treat a \r\n sequence as a single \n
587 ++S.pos;
588 ch = "\n";
589 }
590 } else {
591 if (ch.length > 1) {
592 ++S.pos;
593 ++S.col;
594 }
595 ++S.col;
596 }
597 return ch;
598 }
599
600 function forward(i) {
601 while (i--) next();
602 }
603
604 function looking_at(str) {
605 return S.text.substr(S.pos, str.length) == str;
606 }
607
608 function find_eol() {
609 var text = S.text;
610 for (var i = S.pos, n = S.text.length; i < n; ++i) {
611 var ch = text[i];
612 if (NEWLINE_CHARS.has(ch))
613 return i;
614 }
615 return -1;
616 }
617
618 function find(what, signal_eof) {
619 var pos = S.text.indexOf(what, S.pos);
620 if (signal_eof && pos == -1) throw EX_EOF;
621 return pos;
622 }
623
624 function start_token() {
625 S.tokline = S.line;
626 S.tokcol = S.col;
627 S.tokpos = S.pos;
628 }
629
630 var prev_was_dot = false;
631 var previous_token = null;
632 function token(type, value, is_comment) {
633 S.regex_allowed = ((type == "operator" && !UNARY_POSTFIX.has(value)) ||
634 (type == "keyword" && KEYWORDS_BEFORE_EXPRESSION.has(value)) ||
635 (type == "punc" && PUNC_BEFORE_EXPRESSION.has(value))) ||
636 (type == "arrow");
637 if (type == "punc" && (value == "." || value == "?.")) {
638 prev_was_dot = true;
639 } else if (!is_comment) {
640 prev_was_dot = false;
641 }
642 var ret = {
643 type : type,
644 value : value,
645 line : S.tokline,
646 col : S.tokcol,
647 pos : S.tokpos,
648 endline : S.line,
649 endcol : S.col,
650 endpos : S.pos,
651 nlb : S.newline_before,
652 file : filename
653 };
654 if (/^(?:num|string|regexp)$/i.test(type)) {
655 ret.raw = $TEXT.substring(ret.pos, ret.endpos);
656 }
657 if (!is_comment) {
658 ret.comments_before = S.comments_before;
659 ret.comments_after = S.comments_before = [];
660 }
661 S.newline_before = false;
662 ret = new AST_Token(ret);
663 if (!is_comment) previous_token = ret;
664 return ret;
665 }
666
667 function skip_whitespace() {
668 while (WHITESPACE_CHARS.has(peek()))
669 next();
670 }
671
672 function read_while(pred) {
673 var ret = "", ch, i = 0;
674 while ((ch = peek()) && pred(ch, i++))
675 ret += next();
676 return ret;
677 }
678
679 function parse_error(err) {
680 js_error(err, filename, S.tokline, S.tokcol, S.tokpos);
681 }
682
683 function read_num(prefix) {
684 var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".", is_big_int = false, numeric_separator = false;
685 var num = read_while(function(ch, i) {
686 if (is_big_int) return false;
687
688 var code = ch.charCodeAt(0);
689 switch (code) {
690 case 95: // _
691 return (numeric_separator = true);
692 case 98: case 66: // bB
693 return (has_x = true); // Can occur in hex sequence, don't return false yet
694 case 111: case 79: // oO
695 case 120: case 88: // xX
696 return has_x ? false : (has_x = true);
697 case 101: case 69: // eE
698 return has_x ? true : has_e ? false : (has_e = after_e = true);
699 case 45: // -
700 return after_e || (i == 0 && !prefix);
701 case 43: // +
702 return after_e;
703 case (after_e = false, 46): // .
704 return (!has_dot && !has_x && !has_e) ? (has_dot = true) : false;
705 }
706
707 if (ch === "n") {
708 is_big_int = true;
709
710 return true;
711 }
712
713 return RE_NUM_LITERAL.test(ch);
714 });
715 if (prefix) num = prefix + num;
716 if (RE_OCT_NUMBER.test(num) && next_token.has_directive("use strict")) {
717 parse_error("Legacy octal literals are not allowed in strict mode");
718 }
719 if (numeric_separator) {
720 if (num.endsWith("_")) {
721 parse_error("Numeric separators are not allowed at the end of numeric literals");
722 } else if (num.includes("__")) {
723 parse_error("Only one underscore is allowed as numeric separator");
724 }
725 num = num.replace(/_/g, "");
726 }
727 if (num.endsWith("n")) {
728 const without_n = num.slice(0, -1);
729 const allow_e = RE_HEX_NUMBER.test(without_n);
730 const valid = parse_js_number(without_n, allow_e);
731 if (!has_dot && RE_BIG_INT.test(num) && !isNaN(valid))
732 return token("big_int", without_n);
733 parse_error("Invalid or unexpected token");
734 }
735 var valid = parse_js_number(num);
736 if (!isNaN(valid)) {
737 return token("num", valid);
738 } else {
739 parse_error("Invalid syntax: " + num);
740 }
741 }
742
743 function is_octal(ch) {
744 return ch >= "0" && ch <= "7";
745 }
746
747 function read_escaped_char(in_string, strict_hex, template_string) {
748 var ch = next(true, in_string);
749 switch (ch.charCodeAt(0)) {
750 case 110 : return "\n";
751 case 114 : return "\r";
752 case 116 : return "\t";
753 case 98 : return "\b";
754 case 118 : return "\u000b"; // \v
755 case 102 : return "\f";
756 case 120 : return String.fromCharCode(hex_bytes(2, strict_hex)); // \x
757 case 117 : // \u
758 if (peek() == "{") {
759 next(true);
760 if (peek() === "}")
761 parse_error("Expecting hex-character between {}");
762 while (peek() == "0") next(true); // No significance
763 var result, length = find("}", true) - S.pos;
764 // Avoid 32 bit integer overflow (1 << 32 === 1)
765 // We know first character isn't 0 and thus out of range anyway
766 if (length > 6 || (result = hex_bytes(length, strict_hex)) > 0x10FFFF) {
767 parse_error("Unicode reference out of bounds");
768 }
769 next(true);
770 return from_char_code(result);
771 }
772 return String.fromCharCode(hex_bytes(4, strict_hex));
773 case 10 : return ""; // newline
774 case 13 : // \r
775 if (peek() == "\n") { // DOS newline
776 next(true, in_string);
777 return "";
778 }
779 }
780 if (is_octal(ch)) {
781 if (template_string && strict_hex) {
782 const represents_null_character = ch === "0" && !is_octal(peek());
783 if (!represents_null_character) {
784 parse_error("Octal escape sequences are not allowed in template strings");
785 }
786 }
787 return read_octal_escape_sequence(ch, strict_hex);
788 }
789 return ch;
790 }
791
792 function read_octal_escape_sequence(ch, strict_octal) {
793 // Read
794 var p = peek();
795 if (p >= "0" && p <= "7") {
796 ch += next(true);
797 if (ch[0] <= "3" && (p = peek()) >= "0" && p <= "7")
798 ch += next(true);
799 }
800
801 // Parse
802 if (ch === "0") return "\0";
803 if (ch.length > 0 && next_token.has_directive("use strict") && strict_octal)
804 parse_error("Legacy octal escape sequences are not allowed in strict mode");
805 return String.fromCharCode(parseInt(ch, 8));
806 }
807
808 function hex_bytes(n, strict_hex) {
809 var num = 0;
810 for (; n > 0; --n) {
811 if (!strict_hex && isNaN(parseInt(peek(), 16))) {
812 return parseInt(num, 16) || "";
813 }
814 var digit = next(true);
815 if (isNaN(parseInt(digit, 16)))
816 parse_error("Invalid hex-character pattern in string");
817 num += digit;
818 }
819 return parseInt(num, 16);
820 }
821
822 var read_string = with_eof_error("Unterminated string constant", function() {
823 var quote = next(), ret = "";
824 for (;;) {
825 var ch = next(true, true);
826 if (ch == "\\") ch = read_escaped_char(true, true);
827 else if (ch == "\r" || ch == "\n") parse_error("Unterminated string constant");
828 else if (ch == quote) break;
829 ret += ch;
830 }
831 var tok = token("string", ret);
832 tok.quote = quote;
833 return tok;
834 });
835
836 var read_template_characters = with_eof_error("Unterminated template", function(begin) {
837 if (begin) {
838 S.template_braces.push(S.brace_counter);
839 }
840 var content = "", raw = "", ch, tok;
841 next(true, true);
842 while ((ch = next(true, true)) != "`") {
843 if (ch == "\r") {
844 if (peek() == "\n") ++S.pos;
845 ch = "\n";
846 } else if (ch == "$" && peek() == "{") {
847 next(true, true);
848 S.brace_counter++;
849 tok = token(begin ? "template_head" : "template_substitution", content);
850 tok.raw = raw;
851 return tok;
852 }
853
854 raw += ch;
855 if (ch == "\\") {
856 var tmp = S.pos;
857 var prev_is_tag = previous_token && (previous_token.type === "name" || previous_token.type === "punc" && (previous_token.value === ")" || previous_token.value === "]"));
858 ch = read_escaped_char(true, !prev_is_tag, true);
859 raw += S.text.substr(tmp, S.pos - tmp);
860 }
861
862 content += ch;
863 }
864 S.template_braces.pop();
865 tok = token(begin ? "template_head" : "template_substitution", content);
866 tok.raw = raw;
867 tok.end = true;
868 return tok;
869 });
870
871 function skip_line_comment(type) {
872 var regex_allowed = S.regex_allowed;
873 var i = find_eol(), ret;
874 if (i == -1) {
875 ret = S.text.substr(S.pos);
876 S.pos = S.text.length;
877 } else {
878 ret = S.text.substring(S.pos, i);
879 S.pos = i;
880 }
881 S.col = S.tokcol + (S.pos - S.tokpos);
882 S.comments_before.push(token(type, ret, true));
883 S.regex_allowed = regex_allowed;
884 return next_token;
885 }
886
887 var skip_multiline_comment = with_eof_error("Unterminated multiline comment", function() {
888 var regex_allowed = S.regex_allowed;
889 var i = find("*/", true);
890 var text = S.text.substring(S.pos, i).replace(/\r\n|\r|\u2028|\u2029/g, "\n");
891 // update stream position
892 forward(get_full_char_length(text) /* text length doesn't count \r\n as 2 char while S.pos - i does */ + 2);
893 S.comments_before.push(token("comment2", text, true));
894 S.newline_before = S.newline_before || text.includes("\n");
895 S.regex_allowed = regex_allowed;
896 return next_token;
897 });
898
899 var read_name = with_eof_error("Unterminated identifier name", function() {
900 var name, ch, escaped = false;
901 var read_escaped_identifier_char = function() {
902 escaped = true;
903 next();
904 if (peek() !== "u") {
905 parse_error("Expecting UnicodeEscapeSequence -- uXXXX or u{XXXX}");
906 }
907 return read_escaped_char(false, true);
908 };
909
910 // Read first character (ID_Start)
911 if ((name = peek()) === "\\") {
912 name = read_escaped_identifier_char();
913 if (!is_identifier_start(name)) {
914 parse_error("First identifier char is an invalid identifier char");
915 }
916 } else if (is_identifier_start(name)) {
917 next();
918 } else {
919 return "";
920 }
921
922 // Read ID_Continue
923 while ((ch = peek()) != null) {
924 if ((ch = peek()) === "\\") {
925 ch = read_escaped_identifier_char();
926 if (!is_identifier_char(ch)) {
927 parse_error("Invalid escaped identifier char");
928 }
929 } else {
930 if (!is_identifier_char(ch)) {
931 break;
932 }
933 next();
934 }
935 name += ch;
936 }
937 if (RESERVED_WORDS.has(name) && escaped) {
938 parse_error("Escaped characters are not allowed in keywords");
939 }
940 return name;
941 });
942
943 var read_regexp = with_eof_error("Unterminated regular expression", function(source) {
944 var prev_backslash = false, ch, in_class = false;
945 while ((ch = next(true))) if (NEWLINE_CHARS.has(ch)) {
946 parse_error("Unexpected line terminator");
947 } else if (prev_backslash) {
948 source += "\\" + ch;
949 prev_backslash = false;
950 } else if (ch == "[") {
951 in_class = true;
952 source += ch;
953 } else if (ch == "]" && in_class) {
954 in_class = false;
955 source += ch;
956 } else if (ch == "/" && !in_class) {
957 break;
958 } else if (ch == "\\") {
959 prev_backslash = true;
960 } else {
961 source += ch;
962 }
963 const flags = read_name();
964 return token("regexp", { source, flags });
965 });
966
967 function read_operator(prefix) {
968 function grow(op) {
969 if (!peek()) return op;
970 var bigger = op + peek();
971 if (OPERATORS.has(bigger)) {
972 next();
973 return grow(bigger);
974 } else {
975 return op;
976 }
977 }
978 return token("operator", grow(prefix || next()));
979 }
980
981 function handle_slash() {
982 next();
983 switch (peek()) {
984 case "/":
985 next();
986 return skip_line_comment("comment1");
987 case "*":
988 next();
989 return skip_multiline_comment();
990 }
991 return S.regex_allowed ? read_regexp("") : read_operator("/");
992 }
993
994 function handle_eq_sign() {
995 next();
996 if (peek() === ">") {
997 next();
998 return token("arrow", "=>");
999 } else {
1000 return read_operator("=");
1001 }
1002 }
1003
1004 function handle_dot() {
1005 next();
1006 if (is_digit(peek().charCodeAt(0))) {
1007 return read_num(".");
1008 }
1009 if (peek() === ".") {
1010 next(); // Consume second dot
1011 next(); // Consume third dot
1012 return token("expand", "...");
1013 }
1014
1015 return token("punc", ".");
1016 }
1017
1018 function read_word() {
1019 var word = read_name();
1020 if (prev_was_dot) return token("name", word);
1021 return KEYWORDS_ATOM.has(word) ? token("atom", word)
1022 : !KEYWORDS.has(word) ? token("name", word)
1023 : OPERATORS.has(word) ? token("operator", word)
1024 : token("keyword", word);
1025 }
1026
1027 function with_eof_error(eof_error, cont) {
1028 return function(x) {
1029 try {
1030 return cont(x);
1031 } catch(ex) {
1032 if (ex === EX_EOF) parse_error(eof_error);
1033 else throw ex;
1034 }
1035 };
1036 }
1037
1038 function next_token(force_regexp) {
1039 if (force_regexp != null)
1040 return read_regexp(force_regexp);
1041 if (shebang && S.pos == 0 && looking_at("#!")) {
1042 start_token();
1043 forward(2);
1044 skip_line_comment("comment5");
1045 }
1046 for (;;) {
1047 skip_whitespace();
1048 start_token();
1049 if (html5_comments) {
1050 if (looking_at("<!--")) {
1051 forward(4);
1052 skip_line_comment("comment3");
1053 continue;
1054 }
1055 if (looking_at("-->") && S.newline_before) {
1056 forward(3);
1057 skip_line_comment("comment4");
1058 continue;
1059 }
1060 }
1061 var ch = peek();
1062 if (!ch) return token("eof");
1063 var code = ch.charCodeAt(0);
1064 switch (code) {
1065 case 34: case 39: return read_string();
1066 case 46: return handle_dot();
1067 case 47: {
1068 var tok = handle_slash();
1069 if (tok === next_token) continue;
1070 return tok;
1071 }
1072 case 61: return handle_eq_sign();
1073 case 63: {
1074 if (!is_option_chain_op()) break; // Handled below
1075
1076 next(); // ?
1077 next(); // .
1078
1079 return token("punc", "?.");
1080 }
1081 case 96: return read_template_characters(true);
1082 case 123:
1083 S.brace_counter++;
1084 break;
1085 case 125:
1086 S.brace_counter--;
1087 if (S.template_braces.length > 0
1088 && S.template_braces[S.template_braces.length - 1] === S.brace_counter)
1089 return read_template_characters(false);
1090 break;
1091 }
1092 if (is_digit(code)) return read_num();
1093 if (PUNC_CHARS.has(ch)) return token("punc", next());
1094 if (OPERATOR_CHARS.has(ch)) return read_operator();
1095 if (code == 92 || is_identifier_start(ch)) return read_word();
1096 break;
1097 }
1098 parse_error("Unexpected character '" + ch + "'");
1099 }
1100
1101 next_token.next = next;
1102 next_token.peek = peek;
1103
1104 next_token.context = function(nc) {
1105 if (nc) S = nc;
1106 return S;
1107 };
1108
1109 next_token.add_directive = function(directive) {
1110 S.directive_stack[S.directive_stack.length - 1].push(directive);
1111
1112 if (S.directives[directive] === undefined) {
1113 S.directives[directive] = 1;
1114 } else {
1115 S.directives[directive]++;
1116 }
1117 };
1118
1119 next_token.push_directives_stack = function() {
1120 S.directive_stack.push([]);
1121 };
1122
1123 next_token.pop_directives_stack = function() {
1124 var directives = S.directive_stack[S.directive_stack.length - 1];
1125
1126 for (var i = 0; i < directives.length; i++) {
1127 S.directives[directives[i]]--;
1128 }
1129
1130 S.directive_stack.pop();
1131 };
1132
1133 next_token.has_directive = function(directive) {
1134 return S.directives[directive] > 0;
1135 };
1136
1137 return next_token;
1138
1139}
1140
1141/* -----[ Parser (constants) ]----- */
1142
1143var UNARY_PREFIX = makePredicate([
1144 "typeof",
1145 "void",
1146 "delete",
1147 "--",
1148 "++",
1149 "!",
1150 "~",
1151 "-",
1152 "+"
1153]);
1154
1155var UNARY_POSTFIX = makePredicate([ "--", "++" ]);
1156
1157var ASSIGNMENT = makePredicate([ "=", "+=", "-=", "/=", "*=", "**=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=" ]);
1158
1159var PRECEDENCE = (function(a, ret) {
1160 for (var i = 0; i < a.length; ++i) {
1161 var b = a[i];
1162 for (var j = 0; j < b.length; ++j) {
1163 ret[b[j]] = i + 1;
1164 }
1165 }
1166 return ret;
1167})(
1168 [
1169 ["||"],
1170 ["??"],
1171 ["&&"],
1172 ["|"],
1173 ["^"],
1174 ["&"],
1175 ["==", "===", "!=", "!=="],
1176 ["<", ">", "<=", ">=", "in", "instanceof"],
1177 [">>", "<<", ">>>"],
1178 ["+", "-"],
1179 ["*", "/", "%"],
1180 ["**"]
1181 ],
1182 {}
1183);
1184
1185var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "big_int", "string", "regexp", "name" ]);
1186
1187/* -----[ Parser ]----- */
1188
1189function parse($TEXT, options) {
1190 // maps start tokens to count of comments found outside of their parens
1191 // Example: /* I count */ ( /* I don't */ foo() )
1192 // Useful because comments_before property of call with parens outside
1193 // contains both comments inside and outside these parens. Used to find the
1194 // right #__PURE__ comments for an expression
1195 const outer_comments_before_counts = new Map();
1196
1197 options = defaults(options, {
1198 bare_returns : false,
1199 ecma : null, // Legacy
1200 expression : false,
1201 filename : null,
1202 html5_comments : true,
1203 module : false,
1204 shebang : true,
1205 strict : false,
1206 toplevel : null,
1207 }, true);
1208
1209 var S = {
1210 input : (typeof $TEXT == "string"
1211 ? tokenizer($TEXT, options.filename,
1212 options.html5_comments, options.shebang)
1213 : $TEXT),
1214 token : null,
1215 prev : null,
1216 peeked : null,
1217 in_function : 0,
1218 in_async : -1,
1219 in_generator : -1,
1220 in_directives : true,
1221 in_loop : 0,
1222 labels : []
1223 };
1224
1225 S.token = next();
1226
1227 function is(type, value) {
1228 return is_token(S.token, type, value);
1229 }
1230
1231 function peek() { return S.peeked || (S.peeked = S.input()); }
1232
1233 function next() {
1234 S.prev = S.token;
1235
1236 if (!S.peeked) peek();
1237 S.token = S.peeked;
1238 S.peeked = null;
1239 S.in_directives = S.in_directives && (
1240 S.token.type == "string" || is("punc", ";")
1241 );
1242 return S.token;
1243 }
1244
1245 function prev() {
1246 return S.prev;
1247 }
1248
1249 function croak(msg, line, col, pos) {
1250 var ctx = S.input.context();
1251 js_error(msg,
1252 ctx.filename,
1253 line != null ? line : ctx.tokline,
1254 col != null ? col : ctx.tokcol,
1255 pos != null ? pos : ctx.tokpos);
1256 }
1257
1258 function token_error(token, msg) {
1259 croak(msg, token.line, token.col);
1260 }
1261
1262 function unexpected(token) {
1263 if (token == null)
1264 token = S.token;
1265 token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")");
1266 }
1267
1268 function expect_token(type, val) {
1269 if (is(type, val)) {
1270 return next();
1271 }
1272 token_error(S.token, "Unexpected token " + S.token.type + " «" + S.token.value + "»" + ", expected " + type + " «" + val + "»");
1273 }
1274
1275 function expect(punc) { return expect_token("punc", punc); }
1276
1277 function has_newline_before(token) {
1278 return token.nlb || !token.comments_before.every((comment) => !comment.nlb);
1279 }
1280
1281 function can_insert_semicolon() {
1282 return !options.strict
1283 && (is("eof") || is("punc", "}") || has_newline_before(S.token));
1284 }
1285
1286 function is_in_generator() {
1287 return S.in_generator === S.in_function;
1288 }
1289
1290 function is_in_async() {
1291 return S.in_async === S.in_function;
1292 }
1293
1294 function semicolon(optional) {
1295 if (is("punc", ";")) next();
1296 else if (!optional && !can_insert_semicolon()) unexpected();
1297 }
1298
1299 function parenthesised() {
1300 expect("(");
1301 var exp = expression(true);
1302 expect(")");
1303 return exp;
1304 }
1305
1306 function embed_tokens(parser) {
1307 return function _embed_tokens_wrapper(...args) {
1308 const start = S.token;
1309 const expr = parser(...args);
1310 expr.start = start;
1311 expr.end = prev();
1312 return expr;
1313 };
1314 }
1315
1316 function handle_regexp() {
1317 if (is("operator", "/") || is("operator", "/=")) {
1318 S.peeked = null;
1319 S.token = S.input(S.token.value.substr(1)); // force regexp
1320 }
1321 }
1322
1323 var statement = embed_tokens(function statement(is_export_default, is_for_body, is_if_body) {
1324 handle_regexp();
1325 switch (S.token.type) {
1326 case "string":
1327 if (S.in_directives) {
1328 var token = peek();
1329 if (!S.token.raw.includes("\\")
1330 && (is_token(token, "punc", ";")
1331 || is_token(token, "punc", "}")
1332 || has_newline_before(token)
1333 || is_token(token, "eof"))) {
1334 S.input.add_directive(S.token.value);
1335 } else {
1336 S.in_directives = false;
1337 }
1338 }
1339 var dir = S.in_directives, stat = simple_statement();
1340 return dir && stat.body instanceof AST_String ? new AST_Directive(stat.body) : stat;
1341 case "template_head":
1342 case "num":
1343 case "big_int":
1344 case "regexp":
1345 case "operator":
1346 case "atom":
1347 return simple_statement();
1348
1349 case "name":
1350 if (S.token.value == "async" && is_token(peek(), "keyword", "function")) {
1351 next();
1352 next();
1353 if (is_for_body) {
1354 croak("functions are not allowed as the body of a loop");
1355 }
1356 return function_(AST_Defun, false, true, is_export_default);
1357 }
1358 if (S.token.value == "import" && !is_token(peek(), "punc", "(") && !is_token(peek(), "punc", ".")) {
1359 next();
1360 var node = import_();
1361 semicolon();
1362 return node;
1363 }
1364 return is_token(peek(), "punc", ":")
1365 ? labeled_statement()
1366 : simple_statement();
1367
1368 case "punc":
1369 switch (S.token.value) {
1370 case "{":
1371 return new AST_BlockStatement({
1372 start : S.token,
1373 body : block_(),
1374 end : prev()
1375 });
1376 case "[":
1377 case "(":
1378 return simple_statement();
1379 case ";":
1380 S.in_directives = false;
1381 next();
1382 return new AST_EmptyStatement();
1383 default:
1384 unexpected();
1385 }
1386
1387 case "keyword":
1388 switch (S.token.value) {
1389 case "break":
1390 next();
1391 return break_cont(AST_Break);
1392
1393 case "continue":
1394 next();
1395 return break_cont(AST_Continue);
1396
1397 case "debugger":
1398 next();
1399 semicolon();
1400 return new AST_Debugger();
1401
1402 case "do":
1403 next();
1404 var body = in_loop(statement);
1405 expect_token("keyword", "while");
1406 var condition = parenthesised();
1407 semicolon(true);
1408 return new AST_Do({
1409 body : body,
1410 condition : condition
1411 });
1412
1413 case "while":
1414 next();
1415 return new AST_While({
1416 condition : parenthesised(),
1417 body : in_loop(function() { return statement(false, true); })
1418 });
1419
1420 case "for":
1421 next();
1422 return for_();
1423
1424 case "class":
1425 next();
1426 if (is_for_body) {
1427 croak("classes are not allowed as the body of a loop");
1428 }
1429 if (is_if_body) {
1430 croak("classes are not allowed as the body of an if");
1431 }
1432 return class_(AST_DefClass);
1433
1434 case "function":
1435 next();
1436 if (is_for_body) {
1437 croak("functions are not allowed as the body of a loop");
1438 }
1439 return function_(AST_Defun, false, false, is_export_default);
1440
1441 case "if":
1442 next();
1443 return if_();
1444
1445 case "return":
1446 if (S.in_function == 0 && !options.bare_returns)
1447 croak("'return' outside of function");
1448 next();
1449 var value = null;
1450 if (is("punc", ";")) {
1451 next();
1452 } else if (!can_insert_semicolon()) {
1453 value = expression(true);
1454 semicolon();
1455 }
1456 return new AST_Return({
1457 value: value
1458 });
1459
1460 case "switch":
1461 next();
1462 return new AST_Switch({
1463 expression : parenthesised(),
1464 body : in_loop(switch_body_)
1465 });
1466
1467 case "throw":
1468 next();
1469 if (has_newline_before(S.token))
1470 croak("Illegal newline after 'throw'");
1471 var value = expression(true);
1472 semicolon();
1473 return new AST_Throw({
1474 value: value
1475 });
1476
1477 case "try":
1478 next();
1479 return try_();
1480
1481 case "var":
1482 next();
1483 var node = var_();
1484 semicolon();
1485 return node;
1486
1487 case "let":
1488 next();
1489 var node = let_();
1490 semicolon();
1491 return node;
1492
1493 case "const":
1494 next();
1495 var node = const_();
1496 semicolon();
1497 return node;
1498
1499 case "with":
1500 if (S.input.has_directive("use strict")) {
1501 croak("Strict mode may not include a with statement");
1502 }
1503 next();
1504 return new AST_With({
1505 expression : parenthesised(),
1506 body : statement()
1507 });
1508
1509 case "export":
1510 if (!is_token(peek(), "punc", "(")) {
1511 next();
1512 var node = export_();
1513 if (is("punc", ";")) semicolon();
1514 return node;
1515 }
1516 }
1517 }
1518 unexpected();
1519 });
1520
1521 function labeled_statement() {
1522 var label = as_symbol(AST_Label);
1523 if (label.name === "await" && is_in_async()) {
1524 token_error(S.prev, "await cannot be used as label inside async function");
1525 }
1526 if (S.labels.some((l) => l.name === label.name)) {
1527 // ECMA-262, 12.12: An ECMAScript program is considered
1528 // syntactically incorrect if it contains a
1529 // LabelledStatement that is enclosed by a
1530 // LabelledStatement with the same Identifier as label.
1531 croak("Label " + label.name + " defined twice");
1532 }
1533 expect(":");
1534 S.labels.push(label);
1535 var stat = statement();
1536 S.labels.pop();
1537 if (!(stat instanceof AST_IterationStatement)) {
1538 // check for `continue` that refers to this label.
1539 // those should be reported as syntax errors.
1540 // https://github.com/mishoo/UglifyJS2/issues/287
1541 label.references.forEach(function(ref) {
1542 if (ref instanceof AST_Continue) {
1543 ref = ref.label.start;
1544 croak("Continue label `" + label.name + "` refers to non-IterationStatement.",
1545 ref.line, ref.col, ref.pos);
1546 }
1547 });
1548 }
1549 return new AST_LabeledStatement({ body: stat, label: label });
1550 }
1551
1552 function simple_statement(tmp) {
1553 return new AST_SimpleStatement({ body: (tmp = expression(true), semicolon(), tmp) });
1554 }
1555
1556 function break_cont(type) {
1557 var label = null, ldef;
1558 if (!can_insert_semicolon()) {
1559 label = as_symbol(AST_LabelRef, true);
1560 }
1561 if (label != null) {
1562 ldef = S.labels.find((l) => l.name === label.name);
1563 if (!ldef)
1564 croak("Undefined label " + label.name);
1565 label.thedef = ldef;
1566 } else if (S.in_loop == 0)
1567 croak(type.TYPE + " not inside a loop or switch");
1568 semicolon();
1569 var stat = new type({ label: label });
1570 if (ldef) ldef.references.push(stat);
1571 return stat;
1572 }
1573
1574 function for_() {
1575 var for_await_error = "`for await` invalid in this context";
1576 var await_tok = S.token;
1577 if (await_tok.type == "name" && await_tok.value == "await") {
1578 if (!is_in_async()) {
1579 token_error(await_tok, for_await_error);
1580 }
1581 next();
1582 } else {
1583 await_tok = false;
1584 }
1585 expect("(");
1586 var init = null;
1587 if (!is("punc", ";")) {
1588 init =
1589 is("keyword", "var") ? (next(), var_(true)) :
1590 is("keyword", "let") ? (next(), let_(true)) :
1591 is("keyword", "const") ? (next(), const_(true)) :
1592 expression(true, true);
1593 var is_in = is("operator", "in");
1594 var is_of = is("name", "of");
1595 if (await_tok && !is_of) {
1596 token_error(await_tok, for_await_error);
1597 }
1598 if (is_in || is_of) {
1599 if (init instanceof AST_Definitions) {
1600 if (init.definitions.length > 1)
1601 token_error(init.start, "Only one variable declaration allowed in for..in loop");
1602 } else if (!(is_assignable(init) || (init = to_destructuring(init)) instanceof AST_Destructuring)) {
1603 token_error(init.start, "Invalid left-hand side in for..in loop");
1604 }
1605 next();
1606 if (is_in) {
1607 return for_in(init);
1608 } else {
1609 return for_of(init, !!await_tok);
1610 }
1611 }
1612 } else if (await_tok) {
1613 token_error(await_tok, for_await_error);
1614 }
1615 return regular_for(init);
1616 }
1617
1618 function regular_for(init) {
1619 expect(";");
1620 var test = is("punc", ";") ? null : expression(true);
1621 expect(";");
1622 var step = is("punc", ")") ? null : expression(true);
1623 expect(")");
1624 return new AST_For({
1625 init : init,
1626 condition : test,
1627 step : step,
1628 body : in_loop(function() { return statement(false, true); })
1629 });
1630 }
1631
1632 function for_of(init, is_await) {
1633 var lhs = init instanceof AST_Definitions ? init.definitions[0].name : null;
1634 var obj = expression(true);
1635 expect(")");
1636 return new AST_ForOf({
1637 await : is_await,
1638 init : init,
1639 name : lhs,
1640 object : obj,
1641 body : in_loop(function() { return statement(false, true); })
1642 });
1643 }
1644
1645 function for_in(init) {
1646 var obj = expression(true);
1647 expect(")");
1648 return new AST_ForIn({
1649 init : init,
1650 object : obj,
1651 body : in_loop(function() { return statement(false, true); })
1652 });
1653 }
1654
1655 var arrow_function = function(start, argnames, is_async) {
1656 if (has_newline_before(S.token)) {
1657 croak("Unexpected newline before arrow (=>)");
1658 }
1659
1660 expect_token("arrow", "=>");
1661
1662 var body = _function_body(is("punc", "{"), false, is_async);
1663
1664 var end =
1665 body instanceof Array && body.length ? body[body.length - 1].end :
1666 body instanceof Array ? start :
1667 body.end;
1668
1669 return new AST_Arrow({
1670 start : start,
1671 end : end,
1672 async : is_async,
1673 argnames : argnames,
1674 body : body
1675 });
1676 };
1677
1678 var function_ = function(ctor, is_generator_property, is_async, is_export_default) {
1679 var in_statement = ctor === AST_Defun;
1680 var is_generator = is("operator", "*");
1681 if (is_generator) {
1682 next();
1683 }
1684
1685 var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null;
1686 if (in_statement && !name) {
1687 if (is_export_default) {
1688 ctor = AST_Function;
1689 } else {
1690 unexpected();
1691 }
1692 }
1693
1694 if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration))
1695 unexpected(prev());
1696
1697 var args = [];
1698 var body = _function_body(true, is_generator || is_generator_property, is_async, name, args);
1699 return new ctor({
1700 start : args.start,
1701 end : body.end,
1702 is_generator: is_generator,
1703 async : is_async,
1704 name : name,
1705 argnames: args,
1706 body : body
1707 });
1708 };
1709
1710 function track_used_binding_identifiers(is_parameter, strict) {
1711 var parameters = new Set();
1712 var duplicate = false;
1713 var default_assignment = false;
1714 var spread = false;
1715 var strict_mode = !!strict;
1716 var tracker = {
1717 add_parameter: function(token) {
1718 if (parameters.has(token.value)) {
1719 if (duplicate === false) {
1720 duplicate = token;
1721 }
1722 tracker.check_strict();
1723 } else {
1724 parameters.add(token.value);
1725 if (is_parameter) {
1726 switch (token.value) {
1727 case "arguments":
1728 case "eval":
1729 case "yield":
1730 if (strict_mode) {
1731 token_error(token, "Unexpected " + token.value + " identifier as parameter inside strict mode");
1732 }
1733 break;
1734 default:
1735 if (RESERVED_WORDS.has(token.value)) {
1736 unexpected();
1737 }
1738 }
1739 }
1740 }
1741 },
1742 mark_default_assignment: function(token) {
1743 if (default_assignment === false) {
1744 default_assignment = token;
1745 }
1746 },
1747 mark_spread: function(token) {
1748 if (spread === false) {
1749 spread = token;
1750 }
1751 },
1752 mark_strict_mode: function() {
1753 strict_mode = true;
1754 },
1755 is_strict: function() {
1756 return default_assignment !== false || spread !== false || strict_mode;
1757 },
1758 check_strict: function() {
1759 if (tracker.is_strict() && duplicate !== false) {
1760 token_error(duplicate, "Parameter " + duplicate.value + " was used already");
1761 }
1762 }
1763 };
1764
1765 return tracker;
1766 }
1767
1768 function parameters(params) {
1769 var used_parameters = track_used_binding_identifiers(true, S.input.has_directive("use strict"));
1770
1771 expect("(");
1772
1773 while (!is("punc", ")")) {
1774 var param = parameter(used_parameters);
1775 params.push(param);
1776
1777 if (!is("punc", ")")) {
1778 expect(",");
1779 }
1780
1781 if (param instanceof AST_Expansion) {
1782 break;
1783 }
1784 }
1785
1786 next();
1787 }
1788
1789 function parameter(used_parameters, symbol_type) {
1790 var param;
1791 var expand = false;
1792 if (used_parameters === undefined) {
1793 used_parameters = track_used_binding_identifiers(true, S.input.has_directive("use strict"));
1794 }
1795 if (is("expand", "...")) {
1796 expand = S.token;
1797 used_parameters.mark_spread(S.token);
1798 next();
1799 }
1800 param = binding_element(used_parameters, symbol_type);
1801
1802 if (is("operator", "=") && expand === false) {
1803 used_parameters.mark_default_assignment(S.token);
1804 next();
1805 param = new AST_DefaultAssign({
1806 start: param.start,
1807 left: param,
1808 operator: "=",
1809 right: expression(false),
1810 end: S.token
1811 });
1812 }
1813
1814 if (expand !== false) {
1815 if (!is("punc", ")")) {
1816 unexpected();
1817 }
1818 param = new AST_Expansion({
1819 start: expand,
1820 expression: param,
1821 end: expand
1822 });
1823 }
1824 used_parameters.check_strict();
1825
1826 return param;
1827 }
1828
1829 function binding_element(used_parameters, symbol_type) {
1830 var elements = [];
1831 var first = true;
1832 var is_expand = false;
1833 var expand_token;
1834 var first_token = S.token;
1835 if (used_parameters === undefined) {
1836 used_parameters = track_used_binding_identifiers(false, S.input.has_directive("use strict"));
1837 }
1838 symbol_type = symbol_type === undefined ? AST_SymbolFunarg : symbol_type;
1839 if (is("punc", "[")) {
1840 next();
1841 while (!is("punc", "]")) {
1842 if (first) {
1843 first = false;
1844 } else {
1845 expect(",");
1846 }
1847
1848 if (is("expand", "...")) {
1849 is_expand = true;
1850 expand_token = S.token;
1851 used_parameters.mark_spread(S.token);
1852 next();
1853 }
1854 if (is("punc")) {
1855 switch (S.token.value) {
1856 case ",":
1857 elements.push(new AST_Hole({
1858 start: S.token,
1859 end: S.token
1860 }));
1861 continue;
1862 case "]": // Trailing comma after last element
1863 break;
1864 case "[":
1865 case "{":
1866 elements.push(binding_element(used_parameters, symbol_type));
1867 break;
1868 default:
1869 unexpected();
1870 }
1871 } else if (is("name")) {
1872 used_parameters.add_parameter(S.token);
1873 elements.push(as_symbol(symbol_type));
1874 } else {
1875 croak("Invalid function parameter");
1876 }
1877 if (is("operator", "=") && is_expand === false) {
1878 used_parameters.mark_default_assignment(S.token);
1879 next();
1880 elements[elements.length - 1] = new AST_DefaultAssign({
1881 start: elements[elements.length - 1].start,
1882 left: elements[elements.length - 1],
1883 operator: "=",
1884 right: expression(false),
1885 end: S.token
1886 });
1887 }
1888 if (is_expand) {
1889 if (!is("punc", "]")) {
1890 croak("Rest element must be last element");
1891 }
1892 elements[elements.length - 1] = new AST_Expansion({
1893 start: expand_token,
1894 expression: elements[elements.length - 1],
1895 end: expand_token
1896 });
1897 }
1898 }
1899 expect("]");
1900 used_parameters.check_strict();
1901 return new AST_Destructuring({
1902 start: first_token,
1903 names: elements,
1904 is_array: true,
1905 end: prev()
1906 });
1907 } else if (is("punc", "{")) {
1908 next();
1909 while (!is("punc", "}")) {
1910 if (first) {
1911 first = false;
1912 } else {
1913 expect(",");
1914 }
1915 if (is("expand", "...")) {
1916 is_expand = true;
1917 expand_token = S.token;
1918 used_parameters.mark_spread(S.token);
1919 next();
1920 }
1921 if (is("name") && (is_token(peek(), "punc") || is_token(peek(), "operator")) && [",", "}", "="].includes(peek().value)) {
1922 used_parameters.add_parameter(S.token);
1923 var start = prev();
1924 var value = as_symbol(symbol_type);
1925 if (is_expand) {
1926 elements.push(new AST_Expansion({
1927 start: expand_token,
1928 expression: value,
1929 end: value.end,
1930 }));
1931 } else {
1932 elements.push(new AST_ObjectKeyVal({
1933 start: start,
1934 key: value.name,
1935 value: value,
1936 end: value.end,
1937 }));
1938 }
1939 } else if (is("punc", "}")) {
1940 continue; // Allow trailing hole
1941 } else {
1942 var property_token = S.token;
1943 var property = as_property_name();
1944 if (property === null) {
1945 unexpected(prev());
1946 } else if (prev().type === "name" && !is("punc", ":")) {
1947 elements.push(new AST_ObjectKeyVal({
1948 start: prev(),
1949 key: property,
1950 value: new symbol_type({
1951 start: prev(),
1952 name: property,
1953 end: prev()
1954 }),
1955 end: prev()
1956 }));
1957 } else {
1958 expect(":");
1959 elements.push(new AST_ObjectKeyVal({
1960 start: property_token,
1961 quote: property_token.quote,
1962 key: property,
1963 value: binding_element(used_parameters, symbol_type),
1964 end: prev()
1965 }));
1966 }
1967 }
1968 if (is_expand) {
1969 if (!is("punc", "}")) {
1970 croak("Rest element must be last element");
1971 }
1972 } else if (is("operator", "=")) {
1973 used_parameters.mark_default_assignment(S.token);
1974 next();
1975 elements[elements.length - 1].value = new AST_DefaultAssign({
1976 start: elements[elements.length - 1].value.start,
1977 left: elements[elements.length - 1].value,
1978 operator: "=",
1979 right: expression(false),
1980 end: S.token
1981 });
1982 }
1983 }
1984 expect("}");
1985 used_parameters.check_strict();
1986 return new AST_Destructuring({
1987 start: first_token,
1988 names: elements,
1989 is_array: false,
1990 end: prev()
1991 });
1992 } else if (is("name")) {
1993 used_parameters.add_parameter(S.token);
1994 return as_symbol(symbol_type);
1995 } else {
1996 croak("Invalid function parameter");
1997 }
1998 }
1999
2000 function params_or_seq_(allow_arrows, maybe_sequence) {
2001 var spread_token;
2002 var invalid_sequence;
2003 var trailing_comma;
2004 var a = [];
2005 expect("(");
2006 while (!is("punc", ")")) {
2007 if (spread_token) unexpected(spread_token);
2008 if (is("expand", "...")) {
2009 spread_token = S.token;
2010 if (maybe_sequence) invalid_sequence = S.token;
2011 next();
2012 a.push(new AST_Expansion({
2013 start: prev(),
2014 expression: expression(),
2015 end: S.token,
2016 }));
2017 } else {
2018 a.push(expression());
2019 }
2020 if (!is("punc", ")")) {
2021 expect(",");
2022 if (is("punc", ")")) {
2023 trailing_comma = prev();
2024 if (maybe_sequence) invalid_sequence = trailing_comma;
2025 }
2026 }
2027 }
2028 expect(")");
2029 if (allow_arrows && is("arrow", "=>")) {
2030 if (spread_token && trailing_comma) unexpected(trailing_comma);
2031 } else if (invalid_sequence) {
2032 unexpected(invalid_sequence);
2033 }
2034 return a;
2035 }
2036
2037 function _function_body(block, generator, is_async, name, args) {
2038 var loop = S.in_loop;
2039 var labels = S.labels;
2040 var current_generator = S.in_generator;
2041 var current_async = S.in_async;
2042 ++S.in_function;
2043 if (generator)
2044 S.in_generator = S.in_function;
2045 if (is_async)
2046 S.in_async = S.in_function;
2047 if (args) parameters(args);
2048 if (block)
2049 S.in_directives = true;
2050 S.in_loop = 0;
2051 S.labels = [];
2052 if (block) {
2053 S.input.push_directives_stack();
2054 var a = block_();
2055 if (name) _verify_symbol(name);
2056 if (args) args.forEach(_verify_symbol);
2057 S.input.pop_directives_stack();
2058 } else {
2059 var a = [new AST_Return({
2060 start: S.token,
2061 value: expression(false),
2062 end: S.token
2063 })];
2064 }
2065 --S.in_function;
2066 S.in_loop = loop;
2067 S.labels = labels;
2068 S.in_generator = current_generator;
2069 S.in_async = current_async;
2070 return a;
2071 }
2072
2073 function _await_expression() {
2074 // Previous token must be "await" and not be interpreted as an identifier
2075 if (!is_in_async()) {
2076 croak("Unexpected await expression outside async function",
2077 S.prev.line, S.prev.col, S.prev.pos);
2078 }
2079 // the await expression is parsed as a unary expression in Babel
2080 return new AST_Await({
2081 start: prev(),
2082 end: S.token,
2083 expression : maybe_unary(true),
2084 });
2085 }
2086
2087 function _yield_expression() {
2088 // Previous token must be keyword yield and not be interpret as an identifier
2089 if (!is_in_generator()) {
2090 croak("Unexpected yield expression outside generator function",
2091 S.prev.line, S.prev.col, S.prev.pos);
2092 }
2093 var start = S.token;
2094 var star = false;
2095 var has_expression = true;
2096
2097 // Attempt to get expression or star (and then the mandatory expression)
2098 // behind yield on the same line.
2099 //
2100 // If nothing follows on the same line of the yieldExpression,
2101 // it should default to the value `undefined` for yield to return.
2102 // In that case, the `undefined` stored as `null` in ast.
2103 //
2104 // Note 1: It isn't allowed for yield* to close without an expression
2105 // Note 2: If there is a nlb between yield and star, it is interpret as
2106 // yield <explicit undefined> <inserted automatic semicolon> *
2107 if (can_insert_semicolon() ||
2108 (is("punc") && PUNC_AFTER_EXPRESSION.has(S.token.value))) {
2109 has_expression = false;
2110
2111 } else if (is("operator", "*")) {
2112 star = true;
2113 next();
2114 }
2115
2116 return new AST_Yield({
2117 start : start,
2118 is_star : star,
2119 expression : has_expression ? expression() : null,
2120 end : prev()
2121 });
2122 }
2123
2124 function if_() {
2125 var cond = parenthesised(), body = statement(false, false, true), belse = null;
2126 if (is("keyword", "else")) {
2127 next();
2128 belse = statement(false, false, true);
2129 }
2130 return new AST_If({
2131 condition : cond,
2132 body : body,
2133 alternative : belse
2134 });
2135 }
2136
2137 function block_() {
2138 expect("{");
2139 var a = [];
2140 while (!is("punc", "}")) {
2141 if (is("eof")) unexpected();
2142 a.push(statement());
2143 }
2144 next();
2145 return a;
2146 }
2147
2148 function switch_body_() {
2149 expect("{");
2150 var a = [], cur = null, branch = null, tmp;
2151 while (!is("punc", "}")) {
2152 if (is("eof")) unexpected();
2153 if (is("keyword", "case")) {
2154 if (branch) branch.end = prev();
2155 cur = [];
2156 branch = new AST_Case({
2157 start : (tmp = S.token, next(), tmp),
2158 expression : expression(true),
2159 body : cur
2160 });
2161 a.push(branch);
2162 expect(":");
2163 } else if (is("keyword", "default")) {
2164 if (branch) branch.end = prev();
2165 cur = [];
2166 branch = new AST_Default({
2167 start : (tmp = S.token, next(), expect(":"), tmp),
2168 body : cur
2169 });
2170 a.push(branch);
2171 } else {
2172 if (!cur) unexpected();
2173 cur.push(statement());
2174 }
2175 }
2176 if (branch) branch.end = prev();
2177 next();
2178 return a;
2179 }
2180
2181 function try_() {
2182 var body = block_(), bcatch = null, bfinally = null;
2183 if (is("keyword", "catch")) {
2184 var start = S.token;
2185 next();
2186 if (is("punc", "{")) {
2187 var name = null;
2188 } else {
2189 expect("(");
2190 var name = parameter(undefined, AST_SymbolCatch);
2191 expect(")");
2192 }
2193 bcatch = new AST_Catch({
2194 start : start,
2195 argname : name,
2196 body : block_(),
2197 end : prev()
2198 });
2199 }
2200 if (is("keyword", "finally")) {
2201 var start = S.token;
2202 next();
2203 bfinally = new AST_Finally({
2204 start : start,
2205 body : block_(),
2206 end : prev()
2207 });
2208 }
2209 if (!bcatch && !bfinally)
2210 croak("Missing catch/finally blocks");
2211 return new AST_Try({
2212 body : body,
2213 bcatch : bcatch,
2214 bfinally : bfinally
2215 });
2216 }
2217
2218 function vardefs(no_in, kind) {
2219 var a = [];
2220 var def;
2221 for (;;) {
2222 var sym_type =
2223 kind === "var" ? AST_SymbolVar :
2224 kind === "const" ? AST_SymbolConst :
2225 kind === "let" ? AST_SymbolLet : null;
2226 if (is("punc", "{") || is("punc", "[")) {
2227 def = new AST_VarDef({
2228 start: S.token,
2229 name: binding_element(undefined ,sym_type),
2230 value: is("operator", "=") ? (expect_token("operator", "="), expression(false, no_in)) : null,
2231 end: prev()
2232 });
2233 } else {
2234 def = new AST_VarDef({
2235 start : S.token,
2236 name : as_symbol(sym_type),
2237 value : is("operator", "=")
2238 ? (next(), expression(false, no_in))
2239 : !no_in && kind === "const"
2240 ? croak("Missing initializer in const declaration") : null,
2241 end : prev()
2242 });
2243 if (def.name.name == "import") croak("Unexpected token: import");
2244 }
2245 a.push(def);
2246 if (!is("punc", ","))
2247 break;
2248 next();
2249 }
2250 return a;
2251 }
2252
2253 var var_ = function(no_in) {
2254 return new AST_Var({
2255 start : prev(),
2256 definitions : vardefs(no_in, "var"),
2257 end : prev()
2258 });
2259 };
2260
2261 var let_ = function(no_in) {
2262 return new AST_Let({
2263 start : prev(),
2264 definitions : vardefs(no_in, "let"),
2265 end : prev()
2266 });
2267 };
2268
2269 var const_ = function(no_in) {
2270 return new AST_Const({
2271 start : prev(),
2272 definitions : vardefs(no_in, "const"),
2273 end : prev()
2274 });
2275 };
2276
2277 var new_ = function(allow_calls) {
2278 var start = S.token;
2279 expect_token("operator", "new");
2280 if (is("punc", ".")) {
2281 next();
2282 expect_token("name", "target");
2283 return subscripts(new AST_NewTarget({
2284 start : start,
2285 end : prev()
2286 }), allow_calls);
2287 }
2288 var newexp = expr_atom(false), args;
2289 if (is("punc", "(")) {
2290 next();
2291 args = expr_list(")", true);
2292 } else {
2293 args = [];
2294 }
2295 var call = new AST_New({
2296 start : start,
2297 expression : newexp,
2298 args : args,
2299 end : prev()
2300 });
2301 annotate(call);
2302 return subscripts(call, allow_calls);
2303 };
2304
2305 function as_atom_node() {
2306 var tok = S.token, ret;
2307 switch (tok.type) {
2308 case "name":
2309 ret = _make_symbol(AST_SymbolRef);
2310 break;
2311 case "num":
2312 ret = new AST_Number({ start: tok, end: tok, value: tok.value });
2313 break;
2314 case "big_int":
2315 ret = new AST_BigInt({ start: tok, end: tok, value: tok.value });
2316 break;
2317 case "string":
2318 ret = new AST_String({
2319 start : tok,
2320 end : tok,
2321 value : tok.value,
2322 quote : tok.quote
2323 });
2324 break;
2325 case "regexp":
2326 ret = new AST_RegExp({ start: tok, end: tok, value: tok.value });
2327 break;
2328 case "atom":
2329 switch (tok.value) {
2330 case "false":
2331 ret = new AST_False({ start: tok, end: tok });
2332 break;
2333 case "true":
2334 ret = new AST_True({ start: tok, end: tok });
2335 break;
2336 case "null":
2337 ret = new AST_Null({ start: tok, end: tok });
2338 break;
2339 }
2340 break;
2341 }
2342 next();
2343 return ret;
2344 }
2345
2346 function to_fun_args(ex, default_seen_above) {
2347 var insert_default = function(ex, default_value) {
2348 if (default_value) {
2349 return new AST_DefaultAssign({
2350 start: ex.start,
2351 left: ex,
2352 operator: "=",
2353 right: default_value,
2354 end: default_value.end
2355 });
2356 }
2357 return ex;
2358 };
2359 if (ex instanceof AST_Object) {
2360 return insert_default(new AST_Destructuring({
2361 start: ex.start,
2362 end: ex.end,
2363 is_array: false,
2364 names: ex.properties.map(prop => to_fun_args(prop))
2365 }), default_seen_above);
2366 } else if (ex instanceof AST_ObjectKeyVal) {
2367 ex.value = to_fun_args(ex.value);
2368 return insert_default(ex, default_seen_above);
2369 } else if (ex instanceof AST_Hole) {
2370 return ex;
2371 } else if (ex instanceof AST_Destructuring) {
2372 ex.names = ex.names.map(name => to_fun_args(name));
2373 return insert_default(ex, default_seen_above);
2374 } else if (ex instanceof AST_SymbolRef) {
2375 return insert_default(new AST_SymbolFunarg({
2376 name: ex.name,
2377 start: ex.start,
2378 end: ex.end
2379 }), default_seen_above);
2380 } else if (ex instanceof AST_Expansion) {
2381 ex.expression = to_fun_args(ex.expression);
2382 return insert_default(ex, default_seen_above);
2383 } else if (ex instanceof AST_Array) {
2384 return insert_default(new AST_Destructuring({
2385 start: ex.start,
2386 end: ex.end,
2387 is_array: true,
2388 names: ex.elements.map(elm => to_fun_args(elm))
2389 }), default_seen_above);
2390 } else if (ex instanceof AST_Assign) {
2391 return insert_default(to_fun_args(ex.left, ex.right), default_seen_above);
2392 } else if (ex instanceof AST_DefaultAssign) {
2393 ex.left = to_fun_args(ex.left);
2394 return ex;
2395 } else {
2396 croak("Invalid function parameter", ex.start.line, ex.start.col);
2397 }
2398 }
2399
2400 var expr_atom = function(allow_calls, allow_arrows) {
2401 if (is("operator", "new")) {
2402 return new_(allow_calls);
2403 }
2404 if (is("operator", "import")) {
2405 return import_meta();
2406 }
2407 var start = S.token;
2408 var peeked;
2409 var async = is("name", "async")
2410 && (peeked = peek()).value != "["
2411 && peeked.type != "arrow"
2412 && as_atom_node();
2413 if (is("punc")) {
2414 switch (S.token.value) {
2415 case "(":
2416 if (async && !allow_calls) break;
2417 var exprs = params_or_seq_(allow_arrows, !async);
2418 if (allow_arrows && is("arrow", "=>")) {
2419 return arrow_function(start, exprs.map(e => to_fun_args(e)), !!async);
2420 }
2421 var ex = async ? new AST_Call({
2422 expression: async,
2423 args: exprs
2424 }) : exprs.length == 1 ? exprs[0] : new AST_Sequence({
2425 expressions: exprs
2426 });
2427 if (ex.start) {
2428 const outer_comments_before = start.comments_before.length;
2429 outer_comments_before_counts.set(start, outer_comments_before);
2430 ex.start.comments_before.unshift(...start.comments_before);
2431 start.comments_before = ex.start.comments_before;
2432 if (outer_comments_before == 0 && start.comments_before.length > 0) {
2433 var comment = start.comments_before[0];
2434 if (!comment.nlb) {
2435 comment.nlb = start.nlb;
2436 start.nlb = false;
2437 }
2438 }
2439 start.comments_after = ex.start.comments_after;
2440 }
2441 ex.start = start;
2442 var end = prev();
2443 if (ex.end) {
2444 end.comments_before = ex.end.comments_before;
2445 ex.end.comments_after.push(...end.comments_after);
2446 end.comments_after = ex.end.comments_after;
2447 }
2448 ex.end = end;
2449 if (ex instanceof AST_Call) annotate(ex);
2450 return subscripts(ex, allow_calls);
2451 case "[":
2452 return subscripts(array_(), allow_calls);
2453 case "{":
2454 return subscripts(object_or_destructuring_(), allow_calls);
2455 }
2456 if (!async) unexpected();
2457 }
2458 if (allow_arrows && is("name") && is_token(peek(), "arrow")) {
2459 var param = new AST_SymbolFunarg({
2460 name: S.token.value,
2461 start: start,
2462 end: start,
2463 });
2464 next();
2465 return arrow_function(start, [param], !!async);
2466 }
2467 if (is("keyword", "function")) {
2468 next();
2469 var func = function_(AST_Function, false, !!async);
2470 func.start = start;
2471 func.end = prev();
2472 return subscripts(func, allow_calls);
2473 }
2474 if (async) return subscripts(async, allow_calls);
2475 if (is("keyword", "class")) {
2476 next();
2477 var cls = class_(AST_ClassExpression);
2478 cls.start = start;
2479 cls.end = prev();
2480 return subscripts(cls, allow_calls);
2481 }
2482 if (is("template_head")) {
2483 return subscripts(template_string(), allow_calls);
2484 }
2485 if (ATOMIC_START_TOKEN.has(S.token.type)) {
2486 return subscripts(as_atom_node(), allow_calls);
2487 }
2488 unexpected();
2489 };
2490
2491 function template_string() {
2492 var segments = [], start = S.token;
2493
2494 segments.push(new AST_TemplateSegment({
2495 start: S.token,
2496 raw: S.token.raw,
2497 value: S.token.value,
2498 end: S.token
2499 }));
2500 while (!S.token.end) {
2501 next();
2502 handle_regexp();
2503 segments.push(expression(true));
2504
2505 if (!is_token("template_substitution")) {
2506 unexpected();
2507 }
2508
2509 segments.push(new AST_TemplateSegment({
2510 start: S.token,
2511 raw: S.token.raw,
2512 value: S.token.value,
2513 end: S.token
2514 }));
2515 }
2516 next();
2517
2518 return new AST_TemplateString({
2519 start: start,
2520 segments: segments,
2521 end: S.token
2522 });
2523 }
2524
2525 function expr_list(closing, allow_trailing_comma, allow_empty) {
2526 var first = true, a = [];
2527 while (!is("punc", closing)) {
2528 if (first) first = false; else expect(",");
2529 if (allow_trailing_comma && is("punc", closing)) break;
2530 if (is("punc", ",") && allow_empty) {
2531 a.push(new AST_Hole({ start: S.token, end: S.token }));
2532 } else if (is("expand", "...")) {
2533 next();
2534 a.push(new AST_Expansion({start: prev(), expression: expression(),end: S.token}));
2535 } else {
2536 a.push(expression(false));
2537 }
2538 }
2539 next();
2540 return a;
2541 }
2542
2543 var array_ = embed_tokens(function() {
2544 expect("[");
2545 return new AST_Array({
2546 elements: expr_list("]", !options.strict, true)
2547 });
2548 });
2549
2550 var create_accessor = embed_tokens((is_generator, is_async) => {
2551 return function_(AST_Accessor, is_generator, is_async);
2552 });
2553
2554 var object_or_destructuring_ = embed_tokens(function object_or_destructuring_() {
2555 var start = S.token, first = true, a = [];
2556 expect("{");
2557 while (!is("punc", "}")) {
2558 if (first) first = false; else expect(",");
2559 if (!options.strict && is("punc", "}"))
2560 // allow trailing comma
2561 break;
2562
2563 start = S.token;
2564 if (start.type == "expand") {
2565 next();
2566 a.push(new AST_Expansion({
2567 start: start,
2568 expression: expression(false),
2569 end: prev(),
2570 }));
2571 continue;
2572 }
2573
2574 var name = as_property_name();
2575 var value;
2576
2577 // Check property and fetch value
2578 if (!is("punc", ":")) {
2579 var concise = concise_method_or_getset(name, start);
2580 if (concise) {
2581 a.push(concise);
2582 continue;
2583 }
2584
2585 value = new AST_SymbolRef({
2586 start: prev(),
2587 name: name,
2588 end: prev()
2589 });
2590 } else if (name === null) {
2591 unexpected(prev());
2592 } else {
2593 next(); // `:` - see first condition
2594 value = expression(false);
2595 }
2596
2597 // Check for default value and alter value accordingly if necessary
2598 if (is("operator", "=")) {
2599 next();
2600 value = new AST_Assign({
2601 start: start,
2602 left: value,
2603 operator: "=",
2604 right: expression(false),
2605 end: prev()
2606 });
2607 }
2608
2609 // Create property
2610 a.push(new AST_ObjectKeyVal({
2611 start: start,
2612 quote: start.quote,
2613 key: name instanceof AST_Node ? name : "" + name,
2614 value: value,
2615 end: prev()
2616 }));
2617 }
2618 next();
2619 return new AST_Object({ properties: a });
2620 });
2621
2622 function class_(KindOfClass) {
2623 var start, method, class_name, extends_, a = [];
2624
2625 S.input.push_directives_stack(); // Push directive stack, but not scope stack
2626 S.input.add_directive("use strict");
2627
2628 if (S.token.type == "name" && S.token.value != "extends") {
2629 class_name = as_symbol(KindOfClass === AST_DefClass ? AST_SymbolDefClass : AST_SymbolClass);
2630 }
2631
2632 if (KindOfClass === AST_DefClass && !class_name) {
2633 unexpected();
2634 }
2635
2636 if (S.token.value == "extends") {
2637 next();
2638 extends_ = expression(true);
2639 }
2640
2641 expect("{");
2642
2643 while (is("punc", ";")) { next(); } // Leading semicolons are okay in class bodies.
2644 while (!is("punc", "}")) {
2645 start = S.token;
2646 method = concise_method_or_getset(as_property_name(), start, true);
2647 if (!method) { unexpected(); }
2648 a.push(method);
2649 while (is("punc", ";")) { next(); }
2650 }
2651
2652 S.input.pop_directives_stack();
2653
2654 next();
2655
2656 return new KindOfClass({
2657 start: start,
2658 name: class_name,
2659 extends: extends_,
2660 properties: a,
2661 end: prev(),
2662 });
2663 }
2664
2665 function concise_method_or_getset(name, start, is_class) {
2666 var get_method_name_ast = function(name, start) {
2667 if (typeof name === "string" || typeof name === "number") {
2668 return new AST_SymbolMethod({
2669 start,
2670 name: "" + name,
2671 end: prev()
2672 });
2673 } else if (name === null) {
2674 unexpected();
2675 }
2676 return name;
2677 };
2678 const get_class_property_key_ast = (name) => {
2679 if (typeof name === "string" || typeof name === "number") {
2680 return new AST_SymbolClassProperty({
2681 start: property_token,
2682 end: property_token,
2683 name: "" + name
2684 });
2685 } else if (name === null) {
2686 unexpected();
2687 }
2688 return name;
2689 };
2690 var is_async = false;
2691 var is_static = false;
2692 var is_generator = false;
2693 var property_token = start;
2694 if (is_class && name === "static" && !is("punc", "(")) {
2695 is_static = true;
2696 property_token = S.token;
2697 name = as_property_name();
2698 }
2699 if (name === "async" && !is("punc", "(") && !is("punc", ",") && !is("punc", "}") && !is("operator", "=")) {
2700 is_async = true;
2701 property_token = S.token;
2702 name = as_property_name();
2703 }
2704 if (name === null) {
2705 is_generator = true;
2706 property_token = S.token;
2707 name = as_property_name();
2708 if (name === null) {
2709 unexpected();
2710 }
2711 }
2712 if (is("punc", "(")) {
2713 name = get_method_name_ast(name, start);
2714 var node = new AST_ConciseMethod({
2715 start : start,
2716 static : is_static,
2717 is_generator: is_generator,
2718 async : is_async,
2719 key : name,
2720 quote : name instanceof AST_SymbolMethod ?
2721 property_token.quote : undefined,
2722 value : create_accessor(is_generator, is_async),
2723 end : prev()
2724 });
2725 return node;
2726 }
2727 const setter_token = S.token;
2728 if (name == "get") {
2729 if (!is("punc") || is("punc", "[")) {
2730 name = get_method_name_ast(as_property_name(), start);
2731 return new AST_ObjectGetter({
2732 start : start,
2733 static: is_static,
2734 key : name,
2735 quote : name instanceof AST_SymbolMethod ?
2736 setter_token.quote : undefined,
2737 value : create_accessor(),
2738 end : prev()
2739 });
2740 }
2741 } else if (name == "set") {
2742 if (!is("punc") || is("punc", "[")) {
2743 name = get_method_name_ast(as_property_name(), start);
2744 return new AST_ObjectSetter({
2745 start : start,
2746 static: is_static,
2747 key : name,
2748 quote : name instanceof AST_SymbolMethod ?
2749 setter_token.quote : undefined,
2750 value : create_accessor(),
2751 end : prev()
2752 });
2753 }
2754 }
2755 if (is_class) {
2756 const key = get_class_property_key_ast(name);
2757 const quote = key instanceof AST_SymbolClassProperty
2758 ? property_token.quote
2759 : undefined;
2760 if (is("operator", "=")) {
2761 next();
2762 return new AST_ClassProperty({
2763 start,
2764 static: is_static,
2765 quote,
2766 key,
2767 value: expression(false),
2768 end: prev()
2769 });
2770 } else if (is("name") || is("punc", ";") || is("punc", "}")) {
2771 return new AST_ClassProperty({
2772 start,
2773 static: is_static,
2774 quote,
2775 key,
2776 end: prev()
2777 });
2778 }
2779 }
2780 }
2781
2782 function import_() {
2783 var start = prev();
2784
2785 var imported_name;
2786 var imported_names;
2787 if (is("name")) {
2788 imported_name = as_symbol(AST_SymbolImport);
2789 }
2790
2791 if (is("punc", ",")) {
2792 next();
2793 }
2794
2795 imported_names = map_names(true);
2796
2797 if (imported_names || imported_name) {
2798 expect_token("name", "from");
2799 }
2800 var mod_str = S.token;
2801 if (mod_str.type !== "string") {
2802 unexpected();
2803 }
2804 next();
2805 return new AST_Import({
2806 start: start,
2807 imported_name: imported_name,
2808 imported_names: imported_names,
2809 module_name: new AST_String({
2810 start: mod_str,
2811 value: mod_str.value,
2812 quote: mod_str.quote,
2813 end: mod_str,
2814 }),
2815 end: S.token,
2816 });
2817 }
2818
2819 function import_meta() {
2820 var start = S.token;
2821 expect_token("operator", "import");
2822 expect_token("punc", ".");
2823 expect_token("name", "meta");
2824 return subscripts(new AST_ImportMeta({
2825 start: start,
2826 end: prev()
2827 }), false);
2828 }
2829
2830 function map_name(is_import) {
2831 function make_symbol(type) {
2832 return new type({
2833 name: as_property_name(),
2834 start: prev(),
2835 end: prev()
2836 });
2837 }
2838
2839 var foreign_type = is_import ? AST_SymbolImportForeign : AST_SymbolExportForeign;
2840 var type = is_import ? AST_SymbolImport : AST_SymbolExport;
2841 var start = S.token;
2842 var foreign_name;
2843 var name;
2844
2845 if (is_import) {
2846 foreign_name = make_symbol(foreign_type);
2847 } else {
2848 name = make_symbol(type);
2849 }
2850 if (is("name", "as")) {
2851 next(); // The "as" word
2852 if (is_import) {
2853 name = make_symbol(type);
2854 } else {
2855 foreign_name = make_symbol(foreign_type);
2856 }
2857 } else if (is_import) {
2858 name = new type(foreign_name);
2859 } else {
2860 foreign_name = new foreign_type(name);
2861 }
2862
2863 return new AST_NameMapping({
2864 start: start,
2865 foreign_name: foreign_name,
2866 name: name,
2867 end: prev(),
2868 });
2869 }
2870
2871 function map_nameAsterisk(is_import, name) {
2872 var foreign_type = is_import ? AST_SymbolImportForeign : AST_SymbolExportForeign;
2873 var type = is_import ? AST_SymbolImport : AST_SymbolExport;
2874 var start = S.token;
2875 var foreign_name;
2876 var end = prev();
2877
2878 name = name || new type({
2879 name: "*",
2880 start: start,
2881 end: end,
2882 });
2883
2884 foreign_name = new foreign_type({
2885 name: "*",
2886 start: start,
2887 end: end,
2888 });
2889
2890 return new AST_NameMapping({
2891 start: start,
2892 foreign_name: foreign_name,
2893 name: name,
2894 end: end,
2895 });
2896 }
2897
2898 function map_names(is_import) {
2899 var names;
2900 if (is("punc", "{")) {
2901 next();
2902 names = [];
2903 while (!is("punc", "}")) {
2904 names.push(map_name(is_import));
2905 if (is("punc", ",")) {
2906 next();
2907 }
2908 }
2909 next();
2910 } else if (is("operator", "*")) {
2911 var name;
2912 next();
2913 if (is_import && is("name", "as")) {
2914 next(); // The "as" word
2915 name = as_symbol(is_import ? AST_SymbolImport : AST_SymbolExportForeign);
2916 }
2917 names = [map_nameAsterisk(is_import, name)];
2918 }
2919 return names;
2920 }
2921
2922 function export_() {
2923 var start = S.token;
2924 var is_default;
2925 var exported_names;
2926
2927 if (is("keyword", "default")) {
2928 is_default = true;
2929 next();
2930 } else if (exported_names = map_names(false)) {
2931 if (is("name", "from")) {
2932 next();
2933
2934 var mod_str = S.token;
2935 if (mod_str.type !== "string") {
2936 unexpected();
2937 }
2938 next();
2939
2940 return new AST_Export({
2941 start: start,
2942 is_default: is_default,
2943 exported_names: exported_names,
2944 module_name: new AST_String({
2945 start: mod_str,
2946 value: mod_str.value,
2947 quote: mod_str.quote,
2948 end: mod_str,
2949 }),
2950 end: prev(),
2951 });
2952 } else {
2953 return new AST_Export({
2954 start: start,
2955 is_default: is_default,
2956 exported_names: exported_names,
2957 end: prev(),
2958 });
2959 }
2960 }
2961
2962 var node;
2963 var exported_value;
2964 var exported_definition;
2965 if (is("punc", "{")
2966 || is_default
2967 && (is("keyword", "class") || is("keyword", "function"))
2968 && is_token(peek(), "punc")) {
2969 exported_value = expression(false);
2970 semicolon();
2971 } else if ((node = statement(is_default)) instanceof AST_Definitions && is_default) {
2972 unexpected(node.start);
2973 } else if (node instanceof AST_Definitions || node instanceof AST_Lambda || node instanceof AST_DefClass) {
2974 exported_definition = node;
2975 } else if (node instanceof AST_SimpleStatement) {
2976 exported_value = node.body;
2977 } else {
2978 unexpected(node.start);
2979 }
2980
2981 return new AST_Export({
2982 start: start,
2983 is_default: is_default,
2984 exported_value: exported_value,
2985 exported_definition: exported_definition,
2986 end: prev(),
2987 });
2988 }
2989
2990 function as_property_name() {
2991 var tmp = S.token;
2992 switch (tmp.type) {
2993 case "punc":
2994 if (tmp.value === "[") {
2995 next();
2996 var ex = expression(false);
2997 expect("]");
2998 return ex;
2999 } else unexpected(tmp);
3000 case "operator":
3001 if (tmp.value === "*") {
3002 next();
3003 return null;
3004 }
3005 if (!["delete", "in", "instanceof", "new", "typeof", "void"].includes(tmp.value)) {
3006 unexpected(tmp);
3007 }
3008 /* falls through */
3009 case "name":
3010 case "string":
3011 case "num":
3012 case "big_int":
3013 case "keyword":
3014 case "atom":
3015 next();
3016 return tmp.value;
3017 default:
3018 unexpected(tmp);
3019 }
3020 }
3021
3022 function as_name() {
3023 var tmp = S.token;
3024 if (tmp.type != "name") unexpected();
3025 next();
3026 return tmp.value;
3027 }
3028
3029 function _make_symbol(type) {
3030 var name = S.token.value;
3031 return new (name == "this" ? AST_This :
3032 name == "super" ? AST_Super :
3033 type)({
3034 name : String(name),
3035 start : S.token,
3036 end : S.token
3037 });
3038 }
3039
3040 function _verify_symbol(sym) {
3041 var name = sym.name;
3042 if (is_in_generator() && name == "yield") {
3043 token_error(sym.start, "Yield cannot be used as identifier inside generators");
3044 }
3045 if (S.input.has_directive("use strict")) {
3046 if (name == "yield") {
3047 token_error(sym.start, "Unexpected yield identifier inside strict mode");
3048 }
3049 if (sym instanceof AST_SymbolDeclaration && (name == "arguments" || name == "eval")) {
3050 token_error(sym.start, "Unexpected " + name + " in strict mode");
3051 }
3052 }
3053 }
3054
3055 function as_symbol(type, noerror) {
3056 if (!is("name")) {
3057 if (!noerror) croak("Name expected");
3058 return null;
3059 }
3060 var sym = _make_symbol(type);
3061 _verify_symbol(sym);
3062 next();
3063 return sym;
3064 }
3065
3066 // Annotate AST_Call, AST_Lambda or AST_New with the special comments
3067 function annotate(node) {
3068 var start = node.start;
3069 var comments = start.comments_before;
3070 const comments_outside_parens = outer_comments_before_counts.get(start);
3071 var i = comments_outside_parens != null ? comments_outside_parens : comments.length;
3072 while (--i >= 0) {
3073 var comment = comments[i];
3074 if (/[@#]__/.test(comment.value)) {
3075 if (/[@#]__PURE__/.test(comment.value)) {
3076 set_annotation(node, _PURE);
3077 break;
3078 }
3079 if (/[@#]__INLINE__/.test(comment.value)) {
3080 set_annotation(node, _INLINE);
3081 break;
3082 }
3083 if (/[@#]__NOINLINE__/.test(comment.value)) {
3084 set_annotation(node, _NOINLINE);
3085 break;
3086 }
3087 }
3088 }
3089 }
3090
3091 var subscripts = function(expr, allow_calls, is_chain) {
3092 var start = expr.start;
3093 if (is("punc", ".")) {
3094 next();
3095 return subscripts(new AST_Dot({
3096 start : start,
3097 expression : expr,
3098 optional : false,
3099 property : as_name(),
3100 end : prev()
3101 }), allow_calls, is_chain);
3102 }
3103 if (is("punc", "[")) {
3104 next();
3105 var prop = expression(true);
3106 expect("]");
3107 return subscripts(new AST_Sub({
3108 start : start,
3109 expression : expr,
3110 optional : false,
3111 property : prop,
3112 end : prev()
3113 }), allow_calls, is_chain);
3114 }
3115 if (allow_calls && is("punc", "(")) {
3116 next();
3117 var call = new AST_Call({
3118 start : start,
3119 expression : expr,
3120 optional : false,
3121 args : call_args(),
3122 end : prev()
3123 });
3124 annotate(call);
3125 return subscripts(call, true, is_chain);
3126 }
3127
3128 if (is("punc", "?.")) {
3129 next();
3130
3131 let chain_contents;
3132
3133 if (allow_calls && is("punc", "(")) {
3134 next();
3135
3136 const call = new AST_Call({
3137 start,
3138 optional: true,
3139 expression: expr,
3140 args: call_args(),
3141 end: prev()
3142 });
3143 annotate(call);
3144
3145 chain_contents = subscripts(call, true, true);
3146 } else if (is("name")) {
3147 chain_contents = subscripts(new AST_Dot({
3148 start,
3149 expression: expr,
3150 optional: true,
3151 property: as_name(),
3152 end: prev()
3153 }), allow_calls, true);
3154 } else if (is("punc", "[")) {
3155 next();
3156 const property = expression(true);
3157 expect("]");
3158 chain_contents = subscripts(new AST_Sub({
3159 start,
3160 expression: expr,
3161 optional: true,
3162 property,
3163 end: prev()
3164 }), allow_calls, true);
3165 }
3166
3167 if (!chain_contents) unexpected();
3168
3169 if (chain_contents instanceof AST_Chain) return chain_contents;
3170
3171 return new AST_Chain({
3172 start,
3173 expression: chain_contents,
3174 end: prev()
3175 });
3176 }
3177
3178 if (is("template_head")) {
3179 if (is_chain) {
3180 // a?.b`c` is a syntax error
3181 unexpected();
3182 }
3183
3184 return subscripts(new AST_PrefixedTemplateString({
3185 start: start,
3186 prefix: expr,
3187 template_string: template_string(),
3188 end: prev()
3189 }), allow_calls);
3190 }
3191
3192 return expr;
3193 };
3194
3195 function call_args() {
3196 var args = [];
3197 while (!is("punc", ")")) {
3198 if (is("expand", "...")) {
3199 next();
3200 args.push(new AST_Expansion({
3201 start: prev(),
3202 expression: expression(false),
3203 end: prev()
3204 }));
3205 } else {
3206 args.push(expression(false));
3207 }
3208 if (!is("punc", ")")) {
3209 expect(",");
3210 }
3211 }
3212 next();
3213 return args;
3214 }
3215
3216 var maybe_unary = function(allow_calls, allow_arrows) {
3217 var start = S.token;
3218 if (start.type == "name" && start.value == "await") {
3219 if (is_in_async()) {
3220 next();
3221 return _await_expression();
3222 } else if (S.input.has_directive("use strict")) {
3223 token_error(S.token, "Unexpected await identifier inside strict mode");
3224 }
3225 }
3226 if (is("operator") && UNARY_PREFIX.has(start.value)) {
3227 next();
3228 handle_regexp();
3229 var ex = make_unary(AST_UnaryPrefix, start, maybe_unary(allow_calls));
3230 ex.start = start;
3231 ex.end = prev();
3232 return ex;
3233 }
3234 var val = expr_atom(allow_calls, allow_arrows);
3235 while (is("operator") && UNARY_POSTFIX.has(S.token.value) && !has_newline_before(S.token)) {
3236 if (val instanceof AST_Arrow) unexpected();
3237 val = make_unary(AST_UnaryPostfix, S.token, val);
3238 val.start = start;
3239 val.end = S.token;
3240 next();
3241 }
3242 return val;
3243 };
3244
3245 function make_unary(ctor, token, expr) {
3246 var op = token.value;
3247 switch (op) {
3248 case "++":
3249 case "--":
3250 if (!is_assignable(expr))
3251 croak("Invalid use of " + op + " operator", token.line, token.col, token.pos);
3252 break;
3253 case "delete":
3254 if (expr instanceof AST_SymbolRef && S.input.has_directive("use strict"))
3255 croak("Calling delete on expression not allowed in strict mode", expr.start.line, expr.start.col, expr.start.pos);
3256 break;
3257 }
3258 return new ctor({ operator: op, expression: expr });
3259 }
3260
3261 var expr_op = function(left, min_prec, no_in) {
3262 var op = is("operator") ? S.token.value : null;
3263 if (op == "in" && no_in) op = null;
3264 if (op == "**" && left instanceof AST_UnaryPrefix
3265 /* unary token in front not allowed - parenthesis required */
3266 && !is_token(left.start, "punc", "(")
3267 && left.operator !== "--" && left.operator !== "++")
3268 unexpected(left.start);
3269 var prec = op != null ? PRECEDENCE[op] : null;
3270 if (prec != null && (prec > min_prec || (op === "**" && min_prec === prec))) {
3271 next();
3272 var right = expr_op(maybe_unary(true), prec, no_in);
3273 return expr_op(new AST_Binary({
3274 start : left.start,
3275 left : left,
3276 operator : op,
3277 right : right,
3278 end : right.end
3279 }), min_prec, no_in);
3280 }
3281 return left;
3282 };
3283
3284 function expr_ops(no_in) {
3285 return expr_op(maybe_unary(true, true), 0, no_in);
3286 }
3287
3288 var maybe_conditional = function(no_in) {
3289 var start = S.token;
3290 var expr = expr_ops(no_in);
3291 if (is("operator", "?")) {
3292 next();
3293 var yes = expression(false);
3294 expect(":");
3295 return new AST_Conditional({
3296 start : start,
3297 condition : expr,
3298 consequent : yes,
3299 alternative : expression(false, no_in),
3300 end : prev()
3301 });
3302 }
3303 return expr;
3304 };
3305
3306 function is_assignable(expr) {
3307 return expr instanceof AST_PropAccess || expr instanceof AST_SymbolRef;
3308 }
3309
3310 function to_destructuring(node) {
3311 if (node instanceof AST_Object) {
3312 node = new AST_Destructuring({
3313 start: node.start,
3314 names: node.properties.map(to_destructuring),
3315 is_array: false,
3316 end: node.end
3317 });
3318 } else if (node instanceof AST_Array) {
3319 var names = [];
3320
3321 for (var i = 0; i < node.elements.length; i++) {
3322 // Only allow expansion as last element
3323 if (node.elements[i] instanceof AST_Expansion) {
3324 if (i + 1 !== node.elements.length) {
3325 token_error(node.elements[i].start, "Spread must the be last element in destructuring array");
3326 }
3327 node.elements[i].expression = to_destructuring(node.elements[i].expression);
3328 }
3329
3330 names.push(to_destructuring(node.elements[i]));
3331 }
3332
3333 node = new AST_Destructuring({
3334 start: node.start,
3335 names: names,
3336 is_array: true,
3337 end: node.end
3338 });
3339 } else if (node instanceof AST_ObjectProperty) {
3340 node.value = to_destructuring(node.value);
3341 } else if (node instanceof AST_Assign) {
3342 node = new AST_DefaultAssign({
3343 start: node.start,
3344 left: node.left,
3345 operator: "=",
3346 right: node.right,
3347 end: node.end
3348 });
3349 }
3350 return node;
3351 }
3352
3353 // In ES6, AssignmentExpression can also be an ArrowFunction
3354 var maybe_assign = function(no_in) {
3355 handle_regexp();
3356 var start = S.token;
3357
3358 if (start.type == "name" && start.value == "yield") {
3359 if (is_in_generator()) {
3360 next();
3361 return _yield_expression();
3362 } else if (S.input.has_directive("use strict")) {
3363 token_error(S.token, "Unexpected yield identifier inside strict mode");
3364 }
3365 }
3366
3367 var left = maybe_conditional(no_in);
3368 var val = S.token.value;
3369
3370 if (is("operator") && ASSIGNMENT.has(val)) {
3371 if (is_assignable(left) || (left = to_destructuring(left)) instanceof AST_Destructuring) {
3372 next();
3373 return new AST_Assign({
3374 start : start,
3375 left : left,
3376 operator : val,
3377 right : maybe_assign(no_in),
3378 end : prev()
3379 });
3380 }
3381 croak("Invalid assignment");
3382 }
3383 return left;
3384 };
3385
3386 var expression = function(commas, no_in) {
3387 var start = S.token;
3388 var exprs = [];
3389 while (true) {
3390 exprs.push(maybe_assign(no_in));
3391 if (!commas || !is("punc", ",")) break;
3392 next();
3393 commas = true;
3394 }
3395 return exprs.length == 1 ? exprs[0] : new AST_Sequence({
3396 start : start,
3397 expressions : exprs,
3398 end : peek()
3399 });
3400 };
3401
3402 function in_loop(cont) {
3403 ++S.in_loop;
3404 var ret = cont();
3405 --S.in_loop;
3406 return ret;
3407 }
3408
3409 if (options.expression) {
3410 return expression(true);
3411 }
3412
3413 return (function parse_toplevel() {
3414 var start = S.token;
3415 var body = [];
3416 S.input.push_directives_stack();
3417 if (options.module) S.input.add_directive("use strict");
3418 while (!is("eof")) {
3419 body.push(statement());
3420 }
3421 S.input.pop_directives_stack();
3422 var end = prev();
3423 var toplevel = options.toplevel;
3424 if (toplevel) {
3425 toplevel.body = toplevel.body.concat(body);
3426 toplevel.end = end;
3427 } else {
3428 toplevel = new AST_Toplevel({ start: start, body: body, end: end });
3429 }
3430 return toplevel;
3431 })();
3432
3433}
3434
3435/***********************************************************************
3436
3437 A JavaScript tokenizer / parser / beautifier / compressor.
3438 https://github.com/mishoo/UglifyJS2
3439
3440 -------------------------------- (C) ---------------------------------
3441
3442 Author: Mihai Bazon
3443 <mihai.bazon@gmail.com>
3444 http://mihai.bazon.net/blog
3445
3446 Distributed under the BSD license:
3447
3448 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
3449
3450 Redistribution and use in source and binary forms, with or without
3451 modification, are permitted provided that the following conditions
3452 are met:
3453
3454 * Redistributions of source code must retain the above
3455 copyright notice, this list of conditions and the following
3456 disclaimer.
3457
3458 * Redistributions in binary form must reproduce the above
3459 copyright notice, this list of conditions and the following
3460 disclaimer in the documentation and/or other materials
3461 provided with the distribution.
3462
3463 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
3464 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3465 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
3466 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
3467 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
3468 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
3469 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
3470 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3471 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
3472 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
3473 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3474 SUCH DAMAGE.
3475
3476 ***********************************************************************/
3477
3478function DEFNODE(type, props, methods, base = AST_Node) {
3479 if (!props) props = [];
3480 else props = props.split(/\s+/);
3481 var self_props = props;
3482 if (base && base.PROPS)
3483 props = props.concat(base.PROPS);
3484 var code = "return function AST_" + type + "(props){ if (props) { ";
3485 for (var i = props.length; --i >= 0;) {
3486 code += "this." + props[i] + " = props." + props[i] + ";";
3487 }
3488 const proto = base && Object.create(base.prototype);
3489 if (proto && proto.initialize || (methods && methods.initialize))
3490 code += "this.initialize();";
3491 code += "}";
3492 code += "this.flags = 0;";
3493 code += "}";
3494 var ctor = new Function(code)();
3495 if (proto) {
3496 ctor.prototype = proto;
3497 ctor.BASE = base;
3498 }
3499 if (base) base.SUBCLASSES.push(ctor);
3500 ctor.prototype.CTOR = ctor;
3501 ctor.prototype.constructor = ctor;
3502 ctor.PROPS = props || null;
3503 ctor.SELF_PROPS = self_props;
3504 ctor.SUBCLASSES = [];
3505 if (type) {
3506 ctor.prototype.TYPE = ctor.TYPE = type;
3507 }
3508 if (methods) for (i in methods) if (HOP(methods, i)) {
3509 if (i[0] === "$") {
3510 ctor[i.substr(1)] = methods[i];
3511 } else {
3512 ctor.prototype[i] = methods[i];
3513 }
3514 }
3515 ctor.DEFMETHOD = function(name, method) {
3516 this.prototype[name] = method;
3517 };
3518 return ctor;
3519}
3520
3521var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos nlb comments_before comments_after file raw quote end", {
3522}, null);
3523
3524var AST_Node = DEFNODE("Node", "start end", {
3525 _clone: function(deep) {
3526 if (deep) {
3527 var self = this.clone();
3528 return self.transform(new TreeTransformer(function(node) {
3529 if (node !== self) {
3530 return node.clone(true);
3531 }
3532 }));
3533 }
3534 return new this.CTOR(this);
3535 },
3536 clone: function(deep) {
3537 return this._clone(deep);
3538 },
3539 $documentation: "Base class of all AST nodes",
3540 $propdoc: {
3541 start: "[AST_Token] The first token of this node",
3542 end: "[AST_Token] The last token of this node"
3543 },
3544 _walk: function(visitor) {
3545 return visitor._visit(this);
3546 },
3547 walk: function(visitor) {
3548 return this._walk(visitor); // not sure the indirection will be any help
3549 },
3550 _children_backwards: () => {}
3551}, null);
3552
3553/* -----[ statements ]----- */
3554
3555var AST_Statement = DEFNODE("Statement", null, {
3556 $documentation: "Base class of all statements",
3557});
3558
3559var AST_Debugger = DEFNODE("Debugger", null, {
3560 $documentation: "Represents a debugger statement",
3561}, AST_Statement);
3562
3563var AST_Directive = DEFNODE("Directive", "value quote", {
3564 $documentation: "Represents a directive, like \"use strict\";",
3565 $propdoc: {
3566 value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
3567 quote: "[string] the original quote character"
3568 },
3569}, AST_Statement);
3570
3571var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
3572 $documentation: "A statement consisting of an expression, i.e. a = 1 + 2",
3573 $propdoc: {
3574 body: "[AST_Node] an expression node (should not be instanceof AST_Statement)"
3575 },
3576 _walk: function(visitor) {
3577 return visitor._visit(this, function() {
3578 this.body._walk(visitor);
3579 });
3580 },
3581 _children_backwards(push) {
3582 push(this.body);
3583 }
3584}, AST_Statement);
3585
3586function walk_body(node, visitor) {
3587 const body = node.body;
3588 for (var i = 0, len = body.length; i < len; i++) {
3589 body[i]._walk(visitor);
3590 }
3591}
3592
3593function clone_block_scope(deep) {
3594 var clone = this._clone(deep);
3595 if (this.block_scope) {
3596 // TODO this is sometimes undefined during compression.
3597 // But it should always have a value!
3598 clone.block_scope = this.block_scope.clone();
3599 }
3600 return clone;
3601}
3602
3603var AST_Block = DEFNODE("Block", "body block_scope", {
3604 $documentation: "A body of statements (usually braced)",
3605 $propdoc: {
3606 body: "[AST_Statement*] an array of statements",
3607 block_scope: "[AST_Scope] the block scope"
3608 },
3609 _walk: function(visitor) {
3610 return visitor._visit(this, function() {
3611 walk_body(this, visitor);
3612 });
3613 },
3614 _children_backwards(push) {
3615 let i = this.body.length;
3616 while (i--) push(this.body[i]);
3617 },
3618 clone: clone_block_scope
3619}, AST_Statement);
3620
3621var AST_BlockStatement = DEFNODE("BlockStatement", null, {
3622 $documentation: "A block statement",
3623}, AST_Block);
3624
3625var AST_EmptyStatement = DEFNODE("EmptyStatement", null, {
3626 $documentation: "The empty statement (empty block or simply a semicolon)"
3627}, AST_Statement);
3628
3629var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", {
3630 $documentation: "Base class for all statements that contain one nested body: `For`, `ForIn`, `Do`, `While`, `With`",
3631 $propdoc: {
3632 body: "[AST_Statement] the body; this should always be present, even if it's an AST_EmptyStatement"
3633 }
3634}, AST_Statement);
3635
3636var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
3637 $documentation: "Statement with a label",
3638 $propdoc: {
3639 label: "[AST_Label] a label definition"
3640 },
3641 _walk: function(visitor) {
3642 return visitor._visit(this, function() {
3643 this.label._walk(visitor);
3644 this.body._walk(visitor);
3645 });
3646 },
3647 _children_backwards(push) {
3648 push(this.body);
3649 push(this.label);
3650 },
3651 clone: function(deep) {
3652 var node = this._clone(deep);
3653 if (deep) {
3654 var label = node.label;
3655 var def = this.label;
3656 node.walk(new TreeWalker(function(node) {
3657 if (node instanceof AST_LoopControl
3658 && node.label && node.label.thedef === def) {
3659 node.label.thedef = label;
3660 label.references.push(node);
3661 }
3662 }));
3663 }
3664 return node;
3665 }
3666}, AST_StatementWithBody);
3667
3668var AST_IterationStatement = DEFNODE("IterationStatement", "block_scope", {
3669 $documentation: "Internal class. All loops inherit from it.",
3670 $propdoc: {
3671 block_scope: "[AST_Scope] the block scope for this iteration statement."
3672 },
3673 clone: clone_block_scope
3674}, AST_StatementWithBody);
3675
3676var AST_DWLoop = DEFNODE("DWLoop", "condition", {
3677 $documentation: "Base class for do/while statements",
3678 $propdoc: {
3679 condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement"
3680 }
3681}, AST_IterationStatement);
3682
3683var AST_Do = DEFNODE("Do", null, {
3684 $documentation: "A `do` statement",
3685 _walk: function(visitor) {
3686 return visitor._visit(this, function() {
3687 this.body._walk(visitor);
3688 this.condition._walk(visitor);
3689 });
3690 },
3691 _children_backwards(push) {
3692 push(this.condition);
3693 push(this.body);
3694 }
3695}, AST_DWLoop);
3696
3697var AST_While = DEFNODE("While", null, {
3698 $documentation: "A `while` statement",
3699 _walk: function(visitor) {
3700 return visitor._visit(this, function() {
3701 this.condition._walk(visitor);
3702 this.body._walk(visitor);
3703 });
3704 },
3705 _children_backwards(push) {
3706 push(this.body);
3707 push(this.condition);
3708 },
3709}, AST_DWLoop);
3710
3711var AST_For = DEFNODE("For", "init condition step", {
3712 $documentation: "A `for` statement",
3713 $propdoc: {
3714 init: "[AST_Node?] the `for` initialization code, or null if empty",
3715 condition: "[AST_Node?] the `for` termination clause, or null if empty",
3716 step: "[AST_Node?] the `for` update clause, or null if empty"
3717 },
3718 _walk: function(visitor) {
3719 return visitor._visit(this, function() {
3720 if (this.init) this.init._walk(visitor);
3721 if (this.condition) this.condition._walk(visitor);
3722 if (this.step) this.step._walk(visitor);
3723 this.body._walk(visitor);
3724 });
3725 },
3726 _children_backwards(push) {
3727 push(this.body);
3728 if (this.step) push(this.step);
3729 if (this.condition) push(this.condition);
3730 if (this.init) push(this.init);
3731 },
3732}, AST_IterationStatement);
3733
3734var AST_ForIn = DEFNODE("ForIn", "init object", {
3735 $documentation: "A `for ... in` statement",
3736 $propdoc: {
3737 init: "[AST_Node] the `for/in` initialization code",
3738 object: "[AST_Node] the object that we're looping through"
3739 },
3740 _walk: function(visitor) {
3741 return visitor._visit(this, function() {
3742 this.init._walk(visitor);
3743 this.object._walk(visitor);
3744 this.body._walk(visitor);
3745 });
3746 },
3747 _children_backwards(push) {
3748 push(this.body);
3749 if (this.object) push(this.object);
3750 if (this.init) push(this.init);
3751 },
3752}, AST_IterationStatement);
3753
3754var AST_ForOf = DEFNODE("ForOf", "await", {
3755 $documentation: "A `for ... of` statement",
3756}, AST_ForIn);
3757
3758var AST_With = DEFNODE("With", "expression", {
3759 $documentation: "A `with` statement",
3760 $propdoc: {
3761 expression: "[AST_Node] the `with` expression"
3762 },
3763 _walk: function(visitor) {
3764 return visitor._visit(this, function() {
3765 this.expression._walk(visitor);
3766 this.body._walk(visitor);
3767 });
3768 },
3769 _children_backwards(push) {
3770 push(this.body);
3771 push(this.expression);
3772 },
3773}, AST_StatementWithBody);
3774
3775/* -----[ scope and functions ]----- */
3776
3777var AST_Scope = DEFNODE("Scope", "variables functions uses_with uses_eval parent_scope enclosed cname", {
3778 $documentation: "Base class for all statements introducing a lexical scope",
3779 $propdoc: {
3780 variables: "[Map/S] a map of name -> SymbolDef for all variables/functions defined in this scope",
3781 functions: "[Map/S] like `variables`, but only lists function declarations",
3782 uses_with: "[boolean/S] tells whether this scope uses the `with` statement",
3783 uses_eval: "[boolean/S] tells whether this scope contains a direct call to the global `eval`",
3784 parent_scope: "[AST_Scope?/S] link to the parent scope",
3785 enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes",
3786 cname: "[integer/S] current index for mangling variables (used internally by the mangler)",
3787 },
3788 get_defun_scope: function() {
3789 var self = this;
3790 while (self.is_block_scope()) {
3791 self = self.parent_scope;
3792 }
3793 return self;
3794 },
3795 clone: function(deep, toplevel) {
3796 var node = this._clone(deep);
3797 if (deep && this.variables && toplevel && !this._block_scope) {
3798 node.figure_out_scope({}, {
3799 toplevel: toplevel,
3800 parent_scope: this.parent_scope
3801 });
3802 } else {
3803 if (this.variables) node.variables = new Map(this.variables);
3804 if (this.functions) node.functions = new Map(this.functions);
3805 if (this.enclosed) node.enclosed = this.enclosed.slice();
3806 if (this._block_scope) node._block_scope = this._block_scope;
3807 }
3808 return node;
3809 },
3810 pinned: function() {
3811 return this.uses_eval || this.uses_with;
3812 }
3813}, AST_Block);
3814
3815var AST_Toplevel = DEFNODE("Toplevel", "globals", {
3816 $documentation: "The toplevel scope",
3817 $propdoc: {
3818 globals: "[Map/S] a map of name -> SymbolDef for all undeclared names",
3819 },
3820 wrap_commonjs: function(name) {
3821 var body = this.body;
3822 var wrapped_tl = "(function(exports){'$ORIG';})(typeof " + name + "=='undefined'?(" + name + "={}):" + name + ");";
3823 wrapped_tl = parse(wrapped_tl);
3824 wrapped_tl = wrapped_tl.transform(new TreeTransformer(function(node) {
3825 if (node instanceof AST_Directive && node.value == "$ORIG") {
3826 return MAP.splice(body);
3827 }
3828 }));
3829 return wrapped_tl;
3830 },
3831 wrap_enclose: function(args_values) {
3832 if (typeof args_values != "string") args_values = "";
3833 var index = args_values.indexOf(":");
3834 if (index < 0) index = args_values.length;
3835 var body = this.body;
3836 return parse([
3837 "(function(",
3838 args_values.slice(0, index),
3839 '){"$ORIG"})(',
3840 args_values.slice(index + 1),
3841 ")"
3842 ].join("")).transform(new TreeTransformer(function(node) {
3843 if (node instanceof AST_Directive && node.value == "$ORIG") {
3844 return MAP.splice(body);
3845 }
3846 }));
3847 }
3848}, AST_Scope);
3849
3850var AST_Expansion = DEFNODE("Expansion", "expression", {
3851 $documentation: "An expandible argument, such as ...rest, a splat, such as [1,2,...all], or an expansion in a variable declaration, such as var [first, ...rest] = list",
3852 $propdoc: {
3853 expression: "[AST_Node] the thing to be expanded"
3854 },
3855 _walk: function(visitor) {
3856 return visitor._visit(this, function() {
3857 this.expression.walk(visitor);
3858 });
3859 },
3860 _children_backwards(push) {
3861 push(this.expression);
3862 },
3863});
3864
3865var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments is_generator async", {
3866 $documentation: "Base class for functions",
3867 $propdoc: {
3868 name: "[AST_SymbolDeclaration?] the name of this function",
3869 argnames: "[AST_SymbolFunarg|AST_Destructuring|AST_Expansion|AST_DefaultAssign*] array of function arguments, destructurings, or expanding arguments",
3870 uses_arguments: "[boolean/S] tells whether this function accesses the arguments array",
3871 is_generator: "[boolean] is this a generator method",
3872 async: "[boolean] is this method async",
3873 },
3874 args_as_names: function () {
3875 var out = [];
3876 for (var i = 0; i < this.argnames.length; i++) {
3877 if (this.argnames[i] instanceof AST_Destructuring) {
3878 out.push(...this.argnames[i].all_symbols());
3879 } else {
3880 out.push(this.argnames[i]);
3881 }
3882 }
3883 return out;
3884 },
3885 _walk: function(visitor) {
3886 return visitor._visit(this, function() {
3887 if (this.name) this.name._walk(visitor);
3888 var argnames = this.argnames;
3889 for (var i = 0, len = argnames.length; i < len; i++) {
3890 argnames[i]._walk(visitor);
3891 }
3892 walk_body(this, visitor);
3893 });
3894 },
3895 _children_backwards(push) {
3896 let i = this.body.length;
3897 while (i--) push(this.body[i]);
3898
3899 i = this.argnames.length;
3900 while (i--) push(this.argnames[i]);
3901
3902 if (this.name) push(this.name);
3903 },
3904}, AST_Scope);
3905
3906var AST_Accessor = DEFNODE("Accessor", null, {
3907 $documentation: "A setter/getter function. The `name` property is always null."
3908}, AST_Lambda);
3909
3910var AST_Function = DEFNODE("Function", null, {
3911 $documentation: "A function expression"
3912}, AST_Lambda);
3913
3914var AST_Arrow = DEFNODE("Arrow", null, {
3915 $documentation: "An ES6 Arrow function ((a) => b)"
3916}, AST_Lambda);
3917
3918var AST_Defun = DEFNODE("Defun", null, {
3919 $documentation: "A function definition"
3920}, AST_Lambda);
3921
3922/* -----[ DESTRUCTURING ]----- */
3923var AST_Destructuring = DEFNODE("Destructuring", "names is_array", {
3924 $documentation: "A destructuring of several names. Used in destructuring assignment and with destructuring function argument names",
3925 $propdoc: {
3926 "names": "[AST_Node*] Array of properties or elements",
3927 "is_array": "[Boolean] Whether the destructuring represents an object or array"
3928 },
3929 _walk: function(visitor) {
3930 return visitor._visit(this, function() {
3931 this.names.forEach(function(name) {
3932 name._walk(visitor);
3933 });
3934 });
3935 },
3936 _children_backwards(push) {
3937 let i = this.names.length;
3938 while (i--) push(this.names[i]);
3939 },
3940 all_symbols: function() {
3941 var out = [];
3942 this.walk(new TreeWalker(function (node) {
3943 if (node instanceof AST_Symbol) {
3944 out.push(node);
3945 }
3946 }));
3947 return out;
3948 }
3949});
3950
3951var AST_PrefixedTemplateString = DEFNODE("PrefixedTemplateString", "template_string prefix", {
3952 $documentation: "A templatestring with a prefix, such as String.raw`foobarbaz`",
3953 $propdoc: {
3954 template_string: "[AST_TemplateString] The template string",
3955 prefix: "[AST_Node] The prefix, which will get called."
3956 },
3957 _walk: function(visitor) {
3958 return visitor._visit(this, function () {
3959 this.prefix._walk(visitor);
3960 this.template_string._walk(visitor);
3961 });
3962 },
3963 _children_backwards(push) {
3964 push(this.template_string);
3965 push(this.prefix);
3966 },
3967});
3968
3969var AST_TemplateString = DEFNODE("TemplateString", "segments", {
3970 $documentation: "A template string literal",
3971 $propdoc: {
3972 segments: "[AST_Node*] One or more segments, starting with AST_TemplateSegment. AST_Node may follow AST_TemplateSegment, but each AST_Node must be followed by AST_TemplateSegment."
3973 },
3974 _walk: function(visitor) {
3975 return visitor._visit(this, function() {
3976 this.segments.forEach(function(seg) {
3977 seg._walk(visitor);
3978 });
3979 });
3980 },
3981 _children_backwards(push) {
3982 let i = this.segments.length;
3983 while (i--) push(this.segments[i]);
3984 }
3985});
3986
3987var AST_TemplateSegment = DEFNODE("TemplateSegment", "value raw", {
3988 $documentation: "A segment of a template string literal",
3989 $propdoc: {
3990 value: "Content of the segment",
3991 raw: "Raw content of the segment"
3992 }
3993});
3994
3995/* -----[ JUMPS ]----- */
3996
3997var AST_Jump = DEFNODE("Jump", null, {
3998 $documentation: "Base class for “jumps” (for now that's `return`, `throw`, `break` and `continue`)"
3999}, AST_Statement);
4000
4001var AST_Exit = DEFNODE("Exit", "value", {
4002 $documentation: "Base class for “exits” (`return` and `throw`)",
4003 $propdoc: {
4004 value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return"
4005 },
4006 _walk: function(visitor) {
4007 return visitor._visit(this, this.value && function() {
4008 this.value._walk(visitor);
4009 });
4010 },
4011 _children_backwards(push) {
4012 if (this.value) push(this.value);
4013 },
4014}, AST_Jump);
4015
4016var AST_Return = DEFNODE("Return", null, {
4017 $documentation: "A `return` statement"
4018}, AST_Exit);
4019
4020var AST_Throw = DEFNODE("Throw", null, {
4021 $documentation: "A `throw` statement"
4022}, AST_Exit);
4023
4024var AST_LoopControl = DEFNODE("LoopControl", "label", {
4025 $documentation: "Base class for loop control statements (`break` and `continue`)",
4026 $propdoc: {
4027 label: "[AST_LabelRef?] the label, or null if none",
4028 },
4029 _walk: function(visitor) {
4030 return visitor._visit(this, this.label && function() {
4031 this.label._walk(visitor);
4032 });
4033 },
4034 _children_backwards(push) {
4035 if (this.label) push(this.label);
4036 },
4037}, AST_Jump);
4038
4039var AST_Break = DEFNODE("Break", null, {
4040 $documentation: "A `break` statement"
4041}, AST_LoopControl);
4042
4043var AST_Continue = DEFNODE("Continue", null, {
4044 $documentation: "A `continue` statement"
4045}, AST_LoopControl);
4046
4047var AST_Await = DEFNODE("Await", "expression", {
4048 $documentation: "An `await` statement",
4049 $propdoc: {
4050 expression: "[AST_Node] the mandatory expression being awaited",
4051 },
4052 _walk: function(visitor) {
4053 return visitor._visit(this, function() {
4054 this.expression._walk(visitor);
4055 });
4056 },
4057 _children_backwards(push) {
4058 push(this.expression);
4059 },
4060});
4061
4062var AST_Yield = DEFNODE("Yield", "expression is_star", {
4063 $documentation: "A `yield` statement",
4064 $propdoc: {
4065 expression: "[AST_Node?] the value returned or thrown by this statement; could be null (representing undefined) but only when is_star is set to false",
4066 is_star: "[Boolean] Whether this is a yield or yield* statement"
4067 },
4068 _walk: function(visitor) {
4069 return visitor._visit(this, this.expression && function() {
4070 this.expression._walk(visitor);
4071 });
4072 },
4073 _children_backwards(push) {
4074 if (this.expression) push(this.expression);
4075 }
4076});
4077
4078/* -----[ IF ]----- */
4079
4080var AST_If = DEFNODE("If", "condition alternative", {
4081 $documentation: "A `if` statement",
4082 $propdoc: {
4083 condition: "[AST_Node] the `if` condition",
4084 alternative: "[AST_Statement?] the `else` part, or null if not present"
4085 },
4086 _walk: function(visitor) {
4087 return visitor._visit(this, function() {
4088 this.condition._walk(visitor);
4089 this.body._walk(visitor);
4090 if (this.alternative) this.alternative._walk(visitor);
4091 });
4092 },
4093 _children_backwards(push) {
4094 if (this.alternative) {
4095 push(this.alternative);
4096 }
4097 push(this.body);
4098 push(this.condition);
4099 }
4100}, AST_StatementWithBody);
4101
4102/* -----[ SWITCH ]----- */
4103
4104var AST_Switch = DEFNODE("Switch", "expression", {
4105 $documentation: "A `switch` statement",
4106 $propdoc: {
4107 expression: "[AST_Node] the `switch` “discriminant”"
4108 },
4109 _walk: function(visitor) {
4110 return visitor._visit(this, function() {
4111 this.expression._walk(visitor);
4112 walk_body(this, visitor);
4113 });
4114 },
4115 _children_backwards(push) {
4116 let i = this.body.length;
4117 while (i--) push(this.body[i]);
4118 push(this.expression);
4119 }
4120}, AST_Block);
4121
4122var AST_SwitchBranch = DEFNODE("SwitchBranch", null, {
4123 $documentation: "Base class for `switch` branches",
4124}, AST_Block);
4125
4126var AST_Default = DEFNODE("Default", null, {
4127 $documentation: "A `default` switch branch",
4128}, AST_SwitchBranch);
4129
4130var AST_Case = DEFNODE("Case", "expression", {
4131 $documentation: "A `case` switch branch",
4132 $propdoc: {
4133 expression: "[AST_Node] the `case` expression"
4134 },
4135 _walk: function(visitor) {
4136 return visitor._visit(this, function() {
4137 this.expression._walk(visitor);
4138 walk_body(this, visitor);
4139 });
4140 },
4141 _children_backwards(push) {
4142 let i = this.body.length;
4143 while (i--) push(this.body[i]);
4144 push(this.expression);
4145 },
4146}, AST_SwitchBranch);
4147
4148/* -----[ EXCEPTIONS ]----- */
4149
4150var AST_Try = DEFNODE("Try", "bcatch bfinally", {
4151 $documentation: "A `try` statement",
4152 $propdoc: {
4153 bcatch: "[AST_Catch?] the catch block, or null if not present",
4154 bfinally: "[AST_Finally?] the finally block, or null if not present"
4155 },
4156 _walk: function(visitor) {
4157 return visitor._visit(this, function() {
4158 walk_body(this, visitor);
4159 if (this.bcatch) this.bcatch._walk(visitor);
4160 if (this.bfinally) this.bfinally._walk(visitor);
4161 });
4162 },
4163 _children_backwards(push) {
4164 if (this.bfinally) push(this.bfinally);
4165 if (this.bcatch) push(this.bcatch);
4166 let i = this.body.length;
4167 while (i--) push(this.body[i]);
4168 },
4169}, AST_Block);
4170
4171var AST_Catch = DEFNODE("Catch", "argname", {
4172 $documentation: "A `catch` node; only makes sense as part of a `try` statement",
4173 $propdoc: {
4174 argname: "[AST_SymbolCatch|AST_Destructuring|AST_Expansion|AST_DefaultAssign] symbol for the exception"
4175 },
4176 _walk: function(visitor) {
4177 return visitor._visit(this, function() {
4178 if (this.argname) this.argname._walk(visitor);
4179 walk_body(this, visitor);
4180 });
4181 },
4182 _children_backwards(push) {
4183 let i = this.body.length;
4184 while (i--) push(this.body[i]);
4185 if (this.argname) push(this.argname);
4186 },
4187}, AST_Block);
4188
4189var AST_Finally = DEFNODE("Finally", null, {
4190 $documentation: "A `finally` node; only makes sense as part of a `try` statement"
4191}, AST_Block);
4192
4193/* -----[ VAR/CONST ]----- */
4194
4195var AST_Definitions = DEFNODE("Definitions", "definitions", {
4196 $documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)",
4197 $propdoc: {
4198 definitions: "[AST_VarDef*] array of variable definitions"
4199 },
4200 _walk: function(visitor) {
4201 return visitor._visit(this, function() {
4202 var definitions = this.definitions;
4203 for (var i = 0, len = definitions.length; i < len; i++) {
4204 definitions[i]._walk(visitor);
4205 }
4206 });
4207 },
4208 _children_backwards(push) {
4209 let i = this.definitions.length;
4210 while (i--) push(this.definitions[i]);
4211 },
4212}, AST_Statement);
4213
4214var AST_Var = DEFNODE("Var", null, {
4215 $documentation: "A `var` statement"
4216}, AST_Definitions);
4217
4218var AST_Let = DEFNODE("Let", null, {
4219 $documentation: "A `let` statement"
4220}, AST_Definitions);
4221
4222var AST_Const = DEFNODE("Const", null, {
4223 $documentation: "A `const` statement"
4224}, AST_Definitions);
4225
4226var AST_VarDef = DEFNODE("VarDef", "name value", {
4227 $documentation: "A variable declaration; only appears in a AST_Definitions node",
4228 $propdoc: {
4229 name: "[AST_Destructuring|AST_SymbolConst|AST_SymbolLet|AST_SymbolVar] name of the variable",
4230 value: "[AST_Node?] initializer, or null of there's no initializer"
4231 },
4232 _walk: function(visitor) {
4233 return visitor._visit(this, function() {
4234 this.name._walk(visitor);
4235 if (this.value) this.value._walk(visitor);
4236 });
4237 },
4238 _children_backwards(push) {
4239 if (this.value) push(this.value);
4240 push(this.name);
4241 },
4242});
4243
4244var AST_NameMapping = DEFNODE("NameMapping", "foreign_name name", {
4245 $documentation: "The part of the export/import statement that declare names from a module.",
4246 $propdoc: {
4247 foreign_name: "[AST_SymbolExportForeign|AST_SymbolImportForeign] The name being exported/imported (as specified in the module)",
4248 name: "[AST_SymbolExport|AST_SymbolImport] The name as it is visible to this module."
4249 },
4250 _walk: function (visitor) {
4251 return visitor._visit(this, function() {
4252 this.foreign_name._walk(visitor);
4253 this.name._walk(visitor);
4254 });
4255 },
4256 _children_backwards(push) {
4257 push(this.name);
4258 push(this.foreign_name);
4259 },
4260});
4261
4262var AST_Import = DEFNODE("Import", "imported_name imported_names module_name", {
4263 $documentation: "An `import` statement",
4264 $propdoc: {
4265 imported_name: "[AST_SymbolImport] The name of the variable holding the module's default export.",
4266 imported_names: "[AST_NameMapping*] The names of non-default imported variables",
4267 module_name: "[AST_String] String literal describing where this module came from",
4268 },
4269 _walk: function(visitor) {
4270 return visitor._visit(this, function() {
4271 if (this.imported_name) {
4272 this.imported_name._walk(visitor);
4273 }
4274 if (this.imported_names) {
4275 this.imported_names.forEach(function(name_import) {
4276 name_import._walk(visitor);
4277 });
4278 }
4279 this.module_name._walk(visitor);
4280 });
4281 },
4282 _children_backwards(push) {
4283 push(this.module_name);
4284 if (this.imported_names) {
4285 let i = this.imported_names.length;
4286 while (i--) push(this.imported_names[i]);
4287 }
4288 if (this.imported_name) push(this.imported_name);
4289 },
4290});
4291
4292var AST_ImportMeta = DEFNODE("ImportMeta", null, {
4293 $documentation: "A reference to import.meta",
4294});
4295
4296var AST_Export = DEFNODE("Export", "exported_definition exported_value is_default exported_names module_name", {
4297 $documentation: "An `export` statement",
4298 $propdoc: {
4299 exported_definition: "[AST_Defun|AST_Definitions|AST_DefClass?] An exported definition",
4300 exported_value: "[AST_Node?] An exported value",
4301 exported_names: "[AST_NameMapping*?] List of exported names",
4302 module_name: "[AST_String?] Name of the file to load exports from",
4303 is_default: "[Boolean] Whether this is the default exported value of this module"
4304 },
4305 _walk: function (visitor) {
4306 return visitor._visit(this, function () {
4307 if (this.exported_definition) {
4308 this.exported_definition._walk(visitor);
4309 }
4310 if (this.exported_value) {
4311 this.exported_value._walk(visitor);
4312 }
4313 if (this.exported_names) {
4314 this.exported_names.forEach(function(name_export) {
4315 name_export._walk(visitor);
4316 });
4317 }
4318 if (this.module_name) {
4319 this.module_name._walk(visitor);
4320 }
4321 });
4322 },
4323 _children_backwards(push) {
4324 if (this.module_name) push(this.module_name);
4325 if (this.exported_names) {
4326 let i = this.exported_names.length;
4327 while (i--) push(this.exported_names[i]);
4328 }
4329 if (this.exported_value) push(this.exported_value);
4330 if (this.exported_definition) push(this.exported_definition);
4331 }
4332}, AST_Statement);
4333
4334/* -----[ OTHER ]----- */
4335
4336var AST_Call = DEFNODE("Call", "expression args optional _annotations", {
4337 $documentation: "A function call expression",
4338 $propdoc: {
4339 expression: "[AST_Node] expression to invoke as function",
4340 args: "[AST_Node*] array of arguments",
4341 optional: "[boolean] whether this is an optional call (IE ?.() )",
4342 _annotations: "[number] bitfield containing information about the call"
4343 },
4344 initialize() {
4345 if (this._annotations == null) this._annotations = 0;
4346 },
4347 _walk(visitor) {
4348 return visitor._visit(this, function() {
4349 var args = this.args;
4350 for (var i = 0, len = args.length; i < len; i++) {
4351 args[i]._walk(visitor);
4352 }
4353 this.expression._walk(visitor); // TODO why do we need to crawl this last?
4354 });
4355 },
4356 _children_backwards(push) {
4357 let i = this.args.length;
4358 while (i--) push(this.args[i]);
4359 push(this.expression);
4360 },
4361});
4362
4363var AST_New = DEFNODE("New", null, {
4364 $documentation: "An object instantiation. Derives from a function call since it has exactly the same properties"
4365}, AST_Call);
4366
4367var AST_Sequence = DEFNODE("Sequence", "expressions", {
4368 $documentation: "A sequence expression (comma-separated expressions)",
4369 $propdoc: {
4370 expressions: "[AST_Node*] array of expressions (at least two)"
4371 },
4372 _walk: function(visitor) {
4373 return visitor._visit(this, function() {
4374 this.expressions.forEach(function(node) {
4375 node._walk(visitor);
4376 });
4377 });
4378 },
4379 _children_backwards(push) {
4380 let i = this.expressions.length;
4381 while (i--) push(this.expressions[i]);
4382 },
4383});
4384
4385var AST_PropAccess = DEFNODE("PropAccess", "expression property optional", {
4386 $documentation: "Base class for property access expressions, i.e. `a.foo` or `a[\"foo\"]`",
4387 $propdoc: {
4388 expression: "[AST_Node] the “container” expression",
4389 property: "[AST_Node|string] the property to access. For AST_Dot this is always a plain string, while for AST_Sub it's an arbitrary AST_Node",
4390
4391 optional: "[boolean] whether this is an optional property access (IE ?.)"
4392 }
4393});
4394
4395var AST_Dot = DEFNODE("Dot", "quote", {
4396 $documentation: "A dotted property access expression",
4397 $propdoc: {
4398 quote: "[string] the original quote character when transformed from AST_Sub",
4399 },
4400 _walk: function(visitor) {
4401 return visitor._visit(this, function() {
4402 this.expression._walk(visitor);
4403 });
4404 },
4405 _children_backwards(push) {
4406 push(this.expression);
4407 },
4408}, AST_PropAccess);
4409
4410var AST_Sub = DEFNODE("Sub", null, {
4411 $documentation: "Index-style property access, i.e. `a[\"foo\"]`",
4412 _walk: function(visitor) {
4413 return visitor._visit(this, function() {
4414 this.expression._walk(visitor);
4415 this.property._walk(visitor);
4416 });
4417 },
4418 _children_backwards(push) {
4419 push(this.property);
4420 push(this.expression);
4421 },
4422}, AST_PropAccess);
4423
4424var AST_Chain = DEFNODE("Chain", "expression", {
4425 $documentation: "A chain expression like a?.b?.(c)?.[d]",
4426 $propdoc: {
4427 expression: "[AST_Call|AST_Dot|AST_Sub] chain element."
4428 },
4429 _walk: function (visitor) {
4430 return visitor._visit(this, function() {
4431 this.expression._walk(visitor);
4432 });
4433 },
4434 _children_backwards(push) {
4435 push(this.expression);
4436 },
4437});
4438
4439var AST_Unary = DEFNODE("Unary", "operator expression", {
4440 $documentation: "Base class for unary expressions",
4441 $propdoc: {
4442 operator: "[string] the operator",
4443 expression: "[AST_Node] expression that this unary operator applies to"
4444 },
4445 _walk: function(visitor) {
4446 return visitor._visit(this, function() {
4447 this.expression._walk(visitor);
4448 });
4449 },
4450 _children_backwards(push) {
4451 push(this.expression);
4452 },
4453});
4454
4455var AST_UnaryPrefix = DEFNODE("UnaryPrefix", null, {
4456 $documentation: "Unary prefix expression, i.e. `typeof i` or `++i`"
4457}, AST_Unary);
4458
4459var AST_UnaryPostfix = DEFNODE("UnaryPostfix", null, {
4460 $documentation: "Unary postfix expression, i.e. `i++`"
4461}, AST_Unary);
4462
4463var AST_Binary = DEFNODE("Binary", "operator left right", {
4464 $documentation: "Binary expression, i.e. `a + b`",
4465 $propdoc: {
4466 left: "[AST_Node] left-hand side expression",
4467 operator: "[string] the operator",
4468 right: "[AST_Node] right-hand side expression"
4469 },
4470 _walk: function(visitor) {
4471 return visitor._visit(this, function() {
4472 this.left._walk(visitor);
4473 this.right._walk(visitor);
4474 });
4475 },
4476 _children_backwards(push) {
4477 push(this.right);
4478 push(this.left);
4479 },
4480});
4481
4482var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative", {
4483 $documentation: "Conditional expression using the ternary operator, i.e. `a ? b : c`",
4484 $propdoc: {
4485 condition: "[AST_Node]",
4486 consequent: "[AST_Node]",
4487 alternative: "[AST_Node]"
4488 },
4489 _walk: function(visitor) {
4490 return visitor._visit(this, function() {
4491 this.condition._walk(visitor);
4492 this.consequent._walk(visitor);
4493 this.alternative._walk(visitor);
4494 });
4495 },
4496 _children_backwards(push) {
4497 push(this.alternative);
4498 push(this.consequent);
4499 push(this.condition);
4500 },
4501});
4502
4503var AST_Assign = DEFNODE("Assign", null, {
4504 $documentation: "An assignment expression — `a = b + 5`",
4505}, AST_Binary);
4506
4507var AST_DefaultAssign = DEFNODE("DefaultAssign", null, {
4508 $documentation: "A default assignment expression like in `(a = 3) => a`"
4509}, AST_Binary);
4510
4511/* -----[ LITERALS ]----- */
4512
4513var AST_Array = DEFNODE("Array", "elements", {
4514 $documentation: "An array literal",
4515 $propdoc: {
4516 elements: "[AST_Node*] array of elements"
4517 },
4518 _walk: function(visitor) {
4519 return visitor._visit(this, function() {
4520 var elements = this.elements;
4521 for (var i = 0, len = elements.length; i < len; i++) {
4522 elements[i]._walk(visitor);
4523 }
4524 });
4525 },
4526 _children_backwards(push) {
4527 let i = this.elements.length;
4528 while (i--) push(this.elements[i]);
4529 },
4530});
4531
4532var AST_Object = DEFNODE("Object", "properties", {
4533 $documentation: "An object literal",
4534 $propdoc: {
4535 properties: "[AST_ObjectProperty*] array of properties"
4536 },
4537 _walk: function(visitor) {
4538 return visitor._visit(this, function() {
4539 var properties = this.properties;
4540 for (var i = 0, len = properties.length; i < len; i++) {
4541 properties[i]._walk(visitor);
4542 }
4543 });
4544 },
4545 _children_backwards(push) {
4546 let i = this.properties.length;
4547 while (i--) push(this.properties[i]);
4548 },
4549});
4550
4551var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
4552 $documentation: "Base class for literal object properties",
4553 $propdoc: {
4554 key: "[string|AST_Node] property name. For ObjectKeyVal this is a string. For getters, setters and computed property this is an AST_Node.",
4555 value: "[AST_Node] property value. For getters and setters this is an AST_Accessor."
4556 },
4557 _walk: function(visitor) {
4558 return visitor._visit(this, function() {
4559 if (this.key instanceof AST_Node)
4560 this.key._walk(visitor);
4561 this.value._walk(visitor);
4562 });
4563 },
4564 _children_backwards(push) {
4565 push(this.value);
4566 if (this.key instanceof AST_Node) push(this.key);
4567 }
4568});
4569
4570var AST_ObjectKeyVal = DEFNODE("ObjectKeyVal", "quote", {
4571 $documentation: "A key: value object property",
4572 $propdoc: {
4573 quote: "[string] the original quote character"
4574 },
4575 computed_key() {
4576 return this.key instanceof AST_Node;
4577 }
4578}, AST_ObjectProperty);
4579
4580var AST_ObjectSetter = DEFNODE("ObjectSetter", "quote static", {
4581 $propdoc: {
4582 quote: "[string|undefined] the original quote character, if any",
4583 static: "[boolean] whether this is a static setter (classes only)"
4584 },
4585 $documentation: "An object setter property",
4586 computed_key() {
4587 return !(this.key instanceof AST_SymbolMethod);
4588 }
4589}, AST_ObjectProperty);
4590
4591var AST_ObjectGetter = DEFNODE("ObjectGetter", "quote static", {
4592 $propdoc: {
4593 quote: "[string|undefined] the original quote character, if any",
4594 static: "[boolean] whether this is a static getter (classes only)"
4595 },
4596 $documentation: "An object getter property",
4597 computed_key() {
4598 return !(this.key instanceof AST_SymbolMethod);
4599 }
4600}, AST_ObjectProperty);
4601
4602var AST_ConciseMethod = DEFNODE("ConciseMethod", "quote static is_generator async", {
4603 $propdoc: {
4604 quote: "[string|undefined] the original quote character, if any",
4605 static: "[boolean] is this method static (classes only)",
4606 is_generator: "[boolean] is this a generator method",
4607 async: "[boolean] is this method async",
4608 },
4609 $documentation: "An ES6 concise method inside an object or class",
4610 computed_key() {
4611 return !(this.key instanceof AST_SymbolMethod);
4612 }
4613}, AST_ObjectProperty);
4614
4615var AST_Class = DEFNODE("Class", "name extends properties", {
4616 $propdoc: {
4617 name: "[AST_SymbolClass|AST_SymbolDefClass?] optional class name.",
4618 extends: "[AST_Node]? optional parent class",
4619 properties: "[AST_ObjectProperty*] array of properties"
4620 },
4621 $documentation: "An ES6 class",
4622 _walk: function(visitor) {
4623 return visitor._visit(this, function() {
4624 if (this.name) {
4625 this.name._walk(visitor);
4626 }
4627 if (this.extends) {
4628 this.extends._walk(visitor);
4629 }
4630 this.properties.forEach((prop) => prop._walk(visitor));
4631 });
4632 },
4633 _children_backwards(push) {
4634 let i = this.properties.length;
4635 while (i--) push(this.properties[i]);
4636 if (this.extends) push(this.extends);
4637 if (this.name) push(this.name);
4638 },
4639}, AST_Scope /* TODO a class might have a scope but it's not a scope */);
4640
4641var AST_ClassProperty = DEFNODE("ClassProperty", "static quote", {
4642 $documentation: "A class property",
4643 $propdoc: {
4644 static: "[boolean] whether this is a static key",
4645 quote: "[string] which quote is being used"
4646 },
4647 _walk: function(visitor) {
4648 return visitor._visit(this, function() {
4649 if (this.key instanceof AST_Node)
4650 this.key._walk(visitor);
4651 if (this.value instanceof AST_Node)
4652 this.value._walk(visitor);
4653 });
4654 },
4655 _children_backwards(push) {
4656 if (this.value instanceof AST_Node) push(this.value);
4657 if (this.key instanceof AST_Node) push(this.key);
4658 },
4659 computed_key() {
4660 return !(this.key instanceof AST_SymbolClassProperty);
4661 }
4662}, AST_ObjectProperty);
4663
4664var AST_DefClass = DEFNODE("DefClass", null, {
4665 $documentation: "A class definition",
4666}, AST_Class);
4667
4668var AST_ClassExpression = DEFNODE("ClassExpression", null, {
4669 $documentation: "A class expression."
4670}, AST_Class);
4671
4672var AST_Symbol = DEFNODE("Symbol", "scope name thedef", {
4673 $propdoc: {
4674 name: "[string] name of this symbol",
4675 scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)",
4676 thedef: "[SymbolDef/S] the definition of this symbol"
4677 },
4678 $documentation: "Base class for all symbols"
4679});
4680
4681var AST_NewTarget = DEFNODE("NewTarget", null, {
4682 $documentation: "A reference to new.target"
4683});
4684
4685var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", {
4686 $documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)",
4687}, AST_Symbol);
4688
4689var AST_SymbolVar = DEFNODE("SymbolVar", null, {
4690 $documentation: "Symbol defining a variable",
4691}, AST_SymbolDeclaration);
4692
4693var AST_SymbolBlockDeclaration = DEFNODE("SymbolBlockDeclaration", null, {
4694 $documentation: "Base class for block-scoped declaration symbols"
4695}, AST_SymbolDeclaration);
4696
4697var AST_SymbolConst = DEFNODE("SymbolConst", null, {
4698 $documentation: "A constant declaration"
4699}, AST_SymbolBlockDeclaration);
4700
4701var AST_SymbolLet = DEFNODE("SymbolLet", null, {
4702 $documentation: "A block-scoped `let` declaration"
4703}, AST_SymbolBlockDeclaration);
4704
4705var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, {
4706 $documentation: "Symbol naming a function argument",
4707}, AST_SymbolVar);
4708
4709var AST_SymbolDefun = DEFNODE("SymbolDefun", null, {
4710 $documentation: "Symbol defining a function",
4711}, AST_SymbolDeclaration);
4712
4713var AST_SymbolMethod = DEFNODE("SymbolMethod", null, {
4714 $documentation: "Symbol in an object defining a method",
4715}, AST_Symbol);
4716
4717var AST_SymbolClassProperty = DEFNODE("SymbolClassProperty", null, {
4718 $documentation: "Symbol for a class property",
4719}, AST_Symbol);
4720
4721var AST_SymbolLambda = DEFNODE("SymbolLambda", null, {
4722 $documentation: "Symbol naming a function expression",
4723}, AST_SymbolDeclaration);
4724
4725var AST_SymbolDefClass = DEFNODE("SymbolDefClass", null, {
4726 $documentation: "Symbol naming a class's name in a class declaration. Lexically scoped to its containing scope, and accessible within the class."
4727}, AST_SymbolBlockDeclaration);
4728
4729var AST_SymbolClass = DEFNODE("SymbolClass", null, {
4730 $documentation: "Symbol naming a class's name. Lexically scoped to the class."
4731}, AST_SymbolDeclaration);
4732
4733var AST_SymbolCatch = DEFNODE("SymbolCatch", null, {
4734 $documentation: "Symbol naming the exception in catch",
4735}, AST_SymbolBlockDeclaration);
4736
4737var AST_SymbolImport = DEFNODE("SymbolImport", null, {
4738 $documentation: "Symbol referring to an imported name",
4739}, AST_SymbolBlockDeclaration);
4740
4741var AST_SymbolImportForeign = DEFNODE("SymbolImportForeign", null, {
4742 $documentation: "A symbol imported from a module, but it is defined in the other module, and its real name is irrelevant for this module's purposes",
4743}, AST_Symbol);
4744
4745var AST_Label = DEFNODE("Label", "references", {
4746 $documentation: "Symbol naming a label (declaration)",
4747 $propdoc: {
4748 references: "[AST_LoopControl*] a list of nodes referring to this label"
4749 },
4750 initialize: function() {
4751 this.references = [];
4752 this.thedef = this;
4753 }
4754}, AST_Symbol);
4755
4756var AST_SymbolRef = DEFNODE("SymbolRef", null, {
4757 $documentation: "Reference to some symbol (not definition/declaration)",
4758}, AST_Symbol);
4759
4760var AST_SymbolExport = DEFNODE("SymbolExport", null, {
4761 $documentation: "Symbol referring to a name to export",
4762}, AST_SymbolRef);
4763
4764var AST_SymbolExportForeign = DEFNODE("SymbolExportForeign", null, {
4765 $documentation: "A symbol exported from this module, but it is used in the other module, and its real name is irrelevant for this module's purposes",
4766}, AST_Symbol);
4767
4768var AST_LabelRef = DEFNODE("LabelRef", null, {
4769 $documentation: "Reference to a label symbol",
4770}, AST_Symbol);
4771
4772var AST_This = DEFNODE("This", null, {
4773 $documentation: "The `this` symbol",
4774}, AST_Symbol);
4775
4776var AST_Super = DEFNODE("Super", null, {
4777 $documentation: "The `super` symbol",
4778}, AST_This);
4779
4780var AST_Constant = DEFNODE("Constant", null, {
4781 $documentation: "Base class for all constants",
4782 getValue: function() {
4783 return this.value;
4784 }
4785});
4786
4787var AST_String = DEFNODE("String", "value quote", {
4788 $documentation: "A string literal",
4789 $propdoc: {
4790 value: "[string] the contents of this string",
4791 quote: "[string] the original quote character"
4792 }
4793}, AST_Constant);
4794
4795var AST_Number = DEFNODE("Number", "value literal", {
4796 $documentation: "A number literal",
4797 $propdoc: {
4798 value: "[number] the numeric value",
4799 literal: "[string] numeric value as string (optional)"
4800 }
4801}, AST_Constant);
4802
4803var AST_BigInt = DEFNODE("BigInt", "value", {
4804 $documentation: "A big int literal",
4805 $propdoc: {
4806 value: "[string] big int value"
4807 }
4808}, AST_Constant);
4809
4810var AST_RegExp = DEFNODE("RegExp", "value", {
4811 $documentation: "A regexp literal",
4812 $propdoc: {
4813 value: "[RegExp] the actual regexp",
4814 }
4815}, AST_Constant);
4816
4817var AST_Atom = DEFNODE("Atom", null, {
4818 $documentation: "Base class for atoms",
4819}, AST_Constant);
4820
4821var AST_Null = DEFNODE("Null", null, {
4822 $documentation: "The `null` atom",
4823 value: null
4824}, AST_Atom);
4825
4826var AST_NaN = DEFNODE("NaN", null, {
4827 $documentation: "The impossible value",
4828 value: 0/0
4829}, AST_Atom);
4830
4831var AST_Undefined = DEFNODE("Undefined", null, {
4832 $documentation: "The `undefined` value",
4833 value: (function() {}())
4834}, AST_Atom);
4835
4836var AST_Hole = DEFNODE("Hole", null, {
4837 $documentation: "A hole in an array",
4838 value: (function() {}())
4839}, AST_Atom);
4840
4841var AST_Infinity = DEFNODE("Infinity", null, {
4842 $documentation: "The `Infinity` value",
4843 value: 1/0
4844}, AST_Atom);
4845
4846var AST_Boolean = DEFNODE("Boolean", null, {
4847 $documentation: "Base class for booleans",
4848}, AST_Atom);
4849
4850var AST_False = DEFNODE("False", null, {
4851 $documentation: "The `false` atom",
4852 value: false
4853}, AST_Boolean);
4854
4855var AST_True = DEFNODE("True", null, {
4856 $documentation: "The `true` atom",
4857 value: true
4858}, AST_Boolean);
4859
4860/* -----[ Walk function ]---- */
4861
4862/**
4863 * Walk nodes in depth-first search fashion.
4864 * Callback can return `walk_abort` symbol to stop iteration.
4865 * It can also return `true` to stop iteration just for child nodes.
4866 * Iteration can be stopped and continued by passing the `to_visit` argument,
4867 * which is given to the callback in the second argument.
4868 **/
4869function walk(node, cb, to_visit = [node]) {
4870 const push = to_visit.push.bind(to_visit);
4871 while (to_visit.length) {
4872 const node = to_visit.pop();
4873 const ret = cb(node, to_visit);
4874
4875 if (ret) {
4876 if (ret === walk_abort) return true;
4877 continue;
4878 }
4879
4880 node._children_backwards(push);
4881 }
4882 return false;
4883}
4884
4885function walk_parent(node, cb, initial_stack) {
4886 const to_visit = [node];
4887 const push = to_visit.push.bind(to_visit);
4888 const stack = initial_stack ? initial_stack.slice() : [];
4889 const parent_pop_indices = [];
4890
4891 let current;
4892
4893 const info = {
4894 parent: (n = 0) => {
4895 if (n === -1) {
4896 return current;
4897 }
4898
4899 // [ p1 p0 ] [ 1 0 ]
4900 if (initial_stack && n >= stack.length) {
4901 n -= stack.length;
4902 return initial_stack[
4903 initial_stack.length - (n + 1)
4904 ];
4905 }
4906
4907 return stack[stack.length - (1 + n)];
4908 },
4909 };
4910
4911 while (to_visit.length) {
4912 current = to_visit.pop();
4913
4914 while (
4915 parent_pop_indices.length &&
4916 to_visit.length == parent_pop_indices[parent_pop_indices.length - 1]
4917 ) {
4918 stack.pop();
4919 parent_pop_indices.pop();
4920 }
4921
4922 const ret = cb(current, info);
4923
4924 if (ret) {
4925 if (ret === walk_abort) return true;
4926 continue;
4927 }
4928
4929 const visit_length = to_visit.length;
4930
4931 current._children_backwards(push);
4932
4933 // Push only if we're going to traverse the children
4934 if (to_visit.length > visit_length) {
4935 stack.push(current);
4936 parent_pop_indices.push(visit_length - 1);
4937 }
4938 }
4939
4940 return false;
4941}
4942
4943const walk_abort = Symbol("abort walk");
4944
4945/* -----[ TreeWalker ]----- */
4946
4947class TreeWalker {
4948 constructor(callback) {
4949 this.visit = callback;
4950 this.stack = [];
4951 this.directives = Object.create(null);
4952 }
4953
4954 _visit(node, descend) {
4955 this.push(node);
4956 var ret = this.visit(node, descend ? function() {
4957 descend.call(node);
4958 } : noop);
4959 if (!ret && descend) {
4960 descend.call(node);
4961 }
4962 this.pop();
4963 return ret;
4964 }
4965
4966 parent(n) {
4967 return this.stack[this.stack.length - 2 - (n || 0)];
4968 }
4969
4970 push(node) {
4971 if (node instanceof AST_Lambda) {
4972 this.directives = Object.create(this.directives);
4973 } else if (node instanceof AST_Directive && !this.directives[node.value]) {
4974 this.directives[node.value] = node;
4975 } else if (node instanceof AST_Class) {
4976 this.directives = Object.create(this.directives);
4977 if (!this.directives["use strict"]) {
4978 this.directives["use strict"] = node;
4979 }
4980 }
4981 this.stack.push(node);
4982 }
4983
4984 pop() {
4985 var node = this.stack.pop();
4986 if (node instanceof AST_Lambda || node instanceof AST_Class) {
4987 this.directives = Object.getPrototypeOf(this.directives);
4988 }
4989 }
4990
4991 self() {
4992 return this.stack[this.stack.length - 1];
4993 }
4994
4995 find_parent(type) {
4996 var stack = this.stack;
4997 for (var i = stack.length; --i >= 0;) {
4998 var x = stack[i];
4999 if (x instanceof type) return x;
5000 }
5001 }
5002
5003 has_directive(type) {
5004 var dir = this.directives[type];
5005 if (dir) return dir;
5006 var node = this.stack[this.stack.length - 1];
5007 if (node instanceof AST_Scope && node.body) {
5008 for (var i = 0; i < node.body.length; ++i) {
5009 var st = node.body[i];
5010 if (!(st instanceof AST_Directive)) break;
5011 if (st.value == type) return st;
5012 }
5013 }
5014 }
5015
5016 loopcontrol_target(node) {
5017 var stack = this.stack;
5018 if (node.label) for (var i = stack.length; --i >= 0;) {
5019 var x = stack[i];
5020 if (x instanceof AST_LabeledStatement && x.label.name == node.label.name)
5021 return x.body;
5022 } else for (var i = stack.length; --i >= 0;) {
5023 var x = stack[i];
5024 if (x instanceof AST_IterationStatement
5025 || node instanceof AST_Break && x instanceof AST_Switch)
5026 return x;
5027 }
5028 }
5029}
5030
5031// Tree transformer helpers.
5032class TreeTransformer extends TreeWalker {
5033 constructor(before, after) {
5034 super();
5035 this.before = before;
5036 this.after = after;
5037 }
5038}
5039
5040const _PURE = 0b00000001;
5041const _INLINE = 0b00000010;
5042const _NOINLINE = 0b00000100;
5043
5044var ast = /*#__PURE__*/Object.freeze({
5045__proto__: null,
5046AST_Accessor: AST_Accessor,
5047AST_Array: AST_Array,
5048AST_Arrow: AST_Arrow,
5049AST_Assign: AST_Assign,
5050AST_Atom: AST_Atom,
5051AST_Await: AST_Await,
5052AST_BigInt: AST_BigInt,
5053AST_Binary: AST_Binary,
5054AST_Block: AST_Block,
5055AST_BlockStatement: AST_BlockStatement,
5056AST_Boolean: AST_Boolean,
5057AST_Break: AST_Break,
5058AST_Call: AST_Call,
5059AST_Case: AST_Case,
5060AST_Catch: AST_Catch,
5061AST_Chain: AST_Chain,
5062AST_Class: AST_Class,
5063AST_ClassExpression: AST_ClassExpression,
5064AST_ClassProperty: AST_ClassProperty,
5065AST_ConciseMethod: AST_ConciseMethod,
5066AST_Conditional: AST_Conditional,
5067AST_Const: AST_Const,
5068AST_Constant: AST_Constant,
5069AST_Continue: AST_Continue,
5070AST_Debugger: AST_Debugger,
5071AST_Default: AST_Default,
5072AST_DefaultAssign: AST_DefaultAssign,
5073AST_DefClass: AST_DefClass,
5074AST_Definitions: AST_Definitions,
5075AST_Defun: AST_Defun,
5076AST_Destructuring: AST_Destructuring,
5077AST_Directive: AST_Directive,
5078AST_Do: AST_Do,
5079AST_Dot: AST_Dot,
5080AST_DWLoop: AST_DWLoop,
5081AST_EmptyStatement: AST_EmptyStatement,
5082AST_Exit: AST_Exit,
5083AST_Expansion: AST_Expansion,
5084AST_Export: AST_Export,
5085AST_False: AST_False,
5086AST_Finally: AST_Finally,
5087AST_For: AST_For,
5088AST_ForIn: AST_ForIn,
5089AST_ForOf: AST_ForOf,
5090AST_Function: AST_Function,
5091AST_Hole: AST_Hole,
5092AST_If: AST_If,
5093AST_Import: AST_Import,
5094AST_ImportMeta: AST_ImportMeta,
5095AST_Infinity: AST_Infinity,
5096AST_IterationStatement: AST_IterationStatement,
5097AST_Jump: AST_Jump,
5098AST_Label: AST_Label,
5099AST_LabeledStatement: AST_LabeledStatement,
5100AST_LabelRef: AST_LabelRef,
5101AST_Lambda: AST_Lambda,
5102AST_Let: AST_Let,
5103AST_LoopControl: AST_LoopControl,
5104AST_NameMapping: AST_NameMapping,
5105AST_NaN: AST_NaN,
5106AST_New: AST_New,
5107AST_NewTarget: AST_NewTarget,
5108AST_Node: AST_Node,
5109AST_Null: AST_Null,
5110AST_Number: AST_Number,
5111AST_Object: AST_Object,
5112AST_ObjectGetter: AST_ObjectGetter,
5113AST_ObjectKeyVal: AST_ObjectKeyVal,
5114AST_ObjectProperty: AST_ObjectProperty,
5115AST_ObjectSetter: AST_ObjectSetter,
5116AST_PrefixedTemplateString: AST_PrefixedTemplateString,
5117AST_PropAccess: AST_PropAccess,
5118AST_RegExp: AST_RegExp,
5119AST_Return: AST_Return,
5120AST_Scope: AST_Scope,
5121AST_Sequence: AST_Sequence,
5122AST_SimpleStatement: AST_SimpleStatement,
5123AST_Statement: AST_Statement,
5124AST_StatementWithBody: AST_StatementWithBody,
5125AST_String: AST_String,
5126AST_Sub: AST_Sub,
5127AST_Super: AST_Super,
5128AST_Switch: AST_Switch,
5129AST_SwitchBranch: AST_SwitchBranch,
5130AST_Symbol: AST_Symbol,
5131AST_SymbolBlockDeclaration: AST_SymbolBlockDeclaration,
5132AST_SymbolCatch: AST_SymbolCatch,
5133AST_SymbolClass: AST_SymbolClass,
5134AST_SymbolClassProperty: AST_SymbolClassProperty,
5135AST_SymbolConst: AST_SymbolConst,
5136AST_SymbolDeclaration: AST_SymbolDeclaration,
5137AST_SymbolDefClass: AST_SymbolDefClass,
5138AST_SymbolDefun: AST_SymbolDefun,
5139AST_SymbolExport: AST_SymbolExport,
5140AST_SymbolExportForeign: AST_SymbolExportForeign,
5141AST_SymbolFunarg: AST_SymbolFunarg,
5142AST_SymbolImport: AST_SymbolImport,
5143AST_SymbolImportForeign: AST_SymbolImportForeign,
5144AST_SymbolLambda: AST_SymbolLambda,
5145AST_SymbolLet: AST_SymbolLet,
5146AST_SymbolMethod: AST_SymbolMethod,
5147AST_SymbolRef: AST_SymbolRef,
5148AST_SymbolVar: AST_SymbolVar,
5149AST_TemplateSegment: AST_TemplateSegment,
5150AST_TemplateString: AST_TemplateString,
5151AST_This: AST_This,
5152AST_Throw: AST_Throw,
5153AST_Token: AST_Token,
5154AST_Toplevel: AST_Toplevel,
5155AST_True: AST_True,
5156AST_Try: AST_Try,
5157AST_Unary: AST_Unary,
5158AST_UnaryPostfix: AST_UnaryPostfix,
5159AST_UnaryPrefix: AST_UnaryPrefix,
5160AST_Undefined: AST_Undefined,
5161AST_Var: AST_Var,
5162AST_VarDef: AST_VarDef,
5163AST_While: AST_While,
5164AST_With: AST_With,
5165AST_Yield: AST_Yield,
5166TreeTransformer: TreeTransformer,
5167TreeWalker: TreeWalker,
5168walk: walk,
5169walk_abort: walk_abort,
5170walk_body: walk_body,
5171walk_parent: walk_parent,
5172_INLINE: _INLINE,
5173_NOINLINE: _NOINLINE,
5174_PURE: _PURE
5175});
5176
5177/***********************************************************************
5178
5179 A JavaScript tokenizer / parser / beautifier / compressor.
5180 https://github.com/mishoo/UglifyJS2
5181
5182 -------------------------------- (C) ---------------------------------
5183
5184 Author: Mihai Bazon
5185 <mihai.bazon@gmail.com>
5186 http://mihai.bazon.net/blog
5187
5188 Distributed under the BSD license:
5189
5190 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
5191
5192 Redistribution and use in source and binary forms, with or without
5193 modification, are permitted provided that the following conditions
5194 are met:
5195
5196 * Redistributions of source code must retain the above
5197 copyright notice, this list of conditions and the following
5198 disclaimer.
5199
5200 * Redistributions in binary form must reproduce the above
5201 copyright notice, this list of conditions and the following
5202 disclaimer in the documentation and/or other materials
5203 provided with the distribution.
5204
5205 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
5206 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5207 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
5208 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
5209 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
5210 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
5211 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
5212 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
5213 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
5214 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
5215 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5216 SUCH DAMAGE.
5217
5218 ***********************************************************************/
5219
5220function def_transform(node, descend) {
5221 node.DEFMETHOD("transform", function(tw, in_list) {
5222 let transformed = undefined;
5223 tw.push(this);
5224 if (tw.before) transformed = tw.before(this, descend, in_list);
5225 if (transformed === undefined) {
5226 transformed = this;
5227 descend(transformed, tw);
5228 if (tw.after) {
5229 const after_ret = tw.after(transformed, in_list);
5230 if (after_ret !== undefined) transformed = after_ret;
5231 }
5232 }
5233 tw.pop();
5234 return transformed;
5235 });
5236}
5237
5238function do_list(list, tw) {
5239 return MAP(list, function(node) {
5240 return node.transform(tw, true);
5241 });
5242}
5243
5244def_transform(AST_Node, noop);
5245
5246def_transform(AST_LabeledStatement, function(self, tw) {
5247 self.label = self.label.transform(tw);
5248 self.body = self.body.transform(tw);
5249});
5250
5251def_transform(AST_SimpleStatement, function(self, tw) {
5252 self.body = self.body.transform(tw);
5253});
5254
5255def_transform(AST_Block, function(self, tw) {
5256 self.body = do_list(self.body, tw);
5257});
5258
5259def_transform(AST_Do, function(self, tw) {
5260 self.body = self.body.transform(tw);
5261 self.condition = self.condition.transform(tw);
5262});
5263
5264def_transform(AST_While, function(self, tw) {
5265 self.condition = self.condition.transform(tw);
5266 self.body = self.body.transform(tw);
5267});
5268
5269def_transform(AST_For, function(self, tw) {
5270 if (self.init) self.init = self.init.transform(tw);
5271 if (self.condition) self.condition = self.condition.transform(tw);
5272 if (self.step) self.step = self.step.transform(tw);
5273 self.body = self.body.transform(tw);
5274});
5275
5276def_transform(AST_ForIn, function(self, tw) {
5277 self.init = self.init.transform(tw);
5278 self.object = self.object.transform(tw);
5279 self.body = self.body.transform(tw);
5280});
5281
5282def_transform(AST_With, function(self, tw) {
5283 self.expression = self.expression.transform(tw);
5284 self.body = self.body.transform(tw);
5285});
5286
5287def_transform(AST_Exit, function(self, tw) {
5288 if (self.value) self.value = self.value.transform(tw);
5289});
5290
5291def_transform(AST_LoopControl, function(self, tw) {
5292 if (self.label) self.label = self.label.transform(tw);
5293});
5294
5295def_transform(AST_If, function(self, tw) {
5296 self.condition = self.condition.transform(tw);
5297 self.body = self.body.transform(tw);
5298 if (self.alternative) self.alternative = self.alternative.transform(tw);
5299});
5300
5301def_transform(AST_Switch, function(self, tw) {
5302 self.expression = self.expression.transform(tw);
5303 self.body = do_list(self.body, tw);
5304});
5305
5306def_transform(AST_Case, function(self, tw) {
5307 self.expression = self.expression.transform(tw);
5308 self.body = do_list(self.body, tw);
5309});
5310
5311def_transform(AST_Try, function(self, tw) {
5312 self.body = do_list(self.body, tw);
5313 if (self.bcatch) self.bcatch = self.bcatch.transform(tw);
5314 if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
5315});
5316
5317def_transform(AST_Catch, function(self, tw) {
5318 if (self.argname) self.argname = self.argname.transform(tw);
5319 self.body = do_list(self.body, tw);
5320});
5321
5322def_transform(AST_Definitions, function(self, tw) {
5323 self.definitions = do_list(self.definitions, tw);
5324});
5325
5326def_transform(AST_VarDef, function(self, tw) {
5327 self.name = self.name.transform(tw);
5328 if (self.value) self.value = self.value.transform(tw);
5329});
5330
5331def_transform(AST_Destructuring, function(self, tw) {
5332 self.names = do_list(self.names, tw);
5333});
5334
5335def_transform(AST_Lambda, function(self, tw) {
5336 if (self.name) self.name = self.name.transform(tw);
5337 self.argnames = do_list(self.argnames, tw);
5338 if (self.body instanceof AST_Node) {
5339 self.body = self.body.transform(tw);
5340 } else {
5341 self.body = do_list(self.body, tw);
5342 }
5343});
5344
5345def_transform(AST_Call, function(self, tw) {
5346 self.expression = self.expression.transform(tw);
5347 self.args = do_list(self.args, tw);
5348});
5349
5350def_transform(AST_Sequence, function(self, tw) {
5351 const result = do_list(self.expressions, tw);
5352 self.expressions = result.length
5353 ? result
5354 : [new AST_Number({ value: 0 })];
5355});
5356
5357def_transform(AST_Dot, function(self, tw) {
5358 self.expression = self.expression.transform(tw);
5359});
5360
5361def_transform(AST_Sub, function(self, tw) {
5362 self.expression = self.expression.transform(tw);
5363 self.property = self.property.transform(tw);
5364});
5365
5366def_transform(AST_Chain, function(self, tw) {
5367 self.expression = self.expression.transform(tw);
5368});
5369
5370def_transform(AST_Yield, function(self, tw) {
5371 if (self.expression) self.expression = self.expression.transform(tw);
5372});
5373
5374def_transform(AST_Await, function(self, tw) {
5375 self.expression = self.expression.transform(tw);
5376});
5377
5378def_transform(AST_Unary, function(self, tw) {
5379 self.expression = self.expression.transform(tw);
5380});
5381
5382def_transform(AST_Binary, function(self, tw) {
5383 self.left = self.left.transform(tw);
5384 self.right = self.right.transform(tw);
5385});
5386
5387def_transform(AST_Conditional, function(self, tw) {
5388 self.condition = self.condition.transform(tw);
5389 self.consequent = self.consequent.transform(tw);
5390 self.alternative = self.alternative.transform(tw);
5391});
5392
5393def_transform(AST_Array, function(self, tw) {
5394 self.elements = do_list(self.elements, tw);
5395});
5396
5397def_transform(AST_Object, function(self, tw) {
5398 self.properties = do_list(self.properties, tw);
5399});
5400
5401def_transform(AST_ObjectProperty, function(self, tw) {
5402 if (self.key instanceof AST_Node) {
5403 self.key = self.key.transform(tw);
5404 }
5405 if (self.value) self.value = self.value.transform(tw);
5406});
5407
5408def_transform(AST_Class, function(self, tw) {
5409 if (self.name) self.name = self.name.transform(tw);
5410 if (self.extends) self.extends = self.extends.transform(tw);
5411 self.properties = do_list(self.properties, tw);
5412});
5413
5414def_transform(AST_Expansion, function(self, tw) {
5415 self.expression = self.expression.transform(tw);
5416});
5417
5418def_transform(AST_NameMapping, function(self, tw) {
5419 self.foreign_name = self.foreign_name.transform(tw);
5420 self.name = self.name.transform(tw);
5421});
5422
5423def_transform(AST_Import, function(self, tw) {
5424 if (self.imported_name) self.imported_name = self.imported_name.transform(tw);
5425 if (self.imported_names) do_list(self.imported_names, tw);
5426 self.module_name = self.module_name.transform(tw);
5427});
5428
5429def_transform(AST_Export, function(self, tw) {
5430 if (self.exported_definition) self.exported_definition = self.exported_definition.transform(tw);
5431 if (self.exported_value) self.exported_value = self.exported_value.transform(tw);
5432 if (self.exported_names) do_list(self.exported_names, tw);
5433 if (self.module_name) self.module_name = self.module_name.transform(tw);
5434});
5435
5436def_transform(AST_TemplateString, function(self, tw) {
5437 self.segments = do_list(self.segments, tw);
5438});
5439
5440def_transform(AST_PrefixedTemplateString, function(self, tw) {
5441 self.prefix = self.prefix.transform(tw);
5442 self.template_string = self.template_string.transform(tw);
5443});
5444
5445/***********************************************************************
5446
5447 A JavaScript tokenizer / parser / beautifier / compressor.
5448 https://github.com/mishoo/UglifyJS2
5449
5450 -------------------------------- (C) ---------------------------------
5451
5452 Author: Mihai Bazon
5453 <mihai.bazon@gmail.com>
5454 http://mihai.bazon.net/blog
5455
5456 Distributed under the BSD license:
5457
5458 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
5459
5460 Redistribution and use in source and binary forms, with or without
5461 modification, are permitted provided that the following conditions
5462 are met:
5463
5464 * Redistributions of source code must retain the above
5465 copyright notice, this list of conditions and the following
5466 disclaimer.
5467
5468 * Redistributions in binary form must reproduce the above
5469 copyright notice, this list of conditions and the following
5470 disclaimer in the documentation and/or other materials
5471 provided with the distribution.
5472
5473 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
5474 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5475 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
5476 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
5477 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
5478 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
5479 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
5480 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
5481 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
5482 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
5483 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5484 SUCH DAMAGE.
5485
5486 ***********************************************************************/
5487
5488(function() {
5489
5490 var normalize_directives = function(body) {
5491 var in_directive = true;
5492
5493 for (var i = 0; i < body.length; i++) {
5494 if (in_directive && body[i] instanceof AST_Statement && body[i].body instanceof AST_String) {
5495 body[i] = new AST_Directive({
5496 start: body[i].start,
5497 end: body[i].end,
5498 value: body[i].body.value
5499 });
5500 } else if (in_directive && !(body[i] instanceof AST_Statement && body[i].body instanceof AST_String)) {
5501 in_directive = false;
5502 }
5503 }
5504
5505 return body;
5506 };
5507
5508 var MOZ_TO_ME = {
5509 Program: function(M) {
5510 return new AST_Toplevel({
5511 start: my_start_token(M),
5512 end: my_end_token(M),
5513 body: normalize_directives(M.body.map(from_moz))
5514 });
5515 },
5516 ArrayPattern: function(M) {
5517 return new AST_Destructuring({
5518 start: my_start_token(M),
5519 end: my_end_token(M),
5520 names: M.elements.map(function(elm) {
5521 if (elm === null) {
5522 return new AST_Hole();
5523 }
5524 return from_moz(elm);
5525 }),
5526 is_array: true
5527 });
5528 },
5529 ObjectPattern: function(M) {
5530 return new AST_Destructuring({
5531 start: my_start_token(M),
5532 end: my_end_token(M),
5533 names: M.properties.map(from_moz),
5534 is_array: false
5535 });
5536 },
5537 AssignmentPattern: function(M) {
5538 return new AST_DefaultAssign({
5539 start: my_start_token(M),
5540 end: my_end_token(M),
5541 left: from_moz(M.left),
5542 operator: "=",
5543 right: from_moz(M.right)
5544 });
5545 },
5546 SpreadElement: function(M) {
5547 return new AST_Expansion({
5548 start: my_start_token(M),
5549 end: my_end_token(M),
5550 expression: from_moz(M.argument)
5551 });
5552 },
5553 RestElement: function(M) {
5554 return new AST_Expansion({
5555 start: my_start_token(M),
5556 end: my_end_token(M),
5557 expression: from_moz(M.argument)
5558 });
5559 },
5560 TemplateElement: function(M) {
5561 return new AST_TemplateSegment({
5562 start: my_start_token(M),
5563 end: my_end_token(M),
5564 value: M.value.cooked,
5565 raw: M.value.raw
5566 });
5567 },
5568 TemplateLiteral: function(M) {
5569 var segments = [];
5570 for (var i = 0; i < M.quasis.length; i++) {
5571 segments.push(from_moz(M.quasis[i]));
5572 if (M.expressions[i]) {
5573 segments.push(from_moz(M.expressions[i]));
5574 }
5575 }
5576 return new AST_TemplateString({
5577 start: my_start_token(M),
5578 end: my_end_token(M),
5579 segments: segments
5580 });
5581 },
5582 TaggedTemplateExpression: function(M) {
5583 return new AST_PrefixedTemplateString({
5584 start: my_start_token(M),
5585 end: my_end_token(M),
5586 template_string: from_moz(M.quasi),
5587 prefix: from_moz(M.tag)
5588 });
5589 },
5590 FunctionDeclaration: function(M) {
5591 return new AST_Defun({
5592 start: my_start_token(M),
5593 end: my_end_token(M),
5594 name: from_moz(M.id),
5595 argnames: M.params.map(from_moz),
5596 is_generator: M.generator,
5597 async: M.async,
5598 body: normalize_directives(from_moz(M.body).body)
5599 });
5600 },
5601 FunctionExpression: function(M) {
5602 return new AST_Function({
5603 start: my_start_token(M),
5604 end: my_end_token(M),
5605 name: from_moz(M.id),
5606 argnames: M.params.map(from_moz),
5607 is_generator: M.generator,
5608 async: M.async,
5609 body: normalize_directives(from_moz(M.body).body)
5610 });
5611 },
5612 ArrowFunctionExpression: function(M) {
5613 const body = M.body.type === "BlockStatement"
5614 ? from_moz(M.body).body
5615 : [make_node(AST_Return, {}, { value: from_moz(M.body) })];
5616 return new AST_Arrow({
5617 start: my_start_token(M),
5618 end: my_end_token(M),
5619 argnames: M.params.map(from_moz),
5620 body,
5621 async: M.async,
5622 });
5623 },
5624 ExpressionStatement: function(M) {
5625 return new AST_SimpleStatement({
5626 start: my_start_token(M),
5627 end: my_end_token(M),
5628 body: from_moz(M.expression)
5629 });
5630 },
5631 TryStatement: function(M) {
5632 var handlers = M.handlers || [M.handler];
5633 if (handlers.length > 1 || M.guardedHandlers && M.guardedHandlers.length) {
5634 throw new Error("Multiple catch clauses are not supported.");
5635 }
5636 return new AST_Try({
5637 start : my_start_token(M),
5638 end : my_end_token(M),
5639 body : from_moz(M.block).body,
5640 bcatch : from_moz(handlers[0]),
5641 bfinally : M.finalizer ? new AST_Finally(from_moz(M.finalizer)) : null
5642 });
5643 },
5644 Property: function(M) {
5645 var key = M.key;
5646 var args = {
5647 start : my_start_token(key || M.value),
5648 end : my_end_token(M.value),
5649 key : key.type == "Identifier" ? key.name : key.value,
5650 value : from_moz(M.value)
5651 };
5652 if (M.computed) {
5653 args.key = from_moz(M.key);
5654 }
5655 if (M.method) {
5656 args.is_generator = M.value.generator;
5657 args.async = M.value.async;
5658 if (!M.computed) {
5659 args.key = new AST_SymbolMethod({ name: args.key });
5660 } else {
5661 args.key = from_moz(M.key);
5662 }
5663 return new AST_ConciseMethod(args);
5664 }
5665 if (M.kind == "init") {
5666 if (key.type != "Identifier" && key.type != "Literal") {
5667 args.key = from_moz(key);
5668 }
5669 return new AST_ObjectKeyVal(args);
5670 }
5671 if (typeof args.key === "string" || typeof args.key === "number") {
5672 args.key = new AST_SymbolMethod({
5673 name: args.key
5674 });
5675 }
5676 args.value = new AST_Accessor(args.value);
5677 if (M.kind == "get") return new AST_ObjectGetter(args);
5678 if (M.kind == "set") return new AST_ObjectSetter(args);
5679 if (M.kind == "method") {
5680 args.async = M.value.async;
5681 args.is_generator = M.value.generator;
5682 args.quote = M.computed ? "\"" : null;
5683 return new AST_ConciseMethod(args);
5684 }
5685 },
5686 MethodDefinition: function(M) {
5687 var args = {
5688 start : my_start_token(M),
5689 end : my_end_token(M),
5690 key : M.computed ? from_moz(M.key) : new AST_SymbolMethod({ name: M.key.name || M.key.value }),
5691 value : from_moz(M.value),
5692 static : M.static,
5693 };
5694 if (M.kind == "get") {
5695 return new AST_ObjectGetter(args);
5696 }
5697 if (M.kind == "set") {
5698 return new AST_ObjectSetter(args);
5699 }
5700 args.is_generator = M.value.generator;
5701 args.async = M.value.async;
5702 return new AST_ConciseMethod(args);
5703 },
5704 FieldDefinition: function(M) {
5705 let key;
5706 if (M.computed) {
5707 key = from_moz(M.key);
5708 } else {
5709 if (M.key.type !== "Identifier") throw new Error("Non-Identifier key in FieldDefinition");
5710 key = from_moz(M.key);
5711 }
5712 return new AST_ClassProperty({
5713 start : my_start_token(M),
5714 end : my_end_token(M),
5715 key,
5716 value : from_moz(M.value),
5717 static : M.static,
5718 });
5719 },
5720 ArrayExpression: function(M) {
5721 return new AST_Array({
5722 start : my_start_token(M),
5723 end : my_end_token(M),
5724 elements : M.elements.map(function(elem) {
5725 return elem === null ? new AST_Hole() : from_moz(elem);
5726 })
5727 });
5728 },
5729 ObjectExpression: function(M) {
5730 return new AST_Object({
5731 start : my_start_token(M),
5732 end : my_end_token(M),
5733 properties : M.properties.map(function(prop) {
5734 if (prop.type === "SpreadElement") {
5735 return from_moz(prop);
5736 }
5737 prop.type = "Property";
5738 return from_moz(prop);
5739 })
5740 });
5741 },
5742 SequenceExpression: function(M) {
5743 return new AST_Sequence({
5744 start : my_start_token(M),
5745 end : my_end_token(M),
5746 expressions: M.expressions.map(from_moz)
5747 });
5748 },
5749 MemberExpression: function(M) {
5750 return new (M.computed ? AST_Sub : AST_Dot)({
5751 start : my_start_token(M),
5752 end : my_end_token(M),
5753 property : M.computed ? from_moz(M.property) : M.property.name,
5754 expression : from_moz(M.object),
5755 optional : M.optional || false
5756 });
5757 },
5758 ChainExpression: function(M) {
5759 return new AST_Chain({
5760 start : my_start_token(M),
5761 end : my_end_token(M),
5762 expression : from_moz(M.expression)
5763 });
5764 },
5765 SwitchCase: function(M) {
5766 return new (M.test ? AST_Case : AST_Default)({
5767 start : my_start_token(M),
5768 end : my_end_token(M),
5769 expression : from_moz(M.test),
5770 body : M.consequent.map(from_moz)
5771 });
5772 },
5773 VariableDeclaration: function(M) {
5774 return new (M.kind === "const" ? AST_Const :
5775 M.kind === "let" ? AST_Let : AST_Var)({
5776 start : my_start_token(M),
5777 end : my_end_token(M),
5778 definitions : M.declarations.map(from_moz)
5779 });
5780 },
5781
5782 ImportDeclaration: function(M) {
5783 var imported_name = null;
5784 var imported_names = null;
5785 M.specifiers.forEach(function (specifier) {
5786 if (specifier.type === "ImportSpecifier") {
5787 if (!imported_names) { imported_names = []; }
5788 imported_names.push(new AST_NameMapping({
5789 start: my_start_token(specifier),
5790 end: my_end_token(specifier),
5791 foreign_name: from_moz(specifier.imported),
5792 name: from_moz(specifier.local)
5793 }));
5794 } else if (specifier.type === "ImportDefaultSpecifier") {
5795 imported_name = from_moz(specifier.local);
5796 } else if (specifier.type === "ImportNamespaceSpecifier") {
5797 if (!imported_names) { imported_names = []; }
5798 imported_names.push(new AST_NameMapping({
5799 start: my_start_token(specifier),
5800 end: my_end_token(specifier),
5801 foreign_name: new AST_SymbolImportForeign({ name: "*" }),
5802 name: from_moz(specifier.local)
5803 }));
5804 }
5805 });
5806 return new AST_Import({
5807 start : my_start_token(M),
5808 end : my_end_token(M),
5809 imported_name: imported_name,
5810 imported_names : imported_names,
5811 module_name : from_moz(M.source)
5812 });
5813 },
5814 ExportAllDeclaration: function(M) {
5815 return new AST_Export({
5816 start: my_start_token(M),
5817 end: my_end_token(M),
5818 exported_names: [
5819 new AST_NameMapping({
5820 name: new AST_SymbolExportForeign({ name: "*" }),
5821 foreign_name: new AST_SymbolExportForeign({ name: "*" })
5822 })
5823 ],
5824 module_name: from_moz(M.source)
5825 });
5826 },
5827 ExportNamedDeclaration: function(M) {
5828 return new AST_Export({
5829 start: my_start_token(M),
5830 end: my_end_token(M),
5831 exported_definition: from_moz(M.declaration),
5832 exported_names: M.specifiers && M.specifiers.length ? M.specifiers.map(function (specifier) {
5833 return new AST_NameMapping({
5834 foreign_name: from_moz(specifier.exported),
5835 name: from_moz(specifier.local)
5836 });
5837 }) : null,
5838 module_name: from_moz(M.source)
5839 });
5840 },
5841 ExportDefaultDeclaration: function(M) {
5842 return new AST_Export({
5843 start: my_start_token(M),
5844 end: my_end_token(M),
5845 exported_value: from_moz(M.declaration),
5846 is_default: true
5847 });
5848 },
5849 Literal: function(M) {
5850 var val = M.value, args = {
5851 start : my_start_token(M),
5852 end : my_end_token(M)
5853 };
5854 var rx = M.regex;
5855 if (rx && rx.pattern) {
5856 // RegExpLiteral as per ESTree AST spec
5857 args.value = {
5858 source: rx.pattern,
5859 flags: rx.flags
5860 };
5861 return new AST_RegExp(args);
5862 } else if (rx) {
5863 // support legacy RegExp
5864 const rx_source = M.raw || val;
5865 const match = rx_source.match(/^\/(.*)\/(\w*)$/);
5866 if (!match) throw new Error("Invalid regex source " + rx_source);
5867 const [_, source, flags] = match;
5868 args.value = { source, flags };
5869 return new AST_RegExp(args);
5870 }
5871 if (val === null) return new AST_Null(args);
5872 switch (typeof val) {
5873 case "string":
5874 args.value = val;
5875 return new AST_String(args);
5876 case "number":
5877 args.value = val;
5878 return new AST_Number(args);
5879 case "boolean":
5880 return new (val ? AST_True : AST_False)(args);
5881 }
5882 },
5883 MetaProperty: function(M) {
5884 if (M.meta.name === "new" && M.property.name === "target") {
5885 return new AST_NewTarget({
5886 start: my_start_token(M),
5887 end: my_end_token(M)
5888 });
5889 } else if (M.meta.name === "import" && M.property.name === "meta") {
5890 return new AST_ImportMeta({
5891 start: my_start_token(M),
5892 end: my_end_token(M)
5893 });
5894 }
5895 },
5896 Identifier: function(M) {
5897 var p = FROM_MOZ_STACK[FROM_MOZ_STACK.length - 2];
5898 return new ( p.type == "LabeledStatement" ? AST_Label
5899 : p.type == "VariableDeclarator" && p.id === M ? (p.kind == "const" ? AST_SymbolConst : p.kind == "let" ? AST_SymbolLet : AST_SymbolVar)
5900 : /Import.*Specifier/.test(p.type) ? (p.local === M ? AST_SymbolImport : AST_SymbolImportForeign)
5901 : p.type == "ExportSpecifier" ? (p.local === M ? AST_SymbolExport : AST_SymbolExportForeign)
5902 : p.type == "FunctionExpression" ? (p.id === M ? AST_SymbolLambda : AST_SymbolFunarg)
5903 : p.type == "FunctionDeclaration" ? (p.id === M ? AST_SymbolDefun : AST_SymbolFunarg)
5904 : p.type == "ArrowFunctionExpression" ? (p.params.includes(M)) ? AST_SymbolFunarg : AST_SymbolRef
5905 : p.type == "ClassExpression" ? (p.id === M ? AST_SymbolClass : AST_SymbolRef)
5906 : p.type == "Property" ? (p.key === M && p.computed || p.value === M ? AST_SymbolRef : AST_SymbolMethod)
5907 : p.type == "FieldDefinition" ? (p.key === M && p.computed || p.value === M ? AST_SymbolRef : AST_SymbolClassProperty)
5908 : p.type == "ClassDeclaration" ? (p.id === M ? AST_SymbolDefClass : AST_SymbolRef)
5909 : p.type == "MethodDefinition" ? (p.computed ? AST_SymbolRef : AST_SymbolMethod)
5910 : p.type == "CatchClause" ? AST_SymbolCatch
5911 : p.type == "BreakStatement" || p.type == "ContinueStatement" ? AST_LabelRef
5912 : AST_SymbolRef)({
5913 start : my_start_token(M),
5914 end : my_end_token(M),
5915 name : M.name
5916 });
5917 },
5918 BigIntLiteral(M) {
5919 return new AST_BigInt({
5920 start : my_start_token(M),
5921 end : my_end_token(M),
5922 value : M.value
5923 });
5924 }
5925 };
5926
5927 MOZ_TO_ME.UpdateExpression =
5928 MOZ_TO_ME.UnaryExpression = function To_Moz_Unary(M) {
5929 var prefix = "prefix" in M ? M.prefix
5930 : M.type == "UnaryExpression" ? true : false;
5931 return new (prefix ? AST_UnaryPrefix : AST_UnaryPostfix)({
5932 start : my_start_token(M),
5933 end : my_end_token(M),
5934 operator : M.operator,
5935 expression : from_moz(M.argument)
5936 });
5937 };
5938
5939 MOZ_TO_ME.ClassDeclaration =
5940 MOZ_TO_ME.ClassExpression = function From_Moz_Class(M) {
5941 return new (M.type === "ClassDeclaration" ? AST_DefClass : AST_ClassExpression)({
5942 start : my_start_token(M),
5943 end : my_end_token(M),
5944 name : from_moz(M.id),
5945 extends : from_moz(M.superClass),
5946 properties: M.body.body.map(from_moz)
5947 });
5948 };
5949
5950 map("EmptyStatement", AST_EmptyStatement);
5951 map("BlockStatement", AST_BlockStatement, "body@body");
5952 map("IfStatement", AST_If, "test>condition, consequent>body, alternate>alternative");
5953 map("LabeledStatement", AST_LabeledStatement, "label>label, body>body");
5954 map("BreakStatement", AST_Break, "label>label");
5955 map("ContinueStatement", AST_Continue, "label>label");
5956 map("WithStatement", AST_With, "object>expression, body>body");
5957 map("SwitchStatement", AST_Switch, "discriminant>expression, cases@body");
5958 map("ReturnStatement", AST_Return, "argument>value");
5959 map("ThrowStatement", AST_Throw, "argument>value");
5960 map("WhileStatement", AST_While, "test>condition, body>body");
5961 map("DoWhileStatement", AST_Do, "test>condition, body>body");
5962 map("ForStatement", AST_For, "init>init, test>condition, update>step, body>body");
5963 map("ForInStatement", AST_ForIn, "left>init, right>object, body>body");
5964 map("ForOfStatement", AST_ForOf, "left>init, right>object, body>body, await=await");
5965 map("AwaitExpression", AST_Await, "argument>expression");
5966 map("YieldExpression", AST_Yield, "argument>expression, delegate=is_star");
5967 map("DebuggerStatement", AST_Debugger);
5968 map("VariableDeclarator", AST_VarDef, "id>name, init>value");
5969 map("CatchClause", AST_Catch, "param>argname, body%body");
5970
5971 map("ThisExpression", AST_This);
5972 map("Super", AST_Super);
5973 map("BinaryExpression", AST_Binary, "operator=operator, left>left, right>right");
5974 map("LogicalExpression", AST_Binary, "operator=operator, left>left, right>right");
5975 map("AssignmentExpression", AST_Assign, "operator=operator, left>left, right>right");
5976 map("ConditionalExpression", AST_Conditional, "test>condition, consequent>consequent, alternate>alternative");
5977 map("NewExpression", AST_New, "callee>expression, arguments@args");
5978 map("CallExpression", AST_Call, "callee>expression, optional=optional, arguments@args");
5979
5980 def_to_moz(AST_Toplevel, function To_Moz_Program(M) {
5981 return to_moz_scope("Program", M);
5982 });
5983
5984 def_to_moz(AST_Expansion, function To_Moz_Spread(M) {
5985 return {
5986 type: to_moz_in_destructuring() ? "RestElement" : "SpreadElement",
5987 argument: to_moz(M.expression)
5988 };
5989 });
5990
5991 def_to_moz(AST_PrefixedTemplateString, function To_Moz_TaggedTemplateExpression(M) {
5992 return {
5993 type: "TaggedTemplateExpression",
5994 tag: to_moz(M.prefix),
5995 quasi: to_moz(M.template_string)
5996 };
5997 });
5998
5999 def_to_moz(AST_TemplateString, function To_Moz_TemplateLiteral(M) {
6000 var quasis = [];
6001 var expressions = [];
6002 for (var i = 0; i < M.segments.length; i++) {
6003 if (i % 2 !== 0) {
6004 expressions.push(to_moz(M.segments[i]));
6005 } else {
6006 quasis.push({
6007 type: "TemplateElement",
6008 value: {
6009 raw: M.segments[i].raw,
6010 cooked: M.segments[i].value
6011 },
6012 tail: i === M.segments.length - 1
6013 });
6014 }
6015 }
6016 return {
6017 type: "TemplateLiteral",
6018 quasis: quasis,
6019 expressions: expressions
6020 };
6021 });
6022
6023 def_to_moz(AST_Defun, function To_Moz_FunctionDeclaration(M) {
6024 return {
6025 type: "FunctionDeclaration",
6026 id: to_moz(M.name),
6027 params: M.argnames.map(to_moz),
6028 generator: M.is_generator,
6029 async: M.async,
6030 body: to_moz_scope("BlockStatement", M)
6031 };
6032 });
6033
6034 def_to_moz(AST_Function, function To_Moz_FunctionExpression(M, parent) {
6035 var is_generator = parent.is_generator !== undefined ?
6036 parent.is_generator : M.is_generator;
6037 return {
6038 type: "FunctionExpression",
6039 id: to_moz(M.name),
6040 params: M.argnames.map(to_moz),
6041 generator: is_generator,
6042 async: M.async,
6043 body: to_moz_scope("BlockStatement", M)
6044 };
6045 });
6046
6047 def_to_moz(AST_Arrow, function To_Moz_ArrowFunctionExpression(M) {
6048 var body = {
6049 type: "BlockStatement",
6050 body: M.body.map(to_moz)
6051 };
6052 return {
6053 type: "ArrowFunctionExpression",
6054 params: M.argnames.map(to_moz),
6055 async: M.async,
6056 body: body
6057 };
6058 });
6059
6060 def_to_moz(AST_Destructuring, function To_Moz_ObjectPattern(M) {
6061 if (M.is_array) {
6062 return {
6063 type: "ArrayPattern",
6064 elements: M.names.map(to_moz)
6065 };
6066 }
6067 return {
6068 type: "ObjectPattern",
6069 properties: M.names.map(to_moz)
6070 };
6071 });
6072
6073 def_to_moz(AST_Directive, function To_Moz_Directive(M) {
6074 return {
6075 type: "ExpressionStatement",
6076 expression: {
6077 type: "Literal",
6078 value: M.value,
6079 raw: M.print_to_string()
6080 },
6081 directive: M.value
6082 };
6083 });
6084
6085 def_to_moz(AST_SimpleStatement, function To_Moz_ExpressionStatement(M) {
6086 return {
6087 type: "ExpressionStatement",
6088 expression: to_moz(M.body)
6089 };
6090 });
6091
6092 def_to_moz(AST_SwitchBranch, function To_Moz_SwitchCase(M) {
6093 return {
6094 type: "SwitchCase",
6095 test: to_moz(M.expression),
6096 consequent: M.body.map(to_moz)
6097 };
6098 });
6099
6100 def_to_moz(AST_Try, function To_Moz_TryStatement(M) {
6101 return {
6102 type: "TryStatement",
6103 block: to_moz_block(M),
6104 handler: to_moz(M.bcatch),
6105 guardedHandlers: [],
6106 finalizer: to_moz(M.bfinally)
6107 };
6108 });
6109
6110 def_to_moz(AST_Catch, function To_Moz_CatchClause(M) {
6111 return {
6112 type: "CatchClause",
6113 param: to_moz(M.argname),
6114 guard: null,
6115 body: to_moz_block(M)
6116 };
6117 });
6118
6119 def_to_moz(AST_Definitions, function To_Moz_VariableDeclaration(M) {
6120 return {
6121 type: "VariableDeclaration",
6122 kind:
6123 M instanceof AST_Const ? "const" :
6124 M instanceof AST_Let ? "let" : "var",
6125 declarations: M.definitions.map(to_moz)
6126 };
6127 });
6128
6129 def_to_moz(AST_Export, function To_Moz_ExportDeclaration(M) {
6130 if (M.exported_names) {
6131 if (M.exported_names[0].name.name === "*") {
6132 return {
6133 type: "ExportAllDeclaration",
6134 source: to_moz(M.module_name)
6135 };
6136 }
6137 return {
6138 type: "ExportNamedDeclaration",
6139 specifiers: M.exported_names.map(function (name_mapping) {
6140 return {
6141 type: "ExportSpecifier",
6142 exported: to_moz(name_mapping.foreign_name),
6143 local: to_moz(name_mapping.name)
6144 };
6145 }),
6146 declaration: to_moz(M.exported_definition),
6147 source: to_moz(M.module_name)
6148 };
6149 }
6150 return {
6151 type: M.is_default ? "ExportDefaultDeclaration" : "ExportNamedDeclaration",
6152 declaration: to_moz(M.exported_value || M.exported_definition)
6153 };
6154 });
6155
6156 def_to_moz(AST_Import, function To_Moz_ImportDeclaration(M) {
6157 var specifiers = [];
6158 if (M.imported_name) {
6159 specifiers.push({
6160 type: "ImportDefaultSpecifier",
6161 local: to_moz(M.imported_name)
6162 });
6163 }
6164 if (M.imported_names && M.imported_names[0].foreign_name.name === "*") {
6165 specifiers.push({
6166 type: "ImportNamespaceSpecifier",
6167 local: to_moz(M.imported_names[0].name)
6168 });
6169 } else if (M.imported_names) {
6170 M.imported_names.forEach(function(name_mapping) {
6171 specifiers.push({
6172 type: "ImportSpecifier",
6173 local: to_moz(name_mapping.name),
6174 imported: to_moz(name_mapping.foreign_name)
6175 });
6176 });
6177 }
6178 return {
6179 type: "ImportDeclaration",
6180 specifiers: specifiers,
6181 source: to_moz(M.module_name)
6182 };
6183 });
6184
6185 def_to_moz(AST_ImportMeta, function To_Moz_MetaProperty() {
6186 return {
6187 type: "MetaProperty",
6188 meta: {
6189 type: "Identifier",
6190 name: "import"
6191 },
6192 property: {
6193 type: "Identifier",
6194 name: "meta"
6195 }
6196 };
6197 });
6198
6199 def_to_moz(AST_Sequence, function To_Moz_SequenceExpression(M) {
6200 return {
6201 type: "SequenceExpression",
6202 expressions: M.expressions.map(to_moz)
6203 };
6204 });
6205
6206 def_to_moz(AST_PropAccess, function To_Moz_MemberExpression(M) {
6207 var isComputed = M instanceof AST_Sub;
6208 return {
6209 type: "MemberExpression",
6210 object: to_moz(M.expression),
6211 computed: isComputed,
6212 property: isComputed ? to_moz(M.property) : {type: "Identifier", name: M.property},
6213 optional: M.optional
6214 };
6215 });
6216
6217 def_to_moz(AST_Chain, function To_Moz_ChainExpression(M) {
6218 return {
6219 type: "ChainExpression",
6220 expression: to_moz(M.expression)
6221 };
6222 });
6223
6224 def_to_moz(AST_Unary, function To_Moz_Unary(M) {
6225 return {
6226 type: M.operator == "++" || M.operator == "--" ? "UpdateExpression" : "UnaryExpression",
6227 operator: M.operator,
6228 prefix: M instanceof AST_UnaryPrefix,
6229 argument: to_moz(M.expression)
6230 };
6231 });
6232
6233 def_to_moz(AST_Binary, function To_Moz_BinaryExpression(M) {
6234 if (M.operator == "=" && to_moz_in_destructuring()) {
6235 return {
6236 type: "AssignmentPattern",
6237 left: to_moz(M.left),
6238 right: to_moz(M.right)
6239 };
6240 }
6241
6242 const type = M.operator == "&&" || M.operator == "||" || M.operator === "??"
6243 ? "LogicalExpression"
6244 : "BinaryExpression";
6245
6246 return {
6247 type,
6248 left: to_moz(M.left),
6249 operator: M.operator,
6250 right: to_moz(M.right)
6251 };
6252 });
6253
6254 def_to_moz(AST_Array, function To_Moz_ArrayExpression(M) {
6255 return {
6256 type: "ArrayExpression",
6257 elements: M.elements.map(to_moz)
6258 };
6259 });
6260
6261 def_to_moz(AST_Object, function To_Moz_ObjectExpression(M) {
6262 return {
6263 type: "ObjectExpression",
6264 properties: M.properties.map(to_moz)
6265 };
6266 });
6267
6268 def_to_moz(AST_ObjectProperty, function To_Moz_Property(M, parent) {
6269 var key = M.key instanceof AST_Node ? to_moz(M.key) : {
6270 type: "Identifier",
6271 value: M.key
6272 };
6273 if (typeof M.key === "number") {
6274 key = {
6275 type: "Literal",
6276 value: Number(M.key)
6277 };
6278 }
6279 if (typeof M.key === "string") {
6280 key = {
6281 type: "Identifier",
6282 name: M.key
6283 };
6284 }
6285 var kind;
6286 var string_or_num = typeof M.key === "string" || typeof M.key === "number";
6287 var computed = string_or_num ? false : !(M.key instanceof AST_Symbol) || M.key instanceof AST_SymbolRef;
6288 if (M instanceof AST_ObjectKeyVal) {
6289 kind = "init";
6290 computed = !string_or_num;
6291 } else
6292 if (M instanceof AST_ObjectGetter) {
6293 kind = "get";
6294 } else
6295 if (M instanceof AST_ObjectSetter) {
6296 kind = "set";
6297 }
6298 if (M instanceof AST_ClassProperty) {
6299 return {
6300 type: "FieldDefinition",
6301 computed,
6302 key,
6303 value: to_moz(M.value),
6304 static: M.static
6305 };
6306 }
6307 if (parent instanceof AST_Class) {
6308 return {
6309 type: "MethodDefinition",
6310 computed: computed,
6311 kind: kind,
6312 static: M.static,
6313 key: to_moz(M.key),
6314 value: to_moz(M.value)
6315 };
6316 }
6317 return {
6318 type: "Property",
6319 computed: computed,
6320 kind: kind,
6321 key: key,
6322 value: to_moz(M.value)
6323 };
6324 });
6325
6326 def_to_moz(AST_ConciseMethod, function To_Moz_MethodDefinition(M, parent) {
6327 if (parent instanceof AST_Object) {
6328 return {
6329 type: "Property",
6330 computed: !(M.key instanceof AST_Symbol) || M.key instanceof AST_SymbolRef,
6331 kind: "init",
6332 method: true,
6333 shorthand: false,
6334 key: to_moz(M.key),
6335 value: to_moz(M.value)
6336 };
6337 }
6338 return {
6339 type: "MethodDefinition",
6340 computed: !(M.key instanceof AST_Symbol) || M.key instanceof AST_SymbolRef,
6341 kind: M.key === "constructor" ? "constructor" : "method",
6342 static: M.static,
6343 key: to_moz(M.key),
6344 value: to_moz(M.value)
6345 };
6346 });
6347
6348 def_to_moz(AST_Class, function To_Moz_Class(M) {
6349 var type = M instanceof AST_ClassExpression ? "ClassExpression" : "ClassDeclaration";
6350 return {
6351 type: type,
6352 superClass: to_moz(M.extends),
6353 id: M.name ? to_moz(M.name) : null,
6354 body: {
6355 type: "ClassBody",
6356 body: M.properties.map(to_moz)
6357 }
6358 };
6359 });
6360
6361 def_to_moz(AST_NewTarget, function To_Moz_MetaProperty() {
6362 return {
6363 type: "MetaProperty",
6364 meta: {
6365 type: "Identifier",
6366 name: "new"
6367 },
6368 property: {
6369 type: "Identifier",
6370 name: "target"
6371 }
6372 };
6373 });
6374
6375 def_to_moz(AST_Symbol, function To_Moz_Identifier(M, parent) {
6376 if (M instanceof AST_SymbolMethod && parent.quote) {
6377 return {
6378 type: "Literal",
6379 value: M.name
6380 };
6381 }
6382 var def = M.definition();
6383 return {
6384 type: "Identifier",
6385 name: def ? def.mangled_name || def.name : M.name
6386 };
6387 });
6388
6389 def_to_moz(AST_RegExp, function To_Moz_RegExpLiteral(M) {
6390 const pattern = M.value.source;
6391 const flags = M.value.flags;
6392 return {
6393 type: "Literal",
6394 value: null,
6395 raw: M.print_to_string(),
6396 regex: { pattern, flags }
6397 };
6398 });
6399
6400 def_to_moz(AST_Constant, function To_Moz_Literal(M) {
6401 var value = M.value;
6402 if (typeof value === "number" && (value < 0 || (value === 0 && 1 / value < 0))) {
6403 return {
6404 type: "UnaryExpression",
6405 operator: "-",
6406 prefix: true,
6407 argument: {
6408 type: "Literal",
6409 value: -value,
6410 raw: M.start.raw
6411 }
6412 };
6413 }
6414 return {
6415 type: "Literal",
6416 value: value,
6417 raw: M.start.raw
6418 };
6419 });
6420
6421 def_to_moz(AST_Atom, function To_Moz_Atom(M) {
6422 return {
6423 type: "Identifier",
6424 name: String(M.value)
6425 };
6426 });
6427
6428 def_to_moz(AST_BigInt, M => ({
6429 type: "BigIntLiteral",
6430 value: M.value
6431 }));
6432
6433 AST_Boolean.DEFMETHOD("to_mozilla_ast", AST_Constant.prototype.to_mozilla_ast);
6434 AST_Null.DEFMETHOD("to_mozilla_ast", AST_Constant.prototype.to_mozilla_ast);
6435 AST_Hole.DEFMETHOD("to_mozilla_ast", function To_Moz_ArrayHole() { return null; });
6436
6437 AST_Block.DEFMETHOD("to_mozilla_ast", AST_BlockStatement.prototype.to_mozilla_ast);
6438 AST_Lambda.DEFMETHOD("to_mozilla_ast", AST_Function.prototype.to_mozilla_ast);
6439
6440 /* -----[ tools ]----- */
6441
6442 function raw_token(moznode) {
6443 if (moznode.type == "Literal") {
6444 return moznode.raw != null ? moznode.raw : moznode.value + "";
6445 }
6446 }
6447
6448 function my_start_token(moznode) {
6449 var loc = moznode.loc, start = loc && loc.start;
6450 var range = moznode.range;
6451 return new AST_Token({
6452 file : loc && loc.source,
6453 line : start && start.line,
6454 col : start && start.column,
6455 pos : range ? range[0] : moznode.start,
6456 endline : start && start.line,
6457 endcol : start && start.column,
6458 endpos : range ? range[0] : moznode.start,
6459 raw : raw_token(moznode),
6460 });
6461 }
6462
6463 function my_end_token(moznode) {
6464 var loc = moznode.loc, end = loc && loc.end;
6465 var range = moznode.range;
6466 return new AST_Token({
6467 file : loc && loc.source,
6468 line : end && end.line,
6469 col : end && end.column,
6470 pos : range ? range[1] : moznode.end,
6471 endline : end && end.line,
6472 endcol : end && end.column,
6473 endpos : range ? range[1] : moznode.end,
6474 raw : raw_token(moznode),
6475 });
6476 }
6477
6478 function map(moztype, mytype, propmap) {
6479 var moz_to_me = "function From_Moz_" + moztype + "(M){\n";
6480 moz_to_me += "return new U2." + mytype.name + "({\n" +
6481 "start: my_start_token(M),\n" +
6482 "end: my_end_token(M)";
6483
6484 var me_to_moz = "function To_Moz_" + moztype + "(M){\n";
6485 me_to_moz += "return {\n" +
6486 "type: " + JSON.stringify(moztype);
6487
6488 if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop) {
6489 var m = /([a-z0-9$_]+)([=@>%])([a-z0-9$_]+)/i.exec(prop);
6490 if (!m) throw new Error("Can't understand property map: " + prop);
6491 var moz = m[1], how = m[2], my = m[3];
6492 moz_to_me += ",\n" + my + ": ";
6493 me_to_moz += ",\n" + moz + ": ";
6494 switch (how) {
6495 case "@":
6496 moz_to_me += "M." + moz + ".map(from_moz)";
6497 me_to_moz += "M." + my + ".map(to_moz)";
6498 break;
6499 case ">":
6500 moz_to_me += "from_moz(M." + moz + ")";
6501 me_to_moz += "to_moz(M." + my + ")";
6502 break;
6503 case "=":
6504 moz_to_me += "M." + moz;
6505 me_to_moz += "M." + my;
6506 break;
6507 case "%":
6508 moz_to_me += "from_moz(M." + moz + ").body";
6509 me_to_moz += "to_moz_block(M)";
6510 break;
6511 default:
6512 throw new Error("Can't understand operator in propmap: " + prop);
6513 }
6514 });
6515
6516 moz_to_me += "\n})\n}";
6517 me_to_moz += "\n}\n}";
6518
6519 moz_to_me = new Function("U2", "my_start_token", "my_end_token", "from_moz", "return(" + moz_to_me + ")")(
6520 ast, my_start_token, my_end_token, from_moz
6521 );
6522 me_to_moz = new Function("to_moz", "to_moz_block", "to_moz_scope", "return(" + me_to_moz + ")")(
6523 to_moz, to_moz_block, to_moz_scope
6524 );
6525 MOZ_TO_ME[moztype] = moz_to_me;
6526 def_to_moz(mytype, me_to_moz);
6527 }
6528
6529 var FROM_MOZ_STACK = null;
6530
6531 function from_moz(node) {
6532 FROM_MOZ_STACK.push(node);
6533 var ret = node != null ? MOZ_TO_ME[node.type](node) : null;
6534 FROM_MOZ_STACK.pop();
6535 return ret;
6536 }
6537
6538 AST_Node.from_mozilla_ast = function(node) {
6539 var save_stack = FROM_MOZ_STACK;
6540 FROM_MOZ_STACK = [];
6541 var ast = from_moz(node);
6542 FROM_MOZ_STACK = save_stack;
6543 return ast;
6544 };
6545
6546 function set_moz_loc(mynode, moznode) {
6547 var start = mynode.start;
6548 var end = mynode.end;
6549 if (!(start && end)) {
6550 return moznode;
6551 }
6552 if (start.pos != null && end.endpos != null) {
6553 moznode.range = [start.pos, end.endpos];
6554 }
6555 if (start.line) {
6556 moznode.loc = {
6557 start: {line: start.line, column: start.col},
6558 end: end.endline ? {line: end.endline, column: end.endcol} : null
6559 };
6560 if (start.file) {
6561 moznode.loc.source = start.file;
6562 }
6563 }
6564 return moznode;
6565 }
6566
6567 function def_to_moz(mytype, handler) {
6568 mytype.DEFMETHOD("to_mozilla_ast", function(parent) {
6569 return set_moz_loc(this, handler(this, parent));
6570 });
6571 }
6572
6573 var TO_MOZ_STACK = null;
6574
6575 function to_moz(node) {
6576 if (TO_MOZ_STACK === null) { TO_MOZ_STACK = []; }
6577 TO_MOZ_STACK.push(node);
6578 var ast = node != null ? node.to_mozilla_ast(TO_MOZ_STACK[TO_MOZ_STACK.length - 2]) : null;
6579 TO_MOZ_STACK.pop();
6580 if (TO_MOZ_STACK.length === 0) { TO_MOZ_STACK = null; }
6581 return ast;
6582 }
6583
6584 function to_moz_in_destructuring() {
6585 var i = TO_MOZ_STACK.length;
6586 while (i--) {
6587 if (TO_MOZ_STACK[i] instanceof AST_Destructuring) {
6588 return true;
6589 }
6590 }
6591 return false;
6592 }
6593
6594 function to_moz_block(node) {
6595 return {
6596 type: "BlockStatement",
6597 body: node.body.map(to_moz)
6598 };
6599 }
6600
6601 function to_moz_scope(type, node) {
6602 var body = node.body.map(to_moz);
6603 if (node.body[0] instanceof AST_SimpleStatement && node.body[0].body instanceof AST_String) {
6604 body.unshift(to_moz(new AST_EmptyStatement(node.body[0])));
6605 }
6606 return {
6607 type: type,
6608 body: body
6609 };
6610 }
6611})();
6612
6613// return true if the node at the top of the stack (that means the
6614// innermost node in the current output) is lexically the first in
6615// a statement.
6616function first_in_statement(stack) {
6617 let node = stack.parent(-1);
6618 for (let i = 0, p; p = stack.parent(i); i++) {
6619 if (p instanceof AST_Statement && p.body === node)
6620 return true;
6621 if ((p instanceof AST_Sequence && p.expressions[0] === node) ||
6622 (p.TYPE === "Call" && p.expression === node) ||
6623 (p instanceof AST_PrefixedTemplateString && p.prefix === node) ||
6624 (p instanceof AST_Dot && p.expression === node) ||
6625 (p instanceof AST_Sub && p.expression === node) ||
6626 (p instanceof AST_Conditional && p.condition === node) ||
6627 (p instanceof AST_Binary && p.left === node) ||
6628 (p instanceof AST_UnaryPostfix && p.expression === node)
6629 ) {
6630 node = p;
6631 } else {
6632 return false;
6633 }
6634 }
6635}
6636
6637// Returns whether the leftmost item in the expression is an object
6638function left_is_object(node) {
6639 if (node instanceof AST_Object) return true;
6640 if (node instanceof AST_Sequence) return left_is_object(node.expressions[0]);
6641 if (node.TYPE === "Call") return left_is_object(node.expression);
6642 if (node instanceof AST_PrefixedTemplateString) return left_is_object(node.prefix);
6643 if (node instanceof AST_Dot || node instanceof AST_Sub) return left_is_object(node.expression);
6644 if (node instanceof AST_Conditional) return left_is_object(node.condition);
6645 if (node instanceof AST_Binary) return left_is_object(node.left);
6646 if (node instanceof AST_UnaryPostfix) return left_is_object(node.expression);
6647 return false;
6648}
6649
6650/***********************************************************************
6651
6652 A JavaScript tokenizer / parser / beautifier / compressor.
6653 https://github.com/mishoo/UglifyJS2
6654
6655 -------------------------------- (C) ---------------------------------
6656
6657 Author: Mihai Bazon
6658 <mihai.bazon@gmail.com>
6659 http://mihai.bazon.net/blog
6660
6661 Distributed under the BSD license:
6662
6663 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
6664
6665 Redistribution and use in source and binary forms, with or without
6666 modification, are permitted provided that the following conditions
6667 are met:
6668
6669 * Redistributions of source code must retain the above
6670 copyright notice, this list of conditions and the following
6671 disclaimer.
6672
6673 * Redistributions in binary form must reproduce the above
6674 copyright notice, this list of conditions and the following
6675 disclaimer in the documentation and/or other materials
6676 provided with the distribution.
6677
6678 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
6679 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
6680 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
6681 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
6682 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
6683 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
6684 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
6685 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
6686 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
6687 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
6688 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
6689 SUCH DAMAGE.
6690
6691 ***********************************************************************/
6692
6693const EXPECT_DIRECTIVE = /^$|[;{][\s\n]*$/;
6694const CODE_LINE_BREAK = 10;
6695const CODE_SPACE = 32;
6696
6697const r_annotation = /[@#]__(PURE|INLINE|NOINLINE)__/g;
6698
6699function is_some_comments(comment) {
6700 // multiline comment
6701 return (
6702 (comment.type === "comment2" || comment.type === "comment1")
6703 && /@preserve|@lic|@cc_on|^\**!/i.test(comment.value)
6704 );
6705}
6706
6707function OutputStream(options) {
6708
6709 var readonly = !options;
6710 options = defaults(options, {
6711 ascii_only : false,
6712 beautify : false,
6713 braces : false,
6714 comments : "some",
6715 ecma : 5,
6716 ie8 : false,
6717 indent_level : 4,
6718 indent_start : 0,
6719 inline_script : true,
6720 keep_numbers : false,
6721 keep_quoted_props : false,
6722 max_line_len : false,
6723 preamble : null,
6724 preserve_annotations : false,
6725 quote_keys : false,
6726 quote_style : 0,
6727 safari10 : false,
6728 semicolons : true,
6729 shebang : true,
6730 shorthand : undefined,
6731 source_map : null,
6732 webkit : false,
6733 width : 80,
6734 wrap_iife : false,
6735 wrap_func_args : true,
6736 }, true);
6737
6738 if (options.shorthand === undefined)
6739 options.shorthand = options.ecma > 5;
6740
6741 // Convert comment option to RegExp if neccessary and set up comments filter
6742 var comment_filter = return_false; // Default case, throw all comments away
6743 if (options.comments) {
6744 let comments = options.comments;
6745 if (typeof options.comments === "string" && /^\/.*\/[a-zA-Z]*$/.test(options.comments)) {
6746 var regex_pos = options.comments.lastIndexOf("/");
6747 comments = new RegExp(
6748 options.comments.substr(1, regex_pos - 1),
6749 options.comments.substr(regex_pos + 1)
6750 );
6751 }
6752 if (comments instanceof RegExp) {
6753 comment_filter = function(comment) {
6754 return comment.type != "comment5" && comments.test(comment.value);
6755 };
6756 } else if (typeof comments === "function") {
6757 comment_filter = function(comment) {
6758 return comment.type != "comment5" && comments(this, comment);
6759 };
6760 } else if (comments === "some") {
6761 comment_filter = is_some_comments;
6762 } else { // NOTE includes "all" option
6763 comment_filter = return_true;
6764 }
6765 }
6766
6767 var indentation = 0;
6768 var current_col = 0;
6769 var current_line = 1;
6770 var current_pos = 0;
6771 var OUTPUT = "";
6772 let printed_comments = new Set();
6773
6774 var to_utf8 = options.ascii_only ? function(str, identifier) {
6775 if (options.ecma >= 2015) {
6776 str = str.replace(/[\ud800-\udbff][\udc00-\udfff]/g, function(ch) {
6777 var code = get_full_char_code(ch, 0).toString(16);
6778 return "\\u{" + code + "}";
6779 });
6780 }
6781 return str.replace(/[\u0000-\u001f\u007f-\uffff]/g, function(ch) {
6782 var code = ch.charCodeAt(0).toString(16);
6783 if (code.length <= 2 && !identifier) {
6784 while (code.length < 2) code = "0" + code;
6785 return "\\x" + code;
6786 } else {
6787 while (code.length < 4) code = "0" + code;
6788 return "\\u" + code;
6789 }
6790 });
6791 } : function(str) {
6792 return str.replace(/[\ud800-\udbff][\udc00-\udfff]|([\ud800-\udbff]|[\udc00-\udfff])/g, function(match, lone) {
6793 if (lone) {
6794 return "\\u" + lone.charCodeAt(0).toString(16);
6795 }
6796 return match;
6797 });
6798 };
6799
6800 function make_string(str, quote) {
6801 var dq = 0, sq = 0;
6802 str = str.replace(/[\\\b\f\n\r\v\t\x22\x27\u2028\u2029\0\ufeff]/g,
6803 function(s, i) {
6804 switch (s) {
6805 case '"': ++dq; return '"';
6806 case "'": ++sq; return "'";
6807 case "\\": return "\\\\";
6808 case "\n": return "\\n";
6809 case "\r": return "\\r";
6810 case "\t": return "\\t";
6811 case "\b": return "\\b";
6812 case "\f": return "\\f";
6813 case "\x0B": return options.ie8 ? "\\x0B" : "\\v";
6814 case "\u2028": return "\\u2028";
6815 case "\u2029": return "\\u2029";
6816 case "\ufeff": return "\\ufeff";
6817 case "\0":
6818 return /[0-9]/.test(get_full_char(str, i+1)) ? "\\x00" : "\\0";
6819 }
6820 return s;
6821 });
6822 function quote_single() {
6823 return "'" + str.replace(/\x27/g, "\\'") + "'";
6824 }
6825 function quote_double() {
6826 return '"' + str.replace(/\x22/g, '\\"') + '"';
6827 }
6828 function quote_template() {
6829 return "`" + str.replace(/`/g, "\\`") + "`";
6830 }
6831 str = to_utf8(str);
6832 if (quote === "`") return quote_template();
6833 switch (options.quote_style) {
6834 case 1:
6835 return quote_single();
6836 case 2:
6837 return quote_double();
6838 case 3:
6839 return quote == "'" ? quote_single() : quote_double();
6840 default:
6841 return dq > sq ? quote_single() : quote_double();
6842 }
6843 }
6844
6845 function encode_string(str, quote) {
6846 var ret = make_string(str, quote);
6847 if (options.inline_script) {
6848 ret = ret.replace(/<\x2f(script)([>\/\t\n\f\r ])/gi, "<\\/$1$2");
6849 ret = ret.replace(/\x3c!--/g, "\\x3c!--");
6850 ret = ret.replace(/--\x3e/g, "--\\x3e");
6851 }
6852 return ret;
6853 }
6854
6855 function make_name(name) {
6856 name = name.toString();
6857 name = to_utf8(name, true);
6858 return name;
6859 }
6860
6861 function make_indent(back) {
6862 return " ".repeat(options.indent_start + indentation - back * options.indent_level);
6863 }
6864
6865 /* -----[ beautification/minification ]----- */
6866
6867 var has_parens = false;
6868 var might_need_space = false;
6869 var might_need_semicolon = false;
6870 var might_add_newline = 0;
6871 var need_newline_indented = false;
6872 var need_space = false;
6873 var newline_insert = -1;
6874 var last = "";
6875 var mapping_token, mapping_name, mappings = options.source_map && [];
6876
6877 var do_add_mapping = mappings ? function() {
6878 mappings.forEach(function(mapping) {
6879 try {
6880 options.source_map.add(
6881 mapping.token.file,
6882 mapping.line, mapping.col,
6883 mapping.token.line, mapping.token.col,
6884 !mapping.name && mapping.token.type == "name" ? mapping.token.value : mapping.name
6885 );
6886 } catch(ex) {
6887 // Ignore bad mapping
6888 }
6889 });
6890 mappings = [];
6891 } : noop;
6892
6893 var ensure_line_len = options.max_line_len ? function() {
6894 if (current_col > options.max_line_len) {
6895 if (might_add_newline) {
6896 var left = OUTPUT.slice(0, might_add_newline);
6897 var right = OUTPUT.slice(might_add_newline);
6898 if (mappings) {
6899 var delta = right.length - current_col;
6900 mappings.forEach(function(mapping) {
6901 mapping.line++;
6902 mapping.col += delta;
6903 });
6904 }
6905 OUTPUT = left + "\n" + right;
6906 current_line++;
6907 current_pos++;
6908 current_col = right.length;
6909 }
6910 }
6911 if (might_add_newline) {
6912 might_add_newline = 0;
6913 do_add_mapping();
6914 }
6915 } : noop;
6916
6917 var requireSemicolonChars = makePredicate("( [ + * / - , . `");
6918
6919 function print(str) {
6920 str = String(str);
6921 var ch = get_full_char(str, 0);
6922 if (need_newline_indented && ch) {
6923 need_newline_indented = false;
6924 if (ch !== "\n") {
6925 print("\n");
6926 indent();
6927 }
6928 }
6929 if (need_space && ch) {
6930 need_space = false;
6931 if (!/[\s;})]/.test(ch)) {
6932 space();
6933 }
6934 }
6935 newline_insert = -1;
6936 var prev = last.charAt(last.length - 1);
6937 if (might_need_semicolon) {
6938 might_need_semicolon = false;
6939
6940 if (prev === ":" && ch === "}" || (!ch || !";}".includes(ch)) && prev !== ";") {
6941 if (options.semicolons || requireSemicolonChars.has(ch)) {
6942 OUTPUT += ";";
6943 current_col++;
6944 current_pos++;
6945 } else {
6946 ensure_line_len();
6947 if (current_col > 0) {
6948 OUTPUT += "\n";
6949 current_pos++;
6950 current_line++;
6951 current_col = 0;
6952 }
6953
6954 if (/^\s+$/.test(str)) {
6955 // reset the semicolon flag, since we didn't print one
6956 // now and might still have to later
6957 might_need_semicolon = true;
6958 }
6959 }
6960
6961 if (!options.beautify)
6962 might_need_space = false;
6963 }
6964 }
6965
6966 if (might_need_space) {
6967 if ((is_identifier_char(prev)
6968 && (is_identifier_char(ch) || ch == "\\"))
6969 || (ch == "/" && ch == prev)
6970 || ((ch == "+" || ch == "-") && ch == last)
6971 ) {
6972 OUTPUT += " ";
6973 current_col++;
6974 current_pos++;
6975 }
6976 might_need_space = false;
6977 }
6978
6979 if (mapping_token) {
6980 mappings.push({
6981 token: mapping_token,
6982 name: mapping_name,
6983 line: current_line,
6984 col: current_col
6985 });
6986 mapping_token = false;
6987 if (!might_add_newline) do_add_mapping();
6988 }
6989
6990 OUTPUT += str;
6991 has_parens = str[str.length - 1] == "(";
6992 current_pos += str.length;
6993 var a = str.split(/\r?\n/), n = a.length - 1;
6994 current_line += n;
6995 current_col += a[0].length;
6996 if (n > 0) {
6997 ensure_line_len();
6998 current_col = a[n].length;
6999 }
7000 last = str;
7001 }
7002
7003 var star = function() {
7004 print("*");
7005 };
7006
7007 var space = options.beautify ? function() {
7008 print(" ");
7009 } : function() {
7010 might_need_space = true;
7011 };
7012
7013 var indent = options.beautify ? function(half) {
7014 if (options.beautify) {
7015 print(make_indent(half ? 0.5 : 0));
7016 }
7017 } : noop;
7018
7019 var with_indent = options.beautify ? function(col, cont) {
7020 if (col === true) col = next_indent();
7021 var save_indentation = indentation;
7022 indentation = col;
7023 var ret = cont();
7024 indentation = save_indentation;
7025 return ret;
7026 } : function(col, cont) { return cont(); };
7027
7028 var newline = options.beautify ? function() {
7029 if (newline_insert < 0) return print("\n");
7030 if (OUTPUT[newline_insert] != "\n") {
7031 OUTPUT = OUTPUT.slice(0, newline_insert) + "\n" + OUTPUT.slice(newline_insert);
7032 current_pos++;
7033 current_line++;
7034 }
7035 newline_insert++;
7036 } : options.max_line_len ? function() {
7037 ensure_line_len();
7038 might_add_newline = OUTPUT.length;
7039 } : noop;
7040
7041 var semicolon = options.beautify ? function() {
7042 print(";");
7043 } : function() {
7044 might_need_semicolon = true;
7045 };
7046
7047 function force_semicolon() {
7048 might_need_semicolon = false;
7049 print(";");
7050 }
7051
7052 function next_indent() {
7053 return indentation + options.indent_level;
7054 }
7055
7056 function with_block(cont) {
7057 var ret;
7058 print("{");
7059 newline();
7060 with_indent(next_indent(), function() {
7061 ret = cont();
7062 });
7063 indent();
7064 print("}");
7065 return ret;
7066 }
7067
7068 function with_parens(cont) {
7069 print("(");
7070 //XXX: still nice to have that for argument lists
7071 //var ret = with_indent(current_col, cont);
7072 var ret = cont();
7073 print(")");
7074 return ret;
7075 }
7076
7077 function with_square(cont) {
7078 print("[");
7079 //var ret = with_indent(current_col, cont);
7080 var ret = cont();
7081 print("]");
7082 return ret;
7083 }
7084
7085 function comma() {
7086 print(",");
7087 space();
7088 }
7089
7090 function colon() {
7091 print(":");
7092 space();
7093 }
7094
7095 var add_mapping = mappings ? function(token, name) {
7096 mapping_token = token;
7097 mapping_name = name;
7098 } : noop;
7099
7100 function get() {
7101 if (might_add_newline) {
7102 ensure_line_len();
7103 }
7104 return OUTPUT;
7105 }
7106
7107 function has_nlb() {
7108 let n = OUTPUT.length - 1;
7109 while (n >= 0) {
7110 const code = OUTPUT.charCodeAt(n);
7111 if (code === CODE_LINE_BREAK) {
7112 return true;
7113 }
7114
7115 if (code !== CODE_SPACE) {
7116 return false;
7117 }
7118 n--;
7119 }
7120 return true;
7121 }
7122
7123 function filter_comment(comment) {
7124 if (!options.preserve_annotations) {
7125 comment = comment.replace(r_annotation, " ");
7126 }
7127 if (/^\s*$/.test(comment)) {
7128 return "";
7129 }
7130 return comment.replace(/(<\s*\/\s*)(script)/i, "<\\/$2");
7131 }
7132
7133 function prepend_comments(node) {
7134 var self = this;
7135 var start = node.start;
7136 if (!start) return;
7137 var printed_comments = self.printed_comments;
7138
7139 // There cannot be a newline between return and its value.
7140 const return_with_value = node instanceof AST_Exit && node.value;
7141
7142 if (
7143 start.comments_before
7144 && printed_comments.has(start.comments_before)
7145 ) {
7146 if (return_with_value) {
7147 start.comments_before = [];
7148 } else {
7149 return;
7150 }
7151 }
7152
7153 var comments = start.comments_before;
7154 if (!comments) {
7155 comments = start.comments_before = [];
7156 }
7157 printed_comments.add(comments);
7158
7159 if (return_with_value) {
7160 var tw = new TreeWalker(function(node) {
7161 var parent = tw.parent();
7162 if (parent instanceof AST_Exit
7163 || parent instanceof AST_Binary && parent.left === node
7164 || parent.TYPE == "Call" && parent.expression === node
7165 || parent instanceof AST_Conditional && parent.condition === node
7166 || parent instanceof AST_Dot && parent.expression === node
7167 || parent instanceof AST_Sequence && parent.expressions[0] === node
7168 || parent instanceof AST_Sub && parent.expression === node
7169 || parent instanceof AST_UnaryPostfix) {
7170 if (!node.start) return;
7171 var text = node.start.comments_before;
7172 if (text && !printed_comments.has(text)) {
7173 printed_comments.add(text);
7174 comments = comments.concat(text);
7175 }
7176 } else {
7177 return true;
7178 }
7179 });
7180 tw.push(node);
7181 node.value.walk(tw);
7182 }
7183
7184 if (current_pos == 0) {
7185 if (comments.length > 0 && options.shebang && comments[0].type === "comment5"
7186 && !printed_comments.has(comments[0])) {
7187 print("#!" + comments.shift().value + "\n");
7188 indent();
7189 }
7190 var preamble = options.preamble;
7191 if (preamble) {
7192 print(preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n"));
7193 }
7194 }
7195
7196 comments = comments.filter(comment_filter, node).filter(c => !printed_comments.has(c));
7197 if (comments.length == 0) return;
7198 var last_nlb = has_nlb();
7199 comments.forEach(function(c, i) {
7200 printed_comments.add(c);
7201 if (!last_nlb) {
7202 if (c.nlb) {
7203 print("\n");
7204 indent();
7205 last_nlb = true;
7206 } else if (i > 0) {
7207 space();
7208 }
7209 }
7210
7211 if (/comment[134]/.test(c.type)) {
7212 var value = filter_comment(c.value);
7213 if (value) {
7214 print("//" + value + "\n");
7215 indent();
7216 }
7217 last_nlb = true;
7218 } else if (c.type == "comment2") {
7219 var value = filter_comment(c.value);
7220 if (value) {
7221 print("/*" + value + "*/");
7222 }
7223 last_nlb = false;
7224 }
7225 });
7226 if (!last_nlb) {
7227 if (start.nlb) {
7228 print("\n");
7229 indent();
7230 } else {
7231 space();
7232 }
7233 }
7234 }
7235
7236 function append_comments(node, tail) {
7237 var self = this;
7238 var token = node.end;
7239 if (!token) return;
7240 var printed_comments = self.printed_comments;
7241 var comments = token[tail ? "comments_before" : "comments_after"];
7242 if (!comments || printed_comments.has(comments)) return;
7243 if (!(node instanceof AST_Statement || comments.every((c) =>
7244 !/comment[134]/.test(c.type)
7245 ))) return;
7246 printed_comments.add(comments);
7247 var insert = OUTPUT.length;
7248 comments.filter(comment_filter, node).forEach(function(c, i) {
7249 if (printed_comments.has(c)) return;
7250 printed_comments.add(c);
7251 need_space = false;
7252 if (need_newline_indented) {
7253 print("\n");
7254 indent();
7255 need_newline_indented = false;
7256 } else if (c.nlb && (i > 0 || !has_nlb())) {
7257 print("\n");
7258 indent();
7259 } else if (i > 0 || !tail) {
7260 space();
7261 }
7262 if (/comment[134]/.test(c.type)) {
7263 const value = filter_comment(c.value);
7264 if (value) {
7265 print("//" + value);
7266 }
7267 need_newline_indented = true;
7268 } else if (c.type == "comment2") {
7269 const value = filter_comment(c.value);
7270 if (value) {
7271 print("/*" + value + "*/");
7272 }
7273 need_space = true;
7274 }
7275 });
7276 if (OUTPUT.length > insert) newline_insert = insert;
7277 }
7278
7279 var stack = [];
7280 return {
7281 get : get,
7282 toString : get,
7283 indent : indent,
7284 in_directive : false,
7285 use_asm : null,
7286 active_scope : null,
7287 indentation : function() { return indentation; },
7288 current_width : function() { return current_col - indentation; },
7289 should_break : function() { return options.width && this.current_width() >= options.width; },
7290 has_parens : function() { return has_parens; },
7291 newline : newline,
7292 print : print,
7293 star : star,
7294 space : space,
7295 comma : comma,
7296 colon : colon,
7297 last : function() { return last; },
7298 semicolon : semicolon,
7299 force_semicolon : force_semicolon,
7300 to_utf8 : to_utf8,
7301 print_name : function(name) { print(make_name(name)); },
7302 print_string : function(str, quote, escape_directive) {
7303 var encoded = encode_string(str, quote);
7304 if (escape_directive === true && !encoded.includes("\\")) {
7305 // Insert semicolons to break directive prologue
7306 if (!EXPECT_DIRECTIVE.test(OUTPUT)) {
7307 force_semicolon();
7308 }
7309 force_semicolon();
7310 }
7311 print(encoded);
7312 },
7313 print_template_string_chars: function(str) {
7314 var encoded = encode_string(str, "`").replace(/\${/g, "\\${");
7315 return print(encoded.substr(1, encoded.length - 2));
7316 },
7317 encode_string : encode_string,
7318 next_indent : next_indent,
7319 with_indent : with_indent,
7320 with_block : with_block,
7321 with_parens : with_parens,
7322 with_square : with_square,
7323 add_mapping : add_mapping,
7324 option : function(opt) { return options[opt]; },
7325 printed_comments: printed_comments,
7326 prepend_comments: readonly ? noop : prepend_comments,
7327 append_comments : readonly || comment_filter === return_false ? noop : append_comments,
7328 line : function() { return current_line; },
7329 col : function() { return current_col; },
7330 pos : function() { return current_pos; },
7331 push_node : function(node) { stack.push(node); },
7332 pop_node : function() { return stack.pop(); },
7333 parent : function(n) {
7334 return stack[stack.length - 2 - (n || 0)];
7335 }
7336 };
7337
7338}
7339
7340/* -----[ code generators ]----- */
7341
7342(function() {
7343
7344 /* -----[ utils ]----- */
7345
7346 function DEFPRINT(nodetype, generator) {
7347 nodetype.DEFMETHOD("_codegen", generator);
7348 }
7349
7350 AST_Node.DEFMETHOD("print", function(output, force_parens) {
7351 var self = this, generator = self._codegen;
7352 if (self instanceof AST_Scope) {
7353 output.active_scope = self;
7354 } else if (!output.use_asm && self instanceof AST_Directive && self.value == "use asm") {
7355 output.use_asm = output.active_scope;
7356 }
7357 function doit() {
7358 output.prepend_comments(self);
7359 self.add_source_map(output);
7360 generator(self, output);
7361 output.append_comments(self);
7362 }
7363 output.push_node(self);
7364 if (force_parens || self.needs_parens(output)) {
7365 output.with_parens(doit);
7366 } else {
7367 doit();
7368 }
7369 output.pop_node();
7370 if (self === output.use_asm) {
7371 output.use_asm = null;
7372 }
7373 });
7374 AST_Node.DEFMETHOD("_print", AST_Node.prototype.print);
7375
7376 AST_Node.DEFMETHOD("print_to_string", function(options) {
7377 var output = OutputStream(options);
7378 this.print(output);
7379 return output.get();
7380 });
7381
7382 /* -----[ PARENTHESES ]----- */
7383
7384 function PARENS(nodetype, func) {
7385 if (Array.isArray(nodetype)) {
7386 nodetype.forEach(function(nodetype) {
7387 PARENS(nodetype, func);
7388 });
7389 } else {
7390 nodetype.DEFMETHOD("needs_parens", func);
7391 }
7392 }
7393
7394 PARENS(AST_Node, return_false);
7395
7396 // a function expression needs parens around it when it's provably
7397 // the first token to appear in a statement.
7398 PARENS(AST_Function, function(output) {
7399 if (!output.has_parens() && first_in_statement(output)) {
7400 return true;
7401 }
7402
7403 if (output.option("webkit")) {
7404 var p = output.parent();
7405 if (p instanceof AST_PropAccess && p.expression === this) {
7406 return true;
7407 }
7408 }
7409
7410 if (output.option("wrap_iife")) {
7411 var p = output.parent();
7412 if (p instanceof AST_Call && p.expression === this) {
7413 return true;
7414 }
7415 }
7416
7417 if (output.option("wrap_func_args")) {
7418 var p = output.parent();
7419 if (p instanceof AST_Call && p.args.includes(this)) {
7420 return true;
7421 }
7422 }
7423
7424 return false;
7425 });
7426
7427 PARENS(AST_Arrow, function(output) {
7428 var p = output.parent();
7429
7430 if (
7431 output.option("wrap_func_args")
7432 && p instanceof AST_Call
7433 && p.args.includes(this)
7434 ) {
7435 return true;
7436 }
7437 return p instanceof AST_PropAccess && p.expression === this;
7438 });
7439
7440 // same goes for an object literal (as in AST_Function), because
7441 // otherwise {...} would be interpreted as a block of code.
7442 PARENS(AST_Object, function(output) {
7443 return !output.has_parens() && first_in_statement(output);
7444 });
7445
7446 PARENS(AST_ClassExpression, first_in_statement);
7447
7448 PARENS(AST_Unary, function(output) {
7449 var p = output.parent();
7450 return p instanceof AST_PropAccess && p.expression === this
7451 || p instanceof AST_Call && p.expression === this
7452 || p instanceof AST_Binary
7453 && p.operator === "**"
7454 && this instanceof AST_UnaryPrefix
7455 && p.left === this
7456 && this.operator !== "++"
7457 && this.operator !== "--";
7458 });
7459
7460 PARENS(AST_Await, function(output) {
7461 var p = output.parent();
7462 return p instanceof AST_PropAccess && p.expression === this
7463 || p instanceof AST_Call && p.expression === this
7464 || output.option("safari10") && p instanceof AST_UnaryPrefix;
7465 });
7466
7467 PARENS(AST_Sequence, function(output) {
7468 var p = output.parent();
7469 return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4)
7470 || p instanceof AST_Unary // !(foo, bar, baz)
7471 || p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8
7472 || p instanceof AST_VarDef // var a = (1, 2), b = a + a; ==> b == 4
7473 || p instanceof AST_PropAccess // (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2
7474 || p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ]
7475 || p instanceof AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2
7476 || p instanceof AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30)
7477 * ==> 20 (side effect, set a := 10 and b := 20) */
7478 || p instanceof AST_Arrow // x => (x, x)
7479 || p instanceof AST_DefaultAssign // x => (x = (0, function(){}))
7480 || p instanceof AST_Expansion // [...(a, b)]
7481 || p instanceof AST_ForOf && this === p.object // for (e of (foo, bar)) {}
7482 || p instanceof AST_Yield // yield (foo, bar)
7483 || p instanceof AST_Export // export default (foo, bar)
7484 ;
7485 });
7486
7487 PARENS(AST_Binary, function(output) {
7488 var p = output.parent();
7489 // (foo && bar)()
7490 if (p instanceof AST_Call && p.expression === this)
7491 return true;
7492 // typeof (foo && bar)
7493 if (p instanceof AST_Unary)
7494 return true;
7495 // (foo && bar)["prop"], (foo && bar).prop
7496 if (p instanceof AST_PropAccess && p.expression === this)
7497 return true;
7498 // this deals with precedence: 3 * (2 + 1)
7499 if (p instanceof AST_Binary) {
7500 const po = p.operator;
7501 const so = this.operator;
7502
7503 if (so === "??" && (po === "||" || po === "&&")) {
7504 return true;
7505 }
7506
7507 if (po === "??" && (so === "||" || so === "&&")) {
7508 return true;
7509 }
7510
7511 const pp = PRECEDENCE[po];
7512 const sp = PRECEDENCE[so];
7513 if (pp > sp
7514 || (pp == sp
7515 && (this === p.right || po == "**"))) {
7516 return true;
7517 }
7518 }
7519 });
7520
7521 PARENS(AST_Yield, function(output) {
7522 var p = output.parent();
7523 // (yield 1) + (yield 2)
7524 // a = yield 3
7525 if (p instanceof AST_Binary && p.operator !== "=")
7526 return true;
7527 // (yield 1)()
7528 // new (yield 1)()
7529 if (p instanceof AST_Call && p.expression === this)
7530 return true;
7531 // (yield 1) ? yield 2 : yield 3
7532 if (p instanceof AST_Conditional && p.condition === this)
7533 return true;
7534 // -(yield 4)
7535 if (p instanceof AST_Unary)
7536 return true;
7537 // (yield x).foo
7538 // (yield x)['foo']
7539 if (p instanceof AST_PropAccess && p.expression === this)
7540 return true;
7541 });
7542
7543 PARENS(AST_PropAccess, function(output) {
7544 var p = output.parent();
7545 if (p instanceof AST_New && p.expression === this) {
7546 // i.e. new (foo.bar().baz)
7547 //
7548 // if there's one call into this subtree, then we need
7549 // parens around it too, otherwise the call will be
7550 // interpreted as passing the arguments to the upper New
7551 // expression.
7552 return walk(this, node => {
7553 if (node instanceof AST_Scope) return true;
7554 if (node instanceof AST_Call) {
7555 return walk_abort; // makes walk() return true.
7556 }
7557 });
7558 }
7559 });
7560
7561 PARENS(AST_Call, function(output) {
7562 var p = output.parent(), p1;
7563 if (p instanceof AST_New && p.expression === this
7564 || p instanceof AST_Export && p.is_default && this.expression instanceof AST_Function)
7565 return true;
7566
7567 // workaround for Safari bug.
7568 // https://bugs.webkit.org/show_bug.cgi?id=123506
7569 return this.expression instanceof AST_Function
7570 && p instanceof AST_PropAccess
7571 && p.expression === this
7572 && (p1 = output.parent(1)) instanceof AST_Assign
7573 && p1.left === p;
7574 });
7575
7576 PARENS(AST_New, function(output) {
7577 var p = output.parent();
7578 if (this.args.length === 0
7579 && (p instanceof AST_PropAccess // (new Date).getTime(), (new Date)["getTime"]()
7580 || p instanceof AST_Call && p.expression === this)) // (new foo)(bar)
7581 return true;
7582 });
7583
7584 PARENS(AST_Number, function(output) {
7585 var p = output.parent();
7586 if (p instanceof AST_PropAccess && p.expression === this) {
7587 var value = this.getValue();
7588 if (value < 0 || /^0/.test(make_num(value))) {
7589 return true;
7590 }
7591 }
7592 });
7593
7594 PARENS(AST_BigInt, function(output) {
7595 var p = output.parent();
7596 if (p instanceof AST_PropAccess && p.expression === this) {
7597 var value = this.getValue();
7598 if (value.startsWith("-")) {
7599 return true;
7600 }
7601 }
7602 });
7603
7604 PARENS([ AST_Assign, AST_Conditional ], function(output) {
7605 var p = output.parent();
7606 // !(a = false) → true
7607 if (p instanceof AST_Unary)
7608 return true;
7609 // 1 + (a = 2) + 3 → 6, side effect setting a = 2
7610 if (p instanceof AST_Binary && !(p instanceof AST_Assign))
7611 return true;
7612 // (a = func)() —or— new (a = Object)()
7613 if (p instanceof AST_Call && p.expression === this)
7614 return true;
7615 // (a = foo) ? bar : baz
7616 if (p instanceof AST_Conditional && p.condition === this)
7617 return true;
7618 // (a = foo)["prop"] —or— (a = foo).prop
7619 if (p instanceof AST_PropAccess && p.expression === this)
7620 return true;
7621 // ({a, b} = {a: 1, b: 2}), a destructuring assignment
7622 if (this instanceof AST_Assign && this.left instanceof AST_Destructuring && this.left.is_array === false)
7623 return true;
7624 });
7625
7626 /* -----[ PRINTERS ]----- */
7627
7628 DEFPRINT(AST_Directive, function(self, output) {
7629 output.print_string(self.value, self.quote);
7630 output.semicolon();
7631 });
7632
7633 DEFPRINT(AST_Expansion, function (self, output) {
7634 output.print("...");
7635 self.expression.print(output);
7636 });
7637
7638 DEFPRINT(AST_Destructuring, function (self, output) {
7639 output.print(self.is_array ? "[" : "{");
7640 var len = self.names.length;
7641 self.names.forEach(function (name, i) {
7642 if (i > 0) output.comma();
7643 name.print(output);
7644 // If the final element is a hole, we need to make sure it
7645 // doesn't look like a trailing comma, by inserting an actual
7646 // trailing comma.
7647 if (i == len - 1 && name instanceof AST_Hole) output.comma();
7648 });
7649 output.print(self.is_array ? "]" : "}");
7650 });
7651
7652 DEFPRINT(AST_Debugger, function(self, output) {
7653 output.print("debugger");
7654 output.semicolon();
7655 });
7656
7657 /* -----[ statements ]----- */
7658
7659 function display_body(body, is_toplevel, output, allow_directives) {
7660 var last = body.length - 1;
7661 output.in_directive = allow_directives;
7662 body.forEach(function(stmt, i) {
7663 if (output.in_directive === true && !(stmt instanceof AST_Directive ||
7664 stmt instanceof AST_EmptyStatement ||
7665 (stmt instanceof AST_SimpleStatement && stmt.body instanceof AST_String)
7666 )) {
7667 output.in_directive = false;
7668 }
7669 if (!(stmt instanceof AST_EmptyStatement)) {
7670 output.indent();
7671 stmt.print(output);
7672 if (!(i == last && is_toplevel)) {
7673 output.newline();
7674 if (is_toplevel) output.newline();
7675 }
7676 }
7677 if (output.in_directive === true &&
7678 stmt instanceof AST_SimpleStatement &&
7679 stmt.body instanceof AST_String
7680 ) {
7681 output.in_directive = false;
7682 }
7683 });
7684 output.in_directive = false;
7685 }
7686
7687 AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output) {
7688 force_statement(this.body, output);
7689 });
7690
7691 DEFPRINT(AST_Statement, function(self, output) {
7692 self.body.print(output);
7693 output.semicolon();
7694 });
7695 DEFPRINT(AST_Toplevel, function(self, output) {
7696 display_body(self.body, true, output, true);
7697 output.print("");
7698 });
7699 DEFPRINT(AST_LabeledStatement, function(self, output) {
7700 self.label.print(output);
7701 output.colon();
7702 self.body.print(output);
7703 });
7704 DEFPRINT(AST_SimpleStatement, function(self, output) {
7705 self.body.print(output);
7706 output.semicolon();
7707 });
7708 function print_braced_empty(self, output) {
7709 output.print("{");
7710 output.with_indent(output.next_indent(), function() {
7711 output.append_comments(self, true);
7712 });
7713 output.print("}");
7714 }
7715 function print_braced(self, output, allow_directives) {
7716 if (self.body.length > 0) {
7717 output.with_block(function() {
7718 display_body(self.body, false, output, allow_directives);
7719 });
7720 } else print_braced_empty(self, output);
7721 }
7722 DEFPRINT(AST_BlockStatement, function(self, output) {
7723 print_braced(self, output);
7724 });
7725 DEFPRINT(AST_EmptyStatement, function(self, output) {
7726 output.semicolon();
7727 });
7728 DEFPRINT(AST_Do, function(self, output) {
7729 output.print("do");
7730 output.space();
7731 make_block(self.body, output);
7732 output.space();
7733 output.print("while");
7734 output.space();
7735 output.with_parens(function() {
7736 self.condition.print(output);
7737 });
7738 output.semicolon();
7739 });
7740 DEFPRINT(AST_While, function(self, output) {
7741 output.print("while");
7742 output.space();
7743 output.with_parens(function() {
7744 self.condition.print(output);
7745 });
7746 output.space();
7747 self._do_print_body(output);
7748 });
7749 DEFPRINT(AST_For, function(self, output) {
7750 output.print("for");
7751 output.space();
7752 output.with_parens(function() {
7753 if (self.init) {
7754 if (self.init instanceof AST_Definitions) {
7755 self.init.print(output);
7756 } else {
7757 parenthesize_for_noin(self.init, output, true);
7758 }
7759 output.print(";");
7760 output.space();
7761 } else {
7762 output.print(";");
7763 }
7764 if (self.condition) {
7765 self.condition.print(output);
7766 output.print(";");
7767 output.space();
7768 } else {
7769 output.print(";");
7770 }
7771 if (self.step) {
7772 self.step.print(output);
7773 }
7774 });
7775 output.space();
7776 self._do_print_body(output);
7777 });
7778 DEFPRINT(AST_ForIn, function(self, output) {
7779 output.print("for");
7780 if (self.await) {
7781 output.space();
7782 output.print("await");
7783 }
7784 output.space();
7785 output.with_parens(function() {
7786 self.init.print(output);
7787 output.space();
7788 output.print(self instanceof AST_ForOf ? "of" : "in");
7789 output.space();
7790 self.object.print(output);
7791 });
7792 output.space();
7793 self._do_print_body(output);
7794 });
7795 DEFPRINT(AST_With, function(self, output) {
7796 output.print("with");
7797 output.space();
7798 output.with_parens(function() {
7799 self.expression.print(output);
7800 });
7801 output.space();
7802 self._do_print_body(output);
7803 });
7804
7805 /* -----[ functions ]----- */
7806 AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword) {
7807 var self = this;
7808 if (!nokeyword) {
7809 if (self.async) {
7810 output.print("async");
7811 output.space();
7812 }
7813 output.print("function");
7814 if (self.is_generator) {
7815 output.star();
7816 }
7817 if (self.name) {
7818 output.space();
7819 }
7820 }
7821 if (self.name instanceof AST_Symbol) {
7822 self.name.print(output);
7823 } else if (nokeyword && self.name instanceof AST_Node) {
7824 output.with_square(function() {
7825 self.name.print(output); // Computed method name
7826 });
7827 }
7828 output.with_parens(function() {
7829 self.argnames.forEach(function(arg, i) {
7830 if (i) output.comma();
7831 arg.print(output);
7832 });
7833 });
7834 output.space();
7835 print_braced(self, output, true);
7836 });
7837 DEFPRINT(AST_Lambda, function(self, output) {
7838 self._do_print(output);
7839 });
7840
7841 DEFPRINT(AST_PrefixedTemplateString, function(self, output) {
7842 var tag = self.prefix;
7843 var parenthesize_tag = tag instanceof AST_Lambda
7844 || tag instanceof AST_Binary
7845 || tag instanceof AST_Conditional
7846 || tag instanceof AST_Sequence
7847 || tag instanceof AST_Unary
7848 || tag instanceof AST_Dot && tag.expression instanceof AST_Object;
7849 if (parenthesize_tag) output.print("(");
7850 self.prefix.print(output);
7851 if (parenthesize_tag) output.print(")");
7852 self.template_string.print(output);
7853 });
7854 DEFPRINT(AST_TemplateString, function(self, output) {
7855 var is_tagged = output.parent() instanceof AST_PrefixedTemplateString;
7856
7857 output.print("`");
7858 for (var i = 0; i < self.segments.length; i++) {
7859 if (!(self.segments[i] instanceof AST_TemplateSegment)) {
7860 output.print("${");
7861 self.segments[i].print(output);
7862 output.print("}");
7863 } else if (is_tagged) {
7864 output.print(self.segments[i].raw);
7865 } else {
7866 output.print_template_string_chars(self.segments[i].value);
7867 }
7868 }
7869 output.print("`");
7870 });
7871
7872 AST_Arrow.DEFMETHOD("_do_print", function(output) {
7873 var self = this;
7874 var parent = output.parent();
7875 var needs_parens = (parent instanceof AST_Binary && !(parent instanceof AST_Assign)) ||
7876 parent instanceof AST_Unary ||
7877 (parent instanceof AST_Call && self === parent.expression);
7878 if (needs_parens) { output.print("("); }
7879 if (self.async) {
7880 output.print("async");
7881 output.space();
7882 }
7883 if (self.argnames.length === 1 && self.argnames[0] instanceof AST_Symbol) {
7884 self.argnames[0].print(output);
7885 } else {
7886 output.with_parens(function() {
7887 self.argnames.forEach(function(arg, i) {
7888 if (i) output.comma();
7889 arg.print(output);
7890 });
7891 });
7892 }
7893 output.space();
7894 output.print("=>");
7895 output.space();
7896 const first_statement = self.body[0];
7897 if (
7898 self.body.length === 1
7899 && first_statement instanceof AST_Return
7900 ) {
7901 const returned = first_statement.value;
7902 if (!returned) {
7903 output.print("{}");
7904 } else if (left_is_object(returned)) {
7905 output.print("(");
7906 returned.print(output);
7907 output.print(")");
7908 } else {
7909 returned.print(output);
7910 }
7911 } else {
7912 print_braced(self, output);
7913 }
7914 if (needs_parens) { output.print(")"); }
7915 });
7916
7917 /* -----[ exits ]----- */
7918 AST_Exit.DEFMETHOD("_do_print", function(output, kind) {
7919 output.print(kind);
7920 if (this.value) {
7921 output.space();
7922 const comments = this.value.start.comments_before;
7923 if (comments && comments.length && !output.printed_comments.has(comments)) {
7924 output.print("(");
7925 this.value.print(output);
7926 output.print(")");
7927 } else {
7928 this.value.print(output);
7929 }
7930 }
7931 output.semicolon();
7932 });
7933 DEFPRINT(AST_Return, function(self, output) {
7934 self._do_print(output, "return");
7935 });
7936 DEFPRINT(AST_Throw, function(self, output) {
7937 self._do_print(output, "throw");
7938 });
7939
7940 /* -----[ yield ]----- */
7941
7942 DEFPRINT(AST_Yield, function(self, output) {
7943 var star = self.is_star ? "*" : "";
7944 output.print("yield" + star);
7945 if (self.expression) {
7946 output.space();
7947 self.expression.print(output);
7948 }
7949 });
7950
7951 DEFPRINT(AST_Await, function(self, output) {
7952 output.print("await");
7953 output.space();
7954 var e = self.expression;
7955 var parens = !(
7956 e instanceof AST_Call
7957 || e instanceof AST_SymbolRef
7958 || e instanceof AST_PropAccess
7959 || e instanceof AST_Unary
7960 || e instanceof AST_Constant
7961 || e instanceof AST_Await
7962 || e instanceof AST_Object
7963 );
7964 if (parens) output.print("(");
7965 self.expression.print(output);
7966 if (parens) output.print(")");
7967 });
7968
7969 /* -----[ loop control ]----- */
7970 AST_LoopControl.DEFMETHOD("_do_print", function(output, kind) {
7971 output.print(kind);
7972 if (this.label) {
7973 output.space();
7974 this.label.print(output);
7975 }
7976 output.semicolon();
7977 });
7978 DEFPRINT(AST_Break, function(self, output) {
7979 self._do_print(output, "break");
7980 });
7981 DEFPRINT(AST_Continue, function(self, output) {
7982 self._do_print(output, "continue");
7983 });
7984
7985 /* -----[ if ]----- */
7986 function make_then(self, output) {
7987 var b = self.body;
7988 if (output.option("braces")
7989 || output.option("ie8") && b instanceof AST_Do)
7990 return make_block(b, output);
7991 // The squeezer replaces "block"-s that contain only a single
7992 // statement with the statement itself; technically, the AST
7993 // is correct, but this can create problems when we output an
7994 // IF having an ELSE clause where the THEN clause ends in an
7995 // IF *without* an ELSE block (then the outer ELSE would refer
7996 // to the inner IF). This function checks for this case and
7997 // adds the block braces if needed.
7998 if (!b) return output.force_semicolon();
7999 while (true) {
8000 if (b instanceof AST_If) {
8001 if (!b.alternative) {
8002 make_block(self.body, output);
8003 return;
8004 }
8005 b = b.alternative;
8006 } else if (b instanceof AST_StatementWithBody) {
8007 b = b.body;
8008 } else break;
8009 }
8010 force_statement(self.body, output);
8011 }
8012 DEFPRINT(AST_If, function(self, output) {
8013 output.print("if");
8014 output.space();
8015 output.with_parens(function() {
8016 self.condition.print(output);
8017 });
8018 output.space();
8019 if (self.alternative) {
8020 make_then(self, output);
8021 output.space();
8022 output.print("else");
8023 output.space();
8024 if (self.alternative instanceof AST_If)
8025 self.alternative.print(output);
8026 else
8027 force_statement(self.alternative, output);
8028 } else {
8029 self._do_print_body(output);
8030 }
8031 });
8032
8033 /* -----[ switch ]----- */
8034 DEFPRINT(AST_Switch, function(self, output) {
8035 output.print("switch");
8036 output.space();
8037 output.with_parens(function() {
8038 self.expression.print(output);
8039 });
8040 output.space();
8041 var last = self.body.length - 1;
8042 if (last < 0) print_braced_empty(self, output);
8043 else output.with_block(function() {
8044 self.body.forEach(function(branch, i) {
8045 output.indent(true);
8046 branch.print(output);
8047 if (i < last && branch.body.length > 0)
8048 output.newline();
8049 });
8050 });
8051 });
8052 AST_SwitchBranch.DEFMETHOD("_do_print_body", function(output) {
8053 output.newline();
8054 this.body.forEach(function(stmt) {
8055 output.indent();
8056 stmt.print(output);
8057 output.newline();
8058 });
8059 });
8060 DEFPRINT(AST_Default, function(self, output) {
8061 output.print("default:");
8062 self._do_print_body(output);
8063 });
8064 DEFPRINT(AST_Case, function(self, output) {
8065 output.print("case");
8066 output.space();
8067 self.expression.print(output);
8068 output.print(":");
8069 self._do_print_body(output);
8070 });
8071
8072 /* -----[ exceptions ]----- */
8073 DEFPRINT(AST_Try, function(self, output) {
8074 output.print("try");
8075 output.space();
8076 print_braced(self, output);
8077 if (self.bcatch) {
8078 output.space();
8079 self.bcatch.print(output);
8080 }
8081 if (self.bfinally) {
8082 output.space();
8083 self.bfinally.print(output);
8084 }
8085 });
8086 DEFPRINT(AST_Catch, function(self, output) {
8087 output.print("catch");
8088 if (self.argname) {
8089 output.space();
8090 output.with_parens(function() {
8091 self.argname.print(output);
8092 });
8093 }
8094 output.space();
8095 print_braced(self, output);
8096 });
8097 DEFPRINT(AST_Finally, function(self, output) {
8098 output.print("finally");
8099 output.space();
8100 print_braced(self, output);
8101 });
8102
8103 /* -----[ var/const ]----- */
8104 AST_Definitions.DEFMETHOD("_do_print", function(output, kind) {
8105 output.print(kind);
8106 output.space();
8107 this.definitions.forEach(function(def, i) {
8108 if (i) output.comma();
8109 def.print(output);
8110 });
8111 var p = output.parent();
8112 var in_for = p instanceof AST_For || p instanceof AST_ForIn;
8113 var output_semicolon = !in_for || p && p.init !== this;
8114 if (output_semicolon)
8115 output.semicolon();
8116 });
8117 DEFPRINT(AST_Let, function(self, output) {
8118 self._do_print(output, "let");
8119 });
8120 DEFPRINT(AST_Var, function(self, output) {
8121 self._do_print(output, "var");
8122 });
8123 DEFPRINT(AST_Const, function(self, output) {
8124 self._do_print(output, "const");
8125 });
8126 DEFPRINT(AST_Import, function(self, output) {
8127 output.print("import");
8128 output.space();
8129 if (self.imported_name) {
8130 self.imported_name.print(output);
8131 }
8132 if (self.imported_name && self.imported_names) {
8133 output.print(",");
8134 output.space();
8135 }
8136 if (self.imported_names) {
8137 if (self.imported_names.length === 1 && self.imported_names[0].foreign_name.name === "*") {
8138 self.imported_names[0].print(output);
8139 } else {
8140 output.print("{");
8141 self.imported_names.forEach(function (name_import, i) {
8142 output.space();
8143 name_import.print(output);
8144 if (i < self.imported_names.length - 1) {
8145 output.print(",");
8146 }
8147 });
8148 output.space();
8149 output.print("}");
8150 }
8151 }
8152 if (self.imported_name || self.imported_names) {
8153 output.space();
8154 output.print("from");
8155 output.space();
8156 }
8157 self.module_name.print(output);
8158 output.semicolon();
8159 });
8160 DEFPRINT(AST_ImportMeta, function(self, output) {
8161 output.print("import.meta");
8162 });
8163
8164 DEFPRINT(AST_NameMapping, function(self, output) {
8165 var is_import = output.parent() instanceof AST_Import;
8166 var definition = self.name.definition();
8167 var names_are_different =
8168 (definition && definition.mangled_name || self.name.name) !==
8169 self.foreign_name.name;
8170 if (names_are_different) {
8171 if (is_import) {
8172 output.print(self.foreign_name.name);
8173 } else {
8174 self.name.print(output);
8175 }
8176 output.space();
8177 output.print("as");
8178 output.space();
8179 if (is_import) {
8180 self.name.print(output);
8181 } else {
8182 output.print(self.foreign_name.name);
8183 }
8184 } else {
8185 self.name.print(output);
8186 }
8187 });
8188
8189 DEFPRINT(AST_Export, function(self, output) {
8190 output.print("export");
8191 output.space();
8192 if (self.is_default) {
8193 output.print("default");
8194 output.space();
8195 }
8196 if (self.exported_names) {
8197 if (self.exported_names.length === 1 && self.exported_names[0].name.name === "*") {
8198 self.exported_names[0].print(output);
8199 } else {
8200 output.print("{");
8201 self.exported_names.forEach(function(name_export, i) {
8202 output.space();
8203 name_export.print(output);
8204 if (i < self.exported_names.length - 1) {
8205 output.print(",");
8206 }
8207 });
8208 output.space();
8209 output.print("}");
8210 }
8211 } else if (self.exported_value) {
8212 self.exported_value.print(output);
8213 } else if (self.exported_definition) {
8214 self.exported_definition.print(output);
8215 if (self.exported_definition instanceof AST_Definitions) return;
8216 }
8217 if (self.module_name) {
8218 output.space();
8219 output.print("from");
8220 output.space();
8221 self.module_name.print(output);
8222 }
8223 if (self.exported_value
8224 && !(self.exported_value instanceof AST_Defun ||
8225 self.exported_value instanceof AST_Function ||
8226 self.exported_value instanceof AST_Class)
8227 || self.module_name
8228 || self.exported_names
8229 ) {
8230 output.semicolon();
8231 }
8232 });
8233
8234 function parenthesize_for_noin(node, output, noin) {
8235 var parens = false;
8236 // need to take some precautions here:
8237 // https://github.com/mishoo/UglifyJS2/issues/60
8238 if (noin) {
8239 parens = walk(node, node => {
8240 if (node instanceof AST_Scope) return true;
8241 if (node instanceof AST_Binary && node.operator == "in") {
8242 return walk_abort; // makes walk() return true
8243 }
8244 });
8245 }
8246 node.print(output, parens);
8247 }
8248
8249 DEFPRINT(AST_VarDef, function(self, output) {
8250 self.name.print(output);
8251 if (self.value) {
8252 output.space();
8253 output.print("=");
8254 output.space();
8255 var p = output.parent(1);
8256 var noin = p instanceof AST_For || p instanceof AST_ForIn;
8257 parenthesize_for_noin(self.value, output, noin);
8258 }
8259 });
8260
8261 /* -----[ other expressions ]----- */
8262 DEFPRINT(AST_Call, function(self, output) {
8263 self.expression.print(output);
8264 if (self instanceof AST_New && self.args.length === 0)
8265 return;
8266 if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) {
8267 output.add_mapping(self.start);
8268 }
8269 if (self.optional) output.print("?.");
8270 output.with_parens(function() {
8271 self.args.forEach(function(expr, i) {
8272 if (i) output.comma();
8273 expr.print(output);
8274 });
8275 });
8276 });
8277 DEFPRINT(AST_New, function(self, output) {
8278 output.print("new");
8279 output.space();
8280 AST_Call.prototype._codegen(self, output);
8281 });
8282
8283 AST_Sequence.DEFMETHOD("_do_print", function(output) {
8284 this.expressions.forEach(function(node, index) {
8285 if (index > 0) {
8286 output.comma();
8287 if (output.should_break()) {
8288 output.newline();
8289 output.indent();
8290 }
8291 }
8292 node.print(output);
8293 });
8294 });
8295 DEFPRINT(AST_Sequence, function(self, output) {
8296 self._do_print(output);
8297 // var p = output.parent();
8298 // if (p instanceof AST_Statement) {
8299 // output.with_indent(output.next_indent(), function(){
8300 // self._do_print(output);
8301 // });
8302 // } else {
8303 // self._do_print(output);
8304 // }
8305 });
8306 DEFPRINT(AST_Dot, function(self, output) {
8307 var expr = self.expression;
8308 expr.print(output);
8309 var prop = self.property;
8310 var print_computed = RESERVED_WORDS.has(prop)
8311 ? output.option("ie8")
8312 : !is_identifier_string(prop, output.option("ecma") >= 2015);
8313
8314 if (self.optional) output.print("?.");
8315
8316 if (print_computed) {
8317 output.print("[");
8318 output.add_mapping(self.end);
8319 output.print_string(prop);
8320 output.print("]");
8321 } else {
8322 if (expr instanceof AST_Number && expr.getValue() >= 0) {
8323 if (!/[xa-f.)]/i.test(output.last())) {
8324 output.print(".");
8325 }
8326 }
8327 if (!self.optional) output.print(".");
8328 // the name after dot would be mapped about here.
8329 output.add_mapping(self.end);
8330 output.print_name(prop);
8331 }
8332 });
8333 DEFPRINT(AST_Sub, function(self, output) {
8334 self.expression.print(output);
8335 if (self.optional) output.print("?.");
8336 output.print("[");
8337 self.property.print(output);
8338 output.print("]");
8339 });
8340 DEFPRINT(AST_Chain, function(self, output) {
8341 self.expression.print(output);
8342 });
8343 DEFPRINT(AST_UnaryPrefix, function(self, output) {
8344 var op = self.operator;
8345 output.print(op);
8346 if (/^[a-z]/i.test(op)
8347 || (/[+-]$/.test(op)
8348 && self.expression instanceof AST_UnaryPrefix
8349 && /^[+-]/.test(self.expression.operator))) {
8350 output.space();
8351 }
8352 self.expression.print(output);
8353 });
8354 DEFPRINT(AST_UnaryPostfix, function(self, output) {
8355 self.expression.print(output);
8356 output.print(self.operator);
8357 });
8358 DEFPRINT(AST_Binary, function(self, output) {
8359 var op = self.operator;
8360 self.left.print(output);
8361 if (op[0] == ">" /* ">>" ">>>" ">" ">=" */
8362 && self.left instanceof AST_UnaryPostfix
8363 && self.left.operator == "--") {
8364 // space is mandatory to avoid outputting -->
8365 output.print(" ");
8366 } else {
8367 // the space is optional depending on "beautify"
8368 output.space();
8369 }
8370 output.print(op);
8371 if ((op == "<" || op == "<<")
8372 && self.right instanceof AST_UnaryPrefix
8373 && self.right.operator == "!"
8374 && self.right.expression instanceof AST_UnaryPrefix
8375 && self.right.expression.operator == "--") {
8376 // space is mandatory to avoid outputting <!--
8377 output.print(" ");
8378 } else {
8379 // the space is optional depending on "beautify"
8380 output.space();
8381 }
8382 self.right.print(output);
8383 });
8384 DEFPRINT(AST_Conditional, function(self, output) {
8385 self.condition.print(output);
8386 output.space();
8387 output.print("?");
8388 output.space();
8389 self.consequent.print(output);
8390 output.space();
8391 output.colon();
8392 self.alternative.print(output);
8393 });
8394
8395 /* -----[ literals ]----- */
8396 DEFPRINT(AST_Array, function(self, output) {
8397 output.with_square(function() {
8398 var a = self.elements, len = a.length;
8399 if (len > 0) output.space();
8400 a.forEach(function(exp, i) {
8401 if (i) output.comma();
8402 exp.print(output);
8403 // If the final element is a hole, we need to make sure it
8404 // doesn't look like a trailing comma, by inserting an actual
8405 // trailing comma.
8406 if (i === len - 1 && exp instanceof AST_Hole)
8407 output.comma();
8408 });
8409 if (len > 0) output.space();
8410 });
8411 });
8412 DEFPRINT(AST_Object, function(self, output) {
8413 if (self.properties.length > 0) output.with_block(function() {
8414 self.properties.forEach(function(prop, i) {
8415 if (i) {
8416 output.print(",");
8417 output.newline();
8418 }
8419 output.indent();
8420 prop.print(output);
8421 });
8422 output.newline();
8423 });
8424 else print_braced_empty(self, output);
8425 });
8426 DEFPRINT(AST_Class, function(self, output) {
8427 output.print("class");
8428 output.space();
8429 if (self.name) {
8430 self.name.print(output);
8431 output.space();
8432 }
8433 if (self.extends) {
8434 var parens = (
8435 !(self.extends instanceof AST_SymbolRef)
8436 && !(self.extends instanceof AST_PropAccess)
8437 && !(self.extends instanceof AST_ClassExpression)
8438 && !(self.extends instanceof AST_Function)
8439 );
8440 output.print("extends");
8441 if (parens) {
8442 output.print("(");
8443 } else {
8444 output.space();
8445 }
8446 self.extends.print(output);
8447 if (parens) {
8448 output.print(")");
8449 } else {
8450 output.space();
8451 }
8452 }
8453 if (self.properties.length > 0) output.with_block(function() {
8454 self.properties.forEach(function(prop, i) {
8455 if (i) {
8456 output.newline();
8457 }
8458 output.indent();
8459 prop.print(output);
8460 });
8461 output.newline();
8462 });
8463 else output.print("{}");
8464 });
8465 DEFPRINT(AST_NewTarget, function(self, output) {
8466 output.print("new.target");
8467 });
8468
8469 function print_property_name(key, quote, output) {
8470 if (output.option("quote_keys")) {
8471 return output.print_string(key);
8472 }
8473 if ("" + +key == key && key >= 0) {
8474 if (output.option("keep_numbers")) {
8475 return output.print(key);
8476 }
8477 return output.print(make_num(key));
8478 }
8479 var print_string = RESERVED_WORDS.has(key)
8480 ? output.option("ie8")
8481 : (
8482 output.option("ecma") < 2015
8483 ? !is_basic_identifier_string(key)
8484 : !is_identifier_string(key, true)
8485 );
8486 if (print_string || (quote && output.option("keep_quoted_props"))) {
8487 return output.print_string(key, quote);
8488 }
8489 return output.print_name(key);
8490 }
8491
8492 DEFPRINT(AST_ObjectKeyVal, function(self, output) {
8493 function get_name(self) {
8494 var def = self.definition();
8495 return def ? def.mangled_name || def.name : self.name;
8496 }
8497
8498 var allowShortHand = output.option("shorthand");
8499 if (allowShortHand &&
8500 self.value instanceof AST_Symbol &&
8501 is_identifier_string(self.key, output.option("ecma") >= 2015) &&
8502 get_name(self.value) === self.key &&
8503 !RESERVED_WORDS.has(self.key)
8504 ) {
8505 print_property_name(self.key, self.quote, output);
8506
8507 } else if (allowShortHand &&
8508 self.value instanceof AST_DefaultAssign &&
8509 self.value.left instanceof AST_Symbol &&
8510 is_identifier_string(self.key, output.option("ecma") >= 2015) &&
8511 get_name(self.value.left) === self.key
8512 ) {
8513 print_property_name(self.key, self.quote, output);
8514 output.space();
8515 output.print("=");
8516 output.space();
8517 self.value.right.print(output);
8518 } else {
8519 if (!(self.key instanceof AST_Node)) {
8520 print_property_name(self.key, self.quote, output);
8521 } else {
8522 output.with_square(function() {
8523 self.key.print(output);
8524 });
8525 }
8526 output.colon();
8527 self.value.print(output);
8528 }
8529 });
8530 DEFPRINT(AST_ClassProperty, (self, output) => {
8531 if (self.static) {
8532 output.print("static");
8533 output.space();
8534 }
8535
8536 if (self.key instanceof AST_SymbolClassProperty) {
8537 print_property_name(self.key.name, self.quote, output);
8538 } else {
8539 output.print("[");
8540 self.key.print(output);
8541 output.print("]");
8542 }
8543
8544 if (self.value) {
8545 output.print("=");
8546 self.value.print(output);
8547 }
8548
8549 output.semicolon();
8550 });
8551 AST_ObjectProperty.DEFMETHOD("_print_getter_setter", function(type, output) {
8552 var self = this;
8553 if (self.static) {
8554 output.print("static");
8555 output.space();
8556 }
8557 if (type) {
8558 output.print(type);
8559 output.space();
8560 }
8561 if (self.key instanceof AST_SymbolMethod) {
8562 print_property_name(self.key.name, self.quote, output);
8563 } else {
8564 output.with_square(function() {
8565 self.key.print(output);
8566 });
8567 }
8568 self.value._do_print(output, true);
8569 });
8570 DEFPRINT(AST_ObjectSetter, function(self, output) {
8571 self._print_getter_setter("set", output);
8572 });
8573 DEFPRINT(AST_ObjectGetter, function(self, output) {
8574 self._print_getter_setter("get", output);
8575 });
8576 DEFPRINT(AST_ConciseMethod, function(self, output) {
8577 var type;
8578 if (self.is_generator && self.async) {
8579 type = "async*";
8580 } else if (self.is_generator) {
8581 type = "*";
8582 } else if (self.async) {
8583 type = "async";
8584 }
8585 self._print_getter_setter(type, output);
8586 });
8587 AST_Symbol.DEFMETHOD("_do_print", function(output) {
8588 var def = this.definition();
8589 output.print_name(def ? def.mangled_name || def.name : this.name);
8590 });
8591 DEFPRINT(AST_Symbol, function (self, output) {
8592 self._do_print(output);
8593 });
8594 DEFPRINT(AST_Hole, noop);
8595 DEFPRINT(AST_This, function(self, output) {
8596 output.print("this");
8597 });
8598 DEFPRINT(AST_Super, function(self, output) {
8599 output.print("super");
8600 });
8601 DEFPRINT(AST_Constant, function(self, output) {
8602 output.print(self.getValue());
8603 });
8604 DEFPRINT(AST_String, function(self, output) {
8605 output.print_string(self.getValue(), self.quote, output.in_directive);
8606 });
8607 DEFPRINT(AST_Number, function(self, output) {
8608 if ((output.option("keep_numbers") || output.use_asm) && self.start && self.start.raw != null) {
8609 output.print(self.start.raw);
8610 } else {
8611 output.print(make_num(self.getValue()));
8612 }
8613 });
8614 DEFPRINT(AST_BigInt, function(self, output) {
8615 output.print(self.getValue() + "n");
8616 });
8617
8618 const r_slash_script = /(<\s*\/\s*script)/i;
8619 const slash_script_replace = (_, $1) => $1.replace("/", "\\/");
8620 DEFPRINT(AST_RegExp, function(self, output) {
8621 let { source, flags } = self.getValue();
8622 source = regexp_source_fix(source);
8623 flags = flags ? sort_regexp_flags(flags) : "";
8624 source = source.replace(r_slash_script, slash_script_replace);
8625 output.print(output.to_utf8(`/${source}/${flags}`));
8626 const parent = output.parent();
8627 if (
8628 parent instanceof AST_Binary
8629 && /^\w/.test(parent.operator)
8630 && parent.left === self
8631 ) {
8632 output.print(" ");
8633 }
8634 });
8635
8636 function force_statement(stat, output) {
8637 if (output.option("braces")) {
8638 make_block(stat, output);
8639 } else {
8640 if (!stat || stat instanceof AST_EmptyStatement)
8641 output.force_semicolon();
8642 else
8643 stat.print(output);
8644 }
8645 }
8646
8647 function best_of(a) {
8648 var best = a[0], len = best.length;
8649 for (var i = 1; i < a.length; ++i) {
8650 if (a[i].length < len) {
8651 best = a[i];
8652 len = best.length;
8653 }
8654 }
8655 return best;
8656 }
8657
8658 function make_num(num) {
8659 var str = num.toString(10).replace(/^0\./, ".").replace("e+", "e");
8660 var candidates = [ str ];
8661 if (Math.floor(num) === num) {
8662 if (num < 0) {
8663 candidates.push("-0x" + (-num).toString(16).toLowerCase());
8664 } else {
8665 candidates.push("0x" + num.toString(16).toLowerCase());
8666 }
8667 }
8668 var match, len, digits;
8669 if (match = /^\.0+/.exec(str)) {
8670 len = match[0].length;
8671 digits = str.slice(len);
8672 candidates.push(digits + "e-" + (digits.length + len - 1));
8673 } else if (match = /0+$/.exec(str)) {
8674 len = match[0].length;
8675 candidates.push(str.slice(0, -len) + "e" + len);
8676 } else if (match = /^(\d)\.(\d+)e(-?\d+)$/.exec(str)) {
8677 candidates.push(match[1] + match[2] + "e" + (match[3] - match[2].length));
8678 }
8679 return best_of(candidates);
8680 }
8681
8682 function make_block(stmt, output) {
8683 if (!stmt || stmt instanceof AST_EmptyStatement)
8684 output.print("{}");
8685 else if (stmt instanceof AST_BlockStatement)
8686 stmt.print(output);
8687 else output.with_block(function() {
8688 output.indent();
8689 stmt.print(output);
8690 output.newline();
8691 });
8692 }
8693
8694 /* -----[ source map generators ]----- */
8695
8696 function DEFMAP(nodetype, generator) {
8697 nodetype.forEach(function(nodetype) {
8698 nodetype.DEFMETHOD("add_source_map", generator);
8699 });
8700 }
8701
8702 DEFMAP([
8703 // We could easily add info for ALL nodes, but it seems to me that
8704 // would be quite wasteful, hence this noop in the base class.
8705 AST_Node,
8706 // since the label symbol will mark it
8707 AST_LabeledStatement,
8708 AST_Toplevel,
8709 ], noop);
8710
8711 // XXX: I'm not exactly sure if we need it for all of these nodes,
8712 // or if we should add even more.
8713 DEFMAP([
8714 AST_Array,
8715 AST_BlockStatement,
8716 AST_Catch,
8717 AST_Class,
8718 AST_Constant,
8719 AST_Debugger,
8720 AST_Definitions,
8721 AST_Directive,
8722 AST_Finally,
8723 AST_Jump,
8724 AST_Lambda,
8725 AST_New,
8726 AST_Object,
8727 AST_StatementWithBody,
8728 AST_Symbol,
8729 AST_Switch,
8730 AST_SwitchBranch,
8731 AST_TemplateString,
8732 AST_TemplateSegment,
8733 AST_Try,
8734 ], function(output) {
8735 output.add_mapping(this.start);
8736 });
8737
8738 DEFMAP([
8739 AST_ObjectGetter,
8740 AST_ObjectSetter,
8741 ], function(output) {
8742 output.add_mapping(this.start, this.key.name);
8743 });
8744
8745 DEFMAP([ AST_ObjectProperty ], function(output) {
8746 output.add_mapping(this.start, this.key);
8747 });
8748})();
8749
8750const shallow_cmp = (node1, node2) => {
8751 return (
8752 node1 === null && node2 === null
8753 || node1.TYPE === node2.TYPE && node1.shallow_cmp(node2)
8754 );
8755};
8756
8757const equivalent_to = (tree1, tree2) => {
8758 if (!shallow_cmp(tree1, tree2)) return false;
8759 const walk_1_state = [tree1];
8760 const walk_2_state = [tree2];
8761
8762 const walk_1_push = walk_1_state.push.bind(walk_1_state);
8763 const walk_2_push = walk_2_state.push.bind(walk_2_state);
8764
8765 while (walk_1_state.length && walk_2_state.length) {
8766 const node_1 = walk_1_state.pop();
8767 const node_2 = walk_2_state.pop();
8768
8769 if (!shallow_cmp(node_1, node_2)) return false;
8770
8771 node_1._children_backwards(walk_1_push);
8772 node_2._children_backwards(walk_2_push);
8773
8774 if (walk_1_state.length !== walk_2_state.length) {
8775 // Different number of children
8776 return false;
8777 }
8778 }
8779
8780 return walk_1_state.length == 0 && walk_2_state.length == 0;
8781};
8782
8783// Creates a shallow compare function
8784const mkshallow = (props) => {
8785 const comparisons = Object
8786 .keys(props)
8787 .map(key => {
8788 if (props[key] === "eq") {
8789 return `this.${key} === other.${key}`;
8790 } else if (props[key] === "exist") {
8791 return `(this.${key} == null ? other.${key} == null : this.${key} === other.${key})`;
8792 } else {
8793 throw new Error(`mkshallow: Unexpected instruction: ${props[key]}`);
8794 }
8795 })
8796 .join(" && ");
8797
8798 return new Function("other", "return " + comparisons);
8799};
8800
8801const pass_through = () => true;
8802
8803AST_Node.prototype.shallow_cmp = function () {
8804 throw new Error("did not find a shallow_cmp function for " + this.constructor.name);
8805};
8806
8807AST_Debugger.prototype.shallow_cmp = pass_through;
8808
8809AST_Directive.prototype.shallow_cmp = mkshallow({ value: "eq" });
8810
8811AST_SimpleStatement.prototype.shallow_cmp = pass_through;
8812
8813AST_Block.prototype.shallow_cmp = pass_through;
8814
8815AST_EmptyStatement.prototype.shallow_cmp = pass_through;
8816
8817AST_LabeledStatement.prototype.shallow_cmp = mkshallow({ "label.name": "eq" });
8818
8819AST_Do.prototype.shallow_cmp = pass_through;
8820
8821AST_While.prototype.shallow_cmp = pass_through;
8822
8823AST_For.prototype.shallow_cmp = mkshallow({
8824 init: "exist",
8825 condition: "exist",
8826 step: "exist"
8827});
8828
8829AST_ForIn.prototype.shallow_cmp = pass_through;
8830
8831AST_ForOf.prototype.shallow_cmp = pass_through;
8832
8833AST_With.prototype.shallow_cmp = pass_through;
8834
8835AST_Toplevel.prototype.shallow_cmp = pass_through;
8836
8837AST_Expansion.prototype.shallow_cmp = pass_through;
8838
8839AST_Lambda.prototype.shallow_cmp = mkshallow({
8840 is_generator: "eq",
8841 async: "eq"
8842});
8843
8844AST_Destructuring.prototype.shallow_cmp = mkshallow({
8845 is_array: "eq"
8846});
8847
8848AST_PrefixedTemplateString.prototype.shallow_cmp = pass_through;
8849
8850AST_TemplateString.prototype.shallow_cmp = pass_through;
8851
8852AST_TemplateSegment.prototype.shallow_cmp = mkshallow({
8853 "value": "eq"
8854});
8855
8856AST_Jump.prototype.shallow_cmp = pass_through;
8857
8858AST_LoopControl.prototype.shallow_cmp = pass_through;
8859
8860AST_Await.prototype.shallow_cmp = pass_through;
8861
8862AST_Yield.prototype.shallow_cmp = mkshallow({
8863 is_star: "eq"
8864});
8865
8866AST_If.prototype.shallow_cmp = mkshallow({
8867 alternative: "exist"
8868});
8869
8870AST_Switch.prototype.shallow_cmp = pass_through;
8871
8872AST_SwitchBranch.prototype.shallow_cmp = pass_through;
8873
8874AST_Try.prototype.shallow_cmp = mkshallow({
8875 bcatch: "exist",
8876 bfinally: "exist"
8877});
8878
8879AST_Catch.prototype.shallow_cmp = mkshallow({
8880 argname: "exist"
8881});
8882
8883AST_Finally.prototype.shallow_cmp = pass_through;
8884
8885AST_Definitions.prototype.shallow_cmp = pass_through;
8886
8887AST_VarDef.prototype.shallow_cmp = mkshallow({
8888 value: "exist"
8889});
8890
8891AST_NameMapping.prototype.shallow_cmp = pass_through;
8892
8893AST_Import.prototype.shallow_cmp = mkshallow({
8894 imported_name: "exist",
8895 imported_names: "exist"
8896});
8897
8898AST_ImportMeta.prototype.shallow_cmp = pass_through;
8899
8900AST_Export.prototype.shallow_cmp = mkshallow({
8901 exported_definition: "exist",
8902 exported_value: "exist",
8903 exported_names: "exist",
8904 module_name: "eq",
8905 is_default: "eq",
8906});
8907
8908AST_Call.prototype.shallow_cmp = pass_through;
8909
8910AST_Sequence.prototype.shallow_cmp = pass_through;
8911
8912AST_PropAccess.prototype.shallow_cmp = pass_through;
8913
8914AST_Chain.prototype.shallow_cmp = pass_through;
8915
8916AST_Dot.prototype.shallow_cmp = mkshallow({
8917 property: "eq"
8918});
8919
8920AST_Unary.prototype.shallow_cmp = mkshallow({
8921 operator: "eq"
8922});
8923
8924AST_Binary.prototype.shallow_cmp = mkshallow({
8925 operator: "eq"
8926});
8927
8928AST_Conditional.prototype.shallow_cmp = pass_through;
8929
8930AST_Array.prototype.shallow_cmp = pass_through;
8931
8932AST_Object.prototype.shallow_cmp = pass_through;
8933
8934AST_ObjectProperty.prototype.shallow_cmp = pass_through;
8935
8936AST_ObjectKeyVal.prototype.shallow_cmp = mkshallow({
8937 key: "eq"
8938});
8939
8940AST_ObjectSetter.prototype.shallow_cmp = mkshallow({
8941 static: "eq"
8942});
8943
8944AST_ObjectGetter.prototype.shallow_cmp = mkshallow({
8945 static: "eq"
8946});
8947
8948AST_ConciseMethod.prototype.shallow_cmp = mkshallow({
8949 static: "eq",
8950 is_generator: "eq",
8951 async: "eq",
8952});
8953
8954AST_Class.prototype.shallow_cmp = mkshallow({
8955 name: "exist",
8956 extends: "exist",
8957});
8958
8959AST_ClassProperty.prototype.shallow_cmp = mkshallow({
8960 static: "eq"
8961});
8962
8963AST_Symbol.prototype.shallow_cmp = mkshallow({
8964 name: "eq"
8965});
8966
8967AST_NewTarget.prototype.shallow_cmp = pass_through;
8968
8969AST_This.prototype.shallow_cmp = pass_through;
8970
8971AST_Super.prototype.shallow_cmp = pass_through;
8972
8973AST_String.prototype.shallow_cmp = mkshallow({
8974 value: "eq"
8975});
8976
8977AST_Number.prototype.shallow_cmp = mkshallow({
8978 value: "eq"
8979});
8980
8981AST_BigInt.prototype.shallow_cmp = mkshallow({
8982 value: "eq"
8983});
8984
8985AST_RegExp.prototype.shallow_cmp = function (other) {
8986 return (
8987 this.value.flags === other.value.flags
8988 && this.value.source === other.value.source
8989 );
8990};
8991
8992AST_Atom.prototype.shallow_cmp = pass_through;
8993
8994/***********************************************************************
8995
8996 A JavaScript tokenizer / parser / beautifier / compressor.
8997 https://github.com/mishoo/UglifyJS2
8998
8999 -------------------------------- (C) ---------------------------------
9000
9001 Author: Mihai Bazon
9002 <mihai.bazon@gmail.com>
9003 http://mihai.bazon.net/blog
9004
9005 Distributed under the BSD license:
9006
9007 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
9008
9009 Redistribution and use in source and binary forms, with or without
9010 modification, are permitted provided that the following conditions
9011 are met:
9012
9013 * Redistributions of source code must retain the above
9014 copyright notice, this list of conditions and the following
9015 disclaimer.
9016
9017 * Redistributions in binary form must reproduce the above
9018 copyright notice, this list of conditions and the following
9019 disclaimer in the documentation and/or other materials
9020 provided with the distribution.
9021
9022 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
9023 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9024 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
9025 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
9026 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
9027 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
9028 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
9029 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
9030 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
9031 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
9032 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
9033 SUCH DAMAGE.
9034
9035 ***********************************************************************/
9036
9037const MASK_EXPORT_DONT_MANGLE = 1 << 0;
9038const MASK_EXPORT_WANT_MANGLE = 1 << 1;
9039
9040let function_defs = null;
9041let unmangleable_names = null;
9042
9043class SymbolDef {
9044 constructor(scope, orig, init) {
9045 this.name = orig.name;
9046 this.orig = [ orig ];
9047 this.init = init;
9048 this.eliminated = 0;
9049 this.assignments = 0;
9050 this.scope = scope;
9051 this.replaced = 0;
9052 this.global = false;
9053 this.export = 0;
9054 this.mangled_name = null;
9055 this.undeclared = false;
9056 this.id = SymbolDef.next_id++;
9057 this.chained = false;
9058 this.direct_access = false;
9059 this.escaped = 0;
9060 this.recursive_refs = 0;
9061 this.references = [];
9062 this.should_replace = undefined;
9063 this.single_use = false;
9064 this.fixed = false;
9065 Object.seal(this);
9066 }
9067 fixed_value() {
9068 if (!this.fixed || this.fixed instanceof AST_Node) return this.fixed;
9069 return this.fixed();
9070 }
9071 unmangleable(options) {
9072 if (!options) options = {};
9073
9074 if (
9075 function_defs &&
9076 function_defs.has(this.id) &&
9077 keep_name(options.keep_fnames, this.orig[0].name)
9078 ) return true;
9079
9080 return this.global && !options.toplevel
9081 || (this.export & MASK_EXPORT_DONT_MANGLE)
9082 || this.undeclared
9083 || !options.eval && this.scope.pinned()
9084 || (this.orig[0] instanceof AST_SymbolLambda
9085 || this.orig[0] instanceof AST_SymbolDefun) && keep_name(options.keep_fnames, this.orig[0].name)
9086 || this.orig[0] instanceof AST_SymbolMethod
9087 || (this.orig[0] instanceof AST_SymbolClass
9088 || this.orig[0] instanceof AST_SymbolDefClass) && keep_name(options.keep_classnames, this.orig[0].name);
9089 }
9090 mangle(options) {
9091 const cache = options.cache && options.cache.props;
9092 if (this.global && cache && cache.has(this.name)) {
9093 this.mangled_name = cache.get(this.name);
9094 } else if (!this.mangled_name && !this.unmangleable(options)) {
9095 var s = this.scope;
9096 var sym = this.orig[0];
9097 if (options.ie8 && sym instanceof AST_SymbolLambda)
9098 s = s.parent_scope;
9099 const redefinition = redefined_catch_def(this);
9100 this.mangled_name = redefinition
9101 ? redefinition.mangled_name || redefinition.name
9102 : s.next_mangled(options, this);
9103 if (this.global && cache) {
9104 cache.set(this.name, this.mangled_name);
9105 }
9106 }
9107 }
9108}
9109
9110SymbolDef.next_id = 1;
9111
9112function redefined_catch_def(def) {
9113 if (def.orig[0] instanceof AST_SymbolCatch
9114 && def.scope.is_block_scope()
9115 ) {
9116 return def.scope.get_defun_scope().variables.get(def.name);
9117 }
9118}
9119
9120AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = null, toplevel = this } = {}) {
9121 options = defaults(options, {
9122 cache: null,
9123 ie8: false,
9124 safari10: false,
9125 });
9126
9127 if (!(toplevel instanceof AST_Toplevel)) {
9128 throw new Error("Invalid toplevel scope");
9129 }
9130
9131 // pass 1: setup scope chaining and handle definitions
9132 var scope = this.parent_scope = parent_scope;
9133 var labels = new Map();
9134 var defun = null;
9135 var in_destructuring = null;
9136 var for_scopes = [];
9137 var tw = new TreeWalker((node, descend) => {
9138 if (node.is_block_scope()) {
9139 const save_scope = scope;
9140 node.block_scope = scope = new AST_Scope(node);
9141 scope._block_scope = true;
9142 // AST_Try in the AST sadly *is* (not has) a body itself,
9143 // and its catch and finally branches are children of the AST_Try itself
9144 const parent_scope = node instanceof AST_Catch
9145 ? save_scope.parent_scope
9146 : save_scope;
9147 scope.init_scope_vars(parent_scope);
9148 scope.uses_with = save_scope.uses_with;
9149 scope.uses_eval = save_scope.uses_eval;
9150 if (options.safari10) {
9151 if (node instanceof AST_For || node instanceof AST_ForIn) {
9152 for_scopes.push(scope);
9153 }
9154 }
9155
9156 if (node instanceof AST_Switch) {
9157 // XXX: HACK! Ensure the switch expression gets the correct scope (the parent scope) and the body gets the contained scope
9158 // AST_Switch has a scope within the body, but it itself "is a block scope"
9159 // This means the switched expression has to belong to the outer scope
9160 // while the body inside belongs to the switch itself.
9161 // This is pretty nasty and warrants an AST change similar to AST_Try (read above)
9162 const the_block_scope = scope;
9163 scope = save_scope;
9164 node.expression.walk(tw);
9165 scope = the_block_scope;
9166 for (let i = 0; i < node.body.length; i++) {
9167 node.body[i].walk(tw);
9168 }
9169 } else {
9170 descend();
9171 }
9172 scope = save_scope;
9173 return true;
9174 }
9175 if (node instanceof AST_Destructuring) {
9176 const save_destructuring = in_destructuring;
9177 in_destructuring = node;
9178 descend();
9179 in_destructuring = save_destructuring;
9180 return true;
9181 }
9182 if (node instanceof AST_Scope) {
9183 node.init_scope_vars(scope);
9184 var save_scope = scope;
9185 var save_defun = defun;
9186 var save_labels = labels;
9187 defun = scope = node;
9188 labels = new Map();
9189 descend();
9190 scope = save_scope;
9191 defun = save_defun;
9192 labels = save_labels;
9193 return true; // don't descend again in TreeWalker
9194 }
9195 if (node instanceof AST_LabeledStatement) {
9196 var l = node.label;
9197 if (labels.has(l.name)) {
9198 throw new Error(string_template("Label {name} defined twice", l));
9199 }
9200 labels.set(l.name, l);
9201 descend();
9202 labels.delete(l.name);
9203 return true; // no descend again
9204 }
9205 if (node instanceof AST_With) {
9206 for (var s = scope; s; s = s.parent_scope)
9207 s.uses_with = true;
9208 return;
9209 }
9210 if (node instanceof AST_Symbol) {
9211 node.scope = scope;
9212 }
9213 if (node instanceof AST_Label) {
9214 node.thedef = node;
9215 node.references = [];
9216 }
9217 if (node instanceof AST_SymbolLambda) {
9218 defun.def_function(node, node.name == "arguments" ? undefined : defun);
9219 } else if (node instanceof AST_SymbolDefun) {
9220 // Careful here, the scope where this should be defined is
9221 // the parent scope. The reason is that we enter a new
9222 // scope when we encounter the AST_Defun node (which is
9223 // instanceof AST_Scope) but we get to the symbol a bit
9224 // later.
9225 mark_export((node.scope = defun.parent_scope.get_defun_scope()).def_function(node, defun), 1);
9226 } else if (node instanceof AST_SymbolClass) {
9227 mark_export(defun.def_variable(node, defun), 1);
9228 } else if (node instanceof AST_SymbolImport) {
9229 scope.def_variable(node);
9230 } else if (node instanceof AST_SymbolDefClass) {
9231 // This deals with the name of the class being available
9232 // inside the class.
9233 mark_export((node.scope = defun.parent_scope).def_function(node, defun), 1);
9234 } else if (
9235 node instanceof AST_SymbolVar
9236 || node instanceof AST_SymbolLet
9237 || node instanceof AST_SymbolConst
9238 || node instanceof AST_SymbolCatch
9239 ) {
9240 var def;
9241 if (node instanceof AST_SymbolBlockDeclaration) {
9242 def = scope.def_variable(node, null);
9243 } else {
9244 def = defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined);
9245 }
9246 if (!def.orig.every((sym) => {
9247 if (sym === node) return true;
9248 if (node instanceof AST_SymbolBlockDeclaration) {
9249 return sym instanceof AST_SymbolLambda;
9250 }
9251 return !(sym instanceof AST_SymbolLet || sym instanceof AST_SymbolConst);
9252 })) {
9253 js_error(
9254 `"${node.name}" is redeclared`,
9255 node.start.file,
9256 node.start.line,
9257 node.start.col,
9258 node.start.pos
9259 );
9260 }
9261 if (!(node instanceof AST_SymbolFunarg)) mark_export(def, 2);
9262 if (defun !== scope) {
9263 node.mark_enclosed();
9264 var def = scope.find_variable(node);
9265 if (node.thedef !== def) {
9266 node.thedef = def;
9267 node.reference();
9268 }
9269 }
9270 } else if (node instanceof AST_LabelRef) {
9271 var sym = labels.get(node.name);
9272 if (!sym) throw new Error(string_template("Undefined label {name} [{line},{col}]", {
9273 name: node.name,
9274 line: node.start.line,
9275 col: node.start.col
9276 }));
9277 node.thedef = sym;
9278 }
9279 if (!(scope instanceof AST_Toplevel) && (node instanceof AST_Export || node instanceof AST_Import)) {
9280 js_error(
9281 `"${node.TYPE}" statement may only appear at the top level`,
9282 node.start.file,
9283 node.start.line,
9284 node.start.col,
9285 node.start.pos
9286 );
9287 }
9288 });
9289 this.walk(tw);
9290
9291 function mark_export(def, level) {
9292 if (in_destructuring) {
9293 var i = 0;
9294 do {
9295 level++;
9296 } while (tw.parent(i++) !== in_destructuring);
9297 }
9298 var node = tw.parent(level);
9299 if (def.export = node instanceof AST_Export ? MASK_EXPORT_DONT_MANGLE : 0) {
9300 var exported = node.exported_definition;
9301 if ((exported instanceof AST_Defun || exported instanceof AST_DefClass) && node.is_default) {
9302 def.export = MASK_EXPORT_WANT_MANGLE;
9303 }
9304 }
9305 }
9306
9307 // pass 2: find back references and eval
9308 const is_toplevel = this instanceof AST_Toplevel;
9309 if (is_toplevel) {
9310 this.globals = new Map();
9311 }
9312
9313 var tw = new TreeWalker(node => {
9314 if (node instanceof AST_LoopControl && node.label) {
9315 node.label.thedef.references.push(node);
9316 return true;
9317 }
9318 if (node instanceof AST_SymbolRef) {
9319 var name = node.name;
9320 if (name == "eval" && tw.parent() instanceof AST_Call) {
9321 for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope) {
9322 s.uses_eval = true;
9323 }
9324 }
9325 var sym;
9326 if (tw.parent() instanceof AST_NameMapping && tw.parent(1).module_name
9327 || !(sym = node.scope.find_variable(name))) {
9328
9329 sym = toplevel.def_global(node);
9330 if (node instanceof AST_SymbolExport) sym.export = MASK_EXPORT_DONT_MANGLE;
9331 } else if (sym.scope instanceof AST_Lambda && name == "arguments") {
9332 sym.scope.uses_arguments = true;
9333 }
9334 node.thedef = sym;
9335 node.reference();
9336 if (node.scope.is_block_scope()
9337 && !(sym.orig[0] instanceof AST_SymbolBlockDeclaration)) {
9338 node.scope = node.scope.get_defun_scope();
9339 }
9340 return true;
9341 }
9342 // ensure mangling works if catch reuses a scope variable
9343 var def;
9344 if (node instanceof AST_SymbolCatch && (def = redefined_catch_def(node.definition()))) {
9345 var s = node.scope;
9346 while (s) {
9347 push_uniq(s.enclosed, def);
9348 if (s === def.scope) break;
9349 s = s.parent_scope;
9350 }
9351 }
9352 });
9353 this.walk(tw);
9354
9355 // pass 3: work around IE8 and Safari catch scope bugs
9356 if (options.ie8 || options.safari10) {
9357 walk(this, node => {
9358 if (node instanceof AST_SymbolCatch) {
9359 var name = node.name;
9360 var refs = node.thedef.references;
9361 var scope = node.scope.get_defun_scope();
9362 var def = scope.find_variable(name)
9363 || toplevel.globals.get(name)
9364 || scope.def_variable(node);
9365 refs.forEach(function(ref) {
9366 ref.thedef = def;
9367 ref.reference();
9368 });
9369 node.thedef = def;
9370 node.reference();
9371 return true;
9372 }
9373 });
9374 }
9375
9376 // pass 4: add symbol definitions to loop scopes
9377 // Safari/Webkit bug workaround - loop init let variable shadowing argument.
9378 // https://github.com/mishoo/UglifyJS2/issues/1753
9379 // https://bugs.webkit.org/show_bug.cgi?id=171041
9380 if (options.safari10) {
9381 for (const scope of for_scopes) {
9382 scope.parent_scope.variables.forEach(function(def) {
9383 push_uniq(scope.enclosed, def);
9384 });
9385 }
9386 }
9387});
9388
9389AST_Toplevel.DEFMETHOD("def_global", function(node) {
9390 var globals = this.globals, name = node.name;
9391 if (globals.has(name)) {
9392 return globals.get(name);
9393 } else {
9394 var g = new SymbolDef(this, node);
9395 g.undeclared = true;
9396 g.global = true;
9397 globals.set(name, g);
9398 return g;
9399 }
9400});
9401
9402AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope) {
9403 this.variables = new Map(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
9404 this.functions = new Map(); // map name to AST_SymbolDefun (functions defined in this scope)
9405 this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
9406 this.uses_eval = false; // will be set to true if this or nested scope uses the global `eval`
9407 this.parent_scope = parent_scope; // the parent scope
9408 this.enclosed = []; // a list of variables from this or outer scope(s) that are referenced from this or inner scopes
9409 this.cname = -1; // the current index for mangling functions/variables
9410});
9411
9412AST_Scope.DEFMETHOD("conflicting_def", function (name) {
9413 return (
9414 this.enclosed.find(def => def.name === name)
9415 || this.variables.has(name)
9416 || (this.parent_scope && this.parent_scope.conflicting_def(name))
9417 );
9418});
9419
9420AST_Scope.DEFMETHOD("conflicting_def_shallow", function (name) {
9421 return (
9422 this.enclosed.find(def => def.name === name)
9423 || this.variables.has(name)
9424 );
9425});
9426
9427AST_Scope.DEFMETHOD("add_child_scope", function (scope) {
9428 // `scope` is going to be moved into `this` right now.
9429 // Update the required scopes' information
9430
9431 if (scope.parent_scope === this) return;
9432
9433 scope.parent_scope = this;
9434
9435 // TODO uses_with, uses_eval, etc
9436
9437 const scope_ancestry = (() => {
9438 const ancestry = [];
9439 let cur = this;
9440 do {
9441 ancestry.push(cur);
9442 } while ((cur = cur.parent_scope));
9443 ancestry.reverse();
9444 return ancestry;
9445 })();
9446
9447 const new_scope_enclosed_set = new Set(scope.enclosed);
9448 const to_enclose = [];
9449 for (const scope_topdown of scope_ancestry) {
9450 to_enclose.forEach(e => push_uniq(scope_topdown.enclosed, e));
9451 for (const def of scope_topdown.variables.values()) {
9452 if (new_scope_enclosed_set.has(def)) {
9453 push_uniq(to_enclose, def);
9454 push_uniq(scope_topdown.enclosed, def);
9455 }
9456 }
9457 }
9458});
9459
9460function find_scopes_visible_from(scopes) {
9461 const found_scopes = new Set();
9462
9463 for (const scope of new Set(scopes)) {
9464 (function bubble_up(scope) {
9465 if (scope == null || found_scopes.has(scope)) return;
9466
9467 found_scopes.add(scope);
9468
9469 bubble_up(scope.parent_scope);
9470 })(scope);
9471 }
9472
9473 return [...found_scopes];
9474}
9475
9476// Creates a symbol during compression
9477AST_Scope.DEFMETHOD("create_symbol", function(SymClass, {
9478 source,
9479 tentative_name,
9480 scope,
9481 conflict_scopes = [scope],
9482 init = null
9483} = {}) {
9484 let symbol_name;
9485
9486 conflict_scopes = find_scopes_visible_from(conflict_scopes);
9487
9488 if (tentative_name) {
9489 // Implement hygiene (no new names are conflicting with existing names)
9490 tentative_name =
9491 symbol_name =
9492 tentative_name.replace(/(?:^[^a-z_$]|[^a-z0-9_$])/ig, "_");
9493
9494 let i = 0;
9495 while (conflict_scopes.find(s => s.conflicting_def_shallow(symbol_name))) {
9496 symbol_name = tentative_name + "$" + i++;
9497 }
9498 }
9499
9500 if (!symbol_name) {
9501 throw new Error("No symbol name could be generated in create_symbol()");
9502 }
9503
9504 const symbol = make_node(SymClass, source, {
9505 name: symbol_name,
9506 scope
9507 });
9508
9509 this.def_variable(symbol, init || null);
9510
9511 symbol.mark_enclosed();
9512
9513 return symbol;
9514});
9515
9516
9517AST_Node.DEFMETHOD("is_block_scope", return_false);
9518AST_Class.DEFMETHOD("is_block_scope", return_false);
9519AST_Lambda.DEFMETHOD("is_block_scope", return_false);
9520AST_Toplevel.DEFMETHOD("is_block_scope", return_false);
9521AST_SwitchBranch.DEFMETHOD("is_block_scope", return_false);
9522AST_Block.DEFMETHOD("is_block_scope", return_true);
9523AST_Scope.DEFMETHOD("is_block_scope", function () {
9524 return this._block_scope || false;
9525});
9526AST_IterationStatement.DEFMETHOD("is_block_scope", return_true);
9527
9528AST_Lambda.DEFMETHOD("init_scope_vars", function() {
9529 AST_Scope.prototype.init_scope_vars.apply(this, arguments);
9530 this.uses_arguments = false;
9531 this.def_variable(new AST_SymbolFunarg({
9532 name: "arguments",
9533 start: this.start,
9534 end: this.end
9535 }));
9536});
9537
9538AST_Arrow.DEFMETHOD("init_scope_vars", function() {
9539 AST_Scope.prototype.init_scope_vars.apply(this, arguments);
9540 this.uses_arguments = false;
9541});
9542
9543AST_Symbol.DEFMETHOD("mark_enclosed", function() {
9544 var def = this.definition();
9545 var s = this.scope;
9546 while (s) {
9547 push_uniq(s.enclosed, def);
9548 if (s === def.scope) break;
9549 s = s.parent_scope;
9550 }
9551});
9552
9553AST_Symbol.DEFMETHOD("reference", function() {
9554 this.definition().references.push(this);
9555 this.mark_enclosed();
9556});
9557
9558AST_Scope.DEFMETHOD("find_variable", function(name) {
9559 if (name instanceof AST_Symbol) name = name.name;
9560 return this.variables.get(name)
9561 || (this.parent_scope && this.parent_scope.find_variable(name));
9562});
9563
9564AST_Scope.DEFMETHOD("def_function", function(symbol, init) {
9565 var def = this.def_variable(symbol, init);
9566 if (!def.init || def.init instanceof AST_Defun) def.init = init;
9567 this.functions.set(symbol.name, def);
9568 return def;
9569});
9570
9571AST_Scope.DEFMETHOD("def_variable", function(symbol, init) {
9572 var def = this.variables.get(symbol.name);
9573 if (def) {
9574 def.orig.push(symbol);
9575 if (def.init && (def.scope !== symbol.scope || def.init instanceof AST_Function)) {
9576 def.init = init;
9577 }
9578 } else {
9579 def = new SymbolDef(this, symbol, init);
9580 this.variables.set(symbol.name, def);
9581 def.global = !this.parent_scope;
9582 }
9583 return symbol.thedef = def;
9584});
9585
9586function next_mangled(scope, options) {
9587 var ext = scope.enclosed;
9588 out: while (true) {
9589 var m = base54(++scope.cname);
9590 if (RESERVED_WORDS.has(m)) continue; // skip over "do"
9591
9592 // https://github.com/mishoo/UglifyJS2/issues/242 -- do not
9593 // shadow a name reserved from mangling.
9594 if (options.reserved.has(m)) continue;
9595
9596 // Functions with short names might collide with base54 output
9597 // and therefore cause collisions when keep_fnames is true.
9598 if (unmangleable_names && unmangleable_names.has(m)) continue out;
9599
9600 // we must ensure that the mangled name does not shadow a name
9601 // from some parent scope that is referenced in this or in
9602 // inner scopes.
9603 for (let i = ext.length; --i >= 0;) {
9604 const def = ext[i];
9605 const name = def.mangled_name || (def.unmangleable(options) && def.name);
9606 if (m == name) continue out;
9607 }
9608 return m;
9609 }
9610}
9611
9612AST_Scope.DEFMETHOD("next_mangled", function(options) {
9613 return next_mangled(this, options);
9614});
9615
9616AST_Toplevel.DEFMETHOD("next_mangled", function(options) {
9617 let name;
9618 const mangled_names = this.mangled_names;
9619 do {
9620 name = next_mangled(this, options);
9621 } while (mangled_names.has(name));
9622 return name;
9623});
9624
9625AST_Function.DEFMETHOD("next_mangled", function(options, def) {
9626 // #179, #326
9627 // in Safari strict mode, something like (function x(x){...}) is a syntax error;
9628 // a function expression's argument cannot shadow the function expression's name
9629
9630 var tricky_def = def.orig[0] instanceof AST_SymbolFunarg && this.name && this.name.definition();
9631
9632 // the function's mangled_name is null when keep_fnames is true
9633 var tricky_name = tricky_def ? tricky_def.mangled_name || tricky_def.name : null;
9634
9635 while (true) {
9636 var name = next_mangled(this, options);
9637 if (!tricky_name || tricky_name != name)
9638 return name;
9639 }
9640});
9641
9642AST_Symbol.DEFMETHOD("unmangleable", function(options) {
9643 var def = this.definition();
9644 return !def || def.unmangleable(options);
9645});
9646
9647// labels are always mangleable
9648AST_Label.DEFMETHOD("unmangleable", return_false);
9649
9650AST_Symbol.DEFMETHOD("unreferenced", function() {
9651 return !this.definition().references.length && !this.scope.pinned();
9652});
9653
9654AST_Symbol.DEFMETHOD("definition", function() {
9655 return this.thedef;
9656});
9657
9658AST_Symbol.DEFMETHOD("global", function() {
9659 return this.thedef.global;
9660});
9661
9662AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options) {
9663 options = defaults(options, {
9664 eval : false,
9665 ie8 : false,
9666 keep_classnames: false,
9667 keep_fnames : false,
9668 module : false,
9669 reserved : [],
9670 toplevel : false,
9671 });
9672 if (options.module) options.toplevel = true;
9673 if (!Array.isArray(options.reserved)
9674 && !(options.reserved instanceof Set)
9675 ) {
9676 options.reserved = [];
9677 }
9678 options.reserved = new Set(options.reserved);
9679 // Never mangle arguments
9680 options.reserved.add("arguments");
9681 return options;
9682});
9683
9684AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
9685 options = this._default_mangler_options(options);
9686
9687 // We only need to mangle declaration nodes. Special logic wired
9688 // into the code generator will display the mangled name if it's
9689 // present (and for AST_SymbolRef-s it'll use the mangled name of
9690 // the AST_SymbolDeclaration that it points to).
9691 var lname = -1;
9692 var to_mangle = [];
9693
9694 if (options.keep_fnames) {
9695 function_defs = new Set();
9696 }
9697
9698 const mangled_names = this.mangled_names = new Set();
9699 if (options.cache) {
9700 this.globals.forEach(collect);
9701 if (options.cache.props) {
9702 options.cache.props.forEach(function(mangled_name) {
9703 mangled_names.add(mangled_name);
9704 });
9705 }
9706 }
9707
9708 var tw = new TreeWalker(function(node, descend) {
9709 if (node instanceof AST_LabeledStatement) {
9710 // lname is incremented when we get to the AST_Label
9711 var save_nesting = lname;
9712 descend();
9713 lname = save_nesting;
9714 return true; // don't descend again in TreeWalker
9715 }
9716 if (node instanceof AST_Scope) {
9717 node.variables.forEach(collect);
9718 return;
9719 }
9720 if (node.is_block_scope()) {
9721 node.block_scope.variables.forEach(collect);
9722 return;
9723 }
9724 if (
9725 function_defs
9726 && node instanceof AST_VarDef
9727 && node.value instanceof AST_Lambda
9728 && !node.value.name
9729 && keep_name(options.keep_fnames, node.name.name)
9730 ) {
9731 function_defs.add(node.name.definition().id);
9732 return;
9733 }
9734 if (node instanceof AST_Label) {
9735 let name;
9736 do {
9737 name = base54(++lname);
9738 } while (RESERVED_WORDS.has(name));
9739 node.mangled_name = name;
9740 return true;
9741 }
9742 if (!(options.ie8 || options.safari10) && node instanceof AST_SymbolCatch) {
9743 to_mangle.push(node.definition());
9744 return;
9745 }
9746 });
9747
9748 this.walk(tw);
9749
9750 if (options.keep_fnames || options.keep_classnames) {
9751 unmangleable_names = new Set();
9752 // Collect a set of short names which are unmangleable,
9753 // for use in avoiding collisions in next_mangled.
9754 to_mangle.forEach(def => {
9755 if (def.name.length < 6 && def.unmangleable(options)) {
9756 unmangleable_names.add(def.name);
9757 }
9758 });
9759 }
9760
9761 to_mangle.forEach(def => { def.mangle(options); });
9762
9763 function_defs = null;
9764 unmangleable_names = null;
9765
9766 function collect(symbol) {
9767 const should_mangle = !options.reserved.has(symbol.name)
9768 && !(symbol.export & MASK_EXPORT_DONT_MANGLE);
9769 if (should_mangle) {
9770 to_mangle.push(symbol);
9771 }
9772 }
9773});
9774
9775AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
9776 const cache = options.cache && options.cache.props;
9777 const avoid = new Set();
9778 options.reserved.forEach(to_avoid);
9779 this.globals.forEach(add_def);
9780 this.walk(new TreeWalker(function(node) {
9781 if (node instanceof AST_Scope) node.variables.forEach(add_def);
9782 if (node instanceof AST_SymbolCatch) add_def(node.definition());
9783 }));
9784 return avoid;
9785
9786 function to_avoid(name) {
9787 avoid.add(name);
9788 }
9789
9790 function add_def(def) {
9791 var name = def.name;
9792 if (def.global && cache && cache.has(name)) name = cache.get(name);
9793 else if (!def.unmangleable(options)) return;
9794 to_avoid(name);
9795 }
9796});
9797
9798AST_Toplevel.DEFMETHOD("expand_names", function(options) {
9799 base54.reset();
9800 base54.sort();
9801 options = this._default_mangler_options(options);
9802 var avoid = this.find_colliding_names(options);
9803 var cname = 0;
9804 this.globals.forEach(rename);
9805 this.walk(new TreeWalker(function(node) {
9806 if (node instanceof AST_Scope) node.variables.forEach(rename);
9807 if (node instanceof AST_SymbolCatch) rename(node.definition());
9808 }));
9809
9810 function next_name() {
9811 var name;
9812 do {
9813 name = base54(cname++);
9814 } while (avoid.has(name) || RESERVED_WORDS.has(name));
9815 return name;
9816 }
9817
9818 function rename(def) {
9819 if (def.global && options.cache) return;
9820 if (def.unmangleable(options)) return;
9821 if (options.reserved.has(def.name)) return;
9822 const redefinition = redefined_catch_def(def);
9823 const name = def.name = redefinition ? redefinition.name : next_name();
9824 def.orig.forEach(function(sym) {
9825 sym.name = name;
9826 });
9827 def.references.forEach(function(sym) {
9828 sym.name = name;
9829 });
9830 }
9831});
9832
9833AST_Node.DEFMETHOD("tail_node", return_this);
9834AST_Sequence.DEFMETHOD("tail_node", function() {
9835 return this.expressions[this.expressions.length - 1];
9836});
9837
9838AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options) {
9839 options = this._default_mangler_options(options);
9840 try {
9841 AST_Node.prototype.print = function(stream, force_parens) {
9842 this._print(stream, force_parens);
9843 if (this instanceof AST_Symbol && !this.unmangleable(options)) {
9844 base54.consider(this.name, -1);
9845 } else if (options.properties) {
9846 if (this instanceof AST_Dot) {
9847 base54.consider(this.property, -1);
9848 } else if (this instanceof AST_Sub) {
9849 skip_string(this.property);
9850 }
9851 }
9852 };
9853 base54.consider(this.print_to_string(), 1);
9854 } finally {
9855 AST_Node.prototype.print = AST_Node.prototype._print;
9856 }
9857 base54.sort();
9858
9859 function skip_string(node) {
9860 if (node instanceof AST_String) {
9861 base54.consider(node.value, -1);
9862 } else if (node instanceof AST_Conditional) {
9863 skip_string(node.consequent);
9864 skip_string(node.alternative);
9865 } else if (node instanceof AST_Sequence) {
9866 skip_string(node.tail_node());
9867 }
9868 }
9869});
9870
9871const base54 = (() => {
9872 const leading = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_".split("");
9873 const digits = "0123456789".split("");
9874 let chars;
9875 let frequency;
9876 function reset() {
9877 frequency = new Map();
9878 leading.forEach(function(ch) {
9879 frequency.set(ch, 0);
9880 });
9881 digits.forEach(function(ch) {
9882 frequency.set(ch, 0);
9883 });
9884 }
9885 base54.consider = function(str, delta) {
9886 for (var i = str.length; --i >= 0;) {
9887 frequency.set(str[i], frequency.get(str[i]) + delta);
9888 }
9889 };
9890 function compare(a, b) {
9891 return frequency.get(b) - frequency.get(a);
9892 }
9893 base54.sort = function() {
9894 chars = mergeSort(leading, compare).concat(mergeSort(digits, compare));
9895 };
9896 base54.reset = reset;
9897 reset();
9898 function base54(num) {
9899 var ret = "", base = 54;
9900 num++;
9901 do {
9902 num--;
9903 ret += chars[num % base];
9904 num = Math.floor(num / base);
9905 base = 64;
9906 } while (num > 0);
9907 return ret;
9908 }
9909 return base54;
9910})();
9911
9912let mangle_options = undefined;
9913AST_Node.prototype.size = function (compressor, stack) {
9914 mangle_options = compressor && compressor.mangle_options;
9915
9916 let size = 0;
9917 walk_parent(this, (node, info) => {
9918 size += node._size(info);
9919 }, stack || (compressor && compressor.stack));
9920
9921 // just to save a bit of memory
9922 mangle_options = undefined;
9923
9924 return size;
9925};
9926
9927AST_Node.prototype._size = () => 0;
9928
9929AST_Debugger.prototype._size = () => 8;
9930
9931AST_Directive.prototype._size = function () {
9932 // TODO string encoding stuff
9933 return 2 + this.value.length;
9934};
9935
9936const list_overhead = (array) => array.length && array.length - 1;
9937
9938AST_Block.prototype._size = function () {
9939 return 2 + list_overhead(this.body);
9940};
9941
9942AST_Toplevel.prototype._size = function() {
9943 return list_overhead(this.body);
9944};
9945
9946AST_EmptyStatement.prototype._size = () => 1;
9947
9948AST_LabeledStatement.prototype._size = () => 2; // x:
9949
9950AST_Do.prototype._size = () => 9;
9951
9952AST_While.prototype._size = () => 7;
9953
9954AST_For.prototype._size = () => 8;
9955
9956AST_ForIn.prototype._size = () => 8;
9957// AST_ForOf inherits ^
9958
9959AST_With.prototype._size = () => 6;
9960
9961AST_Expansion.prototype._size = () => 3;
9962
9963/*#__INLINE__*/
9964const lambda_modifiers = func =>
9965 (func.is_generator ? 1 : 0) + (func.async ? 6 : 0);
9966
9967AST_Accessor.prototype._size = function () {
9968 return lambda_modifiers(this) + 4 + list_overhead(this.argnames) + list_overhead(this.body);
9969};
9970
9971AST_Function.prototype._size = function (info) {
9972 const first = !!first_in_statement(info);
9973 return (first * 2) + lambda_modifiers(this) + 12 + list_overhead(this.argnames) + list_overhead(this.body);
9974};
9975
9976AST_Defun.prototype._size = function () {
9977 return lambda_modifiers(this) + 13 + list_overhead(this.argnames) + list_overhead(this.body);
9978};
9979
9980AST_Arrow.prototype._size = function () {
9981 let args_and_arrow = 2 + list_overhead(this.argnames);
9982
9983 if (
9984 !(
9985 this.argnames.length === 1
9986 && this.argnames[0] instanceof AST_Symbol
9987 )
9988 ) {
9989 args_and_arrow += 2;
9990 }
9991
9992 return lambda_modifiers(this) + args_and_arrow + (Array.isArray(this.body) ? list_overhead(this.body) : this.body._size());
9993};
9994
9995AST_Destructuring.prototype._size = () => 2;
9996
9997AST_TemplateString.prototype._size = function () {
9998 return 2 + (Math.floor(this.segments.length / 2) * 3); /* "${}" */
9999};
10000
10001AST_TemplateSegment.prototype._size = function () {
10002 return this.value.length;
10003};
10004
10005AST_Return.prototype._size = function () {
10006 return this.value ? 7 : 6;
10007};
10008
10009AST_Throw.prototype._size = () => 6;
10010
10011AST_Break.prototype._size = function () {
10012 return this.label ? 6 : 5;
10013};
10014
10015AST_Continue.prototype._size = function () {
10016 return this.label ? 9 : 8;
10017};
10018
10019AST_If.prototype._size = () => 4;
10020
10021AST_Switch.prototype._size = function () {
10022 return 8 + list_overhead(this.body);
10023};
10024
10025AST_Case.prototype._size = function () {
10026 return 5 + list_overhead(this.body);
10027};
10028
10029AST_Default.prototype._size = function () {
10030 return 8 + list_overhead(this.body);
10031};
10032
10033AST_Try.prototype._size = function () {
10034 return 3 + list_overhead(this.body);
10035};
10036
10037AST_Catch.prototype._size = function () {
10038 let size = 7 + list_overhead(this.body);
10039 if (this.argname) {
10040 size += 2;
10041 }
10042 return size;
10043};
10044
10045AST_Finally.prototype._size = function () {
10046 return 7 + list_overhead(this.body);
10047};
10048
10049/*#__INLINE__*/
10050const def_size = (size, def) => size + list_overhead(def.definitions);
10051
10052AST_Var.prototype._size = function () {
10053 return def_size(4, this);
10054};
10055
10056AST_Let.prototype._size = function () {
10057 return def_size(4, this);
10058};
10059
10060AST_Const.prototype._size = function () {
10061 return def_size(6, this);
10062};
10063
10064AST_VarDef.prototype._size = function () {
10065 return this.value ? 1 : 0;
10066};
10067
10068AST_NameMapping.prototype._size = function () {
10069 // foreign name isn't mangled
10070 return this.name ? 4 : 0;
10071};
10072
10073AST_Import.prototype._size = function () {
10074 // import
10075 let size = 6;
10076
10077 if (this.imported_name) size += 1;
10078
10079 // from
10080 if (this.imported_name || this.imported_names) size += 5;
10081
10082 // braces, and the commas
10083 if (this.imported_names) {
10084 size += 2 + list_overhead(this.imported_names);
10085 }
10086
10087 return size;
10088};
10089
10090AST_ImportMeta.prototype._size = () => 11;
10091
10092AST_Export.prototype._size = function () {
10093 let size = 7 + (this.is_default ? 8 : 0);
10094
10095 if (this.exported_value) {
10096 size += this.exported_value._size();
10097 }
10098
10099 if (this.exported_names) {
10100 // Braces and commas
10101 size += 2 + list_overhead(this.exported_names);
10102 }
10103
10104 if (this.module_name) {
10105 // "from "
10106 size += 5;
10107 }
10108
10109 return size;
10110};
10111
10112AST_Call.prototype._size = function () {
10113 if (this.optional) {
10114 return 4 + list_overhead(this.args);
10115 }
10116 return 2 + list_overhead(this.args);
10117};
10118
10119AST_New.prototype._size = function () {
10120 return 6 + list_overhead(this.args);
10121};
10122
10123AST_Sequence.prototype._size = function () {
10124 return list_overhead(this.expressions);
10125};
10126
10127AST_Dot.prototype._size = function () {
10128 if (this.optional) {
10129 return this.property.length + 2;
10130 }
10131 return this.property.length + 1;
10132};
10133
10134AST_Sub.prototype._size = function () {
10135 return this.optional ? 4 : 2;
10136};
10137
10138AST_Unary.prototype._size = function () {
10139 if (this.operator === "typeof") return 7;
10140 if (this.operator === "void") return 5;
10141 return this.operator.length;
10142};
10143
10144AST_Binary.prototype._size = function (info) {
10145 if (this.operator === "in") return 4;
10146
10147 let size = this.operator.length;
10148
10149 if (
10150 (this.operator === "+" || this.operator === "-")
10151 && this.right instanceof AST_Unary && this.right.operator === this.operator
10152 ) {
10153 // 1+ +a > needs space between the +
10154 size += 1;
10155 }
10156
10157 if (this.needs_parens(info)) {
10158 size += 2;
10159 }
10160
10161 return size;
10162};
10163
10164AST_Conditional.prototype._size = () => 3;
10165
10166AST_Array.prototype._size = function () {
10167 return 2 + list_overhead(this.elements);
10168};
10169
10170AST_Object.prototype._size = function (info) {
10171 let base = 2;
10172 if (first_in_statement(info)) {
10173 base += 2; // parens
10174 }
10175 return base + list_overhead(this.properties);
10176};
10177
10178/*#__INLINE__*/
10179const key_size = key =>
10180 typeof key === "string" ? key.length : 0;
10181
10182AST_ObjectKeyVal.prototype._size = function () {
10183 return key_size(this.key) + 1;
10184};
10185
10186/*#__INLINE__*/
10187const static_size = is_static => is_static ? 7 : 0;
10188
10189AST_ObjectGetter.prototype._size = function () {
10190 return 5 + static_size(this.static) + key_size(this.key);
10191};
10192
10193AST_ObjectSetter.prototype._size = function () {
10194 return 5 + static_size(this.static) + key_size(this.key);
10195};
10196
10197AST_ConciseMethod.prototype._size = function () {
10198 return static_size(this.static) + key_size(this.key) + lambda_modifiers(this);
10199};
10200
10201AST_Class.prototype._size = function () {
10202 return (
10203 (this.name ? 8 : 7)
10204 + (this.extends ? 8 : 0)
10205 );
10206};
10207
10208AST_ClassProperty.prototype._size = function () {
10209 return (
10210 static_size(this.static)
10211 + (typeof this.key === "string" ? this.key.length + 2 : 0)
10212 + (this.value ? 1 : 0)
10213 );
10214};
10215
10216AST_Symbol.prototype._size = function () {
10217 return !mangle_options || this.definition().unmangleable(mangle_options)
10218 ? this.name.length
10219 : 1;
10220};
10221
10222// TODO take propmangle into account
10223AST_SymbolClassProperty.prototype._size = function () {
10224 return this.name.length;
10225};
10226
10227AST_SymbolRef.prototype._size = AST_SymbolDeclaration.prototype._size = function () {
10228 const { name, thedef } = this;
10229
10230 if (thedef && thedef.global) return name.length;
10231
10232 if (name === "arguments") return 9;
10233
10234 return AST_Symbol.prototype._size.call(this);
10235};
10236
10237AST_NewTarget.prototype._size = () => 10;
10238
10239AST_SymbolImportForeign.prototype._size = function () {
10240 return this.name.length;
10241};
10242
10243AST_SymbolExportForeign.prototype._size = function () {
10244 return this.name.length;
10245};
10246
10247AST_This.prototype._size = () => 4;
10248
10249AST_Super.prototype._size = () => 5;
10250
10251AST_String.prototype._size = function () {
10252 return this.value.length + 2;
10253};
10254
10255AST_Number.prototype._size = function () {
10256 const { value } = this;
10257 if (value === 0) return 1;
10258 if (value > 0 && Math.floor(value) === value) {
10259 return Math.floor(Math.log10(value) + 1);
10260 }
10261 return value.toString().length;
10262};
10263
10264AST_BigInt.prototype._size = function () {
10265 return this.value.length;
10266};
10267
10268AST_RegExp.prototype._size = function () {
10269 return this.value.toString().length;
10270};
10271
10272AST_Null.prototype._size = () => 4;
10273
10274AST_NaN.prototype._size = () => 3;
10275
10276AST_Undefined.prototype._size = () => 6; // "void 0"
10277
10278AST_Hole.prototype._size = () => 0; // comma is taken into account
10279
10280AST_Infinity.prototype._size = () => 8;
10281
10282AST_True.prototype._size = () => 4;
10283
10284AST_False.prototype._size = () => 5;
10285
10286AST_Await.prototype._size = () => 6;
10287
10288AST_Yield.prototype._size = () => 6;
10289
10290/***********************************************************************
10291
10292 A JavaScript tokenizer / parser / beautifier / compressor.
10293 https://github.com/mishoo/UglifyJS2
10294
10295 -------------------------------- (C) ---------------------------------
10296
10297 Author: Mihai Bazon
10298 <mihai.bazon@gmail.com>
10299 http://mihai.bazon.net/blog
10300
10301 Distributed under the BSD license:
10302
10303 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
10304
10305 Redistribution and use in source and binary forms, with or without
10306 modification, are permitted provided that the following conditions
10307 are met:
10308
10309 * Redistributions of source code must retain the above
10310 copyright notice, this list of conditions and the following
10311 disclaimer.
10312
10313 * Redistributions in binary form must reproduce the above
10314 copyright notice, this list of conditions and the following
10315 disclaimer in the documentation and/or other materials
10316 provided with the distribution.
10317
10318 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
10319 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
10320 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
10321 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
10322 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
10323 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
10324 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
10325 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
10326 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
10327 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
10328 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
10329 SUCH DAMAGE.
10330
10331 ***********************************************************************/
10332
10333const UNUSED = 0b00000001;
10334const TRUTHY = 0b00000010;
10335const FALSY = 0b00000100;
10336const UNDEFINED = 0b00001000;
10337const INLINED = 0b00010000;
10338// Nodes to which values are ever written. Used when keep_assign is part of the unused option string.
10339const WRITE_ONLY= 0b00100000;
10340
10341// information specific to a single compression pass
10342const SQUEEZED = 0b0000000100000000;
10343const OPTIMIZED = 0b0000001000000000;
10344const TOP = 0b0000010000000000;
10345
10346const CLEAR_BETWEEN_PASSES = SQUEEZED | OPTIMIZED | TOP;
10347
10348/*@__INLINE__*/
10349const has_flag = (node, flag) => node.flags & flag;
10350/*@__INLINE__*/
10351const set_flag = (node, flag) => { node.flags |= flag; };
10352/*@__INLINE__*/
10353const clear_flag = (node, flag) => { node.flags &= ~flag; };
10354
10355class Compressor extends TreeWalker {
10356 constructor(options, { false_by_default = false, mangle_options = false }) {
10357 super();
10358 if (options.defaults !== undefined && !options.defaults) false_by_default = true;
10359 this.options = defaults(options, {
10360 arguments : false,
10361 arrows : !false_by_default,
10362 booleans : !false_by_default,
10363 booleans_as_integers : false,
10364 collapse_vars : !false_by_default,
10365 comparisons : !false_by_default,
10366 computed_props: !false_by_default,
10367 conditionals : !false_by_default,
10368 dead_code : !false_by_default,
10369 defaults : true,
10370 directives : !false_by_default,
10371 drop_console : false,
10372 drop_debugger : !false_by_default,
10373 ecma : 5,
10374 evaluate : !false_by_default,
10375 expression : false,
10376 global_defs : false,
10377 hoist_funs : false,
10378 hoist_props : !false_by_default,
10379 hoist_vars : false,
10380 ie8 : false,
10381 if_return : !false_by_default,
10382 inline : !false_by_default,
10383 join_vars : !false_by_default,
10384 keep_classnames: false,
10385 keep_fargs : true,
10386 keep_fnames : false,
10387 keep_infinity : false,
10388 loops : !false_by_default,
10389 module : false,
10390 negate_iife : !false_by_default,
10391 passes : 1,
10392 properties : !false_by_default,
10393 pure_getters : !false_by_default && "strict",
10394 pure_funcs : null,
10395 reduce_funcs : null, // legacy
10396 reduce_vars : !false_by_default,
10397 sequences : !false_by_default,
10398 side_effects : !false_by_default,
10399 switches : !false_by_default,
10400 top_retain : null,
10401 toplevel : !!(options && options["top_retain"]),
10402 typeofs : !false_by_default,
10403 unsafe : false,
10404 unsafe_arrows : false,
10405 unsafe_comps : false,
10406 unsafe_Function: false,
10407 unsafe_math : false,
10408 unsafe_symbols: false,
10409 unsafe_methods: false,
10410 unsafe_proto : false,
10411 unsafe_regexp : false,
10412 unsafe_undefined: false,
10413 unused : !false_by_default,
10414 warnings : false // legacy
10415 }, true);
10416 var global_defs = this.options["global_defs"];
10417 if (typeof global_defs == "object") for (var key in global_defs) {
10418 if (key[0] === "@" && HOP(global_defs, key)) {
10419 global_defs[key.slice(1)] = parse(global_defs[key], {
10420 expression: true
10421 });
10422 }
10423 }
10424 if (this.options["inline"] === true) this.options["inline"] = 3;
10425 var pure_funcs = this.options["pure_funcs"];
10426 if (typeof pure_funcs == "function") {
10427 this.pure_funcs = pure_funcs;
10428 } else {
10429 this.pure_funcs = pure_funcs ? function(node) {
10430 return !pure_funcs.includes(node.expression.print_to_string());
10431 } : return_true;
10432 }
10433 var top_retain = this.options["top_retain"];
10434 if (top_retain instanceof RegExp) {
10435 this.top_retain = function(def) {
10436 return top_retain.test(def.name);
10437 };
10438 } else if (typeof top_retain == "function") {
10439 this.top_retain = top_retain;
10440 } else if (top_retain) {
10441 if (typeof top_retain == "string") {
10442 top_retain = top_retain.split(/,/);
10443 }
10444 this.top_retain = function(def) {
10445 return top_retain.includes(def.name);
10446 };
10447 }
10448 if (this.options["module"]) {
10449 this.directives["use strict"] = true;
10450 this.options["toplevel"] = true;
10451 }
10452 var toplevel = this.options["toplevel"];
10453 this.toplevel = typeof toplevel == "string" ? {
10454 funcs: /funcs/.test(toplevel),
10455 vars: /vars/.test(toplevel)
10456 } : {
10457 funcs: toplevel,
10458 vars: toplevel
10459 };
10460 var sequences = this.options["sequences"];
10461 this.sequences_limit = sequences == 1 ? 800 : sequences | 0;
10462 this.evaluated_regexps = new Map();
10463 this._toplevel = undefined;
10464 this.mangle_options = mangle_options;
10465 }
10466
10467 option(key) {
10468 return this.options[key];
10469 }
10470
10471 exposed(def) {
10472 if (def.export) return true;
10473 if (def.global) for (var i = 0, len = def.orig.length; i < len; i++)
10474 if (!this.toplevel[def.orig[i] instanceof AST_SymbolDefun ? "funcs" : "vars"])
10475 return true;
10476 return false;
10477 }
10478
10479 in_boolean_context() {
10480 if (!this.option("booleans")) return false;
10481 var self = this.self();
10482 for (var i = 0, p; p = this.parent(i); i++) {
10483 if (p instanceof AST_SimpleStatement
10484 || p instanceof AST_Conditional && p.condition === self
10485 || p instanceof AST_DWLoop && p.condition === self
10486 || p instanceof AST_For && p.condition === self
10487 || p instanceof AST_If && p.condition === self
10488 || p instanceof AST_UnaryPrefix && p.operator == "!" && p.expression === self) {
10489 return true;
10490 }
10491 if (
10492 p instanceof AST_Binary
10493 && (
10494 p.operator == "&&"
10495 || p.operator == "||"
10496 || p.operator == "??"
10497 )
10498 || p instanceof AST_Conditional
10499 || p.tail_node() === self
10500 ) {
10501 self = p;
10502 } else {
10503 return false;
10504 }
10505 }
10506 }
10507
10508 get_toplevel() {
10509 return this._toplevel;
10510 }
10511
10512 compress(toplevel) {
10513 toplevel = toplevel.resolve_defines(this);
10514 this._toplevel = toplevel;
10515 if (this.option("expression")) {
10516 this._toplevel.process_expression(true);
10517 }
10518 var passes = +this.options.passes || 1;
10519 var min_count = 1 / 0;
10520 var stopping = false;
10521 var mangle = { ie8: this.option("ie8") };
10522 for (var pass = 0; pass < passes; pass++) {
10523 this._toplevel.figure_out_scope(mangle);
10524 if (pass === 0 && this.option("drop_console")) {
10525 // must be run before reduce_vars and compress pass
10526 this._toplevel = this._toplevel.drop_console();
10527 }
10528 if (pass > 0 || this.option("reduce_vars")) {
10529 this._toplevel.reset_opt_flags(this);
10530 }
10531 this._toplevel = this._toplevel.transform(this);
10532 if (passes > 1) {
10533 let count = 0;
10534 walk(this._toplevel, () => { count++; });
10535 if (count < min_count) {
10536 min_count = count;
10537 stopping = false;
10538 } else if (stopping) {
10539 break;
10540 } else {
10541 stopping = true;
10542 }
10543 }
10544 }
10545 if (this.option("expression")) {
10546 this._toplevel.process_expression(false);
10547 }
10548 toplevel = this._toplevel;
10549 this._toplevel = undefined;
10550 return toplevel;
10551 }
10552
10553 before(node, descend) {
10554 if (has_flag(node, SQUEEZED)) return node;
10555 var was_scope = false;
10556 if (node instanceof AST_Scope) {
10557 node = node.hoist_properties(this);
10558 node = node.hoist_declarations(this);
10559 was_scope = true;
10560 }
10561 // Before https://github.com/mishoo/UglifyJS2/pull/1602 AST_Node.optimize()
10562 // would call AST_Node.transform() if a different instance of AST_Node is
10563 // produced after def_optimize().
10564 // This corrupts TreeWalker.stack, which cause AST look-ups to malfunction.
10565 // Migrate and defer all children's AST_Node.transform() to below, which
10566 // will now happen after this parent AST_Node has been properly substituted
10567 // thus gives a consistent AST snapshot.
10568 descend(node, this);
10569 // Existing code relies on how AST_Node.optimize() worked, and omitting the
10570 // following replacement call would result in degraded efficiency of both
10571 // output and performance.
10572 descend(node, this);
10573 var opt = node.optimize(this);
10574 if (was_scope && opt instanceof AST_Scope) {
10575 opt.drop_unused(this);
10576 descend(opt, this);
10577 }
10578 if (opt === node) set_flag(opt, SQUEEZED);
10579 return opt;
10580 }
10581}
10582
10583function def_optimize(node, optimizer) {
10584 node.DEFMETHOD("optimize", function(compressor) {
10585 var self = this;
10586 if (has_flag(self, OPTIMIZED)) return self;
10587 if (compressor.has_directive("use asm")) return self;
10588 var opt = optimizer(self, compressor);
10589 set_flag(opt, OPTIMIZED);
10590 return opt;
10591 });
10592}
10593
10594def_optimize(AST_Node, function(self) {
10595 return self;
10596});
10597
10598AST_Toplevel.DEFMETHOD("drop_console", function() {
10599 return this.transform(new TreeTransformer(function(self) {
10600 if (self.TYPE == "Call") {
10601 var exp = self.expression;
10602 if (exp instanceof AST_PropAccess) {
10603 var name = exp.expression;
10604 while (name.expression) {
10605 name = name.expression;
10606 }
10607 if (is_undeclared_ref(name) && name.name == "console") {
10608 return make_node(AST_Undefined, self);
10609 }
10610 }
10611 }
10612 }));
10613});
10614
10615AST_Node.DEFMETHOD("equivalent_to", function(node) {
10616 return equivalent_to(this, node);
10617});
10618
10619AST_Scope.DEFMETHOD("process_expression", function(insert, compressor) {
10620 var self = this;
10621 var tt = new TreeTransformer(function(node) {
10622 if (insert && node instanceof AST_SimpleStatement) {
10623 return make_node(AST_Return, node, {
10624 value: node.body
10625 });
10626 }
10627 if (!insert && node instanceof AST_Return) {
10628 if (compressor) {
10629 var value = node.value && node.value.drop_side_effect_free(compressor, true);
10630 return value ? make_node(AST_SimpleStatement, node, {
10631 body: value
10632 }) : make_node(AST_EmptyStatement, node);
10633 }
10634 return make_node(AST_SimpleStatement, node, {
10635 body: node.value || make_node(AST_UnaryPrefix, node, {
10636 operator: "void",
10637 expression: make_node(AST_Number, node, {
10638 value: 0
10639 })
10640 })
10641 });
10642 }
10643 if (node instanceof AST_Class || node instanceof AST_Lambda && node !== self) {
10644 return node;
10645 }
10646 if (node instanceof AST_Block) {
10647 var index = node.body.length - 1;
10648 if (index >= 0) {
10649 node.body[index] = node.body[index].transform(tt);
10650 }
10651 } else if (node instanceof AST_If) {
10652 node.body = node.body.transform(tt);
10653 if (node.alternative) {
10654 node.alternative = node.alternative.transform(tt);
10655 }
10656 } else if (node instanceof AST_With) {
10657 node.body = node.body.transform(tt);
10658 }
10659 return node;
10660 });
10661 self.transform(tt);
10662});
10663
10664function read_property(obj, key) {
10665 key = get_value(key);
10666 if (key instanceof AST_Node) return;
10667 var value;
10668 if (obj instanceof AST_Array) {
10669 var elements = obj.elements;
10670 if (key == "length") return make_node_from_constant(elements.length, obj);
10671 if (typeof key == "number" && key in elements) value = elements[key];
10672 } else if (obj instanceof AST_Object) {
10673 key = "" + key;
10674 var props = obj.properties;
10675 for (var i = props.length; --i >= 0;) {
10676 var prop = props[i];
10677 if (!(prop instanceof AST_ObjectKeyVal)) return;
10678 if (!value && props[i].key === key) value = props[i].value;
10679 }
10680 }
10681 return value instanceof AST_SymbolRef && value.fixed_value() || value;
10682}
10683
10684function is_modified(compressor, tw, node, value, level, immutable) {
10685 var parent = tw.parent(level);
10686 var lhs = is_lhs(node, parent);
10687 if (lhs) return lhs;
10688 if (!immutable
10689 && parent instanceof AST_Call
10690 && parent.expression === node
10691 && !(value instanceof AST_Arrow)
10692 && !(value instanceof AST_Class)
10693 && !parent.is_expr_pure(compressor)
10694 && (!(value instanceof AST_Function)
10695 || !(parent instanceof AST_New) && value.contains_this())) {
10696 return true;
10697 }
10698 if (parent instanceof AST_Array) {
10699 return is_modified(compressor, tw, parent, parent, level + 1);
10700 }
10701 if (parent instanceof AST_ObjectKeyVal && node === parent.value) {
10702 var obj = tw.parent(level + 1);
10703 return is_modified(compressor, tw, obj, obj, level + 2);
10704 }
10705 if (parent instanceof AST_PropAccess && parent.expression === node) {
10706 var prop = read_property(value, parent.property);
10707 return !immutable && is_modified(compressor, tw, parent, prop, level + 1);
10708 }
10709}
10710
10711(function(def_reduce_vars) {
10712 def_reduce_vars(AST_Node, noop);
10713
10714 function reset_def(compressor, def) {
10715 def.assignments = 0;
10716 def.chained = false;
10717 def.direct_access = false;
10718 def.escaped = 0;
10719 def.recursive_refs = 0;
10720 def.references = [];
10721 def.single_use = undefined;
10722 if (def.scope.pinned()) {
10723 def.fixed = false;
10724 } else if (def.orig[0] instanceof AST_SymbolConst || !compressor.exposed(def)) {
10725 def.fixed = def.init;
10726 } else {
10727 def.fixed = false;
10728 }
10729 }
10730
10731 function reset_variables(tw, compressor, node) {
10732 node.variables.forEach(function(def) {
10733 reset_def(compressor, def);
10734 if (def.fixed === null) {
10735 tw.defs_to_safe_ids.set(def.id, tw.safe_ids);
10736 mark(tw, def, true);
10737 } else if (def.fixed) {
10738 tw.loop_ids.set(def.id, tw.in_loop);
10739 mark(tw, def, true);
10740 }
10741 });
10742 }
10743
10744 function reset_block_variables(compressor, node) {
10745 if (node.block_scope) node.block_scope.variables.forEach((def) => {
10746 reset_def(compressor, def);
10747 });
10748 }
10749
10750 function push(tw) {
10751 tw.safe_ids = Object.create(tw.safe_ids);
10752 }
10753
10754 function pop(tw) {
10755 tw.safe_ids = Object.getPrototypeOf(tw.safe_ids);
10756 }
10757
10758 function mark(tw, def, safe) {
10759 tw.safe_ids[def.id] = safe;
10760 }
10761
10762 function safe_to_read(tw, def) {
10763 if (def.single_use == "m") return false;
10764 if (tw.safe_ids[def.id]) {
10765 if (def.fixed == null) {
10766 var orig = def.orig[0];
10767 if (orig instanceof AST_SymbolFunarg || orig.name == "arguments") return false;
10768 def.fixed = make_node(AST_Undefined, orig);
10769 }
10770 return true;
10771 }
10772 return def.fixed instanceof AST_Defun;
10773 }
10774
10775 function safe_to_assign(tw, def, scope, value) {
10776 if (def.fixed === undefined) return true;
10777 let def_safe_ids;
10778 if (def.fixed === null
10779 && (def_safe_ids = tw.defs_to_safe_ids.get(def.id))
10780 ) {
10781 def_safe_ids[def.id] = false;
10782 tw.defs_to_safe_ids.delete(def.id);
10783 return true;
10784 }
10785 if (!HOP(tw.safe_ids, def.id)) return false;
10786 if (!safe_to_read(tw, def)) return false;
10787 if (def.fixed === false) return false;
10788 if (def.fixed != null && (!value || def.references.length > def.assignments)) return false;
10789 if (def.fixed instanceof AST_Defun) {
10790 return value instanceof AST_Node && def.fixed.parent_scope === scope;
10791 }
10792 return def.orig.every((sym) => {
10793 return !(sym instanceof AST_SymbolConst
10794 || sym instanceof AST_SymbolDefun
10795 || sym instanceof AST_SymbolLambda);
10796 });
10797 }
10798
10799 function ref_once(tw, compressor, def) {
10800 return compressor.option("unused")
10801 && !def.scope.pinned()
10802 && def.references.length - def.recursive_refs == 1
10803 && tw.loop_ids.get(def.id) === tw.in_loop;
10804 }
10805
10806 function is_immutable(value) {
10807 if (!value) return false;
10808 return value.is_constant()
10809 || value instanceof AST_Lambda
10810 || value instanceof AST_This;
10811 }
10812
10813 function mark_escaped(tw, d, scope, node, value, level, depth) {
10814 var parent = tw.parent(level);
10815 if (value) {
10816 if (value.is_constant()) return;
10817 if (value instanceof AST_ClassExpression) return;
10818 }
10819 if (parent instanceof AST_Assign && parent.operator == "=" && node === parent.right
10820 || parent instanceof AST_Call && (node !== parent.expression || parent instanceof AST_New)
10821 || parent instanceof AST_Exit && node === parent.value && node.scope !== d.scope
10822 || parent instanceof AST_VarDef && node === parent.value
10823 || parent instanceof AST_Yield && node === parent.value && node.scope !== d.scope) {
10824 if (depth > 1 && !(value && value.is_constant_expression(scope))) depth = 1;
10825 if (!d.escaped || d.escaped > depth) d.escaped = depth;
10826 return;
10827 } else if (parent instanceof AST_Array
10828 || parent instanceof AST_Await
10829 || parent instanceof AST_Binary && lazy_op.has(parent.operator)
10830 || parent instanceof AST_Conditional && node !== parent.condition
10831 || parent instanceof AST_Expansion
10832 || parent instanceof AST_Sequence && node === parent.tail_node()) {
10833 mark_escaped(tw, d, scope, parent, parent, level + 1, depth);
10834 } else if (parent instanceof AST_ObjectKeyVal && node === parent.value) {
10835 var obj = tw.parent(level + 1);
10836 mark_escaped(tw, d, scope, obj, obj, level + 2, depth);
10837 } else if (parent instanceof AST_PropAccess && node === parent.expression) {
10838 value = read_property(value, parent.property);
10839 mark_escaped(tw, d, scope, parent, value, level + 1, depth + 1);
10840 if (value) return;
10841 }
10842 if (level > 0) return;
10843 if (parent instanceof AST_Sequence && node !== parent.tail_node()) return;
10844 if (parent instanceof AST_SimpleStatement) return;
10845 d.direct_access = true;
10846 }
10847
10848 const suppress = node => walk(node, node => {
10849 if (!(node instanceof AST_Symbol)) return;
10850 var d = node.definition();
10851 if (!d) return;
10852 if (node instanceof AST_SymbolRef) d.references.push(node);
10853 d.fixed = false;
10854 });
10855 def_reduce_vars(AST_Accessor, function(tw, descend, compressor) {
10856 push(tw);
10857 reset_variables(tw, compressor, this);
10858 descend();
10859 pop(tw);
10860 return true;
10861 });
10862 def_reduce_vars(AST_Assign, function(tw, descend, compressor) {
10863 var node = this;
10864 if (node.left instanceof AST_Destructuring) {
10865 suppress(node.left);
10866 return;
10867 }
10868 var sym = node.left;
10869 if (!(sym instanceof AST_SymbolRef)) return;
10870 var def = sym.definition();
10871 var safe = safe_to_assign(tw, def, sym.scope, node.right);
10872 def.assignments++;
10873 if (!safe) return;
10874 var fixed = def.fixed;
10875 if (!fixed && node.operator != "=") return;
10876 var eq = node.operator == "=";
10877 var value = eq ? node.right : node;
10878 if (is_modified(compressor, tw, node, value, 0)) return;
10879 def.references.push(sym);
10880 if (!eq) def.chained = true;
10881 def.fixed = eq ? function() {
10882 return node.right;
10883 } : function() {
10884 return make_node(AST_Binary, node, {
10885 operator: node.operator.slice(0, -1),
10886 left: fixed instanceof AST_Node ? fixed : fixed(),
10887 right: node.right
10888 });
10889 };
10890 mark(tw, def, false);
10891 node.right.walk(tw);
10892 mark(tw, def, true);
10893 mark_escaped(tw, def, sym.scope, node, value, 0, 1);
10894 return true;
10895 });
10896 def_reduce_vars(AST_Binary, function(tw) {
10897 if (!lazy_op.has(this.operator)) return;
10898 this.left.walk(tw);
10899 push(tw);
10900 this.right.walk(tw);
10901 pop(tw);
10902 return true;
10903 });
10904 def_reduce_vars(AST_Block, function(tw, descend, compressor) {
10905 reset_block_variables(compressor, this);
10906 });
10907 def_reduce_vars(AST_Case, function(tw) {
10908 push(tw);
10909 this.expression.walk(tw);
10910 pop(tw);
10911 push(tw);
10912 walk_body(this, tw);
10913 pop(tw);
10914 return true;
10915 });
10916 def_reduce_vars(AST_Class, function(tw, descend) {
10917 clear_flag(this, INLINED);
10918 push(tw);
10919 descend();
10920 pop(tw);
10921 return true;
10922 });
10923 def_reduce_vars(AST_Conditional, function(tw) {
10924 this.condition.walk(tw);
10925 push(tw);
10926 this.consequent.walk(tw);
10927 pop(tw);
10928 push(tw);
10929 this.alternative.walk(tw);
10930 pop(tw);
10931 return true;
10932 });
10933
10934 def_reduce_vars(AST_Chain, function(tw, descend) {
10935 // Chains' conditions apply left-to-right, cumulatively.
10936 // If we walk normally we don't go in that order because we would pop before pushing again
10937 // Solution: AST_PropAccess and AST_Call push when they are optional, and never pop.
10938 // Then we pop everything when they are done being walked.
10939 const safe_ids = tw.safe_ids;
10940
10941 descend();
10942
10943 // Unroll back to start
10944 tw.safe_ids = safe_ids;
10945 return true;
10946 });
10947 def_reduce_vars(AST_Call, function (tw) {
10948 // TODO this block should just be { return } but
10949 // for some reason the _walk function of AST_Call walks the callee last
10950
10951 this.expression.walk(tw);
10952
10953 if (this.optional) {
10954 // Never pop -- it's popped at AST_Chain above
10955 push(tw);
10956 }
10957
10958 for (const arg of this.args) arg.walk(tw);
10959
10960 return true;
10961 });
10962 def_reduce_vars(AST_PropAccess, function (tw) {
10963 if (!this.optional) return;
10964
10965 this.expression.walk(tw);
10966
10967 // Never pop -- it's popped at AST_Chain above
10968 push(tw);
10969
10970 if (this.property instanceof AST_Node) this.property.walk(tw);
10971
10972 return true;
10973 });
10974 def_reduce_vars(AST_Default, function(tw, descend) {
10975 push(tw);
10976 descend();
10977 pop(tw);
10978 return true;
10979 });
10980 function mark_lambda(tw, descend, compressor) {
10981 clear_flag(this, INLINED);
10982 push(tw);
10983 reset_variables(tw, compressor, this);
10984 if (this.uses_arguments) {
10985 descend();
10986 pop(tw);
10987 return;
10988 }
10989 var iife;
10990 if (!this.name
10991 && (iife = tw.parent()) instanceof AST_Call
10992 && iife.expression === this
10993 && !iife.args.some(arg => arg instanceof AST_Expansion)
10994 && this.argnames.every(arg_name => arg_name instanceof AST_Symbol)
10995 ) {
10996 // Virtually turn IIFE parameters into variable definitions:
10997 // (function(a,b) {...})(c,d) => (function() {var a=c,b=d; ...})()
10998 // So existing transformation rules can work on them.
10999 this.argnames.forEach((arg, i) => {
11000 if (!arg.definition) return;
11001 var d = arg.definition();
11002 // Avoid setting fixed when there's more than one origin for a variable value
11003 if (d.orig.length > 1) return;
11004 if (d.fixed === undefined && (!this.uses_arguments || tw.has_directive("use strict"))) {
11005 d.fixed = function() {
11006 return iife.args[i] || make_node(AST_Undefined, iife);
11007 };
11008 tw.loop_ids.set(d.id, tw.in_loop);
11009 mark(tw, d, true);
11010 } else {
11011 d.fixed = false;
11012 }
11013 });
11014 }
11015 descend();
11016 pop(tw);
11017 return true;
11018 }
11019
11020 def_reduce_vars(AST_Lambda, mark_lambda);
11021
11022 def_reduce_vars(AST_Do, function(tw, descend, compressor) {
11023 reset_block_variables(compressor, this);
11024 const saved_loop = tw.in_loop;
11025 tw.in_loop = this;
11026 push(tw);
11027 this.body.walk(tw);
11028 if (has_break_or_continue(this)) {
11029 pop(tw);
11030 push(tw);
11031 }
11032 this.condition.walk(tw);
11033 pop(tw);
11034 tw.in_loop = saved_loop;
11035 return true;
11036 });
11037 def_reduce_vars(AST_For, function(tw, descend, compressor) {
11038 reset_block_variables(compressor, this);
11039 if (this.init) this.init.walk(tw);
11040 const saved_loop = tw.in_loop;
11041 tw.in_loop = this;
11042 push(tw);
11043 if (this.condition) this.condition.walk(tw);
11044 this.body.walk(tw);
11045 if (this.step) {
11046 if (has_break_or_continue(this)) {
11047 pop(tw);
11048 push(tw);
11049 }
11050 this.step.walk(tw);
11051 }
11052 pop(tw);
11053 tw.in_loop = saved_loop;
11054 return true;
11055 });
11056 def_reduce_vars(AST_ForIn, function(tw, descend, compressor) {
11057 reset_block_variables(compressor, this);
11058 suppress(this.init);
11059 this.object.walk(tw);
11060 const saved_loop = tw.in_loop;
11061 tw.in_loop = this;
11062 push(tw);
11063 this.body.walk(tw);
11064 pop(tw);
11065 tw.in_loop = saved_loop;
11066 return true;
11067 });
11068
11069 def_reduce_vars(AST_If, function(tw) {
11070 this.condition.walk(tw);
11071 push(tw);
11072 this.body.walk(tw);
11073 pop(tw);
11074 if (this.alternative) {
11075 push(tw);
11076 this.alternative.walk(tw);
11077 pop(tw);
11078 }
11079 return true;
11080 });
11081 def_reduce_vars(AST_LabeledStatement, function(tw) {
11082 push(tw);
11083 this.body.walk(tw);
11084 pop(tw);
11085 return true;
11086 });
11087 def_reduce_vars(AST_SymbolCatch, function() {
11088 this.definition().fixed = false;
11089 });
11090
11091 def_reduce_vars(AST_SymbolRef, function(tw, descend, compressor) {
11092 var d = this.definition();
11093 d.references.push(this);
11094 if (d.references.length == 1
11095 && !d.fixed
11096 && d.orig[0] instanceof AST_SymbolDefun) {
11097 tw.loop_ids.set(d.id, tw.in_loop);
11098 }
11099 var fixed_value;
11100 if (d.fixed === undefined || !safe_to_read(tw, d)) {
11101 d.fixed = false;
11102 } else if (d.fixed) {
11103 fixed_value = this.fixed_value();
11104 if (
11105 fixed_value instanceof AST_Lambda
11106 && recursive_ref(tw, d)
11107 ) {
11108 d.recursive_refs++;
11109 } else if (fixed_value
11110 && !compressor.exposed(d)
11111 && ref_once(tw, compressor, d)
11112 ) {
11113 d.single_use =
11114 fixed_value instanceof AST_Lambda && !fixed_value.pinned()
11115 || fixed_value instanceof AST_Class
11116 || d.scope === this.scope && fixed_value.is_constant_expression();
11117 } else {
11118 d.single_use = false;
11119 }
11120 if (is_modified(compressor, tw, this, fixed_value, 0, is_immutable(fixed_value))) {
11121 if (d.single_use) {
11122 d.single_use = "m";
11123 } else {
11124 d.fixed = false;
11125 }
11126 }
11127 }
11128 mark_escaped(tw, d, this.scope, this, fixed_value, 0, 1);
11129 });
11130 def_reduce_vars(AST_Toplevel, function(tw, descend, compressor) {
11131 this.globals.forEach(function(def) {
11132 reset_def(compressor, def);
11133 });
11134 reset_variables(tw, compressor, this);
11135 });
11136 def_reduce_vars(AST_Try, function(tw, descend, compressor) {
11137 reset_block_variables(compressor, this);
11138 push(tw);
11139 walk_body(this, tw);
11140 pop(tw);
11141 if (this.bcatch) {
11142 push(tw);
11143 this.bcatch.walk(tw);
11144 pop(tw);
11145 }
11146 if (this.bfinally) this.bfinally.walk(tw);
11147 return true;
11148 });
11149 def_reduce_vars(AST_Unary, function(tw) {
11150 var node = this;
11151 if (node.operator !== "++" && node.operator !== "--") return;
11152 var exp = node.expression;
11153 if (!(exp instanceof AST_SymbolRef)) return;
11154 var def = exp.definition();
11155 var safe = safe_to_assign(tw, def, exp.scope, true);
11156 def.assignments++;
11157 if (!safe) return;
11158 var fixed = def.fixed;
11159 if (!fixed) return;
11160 def.references.push(exp);
11161 def.chained = true;
11162 def.fixed = function() {
11163 return make_node(AST_Binary, node, {
11164 operator: node.operator.slice(0, -1),
11165 left: make_node(AST_UnaryPrefix, node, {
11166 operator: "+",
11167 expression: fixed instanceof AST_Node ? fixed : fixed()
11168 }),
11169 right: make_node(AST_Number, node, {
11170 value: 1
11171 })
11172 });
11173 };
11174 mark(tw, def, true);
11175 return true;
11176 });
11177 def_reduce_vars(AST_VarDef, function(tw, descend) {
11178 var node = this;
11179 if (node.name instanceof AST_Destructuring) {
11180 suppress(node.name);
11181 return;
11182 }
11183 var d = node.name.definition();
11184 if (node.value) {
11185 if (safe_to_assign(tw, d, node.name.scope, node.value)) {
11186 d.fixed = function() {
11187 return node.value;
11188 };
11189 tw.loop_ids.set(d.id, tw.in_loop);
11190 mark(tw, d, false);
11191 descend();
11192 mark(tw, d, true);
11193 return true;
11194 } else {
11195 d.fixed = false;
11196 }
11197 }
11198 });
11199 def_reduce_vars(AST_While, function(tw, descend, compressor) {
11200 reset_block_variables(compressor, this);
11201 const saved_loop = tw.in_loop;
11202 tw.in_loop = this;
11203 push(tw);
11204 descend();
11205 pop(tw);
11206 tw.in_loop = saved_loop;
11207 return true;
11208 });
11209})(function(node, func) {
11210 node.DEFMETHOD("reduce_vars", func);
11211});
11212
11213AST_Toplevel.DEFMETHOD("reset_opt_flags", function(compressor) {
11214 const self = this;
11215 const reduce_vars = compressor.option("reduce_vars");
11216
11217 const preparation = new TreeWalker(function(node, descend) {
11218 clear_flag(node, CLEAR_BETWEEN_PASSES);
11219 if (reduce_vars) {
11220 if (compressor.top_retain
11221 && node instanceof AST_Defun // Only functions are retained
11222 && preparation.parent() === self
11223 ) {
11224 set_flag(node, TOP);
11225 }
11226 return node.reduce_vars(preparation, descend, compressor);
11227 }
11228 });
11229 // Stack of look-up tables to keep track of whether a `SymbolDef` has been
11230 // properly assigned before use:
11231 // - `push()` & `pop()` when visiting conditional branches
11232 preparation.safe_ids = Object.create(null);
11233 preparation.in_loop = null;
11234 preparation.loop_ids = new Map();
11235 preparation.defs_to_safe_ids = new Map();
11236 self.walk(preparation);
11237});
11238
11239AST_Symbol.DEFMETHOD("fixed_value", function() {
11240 var fixed = this.thedef.fixed;
11241 if (!fixed || fixed instanceof AST_Node) return fixed;
11242 return fixed();
11243});
11244
11245AST_SymbolRef.DEFMETHOD("is_immutable", function() {
11246 var orig = this.definition().orig;
11247 return orig.length == 1 && orig[0] instanceof AST_SymbolLambda;
11248});
11249
11250function is_func_expr(node) {
11251 return node instanceof AST_Arrow || node instanceof AST_Function;
11252}
11253
11254function is_lhs_read_only(lhs) {
11255 if (lhs instanceof AST_This) return true;
11256 if (lhs instanceof AST_SymbolRef) return lhs.definition().orig[0] instanceof AST_SymbolLambda;
11257 if (lhs instanceof AST_PropAccess) {
11258 lhs = lhs.expression;
11259 if (lhs instanceof AST_SymbolRef) {
11260 if (lhs.is_immutable()) return false;
11261 lhs = lhs.fixed_value();
11262 }
11263 if (!lhs) return true;
11264 if (lhs instanceof AST_RegExp) return false;
11265 if (lhs instanceof AST_Constant) return true;
11266 return is_lhs_read_only(lhs);
11267 }
11268 return false;
11269}
11270
11271function is_ref_of(ref, type) {
11272 if (!(ref instanceof AST_SymbolRef)) return false;
11273 var orig = ref.definition().orig;
11274 for (var i = orig.length; --i >= 0;) {
11275 if (orig[i] instanceof type) return true;
11276 }
11277}
11278
11279function find_scope(tw) {
11280 for (let i = 0;;i++) {
11281 const p = tw.parent(i);
11282 if (p instanceof AST_Toplevel) return p;
11283 if (p instanceof AST_Lambda) return p;
11284 if (p.block_scope) return p.block_scope;
11285 }
11286}
11287
11288function find_variable(compressor, name) {
11289 var scope, i = 0;
11290 while (scope = compressor.parent(i++)) {
11291 if (scope instanceof AST_Scope) break;
11292 if (scope instanceof AST_Catch && scope.argname) {
11293 scope = scope.argname.definition().scope;
11294 break;
11295 }
11296 }
11297 return scope.find_variable(name);
11298}
11299
11300function make_sequence(orig, expressions) {
11301 if (expressions.length == 1) return expressions[0];
11302 if (expressions.length == 0) throw new Error("trying to create a sequence with length zero!");
11303 return make_node(AST_Sequence, orig, {
11304 expressions: expressions.reduce(merge_sequence, [])
11305 });
11306}
11307
11308function make_node_from_constant(val, orig) {
11309 switch (typeof val) {
11310 case "string":
11311 return make_node(AST_String, orig, {
11312 value: val
11313 });
11314 case "number":
11315 if (isNaN(val)) return make_node(AST_NaN, orig);
11316 if (isFinite(val)) {
11317 return 1 / val < 0 ? make_node(AST_UnaryPrefix, orig, {
11318 operator: "-",
11319 expression: make_node(AST_Number, orig, { value: -val })
11320 }) : make_node(AST_Number, orig, { value: val });
11321 }
11322 return val < 0 ? make_node(AST_UnaryPrefix, orig, {
11323 operator: "-",
11324 expression: make_node(AST_Infinity, orig)
11325 }) : make_node(AST_Infinity, orig);
11326 case "boolean":
11327 return make_node(val ? AST_True : AST_False, orig);
11328 case "undefined":
11329 return make_node(AST_Undefined, orig);
11330 default:
11331 if (val === null) {
11332 return make_node(AST_Null, orig, { value: null });
11333 }
11334 if (val instanceof RegExp) {
11335 return make_node(AST_RegExp, orig, {
11336 value: {
11337 source: regexp_source_fix(val.source),
11338 flags: val.flags
11339 }
11340 });
11341 }
11342 throw new Error(string_template("Can't handle constant of type: {type}", {
11343 type: typeof val
11344 }));
11345 }
11346}
11347
11348// we shouldn't compress (1,func)(something) to
11349// func(something) because that changes the meaning of
11350// the func (becomes lexical instead of global).
11351function maintain_this_binding(parent, orig, val) {
11352 if (parent instanceof AST_UnaryPrefix && parent.operator == "delete"
11353 || parent instanceof AST_Call && parent.expression === orig
11354 && (val instanceof AST_PropAccess || val instanceof AST_SymbolRef && val.name == "eval")) {
11355 return make_sequence(orig, [ make_node(AST_Number, orig, { value: 0 }), val ]);
11356 }
11357 return val;
11358}
11359
11360function merge_sequence(array, node) {
11361 if (node instanceof AST_Sequence) {
11362 array.push(...node.expressions);
11363 } else {
11364 array.push(node);
11365 }
11366 return array;
11367}
11368
11369function as_statement_array(thing) {
11370 if (thing === null) return [];
11371 if (thing instanceof AST_BlockStatement) return thing.body;
11372 if (thing instanceof AST_EmptyStatement) return [];
11373 if (thing instanceof AST_Statement) return [ thing ];
11374 throw new Error("Can't convert thing to statement array");
11375}
11376
11377function is_empty(thing) {
11378 if (thing === null) return true;
11379 if (thing instanceof AST_EmptyStatement) return true;
11380 if (thing instanceof AST_BlockStatement) return thing.body.length == 0;
11381 return false;
11382}
11383
11384function can_be_evicted_from_block(node) {
11385 return !(
11386 node instanceof AST_DefClass ||
11387 node instanceof AST_Defun ||
11388 node instanceof AST_Let ||
11389 node instanceof AST_Const ||
11390 node instanceof AST_Export ||
11391 node instanceof AST_Import
11392 );
11393}
11394
11395function loop_body(x) {
11396 if (x instanceof AST_IterationStatement) {
11397 return x.body instanceof AST_BlockStatement ? x.body : x;
11398 }
11399 return x;
11400}
11401
11402function is_iife_call(node) {
11403 // Used to determine whether the node can benefit from negation.
11404 // Not the case with arrow functions (you need an extra set of parens).
11405 if (node.TYPE != "Call") return false;
11406 return node.expression instanceof AST_Function || is_iife_call(node.expression);
11407}
11408
11409function is_undeclared_ref(node) {
11410 return node instanceof AST_SymbolRef && node.definition().undeclared;
11411}
11412
11413var global_names = makePredicate("Array Boolean clearInterval clearTimeout console Date decodeURI decodeURIComponent encodeURI encodeURIComponent Error escape eval EvalError Function isFinite isNaN JSON Math Number parseFloat parseInt RangeError ReferenceError RegExp Object setInterval setTimeout String SyntaxError TypeError unescape URIError");
11414AST_SymbolRef.DEFMETHOD("is_declared", function(compressor) {
11415 return !this.definition().undeclared
11416 || compressor.option("unsafe") && global_names.has(this.name);
11417});
11418
11419var identifier_atom = makePredicate("Infinity NaN undefined");
11420function is_identifier_atom(node) {
11421 return node instanceof AST_Infinity
11422 || node instanceof AST_NaN
11423 || node instanceof AST_Undefined;
11424}
11425
11426// Tighten a bunch of statements together. Used whenever there is a block.
11427function tighten_body(statements, compressor) {
11428 var in_loop, in_try;
11429 var scope = compressor.find_parent(AST_Scope).get_defun_scope();
11430 find_loop_scope_try();
11431 var CHANGED, max_iter = 10;
11432 do {
11433 CHANGED = false;
11434 eliminate_spurious_blocks(statements);
11435 if (compressor.option("dead_code")) {
11436 eliminate_dead_code(statements, compressor);
11437 }
11438 if (compressor.option("if_return")) {
11439 handle_if_return(statements, compressor);
11440 }
11441 if (compressor.sequences_limit > 0) {
11442 sequencesize(statements, compressor);
11443 sequencesize_2(statements, compressor);
11444 }
11445 if (compressor.option("join_vars")) {
11446 join_consecutive_vars(statements);
11447 }
11448 if (compressor.option("collapse_vars")) {
11449 collapse(statements, compressor);
11450 }
11451 } while (CHANGED && max_iter-- > 0);
11452
11453 function find_loop_scope_try() {
11454 var node = compressor.self(), level = 0;
11455 do {
11456 if (node instanceof AST_Catch || node instanceof AST_Finally) {
11457 level++;
11458 } else if (node instanceof AST_IterationStatement) {
11459 in_loop = true;
11460 } else if (node instanceof AST_Scope) {
11461 scope = node;
11462 break;
11463 } else if (node instanceof AST_Try) {
11464 in_try = true;
11465 }
11466 } while (node = compressor.parent(level++));
11467 }
11468
11469 // Search from right to left for assignment-like expressions:
11470 // - `var a = x;`
11471 // - `a = x;`
11472 // - `++a`
11473 // For each candidate, scan from left to right for first usage, then try
11474 // to fold assignment into the site for compression.
11475 // Will not attempt to collapse assignments into or past code blocks
11476 // which are not sequentially executed, e.g. loops and conditionals.
11477 function collapse(statements, compressor) {
11478 if (scope.pinned()) return statements;
11479 var args;
11480 var candidates = [];
11481 var stat_index = statements.length;
11482 var scanner = new TreeTransformer(function(node) {
11483 if (abort) return node;
11484 // Skip nodes before `candidate` as quickly as possible
11485 if (!hit) {
11486 if (node !== hit_stack[hit_index]) return node;
11487 hit_index++;
11488 if (hit_index < hit_stack.length) return handle_custom_scan_order(node);
11489 hit = true;
11490 stop_after = find_stop(node, 0);
11491 if (stop_after === node) abort = true;
11492 return node;
11493 }
11494 // Stop immediately if these node types are encountered
11495 var parent = scanner.parent();
11496 if (node instanceof AST_Assign && node.operator != "=" && lhs.equivalent_to(node.left)
11497 || node instanceof AST_Await
11498 || node instanceof AST_Call && lhs instanceof AST_PropAccess && lhs.equivalent_to(node.expression)
11499 || node instanceof AST_Debugger
11500 || node instanceof AST_Destructuring
11501 || node instanceof AST_Expansion
11502 && node.expression instanceof AST_Symbol
11503 && node.expression.definition().references.length > 1
11504 || node instanceof AST_IterationStatement && !(node instanceof AST_For)
11505 || node instanceof AST_LoopControl
11506 || node instanceof AST_Try
11507 || node instanceof AST_With
11508 || node instanceof AST_Yield
11509 || node instanceof AST_Export
11510 || node instanceof AST_Class
11511 || parent instanceof AST_For && node !== parent.init
11512 || !replace_all
11513 && (
11514 node instanceof AST_SymbolRef
11515 && !node.is_declared(compressor)
11516 && !pure_prop_access_globals.has(node))
11517 || node instanceof AST_SymbolRef
11518 && parent instanceof AST_Call
11519 && has_annotation(parent, _NOINLINE)
11520 ) {
11521 abort = true;
11522 return node;
11523 }
11524 // Stop only if candidate is found within conditional branches
11525 if (!stop_if_hit && (!lhs_local || !replace_all)
11526 && (parent instanceof AST_Binary && lazy_op.has(parent.operator) && parent.left !== node
11527 || parent instanceof AST_Conditional && parent.condition !== node
11528 || parent instanceof AST_If && parent.condition !== node)) {
11529 stop_if_hit = parent;
11530 }
11531 // Replace variable with assignment when found
11532 if (can_replace
11533 && !(node instanceof AST_SymbolDeclaration)
11534 && lhs.equivalent_to(node)
11535 ) {
11536 if (stop_if_hit) {
11537 abort = true;
11538 return node;
11539 }
11540 if (is_lhs(node, parent)) {
11541 if (value_def) replaced++;
11542 return node;
11543 } else {
11544 replaced++;
11545 if (value_def && candidate instanceof AST_VarDef) return node;
11546 }
11547 CHANGED = abort = true;
11548 if (candidate instanceof AST_UnaryPostfix) {
11549 return make_node(AST_UnaryPrefix, candidate, candidate);
11550 }
11551 if (candidate instanceof AST_VarDef) {
11552 var def = candidate.name.definition();
11553 var value = candidate.value;
11554 if (def.references.length - def.replaced == 1 && !compressor.exposed(def)) {
11555 def.replaced++;
11556 if (funarg && is_identifier_atom(value)) {
11557 return value.transform(compressor);
11558 } else {
11559 return maintain_this_binding(parent, node, value);
11560 }
11561 }
11562 return make_node(AST_Assign, candidate, {
11563 operator: "=",
11564 left: make_node(AST_SymbolRef, candidate.name, candidate.name),
11565 right: value
11566 });
11567 }
11568 clear_flag(candidate, WRITE_ONLY);
11569 return candidate;
11570 }
11571 // These node types have child nodes that execute sequentially,
11572 // but are otherwise not safe to scan into or beyond them.
11573 var sym;
11574 if (node instanceof AST_Call
11575 || node instanceof AST_Exit
11576 && (side_effects || lhs instanceof AST_PropAccess || may_modify(lhs))
11577 || node instanceof AST_PropAccess
11578 && (side_effects || node.expression.may_throw_on_access(compressor))
11579 || node instanceof AST_SymbolRef
11580 && (lvalues.get(node.name) || side_effects && may_modify(node))
11581 || node instanceof AST_VarDef && node.value
11582 && (lvalues.has(node.name.name) || side_effects && may_modify(node.name))
11583 || (sym = is_lhs(node.left, node))
11584 && (sym instanceof AST_PropAccess || lvalues.has(sym.name))
11585 || may_throw
11586 && (in_try ? node.has_side_effects(compressor) : side_effects_external(node))) {
11587 stop_after = node;
11588 if (node instanceof AST_Scope) abort = true;
11589 }
11590 return handle_custom_scan_order(node);
11591 }, function(node) {
11592 if (abort) return;
11593 if (stop_after === node) abort = true;
11594 if (stop_if_hit === node) stop_if_hit = null;
11595 });
11596 var multi_replacer = new TreeTransformer(function(node) {
11597 if (abort) return node;
11598 // Skip nodes before `candidate` as quickly as possible
11599 if (!hit) {
11600 if (node !== hit_stack[hit_index]) return node;
11601 hit_index++;
11602 if (hit_index < hit_stack.length) return;
11603 hit = true;
11604 return node;
11605 }
11606 // Replace variable when found
11607 if (node instanceof AST_SymbolRef
11608 && node.name == def.name) {
11609 if (!--replaced) abort = true;
11610 if (is_lhs(node, multi_replacer.parent())) return node;
11611 def.replaced++;
11612 value_def.replaced--;
11613 return candidate.value;
11614 }
11615 // Skip (non-executed) functions and (leading) default case in switch statements
11616 if (node instanceof AST_Default || node instanceof AST_Scope) return node;
11617 });
11618 while (--stat_index >= 0) {
11619 // Treat parameters as collapsible in IIFE, i.e.
11620 // function(a, b){ ... }(x());
11621 // would be translated into equivalent assignments:
11622 // var a = x(), b = undefined;
11623 if (stat_index == 0 && compressor.option("unused")) extract_args();
11624 // Find collapsible assignments
11625 var hit_stack = [];
11626 extract_candidates(statements[stat_index]);
11627 while (candidates.length > 0) {
11628 hit_stack = candidates.pop();
11629 var hit_index = 0;
11630 var candidate = hit_stack[hit_stack.length - 1];
11631 var value_def = null;
11632 var stop_after = null;
11633 var stop_if_hit = null;
11634 var lhs = get_lhs(candidate);
11635 if (!lhs || is_lhs_read_only(lhs) || lhs.has_side_effects(compressor)) continue;
11636 // Locate symbols which may execute code outside of scanning range
11637 var lvalues = get_lvalues(candidate);
11638 var lhs_local = is_lhs_local(lhs);
11639 if (lhs instanceof AST_SymbolRef) lvalues.set(lhs.name, false);
11640 var side_effects = value_has_side_effects(candidate);
11641 var replace_all = replace_all_symbols();
11642 var may_throw = candidate.may_throw(compressor);
11643 var funarg = candidate.name instanceof AST_SymbolFunarg;
11644 var hit = funarg;
11645 var abort = false, replaced = 0, can_replace = !args || !hit;
11646 if (!can_replace) {
11647 for (var j = compressor.self().argnames.lastIndexOf(candidate.name) + 1; !abort && j < args.length; j++) {
11648 args[j].transform(scanner);
11649 }
11650 can_replace = true;
11651 }
11652 for (var i = stat_index; !abort && i < statements.length; i++) {
11653 statements[i].transform(scanner);
11654 }
11655 if (value_def) {
11656 var def = candidate.name.definition();
11657 if (abort && def.references.length - def.replaced > replaced) replaced = false;
11658 else {
11659 abort = false;
11660 hit_index = 0;
11661 hit = funarg;
11662 for (var i = stat_index; !abort && i < statements.length; i++) {
11663 statements[i].transform(multi_replacer);
11664 }
11665 value_def.single_use = false;
11666 }
11667 }
11668 if (replaced && !remove_candidate(candidate)) statements.splice(stat_index, 1);
11669 }
11670 }
11671
11672 function handle_custom_scan_order(node) {
11673 // Skip (non-executed) functions
11674 if (node instanceof AST_Scope) return node;
11675
11676 // Scan case expressions first in a switch statement
11677 if (node instanceof AST_Switch) {
11678 node.expression = node.expression.transform(scanner);
11679 for (var i = 0, len = node.body.length; !abort && i < len; i++) {
11680 var branch = node.body[i];
11681 if (branch instanceof AST_Case) {
11682 if (!hit) {
11683 if (branch !== hit_stack[hit_index]) continue;
11684 hit_index++;
11685 }
11686 branch.expression = branch.expression.transform(scanner);
11687 if (!replace_all) break;
11688 }
11689 }
11690 abort = true;
11691 return node;
11692 }
11693 }
11694
11695 function redefined_within_scope(def, scope) {
11696 if (def.global) return false;
11697 let cur_scope = def.scope;
11698 while (cur_scope && cur_scope !== scope) {
11699 if (cur_scope.variables.has(def.name)) return true;
11700 cur_scope = cur_scope.parent_scope;
11701 }
11702 return false;
11703 }
11704
11705 function has_overlapping_symbol(fn, arg, fn_strict) {
11706 var found = false, scan_this = !(fn instanceof AST_Arrow);
11707 arg.walk(new TreeWalker(function(node, descend) {
11708 if (found) return true;
11709 if (node instanceof AST_SymbolRef && (fn.variables.has(node.name) || redefined_within_scope(node.definition(), fn))) {
11710 var s = node.definition().scope;
11711 if (s !== scope) while (s = s.parent_scope) {
11712 if (s === scope) return true;
11713 }
11714 return found = true;
11715 }
11716 if ((fn_strict || scan_this) && node instanceof AST_This) {
11717 return found = true;
11718 }
11719 if (node instanceof AST_Scope && !(node instanceof AST_Arrow)) {
11720 var prev = scan_this;
11721 scan_this = false;
11722 descend();
11723 scan_this = prev;
11724 return true;
11725 }
11726 }));
11727 return found;
11728 }
11729
11730 function extract_args() {
11731 var iife, fn = compressor.self();
11732 if (is_func_expr(fn)
11733 && !fn.name
11734 && !fn.uses_arguments
11735 && !fn.pinned()
11736 && (iife = compressor.parent()) instanceof AST_Call
11737 && iife.expression === fn
11738 && iife.args.every((arg) => !(arg instanceof AST_Expansion))
11739 ) {
11740 var fn_strict = compressor.has_directive("use strict");
11741 if (fn_strict && !member(fn_strict, fn.body)) fn_strict = false;
11742 var len = fn.argnames.length;
11743 args = iife.args.slice(len);
11744 var names = new Set();
11745 for (var i = len; --i >= 0;) {
11746 var sym = fn.argnames[i];
11747 var arg = iife.args[i];
11748 // The following two line fix is a duplicate of the fix at
11749 // https://github.com/terser/terser/commit/011d3eb08cefe6922c7d1bdfa113fc4aeaca1b75
11750 // This might mean that these two pieces of code (one here in collapse_vars and another in reduce_vars
11751 // Might be doing the exact same thing.
11752 const def = sym.definition && sym.definition();
11753 const is_reassigned = def && def.orig.length > 1;
11754 if (is_reassigned) continue;
11755 args.unshift(make_node(AST_VarDef, sym, {
11756 name: sym,
11757 value: arg
11758 }));
11759 if (names.has(sym.name)) continue;
11760 names.add(sym.name);
11761 if (sym instanceof AST_Expansion) {
11762 var elements = iife.args.slice(i);
11763 if (elements.every((arg) =>
11764 !has_overlapping_symbol(fn, arg, fn_strict)
11765 )) {
11766 candidates.unshift([ make_node(AST_VarDef, sym, {
11767 name: sym.expression,
11768 value: make_node(AST_Array, iife, {
11769 elements: elements
11770 })
11771 }) ]);
11772 }
11773 } else {
11774 if (!arg) {
11775 arg = make_node(AST_Undefined, sym).transform(compressor);
11776 } else if (arg instanceof AST_Lambda && arg.pinned()
11777 || has_overlapping_symbol(fn, arg, fn_strict)
11778 ) {
11779 arg = null;
11780 }
11781 if (arg) candidates.unshift([ make_node(AST_VarDef, sym, {
11782 name: sym,
11783 value: arg
11784 }) ]);
11785 }
11786 }
11787 }
11788 }
11789
11790 function extract_candidates(expr) {
11791 hit_stack.push(expr);
11792 if (expr instanceof AST_Assign) {
11793 if (!expr.left.has_side_effects(compressor)) {
11794 candidates.push(hit_stack.slice());
11795 }
11796 extract_candidates(expr.right);
11797 } else if (expr instanceof AST_Binary) {
11798 extract_candidates(expr.left);
11799 extract_candidates(expr.right);
11800 } else if (expr instanceof AST_Call && !has_annotation(expr, _NOINLINE)) {
11801 extract_candidates(expr.expression);
11802 expr.args.forEach(extract_candidates);
11803 } else if (expr instanceof AST_Case) {
11804 extract_candidates(expr.expression);
11805 } else if (expr instanceof AST_Conditional) {
11806 extract_candidates(expr.condition);
11807 extract_candidates(expr.consequent);
11808 extract_candidates(expr.alternative);
11809 } else if (expr instanceof AST_Definitions) {
11810 var len = expr.definitions.length;
11811 // limit number of trailing variable definitions for consideration
11812 var i = len - 200;
11813 if (i < 0) i = 0;
11814 for (; i < len; i++) {
11815 extract_candidates(expr.definitions[i]);
11816 }
11817 } else if (expr instanceof AST_DWLoop) {
11818 extract_candidates(expr.condition);
11819 if (!(expr.body instanceof AST_Block)) {
11820 extract_candidates(expr.body);
11821 }
11822 } else if (expr instanceof AST_Exit) {
11823 if (expr.value) extract_candidates(expr.value);
11824 } else if (expr instanceof AST_For) {
11825 if (expr.init) extract_candidates(expr.init);
11826 if (expr.condition) extract_candidates(expr.condition);
11827 if (expr.step) extract_candidates(expr.step);
11828 if (!(expr.body instanceof AST_Block)) {
11829 extract_candidates(expr.body);
11830 }
11831 } else if (expr instanceof AST_ForIn) {
11832 extract_candidates(expr.object);
11833 if (!(expr.body instanceof AST_Block)) {
11834 extract_candidates(expr.body);
11835 }
11836 } else if (expr instanceof AST_If) {
11837 extract_candidates(expr.condition);
11838 if (!(expr.body instanceof AST_Block)) {
11839 extract_candidates(expr.body);
11840 }
11841 if (expr.alternative && !(expr.alternative instanceof AST_Block)) {
11842 extract_candidates(expr.alternative);
11843 }
11844 } else if (expr instanceof AST_Sequence) {
11845 expr.expressions.forEach(extract_candidates);
11846 } else if (expr instanceof AST_SimpleStatement) {
11847 extract_candidates(expr.body);
11848 } else if (expr instanceof AST_Switch) {
11849 extract_candidates(expr.expression);
11850 expr.body.forEach(extract_candidates);
11851 } else if (expr instanceof AST_Unary) {
11852 if (expr.operator == "++" || expr.operator == "--") {
11853 candidates.push(hit_stack.slice());
11854 }
11855 } else if (expr instanceof AST_VarDef) {
11856 if (expr.value) {
11857 candidates.push(hit_stack.slice());
11858 extract_candidates(expr.value);
11859 }
11860 }
11861 hit_stack.pop();
11862 }
11863
11864 function find_stop(node, level, write_only) {
11865 var parent = scanner.parent(level);
11866 if (parent instanceof AST_Assign) {
11867 if (write_only
11868 && !(parent.left instanceof AST_PropAccess
11869 || lvalues.has(parent.left.name))) {
11870 return find_stop(parent, level + 1, write_only);
11871 }
11872 return node;
11873 }
11874 if (parent instanceof AST_Binary) {
11875 if (write_only && (!lazy_op.has(parent.operator) || parent.left === node)) {
11876 return find_stop(parent, level + 1, write_only);
11877 }
11878 return node;
11879 }
11880 if (parent instanceof AST_Call) return node;
11881 if (parent instanceof AST_Case) return node;
11882 if (parent instanceof AST_Conditional) {
11883 if (write_only && parent.condition === node) {
11884 return find_stop(parent, level + 1, write_only);
11885 }
11886 return node;
11887 }
11888 if (parent instanceof AST_Definitions) {
11889 return find_stop(parent, level + 1, true);
11890 }
11891 if (parent instanceof AST_Exit) {
11892 return write_only ? find_stop(parent, level + 1, write_only) : node;
11893 }
11894 if (parent instanceof AST_If) {
11895 if (write_only && parent.condition === node) {
11896 return find_stop(parent, level + 1, write_only);
11897 }
11898 return node;
11899 }
11900 if (parent instanceof AST_IterationStatement) return node;
11901 if (parent instanceof AST_Sequence) {
11902 return find_stop(parent, level + 1, parent.tail_node() !== node);
11903 }
11904 if (parent instanceof AST_SimpleStatement) {
11905 return find_stop(parent, level + 1, true);
11906 }
11907 if (parent instanceof AST_Switch) return node;
11908 if (parent instanceof AST_VarDef) return node;
11909 return null;
11910 }
11911
11912 function mangleable_var(var_def) {
11913 var value = var_def.value;
11914 if (!(value instanceof AST_SymbolRef)) return;
11915 if (value.name == "arguments") return;
11916 var def = value.definition();
11917 if (def.undeclared) return;
11918 return value_def = def;
11919 }
11920
11921 function get_lhs(expr) {
11922 if (expr instanceof AST_VarDef && expr.name instanceof AST_SymbolDeclaration) {
11923 var def = expr.name.definition();
11924 if (!member(expr.name, def.orig)) return;
11925 var referenced = def.references.length - def.replaced;
11926 if (!referenced) return;
11927 var declared = def.orig.length - def.eliminated;
11928 if (declared > 1 && !(expr.name instanceof AST_SymbolFunarg)
11929 || (referenced > 1 ? mangleable_var(expr) : !compressor.exposed(def))) {
11930 return make_node(AST_SymbolRef, expr.name, expr.name);
11931 }
11932 } else {
11933 const lhs = expr[expr instanceof AST_Assign ? "left" : "expression"];
11934 return !is_ref_of(lhs, AST_SymbolConst)
11935 && !is_ref_of(lhs, AST_SymbolLet) && lhs;
11936 }
11937 }
11938
11939 function get_rvalue(expr) {
11940 return expr[expr instanceof AST_Assign ? "right" : "value"];
11941 }
11942
11943 function get_lvalues(expr) {
11944 var lvalues = new Map();
11945 if (expr instanceof AST_Unary) return lvalues;
11946 var tw = new TreeWalker(function(node) {
11947 var sym = node;
11948 while (sym instanceof AST_PropAccess) sym = sym.expression;
11949 if (sym instanceof AST_SymbolRef || sym instanceof AST_This) {
11950 lvalues.set(sym.name, lvalues.get(sym.name) || is_modified(compressor, tw, node, node, 0));
11951 }
11952 });
11953 get_rvalue(expr).walk(tw);
11954 return lvalues;
11955 }
11956
11957 function remove_candidate(expr) {
11958 if (expr.name instanceof AST_SymbolFunarg) {
11959 var iife = compressor.parent(), argnames = compressor.self().argnames;
11960 var index = argnames.indexOf(expr.name);
11961 if (index < 0) {
11962 iife.args.length = Math.min(iife.args.length, argnames.length - 1);
11963 } else {
11964 var args = iife.args;
11965 if (args[index]) args[index] = make_node(AST_Number, args[index], {
11966 value: 0
11967 });
11968 }
11969 return true;
11970 }
11971 var found = false;
11972 return statements[stat_index].transform(new TreeTransformer(function(node, descend, in_list) {
11973 if (found) return node;
11974 if (node === expr || node.body === expr) {
11975 found = true;
11976 if (node instanceof AST_VarDef) {
11977 node.value = node.name instanceof AST_SymbolConst
11978 ? make_node(AST_Undefined, node.value) // `const` always needs value.
11979 : null;
11980 return node;
11981 }
11982 return in_list ? MAP.skip : null;
11983 }
11984 }, function(node) {
11985 if (node instanceof AST_Sequence) switch (node.expressions.length) {
11986 case 0: return null;
11987 case 1: return node.expressions[0];
11988 }
11989 }));
11990 }
11991
11992 function is_lhs_local(lhs) {
11993 while (lhs instanceof AST_PropAccess) lhs = lhs.expression;
11994 return lhs instanceof AST_SymbolRef
11995 && lhs.definition().scope === scope
11996 && !(in_loop
11997 && (lvalues.has(lhs.name)
11998 || candidate instanceof AST_Unary
11999 || candidate instanceof AST_Assign && candidate.operator != "="));
12000 }
12001
12002 function value_has_side_effects(expr) {
12003 if (expr instanceof AST_Unary) return unary_side_effects.has(expr.operator);
12004 return get_rvalue(expr).has_side_effects(compressor);
12005 }
12006
12007 function replace_all_symbols() {
12008 if (side_effects) return false;
12009 if (value_def) return true;
12010 if (lhs instanceof AST_SymbolRef) {
12011 var def = lhs.definition();
12012 if (def.references.length - def.replaced == (candidate instanceof AST_VarDef ? 1 : 2)) {
12013 return true;
12014 }
12015 }
12016 return false;
12017 }
12018
12019 function may_modify(sym) {
12020 if (!sym.definition) return true; // AST_Destructuring
12021 var def = sym.definition();
12022 if (def.orig.length == 1 && def.orig[0] instanceof AST_SymbolDefun) return false;
12023 if (def.scope.get_defun_scope() !== scope) return true;
12024 return !def.references.every((ref) => {
12025 var s = ref.scope.get_defun_scope();
12026 // "block" scope within AST_Catch
12027 if (s.TYPE == "Scope") s = s.parent_scope;
12028 return s === scope;
12029 });
12030 }
12031
12032 function side_effects_external(node, lhs) {
12033 if (node instanceof AST_Assign) return side_effects_external(node.left, true);
12034 if (node instanceof AST_Unary) return side_effects_external(node.expression, true);
12035 if (node instanceof AST_VarDef) return node.value && side_effects_external(node.value);
12036 if (lhs) {
12037 if (node instanceof AST_Dot) return side_effects_external(node.expression, true);
12038 if (node instanceof AST_Sub) return side_effects_external(node.expression, true);
12039 if (node instanceof AST_SymbolRef) return node.definition().scope !== scope;
12040 }
12041 return false;
12042 }
12043 }
12044
12045 function eliminate_spurious_blocks(statements) {
12046 var seen_dirs = [];
12047 for (var i = 0; i < statements.length;) {
12048 var stat = statements[i];
12049 if (stat instanceof AST_BlockStatement && stat.body.every(can_be_evicted_from_block)) {
12050 CHANGED = true;
12051 eliminate_spurious_blocks(stat.body);
12052 statements.splice(i, 1, ...stat.body);
12053 i += stat.body.length;
12054 } else if (stat instanceof AST_EmptyStatement) {
12055 CHANGED = true;
12056 statements.splice(i, 1);
12057 } else if (stat instanceof AST_Directive) {
12058 if (seen_dirs.indexOf(stat.value) < 0) {
12059 i++;
12060 seen_dirs.push(stat.value);
12061 } else {
12062 CHANGED = true;
12063 statements.splice(i, 1);
12064 }
12065 } else i++;
12066 }
12067 }
12068
12069 function handle_if_return(statements, compressor) {
12070 var self = compressor.self();
12071 var multiple_if_returns = has_multiple_if_returns(statements);
12072 var in_lambda = self instanceof AST_Lambda;
12073 for (var i = statements.length; --i >= 0;) {
12074 var stat = statements[i];
12075 var j = next_index(i);
12076 var next = statements[j];
12077
12078 if (in_lambda && !next && stat instanceof AST_Return) {
12079 if (!stat.value) {
12080 CHANGED = true;
12081 statements.splice(i, 1);
12082 continue;
12083 }
12084 if (stat.value instanceof AST_UnaryPrefix && stat.value.operator == "void") {
12085 CHANGED = true;
12086 statements[i] = make_node(AST_SimpleStatement, stat, {
12087 body: stat.value.expression
12088 });
12089 continue;
12090 }
12091 }
12092
12093 if (stat instanceof AST_If) {
12094 var ab = aborts(stat.body);
12095 if (can_merge_flow(ab)) {
12096 if (ab.label) {
12097 remove(ab.label.thedef.references, ab);
12098 }
12099 CHANGED = true;
12100 stat = stat.clone();
12101 stat.condition = stat.condition.negate(compressor);
12102 var body = as_statement_array_with_return(stat.body, ab);
12103 stat.body = make_node(AST_BlockStatement, stat, {
12104 body: as_statement_array(stat.alternative).concat(extract_functions())
12105 });
12106 stat.alternative = make_node(AST_BlockStatement, stat, {
12107 body: body
12108 });
12109 statements[i] = stat.transform(compressor);
12110 continue;
12111 }
12112
12113 var ab = aborts(stat.alternative);
12114 if (can_merge_flow(ab)) {
12115 if (ab.label) {
12116 remove(ab.label.thedef.references, ab);
12117 }
12118 CHANGED = true;
12119 stat = stat.clone();
12120 stat.body = make_node(AST_BlockStatement, stat.body, {
12121 body: as_statement_array(stat.body).concat(extract_functions())
12122 });
12123 var body = as_statement_array_with_return(stat.alternative, ab);
12124 stat.alternative = make_node(AST_BlockStatement, stat.alternative, {
12125 body: body
12126 });
12127 statements[i] = stat.transform(compressor);
12128 continue;
12129 }
12130 }
12131
12132 if (stat instanceof AST_If && stat.body instanceof AST_Return) {
12133 var value = stat.body.value;
12134 //---
12135 // pretty silly case, but:
12136 // if (foo()) return; return; ==> foo(); return;
12137 if (!value && !stat.alternative
12138 && (in_lambda && !next || next instanceof AST_Return && !next.value)) {
12139 CHANGED = true;
12140 statements[i] = make_node(AST_SimpleStatement, stat.condition, {
12141 body: stat.condition
12142 });
12143 continue;
12144 }
12145 //---
12146 // if (foo()) return x; return y; ==> return foo() ? x : y;
12147 if (value && !stat.alternative && next instanceof AST_Return && next.value) {
12148 CHANGED = true;
12149 stat = stat.clone();
12150 stat.alternative = next;
12151 statements[i] = stat.transform(compressor);
12152 statements.splice(j, 1);
12153 continue;
12154 }
12155 //---
12156 // if (foo()) return x; [ return ; ] ==> return foo() ? x : undefined;
12157 if (value && !stat.alternative
12158 && (!next && in_lambda && multiple_if_returns
12159 || next instanceof AST_Return)) {
12160 CHANGED = true;
12161 stat = stat.clone();
12162 stat.alternative = next || make_node(AST_Return, stat, {
12163 value: null
12164 });
12165 statements[i] = stat.transform(compressor);
12166 if (next) statements.splice(j, 1);
12167 continue;
12168 }
12169 //---
12170 // if (a) return b; if (c) return d; e; ==> return a ? b : c ? d : void e;
12171 //
12172 // if sequences is not enabled, this can lead to an endless loop (issue #866).
12173 // however, with sequences on this helps producing slightly better output for
12174 // the example code.
12175 var prev = statements[prev_index(i)];
12176 if (compressor.option("sequences") && in_lambda && !stat.alternative
12177 && prev instanceof AST_If && prev.body instanceof AST_Return
12178 && next_index(j) == statements.length && next instanceof AST_SimpleStatement) {
12179 CHANGED = true;
12180 stat = stat.clone();
12181 stat.alternative = make_node(AST_BlockStatement, next, {
12182 body: [
12183 next,
12184 make_node(AST_Return, next, {
12185 value: null
12186 })
12187 ]
12188 });
12189 statements[i] = stat.transform(compressor);
12190 statements.splice(j, 1);
12191 continue;
12192 }
12193 }
12194 }
12195
12196 function has_multiple_if_returns(statements) {
12197 var n = 0;
12198 for (var i = statements.length; --i >= 0;) {
12199 var stat = statements[i];
12200 if (stat instanceof AST_If && stat.body instanceof AST_Return) {
12201 if (++n > 1) return true;
12202 }
12203 }
12204 return false;
12205 }
12206
12207 function is_return_void(value) {
12208 return !value || value instanceof AST_UnaryPrefix && value.operator == "void";
12209 }
12210
12211 function can_merge_flow(ab) {
12212 if (!ab) return false;
12213 for (var j = i + 1, len = statements.length; j < len; j++) {
12214 var stat = statements[j];
12215 if (stat instanceof AST_Const || stat instanceof AST_Let) return false;
12216 }
12217 var lct = ab instanceof AST_LoopControl ? compressor.loopcontrol_target(ab) : null;
12218 return ab instanceof AST_Return && in_lambda && is_return_void(ab.value)
12219 || ab instanceof AST_Continue && self === loop_body(lct)
12220 || ab instanceof AST_Break && lct instanceof AST_BlockStatement && self === lct;
12221 }
12222
12223 function extract_functions() {
12224 var tail = statements.slice(i + 1);
12225 statements.length = i + 1;
12226 return tail.filter(function(stat) {
12227 if (stat instanceof AST_Defun) {
12228 statements.push(stat);
12229 return false;
12230 }
12231 return true;
12232 });
12233 }
12234
12235 function as_statement_array_with_return(node, ab) {
12236 var body = as_statement_array(node).slice(0, -1);
12237 if (ab.value) {
12238 body.push(make_node(AST_SimpleStatement, ab.value, {
12239 body: ab.value.expression
12240 }));
12241 }
12242 return body;
12243 }
12244
12245 function next_index(i) {
12246 for (var j = i + 1, len = statements.length; j < len; j++) {
12247 var stat = statements[j];
12248 if (!(stat instanceof AST_Var && declarations_only(stat))) {
12249 break;
12250 }
12251 }
12252 return j;
12253 }
12254
12255 function prev_index(i) {
12256 for (var j = i; --j >= 0;) {
12257 var stat = statements[j];
12258 if (!(stat instanceof AST_Var && declarations_only(stat))) {
12259 break;
12260 }
12261 }
12262 return j;
12263 }
12264 }
12265
12266 function eliminate_dead_code(statements, compressor) {
12267 var has_quit;
12268 var self = compressor.self();
12269 for (var i = 0, n = 0, len = statements.length; i < len; i++) {
12270 var stat = statements[i];
12271 if (stat instanceof AST_LoopControl) {
12272 var lct = compressor.loopcontrol_target(stat);
12273 if (stat instanceof AST_Break
12274 && !(lct instanceof AST_IterationStatement)
12275 && loop_body(lct) === self
12276 || stat instanceof AST_Continue
12277 && loop_body(lct) === self) {
12278 if (stat.label) {
12279 remove(stat.label.thedef.references, stat);
12280 }
12281 } else {
12282 statements[n++] = stat;
12283 }
12284 } else {
12285 statements[n++] = stat;
12286 }
12287 if (aborts(stat)) {
12288 has_quit = statements.slice(i + 1);
12289 break;
12290 }
12291 }
12292 statements.length = n;
12293 CHANGED = n != len;
12294 if (has_quit) has_quit.forEach(function(stat) {
12295 trim_unreachable_code(compressor, stat, statements);
12296 });
12297 }
12298
12299 function declarations_only(node) {
12300 return node.definitions.every((var_def) =>
12301 !var_def.value
12302 );
12303 }
12304
12305 function sequencesize(statements, compressor) {
12306 if (statements.length < 2) return;
12307 var seq = [], n = 0;
12308 function push_seq() {
12309 if (!seq.length) return;
12310 var body = make_sequence(seq[0], seq);
12311 statements[n++] = make_node(AST_SimpleStatement, body, { body: body });
12312 seq = [];
12313 }
12314 for (var i = 0, len = statements.length; i < len; i++) {
12315 var stat = statements[i];
12316 if (stat instanceof AST_SimpleStatement) {
12317 if (seq.length >= compressor.sequences_limit) push_seq();
12318 var body = stat.body;
12319 if (seq.length > 0) body = body.drop_side_effect_free(compressor);
12320 if (body) merge_sequence(seq, body);
12321 } else if (stat instanceof AST_Definitions && declarations_only(stat)
12322 || stat instanceof AST_Defun) {
12323 statements[n++] = stat;
12324 } else {
12325 push_seq();
12326 statements[n++] = stat;
12327 }
12328 }
12329 push_seq();
12330 statements.length = n;
12331 if (n != len) CHANGED = true;
12332 }
12333
12334 function to_simple_statement(block, decls) {
12335 if (!(block instanceof AST_BlockStatement)) return block;
12336 var stat = null;
12337 for (var i = 0, len = block.body.length; i < len; i++) {
12338 var line = block.body[i];
12339 if (line instanceof AST_Var && declarations_only(line)) {
12340 decls.push(line);
12341 } else if (stat) {
12342 return false;
12343 } else {
12344 stat = line;
12345 }
12346 }
12347 return stat;
12348 }
12349
12350 function sequencesize_2(statements, compressor) {
12351 function cons_seq(right) {
12352 n--;
12353 CHANGED = true;
12354 var left = prev.body;
12355 return make_sequence(left, [ left, right ]).transform(compressor);
12356 }
12357 var n = 0, prev;
12358 for (var i = 0; i < statements.length; i++) {
12359 var stat = statements[i];
12360 if (prev) {
12361 if (stat instanceof AST_Exit) {
12362 stat.value = cons_seq(stat.value || make_node(AST_Undefined, stat).transform(compressor));
12363 } else if (stat instanceof AST_For) {
12364 if (!(stat.init instanceof AST_Definitions)) {
12365 const abort = walk(prev.body, node => {
12366 if (node instanceof AST_Scope) return true;
12367 if (
12368 node instanceof AST_Binary
12369 && node.operator === "in"
12370 ) {
12371 return walk_abort;
12372 }
12373 });
12374 if (!abort) {
12375 if (stat.init) stat.init = cons_seq(stat.init);
12376 else {
12377 stat.init = prev.body;
12378 n--;
12379 CHANGED = true;
12380 }
12381 }
12382 }
12383 } else if (stat instanceof AST_ForIn) {
12384 if (!(stat.init instanceof AST_Const) && !(stat.init instanceof AST_Let)) {
12385 stat.object = cons_seq(stat.object);
12386 }
12387 } else if (stat instanceof AST_If) {
12388 stat.condition = cons_seq(stat.condition);
12389 } else if (stat instanceof AST_Switch) {
12390 stat.expression = cons_seq(stat.expression);
12391 } else if (stat instanceof AST_With) {
12392 stat.expression = cons_seq(stat.expression);
12393 }
12394 }
12395 if (compressor.option("conditionals") && stat instanceof AST_If) {
12396 var decls = [];
12397 var body = to_simple_statement(stat.body, decls);
12398 var alt = to_simple_statement(stat.alternative, decls);
12399 if (body !== false && alt !== false && decls.length > 0) {
12400 var len = decls.length;
12401 decls.push(make_node(AST_If, stat, {
12402 condition: stat.condition,
12403 body: body || make_node(AST_EmptyStatement, stat.body),
12404 alternative: alt
12405 }));
12406 decls.unshift(n, 1);
12407 [].splice.apply(statements, decls);
12408 i += len;
12409 n += len + 1;
12410 prev = null;
12411 CHANGED = true;
12412 continue;
12413 }
12414 }
12415 statements[n++] = stat;
12416 prev = stat instanceof AST_SimpleStatement ? stat : null;
12417 }
12418 statements.length = n;
12419 }
12420
12421 function join_object_assignments(defn, body) {
12422 if (!(defn instanceof AST_Definitions)) return;
12423 var def = defn.definitions[defn.definitions.length - 1];
12424 if (!(def.value instanceof AST_Object)) return;
12425 var exprs;
12426 if (body instanceof AST_Assign) {
12427 exprs = [ body ];
12428 } else if (body instanceof AST_Sequence) {
12429 exprs = body.expressions.slice();
12430 }
12431 if (!exprs) return;
12432 var trimmed = false;
12433 do {
12434 var node = exprs[0];
12435 if (!(node instanceof AST_Assign)) break;
12436 if (node.operator != "=") break;
12437 if (!(node.left instanceof AST_PropAccess)) break;
12438 var sym = node.left.expression;
12439 if (!(sym instanceof AST_SymbolRef)) break;
12440 if (def.name.name != sym.name) break;
12441 if (!node.right.is_constant_expression(scope)) break;
12442 var prop = node.left.property;
12443 if (prop instanceof AST_Node) {
12444 prop = prop.evaluate(compressor);
12445 }
12446 if (prop instanceof AST_Node) break;
12447 prop = "" + prop;
12448 var diff = compressor.option("ecma") < 2015
12449 && compressor.has_directive("use strict") ? function(node) {
12450 return node.key != prop && (node.key && node.key.name != prop);
12451 } : function(node) {
12452 return node.key && node.key.name != prop;
12453 };
12454 if (!def.value.properties.every(diff)) break;
12455 var p = def.value.properties.filter(function (p) { return p.key === prop; })[0];
12456 if (!p) {
12457 def.value.properties.push(make_node(AST_ObjectKeyVal, node, {
12458 key: prop,
12459 value: node.right
12460 }));
12461 } else {
12462 p.value = new AST_Sequence({
12463 start: p.start,
12464 expressions: [p.value.clone(), node.right.clone()],
12465 end: p.end
12466 });
12467 }
12468 exprs.shift();
12469 trimmed = true;
12470 } while (exprs.length);
12471 return trimmed && exprs;
12472 }
12473
12474 function join_consecutive_vars(statements) {
12475 var defs;
12476 for (var i = 0, j = -1, len = statements.length; i < len; i++) {
12477 var stat = statements[i];
12478 var prev = statements[j];
12479 if (stat instanceof AST_Definitions) {
12480 if (prev && prev.TYPE == stat.TYPE) {
12481 prev.definitions = prev.definitions.concat(stat.definitions);
12482 CHANGED = true;
12483 } else if (defs && defs.TYPE == stat.TYPE && declarations_only(stat)) {
12484 defs.definitions = defs.definitions.concat(stat.definitions);
12485 CHANGED = true;
12486 } else {
12487 statements[++j] = stat;
12488 defs = stat;
12489 }
12490 } else if (stat instanceof AST_Exit) {
12491 stat.value = extract_object_assignments(stat.value);
12492 } else if (stat instanceof AST_For) {
12493 var exprs = join_object_assignments(prev, stat.init);
12494 if (exprs) {
12495 CHANGED = true;
12496 stat.init = exprs.length ? make_sequence(stat.init, exprs) : null;
12497 statements[++j] = stat;
12498 } else if (prev instanceof AST_Var && (!stat.init || stat.init.TYPE == prev.TYPE)) {
12499 if (stat.init) {
12500 prev.definitions = prev.definitions.concat(stat.init.definitions);
12501 }
12502 stat.init = prev;
12503 statements[j] = stat;
12504 CHANGED = true;
12505 } else if (defs && stat.init && defs.TYPE == stat.init.TYPE && declarations_only(stat.init)) {
12506 defs.definitions = defs.definitions.concat(stat.init.definitions);
12507 stat.init = null;
12508 statements[++j] = stat;
12509 CHANGED = true;
12510 } else {
12511 statements[++j] = stat;
12512 }
12513 } else if (stat instanceof AST_ForIn) {
12514 stat.object = extract_object_assignments(stat.object);
12515 } else if (stat instanceof AST_If) {
12516 stat.condition = extract_object_assignments(stat.condition);
12517 } else if (stat instanceof AST_SimpleStatement) {
12518 var exprs = join_object_assignments(prev, stat.body);
12519 if (exprs) {
12520 CHANGED = true;
12521 if (!exprs.length) continue;
12522 stat.body = make_sequence(stat.body, exprs);
12523 }
12524 statements[++j] = stat;
12525 } else if (stat instanceof AST_Switch) {
12526 stat.expression = extract_object_assignments(stat.expression);
12527 } else if (stat instanceof AST_With) {
12528 stat.expression = extract_object_assignments(stat.expression);
12529 } else {
12530 statements[++j] = stat;
12531 }
12532 }
12533 statements.length = j + 1;
12534
12535 function extract_object_assignments(value) {
12536 statements[++j] = stat;
12537 var exprs = join_object_assignments(prev, value);
12538 if (exprs) {
12539 CHANGED = true;
12540 if (exprs.length) {
12541 return make_sequence(value, exprs);
12542 } else if (value instanceof AST_Sequence) {
12543 return value.tail_node().left;
12544 } else {
12545 return value.left;
12546 }
12547 }
12548 return value;
12549 }
12550 }
12551}
12552
12553function trim_unreachable_code(compressor, stat, target) {
12554 walk(stat, node => {
12555 if (node instanceof AST_Var) {
12556 node.remove_initializers();
12557 target.push(node);
12558 return true;
12559 }
12560 if (
12561 node instanceof AST_Defun
12562 && (node === stat || !compressor.has_directive("use strict"))
12563 ) {
12564 target.push(node === stat ? node : make_node(AST_Var, node, {
12565 definitions: [
12566 make_node(AST_VarDef, node, {
12567 name: make_node(AST_SymbolVar, node.name, node.name),
12568 value: null
12569 })
12570 ]
12571 }));
12572 return true;
12573 }
12574 if (node instanceof AST_Export || node instanceof AST_Import) {
12575 target.push(node);
12576 return true;
12577 }
12578 if (node instanceof AST_Scope) {
12579 return true;
12580 }
12581 });
12582}
12583
12584function get_value(key) {
12585 if (key instanceof AST_Constant) {
12586 return key.getValue();
12587 }
12588 if (key instanceof AST_UnaryPrefix
12589 && key.operator == "void"
12590 && key.expression instanceof AST_Constant) {
12591 return;
12592 }
12593 return key;
12594}
12595
12596function is_undefined(node, compressor) {
12597 return (
12598 has_flag(node, UNDEFINED)
12599 || node instanceof AST_Undefined
12600 || node instanceof AST_UnaryPrefix
12601 && node.operator == "void"
12602 && !node.expression.has_side_effects(compressor)
12603 );
12604}
12605
12606// may_throw_on_access()
12607// returns true if this node may be null, undefined or contain `AST_Accessor`
12608(function(def_may_throw_on_access) {
12609 AST_Node.DEFMETHOD("may_throw_on_access", function(compressor) {
12610 return !compressor.option("pure_getters")
12611 || this._dot_throw(compressor);
12612 });
12613
12614 function is_strict(compressor) {
12615 return /strict/.test(compressor.option("pure_getters"));
12616 }
12617
12618 def_may_throw_on_access(AST_Node, is_strict);
12619 def_may_throw_on_access(AST_Null, return_true);
12620 def_may_throw_on_access(AST_Undefined, return_true);
12621 def_may_throw_on_access(AST_Constant, return_false);
12622 def_may_throw_on_access(AST_Array, return_false);
12623 def_may_throw_on_access(AST_Object, function(compressor) {
12624 if (!is_strict(compressor)) return false;
12625 for (var i = this.properties.length; --i >=0;)
12626 if (this.properties[i]._dot_throw(compressor)) return true;
12627 return false;
12628 });
12629 // Do not be as strict with classes as we are with objects.
12630 // Hopefully the community is not going to abuse static getters and setters.
12631 // https://github.com/terser/terser/issues/724#issuecomment-643655656
12632 def_may_throw_on_access(AST_Class, return_false);
12633 def_may_throw_on_access(AST_ObjectProperty, return_false);
12634 def_may_throw_on_access(AST_ObjectGetter, return_true);
12635 def_may_throw_on_access(AST_Expansion, function(compressor) {
12636 return this.expression._dot_throw(compressor);
12637 });
12638 def_may_throw_on_access(AST_Function, return_false);
12639 def_may_throw_on_access(AST_Arrow, return_false);
12640 def_may_throw_on_access(AST_UnaryPostfix, return_false);
12641 def_may_throw_on_access(AST_UnaryPrefix, function() {
12642 return this.operator == "void";
12643 });
12644 def_may_throw_on_access(AST_Binary, function(compressor) {
12645 return (this.operator == "&&" || this.operator == "||" || this.operator == "??")
12646 && (this.left._dot_throw(compressor) || this.right._dot_throw(compressor));
12647 });
12648 def_may_throw_on_access(AST_Assign, function(compressor) {
12649 return this.operator == "="
12650 && this.right._dot_throw(compressor);
12651 });
12652 def_may_throw_on_access(AST_Conditional, function(compressor) {
12653 return this.consequent._dot_throw(compressor)
12654 || this.alternative._dot_throw(compressor);
12655 });
12656 def_may_throw_on_access(AST_Dot, function(compressor) {
12657 if (!is_strict(compressor)) return false;
12658 if (this.expression instanceof AST_Function && this.property == "prototype") return false;
12659 return true;
12660 });
12661 def_may_throw_on_access(AST_Chain, function(compressor) {
12662 return this.expression._dot_throw(compressor);
12663 });
12664 def_may_throw_on_access(AST_Sequence, function(compressor) {
12665 return this.tail_node()._dot_throw(compressor);
12666 });
12667 def_may_throw_on_access(AST_SymbolRef, function(compressor) {
12668 if (this.name === "arguments") return false;
12669 if (has_flag(this, UNDEFINED)) return true;
12670 if (!is_strict(compressor)) return false;
12671 if (is_undeclared_ref(this) && this.is_declared(compressor)) return false;
12672 if (this.is_immutable()) return false;
12673 var fixed = this.fixed_value();
12674 return !fixed || fixed._dot_throw(compressor);
12675 });
12676})(function(node, func) {
12677 node.DEFMETHOD("_dot_throw", func);
12678});
12679
12680/* -----[ boolean/negation helpers ]----- */
12681
12682// methods to determine whether an expression has a boolean result type
12683(function(def_is_boolean) {
12684 const unary_bool = makePredicate("! delete");
12685 const binary_bool = makePredicate("in instanceof == != === !== < <= >= >");
12686 def_is_boolean(AST_Node, return_false);
12687 def_is_boolean(AST_UnaryPrefix, function() {
12688 return unary_bool.has(this.operator);
12689 });
12690 def_is_boolean(AST_Binary, function() {
12691 return binary_bool.has(this.operator)
12692 || lazy_op.has(this.operator)
12693 && this.left.is_boolean()
12694 && this.right.is_boolean();
12695 });
12696 def_is_boolean(AST_Conditional, function() {
12697 return this.consequent.is_boolean() && this.alternative.is_boolean();
12698 });
12699 def_is_boolean(AST_Assign, function() {
12700 return this.operator == "=" && this.right.is_boolean();
12701 });
12702 def_is_boolean(AST_Sequence, function() {
12703 return this.tail_node().is_boolean();
12704 });
12705 def_is_boolean(AST_True, return_true);
12706 def_is_boolean(AST_False, return_true);
12707})(function(node, func) {
12708 node.DEFMETHOD("is_boolean", func);
12709});
12710
12711// methods to determine if an expression has a numeric result type
12712(function(def_is_number) {
12713 def_is_number(AST_Node, return_false);
12714 def_is_number(AST_Number, return_true);
12715 var unary = makePredicate("+ - ~ ++ --");
12716 def_is_number(AST_Unary, function() {
12717 return unary.has(this.operator);
12718 });
12719 var binary = makePredicate("- * / % & | ^ << >> >>>");
12720 def_is_number(AST_Binary, function(compressor) {
12721 return binary.has(this.operator) || this.operator == "+"
12722 && this.left.is_number(compressor)
12723 && this.right.is_number(compressor);
12724 });
12725 def_is_number(AST_Assign, function(compressor) {
12726 return binary.has(this.operator.slice(0, -1))
12727 || this.operator == "=" && this.right.is_number(compressor);
12728 });
12729 def_is_number(AST_Sequence, function(compressor) {
12730 return this.tail_node().is_number(compressor);
12731 });
12732 def_is_number(AST_Conditional, function(compressor) {
12733 return this.consequent.is_number(compressor) && this.alternative.is_number(compressor);
12734 });
12735})(function(node, func) {
12736 node.DEFMETHOD("is_number", func);
12737});
12738
12739// methods to determine if an expression has a string result type
12740(function(def_is_string) {
12741 def_is_string(AST_Node, return_false);
12742 def_is_string(AST_String, return_true);
12743 def_is_string(AST_TemplateString, return_true);
12744 def_is_string(AST_UnaryPrefix, function() {
12745 return this.operator == "typeof";
12746 });
12747 def_is_string(AST_Binary, function(compressor) {
12748 return this.operator == "+" &&
12749 (this.left.is_string(compressor) || this.right.is_string(compressor));
12750 });
12751 def_is_string(AST_Assign, function(compressor) {
12752 return (this.operator == "=" || this.operator == "+=") && this.right.is_string(compressor);
12753 });
12754 def_is_string(AST_Sequence, function(compressor) {
12755 return this.tail_node().is_string(compressor);
12756 });
12757 def_is_string(AST_Conditional, function(compressor) {
12758 return this.consequent.is_string(compressor) && this.alternative.is_string(compressor);
12759 });
12760})(function(node, func) {
12761 node.DEFMETHOD("is_string", func);
12762});
12763
12764var lazy_op = makePredicate("&& || ??");
12765var unary_side_effects = makePredicate("delete ++ --");
12766
12767function is_lhs(node, parent) {
12768 if (parent instanceof AST_Unary && unary_side_effects.has(parent.operator)) return parent.expression;
12769 if (parent instanceof AST_Assign && parent.left === node) return node;
12770}
12771
12772(function(def_find_defs) {
12773 function to_node(value, orig) {
12774 if (value instanceof AST_Node) return make_node(value.CTOR, orig, value);
12775 if (Array.isArray(value)) return make_node(AST_Array, orig, {
12776 elements: value.map(function(value) {
12777 return to_node(value, orig);
12778 })
12779 });
12780 if (value && typeof value == "object") {
12781 var props = [];
12782 for (var key in value) if (HOP(value, key)) {
12783 props.push(make_node(AST_ObjectKeyVal, orig, {
12784 key: key,
12785 value: to_node(value[key], orig)
12786 }));
12787 }
12788 return make_node(AST_Object, orig, {
12789 properties: props
12790 });
12791 }
12792 return make_node_from_constant(value, orig);
12793 }
12794
12795 AST_Toplevel.DEFMETHOD("resolve_defines", function(compressor) {
12796 if (!compressor.option("global_defs")) return this;
12797 this.figure_out_scope({ ie8: compressor.option("ie8") });
12798 return this.transform(new TreeTransformer(function(node) {
12799 var def = node._find_defs(compressor, "");
12800 if (!def) return;
12801 var level = 0, child = node, parent;
12802 while (parent = this.parent(level++)) {
12803 if (!(parent instanceof AST_PropAccess)) break;
12804 if (parent.expression !== child) break;
12805 child = parent;
12806 }
12807 if (is_lhs(child, parent)) {
12808 return;
12809 }
12810 return def;
12811 }));
12812 });
12813 def_find_defs(AST_Node, noop);
12814 def_find_defs(AST_Chain, function(compressor, suffix) {
12815 return this.expression._find_defs(compressor, suffix);
12816 });
12817 def_find_defs(AST_Dot, function(compressor, suffix) {
12818 return this.expression._find_defs(compressor, "." + this.property + suffix);
12819 });
12820 def_find_defs(AST_SymbolDeclaration, function() {
12821 if (!this.global()) return;
12822 });
12823 def_find_defs(AST_SymbolRef, function(compressor, suffix) {
12824 if (!this.global()) return;
12825 var defines = compressor.option("global_defs");
12826 var name = this.name + suffix;
12827 if (HOP(defines, name)) return to_node(defines[name], this);
12828 });
12829})(function(node, func) {
12830 node.DEFMETHOD("_find_defs", func);
12831});
12832
12833function best_of_expression(ast1, ast2) {
12834 return ast1.size() > ast2.size() ? ast2 : ast1;
12835}
12836
12837function best_of_statement(ast1, ast2) {
12838 return best_of_expression(
12839 make_node(AST_SimpleStatement, ast1, {
12840 body: ast1
12841 }),
12842 make_node(AST_SimpleStatement, ast2, {
12843 body: ast2
12844 })
12845 ).body;
12846}
12847
12848function best_of(compressor, ast1, ast2) {
12849 return (first_in_statement(compressor) ? best_of_statement : best_of_expression)(ast1, ast2);
12850}
12851
12852function convert_to_predicate(obj) {
12853 const out = new Map();
12854 for (var key of Object.keys(obj)) {
12855 out.set(key, makePredicate(obj[key]));
12856 }
12857 return out;
12858}
12859
12860var object_fns = [
12861 "constructor",
12862 "toString",
12863 "valueOf",
12864];
12865var native_fns = convert_to_predicate({
12866 Array: [
12867 "indexOf",
12868 "join",
12869 "lastIndexOf",
12870 "slice",
12871 ].concat(object_fns),
12872 Boolean: object_fns,
12873 Function: object_fns,
12874 Number: [
12875 "toExponential",
12876 "toFixed",
12877 "toPrecision",
12878 ].concat(object_fns),
12879 Object: object_fns,
12880 RegExp: [
12881 "test",
12882 ].concat(object_fns),
12883 String: [
12884 "charAt",
12885 "charCodeAt",
12886 "concat",
12887 "indexOf",
12888 "italics",
12889 "lastIndexOf",
12890 "match",
12891 "replace",
12892 "search",
12893 "slice",
12894 "split",
12895 "substr",
12896 "substring",
12897 "toLowerCase",
12898 "toUpperCase",
12899 "trim",
12900 ].concat(object_fns),
12901});
12902var static_fns = convert_to_predicate({
12903 Array: [
12904 "isArray",
12905 ],
12906 Math: [
12907 "abs",
12908 "acos",
12909 "asin",
12910 "atan",
12911 "ceil",
12912 "cos",
12913 "exp",
12914 "floor",
12915 "log",
12916 "round",
12917 "sin",
12918 "sqrt",
12919 "tan",
12920 "atan2",
12921 "pow",
12922 "max",
12923 "min",
12924 ],
12925 Number: [
12926 "isFinite",
12927 "isNaN",
12928 ],
12929 Object: [
12930 "create",
12931 "getOwnPropertyDescriptor",
12932 "getOwnPropertyNames",
12933 "getPrototypeOf",
12934 "isExtensible",
12935 "isFrozen",
12936 "isSealed",
12937 "keys",
12938 ],
12939 String: [
12940 "fromCharCode",
12941 ],
12942});
12943
12944// methods to evaluate a constant expression
12945(function(def_eval) {
12946 // If the node has been successfully reduced to a constant,
12947 // then its value is returned; otherwise the element itself
12948 // is returned.
12949 // They can be distinguished as constant value is never a
12950 // descendant of AST_Node.
12951 AST_Node.DEFMETHOD("evaluate", function(compressor) {
12952 if (!compressor.option("evaluate")) return this;
12953 var val = this._eval(compressor, 1);
12954 if (!val || val instanceof RegExp) return val;
12955 if (typeof val == "function" || typeof val == "object") return this;
12956 return val;
12957 });
12958 var unaryPrefix = makePredicate("! ~ - + void");
12959 AST_Node.DEFMETHOD("is_constant", function() {
12960 // Accomodate when compress option evaluate=false
12961 // as well as the common constant expressions !0 and -1
12962 if (this instanceof AST_Constant) {
12963 return !(this instanceof AST_RegExp);
12964 } else {
12965 return this instanceof AST_UnaryPrefix
12966 && this.expression instanceof AST_Constant
12967 && unaryPrefix.has(this.operator);
12968 }
12969 });
12970 def_eval(AST_Statement, function() {
12971 throw new Error(string_template("Cannot evaluate a statement [{file}:{line},{col}]", this.start));
12972 });
12973 def_eval(AST_Lambda, return_this);
12974 def_eval(AST_Class, return_this);
12975 def_eval(AST_Node, return_this);
12976 def_eval(AST_Constant, function() {
12977 return this.getValue();
12978 });
12979 def_eval(AST_BigInt, return_this);
12980 def_eval(AST_RegExp, function(compressor) {
12981 let evaluated = compressor.evaluated_regexps.get(this);
12982 if (evaluated === undefined) {
12983 try {
12984 evaluated = (0, eval)(this.print_to_string());
12985 } catch (e) {
12986 evaluated = null;
12987 }
12988 compressor.evaluated_regexps.set(this, evaluated);
12989 }
12990 return evaluated || this;
12991 });
12992 def_eval(AST_TemplateString, function() {
12993 if (this.segments.length !== 1) return this;
12994 return this.segments[0].value;
12995 });
12996 def_eval(AST_Function, function(compressor) {
12997 if (compressor.option("unsafe")) {
12998 var fn = function() {};
12999 fn.node = this;
13000 fn.toString = function() {
13001 return this.node.print_to_string();
13002 };
13003 return fn;
13004 }
13005 return this;
13006 });
13007 def_eval(AST_Array, function(compressor, depth) {
13008 if (compressor.option("unsafe")) {
13009 var elements = [];
13010 for (var i = 0, len = this.elements.length; i < len; i++) {
13011 var element = this.elements[i];
13012 var value = element._eval(compressor, depth);
13013 if (element === value) return this;
13014 elements.push(value);
13015 }
13016 return elements;
13017 }
13018 return this;
13019 });
13020 def_eval(AST_Object, function(compressor, depth) {
13021 if (compressor.option("unsafe")) {
13022 var val = {};
13023 for (var i = 0, len = this.properties.length; i < len; i++) {
13024 var prop = this.properties[i];
13025 if (prop instanceof AST_Expansion) return this;
13026 var key = prop.key;
13027 if (key instanceof AST_Symbol) {
13028 key = key.name;
13029 } else if (key instanceof AST_Node) {
13030 key = key._eval(compressor, depth);
13031 if (key === prop.key) return this;
13032 }
13033 if (typeof Object.prototype[key] === "function") {
13034 return this;
13035 }
13036 if (prop.value instanceof AST_Function) continue;
13037 val[key] = prop.value._eval(compressor, depth);
13038 if (val[key] === prop.value) return this;
13039 }
13040 return val;
13041 }
13042 return this;
13043 });
13044 var non_converting_unary = makePredicate("! typeof void");
13045 def_eval(AST_UnaryPrefix, function(compressor, depth) {
13046 var e = this.expression;
13047 // Function would be evaluated to an array and so typeof would
13048 // incorrectly return 'object'. Hence making is a special case.
13049 if (compressor.option("typeofs")
13050 && this.operator == "typeof"
13051 && (e instanceof AST_Lambda
13052 || e instanceof AST_SymbolRef
13053 && e.fixed_value() instanceof AST_Lambda)) {
13054 return typeof function() {};
13055 }
13056 if (!non_converting_unary.has(this.operator)) depth++;
13057 e = e._eval(compressor, depth);
13058 if (e === this.expression) return this;
13059 switch (this.operator) {
13060 case "!": return !e;
13061 case "typeof":
13062 // typeof <RegExp> returns "object" or "function" on different platforms
13063 // so cannot evaluate reliably
13064 if (e instanceof RegExp) return this;
13065 return typeof e;
13066 case "void": return void e;
13067 case "~": return ~e;
13068 case "-": return -e;
13069 case "+": return +e;
13070 }
13071 return this;
13072 });
13073 var non_converting_binary = makePredicate("&& || ?? === !==");
13074 const identity_comparison = makePredicate("== != === !==");
13075 const has_identity = value =>
13076 typeof value === "object"
13077 || typeof value === "function"
13078 || typeof value === "symbol";
13079
13080 def_eval(AST_Binary, function(compressor, depth) {
13081 if (!non_converting_binary.has(this.operator)) depth++;
13082
13083 var left = this.left._eval(compressor, depth);
13084 if (left === this.left) return this;
13085 var right = this.right._eval(compressor, depth);
13086 if (right === this.right) return this;
13087 var result;
13088
13089 if (
13090 left != null
13091 && right != null
13092 && identity_comparison.has(this.operator)
13093 && has_identity(left)
13094 && has_identity(right)
13095 && typeof left === typeof right
13096 ) {
13097 // Do not compare by reference
13098 return this;
13099 }
13100
13101 switch (this.operator) {
13102 case "&&" : result = left && right; break;
13103 case "||" : result = left || right; break;
13104 case "??" : result = left != null ? left : right; break;
13105 case "|" : result = left | right; break;
13106 case "&" : result = left & right; break;
13107 case "^" : result = left ^ right; break;
13108 case "+" : result = left + right; break;
13109 case "*" : result = left * right; break;
13110 case "**" : result = Math.pow(left, right); break;
13111 case "/" : result = left / right; break;
13112 case "%" : result = left % right; break;
13113 case "-" : result = left - right; break;
13114 case "<<" : result = left << right; break;
13115 case ">>" : result = left >> right; break;
13116 case ">>>" : result = left >>> right; break;
13117 case "==" : result = left == right; break;
13118 case "===" : result = left === right; break;
13119 case "!=" : result = left != right; break;
13120 case "!==" : result = left !== right; break;
13121 case "<" : result = left < right; break;
13122 case "<=" : result = left <= right; break;
13123 case ">" : result = left > right; break;
13124 case ">=" : result = left >= right; break;
13125 default:
13126 return this;
13127 }
13128 if (isNaN(result) && compressor.find_parent(AST_With)) {
13129 // leave original expression as is
13130 return this;
13131 }
13132 return result;
13133 });
13134 def_eval(AST_Conditional, function(compressor, depth) {
13135 var condition = this.condition._eval(compressor, depth);
13136 if (condition === this.condition) return this;
13137 var node = condition ? this.consequent : this.alternative;
13138 var value = node._eval(compressor, depth);
13139 return value === node ? this : value;
13140 });
13141
13142 // Set of AST_SymbolRef which are currently being evaluated.
13143 // Avoids infinite recursion of ._eval()
13144 const reentrant_ref_eval = new Set();
13145 def_eval(AST_SymbolRef, function(compressor, depth) {
13146 if (reentrant_ref_eval.has(this)) return this;
13147
13148 var fixed = this.fixed_value();
13149 if (!fixed) return this;
13150
13151 reentrant_ref_eval.add(this);
13152 const value = fixed._eval(compressor, depth);
13153 reentrant_ref_eval.delete(this);
13154
13155 if (value === fixed) return this;
13156
13157 if (value && typeof value == "object") {
13158 var escaped = this.definition().escaped;
13159 if (escaped && depth > escaped) return this;
13160 }
13161 return value;
13162 });
13163 var global_objs = { Array, Math, Number, Object, String };
13164 var static_values = convert_to_predicate({
13165 Math: [
13166 "E",
13167 "LN10",
13168 "LN2",
13169 "LOG2E",
13170 "LOG10E",
13171 "PI",
13172 "SQRT1_2",
13173 "SQRT2",
13174 ],
13175 Number: [
13176 "MAX_VALUE",
13177 "MIN_VALUE",
13178 "NaN",
13179 "NEGATIVE_INFINITY",
13180 "POSITIVE_INFINITY",
13181 ],
13182 });
13183 def_eval(AST_PropAccess, function(compressor, depth) {
13184 if (this.optional) {
13185 const obj = this.expression._eval(compressor, depth);
13186 if (obj == null) return undefined;
13187 }
13188 if (compressor.option("unsafe")) {
13189 var key = this.property;
13190 if (key instanceof AST_Node) {
13191 key = key._eval(compressor, depth);
13192 if (key === this.property) return this;
13193 }
13194 var exp = this.expression;
13195 var val;
13196 if (is_undeclared_ref(exp)) {
13197
13198 var aa;
13199 var first_arg = exp.name === "hasOwnProperty"
13200 && key === "call"
13201 && (aa = compressor.parent() && compressor.parent().args)
13202 && (aa && aa[0]
13203 && aa[0].evaluate(compressor));
13204
13205 first_arg = first_arg instanceof AST_Dot ? first_arg.expression : first_arg;
13206
13207 if (first_arg == null || first_arg.thedef && first_arg.thedef.undeclared) {
13208 return this.clone();
13209 }
13210 var static_value = static_values.get(exp.name);
13211 if (!static_value || !static_value.has(key)) return this;
13212 val = global_objs[exp.name];
13213 } else {
13214 val = exp._eval(compressor, depth + 1);
13215 if (!val || val === exp || !HOP(val, key)) return this;
13216 if (typeof val == "function") switch (key) {
13217 case "name":
13218 return val.node.name ? val.node.name.name : "";
13219 case "length":
13220 return val.node.argnames.length;
13221 default:
13222 return this;
13223 }
13224 }
13225 return val[key];
13226 }
13227 return this;
13228 });
13229 def_eval(AST_Chain, function(compressor, depth) {
13230 const evaluated = this.expression._eval(compressor, depth);
13231 return evaluated === this.expression ? this : evaluated;
13232 });
13233 def_eval(AST_Call, function(compressor, depth) {
13234 var exp = this.expression;
13235 if (this.optional) {
13236 const callee = this.expression._eval(compressor, depth);
13237 if (callee == null) return undefined;
13238 }
13239 if (compressor.option("unsafe") && exp instanceof AST_PropAccess) {
13240 var key = exp.property;
13241 if (key instanceof AST_Node) {
13242 key = key._eval(compressor, depth);
13243 if (key === exp.property) return this;
13244 }
13245 var val;
13246 var e = exp.expression;
13247 if (is_undeclared_ref(e)) {
13248 var first_arg =
13249 e.name === "hasOwnProperty" &&
13250 key === "call" &&
13251 (this.args[0] && this.args[0].evaluate(compressor));
13252
13253 first_arg = first_arg instanceof AST_Dot ? first_arg.expression : first_arg;
13254
13255 if ((first_arg == null || first_arg.thedef && first_arg.thedef.undeclared)) {
13256 return this.clone();
13257 }
13258 var static_fn = static_fns.get(e.name);
13259 if (!static_fn || !static_fn.has(key)) return this;
13260 val = global_objs[e.name];
13261 } else {
13262 val = e._eval(compressor, depth + 1);
13263 if (val === e || !val) return this;
13264 var native_fn = native_fns.get(val.constructor.name);
13265 if (!native_fn || !native_fn.has(key)) return this;
13266 }
13267 var args = [];
13268 for (var i = 0, len = this.args.length; i < len; i++) {
13269 var arg = this.args[i];
13270 var value = arg._eval(compressor, depth);
13271 if (arg === value) return this;
13272 args.push(value);
13273 }
13274 try {
13275 return val[key].apply(val, args);
13276 } catch (ex) {
13277 // We don't really care
13278 }
13279 }
13280 return this;
13281 });
13282 def_eval(AST_New, return_this);
13283})(function(node, func) {
13284 node.DEFMETHOD("_eval", func);
13285});
13286
13287// method to negate an expression
13288(function(def_negate) {
13289 function basic_negation(exp) {
13290 return make_node(AST_UnaryPrefix, exp, {
13291 operator: "!",
13292 expression: exp
13293 });
13294 }
13295 function best(orig, alt, first_in_statement) {
13296 var negated = basic_negation(orig);
13297 if (first_in_statement) {
13298 var stat = make_node(AST_SimpleStatement, alt, {
13299 body: alt
13300 });
13301 return best_of_expression(negated, stat) === stat ? alt : negated;
13302 }
13303 return best_of_expression(negated, alt);
13304 }
13305 def_negate(AST_Node, function() {
13306 return basic_negation(this);
13307 });
13308 def_negate(AST_Statement, function() {
13309 throw new Error("Cannot negate a statement");
13310 });
13311 def_negate(AST_Function, function() {
13312 return basic_negation(this);
13313 });
13314 def_negate(AST_Arrow, function() {
13315 return basic_negation(this);
13316 });
13317 def_negate(AST_UnaryPrefix, function() {
13318 if (this.operator == "!")
13319 return this.expression;
13320 return basic_negation(this);
13321 });
13322 def_negate(AST_Sequence, function(compressor) {
13323 var expressions = this.expressions.slice();
13324 expressions.push(expressions.pop().negate(compressor));
13325 return make_sequence(this, expressions);
13326 });
13327 def_negate(AST_Conditional, function(compressor, first_in_statement) {
13328 var self = this.clone();
13329 self.consequent = self.consequent.negate(compressor);
13330 self.alternative = self.alternative.negate(compressor);
13331 return best(this, self, first_in_statement);
13332 });
13333 def_negate(AST_Binary, function(compressor, first_in_statement) {
13334 var self = this.clone(), op = this.operator;
13335 if (compressor.option("unsafe_comps")) {
13336 switch (op) {
13337 case "<=" : self.operator = ">" ; return self;
13338 case "<" : self.operator = ">=" ; return self;
13339 case ">=" : self.operator = "<" ; return self;
13340 case ">" : self.operator = "<=" ; return self;
13341 }
13342 }
13343 switch (op) {
13344 case "==" : self.operator = "!="; return self;
13345 case "!=" : self.operator = "=="; return self;
13346 case "===": self.operator = "!=="; return self;
13347 case "!==": self.operator = "==="; return self;
13348 case "&&":
13349 self.operator = "||";
13350 self.left = self.left.negate(compressor, first_in_statement);
13351 self.right = self.right.negate(compressor);
13352 return best(this, self, first_in_statement);
13353 case "||":
13354 self.operator = "&&";
13355 self.left = self.left.negate(compressor, first_in_statement);
13356 self.right = self.right.negate(compressor);
13357 return best(this, self, first_in_statement);
13358 case "??":
13359 self.right = self.right.negate(compressor);
13360 return best(this, self, first_in_statement);
13361 }
13362 return basic_negation(this);
13363 });
13364})(function(node, func) {
13365 node.DEFMETHOD("negate", function(compressor, first_in_statement) {
13366 return func.call(this, compressor, first_in_statement);
13367 });
13368});
13369
13370var global_pure_fns = makePredicate("Boolean decodeURI decodeURIComponent Date encodeURI encodeURIComponent Error escape EvalError isFinite isNaN Number Object parseFloat parseInt RangeError ReferenceError String SyntaxError TypeError unescape URIError");
13371AST_Call.DEFMETHOD("is_expr_pure", function(compressor) {
13372 if (compressor.option("unsafe")) {
13373 var expr = this.expression;
13374 var first_arg = (this.args && this.args[0] && this.args[0].evaluate(compressor));
13375 if (
13376 expr.expression && expr.expression.name === "hasOwnProperty" &&
13377 (first_arg == null || first_arg.thedef && first_arg.thedef.undeclared)
13378 ) {
13379 return false;
13380 }
13381 if (is_undeclared_ref(expr) && global_pure_fns.has(expr.name)) return true;
13382 let static_fn;
13383 if (expr instanceof AST_Dot
13384 && is_undeclared_ref(expr.expression)
13385 && (static_fn = static_fns.get(expr.expression.name))
13386 && static_fn.has(expr.property)) {
13387 return true;
13388 }
13389 }
13390 return !!has_annotation(this, _PURE) || !compressor.pure_funcs(this);
13391});
13392AST_Node.DEFMETHOD("is_call_pure", return_false);
13393AST_Dot.DEFMETHOD("is_call_pure", function(compressor) {
13394 if (!compressor.option("unsafe")) return;
13395 const expr = this.expression;
13396 let map;
13397 if (expr instanceof AST_Array) {
13398 map = native_fns.get("Array");
13399 } else if (expr.is_boolean()) {
13400 map = native_fns.get("Boolean");
13401 } else if (expr.is_number(compressor)) {
13402 map = native_fns.get("Number");
13403 } else if (expr instanceof AST_RegExp) {
13404 map = native_fns.get("RegExp");
13405 } else if (expr.is_string(compressor)) {
13406 map = native_fns.get("String");
13407 } else if (!this.may_throw_on_access(compressor)) {
13408 map = native_fns.get("Object");
13409 }
13410 return map && map.has(this.property);
13411});
13412
13413const pure_prop_access_globals = new Set([
13414 "Number",
13415 "String",
13416 "Array",
13417 "Object",
13418 "Function",
13419 "Promise",
13420]);
13421// determine if expression has side effects
13422(function(def_has_side_effects) {
13423 def_has_side_effects(AST_Node, return_true);
13424
13425 def_has_side_effects(AST_EmptyStatement, return_false);
13426 def_has_side_effects(AST_Constant, return_false);
13427 def_has_side_effects(AST_This, return_false);
13428
13429 function any(list, compressor) {
13430 for (var i = list.length; --i >= 0;)
13431 if (list[i].has_side_effects(compressor))
13432 return true;
13433 return false;
13434 }
13435
13436 def_has_side_effects(AST_Block, function(compressor) {
13437 return any(this.body, compressor);
13438 });
13439 def_has_side_effects(AST_Call, function(compressor) {
13440 if (
13441 !this.is_expr_pure(compressor)
13442 && (!this.expression.is_call_pure(compressor)
13443 || this.expression.has_side_effects(compressor))
13444 ) {
13445 return true;
13446 }
13447 return any(this.args, compressor);
13448 });
13449 def_has_side_effects(AST_Switch, function(compressor) {
13450 return this.expression.has_side_effects(compressor)
13451 || any(this.body, compressor);
13452 });
13453 def_has_side_effects(AST_Case, function(compressor) {
13454 return this.expression.has_side_effects(compressor)
13455 || any(this.body, compressor);
13456 });
13457 def_has_side_effects(AST_Try, function(compressor) {
13458 return any(this.body, compressor)
13459 || this.bcatch && this.bcatch.has_side_effects(compressor)
13460 || this.bfinally && this.bfinally.has_side_effects(compressor);
13461 });
13462 def_has_side_effects(AST_If, function(compressor) {
13463 return this.condition.has_side_effects(compressor)
13464 || this.body && this.body.has_side_effects(compressor)
13465 || this.alternative && this.alternative.has_side_effects(compressor);
13466 });
13467 def_has_side_effects(AST_LabeledStatement, function(compressor) {
13468 return this.body.has_side_effects(compressor);
13469 });
13470 def_has_side_effects(AST_SimpleStatement, function(compressor) {
13471 return this.body.has_side_effects(compressor);
13472 });
13473 def_has_side_effects(AST_Lambda, return_false);
13474 def_has_side_effects(AST_Class, function (compressor) {
13475 if (this.extends && this.extends.has_side_effects(compressor)) {
13476 return true;
13477 }
13478 return any(this.properties, compressor);
13479 });
13480 def_has_side_effects(AST_Binary, function(compressor) {
13481 return this.left.has_side_effects(compressor)
13482 || this.right.has_side_effects(compressor);
13483 });
13484 def_has_side_effects(AST_Assign, return_true);
13485 def_has_side_effects(AST_Conditional, function(compressor) {
13486 return this.condition.has_side_effects(compressor)
13487 || this.consequent.has_side_effects(compressor)
13488 || this.alternative.has_side_effects(compressor);
13489 });
13490 def_has_side_effects(AST_Unary, function(compressor) {
13491 return unary_side_effects.has(this.operator)
13492 || this.expression.has_side_effects(compressor);
13493 });
13494 def_has_side_effects(AST_SymbolRef, function(compressor) {
13495 return !this.is_declared(compressor) && !pure_prop_access_globals.has(this.name);
13496 });
13497 def_has_side_effects(AST_SymbolClassProperty, return_false);
13498 def_has_side_effects(AST_SymbolDeclaration, return_false);
13499 def_has_side_effects(AST_Object, function(compressor) {
13500 return any(this.properties, compressor);
13501 });
13502 def_has_side_effects(AST_ObjectProperty, function(compressor) {
13503 return (
13504 this.computed_key() && this.key.has_side_effects(compressor)
13505 || this.value.has_side_effects(compressor)
13506 );
13507 });
13508 def_has_side_effects(AST_ClassProperty, function(compressor) {
13509 return (
13510 this.computed_key() && this.key.has_side_effects(compressor)
13511 || this.static && this.value && this.value.has_side_effects(compressor)
13512 );
13513 });
13514 def_has_side_effects(AST_ConciseMethod, function(compressor) {
13515 return this.computed_key() && this.key.has_side_effects(compressor);
13516 });
13517 def_has_side_effects(AST_ObjectGetter, function(compressor) {
13518 return this.computed_key() && this.key.has_side_effects(compressor);
13519 });
13520 def_has_side_effects(AST_ObjectSetter, function(compressor) {
13521 return this.computed_key() && this.key.has_side_effects(compressor);
13522 });
13523 def_has_side_effects(AST_Array, function(compressor) {
13524 return any(this.elements, compressor);
13525 });
13526 def_has_side_effects(AST_Dot, function(compressor) {
13527 return !this.optional && this.expression.may_throw_on_access(compressor)
13528 || this.expression.has_side_effects(compressor);
13529 });
13530 def_has_side_effects(AST_Sub, function(compressor) {
13531 if (this.optional && is_nullish(this.expression)) {
13532 return false;
13533 }
13534
13535 return !this.optional && this.expression.may_throw_on_access(compressor)
13536 || this.expression.has_side_effects(compressor)
13537 || this.property.has_side_effects(compressor);
13538 });
13539 def_has_side_effects(AST_Chain, function (compressor) {
13540 return this.expression.has_side_effects(compressor);
13541 });
13542 def_has_side_effects(AST_Sequence, function(compressor) {
13543 return any(this.expressions, compressor);
13544 });
13545 def_has_side_effects(AST_Definitions, function(compressor) {
13546 return any(this.definitions, compressor);
13547 });
13548 def_has_side_effects(AST_VarDef, function() {
13549 return this.value;
13550 });
13551 def_has_side_effects(AST_TemplateSegment, return_false);
13552 def_has_side_effects(AST_TemplateString, function(compressor) {
13553 return any(this.segments, compressor);
13554 });
13555})(function(node, func) {
13556 node.DEFMETHOD("has_side_effects", func);
13557});
13558
13559// determine if expression may throw
13560(function(def_may_throw) {
13561 def_may_throw(AST_Node, return_true);
13562
13563 def_may_throw(AST_Constant, return_false);
13564 def_may_throw(AST_EmptyStatement, return_false);
13565 def_may_throw(AST_Lambda, return_false);
13566 def_may_throw(AST_SymbolDeclaration, return_false);
13567 def_may_throw(AST_This, return_false);
13568
13569 function any(list, compressor) {
13570 for (var i = list.length; --i >= 0;)
13571 if (list[i].may_throw(compressor))
13572 return true;
13573 return false;
13574 }
13575
13576 def_may_throw(AST_Class, function(compressor) {
13577 if (this.extends && this.extends.may_throw(compressor)) return true;
13578 return any(this.properties, compressor);
13579 });
13580
13581 def_may_throw(AST_Array, function(compressor) {
13582 return any(this.elements, compressor);
13583 });
13584 def_may_throw(AST_Assign, function(compressor) {
13585 if (this.right.may_throw(compressor)) return true;
13586 if (!compressor.has_directive("use strict")
13587 && this.operator == "="
13588 && this.left instanceof AST_SymbolRef) {
13589 return false;
13590 }
13591 return this.left.may_throw(compressor);
13592 });
13593 def_may_throw(AST_Binary, function(compressor) {
13594 return this.left.may_throw(compressor)
13595 || this.right.may_throw(compressor);
13596 });
13597 def_may_throw(AST_Block, function(compressor) {
13598 return any(this.body, compressor);
13599 });
13600 def_may_throw(AST_Call, function(compressor) {
13601 if (this.optional && is_nullish(this.expression)) return false;
13602 if (any(this.args, compressor)) return true;
13603 if (this.is_expr_pure(compressor)) return false;
13604 if (this.expression.may_throw(compressor)) return true;
13605 return !(this.expression instanceof AST_Lambda)
13606 || any(this.expression.body, compressor);
13607 });
13608 def_may_throw(AST_Case, function(compressor) {
13609 return this.expression.may_throw(compressor)
13610 || any(this.body, compressor);
13611 });
13612 def_may_throw(AST_Conditional, function(compressor) {
13613 return this.condition.may_throw(compressor)
13614 || this.consequent.may_throw(compressor)
13615 || this.alternative.may_throw(compressor);
13616 });
13617 def_may_throw(AST_Definitions, function(compressor) {
13618 return any(this.definitions, compressor);
13619 });
13620 def_may_throw(AST_If, function(compressor) {
13621 return this.condition.may_throw(compressor)
13622 || this.body && this.body.may_throw(compressor)
13623 || this.alternative && this.alternative.may_throw(compressor);
13624 });
13625 def_may_throw(AST_LabeledStatement, function(compressor) {
13626 return this.body.may_throw(compressor);
13627 });
13628 def_may_throw(AST_Object, function(compressor) {
13629 return any(this.properties, compressor);
13630 });
13631 def_may_throw(AST_ObjectProperty, function(compressor) {
13632 // TODO key may throw too
13633 return this.value.may_throw(compressor);
13634 });
13635 def_may_throw(AST_ClassProperty, function(compressor) {
13636 return (
13637 this.computed_key() && this.key.may_throw(compressor)
13638 || this.static && this.value && this.value.may_throw(compressor)
13639 );
13640 });
13641 def_may_throw(AST_ConciseMethod, function(compressor) {
13642 return this.computed_key() && this.key.may_throw(compressor);
13643 });
13644 def_may_throw(AST_ObjectGetter, function(compressor) {
13645 return this.computed_key() && this.key.may_throw(compressor);
13646 });
13647 def_may_throw(AST_ObjectSetter, function(compressor) {
13648 return this.computed_key() && this.key.may_throw(compressor);
13649 });
13650 def_may_throw(AST_Return, function(compressor) {
13651 return this.value && this.value.may_throw(compressor);
13652 });
13653 def_may_throw(AST_Sequence, function(compressor) {
13654 return any(this.expressions, compressor);
13655 });
13656 def_may_throw(AST_SimpleStatement, function(compressor) {
13657 return this.body.may_throw(compressor);
13658 });
13659 def_may_throw(AST_Dot, function(compressor) {
13660 return !this.optional && this.expression.may_throw_on_access(compressor)
13661 || this.expression.may_throw(compressor);
13662 });
13663 def_may_throw(AST_Sub, function(compressor) {
13664 if (this.optional && is_nullish(this.expression)) return false;
13665
13666 return !this.optional && this.expression.may_throw_on_access(compressor)
13667 || this.expression.may_throw(compressor)
13668 || this.property.may_throw(compressor);
13669 });
13670 def_may_throw(AST_Chain, function(compressor) {
13671 return this.expression.may_throw(compressor);
13672 });
13673 def_may_throw(AST_Switch, function(compressor) {
13674 return this.expression.may_throw(compressor)
13675 || any(this.body, compressor);
13676 });
13677 def_may_throw(AST_SymbolRef, function(compressor) {
13678 return !this.is_declared(compressor) && !pure_prop_access_globals.has(this.name);
13679 });
13680 def_may_throw(AST_SymbolClassProperty, return_false);
13681 def_may_throw(AST_Try, function(compressor) {
13682 return this.bcatch ? this.bcatch.may_throw(compressor) : any(this.body, compressor)
13683 || this.bfinally && this.bfinally.may_throw(compressor);
13684 });
13685 def_may_throw(AST_Unary, function(compressor) {
13686 if (this.operator == "typeof" && this.expression instanceof AST_SymbolRef)
13687 return false;
13688 return this.expression.may_throw(compressor);
13689 });
13690 def_may_throw(AST_VarDef, function(compressor) {
13691 if (!this.value) return false;
13692 return this.value.may_throw(compressor);
13693 });
13694})(function(node, func) {
13695 node.DEFMETHOD("may_throw", func);
13696});
13697
13698// determine if expression is constant
13699(function(def_is_constant_expression) {
13700 function all_refs_local(scope) {
13701 let result = true;
13702 walk(this, node => {
13703 if (node instanceof AST_SymbolRef) {
13704 if (has_flag(this, INLINED)) {
13705 result = false;
13706 return walk_abort;
13707 }
13708 var def = node.definition();
13709 if (
13710 member(def, this.enclosed)
13711 && !this.variables.has(def.name)
13712 ) {
13713 if (scope) {
13714 var scope_def = scope.find_variable(node);
13715 if (def.undeclared ? !scope_def : scope_def === def) {
13716 result = "f";
13717 return true;
13718 }
13719 }
13720 result = false;
13721 return walk_abort;
13722 }
13723 return true;
13724 }
13725 if (node instanceof AST_This && this instanceof AST_Arrow) {
13726 // TODO check arguments too!
13727 result = false;
13728 return walk_abort;
13729 }
13730 });
13731 return result;
13732 }
13733
13734 def_is_constant_expression(AST_Node, return_false);
13735 def_is_constant_expression(AST_Constant, return_true);
13736 def_is_constant_expression(AST_Class, function(scope) {
13737 if (this.extends && !this.extends.is_constant_expression(scope)) {
13738 return false;
13739 }
13740
13741 for (const prop of this.properties) {
13742 if (prop.computed_key() && !prop.key.is_constant_expression(scope)) {
13743 return false;
13744 }
13745 if (prop.static && prop.value && !prop.value.is_constant_expression(scope)) {
13746 return false;
13747 }
13748 }
13749
13750 return all_refs_local.call(this, scope);
13751 });
13752 def_is_constant_expression(AST_Lambda, all_refs_local);
13753 def_is_constant_expression(AST_Unary, function() {
13754 return this.expression.is_constant_expression();
13755 });
13756 def_is_constant_expression(AST_Binary, function() {
13757 return this.left.is_constant_expression()
13758 && this.right.is_constant_expression();
13759 });
13760 def_is_constant_expression(AST_Array, function() {
13761 return this.elements.every((l) => l.is_constant_expression());
13762 });
13763 def_is_constant_expression(AST_Object, function() {
13764 return this.properties.every((l) => l.is_constant_expression());
13765 });
13766 def_is_constant_expression(AST_ObjectProperty, function() {
13767 return !(this.key instanceof AST_Node) && this.value.is_constant_expression();
13768 });
13769})(function(node, func) {
13770 node.DEFMETHOD("is_constant_expression", func);
13771});
13772
13773// tell me if a statement aborts
13774function aborts(thing) {
13775 return thing && thing.aborts();
13776}
13777(function(def_aborts) {
13778 def_aborts(AST_Statement, return_null);
13779 def_aborts(AST_Jump, return_this);
13780 function block_aborts() {
13781 for (var i = 0; i < this.body.length; i++) {
13782 if (aborts(this.body[i])) {
13783 return this.body[i];
13784 }
13785 }
13786 return null;
13787 }
13788 def_aborts(AST_Import, function() { return null; });
13789 def_aborts(AST_BlockStatement, block_aborts);
13790 def_aborts(AST_SwitchBranch, block_aborts);
13791 def_aborts(AST_If, function() {
13792 return this.alternative && aborts(this.body) && aborts(this.alternative) && this;
13793 });
13794})(function(node, func) {
13795 node.DEFMETHOD("aborts", func);
13796});
13797
13798/* -----[ optimizers ]----- */
13799
13800var directives = new Set(["use asm", "use strict"]);
13801def_optimize(AST_Directive, function(self, compressor) {
13802 if (compressor.option("directives")
13803 && (!directives.has(self.value) || compressor.has_directive(self.value) !== self)) {
13804 return make_node(AST_EmptyStatement, self);
13805 }
13806 return self;
13807});
13808
13809def_optimize(AST_Debugger, function(self, compressor) {
13810 if (compressor.option("drop_debugger"))
13811 return make_node(AST_EmptyStatement, self);
13812 return self;
13813});
13814
13815def_optimize(AST_LabeledStatement, function(self, compressor) {
13816 if (self.body instanceof AST_Break
13817 && compressor.loopcontrol_target(self.body) === self.body) {
13818 return make_node(AST_EmptyStatement, self);
13819 }
13820 return self.label.references.length == 0 ? self.body : self;
13821});
13822
13823def_optimize(AST_Block, function(self, compressor) {
13824 tighten_body(self.body, compressor);
13825 return self;
13826});
13827
13828function can_be_extracted_from_if_block(node) {
13829 return !(
13830 node instanceof AST_Const
13831 || node instanceof AST_Let
13832 || node instanceof AST_Class
13833 );
13834}
13835
13836def_optimize(AST_BlockStatement, function(self, compressor) {
13837 tighten_body(self.body, compressor);
13838 switch (self.body.length) {
13839 case 1:
13840 if (!compressor.has_directive("use strict")
13841 && compressor.parent() instanceof AST_If
13842 && can_be_extracted_from_if_block(self.body[0])
13843 || can_be_evicted_from_block(self.body[0])) {
13844 return self.body[0];
13845 }
13846 break;
13847 case 0: return make_node(AST_EmptyStatement, self);
13848 }
13849 return self;
13850});
13851
13852function opt_AST_Lambda(self, compressor) {
13853 tighten_body(self.body, compressor);
13854 if (compressor.option("side_effects")
13855 && self.body.length == 1
13856 && self.body[0] === compressor.has_directive("use strict")) {
13857 self.body.length = 0;
13858 }
13859 return self;
13860}
13861def_optimize(AST_Lambda, opt_AST_Lambda);
13862
13863const r_keep_assign = /keep_assign/;
13864AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
13865 if (!compressor.option("unused")) return;
13866 if (compressor.has_directive("use asm")) return;
13867 var self = this;
13868 if (self.pinned()) return;
13869 var drop_funcs = !(self instanceof AST_Toplevel) || compressor.toplevel.funcs;
13870 var drop_vars = !(self instanceof AST_Toplevel) || compressor.toplevel.vars;
13871 const assign_as_unused = r_keep_assign.test(compressor.option("unused")) ? return_false : function(node) {
13872 if (node instanceof AST_Assign
13873 && (has_flag(node, WRITE_ONLY) || node.operator == "=")
13874 ) {
13875 return node.left;
13876 }
13877 if (node instanceof AST_Unary && has_flag(node, WRITE_ONLY)) {
13878 return node.expression;
13879 }
13880 };
13881 var in_use_ids = new Map();
13882 var fixed_ids = new Map();
13883 if (self instanceof AST_Toplevel && compressor.top_retain) {
13884 self.variables.forEach(function(def) {
13885 if (compressor.top_retain(def) && !in_use_ids.has(def.id)) {
13886 in_use_ids.set(def.id, def);
13887 }
13888 });
13889 }
13890 var var_defs_by_id = new Map();
13891 var initializations = new Map();
13892 // pass 1: find out which symbols are directly used in
13893 // this scope (not in nested scopes).
13894 var scope = this;
13895 var tw = new TreeWalker(function(node, descend) {
13896 if (node instanceof AST_Lambda && node.uses_arguments && !tw.has_directive("use strict")) {
13897 node.argnames.forEach(function(argname) {
13898 if (!(argname instanceof AST_SymbolDeclaration)) return;
13899 var def = argname.definition();
13900 if (!in_use_ids.has(def.id)) {
13901 in_use_ids.set(def.id, def);
13902 }
13903 });
13904 }
13905 if (node === self) return;
13906 if (node instanceof AST_Defun || node instanceof AST_DefClass) {
13907 var node_def = node.name.definition();
13908 const in_export = tw.parent() instanceof AST_Export;
13909 if (in_export || !drop_funcs && scope === self) {
13910 if (node_def.global && !in_use_ids.has(node_def.id)) {
13911 in_use_ids.set(node_def.id, node_def);
13912 }
13913 }
13914 if (node instanceof AST_DefClass) {
13915 if (
13916 node.extends
13917 && (node.extends.has_side_effects(compressor)
13918 || node.extends.may_throw(compressor))
13919 ) {
13920 node.extends.walk(tw);
13921 }
13922 for (const prop of node.properties) {
13923 if (
13924 prop.has_side_effects(compressor) ||
13925 prop.may_throw(compressor)
13926 ) {
13927 prop.walk(tw);
13928 }
13929 }
13930 }
13931 map_add(initializations, node_def.id, node);
13932 return true; // don't go in nested scopes
13933 }
13934 if (node instanceof AST_SymbolFunarg && scope === self) {
13935 map_add(var_defs_by_id, node.definition().id, node);
13936 }
13937 if (node instanceof AST_Definitions && scope === self) {
13938 const in_export = tw.parent() instanceof AST_Export;
13939 node.definitions.forEach(function(def) {
13940 if (def.name instanceof AST_SymbolVar) {
13941 map_add(var_defs_by_id, def.name.definition().id, def);
13942 }
13943 if (in_export || !drop_vars) {
13944 walk(def.name, node => {
13945 if (node instanceof AST_SymbolDeclaration) {
13946 const def = node.definition();
13947 if (
13948 (in_export || def.global)
13949 && !in_use_ids.has(def.id)
13950 ) {
13951 in_use_ids.set(def.id, def);
13952 }
13953 }
13954 });
13955 }
13956 if (def.value) {
13957 if (def.name instanceof AST_Destructuring) {
13958 def.walk(tw);
13959 } else {
13960 var node_def = def.name.definition();
13961 map_add(initializations, node_def.id, def.value);
13962 if (!node_def.chained && def.name.fixed_value() === def.value) {
13963 fixed_ids.set(node_def.id, def);
13964 }
13965 }
13966 if (def.value.has_side_effects(compressor)) {
13967 def.value.walk(tw);
13968 }
13969 }
13970 });
13971 return true;
13972 }
13973 return scan_ref_scoped(node, descend);
13974 });
13975 self.walk(tw);
13976 // pass 2: for every used symbol we need to walk its
13977 // initialization code to figure out if it uses other
13978 // symbols (that may not be in_use).
13979 tw = new TreeWalker(scan_ref_scoped);
13980 in_use_ids.forEach(function (def) {
13981 var init = initializations.get(def.id);
13982 if (init) init.forEach(function(init) {
13983 init.walk(tw);
13984 });
13985 });
13986 // pass 3: we should drop declarations not in_use
13987 var tt = new TreeTransformer(
13988 function before(node, descend, in_list) {
13989 var parent = tt.parent();
13990 if (drop_vars) {
13991 const sym = assign_as_unused(node);
13992 if (sym instanceof AST_SymbolRef) {
13993 var def = sym.definition();
13994 var in_use = in_use_ids.has(def.id);
13995 if (node instanceof AST_Assign) {
13996 if (!in_use || fixed_ids.has(def.id) && fixed_ids.get(def.id) !== node) {
13997 return maintain_this_binding(parent, node, node.right.transform(tt));
13998 }
13999 } else if (!in_use) return in_list ? MAP.skip : make_node(AST_Number, node, {
14000 value: 0
14001 });
14002 }
14003 }
14004 if (scope !== self) return;
14005 var def;
14006 if (node.name
14007 && (node instanceof AST_ClassExpression
14008 && !keep_name(compressor.option("keep_classnames"), (def = node.name.definition()).name)
14009 || node instanceof AST_Function
14010 && !keep_name(compressor.option("keep_fnames"), (def = node.name.definition()).name))) {
14011 // any declarations with same name will overshadow
14012 // name of this anonymous function and can therefore
14013 // never be used anywhere
14014 if (!in_use_ids.has(def.id) || def.orig.length > 1) node.name = null;
14015 }
14016 if (node instanceof AST_Lambda && !(node instanceof AST_Accessor)) {
14017 var trim = !compressor.option("keep_fargs");
14018 for (var a = node.argnames, i = a.length; --i >= 0;) {
14019 var sym = a[i];
14020 if (sym instanceof AST_Expansion) {
14021 sym = sym.expression;
14022 }
14023 if (sym instanceof AST_DefaultAssign) {
14024 sym = sym.left;
14025 }
14026 // Do not drop destructuring arguments.
14027 // They constitute a type assertion, so dropping
14028 // them would stop that TypeError which would happen
14029 // if someone called it with an incorrectly formatted
14030 // parameter.
14031 if (!(sym instanceof AST_Destructuring) && !in_use_ids.has(sym.definition().id)) {
14032 set_flag(sym, UNUSED);
14033 if (trim) {
14034 a.pop();
14035 }
14036 } else {
14037 trim = false;
14038 }
14039 }
14040 }
14041 if ((node instanceof AST_Defun || node instanceof AST_DefClass) && node !== self) {
14042 const def = node.name.definition();
14043 let keep = def.global && !drop_funcs || in_use_ids.has(def.id);
14044 if (!keep) {
14045 def.eliminated++;
14046 if (node instanceof AST_DefClass) {
14047 // Classes might have extends with side effects
14048 const side_effects = node.drop_side_effect_free(compressor);
14049 if (side_effects) {
14050 return make_node(AST_SimpleStatement, node, {
14051 body: side_effects
14052 });
14053 }
14054 }
14055 return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
14056 }
14057 }
14058 if (node instanceof AST_Definitions && !(parent instanceof AST_ForIn && parent.init === node)) {
14059 var drop_block = !(parent instanceof AST_Toplevel) && !(node instanceof AST_Var);
14060 // place uninitialized names at the start
14061 var body = [], head = [], tail = [];
14062 // for unused names whose initialization has
14063 // side effects, we can cascade the init. code
14064 // into the next one, or next statement.
14065 var side_effects = [];
14066 node.definitions.forEach(function(def) {
14067 if (def.value) def.value = def.value.transform(tt);
14068 var is_destructure = def.name instanceof AST_Destructuring;
14069 var sym = is_destructure
14070 ? new SymbolDef(null, { name: "<destructure>" }) /* fake SymbolDef */
14071 : def.name.definition();
14072 if (drop_block && sym.global) return tail.push(def);
14073 if (!(drop_vars || drop_block)
14074 || is_destructure
14075 && (def.name.names.length
14076 || def.name.is_array
14077 || compressor.option("pure_getters") != true)
14078 || in_use_ids.has(sym.id)
14079 ) {
14080 if (def.value && fixed_ids.has(sym.id) && fixed_ids.get(sym.id) !== def) {
14081 def.value = def.value.drop_side_effect_free(compressor);
14082 }
14083 if (def.name instanceof AST_SymbolVar) {
14084 var var_defs = var_defs_by_id.get(sym.id);
14085 if (var_defs.length > 1 && (!def.value || sym.orig.indexOf(def.name) > sym.eliminated)) {
14086 if (def.value) {
14087 var ref = make_node(AST_SymbolRef, def.name, def.name);
14088 sym.references.push(ref);
14089 var assign = make_node(AST_Assign, def, {
14090 operator: "=",
14091 left: ref,
14092 right: def.value
14093 });
14094 if (fixed_ids.get(sym.id) === def) {
14095 fixed_ids.set(sym.id, assign);
14096 }
14097 side_effects.push(assign.transform(tt));
14098 }
14099 remove(var_defs, def);
14100 sym.eliminated++;
14101 return;
14102 }
14103 }
14104 if (def.value) {
14105 if (side_effects.length > 0) {
14106 if (tail.length > 0) {
14107 side_effects.push(def.value);
14108 def.value = make_sequence(def.value, side_effects);
14109 } else {
14110 body.push(make_node(AST_SimpleStatement, node, {
14111 body: make_sequence(node, side_effects)
14112 }));
14113 }
14114 side_effects = [];
14115 }
14116 tail.push(def);
14117 } else {
14118 head.push(def);
14119 }
14120 } else if (sym.orig[0] instanceof AST_SymbolCatch) {
14121 var value = def.value && def.value.drop_side_effect_free(compressor);
14122 if (value) side_effects.push(value);
14123 def.value = null;
14124 head.push(def);
14125 } else {
14126 var value = def.value && def.value.drop_side_effect_free(compressor);
14127 if (value) {
14128 side_effects.push(value);
14129 }
14130 sym.eliminated++;
14131 }
14132 });
14133 if (head.length > 0 || tail.length > 0) {
14134 node.definitions = head.concat(tail);
14135 body.push(node);
14136 }
14137 if (side_effects.length > 0) {
14138 body.push(make_node(AST_SimpleStatement, node, {
14139 body: make_sequence(node, side_effects)
14140 }));
14141 }
14142 switch (body.length) {
14143 case 0:
14144 return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
14145 case 1:
14146 return body[0];
14147 default:
14148 return in_list ? MAP.splice(body) : make_node(AST_BlockStatement, node, {
14149 body: body
14150 });
14151 }
14152 }
14153 // certain combination of unused name + side effect leads to:
14154 // https://github.com/mishoo/UglifyJS2/issues/44
14155 // https://github.com/mishoo/UglifyJS2/issues/1830
14156 // https://github.com/mishoo/UglifyJS2/issues/1838
14157 // that's an invalid AST.
14158 // We fix it at this stage by moving the `var` outside the `for`.
14159 if (node instanceof AST_For) {
14160 descend(node, this);
14161 var block;
14162 if (node.init instanceof AST_BlockStatement) {
14163 block = node.init;
14164 node.init = block.body.pop();
14165 block.body.push(node);
14166 }
14167 if (node.init instanceof AST_SimpleStatement) {
14168 node.init = node.init.body;
14169 } else if (is_empty(node.init)) {
14170 node.init = null;
14171 }
14172 return !block ? node : in_list ? MAP.splice(block.body) : block;
14173 }
14174 if (node instanceof AST_LabeledStatement
14175 && node.body instanceof AST_For
14176 ) {
14177 descend(node, this);
14178 if (node.body instanceof AST_BlockStatement) {
14179 var block = node.body;
14180 node.body = block.body.pop();
14181 block.body.push(node);
14182 return in_list ? MAP.splice(block.body) : block;
14183 }
14184 return node;
14185 }
14186 if (node instanceof AST_BlockStatement) {
14187 descend(node, this);
14188 if (in_list && node.body.every(can_be_evicted_from_block)) {
14189 return MAP.splice(node.body);
14190 }
14191 return node;
14192 }
14193 if (node instanceof AST_Scope) {
14194 const save_scope = scope;
14195 scope = node;
14196 descend(node, this);
14197 scope = save_scope;
14198 return node;
14199 }
14200 }
14201 );
14202
14203 self.transform(tt);
14204
14205 function scan_ref_scoped(node, descend) {
14206 var node_def;
14207 const sym = assign_as_unused(node);
14208 if (sym instanceof AST_SymbolRef
14209 && !is_ref_of(node.left, AST_SymbolBlockDeclaration)
14210 && self.variables.get(sym.name) === (node_def = sym.definition())
14211 ) {
14212 if (node instanceof AST_Assign) {
14213 node.right.walk(tw);
14214 if (!node_def.chained && node.left.fixed_value() === node.right) {
14215 fixed_ids.set(node_def.id, node);
14216 }
14217 }
14218 return true;
14219 }
14220 if (node instanceof AST_SymbolRef) {
14221 node_def = node.definition();
14222 if (!in_use_ids.has(node_def.id)) {
14223 in_use_ids.set(node_def.id, node_def);
14224 if (node_def.orig[0] instanceof AST_SymbolCatch) {
14225 const redef = node_def.scope.is_block_scope()
14226 && node_def.scope.get_defun_scope().variables.get(node_def.name);
14227 if (redef) in_use_ids.set(redef.id, redef);
14228 }
14229 }
14230 return true;
14231 }
14232 if (node instanceof AST_Scope) {
14233 var save_scope = scope;
14234 scope = node;
14235 descend();
14236 scope = save_scope;
14237 return true;
14238 }
14239 }
14240});
14241
14242AST_Scope.DEFMETHOD("hoist_declarations", function(compressor) {
14243 var self = this;
14244 if (compressor.has_directive("use asm")) return self;
14245 // Hoisting makes no sense in an arrow func
14246 if (!Array.isArray(self.body)) return self;
14247
14248 var hoist_funs = compressor.option("hoist_funs");
14249 var hoist_vars = compressor.option("hoist_vars");
14250
14251 if (hoist_funs || hoist_vars) {
14252 var dirs = [];
14253 var hoisted = [];
14254 var vars = new Map(), vars_found = 0, var_decl = 0;
14255 // let's count var_decl first, we seem to waste a lot of
14256 // space if we hoist `var` when there's only one.
14257 walk(self, node => {
14258 if (node instanceof AST_Scope && node !== self)
14259 return true;
14260 if (node instanceof AST_Var) {
14261 ++var_decl;
14262 return true;
14263 }
14264 });
14265 hoist_vars = hoist_vars && var_decl > 1;
14266 var tt = new TreeTransformer(
14267 function before(node) {
14268 if (node !== self) {
14269 if (node instanceof AST_Directive) {
14270 dirs.push(node);
14271 return make_node(AST_EmptyStatement, node);
14272 }
14273 if (hoist_funs && node instanceof AST_Defun
14274 && !(tt.parent() instanceof AST_Export)
14275 && tt.parent() === self) {
14276 hoisted.push(node);
14277 return make_node(AST_EmptyStatement, node);
14278 }
14279 if (
14280 hoist_vars
14281 && node instanceof AST_Var
14282 && !node.definitions.some(def => def.name instanceof AST_Destructuring)
14283 ) {
14284 node.definitions.forEach(function(def) {
14285 vars.set(def.name.name, def);
14286 ++vars_found;
14287 });
14288 var seq = node.to_assignments(compressor);
14289 var p = tt.parent();
14290 if (p instanceof AST_ForIn && p.init === node) {
14291 if (seq == null) {
14292 var def = node.definitions[0].name;
14293 return make_node(AST_SymbolRef, def, def);
14294 }
14295 return seq;
14296 }
14297 if (p instanceof AST_For && p.init === node) {
14298 return seq;
14299 }
14300 if (!seq) return make_node(AST_EmptyStatement, node);
14301 return make_node(AST_SimpleStatement, node, {
14302 body: seq
14303 });
14304 }
14305 if (node instanceof AST_Scope)
14306 return node; // to avoid descending in nested scopes
14307 }
14308 }
14309 );
14310 self = self.transform(tt);
14311 if (vars_found > 0) {
14312 // collect only vars which don't show up in self's arguments list
14313 var defs = [];
14314 const is_lambda = self instanceof AST_Lambda;
14315 const args_as_names = is_lambda ? self.args_as_names() : null;
14316 vars.forEach((def, name) => {
14317 if (is_lambda && args_as_names.some((x) => x.name === def.name.name)) {
14318 vars.delete(name);
14319 } else {
14320 def = def.clone();
14321 def.value = null;
14322 defs.push(def);
14323 vars.set(name, def);
14324 }
14325 });
14326 if (defs.length > 0) {
14327 // try to merge in assignments
14328 for (var i = 0; i < self.body.length;) {
14329 if (self.body[i] instanceof AST_SimpleStatement) {
14330 var expr = self.body[i].body, sym, assign;
14331 if (expr instanceof AST_Assign
14332 && expr.operator == "="
14333 && (sym = expr.left) instanceof AST_Symbol
14334 && vars.has(sym.name)
14335 ) {
14336 var def = vars.get(sym.name);
14337 if (def.value) break;
14338 def.value = expr.right;
14339 remove(defs, def);
14340 defs.push(def);
14341 self.body.splice(i, 1);
14342 continue;
14343 }
14344 if (expr instanceof AST_Sequence
14345 && (assign = expr.expressions[0]) instanceof AST_Assign
14346 && assign.operator == "="
14347 && (sym = assign.left) instanceof AST_Symbol
14348 && vars.has(sym.name)
14349 ) {
14350 var def = vars.get(sym.name);
14351 if (def.value) break;
14352 def.value = assign.right;
14353 remove(defs, def);
14354 defs.push(def);
14355 self.body[i].body = make_sequence(expr, expr.expressions.slice(1));
14356 continue;
14357 }
14358 }
14359 if (self.body[i] instanceof AST_EmptyStatement) {
14360 self.body.splice(i, 1);
14361 continue;
14362 }
14363 if (self.body[i] instanceof AST_BlockStatement) {
14364 self.body.splice(i, 1, ...self.body[i].body);
14365 continue;
14366 }
14367 break;
14368 }
14369 defs = make_node(AST_Var, self, {
14370 definitions: defs
14371 });
14372 hoisted.push(defs);
14373 }
14374 }
14375 self.body = dirs.concat(hoisted, self.body);
14376 }
14377 return self;
14378});
14379
14380AST_Scope.DEFMETHOD("hoist_properties", function(compressor) {
14381 var self = this;
14382 if (!compressor.option("hoist_props") || compressor.has_directive("use asm")) return self;
14383 var top_retain = self instanceof AST_Toplevel && compressor.top_retain || return_false;
14384 var defs_by_id = new Map();
14385 var hoister = new TreeTransformer(function(node, descend) {
14386 if (node instanceof AST_Definitions
14387 && hoister.parent() instanceof AST_Export) return node;
14388 if (node instanceof AST_VarDef) {
14389 const sym = node.name;
14390 let def;
14391 let value;
14392 if (sym.scope === self
14393 && (def = sym.definition()).escaped != 1
14394 && !def.assignments
14395 && !def.direct_access
14396 && !def.single_use
14397 && !compressor.exposed(def)
14398 && !top_retain(def)
14399 && (value = sym.fixed_value()) === node.value
14400 && value instanceof AST_Object
14401 && !value.properties.some(prop =>
14402 prop instanceof AST_Expansion || prop.computed_key()
14403 )
14404 ) {
14405 descend(node, this);
14406 const defs = new Map();
14407 const assignments = [];
14408 value.properties.forEach(({ key, value }) => {
14409 const scope = find_scope(hoister);
14410 const symbol = self.create_symbol(sym.CTOR, {
14411 source: sym,
14412 scope,
14413 conflict_scopes: new Set([
14414 scope,
14415 ...sym.definition().references.map(ref => ref.scope)
14416 ]),
14417 tentative_name: sym.name + "_" + key
14418 });
14419
14420 defs.set(String(key), symbol.definition());
14421
14422 assignments.push(make_node(AST_VarDef, node, {
14423 name: symbol,
14424 value
14425 }));
14426 });
14427 defs_by_id.set(def.id, defs);
14428 return MAP.splice(assignments);
14429 }
14430 } else if (node instanceof AST_PropAccess
14431 && node.expression instanceof AST_SymbolRef
14432 ) {
14433 const defs = defs_by_id.get(node.expression.definition().id);
14434 if (defs) {
14435 const def = defs.get(String(get_value(node.property)));
14436 const sym = make_node(AST_SymbolRef, node, {
14437 name: def.name,
14438 scope: node.expression.scope,
14439 thedef: def
14440 });
14441 sym.reference({});
14442 return sym;
14443 }
14444 }
14445 });
14446 return self.transform(hoister);
14447});
14448
14449// drop_side_effect_free()
14450// remove side-effect-free parts which only affects return value
14451(function(def_drop_side_effect_free) {
14452 // Drop side-effect-free elements from an array of expressions.
14453 // Returns an array of expressions with side-effects or null
14454 // if all elements were dropped. Note: original array may be
14455 // returned if nothing changed.
14456 function trim(nodes, compressor, first_in_statement) {
14457 var len = nodes.length;
14458 if (!len) return null;
14459 var ret = [], changed = false;
14460 for (var i = 0; i < len; i++) {
14461 var node = nodes[i].drop_side_effect_free(compressor, first_in_statement);
14462 changed |= node !== nodes[i];
14463 if (node) {
14464 ret.push(node);
14465 first_in_statement = false;
14466 }
14467 }
14468 return changed ? ret.length ? ret : null : nodes;
14469 }
14470
14471 def_drop_side_effect_free(AST_Node, return_this);
14472 def_drop_side_effect_free(AST_Constant, return_null);
14473 def_drop_side_effect_free(AST_This, return_null);
14474 def_drop_side_effect_free(AST_Call, function(compressor, first_in_statement) {
14475 if (this.optional && is_nullish(this.expression)) {
14476 return make_node(AST_Undefined, this);
14477 }
14478
14479 if (!this.is_expr_pure(compressor)) {
14480 if (this.expression.is_call_pure(compressor)) {
14481 var exprs = this.args.slice();
14482 exprs.unshift(this.expression.expression);
14483 exprs = trim(exprs, compressor, first_in_statement);
14484 return exprs && make_sequence(this, exprs);
14485 }
14486 if (is_func_expr(this.expression)
14487 && (!this.expression.name || !this.expression.name.definition().references.length)) {
14488 var node = this.clone();
14489 node.expression.process_expression(false, compressor);
14490 return node;
14491 }
14492 return this;
14493 }
14494 var args = trim(this.args, compressor, first_in_statement);
14495 return args && make_sequence(this, args);
14496 });
14497 def_drop_side_effect_free(AST_Accessor, return_null);
14498 def_drop_side_effect_free(AST_Function, return_null);
14499 def_drop_side_effect_free(AST_Arrow, return_null);
14500 def_drop_side_effect_free(AST_Class, function (compressor) {
14501 const with_effects = [];
14502 const trimmed_extends = this.extends && this.extends.drop_side_effect_free(compressor);
14503 if (trimmed_extends) with_effects.push(trimmed_extends);
14504 for (const prop of this.properties) {
14505 const trimmed_prop = prop.drop_side_effect_free(compressor);
14506 if (trimmed_prop) with_effects.push(trimmed_prop);
14507 }
14508 if (!with_effects.length) return null;
14509 return make_sequence(this, with_effects);
14510 });
14511 def_drop_side_effect_free(AST_Binary, function(compressor, first_in_statement) {
14512 var right = this.right.drop_side_effect_free(compressor);
14513 if (!right) return this.left.drop_side_effect_free(compressor, first_in_statement);
14514 if (lazy_op.has(this.operator)) {
14515 if (right === this.right) return this;
14516 var node = this.clone();
14517 node.right = right;
14518 return node;
14519 } else {
14520 var left = this.left.drop_side_effect_free(compressor, first_in_statement);
14521 if (!left) return this.right.drop_side_effect_free(compressor, first_in_statement);
14522 return make_sequence(this, [ left, right ]);
14523 }
14524 });
14525 def_drop_side_effect_free(AST_Assign, function(compressor) {
14526 var left = this.left;
14527 if (left.has_side_effects(compressor)
14528 || compressor.has_directive("use strict")
14529 && left instanceof AST_PropAccess
14530 && left.expression.is_constant()) {
14531 return this;
14532 }
14533 set_flag(this, WRITE_ONLY);
14534 while (left instanceof AST_PropAccess) {
14535 left = left.expression;
14536 }
14537 if (left.is_constant_expression(compressor.find_parent(AST_Scope))) {
14538 return this.right.drop_side_effect_free(compressor);
14539 }
14540 return this;
14541 });
14542 def_drop_side_effect_free(AST_Conditional, function(compressor) {
14543 var consequent = this.consequent.drop_side_effect_free(compressor);
14544 var alternative = this.alternative.drop_side_effect_free(compressor);
14545 if (consequent === this.consequent && alternative === this.alternative) return this;
14546 if (!consequent) return alternative ? make_node(AST_Binary, this, {
14547 operator: "||",
14548 left: this.condition,
14549 right: alternative
14550 }) : this.condition.drop_side_effect_free(compressor);
14551 if (!alternative) return make_node(AST_Binary, this, {
14552 operator: "&&",
14553 left: this.condition,
14554 right: consequent
14555 });
14556 var node = this.clone();
14557 node.consequent = consequent;
14558 node.alternative = alternative;
14559 return node;
14560 });
14561 def_drop_side_effect_free(AST_Unary, function(compressor, first_in_statement) {
14562 if (unary_side_effects.has(this.operator)) {
14563 if (!this.expression.has_side_effects(compressor)) {
14564 set_flag(this, WRITE_ONLY);
14565 } else {
14566 clear_flag(this, WRITE_ONLY);
14567 }
14568 return this;
14569 }
14570 if (this.operator == "typeof" && this.expression instanceof AST_SymbolRef) return null;
14571 var expression = this.expression.drop_side_effect_free(compressor, first_in_statement);
14572 if (first_in_statement && expression && is_iife_call(expression)) {
14573 if (expression === this.expression && this.operator == "!") return this;
14574 return expression.negate(compressor, first_in_statement);
14575 }
14576 return expression;
14577 });
14578 def_drop_side_effect_free(AST_SymbolRef, function(compressor) {
14579 const safe_access = this.is_declared(compressor)
14580 || pure_prop_access_globals.has(this.name);
14581 return safe_access ? null : this;
14582 });
14583 def_drop_side_effect_free(AST_Object, function(compressor, first_in_statement) {
14584 var values = trim(this.properties, compressor, first_in_statement);
14585 return values && make_sequence(this, values);
14586 });
14587 def_drop_side_effect_free(AST_ObjectProperty, function(compressor, first_in_statement) {
14588 const computed_key = this instanceof AST_ObjectKeyVal && this.key instanceof AST_Node;
14589 const key = computed_key && this.key.drop_side_effect_free(compressor, first_in_statement);
14590 const value = this.value.drop_side_effect_free(compressor, first_in_statement);
14591 if (key && value) {
14592 return make_sequence(this, [key, value]);
14593 }
14594 return key || value;
14595 });
14596 def_drop_side_effect_free(AST_ClassProperty, function (compressor) {
14597 const key = this.computed_key() && this.key.drop_side_effect_free(compressor);
14598
14599 const value = this.static && this.value
14600 && this.value.drop_side_effect_free(compressor);
14601
14602 if (key && value) return make_sequence(this, [key, value]);
14603 return key || value || null;
14604 });
14605 def_drop_side_effect_free(AST_ConciseMethod, function () {
14606 return this.computed_key() ? this.key : null;
14607 });
14608 def_drop_side_effect_free(AST_ObjectGetter, function () {
14609 return this.computed_key() ? this.key : null;
14610 });
14611 def_drop_side_effect_free(AST_ObjectSetter, function () {
14612 return this.computed_key() ? this.key : null;
14613 });
14614 def_drop_side_effect_free(AST_Array, function(compressor, first_in_statement) {
14615 var values = trim(this.elements, compressor, first_in_statement);
14616 return values && make_sequence(this, values);
14617 });
14618 def_drop_side_effect_free(AST_Dot, function(compressor, first_in_statement) {
14619 if (this.optional) {
14620 return is_nullish(this.expression) ? make_node(AST_Undefined, this) : this;
14621 }
14622 if (this.expression.may_throw_on_access(compressor)) return this;
14623
14624 return this.expression.drop_side_effect_free(compressor, first_in_statement);
14625 });
14626 def_drop_side_effect_free(AST_Sub, function(compressor, first_in_statement) {
14627 if (this.optional) {
14628 return is_nullish(this.expression) ? make_node(AST_Undefined, this): this;
14629 }
14630 if (this.expression.may_throw_on_access(compressor)) return this;
14631
14632 var expression = this.expression.drop_side_effect_free(compressor, first_in_statement);
14633 if (!expression) return this.property.drop_side_effect_free(compressor, first_in_statement);
14634 var property = this.property.drop_side_effect_free(compressor);
14635 if (!property) return expression;
14636 return make_sequence(this, [ expression, property ]);
14637 });
14638 def_drop_side_effect_free(AST_Chain, function (compressor, first_in_statement) {
14639 return this.expression.drop_side_effect_free(compressor, first_in_statement);
14640 });
14641 def_drop_side_effect_free(AST_Sequence, function(compressor) {
14642 var last = this.tail_node();
14643 var expr = last.drop_side_effect_free(compressor);
14644 if (expr === last) return this;
14645 var expressions = this.expressions.slice(0, -1);
14646 if (expr) expressions.push(expr);
14647 if (!expressions.length) {
14648 return make_node(AST_Number, this, { value: 0 });
14649 }
14650 return make_sequence(this, expressions);
14651 });
14652 def_drop_side_effect_free(AST_Expansion, function(compressor, first_in_statement) {
14653 return this.expression.drop_side_effect_free(compressor, first_in_statement);
14654 });
14655 def_drop_side_effect_free(AST_TemplateSegment, return_null);
14656 def_drop_side_effect_free(AST_TemplateString, function(compressor) {
14657 var values = trim(this.segments, compressor, first_in_statement);
14658 return values && make_sequence(this, values);
14659 });
14660})(function(node, func) {
14661 node.DEFMETHOD("drop_side_effect_free", func);
14662});
14663
14664def_optimize(AST_SimpleStatement, function(self, compressor) {
14665 if (compressor.option("side_effects")) {
14666 var body = self.body;
14667 var node = body.drop_side_effect_free(compressor, true);
14668 if (!node) {
14669 return make_node(AST_EmptyStatement, self);
14670 }
14671 if (node !== body) {
14672 return make_node(AST_SimpleStatement, self, { body: node });
14673 }
14674 }
14675 return self;
14676});
14677
14678def_optimize(AST_While, function(self, compressor) {
14679 return compressor.option("loops") ? make_node(AST_For, self, self).optimize(compressor) : self;
14680});
14681
14682function has_break_or_continue(loop, parent) {
14683 var found = false;
14684 var tw = new TreeWalker(function(node) {
14685 if (found || node instanceof AST_Scope) return true;
14686 if (node instanceof AST_LoopControl && tw.loopcontrol_target(node) === loop) {
14687 return found = true;
14688 }
14689 });
14690 if (parent instanceof AST_LabeledStatement) tw.push(parent);
14691 tw.push(loop);
14692 loop.body.walk(tw);
14693 return found;
14694}
14695
14696def_optimize(AST_Do, function(self, compressor) {
14697 if (!compressor.option("loops")) return self;
14698 var cond = self.condition.tail_node().evaluate(compressor);
14699 if (!(cond instanceof AST_Node)) {
14700 if (cond) return make_node(AST_For, self, {
14701 body: make_node(AST_BlockStatement, self.body, {
14702 body: [
14703 self.body,
14704 make_node(AST_SimpleStatement, self.condition, {
14705 body: self.condition
14706 })
14707 ]
14708 })
14709 }).optimize(compressor);
14710 if (!has_break_or_continue(self, compressor.parent())) {
14711 return make_node(AST_BlockStatement, self.body, {
14712 body: [
14713 self.body,
14714 make_node(AST_SimpleStatement, self.condition, {
14715 body: self.condition
14716 })
14717 ]
14718 }).optimize(compressor);
14719 }
14720 }
14721 return self;
14722});
14723
14724function if_break_in_loop(self, compressor) {
14725 var first = self.body instanceof AST_BlockStatement ? self.body.body[0] : self.body;
14726 if (compressor.option("dead_code") && is_break(first)) {
14727 var body = [];
14728 if (self.init instanceof AST_Statement) {
14729 body.push(self.init);
14730 } else if (self.init) {
14731 body.push(make_node(AST_SimpleStatement, self.init, {
14732 body: self.init
14733 }));
14734 }
14735 if (self.condition) {
14736 body.push(make_node(AST_SimpleStatement, self.condition, {
14737 body: self.condition
14738 }));
14739 }
14740 trim_unreachable_code(compressor, self.body, body);
14741 return make_node(AST_BlockStatement, self, {
14742 body: body
14743 });
14744 }
14745 if (first instanceof AST_If) {
14746 if (is_break(first.body)) {
14747 if (self.condition) {
14748 self.condition = make_node(AST_Binary, self.condition, {
14749 left: self.condition,
14750 operator: "&&",
14751 right: first.condition.negate(compressor),
14752 });
14753 } else {
14754 self.condition = first.condition.negate(compressor);
14755 }
14756 drop_it(first.alternative);
14757 } else if (is_break(first.alternative)) {
14758 if (self.condition) {
14759 self.condition = make_node(AST_Binary, self.condition, {
14760 left: self.condition,
14761 operator: "&&",
14762 right: first.condition,
14763 });
14764 } else {
14765 self.condition = first.condition;
14766 }
14767 drop_it(first.body);
14768 }
14769 }
14770 return self;
14771
14772 function is_break(node) {
14773 return node instanceof AST_Break
14774 && compressor.loopcontrol_target(node) === compressor.self();
14775 }
14776
14777 function drop_it(rest) {
14778 rest = as_statement_array(rest);
14779 if (self.body instanceof AST_BlockStatement) {
14780 self.body = self.body.clone();
14781 self.body.body = rest.concat(self.body.body.slice(1));
14782 self.body = self.body.transform(compressor);
14783 } else {
14784 self.body = make_node(AST_BlockStatement, self.body, {
14785 body: rest
14786 }).transform(compressor);
14787 }
14788 self = if_break_in_loop(self, compressor);
14789 }
14790}
14791
14792def_optimize(AST_For, function(self, compressor) {
14793 if (!compressor.option("loops")) return self;
14794 if (compressor.option("side_effects") && self.init) {
14795 self.init = self.init.drop_side_effect_free(compressor);
14796 }
14797 if (self.condition) {
14798 var cond = self.condition.evaluate(compressor);
14799 if (!(cond instanceof AST_Node)) {
14800 if (cond) self.condition = null;
14801 else if (!compressor.option("dead_code")) {
14802 var orig = self.condition;
14803 self.condition = make_node_from_constant(cond, self.condition);
14804 self.condition = best_of_expression(self.condition.transform(compressor), orig);
14805 }
14806 }
14807 if (compressor.option("dead_code")) {
14808 if (cond instanceof AST_Node) cond = self.condition.tail_node().evaluate(compressor);
14809 if (!cond) {
14810 var body = [];
14811 trim_unreachable_code(compressor, self.body, body);
14812 if (self.init instanceof AST_Statement) {
14813 body.push(self.init);
14814 } else if (self.init) {
14815 body.push(make_node(AST_SimpleStatement, self.init, {
14816 body: self.init
14817 }));
14818 }
14819 body.push(make_node(AST_SimpleStatement, self.condition, {
14820 body: self.condition
14821 }));
14822 return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor);
14823 }
14824 }
14825 }
14826 return if_break_in_loop(self, compressor);
14827});
14828
14829def_optimize(AST_If, function(self, compressor) {
14830 if (is_empty(self.alternative)) self.alternative = null;
14831
14832 if (!compressor.option("conditionals")) return self;
14833 // if condition can be statically determined, drop
14834 // one of the blocks. note, statically determined implies
14835 // “has no side effects”; also it doesn't work for cases like
14836 // `x && true`, though it probably should.
14837 var cond = self.condition.evaluate(compressor);
14838 if (!compressor.option("dead_code") && !(cond instanceof AST_Node)) {
14839 var orig = self.condition;
14840 self.condition = make_node_from_constant(cond, orig);
14841 self.condition = best_of_expression(self.condition.transform(compressor), orig);
14842 }
14843 if (compressor.option("dead_code")) {
14844 if (cond instanceof AST_Node) cond = self.condition.tail_node().evaluate(compressor);
14845 if (!cond) {
14846 var body = [];
14847 trim_unreachable_code(compressor, self.body, body);
14848 body.push(make_node(AST_SimpleStatement, self.condition, {
14849 body: self.condition
14850 }));
14851 if (self.alternative) body.push(self.alternative);
14852 return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor);
14853 } else if (!(cond instanceof AST_Node)) {
14854 var body = [];
14855 body.push(make_node(AST_SimpleStatement, self.condition, {
14856 body: self.condition
14857 }));
14858 body.push(self.body);
14859 if (self.alternative) {
14860 trim_unreachable_code(compressor, self.alternative, body);
14861 }
14862 return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor);
14863 }
14864 }
14865 var negated = self.condition.negate(compressor);
14866 var self_condition_length = self.condition.size();
14867 var negated_length = negated.size();
14868 var negated_is_best = negated_length < self_condition_length;
14869 if (self.alternative && negated_is_best) {
14870 negated_is_best = false; // because we already do the switch here.
14871 // no need to swap values of self_condition_length and negated_length
14872 // here because they are only used in an equality comparison later on.
14873 self.condition = negated;
14874 var tmp = self.body;
14875 self.body = self.alternative || make_node(AST_EmptyStatement, self);
14876 self.alternative = tmp;
14877 }
14878 if (is_empty(self.body) && is_empty(self.alternative)) {
14879 return make_node(AST_SimpleStatement, self.condition, {
14880 body: self.condition.clone()
14881 }).optimize(compressor);
14882 }
14883 if (self.body instanceof AST_SimpleStatement
14884 && self.alternative instanceof AST_SimpleStatement) {
14885 return make_node(AST_SimpleStatement, self, {
14886 body: make_node(AST_Conditional, self, {
14887 condition : self.condition,
14888 consequent : self.body.body,
14889 alternative : self.alternative.body
14890 })
14891 }).optimize(compressor);
14892 }
14893 if (is_empty(self.alternative) && self.body instanceof AST_SimpleStatement) {
14894 if (self_condition_length === negated_length && !negated_is_best
14895 && self.condition instanceof AST_Binary && self.condition.operator == "||") {
14896 // although the code length of self.condition and negated are the same,
14897 // negated does not require additional surrounding parentheses.
14898 // see https://github.com/mishoo/UglifyJS2/issues/979
14899 negated_is_best = true;
14900 }
14901 if (negated_is_best) return make_node(AST_SimpleStatement, self, {
14902 body: make_node(AST_Binary, self, {
14903 operator : "||",
14904 left : negated,
14905 right : self.body.body
14906 })
14907 }).optimize(compressor);
14908 return make_node(AST_SimpleStatement, self, {
14909 body: make_node(AST_Binary, self, {
14910 operator : "&&",
14911 left : self.condition,
14912 right : self.body.body
14913 })
14914 }).optimize(compressor);
14915 }
14916 if (self.body instanceof AST_EmptyStatement
14917 && self.alternative instanceof AST_SimpleStatement) {
14918 return make_node(AST_SimpleStatement, self, {
14919 body: make_node(AST_Binary, self, {
14920 operator : "||",
14921 left : self.condition,
14922 right : self.alternative.body
14923 })
14924 }).optimize(compressor);
14925 }
14926 if (self.body instanceof AST_Exit
14927 && self.alternative instanceof AST_Exit
14928 && self.body.TYPE == self.alternative.TYPE) {
14929 return make_node(self.body.CTOR, self, {
14930 value: make_node(AST_Conditional, self, {
14931 condition : self.condition,
14932 consequent : self.body.value || make_node(AST_Undefined, self.body),
14933 alternative : self.alternative.value || make_node(AST_Undefined, self.alternative)
14934 }).transform(compressor)
14935 }).optimize(compressor);
14936 }
14937 if (self.body instanceof AST_If
14938 && !self.body.alternative
14939 && !self.alternative) {
14940 self = make_node(AST_If, self, {
14941 condition: make_node(AST_Binary, self.condition, {
14942 operator: "&&",
14943 left: self.condition,
14944 right: self.body.condition
14945 }),
14946 body: self.body.body,
14947 alternative: null
14948 });
14949 }
14950 if (aborts(self.body)) {
14951 if (self.alternative) {
14952 var alt = self.alternative;
14953 self.alternative = null;
14954 return make_node(AST_BlockStatement, self, {
14955 body: [ self, alt ]
14956 }).optimize(compressor);
14957 }
14958 }
14959 if (aborts(self.alternative)) {
14960 var body = self.body;
14961 self.body = self.alternative;
14962 self.condition = negated_is_best ? negated : self.condition.negate(compressor);
14963 self.alternative = null;
14964 return make_node(AST_BlockStatement, self, {
14965 body: [ self, body ]
14966 }).optimize(compressor);
14967 }
14968 return self;
14969});
14970
14971def_optimize(AST_Switch, function(self, compressor) {
14972 if (!compressor.option("switches")) return self;
14973 var branch;
14974 var value = self.expression.evaluate(compressor);
14975 if (!(value instanceof AST_Node)) {
14976 var orig = self.expression;
14977 self.expression = make_node_from_constant(value, orig);
14978 self.expression = best_of_expression(self.expression.transform(compressor), orig);
14979 }
14980 if (!compressor.option("dead_code")) return self;
14981 if (value instanceof AST_Node) {
14982 value = self.expression.tail_node().evaluate(compressor);
14983 }
14984 var decl = [];
14985 var body = [];
14986 var default_branch;
14987 var exact_match;
14988 for (var i = 0, len = self.body.length; i < len && !exact_match; i++) {
14989 branch = self.body[i];
14990 if (branch instanceof AST_Default) {
14991 if (!default_branch) {
14992 default_branch = branch;
14993 } else {
14994 eliminate_branch(branch, body[body.length - 1]);
14995 }
14996 } else if (!(value instanceof AST_Node)) {
14997 var exp = branch.expression.evaluate(compressor);
14998 if (!(exp instanceof AST_Node) && exp !== value) {
14999 eliminate_branch(branch, body[body.length - 1]);
15000 continue;
15001 }
15002 if (exp instanceof AST_Node) exp = branch.expression.tail_node().evaluate(compressor);
15003 if (exp === value) {
15004 exact_match = branch;
15005 if (default_branch) {
15006 var default_index = body.indexOf(default_branch);
15007 body.splice(default_index, 1);
15008 eliminate_branch(default_branch, body[default_index - 1]);
15009 default_branch = null;
15010 }
15011 }
15012 }
15013 if (aborts(branch)) {
15014 var prev = body[body.length - 1];
15015 if (aborts(prev) && prev.body.length == branch.body.length
15016 && make_node(AST_BlockStatement, prev, prev).equivalent_to(make_node(AST_BlockStatement, branch, branch))) {
15017 prev.body = [];
15018 }
15019 }
15020 body.push(branch);
15021 }
15022 while (i < len) eliminate_branch(self.body[i++], body[body.length - 1]);
15023 if (body.length > 0) {
15024 body[0].body = decl.concat(body[0].body);
15025 }
15026 self.body = body;
15027 while (branch = body[body.length - 1]) {
15028 var stat = branch.body[branch.body.length - 1];
15029 if (stat instanceof AST_Break && compressor.loopcontrol_target(stat) === self)
15030 branch.body.pop();
15031 if (branch.body.length || branch instanceof AST_Case
15032 && (default_branch || branch.expression.has_side_effects(compressor))) break;
15033 if (body.pop() === default_branch) default_branch = null;
15034 }
15035 if (body.length == 0) {
15036 return make_node(AST_BlockStatement, self, {
15037 body: decl.concat(make_node(AST_SimpleStatement, self.expression, {
15038 body: self.expression
15039 }))
15040 }).optimize(compressor);
15041 }
15042 if (body.length == 1 && (body[0] === exact_match || body[0] === default_branch)) {
15043 var has_break = false;
15044 var tw = new TreeWalker(function(node) {
15045 if (has_break
15046 || node instanceof AST_Lambda
15047 || node instanceof AST_SimpleStatement) return true;
15048 if (node instanceof AST_Break && tw.loopcontrol_target(node) === self)
15049 has_break = true;
15050 });
15051 self.walk(tw);
15052 if (!has_break) {
15053 var statements = body[0].body.slice();
15054 var exp = body[0].expression;
15055 if (exp) statements.unshift(make_node(AST_SimpleStatement, exp, {
15056 body: exp
15057 }));
15058 statements.unshift(make_node(AST_SimpleStatement, self.expression, {
15059 body:self.expression
15060 }));
15061 return make_node(AST_BlockStatement, self, {
15062 body: statements
15063 }).optimize(compressor);
15064 }
15065 }
15066 return self;
15067
15068 function eliminate_branch(branch, prev) {
15069 if (prev && !aborts(prev)) {
15070 prev.body = prev.body.concat(branch.body);
15071 } else {
15072 trim_unreachable_code(compressor, branch, decl);
15073 }
15074 }
15075});
15076
15077def_optimize(AST_Try, function(self, compressor) {
15078 tighten_body(self.body, compressor);
15079 if (self.bcatch && self.bfinally && self.bfinally.body.every(is_empty)) self.bfinally = null;
15080 if (compressor.option("dead_code") && self.body.every(is_empty)) {
15081 var body = [];
15082 if (self.bcatch) {
15083 trim_unreachable_code(compressor, self.bcatch, body);
15084 }
15085 if (self.bfinally) body.push(...self.bfinally.body);
15086 return make_node(AST_BlockStatement, self, {
15087 body: body
15088 }).optimize(compressor);
15089 }
15090 return self;
15091});
15092
15093AST_Definitions.DEFMETHOD("remove_initializers", function() {
15094 var decls = [];
15095 this.definitions.forEach(function(def) {
15096 if (def.name instanceof AST_SymbolDeclaration) {
15097 def.value = null;
15098 decls.push(def);
15099 } else {
15100 walk(def.name, node => {
15101 if (node instanceof AST_SymbolDeclaration) {
15102 decls.push(make_node(AST_VarDef, def, {
15103 name: node,
15104 value: null
15105 }));
15106 }
15107 });
15108 }
15109 });
15110 this.definitions = decls;
15111});
15112
15113AST_Definitions.DEFMETHOD("to_assignments", function(compressor) {
15114 var reduce_vars = compressor.option("reduce_vars");
15115 var assignments = [];
15116
15117 for (const def of this.definitions) {
15118 if (def.value) {
15119 var name = make_node(AST_SymbolRef, def.name, def.name);
15120 assignments.push(make_node(AST_Assign, def, {
15121 operator : "=",
15122 left : name,
15123 right : def.value
15124 }));
15125 if (reduce_vars) name.definition().fixed = false;
15126 } else if (def.value) {
15127 // Because it's a destructuring, do not turn into an assignment.
15128 var varDef = make_node(AST_VarDef, def, {
15129 name: def.name,
15130 value: def.value
15131 });
15132 var var_ = make_node(AST_Var, def, {
15133 definitions: [ varDef ]
15134 });
15135 assignments.push(var_);
15136 }
15137 const thedef = def.name.definition();
15138 thedef.eliminated++;
15139 thedef.replaced--;
15140 }
15141
15142 if (assignments.length == 0) return null;
15143 return make_sequence(this, assignments);
15144});
15145
15146def_optimize(AST_Definitions, function(self) {
15147 if (self.definitions.length == 0)
15148 return make_node(AST_EmptyStatement, self);
15149 return self;
15150});
15151
15152def_optimize(AST_Import, function(self) {
15153 return self;
15154});
15155
15156// TODO this only works with AST_Defun, shouldn't it work for other ways of defining functions?
15157function retain_top_func(fn, compressor) {
15158 return compressor.top_retain
15159 && fn instanceof AST_Defun
15160 && has_flag(fn, TOP)
15161 && fn.name
15162 && compressor.top_retain(fn.name);
15163}
15164
15165def_optimize(AST_Call, function(self, compressor) {
15166 var exp = self.expression;
15167 var fn = exp;
15168 inline_array_like_spread(self.args);
15169 var simple_args = self.args.every((arg) =>
15170 !(arg instanceof AST_Expansion)
15171 );
15172
15173 if (compressor.option("reduce_vars")
15174 && fn instanceof AST_SymbolRef
15175 && !has_annotation(self, _NOINLINE)
15176 ) {
15177 const fixed = fn.fixed_value();
15178 if (!retain_top_func(fixed, compressor)) {
15179 fn = fixed;
15180 }
15181 }
15182
15183 if (self.optional && is_nullish(fn)) {
15184 return make_node(AST_Undefined, self);
15185 }
15186
15187 var is_func = fn instanceof AST_Lambda;
15188
15189 if (is_func && fn.pinned()) return self;
15190
15191 if (compressor.option("unused")
15192 && simple_args
15193 && is_func
15194 && !fn.uses_arguments) {
15195 var pos = 0, last = 0;
15196 for (var i = 0, len = self.args.length; i < len; i++) {
15197 if (fn.argnames[i] instanceof AST_Expansion) {
15198 if (has_flag(fn.argnames[i].expression, UNUSED)) while (i < len) {
15199 var node = self.args[i++].drop_side_effect_free(compressor);
15200 if (node) {
15201 self.args[pos++] = node;
15202 }
15203 } else while (i < len) {
15204 self.args[pos++] = self.args[i++];
15205 }
15206 last = pos;
15207 break;
15208 }
15209 var trim = i >= fn.argnames.length;
15210 if (trim || has_flag(fn.argnames[i], UNUSED)) {
15211 var node = self.args[i].drop_side_effect_free(compressor);
15212 if (node) {
15213 self.args[pos++] = node;
15214 } else if (!trim) {
15215 self.args[pos++] = make_node(AST_Number, self.args[i], {
15216 value: 0
15217 });
15218 continue;
15219 }
15220 } else {
15221 self.args[pos++] = self.args[i];
15222 }
15223 last = pos;
15224 }
15225 self.args.length = last;
15226 }
15227
15228 if (compressor.option("unsafe")) {
15229 if (is_undeclared_ref(exp)) switch (exp.name) {
15230 case "Array":
15231 if (self.args.length != 1) {
15232 return make_node(AST_Array, self, {
15233 elements: self.args
15234 }).optimize(compressor);
15235 } else if (self.args[0] instanceof AST_Number && self.args[0].value <= 11) {
15236 const elements = [];
15237 for (let i = 0; i < self.args[0].value; i++) elements.push(new AST_Hole);
15238 return new AST_Array({ elements });
15239 }
15240 break;
15241 case "Object":
15242 if (self.args.length == 0) {
15243 return make_node(AST_Object, self, {
15244 properties: []
15245 });
15246 }
15247 break;
15248 case "String":
15249 if (self.args.length == 0) return make_node(AST_String, self, {
15250 value: ""
15251 });
15252 if (self.args.length <= 1) return make_node(AST_Binary, self, {
15253 left: self.args[0],
15254 operator: "+",
15255 right: make_node(AST_String, self, { value: "" })
15256 }).optimize(compressor);
15257 break;
15258 case "Number":
15259 if (self.args.length == 0) return make_node(AST_Number, self, {
15260 value: 0
15261 });
15262 if (self.args.length == 1 && compressor.option("unsafe_math")) {
15263 return make_node(AST_UnaryPrefix, self, {
15264 expression: self.args[0],
15265 operator: "+"
15266 }).optimize(compressor);
15267 }
15268 break;
15269 case "Symbol":
15270 if (self.args.length == 1 && self.args[0] instanceof AST_String && compressor.option("unsafe_symbols"))
15271 self.args.length = 0;
15272 break;
15273 case "Boolean":
15274 if (self.args.length == 0) return make_node(AST_False, self);
15275 if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, {
15276 expression: make_node(AST_UnaryPrefix, self, {
15277 expression: self.args[0],
15278 operator: "!"
15279 }),
15280 operator: "!"
15281 }).optimize(compressor);
15282 break;
15283 case "RegExp":
15284 var params = [];
15285 if (self.args.length >= 1
15286 && self.args.length <= 2
15287 && self.args.every((arg) => {
15288 var value = arg.evaluate(compressor);
15289 params.push(value);
15290 return arg !== value;
15291 })
15292 ) {
15293 let [ source, flags ] = params;
15294 source = regexp_source_fix(new RegExp(source).source);
15295 const rx = make_node(AST_RegExp, self, {
15296 value: { source, flags }
15297 });
15298 if (rx._eval(compressor) !== rx) {
15299 return rx;
15300 }
15301 }
15302 break;
15303 } else if (exp instanceof AST_Dot) switch(exp.property) {
15304 case "toString":
15305 if (self.args.length == 0 && !exp.expression.may_throw_on_access(compressor)) {
15306 return make_node(AST_Binary, self, {
15307 left: make_node(AST_String, self, { value: "" }),
15308 operator: "+",
15309 right: exp.expression
15310 }).optimize(compressor);
15311 }
15312 break;
15313 case "join":
15314 if (exp.expression instanceof AST_Array) EXIT: {
15315 var separator;
15316 if (self.args.length > 0) {
15317 separator = self.args[0].evaluate(compressor);
15318 if (separator === self.args[0]) break EXIT; // not a constant
15319 }
15320 var elements = [];
15321 var consts = [];
15322 for (var i = 0, len = exp.expression.elements.length; i < len; i++) {
15323 var el = exp.expression.elements[i];
15324 if (el instanceof AST_Expansion) break EXIT;
15325 var value = el.evaluate(compressor);
15326 if (value !== el) {
15327 consts.push(value);
15328 } else {
15329 if (consts.length > 0) {
15330 elements.push(make_node(AST_String, self, {
15331 value: consts.join(separator)
15332 }));
15333 consts.length = 0;
15334 }
15335 elements.push(el);
15336 }
15337 }
15338 if (consts.length > 0) {
15339 elements.push(make_node(AST_String, self, {
15340 value: consts.join(separator)
15341 }));
15342 }
15343 if (elements.length == 0) return make_node(AST_String, self, { value: "" });
15344 if (elements.length == 1) {
15345 if (elements[0].is_string(compressor)) {
15346 return elements[0];
15347 }
15348 return make_node(AST_Binary, elements[0], {
15349 operator : "+",
15350 left : make_node(AST_String, self, { value: "" }),
15351 right : elements[0]
15352 });
15353 }
15354 if (separator == "") {
15355 var first;
15356 if (elements[0].is_string(compressor)
15357 || elements[1].is_string(compressor)) {
15358 first = elements.shift();
15359 } else {
15360 first = make_node(AST_String, self, { value: "" });
15361 }
15362 return elements.reduce(function(prev, el) {
15363 return make_node(AST_Binary, el, {
15364 operator : "+",
15365 left : prev,
15366 right : el
15367 });
15368 }, first).optimize(compressor);
15369 }
15370 // need this awkward cloning to not affect original element
15371 // best_of will decide which one to get through.
15372 var node = self.clone();
15373 node.expression = node.expression.clone();
15374 node.expression.expression = node.expression.expression.clone();
15375 node.expression.expression.elements = elements;
15376 return best_of(compressor, self, node);
15377 }
15378 break;
15379 case "charAt":
15380 if (exp.expression.is_string(compressor)) {
15381 var arg = self.args[0];
15382 var index = arg ? arg.evaluate(compressor) : 0;
15383 if (index !== arg) {
15384 return make_node(AST_Sub, exp, {
15385 expression: exp.expression,
15386 property: make_node_from_constant(index | 0, arg || exp)
15387 }).optimize(compressor);
15388 }
15389 }
15390 break;
15391 case "apply":
15392 if (self.args.length == 2 && self.args[1] instanceof AST_Array) {
15393 var args = self.args[1].elements.slice();
15394 args.unshift(self.args[0]);
15395 return make_node(AST_Call, self, {
15396 expression: make_node(AST_Dot, exp, {
15397 expression: exp.expression,
15398 optional: false,
15399 property: "call"
15400 }),
15401 args: args
15402 }).optimize(compressor);
15403 }
15404 break;
15405 case "call":
15406 var func = exp.expression;
15407 if (func instanceof AST_SymbolRef) {
15408 func = func.fixed_value();
15409 }
15410 if (func instanceof AST_Lambda && !func.contains_this()) {
15411 return (self.args.length ? make_sequence(this, [
15412 self.args[0],
15413 make_node(AST_Call, self, {
15414 expression: exp.expression,
15415 args: self.args.slice(1)
15416 })
15417 ]) : make_node(AST_Call, self, {
15418 expression: exp.expression,
15419 args: []
15420 })).optimize(compressor);
15421 }
15422 break;
15423 }
15424 }
15425
15426 if (compressor.option("unsafe_Function")
15427 && is_undeclared_ref(exp)
15428 && exp.name == "Function") {
15429 // new Function() => function(){}
15430 if (self.args.length == 0) return make_node(AST_Function, self, {
15431 argnames: [],
15432 body: []
15433 }).optimize(compressor);
15434 if (self.args.every((x) => x instanceof AST_String)) {
15435 // quite a corner-case, but we can handle it:
15436 // https://github.com/mishoo/UglifyJS2/issues/203
15437 // if the code argument is a constant, then we can minify it.
15438 try {
15439 var code = "n(function(" + self.args.slice(0, -1).map(function(arg) {
15440 return arg.value;
15441 }).join(",") + "){" + self.args[self.args.length - 1].value + "})";
15442 var ast = parse(code);
15443 var mangle = { ie8: compressor.option("ie8") };
15444 ast.figure_out_scope(mangle);
15445 var comp = new Compressor(compressor.options, {
15446 mangle_options: compressor.mangle_options
15447 });
15448 ast = ast.transform(comp);
15449 ast.figure_out_scope(mangle);
15450 base54.reset();
15451 ast.compute_char_frequency(mangle);
15452 ast.mangle_names(mangle);
15453 var fun;
15454 walk(ast, node => {
15455 if (is_func_expr(node)) {
15456 fun = node;
15457 return walk_abort;
15458 }
15459 });
15460 var code = OutputStream();
15461 AST_BlockStatement.prototype._codegen.call(fun, fun, code);
15462 self.args = [
15463 make_node(AST_String, self, {
15464 value: fun.argnames.map(function(arg) {
15465 return arg.print_to_string();
15466 }).join(",")
15467 }),
15468 make_node(AST_String, self.args[self.args.length - 1], {
15469 value: code.get().replace(/^{|}$/g, "")
15470 })
15471 ];
15472 return self;
15473 } catch (ex) {
15474 if (!(ex instanceof JS_Parse_Error)) {
15475 throw ex;
15476 }
15477
15478 // Otherwise, it crashes at runtime. Or maybe it's nonstandard syntax.
15479 }
15480 }
15481 }
15482
15483 var stat = is_func && fn.body[0];
15484 var is_regular_func = is_func && !fn.is_generator && !fn.async;
15485 var can_inline = is_regular_func && compressor.option("inline") && !self.is_expr_pure(compressor);
15486 if (can_inline && stat instanceof AST_Return) {
15487 let returned = stat.value;
15488 if (!returned || returned.is_constant_expression()) {
15489 if (returned) {
15490 returned = returned.clone(true);
15491 } else {
15492 returned = make_node(AST_Undefined, self);
15493 }
15494 const args = self.args.concat(returned);
15495 return make_sequence(self, args).optimize(compressor);
15496 }
15497
15498 // optimize identity function
15499 if (
15500 fn.argnames.length === 1
15501 && (fn.argnames[0] instanceof AST_SymbolFunarg)
15502 && self.args.length < 2
15503 && returned instanceof AST_SymbolRef
15504 && returned.name === fn.argnames[0].name
15505 ) {
15506 const replacement =
15507 (self.args[0] || make_node(AST_Undefined)).optimize(compressor);
15508
15509 let parent;
15510 if (
15511 replacement instanceof AST_PropAccess
15512 && (parent = compressor.parent()) instanceof AST_Call
15513 && parent.expression === self
15514 ) {
15515 // identity function was being used to remove `this`, like in
15516 //
15517 // id(bag.no_this)(...)
15518 //
15519 // Replace with a larger but more effish (0, bag.no_this) wrapper.
15520
15521 return make_sequence(self, [
15522 make_node(AST_Number, self, { value: 0 }),
15523 replacement
15524 ]);
15525 }
15526 // replace call with first argument or undefined if none passed
15527 return replacement;
15528 }
15529 }
15530
15531 if (can_inline) {
15532 var scope, in_loop, level = -1;
15533 let def;
15534 let returned_value;
15535 let nearest_scope;
15536 if (simple_args
15537 && !fn.uses_arguments
15538 && !(compressor.parent() instanceof AST_Class)
15539 && !(fn.name && fn instanceof AST_Function)
15540 && (returned_value = can_flatten_body(stat))
15541 && (exp === fn
15542 || has_annotation(self, _INLINE)
15543 || compressor.option("unused")
15544 && (def = exp.definition()).references.length == 1
15545 && !recursive_ref(compressor, def)
15546 && fn.is_constant_expression(exp.scope))
15547 && !has_annotation(self, _PURE | _NOINLINE)
15548 && !fn.contains_this()
15549 && can_inject_symbols()
15550 && (nearest_scope = find_scope(compressor))
15551 && !scope_encloses_variables_in_this_scope(nearest_scope, fn)
15552 && !(function in_default_assign() {
15553 // Due to the fact function parameters have their own scope
15554 // which can't use `var something` in the function body within,
15555 // we simply don't inline into DefaultAssign.
15556 let i = 0;
15557 let p;
15558 while ((p = compressor.parent(i++))) {
15559 if (p instanceof AST_DefaultAssign) return true;
15560 if (p instanceof AST_Block) break;
15561 }
15562 return false;
15563 })()
15564 && !(scope instanceof AST_Class)
15565 ) {
15566 set_flag(fn, SQUEEZED);
15567 nearest_scope.add_child_scope(fn);
15568 return make_sequence(self, flatten_fn(returned_value)).optimize(compressor);
15569 }
15570 }
15571
15572 if (can_inline && has_annotation(self, _INLINE)) {
15573 set_flag(fn, SQUEEZED);
15574 fn = make_node(fn.CTOR === AST_Defun ? AST_Function : fn.CTOR, fn, fn);
15575 fn.figure_out_scope({}, {
15576 parent_scope: find_scope(compressor),
15577 toplevel: compressor.get_toplevel()
15578 });
15579
15580 return make_node(AST_Call, self, {
15581 expression: fn,
15582 args: self.args,
15583 }).optimize(compressor);
15584 }
15585
15586 const can_drop_this_call = is_regular_func && compressor.option("side_effects") && fn.body.every(is_empty);
15587 if (can_drop_this_call) {
15588 var args = self.args.concat(make_node(AST_Undefined, self));
15589 return make_sequence(self, args).optimize(compressor);
15590 }
15591
15592 if (compressor.option("negate_iife")
15593 && compressor.parent() instanceof AST_SimpleStatement
15594 && is_iife_call(self)) {
15595 return self.negate(compressor, true);
15596 }
15597
15598 var ev = self.evaluate(compressor);
15599 if (ev !== self) {
15600 ev = make_node_from_constant(ev, self).optimize(compressor);
15601 return best_of(compressor, ev, self);
15602 }
15603
15604 return self;
15605
15606 function return_value(stat) {
15607 if (!stat) return make_node(AST_Undefined, self);
15608 if (stat instanceof AST_Return) {
15609 if (!stat.value) return make_node(AST_Undefined, self);
15610 return stat.value.clone(true);
15611 }
15612 if (stat instanceof AST_SimpleStatement) {
15613 return make_node(AST_UnaryPrefix, stat, {
15614 operator: "void",
15615 expression: stat.body.clone(true)
15616 });
15617 }
15618 }
15619
15620 function can_flatten_body(stat) {
15621 var body = fn.body;
15622 var len = body.length;
15623 if (compressor.option("inline") < 3) {
15624 return len == 1 && return_value(stat);
15625 }
15626 stat = null;
15627 for (var i = 0; i < len; i++) {
15628 var line = body[i];
15629 if (line instanceof AST_Var) {
15630 if (stat && !line.definitions.every((var_def) =>
15631 !var_def.value
15632 )) {
15633 return false;
15634 }
15635 } else if (stat) {
15636 return false;
15637 } else if (!(line instanceof AST_EmptyStatement)) {
15638 stat = line;
15639 }
15640 }
15641 return return_value(stat);
15642 }
15643
15644 function can_inject_args(block_scoped, safe_to_inject) {
15645 for (var i = 0, len = fn.argnames.length; i < len; i++) {
15646 var arg = fn.argnames[i];
15647 if (arg instanceof AST_DefaultAssign) {
15648 if (has_flag(arg.left, UNUSED)) continue;
15649 return false;
15650 }
15651 if (arg instanceof AST_Destructuring) return false;
15652 if (arg instanceof AST_Expansion) {
15653 if (has_flag(arg.expression, UNUSED)) continue;
15654 return false;
15655 }
15656 if (has_flag(arg, UNUSED)) continue;
15657 if (!safe_to_inject
15658 || block_scoped.has(arg.name)
15659 || identifier_atom.has(arg.name)
15660 || scope.conflicting_def(arg.name)) {
15661 return false;
15662 }
15663 if (in_loop) in_loop.push(arg.definition());
15664 }
15665 return true;
15666 }
15667
15668 function can_inject_vars(block_scoped, safe_to_inject) {
15669 var len = fn.body.length;
15670 for (var i = 0; i < len; i++) {
15671 var stat = fn.body[i];
15672 if (!(stat instanceof AST_Var)) continue;
15673 if (!safe_to_inject) return false;
15674 for (var j = stat.definitions.length; --j >= 0;) {
15675 var name = stat.definitions[j].name;
15676 if (name instanceof AST_Destructuring
15677 || block_scoped.has(name.name)
15678 || identifier_atom.has(name.name)
15679 || scope.conflicting_def(name.name)) {
15680 return false;
15681 }
15682 if (in_loop) in_loop.push(name.definition());
15683 }
15684 }
15685 return true;
15686 }
15687
15688 function can_inject_symbols() {
15689 var block_scoped = new Set();
15690 do {
15691 scope = compressor.parent(++level);
15692 if (scope.is_block_scope() && scope.block_scope) {
15693 // TODO this is sometimes undefined during compression.
15694 // But it should always have a value!
15695 scope.block_scope.variables.forEach(function (variable) {
15696 block_scoped.add(variable.name);
15697 });
15698 }
15699 if (scope instanceof AST_Catch) {
15700 // TODO can we delete? AST_Catch is a block scope.
15701 if (scope.argname) {
15702 block_scoped.add(scope.argname.name);
15703 }
15704 } else if (scope instanceof AST_IterationStatement) {
15705 in_loop = [];
15706 } else if (scope instanceof AST_SymbolRef) {
15707 if (scope.fixed_value() instanceof AST_Scope) return false;
15708 }
15709 } while (!(scope instanceof AST_Scope));
15710
15711 var safe_to_inject = !(scope instanceof AST_Toplevel) || compressor.toplevel.vars;
15712 var inline = compressor.option("inline");
15713 if (!can_inject_vars(block_scoped, inline >= 3 && safe_to_inject)) return false;
15714 if (!can_inject_args(block_scoped, inline >= 2 && safe_to_inject)) return false;
15715 return !in_loop || in_loop.length == 0 || !is_reachable(fn, in_loop);
15716 }
15717
15718 function append_var(decls, expressions, name, value) {
15719 var def = name.definition();
15720
15721 // Name already exists, only when a function argument had the same name
15722 const already_appended = scope.variables.has(name.name);
15723 if (!already_appended) {
15724 scope.variables.set(name.name, def);
15725 scope.enclosed.push(def);
15726 decls.push(make_node(AST_VarDef, name, {
15727 name: name,
15728 value: null
15729 }));
15730 }
15731
15732 var sym = make_node(AST_SymbolRef, name, name);
15733 def.references.push(sym);
15734 if (value) expressions.push(make_node(AST_Assign, self, {
15735 operator: "=",
15736 left: sym,
15737 right: value.clone()
15738 }));
15739 }
15740
15741 function flatten_args(decls, expressions) {
15742 var len = fn.argnames.length;
15743 for (var i = self.args.length; --i >= len;) {
15744 expressions.push(self.args[i]);
15745 }
15746 for (i = len; --i >= 0;) {
15747 var name = fn.argnames[i];
15748 var value = self.args[i];
15749 if (has_flag(name, UNUSED) || !name.name || scope.conflicting_def(name.name)) {
15750 if (value) expressions.push(value);
15751 } else {
15752 var symbol = make_node(AST_SymbolVar, name, name);
15753 name.definition().orig.push(symbol);
15754 if (!value && in_loop) value = make_node(AST_Undefined, self);
15755 append_var(decls, expressions, symbol, value);
15756 }
15757 }
15758 decls.reverse();
15759 expressions.reverse();
15760 }
15761
15762 function flatten_vars(decls, expressions) {
15763 var pos = expressions.length;
15764 for (var i = 0, lines = fn.body.length; i < lines; i++) {
15765 var stat = fn.body[i];
15766 if (!(stat instanceof AST_Var)) continue;
15767 for (var j = 0, defs = stat.definitions.length; j < defs; j++) {
15768 var var_def = stat.definitions[j];
15769 var name = var_def.name;
15770 append_var(decls, expressions, name, var_def.value);
15771 if (in_loop && fn.argnames.every((argname) =>
15772 argname.name != name.name
15773 )) {
15774 var def = fn.variables.get(name.name);
15775 var sym = make_node(AST_SymbolRef, name, name);
15776 def.references.push(sym);
15777 expressions.splice(pos++, 0, make_node(AST_Assign, var_def, {
15778 operator: "=",
15779 left: sym,
15780 right: make_node(AST_Undefined, name)
15781 }));
15782 }
15783 }
15784 }
15785 }
15786
15787 function flatten_fn(returned_value) {
15788 var decls = [];
15789 var expressions = [];
15790 flatten_args(decls, expressions);
15791 flatten_vars(decls, expressions);
15792 expressions.push(returned_value);
15793 if (decls.length) {
15794 const i = scope.body.indexOf(compressor.parent(level - 1)) + 1;
15795 scope.body.splice(i, 0, make_node(AST_Var, fn, {
15796 definitions: decls
15797 }));
15798 }
15799 return expressions.map(exp => exp.clone(true));
15800 }
15801});
15802
15803def_optimize(AST_New, function(self, compressor) {
15804 if (
15805 compressor.option("unsafe") &&
15806 is_undeclared_ref(self.expression) &&
15807 ["Object", "RegExp", "Function", "Error", "Array"].includes(self.expression.name)
15808 ) return make_node(AST_Call, self, self).transform(compressor);
15809 return self;
15810});
15811
15812def_optimize(AST_Sequence, function(self, compressor) {
15813 if (!compressor.option("side_effects")) return self;
15814 var expressions = [];
15815 filter_for_side_effects();
15816 var end = expressions.length - 1;
15817 trim_right_for_undefined();
15818 if (end == 0) {
15819 self = maintain_this_binding(compressor.parent(), compressor.self(), expressions[0]);
15820 if (!(self instanceof AST_Sequence)) self = self.optimize(compressor);
15821 return self;
15822 }
15823 self.expressions = expressions;
15824 return self;
15825
15826 function filter_for_side_effects() {
15827 var first = first_in_statement(compressor);
15828 var last = self.expressions.length - 1;
15829 self.expressions.forEach(function(expr, index) {
15830 if (index < last) expr = expr.drop_side_effect_free(compressor, first);
15831 if (expr) {
15832 merge_sequence(expressions, expr);
15833 first = false;
15834 }
15835 });
15836 }
15837
15838 function trim_right_for_undefined() {
15839 while (end > 0 && is_undefined(expressions[end], compressor)) end--;
15840 if (end < expressions.length - 1) {
15841 expressions[end] = make_node(AST_UnaryPrefix, self, {
15842 operator : "void",
15843 expression : expressions[end]
15844 });
15845 expressions.length = end + 1;
15846 }
15847 }
15848});
15849
15850AST_Unary.DEFMETHOD("lift_sequences", function(compressor) {
15851 if (compressor.option("sequences")) {
15852 if (this.expression instanceof AST_Sequence) {
15853 var x = this.expression.expressions.slice();
15854 var e = this.clone();
15855 e.expression = x.pop();
15856 x.push(e);
15857 return make_sequence(this, x).optimize(compressor);
15858 }
15859 }
15860 return this;
15861});
15862
15863def_optimize(AST_UnaryPostfix, function(self, compressor) {
15864 return self.lift_sequences(compressor);
15865});
15866
15867def_optimize(AST_UnaryPrefix, function(self, compressor) {
15868 var e = self.expression;
15869 if (self.operator == "delete"
15870 && !(e instanceof AST_SymbolRef
15871 || e instanceof AST_PropAccess
15872 || is_identifier_atom(e))) {
15873 if (e instanceof AST_Sequence) {
15874 const exprs = e.expressions.slice();
15875 exprs.push(make_node(AST_True, self));
15876 return make_sequence(self, exprs).optimize(compressor);
15877 }
15878 return make_sequence(self, [ e, make_node(AST_True, self) ]).optimize(compressor);
15879 }
15880 var seq = self.lift_sequences(compressor);
15881 if (seq !== self) {
15882 return seq;
15883 }
15884 if (compressor.option("side_effects") && self.operator == "void") {
15885 e = e.drop_side_effect_free(compressor);
15886 if (e) {
15887 self.expression = e;
15888 return self;
15889 } else {
15890 return make_node(AST_Undefined, self).optimize(compressor);
15891 }
15892 }
15893 if (compressor.in_boolean_context()) {
15894 switch (self.operator) {
15895 case "!":
15896 if (e instanceof AST_UnaryPrefix && e.operator == "!") {
15897 // !!foo ==> foo, if we're in boolean context
15898 return e.expression;
15899 }
15900 if (e instanceof AST_Binary) {
15901 self = best_of(compressor, self, e.negate(compressor, first_in_statement(compressor)));
15902 }
15903 break;
15904 case "typeof":
15905 // typeof always returns a non-empty string, thus it's
15906 // always true in booleans
15907 // And we don't need to check if it's undeclared, because in typeof, that's OK
15908 return (e instanceof AST_SymbolRef ? make_node(AST_True, self) : make_sequence(self, [
15909 e,
15910 make_node(AST_True, self)
15911 ])).optimize(compressor);
15912 }
15913 }
15914 if (self.operator == "-" && e instanceof AST_Infinity) {
15915 e = e.transform(compressor);
15916 }
15917 if (e instanceof AST_Binary
15918 && (self.operator == "+" || self.operator == "-")
15919 && (e.operator == "*" || e.operator == "/" || e.operator == "%")) {
15920 return make_node(AST_Binary, self, {
15921 operator: e.operator,
15922 left: make_node(AST_UnaryPrefix, e.left, {
15923 operator: self.operator,
15924 expression: e.left
15925 }),
15926 right: e.right
15927 });
15928 }
15929 // avoids infinite recursion of numerals
15930 if (self.operator != "-"
15931 || !(e instanceof AST_Number || e instanceof AST_Infinity || e instanceof AST_BigInt)) {
15932 var ev = self.evaluate(compressor);
15933 if (ev !== self) {
15934 ev = make_node_from_constant(ev, self).optimize(compressor);
15935 return best_of(compressor, ev, self);
15936 }
15937 }
15938 return self;
15939});
15940
15941AST_Binary.DEFMETHOD("lift_sequences", function(compressor) {
15942 if (compressor.option("sequences")) {
15943 if (this.left instanceof AST_Sequence) {
15944 var x = this.left.expressions.slice();
15945 var e = this.clone();
15946 e.left = x.pop();
15947 x.push(e);
15948 return make_sequence(this, x).optimize(compressor);
15949 }
15950 if (this.right instanceof AST_Sequence && !this.left.has_side_effects(compressor)) {
15951 var assign = this.operator == "=" && this.left instanceof AST_SymbolRef;
15952 var x = this.right.expressions;
15953 var last = x.length - 1;
15954 for (var i = 0; i < last; i++) {
15955 if (!assign && x[i].has_side_effects(compressor)) break;
15956 }
15957 if (i == last) {
15958 x = x.slice();
15959 var e = this.clone();
15960 e.right = x.pop();
15961 x.push(e);
15962 return make_sequence(this, x).optimize(compressor);
15963 } else if (i > 0) {
15964 var e = this.clone();
15965 e.right = make_sequence(this.right, x.slice(i));
15966 x = x.slice(0, i);
15967 x.push(e);
15968 return make_sequence(this, x).optimize(compressor);
15969 }
15970 }
15971 }
15972 return this;
15973});
15974
15975var commutativeOperators = makePredicate("== === != !== * & | ^");
15976function is_object(node) {
15977 return node instanceof AST_Array
15978 || node instanceof AST_Lambda
15979 || node instanceof AST_Object
15980 || node instanceof AST_Class;
15981}
15982
15983def_optimize(AST_Binary, function(self, compressor) {
15984 function reversible() {
15985 return self.left.is_constant()
15986 || self.right.is_constant()
15987 || !self.left.has_side_effects(compressor)
15988 && !self.right.has_side_effects(compressor);
15989 }
15990 function reverse(op) {
15991 if (reversible()) {
15992 if (op) self.operator = op;
15993 var tmp = self.left;
15994 self.left = self.right;
15995 self.right = tmp;
15996 }
15997 }
15998 if (commutativeOperators.has(self.operator)) {
15999 if (self.right.is_constant()
16000 && !self.left.is_constant()) {
16001 // if right is a constant, whatever side effects the
16002 // left side might have could not influence the
16003 // result. hence, force switch.
16004
16005 if (!(self.left instanceof AST_Binary
16006 && PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) {
16007 reverse();
16008 }
16009 }
16010 }
16011 self = self.lift_sequences(compressor);
16012 if (compressor.option("comparisons")) switch (self.operator) {
16013 case "===":
16014 case "!==":
16015 var is_strict_comparison = true;
16016 if ((self.left.is_string(compressor) && self.right.is_string(compressor)) ||
16017 (self.left.is_number(compressor) && self.right.is_number(compressor)) ||
16018 (self.left.is_boolean() && self.right.is_boolean()) ||
16019 self.left.equivalent_to(self.right)) {
16020 self.operator = self.operator.substr(0, 2);
16021 }
16022 // XXX: intentionally falling down to the next case
16023 case "==":
16024 case "!=":
16025 // void 0 == x => null == x
16026 if (!is_strict_comparison && is_undefined(self.left, compressor)) {
16027 self.left = make_node(AST_Null, self.left);
16028 } else if (compressor.option("typeofs")
16029 // "undefined" == typeof x => undefined === x
16030 && self.left instanceof AST_String
16031 && self.left.value == "undefined"
16032 && self.right instanceof AST_UnaryPrefix
16033 && self.right.operator == "typeof") {
16034 var expr = self.right.expression;
16035 if (expr instanceof AST_SymbolRef ? expr.is_declared(compressor)
16036 : !(expr instanceof AST_PropAccess && compressor.option("ie8"))) {
16037 self.right = expr;
16038 self.left = make_node(AST_Undefined, self.left).optimize(compressor);
16039 if (self.operator.length == 2) self.operator += "=";
16040 }
16041 } else if (self.left instanceof AST_SymbolRef
16042 // obj !== obj => false
16043 && self.right instanceof AST_SymbolRef
16044 && self.left.definition() === self.right.definition()
16045 && is_object(self.left.fixed_value())) {
16046 return make_node(self.operator[0] == "=" ? AST_True : AST_False, self);
16047 }
16048 break;
16049 case "&&":
16050 case "||":
16051 var lhs = self.left;
16052 if (lhs.operator == self.operator) {
16053 lhs = lhs.right;
16054 }
16055 if (lhs instanceof AST_Binary
16056 && lhs.operator == (self.operator == "&&" ? "!==" : "===")
16057 && self.right instanceof AST_Binary
16058 && lhs.operator == self.right.operator
16059 && (is_undefined(lhs.left, compressor) && self.right.left instanceof AST_Null
16060 || lhs.left instanceof AST_Null && is_undefined(self.right.left, compressor))
16061 && !lhs.right.has_side_effects(compressor)
16062 && lhs.right.equivalent_to(self.right.right)) {
16063 var combined = make_node(AST_Binary, self, {
16064 operator: lhs.operator.slice(0, -1),
16065 left: make_node(AST_Null, self),
16066 right: lhs.right
16067 });
16068 if (lhs !== self.left) {
16069 combined = make_node(AST_Binary, self, {
16070 operator: self.operator,
16071 left: self.left.left,
16072 right: combined
16073 });
16074 }
16075 return combined;
16076 }
16077 break;
16078 }
16079 if (self.operator == "+" && compressor.in_boolean_context()) {
16080 var ll = self.left.evaluate(compressor);
16081 var rr = self.right.evaluate(compressor);
16082 if (ll && typeof ll == "string") {
16083 return make_sequence(self, [
16084 self.right,
16085 make_node(AST_True, self)
16086 ]).optimize(compressor);
16087 }
16088 if (rr && typeof rr == "string") {
16089 return make_sequence(self, [
16090 self.left,
16091 make_node(AST_True, self)
16092 ]).optimize(compressor);
16093 }
16094 }
16095 if (compressor.option("comparisons") && self.is_boolean()) {
16096 if (!(compressor.parent() instanceof AST_Binary)
16097 || compressor.parent() instanceof AST_Assign) {
16098 var negated = make_node(AST_UnaryPrefix, self, {
16099 operator: "!",
16100 expression: self.negate(compressor, first_in_statement(compressor))
16101 });
16102 self = best_of(compressor, self, negated);
16103 }
16104 if (compressor.option("unsafe_comps")) {
16105 switch (self.operator) {
16106 case "<": reverse(">"); break;
16107 case "<=": reverse(">="); break;
16108 }
16109 }
16110 }
16111 if (self.operator == "+") {
16112 if (self.right instanceof AST_String
16113 && self.right.getValue() == ""
16114 && self.left.is_string(compressor)) {
16115 return self.left;
16116 }
16117 if (self.left instanceof AST_String
16118 && self.left.getValue() == ""
16119 && self.right.is_string(compressor)) {
16120 return self.right;
16121 }
16122 if (self.left instanceof AST_Binary
16123 && self.left.operator == "+"
16124 && self.left.left instanceof AST_String
16125 && self.left.left.getValue() == ""
16126 && self.right.is_string(compressor)) {
16127 self.left = self.left.right;
16128 return self;
16129 }
16130 }
16131 if (compressor.option("evaluate")) {
16132 switch (self.operator) {
16133 case "&&":
16134 var ll = has_flag(self.left, TRUTHY)
16135 ? true
16136 : has_flag(self.left, FALSY)
16137 ? false
16138 : self.left.evaluate(compressor);
16139 if (!ll) {
16140 return maintain_this_binding(compressor.parent(), compressor.self(), self.left).optimize(compressor);
16141 } else if (!(ll instanceof AST_Node)) {
16142 return make_sequence(self, [ self.left, self.right ]).optimize(compressor);
16143 }
16144 var rr = self.right.evaluate(compressor);
16145 if (!rr) {
16146 if (compressor.in_boolean_context()) {
16147 return make_sequence(self, [
16148 self.left,
16149 make_node(AST_False, self)
16150 ]).optimize(compressor);
16151 } else {
16152 set_flag(self, FALSY);
16153 }
16154 } else if (!(rr instanceof AST_Node)) {
16155 var parent = compressor.parent();
16156 if (parent.operator == "&&" && parent.left === compressor.self() || compressor.in_boolean_context()) {
16157 return self.left.optimize(compressor);
16158 }
16159 }
16160 // x || false && y ---> x ? y : false
16161 if (self.left.operator == "||") {
16162 var lr = self.left.right.evaluate(compressor);
16163 if (!lr) return make_node(AST_Conditional, self, {
16164 condition: self.left.left,
16165 consequent: self.right,
16166 alternative: self.left.right
16167 }).optimize(compressor);
16168 }
16169 break;
16170 case "||":
16171 var ll = has_flag(self.left, TRUTHY)
16172 ? true
16173 : has_flag(self.left, FALSY)
16174 ? false
16175 : self.left.evaluate(compressor);
16176 if (!ll) {
16177 return make_sequence(self, [ self.left, self.right ]).optimize(compressor);
16178 } else if (!(ll instanceof AST_Node)) {
16179 return maintain_this_binding(compressor.parent(), compressor.self(), self.left).optimize(compressor);
16180 }
16181 var rr = self.right.evaluate(compressor);
16182 if (!rr) {
16183 var parent = compressor.parent();
16184 if (parent.operator == "||" && parent.left === compressor.self() || compressor.in_boolean_context()) {
16185 return self.left.optimize(compressor);
16186 }
16187 } else if (!(rr instanceof AST_Node)) {
16188 if (compressor.in_boolean_context()) {
16189 return make_sequence(self, [
16190 self.left,
16191 make_node(AST_True, self)
16192 ]).optimize(compressor);
16193 } else {
16194 set_flag(self, TRUTHY);
16195 }
16196 }
16197 if (self.left.operator == "&&") {
16198 var lr = self.left.right.evaluate(compressor);
16199 if (lr && !(lr instanceof AST_Node)) return make_node(AST_Conditional, self, {
16200 condition: self.left.left,
16201 consequent: self.left.right,
16202 alternative: self.right
16203 }).optimize(compressor);
16204 }
16205 break;
16206 case "??":
16207 if (is_nullish(self.left)) {
16208 return self.right;
16209 }
16210
16211 var ll = self.left.evaluate(compressor);
16212 if (!(ll instanceof AST_Node)) {
16213 // if we know the value for sure we can simply compute right away.
16214 return ll == null ? self.right : self.left;
16215 }
16216
16217 if (compressor.in_boolean_context()) {
16218 const rr = self.right.evaluate(compressor);
16219 if (!(rr instanceof AST_Node) && !rr) {
16220 return self.left;
16221 }
16222 }
16223 }
16224 var associative = true;
16225 switch (self.operator) {
16226 case "+":
16227 // (x + "foo") + "bar" => x + "foobar"
16228 if (self.right instanceof AST_Constant
16229 && self.left instanceof AST_Binary
16230 && self.left.operator == "+"
16231 && self.left.is_string(compressor)) {
16232 var binary = make_node(AST_Binary, self, {
16233 operator: "+",
16234 left: self.left.right,
16235 right: self.right,
16236 });
16237 var r = binary.optimize(compressor);
16238 if (binary !== r) {
16239 self = make_node(AST_Binary, self, {
16240 operator: "+",
16241 left: self.left.left,
16242 right: r
16243 });
16244 }
16245 }
16246 // (x + "foo") + ("bar" + y) => (x + "foobar") + y
16247 if (self.left instanceof AST_Binary
16248 && self.left.operator == "+"
16249 && self.left.is_string(compressor)
16250 && self.right instanceof AST_Binary
16251 && self.right.operator == "+"
16252 && self.right.is_string(compressor)) {
16253 var binary = make_node(AST_Binary, self, {
16254 operator: "+",
16255 left: self.left.right,
16256 right: self.right.left,
16257 });
16258 var m = binary.optimize(compressor);
16259 if (binary !== m) {
16260 self = make_node(AST_Binary, self, {
16261 operator: "+",
16262 left: make_node(AST_Binary, self.left, {
16263 operator: "+",
16264 left: self.left.left,
16265 right: m
16266 }),
16267 right: self.right.right
16268 });
16269 }
16270 }
16271 // a + -b => a - b
16272 if (self.right instanceof AST_UnaryPrefix
16273 && self.right.operator == "-"
16274 && self.left.is_number(compressor)) {
16275 self = make_node(AST_Binary, self, {
16276 operator: "-",
16277 left: self.left,
16278 right: self.right.expression
16279 });
16280 break;
16281 }
16282 // -a + b => b - a
16283 if (self.left instanceof AST_UnaryPrefix
16284 && self.left.operator == "-"
16285 && reversible()
16286 && self.right.is_number(compressor)) {
16287 self = make_node(AST_Binary, self, {
16288 operator: "-",
16289 left: self.right,
16290 right: self.left.expression
16291 });
16292 break;
16293 }
16294 // `foo${bar}baz` + 1 => `foo${bar}baz1`
16295 if (self.left instanceof AST_TemplateString) {
16296 var l = self.left;
16297 var r = self.right.evaluate(compressor);
16298 if (r != self.right) {
16299 l.segments[l.segments.length - 1].value += r.toString();
16300 return l;
16301 }
16302 }
16303 // 1 + `foo${bar}baz` => `1foo${bar}baz`
16304 if (self.right instanceof AST_TemplateString) {
16305 var r = self.right;
16306 var l = self.left.evaluate(compressor);
16307 if (l != self.left) {
16308 r.segments[0].value = l.toString() + r.segments[0].value ;
16309 return r;
16310 }
16311 }
16312 // `1${bar}2` + `foo${bar}baz` => `1${bar}2foo${bar}baz`
16313 if (self.left instanceof AST_TemplateString
16314 && self.right instanceof AST_TemplateString) {
16315 var l = self.left;
16316 var segments = l.segments;
16317 var r = self.right;
16318 segments[segments.length - 1].value += r.segments[0].value;
16319 for (var i = 1; i < r.segments.length; i++) {
16320 segments.push(r.segments[i]);
16321 }
16322 return l;
16323 }
16324 case "*":
16325 associative = compressor.option("unsafe_math");
16326 case "&":
16327 case "|":
16328 case "^":
16329 // a + +b => +b + a
16330 if (self.left.is_number(compressor)
16331 && self.right.is_number(compressor)
16332 && reversible()
16333 && !(self.left instanceof AST_Binary
16334 && self.left.operator != self.operator
16335 && PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) {
16336 var reversed = make_node(AST_Binary, self, {
16337 operator: self.operator,
16338 left: self.right,
16339 right: self.left
16340 });
16341 if (self.right instanceof AST_Constant
16342 && !(self.left instanceof AST_Constant)) {
16343 self = best_of(compressor, reversed, self);
16344 } else {
16345 self = best_of(compressor, self, reversed);
16346 }
16347 }
16348 if (associative && self.is_number(compressor)) {
16349 // a + (b + c) => (a + b) + c
16350 if (self.right instanceof AST_Binary
16351 && self.right.operator == self.operator) {
16352 self = make_node(AST_Binary, self, {
16353 operator: self.operator,
16354 left: make_node(AST_Binary, self.left, {
16355 operator: self.operator,
16356 left: self.left,
16357 right: self.right.left,
16358 start: self.left.start,
16359 end: self.right.left.end
16360 }),
16361 right: self.right.right
16362 });
16363 }
16364 // (n + 2) + 3 => 5 + n
16365 // (2 * n) * 3 => 6 + n
16366 if (self.right instanceof AST_Constant
16367 && self.left instanceof AST_Binary
16368 && self.left.operator == self.operator) {
16369 if (self.left.left instanceof AST_Constant) {
16370 self = make_node(AST_Binary, self, {
16371 operator: self.operator,
16372 left: make_node(AST_Binary, self.left, {
16373 operator: self.operator,
16374 left: self.left.left,
16375 right: self.right,
16376 start: self.left.left.start,
16377 end: self.right.end
16378 }),
16379 right: self.left.right
16380 });
16381 } else if (self.left.right instanceof AST_Constant) {
16382 self = make_node(AST_Binary, self, {
16383 operator: self.operator,
16384 left: make_node(AST_Binary, self.left, {
16385 operator: self.operator,
16386 left: self.left.right,
16387 right: self.right,
16388 start: self.left.right.start,
16389 end: self.right.end
16390 }),
16391 right: self.left.left
16392 });
16393 }
16394 }
16395 // (a | 1) | (2 | d) => (3 | a) | b
16396 if (self.left instanceof AST_Binary
16397 && self.left.operator == self.operator
16398 && self.left.right instanceof AST_Constant
16399 && self.right instanceof AST_Binary
16400 && self.right.operator == self.operator
16401 && self.right.left instanceof AST_Constant) {
16402 self = make_node(AST_Binary, self, {
16403 operator: self.operator,
16404 left: make_node(AST_Binary, self.left, {
16405 operator: self.operator,
16406 left: make_node(AST_Binary, self.left.left, {
16407 operator: self.operator,
16408 left: self.left.right,
16409 right: self.right.left,
16410 start: self.left.right.start,
16411 end: self.right.left.end
16412 }),
16413 right: self.left.left
16414 }),
16415 right: self.right.right
16416 });
16417 }
16418 }
16419 }
16420 }
16421 // x && (y && z) ==> x && y && z
16422 // x || (y || z) ==> x || y || z
16423 // x + ("y" + z) ==> x + "y" + z
16424 // "x" + (y + "z")==> "x" + y + "z"
16425 if (self.right instanceof AST_Binary
16426 && self.right.operator == self.operator
16427 && (lazy_op.has(self.operator)
16428 || (self.operator == "+"
16429 && (self.right.left.is_string(compressor)
16430 || (self.left.is_string(compressor)
16431 && self.right.right.is_string(compressor)))))
16432 ) {
16433 self.left = make_node(AST_Binary, self.left, {
16434 operator : self.operator,
16435 left : self.left.transform(compressor),
16436 right : self.right.left.transform(compressor)
16437 });
16438 self.right = self.right.right.transform(compressor);
16439 return self.transform(compressor);
16440 }
16441 var ev = self.evaluate(compressor);
16442 if (ev !== self) {
16443 ev = make_node_from_constant(ev, self).optimize(compressor);
16444 return best_of(compressor, ev, self);
16445 }
16446 return self;
16447});
16448
16449def_optimize(AST_SymbolExport, function(self) {
16450 return self;
16451});
16452
16453function recursive_ref(compressor, def) {
16454 var node;
16455 for (var i = 0; node = compressor.parent(i); i++) {
16456 if (
16457 node instanceof AST_Lambda
16458 || node instanceof AST_Class
16459 ) {
16460 var name = node.name;
16461 if (name && name.definition() === def) break;
16462 }
16463 }
16464 return node;
16465}
16466
16467function within_array_or_object_literal(compressor) {
16468 var node, level = 0;
16469 while (node = compressor.parent(level++)) {
16470 if (node instanceof AST_Statement) return false;
16471 if (node instanceof AST_Array
16472 || node instanceof AST_ObjectKeyVal
16473 || node instanceof AST_Object) {
16474 return true;
16475 }
16476 }
16477 return false;
16478}
16479
16480def_optimize(AST_SymbolRef, function(self, compressor) {
16481 if (
16482 !compressor.option("ie8")
16483 && is_undeclared_ref(self)
16484 && !compressor.find_parent(AST_With)
16485 ) {
16486 switch (self.name) {
16487 case "undefined":
16488 return make_node(AST_Undefined, self).optimize(compressor);
16489 case "NaN":
16490 return make_node(AST_NaN, self).optimize(compressor);
16491 case "Infinity":
16492 return make_node(AST_Infinity, self).optimize(compressor);
16493 }
16494 }
16495
16496 const parent = compressor.parent();
16497 if (compressor.option("reduce_vars") && is_lhs(self, parent) !== self) {
16498 const def = self.definition();
16499 const nearest_scope = find_scope(compressor);
16500 if (compressor.top_retain && def.global && compressor.top_retain(def)) {
16501 def.fixed = false;
16502 def.single_use = false;
16503 return self;
16504 }
16505
16506 let fixed = self.fixed_value();
16507 let single_use = def.single_use
16508 && !(parent instanceof AST_Call
16509 && (parent.is_expr_pure(compressor))
16510 || has_annotation(parent, _NOINLINE))
16511 && !(parent instanceof AST_Export
16512 && fixed instanceof AST_Lambda
16513 && fixed.name);
16514
16515 if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
16516 if (retain_top_func(fixed, compressor)) {
16517 single_use = false;
16518 } else if (def.scope !== self.scope
16519 && (def.escaped == 1
16520 || has_flag(fixed, INLINED)
16521 || within_array_or_object_literal(compressor))) {
16522 single_use = false;
16523 } else if (recursive_ref(compressor, def)) {
16524 single_use = false;
16525 } else if (def.scope !== self.scope || def.orig[0] instanceof AST_SymbolFunarg) {
16526 single_use = fixed.is_constant_expression(self.scope);
16527 if (single_use == "f") {
16528 var scope = self.scope;
16529 do {
16530 if (scope instanceof AST_Defun || is_func_expr(scope)) {
16531 set_flag(scope, INLINED);
16532 }
16533 } while (scope = scope.parent_scope);
16534 }
16535 }
16536 }
16537 if (single_use && fixed instanceof AST_Lambda) {
16538 single_use =
16539 def.scope === self.scope
16540 && !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
16541 || parent instanceof AST_Call
16542 && parent.expression === self
16543 && !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
16544 && !(fixed.name && fixed.name.definition().recursive_refs > 0);
16545 }
16546 if (single_use && fixed instanceof AST_Class) {
16547 const extends_inert = !fixed.extends
16548 || !fixed.extends.may_throw(compressor)
16549 && !fixed.extends.has_side_effects(compressor);
16550 single_use = extends_inert
16551 && !fixed.properties.some(prop =>
16552 prop.may_throw(compressor) || prop.has_side_effects(compressor)
16553 );
16554 }
16555
16556 if (single_use && fixed) {
16557 if (fixed instanceof AST_DefClass) {
16558 set_flag(fixed, SQUEEZED);
16559 fixed = make_node(AST_ClassExpression, fixed, fixed);
16560 }
16561 if (fixed instanceof AST_Defun) {
16562 set_flag(fixed, SQUEEZED);
16563 fixed = make_node(AST_Function, fixed, fixed);
16564 }
16565 if (def.recursive_refs > 0 && fixed.name instanceof AST_SymbolDefun) {
16566 const defun_def = fixed.name.definition();
16567 let lambda_def = fixed.variables.get(fixed.name.name);
16568 let name = lambda_def && lambda_def.orig[0];
16569 if (!(name instanceof AST_SymbolLambda)) {
16570 name = make_node(AST_SymbolLambda, fixed.name, fixed.name);
16571 name.scope = fixed;
16572 fixed.name = name;
16573 lambda_def = fixed.def_function(name);
16574 }
16575 walk(fixed, node => {
16576 if (node instanceof AST_SymbolRef && node.definition() === defun_def) {
16577 node.thedef = lambda_def;
16578 lambda_def.references.push(node);
16579 }
16580 });
16581 }
16582 if (
16583 (fixed instanceof AST_Lambda || fixed instanceof AST_Class)
16584 && fixed.parent_scope !== nearest_scope
16585 ) {
16586 fixed = fixed.clone(true, compressor.get_toplevel());
16587
16588 nearest_scope.add_child_scope(fixed);
16589 }
16590 return fixed.optimize(compressor);
16591 }
16592
16593 // multiple uses
16594 if (fixed) {
16595 let replace;
16596
16597 if (fixed instanceof AST_This) {
16598 if (!(def.orig[0] instanceof AST_SymbolFunarg)
16599 && def.references.every((ref) =>
16600 def.scope === ref.scope
16601 )) {
16602 replace = fixed;
16603 }
16604 } else {
16605 var ev = fixed.evaluate(compressor);
16606 if (
16607 ev !== fixed
16608 && (compressor.option("unsafe_regexp") || !(ev instanceof RegExp))
16609 ) {
16610 replace = make_node_from_constant(ev, fixed);
16611 }
16612 }
16613
16614 if (replace) {
16615 const name_length = self.size(compressor);
16616 const replace_size = replace.size(compressor);
16617
16618 let overhead = 0;
16619 if (compressor.option("unused") && !compressor.exposed(def)) {
16620 overhead =
16621 (name_length + 2 + replace_size) /
16622 (def.references.length - def.assignments);
16623 }
16624
16625 if (replace_size <= name_length + overhead) {
16626 return replace;
16627 }
16628 }
16629 }
16630 }
16631 return self;
16632});
16633
16634function scope_encloses_variables_in_this_scope(scope, pulled_scope) {
16635 for (const enclosed of pulled_scope.enclosed) {
16636 if (pulled_scope.variables.has(enclosed.name)) {
16637 continue;
16638 }
16639 const looked_up = scope.find_variable(enclosed.name);
16640 if (looked_up) {
16641 if (looked_up === enclosed) continue;
16642 return true;
16643 }
16644 }
16645 return false;
16646}
16647
16648function is_atomic(lhs, self) {
16649 return lhs instanceof AST_SymbolRef || lhs.TYPE === self.TYPE;
16650}
16651
16652def_optimize(AST_Undefined, function(self, compressor) {
16653 if (compressor.option("unsafe_undefined")) {
16654 var undef = find_variable(compressor, "undefined");
16655 if (undef) {
16656 var ref = make_node(AST_SymbolRef, self, {
16657 name : "undefined",
16658 scope : undef.scope,
16659 thedef : undef
16660 });
16661 set_flag(ref, UNDEFINED);
16662 return ref;
16663 }
16664 }
16665 var lhs = is_lhs(compressor.self(), compressor.parent());
16666 if (lhs && is_atomic(lhs, self)) return self;
16667 return make_node(AST_UnaryPrefix, self, {
16668 operator: "void",
16669 expression: make_node(AST_Number, self, {
16670 value: 0
16671 })
16672 });
16673});
16674
16675def_optimize(AST_Infinity, function(self, compressor) {
16676 var lhs = is_lhs(compressor.self(), compressor.parent());
16677 if (lhs && is_atomic(lhs, self)) return self;
16678 if (
16679 compressor.option("keep_infinity")
16680 && !(lhs && !is_atomic(lhs, self))
16681 && !find_variable(compressor, "Infinity")
16682 ) {
16683 return self;
16684 }
16685 return make_node(AST_Binary, self, {
16686 operator: "/",
16687 left: make_node(AST_Number, self, {
16688 value: 1
16689 }),
16690 right: make_node(AST_Number, self, {
16691 value: 0
16692 })
16693 });
16694});
16695
16696def_optimize(AST_NaN, function(self, compressor) {
16697 var lhs = is_lhs(compressor.self(), compressor.parent());
16698 if (lhs && !is_atomic(lhs, self)
16699 || find_variable(compressor, "NaN")) {
16700 return make_node(AST_Binary, self, {
16701 operator: "/",
16702 left: make_node(AST_Number, self, {
16703 value: 0
16704 }),
16705 right: make_node(AST_Number, self, {
16706 value: 0
16707 })
16708 });
16709 }
16710 return self;
16711});
16712
16713function is_reachable(self, defs) {
16714 const find_ref = node => {
16715 if (node instanceof AST_SymbolRef && member(node.definition(), defs)) {
16716 return walk_abort;
16717 }
16718 };
16719
16720 return walk_parent(self, (node, info) => {
16721 if (node instanceof AST_Scope && node !== self) {
16722 var parent = info.parent();
16723
16724 if (parent instanceof AST_Call && parent.expression === node) return;
16725
16726 if (walk(node, find_ref)) return walk_abort;
16727
16728 return true;
16729 }
16730 });
16731}
16732
16733const ASSIGN_OPS = makePredicate("+ - / * % >> << >>> | ^ &");
16734const ASSIGN_OPS_COMMUTATIVE = makePredicate("* | ^ &");
16735def_optimize(AST_Assign, function(self, compressor) {
16736 var def;
16737 if (compressor.option("dead_code")
16738 && self.left instanceof AST_SymbolRef
16739 && (def = self.left.definition()).scope === compressor.find_parent(AST_Lambda)) {
16740 var level = 0, node, parent = self;
16741 do {
16742 node = parent;
16743 parent = compressor.parent(level++);
16744 if (parent instanceof AST_Exit) {
16745 if (in_try(level, parent)) break;
16746 if (is_reachable(def.scope, [ def ])) break;
16747 if (self.operator == "=") return self.right;
16748 def.fixed = false;
16749 return make_node(AST_Binary, self, {
16750 operator: self.operator.slice(0, -1),
16751 left: self.left,
16752 right: self.right
16753 }).optimize(compressor);
16754 }
16755 } while (parent instanceof AST_Binary && parent.right === node
16756 || parent instanceof AST_Sequence && parent.tail_node() === node);
16757 }
16758 self = self.lift_sequences(compressor);
16759 if (self.operator == "=" && self.left instanceof AST_SymbolRef && self.right instanceof AST_Binary) {
16760 // x = expr1 OP expr2
16761 if (self.right.left instanceof AST_SymbolRef
16762 && self.right.left.name == self.left.name
16763 && ASSIGN_OPS.has(self.right.operator)) {
16764 // x = x - 2 ---> x -= 2
16765 self.operator = self.right.operator + "=";
16766 self.right = self.right.right;
16767 } else if (self.right.right instanceof AST_SymbolRef
16768 && self.right.right.name == self.left.name
16769 && ASSIGN_OPS_COMMUTATIVE.has(self.right.operator)
16770 && !self.right.left.has_side_effects(compressor)) {
16771 // x = 2 & x ---> x &= 2
16772 self.operator = self.right.operator + "=";
16773 self.right = self.right.left;
16774 }
16775 }
16776 return self;
16777
16778 function in_try(level, node) {
16779 var right = self.right;
16780 self.right = make_node(AST_Null, right);
16781 var may_throw = node.may_throw(compressor);
16782 self.right = right;
16783 var scope = self.left.definition().scope;
16784 var parent;
16785 while ((parent = compressor.parent(level++)) !== scope) {
16786 if (parent instanceof AST_Try) {
16787 if (parent.bfinally) return true;
16788 if (may_throw && parent.bcatch) return true;
16789 }
16790 }
16791 }
16792});
16793
16794def_optimize(AST_DefaultAssign, function(self, compressor) {
16795 if (!compressor.option("evaluate")) {
16796 return self;
16797 }
16798 var evaluateRight = self.right.evaluate(compressor);
16799
16800 // `[x = undefined] = foo` ---> `[x] = foo`
16801 if (evaluateRight === undefined) {
16802 self = self.left;
16803 } else if (evaluateRight !== self.right) {
16804 evaluateRight = make_node_from_constant(evaluateRight, self.right);
16805 self.right = best_of_expression(evaluateRight, self.right);
16806 }
16807
16808 return self;
16809});
16810
16811function is_nullish(node) {
16812 let fixed;
16813 return (
16814 node instanceof AST_Null
16815 || is_undefined(node)
16816 || (
16817 node instanceof AST_SymbolRef
16818 && (fixed = node.definition().fixed) instanceof AST_Node
16819 && is_nullish(fixed)
16820 )
16821 // Recurse into those optional chains!
16822 || node instanceof AST_PropAccess && node.optional && is_nullish(node.expression)
16823 || node instanceof AST_Call && node.optional && is_nullish(node.expression)
16824 || node instanceof AST_Chain && is_nullish(node.expression)
16825 );
16826}
16827
16828function is_nullish_check(check, check_subject, compressor) {
16829 if (check_subject.may_throw(compressor)) return false;
16830
16831 let nullish_side;
16832
16833 // foo == null
16834 if (
16835 check instanceof AST_Binary
16836 && check.operator === "=="
16837 // which side is nullish?
16838 && (
16839 (nullish_side = is_nullish(check.left) && check.left)
16840 || (nullish_side = is_nullish(check.right) && check.right)
16841 )
16842 // is the other side the same as the check_subject
16843 && (
16844 nullish_side === check.left
16845 ? check.right
16846 : check.left
16847 ).equivalent_to(check_subject)
16848 ) {
16849 return true;
16850 }
16851
16852 // foo === null || foo === undefined
16853 if (check instanceof AST_Binary && check.operator === "||") {
16854 let null_cmp;
16855 let undefined_cmp;
16856
16857 const find_comparison = cmp => {
16858 if (!(
16859 cmp instanceof AST_Binary
16860 && (cmp.operator === "===" || cmp.operator === "==")
16861 )) {
16862 return false;
16863 }
16864
16865 let found = 0;
16866 let defined_side;
16867
16868 if (cmp.left instanceof AST_Null) {
16869 found++;
16870 null_cmp = cmp;
16871 defined_side = cmp.right;
16872 }
16873 if (cmp.right instanceof AST_Null) {
16874 found++;
16875 null_cmp = cmp;
16876 defined_side = cmp.left;
16877 }
16878 if (is_undefined(cmp.left)) {
16879 found++;
16880 undefined_cmp = cmp;
16881 defined_side = cmp.right;
16882 }
16883 if (is_undefined(cmp.right)) {
16884 found++;
16885 undefined_cmp = cmp;
16886 defined_side = cmp.left;
16887 }
16888
16889 if (found !== 1) {
16890 return false;
16891 }
16892
16893 if (!defined_side.equivalent_to(check_subject)) {
16894 return false;
16895 }
16896
16897 return true;
16898 };
16899
16900 if (!find_comparison(check.left)) return false;
16901 if (!find_comparison(check.right)) return false;
16902
16903 if (null_cmp && undefined_cmp && null_cmp !== undefined_cmp) {
16904 return true;
16905 }
16906 }
16907
16908 return false;
16909}
16910
16911def_optimize(AST_Conditional, function(self, compressor) {
16912 if (!compressor.option("conditionals")) return self;
16913 // This looks like lift_sequences(), should probably be under "sequences"
16914 if (self.condition instanceof AST_Sequence) {
16915 var expressions = self.condition.expressions.slice();
16916 self.condition = expressions.pop();
16917 expressions.push(self);
16918 return make_sequence(self, expressions);
16919 }
16920 var cond = self.condition.evaluate(compressor);
16921 if (cond !== self.condition) {
16922 if (cond) {
16923 return maintain_this_binding(compressor.parent(), compressor.self(), self.consequent);
16924 } else {
16925 return maintain_this_binding(compressor.parent(), compressor.self(), self.alternative);
16926 }
16927 }
16928 var negated = cond.negate(compressor, first_in_statement(compressor));
16929 if (best_of(compressor, cond, negated) === negated) {
16930 self = make_node(AST_Conditional, self, {
16931 condition: negated,
16932 consequent: self.alternative,
16933 alternative: self.consequent
16934 });
16935 }
16936 var condition = self.condition;
16937 var consequent = self.consequent;
16938 var alternative = self.alternative;
16939 // x?x:y --> x||y
16940 if (condition instanceof AST_SymbolRef
16941 && consequent instanceof AST_SymbolRef
16942 && condition.definition() === consequent.definition()) {
16943 return make_node(AST_Binary, self, {
16944 operator: "||",
16945 left: condition,
16946 right: alternative
16947 });
16948 }
16949 // if (foo) exp = something; else exp = something_else;
16950 // |
16951 // v
16952 // exp = foo ? something : something_else;
16953 if (consequent instanceof AST_Assign
16954 && alternative instanceof AST_Assign
16955 && consequent.operator == alternative.operator
16956 && consequent.left.equivalent_to(alternative.left)
16957 && (!self.condition.has_side_effects(compressor)
16958 || consequent.operator == "="
16959 && !consequent.left.has_side_effects(compressor))) {
16960 return make_node(AST_Assign, self, {
16961 operator: consequent.operator,
16962 left: consequent.left,
16963 right: make_node(AST_Conditional, self, {
16964 condition: self.condition,
16965 consequent: consequent.right,
16966 alternative: alternative.right
16967 })
16968 });
16969 }
16970 // x ? y(a) : y(b) --> y(x ? a : b)
16971 var arg_index;
16972 if (consequent instanceof AST_Call
16973 && alternative.TYPE === consequent.TYPE
16974 && consequent.args.length > 0
16975 && consequent.args.length == alternative.args.length
16976 && consequent.expression.equivalent_to(alternative.expression)
16977 && !self.condition.has_side_effects(compressor)
16978 && !consequent.expression.has_side_effects(compressor)
16979 && typeof (arg_index = single_arg_diff()) == "number") {
16980 var node = consequent.clone();
16981 node.args[arg_index] = make_node(AST_Conditional, self, {
16982 condition: self.condition,
16983 consequent: consequent.args[arg_index],
16984 alternative: alternative.args[arg_index]
16985 });
16986 return node;
16987 }
16988 // a ? b : c ? b : d --> (a || c) ? b : d
16989 if (alternative instanceof AST_Conditional
16990 && consequent.equivalent_to(alternative.consequent)) {
16991 return make_node(AST_Conditional, self, {
16992 condition: make_node(AST_Binary, self, {
16993 operator: "||",
16994 left: condition,
16995 right: alternative.condition
16996 }),
16997 consequent: consequent,
16998 alternative: alternative.alternative
16999 }).optimize(compressor);
17000 }
17001
17002 // a == null ? b : a -> a ?? b
17003 if (
17004 compressor.option("ecma") >= 2020 &&
17005 is_nullish_check(condition, alternative, compressor)
17006 ) {
17007 return make_node(AST_Binary, self, {
17008 operator: "??",
17009 left: alternative,
17010 right: consequent
17011 }).optimize(compressor);
17012 }
17013
17014 // a ? b : (c, b) --> (a || c), b
17015 if (alternative instanceof AST_Sequence
17016 && consequent.equivalent_to(alternative.expressions[alternative.expressions.length - 1])) {
17017 return make_sequence(self, [
17018 make_node(AST_Binary, self, {
17019 operator: "||",
17020 left: condition,
17021 right: make_sequence(self, alternative.expressions.slice(0, -1))
17022 }),
17023 consequent
17024 ]).optimize(compressor);
17025 }
17026 // a ? b : (c && b) --> (a || c) && b
17027 if (alternative instanceof AST_Binary
17028 && alternative.operator == "&&"
17029 && consequent.equivalent_to(alternative.right)) {
17030 return make_node(AST_Binary, self, {
17031 operator: "&&",
17032 left: make_node(AST_Binary, self, {
17033 operator: "||",
17034 left: condition,
17035 right: alternative.left
17036 }),
17037 right: consequent
17038 }).optimize(compressor);
17039 }
17040 // x?y?z:a:a --> x&&y?z:a
17041 if (consequent instanceof AST_Conditional
17042 && consequent.alternative.equivalent_to(alternative)) {
17043 return make_node(AST_Conditional, self, {
17044 condition: make_node(AST_Binary, self, {
17045 left: self.condition,
17046 operator: "&&",
17047 right: consequent.condition
17048 }),
17049 consequent: consequent.consequent,
17050 alternative: alternative
17051 });
17052 }
17053 // x ? y : y --> x, y
17054 if (consequent.equivalent_to(alternative)) {
17055 return make_sequence(self, [
17056 self.condition,
17057 consequent
17058 ]).optimize(compressor);
17059 }
17060 // x ? y || z : z --> x && y || z
17061 if (consequent instanceof AST_Binary
17062 && consequent.operator == "||"
17063 && consequent.right.equivalent_to(alternative)) {
17064 return make_node(AST_Binary, self, {
17065 operator: "||",
17066 left: make_node(AST_Binary, self, {
17067 operator: "&&",
17068 left: self.condition,
17069 right: consequent.left
17070 }),
17071 right: alternative
17072 }).optimize(compressor);
17073 }
17074 var in_bool = compressor.in_boolean_context();
17075 if (is_true(self.consequent)) {
17076 if (is_false(self.alternative)) {
17077 // c ? true : false ---> !!c
17078 return booleanize(self.condition);
17079 }
17080 // c ? true : x ---> !!c || x
17081 return make_node(AST_Binary, self, {
17082 operator: "||",
17083 left: booleanize(self.condition),
17084 right: self.alternative
17085 });
17086 }
17087 if (is_false(self.consequent)) {
17088 if (is_true(self.alternative)) {
17089 // c ? false : true ---> !c
17090 return booleanize(self.condition.negate(compressor));
17091 }
17092 // c ? false : x ---> !c && x
17093 return make_node(AST_Binary, self, {
17094 operator: "&&",
17095 left: booleanize(self.condition.negate(compressor)),
17096 right: self.alternative
17097 });
17098 }
17099 if (is_true(self.alternative)) {
17100 // c ? x : true ---> !c || x
17101 return make_node(AST_Binary, self, {
17102 operator: "||",
17103 left: booleanize(self.condition.negate(compressor)),
17104 right: self.consequent
17105 });
17106 }
17107 if (is_false(self.alternative)) {
17108 // c ? x : false ---> !!c && x
17109 return make_node(AST_Binary, self, {
17110 operator: "&&",
17111 left: booleanize(self.condition),
17112 right: self.consequent
17113 });
17114 }
17115
17116 return self;
17117
17118 function booleanize(node) {
17119 if (node.is_boolean()) return node;
17120 // !!expression
17121 return make_node(AST_UnaryPrefix, node, {
17122 operator: "!",
17123 expression: node.negate(compressor)
17124 });
17125 }
17126
17127 // AST_True or !0
17128 function is_true(node) {
17129 return node instanceof AST_True
17130 || in_bool
17131 && node instanceof AST_Constant
17132 && node.getValue()
17133 || (node instanceof AST_UnaryPrefix
17134 && node.operator == "!"
17135 && node.expression instanceof AST_Constant
17136 && !node.expression.getValue());
17137 }
17138 // AST_False or !1
17139 function is_false(node) {
17140 return node instanceof AST_False
17141 || in_bool
17142 && node instanceof AST_Constant
17143 && !node.getValue()
17144 || (node instanceof AST_UnaryPrefix
17145 && node.operator == "!"
17146 && node.expression instanceof AST_Constant
17147 && node.expression.getValue());
17148 }
17149
17150 function single_arg_diff() {
17151 var a = consequent.args;
17152 var b = alternative.args;
17153 for (var i = 0, len = a.length; i < len; i++) {
17154 if (a[i] instanceof AST_Expansion) return;
17155 if (!a[i].equivalent_to(b[i])) {
17156 if (b[i] instanceof AST_Expansion) return;
17157 for (var j = i + 1; j < len; j++) {
17158 if (a[j] instanceof AST_Expansion) return;
17159 if (!a[j].equivalent_to(b[j])) return;
17160 }
17161 return i;
17162 }
17163 }
17164 }
17165});
17166
17167def_optimize(AST_Boolean, function(self, compressor) {
17168 if (compressor.in_boolean_context()) return make_node(AST_Number, self, {
17169 value: +self.value
17170 });
17171 var p = compressor.parent();
17172 if (compressor.option("booleans_as_integers")) {
17173 if (p instanceof AST_Binary && (p.operator == "===" || p.operator == "!==")) {
17174 p.operator = p.operator.replace(/=$/, "");
17175 }
17176 return make_node(AST_Number, self, {
17177 value: +self.value
17178 });
17179 }
17180 if (compressor.option("booleans")) {
17181 if (p instanceof AST_Binary && (p.operator == "=="
17182 || p.operator == "!=")) {
17183 return make_node(AST_Number, self, {
17184 value: +self.value
17185 });
17186 }
17187 return make_node(AST_UnaryPrefix, self, {
17188 operator: "!",
17189 expression: make_node(AST_Number, self, {
17190 value: 1 - self.value
17191 })
17192 });
17193 }
17194 return self;
17195});
17196
17197function safe_to_flatten(value, compressor) {
17198 if (value instanceof AST_SymbolRef) {
17199 value = value.fixed_value();
17200 }
17201 if (!value) return false;
17202 if (!(value instanceof AST_Lambda || value instanceof AST_Class)) return true;
17203 if (!(value instanceof AST_Lambda && value.contains_this())) return true;
17204 return compressor.parent() instanceof AST_New;
17205}
17206
17207AST_PropAccess.DEFMETHOD("flatten_object", function(key, compressor) {
17208 if (!compressor.option("properties")) return;
17209 var arrows = compressor.option("unsafe_arrows") && compressor.option("ecma") >= 2015;
17210 var expr = this.expression;
17211 if (expr instanceof AST_Object) {
17212 var props = expr.properties;
17213 for (var i = props.length; --i >= 0;) {
17214 var prop = props[i];
17215 if ("" + (prop instanceof AST_ConciseMethod ? prop.key.name : prop.key) == key) {
17216 if (!props.every((prop) => {
17217 return prop instanceof AST_ObjectKeyVal
17218 || arrows && prop instanceof AST_ConciseMethod && !prop.is_generator;
17219 })) break;
17220 if (!safe_to_flatten(prop.value, compressor)) break;
17221 return make_node(AST_Sub, this, {
17222 expression: make_node(AST_Array, expr, {
17223 elements: props.map(function(prop) {
17224 var v = prop.value;
17225 if (v instanceof AST_Accessor) v = make_node(AST_Function, v, v);
17226 var k = prop.key;
17227 if (k instanceof AST_Node && !(k instanceof AST_SymbolMethod)) {
17228 return make_sequence(prop, [ k, v ]);
17229 }
17230 return v;
17231 })
17232 }),
17233 property: make_node(AST_Number, this, {
17234 value: i
17235 })
17236 });
17237 }
17238 }
17239 }
17240});
17241
17242def_optimize(AST_Sub, function(self, compressor) {
17243 var expr = self.expression;
17244 var prop = self.property;
17245 if (compressor.option("properties")) {
17246 var key = prop.evaluate(compressor);
17247 if (key !== prop) {
17248 if (typeof key == "string") {
17249 if (key == "undefined") {
17250 key = undefined;
17251 } else {
17252 var value = parseFloat(key);
17253 if (value.toString() == key) {
17254 key = value;
17255 }
17256 }
17257 }
17258 prop = self.property = best_of_expression(prop, make_node_from_constant(key, prop).transform(compressor));
17259 var property = "" + key;
17260 if (is_basic_identifier_string(property)
17261 && property.length <= prop.size() + 1) {
17262 return make_node(AST_Dot, self, {
17263 expression: expr,
17264 optional: self.optional,
17265 property: property,
17266 quote: prop.quote,
17267 }).optimize(compressor);
17268 }
17269 }
17270 }
17271 var fn;
17272 OPT_ARGUMENTS: if (compressor.option("arguments")
17273 && expr instanceof AST_SymbolRef
17274 && expr.name == "arguments"
17275 && expr.definition().orig.length == 1
17276 && (fn = expr.scope) instanceof AST_Lambda
17277 && fn.uses_arguments
17278 && !(fn instanceof AST_Arrow)
17279 && prop instanceof AST_Number) {
17280 var index = prop.getValue();
17281 var params = new Set();
17282 var argnames = fn.argnames;
17283 for (var n = 0; n < argnames.length; n++) {
17284 if (!(argnames[n] instanceof AST_SymbolFunarg)) {
17285 break OPT_ARGUMENTS; // destructuring parameter - bail
17286 }
17287 var param = argnames[n].name;
17288 if (params.has(param)) {
17289 break OPT_ARGUMENTS; // duplicate parameter - bail
17290 }
17291 params.add(param);
17292 }
17293 var argname = fn.argnames[index];
17294 if (argname && compressor.has_directive("use strict")) {
17295 var def = argname.definition();
17296 if (!compressor.option("reduce_vars") || def.assignments || def.orig.length > 1) {
17297 argname = null;
17298 }
17299 } else if (!argname && !compressor.option("keep_fargs") && index < fn.argnames.length + 5) {
17300 while (index >= fn.argnames.length) {
17301 argname = fn.create_symbol(AST_SymbolFunarg, {
17302 source: fn,
17303 scope: fn,
17304 tentative_name: "argument_" + fn.argnames.length,
17305 });
17306 fn.argnames.push(argname);
17307 }
17308 }
17309 if (argname) {
17310 var sym = make_node(AST_SymbolRef, self, argname);
17311 sym.reference({});
17312 clear_flag(argname, UNUSED);
17313 return sym;
17314 }
17315 }
17316 if (is_lhs(self, compressor.parent())) return self;
17317 if (key !== prop) {
17318 var sub = self.flatten_object(property, compressor);
17319 if (sub) {
17320 expr = self.expression = sub.expression;
17321 prop = self.property = sub.property;
17322 }
17323 }
17324 if (compressor.option("properties") && compressor.option("side_effects")
17325 && prop instanceof AST_Number && expr instanceof AST_Array) {
17326 var index = prop.getValue();
17327 var elements = expr.elements;
17328 var retValue = elements[index];
17329 FLATTEN: if (safe_to_flatten(retValue, compressor)) {
17330 var flatten = true;
17331 var values = [];
17332 for (var i = elements.length; --i > index;) {
17333 var value = elements[i].drop_side_effect_free(compressor);
17334 if (value) {
17335 values.unshift(value);
17336 if (flatten && value.has_side_effects(compressor)) flatten = false;
17337 }
17338 }
17339 if (retValue instanceof AST_Expansion) break FLATTEN;
17340 retValue = retValue instanceof AST_Hole ? make_node(AST_Undefined, retValue) : retValue;
17341 if (!flatten) values.unshift(retValue);
17342 while (--i >= 0) {
17343 var value = elements[i];
17344 if (value instanceof AST_Expansion) break FLATTEN;
17345 value = value.drop_side_effect_free(compressor);
17346 if (value) values.unshift(value);
17347 else index--;
17348 }
17349 if (flatten) {
17350 values.push(retValue);
17351 return make_sequence(self, values).optimize(compressor);
17352 } else return make_node(AST_Sub, self, {
17353 expression: make_node(AST_Array, expr, {
17354 elements: values
17355 }),
17356 property: make_node(AST_Number, prop, {
17357 value: index
17358 })
17359 });
17360 }
17361 }
17362 var ev = self.evaluate(compressor);
17363 if (ev !== self) {
17364 ev = make_node_from_constant(ev, self).optimize(compressor);
17365 return best_of(compressor, ev, self);
17366 }
17367 if (self.optional && is_nullish(self.expression)) {
17368 return make_node(AST_Undefined, self);
17369 }
17370 return self;
17371});
17372
17373def_optimize(AST_Chain, function (self, compressor) {
17374 self.expression = self.expression.optimize(compressor);
17375 return self;
17376});
17377
17378AST_Lambda.DEFMETHOD("contains_this", function() {
17379 return walk(this, node => {
17380 if (node instanceof AST_This) return walk_abort;
17381 if (
17382 node !== this
17383 && node instanceof AST_Scope
17384 && !(node instanceof AST_Arrow)
17385 ) {
17386 return true;
17387 }
17388 });
17389});
17390
17391def_optimize(AST_Dot, function(self, compressor) {
17392 const parent = compressor.parent();
17393 if (is_lhs(self, parent)) return self;
17394 if (compressor.option("unsafe_proto")
17395 && self.expression instanceof AST_Dot
17396 && self.expression.property == "prototype") {
17397 var exp = self.expression.expression;
17398 if (is_undeclared_ref(exp)) switch (exp.name) {
17399 case "Array":
17400 self.expression = make_node(AST_Array, self.expression, {
17401 elements: []
17402 });
17403 break;
17404 case "Function":
17405 self.expression = make_node(AST_Function, self.expression, {
17406 argnames: [],
17407 body: []
17408 });
17409 break;
17410 case "Number":
17411 self.expression = make_node(AST_Number, self.expression, {
17412 value: 0
17413 });
17414 break;
17415 case "Object":
17416 self.expression = make_node(AST_Object, self.expression, {
17417 properties: []
17418 });
17419 break;
17420 case "RegExp":
17421 self.expression = make_node(AST_RegExp, self.expression, {
17422 value: { source: "t", flags: "" }
17423 });
17424 break;
17425 case "String":
17426 self.expression = make_node(AST_String, self.expression, {
17427 value: ""
17428 });
17429 break;
17430 }
17431 }
17432 if (!(parent instanceof AST_Call) || !has_annotation(parent, _NOINLINE)) {
17433 const sub = self.flatten_object(self.property, compressor);
17434 if (sub) return sub.optimize(compressor);
17435 }
17436 let ev = self.evaluate(compressor);
17437 if (ev !== self) {
17438 ev = make_node_from_constant(ev, self).optimize(compressor);
17439 return best_of(compressor, ev, self);
17440 }
17441 if (self.optional && is_nullish(self.expression)) {
17442 return make_node(AST_Undefined, self);
17443 }
17444 return self;
17445});
17446
17447function literals_in_boolean_context(self, compressor) {
17448 if (compressor.in_boolean_context()) {
17449 return best_of(compressor, self, make_sequence(self, [
17450 self,
17451 make_node(AST_True, self)
17452 ]).optimize(compressor));
17453 }
17454 return self;
17455}
17456
17457function inline_array_like_spread(elements) {
17458 for (var i = 0; i < elements.length; i++) {
17459 var el = elements[i];
17460 if (el instanceof AST_Expansion) {
17461 var expr = el.expression;
17462 if (
17463 expr instanceof AST_Array
17464 && !expr.elements.some(elm => elm instanceof AST_Hole)
17465 ) {
17466 elements.splice(i, 1, ...expr.elements);
17467 // Step back one, as the element at i is now new.
17468 i--;
17469 }
17470 // In array-like spread, spreading a non-iterable value is TypeError.
17471 // We therefore can’t optimize anything else, unlike with object spread.
17472 }
17473 }
17474}
17475
17476def_optimize(AST_Array, function(self, compressor) {
17477 var optimized = literals_in_boolean_context(self, compressor);
17478 if (optimized !== self) {
17479 return optimized;
17480 }
17481 inline_array_like_spread(self.elements);
17482 return self;
17483});
17484
17485function inline_object_prop_spread(props) {
17486 for (var i = 0; i < props.length; i++) {
17487 var prop = props[i];
17488 if (prop instanceof AST_Expansion) {
17489 const expr = prop.expression;
17490 if (
17491 expr instanceof AST_Object
17492 && expr.properties.every(prop => prop instanceof AST_ObjectKeyVal)
17493 ) {
17494 props.splice(i, 1, ...expr.properties);
17495 // Step back one, as the property at i is now new.
17496 i--;
17497 } else if (expr instanceof AST_Constant
17498 && !(expr instanceof AST_String)) {
17499 // Unlike array-like spread, in object spread, spreading a
17500 // non-iterable value silently does nothing; it is thus safe
17501 // to remove. AST_String is the only iterable AST_Constant.
17502 props.splice(i, 1);
17503 }
17504 }
17505 }
17506}
17507
17508def_optimize(AST_Object, function(self, compressor) {
17509 var optimized = literals_in_boolean_context(self, compressor);
17510 if (optimized !== self) {
17511 return optimized;
17512 }
17513 inline_object_prop_spread(self.properties);
17514 return self;
17515});
17516
17517def_optimize(AST_RegExp, literals_in_boolean_context);
17518
17519def_optimize(AST_Return, function(self, compressor) {
17520 if (self.value && is_undefined(self.value, compressor)) {
17521 self.value = null;
17522 }
17523 return self;
17524});
17525
17526def_optimize(AST_Arrow, opt_AST_Lambda);
17527
17528def_optimize(AST_Function, function(self, compressor) {
17529 self = opt_AST_Lambda(self, compressor);
17530 if (compressor.option("unsafe_arrows")
17531 && compressor.option("ecma") >= 2015
17532 && !self.name
17533 && !self.is_generator
17534 && !self.uses_arguments
17535 && !self.pinned()) {
17536 const uses_this = walk(self, node => {
17537 if (node instanceof AST_This) return walk_abort;
17538 });
17539 if (!uses_this) return make_node(AST_Arrow, self, self).optimize(compressor);
17540 }
17541 return self;
17542});
17543
17544def_optimize(AST_Class, function(self) {
17545 // HACK to avoid compress failure.
17546 // AST_Class is not really an AST_Scope/AST_Block as it lacks a body.
17547 return self;
17548});
17549
17550def_optimize(AST_Yield, function(self, compressor) {
17551 if (self.expression && !self.is_star && is_undefined(self.expression, compressor)) {
17552 self.expression = null;
17553 }
17554 return self;
17555});
17556
17557def_optimize(AST_TemplateString, function(self, compressor) {
17558 if (!compressor.option("evaluate")
17559 || compressor.parent() instanceof AST_PrefixedTemplateString)
17560 return self;
17561
17562 var segments = [];
17563 for (var i = 0; i < self.segments.length; i++) {
17564 var segment = self.segments[i];
17565 if (segment instanceof AST_Node) {
17566 var result = segment.evaluate(compressor);
17567 // Evaluate to constant value
17568 // Constant value shorter than ${segment}
17569 if (result !== segment && (result + "").length <= segment.size() + "${}".length) {
17570 // There should always be a previous and next segment if segment is a node
17571 segments[segments.length - 1].value = segments[segments.length - 1].value + result + self.segments[++i].value;
17572 continue;
17573 }
17574 // `before ${`innerBefore ${any} innerAfter`} after` => `before innerBefore ${any} innerAfter after`
17575 // TODO:
17576 // `before ${'test' + foo} after` => `before innerBefore ${any} innerAfter after`
17577 // `before ${foo + 'test} after` => `before innerBefore ${any} innerAfter after`
17578 if (segment instanceof AST_TemplateString) {
17579 var inners = segment.segments;
17580 segments[segments.length - 1].value += inners[0].value;
17581 for (var j = 1; j < inners.length; j++) {
17582 segment = inners[j];
17583 segments.push(segment);
17584 }
17585 continue;
17586 }
17587 }
17588 segments.push(segment);
17589 }
17590 self.segments = segments;
17591
17592 // `foo` => "foo"
17593 if (segments.length == 1) {
17594 return make_node(AST_String, self, segments[0]);
17595 }
17596 if (segments.length === 3 && segments[1] instanceof AST_Node) {
17597 // `foo${bar}` => "foo" + bar
17598 if (segments[2].value === "") {
17599 return make_node(AST_Binary, self, {
17600 operator: "+",
17601 left: make_node(AST_String, self, {
17602 value: segments[0].value,
17603 }),
17604 right: segments[1],
17605 });
17606 }
17607 // `{bar}baz` => bar + "baz"
17608 if (segments[0].value === "") {
17609 return make_node(AST_Binary, self, {
17610 operator: "+",
17611 left: segments[1],
17612 right: make_node(AST_String, self, {
17613 value: segments[2].value,
17614 }),
17615 });
17616 }
17617 }
17618 return self;
17619});
17620
17621def_optimize(AST_PrefixedTemplateString, function(self) {
17622 return self;
17623});
17624
17625// ["p"]:1 ---> p:1
17626// [42]:1 ---> 42:1
17627function lift_key(self, compressor) {
17628 if (!compressor.option("computed_props")) return self;
17629 // save a comparison in the typical case
17630 if (!(self.key instanceof AST_Constant)) return self;
17631 // allow certain acceptable props as not all AST_Constants are true constants
17632 if (self.key instanceof AST_String || self.key instanceof AST_Number) {
17633 if (self.key.value === "__proto__") return self;
17634 if (self.key.value == "constructor"
17635 && compressor.parent() instanceof AST_Class) return self;
17636 if (self instanceof AST_ObjectKeyVal) {
17637 self.key = self.key.value;
17638 } else if (self instanceof AST_ClassProperty) {
17639 self.key = make_node(AST_SymbolClassProperty, self.key, {
17640 name: self.key.value
17641 });
17642 } else {
17643 self.key = make_node(AST_SymbolMethod, self.key, {
17644 name: self.key.value
17645 });
17646 }
17647 }
17648 return self;
17649}
17650
17651def_optimize(AST_ObjectProperty, lift_key);
17652
17653def_optimize(AST_ConciseMethod, function(self, compressor) {
17654 lift_key(self, compressor);
17655 // p(){return x;} ---> p:()=>x
17656 if (compressor.option("arrows")
17657 && compressor.parent() instanceof AST_Object
17658 && !self.is_generator
17659 && !self.value.uses_arguments
17660 && !self.value.pinned()
17661 && self.value.body.length == 1
17662 && self.value.body[0] instanceof AST_Return
17663 && self.value.body[0].value
17664 && !self.value.contains_this()) {
17665 var arrow = make_node(AST_Arrow, self.value, self.value);
17666 arrow.async = self.async;
17667 arrow.is_generator = self.is_generator;
17668 return make_node(AST_ObjectKeyVal, self, {
17669 key: self.key instanceof AST_SymbolMethod ? self.key.name : self.key,
17670 value: arrow,
17671 quote: self.quote,
17672 });
17673 }
17674 return self;
17675});
17676
17677def_optimize(AST_ObjectKeyVal, function(self, compressor) {
17678 lift_key(self, compressor);
17679 // p:function(){} ---> p(){}
17680 // p:function*(){} ---> *p(){}
17681 // p:async function(){} ---> async p(){}
17682 // p:()=>{} ---> p(){}
17683 // p:async()=>{} ---> async p(){}
17684 var unsafe_methods = compressor.option("unsafe_methods");
17685 if (unsafe_methods
17686 && compressor.option("ecma") >= 2015
17687 && (!(unsafe_methods instanceof RegExp) || unsafe_methods.test(self.key + ""))) {
17688 var key = self.key;
17689 var value = self.value;
17690 var is_arrow_with_block = value instanceof AST_Arrow
17691 && Array.isArray(value.body)
17692 && !value.contains_this();
17693 if ((is_arrow_with_block || value instanceof AST_Function) && !value.name) {
17694 return make_node(AST_ConciseMethod, self, {
17695 async: value.async,
17696 is_generator: value.is_generator,
17697 key: key instanceof AST_Node ? key : make_node(AST_SymbolMethod, self, {
17698 name: key,
17699 }),
17700 value: make_node(AST_Accessor, value, value),
17701 quote: self.quote,
17702 });
17703 }
17704 }
17705 return self;
17706});
17707
17708def_optimize(AST_Destructuring, function(self, compressor) {
17709 if (compressor.option("pure_getters") == true
17710 && compressor.option("unused")
17711 && !self.is_array
17712 && Array.isArray(self.names)
17713 && !is_destructuring_export_decl(compressor)
17714 && !(self.names[self.names.length - 1] instanceof AST_Expansion)) {
17715 var keep = [];
17716 for (var i = 0; i < self.names.length; i++) {
17717 var elem = self.names[i];
17718 if (!(elem instanceof AST_ObjectKeyVal
17719 && typeof elem.key == "string"
17720 && elem.value instanceof AST_SymbolDeclaration
17721 && !should_retain(compressor, elem.value.definition()))) {
17722 keep.push(elem);
17723 }
17724 }
17725 if (keep.length != self.names.length) {
17726 self.names = keep;
17727 }
17728 }
17729 return self;
17730
17731 function is_destructuring_export_decl(compressor) {
17732 var ancestors = [/^VarDef$/, /^(Const|Let|Var)$/, /^Export$/];
17733 for (var a = 0, p = 0, len = ancestors.length; a < len; p++) {
17734 var parent = compressor.parent(p);
17735 if (!parent) return false;
17736 if (a === 0 && parent.TYPE == "Destructuring") continue;
17737 if (!ancestors[a].test(parent.TYPE)) {
17738 return false;
17739 }
17740 a++;
17741 }
17742 return true;
17743 }
17744
17745 function should_retain(compressor, def) {
17746 if (def.references.length) return true;
17747 if (!def.global) return false;
17748 if (compressor.toplevel.vars) {
17749 if (compressor.top_retain) {
17750 return compressor.top_retain(def);
17751 }
17752 return false;
17753 }
17754 return true;
17755 }
17756});
17757
17758/***********************************************************************
17759
17760 A JavaScript tokenizer / parser / beautifier / compressor.
17761 https://github.com/mishoo/UglifyJS2
17762
17763 -------------------------------- (C) ---------------------------------
17764
17765 Author: Mihai Bazon
17766 <mihai.bazon@gmail.com>
17767 http://mihai.bazon.net/blog
17768
17769 Distributed under the BSD license:
17770
17771 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
17772
17773 Redistribution and use in source and binary forms, with or without
17774 modification, are permitted provided that the following conditions
17775 are met:
17776
17777 * Redistributions of source code must retain the above
17778 copyright notice, this list of conditions and the following
17779 disclaimer.
17780
17781 * Redistributions in binary form must reproduce the above
17782 copyright notice, this list of conditions and the following
17783 disclaimer in the documentation and/or other materials
17784 provided with the distribution.
17785
17786 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
17787 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17788 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17789 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
17790 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
17791 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17792 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
17793 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
17794 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
17795 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
17796 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
17797 SUCH DAMAGE.
17798
17799 ***********************************************************************/
17800
17801// a small wrapper around fitzgen's source-map library
17802async function SourceMap(options) {
17803 options = defaults(options, {
17804 file : null,
17805 root : null,
17806 orig : null,
17807
17808 orig_line_diff : 0,
17809 dest_line_diff : 0,
17810 });
17811
17812 var orig_map;
17813 var generator = new MOZ_SourceMap.SourceMapGenerator({
17814 file : options.file,
17815 sourceRoot : options.root
17816 });
17817
17818 if (options.orig) {
17819 orig_map = await new MOZ_SourceMap.SourceMapConsumer(options.orig);
17820 orig_map.sources.forEach(function(source) {
17821 var sourceContent = orig_map.sourceContentFor(source, true);
17822 if (sourceContent) {
17823 generator.setSourceContent(source, sourceContent);
17824 }
17825 });
17826 }
17827
17828 function add(source, gen_line, gen_col, orig_line, orig_col, name) {
17829 if (orig_map) {
17830 var info = orig_map.originalPositionFor({
17831 line: orig_line,
17832 column: orig_col
17833 });
17834 if (info.source === null) {
17835 return;
17836 }
17837 source = info.source;
17838 orig_line = info.line;
17839 orig_col = info.column;
17840 name = info.name || name;
17841 }
17842 generator.addMapping({
17843 generated : { line: gen_line + options.dest_line_diff, column: gen_col },
17844 original : { line: orig_line + options.orig_line_diff, column: orig_col },
17845 source : source,
17846 name : name
17847 });
17848 }
17849
17850 return {
17851 add : add,
17852 get : function() { return generator; },
17853 toString : function() { return generator.toString(); },
17854 destroy : function () {
17855 if (orig_map && orig_map.destroy) {
17856 orig_map.destroy();
17857 }
17858 }
17859 };
17860}
17861
17862var domprops = [
17863 "$&",
17864 "$'",
17865 "$*",
17866 "$+",
17867 "$1",
17868 "$2",
17869 "$3",
17870 "$4",
17871 "$5",
17872 "$6",
17873 "$7",
17874 "$8",
17875 "$9",
17876 "$_",
17877 "$`",
17878 "$input",
17879 "-moz-animation",
17880 "-moz-animation-delay",
17881 "-moz-animation-direction",
17882 "-moz-animation-duration",
17883 "-moz-animation-fill-mode",
17884 "-moz-animation-iteration-count",
17885 "-moz-animation-name",
17886 "-moz-animation-play-state",
17887 "-moz-animation-timing-function",
17888 "-moz-appearance",
17889 "-moz-backface-visibility",
17890 "-moz-border-end",
17891 "-moz-border-end-color",
17892 "-moz-border-end-style",
17893 "-moz-border-end-width",
17894 "-moz-border-image",
17895 "-moz-border-start",
17896 "-moz-border-start-color",
17897 "-moz-border-start-style",
17898 "-moz-border-start-width",
17899 "-moz-box-align",
17900 "-moz-box-direction",
17901 "-moz-box-flex",
17902 "-moz-box-ordinal-group",
17903 "-moz-box-orient",
17904 "-moz-box-pack",
17905 "-moz-box-sizing",
17906 "-moz-float-edge",
17907 "-moz-font-feature-settings",
17908 "-moz-font-language-override",
17909 "-moz-force-broken-image-icon",
17910 "-moz-hyphens",
17911 "-moz-image-region",
17912 "-moz-margin-end",
17913 "-moz-margin-start",
17914 "-moz-orient",
17915 "-moz-osx-font-smoothing",
17916 "-moz-outline-radius",
17917 "-moz-outline-radius-bottomleft",
17918 "-moz-outline-radius-bottomright",
17919 "-moz-outline-radius-topleft",
17920 "-moz-outline-radius-topright",
17921 "-moz-padding-end",
17922 "-moz-padding-start",
17923 "-moz-perspective",
17924 "-moz-perspective-origin",
17925 "-moz-tab-size",
17926 "-moz-text-size-adjust",
17927 "-moz-transform",
17928 "-moz-transform-origin",
17929 "-moz-transform-style",
17930 "-moz-transition",
17931 "-moz-transition-delay",
17932 "-moz-transition-duration",
17933 "-moz-transition-property",
17934 "-moz-transition-timing-function",
17935 "-moz-user-focus",
17936 "-moz-user-input",
17937 "-moz-user-modify",
17938 "-moz-user-select",
17939 "-moz-window-dragging",
17940 "-webkit-align-content",
17941 "-webkit-align-items",
17942 "-webkit-align-self",
17943 "-webkit-animation",
17944 "-webkit-animation-delay",
17945 "-webkit-animation-direction",
17946 "-webkit-animation-duration",
17947 "-webkit-animation-fill-mode",
17948 "-webkit-animation-iteration-count",
17949 "-webkit-animation-name",
17950 "-webkit-animation-play-state",
17951 "-webkit-animation-timing-function",
17952 "-webkit-appearance",
17953 "-webkit-backface-visibility",
17954 "-webkit-background-clip",
17955 "-webkit-background-origin",
17956 "-webkit-background-size",
17957 "-webkit-border-bottom-left-radius",
17958 "-webkit-border-bottom-right-radius",
17959 "-webkit-border-image",
17960 "-webkit-border-radius",
17961 "-webkit-border-top-left-radius",
17962 "-webkit-border-top-right-radius",
17963 "-webkit-box-align",
17964 "-webkit-box-direction",
17965 "-webkit-box-flex",
17966 "-webkit-box-ordinal-group",
17967 "-webkit-box-orient",
17968 "-webkit-box-pack",
17969 "-webkit-box-shadow",
17970 "-webkit-box-sizing",
17971 "-webkit-filter",
17972 "-webkit-flex",
17973 "-webkit-flex-basis",
17974 "-webkit-flex-direction",
17975 "-webkit-flex-flow",
17976 "-webkit-flex-grow",
17977 "-webkit-flex-shrink",
17978 "-webkit-flex-wrap",
17979 "-webkit-justify-content",
17980 "-webkit-line-clamp",
17981 "-webkit-mask",
17982 "-webkit-mask-clip",
17983 "-webkit-mask-composite",
17984 "-webkit-mask-image",
17985 "-webkit-mask-origin",
17986 "-webkit-mask-position",
17987 "-webkit-mask-position-x",
17988 "-webkit-mask-position-y",
17989 "-webkit-mask-repeat",
17990 "-webkit-mask-size",
17991 "-webkit-order",
17992 "-webkit-perspective",
17993 "-webkit-perspective-origin",
17994 "-webkit-text-fill-color",
17995 "-webkit-text-size-adjust",
17996 "-webkit-text-stroke",
17997 "-webkit-text-stroke-color",
17998 "-webkit-text-stroke-width",
17999 "-webkit-transform",
18000 "-webkit-transform-origin",
18001 "-webkit-transform-style",
18002 "-webkit-transition",
18003 "-webkit-transition-delay",
18004 "-webkit-transition-duration",
18005 "-webkit-transition-property",
18006 "-webkit-transition-timing-function",
18007 "-webkit-user-select",
18008 "0",
18009 "1",
18010 "10",
18011 "11",
18012 "12",
18013 "13",
18014 "14",
18015 "15",
18016 "16",
18017 "17",
18018 "18",
18019 "19",
18020 "2",
18021 "20",
18022 "3",
18023 "4",
18024 "5",
18025 "6",
18026 "7",
18027 "8",
18028 "9",
18029 "@@iterator",
18030 "ABORT_ERR",
18031 "ACTIVE",
18032 "ACTIVE_ATTRIBUTES",
18033 "ACTIVE_TEXTURE",
18034 "ACTIVE_UNIFORMS",
18035 "ACTIVE_UNIFORM_BLOCKS",
18036 "ADDITION",
18037 "ALIASED_LINE_WIDTH_RANGE",
18038 "ALIASED_POINT_SIZE_RANGE",
18039 "ALLOW_KEYBOARD_INPUT",
18040 "ALLPASS",
18041 "ALPHA",
18042 "ALPHA_BITS",
18043 "ALREADY_SIGNALED",
18044 "ALT_MASK",
18045 "ALWAYS",
18046 "ANY_SAMPLES_PASSED",
18047 "ANY_SAMPLES_PASSED_CONSERVATIVE",
18048 "ANY_TYPE",
18049 "ANY_UNORDERED_NODE_TYPE",
18050 "ARRAY_BUFFER",
18051 "ARRAY_BUFFER_BINDING",
18052 "ATTACHED_SHADERS",
18053 "ATTRIBUTE_NODE",
18054 "AT_TARGET",
18055 "AbortController",
18056 "AbortSignal",
18057 "AbsoluteOrientationSensor",
18058 "AbstractRange",
18059 "Accelerometer",
18060 "AddSearchProvider",
18061 "AggregateError",
18062 "AnalyserNode",
18063 "Animation",
18064 "AnimationEffect",
18065 "AnimationEvent",
18066 "AnimationPlaybackEvent",
18067 "AnimationTimeline",
18068 "AnonXMLHttpRequest",
18069 "Any",
18070 "ApplicationCache",
18071 "ApplicationCacheErrorEvent",
18072 "Array",
18073 "ArrayBuffer",
18074 "ArrayType",
18075 "Atomics",
18076 "Attr",
18077 "Audio",
18078 "AudioBuffer",
18079 "AudioBufferSourceNode",
18080 "AudioContext",
18081 "AudioDestinationNode",
18082 "AudioListener",
18083 "AudioNode",
18084 "AudioParam",
18085 "AudioParamMap",
18086 "AudioProcessingEvent",
18087 "AudioScheduledSourceNode",
18088 "AudioStreamTrack",
18089 "AudioWorklet",
18090 "AudioWorkletNode",
18091 "AuthenticatorAssertionResponse",
18092 "AuthenticatorAttestationResponse",
18093 "AuthenticatorResponse",
18094 "AutocompleteErrorEvent",
18095 "BACK",
18096 "BAD_BOUNDARYPOINTS_ERR",
18097 "BAD_REQUEST",
18098 "BANDPASS",
18099 "BLEND",
18100 "BLEND_COLOR",
18101 "BLEND_DST_ALPHA",
18102 "BLEND_DST_RGB",
18103 "BLEND_EQUATION",
18104 "BLEND_EQUATION_ALPHA",
18105 "BLEND_EQUATION_RGB",
18106 "BLEND_SRC_ALPHA",
18107 "BLEND_SRC_RGB",
18108 "BLUE_BITS",
18109 "BLUR",
18110 "BOOL",
18111 "BOOLEAN_TYPE",
18112 "BOOL_VEC2",
18113 "BOOL_VEC3",
18114 "BOOL_VEC4",
18115 "BOTH",
18116 "BROWSER_DEFAULT_WEBGL",
18117 "BUBBLING_PHASE",
18118 "BUFFER_SIZE",
18119 "BUFFER_USAGE",
18120 "BYTE",
18121 "BYTES_PER_ELEMENT",
18122 "BackgroundFetchManager",
18123 "BackgroundFetchRecord",
18124 "BackgroundFetchRegistration",
18125 "BarProp",
18126 "BarcodeDetector",
18127 "BaseAudioContext",
18128 "BaseHref",
18129 "BatteryManager",
18130 "BeforeInstallPromptEvent",
18131 "BeforeLoadEvent",
18132 "BeforeUnloadEvent",
18133 "BigInt",
18134 "BigInt64Array",
18135 "BigUint64Array",
18136 "BiquadFilterNode",
18137 "Blob",
18138 "BlobEvent",
18139 "Bluetooth",
18140 "BluetoothCharacteristicProperties",
18141 "BluetoothDevice",
18142 "BluetoothRemoteGATTCharacteristic",
18143 "BluetoothRemoteGATTDescriptor",
18144 "BluetoothRemoteGATTServer",
18145 "BluetoothRemoteGATTService",
18146 "BluetoothUUID",
18147 "Boolean",
18148 "BroadcastChannel",
18149 "ByteLengthQueuingStrategy",
18150 "CAPTURING_PHASE",
18151 "CCW",
18152 "CDATASection",
18153 "CDATA_SECTION_NODE",
18154 "CHANGE",
18155 "CHARSET_RULE",
18156 "CHECKING",
18157 "CLAMP_TO_EDGE",
18158 "CLICK",
18159 "CLOSED",
18160 "CLOSING",
18161 "COLOR",
18162 "COLOR_ATTACHMENT0",
18163 "COLOR_ATTACHMENT1",
18164 "COLOR_ATTACHMENT10",
18165 "COLOR_ATTACHMENT11",
18166 "COLOR_ATTACHMENT12",
18167 "COLOR_ATTACHMENT13",
18168 "COLOR_ATTACHMENT14",
18169 "COLOR_ATTACHMENT15",
18170 "COLOR_ATTACHMENT2",
18171 "COLOR_ATTACHMENT3",
18172 "COLOR_ATTACHMENT4",
18173 "COLOR_ATTACHMENT5",
18174 "COLOR_ATTACHMENT6",
18175 "COLOR_ATTACHMENT7",
18176 "COLOR_ATTACHMENT8",
18177 "COLOR_ATTACHMENT9",
18178 "COLOR_BUFFER_BIT",
18179 "COLOR_CLEAR_VALUE",
18180 "COLOR_WRITEMASK",
18181 "COMMENT_NODE",
18182 "COMPARE_REF_TO_TEXTURE",
18183 "COMPILE_STATUS",
18184 "COMPRESSED_RGBA_S3TC_DXT1_EXT",
18185 "COMPRESSED_RGBA_S3TC_DXT3_EXT",
18186 "COMPRESSED_RGBA_S3TC_DXT5_EXT",
18187 "COMPRESSED_RGB_S3TC_DXT1_EXT",
18188 "COMPRESSED_TEXTURE_FORMATS",
18189 "CONDITION_SATISFIED",
18190 "CONFIGURATION_UNSUPPORTED",
18191 "CONNECTING",
18192 "CONSTANT_ALPHA",
18193 "CONSTANT_COLOR",
18194 "CONSTRAINT_ERR",
18195 "CONTEXT_LOST_WEBGL",
18196 "CONTROL_MASK",
18197 "COPY_READ_BUFFER",
18198 "COPY_READ_BUFFER_BINDING",
18199 "COPY_WRITE_BUFFER",
18200 "COPY_WRITE_BUFFER_BINDING",
18201 "COUNTER_STYLE_RULE",
18202 "CSS",
18203 "CSS2Properties",
18204 "CSSAnimation",
18205 "CSSCharsetRule",
18206 "CSSConditionRule",
18207 "CSSCounterStyleRule",
18208 "CSSFontFaceRule",
18209 "CSSFontFeatureValuesRule",
18210 "CSSGroupingRule",
18211 "CSSImageValue",
18212 "CSSImportRule",
18213 "CSSKeyframeRule",
18214 "CSSKeyframesRule",
18215 "CSSKeywordValue",
18216 "CSSMathInvert",
18217 "CSSMathMax",
18218 "CSSMathMin",
18219 "CSSMathNegate",
18220 "CSSMathProduct",
18221 "CSSMathSum",
18222 "CSSMathValue",
18223 "CSSMatrixComponent",
18224 "CSSMediaRule",
18225 "CSSMozDocumentRule",
18226 "CSSNameSpaceRule",
18227 "CSSNamespaceRule",
18228 "CSSNumericArray",
18229 "CSSNumericValue",
18230 "CSSPageRule",
18231 "CSSPerspective",
18232 "CSSPositionValue",
18233 "CSSPrimitiveValue",
18234 "CSSRotate",
18235 "CSSRule",
18236 "CSSRuleList",
18237 "CSSScale",
18238 "CSSSkew",
18239 "CSSSkewX",
18240 "CSSSkewY",
18241 "CSSStyleDeclaration",
18242 "CSSStyleRule",
18243 "CSSStyleSheet",
18244 "CSSStyleValue",
18245 "CSSSupportsRule",
18246 "CSSTransformComponent",
18247 "CSSTransformValue",
18248 "CSSTransition",
18249 "CSSTranslate",
18250 "CSSUnitValue",
18251 "CSSUnknownRule",
18252 "CSSUnparsedValue",
18253 "CSSValue",
18254 "CSSValueList",
18255 "CSSVariableReferenceValue",
18256 "CSSVariablesDeclaration",
18257 "CSSVariablesRule",
18258 "CSSViewportRule",
18259 "CSS_ATTR",
18260 "CSS_CM",
18261 "CSS_COUNTER",
18262 "CSS_CUSTOM",
18263 "CSS_DEG",
18264 "CSS_DIMENSION",
18265 "CSS_EMS",
18266 "CSS_EXS",
18267 "CSS_FILTER_BLUR",
18268 "CSS_FILTER_BRIGHTNESS",
18269 "CSS_FILTER_CONTRAST",
18270 "CSS_FILTER_CUSTOM",
18271 "CSS_FILTER_DROP_SHADOW",
18272 "CSS_FILTER_GRAYSCALE",
18273 "CSS_FILTER_HUE_ROTATE",
18274 "CSS_FILTER_INVERT",
18275 "CSS_FILTER_OPACITY",
18276 "CSS_FILTER_REFERENCE",
18277 "CSS_FILTER_SATURATE",
18278 "CSS_FILTER_SEPIA",
18279 "CSS_GRAD",
18280 "CSS_HZ",
18281 "CSS_IDENT",
18282 "CSS_IN",
18283 "CSS_INHERIT",
18284 "CSS_KHZ",
18285 "CSS_MATRIX",
18286 "CSS_MATRIX3D",
18287 "CSS_MM",
18288 "CSS_MS",
18289 "CSS_NUMBER",
18290 "CSS_PC",
18291 "CSS_PERCENTAGE",
18292 "CSS_PERSPECTIVE",
18293 "CSS_PRIMITIVE_VALUE",
18294 "CSS_PT",
18295 "CSS_PX",
18296 "CSS_RAD",
18297 "CSS_RECT",
18298 "CSS_RGBCOLOR",
18299 "CSS_ROTATE",
18300 "CSS_ROTATE3D",
18301 "CSS_ROTATEX",
18302 "CSS_ROTATEY",
18303 "CSS_ROTATEZ",
18304 "CSS_S",
18305 "CSS_SCALE",
18306 "CSS_SCALE3D",
18307 "CSS_SCALEX",
18308 "CSS_SCALEY",
18309 "CSS_SCALEZ",
18310 "CSS_SKEW",
18311 "CSS_SKEWX",
18312 "CSS_SKEWY",
18313 "CSS_STRING",
18314 "CSS_TRANSLATE",
18315 "CSS_TRANSLATE3D",
18316 "CSS_TRANSLATEX",
18317 "CSS_TRANSLATEY",
18318 "CSS_TRANSLATEZ",
18319 "CSS_UNKNOWN",
18320 "CSS_URI",
18321 "CSS_VALUE_LIST",
18322 "CSS_VH",
18323 "CSS_VMAX",
18324 "CSS_VMIN",
18325 "CSS_VW",
18326 "CULL_FACE",
18327 "CULL_FACE_MODE",
18328 "CURRENT_PROGRAM",
18329 "CURRENT_QUERY",
18330 "CURRENT_VERTEX_ATTRIB",
18331 "CUSTOM",
18332 "CW",
18333 "Cache",
18334 "CacheStorage",
18335 "CanvasCaptureMediaStream",
18336 "CanvasCaptureMediaStreamTrack",
18337 "CanvasGradient",
18338 "CanvasPattern",
18339 "CanvasRenderingContext2D",
18340 "CaretPosition",
18341 "ChannelMergerNode",
18342 "ChannelSplitterNode",
18343 "CharacterData",
18344 "ClientRect",
18345 "ClientRectList",
18346 "Clipboard",
18347 "ClipboardEvent",
18348 "ClipboardItem",
18349 "CloseEvent",
18350 "Collator",
18351 "CommandEvent",
18352 "Comment",
18353 "CompileError",
18354 "CompositionEvent",
18355 "CompressionStream",
18356 "Console",
18357 "ConstantSourceNode",
18358 "Controllers",
18359 "ConvolverNode",
18360 "CountQueuingStrategy",
18361 "Counter",
18362 "Credential",
18363 "CredentialsContainer",
18364 "Crypto",
18365 "CryptoKey",
18366 "CustomElementRegistry",
18367 "CustomEvent",
18368 "DATABASE_ERR",
18369 "DATA_CLONE_ERR",
18370 "DATA_ERR",
18371 "DBLCLICK",
18372 "DECR",
18373 "DECR_WRAP",
18374 "DELETE_STATUS",
18375 "DEPTH",
18376 "DEPTH24_STENCIL8",
18377 "DEPTH32F_STENCIL8",
18378 "DEPTH_ATTACHMENT",
18379 "DEPTH_BITS",
18380 "DEPTH_BUFFER_BIT",
18381 "DEPTH_CLEAR_VALUE",
18382 "DEPTH_COMPONENT",
18383 "DEPTH_COMPONENT16",
18384 "DEPTH_COMPONENT24",
18385 "DEPTH_COMPONENT32F",
18386 "DEPTH_FUNC",
18387 "DEPTH_RANGE",
18388 "DEPTH_STENCIL",
18389 "DEPTH_STENCIL_ATTACHMENT",
18390 "DEPTH_TEST",
18391 "DEPTH_WRITEMASK",
18392 "DEVICE_INELIGIBLE",
18393 "DIRECTION_DOWN",
18394 "DIRECTION_LEFT",
18395 "DIRECTION_RIGHT",
18396 "DIRECTION_UP",
18397 "DISABLED",
18398 "DISPATCH_REQUEST_ERR",
18399 "DITHER",
18400 "DOCUMENT_FRAGMENT_NODE",
18401 "DOCUMENT_NODE",
18402 "DOCUMENT_POSITION_CONTAINED_BY",
18403 "DOCUMENT_POSITION_CONTAINS",
18404 "DOCUMENT_POSITION_DISCONNECTED",
18405 "DOCUMENT_POSITION_FOLLOWING",
18406 "DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC",
18407 "DOCUMENT_POSITION_PRECEDING",
18408 "DOCUMENT_TYPE_NODE",
18409 "DOMCursor",
18410 "DOMError",
18411 "DOMException",
18412 "DOMImplementation",
18413 "DOMImplementationLS",
18414 "DOMMatrix",
18415 "DOMMatrixReadOnly",
18416 "DOMParser",
18417 "DOMPoint",
18418 "DOMPointReadOnly",
18419 "DOMQuad",
18420 "DOMRect",
18421 "DOMRectList",
18422 "DOMRectReadOnly",
18423 "DOMRequest",
18424 "DOMSTRING_SIZE_ERR",
18425 "DOMSettableTokenList",
18426 "DOMStringList",
18427 "DOMStringMap",
18428 "DOMTokenList",
18429 "DOMTransactionEvent",
18430 "DOM_DELTA_LINE",
18431 "DOM_DELTA_PAGE",
18432 "DOM_DELTA_PIXEL",
18433 "DOM_INPUT_METHOD_DROP",
18434 "DOM_INPUT_METHOD_HANDWRITING",
18435 "DOM_INPUT_METHOD_IME",
18436 "DOM_INPUT_METHOD_KEYBOARD",
18437 "DOM_INPUT_METHOD_MULTIMODAL",
18438 "DOM_INPUT_METHOD_OPTION",
18439 "DOM_INPUT_METHOD_PASTE",
18440 "DOM_INPUT_METHOD_SCRIPT",
18441 "DOM_INPUT_METHOD_UNKNOWN",
18442 "DOM_INPUT_METHOD_VOICE",
18443 "DOM_KEY_LOCATION_JOYSTICK",
18444 "DOM_KEY_LOCATION_LEFT",
18445 "DOM_KEY_LOCATION_MOBILE",
18446 "DOM_KEY_LOCATION_NUMPAD",
18447 "DOM_KEY_LOCATION_RIGHT",
18448 "DOM_KEY_LOCATION_STANDARD",
18449 "DOM_VK_0",
18450 "DOM_VK_1",
18451 "DOM_VK_2",
18452 "DOM_VK_3",
18453 "DOM_VK_4",
18454 "DOM_VK_5",
18455 "DOM_VK_6",
18456 "DOM_VK_7",
18457 "DOM_VK_8",
18458 "DOM_VK_9",
18459 "DOM_VK_A",
18460 "DOM_VK_ACCEPT",
18461 "DOM_VK_ADD",
18462 "DOM_VK_ALT",
18463 "DOM_VK_ALTGR",
18464 "DOM_VK_AMPERSAND",
18465 "DOM_VK_ASTERISK",
18466 "DOM_VK_AT",
18467 "DOM_VK_ATTN",
18468 "DOM_VK_B",
18469 "DOM_VK_BACKSPACE",
18470 "DOM_VK_BACK_QUOTE",
18471 "DOM_VK_BACK_SLASH",
18472 "DOM_VK_BACK_SPACE",
18473 "DOM_VK_C",
18474 "DOM_VK_CANCEL",
18475 "DOM_VK_CAPS_LOCK",
18476 "DOM_VK_CIRCUMFLEX",
18477 "DOM_VK_CLEAR",
18478 "DOM_VK_CLOSE_BRACKET",
18479 "DOM_VK_CLOSE_CURLY_BRACKET",
18480 "DOM_VK_CLOSE_PAREN",
18481 "DOM_VK_COLON",
18482 "DOM_VK_COMMA",
18483 "DOM_VK_CONTEXT_MENU",
18484 "DOM_VK_CONTROL",
18485 "DOM_VK_CONVERT",
18486 "DOM_VK_CRSEL",
18487 "DOM_VK_CTRL",
18488 "DOM_VK_D",
18489 "DOM_VK_DECIMAL",
18490 "DOM_VK_DELETE",
18491 "DOM_VK_DIVIDE",
18492 "DOM_VK_DOLLAR",
18493 "DOM_VK_DOUBLE_QUOTE",
18494 "DOM_VK_DOWN",
18495 "DOM_VK_E",
18496 "DOM_VK_EISU",
18497 "DOM_VK_END",
18498 "DOM_VK_ENTER",
18499 "DOM_VK_EQUALS",
18500 "DOM_VK_EREOF",
18501 "DOM_VK_ESCAPE",
18502 "DOM_VK_EXCLAMATION",
18503 "DOM_VK_EXECUTE",
18504 "DOM_VK_EXSEL",
18505 "DOM_VK_F",
18506 "DOM_VK_F1",
18507 "DOM_VK_F10",
18508 "DOM_VK_F11",
18509 "DOM_VK_F12",
18510 "DOM_VK_F13",
18511 "DOM_VK_F14",
18512 "DOM_VK_F15",
18513 "DOM_VK_F16",
18514 "DOM_VK_F17",
18515 "DOM_VK_F18",
18516 "DOM_VK_F19",
18517 "DOM_VK_F2",
18518 "DOM_VK_F20",
18519 "DOM_VK_F21",
18520 "DOM_VK_F22",
18521 "DOM_VK_F23",
18522 "DOM_VK_F24",
18523 "DOM_VK_F25",
18524 "DOM_VK_F26",
18525 "DOM_VK_F27",
18526 "DOM_VK_F28",
18527 "DOM_VK_F29",
18528 "DOM_VK_F3",
18529 "DOM_VK_F30",
18530 "DOM_VK_F31",
18531 "DOM_VK_F32",
18532 "DOM_VK_F33",
18533 "DOM_VK_F34",
18534 "DOM_VK_F35",
18535 "DOM_VK_F36",
18536 "DOM_VK_F4",
18537 "DOM_VK_F5",
18538 "DOM_VK_F6",
18539 "DOM_VK_F7",
18540 "DOM_VK_F8",
18541 "DOM_VK_F9",
18542 "DOM_VK_FINAL",
18543 "DOM_VK_FRONT",
18544 "DOM_VK_G",
18545 "DOM_VK_GREATER_THAN",
18546 "DOM_VK_H",
18547 "DOM_VK_HANGUL",
18548 "DOM_VK_HANJA",
18549 "DOM_VK_HASH",
18550 "DOM_VK_HELP",
18551 "DOM_VK_HK_TOGGLE",
18552 "DOM_VK_HOME",
18553 "DOM_VK_HYPHEN_MINUS",
18554 "DOM_VK_I",
18555 "DOM_VK_INSERT",
18556 "DOM_VK_J",
18557 "DOM_VK_JUNJA",
18558 "DOM_VK_K",
18559 "DOM_VK_KANA",
18560 "DOM_VK_KANJI",
18561 "DOM_VK_L",
18562 "DOM_VK_LEFT",
18563 "DOM_VK_LEFT_TAB",
18564 "DOM_VK_LESS_THAN",
18565 "DOM_VK_M",
18566 "DOM_VK_META",
18567 "DOM_VK_MODECHANGE",
18568 "DOM_VK_MULTIPLY",
18569 "DOM_VK_N",
18570 "DOM_VK_NONCONVERT",
18571 "DOM_VK_NUMPAD0",
18572 "DOM_VK_NUMPAD1",
18573 "DOM_VK_NUMPAD2",
18574 "DOM_VK_NUMPAD3",
18575 "DOM_VK_NUMPAD4",
18576 "DOM_VK_NUMPAD5",
18577 "DOM_VK_NUMPAD6",
18578 "DOM_VK_NUMPAD7",
18579 "DOM_VK_NUMPAD8",
18580 "DOM_VK_NUMPAD9",
18581 "DOM_VK_NUM_LOCK",
18582 "DOM_VK_O",
18583 "DOM_VK_OEM_1",
18584 "DOM_VK_OEM_102",
18585 "DOM_VK_OEM_2",
18586 "DOM_VK_OEM_3",
18587 "DOM_VK_OEM_4",
18588 "DOM_VK_OEM_5",
18589 "DOM_VK_OEM_6",
18590 "DOM_VK_OEM_7",
18591 "DOM_VK_OEM_8",
18592 "DOM_VK_OEM_COMMA",
18593 "DOM_VK_OEM_MINUS",
18594 "DOM_VK_OEM_PERIOD",
18595 "DOM_VK_OEM_PLUS",
18596 "DOM_VK_OPEN_BRACKET",
18597 "DOM_VK_OPEN_CURLY_BRACKET",
18598 "DOM_VK_OPEN_PAREN",
18599 "DOM_VK_P",
18600 "DOM_VK_PA1",
18601 "DOM_VK_PAGEDOWN",
18602 "DOM_VK_PAGEUP",
18603 "DOM_VK_PAGE_DOWN",
18604 "DOM_VK_PAGE_UP",
18605 "DOM_VK_PAUSE",
18606 "DOM_VK_PERCENT",
18607 "DOM_VK_PERIOD",
18608 "DOM_VK_PIPE",
18609 "DOM_VK_PLAY",
18610 "DOM_VK_PLUS",
18611 "DOM_VK_PRINT",
18612 "DOM_VK_PRINTSCREEN",
18613 "DOM_VK_PROCESSKEY",
18614 "DOM_VK_PROPERITES",
18615 "DOM_VK_Q",
18616 "DOM_VK_QUESTION_MARK",
18617 "DOM_VK_QUOTE",
18618 "DOM_VK_R",
18619 "DOM_VK_REDO",
18620 "DOM_VK_RETURN",
18621 "DOM_VK_RIGHT",
18622 "DOM_VK_S",
18623 "DOM_VK_SCROLL_LOCK",
18624 "DOM_VK_SELECT",
18625 "DOM_VK_SEMICOLON",
18626 "DOM_VK_SEPARATOR",
18627 "DOM_VK_SHIFT",
18628 "DOM_VK_SLASH",
18629 "DOM_VK_SLEEP",
18630 "DOM_VK_SPACE",
18631 "DOM_VK_SUBTRACT",
18632 "DOM_VK_T",
18633 "DOM_VK_TAB",
18634 "DOM_VK_TILDE",
18635 "DOM_VK_U",
18636 "DOM_VK_UNDERSCORE",
18637 "DOM_VK_UNDO",
18638 "DOM_VK_UNICODE",
18639 "DOM_VK_UP",
18640 "DOM_VK_V",
18641 "DOM_VK_VOLUME_DOWN",
18642 "DOM_VK_VOLUME_MUTE",
18643 "DOM_VK_VOLUME_UP",
18644 "DOM_VK_W",
18645 "DOM_VK_WIN",
18646 "DOM_VK_WINDOW",
18647 "DOM_VK_WIN_ICO_00",
18648 "DOM_VK_WIN_ICO_CLEAR",
18649 "DOM_VK_WIN_ICO_HELP",
18650 "DOM_VK_WIN_OEM_ATTN",
18651 "DOM_VK_WIN_OEM_AUTO",
18652 "DOM_VK_WIN_OEM_BACKTAB",
18653 "DOM_VK_WIN_OEM_CLEAR",
18654 "DOM_VK_WIN_OEM_COPY",
18655 "DOM_VK_WIN_OEM_CUSEL",
18656 "DOM_VK_WIN_OEM_ENLW",
18657 "DOM_VK_WIN_OEM_FINISH",
18658 "DOM_VK_WIN_OEM_FJ_JISHO",
18659 "DOM_VK_WIN_OEM_FJ_LOYA",
18660 "DOM_VK_WIN_OEM_FJ_MASSHOU",
18661 "DOM_VK_WIN_OEM_FJ_ROYA",
18662 "DOM_VK_WIN_OEM_FJ_TOUROKU",
18663 "DOM_VK_WIN_OEM_JUMP",
18664 "DOM_VK_WIN_OEM_PA1",
18665 "DOM_VK_WIN_OEM_PA2",
18666 "DOM_VK_WIN_OEM_PA3",
18667 "DOM_VK_WIN_OEM_RESET",
18668 "DOM_VK_WIN_OEM_WSCTRL",
18669 "DOM_VK_X",
18670 "DOM_VK_XF86XK_ADD_FAVORITE",
18671 "DOM_VK_XF86XK_APPLICATION_LEFT",
18672 "DOM_VK_XF86XK_APPLICATION_RIGHT",
18673 "DOM_VK_XF86XK_AUDIO_CYCLE_TRACK",
18674 "DOM_VK_XF86XK_AUDIO_FORWARD",
18675 "DOM_VK_XF86XK_AUDIO_LOWER_VOLUME",
18676 "DOM_VK_XF86XK_AUDIO_MEDIA",
18677 "DOM_VK_XF86XK_AUDIO_MUTE",
18678 "DOM_VK_XF86XK_AUDIO_NEXT",
18679 "DOM_VK_XF86XK_AUDIO_PAUSE",
18680 "DOM_VK_XF86XK_AUDIO_PLAY",
18681 "DOM_VK_XF86XK_AUDIO_PREV",
18682 "DOM_VK_XF86XK_AUDIO_RAISE_VOLUME",
18683 "DOM_VK_XF86XK_AUDIO_RANDOM_PLAY",
18684 "DOM_VK_XF86XK_AUDIO_RECORD",
18685 "DOM_VK_XF86XK_AUDIO_REPEAT",
18686 "DOM_VK_XF86XK_AUDIO_REWIND",
18687 "DOM_VK_XF86XK_AUDIO_STOP",
18688 "DOM_VK_XF86XK_AWAY",
18689 "DOM_VK_XF86XK_BACK",
18690 "DOM_VK_XF86XK_BACK_FORWARD",
18691 "DOM_VK_XF86XK_BATTERY",
18692 "DOM_VK_XF86XK_BLUE",
18693 "DOM_VK_XF86XK_BLUETOOTH",
18694 "DOM_VK_XF86XK_BOOK",
18695 "DOM_VK_XF86XK_BRIGHTNESS_ADJUST",
18696 "DOM_VK_XF86XK_CALCULATOR",
18697 "DOM_VK_XF86XK_CALENDAR",
18698 "DOM_VK_XF86XK_CD",
18699 "DOM_VK_XF86XK_CLOSE",
18700 "DOM_VK_XF86XK_COMMUNITY",
18701 "DOM_VK_XF86XK_CONTRAST_ADJUST",
18702 "DOM_VK_XF86XK_COPY",
18703 "DOM_VK_XF86XK_CUT",
18704 "DOM_VK_XF86XK_CYCLE_ANGLE",
18705 "DOM_VK_XF86XK_DISPLAY",
18706 "DOM_VK_XF86XK_DOCUMENTS",
18707 "DOM_VK_XF86XK_DOS",
18708 "DOM_VK_XF86XK_EJECT",
18709 "DOM_VK_XF86XK_EXCEL",
18710 "DOM_VK_XF86XK_EXPLORER",
18711 "DOM_VK_XF86XK_FAVORITES",
18712 "DOM_VK_XF86XK_FINANCE",
18713 "DOM_VK_XF86XK_FORWARD",
18714 "DOM_VK_XF86XK_FRAME_BACK",
18715 "DOM_VK_XF86XK_FRAME_FORWARD",
18716 "DOM_VK_XF86XK_GAME",
18717 "DOM_VK_XF86XK_GO",
18718 "DOM_VK_XF86XK_GREEN",
18719 "DOM_VK_XF86XK_HIBERNATE",
18720 "DOM_VK_XF86XK_HISTORY",
18721 "DOM_VK_XF86XK_HOME_PAGE",
18722 "DOM_VK_XF86XK_HOT_LINKS",
18723 "DOM_VK_XF86XK_I_TOUCH",
18724 "DOM_VK_XF86XK_KBD_BRIGHTNESS_DOWN",
18725 "DOM_VK_XF86XK_KBD_BRIGHTNESS_UP",
18726 "DOM_VK_XF86XK_KBD_LIGHT_ON_OFF",
18727 "DOM_VK_XF86XK_LAUNCH0",
18728 "DOM_VK_XF86XK_LAUNCH1",
18729 "DOM_VK_XF86XK_LAUNCH2",
18730 "DOM_VK_XF86XK_LAUNCH3",
18731 "DOM_VK_XF86XK_LAUNCH4",
18732 "DOM_VK_XF86XK_LAUNCH5",
18733 "DOM_VK_XF86XK_LAUNCH6",
18734 "DOM_VK_XF86XK_LAUNCH7",
18735 "DOM_VK_XF86XK_LAUNCH8",
18736 "DOM_VK_XF86XK_LAUNCH9",
18737 "DOM_VK_XF86XK_LAUNCH_A",
18738 "DOM_VK_XF86XK_LAUNCH_B",
18739 "DOM_VK_XF86XK_LAUNCH_C",
18740 "DOM_VK_XF86XK_LAUNCH_D",
18741 "DOM_VK_XF86XK_LAUNCH_E",
18742 "DOM_VK_XF86XK_LAUNCH_F",
18743 "DOM_VK_XF86XK_LIGHT_BULB",
18744 "DOM_VK_XF86XK_LOG_OFF",
18745 "DOM_VK_XF86XK_MAIL",
18746 "DOM_VK_XF86XK_MAIL_FORWARD",
18747 "DOM_VK_XF86XK_MARKET",
18748 "DOM_VK_XF86XK_MEETING",
18749 "DOM_VK_XF86XK_MEMO",
18750 "DOM_VK_XF86XK_MENU_KB",
18751 "DOM_VK_XF86XK_MENU_PB",
18752 "DOM_VK_XF86XK_MESSENGER",
18753 "DOM_VK_XF86XK_MON_BRIGHTNESS_DOWN",
18754 "DOM_VK_XF86XK_MON_BRIGHTNESS_UP",
18755 "DOM_VK_XF86XK_MUSIC",
18756 "DOM_VK_XF86XK_MY_COMPUTER",
18757 "DOM_VK_XF86XK_MY_SITES",
18758 "DOM_VK_XF86XK_NEW",
18759 "DOM_VK_XF86XK_NEWS",
18760 "DOM_VK_XF86XK_OFFICE_HOME",
18761 "DOM_VK_XF86XK_OPEN",
18762 "DOM_VK_XF86XK_OPEN_URL",
18763 "DOM_VK_XF86XK_OPTION",
18764 "DOM_VK_XF86XK_PASTE",
18765 "DOM_VK_XF86XK_PHONE",
18766 "DOM_VK_XF86XK_PICTURES",
18767 "DOM_VK_XF86XK_POWER_DOWN",
18768 "DOM_VK_XF86XK_POWER_OFF",
18769 "DOM_VK_XF86XK_RED",
18770 "DOM_VK_XF86XK_REFRESH",
18771 "DOM_VK_XF86XK_RELOAD",
18772 "DOM_VK_XF86XK_REPLY",
18773 "DOM_VK_XF86XK_ROCKER_DOWN",
18774 "DOM_VK_XF86XK_ROCKER_ENTER",
18775 "DOM_VK_XF86XK_ROCKER_UP",
18776 "DOM_VK_XF86XK_ROTATE_WINDOWS",
18777 "DOM_VK_XF86XK_ROTATION_KB",
18778 "DOM_VK_XF86XK_ROTATION_PB",
18779 "DOM_VK_XF86XK_SAVE",
18780 "DOM_VK_XF86XK_SCREEN_SAVER",
18781 "DOM_VK_XF86XK_SCROLL_CLICK",
18782 "DOM_VK_XF86XK_SCROLL_DOWN",
18783 "DOM_VK_XF86XK_SCROLL_UP",
18784 "DOM_VK_XF86XK_SEARCH",
18785 "DOM_VK_XF86XK_SEND",
18786 "DOM_VK_XF86XK_SHOP",
18787 "DOM_VK_XF86XK_SPELL",
18788 "DOM_VK_XF86XK_SPLIT_SCREEN",
18789 "DOM_VK_XF86XK_STANDBY",
18790 "DOM_VK_XF86XK_START",
18791 "DOM_VK_XF86XK_STOP",
18792 "DOM_VK_XF86XK_SUBTITLE",
18793 "DOM_VK_XF86XK_SUPPORT",
18794 "DOM_VK_XF86XK_SUSPEND",
18795 "DOM_VK_XF86XK_TASK_PANE",
18796 "DOM_VK_XF86XK_TERMINAL",
18797 "DOM_VK_XF86XK_TIME",
18798 "DOM_VK_XF86XK_TOOLS",
18799 "DOM_VK_XF86XK_TOP_MENU",
18800 "DOM_VK_XF86XK_TO_DO_LIST",
18801 "DOM_VK_XF86XK_TRAVEL",
18802 "DOM_VK_XF86XK_USER1KB",
18803 "DOM_VK_XF86XK_USER2KB",
18804 "DOM_VK_XF86XK_USER_PB",
18805 "DOM_VK_XF86XK_UWB",
18806 "DOM_VK_XF86XK_VENDOR_HOME",
18807 "DOM_VK_XF86XK_VIDEO",
18808 "DOM_VK_XF86XK_VIEW",
18809 "DOM_VK_XF86XK_WAKE_UP",
18810 "DOM_VK_XF86XK_WEB_CAM",
18811 "DOM_VK_XF86XK_WHEEL_BUTTON",
18812 "DOM_VK_XF86XK_WLAN",
18813 "DOM_VK_XF86XK_WORD",
18814 "DOM_VK_XF86XK_WWW",
18815 "DOM_VK_XF86XK_XFER",
18816 "DOM_VK_XF86XK_YELLOW",
18817 "DOM_VK_XF86XK_ZOOM_IN",
18818 "DOM_VK_XF86XK_ZOOM_OUT",
18819 "DOM_VK_Y",
18820 "DOM_VK_Z",
18821 "DOM_VK_ZOOM",
18822 "DONE",
18823 "DONT_CARE",
18824 "DOWNLOADING",
18825 "DRAGDROP",
18826 "DRAW_BUFFER0",
18827 "DRAW_BUFFER1",
18828 "DRAW_BUFFER10",
18829 "DRAW_BUFFER11",
18830 "DRAW_BUFFER12",
18831 "DRAW_BUFFER13",
18832 "DRAW_BUFFER14",
18833 "DRAW_BUFFER15",
18834 "DRAW_BUFFER2",
18835 "DRAW_BUFFER3",
18836 "DRAW_BUFFER4",
18837 "DRAW_BUFFER5",
18838 "DRAW_BUFFER6",
18839 "DRAW_BUFFER7",
18840 "DRAW_BUFFER8",
18841 "DRAW_BUFFER9",
18842 "DRAW_FRAMEBUFFER",
18843 "DRAW_FRAMEBUFFER_BINDING",
18844 "DST_ALPHA",
18845 "DST_COLOR",
18846 "DYNAMIC_COPY",
18847 "DYNAMIC_DRAW",
18848 "DYNAMIC_READ",
18849 "DataChannel",
18850 "DataTransfer",
18851 "DataTransferItem",
18852 "DataTransferItemList",
18853 "DataView",
18854 "Date",
18855 "DateTimeFormat",
18856 "DecompressionStream",
18857 "DelayNode",
18858 "DeprecationReportBody",
18859 "DesktopNotification",
18860 "DesktopNotificationCenter",
18861 "DeviceLightEvent",
18862 "DeviceMotionEvent",
18863 "DeviceMotionEventAcceleration",
18864 "DeviceMotionEventRotationRate",
18865 "DeviceOrientationEvent",
18866 "DeviceProximityEvent",
18867 "DeviceStorage",
18868 "DeviceStorageChangeEvent",
18869 "Directory",
18870 "DisplayNames",
18871 "Document",
18872 "DocumentFragment",
18873 "DocumentTimeline",
18874 "DocumentType",
18875 "DragEvent",
18876 "DynamicsCompressorNode",
18877 "E",
18878 "ELEMENT_ARRAY_BUFFER",
18879 "ELEMENT_ARRAY_BUFFER_BINDING",
18880 "ELEMENT_NODE",
18881 "EMPTY",
18882 "ENCODING_ERR",
18883 "ENDED",
18884 "END_TO_END",
18885 "END_TO_START",
18886 "ENTITY_NODE",
18887 "ENTITY_REFERENCE_NODE",
18888 "EPSILON",
18889 "EQUAL",
18890 "EQUALPOWER",
18891 "ERROR",
18892 "EXPONENTIAL_DISTANCE",
18893 "Element",
18894 "ElementInternals",
18895 "ElementQuery",
18896 "EnterPictureInPictureEvent",
18897 "Entity",
18898 "EntityReference",
18899 "Error",
18900 "ErrorEvent",
18901 "EvalError",
18902 "Event",
18903 "EventException",
18904 "EventSource",
18905 "EventTarget",
18906 "External",
18907 "FASTEST",
18908 "FIDOSDK",
18909 "FILTER_ACCEPT",
18910 "FILTER_INTERRUPT",
18911 "FILTER_REJECT",
18912 "FILTER_SKIP",
18913 "FINISHED_STATE",
18914 "FIRST_ORDERED_NODE_TYPE",
18915 "FLOAT",
18916 "FLOAT_32_UNSIGNED_INT_24_8_REV",
18917 "FLOAT_MAT2",
18918 "FLOAT_MAT2x3",
18919 "FLOAT_MAT2x4",
18920 "FLOAT_MAT3",
18921 "FLOAT_MAT3x2",
18922 "FLOAT_MAT3x4",
18923 "FLOAT_MAT4",
18924 "FLOAT_MAT4x2",
18925 "FLOAT_MAT4x3",
18926 "FLOAT_VEC2",
18927 "FLOAT_VEC3",
18928 "FLOAT_VEC4",
18929 "FOCUS",
18930 "FONT_FACE_RULE",
18931 "FONT_FEATURE_VALUES_RULE",
18932 "FRAGMENT_SHADER",
18933 "FRAGMENT_SHADER_DERIVATIVE_HINT",
18934 "FRAGMENT_SHADER_DERIVATIVE_HINT_OES",
18935 "FRAMEBUFFER",
18936 "FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE",
18937 "FRAMEBUFFER_ATTACHMENT_BLUE_SIZE",
18938 "FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING",
18939 "FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE",
18940 "FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE",
18941 "FRAMEBUFFER_ATTACHMENT_GREEN_SIZE",
18942 "FRAMEBUFFER_ATTACHMENT_OBJECT_NAME",
18943 "FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE",
18944 "FRAMEBUFFER_ATTACHMENT_RED_SIZE",
18945 "FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE",
18946 "FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE",
18947 "FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER",
18948 "FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL",
18949 "FRAMEBUFFER_BINDING",
18950 "FRAMEBUFFER_COMPLETE",
18951 "FRAMEBUFFER_DEFAULT",
18952 "FRAMEBUFFER_INCOMPLETE_ATTACHMENT",
18953 "FRAMEBUFFER_INCOMPLETE_DIMENSIONS",
18954 "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT",
18955 "FRAMEBUFFER_INCOMPLETE_MULTISAMPLE",
18956 "FRAMEBUFFER_UNSUPPORTED",
18957 "FRONT",
18958 "FRONT_AND_BACK",
18959 "FRONT_FACE",
18960 "FUNC_ADD",
18961 "FUNC_REVERSE_SUBTRACT",
18962 "FUNC_SUBTRACT",
18963 "FeaturePolicy",
18964 "FeaturePolicyViolationReportBody",
18965 "FederatedCredential",
18966 "Feed",
18967 "FeedEntry",
18968 "File",
18969 "FileError",
18970 "FileList",
18971 "FileReader",
18972 "FileSystem",
18973 "FileSystemDirectoryEntry",
18974 "FileSystemDirectoryReader",
18975 "FileSystemEntry",
18976 "FileSystemFileEntry",
18977 "FinalizationRegistry",
18978 "FindInPage",
18979 "Float32Array",
18980 "Float64Array",
18981 "FocusEvent",
18982 "FontFace",
18983 "FontFaceSet",
18984 "FontFaceSetLoadEvent",
18985 "FormData",
18986 "FormDataEvent",
18987 "FragmentDirective",
18988 "Function",
18989 "GENERATE_MIPMAP_HINT",
18990 "GEQUAL",
18991 "GREATER",
18992 "GREEN_BITS",
18993 "GainNode",
18994 "Gamepad",
18995 "GamepadAxisMoveEvent",
18996 "GamepadButton",
18997 "GamepadButtonEvent",
18998 "GamepadEvent",
18999 "GamepadHapticActuator",
19000 "GamepadPose",
19001 "Geolocation",
19002 "GeolocationCoordinates",
19003 "GeolocationPosition",
19004 "GeolocationPositionError",
19005 "GestureEvent",
19006 "Global",
19007 "Gyroscope",
19008 "HALF_FLOAT",
19009 "HAVE_CURRENT_DATA",
19010 "HAVE_ENOUGH_DATA",
19011 "HAVE_FUTURE_DATA",
19012 "HAVE_METADATA",
19013 "HAVE_NOTHING",
19014 "HEADERS_RECEIVED",
19015 "HIDDEN",
19016 "HIERARCHY_REQUEST_ERR",
19017 "HIGHPASS",
19018 "HIGHSHELF",
19019 "HIGH_FLOAT",
19020 "HIGH_INT",
19021 "HORIZONTAL",
19022 "HORIZONTAL_AXIS",
19023 "HRTF",
19024 "HTMLAllCollection",
19025 "HTMLAnchorElement",
19026 "HTMLAppletElement",
19027 "HTMLAreaElement",
19028 "HTMLAudioElement",
19029 "HTMLBRElement",
19030 "HTMLBaseElement",
19031 "HTMLBaseFontElement",
19032 "HTMLBlockquoteElement",
19033 "HTMLBodyElement",
19034 "HTMLButtonElement",
19035 "HTMLCanvasElement",
19036 "HTMLCollection",
19037 "HTMLCommandElement",
19038 "HTMLContentElement",
19039 "HTMLDListElement",
19040 "HTMLDataElement",
19041 "HTMLDataListElement",
19042 "HTMLDetailsElement",
19043 "HTMLDialogElement",
19044 "HTMLDirectoryElement",
19045 "HTMLDivElement",
19046 "HTMLDocument",
19047 "HTMLElement",
19048 "HTMLEmbedElement",
19049 "HTMLFieldSetElement",
19050 "HTMLFontElement",
19051 "HTMLFormControlsCollection",
19052 "HTMLFormElement",
19053 "HTMLFrameElement",
19054 "HTMLFrameSetElement",
19055 "HTMLHRElement",
19056 "HTMLHeadElement",
19057 "HTMLHeadingElement",
19058 "HTMLHtmlElement",
19059 "HTMLIFrameElement",
19060 "HTMLImageElement",
19061 "HTMLInputElement",
19062 "HTMLIsIndexElement",
19063 "HTMLKeygenElement",
19064 "HTMLLIElement",
19065 "HTMLLabelElement",
19066 "HTMLLegendElement",
19067 "HTMLLinkElement",
19068 "HTMLMapElement",
19069 "HTMLMarqueeElement",
19070 "HTMLMediaElement",
19071 "HTMLMenuElement",
19072 "HTMLMenuItemElement",
19073 "HTMLMetaElement",
19074 "HTMLMeterElement",
19075 "HTMLModElement",
19076 "HTMLOListElement",
19077 "HTMLObjectElement",
19078 "HTMLOptGroupElement",
19079 "HTMLOptionElement",
19080 "HTMLOptionsCollection",
19081 "HTMLOutputElement",
19082 "HTMLParagraphElement",
19083 "HTMLParamElement",
19084 "HTMLPictureElement",
19085 "HTMLPreElement",
19086 "HTMLProgressElement",
19087 "HTMLPropertiesCollection",
19088 "HTMLQuoteElement",
19089 "HTMLScriptElement",
19090 "HTMLSelectElement",
19091 "HTMLShadowElement",
19092 "HTMLSlotElement",
19093 "HTMLSourceElement",
19094 "HTMLSpanElement",
19095 "HTMLStyleElement",
19096 "HTMLTableCaptionElement",
19097 "HTMLTableCellElement",
19098 "HTMLTableColElement",
19099 "HTMLTableElement",
19100 "HTMLTableRowElement",
19101 "HTMLTableSectionElement",
19102 "HTMLTemplateElement",
19103 "HTMLTextAreaElement",
19104 "HTMLTimeElement",
19105 "HTMLTitleElement",
19106 "HTMLTrackElement",
19107 "HTMLUListElement",
19108 "HTMLUnknownElement",
19109 "HTMLVideoElement",
19110 "HashChangeEvent",
19111 "Headers",
19112 "History",
19113 "Hz",
19114 "ICE_CHECKING",
19115 "ICE_CLOSED",
19116 "ICE_COMPLETED",
19117 "ICE_CONNECTED",
19118 "ICE_FAILED",
19119 "ICE_GATHERING",
19120 "ICE_WAITING",
19121 "IDBCursor",
19122 "IDBCursorWithValue",
19123 "IDBDatabase",
19124 "IDBDatabaseException",
19125 "IDBFactory",
19126 "IDBFileHandle",
19127 "IDBFileRequest",
19128 "IDBIndex",
19129 "IDBKeyRange",
19130 "IDBMutableFile",
19131 "IDBObjectStore",
19132 "IDBOpenDBRequest",
19133 "IDBRequest",
19134 "IDBTransaction",
19135 "IDBVersionChangeEvent",
19136 "IDLE",
19137 "IIRFilterNode",
19138 "IMPLEMENTATION_COLOR_READ_FORMAT",
19139 "IMPLEMENTATION_COLOR_READ_TYPE",
19140 "IMPORT_RULE",
19141 "INCR",
19142 "INCR_WRAP",
19143 "INDEX_SIZE_ERR",
19144 "INT",
19145 "INTERLEAVED_ATTRIBS",
19146 "INT_2_10_10_10_REV",
19147 "INT_SAMPLER_2D",
19148 "INT_SAMPLER_2D_ARRAY",
19149 "INT_SAMPLER_3D",
19150 "INT_SAMPLER_CUBE",
19151 "INT_VEC2",
19152 "INT_VEC3",
19153 "INT_VEC4",
19154 "INUSE_ATTRIBUTE_ERR",
19155 "INVALID_ACCESS_ERR",
19156 "INVALID_CHARACTER_ERR",
19157 "INVALID_ENUM",
19158 "INVALID_EXPRESSION_ERR",
19159 "INVALID_FRAMEBUFFER_OPERATION",
19160 "INVALID_INDEX",
19161 "INVALID_MODIFICATION_ERR",
19162 "INVALID_NODE_TYPE_ERR",
19163 "INVALID_OPERATION",
19164 "INVALID_STATE_ERR",
19165 "INVALID_VALUE",
19166 "INVERSE_DISTANCE",
19167 "INVERT",
19168 "IceCandidate",
19169 "IdleDeadline",
19170 "Image",
19171 "ImageBitmap",
19172 "ImageBitmapRenderingContext",
19173 "ImageCapture",
19174 "ImageData",
19175 "Infinity",
19176 "InputDeviceCapabilities",
19177 "InputDeviceInfo",
19178 "InputEvent",
19179 "InputMethodContext",
19180 "InstallTrigger",
19181 "InstallTriggerImpl",
19182 "Instance",
19183 "Int16Array",
19184 "Int32Array",
19185 "Int8Array",
19186 "Intent",
19187 "InternalError",
19188 "IntersectionObserver",
19189 "IntersectionObserverEntry",
19190 "Intl",
19191 "IsSearchProviderInstalled",
19192 "Iterator",
19193 "JSON",
19194 "KEEP",
19195 "KEYDOWN",
19196 "KEYFRAMES_RULE",
19197 "KEYFRAME_RULE",
19198 "KEYPRESS",
19199 "KEYUP",
19200 "KeyEvent",
19201 "Keyboard",
19202 "KeyboardEvent",
19203 "KeyboardLayoutMap",
19204 "KeyframeEffect",
19205 "LENGTHADJUST_SPACING",
19206 "LENGTHADJUST_SPACINGANDGLYPHS",
19207 "LENGTHADJUST_UNKNOWN",
19208 "LEQUAL",
19209 "LESS",
19210 "LINEAR",
19211 "LINEAR_DISTANCE",
19212 "LINEAR_MIPMAP_LINEAR",
19213 "LINEAR_MIPMAP_NEAREST",
19214 "LINES",
19215 "LINE_LOOP",
19216 "LINE_STRIP",
19217 "LINE_WIDTH",
19218 "LINK_STATUS",
19219 "LIVE",
19220 "LN10",
19221 "LN2",
19222 "LOADED",
19223 "LOADING",
19224 "LOG10E",
19225 "LOG2E",
19226 "LOWPASS",
19227 "LOWSHELF",
19228 "LOW_FLOAT",
19229 "LOW_INT",
19230 "LSException",
19231 "LSParserFilter",
19232 "LUMINANCE",
19233 "LUMINANCE_ALPHA",
19234 "LargestContentfulPaint",
19235 "LayoutShift",
19236 "LayoutShiftAttribution",
19237 "LinearAccelerationSensor",
19238 "LinkError",
19239 "ListFormat",
19240 "LocalMediaStream",
19241 "Locale",
19242 "Location",
19243 "Lock",
19244 "LockManager",
19245 "MAX",
19246 "MAX_3D_TEXTURE_SIZE",
19247 "MAX_ARRAY_TEXTURE_LAYERS",
19248 "MAX_CLIENT_WAIT_TIMEOUT_WEBGL",
19249 "MAX_COLOR_ATTACHMENTS",
19250 "MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS",
19251 "MAX_COMBINED_TEXTURE_IMAGE_UNITS",
19252 "MAX_COMBINED_UNIFORM_BLOCKS",
19253 "MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS",
19254 "MAX_CUBE_MAP_TEXTURE_SIZE",
19255 "MAX_DRAW_BUFFERS",
19256 "MAX_ELEMENTS_INDICES",
19257 "MAX_ELEMENTS_VERTICES",
19258 "MAX_ELEMENT_INDEX",
19259 "MAX_FRAGMENT_INPUT_COMPONENTS",
19260 "MAX_FRAGMENT_UNIFORM_BLOCKS",
19261 "MAX_FRAGMENT_UNIFORM_COMPONENTS",
19262 "MAX_FRAGMENT_UNIFORM_VECTORS",
19263 "MAX_PROGRAM_TEXEL_OFFSET",
19264 "MAX_RENDERBUFFER_SIZE",
19265 "MAX_SAFE_INTEGER",
19266 "MAX_SAMPLES",
19267 "MAX_SERVER_WAIT_TIMEOUT",
19268 "MAX_TEXTURE_IMAGE_UNITS",
19269 "MAX_TEXTURE_LOD_BIAS",
19270 "MAX_TEXTURE_MAX_ANISOTROPY_EXT",
19271 "MAX_TEXTURE_SIZE",
19272 "MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS",
19273 "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS",
19274 "MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS",
19275 "MAX_UNIFORM_BLOCK_SIZE",
19276 "MAX_UNIFORM_BUFFER_BINDINGS",
19277 "MAX_VALUE",
19278 "MAX_VARYING_COMPONENTS",
19279 "MAX_VARYING_VECTORS",
19280 "MAX_VERTEX_ATTRIBS",
19281 "MAX_VERTEX_OUTPUT_COMPONENTS",
19282 "MAX_VERTEX_TEXTURE_IMAGE_UNITS",
19283 "MAX_VERTEX_UNIFORM_BLOCKS",
19284 "MAX_VERTEX_UNIFORM_COMPONENTS",
19285 "MAX_VERTEX_UNIFORM_VECTORS",
19286 "MAX_VIEWPORT_DIMS",
19287 "MEDIA_ERR_ABORTED",
19288 "MEDIA_ERR_DECODE",
19289 "MEDIA_ERR_ENCRYPTED",
19290 "MEDIA_ERR_NETWORK",
19291 "MEDIA_ERR_SRC_NOT_SUPPORTED",
19292 "MEDIA_KEYERR_CLIENT",
19293 "MEDIA_KEYERR_DOMAIN",
19294 "MEDIA_KEYERR_HARDWARECHANGE",
19295 "MEDIA_KEYERR_OUTPUT",
19296 "MEDIA_KEYERR_SERVICE",
19297 "MEDIA_KEYERR_UNKNOWN",
19298 "MEDIA_RULE",
19299 "MEDIUM_FLOAT",
19300 "MEDIUM_INT",
19301 "META_MASK",
19302 "MIDIAccess",
19303 "MIDIConnectionEvent",
19304 "MIDIInput",
19305 "MIDIInputMap",
19306 "MIDIMessageEvent",
19307 "MIDIOutput",
19308 "MIDIOutputMap",
19309 "MIDIPort",
19310 "MIN",
19311 "MIN_PROGRAM_TEXEL_OFFSET",
19312 "MIN_SAFE_INTEGER",
19313 "MIN_VALUE",
19314 "MIRRORED_REPEAT",
19315 "MODE_ASYNCHRONOUS",
19316 "MODE_SYNCHRONOUS",
19317 "MODIFICATION",
19318 "MOUSEDOWN",
19319 "MOUSEDRAG",
19320 "MOUSEMOVE",
19321 "MOUSEOUT",
19322 "MOUSEOVER",
19323 "MOUSEUP",
19324 "MOZ_KEYFRAMES_RULE",
19325 "MOZ_KEYFRAME_RULE",
19326 "MOZ_SOURCE_CURSOR",
19327 "MOZ_SOURCE_ERASER",
19328 "MOZ_SOURCE_KEYBOARD",
19329 "MOZ_SOURCE_MOUSE",
19330 "MOZ_SOURCE_PEN",
19331 "MOZ_SOURCE_TOUCH",
19332 "MOZ_SOURCE_UNKNOWN",
19333 "MSGESTURE_FLAG_BEGIN",
19334 "MSGESTURE_FLAG_CANCEL",
19335 "MSGESTURE_FLAG_END",
19336 "MSGESTURE_FLAG_INERTIA",
19337 "MSGESTURE_FLAG_NONE",
19338 "MSPOINTER_TYPE_MOUSE",
19339 "MSPOINTER_TYPE_PEN",
19340 "MSPOINTER_TYPE_TOUCH",
19341 "MS_ASYNC_CALLBACK_STATUS_ASSIGN_DELEGATE",
19342 "MS_ASYNC_CALLBACK_STATUS_CANCEL",
19343 "MS_ASYNC_CALLBACK_STATUS_CHOOSEANY",
19344 "MS_ASYNC_CALLBACK_STATUS_ERROR",
19345 "MS_ASYNC_CALLBACK_STATUS_JOIN",
19346 "MS_ASYNC_OP_STATUS_CANCELED",
19347 "MS_ASYNC_OP_STATUS_ERROR",
19348 "MS_ASYNC_OP_STATUS_SUCCESS",
19349 "MS_MANIPULATION_STATE_ACTIVE",
19350 "MS_MANIPULATION_STATE_CANCELLED",
19351 "MS_MANIPULATION_STATE_COMMITTED",
19352 "MS_MANIPULATION_STATE_DRAGGING",
19353 "MS_MANIPULATION_STATE_INERTIA",
19354 "MS_MANIPULATION_STATE_PRESELECT",
19355 "MS_MANIPULATION_STATE_SELECTING",
19356 "MS_MANIPULATION_STATE_STOPPED",
19357 "MS_MEDIA_ERR_ENCRYPTED",
19358 "MS_MEDIA_KEYERR_CLIENT",
19359 "MS_MEDIA_KEYERR_DOMAIN",
19360 "MS_MEDIA_KEYERR_HARDWARECHANGE",
19361 "MS_MEDIA_KEYERR_OUTPUT",
19362 "MS_MEDIA_KEYERR_SERVICE",
19363 "MS_MEDIA_KEYERR_UNKNOWN",
19364 "Map",
19365 "Math",
19366 "MathMLElement",
19367 "MediaCapabilities",
19368 "MediaCapabilitiesInfo",
19369 "MediaController",
19370 "MediaDeviceInfo",
19371 "MediaDevices",
19372 "MediaElementAudioSourceNode",
19373 "MediaEncryptedEvent",
19374 "MediaError",
19375 "MediaKeyError",
19376 "MediaKeyEvent",
19377 "MediaKeyMessageEvent",
19378 "MediaKeyNeededEvent",
19379 "MediaKeySession",
19380 "MediaKeyStatusMap",
19381 "MediaKeySystemAccess",
19382 "MediaKeys",
19383 "MediaList",
19384 "MediaMetadata",
19385 "MediaQueryList",
19386 "MediaQueryListEvent",
19387 "MediaRecorder",
19388 "MediaRecorderErrorEvent",
19389 "MediaSession",
19390 "MediaSettingsRange",
19391 "MediaSource",
19392 "MediaStream",
19393 "MediaStreamAudioDestinationNode",
19394 "MediaStreamAudioSourceNode",
19395 "MediaStreamEvent",
19396 "MediaStreamTrack",
19397 "MediaStreamTrackAudioSourceNode",
19398 "MediaStreamTrackEvent",
19399 "Memory",
19400 "MessageChannel",
19401 "MessageEvent",
19402 "MessagePort",
19403 "Methods",
19404 "MimeType",
19405 "MimeTypeArray",
19406 "Module",
19407 "MouseEvent",
19408 "MouseScrollEvent",
19409 "MozAnimation",
19410 "MozAnimationDelay",
19411 "MozAnimationDirection",
19412 "MozAnimationDuration",
19413 "MozAnimationFillMode",
19414 "MozAnimationIterationCount",
19415 "MozAnimationName",
19416 "MozAnimationPlayState",
19417 "MozAnimationTimingFunction",
19418 "MozAppearance",
19419 "MozBackfaceVisibility",
19420 "MozBinding",
19421 "MozBorderBottomColors",
19422 "MozBorderEnd",
19423 "MozBorderEndColor",
19424 "MozBorderEndStyle",
19425 "MozBorderEndWidth",
19426 "MozBorderImage",
19427 "MozBorderLeftColors",
19428 "MozBorderRightColors",
19429 "MozBorderStart",
19430 "MozBorderStartColor",
19431 "MozBorderStartStyle",
19432 "MozBorderStartWidth",
19433 "MozBorderTopColors",
19434 "MozBoxAlign",
19435 "MozBoxDirection",
19436 "MozBoxFlex",
19437 "MozBoxOrdinalGroup",
19438 "MozBoxOrient",
19439 "MozBoxPack",
19440 "MozBoxSizing",
19441 "MozCSSKeyframeRule",
19442 "MozCSSKeyframesRule",
19443 "MozColumnCount",
19444 "MozColumnFill",
19445 "MozColumnGap",
19446 "MozColumnRule",
19447 "MozColumnRuleColor",
19448 "MozColumnRuleStyle",
19449 "MozColumnRuleWidth",
19450 "MozColumnWidth",
19451 "MozColumns",
19452 "MozContactChangeEvent",
19453 "MozFloatEdge",
19454 "MozFontFeatureSettings",
19455 "MozFontLanguageOverride",
19456 "MozForceBrokenImageIcon",
19457 "MozHyphens",
19458 "MozImageRegion",
19459 "MozMarginEnd",
19460 "MozMarginStart",
19461 "MozMmsEvent",
19462 "MozMmsMessage",
19463 "MozMobileMessageThread",
19464 "MozOSXFontSmoothing",
19465 "MozOrient",
19466 "MozOsxFontSmoothing",
19467 "MozOutlineRadius",
19468 "MozOutlineRadiusBottomleft",
19469 "MozOutlineRadiusBottomright",
19470 "MozOutlineRadiusTopleft",
19471 "MozOutlineRadiusTopright",
19472 "MozPaddingEnd",
19473 "MozPaddingStart",
19474 "MozPerspective",
19475 "MozPerspectiveOrigin",
19476 "MozPowerManager",
19477 "MozSettingsEvent",
19478 "MozSmsEvent",
19479 "MozSmsMessage",
19480 "MozStackSizing",
19481 "MozTabSize",
19482 "MozTextAlignLast",
19483 "MozTextDecorationColor",
19484 "MozTextDecorationLine",
19485 "MozTextDecorationStyle",
19486 "MozTextSizeAdjust",
19487 "MozTransform",
19488 "MozTransformOrigin",
19489 "MozTransformStyle",
19490 "MozTransition",
19491 "MozTransitionDelay",
19492 "MozTransitionDuration",
19493 "MozTransitionProperty",
19494 "MozTransitionTimingFunction",
19495 "MozUserFocus",
19496 "MozUserInput",
19497 "MozUserModify",
19498 "MozUserSelect",
19499 "MozWindowDragging",
19500 "MozWindowShadow",
19501 "MutationEvent",
19502 "MutationObserver",
19503 "MutationRecord",
19504 "NAMESPACE_ERR",
19505 "NAMESPACE_RULE",
19506 "NEAREST",
19507 "NEAREST_MIPMAP_LINEAR",
19508 "NEAREST_MIPMAP_NEAREST",
19509 "NEGATIVE_INFINITY",
19510 "NETWORK_EMPTY",
19511 "NETWORK_ERR",
19512 "NETWORK_IDLE",
19513 "NETWORK_LOADED",
19514 "NETWORK_LOADING",
19515 "NETWORK_NO_SOURCE",
19516 "NEVER",
19517 "NEW",
19518 "NEXT",
19519 "NEXT_NO_DUPLICATE",
19520 "NICEST",
19521 "NODE_AFTER",
19522 "NODE_BEFORE",
19523 "NODE_BEFORE_AND_AFTER",
19524 "NODE_INSIDE",
19525 "NONE",
19526 "NON_TRANSIENT_ERR",
19527 "NOTATION_NODE",
19528 "NOTCH",
19529 "NOTEQUAL",
19530 "NOT_ALLOWED_ERR",
19531 "NOT_FOUND_ERR",
19532 "NOT_READABLE_ERR",
19533 "NOT_SUPPORTED_ERR",
19534 "NO_DATA_ALLOWED_ERR",
19535 "NO_ERR",
19536 "NO_ERROR",
19537 "NO_MODIFICATION_ALLOWED_ERR",
19538 "NUMBER_TYPE",
19539 "NUM_COMPRESSED_TEXTURE_FORMATS",
19540 "NaN",
19541 "NamedNodeMap",
19542 "NavigationPreloadManager",
19543 "Navigator",
19544 "NearbyLinks",
19545 "NetworkInformation",
19546 "Node",
19547 "NodeFilter",
19548 "NodeIterator",
19549 "NodeList",
19550 "Notation",
19551 "Notification",
19552 "NotifyPaintEvent",
19553 "Number",
19554 "NumberFormat",
19555 "OBJECT_TYPE",
19556 "OBSOLETE",
19557 "OK",
19558 "ONE",
19559 "ONE_MINUS_CONSTANT_ALPHA",
19560 "ONE_MINUS_CONSTANT_COLOR",
19561 "ONE_MINUS_DST_ALPHA",
19562 "ONE_MINUS_DST_COLOR",
19563 "ONE_MINUS_SRC_ALPHA",
19564 "ONE_MINUS_SRC_COLOR",
19565 "OPEN",
19566 "OPENED",
19567 "OPENING",
19568 "ORDERED_NODE_ITERATOR_TYPE",
19569 "ORDERED_NODE_SNAPSHOT_TYPE",
19570 "OTHER_ERROR",
19571 "OUT_OF_MEMORY",
19572 "Object",
19573 "OfflineAudioCompletionEvent",
19574 "OfflineAudioContext",
19575 "OfflineResourceList",
19576 "OffscreenCanvas",
19577 "OffscreenCanvasRenderingContext2D",
19578 "Option",
19579 "OrientationSensor",
19580 "OscillatorNode",
19581 "OverconstrainedError",
19582 "OverflowEvent",
19583 "PACK_ALIGNMENT",
19584 "PACK_ROW_LENGTH",
19585 "PACK_SKIP_PIXELS",
19586 "PACK_SKIP_ROWS",
19587 "PAGE_RULE",
19588 "PARSE_ERR",
19589 "PATHSEG_ARC_ABS",
19590 "PATHSEG_ARC_REL",
19591 "PATHSEG_CLOSEPATH",
19592 "PATHSEG_CURVETO_CUBIC_ABS",
19593 "PATHSEG_CURVETO_CUBIC_REL",
19594 "PATHSEG_CURVETO_CUBIC_SMOOTH_ABS",
19595 "PATHSEG_CURVETO_CUBIC_SMOOTH_REL",
19596 "PATHSEG_CURVETO_QUADRATIC_ABS",
19597 "PATHSEG_CURVETO_QUADRATIC_REL",
19598 "PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS",
19599 "PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL",
19600 "PATHSEG_LINETO_ABS",
19601 "PATHSEG_LINETO_HORIZONTAL_ABS",
19602 "PATHSEG_LINETO_HORIZONTAL_REL",
19603 "PATHSEG_LINETO_REL",
19604 "PATHSEG_LINETO_VERTICAL_ABS",
19605 "PATHSEG_LINETO_VERTICAL_REL",
19606 "PATHSEG_MOVETO_ABS",
19607 "PATHSEG_MOVETO_REL",
19608 "PATHSEG_UNKNOWN",
19609 "PATH_EXISTS_ERR",
19610 "PEAKING",
19611 "PERMISSION_DENIED",
19612 "PERSISTENT",
19613 "PI",
19614 "PIXEL_PACK_BUFFER",
19615 "PIXEL_PACK_BUFFER_BINDING",
19616 "PIXEL_UNPACK_BUFFER",
19617 "PIXEL_UNPACK_BUFFER_BINDING",
19618 "PLAYING_STATE",
19619 "POINTS",
19620 "POLYGON_OFFSET_FACTOR",
19621 "POLYGON_OFFSET_FILL",
19622 "POLYGON_OFFSET_UNITS",
19623 "POSITION_UNAVAILABLE",
19624 "POSITIVE_INFINITY",
19625 "PREV",
19626 "PREV_NO_DUPLICATE",
19627 "PROCESSING_INSTRUCTION_NODE",
19628 "PageChangeEvent",
19629 "PageTransitionEvent",
19630 "PaintRequest",
19631 "PaintRequestList",
19632 "PannerNode",
19633 "PasswordCredential",
19634 "Path2D",
19635 "PaymentAddress",
19636 "PaymentInstruments",
19637 "PaymentManager",
19638 "PaymentMethodChangeEvent",
19639 "PaymentRequest",
19640 "PaymentRequestUpdateEvent",
19641 "PaymentResponse",
19642 "Performance",
19643 "PerformanceElementTiming",
19644 "PerformanceEntry",
19645 "PerformanceEventTiming",
19646 "PerformanceLongTaskTiming",
19647 "PerformanceMark",
19648 "PerformanceMeasure",
19649 "PerformanceNavigation",
19650 "PerformanceNavigationTiming",
19651 "PerformanceObserver",
19652 "PerformanceObserverEntryList",
19653 "PerformancePaintTiming",
19654 "PerformanceResourceTiming",
19655 "PerformanceServerTiming",
19656 "PerformanceTiming",
19657 "PeriodicSyncManager",
19658 "PeriodicWave",
19659 "PermissionStatus",
19660 "Permissions",
19661 "PhotoCapabilities",
19662 "PictureInPictureWindow",
19663 "Plugin",
19664 "PluginArray",
19665 "PluralRules",
19666 "PointerEvent",
19667 "PopStateEvent",
19668 "PopupBlockedEvent",
19669 "Presentation",
19670 "PresentationAvailability",
19671 "PresentationConnection",
19672 "PresentationConnectionAvailableEvent",
19673 "PresentationConnectionCloseEvent",
19674 "PresentationConnectionList",
19675 "PresentationReceiver",
19676 "PresentationRequest",
19677 "ProcessingInstruction",
19678 "ProgressEvent",
19679 "Promise",
19680 "PromiseRejectionEvent",
19681 "PropertyNodeList",
19682 "Proxy",
19683 "PublicKeyCredential",
19684 "PushManager",
19685 "PushSubscription",
19686 "PushSubscriptionOptions",
19687 "Q",
19688 "QUERY_RESULT",
19689 "QUERY_RESULT_AVAILABLE",
19690 "QUOTA_ERR",
19691 "QUOTA_EXCEEDED_ERR",
19692 "QueryInterface",
19693 "R11F_G11F_B10F",
19694 "R16F",
19695 "R16I",
19696 "R16UI",
19697 "R32F",
19698 "R32I",
19699 "R32UI",
19700 "R8",
19701 "R8I",
19702 "R8UI",
19703 "R8_SNORM",
19704 "RASTERIZER_DISCARD",
19705 "READ_BUFFER",
19706 "READ_FRAMEBUFFER",
19707 "READ_FRAMEBUFFER_BINDING",
19708 "READ_ONLY",
19709 "READ_ONLY_ERR",
19710 "READ_WRITE",
19711 "RED",
19712 "RED_BITS",
19713 "RED_INTEGER",
19714 "REMOVAL",
19715 "RENDERBUFFER",
19716 "RENDERBUFFER_ALPHA_SIZE",
19717 "RENDERBUFFER_BINDING",
19718 "RENDERBUFFER_BLUE_SIZE",
19719 "RENDERBUFFER_DEPTH_SIZE",
19720 "RENDERBUFFER_GREEN_SIZE",
19721 "RENDERBUFFER_HEIGHT",
19722 "RENDERBUFFER_INTERNAL_FORMAT",
19723 "RENDERBUFFER_RED_SIZE",
19724 "RENDERBUFFER_SAMPLES",
19725 "RENDERBUFFER_STENCIL_SIZE",
19726 "RENDERBUFFER_WIDTH",
19727 "RENDERER",
19728 "RENDERING_INTENT_ABSOLUTE_COLORIMETRIC",
19729 "RENDERING_INTENT_AUTO",
19730 "RENDERING_INTENT_PERCEPTUAL",
19731 "RENDERING_INTENT_RELATIVE_COLORIMETRIC",
19732 "RENDERING_INTENT_SATURATION",
19733 "RENDERING_INTENT_UNKNOWN",
19734 "REPEAT",
19735 "REPLACE",
19736 "RG",
19737 "RG16F",
19738 "RG16I",
19739 "RG16UI",
19740 "RG32F",
19741 "RG32I",
19742 "RG32UI",
19743 "RG8",
19744 "RG8I",
19745 "RG8UI",
19746 "RG8_SNORM",
19747 "RGB",
19748 "RGB10_A2",
19749 "RGB10_A2UI",
19750 "RGB16F",
19751 "RGB16I",
19752 "RGB16UI",
19753 "RGB32F",
19754 "RGB32I",
19755 "RGB32UI",
19756 "RGB565",
19757 "RGB5_A1",
19758 "RGB8",
19759 "RGB8I",
19760 "RGB8UI",
19761 "RGB8_SNORM",
19762 "RGB9_E5",
19763 "RGBA",
19764 "RGBA16F",
19765 "RGBA16I",
19766 "RGBA16UI",
19767 "RGBA32F",
19768 "RGBA32I",
19769 "RGBA32UI",
19770 "RGBA4",
19771 "RGBA8",
19772 "RGBA8I",
19773 "RGBA8UI",
19774 "RGBA8_SNORM",
19775 "RGBA_INTEGER",
19776 "RGBColor",
19777 "RGB_INTEGER",
19778 "RG_INTEGER",
19779 "ROTATION_CLOCKWISE",
19780 "ROTATION_COUNTERCLOCKWISE",
19781 "RTCCertificate",
19782 "RTCDTMFSender",
19783 "RTCDTMFToneChangeEvent",
19784 "RTCDataChannel",
19785 "RTCDataChannelEvent",
19786 "RTCDtlsTransport",
19787 "RTCError",
19788 "RTCErrorEvent",
19789 "RTCIceCandidate",
19790 "RTCIceTransport",
19791 "RTCPeerConnection",
19792 "RTCPeerConnectionIceErrorEvent",
19793 "RTCPeerConnectionIceEvent",
19794 "RTCRtpReceiver",
19795 "RTCRtpSender",
19796 "RTCRtpTransceiver",
19797 "RTCSctpTransport",
19798 "RTCSessionDescription",
19799 "RTCStatsReport",
19800 "RTCTrackEvent",
19801 "RadioNodeList",
19802 "Range",
19803 "RangeError",
19804 "RangeException",
19805 "ReadableStream",
19806 "ReadableStreamDefaultReader",
19807 "RecordErrorEvent",
19808 "Rect",
19809 "ReferenceError",
19810 "Reflect",
19811 "RegExp",
19812 "RelativeOrientationSensor",
19813 "RelativeTimeFormat",
19814 "RemotePlayback",
19815 "Report",
19816 "ReportBody",
19817 "ReportingObserver",
19818 "Request",
19819 "ResizeObserver",
19820 "ResizeObserverEntry",
19821 "ResizeObserverSize",
19822 "Response",
19823 "RuntimeError",
19824 "SAMPLER_2D",
19825 "SAMPLER_2D_ARRAY",
19826 "SAMPLER_2D_ARRAY_SHADOW",
19827 "SAMPLER_2D_SHADOW",
19828 "SAMPLER_3D",
19829 "SAMPLER_BINDING",
19830 "SAMPLER_CUBE",
19831 "SAMPLER_CUBE_SHADOW",
19832 "SAMPLES",
19833 "SAMPLE_ALPHA_TO_COVERAGE",
19834 "SAMPLE_BUFFERS",
19835 "SAMPLE_COVERAGE",
19836 "SAMPLE_COVERAGE_INVERT",
19837 "SAMPLE_COVERAGE_VALUE",
19838 "SAWTOOTH",
19839 "SCHEDULED_STATE",
19840 "SCISSOR_BOX",
19841 "SCISSOR_TEST",
19842 "SCROLL_PAGE_DOWN",
19843 "SCROLL_PAGE_UP",
19844 "SDP_ANSWER",
19845 "SDP_OFFER",
19846 "SDP_PRANSWER",
19847 "SECURITY_ERR",
19848 "SELECT",
19849 "SEPARATE_ATTRIBS",
19850 "SERIALIZE_ERR",
19851 "SEVERITY_ERROR",
19852 "SEVERITY_FATAL_ERROR",
19853 "SEVERITY_WARNING",
19854 "SHADER_COMPILER",
19855 "SHADER_TYPE",
19856 "SHADING_LANGUAGE_VERSION",
19857 "SHIFT_MASK",
19858 "SHORT",
19859 "SHOWING",
19860 "SHOW_ALL",
19861 "SHOW_ATTRIBUTE",
19862 "SHOW_CDATA_SECTION",
19863 "SHOW_COMMENT",
19864 "SHOW_DOCUMENT",
19865 "SHOW_DOCUMENT_FRAGMENT",
19866 "SHOW_DOCUMENT_TYPE",
19867 "SHOW_ELEMENT",
19868 "SHOW_ENTITY",
19869 "SHOW_ENTITY_REFERENCE",
19870 "SHOW_NOTATION",
19871 "SHOW_PROCESSING_INSTRUCTION",
19872 "SHOW_TEXT",
19873 "SIGNALED",
19874 "SIGNED_NORMALIZED",
19875 "SINE",
19876 "SOUNDFIELD",
19877 "SQLException",
19878 "SQRT1_2",
19879 "SQRT2",
19880 "SQUARE",
19881 "SRC_ALPHA",
19882 "SRC_ALPHA_SATURATE",
19883 "SRC_COLOR",
19884 "SRGB",
19885 "SRGB8",
19886 "SRGB8_ALPHA8",
19887 "START_TO_END",
19888 "START_TO_START",
19889 "STATIC_COPY",
19890 "STATIC_DRAW",
19891 "STATIC_READ",
19892 "STENCIL",
19893 "STENCIL_ATTACHMENT",
19894 "STENCIL_BACK_FAIL",
19895 "STENCIL_BACK_FUNC",
19896 "STENCIL_BACK_PASS_DEPTH_FAIL",
19897 "STENCIL_BACK_PASS_DEPTH_PASS",
19898 "STENCIL_BACK_REF",
19899 "STENCIL_BACK_VALUE_MASK",
19900 "STENCIL_BACK_WRITEMASK",
19901 "STENCIL_BITS",
19902 "STENCIL_BUFFER_BIT",
19903 "STENCIL_CLEAR_VALUE",
19904 "STENCIL_FAIL",
19905 "STENCIL_FUNC",
19906 "STENCIL_INDEX",
19907 "STENCIL_INDEX8",
19908 "STENCIL_PASS_DEPTH_FAIL",
19909 "STENCIL_PASS_DEPTH_PASS",
19910 "STENCIL_REF",
19911 "STENCIL_TEST",
19912 "STENCIL_VALUE_MASK",
19913 "STENCIL_WRITEMASK",
19914 "STREAM_COPY",
19915 "STREAM_DRAW",
19916 "STREAM_READ",
19917 "STRING_TYPE",
19918 "STYLE_RULE",
19919 "SUBPIXEL_BITS",
19920 "SUPPORTS_RULE",
19921 "SVGAElement",
19922 "SVGAltGlyphDefElement",
19923 "SVGAltGlyphElement",
19924 "SVGAltGlyphItemElement",
19925 "SVGAngle",
19926 "SVGAnimateColorElement",
19927 "SVGAnimateElement",
19928 "SVGAnimateMotionElement",
19929 "SVGAnimateTransformElement",
19930 "SVGAnimatedAngle",
19931 "SVGAnimatedBoolean",
19932 "SVGAnimatedEnumeration",
19933 "SVGAnimatedInteger",
19934 "SVGAnimatedLength",
19935 "SVGAnimatedLengthList",
19936 "SVGAnimatedNumber",
19937 "SVGAnimatedNumberList",
19938 "SVGAnimatedPreserveAspectRatio",
19939 "SVGAnimatedRect",
19940 "SVGAnimatedString",
19941 "SVGAnimatedTransformList",
19942 "SVGAnimationElement",
19943 "SVGCircleElement",
19944 "SVGClipPathElement",
19945 "SVGColor",
19946 "SVGComponentTransferFunctionElement",
19947 "SVGCursorElement",
19948 "SVGDefsElement",
19949 "SVGDescElement",
19950 "SVGDiscardElement",
19951 "SVGDocument",
19952 "SVGElement",
19953 "SVGElementInstance",
19954 "SVGElementInstanceList",
19955 "SVGEllipseElement",
19956 "SVGException",
19957 "SVGFEBlendElement",
19958 "SVGFEColorMatrixElement",
19959 "SVGFEComponentTransferElement",
19960 "SVGFECompositeElement",
19961 "SVGFEConvolveMatrixElement",
19962 "SVGFEDiffuseLightingElement",
19963 "SVGFEDisplacementMapElement",
19964 "SVGFEDistantLightElement",
19965 "SVGFEDropShadowElement",
19966 "SVGFEFloodElement",
19967 "SVGFEFuncAElement",
19968 "SVGFEFuncBElement",
19969 "SVGFEFuncGElement",
19970 "SVGFEFuncRElement",
19971 "SVGFEGaussianBlurElement",
19972 "SVGFEImageElement",
19973 "SVGFEMergeElement",
19974 "SVGFEMergeNodeElement",
19975 "SVGFEMorphologyElement",
19976 "SVGFEOffsetElement",
19977 "SVGFEPointLightElement",
19978 "SVGFESpecularLightingElement",
19979 "SVGFESpotLightElement",
19980 "SVGFETileElement",
19981 "SVGFETurbulenceElement",
19982 "SVGFilterElement",
19983 "SVGFontElement",
19984 "SVGFontFaceElement",
19985 "SVGFontFaceFormatElement",
19986 "SVGFontFaceNameElement",
19987 "SVGFontFaceSrcElement",
19988 "SVGFontFaceUriElement",
19989 "SVGForeignObjectElement",
19990 "SVGGElement",
19991 "SVGGeometryElement",
19992 "SVGGlyphElement",
19993 "SVGGlyphRefElement",
19994 "SVGGradientElement",
19995 "SVGGraphicsElement",
19996 "SVGHKernElement",
19997 "SVGImageElement",
19998 "SVGLength",
19999 "SVGLengthList",
20000 "SVGLineElement",
20001 "SVGLinearGradientElement",
20002 "SVGMPathElement",
20003 "SVGMarkerElement",
20004 "SVGMaskElement",
20005 "SVGMatrix",
20006 "SVGMetadataElement",
20007 "SVGMissingGlyphElement",
20008 "SVGNumber",
20009 "SVGNumberList",
20010 "SVGPaint",
20011 "SVGPathElement",
20012 "SVGPathSeg",
20013 "SVGPathSegArcAbs",
20014 "SVGPathSegArcRel",
20015 "SVGPathSegClosePath",
20016 "SVGPathSegCurvetoCubicAbs",
20017 "SVGPathSegCurvetoCubicRel",
20018 "SVGPathSegCurvetoCubicSmoothAbs",
20019 "SVGPathSegCurvetoCubicSmoothRel",
20020 "SVGPathSegCurvetoQuadraticAbs",
20021 "SVGPathSegCurvetoQuadraticRel",
20022 "SVGPathSegCurvetoQuadraticSmoothAbs",
20023 "SVGPathSegCurvetoQuadraticSmoothRel",
20024 "SVGPathSegLinetoAbs",
20025 "SVGPathSegLinetoHorizontalAbs",
20026 "SVGPathSegLinetoHorizontalRel",
20027 "SVGPathSegLinetoRel",
20028 "SVGPathSegLinetoVerticalAbs",
20029 "SVGPathSegLinetoVerticalRel",
20030 "SVGPathSegList",
20031 "SVGPathSegMovetoAbs",
20032 "SVGPathSegMovetoRel",
20033 "SVGPatternElement",
20034 "SVGPoint",
20035 "SVGPointList",
20036 "SVGPolygonElement",
20037 "SVGPolylineElement",
20038 "SVGPreserveAspectRatio",
20039 "SVGRadialGradientElement",
20040 "SVGRect",
20041 "SVGRectElement",
20042 "SVGRenderingIntent",
20043 "SVGSVGElement",
20044 "SVGScriptElement",
20045 "SVGSetElement",
20046 "SVGStopElement",
20047 "SVGStringList",
20048 "SVGStyleElement",
20049 "SVGSwitchElement",
20050 "SVGSymbolElement",
20051 "SVGTRefElement",
20052 "SVGTSpanElement",
20053 "SVGTextContentElement",
20054 "SVGTextElement",
20055 "SVGTextPathElement",
20056 "SVGTextPositioningElement",
20057 "SVGTitleElement",
20058 "SVGTransform",
20059 "SVGTransformList",
20060 "SVGUnitTypes",
20061 "SVGUseElement",
20062 "SVGVKernElement",
20063 "SVGViewElement",
20064 "SVGViewSpec",
20065 "SVGZoomAndPan",
20066 "SVGZoomEvent",
20067 "SVG_ANGLETYPE_DEG",
20068 "SVG_ANGLETYPE_GRAD",
20069 "SVG_ANGLETYPE_RAD",
20070 "SVG_ANGLETYPE_UNKNOWN",
20071 "SVG_ANGLETYPE_UNSPECIFIED",
20072 "SVG_CHANNEL_A",
20073 "SVG_CHANNEL_B",
20074 "SVG_CHANNEL_G",
20075 "SVG_CHANNEL_R",
20076 "SVG_CHANNEL_UNKNOWN",
20077 "SVG_COLORTYPE_CURRENTCOLOR",
20078 "SVG_COLORTYPE_RGBCOLOR",
20079 "SVG_COLORTYPE_RGBCOLOR_ICCCOLOR",
20080 "SVG_COLORTYPE_UNKNOWN",
20081 "SVG_EDGEMODE_DUPLICATE",
20082 "SVG_EDGEMODE_NONE",
20083 "SVG_EDGEMODE_UNKNOWN",
20084 "SVG_EDGEMODE_WRAP",
20085 "SVG_FEBLEND_MODE_COLOR",
20086 "SVG_FEBLEND_MODE_COLOR_BURN",
20087 "SVG_FEBLEND_MODE_COLOR_DODGE",
20088 "SVG_FEBLEND_MODE_DARKEN",
20089 "SVG_FEBLEND_MODE_DIFFERENCE",
20090 "SVG_FEBLEND_MODE_EXCLUSION",
20091 "SVG_FEBLEND_MODE_HARD_LIGHT",
20092 "SVG_FEBLEND_MODE_HUE",
20093 "SVG_FEBLEND_MODE_LIGHTEN",
20094 "SVG_FEBLEND_MODE_LUMINOSITY",
20095 "SVG_FEBLEND_MODE_MULTIPLY",
20096 "SVG_FEBLEND_MODE_NORMAL",
20097 "SVG_FEBLEND_MODE_OVERLAY",
20098 "SVG_FEBLEND_MODE_SATURATION",
20099 "SVG_FEBLEND_MODE_SCREEN",
20100 "SVG_FEBLEND_MODE_SOFT_LIGHT",
20101 "SVG_FEBLEND_MODE_UNKNOWN",
20102 "SVG_FECOLORMATRIX_TYPE_HUEROTATE",
20103 "SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA",
20104 "SVG_FECOLORMATRIX_TYPE_MATRIX",
20105 "SVG_FECOLORMATRIX_TYPE_SATURATE",
20106 "SVG_FECOLORMATRIX_TYPE_UNKNOWN",
20107 "SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE",
20108 "SVG_FECOMPONENTTRANSFER_TYPE_GAMMA",
20109 "SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY",
20110 "SVG_FECOMPONENTTRANSFER_TYPE_LINEAR",
20111 "SVG_FECOMPONENTTRANSFER_TYPE_TABLE",
20112 "SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN",
20113 "SVG_FECOMPOSITE_OPERATOR_ARITHMETIC",
20114 "SVG_FECOMPOSITE_OPERATOR_ATOP",
20115 "SVG_FECOMPOSITE_OPERATOR_IN",
20116 "SVG_FECOMPOSITE_OPERATOR_OUT",
20117 "SVG_FECOMPOSITE_OPERATOR_OVER",
20118 "SVG_FECOMPOSITE_OPERATOR_UNKNOWN",
20119 "SVG_FECOMPOSITE_OPERATOR_XOR",
20120 "SVG_INVALID_VALUE_ERR",
20121 "SVG_LENGTHTYPE_CM",
20122 "SVG_LENGTHTYPE_EMS",
20123 "SVG_LENGTHTYPE_EXS",
20124 "SVG_LENGTHTYPE_IN",
20125 "SVG_LENGTHTYPE_MM",
20126 "SVG_LENGTHTYPE_NUMBER",
20127 "SVG_LENGTHTYPE_PC",
20128 "SVG_LENGTHTYPE_PERCENTAGE",
20129 "SVG_LENGTHTYPE_PT",
20130 "SVG_LENGTHTYPE_PX",
20131 "SVG_LENGTHTYPE_UNKNOWN",
20132 "SVG_MARKERUNITS_STROKEWIDTH",
20133 "SVG_MARKERUNITS_UNKNOWN",
20134 "SVG_MARKERUNITS_USERSPACEONUSE",
20135 "SVG_MARKER_ORIENT_ANGLE",
20136 "SVG_MARKER_ORIENT_AUTO",
20137 "SVG_MARKER_ORIENT_UNKNOWN",
20138 "SVG_MASKTYPE_ALPHA",
20139 "SVG_MASKTYPE_LUMINANCE",
20140 "SVG_MATRIX_NOT_INVERTABLE",
20141 "SVG_MEETORSLICE_MEET",
20142 "SVG_MEETORSLICE_SLICE",
20143 "SVG_MEETORSLICE_UNKNOWN",
20144 "SVG_MORPHOLOGY_OPERATOR_DILATE",
20145 "SVG_MORPHOLOGY_OPERATOR_ERODE",
20146 "SVG_MORPHOLOGY_OPERATOR_UNKNOWN",
20147 "SVG_PAINTTYPE_CURRENTCOLOR",
20148 "SVG_PAINTTYPE_NONE",
20149 "SVG_PAINTTYPE_RGBCOLOR",
20150 "SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR",
20151 "SVG_PAINTTYPE_UNKNOWN",
20152 "SVG_PAINTTYPE_URI",
20153 "SVG_PAINTTYPE_URI_CURRENTCOLOR",
20154 "SVG_PAINTTYPE_URI_NONE",
20155 "SVG_PAINTTYPE_URI_RGBCOLOR",
20156 "SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR",
20157 "SVG_PRESERVEASPECTRATIO_NONE",
20158 "SVG_PRESERVEASPECTRATIO_UNKNOWN",
20159 "SVG_PRESERVEASPECTRATIO_XMAXYMAX",
20160 "SVG_PRESERVEASPECTRATIO_XMAXYMID",
20161 "SVG_PRESERVEASPECTRATIO_XMAXYMIN",
20162 "SVG_PRESERVEASPECTRATIO_XMIDYMAX",
20163 "SVG_PRESERVEASPECTRATIO_XMIDYMID",
20164 "SVG_PRESERVEASPECTRATIO_XMIDYMIN",
20165 "SVG_PRESERVEASPECTRATIO_XMINYMAX",
20166 "SVG_PRESERVEASPECTRATIO_XMINYMID",
20167 "SVG_PRESERVEASPECTRATIO_XMINYMIN",
20168 "SVG_SPREADMETHOD_PAD",
20169 "SVG_SPREADMETHOD_REFLECT",
20170 "SVG_SPREADMETHOD_REPEAT",
20171 "SVG_SPREADMETHOD_UNKNOWN",
20172 "SVG_STITCHTYPE_NOSTITCH",
20173 "SVG_STITCHTYPE_STITCH",
20174 "SVG_STITCHTYPE_UNKNOWN",
20175 "SVG_TRANSFORM_MATRIX",
20176 "SVG_TRANSFORM_ROTATE",
20177 "SVG_TRANSFORM_SCALE",
20178 "SVG_TRANSFORM_SKEWX",
20179 "SVG_TRANSFORM_SKEWY",
20180 "SVG_TRANSFORM_TRANSLATE",
20181 "SVG_TRANSFORM_UNKNOWN",
20182 "SVG_TURBULENCE_TYPE_FRACTALNOISE",
20183 "SVG_TURBULENCE_TYPE_TURBULENCE",
20184 "SVG_TURBULENCE_TYPE_UNKNOWN",
20185 "SVG_UNIT_TYPE_OBJECTBOUNDINGBOX",
20186 "SVG_UNIT_TYPE_UNKNOWN",
20187 "SVG_UNIT_TYPE_USERSPACEONUSE",
20188 "SVG_WRONG_TYPE_ERR",
20189 "SVG_ZOOMANDPAN_DISABLE",
20190 "SVG_ZOOMANDPAN_MAGNIFY",
20191 "SVG_ZOOMANDPAN_UNKNOWN",
20192 "SYNC_CONDITION",
20193 "SYNC_FENCE",
20194 "SYNC_FLAGS",
20195 "SYNC_FLUSH_COMMANDS_BIT",
20196 "SYNC_GPU_COMMANDS_COMPLETE",
20197 "SYNC_STATUS",
20198 "SYNTAX_ERR",
20199 "SavedPages",
20200 "Screen",
20201 "ScreenOrientation",
20202 "Script",
20203 "ScriptProcessorNode",
20204 "ScrollAreaEvent",
20205 "SecurityPolicyViolationEvent",
20206 "Selection",
20207 "Sensor",
20208 "SensorErrorEvent",
20209 "ServiceWorker",
20210 "ServiceWorkerContainer",
20211 "ServiceWorkerRegistration",
20212 "SessionDescription",
20213 "Set",
20214 "ShadowRoot",
20215 "SharedArrayBuffer",
20216 "SharedWorker",
20217 "SimpleGestureEvent",
20218 "SourceBuffer",
20219 "SourceBufferList",
20220 "SpeechSynthesis",
20221 "SpeechSynthesisErrorEvent",
20222 "SpeechSynthesisEvent",
20223 "SpeechSynthesisUtterance",
20224 "SpeechSynthesisVoice",
20225 "StaticRange",
20226 "StereoPannerNode",
20227 "StopIteration",
20228 "Storage",
20229 "StorageEvent",
20230 "StorageManager",
20231 "String",
20232 "StructType",
20233 "StylePropertyMap",
20234 "StylePropertyMapReadOnly",
20235 "StyleSheet",
20236 "StyleSheetList",
20237 "SubmitEvent",
20238 "SubtleCrypto",
20239 "Symbol",
20240 "SyncManager",
20241 "SyntaxError",
20242 "TEMPORARY",
20243 "TEXTPATH_METHODTYPE_ALIGN",
20244 "TEXTPATH_METHODTYPE_STRETCH",
20245 "TEXTPATH_METHODTYPE_UNKNOWN",
20246 "TEXTPATH_SPACINGTYPE_AUTO",
20247 "TEXTPATH_SPACINGTYPE_EXACT",
20248 "TEXTPATH_SPACINGTYPE_UNKNOWN",
20249 "TEXTURE",
20250 "TEXTURE0",
20251 "TEXTURE1",
20252 "TEXTURE10",
20253 "TEXTURE11",
20254 "TEXTURE12",
20255 "TEXTURE13",
20256 "TEXTURE14",
20257 "TEXTURE15",
20258 "TEXTURE16",
20259 "TEXTURE17",
20260 "TEXTURE18",
20261 "TEXTURE19",
20262 "TEXTURE2",
20263 "TEXTURE20",
20264 "TEXTURE21",
20265 "TEXTURE22",
20266 "TEXTURE23",
20267 "TEXTURE24",
20268 "TEXTURE25",
20269 "TEXTURE26",
20270 "TEXTURE27",
20271 "TEXTURE28",
20272 "TEXTURE29",
20273 "TEXTURE3",
20274 "TEXTURE30",
20275 "TEXTURE31",
20276 "TEXTURE4",
20277 "TEXTURE5",
20278 "TEXTURE6",
20279 "TEXTURE7",
20280 "TEXTURE8",
20281 "TEXTURE9",
20282 "TEXTURE_2D",
20283 "TEXTURE_2D_ARRAY",
20284 "TEXTURE_3D",
20285 "TEXTURE_BASE_LEVEL",
20286 "TEXTURE_BINDING_2D",
20287 "TEXTURE_BINDING_2D_ARRAY",
20288 "TEXTURE_BINDING_3D",
20289 "TEXTURE_BINDING_CUBE_MAP",
20290 "TEXTURE_COMPARE_FUNC",
20291 "TEXTURE_COMPARE_MODE",
20292 "TEXTURE_CUBE_MAP",
20293 "TEXTURE_CUBE_MAP_NEGATIVE_X",
20294 "TEXTURE_CUBE_MAP_NEGATIVE_Y",
20295 "TEXTURE_CUBE_MAP_NEGATIVE_Z",
20296 "TEXTURE_CUBE_MAP_POSITIVE_X",
20297 "TEXTURE_CUBE_MAP_POSITIVE_Y",
20298 "TEXTURE_CUBE_MAP_POSITIVE_Z",
20299 "TEXTURE_IMMUTABLE_FORMAT",
20300 "TEXTURE_IMMUTABLE_LEVELS",
20301 "TEXTURE_MAG_FILTER",
20302 "TEXTURE_MAX_ANISOTROPY_EXT",
20303 "TEXTURE_MAX_LEVEL",
20304 "TEXTURE_MAX_LOD",
20305 "TEXTURE_MIN_FILTER",
20306 "TEXTURE_MIN_LOD",
20307 "TEXTURE_WRAP_R",
20308 "TEXTURE_WRAP_S",
20309 "TEXTURE_WRAP_T",
20310 "TEXT_NODE",
20311 "TIMEOUT",
20312 "TIMEOUT_ERR",
20313 "TIMEOUT_EXPIRED",
20314 "TIMEOUT_IGNORED",
20315 "TOO_LARGE_ERR",
20316 "TRANSACTION_INACTIVE_ERR",
20317 "TRANSFORM_FEEDBACK",
20318 "TRANSFORM_FEEDBACK_ACTIVE",
20319 "TRANSFORM_FEEDBACK_BINDING",
20320 "TRANSFORM_FEEDBACK_BUFFER",
20321 "TRANSFORM_FEEDBACK_BUFFER_BINDING",
20322 "TRANSFORM_FEEDBACK_BUFFER_MODE",
20323 "TRANSFORM_FEEDBACK_BUFFER_SIZE",
20324 "TRANSFORM_FEEDBACK_BUFFER_START",
20325 "TRANSFORM_FEEDBACK_PAUSED",
20326 "TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN",
20327 "TRANSFORM_FEEDBACK_VARYINGS",
20328 "TRIANGLE",
20329 "TRIANGLES",
20330 "TRIANGLE_FAN",
20331 "TRIANGLE_STRIP",
20332 "TYPE_BACK_FORWARD",
20333 "TYPE_ERR",
20334 "TYPE_MISMATCH_ERR",
20335 "TYPE_NAVIGATE",
20336 "TYPE_RELOAD",
20337 "TYPE_RESERVED",
20338 "Table",
20339 "TaskAttributionTiming",
20340 "Text",
20341 "TextDecoder",
20342 "TextDecoderStream",
20343 "TextEncoder",
20344 "TextEncoderStream",
20345 "TextEvent",
20346 "TextMetrics",
20347 "TextTrack",
20348 "TextTrackCue",
20349 "TextTrackCueList",
20350 "TextTrackList",
20351 "TimeEvent",
20352 "TimeRanges",
20353 "Touch",
20354 "TouchEvent",
20355 "TouchList",
20356 "TrackEvent",
20357 "TransformStream",
20358 "TransitionEvent",
20359 "TreeWalker",
20360 "TrustedHTML",
20361 "TrustedScript",
20362 "TrustedScriptURL",
20363 "TrustedTypePolicy",
20364 "TrustedTypePolicyFactory",
20365 "TypeError",
20366 "TypedObject",
20367 "U2F",
20368 "UIEvent",
20369 "UNCACHED",
20370 "UNIFORM_ARRAY_STRIDE",
20371 "UNIFORM_BLOCK_ACTIVE_UNIFORMS",
20372 "UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES",
20373 "UNIFORM_BLOCK_BINDING",
20374 "UNIFORM_BLOCK_DATA_SIZE",
20375 "UNIFORM_BLOCK_INDEX",
20376 "UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER",
20377 "UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER",
20378 "UNIFORM_BUFFER",
20379 "UNIFORM_BUFFER_BINDING",
20380 "UNIFORM_BUFFER_OFFSET_ALIGNMENT",
20381 "UNIFORM_BUFFER_SIZE",
20382 "UNIFORM_BUFFER_START",
20383 "UNIFORM_IS_ROW_MAJOR",
20384 "UNIFORM_MATRIX_STRIDE",
20385 "UNIFORM_OFFSET",
20386 "UNIFORM_SIZE",
20387 "UNIFORM_TYPE",
20388 "UNKNOWN_ERR",
20389 "UNKNOWN_RULE",
20390 "UNMASKED_RENDERER_WEBGL",
20391 "UNMASKED_VENDOR_WEBGL",
20392 "UNORDERED_NODE_ITERATOR_TYPE",
20393 "UNORDERED_NODE_SNAPSHOT_TYPE",
20394 "UNPACK_ALIGNMENT",
20395 "UNPACK_COLORSPACE_CONVERSION_WEBGL",
20396 "UNPACK_FLIP_Y_WEBGL",
20397 "UNPACK_IMAGE_HEIGHT",
20398 "UNPACK_PREMULTIPLY_ALPHA_WEBGL",
20399 "UNPACK_ROW_LENGTH",
20400 "UNPACK_SKIP_IMAGES",
20401 "UNPACK_SKIP_PIXELS",
20402 "UNPACK_SKIP_ROWS",
20403 "UNSCHEDULED_STATE",
20404 "UNSENT",
20405 "UNSIGNALED",
20406 "UNSIGNED_BYTE",
20407 "UNSIGNED_INT",
20408 "UNSIGNED_INT_10F_11F_11F_REV",
20409 "UNSIGNED_INT_24_8",
20410 "UNSIGNED_INT_2_10_10_10_REV",
20411 "UNSIGNED_INT_5_9_9_9_REV",
20412 "UNSIGNED_INT_SAMPLER_2D",
20413 "UNSIGNED_INT_SAMPLER_2D_ARRAY",
20414 "UNSIGNED_INT_SAMPLER_3D",
20415 "UNSIGNED_INT_SAMPLER_CUBE",
20416 "UNSIGNED_INT_VEC2",
20417 "UNSIGNED_INT_VEC3",
20418 "UNSIGNED_INT_VEC4",
20419 "UNSIGNED_NORMALIZED",
20420 "UNSIGNED_SHORT",
20421 "UNSIGNED_SHORT_4_4_4_4",
20422 "UNSIGNED_SHORT_5_5_5_1",
20423 "UNSIGNED_SHORT_5_6_5",
20424 "UNSPECIFIED_EVENT_TYPE_ERR",
20425 "UPDATEREADY",
20426 "URIError",
20427 "URL",
20428 "URLSearchParams",
20429 "URLUnencoded",
20430 "URL_MISMATCH_ERR",
20431 "USB",
20432 "USBAlternateInterface",
20433 "USBConfiguration",
20434 "USBConnectionEvent",
20435 "USBDevice",
20436 "USBEndpoint",
20437 "USBInTransferResult",
20438 "USBInterface",
20439 "USBIsochronousInTransferPacket",
20440 "USBIsochronousInTransferResult",
20441 "USBIsochronousOutTransferPacket",
20442 "USBIsochronousOutTransferResult",
20443 "USBOutTransferResult",
20444 "UTC",
20445 "Uint16Array",
20446 "Uint32Array",
20447 "Uint8Array",
20448 "Uint8ClampedArray",
20449 "UserActivation",
20450 "UserMessageHandler",
20451 "UserMessageHandlersNamespace",
20452 "UserProximityEvent",
20453 "VALIDATE_STATUS",
20454 "VALIDATION_ERR",
20455 "VARIABLES_RULE",
20456 "VENDOR",
20457 "VERSION",
20458 "VERSION_CHANGE",
20459 "VERSION_ERR",
20460 "VERTEX_ARRAY_BINDING",
20461 "VERTEX_ATTRIB_ARRAY_BUFFER_BINDING",
20462 "VERTEX_ATTRIB_ARRAY_DIVISOR",
20463 "VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE",
20464 "VERTEX_ATTRIB_ARRAY_ENABLED",
20465 "VERTEX_ATTRIB_ARRAY_INTEGER",
20466 "VERTEX_ATTRIB_ARRAY_NORMALIZED",
20467 "VERTEX_ATTRIB_ARRAY_POINTER",
20468 "VERTEX_ATTRIB_ARRAY_SIZE",
20469 "VERTEX_ATTRIB_ARRAY_STRIDE",
20470 "VERTEX_ATTRIB_ARRAY_TYPE",
20471 "VERTEX_SHADER",
20472 "VERTICAL",
20473 "VERTICAL_AXIS",
20474 "VER_ERR",
20475 "VIEWPORT",
20476 "VIEWPORT_RULE",
20477 "VRDisplay",
20478 "VRDisplayCapabilities",
20479 "VRDisplayEvent",
20480 "VREyeParameters",
20481 "VRFieldOfView",
20482 "VRFrameData",
20483 "VRPose",
20484 "VRStageParameters",
20485 "VTTCue",
20486 "VTTRegion",
20487 "ValidityState",
20488 "VideoPlaybackQuality",
20489 "VideoStreamTrack",
20490 "VisualViewport",
20491 "WAIT_FAILED",
20492 "WEBKIT_FILTER_RULE",
20493 "WEBKIT_KEYFRAMES_RULE",
20494 "WEBKIT_KEYFRAME_RULE",
20495 "WEBKIT_REGION_RULE",
20496 "WRONG_DOCUMENT_ERR",
20497 "WakeLock",
20498 "WakeLockSentinel",
20499 "WasmAnyRef",
20500 "WaveShaperNode",
20501 "WeakMap",
20502 "WeakRef",
20503 "WeakSet",
20504 "WebAssembly",
20505 "WebGL2RenderingContext",
20506 "WebGLActiveInfo",
20507 "WebGLBuffer",
20508 "WebGLContextEvent",
20509 "WebGLFramebuffer",
20510 "WebGLProgram",
20511 "WebGLQuery",
20512 "WebGLRenderbuffer",
20513 "WebGLRenderingContext",
20514 "WebGLSampler",
20515 "WebGLShader",
20516 "WebGLShaderPrecisionFormat",
20517 "WebGLSync",
20518 "WebGLTexture",
20519 "WebGLTransformFeedback",
20520 "WebGLUniformLocation",
20521 "WebGLVertexArray",
20522 "WebGLVertexArrayObject",
20523 "WebKitAnimationEvent",
20524 "WebKitBlobBuilder",
20525 "WebKitCSSFilterRule",
20526 "WebKitCSSFilterValue",
20527 "WebKitCSSKeyframeRule",
20528 "WebKitCSSKeyframesRule",
20529 "WebKitCSSMatrix",
20530 "WebKitCSSRegionRule",
20531 "WebKitCSSTransformValue",
20532 "WebKitDataCue",
20533 "WebKitGamepad",
20534 "WebKitMediaKeyError",
20535 "WebKitMediaKeyMessageEvent",
20536 "WebKitMediaKeySession",
20537 "WebKitMediaKeys",
20538 "WebKitMediaSource",
20539 "WebKitMutationObserver",
20540 "WebKitNamespace",
20541 "WebKitPlaybackTargetAvailabilityEvent",
20542 "WebKitPoint",
20543 "WebKitShadowRoot",
20544 "WebKitSourceBuffer",
20545 "WebKitSourceBufferList",
20546 "WebKitTransitionEvent",
20547 "WebSocket",
20548 "WebkitAlignContent",
20549 "WebkitAlignItems",
20550 "WebkitAlignSelf",
20551 "WebkitAnimation",
20552 "WebkitAnimationDelay",
20553 "WebkitAnimationDirection",
20554 "WebkitAnimationDuration",
20555 "WebkitAnimationFillMode",
20556 "WebkitAnimationIterationCount",
20557 "WebkitAnimationName",
20558 "WebkitAnimationPlayState",
20559 "WebkitAnimationTimingFunction",
20560 "WebkitAppearance",
20561 "WebkitBackfaceVisibility",
20562 "WebkitBackgroundClip",
20563 "WebkitBackgroundOrigin",
20564 "WebkitBackgroundSize",
20565 "WebkitBorderBottomLeftRadius",
20566 "WebkitBorderBottomRightRadius",
20567 "WebkitBorderImage",
20568 "WebkitBorderRadius",
20569 "WebkitBorderTopLeftRadius",
20570 "WebkitBorderTopRightRadius",
20571 "WebkitBoxAlign",
20572 "WebkitBoxDirection",
20573 "WebkitBoxFlex",
20574 "WebkitBoxOrdinalGroup",
20575 "WebkitBoxOrient",
20576 "WebkitBoxPack",
20577 "WebkitBoxShadow",
20578 "WebkitBoxSizing",
20579 "WebkitFilter",
20580 "WebkitFlex",
20581 "WebkitFlexBasis",
20582 "WebkitFlexDirection",
20583 "WebkitFlexFlow",
20584 "WebkitFlexGrow",
20585 "WebkitFlexShrink",
20586 "WebkitFlexWrap",
20587 "WebkitJustifyContent",
20588 "WebkitLineClamp",
20589 "WebkitMask",
20590 "WebkitMaskClip",
20591 "WebkitMaskComposite",
20592 "WebkitMaskImage",
20593 "WebkitMaskOrigin",
20594 "WebkitMaskPosition",
20595 "WebkitMaskPositionX",
20596 "WebkitMaskPositionY",
20597 "WebkitMaskRepeat",
20598 "WebkitMaskSize",
20599 "WebkitOrder",
20600 "WebkitPerspective",
20601 "WebkitPerspectiveOrigin",
20602 "WebkitTextFillColor",
20603 "WebkitTextSizeAdjust",
20604 "WebkitTextStroke",
20605 "WebkitTextStrokeColor",
20606 "WebkitTextStrokeWidth",
20607 "WebkitTransform",
20608 "WebkitTransformOrigin",
20609 "WebkitTransformStyle",
20610 "WebkitTransition",
20611 "WebkitTransitionDelay",
20612 "WebkitTransitionDuration",
20613 "WebkitTransitionProperty",
20614 "WebkitTransitionTimingFunction",
20615 "WebkitUserSelect",
20616 "WheelEvent",
20617 "Window",
20618 "Worker",
20619 "Worklet",
20620 "WritableStream",
20621 "WritableStreamDefaultWriter",
20622 "XMLDocument",
20623 "XMLHttpRequest",
20624 "XMLHttpRequestEventTarget",
20625 "XMLHttpRequestException",
20626 "XMLHttpRequestProgressEvent",
20627 "XMLHttpRequestUpload",
20628 "XMLSerializer",
20629 "XMLStylesheetProcessingInstruction",
20630 "XPathEvaluator",
20631 "XPathException",
20632 "XPathExpression",
20633 "XPathNSResolver",
20634 "XPathResult",
20635 "XRBoundedReferenceSpace",
20636 "XRDOMOverlayState",
20637 "XRFrame",
20638 "XRHitTestResult",
20639 "XRHitTestSource",
20640 "XRInputSource",
20641 "XRInputSourceArray",
20642 "XRInputSourceEvent",
20643 "XRInputSourcesChangeEvent",
20644 "XRLayer",
20645 "XRPose",
20646 "XRRay",
20647 "XRReferenceSpace",
20648 "XRReferenceSpaceEvent",
20649 "XRRenderState",
20650 "XRRigidTransform",
20651 "XRSession",
20652 "XRSessionEvent",
20653 "XRSpace",
20654 "XRSystem",
20655 "XRTransientInputHitTestResult",
20656 "XRTransientInputHitTestSource",
20657 "XRView",
20658 "XRViewerPose",
20659 "XRViewport",
20660 "XRWebGLLayer",
20661 "XSLTProcessor",
20662 "ZERO",
20663 "_XD0M_",
20664 "_YD0M_",
20665 "__defineGetter__",
20666 "__defineSetter__",
20667 "__lookupGetter__",
20668 "__lookupSetter__",
20669 "__opera",
20670 "__proto__",
20671 "_browserjsran",
20672 "a",
20673 "aLink",
20674 "abbr",
20675 "abort",
20676 "aborted",
20677 "abs",
20678 "absolute",
20679 "acceleration",
20680 "accelerationIncludingGravity",
20681 "accelerator",
20682 "accept",
20683 "acceptCharset",
20684 "acceptNode",
20685 "accessKey",
20686 "accessKeyLabel",
20687 "accuracy",
20688 "acos",
20689 "acosh",
20690 "action",
20691 "actionURL",
20692 "actions",
20693 "activated",
20694 "active",
20695 "activeCues",
20696 "activeElement",
20697 "activeSourceBuffers",
20698 "activeSourceCount",
20699 "activeTexture",
20700 "activeVRDisplays",
20701 "actualBoundingBoxAscent",
20702 "actualBoundingBoxDescent",
20703 "actualBoundingBoxLeft",
20704 "actualBoundingBoxRight",
20705 "add",
20706 "addAll",
20707 "addBehavior",
20708 "addCandidate",
20709 "addColorStop",
20710 "addCue",
20711 "addElement",
20712 "addEventListener",
20713 "addFilter",
20714 "addFromString",
20715 "addFromUri",
20716 "addIceCandidate",
20717 "addImport",
20718 "addListener",
20719 "addModule",
20720 "addNamed",
20721 "addPageRule",
20722 "addPath",
20723 "addPointer",
20724 "addRange",
20725 "addRegion",
20726 "addRule",
20727 "addSearchEngine",
20728 "addSourceBuffer",
20729 "addStream",
20730 "addTextTrack",
20731 "addTrack",
20732 "addTransceiver",
20733 "addWakeLockListener",
20734 "added",
20735 "addedNodes",
20736 "additionalName",
20737 "additiveSymbols",
20738 "addons",
20739 "address",
20740 "addressLine",
20741 "adoptNode",
20742 "adoptedStyleSheets",
20743 "adr",
20744 "advance",
20745 "after",
20746 "album",
20747 "alert",
20748 "algorithm",
20749 "align",
20750 "align-content",
20751 "align-items",
20752 "align-self",
20753 "alignContent",
20754 "alignItems",
20755 "alignSelf",
20756 "alignmentBaseline",
20757 "alinkColor",
20758 "all",
20759 "allSettled",
20760 "allow",
20761 "allowFullscreen",
20762 "allowPaymentRequest",
20763 "allowedDirections",
20764 "allowedFeatures",
20765 "allowedToPlay",
20766 "allowsFeature",
20767 "alpha",
20768 "alt",
20769 "altGraphKey",
20770 "altHtml",
20771 "altKey",
20772 "altLeft",
20773 "alternate",
20774 "alternateSetting",
20775 "alternates",
20776 "altitude",
20777 "altitudeAccuracy",
20778 "amplitude",
20779 "ancestorOrigins",
20780 "anchor",
20781 "anchorNode",
20782 "anchorOffset",
20783 "anchors",
20784 "and",
20785 "angle",
20786 "angularAcceleration",
20787 "angularVelocity",
20788 "animVal",
20789 "animate",
20790 "animatedInstanceRoot",
20791 "animatedNormalizedPathSegList",
20792 "animatedPathSegList",
20793 "animatedPoints",
20794 "animation",
20795 "animation-delay",
20796 "animation-direction",
20797 "animation-duration",
20798 "animation-fill-mode",
20799 "animation-iteration-count",
20800 "animation-name",
20801 "animation-play-state",
20802 "animation-timing-function",
20803 "animationDelay",
20804 "animationDirection",
20805 "animationDuration",
20806 "animationFillMode",
20807 "animationIterationCount",
20808 "animationName",
20809 "animationPlayState",
20810 "animationStartTime",
20811 "animationTimingFunction",
20812 "animationsPaused",
20813 "anniversary",
20814 "antialias",
20815 "anticipatedRemoval",
20816 "any",
20817 "app",
20818 "appCodeName",
20819 "appMinorVersion",
20820 "appName",
20821 "appNotifications",
20822 "appVersion",
20823 "appearance",
20824 "append",
20825 "appendBuffer",
20826 "appendChild",
20827 "appendData",
20828 "appendItem",
20829 "appendMedium",
20830 "appendNamed",
20831 "appendRule",
20832 "appendStream",
20833 "appendWindowEnd",
20834 "appendWindowStart",
20835 "applets",
20836 "applicationCache",
20837 "applicationServerKey",
20838 "apply",
20839 "applyConstraints",
20840 "applyElement",
20841 "arc",
20842 "arcTo",
20843 "archive",
20844 "areas",
20845 "arguments",
20846 "ariaAtomic",
20847 "ariaAutoComplete",
20848 "ariaBusy",
20849 "ariaChecked",
20850 "ariaColCount",
20851 "ariaColIndex",
20852 "ariaColSpan",
20853 "ariaCurrent",
20854 "ariaDescription",
20855 "ariaDisabled",
20856 "ariaExpanded",
20857 "ariaHasPopup",
20858 "ariaHidden",
20859 "ariaKeyShortcuts",
20860 "ariaLabel",
20861 "ariaLevel",
20862 "ariaLive",
20863 "ariaModal",
20864 "ariaMultiLine",
20865 "ariaMultiSelectable",
20866 "ariaOrientation",
20867 "ariaPlaceholder",
20868 "ariaPosInSet",
20869 "ariaPressed",
20870 "ariaReadOnly",
20871 "ariaRelevant",
20872 "ariaRequired",
20873 "ariaRoleDescription",
20874 "ariaRowCount",
20875 "ariaRowIndex",
20876 "ariaRowSpan",
20877 "ariaSelected",
20878 "ariaSetSize",
20879 "ariaSort",
20880 "ariaValueMax",
20881 "ariaValueMin",
20882 "ariaValueNow",
20883 "ariaValueText",
20884 "arrayBuffer",
20885 "artist",
20886 "artwork",
20887 "as",
20888 "asIntN",
20889 "asUintN",
20890 "asin",
20891 "asinh",
20892 "assert",
20893 "assign",
20894 "assignedElements",
20895 "assignedNodes",
20896 "assignedSlot",
20897 "async",
20898 "asyncIterator",
20899 "atEnd",
20900 "atan",
20901 "atan2",
20902 "atanh",
20903 "atob",
20904 "attachEvent",
20905 "attachInternals",
20906 "attachShader",
20907 "attachShadow",
20908 "attachments",
20909 "attack",
20910 "attestationObject",
20911 "attrChange",
20912 "attrName",
20913 "attributeFilter",
20914 "attributeName",
20915 "attributeNamespace",
20916 "attributeOldValue",
20917 "attributeStyleMap",
20918 "attributes",
20919 "attribution",
20920 "audioBitsPerSecond",
20921 "audioTracks",
20922 "audioWorklet",
20923 "authenticatedSignedWrites",
20924 "authenticatorData",
20925 "autoIncrement",
20926 "autobuffer",
20927 "autocapitalize",
20928 "autocomplete",
20929 "autocorrect",
20930 "autofocus",
20931 "automationRate",
20932 "autoplay",
20933 "availHeight",
20934 "availLeft",
20935 "availTop",
20936 "availWidth",
20937 "availability",
20938 "available",
20939 "aversion",
20940 "ax",
20941 "axes",
20942 "axis",
20943 "ay",
20944 "azimuth",
20945 "b",
20946 "back",
20947 "backface-visibility",
20948 "backfaceVisibility",
20949 "background",
20950 "background-attachment",
20951 "background-blend-mode",
20952 "background-clip",
20953 "background-color",
20954 "background-image",
20955 "background-origin",
20956 "background-position",
20957 "background-position-x",
20958 "background-position-y",
20959 "background-repeat",
20960 "background-size",
20961 "backgroundAttachment",
20962 "backgroundBlendMode",
20963 "backgroundClip",
20964 "backgroundColor",
20965 "backgroundFetch",
20966 "backgroundImage",
20967 "backgroundOrigin",
20968 "backgroundPosition",
20969 "backgroundPositionX",
20970 "backgroundPositionY",
20971 "backgroundRepeat",
20972 "backgroundSize",
20973 "badInput",
20974 "badge",
20975 "balance",
20976 "baseFrequencyX",
20977 "baseFrequencyY",
20978 "baseLatency",
20979 "baseLayer",
20980 "baseNode",
20981 "baseOffset",
20982 "baseURI",
20983 "baseVal",
20984 "baselineShift",
20985 "battery",
20986 "bday",
20987 "before",
20988 "beginElement",
20989 "beginElementAt",
20990 "beginPath",
20991 "beginQuery",
20992 "beginTransformFeedback",
20993 "behavior",
20994 "behaviorCookie",
20995 "behaviorPart",
20996 "behaviorUrns",
20997 "beta",
20998 "bezierCurveTo",
20999 "bgColor",
21000 "bgProperties",
21001 "bias",
21002 "big",
21003 "bigint64",
21004 "biguint64",
21005 "binaryType",
21006 "bind",
21007 "bindAttribLocation",
21008 "bindBuffer",
21009 "bindBufferBase",
21010 "bindBufferRange",
21011 "bindFramebuffer",
21012 "bindRenderbuffer",
21013 "bindSampler",
21014 "bindTexture",
21015 "bindTransformFeedback",
21016 "bindVertexArray",
21017 "blendColor",
21018 "blendEquation",
21019 "blendEquationSeparate",
21020 "blendFunc",
21021 "blendFuncSeparate",
21022 "blink",
21023 "blitFramebuffer",
21024 "blob",
21025 "block-size",
21026 "blockDirection",
21027 "blockSize",
21028 "blockedURI",
21029 "blue",
21030 "bluetooth",
21031 "blur",
21032 "body",
21033 "bodyUsed",
21034 "bold",
21035 "bookmarks",
21036 "booleanValue",
21037 "border",
21038 "border-block",
21039 "border-block-color",
21040 "border-block-end",
21041 "border-block-end-color",
21042 "border-block-end-style",
21043 "border-block-end-width",
21044 "border-block-start",
21045 "border-block-start-color",
21046 "border-block-start-style",
21047 "border-block-start-width",
21048 "border-block-style",
21049 "border-block-width",
21050 "border-bottom",
21051 "border-bottom-color",
21052 "border-bottom-left-radius",
21053 "border-bottom-right-radius",
21054 "border-bottom-style",
21055 "border-bottom-width",
21056 "border-collapse",
21057 "border-color",
21058 "border-end-end-radius",
21059 "border-end-start-radius",
21060 "border-image",
21061 "border-image-outset",
21062 "border-image-repeat",
21063 "border-image-slice",
21064 "border-image-source",
21065 "border-image-width",
21066 "border-inline",
21067 "border-inline-color",
21068 "border-inline-end",
21069 "border-inline-end-color",
21070 "border-inline-end-style",
21071 "border-inline-end-width",
21072 "border-inline-start",
21073 "border-inline-start-color",
21074 "border-inline-start-style",
21075 "border-inline-start-width",
21076 "border-inline-style",
21077 "border-inline-width",
21078 "border-left",
21079 "border-left-color",
21080 "border-left-style",
21081 "border-left-width",
21082 "border-radius",
21083 "border-right",
21084 "border-right-color",
21085 "border-right-style",
21086 "border-right-width",
21087 "border-spacing",
21088 "border-start-end-radius",
21089 "border-start-start-radius",
21090 "border-style",
21091 "border-top",
21092 "border-top-color",
21093 "border-top-left-radius",
21094 "border-top-right-radius",
21095 "border-top-style",
21096 "border-top-width",
21097 "border-width",
21098 "borderBlock",
21099 "borderBlockColor",
21100 "borderBlockEnd",
21101 "borderBlockEndColor",
21102 "borderBlockEndStyle",
21103 "borderBlockEndWidth",
21104 "borderBlockStart",
21105 "borderBlockStartColor",
21106 "borderBlockStartStyle",
21107 "borderBlockStartWidth",
21108 "borderBlockStyle",
21109 "borderBlockWidth",
21110 "borderBottom",
21111 "borderBottomColor",
21112 "borderBottomLeftRadius",
21113 "borderBottomRightRadius",
21114 "borderBottomStyle",
21115 "borderBottomWidth",
21116 "borderBoxSize",
21117 "borderCollapse",
21118 "borderColor",
21119 "borderColorDark",
21120 "borderColorLight",
21121 "borderEndEndRadius",
21122 "borderEndStartRadius",
21123 "borderImage",
21124 "borderImageOutset",
21125 "borderImageRepeat",
21126 "borderImageSlice",
21127 "borderImageSource",
21128 "borderImageWidth",
21129 "borderInline",
21130 "borderInlineColor",
21131 "borderInlineEnd",
21132 "borderInlineEndColor",
21133 "borderInlineEndStyle",
21134 "borderInlineEndWidth",
21135 "borderInlineStart",
21136 "borderInlineStartColor",
21137 "borderInlineStartStyle",
21138 "borderInlineStartWidth",
21139 "borderInlineStyle",
21140 "borderInlineWidth",
21141 "borderLeft",
21142 "borderLeftColor",
21143 "borderLeftStyle",
21144 "borderLeftWidth",
21145 "borderRadius",
21146 "borderRight",
21147 "borderRightColor",
21148 "borderRightStyle",
21149 "borderRightWidth",
21150 "borderSpacing",
21151 "borderStartEndRadius",
21152 "borderStartStartRadius",
21153 "borderStyle",
21154 "borderTop",
21155 "borderTopColor",
21156 "borderTopLeftRadius",
21157 "borderTopRightRadius",
21158 "borderTopStyle",
21159 "borderTopWidth",
21160 "borderWidth",
21161 "bottom",
21162 "bottomMargin",
21163 "bound",
21164 "boundElements",
21165 "boundingClientRect",
21166 "boundingHeight",
21167 "boundingLeft",
21168 "boundingTop",
21169 "boundingWidth",
21170 "bounds",
21171 "boundsGeometry",
21172 "box-decoration-break",
21173 "box-shadow",
21174 "box-sizing",
21175 "boxDecorationBreak",
21176 "boxShadow",
21177 "boxSizing",
21178 "break-after",
21179 "break-before",
21180 "break-inside",
21181 "breakAfter",
21182 "breakBefore",
21183 "breakInside",
21184 "broadcast",
21185 "browserLanguage",
21186 "btoa",
21187 "bubbles",
21188 "buffer",
21189 "bufferData",
21190 "bufferDepth",
21191 "bufferSize",
21192 "bufferSubData",
21193 "buffered",
21194 "bufferedAmount",
21195 "bufferedAmountLowThreshold",
21196 "buildID",
21197 "buildNumber",
21198 "button",
21199 "buttonID",
21200 "buttons",
21201 "byteLength",
21202 "byteOffset",
21203 "bytesWritten",
21204 "c",
21205 "cache",
21206 "caches",
21207 "call",
21208 "caller",
21209 "canBeFormatted",
21210 "canBeMounted",
21211 "canBeShared",
21212 "canHaveChildren",
21213 "canHaveHTML",
21214 "canInsertDTMF",
21215 "canMakePayment",
21216 "canPlayType",
21217 "canPresent",
21218 "canTrickleIceCandidates",
21219 "cancel",
21220 "cancelAndHoldAtTime",
21221 "cancelAnimationFrame",
21222 "cancelBubble",
21223 "cancelIdleCallback",
21224 "cancelScheduledValues",
21225 "cancelVideoFrameCallback",
21226 "cancelWatchAvailability",
21227 "cancelable",
21228 "candidate",
21229 "canonicalUUID",
21230 "canvas",
21231 "capabilities",
21232 "caption",
21233 "caption-side",
21234 "captionSide",
21235 "capture",
21236 "captureEvents",
21237 "captureStackTrace",
21238 "captureStream",
21239 "caret-color",
21240 "caretBidiLevel",
21241 "caretColor",
21242 "caretPositionFromPoint",
21243 "caretRangeFromPoint",
21244 "cast",
21245 "catch",
21246 "category",
21247 "cbrt",
21248 "cd",
21249 "ceil",
21250 "cellIndex",
21251 "cellPadding",
21252 "cellSpacing",
21253 "cells",
21254 "ch",
21255 "chOff",
21256 "chain",
21257 "challenge",
21258 "changeType",
21259 "changedTouches",
21260 "channel",
21261 "channelCount",
21262 "channelCountMode",
21263 "channelInterpretation",
21264 "char",
21265 "charAt",
21266 "charCode",
21267 "charCodeAt",
21268 "charIndex",
21269 "charLength",
21270 "characterData",
21271 "characterDataOldValue",
21272 "characterSet",
21273 "characteristic",
21274 "charging",
21275 "chargingTime",
21276 "charset",
21277 "check",
21278 "checkEnclosure",
21279 "checkFramebufferStatus",
21280 "checkIntersection",
21281 "checkValidity",
21282 "checked",
21283 "childElementCount",
21284 "childList",
21285 "childNodes",
21286 "children",
21287 "chrome",
21288 "ciphertext",
21289 "cite",
21290 "city",
21291 "claimInterface",
21292 "claimed",
21293 "classList",
21294 "className",
21295 "classid",
21296 "clear",
21297 "clearAppBadge",
21298 "clearAttributes",
21299 "clearBufferfi",
21300 "clearBufferfv",
21301 "clearBufferiv",
21302 "clearBufferuiv",
21303 "clearColor",
21304 "clearData",
21305 "clearDepth",
21306 "clearHalt",
21307 "clearImmediate",
21308 "clearInterval",
21309 "clearLiveSeekableRange",
21310 "clearMarks",
21311 "clearMaxGCPauseAccumulator",
21312 "clearMeasures",
21313 "clearParameters",
21314 "clearRect",
21315 "clearResourceTimings",
21316 "clearShadow",
21317 "clearStencil",
21318 "clearTimeout",
21319 "clearWatch",
21320 "click",
21321 "clickCount",
21322 "clientDataJSON",
21323 "clientHeight",
21324 "clientInformation",
21325 "clientLeft",
21326 "clientRect",
21327 "clientRects",
21328 "clientTop",
21329 "clientWaitSync",
21330 "clientWidth",
21331 "clientX",
21332 "clientY",
21333 "clip",
21334 "clip-path",
21335 "clip-rule",
21336 "clipBottom",
21337 "clipLeft",
21338 "clipPath",
21339 "clipPathUnits",
21340 "clipRight",
21341 "clipRule",
21342 "clipTop",
21343 "clipboard",
21344 "clipboardData",
21345 "clone",
21346 "cloneContents",
21347 "cloneNode",
21348 "cloneRange",
21349 "close",
21350 "closePath",
21351 "closed",
21352 "closest",
21353 "clz",
21354 "clz32",
21355 "cm",
21356 "cmp",
21357 "code",
21358 "codeBase",
21359 "codePointAt",
21360 "codeType",
21361 "colSpan",
21362 "collapse",
21363 "collapseToEnd",
21364 "collapseToStart",
21365 "collapsed",
21366 "collect",
21367 "colno",
21368 "color",
21369 "color-adjust",
21370 "color-interpolation",
21371 "color-interpolation-filters",
21372 "colorAdjust",
21373 "colorDepth",
21374 "colorInterpolation",
21375 "colorInterpolationFilters",
21376 "colorMask",
21377 "colorType",
21378 "cols",
21379 "column-count",
21380 "column-fill",
21381 "column-gap",
21382 "column-rule",
21383 "column-rule-color",
21384 "column-rule-style",
21385 "column-rule-width",
21386 "column-span",
21387 "column-width",
21388 "columnCount",
21389 "columnFill",
21390 "columnGap",
21391 "columnNumber",
21392 "columnRule",
21393 "columnRuleColor",
21394 "columnRuleStyle",
21395 "columnRuleWidth",
21396 "columnSpan",
21397 "columnWidth",
21398 "columns",
21399 "command",
21400 "commit",
21401 "commitPreferences",
21402 "commitStyles",
21403 "commonAncestorContainer",
21404 "compact",
21405 "compareBoundaryPoints",
21406 "compareDocumentPosition",
21407 "compareEndPoints",
21408 "compareExchange",
21409 "compareNode",
21410 "comparePoint",
21411 "compatMode",
21412 "compatible",
21413 "compile",
21414 "compileShader",
21415 "compileStreaming",
21416 "complete",
21417 "component",
21418 "componentFromPoint",
21419 "composed",
21420 "composedPath",
21421 "composite",
21422 "compositionEndOffset",
21423 "compositionStartOffset",
21424 "compressedTexImage2D",
21425 "compressedTexImage3D",
21426 "compressedTexSubImage2D",
21427 "compressedTexSubImage3D",
21428 "computedStyleMap",
21429 "concat",
21430 "conditionText",
21431 "coneInnerAngle",
21432 "coneOuterAngle",
21433 "coneOuterGain",
21434 "configuration",
21435 "configurationName",
21436 "configurationValue",
21437 "configurations",
21438 "confirm",
21439 "confirmComposition",
21440 "confirmSiteSpecificTrackingException",
21441 "confirmWebWideTrackingException",
21442 "connect",
21443 "connectEnd",
21444 "connectShark",
21445 "connectStart",
21446 "connected",
21447 "connection",
21448 "connectionList",
21449 "connectionSpeed",
21450 "connectionState",
21451 "connections",
21452 "console",
21453 "consolidate",
21454 "constraint",
21455 "constrictionActive",
21456 "construct",
21457 "constructor",
21458 "contactID",
21459 "contain",
21460 "containerId",
21461 "containerName",
21462 "containerSrc",
21463 "containerType",
21464 "contains",
21465 "containsNode",
21466 "content",
21467 "contentBoxSize",
21468 "contentDocument",
21469 "contentEditable",
21470 "contentHint",
21471 "contentOverflow",
21472 "contentRect",
21473 "contentScriptType",
21474 "contentStyleType",
21475 "contentType",
21476 "contentWindow",
21477 "context",
21478 "contextMenu",
21479 "contextmenu",
21480 "continue",
21481 "continuePrimaryKey",
21482 "continuous",
21483 "control",
21484 "controlTransferIn",
21485 "controlTransferOut",
21486 "controller",
21487 "controls",
21488 "controlsList",
21489 "convertPointFromNode",
21490 "convertQuadFromNode",
21491 "convertRectFromNode",
21492 "convertToBlob",
21493 "convertToSpecifiedUnits",
21494 "cookie",
21495 "cookieEnabled",
21496 "coords",
21497 "copyBufferSubData",
21498 "copyFromChannel",
21499 "copyTexImage2D",
21500 "copyTexSubImage2D",
21501 "copyTexSubImage3D",
21502 "copyToChannel",
21503 "copyWithin",
21504 "correspondingElement",
21505 "correspondingUseElement",
21506 "corruptedVideoFrames",
21507 "cos",
21508 "cosh",
21509 "count",
21510 "countReset",
21511 "counter-increment",
21512 "counter-reset",
21513 "counter-set",
21514 "counterIncrement",
21515 "counterReset",
21516 "counterSet",
21517 "country",
21518 "cpuClass",
21519 "cpuSleepAllowed",
21520 "create",
21521 "createAnalyser",
21522 "createAnswer",
21523 "createAttribute",
21524 "createAttributeNS",
21525 "createBiquadFilter",
21526 "createBuffer",
21527 "createBufferSource",
21528 "createCDATASection",
21529 "createCSSStyleSheet",
21530 "createCaption",
21531 "createChannelMerger",
21532 "createChannelSplitter",
21533 "createComment",
21534 "createConstantSource",
21535 "createContextualFragment",
21536 "createControlRange",
21537 "createConvolver",
21538 "createDTMFSender",
21539 "createDataChannel",
21540 "createDelay",
21541 "createDelayNode",
21542 "createDocument",
21543 "createDocumentFragment",
21544 "createDocumentType",
21545 "createDynamicsCompressor",
21546 "createElement",
21547 "createElementNS",
21548 "createEntityReference",
21549 "createEvent",
21550 "createEventObject",
21551 "createExpression",
21552 "createFramebuffer",
21553 "createFunction",
21554 "createGain",
21555 "createGainNode",
21556 "createHTML",
21557 "createHTMLDocument",
21558 "createIIRFilter",
21559 "createImageBitmap",
21560 "createImageData",
21561 "createIndex",
21562 "createJavaScriptNode",
21563 "createLinearGradient",
21564 "createMediaElementSource",
21565 "createMediaKeys",
21566 "createMediaStreamDestination",
21567 "createMediaStreamSource",
21568 "createMediaStreamTrackSource",
21569 "createMutableFile",
21570 "createNSResolver",
21571 "createNodeIterator",
21572 "createNotification",
21573 "createObjectStore",
21574 "createObjectURL",
21575 "createOffer",
21576 "createOscillator",
21577 "createPanner",
21578 "createPattern",
21579 "createPeriodicWave",
21580 "createPolicy",
21581 "createPopup",
21582 "createProcessingInstruction",
21583 "createProgram",
21584 "createQuery",
21585 "createRadialGradient",
21586 "createRange",
21587 "createRangeCollection",
21588 "createReader",
21589 "createRenderbuffer",
21590 "createSVGAngle",
21591 "createSVGLength",
21592 "createSVGMatrix",
21593 "createSVGNumber",
21594 "createSVGPathSegArcAbs",
21595 "createSVGPathSegArcRel",
21596 "createSVGPathSegClosePath",
21597 "createSVGPathSegCurvetoCubicAbs",
21598 "createSVGPathSegCurvetoCubicRel",
21599 "createSVGPathSegCurvetoCubicSmoothAbs",
21600 "createSVGPathSegCurvetoCubicSmoothRel",
21601 "createSVGPathSegCurvetoQuadraticAbs",
21602 "createSVGPathSegCurvetoQuadraticRel",
21603 "createSVGPathSegCurvetoQuadraticSmoothAbs",
21604 "createSVGPathSegCurvetoQuadraticSmoothRel",
21605 "createSVGPathSegLinetoAbs",
21606 "createSVGPathSegLinetoHorizontalAbs",
21607 "createSVGPathSegLinetoHorizontalRel",
21608 "createSVGPathSegLinetoRel",
21609 "createSVGPathSegLinetoVerticalAbs",
21610 "createSVGPathSegLinetoVerticalRel",
21611 "createSVGPathSegMovetoAbs",
21612 "createSVGPathSegMovetoRel",
21613 "createSVGPoint",
21614 "createSVGRect",
21615 "createSVGTransform",
21616 "createSVGTransformFromMatrix",
21617 "createSampler",
21618 "createScript",
21619 "createScriptProcessor",
21620 "createScriptURL",
21621 "createSession",
21622 "createShader",
21623 "createShadowRoot",
21624 "createStereoPanner",
21625 "createStyleSheet",
21626 "createTBody",
21627 "createTFoot",
21628 "createTHead",
21629 "createTextNode",
21630 "createTextRange",
21631 "createTexture",
21632 "createTouch",
21633 "createTouchList",
21634 "createTransformFeedback",
21635 "createTreeWalker",
21636 "createVertexArray",
21637 "createWaveShaper",
21638 "creationTime",
21639 "credentials",
21640 "crossOrigin",
21641 "crossOriginIsolated",
21642 "crypto",
21643 "csi",
21644 "csp",
21645 "cssFloat",
21646 "cssRules",
21647 "cssText",
21648 "cssValueType",
21649 "ctrlKey",
21650 "ctrlLeft",
21651 "cues",
21652 "cullFace",
21653 "currentDirection",
21654 "currentLocalDescription",
21655 "currentNode",
21656 "currentPage",
21657 "currentRect",
21658 "currentRemoteDescription",
21659 "currentScale",
21660 "currentScript",
21661 "currentSrc",
21662 "currentState",
21663 "currentStyle",
21664 "currentTarget",
21665 "currentTime",
21666 "currentTranslate",
21667 "currentView",
21668 "cursor",
21669 "curve",
21670 "customElements",
21671 "customError",
21672 "cx",
21673 "cy",
21674 "d",
21675 "data",
21676 "dataFld",
21677 "dataFormatAs",
21678 "dataLoss",
21679 "dataLossMessage",
21680 "dataPageSize",
21681 "dataSrc",
21682 "dataTransfer",
21683 "database",
21684 "databases",
21685 "dataset",
21686 "dateTime",
21687 "db",
21688 "debug",
21689 "debuggerEnabled",
21690 "declare",
21691 "decode",
21692 "decodeAudioData",
21693 "decodeURI",
21694 "decodeURIComponent",
21695 "decodedBodySize",
21696 "decoding",
21697 "decodingInfo",
21698 "decrypt",
21699 "default",
21700 "defaultCharset",
21701 "defaultChecked",
21702 "defaultMuted",
21703 "defaultPlaybackRate",
21704 "defaultPolicy",
21705 "defaultPrevented",
21706 "defaultRequest",
21707 "defaultSelected",
21708 "defaultStatus",
21709 "defaultURL",
21710 "defaultValue",
21711 "defaultView",
21712 "defaultstatus",
21713 "defer",
21714 "define",
21715 "defineMagicFunction",
21716 "defineMagicVariable",
21717 "defineProperties",
21718 "defineProperty",
21719 "deg",
21720 "delay",
21721 "delayTime",
21722 "delegatesFocus",
21723 "delete",
21724 "deleteBuffer",
21725 "deleteCaption",
21726 "deleteCell",
21727 "deleteContents",
21728 "deleteData",
21729 "deleteDatabase",
21730 "deleteFramebuffer",
21731 "deleteFromDocument",
21732 "deleteIndex",
21733 "deleteMedium",
21734 "deleteObjectStore",
21735 "deleteProgram",
21736 "deleteProperty",
21737 "deleteQuery",
21738 "deleteRenderbuffer",
21739 "deleteRow",
21740 "deleteRule",
21741 "deleteSampler",
21742 "deleteShader",
21743 "deleteSync",
21744 "deleteTFoot",
21745 "deleteTHead",
21746 "deleteTexture",
21747 "deleteTransformFeedback",
21748 "deleteVertexArray",
21749 "deliverChangeRecords",
21750 "delivery",
21751 "deliveryInfo",
21752 "deliveryStatus",
21753 "deliveryTimestamp",
21754 "delta",
21755 "deltaMode",
21756 "deltaX",
21757 "deltaY",
21758 "deltaZ",
21759 "dependentLocality",
21760 "depthFar",
21761 "depthFunc",
21762 "depthMask",
21763 "depthNear",
21764 "depthRange",
21765 "deref",
21766 "deriveBits",
21767 "deriveKey",
21768 "description",
21769 "deselectAll",
21770 "designMode",
21771 "desiredSize",
21772 "destination",
21773 "destinationURL",
21774 "detach",
21775 "detachEvent",
21776 "detachShader",
21777 "detail",
21778 "details",
21779 "detect",
21780 "detune",
21781 "device",
21782 "deviceClass",
21783 "deviceId",
21784 "deviceMemory",
21785 "devicePixelContentBoxSize",
21786 "devicePixelRatio",
21787 "deviceProtocol",
21788 "deviceSubclass",
21789 "deviceVersionMajor",
21790 "deviceVersionMinor",
21791 "deviceVersionSubminor",
21792 "deviceXDPI",
21793 "deviceYDPI",
21794 "didTimeout",
21795 "diffuseConstant",
21796 "digest",
21797 "dimensions",
21798 "dir",
21799 "dirName",
21800 "direction",
21801 "dirxml",
21802 "disable",
21803 "disablePictureInPicture",
21804 "disableRemotePlayback",
21805 "disableVertexAttribArray",
21806 "disabled",
21807 "dischargingTime",
21808 "disconnect",
21809 "disconnectShark",
21810 "dispatchEvent",
21811 "display",
21812 "displayId",
21813 "displayName",
21814 "disposition",
21815 "distanceModel",
21816 "div",
21817 "divisor",
21818 "djsapi",
21819 "djsproxy",
21820 "doImport",
21821 "doNotTrack",
21822 "doScroll",
21823 "doctype",
21824 "document",
21825 "documentElement",
21826 "documentMode",
21827 "documentURI",
21828 "dolphin",
21829 "dolphinGameCenter",
21830 "dolphininfo",
21831 "dolphinmeta",
21832 "domComplete",
21833 "domContentLoadedEventEnd",
21834 "domContentLoadedEventStart",
21835 "domInteractive",
21836 "domLoading",
21837 "domOverlayState",
21838 "domain",
21839 "domainLookupEnd",
21840 "domainLookupStart",
21841 "dominant-baseline",
21842 "dominantBaseline",
21843 "done",
21844 "dopplerFactor",
21845 "dotAll",
21846 "downDegrees",
21847 "downlink",
21848 "download",
21849 "downloadTotal",
21850 "downloaded",
21851 "dpcm",
21852 "dpi",
21853 "dppx",
21854 "dragDrop",
21855 "draggable",
21856 "drawArrays",
21857 "drawArraysInstanced",
21858 "drawArraysInstancedANGLE",
21859 "drawBuffers",
21860 "drawCustomFocusRing",
21861 "drawElements",
21862 "drawElementsInstanced",
21863 "drawElementsInstancedANGLE",
21864 "drawFocusIfNeeded",
21865 "drawImage",
21866 "drawImageFromRect",
21867 "drawRangeElements",
21868 "drawSystemFocusRing",
21869 "drawingBufferHeight",
21870 "drawingBufferWidth",
21871 "dropEffect",
21872 "droppedVideoFrames",
21873 "dropzone",
21874 "dtmf",
21875 "dump",
21876 "dumpProfile",
21877 "duplicate",
21878 "durability",
21879 "duration",
21880 "dvname",
21881 "dvnum",
21882 "dx",
21883 "dy",
21884 "dynsrc",
21885 "e",
21886 "edgeMode",
21887 "effect",
21888 "effectAllowed",
21889 "effectiveDirective",
21890 "effectiveType",
21891 "elapsedTime",
21892 "element",
21893 "elementFromPoint",
21894 "elementTiming",
21895 "elements",
21896 "elementsFromPoint",
21897 "elevation",
21898 "ellipse",
21899 "em",
21900 "email",
21901 "embeds",
21902 "emma",
21903 "empty",
21904 "empty-cells",
21905 "emptyCells",
21906 "emptyHTML",
21907 "emptyScript",
21908 "emulatedPosition",
21909 "enable",
21910 "enableBackground",
21911 "enableDelegations",
21912 "enableStyleSheetsForSet",
21913 "enableVertexAttribArray",
21914 "enabled",
21915 "enabledPlugin",
21916 "encode",
21917 "encodeInto",
21918 "encodeURI",
21919 "encodeURIComponent",
21920 "encodedBodySize",
21921 "encoding",
21922 "encodingInfo",
21923 "encrypt",
21924 "enctype",
21925 "end",
21926 "endContainer",
21927 "endElement",
21928 "endElementAt",
21929 "endOfStream",
21930 "endOffset",
21931 "endQuery",
21932 "endTime",
21933 "endTransformFeedback",
21934 "ended",
21935 "endpoint",
21936 "endpointNumber",
21937 "endpoints",
21938 "endsWith",
21939 "enterKeyHint",
21940 "entities",
21941 "entries",
21942 "entryType",
21943 "enumerate",
21944 "enumerateDevices",
21945 "enumerateEditable",
21946 "environmentBlendMode",
21947 "equals",
21948 "error",
21949 "errorCode",
21950 "errorDetail",
21951 "errorText",
21952 "escape",
21953 "estimate",
21954 "eval",
21955 "evaluate",
21956 "event",
21957 "eventPhase",
21958 "every",
21959 "ex",
21960 "exception",
21961 "exchange",
21962 "exec",
21963 "execCommand",
21964 "execCommandShowHelp",
21965 "execScript",
21966 "exitFullscreen",
21967 "exitPictureInPicture",
21968 "exitPointerLock",
21969 "exitPresent",
21970 "exp",
21971 "expand",
21972 "expandEntityReferences",
21973 "expando",
21974 "expansion",
21975 "expiration",
21976 "expirationTime",
21977 "expires",
21978 "expiryDate",
21979 "explicitOriginalTarget",
21980 "expm1",
21981 "exponent",
21982 "exponentialRampToValueAtTime",
21983 "exportKey",
21984 "extend",
21985 "extensions",
21986 "extentNode",
21987 "extentOffset",
21988 "external",
21989 "externalResourcesRequired",
21990 "extractContents",
21991 "extractable",
21992 "eye",
21993 "f",
21994 "face",
21995 "factoryReset",
21996 "failureReason",
21997 "fallback",
21998 "family",
21999 "familyName",
22000 "farthestViewportElement",
22001 "fastSeek",
22002 "fatal",
22003 "featureId",
22004 "featurePolicy",
22005 "featureSettings",
22006 "features",
22007 "fenceSync",
22008 "fetch",
22009 "fetchStart",
22010 "fftSize",
22011 "fgColor",
22012 "fieldOfView",
22013 "file",
22014 "fileCreatedDate",
22015 "fileHandle",
22016 "fileModifiedDate",
22017 "fileName",
22018 "fileSize",
22019 "fileUpdatedDate",
22020 "filename",
22021 "files",
22022 "filesystem",
22023 "fill",
22024 "fill-opacity",
22025 "fill-rule",
22026 "fillLightMode",
22027 "fillOpacity",
22028 "fillRect",
22029 "fillRule",
22030 "fillStyle",
22031 "fillText",
22032 "filter",
22033 "filterResX",
22034 "filterResY",
22035 "filterUnits",
22036 "filters",
22037 "finally",
22038 "find",
22039 "findIndex",
22040 "findRule",
22041 "findText",
22042 "finish",
22043 "finished",
22044 "fireEvent",
22045 "firesTouchEvents",
22046 "firstChild",
22047 "firstElementChild",
22048 "firstPage",
22049 "fixed",
22050 "flags",
22051 "flat",
22052 "flatMap",
22053 "flex",
22054 "flex-basis",
22055 "flex-direction",
22056 "flex-flow",
22057 "flex-grow",
22058 "flex-shrink",
22059 "flex-wrap",
22060 "flexBasis",
22061 "flexDirection",
22062 "flexFlow",
22063 "flexGrow",
22064 "flexShrink",
22065 "flexWrap",
22066 "flipX",
22067 "flipY",
22068 "float",
22069 "float32",
22070 "float64",
22071 "flood-color",
22072 "flood-opacity",
22073 "floodColor",
22074 "floodOpacity",
22075 "floor",
22076 "flush",
22077 "focus",
22078 "focusNode",
22079 "focusOffset",
22080 "font",
22081 "font-family",
22082 "font-feature-settings",
22083 "font-kerning",
22084 "font-language-override",
22085 "font-optical-sizing",
22086 "font-size",
22087 "font-size-adjust",
22088 "font-stretch",
22089 "font-style",
22090 "font-synthesis",
22091 "font-variant",
22092 "font-variant-alternates",
22093 "font-variant-caps",
22094 "font-variant-east-asian",
22095 "font-variant-ligatures",
22096 "font-variant-numeric",
22097 "font-variant-position",
22098 "font-variation-settings",
22099 "font-weight",
22100 "fontFamily",
22101 "fontFeatureSettings",
22102 "fontKerning",
22103 "fontLanguageOverride",
22104 "fontOpticalSizing",
22105 "fontSize",
22106 "fontSizeAdjust",
22107 "fontSmoothingEnabled",
22108 "fontStretch",
22109 "fontStyle",
22110 "fontSynthesis",
22111 "fontVariant",
22112 "fontVariantAlternates",
22113 "fontVariantCaps",
22114 "fontVariantEastAsian",
22115 "fontVariantLigatures",
22116 "fontVariantNumeric",
22117 "fontVariantPosition",
22118 "fontVariationSettings",
22119 "fontWeight",
22120 "fontcolor",
22121 "fontfaces",
22122 "fonts",
22123 "fontsize",
22124 "for",
22125 "forEach",
22126 "force",
22127 "forceRedraw",
22128 "form",
22129 "formAction",
22130 "formData",
22131 "formEnctype",
22132 "formMethod",
22133 "formNoValidate",
22134 "formTarget",
22135 "format",
22136 "formatToParts",
22137 "forms",
22138 "forward",
22139 "forwardX",
22140 "forwardY",
22141 "forwardZ",
22142 "foundation",
22143 "fr",
22144 "fragmentDirective",
22145 "frame",
22146 "frameBorder",
22147 "frameElement",
22148 "frameSpacing",
22149 "framebuffer",
22150 "framebufferHeight",
22151 "framebufferRenderbuffer",
22152 "framebufferTexture2D",
22153 "framebufferTextureLayer",
22154 "framebufferWidth",
22155 "frames",
22156 "freeSpace",
22157 "freeze",
22158 "frequency",
22159 "frequencyBinCount",
22160 "from",
22161 "fromCharCode",
22162 "fromCodePoint",
22163 "fromElement",
22164 "fromEntries",
22165 "fromFloat32Array",
22166 "fromFloat64Array",
22167 "fromMatrix",
22168 "fromPoint",
22169 "fromQuad",
22170 "fromRect",
22171 "frontFace",
22172 "fround",
22173 "fullPath",
22174 "fullScreen",
22175 "fullscreen",
22176 "fullscreenElement",
22177 "fullscreenEnabled",
22178 "fx",
22179 "fy",
22180 "gain",
22181 "gamepad",
22182 "gamma",
22183 "gap",
22184 "gatheringState",
22185 "gatt",
22186 "genderIdentity",
22187 "generateCertificate",
22188 "generateKey",
22189 "generateMipmap",
22190 "generateRequest",
22191 "geolocation",
22192 "gestureObject",
22193 "get",
22194 "getActiveAttrib",
22195 "getActiveUniform",
22196 "getActiveUniformBlockName",
22197 "getActiveUniformBlockParameter",
22198 "getActiveUniforms",
22199 "getAdjacentText",
22200 "getAll",
22201 "getAllKeys",
22202 "getAllResponseHeaders",
22203 "getAllowlistForFeature",
22204 "getAnimations",
22205 "getAsFile",
22206 "getAsString",
22207 "getAttachedShaders",
22208 "getAttribLocation",
22209 "getAttribute",
22210 "getAttributeNS",
22211 "getAttributeNames",
22212 "getAttributeNode",
22213 "getAttributeNodeNS",
22214 "getAttributeType",
22215 "getAudioTracks",
22216 "getAvailability",
22217 "getBBox",
22218 "getBattery",
22219 "getBigInt64",
22220 "getBigUint64",
22221 "getBlob",
22222 "getBookmark",
22223 "getBoundingClientRect",
22224 "getBounds",
22225 "getBoxQuads",
22226 "getBufferParameter",
22227 "getBufferSubData",
22228 "getByteFrequencyData",
22229 "getByteTimeDomainData",
22230 "getCSSCanvasContext",
22231 "getCTM",
22232 "getCandidateWindowClientRect",
22233 "getCanonicalLocales",
22234 "getCapabilities",
22235 "getChannelData",
22236 "getCharNumAtPosition",
22237 "getCharacteristic",
22238 "getCharacteristics",
22239 "getClientExtensionResults",
22240 "getClientRect",
22241 "getClientRects",
22242 "getCoalescedEvents",
22243 "getCompositionAlternatives",
22244 "getComputedStyle",
22245 "getComputedTextLength",
22246 "getComputedTiming",
22247 "getConfiguration",
22248 "getConstraints",
22249 "getContext",
22250 "getContextAttributes",
22251 "getContributingSources",
22252 "getCounterValue",
22253 "getCueAsHTML",
22254 "getCueById",
22255 "getCurrentPosition",
22256 "getCurrentTime",
22257 "getData",
22258 "getDatabaseNames",
22259 "getDate",
22260 "getDay",
22261 "getDefaultComputedStyle",
22262 "getDescriptor",
22263 "getDescriptors",
22264 "getDestinationInsertionPoints",
22265 "getDevices",
22266 "getDirectory",
22267 "getDisplayMedia",
22268 "getDistributedNodes",
22269 "getEditable",
22270 "getElementById",
22271 "getElementsByClassName",
22272 "getElementsByName",
22273 "getElementsByTagName",
22274 "getElementsByTagNameNS",
22275 "getEnclosureList",
22276 "getEndPositionOfChar",
22277 "getEntries",
22278 "getEntriesByName",
22279 "getEntriesByType",
22280 "getError",
22281 "getExtension",
22282 "getExtentOfChar",
22283 "getEyeParameters",
22284 "getFeature",
22285 "getFile",
22286 "getFiles",
22287 "getFilesAndDirectories",
22288 "getFingerprints",
22289 "getFloat32",
22290 "getFloat64",
22291 "getFloatFrequencyData",
22292 "getFloatTimeDomainData",
22293 "getFloatValue",
22294 "getFragDataLocation",
22295 "getFrameData",
22296 "getFramebufferAttachmentParameter",
22297 "getFrequencyResponse",
22298 "getFullYear",
22299 "getGamepads",
22300 "getHitTestResults",
22301 "getHitTestResultsForTransientInput",
22302 "getHours",
22303 "getIdentityAssertion",
22304 "getIds",
22305 "getImageData",
22306 "getIndexedParameter",
22307 "getInstalledRelatedApps",
22308 "getInt16",
22309 "getInt32",
22310 "getInt8",
22311 "getInternalformatParameter",
22312 "getIntersectionList",
22313 "getItem",
22314 "getItems",
22315 "getKey",
22316 "getKeyframes",
22317 "getLayers",
22318 "getLayoutMap",
22319 "getLineDash",
22320 "getLocalCandidates",
22321 "getLocalParameters",
22322 "getLocalStreams",
22323 "getMarks",
22324 "getMatchedCSSRules",
22325 "getMaxGCPauseSinceClear",
22326 "getMeasures",
22327 "getMetadata",
22328 "getMilliseconds",
22329 "getMinutes",
22330 "getModifierState",
22331 "getMonth",
22332 "getNamedItem",
22333 "getNamedItemNS",
22334 "getNativeFramebufferScaleFactor",
22335 "getNotifications",
22336 "getNotifier",
22337 "getNumberOfChars",
22338 "getOffsetReferenceSpace",
22339 "getOutputTimestamp",
22340 "getOverrideHistoryNavigationMode",
22341 "getOverrideStyle",
22342 "getOwnPropertyDescriptor",
22343 "getOwnPropertyDescriptors",
22344 "getOwnPropertyNames",
22345 "getOwnPropertySymbols",
22346 "getParameter",
22347 "getParameters",
22348 "getParent",
22349 "getPathSegAtLength",
22350 "getPhotoCapabilities",
22351 "getPhotoSettings",
22352 "getPointAtLength",
22353 "getPose",
22354 "getPredictedEvents",
22355 "getPreference",
22356 "getPreferenceDefault",
22357 "getPresentationAttribute",
22358 "getPreventDefault",
22359 "getPrimaryService",
22360 "getPrimaryServices",
22361 "getProgramInfoLog",
22362 "getProgramParameter",
22363 "getPropertyCSSValue",
22364 "getPropertyPriority",
22365 "getPropertyShorthand",
22366 "getPropertyType",
22367 "getPropertyValue",
22368 "getPrototypeOf",
22369 "getQuery",
22370 "getQueryParameter",
22371 "getRGBColorValue",
22372 "getRandomValues",
22373 "getRangeAt",
22374 "getReader",
22375 "getReceivers",
22376 "getRectValue",
22377 "getRegistration",
22378 "getRegistrations",
22379 "getRemoteCandidates",
22380 "getRemoteCertificates",
22381 "getRemoteParameters",
22382 "getRemoteStreams",
22383 "getRenderbufferParameter",
22384 "getResponseHeader",
22385 "getRoot",
22386 "getRootNode",
22387 "getRotationOfChar",
22388 "getSVGDocument",
22389 "getSamplerParameter",
22390 "getScreenCTM",
22391 "getSeconds",
22392 "getSelectedCandidatePair",
22393 "getSelection",
22394 "getSenders",
22395 "getService",
22396 "getSettings",
22397 "getShaderInfoLog",
22398 "getShaderParameter",
22399 "getShaderPrecisionFormat",
22400 "getShaderSource",
22401 "getSimpleDuration",
22402 "getSiteIcons",
22403 "getSources",
22404 "getSpeculativeParserUrls",
22405 "getStartPositionOfChar",
22406 "getStartTime",
22407 "getState",
22408 "getStats",
22409 "getStatusForPolicy",
22410 "getStorageUpdates",
22411 "getStreamById",
22412 "getStringValue",
22413 "getSubStringLength",
22414 "getSubscription",
22415 "getSupportedConstraints",
22416 "getSupportedExtensions",
22417 "getSupportedFormats",
22418 "getSyncParameter",
22419 "getSynchronizationSources",
22420 "getTags",
22421 "getTargetRanges",
22422 "getTexParameter",
22423 "getTime",
22424 "getTimezoneOffset",
22425 "getTiming",
22426 "getTotalLength",
22427 "getTrackById",
22428 "getTracks",
22429 "getTransceivers",
22430 "getTransform",
22431 "getTransformFeedbackVarying",
22432 "getTransformToElement",
22433 "getTransports",
22434 "getType",
22435 "getTypeMapping",
22436 "getUTCDate",
22437 "getUTCDay",
22438 "getUTCFullYear",
22439 "getUTCHours",
22440 "getUTCMilliseconds",
22441 "getUTCMinutes",
22442 "getUTCMonth",
22443 "getUTCSeconds",
22444 "getUint16",
22445 "getUint32",
22446 "getUint8",
22447 "getUniform",
22448 "getUniformBlockIndex",
22449 "getUniformIndices",
22450 "getUniformLocation",
22451 "getUserMedia",
22452 "getVRDisplays",
22453 "getValues",
22454 "getVarDate",
22455 "getVariableValue",
22456 "getVertexAttrib",
22457 "getVertexAttribOffset",
22458 "getVideoPlaybackQuality",
22459 "getVideoTracks",
22460 "getViewerPose",
22461 "getViewport",
22462 "getVoices",
22463 "getWakeLockState",
22464 "getWriter",
22465 "getYear",
22466 "givenName",
22467 "global",
22468 "globalAlpha",
22469 "globalCompositeOperation",
22470 "globalThis",
22471 "glyphOrientationHorizontal",
22472 "glyphOrientationVertical",
22473 "glyphRef",
22474 "go",
22475 "grabFrame",
22476 "grad",
22477 "gradientTransform",
22478 "gradientUnits",
22479 "grammars",
22480 "green",
22481 "grid",
22482 "grid-area",
22483 "grid-auto-columns",
22484 "grid-auto-flow",
22485 "grid-auto-rows",
22486 "grid-column",
22487 "grid-column-end",
22488 "grid-column-gap",
22489 "grid-column-start",
22490 "grid-gap",
22491 "grid-row",
22492 "grid-row-end",
22493 "grid-row-gap",
22494 "grid-row-start",
22495 "grid-template",
22496 "grid-template-areas",
22497 "grid-template-columns",
22498 "grid-template-rows",
22499 "gridArea",
22500 "gridAutoColumns",
22501 "gridAutoFlow",
22502 "gridAutoRows",
22503 "gridColumn",
22504 "gridColumnEnd",
22505 "gridColumnGap",
22506 "gridColumnStart",
22507 "gridGap",
22508 "gridRow",
22509 "gridRowEnd",
22510 "gridRowGap",
22511 "gridRowStart",
22512 "gridTemplate",
22513 "gridTemplateAreas",
22514 "gridTemplateColumns",
22515 "gridTemplateRows",
22516 "gripSpace",
22517 "group",
22518 "groupCollapsed",
22519 "groupEnd",
22520 "groupId",
22521 "hadRecentInput",
22522 "hand",
22523 "handedness",
22524 "hapticActuators",
22525 "hardwareConcurrency",
22526 "has",
22527 "hasAttribute",
22528 "hasAttributeNS",
22529 "hasAttributes",
22530 "hasBeenActive",
22531 "hasChildNodes",
22532 "hasComposition",
22533 "hasEnrolledInstrument",
22534 "hasExtension",
22535 "hasExternalDisplay",
22536 "hasFeature",
22537 "hasFocus",
22538 "hasInstance",
22539 "hasLayout",
22540 "hasOrientation",
22541 "hasOwnProperty",
22542 "hasPointerCapture",
22543 "hasPosition",
22544 "hasReading",
22545 "hasStorageAccess",
22546 "hash",
22547 "head",
22548 "headers",
22549 "heading",
22550 "height",
22551 "hidden",
22552 "hide",
22553 "hideFocus",
22554 "high",
22555 "highWaterMark",
22556 "hint",
22557 "history",
22558 "honorificPrefix",
22559 "honorificSuffix",
22560 "horizontalOverflow",
22561 "host",
22562 "hostCandidate",
22563 "hostname",
22564 "href",
22565 "hrefTranslate",
22566 "hreflang",
22567 "hspace",
22568 "html5TagCheckInerface",
22569 "htmlFor",
22570 "htmlText",
22571 "httpEquiv",
22572 "httpRequestStatusCode",
22573 "hwTimestamp",
22574 "hyphens",
22575 "hypot",
22576 "iccId",
22577 "iceConnectionState",
22578 "iceGatheringState",
22579 "iceTransport",
22580 "icon",
22581 "iconURL",
22582 "id",
22583 "identifier",
22584 "identity",
22585 "idpLoginUrl",
22586 "ignoreBOM",
22587 "ignoreCase",
22588 "ignoreDepthValues",
22589 "image-orientation",
22590 "image-rendering",
22591 "imageHeight",
22592 "imageOrientation",
22593 "imageRendering",
22594 "imageSizes",
22595 "imageSmoothingEnabled",
22596 "imageSmoothingQuality",
22597 "imageSrcset",
22598 "imageWidth",
22599 "images",
22600 "ime-mode",
22601 "imeMode",
22602 "implementation",
22603 "importKey",
22604 "importNode",
22605 "importStylesheet",
22606 "imports",
22607 "impp",
22608 "imul",
22609 "in",
22610 "in1",
22611 "in2",
22612 "inBandMetadataTrackDispatchType",
22613 "inRange",
22614 "includes",
22615 "incremental",
22616 "indeterminate",
22617 "index",
22618 "indexNames",
22619 "indexOf",
22620 "indexedDB",
22621 "indicate",
22622 "inertiaDestinationX",
22623 "inertiaDestinationY",
22624 "info",
22625 "init",
22626 "initAnimationEvent",
22627 "initBeforeLoadEvent",
22628 "initClipboardEvent",
22629 "initCloseEvent",
22630 "initCommandEvent",
22631 "initCompositionEvent",
22632 "initCustomEvent",
22633 "initData",
22634 "initDataType",
22635 "initDeviceMotionEvent",
22636 "initDeviceOrientationEvent",
22637 "initDragEvent",
22638 "initErrorEvent",
22639 "initEvent",
22640 "initFocusEvent",
22641 "initGestureEvent",
22642 "initHashChangeEvent",
22643 "initKeyEvent",
22644 "initKeyboardEvent",
22645 "initMSManipulationEvent",
22646 "initMessageEvent",
22647 "initMouseEvent",
22648 "initMouseScrollEvent",
22649 "initMouseWheelEvent",
22650 "initMutationEvent",
22651 "initNSMouseEvent",
22652 "initOverflowEvent",
22653 "initPageEvent",
22654 "initPageTransitionEvent",
22655 "initPointerEvent",
22656 "initPopStateEvent",
22657 "initProgressEvent",
22658 "initScrollAreaEvent",
22659 "initSimpleGestureEvent",
22660 "initStorageEvent",
22661 "initTextEvent",
22662 "initTimeEvent",
22663 "initTouchEvent",
22664 "initTransitionEvent",
22665 "initUIEvent",
22666 "initWebKitAnimationEvent",
22667 "initWebKitTransitionEvent",
22668 "initWebKitWheelEvent",
22669 "initWheelEvent",
22670 "initialTime",
22671 "initialize",
22672 "initiatorType",
22673 "inline-size",
22674 "inlineSize",
22675 "inlineVerticalFieldOfView",
22676 "inner",
22677 "innerHTML",
22678 "innerHeight",
22679 "innerText",
22680 "innerWidth",
22681 "input",
22682 "inputBuffer",
22683 "inputEncoding",
22684 "inputMethod",
22685 "inputMode",
22686 "inputSource",
22687 "inputSources",
22688 "inputType",
22689 "inputs",
22690 "insertAdjacentElement",
22691 "insertAdjacentHTML",
22692 "insertAdjacentText",
22693 "insertBefore",
22694 "insertCell",
22695 "insertDTMF",
22696 "insertData",
22697 "insertItemBefore",
22698 "insertNode",
22699 "insertRow",
22700 "insertRule",
22701 "inset",
22702 "inset-block",
22703 "inset-block-end",
22704 "inset-block-start",
22705 "inset-inline",
22706 "inset-inline-end",
22707 "inset-inline-start",
22708 "insetBlock",
22709 "insetBlockEnd",
22710 "insetBlockStart",
22711 "insetInline",
22712 "insetInlineEnd",
22713 "insetInlineStart",
22714 "installing",
22715 "instanceRoot",
22716 "instantiate",
22717 "instantiateStreaming",
22718 "instruments",
22719 "int16",
22720 "int32",
22721 "int8",
22722 "integrity",
22723 "interactionMode",
22724 "intercept",
22725 "interfaceClass",
22726 "interfaceName",
22727 "interfaceNumber",
22728 "interfaceProtocol",
22729 "interfaceSubclass",
22730 "interfaces",
22731 "interimResults",
22732 "internalSubset",
22733 "interpretation",
22734 "intersectionRatio",
22735 "intersectionRect",
22736 "intersectsNode",
22737 "interval",
22738 "invalidIteratorState",
22739 "invalidateFramebuffer",
22740 "invalidateSubFramebuffer",
22741 "inverse",
22742 "invertSelf",
22743 "is",
22744 "is2D",
22745 "isActive",
22746 "isAlternate",
22747 "isArray",
22748 "isBingCurrentSearchDefault",
22749 "isBuffer",
22750 "isCandidateWindowVisible",
22751 "isChar",
22752 "isCollapsed",
22753 "isComposing",
22754 "isConcatSpreadable",
22755 "isConnected",
22756 "isContentEditable",
22757 "isContentHandlerRegistered",
22758 "isContextLost",
22759 "isDefaultNamespace",
22760 "isDirectory",
22761 "isDisabled",
22762 "isEnabled",
22763 "isEqual",
22764 "isEqualNode",
22765 "isExtensible",
22766 "isExternalCTAP2SecurityKeySupported",
22767 "isFile",
22768 "isFinite",
22769 "isFramebuffer",
22770 "isFrozen",
22771 "isGenerator",
22772 "isHTML",
22773 "isHistoryNavigation",
22774 "isId",
22775 "isIdentity",
22776 "isInjected",
22777 "isInteger",
22778 "isIntersecting",
22779 "isLockFree",
22780 "isMap",
22781 "isMultiLine",
22782 "isNaN",
22783 "isOpen",
22784 "isPointInFill",
22785 "isPointInPath",
22786 "isPointInRange",
22787 "isPointInStroke",
22788 "isPrefAlternate",
22789 "isPresenting",
22790 "isPrimary",
22791 "isProgram",
22792 "isPropertyImplicit",
22793 "isProtocolHandlerRegistered",
22794 "isPrototypeOf",
22795 "isQuery",
22796 "isRenderbuffer",
22797 "isSafeInteger",
22798 "isSameNode",
22799 "isSampler",
22800 "isScript",
22801 "isScriptURL",
22802 "isSealed",
22803 "isSecureContext",
22804 "isSessionSupported",
22805 "isShader",
22806 "isSupported",
22807 "isSync",
22808 "isTextEdit",
22809 "isTexture",
22810 "isTransformFeedback",
22811 "isTrusted",
22812 "isTypeSupported",
22813 "isUserVerifyingPlatformAuthenticatorAvailable",
22814 "isVertexArray",
22815 "isView",
22816 "isVisible",
22817 "isochronousTransferIn",
22818 "isochronousTransferOut",
22819 "isolation",
22820 "italics",
22821 "item",
22822 "itemId",
22823 "itemProp",
22824 "itemRef",
22825 "itemScope",
22826 "itemType",
22827 "itemValue",
22828 "items",
22829 "iterateNext",
22830 "iterationComposite",
22831 "iterator",
22832 "javaEnabled",
22833 "jobTitle",
22834 "join",
22835 "json",
22836 "justify-content",
22837 "justify-items",
22838 "justify-self",
22839 "justifyContent",
22840 "justifyItems",
22841 "justifySelf",
22842 "k1",
22843 "k2",
22844 "k3",
22845 "k4",
22846 "kHz",
22847 "keepalive",
22848 "kernelMatrix",
22849 "kernelUnitLengthX",
22850 "kernelUnitLengthY",
22851 "kerning",
22852 "key",
22853 "keyCode",
22854 "keyFor",
22855 "keyIdentifier",
22856 "keyLightEnabled",
22857 "keyLocation",
22858 "keyPath",
22859 "keyStatuses",
22860 "keySystem",
22861 "keyText",
22862 "keyUsage",
22863 "keyboard",
22864 "keys",
22865 "keytype",
22866 "kind",
22867 "knee",
22868 "label",
22869 "labels",
22870 "lang",
22871 "language",
22872 "languages",
22873 "largeArcFlag",
22874 "lastChild",
22875 "lastElementChild",
22876 "lastEventId",
22877 "lastIndex",
22878 "lastIndexOf",
22879 "lastInputTime",
22880 "lastMatch",
22881 "lastMessageSubject",
22882 "lastMessageType",
22883 "lastModified",
22884 "lastModifiedDate",
22885 "lastPage",
22886 "lastParen",
22887 "lastState",
22888 "lastStyleSheetSet",
22889 "latitude",
22890 "layerX",
22891 "layerY",
22892 "layoutFlow",
22893 "layoutGrid",
22894 "layoutGridChar",
22895 "layoutGridLine",
22896 "layoutGridMode",
22897 "layoutGridType",
22898 "lbound",
22899 "left",
22900 "leftContext",
22901 "leftDegrees",
22902 "leftMargin",
22903 "leftProjectionMatrix",
22904 "leftViewMatrix",
22905 "length",
22906 "lengthAdjust",
22907 "lengthComputable",
22908 "letter-spacing",
22909 "letterSpacing",
22910 "level",
22911 "lighting-color",
22912 "lightingColor",
22913 "limitingConeAngle",
22914 "line",
22915 "line-break",
22916 "line-height",
22917 "lineAlign",
22918 "lineBreak",
22919 "lineCap",
22920 "lineDashOffset",
22921 "lineHeight",
22922 "lineJoin",
22923 "lineNumber",
22924 "lineTo",
22925 "lineWidth",
22926 "linearAcceleration",
22927 "linearRampToValueAtTime",
22928 "linearVelocity",
22929 "lineno",
22930 "lines",
22931 "link",
22932 "linkColor",
22933 "linkProgram",
22934 "links",
22935 "list",
22936 "list-style",
22937 "list-style-image",
22938 "list-style-position",
22939 "list-style-type",
22940 "listStyle",
22941 "listStyleImage",
22942 "listStylePosition",
22943 "listStyleType",
22944 "listener",
22945 "load",
22946 "loadEventEnd",
22947 "loadEventStart",
22948 "loadTime",
22949 "loadTimes",
22950 "loaded",
22951 "loading",
22952 "localDescription",
22953 "localName",
22954 "localService",
22955 "localStorage",
22956 "locale",
22957 "localeCompare",
22958 "location",
22959 "locationbar",
22960 "lock",
22961 "locked",
22962 "lockedFile",
22963 "locks",
22964 "log",
22965 "log10",
22966 "log1p",
22967 "log2",
22968 "logicalXDPI",
22969 "logicalYDPI",
22970 "longDesc",
22971 "longitude",
22972 "lookupNamespaceURI",
22973 "lookupPrefix",
22974 "loop",
22975 "loopEnd",
22976 "loopStart",
22977 "looping",
22978 "low",
22979 "lower",
22980 "lowerBound",
22981 "lowerOpen",
22982 "lowsrc",
22983 "m11",
22984 "m12",
22985 "m13",
22986 "m14",
22987 "m21",
22988 "m22",
22989 "m23",
22990 "m24",
22991 "m31",
22992 "m32",
22993 "m33",
22994 "m34",
22995 "m41",
22996 "m42",
22997 "m43",
22998 "m44",
22999 "makeXRCompatible",
23000 "manifest",
23001 "manufacturer",
23002 "manufacturerName",
23003 "map",
23004 "mapping",
23005 "margin",
23006 "margin-block",
23007 "margin-block-end",
23008 "margin-block-start",
23009 "margin-bottom",
23010 "margin-inline",
23011 "margin-inline-end",
23012 "margin-inline-start",
23013 "margin-left",
23014 "margin-right",
23015 "margin-top",
23016 "marginBlock",
23017 "marginBlockEnd",
23018 "marginBlockStart",
23019 "marginBottom",
23020 "marginHeight",
23021 "marginInline",
23022 "marginInlineEnd",
23023 "marginInlineStart",
23024 "marginLeft",
23025 "marginRight",
23026 "marginTop",
23027 "marginWidth",
23028 "mark",
23029 "marker",
23030 "marker-end",
23031 "marker-mid",
23032 "marker-offset",
23033 "marker-start",
23034 "markerEnd",
23035 "markerHeight",
23036 "markerMid",
23037 "markerOffset",
23038 "markerStart",
23039 "markerUnits",
23040 "markerWidth",
23041 "marks",
23042 "mask",
23043 "mask-clip",
23044 "mask-composite",
23045 "mask-image",
23046 "mask-mode",
23047 "mask-origin",
23048 "mask-position",
23049 "mask-position-x",
23050 "mask-position-y",
23051 "mask-repeat",
23052 "mask-size",
23053 "mask-type",
23054 "maskClip",
23055 "maskComposite",
23056 "maskContentUnits",
23057 "maskImage",
23058 "maskMode",
23059 "maskOrigin",
23060 "maskPosition",
23061 "maskPositionX",
23062 "maskPositionY",
23063 "maskRepeat",
23064 "maskSize",
23065 "maskType",
23066 "maskUnits",
23067 "match",
23068 "matchAll",
23069 "matchMedia",
23070 "matchMedium",
23071 "matches",
23072 "matrix",
23073 "matrixTransform",
23074 "max",
23075 "max-block-size",
23076 "max-height",
23077 "max-inline-size",
23078 "max-width",
23079 "maxActions",
23080 "maxAlternatives",
23081 "maxBlockSize",
23082 "maxChannelCount",
23083 "maxChannels",
23084 "maxConnectionsPerServer",
23085 "maxDecibels",
23086 "maxDistance",
23087 "maxHeight",
23088 "maxInlineSize",
23089 "maxLayers",
23090 "maxLength",
23091 "maxMessageSize",
23092 "maxPacketLifeTime",
23093 "maxRetransmits",
23094 "maxTouchPoints",
23095 "maxValue",
23096 "maxWidth",
23097 "measure",
23098 "measureText",
23099 "media",
23100 "mediaCapabilities",
23101 "mediaDevices",
23102 "mediaElement",
23103 "mediaGroup",
23104 "mediaKeys",
23105 "mediaSession",
23106 "mediaStream",
23107 "mediaText",
23108 "meetOrSlice",
23109 "memory",
23110 "menubar",
23111 "mergeAttributes",
23112 "message",
23113 "messageClass",
23114 "messageHandlers",
23115 "messageType",
23116 "metaKey",
23117 "metadata",
23118 "method",
23119 "methodDetails",
23120 "methodName",
23121 "mid",
23122 "mimeType",
23123 "mimeTypes",
23124 "min",
23125 "min-block-size",
23126 "min-height",
23127 "min-inline-size",
23128 "min-width",
23129 "minBlockSize",
23130 "minDecibels",
23131 "minHeight",
23132 "minInlineSize",
23133 "minLength",
23134 "minValue",
23135 "minWidth",
23136 "miterLimit",
23137 "mix-blend-mode",
23138 "mixBlendMode",
23139 "mm",
23140 "mode",
23141 "modify",
23142 "mount",
23143 "move",
23144 "moveBy",
23145 "moveEnd",
23146 "moveFirst",
23147 "moveFocusDown",
23148 "moveFocusLeft",
23149 "moveFocusRight",
23150 "moveFocusUp",
23151 "moveNext",
23152 "moveRow",
23153 "moveStart",
23154 "moveTo",
23155 "moveToBookmark",
23156 "moveToElementText",
23157 "moveToPoint",
23158 "movementX",
23159 "movementY",
23160 "mozAdd",
23161 "mozAnimationStartTime",
23162 "mozAnon",
23163 "mozApps",
23164 "mozAudioCaptured",
23165 "mozAudioChannelType",
23166 "mozAutoplayEnabled",
23167 "mozCancelAnimationFrame",
23168 "mozCancelFullScreen",
23169 "mozCancelRequestAnimationFrame",
23170 "mozCaptureStream",
23171 "mozCaptureStreamUntilEnded",
23172 "mozClearDataAt",
23173 "mozContact",
23174 "mozContacts",
23175 "mozCreateFileHandle",
23176 "mozCurrentTransform",
23177 "mozCurrentTransformInverse",
23178 "mozCursor",
23179 "mozDash",
23180 "mozDashOffset",
23181 "mozDecodedFrames",
23182 "mozExitPointerLock",
23183 "mozFillRule",
23184 "mozFragmentEnd",
23185 "mozFrameDelay",
23186 "mozFullScreen",
23187 "mozFullScreenElement",
23188 "mozFullScreenEnabled",
23189 "mozGetAll",
23190 "mozGetAllKeys",
23191 "mozGetAsFile",
23192 "mozGetDataAt",
23193 "mozGetMetadata",
23194 "mozGetUserMedia",
23195 "mozHasAudio",
23196 "mozHasItem",
23197 "mozHidden",
23198 "mozImageSmoothingEnabled",
23199 "mozIndexedDB",
23200 "mozInnerScreenX",
23201 "mozInnerScreenY",
23202 "mozInputSource",
23203 "mozIsTextField",
23204 "mozItem",
23205 "mozItemCount",
23206 "mozItems",
23207 "mozLength",
23208 "mozLockOrientation",
23209 "mozMatchesSelector",
23210 "mozMovementX",
23211 "mozMovementY",
23212 "mozOpaque",
23213 "mozOrientation",
23214 "mozPaintCount",
23215 "mozPaintedFrames",
23216 "mozParsedFrames",
23217 "mozPay",
23218 "mozPointerLockElement",
23219 "mozPresentedFrames",
23220 "mozPreservesPitch",
23221 "mozPressure",
23222 "mozPrintCallback",
23223 "mozRTCIceCandidate",
23224 "mozRTCPeerConnection",
23225 "mozRTCSessionDescription",
23226 "mozRemove",
23227 "mozRequestAnimationFrame",
23228 "mozRequestFullScreen",
23229 "mozRequestPointerLock",
23230 "mozSetDataAt",
23231 "mozSetImageElement",
23232 "mozSourceNode",
23233 "mozSrcObject",
23234 "mozSystem",
23235 "mozTCPSocket",
23236 "mozTextStyle",
23237 "mozTypesAt",
23238 "mozUnlockOrientation",
23239 "mozUserCancelled",
23240 "mozVisibilityState",
23241 "ms",
23242 "msAnimation",
23243 "msAnimationDelay",
23244 "msAnimationDirection",
23245 "msAnimationDuration",
23246 "msAnimationFillMode",
23247 "msAnimationIterationCount",
23248 "msAnimationName",
23249 "msAnimationPlayState",
23250 "msAnimationStartTime",
23251 "msAnimationTimingFunction",
23252 "msBackfaceVisibility",
23253 "msBlockProgression",
23254 "msCSSOMElementFloatMetrics",
23255 "msCaching",
23256 "msCachingEnabled",
23257 "msCancelRequestAnimationFrame",
23258 "msCapsLockWarningOff",
23259 "msClearImmediate",
23260 "msClose",
23261 "msContentZoomChaining",
23262 "msContentZoomFactor",
23263 "msContentZoomLimit",
23264 "msContentZoomLimitMax",
23265 "msContentZoomLimitMin",
23266 "msContentZoomSnap",
23267 "msContentZoomSnapPoints",
23268 "msContentZoomSnapType",
23269 "msContentZooming",
23270 "msConvertURL",
23271 "msCrypto",
23272 "msDoNotTrack",
23273 "msElementsFromPoint",
23274 "msElementsFromRect",
23275 "msExitFullscreen",
23276 "msExtendedCode",
23277 "msFillRule",
23278 "msFirstPaint",
23279 "msFlex",
23280 "msFlexAlign",
23281 "msFlexDirection",
23282 "msFlexFlow",
23283 "msFlexItemAlign",
23284 "msFlexLinePack",
23285 "msFlexNegative",
23286 "msFlexOrder",
23287 "msFlexPack",
23288 "msFlexPositive",
23289 "msFlexPreferredSize",
23290 "msFlexWrap",
23291 "msFlowFrom",
23292 "msFlowInto",
23293 "msFontFeatureSettings",
23294 "msFullscreenElement",
23295 "msFullscreenEnabled",
23296 "msGetInputContext",
23297 "msGetRegionContent",
23298 "msGetUntransformedBounds",
23299 "msGraphicsTrustStatus",
23300 "msGridColumn",
23301 "msGridColumnAlign",
23302 "msGridColumnSpan",
23303 "msGridColumns",
23304 "msGridRow",
23305 "msGridRowAlign",
23306 "msGridRowSpan",
23307 "msGridRows",
23308 "msHidden",
23309 "msHighContrastAdjust",
23310 "msHyphenateLimitChars",
23311 "msHyphenateLimitLines",
23312 "msHyphenateLimitZone",
23313 "msHyphens",
23314 "msImageSmoothingEnabled",
23315 "msImeAlign",
23316 "msIndexedDB",
23317 "msInterpolationMode",
23318 "msIsStaticHTML",
23319 "msKeySystem",
23320 "msKeys",
23321 "msLaunchUri",
23322 "msLockOrientation",
23323 "msManipulationViewsEnabled",
23324 "msMatchMedia",
23325 "msMatchesSelector",
23326 "msMaxTouchPoints",
23327 "msOrientation",
23328 "msOverflowStyle",
23329 "msPerspective",
23330 "msPerspectiveOrigin",
23331 "msPlayToDisabled",
23332 "msPlayToPreferredSourceUri",
23333 "msPlayToPrimary",
23334 "msPointerEnabled",
23335 "msRegionOverflow",
23336 "msReleasePointerCapture",
23337 "msRequestAnimationFrame",
23338 "msRequestFullscreen",
23339 "msSaveBlob",
23340 "msSaveOrOpenBlob",
23341 "msScrollChaining",
23342 "msScrollLimit",
23343 "msScrollLimitXMax",
23344 "msScrollLimitXMin",
23345 "msScrollLimitYMax",
23346 "msScrollLimitYMin",
23347 "msScrollRails",
23348 "msScrollSnapPointsX",
23349 "msScrollSnapPointsY",
23350 "msScrollSnapType",
23351 "msScrollSnapX",
23352 "msScrollSnapY",
23353 "msScrollTranslation",
23354 "msSetImmediate",
23355 "msSetMediaKeys",
23356 "msSetPointerCapture",
23357 "msTextCombineHorizontal",
23358 "msTextSizeAdjust",
23359 "msToBlob",
23360 "msTouchAction",
23361 "msTouchSelect",
23362 "msTraceAsyncCallbackCompleted",
23363 "msTraceAsyncCallbackStarting",
23364 "msTraceAsyncOperationCompleted",
23365 "msTraceAsyncOperationStarting",
23366 "msTransform",
23367 "msTransformOrigin",
23368 "msTransformStyle",
23369 "msTransition",
23370 "msTransitionDelay",
23371 "msTransitionDuration",
23372 "msTransitionProperty",
23373 "msTransitionTimingFunction",
23374 "msUnlockOrientation",
23375 "msUpdateAsyncCallbackRelation",
23376 "msUserSelect",
23377 "msVisibilityState",
23378 "msWrapFlow",
23379 "msWrapMargin",
23380 "msWrapThrough",
23381 "msWriteProfilerMark",
23382 "msZoom",
23383 "msZoomTo",
23384 "mt",
23385 "mul",
23386 "multiEntry",
23387 "multiSelectionObj",
23388 "multiline",
23389 "multiple",
23390 "multiply",
23391 "multiplySelf",
23392 "mutableFile",
23393 "muted",
23394 "n",
23395 "name",
23396 "nameProp",
23397 "namedItem",
23398 "namedRecordset",
23399 "names",
23400 "namespaceURI",
23401 "namespaces",
23402 "naturalHeight",
23403 "naturalWidth",
23404 "navigate",
23405 "navigation",
23406 "navigationMode",
23407 "navigationPreload",
23408 "navigationStart",
23409 "navigator",
23410 "near",
23411 "nearestViewportElement",
23412 "negative",
23413 "negotiated",
23414 "netscape",
23415 "networkState",
23416 "newScale",
23417 "newTranslate",
23418 "newURL",
23419 "newValue",
23420 "newValueSpecifiedUnits",
23421 "newVersion",
23422 "newhome",
23423 "next",
23424 "nextElementSibling",
23425 "nextHopProtocol",
23426 "nextNode",
23427 "nextPage",
23428 "nextSibling",
23429 "nickname",
23430 "noHref",
23431 "noModule",
23432 "noResize",
23433 "noShade",
23434 "noValidate",
23435 "noWrap",
23436 "node",
23437 "nodeName",
23438 "nodeType",
23439 "nodeValue",
23440 "nonce",
23441 "normalize",
23442 "normalizedPathSegList",
23443 "notationName",
23444 "notations",
23445 "note",
23446 "noteGrainOn",
23447 "noteOff",
23448 "noteOn",
23449 "notify",
23450 "now",
23451 "numOctaves",
23452 "number",
23453 "numberOfChannels",
23454 "numberOfInputs",
23455 "numberOfItems",
23456 "numberOfOutputs",
23457 "numberValue",
23458 "oMatchesSelector",
23459 "object",
23460 "object-fit",
23461 "object-position",
23462 "objectFit",
23463 "objectPosition",
23464 "objectStore",
23465 "objectStoreNames",
23466 "objectType",
23467 "observe",
23468 "of",
23469 "offscreenBuffering",
23470 "offset",
23471 "offset-anchor",
23472 "offset-distance",
23473 "offset-path",
23474 "offset-rotate",
23475 "offsetAnchor",
23476 "offsetDistance",
23477 "offsetHeight",
23478 "offsetLeft",
23479 "offsetNode",
23480 "offsetParent",
23481 "offsetPath",
23482 "offsetRotate",
23483 "offsetTop",
23484 "offsetWidth",
23485 "offsetX",
23486 "offsetY",
23487 "ok",
23488 "oldURL",
23489 "oldValue",
23490 "oldVersion",
23491 "olderShadowRoot",
23492 "onLine",
23493 "onabort",
23494 "onabsolutedeviceorientation",
23495 "onactivate",
23496 "onactive",
23497 "onaddsourcebuffer",
23498 "onaddstream",
23499 "onaddtrack",
23500 "onafterprint",
23501 "onafterscriptexecute",
23502 "onafterupdate",
23503 "onanimationcancel",
23504 "onanimationend",
23505 "onanimationiteration",
23506 "onanimationstart",
23507 "onappinstalled",
23508 "onaudioend",
23509 "onaudioprocess",
23510 "onaudiostart",
23511 "onautocomplete",
23512 "onautocompleteerror",
23513 "onauxclick",
23514 "onbeforeactivate",
23515 "onbeforecopy",
23516 "onbeforecut",
23517 "onbeforedeactivate",
23518 "onbeforeeditfocus",
23519 "onbeforeinstallprompt",
23520 "onbeforepaste",
23521 "onbeforeprint",
23522 "onbeforescriptexecute",
23523 "onbeforeunload",
23524 "onbeforeupdate",
23525 "onbeforexrselect",
23526 "onbegin",
23527 "onblocked",
23528 "onblur",
23529 "onbounce",
23530 "onboundary",
23531 "onbufferedamountlow",
23532 "oncached",
23533 "oncancel",
23534 "oncandidatewindowhide",
23535 "oncandidatewindowshow",
23536 "oncandidatewindowupdate",
23537 "oncanplay",
23538 "oncanplaythrough",
23539 "once",
23540 "oncellchange",
23541 "onchange",
23542 "oncharacteristicvaluechanged",
23543 "onchargingchange",
23544 "onchargingtimechange",
23545 "onchecking",
23546 "onclick",
23547 "onclose",
23548 "onclosing",
23549 "oncompassneedscalibration",
23550 "oncomplete",
23551 "onconnect",
23552 "onconnecting",
23553 "onconnectionavailable",
23554 "onconnectionstatechange",
23555 "oncontextmenu",
23556 "oncontrollerchange",
23557 "oncontrolselect",
23558 "oncopy",
23559 "oncuechange",
23560 "oncut",
23561 "ondataavailable",
23562 "ondatachannel",
23563 "ondatasetchanged",
23564 "ondatasetcomplete",
23565 "ondblclick",
23566 "ondeactivate",
23567 "ondevicechange",
23568 "ondevicelight",
23569 "ondevicemotion",
23570 "ondeviceorientation",
23571 "ondeviceorientationabsolute",
23572 "ondeviceproximity",
23573 "ondischargingtimechange",
23574 "ondisconnect",
23575 "ondisplay",
23576 "ondownloading",
23577 "ondrag",
23578 "ondragend",
23579 "ondragenter",
23580 "ondragexit",
23581 "ondragleave",
23582 "ondragover",
23583 "ondragstart",
23584 "ondrop",
23585 "ondurationchange",
23586 "onemptied",
23587 "onencrypted",
23588 "onend",
23589 "onended",
23590 "onenter",
23591 "onenterpictureinpicture",
23592 "onerror",
23593 "onerrorupdate",
23594 "onexit",
23595 "onfilterchange",
23596 "onfinish",
23597 "onfocus",
23598 "onfocusin",
23599 "onfocusout",
23600 "onformdata",
23601 "onfreeze",
23602 "onfullscreenchange",
23603 "onfullscreenerror",
23604 "ongatheringstatechange",
23605 "ongattserverdisconnected",
23606 "ongesturechange",
23607 "ongestureend",
23608 "ongesturestart",
23609 "ongotpointercapture",
23610 "onhashchange",
23611 "onhelp",
23612 "onicecandidate",
23613 "onicecandidateerror",
23614 "oniceconnectionstatechange",
23615 "onicegatheringstatechange",
23616 "oninactive",
23617 "oninput",
23618 "oninputsourceschange",
23619 "oninvalid",
23620 "onkeydown",
23621 "onkeypress",
23622 "onkeystatuseschange",
23623 "onkeyup",
23624 "onlanguagechange",
23625 "onlayoutcomplete",
23626 "onleavepictureinpicture",
23627 "onlevelchange",
23628 "onload",
23629 "onloadeddata",
23630 "onloadedmetadata",
23631 "onloadend",
23632 "onloading",
23633 "onloadingdone",
23634 "onloadingerror",
23635 "onloadstart",
23636 "onlosecapture",
23637 "onlostpointercapture",
23638 "only",
23639 "onmark",
23640 "onmessage",
23641 "onmessageerror",
23642 "onmidimessage",
23643 "onmousedown",
23644 "onmouseenter",
23645 "onmouseleave",
23646 "onmousemove",
23647 "onmouseout",
23648 "onmouseover",
23649 "onmouseup",
23650 "onmousewheel",
23651 "onmove",
23652 "onmoveend",
23653 "onmovestart",
23654 "onmozfullscreenchange",
23655 "onmozfullscreenerror",
23656 "onmozorientationchange",
23657 "onmozpointerlockchange",
23658 "onmozpointerlockerror",
23659 "onmscontentzoom",
23660 "onmsfullscreenchange",
23661 "onmsfullscreenerror",
23662 "onmsgesturechange",
23663 "onmsgesturedoubletap",
23664 "onmsgestureend",
23665 "onmsgesturehold",
23666 "onmsgesturestart",
23667 "onmsgesturetap",
23668 "onmsgotpointercapture",
23669 "onmsinertiastart",
23670 "onmslostpointercapture",
23671 "onmsmanipulationstatechanged",
23672 "onmsneedkey",
23673 "onmsorientationchange",
23674 "onmspointercancel",
23675 "onmspointerdown",
23676 "onmspointerenter",
23677 "onmspointerhover",
23678 "onmspointerleave",
23679 "onmspointermove",
23680 "onmspointerout",
23681 "onmspointerover",
23682 "onmspointerup",
23683 "onmssitemodejumplistitemremoved",
23684 "onmsthumbnailclick",
23685 "onmute",
23686 "onnegotiationneeded",
23687 "onnomatch",
23688 "onnoupdate",
23689 "onobsolete",
23690 "onoffline",
23691 "ononline",
23692 "onopen",
23693 "onorientationchange",
23694 "onpagechange",
23695 "onpagehide",
23696 "onpageshow",
23697 "onpaste",
23698 "onpause",
23699 "onpayerdetailchange",
23700 "onpaymentmethodchange",
23701 "onplay",
23702 "onplaying",
23703 "onpluginstreamstart",
23704 "onpointercancel",
23705 "onpointerdown",
23706 "onpointerenter",
23707 "onpointerleave",
23708 "onpointerlockchange",
23709 "onpointerlockerror",
23710 "onpointermove",
23711 "onpointerout",
23712 "onpointerover",
23713 "onpointerrawupdate",
23714 "onpointerup",
23715 "onpopstate",
23716 "onprocessorerror",
23717 "onprogress",
23718 "onpropertychange",
23719 "onratechange",
23720 "onreading",
23721 "onreadystatechange",
23722 "onrejectionhandled",
23723 "onrelease",
23724 "onremove",
23725 "onremovesourcebuffer",
23726 "onremovestream",
23727 "onremovetrack",
23728 "onrepeat",
23729 "onreset",
23730 "onresize",
23731 "onresizeend",
23732 "onresizestart",
23733 "onresourcetimingbufferfull",
23734 "onresult",
23735 "onresume",
23736 "onrowenter",
23737 "onrowexit",
23738 "onrowsdelete",
23739 "onrowsinserted",
23740 "onscroll",
23741 "onsearch",
23742 "onsecuritypolicyviolation",
23743 "onseeked",
23744 "onseeking",
23745 "onselect",
23746 "onselectedcandidatepairchange",
23747 "onselectend",
23748 "onselectionchange",
23749 "onselectstart",
23750 "onshippingaddresschange",
23751 "onshippingoptionchange",
23752 "onshow",
23753 "onsignalingstatechange",
23754 "onsoundend",
23755 "onsoundstart",
23756 "onsourceclose",
23757 "onsourceclosed",
23758 "onsourceended",
23759 "onsourceopen",
23760 "onspeechend",
23761 "onspeechstart",
23762 "onsqueeze",
23763 "onsqueezeend",
23764 "onsqueezestart",
23765 "onstalled",
23766 "onstart",
23767 "onstatechange",
23768 "onstop",
23769 "onstorage",
23770 "onstoragecommit",
23771 "onsubmit",
23772 "onsuccess",
23773 "onsuspend",
23774 "onterminate",
23775 "ontextinput",
23776 "ontimeout",
23777 "ontimeupdate",
23778 "ontoggle",
23779 "ontonechange",
23780 "ontouchcancel",
23781 "ontouchend",
23782 "ontouchmove",
23783 "ontouchstart",
23784 "ontrack",
23785 "ontransitioncancel",
23786 "ontransitionend",
23787 "ontransitionrun",
23788 "ontransitionstart",
23789 "onunhandledrejection",
23790 "onunload",
23791 "onunmute",
23792 "onupdate",
23793 "onupdateend",
23794 "onupdatefound",
23795 "onupdateready",
23796 "onupdatestart",
23797 "onupgradeneeded",
23798 "onuserproximity",
23799 "onversionchange",
23800 "onvisibilitychange",
23801 "onvoiceschanged",
23802 "onvolumechange",
23803 "onvrdisplayactivate",
23804 "onvrdisplayconnect",
23805 "onvrdisplaydeactivate",
23806 "onvrdisplaydisconnect",
23807 "onvrdisplaypresentchange",
23808 "onwaiting",
23809 "onwaitingforkey",
23810 "onwarning",
23811 "onwebkitanimationend",
23812 "onwebkitanimationiteration",
23813 "onwebkitanimationstart",
23814 "onwebkitcurrentplaybacktargetiswirelesschanged",
23815 "onwebkitfullscreenchange",
23816 "onwebkitfullscreenerror",
23817 "onwebkitkeyadded",
23818 "onwebkitkeyerror",
23819 "onwebkitkeymessage",
23820 "onwebkitneedkey",
23821 "onwebkitorientationchange",
23822 "onwebkitplaybacktargetavailabilitychanged",
23823 "onwebkitpointerlockchange",
23824 "onwebkitpointerlockerror",
23825 "onwebkitresourcetimingbufferfull",
23826 "onwebkittransitionend",
23827 "onwheel",
23828 "onzoom",
23829 "opacity",
23830 "open",
23831 "openCursor",
23832 "openDatabase",
23833 "openKeyCursor",
23834 "opened",
23835 "opener",
23836 "opera",
23837 "operationType",
23838 "operator",
23839 "opr",
23840 "optimum",
23841 "options",
23842 "or",
23843 "order",
23844 "orderX",
23845 "orderY",
23846 "ordered",
23847 "org",
23848 "organization",
23849 "orient",
23850 "orientAngle",
23851 "orientType",
23852 "orientation",
23853 "orientationX",
23854 "orientationY",
23855 "orientationZ",
23856 "origin",
23857 "originalPolicy",
23858 "originalTarget",
23859 "orphans",
23860 "oscpu",
23861 "outerHTML",
23862 "outerHeight",
23863 "outerText",
23864 "outerWidth",
23865 "outline",
23866 "outline-color",
23867 "outline-offset",
23868 "outline-style",
23869 "outline-width",
23870 "outlineColor",
23871 "outlineOffset",
23872 "outlineStyle",
23873 "outlineWidth",
23874 "outputBuffer",
23875 "outputLatency",
23876 "outputs",
23877 "overflow",
23878 "overflow-anchor",
23879 "overflow-block",
23880 "overflow-inline",
23881 "overflow-wrap",
23882 "overflow-x",
23883 "overflow-y",
23884 "overflowAnchor",
23885 "overflowBlock",
23886 "overflowInline",
23887 "overflowWrap",
23888 "overflowX",
23889 "overflowY",
23890 "overrideMimeType",
23891 "oversample",
23892 "overscroll-behavior",
23893 "overscroll-behavior-block",
23894 "overscroll-behavior-inline",
23895 "overscroll-behavior-x",
23896 "overscroll-behavior-y",
23897 "overscrollBehavior",
23898 "overscrollBehaviorBlock",
23899 "overscrollBehaviorInline",
23900 "overscrollBehaviorX",
23901 "overscrollBehaviorY",
23902 "ownKeys",
23903 "ownerDocument",
23904 "ownerElement",
23905 "ownerNode",
23906 "ownerRule",
23907 "ownerSVGElement",
23908 "owningElement",
23909 "p1",
23910 "p2",
23911 "p3",
23912 "p4",
23913 "packetSize",
23914 "packets",
23915 "pad",
23916 "padEnd",
23917 "padStart",
23918 "padding",
23919 "padding-block",
23920 "padding-block-end",
23921 "padding-block-start",
23922 "padding-bottom",
23923 "padding-inline",
23924 "padding-inline-end",
23925 "padding-inline-start",
23926 "padding-left",
23927 "padding-right",
23928 "padding-top",
23929 "paddingBlock",
23930 "paddingBlockEnd",
23931 "paddingBlockStart",
23932 "paddingBottom",
23933 "paddingInline",
23934 "paddingInlineEnd",
23935 "paddingInlineStart",
23936 "paddingLeft",
23937 "paddingRight",
23938 "paddingTop",
23939 "page",
23940 "page-break-after",
23941 "page-break-before",
23942 "page-break-inside",
23943 "pageBreakAfter",
23944 "pageBreakBefore",
23945 "pageBreakInside",
23946 "pageCount",
23947 "pageLeft",
23948 "pageTop",
23949 "pageX",
23950 "pageXOffset",
23951 "pageY",
23952 "pageYOffset",
23953 "pages",
23954 "paint-order",
23955 "paintOrder",
23956 "paintRequests",
23957 "paintType",
23958 "paintWorklet",
23959 "palette",
23960 "pan",
23961 "panningModel",
23962 "parameters",
23963 "parent",
23964 "parentElement",
23965 "parentNode",
23966 "parentRule",
23967 "parentStyleSheet",
23968 "parentTextEdit",
23969 "parentWindow",
23970 "parse",
23971 "parseAll",
23972 "parseFloat",
23973 "parseFromString",
23974 "parseInt",
23975 "part",
23976 "participants",
23977 "passive",
23978 "password",
23979 "pasteHTML",
23980 "path",
23981 "pathLength",
23982 "pathSegList",
23983 "pathSegType",
23984 "pathSegTypeAsLetter",
23985 "pathname",
23986 "pattern",
23987 "patternContentUnits",
23988 "patternMismatch",
23989 "patternTransform",
23990 "patternUnits",
23991 "pause",
23992 "pauseAnimations",
23993 "pauseOnExit",
23994 "pauseProfilers",
23995 "pauseTransformFeedback",
23996 "paused",
23997 "payerEmail",
23998 "payerName",
23999 "payerPhone",
24000 "paymentManager",
24001 "pc",
24002 "peerIdentity",
24003 "pending",
24004 "pendingLocalDescription",
24005 "pendingRemoteDescription",
24006 "percent",
24007 "performance",
24008 "periodicSync",
24009 "permission",
24010 "permissionState",
24011 "permissions",
24012 "persist",
24013 "persisted",
24014 "personalbar",
24015 "perspective",
24016 "perspective-origin",
24017 "perspectiveOrigin",
24018 "phone",
24019 "phoneticFamilyName",
24020 "phoneticGivenName",
24021 "photo",
24022 "pictureInPictureElement",
24023 "pictureInPictureEnabled",
24024 "pictureInPictureWindow",
24025 "ping",
24026 "pipeThrough",
24027 "pipeTo",
24028 "pitch",
24029 "pixelBottom",
24030 "pixelDepth",
24031 "pixelHeight",
24032 "pixelLeft",
24033 "pixelRight",
24034 "pixelStorei",
24035 "pixelTop",
24036 "pixelUnitToMillimeterX",
24037 "pixelUnitToMillimeterY",
24038 "pixelWidth",
24039 "place-content",
24040 "place-items",
24041 "place-self",
24042 "placeContent",
24043 "placeItems",
24044 "placeSelf",
24045 "placeholder",
24046 "platform",
24047 "platforms",
24048 "play",
24049 "playEffect",
24050 "playState",
24051 "playbackRate",
24052 "playbackState",
24053 "playbackTime",
24054 "played",
24055 "playoutDelayHint",
24056 "playsInline",
24057 "plugins",
24058 "pluginspage",
24059 "pname",
24060 "pointer-events",
24061 "pointerBeforeReferenceNode",
24062 "pointerEnabled",
24063 "pointerEvents",
24064 "pointerId",
24065 "pointerLockElement",
24066 "pointerType",
24067 "points",
24068 "pointsAtX",
24069 "pointsAtY",
24070 "pointsAtZ",
24071 "polygonOffset",
24072 "pop",
24073 "populateMatrix",
24074 "popupWindowFeatures",
24075 "popupWindowName",
24076 "popupWindowURI",
24077 "port",
24078 "port1",
24079 "port2",
24080 "ports",
24081 "posBottom",
24082 "posHeight",
24083 "posLeft",
24084 "posRight",
24085 "posTop",
24086 "posWidth",
24087 "pose",
24088 "position",
24089 "positionAlign",
24090 "positionX",
24091 "positionY",
24092 "positionZ",
24093 "postError",
24094 "postMessage",
24095 "postalCode",
24096 "poster",
24097 "pow",
24098 "powerEfficient",
24099 "powerOff",
24100 "preMultiplySelf",
24101 "precision",
24102 "preferredStyleSheetSet",
24103 "preferredStylesheetSet",
24104 "prefix",
24105 "preload",
24106 "prepend",
24107 "presentation",
24108 "preserveAlpha",
24109 "preserveAspectRatio",
24110 "preserveAspectRatioString",
24111 "pressed",
24112 "pressure",
24113 "prevValue",
24114 "preventDefault",
24115 "preventExtensions",
24116 "preventSilentAccess",
24117 "previousElementSibling",
24118 "previousNode",
24119 "previousPage",
24120 "previousRect",
24121 "previousScale",
24122 "previousSibling",
24123 "previousTranslate",
24124 "primaryKey",
24125 "primitiveType",
24126 "primitiveUnits",
24127 "principals",
24128 "print",
24129 "priority",
24130 "privateKey",
24131 "probablySupportsContext",
24132 "process",
24133 "processIceMessage",
24134 "processingEnd",
24135 "processingStart",
24136 "product",
24137 "productId",
24138 "productName",
24139 "productSub",
24140 "profile",
24141 "profileEnd",
24142 "profiles",
24143 "projectionMatrix",
24144 "promise",
24145 "prompt",
24146 "properties",
24147 "propertyIsEnumerable",
24148 "propertyName",
24149 "protocol",
24150 "protocolLong",
24151 "prototype",
24152 "provider",
24153 "pseudoClass",
24154 "pseudoElement",
24155 "pt",
24156 "publicId",
24157 "publicKey",
24158 "published",
24159 "pulse",
24160 "push",
24161 "pushManager",
24162 "pushNotification",
24163 "pushState",
24164 "put",
24165 "putImageData",
24166 "px",
24167 "quadraticCurveTo",
24168 "qualifier",
24169 "quaternion",
24170 "query",
24171 "queryCommandEnabled",
24172 "queryCommandIndeterm",
24173 "queryCommandState",
24174 "queryCommandSupported",
24175 "queryCommandText",
24176 "queryCommandValue",
24177 "querySelector",
24178 "querySelectorAll",
24179 "queueMicrotask",
24180 "quote",
24181 "quotes",
24182 "r",
24183 "r1",
24184 "r2",
24185 "race",
24186 "rad",
24187 "radiogroup",
24188 "radiusX",
24189 "radiusY",
24190 "random",
24191 "range",
24192 "rangeCount",
24193 "rangeMax",
24194 "rangeMin",
24195 "rangeOffset",
24196 "rangeOverflow",
24197 "rangeParent",
24198 "rangeUnderflow",
24199 "rate",
24200 "ratio",
24201 "raw",
24202 "rawId",
24203 "read",
24204 "readAsArrayBuffer",
24205 "readAsBinaryString",
24206 "readAsBlob",
24207 "readAsDataURL",
24208 "readAsText",
24209 "readBuffer",
24210 "readEntries",
24211 "readOnly",
24212 "readPixels",
24213 "readReportRequested",
24214 "readText",
24215 "readValue",
24216 "readable",
24217 "ready",
24218 "readyState",
24219 "reason",
24220 "reboot",
24221 "receivedAlert",
24222 "receiver",
24223 "receivers",
24224 "recipient",
24225 "reconnect",
24226 "recordNumber",
24227 "recordsAvailable",
24228 "recordset",
24229 "rect",
24230 "red",
24231 "redEyeReduction",
24232 "redirect",
24233 "redirectCount",
24234 "redirectEnd",
24235 "redirectStart",
24236 "redirected",
24237 "reduce",
24238 "reduceRight",
24239 "reduction",
24240 "refDistance",
24241 "refX",
24242 "refY",
24243 "referenceNode",
24244 "referenceSpace",
24245 "referrer",
24246 "referrerPolicy",
24247 "refresh",
24248 "region",
24249 "regionAnchorX",
24250 "regionAnchorY",
24251 "regionId",
24252 "regions",
24253 "register",
24254 "registerContentHandler",
24255 "registerElement",
24256 "registerProperty",
24257 "registerProtocolHandler",
24258 "reject",
24259 "rel",
24260 "relList",
24261 "relatedAddress",
24262 "relatedNode",
24263 "relatedPort",
24264 "relatedTarget",
24265 "release",
24266 "releaseCapture",
24267 "releaseEvents",
24268 "releaseInterface",
24269 "releaseLock",
24270 "releasePointerCapture",
24271 "releaseShaderCompiler",
24272 "reliable",
24273 "reliableWrite",
24274 "reload",
24275 "rem",
24276 "remainingSpace",
24277 "remote",
24278 "remoteDescription",
24279 "remove",
24280 "removeAllRanges",
24281 "removeAttribute",
24282 "removeAttributeNS",
24283 "removeAttributeNode",
24284 "removeBehavior",
24285 "removeChild",
24286 "removeCue",
24287 "removeEventListener",
24288 "removeFilter",
24289 "removeImport",
24290 "removeItem",
24291 "removeListener",
24292 "removeNamedItem",
24293 "removeNamedItemNS",
24294 "removeNode",
24295 "removeParameter",
24296 "removeProperty",
24297 "removeRange",
24298 "removeRegion",
24299 "removeRule",
24300 "removeSiteSpecificTrackingException",
24301 "removeSourceBuffer",
24302 "removeStream",
24303 "removeTrack",
24304 "removeVariable",
24305 "removeWakeLockListener",
24306 "removeWebWideTrackingException",
24307 "removed",
24308 "removedNodes",
24309 "renderHeight",
24310 "renderState",
24311 "renderTime",
24312 "renderWidth",
24313 "renderbufferStorage",
24314 "renderbufferStorageMultisample",
24315 "renderedBuffer",
24316 "renderingMode",
24317 "renotify",
24318 "repeat",
24319 "replace",
24320 "replaceAdjacentText",
24321 "replaceAll",
24322 "replaceChild",
24323 "replaceChildren",
24324 "replaceData",
24325 "replaceId",
24326 "replaceItem",
24327 "replaceNode",
24328 "replaceState",
24329 "replaceSync",
24330 "replaceTrack",
24331 "replaceWholeText",
24332 "replaceWith",
24333 "reportValidity",
24334 "request",
24335 "requestAnimationFrame",
24336 "requestAutocomplete",
24337 "requestData",
24338 "requestDevice",
24339 "requestFrame",
24340 "requestFullscreen",
24341 "requestHitTestSource",
24342 "requestHitTestSourceForTransientInput",
24343 "requestId",
24344 "requestIdleCallback",
24345 "requestMIDIAccess",
24346 "requestMediaKeySystemAccess",
24347 "requestPermission",
24348 "requestPictureInPicture",
24349 "requestPointerLock",
24350 "requestPresent",
24351 "requestReferenceSpace",
24352 "requestSession",
24353 "requestStart",
24354 "requestStorageAccess",
24355 "requestSubmit",
24356 "requestVideoFrameCallback",
24357 "requestingWindow",
24358 "requireInteraction",
24359 "required",
24360 "requiredExtensions",
24361 "requiredFeatures",
24362 "reset",
24363 "resetPose",
24364 "resetTransform",
24365 "resize",
24366 "resizeBy",
24367 "resizeTo",
24368 "resolve",
24369 "response",
24370 "responseBody",
24371 "responseEnd",
24372 "responseReady",
24373 "responseStart",
24374 "responseText",
24375 "responseType",
24376 "responseURL",
24377 "responseXML",
24378 "restartIce",
24379 "restore",
24380 "result",
24381 "resultIndex",
24382 "resultType",
24383 "results",
24384 "resume",
24385 "resumeProfilers",
24386 "resumeTransformFeedback",
24387 "retry",
24388 "returnValue",
24389 "rev",
24390 "reverse",
24391 "reversed",
24392 "revocable",
24393 "revokeObjectURL",
24394 "rgbColor",
24395 "right",
24396 "rightContext",
24397 "rightDegrees",
24398 "rightMargin",
24399 "rightProjectionMatrix",
24400 "rightViewMatrix",
24401 "role",
24402 "rolloffFactor",
24403 "root",
24404 "rootBounds",
24405 "rootElement",
24406 "rootMargin",
24407 "rotate",
24408 "rotateAxisAngle",
24409 "rotateAxisAngleSelf",
24410 "rotateFromVector",
24411 "rotateFromVectorSelf",
24412 "rotateSelf",
24413 "rotation",
24414 "rotationAngle",
24415 "rotationRate",
24416 "round",
24417 "row-gap",
24418 "rowGap",
24419 "rowIndex",
24420 "rowSpan",
24421 "rows",
24422 "rtcpTransport",
24423 "rtt",
24424 "ruby-align",
24425 "ruby-position",
24426 "rubyAlign",
24427 "rubyOverhang",
24428 "rubyPosition",
24429 "rules",
24430 "runtime",
24431 "runtimeStyle",
24432 "rx",
24433 "ry",
24434 "s",
24435 "safari",
24436 "sample",
24437 "sampleCoverage",
24438 "sampleRate",
24439 "samplerParameterf",
24440 "samplerParameteri",
24441 "sandbox",
24442 "save",
24443 "saveData",
24444 "scale",
24445 "scale3d",
24446 "scale3dSelf",
24447 "scaleNonUniform",
24448 "scaleNonUniformSelf",
24449 "scaleSelf",
24450 "scheme",
24451 "scissor",
24452 "scope",
24453 "scopeName",
24454 "scoped",
24455 "screen",
24456 "screenBrightness",
24457 "screenEnabled",
24458 "screenLeft",
24459 "screenPixelToMillimeterX",
24460 "screenPixelToMillimeterY",
24461 "screenTop",
24462 "screenX",
24463 "screenY",
24464 "scriptURL",
24465 "scripts",
24466 "scroll",
24467 "scroll-behavior",
24468 "scroll-margin",
24469 "scroll-margin-block",
24470 "scroll-margin-block-end",
24471 "scroll-margin-block-start",
24472 "scroll-margin-bottom",
24473 "scroll-margin-inline",
24474 "scroll-margin-inline-end",
24475 "scroll-margin-inline-start",
24476 "scroll-margin-left",
24477 "scroll-margin-right",
24478 "scroll-margin-top",
24479 "scroll-padding",
24480 "scroll-padding-block",
24481 "scroll-padding-block-end",
24482 "scroll-padding-block-start",
24483 "scroll-padding-bottom",
24484 "scroll-padding-inline",
24485 "scroll-padding-inline-end",
24486 "scroll-padding-inline-start",
24487 "scroll-padding-left",
24488 "scroll-padding-right",
24489 "scroll-padding-top",
24490 "scroll-snap-align",
24491 "scroll-snap-type",
24492 "scrollAmount",
24493 "scrollBehavior",
24494 "scrollBy",
24495 "scrollByLines",
24496 "scrollByPages",
24497 "scrollDelay",
24498 "scrollHeight",
24499 "scrollIntoView",
24500 "scrollIntoViewIfNeeded",
24501 "scrollLeft",
24502 "scrollLeftMax",
24503 "scrollMargin",
24504 "scrollMarginBlock",
24505 "scrollMarginBlockEnd",
24506 "scrollMarginBlockStart",
24507 "scrollMarginBottom",
24508 "scrollMarginInline",
24509 "scrollMarginInlineEnd",
24510 "scrollMarginInlineStart",
24511 "scrollMarginLeft",
24512 "scrollMarginRight",
24513 "scrollMarginTop",
24514 "scrollMaxX",
24515 "scrollMaxY",
24516 "scrollPadding",
24517 "scrollPaddingBlock",
24518 "scrollPaddingBlockEnd",
24519 "scrollPaddingBlockStart",
24520 "scrollPaddingBottom",
24521 "scrollPaddingInline",
24522 "scrollPaddingInlineEnd",
24523 "scrollPaddingInlineStart",
24524 "scrollPaddingLeft",
24525 "scrollPaddingRight",
24526 "scrollPaddingTop",
24527 "scrollRestoration",
24528 "scrollSnapAlign",
24529 "scrollSnapType",
24530 "scrollTo",
24531 "scrollTop",
24532 "scrollTopMax",
24533 "scrollWidth",
24534 "scrollX",
24535 "scrollY",
24536 "scrollbar-color",
24537 "scrollbar-width",
24538 "scrollbar3dLightColor",
24539 "scrollbarArrowColor",
24540 "scrollbarBaseColor",
24541 "scrollbarColor",
24542 "scrollbarDarkShadowColor",
24543 "scrollbarFaceColor",
24544 "scrollbarHighlightColor",
24545 "scrollbarShadowColor",
24546 "scrollbarTrackColor",
24547 "scrollbarWidth",
24548 "scrollbars",
24549 "scrolling",
24550 "scrollingElement",
24551 "sctp",
24552 "sctpCauseCode",
24553 "sdp",
24554 "sdpLineNumber",
24555 "sdpMLineIndex",
24556 "sdpMid",
24557 "seal",
24558 "search",
24559 "searchBox",
24560 "searchBoxJavaBridge_",
24561 "searchParams",
24562 "sectionRowIndex",
24563 "secureConnectionStart",
24564 "security",
24565 "seed",
24566 "seekToNextFrame",
24567 "seekable",
24568 "seeking",
24569 "select",
24570 "selectAllChildren",
24571 "selectAlternateInterface",
24572 "selectConfiguration",
24573 "selectNode",
24574 "selectNodeContents",
24575 "selectNodes",
24576 "selectSingleNode",
24577 "selectSubString",
24578 "selected",
24579 "selectedIndex",
24580 "selectedOptions",
24581 "selectedStyleSheetSet",
24582 "selectedStylesheetSet",
24583 "selection",
24584 "selectionDirection",
24585 "selectionEnd",
24586 "selectionStart",
24587 "selector",
24588 "selectorText",
24589 "self",
24590 "send",
24591 "sendAsBinary",
24592 "sendBeacon",
24593 "sender",
24594 "sentAlert",
24595 "sentTimestamp",
24596 "separator",
24597 "serialNumber",
24598 "serializeToString",
24599 "serverTiming",
24600 "service",
24601 "serviceWorker",
24602 "session",
24603 "sessionId",
24604 "sessionStorage",
24605 "set",
24606 "setActionHandler",
24607 "setActive",
24608 "setAlpha",
24609 "setAppBadge",
24610 "setAttribute",
24611 "setAttributeNS",
24612 "setAttributeNode",
24613 "setAttributeNodeNS",
24614 "setBaseAndExtent",
24615 "setBigInt64",
24616 "setBigUint64",
24617 "setBingCurrentSearchDefault",
24618 "setCapture",
24619 "setCodecPreferences",
24620 "setColor",
24621 "setCompositeOperation",
24622 "setConfiguration",
24623 "setCurrentTime",
24624 "setCustomValidity",
24625 "setData",
24626 "setDate",
24627 "setDragImage",
24628 "setEnd",
24629 "setEndAfter",
24630 "setEndBefore",
24631 "setEndPoint",
24632 "setFillColor",
24633 "setFilterRes",
24634 "setFloat32",
24635 "setFloat64",
24636 "setFloatValue",
24637 "setFormValue",
24638 "setFullYear",
24639 "setHeaderValue",
24640 "setHours",
24641 "setIdentityProvider",
24642 "setImmediate",
24643 "setInt16",
24644 "setInt32",
24645 "setInt8",
24646 "setInterval",
24647 "setItem",
24648 "setKeyframes",
24649 "setLineCap",
24650 "setLineDash",
24651 "setLineJoin",
24652 "setLineWidth",
24653 "setLiveSeekableRange",
24654 "setLocalDescription",
24655 "setMatrix",
24656 "setMatrixValue",
24657 "setMediaKeys",
24658 "setMilliseconds",
24659 "setMinutes",
24660 "setMiterLimit",
24661 "setMonth",
24662 "setNamedItem",
24663 "setNamedItemNS",
24664 "setNonUserCodeExceptions",
24665 "setOrientToAngle",
24666 "setOrientToAuto",
24667 "setOrientation",
24668 "setOverrideHistoryNavigationMode",
24669 "setPaint",
24670 "setParameter",
24671 "setParameters",
24672 "setPeriodicWave",
24673 "setPointerCapture",
24674 "setPosition",
24675 "setPositionState",
24676 "setPreference",
24677 "setProperty",
24678 "setPrototypeOf",
24679 "setRGBColor",
24680 "setRGBColorICCColor",
24681 "setRadius",
24682 "setRangeText",
24683 "setRemoteDescription",
24684 "setRequestHeader",
24685 "setResizable",
24686 "setResourceTimingBufferSize",
24687 "setRotate",
24688 "setScale",
24689 "setSeconds",
24690 "setSelectionRange",
24691 "setServerCertificate",
24692 "setShadow",
24693 "setSinkId",
24694 "setSkewX",
24695 "setSkewY",
24696 "setStart",
24697 "setStartAfter",
24698 "setStartBefore",
24699 "setStdDeviation",
24700 "setStreams",
24701 "setStringValue",
24702 "setStrokeColor",
24703 "setSuggestResult",
24704 "setTargetAtTime",
24705 "setTargetValueAtTime",
24706 "setTime",
24707 "setTimeout",
24708 "setTransform",
24709 "setTranslate",
24710 "setUTCDate",
24711 "setUTCFullYear",
24712 "setUTCHours",
24713 "setUTCMilliseconds",
24714 "setUTCMinutes",
24715 "setUTCMonth",
24716 "setUTCSeconds",
24717 "setUint16",
24718 "setUint32",
24719 "setUint8",
24720 "setUri",
24721 "setValidity",
24722 "setValueAtTime",
24723 "setValueCurveAtTime",
24724 "setVariable",
24725 "setVelocity",
24726 "setVersion",
24727 "setYear",
24728 "settingName",
24729 "settingValue",
24730 "sex",
24731 "shaderSource",
24732 "shadowBlur",
24733 "shadowColor",
24734 "shadowOffsetX",
24735 "shadowOffsetY",
24736 "shadowRoot",
24737 "shape",
24738 "shape-image-threshold",
24739 "shape-margin",
24740 "shape-outside",
24741 "shape-rendering",
24742 "shapeImageThreshold",
24743 "shapeMargin",
24744 "shapeOutside",
24745 "shapeRendering",
24746 "sheet",
24747 "shift",
24748 "shiftKey",
24749 "shiftLeft",
24750 "shippingAddress",
24751 "shippingOption",
24752 "shippingType",
24753 "show",
24754 "showHelp",
24755 "showModal",
24756 "showModalDialog",
24757 "showModelessDialog",
24758 "showNotification",
24759 "sidebar",
24760 "sign",
24761 "signal",
24762 "signalingState",
24763 "signature",
24764 "silent",
24765 "sin",
24766 "singleNodeValue",
24767 "sinh",
24768 "sinkId",
24769 "sittingToStandingTransform",
24770 "size",
24771 "sizeToContent",
24772 "sizeX",
24773 "sizeZ",
24774 "sizes",
24775 "skewX",
24776 "skewXSelf",
24777 "skewY",
24778 "skewYSelf",
24779 "slice",
24780 "slope",
24781 "slot",
24782 "small",
24783 "smil",
24784 "smooth",
24785 "smoothingTimeConstant",
24786 "snapToLines",
24787 "snapshotItem",
24788 "snapshotLength",
24789 "some",
24790 "sort",
24791 "sortingCode",
24792 "source",
24793 "sourceBuffer",
24794 "sourceBuffers",
24795 "sourceCapabilities",
24796 "sourceFile",
24797 "sourceIndex",
24798 "sources",
24799 "spacing",
24800 "span",
24801 "speak",
24802 "speakAs",
24803 "speaking",
24804 "species",
24805 "specified",
24806 "specularConstant",
24807 "specularExponent",
24808 "speechSynthesis",
24809 "speed",
24810 "speedOfSound",
24811 "spellcheck",
24812 "splice",
24813 "split",
24814 "splitText",
24815 "spreadMethod",
24816 "sqrt",
24817 "src",
24818 "srcElement",
24819 "srcFilter",
24820 "srcObject",
24821 "srcUrn",
24822 "srcdoc",
24823 "srclang",
24824 "srcset",
24825 "stack",
24826 "stackTraceLimit",
24827 "stacktrace",
24828 "stageParameters",
24829 "standalone",
24830 "standby",
24831 "start",
24832 "startContainer",
24833 "startIce",
24834 "startMessages",
24835 "startNotifications",
24836 "startOffset",
24837 "startProfiling",
24838 "startRendering",
24839 "startShark",
24840 "startTime",
24841 "startsWith",
24842 "state",
24843 "status",
24844 "statusCode",
24845 "statusMessage",
24846 "statusText",
24847 "statusbar",
24848 "stdDeviationX",
24849 "stdDeviationY",
24850 "stencilFunc",
24851 "stencilFuncSeparate",
24852 "stencilMask",
24853 "stencilMaskSeparate",
24854 "stencilOp",
24855 "stencilOpSeparate",
24856 "step",
24857 "stepDown",
24858 "stepMismatch",
24859 "stepUp",
24860 "sticky",
24861 "stitchTiles",
24862 "stop",
24863 "stop-color",
24864 "stop-opacity",
24865 "stopColor",
24866 "stopImmediatePropagation",
24867 "stopNotifications",
24868 "stopOpacity",
24869 "stopProfiling",
24870 "stopPropagation",
24871 "stopShark",
24872 "stopped",
24873 "storage",
24874 "storageArea",
24875 "storageName",
24876 "storageStatus",
24877 "store",
24878 "storeSiteSpecificTrackingException",
24879 "storeWebWideTrackingException",
24880 "stpVersion",
24881 "stream",
24882 "streams",
24883 "stretch",
24884 "strike",
24885 "string",
24886 "stringValue",
24887 "stringify",
24888 "stroke",
24889 "stroke-dasharray",
24890 "stroke-dashoffset",
24891 "stroke-linecap",
24892 "stroke-linejoin",
24893 "stroke-miterlimit",
24894 "stroke-opacity",
24895 "stroke-width",
24896 "strokeDasharray",
24897 "strokeDashoffset",
24898 "strokeLinecap",
24899 "strokeLinejoin",
24900 "strokeMiterlimit",
24901 "strokeOpacity",
24902 "strokeRect",
24903 "strokeStyle",
24904 "strokeText",
24905 "strokeWidth",
24906 "style",
24907 "styleFloat",
24908 "styleMap",
24909 "styleMedia",
24910 "styleSheet",
24911 "styleSheetSets",
24912 "styleSheets",
24913 "sub",
24914 "subarray",
24915 "subject",
24916 "submit",
24917 "submitFrame",
24918 "submitter",
24919 "subscribe",
24920 "substr",
24921 "substring",
24922 "substringData",
24923 "subtle",
24924 "subtree",
24925 "suffix",
24926 "suffixes",
24927 "summary",
24928 "sup",
24929 "supported",
24930 "supportedContentEncodings",
24931 "supportedEntryTypes",
24932 "supports",
24933 "supportsSession",
24934 "surfaceScale",
24935 "surroundContents",
24936 "suspend",
24937 "suspendRedraw",
24938 "swapCache",
24939 "swapNode",
24940 "sweepFlag",
24941 "symbols",
24942 "sync",
24943 "sysexEnabled",
24944 "system",
24945 "systemCode",
24946 "systemId",
24947 "systemLanguage",
24948 "systemXDPI",
24949 "systemYDPI",
24950 "tBodies",
24951 "tFoot",
24952 "tHead",
24953 "tabIndex",
24954 "table",
24955 "table-layout",
24956 "tableLayout",
24957 "tableValues",
24958 "tag",
24959 "tagName",
24960 "tagUrn",
24961 "tags",
24962 "taintEnabled",
24963 "takePhoto",
24964 "takeRecords",
24965 "tan",
24966 "tangentialPressure",
24967 "tanh",
24968 "target",
24969 "targetElement",
24970 "targetRayMode",
24971 "targetRaySpace",
24972 "targetTouches",
24973 "targetX",
24974 "targetY",
24975 "tcpType",
24976 "tee",
24977 "tel",
24978 "terminate",
24979 "test",
24980 "texImage2D",
24981 "texImage3D",
24982 "texParameterf",
24983 "texParameteri",
24984 "texStorage2D",
24985 "texStorage3D",
24986 "texSubImage2D",
24987 "texSubImage3D",
24988 "text",
24989 "text-align",
24990 "text-align-last",
24991 "text-anchor",
24992 "text-combine-upright",
24993 "text-decoration",
24994 "text-decoration-color",
24995 "text-decoration-line",
24996 "text-decoration-skip-ink",
24997 "text-decoration-style",
24998 "text-decoration-thickness",
24999 "text-emphasis",
25000 "text-emphasis-color",
25001 "text-emphasis-position",
25002 "text-emphasis-style",
25003 "text-indent",
25004 "text-justify",
25005 "text-orientation",
25006 "text-overflow",
25007 "text-rendering",
25008 "text-shadow",
25009 "text-transform",
25010 "text-underline-offset",
25011 "text-underline-position",
25012 "textAlign",
25013 "textAlignLast",
25014 "textAnchor",
25015 "textAutospace",
25016 "textBaseline",
25017 "textCombineUpright",
25018 "textContent",
25019 "textDecoration",
25020 "textDecorationBlink",
25021 "textDecorationColor",
25022 "textDecorationLine",
25023 "textDecorationLineThrough",
25024 "textDecorationNone",
25025 "textDecorationOverline",
25026 "textDecorationSkipInk",
25027 "textDecorationStyle",
25028 "textDecorationThickness",
25029 "textDecorationUnderline",
25030 "textEmphasis",
25031 "textEmphasisColor",
25032 "textEmphasisPosition",
25033 "textEmphasisStyle",
25034 "textIndent",
25035 "textJustify",
25036 "textJustifyTrim",
25037 "textKashida",
25038 "textKashidaSpace",
25039 "textLength",
25040 "textOrientation",
25041 "textOverflow",
25042 "textRendering",
25043 "textShadow",
25044 "textTracks",
25045 "textTransform",
25046 "textUnderlineOffset",
25047 "textUnderlinePosition",
25048 "then",
25049 "threadId",
25050 "threshold",
25051 "thresholds",
25052 "tiltX",
25053 "tiltY",
25054 "time",
25055 "timeEnd",
25056 "timeLog",
25057 "timeOrigin",
25058 "timeRemaining",
25059 "timeStamp",
25060 "timecode",
25061 "timeline",
25062 "timelineTime",
25063 "timeout",
25064 "timestamp",
25065 "timestampOffset",
25066 "timing",
25067 "title",
25068 "to",
25069 "toArray",
25070 "toBlob",
25071 "toDataURL",
25072 "toDateString",
25073 "toElement",
25074 "toExponential",
25075 "toFixed",
25076 "toFloat32Array",
25077 "toFloat64Array",
25078 "toGMTString",
25079 "toISOString",
25080 "toJSON",
25081 "toLocaleDateString",
25082 "toLocaleFormat",
25083 "toLocaleLowerCase",
25084 "toLocaleString",
25085 "toLocaleTimeString",
25086 "toLocaleUpperCase",
25087 "toLowerCase",
25088 "toMatrix",
25089 "toMethod",
25090 "toPrecision",
25091 "toPrimitive",
25092 "toSdp",
25093 "toSource",
25094 "toStaticHTML",
25095 "toString",
25096 "toStringTag",
25097 "toSum",
25098 "toTimeString",
25099 "toUTCString",
25100 "toUpperCase",
25101 "toggle",
25102 "toggleAttribute",
25103 "toggleLongPressEnabled",
25104 "tone",
25105 "toneBuffer",
25106 "tooLong",
25107 "tooShort",
25108 "toolbar",
25109 "top",
25110 "topMargin",
25111 "total",
25112 "totalFrameDelay",
25113 "totalVideoFrames",
25114 "touch-action",
25115 "touchAction",
25116 "touched",
25117 "touches",
25118 "trace",
25119 "track",
25120 "trackVisibility",
25121 "transaction",
25122 "transactions",
25123 "transceiver",
25124 "transferControlToOffscreen",
25125 "transferFromImageBitmap",
25126 "transferImageBitmap",
25127 "transferIn",
25128 "transferOut",
25129 "transferSize",
25130 "transferToImageBitmap",
25131 "transform",
25132 "transform-box",
25133 "transform-origin",
25134 "transform-style",
25135 "transformBox",
25136 "transformFeedbackVaryings",
25137 "transformOrigin",
25138 "transformPoint",
25139 "transformString",
25140 "transformStyle",
25141 "transformToDocument",
25142 "transformToFragment",
25143 "transition",
25144 "transition-delay",
25145 "transition-duration",
25146 "transition-property",
25147 "transition-timing-function",
25148 "transitionDelay",
25149 "transitionDuration",
25150 "transitionProperty",
25151 "transitionTimingFunction",
25152 "translate",
25153 "translateSelf",
25154 "translationX",
25155 "translationY",
25156 "transport",
25157 "trim",
25158 "trimEnd",
25159 "trimLeft",
25160 "trimRight",
25161 "trimStart",
25162 "trueSpeed",
25163 "trunc",
25164 "truncate",
25165 "trustedTypes",
25166 "turn",
25167 "twist",
25168 "type",
25169 "typeDetail",
25170 "typeMismatch",
25171 "typeMustMatch",
25172 "types",
25173 "u2f",
25174 "ubound",
25175 "uint16",
25176 "uint32",
25177 "uint8",
25178 "uint8Clamped",
25179 "undefined",
25180 "unescape",
25181 "uneval",
25182 "unicode",
25183 "unicode-bidi",
25184 "unicodeBidi",
25185 "unicodeRange",
25186 "uniform1f",
25187 "uniform1fv",
25188 "uniform1i",
25189 "uniform1iv",
25190 "uniform1ui",
25191 "uniform1uiv",
25192 "uniform2f",
25193 "uniform2fv",
25194 "uniform2i",
25195 "uniform2iv",
25196 "uniform2ui",
25197 "uniform2uiv",
25198 "uniform3f",
25199 "uniform3fv",
25200 "uniform3i",
25201 "uniform3iv",
25202 "uniform3ui",
25203 "uniform3uiv",
25204 "uniform4f",
25205 "uniform4fv",
25206 "uniform4i",
25207 "uniform4iv",
25208 "uniform4ui",
25209 "uniform4uiv",
25210 "uniformBlockBinding",
25211 "uniformMatrix2fv",
25212 "uniformMatrix2x3fv",
25213 "uniformMatrix2x4fv",
25214 "uniformMatrix3fv",
25215 "uniformMatrix3x2fv",
25216 "uniformMatrix3x4fv",
25217 "uniformMatrix4fv",
25218 "uniformMatrix4x2fv",
25219 "uniformMatrix4x3fv",
25220 "unique",
25221 "uniqueID",
25222 "uniqueNumber",
25223 "unit",
25224 "unitType",
25225 "units",
25226 "unloadEventEnd",
25227 "unloadEventStart",
25228 "unlock",
25229 "unmount",
25230 "unobserve",
25231 "unpause",
25232 "unpauseAnimations",
25233 "unreadCount",
25234 "unregister",
25235 "unregisterContentHandler",
25236 "unregisterProtocolHandler",
25237 "unscopables",
25238 "unselectable",
25239 "unshift",
25240 "unsubscribe",
25241 "unsuspendRedraw",
25242 "unsuspendRedrawAll",
25243 "unwatch",
25244 "unwrapKey",
25245 "upDegrees",
25246 "upX",
25247 "upY",
25248 "upZ",
25249 "update",
25250 "updateCommands",
25251 "updateIce",
25252 "updateInterval",
25253 "updatePlaybackRate",
25254 "updateRenderState",
25255 "updateSettings",
25256 "updateTiming",
25257 "updateViaCache",
25258 "updateWith",
25259 "updated",
25260 "updating",
25261 "upgrade",
25262 "upload",
25263 "uploadTotal",
25264 "uploaded",
25265 "upper",
25266 "upperBound",
25267 "upperOpen",
25268 "uri",
25269 "url",
25270 "urn",
25271 "urns",
25272 "usages",
25273 "usb",
25274 "usbVersionMajor",
25275 "usbVersionMinor",
25276 "usbVersionSubminor",
25277 "useCurrentView",
25278 "useMap",
25279 "useProgram",
25280 "usedSpace",
25281 "user-select",
25282 "userActivation",
25283 "userAgent",
25284 "userChoice",
25285 "userHandle",
25286 "userHint",
25287 "userLanguage",
25288 "userSelect",
25289 "userVisibleOnly",
25290 "username",
25291 "usernameFragment",
25292 "utterance",
25293 "uuid",
25294 "v8BreakIterator",
25295 "vAlign",
25296 "vLink",
25297 "valid",
25298 "validate",
25299 "validateProgram",
25300 "validationMessage",
25301 "validity",
25302 "value",
25303 "valueAsDate",
25304 "valueAsNumber",
25305 "valueAsString",
25306 "valueInSpecifiedUnits",
25307 "valueMissing",
25308 "valueOf",
25309 "valueText",
25310 "valueType",
25311 "values",
25312 "variable",
25313 "variant",
25314 "variationSettings",
25315 "vector-effect",
25316 "vectorEffect",
25317 "velocityAngular",
25318 "velocityExpansion",
25319 "velocityX",
25320 "velocityY",
25321 "vendor",
25322 "vendorId",
25323 "vendorSub",
25324 "verify",
25325 "version",
25326 "vertexAttrib1f",
25327 "vertexAttrib1fv",
25328 "vertexAttrib2f",
25329 "vertexAttrib2fv",
25330 "vertexAttrib3f",
25331 "vertexAttrib3fv",
25332 "vertexAttrib4f",
25333 "vertexAttrib4fv",
25334 "vertexAttribDivisor",
25335 "vertexAttribDivisorANGLE",
25336 "vertexAttribI4i",
25337 "vertexAttribI4iv",
25338 "vertexAttribI4ui",
25339 "vertexAttribI4uiv",
25340 "vertexAttribIPointer",
25341 "vertexAttribPointer",
25342 "vertical",
25343 "vertical-align",
25344 "verticalAlign",
25345 "verticalOverflow",
25346 "vh",
25347 "vibrate",
25348 "vibrationActuator",
25349 "videoBitsPerSecond",
25350 "videoHeight",
25351 "videoTracks",
25352 "videoWidth",
25353 "view",
25354 "viewBox",
25355 "viewBoxString",
25356 "viewTarget",
25357 "viewTargetString",
25358 "viewport",
25359 "viewportAnchorX",
25360 "viewportAnchorY",
25361 "viewportElement",
25362 "views",
25363 "violatedDirective",
25364 "visibility",
25365 "visibilityState",
25366 "visible",
25367 "visualViewport",
25368 "vlinkColor",
25369 "vmax",
25370 "vmin",
25371 "voice",
25372 "voiceURI",
25373 "volume",
25374 "vrml",
25375 "vspace",
25376 "vw",
25377 "w",
25378 "wait",
25379 "waitSync",
25380 "waiting",
25381 "wake",
25382 "wakeLock",
25383 "wand",
25384 "warn",
25385 "wasClean",
25386 "wasDiscarded",
25387 "watch",
25388 "watchAvailability",
25389 "watchPosition",
25390 "webdriver",
25391 "webkitAddKey",
25392 "webkitAlignContent",
25393 "webkitAlignItems",
25394 "webkitAlignSelf",
25395 "webkitAnimation",
25396 "webkitAnimationDelay",
25397 "webkitAnimationDirection",
25398 "webkitAnimationDuration",
25399 "webkitAnimationFillMode",
25400 "webkitAnimationIterationCount",
25401 "webkitAnimationName",
25402 "webkitAnimationPlayState",
25403 "webkitAnimationTimingFunction",
25404 "webkitAppearance",
25405 "webkitAudioContext",
25406 "webkitAudioDecodedByteCount",
25407 "webkitAudioPannerNode",
25408 "webkitBackfaceVisibility",
25409 "webkitBackground",
25410 "webkitBackgroundAttachment",
25411 "webkitBackgroundClip",
25412 "webkitBackgroundColor",
25413 "webkitBackgroundImage",
25414 "webkitBackgroundOrigin",
25415 "webkitBackgroundPosition",
25416 "webkitBackgroundPositionX",
25417 "webkitBackgroundPositionY",
25418 "webkitBackgroundRepeat",
25419 "webkitBackgroundSize",
25420 "webkitBackingStorePixelRatio",
25421 "webkitBorderBottomLeftRadius",
25422 "webkitBorderBottomRightRadius",
25423 "webkitBorderImage",
25424 "webkitBorderImageOutset",
25425 "webkitBorderImageRepeat",
25426 "webkitBorderImageSlice",
25427 "webkitBorderImageSource",
25428 "webkitBorderImageWidth",
25429 "webkitBorderRadius",
25430 "webkitBorderTopLeftRadius",
25431 "webkitBorderTopRightRadius",
25432 "webkitBoxAlign",
25433 "webkitBoxDirection",
25434 "webkitBoxFlex",
25435 "webkitBoxOrdinalGroup",
25436 "webkitBoxOrient",
25437 "webkitBoxPack",
25438 "webkitBoxShadow",
25439 "webkitBoxSizing",
25440 "webkitCancelAnimationFrame",
25441 "webkitCancelFullScreen",
25442 "webkitCancelKeyRequest",
25443 "webkitCancelRequestAnimationFrame",
25444 "webkitClearResourceTimings",
25445 "webkitClosedCaptionsVisible",
25446 "webkitConvertPointFromNodeToPage",
25447 "webkitConvertPointFromPageToNode",
25448 "webkitCreateShadowRoot",
25449 "webkitCurrentFullScreenElement",
25450 "webkitCurrentPlaybackTargetIsWireless",
25451 "webkitDecodedFrameCount",
25452 "webkitDirectionInvertedFromDevice",
25453 "webkitDisplayingFullscreen",
25454 "webkitDroppedFrameCount",
25455 "webkitEnterFullScreen",
25456 "webkitEnterFullscreen",
25457 "webkitEntries",
25458 "webkitExitFullScreen",
25459 "webkitExitFullscreen",
25460 "webkitExitPointerLock",
25461 "webkitFilter",
25462 "webkitFlex",
25463 "webkitFlexBasis",
25464 "webkitFlexDirection",
25465 "webkitFlexFlow",
25466 "webkitFlexGrow",
25467 "webkitFlexShrink",
25468 "webkitFlexWrap",
25469 "webkitFullScreenKeyboardInputAllowed",
25470 "webkitFullscreenElement",
25471 "webkitFullscreenEnabled",
25472 "webkitGenerateKeyRequest",
25473 "webkitGetAsEntry",
25474 "webkitGetDatabaseNames",
25475 "webkitGetEntries",
25476 "webkitGetEntriesByName",
25477 "webkitGetEntriesByType",
25478 "webkitGetFlowByName",
25479 "webkitGetGamepads",
25480 "webkitGetImageDataHD",
25481 "webkitGetNamedFlows",
25482 "webkitGetRegionFlowRanges",
25483 "webkitGetUserMedia",
25484 "webkitHasClosedCaptions",
25485 "webkitHidden",
25486 "webkitIDBCursor",
25487 "webkitIDBDatabase",
25488 "webkitIDBDatabaseError",
25489 "webkitIDBDatabaseException",
25490 "webkitIDBFactory",
25491 "webkitIDBIndex",
25492 "webkitIDBKeyRange",
25493 "webkitIDBObjectStore",
25494 "webkitIDBRequest",
25495 "webkitIDBTransaction",
25496 "webkitImageSmoothingEnabled",
25497 "webkitIndexedDB",
25498 "webkitInitMessageEvent",
25499 "webkitIsFullScreen",
25500 "webkitJustifyContent",
25501 "webkitKeys",
25502 "webkitLineClamp",
25503 "webkitLineDashOffset",
25504 "webkitLockOrientation",
25505 "webkitMask",
25506 "webkitMaskClip",
25507 "webkitMaskComposite",
25508 "webkitMaskImage",
25509 "webkitMaskOrigin",
25510 "webkitMaskPosition",
25511 "webkitMaskPositionX",
25512 "webkitMaskPositionY",
25513 "webkitMaskRepeat",
25514 "webkitMaskSize",
25515 "webkitMatchesSelector",
25516 "webkitMediaStream",
25517 "webkitNotifications",
25518 "webkitOfflineAudioContext",
25519 "webkitOrder",
25520 "webkitOrientation",
25521 "webkitPeerConnection00",
25522 "webkitPersistentStorage",
25523 "webkitPerspective",
25524 "webkitPerspectiveOrigin",
25525 "webkitPointerLockElement",
25526 "webkitPostMessage",
25527 "webkitPreservesPitch",
25528 "webkitPutImageDataHD",
25529 "webkitRTCPeerConnection",
25530 "webkitRegionOverset",
25531 "webkitRelativePath",
25532 "webkitRequestAnimationFrame",
25533 "webkitRequestFileSystem",
25534 "webkitRequestFullScreen",
25535 "webkitRequestFullscreen",
25536 "webkitRequestPointerLock",
25537 "webkitResolveLocalFileSystemURL",
25538 "webkitSetMediaKeys",
25539 "webkitSetResourceTimingBufferSize",
25540 "webkitShadowRoot",
25541 "webkitShowPlaybackTargetPicker",
25542 "webkitSlice",
25543 "webkitSpeechGrammar",
25544 "webkitSpeechGrammarList",
25545 "webkitSpeechRecognition",
25546 "webkitSpeechRecognitionError",
25547 "webkitSpeechRecognitionEvent",
25548 "webkitStorageInfo",
25549 "webkitSupportsFullscreen",
25550 "webkitTemporaryStorage",
25551 "webkitTextFillColor",
25552 "webkitTextSizeAdjust",
25553 "webkitTextStroke",
25554 "webkitTextStrokeColor",
25555 "webkitTextStrokeWidth",
25556 "webkitTransform",
25557 "webkitTransformOrigin",
25558 "webkitTransformStyle",
25559 "webkitTransition",
25560 "webkitTransitionDelay",
25561 "webkitTransitionDuration",
25562 "webkitTransitionProperty",
25563 "webkitTransitionTimingFunction",
25564 "webkitURL",
25565 "webkitUnlockOrientation",
25566 "webkitUserSelect",
25567 "webkitVideoDecodedByteCount",
25568 "webkitVisibilityState",
25569 "webkitWirelessVideoPlaybackDisabled",
25570 "webkitdirectory",
25571 "webkitdropzone",
25572 "webstore",
25573 "weight",
25574 "whatToShow",
25575 "wheelDelta",
25576 "wheelDeltaX",
25577 "wheelDeltaY",
25578 "whenDefined",
25579 "which",
25580 "white-space",
25581 "whiteSpace",
25582 "wholeText",
25583 "widows",
25584 "width",
25585 "will-change",
25586 "willChange",
25587 "willValidate",
25588 "window",
25589 "withCredentials",
25590 "word-break",
25591 "word-spacing",
25592 "word-wrap",
25593 "wordBreak",
25594 "wordSpacing",
25595 "wordWrap",
25596 "workerStart",
25597 "wrap",
25598 "wrapKey",
25599 "writable",
25600 "writableAuxiliaries",
25601 "write",
25602 "writeText",
25603 "writeValue",
25604 "writeWithoutResponse",
25605 "writeln",
25606 "writing-mode",
25607 "writingMode",
25608 "x",
25609 "x1",
25610 "x2",
25611 "xChannelSelector",
25612 "xmlEncoding",
25613 "xmlStandalone",
25614 "xmlVersion",
25615 "xmlbase",
25616 "xmllang",
25617 "xmlspace",
25618 "xor",
25619 "xr",
25620 "y",
25621 "y1",
25622 "y2",
25623 "yChannelSelector",
25624 "yandex",
25625 "z",
25626 "z-index",
25627 "zIndex",
25628 "zoom",
25629 "zoomAndPan",
25630 "zoomRectScreen",
25631];
25632
25633/***********************************************************************
25634
25635 A JavaScript tokenizer / parser / beautifier / compressor.
25636 https://github.com/mishoo/UglifyJS2
25637
25638 -------------------------------- (C) ---------------------------------
25639
25640 Author: Mihai Bazon
25641 <mihai.bazon@gmail.com>
25642 http://mihai.bazon.net/blog
25643
25644 Distributed under the BSD license:
25645
25646 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
25647
25648 Redistribution and use in source and binary forms, with or without
25649 modification, are permitted provided that the following conditions
25650 are met:
25651
25652 * Redistributions of source code must retain the above
25653 copyright notice, this list of conditions and the following
25654 disclaimer.
25655
25656 * Redistributions in binary form must reproduce the above
25657 copyright notice, this list of conditions and the following
25658 disclaimer in the documentation and/or other materials
25659 provided with the distribution.
25660
25661 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
25662 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25663 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25664 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
25665 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
25666 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25667 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25668 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25669 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
25670 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
25671 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25672 SUCH DAMAGE.
25673
25674 ***********************************************************************/
25675
25676function find_builtins(reserved) {
25677 domprops.forEach(add);
25678
25679 // Compatibility fix for some standard defined globals not defined on every js environment
25680 var new_globals = ["Symbol", "Map", "Promise", "Proxy", "Reflect", "Set", "WeakMap", "WeakSet"];
25681 var objects = {};
25682 var global_ref = typeof global === "object" ? global : self;
25683
25684 new_globals.forEach(function (new_global) {
25685 objects[new_global] = global_ref[new_global] || new Function();
25686 });
25687
25688 [
25689 "null",
25690 "true",
25691 "false",
25692 "NaN",
25693 "Infinity",
25694 "-Infinity",
25695 "undefined",
25696 ].forEach(add);
25697 [ Object, Array, Function, Number,
25698 String, Boolean, Error, Math,
25699 Date, RegExp, objects.Symbol, ArrayBuffer,
25700 DataView, decodeURI, decodeURIComponent,
25701 encodeURI, encodeURIComponent, eval, EvalError,
25702 Float32Array, Float64Array, Int8Array, Int16Array,
25703 Int32Array, isFinite, isNaN, JSON, objects.Map, parseFloat,
25704 parseInt, objects.Promise, objects.Proxy, RangeError, ReferenceError,
25705 objects.Reflect, objects.Set, SyntaxError, TypeError, Uint8Array,
25706 Uint8ClampedArray, Uint16Array, Uint32Array, URIError,
25707 objects.WeakMap, objects.WeakSet
25708 ].forEach(function(ctor) {
25709 Object.getOwnPropertyNames(ctor).map(add);
25710 if (ctor.prototype) {
25711 Object.getOwnPropertyNames(ctor.prototype).map(add);
25712 }
25713 });
25714 function add(name) {
25715 reserved.add(name);
25716 }
25717}
25718
25719function reserve_quoted_keys(ast, reserved) {
25720 function add(name) {
25721 push_uniq(reserved, name);
25722 }
25723
25724 ast.walk(new TreeWalker(function(node) {
25725 if (node instanceof AST_ObjectKeyVal && node.quote) {
25726 add(node.key);
25727 } else if (node instanceof AST_ObjectProperty && node.quote) {
25728 add(node.key.name);
25729 } else if (node instanceof AST_Sub) {
25730 addStrings(node.property, add);
25731 }
25732 }));
25733}
25734
25735function addStrings(node, add) {
25736 node.walk(new TreeWalker(function(node) {
25737 if (node instanceof AST_Sequence) {
25738 addStrings(node.tail_node(), add);
25739 } else if (node instanceof AST_String) {
25740 add(node.value);
25741 } else if (node instanceof AST_Conditional) {
25742 addStrings(node.consequent, add);
25743 addStrings(node.alternative, add);
25744 }
25745 return true;
25746 }));
25747}
25748
25749function mangle_properties(ast, options) {
25750 options = defaults(options, {
25751 builtins: false,
25752 cache: null,
25753 debug: false,
25754 keep_quoted: false,
25755 only_cache: false,
25756 regex: null,
25757 reserved: null,
25758 undeclared: false,
25759 }, true);
25760
25761 var reserved_option = options.reserved;
25762 if (!Array.isArray(reserved_option)) reserved_option = [reserved_option];
25763 var reserved = new Set(reserved_option);
25764 if (!options.builtins) find_builtins(reserved);
25765
25766 var cname = -1;
25767 var cache;
25768 if (options.cache) {
25769 cache = options.cache.props;
25770 cache.forEach(function(mangled_name) {
25771 reserved.add(mangled_name);
25772 });
25773 } else {
25774 cache = new Map();
25775 }
25776
25777 var regex = options.regex && new RegExp(options.regex);
25778
25779 // note debug is either false (disabled), or a string of the debug suffix to use (enabled).
25780 // note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
25781 // the same as passing an empty string.
25782 var debug = options.debug !== false;
25783 var debug_name_suffix;
25784 if (debug) {
25785 debug_name_suffix = (options.debug === true ? "" : options.debug);
25786 }
25787
25788 var names_to_mangle = new Set();
25789 var unmangleable = new Set();
25790
25791 var keep_quoted_strict = options.keep_quoted === "strict";
25792
25793 // step 1: find candidates to mangle
25794 ast.walk(new TreeWalker(function(node) {
25795 if (node instanceof AST_ObjectKeyVal) {
25796 if (typeof node.key == "string" &&
25797 (!keep_quoted_strict || !node.quote)) {
25798 add(node.key);
25799 }
25800 } else if (node instanceof AST_ObjectProperty) {
25801 // setter or getter, since KeyVal is handled above
25802 if (!keep_quoted_strict || !node.key.end.quote) {
25803 add(node.key.name);
25804 }
25805 } else if (node instanceof AST_Dot) {
25806 var declared = !!options.undeclared;
25807 if (!declared) {
25808 var root = node;
25809 while (root.expression) {
25810 root = root.expression;
25811 }
25812 declared = !(root.thedef && root.thedef.undeclared);
25813 }
25814 if (declared &&
25815 (!keep_quoted_strict || !node.quote)) {
25816 add(node.property);
25817 }
25818 } else if (node instanceof AST_Sub) {
25819 if (!keep_quoted_strict) {
25820 addStrings(node.property, add);
25821 }
25822 } else if (node instanceof AST_Call
25823 && node.expression.print_to_string() == "Object.defineProperty") {
25824 addStrings(node.args[1], add);
25825 } else if (node instanceof AST_Binary && node.operator === "in") {
25826 addStrings(node.left, add);
25827 }
25828 }));
25829
25830 // step 2: transform the tree, renaming properties
25831 return ast.transform(new TreeTransformer(function(node) {
25832 if (node instanceof AST_ObjectKeyVal) {
25833 if (typeof node.key == "string" &&
25834 (!keep_quoted_strict || !node.quote)) {
25835 node.key = mangle(node.key);
25836 }
25837 } else if (node instanceof AST_ObjectProperty) {
25838 // setter, getter, method or class field
25839 if (!keep_quoted_strict || !node.key.end.quote) {
25840 node.key.name = mangle(node.key.name);
25841 }
25842 } else if (node instanceof AST_Dot) {
25843 if (!keep_quoted_strict || !node.quote) {
25844 node.property = mangle(node.property);
25845 }
25846 } else if (!options.keep_quoted && node instanceof AST_Sub) {
25847 node.property = mangleStrings(node.property);
25848 } else if (node instanceof AST_Call
25849 && node.expression.print_to_string() == "Object.defineProperty") {
25850 node.args[1] = mangleStrings(node.args[1]);
25851 } else if (node instanceof AST_Binary && node.operator === "in") {
25852 node.left = mangleStrings(node.left);
25853 }
25854 }));
25855
25856 // only function declarations after this line
25857
25858 function can_mangle(name) {
25859 if (unmangleable.has(name)) return false;
25860 if (reserved.has(name)) return false;
25861 if (options.only_cache) {
25862 return cache.has(name);
25863 }
25864 if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
25865 return true;
25866 }
25867
25868 function should_mangle(name) {
25869 if (regex && !regex.test(name)) return false;
25870 if (reserved.has(name)) return false;
25871 return cache.has(name)
25872 || names_to_mangle.has(name);
25873 }
25874
25875 function add(name) {
25876 if (can_mangle(name))
25877 names_to_mangle.add(name);
25878
25879 if (!should_mangle(name)) {
25880 unmangleable.add(name);
25881 }
25882 }
25883
25884 function mangle(name) {
25885 if (!should_mangle(name)) {
25886 return name;
25887 }
25888
25889 var mangled = cache.get(name);
25890 if (!mangled) {
25891 if (debug) {
25892 // debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
25893 var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_";
25894
25895 if (can_mangle(debug_mangled)) {
25896 mangled = debug_mangled;
25897 }
25898 }
25899
25900 // either debug mode is off, or it is on and we could not use the mangled name
25901 if (!mangled) {
25902 do {
25903 mangled = base54(++cname);
25904 } while (!can_mangle(mangled));
25905 }
25906
25907 cache.set(name, mangled);
25908 }
25909 return mangled;
25910 }
25911
25912 function mangleStrings(node) {
25913 return node.transform(new TreeTransformer(function(node) {
25914 if (node instanceof AST_Sequence) {
25915 var last = node.expressions.length - 1;
25916 node.expressions[last] = mangleStrings(node.expressions[last]);
25917 } else if (node instanceof AST_String) {
25918 node.value = mangle(node.value);
25919 } else if (node instanceof AST_Conditional) {
25920 node.consequent = mangleStrings(node.consequent);
25921 node.alternative = mangleStrings(node.alternative);
25922 }
25923 return node;
25924 }));
25925 }
25926}
25927
25928var to_ascii = typeof atob == "undefined" ? function(b64) {
25929 return Buffer.from(b64, "base64").toString();
25930} : atob;
25931var to_base64 = typeof btoa == "undefined" ? function(str) {
25932 return Buffer.from(str).toString("base64");
25933} : btoa;
25934
25935function read_source_map(code) {
25936 var match = /(?:^|[^.])\/\/# sourceMappingURL=data:application\/json(;[\w=-]*)?;base64,([+/0-9A-Za-z]*=*)\s*$/.exec(code);
25937 if (!match) {
25938 console.warn("inline source map not found");
25939 return null;
25940 }
25941 return to_ascii(match[2]);
25942}
25943
25944function set_shorthand(name, options, keys) {
25945 if (options[name]) {
25946 keys.forEach(function(key) {
25947 if (options[key]) {
25948 if (typeof options[key] != "object") options[key] = {};
25949 if (!(name in options[key])) options[key][name] = options[name];
25950 }
25951 });
25952 }
25953}
25954
25955function init_cache(cache) {
25956 if (!cache) return;
25957 if (!("props" in cache)) {
25958 cache.props = new Map();
25959 } else if (!(cache.props instanceof Map)) {
25960 cache.props = map_from_object(cache.props);
25961 }
25962}
25963
25964function cache_to_json(cache) {
25965 return {
25966 props: map_to_object(cache.props)
25967 };
25968}
25969
25970async function minify(files, options) {
25971 options = defaults(options, {
25972 compress: {},
25973 ecma: undefined,
25974 enclose: false,
25975 ie8: false,
25976 keep_classnames: undefined,
25977 keep_fnames: false,
25978 mangle: {},
25979 module: false,
25980 nameCache: null,
25981 output: null,
25982 format: null,
25983 parse: {},
25984 rename: undefined,
25985 safari10: false,
25986 sourceMap: false,
25987 timings: false,
25988 toplevel: false,
25989 warnings: false,
25990 wrap: false,
25991 }, true);
25992 var timings = options.timings && {
25993 start: Date.now()
25994 };
25995 if (options.keep_classnames === undefined) {
25996 options.keep_classnames = options.keep_fnames;
25997 }
25998 if (options.rename === undefined) {
25999 options.rename = options.compress && options.mangle;
26000 }
26001 if (options.output && options.format) {
26002 throw new Error("Please only specify either output or format option, preferrably format.");
26003 }
26004 options.format = options.format || options.output || {};
26005 set_shorthand("ecma", options, [ "parse", "compress", "format" ]);
26006 set_shorthand("ie8", options, [ "compress", "mangle", "format" ]);
26007 set_shorthand("keep_classnames", options, [ "compress", "mangle" ]);
26008 set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
26009 set_shorthand("module", options, [ "parse", "compress", "mangle" ]);
26010 set_shorthand("safari10", options, [ "mangle", "format" ]);
26011 set_shorthand("toplevel", options, [ "compress", "mangle" ]);
26012 set_shorthand("warnings", options, [ "compress" ]); // legacy
26013 var quoted_props;
26014 if (options.mangle) {
26015 options.mangle = defaults(options.mangle, {
26016 cache: options.nameCache && (options.nameCache.vars || {}),
26017 eval: false,
26018 ie8: false,
26019 keep_classnames: false,
26020 keep_fnames: false,
26021 module: false,
26022 properties: false,
26023 reserved: [],
26024 safari10: false,
26025 toplevel: false,
26026 }, true);
26027 if (options.mangle.properties) {
26028 if (typeof options.mangle.properties != "object") {
26029 options.mangle.properties = {};
26030 }
26031 if (options.mangle.properties.keep_quoted) {
26032 quoted_props = options.mangle.properties.reserved;
26033 if (!Array.isArray(quoted_props)) quoted_props = [];
26034 options.mangle.properties.reserved = quoted_props;
26035 }
26036 if (options.nameCache && !("cache" in options.mangle.properties)) {
26037 options.mangle.properties.cache = options.nameCache.props || {};
26038 }
26039 }
26040 init_cache(options.mangle.cache);
26041 init_cache(options.mangle.properties.cache);
26042 }
26043 if (options.sourceMap) {
26044 options.sourceMap = defaults(options.sourceMap, {
26045 asObject: false,
26046 content: null,
26047 filename: null,
26048 includeSources: false,
26049 root: null,
26050 url: null,
26051 }, true);
26052 }
26053 if (timings) timings.parse = Date.now();
26054 var toplevel;
26055 if (files instanceof AST_Toplevel) {
26056 toplevel = files;
26057 } else {
26058 if (typeof files == "string") {
26059 files = [ files ];
26060 }
26061 options.parse = options.parse || {};
26062 options.parse.toplevel = null;
26063 for (var name in files) if (HOP(files, name)) {
26064 options.parse.filename = name;
26065 options.parse.toplevel = parse(files[name], options.parse);
26066 if (options.sourceMap && options.sourceMap.content == "inline") {
26067 if (Object.keys(files).length > 1)
26068 throw new Error("inline source map only works with singular input");
26069 options.sourceMap.content = read_source_map(files[name]);
26070 }
26071 }
26072 toplevel = options.parse.toplevel;
26073 }
26074 if (quoted_props && options.mangle.properties.keep_quoted !== "strict") {
26075 reserve_quoted_keys(toplevel, quoted_props);
26076 }
26077 if (options.wrap) {
26078 toplevel = toplevel.wrap_commonjs(options.wrap);
26079 }
26080 if (options.enclose) {
26081 toplevel = toplevel.wrap_enclose(options.enclose);
26082 }
26083 if (timings) timings.rename = Date.now();
26084 if (timings) timings.compress = Date.now();
26085 if (options.compress) {
26086 toplevel = new Compressor(options.compress, {
26087 mangle_options: options.mangle
26088 }).compress(toplevel);
26089 }
26090 if (timings) timings.scope = Date.now();
26091 if (options.mangle) toplevel.figure_out_scope(options.mangle);
26092 if (timings) timings.mangle = Date.now();
26093 if (options.mangle) {
26094 base54.reset();
26095 toplevel.compute_char_frequency(options.mangle);
26096 toplevel.mangle_names(options.mangle);
26097 }
26098 if (timings) timings.properties = Date.now();
26099 if (options.mangle && options.mangle.properties) {
26100 toplevel = mangle_properties(toplevel, options.mangle.properties);
26101 }
26102 if (timings) timings.format = Date.now();
26103 var result = {};
26104 if (options.format.ast) {
26105 result.ast = toplevel;
26106 }
26107 if (!HOP(options.format, "code") || options.format.code) {
26108 if (options.sourceMap) {
26109 options.format.source_map = await SourceMap({
26110 file: options.sourceMap.filename,
26111 orig: options.sourceMap.content,
26112 root: options.sourceMap.root
26113 });
26114 if (options.sourceMap.includeSources) {
26115 if (files instanceof AST_Toplevel) {
26116 throw new Error("original source content unavailable");
26117 } else for (var name in files) if (HOP(files, name)) {
26118 options.format.source_map.get().setSourceContent(name, files[name]);
26119 }
26120 }
26121 }
26122 delete options.format.ast;
26123 delete options.format.code;
26124 var stream = OutputStream(options.format);
26125 toplevel.print(stream);
26126 result.code = stream.get();
26127 if (options.sourceMap) {
26128 if(options.sourceMap.asObject) {
26129 result.map = options.format.source_map.get().toJSON();
26130 } else {
26131 result.map = options.format.source_map.toString();
26132 }
26133 if (options.sourceMap.url == "inline") {
26134 var sourceMap = typeof result.map === "object" ? JSON.stringify(result.map) : result.map;
26135 result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(sourceMap);
26136 } else if (options.sourceMap.url) {
26137 result.code += "\n//# sourceMappingURL=" + options.sourceMap.url;
26138 }
26139 }
26140 }
26141 if (options.nameCache && options.mangle) {
26142 if (options.mangle.cache) options.nameCache.vars = cache_to_json(options.mangle.cache);
26143 if (options.mangle.properties && options.mangle.properties.cache) {
26144 options.nameCache.props = cache_to_json(options.mangle.properties.cache);
26145 }
26146 }
26147 if (options.format && options.format.source_map) {
26148 options.format.source_map.destroy();
26149 }
26150 if (timings) {
26151 timings.end = Date.now();
26152 result.timings = {
26153 parse: 1e-3 * (timings.rename - timings.parse),
26154 rename: 1e-3 * (timings.compress - timings.rename),
26155 compress: 1e-3 * (timings.scope - timings.compress),
26156 scope: 1e-3 * (timings.mangle - timings.scope),
26157 mangle: 1e-3 * (timings.properties - timings.mangle),
26158 properties: 1e-3 * (timings.format - timings.properties),
26159 format: 1e-3 * (timings.end - timings.format),
26160 total: 1e-3 * (timings.end - timings.start)
26161 };
26162 }
26163 return result;
26164}
26165
26166async function run_cli({ program, packageJson, fs, path }) {
26167 const skip_keys = new Set([ "cname", "parent_scope", "scope", "uses_eval", "uses_with" ]);
26168 var files = {};
26169 var options = {
26170 compress: false,
26171 mangle: false
26172 };
26173 const default_options = await _default_options();
26174 program.version(packageJson.name + " " + packageJson.version);
26175 program.parseArgv = program.parse;
26176 program.parse = undefined;
26177
26178 if (process.argv.includes("ast")) program.helpInformation = describe_ast;
26179 else if (process.argv.includes("options")) program.helpInformation = function() {
26180 var text = [];
26181 for (var option in default_options) {
26182 text.push("--" + (option === "sourceMap" ? "source-map" : option) + " options:");
26183 text.push(format_object(default_options[option]));
26184 text.push("");
26185 }
26186 return text.join("\n");
26187 };
26188
26189 program.option("-p, --parse <options>", "Specify parser options.", parse_js());
26190 program.option("-c, --compress [options]", "Enable compressor/specify compressor options.", parse_js());
26191 program.option("-m, --mangle [options]", "Mangle names/specify mangler options.", parse_js());
26192 program.option("--mangle-props [options]", "Mangle properties/specify mangler options.", parse_js());
26193 program.option("-f, --format [options]", "Format options.", parse_js());
26194 program.option("-b, --beautify [options]", "Alias for --format beautify=true.", parse_js());
26195 program.option("-o, --output <file>", "Output file (default STDOUT).");
26196 program.option("--comments [filter]", "Preserve copyright comments in the output.");
26197 program.option("--config-file <file>", "Read minify() options from JSON file.");
26198 program.option("-d, --define <expr>[=value]", "Global definitions.", parse_js("define"));
26199 program.option("--ecma <version>", "Specify ECMAScript release: 5, 2015, 2016 or 2017...");
26200 program.option("-e, --enclose [arg[,...][:value[,...]]]", "Embed output in a big function with configurable arguments and values.");
26201 program.option("--ie8", "Support non-standard Internet Explorer 8.");
26202 program.option("--keep-classnames", "Do not mangle/drop class names.");
26203 program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
26204 program.option("--module", "Input is an ES6 module");
26205 program.option("--name-cache <file>", "File to hold mangled name mappings.");
26206 program.option("--rename", "Force symbol expansion.");
26207 program.option("--no-rename", "Disable symbol expansion.");
26208 program.option("--safari10", "Support non-standard Safari 10.");
26209 program.option("--source-map [options]", "Enable source map/specify source map options.", parse_js());
26210 program.option("--timings", "Display operations run time on STDERR.");
26211 program.option("--toplevel", "Compress and/or mangle variables in toplevel scope.");
26212 program.option("--wrap <name>", "Embed everything as a function with “exports” corresponding to “name” globally.");
26213 program.arguments("[files...]").parseArgv(process.argv);
26214 if (program.configFile) {
26215 options = JSON.parse(read_file(program.configFile));
26216 }
26217 if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
26218 fatal("ERROR: cannot write source map to STDOUT");
26219 }
26220
26221 [
26222 "compress",
26223 "enclose",
26224 "ie8",
26225 "mangle",
26226 "module",
26227 "safari10",
26228 "sourceMap",
26229 "toplevel",
26230 "wrap"
26231 ].forEach(function(name) {
26232 if (name in program) {
26233 options[name] = program[name];
26234 }
26235 });
26236
26237 if ("ecma" in program) {
26238 if (program.ecma != (program.ecma | 0)) fatal("ERROR: ecma must be an integer");
26239 const ecma = program.ecma | 0;
26240 if (ecma > 5 && ecma < 2015)
26241 options.ecma = ecma + 2009;
26242 else
26243 options.ecma = ecma;
26244 }
26245 if (program.beautify || program.format) {
26246 if (program.beautify && program.format) {
26247 fatal("Please only specify one of --beautify or --format");
26248 }
26249 if (program.beautify) {
26250 options.format = typeof program.beautify == "object" ? program.beautify : {};
26251 if (!("beautify" in options.format)) {
26252 options.format.beautify = true;
26253 }
26254 }
26255 if (program.format) {
26256 options.format = typeof program.format == "object" ? program.format : {};
26257 }
26258 }
26259 if (program.comments) {
26260 if (typeof options.format != "object") options.format = {};
26261 options.format.comments = typeof program.comments == "string" ? (program.comments == "false" ? false : program.comments) : "some";
26262 }
26263 if (program.define) {
26264 if (typeof options.compress != "object") options.compress = {};
26265 if (typeof options.compress.global_defs != "object") options.compress.global_defs = {};
26266 for (var expr in program.define) {
26267 options.compress.global_defs[expr] = program.define[expr];
26268 }
26269 }
26270 if (program.keepClassnames) {
26271 options.keep_classnames = true;
26272 }
26273 if (program.keepFnames) {
26274 options.keep_fnames = true;
26275 }
26276 if (program.mangleProps) {
26277 if (program.mangleProps.domprops) {
26278 delete program.mangleProps.domprops;
26279 } else {
26280 if (typeof program.mangleProps != "object") program.mangleProps = {};
26281 if (!Array.isArray(program.mangleProps.reserved)) program.mangleProps.reserved = [];
26282 }
26283 if (typeof options.mangle != "object") options.mangle = {};
26284 options.mangle.properties = program.mangleProps;
26285 }
26286 if (program.nameCache) {
26287 options.nameCache = JSON.parse(read_file(program.nameCache, "{}"));
26288 }
26289 if (program.output == "ast") {
26290 options.format = {
26291 ast: true,
26292 code: false
26293 };
26294 }
26295 if (program.parse) {
26296 if (!program.parse.acorn && !program.parse.spidermonkey) {
26297 options.parse = program.parse;
26298 } else if (program.sourceMap && program.sourceMap.content == "inline") {
26299 fatal("ERROR: inline source map only works with built-in parser");
26300 }
26301 }
26302 if (~program.rawArgs.indexOf("--rename")) {
26303 options.rename = true;
26304 } else if (!program.rename) {
26305 options.rename = false;
26306 }
26307
26308 let convert_path = name => name;
26309 if (typeof program.sourceMap == "object" && "base" in program.sourceMap) {
26310 convert_path = function() {
26311 var base = program.sourceMap.base;
26312 delete options.sourceMap.base;
26313 return function(name) {
26314 return path.relative(base, name);
26315 };
26316 }();
26317 }
26318
26319 let filesList;
26320 if (options.files && options.files.length) {
26321 filesList = options.files;
26322
26323 delete options.files;
26324 } else if (program.args.length) {
26325 filesList = program.args;
26326 }
26327
26328 if (filesList) {
26329 simple_glob(filesList).forEach(function(name) {
26330 files[convert_path(name)] = read_file(name);
26331 });
26332 } else {
26333 await new Promise((resolve) => {
26334 var chunks = [];
26335 process.stdin.setEncoding("utf8");
26336 process.stdin.on("data", function(chunk) {
26337 chunks.push(chunk);
26338 }).on("end", function() {
26339 files = [ chunks.join("") ];
26340 resolve();
26341 });
26342 process.stdin.resume();
26343 });
26344 }
26345
26346 await run_cli();
26347
26348 function convert_ast(fn) {
26349 return AST_Node.from_mozilla_ast(Object.keys(files).reduce(fn, null));
26350 }
26351
26352 async function run_cli() {
26353 var content = program.sourceMap && program.sourceMap.content;
26354 if (content && content !== "inline") {
26355 options.sourceMap.content = read_file(content, content);
26356 }
26357 if (program.timings) options.timings = true;
26358
26359 try {
26360 if (program.parse) {
26361 if (program.parse.acorn) {
26362 files = convert_ast(function(toplevel, name) {
26363 return require("acorn").parse(files[name], {
26364 ecmaVersion: 2018,
26365 locations: true,
26366 program: toplevel,
26367 sourceFile: name,
26368 sourceType: options.module || program.parse.module ? "module" : "script"
26369 });
26370 });
26371 } else if (program.parse.spidermonkey) {
26372 files = convert_ast(function(toplevel, name) {
26373 var obj = JSON.parse(files[name]);
26374 if (!toplevel) return obj;
26375 toplevel.body = toplevel.body.concat(obj.body);
26376 return toplevel;
26377 });
26378 }
26379 }
26380 } catch (ex) {
26381 fatal(ex);
26382 }
26383
26384 let result;
26385 try {
26386 result = await minify(files, options);
26387 } catch (ex) {
26388 if (ex.name == "SyntaxError") {
26389 print_error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
26390 var col = ex.col;
26391 var lines = files[ex.filename].split(/\r?\n/);
26392 var line = lines[ex.line - 1];
26393 if (!line && !col) {
26394 line = lines[ex.line - 2];
26395 col = line.length;
26396 }
26397 if (line) {
26398 var limit = 70;
26399 if (col > limit) {
26400 line = line.slice(col - limit);
26401 col = limit;
26402 }
26403 print_error(line.slice(0, 80));
26404 print_error(line.slice(0, col).replace(/\S/g, " ") + "^");
26405 }
26406 }
26407 if (ex.defs) {
26408 print_error("Supported options:");
26409 print_error(format_object(ex.defs));
26410 }
26411 fatal(ex);
26412 return;
26413 }
26414
26415 if (program.output == "ast") {
26416 if (!options.compress && !options.mangle) {
26417 result.ast.figure_out_scope({});
26418 }
26419 console.log(JSON.stringify(result.ast, function(key, value) {
26420 if (value) switch (key) {
26421 case "thedef":
26422 return symdef(value);
26423 case "enclosed":
26424 return value.length ? value.map(symdef) : undefined;
26425 case "variables":
26426 case "functions":
26427 case "globals":
26428 return value.size ? collect_from_map(value, symdef) : undefined;
26429 }
26430 if (skip_keys.has(key)) return;
26431 if (value instanceof AST_Token) return;
26432 if (value instanceof Map) return;
26433 if (value instanceof AST_Node) {
26434 var result = {
26435 _class: "AST_" + value.TYPE
26436 };
26437 if (value.block_scope) {
26438 result.variables = value.block_scope.variables;
26439 result.functions = value.block_scope.functions;
26440 result.enclosed = value.block_scope.enclosed;
26441 }
26442 value.CTOR.PROPS.forEach(function(prop) {
26443 result[prop] = value[prop];
26444 });
26445 return result;
26446 }
26447 return value;
26448 }, 2));
26449 } else if (program.output == "spidermonkey") {
26450 try {
26451 const minified = await minify(result.code, {
26452 compress: false,
26453 mangle: false,
26454 format: {
26455 ast: true,
26456 code: false
26457 }
26458 });
26459 console.log(JSON.stringify(minified.ast.to_mozilla_ast(), null, 2));
26460 } catch (ex) {
26461 fatal(ex);
26462 return;
26463 }
26464 } else if (program.output) {
26465 fs.writeFileSync(program.output, result.code);
26466 if (options.sourceMap && options.sourceMap.url !== "inline" && result.map) {
26467 fs.writeFileSync(program.output + ".map", result.map);
26468 }
26469 } else {
26470 console.log(result.code);
26471 }
26472 if (program.nameCache) {
26473 fs.writeFileSync(program.nameCache, JSON.stringify(options.nameCache));
26474 }
26475 if (result.timings) for (var phase in result.timings) {
26476 print_error("- " + phase + ": " + result.timings[phase].toFixed(3) + "s");
26477 }
26478 }
26479
26480 function fatal(message) {
26481 if (message instanceof Error) message = message.stack.replace(/^\S*?Error:/, "ERROR:");
26482 print_error(message);
26483 process.exit(1);
26484 }
26485
26486 // A file glob function that only supports "*" and "?" wildcards in the basename.
26487 // Example: "foo/bar/*baz??.*.js"
26488 // Argument `glob` may be a string or an array of strings.
26489 // Returns an array of strings. Garbage in, garbage out.
26490 function simple_glob(glob) {
26491 if (Array.isArray(glob)) {
26492 return [].concat.apply([], glob.map(simple_glob));
26493 }
26494 if (glob && glob.match(/[*?]/)) {
26495 var dir = path.dirname(glob);
26496 try {
26497 var entries = fs.readdirSync(dir);
26498 } catch (ex) {}
26499 if (entries) {
26500 var pattern = "^" + path.basename(glob)
26501 .replace(/[.+^$[\]\\(){}]/g, "\\$&")
26502 .replace(/\*/g, "[^/\\\\]*")
26503 .replace(/\?/g, "[^/\\\\]") + "$";
26504 var mod = process.platform === "win32" ? "i" : "";
26505 var rx = new RegExp(pattern, mod);
26506 var results = entries.filter(function(name) {
26507 return rx.test(name);
26508 }).map(function(name) {
26509 return path.join(dir, name);
26510 });
26511 if (results.length) return results;
26512 }
26513 }
26514 return [ glob ];
26515 }
26516
26517 function read_file(path, default_value) {
26518 try {
26519 return fs.readFileSync(path, "utf8");
26520 } catch (ex) {
26521 if ((ex.code == "ENOENT" || ex.code == "ENAMETOOLONG") && default_value != null) return default_value;
26522 fatal(ex);
26523 }
26524 }
26525
26526 function parse_js(flag) {
26527 return function(value, options) {
26528 options = options || {};
26529 try {
26530 walk(parse(value, { expression: true }), node => {
26531 if (node instanceof AST_Assign) {
26532 var name = node.left.print_to_string();
26533 var value = node.right;
26534 if (flag) {
26535 options[name] = value;
26536 } else if (value instanceof AST_Array) {
26537 options[name] = value.elements.map(to_string);
26538 } else if (value instanceof AST_RegExp) {
26539 value = value.value;
26540 options[name] = new RegExp(value.source, value.flags);
26541 } else {
26542 options[name] = to_string(value);
26543 }
26544 return true;
26545 }
26546 if (node instanceof AST_Symbol || node instanceof AST_PropAccess) {
26547 var name = node.print_to_string();
26548 options[name] = true;
26549 return true;
26550 }
26551 if (!(node instanceof AST_Sequence)) throw node;
26552
26553 function to_string(value) {
26554 return value instanceof AST_Constant ? value.getValue() : value.print_to_string({
26555 quote_keys: true
26556 });
26557 }
26558 });
26559 } catch(ex) {
26560 if (flag) {
26561 fatal("Error parsing arguments for '" + flag + "': " + value);
26562 } else {
26563 options[value] = null;
26564 }
26565 }
26566 return options;
26567 };
26568 }
26569
26570 function symdef(def) {
26571 var ret = (1e6 + def.id) + " " + def.name;
26572 if (def.mangled_name) ret += " " + def.mangled_name;
26573 return ret;
26574 }
26575
26576 function collect_from_map(map, callback) {
26577 var result = [];
26578 map.forEach(function (def) {
26579 result.push(callback(def));
26580 });
26581 return result;
26582 }
26583
26584 function format_object(obj) {
26585 var lines = [];
26586 var padding = "";
26587 Object.keys(obj).map(function(name) {
26588 if (padding.length < name.length) padding = Array(name.length + 1).join(" ");
26589 return [ name, JSON.stringify(obj[name]) ];
26590 }).forEach(function(tokens) {
26591 lines.push(" " + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]);
26592 });
26593 return lines.join("\n");
26594 }
26595
26596 function print_error(msg) {
26597 process.stderr.write(msg);
26598 process.stderr.write("\n");
26599 }
26600
26601 function describe_ast() {
26602 var out = OutputStream({ beautify: true });
26603 function doitem(ctor) {
26604 out.print("AST_" + ctor.TYPE);
26605 const props = ctor.SELF_PROPS.filter(prop => !/^\$/.test(prop));
26606
26607 if (props.length > 0) {
26608 out.space();
26609 out.with_parens(function() {
26610 props.forEach(function(prop, i) {
26611 if (i) out.space();
26612 out.print(prop);
26613 });
26614 });
26615 }
26616
26617 if (ctor.documentation) {
26618 out.space();
26619 out.print_string(ctor.documentation);
26620 }
26621
26622 if (ctor.SUBCLASSES.length > 0) {
26623 out.space();
26624 out.with_block(function() {
26625 ctor.SUBCLASSES.forEach(function(ctor) {
26626 out.indent();
26627 doitem(ctor);
26628 out.newline();
26629 });
26630 });
26631 }
26632 }
26633 doitem(AST_Node);
26634 return out + "\n";
26635 }
26636}
26637
26638async function _default_options() {
26639 const defs = {};
26640
26641 Object.keys(infer_options({ 0: 0 })).forEach((component) => {
26642 const options = infer_options({
26643 [component]: {0: 0}
26644 });
26645
26646 if (options) defs[component] = options;
26647 });
26648 return defs;
26649}
26650
26651async function infer_options(options) {
26652 try {
26653 await minify("", options);
26654 } catch (error) {
26655 return error.defs;
26656 }
26657}
26658
26659exports._default_options = _default_options;
26660exports._run_cli = run_cli;
26661exports.minify = minify;
26662
26663})));
26664//# sourceMappingURL=bundle.min.js.map