source: frontend/node_modules/terser/dist/bundle.min.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 13 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 1.0 MB
Line 
1(function (global, factory) {
2typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@jridgewell/source-map')) :
3typeof define === 'function' && define.amd ? define(['exports', '@jridgewell/source-map'], factory) :
4(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Terser = {}, global.sourceMap));
5})(this, (function (exports, sourceMap) { 'use strict';
6
7/***********************************************************************
8
9 A JavaScript tokenizer / parser / beautifier / compressor.
10 https://github.com/mishoo/UglifyJS2
11
12 -------------------------------- (C) ---------------------------------
13
14 Author: Mihai Bazon
15 <mihai.bazon@gmail.com>
16 http://mihai.bazon.net/blog
17
18 Distributed under the BSD license:
19
20 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
21
22 Redistribution and use in source and binary forms, with or without
23 modification, are permitted provided that the following conditions
24 are met:
25
26 * Redistributions of source code must retain the above
27 copyright notice, this list of conditions and the following
28 disclaimer.
29
30 * Redistributions in binary form must reproduce the above
31 copyright notice, this list of conditions and the following
32 disclaimer in the documentation and/or other materials
33 provided with the distribution.
34
35 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
36 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
39 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
40 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
41 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
42 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
44 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
45 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46 SUCH DAMAGE.
47
48 ***********************************************************************/
49
50function characters(str) {
51 return str.split("");
52}
53
54function member(name, array) {
55 return array.includes(name);
56}
57
58class DefaultsError extends Error {
59 constructor(msg, defs) {
60 super();
61
62 this.name = "DefaultsError";
63 this.message = msg;
64 this.defs = defs;
65 }
66}
67
68function defaults(args, defs, croak) {
69 if (args === true) {
70 args = {};
71 } else if (args != null && typeof args === "object") {
72 args = {...args};
73 }
74
75 const ret = args || {};
76
77 if (croak) for (const i in ret) if (HOP(ret, i) && !HOP(defs, i)) {
78 throw new DefaultsError("`" + i + "` is not a supported option", defs);
79 }
80
81 for (const i in defs) if (HOP(defs, i)) {
82 if (!args || !HOP(args, i)) {
83 ret[i] = defs[i];
84 } else if (i === "ecma" || i === "builtins_ecma") {
85 let ecma = args[i] | 0;
86 if (ecma > 5 && ecma < 2015) ecma += 2009;
87 ret[i] = ecma;
88 } else {
89 ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
90 }
91 }
92
93 return ret;
94}
95
96function noop() {}
97function return_false() { return false; }
98function return_true() { return true; }
99function return_this() { return this; }
100function return_null() { return null; }
101
102var MAP = (function() {
103 function MAP(a, tw, allow_splicing = true) {
104 const new_a = [];
105
106 for (let i = 0; i < a.length; ++i) {
107 let item = a[i];
108 let ret = item.transform(tw, allow_splicing);
109
110 if (ret instanceof AST_Node) {
111 new_a.push(ret);
112 } else if (ret instanceof Splice) {
113 new_a.push(...ret.v);
114 }
115 }
116
117 return new_a;
118 }
119
120 MAP.splice = function(val) { return new Splice(val); };
121 MAP.skip = {};
122 function Splice(val) { this.v = val; }
123 return MAP;
124})();
125
126function make_node(ctor, orig, props) {
127 if (!props) props = {};
128 if (orig) {
129 if (!props.start) props.start = orig.start;
130 if (!props.end) props.end = orig.end;
131 }
132 return new ctor(props);
133}
134
135/** Makes a `void 0` expression. Use instead of AST_Undefined which may conflict
136 * with an existing variable called `undefined` */
137function make_void_0(orig) {
138 return make_node(AST_UnaryPrefix, orig, {
139 operator: "void",
140 expression: make_node(AST_Number, orig, { value: 0 })
141 });
142}
143
144function push_uniq(array, el) {
145 if (!array.includes(el))
146 array.push(el);
147}
148
149function string_template(text, props) {
150 return text.replace(/{(.+?)}/g, function(str, p) {
151 return props && props[p];
152 });
153}
154
155function remove(array, el) {
156 for (var i = array.length; --i >= 0;) {
157 if (array[i] === el) array.splice(i, 1);
158 }
159}
160
161function mergeSort(array, cmp) {
162 if (array.length < 2) return array.slice();
163 function merge(a, b) {
164 var r = [], ai = 0, bi = 0, i = 0;
165 while (ai < a.length && bi < b.length) {
166 cmp(a[ai], b[bi]) <= 0
167 ? r[i++] = a[ai++]
168 : r[i++] = b[bi++];
169 }
170 if (ai < a.length) r.push.apply(r, a.slice(ai));
171 if (bi < b.length) r.push.apply(r, b.slice(bi));
172 return r;
173 }
174 function _ms(a) {
175 if (a.length <= 1)
176 return a;
177 var m = Math.floor(a.length / 2), left = a.slice(0, m), right = a.slice(m);
178 left = _ms(left);
179 right = _ms(right);
180 return merge(left, right);
181 }
182 return _ms(array);
183}
184
185function makePredicate(words) {
186 if (!Array.isArray(words)) words = words.split(" ");
187
188 return new Set(words.sort());
189}
190
191function map_add(map, key, value) {
192 if (map.has(key)) {
193 map.get(key).push(value);
194 } else {
195 map.set(key, [ value ]);
196 }
197}
198
199function map_from_object(obj) {
200 var map = new Map();
201 for (var key in obj) {
202 if (HOP(obj, key) && key.charAt(0) === "$") {
203 map.set(key.substr(1), obj[key]);
204 }
205 }
206 return map;
207}
208
209function map_to_object(map) {
210 var obj = Object.create(null);
211 map.forEach(function (value, key) {
212 obj["$" + key] = value;
213 });
214 return obj;
215}
216
217function HOP(obj, prop) {
218 return Object.prototype.hasOwnProperty.call(obj, prop);
219}
220
221function keep_name(keep_setting, name) {
222 return keep_setting === true
223 || (keep_setting instanceof RegExp && keep_setting.test(name));
224}
225
226var lineTerminatorEscape = {
227 "\0": "0",
228 "\n": "n",
229 "\r": "r",
230 "\u2028": "u2028",
231 "\u2029": "u2029",
232};
233function regexp_source_fix(source) {
234 // V8 does not escape line terminators in regexp patterns in node 12
235 // We'll also remove literal \0
236 return source.replace(/[\0\n\r\u2028\u2029]/g, function (match, offset) {
237 var escaped = source[offset - 1] == "\\"
238 && (source[offset - 2] != "\\"
239 || /(?:^|[^\\])(?:\\{2})*$/.test(source.slice(0, offset - 1)));
240 return (escaped ? "" : "\\") + lineTerminatorEscape[match];
241 });
242}
243
244// Subset of regexps that is not going to cause regexp based DDOS
245// https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
246const re_safe_regexp = /^[\\/|\0\s\w^$.[\]()]*$/;
247
248/** Check if the regexp is safe for Terser to create without risking a RegExp DOS */
249const regexp_is_safe = (source) => re_safe_regexp.test(source);
250
251const all_flags = "dgimsuyv";
252function sort_regexp_flags(flags) {
253 const existing_flags = new Set(flags.split(""));
254 let out = "";
255 for (const flag of all_flags) {
256 if (existing_flags.has(flag)) {
257 out += flag;
258 existing_flags.delete(flag);
259 }
260 }
261 if (existing_flags.size) {
262 // Flags Terser doesn't know about
263 existing_flags.forEach(flag => { out += flag; });
264 }
265 return out;
266}
267
268function has_annotation(node, annotation) {
269 return node._annotations & annotation;
270}
271
272function set_annotation(node, annotation) {
273 node._annotations |= annotation;
274}
275
276function clear_annotation(node, annotation) {
277 node._annotations &= ~annotation;
278}
279
280/***********************************************************************
281
282 A JavaScript tokenizer / parser / beautifier / compressor.
283 https://github.com/mishoo/UglifyJS2
284
285 -------------------------------- (C) ---------------------------------
286
287 Author: Mihai Bazon
288 <mihai.bazon@gmail.com>
289 http://mihai.bazon.net/blog
290
291 Distributed under the BSD license:
292
293 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
294 Parser based on parse-js (http://marijn.haverbeke.nl/parse-js/).
295
296 Redistribution and use in source and binary forms, with or without
297 modification, are permitted provided that the following conditions
298 are met:
299
300 * Redistributions of source code must retain the above
301 copyright notice, this list of conditions and the following
302 disclaimer.
303
304 * Redistributions in binary form must reproduce the above
305 copyright notice, this list of conditions and the following
306 disclaimer in the documentation and/or other materials
307 provided with the distribution.
308
309 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
310 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
311 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
312 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
313 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
314 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
315 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
316 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
317 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
318 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
319 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
320 SUCH DAMAGE.
321
322 ***********************************************************************/
323
324var LATEST_RAW = ""; // Only used for numbers and template strings
325var TEMPLATE_RAWS = new Map(); // Raw template strings
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 import super this " + KEYWORDS_ATOM + " " + KEYWORDS;
330var ALL_RESERVED_WORDS = "implements interface package private protected public static " + RESERVED_WORDS;
331var KEYWORDS_BEFORE_EXPRESSION = "return new delete throw else case yield await";
332
333KEYWORDS = makePredicate(KEYWORDS);
334RESERVED_WORDS = makePredicate(RESERVED_WORDS);
335KEYWORDS_BEFORE_EXPRESSION = makePredicate(KEYWORDS_BEFORE_EXPRESSION);
336KEYWORDS_ATOM = makePredicate(KEYWORDS_ATOM);
337ALL_RESERVED_WORDS = makePredicate(ALL_RESERVED_WORDS);
338
339var OPERATOR_CHARS = makePredicate(characters("+-*&%=<>!?|~^"));
340
341var RE_HEX_NUMBER = /^0x[0-9a-f]+$/i;
342var RE_OCT_NUMBER = /^0[0-7]+$/;
343var RE_ES6_OCT_NUMBER = /^0o[0-7]+$/i;
344var RE_BIN_NUMBER = /^0b[01]+$/i;
345var RE_DEC_NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i;
346var RE_BIG_INT = /^(0[xob])?[0-9a-f]+n$/i;
347
348var RE_KEYWORD_RELATIONAL_OPERATORS = /in(?:stanceof)?/y;
349
350var OPERATORS = makePredicate([
351 "in",
352 "instanceof",
353 "typeof",
354 "new",
355 "void",
356 "delete",
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 "^=",
397 "&=",
398 "&&",
399 "??",
400 "||",
401]);
402
403var 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"));
404
405var NEWLINE_CHARS = makePredicate(characters("\n\r\u2028\u2029"));
406
407var PUNC_AFTER_EXPRESSION = makePredicate(characters(";]),:"));
408
409var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,;:"));
410
411var PUNC_CHARS = makePredicate(characters("[]{}(),;:"));
412
413/* -----[ Tokenizer ]----- */
414
415// surrogate safe regexps adapted from https://github.com/mathiasbynens/unicode-8.0.0/tree/89b412d8a71ecca9ed593d9e9fa073ab64acfebe/Binary_Property
416var UNICODE = {
417 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]/,
418 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])+/,
419};
420
421function get_full_char(str, pos) {
422 if (is_surrogate_pair_head(str.charCodeAt(pos))) {
423 if (is_surrogate_pair_tail(str.charCodeAt(pos + 1))) {
424 return str.charAt(pos) + str.charAt(pos + 1);
425 }
426 } else if (is_surrogate_pair_tail(str.charCodeAt(pos))) {
427 if (is_surrogate_pair_head(str.charCodeAt(pos - 1))) {
428 return str.charAt(pos - 1) + str.charAt(pos);
429 }
430 }
431 return str.charAt(pos);
432}
433
434function get_full_char_code(str, pos) {
435 // https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Surrogates
436 if (is_surrogate_pair_head(str.charCodeAt(pos))) {
437 return 0x10000 + (str.charCodeAt(pos) - 0xd800 << 10) + str.charCodeAt(pos + 1) - 0xdc00;
438 }
439 return str.charCodeAt(pos);
440}
441
442function get_full_char_length(str) {
443 var surrogates = 0;
444
445 for (var i = 0; i < str.length; i++) {
446 if (is_surrogate_pair_head(str.charCodeAt(i)) && is_surrogate_pair_tail(str.charCodeAt(i + 1))) {
447 surrogates++;
448 i++;
449 }
450 }
451
452 return str.length - surrogates;
453}
454
455function from_char_code(code) {
456 // Based on https://github.com/mathiasbynens/String.fromCodePoint/blob/master/fromcodepoint.js
457 if (code > 0xFFFF) {
458 code -= 0x10000;
459 return (String.fromCharCode((code >> 10) + 0xD800) +
460 String.fromCharCode((code % 0x400) + 0xDC00));
461 }
462 return String.fromCharCode(code);
463}
464
465function is_surrogate_pair_head(code) {
466 return code >= 0xd800 && code <= 0xdbff;
467}
468
469function is_surrogate_pair_tail(code) {
470 return code >= 0xdc00 && code <= 0xdfff;
471}
472
473function is_digit(code) {
474 return code >= 48 && code <= 57;
475}
476
477function is_identifier_start(ch) {
478 return UNICODE.ID_Start.test(ch);
479}
480
481function is_identifier_char(ch) {
482 return UNICODE.ID_Continue.test(ch);
483}
484
485const BASIC_IDENT = /^[a-z_$][a-z0-9_$]*$/i;
486
487function is_basic_identifier_string(str) {
488 return BASIC_IDENT.test(str);
489}
490
491function is_identifier_string(str, allow_surrogates) {
492 if (BASIC_IDENT.test(str)) {
493 return true;
494 }
495 if (!allow_surrogates && /[\ud800-\udfff]/.test(str)) {
496 return false;
497 }
498 var match = UNICODE.ID_Start.exec(str);
499 if (!match || match.index !== 0) {
500 return false;
501 }
502
503 str = str.slice(match[0].length);
504 if (!str) {
505 return true;
506 }
507
508 match = UNICODE.ID_Continue.exec(str);
509 return !!match && match[0].length === str.length;
510}
511
512function parse_js_number(num, allow_e = true) {
513 if (!allow_e && num.includes("e")) {
514 return NaN;
515 }
516 if (RE_HEX_NUMBER.test(num)) {
517 return parseInt(num.substr(2), 16);
518 } else if (RE_OCT_NUMBER.test(num)) {
519 return parseInt(num.substr(1), 8);
520 } else if (RE_ES6_OCT_NUMBER.test(num)) {
521 return parseInt(num.substr(2), 8);
522 } else if (RE_BIN_NUMBER.test(num)) {
523 return parseInt(num.substr(2), 2);
524 } else if (RE_DEC_NUMBER.test(num)) {
525 return parseFloat(num);
526 } else {
527 var val = parseFloat(num);
528 if (val == num) return val;
529 }
530}
531
532class JS_Parse_Error extends Error {
533 constructor(message, filename, line, col, pos) {
534 super();
535
536 this.name = "SyntaxError";
537 this.message = message;
538 this.filename = filename;
539 this.line = line;
540 this.col = col;
541 this.pos = pos;
542 }
543}
544
545function js_error(message, filename, line, col, pos) {
546 throw new JS_Parse_Error(message, filename, line, col, pos);
547}
548
549function is_token(token, type, val) {
550 return token.type == type && (val == null || token.value == val);
551}
552
553var EX_EOF = {};
554
555function tokenizer($TEXT, filename, html5_comments, shebang) {
556 var S = {
557 text : $TEXT,
558 filename : filename,
559 pos : 0,
560 tokpos : 0,
561 line : 1,
562 tokline : 0,
563 col : 0,
564 tokcol : 0,
565 newline_before : false,
566 regex_allowed : false,
567 brace_counter : 0,
568 template_braces : [],
569 comments_before : [],
570 directives : {},
571 directive_stack : []
572 };
573
574 function peek() { return get_full_char(S.text, S.pos); }
575
576 // Used because parsing ?. involves a lookahead for a digit
577 function is_option_chain_op() {
578 const must_be_dot = S.text.charCodeAt(S.pos + 1) === 46;
579 if (!must_be_dot) return false;
580
581 const cannot_be_digit = S.text.charCodeAt(S.pos + 2);
582 return cannot_be_digit < 48 || cannot_be_digit > 57;
583 }
584
585 function next(signal_eof, in_string) {
586 var ch = get_full_char(S.text, S.pos++);
587 if (signal_eof && !ch)
588 throw EX_EOF;
589 if (NEWLINE_CHARS.has(ch)) {
590 S.newline_before = S.newline_before || !in_string;
591 ++S.line;
592 S.col = 0;
593 if (ch == "\r" && peek() == "\n") {
594 // treat a \r\n sequence as a single \n
595 ++S.pos;
596 ch = "\n";
597 }
598 } else {
599 if (ch.length > 1) {
600 ++S.pos;
601 ++S.col;
602 }
603 ++S.col;
604 }
605 return ch;
606 }
607
608 function forward(i) {
609 while (i--) next();
610 }
611
612 function looking_at(str) {
613 return S.text.substr(S.pos, str.length) == str;
614 }
615
616 function find_eol() {
617 var text = S.text;
618 for (var i = S.pos, n = S.text.length; i < n; ++i) {
619 var ch = text[i];
620 if (NEWLINE_CHARS.has(ch))
621 return i;
622 }
623 return -1;
624 }
625
626 function find(what, signal_eof) {
627 var pos = S.text.indexOf(what, S.pos);
628 if (signal_eof && pos == -1) throw EX_EOF;
629 return pos;
630 }
631
632 function start_token() {
633 S.tokline = S.line;
634 S.tokcol = S.col;
635 S.tokpos = S.pos;
636 }
637
638 var prev_was_dot = false;
639 var previous_token = null;
640 function token(type, value, is_comment) {
641 S.regex_allowed = ((type == "operator" && !UNARY_POSTFIX.has(value)) ||
642 (type == "keyword" && KEYWORDS_BEFORE_EXPRESSION.has(value)) ||
643 (type == "punc" && PUNC_BEFORE_EXPRESSION.has(value))) ||
644 (type == "arrow");
645 if (type == "punc" && (value == "." || value == "?.")) {
646 prev_was_dot = true;
647 } else if (!is_comment) {
648 prev_was_dot = false;
649 }
650 const line = S.tokline;
651 const col = S.tokcol;
652 const pos = S.tokpos;
653 const nlb = S.newline_before;
654 const file = filename;
655 let comments_before = [];
656 let comments_after = [];
657
658 if (!is_comment) {
659 comments_before = S.comments_before;
660 comments_after = S.comments_before = [];
661 }
662 S.newline_before = false;
663 const tok = new AST_Token(type, value, line, col, pos, nlb, comments_before, comments_after, file);
664
665 if (!is_comment) previous_token = tok;
666 return tok;
667 }
668
669 function skip_whitespace() {
670 while (WHITESPACE_CHARS.has(peek()))
671 next();
672 }
673
674 function peek_next_token_start_or_newline() {
675 var pos = S.pos;
676 for (var in_multiline_comment = false; pos < S.text.length; ) {
677 var ch = get_full_char(S.text, pos);
678 if (NEWLINE_CHARS.has(ch)) {
679 return { char: ch, pos: pos };
680 } else if (in_multiline_comment) {
681 if (ch == "*" && get_full_char(S.text, pos + 1) == "/") {
682 pos += 2;
683 in_multiline_comment = false;
684 } else {
685 pos++;
686 }
687 } else if (!WHITESPACE_CHARS.has(ch)) {
688 if (ch == "/") {
689 var next_ch = get_full_char(S.text, pos + 1);
690 if (next_ch == "/") {
691 pos = find_eol();
692 return { char: get_full_char(S.text, pos), pos: pos };
693 } else if (next_ch == "*") {
694 in_multiline_comment = true;
695 pos += 2;
696 continue;
697 }
698 }
699 return { char: ch, pos: pos };
700 } else {
701 pos++;
702 }
703 }
704 return { char: null, pos: pos };
705 }
706
707 function ch_starts_binding_identifier(ch, pos) {
708 if (ch == "\\") {
709 return true;
710 } else if (is_identifier_start(ch)) {
711 RE_KEYWORD_RELATIONAL_OPERATORS.lastIndex = pos;
712 if (RE_KEYWORD_RELATIONAL_OPERATORS.test(S.text)) {
713 var after = get_full_char(S.text, RE_KEYWORD_RELATIONAL_OPERATORS.lastIndex);
714 if (!is_identifier_char(after) && after != "\\") {
715 // "in" or "instanceof" are keywords, not binding identifiers
716 return false;
717 }
718 }
719 return true;
720 }
721 return false;
722 }
723
724 function read_while(pred) {
725 var ret = "", ch, i = 0;
726 while ((ch = peek()) && pred(ch, i++))
727 ret += next();
728 return ret;
729 }
730
731 function parse_error(err) {
732 js_error(err, filename, S.tokline, S.tokcol, S.tokpos);
733 }
734
735 function read_num(prefix) {
736 var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".", is_big_int = false, numeric_separator = false;
737 var num = read_while(function(ch, i) {
738 if (is_big_int) return false;
739
740 var code = ch.charCodeAt(0);
741 switch (code) {
742 case 95: // _
743 return (numeric_separator = true);
744 case 98: case 66: // bB
745 return (has_x = true); // Can occur in hex sequence, don't return false yet
746 case 111: case 79: // oO
747 case 120: case 88: // xX
748 return has_x ? false : (has_x = true);
749 case 101: case 69: // eE
750 return has_x ? true : has_e ? false : (has_e = after_e = true);
751 case 45: // -
752 return after_e || (i == 0 && !prefix);
753 case 43: // +
754 return after_e;
755 case (after_e = false, 46): // .
756 return (!has_dot && !has_x && !has_e) ? (has_dot = true) : false;
757 case 110: // n
758 is_big_int = true;
759 return true;
760 }
761
762 return (
763 code >= 48 && code <= 57 // 0-9
764 || code >= 97 && code <= 102 // a-f
765 || code >= 65 && code <= 70 // A-F
766 );
767 });
768 if (prefix) num = prefix + num;
769
770 LATEST_RAW = num;
771
772 if (RE_OCT_NUMBER.test(num) && next_token.has_directive("use strict")) {
773 parse_error("Legacy octal literals are not allowed in strict mode");
774 }
775 if (numeric_separator) {
776 if (num.endsWith("_")) {
777 parse_error("Numeric separators are not allowed at the end of numeric literals");
778 } else if (num.includes("__")) {
779 parse_error("Only one underscore is allowed as numeric separator");
780 }
781 num = num.replace(/_/g, "");
782 }
783 if (is_big_int) {
784 const without_n = num.slice(0, -1);
785 const allow_e = RE_HEX_NUMBER.test(without_n);
786 const valid = parse_js_number(without_n, allow_e);
787 if (!has_dot && RE_BIG_INT.test(num) && !isNaN(valid))
788 return token("big_int", without_n);
789 parse_error("Invalid or unexpected token");
790 }
791 var valid = parse_js_number(num);
792 if (!isNaN(valid)) {
793 return token("num", valid);
794 } else {
795 parse_error("Invalid syntax: " + num);
796 }
797 }
798
799 function is_octal(ch) {
800 return ch >= "0" && ch <= "7";
801 }
802
803 function read_escaped_char(in_string, strict_hex, template_string) {
804 var ch = next(true, in_string);
805 switch (ch.charCodeAt(0)) {
806 case 110 : return "\n";
807 case 114 : return "\r";
808 case 116 : return "\t";
809 case 98 : return "\b";
810 case 118 : return "\u000b"; // \v
811 case 102 : return "\f";
812 case 120 : return String.fromCharCode(hex_bytes(2, strict_hex)); // \x
813 case 117 : // \u
814 if (peek() == "{") {
815 next(true);
816 if (peek() === "}")
817 parse_error("Expecting hex-character between {}");
818 while (peek() == "0") next(true); // No significance
819 var result, length = find("}", true) - S.pos;
820 // Avoid 32 bit integer overflow (1 << 32 === 1)
821 // We know first character isn't 0 and thus out of range anyway
822 if (length > 6 || (result = hex_bytes(length, strict_hex)) > 0x10FFFF) {
823 parse_error("Unicode reference out of bounds");
824 }
825 next(true);
826 return from_char_code(result);
827 }
828 return String.fromCharCode(hex_bytes(4, strict_hex));
829 case 10 : return ""; // newline
830 case 13 : // \r
831 if (peek() == "\n") { // DOS newline
832 next(true, in_string);
833 return "";
834 }
835 }
836 if (is_octal(ch)) {
837 if (template_string && strict_hex) {
838 const represents_null_character = ch === "0" && !is_octal(peek());
839 if (!represents_null_character) {
840 parse_error("Octal escape sequences are not allowed in template strings");
841 }
842 }
843 return read_octal_escape_sequence(ch, strict_hex);
844 }
845 return ch;
846 }
847
848 function read_octal_escape_sequence(ch, strict_octal) {
849 // Read
850 var p = peek();
851 if (p >= "0" && p <= "7") {
852 ch += next(true);
853 if (ch[0] <= "3" && (p = peek()) >= "0" && p <= "7")
854 ch += next(true);
855 }
856
857 // Parse
858 if (ch === "0") return "\0";
859 if (ch.length > 0 && next_token.has_directive("use strict") && strict_octal)
860 parse_error("Legacy octal escape sequences are not allowed in strict mode");
861 return String.fromCharCode(parseInt(ch, 8));
862 }
863
864 function hex_bytes(n, strict_hex) {
865 var num = 0;
866 for (; n > 0; --n) {
867 if (!strict_hex && isNaN(parseInt(peek(), 16))) {
868 return parseInt(num, 16) || "";
869 }
870 var digit = next(true);
871 if (isNaN(parseInt(digit, 16)))
872 parse_error("Invalid hex-character pattern in string");
873 num += digit;
874 }
875 return parseInt(num, 16);
876 }
877
878 var read_string = with_eof_error("Unterminated string constant", function() {
879 const start_pos = S.pos;
880 var quote = next(), ret = [];
881 for (;;) {
882 var ch = next(true, true);
883 if (ch == "\\") ch = read_escaped_char(true, true);
884 else if (ch == "\r" || ch == "\n") parse_error("Unterminated string constant");
885 else if (ch == quote) break;
886 ret.push(ch);
887 }
888 var tok = token("string", ret.join(""));
889 LATEST_RAW = S.text.slice(start_pos, S.pos);
890 tok.quote = quote;
891 return tok;
892 });
893
894 var read_template_characters = with_eof_error("Unterminated template", function(begin) {
895 if (begin) {
896 S.template_braces.push(S.brace_counter);
897 }
898 var content = "", raw = "", ch, tok;
899 next(true, true);
900 while ((ch = next(true, true)) != "`") {
901 if (ch == "\r") {
902 if (peek() == "\n") ++S.pos;
903 ch = "\n";
904 } else if (ch == "$" && peek() == "{") {
905 next(true, true);
906 S.brace_counter++;
907 tok = token(begin ? "template_head" : "template_cont", content);
908 TEMPLATE_RAWS.set(tok, raw);
909 tok.template_end = false;
910 return tok;
911 }
912
913 raw += ch;
914 if (ch == "\\") {
915 var tmp = S.pos;
916 var prev_is_tag = previous_token && (previous_token.type === "name" || previous_token.type === "punc" && (previous_token.value === ")" || previous_token.value === "]"));
917 ch = read_escaped_char(true, !prev_is_tag, true);
918 raw += S.text.substr(tmp, S.pos - tmp);
919 }
920
921 content += ch;
922 }
923 S.template_braces.pop();
924 tok = token(begin ? "template_head" : "template_cont", content);
925 TEMPLATE_RAWS.set(tok, raw);
926 tok.template_end = true;
927 return tok;
928 });
929
930 function skip_line_comment(type) {
931 var regex_allowed = S.regex_allowed;
932 var i = find_eol(), ret;
933 if (i == -1) {
934 ret = S.text.substr(S.pos);
935 S.pos = S.text.length;
936 } else {
937 ret = S.text.substring(S.pos, i);
938 S.pos = i;
939 }
940 S.col = S.tokcol + (S.pos - S.tokpos);
941 S.comments_before.push(token(type, ret, true));
942 S.regex_allowed = regex_allowed;
943 return next_token;
944 }
945
946 var skip_multiline_comment = with_eof_error("Unterminated multiline comment", function() {
947 var regex_allowed = S.regex_allowed;
948 var i = find("*/", true);
949 var text = S.text.substring(S.pos, i).replace(/\r\n|\r|\u2028|\u2029/g, "\n");
950 // update stream position
951 forward(get_full_char_length(text) /* text length doesn't count \r\n as 2 char while S.pos - i does */ + 2);
952 S.comments_before.push(token("comment2", text, true));
953 S.newline_before = S.newline_before || text.includes("\n");
954 S.regex_allowed = regex_allowed;
955 return next_token;
956 });
957
958 var read_name = function () {
959 let start = S.pos, end = start - 1, ch = "c";
960
961 while (
962 (ch = S.text.charAt(++end))
963 && (ch >= "a" && ch <= "z" || ch >= "A" && ch <= "Z")
964 );
965
966 // 0x7F is very rare in actual code, so we compare it to "~" (0x7E)
967 if (end > start + 1 && ch && ch !== "\\" && !is_identifier_char(ch) && ch <= "~") {
968 S.pos += end - start;
969 S.col += end - start;
970 return S.text.slice(start, S.pos);
971 }
972
973 return read_name_hard();
974 };
975
976 var read_name_hard = with_eof_error("Unterminated identifier name", function() {
977 var name = [], ch, escaped = false;
978 var read_escaped_identifier_char = function() {
979 escaped = true;
980 next();
981 if (peek() !== "u") {
982 parse_error("Expecting UnicodeEscapeSequence -- uXXXX or u{XXXX}");
983 }
984 return read_escaped_char(false, true);
985 };
986
987 // Read first character (ID_Start)
988 if ((ch = peek()) === "\\") {
989 ch = read_escaped_identifier_char();
990 if (!is_identifier_start(ch)) {
991 parse_error("First identifier char is an invalid identifier char");
992 }
993 } else if (is_identifier_start(ch)) {
994 next();
995 } else {
996 return "";
997 }
998
999 name.push(ch);
1000
1001 // Read ID_Continue
1002 while ((ch = peek()) != null) {
1003 if ((ch = peek()) === "\\") {
1004 ch = read_escaped_identifier_char();
1005 if (!is_identifier_char(ch)) {
1006 parse_error("Invalid escaped identifier char");
1007 }
1008 } else {
1009 if (!is_identifier_char(ch)) {
1010 break;
1011 }
1012 next();
1013 }
1014 name.push(ch);
1015 }
1016 const name_str = name.join("");
1017 if (RESERVED_WORDS.has(name_str) && escaped) {
1018 parse_error("Escaped characters are not allowed in keywords");
1019 }
1020 return name_str;
1021 });
1022
1023 var read_regexp = with_eof_error("Unterminated regular expression", function(source) {
1024 var prev_backslash = false, ch, in_class = false;
1025 while ((ch = next(true))) if (NEWLINE_CHARS.has(ch)) {
1026 parse_error("Unexpected line terminator");
1027 } else if (prev_backslash) {
1028 if (/^[\u0000-\u007F]$/.test(ch)) {
1029 source += "\\" + ch;
1030 } else {
1031 // Remove the useless slash before the escape, but only for characters that won't be added to regexp syntax
1032 source += ch;
1033 }
1034 prev_backslash = false;
1035 } else if (ch == "[") {
1036 in_class = true;
1037 source += ch;
1038 } else if (ch == "]" && in_class) {
1039 in_class = false;
1040 source += ch;
1041 } else if (ch == "/" && !in_class) {
1042 break;
1043 } else if (ch == "\\") {
1044 prev_backslash = true;
1045 } else {
1046 source += ch;
1047 }
1048 const flags = read_name();
1049 return token("regexp", "/" + source + "/" + flags);
1050 });
1051
1052 function read_operator(prefix) {
1053 function grow(op) {
1054 if (!peek()) return op;
1055 var bigger = op + peek();
1056 if (OPERATORS.has(bigger)) {
1057 next();
1058 return grow(bigger);
1059 } else {
1060 return op;
1061 }
1062 }
1063 return token("operator", grow(prefix || next()));
1064 }
1065
1066 function handle_slash() {
1067 next();
1068 switch (peek()) {
1069 case "/":
1070 next();
1071 return skip_line_comment("comment1");
1072 case "*":
1073 next();
1074 return skip_multiline_comment();
1075 }
1076 return S.regex_allowed ? read_regexp("") : read_operator("/");
1077 }
1078
1079 function handle_eq_sign() {
1080 next();
1081 if (peek() === ">") {
1082 next();
1083 return token("arrow", "=>");
1084 } else {
1085 return read_operator("=");
1086 }
1087 }
1088
1089 function handle_dot() {
1090 next();
1091 if (is_digit(peek().charCodeAt(0))) {
1092 return read_num(".");
1093 }
1094 if (peek() === ".") {
1095 next(); // Consume second dot
1096 next(); // Consume third dot
1097 return token("expand", "...");
1098 }
1099
1100 return token("punc", ".");
1101 }
1102
1103 function read_word() {
1104 var word = read_name();
1105 if (prev_was_dot) return token("name", word);
1106 return KEYWORDS_ATOM.has(word) ? token("atom", word)
1107 : !KEYWORDS.has(word) ? token("name", word)
1108 : OPERATORS.has(word) ? token("operator", word)
1109 : token("keyword", word);
1110 }
1111
1112 function read_private_word() {
1113 next();
1114 return token("privatename", read_name());
1115 }
1116
1117 function with_eof_error(eof_error, cont) {
1118 return function(x) {
1119 try {
1120 return cont(x);
1121 } catch(ex) {
1122 if (ex === EX_EOF) parse_error(eof_error);
1123 else throw ex;
1124 }
1125 };
1126 }
1127
1128 function next_token(force_regexp) {
1129 if (force_regexp != null)
1130 return read_regexp(force_regexp);
1131 if (shebang && S.pos == 0 && looking_at("#!")) {
1132 start_token();
1133 forward(2);
1134 skip_line_comment("comment5");
1135 }
1136 for (;;) {
1137 skip_whitespace();
1138 start_token();
1139 if (html5_comments) {
1140 if (looking_at("<!--")) {
1141 forward(4);
1142 skip_line_comment("comment3");
1143 continue;
1144 }
1145 if (looking_at("-->") && S.newline_before) {
1146 forward(3);
1147 skip_line_comment("comment4");
1148 continue;
1149 }
1150 }
1151 var ch = peek();
1152 if (!ch) return token("eof");
1153 var code = ch.charCodeAt(0);
1154 switch (code) {
1155 case 34: case 39: return read_string();
1156 case 46: return handle_dot();
1157 case 47: {
1158 var tok = handle_slash();
1159 if (tok === next_token) continue;
1160 return tok;
1161 }
1162 case 61: return handle_eq_sign();
1163 case 63: {
1164 if (!is_option_chain_op()) break; // Handled below
1165
1166 next(); // ?
1167 next(); // .
1168
1169 return token("punc", "?.");
1170 }
1171 case 96: return read_template_characters(true);
1172 case 123:
1173 S.brace_counter++;
1174 break;
1175 case 125:
1176 S.brace_counter--;
1177 if (S.template_braces.length > 0
1178 && S.template_braces[S.template_braces.length - 1] === S.brace_counter)
1179 return read_template_characters(false);
1180 break;
1181 }
1182 if (is_digit(code)) return read_num();
1183 if (PUNC_CHARS.has(ch)) return token("punc", next());
1184 if (OPERATOR_CHARS.has(ch)) return read_operator();
1185 if (code == 92 || is_identifier_start(ch)) return read_word();
1186 if (code == 35) return read_private_word();
1187 break;
1188 }
1189 parse_error("Unexpected character '" + ch + "'");
1190 }
1191
1192 next_token.next = next;
1193 next_token.peek = peek;
1194
1195 next_token.context = function(nc) {
1196 if (nc) S = nc;
1197 return S;
1198 };
1199
1200 next_token.add_directive = function(directive) {
1201 S.directive_stack[S.directive_stack.length - 1].push(directive);
1202
1203 if (S.directives[directive] === undefined) {
1204 S.directives[directive] = 1;
1205 } else {
1206 S.directives[directive]++;
1207 }
1208 };
1209
1210 next_token.push_directives_stack = function() {
1211 S.directive_stack.push([]);
1212 };
1213
1214 next_token.pop_directives_stack = function() {
1215 var directives = S.directive_stack[S.directive_stack.length - 1];
1216
1217 for (var i = 0; i < directives.length; i++) {
1218 S.directives[directives[i]]--;
1219 }
1220
1221 S.directive_stack.pop();
1222 };
1223
1224 next_token.has_directive = function(directive) {
1225 return S.directives[directive] > 0;
1226 };
1227
1228 next_token.peek_next_token_start_or_newline = peek_next_token_start_or_newline;
1229 next_token.ch_starts_binding_identifier = ch_starts_binding_identifier;
1230
1231 return next_token;
1232
1233}
1234
1235/* -----[ Parser (constants) ]----- */
1236
1237var UNARY_PREFIX = makePredicate([
1238 "typeof",
1239 "void",
1240 "delete",
1241 "--",
1242 "++",
1243 "!",
1244 "~",
1245 "-",
1246 "+"
1247]);
1248
1249var UNARY_POSTFIX = makePredicate([ "--", "++" ]);
1250
1251var ASSIGNMENT = makePredicate([ "=", "+=", "-=", "??=", "&&=", "||=", "/=", "*=", "**=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=" ]);
1252
1253var LOGICAL_ASSIGNMENT = makePredicate([ "??=", "&&=", "||=" ]);
1254
1255var PRECEDENCE = (function(a, ret) {
1256 for (var i = 0; i < a.length; ++i) {
1257 for (const op of a[i]) {
1258 ret[op] = i + 1;
1259 }
1260 }
1261 return ret;
1262})(
1263 [
1264 ["||"],
1265 ["??"],
1266 ["&&"],
1267 ["|"],
1268 ["^"],
1269 ["&"],
1270 ["==", "===", "!=", "!=="],
1271 ["<", ">", "<=", ">=", "in", "instanceof"],
1272 [">>", "<<", ">>>"],
1273 ["+", "-"],
1274 ["*", "/", "%"],
1275 ["**"]
1276 ],
1277 {}
1278);
1279
1280var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "big_int", "string", "regexp", "name"]);
1281
1282/* -----[ Parser ]----- */
1283
1284function parse($TEXT, options) {
1285 // maps start tokens to count of comments found outside of their parens
1286 // Example: /* I count */ ( /* I don't */ foo() )
1287 // Useful because comments_before property of call with parens outside
1288 // contains both comments inside and outside these parens. Used to find the
1289
1290 const outer_comments_before_counts = new WeakMap();
1291
1292 options = defaults(options, {
1293 bare_returns : false,
1294 ecma : null, // Legacy
1295 expression : false,
1296 filename : null,
1297 html5_comments : true,
1298 module : false,
1299 shebang : true,
1300 strict : false,
1301 toplevel : null,
1302 }, true);
1303
1304 var S = {
1305 input : (typeof $TEXT == "string"
1306 ? tokenizer($TEXT, options.filename,
1307 options.html5_comments, options.shebang)
1308 : $TEXT),
1309 token : null,
1310 prev : null,
1311 peeked : null,
1312 in_function : 0,
1313 in_async : -1,
1314 in_generator : -1,
1315 in_directives : true,
1316 in_loop : 0,
1317 labels : []
1318 };
1319
1320 S.token = next();
1321
1322 function is(type, value) {
1323 return is_token(S.token, type, value);
1324 }
1325
1326 function peek() { return S.peeked || (S.peeked = S.input()); }
1327
1328 function next() {
1329 S.prev = S.token;
1330
1331 if (!S.peeked) peek();
1332 S.token = S.peeked;
1333 S.peeked = null;
1334 S.in_directives = S.in_directives && (
1335 S.token.type == "string" || is("punc", ";")
1336 );
1337 return S.token;
1338 }
1339
1340 function prev() {
1341 return S.prev;
1342 }
1343
1344 function croak(msg, line, col, pos) {
1345 var ctx = S.input.context();
1346 js_error(msg,
1347 ctx.filename,
1348 line != null ? line : ctx.tokline,
1349 col != null ? col : ctx.tokcol,
1350 pos != null ? pos : ctx.tokpos);
1351 }
1352
1353 function token_error(token, msg) {
1354 croak(msg, token.line, token.col);
1355 }
1356
1357 function unexpected(token) {
1358 if (token == null)
1359 token = S.token;
1360 token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")");
1361 }
1362
1363 function expect_token(type, val) {
1364 if (is(type, val)) {
1365 return next();
1366 }
1367 token_error(S.token, "Unexpected token " + S.token.type + " «" + S.token.value + "»" + ", expected " + type + " «" + val + "»");
1368 }
1369
1370 function expect(punc) { return expect_token("punc", punc); }
1371
1372 function has_newline_before(token) {
1373 return token.nlb || !token.comments_before.every((comment) => !comment.nlb);
1374 }
1375
1376 function can_insert_semicolon() {
1377 return !options.strict
1378 && (is("eof") || is("punc", "}") || has_newline_before(S.token));
1379 }
1380
1381 function is_in_generator() {
1382 return S.in_generator === S.in_function;
1383 }
1384
1385 function is_in_async() {
1386 return S.in_async === S.in_function;
1387 }
1388
1389 function can_await() {
1390 return (
1391 S.in_async === S.in_function
1392 || S.in_function === 0 && S.input.has_directive("use strict")
1393 );
1394 }
1395
1396 function semicolon(optional) {
1397 if (is("punc", ";")) next();
1398 else if (!optional && !can_insert_semicolon()) unexpected();
1399 }
1400
1401 function parenthesised() {
1402 expect("(");
1403 var exp = expression(true);
1404 expect(")");
1405 return exp;
1406 }
1407
1408 function embed_tokens(parser) {
1409 return function _embed_tokens_wrapper(...args) {
1410 const start = S.token;
1411 const expr = parser(...args);
1412 expr.start = start;
1413 expr.end = prev();
1414 return expr;
1415 };
1416 }
1417
1418 function handle_regexp() {
1419 if (is("operator", "/") || is("operator", "/=")) {
1420 S.peeked = null;
1421 S.token = S.input(S.token.value.substr(1)); // force regexp
1422 }
1423 }
1424
1425 var statement = embed_tokens(function statement(is_export_default, is_for_body, is_if_body) {
1426 handle_regexp();
1427 switch (S.token.type) {
1428 case "string":
1429 if (S.in_directives) {
1430 var token = peek();
1431 if (!LATEST_RAW.includes("\\")
1432 && (is_token(token, "punc", ";")
1433 || is_token(token, "punc", "}")
1434 || has_newline_before(token)
1435 || is_token(token, "eof"))) {
1436 S.input.add_directive(S.token.value);
1437 } else {
1438 S.in_directives = false;
1439 }
1440 }
1441 var dir = S.in_directives, stat = simple_statement();
1442 return dir && stat.body instanceof AST_String ? new AST_Directive(stat.body) : stat;
1443 case "template_head":
1444 case "num":
1445 case "big_int":
1446 case "regexp":
1447 case "operator":
1448 case "atom":
1449 return simple_statement();
1450
1451 case "name":
1452 if (S.token.value == "async" && is_token(peek(), "keyword", "function")) {
1453 next();
1454 next();
1455 if (is_for_body) {
1456 croak("functions are not allowed as the body of a loop");
1457 }
1458 return function_(AST_Defun, false, true, is_export_default);
1459 }
1460 if (S.token.value == "import" && !is_token(peek(), "punc", "(") && !is_token(peek(), "punc", ".")) {
1461 next();
1462 var node = import_statement();
1463 semicolon();
1464 return node;
1465 }
1466 if (S.token.value == "using" && is_token(peek(), "name") && !has_newline_before(peek())) {
1467 next();
1468 var node = using_();
1469 semicolon();
1470 return node;
1471 }
1472 if (S.token.value == "await" && can_await() && is_token(peek(), "name", "using") && !has_newline_before(peek())) {
1473 var next_next = S.input.peek_next_token_start_or_newline();
1474 if (S.input.ch_starts_binding_identifier(next_next.char, next_next.pos)) {
1475 next();
1476 // The "using" token will be consumed by the await_using_ function.
1477 var node = await_using_();
1478 semicolon();
1479 return node;
1480 }
1481 }
1482 return is_token(peek(), "punc", ":")
1483 ? labeled_statement()
1484 : simple_statement();
1485
1486 case "privatename":
1487 if(!S.in_class)
1488 croak("Private field must be used in an enclosing class");
1489 return simple_statement();
1490
1491 case "punc":
1492 switch (S.token.value) {
1493 case "{":
1494 return new AST_BlockStatement({
1495 start : S.token,
1496 body : block_(),
1497 end : prev()
1498 });
1499 case "[":
1500 case "(":
1501 return simple_statement();
1502 case ";":
1503 S.in_directives = false;
1504 next();
1505 return new AST_EmptyStatement();
1506 default:
1507 unexpected();
1508 }
1509
1510 case "keyword":
1511 switch (S.token.value) {
1512 case "break":
1513 next();
1514 return break_cont(AST_Break);
1515
1516 case "continue":
1517 next();
1518 return break_cont(AST_Continue);
1519
1520 case "debugger":
1521 next();
1522 semicolon();
1523 return new AST_Debugger();
1524
1525 case "do":
1526 next();
1527 var body = in_loop(statement);
1528 expect_token("keyword", "while");
1529 var condition = parenthesised();
1530 semicolon(true);
1531 return new AST_Do({
1532 body : body,
1533 condition : condition
1534 });
1535
1536 case "while":
1537 next();
1538 return new AST_While({
1539 condition : parenthesised(),
1540 body : in_loop(function() { return statement(false, true); })
1541 });
1542
1543 case "for":
1544 next();
1545 return for_();
1546
1547 case "class":
1548 next();
1549 if (is_for_body) {
1550 croak("classes are not allowed as the body of a loop");
1551 }
1552 if (is_if_body) {
1553 croak("classes are not allowed as the body of an if");
1554 }
1555 return class_(AST_DefClass, is_export_default);
1556
1557 case "function":
1558 next();
1559 if (is_for_body) {
1560 croak("functions are not allowed as the body of a loop");
1561 }
1562 return function_(AST_Defun, false, false, is_export_default);
1563
1564 case "if":
1565 next();
1566 return if_();
1567
1568 case "return":
1569 if (S.in_function == 0 && !options.bare_returns)
1570 croak("'return' outside of function");
1571 next();
1572 var value = null;
1573 if (is("punc", ";")) {
1574 next();
1575 } else if (!can_insert_semicolon()) {
1576 value = expression(true);
1577 semicolon();
1578 }
1579 return new AST_Return({
1580 value: value
1581 });
1582
1583 case "switch":
1584 next();
1585 return new AST_Switch({
1586 expression : parenthesised(),
1587 body : in_loop(switch_body_)
1588 });
1589
1590 case "throw":
1591 next();
1592 if (has_newline_before(S.token))
1593 croak("Illegal newline after 'throw'");
1594 var value = expression(true);
1595 semicolon();
1596 return new AST_Throw({
1597 value: value
1598 });
1599
1600 case "try":
1601 next();
1602 return try_();
1603
1604 case "var":
1605 next();
1606 var node = var_();
1607 semicolon();
1608 return node;
1609
1610 case "let":
1611 next();
1612 var node = let_();
1613 semicolon();
1614 return node;
1615
1616 case "const":
1617 next();
1618 var node = const_();
1619 semicolon();
1620 return node;
1621
1622 case "with":
1623 if (S.input.has_directive("use strict")) {
1624 croak("Strict mode may not include a with statement");
1625 }
1626 next();
1627 return new AST_With({
1628 expression : parenthesised(),
1629 body : statement()
1630 });
1631
1632 case "export":
1633 if (!is_token(peek(), "punc", "(")) {
1634 next();
1635 var node = export_statement();
1636 if (is("punc", ";")) semicolon();
1637 return node;
1638 }
1639 }
1640 }
1641 unexpected();
1642 });
1643
1644 function labeled_statement() {
1645 var label = as_symbol(AST_Label);
1646 if (label.name === "await" && is_in_async()) {
1647 token_error(S.prev, "await cannot be used as label inside async function");
1648 }
1649 if (S.labels.some((l) => l.name === label.name)) {
1650 // ECMA-262, 12.12: An ECMAScript program is considered
1651 // syntactically incorrect if it contains a
1652 // LabelledStatement that is enclosed by a
1653 // LabelledStatement with the same Identifier as label.
1654 croak("Label " + label.name + " defined twice");
1655 }
1656 expect(":");
1657 S.labels.push(label);
1658 var stat = statement();
1659 S.labels.pop();
1660 if (!(stat instanceof AST_IterationStatement)) {
1661 // check for `continue` that refers to this label.
1662 // those should be reported as syntax errors.
1663 // https://github.com/mishoo/UglifyJS2/issues/287
1664 label.references.forEach(function(ref) {
1665 if (ref instanceof AST_Continue) {
1666 ref = ref.label.start;
1667 croak("Continue label `" + label.name + "` refers to non-IterationStatement.",
1668 ref.line, ref.col, ref.pos);
1669 }
1670 });
1671 }
1672 return new AST_LabeledStatement({ body: stat, label: label });
1673 }
1674
1675 function simple_statement(tmp) {
1676 return new AST_SimpleStatement({ body: (tmp = expression(true), semicolon(), tmp) });
1677 }
1678
1679 function break_cont(type) {
1680 var label = null, ldef;
1681 if (!can_insert_semicolon()) {
1682 label = as_symbol(AST_LabelRef, true);
1683 }
1684 if (label != null) {
1685 ldef = S.labels.find((l) => l.name === label.name);
1686 if (!ldef)
1687 croak("Undefined label " + label.name);
1688 label.thedef = ldef;
1689 } else if (S.in_loop == 0)
1690 croak(type.TYPE + " not inside a loop or switch");
1691 semicolon();
1692 var stat = new type({ label: label });
1693 if (ldef) ldef.references.push(stat);
1694 return stat;
1695 }
1696
1697 function for_() {
1698 var for_await_error = "`for await` invalid in this context";
1699 var await_tok = S.token;
1700 if (await_tok.type == "name" && await_tok.value == "await") {
1701 if (!can_await()) {
1702 token_error(await_tok, for_await_error);
1703 }
1704 next();
1705 } else {
1706 await_tok = false;
1707 }
1708 expect("(");
1709 var init = null;
1710 if (!is("punc", ";")) {
1711 init =
1712 is("keyword", "var") ? (next(), var_(true)) :
1713 is("keyword", "let") ? (next(), let_(true)) :
1714 is("keyword", "const") ? (next(), const_(true)) :
1715 is("name", "using") && is_token(peek(), "name") && (peek().value != "of" || S.input.peek_next_token_start_or_newline().char == "=") ? (next(), using_(true)) :
1716 is("name", "await") && can_await() && is_token(peek(), "name", "using") ? (next(), await_using_(true)) :
1717 expression(true, true);
1718 var is_in = is("operator", "in");
1719 var is_of = is("name", "of");
1720 if (await_tok && !is_of) {
1721 token_error(await_tok, for_await_error);
1722 }
1723 if (is_in || is_of) {
1724 if (init instanceof AST_DefinitionsLike) {
1725 if (init.definitions.length > 1)
1726 token_error(init.start, "Only one variable declaration allowed in for..in loop");
1727 if (is_in && init instanceof AST_Using) {
1728 token_error(init.start, "Invalid using declaration in for..in loop");
1729 }
1730 } else if (!(is_assignable(init) || (init = to_destructuring(init)) instanceof AST_Destructuring)) {
1731 token_error(init.start, "Invalid left-hand side in for..in loop");
1732 }
1733 next();
1734 if (is_in) {
1735 return for_in(init);
1736 } else {
1737 return for_of(init, !!await_tok);
1738 }
1739 }
1740 } else if (await_tok) {
1741 token_error(await_tok, for_await_error);
1742 }
1743 return regular_for(init);
1744 }
1745
1746 function regular_for(init) {
1747 expect(";");
1748 var test = is("punc", ";") ? null : expression(true);
1749 expect(";");
1750 var step = is("punc", ")") ? null : expression(true);
1751 expect(")");
1752 return new AST_For({
1753 init : init,
1754 condition : test,
1755 step : step,
1756 body : in_loop(function() { return statement(false, true); })
1757 });
1758 }
1759
1760 function for_of(init, is_await) {
1761 var lhs = init instanceof AST_DefinitionsLike ? init.definitions[0].name : null;
1762 var obj = expression(true);
1763 expect(")");
1764 return new AST_ForOf({
1765 await : is_await,
1766 init : init,
1767 name : lhs,
1768 object : obj,
1769 body : in_loop(function() { return statement(false, true); })
1770 });
1771 }
1772
1773 function for_in(init) {
1774 var obj = expression(true);
1775 expect(")");
1776 return new AST_ForIn({
1777 init : init,
1778 object : obj,
1779 body : in_loop(function() { return statement(false, true); })
1780 });
1781 }
1782
1783 var arrow_function = function(start, argnames, is_async) {
1784 if (has_newline_before(S.token)) {
1785 croak("Unexpected newline before arrow (=>)");
1786 }
1787
1788 expect_token("arrow", "=>");
1789
1790 var body = _function_body(is("punc", "{"), false, is_async);
1791
1792 return new AST_Arrow({
1793 start : start,
1794 end : body.end,
1795 async : is_async,
1796 argnames : argnames,
1797 body : body
1798 });
1799 };
1800
1801 var function_ = function(ctor, is_generator, is_async, is_export_default) {
1802 var in_statement = ctor === AST_Defun;
1803 if (is("operator", "*")) {
1804 is_generator = true;
1805 next();
1806 }
1807
1808 var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null;
1809 if (in_statement && !name) {
1810 if (is_export_default) {
1811 ctor = AST_Function;
1812 } else {
1813 unexpected();
1814 }
1815 }
1816
1817 if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration))
1818 unexpected(prev());
1819
1820 var args = [];
1821 var body = _function_body(true, is_generator, is_async, name, args);
1822 return new ctor({
1823 start : args.start,
1824 end : body.end,
1825 is_generator: is_generator,
1826 async : is_async,
1827 name : name,
1828 argnames: args,
1829 body : body
1830 });
1831 };
1832
1833 class UsedParametersTracker {
1834 constructor(is_parameter, strict, duplicates_ok = false) {
1835 this.is_parameter = is_parameter;
1836 this.duplicates_ok = duplicates_ok;
1837 this.parameters = new Set();
1838 this.duplicate = null;
1839 this.default_assignment = false;
1840 this.spread = false;
1841 this.strict_mode = !!strict;
1842 }
1843 add_parameter(token) {
1844 if (this.parameters.has(token.value)) {
1845 if (this.duplicate === null) {
1846 this.duplicate = token;
1847 }
1848 this.check_strict();
1849 } else {
1850 this.parameters.add(token.value);
1851 if (this.is_parameter) {
1852 switch (token.value) {
1853 case "arguments":
1854 case "eval":
1855 case "yield":
1856 if (this.strict_mode) {
1857 token_error(token, "Unexpected " + token.value + " identifier as parameter inside strict mode");
1858 }
1859 break;
1860 default:
1861 if (RESERVED_WORDS.has(token.value)) {
1862 unexpected();
1863 }
1864 }
1865 }
1866 }
1867 }
1868 mark_default_assignment(token) {
1869 if (this.default_assignment === false) {
1870 this.default_assignment = token;
1871 }
1872 }
1873 mark_spread(token) {
1874 if (this.spread === false) {
1875 this.spread = token;
1876 }
1877 }
1878 mark_strict_mode() {
1879 this.strict_mode = true;
1880 }
1881 is_strict() {
1882 return this.default_assignment !== false || this.spread !== false || this.strict_mode;
1883 }
1884 check_strict() {
1885 if (this.is_strict() && this.duplicate !== null && !this.duplicates_ok) {
1886 token_error(this.duplicate, "Parameter " + this.duplicate.value + " was used already");
1887 }
1888 }
1889 }
1890
1891 function parameters(params) {
1892 var used_parameters = new UsedParametersTracker(true, S.input.has_directive("use strict"));
1893
1894 expect("(");
1895
1896 while (!is("punc", ")")) {
1897 var param = parameter(used_parameters);
1898 params.push(param);
1899
1900 if (!is("punc", ")")) {
1901 expect(",");
1902 }
1903
1904 if (param instanceof AST_Expansion) {
1905 break;
1906 }
1907 }
1908
1909 next();
1910 }
1911
1912 function parameter(used_parameters, symbol_type) {
1913 var param;
1914 var expand = false;
1915 if (used_parameters === undefined) {
1916 used_parameters = new UsedParametersTracker(true, S.input.has_directive("use strict"));
1917 }
1918 if (is("expand", "...")) {
1919 expand = S.token;
1920 used_parameters.mark_spread(S.token);
1921 next();
1922 }
1923 param = binding_element(used_parameters, symbol_type);
1924
1925 if (is("operator", "=") && expand === false) {
1926 used_parameters.mark_default_assignment(S.token);
1927 next();
1928 param = new AST_DefaultAssign({
1929 start: param.start,
1930 left: param,
1931 operator: "=",
1932 right: expression(false),
1933 end: S.token
1934 });
1935 }
1936
1937 if (expand !== false) {
1938 if (!is("punc", ")")) {
1939 unexpected();
1940 }
1941 param = new AST_Expansion({
1942 start: expand,
1943 expression: param,
1944 end: expand
1945 });
1946 }
1947 used_parameters.check_strict();
1948
1949 return param;
1950 }
1951
1952 function binding_element(used_parameters, symbol_type) {
1953 var elements = [];
1954 var first = true;
1955 var is_expand = false;
1956 var expand_token;
1957 var first_token = S.token;
1958 if (used_parameters === undefined) {
1959 const strict = S.input.has_directive("use strict");
1960 const duplicates_ok = symbol_type === AST_SymbolVar;
1961 used_parameters = new UsedParametersTracker(false, strict, duplicates_ok);
1962 }
1963 symbol_type = symbol_type === undefined ? AST_SymbolFunarg : symbol_type;
1964 if (is("punc", "[")) {
1965 next();
1966 while (!is("punc", "]")) {
1967 if (first) {
1968 first = false;
1969 } else {
1970 expect(",");
1971 }
1972
1973 if (is("expand", "...")) {
1974 is_expand = true;
1975 expand_token = S.token;
1976 used_parameters.mark_spread(S.token);
1977 next();
1978 }
1979 if (is("punc")) {
1980 switch (S.token.value) {
1981 case ",":
1982 elements.push(new AST_Hole({
1983 start: S.token,
1984 end: S.token
1985 }));
1986 continue;
1987 case "]": // Trailing comma after last element
1988 break;
1989 case "[":
1990 case "{":
1991 elements.push(binding_element(used_parameters, symbol_type));
1992 break;
1993 default:
1994 unexpected();
1995 }
1996 } else if (is("name")) {
1997 used_parameters.add_parameter(S.token);
1998 elements.push(as_symbol(symbol_type));
1999 } else {
2000 croak("Invalid function parameter");
2001 }
2002 if (is("operator", "=") && is_expand === false) {
2003 used_parameters.mark_default_assignment(S.token);
2004 next();
2005 elements[elements.length - 1] = new AST_DefaultAssign({
2006 start: elements[elements.length - 1].start,
2007 left: elements[elements.length - 1],
2008 operator: "=",
2009 right: expression(false),
2010 end: S.token
2011 });
2012 }
2013 if (is_expand) {
2014 if (!is("punc", "]")) {
2015 croak("Rest element must be last element");
2016 }
2017 elements[elements.length - 1] = new AST_Expansion({
2018 start: expand_token,
2019 expression: elements[elements.length - 1],
2020 end: expand_token
2021 });
2022 }
2023 }
2024 expect("]");
2025 used_parameters.check_strict();
2026 return new AST_Destructuring({
2027 start: first_token,
2028 names: elements,
2029 is_array: true,
2030 end: prev()
2031 });
2032 } else if (is("punc", "{")) {
2033 next();
2034 while (!is("punc", "}")) {
2035 if (first) {
2036 first = false;
2037 } else {
2038 expect(",");
2039 }
2040 if (is("expand", "...")) {
2041 is_expand = true;
2042 expand_token = S.token;
2043 used_parameters.mark_spread(S.token);
2044 next();
2045 }
2046 if (is("name") && (is_token(peek(), "punc") || is_token(peek(), "operator")) && [",", "}", "="].includes(peek().value)) {
2047 used_parameters.add_parameter(S.token);
2048 var start = prev();
2049 var value = as_symbol(symbol_type);
2050 if (is_expand) {
2051 elements.push(new AST_Expansion({
2052 start: expand_token,
2053 expression: value,
2054 end: value.end,
2055 }));
2056 } else {
2057 elements.push(new AST_ObjectKeyVal({
2058 start: start,
2059 key: value.name,
2060 value: value,
2061 end: value.end,
2062 }));
2063 }
2064 } else if (is("punc", "}")) {
2065 continue; // Allow trailing hole
2066 } else {
2067 var property_token = S.token;
2068 var property = as_property_name();
2069 if (property === null) {
2070 unexpected(prev());
2071 } else if (prev().type === "name" && !is("punc", ":")) {
2072 elements.push(new AST_ObjectKeyVal({
2073 start: prev(),
2074 key: property,
2075 value: new symbol_type({
2076 start: prev(),
2077 name: property,
2078 end: prev()
2079 }),
2080 end: prev()
2081 }));
2082 } else {
2083 expect(":");
2084 elements.push(new AST_ObjectKeyVal({
2085 start: property_token,
2086 quote: property_token.quote,
2087 key: property,
2088 value: binding_element(used_parameters, symbol_type),
2089 end: prev()
2090 }));
2091 }
2092 }
2093 if (is_expand) {
2094 if (!is("punc", "}")) {
2095 croak("Rest element must be last element");
2096 }
2097 } else if (is("operator", "=")) {
2098 used_parameters.mark_default_assignment(S.token);
2099 next();
2100 elements[elements.length - 1].value = new AST_DefaultAssign({
2101 start: elements[elements.length - 1].value.start,
2102 left: elements[elements.length - 1].value,
2103 operator: "=",
2104 right: expression(false),
2105 end: S.token
2106 });
2107 }
2108 }
2109 expect("}");
2110 used_parameters.check_strict();
2111 return new AST_Destructuring({
2112 start: first_token,
2113 names: elements,
2114 is_array: false,
2115 end: prev()
2116 });
2117 } else if (is("name")) {
2118 used_parameters.add_parameter(S.token);
2119 return as_symbol(symbol_type);
2120 } else {
2121 croak("Invalid function parameter");
2122 }
2123 }
2124
2125 function params_or_seq_(allow_arrows, maybe_sequence) {
2126 var spread_token;
2127 var invalid_sequence;
2128 var trailing_comma;
2129 var a = [];
2130 expect("(");
2131 while (!is("punc", ")")) {
2132 if (spread_token) unexpected(spread_token);
2133 if (is("expand", "...")) {
2134 spread_token = S.token;
2135 if (maybe_sequence) invalid_sequence = S.token;
2136 next();
2137 a.push(new AST_Expansion({
2138 start: prev(),
2139 expression: expression(),
2140 end: S.token,
2141 }));
2142 } else {
2143 a.push(expression());
2144 }
2145 if (!is("punc", ")")) {
2146 expect(",");
2147 if (is("punc", ")")) {
2148 trailing_comma = prev();
2149 if (maybe_sequence) invalid_sequence = trailing_comma;
2150 }
2151 }
2152 }
2153 expect(")");
2154 if (allow_arrows && is("arrow", "=>")) {
2155 if (spread_token && trailing_comma) unexpected(trailing_comma);
2156 } else if (invalid_sequence) {
2157 unexpected(invalid_sequence);
2158 }
2159 return a;
2160 }
2161
2162 function _function_body(block, generator, is_async, name, args) {
2163 var loop = S.in_loop;
2164 var labels = S.labels;
2165 var current_generator = S.in_generator;
2166 var current_async = S.in_async;
2167 ++S.in_function;
2168 if (generator)
2169 S.in_generator = S.in_function;
2170 if (is_async)
2171 S.in_async = S.in_function;
2172 if (args) parameters(args);
2173 if (block)
2174 S.in_directives = true;
2175 S.in_loop = 0;
2176 S.labels = [];
2177 if (block) {
2178 S.input.push_directives_stack();
2179 var a = block_();
2180 if (name) _verify_symbol(name);
2181 if (args) args.forEach(_verify_symbol);
2182 S.input.pop_directives_stack();
2183 } else {
2184 var a = [new AST_Return({
2185 start: S.token,
2186 value: expression(false),
2187 end: S.token
2188 })];
2189 }
2190 --S.in_function;
2191 S.in_loop = loop;
2192 S.labels = labels;
2193 S.in_generator = current_generator;
2194 S.in_async = current_async;
2195 return a;
2196 }
2197
2198 function _await_expression() {
2199 // Previous token must be "await" and not be interpreted as an identifier
2200 if (!can_await()) {
2201 croak("Unexpected await expression outside async function",
2202 S.prev.line, S.prev.col, S.prev.pos);
2203 }
2204 // the await expression is parsed as a unary expression in Babel
2205 return new AST_Await({
2206 start: prev(),
2207 end: S.token,
2208 expression : maybe_unary(true),
2209 });
2210 }
2211
2212 function _yield_expression() {
2213 var start = S.token;
2214 var star = false;
2215 var has_expression = true;
2216
2217 // Attempt to get expression or star (and then the mandatory expression)
2218 // behind yield on the same line.
2219 //
2220 // If nothing follows on the same line of the yieldExpression,
2221 // it should default to the value `undefined` for yield to return.
2222 // In that case, the `undefined` stored as `null` in ast.
2223 //
2224 // Note 1: It isn't allowed for yield* to close without an expression
2225 // Note 2: If there is a nlb between yield and star, it is interpret as
2226 // yield <explicit undefined> <inserted automatic semicolon> *
2227 if (
2228 can_insert_semicolon()
2229 || is("punc") && PUNC_AFTER_EXPRESSION.has(S.token.value)
2230 || is("template_cont")
2231 ) {
2232 has_expression = false;
2233 } else if (is("operator", "*")) {
2234 star = true;
2235 next();
2236 }
2237
2238 return new AST_Yield({
2239 start : start,
2240 is_star : star,
2241 expression : has_expression ? expression() : null,
2242 end : prev()
2243 });
2244 }
2245
2246 function if_() {
2247 var cond = parenthesised(), body = statement(false, false, true), belse = null;
2248 if (is("keyword", "else")) {
2249 next();
2250 belse = statement(false, false, true);
2251 }
2252 return new AST_If({
2253 condition : cond,
2254 body : body,
2255 alternative : belse
2256 });
2257 }
2258
2259 function block_() {
2260 expect("{");
2261 var a = [];
2262 while (!is("punc", "}")) {
2263 if (is("eof")) unexpected();
2264 a.push(statement());
2265 }
2266 next();
2267 return a;
2268 }
2269
2270 function switch_body_() {
2271 expect("{");
2272 var a = [], cur = null, branch = null, tmp;
2273 while (!is("punc", "}")) {
2274 if (is("eof")) unexpected();
2275 if (is("keyword", "case")) {
2276 if (branch) branch.end = prev();
2277 cur = [];
2278 branch = new AST_Case({
2279 start : (tmp = S.token, next(), tmp),
2280 expression : expression(true),
2281 body : cur
2282 });
2283 a.push(branch);
2284 expect(":");
2285 } else if (is("keyword", "default")) {
2286 if (branch) branch.end = prev();
2287 cur = [];
2288 branch = new AST_Default({
2289 start : (tmp = S.token, next(), expect(":"), tmp),
2290 body : cur
2291 });
2292 a.push(branch);
2293 } else {
2294 if (!cur) unexpected();
2295 cur.push(statement());
2296 }
2297 }
2298 if (branch) branch.end = prev();
2299 next();
2300 return a;
2301 }
2302
2303 function try_() {
2304 var body, bcatch = null, bfinally = null;
2305 body = new AST_TryBlock({
2306 start : S.token,
2307 body : block_(),
2308 end : prev(),
2309 });
2310 if (is("keyword", "catch")) {
2311 var start = S.token;
2312 next();
2313 if (is("punc", "{")) {
2314 var name = null;
2315 } else {
2316 expect("(");
2317 var name = parameter(undefined, AST_SymbolCatch);
2318 expect(")");
2319 }
2320 bcatch = new AST_Catch({
2321 start : start,
2322 argname : name,
2323 body : block_(),
2324 end : prev()
2325 });
2326 }
2327 if (is("keyword", "finally")) {
2328 var start = S.token;
2329 next();
2330 bfinally = new AST_Finally({
2331 start : start,
2332 body : block_(),
2333 end : prev()
2334 });
2335 }
2336 if (!bcatch && !bfinally)
2337 croak("Missing catch/finally blocks");
2338 return new AST_Try({
2339 body : body,
2340 bcatch : bcatch,
2341 bfinally : bfinally
2342 });
2343 }
2344
2345 /**
2346 * var
2347 * vardef1 = 2,
2348 * vardef2 = 3;
2349 */
2350 function vardefs(no_in, kind) {
2351 var var_defs = [];
2352 var def;
2353 for (;;) {
2354 var sym_type =
2355 kind === "var" ? AST_SymbolVar :
2356 kind === "const" ? AST_SymbolConst :
2357 kind === "let" ? AST_SymbolLet :
2358 kind === "using" ? AST_SymbolUsing :
2359 kind === "await using" ? AST_SymbolUsing : null;
2360 var def_type = kind === "using" || kind === "await using" ? AST_UsingDef : AST_VarDef;
2361 // var { a } = b
2362 if (is("punc", "{") || is("punc", "[")) {
2363 def = new def_type({
2364 start: S.token,
2365 name: binding_element(undefined, sym_type),
2366 value: is("operator", "=") ? (expect_token("operator", "="), expression(false, no_in)) : null,
2367 end: prev()
2368 });
2369 } else {
2370 def = new def_type({
2371 start : S.token,
2372 name : as_symbol(sym_type),
2373 value : is("operator", "=")
2374 ? (next(), expression(false, no_in))
2375 : !no_in && (kind === "const" || kind === "using" || kind === "await using")
2376 ? croak("Missing initializer in " + kind + " declaration") : null,
2377 end : prev()
2378 });
2379 if (def.name.name == "import") croak("Unexpected token: import");
2380 }
2381 var_defs.push(def);
2382 if (!is("punc", ","))
2383 break;
2384 next();
2385 }
2386 return var_defs;
2387 }
2388
2389 var var_ = function(no_in) {
2390 return new AST_Var({
2391 start : prev(),
2392 definitions : vardefs(no_in, "var"),
2393 end : prev()
2394 });
2395 };
2396
2397 var let_ = function(no_in) {
2398 return new AST_Let({
2399 start : prev(),
2400 definitions : vardefs(no_in, "let"),
2401 end : prev()
2402 });
2403 };
2404
2405 var const_ = function(no_in) {
2406 return new AST_Const({
2407 start : prev(),
2408 definitions : vardefs(no_in, "const"),
2409 end : prev()
2410 });
2411 };
2412
2413 var using_ = function(no_in) {
2414 return new AST_Using({
2415 start : prev(),
2416 await : false,
2417 definitions : vardefs(no_in, "using"),
2418 end : prev()
2419 });
2420 };
2421
2422 var await_using_ = function(no_in) {
2423 // Assumption: When await_using_ is called, only the `await` token has been consumed.
2424 return new AST_Using({
2425 start : prev(),
2426 await : true,
2427 definitions : (next(), vardefs(no_in, "await using")),
2428 end : prev()
2429 });
2430 };
2431
2432 var new_ = function(allow_calls) {
2433 var start = S.token;
2434 expect_token("operator", "new");
2435 if (is("punc", ".")) {
2436 next();
2437 expect_token("name", "target");
2438 return subscripts(new AST_NewTarget({
2439 start : start,
2440 end : prev()
2441 }), allow_calls);
2442 }
2443 var newexp = expr_atom(false), args;
2444 if (is("punc", "(")) {
2445 next();
2446 args = expr_list(")", true);
2447 } else {
2448 args = [];
2449 }
2450 var call = new AST_New({
2451 start : start,
2452 expression : newexp,
2453 args : args,
2454 end : prev()
2455 });
2456 annotate(call);
2457 return subscripts(call, allow_calls);
2458 };
2459
2460 function as_atom_node() {
2461 var tok = S.token, ret;
2462 switch (tok.type) {
2463 case "name":
2464 ret = _make_symbol(AST_SymbolRef);
2465 break;
2466 case "num":
2467 if (tok.value === Infinity) {
2468 // very large float values are parsed as Infinity
2469 ret = new AST_Infinity({
2470 start: tok,
2471 end: tok,
2472 });
2473 } else {
2474 ret = new AST_Number({
2475 start: tok,
2476 end: tok,
2477 value: tok.value,
2478 raw: LATEST_RAW
2479 });
2480 }
2481 break;
2482 case "big_int":
2483 ret = new AST_BigInt({
2484 start: tok,
2485 end: tok,
2486 value: tok.value,
2487 raw: LATEST_RAW,
2488 });
2489 break;
2490 case "string":
2491 ret = new AST_String({
2492 start : tok,
2493 end : tok,
2494 value : tok.value,
2495 quote : tok.quote
2496 });
2497 annotate(ret);
2498 break;
2499 case "regexp":
2500 const [_, source, flags] = tok.value.match(/^\/(.*)\/(\w*)$/);
2501
2502 ret = new AST_RegExp({ start: tok, end: tok, value: { source, flags } });
2503 break;
2504 case "atom":
2505 switch (tok.value) {
2506 case "false":
2507 ret = new AST_False({ start: tok, end: tok });
2508 break;
2509 case "true":
2510 ret = new AST_True({ start: tok, end: tok });
2511 break;
2512 case "null":
2513 ret = new AST_Null({ start: tok, end: tok });
2514 break;
2515 }
2516 break;
2517 }
2518 next();
2519 return ret;
2520 }
2521
2522 function to_fun_args(ex, default_seen_above) {
2523 var insert_default = function(ex, default_value) {
2524 if (default_value) {
2525 return new AST_DefaultAssign({
2526 start: ex.start,
2527 left: ex,
2528 operator: "=",
2529 right: default_value,
2530 end: default_value.end
2531 });
2532 }
2533 return ex;
2534 };
2535 if (ex instanceof AST_Object) {
2536 return insert_default(new AST_Destructuring({
2537 start: ex.start,
2538 end: ex.end,
2539 is_array: false,
2540 names: ex.properties.map(prop => to_fun_args(prop))
2541 }), default_seen_above);
2542 } else if (ex instanceof AST_ObjectKeyVal) {
2543 ex.value = to_fun_args(ex.value);
2544 return insert_default(ex, default_seen_above);
2545 } else if (ex instanceof AST_Hole) {
2546 return ex;
2547 } else if (ex instanceof AST_Destructuring) {
2548 ex.names = ex.names.map(name => to_fun_args(name));
2549 return insert_default(ex, default_seen_above);
2550 } else if (ex instanceof AST_SymbolRef) {
2551 return insert_default(new AST_SymbolFunarg({
2552 name: ex.name,
2553 start: ex.start,
2554 end: ex.end
2555 }), default_seen_above);
2556 } else if (ex instanceof AST_Expansion) {
2557 ex.expression = to_fun_args(ex.expression);
2558 return insert_default(ex, default_seen_above);
2559 } else if (ex instanceof AST_Array) {
2560 return insert_default(new AST_Destructuring({
2561 start: ex.start,
2562 end: ex.end,
2563 is_array: true,
2564 names: ex.elements.map(elm => to_fun_args(elm))
2565 }), default_seen_above);
2566 } else if (ex instanceof AST_Assign) {
2567 return insert_default(to_fun_args(ex.left, ex.right), default_seen_above);
2568 } else if (ex instanceof AST_DefaultAssign) {
2569 ex.left = to_fun_args(ex.left);
2570 return ex;
2571 } else {
2572 croak("Invalid function parameter", ex.start.line, ex.start.col);
2573 }
2574 }
2575
2576 var expr_atom = function(allow_calls, allow_arrows) {
2577 if (is("operator", "new")) {
2578 return new_(allow_calls);
2579 }
2580 if (is("name", "import") && is_token(peek(), "punc", ".")) {
2581 return parse_import_expr(allow_calls);
2582 }
2583 var start = S.token;
2584 var peeked;
2585 var async = is("name", "async")
2586 && (peeked = peek()).value != "["
2587 && peeked.type != "arrow"
2588 && as_atom_node();
2589 if (is("punc")) {
2590 switch (S.token.value) {
2591 case "(":
2592 if (async && !allow_calls) break;
2593 var exprs = params_or_seq_(allow_arrows, !async);
2594 if (allow_arrows && is("arrow", "=>")) {
2595 return arrow_function(start, exprs.map(e => to_fun_args(e)), !!async);
2596 }
2597 var ex = async ? new AST_Call({
2598 expression: async,
2599 args: exprs
2600 }) : to_expr_or_sequence(start, exprs);
2601 if (ex.start) {
2602 const outer_comments_before = start.comments_before.length;
2603 outer_comments_before_counts.set(start, outer_comments_before);
2604 ex.start.comments_before.unshift(...start.comments_before);
2605 start.comments_before = ex.start.comments_before;
2606 if (outer_comments_before == 0 && start.comments_before.length > 0) {
2607 var comment = start.comments_before[0];
2608 if (!comment.nlb) {
2609 comment.nlb = start.nlb;
2610 start.nlb = false;
2611 }
2612 }
2613 start.comments_after = ex.start.comments_after;
2614 }
2615 ex.start = start;
2616 var end = prev();
2617 if (ex.end) {
2618 end.comments_before = ex.end.comments_before;
2619 ex.end.comments_after.push(...end.comments_after);
2620 end.comments_after = ex.end.comments_after;
2621 }
2622 ex.end = end;
2623 if (ex instanceof AST_Call) annotate(ex);
2624 return subscripts(ex, allow_calls);
2625 case "[":
2626 return subscripts(array_(), allow_calls);
2627 case "{":
2628 return subscripts(object_or_destructuring_(), allow_calls);
2629 }
2630 if (!async) unexpected();
2631 }
2632 if (allow_arrows && is("name") && is_token(peek(), "arrow")) {
2633 var param = new AST_SymbolFunarg({
2634 name: S.token.value,
2635 start: start,
2636 end: start,
2637 });
2638 next();
2639 return arrow_function(start, [param], !!async);
2640 }
2641 if (is("keyword", "function")) {
2642 next();
2643 var func = function_(AST_Function, false, !!async);
2644 func.start = start;
2645 func.end = prev();
2646 return subscripts(func, allow_calls);
2647 }
2648 if (async) return subscripts(async, allow_calls);
2649 if (is("keyword", "class")) {
2650 next();
2651 var cls = class_(AST_ClassExpression);
2652 cls.start = start;
2653 cls.end = prev();
2654 return subscripts(cls, allow_calls);
2655 }
2656 if (is("template_head")) {
2657 return subscripts(template_string(), allow_calls);
2658 }
2659 if (ATOMIC_START_TOKEN.has(S.token.type)) {
2660 return subscripts(as_atom_node(), allow_calls);
2661 }
2662 unexpected();
2663 };
2664
2665 function template_string() {
2666 var segments = [], start = S.token;
2667
2668 segments.push(new AST_TemplateSegment({
2669 start: S.token,
2670 raw: TEMPLATE_RAWS.get(S.token),
2671 value: S.token.value,
2672 end: S.token
2673 }));
2674
2675 while (!S.token.template_end) {
2676 next();
2677 handle_regexp();
2678 segments.push(expression(true));
2679
2680 segments.push(new AST_TemplateSegment({
2681 start: S.token,
2682 raw: TEMPLATE_RAWS.get(S.token),
2683 value: S.token.value,
2684 end: S.token
2685 }));
2686 }
2687 next();
2688
2689 return new AST_TemplateString({
2690 start: start,
2691 segments: segments,
2692 end: S.token
2693 });
2694 }
2695
2696 function expr_list(closing, allow_trailing_comma, allow_empty) {
2697 var first = true, a = [];
2698 while (!is("punc", closing)) {
2699 if (first) first = false; else expect(",");
2700 if (allow_trailing_comma && is("punc", closing)) break;
2701 if (is("punc", ",") && allow_empty) {
2702 a.push(new AST_Hole({ start: S.token, end: S.token }));
2703 } else if (is("expand", "...")) {
2704 next();
2705 a.push(new AST_Expansion({start: prev(), expression: expression(),end: S.token}));
2706 } else {
2707 a.push(expression(false));
2708 }
2709 }
2710 next();
2711 return a;
2712 }
2713
2714 var array_ = embed_tokens(function() {
2715 expect("[");
2716 return new AST_Array({
2717 elements: expr_list("]", !options.strict, true)
2718 });
2719 });
2720
2721 var create_accessor = embed_tokens((is_generator, is_async) => {
2722 return function_(AST_Accessor, is_generator, is_async);
2723 });
2724
2725 var object_or_destructuring_ = embed_tokens(function object_or_destructuring_() {
2726 var start = S.token, first = true, a = [];
2727 expect("{");
2728 while (!is("punc", "}")) {
2729 if (first) first = false; else expect(",");
2730 if (!options.strict && is("punc", "}"))
2731 // allow trailing comma
2732 break;
2733
2734 start = S.token;
2735 if (start.type == "expand") {
2736 next();
2737 a.push(new AST_Expansion({
2738 start: start,
2739 expression: expression(false),
2740 end: prev(),
2741 }));
2742 continue;
2743 }
2744 if(is("privatename")) {
2745 croak("private fields are not allowed in an object");
2746 }
2747 var name = as_property_name();
2748 var value;
2749
2750 // Check property and fetch value
2751 if (!is("punc", ":")) {
2752 var concise = object_or_class_property(name, start);
2753 if (concise) {
2754 a.push(concise);
2755 continue;
2756 }
2757
2758 value = new AST_SymbolRef({
2759 start: prev(),
2760 name: name,
2761 end: prev()
2762 });
2763 } else if (name === null) {
2764 unexpected(prev());
2765 } else {
2766 next(); // `:` - see first condition
2767 value = expression(false);
2768 }
2769
2770 // Check for default value and alter value accordingly if necessary
2771 if (is("operator", "=")) {
2772 next();
2773 value = new AST_Assign({
2774 start: start,
2775 left: value,
2776 operator: "=",
2777 right: expression(false),
2778 logical: false,
2779 end: prev()
2780 });
2781 }
2782
2783 // Create property
2784 const kv = new AST_ObjectKeyVal({
2785 start: start,
2786 quote: start.quote,
2787 key: name,
2788 value: value,
2789 end: prev()
2790 });
2791 a.push(annotate(kv));
2792 }
2793 next();
2794 return new AST_Object({ properties: a });
2795 });
2796
2797 function class_(KindOfClass, is_export_default) {
2798 var start, method, class_name, extends_, properties = [];
2799
2800 S.input.push_directives_stack(); // Push directive stack, but not scope stack
2801 S.input.add_directive("use strict");
2802
2803 if (S.token.type == "name" && S.token.value != "extends") {
2804 class_name = as_symbol(KindOfClass === AST_DefClass ? AST_SymbolDefClass : AST_SymbolClass);
2805 }
2806
2807 if (KindOfClass === AST_DefClass && !class_name) {
2808 if (is_export_default) {
2809 KindOfClass = AST_ClassExpression;
2810 } else {
2811 unexpected();
2812 }
2813 }
2814
2815 if (S.token.value == "extends") {
2816 next();
2817 extends_ = expression(true);
2818 }
2819
2820 expect("{");
2821 // mark in class feild,
2822 const save_in_class = S.in_class;
2823 S.in_class = true;
2824 while (is("punc", ";")) { next(); } // Leading semicolons are okay in class bodies.
2825 while (!is("punc", "}")) {
2826 start = S.token;
2827 method = object_or_class_property(as_property_name(), start, true);
2828 if (!method) { unexpected(); }
2829 properties.push(method);
2830 while (is("punc", ";")) { next(); }
2831 }
2832 // mark in class feild,
2833 S.in_class = save_in_class;
2834
2835 S.input.pop_directives_stack();
2836
2837 next();
2838
2839 return new KindOfClass({
2840 start: start,
2841 name: class_name,
2842 extends: extends_,
2843 properties: properties,
2844 end: prev(),
2845 });
2846 }
2847
2848 function object_or_class_property(name, start, is_class) {
2849 const get_symbol_ast = (name, SymbolClass) => {
2850 if (typeof name === "string") {
2851 return new SymbolClass({ start, name, end: prev() });
2852 } else if (name === null) {
2853 unexpected();
2854 }
2855 return name;
2856 };
2857
2858 var is_private = prev().type === "privatename";
2859 const is_not_method_start = () =>
2860 !is("punc", "(") && !is("punc", ",") && !is("punc", "}") && !is("punc", ";") && !is("operator", "=") && !is_private;
2861
2862 var is_async = false;
2863 var is_static = false;
2864 var is_generator = false;
2865 var accessor_type = null;
2866
2867 if (is_class && name === "static" && is_not_method_start()) {
2868 const static_block = class_static_block();
2869 if (static_block != null) {
2870 return static_block;
2871 }
2872 is_static = true;
2873 name = as_property_name();
2874 }
2875 if (name === "async" && is_not_method_start()) {
2876 is_async = true;
2877 name = as_property_name();
2878 }
2879 if (prev().type === "operator" && prev().value === "*") {
2880 is_generator = true;
2881 name = as_property_name();
2882 }
2883 if ((name === "get" || name === "set") && is_not_method_start()) {
2884 accessor_type = name;
2885 name = as_property_name();
2886 }
2887 if (!is_private && prev().type === "privatename") {
2888 is_private = true;
2889 }
2890
2891 const property_token = prev();
2892
2893 if (accessor_type != null) {
2894 if (!is_private) {
2895 const AccessorClass = accessor_type === "get"
2896 ? AST_ObjectGetter
2897 : AST_ObjectSetter;
2898
2899 name = get_symbol_ast(name, AST_SymbolMethod);
2900 return annotate(new AccessorClass({
2901 start,
2902 static: is_static,
2903 key: name,
2904 quote: name instanceof AST_SymbolMethod ? property_token.quote : undefined,
2905 value: create_accessor(),
2906 end: prev()
2907 }));
2908 } else {
2909 const AccessorClass = accessor_type === "get"
2910 ? AST_PrivateGetter
2911 : AST_PrivateSetter;
2912
2913 return annotate(new AccessorClass({
2914 start,
2915 static: is_static,
2916 key: get_symbol_ast(name, AST_SymbolMethod),
2917 value: create_accessor(),
2918 end: prev(),
2919 }));
2920 }
2921 }
2922
2923 if (is("punc", "(")) {
2924 name = get_symbol_ast(name, AST_SymbolMethod);
2925 const AST_MethodVariant = is_private
2926 ? AST_PrivateMethod
2927 : AST_ConciseMethod;
2928 var node = new AST_MethodVariant({
2929 start : start,
2930 static : is_static,
2931 key : name,
2932 quote : name instanceof AST_SymbolMethod ?
2933 property_token.quote : undefined,
2934 value : create_accessor(is_generator, is_async),
2935 end : prev()
2936 });
2937 return annotate(node);
2938 }
2939
2940 if (is_class) {
2941 const AST_SymbolVariant = is_private
2942 ? AST_SymbolPrivateProperty
2943 : AST_SymbolClassProperty;
2944 const AST_ClassPropertyVariant = is_private
2945 ? AST_ClassPrivateProperty
2946 : AST_ClassProperty;
2947
2948 const key = get_symbol_ast(name, AST_SymbolVariant);
2949 const quote = key instanceof AST_SymbolClassProperty
2950 ? property_token.quote
2951 : undefined;
2952 if (is("operator", "=")) {
2953 next();
2954 return annotate(
2955 new AST_ClassPropertyVariant({
2956 start,
2957 static: is_static,
2958 quote,
2959 key,
2960 value: expression(false),
2961 end: prev()
2962 })
2963 );
2964 } else if (
2965 is("name")
2966 || is("privatename")
2967 || is("punc", "[")
2968 || is("operator", "*")
2969 || is("punc", ";")
2970 || is("punc", "}")
2971 || is("string")
2972 || is("num")
2973 || is("big_int")
2974 ) {
2975 return annotate(
2976 new AST_ClassPropertyVariant({
2977 start,
2978 static: is_static,
2979 quote,
2980 key,
2981 end: prev()
2982 })
2983 );
2984 }
2985 }
2986 }
2987
2988 function class_static_block() {
2989 if (!is("punc", "{")) {
2990 return null;
2991 }
2992
2993 const start = S.token;
2994 const body = [];
2995
2996 next();
2997
2998 while (!is("punc", "}")) {
2999 body.push(statement());
3000 }
3001
3002 next();
3003
3004 return new AST_ClassStaticBlock({ start, body, end: prev() });
3005 }
3006
3007 function maybe_import_attributes() {
3008 if (
3009 (is("keyword", "with") || is("name", "assert"))
3010 && !has_newline_before(S.token)
3011 ) {
3012 next();
3013 return object_or_destructuring_();
3014 }
3015 return null;
3016 }
3017
3018 function import_statement() {
3019 var start = prev();
3020
3021 // import source x from "..."
3022 // import defer * as x from "..."
3023 var phase = null;
3024 if (is("name", "source") || is("name", "defer")) {
3025 var peeked = peek();
3026 if (!is_token(peeked, "name", "from") && !is_token(peeked, "punc", ",")) {
3027 phase = S.token.value;
3028 next();
3029 }
3030 }
3031
3032 var imported_name;
3033 var imported_names;
3034 if (is("name")) {
3035 imported_name = as_symbol(AST_SymbolImport);
3036 }
3037
3038 if (is("punc", ",")) {
3039 next();
3040 }
3041
3042 imported_names = map_names(true);
3043
3044 if (imported_names || imported_name) {
3045 expect_token("name", "from");
3046 }
3047 var mod_str = S.token;
3048 if (mod_str.type !== "string") {
3049 unexpected();
3050 }
3051 next();
3052
3053 const attributes = maybe_import_attributes();
3054
3055 return new AST_Import({
3056 start,
3057 imported_name,
3058 imported_names,
3059 module_name: new AST_String({
3060 start: mod_str,
3061 value: mod_str.value,
3062 quote: mod_str.quote,
3063 end: mod_str,
3064 }),
3065 attributes,
3066 phase,
3067 end: S.token,
3068 });
3069 }
3070
3071 // import.meta
3072 // import.source("module")
3073 // import.defer("module")
3074 function parse_import_expr(allow_calls) {
3075 var start = S.token;
3076 expect_token("name", "import");
3077 expect_token("punc", ".");
3078 if (is("name", "source") || is("name", "defer")) {
3079 var phase = S.token.value;
3080 next();
3081 if (!is("punc", "(")) {
3082 croak("'import." + phase + "' can only be used in a dynamic import");
3083 }
3084 next();
3085 var args = expr_list(")");
3086 return subscripts(new AST_DynamicImport({
3087 start: start,
3088 phase: phase,
3089 args: args,
3090 end: prev()
3091 }), allow_calls);
3092 }
3093 expect_token("name", "meta");
3094 return subscripts(new AST_ImportMeta({
3095 start: start,
3096 end: prev()
3097 }), allow_calls);
3098 }
3099
3100 function map_name(is_import) {
3101 function make_symbol(type, quote) {
3102 return new type({
3103 name: as_property_name(),
3104 quote: quote || undefined,
3105 start: prev(),
3106 end: prev()
3107 });
3108 }
3109
3110 var foreign_type = is_import ? AST_SymbolImportForeign : AST_SymbolExportForeign;
3111 var type = is_import ? AST_SymbolImport : AST_SymbolExport;
3112 var start = S.token;
3113 var foreign_name;
3114 var name;
3115
3116 if (is_import) {
3117 foreign_name = make_symbol(foreign_type, start.quote);
3118 } else {
3119 name = make_symbol(type, start.quote);
3120 }
3121 if (is("name", "as")) {
3122 next(); // The "as" word
3123 if (is_import) {
3124 name = make_symbol(type);
3125 } else {
3126 foreign_name = make_symbol(foreign_type, S.token.quote);
3127 }
3128 } else {
3129 if (is_import) {
3130 name = new type(foreign_name);
3131 } else {
3132 foreign_name = new foreign_type(name);
3133 }
3134 }
3135
3136 return new AST_NameMapping({
3137 start: start,
3138 foreign_name: foreign_name,
3139 name: name,
3140 end: prev(),
3141 });
3142 }
3143
3144 function map_nameAsterisk(is_import, import_or_export_foreign_name) {
3145 var foreign_type = is_import ? AST_SymbolImportForeign : AST_SymbolExportForeign;
3146 var type = is_import ? AST_SymbolImport : AST_SymbolExport;
3147 var start = S.token;
3148 var name, foreign_name;
3149 var end = prev();
3150
3151 if (is_import) {
3152 name = import_or_export_foreign_name;
3153 } else {
3154 foreign_name = import_or_export_foreign_name;
3155 }
3156
3157 name = name || new type({
3158 start: start,
3159 name: "*",
3160 end: end,
3161 });
3162
3163 foreign_name = foreign_name || new foreign_type({
3164 start: start,
3165 name: "*",
3166 end: end,
3167 });
3168
3169 return new AST_NameMapping({
3170 start: start,
3171 foreign_name: foreign_name,
3172 name: name,
3173 end: end,
3174 });
3175 }
3176
3177 function map_names(is_import) {
3178 var names;
3179 if (is("punc", "{")) {
3180 next();
3181 names = [];
3182 while (!is("punc", "}")) {
3183 names.push(map_name(is_import));
3184 if (is("punc", ",")) {
3185 next();
3186 }
3187 }
3188 next();
3189 } else if (is("operator", "*")) {
3190 var name;
3191 next();
3192 if (is("name", "as")) {
3193 next(); // The "as" word
3194 name = is_import ? as_symbol(AST_SymbolImport) : as_symbol_or_string(AST_SymbolExportForeign);
3195 }
3196 names = [map_nameAsterisk(is_import, name)];
3197 }
3198 return names;
3199 }
3200
3201 function export_statement() {
3202 var start = S.token;
3203 var is_default;
3204 var exported_names;
3205
3206 if (is("keyword", "default")) {
3207 is_default = true;
3208 next();
3209 } else if (exported_names = map_names(false)) {
3210 if (is("name", "from")) {
3211 next();
3212
3213 var mod_str = S.token;
3214 if (mod_str.type !== "string") {
3215 unexpected();
3216 }
3217 next();
3218
3219 const attributes = maybe_import_attributes();
3220
3221 return new AST_Export({
3222 start: start,
3223 is_default: is_default,
3224 exported_names: exported_names,
3225 module_name: new AST_String({
3226 start: mod_str,
3227 value: mod_str.value,
3228 quote: mod_str.quote,
3229 end: mod_str,
3230 }),
3231 end: prev(),
3232 attributes
3233 });
3234 } else {
3235 return new AST_Export({
3236 start: start,
3237 is_default: is_default,
3238 exported_names: exported_names,
3239 end: prev(),
3240 });
3241 }
3242 }
3243
3244 var node;
3245 var exported_value;
3246 var exported_definition;
3247 if (is("punc", "{")
3248 || is_default
3249 && (is("keyword", "class") || is("keyword", "function"))
3250 && is_token(peek(), "punc")) {
3251 exported_value = expression(false);
3252 semicolon();
3253 } else if ((node = statement(is_default)) instanceof AST_Definitions && is_default) {
3254 unexpected(node.start);
3255 } else if (
3256 node instanceof AST_Definitions
3257 || node instanceof AST_Defun
3258 || node instanceof AST_DefClass
3259 ) {
3260 exported_definition = node;
3261 } else if (
3262 node instanceof AST_ClassExpression
3263 || node instanceof AST_Function
3264 ) {
3265 exported_value = node;
3266 } else if (node instanceof AST_SimpleStatement) {
3267 exported_value = node.body;
3268 } else {
3269 unexpected(node.start);
3270 }
3271
3272 return new AST_Export({
3273 start: start,
3274 is_default: is_default,
3275 exported_value: exported_value,
3276 exported_definition: exported_definition,
3277 end: prev(),
3278 attributes: null
3279 });
3280 }
3281
3282 function as_property_name() {
3283 var tmp = S.token;
3284 switch (tmp.type) {
3285 case "punc":
3286 if (tmp.value === "[") {
3287 next();
3288 var ex = expression(false);
3289 expect("]");
3290 return ex;
3291 } else unexpected(tmp);
3292 case "operator":
3293 if (tmp.value === "*") {
3294 next();
3295 return null;
3296 }
3297 if (!["delete", "in", "instanceof", "new", "typeof", "void"].includes(tmp.value)) {
3298 unexpected(tmp);
3299 }
3300 /* falls through */
3301 case "name":
3302 case "privatename":
3303 case "string":
3304 case "keyword":
3305 case "atom":
3306 next();
3307 return tmp.value;
3308 case "num":
3309 case "big_int":
3310 next();
3311 return "" + tmp.value;
3312 default:
3313 unexpected(tmp);
3314 }
3315 }
3316
3317 function as_name() {
3318 var tmp = S.token;
3319 if (tmp.type != "name" && tmp.type != "privatename") unexpected();
3320 next();
3321 return tmp.value;
3322 }
3323
3324 function _make_symbol(type) {
3325 var name = S.token.value;
3326 return new (name == "this" ? AST_This :
3327 name == "super" ? AST_Super :
3328 type)({
3329 name : String(name),
3330 start : S.token,
3331 end : S.token
3332 });
3333 }
3334
3335 function _verify_symbol(sym) {
3336 var name = sym.name;
3337 if (is_in_generator() && name == "yield") {
3338 token_error(sym.start, "Yield cannot be used as identifier inside generators");
3339 }
3340 if (S.input.has_directive("use strict")) {
3341 if (name == "yield") {
3342 token_error(sym.start, "Unexpected yield identifier inside strict mode");
3343 }
3344 if (sym instanceof AST_SymbolDeclaration && (name == "arguments" || name == "eval")) {
3345 token_error(sym.start, "Unexpected " + name + " in strict mode");
3346 }
3347 }
3348 }
3349
3350 function as_symbol(type, noerror) {
3351 if (!is("name")) {
3352 if (!noerror) croak("Name expected");
3353 return null;
3354 }
3355 var sym = _make_symbol(type);
3356 _verify_symbol(sym);
3357 next();
3358 return sym;
3359 }
3360
3361 function as_symbol_or_string(type) {
3362 if (!is("name")) {
3363 if (!is("string")) {
3364 croak("Name or string expected");
3365 }
3366 var tok = S.token;
3367 var ret = new type({
3368 start : tok,
3369 end : tok,
3370 name : tok.value,
3371 quote : tok.quote
3372 });
3373 next();
3374 return ret;
3375 }
3376 var sym = _make_symbol(type);
3377 _verify_symbol(sym);
3378 next();
3379 return sym;
3380 }
3381
3382 // Annotate AST_Call, AST_Lambda or AST_New with the special comments
3383 function annotate(node, before_token = node.start) {
3384 var comments = before_token.comments_before;
3385 const comments_outside_parens = outer_comments_before_counts.get(before_token);
3386 var i = comments_outside_parens != null ? comments_outside_parens : comments.length;
3387 while (--i >= 0) {
3388 var comment = comments[i];
3389 if (/[@#]__/.test(comment.value)) {
3390 if (/[@#]__PURE__/.test(comment.value)) {
3391 set_annotation(node, _PURE);
3392 break;
3393 }
3394 if (/[@#]__INLINE__/.test(comment.value)) {
3395 set_annotation(node, _INLINE);
3396 break;
3397 }
3398 if (/[@#]__NOINLINE__/.test(comment.value)) {
3399 set_annotation(node, _NOINLINE);
3400 break;
3401 }
3402 if (/[@#]__KEY__/.test(comment.value)) {
3403 set_annotation(node, _KEY);
3404 break;
3405 }
3406 if (/[@#]__MANGLE_PROP__/.test(comment.value)) {
3407 set_annotation(node, _MANGLEPROP);
3408 break;
3409 }
3410 }
3411 }
3412 return node;
3413 }
3414
3415 var subscripts = function(expr, allow_calls, is_chain) {
3416 var start = expr.start;
3417 if (is("punc", ".")) {
3418 next();
3419 if(is("privatename") && !S.in_class)
3420 croak("Private field must be used in an enclosing class");
3421 const AST_DotVariant = is("privatename") ? AST_DotHash : AST_Dot;
3422 return annotate(subscripts(new AST_DotVariant({
3423 start : start,
3424 expression : expr,
3425 optional : false,
3426 property : as_name(),
3427 end : prev()
3428 }), allow_calls, is_chain));
3429 }
3430 if (is("punc", "[")) {
3431 next();
3432 var prop = expression(true);
3433 expect("]");
3434 return annotate(subscripts(new AST_Sub({
3435 start : start,
3436 expression : expr,
3437 optional : false,
3438 property : prop,
3439 end : prev()
3440 }), allow_calls, is_chain));
3441 }
3442 if (allow_calls && is("punc", "(")) {
3443 next();
3444 var call = new AST_Call({
3445 start : start,
3446 expression : expr,
3447 optional : false,
3448 args : call_args(),
3449 end : prev()
3450 });
3451 annotate(call);
3452 return subscripts(call, true, is_chain);
3453 }
3454
3455 // Optional chain
3456 if (is("punc", "?.")) {
3457 next();
3458
3459 let chain_contents;
3460
3461 if (allow_calls && is("punc", "(")) {
3462 next();
3463
3464 const call = new AST_Call({
3465 start,
3466 optional: true,
3467 expression: expr,
3468 args: call_args(),
3469 end: prev()
3470 });
3471 annotate(call);
3472
3473 chain_contents = subscripts(call, true, true);
3474 } else if (is("name") || is("privatename")) {
3475 if(is("privatename") && !S.in_class)
3476 croak("Private field must be used in an enclosing class");
3477 const AST_DotVariant = is("privatename") ? AST_DotHash : AST_Dot;
3478 chain_contents = annotate(subscripts(new AST_DotVariant({
3479 start,
3480 expression: expr,
3481 optional: true,
3482 property: as_name(),
3483 end: prev()
3484 }), allow_calls, true));
3485 } else if (is("punc", "[")) {
3486 next();
3487 const property = expression(true);
3488 expect("]");
3489 chain_contents = annotate(subscripts(new AST_Sub({
3490 start,
3491 expression: expr,
3492 optional: true,
3493 property,
3494 end: prev()
3495 }), allow_calls, true));
3496 }
3497
3498 if (!chain_contents) unexpected();
3499
3500 if (chain_contents instanceof AST_Chain) return chain_contents;
3501
3502 return new AST_Chain({
3503 start,
3504 expression: chain_contents,
3505 end: prev()
3506 });
3507 }
3508
3509 if (is("template_head")) {
3510 if (is_chain) {
3511 // a?.b`c` is a syntax error
3512 unexpected();
3513 }
3514
3515 return subscripts(new AST_PrefixedTemplateString({
3516 start: start,
3517 prefix: expr,
3518 template_string: template_string(),
3519 end: prev()
3520 }), allow_calls);
3521 }
3522 return expr;
3523 };
3524
3525 function call_args() {
3526 var args = [];
3527 while (!is("punc", ")")) {
3528 if (is("expand", "...")) {
3529 next();
3530 args.push(new AST_Expansion({
3531 start: prev(),
3532 expression: expression(false),
3533 end: prev()
3534 }));
3535 } else {
3536 args.push(expression(false));
3537 }
3538 if (!is("punc", ")")) {
3539 expect(",");
3540 }
3541 }
3542 next();
3543 return args;
3544 }
3545
3546 var maybe_unary = function(allow_calls, allow_arrows) {
3547 var start = S.token;
3548 if (start.type == "name" && start.value == "await" && can_await()) {
3549 next();
3550 return _await_expression();
3551 }
3552 if (is("operator") && UNARY_PREFIX.has(start.value)) {
3553 next();
3554 handle_regexp();
3555 var ex = make_unary(AST_UnaryPrefix, start, maybe_unary(allow_calls));
3556 ex.start = start;
3557 ex.end = prev();
3558 return ex;
3559 }
3560 var val = expr_atom(allow_calls, allow_arrows);
3561 while (is("operator") && UNARY_POSTFIX.has(S.token.value) && !has_newline_before(S.token)) {
3562 if (val instanceof AST_Arrow) unexpected();
3563 val = make_unary(AST_UnaryPostfix, S.token, val);
3564 val.start = start;
3565 val.end = S.token;
3566 next();
3567 }
3568 return val;
3569 };
3570
3571 function make_unary(ctor, token, expr) {
3572 var op = token.value;
3573 switch (op) {
3574 case "++":
3575 case "--":
3576 if (!is_assignable(expr))
3577 croak("Invalid use of " + op + " operator", token.line, token.col, token.pos);
3578 break;
3579 case "delete":
3580 if (expr instanceof AST_SymbolRef && S.input.has_directive("use strict"))
3581 croak("Calling delete on expression not allowed in strict mode", expr.start.line, expr.start.col, expr.start.pos);
3582 break;
3583 }
3584 return new ctor({ operator: op, expression: expr });
3585 }
3586
3587 var expr_op = function(left, min_prec, no_in) {
3588 var op = is("operator") ? S.token.value : null;
3589 if (op == "in" && no_in) op = null;
3590 if (op == "**" && left instanceof AST_UnaryPrefix
3591 /* unary token in front not allowed - parenthesis required */
3592 && !is_token(left.start, "punc", "(")
3593 && left.operator !== "--" && left.operator !== "++")
3594 unexpected(left.start);
3595 var prec = op != null ? PRECEDENCE[op] : null;
3596 if (prec != null && (prec > min_prec || (op === "**" && min_prec === prec))) {
3597 next();
3598 var right = expr_ops(no_in, prec, true);
3599 return expr_op(new AST_Binary({
3600 start : left.start,
3601 left : left,
3602 operator : op,
3603 right : right,
3604 end : right.end
3605 }), min_prec, no_in);
3606 }
3607 return left;
3608 };
3609
3610 function expr_ops(no_in, min_prec, allow_calls, allow_arrows) {
3611 // maybe_unary won't return us a AST_SymbolPrivateProperty
3612 if (!no_in && min_prec < PRECEDENCE["in"] && is("privatename")) {
3613 if(!S.in_class) {
3614 croak("Private field must be used in an enclosing class");
3615 }
3616
3617 const start = S.token;
3618 const key = new AST_SymbolPrivateProperty({
3619 start,
3620 name: start.value,
3621 end: start
3622 });
3623 next();
3624 expect_token("operator", "in");
3625
3626 const private_in = new AST_PrivateIn({
3627 start,
3628 key,
3629 value: expr_ops(no_in, PRECEDENCE["in"], true),
3630 end: prev()
3631 });
3632
3633 return expr_op(private_in, 0, no_in);
3634 } else {
3635 return expr_op(maybe_unary(allow_calls, allow_arrows), min_prec, no_in);
3636 }
3637 }
3638
3639 var maybe_conditional = function(no_in) {
3640 var start = S.token;
3641 var expr = expr_ops(no_in, 0, true, true);
3642 if (is("operator", "?")) {
3643 next();
3644 var yes = expression(false);
3645 expect(":");
3646 return new AST_Conditional({
3647 start : start,
3648 condition : expr,
3649 consequent : yes,
3650 alternative : expression(false, no_in),
3651 end : prev()
3652 });
3653 }
3654 return expr;
3655 };
3656
3657 function is_assignable(expr) {
3658 return expr instanceof AST_PropAccess || expr instanceof AST_SymbolRef;
3659 }
3660
3661 function to_destructuring(node) {
3662 if (node instanceof AST_Object) {
3663 node = new AST_Destructuring({
3664 start: node.start,
3665 names: node.properties.map(to_destructuring),
3666 is_array: false,
3667 end: node.end
3668 });
3669 } else if (node instanceof AST_Array) {
3670 var names = [];
3671
3672 for (var i = 0; i < node.elements.length; i++) {
3673 // Only allow expansion as last element
3674 if (node.elements[i] instanceof AST_Expansion) {
3675 if (i + 1 !== node.elements.length) {
3676 token_error(node.elements[i].start, "Spread must the be last element in destructuring array");
3677 }
3678 node.elements[i].expression = to_destructuring(node.elements[i].expression);
3679 }
3680
3681 names.push(to_destructuring(node.elements[i]));
3682 }
3683
3684 node = new AST_Destructuring({
3685 start: node.start,
3686 names: names,
3687 is_array: true,
3688 end: node.end
3689 });
3690 } else if (node instanceof AST_ObjectProperty) {
3691 node.value = to_destructuring(node.value);
3692 } else if (node instanceof AST_Assign) {
3693 node = new AST_DefaultAssign({
3694 start: node.start,
3695 left: node.left,
3696 operator: "=",
3697 right: node.right,
3698 end: node.end
3699 });
3700 }
3701 return node;
3702 }
3703
3704 // In ES6, AssignmentExpression can also be an ArrowFunction
3705 var maybe_assign = function(no_in) {
3706 handle_regexp();
3707 var start = S.token;
3708
3709 if (start.type == "name" && start.value == "yield") {
3710 if (is_in_generator()) {
3711 next();
3712 return _yield_expression();
3713 } else if (S.input.has_directive("use strict")) {
3714 token_error(S.token, "Unexpected yield identifier inside strict mode");
3715 }
3716 }
3717
3718 var left = maybe_conditional(no_in);
3719 var val = S.token.value;
3720
3721 if (is("operator") && ASSIGNMENT.has(val)) {
3722 if (is_assignable(left) || (left = to_destructuring(left)) instanceof AST_Destructuring) {
3723 next();
3724
3725 return new AST_Assign({
3726 start : start,
3727 left : left,
3728 operator : val,
3729 right : maybe_assign(no_in),
3730 logical : LOGICAL_ASSIGNMENT.has(val),
3731 end : prev()
3732 });
3733 }
3734 croak("Invalid assignment");
3735 }
3736 return left;
3737 };
3738
3739 var to_expr_or_sequence = function(start, exprs) {
3740 if (exprs.length === 1) {
3741 return exprs[0];
3742 } else if (exprs.length > 1) {
3743 return new AST_Sequence({ start, expressions: exprs, end: peek() });
3744 } else {
3745 croak("Invalid parenthesized expression");
3746 }
3747 };
3748
3749 var expression = function(commas, no_in) {
3750 var start = S.token;
3751 var exprs = [];
3752 while (true) {
3753 exprs.push(maybe_assign(no_in));
3754 if (!commas || !is("punc", ",")) break;
3755 next();
3756 commas = true;
3757 }
3758 return to_expr_or_sequence(start, exprs);
3759 };
3760
3761 function in_loop(cont) {
3762 ++S.in_loop;
3763 var ret = cont();
3764 --S.in_loop;
3765 return ret;
3766 }
3767
3768 if (options.expression) {
3769 return expression(true);
3770 }
3771
3772 return (function parse_toplevel() {
3773 var start = S.token;
3774 var body = [];
3775 S.input.push_directives_stack();
3776 if (options.module) S.input.add_directive("use strict");
3777 while (!is("eof")) {
3778 body.push(statement());
3779 }
3780 S.input.pop_directives_stack();
3781 var end = prev();
3782 var toplevel = options.toplevel;
3783 if (toplevel) {
3784 toplevel.body = toplevel.body.concat(body);
3785 toplevel.end = end;
3786 } else {
3787 toplevel = new AST_Toplevel({ start: start, body: body, end: end });
3788 }
3789 TEMPLATE_RAWS = new Map();
3790 return toplevel;
3791 })();
3792
3793}
3794
3795/***********************************************************************
3796
3797 A JavaScript tokenizer / parser / beautifier / compressor.
3798 https://github.com/mishoo/UglifyJS2
3799
3800 -------------------------------- (C) ---------------------------------
3801
3802 Author: Mihai Bazon
3803 <mihai.bazon@gmail.com>
3804 http://mihai.bazon.net/blog
3805
3806 Distributed under the BSD license:
3807
3808 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
3809
3810 Redistribution and use in source and binary forms, with or without
3811 modification, are permitted provided that the following conditions
3812 are met:
3813
3814 * Redistributions of source code must retain the above
3815 copyright notice, this list of conditions and the following
3816 disclaimer.
3817
3818 * Redistributions in binary form must reproduce the above
3819 copyright notice, this list of conditions and the following
3820 disclaimer in the documentation and/or other materials
3821 provided with the distribution.
3822
3823 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
3824 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3825 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
3826 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
3827 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
3828 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
3829 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
3830 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3831 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
3832 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
3833 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3834 SUCH DAMAGE.
3835
3836 ***********************************************************************/
3837
3838function DEFNODE(type, props, ctor, methods, base = AST_Node) {
3839 if (!props) props = [];
3840 else props = props.split(/\s+/);
3841 var self_props = props;
3842 if (base && base.PROPS)
3843 props = props.concat(base.PROPS);
3844 const proto = base && Object.create(base.prototype);
3845 if (proto) {
3846 ctor.prototype = proto;
3847 ctor.BASE = base;
3848 }
3849 if (base) base.SUBCLASSES.push(ctor);
3850 ctor.prototype.CTOR = ctor;
3851 ctor.prototype.constructor = ctor;
3852 ctor.PROPS = props || null;
3853 ctor.SELF_PROPS = self_props;
3854 ctor.SUBCLASSES = [];
3855 if (type) {
3856 ctor.prototype.TYPE = ctor.TYPE = type;
3857 }
3858 if (methods) for (let i in methods) if (HOP(methods, i)) {
3859 if (i[0] === "$") {
3860 ctor[i.substr(1)] = methods[i];
3861 } else {
3862 ctor.prototype[i] = methods[i];
3863 }
3864 }
3865 ctor.DEFMETHOD = function(name, method) {
3866 this.prototype[name] = method;
3867 };
3868 return ctor;
3869}
3870
3871const has_tok_flag = (tok, flag) => Boolean(tok.flags & flag);
3872const set_tok_flag = (tok, flag, truth) => {
3873 if (truth) {
3874 tok.flags |= flag;
3875 } else {
3876 tok.flags &= ~flag;
3877 }
3878};
3879
3880const TOK_FLAG_NLB = 0b0001;
3881const TOK_FLAG_QUOTE_SINGLE = 0b0010;
3882const TOK_FLAG_QUOTE_EXISTS = 0b0100;
3883const TOK_FLAG_TEMPLATE_END = 0b1000;
3884
3885class AST_Token {
3886 constructor(type, value, line, col, pos, nlb, comments_before, comments_after, file) {
3887 this.flags = (nlb ? 1 : 0);
3888
3889 this.type = type;
3890 this.value = value;
3891 this.line = line;
3892 this.col = col;
3893 this.pos = pos;
3894 this.comments_before = comments_before;
3895 this.comments_after = comments_after;
3896 this.file = file;
3897
3898 Object.seal(this);
3899 }
3900
3901 // Return a string summary of the token for node.js console.log
3902 [Symbol.for("nodejs.util.inspect.custom")](_depth, options) {
3903 const special = str => options.stylize(str, "special");
3904 const quote = typeof this.value === "string" && this.value.includes("`") ? "'" : "`";
3905 const value = `${quote}${this.value}${quote}`;
3906 return `${special("[AST_Token")} ${value} at ${this.line}:${this.col}${special("]")}`;
3907 }
3908
3909 get nlb() {
3910 return has_tok_flag(this, TOK_FLAG_NLB);
3911 }
3912
3913 set nlb(new_nlb) {
3914 set_tok_flag(this, TOK_FLAG_NLB, new_nlb);
3915 }
3916
3917 get quote() {
3918 return !has_tok_flag(this, TOK_FLAG_QUOTE_EXISTS)
3919 ? ""
3920 : (has_tok_flag(this, TOK_FLAG_QUOTE_SINGLE) ? "'" : '"');
3921 }
3922
3923 set quote(quote_type) {
3924 set_tok_flag(this, TOK_FLAG_QUOTE_SINGLE, quote_type === "'");
3925 set_tok_flag(this, TOK_FLAG_QUOTE_EXISTS, !!quote_type);
3926 }
3927
3928 get template_end() {
3929 return has_tok_flag(this, TOK_FLAG_TEMPLATE_END);
3930 }
3931
3932 set template_end(new_template_end) {
3933 set_tok_flag(this, TOK_FLAG_TEMPLATE_END, new_template_end);
3934 }
3935}
3936
3937var AST_Node = DEFNODE("Node", "start end", function AST_Node(props) {
3938 if (props) {
3939 this.start = props.start;
3940 this.end = props.end;
3941 }
3942
3943 this.flags = 0;
3944}, {
3945 _clone: function(deep) {
3946 if (deep) {
3947 var self = this.clone();
3948 return self.transform(new TreeTransformer(function(node) {
3949 if (node !== self) {
3950 return node.clone(true);
3951 }
3952 }));
3953 }
3954 return new this.CTOR(this);
3955 },
3956 clone: function(deep) {
3957 return this._clone(deep);
3958 },
3959 $documentation: "Base class of all AST nodes",
3960 $propdoc: {
3961 start: "[AST_Token] The first token of this node",
3962 end: "[AST_Token] The last token of this node"
3963 },
3964 _walk: function(visitor) {
3965 return visitor._visit(this);
3966 },
3967 walk: function(visitor) {
3968 return this._walk(visitor); // not sure the indirection will be any help
3969 },
3970 _children_backwards: () => {}
3971}, null);
3972
3973/* -----[ statements ]----- */
3974
3975var AST_Statement = DEFNODE("Statement", null, function AST_Statement(props) {
3976 if (props) {
3977 this.start = props.start;
3978 this.end = props.end;
3979 }
3980
3981 this.flags = 0;
3982}, {
3983 $documentation: "Base class of all statements",
3984});
3985
3986var AST_Debugger = DEFNODE("Debugger", null, function AST_Debugger(props) {
3987 if (props) {
3988 this.start = props.start;
3989 this.end = props.end;
3990 }
3991
3992 this.flags = 0;
3993}, {
3994 $documentation: "Represents a debugger statement",
3995}, AST_Statement);
3996
3997var AST_Directive = DEFNODE("Directive", "value quote", function AST_Directive(props) {
3998 if (props) {
3999 this.value = props.value;
4000 this.quote = props.quote;
4001 this.start = props.start;
4002 this.end = props.end;
4003 }
4004
4005 this.flags = 0;
4006}, {
4007 $documentation: "Represents a directive, like \"use strict\";",
4008 $propdoc: {
4009 value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
4010 quote: "[string] the original quote character"
4011 },
4012}, AST_Statement);
4013
4014var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", function AST_SimpleStatement(props) {
4015 if (props) {
4016 this.body = props.body;
4017 this.start = props.start;
4018 this.end = props.end;
4019 }
4020
4021 this.flags = 0;
4022}, {
4023 $documentation: "A statement consisting of an expression, i.e. a = 1 + 2",
4024 $propdoc: {
4025 body: "[AST_Node] an expression node (should not be instanceof AST_Statement)"
4026 },
4027 _walk: function(visitor) {
4028 return visitor._visit(this, function() {
4029 this.body._walk(visitor);
4030 });
4031 },
4032 _children_backwards(push) {
4033 push(this.body);
4034 }
4035}, AST_Statement);
4036
4037function walk_body(node, visitor) {
4038 const body = node.body;
4039 for (var i = 0, len = body.length; i < len; i++) {
4040 body[i]._walk(visitor);
4041 }
4042}
4043
4044function clone_block_scope(deep) {
4045 var clone = this._clone(deep);
4046 if (this.block_scope) {
4047 clone.block_scope = this.block_scope.clone();
4048 }
4049 return clone;
4050}
4051
4052var AST_Block = DEFNODE("Block", "body block_scope", function AST_Block(props) {
4053 if (props) {
4054 this.body = props.body;
4055 this.block_scope = props.block_scope;
4056 this.start = props.start;
4057 this.end = props.end;
4058 }
4059
4060 this.flags = 0;
4061}, {
4062 $documentation: "A body of statements (usually braced)",
4063 $propdoc: {
4064 body: "[AST_Statement*] an array of statements",
4065 block_scope: "[AST_Scope] the block scope"
4066 },
4067 _walk: function(visitor) {
4068 return visitor._visit(this, function() {
4069 walk_body(this, visitor);
4070 });
4071 },
4072 _children_backwards(push) {
4073 let i = this.body.length;
4074 while (i--) push(this.body[i]);
4075 },
4076 clone: clone_block_scope
4077}, AST_Statement);
4078
4079var AST_BlockStatement = DEFNODE("BlockStatement", null, function AST_BlockStatement(props) {
4080 if (props) {
4081 this.body = props.body;
4082 this.block_scope = props.block_scope;
4083 this.start = props.start;
4084 this.end = props.end;
4085 }
4086
4087 this.flags = 0;
4088}, {
4089 $documentation: "A block statement",
4090}, AST_Block);
4091
4092var AST_EmptyStatement = DEFNODE("EmptyStatement", null, function AST_EmptyStatement(props) {
4093 if (props) {
4094 this.start = props.start;
4095 this.end = props.end;
4096 }
4097
4098 this.flags = 0;
4099}, {
4100 $documentation: "The empty statement (empty block or simply a semicolon)"
4101}, AST_Statement);
4102
4103var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", function AST_StatementWithBody(props) {
4104 if (props) {
4105 this.body = props.body;
4106 this.start = props.start;
4107 this.end = props.end;
4108 }
4109
4110 this.flags = 0;
4111}, {
4112 $documentation: "Base class for all statements that contain one nested body: `For`, `ForIn`, `Do`, `While`, `With`",
4113 $propdoc: {
4114 body: "[AST_Statement] the body; this should always be present, even if it's an AST_EmptyStatement"
4115 }
4116}, AST_Statement);
4117
4118var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", function AST_LabeledStatement(props) {
4119 if (props) {
4120 this.label = props.label;
4121 this.body = props.body;
4122 this.start = props.start;
4123 this.end = props.end;
4124 }
4125
4126 this.flags = 0;
4127}, {
4128 $documentation: "Statement with a label",
4129 $propdoc: {
4130 label: "[AST_Label] a label definition"
4131 },
4132 _walk: function(visitor) {
4133 return visitor._visit(this, function() {
4134 this.label._walk(visitor);
4135 this.body._walk(visitor);
4136 });
4137 },
4138 _children_backwards(push) {
4139 push(this.body);
4140 push(this.label);
4141 },
4142 clone: function(deep) {
4143 var node = this._clone(deep);
4144 if (deep) {
4145 var label = node.label;
4146 var def = this.label;
4147 node.walk(new TreeWalker(function(node) {
4148 if (node instanceof AST_LoopControl
4149 && node.label && node.label.thedef === def) {
4150 node.label.thedef = label;
4151 label.references.push(node);
4152 }
4153 }));
4154 }
4155 return node;
4156 }
4157}, AST_StatementWithBody);
4158
4159var AST_IterationStatement = DEFNODE(
4160 "IterationStatement",
4161 "block_scope",
4162 function AST_IterationStatement(props) {
4163 if (props) {
4164 this.block_scope = props.block_scope;
4165 this.body = props.body;
4166 this.start = props.start;
4167 this.end = props.end;
4168 }
4169
4170 this.flags = 0;
4171 },
4172 {
4173 $documentation: "Internal class. All loops inherit from it.",
4174 $propdoc: {
4175 block_scope: "[AST_Scope] the block scope for this iteration statement."
4176 },
4177 clone: clone_block_scope
4178 },
4179 AST_StatementWithBody
4180);
4181
4182var AST_DWLoop = DEFNODE("DWLoop", "condition", function AST_DWLoop(props) {
4183 if (props) {
4184 this.condition = props.condition;
4185 this.block_scope = props.block_scope;
4186 this.body = props.body;
4187 this.start = props.start;
4188 this.end = props.end;
4189 }
4190
4191 this.flags = 0;
4192}, {
4193 $documentation: "Base class for do/while statements",
4194 $propdoc: {
4195 condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement"
4196 }
4197}, AST_IterationStatement);
4198
4199var AST_Do = DEFNODE("Do", null, function AST_Do(props) {
4200 if (props) {
4201 this.condition = props.condition;
4202 this.block_scope = props.block_scope;
4203 this.body = props.body;
4204 this.start = props.start;
4205 this.end = props.end;
4206 }
4207
4208 this.flags = 0;
4209}, {
4210 $documentation: "A `do` statement",
4211 _walk: function(visitor) {
4212 return visitor._visit(this, function() {
4213 this.body._walk(visitor);
4214 this.condition._walk(visitor);
4215 });
4216 },
4217 _children_backwards(push) {
4218 push(this.condition);
4219 push(this.body);
4220 }
4221}, AST_DWLoop);
4222
4223var AST_While = DEFNODE("While", null, function AST_While(props) {
4224 if (props) {
4225 this.condition = props.condition;
4226 this.block_scope = props.block_scope;
4227 this.body = props.body;
4228 this.start = props.start;
4229 this.end = props.end;
4230 }
4231
4232 this.flags = 0;
4233}, {
4234 $documentation: "A `while` statement",
4235 _walk: function(visitor) {
4236 return visitor._visit(this, function() {
4237 this.condition._walk(visitor);
4238 this.body._walk(visitor);
4239 });
4240 },
4241 _children_backwards(push) {
4242 push(this.body);
4243 push(this.condition);
4244 },
4245}, AST_DWLoop);
4246
4247var AST_For = DEFNODE("For", "init condition step", function AST_For(props) {
4248 if (props) {
4249 this.init = props.init;
4250 this.condition = props.condition;
4251 this.step = props.step;
4252 this.block_scope = props.block_scope;
4253 this.body = props.body;
4254 this.start = props.start;
4255 this.end = props.end;
4256 }
4257
4258 this.flags = 0;
4259}, {
4260 $documentation: "A `for` statement",
4261 $propdoc: {
4262 init: "[AST_Node?] the `for` initialization code, or null if empty",
4263 condition: "[AST_Node?] the `for` termination clause, or null if empty",
4264 step: "[AST_Node?] the `for` update clause, or null if empty"
4265 },
4266 _walk: function(visitor) {
4267 return visitor._visit(this, function() {
4268 if (this.init) this.init._walk(visitor);
4269 if (this.condition) this.condition._walk(visitor);
4270 if (this.step) this.step._walk(visitor);
4271 this.body._walk(visitor);
4272 });
4273 },
4274 _children_backwards(push) {
4275 push(this.body);
4276 if (this.step) push(this.step);
4277 if (this.condition) push(this.condition);
4278 if (this.init) push(this.init);
4279 },
4280}, AST_IterationStatement);
4281
4282var AST_ForIn = DEFNODE("ForIn", "init object", function AST_ForIn(props) {
4283 if (props) {
4284 this.init = props.init;
4285 this.object = props.object;
4286 this.block_scope = props.block_scope;
4287 this.body = props.body;
4288 this.start = props.start;
4289 this.end = props.end;
4290 }
4291
4292 this.flags = 0;
4293}, {
4294 $documentation: "A `for ... in` statement",
4295 $propdoc: {
4296 init: "[AST_Node] the `for/in` initialization code",
4297 object: "[AST_Node] the object that we're looping through"
4298 },
4299 _walk: function(visitor) {
4300 return visitor._visit(this, function() {
4301 this.init._walk(visitor);
4302 this.object._walk(visitor);
4303 this.body._walk(visitor);
4304 });
4305 },
4306 _children_backwards(push) {
4307 push(this.body);
4308 if (this.object) push(this.object);
4309 if (this.init) push(this.init);
4310 },
4311}, AST_IterationStatement);
4312
4313var AST_ForOf = DEFNODE("ForOf", "await", function AST_ForOf(props) {
4314 if (props) {
4315 this.await = props.await;
4316 this.init = props.init;
4317 this.object = props.object;
4318 this.block_scope = props.block_scope;
4319 this.body = props.body;
4320 this.start = props.start;
4321 this.end = props.end;
4322 }
4323
4324 this.flags = 0;
4325}, {
4326 $documentation: "A `for ... of` statement",
4327}, AST_ForIn);
4328
4329var AST_With = DEFNODE("With", "expression", function AST_With(props) {
4330 if (props) {
4331 this.expression = props.expression;
4332 this.body = props.body;
4333 this.start = props.start;
4334 this.end = props.end;
4335 }
4336
4337 this.flags = 0;
4338}, {
4339 $documentation: "A `with` statement",
4340 $propdoc: {
4341 expression: "[AST_Node] the `with` expression"
4342 },
4343 _walk: function(visitor) {
4344 return visitor._visit(this, function() {
4345 this.expression._walk(visitor);
4346 this.body._walk(visitor);
4347 });
4348 },
4349 _children_backwards(push) {
4350 push(this.body);
4351 push(this.expression);
4352 },
4353}, AST_StatementWithBody);
4354
4355/* -----[ scope and functions ]----- */
4356
4357var AST_Scope = DEFNODE(
4358 "Scope",
4359 "variables uses_with uses_eval parent_scope enclosed cname",
4360 function AST_Scope(props) {
4361 if (props) {
4362 this.variables = props.variables;
4363 this.uses_with = props.uses_with;
4364 this.uses_eval = props.uses_eval;
4365 this.parent_scope = props.parent_scope;
4366 this.enclosed = props.enclosed;
4367 this.cname = props.cname;
4368 this.body = props.body;
4369 this.block_scope = props.block_scope;
4370 this.start = props.start;
4371 this.end = props.end;
4372 }
4373
4374 this.flags = 0;
4375 },
4376 {
4377 $documentation: "Base class for all statements introducing a lexical scope",
4378 $propdoc: {
4379 variables: "[Map/S] a map of name -> SymbolDef for all variables/functions defined in this scope",
4380 uses_with: "[boolean/S] tells whether this scope uses the `with` statement",
4381 uses_eval: "[boolean/S] tells whether this scope contains a direct call to the global `eval`",
4382 parent_scope: "[AST_Scope?/S] link to the parent scope",
4383 enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes",
4384 cname: "[integer/S] current index for mangling variables (used internally by the mangler)",
4385 },
4386 get_defun_scope: function() {
4387 var self = this;
4388 while (self.is_block_scope()) {
4389 self = self.parent_scope;
4390 }
4391 return self;
4392 },
4393 clone: function(deep, toplevel) {
4394 var node = this._clone(deep);
4395 if (deep && this.variables && toplevel && !this._block_scope) {
4396 node.figure_out_scope({}, {
4397 toplevel: toplevel,
4398 parent_scope: this.parent_scope
4399 });
4400 } else {
4401 if (this.variables) node.variables = new Map(this.variables);
4402 if (this.enclosed) node.enclosed = this.enclosed.slice();
4403 if (this._block_scope) node._block_scope = this._block_scope;
4404 }
4405 return node;
4406 },
4407 pinned: function() {
4408 return this.uses_eval || this.uses_with;
4409 }
4410 },
4411 AST_Block
4412);
4413
4414var AST_Toplevel = DEFNODE("Toplevel", "globals", function AST_Toplevel(props) {
4415 if (props) {
4416 this.globals = props.globals;
4417 this.variables = props.variables;
4418 this.uses_with = props.uses_with;
4419 this.uses_eval = props.uses_eval;
4420 this.parent_scope = props.parent_scope;
4421 this.enclosed = props.enclosed;
4422 this.cname = props.cname;
4423 this.body = props.body;
4424 this.block_scope = props.block_scope;
4425 this.start = props.start;
4426 this.end = props.end;
4427 }
4428
4429 this.flags = 0;
4430}, {
4431 $documentation: "The toplevel scope",
4432 $propdoc: {
4433 globals: "[Map/S] a map of name -> SymbolDef for all undeclared names",
4434 },
4435 wrap_commonjs: function(name) {
4436 var body = this.body;
4437 var wrapped_tl = "(function(exports){'$ORIG';})(typeof " + name + "=='undefined'?(" + name + "={}):" + name + ");";
4438 wrapped_tl = parse(wrapped_tl);
4439 wrapped_tl = wrapped_tl.transform(new TreeTransformer(function(node) {
4440 if (node instanceof AST_Directive && node.value == "$ORIG") {
4441 return MAP.splice(body);
4442 }
4443 }));
4444 return wrapped_tl;
4445 },
4446 wrap_enclose: function(args_values) {
4447 if (typeof args_values != "string") args_values = "";
4448 var index = args_values.indexOf(":");
4449 if (index < 0) index = args_values.length;
4450 var body = this.body;
4451 return parse([
4452 "(function(",
4453 args_values.slice(0, index),
4454 '){"$ORIG"})(',
4455 args_values.slice(index + 1),
4456 ")"
4457 ].join("")).transform(new TreeTransformer(function(node) {
4458 if (node instanceof AST_Directive && node.value == "$ORIG") {
4459 return MAP.splice(body);
4460 }
4461 }));
4462 }
4463}, AST_Scope);
4464
4465var AST_Expansion = DEFNODE("Expansion", "expression", function AST_Expansion(props) {
4466 if (props) {
4467 this.expression = props.expression;
4468 this.start = props.start;
4469 this.end = props.end;
4470 }
4471
4472 this.flags = 0;
4473}, {
4474 $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",
4475 $propdoc: {
4476 expression: "[AST_Node] the thing to be expanded"
4477 },
4478 _walk: function(visitor) {
4479 return visitor._visit(this, function() {
4480 this.expression.walk(visitor);
4481 });
4482 },
4483 _children_backwards(push) {
4484 push(this.expression);
4485 },
4486});
4487
4488var AST_Lambda = DEFNODE(
4489 "Lambda",
4490 "name argnames uses_arguments is_generator async",
4491 function AST_Lambda(props) {
4492 if (props) {
4493 this.name = props.name;
4494 this.argnames = props.argnames;
4495 this.uses_arguments = props.uses_arguments;
4496 this.is_generator = props.is_generator;
4497 this.async = props.async;
4498 this.variables = props.variables;
4499 this.uses_with = props.uses_with;
4500 this.uses_eval = props.uses_eval;
4501 this.parent_scope = props.parent_scope;
4502 this.enclosed = props.enclosed;
4503 this.cname = props.cname;
4504 this.body = props.body;
4505 this.block_scope = props.block_scope;
4506 this.start = props.start;
4507 this.end = props.end;
4508 }
4509
4510 this.flags = 0;
4511 },
4512 {
4513 $documentation: "Base class for functions",
4514 $propdoc: {
4515 name: "[AST_SymbolDeclaration?] the name of this function",
4516 argnames: "[AST_SymbolFunarg|AST_Destructuring|AST_Expansion|AST_DefaultAssign*] array of function arguments, destructurings, or expanding arguments",
4517 uses_arguments: "[boolean/S] tells whether this function accesses the arguments array",
4518 is_generator: "[boolean] is this a generator method",
4519 async: "[boolean] is this method async",
4520 },
4521 args_as_names: function () {
4522 var out = [];
4523 for (var i = 0; i < this.argnames.length; i++) {
4524 if (this.argnames[i] instanceof AST_Destructuring) {
4525 out.push(...this.argnames[i].all_symbols());
4526 } else {
4527 out.push(this.argnames[i]);
4528 }
4529 }
4530 return out;
4531 },
4532 _walk: function(visitor) {
4533 return visitor._visit(this, function() {
4534 if (this.name) this.name._walk(visitor);
4535 var argnames = this.argnames;
4536 for (var i = 0, len = argnames.length; i < len; i++) {
4537 argnames[i]._walk(visitor);
4538 }
4539 walk_body(this, visitor);
4540 });
4541 },
4542 _children_backwards(push) {
4543 let i = this.body.length;
4544 while (i--) push(this.body[i]);
4545
4546 i = this.argnames.length;
4547 while (i--) push(this.argnames[i]);
4548
4549 if (this.name) push(this.name);
4550 },
4551 is_braceless() {
4552 return this.body[0] instanceof AST_Return && this.body[0].value;
4553 },
4554 // Default args and expansion don't count, so .argnames.length doesn't cut it
4555 length_property() {
4556 let length = 0;
4557
4558 for (const arg of this.argnames) {
4559 if (arg instanceof AST_SymbolFunarg || arg instanceof AST_Destructuring) {
4560 length++;
4561 }
4562 }
4563
4564 return length;
4565 }
4566 },
4567 AST_Scope
4568);
4569
4570var AST_Accessor = DEFNODE("Accessor", null, function AST_Accessor(props) {
4571 if (props) {
4572 this.name = props.name;
4573 this.argnames = props.argnames;
4574 this.uses_arguments = props.uses_arguments;
4575 this.is_generator = props.is_generator;
4576 this.async = props.async;
4577 this.variables = props.variables;
4578 this.uses_with = props.uses_with;
4579 this.uses_eval = props.uses_eval;
4580 this.parent_scope = props.parent_scope;
4581 this.enclosed = props.enclosed;
4582 this.cname = props.cname;
4583 this.body = props.body;
4584 this.block_scope = props.block_scope;
4585 this.start = props.start;
4586 this.end = props.end;
4587 }
4588
4589 this.flags = 0;
4590}, {
4591 $documentation: "A setter/getter function. The `name` property is always null."
4592}, AST_Lambda);
4593
4594var AST_Function = DEFNODE("Function", null, function AST_Function(props) {
4595 if (props) {
4596 this.name = props.name;
4597 this.argnames = props.argnames;
4598 this.uses_arguments = props.uses_arguments;
4599 this.is_generator = props.is_generator;
4600 this.async = props.async;
4601 this.variables = props.variables;
4602 this.uses_with = props.uses_with;
4603 this.uses_eval = props.uses_eval;
4604 this.parent_scope = props.parent_scope;
4605 this.enclosed = props.enclosed;
4606 this.cname = props.cname;
4607 this.body = props.body;
4608 this.block_scope = props.block_scope;
4609 this.start = props.start;
4610 this.end = props.end;
4611 }
4612
4613 this.flags = 0;
4614}, {
4615 $documentation: "A function expression"
4616}, AST_Lambda);
4617
4618var AST_Arrow = DEFNODE("Arrow", null, function AST_Arrow(props) {
4619 if (props) {
4620 this.name = props.name;
4621 this.argnames = props.argnames;
4622 this.uses_arguments = props.uses_arguments;
4623 this.is_generator = props.is_generator;
4624 this.async = props.async;
4625 this.variables = props.variables;
4626 this.uses_with = props.uses_with;
4627 this.uses_eval = props.uses_eval;
4628 this.parent_scope = props.parent_scope;
4629 this.enclosed = props.enclosed;
4630 this.cname = props.cname;
4631 this.body = props.body;
4632 this.block_scope = props.block_scope;
4633 this.start = props.start;
4634 this.end = props.end;
4635 }
4636
4637 this.flags = 0;
4638}, {
4639 $documentation: "An ES6 Arrow function ((a) => b)"
4640}, AST_Lambda);
4641
4642var AST_Defun = DEFNODE("Defun", null, function AST_Defun(props) {
4643 if (props) {
4644 this.name = props.name;
4645 this.argnames = props.argnames;
4646 this.uses_arguments = props.uses_arguments;
4647 this.is_generator = props.is_generator;
4648 this.async = props.async;
4649 this.variables = props.variables;
4650 this.uses_with = props.uses_with;
4651 this.uses_eval = props.uses_eval;
4652 this.parent_scope = props.parent_scope;
4653 this.enclosed = props.enclosed;
4654 this.cname = props.cname;
4655 this.body = props.body;
4656 this.block_scope = props.block_scope;
4657 this.start = props.start;
4658 this.end = props.end;
4659 }
4660
4661 this.flags = 0;
4662}, {
4663 $documentation: "A function definition"
4664}, AST_Lambda);
4665
4666/* -----[ DESTRUCTURING ]----- */
4667var AST_Destructuring = DEFNODE("Destructuring", "names is_array", function AST_Destructuring(props) {
4668 if (props) {
4669 this.names = props.names;
4670 this.is_array = props.is_array;
4671 this.start = props.start;
4672 this.end = props.end;
4673 }
4674
4675 this.flags = 0;
4676}, {
4677 $documentation: "A destructuring of several names. Used in destructuring assignment and with destructuring function argument names",
4678 $propdoc: {
4679 "names": "[AST_Node*] Array of properties or elements",
4680 "is_array": "[Boolean] Whether the destructuring represents an object or array"
4681 },
4682 _walk: function(visitor) {
4683 return visitor._visit(this, function() {
4684 this.names.forEach(function(name) {
4685 name._walk(visitor);
4686 });
4687 });
4688 },
4689 _children_backwards(push) {
4690 let i = this.names.length;
4691 while (i--) push(this.names[i]);
4692 },
4693 all_symbols: function() {
4694 var out = [];
4695 walk(this, node => {
4696 if (node instanceof AST_SymbolDeclaration) {
4697 out.push(node);
4698 }
4699 if (node instanceof AST_Lambda) {
4700 return true;
4701 }
4702 });
4703 return out;
4704 }
4705});
4706
4707var AST_PrefixedTemplateString = DEFNODE(
4708 "PrefixedTemplateString",
4709 "template_string prefix",
4710 function AST_PrefixedTemplateString(props) {
4711 if (props) {
4712 this.template_string = props.template_string;
4713 this.prefix = props.prefix;
4714 this.start = props.start;
4715 this.end = props.end;
4716 }
4717
4718 this.flags = 0;
4719 },
4720 {
4721 $documentation: "A templatestring with a prefix, such as String.raw`foobarbaz`",
4722 $propdoc: {
4723 template_string: "[AST_TemplateString] The template string",
4724 prefix: "[AST_Node] The prefix, which will get called."
4725 },
4726 _walk: function(visitor) {
4727 return visitor._visit(this, function () {
4728 this.prefix._walk(visitor);
4729 this.template_string._walk(visitor);
4730 });
4731 },
4732 _children_backwards(push) {
4733 push(this.template_string);
4734 push(this.prefix);
4735 },
4736 }
4737);
4738
4739var AST_TemplateString = DEFNODE("TemplateString", "segments", function AST_TemplateString(props) {
4740 if (props) {
4741 this.segments = props.segments;
4742 this.start = props.start;
4743 this.end = props.end;
4744 }
4745
4746 this.flags = 0;
4747}, {
4748 $documentation: "A template string literal",
4749 $propdoc: {
4750 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."
4751 },
4752 _walk: function(visitor) {
4753 return visitor._visit(this, function() {
4754 this.segments.forEach(function(seg) {
4755 seg._walk(visitor);
4756 });
4757 });
4758 },
4759 _children_backwards(push) {
4760 let i = this.segments.length;
4761 while (i--) push(this.segments[i]);
4762 }
4763});
4764
4765var AST_TemplateSegment = DEFNODE("TemplateSegment", "value raw", function AST_TemplateSegment(props) {
4766 if (props) {
4767 this.value = props.value;
4768 this.raw = props.raw;
4769 this.start = props.start;
4770 this.end = props.end;
4771 }
4772
4773 this.flags = 0;
4774}, {
4775 $documentation: "A segment of a template string literal",
4776 $propdoc: {
4777 value: "Content of the segment",
4778 raw: "Raw source of the segment",
4779 }
4780});
4781
4782/* -----[ JUMPS ]----- */
4783
4784var AST_Jump = DEFNODE("Jump", null, function AST_Jump(props) {
4785 if (props) {
4786 this.start = props.start;
4787 this.end = props.end;
4788 }
4789
4790 this.flags = 0;
4791}, {
4792 $documentation: "Base class for “jumps” (for now that's `return`, `throw`, `break` and `continue`)"
4793}, AST_Statement);
4794
4795/** Base class for “exits” (`return` and `throw`) */
4796var AST_Exit = DEFNODE("Exit", "value", function AST_Exit(props) {
4797 if (props) {
4798 this.value = props.value;
4799 this.start = props.start;
4800 this.end = props.end;
4801 }
4802
4803 this.flags = 0;
4804}, {
4805 $documentation: "Base class for “exits” (`return` and `throw`)",
4806 $propdoc: {
4807 value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return"
4808 },
4809 _walk: function(visitor) {
4810 return visitor._visit(this, this.value && function() {
4811 this.value._walk(visitor);
4812 });
4813 },
4814 _children_backwards(push) {
4815 if (this.value) push(this.value);
4816 },
4817}, AST_Jump);
4818
4819var AST_Return = DEFNODE("Return", null, function AST_Return(props) {
4820 if (props) {
4821 this.value = props.value;
4822 this.start = props.start;
4823 this.end = props.end;
4824 }
4825
4826 this.flags = 0;
4827}, {
4828 $documentation: "A `return` statement"
4829}, AST_Exit);
4830
4831var AST_Throw = DEFNODE("Throw", null, function AST_Throw(props) {
4832 if (props) {
4833 this.value = props.value;
4834 this.start = props.start;
4835 this.end = props.end;
4836 }
4837
4838 this.flags = 0;
4839}, {
4840 $documentation: "A `throw` statement"
4841}, AST_Exit);
4842
4843var AST_LoopControl = DEFNODE("LoopControl", "label", function AST_LoopControl(props) {
4844 if (props) {
4845 this.label = props.label;
4846 this.start = props.start;
4847 this.end = props.end;
4848 }
4849
4850 this.flags = 0;
4851}, {
4852 $documentation: "Base class for loop control statements (`break` and `continue`)",
4853 $propdoc: {
4854 label: "[AST_LabelRef?] the label, or null if none",
4855 },
4856 _walk: function(visitor) {
4857 return visitor._visit(this, this.label && function() {
4858 this.label._walk(visitor);
4859 });
4860 },
4861 _children_backwards(push) {
4862 if (this.label) push(this.label);
4863 },
4864}, AST_Jump);
4865
4866var AST_Break = DEFNODE("Break", null, function AST_Break(props) {
4867 if (props) {
4868 this.label = props.label;
4869 this.start = props.start;
4870 this.end = props.end;
4871 }
4872
4873 this.flags = 0;
4874}, {
4875 $documentation: "A `break` statement"
4876}, AST_LoopControl);
4877
4878var AST_Continue = DEFNODE("Continue", null, function AST_Continue(props) {
4879 if (props) {
4880 this.label = props.label;
4881 this.start = props.start;
4882 this.end = props.end;
4883 }
4884
4885 this.flags = 0;
4886}, {
4887 $documentation: "A `continue` statement"
4888}, AST_LoopControl);
4889
4890var AST_Await = DEFNODE("Await", "expression", function AST_Await(props) {
4891 if (props) {
4892 this.expression = props.expression;
4893 this.start = props.start;
4894 this.end = props.end;
4895 }
4896
4897 this.flags = 0;
4898}, {
4899 $documentation: "An `await` statement",
4900 $propdoc: {
4901 expression: "[AST_Node] the mandatory expression being awaited",
4902 },
4903 _walk: function(visitor) {
4904 return visitor._visit(this, function() {
4905 this.expression._walk(visitor);
4906 });
4907 },
4908 _children_backwards(push) {
4909 push(this.expression);
4910 },
4911});
4912
4913var AST_Yield = DEFNODE("Yield", "expression is_star", function AST_Yield(props) {
4914 if (props) {
4915 this.expression = props.expression;
4916 this.is_star = props.is_star;
4917 this.start = props.start;
4918 this.end = props.end;
4919 }
4920
4921 this.flags = 0;
4922}, {
4923 $documentation: "A `yield` statement",
4924 $propdoc: {
4925 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",
4926 is_star: "[Boolean] Whether this is a yield or yield* statement"
4927 },
4928 _walk: function(visitor) {
4929 return visitor._visit(this, this.expression && function() {
4930 this.expression._walk(visitor);
4931 });
4932 },
4933 _children_backwards(push) {
4934 if (this.expression) push(this.expression);
4935 }
4936});
4937
4938/* -----[ IF ]----- */
4939
4940var AST_If = DEFNODE("If", "condition alternative", function AST_If(props) {
4941 if (props) {
4942 this.condition = props.condition;
4943 this.alternative = props.alternative;
4944 this.body = props.body;
4945 this.start = props.start;
4946 this.end = props.end;
4947 }
4948
4949 this.flags = 0;
4950}, {
4951 $documentation: "A `if` statement",
4952 $propdoc: {
4953 condition: "[AST_Node] the `if` condition",
4954 alternative: "[AST_Statement?] the `else` part, or null if not present"
4955 },
4956 _walk: function(visitor) {
4957 return visitor._visit(this, function() {
4958 this.condition._walk(visitor);
4959 this.body._walk(visitor);
4960 if (this.alternative) this.alternative._walk(visitor);
4961 });
4962 },
4963 _children_backwards(push) {
4964 if (this.alternative) {
4965 push(this.alternative);
4966 }
4967 push(this.body);
4968 push(this.condition);
4969 }
4970}, AST_StatementWithBody);
4971
4972/* -----[ SWITCH ]----- */
4973
4974var AST_Switch = DEFNODE("Switch", "expression", function AST_Switch(props) {
4975 if (props) {
4976 this.expression = props.expression;
4977 this.body = props.body;
4978 this.block_scope = props.block_scope;
4979 this.start = props.start;
4980 this.end = props.end;
4981 }
4982
4983 this.flags = 0;
4984}, {
4985 $documentation: "A `switch` statement",
4986 $propdoc: {
4987 expression: "[AST_Node] the `switch` “discriminant”"
4988 },
4989 _walk: function(visitor) {
4990 return visitor._visit(this, function() {
4991 this.expression._walk(visitor);
4992 walk_body(this, visitor);
4993 });
4994 },
4995 _children_backwards(push) {
4996 let i = this.body.length;
4997 while (i--) push(this.body[i]);
4998 push(this.expression);
4999 }
5000}, AST_Block);
5001
5002var AST_SwitchBranch = DEFNODE("SwitchBranch", null, function AST_SwitchBranch(props) {
5003 if (props) {
5004 this.body = props.body;
5005 this.block_scope = props.block_scope;
5006 this.start = props.start;
5007 this.end = props.end;
5008 }
5009
5010 this.flags = 0;
5011}, {
5012 $documentation: "Base class for `switch` branches",
5013}, AST_Block);
5014
5015var AST_Default = DEFNODE("Default", null, function AST_Default(props) {
5016 if (props) {
5017 this.body = props.body;
5018 this.block_scope = props.block_scope;
5019 this.start = props.start;
5020 this.end = props.end;
5021 }
5022
5023 this.flags = 0;
5024}, {
5025 $documentation: "A `default` switch branch",
5026}, AST_SwitchBranch);
5027
5028var AST_Case = DEFNODE("Case", "expression", function AST_Case(props) {
5029 if (props) {
5030 this.expression = props.expression;
5031 this.body = props.body;
5032 this.block_scope = props.block_scope;
5033 this.start = props.start;
5034 this.end = props.end;
5035 }
5036
5037 this.flags = 0;
5038}, {
5039 $documentation: "A `case` switch branch",
5040 $propdoc: {
5041 expression: "[AST_Node] the `case` expression"
5042 },
5043 _walk: function(visitor) {
5044 return visitor._visit(this, function() {
5045 this.expression._walk(visitor);
5046 walk_body(this, visitor);
5047 });
5048 },
5049 _children_backwards(push) {
5050 let i = this.body.length;
5051 while (i--) push(this.body[i]);
5052 push(this.expression);
5053 },
5054}, AST_SwitchBranch);
5055
5056/* -----[ EXCEPTIONS ]----- */
5057
5058var AST_Try = DEFNODE("Try", "body bcatch bfinally", function AST_Try(props) {
5059 if (props) {
5060 this.body = props.body;
5061 this.bcatch = props.bcatch;
5062 this.bfinally = props.bfinally;
5063 this.start = props.start;
5064 this.end = props.end;
5065 }
5066
5067 this.flags = 0;
5068}, {
5069 $documentation: "A `try` statement",
5070 $propdoc: {
5071 body: "[AST_TryBlock] the try block",
5072 bcatch: "[AST_Catch?] the catch block, or null if not present",
5073 bfinally: "[AST_Finally?] the finally block, or null if not present"
5074 },
5075 _walk: function(visitor) {
5076 return visitor._visit(this, function() {
5077 this.body._walk(visitor);
5078 if (this.bcatch) this.bcatch._walk(visitor);
5079 if (this.bfinally) this.bfinally._walk(visitor);
5080 });
5081 },
5082 _children_backwards(push) {
5083 if (this.bfinally) push(this.bfinally);
5084 if (this.bcatch) push(this.bcatch);
5085 push(this.body);
5086 },
5087}, AST_Statement);
5088
5089var AST_TryBlock = DEFNODE("TryBlock", null, function AST_TryBlock(props) {
5090 if (props) {
5091 this.body = props.body;
5092 this.block_scope = props.block_scope;
5093 this.start = props.start;
5094 this.end = props.end;
5095 }
5096
5097 this.flags = 0;
5098}, {
5099 $documentation: "The `try` block of a try statement"
5100}, AST_Block);
5101
5102var AST_Catch = DEFNODE("Catch", "argname", function AST_Catch(props) {
5103 if (props) {
5104 this.argname = props.argname;
5105 this.body = props.body;
5106 this.block_scope = props.block_scope;
5107 this.start = props.start;
5108 this.end = props.end;
5109 }
5110
5111 this.flags = 0;
5112}, {
5113 $documentation: "A `catch` node; only makes sense as part of a `try` statement",
5114 $propdoc: {
5115 argname: "[AST_SymbolCatch|AST_Destructuring|AST_Expansion|AST_DefaultAssign] symbol for the exception"
5116 },
5117 _walk: function(visitor) {
5118 return visitor._visit(this, function() {
5119 if (this.argname) this.argname._walk(visitor);
5120 walk_body(this, visitor);
5121 });
5122 },
5123 _children_backwards(push) {
5124 let i = this.body.length;
5125 while (i--) push(this.body[i]);
5126 if (this.argname) push(this.argname);
5127 },
5128}, AST_Block);
5129
5130var AST_Finally = DEFNODE("Finally", null, function AST_Finally(props) {
5131 if (props) {
5132 this.body = props.body;
5133 this.block_scope = props.block_scope;
5134 this.start = props.start;
5135 this.end = props.end;
5136 }
5137
5138 this.flags = 0;
5139}, {
5140 $documentation: "A `finally` node; only makes sense as part of a `try` statement"
5141}, AST_Block);
5142
5143/* -----[ VAR/CONST ]----- */
5144
5145var AST_DefinitionsLike = DEFNODE("DefinitionsLike", "definitions", function AST_DefinitionsLike(props) {
5146 if (props) {
5147 this.definitions = props.definitions;
5148 this.start = props.start;
5149 this.end = props.end;
5150 }
5151
5152 this.flags = 0;
5153}, {
5154 $documentation: "Base class for variable definitions and `using`",
5155 $propdoc: {
5156 definitions: "[AST_VarDef*|AST_UsingDef*] array of variable definitions"
5157 },
5158 _walk: function(visitor) {
5159 return visitor._visit(this, function() {
5160 var definitions = this.definitions;
5161 for (var i = 0, len = definitions.length; i < len; i++) {
5162 definitions[i]._walk(visitor);
5163 }
5164 });
5165 },
5166 _children_backwards(push) {
5167 let i = this.definitions.length;
5168 while (i--) push(this.definitions[i]);
5169 },
5170}, AST_Statement);
5171
5172var AST_Definitions = DEFNODE("Definitions", null, function AST_Definitions(props) {
5173 if (props) {
5174 this.definitions = props.definitions;
5175 this.start = props.start;
5176 this.end = props.end;
5177 }
5178
5179 this.flags = 0;
5180}, {
5181 $documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)",
5182}, AST_DefinitionsLike);
5183
5184var AST_Var = DEFNODE("Var", null, function AST_Var(props) {
5185 if (props) {
5186 this.definitions = props.definitions;
5187 this.start = props.start;
5188 this.end = props.end;
5189 }
5190
5191 this.flags = 0;
5192}, {
5193 $documentation: "A `var` statement"
5194}, AST_Definitions);
5195
5196var AST_Let = DEFNODE("Let", null, function AST_Let(props) {
5197 if (props) {
5198 this.definitions = props.definitions;
5199 this.start = props.start;
5200 this.end = props.end;
5201 }
5202
5203 this.flags = 0;
5204}, {
5205 $documentation: "A `let` statement"
5206}, AST_Definitions);
5207
5208var AST_Const = DEFNODE("Const", null, function AST_Const(props) {
5209 if (props) {
5210 this.definitions = props.definitions;
5211 this.start = props.start;
5212 this.end = props.end;
5213 }
5214
5215 this.flags = 0;
5216}, {
5217 $documentation: "A `const` statement"
5218}, AST_Definitions);
5219
5220var AST_Using = DEFNODE("Using", "await", function AST_Using(props) {
5221 if (props) {
5222 this.await = props.await;
5223 this.definitions = props.definitions;
5224 this.start = props.start;
5225 this.end = props.end;
5226 }
5227
5228 this.flags = 0;
5229}, {
5230 $documentation: "A `using` statement",
5231 $propdoc: {
5232 await: "[boolean] Whether it's `await using`"
5233 },
5234}, AST_DefinitionsLike);
5235
5236var AST_VarDefLike = DEFNODE("VarDefLike", "name value", function AST_VarDefLike(props) {
5237 if (props) {
5238 this.name = props.name;
5239 this.value = props.value;
5240 this.start = props.start;
5241 this.end = props.end;
5242 }
5243
5244 this.flags = 0;
5245}, {
5246 $documentation: "A name=value pair in a variable definition statement or `using`",
5247 $propdoc: {
5248 name: "[AST_Destructuring|AST_SymbolDeclaration] name of the variable",
5249 value: "[AST_Node?] initializer, or null of there's no initializer"
5250 },
5251 _walk: function(visitor) {
5252 return visitor._visit(this, function() {
5253 this.name._walk(visitor);
5254 if (this.value) this.value._walk(visitor);
5255 });
5256 },
5257 _children_backwards(push) {
5258 if (this.value) push(this.value);
5259 push(this.name);
5260 },
5261 declarations_as_names() {
5262 if (this.name instanceof AST_SymbolDeclaration) {
5263 return [this.name];
5264 } else {
5265 return this.name.all_symbols();
5266 }
5267 }
5268});
5269
5270var AST_VarDef = DEFNODE("VarDef", null, function AST_VarDef(props) {
5271 if (props) {
5272 this.name = props.name;
5273 this.value = props.value;
5274 this.start = props.start;
5275 this.end = props.end;
5276 }
5277
5278 this.flags = 0;
5279}, {
5280 $documentation: "A variable declaration; only appears in a AST_Definitions node",
5281}, AST_VarDefLike);
5282
5283var AST_UsingDef = DEFNODE("UsingDef", null, function AST_UsingDef(props) {
5284 if (props) {
5285 this.name = props.name;
5286 this.value = props.value;
5287 this.start = props.start;
5288 this.end = props.end;
5289 }
5290
5291 this.flags = 0;
5292}, {
5293 $documentation: "Like VarDef but specific to AST_Using",
5294}, AST_VarDefLike);
5295
5296var AST_NameMapping = DEFNODE("NameMapping", "foreign_name name", function AST_NameMapping(props) {
5297 if (props) {
5298 this.foreign_name = props.foreign_name;
5299 this.name = props.name;
5300 this.start = props.start;
5301 this.end = props.end;
5302 }
5303
5304 this.flags = 0;
5305}, {
5306 $documentation: "The part of the export/import statement that declare names from a module.",
5307 $propdoc: {
5308 foreign_name: "[AST_SymbolExportForeign|AST_SymbolImportForeign] The name being exported/imported (as specified in the module)",
5309 name: "[AST_SymbolExport|AST_SymbolImport] The name as it is visible to this module."
5310 },
5311 _walk: function (visitor) {
5312 return visitor._visit(this, function() {
5313 this.foreign_name._walk(visitor);
5314 this.name._walk(visitor);
5315 });
5316 },
5317 _children_backwards(push) {
5318 push(this.name);
5319 push(this.foreign_name);
5320 },
5321});
5322
5323var AST_Import = DEFNODE(
5324 "Import",
5325 "phase imported_name imported_names module_name attributes",
5326 function AST_Import(props) {
5327 if (props) {
5328 this.phase = props.phase;
5329 this.imported_name = props.imported_name;
5330 this.imported_names = props.imported_names;
5331 this.module_name = props.module_name;
5332 this.attributes = props.attributes;
5333 this.start = props.start;
5334 this.end = props.end;
5335 }
5336
5337 this.flags = 0;
5338 },
5339 {
5340 $documentation: "An `import` statement",
5341 $propdoc: {
5342 phase: "[string?] Phase keyword: 'source', 'defer', or null.",
5343 imported_name: "[AST_SymbolImport] The name of the variable holding the module's default export.",
5344 imported_names: "[AST_NameMapping*] The names of non-default imported variables",
5345 module_name: "[AST_String] String literal describing where this module came from",
5346 attributes: "[AST_Object?] The import attributes (with {...})"
5347 },
5348 _walk: function(visitor) {
5349 return visitor._visit(this, function() {
5350 if (this.imported_name) {
5351 this.imported_name._walk(visitor);
5352 }
5353 if (this.imported_names) {
5354 this.imported_names.forEach(function(name_import) {
5355 name_import._walk(visitor);
5356 });
5357 }
5358 this.module_name._walk(visitor);
5359 });
5360 },
5361 _children_backwards(push) {
5362 push(this.module_name);
5363 if (this.imported_names) {
5364 let i = this.imported_names.length;
5365 while (i--) push(this.imported_names[i]);
5366 }
5367 if (this.imported_name) push(this.imported_name);
5368 },
5369 }
5370);
5371
5372var AST_ImportMeta = DEFNODE("ImportMeta", null, function AST_ImportMeta(props) {
5373 if (props) {
5374 this.start = props.start;
5375 this.end = props.end;
5376 }
5377
5378 this.flags = 0;
5379}, {
5380 $documentation: "A reference to import.meta",
5381});
5382
5383var AST_DynamicImport = DEFNODE(
5384 "DynamicImport",
5385 "phase args",
5386 function AST_DynamicImport(props) {
5387 if (props) {
5388 this.phase = props.phase;
5389 this.args = props.args;
5390 this.start = props.start;
5391 this.end = props.end;
5392 }
5393
5394 this.flags = 0;
5395 },
5396 {
5397 $documentation: "A phased dynamic import expression: `import.source(specifier [, options])` or `import.defer(specifier [, options])`. Plain `import(x)` continues to be parsed as an AST_Call with a synthetic `import` SymbolRef callee.",
5398 $propdoc: {
5399 phase: "[string] Phase keyword ('source' or 'defer').",
5400 args: "[AST_Node*] specifier followed by optional options argument"
5401 },
5402 _walk: function(visitor) {
5403 return visitor._visit(this, function() {
5404 var args = this.args;
5405 for (var i = 0, len = args.length; i < len; i++) {
5406 args[i]._walk(visitor);
5407 }
5408 });
5409 },
5410 _children_backwards(push) {
5411 let i = this.args.length;
5412 while (i--) push(this.args[i]);
5413 },
5414 }
5415);
5416
5417var AST_Export = DEFNODE(
5418 "Export",
5419 "exported_definition exported_value is_default exported_names module_name attributes",
5420 function AST_Export(props) {
5421 if (props) {
5422 this.exported_definition = props.exported_definition;
5423 this.exported_value = props.exported_value;
5424 this.is_default = props.is_default;
5425 this.exported_names = props.exported_names;
5426 this.module_name = props.module_name;
5427 this.attributes = props.attributes;
5428 this.start = props.start;
5429 this.end = props.end;
5430 }
5431
5432 this.flags = 0;
5433 },
5434 {
5435 $documentation: "An `export` statement",
5436 $propdoc: {
5437 exported_definition: "[AST_Defun|AST_Definitions|AST_DefClass?] An exported definition",
5438 exported_value: "[AST_Node?] An exported value",
5439 exported_names: "[AST_NameMapping*?] List of exported names",
5440 module_name: "[AST_String?] Name of the file to load exports from",
5441 is_default: "[Boolean] Whether this is the default exported value of this module",
5442 attributes: "[AST_Object?] The import attributes"
5443 },
5444 _walk: function (visitor) {
5445 return visitor._visit(this, function () {
5446 if (this.exported_definition) {
5447 this.exported_definition._walk(visitor);
5448 }
5449 if (this.exported_value) {
5450 this.exported_value._walk(visitor);
5451 }
5452 if (this.exported_names) {
5453 this.exported_names.forEach(function(name_export) {
5454 name_export._walk(visitor);
5455 });
5456 }
5457 if (this.module_name) {
5458 this.module_name._walk(visitor);
5459 }
5460 });
5461 },
5462 _children_backwards(push) {
5463 if (this.module_name) push(this.module_name);
5464 if (this.exported_names) {
5465 let i = this.exported_names.length;
5466 while (i--) push(this.exported_names[i]);
5467 }
5468 if (this.exported_value) push(this.exported_value);
5469 if (this.exported_definition) push(this.exported_definition);
5470 }
5471 },
5472 AST_Statement
5473);
5474
5475/* -----[ OTHER ]----- */
5476
5477var AST_Call = DEFNODE(
5478 "Call",
5479 "expression args optional _annotations",
5480 function AST_Call(props) {
5481 if (props) {
5482 this.expression = props.expression;
5483 this.args = props.args;
5484 this.optional = props.optional;
5485 this._annotations = props._annotations;
5486 this.start = props.start;
5487 this.end = props.end;
5488 this.initialize();
5489 }
5490
5491 this.flags = 0;
5492 },
5493 {
5494 $documentation: "A function call expression",
5495 $propdoc: {
5496 expression: "[AST_Node] expression to invoke as function",
5497 args: "[AST_Node*] array of arguments",
5498 optional: "[boolean] whether this is an optional call (IE ?.() )",
5499 _annotations: "[number] bitfield containing information about the call"
5500 },
5501 initialize() {
5502 if (this._annotations == null) this._annotations = 0;
5503 },
5504 _walk(visitor) {
5505 return visitor._visit(this, function() {
5506 var args = this.args;
5507 for (var i = 0, len = args.length; i < len; i++) {
5508 args[i]._walk(visitor);
5509 }
5510 this.expression._walk(visitor); // TODO why do we need to crawl this last?
5511 });
5512 },
5513 _children_backwards(push) {
5514 let i = this.args.length;
5515 while (i--) push(this.args[i]);
5516 push(this.expression);
5517 },
5518 }
5519);
5520
5521var AST_New = DEFNODE("New", null, function AST_New(props) {
5522 if (props) {
5523 this.expression = props.expression;
5524 this.args = props.args;
5525 this.optional = props.optional;
5526 this._annotations = props._annotations;
5527 this.start = props.start;
5528 this.end = props.end;
5529 this.initialize();
5530 }
5531
5532 this.flags = 0;
5533}, {
5534 $documentation: "An object instantiation. Derives from a function call since it has exactly the same properties"
5535}, AST_Call);
5536
5537var AST_Sequence = DEFNODE("Sequence", "expressions", function AST_Sequence(props) {
5538 if (props) {
5539 this.expressions = props.expressions;
5540 this.start = props.start;
5541 this.end = props.end;
5542 }
5543
5544 this.flags = 0;
5545}, {
5546 $documentation: "A sequence expression (comma-separated expressions)",
5547 $propdoc: {
5548 expressions: "[AST_Node*] array of expressions (at least two)"
5549 },
5550 _walk: function(visitor) {
5551 return visitor._visit(this, function() {
5552 this.expressions.forEach(function(node) {
5553 node._walk(visitor);
5554 });
5555 });
5556 },
5557 _children_backwards(push) {
5558 let i = this.expressions.length;
5559 while (i--) push(this.expressions[i]);
5560 },
5561});
5562
5563var AST_PropAccess = DEFNODE(
5564 "PropAccess",
5565 "expression property optional",
5566 function AST_PropAccess(props) {
5567 if (props) {
5568 this.expression = props.expression;
5569 this.property = props.property;
5570 this.optional = props.optional;
5571 this.start = props.start;
5572 this.end = props.end;
5573 }
5574
5575 this.flags = 0;
5576 },
5577 {
5578 $documentation: "Base class for property access expressions, i.e. `a.foo` or `a[\"foo\"]`",
5579 $propdoc: {
5580 expression: "[AST_Node] the “container” expression",
5581 property: "[AST_Node|string] the property to access. For AST_Dot & AST_DotHash this is always a plain string, while for AST_Sub it's an arbitrary AST_Node",
5582
5583 optional: "[boolean] whether this is an optional property access (IE ?.)"
5584 }
5585 }
5586);
5587
5588var AST_Dot = DEFNODE("Dot", "quote", function AST_Dot(props) {
5589 if (props) {
5590 this.quote = props.quote;
5591 this.expression = props.expression;
5592 this.property = props.property;
5593 this.optional = props.optional;
5594 this._annotations = props._annotations;
5595 this.start = props.start;
5596 this.end = props.end;
5597 }
5598
5599 this.flags = 0;
5600}, {
5601 $documentation: "A dotted property access expression",
5602 $propdoc: {
5603 quote: "[string] the original quote character when transformed from AST_Sub",
5604 },
5605 _walk: function(visitor) {
5606 return visitor._visit(this, function() {
5607 this.expression._walk(visitor);
5608 });
5609 },
5610 _children_backwards(push) {
5611 push(this.expression);
5612 },
5613}, AST_PropAccess);
5614
5615var AST_DotHash = DEFNODE("DotHash", "", function AST_DotHash(props) {
5616 if (props) {
5617 this.expression = props.expression;
5618 this.property = props.property;
5619 this.optional = props.optional;
5620 this.start = props.start;
5621 this.end = props.end;
5622 }
5623
5624 this.flags = 0;
5625}, {
5626 $documentation: "A dotted property access to a private property",
5627 _walk: function(visitor) {
5628 return visitor._visit(this, function() {
5629 this.expression._walk(visitor);
5630 });
5631 },
5632 _children_backwards(push) {
5633 push(this.expression);
5634 },
5635}, AST_PropAccess);
5636
5637var AST_Sub = DEFNODE("Sub", null, function AST_Sub(props) {
5638 if (props) {
5639 this.expression = props.expression;
5640 this.property = props.property;
5641 this.optional = props.optional;
5642 this._annotations = props._annotations;
5643 this.start = props.start;
5644 this.end = props.end;
5645 }
5646
5647 this.flags = 0;
5648}, {
5649 $documentation: "Index-style property access, i.e. `a[\"foo\"]`",
5650 _walk: function(visitor) {
5651 return visitor._visit(this, function() {
5652 this.expression._walk(visitor);
5653 this.property._walk(visitor);
5654 });
5655 },
5656 _children_backwards(push) {
5657 push(this.property);
5658 push(this.expression);
5659 },
5660}, AST_PropAccess);
5661
5662var AST_Chain = DEFNODE("Chain", "expression", function AST_Chain(props) {
5663 if (props) {
5664 this.expression = props.expression;
5665 this.start = props.start;
5666 this.end = props.end;
5667 }
5668
5669 this.flags = 0;
5670}, {
5671 $documentation: "A chain expression like a?.b?.(c)?.[d]",
5672 $propdoc: {
5673 expression: "[AST_Call|AST_Dot|AST_DotHash|AST_Sub] chain element."
5674 },
5675 _walk: function (visitor) {
5676 return visitor._visit(this, function() {
5677 this.expression._walk(visitor);
5678 });
5679 },
5680 _children_backwards(push) {
5681 push(this.expression);
5682 },
5683});
5684
5685var AST_Unary = DEFNODE("Unary", "operator expression", function AST_Unary(props) {
5686 if (props) {
5687 this.operator = props.operator;
5688 this.expression = props.expression;
5689 this.start = props.start;
5690 this.end = props.end;
5691 }
5692
5693 this.flags = 0;
5694}, {
5695 $documentation: "Base class for unary expressions",
5696 $propdoc: {
5697 operator: "[string] the operator",
5698 expression: "[AST_Node] expression that this unary operator applies to"
5699 },
5700 _walk: function(visitor) {
5701 return visitor._visit(this, function() {
5702 this.expression._walk(visitor);
5703 });
5704 },
5705 _children_backwards(push) {
5706 push(this.expression);
5707 },
5708});
5709
5710var AST_UnaryPrefix = DEFNODE("UnaryPrefix", null, function AST_UnaryPrefix(props) {
5711 if (props) {
5712 this.operator = props.operator;
5713 this.expression = props.expression;
5714 this.start = props.start;
5715 this.end = props.end;
5716 }
5717
5718 this.flags = 0;
5719}, {
5720 $documentation: "Unary prefix expression, i.e. `typeof i` or `++i`"
5721}, AST_Unary);
5722
5723var AST_UnaryPostfix = DEFNODE("UnaryPostfix", null, function AST_UnaryPostfix(props) {
5724 if (props) {
5725 this.operator = props.operator;
5726 this.expression = props.expression;
5727 this.start = props.start;
5728 this.end = props.end;
5729 }
5730
5731 this.flags = 0;
5732}, {
5733 $documentation: "Unary postfix expression, i.e. `i++`"
5734}, AST_Unary);
5735
5736var AST_Binary = DEFNODE("Binary", "operator left right", function AST_Binary(props) {
5737 if (props) {
5738 this.operator = props.operator;
5739 this.left = props.left;
5740 this.right = props.right;
5741 this.start = props.start;
5742 this.end = props.end;
5743 }
5744
5745 this.flags = 0;
5746}, {
5747 $documentation: "Binary expression, i.e. `a + b`",
5748 $propdoc: {
5749 left: "[AST_Node] left-hand side expression",
5750 operator: "[string] the operator",
5751 right: "[AST_Node] right-hand side expression"
5752 },
5753 _walk: function(visitor) {
5754 return visitor._visit(this, function() {
5755 this.left._walk(visitor);
5756 this.right._walk(visitor);
5757 });
5758 },
5759 _children_backwards(push) {
5760 push(this.right);
5761 push(this.left);
5762 },
5763});
5764
5765var AST_Conditional = DEFNODE(
5766 "Conditional",
5767 "condition consequent alternative",
5768 function AST_Conditional(props) {
5769 if (props) {
5770 this.condition = props.condition;
5771 this.consequent = props.consequent;
5772 this.alternative = props.alternative;
5773 this.start = props.start;
5774 this.end = props.end;
5775 }
5776
5777 this.flags = 0;
5778 },
5779 {
5780 $documentation: "Conditional expression using the ternary operator, i.e. `a ? b : c`",
5781 $propdoc: {
5782 condition: "[AST_Node]",
5783 consequent: "[AST_Node]",
5784 alternative: "[AST_Node]"
5785 },
5786 _walk: function(visitor) {
5787 return visitor._visit(this, function() {
5788 this.condition._walk(visitor);
5789 this.consequent._walk(visitor);
5790 this.alternative._walk(visitor);
5791 });
5792 },
5793 _children_backwards(push) {
5794 push(this.alternative);
5795 push(this.consequent);
5796 push(this.condition);
5797 },
5798 }
5799);
5800
5801var AST_Assign = DEFNODE("Assign", "logical", function AST_Assign(props) {
5802 if (props) {
5803 this.logical = props.logical;
5804 this.operator = props.operator;
5805 this.left = props.left;
5806 this.right = props.right;
5807 this.start = props.start;
5808 this.end = props.end;
5809 }
5810
5811 this.flags = 0;
5812}, {
5813 $documentation: "An assignment expression — `a = b + 5`",
5814 $propdoc: {
5815 logical: "Whether it's a logical assignment"
5816 }
5817}, AST_Binary);
5818
5819var AST_DefaultAssign = DEFNODE("DefaultAssign", null, function AST_DefaultAssign(props) {
5820 if (props) {
5821 this.operator = props.operator;
5822 this.left = props.left;
5823 this.right = props.right;
5824 this.start = props.start;
5825 this.end = props.end;
5826 }
5827
5828 this.flags = 0;
5829}, {
5830 $documentation: "A default assignment expression like in `(a = 3) => a`"
5831}, AST_Binary);
5832
5833/* -----[ LITERALS ]----- */
5834
5835var AST_Array = DEFNODE("Array", "elements", function AST_Array(props) {
5836 if (props) {
5837 this.elements = props.elements;
5838 this.start = props.start;
5839 this.end = props.end;
5840 }
5841
5842 this.flags = 0;
5843}, {
5844 $documentation: "An array literal",
5845 $propdoc: {
5846 elements: "[AST_Node*] array of elements"
5847 },
5848 _walk: function(visitor) {
5849 return visitor._visit(this, function() {
5850 var elements = this.elements;
5851 for (var i = 0, len = elements.length; i < len; i++) {
5852 elements[i]._walk(visitor);
5853 }
5854 });
5855 },
5856 _children_backwards(push) {
5857 let i = this.elements.length;
5858 while (i--) push(this.elements[i]);
5859 },
5860});
5861
5862var AST_Object = DEFNODE("Object", "properties", function AST_Object(props) {
5863 if (props) {
5864 this.properties = props.properties;
5865 this.start = props.start;
5866 this.end = props.end;
5867 }
5868
5869 this.flags = 0;
5870}, {
5871 $documentation: "An object literal",
5872 $propdoc: {
5873 properties: "[AST_ObjectProperty*] array of properties"
5874 },
5875 _walk: function(visitor) {
5876 return visitor._visit(this, function() {
5877 var properties = this.properties;
5878 for (var i = 0, len = properties.length; i < len; i++) {
5879 properties[i]._walk(visitor);
5880 }
5881 });
5882 },
5883 _children_backwards(push) {
5884 let i = this.properties.length;
5885 while (i--) push(this.properties[i]);
5886 },
5887});
5888
5889/* -----[ OBJECT/CLASS PROPERTIES ]----- */
5890
5891/**
5892 * Everything inside the curly braces of an object/class is a subclass of AST_ObjectProperty, except for AST_ClassStaticBlock.
5893 **/
5894var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", function AST_ObjectProperty(props) {
5895 if (props) {
5896 this.key = props.key;
5897 this.value = props.value;
5898 this.start = props.start;
5899 this.end = props.end;
5900 this._annotations = props._annotations;
5901 }
5902
5903 this.flags = 0;
5904}, {
5905 $documentation: "Base class for literal object properties",
5906 $propdoc: {
5907 key: "[string|AST_Node] property name. For ObjectKeyVal this is a string. For getters, setters and computed property this is an AST_Node.",
5908 value: "[AST_Node] property value. For getters, setters and methods this is an AST_Accessor."
5909 },
5910 _walk: function(visitor) {
5911 return visitor._visit(this, function() {
5912 if (this.key instanceof AST_Node)
5913 this.key._walk(visitor);
5914 this.value._walk(visitor);
5915 });
5916 },
5917 _children_backwards(push) {
5918 push(this.value);
5919 if (this.key instanceof AST_Node) push(this.key);
5920 },
5921});
5922
5923var AST_ObjectKeyVal = DEFNODE("ObjectKeyVal", "quote", function AST_ObjectKeyVal(props) {
5924 if (props) {
5925 this.quote = props.quote;
5926 this.key = props.key;
5927 this.value = props.value;
5928 this.start = props.start;
5929 this.end = props.end;
5930 this._annotations = props._annotations;
5931 }
5932
5933 this.flags = 0;
5934}, {
5935 $documentation: "A key: value object property",
5936 $propdoc: {
5937 quote: "[string] the original quote character"
5938 },
5939 computed_key() {
5940 return this.key instanceof AST_Node;
5941 }
5942}, AST_ObjectProperty);
5943
5944var AST_PrivateSetter = DEFNODE("PrivateSetter", "static", function AST_PrivateSetter(props) {
5945 if (props) {
5946 this.static = props.static;
5947 this.key = props.key;
5948 this.value = props.value;
5949 this.start = props.start;
5950 this.end = props.end;
5951 }
5952
5953 this.flags = 0;
5954}, {
5955 $propdoc: {
5956 static: "[boolean] whether this is a static private setter"
5957 },
5958 $documentation: "A private setter property",
5959 computed_key() {
5960 return false;
5961 }
5962}, AST_ObjectProperty);
5963
5964var AST_PrivateGetter = DEFNODE("PrivateGetter", "static", function AST_PrivateGetter(props) {
5965 if (props) {
5966 this.static = props.static;
5967 this.key = props.key;
5968 this.value = props.value;
5969 this.start = props.start;
5970 this.end = props.end;
5971 }
5972
5973 this.flags = 0;
5974}, {
5975 $propdoc: {
5976 static: "[boolean] whether this is a static private getter"
5977 },
5978 $documentation: "A private getter property",
5979 computed_key() {
5980 return false;
5981 }
5982}, AST_ObjectProperty);
5983
5984var AST_ObjectSetter = DEFNODE("ObjectSetter", "quote static", function AST_ObjectSetter(props) {
5985 if (props) {
5986 this.quote = props.quote;
5987 this.static = props.static;
5988 this.key = props.key;
5989 this.value = props.value;
5990 this.start = props.start;
5991 this.end = props.end;
5992 this._annotations = props._annotations;
5993 }
5994
5995 this.flags = 0;
5996}, {
5997 $propdoc: {
5998 quote: "[string|undefined] the original quote character, if any",
5999 static: "[boolean] whether this is a static setter (classes only)"
6000 },
6001 $documentation: "An object setter property",
6002 computed_key() {
6003 return !(this.key instanceof AST_SymbolMethod);
6004 }
6005}, AST_ObjectProperty);
6006
6007var AST_ObjectGetter = DEFNODE("ObjectGetter", "quote static", function AST_ObjectGetter(props) {
6008 if (props) {
6009 this.quote = props.quote;
6010 this.static = props.static;
6011 this.key = props.key;
6012 this.value = props.value;
6013 this.start = props.start;
6014 this.end = props.end;
6015 this._annotations = props._annotations;
6016 }
6017
6018 this.flags = 0;
6019}, {
6020 $propdoc: {
6021 quote: "[string|undefined] the original quote character, if any",
6022 static: "[boolean] whether this is a static getter (classes only)"
6023 },
6024 $documentation: "An object getter property",
6025 computed_key() {
6026 return !(this.key instanceof AST_SymbolMethod);
6027 }
6028}, AST_ObjectProperty);
6029
6030var AST_ConciseMethod = DEFNODE("ConciseMethod", "quote static", function AST_ConciseMethod(props) {
6031 if (props) {
6032 this.quote = props.quote;
6033 this.static = props.static;
6034 this.key = props.key;
6035 this.value = props.value;
6036 this.start = props.start;
6037 this.end = props.end;
6038 this._annotations = props._annotations;
6039 }
6040
6041 this.flags = 0;
6042}, {
6043 $propdoc: {
6044 quote: "[string|undefined] the original quote character, if any",
6045 static: "[boolean] is this method static (classes only)",
6046 },
6047 $documentation: "An ES6 concise method inside an object or class",
6048 computed_key() {
6049 return !(this.key instanceof AST_SymbolMethod);
6050 }
6051}, AST_ObjectProperty);
6052
6053var AST_PrivateMethod = DEFNODE("PrivateMethod", "static", function AST_PrivateMethod(props) {
6054 if (props) {
6055 this.static = props.static;
6056 this.key = props.key;
6057 this.value = props.value;
6058 this.start = props.start;
6059 this.end = props.end;
6060 }
6061
6062 this.flags = 0;
6063}, {
6064 $documentation: "A private class method inside a class",
6065 $propdoc: {
6066 static: "[boolean] is this a static private method",
6067 },
6068 computed_key() {
6069 return false;
6070 },
6071}, AST_ObjectProperty);
6072
6073var AST_Class = DEFNODE("Class", "name extends properties", function AST_Class(props) {
6074 if (props) {
6075 this.name = props.name;
6076 this.extends = props.extends;
6077 this.properties = props.properties;
6078 this.variables = props.variables;
6079 this.uses_with = props.uses_with;
6080 this.uses_eval = props.uses_eval;
6081 this.parent_scope = props.parent_scope;
6082 this.enclosed = props.enclosed;
6083 this.cname = props.cname;
6084 this.body = props.body;
6085 this.block_scope = props.block_scope;
6086 this.start = props.start;
6087 this.end = props.end;
6088 }
6089
6090 this.flags = 0;
6091}, {
6092 $propdoc: {
6093 name: "[AST_SymbolClass|AST_SymbolDefClass?] optional class name.",
6094 extends: "[AST_Node]? optional parent class",
6095 properties: "[AST_ObjectProperty|AST_ClassStaticBlock]* array of properties or static blocks"
6096 },
6097 $documentation: "An ES6 class",
6098 _walk: function(visitor) {
6099 return visitor._visit(this, function() {
6100 if (this.name) {
6101 this.name._walk(visitor);
6102 }
6103 if (this.extends) {
6104 this.extends._walk(visitor);
6105 }
6106 this.properties.forEach((prop) => prop._walk(visitor));
6107 });
6108 },
6109 _children_backwards(push) {
6110 let i = this.properties.length;
6111 while (i--) push(this.properties[i]);
6112 if (this.extends) push(this.extends);
6113 if (this.name) push(this.name);
6114 },
6115 /** go through the bits that are executed instantly, not when the class is `new`'d. Doesn't walk the name. */
6116 visit_nondeferred_class_parts(visitor) {
6117 if (this.extends) {
6118 this.extends._walk(visitor);
6119 }
6120 this.properties.forEach((prop) => {
6121 if (prop instanceof AST_ClassStaticBlock) {
6122 prop._walk(visitor);
6123 return;
6124 }
6125 if (prop.computed_key()) {
6126 visitor.push(prop);
6127 prop.key._walk(visitor);
6128 visitor.pop();
6129 }
6130 if (
6131 prop instanceof AST_ClassPrivateProperty && prop.static && prop.value
6132 || prop instanceof AST_ClassProperty && prop.static && prop.value
6133 ) {
6134 visitor.push(prop);
6135 prop.value._walk(visitor);
6136 visitor.pop();
6137 }
6138 });
6139 },
6140 /** go through the bits that are executed later, when the class is `new`'d or a static method is called */
6141 visit_deferred_class_parts(visitor) {
6142 this.properties.forEach((prop) => {
6143 if (
6144 prop instanceof AST_ConciseMethod
6145 || prop instanceof AST_PrivateMethod
6146 ) {
6147 prop.walk(visitor);
6148 } else if (
6149 prop instanceof AST_ClassProperty && !prop.static && prop.value
6150 || prop instanceof AST_ClassPrivateProperty && !prop.static && prop.value
6151 ) {
6152 visitor.push(prop);
6153 prop.value._walk(visitor);
6154 visitor.pop();
6155 }
6156 });
6157 },
6158 is_self_referential: function() {
6159 const this_id = this.name && this.name.definition().id;
6160 let found = false;
6161 let class_this = true;
6162 this.visit_nondeferred_class_parts(new TreeWalker((node, descend) => {
6163 if (found) return true;
6164 if (node instanceof AST_This) return (found = class_this);
6165 if (node instanceof AST_SymbolRef) return (found = node.definition().id === this_id);
6166 if (node instanceof AST_Lambda && !(node instanceof AST_Arrow)) {
6167 const class_this_save = class_this;
6168 class_this = false;
6169 descend();
6170 class_this = class_this_save;
6171 return true;
6172 }
6173 }));
6174 return found;
6175 },
6176}, AST_Scope /* TODO a class might have a scope but it's not a scope */);
6177
6178var AST_ClassProperty = DEFNODE("ClassProperty", "static quote", function AST_ClassProperty(props) {
6179 if (props) {
6180 this.static = props.static;
6181 this.quote = props.quote;
6182 this.key = props.key;
6183 this.value = props.value;
6184 this.start = props.start;
6185 this.end = props.end;
6186 this._annotations = props._annotations;
6187 }
6188
6189 this.flags = 0;
6190}, {
6191 $documentation: "A class property",
6192 $propdoc: {
6193 static: "[boolean] whether this is a static key",
6194 quote: "[string] which quote is being used"
6195 },
6196 _walk: function(visitor) {
6197 return visitor._visit(this, function() {
6198 if (this.key instanceof AST_Node)
6199 this.key._walk(visitor);
6200 if (this.value instanceof AST_Node)
6201 this.value._walk(visitor);
6202 });
6203 },
6204 _children_backwards(push) {
6205 if (this.value instanceof AST_Node) push(this.value);
6206 if (this.key instanceof AST_Node) push(this.key);
6207 },
6208 computed_key() {
6209 return !(this.key instanceof AST_SymbolClassProperty);
6210 }
6211}, AST_ObjectProperty);
6212
6213var AST_ClassPrivateProperty = DEFNODE("ClassPrivateProperty", "", function AST_ClassPrivateProperty(props) {
6214 if (props) {
6215 this.static = props.static;
6216 this.key = props.key;
6217 this.value = props.value;
6218 this.start = props.start;
6219 this.end = props.end;
6220 }
6221
6222 this.flags = 0;
6223}, {
6224 $documentation: "A class property for a private property",
6225 _walk: function(visitor) {
6226 return visitor._visit(this, function() {
6227 if (this.value instanceof AST_Node)
6228 this.value._walk(visitor);
6229 });
6230 },
6231 _children_backwards(push) {
6232 if (this.value instanceof AST_Node) push(this.value);
6233 },
6234 computed_key() {
6235 return false;
6236 },
6237}, AST_ObjectProperty);
6238
6239var AST_PrivateIn = DEFNODE("PrivateIn", "key value", function AST_PrivateIn(props) {
6240 if (props) {
6241 this.key = props.key;
6242 this.value = props.value;
6243 this.start = props.start;
6244 this.end = props.end;
6245 }
6246
6247 this.flags = 0;
6248}, {
6249 $documentation: "An `in` binop when the key is private, eg #x in this",
6250 _walk: function(visitor) {
6251 return visitor._visit(this, function() {
6252 this.key._walk(visitor);
6253 this.value._walk(visitor);
6254 });
6255 },
6256 _children_backwards(push) {
6257 push(this.value);
6258 push(this.key);
6259 },
6260});
6261
6262var AST_DefClass = DEFNODE("DefClass", null, function AST_DefClass(props) {
6263 if (props) {
6264 this.name = props.name;
6265 this.extends = props.extends;
6266 this.properties = props.properties;
6267 this.variables = props.variables;
6268 this.uses_with = props.uses_with;
6269 this.uses_eval = props.uses_eval;
6270 this.parent_scope = props.parent_scope;
6271 this.enclosed = props.enclosed;
6272 this.cname = props.cname;
6273 this.body = props.body;
6274 this.block_scope = props.block_scope;
6275 this.start = props.start;
6276 this.end = props.end;
6277 }
6278
6279 this.flags = 0;
6280}, {
6281 $documentation: "A class definition",
6282}, AST_Class);
6283
6284var AST_ClassStaticBlock = DEFNODE("ClassStaticBlock", "body block_scope", function AST_ClassStaticBlock (props) {
6285 this.body = props.body;
6286 this.block_scope = props.block_scope;
6287 this.start = props.start;
6288 this.end = props.end;
6289}, {
6290 $documentation: "A block containing statements to be executed in the context of the class",
6291 $propdoc: {
6292 body: "[AST_Statement*] an array of statements",
6293 },
6294 _walk: function(visitor) {
6295 return visitor._visit(this, function() {
6296 walk_body(this, visitor);
6297 });
6298 },
6299 _children_backwards(push) {
6300 let i = this.body.length;
6301 while (i--) push(this.body[i]);
6302 },
6303 clone: clone_block_scope,
6304 computed_key() {
6305 return false;
6306 },
6307}, AST_Scope);
6308
6309var AST_ClassExpression = DEFNODE("ClassExpression", null, function AST_ClassExpression(props) {
6310 if (props) {
6311 this.name = props.name;
6312 this.extends = props.extends;
6313 this.properties = props.properties;
6314 this.variables = props.variables;
6315 this.uses_with = props.uses_with;
6316 this.uses_eval = props.uses_eval;
6317 this.parent_scope = props.parent_scope;
6318 this.enclosed = props.enclosed;
6319 this.cname = props.cname;
6320 this.body = props.body;
6321 this.block_scope = props.block_scope;
6322 this.start = props.start;
6323 this.end = props.end;
6324 }
6325
6326 this.flags = 0;
6327}, {
6328 $documentation: "A class expression."
6329}, AST_Class);
6330
6331var AST_Symbol = DEFNODE("Symbol", "scope name thedef", function AST_Symbol(props) {
6332 if (props) {
6333 this.scope = props.scope;
6334 this.name = props.name;
6335 this.thedef = props.thedef;
6336 this.start = props.start;
6337 this.end = props.end;
6338 }
6339
6340 this.flags = 0;
6341}, {
6342 $propdoc: {
6343 name: "[string] name of this symbol",
6344 scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)",
6345 thedef: "[SymbolDef/S] the definition of this symbol"
6346 },
6347 $documentation: "Base class for all symbols"
6348});
6349
6350var AST_NewTarget = DEFNODE("NewTarget", null, function AST_NewTarget(props) {
6351 if (props) {
6352 this.start = props.start;
6353 this.end = props.end;
6354 }
6355
6356 this.flags = 0;
6357}, {
6358 $documentation: "A reference to new.target"
6359});
6360
6361var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", function AST_SymbolDeclaration(props) {
6362 if (props) {
6363 this.init = props.init;
6364 this.scope = props.scope;
6365 this.name = props.name;
6366 this.thedef = props.thedef;
6367 this.start = props.start;
6368 this.end = props.end;
6369 }
6370
6371 this.flags = 0;
6372}, {
6373 $documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)",
6374}, AST_Symbol);
6375
6376var AST_SymbolVar = DEFNODE("SymbolVar", null, function AST_SymbolVar(props) {
6377 if (props) {
6378 this.init = props.init;
6379 this.scope = props.scope;
6380 this.name = props.name;
6381 this.thedef = props.thedef;
6382 this.start = props.start;
6383 this.end = props.end;
6384 }
6385
6386 this.flags = 0;
6387}, {
6388 $documentation: "Symbol defining a variable",
6389}, AST_SymbolDeclaration);
6390
6391var AST_SymbolBlockDeclaration = DEFNODE(
6392 "SymbolBlockDeclaration",
6393 null,
6394 function AST_SymbolBlockDeclaration(props) {
6395 if (props) {
6396 this.init = props.init;
6397 this.scope = props.scope;
6398 this.name = props.name;
6399 this.thedef = props.thedef;
6400 this.start = props.start;
6401 this.end = props.end;
6402 }
6403
6404 this.flags = 0;
6405 },
6406 {
6407 $documentation: "Base class for block-scoped declaration symbols"
6408 },
6409 AST_SymbolDeclaration
6410);
6411
6412var AST_SymbolConst = DEFNODE("SymbolConst", null, function AST_SymbolConst(props) {
6413 if (props) {
6414 this.init = props.init;
6415 this.scope = props.scope;
6416 this.name = props.name;
6417 this.thedef = props.thedef;
6418 this.start = props.start;
6419 this.end = props.end;
6420 }
6421
6422 this.flags = 0;
6423}, {
6424 $documentation: "A constant declaration"
6425}, AST_SymbolBlockDeclaration);
6426
6427var AST_SymbolUsing = DEFNODE("SymbolUsing", null, function AST_SymbolUsing(props) {
6428 if (props) {
6429 this.init = props.init;
6430 this.scope = props.scope;
6431 this.name = props.name;
6432 this.thedef = props.thedef;
6433 this.start = props.start;
6434 this.end = props.end;
6435 }
6436
6437 this.flags = 0;
6438}, {
6439 $documentation: "A `using` declaration"
6440}, AST_SymbolBlockDeclaration);
6441
6442var AST_SymbolLet = DEFNODE("SymbolLet", null, function AST_SymbolLet(props) {
6443 if (props) {
6444 this.init = props.init;
6445 this.scope = props.scope;
6446 this.name = props.name;
6447 this.thedef = props.thedef;
6448 this.start = props.start;
6449 this.end = props.end;
6450 }
6451
6452 this.flags = 0;
6453}, {
6454 $documentation: "A block-scoped `let` declaration"
6455}, AST_SymbolBlockDeclaration);
6456
6457var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, function AST_SymbolFunarg(props) {
6458 if (props) {
6459 this.init = props.init;
6460 this.scope = props.scope;
6461 this.name = props.name;
6462 this.thedef = props.thedef;
6463 this.start = props.start;
6464 this.end = props.end;
6465 }
6466
6467 this.flags = 0;
6468}, {
6469 $documentation: "Symbol naming a function argument",
6470}, AST_SymbolVar);
6471
6472var AST_SymbolDefun = DEFNODE("SymbolDefun", null, function AST_SymbolDefun(props) {
6473 if (props) {
6474 this.init = props.init;
6475 this.scope = props.scope;
6476 this.name = props.name;
6477 this.thedef = props.thedef;
6478 this.start = props.start;
6479 this.end = props.end;
6480 }
6481
6482 this.flags = 0;
6483}, {
6484 $documentation: "Symbol defining a function",
6485}, AST_SymbolDeclaration);
6486
6487var AST_SymbolMethod = DEFNODE("SymbolMethod", null, function AST_SymbolMethod(props) {
6488 if (props) {
6489 this.scope = props.scope;
6490 this.name = props.name;
6491 this.thedef = props.thedef;
6492 this.start = props.start;
6493 this.end = props.end;
6494 }
6495
6496 this.flags = 0;
6497}, {
6498 $documentation: "Symbol in an object defining a method",
6499}, AST_Symbol);
6500
6501var AST_SymbolClassProperty = DEFNODE("SymbolClassProperty", null, function AST_SymbolClassProperty(props) {
6502 if (props) {
6503 this.scope = props.scope;
6504 this.name = props.name;
6505 this.thedef = props.thedef;
6506 this.start = props.start;
6507 this.end = props.end;
6508 }
6509
6510 this.flags = 0;
6511}, {
6512 $documentation: "Symbol for a class property",
6513}, AST_Symbol);
6514
6515var AST_SymbolLambda = DEFNODE("SymbolLambda", null, function AST_SymbolLambda(props) {
6516 if (props) {
6517 this.init = props.init;
6518 this.scope = props.scope;
6519 this.name = props.name;
6520 this.thedef = props.thedef;
6521 this.start = props.start;
6522 this.end = props.end;
6523 }
6524
6525 this.flags = 0;
6526}, {
6527 $documentation: "Symbol naming a function expression",
6528}, AST_SymbolDeclaration);
6529
6530var AST_SymbolDefClass = DEFNODE("SymbolDefClass", null, function AST_SymbolDefClass(props) {
6531 if (props) {
6532 this.init = props.init;
6533 this.scope = props.scope;
6534 this.name = props.name;
6535 this.thedef = props.thedef;
6536 this.start = props.start;
6537 this.end = props.end;
6538 }
6539
6540 this.flags = 0;
6541}, {
6542 $documentation: "Symbol naming a class's name in a class declaration. Lexically scoped to its containing scope, and accessible within the class."
6543}, AST_SymbolBlockDeclaration);
6544
6545var AST_SymbolClass = DEFNODE("SymbolClass", null, function AST_SymbolClass(props) {
6546 if (props) {
6547 this.init = props.init;
6548 this.scope = props.scope;
6549 this.name = props.name;
6550 this.thedef = props.thedef;
6551 this.start = props.start;
6552 this.end = props.end;
6553 }
6554
6555 this.flags = 0;
6556}, {
6557 $documentation: "Symbol naming a class's name. Lexically scoped to the class."
6558}, AST_SymbolDeclaration);
6559
6560var AST_SymbolCatch = DEFNODE("SymbolCatch", null, function AST_SymbolCatch(props) {
6561 if (props) {
6562 this.init = props.init;
6563 this.scope = props.scope;
6564 this.name = props.name;
6565 this.thedef = props.thedef;
6566 this.start = props.start;
6567 this.end = props.end;
6568 }
6569
6570 this.flags = 0;
6571}, {
6572 $documentation: "Symbol naming the exception in catch",
6573}, AST_SymbolBlockDeclaration);
6574
6575var AST_SymbolImport = DEFNODE("SymbolImport", null, function AST_SymbolImport(props) {
6576 if (props) {
6577 this.init = props.init;
6578 this.scope = props.scope;
6579 this.name = props.name;
6580 this.thedef = props.thedef;
6581 this.start = props.start;
6582 this.end = props.end;
6583 }
6584
6585 this.flags = 0;
6586}, {
6587 $documentation: "Symbol referring to an imported name",
6588}, AST_SymbolBlockDeclaration);
6589
6590var AST_SymbolImportForeign = DEFNODE("SymbolImportForeign", "quote", function AST_SymbolImportForeign(props) {
6591 if (props) {
6592 this.quote = props.quote;
6593 this.scope = props.scope;
6594 this.name = props.name;
6595 this.thedef = props.thedef;
6596 this.start = props.start;
6597 this.end = props.end;
6598 }
6599
6600 this.flags = 0;
6601}, {
6602 $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",
6603}, AST_Symbol);
6604
6605var AST_Label = DEFNODE("Label", "references", function AST_Label(props) {
6606 if (props) {
6607 this.references = props.references;
6608 this.scope = props.scope;
6609 this.name = props.name;
6610 this.thedef = props.thedef;
6611 this.start = props.start;
6612 this.end = props.end;
6613 this.initialize();
6614 }
6615
6616 this.flags = 0;
6617}, {
6618 $documentation: "Symbol naming a label (declaration)",
6619 $propdoc: {
6620 references: "[AST_LoopControl*] a list of nodes referring to this label"
6621 },
6622 initialize: function() {
6623 this.references = [];
6624 this.thedef = this;
6625 }
6626}, AST_Symbol);
6627
6628var AST_SymbolRef = DEFNODE("SymbolRef", null, function AST_SymbolRef(props) {
6629 if (props) {
6630 this.scope = props.scope;
6631 this.name = props.name;
6632 this.thedef = props.thedef;
6633 this.start = props.start;
6634 this.end = props.end;
6635 }
6636
6637 this.flags = 0;
6638}, {
6639 $documentation: "Reference to some symbol (not definition/declaration)",
6640}, AST_Symbol);
6641
6642var AST_SymbolExport = DEFNODE("SymbolExport", "quote", function AST_SymbolExport(props) {
6643 if (props) {
6644 this.quote = props.quote;
6645 this.scope = props.scope;
6646 this.name = props.name;
6647 this.thedef = props.thedef;
6648 this.start = props.start;
6649 this.end = props.end;
6650 }
6651
6652 this.flags = 0;
6653}, {
6654 $documentation: "Symbol referring to a name to export",
6655}, AST_SymbolRef);
6656
6657var AST_SymbolExportForeign = DEFNODE("SymbolExportForeign", "quote", function AST_SymbolExportForeign(props) {
6658 if (props) {
6659 this.quote = props.quote;
6660 this.scope = props.scope;
6661 this.name = props.name;
6662 this.thedef = props.thedef;
6663 this.start = props.start;
6664 this.end = props.end;
6665 }
6666
6667 this.flags = 0;
6668}, {
6669 $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",
6670}, AST_Symbol);
6671
6672var AST_LabelRef = DEFNODE("LabelRef", null, function AST_LabelRef(props) {
6673 if (props) {
6674 this.scope = props.scope;
6675 this.name = props.name;
6676 this.thedef = props.thedef;
6677 this.start = props.start;
6678 this.end = props.end;
6679 }
6680
6681 this.flags = 0;
6682}, {
6683 $documentation: "Reference to a label symbol",
6684}, AST_Symbol);
6685
6686var AST_SymbolPrivateProperty = DEFNODE("SymbolPrivateProperty", null, function AST_SymbolPrivateProperty(props) {
6687 if (props) {
6688 this.scope = props.scope;
6689 this.name = props.name;
6690 this.thedef = props.thedef;
6691 this.start = props.start;
6692 this.end = props.end;
6693 }
6694
6695 this.flags = 0;
6696}, {
6697 $documentation: "A symbol that refers to a private property",
6698}, AST_Symbol);
6699
6700var AST_This = DEFNODE("This", null, function AST_This(props) {
6701 if (props) {
6702 this.scope = props.scope;
6703 this.name = props.name;
6704 this.thedef = props.thedef;
6705 this.start = props.start;
6706 this.end = props.end;
6707 }
6708
6709 this.flags = 0;
6710}, {
6711 $documentation: "The `this` symbol",
6712}, AST_Symbol);
6713
6714var AST_Super = DEFNODE("Super", null, function AST_Super(props) {
6715 if (props) {
6716 this.scope = props.scope;
6717 this.name = props.name;
6718 this.thedef = props.thedef;
6719 this.start = props.start;
6720 this.end = props.end;
6721 }
6722
6723 this.flags = 0;
6724}, {
6725 $documentation: "The `super` symbol",
6726}, AST_This);
6727
6728var AST_Constant = DEFNODE("Constant", null, function AST_Constant(props) {
6729 if (props) {
6730 this.start = props.start;
6731 this.end = props.end;
6732 }
6733
6734 this.flags = 0;
6735}, {
6736 $documentation: "Base class for all constants",
6737 getValue: function() {
6738 return this.value;
6739 }
6740});
6741
6742var AST_String = DEFNODE("String", "value quote", function AST_String(props) {
6743 if (props) {
6744 this.value = props.value;
6745 this.quote = props.quote;
6746 this.start = props.start;
6747 this.end = props.end;
6748 this._annotations = props._annotations;
6749 }
6750
6751 this.flags = 0;
6752}, {
6753 $documentation: "A string literal",
6754 $propdoc: {
6755 value: "[string] the contents of this string",
6756 quote: "[string] the original quote character"
6757 }
6758}, AST_Constant);
6759
6760var AST_Number = DEFNODE("Number", "value raw", function AST_Number(props) {
6761 if (props) {
6762 this.value = props.value;
6763 this.raw = props.raw;
6764 this.start = props.start;
6765 this.end = props.end;
6766 }
6767
6768 this.flags = 0;
6769}, {
6770 $documentation: "A number literal",
6771 $propdoc: {
6772 value: "[number] the numeric value",
6773 raw: "[string] numeric value as string"
6774 }
6775}, AST_Constant);
6776
6777var AST_BigInt = DEFNODE("BigInt", "value raw", function AST_BigInt(props) {
6778 if (props) {
6779 this.value = props.value;
6780 this.raw = props.raw;
6781 this.start = props.start;
6782 this.end = props.end;
6783 }
6784
6785 this.flags = 0;
6786}, {
6787 $documentation: "A big int literal",
6788 $propdoc: {
6789 value: "[string] big int value, represented as a string",
6790 raw: "[string] the original format preserved"
6791 }
6792}, AST_Constant);
6793
6794var AST_RegExp = DEFNODE("RegExp", "value", function AST_RegExp(props) {
6795 if (props) {
6796 this.value = props.value;
6797 this.start = props.start;
6798 this.end = props.end;
6799 }
6800
6801 this.flags = 0;
6802}, {
6803 $documentation: "A regexp literal",
6804 $propdoc: {
6805 value: "[RegExp] the actual regexp",
6806 }
6807}, AST_Constant);
6808
6809var AST_Atom = DEFNODE("Atom", null, function AST_Atom(props) {
6810 if (props) {
6811 this.start = props.start;
6812 this.end = props.end;
6813 }
6814
6815 this.flags = 0;
6816}, {
6817 $documentation: "Base class for atoms",
6818}, AST_Constant);
6819
6820var AST_Null = DEFNODE("Null", null, function AST_Null(props) {
6821 if (props) {
6822 this.start = props.start;
6823 this.end = props.end;
6824 }
6825
6826 this.flags = 0;
6827}, {
6828 $documentation: "The `null` atom",
6829 value: null
6830}, AST_Atom);
6831
6832var AST_NaN = DEFNODE("NaN", null, function AST_NaN(props) {
6833 if (props) {
6834 this.start = props.start;
6835 this.end = props.end;
6836 }
6837
6838 this.flags = 0;
6839}, {
6840 $documentation: "The impossible value",
6841 value: 0/0
6842}, AST_Atom);
6843
6844var AST_Undefined = DEFNODE("Undefined", null, function AST_Undefined(props) {
6845 if (props) {
6846 this.start = props.start;
6847 this.end = props.end;
6848 }
6849
6850 this.flags = 0;
6851}, {
6852 $documentation: "The `undefined` value",
6853 value: (function() {}())
6854}, AST_Atom);
6855
6856var AST_Hole = DEFNODE("Hole", null, function AST_Hole(props) {
6857 if (props) {
6858 this.start = props.start;
6859 this.end = props.end;
6860 }
6861
6862 this.flags = 0;
6863}, {
6864 $documentation: "A hole in an array",
6865 value: (function() {}())
6866}, AST_Atom);
6867
6868var AST_Infinity = DEFNODE("Infinity", null, function AST_Infinity(props) {
6869 if (props) {
6870 this.start = props.start;
6871 this.end = props.end;
6872 }
6873
6874 this.flags = 0;
6875}, {
6876 $documentation: "The `Infinity` value",
6877 value: 1/0
6878}, AST_Atom);
6879
6880var AST_Boolean = DEFNODE("Boolean", null, function AST_Boolean(props) {
6881 if (props) {
6882 this.start = props.start;
6883 this.end = props.end;
6884 }
6885
6886 this.flags = 0;
6887}, {
6888 $documentation: "Base class for booleans",
6889}, AST_Atom);
6890
6891var AST_False = DEFNODE("False", null, function AST_False(props) {
6892 if (props) {
6893 this.start = props.start;
6894 this.end = props.end;
6895 }
6896
6897 this.flags = 0;
6898}, {
6899 $documentation: "The `false` atom",
6900 value: false
6901}, AST_Boolean);
6902
6903var AST_True = DEFNODE("True", null, function AST_True(props) {
6904 if (props) {
6905 this.start = props.start;
6906 this.end = props.end;
6907 }
6908
6909 this.flags = 0;
6910}, {
6911 $documentation: "The `true` atom",
6912 value: true
6913}, AST_Boolean);
6914
6915/* -----[ Walk function ]---- */
6916
6917/**
6918 * Walk nodes in depth-first search fashion.
6919 * Callback can return `walk_abort` symbol to stop iteration.
6920 * It can also return `true` to stop iteration just for child nodes.
6921 * Iteration can be stopped and continued by passing the `to_visit` argument,
6922 * which is given to the callback in the second argument.
6923 **/
6924function walk(node, cb, to_visit = [node]) {
6925 const push = to_visit.push.bind(to_visit);
6926 while (to_visit.length) {
6927 const node = to_visit.pop();
6928 const ret = cb(node, to_visit);
6929
6930 if (ret) {
6931 if (ret === walk_abort) return true;
6932 continue;
6933 }
6934
6935 node._children_backwards(push);
6936 }
6937 return false;
6938}
6939
6940/**
6941 * Walks an AST node and its children.
6942 *
6943 * {cb} can return `walk_abort` to interrupt the walk.
6944 *
6945 * @param node
6946 * @param cb {(node, info: { parent: (nth) => any }) => (boolean | undefined)}
6947 *
6948 * @returns {boolean} whether the walk was aborted
6949 *
6950 * @example
6951 * const found_some_cond = walk_parent(my_ast_node, (node, { parent }) => {
6952 * if (some_cond(node, parent())) return walk_abort
6953 * });
6954 */
6955function walk_parent(node, cb, initial_stack) {
6956 const to_visit = [node];
6957 const push = to_visit.push.bind(to_visit);
6958 const stack = initial_stack ? initial_stack.slice() : [];
6959 const parent_pop_indices = [];
6960
6961 let current;
6962
6963 const info = {
6964 parent: (n = 0) => {
6965 if (n === -1) {
6966 return current;
6967 }
6968
6969 // [ p1 p0 ] [ 1 0 ]
6970 if (initial_stack && n >= stack.length) {
6971 n -= stack.length;
6972 return initial_stack[
6973 initial_stack.length - (n + 1)
6974 ];
6975 }
6976
6977 return stack[stack.length - (1 + n)];
6978 },
6979 };
6980
6981 while (to_visit.length) {
6982 current = to_visit.pop();
6983
6984 while (
6985 parent_pop_indices.length &&
6986 to_visit.length == parent_pop_indices[parent_pop_indices.length - 1]
6987 ) {
6988 stack.pop();
6989 parent_pop_indices.pop();
6990 }
6991
6992 const ret = cb(current, info);
6993
6994 if (ret) {
6995 if (ret === walk_abort) return true;
6996 continue;
6997 }
6998
6999 const visit_length = to_visit.length;
7000
7001 current._children_backwards(push);
7002
7003 // Push only if we're going to traverse the children
7004 if (to_visit.length > visit_length) {
7005 stack.push(current);
7006 parent_pop_indices.push(visit_length - 1);
7007 }
7008 }
7009
7010 return false;
7011}
7012
7013const walk_abort = Symbol("abort walk");
7014
7015/* -----[ TreeWalker ]----- */
7016
7017class TreeWalker {
7018 constructor(callback) {
7019 this.visit = callback;
7020 this.stack = [];
7021 this.directives = Object.create(null);
7022 }
7023
7024 _visit(node, descend) {
7025 this.push(node);
7026 var ret = this.visit(node, descend ? function() {
7027 descend.call(node);
7028 } : noop);
7029 if (!ret && descend) {
7030 descend.call(node);
7031 }
7032 this.pop();
7033 return ret;
7034 }
7035
7036 parent(n) {
7037 return this.stack[this.stack.length - 2 - (n || 0)];
7038 }
7039
7040 push(node) {
7041 if (node instanceof AST_Lambda) {
7042 this.directives = Object.create(this.directives);
7043 } else if (node instanceof AST_Directive && !this.directives[node.value]) {
7044 this.directives[node.value] = node;
7045 } else if (node instanceof AST_Class) {
7046 this.directives = Object.create(this.directives);
7047 if (!this.directives["use strict"]) {
7048 this.directives["use strict"] = node;
7049 }
7050 }
7051 this.stack.push(node);
7052 }
7053
7054 pop() {
7055 var node = this.stack.pop();
7056 if (node instanceof AST_Lambda || node instanceof AST_Class) {
7057 this.directives = Object.getPrototypeOf(this.directives);
7058 }
7059 }
7060
7061 self() {
7062 return this.stack[this.stack.length - 1];
7063 }
7064
7065 find_parent(type) {
7066 var stack = this.stack;
7067 for (var i = stack.length; --i >= 0;) {
7068 var x = stack[i];
7069 if (x instanceof type) return x;
7070 }
7071 }
7072
7073 is_within_loop() {
7074 let i = this.stack.length - 1;
7075 let child = this.stack[i];
7076 while (i--) {
7077 const node = this.stack[i];
7078
7079 if (node instanceof AST_Lambda) return false;
7080 if (
7081 node instanceof AST_IterationStatement
7082 // exclude for-loop bits that only run once
7083 && !((node instanceof AST_For) && child === node.init)
7084 && !((node instanceof AST_ForIn || node instanceof AST_ForOf) && child === node.object)
7085 ) {
7086 return true;
7087 }
7088
7089 child = node;
7090 }
7091
7092 return false;
7093 }
7094
7095 find_scope() {
7096 var stack = this.stack;
7097 for (var i = stack.length; --i >= 0;) {
7098 const p = stack[i];
7099 if (p instanceof AST_Toplevel) return p;
7100 if (p instanceof AST_Lambda) return p;
7101 if (p.block_scope) return p.block_scope;
7102 }
7103 }
7104
7105 has_directive(type) {
7106 var dir = this.directives[type];
7107 if (dir) return dir;
7108 var node = this.stack[this.stack.length - 1];
7109 if (node instanceof AST_Scope && node.body) {
7110 for (var i = 0; i < node.body.length; ++i) {
7111 var st = node.body[i];
7112 if (!(st instanceof AST_Directive)) break;
7113 if (st.value == type) return st;
7114 }
7115 }
7116 }
7117
7118 loopcontrol_target(node) {
7119 var stack = this.stack;
7120 if (node.label) for (var i = stack.length; --i >= 0;) {
7121 var x = stack[i];
7122 if (x instanceof AST_LabeledStatement && x.label.name == node.label.name)
7123 return x.body;
7124 } else for (var i = stack.length; --i >= 0;) {
7125 var x = stack[i];
7126 if (x instanceof AST_IterationStatement
7127 || node instanceof AST_Break && x instanceof AST_Switch)
7128 return x;
7129 }
7130 }
7131}
7132
7133// Tree transformer helpers.
7134class TreeTransformer extends TreeWalker {
7135 constructor(before, after) {
7136 super();
7137 this.before = before;
7138 this.after = after;
7139 }
7140}
7141
7142const _PURE = 0b00000001;
7143const _INLINE = 0b00000010;
7144const _NOINLINE = 0b00000100;
7145const _KEY = 0b00001000;
7146const _MANGLEPROP = 0b00010000;
7147
7148/***********************************************************************
7149
7150 A JavaScript tokenizer / parser / beautifier / compressor.
7151 https://github.com/mishoo/UglifyJS2
7152
7153 -------------------------------- (C) ---------------------------------
7154
7155 Author: Mihai Bazon
7156 <mihai.bazon@gmail.com>
7157 http://mihai.bazon.net/blog
7158
7159 Distributed under the BSD license:
7160
7161 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
7162
7163 Redistribution and use in source and binary forms, with or without
7164 modification, are permitted provided that the following conditions
7165 are met:
7166
7167 * Redistributions of source code must retain the above
7168 copyright notice, this list of conditions and the following
7169 disclaimer.
7170
7171 * Redistributions in binary form must reproduce the above
7172 copyright notice, this list of conditions and the following
7173 disclaimer in the documentation and/or other materials
7174 provided with the distribution.
7175
7176 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
7177 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7178 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
7179 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
7180 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
7181 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
7182 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
7183 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
7184 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
7185 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
7186 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
7187 SUCH DAMAGE.
7188
7189 ***********************************************************************/
7190
7191function def_transform(node, descend) {
7192 node.DEFMETHOD("transform", function(tw, in_list) {
7193 let transformed = undefined;
7194 tw.push(this);
7195 if (tw.before) transformed = tw.before(this, descend, in_list);
7196 if (transformed === undefined) {
7197 transformed = this;
7198 descend(transformed, tw);
7199 if (tw.after) {
7200 const after_ret = tw.after(transformed, in_list);
7201 if (after_ret !== undefined) transformed = after_ret;
7202 }
7203 }
7204 tw.pop();
7205 return transformed;
7206 });
7207}
7208
7209def_transform(AST_Node, noop);
7210
7211def_transform(AST_LabeledStatement, function(self, tw) {
7212 self.label = self.label.transform(tw);
7213 self.body = self.body.transform(tw);
7214});
7215
7216def_transform(AST_SimpleStatement, function(self, tw) {
7217 self.body = self.body.transform(tw);
7218});
7219
7220def_transform(AST_Block, function(self, tw) {
7221 self.body = MAP(self.body, tw);
7222});
7223
7224def_transform(AST_Do, function(self, tw) {
7225 self.body = self.body.transform(tw);
7226 self.condition = self.condition.transform(tw);
7227});
7228
7229def_transform(AST_While, function(self, tw) {
7230 self.condition = self.condition.transform(tw);
7231 self.body = self.body.transform(tw);
7232});
7233
7234def_transform(AST_For, function(self, tw) {
7235 if (self.init) self.init = self.init.transform(tw);
7236 if (self.condition) self.condition = self.condition.transform(tw);
7237 if (self.step) self.step = self.step.transform(tw);
7238 self.body = self.body.transform(tw);
7239});
7240
7241def_transform(AST_ForIn, function(self, tw) {
7242 self.init = self.init.transform(tw);
7243 self.object = self.object.transform(tw);
7244 self.body = self.body.transform(tw);
7245});
7246
7247def_transform(AST_With, function(self, tw) {
7248 self.expression = self.expression.transform(tw);
7249 self.body = self.body.transform(tw);
7250});
7251
7252def_transform(AST_Exit, function(self, tw) {
7253 if (self.value) self.value = self.value.transform(tw);
7254});
7255
7256def_transform(AST_LoopControl, function(self, tw) {
7257 if (self.label) self.label = self.label.transform(tw);
7258});
7259
7260def_transform(AST_If, function(self, tw) {
7261 self.condition = self.condition.transform(tw);
7262 self.body = self.body.transform(tw);
7263 if (self.alternative) self.alternative = self.alternative.transform(tw);
7264});
7265
7266def_transform(AST_Switch, function(self, tw) {
7267 self.expression = self.expression.transform(tw);
7268 self.body = MAP(self.body, tw);
7269});
7270
7271def_transform(AST_Case, function(self, tw) {
7272 self.expression = self.expression.transform(tw);
7273 self.body = MAP(self.body, tw);
7274});
7275
7276def_transform(AST_Try, function(self, tw) {
7277 self.body = self.body.transform(tw);
7278 if (self.bcatch) self.bcatch = self.bcatch.transform(tw);
7279 if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
7280});
7281
7282def_transform(AST_Catch, function(self, tw) {
7283 if (self.argname) self.argname = self.argname.transform(tw);
7284 self.body = MAP(self.body, tw);
7285});
7286
7287def_transform(AST_DefinitionsLike, function(self, tw) {
7288 self.definitions = MAP(self.definitions, tw);
7289});
7290
7291def_transform(AST_VarDefLike, function(self, tw) {
7292 self.name = self.name.transform(tw);
7293 if (self.value) self.value = self.value.transform(tw);
7294});
7295
7296def_transform(AST_Destructuring, function(self, tw) {
7297 self.names = MAP(self.names, tw);
7298});
7299
7300def_transform(AST_Lambda, function(self, tw) {
7301 if (self.name) self.name = self.name.transform(tw);
7302 self.argnames = MAP(self.argnames, tw, /* allow_splicing */ false);
7303 if (self.body instanceof AST_Node) {
7304 self.body = self.body.transform(tw);
7305 } else {
7306 self.body = MAP(self.body, tw);
7307 }
7308});
7309
7310def_transform(AST_Call, function(self, tw) {
7311 self.expression = self.expression.transform(tw);
7312 self.args = MAP(self.args, tw, /* allow_splicing */ false);
7313});
7314
7315def_transform(AST_Sequence, function(self, tw) {
7316 const result = MAP(self.expressions, tw);
7317 self.expressions = result.length
7318 ? result
7319 : [new AST_Number({ value: 0 })];
7320});
7321
7322def_transform(AST_PropAccess, function(self, tw) {
7323 self.expression = self.expression.transform(tw);
7324});
7325
7326def_transform(AST_Sub, function(self, tw) {
7327 self.expression = self.expression.transform(tw);
7328 self.property = self.property.transform(tw);
7329});
7330
7331def_transform(AST_Chain, function(self, tw) {
7332 self.expression = self.expression.transform(tw);
7333});
7334
7335def_transform(AST_Yield, function(self, tw) {
7336 if (self.expression) self.expression = self.expression.transform(tw);
7337});
7338
7339def_transform(AST_Await, function(self, tw) {
7340 self.expression = self.expression.transform(tw);
7341});
7342
7343def_transform(AST_Unary, function(self, tw) {
7344 self.expression = self.expression.transform(tw);
7345});
7346
7347def_transform(AST_Binary, function(self, tw) {
7348 self.left = self.left.transform(tw);
7349 self.right = self.right.transform(tw);
7350});
7351
7352def_transform(AST_PrivateIn, function(self, tw) {
7353 self.key = self.key.transform(tw);
7354 self.value = self.value.transform(tw);
7355});
7356
7357def_transform(AST_Conditional, function(self, tw) {
7358 self.condition = self.condition.transform(tw);
7359 self.consequent = self.consequent.transform(tw);
7360 self.alternative = self.alternative.transform(tw);
7361});
7362
7363def_transform(AST_Array, function(self, tw) {
7364 self.elements = MAP(self.elements, tw);
7365});
7366
7367def_transform(AST_Object, function(self, tw) {
7368 self.properties = MAP(self.properties, tw);
7369});
7370
7371def_transform(AST_ObjectProperty, function(self, tw) {
7372 if (self.key instanceof AST_Node) {
7373 self.key = self.key.transform(tw);
7374 }
7375 if (self.value) self.value = self.value.transform(tw);
7376});
7377
7378def_transform(AST_Class, function(self, tw) {
7379 if (self.name) self.name = self.name.transform(tw);
7380 if (self.extends) self.extends = self.extends.transform(tw);
7381 self.properties = MAP(self.properties, tw);
7382});
7383
7384def_transform(AST_ClassStaticBlock, function(self, tw) {
7385 self.body = MAP(self.body, tw);
7386});
7387
7388def_transform(AST_Expansion, function(self, tw) {
7389 self.expression = self.expression.transform(tw);
7390});
7391
7392def_transform(AST_NameMapping, function(self, tw) {
7393 self.foreign_name = self.foreign_name.transform(tw);
7394 self.name = self.name.transform(tw);
7395});
7396
7397def_transform(AST_Import, function(self, tw) {
7398 if (self.imported_name) self.imported_name = self.imported_name.transform(tw);
7399 if (self.imported_names) MAP(self.imported_names, tw);
7400 self.module_name = self.module_name.transform(tw);
7401});
7402
7403def_transform(AST_Export, function(self, tw) {
7404 if (self.exported_definition) self.exported_definition = self.exported_definition.transform(tw);
7405 if (self.exported_value) self.exported_value = self.exported_value.transform(tw);
7406 if (self.exported_names) MAP(self.exported_names, tw);
7407 if (self.module_name) self.module_name = self.module_name.transform(tw);
7408});
7409
7410def_transform(AST_TemplateString, function(self, tw) {
7411 self.segments = MAP(self.segments, tw);
7412});
7413
7414def_transform(AST_PrefixedTemplateString, function(self, tw) {
7415 self.prefix = self.prefix.transform(tw);
7416 self.template_string = self.template_string.transform(tw);
7417});
7418
7419/***********************************************************************
7420
7421 A JavaScript tokenizer / parser / beautifier / compressor.
7422 https://github.com/mishoo/UglifyJS2
7423
7424 -------------------------------- (C) ---------------------------------
7425
7426 Author: Mihai Bazon
7427 <mihai.bazon@gmail.com>
7428 http://mihai.bazon.net/blog
7429
7430 Distributed under the BSD license:
7431
7432 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
7433
7434 Redistribution and use in source and binary forms, with or without
7435 modification, are permitted provided that the following conditions
7436 are met:
7437
7438 * Redistributions of source code must retain the above
7439 copyright notice, this list of conditions and the following
7440 disclaimer.
7441
7442 * Redistributions in binary form must reproduce the above
7443 copyright notice, this list of conditions and the following
7444 disclaimer in the documentation and/or other materials
7445 provided with the distribution.
7446
7447 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
7448 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7449 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
7450 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
7451 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
7452 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
7453 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
7454 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
7455 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
7456 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
7457 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
7458 SUCH DAMAGE.
7459
7460 ***********************************************************************/
7461
7462(function() {
7463
7464 var normalize_directives = function(body) {
7465 for (var i = 0; i < body.length; i++) {
7466 if (body[i] instanceof AST_Statement && body[i].body instanceof AST_String) {
7467 body[i] = new AST_Directive({
7468 start: body[i].start,
7469 end: body[i].end,
7470 quote: '"',
7471 value: body[i].body.value
7472 });
7473 } else {
7474 return body;
7475 }
7476 }
7477
7478 return body;
7479 };
7480
7481 function import_attributes_from_moz(attributes) {
7482 if (attributes && attributes.length > 0) {
7483 return new AST_Object({
7484 start: my_start_token(attributes),
7485 end: my_end_token(attributes),
7486 properties: attributes.map((attr) =>
7487 new AST_ObjectKeyVal({
7488 start: my_start_token(attr),
7489 end: my_end_token(attr),
7490 key: attr.key.name || attr.key.value,
7491 value: from_moz(attr.value)
7492 })
7493 )
7494 });
7495 }
7496 return null;
7497 }
7498
7499 var MOZ_TO_ME = {
7500 Program: function(M) {
7501 return new AST_Toplevel({
7502 start: my_start_token(M),
7503 end: my_end_token(M),
7504 body: normalize_directives(M.body.map(from_moz))
7505 });
7506 },
7507
7508 ArrayPattern: function(M) {
7509 return new AST_Destructuring({
7510 start: my_start_token(M),
7511 end: my_end_token(M),
7512 names: M.elements.map(function(elm) {
7513 if (elm === null) {
7514 return new AST_Hole();
7515 }
7516 return from_moz(elm);
7517 }),
7518 is_array: true
7519 });
7520 },
7521
7522 ObjectPattern: function(M) {
7523 return new AST_Destructuring({
7524 start: my_start_token(M),
7525 end: my_end_token(M),
7526 names: M.properties.map(from_moz),
7527 is_array: false
7528 });
7529 },
7530
7531 AssignmentPattern: function(M) {
7532 return new AST_DefaultAssign({
7533 start: my_start_token(M),
7534 end: my_end_token(M),
7535 left: from_moz(M.left),
7536 operator: "=",
7537 right: from_moz(M.right)
7538 });
7539 },
7540
7541 SpreadElement: function(M) {
7542 return new AST_Expansion({
7543 start: my_start_token(M),
7544 end: my_end_token(M),
7545 expression: from_moz(M.argument)
7546 });
7547 },
7548
7549 RestElement: function(M) {
7550 return new AST_Expansion({
7551 start: my_start_token(M),
7552 end: my_end_token(M),
7553 expression: from_moz(M.argument)
7554 });
7555 },
7556
7557 TemplateElement: function(M) {
7558 return new AST_TemplateSegment({
7559 start: my_start_token(M),
7560 end: my_end_token(M),
7561 value: M.value.cooked,
7562 raw: M.value.raw
7563 });
7564 },
7565
7566 TemplateLiteral: function(M) {
7567 var segments = [];
7568 for (var i = 0; i < M.quasis.length; i++) {
7569 segments.push(from_moz(M.quasis[i]));
7570 if (M.expressions[i]) {
7571 segments.push(from_moz(M.expressions[i]));
7572 }
7573 }
7574 return new AST_TemplateString({
7575 start: my_start_token(M),
7576 end: my_end_token(M),
7577 segments: segments
7578 });
7579 },
7580
7581 TaggedTemplateExpression: function(M) {
7582 return new AST_PrefixedTemplateString({
7583 start: my_start_token(M),
7584 end: my_end_token(M),
7585 template_string: from_moz(M.quasi),
7586 prefix: from_moz(M.tag)
7587 });
7588 },
7589
7590 FunctionDeclaration: function(M) {
7591 return new AST_Defun({
7592 start: my_start_token(M),
7593 end: my_end_token(M),
7594 name: M.id && from_moz_symbol(AST_SymbolDefun, M.id),
7595 argnames: M.params.map(M => from_moz_pattern(M, AST_SymbolFunarg)),
7596 is_generator: M.generator,
7597 async: M.async,
7598 body: normalize_directives(from_moz(M.body).body)
7599 });
7600 },
7601
7602 FunctionExpression: function(M) {
7603 return from_moz_lambda(M, /*is_method=*/false);
7604 },
7605
7606 ArrowFunctionExpression: function(M) {
7607 const body = M.body.type === "BlockStatement"
7608 ? from_moz(M.body).body
7609 : [make_node(AST_Return, {}, { value: from_moz(M.body) })];
7610 return new AST_Arrow({
7611 start: my_start_token(M),
7612 end: my_end_token(M),
7613 argnames: M.params.map(p => from_moz_pattern(p, AST_SymbolFunarg)),
7614 body,
7615 async: M.async,
7616 });
7617 },
7618
7619 ExpressionStatement: function(M) {
7620 return new AST_SimpleStatement({
7621 start: my_start_token(M),
7622 end: my_end_token(M),
7623 body: from_moz(M.expression)
7624 });
7625 },
7626
7627 TryStatement: function(M) {
7628 var handlers = M.handlers || [M.handler];
7629 if (handlers.length > 1 || M.guardedHandlers && M.guardedHandlers.length) {
7630 throw new Error("Multiple catch clauses are not supported.");
7631 }
7632 return new AST_Try({
7633 start : my_start_token(M),
7634 end : my_end_token(M),
7635 body : new AST_TryBlock(from_moz(M.block)),
7636 bcatch : from_moz(handlers[0]),
7637 bfinally : M.finalizer ? new AST_Finally(from_moz(M.finalizer)) : null
7638 });
7639 },
7640
7641 Property: function(M) {
7642 if (M.kind == "init" && !M.method) {
7643 var args = {
7644 start : my_start_token(M.key || M.value),
7645 end : my_end_token(M.value),
7646 key : M.computed
7647 ? from_moz(M.key)
7648 : M.key.name || String(M.key.value),
7649 quote : from_moz_quote(M.key, M.computed),
7650 static : false, // always an object
7651 value : from_moz(M.value)
7652 };
7653
7654 return new AST_ObjectKeyVal(args);
7655 } else {
7656 var value = from_moz_lambda(M.value, /*is_method=*/true);
7657 var args = {
7658 start : my_start_token(M.key || M.value),
7659 end : my_end_token(M.value),
7660 key : M.computed
7661 ? from_moz(M.key)
7662 : from_moz_symbol(AST_SymbolMethod, M.key),
7663 quote : from_moz_quote(M.key, M.computed),
7664 static : false, // always an object
7665 value,
7666 };
7667
7668 if (M.kind == "get") return new AST_ObjectGetter(args);
7669 if (M.kind == "set") return new AST_ObjectSetter(args);
7670 if (M.method) return new AST_ConciseMethod(args);
7671 }
7672 },
7673
7674 MethodDefinition: function(M) {
7675 const is_private = M.key.type === "PrivateIdentifier";
7676 const key = M.computed ? from_moz(M.key) : new AST_SymbolMethod({ name: M.key.name || String(M.key.value) });
7677
7678 var args = {
7679 start : my_start_token(M),
7680 end : my_end_token(M),
7681 key,
7682 quote : from_moz_quote(M.key, M.computed),
7683 value : from_moz_lambda(M.value, /*is_method=*/true),
7684 static : M.static,
7685 };
7686 if (M.kind == "get") {
7687 return new (is_private ? AST_PrivateGetter : AST_ObjectGetter)(args);
7688 }
7689 if (M.kind == "set") {
7690 return new (is_private ? AST_PrivateSetter : AST_ObjectSetter)(args);
7691 }
7692 return new (is_private ? AST_PrivateMethod : AST_ConciseMethod)(args);
7693 },
7694
7695 FieldDefinition: function(M) {
7696 let key;
7697 if (M.computed) {
7698 key = from_moz(M.key);
7699 } else {
7700 if (M.key.type !== "Identifier") throw new Error("Non-Identifier key in FieldDefinition");
7701 key = from_moz(M.key);
7702 }
7703 return new AST_ClassProperty({
7704 start : my_start_token(M),
7705 end : my_end_token(M),
7706 quote : from_moz_quote(M.key, M.computed),
7707 key,
7708 value : from_moz(M.value),
7709 static : M.static,
7710 });
7711 },
7712
7713 PropertyDefinition: function(M) {
7714 let key;
7715 if (M.computed) {
7716 key = from_moz(M.key);
7717 } else if (M.key.type === "PrivateIdentifier") {
7718 return new AST_ClassPrivateProperty({
7719 start : my_start_token(M),
7720 end : my_end_token(M),
7721 key : from_moz(M.key),
7722 value : from_moz(M.value),
7723 static : M.static,
7724 });
7725 } else {
7726 key = from_moz_symbol(AST_SymbolClassProperty, M.key);
7727 }
7728
7729 return new AST_ClassProperty({
7730 start : my_start_token(M),
7731 end : my_end_token(M),
7732 quote : from_moz_quote(M.key, M.computed),
7733 key,
7734 value : from_moz(M.value),
7735 static : M.static,
7736 });
7737 },
7738
7739 PrivateIdentifier: function (M) {
7740 return new AST_SymbolPrivateProperty({
7741 start: my_start_token(M),
7742 end: my_end_token(M),
7743 name: M.name
7744 });
7745 },
7746
7747 StaticBlock: function(M) {
7748 return new AST_ClassStaticBlock({
7749 start : my_start_token(M),
7750 end : my_end_token(M),
7751 body : M.body.map(from_moz),
7752 });
7753 },
7754
7755 ArrayExpression: function(M) {
7756 return new AST_Array({
7757 start : my_start_token(M),
7758 end : my_end_token(M),
7759 elements : M.elements.map(function(elem) {
7760 return elem === null ? new AST_Hole() : from_moz(elem);
7761 })
7762 });
7763 },
7764
7765 ObjectExpression: function(M) {
7766 return new AST_Object({
7767 start : my_start_token(M),
7768 end : my_end_token(M),
7769 properties : M.properties.map(function(prop) {
7770 if (prop.type === "SpreadElement") {
7771 return from_moz(prop);
7772 }
7773 prop.type = "Property";
7774 return from_moz(prop);
7775 })
7776 });
7777 },
7778
7779 SequenceExpression: function(M) {
7780 return new AST_Sequence({
7781 start : my_start_token(M),
7782 end : my_end_token(M),
7783 expressions: M.expressions.map(from_moz)
7784 });
7785 },
7786
7787 MemberExpression: function(M) {
7788 if (M.property.type === "PrivateIdentifier") {
7789 return new AST_DotHash({
7790 start : my_start_token(M),
7791 end : my_end_token(M),
7792 property : M.property.name,
7793 expression : from_moz(M.object),
7794 optional : M.optional || false
7795 });
7796 }
7797 return new (M.computed ? AST_Sub : AST_Dot)({
7798 start : my_start_token(M),
7799 end : my_end_token(M),
7800 property : M.computed ? from_moz(M.property) : M.property.name,
7801 expression : from_moz(M.object),
7802 optional : M.optional || false
7803 });
7804 },
7805
7806 ChainExpression: function(M) {
7807 return new AST_Chain({
7808 start : my_start_token(M),
7809 end : my_end_token(M),
7810 expression : from_moz(M.expression)
7811 });
7812 },
7813
7814 SwitchCase: function(M) {
7815 return new (M.test ? AST_Case : AST_Default)({
7816 start : my_start_token(M),
7817 end : my_end_token(M),
7818 expression : from_moz(M.test),
7819 body : M.consequent.map(from_moz)
7820 });
7821 },
7822
7823 VariableDeclaration: function(M) {
7824 let decl_type;
7825 let defs_type = AST_VarDef;
7826 let sym_type;
7827 let await_using = false;
7828 if (M.kind === "const") {
7829 decl_type = AST_Const;
7830 sym_type = AST_SymbolConst;
7831 } else if (M.kind === "let") {
7832 decl_type = AST_Let;
7833 sym_type = AST_SymbolLet;
7834 } else if (M.kind === "using") {
7835 decl_type = AST_Using;
7836 defs_type = AST_UsingDef;
7837 sym_type = AST_SymbolUsing;
7838 } else if (M.kind === "await using") {
7839 decl_type = AST_Using;
7840 defs_type = AST_UsingDef;
7841 sym_type = AST_SymbolUsing;
7842 await_using = true;
7843 } else {
7844 decl_type = AST_Var;
7845 sym_type = AST_SymbolVar;
7846 }
7847 const definitions = M.declarations.map(M => {
7848 return new defs_type({
7849 start: my_start_token(M),
7850 end: my_end_token(M),
7851 name: from_moz_pattern(M.id, sym_type),
7852 value: from_moz(M.init),
7853 });
7854 });
7855 return new decl_type({
7856 start : my_start_token(M),
7857 end : my_end_token(M),
7858 definitions : definitions,
7859 await : await_using,
7860 });
7861 },
7862
7863 ImportDeclaration: function(M) {
7864 var imported_name = null;
7865 var imported_names = null;
7866 M.specifiers.forEach(function (specifier) {
7867 if (specifier.type === "ImportSpecifier" || specifier.type === "ImportNamespaceSpecifier") {
7868 if (!imported_names) { imported_names = []; }
7869 imported_names.push(from_moz(specifier));
7870 } else if (specifier.type === "ImportDefaultSpecifier") {
7871 imported_name = from_moz(specifier);
7872 }
7873 });
7874 return new AST_Import({
7875 start : my_start_token(M),
7876 end : my_end_token(M),
7877 imported_name: imported_name,
7878 imported_names : imported_names,
7879 module_name : from_moz(M.source),
7880 attributes: import_attributes_from_moz(M.attributes || M.assertions),
7881 phase: M.phase || null
7882 });
7883 },
7884
7885 ImportSpecifier: function(M) {
7886 return new AST_NameMapping({
7887 start: my_start_token(M),
7888 end: my_end_token(M),
7889 foreign_name: from_moz_symbol(AST_SymbolImportForeign, M.imported, M.imported.type === "Literal"),
7890 name: from_moz_symbol(AST_SymbolImport, M.local)
7891 });
7892 },
7893
7894 ImportDefaultSpecifier: function(M) {
7895 return from_moz_symbol(AST_SymbolImport, M.local);
7896 },
7897
7898 ImportNamespaceSpecifier: function(M) {
7899 return new AST_NameMapping({
7900 start: my_start_token(M),
7901 end: my_end_token(M),
7902 foreign_name: new AST_SymbolImportForeign({ name: "*" }),
7903 name: from_moz_symbol(AST_SymbolImport, M.local)
7904 });
7905 },
7906
7907 ImportExpression: function(M) {
7908 const args = [from_moz(M.source)];
7909 if (M.options) {
7910 args.push(from_moz(M.options));
7911 }
7912 if (M.phase) {
7913 return new AST_DynamicImport({
7914 start: my_start_token(M),
7915 end: my_end_token(M),
7916 phase: M.phase,
7917 args: args
7918 });
7919 }
7920 return new AST_Call({
7921 start: my_start_token(M),
7922 end: my_end_token(M),
7923 expression: from_moz({
7924 type: "Identifier",
7925 name: "import"
7926 }),
7927 optional: false,
7928 args
7929 });
7930 },
7931
7932 ExportAllDeclaration: function(M) {
7933 var foreign_name = M.exported == null ?
7934 new AST_SymbolExportForeign({ name: "*" }) :
7935 from_moz_symbol(AST_SymbolExportForeign, M.exported, M.exported.type === "Literal");
7936 return new AST_Export({
7937 start: my_start_token(M),
7938 end: my_end_token(M),
7939 exported_names: [
7940 new AST_NameMapping({
7941 start: my_start_token(M),
7942 end: my_end_token(M),
7943 name: new AST_SymbolExport({ name: "*" }),
7944 foreign_name: foreign_name
7945 })
7946 ],
7947 module_name: from_moz(M.source),
7948 attributes: import_attributes_from_moz(M.attributes || M.assertions)
7949 });
7950 },
7951
7952 ExportNamedDeclaration: function(M) {
7953 if (M.declaration) {
7954 // export const, export function, ...
7955 return new AST_Export({
7956 start: my_start_token(M),
7957 end: my_end_token(M),
7958 exported_definition: from_moz(M.declaration),
7959 exported_names: null,
7960 module_name: null,
7961 attributes: null,
7962 });
7963 } else {
7964 return new AST_Export({
7965 start: my_start_token(M),
7966 end: my_end_token(M),
7967 exported_definition: null,
7968 exported_names: M.specifiers && M.specifiers.length ? M.specifiers.map(from_moz) : [],
7969 module_name: from_moz(M.source),
7970 attributes: import_attributes_from_moz(M.attributes || M.assertions),
7971 });
7972 }
7973 },
7974
7975 ExportDefaultDeclaration: function(M) {
7976 return new AST_Export({
7977 start: my_start_token(M),
7978 end: my_end_token(M),
7979 exported_value: from_moz(M.declaration),
7980 is_default: true
7981 });
7982 },
7983
7984 ExportSpecifier: function(M) {
7985 return new AST_NameMapping({
7986 start: my_start_token(M),
7987 end: my_end_token(M),
7988 foreign_name: from_moz_symbol(AST_SymbolExportForeign, M.exported, M.exported.type === "Literal"),
7989 name: from_moz_symbol(AST_SymbolExport, M.local, M.local.type === "Literal"),
7990 });
7991 },
7992
7993 Literal: function(M) {
7994 var val = M.value, args = {
7995 start : my_start_token(M),
7996 end : my_end_token(M)
7997 };
7998 var rx = M.regex;
7999 if (rx && rx.pattern) {
8000 // RegExpLiteral as per ESTree AST spec
8001 args.value = {
8002 source: rx.pattern,
8003 flags: rx.flags
8004 };
8005 return new AST_RegExp(args);
8006 } else if (rx) {
8007 // support legacy RegExp
8008 const rx_source = M.raw || val;
8009 const match = rx_source.match(/^\/(.*)\/(\w*)$/);
8010 if (!match) throw new Error("Invalid regex source " + rx_source);
8011 const [_, source, flags] = match;
8012 args.value = { source, flags };
8013 return new AST_RegExp(args);
8014 }
8015 const bi = typeof M.value === "bigint" ? M.value.toString() : M.bigint;
8016 if (typeof bi === "string") {
8017 args.value = bi;
8018 args.raw = M.raw;
8019 return new AST_BigInt(args);
8020 }
8021 if (val === null) return new AST_Null(args);
8022 switch (typeof val) {
8023 case "string":
8024 args.quote = "\"";
8025 args.value = val;
8026 return new AST_String(args);
8027 case "number":
8028 args.value = val;
8029 args.raw = M.raw || val.toString();
8030 return new AST_Number(args);
8031 case "boolean":
8032 return new (val ? AST_True : AST_False)(args);
8033 }
8034 },
8035
8036 MetaProperty: function(M) {
8037 if (M.meta.name === "new" && M.property.name === "target") {
8038 return new AST_NewTarget({
8039 start: my_start_token(M),
8040 end: my_end_token(M)
8041 });
8042 } else if (M.meta.name === "import" && M.property.name === "meta") {
8043 return new AST_ImportMeta({
8044 start: my_start_token(M),
8045 end: my_end_token(M)
8046 });
8047 }
8048 },
8049
8050 Identifier: function(M) {
8051 return new AST_SymbolRef({
8052 start : my_start_token(M),
8053 end : my_end_token(M),
8054 name : M.name
8055 });
8056 },
8057
8058 EmptyStatement: function(M) {
8059 return new AST_EmptyStatement({
8060 start: my_start_token(M),
8061 end: my_end_token(M)
8062 });
8063 },
8064
8065 BlockStatement: function(M) {
8066 return new AST_BlockStatement({
8067 start: my_start_token(M),
8068 end: my_end_token(M),
8069 body: M.body.map(from_moz)
8070 });
8071 },
8072
8073 IfStatement: function(M) {
8074 return new AST_If({
8075 start: my_start_token(M),
8076 end: my_end_token(M),
8077 condition: from_moz(M.test),
8078 body: from_moz(M.consequent),
8079 alternative: from_moz(M.alternate)
8080 });
8081 },
8082
8083 LabeledStatement: function(M) {
8084 try {
8085 const label = from_moz_symbol(AST_Label, M.label);
8086 FROM_MOZ_LABELS.push(label);
8087
8088 const stat = new AST_LabeledStatement({
8089 start: my_start_token(M),
8090 end: my_end_token(M),
8091 label,
8092 body: from_moz(M.body)
8093 });
8094
8095 return stat;
8096 } finally {
8097 FROM_MOZ_LABELS.pop();
8098 }
8099 },
8100
8101 BreakStatement: function(M) {
8102 return new AST_Break({
8103 start: my_start_token(M),
8104 end: my_end_token(M),
8105 label: from_moz_label_ref(M.label),
8106 });
8107 },
8108
8109 ContinueStatement: function(M) {
8110 return new AST_Continue({
8111 start: my_start_token(M),
8112 end: my_end_token(M),
8113 label: from_moz_label_ref(M.label),
8114 });
8115 },
8116
8117 WithStatement: function(M) {
8118 return new AST_With({
8119 start: my_start_token(M),
8120 end: my_end_token(M),
8121 expression: from_moz(M.object),
8122 body: from_moz(M.body)
8123 });
8124 },
8125
8126 SwitchStatement: function(M) {
8127 return new AST_Switch({
8128 start: my_start_token(M),
8129 end: my_end_token(M),
8130 expression: from_moz(M.discriminant),
8131 body: M.cases.map(from_moz)
8132 });
8133 },
8134
8135 ReturnStatement: function(M) {
8136 return new AST_Return({
8137 start: my_start_token(M),
8138 end: my_end_token(M),
8139 value: from_moz(M.argument)
8140 });
8141 },
8142
8143 ThrowStatement: function(M) {
8144 return new AST_Throw({
8145 start: my_start_token(M),
8146 end: my_end_token(M),
8147 value: from_moz(M.argument)
8148 });
8149 },
8150
8151 WhileStatement: function(M) {
8152 return new AST_While({
8153 start: my_start_token(M),
8154 end: my_end_token(M),
8155 condition: from_moz(M.test),
8156 body: from_moz(M.body)
8157 });
8158 },
8159
8160 DoWhileStatement: function(M) {
8161 return new AST_Do({
8162 start: my_start_token(M),
8163 end: my_end_token(M),
8164 condition: from_moz(M.test),
8165 body: from_moz(M.body)
8166 });
8167 },
8168
8169 ForStatement: function(M) {
8170 return new AST_For({
8171 start: my_start_token(M),
8172 end: my_end_token(M),
8173 init: from_moz(M.init),
8174 condition: from_moz(M.test),
8175 step: from_moz(M.update),
8176 body: from_moz(M.body)
8177 });
8178 },
8179
8180 ForInStatement: function(M) {
8181 return new AST_ForIn({
8182 start: my_start_token(M),
8183 end: my_end_token(M),
8184 init: from_moz(M.left),
8185 object: from_moz(M.right),
8186 body: from_moz(M.body)
8187 });
8188 },
8189
8190 ForOfStatement: function(M) {
8191 return new AST_ForOf({
8192 start: my_start_token(M),
8193 end: my_end_token(M),
8194 init: from_moz(M.left),
8195 object: from_moz(M.right),
8196 body: from_moz(M.body),
8197 await: M.await
8198 });
8199 },
8200
8201 AwaitExpression: function(M) {
8202 return new AST_Await({
8203 start: my_start_token(M),
8204 end: my_end_token(M),
8205 expression: from_moz(M.argument)
8206 });
8207 },
8208
8209 YieldExpression: function(M) {
8210 return new AST_Yield({
8211 start: my_start_token(M),
8212 end: my_end_token(M),
8213 expression: from_moz(M.argument),
8214 is_star: M.delegate
8215 });
8216 },
8217
8218 DebuggerStatement: function(M) {
8219 return new AST_Debugger({
8220 start: my_start_token(M),
8221 end: my_end_token(M)
8222 });
8223 },
8224
8225 CatchClause: function(M) {
8226 return new AST_Catch({
8227 start: my_start_token(M),
8228 end: my_end_token(M),
8229 argname: M.param ? from_moz_pattern(M.param, AST_SymbolCatch) : null,
8230 body: from_moz(M.body).body
8231 });
8232 },
8233
8234 ThisExpression: function(M) {
8235 return new AST_This({
8236 start: my_start_token(M),
8237 name: "this",
8238 end: my_end_token(M)
8239 });
8240 },
8241
8242 Super: function(M) {
8243 return new AST_Super({
8244 start: my_start_token(M),
8245 end: my_end_token(M),
8246 name: "super",
8247 });
8248 },
8249
8250 BinaryExpression: function(M) {
8251 if (M.left.type === "PrivateIdentifier") {
8252 return new AST_PrivateIn({
8253 start: my_start_token(M),
8254 end: my_end_token(M),
8255 key: new AST_SymbolPrivateProperty({
8256 start: my_start_token(M.left),
8257 end: my_end_token(M.left),
8258 name: M.left.name
8259 }),
8260 value: from_moz(M.right),
8261 });
8262 }
8263 return new AST_Binary({
8264 start: my_start_token(M),
8265 end: my_end_token(M),
8266 operator: M.operator,
8267 left: from_moz(M.left),
8268 right: from_moz(M.right)
8269 });
8270 },
8271
8272 LogicalExpression: function(M) {
8273 return new AST_Binary({
8274 start: my_start_token(M),
8275 end: my_end_token(M),
8276 operator: M.operator,
8277 left: from_moz(M.left),
8278 right: from_moz(M.right)
8279 });
8280 },
8281
8282 AssignmentExpression: function(M) {
8283 return new AST_Assign({
8284 start: my_start_token(M),
8285 end: my_end_token(M),
8286 operator: M.operator,
8287 logical: M.operator === "??=" || M.operator === "&&=" || M.operator === "||=",
8288 left: from_moz(M.left),
8289 right: from_moz(M.right)
8290 });
8291 },
8292
8293 ConditionalExpression: function(M) {
8294 return new AST_Conditional({
8295 start: my_start_token(M),
8296 end: my_end_token(M),
8297 condition: from_moz(M.test),
8298 consequent: from_moz(M.consequent),
8299 alternative: from_moz(M.alternate)
8300 });
8301 },
8302
8303 NewExpression: function(M) {
8304 return new AST_New({
8305 start: my_start_token(M),
8306 end: my_end_token(M),
8307 expression: from_moz(M.callee),
8308 args: M.arguments.map(from_moz)
8309 });
8310 },
8311
8312 CallExpression: function(M) {
8313 return new AST_Call({
8314 start: my_start_token(M),
8315 end: my_end_token(M),
8316 expression: from_moz(M.callee),
8317 optional: M.optional,
8318 args: M.arguments.map(from_moz)
8319 });
8320 }
8321 };
8322
8323 MOZ_TO_ME.UpdateExpression =
8324 MOZ_TO_ME.UnaryExpression = function To_Moz_Unary(M) {
8325 var prefix = "prefix" in M ? M.prefix
8326 : M.type == "UnaryExpression" ? true : false;
8327 return new (prefix ? AST_UnaryPrefix : AST_UnaryPostfix)({
8328 start : my_start_token(M),
8329 end : my_end_token(M),
8330 operator : M.operator,
8331 expression : from_moz(M.argument)
8332 });
8333 };
8334
8335 MOZ_TO_ME.ClassDeclaration =
8336 MOZ_TO_ME.ClassExpression = function From_Moz_Class(M) {
8337 return new (M.type === "ClassDeclaration" ? AST_DefClass : AST_ClassExpression)({
8338 start : my_start_token(M),
8339 end : my_end_token(M),
8340 name : M.id && from_moz_symbol(M.type === "ClassDeclaration" ? AST_SymbolDefClass : AST_SymbolClass, M.id),
8341 extends : from_moz(M.superClass),
8342 properties: M.body.body.map(from_moz)
8343 });
8344 };
8345
8346 def_to_moz(AST_EmptyStatement, function To_Moz_EmptyStatement() {
8347 return {
8348 type: "EmptyStatement"
8349 };
8350 });
8351 def_to_moz(AST_BlockStatement, function To_Moz_BlockStatement(M) {
8352 return {
8353 type: "BlockStatement",
8354 body: M.body.map(to_moz)
8355 };
8356 });
8357 def_to_moz(AST_If, function To_Moz_IfStatement(M) {
8358 return {
8359 type: "IfStatement",
8360 test: to_moz(M.condition),
8361 consequent: to_moz(M.body),
8362 alternate: to_moz(M.alternative)
8363 };
8364 });
8365 def_to_moz(AST_LabeledStatement, function To_Moz_LabeledStatement(M) {
8366 return {
8367 type: "LabeledStatement",
8368 label: to_moz(M.label),
8369 body: to_moz(M.body)
8370 };
8371 });
8372 def_to_moz(AST_Break, function To_Moz_BreakStatement(M) {
8373 return {
8374 type: "BreakStatement",
8375 label: to_moz(M.label)
8376 };
8377 });
8378 def_to_moz(AST_Continue, function To_Moz_ContinueStatement(M) {
8379 return {
8380 type: "ContinueStatement",
8381 label: to_moz(M.label)
8382 };
8383 });
8384 def_to_moz(AST_With, function To_Moz_WithStatement(M) {
8385 return {
8386 type: "WithStatement",
8387 object: to_moz(M.expression),
8388 body: to_moz(M.body)
8389 };
8390 });
8391 def_to_moz(AST_Switch, function To_Moz_SwitchStatement(M) {
8392 return {
8393 type: "SwitchStatement",
8394 discriminant: to_moz(M.expression),
8395 cases: M.body.map(to_moz)
8396 };
8397 });
8398 def_to_moz(AST_Return, function To_Moz_ReturnStatement(M) {
8399 return {
8400 type: "ReturnStatement",
8401 argument: to_moz(M.value)
8402 };
8403 });
8404 def_to_moz(AST_Throw, function To_Moz_ThrowStatement(M) {
8405 return {
8406 type: "ThrowStatement",
8407 argument: to_moz(M.value)
8408 };
8409 });
8410 def_to_moz(AST_While, function To_Moz_WhileStatement(M) {
8411 return {
8412 type: "WhileStatement",
8413 test: to_moz(M.condition),
8414 body: to_moz(M.body)
8415 };
8416 });
8417 def_to_moz(AST_Do, function To_Moz_DoWhileStatement(M) {
8418 return {
8419 type: "DoWhileStatement",
8420 test: to_moz(M.condition),
8421 body: to_moz(M.body)
8422 };
8423 });
8424 def_to_moz(AST_For, function To_Moz_ForStatement(M) {
8425 return {
8426 type: "ForStatement",
8427 init: to_moz(M.init),
8428 test: to_moz(M.condition),
8429 update: to_moz(M.step),
8430 body: to_moz(M.body)
8431 };
8432 });
8433 def_to_moz(AST_ForIn, function To_Moz_ForInStatement(M) {
8434 return {
8435 type: "ForInStatement",
8436 left: to_moz(M.init),
8437 right: to_moz(M.object),
8438 body: to_moz(M.body)
8439 };
8440 });
8441 def_to_moz(AST_ForOf, function To_Moz_ForOfStatement(M) {
8442 return {
8443 type: "ForOfStatement",
8444 left: to_moz(M.init),
8445 right: to_moz(M.object),
8446 body: to_moz(M.body),
8447 await: M.await
8448 };
8449 });
8450 def_to_moz(AST_Await, function To_Moz_AwaitExpression(M) {
8451 return {
8452 type: "AwaitExpression",
8453 argument: to_moz(M.expression)
8454 };
8455 });
8456 def_to_moz(AST_Yield, function To_Moz_YieldExpression(M) {
8457 return {
8458 type: "YieldExpression",
8459 argument: to_moz(M.expression),
8460 delegate: M.is_star
8461 };
8462 });
8463 def_to_moz(AST_Debugger, function To_Moz_DebuggerStatement() {
8464 return {
8465 type: "DebuggerStatement"
8466 };
8467 });
8468 def_to_moz(AST_VarDefLike, function To_Moz_VariableDeclarator(M) {
8469 return {
8470 type: "VariableDeclarator",
8471 id: to_moz(M.name),
8472 init: to_moz(M.value)
8473 };
8474 });
8475
8476 def_to_moz(AST_This, function To_Moz_ThisExpression() {
8477 return {
8478 type: "ThisExpression"
8479 };
8480 });
8481 def_to_moz(AST_Super, function To_Moz_Super() {
8482 return {
8483 type: "Super"
8484 };
8485 });
8486 def_to_moz(AST_Conditional, function To_Moz_ConditionalExpression(M) {
8487 return {
8488 type: "ConditionalExpression",
8489 test: to_moz(M.condition),
8490 consequent: to_moz(M.consequent),
8491 alternate: to_moz(M.alternative)
8492 };
8493 });
8494 def_to_moz(AST_New, function To_Moz_NewExpression(M) {
8495 return {
8496 type: "NewExpression",
8497 callee: to_moz(M.expression),
8498 arguments: M.args.map(to_moz)
8499 };
8500 });
8501 def_to_moz(AST_Call, function To_Moz_CallExpression(M) {
8502 if (M.expression instanceof AST_SymbolRef && M.expression.name === "import") {
8503 const [source, options] = M.args.map(to_moz);
8504 return {
8505 type: "ImportExpression",
8506 source,
8507 options: options || null
8508 };
8509 }
8510
8511 return {
8512 type: "CallExpression",
8513 callee: to_moz(M.expression),
8514 optional: M.optional,
8515 arguments: M.args.map(to_moz)
8516 };
8517 });
8518
8519 def_to_moz(AST_DynamicImport, function To_Moz_ImportExpression(M) {
8520 const [source, options] = M.args.map(to_moz);
8521 return {
8522 type: "ImportExpression",
8523 source,
8524 options: options || null,
8525 phase: M.phase
8526 };
8527 });
8528
8529 def_to_moz(AST_Toplevel, function To_Moz_Program(M) {
8530 return to_moz_scope("Program", M);
8531 });
8532
8533 def_to_moz(AST_Expansion, function To_Moz_Spread(M) {
8534 return {
8535 type: to_moz_in_destructuring() ? "RestElement" : "SpreadElement",
8536 argument: to_moz(M.expression)
8537 };
8538 });
8539
8540 def_to_moz(AST_PrefixedTemplateString, function To_Moz_TaggedTemplateExpression(M) {
8541 return {
8542 type: "TaggedTemplateExpression",
8543 tag: to_moz(M.prefix),
8544 quasi: to_moz(M.template_string)
8545 };
8546 });
8547
8548 def_to_moz(AST_TemplateString, function To_Moz_TemplateLiteral(M) {
8549 var quasis = [];
8550 var expressions = [];
8551 for (var i = 0; i < M.segments.length; i++) {
8552 if (i % 2 !== 0) {
8553 expressions.push(to_moz(M.segments[i]));
8554 } else {
8555 quasis.push({
8556 type: "TemplateElement",
8557 value: {
8558 raw: M.segments[i].raw,
8559 cooked: M.segments[i].value
8560 },
8561 tail: i === M.segments.length - 1
8562 });
8563 }
8564 }
8565 return {
8566 type: "TemplateLiteral",
8567 quasis: quasis,
8568 expressions: expressions
8569 };
8570 });
8571
8572 def_to_moz(AST_Defun, function To_Moz_FunctionDeclaration(M) {
8573 return {
8574 type: "FunctionDeclaration",
8575 id: to_moz(M.name),
8576 params: M.argnames.map(to_moz_pattern),
8577 generator: M.is_generator,
8578 async: M.async,
8579 body: to_moz_scope("BlockStatement", M)
8580 };
8581 });
8582
8583 def_to_moz(AST_Function, function To_Moz_FunctionExpression(M) {
8584 return {
8585 type: "FunctionExpression",
8586 id: to_moz(M.name),
8587 params: M.argnames.map(to_moz_pattern),
8588 generator: M.is_generator || false,
8589 async: M.async || false,
8590 body: to_moz_scope("BlockStatement", M)
8591 };
8592 });
8593
8594 def_to_moz(AST_Arrow, function To_Moz_ArrowFunctionExpression(M) {
8595 var body = M.body.length === 1 && M.body[0] instanceof AST_Return && M.body[0].value
8596 ? to_moz(M.body[0].value)
8597 : {
8598 type: "BlockStatement",
8599 body: M.body.map(to_moz)
8600 };
8601 return {
8602 type: "ArrowFunctionExpression",
8603 params: M.argnames.map(to_moz_pattern),
8604 async: M.async,
8605 body: body,
8606 };
8607 });
8608
8609 def_to_moz(AST_Destructuring, function To_Moz_ObjectPattern(M) {
8610 if (M.is_array) {
8611 return {
8612 type: "ArrayPattern",
8613 elements: M.names.map(
8614 M => M instanceof AST_Hole ? null : to_moz_pattern(M)
8615 ),
8616 };
8617 }
8618 return {
8619 type: "ObjectPattern",
8620 properties: M.names.map(M => {
8621 if (M instanceof AST_ObjectKeyVal) {
8622 var computed = M.computed_key();
8623 const [shorthand, key] = to_moz_property_key(M.key, computed, M.quote, M.value);
8624
8625 return {
8626 type: "Property",
8627 computed,
8628 kind: "init",
8629 key: key,
8630 method: false,
8631 shorthand,
8632 value: to_moz_pattern(M.value)
8633 };
8634 } else {
8635 return to_moz_pattern(M);
8636 }
8637 }),
8638 };
8639 });
8640
8641 def_to_moz(AST_DefaultAssign, function To_Moz_AssignmentExpression(M) {
8642 return {
8643 type: "AssignmentPattern",
8644 left: to_moz_pattern(M.left),
8645 right: to_moz(M.right),
8646 };
8647 });
8648
8649 def_to_moz(AST_Directive, function To_Moz_Directive(M) {
8650 return {
8651 type: "ExpressionStatement",
8652 expression: {
8653 type: "Literal",
8654 value: M.value,
8655 raw: M.print_to_string()
8656 },
8657 directive: M.value
8658 };
8659 });
8660
8661 def_to_moz(AST_SimpleStatement, function To_Moz_ExpressionStatement(M) {
8662 return {
8663 type: "ExpressionStatement",
8664 expression: to_moz(M.body)
8665 };
8666 });
8667
8668 def_to_moz(AST_SwitchBranch, function To_Moz_SwitchCase(M) {
8669 return {
8670 type: "SwitchCase",
8671 test: to_moz(M.expression),
8672 consequent: M.body.map(to_moz)
8673 };
8674 });
8675
8676 def_to_moz(AST_Try, function To_Moz_TryStatement(M) {
8677 return {
8678 type: "TryStatement",
8679 block: to_moz_block(M.body),
8680 handler: to_moz(M.bcatch),
8681 guardedHandlers: [],
8682 finalizer: to_moz(M.bfinally)
8683 };
8684 });
8685
8686 def_to_moz(AST_Catch, function To_Moz_CatchClause(M) {
8687 return {
8688 type: "CatchClause",
8689 param: M.argname != null ? to_moz_pattern(M.argname) : null,
8690 body: to_moz_block(M)
8691 };
8692 });
8693
8694 def_to_moz(AST_DefinitionsLike, function To_Moz_VariableDeclaration(M) {
8695 return {
8696 type: "VariableDeclaration",
8697 kind:
8698 M instanceof AST_Const ? "const" :
8699 M instanceof AST_Let ? "let" :
8700 M instanceof AST_Using ? (M.await ? "await using" : "using") :
8701 "var",
8702 declarations: M.definitions.map(to_moz)
8703 };
8704 });
8705
8706 function import_attributes_to_moz(attribute) {
8707 const import_attributes = [];
8708 if (attribute) {
8709 for (const { key, value } of attribute.properties) {
8710 const key_moz = is_basic_identifier_string(key)
8711 ? { type: "Identifier", name: key }
8712 : { type: "Literal", value: key, raw: JSON.stringify(key) };
8713 import_attributes.push({
8714 type: "ImportAttribute",
8715 key: key_moz,
8716 value: to_moz(value)
8717 });
8718 }
8719 }
8720 return import_attributes;
8721 }
8722
8723 def_to_moz(AST_Export, function To_Moz_ExportDeclaration(M) {
8724 if (M.exported_names) {
8725 var first_exported = M.exported_names[0];
8726 if (first_exported && first_exported.name.name === "*" && !first_exported.name.quote) {
8727 var foreign_name = first_exported.foreign_name;
8728 var exported = foreign_name.name === "*" && !foreign_name.quote
8729 ? null
8730 : to_moz(foreign_name);
8731 return {
8732 type: "ExportAllDeclaration",
8733 source: to_moz(M.module_name),
8734 exported: exported,
8735 attributes: import_attributes_to_moz(M.attributes)
8736 };
8737 }
8738 return {
8739 type: "ExportNamedDeclaration",
8740 specifiers: M.exported_names.map(function (name_mapping) {
8741 return {
8742 type: "ExportSpecifier",
8743 exported: to_moz(name_mapping.foreign_name),
8744 local: to_moz(name_mapping.name)
8745 };
8746 }),
8747 declaration: to_moz(M.exported_definition),
8748 source: to_moz(M.module_name),
8749 attributes: import_attributes_to_moz(M.attributes)
8750 };
8751 }
8752
8753 if (M.is_default) {
8754 return {
8755 type: "ExportDefaultDeclaration",
8756 declaration: to_moz(M.exported_value || M.exported_definition),
8757 };
8758 } else {
8759 return {
8760 type: "ExportNamedDeclaration",
8761 declaration: to_moz(M.exported_value || M.exported_definition),
8762 specifiers: [],
8763 source: null,
8764 };
8765 }
8766 });
8767
8768 def_to_moz(AST_Import, function To_Moz_ImportDeclaration(M) {
8769 var specifiers = [];
8770 if (M.imported_name) {
8771 specifiers.push({
8772 type: "ImportDefaultSpecifier",
8773 local: to_moz(M.imported_name)
8774 });
8775 }
8776 if (M.imported_names) {
8777 var first_imported_foreign_name = M.imported_names[0].foreign_name;
8778 if (first_imported_foreign_name.name === "*" && !first_imported_foreign_name.quote) {
8779 specifiers.push({
8780 type: "ImportNamespaceSpecifier",
8781 local: to_moz(M.imported_names[0].name)
8782 });
8783 } else {
8784 M.imported_names.forEach(function(name_mapping) {
8785 specifiers.push({
8786 type: "ImportSpecifier",
8787 local: to_moz(name_mapping.name),
8788 imported: to_moz(name_mapping.foreign_name)
8789 });
8790 });
8791 }
8792 }
8793 var moz = {
8794 type: "ImportDeclaration",
8795 specifiers: specifiers,
8796 source: to_moz(M.module_name),
8797 attributes: import_attributes_to_moz(M.attributes)
8798 };
8799 if (M.phase) moz.phase = M.phase;
8800 return moz;
8801 });
8802
8803 def_to_moz(AST_ImportMeta, function To_Moz_MetaProperty() {
8804 return {
8805 type: "MetaProperty",
8806 meta: {
8807 type: "Identifier",
8808 name: "import"
8809 },
8810 property: {
8811 type: "Identifier",
8812 name: "meta"
8813 }
8814 };
8815 });
8816
8817 def_to_moz(AST_Sequence, function To_Moz_SequenceExpression(M) {
8818 return {
8819 type: "SequenceExpression",
8820 expressions: M.expressions.map(to_moz)
8821 };
8822 });
8823
8824 def_to_moz(AST_DotHash, function To_Moz_PrivateMemberExpression(M) {
8825 return {
8826 type: "MemberExpression",
8827 object: to_moz(M.expression),
8828 computed: false,
8829 property: {
8830 type: "PrivateIdentifier",
8831 name: M.property
8832 },
8833 optional: M.optional
8834 };
8835 });
8836
8837 def_to_moz(AST_PropAccess, function To_Moz_MemberExpression(M) {
8838 var isComputed = M instanceof AST_Sub;
8839 return {
8840 type: "MemberExpression",
8841 object: to_moz(M.expression),
8842 computed: isComputed,
8843 property: isComputed ? to_moz(M.property) : {type: "Identifier", name: M.property},
8844 optional: M.optional
8845 };
8846 });
8847
8848 def_to_moz(AST_Chain, function To_Moz_ChainExpression(M) {
8849 return {
8850 type: "ChainExpression",
8851 expression: to_moz(M.expression)
8852 };
8853 });
8854
8855 def_to_moz(AST_Unary, function To_Moz_Unary(M) {
8856 return {
8857 type: M.operator == "++" || M.operator == "--" ? "UpdateExpression" : "UnaryExpression",
8858 operator: M.operator,
8859 prefix: M instanceof AST_UnaryPrefix,
8860 argument: to_moz(M.expression)
8861 };
8862 });
8863
8864 def_to_moz(AST_Binary, function To_Moz_BinaryExpression(M) {
8865 if (M.operator == "=" && to_moz_in_destructuring()) {
8866 return {
8867 type: "AssignmentPattern",
8868 left: to_moz(M.left),
8869 right: to_moz(M.right)
8870 };
8871 }
8872
8873 const type = M.operator == "&&" || M.operator == "||" || M.operator === "??"
8874 ? "LogicalExpression"
8875 : "BinaryExpression";
8876
8877 return {
8878 type,
8879 left: to_moz(M.left),
8880 operator: M.operator,
8881 right: to_moz(M.right)
8882 };
8883 });
8884
8885 def_to_moz(AST_Assign, function To_Moz_AssignmentExpression(M) {
8886 return {
8887 type: "AssignmentExpression",
8888 operator: M.operator,
8889 left: to_moz(M.left),
8890 right: to_moz(M.right)
8891 };
8892 });
8893
8894 def_to_moz(AST_PrivateIn, function To_Moz_BinaryExpression_PrivateIn(M) {
8895 return {
8896 type: "BinaryExpression",
8897 left: { type: "PrivateIdentifier", name: M.key.name },
8898 operator: "in",
8899 right: to_moz(M.value),
8900 };
8901 });
8902
8903 def_to_moz(AST_Array, function To_Moz_ArrayExpression(M) {
8904 return {
8905 type: "ArrayExpression",
8906 elements: M.elements.map(to_moz)
8907 };
8908 });
8909
8910 def_to_moz(AST_Object, function To_Moz_ObjectExpression(M) {
8911 return {
8912 type: "ObjectExpression",
8913 properties: M.properties.map(to_moz)
8914 };
8915 });
8916
8917 def_to_moz(AST_ObjectProperty, function To_Moz_Property(M, parent) {
8918 var computed = M.computed_key();
8919 const [shorthand, key] = to_moz_property_key(M.key, computed, M.quote, M.value);
8920
8921 var kind;
8922 if (M instanceof AST_ObjectGetter) {
8923 kind = "get";
8924 } else
8925 if (M instanceof AST_ObjectSetter) {
8926 kind = "set";
8927 }
8928 if (M instanceof AST_PrivateGetter || M instanceof AST_PrivateSetter) {
8929 const kind = M instanceof AST_PrivateGetter ? "get" : "set";
8930 return {
8931 type: "MethodDefinition",
8932 computed: false,
8933 kind: kind,
8934 static: M.static,
8935 key: {
8936 type: "PrivateIdentifier",
8937 name: M.key.name
8938 },
8939 value: to_moz(M.value)
8940 };
8941 }
8942 if (M instanceof AST_ClassPrivateProperty) {
8943 return {
8944 type: "PropertyDefinition",
8945 key: {
8946 type: "PrivateIdentifier",
8947 name: M.key.name
8948 },
8949 value: to_moz(M.value),
8950 computed: false,
8951 static: M.static
8952 };
8953 }
8954 if (M instanceof AST_ClassProperty) {
8955 return {
8956 type: "PropertyDefinition",
8957 key,
8958 value: to_moz(M.value),
8959 computed,
8960 static: M.static
8961 };
8962 }
8963 if (parent instanceof AST_Class) {
8964 return {
8965 type: "MethodDefinition",
8966 computed: computed,
8967 kind: kind,
8968 static: M.static,
8969 key: to_moz(M.key),
8970 value: to_moz(M.value)
8971 };
8972 }
8973 return {
8974 type: "Property",
8975 computed: computed,
8976 method: false,
8977 shorthand,
8978 kind: kind,
8979 key: key,
8980 value: to_moz(M.value)
8981 };
8982 });
8983
8984 def_to_moz(AST_ObjectKeyVal, function To_Moz_Property(M) {
8985 var computed = M.computed_key();
8986 const [shorthand, key] = to_moz_property_key(M.key, computed, M.quote, M.value);
8987
8988 return {
8989 type: "Property",
8990 computed: computed,
8991 shorthand: shorthand,
8992 method: false,
8993 kind: "init",
8994 key: key,
8995 value: to_moz(M.value)
8996 };
8997 });
8998
8999 def_to_moz(AST_ConciseMethod, function To_Moz_MethodDefinition(M, parent) {
9000 const computed = M.computed_key();
9001 const [_always_false, key] = to_moz_property_key(M.key, computed, M.quote, M.value);
9002
9003 if (parent instanceof AST_Object) {
9004 return {
9005 type: "Property",
9006 kind: "init",
9007 computed,
9008 method: true,
9009 shorthand: false,
9010 key,
9011 value: to_moz(M.value),
9012 };
9013 }
9014
9015 return {
9016 type: "MethodDefinition",
9017 kind: !computed && M.key.name === "constructor" ? "constructor" : "method",
9018 computed,
9019 key,
9020 value: to_moz(M.value),
9021 static: M.static,
9022 };
9023 });
9024
9025 def_to_moz(AST_PrivateMethod, function To_Moz_MethodDefinition(M) {
9026 return {
9027 type: "MethodDefinition",
9028 kind: "method",
9029 key: { type: "PrivateIdentifier", name: M.key.name },
9030 value: to_moz(M.value),
9031 computed: false,
9032 static: M.static,
9033 };
9034 });
9035
9036 def_to_moz(AST_Class, function To_Moz_Class(M) {
9037 var type = M instanceof AST_ClassExpression ? "ClassExpression" : "ClassDeclaration";
9038 return {
9039 type: type,
9040 superClass: to_moz(M.extends),
9041 id: M.name ? to_moz(M.name) : null,
9042 body: {
9043 type: "ClassBody",
9044 body: M.properties.map(to_moz)
9045 }
9046 };
9047 });
9048
9049 def_to_moz(AST_ClassStaticBlock, function To_Moz_StaticBlock(M) {
9050 return {
9051 type: "StaticBlock",
9052 body: M.body.map(to_moz),
9053 };
9054 });
9055
9056 def_to_moz(AST_NewTarget, function To_Moz_MetaProperty() {
9057 return {
9058 type: "MetaProperty",
9059 meta: {
9060 type: "Identifier",
9061 name: "new"
9062 },
9063 property: {
9064 type: "Identifier",
9065 name: "target"
9066 }
9067 };
9068 });
9069
9070 def_to_moz(AST_Symbol, function To_Moz_Identifier(M, parent) {
9071 if (
9072 (M instanceof AST_SymbolMethod && parent.quote) ||
9073 ((
9074 M instanceof AST_SymbolImportForeign ||
9075 M instanceof AST_SymbolExportForeign ||
9076 M instanceof AST_SymbolExport
9077 ) && M.quote)
9078 ) {
9079 return {
9080 type: "Literal",
9081 value: M.name
9082 };
9083 }
9084 var def = M.definition();
9085 return {
9086 type: "Identifier",
9087 name: def ? def.mangled_name || def.name : M.name
9088 };
9089 });
9090
9091 def_to_moz(AST_RegExp, function To_Moz_RegExpLiteral(M) {
9092 const pattern = M.value.source;
9093 const flags = M.value.flags;
9094 return {
9095 type: "Literal",
9096 value: null,
9097 raw: M.print_to_string(),
9098 regex: { pattern, flags }
9099 };
9100 });
9101
9102 def_to_moz(AST_Constant, function To_Moz_Literal(M) {
9103 var value = M.value;
9104 return {
9105 type: "Literal",
9106 value: value,
9107 raw: M.raw || M.print_to_string()
9108 };
9109 });
9110
9111 def_to_moz(AST_Atom, function To_Moz_Atom(M) {
9112 return {
9113 type: "Identifier",
9114 name: String(M.value)
9115 };
9116 });
9117
9118 def_to_moz(AST_BigInt, M => ({
9119 type: "Literal",
9120 // value cannot be represented natively
9121 // see: https://github.com/estree/estree/blob/master/es2020.md#bigintliteral
9122 value: null,
9123 // `M.value` is a string that may be a hex number representation.
9124 // but "bigint" property should have only decimal digits
9125 bigint: typeof BigInt === "function" ? BigInt(M.value).toString() : M.value,
9126 raw: M.raw,
9127 }));
9128
9129 AST_Boolean.DEFMETHOD("to_mozilla_ast", AST_Constant.prototype.to_mozilla_ast);
9130 AST_Null.DEFMETHOD("to_mozilla_ast", AST_Constant.prototype.to_mozilla_ast);
9131 AST_Hole.DEFMETHOD("to_mozilla_ast", function To_Moz_ArrayHole() { return null; });
9132
9133 AST_Block.DEFMETHOD("to_mozilla_ast", AST_BlockStatement.prototype.to_mozilla_ast);
9134 AST_Lambda.DEFMETHOD("to_mozilla_ast", AST_Function.prototype.to_mozilla_ast);
9135
9136 /* -----[ tools ]----- */
9137
9138 function my_start_token(moznode) {
9139 var loc = moznode.loc, start = loc && loc.start;
9140 var range = moznode.range;
9141 return new AST_Token(
9142 "",
9143 "",
9144 start && start.line || 0,
9145 start && start.column || 0,
9146 range ? range [0] : moznode.start,
9147 false,
9148 [],
9149 [],
9150 loc && loc.source,
9151 );
9152 }
9153
9154 function my_end_token(moznode) {
9155 var loc = moznode.loc, end = loc && loc.end;
9156 var range = moznode.range;
9157 return new AST_Token(
9158 "",
9159 "",
9160 end && end.line || 0,
9161 end && end.column || 0,
9162 range ? range [0] : moznode.end,
9163 false,
9164 [],
9165 [],
9166 loc && loc.source,
9167 );
9168 }
9169
9170 var FROM_MOZ_LABELS = null;
9171
9172 function from_moz(node) {
9173 if (node == null) return null;
9174 return MOZ_TO_ME[node.type](node);
9175 }
9176
9177 function from_moz_quote(moz_key, computed) {
9178 if (!computed && moz_key.type === "Literal" && typeof moz_key.value === "string") {
9179 return '"';
9180 } else {
9181 return "";
9182 }
9183 }
9184
9185 function from_moz_symbol(symbol_type, M, has_quote) {
9186 return new symbol_type({
9187 start: my_start_token(M),
9188 quote: has_quote ? '"' : undefined,
9189 name: M.type === "Identifier" ? M.name : String(M.value),
9190 end: my_end_token(M),
9191 });
9192 }
9193
9194 function from_moz_lambda(M, is_method) {
9195 return new (is_method ? AST_Accessor : AST_Function)({
9196 start: my_start_token(M),
9197 end: my_end_token(M),
9198 name: M.id && from_moz_symbol(is_method ? AST_SymbolMethod : AST_SymbolLambda, M.id),
9199 argnames: M.params.map(M => from_moz_pattern(M, AST_SymbolFunarg)),
9200 is_generator: M.generator,
9201 async: M.async,
9202 body: normalize_directives(from_moz(M.body).body)
9203 });
9204 }
9205
9206 function from_moz_pattern(M, sym_type) {
9207 switch (M.type) {
9208 case "ObjectPattern":
9209 return new AST_Destructuring({
9210 start: my_start_token(M),
9211 end: my_end_token(M),
9212 names: M.properties.map(p => from_moz_pattern(p, sym_type)),
9213 is_array: false
9214 });
9215
9216 case "Property":
9217 var key = M.key;
9218 var args = {
9219 start : my_start_token(key || M.value),
9220 end : my_end_token(M.value),
9221 key : key.type == "Identifier" ? key.name : String(key.value),
9222 quote : !M.computed && key.type === "Literal" && typeof key.value === "string"
9223 ? '"'
9224 : "",
9225 value : from_moz_pattern(M.value, sym_type)
9226 };
9227 if (M.computed) {
9228 args.key = from_moz(M.key);
9229 }
9230 return new AST_ObjectKeyVal(args);
9231
9232 case "ArrayPattern":
9233 return new AST_Destructuring({
9234 start: my_start_token(M),
9235 end: my_end_token(M),
9236 names: M.elements.map(function(elm) {
9237 if (elm === null) {
9238 return new AST_Hole();
9239 }
9240 return from_moz_pattern(elm, sym_type);
9241 }),
9242 is_array: true
9243 });
9244
9245 case "SpreadElement":
9246 case "RestElement":
9247 return new AST_Expansion({
9248 start: my_start_token(M),
9249 end: my_end_token(M),
9250 expression: from_moz_pattern(M.argument, sym_type),
9251 });
9252
9253 case "AssignmentPattern":
9254 return new AST_DefaultAssign({
9255 start : my_start_token(M),
9256 end : my_end_token(M),
9257 left : from_moz_pattern(M.left, sym_type),
9258 operator: "=",
9259 right : from_moz(M.right),
9260 });
9261
9262 case "Identifier":
9263 return new sym_type({
9264 start : my_start_token(M),
9265 end : my_end_token(M),
9266 name : M.name,
9267 });
9268
9269 default:
9270 throw new Error("Invalid node type for destructuring: " + M.type);
9271 }
9272 }
9273
9274 function from_moz_label_ref(m_label) {
9275 if (!m_label) return null;
9276
9277 const label = from_moz_symbol(AST_LabelRef, m_label);
9278
9279 let i = FROM_MOZ_LABELS.length;
9280 while (i--) {
9281 const label_origin = FROM_MOZ_LABELS[i];
9282
9283 if (label.name === label_origin.name) {
9284 label.thedef = label_origin;
9285 break;
9286 }
9287 }
9288
9289 return label;
9290 }
9291
9292 AST_Node.from_mozilla_ast = function(node) {
9293 var save_labels = FROM_MOZ_LABELS;
9294 FROM_MOZ_LABELS = [];
9295 var ast = from_moz(node);
9296 FROM_MOZ_LABELS = save_labels;
9297 return ast;
9298 };
9299
9300 function set_moz_loc(mynode, moznode) {
9301 var start = mynode.start;
9302 var end = mynode.end;
9303 if (!(start && end)) {
9304 return moznode;
9305 }
9306 if (start.pos != null && end.endpos != null) {
9307 moznode.range = [start.pos, end.endpos];
9308 }
9309 if (start.line) {
9310 moznode.loc = {
9311 start: {line: start.line, column: start.col},
9312 end: end.endline ? {line: end.endline, column: end.endcol} : null
9313 };
9314 if (start.file) {
9315 moznode.loc.source = start.file;
9316 }
9317 }
9318 return moznode;
9319 }
9320
9321 function def_to_moz(mytype, handler) {
9322 mytype.DEFMETHOD("to_mozilla_ast", function(parent) {
9323 return set_moz_loc(this, handler(this, parent));
9324 });
9325 }
9326
9327 var TO_MOZ_STACK = null;
9328
9329 function to_moz(node) {
9330 if (TO_MOZ_STACK === null) { TO_MOZ_STACK = []; }
9331 TO_MOZ_STACK.push(node);
9332 var ast = node != null ? node.to_mozilla_ast(TO_MOZ_STACK[TO_MOZ_STACK.length - 2]) : null;
9333 TO_MOZ_STACK.pop();
9334 if (TO_MOZ_STACK.length === 0) { TO_MOZ_STACK = null; }
9335 return ast;
9336 }
9337
9338 /** Object property keys can be number literals, string literals, or raw names. Additionally they can be shorthand. We decide that here. */
9339 function to_moz_property_key(key, computed = false, quote = false, value = null) {
9340 if (computed) {
9341 return [false, to_moz(key)];
9342 }
9343
9344 const key_name = typeof key === "string" ? key : key.name;
9345 let moz_key;
9346 if (quote) {
9347 moz_key = { type: "Literal", value: key_name, raw: JSON.stringify(key_name) };
9348 } else if ("" + +key_name === key_name && +key_name >= 0) {
9349 // representable as a number
9350 moz_key = { type: "Literal", value: +key_name, raw: JSON.stringify(+key_name) };
9351 } else {
9352 moz_key = { type: "Identifier", name: key_name };
9353 }
9354
9355 const shorthand =
9356 moz_key.type === "Identifier"
9357 && moz_key.name === key_name
9358 && (value instanceof AST_Symbol && value.name === key_name
9359 || value instanceof AST_DefaultAssign && value.left.name === key_name);
9360 return [shorthand, moz_key];
9361 }
9362
9363 function to_moz_pattern(node) {
9364 if (node instanceof AST_Expansion) {
9365 return {
9366 type: "RestElement",
9367 argument: to_moz_pattern(node.expression),
9368 };
9369 }
9370
9371 if ((
9372 node instanceof AST_Symbol
9373 || node instanceof AST_Destructuring
9374 || node instanceof AST_DefaultAssign
9375 || node instanceof AST_PropAccess
9376 )) {
9377 // Plain translation
9378 return to_moz(node);
9379 }
9380
9381 throw new Error(node.TYPE);
9382 }
9383
9384 function to_moz_in_destructuring() {
9385 var i = TO_MOZ_STACK.length;
9386 while (i--) {
9387 if (TO_MOZ_STACK[i] instanceof AST_Destructuring) {
9388 return true;
9389 }
9390 }
9391 return false;
9392 }
9393
9394 function to_moz_block(node) {
9395 return {
9396 type: "BlockStatement",
9397 body: node.body.map(to_moz)
9398 };
9399 }
9400
9401 function to_moz_scope(type, node) {
9402 var body = node.body.map(to_moz);
9403 if (node.body[0] instanceof AST_SimpleStatement && node.body[0].body instanceof AST_String) {
9404 body.unshift(to_moz(new AST_EmptyStatement(node.body[0])));
9405 }
9406 return {
9407 type: type,
9408 body: body
9409 };
9410 }
9411})();
9412
9413// return true if the node at the top of the stack (that means the
9414// innermost node in the current output) is lexically the first in
9415// a statement.
9416function first_in_statement(stack) {
9417 let node = stack.parent(-1);
9418 for (let i = 0, p; p = stack.parent(i); i++) {
9419 if (p instanceof AST_Statement && p.body === node)
9420 return true;
9421 if ((p instanceof AST_Sequence && p.expressions[0] === node) ||
9422 (p.TYPE === "Call" && p.expression === node) ||
9423 (p instanceof AST_PrefixedTemplateString && p.prefix === node) ||
9424 (p instanceof AST_Dot && p.expression === node) ||
9425 (p instanceof AST_Sub && p.expression === node) ||
9426 (p instanceof AST_Chain && p.expression === node) ||
9427 (p instanceof AST_Conditional && p.condition === node) ||
9428 (p instanceof AST_Binary && p.left === node) ||
9429 (p instanceof AST_UnaryPostfix && p.expression === node)
9430 ) {
9431 node = p;
9432 } else {
9433 return false;
9434 }
9435 }
9436}
9437
9438// Returns whether the leftmost item in the expression is an object
9439function left_is_object(node) {
9440 if (node instanceof AST_Object) return true;
9441 if (node instanceof AST_Sequence) return left_is_object(node.expressions[0]);
9442 if (node.TYPE === "Call") return left_is_object(node.expression);
9443 if (node instanceof AST_PrefixedTemplateString) return left_is_object(node.prefix);
9444 if (node instanceof AST_Dot || node instanceof AST_Sub) return left_is_object(node.expression);
9445 if (node instanceof AST_Chain) return left_is_object(node.expression);
9446 if (node instanceof AST_Conditional) return left_is_object(node.condition);
9447 if (node instanceof AST_Binary) return left_is_object(node.left);
9448 if (node instanceof AST_UnaryPostfix) return left_is_object(node.expression);
9449 return false;
9450}
9451
9452/***********************************************************************
9453
9454 A JavaScript tokenizer / parser / beautifier / compressor.
9455 https://github.com/mishoo/UglifyJS2
9456
9457 -------------------------------- (C) ---------------------------------
9458
9459 Author: Mihai Bazon
9460 <mihai.bazon@gmail.com>
9461 http://mihai.bazon.net/blog
9462
9463 Distributed under the BSD license:
9464
9465 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
9466
9467 Redistribution and use in source and binary forms, with or without
9468 modification, are permitted provided that the following conditions
9469 are met:
9470
9471 * Redistributions of source code must retain the above
9472 copyright notice, this list of conditions and the following
9473 disclaimer.
9474
9475 * Redistributions in binary form must reproduce the above
9476 copyright notice, this list of conditions and the following
9477 disclaimer in the documentation and/or other materials
9478 provided with the distribution.
9479
9480 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
9481 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9482 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
9483 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
9484 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
9485 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
9486 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
9487 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
9488 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
9489 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
9490 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
9491 SUCH DAMAGE.
9492
9493 ***********************************************************************/
9494
9495const CODE_LINE_BREAK = 10;
9496const CODE_SPACE = 32;
9497
9498const r_annotation = /[@#]__(PURE|INLINE|NOINLINE)__/;
9499
9500function is_some_comments(comment) {
9501 // multiline comment
9502 return (
9503 (comment.type === "comment2" || comment.type === "comment1")
9504 && /@preserve|@copyright|@lic|@cc_on|^\**!/i.test(comment.value)
9505 );
9506}
9507
9508const ROPE_COMMIT_WHEN = 8 * 1000;
9509class Rope {
9510 constructor() {
9511 this.committed = "";
9512 this.current = "";
9513 }
9514
9515 append(str) {
9516 /** When `this.current` is too long, commit it. */
9517 if (this.current.length > ROPE_COMMIT_WHEN) {
9518 this.committed += this.current + str;
9519 this.current = "";
9520 } else {
9521 this.current += str;
9522 }
9523 }
9524
9525 insertAt(char, index) {
9526 const { committed, current } = this;
9527 if (index < committed.length) {
9528 this.committed = committed.slice(0, index) + char + committed.slice(index);
9529 } else if (index === committed.length) {
9530 this.committed += char;
9531 } else {
9532 index -= committed.length;
9533 this.committed += current.slice(0, index) + char;
9534 this.current = current.slice(index);
9535 }
9536 }
9537
9538 charAt(index) {
9539 const { committed } = this;
9540 if (index < committed.length) return committed[index];
9541 return this.current[index - committed.length];
9542 }
9543
9544 charCodeAt(index) {
9545 const { committed } = this;
9546 if (index < committed.length) return committed.charCodeAt(index);
9547 return this.current.charCodeAt(index - committed.length);
9548 }
9549
9550 length() {
9551 return this.committed.length + this.current.length;
9552 }
9553
9554 expectDirective() {
9555 // /^$|[;{][\s\n]*$/
9556
9557 let ch, n = this.length();
9558
9559 if (n <= 0) return true;
9560
9561 // Skip N whitespace from the end
9562 while (
9563 (ch = this.charCodeAt(--n))
9564 && (ch == CODE_SPACE || ch == CODE_LINE_BREAK)
9565 );
9566
9567 // either ";", or "{", or the string ended
9568 return !ch || ch === 59 || ch === 123;
9569 }
9570
9571 hasNLB() {
9572 let n = this.length() - 1;
9573 while (n >= 0) {
9574 const code = this.charCodeAt(n--);
9575
9576 if (code === CODE_LINE_BREAK) return true;
9577 if (code !== CODE_SPACE) return false;
9578 }
9579 return true;
9580 }
9581
9582
9583 toString() {
9584 return this.committed + this.current;
9585 }
9586}
9587
9588function OutputStream(options) {
9589
9590 var readonly = !options;
9591 options = defaults(options, {
9592 ascii_only : false,
9593 beautify : false,
9594 braces : false,
9595 comments : "some",
9596 ecma : 5,
9597 ie8 : false,
9598 indent_level : 4,
9599 indent_start : 0,
9600 inline_script : true,
9601 keep_numbers : false,
9602 keep_quoted_props : false,
9603 max_line_len : false,
9604 preamble : null,
9605 preserve_annotations : false,
9606 quote_keys : false,
9607 quote_style : 0,
9608 safari10 : false,
9609 semicolons : true,
9610 shebang : true,
9611 shorthand : undefined,
9612 source_map : null,
9613 webkit : false,
9614 width : 80,
9615 wrap_iife : false,
9616 wrap_func_args : false,
9617
9618 _destroy_ast : false
9619 }, true);
9620
9621 if (options.shorthand === undefined)
9622 options.shorthand = options.ecma > 5;
9623
9624 // Convert comment option to RegExp if necessary and set up comments filter
9625 var comment_filter = return_false; // Default case, throw all comments away
9626 if (options.comments) {
9627 let comments = options.comments;
9628 if (typeof options.comments === "string" && /^\/.*\/[a-zA-Z]*$/.test(options.comments)) {
9629 var regex_pos = options.comments.lastIndexOf("/");
9630 comments = new RegExp(
9631 options.comments.substr(1, regex_pos - 1),
9632 options.comments.substr(regex_pos + 1)
9633 );
9634 }
9635 if (comments instanceof RegExp) {
9636 comment_filter = function(comment) {
9637 return comment.type != "comment5" && comments.test(comment.value);
9638 };
9639 } else if (typeof comments === "function") {
9640 comment_filter = function(comment) {
9641 return comment.type != "comment5" && comments(this, comment);
9642 };
9643 } else if (comments === "some") {
9644 comment_filter = is_some_comments;
9645 } else { // NOTE includes "all" option
9646 comment_filter = return_true;
9647 }
9648 }
9649
9650 if (options.preserve_annotations) {
9651 let prev_comment_filter = comment_filter;
9652 comment_filter = function (comment) {
9653 return r_annotation.test(comment.value) || prev_comment_filter.apply(this, arguments);
9654 };
9655 }
9656
9657 var indentation = 0;
9658 var current_col = 0;
9659 var current_line = 1;
9660 var current_pos = 0;
9661 var OUTPUT = new Rope();
9662 let printed_comments = new Set();
9663
9664 var to_utf8 = options.ascii_only ? function(str, identifier = false, regexp = false) {
9665 if (options.ecma >= 2015 && !options.safari10 && !regexp) {
9666 str = str.replace(/[\ud800-\udbff][\udc00-\udfff]/g, function(ch) {
9667 var code = get_full_char_code(ch, 0).toString(16);
9668 return "\\u{" + code + "}";
9669 });
9670 }
9671 return str.replace(/[\u0000-\u001f\u007f-\uffff]/g, function(ch) {
9672 var code = ch.charCodeAt(0).toString(16);
9673 if (code.length <= 2 && !identifier) {
9674 while (code.length < 2) code = "0" + code;
9675 return "\\x" + code;
9676 } else {
9677 while (code.length < 4) code = "0" + code;
9678 return "\\u" + code;
9679 }
9680 });
9681 } : function(str) {
9682 return str.replace(/[\ud800-\udbff][\udc00-\udfff]|([\ud800-\udbff]|[\udc00-\udfff])/g, function(match, lone) {
9683 if (lone) {
9684 return "\\u" + lone.charCodeAt(0).toString(16);
9685 }
9686 return match;
9687 });
9688 };
9689
9690 function make_string(str, quote) {
9691 var dq = 0, sq = 0;
9692 str = str.replace(/[\\\b\f\n\r\v\t\x22\x27\u2028\u2029\0\ufeff]/g,
9693 function(s, i) {
9694 switch (s) {
9695 case '"': ++dq; return '"';
9696 case "'": ++sq; return "'";
9697 case "\\": return "\\\\";
9698 case "\n": return "\\n";
9699 case "\r": return "\\r";
9700 case "\t": return "\\t";
9701 case "\b": return "\\b";
9702 case "\f": return "\\f";
9703 case "\x0B": return options.ie8 ? "\\x0B" : "\\v";
9704 case "\u2028": return "\\u2028";
9705 case "\u2029": return "\\u2029";
9706 case "\ufeff": return "\\ufeff";
9707 case "\0":
9708 return /[0-9]/.test(get_full_char(str, i+1)) ? "\\x00" : "\\0";
9709 }
9710 return s;
9711 });
9712 function quote_single() {
9713 return "'" + str.replace(/\x27/g, "\\'") + "'";
9714 }
9715 function quote_double() {
9716 return '"' + str.replace(/\x22/g, '\\"') + '"';
9717 }
9718 function quote_template() {
9719 return "`" + str.replace(/`/g, "\\`") + "`";
9720 }
9721 str = to_utf8(str);
9722 if (quote === "`") return quote_template();
9723 switch (options.quote_style) {
9724 case 1:
9725 return quote_single();
9726 case 2:
9727 return quote_double();
9728 case 3:
9729 return quote == "'" ? quote_single() : quote_double();
9730 default:
9731 return dq > sq ? quote_single() : quote_double();
9732 }
9733 }
9734
9735 function encode_string(str, quote) {
9736 var ret = make_string(str, quote);
9737 if (options.inline_script) {
9738 ret = ret.replace(/<\x2f(script)([>\/\t\n\f\r ])/gi, "<\\/$1$2");
9739 ret = ret.replace(/\x3c!--/g, "\\x3c!--");
9740 ret = ret.replace(/--\x3e/g, "--\\x3e");
9741 }
9742 return ret;
9743 }
9744
9745 function make_name(name) {
9746 name = name.toString();
9747 name = to_utf8(name, true);
9748 return name;
9749 }
9750
9751 function make_indent(back) {
9752 return " ".repeat(options.indent_start + indentation - back * options.indent_level);
9753 }
9754
9755 /* -----[ beautification/minification ]----- */
9756
9757 var has_parens = false;
9758 var might_need_space = false;
9759 var might_need_semicolon = false;
9760 var might_add_newline = 0;
9761 var need_newline_indented = false;
9762 var need_space = false;
9763 var newline_insert = -1;
9764 var last = "";
9765 var mapping_token, mapping_name, mappings = options.source_map && [];
9766
9767 var do_add_mapping = mappings ? function() {
9768 mappings.forEach(function(mapping) {
9769 try {
9770 let { name, token } = mapping;
9771 if (name !== false) {
9772 if (token.type == "name" || token.type === "privatename") {
9773 name = token.value;
9774 } else if (name instanceof AST_Symbol) {
9775 name = token.type === "string" ? token.value : name.name;
9776 }
9777 }
9778 options.source_map.add(
9779 mapping.token.file,
9780 mapping.line, mapping.col,
9781 mapping.token.line, mapping.token.col,
9782 is_basic_identifier_string(name) ? name : undefined
9783 );
9784 } catch(ex) {
9785 // Ignore bad mapping
9786 }
9787 });
9788 mappings = [];
9789 } : noop;
9790
9791 var ensure_line_len = options.max_line_len ? function() {
9792 if (current_col > options.max_line_len) {
9793 if (might_add_newline) {
9794 OUTPUT.insertAt("\n", might_add_newline);
9795 const len_after_newline = OUTPUT.length() - might_add_newline - 1;
9796 if (mappings) {
9797 var delta = len_after_newline - current_col;
9798 mappings.forEach(function(mapping) {
9799 mapping.line++;
9800 mapping.col += delta;
9801 });
9802 }
9803 current_line++;
9804 current_pos++;
9805 current_col = len_after_newline;
9806 }
9807 }
9808 if (might_add_newline) {
9809 might_add_newline = 0;
9810 do_add_mapping();
9811 }
9812 } : noop;
9813
9814 var requireSemicolonChars = makePredicate("( [ + * / - , . `");
9815
9816 function print(str) {
9817 str = String(str);
9818 var ch = get_full_char(str, 0);
9819 if (need_newline_indented && ch) {
9820 need_newline_indented = false;
9821 if (ch !== "\n") {
9822 print("\n");
9823 indent();
9824 }
9825 }
9826 if (need_space && ch) {
9827 need_space = false;
9828 if (!/[\s;})]/.test(ch)) {
9829 space();
9830 }
9831 }
9832 newline_insert = -1;
9833 var prev = last.charAt(last.length - 1);
9834 if (might_need_semicolon) {
9835 might_need_semicolon = false;
9836
9837 if (prev === ":" && ch === "}" || (!ch || !";}".includes(ch)) && prev !== ";") {
9838 if (options.semicolons || requireSemicolonChars.has(ch)) {
9839 OUTPUT.append(";");
9840 current_col++;
9841 current_pos++;
9842 } else {
9843 ensure_line_len();
9844 if (current_col > 0) {
9845 OUTPUT.append("\n");
9846 current_pos++;
9847 current_line++;
9848 current_col = 0;
9849 }
9850
9851 if (/^\s+$/.test(str)) {
9852 // reset the semicolon flag, since we didn't print one
9853 // now and might still have to later
9854 might_need_semicolon = true;
9855 }
9856 }
9857
9858 if (!options.beautify)
9859 might_need_space = false;
9860 }
9861 }
9862
9863 if (might_need_space) {
9864 if ((is_identifier_char(prev)
9865 && (is_identifier_char(ch) || ch == "\\"))
9866 || (ch == "/" && ch == prev)
9867 || ((ch == "+" || ch == "-") && ch == last)
9868 ) {
9869 OUTPUT.append(" ");
9870 current_col++;
9871 current_pos++;
9872 }
9873 might_need_space = false;
9874 }
9875
9876 if (mapping_token) {
9877 mappings.push({
9878 token: mapping_token,
9879 name: mapping_name,
9880 line: current_line,
9881 col: current_col
9882 });
9883 mapping_token = false;
9884 if (!might_add_newline) do_add_mapping();
9885 }
9886
9887 OUTPUT.append(str);
9888 has_parens = str[str.length - 1] == "(";
9889 current_pos += str.length;
9890 var a = str.split(/\r?\n/), n = a.length - 1;
9891 current_line += n;
9892 current_col += a[0].length;
9893 if (n > 0) {
9894 ensure_line_len();
9895 current_col = a[n].length;
9896 }
9897 last = str;
9898 }
9899
9900 var star = function() {
9901 print("*");
9902 };
9903
9904 var space = options.beautify ? function() {
9905 print(" ");
9906 } : function() {
9907 might_need_space = true;
9908 };
9909
9910 var indent = options.beautify ? function(half) {
9911 if (options.beautify) {
9912 print(make_indent(half ? 0.5 : 0));
9913 }
9914 } : noop;
9915
9916 var with_indent = options.beautify ? function(col, cont) {
9917 if (col === true) col = next_indent();
9918 var save_indentation = indentation;
9919 indentation = col;
9920 var ret = cont();
9921 indentation = save_indentation;
9922 return ret;
9923 } : function(col, cont) { return cont(); };
9924
9925 var newline = options.beautify ? function() {
9926 if (newline_insert < 0) return print("\n");
9927 if (OUTPUT.charAt(newline_insert) != "\n") {
9928 OUTPUT.insertAt("\n", newline_insert);
9929 current_pos++;
9930 current_line++;
9931 }
9932 newline_insert++;
9933 } : options.max_line_len ? function() {
9934 ensure_line_len();
9935 might_add_newline = OUTPUT.length();
9936 } : noop;
9937
9938 var semicolon = options.beautify ? function() {
9939 print(";");
9940 } : function() {
9941 might_need_semicolon = true;
9942 };
9943
9944 function force_semicolon() {
9945 might_need_semicolon = false;
9946 print(";");
9947 }
9948
9949 function next_indent() {
9950 return indentation + options.indent_level;
9951 }
9952
9953 function with_block(cont) {
9954 var ret;
9955 print("{");
9956 newline();
9957 with_indent(next_indent(), function() {
9958 ret = cont();
9959 });
9960 indent();
9961 print("}");
9962 return ret;
9963 }
9964
9965 function with_parens(cont) {
9966 print("(");
9967 //XXX: still nice to have that for argument lists
9968 //var ret = with_indent(current_col, cont);
9969 var ret = cont();
9970 print(")");
9971 return ret;
9972 }
9973
9974 function with_square(cont) {
9975 print("[");
9976 //var ret = with_indent(current_col, cont);
9977 var ret = cont();
9978 print("]");
9979 return ret;
9980 }
9981
9982 function comma() {
9983 print(",");
9984 space();
9985 }
9986
9987 function colon() {
9988 print(":");
9989 space();
9990 }
9991
9992 var add_mapping = mappings ? function(token, name) {
9993 mapping_token = token;
9994 mapping_name = name;
9995 } : noop;
9996
9997 function get() {
9998 if (might_add_newline) {
9999 ensure_line_len();
10000 }
10001 return OUTPUT.toString();
10002 }
10003
10004 function filter_comment(comment) {
10005 if (!options.preserve_annotations) {
10006 comment = comment.replace(r_annotation, " ");
10007 }
10008 if (/^\s*$/.test(comment)) {
10009 return "";
10010 }
10011 return comment.replace(/(<\s*\/\s*)(script)/i, "<\\/$2");
10012 }
10013
10014 function prepend_comments(node) {
10015 var self = this;
10016 var start = node.start;
10017 if (!start) return;
10018 var printed_comments = self.printed_comments;
10019
10020 // There cannot be a newline between return/yield and its value.
10021 const keyword_with_value =
10022 node instanceof AST_Exit && node.value
10023 || (node instanceof AST_Await || node instanceof AST_Yield)
10024 && node.expression;
10025
10026 if (
10027 start.comments_before
10028 && printed_comments.has(start.comments_before)
10029 ) {
10030 if (keyword_with_value) {
10031 start.comments_before = [];
10032 } else {
10033 return;
10034 }
10035 }
10036
10037 var comments = start.comments_before;
10038 if (!comments) {
10039 comments = start.comments_before = [];
10040 }
10041 printed_comments.add(comments);
10042
10043 if (keyword_with_value) {
10044 var tw = new TreeWalker(function(node) {
10045 var parent = tw.parent();
10046 if (parent instanceof AST_Exit
10047 || parent instanceof AST_Await
10048 || parent instanceof AST_Yield
10049 || parent instanceof AST_Binary && parent.left === node
10050 || parent.TYPE == "Call" && parent.expression === node
10051 || parent instanceof AST_Conditional && parent.condition === node
10052 || parent instanceof AST_Dot && parent.expression === node
10053 || parent instanceof AST_Sequence && parent.expressions[0] === node
10054 || parent instanceof AST_Sub && parent.expression === node
10055 || parent instanceof AST_UnaryPostfix) {
10056 if (!node.start) return;
10057 var text = node.start.comments_before;
10058 if (text && !printed_comments.has(text)) {
10059 printed_comments.add(text);
10060 comments = comments.concat(text);
10061 }
10062 } else {
10063 return true;
10064 }
10065 });
10066 tw.push(node);
10067 keyword_with_value.walk(tw);
10068 }
10069
10070 if (current_pos == 0) {
10071 if (comments.length > 0 && options.shebang && comments[0].type === "comment5"
10072 && !printed_comments.has(comments[0])) {
10073 print("#!" + comments.shift().value + "\n");
10074 indent();
10075 }
10076 var preamble = options.preamble;
10077 if (preamble) {
10078 print(preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n"));
10079 }
10080 }
10081
10082 comments = comments.filter(comment_filter, node).filter(c => !printed_comments.has(c));
10083 if (comments.length == 0) return;
10084 var last_nlb = OUTPUT.hasNLB();
10085 comments.forEach(function(c, i) {
10086 printed_comments.add(c);
10087 if (!last_nlb) {
10088 if (c.nlb) {
10089 print("\n");
10090 indent();
10091 last_nlb = true;
10092 } else if (i > 0) {
10093 space();
10094 }
10095 }
10096
10097 if (/comment[134]/.test(c.type)) {
10098 var value = filter_comment(c.value);
10099 if (value) {
10100 print("//" + value + "\n");
10101 indent();
10102 }
10103 last_nlb = true;
10104 } else if (c.type == "comment2") {
10105 var value = filter_comment(c.value);
10106 if (value) {
10107 print("/*" + value + "*/");
10108 }
10109 last_nlb = false;
10110 }
10111 });
10112 if (!last_nlb) {
10113 if (start.nlb) {
10114 print("\n");
10115 indent();
10116 } else {
10117 space();
10118 }
10119 }
10120 }
10121
10122 function append_comments(node, tail) {
10123 var self = this;
10124 var token = node.end;
10125 if (!token) return;
10126 var printed_comments = self.printed_comments;
10127 var comments = token[tail ? "comments_before" : "comments_after"];
10128 if (!comments || printed_comments.has(comments)) return;
10129 if (!(node instanceof AST_Statement || comments.every((c) =>
10130 !/comment[134]/.test(c.type)
10131 ))) return;
10132 printed_comments.add(comments);
10133 var insert = OUTPUT.length();
10134 comments.filter(comment_filter, node).forEach(function(c, i) {
10135 if (printed_comments.has(c)) return;
10136 printed_comments.add(c);
10137 need_space = false;
10138 if (need_newline_indented) {
10139 print("\n");
10140 indent();
10141 need_newline_indented = false;
10142 } else if (c.nlb && (i > 0 || !OUTPUT.hasNLB())) {
10143 print("\n");
10144 indent();
10145 } else if (i > 0 || !tail) {
10146 space();
10147 }
10148 if (/comment[134]/.test(c.type)) {
10149 const value = filter_comment(c.value);
10150 if (value) {
10151 print("//" + value);
10152 }
10153 need_newline_indented = true;
10154 } else if (c.type == "comment2") {
10155 const value = filter_comment(c.value);
10156 if (value) {
10157 print("/*" + value + "*/");
10158 }
10159 need_space = true;
10160 }
10161 });
10162 if (OUTPUT.length() > insert) newline_insert = insert;
10163 }
10164
10165 /**
10166 * When output.option("_destroy_ast") is enabled, destroy the function.
10167 * Call this after printing it.
10168 */
10169 const gc_scope =
10170 options["_destroy_ast"]
10171 ? function gc_scope(scope) {
10172 scope.body.length = 0;
10173 scope.argnames.length = 0;
10174 }
10175 : noop;
10176
10177 var stack = [];
10178 return {
10179 get : get,
10180 toString : get,
10181 indent : indent,
10182 in_directive : false,
10183 use_asm : null,
10184 active_scope : null,
10185 indentation : function() { return indentation; },
10186 current_width : function() { return current_col - indentation; },
10187 should_break : function() { return options.width && this.current_width() >= options.width; },
10188 has_parens : function() { return has_parens; },
10189 newline : newline,
10190 print : print,
10191 star : star,
10192 space : space,
10193 comma : comma,
10194 colon : colon,
10195 last : function() { return last; },
10196 semicolon : semicolon,
10197 force_semicolon : force_semicolon,
10198 to_utf8 : to_utf8,
10199 print_name : function(name) { print(make_name(name)); },
10200 print_string : function(str, quote, escape_directive) {
10201 var encoded = encode_string(str, quote);
10202 if (escape_directive === true && !encoded.includes("\\")) {
10203 // Insert semicolons to break directive prologue
10204 if (!OUTPUT.expectDirective()) {
10205 force_semicolon();
10206 }
10207 force_semicolon();
10208 }
10209 print(encoded);
10210 },
10211 print_template_string_chars: function(str) {
10212 var encoded = encode_string(str, "`").replace(/\${/g, "\\${");
10213 return print(encoded.substr(1, encoded.length - 2));
10214 },
10215 encode_string : encode_string,
10216 next_indent : next_indent,
10217 with_indent : with_indent,
10218 with_block : with_block,
10219 with_parens : with_parens,
10220 with_square : with_square,
10221 add_mapping : add_mapping,
10222 option : function(opt) { return options[opt]; },
10223 gc_scope,
10224 printed_comments: printed_comments,
10225 prepend_comments: readonly ? noop : prepend_comments,
10226 append_comments : readonly || comment_filter === return_false ? noop : append_comments,
10227 line : function() { return current_line; },
10228 col : function() { return current_col; },
10229 pos : function() { return current_pos; },
10230 push_node : function(node) { stack.push(node); },
10231 pop_node : function() { return stack.pop(); },
10232 parent : function(n) {
10233 return stack[stack.length - 2 - (n || 0)];
10234 }
10235 };
10236
10237}
10238
10239/* -----[ code generators ]----- */
10240
10241(function() {
10242
10243 /* -----[ utils ]----- */
10244
10245 function DEFPRINT(nodetype, generator) {
10246 nodetype.DEFMETHOD("_codegen", generator);
10247 }
10248
10249 AST_Node.DEFMETHOD("print", function(output, force_parens) {
10250 var self = this, generator = self._codegen;
10251 if (self instanceof AST_Scope) {
10252 output.active_scope = self;
10253 } else if (!output.use_asm && self instanceof AST_Directive && self.value == "use asm") {
10254 output.use_asm = output.active_scope;
10255 }
10256 function doit() {
10257 output.prepend_comments(self);
10258 self.add_source_map(output);
10259 generator(self, output);
10260 output.append_comments(self);
10261 }
10262 output.push_node(self);
10263 if (force_parens || self.needs_parens(output)) {
10264 output.with_parens(doit);
10265 } else {
10266 doit();
10267 }
10268 output.pop_node();
10269 if (self === output.use_asm) {
10270 output.use_asm = null;
10271 }
10272 });
10273 AST_Node.DEFMETHOD("_print", AST_Node.prototype.print);
10274
10275 AST_Node.DEFMETHOD("print_to_string", function(options) {
10276 var output = OutputStream(options);
10277 this.print(output);
10278 return output.get();
10279 });
10280
10281 /* -----[ PARENTHESES ]----- */
10282
10283 function PARENS(nodetype, func) {
10284 if (Array.isArray(nodetype)) {
10285 nodetype.forEach(function(nodetype) {
10286 PARENS(nodetype, func);
10287 });
10288 } else {
10289 nodetype.DEFMETHOD("needs_parens", func);
10290 }
10291 }
10292
10293 PARENS(AST_Node, return_false);
10294
10295 // a function expression needs parens around it when it's provably
10296 // the first token to appear in a statement.
10297 PARENS(AST_Function, function(output) {
10298 if (!output.has_parens() && first_in_statement(output)) {
10299 return true;
10300 }
10301
10302 if (output.option("webkit")) {
10303 var p = output.parent();
10304 if (p instanceof AST_PropAccess && p.expression === this) {
10305 return true;
10306 }
10307 }
10308
10309 if (output.option("wrap_iife")) {
10310 var p = output.parent();
10311 if (p instanceof AST_Call && p.expression === this) {
10312 return true;
10313 }
10314 }
10315
10316 if (output.option("wrap_func_args")) {
10317 var p = output.parent();
10318 if (p instanceof AST_Call && p.args.includes(this)) {
10319 return true;
10320 }
10321 }
10322
10323 return false;
10324 });
10325
10326 PARENS(AST_Arrow, function(output) {
10327 var p = output.parent();
10328
10329 if (
10330 output.option("wrap_func_args")
10331 && p instanceof AST_Call
10332 && p.args.includes(this)
10333 ) {
10334 return true;
10335 }
10336 return p instanceof AST_PropAccess && p.expression === this
10337 || p instanceof AST_Conditional && p.condition === this;
10338 });
10339
10340 // same goes for an object literal (as in AST_Function), because
10341 // otherwise {...} would be interpreted as a block of code.
10342 PARENS(AST_Object, function(output) {
10343 return !output.has_parens() && first_in_statement(output);
10344 });
10345
10346 PARENS(AST_ClassExpression, first_in_statement);
10347
10348 PARENS(AST_Unary, function(output) {
10349 var p = output.parent();
10350 return p instanceof AST_PropAccess && p.expression === this
10351 || p instanceof AST_Call && p.expression === this
10352 || p instanceof AST_Binary
10353 && p.operator === "**"
10354 && this instanceof AST_UnaryPrefix
10355 && p.left === this
10356 && this.operator !== "++"
10357 && this.operator !== "--";
10358 });
10359
10360 PARENS(AST_Await, function(output) {
10361 var p = output.parent();
10362 return p instanceof AST_PropAccess && p.expression === this
10363 || p instanceof AST_Call && p.expression === this
10364 || p instanceof AST_Binary && p.operator === "**" && p.left === this
10365 || output.option("safari10") && p instanceof AST_UnaryPrefix;
10366 });
10367
10368 PARENS(AST_Sequence, function(output) {
10369 var p = output.parent();
10370 return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4)
10371 || p instanceof AST_Unary // !(foo, bar, baz)
10372 || p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8
10373 || p instanceof AST_VarDefLike // var a = (1, 2), b = a + a; ==> b == 4
10374 || p instanceof AST_PropAccess && this !== p.property // (1, {foo:2}).foo, (1, {foo:2})["foo"], not foo[1, 2]
10375 || p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ]
10376 || p instanceof AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2
10377 || p instanceof AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30)
10378 * ==> 20 (side effect, set a := 10 and b := 20) */
10379 || p instanceof AST_Arrow // x => (x, x)
10380 || p instanceof AST_DefaultAssign // x => (x = (0, function(){}))
10381 || p instanceof AST_Expansion // [...(a, b)]
10382 || p instanceof AST_ForOf && this === p.object // for (e of (foo, bar)) {}
10383 || p instanceof AST_Yield // yield (foo, bar)
10384 || p instanceof AST_Export // export default (foo, bar)
10385 ;
10386 });
10387
10388 PARENS(AST_Binary, function(output) {
10389 var p = output.parent();
10390 // (foo && bar)()
10391 if (p instanceof AST_Call && p.expression === this)
10392 return true;
10393 // typeof (foo && bar)
10394 if (p instanceof AST_Unary)
10395 return true;
10396 // (foo && bar)["prop"], (foo && bar).prop
10397 if (p instanceof AST_PropAccess && p.expression === this)
10398 return true;
10399 // this deals with precedence: 3 * (2 + 1)
10400 if (p instanceof AST_Binary) {
10401 const parent_op = p.operator;
10402 const op = this.operator;
10403
10404 // It is forbidden for ?? to be used with || or && without parens.
10405 if (op === "??" && (parent_op === "||" || parent_op === "&&")) {
10406 return true;
10407 }
10408 if (parent_op === "??" && (op === "||" || op === "&&")) {
10409 return true;
10410 }
10411
10412 const pp = PRECEDENCE[parent_op];
10413 const sp = PRECEDENCE[op];
10414 if (pp > sp
10415 || (pp == sp
10416 && (this === p.right || parent_op == "**"))) {
10417 return true;
10418 }
10419 }
10420 if (p instanceof AST_PrivateIn) {
10421 const op = this.operator;
10422
10423 const pp = PRECEDENCE["in"];
10424 const sp = PRECEDENCE[op];
10425 if (pp > sp || (pp == sp && this === p.value)) {
10426 return true;
10427 }
10428 }
10429 });
10430
10431 PARENS(AST_PrivateIn, function(output) {
10432 var p = output.parent();
10433 // (#x in this)()
10434 if (p instanceof AST_Call && p.expression === this) {
10435 return true;
10436 }
10437 // typeof (#x in this)
10438 if (p instanceof AST_Unary) {
10439 return true;
10440 }
10441 // (#x in this)["prop"], (#x in this).prop
10442 if (p instanceof AST_PropAccess && p.expression === this) {
10443 return true;
10444 }
10445 // same precedence as regular in operator
10446 if (p instanceof AST_Binary) {
10447 const parent_op = p.operator;
10448
10449 const pp = PRECEDENCE[parent_op];
10450 const sp = PRECEDENCE["in"];
10451 if (pp > sp
10452 || (pp == sp
10453 && (this === p.right || parent_op == "**"))) {
10454 return true;
10455 }
10456 }
10457 // rules are the same as binary in, but the class differs
10458 if (p instanceof AST_PrivateIn && this === p.value) {
10459 return true;
10460 }
10461 });
10462
10463 PARENS(AST_Yield, function(output) {
10464 var p = output.parent();
10465 // (yield 1) + (yield 2)
10466 // a = yield 3
10467 if (p instanceof AST_Binary && p.operator !== "=")
10468 return true;
10469 // (yield 1)()
10470 // new (yield 1)()
10471 if (p instanceof AST_Call && p.expression === this)
10472 return true;
10473 // (yield 1) ? yield 2 : yield 3
10474 if (p instanceof AST_Conditional && p.condition === this)
10475 return true;
10476 // -(yield 4)
10477 if (p instanceof AST_Unary)
10478 return true;
10479 // (yield x).foo
10480 // (yield x)['foo']
10481 if (p instanceof AST_PropAccess && p.expression === this)
10482 return true;
10483 });
10484
10485 PARENS(AST_Chain, function(output) {
10486 var p = output.parent();
10487 if (!(p instanceof AST_Call || p instanceof AST_PropAccess)) return false;
10488 return p.expression === this;
10489 });
10490
10491 PARENS(AST_PropAccess, function(output) {
10492 var p = output.parent();
10493 if (p instanceof AST_New && p.expression === this) {
10494 // i.e. new (foo.bar().baz)
10495 //
10496 // if there's one call into this subtree, then we need
10497 // parens around it too, otherwise the call will be
10498 // interpreted as passing the arguments to the upper New
10499 // expression.
10500 return walk(this, node => {
10501 if (node instanceof AST_Scope) return true;
10502 if (node instanceof AST_Call) {
10503 return walk_abort; // makes walk() return true.
10504 }
10505 });
10506 }
10507 });
10508
10509 PARENS(AST_Call, function(output) {
10510 var p = output.parent(), p1;
10511 if (p instanceof AST_New && p.expression === this
10512 || p instanceof AST_Export && p.is_default && this.expression instanceof AST_Function)
10513 return true;
10514
10515 // workaround for Safari bug.
10516 // https://bugs.webkit.org/show_bug.cgi?id=123506
10517 return this.expression instanceof AST_Function
10518 && p instanceof AST_PropAccess
10519 && p.expression === this
10520 && (p1 = output.parent(1)) instanceof AST_Assign
10521 && p1.left === p;
10522 });
10523
10524 PARENS(AST_New, function(output) {
10525 var p = output.parent();
10526 if (this.args.length === 0
10527 && (p instanceof AST_PropAccess // (new Date).getTime(), (new Date)["getTime"]()
10528 || p instanceof AST_Call && p.expression === this
10529 || p instanceof AST_PrefixedTemplateString && p.prefix === this)) // (new foo)(bar)
10530 return true;
10531 });
10532
10533 PARENS(AST_Number, function(output) {
10534 var p = output.parent();
10535 if (p instanceof AST_PropAccess && p.expression === this) {
10536 var value = this.getValue();
10537 if (value < 0 || /^0/.test(make_num(value))) {
10538 return true;
10539 }
10540 }
10541 });
10542
10543 PARENS(AST_BigInt, function(output) {
10544 var p = output.parent();
10545 if (p instanceof AST_PropAccess && p.expression === this) {
10546 var value = this.getValue();
10547 if (value.startsWith("-")) {
10548 return true;
10549 }
10550 }
10551 });
10552
10553 PARENS([ AST_Assign, AST_Conditional ], function(output) {
10554 var p = output.parent();
10555 // !(a = false) → true
10556 if (p instanceof AST_Unary)
10557 return true;
10558 // 1 + (a = 2) + 3 → 6, side effect setting a = 2
10559 if (p instanceof AST_Binary && !(p instanceof AST_Assign))
10560 return true;
10561 // (a = func)() —or— new (a = Object)()
10562 if (p instanceof AST_Call && p.expression === this)
10563 return true;
10564 // (a = foo) ? bar : baz
10565 if (p instanceof AST_Conditional && p.condition === this)
10566 return true;
10567 // (a = foo)["prop"] —or— (a = foo).prop
10568 if (p instanceof AST_PropAccess && p.expression === this)
10569 return true;
10570 // ({a, b} = {a: 1, b: 2}), a destructuring assignment
10571 if (this instanceof AST_Assign && this.left instanceof AST_Destructuring && this.left.is_array === false)
10572 return true;
10573 });
10574
10575 /* -----[ PRINTERS ]----- */
10576
10577 DEFPRINT(AST_Directive, function(self, output) {
10578 output.print_string(self.value, self.quote);
10579 output.semicolon();
10580 });
10581
10582 DEFPRINT(AST_Expansion, function (self, output) {
10583 output.print("...");
10584 self.expression.print(output);
10585 });
10586
10587 DEFPRINT(AST_Destructuring, function (self, output) {
10588 output.print(self.is_array ? "[" : "{");
10589 var len = self.names.length;
10590 self.names.forEach(function (name, i) {
10591 if (i > 0) output.comma();
10592 name.print(output);
10593 // If the final element is a hole, we need to make sure it
10594 // doesn't look like a trailing comma, by inserting an actual
10595 // trailing comma.
10596 if (i == len - 1 && name instanceof AST_Hole) output.comma();
10597 });
10598 output.print(self.is_array ? "]" : "}");
10599 });
10600
10601 DEFPRINT(AST_Debugger, function(self, output) {
10602 output.print("debugger");
10603 output.semicolon();
10604 });
10605
10606 /* -----[ statements ]----- */
10607
10608 function display_body(body, is_toplevel, output, allow_directives) {
10609 var last = body.length - 1;
10610 output.in_directive = allow_directives;
10611 body.forEach(function(stmt, i) {
10612 if (output.in_directive === true && !(stmt instanceof AST_Directive ||
10613 stmt instanceof AST_EmptyStatement ||
10614 (stmt instanceof AST_SimpleStatement && stmt.body instanceof AST_String)
10615 )) {
10616 output.in_directive = false;
10617 }
10618 if (!(stmt instanceof AST_EmptyStatement)) {
10619 output.indent();
10620 stmt.print(output);
10621 if (!(i == last && is_toplevel)) {
10622 output.newline();
10623 if (is_toplevel) output.newline();
10624 }
10625 }
10626 if (output.in_directive === true &&
10627 stmt instanceof AST_SimpleStatement &&
10628 stmt.body instanceof AST_String
10629 ) {
10630 output.in_directive = false;
10631 }
10632 });
10633 output.in_directive = false;
10634 }
10635
10636 AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output) {
10637 print_maybe_braced_body(this.body, output);
10638 });
10639
10640 DEFPRINT(AST_Statement, function(self, output) {
10641 self.body.print(output);
10642 output.semicolon();
10643 });
10644 DEFPRINT(AST_Toplevel, function(self, output) {
10645 display_body(self.body, true, output, true);
10646 output.print("");
10647 });
10648 DEFPRINT(AST_LabeledStatement, function(self, output) {
10649 self.label.print(output);
10650 output.colon();
10651 self.body.print(output);
10652 });
10653 DEFPRINT(AST_SimpleStatement, function(self, output) {
10654 self.body.print(output);
10655 output.semicolon();
10656 });
10657 function print_braced_empty(self, output) {
10658 output.print("{");
10659 output.with_indent(output.next_indent(), function() {
10660 output.append_comments(self, true);
10661 });
10662 output.add_mapping(self.end);
10663 output.print("}");
10664 }
10665 function print_braced(self, output, allow_directives) {
10666 if (self.body.length > 0) {
10667 output.with_block(function() {
10668 display_body(self.body, false, output, allow_directives);
10669 output.add_mapping(self.end);
10670 });
10671 } else print_braced_empty(self, output);
10672 }
10673 DEFPRINT(AST_BlockStatement, function(self, output) {
10674 print_braced(self, output);
10675 });
10676 DEFPRINT(AST_EmptyStatement, function(self, output) {
10677 output.semicolon();
10678 });
10679 DEFPRINT(AST_Do, function(self, output) {
10680 output.print("do");
10681 output.space();
10682 make_block(self.body, output);
10683 output.space();
10684 output.print("while");
10685 output.space();
10686 output.with_parens(function() {
10687 self.condition.print(output);
10688 });
10689 output.semicolon();
10690 });
10691 DEFPRINT(AST_While, function(self, output) {
10692 output.print("while");
10693 output.space();
10694 output.with_parens(function() {
10695 self.condition.print(output);
10696 });
10697 output.space();
10698 self._do_print_body(output);
10699 });
10700 DEFPRINT(AST_For, function(self, output) {
10701 output.print("for");
10702 output.space();
10703 output.with_parens(function() {
10704 if (self.init) {
10705 if (self.init instanceof AST_DefinitionsLike) {
10706 self.init.print(output);
10707 } else {
10708 parenthesize_for_noin(self.init, output, true);
10709 }
10710 output.print(";");
10711 output.space();
10712 } else {
10713 output.print(";");
10714 }
10715 if (self.condition) {
10716 self.condition.print(output);
10717 output.print(";");
10718 output.space();
10719 } else {
10720 output.print(";");
10721 }
10722 if (self.step) {
10723 self.step.print(output);
10724 }
10725 });
10726 output.space();
10727 self._do_print_body(output);
10728 });
10729 DEFPRINT(AST_ForIn, function(self, output) {
10730 output.print("for");
10731 if (self.await) {
10732 output.space();
10733 output.print("await");
10734 }
10735 output.space();
10736 output.with_parens(function() {
10737 self.init.print(output);
10738 output.space();
10739 output.print(self instanceof AST_ForOf ? "of" : "in");
10740 output.space();
10741 self.object.print(output);
10742 });
10743 output.space();
10744 self._do_print_body(output);
10745 });
10746 DEFPRINT(AST_With, function(self, output) {
10747 output.print("with");
10748 output.space();
10749 output.with_parens(function() {
10750 self.expression.print(output);
10751 });
10752 output.space();
10753 self._do_print_body(output);
10754 });
10755
10756 /* -----[ functions ]----- */
10757 AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword) {
10758 var self = this;
10759 if (!nokeyword) {
10760 if (self.async) {
10761 output.print("async");
10762 output.space();
10763 }
10764 output.print("function");
10765 if (self.is_generator) {
10766 output.star();
10767 }
10768 if (self.name) {
10769 output.space();
10770 }
10771 }
10772 if (self.name instanceof AST_Symbol) {
10773 self.name.print(output);
10774 } else if (nokeyword && self.name instanceof AST_Node) {
10775 output.with_square(function() {
10776 self.name.print(output); // Computed method name
10777 });
10778 }
10779 output.with_parens(function() {
10780 self.argnames.forEach(function(arg, i) {
10781 if (i) output.comma();
10782 arg.print(output);
10783 });
10784 });
10785 output.space();
10786 print_braced(self, output, true);
10787 });
10788 DEFPRINT(AST_Lambda, function(self, output) {
10789 self._do_print(output);
10790 output.gc_scope(self);
10791 });
10792
10793 DEFPRINT(AST_PrefixedTemplateString, function(self, output) {
10794 var tag = self.prefix;
10795 var parenthesize_tag = tag instanceof AST_Lambda
10796 || tag instanceof AST_Binary
10797 || tag instanceof AST_Conditional
10798 || tag instanceof AST_Sequence
10799 || tag instanceof AST_Unary
10800 || tag instanceof AST_Dot && tag.expression instanceof AST_Object;
10801 if (parenthesize_tag) output.print("(");
10802 self.prefix.print(output);
10803 if (parenthesize_tag) output.print(")");
10804 self.template_string.print(output);
10805 });
10806 DEFPRINT(AST_TemplateString, function(self, output) {
10807 var is_tagged = output.parent() instanceof AST_PrefixedTemplateString;
10808
10809 output.print("`");
10810 for (var i = 0; i < self.segments.length; i++) {
10811 if (!(self.segments[i] instanceof AST_TemplateSegment)) {
10812 output.print("${");
10813 self.segments[i].print(output);
10814 output.print("}");
10815 } else if (is_tagged) {
10816 output.print(self.segments[i].raw);
10817 } else {
10818 output.print_template_string_chars(self.segments[i].value);
10819 }
10820 }
10821 output.print("`");
10822 });
10823 DEFPRINT(AST_TemplateSegment, function(self, output) {
10824 output.print_template_string_chars(self.value);
10825 });
10826
10827 AST_Arrow.DEFMETHOD("_do_print", function(output) {
10828 var self = this;
10829 var parent = output.parent();
10830 var needs_parens = (parent instanceof AST_Binary &&
10831 !(parent instanceof AST_Assign) &&
10832 !(parent instanceof AST_DefaultAssign)) ||
10833 parent instanceof AST_Unary ||
10834 (parent instanceof AST_Call && self === parent.expression);
10835 if (needs_parens) { output.print("("); }
10836 if (self.async) {
10837 output.print("async");
10838 output.space();
10839 }
10840 if (self.argnames.length === 1 && self.argnames[0] instanceof AST_Symbol) {
10841 self.argnames[0].print(output);
10842 } else {
10843 output.with_parens(function() {
10844 self.argnames.forEach(function(arg, i) {
10845 if (i) output.comma();
10846 arg.print(output);
10847 });
10848 });
10849 }
10850 output.space();
10851 output.print("=>");
10852 output.space();
10853 const first_statement = self.body[0];
10854 if (
10855 self.body.length === 1
10856 && first_statement instanceof AST_Return
10857 ) {
10858 const returned = first_statement.value;
10859 if (!returned) {
10860 output.print("{}");
10861 } else if (left_is_object(returned)) {
10862 output.print("(");
10863 returned.print(output);
10864 output.print(")");
10865 } else {
10866 returned.print(output);
10867 }
10868 } else {
10869 print_braced(self, output);
10870 }
10871 if (needs_parens) { output.print(")"); }
10872 output.gc_scope(self);
10873 });
10874
10875 /* -----[ exits ]----- */
10876 AST_Exit.DEFMETHOD("_do_print", function(output, kind) {
10877 output.print(kind);
10878 if (this.value) {
10879 output.space();
10880 const comments = this.value.start.comments_before;
10881 if (comments && comments.length && !output.printed_comments.has(comments)) {
10882 output.print("(");
10883 this.value.print(output);
10884 output.print(")");
10885 } else {
10886 this.value.print(output);
10887 }
10888 }
10889 output.semicolon();
10890 });
10891 DEFPRINT(AST_Return, function(self, output) {
10892 self._do_print(output, "return");
10893 });
10894 DEFPRINT(AST_Throw, function(self, output) {
10895 self._do_print(output, "throw");
10896 });
10897
10898 /* -----[ yield ]----- */
10899
10900 DEFPRINT(AST_Yield, function(self, output) {
10901 var star = self.is_star ? "*" : "";
10902 output.print("yield" + star);
10903 if (self.expression) {
10904 output.space();
10905 self.expression.print(output);
10906 }
10907 });
10908
10909 DEFPRINT(AST_Await, function(self, output) {
10910 output.print("await");
10911 output.space();
10912 var e = self.expression;
10913 var parens = !(
10914 e instanceof AST_Call
10915 || e instanceof AST_SymbolRef
10916 || e instanceof AST_PropAccess
10917 || e instanceof AST_Unary
10918 || e instanceof AST_Constant
10919 || e instanceof AST_Await
10920 || e instanceof AST_Object
10921 );
10922 if (parens) output.print("(");
10923 self.expression.print(output);
10924 if (parens) output.print(")");
10925 });
10926
10927 /* -----[ loop control ]----- */
10928 AST_LoopControl.DEFMETHOD("_do_print", function(output, kind) {
10929 output.print(kind);
10930 if (this.label) {
10931 output.space();
10932 this.label.print(output);
10933 }
10934 output.semicolon();
10935 });
10936 DEFPRINT(AST_Break, function(self, output) {
10937 self._do_print(output, "break");
10938 });
10939 DEFPRINT(AST_Continue, function(self, output) {
10940 self._do_print(output, "continue");
10941 });
10942
10943 /* -----[ if ]----- */
10944 function make_then(self, output) {
10945 var b = self.body;
10946 if (output.option("braces")
10947 || output.option("ie8") && b instanceof AST_Do)
10948 return make_block(b, output);
10949 // The squeezer replaces "block"-s that contain only a single
10950 // statement with the statement itself; technically, the AST
10951 // is correct, but this can create problems when we output an
10952 // IF having an ELSE clause where the THEN clause ends in an
10953 // IF *without* an ELSE block (then the outer ELSE would refer
10954 // to the inner IF). This function checks for this case and
10955 // adds the block braces if needed.
10956 if (!b) return output.force_semicolon();
10957 while (true) {
10958 if (b instanceof AST_If) {
10959 if (!b.alternative) {
10960 make_block(self.body, output);
10961 return;
10962 }
10963 b = b.alternative;
10964 } else if (b instanceof AST_StatementWithBody) {
10965 b = b.body;
10966 } else break;
10967 }
10968 print_maybe_braced_body(self.body, output);
10969 }
10970 DEFPRINT(AST_If, function(self, output) {
10971 output.print("if");
10972 output.space();
10973 output.with_parens(function() {
10974 self.condition.print(output);
10975 });
10976 output.space();
10977 if (self.alternative) {
10978 make_then(self, output);
10979 output.space();
10980 output.print("else");
10981 output.space();
10982 if (self.alternative instanceof AST_If)
10983 self.alternative.print(output);
10984 else
10985 print_maybe_braced_body(self.alternative, output);
10986 } else {
10987 self._do_print_body(output);
10988 }
10989 });
10990
10991 /* -----[ switch ]----- */
10992 DEFPRINT(AST_Switch, function(self, output) {
10993 output.print("switch");
10994 output.space();
10995 output.with_parens(function() {
10996 self.expression.print(output);
10997 });
10998 output.space();
10999 var last = self.body.length - 1;
11000 if (last < 0) print_braced_empty(self, output);
11001 else output.with_block(function() {
11002 self.body.forEach(function(branch, i) {
11003 output.indent(true);
11004 branch.print(output);
11005 if (i < last && branch.body.length > 0)
11006 output.newline();
11007 });
11008 });
11009 });
11010 AST_SwitchBranch.DEFMETHOD("_do_print_body", function(output) {
11011 output.newline();
11012 this.body.forEach(function(stmt) {
11013 output.indent();
11014 stmt.print(output);
11015 output.newline();
11016 });
11017 });
11018 DEFPRINT(AST_Default, function(self, output) {
11019 output.print("default:");
11020 self._do_print_body(output);
11021 });
11022 DEFPRINT(AST_Case, function(self, output) {
11023 output.print("case");
11024 output.space();
11025 self.expression.print(output);
11026 output.print(":");
11027 self._do_print_body(output);
11028 });
11029
11030 /* -----[ exceptions ]----- */
11031 DEFPRINT(AST_Try, function(self, output) {
11032 output.print("try");
11033 output.space();
11034 self.body.print(output);
11035 if (self.bcatch) {
11036 output.space();
11037 self.bcatch.print(output);
11038 }
11039 if (self.bfinally) {
11040 output.space();
11041 self.bfinally.print(output);
11042 }
11043 });
11044 DEFPRINT(AST_TryBlock, function(self, output) {
11045 print_braced(self, output);
11046 });
11047 DEFPRINT(AST_Catch, function(self, output) {
11048 output.print("catch");
11049 if (self.argname) {
11050 output.space();
11051 output.with_parens(function() {
11052 self.argname.print(output);
11053 });
11054 }
11055 output.space();
11056 print_braced(self, output);
11057 });
11058 DEFPRINT(AST_Finally, function(self, output) {
11059 output.print("finally");
11060 output.space();
11061 print_braced(self, output);
11062 });
11063
11064 /* -----[ var/const ]----- */
11065 AST_DefinitionsLike.DEFMETHOD("_do_print", function(output, kind) {
11066 output.print(kind);
11067 output.space();
11068 this.definitions.forEach(function(def, i) {
11069 if (i) output.comma();
11070 def.print(output);
11071 });
11072 var p = output.parent();
11073 var in_for = p instanceof AST_For || p instanceof AST_ForIn;
11074 var output_semicolon = !in_for || p && p.init !== this;
11075 if (output_semicolon)
11076 output.semicolon();
11077 });
11078 DEFPRINT(AST_Let, function(self, output) {
11079 self._do_print(output, "let");
11080 });
11081 DEFPRINT(AST_Var, function(self, output) {
11082 self._do_print(output, "var");
11083 });
11084 DEFPRINT(AST_Const, function(self, output) {
11085 self._do_print(output, "const");
11086 });
11087 DEFPRINT(AST_Using, function(self, output) {
11088 self._do_print(output, self.await ? "await using" : "using");
11089 });
11090 DEFPRINT(AST_Import, function(self, output) {
11091 output.print("import");
11092 output.space();
11093 if (self.phase) {
11094 output.print(self.phase);
11095 output.space();
11096 }
11097 if (self.imported_name) {
11098 self.imported_name.print(output);
11099 }
11100 if (self.imported_name && self.imported_names) {
11101 output.print(",");
11102 output.space();
11103 }
11104 if (self.imported_names) {
11105 if (self.imported_names.length === 1 &&
11106 self.imported_names[0].foreign_name.name === "*" &&
11107 !self.imported_names[0].foreign_name.quote) {
11108 self.imported_names[0].print(output);
11109 } else {
11110 output.print("{");
11111 self.imported_names.forEach(function (name_import, i) {
11112 output.space();
11113 name_import.print(output);
11114 if (i < self.imported_names.length - 1) {
11115 output.print(",");
11116 }
11117 });
11118 output.space();
11119 output.print("}");
11120 }
11121 }
11122 if (self.imported_name || self.imported_names) {
11123 output.space();
11124 output.print("from");
11125 output.space();
11126 }
11127 self.module_name.print(output);
11128 if (self.attributes) {
11129 output.print("with");
11130 self.attributes.print(output);
11131 }
11132 output.semicolon();
11133 });
11134 DEFPRINT(AST_ImportMeta, function(self, output) {
11135 output.print("import.meta");
11136 });
11137 DEFPRINT(AST_DynamicImport, function(self, output) {
11138 output.print("import." + self.phase);
11139 output.with_parens(function() {
11140 self.args.forEach(function(arg, i) {
11141 if (i) output.comma();
11142 arg.print(output);
11143 });
11144 });
11145 });
11146
11147 DEFPRINT(AST_NameMapping, function(self, output) {
11148 var is_import = output.parent() instanceof AST_Import;
11149 var definition = self.name.definition();
11150 var foreign_name = self.foreign_name;
11151 var names_are_different =
11152 (definition && definition.mangled_name || self.name.name) !==
11153 foreign_name.name;
11154 if (!names_are_different &&
11155 foreign_name.name === "*" &&
11156 !!foreign_name.quote != !!self.name.quote) {
11157 // export * as "*"
11158 names_are_different = true;
11159 }
11160 var foreign_name_is_name = !foreign_name.quote;
11161 if (names_are_different) {
11162 if (is_import) {
11163 if (foreign_name_is_name) {
11164 output.print(foreign_name.name);
11165 } else {
11166 output.print_string(foreign_name.name, foreign_name.quote);
11167 }
11168 } else {
11169 if (!self.name.quote) {
11170 self.name.print(output);
11171 } else {
11172 output.print_string(self.name.name, self.name.quote);
11173 }
11174
11175 }
11176 output.space();
11177 output.print("as");
11178 output.space();
11179 if (is_import) {
11180 self.name.print(output);
11181 } else {
11182 if (foreign_name_is_name) {
11183 output.print(foreign_name.name);
11184 } else {
11185 output.print_string(foreign_name.name, foreign_name.quote);
11186 }
11187 }
11188 } else {
11189 if (!self.name.quote) {
11190 self.name.print(output);
11191 } else {
11192 output.print_string(self.name.name, self.name.quote);
11193 }
11194 }
11195 });
11196
11197 DEFPRINT(AST_Export, function(self, output) {
11198 output.print("export");
11199 output.space();
11200 if (self.is_default) {
11201 output.print("default");
11202 output.space();
11203 }
11204 if (self.exported_names) {
11205 if (self.exported_names.length === 1 &&
11206 self.exported_names[0].name.name === "*" &&
11207 !self.exported_names[0].name.quote) {
11208 self.exported_names[0].print(output);
11209 } else {
11210 output.print("{");
11211 self.exported_names.forEach(function(name_export, i) {
11212 output.space();
11213 name_export.print(output);
11214 if (i < self.exported_names.length - 1) {
11215 output.print(",");
11216 }
11217 });
11218 output.space();
11219 output.print("}");
11220 }
11221 } else if (self.exported_value) {
11222 self.exported_value.print(output);
11223 } else if (self.exported_definition) {
11224 self.exported_definition.print(output);
11225 if (self.exported_definition instanceof AST_Definitions) return;
11226 }
11227 if (self.module_name) {
11228 output.space();
11229 output.print("from");
11230 output.space();
11231 self.module_name.print(output);
11232 }
11233 if (self.attributes) {
11234 output.print("with");
11235 self.attributes.print(output);
11236 }
11237 if (self.exported_value
11238 && !(self.exported_value instanceof AST_Defun ||
11239 self.exported_value instanceof AST_Function ||
11240 self.exported_value instanceof AST_Class)
11241 || self.module_name
11242 || self.exported_names
11243 ) {
11244 output.semicolon();
11245 }
11246 });
11247
11248 function parenthesize_for_noin(node, output, noin) {
11249 var parens = false;
11250 // need to take some precautions here:
11251 // https://github.com/mishoo/UglifyJS2/issues/60
11252 if (noin) {
11253 parens = walk(node, node => {
11254 // Don't go into scopes -- except arrow functions:
11255 // https://github.com/terser/terser/issues/1019#issuecomment-877642607
11256 if (node instanceof AST_Scope && !(node instanceof AST_Arrow)) {
11257 return true;
11258 }
11259 if (
11260 node instanceof AST_Binary && node.operator == "in"
11261 || node instanceof AST_PrivateIn
11262 ) {
11263 return walk_abort; // makes walk() return true
11264 }
11265 });
11266 }
11267 node.print(output, parens);
11268 }
11269
11270 DEFPRINT(AST_VarDefLike, function(self, output) {
11271 self.name.print(output);
11272 if (self.value) {
11273 output.space();
11274 output.print("=");
11275 output.space();
11276 var p = output.parent(1);
11277 var noin = p instanceof AST_For || p instanceof AST_ForIn;
11278 parenthesize_for_noin(self.value, output, noin);
11279 }
11280 });
11281
11282 /* -----[ other expressions ]----- */
11283 DEFPRINT(AST_Call, function(self, output) {
11284 self.expression.print(output);
11285 if (self instanceof AST_New && self.args.length === 0)
11286 return;
11287 if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) {
11288 output.add_mapping(self.start);
11289 }
11290 if (self.optional) output.print("?.");
11291 output.with_parens(function() {
11292 self.args.forEach(function(expr, i) {
11293 if (i) output.comma();
11294 expr.print(output);
11295 });
11296 });
11297 });
11298 DEFPRINT(AST_New, function(self, output) {
11299 output.print("new");
11300 output.space();
11301 AST_Call.prototype._codegen(self, output);
11302 });
11303
11304 AST_Sequence.DEFMETHOD("_do_print", function(output) {
11305 this.expressions.forEach(function(node, index) {
11306 if (index > 0) {
11307 output.comma();
11308 if (output.should_break()) {
11309 output.newline();
11310 output.indent();
11311 }
11312 }
11313 node.print(output);
11314 });
11315 });
11316 DEFPRINT(AST_Sequence, function(self, output) {
11317 self._do_print(output);
11318 // var p = output.parent();
11319 // if (p instanceof AST_Statement) {
11320 // output.with_indent(output.next_indent(), function(){
11321 // self._do_print(output);
11322 // });
11323 // } else {
11324 // self._do_print(output);
11325 // }
11326 });
11327 DEFPRINT(AST_Dot, function(self, output) {
11328 var expr = self.expression;
11329 expr.print(output);
11330 var prop = self.property;
11331 var print_computed = ALL_RESERVED_WORDS.has(prop)
11332 ? output.option("ie8")
11333 : !is_identifier_string(
11334 prop,
11335 output.option("ecma") >= 2015 && !output.option("safari10")
11336 );
11337
11338 if (self.optional) output.print("?.");
11339
11340 if (print_computed) {
11341 output.print("[");
11342 output.add_mapping(self.end);
11343 output.print_string(prop);
11344 output.print("]");
11345 } else {
11346 if (expr instanceof AST_Number && expr.getValue() >= 0) {
11347 if (!/[xa-f.)]/i.test(output.last())) {
11348 output.print(".");
11349 }
11350 }
11351 if (!self.optional) output.print(".");
11352 // the name after dot would be mapped about here.
11353 output.add_mapping(self.end);
11354 output.print_name(prop);
11355 }
11356 });
11357 DEFPRINT(AST_DotHash, function(self, output) {
11358 var expr = self.expression;
11359 expr.print(output);
11360 var prop = self.property;
11361
11362 if (self.optional) output.print("?");
11363 output.print(".#");
11364 output.add_mapping(self.end);
11365 output.print_name(prop);
11366 });
11367 DEFPRINT(AST_Sub, function(self, output) {
11368 self.expression.print(output);
11369 if (self.optional) output.print("?.");
11370 output.print("[");
11371 self.property.print(output);
11372 output.print("]");
11373 });
11374 DEFPRINT(AST_Chain, function(self, output) {
11375 self.expression.print(output);
11376 });
11377 DEFPRINT(AST_UnaryPrefix, function(self, output) {
11378 var op = self.operator;
11379 if (op === "--" && output.last().endsWith("!")) {
11380 // avoid printing "<!--"
11381 output.print(" ");
11382 }
11383 output.print(op);
11384 if (/^[a-z]/i.test(op)
11385 || (/[+-]$/.test(op)
11386 && self.expression instanceof AST_UnaryPrefix
11387 && /^[+-]/.test(self.expression.operator))) {
11388 output.space();
11389 }
11390 self.expression.print(output);
11391 });
11392 DEFPRINT(AST_UnaryPostfix, function(self, output) {
11393 self.expression.print(output);
11394 output.print(self.operator);
11395 });
11396 DEFPRINT(AST_Binary, function(self, output) {
11397 var op = self.operator;
11398 self.left.print(output);
11399 if (op[0] == ">" /* ">>" ">>>" ">" ">=" */
11400 && output.last().endsWith("--")) {
11401 // space is mandatory to avoid outputting -->
11402 output.print(" ");
11403 } else {
11404 // the space is optional depending on "beautify"
11405 output.space();
11406 }
11407 output.print(op);
11408 output.space();
11409 self.right.print(output);
11410 });
11411 DEFPRINT(AST_Conditional, function(self, output) {
11412 self.condition.print(output);
11413 output.space();
11414 output.print("?");
11415 output.space();
11416 self.consequent.print(output);
11417 output.space();
11418 output.colon();
11419 self.alternative.print(output);
11420 });
11421
11422 /* -----[ literals ]----- */
11423 DEFPRINT(AST_Array, function(self, output) {
11424 output.with_square(function() {
11425 var a = self.elements, len = a.length;
11426 if (len > 0) output.space();
11427 a.forEach(function(exp, i) {
11428 if (i) output.comma();
11429 exp.print(output);
11430 // If the final element is a hole, we need to make sure it
11431 // doesn't look like a trailing comma, by inserting an actual
11432 // trailing comma.
11433 if (i === len - 1 && exp instanceof AST_Hole)
11434 output.comma();
11435 });
11436 if (len > 0) output.space();
11437 });
11438 });
11439 DEFPRINT(AST_Object, function(self, output) {
11440 if (self.properties.length > 0) output.with_block(function() {
11441 self.properties.forEach(function(prop, i) {
11442 if (i) {
11443 output.print(",");
11444 output.newline();
11445 }
11446 output.indent();
11447 prop.print(output);
11448 });
11449 output.newline();
11450 });
11451 else print_braced_empty(self, output);
11452 });
11453 DEFPRINT(AST_Class, function(self, output) {
11454 output.print("class");
11455 output.space();
11456 if (self.name) {
11457 self.name.print(output);
11458 output.space();
11459 }
11460 if (self.extends) {
11461 var parens = (
11462 !(self.extends instanceof AST_SymbolRef)
11463 && !(self.extends instanceof AST_PropAccess)
11464 && !(self.extends instanceof AST_ClassExpression)
11465 && !(self.extends instanceof AST_Function)
11466 );
11467 output.print("extends");
11468 if (parens) {
11469 output.print("(");
11470 } else {
11471 output.space();
11472 }
11473 self.extends.print(output);
11474 if (parens) {
11475 output.print(")");
11476 } else {
11477 output.space();
11478 }
11479 }
11480 if (self.properties.length > 0) output.with_block(function() {
11481 self.properties.forEach(function(prop, i) {
11482 if (i) {
11483 output.newline();
11484 }
11485 output.indent();
11486 prop.print(output);
11487 });
11488 output.newline();
11489 });
11490 else output.print("{}");
11491 });
11492 DEFPRINT(AST_NewTarget, function(self, output) {
11493 output.print("new.target");
11494 });
11495
11496 /** Prints a prop name. Returns whether it can be used as a shorthand. */
11497 function print_property_name(key, quote, output) {
11498 if (output.option("quote_keys")) {
11499 output.print_string(key);
11500 return false;
11501 }
11502 if ("" + +key == key && key >= 0) {
11503 if (output.option("keep_numbers")) {
11504 output.print(key);
11505 return false;
11506 }
11507 output.print(make_num(key));
11508 return false;
11509 }
11510 var print_string = ALL_RESERVED_WORDS.has(key)
11511 ? output.option("ie8")
11512 : (
11513 output.option("ecma") < 2015 || output.option("safari10")
11514 ? !is_basic_identifier_string(key)
11515 : !is_identifier_string(key, true)
11516 );
11517 if (print_string || (quote && output.option("keep_quoted_props"))) {
11518 output.print_string(key, quote);
11519 return false;
11520 }
11521 output.print_name(key);
11522 return true;
11523 }
11524
11525 DEFPRINT(AST_ObjectKeyVal, function(self, output) {
11526 function get_name(self) {
11527 var def = self.definition();
11528 return def ? def.mangled_name || def.name : self.name;
11529 }
11530
11531 const try_shorthand = output.option("shorthand") && !(self.key instanceof AST_Node);
11532 if (
11533 try_shorthand
11534 && self.value instanceof AST_Symbol
11535 && get_name(self.value) === self.key
11536 && !ALL_RESERVED_WORDS.has(self.key)
11537 ) {
11538 const was_shorthand = print_property_name(self.key, self.quote, output);
11539 if (!was_shorthand) {
11540 output.colon();
11541 self.value.print(output);
11542 }
11543 } else if (
11544 try_shorthand
11545 && self.value instanceof AST_DefaultAssign
11546 && self.value.left instanceof AST_Symbol
11547 && get_name(self.value.left) === self.key
11548 ) {
11549 const was_shorthand = print_property_name(self.key, self.quote, output);
11550 if (!was_shorthand) {
11551 output.colon();
11552 self.value.left.print(output);
11553 }
11554 output.space();
11555 output.print("=");
11556 output.space();
11557 self.value.right.print(output);
11558 } else {
11559 if (!(self.key instanceof AST_Node)) {
11560 print_property_name(self.key, self.quote, output);
11561 } else {
11562 output.with_square(function() {
11563 self.key.print(output);
11564 });
11565 }
11566 output.colon();
11567 self.value.print(output);
11568 }
11569 });
11570 DEFPRINT(AST_ClassPrivateProperty, (self, output) => {
11571 if (self.static) {
11572 output.print("static");
11573 output.space();
11574 }
11575
11576 output.print("#");
11577
11578 print_property_name(self.key.name, undefined, output);
11579
11580 if (self.value) {
11581 output.print("=");
11582 self.value.print(output);
11583 }
11584
11585 output.semicolon();
11586 });
11587 DEFPRINT(AST_ClassProperty, (self, output) => {
11588 if (self.static) {
11589 output.print("static");
11590 output.space();
11591 }
11592
11593 if (self.key instanceof AST_SymbolClassProperty) {
11594 print_property_name(self.key.name, self.quote, output);
11595 } else {
11596 output.print("[");
11597 self.key.print(output);
11598 output.print("]");
11599 }
11600
11601 if (self.value) {
11602 output.print("=");
11603 self.value.print(output);
11604 }
11605
11606 output.semicolon();
11607 });
11608 AST_ObjectProperty.DEFMETHOD("_print_getter_setter", function(type, is_private, output) {
11609 var self = this;
11610 if (self.static) {
11611 output.print("static");
11612 output.space();
11613 }
11614 if (type) {
11615 output.print(type);
11616 output.space();
11617 }
11618 if (self.key instanceof AST_SymbolMethod) {
11619 if (is_private) output.print("#");
11620 print_property_name(self.key.name, self.quote, output);
11621 self.key.add_source_map(output);
11622 } else {
11623 output.with_square(function() {
11624 self.key.print(output);
11625 });
11626 }
11627 self.value._do_print(output, true);
11628 });
11629 DEFPRINT(AST_ObjectSetter, function(self, output) {
11630 self._print_getter_setter("set", false, output);
11631 });
11632 DEFPRINT(AST_ObjectGetter, function(self, output) {
11633 self._print_getter_setter("get", false, output);
11634 });
11635 DEFPRINT(AST_PrivateSetter, function(self, output) {
11636 self._print_getter_setter("set", true, output);
11637 });
11638 DEFPRINT(AST_PrivateGetter, function(self, output) {
11639 self._print_getter_setter("get", true, output);
11640 });
11641 DEFPRINT(AST_ConciseMethod, function(self, output) {
11642 var type;
11643 if (self.value.is_generator && self.value.async) {
11644 type = "async*";
11645 } else if (self.value.is_generator) {
11646 type = "*";
11647 } else if (self.value.async) {
11648 type = "async";
11649 }
11650 self._print_getter_setter(type, false, output);
11651 });
11652 DEFPRINT(AST_PrivateMethod, function(self, output) {
11653 var type;
11654 if (self.value.is_generator && self.value.async) {
11655 type = "async*";
11656 } else if (self.value.is_generator) {
11657 type = "*";
11658 } else if (self.value.async) {
11659 type = "async";
11660 }
11661 self._print_getter_setter(type, true, output);
11662 });
11663 DEFPRINT(AST_PrivateIn, function(self, output) {
11664 self.key.print(output);
11665 output.space();
11666 output.print("in");
11667 output.space();
11668 self.value.print(output);
11669 });
11670 DEFPRINT(AST_SymbolPrivateProperty, function(self, output) {
11671 output.print("#" + self.name);
11672 });
11673 DEFPRINT(AST_ClassStaticBlock, function (self, output) {
11674 output.print("static");
11675 output.space();
11676 print_braced(self, output);
11677 });
11678 AST_Symbol.DEFMETHOD("_do_print", function(output) {
11679 var def = this.definition();
11680 output.print_name(def ? def.mangled_name || def.name : this.name);
11681 });
11682 DEFPRINT(AST_Symbol, function (self, output) {
11683 self._do_print(output);
11684 });
11685 DEFPRINT(AST_Hole, noop);
11686 DEFPRINT(AST_This, function(self, output) {
11687 output.print("this");
11688 });
11689 DEFPRINT(AST_Super, function(self, output) {
11690 output.print("super");
11691 });
11692 DEFPRINT(AST_Constant, function(self, output) {
11693 output.print(self.getValue());
11694 });
11695 DEFPRINT(AST_String, function(self, output) {
11696 output.print_string(self.getValue(), self.quote, output.in_directive);
11697 });
11698 DEFPRINT(AST_Number, function(self, output) {
11699 if ((output.option("keep_numbers") || output.use_asm) && self.raw) {
11700 output.print(self.raw);
11701 } else {
11702 output.print(make_num(self.getValue()));
11703 }
11704 });
11705 DEFPRINT(AST_BigInt, function(self, output) {
11706 if (output.option("keep_numbers") && self.raw) {
11707 output.print(self.raw);
11708 } else {
11709 output.print(self.getValue() + "n");
11710 }
11711 });
11712
11713 const r_slash_script = /(<\s*\/\s*script)/i;
11714 const r_starts_with_script = /^\s*script/i;
11715 const slash_script_replace = (_, $1) => $1.replace("/", "\\/");
11716 DEFPRINT(AST_RegExp, function(self, output) {
11717 let { source, flags } = self.getValue();
11718 source = regexp_source_fix(source);
11719 flags = flags ? sort_regexp_flags(flags) : "";
11720
11721 // Avoid outputting end of script tag
11722 source = source.replace(r_slash_script, slash_script_replace);
11723 if (r_starts_with_script.test(source) && output.last().endsWith("<")) {
11724 output.print(" ");
11725 }
11726
11727 output.print(output.to_utf8(`/${source}/${flags}`, false, true));
11728
11729 const parent = output.parent();
11730 if (
11731 parent instanceof AST_Binary
11732 && /^\w/.test(parent.operator)
11733 && parent.left === self
11734 ) {
11735 output.print(" ");
11736 }
11737 });
11738
11739 /** if, for, while, may or may not have braces surrounding its body */
11740 function print_maybe_braced_body(stat, output) {
11741 if (output.option("braces")) {
11742 make_block(stat, output);
11743 } else {
11744 if (!stat || stat instanceof AST_EmptyStatement)
11745 output.force_semicolon();
11746 else if ((stat instanceof AST_DefinitionsLike && !(stat instanceof AST_Var)) || stat instanceof AST_Class)
11747 make_block(stat, output);
11748 else
11749 stat.print(output);
11750 }
11751 }
11752
11753 function best_of(a) {
11754 var best = a[0], len = best.length;
11755 for (var i = 1; i < a.length; ++i) {
11756 if (a[i].length < len) {
11757 best = a[i];
11758 len = best.length;
11759 }
11760 }
11761 return best;
11762 }
11763
11764 function make_num(num) {
11765 var str = num.toString(10).replace(/^0\./, ".").replace("e+", "e");
11766 var candidates = [ str ];
11767 if (Math.floor(num) === num) {
11768 if (num < 0) {
11769 candidates.push("-0x" + (-num).toString(16).toLowerCase());
11770 } else {
11771 candidates.push("0x" + num.toString(16).toLowerCase());
11772 }
11773 }
11774 var match, len, digits;
11775 if (match = /^\.0+/.exec(str)) {
11776 len = match[0].length;
11777 digits = str.slice(len);
11778 candidates.push(digits + "e-" + (digits.length + len - 1));
11779 } else if (match = /0+$/.exec(str)) {
11780 len = match[0].length;
11781 candidates.push(str.slice(0, -len) + "e" + len);
11782 } else if (match = /^(\d)\.(\d+)e(-?\d+)$/.exec(str)) {
11783 candidates.push(match[1] + match[2] + "e" + (match[3] - match[2].length));
11784 }
11785 return best_of(candidates);
11786 }
11787
11788 function make_block(stmt, output) {
11789 if (!stmt || stmt instanceof AST_EmptyStatement)
11790 output.print("{}");
11791 else if (stmt instanceof AST_BlockStatement)
11792 stmt.print(output);
11793 else output.with_block(function() {
11794 output.indent();
11795 stmt.print(output);
11796 output.newline();
11797 });
11798 }
11799
11800 /* -----[ source map generators ]----- */
11801
11802 function DEFMAP(nodetype, generator) {
11803 nodetype.forEach(function(nodetype) {
11804 nodetype.DEFMETHOD("add_source_map", generator);
11805 });
11806 }
11807
11808 DEFMAP([
11809 // We could easily add info for ALL nodes, but it seems to me that
11810 // would be quite wasteful, hence this noop in the base class.
11811 AST_Node,
11812 // since the label symbol will mark it
11813 AST_LabeledStatement,
11814 AST_Toplevel,
11815 ], noop);
11816
11817 // XXX: I'm not exactly sure if we need it for all of these nodes,
11818 // or if we should add even more.
11819 DEFMAP([
11820 AST_Array,
11821 AST_BlockStatement,
11822 AST_Catch,
11823 AST_Class,
11824 AST_Constant,
11825 AST_Debugger,
11826 AST_DefinitionsLike,
11827 AST_Directive,
11828 AST_Finally,
11829 AST_Jump,
11830 AST_Lambda,
11831 AST_New,
11832 AST_Object,
11833 AST_StatementWithBody,
11834 AST_Symbol,
11835 AST_Switch,
11836 AST_SwitchBranch,
11837 AST_TemplateString,
11838 AST_TemplateSegment,
11839 AST_Try,
11840 ], function(output) {
11841 output.add_mapping(this.start);
11842 });
11843
11844 DEFMAP([
11845 AST_ObjectGetter,
11846 AST_ObjectSetter,
11847 AST_PrivateGetter,
11848 AST_PrivateSetter,
11849 AST_ConciseMethod,
11850 AST_PrivateMethod,
11851 ], function(output) {
11852 output.add_mapping(this.start, false /*name handled below*/);
11853 });
11854
11855 DEFMAP([
11856 AST_SymbolMethod,
11857 AST_SymbolPrivateProperty
11858 ], function(output) {
11859 const tok_type = this.end && this.end.type;
11860 if (tok_type === "name" || tok_type === "privatename") {
11861 output.add_mapping(this.end, this.name);
11862 } else {
11863 output.add_mapping(this.end);
11864 }
11865 });
11866
11867 DEFMAP([ AST_ObjectProperty ], function(output) {
11868 output.add_mapping(this.start, this.key);
11869 });
11870})();
11871
11872const shallow_cmp = (node1, node2) => {
11873 return (
11874 node1 === null && node2 === null
11875 || node1.TYPE === node2.TYPE && node1.shallow_cmp(node2)
11876 );
11877};
11878
11879const equivalent_to = (tree1, tree2) => {
11880 if (!shallow_cmp(tree1, tree2)) return false;
11881 const walk_1_state = [tree1];
11882 const walk_2_state = [tree2];
11883
11884 const walk_1_push = walk_1_state.push.bind(walk_1_state);
11885 const walk_2_push = walk_2_state.push.bind(walk_2_state);
11886
11887 while (walk_1_state.length && walk_2_state.length) {
11888 const node_1 = walk_1_state.pop();
11889 const node_2 = walk_2_state.pop();
11890
11891 if (!shallow_cmp(node_1, node_2)) return false;
11892
11893 node_1._children_backwards(walk_1_push);
11894 node_2._children_backwards(walk_2_push);
11895
11896 if (walk_1_state.length !== walk_2_state.length) {
11897 // Different number of children
11898 return false;
11899 }
11900 }
11901
11902 return walk_1_state.length == 0 && walk_2_state.length == 0;
11903};
11904
11905const pass_through = () => true;
11906
11907AST_Node.prototype.shallow_cmp = function () {
11908 throw new Error("did not find a shallow_cmp function for " + this.constructor.name);
11909};
11910
11911AST_Debugger.prototype.shallow_cmp = pass_through;
11912
11913AST_Directive.prototype.shallow_cmp = function(other) {
11914 return this.value === other.value;
11915};
11916
11917AST_SimpleStatement.prototype.shallow_cmp = pass_through;
11918
11919AST_Block.prototype.shallow_cmp = pass_through;
11920
11921AST_EmptyStatement.prototype.shallow_cmp = pass_through;
11922
11923AST_LabeledStatement.prototype.shallow_cmp = function(other) {
11924 return this.label.name === other.label.name;
11925};
11926
11927AST_Do.prototype.shallow_cmp = pass_through;
11928
11929AST_While.prototype.shallow_cmp = pass_through;
11930
11931AST_For.prototype.shallow_cmp = function(other) {
11932 return (this.init == null ? other.init == null : this.init === other.init) && (this.condition == null ? other.condition == null : this.condition === other.condition) && (this.step == null ? other.step == null : this.step === other.step);
11933};
11934
11935AST_ForIn.prototype.shallow_cmp = pass_through;
11936
11937AST_ForOf.prototype.shallow_cmp = pass_through;
11938
11939AST_With.prototype.shallow_cmp = pass_through;
11940
11941AST_Toplevel.prototype.shallow_cmp = pass_through;
11942
11943AST_Expansion.prototype.shallow_cmp = pass_through;
11944
11945AST_Lambda.prototype.shallow_cmp = function(other) {
11946 return this.is_generator === other.is_generator && this.async === other.async;
11947};
11948
11949AST_Destructuring.prototype.shallow_cmp = function(other) {
11950 return this.is_array === other.is_array;
11951};
11952
11953AST_PrefixedTemplateString.prototype.shallow_cmp = pass_through;
11954
11955AST_TemplateString.prototype.shallow_cmp = pass_through;
11956
11957AST_TemplateSegment.prototype.shallow_cmp = function(other) {
11958 return this.value === other.value;
11959};
11960
11961AST_Jump.prototype.shallow_cmp = pass_through;
11962
11963AST_LoopControl.prototype.shallow_cmp = pass_through;
11964
11965AST_Await.prototype.shallow_cmp = pass_through;
11966
11967AST_Yield.prototype.shallow_cmp = function(other) {
11968 return this.is_star === other.is_star;
11969};
11970
11971AST_If.prototype.shallow_cmp = function(other) {
11972 return this.alternative == null ? other.alternative == null : this.alternative === other.alternative;
11973};
11974
11975AST_Switch.prototype.shallow_cmp = pass_through;
11976
11977AST_SwitchBranch.prototype.shallow_cmp = pass_through;
11978
11979AST_Try.prototype.shallow_cmp = function(other) {
11980 return (this.body === other.body) && (this.bcatch == null ? other.bcatch == null : this.bcatch === other.bcatch) && (this.bfinally == null ? other.bfinally == null : this.bfinally === other.bfinally);
11981};
11982
11983AST_Catch.prototype.shallow_cmp = function(other) {
11984 return this.argname == null ? other.argname == null : this.argname === other.argname;
11985};
11986
11987AST_Finally.prototype.shallow_cmp = pass_through;
11988
11989AST_DefinitionsLike.prototype.shallow_cmp = pass_through;
11990
11991AST_VarDefLike.prototype.shallow_cmp = function(other) {
11992 return this.value == null ? other.value == null : this.value === other.value;
11993};
11994
11995AST_NameMapping.prototype.shallow_cmp = pass_through;
11996
11997AST_Import.prototype.shallow_cmp = function(other) {
11998 return (this.imported_name || null) === (other.imported_name || null)
11999 && (this.imported_names || null) === (other.imported_names || null)
12000 && (this.attributes || null) === (other.attributes || null)
12001 && (this.phase || null) === (other.phase || null);
12002};
12003
12004AST_ImportMeta.prototype.shallow_cmp = pass_through;
12005
12006AST_DynamicImport.prototype.shallow_cmp = function(other) {
12007 return (this.phase || null) === (other.phase || null) && this.args.length === other.args.length;
12008};
12009
12010AST_Export.prototype.shallow_cmp = function(other) {
12011 return (this.exported_definition == null ? other.exported_definition == null : this.exported_definition === other.exported_definition) && (this.exported_value == null ? other.exported_value == null : this.exported_value === other.exported_value) && (this.exported_names == null ? other.exported_names == null : this.exported_names === other.exported_names) && (this.attributes == null ? other.attributes == null : this.attributes === other.attributes) && this.module_name === other.module_name && this.is_default === other.is_default;
12012};
12013
12014AST_Call.prototype.shallow_cmp = pass_through;
12015
12016AST_Sequence.prototype.shallow_cmp = pass_through;
12017
12018AST_PropAccess.prototype.shallow_cmp = pass_through;
12019
12020AST_Chain.prototype.shallow_cmp = pass_through;
12021
12022AST_Dot.prototype.shallow_cmp = function(other) {
12023 return (
12024 this.property === other.property
12025 && !!this.quote === !!other.quote
12026 );
12027};
12028
12029AST_DotHash.prototype.shallow_cmp = function(other) {
12030 return this.property === other.property;
12031};
12032
12033AST_Unary.prototype.shallow_cmp = function(other) {
12034 return this.operator === other.operator;
12035};
12036
12037AST_Binary.prototype.shallow_cmp = function(other) {
12038 return this.operator === other.operator;
12039};
12040
12041AST_PrivateIn.prototype.shallow_cmp = pass_through;
12042
12043AST_Conditional.prototype.shallow_cmp = pass_through;
12044
12045AST_Array.prototype.shallow_cmp = pass_through;
12046
12047AST_Object.prototype.shallow_cmp = pass_through;
12048
12049AST_ObjectProperty.prototype.shallow_cmp = pass_through;
12050
12051AST_ObjectKeyVal.prototype.shallow_cmp = function(other) {
12052 return this.key === other.key && this.quote === other.quote;
12053};
12054
12055AST_ObjectSetter.prototype.shallow_cmp = function(other) {
12056 return this.static === other.static;
12057};
12058
12059AST_ObjectGetter.prototype.shallow_cmp = function(other) {
12060 return this.static === other.static;
12061};
12062
12063AST_ConciseMethod.prototype.shallow_cmp = function(other) {
12064 return this.static === other.static;
12065};
12066
12067AST_PrivateMethod.prototype.shallow_cmp = function(other) {
12068 return this.static === other.static;
12069};
12070
12071AST_Class.prototype.shallow_cmp = function(other) {
12072 return (this.name == null ? other.name == null : this.name === other.name) && (this.extends == null ? other.extends == null : this.extends === other.extends);
12073};
12074
12075AST_ClassProperty.prototype.shallow_cmp = function(other) {
12076 return this.static === other.static
12077 && (typeof this.key === "string"
12078 ? this.key === other.key
12079 : true /* AST_Node handled elsewhere */);
12080};
12081
12082AST_ClassPrivateProperty.prototype.shallow_cmp = function(other) {
12083 return this.static === other.static;
12084};
12085
12086AST_Symbol.prototype.shallow_cmp = function(other) {
12087 return this.name === other.name;
12088};
12089
12090AST_NewTarget.prototype.shallow_cmp = pass_through;
12091
12092AST_This.prototype.shallow_cmp = pass_through;
12093
12094AST_Super.prototype.shallow_cmp = pass_through;
12095
12096AST_String.prototype.shallow_cmp = function(other) {
12097 return this.value === other.value;
12098};
12099
12100AST_Number.prototype.shallow_cmp = function(other) {
12101 return this.value === other.value;
12102};
12103
12104AST_BigInt.prototype.shallow_cmp = function(other) {
12105 return this.value === other.value;
12106};
12107
12108AST_RegExp.prototype.shallow_cmp = function (other) {
12109 return (
12110 this.value.flags === other.value.flags
12111 && this.value.source === other.value.source
12112 );
12113};
12114
12115AST_Atom.prototype.shallow_cmp = pass_through;
12116
12117/***********************************************************************
12118
12119 A JavaScript tokenizer / parser / beautifier / compressor.
12120 https://github.com/mishoo/UglifyJS2
12121
12122 -------------------------------- (C) ---------------------------------
12123
12124 Author: Mihai Bazon
12125 <mihai.bazon@gmail.com>
12126 http://mihai.bazon.net/blog
12127
12128 Distributed under the BSD license:
12129
12130 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
12131
12132 Redistribution and use in source and binary forms, with or without
12133 modification, are permitted provided that the following conditions
12134 are met:
12135
12136 * Redistributions of source code must retain the above
12137 copyright notice, this list of conditions and the following
12138 disclaimer.
12139
12140 * Redistributions in binary form must reproduce the above
12141 copyright notice, this list of conditions and the following
12142 disclaimer in the documentation and/or other materials
12143 provided with the distribution.
12144
12145 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
12146 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
12147 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12148 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
12149 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
12150 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
12151 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
12152 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
12153 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
12154 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
12155 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
12156 SUCH DAMAGE.
12157
12158 ***********************************************************************/
12159
12160const MASK_EXPORT_DONT_MANGLE = 1 << 0;
12161const MASK_EXPORT_WANT_MANGLE = 1 << 1;
12162
12163let function_defs = null;
12164let unmangleable_names = null;
12165/**
12166 * When defined, there is a function declaration somewhere that's inside of a block.
12167 * See https://tc39.es/ecma262/multipage/additional-ecmascript-features-for-web-browsers.html#sec-block-level-function-declarations-web-legacy-compatibility-semantics
12168*/
12169let scopes_with_block_defuns = null;
12170
12171class SymbolDef {
12172 constructor(scope, orig, init) {
12173 this.name = orig.name;
12174 this.orig = [ orig ];
12175 this.init = init;
12176 this.eliminated = 0;
12177 this.assignments = 0;
12178 this.scope = scope;
12179 this.replaced = 0;
12180 this.global = false;
12181 this.export = 0;
12182 this.mangled_name = null;
12183 this.undeclared = false;
12184 this.id = SymbolDef.next_id++;
12185 this.chained = false;
12186 this.direct_access = false;
12187 this.escaped = 0;
12188 this.recursive_refs = 0;
12189 this.references = [];
12190 this.should_replace = undefined;
12191 this.single_use = false;
12192 this.fixed = false;
12193 Object.seal(this);
12194 }
12195 fixed_value() {
12196 if (!this.fixed || this.fixed instanceof AST_Node) return this.fixed;
12197 return this.fixed();
12198 }
12199 unmangleable(options) {
12200 if (!options) options = {};
12201
12202 if (
12203 function_defs &&
12204 function_defs.has(this.id) &&
12205 keep_name(options.keep_fnames, this.orig[0].name)
12206 ) return true;
12207
12208 return this.global && !options.toplevel
12209 || (this.export & MASK_EXPORT_DONT_MANGLE)
12210 || this.undeclared
12211 || !options.eval && this.scope.pinned()
12212 || (this.orig[0] instanceof AST_SymbolLambda
12213 || this.orig[0] instanceof AST_SymbolDefun) && keep_name(options.keep_fnames, this.orig[0].name)
12214 || this.orig[0] instanceof AST_SymbolMethod
12215 || (this.orig[0] instanceof AST_SymbolClass
12216 || this.orig[0] instanceof AST_SymbolDefClass) && keep_name(options.keep_classnames, this.orig[0].name);
12217 }
12218 mangle(options) {
12219 const cache = options.cache && options.cache.props;
12220 if (this.global && cache && cache.has(this.name)) {
12221 this.mangled_name = cache.get(this.name);
12222 } else if (!this.mangled_name && !this.unmangleable(options)) {
12223 var s = this.scope;
12224 var sym = this.orig[0];
12225 if (options.ie8 && sym instanceof AST_SymbolLambda)
12226 s = s.parent_scope;
12227 const redefinition = redefined_catch_def(this);
12228 this.mangled_name = redefinition
12229 ? redefinition.mangled_name || redefinition.name
12230 : s.next_mangled(options, this);
12231 if (this.global && cache) {
12232 cache.set(this.name, this.mangled_name);
12233 }
12234 }
12235 }
12236}
12237
12238SymbolDef.next_id = 1;
12239
12240function redefined_catch_def(def) {
12241 if (def.orig[0] instanceof AST_SymbolCatch
12242 && def.scope.is_block_scope()
12243 ) {
12244 return def.scope.get_defun_scope().variables.get(def.name);
12245 }
12246}
12247
12248AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = undefined, toplevel = this } = {}) {
12249 options = defaults(options, {
12250 cache: null,
12251 ie8: false,
12252 safari10: false,
12253 module: false,
12254 });
12255
12256 if (!(toplevel instanceof AST_Toplevel)) {
12257 throw new Error("Invalid toplevel scope");
12258 }
12259
12260 // pass 1: setup scope chaining and handle definitions
12261 var scope = this.parent_scope = parent_scope;
12262 var labels = new Map();
12263 var defun = null;
12264 var in_destructuring = null;
12265 var for_scopes = [];
12266 var tw = new TreeWalker((node, descend) => {
12267 if (node.is_block_scope()) {
12268 const save_scope = scope;
12269 node.block_scope = scope = new AST_Scope(node);
12270 scope._block_scope = true;
12271 scope.init_scope_vars(save_scope);
12272 scope.uses_with = save_scope.uses_with;
12273 scope.uses_eval = save_scope.uses_eval;
12274
12275 if (options.safari10) {
12276 if (node instanceof AST_For || node instanceof AST_ForIn || node instanceof AST_ForOf) {
12277 for_scopes.push(scope);
12278 }
12279 }
12280
12281 if (node instanceof AST_Switch) {
12282 // XXX: HACK! Ensure the switch expression gets the correct scope (the parent scope) and the body gets the contained scope
12283 // AST_Switch has a scope within the body, but it itself "is a block scope"
12284 // This means the switched expression has to belong to the outer scope
12285 // while the body inside belongs to the switch itself.
12286 // This is pretty nasty and warrants an AST change
12287 const the_block_scope = scope;
12288 scope = save_scope;
12289 node.expression.walk(tw);
12290 scope = the_block_scope;
12291 for (let i = 0; i < node.body.length; i++) {
12292 node.body[i].walk(tw);
12293 }
12294 } else {
12295 descend();
12296 }
12297 scope = save_scope;
12298 return true;
12299 }
12300 if (node instanceof AST_Destructuring) {
12301 const save_destructuring = in_destructuring;
12302 in_destructuring = node;
12303 descend();
12304 in_destructuring = save_destructuring;
12305 return true;
12306 }
12307 if (node instanceof AST_Scope) {
12308 node.init_scope_vars(scope);
12309 var save_scope = scope;
12310 var save_defun = defun;
12311 var save_labels = labels;
12312 defun = scope = node;
12313 labels = new Map();
12314 descend();
12315 scope = save_scope;
12316 defun = save_defun;
12317 labels = save_labels;
12318 return true; // don't descend again in TreeWalker
12319 }
12320 if (node instanceof AST_LabeledStatement) {
12321 var l = node.label;
12322 if (labels.has(l.name)) {
12323 throw new Error(string_template("Label {name} defined twice", l));
12324 }
12325 labels.set(l.name, l);
12326 descend();
12327 labels.delete(l.name);
12328 return true; // no descend again
12329 }
12330 if (node instanceof AST_With) {
12331 for (var s = scope; s; s = s.parent_scope)
12332 s.uses_with = true;
12333 return;
12334 }
12335 if (node instanceof AST_Symbol) {
12336 node.scope = scope;
12337 }
12338 if (node instanceof AST_Label) {
12339 node.thedef = node;
12340 node.references = [];
12341 }
12342 if (node instanceof AST_SymbolLambda) {
12343 defun.def_function(node, node.name == "arguments" ? undefined : defun);
12344 } else if (node instanceof AST_SymbolDefun) {
12345 // Careful here, the scope where this should be defined is
12346 // the parent scope. The reason is that we enter a new
12347 // scope when we encounter the AST_Defun node (which is
12348 // instanceof AST_Scope) but we get to the symbol a bit
12349 // later.
12350 const closest_scope = defun.parent_scope;
12351
12352 // In strict mode, function definitions are block-scoped
12353 node.scope = tw.directives["use strict"]
12354 ? closest_scope
12355 : closest_scope.get_defun_scope();
12356
12357 mark_export(node.scope.def_function(node, defun), 1);
12358 } else if (node instanceof AST_SymbolClass) {
12359 mark_export(defun.def_variable(node, defun), 1);
12360 } else if (node instanceof AST_SymbolImport) {
12361 scope.def_variable(node);
12362 } else if (node instanceof AST_SymbolDefClass) {
12363 // This deals with the name of the class being available
12364 // inside the class.
12365 mark_export((node.scope = defun.parent_scope).def_function(node, defun), 1);
12366 } else if (
12367 node instanceof AST_SymbolVar
12368 || node instanceof AST_SymbolLet
12369 || node instanceof AST_SymbolConst
12370 || node instanceof AST_SymbolUsing
12371 || node instanceof AST_SymbolCatch
12372 ) {
12373 var def;
12374 if (node instanceof AST_SymbolBlockDeclaration) {
12375 def = scope.def_variable(node, null);
12376 } else {
12377 def = defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined);
12378 }
12379 if (!def.orig.every((sym) => {
12380 if (sym === node) return true;
12381 if (node instanceof AST_SymbolBlockDeclaration) {
12382 return sym instanceof AST_SymbolLambda;
12383 }
12384 return !(sym instanceof AST_SymbolLet || sym instanceof AST_SymbolConst || sym instanceof AST_SymbolUsing);
12385 })) {
12386 js_error(
12387 `"${node.name}" is redeclared`,
12388 node.start.file,
12389 node.start.line,
12390 node.start.col,
12391 node.start.pos
12392 );
12393 }
12394 if (!(node instanceof AST_SymbolFunarg)) mark_export(def, 2);
12395 if (defun !== scope) {
12396 node.mark_enclosed();
12397 var def = scope.find_variable(node);
12398 if (node.thedef !== def) {
12399 node.thedef = def;
12400 node.reference();
12401 }
12402 }
12403 } else if (node instanceof AST_LabelRef) {
12404 var sym = labels.get(node.name);
12405 if (!sym) throw new Error(string_template("Undefined label {name} [{line},{col}]", {
12406 name: node.name,
12407 line: node.start.line,
12408 col: node.start.col
12409 }));
12410 node.thedef = sym;
12411 }
12412 if (!(scope instanceof AST_Toplevel) && (node instanceof AST_Export || node instanceof AST_Import)) {
12413 js_error(
12414 `"${node.TYPE}" statement may only appear at the top level`,
12415 node.start.file,
12416 node.start.line,
12417 node.start.col,
12418 node.start.pos
12419 );
12420 }
12421 });
12422
12423 if (options.module) {
12424 tw.directives["use strict"] = true;
12425 }
12426
12427 this.walk(tw);
12428
12429 function mark_export(def, level) {
12430 if (in_destructuring) {
12431 var i = 0;
12432 do {
12433 level++;
12434 } while (tw.parent(i++) !== in_destructuring);
12435 }
12436 var node = tw.parent(level);
12437 if (def.export = node instanceof AST_Export ? MASK_EXPORT_DONT_MANGLE : 0) {
12438 var exported = node.exported_definition;
12439 if ((exported instanceof AST_Defun || exported instanceof AST_DefClass) && node.is_default) {
12440 def.export = MASK_EXPORT_WANT_MANGLE;
12441 }
12442 }
12443 }
12444
12445 // pass 2: find back references and eval
12446 const is_toplevel = this instanceof AST_Toplevel;
12447 if (is_toplevel) {
12448 this.globals = new Map();
12449 }
12450
12451 var tw = new TreeWalker(node => {
12452 if (node instanceof AST_LoopControl && node.label) {
12453 node.label.thedef.references.push(node);
12454 return true;
12455 }
12456 if (node instanceof AST_SymbolRef) {
12457 var name = node.name;
12458 if (name == "eval" && tw.parent() instanceof AST_Call) {
12459 for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope) {
12460 s.uses_eval = true;
12461 }
12462 }
12463 var sym;
12464 if (tw.parent() instanceof AST_NameMapping && tw.parent(1).module_name
12465 || !(sym = node.scope.find_variable(name))) {
12466
12467 sym = toplevel.def_global(node);
12468 if (node instanceof AST_SymbolExport) sym.export = MASK_EXPORT_DONT_MANGLE;
12469 } else if (sym.scope instanceof AST_Lambda && name == "arguments") {
12470 sym.scope.get_defun_scope().uses_arguments = true;
12471 }
12472 node.thedef = sym;
12473 node.reference();
12474 if (node.scope.is_block_scope()
12475 && !(sym.orig[0] instanceof AST_SymbolBlockDeclaration)) {
12476 node.scope = node.scope.get_defun_scope();
12477 }
12478 return true;
12479 }
12480 // ensure mangling works if catch reuses a scope variable
12481 var def;
12482 if (node instanceof AST_SymbolCatch && (def = redefined_catch_def(node.definition()))) {
12483 var s = node.scope;
12484 while (s) {
12485 push_uniq(s.enclosed, def);
12486 if (s === def.scope) break;
12487 s = s.parent_scope;
12488 }
12489 }
12490 });
12491 this.walk(tw);
12492
12493 // pass 3: work around IE8 and Safari catch scope bugs
12494 if (options.ie8 || options.safari10) {
12495 walk(this, node => {
12496 if (node instanceof AST_SymbolCatch) {
12497 var name = node.name;
12498 var refs = node.thedef.references;
12499 var scope = node.scope.get_defun_scope();
12500 var def = scope.find_variable(name)
12501 || toplevel.globals.get(name)
12502 || scope.def_variable(node);
12503 refs.forEach(function(ref) {
12504 ref.thedef = def;
12505 ref.reference();
12506 });
12507 node.thedef = def;
12508 node.reference();
12509 return true;
12510 }
12511 });
12512 }
12513
12514 // pass 4: add symbol definitions to loop scopes
12515 // Safari/Webkit bug workaround - loop init let variable shadowing argument.
12516 // https://github.com/mishoo/UglifyJS2/issues/1753
12517 // https://bugs.webkit.org/show_bug.cgi?id=171041
12518 if (options.safari10) {
12519 for (const scope of for_scopes) {
12520 scope.parent_scope.variables.forEach(function(def) {
12521 push_uniq(scope.enclosed, def);
12522 });
12523 }
12524 }
12525});
12526
12527AST_Toplevel.DEFMETHOD("def_global", function(node) {
12528 var globals = this.globals, name = node.name;
12529 if (globals.has(name)) {
12530 return globals.get(name);
12531 } else {
12532 var g = new SymbolDef(this, node);
12533 g.undeclared = true;
12534 g.global = true;
12535 globals.set(name, g);
12536 return g;
12537 }
12538});
12539
12540AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope) {
12541 this.variables = new Map(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
12542 this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
12543 this.uses_eval = false; // will be set to true if this or nested scope uses the global `eval`
12544 this.parent_scope = parent_scope; // the parent scope
12545 this.enclosed = []; // a list of variables from this or outer scope(s) that are referenced from this or inner scopes
12546 this.cname = -1; // the current index for mangling functions/variables
12547});
12548
12549AST_Scope.DEFMETHOD("conflicting_def", function (name) {
12550 return (
12551 this.enclosed.find(def => def.name === name)
12552 || this.variables.has(name)
12553 || (this.parent_scope && this.parent_scope.conflicting_def(name))
12554 );
12555});
12556
12557AST_Scope.DEFMETHOD("conflicting_def_shallow", function (name) {
12558 return (
12559 this.enclosed.find(def => def.name === name)
12560 || this.variables.has(name)
12561 );
12562});
12563
12564AST_Scope.DEFMETHOD("add_child_scope", function (scope) {
12565 // `scope` is going to be moved into `this` right now.
12566 // Update the required scopes' information
12567
12568 if (scope.parent_scope === this) return;
12569
12570 scope.parent_scope = this;
12571
12572 // Propagate to this.uses_arguments from arrow functions
12573 if ((scope instanceof AST_Arrow) && (this instanceof AST_Lambda && !this.uses_arguments)) {
12574 this.uses_arguments = walk(scope, node => {
12575 if (
12576 node instanceof AST_SymbolRef
12577 && node.scope instanceof AST_Lambda
12578 && node.name === "arguments"
12579 ) {
12580 return walk_abort;
12581 }
12582
12583 if (node instanceof AST_Lambda && !(node instanceof AST_Arrow)) {
12584 return true;
12585 }
12586 });
12587 }
12588
12589 this.uses_with = this.uses_with || scope.uses_with;
12590 this.uses_eval = this.uses_eval || scope.uses_eval;
12591
12592 const scope_ancestry = (() => {
12593 const ancestry = [];
12594 let cur = this;
12595 do {
12596 ancestry.push(cur);
12597 } while ((cur = cur.parent_scope));
12598 ancestry.reverse();
12599 return ancestry;
12600 })();
12601
12602 const new_scope_enclosed_set = new Set(scope.enclosed);
12603 const to_enclose = [];
12604 for (const scope_topdown of scope_ancestry) {
12605 to_enclose.forEach(e => push_uniq(scope_topdown.enclosed, e));
12606 for (const def of scope_topdown.variables.values()) {
12607 if (new_scope_enclosed_set.has(def)) {
12608 push_uniq(to_enclose, def);
12609 push_uniq(scope_topdown.enclosed, def);
12610 }
12611 }
12612 }
12613});
12614
12615function find_scopes_visible_from(scopes) {
12616 const found_scopes = new Set();
12617
12618 for (const scope of new Set(scopes)) {
12619 (function bubble_up(scope) {
12620 if (scope == null || found_scopes.has(scope)) return;
12621
12622 found_scopes.add(scope);
12623
12624 bubble_up(scope.parent_scope);
12625 })(scope);
12626 }
12627
12628 return [...found_scopes];
12629}
12630
12631// Creates a symbol during compression
12632AST_Scope.DEFMETHOD("create_symbol", function(SymClass, {
12633 source,
12634 tentative_name,
12635 scope,
12636 conflict_scopes = [scope],
12637 init = null
12638} = {}) {
12639 let symbol_name;
12640
12641 conflict_scopes = find_scopes_visible_from(conflict_scopes);
12642
12643 if (tentative_name) {
12644 // Implement hygiene (no new names are conflicting with existing names)
12645 tentative_name =
12646 symbol_name =
12647 tentative_name.replace(/(?:^[^a-z_$]|[^a-z0-9_$])/ig, "_");
12648
12649 let i = 0;
12650 while (conflict_scopes.find(s => s.conflicting_def_shallow(symbol_name))) {
12651 symbol_name = tentative_name + "$" + i++;
12652 }
12653 }
12654
12655 if (!symbol_name) {
12656 throw new Error("No symbol name could be generated in create_symbol()");
12657 }
12658
12659 const symbol = make_node(SymClass, source, {
12660 name: symbol_name,
12661 scope
12662 });
12663
12664 this.def_variable(symbol, init || null);
12665
12666 symbol.mark_enclosed();
12667
12668 return symbol;
12669});
12670
12671
12672AST_Node.DEFMETHOD("is_block_scope", return_false);
12673AST_Class.DEFMETHOD("is_block_scope", return_false);
12674AST_Lambda.DEFMETHOD("is_block_scope", return_false);
12675AST_Toplevel.DEFMETHOD("is_block_scope", return_false);
12676AST_SwitchBranch.DEFMETHOD("is_block_scope", return_false);
12677AST_Block.DEFMETHOD("is_block_scope", return_true);
12678AST_Scope.DEFMETHOD("is_block_scope", function () {
12679 return this._block_scope || false;
12680});
12681AST_IterationStatement.DEFMETHOD("is_block_scope", return_true);
12682
12683AST_Lambda.DEFMETHOD("init_scope_vars", function() {
12684 AST_Scope.prototype.init_scope_vars.apply(this, arguments);
12685 this.uses_arguments = false;
12686 this.def_variable(new AST_SymbolFunarg({
12687 name: "arguments",
12688 start: this.start,
12689 end: this.end
12690 }));
12691});
12692
12693AST_Arrow.DEFMETHOD("init_scope_vars", function() {
12694 AST_Scope.prototype.init_scope_vars.apply(this, arguments);
12695 this.uses_arguments = false;
12696});
12697
12698AST_Symbol.DEFMETHOD("mark_enclosed", function() {
12699 var def = this.definition();
12700 var s = this.scope;
12701 while (s) {
12702 push_uniq(s.enclosed, def);
12703 if (s === def.scope) break;
12704 s = s.parent_scope;
12705 }
12706});
12707
12708AST_Symbol.DEFMETHOD("reference", function() {
12709 this.definition().references.push(this);
12710 this.mark_enclosed();
12711});
12712
12713AST_Scope.DEFMETHOD("find_variable", function(name) {
12714 if (name instanceof AST_Symbol) name = name.name;
12715 return this.variables.get(name)
12716 || (this.parent_scope && this.parent_scope.find_variable(name));
12717});
12718
12719AST_Scope.DEFMETHOD("def_function", function(symbol, init) {
12720 var def = this.def_variable(symbol, init);
12721 if (!def.init || def.init instanceof AST_Defun) def.init = init;
12722 return def;
12723});
12724
12725AST_Scope.DEFMETHOD("def_variable", function(symbol, init) {
12726 var def = this.variables.get(symbol.name);
12727 if (def) {
12728 def.orig.push(symbol);
12729 if (def.init && (def.scope !== symbol.scope || def.init instanceof AST_Function)) {
12730 def.init = init;
12731 }
12732 } else {
12733 def = new SymbolDef(this, symbol, init);
12734 this.variables.set(symbol.name, def);
12735 def.global = !this.parent_scope;
12736 }
12737 return symbol.thedef = def;
12738});
12739
12740function next_mangled(scope, options) {
12741 let defun_scope;
12742 if (
12743 scopes_with_block_defuns
12744 && (defun_scope = scope.get_defun_scope())
12745 && scopes_with_block_defuns.has(defun_scope)
12746 ) {
12747 scope = defun_scope;
12748 }
12749
12750 var ext = scope.enclosed;
12751 var nth_identifier = options.nth_identifier;
12752 out: while (true) {
12753 var m = nth_identifier.get(++scope.cname);
12754 if (ALL_RESERVED_WORDS.has(m)) continue; // skip over "do"
12755
12756 // https://github.com/mishoo/UglifyJS2/issues/242 -- do not
12757 // shadow a name reserved from mangling.
12758 if (options.reserved.has(m)) continue;
12759
12760 // Functions with short names might collide with base54 output
12761 // and therefore cause collisions when keep_fnames is true.
12762 if (unmangleable_names && unmangleable_names.has(m)) continue out;
12763
12764 // we must ensure that the mangled name does not shadow a name
12765 // from some parent scope that is referenced in this or in
12766 // inner scopes.
12767 for (let i = ext.length; --i >= 0;) {
12768 const def = ext[i];
12769 const name = def.mangled_name || (def.unmangleable(options) && def.name);
12770 if (m == name) continue out;
12771 }
12772 return m;
12773 }
12774}
12775
12776AST_Scope.DEFMETHOD("next_mangled", function(options) {
12777 return next_mangled(this, options);
12778});
12779
12780AST_Toplevel.DEFMETHOD("next_mangled", function(options) {
12781 let name;
12782 const mangled_names = this.mangled_names;
12783 do {
12784 name = next_mangled(this, options);
12785 } while (mangled_names.has(name));
12786 return name;
12787});
12788
12789AST_Function.DEFMETHOD("next_mangled", function(options, def) {
12790 // #179, #326
12791 // in Safari strict mode, something like (function x(x){...}) is a syntax error;
12792 // a function expression's argument cannot shadow the function expression's name
12793
12794 var tricky_def = def.orig[0] instanceof AST_SymbolFunarg && this.name && this.name.definition();
12795
12796 // the function's mangled_name is null when keep_fnames is true
12797 var tricky_name = tricky_def ? tricky_def.mangled_name || tricky_def.name : null;
12798
12799 while (true) {
12800 var name = next_mangled(this, options);
12801 if (!tricky_name || tricky_name != name)
12802 return name;
12803 }
12804});
12805
12806AST_Symbol.DEFMETHOD("unmangleable", function(options) {
12807 var def = this.definition();
12808 return !def || def.unmangleable(options);
12809});
12810
12811// labels are always mangleable
12812AST_Label.DEFMETHOD("unmangleable", return_false);
12813
12814AST_Symbol.DEFMETHOD("unreferenced", function() {
12815 return !this.definition().references.length && !this.scope.pinned();
12816});
12817
12818AST_Symbol.DEFMETHOD("definition", function() {
12819 return this.thedef;
12820});
12821
12822AST_Symbol.DEFMETHOD("global", function() {
12823 return this.thedef.global;
12824});
12825
12826/**
12827 * Format the mangler options (if any) into their appropriate types
12828 */
12829function format_mangler_options(options) {
12830 options = defaults(options, {
12831 eval : false,
12832 nth_identifier : base54,
12833 ie8 : false,
12834 keep_classnames: false,
12835 keep_fnames : false,
12836 module : false,
12837 reserved : [],
12838 toplevel : false,
12839 });
12840 if (options.module) options.toplevel = true;
12841 if (!Array.isArray(options.reserved)
12842 && !(options.reserved instanceof Set)
12843 ) {
12844 options.reserved = [];
12845 }
12846 options.reserved = new Set(options.reserved);
12847 // Never mangle arguments
12848 options.reserved.add("arguments");
12849 return options;
12850}
12851
12852AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
12853 options = format_mangler_options(options);
12854 var nth_identifier = options.nth_identifier;
12855
12856 // We only need to mangle declaration nodes. Special logic wired
12857 // into the code generator will display the mangled name if it's
12858 // present (and for AST_SymbolRef-s it'll use the mangled name of
12859 // the AST_SymbolDeclaration that it points to).
12860 var lname = -1;
12861 var to_mangle = [];
12862
12863 if (options.keep_fnames) {
12864 function_defs = new Set();
12865 }
12866
12867 const mangled_names = this.mangled_names = new Set();
12868 unmangleable_names = new Set();
12869
12870 if (options.cache) {
12871 this.globals.forEach(collect);
12872 if (options.cache.props) {
12873 options.cache.props.forEach(function(mangled_name) {
12874 mangled_names.add(mangled_name);
12875 });
12876 }
12877 }
12878
12879 var tw = new TreeWalker(function(node, descend) {
12880 if (node instanceof AST_LabeledStatement) {
12881 // lname is incremented when we get to the AST_Label
12882 var save_nesting = lname;
12883 descend();
12884 lname = save_nesting;
12885 return true; // don't descend again in TreeWalker
12886 }
12887 if (
12888 node instanceof AST_Defun
12889 && !(tw.parent() instanceof AST_Scope)
12890 ) {
12891 scopes_with_block_defuns = scopes_with_block_defuns || new Set();
12892 scopes_with_block_defuns.add(node.parent_scope.get_defun_scope());
12893 }
12894 if (node instanceof AST_Scope) {
12895 node.variables.forEach(collect);
12896 return;
12897 }
12898 if (node.is_block_scope()) {
12899 node.block_scope.variables.forEach(collect);
12900 return;
12901 }
12902 if (
12903 function_defs
12904 && node instanceof AST_VarDef
12905 && node.name instanceof AST_Symbol
12906 && node.value instanceof AST_Lambda
12907 && !node.value.name
12908 && keep_name(options.keep_fnames, node.name.name)
12909 ) {
12910 function_defs.add(node.name.definition().id);
12911 return;
12912 }
12913 if (node instanceof AST_Label) {
12914 let name;
12915 do {
12916 name = nth_identifier.get(++lname);
12917 } while (ALL_RESERVED_WORDS.has(name));
12918 node.mangled_name = name;
12919 return true;
12920 }
12921 if (!(options.ie8 || options.safari10) && node instanceof AST_SymbolCatch) {
12922 to_mangle.push(node.definition());
12923 return;
12924 }
12925 });
12926
12927 this.walk(tw);
12928
12929 if (options.keep_fnames || options.keep_classnames) {
12930 // Collect a set of short names which are unmangleable,
12931 // for use in avoiding collisions in next_mangled.
12932 to_mangle.forEach(def => {
12933 if (def.name.length < 6 && def.unmangleable(options)) {
12934 unmangleable_names.add(def.name);
12935 }
12936 });
12937 }
12938
12939 to_mangle.forEach(def => { def.mangle(options); });
12940
12941 function_defs = null;
12942 unmangleable_names = null;
12943 scopes_with_block_defuns = null;
12944
12945 function collect(symbol) {
12946 if (symbol.export & MASK_EXPORT_DONT_MANGLE) {
12947 unmangleable_names.add(symbol.name);
12948 } else if (!options.reserved.has(symbol.name)) {
12949 to_mangle.push(symbol);
12950 }
12951 }
12952});
12953
12954AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
12955 const cache = options.cache && options.cache.props;
12956 const avoid = new Set();
12957 options.reserved.forEach(to_avoid);
12958 this.globals.forEach(add_def);
12959 this.walk(new TreeWalker(function(node) {
12960 if (node instanceof AST_Scope) node.variables.forEach(add_def);
12961 if (node instanceof AST_SymbolCatch) add_def(node.definition());
12962 }));
12963 return avoid;
12964
12965 function to_avoid(name) {
12966 avoid.add(name);
12967 }
12968
12969 function add_def(def) {
12970 var name = def.name;
12971 if (def.global && cache && cache.has(name)) name = cache.get(name);
12972 else if (!def.unmangleable(options)) return;
12973 to_avoid(name);
12974 }
12975});
12976
12977AST_Toplevel.DEFMETHOD("expand_names", function(options) {
12978 options = format_mangler_options(options);
12979 var nth_identifier = options.nth_identifier;
12980 if (nth_identifier.reset && nth_identifier.sort) {
12981 nth_identifier.reset();
12982 nth_identifier.sort();
12983 }
12984 var avoid = this.find_colliding_names(options);
12985 var cname = 0;
12986 this.globals.forEach(rename);
12987 this.walk(new TreeWalker(function(node) {
12988 if (node instanceof AST_Scope) node.variables.forEach(rename);
12989 if (node instanceof AST_SymbolCatch) rename(node.definition());
12990 }));
12991
12992 function next_name() {
12993 var name;
12994 do {
12995 name = nth_identifier.get(cname++);
12996 } while (avoid.has(name) || ALL_RESERVED_WORDS.has(name));
12997 return name;
12998 }
12999
13000 function rename(def) {
13001 if (def.global && options.cache) return;
13002 if (def.unmangleable(options)) return;
13003 if (options.reserved.has(def.name)) return;
13004 const redefinition = redefined_catch_def(def);
13005 const name = def.name = redefinition ? redefinition.name : next_name();
13006 def.orig.forEach(function(sym) {
13007 sym.name = name;
13008 });
13009 def.references.forEach(function(sym) {
13010 sym.name = name;
13011 });
13012 }
13013});
13014
13015AST_Node.DEFMETHOD("tail_node", return_this);
13016AST_Sequence.DEFMETHOD("tail_node", function() {
13017 return this.expressions[this.expressions.length - 1];
13018});
13019
13020AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options) {
13021 options = format_mangler_options(options);
13022 var nth_identifier = options.nth_identifier;
13023 if (!nth_identifier.reset || !nth_identifier.consider || !nth_identifier.sort) {
13024 // If the identifier mangler is invariant, skip computing character frequency.
13025 return;
13026 }
13027 nth_identifier.reset();
13028
13029 try {
13030 AST_Node.prototype.print = function(stream, force_parens) {
13031 this._print(stream, force_parens);
13032 if (this instanceof AST_Symbol && !this.unmangleable(options)) {
13033 nth_identifier.consider(this.name, -1);
13034 } else if (options.properties) {
13035 if (this instanceof AST_DotHash) {
13036 nth_identifier.consider("#" + this.property, -1);
13037 } else if (this instanceof AST_Dot) {
13038 nth_identifier.consider(this.property, -1);
13039 } else if (this instanceof AST_Sub) {
13040 skip_string(this.property);
13041 }
13042 }
13043 };
13044 nth_identifier.consider(this.print_to_string(), 1);
13045 } finally {
13046 AST_Node.prototype.print = AST_Node.prototype._print;
13047 }
13048 nth_identifier.sort();
13049
13050 function skip_string(node) {
13051 if (node instanceof AST_String) {
13052 nth_identifier.consider(node.value, -1);
13053 } else if (node instanceof AST_Conditional) {
13054 skip_string(node.consequent);
13055 skip_string(node.alternative);
13056 } else if (node instanceof AST_Sequence) {
13057 skip_string(node.tail_node());
13058 }
13059 }
13060});
13061
13062const base54 = (() => {
13063 const leading = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_".split("");
13064 const digits = "0123456789".split("");
13065 let chars;
13066 let frequency;
13067 function reset() {
13068 frequency = new Map();
13069 leading.forEach(function(ch) {
13070 frequency.set(ch, 0);
13071 });
13072 digits.forEach(function(ch) {
13073 frequency.set(ch, 0);
13074 });
13075 }
13076 function consider(str, delta) {
13077 for (var i = str.length; --i >= 0;) {
13078 frequency.set(str[i], frequency.get(str[i]) + delta);
13079 }
13080 }
13081 function compare(a, b) {
13082 return frequency.get(b) - frequency.get(a);
13083 }
13084 function sort() {
13085 chars = mergeSort(leading, compare).concat(mergeSort(digits, compare));
13086 }
13087 // Ensure this is in a usable initial state.
13088 reset();
13089 sort();
13090 function base54(num) {
13091 var ret = "", base = 54;
13092 num++;
13093 do {
13094 num--;
13095 ret += chars[num % base];
13096 num = Math.floor(num / base);
13097 base = 64;
13098 } while (num > 0);
13099 return ret;
13100 }
13101
13102 return {
13103 get: base54,
13104 consider,
13105 reset,
13106 sort
13107 };
13108})();
13109
13110let mangle_options = undefined;
13111AST_Node.prototype.size = function (compressor, stack) {
13112 mangle_options = compressor && compressor._mangle_options;
13113
13114 let size = 0;
13115 walk_parent(this, (node, info) => {
13116 size += node._size(info);
13117
13118 // Braceless arrow functions have fake "return" statements
13119 if (node instanceof AST_Arrow && node.is_braceless()) {
13120 size += node.body[0].value._size(info);
13121 return true;
13122 }
13123 }, stack || (compressor && compressor.stack));
13124
13125 // just to save a bit of memory
13126 mangle_options = undefined;
13127
13128 return size;
13129};
13130
13131AST_Node.prototype._size = () => 0;
13132
13133AST_Debugger.prototype._size = () => 8;
13134
13135AST_Directive.prototype._size = function () {
13136 // TODO string encoding stuff
13137 return 2 + this.value.length;
13138};
13139
13140/** Count commas/semicolons necessary to show a list of expressions/statements */
13141const list_overhead = (array) => array.length && array.length - 1;
13142
13143AST_Block.prototype._size = function () {
13144 return 2 + list_overhead(this.body);
13145};
13146
13147AST_Toplevel.prototype._size = function() {
13148 return list_overhead(this.body);
13149};
13150
13151AST_EmptyStatement.prototype._size = () => 1;
13152
13153AST_LabeledStatement.prototype._size = () => 2; // x:
13154
13155AST_Do.prototype._size = () => 9;
13156
13157AST_While.prototype._size = () => 7;
13158
13159AST_For.prototype._size = () => 8;
13160
13161AST_ForIn.prototype._size = () => 8;
13162// AST_ForOf inherits ^
13163
13164AST_With.prototype._size = () => 6;
13165
13166AST_Expansion.prototype._size = () => 3;
13167
13168const lambda_modifiers = func =>
13169 (func.is_generator ? 1 : 0) + (func.async ? 6 : 0);
13170
13171AST_Accessor.prototype._size = function () {
13172 return lambda_modifiers(this) + 4 + list_overhead(this.argnames) + list_overhead(this.body);
13173};
13174
13175AST_Function.prototype._size = function (info) {
13176 const first = !!first_in_statement(info);
13177 return (first * 2) + lambda_modifiers(this) + 12 + list_overhead(this.argnames) + list_overhead(this.body);
13178};
13179
13180AST_Defun.prototype._size = function () {
13181 return lambda_modifiers(this) + 13 + list_overhead(this.argnames) + list_overhead(this.body);
13182};
13183
13184AST_Arrow.prototype._size = function () {
13185 let args_and_arrow = 2 + list_overhead(this.argnames);
13186
13187 if (
13188 !(
13189 this.argnames.length === 1
13190 && this.argnames[0] instanceof AST_Symbol
13191 )
13192 ) {
13193 args_and_arrow += 2; // parens around the args
13194 }
13195
13196 const body_overhead = this.is_braceless() ? 0 : list_overhead(this.body) + 2;
13197
13198 return lambda_modifiers(this) + args_and_arrow + body_overhead;
13199};
13200
13201AST_Destructuring.prototype._size = () => 2;
13202
13203AST_TemplateString.prototype._size = function () {
13204 return 2 + (Math.floor(this.segments.length / 2) * 3); /* "${}" */
13205};
13206
13207AST_TemplateSegment.prototype._size = function () {
13208 return this.value.length;
13209};
13210
13211AST_Return.prototype._size = function () {
13212 return this.value ? 7 : 6;
13213};
13214
13215AST_Throw.prototype._size = () => 6;
13216
13217AST_Break.prototype._size = function () {
13218 return this.label ? 6 : 5;
13219};
13220
13221AST_Continue.prototype._size = function () {
13222 return this.label ? 9 : 8;
13223};
13224
13225AST_If.prototype._size = () => 4;
13226
13227AST_Switch.prototype._size = function () {
13228 return 8 + list_overhead(this.body);
13229};
13230
13231AST_Case.prototype._size = function () {
13232 return 5 + list_overhead(this.body);
13233};
13234
13235AST_Default.prototype._size = function () {
13236 return 8 + list_overhead(this.body);
13237};
13238
13239AST_Try.prototype._size = () => 3;
13240
13241AST_Catch.prototype._size = function () {
13242 let size = 7 + list_overhead(this.body);
13243 if (this.argname) {
13244 size += 2;
13245 }
13246 return size;
13247};
13248
13249AST_Finally.prototype._size = function () {
13250 return 7 + list_overhead(this.body);
13251};
13252
13253AST_Var.prototype._size = function () {
13254 return 4 + list_overhead(this.definitions);
13255};
13256
13257AST_Let.prototype._size = function () {
13258 return 4 + list_overhead(this.definitions);
13259};
13260
13261AST_Const.prototype._size = function () {
13262 return 6 + list_overhead(this.definitions);
13263};
13264
13265AST_Using.prototype._size = function () {
13266 const await_size = this.await ? 6 : 0;
13267 return await_size + 6 + list_overhead(this.definitions);
13268};
13269
13270AST_VarDefLike.prototype._size = function () {
13271 return this.value ? 1 : 0;
13272};
13273
13274AST_NameMapping.prototype._size = function () {
13275 // foreign name isn't mangled
13276 return this.name ? 4 : 0;
13277};
13278
13279AST_Import.prototype._size = function () {
13280 // import
13281 let size = 6;
13282
13283 if (this.imported_name) size += 1;
13284
13285 // from
13286 if (this.imported_name || this.imported_names) size += 5;
13287
13288 // braces, and the commas
13289 if (this.imported_names) {
13290 size += 2 + list_overhead(this.imported_names);
13291 }
13292
13293 return size;
13294};
13295
13296AST_ImportMeta.prototype._size = () => 11;
13297
13298AST_DynamicImport.prototype._size = function () {
13299 // `import.` + phase + `()` + arg overhead
13300 return 9 + this.phase.length + list_overhead(this.args);
13301};
13302
13303AST_Export.prototype._size = function () {
13304 let size = 7 + (this.is_default ? 8 : 0);
13305
13306 if (this.exported_value) {
13307 size += this.exported_value._size();
13308 }
13309
13310 if (this.exported_names) {
13311 // Braces and commas
13312 size += 2 + list_overhead(this.exported_names);
13313 }
13314
13315 if (this.module_name) {
13316 // "from "
13317 size += 5;
13318 }
13319
13320 return size;
13321};
13322
13323AST_Call.prototype._size = function () {
13324 if (this.optional) {
13325 return 4 + list_overhead(this.args);
13326 }
13327 return 2 + list_overhead(this.args);
13328};
13329
13330AST_New.prototype._size = function () {
13331 return 6 + list_overhead(this.args);
13332};
13333
13334AST_Sequence.prototype._size = function () {
13335 return list_overhead(this.expressions);
13336};
13337
13338AST_Dot.prototype._size = function () {
13339 if (this.optional) {
13340 return this.property.length + 2;
13341 }
13342 return this.property.length + 1;
13343};
13344
13345AST_DotHash.prototype._size = function () {
13346 if (this.optional) {
13347 return this.property.length + 3;
13348 }
13349 return this.property.length + 2;
13350};
13351
13352AST_Sub.prototype._size = function () {
13353 return this.optional ? 4 : 2;
13354};
13355
13356AST_Unary.prototype._size = function () {
13357 if (this.operator === "typeof") return 7;
13358 if (this.operator === "void") return 5;
13359 return this.operator.length;
13360};
13361
13362AST_Binary.prototype._size = function (info) {
13363 if (this.operator === "in") return 4;
13364
13365 let size = this.operator.length;
13366
13367 if (
13368 (this.operator === "+" || this.operator === "-")
13369 && this.right instanceof AST_Unary && this.right.operator === this.operator
13370 ) {
13371 // 1+ +a > needs space between the +
13372 size += 1;
13373 }
13374
13375 if (this.needs_parens(info)) {
13376 size += 2;
13377 }
13378
13379 return size;
13380};
13381
13382AST_Conditional.prototype._size = () => 3;
13383
13384AST_Array.prototype._size = function () {
13385 return 2 + list_overhead(this.elements);
13386};
13387
13388AST_Object.prototype._size = function (info) {
13389 let base = 2;
13390 if (first_in_statement(info)) {
13391 base += 2; // parens
13392 }
13393 return base + list_overhead(this.properties);
13394};
13395
13396/*#__INLINE__*/
13397const key_size = key =>
13398 typeof key === "string" ? key.length : 0;
13399
13400AST_ObjectKeyVal.prototype._size = function () {
13401 return key_size(this.key) + 1;
13402};
13403
13404/*#__INLINE__*/
13405const static_size = is_static => is_static ? 7 : 0;
13406
13407AST_ObjectGetter.prototype._size = function () {
13408 return 5 + static_size(this.static) + key_size(this.key);
13409};
13410
13411AST_ObjectSetter.prototype._size = function () {
13412 return 5 + static_size(this.static) + key_size(this.key);
13413};
13414
13415AST_ConciseMethod.prototype._size = function () {
13416 return static_size(this.static) + key_size(this.key);
13417};
13418
13419AST_PrivateMethod.prototype._size = function () {
13420 return AST_ConciseMethod.prototype._size.call(this) + 1;
13421};
13422
13423AST_PrivateGetter.prototype._size = function () {
13424 return AST_ConciseMethod.prototype._size.call(this) + 4;
13425};
13426
13427AST_PrivateSetter.prototype._size = function () {
13428 return AST_ConciseMethod.prototype._size.call(this) + 4;
13429};
13430
13431AST_PrivateIn.prototype._size = function () {
13432 return 5; // "#", and " in "
13433};
13434
13435AST_Class.prototype._size = function () {
13436 return (
13437 (this.name ? 8 : 7)
13438 + (this.extends ? 8 : 0)
13439 );
13440};
13441
13442AST_ClassStaticBlock.prototype._size = function () {
13443 // "static{}" + semicolons
13444 return 8 + list_overhead(this.body);
13445};
13446
13447AST_ClassProperty.prototype._size = function () {
13448 return (
13449 static_size(this.static)
13450 + (typeof this.key === "string" ? this.key.length + 2 : 0)
13451 + (this.value ? 1 : 0)
13452 );
13453};
13454
13455AST_ClassPrivateProperty.prototype._size = function () {
13456 return AST_ClassProperty.prototype._size.call(this) + 1;
13457};
13458
13459AST_Symbol.prototype._size = function () {
13460 if (!(mangle_options && this.thedef && !this.thedef.unmangleable(mangle_options))) {
13461 return this.name.length;
13462 } else {
13463 return 1;
13464 }
13465};
13466
13467// TODO take propmangle into account
13468AST_SymbolClassProperty.prototype._size = function () {
13469 return this.name.length;
13470};
13471
13472AST_SymbolRef.prototype._size = AST_SymbolDeclaration.prototype._size = function () {
13473 if (this.name === "arguments") return 9;
13474
13475 return AST_Symbol.prototype._size.call(this);
13476};
13477
13478AST_NewTarget.prototype._size = () => 10;
13479
13480AST_SymbolImportForeign.prototype._size = function () {
13481 return this.name.length;
13482};
13483
13484AST_SymbolExportForeign.prototype._size = function () {
13485 return this.name.length;
13486};
13487
13488AST_This.prototype._size = () => 4;
13489
13490AST_Super.prototype._size = () => 5;
13491
13492AST_String.prototype._size = function () {
13493 return this.value.length + 2;
13494};
13495
13496AST_Number.prototype._size = function () {
13497 const { value } = this;
13498 if (value === 0) return 1;
13499 if (value > 0 && Math.floor(value) === value) {
13500 return Math.floor(Math.log10(value) + 1);
13501 }
13502 return value.toString().length;
13503};
13504
13505AST_BigInt.prototype._size = function () {
13506 return this.value.length;
13507};
13508
13509AST_RegExp.prototype._size = function () {
13510 return this.value.toString().length;
13511};
13512
13513AST_Null.prototype._size = () => 4;
13514
13515AST_NaN.prototype._size = () => 3;
13516
13517AST_Undefined.prototype._size = () => 6; // "void 0"
13518
13519AST_Hole.prototype._size = () => 0; // comma is taken into account by list_overhead()
13520
13521AST_Infinity.prototype._size = () => 8;
13522
13523AST_True.prototype._size = () => 4;
13524
13525AST_False.prototype._size = () => 5;
13526
13527AST_Await.prototype._size = () => 6;
13528
13529AST_Yield.prototype._size = () => 6;
13530
13531/***********************************************************************
13532
13533 A JavaScript tokenizer / parser / beautifier / compressor.
13534 https://github.com/mishoo/UglifyJS2
13535
13536 -------------------------------- (C) ---------------------------------
13537
13538 Author: Mihai Bazon
13539 <mihai.bazon@gmail.com>
13540 http://mihai.bazon.net/blog
13541
13542 Distributed under the BSD license:
13543
13544 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
13545
13546 Redistribution and use in source and binary forms, with or without
13547 modification, are permitted provided that the following conditions
13548 are met:
13549
13550 * Redistributions of source code must retain the above
13551 copyright notice, this list of conditions and the following
13552 disclaimer.
13553
13554 * Redistributions in binary form must reproduce the above
13555 copyright notice, this list of conditions and the following
13556 disclaimer in the documentation and/or other materials
13557 provided with the distribution.
13558
13559 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
13560 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
13561 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
13562 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
13563 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
13564 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
13565 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
13566 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13567 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
13568 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
13569 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
13570 SUCH DAMAGE.
13571
13572 ***********************************************************************/
13573
13574// bitfield flags to be stored in node.flags.
13575// These are set and unset during compression, and store information in the node without requiring multiple fields.
13576const UNUSED = 0b00000001;
13577const TRUTHY = 0b00000010;
13578const FALSY = 0b00000100;
13579const UNDEFINED = 0b00001000;
13580const INLINED = 0b00010000;
13581// Nodes to which values are ever written. Used when keep_assign is part of the unused option string.
13582const WRITE_ONLY = 0b00100000;
13583
13584// information specific to a single compression pass
13585const SQUEEZED = 0b0000000100000000;
13586const OPTIMIZED = 0b0000001000000000;
13587const TOP = 0b0000010000000000;
13588const CLEAR_BETWEEN_PASSES = SQUEEZED | OPTIMIZED | TOP;
13589
13590const has_flag = (node, flag) => node.flags & flag;
13591const set_flag = (node, flag) => { node.flags |= flag; };
13592const clear_flag = (node, flag) => { node.flags &= ~flag; };
13593
13594/***********************************************************************
13595
13596 A JavaScript tokenizer / parser / beautifier / compressor.
13597 https://github.com/mishoo/UglifyJS2
13598
13599 -------------------------------- (C) ---------------------------------
13600
13601 Author: Mihai Bazon
13602 <mihai.bazon@gmail.com>
13603 http://mihai.bazon.net/blog
13604
13605 Distributed under the BSD license:
13606
13607 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
13608
13609 Redistribution and use in source and binary forms, with or without
13610 modification, are permitted provided that the following conditions
13611 are met:
13612
13613 * Redistributions of source code must retain the above
13614 copyright notice, this list of conditions and the following
13615 disclaimer.
13616
13617 * Redistributions in binary form must reproduce the above
13618 copyright notice, this list of conditions and the following
13619 disclaimer in the documentation and/or other materials
13620 provided with the distribution.
13621
13622 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
13623 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
13624 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
13625 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
13626 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
13627 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
13628 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
13629 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13630 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
13631 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
13632 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
13633 SUCH DAMAGE.
13634
13635 ***********************************************************************/
13636
13637function merge_sequence(array, node) {
13638 if (node instanceof AST_Sequence) {
13639 array.push(...node.expressions);
13640 } else {
13641 array.push(node);
13642 }
13643 return array;
13644}
13645
13646function make_sequence(orig, expressions) {
13647 if (expressions.length == 1) return expressions[0];
13648 if (expressions.length == 0) throw new Error("trying to create a sequence with length zero!");
13649 return make_node(AST_Sequence, orig, {
13650 expressions: expressions.reduce(merge_sequence, [])
13651 });
13652}
13653
13654function make_empty_function(self) {
13655 return make_node(AST_Function, self, {
13656 uses_arguments: false,
13657 argnames: [],
13658 body: [],
13659 is_generator: false,
13660 async: false,
13661 variables: new Map(),
13662 uses_with: false,
13663 uses_eval: false,
13664 parent_scope: null,
13665 enclosed: [],
13666 cname: 0,
13667 block_scope: undefined,
13668 });
13669}
13670
13671function make_node_from_constant(val, orig) {
13672 switch (typeof val) {
13673 case "string":
13674 return make_node(AST_String, orig, {
13675 value: val
13676 });
13677 case "number":
13678 if (isNaN(val)) return make_node(AST_NaN, orig);
13679 if (isFinite(val)) {
13680 return 1 / val < 0 ? make_node(AST_UnaryPrefix, orig, {
13681 operator: "-",
13682 expression: make_node(AST_Number, orig, { value: -val })
13683 }) : make_node(AST_Number, orig, { value: val });
13684 }
13685 return val < 0 ? make_node(AST_UnaryPrefix, orig, {
13686 operator: "-",
13687 expression: make_node(AST_Infinity, orig)
13688 }) : make_node(AST_Infinity, orig);
13689 case "bigint":
13690 return make_node(AST_BigInt, orig, { value: val.toString() });
13691 case "boolean":
13692 return make_node(val ? AST_True : AST_False, orig);
13693 case "undefined":
13694 return make_void_0(orig);
13695 default:
13696 if (val === null) {
13697 return make_node(AST_Null, orig, { value: null });
13698 }
13699 if (val instanceof RegExp) {
13700 return make_node(AST_RegExp, orig, {
13701 value: {
13702 source: regexp_source_fix(val.source),
13703 flags: val.flags
13704 }
13705 });
13706 }
13707 throw new Error(string_template("Can't handle constant of type: {type}", {
13708 type: typeof val
13709 }));
13710 }
13711}
13712
13713function best_of_expression(ast1, ast2) {
13714 return ast1.size() > ast2.size() ? ast2 : ast1;
13715}
13716
13717function best_of_statement(ast1, ast2) {
13718 return best_of_expression(
13719 make_node(AST_SimpleStatement, ast1, {
13720 body: ast1
13721 }),
13722 make_node(AST_SimpleStatement, ast2, {
13723 body: ast2
13724 })
13725 ).body;
13726}
13727
13728/** Find which node is smaller, and return that */
13729function best_of(compressor, ast1, ast2) {
13730 if (first_in_statement(compressor)) {
13731 return best_of_statement(ast1, ast2);
13732 } else {
13733 return best_of_expression(ast1, ast2);
13734 }
13735}
13736
13737/** Simplify an object property's key, if possible */
13738function get_simple_key(key) {
13739 if (key instanceof AST_Constant) {
13740 return key.getValue();
13741 }
13742 if (key instanceof AST_UnaryPrefix
13743 && key.operator == "void"
13744 && key.expression instanceof AST_Constant) {
13745 return undefined;
13746 }
13747 return key;
13748}
13749
13750function read_property(obj, key) {
13751 key = get_simple_key(key);
13752 if (key instanceof AST_Node) return;
13753
13754 var value;
13755 if (obj instanceof AST_Array) {
13756 var elements = obj.elements;
13757 if (key == "length") return make_node_from_constant(elements.length, obj);
13758 if (typeof key == "number" && key in elements) value = elements[key];
13759 } else if (obj instanceof AST_Object) {
13760 key = "" + key;
13761 var props = obj.properties;
13762 for (var i = props.length; --i >= 0;) {
13763 var prop = props[i];
13764 if (!(prop instanceof AST_ObjectKeyVal)) return;
13765 if (!value && props[i].key === key) value = props[i].value;
13766 }
13767 }
13768
13769 return value instanceof AST_SymbolRef && value.fixed_value() || value;
13770}
13771
13772function has_break_or_continue(loop, parent) {
13773 var found = false;
13774 var tw = new TreeWalker(function(node) {
13775 if (found || node instanceof AST_Scope) return true;
13776 if (node instanceof AST_LoopControl && tw.loopcontrol_target(node) === loop) {
13777 return found = true;
13778 }
13779 });
13780 if (parent instanceof AST_LabeledStatement) tw.push(parent);
13781 tw.push(loop);
13782 loop.body.walk(tw);
13783 return found;
13784}
13785
13786// we shouldn't compress (1,func)(something) to
13787// func(something) because that changes the meaning of
13788// the func (becomes lexical instead of global).
13789function maintain_this_binding(parent, orig, val) {
13790 if (requires_sequence_to_maintain_binding(parent, orig, val)) {
13791 const zero = make_node(AST_Number, orig, { value: 0 });
13792 return make_sequence(orig, [ zero, val ]);
13793 } else {
13794 return val;
13795 }
13796}
13797
13798/** Detect (1, x.noThis)(), (0, eval)(), which need sequences */
13799function requires_sequence_to_maintain_binding(parent, orig, val) {
13800 return (
13801 parent instanceof AST_UnaryPrefix && parent.operator == "delete"
13802 || parent instanceof AST_Call && parent.expression === orig
13803 && (
13804 val instanceof AST_Chain
13805 || val instanceof AST_PropAccess
13806 || val instanceof AST_SymbolRef && val.name == "eval"
13807 )
13808 );
13809}
13810
13811function is_func_expr(node) {
13812 return node instanceof AST_Arrow || node instanceof AST_Function;
13813}
13814
13815/**
13816 * Used to determine whether the node can benefit from negation.
13817 * Not the case with arrow functions (you need an extra set of parens). */
13818function is_iife_call(node) {
13819 if (node.TYPE != "Call") return false;
13820 return node.expression instanceof AST_Function || is_iife_call(node.expression);
13821}
13822
13823function is_empty(thing) {
13824 if (thing === null) return true;
13825 if (thing instanceof AST_EmptyStatement) return true;
13826 if (thing instanceof AST_BlockStatement) return thing.body.length == 0;
13827 return false;
13828}
13829
13830const identifier_atom = makePredicate("Infinity NaN undefined");
13831function is_identifier_atom(node) {
13832 return node instanceof AST_Infinity
13833 || node instanceof AST_NaN
13834 || node instanceof AST_Undefined;
13835}
13836
13837/** Check if this is a SymbolRef node which has one def of a certain AST type */
13838function is_ref_of(ref, type) {
13839 if (!(ref instanceof AST_SymbolRef)) return false;
13840 var orig = ref.definition().orig;
13841 for (var i = orig.length; --i >= 0;) {
13842 if (orig[i] instanceof type) return true;
13843 }
13844}
13845
13846/**Can we turn { block contents... } into just the block contents ?
13847 * Not if one of these is inside.
13848 **/
13849function can_be_evicted_from_block(node) {
13850 return !(
13851 node instanceof AST_DefClass ||
13852 node instanceof AST_Defun ||
13853 node instanceof AST_Let ||
13854 node instanceof AST_Const ||
13855 node instanceof AST_Using ||
13856 node instanceof AST_Export ||
13857 node instanceof AST_Import
13858 );
13859}
13860
13861function as_statement_array(thing) {
13862 if (thing === null) return [];
13863 if (thing instanceof AST_BlockStatement) return thing.body;
13864 if (thing instanceof AST_EmptyStatement) return [];
13865 if (thing instanceof AST_Statement) return [ thing ];
13866 throw new Error("Can't convert thing to statement array");
13867}
13868
13869function is_reachable(scope_node, defs) {
13870 const find_ref = node => {
13871 if (node instanceof AST_SymbolRef && defs.includes(node.definition())) {
13872 return walk_abort;
13873 }
13874 };
13875
13876 return walk_parent(scope_node, (node, info) => {
13877 if (node instanceof AST_Scope && node !== scope_node) {
13878 var parent = info.parent();
13879
13880 if (
13881 parent instanceof AST_Call
13882 && parent.expression === node
13883 // Async/Generators aren't guaranteed to sync evaluate all of
13884 // their body steps, so it's possible they close over the variable.
13885 && !(node.async || node.is_generator)
13886 ) {
13887 return;
13888 }
13889
13890 if (walk(node, find_ref)) return walk_abort;
13891
13892 return true;
13893 }
13894 });
13895}
13896
13897/** Check if a ref refers to the name of a function/class it's defined within */
13898function is_recursive_ref(tw, def) {
13899 var node;
13900 for (var i = 0; node = tw.parent(i); i++) {
13901 if (node instanceof AST_Lambda || node instanceof AST_Class) {
13902 var name = node.name;
13903 if (name && name.definition() === def) {
13904 return true;
13905 }
13906 }
13907 }
13908 return false;
13909}
13910
13911// TODO this only works with AST_Defun, shouldn't it work for other ways of defining functions?
13912function retain_top_func(fn, compressor) {
13913 return compressor.top_retain
13914 && fn instanceof AST_Defun
13915 && has_flag(fn, TOP)
13916 && fn.name
13917 && compressor.top_retain(fn.name.definition());
13918}
13919
13920/***********************************************************************
13921
13922 A JavaScript tokenizer / parser / beautifier / compressor.
13923 https://github.com/mishoo/UglifyJS2
13924
13925 -------------------------------- (C) ---------------------------------
13926
13927 Author: Mihai Bazon
13928 <mihai.bazon@gmail.com>
13929 http://mihai.bazon.net/blog
13930
13931 Distributed under the BSD license:
13932
13933 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
13934
13935 Redistribution and use in source and binary forms, with or without
13936 modification, are permitted provided that the following conditions
13937 are met:
13938
13939 * Redistributions of source code must retain the above
13940 copyright notice, this list of conditions and the following
13941 disclaimer.
13942
13943 * Redistributions in binary form must reproduce the above
13944 copyright notice, this list of conditions and the following
13945 disclaimer in the documentation and/or other materials
13946 provided with the distribution.
13947
13948 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
13949 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
13950 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
13951 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
13952 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
13953 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
13954 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
13955 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13956 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
13957 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
13958 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
13959 SUCH DAMAGE.
13960
13961 ***********************************************************************/
13962
13963// Lists of native methods, useful for `unsafe` option which assumes they exist.
13964// Note: Lots of methods and functions are missing here, in case they aren't pure
13965// or not available in all JS environments.
13966
13967const make_nested_lookup = (feature_callback) => (compressor) => {
13968 const obj = feature_callback(feature_variables(compressor));
13969
13970 const out = new Map();
13971 for (var key of Object.keys(obj)) {
13972 if (obj[key]) {
13973 out.set(key, makePredicate(remove_false(obj[key])));
13974 }
13975 }
13976
13977 const does_have = (global_name, fname) => {
13978 const inner_map = out.get(global_name);
13979 return inner_map != null && inner_map.has(fname);
13980 };
13981 return does_have;
13982};
13983
13984const make_lookup = (feature_callback) => (compressor) => {
13985 const obj = feature_callback(feature_variables(compressor));
13986
13987 const predicate = makePredicate(remove_false(obj));
13988 const does_have = (global_name) => {
13989 return predicate.has(global_name);
13990 };
13991 return does_have;
13992};
13993
13994function remove_false(arr) {
13995 for (let i = 0; i < arr.length; i++) {
13996 if (arr[i] === false) {
13997 arr.splice(i, 1);
13998 i--;
13999 }
14000 }
14001 return arr;
14002}
14003
14004/** Generate the object with arguments seen below */
14005function feature_variables(compressor) {
14006 return {
14007 sloppy: compressor.option("unsafe"),
14008 es: compressor.option("builtins_ecma"),
14009 };
14010}
14011
14012// eslint-disable-next-line no-unused-vars
14013const pure_access_globals = make_lookup(({ sloppy, es }) => [
14014 "Array",
14015 "Boolean",
14016 "clearInterval",
14017 "clearTimeout",
14018 "console",
14019 "Date",
14020 "decodeURI",
14021 "decodeURIComponent",
14022 "encodeURI",
14023 "encodeURIComponent",
14024 "Error",
14025 "escape",
14026 "eval",
14027 "EvalError",
14028 "Function",
14029 es >= 2020 && "globalThis",
14030 "isFinite",
14031 "isNaN",
14032 "JSON",
14033 "Math",
14034 "Number",
14035 "parseFloat",
14036 "parseInt",
14037 "RangeError",
14038 "ReferenceError",
14039 "RegExp",
14040 "Object",
14041 "setInterval",
14042 "setTimeout",
14043 "String",
14044 "SyntaxError",
14045 "TypeError",
14046 "unescape",
14047 "URIError",
14048]);
14049
14050// Objects which are safe to access without throwing or causing a side effect.
14051// Usually we'd check the `unsafe` option first but these are way too common for that
14052const pure_prop_access_globals = new Set([
14053 "Number",
14054 "String",
14055 "Array",
14056 "Object",
14057 "Function",
14058 "Promise",
14059]);
14060
14061// eslint-disable-next-line no-unused-vars
14062const is_pure_native_fn = make_lookup(({ sloppy, es }) => [
14063 sloppy && es >= 2021 && "AggregateError",
14064 "Array",
14065 "ArrayBuffer",
14066 es >= 2020 && "BigInt",
14067 es >= 2020 && "BigInt64Array",
14068 es >= 2020 && "BigUint64Array",
14069 "Boolean",
14070 "Date",
14071 sloppy && "decodeURI",
14072 sloppy && "decodeURIComponent",
14073 sloppy && "encodeURI",
14074 sloppy && "encodeURIComponent",
14075 "Error",
14076 "escape",
14077 "EvalError",
14078 es >= 2021 && "FinalizationRegistry",
14079 es >= 2026 && "Float16Array",
14080 "Float32Array",
14081 "Float64Array",
14082 "Int16Array",
14083 "Int32Array",
14084 "Int8Array",
14085 "isFinite",
14086 "isNaN",
14087 es >= 2026 && "Iterator",
14088 es >= 2015 && "Map",
14089 "Number",
14090 "parseFloat",
14091 "parseInt",
14092 es >= 2015 && "Promise",
14093 es >= 2015 && "Proxy",
14094 "RangeError",
14095 "ReferenceError",
14096 sloppy && "RegExp",
14097 es >= 2015 && "Set",
14098 "String",
14099 es >= 2015 && "Symbol",
14100 "SyntaxError",
14101 "TypeError",
14102 "Uint16Array",
14103 "Uint32Array",
14104 "Uint8Array",
14105 "Uint8ClampedArray",
14106 sloppy && "unescape",
14107 "URIError",
14108 sloppy && es >= 2015 && "WeakMap",
14109 sloppy && es >= 2021 && "WeakRef",
14110 sloppy && es >= 2015 && "WeakSet",
14111]);
14112
14113const arg1_is_iterable = new Set([
14114 "Map",
14115 "Set",
14116 "WeakMap",
14117 "WeakSet",
14118]);
14119const arg1_is_range_or_iterable = new Set([
14120 "ArrayBuffer",
14121 "Float32Array",
14122 "Float64Array",
14123 "Int16Array",
14124 "Int32Array",
14125 "Int8Array",
14126 "Uint16Array",
14127 "Uint32Array",
14128 "Uint8Array",
14129 "Uint8ClampedArray",
14130]);
14131const lone_arg_is_range = new Set(["Array"]);
14132
14133const object_methods = [
14134 "constructor",
14135 "toString",
14136 "valueOf",
14137];
14138
14139// eslint-disable-next-line no-unused-vars
14140const is_pure_native_method = make_nested_lookup(({ sloppy, es }) => ({
14141 Array: [
14142 es >= 2022 && "at",
14143 es >= 2019 && "flat",
14144 es >= 2016 && "includes",
14145 "indexOf",
14146 "join",
14147 "lastIndexOf",
14148 "slice",
14149 ...object_methods,
14150 ],
14151 Boolean: object_methods,
14152 Function: object_methods,
14153 Number: [
14154 "toExponential",
14155 "toFixed",
14156 "toPrecision",
14157 ...object_methods,
14158 ],
14159 Object: object_methods,
14160 RegExp: [
14161 "test",
14162 ...object_methods,
14163 ],
14164 String: [
14165 es >= 2022 && "at",
14166 "charAt",
14167 "charCodeAt",
14168 es >= 2015 && "codePointAt",
14169 "concat",
14170 es >= 2025 && "endsWith",
14171 es >= 2015 && "includes",
14172 "indexOf",
14173 "italics",
14174 "lastIndexOf",
14175 es >= 2020 && "localeCompare",
14176 "match",
14177 es >= 2020 && "matchAll",
14178 es >= 2015 && "normalize",
14179 es >= 2017 && "padStart",
14180 es >= 2017 && "padEnd",
14181 es >= 2015 && sloppy && "repeat",
14182 "replace",
14183 es >= 2021 && "replaceAll",
14184 "search",
14185 "slice",
14186 "split",
14187 es >= 2015 && "startsWith",
14188 "substr",
14189 "substring",
14190 es >= 2015 && "repeat",
14191 "toLocaleLowerCase",
14192 "toLocaleUpperCase",
14193 "toLowerCase",
14194 "toUpperCase",
14195 "trim",
14196 es >= 2019 && "trimEnd",
14197 es >= 2019 && "trimStart",
14198 es >= 2019 && "trimLeft",
14199 es >= 2019 && "trimRight",
14200 ...object_methods,
14201 ],
14202}));
14203
14204// eslint-disable-next-line no-unused-vars
14205const is_pure_native_static_fn = make_nested_lookup(({ sloppy, es }) => ({
14206 Array: [
14207 "isArray",
14208 es >= 2015 && "of",
14209 ],
14210 ArrayBuffer: [
14211 "isView",
14212 ],
14213 BigInt: es >= 2020 && [
14214 sloppy && "asIntN",
14215 sloppy && "asUintN",
14216 ],
14217 BigInt64Array: sloppy && es >= 2020 && ["of"],
14218 BigUint64Array: sloppy && es >= 2020 && ["of"],
14219 Date: [
14220 "now",
14221 "parse",
14222 "UTC",
14223 ],
14224 Error: [
14225 es >= 2026 && "isError",
14226 ],
14227 Float16Array: sloppy && es >= 2026 && ["of"],
14228 Float32Array: sloppy && ["of"],
14229 Float64Array: sloppy && ["of"],
14230 Int16Array: sloppy && ["of"],
14231 Int32Array: sloppy && ["of"],
14232 Int8Array: sloppy && ["of"],
14233 Math: [
14234 "abs",
14235 "acos",
14236 es >= 2015 && "acosh",
14237 "asin",
14238 es >= 2015 && "asinh",
14239 "atan",
14240 "atan2",
14241 es >= 2015 && "atanh",
14242 es >= 2015 && "cbrt",
14243 "ceil",
14244 es >= 2015 && "clz32",
14245 "cos",
14246 es >= 2015 && "cosh",
14247 "exp",
14248 es >= 2015 && "expm1",
14249 "floor",
14250 es >= 2026 && "f16round",
14251 es >= 2015 && "fround",
14252 es >= 2015 && "hypot",
14253 es >= 2015 && "imul",
14254 "log",
14255 es >= 2015 && "log10",
14256 es >= 2015 && "log1p",
14257 es >= 2015 && "log2",
14258 "max",
14259 "min",
14260 "pow",
14261 "round",
14262 es >= 2015 && "sign",
14263 "sin",
14264 es >= 2015 && "sinh",
14265 "sqrt",
14266 "tan",
14267 es >= 2015 && "tanh",
14268 es >= 2015 && "trunc",
14269 ],
14270 Number: [
14271 es >= 2015 && "isFinite",
14272 es >= 2015 && "isInteger",
14273 es >= 2015 && "isSafeInteger",
14274 es >= 2015 && "isNaN",
14275 es >= 2015 && "parseFloat",
14276 es >= 2015 && "parseInt",
14277 ],
14278 Object: [
14279 sloppy && "create",
14280 sloppy && "getOwnPropertyDescriptor",
14281 es >= 2017 && sloppy && "getOwnPropertyDescriptors",
14282 sloppy && "getOwnPropertyNames",
14283 es >= 2015 && sloppy && "getOwnPropertySymbols",
14284 sloppy && "getPrototypeOf",
14285 es >= 2022 && sloppy && "hasOwn",
14286 es >= 2015 && "is",
14287 "isExtensible",
14288 "isFrozen",
14289 "isSealed",
14290 es >= 2015 && sloppy && "keys",
14291 ],
14292 Promise: es >= 2015 && [
14293 es >= 2024 && "withResolvers",
14294 ],
14295 Proxy: es >= 2015 && [
14296 sloppy && "revocable",
14297 ],
14298 Reflect: es >= 2015 && [
14299 sloppy && "has",
14300 sloppy && "isExtensible",
14301 sloppy && "ownKeys",
14302 ],
14303 RegExp: [
14304 es >= 2026 && sloppy && "escape",
14305 ],
14306 String: [
14307 "fromCharCode",
14308 sloppy && es >= 2025 && "fromCodePoint",
14309 ],
14310 Uint16Array: ["of"],
14311 Uint32Array: ["of"],
14312 Uint8Array: ["of"],
14313 Uint8ClampedArray: ["of"],
14314}));
14315
14316// Known numeric values which come with JS environments
14317// eslint-disable-next-line no-unused-vars
14318const is_pure_native_static_property = make_nested_lookup(({ sloppy, es }) => ({
14319 Math: [
14320 "E",
14321 "LN10",
14322 "LN2",
14323 "LOG2E",
14324 "LOG10E",
14325 "PI",
14326 "SQRT1_2",
14327 "SQRT2",
14328 ],
14329 Number: [
14330 es >= 2015 && "EPSILON",
14331 es >= 2015 && "MAX_SAFE_VALUE",
14332 "MAX_VALUE",
14333 es >= 2015 && "MIN_SAFE_VALUE",
14334 "MIN_VALUE",
14335 "NaN",
14336 "NEGATIVE_INFINITY",
14337 "POSITIVE_INFINITY",
14338 ],
14339 RegExp: [
14340 "$_",
14341 "$0",
14342 "$1",
14343 "$2",
14344 "$3",
14345 "$4",
14346 "$5",
14347 "$6",
14348 "$7",
14349 "$8",
14350 "$9",
14351 "input",
14352 "lastMatch",
14353 "lastParen",
14354 "leftContext",
14355 "rightContext",
14356 ],
14357}));
14358
14359const re_uppercase_first_letter = /^[A-Z]/;
14360function is_pure_builtin_call(compressor, call) {
14361 let builtin = "";
14362 let method = "";
14363
14364 let exp = call.expression;
14365 if (is_undeclared_ref(exp)) {
14366 builtin = exp.name;
14367 } else if (exp instanceof AST_Dot) {
14368 method = exp.property;
14369
14370 exp = exp.expression;
14371 if (is_undeclared_ref(exp)) {
14372 if (
14373 // globalThis.pureFunc()
14374 exp.name === "globalThis"
14375 && compressor.option("builtins_ecma") >= 2020
14376 ) {
14377 builtin = method;
14378 method = "";
14379 } else {
14380 // SomeBuiltin.pureFunc()
14381 builtin = exp.name;
14382 }
14383 } else if (exp instanceof AST_Dot) {
14384 if (
14385 is_undeclared_ref(exp.expression)
14386 && exp.expression.name === "globalThis"
14387 && compressor.option("builtins_ecma") >= 2020
14388 ) {
14389 // globalThis.SomeBuiltin.pureFunc()
14390 builtin = exp.property;
14391 } else {
14392 return false;
14393 }
14394 } else {
14395 return false;
14396 }
14397 } else {
14398 return false;
14399 }
14400
14401 if (!method) {
14402 if (compressor.is_pure_native_fn(builtin)) {
14403 // some require `new`, others throw if you use it
14404 const is_new = call instanceof AST_New;
14405 const should_be_new = re_uppercase_first_letter.test(builtin); // true of all `is_pure_native_fn`
14406 if (is_new !== should_be_new) return false;
14407
14408 if (!is_builtin_pure_with_these_args(builtin, call.args)) {
14409 return false;
14410 }
14411
14412 return true;
14413 }
14414
14415 return false;
14416 } else {
14417 return compressor.is_pure_native_static_fn(builtin, method);
14418 }
14419}
14420
14421/** Some builtins are listed above but their purity is subject to some conditions */
14422function is_builtin_pure_with_these_args(builtin, args) {
14423 // all the builtins we deal with here are ok with getting 0 args
14424 if (args.length === 0) return true;
14425
14426 let arg1 = args[0];
14427 if (arg1 instanceof AST_SymbolRef) {
14428 arg1 = arg1.fixed_value();
14429 }
14430
14431 if (lone_arg_is_range.has(builtin)) { // new Array(number)
14432 const arg_valid = args.length > 1
14433 || arg1 instanceof AST_Number
14434 && arg1.value >= 0 && arg1.value <= 0xffffffff;
14435 // TODO: or, we are asked to ignore TypeError
14436 if (!arg_valid) return false;
14437 }
14438
14439 if (arg1_is_range_or_iterable.has(builtin)) { // new Float32Array(number | Array)
14440 const arg_valid = args.length === 0
14441 || arg1 instanceof AST_Array
14442 || arg1 instanceof AST_Number
14443 && arg1.value >= 0 && arg1.value <= 0xffffffff;
14444 if (!arg_valid) return false;
14445 }
14446
14447 if (arg1_is_iterable.has(builtin)) { // new Set(iterable)
14448 const arg_valid = args.length === 0 || arg1 instanceof AST_Array;
14449 if (!arg_valid) return false;
14450 }
14451
14452 return true;
14453}
14454
14455/***********************************************************************
14456
14457 A JavaScript tokenizer / parser / beautifier / compressor.
14458 https://github.com/mishoo/UglifyJS2
14459
14460 -------------------------------- (C) ---------------------------------
14461
14462 Author: Mihai Bazon
14463 <mihai.bazon@gmail.com>
14464 http://mihai.bazon.net/blog
14465
14466 Distributed under the BSD license:
14467
14468 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
14469
14470 Redistribution and use in source and binary forms, with or without
14471 modification, are permitted provided that the following conditions
14472 are met:
14473
14474 * Redistributions of source code must retain the above
14475 copyright notice, this list of conditions and the following
14476 disclaimer.
14477
14478 * Redistributions in binary form must reproduce the above
14479 copyright notice, this list of conditions and the following
14480 disclaimer in the documentation and/or other materials
14481 provided with the distribution.
14482
14483 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
14484 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14485 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
14486 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
14487 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
14488 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
14489 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
14490 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
14491 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
14492 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
14493 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
14494 SUCH DAMAGE.
14495
14496 ***********************************************************************/
14497
14498// Functions and methods to infer certain facts about expressions
14499// It's not always possible to be 100% sure about something just by static analysis,
14500// so `true` means yes, and `false` means maybe
14501
14502const is_undeclared_ref = (node) =>
14503 node instanceof AST_SymbolRef && node.definition().undeclared;
14504
14505const bitwise_binop = makePredicate("<<< >> << & | ^ ~");
14506const lazy_op = makePredicate("&& || ??");
14507const unary_side_effects = makePredicate("delete ++ --");
14508
14509// methods to determine whether an expression has a boolean result type
14510(function(def_is_boolean) {
14511 const unary_bool = makePredicate("! delete");
14512 const binary_bool = makePredicate("in instanceof == != === !== < <= >= >");
14513 def_is_boolean(AST_Node, return_false);
14514 def_is_boolean(AST_UnaryPrefix, function() {
14515 return unary_bool.has(this.operator);
14516 });
14517 def_is_boolean(AST_Binary, function() {
14518 return binary_bool.has(this.operator)
14519 || lazy_op.has(this.operator)
14520 && this.left.is_boolean()
14521 && this.right.is_boolean();
14522 });
14523 def_is_boolean(AST_Conditional, function() {
14524 return this.consequent.is_boolean() && this.alternative.is_boolean();
14525 });
14526 def_is_boolean(AST_Assign, function() {
14527 return this.operator == "=" && this.right.is_boolean();
14528 });
14529 def_is_boolean(AST_Sequence, function() {
14530 return this.tail_node().is_boolean();
14531 });
14532 def_is_boolean(AST_True, return_true);
14533 def_is_boolean(AST_False, return_true);
14534})(function(node, func) {
14535 node.DEFMETHOD("is_boolean", func);
14536});
14537
14538// methods to determine if an expression has a numeric result type
14539(function(def_is_number) {
14540 def_is_number(AST_Node, return_false);
14541 def_is_number(AST_Number, return_true);
14542 const unary = makePredicate("+ - ~ ++ --");
14543 def_is_number(AST_Unary, function(compressor) {
14544 return unary.has(this.operator) && this.expression.is_number(compressor);
14545 });
14546 const numeric_ops = makePredicate("- * / % & | ^ << >> >>>");
14547 def_is_number(AST_Binary, function(compressor) {
14548 if (this.operator === "+") {
14549 // Both sides need to be `number`. Or one is a `number` and the other is number-ish.
14550 return this.left.is_number(compressor) && this.right.is_number_or_bigint(compressor)
14551 || this.right.is_number(compressor) && this.left.is_number_or_bigint(compressor);
14552 } else if (numeric_ops.has(this.operator)) {
14553 return this.left.is_number(compressor) || this.right.is_number(compressor);
14554 } else {
14555 return false;
14556 }
14557 });
14558 def_is_number(AST_Assign, function(compressor) {
14559 return (this.operator === "=" || numeric_ops.has(this.operator.slice(0, -1)))
14560 && this.right.is_number(compressor);
14561 });
14562 def_is_number(AST_Sequence, function(compressor) {
14563 return this.tail_node().is_number(compressor);
14564 });
14565 def_is_number(AST_Conditional, function(compressor) {
14566 return this.consequent.is_number(compressor) && this.alternative.is_number(compressor);
14567 });
14568})(function(node, func) {
14569 node.DEFMETHOD("is_number", func);
14570});
14571
14572// methods to determine if an expression returns a BigInt
14573(function(def_is_bigint) {
14574 def_is_bigint(AST_Node, return_false);
14575 def_is_bigint(AST_BigInt, return_true);
14576 const unary = makePredicate("+ - ~ ++ --");
14577 def_is_bigint(AST_Unary, function(compressor) {
14578 return unary.has(this.operator) && this.expression.is_bigint(compressor);
14579 });
14580 const numeric_ops = makePredicate("- * / % & | ^ << >>");
14581 def_is_bigint(AST_Binary, function(compressor) {
14582 if (this.operator === "+") {
14583 return this.left.is_bigint(compressor) && this.right.is_number_or_bigint(compressor)
14584 || this.right.is_bigint(compressor) && this.left.is_number_or_bigint(compressor);
14585 } else if (numeric_ops.has(this.operator)) {
14586 return this.left.is_bigint(compressor) || this.right.is_bigint(compressor);
14587 } else {
14588 return false;
14589 }
14590 });
14591 def_is_bigint(AST_Assign, function(compressor) {
14592 return (numeric_ops.has(this.operator.slice(0, -1)) || this.operator == "=")
14593 && this.right.is_bigint(compressor);
14594 });
14595 def_is_bigint(AST_Sequence, function(compressor) {
14596 return this.tail_node().is_bigint(compressor);
14597 });
14598 def_is_bigint(AST_Conditional, function(compressor) {
14599 return this.consequent.is_bigint(compressor) && this.alternative.is_bigint(compressor);
14600 });
14601})(function(node, func) {
14602 node.DEFMETHOD("is_bigint", func);
14603});
14604
14605// methods to determine if an expression is a number or a bigint
14606(function(def_is_number_or_bigint) {
14607 def_is_number_or_bigint(AST_Node, return_false);
14608 def_is_number_or_bigint(AST_Number, return_true);
14609 def_is_number_or_bigint(AST_BigInt, return_true);
14610 const numeric_unary_ops = makePredicate("+ - ~ ++ --");
14611 def_is_number_or_bigint(AST_Unary, function(_compressor) {
14612 return numeric_unary_ops.has(this.operator);
14613 });
14614 const numeric_ops = makePredicate("- * / % & | ^ << >>");
14615 def_is_number_or_bigint(AST_Binary, function(compressor) {
14616 return this.operator === "+"
14617 ? this.left.is_number_or_bigint(compressor) && this.right.is_number_or_bigint(compressor)
14618 : numeric_ops.has(this.operator);
14619 });
14620 def_is_number_or_bigint(AST_Assign, function(compressor) {
14621 return numeric_ops.has(this.operator.slice(0, -1))
14622 || this.operator == "=" && this.right.is_number_or_bigint(compressor);
14623 });
14624 def_is_number_or_bigint(AST_Sequence, function(compressor) {
14625 return this.tail_node().is_number_or_bigint(compressor);
14626 });
14627 def_is_number_or_bigint(AST_Conditional, function(compressor) {
14628 return this.consequent.is_number_or_bigint(compressor) && this.alternative.is_number_or_bigint(compressor);
14629 });
14630}(function (node, func) {
14631 node.DEFMETHOD("is_number_or_bigint", func);
14632}));
14633
14634
14635// methods to determine if an expression is a 32 bit integer (IE results from bitwise ops, or is an integer constant fitting in that size
14636(function(def_is_32_bit_integer) {
14637 def_is_32_bit_integer(AST_Node, return_false);
14638 def_is_32_bit_integer(AST_Number, function(_compressor) {
14639 return this.value === (this.value | 0);
14640 });
14641 def_is_32_bit_integer(AST_UnaryPrefix, function(compressor) {
14642 return this.operator == "~" ? this.expression.is_number(compressor)
14643 : this.operator === "+" ? this.expression.is_32_bit_integer(compressor)
14644 : false;
14645 });
14646 def_is_32_bit_integer(AST_Binary, function(compressor) {
14647 return bitwise_binop.has(this.operator)
14648 && (this.left.is_number(compressor) || this.right.is_number(compressor));
14649 });
14650}(function (node, func) {
14651 node.DEFMETHOD("is_32_bit_integer", func);
14652}));
14653
14654// methods to determine if an expression has a string result type
14655(function(def_is_string) {
14656 def_is_string(AST_Node, return_false);
14657 def_is_string(AST_String, return_true);
14658 def_is_string(AST_TemplateString, return_true);
14659 def_is_string(AST_UnaryPrefix, function() {
14660 return this.operator == "typeof";
14661 });
14662 def_is_string(AST_Binary, function(compressor) {
14663 return this.operator == "+" &&
14664 (this.left.is_string(compressor) || this.right.is_string(compressor));
14665 });
14666 def_is_string(AST_Assign, function(compressor) {
14667 return (this.operator == "=" || this.operator == "+=") && this.right.is_string(compressor);
14668 });
14669 def_is_string(AST_Sequence, function(compressor) {
14670 return this.tail_node().is_string(compressor);
14671 });
14672 def_is_string(AST_Conditional, function(compressor) {
14673 return this.consequent.is_string(compressor) && this.alternative.is_string(compressor);
14674 });
14675})(function(node, func) {
14676 node.DEFMETHOD("is_string", func);
14677});
14678
14679function is_undefined(node, compressor) {
14680 return (
14681 has_flag(node, UNDEFINED)
14682 || node instanceof AST_Undefined
14683 || node instanceof AST_UnaryPrefix
14684 && node.operator == "void"
14685 && !node.expression.has_side_effects(compressor)
14686 );
14687}
14688
14689// Is the node explicitly null or undefined.
14690function is_null_or_undefined(node, compressor) {
14691 let fixed;
14692 return (
14693 node instanceof AST_Null
14694 || is_undefined(node, compressor)
14695 || (
14696 node instanceof AST_SymbolRef
14697 && (fixed = node.definition().fixed) instanceof AST_Node
14698 && is_nullish(fixed, compressor)
14699 )
14700 );
14701}
14702
14703// Find out if this expression is optionally chained from a base-point that we
14704// can statically analyze as null or undefined.
14705function is_nullish_shortcircuited(node, compressor) {
14706 if (node instanceof AST_PropAccess || node instanceof AST_Call) {
14707 return (
14708 (node.optional && is_null_or_undefined(node.expression, compressor))
14709 || is_nullish_shortcircuited(node.expression, compressor)
14710 );
14711 }
14712 if (node instanceof AST_Chain) return is_nullish_shortcircuited(node.expression, compressor);
14713 return false;
14714}
14715
14716// Find out if something is == null, or can short circuit into nullish.
14717// Used to optimize ?. and ??
14718function is_nullish(node, compressor) {
14719 if (is_null_or_undefined(node, compressor)) return true;
14720 return is_nullish_shortcircuited(node, compressor);
14721}
14722
14723// Determine if expression might cause side effects
14724// If there's a possibility that a node may change something when it's executed, this returns true
14725(function(def_has_side_effects) {
14726 def_has_side_effects(AST_Node, return_true);
14727
14728 def_has_side_effects(AST_EmptyStatement, return_false);
14729 def_has_side_effects(AST_Constant, return_false);
14730 def_has_side_effects(AST_This, return_false);
14731
14732 function any(list, compressor) {
14733 for (var i = list.length; --i >= 0;)
14734 if (list[i].has_side_effects(compressor))
14735 return true;
14736 return false;
14737 }
14738
14739 def_has_side_effects(AST_Block, function(compressor) {
14740 return any(this.body, compressor);
14741 });
14742 def_has_side_effects(AST_Call, function(compressor) {
14743 if (
14744 !this.is_callee_pure(compressor)
14745 && (!this.expression.is_call_pure(compressor)
14746 || this.expression.has_side_effects(compressor))
14747 ) {
14748 return true;
14749 }
14750 return any(this.args, compressor);
14751 });
14752 def_has_side_effects(AST_Switch, function(compressor) {
14753 return this.expression.has_side_effects(compressor)
14754 || any(this.body, compressor);
14755 });
14756 def_has_side_effects(AST_Case, function(compressor) {
14757 return this.expression.has_side_effects(compressor)
14758 || any(this.body, compressor);
14759 });
14760 def_has_side_effects(AST_Try, function(compressor) {
14761 return this.body.has_side_effects(compressor)
14762 || this.bcatch && this.bcatch.has_side_effects(compressor)
14763 || this.bfinally && this.bfinally.has_side_effects(compressor);
14764 });
14765 def_has_side_effects(AST_If, function(compressor) {
14766 return this.condition.has_side_effects(compressor)
14767 || this.body && this.body.has_side_effects(compressor)
14768 || this.alternative && this.alternative.has_side_effects(compressor);
14769 });
14770 def_has_side_effects(AST_ImportMeta, return_false);
14771 def_has_side_effects(AST_DynamicImport, function() {
14772 // `import.source(x)` only compiles the module, which is side-effect free
14773 return this.phase !== "source";
14774 });
14775 def_has_side_effects(AST_LabeledStatement, function(compressor) {
14776 return this.body.has_side_effects(compressor);
14777 });
14778 def_has_side_effects(AST_SimpleStatement, function(compressor) {
14779 return this.body.has_side_effects(compressor);
14780 });
14781 def_has_side_effects(AST_Lambda, return_false);
14782 def_has_side_effects(AST_Class, function (compressor) {
14783 if (this.extends && this.extends.has_side_effects(compressor)) {
14784 return true;
14785 }
14786 return any(this.properties, compressor);
14787 });
14788 def_has_side_effects(AST_ClassStaticBlock, function(compressor) {
14789 return any(this.body, compressor);
14790 });
14791 def_has_side_effects(AST_Binary, function(compressor) {
14792 return this.left.has_side_effects(compressor)
14793 || this.right.has_side_effects(compressor);
14794 });
14795 def_has_side_effects(AST_Assign, return_true);
14796 def_has_side_effects(AST_Conditional, function(compressor) {
14797 return this.condition.has_side_effects(compressor)
14798 || this.consequent.has_side_effects(compressor)
14799 || this.alternative.has_side_effects(compressor);
14800 });
14801 def_has_side_effects(AST_Unary, function(compressor) {
14802 return unary_side_effects.has(this.operator)
14803 || this.expression.has_side_effects(compressor);
14804 });
14805 def_has_side_effects(AST_SymbolRef, function(compressor) {
14806 return !this.is_declared(compressor) && !pure_prop_access_globals.has(this.name);
14807 });
14808 def_has_side_effects(AST_SymbolClassProperty, return_false);
14809 def_has_side_effects(AST_SymbolDeclaration, return_false);
14810 def_has_side_effects(AST_Object, function(compressor) {
14811 return any(this.properties, compressor);
14812 });
14813 def_has_side_effects(AST_ObjectKeyVal, function(compressor) {
14814 return (
14815 this.computed_key() && this.key.has_side_effects(compressor)
14816 || this.value && this.value.has_side_effects(compressor)
14817 );
14818 });
14819 def_has_side_effects([
14820 AST_ClassProperty,
14821 AST_ClassPrivateProperty,
14822 ], function(compressor) {
14823 return (
14824 this.computed_key() && this.key.has_side_effects(compressor)
14825 || this.static && this.value && this.value.has_side_effects(compressor)
14826 );
14827 });
14828 def_has_side_effects([
14829 AST_PrivateMethod,
14830 AST_PrivateGetter,
14831 AST_PrivateSetter,
14832 AST_ConciseMethod,
14833 AST_ObjectGetter,
14834 AST_ObjectSetter,
14835 ], function(compressor) {
14836 return this.computed_key() && this.key.has_side_effects(compressor);
14837 });
14838 def_has_side_effects(AST_Array, function(compressor) {
14839 return any(this.elements, compressor);
14840 });
14841 def_has_side_effects(AST_Dot, function(compressor) {
14842 if (is_nullish(this, compressor)) {
14843 return this.expression.has_side_effects(compressor);
14844 }
14845 if (!this.optional && this.expression.may_throw_on_access(compressor)) {
14846 return true;
14847 }
14848
14849 return this.expression.has_side_effects(compressor);
14850 });
14851 def_has_side_effects(AST_Sub, function(compressor) {
14852 if (is_nullish(this, compressor)) {
14853 return this.expression.has_side_effects(compressor);
14854 }
14855 if (!this.optional && this.expression.may_throw_on_access(compressor)) {
14856 return true;
14857 }
14858
14859 var property = this.property.has_side_effects(compressor);
14860 if (property && this.optional) return true; // "?." is a condition
14861
14862 return property || this.expression.has_side_effects(compressor);
14863 });
14864 def_has_side_effects(AST_Chain, function (compressor) {
14865 return this.expression.has_side_effects(compressor);
14866 });
14867 def_has_side_effects(AST_Sequence, function(compressor) {
14868 return any(this.expressions, compressor);
14869 });
14870 def_has_side_effects(AST_Definitions, function(compressor) {
14871 return any(this.definitions, compressor);
14872 });
14873 def_has_side_effects(AST_VarDef, function() {
14874 return this.value != null;
14875 });
14876 def_has_side_effects(AST_TemplateSegment, return_false);
14877 def_has_side_effects(AST_TemplateString, function(compressor) {
14878 return any(this.segments, compressor);
14879 });
14880})(function(node_or_nodes, func) {
14881 for (const node of [].concat(node_or_nodes)) {
14882 node.DEFMETHOD("has_side_effects", func);
14883 }
14884});
14885
14886// determine if expression may throw
14887(function(def_may_throw) {
14888 def_may_throw(AST_Node, return_true);
14889
14890 def_may_throw(AST_Constant, return_false);
14891 def_may_throw(AST_EmptyStatement, return_false);
14892 def_may_throw(AST_Lambda, return_false);
14893 def_may_throw(AST_SymbolDeclaration, return_false);
14894 def_may_throw(AST_This, return_false);
14895 def_may_throw(AST_ImportMeta, return_false);
14896
14897 function any(list, compressor) {
14898 for (var i = list.length; --i >= 0;)
14899 if (list[i].may_throw(compressor))
14900 return true;
14901 return false;
14902 }
14903
14904 def_may_throw(AST_Class, function(compressor) {
14905 if (this.extends && this.extends.may_throw(compressor)) return true;
14906 return any(this.properties, compressor);
14907 });
14908 def_may_throw(AST_ClassStaticBlock, function (compressor) {
14909 return any(this.body, compressor);
14910 });
14911
14912 def_may_throw(AST_Array, function(compressor) {
14913 return any(this.elements, compressor);
14914 });
14915 def_may_throw(AST_Assign, function(compressor) {
14916 if (this.right.may_throw(compressor)) return true;
14917 if (!compressor.has_directive("use strict")
14918 && this.operator == "="
14919 && this.left instanceof AST_SymbolRef) {
14920 return false;
14921 }
14922 return this.left.may_throw(compressor);
14923 });
14924 def_may_throw(AST_Binary, function(compressor) {
14925 return this.left.may_throw(compressor)
14926 || this.right.may_throw(compressor);
14927 });
14928 def_may_throw(AST_Block, function(compressor) {
14929 return any(this.body, compressor);
14930 });
14931 def_may_throw(AST_Call, function(compressor) {
14932 if (is_nullish(this, compressor)) return false;
14933 if (any(this.args, compressor)) return true;
14934 if (this.is_callee_pure(compressor)) return false;
14935 if (this.expression.may_throw(compressor)) return true;
14936 return !(this.expression instanceof AST_Lambda)
14937 || any(this.expression.body, compressor);
14938 });
14939 def_may_throw(AST_Case, function(compressor) {
14940 return this.expression.may_throw(compressor)
14941 || any(this.body, compressor);
14942 });
14943 def_may_throw(AST_Conditional, function(compressor) {
14944 return this.condition.may_throw(compressor)
14945 || this.consequent.may_throw(compressor)
14946 || this.alternative.may_throw(compressor);
14947 });
14948 def_may_throw(AST_Definitions, function(compressor) {
14949 return any(this.definitions, compressor);
14950 });
14951 def_may_throw(AST_If, function(compressor) {
14952 return this.condition.may_throw(compressor)
14953 || this.body && this.body.may_throw(compressor)
14954 || this.alternative && this.alternative.may_throw(compressor);
14955 });
14956 def_may_throw(AST_LabeledStatement, function(compressor) {
14957 return this.body.may_throw(compressor);
14958 });
14959 def_may_throw(AST_Object, function(compressor) {
14960 return any(this.properties, compressor);
14961 });
14962 def_may_throw(AST_ObjectKeyVal, function(compressor) {
14963 return (
14964 this.computed_key() && this.key.may_throw(compressor)
14965 || this.value ? this.value.may_throw(compressor) : false
14966 );
14967 });
14968 def_may_throw([
14969 AST_ClassProperty,
14970 AST_ClassPrivateProperty,
14971 ], function(compressor) {
14972 return (
14973 this.computed_key() && this.key.may_throw(compressor)
14974 || this.static && this.value && this.value.may_throw(compressor)
14975 );
14976 });
14977 def_may_throw([
14978 AST_ConciseMethod,
14979 AST_ObjectGetter,
14980 AST_ObjectSetter,
14981 ], function(compressor) {
14982 return this.computed_key() && this.key.may_throw(compressor);
14983 });
14984 def_may_throw([
14985 AST_PrivateMethod,
14986 AST_PrivateGetter,
14987 AST_PrivateSetter,
14988 ], return_false);
14989 def_may_throw(AST_Return, function(compressor) {
14990 return this.value && this.value.may_throw(compressor);
14991 });
14992 def_may_throw(AST_Sequence, function(compressor) {
14993 return any(this.expressions, compressor);
14994 });
14995 def_may_throw(AST_SimpleStatement, function(compressor) {
14996 return this.body.may_throw(compressor);
14997 });
14998 def_may_throw(AST_Dot, function(compressor) {
14999 if (is_nullish(this, compressor)) return false;
15000 return !this.optional && this.expression.may_throw_on_access(compressor)
15001 || this.expression.may_throw(compressor);
15002 });
15003 def_may_throw(AST_Sub, function(compressor) {
15004 if (is_nullish(this, compressor)) return false;
15005 return !this.optional && this.expression.may_throw_on_access(compressor)
15006 || this.expression.may_throw(compressor)
15007 || this.property.may_throw(compressor);
15008 });
15009 def_may_throw(AST_Chain, function(compressor) {
15010 return this.expression.may_throw(compressor);
15011 });
15012 def_may_throw(AST_Switch, function(compressor) {
15013 return this.expression.may_throw(compressor)
15014 || any(this.body, compressor);
15015 });
15016 def_may_throw(AST_SymbolRef, function(compressor) {
15017 return !this.is_declared(compressor) && !pure_prop_access_globals.has(this.name);
15018 });
15019 def_may_throw(AST_SymbolClassProperty, return_false);
15020 def_may_throw(AST_Try, function(compressor) {
15021 return this.bcatch ? this.bcatch.may_throw(compressor) : this.body.may_throw(compressor)
15022 || this.bfinally && this.bfinally.may_throw(compressor);
15023 });
15024 def_may_throw(AST_Unary, function(compressor) {
15025 if (this.operator == "typeof" && this.expression instanceof AST_SymbolRef)
15026 return false;
15027 return this.expression.may_throw(compressor);
15028 });
15029 def_may_throw(AST_VarDef, function(compressor) {
15030 if (!this.value) return false;
15031 return this.value.may_throw(compressor);
15032 });
15033})(function(node_or_nodes, func) {
15034 for (const node of [].concat(node_or_nodes)) {
15035 node.DEFMETHOD("may_throw", func);
15036 }
15037});
15038
15039// determine if expression is constant
15040(function(def_is_constant_expression) {
15041 function all_refs_local(scope) {
15042 let result = true;
15043 walk(this, node => {
15044 if (node instanceof AST_SymbolRef) {
15045 if (has_flag(this, INLINED)) {
15046 result = false;
15047 return walk_abort;
15048 }
15049 var def = node.definition();
15050 if (
15051 member(def, this.enclosed)
15052 && !this.variables.has(def.name)
15053 ) {
15054 if (scope) {
15055 var scope_def = scope.find_variable(node);
15056 if (def.undeclared ? !scope_def : scope_def === def) {
15057 result = "f";
15058 return true;
15059 }
15060 }
15061 result = false;
15062 return walk_abort;
15063 }
15064 return true;
15065 }
15066 if (node instanceof AST_This && this instanceof AST_Arrow) {
15067 result = false;
15068 return walk_abort;
15069 }
15070 });
15071 return result;
15072 }
15073
15074 def_is_constant_expression(AST_Node, return_false);
15075 def_is_constant_expression(AST_Constant, return_true);
15076 def_is_constant_expression(AST_Class, function(scope) {
15077 if (this.extends && !this.extends.is_constant_expression(scope)) {
15078 return false;
15079 }
15080
15081 for (const prop of this.properties) {
15082 if (prop.computed_key() && !prop.key.is_constant_expression(scope)) {
15083 return false;
15084 }
15085 if (prop.static && prop.value && !prop.value.is_constant_expression(scope)) {
15086 return false;
15087 }
15088 if (prop instanceof AST_ClassStaticBlock) {
15089 return false;
15090 }
15091 }
15092
15093 return all_refs_local.call(this, scope);
15094 });
15095 def_is_constant_expression(AST_Lambda, all_refs_local);
15096 def_is_constant_expression(AST_Unary, function() {
15097 return this.expression.is_constant_expression();
15098 });
15099 def_is_constant_expression(AST_Binary, function() {
15100 return this.left.is_constant_expression()
15101 && this.right.is_constant_expression();
15102 });
15103 def_is_constant_expression(AST_Array, function() {
15104 return this.elements.every((l) => l.is_constant_expression());
15105 });
15106 def_is_constant_expression(AST_Object, function() {
15107 return this.properties.every((l) => l.is_constant_expression());
15108 });
15109 def_is_constant_expression(AST_ObjectProperty, function() {
15110 return !!(!(this.key instanceof AST_Node) && this.value && this.value.is_constant_expression());
15111 });
15112})(function(node, func) {
15113 node.DEFMETHOD("is_constant_expression", func);
15114});
15115
15116
15117// may_throw_on_access()
15118// returns true if this node may be null, undefined or contain `AST_Accessor`
15119(function(def_may_throw_on_access) {
15120 AST_Node.DEFMETHOD("may_throw_on_access", function(compressor) {
15121 return !compressor.option("pure_getters")
15122 || this._dot_throw(compressor);
15123 });
15124
15125 function is_strict(compressor) {
15126 return /strict/.test(compressor.option("pure_getters"));
15127 }
15128
15129 def_may_throw_on_access(AST_Node, is_strict);
15130 def_may_throw_on_access(AST_Null, return_true);
15131 def_may_throw_on_access(AST_Undefined, return_true);
15132 def_may_throw_on_access(AST_Constant, return_false);
15133 def_may_throw_on_access(AST_Array, return_false);
15134 def_may_throw_on_access(AST_Object, function(compressor) {
15135 if (!is_strict(compressor)) return false;
15136 for (var i = this.properties.length; --i >=0;)
15137 if (this.properties[i]._dot_throw(compressor)) return true;
15138 return false;
15139 });
15140 // Do not be as strict with classes as we are with objects.
15141 // Hopefully the community is not going to abuse static getters and setters.
15142 // https://github.com/terser/terser/issues/724#issuecomment-643655656
15143 def_may_throw_on_access(AST_Class, return_false);
15144 def_may_throw_on_access(AST_ObjectProperty, return_false);
15145 def_may_throw_on_access(AST_ObjectGetter, return_true);
15146 def_may_throw_on_access(AST_Expansion, function(compressor) {
15147 return this.expression._dot_throw(compressor);
15148 });
15149 def_may_throw_on_access(AST_Function, return_false);
15150 def_may_throw_on_access(AST_Arrow, return_false);
15151 def_may_throw_on_access(AST_UnaryPostfix, return_false);
15152 def_may_throw_on_access(AST_UnaryPrefix, function() {
15153 return this.operator == "void";
15154 });
15155 def_may_throw_on_access(AST_Binary, function(compressor) {
15156 return (this.operator == "&&" || this.operator == "||" || this.operator == "??")
15157 && (this.left._dot_throw(compressor) || this.right._dot_throw(compressor));
15158 });
15159 def_may_throw_on_access(AST_Assign, function(compressor) {
15160 if (this.logical) return true;
15161
15162 return this.operator == "="
15163 && this.right._dot_throw(compressor);
15164 });
15165 def_may_throw_on_access(AST_Conditional, function(compressor) {
15166 return this.consequent._dot_throw(compressor)
15167 || this.alternative._dot_throw(compressor);
15168 });
15169 def_may_throw_on_access(AST_Dot, function(compressor) {
15170 if (!is_strict(compressor)) return false;
15171
15172 if (this.property == "prototype") {
15173 return !(
15174 this.expression instanceof AST_Function
15175 || this.expression instanceof AST_Class
15176 );
15177 }
15178 return true;
15179 });
15180 def_may_throw_on_access(AST_Chain, function(compressor) {
15181 return this.expression._dot_throw(compressor);
15182 });
15183 def_may_throw_on_access(AST_Sequence, function(compressor) {
15184 return this.tail_node()._dot_throw(compressor);
15185 });
15186 def_may_throw_on_access(AST_SymbolRef, function(compressor) {
15187 if (this.name === "arguments" && this.scope instanceof AST_Lambda) return false;
15188 if (has_flag(this, UNDEFINED)) return true;
15189 if (!is_strict(compressor)) return false;
15190 if (is_undeclared_ref(this) && this.is_declared(compressor)) return false;
15191 if (this.is_immutable()) return false;
15192 var fixed = this.fixed_value();
15193 return !fixed || fixed._dot_throw(compressor);
15194 });
15195})(function(node, func) {
15196 node.DEFMETHOD("_dot_throw", func);
15197});
15198
15199function is_lhs(node, parent) {
15200 if (parent instanceof AST_Unary && unary_side_effects.has(parent.operator)) return parent.expression;
15201 if (parent instanceof AST_Assign && parent.left === node) return node;
15202 if (parent instanceof AST_ForIn && parent.init === node) return node;
15203}
15204
15205// method to negate an expression
15206(function(def_negate) {
15207 function basic_negation(exp) {
15208 return make_node(AST_UnaryPrefix, exp, {
15209 operator: "!",
15210 expression: exp
15211 });
15212 }
15213 function best(orig, alt, first_in_statement) {
15214 var negated = basic_negation(orig);
15215 if (first_in_statement) {
15216 var stat = make_node(AST_SimpleStatement, alt, {
15217 body: alt
15218 });
15219 return best_of_expression(negated, stat) === stat ? alt : negated;
15220 }
15221 return best_of_expression(negated, alt);
15222 }
15223 def_negate(AST_Node, function() {
15224 return basic_negation(this);
15225 });
15226 def_negate(AST_Statement, function() {
15227 throw new Error("Cannot negate a statement");
15228 });
15229 def_negate(AST_Function, function() {
15230 return basic_negation(this);
15231 });
15232 def_negate(AST_Class, function() {
15233 return basic_negation(this);
15234 });
15235 def_negate(AST_Arrow, function() {
15236 return basic_negation(this);
15237 });
15238 def_negate(AST_UnaryPrefix, function() {
15239 if (this.operator == "!")
15240 return this.expression;
15241 return basic_negation(this);
15242 });
15243 def_negate(AST_Sequence, function(compressor) {
15244 var expressions = this.expressions.slice();
15245 expressions.push(expressions.pop().negate(compressor));
15246 return make_sequence(this, expressions);
15247 });
15248 def_negate(AST_Conditional, function(compressor, first_in_statement) {
15249 var self = this.clone();
15250 self.consequent = self.consequent.negate(compressor);
15251 self.alternative = self.alternative.negate(compressor);
15252 return best(this, self, first_in_statement);
15253 });
15254 def_negate(AST_Binary, function(compressor, first_in_statement) {
15255 var self = this.clone(), op = this.operator;
15256 if (compressor.option("unsafe_comps")) {
15257 switch (op) {
15258 case "<=" : self.operator = ">" ; return self;
15259 case "<" : self.operator = ">=" ; return self;
15260 case ">=" : self.operator = "<" ; return self;
15261 case ">" : self.operator = "<=" ; return self;
15262 }
15263 }
15264 switch (op) {
15265 case "==" : self.operator = "!="; return self;
15266 case "!=" : self.operator = "=="; return self;
15267 case "===": self.operator = "!=="; return self;
15268 case "!==": self.operator = "==="; return self;
15269 case "&&":
15270 self.operator = "||";
15271 self.left = self.left.negate(compressor, first_in_statement);
15272 self.right = self.right.negate(compressor);
15273 return best(this, self, first_in_statement);
15274 case "||":
15275 self.operator = "&&";
15276 self.left = self.left.negate(compressor, first_in_statement);
15277 self.right = self.right.negate(compressor);
15278 return best(this, self, first_in_statement);
15279 }
15280 return basic_negation(this);
15281 });
15282})(function(node, func) {
15283 node.DEFMETHOD("negate", function(compressor, first_in_statement) {
15284 return func.call(this, compressor, first_in_statement);
15285 });
15286});
15287
15288(function (def_bitwise_negate) {
15289 function basic_bitwise_negation(exp) {
15290 return make_node(AST_UnaryPrefix, exp, {
15291 operator: "~",
15292 expression: exp
15293 });
15294 }
15295
15296 def_bitwise_negate(AST_Node, function(_compressor) {
15297 return basic_bitwise_negation(this);
15298 });
15299
15300 def_bitwise_negate(AST_Number, function(_compressor) {
15301 const neg = ~this.value;
15302 if (neg.toString().length > this.value.toString().length) {
15303 return basic_bitwise_negation(this);
15304 }
15305 return make_node(AST_Number, this, { value: neg });
15306 });
15307
15308 def_bitwise_negate(AST_UnaryPrefix, function(compressor, in_32_bit_context) {
15309 if (
15310 this.operator == "~"
15311 && (
15312 this.expression.is_32_bit_integer(compressor) ||
15313 (in_32_bit_context != null ? in_32_bit_context : compressor.in_32_bit_context())
15314 )
15315 ) {
15316 return this.expression;
15317 } else {
15318 return basic_bitwise_negation(this);
15319 }
15320 });
15321})(function (node, func) {
15322 node.DEFMETHOD("bitwise_negate", func);
15323});
15324
15325// Is the callee of this function pure?
15326var 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");
15327AST_Call.DEFMETHOD("is_callee_pure", function(compressor) {
15328 if (compressor.option("unsafe")) {
15329 var expr = this.expression;
15330 var first_arg;
15331 if (
15332 expr.expression && expr.expression.name === "hasOwnProperty" &&
15333 (
15334 (first_arg = (this.args && this.args[0] && this.args[0].evaluate(compressor))) == null
15335 || first_arg.thedef && first_arg.thedef.undeclared
15336 )
15337 ) {
15338 return false;
15339 }
15340 if (is_undeclared_ref(expr) && global_pure_fns.has(expr.name)) return true;
15341 if (is_pure_builtin_call(compressor, this)) return true;
15342 } else if (compressor.option("builtins_pure")) {
15343 if (is_pure_builtin_call(compressor, this)) return true;
15344 }
15345 if ((this instanceof AST_New) && compressor.option("pure_new")) {
15346 return true;
15347 }
15348 if (compressor.option("side_effects") && has_annotation(this, _PURE)) {
15349 return true;
15350 }
15351 return !compressor.pure_funcs(this);
15352});
15353
15354// If I call this, is it a pure function?
15355AST_Node.DEFMETHOD("is_call_pure", return_false);
15356AST_Dot.DEFMETHOD("is_call_pure", function(compressor) {
15357 if (!compressor.option("unsafe")) return;
15358 const expr = this.expression;
15359
15360 let native_obj;
15361 if (expr instanceof AST_Array) {
15362 native_obj = "Array";
15363 } else if (expr.is_boolean()) {
15364 native_obj = "Boolean";
15365 } else if (expr.is_number(compressor)) {
15366 native_obj = "Number";
15367 } else if (expr instanceof AST_RegExp) {
15368 native_obj = "RegExp";
15369 } else if (expr.is_string(compressor)) {
15370 native_obj = "String";
15371 } else if (!this.may_throw_on_access(compressor)) {
15372 native_obj = "Object";
15373 }
15374 return native_obj != null && compressor.is_pure_native_method(native_obj, this.property);
15375});
15376
15377// tell me if a statement aborts
15378const aborts = (thing) => thing && thing.aborts();
15379
15380(function(def_aborts) {
15381 def_aborts(AST_Statement, return_null);
15382 def_aborts(AST_Jump, return_this);
15383 function block_aborts() {
15384 for (var i = 0; i < this.body.length; i++) {
15385 if (aborts(this.body[i])) {
15386 return this.body[i];
15387 }
15388 }
15389 return null;
15390 }
15391 def_aborts(AST_Import, return_null);
15392 def_aborts(AST_BlockStatement, block_aborts);
15393 def_aborts(AST_SwitchBranch, block_aborts);
15394 def_aborts(AST_DefClass, function () {
15395 for (const prop of this.properties) {
15396 if (prop instanceof AST_ClassStaticBlock) {
15397 if (prop.aborts()) return prop;
15398 }
15399 }
15400 return null;
15401 });
15402 def_aborts(AST_ClassStaticBlock, block_aborts);
15403 def_aborts(AST_If, function() {
15404 return this.alternative && aborts(this.body) && aborts(this.alternative) && this;
15405 });
15406})(function(node, func) {
15407 node.DEFMETHOD("aborts", func);
15408});
15409
15410AST_Node.DEFMETHOD("contains_this", function() {
15411 return walk(this, node => {
15412 if (node instanceof AST_This) return walk_abort;
15413 if (
15414 node !== this
15415 && node instanceof AST_Scope
15416 && !(node instanceof AST_Arrow)
15417 ) {
15418 return true;
15419 }
15420 });
15421});
15422
15423function is_modified(compressor, tw, node, value, level, immutable) {
15424 var parent = tw.parent(level);
15425 var lhs = is_lhs(node, parent);
15426 if (lhs) return lhs;
15427 if (!immutable
15428 && parent instanceof AST_Call
15429 && parent.expression === node
15430 && !(value instanceof AST_Arrow)
15431 && !(value instanceof AST_Class)
15432 && !parent.is_callee_pure(compressor)
15433 && (!(value instanceof AST_Function)
15434 || !(parent instanceof AST_New) && value.contains_this())) {
15435 return true;
15436 }
15437 if (parent instanceof AST_Array) {
15438 return is_modified(compressor, tw, parent, parent, level + 1);
15439 }
15440 if (parent instanceof AST_ObjectKeyVal && node === parent.value) {
15441 var obj = tw.parent(level + 1);
15442 return is_modified(compressor, tw, obj, obj, level + 2);
15443 }
15444 if (parent instanceof AST_PropAccess && parent.expression === node) {
15445 var prop = read_property(value, parent.property);
15446 return !immutable && is_modified(compressor, tw, parent, prop, level + 1);
15447 }
15448}
15449
15450/**
15451 * Check if a node may be used by the expression it's in
15452 * void (0, 1, {node}, 2) -> false
15453 * console.log(0, {node}) -> true
15454 */
15455function is_used_in_expression(tw) {
15456 for (let p = -1, node, parent; node = tw.parent(p), parent = tw.parent(p + 1); p++) {
15457 if (parent instanceof AST_Sequence) {
15458 const nth_expression = parent.expressions.indexOf(node);
15459 if (nth_expression !== parent.expressions.length - 1) {
15460 // Detect (0, x.noThis)() constructs
15461 const grandparent = tw.parent(p + 2);
15462 if (
15463 parent.expressions.length > 2
15464 || parent.expressions.length === 1
15465 || !requires_sequence_to_maintain_binding(grandparent, parent, parent.expressions[1])
15466 ) {
15467 return false;
15468 }
15469 return true;
15470 } else {
15471 continue;
15472 }
15473 }
15474 if (parent instanceof AST_Unary) {
15475 const op = parent.operator;
15476 if (op === "void") {
15477 return false;
15478 }
15479 if (op === "typeof" || op === "+" || op === "-" || op === "!" || op === "~") {
15480 continue;
15481 }
15482 }
15483 if (
15484 parent instanceof AST_SimpleStatement
15485 || parent instanceof AST_LabeledStatement
15486 ) {
15487 return false;
15488 }
15489 if (parent instanceof AST_Scope) {
15490 return false;
15491 }
15492 return true;
15493 }
15494
15495 return true;
15496}
15497
15498/***********************************************************************
15499
15500 A JavaScript tokenizer / parser / beautifier / compressor.
15501 https://github.com/mishoo/UglifyJS2
15502
15503 -------------------------------- (C) ---------------------------------
15504
15505 Author: Mihai Bazon
15506 <mihai.bazon@gmail.com>
15507 http://mihai.bazon.net/blog
15508
15509 Distributed under the BSD license:
15510
15511 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
15512
15513 Redistribution and use in source and binary forms, with or without
15514 modification, are permitted provided that the following conditions
15515 are met:
15516
15517 * Redistributions of source code must retain the above
15518 copyright notice, this list of conditions and the following
15519 disclaimer.
15520
15521 * Redistributions in binary form must reproduce the above
15522 copyright notice, this list of conditions and the following
15523 disclaimer in the documentation and/or other materials
15524 provided with the distribution.
15525
15526 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
15527 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15528 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15529 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
15530 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
15531 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
15532 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
15533 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
15534 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
15535 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
15536 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
15537 SUCH DAMAGE.
15538
15539 ***********************************************************************/
15540
15541// methods to evaluate a constant expression
15542
15543function def_eval(node, func) {
15544 node.DEFMETHOD("_eval", func);
15545}
15546
15547// Used to propagate a nullish short-circuit signal upwards through the chain.
15548const nullish = Symbol("This AST_Chain is nullish");
15549
15550// If the node has been successfully reduced to a constant,
15551// then its value is returned; otherwise the element itself
15552// is returned.
15553// They can be distinguished as constant value is never a
15554// descendant of AST_Node.
15555AST_Node.DEFMETHOD("evaluate", function (compressor) {
15556 if (!compressor.option("evaluate"))
15557 return this;
15558 var val = this._eval(compressor, 1);
15559 if (!val || val instanceof RegExp)
15560 return val;
15561 if (typeof val == "function" || typeof val == "object" || val == nullish)
15562 return this;
15563
15564 // Evaluated strings can be larger than the original expression
15565 if (typeof val === "string") {
15566 const unevaluated_size = this.size(compressor);
15567 if (val.length + 2 > unevaluated_size) return this;
15568 }
15569
15570 return val;
15571});
15572
15573var unaryPrefix = makePredicate("! ~ - + void");
15574AST_Node.DEFMETHOD("is_constant", function () {
15575 // Accomodate when compress option evaluate=false
15576 // as well as the common constant expressions !0 and -1
15577 if (this instanceof AST_Constant) {
15578 return !(this instanceof AST_RegExp);
15579 } else {
15580 return this instanceof AST_UnaryPrefix
15581 && unaryPrefix.has(this.operator)
15582 && (
15583 // `this.expression` may be an `AST_RegExp`,
15584 // so not only `.is_constant()`.
15585 this.expression instanceof AST_Constant
15586 || this.expression.is_constant()
15587 );
15588 }
15589});
15590
15591def_eval(AST_Statement, function () {
15592 throw new Error(string_template("Cannot evaluate a statement [{file}:{line},{col}]", this.start));
15593});
15594
15595def_eval(AST_Lambda, return_this);
15596def_eval(AST_Class, return_this);
15597def_eval(AST_Node, return_this);
15598def_eval(AST_Constant, function () {
15599 return this.getValue();
15600});
15601
15602const supports_bigint = typeof BigInt === "function";
15603def_eval(AST_BigInt, function () {
15604 if (supports_bigint) {
15605 return BigInt(this.value);
15606 } else {
15607 return this;
15608 }
15609});
15610
15611def_eval(AST_RegExp, function (compressor) {
15612 let evaluated = compressor.evaluated_regexps.get(this.value);
15613 if (evaluated === undefined && regexp_is_safe(this.value.source)) {
15614 try {
15615 const { source, flags } = this.value;
15616 evaluated = new RegExp(source, flags);
15617 } catch (e) {
15618 evaluated = null;
15619 }
15620 compressor.evaluated_regexps.set(this.value, evaluated);
15621 }
15622 return evaluated || this;
15623});
15624
15625def_eval(AST_TemplateString, function () {
15626 if (this.segments.length !== 1) return this;
15627 return this.segments[0].value;
15628});
15629
15630def_eval(AST_Function, function (compressor) {
15631 if (compressor.option("unsafe")) {
15632 var fn = function () { };
15633 fn.node = this;
15634 fn.toString = () => this.print_to_string();
15635 return fn;
15636 }
15637 return this;
15638});
15639
15640def_eval(AST_Array, function (compressor, depth) {
15641 if (compressor.option("unsafe")) {
15642 var elements = [];
15643 for (var i = 0, len = this.elements.length; i < len; i++) {
15644 var element = this.elements[i];
15645 var value = element._eval(compressor, depth);
15646 if (element === value)
15647 return this;
15648 elements.push(value);
15649 }
15650 return elements;
15651 }
15652 return this;
15653});
15654
15655def_eval(AST_Object, function (compressor, depth) {
15656 if (compressor.option("unsafe")) {
15657 var val = {};
15658 for (var i = 0, len = this.properties.length; i < len; i++) {
15659 var prop = this.properties[i];
15660 if (prop instanceof AST_Expansion)
15661 return this;
15662 var key = prop.key;
15663 if (key instanceof AST_Symbol) {
15664 key = key.name;
15665 } else if (key instanceof AST_Node) {
15666 key = key._eval(compressor, depth);
15667 if (key === prop.key)
15668 return this;
15669 }
15670 if (typeof Object.prototype[key] === "function") {
15671 return this;
15672 }
15673 if (prop.value instanceof AST_Function)
15674 continue;
15675 val[key] = prop.value._eval(compressor, depth);
15676 if (val[key] === prop.value)
15677 return this;
15678 }
15679 return val;
15680 }
15681 return this;
15682});
15683
15684var non_converting_unary = makePredicate("! typeof void");
15685def_eval(AST_UnaryPrefix, function (compressor, depth) {
15686 var e = this.expression;
15687 if (compressor.option("typeofs")
15688 && this.operator == "typeof") {
15689 // Function would be evaluated to an array and so typeof would
15690 // incorrectly return 'object'. Hence making is a special case.
15691 if (e instanceof AST_Lambda
15692 || e instanceof AST_SymbolRef
15693 && e.fixed_value() instanceof AST_Lambda) {
15694 return typeof function () { };
15695 }
15696 if (
15697 (e instanceof AST_Object
15698 || e instanceof AST_Array
15699 || (e instanceof AST_SymbolRef
15700 && (e.fixed_value() instanceof AST_Object
15701 || e.fixed_value() instanceof AST_Array)))
15702 && !e.has_side_effects(compressor)
15703 ) {
15704 return typeof {};
15705 }
15706 }
15707 if (!non_converting_unary.has(this.operator))
15708 depth++;
15709 e = e._eval(compressor, depth);
15710 if (e === this.expression)
15711 return this;
15712 switch (this.operator) {
15713 case "!": return !e;
15714 case "typeof":
15715 // typeof <RegExp> returns "object" or "function" on different platforms
15716 // so cannot evaluate reliably
15717 if (e instanceof RegExp)
15718 return this;
15719 return typeof e;
15720 case "void": return void e;
15721 case "~": return ~e;
15722 case "-": return -e;
15723 case "+": return +e;
15724 }
15725 return this;
15726});
15727
15728var non_converting_binary = makePredicate("&& || ?? === !==");
15729const identity_comparison = makePredicate("== != === !==");
15730const has_identity = value => typeof value === "object"
15731 || typeof value === "function"
15732 || typeof value === "symbol";
15733
15734def_eval(AST_Binary, function (compressor, depth) {
15735 if (!non_converting_binary.has(this.operator))
15736 depth++;
15737
15738 var left = this.left._eval(compressor, depth);
15739 if (left === this.left)
15740 return this;
15741 var right = this.right._eval(compressor, depth);
15742 if (right === this.right)
15743 return this;
15744
15745 if (left != null
15746 && right != null
15747 && identity_comparison.has(this.operator)
15748 && has_identity(left)
15749 && has_identity(right)
15750 && typeof left === typeof right) {
15751 // Do not compare by reference
15752 return this;
15753 }
15754
15755 // Do not mix BigInt and Number; Don't use `>>>` on BigInt or `/ 0n`
15756 if (
15757 (typeof left === "bigint") !== (typeof right === "bigint")
15758 || typeof left === "bigint"
15759 && (this.operator === ">>>"
15760 || this.operator === "/" && Number(right) === 0)
15761 ) {
15762 return this;
15763 }
15764
15765 var result;
15766 switch (this.operator) {
15767 case "&&": result = left && right; break;
15768 case "||": result = left || right; break;
15769 case "??": result = left != null ? left : right; break;
15770 case "|": result = left | right; break;
15771 case "&": result = left & right; break;
15772 case "^": result = left ^ right; break;
15773 case "+": result = left + right; break;
15774 case "*": result = left * right; break;
15775 case "**": result = left ** right; break;
15776 case "/": result = left / right; break;
15777 case "%": result = left % right; break;
15778 case "-": result = left - right; break;
15779 case "<<": result = left << right; break;
15780 case ">>": result = left >> right; break;
15781 case ">>>": result = left >>> right; break;
15782 case "==": result = left == right; break;
15783 case "===": result = left === right; break;
15784 case "!=": result = left != right; break;
15785 case "!==": result = left !== right; break;
15786 case "<": result = left < right; break;
15787 case "<=": result = left <= right; break;
15788 case ">": result = left > right; break;
15789 case ">=": result = left >= right; break;
15790 default:
15791 return this;
15792 }
15793 if (typeof result === "number" && isNaN(result) && compressor.find_parent(AST_With)) {
15794 // leave original expression as is
15795 return this;
15796 }
15797 return result;
15798});
15799
15800def_eval(AST_Conditional, function (compressor, depth) {
15801 var condition = this.condition._eval(compressor, depth);
15802 if (condition === this.condition)
15803 return this;
15804 var node = condition ? this.consequent : this.alternative;
15805 var value = node._eval(compressor, depth);
15806 return value === node ? this : value;
15807});
15808
15809// Set of AST_SymbolRef which are currently being evaluated.
15810// Avoids infinite recursion of ._eval()
15811const reentrant_ref_eval = new Set();
15812def_eval(AST_SymbolRef, function (compressor, depth) {
15813 if (reentrant_ref_eval.has(this))
15814 return this;
15815
15816 var fixed = this.fixed_value();
15817 if (!fixed)
15818 return this;
15819
15820 reentrant_ref_eval.add(this);
15821 const value = fixed._eval(compressor, depth);
15822 reentrant_ref_eval.delete(this);
15823
15824 if (value === fixed)
15825 return this;
15826
15827 if (value && typeof value == "object") {
15828 var escaped = this.definition().escaped;
15829 if (escaped && depth > escaped)
15830 return this;
15831 }
15832 return value;
15833});
15834
15835def_eval(AST_Chain, function (compressor, depth) {
15836 const evaluated = this.expression._eval(compressor, depth, /*ast_chain=*/true);
15837 return evaluated === nullish
15838 ? undefined
15839 : evaluated === this.expression
15840 ? this
15841 : evaluated;
15842});
15843
15844const global_objs = { Array, Math, Number, Object, String };
15845
15846const regexp_flags = new Set([
15847 "dotAll",
15848 "global",
15849 "ignoreCase",
15850 "multiline",
15851 "sticky",
15852 "unicode",
15853]);
15854
15855def_eval(AST_PropAccess, function (compressor, depth, ast_chain) {
15856 let obj = (ast_chain || this.property === "length" || compressor.option("unsafe"))
15857 && this.expression._eval(compressor, depth + 1, ast_chain);
15858
15859 if (ast_chain) {
15860 if (obj === nullish || (this.optional && obj == null)) return nullish;
15861 }
15862
15863 // `.length` of strings and arrays is always safe
15864 if (this.property === "length") {
15865 if (typeof obj === "string") {
15866 return obj.length;
15867 }
15868
15869 const is_spreadless_array =
15870 obj instanceof AST_Array
15871 && obj.elements.every(el => !(el instanceof AST_Expansion));
15872
15873 if (
15874 is_spreadless_array
15875 && obj.elements.every(el => !el.has_side_effects(compressor))
15876 ) {
15877 return obj.elements.length;
15878 }
15879 }
15880
15881 if (compressor.option("unsafe")) {
15882 var key = this.property;
15883 if (key instanceof AST_Node) {
15884 key = key._eval(compressor, depth);
15885 if (key === this.property)
15886 return this;
15887 }
15888
15889 var exp = this.expression;
15890 if (is_undeclared_ref(exp)) {
15891 var aa;
15892 var first_arg = exp.name === "hasOwnProperty"
15893 && key === "call"
15894 && (aa = compressor.parent() && compressor.parent().args)
15895 && (aa && aa[0]
15896 && aa[0].evaluate(compressor));
15897
15898 first_arg = first_arg instanceof AST_Dot ? first_arg.expression : first_arg;
15899
15900 if (first_arg == null || first_arg.thedef && first_arg.thedef.undeclared) {
15901 return this.clone();
15902 }
15903 if (!compressor.is_pure_native_static_property(exp.name, key))
15904 return this;
15905 obj = global_objs[exp.name];
15906 } else {
15907 if (obj instanceof RegExp) {
15908 if (key == "source") {
15909 return regexp_source_fix(obj.source);
15910 } else if (key == "flags" || regexp_flags.has(key)) {
15911 return obj[key];
15912 }
15913 }
15914 if (!obj || obj === exp || !HOP(obj, key))
15915 return this;
15916
15917 if (typeof obj == "function")
15918 switch (key) {
15919 case "name":
15920 return obj.node.name ? obj.node.name.name : "";
15921 case "length":
15922 return obj.node.length_property();
15923 default:
15924 return this;
15925 }
15926 }
15927 return obj[key];
15928 }
15929 return this;
15930});
15931
15932def_eval(AST_Call, function (compressor, depth, ast_chain) {
15933 var exp = this.expression;
15934
15935 if (ast_chain) {
15936 const callee = exp._eval(compressor, depth, ast_chain);
15937 if (callee === nullish || (this.optional && callee == null)) return nullish;
15938 }
15939
15940 if (compressor.option("unsafe") && exp instanceof AST_PropAccess) {
15941 var key = exp.property;
15942 if (key instanceof AST_Node) {
15943 key = key._eval(compressor, depth);
15944 if (typeof key !== "string" && typeof key !== "number")
15945 return this;
15946 }
15947 var val;
15948 var e = exp.expression;
15949 if (is_undeclared_ref(e)) {
15950 var first_arg = e.name === "hasOwnProperty" &&
15951 key === "call" &&
15952 (this.args[0] && this.args[0].evaluate(compressor));
15953
15954 first_arg = first_arg instanceof AST_Dot ? first_arg.expression : first_arg;
15955
15956 if ((first_arg == null || first_arg.thedef && first_arg.thedef.undeclared)) {
15957 return this.clone();
15958 }
15959 if (!compressor.is_pure_native_static_fn(e.name, key)) return this;
15960 val = global_objs[e.name];
15961 } else {
15962 val = e._eval(compressor, depth + 1, /* don't pass ast_chain (exponential work) */);
15963
15964 if (val === e || !val)
15965 return this;
15966 if (!compressor.is_pure_native_method(val.constructor.name, key))
15967 return this;
15968 }
15969 var args = [];
15970 for (var i = 0, len = this.args.length; i < len; i++) {
15971 var arg = this.args[i];
15972 var value = arg._eval(compressor, depth);
15973 if (arg === value)
15974 return this;
15975 if (arg instanceof AST_Lambda)
15976 return this;
15977 args.push(value);
15978 }
15979 try {
15980 return val[key].apply(val, args);
15981 } catch (ex) {
15982 // We don't really care
15983 }
15984 }
15985 return this;
15986});
15987
15988// Also a subclass of AST_Call
15989def_eval(AST_New, return_this);
15990
15991/***********************************************************************
15992
15993 A JavaScript tokenizer / parser / beautifier / compressor.
15994 https://github.com/mishoo/UglifyJS2
15995
15996 -------------------------------- (C) ---------------------------------
15997
15998 Author: Mihai Bazon
15999 <mihai.bazon@gmail.com>
16000 http://mihai.bazon.net/blog
16001
16002 Distributed under the BSD license:
16003
16004 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
16005
16006 Redistribution and use in source and binary forms, with or without
16007 modification, are permitted provided that the following conditions
16008 are met:
16009
16010 * Redistributions of source code must retain the above
16011 copyright notice, this list of conditions and the following
16012 disclaimer.
16013
16014 * Redistributions in binary form must reproduce the above
16015 copyright notice, this list of conditions and the following
16016 disclaimer in the documentation and/or other materials
16017 provided with the distribution.
16018
16019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
16020 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16021 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16022 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
16023 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
16024 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
16025 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
16026 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
16027 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
16028 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
16029 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
16030 SUCH DAMAGE.
16031
16032 ***********************************************************************/
16033
16034// AST_Node#drop_side_effect_free() gets called when we don't care about the value,
16035// only about side effects. We'll be defining this method for each node type in this module
16036//
16037// Examples:
16038// foo++ -> foo++
16039// 1 + func() -> func()
16040// 10 -> (nothing)
16041// knownPureFunc(foo++) -> foo++
16042
16043function def_drop_side_effect_free(node_or_nodes, func) {
16044 for (const node of [].concat(node_or_nodes)) {
16045 node.DEFMETHOD("drop_side_effect_free", func);
16046 }
16047}
16048
16049// Drop side-effect-free elements from an array of expressions.
16050// Returns an array of expressions with side-effects or null
16051// if all elements were dropped. Note: original array may be
16052// returned if nothing changed.
16053function trim(nodes, compressor, first_in_statement) {
16054 var len = nodes.length;
16055 if (!len) return null;
16056
16057 var ret = [], changed = false;
16058 for (var i = 0; i < len; i++) {
16059 var node = nodes[i].drop_side_effect_free(compressor, first_in_statement);
16060 changed |= node !== nodes[i];
16061 if (node) {
16062 ret.push(node);
16063 first_in_statement = false;
16064 }
16065 }
16066 return changed ? ret.length ? ret : null : nodes;
16067}
16068
16069def_drop_side_effect_free(AST_Node, return_this);
16070def_drop_side_effect_free(AST_Constant, return_null);
16071def_drop_side_effect_free(AST_This, return_null);
16072
16073def_drop_side_effect_free(AST_Call, function (compressor, first_in_statement) {
16074 if (is_nullish_shortcircuited(this, compressor)) {
16075 return this.expression.drop_side_effect_free(compressor, first_in_statement);
16076 }
16077
16078 if (!this.is_callee_pure(compressor)) {
16079 if (this.expression.is_call_pure(compressor)) {
16080 var exprs = this.args.slice();
16081 exprs.unshift(this.expression.expression);
16082 exprs = trim(exprs, compressor, first_in_statement);
16083 return exprs && make_sequence(this, exprs);
16084 }
16085 if (is_func_expr(this.expression)
16086 && (!this.expression.name || !this.expression.name.definition().references.length)) {
16087 var node = this.clone();
16088 node.expression.process_expression(false, compressor);
16089 return node;
16090 }
16091 return this;
16092 }
16093
16094 var args = trim(this.args, compressor, first_in_statement);
16095 return args && make_sequence(this, args);
16096});
16097
16098def_drop_side_effect_free(AST_DynamicImport, function (compressor, first_in_statement) {
16099 if (this.phase !== "source") return this;
16100 var args = trim(this.args, compressor, first_in_statement);
16101 return args && make_sequence(this, args);
16102});
16103
16104def_drop_side_effect_free(AST_Accessor, return_null);
16105
16106def_drop_side_effect_free(AST_Function, return_null);
16107
16108def_drop_side_effect_free(AST_Arrow, return_null);
16109
16110def_drop_side_effect_free(AST_Class, function (compressor) {
16111 const with_effects = [];
16112
16113 if (this.is_self_referential() && this.has_side_effects(compressor)) {
16114 return this;
16115 }
16116
16117 const trimmed_extends = this.extends && this.extends.drop_side_effect_free(compressor);
16118 if (trimmed_extends) with_effects.push(trimmed_extends);
16119
16120 for (const prop of this.properties) {
16121 if (prop instanceof AST_ClassStaticBlock) {
16122 if (prop.has_side_effects(compressor)) {
16123 return this; // Be cautious about these
16124 }
16125 } else {
16126 const trimmed_prop = prop.drop_side_effect_free(compressor);
16127 if (trimmed_prop) with_effects.push(trimmed_prop);
16128 }
16129 }
16130
16131 if (!with_effects.length)
16132 return null;
16133
16134 const exprs = make_sequence(this, with_effects);
16135 if (this instanceof AST_DefClass) {
16136 // We want a statement
16137 return make_node(AST_SimpleStatement, this, { body: exprs });
16138 } else {
16139 return exprs;
16140 }
16141});
16142
16143def_drop_side_effect_free([
16144 AST_ClassProperty,
16145 AST_ClassPrivateProperty,
16146], function (compressor) {
16147 const key = this.computed_key() && this.key.drop_side_effect_free(compressor);
16148
16149 const value = this.static && this.value
16150 && this.value.drop_side_effect_free(compressor);
16151
16152 if (key && value)
16153 return make_sequence(this, [key, value]);
16154 return key || value || null;
16155});
16156
16157def_drop_side_effect_free(AST_Binary, function (compressor, first_in_statement) {
16158 var right = this.right.drop_side_effect_free(compressor);
16159 if (!right)
16160 return this.left.drop_side_effect_free(compressor, first_in_statement);
16161 if (lazy_op.has(this.operator)) {
16162 if (right === this.right)
16163 return this;
16164 var node = this.clone();
16165 node.right = right;
16166 return node;
16167 } else {
16168 var left = this.left.drop_side_effect_free(compressor, first_in_statement);
16169 if (!left)
16170 return this.right.drop_side_effect_free(compressor, first_in_statement);
16171 return make_sequence(this, [left, right]);
16172 }
16173});
16174
16175def_drop_side_effect_free(AST_Assign, function (compressor) {
16176 if (this.logical)
16177 return this;
16178
16179 var left = this.left;
16180 if (left.has_side_effects(compressor)
16181 || compressor.has_directive("use strict")
16182 && left instanceof AST_PropAccess
16183 && left.expression.is_constant()) {
16184 return this;
16185 }
16186 set_flag(this, WRITE_ONLY);
16187 while (left instanceof AST_PropAccess) {
16188 left = left.expression;
16189 }
16190 if (left.is_constant_expression(compressor.find_parent(AST_Scope))) {
16191 return this.right.drop_side_effect_free(compressor);
16192 }
16193 return this;
16194});
16195
16196def_drop_side_effect_free(AST_Conditional, function (compressor) {
16197 var consequent = this.consequent.drop_side_effect_free(compressor);
16198 var alternative = this.alternative.drop_side_effect_free(compressor);
16199 if (consequent === this.consequent && alternative === this.alternative)
16200 return this;
16201 if (!consequent)
16202 return alternative ? make_node(AST_Binary, this, {
16203 operator: "||",
16204 left: this.condition,
16205 right: alternative
16206 }) : this.condition.drop_side_effect_free(compressor);
16207 if (!alternative)
16208 return make_node(AST_Binary, this, {
16209 operator: "&&",
16210 left: this.condition,
16211 right: consequent
16212 });
16213 var node = this.clone();
16214 node.consequent = consequent;
16215 node.alternative = alternative;
16216 return node;
16217});
16218
16219def_drop_side_effect_free(AST_Unary, function (compressor, first_in_statement) {
16220 if (unary_side_effects.has(this.operator)) {
16221 if (!this.expression.has_side_effects(compressor)) {
16222 set_flag(this, WRITE_ONLY);
16223 } else {
16224 clear_flag(this, WRITE_ONLY);
16225 }
16226 return this;
16227 }
16228 if (this.operator == "typeof" && this.expression instanceof AST_SymbolRef)
16229 return null;
16230 var expression = this.expression.drop_side_effect_free(compressor, first_in_statement);
16231 if (first_in_statement && expression && is_iife_call(expression)) {
16232 if (expression === this.expression && this.operator == "!")
16233 return this;
16234 return expression.negate(compressor, first_in_statement);
16235 }
16236 return expression;
16237});
16238
16239def_drop_side_effect_free(AST_SymbolRef, function (compressor) {
16240 const safe_access = this.is_declared(compressor)
16241 || pure_prop_access_globals.has(this.name);
16242 return safe_access ? null : this;
16243});
16244
16245def_drop_side_effect_free(AST_Object, function (compressor, first_in_statement) {
16246 var values = trim(this.properties, compressor, first_in_statement);
16247 return values && make_sequence(this, values);
16248});
16249
16250def_drop_side_effect_free(AST_ObjectKeyVal, function (compressor, first_in_statement) {
16251 const computed_key = this.key instanceof AST_Node;
16252 const key = computed_key && this.key.drop_side_effect_free(compressor, first_in_statement);
16253 const value = this.value.drop_side_effect_free(compressor, first_in_statement);
16254 if (key && value) {
16255 return make_sequence(this, [key, value]);
16256 }
16257 return key || value;
16258});
16259
16260def_drop_side_effect_free([
16261 AST_ConciseMethod,
16262 AST_ObjectGetter,
16263 AST_ObjectSetter,
16264], function (compressor, first_in_statement) {
16265 return this.computed_key() ? this.key.drop_side_effect_free(compressor, first_in_statement) : null;
16266});
16267
16268def_drop_side_effect_free([
16269 AST_PrivateMethod,
16270 AST_PrivateGetter,
16271 AST_PrivateSetter,
16272], function () {
16273 return null;
16274});
16275
16276def_drop_side_effect_free(AST_Array, function (compressor, first_in_statement) {
16277 var values = trim(this.elements, compressor, first_in_statement);
16278 return values && make_sequence(this, values);
16279});
16280
16281def_drop_side_effect_free(AST_Dot, function (compressor, first_in_statement) {
16282 if (is_nullish_shortcircuited(this, compressor)) {
16283 return this.expression.drop_side_effect_free(compressor, first_in_statement);
16284 }
16285 if (!this.optional && this.expression.may_throw_on_access(compressor)) {
16286 return this;
16287 }
16288
16289 return this.expression.drop_side_effect_free(compressor, first_in_statement);
16290});
16291
16292def_drop_side_effect_free(AST_Sub, function (compressor, first_in_statement) {
16293 if (is_nullish_shortcircuited(this, compressor)) {
16294 return this.expression.drop_side_effect_free(compressor, first_in_statement);
16295 }
16296 if (!this.optional && this.expression.may_throw_on_access(compressor)) {
16297 return this;
16298 }
16299
16300 var property = this.property.drop_side_effect_free(compressor);
16301 if (property && this.optional) return this;
16302
16303 var expression = this.expression.drop_side_effect_free(compressor, first_in_statement);
16304
16305 if (expression && property) return make_sequence(this, [expression, property]);
16306 return expression || property;
16307});
16308
16309def_drop_side_effect_free(AST_Chain, function (compressor, first_in_statement) {
16310 return this.expression.drop_side_effect_free(compressor, first_in_statement);
16311});
16312
16313def_drop_side_effect_free(AST_Sequence, function (compressor) {
16314 var last = this.tail_node();
16315 var expr = last.drop_side_effect_free(compressor);
16316 if (expr === last)
16317 return this;
16318 var expressions = this.expressions.slice(0, -1);
16319 if (expr)
16320 expressions.push(expr);
16321 if (!expressions.length) {
16322 return make_node(AST_Number, this, { value: 0 });
16323 }
16324 return make_sequence(this, expressions);
16325});
16326
16327def_drop_side_effect_free(AST_Expansion, function (compressor, first_in_statement) {
16328 return this.expression.drop_side_effect_free(compressor, first_in_statement);
16329});
16330
16331def_drop_side_effect_free(AST_TemplateSegment, return_null);
16332
16333def_drop_side_effect_free(AST_TemplateString, function (compressor) {
16334 var values = trim(this.segments, compressor, first_in_statement);
16335 return values && make_sequence(this, values);
16336});
16337
16338/***********************************************************************
16339
16340 A JavaScript tokenizer / parser / beautifier / compressor.
16341 https://github.com/mishoo/UglifyJS2
16342
16343 -------------------------------- (C) ---------------------------------
16344
16345 Author: Mihai Bazon
16346 <mihai.bazon@gmail.com>
16347 http://mihai.bazon.net/blog
16348
16349 Distributed under the BSD license:
16350
16351 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
16352
16353 Redistribution and use in source and binary forms, with or without
16354 modification, are permitted provided that the following conditions
16355 are met:
16356
16357 * Redistributions of source code must retain the above
16358 copyright notice, this list of conditions and the following
16359 disclaimer.
16360
16361 * Redistributions in binary form must reproduce the above
16362 copyright notice, this list of conditions and the following
16363 disclaimer in the documentation and/or other materials
16364 provided with the distribution.
16365
16366 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
16367 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16368 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16369 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
16370 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
16371 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
16372 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
16373 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
16374 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
16375 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
16376 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
16377 SUCH DAMAGE.
16378
16379 ***********************************************************************/
16380
16381const r_keep_assign = /keep_assign/;
16382
16383/** Drop unused variables from this scope */
16384AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
16385 if (!compressor.option("unused")) return;
16386 if (compressor.has_directive("use asm")) return;
16387 if (!this.variables) return; // not really a scope (eg: AST_Class)
16388
16389 var self = this;
16390 if (self.pinned()) return;
16391 var drop_funcs = !(self instanceof AST_Toplevel) || compressor.toplevel.funcs;
16392 var drop_vars = !(self instanceof AST_Toplevel) || compressor.toplevel.vars;
16393 const assign_as_unused = r_keep_assign.test(compressor.option("unused")) ? return_false : function(node) {
16394 if (node instanceof AST_Assign
16395 && !node.logical
16396 && (has_flag(node, WRITE_ONLY) || node.operator == "=")
16397 ) {
16398 return node.left;
16399 }
16400 if (node instanceof AST_Unary && has_flag(node, WRITE_ONLY)) {
16401 return node.expression;
16402 }
16403 };
16404 var in_use_ids = new Map();
16405 var fixed_ids = new Map();
16406 if (self instanceof AST_Toplevel && compressor.top_retain) {
16407 self.variables.forEach(function(def) {
16408 if (compressor.top_retain(def)) {
16409 in_use_ids.set(def.id, def);
16410 }
16411 });
16412 }
16413 var var_defs_by_id = new Map();
16414 var initializations = new Map();
16415
16416 // pass 1: find out which symbols are directly used in
16417 // this scope (not in nested scopes).
16418 var scope = this;
16419 var tw = new TreeWalker(function(node, descend) {
16420 if (node instanceof AST_Lambda && node.uses_arguments && !tw.has_directive("use strict")) {
16421 node.argnames.forEach(function(argname) {
16422 if (!(argname instanceof AST_SymbolDeclaration)) return;
16423 var def = argname.definition();
16424 in_use_ids.set(def.id, def);
16425 });
16426 }
16427 if (node === self) return;
16428 if (node instanceof AST_Class && node.has_side_effects(compressor)) {
16429 if (node.is_self_referential()) {
16430 descend();
16431 } else {
16432 node.visit_nondeferred_class_parts(tw);
16433 }
16434 }
16435 if (node instanceof AST_Defun || node instanceof AST_DefClass) {
16436 var node_def = node.name.definition();
16437 const in_export = tw.parent() instanceof AST_Export;
16438 if (in_export || !drop_funcs && scope === self) {
16439 if (node_def.global) {
16440 in_use_ids.set(node_def.id, node_def);
16441 }
16442 }
16443
16444 map_add(initializations, node_def.id, node);
16445 return true; // don't go in nested scopes
16446 }
16447 // In the root scope, we drop things. In inner scopes, we just check for uses.
16448 const in_root_scope = scope === self;
16449 if (node instanceof AST_SymbolFunarg && in_root_scope) {
16450 map_add(var_defs_by_id, node.definition().id, node);
16451 }
16452 if (node instanceof AST_Definitions && in_root_scope) {
16453 const in_export = tw.parent() instanceof AST_Export;
16454 node.definitions.forEach(function(def) {
16455 if (def.name instanceof AST_SymbolVar) {
16456 map_add(var_defs_by_id, def.name.definition().id, def);
16457 }
16458 if (in_export || !drop_vars) {
16459 walk(def.name, node => {
16460 if (node instanceof AST_SymbolDeclaration) {
16461 const def = node.definition();
16462 if (def.global) {
16463 in_use_ids.set(def.id, def);
16464 }
16465 }
16466 });
16467 }
16468 if (def.name instanceof AST_Destructuring) {
16469 def.walk(tw);
16470 }
16471 if (def.name instanceof AST_SymbolDeclaration && def.value) {
16472 var node_def = def.name.definition();
16473 map_add(initializations, node_def.id, def.value);
16474 if (!node_def.chained && def.name.fixed_value() === def.value) {
16475 fixed_ids.set(node_def.id, def);
16476 }
16477 if (def.value.has_side_effects(compressor)) {
16478 def.value.walk(tw);
16479 }
16480 }
16481 });
16482 return true;
16483 }
16484 return scan_ref_scoped(node, descend);
16485 });
16486 self.walk(tw);
16487
16488 // pass 2: for every used symbol we need to walk its
16489 // initialization code to figure out if it uses other
16490 // symbols (that may not be in_use).
16491 tw = new TreeWalker(scan_ref_scoped);
16492 in_use_ids.forEach(function (def) {
16493 var init = initializations.get(def.id);
16494 if (init) init.forEach(function(init) {
16495 init.walk(tw);
16496 });
16497 });
16498
16499 // pass 3: we should drop declarations not in_use
16500 var tt = new TreeTransformer(
16501 function before(node, descend, in_list) {
16502 var parent = tt.parent();
16503 if (drop_vars) {
16504 const sym = assign_as_unused(node);
16505 if (sym instanceof AST_SymbolRef) {
16506 var def = sym.definition();
16507 var in_use = in_use_ids.has(def.id);
16508 if (node instanceof AST_Assign) {
16509 if (!in_use || fixed_ids.has(def.id) && fixed_ids.get(def.id) !== node) {
16510 const assignee = node.right.transform(tt);
16511 if (!in_use && !assignee.has_side_effects(compressor) && !is_used_in_expression(tt)) {
16512 return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 });
16513 }
16514 return maintain_this_binding(parent, node, assignee);
16515 }
16516 } else if (!in_use) {
16517 return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 });
16518 }
16519 }
16520 }
16521 if (scope !== self) return;
16522 var def;
16523 if (node.name
16524 && (node instanceof AST_ClassExpression
16525 && !keep_name(compressor.option("keep_classnames"), (def = node.name.definition()).name)
16526 || node instanceof AST_Function
16527 && !keep_name(compressor.option("keep_fnames"), (def = node.name.definition()).name))) {
16528 // any declarations with same name will overshadow
16529 // name of this anonymous function and can therefore
16530 // never be used anywhere
16531 if (!in_use_ids.has(def.id) || def.orig.length > 1) node.name = null;
16532 }
16533 if (node instanceof AST_Lambda && !(node instanceof AST_Accessor)) {
16534 var trim =
16535 !compressor.option("keep_fargs")
16536 // Is this an IIFE that won't refer to its name?
16537 || parent instanceof AST_Call
16538 && parent.expression === node
16539 && !node.pinned()
16540 && (!node.name || node.name.unreferenced());
16541 for (var a = node.argnames, i = a.length; --i >= 0;) {
16542 var sym = a[i];
16543 if (sym instanceof AST_Expansion) {
16544 sym = sym.expression;
16545 }
16546 if (sym instanceof AST_DefaultAssign) {
16547 sym = sym.left;
16548 }
16549 // Do not drop destructuring arguments.
16550 // They constitute a type assertion of sorts
16551 if (
16552 !(sym instanceof AST_Destructuring)
16553 && !in_use_ids.has(sym.definition().id)
16554 ) {
16555 set_flag(sym, UNUSED);
16556 if (trim) {
16557 a.pop();
16558 }
16559 } else {
16560 trim = false;
16561 }
16562 }
16563 }
16564 if (node instanceof AST_DefClass && node !== self) {
16565 const def = node.name.definition();
16566 descend(node, this);
16567 const keep_class = def.global && !drop_funcs || in_use_ids.has(def.id);
16568 if (!keep_class) {
16569 const kept = node.drop_side_effect_free(compressor);
16570 if (kept == null) {
16571 def.eliminated++;
16572 return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
16573 }
16574 return kept;
16575 }
16576 return node;
16577 }
16578 if (node instanceof AST_Defun && node !== self) {
16579 const def = node.name.definition();
16580 const keep = def.global && !drop_funcs || in_use_ids.has(def.id);
16581 if (!keep) {
16582 def.eliminated++;
16583 return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
16584 }
16585 }
16586 if (node instanceof AST_Definitions && !(parent instanceof AST_ForIn && parent.init === node)) {
16587 var drop_block = !(parent instanceof AST_Toplevel) && !(node instanceof AST_Var);
16588 // place uninitialized names at the start
16589 var body = [], head = [], tail = [];
16590 // for unused names whose initialization has
16591 // side effects, we can cascade the init. code
16592 // into the next one, or next statement.
16593 var side_effects = [];
16594 node.definitions.forEach(function(def) {
16595 if (def.value) def.value = def.value.transform(tt);
16596 var is_destructure = def.name instanceof AST_Destructuring;
16597 var sym = is_destructure
16598 ? new SymbolDef(null, { name: "<destructure>" }) /* fake SymbolDef */
16599 : def.name.definition();
16600 if (drop_block && sym.global) return tail.push(def);
16601 if (!(drop_vars || drop_block)
16602 || is_destructure
16603 && (def.name.names.length
16604 || def.name.is_array
16605 || compressor.option("pure_getters") != true)
16606 || in_use_ids.has(sym.id)
16607 ) {
16608 if (def.value && fixed_ids.has(sym.id) && fixed_ids.get(sym.id) !== def) {
16609 def.value = def.value.drop_side_effect_free(compressor);
16610 }
16611 if (def.name instanceof AST_SymbolVar) {
16612 var var_defs = var_defs_by_id.get(sym.id);
16613 if (var_defs.length > 1 && (!def.value || sym.orig.indexOf(def.name) > sym.eliminated)) {
16614 if (def.value) {
16615 var ref = make_node(AST_SymbolRef, def.name, def.name);
16616 sym.references.push(ref);
16617 var assign = make_node(AST_Assign, def, {
16618 operator: "=",
16619 logical: false,
16620 left: ref,
16621 right: def.value
16622 });
16623 if (fixed_ids.get(sym.id) === def) {
16624 fixed_ids.set(sym.id, assign);
16625 }
16626 side_effects.push(assign.transform(tt));
16627 }
16628 remove(var_defs, def);
16629 sym.eliminated++;
16630 return;
16631 }
16632 }
16633 if (def.value) {
16634 if (side_effects.length > 0) {
16635 if (tail.length > 0) {
16636 side_effects.push(def.value);
16637 def.value = make_sequence(def.value, side_effects);
16638 } else {
16639 body.push(make_node(AST_SimpleStatement, node, {
16640 body: make_sequence(node, side_effects)
16641 }));
16642 }
16643 side_effects = [];
16644 }
16645 tail.push(def);
16646 } else {
16647 head.push(def);
16648 }
16649 } else if (sym.orig[0] instanceof AST_SymbolCatch) {
16650 var value = def.value && def.value.drop_side_effect_free(compressor);
16651 if (value) side_effects.push(value);
16652 def.value = null;
16653 head.push(def);
16654 } else {
16655 var value = def.value && def.value.drop_side_effect_free(compressor);
16656 if (value) {
16657 side_effects.push(value);
16658 }
16659 sym.eliminated++;
16660 }
16661 });
16662 if (head.length > 0 || tail.length > 0) {
16663 node.definitions = head.concat(tail);
16664 body.push(node);
16665 }
16666 if (side_effects.length > 0) {
16667 body.push(make_node(AST_SimpleStatement, node, {
16668 body: make_sequence(node, side_effects)
16669 }));
16670 }
16671 switch (body.length) {
16672 case 0:
16673 return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
16674 case 1:
16675 return body[0];
16676 default:
16677 return in_list ? MAP.splice(body) : make_node(AST_BlockStatement, node, { body });
16678 }
16679 }
16680 // certain combination of unused name + side effect leads to:
16681 // https://github.com/mishoo/UglifyJS2/issues/44
16682 // https://github.com/mishoo/UglifyJS2/issues/1830
16683 // https://github.com/mishoo/UglifyJS2/issues/1838
16684 // that's an invalid AST.
16685 // We fix it at this stage by moving the `var` outside the `for`.
16686 if (node instanceof AST_For) {
16687 descend(node, this);
16688 var block;
16689 if (node.init instanceof AST_BlockStatement) {
16690 block = node.init;
16691 node.init = block.body.pop();
16692 block.body.push(node);
16693 }
16694 if (node.init instanceof AST_SimpleStatement) {
16695 node.init = node.init.body;
16696 } else if (is_empty(node.init)) {
16697 node.init = null;
16698 }
16699 return !block ? node : in_list ? MAP.splice(block.body) : block;
16700 }
16701 if (node instanceof AST_LabeledStatement
16702 && node.body instanceof AST_For
16703 ) {
16704 descend(node, this);
16705 if (node.body instanceof AST_BlockStatement) {
16706 var block = node.body;
16707 node.body = block.body.pop();
16708 block.body.push(node);
16709 return in_list ? MAP.splice(block.body) : block;
16710 }
16711 return node;
16712 }
16713 if (node instanceof AST_BlockStatement) {
16714 descend(node, this);
16715 if (in_list && node.body.every(can_be_evicted_from_block)) {
16716 return MAP.splice(node.body);
16717 }
16718 return node;
16719 }
16720 if (node instanceof AST_Scope && !(node instanceof AST_ClassStaticBlock)) {
16721 const save_scope = scope;
16722 scope = node;
16723 descend(node, this);
16724 scope = save_scope;
16725 return node;
16726 }
16727 },
16728 function after(node, in_list) {
16729 if (node instanceof AST_Sequence) {
16730 switch (node.expressions.length) {
16731 case 0: return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 });
16732 case 1: return node.expressions[0];
16733 }
16734 }
16735 }
16736 );
16737
16738 self.transform(tt);
16739
16740 function scan_ref_scoped(node, descend) {
16741 var node_def;
16742 const sym = assign_as_unused(node);
16743 if (sym instanceof AST_SymbolRef
16744 && !is_ref_of(node.left, AST_SymbolBlockDeclaration)
16745 && self.variables.get(sym.name) === (node_def = sym.definition())
16746 ) {
16747 if (node instanceof AST_Assign) {
16748 node.right.walk(tw);
16749 if (!node_def.chained && node.left.fixed_value() === node.right) {
16750 fixed_ids.set(node_def.id, node);
16751 }
16752 }
16753 return true;
16754 }
16755 if (node instanceof AST_SymbolRef) {
16756 node_def = node.definition();
16757 if (!in_use_ids.has(node_def.id)) {
16758 in_use_ids.set(node_def.id, node_def);
16759 if (node_def.orig[0] instanceof AST_SymbolCatch) {
16760 const redef = node_def.scope.is_block_scope()
16761 && node_def.scope.get_defun_scope().variables.get(node_def.name);
16762 if (redef) in_use_ids.set(redef.id, redef);
16763 }
16764 }
16765 return true;
16766 }
16767 if (node instanceof AST_Class) {
16768 descend();
16769 return true;
16770 }
16771 if (node instanceof AST_Scope && !(node instanceof AST_ClassStaticBlock)) {
16772 var save_scope = scope;
16773 scope = node;
16774 descend();
16775 scope = save_scope;
16776 return true;
16777 }
16778 }
16779});
16780
16781/***********************************************************************
16782
16783 A JavaScript tokenizer / parser / beautifier / compressor.
16784 https://github.com/mishoo/UglifyJS2
16785
16786 -------------------------------- (C) ---------------------------------
16787
16788 Author: Mihai Bazon
16789 <mihai.bazon@gmail.com>
16790 http://mihai.bazon.net/blog
16791
16792 Distributed under the BSD license:
16793
16794 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
16795
16796 Redistribution and use in source and binary forms, with or without
16797 modification, are permitted provided that the following conditions
16798 are met:
16799
16800 * Redistributions of source code must retain the above
16801 copyright notice, this list of conditions and the following
16802 disclaimer.
16803
16804 * Redistributions in binary form must reproduce the above
16805 copyright notice, this list of conditions and the following
16806 disclaimer in the documentation and/or other materials
16807 provided with the distribution.
16808
16809 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
16810 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16811 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16812 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
16813 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
16814 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
16815 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
16816 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
16817 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
16818 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
16819 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
16820 SUCH DAMAGE.
16821
16822 ***********************************************************************/
16823
16824/**
16825 * Define the method AST_Node#reduce_vars, which goes through the AST in
16826 * execution order to perform basic flow analysis
16827 */
16828function def_reduce_vars(node, func) {
16829 node.DEFMETHOD("reduce_vars", func);
16830}
16831
16832def_reduce_vars(AST_Node, noop);
16833
16834/** Clear definition properties */
16835function reset_def(compressor, def) {
16836 def.assignments = 0;
16837 def.chained = false;
16838 def.direct_access = false;
16839 def.escaped = 0;
16840 def.recursive_refs = 0;
16841 def.references = [];
16842 def.single_use = undefined;
16843 if (
16844 def.scope.pinned()
16845 || (def.orig[0] instanceof AST_SymbolFunarg && def.scope.uses_arguments)
16846 ) {
16847 def.fixed = false;
16848 } else if (def.orig[0] instanceof AST_SymbolConst || !compressor.exposed(def)) {
16849 def.fixed = def.init;
16850 } else {
16851 def.fixed = false;
16852 }
16853}
16854
16855function reset_variables(tw, compressor, node) {
16856 node.variables.forEach(function(def) {
16857 reset_def(compressor, def);
16858 if (def.fixed === null) {
16859 tw.defs_to_safe_ids.set(def.id, tw.safe_ids);
16860 mark(tw, def, true);
16861 } else if (def.fixed) {
16862 tw.loop_ids.set(def.id, tw.in_loop);
16863 mark(tw, def, true);
16864 }
16865 });
16866}
16867
16868function reset_block_variables(compressor, node) {
16869 if (node.block_scope) node.block_scope.variables.forEach((def) => {
16870 reset_def(compressor, def);
16871 });
16872}
16873
16874function push(tw) {
16875 tw.safe_ids = Object.create(tw.safe_ids);
16876}
16877
16878function pop(tw) {
16879 tw.safe_ids = Object.getPrototypeOf(tw.safe_ids);
16880}
16881
16882function mark(tw, def, safe) {
16883 tw.safe_ids[def.id] = safe;
16884}
16885
16886function safe_to_read(tw, def) {
16887 if (def.single_use == "m") return false;
16888 if (tw.safe_ids[def.id]) {
16889 if (def.fixed == null) {
16890 var orig = def.orig[0];
16891 if (orig instanceof AST_SymbolFunarg || orig.name == "arguments") return false;
16892 def.fixed = make_void_0(orig);
16893 }
16894 return true;
16895 }
16896 return def.fixed instanceof AST_Defun;
16897}
16898
16899function safe_to_assign(tw, def, scope, value) {
16900 if (def.fixed === undefined) return true;
16901 let def_safe_ids;
16902 if (def.fixed === null
16903 && (def_safe_ids = tw.defs_to_safe_ids.get(def.id))
16904 ) {
16905 def_safe_ids[def.id] = false;
16906 tw.defs_to_safe_ids.delete(def.id);
16907 return true;
16908 }
16909 if (!HOP(tw.safe_ids, def.id)) return false;
16910 if (!safe_to_read(tw, def)) return false;
16911 if (def.fixed === false) return false;
16912 if (def.fixed != null && (!value || def.references.length > def.assignments)) return false;
16913 if (def.fixed instanceof AST_Defun) {
16914 return value instanceof AST_Node && def.fixed.parent_scope === scope;
16915 }
16916 return def.orig.every((sym) => {
16917 return !(sym instanceof AST_SymbolConst
16918 || sym instanceof AST_SymbolDefun
16919 || sym instanceof AST_SymbolLambda);
16920 });
16921}
16922
16923function ref_once(tw, compressor, def) {
16924 return compressor.option("unused")
16925 && !def.scope.pinned()
16926 && def.references.length - def.recursive_refs == 1
16927 && tw.loop_ids.get(def.id) === tw.in_loop;
16928}
16929
16930function is_immutable(value) {
16931 if (!value) return false;
16932 return value.is_constant()
16933 || value instanceof AST_Lambda
16934 || value instanceof AST_This;
16935}
16936
16937// A definition "escapes" when its value can leave the point of use.
16938// Example: `a = b || c`
16939// In this example, "b" and "c" are escaping, because they're going into "a"
16940//
16941// def.escaped is != 0 when it escapes.
16942//
16943// When greater than 1, it means that N chained properties will be read off
16944// of that def before an escape occurs. This is useful for evaluating
16945// property accesses, where you need to know when to stop.
16946function mark_escaped(tw, d, scope, node, value, level = 0, depth = 1) {
16947 var parent = tw.parent(level);
16948 if (value) {
16949 if (value.is_constant()) return;
16950 if (value instanceof AST_ClassExpression) return;
16951 }
16952
16953 if (
16954 parent instanceof AST_Assign && (parent.operator === "=" || parent.logical) && node === parent.right
16955 || parent instanceof AST_Call && (node !== parent.expression || parent instanceof AST_New)
16956 || parent instanceof AST_Exit && node === parent.value && node.scope !== d.scope
16957 || parent instanceof AST_VarDefLike && node === parent.value
16958 || parent instanceof AST_Yield && node === parent.value && node.scope !== d.scope
16959 ) {
16960 if (depth > 1 && !(value && value.is_constant_expression(scope))) depth = 1;
16961 if (!d.escaped || d.escaped > depth) d.escaped = depth;
16962 return;
16963 } else if (
16964 parent instanceof AST_Array
16965 || parent instanceof AST_Await
16966 || parent instanceof AST_Binary && lazy_op.has(parent.operator)
16967 || parent instanceof AST_Conditional && node !== parent.condition
16968 || parent instanceof AST_Expansion
16969 || parent instanceof AST_Sequence && node === parent.tail_node()
16970 ) {
16971 mark_escaped(tw, d, scope, parent, parent, level + 1, depth);
16972 } else if (parent instanceof AST_ObjectKeyVal && node === parent.value) {
16973 var obj = tw.parent(level + 1);
16974
16975 mark_escaped(tw, d, scope, obj, obj, level + 2, depth);
16976 } else if (parent instanceof AST_PropAccess && node === parent.expression) {
16977 value = read_property(value, parent.property);
16978
16979 mark_escaped(tw, d, scope, parent, value, level + 1, depth + 1);
16980 if (value) return;
16981 }
16982
16983 if (level > 0) return;
16984 if (parent instanceof AST_Sequence && node !== parent.tail_node()) return;
16985 if (parent instanceof AST_SimpleStatement) return;
16986
16987 d.direct_access = true;
16988}
16989
16990const suppress = node => walk(node, node => {
16991 if (!(node instanceof AST_Symbol)) return;
16992 var d = node.definition();
16993 if (!d) return;
16994 if (node instanceof AST_SymbolRef) d.references.push(node);
16995 d.fixed = false;
16996});
16997
16998def_reduce_vars(AST_Accessor, function(tw, descend, compressor) {
16999 push(tw);
17000 reset_variables(tw, compressor, this);
17001 descend();
17002 pop(tw);
17003 return true;
17004});
17005
17006def_reduce_vars(AST_Assign, function(tw, descend, compressor) {
17007 var node = this;
17008 if (node.left instanceof AST_Destructuring) {
17009 suppress(node.left);
17010 return;
17011 }
17012
17013 const finish_walk = () => {
17014 if (node.logical) {
17015 node.left.walk(tw);
17016
17017 push(tw);
17018 node.right.walk(tw);
17019 pop(tw);
17020
17021 return true;
17022 }
17023 };
17024
17025 var sym = node.left;
17026 if (!(sym instanceof AST_SymbolRef)) return finish_walk();
17027
17028 var def = sym.definition();
17029 var safe = safe_to_assign(tw, def, sym.scope, node.right);
17030 def.assignments++;
17031 if (!safe) return finish_walk();
17032
17033 var fixed = def.fixed;
17034 if (!fixed && node.operator != "=" && !node.logical) return finish_walk();
17035
17036 var eq = node.operator == "=";
17037 var value = eq ? node.right : node;
17038 if (is_modified(compressor, tw, node, value, 0)) return finish_walk();
17039
17040 def.references.push(sym);
17041
17042 if (!node.logical) {
17043 if (!eq) def.chained = true;
17044
17045 def.fixed = eq ? function() {
17046 return node.right;
17047 } : function() {
17048 return make_node(AST_Binary, node, {
17049 operator: node.operator.slice(0, -1),
17050 left: fixed instanceof AST_Node ? fixed : fixed(),
17051 right: node.right
17052 });
17053 };
17054 }
17055
17056 if (node.logical) {
17057 mark(tw, def, false);
17058 push(tw);
17059 node.right.walk(tw);
17060 pop(tw);
17061 return true;
17062 }
17063
17064 mark(tw, def, false);
17065 node.right.walk(tw);
17066 mark(tw, def, true);
17067
17068 mark_escaped(tw, def, sym.scope, node, value, 0, 1);
17069
17070 return true;
17071});
17072
17073def_reduce_vars(AST_Binary, function(tw) {
17074 if (!lazy_op.has(this.operator)) return;
17075 this.left.walk(tw);
17076 push(tw);
17077 this.right.walk(tw);
17078 pop(tw);
17079 return true;
17080});
17081
17082def_reduce_vars(AST_Block, function(tw, descend, compressor) {
17083 reset_block_variables(compressor, this);
17084});
17085
17086def_reduce_vars(AST_Case, function(tw) {
17087 push(tw);
17088 this.expression.walk(tw);
17089 pop(tw);
17090 push(tw);
17091 walk_body(this, tw);
17092 pop(tw);
17093 return true;
17094});
17095
17096def_reduce_vars(AST_Class, function(tw, descend) {
17097 clear_flag(this, INLINED);
17098 push(tw);
17099 descend();
17100 pop(tw);
17101 return true;
17102});
17103
17104def_reduce_vars(AST_ClassStaticBlock, function(tw, descend, compressor) {
17105 reset_block_variables(compressor, this);
17106});
17107
17108def_reduce_vars(AST_Conditional, function(tw) {
17109 this.condition.walk(tw);
17110 push(tw);
17111 this.consequent.walk(tw);
17112 pop(tw);
17113 push(tw);
17114 this.alternative.walk(tw);
17115 pop(tw);
17116 return true;
17117});
17118
17119def_reduce_vars(AST_Chain, function(tw, descend) {
17120 // Chains' conditions apply left-to-right, cumulatively.
17121 // If we walk normally we don't go in that order because we would pop before pushing again
17122 // Solution: AST_PropAccess and AST_Call push when they are optional, and never pop.
17123 // Then we pop everything when they are done being walked.
17124 const safe_ids = tw.safe_ids;
17125
17126 descend();
17127
17128 // Unroll back to start
17129 tw.safe_ids = safe_ids;
17130 return true;
17131});
17132
17133def_reduce_vars(AST_Call, function (tw) {
17134 this.expression.walk(tw);
17135
17136 if (this.optional) {
17137 // Never pop -- it's popped at AST_Chain above
17138 push(tw);
17139 }
17140
17141 for (const arg of this.args) arg.walk(tw);
17142
17143 return true;
17144});
17145
17146def_reduce_vars(AST_PropAccess, function (tw) {
17147 if (!this.optional) return;
17148
17149 this.expression.walk(tw);
17150
17151 // Never pop -- it's popped at AST_Chain above
17152 push(tw);
17153
17154 if (this.property instanceof AST_Node) this.property.walk(tw);
17155
17156 return true;
17157});
17158
17159def_reduce_vars(AST_Default, function(tw, descend) {
17160 push(tw);
17161 descend();
17162 pop(tw);
17163 return true;
17164});
17165
17166function mark_lambda(tw, descend, compressor) {
17167 clear_flag(this, INLINED);
17168 push(tw);
17169 reset_variables(tw, compressor, this);
17170
17171 var iife;
17172 if (!this.name
17173 && !this.uses_arguments
17174 && !this.pinned()
17175 && (iife = tw.parent()) instanceof AST_Call
17176 && iife.expression === this
17177 && !iife.args.some(arg => arg instanceof AST_Expansion)
17178 && this.argnames.every(arg_name => arg_name instanceof AST_Symbol)
17179 ) {
17180 // Virtually turn IIFE parameters into variable definitions:
17181 // (function(a,b) {...})(c,d) => (function() {var a=c,b=d; ...})()
17182 // So existing transformation rules can work on them.
17183 this.argnames.forEach((arg, i) => {
17184 if (!arg.definition) return;
17185 var d = arg.definition();
17186 // Avoid setting fixed when there's more than one origin for a variable value
17187 if (d.orig.length > 1) return;
17188 if (d.fixed === undefined && (!this.uses_arguments || tw.has_directive("use strict"))) {
17189 d.fixed = function() {
17190 return iife.args[i] || make_void_0(iife);
17191 };
17192 tw.loop_ids.set(d.id, tw.in_loop);
17193 mark(tw, d, true);
17194 } else {
17195 d.fixed = false;
17196 }
17197 });
17198 }
17199
17200 descend();
17201 pop(tw);
17202
17203 handle_defined_after_hoist(this);
17204
17205 return true;
17206}
17207
17208/**
17209 * It's possible for a hoisted function to use something that's not defined yet. Example:
17210 *
17211 * hoisted();
17212 * var defined_after = true;
17213 * function hoisted() {
17214 * // use defined_after
17215 * }
17216 *
17217 * Or even indirectly:
17218 *
17219 * B();
17220 * var defined_after = true;
17221 * function A() {
17222 * // use defined_after
17223 * }
17224 * function B() {
17225 * A();
17226 * }
17227 *
17228 * Access a variable before declaration will either throw a ReferenceError
17229 * (if the variable is declared with `let` or `const`),
17230 * or get an `undefined` (if the variable is declared with `var`).
17231 *
17232 * If the variable is inlined into the function, the behavior will change.
17233 *
17234 * This function is called on the parent to disallow inlining of such variables,
17235 */
17236function handle_defined_after_hoist(parent) {
17237 const defuns = [];
17238 walk(parent, node => {
17239 if (node === parent) return;
17240 if (node instanceof AST_Defun) {
17241 defuns.push(node);
17242 return true;
17243 }
17244 if (
17245 node instanceof AST_Scope
17246 || node instanceof AST_SimpleStatement
17247 ) return true;
17248 });
17249
17250 // `defun` id to array of `defun` it uses
17251 const defun_dependencies_map = new Map();
17252 // `defun` id to array of enclosing `def` that are used by the function
17253 const dependencies_map = new Map();
17254 // all symbol ids that will be tracked for read/write
17255 const symbols_of_interest = new Set();
17256 const defuns_of_interest = new Set();
17257
17258 for (const defun of defuns) {
17259 const fname_def = defun.name.definition();
17260 const enclosing_defs = [];
17261
17262 for (const def of defun.enclosed) {
17263 if (
17264 def.fixed === false
17265 || def === fname_def
17266 || def.scope.get_defun_scope() !== parent
17267 ) {
17268 continue;
17269 }
17270
17271 symbols_of_interest.add(def.id);
17272
17273 // found a reference to another function
17274 if (
17275 def.assignments === 0
17276 && def.orig.length === 1
17277 && def.orig[0] instanceof AST_SymbolDefun
17278 ) {
17279 defuns_of_interest.add(def.id);
17280 symbols_of_interest.add(def.id);
17281
17282 defuns_of_interest.add(fname_def.id);
17283 symbols_of_interest.add(fname_def.id);
17284
17285 if (!defun_dependencies_map.has(fname_def.id)) {
17286 defun_dependencies_map.set(fname_def.id, []);
17287 }
17288 defun_dependencies_map.get(fname_def.id).push(def.id);
17289
17290 continue;
17291 }
17292
17293 enclosing_defs.push(def);
17294 }
17295
17296 if (enclosing_defs.length) {
17297 dependencies_map.set(fname_def.id, enclosing_defs);
17298 defuns_of_interest.add(fname_def.id);
17299 symbols_of_interest.add(fname_def.id);
17300 }
17301 }
17302
17303 // No defuns use outside constants
17304 if (!dependencies_map.size) {
17305 return;
17306 }
17307
17308 // Increment to count "symbols of interest" (defuns or defs) that we found.
17309 // These are tracked in AST order so we can check which is after which.
17310 let symbol_index = 1;
17311 // Map a defun ID to its first read (a `symbol_index`)
17312 const defun_first_read_map = new Map();
17313 // Map a symbol ID to its last write (a `symbol_index`)
17314 const symbol_last_write_map = new Map();
17315
17316 walk_parent(parent, (node, walk_info) => {
17317 if (node instanceof AST_Symbol && node.thedef) {
17318 const id = node.definition().id;
17319
17320 symbol_index++;
17321
17322 // Track last-writes to symbols
17323 if (symbols_of_interest.has(id)) {
17324 if (node instanceof AST_SymbolDeclaration || is_lhs(node, walk_info.parent())) {
17325 symbol_last_write_map.set(id, symbol_index);
17326 }
17327 }
17328
17329 // Track first-reads of defuns (refined later)
17330 if (defuns_of_interest.has(id)) {
17331 if (!defun_first_read_map.has(id) && !is_recursive_ref(walk_info, id)) {
17332 defun_first_read_map.set(id, symbol_index);
17333 }
17334 }
17335 }
17336 });
17337
17338 // Refine `defun_first_read_map` to be as high as possible
17339 for (const [defun, defun_first_read] of defun_first_read_map) {
17340 // Update all dependencies of `defun`
17341 const queue = new Set(defun_dependencies_map.get(defun));
17342 for (const enclosed_defun of queue) {
17343 let enclosed_defun_first_read = defun_first_read_map.get(enclosed_defun);
17344 if (enclosed_defun_first_read != null && enclosed_defun_first_read < defun_first_read) {
17345 continue;
17346 }
17347
17348 defun_first_read_map.set(enclosed_defun, defun_first_read);
17349
17350 for (const enclosed_enclosed_defun of defun_dependencies_map.get(enclosed_defun) || []) {
17351 queue.add(enclosed_enclosed_defun);
17352 }
17353 }
17354 }
17355
17356 // ensure write-then-read order, otherwise clear `fixed`
17357 // This is safe because last-writes (found_symbol_writes) are assumed to be as late as possible, and first-reads (defun_first_read_map) are assumed to be as early as possible.
17358 for (const [defun, defs] of dependencies_map) {
17359 const defun_first_read = defun_first_read_map.get(defun);
17360 if (defun_first_read === undefined) {
17361 continue;
17362 }
17363
17364 for (const def of defs) {
17365 if (def.fixed === false) {
17366 continue;
17367 }
17368
17369 let def_last_write = symbol_last_write_map.get(def.id) || 0;
17370
17371 if (defun_first_read < def_last_write) {
17372 def.fixed = false;
17373 }
17374 }
17375 }
17376}
17377
17378def_reduce_vars(AST_Lambda, mark_lambda);
17379
17380def_reduce_vars(AST_Do, function(tw, descend, compressor) {
17381 reset_block_variables(compressor, this);
17382 const saved_loop = tw.in_loop;
17383 tw.in_loop = this;
17384 push(tw);
17385 this.body.walk(tw);
17386 if (has_break_or_continue(this)) {
17387 pop(tw);
17388 push(tw);
17389 }
17390 this.condition.walk(tw);
17391 pop(tw);
17392 tw.in_loop = saved_loop;
17393 return true;
17394});
17395
17396def_reduce_vars(AST_For, function(tw, descend, compressor) {
17397 reset_block_variables(compressor, this);
17398 if (this.init) this.init.walk(tw);
17399 const saved_loop = tw.in_loop;
17400 tw.in_loop = this;
17401 push(tw);
17402 if (this.condition) this.condition.walk(tw);
17403 this.body.walk(tw);
17404 if (this.step) {
17405 if (has_break_or_continue(this)) {
17406 pop(tw);
17407 push(tw);
17408 }
17409 this.step.walk(tw);
17410 }
17411 pop(tw);
17412 tw.in_loop = saved_loop;
17413 return true;
17414});
17415
17416def_reduce_vars(AST_ForIn, function(tw, descend, compressor) {
17417 reset_block_variables(compressor, this);
17418 suppress(this.init);
17419 this.object.walk(tw);
17420 const saved_loop = tw.in_loop;
17421 tw.in_loop = this;
17422 push(tw);
17423 this.body.walk(tw);
17424 pop(tw);
17425 tw.in_loop = saved_loop;
17426 return true;
17427});
17428
17429def_reduce_vars(AST_If, function(tw) {
17430 this.condition.walk(tw);
17431 push(tw);
17432 this.body.walk(tw);
17433 pop(tw);
17434 if (this.alternative) {
17435 push(tw);
17436 this.alternative.walk(tw);
17437 pop(tw);
17438 }
17439 return true;
17440});
17441
17442def_reduce_vars(AST_LabeledStatement, function(tw) {
17443 push(tw);
17444 this.body.walk(tw);
17445 pop(tw);
17446 return true;
17447});
17448
17449def_reduce_vars(AST_SymbolCatch, function() {
17450 this.definition().fixed = false;
17451});
17452
17453def_reduce_vars(AST_SymbolRef, function(tw, descend, compressor) {
17454 var d = this.definition();
17455 d.references.push(this);
17456 if (d.references.length == 1
17457 && !d.fixed
17458 && d.orig[0] instanceof AST_SymbolDefun) {
17459 tw.loop_ids.set(d.id, tw.in_loop);
17460 }
17461 var fixed_value;
17462 if (d.fixed === undefined || !safe_to_read(tw, d)) {
17463 d.fixed = false;
17464 } else if (d.fixed) {
17465 fixed_value = this.fixed_value();
17466 if (
17467 fixed_value instanceof AST_Lambda
17468 && is_recursive_ref(tw, d)
17469 ) {
17470 d.recursive_refs++;
17471 } else if (fixed_value
17472 && !compressor.exposed(d)
17473 && ref_once(tw, compressor, d)
17474 ) {
17475 d.single_use =
17476 fixed_value instanceof AST_Lambda && !fixed_value.pinned()
17477 || fixed_value instanceof AST_Class
17478 || d.scope === this.scope && fixed_value.is_constant_expression();
17479 } else {
17480 d.single_use = false;
17481 }
17482 if (is_modified(compressor, tw, this, fixed_value, 0, is_immutable(fixed_value))) {
17483 if (d.single_use) {
17484 d.single_use = "m";
17485 } else {
17486 d.fixed = false;
17487 }
17488 }
17489 }
17490 mark_escaped(tw, d, this.scope, this, fixed_value, 0, 1);
17491});
17492
17493def_reduce_vars(AST_Toplevel, function(tw, descend, compressor) {
17494 this.globals.forEach(function(def) {
17495 reset_def(compressor, def);
17496 });
17497 reset_variables(tw, compressor, this);
17498 descend();
17499 handle_defined_after_hoist(this);
17500 return true;
17501});
17502
17503def_reduce_vars(AST_Try, function(tw, descend, compressor) {
17504 reset_block_variables(compressor, this);
17505 push(tw);
17506 this.body.walk(tw);
17507 pop(tw);
17508 if (this.bcatch) {
17509 push(tw);
17510 this.bcatch.walk(tw);
17511 pop(tw);
17512 }
17513 if (this.bfinally) this.bfinally.walk(tw);
17514 return true;
17515});
17516
17517def_reduce_vars(AST_Unary, function(tw) {
17518 var node = this;
17519 if (node.operator !== "++" && node.operator !== "--") return;
17520 var exp = node.expression;
17521 if (!(exp instanceof AST_SymbolRef)) return;
17522 var def = exp.definition();
17523 var safe = safe_to_assign(tw, def, exp.scope, true);
17524 def.assignments++;
17525 if (!safe) return;
17526 var fixed = def.fixed;
17527 if (!fixed) return;
17528 def.references.push(exp);
17529 def.chained = true;
17530 def.fixed = function() {
17531 return make_node(AST_Binary, node, {
17532 operator: node.operator.slice(0, -1),
17533 left: make_node(AST_UnaryPrefix, node, {
17534 operator: "+",
17535 expression: fixed instanceof AST_Node ? fixed : fixed()
17536 }),
17537 right: make_node(AST_Number, node, {
17538 value: 1
17539 })
17540 });
17541 };
17542 mark(tw, def, true);
17543 return true;
17544});
17545
17546def_reduce_vars(AST_VarDef, function(tw, descend) {
17547 var node = this;
17548 if (node.name instanceof AST_Destructuring) {
17549 suppress(node.name);
17550 return;
17551 }
17552 var d = node.name.definition();
17553 if (node.value) {
17554 if (safe_to_assign(tw, d, node.name.scope, node.value)) {
17555 d.fixed = function() {
17556 return node.value;
17557 };
17558 tw.loop_ids.set(d.id, tw.in_loop);
17559 mark(tw, d, false);
17560 descend();
17561 mark(tw, d, true);
17562 return true;
17563 } else {
17564 d.fixed = false;
17565 }
17566 }
17567});
17568
17569def_reduce_vars(AST_UsingDef, function() {
17570 suppress(this.name);
17571});
17572
17573def_reduce_vars(AST_While, function(tw, descend, compressor) {
17574 reset_block_variables(compressor, this);
17575 const saved_loop = tw.in_loop;
17576 tw.in_loop = this;
17577 push(tw);
17578 descend();
17579 pop(tw);
17580 tw.in_loop = saved_loop;
17581 return true;
17582});
17583
17584/***********************************************************************
17585
17586 A JavaScript tokenizer / parser / beautifier / compressor.
17587 https://github.com/mishoo/UglifyJS2
17588
17589 -------------------------------- (C) ---------------------------------
17590
17591 Author: Mihai Bazon
17592 <mihai.bazon@gmail.com>
17593 http://mihai.bazon.net/blog
17594
17595 Distributed under the BSD license:
17596
17597 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
17598
17599 Redistribution and use in source and binary forms, with or without
17600 modification, are permitted provided that the following conditions
17601 are met:
17602
17603 * Redistributions of source code must retain the above
17604 copyright notice, this list of conditions and the following
17605 disclaimer.
17606
17607 * Redistributions in binary form must reproduce the above
17608 copyright notice, this list of conditions and the following
17609 disclaimer in the documentation and/or other materials
17610 provided with the distribution.
17611
17612 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
17613 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17614 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17615 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
17616 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
17617 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17618 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
17619 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
17620 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
17621 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
17622 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
17623 SUCH DAMAGE.
17624
17625 ***********************************************************************/
17626
17627function loop_body(x) {
17628 if (x instanceof AST_IterationStatement) {
17629 return x.body instanceof AST_BlockStatement ? x.body : x;
17630 }
17631 return x;
17632}
17633
17634function is_lhs_read_only(lhs) {
17635 if (lhs instanceof AST_This) return true;
17636 if (lhs instanceof AST_SymbolRef) return lhs.definition().orig[0] instanceof AST_SymbolLambda;
17637 if (lhs instanceof AST_PropAccess) {
17638 lhs = lhs.expression;
17639 if (lhs instanceof AST_SymbolRef) {
17640 if (lhs.is_immutable()) return false;
17641 lhs = lhs.fixed_value();
17642 }
17643 if (!lhs) return true;
17644 if (lhs instanceof AST_RegExp) return false;
17645 if (lhs instanceof AST_Constant) return true;
17646 return is_lhs_read_only(lhs);
17647 }
17648 return false;
17649}
17650
17651/** var a = 1 --> var a*/
17652function remove_initializers(var_statement) {
17653 var decls = [];
17654 var_statement.definitions.forEach(function(def) {
17655 if (def.name instanceof AST_SymbolDeclaration) {
17656 def.value = null;
17657 decls.push(def);
17658 } else {
17659 def.declarations_as_names().forEach(name => {
17660 decls.push(make_node(AST_VarDef, def, {
17661 name,
17662 value: null
17663 }));
17664 });
17665 }
17666 });
17667 return decls.length ? make_node(AST_Var, var_statement, { definitions: decls }) : null;
17668}
17669
17670/** Called on code which won't be executed but has an effect outside of itself: `var`, `function` statements, `export`, `import`. */
17671function extract_from_unreachable_code(compressor, stat, target) {
17672 walk(stat, node => {
17673 if (node instanceof AST_Var) {
17674 const no_initializers = remove_initializers(node);
17675 if (no_initializers) target.push(no_initializers);
17676 return true;
17677 }
17678 if (
17679 node instanceof AST_Defun
17680 && (node === stat || !compressor.has_directive("use strict"))
17681 ) {
17682 target.push(node === stat ? node : make_node(AST_Var, node, {
17683 definitions: [
17684 make_node(AST_VarDef, node, {
17685 name: make_node(AST_SymbolVar, node.name, node.name),
17686 value: null
17687 })
17688 ]
17689 }));
17690 return true;
17691 }
17692 if (node instanceof AST_Export || node instanceof AST_Import) {
17693 target.push(node);
17694 return true;
17695 }
17696 if (node instanceof AST_Scope || node instanceof AST_Class) {
17697 // Do not go into nested scopes
17698 return true;
17699 }
17700 });
17701}
17702
17703/** Tighten a bunch of statements together, and perform statement-level optimization. */
17704function tighten_body(statements, compressor) {
17705 const nearest_scope = compressor.find_scope();
17706 const defun_scope = nearest_scope.get_defun_scope();
17707 const { in_loop, in_try } = find_loop_scope_try();
17708
17709 var CHANGED, max_iter = 10;
17710 do {
17711 CHANGED = false;
17712 eliminate_spurious_blocks(statements);
17713 if (compressor.option("dead_code")) {
17714 eliminate_dead_code(statements, compressor);
17715 }
17716 if (compressor.option("if_return")) {
17717 handle_if_return(statements, compressor);
17718 }
17719 if (compressor.sequences_limit > 0) {
17720 sequencesize(statements, compressor);
17721 sequencesize_2(statements, compressor);
17722 }
17723 if (compressor.option("join_vars")) {
17724 join_consecutive_vars(statements);
17725 }
17726 if (compressor.option("collapse_vars")) {
17727 collapse(statements, compressor);
17728 }
17729 } while (CHANGED && max_iter-- > 0);
17730
17731 function find_loop_scope_try() {
17732 var node = compressor.self(), level = 0, in_loop = false, in_try = false;
17733 do {
17734 if (node instanceof AST_IterationStatement) {
17735 in_loop = true;
17736 } else if (node instanceof AST_Scope) {
17737 break;
17738 } else if (node instanceof AST_TryBlock) {
17739 in_try = true;
17740 }
17741 } while (node = compressor.parent(level++));
17742
17743 return { in_loop, in_try };
17744 }
17745
17746 // Search from right to left for assignment-like expressions:
17747 // - `var a = x;`
17748 // - `a = x;`
17749 // - `++a`
17750 // For each candidate, scan from left to right for first usage, then try
17751 // to fold assignment into the site for compression.
17752 // Will not attempt to collapse assignments into or past code blocks
17753 // which are not sequentially executed, e.g. loops and conditionals.
17754 function collapse(statements, compressor) {
17755 if (nearest_scope.pinned() || defun_scope.pinned())
17756 return statements;
17757 var args;
17758 var candidates = [];
17759 var stat_index = statements.length;
17760 var scanner = new TreeTransformer(function (node) {
17761 if (abort)
17762 return node;
17763 // Skip nodes before `candidate` as quickly as possible
17764 if (!hit) {
17765 if (node !== hit_stack[hit_index])
17766 return node;
17767 hit_index++;
17768 if (hit_index < hit_stack.length)
17769 return handle_custom_scan_order(node);
17770 hit = true;
17771 stop_after = find_stop(node, 0);
17772 if (stop_after === node)
17773 abort = true;
17774 return node;
17775 }
17776 // Stop immediately if these node types are encountered
17777 var parent = scanner.parent();
17778 if (node instanceof AST_Assign
17779 && (node.logical || node.operator != "=" && lhs.equivalent_to(node.left))
17780 || node instanceof AST_Await
17781 || node instanceof AST_Using
17782 || node instanceof AST_Call && lhs instanceof AST_PropAccess && lhs.equivalent_to(node.expression)
17783 ||
17784 (node instanceof AST_Call || node instanceof AST_PropAccess)
17785 && node.optional
17786 || node instanceof AST_Debugger
17787 || node instanceof AST_Destructuring
17788 || node instanceof AST_Expansion
17789 && node.expression instanceof AST_Symbol
17790 && (
17791 node.expression instanceof AST_This
17792 || node.expression.definition().references.length > 1
17793 )
17794 || node instanceof AST_IterationStatement && !(node instanceof AST_For)
17795 || node instanceof AST_LoopControl
17796 || node instanceof AST_Try
17797 || node instanceof AST_With
17798 || node instanceof AST_Yield
17799 || node instanceof AST_Export
17800 || node instanceof AST_Class
17801 || parent instanceof AST_For && node !== parent.init
17802 || !replace_all
17803 && (
17804 node instanceof AST_SymbolRef
17805 && !node.is_declared(compressor)
17806 && !pure_prop_access_globals.has(node)
17807 )
17808 || node instanceof AST_SymbolRef
17809 && parent instanceof AST_Call
17810 && has_annotation(parent, _NOINLINE)
17811 || node instanceof AST_ObjectProperty && node.key instanceof AST_Node
17812 ) {
17813 abort = true;
17814 return node;
17815 }
17816 // Stop only if candidate is found within conditional branches
17817 if (!stop_if_hit && (!lhs_local || !replace_all)
17818 && (parent instanceof AST_Binary && lazy_op.has(parent.operator) && parent.left !== node
17819 || parent instanceof AST_Conditional && parent.condition !== node
17820 || parent instanceof AST_If && parent.condition !== node)) {
17821 stop_if_hit = parent;
17822 }
17823 // Replace variable with assignment when found
17824 if (
17825 can_replace
17826 && !(node instanceof AST_SymbolDeclaration)
17827 && lhs.equivalent_to(node)
17828 && !shadows(scanner.find_scope() || nearest_scope, lvalues)
17829 ) {
17830 if (stop_if_hit) {
17831 abort = true;
17832 return node;
17833 }
17834 if (is_lhs(node, parent)) {
17835 if (value_def)
17836 replaced++;
17837 return node;
17838 } else {
17839 replaced++;
17840 if (value_def && candidate instanceof AST_VarDef)
17841 return node;
17842 }
17843 CHANGED = abort = true;
17844 if (candidate instanceof AST_UnaryPostfix) {
17845 return make_node(AST_UnaryPrefix, candidate, candidate);
17846 }
17847 if (candidate instanceof AST_VarDef) {
17848 var def = candidate.name.definition();
17849 var value = candidate.value;
17850 if (def.references.length - def.replaced == 1 && !compressor.exposed(def)) {
17851 def.replaced++;
17852 if (funarg && is_identifier_atom(value)) {
17853 return value.transform(compressor);
17854 } else {
17855 return maintain_this_binding(parent, node, value);
17856 }
17857 }
17858 return make_node(AST_Assign, candidate, {
17859 operator: "=",
17860 logical: false,
17861 left: make_node(AST_SymbolRef, candidate.name, candidate.name),
17862 right: value
17863 });
17864 }
17865 clear_flag(candidate, WRITE_ONLY);
17866 return candidate;
17867 }
17868 // These node types have child nodes that execute sequentially,
17869 // but are otherwise not safe to scan into or beyond them.
17870 var sym;
17871 if (node instanceof AST_Call
17872 || node instanceof AST_Exit
17873 && (side_effects || lhs instanceof AST_PropAccess || may_modify(lhs))
17874 || node instanceof AST_PropAccess
17875 && (side_effects || node.expression.may_throw_on_access(compressor))
17876 || node instanceof AST_SymbolRef
17877 && ((lvalues.has(node.name) && lvalues.get(node.name).modified) || side_effects && may_modify(node))
17878 || node instanceof AST_VarDef && node.value
17879 && (lvalues.has(node.name.name) || side_effects && may_modify(node.name))
17880 || node instanceof AST_Using
17881 || (sym = is_lhs(node.left, node))
17882 && (sym instanceof AST_PropAccess || lvalues.has(sym.name))
17883 || may_throw
17884 && (in_try ? node.has_side_effects(compressor) : side_effects_external(node))) {
17885 stop_after = node;
17886 if (node instanceof AST_Scope)
17887 abort = true;
17888 }
17889 return handle_custom_scan_order(node);
17890 }, function (node) {
17891 if (abort)
17892 return;
17893 if (stop_after === node)
17894 abort = true;
17895 if (stop_if_hit === node)
17896 stop_if_hit = null;
17897 });
17898
17899 var multi_replacer = new TreeTransformer(function (node) {
17900 if (abort)
17901 return node;
17902 // Skip nodes before `candidate` as quickly as possible
17903 if (!hit) {
17904 if (node !== hit_stack[hit_index])
17905 return node;
17906 hit_index++;
17907 if (hit_index < hit_stack.length)
17908 return;
17909 hit = true;
17910 return node;
17911 }
17912 // Replace variable when found
17913 if (node instanceof AST_SymbolRef
17914 && node.name == def.name) {
17915 if (!--replaced)
17916 abort = true;
17917 if (is_lhs(node, multi_replacer.parent()))
17918 return node;
17919 def.replaced++;
17920 value_def.replaced--;
17921 return candidate.value;
17922 }
17923 // Skip (non-executed) functions and (leading) default case in switch statements
17924 if (node instanceof AST_Default || node instanceof AST_Scope)
17925 return node;
17926 });
17927
17928 while (--stat_index >= 0) {
17929 // Treat parameters as collapsible in IIFE, i.e.
17930 // function(a, b){ ... }(x());
17931 // would be translated into equivalent assignments:
17932 // var a = x(), b = undefined;
17933 if (stat_index == 0 && compressor.option("unused"))
17934 extract_args();
17935 // Find collapsible assignments
17936 var hit_stack = [];
17937 extract_candidates(statements[stat_index]);
17938 while (candidates.length > 0) {
17939 hit_stack = candidates.pop();
17940 var hit_index = 0;
17941 var candidate = hit_stack[hit_stack.length - 1];
17942 var value_def = null;
17943 var stop_after = null;
17944 var stop_if_hit = null;
17945 var lhs = get_lhs(candidate);
17946 if (!lhs || is_lhs_read_only(lhs) || lhs.has_side_effects(compressor))
17947 continue;
17948 // Locate symbols which may execute code outside of scanning range
17949 var lvalues = get_lvalues(candidate);
17950 var lhs_local = is_lhs_local(lhs);
17951 if (lhs instanceof AST_SymbolRef) {
17952 lvalues.set(lhs.name, { def: lhs.definition(), modified: false });
17953 }
17954 var side_effects = value_has_side_effects(candidate);
17955 var replace_all = replace_all_symbols();
17956 var may_throw = candidate.may_throw(compressor);
17957 var funarg = candidate.name instanceof AST_SymbolFunarg;
17958 var hit = funarg;
17959 var abort = false, replaced = 0, can_replace = !args || !hit;
17960 if (!can_replace) {
17961 for (
17962 let j = compressor.self().argnames.lastIndexOf(candidate.name) + 1;
17963 !abort && j < args.length;
17964 j++
17965 ) {
17966 args[j].transform(scanner);
17967 }
17968 can_replace = true;
17969 }
17970 for (var i = stat_index; !abort && i < statements.length; i++) {
17971 statements[i].transform(scanner);
17972 }
17973 if (value_def) {
17974 var def = candidate.name.definition();
17975 if (abort && def.references.length - def.replaced > replaced)
17976 replaced = false;
17977 else {
17978 abort = false;
17979 hit_index = 0;
17980 hit = funarg;
17981 for (var i = stat_index; !abort && i < statements.length; i++) {
17982 statements[i].transform(multi_replacer);
17983 }
17984 value_def.single_use = false;
17985 }
17986 }
17987 if (replaced && !remove_candidate(candidate))
17988 statements.splice(stat_index, 1);
17989 }
17990 }
17991
17992 function handle_custom_scan_order(node) {
17993 // Skip (non-executed) functions
17994 if (node instanceof AST_Scope)
17995 return node;
17996
17997 // Scan case expressions first in a switch statement
17998 if (node instanceof AST_Switch) {
17999 node.expression = node.expression.transform(scanner);
18000 for (var i = 0, len = node.body.length; !abort && i < len; i++) {
18001 var branch = node.body[i];
18002 if (branch instanceof AST_Case) {
18003 if (!hit) {
18004 if (branch !== hit_stack[hit_index])
18005 continue;
18006 hit_index++;
18007 }
18008 branch.expression = branch.expression.transform(scanner);
18009 if (!replace_all)
18010 break;
18011 }
18012 }
18013 abort = true;
18014 return node;
18015 }
18016 }
18017
18018 function redefined_within_scope(def, scope) {
18019 if (def.global)
18020 return false;
18021 let cur_scope = def.scope;
18022 while (cur_scope && cur_scope !== scope) {
18023 if (cur_scope.variables.has(def.name)) {
18024 return true;
18025 }
18026 cur_scope = cur_scope.parent_scope;
18027 }
18028 return false;
18029 }
18030
18031 function has_overlapping_symbol(fn, arg, fn_strict) {
18032 var found = false, scan_this = !(fn instanceof AST_Arrow);
18033 arg.walk(new TreeWalker(function (node, descend) {
18034 if (found)
18035 return true;
18036 if (node instanceof AST_SymbolRef && (fn.variables.has(node.name) || redefined_within_scope(node.definition(), fn))) {
18037 var s = node.definition().scope;
18038 if (s !== defun_scope)
18039 while (s = s.parent_scope) {
18040 if (s === defun_scope)
18041 return true;
18042 }
18043 return found = true;
18044 }
18045 if ((fn_strict || scan_this) && node instanceof AST_This) {
18046 return found = true;
18047 }
18048 if (node instanceof AST_Scope && !(node instanceof AST_Arrow)) {
18049 var prev = scan_this;
18050 scan_this = false;
18051 descend();
18052 scan_this = prev;
18053 return true;
18054 }
18055 }));
18056 return found;
18057 }
18058
18059 function arg_is_injectable(arg) {
18060 if (arg instanceof AST_Expansion) return false;
18061 const contains_await = walk(arg, (node) => {
18062 if (node instanceof AST_Await) return walk_abort;
18063 });
18064 if (contains_await) return false;
18065 return true;
18066 }
18067 function extract_args() {
18068 var iife, fn = compressor.self();
18069 if (is_func_expr(fn)
18070 && !fn.name
18071 && !fn.uses_arguments
18072 && !fn.pinned()
18073 && (iife = compressor.parent()) instanceof AST_Call
18074 && iife.expression === fn
18075 && iife.args.every(arg_is_injectable)
18076 ) {
18077 var fn_strict = compressor.has_directive("use strict");
18078 if (fn_strict && !member(fn_strict, fn.body))
18079 fn_strict = false;
18080 var len = fn.argnames.length;
18081 args = iife.args.slice(len);
18082 var names = new Set();
18083 for (var i = len; --i >= 0;) {
18084 var sym = fn.argnames[i];
18085 var arg = iife.args[i];
18086 // The following two line fix is a duplicate of the fix at
18087 // https://github.com/terser/terser/commit/011d3eb08cefe6922c7d1bdfa113fc4aeaca1b75
18088 // This might mean that these two pieces of code (one here in collapse_vars and another in reduce_vars
18089 // Might be doing the exact same thing.
18090 const def = sym.definition && sym.definition();
18091 const is_reassigned = def && def.orig.length > 1;
18092 if (is_reassigned)
18093 continue;
18094 args.unshift(make_node(AST_VarDef, sym, {
18095 name: sym,
18096 value: arg
18097 }));
18098 if (names.has(sym.name))
18099 continue;
18100 names.add(sym.name);
18101 if (sym instanceof AST_Expansion) {
18102 var elements = iife.args.slice(i);
18103 if (elements.every((arg) => !has_overlapping_symbol(fn, arg, fn_strict)
18104 )) {
18105 candidates.unshift([make_node(AST_VarDef, sym, {
18106 name: sym.expression,
18107 value: make_node(AST_Array, iife, {
18108 elements: elements
18109 })
18110 })]);
18111 }
18112 } else {
18113 if (!arg) {
18114 arg = make_void_0(sym).transform(compressor);
18115 } else if (arg instanceof AST_Lambda && arg.pinned()
18116 || has_overlapping_symbol(fn, arg, fn_strict)) {
18117 arg = null;
18118 }
18119 if (arg)
18120 candidates.unshift([make_node(AST_VarDef, sym, {
18121 name: sym,
18122 value: arg
18123 })]);
18124 }
18125 }
18126 }
18127 }
18128
18129 function extract_candidates(expr) {
18130 hit_stack.push(expr);
18131 if (expr instanceof AST_Assign) {
18132 if (!expr.left.has_side_effects(compressor)
18133 && !(expr.right instanceof AST_Chain)) {
18134 candidates.push(hit_stack.slice());
18135 }
18136 extract_candidates(expr.right);
18137 } else if (expr instanceof AST_Binary) {
18138 extract_candidates(expr.left);
18139 extract_candidates(expr.right);
18140 } else if (expr instanceof AST_Call && !has_annotation(expr, _NOINLINE)) {
18141 extract_candidates(expr.expression);
18142 expr.args.forEach(extract_candidates);
18143 } else if (expr instanceof AST_Case) {
18144 extract_candidates(expr.expression);
18145 } else if (expr instanceof AST_Conditional) {
18146 extract_candidates(expr.condition);
18147 extract_candidates(expr.consequent);
18148 extract_candidates(expr.alternative);
18149 } else if (expr instanceof AST_Definitions) {
18150 var len = expr.definitions.length;
18151 // limit number of trailing variable definitions for consideration
18152 var i = len - 200;
18153 if (i < 0)
18154 i = 0;
18155 for (; i < len; i++) {
18156 extract_candidates(expr.definitions[i]);
18157 }
18158 } else if (expr instanceof AST_DWLoop) {
18159 extract_candidates(expr.condition);
18160 if (!(expr.body instanceof AST_Block)) {
18161 extract_candidates(expr.body);
18162 }
18163 } else if (expr instanceof AST_Exit) {
18164 if (expr.value)
18165 extract_candidates(expr.value);
18166 } else if (expr instanceof AST_For) {
18167 if (expr.init)
18168 extract_candidates(expr.init);
18169 if (expr.condition)
18170 extract_candidates(expr.condition);
18171 if (expr.step)
18172 extract_candidates(expr.step);
18173 if (!(expr.body instanceof AST_Block)) {
18174 extract_candidates(expr.body);
18175 }
18176 } else if (expr instanceof AST_ForIn) {
18177 extract_candidates(expr.object);
18178 if (!(expr.body instanceof AST_Block)) {
18179 extract_candidates(expr.body);
18180 }
18181 } else if (expr instanceof AST_If) {
18182 extract_candidates(expr.condition);
18183 if (!(expr.body instanceof AST_Block)) {
18184 extract_candidates(expr.body);
18185 }
18186 if (expr.alternative && !(expr.alternative instanceof AST_Block)) {
18187 extract_candidates(expr.alternative);
18188 }
18189 } else if (expr instanceof AST_Sequence) {
18190 expr.expressions.forEach(extract_candidates);
18191 } else if (expr instanceof AST_SimpleStatement) {
18192 extract_candidates(expr.body);
18193 } else if (expr instanceof AST_Switch) {
18194 extract_candidates(expr.expression);
18195 expr.body.forEach(extract_candidates);
18196 } else if (expr instanceof AST_Unary) {
18197 if (expr.operator == "++" || expr.operator == "--") {
18198 candidates.push(hit_stack.slice());
18199 }
18200 } else if (expr instanceof AST_VarDef) {
18201 if (expr.value && !(expr.value instanceof AST_Chain)) {
18202 candidates.push(hit_stack.slice());
18203 extract_candidates(expr.value);
18204 }
18205 }
18206 hit_stack.pop();
18207 }
18208
18209 function find_stop(node, level, write_only) {
18210 var parent = scanner.parent(level);
18211 if (parent instanceof AST_Assign) {
18212 if (write_only
18213 && !parent.logical
18214 && !(parent.left instanceof AST_PropAccess
18215 || lvalues.has(parent.left.name))) {
18216 return find_stop(parent, level + 1, write_only);
18217 }
18218 return node;
18219 }
18220 if (parent instanceof AST_Binary) {
18221 if (write_only && (!lazy_op.has(parent.operator) || parent.left === node)) {
18222 return find_stop(parent, level + 1, write_only);
18223 }
18224 return node;
18225 }
18226 if (parent instanceof AST_Call)
18227 return node;
18228 if (parent instanceof AST_Case)
18229 return node;
18230 if (parent instanceof AST_Conditional) {
18231 if (write_only && parent.condition === node) {
18232 return find_stop(parent, level + 1, write_only);
18233 }
18234 return node;
18235 }
18236 if (parent instanceof AST_Definitions) {
18237 return find_stop(parent, level + 1, true);
18238 }
18239 if (parent instanceof AST_Exit) {
18240 return write_only ? find_stop(parent, level + 1, write_only) : node;
18241 }
18242 if (parent instanceof AST_If) {
18243 if (write_only && parent.condition === node) {
18244 return find_stop(parent, level + 1, write_only);
18245 }
18246 return node;
18247 }
18248 if (parent instanceof AST_IterationStatement)
18249 return node;
18250 if (parent instanceof AST_Sequence) {
18251 return find_stop(parent, level + 1, parent.tail_node() !== node);
18252 }
18253 if (parent instanceof AST_SimpleStatement) {
18254 return find_stop(parent, level + 1, true);
18255 }
18256 if (parent instanceof AST_Switch)
18257 return node;
18258 if (parent instanceof AST_VarDef)
18259 return node;
18260 return null;
18261 }
18262
18263 function mangleable_var(var_def) {
18264 var value = var_def.value;
18265 if (!(value instanceof AST_SymbolRef))
18266 return;
18267 if (value.name == "arguments")
18268 return;
18269 var def = value.definition();
18270 if (def.undeclared)
18271 return;
18272 return value_def = def;
18273 }
18274
18275 function get_lhs(expr) {
18276 if (expr instanceof AST_Assign && expr.logical) {
18277 return false;
18278 } else if (expr instanceof AST_VarDef && expr.name instanceof AST_SymbolDeclaration) {
18279 var def = expr.name.definition();
18280 if (!member(expr.name, def.orig))
18281 return;
18282 var referenced = def.references.length - def.replaced;
18283 if (!referenced)
18284 return;
18285 var declared = def.orig.length - def.eliminated;
18286 if (declared > 1 && !(expr.name instanceof AST_SymbolFunarg)
18287 || (referenced > 1 ? mangleable_var(expr) : !compressor.exposed(def))) {
18288 return make_node(AST_SymbolRef, expr.name, expr.name);
18289 }
18290 } else {
18291 const lhs = expr instanceof AST_Assign
18292 ? expr.left
18293 : expr.expression;
18294 return !is_ref_of(lhs, AST_SymbolConst)
18295 && !is_ref_of(lhs, AST_SymbolLet)
18296 && !is_ref_of(lhs, AST_SymbolUsing)
18297 && lhs;
18298 }
18299 }
18300
18301 function get_rvalue(expr) {
18302 if (expr instanceof AST_Assign) {
18303 return expr.right;
18304 } else {
18305 return expr.value;
18306 }
18307 }
18308
18309 function get_lvalues(expr) {
18310 var lvalues = new Map();
18311 if (expr instanceof AST_Unary)
18312 return lvalues;
18313 var tw = new TreeWalker(function (node) {
18314 var sym = node;
18315 while (sym instanceof AST_PropAccess)
18316 sym = sym.expression;
18317 if (sym instanceof AST_SymbolRef) {
18318 const prev = lvalues.get(sym.name);
18319 if (!prev || !prev.modified) {
18320 lvalues.set(sym.name, {
18321 def: sym.definition(),
18322 modified: is_modified(compressor, tw, node, node, 0)
18323 });
18324 }
18325 }
18326 });
18327 get_rvalue(expr).walk(tw);
18328 return lvalues;
18329 }
18330
18331 function remove_candidate(expr) {
18332 if (expr.name instanceof AST_SymbolFunarg) {
18333 var iife = compressor.parent(), argnames = compressor.self().argnames;
18334 var index = argnames.indexOf(expr.name);
18335 if (index < 0) {
18336 iife.args.length = Math.min(iife.args.length, argnames.length - 1);
18337 } else {
18338 var args = iife.args;
18339 if (args[index])
18340 args[index] = make_node(AST_Number, args[index], {
18341 value: 0
18342 });
18343 }
18344 return true;
18345 }
18346 var found = false;
18347 return statements[stat_index].transform(new TreeTransformer(function (node, descend, in_list) {
18348 if (found)
18349 return node;
18350 if (node === expr || node.body === expr) {
18351 found = true;
18352 if (node instanceof AST_VarDef) {
18353 node.value = node.name instanceof AST_SymbolConst
18354 ? make_void_0(node.value) // `const` always needs value.
18355 : null;
18356 return node;
18357 }
18358 return in_list ? MAP.skip : null;
18359 }
18360 }, function (node) {
18361 if (node instanceof AST_Sequence)
18362 switch (node.expressions.length) {
18363 case 0: return null;
18364 case 1: return node.expressions[0];
18365 }
18366 }));
18367 }
18368
18369 function is_lhs_local(lhs) {
18370 while (lhs instanceof AST_PropAccess)
18371 lhs = lhs.expression;
18372 return lhs instanceof AST_SymbolRef
18373 && lhs.definition().scope.get_defun_scope() === defun_scope
18374 && !(in_loop
18375 && (lvalues.has(lhs.name)
18376 || candidate instanceof AST_Unary
18377 || (candidate instanceof AST_Assign
18378 && !candidate.logical
18379 && candidate.operator != "=")));
18380 }
18381
18382 function value_has_side_effects(expr) {
18383 if (expr instanceof AST_Unary)
18384 return unary_side_effects.has(expr.operator);
18385 return get_rvalue(expr).has_side_effects(compressor);
18386 }
18387
18388 function replace_all_symbols() {
18389 if (side_effects)
18390 return false;
18391 if (value_def)
18392 return true;
18393 if (lhs instanceof AST_SymbolRef) {
18394 var def = lhs.definition();
18395 if (def.references.length - def.replaced == (candidate instanceof AST_VarDef ? 1 : 2)) {
18396 return true;
18397 }
18398 }
18399 return false;
18400 }
18401
18402 function may_modify(sym) {
18403 if (!sym.definition)
18404 return true; // AST_Destructuring
18405 var def = sym.definition();
18406 if (def.orig.length == 1 && def.orig[0] instanceof AST_SymbolDefun)
18407 return false;
18408 if (def.scope.get_defun_scope() !== defun_scope)
18409 return true;
18410 return def.references.some((ref) =>
18411 ref.scope.get_defun_scope() !== defun_scope
18412 );
18413 }
18414
18415 function side_effects_external(node, lhs) {
18416 if (node instanceof AST_Assign)
18417 return side_effects_external(node.left, true);
18418 if (node instanceof AST_Unary)
18419 return side_effects_external(node.expression, true);
18420 if (node instanceof AST_VarDef)
18421 return node.value && side_effects_external(node.value);
18422 if (lhs) {
18423 if (node instanceof AST_Dot)
18424 return side_effects_external(node.expression, true);
18425 if (node instanceof AST_Sub)
18426 return side_effects_external(node.expression, true);
18427 if (node instanceof AST_SymbolRef)
18428 return node.definition().scope.get_defun_scope() !== defun_scope;
18429 }
18430 return false;
18431 }
18432
18433 /**
18434 * Will any of the pulled-in lvalues shadow a variable in newScope or parents?
18435 * similar to scope_encloses_variables_in_this_scope */
18436 function shadows(my_scope, lvalues) {
18437 for (const { def } of lvalues.values()) {
18438 const looked_up = my_scope.find_variable(def.name);
18439 if (looked_up) {
18440 if (looked_up === def) continue;
18441 return true;
18442 }
18443 }
18444 return false;
18445 }
18446 }
18447
18448 function eliminate_spurious_blocks(statements) {
18449 var seen_dirs = [];
18450 for (var i = 0; i < statements.length;) {
18451 var stat = statements[i];
18452 if (stat instanceof AST_BlockStatement && stat.body.every(can_be_evicted_from_block)) {
18453 CHANGED = true;
18454 eliminate_spurious_blocks(stat.body);
18455 statements.splice(i, 1, ...stat.body);
18456 i += stat.body.length;
18457 } else if (stat instanceof AST_EmptyStatement) {
18458 CHANGED = true;
18459 statements.splice(i, 1);
18460 } else if (stat instanceof AST_Directive) {
18461 if (seen_dirs.indexOf(stat.value) < 0) {
18462 i++;
18463 seen_dirs.push(stat.value);
18464 } else {
18465 CHANGED = true;
18466 statements.splice(i, 1);
18467 }
18468 } else
18469 i++;
18470 }
18471 }
18472
18473 function handle_if_return(statements, compressor) {
18474 var self = compressor.self();
18475 var multiple_if_returns = has_multiple_if_returns(statements);
18476 var in_lambda = self instanceof AST_Lambda;
18477 // Prevent extremely deep nesting
18478 // https://github.com/terser/terser/issues/1432
18479 // https://github.com/webpack/webpack/issues/17548
18480 const iteration_start = Math.min(statements.length, 500);
18481 for (var i = iteration_start; --i >= 0;) {
18482 var stat = statements[i];
18483 var j = next_index(i);
18484 var next = statements[j];
18485
18486 if (in_lambda && !next && stat instanceof AST_Return) {
18487 if (!stat.value) {
18488 CHANGED = true;
18489 statements.splice(i, 1);
18490 continue;
18491 }
18492 if (stat.value instanceof AST_UnaryPrefix && stat.value.operator == "void") {
18493 CHANGED = true;
18494 statements[i] = make_node(AST_SimpleStatement, stat, {
18495 body: stat.value.expression
18496 });
18497 continue;
18498 }
18499 }
18500
18501 if (stat instanceof AST_If) {
18502 let ab, new_else;
18503
18504 ab = aborts(stat.body);
18505 if (
18506 can_merge_flow(ab)
18507 && (new_else = as_statement_array_with_return(stat.body, ab))
18508 ) {
18509 if (ab.label) {
18510 remove(ab.label.thedef.references, ab);
18511 }
18512 CHANGED = true;
18513 stat = stat.clone();
18514 stat.condition = stat.condition.negate(compressor);
18515 stat.body = make_node(AST_BlockStatement, stat, {
18516 body: as_statement_array(stat.alternative).concat(extract_defuns())
18517 });
18518 stat.alternative = make_node(AST_BlockStatement, stat, {
18519 body: new_else
18520 });
18521 statements[i] = stat.transform(compressor);
18522 continue;
18523 }
18524
18525 ab = aborts(stat.alternative);
18526 if (
18527 can_merge_flow(ab)
18528 && (new_else = as_statement_array_with_return(stat.alternative, ab))
18529 ) {
18530 if (ab.label) {
18531 remove(ab.label.thedef.references, ab);
18532 }
18533 CHANGED = true;
18534 stat = stat.clone();
18535 stat.body = make_node(AST_BlockStatement, stat.body, {
18536 body: as_statement_array(stat.body).concat(extract_defuns())
18537 });
18538 stat.alternative = make_node(AST_BlockStatement, stat.alternative, {
18539 body: new_else
18540 });
18541 statements[i] = stat.transform(compressor);
18542 continue;
18543 }
18544 }
18545
18546 if (stat instanceof AST_If && stat.body instanceof AST_Return) {
18547 var value = stat.body.value;
18548 //---
18549 // pretty silly case, but:
18550 // if (foo()) return; return; ==> foo(); return;
18551 if (!value && !stat.alternative
18552 && (in_lambda && !next || next instanceof AST_Return && !next.value)) {
18553 CHANGED = true;
18554 statements[i] = make_node(AST_SimpleStatement, stat.condition, {
18555 body: stat.condition
18556 });
18557 continue;
18558 }
18559 //---
18560 // if (foo()) return x; return y; ==> return foo() ? x : y;
18561 if (value && !stat.alternative && next instanceof AST_Return && next.value) {
18562 CHANGED = true;
18563 stat = stat.clone();
18564 stat.alternative = next;
18565 statements[i] = stat.transform(compressor);
18566 statements.splice(j, 1);
18567 continue;
18568 }
18569 //---
18570 // if (foo()) return x; [ return ; ] ==> return foo() ? x : undefined;
18571 if (value && !stat.alternative
18572 && (!next && in_lambda && multiple_if_returns
18573 || next instanceof AST_Return)) {
18574 CHANGED = true;
18575 stat = stat.clone();
18576 stat.alternative = next || make_node(AST_Return, stat, {
18577 value: null
18578 });
18579 statements[i] = stat.transform(compressor);
18580 if (next)
18581 statements.splice(j, 1);
18582 continue;
18583 }
18584 //---
18585 // if (a) return b; if (c) return d; e; ==> return a ? b : c ? d : void e;
18586 //
18587 // if sequences is not enabled, this can lead to an endless loop (issue #866).
18588 // however, with sequences on this helps producing slightly better output for
18589 // the example code.
18590 var prev = statements[prev_index(i)];
18591 if (compressor.option("sequences") && in_lambda && !stat.alternative
18592 && prev instanceof AST_If && prev.body instanceof AST_Return
18593 && next_index(j) == statements.length && next instanceof AST_SimpleStatement) {
18594 CHANGED = true;
18595 stat = stat.clone();
18596 stat.alternative = make_node(AST_BlockStatement, next, {
18597 body: [
18598 next,
18599 make_node(AST_Return, next, {
18600 value: null
18601 })
18602 ]
18603 });
18604 statements[i] = stat.transform(compressor);
18605 statements.splice(j, 1);
18606 continue;
18607 }
18608 }
18609 }
18610
18611 function has_multiple_if_returns(statements) {
18612 var n = 0;
18613 for (var i = statements.length; --i >= 0;) {
18614 var stat = statements[i];
18615 if (stat instanceof AST_If && stat.body instanceof AST_Return) {
18616 if (++n > 1)
18617 return true;
18618 }
18619 }
18620 return false;
18621 }
18622
18623 function is_return_void(value) {
18624 return !value || value instanceof AST_UnaryPrefix && value.operator == "void";
18625 }
18626
18627 function can_merge_flow(ab) {
18628 if (!ab)
18629 return false;
18630 for (var j = i + 1, len = statements.length; j < len; j++) {
18631 var stat = statements[j];
18632 if (stat instanceof AST_DefinitionsLike && !(stat instanceof AST_Var))
18633 return false;
18634 }
18635 var lct = ab instanceof AST_LoopControl ? compressor.loopcontrol_target(ab) : null;
18636 return ab instanceof AST_Return && in_lambda && is_return_void(ab.value)
18637 || ab instanceof AST_Continue && self === loop_body(lct)
18638 || ab instanceof AST_Break && lct instanceof AST_BlockStatement && self === lct;
18639 }
18640
18641 function extract_defuns() {
18642 var tail = statements.slice(i + 1);
18643 statements.length = i + 1;
18644 return tail.filter(function (stat) {
18645 if (stat instanceof AST_Defun) {
18646 statements.push(stat);
18647 return false;
18648 }
18649 return true;
18650 });
18651 }
18652
18653 function as_statement_array_with_return(node, ab) {
18654 var body = as_statement_array(node);
18655 if (ab !== body[body.length - 1]) {
18656 return undefined;
18657 }
18658 body = body.slice(0, -1);
18659 if (!body.every(stat => can_be_evicted_from_block(stat))) {
18660 return undefined;
18661 }
18662 if (ab.value) {
18663 body.push(make_node(AST_SimpleStatement, ab.value, {
18664 body: ab.value.expression
18665 }));
18666 }
18667 return body;
18668 }
18669
18670 function next_index(i) {
18671 for (var j = i + 1, len = statements.length; j < len; j++) {
18672 var stat = statements[j];
18673 if (!(stat instanceof AST_Var && declarations_only(stat))) {
18674 break;
18675 }
18676 }
18677 return j;
18678 }
18679
18680 function prev_index(i) {
18681 for (var j = i; --j >= 0;) {
18682 var stat = statements[j];
18683 if (!(stat instanceof AST_Var && declarations_only(stat))) {
18684 break;
18685 }
18686 }
18687 return j;
18688 }
18689 }
18690
18691 function eliminate_dead_code(statements, compressor) {
18692 var has_quit;
18693 var self = compressor.self();
18694 for (var i = 0, n = 0, len = statements.length; i < len; i++) {
18695 var stat = statements[i];
18696 if (stat instanceof AST_LoopControl) {
18697 var lct = compressor.loopcontrol_target(stat);
18698 if (stat instanceof AST_Break
18699 && !(lct instanceof AST_IterationStatement)
18700 && loop_body(lct) === self
18701 || stat instanceof AST_Continue
18702 && loop_body(lct) === self) {
18703 if (stat.label) {
18704 remove(stat.label.thedef.references, stat);
18705 }
18706 } else {
18707 statements[n++] = stat;
18708 }
18709 } else {
18710 statements[n++] = stat;
18711 }
18712 if (aborts(stat)) {
18713 has_quit = statements.slice(i + 1);
18714 break;
18715 }
18716 }
18717 statements.length = n;
18718 CHANGED = n != len;
18719 if (has_quit)
18720 has_quit.forEach(function (stat) {
18721 extract_from_unreachable_code(compressor, stat, statements);
18722 });
18723 }
18724
18725 function declarations_only(node) {
18726 return node.definitions.every((var_def) => !var_def.value);
18727 }
18728
18729 function sequencesize(statements, compressor) {
18730 if (statements.length < 2)
18731 return;
18732 var seq = [], n = 0;
18733 function push_seq() {
18734 if (!seq.length)
18735 return;
18736 var body = make_sequence(seq[0], seq);
18737 statements[n++] = make_node(AST_SimpleStatement, body, { body: body });
18738 seq = [];
18739 }
18740 for (var i = 0, len = statements.length; i < len; i++) {
18741 var stat = statements[i];
18742 if (stat instanceof AST_SimpleStatement) {
18743 if (seq.length >= compressor.sequences_limit)
18744 push_seq();
18745 var body = stat.body;
18746 if (seq.length > 0)
18747 body = body.drop_side_effect_free(compressor);
18748 if (body)
18749 merge_sequence(seq, body);
18750 } else if (stat instanceof AST_Definitions && declarations_only(stat)
18751 || stat instanceof AST_Defun) {
18752 statements[n++] = stat;
18753 } else {
18754 push_seq();
18755 statements[n++] = stat;
18756 }
18757 }
18758 push_seq();
18759 statements.length = n;
18760 if (n != len)
18761 CHANGED = true;
18762 }
18763
18764 function to_simple_statement(block, decls) {
18765 if (!(block instanceof AST_BlockStatement))
18766 return block;
18767 var stat = null;
18768 for (var i = 0, len = block.body.length; i < len; i++) {
18769 var line = block.body[i];
18770 if (line instanceof AST_Var && declarations_only(line)) {
18771 decls.push(line);
18772 } else if (stat || line instanceof AST_DefinitionsLike && !(line instanceof AST_Var)) {
18773 return false;
18774 } else {
18775 stat = line;
18776 }
18777 }
18778 return stat;
18779 }
18780
18781 function sequencesize_2(statements, compressor) {
18782 function cons_seq(right) {
18783 n--;
18784 CHANGED = true;
18785 var left = prev.body;
18786 return make_sequence(left, [left, right]).transform(compressor);
18787 }
18788 var n = 0, prev;
18789 for (var i = 0; i < statements.length; i++) {
18790 var stat = statements[i];
18791 if (prev) {
18792 if (stat instanceof AST_Exit) {
18793 stat.value = cons_seq(stat.value || make_void_0(stat).transform(compressor));
18794 } else if (stat instanceof AST_For) {
18795 if (!(stat.init instanceof AST_DefinitionsLike)) {
18796 const abort = walk(prev.body, node => {
18797 if (node instanceof AST_Scope)
18798 return true;
18799 if (node instanceof AST_Binary
18800 && node.operator === "in") {
18801 return walk_abort;
18802 }
18803 });
18804 if (!abort) {
18805 if (stat.init)
18806 stat.init = cons_seq(stat.init);
18807 else {
18808 stat.init = prev.body;
18809 n--;
18810 CHANGED = true;
18811 }
18812 }
18813 }
18814 } else if (stat instanceof AST_ForIn) {
18815 if (!(stat.init instanceof AST_DefinitionsLike) || stat.init instanceof AST_Var) {
18816 stat.object = cons_seq(stat.object);
18817 }
18818 } else if (stat instanceof AST_If) {
18819 stat.condition = cons_seq(stat.condition);
18820 } else if (stat instanceof AST_Switch) {
18821 stat.expression = cons_seq(stat.expression);
18822 } else if (stat instanceof AST_With) {
18823 stat.expression = cons_seq(stat.expression);
18824 }
18825 }
18826 if (compressor.option("conditionals") && stat instanceof AST_If) {
18827 var decls = [];
18828 var body = to_simple_statement(stat.body, decls);
18829 var alt = to_simple_statement(stat.alternative, decls);
18830 if (body !== false && alt !== false && decls.length > 0) {
18831 var len = decls.length;
18832 decls.push(make_node(AST_If, stat, {
18833 condition: stat.condition,
18834 body: body || make_node(AST_EmptyStatement, stat.body),
18835 alternative: alt
18836 }));
18837 decls.unshift(n, 1);
18838 [].splice.apply(statements, decls);
18839 i += len;
18840 n += len + 1;
18841 prev = null;
18842 CHANGED = true;
18843 continue;
18844 }
18845 }
18846 statements[n++] = stat;
18847 prev = stat instanceof AST_SimpleStatement ? stat : null;
18848 }
18849 statements.length = n;
18850 }
18851
18852 function join_object_assignments(defn, body) {
18853 if (!(defn instanceof AST_Definitions))
18854 return;
18855 var def = defn.definitions[defn.definitions.length - 1];
18856 if (!(def.value instanceof AST_Object))
18857 return;
18858 var exprs;
18859 if (body instanceof AST_Assign && !body.logical) {
18860 exprs = [body];
18861 } else if (body instanceof AST_Sequence) {
18862 exprs = body.expressions.slice();
18863 }
18864 if (!exprs)
18865 return;
18866 var trimmed = false;
18867 do {
18868 var node = exprs[0];
18869 if (!(node instanceof AST_Assign))
18870 break;
18871 if (node.operator != "=")
18872 break;
18873 if (!(node.left instanceof AST_PropAccess))
18874 break;
18875 var sym = node.left.expression;
18876 if (!(sym instanceof AST_SymbolRef))
18877 break;
18878 if (def.name.name != sym.name)
18879 break;
18880 if (!node.right.is_constant_expression(nearest_scope))
18881 break;
18882 var prop = node.left.property;
18883 if (prop instanceof AST_Node) {
18884 prop = prop.evaluate(compressor);
18885 }
18886 if (prop instanceof AST_Node)
18887 break;
18888 prop = "" + prop;
18889 var diff = compressor.option("ecma") < 2015
18890 && compressor.has_directive("use strict") ? function (node) {
18891 return node.key != prop && (node.key && node.key.name != prop);
18892 } : function (node) {
18893 return node.key && node.key.name != prop;
18894 };
18895 if (!def.value.properties.every(diff))
18896 break;
18897 var p = def.value.properties.filter(function (p) { return p.key === prop; })[0];
18898 if (!p) {
18899 def.value.properties.push(make_node(AST_ObjectKeyVal, node, {
18900 key: prop,
18901 value: node.right
18902 }));
18903 } else {
18904 p.value = new AST_Sequence({
18905 start: p.start,
18906 expressions: [p.value.clone(), node.right.clone()],
18907 end: p.end
18908 });
18909 }
18910 exprs.shift();
18911 trimmed = true;
18912 } while (exprs.length);
18913 return trimmed && exprs;
18914 }
18915
18916 function join_consecutive_vars(statements) {
18917 var defs;
18918 for (var i = 0, j = -1, len = statements.length; i < len; i++) {
18919 var stat = statements[i];
18920 var prev = statements[j];
18921 if (stat instanceof AST_Definitions) {
18922 if (prev && prev.TYPE == stat.TYPE) {
18923 prev.definitions = prev.definitions.concat(stat.definitions);
18924 CHANGED = true;
18925 } else if (defs && defs.TYPE == stat.TYPE && declarations_only(stat)) {
18926 defs.definitions = defs.definitions.concat(stat.definitions);
18927 CHANGED = true;
18928 } else {
18929 statements[++j] = stat;
18930 defs = stat;
18931 }
18932 } else if (
18933 stat instanceof AST_Using
18934 && prev instanceof AST_Using
18935 && prev.await === stat.await
18936 ) {
18937 prev.definitions = prev.definitions.concat(stat.definitions);
18938 } else if (stat instanceof AST_Exit) {
18939 stat.value = extract_object_assignments(stat.value);
18940 } else if (stat instanceof AST_For) {
18941 var exprs = join_object_assignments(prev, stat.init);
18942 if (exprs) {
18943 CHANGED = true;
18944 stat.init = exprs.length ? make_sequence(stat.init, exprs) : null;
18945 statements[++j] = stat;
18946 } else if (
18947 prev instanceof AST_Var
18948 && (!stat.init || stat.init.TYPE == prev.TYPE)
18949 ) {
18950 if (stat.init) {
18951 prev.definitions = prev.definitions.concat(stat.init.definitions);
18952 }
18953 stat.init = prev;
18954 statements[j] = stat;
18955 CHANGED = true;
18956 } else if (
18957 defs instanceof AST_Var
18958 && stat.init instanceof AST_Var
18959 && declarations_only(stat.init)
18960 ) {
18961 defs.definitions = defs.definitions.concat(stat.init.definitions);
18962 stat.init = null;
18963 statements[++j] = stat;
18964 CHANGED = true;
18965 } else {
18966 statements[++j] = stat;
18967 }
18968 } else if (stat instanceof AST_ForIn) {
18969 stat.object = extract_object_assignments(stat.object);
18970 } else if (stat instanceof AST_If) {
18971 stat.condition = extract_object_assignments(stat.condition);
18972 } else if (stat instanceof AST_SimpleStatement) {
18973 var exprs = join_object_assignments(prev, stat.body);
18974 if (exprs) {
18975 CHANGED = true;
18976 if (!exprs.length)
18977 continue;
18978 stat.body = make_sequence(stat.body, exprs);
18979 }
18980 statements[++j] = stat;
18981 } else if (stat instanceof AST_Switch) {
18982 stat.expression = extract_object_assignments(stat.expression);
18983 } else if (stat instanceof AST_With) {
18984 stat.expression = extract_object_assignments(stat.expression);
18985 } else {
18986 statements[++j] = stat;
18987 }
18988 }
18989 statements.length = j + 1;
18990
18991 function extract_object_assignments(value) {
18992 statements[++j] = stat;
18993 var exprs = join_object_assignments(prev, value);
18994 if (exprs) {
18995 CHANGED = true;
18996 if (exprs.length) {
18997 return make_sequence(value, exprs);
18998 } else if (value instanceof AST_Sequence) {
18999 return value.tail_node().left;
19000 } else {
19001 return value.left;
19002 }
19003 }
19004 return value;
19005 }
19006 }
19007}
19008
19009/***********************************************************************
19010
19011 A JavaScript tokenizer / parser / beautifier / compressor.
19012 https://github.com/mishoo/UglifyJS2
19013
19014 -------------------------------- (C) ---------------------------------
19015
19016 Author: Mihai Bazon
19017 <mihai.bazon@gmail.com>
19018 http://mihai.bazon.net/blog
19019
19020 Distributed under the BSD license:
19021
19022 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
19023
19024 Redistribution and use in source and binary forms, with or without
19025 modification, are permitted provided that the following conditions
19026 are met:
19027
19028 * Redistributions of source code must retain the above
19029 copyright notice, this list of conditions and the following
19030 disclaimer.
19031
19032 * Redistributions in binary form must reproduce the above
19033 copyright notice, this list of conditions and the following
19034 disclaimer in the documentation and/or other materials
19035 provided with the distribution.
19036
19037 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
19038 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19039 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19040 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
19041 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
19042 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19043 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
19044 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
19045 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
19046 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
19047 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
19048 SUCH DAMAGE.
19049
19050 ***********************************************************************/
19051
19052/**
19053 * Module that contains the inlining logic.
19054 *
19055 * @module
19056 *
19057 * The stars of the show are `inline_into_symbolref` and `inline_into_call`.
19058 */
19059
19060function within_array_or_object_literal(compressor) {
19061 var node, level = 0;
19062 while (node = compressor.parent(level++)) {
19063 if (node instanceof AST_Statement) return false;
19064 if (node instanceof AST_Array
19065 || node instanceof AST_ObjectKeyVal
19066 || node instanceof AST_Object) {
19067 return true;
19068 }
19069 }
19070 return false;
19071}
19072
19073function scope_encloses_variables_in_this_scope(scope, pulled_scope) {
19074 for (const enclosed of pulled_scope.enclosed) {
19075 if (pulled_scope.variables.has(enclosed.name)) {
19076 continue;
19077 }
19078 const looked_up = scope.find_variable(enclosed.name);
19079 if (looked_up) {
19080 if (looked_up === enclosed) continue;
19081 return true;
19082 }
19083 }
19084 return false;
19085}
19086
19087/**
19088 * An extra check function for `top_retain` option, compare the length of const identifier
19089 * and init value length and return true if init value is longer than identifier. for example:
19090 * ```
19091 * // top_retain: ["example"]
19092 * const example = 100
19093 * ```
19094 * it will return false because length of "100" is short than identifier "example".
19095 */
19096function is_const_symbol_short_than_init_value(def, fixed_value) {
19097 if (def.orig.length === 1 && fixed_value) {
19098 const init_value_length = fixed_value.size();
19099 const identifer_length = def.name.length;
19100 return init_value_length > identifer_length;
19101 }
19102 return true;
19103}
19104
19105function inline_into_symbolref(self, compressor) {
19106 if (compressor.in_computed_key()) return self;
19107
19108 const parent = compressor.parent();
19109 const def = self.definition();
19110 const nearest_scope = compressor.find_scope();
19111 let fixed = self.fixed_value();
19112 if (
19113 compressor.top_retain &&
19114 def.global &&
19115 compressor.top_retain(def) &&
19116 // when identifier is in top_retain option dose not mean we can always inline it.
19117 // if identifier name is longer then init value, we can replace it.
19118 is_const_symbol_short_than_init_value(def, fixed)
19119 ) {
19120 // keep it
19121 def.fixed = false;
19122 def.single_use = false;
19123 return self;
19124 }
19125
19126 if (dont_inline_lambda_in_loop(compressor, fixed)) return self;
19127
19128 let single_use = def.single_use
19129 && !(parent instanceof AST_Call
19130 && (parent.is_callee_pure(compressor))
19131 || has_annotation(parent, _NOINLINE))
19132 && !(parent instanceof AST_Export
19133 && fixed instanceof AST_Lambda
19134 && fixed.name);
19135
19136 if (single_use && fixed instanceof AST_Node) {
19137 single_use =
19138 !fixed.has_side_effects(compressor)
19139 && !fixed.may_throw(compressor);
19140 }
19141
19142 if (fixed instanceof AST_Class && def.scope !== self.scope) {
19143 return self;
19144 }
19145
19146 if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
19147 if (retain_top_func(fixed, compressor)) {
19148 single_use = false;
19149 } else if (def.scope !== self.scope
19150 && (def.escaped == 1
19151 || has_flag(fixed, INLINED)
19152 || within_array_or_object_literal(compressor)
19153 || !compressor.option("reduce_funcs"))) {
19154 single_use = false;
19155 } else if (is_recursive_ref(compressor, def)) {
19156 single_use = false;
19157 } else if (def.scope !== self.scope || def.orig[0] instanceof AST_SymbolFunarg) {
19158 single_use = fixed.is_constant_expression(self.scope);
19159 if (single_use == "f") {
19160 var scope = self.scope;
19161 do {
19162 if (scope instanceof AST_Defun || is_func_expr(scope)) {
19163 set_flag(scope, INLINED);
19164 }
19165 } while (scope = scope.parent_scope);
19166 }
19167 }
19168 }
19169
19170 if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
19171 single_use =
19172 def.scope === self.scope
19173 && !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
19174 || parent instanceof AST_Call
19175 && parent.expression === self
19176 && !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
19177 && !(fixed.name && fixed.name.definition().recursive_refs > 0);
19178 }
19179
19180 if (single_use && fixed) {
19181 if (fixed instanceof AST_DefClass) {
19182 set_flag(fixed, SQUEEZED);
19183 fixed = make_node(AST_ClassExpression, fixed, fixed);
19184 }
19185 if (fixed instanceof AST_Defun) {
19186 set_flag(fixed, SQUEEZED);
19187 fixed = make_node(AST_Function, fixed, fixed);
19188 }
19189 if (def.recursive_refs > 0 && fixed.name instanceof AST_SymbolDefun) {
19190 const defun_def = fixed.name.definition();
19191 let lambda_def = fixed.variables.get(fixed.name.name);
19192 let name = lambda_def && lambda_def.orig[0];
19193 if (!(name instanceof AST_SymbolLambda)) {
19194 name = make_node(AST_SymbolLambda, fixed.name, fixed.name);
19195 name.scope = fixed;
19196 fixed.name = name;
19197 lambda_def = fixed.def_function(name);
19198 }
19199 walk(fixed, node => {
19200 if (node instanceof AST_SymbolRef && node.definition() === defun_def) {
19201 node.thedef = lambda_def;
19202 lambda_def.references.push(node);
19203 }
19204 });
19205 }
19206 if (
19207 (fixed instanceof AST_Lambda || fixed instanceof AST_Class)
19208 && fixed.parent_scope !== nearest_scope
19209 ) {
19210 fixed = fixed.clone(true, compressor.get_toplevel());
19211
19212 nearest_scope.add_child_scope(fixed);
19213 }
19214 return fixed.optimize(compressor);
19215 }
19216
19217 // multiple uses
19218 if (fixed) {
19219 let replace;
19220
19221 if (fixed instanceof AST_This) {
19222 if (!(def.orig[0] instanceof AST_SymbolFunarg)
19223 && def.references.every((ref) =>
19224 def.scope === ref.scope
19225 )) {
19226 replace = fixed;
19227 }
19228 } else {
19229 var ev = fixed.evaluate(compressor);
19230 if (
19231 ev !== fixed
19232 && (compressor.option("unsafe_regexp") || !(ev instanceof RegExp))
19233 ) {
19234 replace = make_node_from_constant(ev, fixed);
19235 }
19236 }
19237
19238 if (replace) {
19239 const name_length = self.size(compressor);
19240 const replace_size = replace.size(compressor);
19241
19242 let overhead = 0;
19243 if (compressor.option("unused") && !compressor.exposed(def)) {
19244 overhead =
19245 (name_length + 2 + fixed.size(compressor)) /
19246 (def.references.length - def.assignments);
19247 }
19248
19249 if (replace_size <= name_length + overhead) {
19250 return replace;
19251 }
19252 }
19253 }
19254
19255 return self;
19256}
19257
19258function inline_into_call(self, compressor) {
19259 if (compressor.in_computed_key()) return self;
19260
19261 var exp = self.expression;
19262 var fn = exp;
19263 var simple_args = self.args.every((arg) => !(arg instanceof AST_Expansion));
19264
19265 if (compressor.option("reduce_vars")
19266 && fn instanceof AST_SymbolRef
19267 && !has_annotation(self, _NOINLINE)
19268 ) {
19269 const fixed = fn.fixed_value();
19270
19271 if (
19272 retain_top_func(fixed, compressor)
19273 || !compressor.toplevel.funcs && exp.definition().global
19274 ) {
19275 return self;
19276 }
19277
19278 fn = fixed;
19279 }
19280
19281 if (
19282 dont_inline_lambda_in_loop(compressor, fn)
19283 && !has_annotation(self, _INLINE)
19284 ) return self;
19285
19286 var is_func = fn instanceof AST_Lambda;
19287
19288 var stat = is_func && fn.body[0];
19289 var is_regular_func = is_func && !fn.is_generator && !fn.async;
19290 var can_inline = is_regular_func && compressor.option("inline") && !self.is_callee_pure(compressor);
19291 if (can_inline && stat instanceof AST_Return) {
19292 let returned = stat.value;
19293 if (!returned || returned.is_constant_expression()) {
19294 if (returned) {
19295 returned = returned.clone(true);
19296 } else {
19297 returned = make_void_0(self);
19298 }
19299 const args = self.args.concat(returned);
19300 return make_sequence(self, args).optimize(compressor);
19301 }
19302
19303 // optimize identity function
19304 if (
19305 fn.argnames.length === 1
19306 && (fn.argnames[0] instanceof AST_SymbolFunarg)
19307 && self.args.length < 2
19308 && !(self.args[0] instanceof AST_Expansion)
19309 && returned instanceof AST_SymbolRef
19310 && returned.name === fn.argnames[0].name
19311 ) {
19312 const replacement =
19313 (self.args[0] || make_void_0()).optimize(compressor);
19314
19315 let parent;
19316 if (
19317 replacement instanceof AST_PropAccess
19318 && (parent = compressor.parent()) instanceof AST_Call
19319 && parent.expression === self
19320 ) {
19321 // identity function was being used to remove `this`, like in
19322 //
19323 // id(bag.no_this)(...)
19324 //
19325 // Replace with a larger but more effish (0, bag.no_this) wrapper.
19326
19327 return make_sequence(self, [
19328 make_node(AST_Number, self, { value: 0 }),
19329 replacement
19330 ]);
19331 }
19332 // replace call with first argument or undefined if none passed
19333 return replacement;
19334 }
19335 }
19336
19337 if (can_inline) {
19338 var scope, in_loop, level = -1;
19339 let def;
19340 let returned_value;
19341 let nearest_scope;
19342 if (simple_args
19343 && !fn.uses_arguments
19344 && !(compressor.parent() instanceof AST_Class)
19345 && !(fn.name && fn instanceof AST_Function)
19346 && (returned_value = can_flatten_body(stat))
19347 && (exp === fn
19348 || has_annotation(self, _INLINE)
19349 || compressor.option("unused")
19350 && (def = exp.definition()).references.length == 1
19351 && !is_recursive_ref(compressor, def)
19352 && fn.is_constant_expression(exp.scope))
19353 && !has_annotation(self, _PURE | _NOINLINE)
19354 && !fn.contains_this()
19355 && can_inject_symbols()
19356 && (nearest_scope = compressor.find_scope())
19357 && !scope_encloses_variables_in_this_scope(nearest_scope, fn)
19358 && !(function in_default_assign() {
19359 // Due to the fact function parameters have their own scope
19360 // which can't use `var something` in the function body within,
19361 // we simply don't inline into DefaultAssign.
19362 let i = 0;
19363 let p;
19364 while ((p = compressor.parent(i++))) {
19365 if (p instanceof AST_DefaultAssign) return true;
19366 if (p instanceof AST_Block) break;
19367 }
19368 return false;
19369 })()
19370 && !(scope instanceof AST_Class)
19371 ) {
19372 set_flag(fn, SQUEEZED);
19373 nearest_scope.add_child_scope(fn);
19374 return make_sequence(self, flatten_fn(returned_value)).optimize(compressor);
19375 }
19376 }
19377
19378 if (can_inline && has_annotation(self, _INLINE)) {
19379 set_flag(fn, SQUEEZED);
19380 fn = make_node(fn.CTOR === AST_Defun ? AST_Function : fn.CTOR, fn, fn);
19381 fn = fn.clone(true);
19382 fn.figure_out_scope({}, {
19383 parent_scope: compressor.find_scope(),
19384 toplevel: compressor.get_toplevel()
19385 });
19386
19387 return make_node(AST_Call, self, {
19388 expression: fn,
19389 args: self.args,
19390 }).optimize(compressor);
19391 }
19392
19393 const can_drop_this_call = is_regular_func && compressor.option("side_effects") && fn.body.every(is_empty);
19394 if (can_drop_this_call) {
19395 var args = self.args.concat(make_void_0(self));
19396 return make_sequence(self, args).optimize(compressor);
19397 }
19398
19399 if (compressor.option("negate_iife")
19400 && compressor.parent() instanceof AST_SimpleStatement
19401 && is_iife_call(self)) {
19402 return self.negate(compressor, true);
19403 }
19404
19405 var ev = self.evaluate(compressor);
19406 if (ev !== self) {
19407 ev = make_node_from_constant(ev, self).optimize(compressor);
19408 return best_of(compressor, ev, self);
19409 }
19410
19411 return self;
19412
19413 function return_value(stat) {
19414 if (!stat) return make_void_0(self);
19415 if (stat instanceof AST_Return) {
19416 if (!stat.value) return make_void_0(self);
19417 return stat.value.clone(true);
19418 }
19419 if (stat instanceof AST_SimpleStatement) {
19420 return make_node(AST_UnaryPrefix, stat, {
19421 operator: "void",
19422 expression: stat.body.clone(true)
19423 });
19424 }
19425 }
19426
19427 function can_flatten_body(stat) {
19428 var body = fn.body;
19429 var len = body.length;
19430 if (compressor.option("inline") < 3) {
19431 return len == 1 && return_value(stat);
19432 }
19433 stat = null;
19434 for (var i = 0; i < len; i++) {
19435 var line = body[i];
19436 if (line instanceof AST_Var) {
19437 if (stat && !line.definitions.every((var_def) =>
19438 !var_def.value
19439 )) {
19440 return false;
19441 }
19442 } else if (stat) {
19443 return false;
19444 } else if (!(line instanceof AST_EmptyStatement)) {
19445 stat = line;
19446 }
19447 }
19448 return return_value(stat);
19449 }
19450
19451 function can_inject_args(block_scoped, safe_to_inject) {
19452 for (var i = 0, len = fn.argnames.length; i < len; i++) {
19453 var arg = fn.argnames[i];
19454 if (arg instanceof AST_DefaultAssign) {
19455 if (has_flag(arg.left, UNUSED)) continue;
19456 return false;
19457 }
19458 if (arg instanceof AST_Destructuring) return false;
19459 if (arg instanceof AST_Expansion) {
19460 if (has_flag(arg.expression, UNUSED)) continue;
19461 return false;
19462 }
19463 if (has_flag(arg, UNUSED)) continue;
19464 if (!safe_to_inject
19465 || block_scoped.has(arg.name)
19466 || identifier_atom.has(arg.name)
19467 || scope.conflicting_def(arg.name)) {
19468 return false;
19469 }
19470 if (in_loop) in_loop.push(arg.definition());
19471 }
19472 return true;
19473 }
19474
19475 function can_inject_vars(block_scoped, safe_to_inject) {
19476 var len = fn.body.length;
19477 for (var i = 0; i < len; i++) {
19478 var stat = fn.body[i];
19479 if (!(stat instanceof AST_Var)) continue;
19480 if (!safe_to_inject) return false;
19481 for (var j = stat.definitions.length; --j >= 0;) {
19482 var name = stat.definitions[j].name;
19483 if (name instanceof AST_Destructuring
19484 || block_scoped.has(name.name)
19485 || identifier_atom.has(name.name)
19486 || scope.conflicting_def(name.name)) {
19487 return false;
19488 }
19489 if (in_loop) in_loop.push(name.definition());
19490 }
19491 }
19492 return true;
19493 }
19494
19495 function can_inject_symbols() {
19496 var block_scoped = new Set();
19497 do {
19498 scope = compressor.parent(++level);
19499 if (scope.is_block_scope() && scope.block_scope) {
19500 // TODO this is sometimes undefined during compression.
19501 // But it should always have a value!
19502 scope.block_scope.variables.forEach(function (variable) {
19503 block_scoped.add(variable.name);
19504 });
19505 }
19506 if (scope instanceof AST_Catch) {
19507 // TODO can we delete? AST_Catch is a block scope.
19508 if (scope.argname) {
19509 block_scoped.add(scope.argname.name);
19510 }
19511 } else if (scope instanceof AST_IterationStatement) {
19512 in_loop = [];
19513 } else if (scope instanceof AST_SymbolRef) {
19514 if (scope.fixed_value() instanceof AST_Scope) return false;
19515 }
19516 } while (!(scope instanceof AST_Scope));
19517
19518 var safe_to_inject = !(scope instanceof AST_Toplevel) || compressor.toplevel.vars;
19519 var inline = compressor.option("inline");
19520 if (!can_inject_vars(block_scoped, inline >= 3 && safe_to_inject)) return false;
19521 if (!can_inject_args(block_scoped, inline >= 2 && safe_to_inject)) return false;
19522 return !in_loop || in_loop.length == 0 || !is_reachable(fn, in_loop);
19523 }
19524
19525 function append_var(decls, expressions, name, value) {
19526 var def = name.definition();
19527
19528 // Name already exists, only when a function argument had the same name
19529 const already_appended = scope.variables.has(name.name);
19530 if (!already_appended) {
19531 scope.variables.set(name.name, def);
19532 scope.enclosed.push(def);
19533 decls.push(make_node(AST_VarDef, name, {
19534 name: name,
19535 value: null
19536 }));
19537 }
19538
19539 var sym = make_node(AST_SymbolRef, name, name);
19540 def.references.push(sym);
19541 if (value) expressions.push(make_node(AST_Assign, self, {
19542 operator: "=",
19543 logical: false,
19544 left: sym,
19545 right: value.clone()
19546 }));
19547 }
19548
19549 function flatten_args(decls, expressions) {
19550 var len = fn.argnames.length;
19551 for (var i = self.args.length; --i >= len;) {
19552 expressions.push(self.args[i]);
19553 }
19554 for (i = len; --i >= 0;) {
19555 var name = fn.argnames[i];
19556 var value = self.args[i];
19557 if (has_flag(name, UNUSED) || !name.name || scope.conflicting_def(name.name)) {
19558 if (value) expressions.push(value);
19559 } else {
19560 var symbol = make_node(AST_SymbolVar, name, name);
19561 name.definition().orig.push(symbol);
19562 if (!value && in_loop) value = make_void_0(self);
19563 append_var(decls, expressions, symbol, value);
19564 }
19565 }
19566 decls.reverse();
19567 expressions.reverse();
19568 }
19569
19570 function flatten_vars(decls, expressions) {
19571 var pos = expressions.length;
19572 for (var i = 0, lines = fn.body.length; i < lines; i++) {
19573 var stat = fn.body[i];
19574 if (!(stat instanceof AST_Var)) continue;
19575 for (var j = 0, defs = stat.definitions.length; j < defs; j++) {
19576 var var_def = stat.definitions[j];
19577 var name = var_def.name;
19578 append_var(decls, expressions, name, var_def.value);
19579 if (in_loop && fn.argnames.every((argname) =>
19580 argname.name != name.name
19581 )) {
19582 var def = fn.variables.get(name.name);
19583 var sym = make_node(AST_SymbolRef, name, name);
19584 def.references.push(sym);
19585 expressions.splice(pos++, 0, make_node(AST_Assign, var_def, {
19586 operator: "=",
19587 logical: false,
19588 left: sym,
19589 right: make_void_0(name),
19590 }));
19591 }
19592 }
19593 }
19594 }
19595
19596 function flatten_fn(returned_value) {
19597 var decls = [];
19598 var expressions = [];
19599 flatten_args(decls, expressions);
19600 flatten_vars(decls, expressions);
19601 expressions.push(returned_value);
19602
19603 if (decls.length) {
19604 const i = scope.body.indexOf(compressor.parent(level - 1)) + 1;
19605 scope.body.splice(i, 0, make_node(AST_Var, fn, {
19606 definitions: decls
19607 }));
19608 }
19609
19610 return expressions.map(exp => exp.clone(true));
19611 }
19612}
19613
19614/** prevent inlining functions into loops, for performance reasons */
19615function dont_inline_lambda_in_loop(compressor, maybe_lambda) {
19616 return (
19617 (maybe_lambda instanceof AST_Lambda || maybe_lambda instanceof AST_Class)
19618 && !!compressor.is_within_loop()
19619 );
19620}
19621
19622(function(def_find_defs) {
19623 function to_node(value, orig) {
19624 if (value instanceof AST_Node) {
19625 if (!(value instanceof AST_Constant)) {
19626 // Value may be a function, an array including functions and even a complex assign / block expression,
19627 // so it should never be shared in different places.
19628 // Otherwise wrong information may be used in the compression phase
19629 value = value.clone(true);
19630 }
19631 return make_node(value.CTOR, orig, value);
19632 }
19633 if (Array.isArray(value)) return make_node(AST_Array, orig, {
19634 elements: value.map(function(value) {
19635 return to_node(value, orig);
19636 })
19637 });
19638 if (value && typeof value == "object") {
19639 var props = [];
19640 for (var key in value) if (HOP(value, key)) {
19641 props.push(make_node(AST_ObjectKeyVal, orig, {
19642 key: key,
19643 value: to_node(value[key], orig)
19644 }));
19645 }
19646 return make_node(AST_Object, orig, {
19647 properties: props
19648 });
19649 }
19650 return make_node_from_constant(value, orig);
19651 }
19652
19653 AST_Toplevel.DEFMETHOD("resolve_defines", function(compressor) {
19654 if (!compressor.option("global_defs")) return this;
19655 this.figure_out_scope({ ie8: compressor.option("ie8") });
19656 return this.transform(new TreeTransformer(function(node) {
19657 var def = node._find_defs(compressor, "");
19658 if (!def) return;
19659 var level = 0, child = node, parent;
19660 while (parent = this.parent(level++)) {
19661 if (!(parent instanceof AST_PropAccess)) break;
19662 if (parent.expression !== child) break;
19663 child = parent;
19664 }
19665 if (is_lhs(child, parent)) {
19666 return;
19667 }
19668 return def;
19669 }));
19670 });
19671 def_find_defs(AST_Node, noop);
19672 def_find_defs(AST_Chain, function(compressor, suffix) {
19673 return this.expression._find_defs(compressor, suffix);
19674 });
19675 def_find_defs(AST_Dot, function(compressor, suffix) {
19676 return this.expression._find_defs(compressor, "." + this.property + suffix);
19677 });
19678 def_find_defs(AST_SymbolDeclaration, function() {
19679 if (!this.global()) return;
19680 });
19681 def_find_defs(AST_SymbolRef, function(compressor, suffix) {
19682 if (!this.global()) return;
19683 var defines = compressor.option("global_defs");
19684 var name = this.name + suffix;
19685 if (HOP(defines, name)) return to_node(defines[name], this);
19686 });
19687 def_find_defs(AST_ImportMeta, function(compressor, suffix) {
19688 var defines = compressor.option("global_defs");
19689 var name = "import.meta" + suffix;
19690 if (HOP(defines, name)) return to_node(defines[name], this);
19691 });
19692})(function(node, func) {
19693 node.DEFMETHOD("_find_defs", func);
19694});
19695
19696/***********************************************************************
19697
19698 A JavaScript tokenizer / parser / beautifier / compressor.
19699 https://github.com/mishoo/UglifyJS2
19700
19701 -------------------------------- (C) ---------------------------------
19702
19703 Author: Mihai Bazon
19704 <mihai.bazon@gmail.com>
19705 http://mihai.bazon.net/blog
19706
19707 Distributed under the BSD license:
19708
19709 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
19710
19711 Redistribution and use in source and binary forms, with or without
19712 modification, are permitted provided that the following conditions
19713 are met:
19714
19715 * Redistributions of source code must retain the above
19716 copyright notice, this list of conditions and the following
19717 disclaimer.
19718
19719 * Redistributions in binary form must reproduce the above
19720 copyright notice, this list of conditions and the following
19721 disclaimer in the documentation and/or other materials
19722 provided with the distribution.
19723
19724 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
19725 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19726 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19727 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
19728 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
19729 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19730 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
19731 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
19732 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
19733 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
19734 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
19735 SUCH DAMAGE.
19736
19737 ***********************************************************************/
19738
19739class Compressor extends TreeWalker {
19740 constructor(options, { false_by_default = false, mangle_options = false }) {
19741 super();
19742 if (options.defaults !== undefined && !options.defaults) false_by_default = true;
19743 this.options = defaults(options, {
19744 arguments : false,
19745 arrows : !false_by_default,
19746 booleans : !false_by_default,
19747 booleans_as_integers : false,
19748 collapse_vars : !false_by_default,
19749 comparisons : !false_by_default,
19750 computed_props: !false_by_default,
19751 conditionals : !false_by_default,
19752 dead_code : !false_by_default,
19753 defaults : true,
19754 directives : !false_by_default,
19755 drop_console : false,
19756 drop_debugger : !false_by_default,
19757 ecma : 5,
19758 builtins_ecma : 5,
19759 builtins_pure : false,
19760 evaluate : !false_by_default,
19761 expression : false,
19762 global_defs : false,
19763 hoist_funs : false,
19764 hoist_props : !false_by_default,
19765 hoist_vars : false,
19766 ie8 : false,
19767 if_return : !false_by_default,
19768 inline : !false_by_default,
19769 join_vars : !false_by_default,
19770 keep_classnames: false,
19771 keep_fargs : true,
19772 keep_fnames : false,
19773 keep_infinity : false,
19774 lhs_constants : !false_by_default,
19775 loops : !false_by_default,
19776 module : false,
19777 negate_iife : !false_by_default,
19778 passes : 1,
19779 properties : !false_by_default,
19780 pure_getters : !false_by_default && "strict",
19781 pure_funcs : null,
19782 pure_new : false,
19783 reduce_funcs : !false_by_default,
19784 reduce_vars : !false_by_default,
19785 sequences : !false_by_default,
19786 side_effects : !false_by_default,
19787 switches : !false_by_default,
19788 top_retain : null,
19789 toplevel : !!(options && options["top_retain"]),
19790 typeofs : !false_by_default,
19791 unsafe : false,
19792 unsafe_arrows : false,
19793 unsafe_comps : false,
19794 unsafe_Function: false,
19795 unsafe_math : false,
19796 unsafe_symbols: false,
19797 unsafe_methods: false,
19798 unsafe_proto : false,
19799 unsafe_regexp : false,
19800 unsafe_undefined: false,
19801 unused : !false_by_default,
19802 warnings : false // legacy
19803 }, true);
19804 var global_defs = this.options["global_defs"];
19805 if (typeof global_defs == "object") for (var key in global_defs) {
19806 if (key[0] === "@" && HOP(global_defs, key)) {
19807 global_defs[key.slice(1)] = parse(global_defs[key], {
19808 expression: true
19809 });
19810 }
19811 }
19812 if (this.options["inline"] === true) this.options["inline"] = 3;
19813 var pure_funcs = this.options["pure_funcs"];
19814 if (typeof pure_funcs == "function") {
19815 this.pure_funcs = pure_funcs;
19816 } else {
19817 this.pure_funcs = pure_funcs ? function(node) {
19818 return !pure_funcs.includes(node.expression.print_to_string());
19819 } : return_true;
19820 }
19821 var top_retain = this.options["top_retain"];
19822 if (top_retain instanceof RegExp) {
19823 this.top_retain = function(def) {
19824 return top_retain.test(def.name);
19825 };
19826 } else if (typeof top_retain == "function") {
19827 this.top_retain = top_retain;
19828 } else if (top_retain) {
19829 if (typeof top_retain == "string") {
19830 top_retain = top_retain.split(/,/);
19831 }
19832 this.top_retain = function(def) {
19833 return top_retain.includes(def.name);
19834 };
19835 }
19836 if (this.options["module"]) {
19837 this.directives["use strict"] = true;
19838 this.options["toplevel"] = true;
19839 }
19840 var toplevel = this.options["toplevel"];
19841 this.toplevel = typeof toplevel == "string" ? {
19842 funcs: /funcs/.test(toplevel),
19843 vars: /vars/.test(toplevel)
19844 } : {
19845 funcs: toplevel,
19846 vars: toplevel
19847 };
19848 var sequences = this.options["sequences"];
19849 this.sequences_limit = sequences == 1 ? 800 : sequences | 0;
19850 this.evaluated_regexps = new Map();
19851 this._toplevel = undefined;
19852 this._mangle_options = mangle_options
19853 ? format_mangler_options(mangle_options)
19854 : mangle_options;
19855
19856 this.pure_access_globals = pure_access_globals(this);
19857 this.is_pure_native_fn = is_pure_native_fn(this);
19858 this.is_pure_native_method = is_pure_native_method(this);
19859 this.is_pure_native_static_fn = is_pure_native_static_fn(this);
19860 this.is_pure_native_static_property = is_pure_native_static_property(this);
19861 }
19862
19863 mangle_options() {
19864 var nth_identifier = this._mangle_options && this._mangle_options.nth_identifier || base54;
19865 var module = this._mangle_options && this._mangle_options.module || this.option("module");
19866 return { ie8: this.option("ie8"), nth_identifier, module };
19867 }
19868
19869 option(key) {
19870 return this.options[key];
19871 }
19872
19873 exposed(def) {
19874 if (def.export) return true;
19875 if (def.global) for (var i = 0, len = def.orig.length; i < len; i++)
19876 if (!this.toplevel[def.orig[i] instanceof AST_SymbolDefun ? "funcs" : "vars"])
19877 return true;
19878 return false;
19879 }
19880
19881 in_boolean_context() {
19882 if (!this.option("booleans")) return false;
19883 var self = this.self();
19884 for (var i = 0, p; p = this.parent(i); i++) {
19885 if (p instanceof AST_SimpleStatement
19886 || p instanceof AST_Conditional && p.condition === self
19887 || p instanceof AST_DWLoop && p.condition === self
19888 || p instanceof AST_For && p.condition === self
19889 || p instanceof AST_If && p.condition === self
19890 || p instanceof AST_UnaryPrefix && p.operator == "!" && p.expression === self) {
19891 return true;
19892 }
19893 if (
19894 p instanceof AST_Binary
19895 && (
19896 p.operator == "&&"
19897 || p.operator == "||"
19898 || p.operator == "??"
19899 )
19900 || p instanceof AST_Conditional
19901 || p.tail_node() === self
19902 ) {
19903 self = p;
19904 } else {
19905 return false;
19906 }
19907 }
19908 }
19909
19910 /** True if compressor.self()'s result will be turned into a 32-bit integer.
19911 * ex:
19912 * ~{expr}
19913 * (1, 2, {expr}) | 0
19914 **/
19915 in_32_bit_context(other_operand_must_be_number) {
19916 if (!this.option("evaluate")) return false;
19917 var self = this.self();
19918 for (var i = 0, p; p = this.parent(i); i++) {
19919 if (p instanceof AST_Binary && bitwise_binop.has(p.operator)) {
19920 if (other_operand_must_be_number) {
19921 return (self === p.left ? p.right : p.left).is_number(this);
19922 } else {
19923 return true;
19924 }
19925 }
19926 if (p instanceof AST_UnaryPrefix) {
19927 return p.operator === "~";
19928 }
19929 if (
19930 p instanceof AST_Binary
19931 && (
19932 // Don't talk about p.left. Can change branch taken
19933 p.operator == "&&" && p.right === self
19934 || p.operator == "||" && p.right === self
19935 || p.operator == "??" && p.right === self
19936 )
19937 || p instanceof AST_Conditional && p.condition !== self
19938 || p.tail_node() === self
19939 ) {
19940 self = p;
19941 } else {
19942 return false;
19943 }
19944 }
19945 }
19946
19947 in_computed_key() {
19948 if (!this.option("evaluate")) return false;
19949 var self = this.self();
19950 for (var i = 0, p; p = this.parent(i); i++) {
19951 if (p instanceof AST_ObjectProperty && p.key === self) {
19952 return true;
19953 }
19954 }
19955 return false;
19956 }
19957
19958 get_toplevel() {
19959 return this._toplevel;
19960 }
19961
19962 compress(toplevel) {
19963 toplevel = toplevel.resolve_defines(this);
19964 this._toplevel = toplevel;
19965 if (this.option("expression")) {
19966 this._toplevel.process_expression(true);
19967 }
19968 var passes = +this.options.passes || 1;
19969 var min_count = 1 / 0;
19970 var stopping = false;
19971 var mangle = this.mangle_options();
19972 for (var pass = 0; pass < passes; pass++) {
19973 this._toplevel.figure_out_scope(mangle);
19974 if (pass === 0 && this.option("drop_console")) {
19975 // must be run before reduce_vars and compress pass
19976 this._toplevel = this._toplevel.drop_console(this.option("drop_console"));
19977 }
19978 if (pass > 0 || this.option("reduce_vars")) {
19979 this._toplevel.reset_opt_flags(this);
19980 }
19981 this._toplevel = this._toplevel.transform(this);
19982 if (passes > 1) {
19983 let count = 0;
19984 walk(this._toplevel, () => { count++; });
19985 if (count < min_count) {
19986 min_count = count;
19987 stopping = false;
19988 } else if (stopping) {
19989 break;
19990 } else {
19991 stopping = true;
19992 }
19993 }
19994 }
19995 if (this.option("expression")) {
19996 this._toplevel.process_expression(false);
19997 }
19998 toplevel = this._toplevel;
19999 this._toplevel = undefined;
20000 return toplevel;
20001 }
20002
20003 before(node, descend) {
20004 if (has_flag(node, SQUEEZED)) return node;
20005 var was_scope = false;
20006 if (node instanceof AST_Scope) {
20007 node = node.hoist_properties(this);
20008 node = node.hoist_declarations(this);
20009 was_scope = true;
20010 }
20011 // Before https://github.com/mishoo/UglifyJS2/pull/1602 AST_Node.optimize()
20012 // would call AST_Node.transform() if a different instance of AST_Node is
20013 // produced after def_optimize().
20014 // This corrupts TreeWalker.stack, which cause AST look-ups to malfunction.
20015 // Migrate and defer all children's AST_Node.transform() to below, which
20016 // will now happen after this parent AST_Node has been properly substituted
20017 // thus gives a consistent AST snapshot.
20018 descend(node, this);
20019 // Existing code relies on how AST_Node.optimize() worked, and omitting the
20020 // following replacement call would result in degraded efficiency of both
20021 // output and performance.
20022 descend(node, this);
20023 var opt = node.optimize(this);
20024 if (was_scope && opt instanceof AST_Scope) {
20025 opt.drop_unused(this);
20026 descend(opt, this);
20027 }
20028 if (opt === node) set_flag(opt, SQUEEZED);
20029 return opt;
20030 }
20031
20032 /** Alternative to plain is_lhs() which doesn't work within .optimize() */
20033 is_lhs() {
20034 const self = this.stack[this.stack.length - 1];
20035 const parent = this.stack[this.stack.length - 2];
20036 return is_lhs(self, parent);
20037 }
20038}
20039
20040
20041function def_optimize(node, optimizer) {
20042 node.DEFMETHOD("optimize", function(compressor) {
20043 var self = this;
20044 if (has_flag(self, OPTIMIZED)) return self;
20045 if (compressor.has_directive("use asm")) return self;
20046 var opt = optimizer(self, compressor);
20047 set_flag(opt, OPTIMIZED);
20048 return opt;
20049 });
20050}
20051
20052def_optimize(AST_Node, function(self) {
20053 return self;
20054});
20055
20056AST_Toplevel.DEFMETHOD("drop_console", function(options) {
20057 const isArray = Array.isArray(options);
20058 const tt = new TreeTransformer(function(self) {
20059 if (self.TYPE !== "Call") {
20060 return;
20061 }
20062
20063 var exp = self.expression;
20064
20065 if (!(exp instanceof AST_PropAccess)) {
20066 return;
20067 }
20068
20069 var name = exp.expression;
20070 var property = exp.property;
20071 var depth = 2;
20072 while (name.expression) {
20073 property = name.property;
20074 name = name.expression;
20075 depth++;
20076 }
20077
20078 if (isArray && !options.includes(property)) {
20079 return;
20080 }
20081
20082 if (is_undeclared_ref(name) && name.name == "console") {
20083 if (
20084 depth === 3
20085 && !["call", "apply"].includes(exp.property)
20086 && is_used_in_expression(tt)
20087 ) {
20088 // a (used) call to Function.prototype methods (eg: console.log.bind(console))
20089 // but not .call and .apply which would also return undefined.
20090 exp.expression = make_empty_function(self);
20091 set_flag(exp.expression, SQUEEZED);
20092 self.args = [];
20093 } else {
20094 return make_void_0(self);
20095 }
20096 }
20097 });
20098
20099 return this.transform(tt);
20100});
20101
20102AST_Node.DEFMETHOD("equivalent_to", function(node) {
20103 return equivalent_to(this, node);
20104});
20105
20106AST_Scope.DEFMETHOD("process_expression", function(insert, compressor) {
20107 var self = this;
20108 var tt = new TreeTransformer(function(node) {
20109 if (insert && node instanceof AST_SimpleStatement) {
20110 return make_node(AST_Return, node, {
20111 value: node.body
20112 });
20113 }
20114 if (!insert && node instanceof AST_Return) {
20115 if (compressor) {
20116 var value = node.value && node.value.drop_side_effect_free(compressor, true);
20117 return value
20118 ? make_node(AST_SimpleStatement, node, { body: value })
20119 : make_node(AST_EmptyStatement, node);
20120 }
20121 return make_node(AST_SimpleStatement, node, {
20122 body: node.value || make_void_0(node)
20123 });
20124 }
20125 if (node instanceof AST_Class || node instanceof AST_Lambda && node !== self) {
20126 return node;
20127 }
20128 if (node instanceof AST_Block) {
20129 var index = node.body.length - 1;
20130 if (index >= 0) {
20131 node.body[index] = node.body[index].transform(tt);
20132 }
20133 } else if (node instanceof AST_If) {
20134 node.body = node.body.transform(tt);
20135 if (node.alternative) {
20136 node.alternative = node.alternative.transform(tt);
20137 }
20138 } else if (node instanceof AST_With) {
20139 node.body = node.body.transform(tt);
20140 }
20141 return node;
20142 });
20143 self.transform(tt);
20144});
20145
20146AST_Toplevel.DEFMETHOD("reset_opt_flags", function(compressor) {
20147 const self = this;
20148 const reduce_vars = compressor.option("reduce_vars");
20149
20150 const preparation = new TreeWalker(function(node, descend) {
20151 clear_flag(node, CLEAR_BETWEEN_PASSES);
20152 if (reduce_vars) {
20153 if (compressor.top_retain
20154 && node instanceof AST_Defun // Only functions are retained
20155 && preparation.parent() === self
20156 ) {
20157 set_flag(node, TOP);
20158 }
20159 return node.reduce_vars(preparation, descend, compressor);
20160 }
20161 });
20162 // Stack of look-up tables to keep track of whether a `SymbolDef` has been
20163 // properly assigned before use:
20164 // - `push()` & `pop()` when visiting conditional branches
20165 preparation.safe_ids = Object.create(null);
20166 preparation.in_loop = null;
20167 preparation.loop_ids = new Map();
20168 preparation.defs_to_safe_ids = new Map();
20169 self.walk(preparation);
20170});
20171
20172AST_Symbol.DEFMETHOD("fixed_value", function() {
20173 var fixed = this.thedef.fixed;
20174 if (!fixed || fixed instanceof AST_Node) return fixed;
20175 return fixed();
20176});
20177
20178AST_SymbolRef.DEFMETHOD("is_immutable", function() {
20179 var orig = this.definition().orig;
20180 return orig.length == 1 && orig[0] instanceof AST_SymbolLambda;
20181});
20182
20183function find_variable(compressor, name) {
20184 var scope, i = 0;
20185 while (scope = compressor.parent(i++)) {
20186 if (scope instanceof AST_Scope) break;
20187 if (scope instanceof AST_Catch && scope.argname) {
20188 scope = scope.argname.definition().scope;
20189 break;
20190 }
20191 }
20192 return scope.find_variable(name);
20193}
20194
20195AST_SymbolRef.DEFMETHOD("is_declared", function(compressor) {
20196 return !this.definition().undeclared
20197 || (compressor.option("unsafe") || compressor.option("builtins_pure")) && compressor.pure_access_globals(this.name);
20198});
20199
20200/* -----[ optimizers ]----- */
20201
20202var directives = new Set(["use asm", "use strict"]);
20203def_optimize(AST_Directive, function(self, compressor) {
20204 if (compressor.option("directives")
20205 && (!directives.has(self.value) || compressor.has_directive(self.value) !== self)) {
20206 return make_node(AST_EmptyStatement, self);
20207 }
20208 return self;
20209});
20210
20211def_optimize(AST_Debugger, function(self, compressor) {
20212 if (compressor.option("drop_debugger"))
20213 return make_node(AST_EmptyStatement, self);
20214 return self;
20215});
20216
20217def_optimize(AST_LabeledStatement, function(self, compressor) {
20218 if (self.body instanceof AST_Break
20219 && compressor.loopcontrol_target(self.body) === self.body) {
20220 return make_node(AST_EmptyStatement, self);
20221 }
20222 return self.label.references.length == 0 ? self.body : self;
20223});
20224
20225def_optimize(AST_Block, function(self, compressor) {
20226 tighten_body(self.body, compressor);
20227 return self;
20228});
20229
20230function can_be_extracted_from_if_block(node) {
20231 return !(
20232 node instanceof AST_Const
20233 || node instanceof AST_Let
20234 || node instanceof AST_Using
20235 || node instanceof AST_Class
20236 );
20237}
20238
20239def_optimize(AST_BlockStatement, function(self, compressor) {
20240 tighten_body(self.body, compressor);
20241 switch (self.body.length) {
20242 case 1:
20243 if (!compressor.has_directive("use strict")
20244 && compressor.parent() instanceof AST_If
20245 && can_be_extracted_from_if_block(self.body[0])
20246 || can_be_evicted_from_block(self.body[0])) {
20247 return self.body[0];
20248 }
20249 break;
20250 case 0: return make_node(AST_EmptyStatement, self);
20251 }
20252 return self;
20253});
20254
20255function opt_AST_Lambda(self, compressor) {
20256 tighten_body(self.body, compressor);
20257 if (compressor.option("side_effects")
20258 && self.body.length == 1
20259 && self.body[0] === compressor.has_directive("use strict")) {
20260 self.body.length = 0;
20261 }
20262 return self;
20263}
20264def_optimize(AST_Lambda, opt_AST_Lambda);
20265
20266AST_Scope.DEFMETHOD("hoist_declarations", function(compressor) {
20267 var self = this;
20268 if (compressor.has_directive("use asm")) return self;
20269
20270 var hoist_funs = compressor.option("hoist_funs");
20271 var hoist_vars = compressor.option("hoist_vars");
20272
20273 if (hoist_funs || hoist_vars) {
20274 var dirs = [];
20275 var hoisted = [];
20276 var vars = new Map(), vars_found = 0, var_decl = 0;
20277 // let's count var_decl first, we seem to waste a lot of
20278 // space if we hoist `var` when there's only one.
20279 walk(self, node => {
20280 if (node instanceof AST_Scope && node !== self)
20281 return true;
20282 if (node instanceof AST_Var) {
20283 ++var_decl;
20284 return true;
20285 }
20286 });
20287 hoist_vars = hoist_vars && var_decl > 1;
20288 var tt = new TreeTransformer(
20289 function before(node) {
20290 if (node !== self) {
20291 if (node instanceof AST_Directive) {
20292 dirs.push(node);
20293 return make_node(AST_EmptyStatement, node);
20294 }
20295 if (hoist_funs && node instanceof AST_Defun
20296 && !(tt.parent() instanceof AST_Export)
20297 && tt.parent() === self) {
20298 hoisted.push(node);
20299 return make_node(AST_EmptyStatement, node);
20300 }
20301 if (
20302 hoist_vars
20303 && node instanceof AST_Var
20304 && !node.definitions.some(def => def.name instanceof AST_Destructuring)
20305 ) {
20306 node.definitions.forEach(function(def) {
20307 vars.set(def.name.name, def);
20308 ++vars_found;
20309 });
20310 var seq = node.to_assignments(compressor);
20311 var p = tt.parent();
20312 if (p instanceof AST_ForIn && p.init === node) {
20313 if (seq == null) {
20314 var def = node.definitions[0].name;
20315 return make_node(AST_SymbolRef, def, def);
20316 }
20317 return seq;
20318 }
20319 if (p instanceof AST_For && p.init === node) {
20320 return seq;
20321 }
20322 if (!seq) return make_node(AST_EmptyStatement, node);
20323 return make_node(AST_SimpleStatement, node, {
20324 body: seq
20325 });
20326 }
20327 if (node instanceof AST_Scope)
20328 return node; // to avoid descending in nested scopes
20329 }
20330 }
20331 );
20332 self = self.transform(tt);
20333 if (vars_found > 0) {
20334 // collect only vars which don't show up in self's arguments list
20335 var defs = [];
20336 const is_lambda = self instanceof AST_Lambda;
20337 const args_as_names = is_lambda ? self.args_as_names() : null;
20338 vars.forEach((def, name) => {
20339 if (is_lambda && args_as_names.some((x) => x.name === def.name.name)) {
20340 vars.delete(name);
20341 } else {
20342 def = def.clone();
20343 def.value = null;
20344 defs.push(def);
20345 vars.set(name, def);
20346 }
20347 });
20348 if (defs.length > 0) {
20349 // try to merge in assignments
20350 for (var i = 0; i < self.body.length;) {
20351 if (self.body[i] instanceof AST_SimpleStatement) {
20352 var expr = self.body[i].body, sym, assign;
20353 if (expr instanceof AST_Assign
20354 && expr.operator == "="
20355 && (sym = expr.left) instanceof AST_Symbol
20356 && vars.has(sym.name)
20357 ) {
20358 var def = vars.get(sym.name);
20359 if (def.value) break;
20360 def.value = expr.right;
20361 remove(defs, def);
20362 defs.push(def);
20363 self.body.splice(i, 1);
20364 continue;
20365 }
20366 if (expr instanceof AST_Sequence
20367 && (assign = expr.expressions[0]) instanceof AST_Assign
20368 && assign.operator == "="
20369 && (sym = assign.left) instanceof AST_Symbol
20370 && vars.has(sym.name)
20371 ) {
20372 var def = vars.get(sym.name);
20373 if (def.value) break;
20374 def.value = assign.right;
20375 remove(defs, def);
20376 defs.push(def);
20377 self.body[i].body = make_sequence(expr, expr.expressions.slice(1));
20378 continue;
20379 }
20380 }
20381 if (self.body[i] instanceof AST_EmptyStatement) {
20382 self.body.splice(i, 1);
20383 continue;
20384 }
20385 if (self.body[i] instanceof AST_BlockStatement) {
20386 self.body.splice(i, 1, ...self.body[i].body);
20387 continue;
20388 }
20389 break;
20390 }
20391 defs = make_node(AST_Var, self, {
20392 definitions: defs
20393 });
20394 hoisted.push(defs);
20395 }
20396 }
20397 self.body = dirs.concat(hoisted, self.body);
20398 }
20399 return self;
20400});
20401
20402AST_Scope.DEFMETHOD("hoist_properties", function(compressor) {
20403 var self = this;
20404 if (!compressor.option("hoist_props") || compressor.has_directive("use asm")) return self;
20405 var top_retain = self instanceof AST_Toplevel && compressor.top_retain || return_false;
20406 var defs_by_id = new Map();
20407 var hoister = new TreeTransformer(function(node, descend) {
20408 if (node instanceof AST_VarDef) {
20409 const sym = node.name;
20410 let def;
20411 let value;
20412 if (sym.scope === self
20413 && !(sym instanceof AST_SymbolUsing)
20414 && (def = sym.definition()).escaped != 1
20415 && !def.assignments
20416 && !def.direct_access
20417 && !def.single_use
20418 && !compressor.exposed(def)
20419 && !top_retain(def)
20420 && (value = sym.fixed_value()) === node.value
20421 && value instanceof AST_Object
20422 && !value.properties.some(prop =>
20423 prop instanceof AST_Expansion || prop.computed_key()
20424 )
20425 ) {
20426 descend(node, this);
20427 const defs = new Map();
20428 const assignments = [];
20429 value.properties.forEach(({ key, value }) => {
20430 const scope = hoister.find_scope();
20431 const symbol = self.create_symbol(sym.CTOR, {
20432 source: sym,
20433 scope,
20434 conflict_scopes: new Set([
20435 scope,
20436 ...sym.definition().references.map(ref => ref.scope)
20437 ]),
20438 tentative_name: sym.name + "_" + key
20439 });
20440
20441 defs.set(String(key), symbol.definition());
20442
20443 assignments.push(make_node(AST_VarDef, node, {
20444 name: symbol,
20445 value
20446 }));
20447 });
20448 defs_by_id.set(def.id, defs);
20449 return MAP.splice(assignments);
20450 }
20451 } else if (node instanceof AST_PropAccess
20452 && node.expression instanceof AST_SymbolRef
20453 ) {
20454 const defs = defs_by_id.get(node.expression.definition().id);
20455 if (defs) {
20456 const def = defs.get(String(get_simple_key(node.property)));
20457 const sym = make_node(AST_SymbolRef, node, {
20458 name: def.name,
20459 scope: node.expression.scope,
20460 thedef: def
20461 });
20462 sym.reference({});
20463 return sym;
20464 }
20465 }
20466 });
20467 return self.transform(hoister);
20468});
20469
20470def_optimize(AST_SimpleStatement, function(self, compressor) {
20471 if (compressor.option("side_effects")) {
20472 var body = self.body;
20473 var node = body.drop_side_effect_free(compressor, true);
20474 if (!node) {
20475 return make_node(AST_EmptyStatement, self);
20476 }
20477 if (node !== body) {
20478 return make_node(AST_SimpleStatement, self, { body: node });
20479 }
20480 }
20481 return self;
20482});
20483
20484def_optimize(AST_While, function(self, compressor) {
20485 return compressor.option("loops") ? make_node(AST_For, self, self).optimize(compressor) : self;
20486});
20487
20488def_optimize(AST_Do, function(self, compressor) {
20489 if (!compressor.option("loops")) return self;
20490 var cond = self.condition.tail_node().evaluate(compressor);
20491 if (!(cond instanceof AST_Node)) {
20492 if (cond) return make_node(AST_For, self, {
20493 body: make_node(AST_BlockStatement, self.body, {
20494 body: [
20495 self.body,
20496 make_node(AST_SimpleStatement, self.condition, {
20497 body: self.condition
20498 })
20499 ]
20500 })
20501 }).optimize(compressor);
20502 if (!has_break_or_continue(self, compressor.parent())) {
20503 return make_node(AST_BlockStatement, self.body, {
20504 body: [
20505 self.body,
20506 make_node(AST_SimpleStatement, self.condition, {
20507 body: self.condition
20508 })
20509 ]
20510 }).optimize(compressor);
20511 }
20512 }
20513 return self;
20514});
20515
20516function if_break_in_loop(self, compressor) {
20517 var first = self.body instanceof AST_BlockStatement ? self.body.body[0] : self.body;
20518 if (compressor.option("dead_code") && is_break(first)) {
20519 var body = [];
20520 if (self.init instanceof AST_Statement) {
20521 body.push(self.init);
20522 } else if (self.init) {
20523 body.push(make_node(AST_SimpleStatement, self.init, {
20524 body: self.init
20525 }));
20526 }
20527 if (self.condition) {
20528 body.push(make_node(AST_SimpleStatement, self.condition, {
20529 body: self.condition
20530 }));
20531 }
20532 extract_from_unreachable_code(compressor, self.body, body);
20533 return make_node(AST_BlockStatement, self, {
20534 body: body
20535 });
20536 }
20537 if (first instanceof AST_If) {
20538 if (is_break(first.body)) {
20539 if (self.condition) {
20540 self.condition = make_node(AST_Binary, self.condition, {
20541 left: self.condition,
20542 operator: "&&",
20543 right: first.condition.negate(compressor),
20544 });
20545 } else {
20546 self.condition = first.condition.negate(compressor);
20547 }
20548 drop_it(first.alternative);
20549 } else if (is_break(first.alternative)) {
20550 if (self.condition) {
20551 self.condition = make_node(AST_Binary, self.condition, {
20552 left: self.condition,
20553 operator: "&&",
20554 right: first.condition,
20555 });
20556 } else {
20557 self.condition = first.condition;
20558 }
20559 drop_it(first.body);
20560 }
20561 }
20562 return self;
20563
20564 function is_break(node) {
20565 return node instanceof AST_Break
20566 && compressor.loopcontrol_target(node) === compressor.self();
20567 }
20568
20569 function drop_it(rest) {
20570 rest = as_statement_array(rest);
20571 if (self.body instanceof AST_BlockStatement) {
20572 self.body = self.body.clone();
20573 self.body.body = rest.concat(self.body.body.slice(1));
20574 self.body = self.body.transform(compressor);
20575 } else {
20576 self.body = make_node(AST_BlockStatement, self.body, {
20577 body: rest
20578 }).transform(compressor);
20579 }
20580 self = if_break_in_loop(self, compressor);
20581 }
20582}
20583
20584def_optimize(AST_For, function(self, compressor) {
20585 if (!compressor.option("loops")) return self;
20586 if (compressor.option("side_effects") && self.init) {
20587 self.init = self.init.drop_side_effect_free(compressor);
20588 }
20589 if (self.condition) {
20590 var cond = self.condition.evaluate(compressor);
20591 if (!(cond instanceof AST_Node)) {
20592 if (cond) self.condition = null;
20593 else if (!compressor.option("dead_code")) {
20594 var orig = self.condition;
20595 self.condition = make_node_from_constant(cond, self.condition);
20596 self.condition = best_of_expression(self.condition.transform(compressor), orig);
20597 }
20598 }
20599 if (compressor.option("dead_code")) {
20600 if (cond instanceof AST_Node) cond = self.condition.tail_node().evaluate(compressor);
20601 if (!cond) {
20602 var body = [];
20603 extract_from_unreachable_code(compressor, self.body, body);
20604 if (self.init instanceof AST_Statement) {
20605 body.push(self.init);
20606 } else if (self.init) {
20607 body.push(make_node(AST_SimpleStatement, self.init, {
20608 body: self.init
20609 }));
20610 }
20611 body.push(make_node(AST_SimpleStatement, self.condition, {
20612 body: self.condition
20613 }));
20614 return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor);
20615 }
20616 }
20617 }
20618 return if_break_in_loop(self, compressor);
20619});
20620
20621def_optimize(AST_If, function(self, compressor) {
20622 if (is_empty(self.alternative)) self.alternative = null;
20623
20624 if (!compressor.option("conditionals")) return self;
20625 // if condition can be statically determined, drop
20626 // one of the blocks. note, statically determined implies
20627 // “has no side effects”; also it doesn't work for cases like
20628 // `x && true`, though it probably should.
20629 var cond = self.condition.evaluate(compressor);
20630 if (!compressor.option("dead_code") && !(cond instanceof AST_Node)) {
20631 var orig = self.condition;
20632 self.condition = make_node_from_constant(cond, orig);
20633 self.condition = best_of_expression(self.condition.transform(compressor), orig);
20634 }
20635 if (compressor.option("dead_code")) {
20636 if (cond instanceof AST_Node) cond = self.condition.tail_node().evaluate(compressor);
20637 if (!cond) {
20638 var body = [];
20639 extract_from_unreachable_code(compressor, self.body, body);
20640 body.push(make_node(AST_SimpleStatement, self.condition, {
20641 body: self.condition
20642 }));
20643 if (self.alternative) body.push(self.alternative);
20644 return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor);
20645 } else if (!(cond instanceof AST_Node)) {
20646 var body = [];
20647 body.push(make_node(AST_SimpleStatement, self.condition, {
20648 body: self.condition
20649 }));
20650 body.push(self.body);
20651 if (self.alternative) {
20652 extract_from_unreachable_code(compressor, self.alternative, body);
20653 }
20654 return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor);
20655 }
20656 }
20657 var negated = self.condition.negate(compressor);
20658 var self_condition_length = self.condition.size();
20659 var negated_length = negated.size();
20660 var negated_is_best = negated_length < self_condition_length;
20661 if (self.alternative && negated_is_best) {
20662 negated_is_best = false; // because we already do the switch here.
20663 // no need to swap values of self_condition_length and negated_length
20664 // here because they are only used in an equality comparison later on.
20665 self.condition = negated;
20666 var tmp = self.body;
20667 self.body = self.alternative || make_node(AST_EmptyStatement, self);
20668 self.alternative = tmp;
20669 }
20670 if (is_empty(self.body) && is_empty(self.alternative)) {
20671 return make_node(AST_SimpleStatement, self.condition, {
20672 body: self.condition.clone()
20673 }).optimize(compressor);
20674 }
20675 if (self.body instanceof AST_SimpleStatement
20676 && self.alternative instanceof AST_SimpleStatement) {
20677 return make_node(AST_SimpleStatement, self, {
20678 body: make_node(AST_Conditional, self, {
20679 condition : self.condition,
20680 consequent : self.body.body,
20681 alternative : self.alternative.body
20682 })
20683 }).optimize(compressor);
20684 }
20685 if (is_empty(self.alternative) && self.body instanceof AST_SimpleStatement) {
20686 if (self_condition_length === negated_length && !negated_is_best
20687 && self.condition instanceof AST_Binary && self.condition.operator == "||") {
20688 // although the code length of self.condition and negated are the same,
20689 // negated does not require additional surrounding parentheses.
20690 // see https://github.com/mishoo/UglifyJS2/issues/979
20691 negated_is_best = true;
20692 }
20693 if (negated_is_best) return make_node(AST_SimpleStatement, self, {
20694 body: make_node(AST_Binary, self, {
20695 operator : "||",
20696 left : negated,
20697 right : self.body.body
20698 })
20699 }).optimize(compressor);
20700 return make_node(AST_SimpleStatement, self, {
20701 body: make_node(AST_Binary, self, {
20702 operator : "&&",
20703 left : self.condition,
20704 right : self.body.body
20705 })
20706 }).optimize(compressor);
20707 }
20708 if (self.body instanceof AST_EmptyStatement
20709 && self.alternative instanceof AST_SimpleStatement) {
20710 return make_node(AST_SimpleStatement, self, {
20711 body: make_node(AST_Binary, self, {
20712 operator : "||",
20713 left : self.condition,
20714 right : self.alternative.body
20715 })
20716 }).optimize(compressor);
20717 }
20718 if (self.body instanceof AST_Exit
20719 && self.alternative instanceof AST_Exit
20720 && self.body.TYPE == self.alternative.TYPE) {
20721 return make_node(self.body.CTOR, self, {
20722 value: make_node(AST_Conditional, self, {
20723 condition : self.condition,
20724 consequent : self.body.value || make_void_0(self.body),
20725 alternative : self.alternative.value || make_void_0(self.alternative),
20726 }).transform(compressor)
20727 }).optimize(compressor);
20728 }
20729 if (self.body instanceof AST_If
20730 && !self.body.alternative
20731 && !self.alternative) {
20732 self = make_node(AST_If, self, {
20733 condition: make_node(AST_Binary, self.condition, {
20734 operator: "&&",
20735 left: self.condition,
20736 right: self.body.condition
20737 }),
20738 body: self.body.body,
20739 alternative: null
20740 });
20741 }
20742 if (aborts(self.body)) {
20743 if (self.alternative) {
20744 var alt = self.alternative;
20745 self.alternative = null;
20746 return make_node(AST_BlockStatement, self, {
20747 body: [ self, alt ]
20748 }).optimize(compressor);
20749 }
20750 }
20751 if (aborts(self.alternative)) {
20752 var body = self.body;
20753 self.body = self.alternative;
20754 self.condition = negated_is_best ? negated : self.condition.negate(compressor);
20755 self.alternative = null;
20756 return make_node(AST_BlockStatement, self, {
20757 body: [ self, body ]
20758 }).optimize(compressor);
20759 }
20760 return self;
20761});
20762
20763def_optimize(AST_Switch, function(self, compressor) {
20764 if (!compressor.option("switches")) return self;
20765 var branch;
20766 var value = self.expression.evaluate(compressor);
20767 if (!(value instanceof AST_Node)) {
20768 var orig = self.expression;
20769 self.expression = make_node_from_constant(value, orig);
20770 self.expression = best_of_expression(self.expression.transform(compressor), orig);
20771 }
20772 if (!compressor.option("dead_code")) return self;
20773 if (value instanceof AST_Node) {
20774 value = self.expression.tail_node().evaluate(compressor);
20775 }
20776 var decl = [];
20777 var body = [];
20778 var default_branch;
20779 var exact_match;
20780 // - compress self.body into `body`
20781 // - find and deduplicate default branch
20782 // - find the exact match (`case 1234` inside `switch(1234)`)
20783 for (var i = 0, len = self.body.length; i < len && !exact_match; i++) {
20784 branch = self.body[i];
20785 if (branch instanceof AST_Default) {
20786 if (!default_branch) {
20787 default_branch = branch;
20788 } else {
20789 eliminate_branch(branch, body[body.length - 1]);
20790 }
20791 } else if (!(value instanceof AST_Node)) {
20792 var exp = branch.expression.evaluate(compressor);
20793 if (!(exp instanceof AST_Node) && exp !== value) {
20794 eliminate_branch(branch, body[body.length - 1]);
20795 continue;
20796 }
20797 if (exp instanceof AST_Node && !exp.has_side_effects(compressor)) {
20798 exp = branch.expression.tail_node().evaluate(compressor);
20799 }
20800 if (exp === value) {
20801 exact_match = branch;
20802 if (default_branch) {
20803 var default_index = body.indexOf(default_branch);
20804 body.splice(default_index, 1);
20805 eliminate_branch(default_branch, body[default_index - 1]);
20806 default_branch = null;
20807 }
20808 }
20809 }
20810 body.push(branch);
20811 }
20812 // i < len if we found an exact_match. eliminate the rest
20813 while (i < len) eliminate_branch(self.body[i++], body[body.length - 1]);
20814 self.body = body;
20815
20816 let default_or_exact = default_branch || exact_match;
20817 default_branch = null;
20818 exact_match = null;
20819
20820 // group equivalent branches so they will be located next to each other,
20821 // that way the next micro-optimization will merge them.
20822 // ** bail micro-optimization if not a simple switch case with breaks
20823 if (body.every((branch, i) =>
20824 (branch === default_or_exact || branch.expression instanceof AST_Constant)
20825 && (branch.body.length === 0 || aborts(branch) || body.length - 1 === i))
20826 ) {
20827 for (let i = 0; i < body.length; i++) {
20828 const branch = body[i];
20829 for (let j = i + 1; j < body.length; j++) {
20830 const next = body[j];
20831 if (next.body.length === 0) continue;
20832 const last_branch = j === (body.length - 1);
20833 const equivalentBranch = branches_equivalent(next, branch, false);
20834 if (equivalentBranch || (last_branch && branches_equivalent(next, branch, true))) {
20835 if (!equivalentBranch && last_branch) {
20836 next.body.push(make_node(AST_Break));
20837 }
20838
20839 // let's find previous siblings with inert fallthrough...
20840 let x = j - 1;
20841 let fallthroughDepth = 0;
20842 while (x > i) {
20843 if (is_inert_body(body[x--])) {
20844 fallthroughDepth++;
20845 } else {
20846 break;
20847 }
20848 }
20849
20850 const plucked = body.splice(j - fallthroughDepth, 1 + fallthroughDepth);
20851 body.splice(i + 1, 0, ...plucked);
20852 i += plucked.length;
20853 }
20854 }
20855 }
20856 }
20857
20858 // merge equivalent branches in a row
20859 for (let i = 0; i < body.length; i++) {
20860 let branch = body[i];
20861 if (branch.body.length === 0) continue;
20862 if (!aborts(branch)) continue;
20863
20864 for (let j = i + 1; j < body.length; i++, j++) {
20865 let next = body[j];
20866 if (next.body.length === 0) continue;
20867 if (
20868 branches_equivalent(next, branch, false)
20869 || (j === body.length - 1 && branches_equivalent(next, branch, true))
20870 ) {
20871 branch.body = [];
20872 branch = next;
20873 continue;
20874 }
20875 break;
20876 }
20877 }
20878
20879 // Prune any empty branches at the end of the switch statement.
20880 {
20881 let i = body.length - 1;
20882 for (; i >= 0; i--) {
20883 let bbody = body[i].body;
20884 while (is_break(bbody[bbody.length - 1], compressor)) bbody.pop();
20885 if (!is_inert_body(body[i])) break;
20886 }
20887 // i now points to the index of a branch that contains a body. By incrementing, it's
20888 // pointing to the first branch that's empty.
20889 i++;
20890 if (!default_or_exact || body.indexOf(default_or_exact) >= i) {
20891 // The default behavior is to do nothing. We can take advantage of that to
20892 // remove all case expressions that are side-effect free that also do
20893 // nothing, since they'll default to doing nothing. But we can't remove any
20894 // case expressions before one that would side-effect, since they may cause
20895 // the side-effect to be skipped.
20896 for (let j = body.length - 1; j >= i; j--) {
20897 let branch = body[j];
20898 if (branch === default_or_exact) {
20899 default_or_exact = null;
20900 eliminate_branch(body.pop());
20901 } else if (!branch.expression.has_side_effects(compressor)) {
20902 eliminate_branch(body.pop());
20903 } else {
20904 break;
20905 }
20906 }
20907 }
20908 }
20909
20910
20911 // Prune side-effect free branches that fall into default.
20912 DEFAULT: if (default_or_exact) {
20913 let default_index = body.indexOf(default_or_exact);
20914 let default_body_index = default_index;
20915 for (; default_body_index < body.length - 1; default_body_index++) {
20916 if (!is_inert_body(body[default_body_index])) break;
20917 }
20918 if (default_body_index < body.length - 1) {
20919 break DEFAULT;
20920 }
20921
20922 let side_effect_index = body.length - 1;
20923 for (; side_effect_index >= 0; side_effect_index--) {
20924 let branch = body[side_effect_index];
20925 if (branch === default_or_exact) continue;
20926 if (branch.expression.has_side_effects(compressor)) break;
20927 }
20928 // If the default behavior comes after any side-effect case expressions,
20929 // then we can fold all side-effect free cases into the default branch.
20930 // If the side-effect case is after the default, then any side-effect
20931 // free cases could prevent the side-effect from occurring.
20932 if (default_body_index > side_effect_index) {
20933 let prev_body_index = default_index - 1;
20934 for (; prev_body_index >= 0; prev_body_index--) {
20935 if (!is_inert_body(body[prev_body_index])) break;
20936 }
20937 let before = Math.max(side_effect_index, prev_body_index) + 1;
20938 let after = default_index;
20939 if (side_effect_index > default_index) {
20940 // If the default falls into the same body as a side-effect
20941 // case, then we need preserve that case and only prune the
20942 // cases after it.
20943 after = side_effect_index;
20944 body[side_effect_index].body = body[default_body_index].body;
20945 } else {
20946 // The default will be the last branch.
20947 default_or_exact.body = body[default_body_index].body;
20948 }
20949
20950 // Prune everything after the default (or last side-effect case)
20951 // until the next case with a body.
20952 body.splice(after + 1, default_body_index - after);
20953 // Prune everything before the default that falls into it.
20954 body.splice(before, default_index - before);
20955 }
20956 }
20957
20958 // See if we can remove the switch entirely if all cases (the default) fall into the same case body.
20959 DEFAULT: if (default_or_exact) {
20960 let i = body.findIndex(branch => !is_inert_body(branch));
20961 let caseBody;
20962 // `i` is equal to one of the following:
20963 // - `-1`, there is no body in the switch statement.
20964 // - `body.length - 1`, all cases fall into the same body.
20965 // - anything else, there are multiple bodies in the switch.
20966 if (i === body.length - 1) {
20967 // All cases fall into the case body.
20968 let branch = body[i];
20969 if (has_nested_break(self)) break DEFAULT;
20970
20971 // This is the last case body, and we've already pruned any breaks, so it's
20972 // safe to hoist.
20973 caseBody = make_node(AST_BlockStatement, branch, {
20974 body: branch.body
20975 });
20976 branch.body = [];
20977 } else if (i !== -1) {
20978 // If there are multiple bodies, then we cannot optimize anything.
20979 break DEFAULT;
20980 }
20981
20982 let sideEffect = body.find(
20983 branch => branch !== default_or_exact && branch.expression.has_side_effects(compressor)
20984 );
20985 // If no cases cause a side-effect, we can eliminate the switch entirely.
20986 if (!sideEffect) {
20987 return make_node(AST_BlockStatement, self, {
20988 body: decl.concat(
20989 statement(self.expression),
20990 default_or_exact.expression ? statement(default_or_exact.expression) : [],
20991 caseBody || []
20992 )
20993 }).optimize(compressor);
20994 }
20995
20996 // If we're this far, either there was no body or all cases fell into the same body.
20997 // If there was no body, then we don't need a default branch (because the default is
20998 // do nothing). If there was a body, we'll extract it to after the switch, so the
20999 // switch's new default is to do nothing and we can still prune it.
21000 const default_index = body.indexOf(default_or_exact);
21001 body.splice(default_index, 1);
21002 default_or_exact = null;
21003
21004 if (caseBody) {
21005 // Recurse into switch statement one more time so that we can append the case body
21006 // outside of the switch. This recursion will only happen once since we've pruned
21007 // the default case.
21008 return make_node(AST_BlockStatement, self, {
21009 body: decl.concat(self, caseBody)
21010 }).optimize(compressor);
21011 }
21012 // If we fall here, there is a default branch somewhere, there are no case bodies,
21013 // and there's a side-effect somewhere. Just let the below paths take care of it.
21014 }
21015
21016 // Reintegrate `decl` (var statements)
21017 if (body.length > 0) {
21018 body[0].body = decl.concat(body[0].body);
21019 }
21020 if (body.length == 0) {
21021 return make_node(AST_BlockStatement, self, {
21022 body: decl.concat(statement(self.expression))
21023 }).optimize(compressor);
21024 }
21025
21026 if (body.length == 1 && !has_nested_break(self)) {
21027 // This is the last case body, and we've already pruned any breaks, so it's
21028 // safe to hoist.
21029 let branch = body[0];
21030 return make_node(AST_If, self, {
21031 condition: make_node(AST_Binary, self, {
21032 operator: "===",
21033 left: self.expression,
21034 right: branch.expression,
21035 }),
21036 body: make_node(AST_BlockStatement, branch, {
21037 body: branch.body
21038 }),
21039 alternative: null
21040 }).optimize(compressor);
21041 }
21042 if (body.length === 2 && default_or_exact && !has_nested_break(self)) {
21043 let branch = body[0] === default_or_exact ? body[1] : body[0];
21044 let exact_exp = default_or_exact.expression && statement(default_or_exact.expression);
21045 if (aborts(body[0])) {
21046 // Only the first branch body could have a break (at the last statement)
21047 let first = body[0];
21048 if (is_break(first.body[first.body.length - 1], compressor)) {
21049 first.body.pop();
21050 }
21051 return make_node(AST_If, self, {
21052 condition: make_node(AST_Binary, self, {
21053 operator: "===",
21054 left: self.expression,
21055 right: branch.expression,
21056 }),
21057 body: make_node(AST_BlockStatement, branch, {
21058 body: branch.body
21059 }),
21060 alternative: make_node(AST_BlockStatement, default_or_exact, {
21061 body: [].concat(
21062 exact_exp || [],
21063 default_or_exact.body
21064 )
21065 })
21066 }).optimize(compressor);
21067 }
21068 let operator = "===";
21069 let consequent = make_node(AST_BlockStatement, branch, {
21070 body: branch.body,
21071 });
21072 let always = make_node(AST_BlockStatement, default_or_exact, {
21073 body: [].concat(
21074 exact_exp || [],
21075 default_or_exact.body
21076 )
21077 });
21078 if (body[0] === default_or_exact) {
21079 operator = "!==";
21080 let tmp = always;
21081 always = consequent;
21082 consequent = tmp;
21083 }
21084 return make_node(AST_BlockStatement, self, {
21085 body: [
21086 make_node(AST_If, self, {
21087 condition: make_node(AST_Binary, self, {
21088 operator: operator,
21089 left: self.expression,
21090 right: branch.expression,
21091 }),
21092 body: consequent,
21093 alternative: null,
21094 }),
21095 always,
21096 ],
21097 }).optimize(compressor);
21098 }
21099 return self;
21100
21101 function eliminate_branch(branch, prev) {
21102 if (prev && !aborts(prev)) {
21103 prev.body = prev.body.concat(branch.body);
21104 } else {
21105 extract_from_unreachable_code(compressor, branch, decl);
21106 }
21107 }
21108 function branches_equivalent(branch, prev, insertBreak) {
21109 let bbody = branch.body;
21110 let pbody = prev.body;
21111 if (insertBreak) {
21112 bbody = bbody.concat(make_node(AST_Break));
21113 }
21114 if (bbody.length !== pbody.length) return false;
21115 let bblock = make_node(AST_BlockStatement, branch, { body: bbody });
21116 let pblock = make_node(AST_BlockStatement, prev, { body: pbody });
21117 return bblock.equivalent_to(pblock);
21118 }
21119 function statement(body) {
21120 return make_node(AST_SimpleStatement, body, { body });
21121 }
21122 function has_nested_break(root) {
21123 let has_break = false;
21124
21125 let tw = new TreeWalker(node => {
21126 if (has_break) return true;
21127 if (node instanceof AST_Lambda) return true;
21128 if (node instanceof AST_SimpleStatement) return true;
21129 if (!is_break(node, tw)) return;
21130 let parent = tw.parent();
21131 if (
21132 parent instanceof AST_SwitchBranch
21133 && parent.body[parent.body.length - 1] === node
21134 ) {
21135 return;
21136 }
21137 has_break = true;
21138 });
21139 root.walk(tw);
21140 return has_break;
21141 }
21142 function is_break(node, stack) {
21143 return node instanceof AST_Break
21144 && stack.loopcontrol_target(node) === self;
21145 }
21146 function is_inert_body(branch) {
21147 return !aborts(branch) && !make_node(AST_BlockStatement, branch, {
21148 body: branch.body
21149 }).has_side_effects(compressor);
21150 }
21151});
21152
21153def_optimize(AST_Try, function(self, compressor) {
21154 if (self.bcatch && self.bfinally && self.bfinally.body.every(is_empty)) self.bfinally = null;
21155
21156 if (compressor.option("dead_code") && self.body.body.every(is_empty)) {
21157 var body = [];
21158 if (self.bcatch) {
21159 extract_from_unreachable_code(compressor, self.bcatch, body);
21160 }
21161 if (self.bfinally) body.push(...self.bfinally.body);
21162 return make_node(AST_BlockStatement, self, {
21163 body: body
21164 }).optimize(compressor);
21165 }
21166 return self;
21167});
21168
21169AST_Definitions.DEFMETHOD("to_assignments", function(compressor) {
21170 var reduce_vars = compressor.option("reduce_vars");
21171 var assignments = [];
21172
21173 for (const def of this.definitions) {
21174 if (def.value) {
21175 var name = make_node(AST_SymbolRef, def.name, def.name);
21176 assignments.push(make_node(AST_Assign, def, {
21177 operator : "=",
21178 logical: false,
21179 left : name,
21180 right : def.value
21181 }));
21182 if (reduce_vars) name.definition().fixed = false;
21183 }
21184 const thedef = def.name.definition();
21185 thedef.eliminated++;
21186 thedef.replaced--;
21187 }
21188
21189 if (assignments.length == 0) return null;
21190 return make_sequence(this, assignments);
21191});
21192
21193def_optimize(AST_Definitions, function(self) {
21194 if (self.definitions.length == 0) {
21195 return make_node(AST_EmptyStatement, self);
21196 }
21197 return self;
21198});
21199
21200def_optimize(AST_VarDef, function(self, compressor) {
21201 if (
21202 self.name instanceof AST_SymbolLet
21203 && self.value != null
21204 && is_undefined(self.value, compressor)
21205 ) {
21206 self.value = null;
21207 }
21208 return self;
21209});
21210
21211def_optimize(AST_Import, function(self) {
21212 return self;
21213});
21214
21215def_optimize(AST_Call, function(self, compressor) {
21216 var exp = self.expression;
21217 var fn = exp;
21218 inline_array_like_spread(self.args);
21219 var simple_args = self.args.every((arg) => !(arg instanceof AST_Expansion));
21220
21221 if (compressor.option("reduce_vars") && fn instanceof AST_SymbolRef) {
21222 fn = fn.fixed_value();
21223 }
21224
21225 var is_func = fn instanceof AST_Lambda;
21226
21227 if (is_func && fn.pinned()) return self;
21228
21229 if (compressor.option("unused")
21230 && simple_args
21231 && is_func
21232 && !fn.uses_arguments) {
21233 var pos = 0, last = 0;
21234 for (var i = 0, len = self.args.length; i < len; i++) {
21235 if (fn.argnames[i] instanceof AST_Expansion) {
21236 if (has_flag(fn.argnames[i].expression, UNUSED)) while (i < len) {
21237 var node = self.args[i++].drop_side_effect_free(compressor);
21238 if (node) {
21239 self.args[pos++] = node;
21240 }
21241 } else while (i < len) {
21242 self.args[pos++] = self.args[i++];
21243 }
21244 last = pos;
21245 break;
21246 }
21247 var trim = i >= fn.argnames.length;
21248 if (trim || has_flag(fn.argnames[i], UNUSED)) {
21249 var node = self.args[i].drop_side_effect_free(compressor);
21250 if (node) {
21251 self.args[pos++] = node;
21252 } else if (!trim) {
21253 self.args[pos++] = make_node(AST_Number, self.args[i], {
21254 value: 0
21255 });
21256 continue;
21257 }
21258 } else {
21259 self.args[pos++] = self.args[i];
21260 }
21261 last = pos;
21262 }
21263 self.args.length = last;
21264 }
21265
21266 if (
21267 exp instanceof AST_Dot
21268 && exp.expression instanceof AST_SymbolRef
21269 && exp.expression.name === "console"
21270 && exp.expression.definition().undeclared
21271 && exp.property === "assert"
21272 ) {
21273 const condition = self.args[0];
21274 if (condition) {
21275 const value = condition.evaluate(compressor);
21276
21277 if (value === 1 || value === true) {
21278 return make_void_0(self).optimize(compressor);
21279 }
21280 }
21281 }
21282
21283 if (compressor.option("unsafe") && !exp.contains_optional()) {
21284 if (exp instanceof AST_Dot && exp.start.value === "Array" && exp.property === "from" && self.args.length === 1) {
21285 const [argument] = self.args;
21286 if (argument instanceof AST_Array) {
21287 return make_node(AST_Array, argument, {
21288 elements: argument.elements
21289 }).optimize(compressor);
21290 }
21291 }
21292 if (is_undeclared_ref(exp)) switch (exp.name) {
21293 case "Array":
21294 if (self.args.length != 1) {
21295 return make_node(AST_Array, self, {
21296 elements: self.args
21297 }).optimize(compressor);
21298 } else if (self.args[0] instanceof AST_Number && self.args[0].value <= 11) {
21299 const elements = [];
21300 for (let i = 0; i < self.args[0].value; i++) elements.push(new AST_Hole);
21301 return new AST_Array({ elements });
21302 }
21303 break;
21304 case "Object":
21305 if (self.args.length == 0) {
21306 return make_node(AST_Object, self, {
21307 properties: []
21308 });
21309 }
21310 break;
21311 case "String":
21312 if (self.args.length == 0) return make_node(AST_String, self, {
21313 value: ""
21314 });
21315 if (self.args.length <= 1) return make_node(AST_Binary, self, {
21316 left: self.args[0],
21317 operator: "+",
21318 right: make_node(AST_String, self, { value: "" })
21319 }).optimize(compressor);
21320 break;
21321 case "Number":
21322 if (self.args.length == 0) return make_node(AST_Number, self, {
21323 value: 0
21324 });
21325 if (self.args.length == 1 && compressor.option("unsafe_math")) {
21326 return make_node(AST_UnaryPrefix, self, {
21327 expression: self.args[0],
21328 operator: "+"
21329 }).optimize(compressor);
21330 }
21331 break;
21332 case "Symbol":
21333 if (self.args.length == 1 && self.args[0] instanceof AST_String && compressor.option("unsafe_symbols"))
21334 self.args.length = 0;
21335 break;
21336 case "Boolean":
21337 if (self.args.length == 0) return make_node(AST_False, self);
21338 if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, {
21339 expression: make_node(AST_UnaryPrefix, self, {
21340 expression: self.args[0],
21341 operator: "!"
21342 }),
21343 operator: "!"
21344 }).optimize(compressor);
21345 break;
21346 case "RegExp":
21347 var params = [];
21348 if (self.args.length >= 1
21349 && self.args.length <= 2
21350 && self.args.every((arg) => {
21351 var value = arg.evaluate(compressor);
21352 params.push(value);
21353 return arg !== value;
21354 })
21355 && regexp_is_safe(params[0])
21356 ) {
21357 let [ source, flags ] = params;
21358 source = regexp_source_fix(new RegExp(source).source);
21359 const rx = make_node(AST_RegExp, self, {
21360 value: { source, flags }
21361 });
21362 if (rx._eval(compressor) !== rx) {
21363 return rx;
21364 }
21365 }
21366 break;
21367 } else if (exp instanceof AST_Dot) switch(exp.property) {
21368 case "toString":
21369 if (self.args.length == 0 && !exp.expression.may_throw_on_access(compressor)) {
21370 return make_node(AST_Binary, self, {
21371 left: make_node(AST_String, self, { value: "" }),
21372 operator: "+",
21373 right: exp.expression
21374 }).optimize(compressor);
21375 }
21376 break;
21377 case "join":
21378 if (exp.expression instanceof AST_Array) EXIT: {
21379 var separator;
21380 if (self.args.length > 0) {
21381 separator = self.args[0].evaluate(compressor);
21382 if (separator === self.args[0]) break EXIT; // not a constant
21383 }
21384 var elements = [];
21385 var consts = [];
21386 for (var i = 0, len = exp.expression.elements.length; i < len; i++) {
21387 var el = exp.expression.elements[i];
21388 if (el instanceof AST_Expansion) break EXIT;
21389 var value = el.evaluate(compressor);
21390 if (value !== el) {
21391 consts.push(value);
21392 } else {
21393 if (consts.length > 0) {
21394 elements.push(make_node(AST_String, self, {
21395 value: consts.join(separator)
21396 }));
21397 consts.length = 0;
21398 }
21399 elements.push(el);
21400 }
21401 }
21402 if (consts.length > 0) {
21403 elements.push(make_node(AST_String, self, {
21404 value: consts.join(separator)
21405 }));
21406 }
21407 if (elements.length == 0) return make_node(AST_String, self, { value: "" });
21408 if (elements.length == 1) {
21409 if (elements[0].is_string(compressor)) {
21410 return elements[0];
21411 }
21412 return make_node(AST_Binary, elements[0], {
21413 operator : "+",
21414 left : make_node(AST_String, self, { value: "" }),
21415 right : elements[0]
21416 });
21417 }
21418 if (separator == "") {
21419 var first;
21420 if (elements[0].is_string(compressor)
21421 || elements[1].is_string(compressor)) {
21422 first = elements.shift();
21423 } else {
21424 first = make_node(AST_String, self, { value: "" });
21425 }
21426 return elements.reduce(function(prev, el) {
21427 return make_node(AST_Binary, el, {
21428 operator : "+",
21429 left : prev,
21430 right : el
21431 });
21432 }, first).optimize(compressor);
21433 }
21434 // need this awkward cloning to not affect original element
21435 // best_of will decide which one to get through.
21436 var node = self.clone();
21437 node.expression = node.expression.clone();
21438 node.expression.expression = node.expression.expression.clone();
21439 node.expression.expression.elements = elements;
21440 return best_of(compressor, self, node);
21441 }
21442 break;
21443 case "charAt":
21444 if (exp.expression.is_string(compressor)) {
21445 var arg = self.args[0];
21446 var index = arg ? arg.evaluate(compressor) : 0;
21447 if (index !== arg) {
21448 return make_node(AST_Sub, exp, {
21449 expression: exp.expression,
21450 property: make_node_from_constant(index | 0, arg || exp)
21451 }).optimize(compressor);
21452 }
21453 }
21454 break;
21455 case "apply":
21456 if (self.args.length == 2 && self.args[1] instanceof AST_Array) {
21457 var args = self.args[1].elements.slice();
21458 args.unshift(self.args[0]);
21459 return make_node(AST_Call, self, {
21460 expression: make_node(AST_Dot, exp, {
21461 expression: exp.expression,
21462 optional: false,
21463 property: "call"
21464 }),
21465 args: args
21466 }).optimize(compressor);
21467 }
21468 break;
21469 case "call":
21470 var func = exp.expression;
21471 if (func instanceof AST_SymbolRef) {
21472 func = func.fixed_value();
21473 }
21474 if (func instanceof AST_Lambda && !func.contains_this()) {
21475 return (self.args.length ? make_sequence(this, [
21476 self.args[0],
21477 make_node(AST_Call, self, {
21478 expression: exp.expression,
21479 args: self.args.slice(1)
21480 })
21481 ]) : make_node(AST_Call, self, {
21482 expression: exp.expression,
21483 args: []
21484 })).optimize(compressor);
21485 }
21486 break;
21487 }
21488 }
21489
21490 if (compressor.option("unsafe_Function")
21491 && is_undeclared_ref(exp)
21492 && exp.name == "Function") {
21493 // new Function() => function(){}
21494 if (self.args.length == 0) return make_empty_function(self).optimize(compressor);
21495 if (self.args.every((x) => x instanceof AST_String)) {
21496 // quite a corner-case, but we can handle it:
21497 // https://github.com/mishoo/UglifyJS2/issues/203
21498 // if the code argument is a constant, then we can minify it.
21499 try {
21500 var code = "n(function(" + self.args.slice(0, -1).map(function(arg) {
21501 return arg.value;
21502 }).join(",") + "){" + self.args[self.args.length - 1].value + "})";
21503 var ast = parse(code);
21504 var mangle = compressor.mangle_options();
21505 ast.figure_out_scope(mangle);
21506 var comp = new Compressor(compressor.options, {
21507 mangle_options: compressor._mangle_options
21508 });
21509 ast = ast.transform(comp);
21510 ast.figure_out_scope(mangle);
21511 ast.compute_char_frequency(mangle);
21512 ast.mangle_names(mangle);
21513 var fun;
21514 walk(ast, node => {
21515 if (is_func_expr(node)) {
21516 fun = node;
21517 return walk_abort;
21518 }
21519 });
21520 var code = OutputStream();
21521 AST_BlockStatement.prototype._codegen.call(fun, fun, code);
21522 self.args = [
21523 make_node(AST_String, self, {
21524 value: fun.argnames.map(function(arg) {
21525 return arg.print_to_string();
21526 }).join(",")
21527 }),
21528 make_node(AST_String, self.args[self.args.length - 1], {
21529 value: code.get().replace(/^{|}$/g, "")
21530 })
21531 ];
21532 return self;
21533 } catch (ex) {
21534 if (!(ex instanceof JS_Parse_Error)) {
21535 throw ex;
21536 }
21537
21538 // Otherwise, it crashes at runtime. Or maybe it's nonstandard syntax.
21539 }
21540 }
21541 }
21542
21543 return inline_into_call(self, compressor);
21544});
21545
21546/** Does this node contain optional property access or optional call? */
21547AST_Node.DEFMETHOD("contains_optional", function() {
21548 if (
21549 this instanceof AST_PropAccess
21550 || this instanceof AST_Call
21551 || this instanceof AST_Chain
21552 ) {
21553 if (this.optional) {
21554 return true;
21555 } else {
21556 return this.expression.contains_optional();
21557 }
21558 } else {
21559 return false;
21560 }
21561});
21562
21563def_optimize(AST_New, function(self, compressor) {
21564 if (
21565 compressor.option("unsafe") &&
21566 is_undeclared_ref(self.expression) &&
21567 ["Object", "RegExp", "Function", "Error", "Array"].includes(self.expression.name)
21568 ) return make_node(AST_Call, self, self).transform(compressor);
21569 return self;
21570});
21571
21572def_optimize(AST_Sequence, function(self, compressor) {
21573 if (!compressor.option("side_effects")) return self;
21574 var expressions = [];
21575 filter_for_side_effects();
21576 var end = expressions.length - 1;
21577 trim_right_for_undefined();
21578 if (end == 0) {
21579 self = maintain_this_binding(compressor.parent(), compressor.self(), expressions[0]);
21580 if (!(self instanceof AST_Sequence)) self = self.optimize(compressor);
21581 return self;
21582 }
21583 self.expressions = expressions;
21584 return self;
21585
21586 function filter_for_side_effects() {
21587 var first = first_in_statement(compressor);
21588 var last = self.expressions.length - 1;
21589 self.expressions.forEach(function(expr, index) {
21590 if (index < last) expr = expr.drop_side_effect_free(compressor, first);
21591 if (expr) {
21592 merge_sequence(expressions, expr);
21593 first = false;
21594 }
21595 });
21596 }
21597
21598 function trim_right_for_undefined() {
21599 while (end > 0 && is_undefined(expressions[end], compressor)) end--;
21600 if (end < expressions.length - 1) {
21601 expressions[end] = make_node(AST_UnaryPrefix, self, {
21602 operator : "void",
21603 expression : expressions[end]
21604 });
21605 expressions.length = end + 1;
21606 }
21607 }
21608});
21609
21610AST_Unary.DEFMETHOD("lift_sequences", function(compressor) {
21611 if (compressor.option("sequences")) {
21612 if (this.expression instanceof AST_Sequence) {
21613 var x = this.expression.expressions.slice();
21614 var e = this.clone();
21615 e.expression = x.pop();
21616 x.push(e);
21617 return make_sequence(this, x).optimize(compressor);
21618 }
21619 }
21620 return this;
21621});
21622
21623def_optimize(AST_UnaryPostfix, function(self, compressor) {
21624 return self.lift_sequences(compressor);
21625});
21626
21627def_optimize(AST_UnaryPrefix, function(self, compressor) {
21628 var e = self.expression;
21629 if (
21630 self.operator == "delete" &&
21631 !(
21632 e instanceof AST_SymbolRef ||
21633 e instanceof AST_PropAccess ||
21634 e instanceof AST_Chain ||
21635 is_identifier_atom(e)
21636 )
21637 ) {
21638 return make_sequence(self, [e, make_node(AST_True, self)]).optimize(compressor);
21639 }
21640 // Short-circuit common `void 0`
21641 if (self.operator === "void" && e instanceof AST_Number && e.value === 0) {
21642 return unsafe_undefined_ref(self, compressor) || self;
21643 }
21644 var seq = self.lift_sequences(compressor);
21645 if (seq !== self) {
21646 return seq;
21647 }
21648 if (compressor.option("side_effects") && self.operator == "void") {
21649 e = e.drop_side_effect_free(compressor);
21650 if (e) {
21651 self.expression = e;
21652 return self;
21653 } else {
21654 return make_void_0(self).optimize(compressor);
21655 }
21656 }
21657 if (compressor.in_boolean_context()) {
21658 switch (self.operator) {
21659 case "!":
21660 if (e instanceof AST_UnaryPrefix && e.operator == "!") {
21661 // !!foo ==> foo, if we're in boolean context
21662 return e.expression;
21663 }
21664 if (e instanceof AST_Binary) {
21665 self = best_of(compressor, self, e.negate(compressor, first_in_statement(compressor)));
21666 }
21667 break;
21668 case "typeof":
21669 // typeof always returns a non-empty string, thus it's
21670 // always true in booleans
21671 // And we don't need to check if it's undeclared, because in typeof, that's OK
21672 return (e instanceof AST_SymbolRef ? make_node(AST_True, self) : make_sequence(self, [
21673 e,
21674 make_node(AST_True, self)
21675 ])).optimize(compressor);
21676 }
21677 }
21678 if (self.operator == "-" && e instanceof AST_Infinity) {
21679 e = e.transform(compressor);
21680 }
21681 if (e instanceof AST_Binary
21682 && (self.operator == "+" || self.operator == "-")
21683 && (e.operator == "*" || e.operator == "/" || e.operator == "%")) {
21684 return make_node(AST_Binary, self, {
21685 operator: e.operator,
21686 left: make_node(AST_UnaryPrefix, e.left, {
21687 operator: self.operator,
21688 expression: e.left
21689 }),
21690 right: e.right
21691 });
21692 }
21693
21694 if (compressor.option("evaluate")) {
21695 // ~~x => x (in 32-bit context)
21696 // ~~{32 bit integer} => {32 bit integer}
21697 if (
21698 self.operator === "~"
21699 && self.expression instanceof AST_UnaryPrefix
21700 && self.expression.operator === "~"
21701 && (compressor.in_32_bit_context(false) || self.expression.expression.is_32_bit_integer(compressor))
21702 ) {
21703 return self.expression.expression;
21704 }
21705
21706 // ~(x ^ y) => x ^ ~y
21707 if (
21708 self.operator === "~"
21709 && e instanceof AST_Binary
21710 && e.operator === "^"
21711 ) {
21712 if (e.left instanceof AST_UnaryPrefix && e.left.operator === "~") {
21713 // ~(~x ^ y) => x ^ y
21714 e.left = e.left.bitwise_negate(compressor, true);
21715 } else {
21716 e.right = e.right.bitwise_negate(compressor, true);
21717 }
21718 return e;
21719 }
21720 }
21721
21722 if (
21723 self.operator != "-"
21724 // avoid infinite recursion of numerals
21725 || !(e instanceof AST_Number || e instanceof AST_Infinity || e instanceof AST_BigInt)
21726 ) {
21727 var ev = self.evaluate(compressor);
21728 if (ev !== self) {
21729 ev = make_node_from_constant(ev, self).optimize(compressor);
21730 return best_of(compressor, ev, self);
21731 }
21732 }
21733 return self;
21734});
21735
21736AST_Binary.DEFMETHOD("lift_sequences", function(compressor) {
21737 if (compressor.option("sequences")) {
21738 if (this.left instanceof AST_Sequence) {
21739 var x = this.left.expressions.slice();
21740 var e = this.clone();
21741 e.left = x.pop();
21742 x.push(e);
21743 return make_sequence(this, x).optimize(compressor);
21744 }
21745 if (this.right instanceof AST_Sequence && !this.left.has_side_effects(compressor)) {
21746 var assign = this.operator == "=" && this.left instanceof AST_SymbolRef;
21747 var x = this.right.expressions;
21748 var last = x.length - 1;
21749 for (var i = 0; i < last; i++) {
21750 if (!assign && x[i].has_side_effects(compressor)) break;
21751 }
21752 if (i == last) {
21753 x = x.slice();
21754 var e = this.clone();
21755 e.right = x.pop();
21756 x.push(e);
21757 return make_sequence(this, x).optimize(compressor);
21758 } else if (i > 0) {
21759 var e = this.clone();
21760 e.right = make_sequence(this.right, x.slice(i));
21761 x = x.slice(0, i);
21762 x.push(e);
21763 return make_sequence(this, x).optimize(compressor);
21764 }
21765 }
21766 }
21767 return this;
21768});
21769
21770var commutativeOperators = makePredicate("== === != !== * & | ^");
21771function is_object(node) {
21772 return node instanceof AST_Array
21773 || node instanceof AST_Lambda
21774 || node instanceof AST_Object
21775 || node instanceof AST_Class;
21776}
21777
21778def_optimize(AST_Binary, function(self, compressor) {
21779 function reversible() {
21780 return self.left.is_constant()
21781 || self.right.is_constant()
21782 || !self.left.has_side_effects(compressor)
21783 && !self.right.has_side_effects(compressor);
21784 }
21785 function reverse(op) {
21786 if (reversible()) {
21787 if (op) self.operator = op;
21788 var tmp = self.left;
21789 self.left = self.right;
21790 self.right = tmp;
21791 }
21792 }
21793 if (compressor.option("lhs_constants") && commutativeOperators.has(self.operator)) {
21794 if (self.right.is_constant()
21795 && !self.left.is_constant()) {
21796 // if right is a constant, whatever side effects the
21797 // left side might have could not influence the
21798 // result. hence, force switch.
21799
21800 if (!(self.left instanceof AST_Binary
21801 && PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) {
21802 reverse();
21803 }
21804 }
21805 }
21806 self = self.lift_sequences(compressor);
21807 if (compressor.option("comparisons")) switch (self.operator) {
21808 case "===":
21809 case "!==":
21810 var is_strict_comparison = true;
21811 if (
21812 (self.left.is_string(compressor) && self.right.is_string(compressor)) ||
21813 (self.left.is_number(compressor) && self.right.is_number(compressor)) ||
21814 (self.left.is_bigint(compressor) && self.right.is_bigint(compressor)) ||
21815 (self.left.is_boolean() && self.right.is_boolean()) ||
21816 self.left.equivalent_to(self.right)
21817 ) {
21818 self.operator = self.operator.substr(0, 2);
21819 }
21820
21821 // XXX: intentionally falling down to the next case
21822 case "==":
21823 case "!=":
21824 // void 0 == x => null == x
21825 if (!is_strict_comparison && is_undefined(self.left, compressor)) {
21826 self.left = make_node(AST_Null, self.left);
21827 // x == void 0 => x == null
21828 } else if (!is_strict_comparison && is_undefined(self.right, compressor)) {
21829 self.right = make_node(AST_Null, self.right);
21830 } else if (compressor.option("typeofs")
21831 // "undefined" == typeof x => undefined === x
21832 && self.left instanceof AST_String
21833 && self.left.value == "undefined"
21834 && self.right instanceof AST_UnaryPrefix
21835 && self.right.operator == "typeof") {
21836 var expr = self.right.expression;
21837 if (expr instanceof AST_SymbolRef ? expr.is_declared(compressor)
21838 : !(expr instanceof AST_PropAccess && compressor.option("ie8"))) {
21839 self.right = expr;
21840 self.left = make_void_0(self.left).optimize(compressor);
21841 if (self.operator.length == 2) self.operator += "=";
21842 }
21843 } else if (compressor.option("typeofs")
21844 // typeof x === "undefined" => x === undefined
21845 && self.left instanceof AST_UnaryPrefix
21846 && self.left.operator == "typeof"
21847 && self.right instanceof AST_String
21848 && self.right.value == "undefined") {
21849 var expr = self.left.expression;
21850 if (expr instanceof AST_SymbolRef ? expr.is_declared(compressor)
21851 : !(expr instanceof AST_PropAccess && compressor.option("ie8"))) {
21852 self.left = expr;
21853 self.right = make_void_0(self.right).optimize(compressor);
21854 if (self.operator.length == 2) self.operator += "=";
21855 }
21856 } else if (self.left instanceof AST_SymbolRef
21857 // obj !== obj => false
21858 && self.right instanceof AST_SymbolRef
21859 && self.left.definition() === self.right.definition()
21860 && is_object(self.left.fixed_value())) {
21861 return make_node(self.operator[0] == "=" ? AST_True : AST_False, self);
21862 } else if (self.left.is_32_bit_integer(compressor) && self.right.is_32_bit_integer(compressor)) {
21863 const not = node => make_node(AST_UnaryPrefix, node, {
21864 operator: "!",
21865 expression: node
21866 });
21867 const booleanify = (node, truthy) => {
21868 if (truthy) {
21869 return compressor.in_boolean_context()
21870 ? node
21871 : not(not(node));
21872 } else {
21873 return not(node);
21874 }
21875 };
21876
21877 // The only falsy 32-bit integer is 0
21878 if (self.left instanceof AST_Number && self.left.value === 0) {
21879 return booleanify(self.right, self.operator[0] === "!");
21880 }
21881 if (self.right instanceof AST_Number && self.right.value === 0) {
21882 return booleanify(self.left, self.operator[0] === "!");
21883 }
21884
21885 // Mask all-bits check
21886 // (x & 0xFF) != 0xFF => !(~x & 0xFF)
21887 let and_op, x, mask;
21888 if (
21889 (and_op =
21890 self.left instanceof AST_Binary ? self.left
21891 : self.right instanceof AST_Binary ? self.right : null)
21892 && (mask = and_op === self.left ? self.right : self.left)
21893 && and_op.operator === "&"
21894 && mask instanceof AST_Number
21895 && mask.is_32_bit_integer(compressor)
21896 && (x =
21897 and_op.left.equivalent_to(mask) ? and_op.right
21898 : and_op.right.equivalent_to(mask) ? and_op.left : null)
21899 ) {
21900 let optimized = booleanify(make_node(AST_Binary, self, {
21901 operator: "&",
21902 left: mask,
21903 right: make_node(AST_UnaryPrefix, self, {
21904 operator: "~",
21905 expression: x
21906 })
21907 }), self.operator[0] === "!");
21908
21909 return best_of(compressor, optimized, self);
21910 }
21911 }
21912 break;
21913 case "&&":
21914 case "||":
21915 var lhs = self.left;
21916 if (lhs.operator == self.operator) {
21917 lhs = lhs.right;
21918 }
21919 if (lhs instanceof AST_Binary
21920 && lhs.operator == (self.operator == "&&" ? "!==" : "===")
21921 && self.right instanceof AST_Binary
21922 && lhs.operator == self.right.operator
21923 && (is_undefined(lhs.left, compressor) && self.right.left instanceof AST_Null
21924 || lhs.left instanceof AST_Null && is_undefined(self.right.left, compressor))
21925 && !lhs.right.has_side_effects(compressor)
21926 && lhs.right.equivalent_to(self.right.right)) {
21927 var combined = make_node(AST_Binary, self, {
21928 operator: lhs.operator.slice(0, -1),
21929 left: make_node(AST_Null, self),
21930 right: lhs.right
21931 });
21932 if (lhs !== self.left) {
21933 combined = make_node(AST_Binary, self, {
21934 operator: self.operator,
21935 left: self.left.left,
21936 right: combined
21937 });
21938 }
21939 return combined;
21940 }
21941 break;
21942 }
21943 if (self.operator == "+" && compressor.in_boolean_context()) {
21944 var ll = self.left.evaluate(compressor);
21945 var rr = self.right.evaluate(compressor);
21946 if (ll && typeof ll == "string") {
21947 return make_sequence(self, [
21948 self.right,
21949 make_node(AST_True, self)
21950 ]).optimize(compressor);
21951 }
21952 if (rr && typeof rr == "string") {
21953 return make_sequence(self, [
21954 self.left,
21955 make_node(AST_True, self)
21956 ]).optimize(compressor);
21957 }
21958 }
21959 if (compressor.option("comparisons") && self.is_boolean()) {
21960 if (!(compressor.parent() instanceof AST_Binary)
21961 || compressor.parent() instanceof AST_Assign) {
21962 var negated = make_node(AST_UnaryPrefix, self, {
21963 operator: "!",
21964 expression: self.negate(compressor, first_in_statement(compressor))
21965 });
21966 self = best_of(compressor, self, negated);
21967 }
21968 if (compressor.option("unsafe_comps")) {
21969 switch (self.operator) {
21970 case "<": reverse(">"); break;
21971 case "<=": reverse(">="); break;
21972 }
21973 }
21974 }
21975 if (self.operator == "+") {
21976 if (self.right instanceof AST_String
21977 && self.right.getValue() == ""
21978 && self.left.is_string(compressor)) {
21979 return self.left;
21980 }
21981 if (self.left instanceof AST_String
21982 && self.left.getValue() == ""
21983 && self.right.is_string(compressor)) {
21984 return self.right;
21985 }
21986 if (self.left instanceof AST_Binary
21987 && self.left.operator == "+"
21988 && self.left.left instanceof AST_String
21989 && self.left.left.getValue() == ""
21990 && self.right.is_string(compressor)) {
21991 self.left = self.left.right;
21992 return self;
21993 }
21994 }
21995 if (compressor.option("evaluate")) {
21996 switch (self.operator) {
21997 case "&&":
21998 var ll = has_flag(self.left, TRUTHY)
21999 ? true
22000 : has_flag(self.left, FALSY)
22001 ? false
22002 : self.left.evaluate(compressor);
22003 if (!ll) {
22004 return maintain_this_binding(compressor.parent(), compressor.self(), self.left).optimize(compressor);
22005 } else if (!(ll instanceof AST_Node)) {
22006 return make_sequence(self, [ self.left, self.right ]).optimize(compressor);
22007 }
22008 var rr = self.right.evaluate(compressor);
22009 if (!rr) {
22010 if (compressor.in_boolean_context()) {
22011 return make_sequence(self, [
22012 self.left,
22013 make_node(AST_False, self)
22014 ]).optimize(compressor);
22015 } else {
22016 set_flag(self, FALSY);
22017 }
22018 } else if (!(rr instanceof AST_Node)) {
22019 var parent = compressor.parent();
22020 if (parent.operator == "&&" && parent.left === compressor.self() || compressor.in_boolean_context()) {
22021 return self.left.optimize(compressor);
22022 }
22023 }
22024 // x || false && y ---> x ? y : false
22025 if (self.left.operator == "||") {
22026 var lr = self.left.right.evaluate(compressor);
22027 if (!lr) return make_node(AST_Conditional, self, {
22028 condition: self.left.left,
22029 consequent: self.right,
22030 alternative: self.left.right
22031 }).optimize(compressor);
22032 }
22033 break;
22034 case "||":
22035 var ll = has_flag(self.left, TRUTHY)
22036 ? true
22037 : has_flag(self.left, FALSY)
22038 ? false
22039 : self.left.evaluate(compressor);
22040 if (!ll) {
22041 return make_sequence(self, [ self.left, self.right ]).optimize(compressor);
22042 } else if (!(ll instanceof AST_Node)) {
22043 return maintain_this_binding(compressor.parent(), compressor.self(), self.left).optimize(compressor);
22044 }
22045 var rr = self.right.evaluate(compressor);
22046 if (!rr) {
22047 var parent = compressor.parent();
22048 if (parent.operator == "||" && parent.left === compressor.self() || compressor.in_boolean_context()) {
22049 return self.left.optimize(compressor);
22050 }
22051 } else if (!(rr instanceof AST_Node)) {
22052 if (compressor.in_boolean_context()) {
22053 return make_sequence(self, [
22054 self.left,
22055 make_node(AST_True, self)
22056 ]).optimize(compressor);
22057 } else {
22058 set_flag(self, TRUTHY);
22059 }
22060 }
22061 if (self.left.operator == "&&") {
22062 var lr = self.left.right.evaluate(compressor);
22063 if (lr && !(lr instanceof AST_Node)) return make_node(AST_Conditional, self, {
22064 condition: self.left.left,
22065 consequent: self.left.right,
22066 alternative: self.right
22067 }).optimize(compressor);
22068 }
22069 break;
22070 case "??":
22071 if (is_nullish(self.left, compressor)) {
22072 return self.right;
22073 }
22074
22075 var ll = self.left.evaluate(compressor);
22076 if (!(ll instanceof AST_Node)) {
22077 // if we know the value for sure we can simply compute right away.
22078 return ll == null ? self.right : self.left;
22079 }
22080
22081 if (compressor.in_boolean_context()) {
22082 const rr = self.right.evaluate(compressor);
22083 if (!(rr instanceof AST_Node) && !rr) {
22084 return self.left;
22085 }
22086 }
22087 }
22088 var associative = true;
22089 switch (self.operator) {
22090 case "+":
22091 // (x + "foo") + "bar" => x + "foobar"
22092 if (self.right instanceof AST_Constant
22093 && self.left instanceof AST_Binary
22094 && self.left.operator == "+"
22095 && self.left.is_string(compressor)) {
22096 var binary = make_node(AST_Binary, self, {
22097 operator: "+",
22098 left: self.left.right,
22099 right: self.right,
22100 });
22101 var r = binary.optimize(compressor);
22102 if (binary !== r) {
22103 self = make_node(AST_Binary, self, {
22104 operator: "+",
22105 left: self.left.left,
22106 right: r
22107 });
22108 }
22109 }
22110 // (x + "foo") + ("bar" + y) => (x + "foobar") + y
22111 if (self.left instanceof AST_Binary
22112 && self.left.operator == "+"
22113 && self.left.is_string(compressor)
22114 && self.right instanceof AST_Binary
22115 && self.right.operator == "+"
22116 && self.right.is_string(compressor)) {
22117 var binary = make_node(AST_Binary, self, {
22118 operator: "+",
22119 left: self.left.right,
22120 right: self.right.left,
22121 });
22122 var m = binary.optimize(compressor);
22123 if (binary !== m) {
22124 self = make_node(AST_Binary, self, {
22125 operator: "+",
22126 left: make_node(AST_Binary, self.left, {
22127 operator: "+",
22128 left: self.left.left,
22129 right: m
22130 }),
22131 right: self.right.right
22132 });
22133 }
22134 }
22135 // a + -b => a - b
22136 if (self.right instanceof AST_UnaryPrefix
22137 && self.right.operator == "-"
22138 && self.left.is_number_or_bigint(compressor)) {
22139 self = make_node(AST_Binary, self, {
22140 operator: "-",
22141 left: self.left,
22142 right: self.right.expression
22143 });
22144 break;
22145 }
22146 // -a + b => b - a
22147 if (self.left instanceof AST_UnaryPrefix
22148 && self.left.operator == "-"
22149 && reversible()
22150 && self.right.is_number_or_bigint(compressor)) {
22151 self = make_node(AST_Binary, self, {
22152 operator: "-",
22153 left: self.right,
22154 right: self.left.expression
22155 });
22156 break;
22157 }
22158 // `foo${bar}baz` + 1 => `foo${bar}baz1`
22159 if (self.left instanceof AST_TemplateString) {
22160 var l = self.left;
22161 var r = self.right.evaluate(compressor);
22162 if (r != self.right) {
22163 l.segments[l.segments.length - 1].value += String(r);
22164 return l;
22165 }
22166 }
22167 // 1 + `foo${bar}baz` => `1foo${bar}baz`
22168 if (self.right instanceof AST_TemplateString) {
22169 var r = self.right;
22170 var l = self.left.evaluate(compressor);
22171 if (l != self.left) {
22172 r.segments[0].value = String(l) + r.segments[0].value;
22173 return r;
22174 }
22175 }
22176 // `1${bar}2` + `foo${bar}baz` => `1${bar}2foo${bar}baz`
22177 if (self.left instanceof AST_TemplateString
22178 && self.right instanceof AST_TemplateString) {
22179 var l = self.left;
22180 var segments = l.segments;
22181 var r = self.right;
22182 segments[segments.length - 1].value += r.segments[0].value;
22183 for (var i = 1; i < r.segments.length; i++) {
22184 segments.push(r.segments[i]);
22185 }
22186 return l;
22187 }
22188 case "*":
22189 associative = compressor.option("unsafe_math");
22190 case "&":
22191 case "|":
22192 case "^":
22193 // a + +b => +b + a
22194 if (
22195 self.left.is_number_or_bigint(compressor)
22196 && self.right.is_number_or_bigint(compressor)
22197 && reversible()
22198 && !(self.left instanceof AST_Binary
22199 && self.left.operator != self.operator
22200 && PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) {
22201 var reversed = make_node(AST_Binary, self, {
22202 operator: self.operator,
22203 left: self.right,
22204 right: self.left
22205 });
22206 if (self.right instanceof AST_Constant
22207 && !(self.left instanceof AST_Constant)) {
22208 self = best_of(compressor, reversed, self);
22209 } else {
22210 self = best_of(compressor, self, reversed);
22211 }
22212 }
22213 if (associative && self.is_number_or_bigint(compressor)) {
22214 // a + (b + c) => (a + b) + c
22215 if (self.right instanceof AST_Binary
22216 && self.right.operator == self.operator) {
22217 self = make_node(AST_Binary, self, {
22218 operator: self.operator,
22219 left: make_node(AST_Binary, self.left, {
22220 operator: self.operator,
22221 left: self.left,
22222 right: self.right.left,
22223 start: self.left.start,
22224 end: self.right.left.end
22225 }),
22226 right: self.right.right
22227 });
22228 }
22229 // (n + 2) + 3 => 5 + n
22230 // (2 * n) * 3 => 6 + n
22231 if (self.right instanceof AST_Constant
22232 && self.left instanceof AST_Binary
22233 && self.left.operator == self.operator) {
22234 if (self.left.left instanceof AST_Constant) {
22235 self = make_node(AST_Binary, self, {
22236 operator: self.operator,
22237 left: make_node(AST_Binary, self.left, {
22238 operator: self.operator,
22239 left: self.left.left,
22240 right: self.right,
22241 start: self.left.left.start,
22242 end: self.right.end
22243 }),
22244 right: self.left.right
22245 });
22246 } else if (self.left.right instanceof AST_Constant) {
22247 self = make_node(AST_Binary, self, {
22248 operator: self.operator,
22249 left: make_node(AST_Binary, self.left, {
22250 operator: self.operator,
22251 left: self.left.right,
22252 right: self.right,
22253 start: self.left.right.start,
22254 end: self.right.end
22255 }),
22256 right: self.left.left
22257 });
22258 }
22259 }
22260 // (a | 1) | (2 | d) => (3 | a) | b
22261 if (self.left instanceof AST_Binary
22262 && self.left.operator == self.operator
22263 && self.left.right instanceof AST_Constant
22264 && self.right instanceof AST_Binary
22265 && self.right.operator == self.operator
22266 && self.right.left instanceof AST_Constant) {
22267 self = make_node(AST_Binary, self, {
22268 operator: self.operator,
22269 left: make_node(AST_Binary, self.left, {
22270 operator: self.operator,
22271 left: make_node(AST_Binary, self.left.left, {
22272 operator: self.operator,
22273 left: self.left.right,
22274 right: self.right.left,
22275 start: self.left.right.start,
22276 end: self.right.left.end
22277 }),
22278 right: self.left.left
22279 }),
22280 right: self.right.right
22281 });
22282 }
22283 }
22284 }
22285
22286 // bitwise ops
22287 if (bitwise_binop.has(self.operator)) {
22288 // Use De Morgan's laws
22289 // z & (X | y)
22290 // => z & X (given y & z === 0)
22291 // => z & X | {y & z} (given y & z !== 0)
22292 let y, z, x_node, y_node, z_node = self.left;
22293 if (
22294 self.operator === "&"
22295 && self.right instanceof AST_Binary
22296 && self.right.operator === "|"
22297 && typeof (z = self.left.evaluate(compressor)) === "number"
22298 ) {
22299 if (typeof (y = self.right.right.evaluate(compressor)) === "number") {
22300 // z & (X | y)
22301 x_node = self.right.left;
22302 y_node = self.right.right;
22303 } else if (typeof (y = self.right.left.evaluate(compressor)) === "number") {
22304 // z & (y | X)
22305 x_node = self.right.right;
22306 y_node = self.right.left;
22307 }
22308
22309 if (x_node && y_node) {
22310 if ((y & z) === 0) {
22311 self = make_node(AST_Binary, self, {
22312 operator: self.operator,
22313 left: z_node,
22314 right: x_node
22315 });
22316 } else {
22317 const reordered_ops = make_node(AST_Binary, self, {
22318 operator: "|",
22319 left: make_node(AST_Binary, self, {
22320 operator: "&",
22321 left: x_node,
22322 right: z_node
22323 }),
22324 right: make_node_from_constant(y & z, y_node),
22325 });
22326
22327 self = best_of(compressor, self, reordered_ops);
22328 }
22329 }
22330 }
22331
22332 // x | x => 0 | x
22333 // x & x => 0 | x
22334 if (
22335 (self.operator === "|" || self.operator === "&")
22336 && self.left.equivalent_to(self.right)
22337 && !self.left.has_side_effects(compressor)
22338 && compressor.in_32_bit_context(true)
22339 ) {
22340 self.left = make_node(AST_Number, self, { value: 0 });
22341 self.operator = "|";
22342 }
22343
22344 // ~x ^ ~y => x ^ y
22345 if (
22346 self.operator === "^"
22347 && self.left instanceof AST_UnaryPrefix
22348 && self.left.operator === "~"
22349 && self.right instanceof AST_UnaryPrefix
22350 && self.right.operator === "~"
22351 ) {
22352 self = make_node(AST_Binary, self, {
22353 operator: "^",
22354 left: self.left.expression,
22355 right: self.right.expression
22356 });
22357 }
22358
22359
22360 // Shifts that do nothing
22361 // {anything} >> 0 => {anything} | 0
22362 // {anything} << 0 => {anything} | 0
22363 if (
22364 (self.operator === "<<" || self.operator === ">>")
22365 && self.right instanceof AST_Number && self.right.value === 0
22366 ) {
22367 self.operator = "|";
22368 }
22369
22370 // Find useless to-bitwise conversions
22371 // {32 bit integer} | 0 => {32 bit integer}
22372 // {32 bit integer} ^ 0 => {32 bit integer}
22373 const zero_side = self.right instanceof AST_Number && self.right.value === 0 ? self.right
22374 : self.left instanceof AST_Number && self.left.value === 0 ? self.left
22375 : null;
22376 const non_zero_side = zero_side && (zero_side === self.right ? self.left : self.right);
22377 if (
22378 zero_side
22379 && (self.operator === "|" || self.operator === "^")
22380 && (non_zero_side.is_32_bit_integer(compressor) || compressor.in_32_bit_context(true))
22381 ) {
22382 return non_zero_side;
22383 }
22384
22385 // {anything} & 0 => 0
22386 if (
22387 zero_side
22388 && self.operator === "&"
22389 && !non_zero_side.has_side_effects(compressor)
22390 && non_zero_side.is_32_bit_integer(compressor)
22391 ) {
22392 return zero_side;
22393 }
22394
22395 // ~0 is all ones, as well as -1.
22396 // We can ellide some operations with it.
22397 const is_full_mask = (node) =>
22398 node instanceof AST_Number && node.value === -1
22399 ||
22400 node instanceof AST_UnaryPrefix
22401 && node.operator === "-"
22402 && node.expression instanceof AST_Number
22403 && node.expression.value === 1;
22404
22405 const full_mask = is_full_mask(self.right) ? self.right
22406 : is_full_mask(self.left) ? self.left
22407 : null;
22408 const other_side = (full_mask === self.right ? self.left : self.right);
22409
22410 // {32 bit integer} & -1 => {32 bit integer}
22411 if (
22412 full_mask
22413 && self.operator === "&"
22414 && (
22415 other_side.is_32_bit_integer(compressor)
22416 || compressor.in_32_bit_context(true)
22417 )
22418 ) {
22419 return other_side;
22420 }
22421
22422 // {anything} ^ -1 => ~{anything}
22423 if (
22424 full_mask
22425 && self.operator === "^"
22426 && (
22427 other_side.is_32_bit_integer(compressor)
22428 || compressor.in_32_bit_context(true)
22429 )
22430 ) {
22431 return other_side.bitwise_negate(compressor);
22432 }
22433 }
22434 }
22435 // x && (y && z) ==> x && y && z
22436 // x || (y || z) ==> x || y || z
22437 // x + ("y" + z) ==> x + "y" + z
22438 // "x" + (y + "z")==> "x" + y + "z"
22439 if (self.right instanceof AST_Binary
22440 && self.right.operator == self.operator
22441 && (lazy_op.has(self.operator)
22442 || (self.operator == "+"
22443 && (self.right.left.is_string(compressor)
22444 || (self.left.is_string(compressor)
22445 && self.right.right.is_string(compressor)))))
22446 ) {
22447 self.left = make_node(AST_Binary, self.left, {
22448 operator : self.operator,
22449 left : self.left.transform(compressor),
22450 right : self.right.left.transform(compressor)
22451 });
22452 self.right = self.right.right.transform(compressor);
22453 return self.transform(compressor);
22454 }
22455 var ev = self.evaluate(compressor);
22456 if (ev !== self) {
22457 ev = make_node_from_constant(ev, self).optimize(compressor);
22458 return best_of(compressor, ev, self);
22459 }
22460 return self;
22461});
22462
22463def_optimize(AST_SymbolExport, function(self) {
22464 return self;
22465});
22466
22467def_optimize(AST_SymbolRef, function(self, compressor) {
22468 if (
22469 !compressor.option("ie8")
22470 && is_undeclared_ref(self)
22471 && !compressor.find_parent(AST_With)
22472 ) {
22473 switch (self.name) {
22474 case "undefined":
22475 return make_node(AST_Undefined, self).optimize(compressor);
22476 case "NaN":
22477 return make_node(AST_NaN, self).optimize(compressor);
22478 case "Infinity":
22479 return make_node(AST_Infinity, self).optimize(compressor);
22480 }
22481 }
22482
22483 if (compressor.option("reduce_vars") && !compressor.is_lhs()) {
22484 return inline_into_symbolref(self, compressor);
22485 } else {
22486 return self;
22487 }
22488});
22489
22490function is_atomic(lhs, self) {
22491 return lhs instanceof AST_SymbolRef || lhs.TYPE === self.TYPE;
22492}
22493
22494/** Apply the `unsafe_undefined` option: find a variable called `undefined` and turn `self` into a reference to it. */
22495function unsafe_undefined_ref(self, compressor) {
22496 if (compressor.option("unsafe_undefined")) {
22497 var undef = find_variable(compressor, "undefined");
22498 if (undef) {
22499 var ref = make_node(AST_SymbolRef, self, {
22500 name : "undefined",
22501 scope : undef.scope,
22502 thedef : undef
22503 });
22504 set_flag(ref, UNDEFINED);
22505 return ref;
22506 }
22507 }
22508 return null;
22509}
22510
22511def_optimize(AST_Undefined, function(self, compressor) {
22512 var symbolref = unsafe_undefined_ref(self, compressor);
22513 if (symbolref) return symbolref;
22514 var lhs = compressor.is_lhs();
22515 if (lhs && is_atomic(lhs, self)) return self;
22516 return make_void_0(self);
22517});
22518
22519def_optimize(AST_Infinity, function(self, compressor) {
22520 var lhs = compressor.is_lhs();
22521 if (lhs && is_atomic(lhs, self)) return self;
22522 if (
22523 compressor.option("keep_infinity")
22524 && !(lhs && !is_atomic(lhs, self))
22525 && !find_variable(compressor, "Infinity")
22526 ) {
22527 return self;
22528 }
22529 return make_node(AST_Binary, self, {
22530 operator: "/",
22531 left: make_node(AST_Number, self, {
22532 value: 1
22533 }),
22534 right: make_node(AST_Number, self, {
22535 value: 0
22536 })
22537 });
22538});
22539
22540def_optimize(AST_NaN, function(self, compressor) {
22541 var lhs = compressor.is_lhs();
22542 if (lhs && !is_atomic(lhs, self)
22543 || find_variable(compressor, "NaN")) {
22544 return make_node(AST_Binary, self, {
22545 operator: "/",
22546 left: make_node(AST_Number, self, {
22547 value: 0
22548 }),
22549 right: make_node(AST_Number, self, {
22550 value: 0
22551 })
22552 });
22553 }
22554 return self;
22555});
22556
22557const ASSIGN_OPS = makePredicate("+ - / * % >> << >>> | ^ &");
22558const ASSIGN_OPS_COMMUTATIVE = makePredicate("* | ^ &");
22559def_optimize(AST_Assign, function(self, compressor) {
22560 if (self.logical) {
22561 return self.lift_sequences(compressor);
22562 }
22563
22564 var def;
22565 // x = x ---> x
22566 if (
22567 self.operator === "="
22568 && self.left instanceof AST_SymbolRef
22569 && self.left.name !== "arguments"
22570 && !(def = self.left.definition()).undeclared
22571 && self.right.equivalent_to(self.left)
22572 ) {
22573 return self.right;
22574 }
22575
22576 if (compressor.option("dead_code")
22577 && self.left instanceof AST_SymbolRef
22578 && (def = self.left.definition()).scope === compressor.find_parent(AST_Lambda)) {
22579 var level = 0, node, parent = self;
22580 do {
22581 node = parent;
22582 parent = compressor.parent(level++);
22583 if (parent instanceof AST_Exit) {
22584 if (in_try(level, parent)) break;
22585 if (is_reachable(def.scope, [ def ])) break;
22586 if (self.operator == "=") return self.right;
22587 def.fixed = false;
22588 return make_node(AST_Binary, self, {
22589 operator: self.operator.slice(0, -1),
22590 left: self.left,
22591 right: self.right
22592 }).optimize(compressor);
22593 }
22594 } while (parent instanceof AST_Binary && parent.right === node
22595 || parent instanceof AST_Sequence && parent.tail_node() === node);
22596 }
22597 self = self.lift_sequences(compressor);
22598
22599 if (self.operator == "=" && self.left instanceof AST_SymbolRef && self.right instanceof AST_Binary) {
22600 // x = expr1 OP expr2
22601 if (self.right.left instanceof AST_SymbolRef
22602 && self.right.left.name == self.left.name
22603 && ASSIGN_OPS.has(self.right.operator)) {
22604 // x = x - 2 ---> x -= 2
22605 self.operator = self.right.operator + "=";
22606 self.right = self.right.right;
22607 } else if (self.right.right instanceof AST_SymbolRef
22608 && self.right.right.name == self.left.name
22609 && ASSIGN_OPS_COMMUTATIVE.has(self.right.operator)
22610 && !self.right.left.has_side_effects(compressor)) {
22611 // x = 2 & x ---> x &= 2
22612 self.operator = self.right.operator + "=";
22613 self.right = self.right.left;
22614 }
22615 }
22616 return self;
22617
22618 function in_try(level, node) {
22619 function may_assignment_throw() {
22620 const right = self.right;
22621 self.right = make_node(AST_Null, right);
22622 const may_throw = node.may_throw(compressor);
22623 self.right = right;
22624
22625 return may_throw;
22626 }
22627
22628 var stop_at = self.left.definition().scope.get_defun_scope();
22629 var parent;
22630 while ((parent = compressor.parent(level++)) !== stop_at) {
22631 if (parent instanceof AST_Try) {
22632 if (parent.bfinally) return true;
22633 if (parent.bcatch && may_assignment_throw()) return true;
22634 }
22635 }
22636 }
22637});
22638
22639def_optimize(AST_DefaultAssign, function(self, compressor) {
22640 if (!compressor.option("evaluate")) {
22641 return self;
22642 }
22643 var evaluateRight = self.right.evaluate(compressor);
22644
22645 // `[x = undefined] = foo` ---> `[x] = foo`
22646 // `(arg = undefined) => ...` ---> `(arg) => ...` (unless `keep_fargs`)
22647 // `((arg = undefined) => ...)()` ---> `((arg) => ...)()`
22648 let lambda, iife;
22649 if (evaluateRight === undefined) {
22650 if (
22651 (lambda = compressor.parent()) instanceof AST_Lambda
22652 ? (
22653 compressor.option("keep_fargs") === false
22654 || (iife = compressor.parent(1)).TYPE === "Call"
22655 && iife.expression === lambda
22656 )
22657 : true
22658 ) {
22659 self = self.left;
22660 }
22661 } else if (evaluateRight !== self.right) {
22662 evaluateRight = make_node_from_constant(evaluateRight, self.right);
22663 self.right = best_of_expression(evaluateRight, self.right);
22664 }
22665
22666 return self;
22667});
22668
22669function is_nullish_check(check, check_subject, compressor) {
22670 if (check_subject.may_throw(compressor)) return false;
22671
22672 let nullish_side;
22673
22674 // foo == null
22675 if (
22676 check instanceof AST_Binary
22677 && check.operator === "=="
22678 // which side is nullish?
22679 && (
22680 (nullish_side = is_nullish(check.left, compressor) && check.left)
22681 || (nullish_side = is_nullish(check.right, compressor) && check.right)
22682 )
22683 // is the other side the same as the check_subject
22684 && (
22685 nullish_side === check.left
22686 ? check.right
22687 : check.left
22688 ).equivalent_to(check_subject)
22689 ) {
22690 return true;
22691 }
22692
22693 // foo === null || foo === undefined
22694 if (check instanceof AST_Binary && check.operator === "||") {
22695 let null_cmp;
22696 let undefined_cmp;
22697
22698 const find_comparison = cmp => {
22699 if (!(
22700 cmp instanceof AST_Binary
22701 && (cmp.operator === "===" || cmp.operator === "==")
22702 )) {
22703 return false;
22704 }
22705
22706 let found = 0;
22707 let defined_side;
22708
22709 if (cmp.left instanceof AST_Null) {
22710 found++;
22711 null_cmp = cmp;
22712 defined_side = cmp.right;
22713 }
22714 if (cmp.right instanceof AST_Null) {
22715 found++;
22716 null_cmp = cmp;
22717 defined_side = cmp.left;
22718 }
22719 if (is_undefined(cmp.left, compressor)) {
22720 found++;
22721 undefined_cmp = cmp;
22722 defined_side = cmp.right;
22723 }
22724 if (is_undefined(cmp.right, compressor)) {
22725 found++;
22726 undefined_cmp = cmp;
22727 defined_side = cmp.left;
22728 }
22729
22730 if (found !== 1) {
22731 return false;
22732 }
22733
22734 if (!defined_side.equivalent_to(check_subject)) {
22735 return false;
22736 }
22737
22738 return true;
22739 };
22740
22741 if (!find_comparison(check.left)) return false;
22742 if (!find_comparison(check.right)) return false;
22743
22744 if (null_cmp && undefined_cmp && null_cmp !== undefined_cmp) {
22745 return true;
22746 }
22747 }
22748
22749 return false;
22750}
22751
22752def_optimize(AST_Conditional, function(self, compressor) {
22753 if (!compressor.option("conditionals")) return self;
22754 // This looks like lift_sequences(), should probably be under "sequences"
22755 if (self.condition instanceof AST_Sequence) {
22756 var expressions = self.condition.expressions.slice();
22757 self.condition = expressions.pop();
22758 expressions.push(self);
22759 return make_sequence(self, expressions);
22760 }
22761 var cond = self.condition.evaluate(compressor);
22762 if (cond !== self.condition) {
22763 if (cond) {
22764 return maintain_this_binding(compressor.parent(), compressor.self(), self.consequent);
22765 } else {
22766 return maintain_this_binding(compressor.parent(), compressor.self(), self.alternative);
22767 }
22768 }
22769 var negated = cond.negate(compressor, first_in_statement(compressor));
22770 if (best_of(compressor, cond, negated) === negated) {
22771 self = make_node(AST_Conditional, self, {
22772 condition: negated,
22773 consequent: self.alternative,
22774 alternative: self.consequent
22775 });
22776 }
22777 var condition = self.condition;
22778 var consequent = self.consequent;
22779 var alternative = self.alternative;
22780 // x?x:y --> x||y
22781 if (condition instanceof AST_SymbolRef
22782 && consequent instanceof AST_SymbolRef
22783 && condition.definition() === consequent.definition()) {
22784 return make_node(AST_Binary, self, {
22785 operator: "||",
22786 left: condition,
22787 right: alternative
22788 });
22789 }
22790 // if (foo) exp = something; else exp = something_else;
22791 // |
22792 // v
22793 // exp = foo ? something : something_else;
22794 if (
22795 consequent instanceof AST_Assign
22796 && alternative instanceof AST_Assign
22797 && consequent.operator === alternative.operator
22798 && consequent.logical === alternative.logical
22799 && consequent.left.equivalent_to(alternative.left)
22800 && (!self.condition.has_side_effects(compressor)
22801 || consequent.operator == "="
22802 && !consequent.left.has_side_effects(compressor))
22803 ) {
22804 return make_node(AST_Assign, self, {
22805 operator: consequent.operator,
22806 left: consequent.left,
22807 logical: consequent.logical,
22808 right: make_node(AST_Conditional, self, {
22809 condition: self.condition,
22810 consequent: consequent.right,
22811 alternative: alternative.right
22812 })
22813 });
22814 }
22815 // x ? y(a) : y(b) --> y(x ? a : b)
22816 var arg_index;
22817 if (consequent instanceof AST_Call
22818 && alternative.TYPE === consequent.TYPE
22819 && consequent.args.length > 0
22820 && consequent.args.length == alternative.args.length
22821 && consequent.expression.equivalent_to(alternative.expression)
22822 && !self.condition.has_side_effects(compressor)
22823 && !consequent.expression.has_side_effects(compressor)
22824 && typeof (arg_index = single_arg_diff()) == "number") {
22825 var node = consequent.clone();
22826 node.args[arg_index] = make_node(AST_Conditional, self, {
22827 condition: self.condition,
22828 consequent: consequent.args[arg_index],
22829 alternative: alternative.args[arg_index]
22830 });
22831 return node;
22832 }
22833 // a ? b : c ? b : d --> (a || c) ? b : d
22834 if (alternative instanceof AST_Conditional
22835 && consequent.equivalent_to(alternative.consequent)) {
22836 return make_node(AST_Conditional, self, {
22837 condition: make_node(AST_Binary, self, {
22838 operator: "||",
22839 left: condition,
22840 right: alternative.condition
22841 }),
22842 consequent: consequent,
22843 alternative: alternative.alternative
22844 }).optimize(compressor);
22845 }
22846
22847 // a == null ? b : a -> a ?? b
22848 if (
22849 compressor.option("ecma") >= 2020 &&
22850 is_nullish_check(condition, alternative, compressor)
22851 ) {
22852 return make_node(AST_Binary, self, {
22853 operator: "??",
22854 left: alternative,
22855 right: consequent
22856 }).optimize(compressor);
22857 }
22858
22859 // a ? b : (c, b) --> (a || c), b
22860 if (alternative instanceof AST_Sequence
22861 && consequent.equivalent_to(alternative.expressions[alternative.expressions.length - 1])) {
22862 return make_sequence(self, [
22863 make_node(AST_Binary, self, {
22864 operator: "||",
22865 left: condition,
22866 right: make_sequence(self, alternative.expressions.slice(0, -1))
22867 }),
22868 consequent
22869 ]).optimize(compressor);
22870 }
22871 // a ? b : (c && b) --> (a || c) && b
22872 if (alternative instanceof AST_Binary
22873 && alternative.operator == "&&"
22874 && consequent.equivalent_to(alternative.right)) {
22875 return make_node(AST_Binary, self, {
22876 operator: "&&",
22877 left: make_node(AST_Binary, self, {
22878 operator: "||",
22879 left: condition,
22880 right: alternative.left
22881 }),
22882 right: consequent
22883 }).optimize(compressor);
22884 }
22885 // x?y?z:a:a --> x&&y?z:a
22886 if (consequent instanceof AST_Conditional
22887 && consequent.alternative.equivalent_to(alternative)) {
22888 return make_node(AST_Conditional, self, {
22889 condition: make_node(AST_Binary, self, {
22890 left: self.condition,
22891 operator: "&&",
22892 right: consequent.condition
22893 }),
22894 consequent: consequent.consequent,
22895 alternative: alternative
22896 });
22897 }
22898 // x ? y : y --> x, y
22899 if (consequent.equivalent_to(alternative)) {
22900 return make_sequence(self, [
22901 self.condition,
22902 consequent
22903 ]).optimize(compressor);
22904 }
22905 // x ? y || z : z --> x && y || z
22906 if (consequent instanceof AST_Binary
22907 && consequent.operator == "||"
22908 && consequent.right.equivalent_to(alternative)) {
22909 return make_node(AST_Binary, self, {
22910 operator: "||",
22911 left: make_node(AST_Binary, self, {
22912 operator: "&&",
22913 left: self.condition,
22914 right: consequent.left
22915 }),
22916 right: alternative
22917 }).optimize(compressor);
22918 }
22919
22920 const in_bool = compressor.in_boolean_context();
22921 if (is_true(self.consequent)) {
22922 if (is_false(self.alternative)) {
22923 // c ? true : false ---> !!c
22924 return booleanize(self.condition);
22925 }
22926 // c ? true : x ---> !!c || x
22927 return make_node(AST_Binary, self, {
22928 operator: "||",
22929 left: booleanize(self.condition),
22930 right: self.alternative
22931 });
22932 }
22933 if (is_false(self.consequent)) {
22934 if (is_true(self.alternative)) {
22935 // c ? false : true ---> !c
22936 return booleanize(self.condition.negate(compressor));
22937 }
22938 // c ? false : x ---> !c && x
22939 return make_node(AST_Binary, self, {
22940 operator: "&&",
22941 left: booleanize(self.condition.negate(compressor)),
22942 right: self.alternative
22943 });
22944 }
22945 if (is_true(self.alternative)) {
22946 // c ? x : true ---> !c || x
22947 return make_node(AST_Binary, self, {
22948 operator: "||",
22949 left: booleanize(self.condition.negate(compressor)),
22950 right: self.consequent
22951 });
22952 }
22953 if (is_false(self.alternative)) {
22954 // c ? x : false ---> !!c && x
22955 return make_node(AST_Binary, self, {
22956 operator: "&&",
22957 left: booleanize(self.condition),
22958 right: self.consequent
22959 });
22960 }
22961
22962 return self;
22963
22964 function booleanize(node) {
22965 if (node.is_boolean()) return node;
22966 // !!expression
22967 return make_node(AST_UnaryPrefix, node, {
22968 operator: "!",
22969 expression: node.negate(compressor)
22970 });
22971 }
22972
22973 // AST_True or !0
22974 function is_true(node) {
22975 return node instanceof AST_True
22976 || in_bool
22977 && node instanceof AST_Constant
22978 && node.getValue()
22979 || (node instanceof AST_UnaryPrefix
22980 && node.operator == "!"
22981 && node.expression instanceof AST_Constant
22982 && !node.expression.getValue());
22983 }
22984 // AST_False or !1
22985 function is_false(node) {
22986 return node instanceof AST_False
22987 || in_bool
22988 && node instanceof AST_Constant
22989 && !node.getValue()
22990 || (node instanceof AST_UnaryPrefix
22991 && node.operator == "!"
22992 && node.expression instanceof AST_Constant
22993 && node.expression.getValue());
22994 }
22995
22996 function single_arg_diff() {
22997 var a = consequent.args;
22998 var b = alternative.args;
22999 for (var i = 0, len = a.length; i < len; i++) {
23000 if (a[i] instanceof AST_Expansion) return;
23001 if (!a[i].equivalent_to(b[i])) {
23002 if (b[i] instanceof AST_Expansion) return;
23003 for (var j = i + 1; j < len; j++) {
23004 if (a[j] instanceof AST_Expansion) return;
23005 if (!a[j].equivalent_to(b[j])) return;
23006 }
23007 return i;
23008 }
23009 }
23010 }
23011});
23012
23013def_optimize(AST_Boolean, function(self, compressor) {
23014 if (compressor.in_boolean_context()) return make_node(AST_Number, self, {
23015 value: +self.value
23016 });
23017 var p = compressor.parent();
23018 if (compressor.option("booleans_as_integers")) {
23019 if (p instanceof AST_Binary && (p.operator == "===" || p.operator == "!==")) {
23020 p.operator = p.operator.replace(/=$/, "");
23021 }
23022 return make_node(AST_Number, self, {
23023 value: +self.value
23024 });
23025 }
23026 if (compressor.option("booleans")) {
23027 if (p instanceof AST_Binary && (p.operator == "=="
23028 || p.operator == "!=")) {
23029 return make_node(AST_Number, self, {
23030 value: +self.value
23031 });
23032 }
23033 return make_node(AST_UnaryPrefix, self, {
23034 operator: "!",
23035 expression: make_node(AST_Number, self, {
23036 value: 1 - self.value
23037 })
23038 });
23039 }
23040 return self;
23041});
23042
23043function safe_to_flatten(value, compressor) {
23044 if (value instanceof AST_SymbolRef) {
23045 value = value.fixed_value();
23046 }
23047 if (!value) return false;
23048 if (!(value instanceof AST_Lambda || value instanceof AST_Class)) return true;
23049 if (!(value instanceof AST_Lambda && value.contains_this())) return true;
23050 return compressor.parent() instanceof AST_New;
23051}
23052
23053AST_PropAccess.DEFMETHOD("flatten_object", function(key, compressor) {
23054 if (!compressor.option("properties")) return;
23055 if (key === "__proto__") return;
23056 if (this instanceof AST_DotHash) return;
23057
23058 var arrows = compressor.option("unsafe_arrows") && compressor.option("ecma") >= 2015;
23059 var expr = this.expression;
23060 if (expr instanceof AST_Object) {
23061 var props = expr.properties;
23062
23063 for (var i = props.length; --i >= 0;) {
23064 var prop = props[i];
23065
23066 if ("" + (prop instanceof AST_ConciseMethod ? prop.key.name : prop.key) == key) {
23067 const all_props_flattenable = props.every((p) =>
23068 (p instanceof AST_ObjectKeyVal
23069 || arrows && p instanceof AST_ConciseMethod && !p.value.is_generator
23070 )
23071 && !p.computed_key()
23072 );
23073
23074 if (!all_props_flattenable) return;
23075 if (!safe_to_flatten(prop.value, compressor)) return;
23076
23077 return make_node(AST_Sub, this, {
23078 expression: make_node(AST_Array, expr, {
23079 elements: props.map(function(prop) {
23080 var v = prop.value;
23081 if (v instanceof AST_Accessor) {
23082 v = make_node(AST_Function, v, v);
23083 }
23084
23085 var k = prop.key;
23086 if (k instanceof AST_Node && !(k instanceof AST_SymbolMethod)) {
23087 return make_sequence(prop, [ k, v ]);
23088 }
23089
23090 return v;
23091 })
23092 }),
23093 property: make_node(AST_Number, this, {
23094 value: i
23095 })
23096 });
23097 }
23098 }
23099 }
23100});
23101
23102def_optimize(AST_Sub, function(self, compressor) {
23103 var expr = self.expression;
23104 var prop = self.property;
23105 if (compressor.option("properties")) {
23106 var key = prop.evaluate(compressor);
23107 if (key !== prop) {
23108 if (typeof key == "string") {
23109 if (key == "undefined") {
23110 key = undefined;
23111 } else {
23112 var value = parseFloat(key);
23113 if (value.toString() == key) {
23114 key = value;
23115 }
23116 }
23117 }
23118 prop = self.property = best_of_expression(
23119 prop,
23120 make_node_from_constant(key, prop).transform(compressor)
23121 );
23122 var property = "" + key;
23123 if (is_basic_identifier_string(property)
23124 && property.length <= prop.size() + 1) {
23125 return make_node(AST_Dot, self, {
23126 expression: expr,
23127 optional: self.optional,
23128 property: property,
23129 quote: prop.quote,
23130 }).optimize(compressor);
23131 }
23132 }
23133 }
23134 var fn;
23135 OPT_ARGUMENTS: if (compressor.option("arguments")
23136 && expr instanceof AST_SymbolRef
23137 && expr.name == "arguments"
23138 && expr.definition().orig.length == 1
23139 && (fn = expr.scope) instanceof AST_Lambda
23140 && fn.uses_arguments
23141 && !(fn instanceof AST_Arrow)
23142 && prop instanceof AST_Number) {
23143 var index = prop.getValue();
23144 var params = new Set();
23145 var argnames = fn.argnames;
23146 for (var n = 0; n < argnames.length; n++) {
23147 if (!(argnames[n] instanceof AST_SymbolFunarg)) {
23148 break OPT_ARGUMENTS; // destructuring parameter - bail
23149 }
23150 var param = argnames[n].name;
23151 if (params.has(param)) {
23152 break OPT_ARGUMENTS; // duplicate parameter - bail
23153 }
23154 params.add(param);
23155 }
23156 var argname = fn.argnames[index];
23157 if (argname && compressor.has_directive("use strict")) {
23158 var def = argname.definition();
23159 if (!compressor.option("reduce_vars") || def.assignments || def.orig.length > 1) {
23160 argname = null;
23161 }
23162 } else if (!argname && !compressor.option("keep_fargs") && index < fn.argnames.length + 5) {
23163 while (index >= fn.argnames.length) {
23164 argname = fn.create_symbol(AST_SymbolFunarg, {
23165 source: fn,
23166 scope: fn,
23167 tentative_name: "argument_" + fn.argnames.length,
23168 });
23169 fn.argnames.push(argname);
23170 }
23171 }
23172 if (argname) {
23173 var sym = make_node(AST_SymbolRef, self, argname);
23174 sym.reference({});
23175 clear_flag(argname, UNUSED);
23176 return sym;
23177 }
23178 }
23179 if (compressor.is_lhs()) return self;
23180 if (key !== prop) {
23181 var sub = self.flatten_object(property, compressor);
23182 if (sub) {
23183 expr = self.expression = sub.expression;
23184 prop = self.property = sub.property;
23185 }
23186 }
23187 if (compressor.option("properties") && compressor.option("side_effects")
23188 && prop instanceof AST_Number && expr instanceof AST_Array) {
23189 var index = prop.getValue();
23190 var elements = expr.elements;
23191 var retValue = elements[index];
23192 FLATTEN: if (safe_to_flatten(retValue, compressor)) {
23193 var flatten = true;
23194 var values = [];
23195 for (var i = elements.length; --i > index;) {
23196 var value = elements[i].drop_side_effect_free(compressor);
23197 if (value) {
23198 values.unshift(value);
23199 if (flatten && value.has_side_effects(compressor)) flatten = false;
23200 }
23201 }
23202 if (retValue instanceof AST_Expansion) break FLATTEN;
23203 retValue = retValue instanceof AST_Hole ? make_void_0(retValue) : retValue;
23204 if (!flatten) values.unshift(retValue);
23205 while (--i >= 0) {
23206 var value = elements[i];
23207 if (value instanceof AST_Expansion) break FLATTEN;
23208 value = value.drop_side_effect_free(compressor);
23209 if (value) values.unshift(value);
23210 else index--;
23211 }
23212 if (flatten) {
23213 values.push(retValue);
23214 return make_sequence(self, values).optimize(compressor);
23215 } else return make_node(AST_Sub, self, {
23216 expression: make_node(AST_Array, expr, {
23217 elements: values
23218 }),
23219 property: make_node(AST_Number, prop, {
23220 value: index
23221 })
23222 });
23223 }
23224 }
23225 var ev = self.evaluate(compressor);
23226 if (ev !== self) {
23227 ev = make_node_from_constant(ev, self).optimize(compressor);
23228 return best_of(compressor, ev, self);
23229 }
23230 return self;
23231});
23232
23233def_optimize(AST_Chain, function (self, compressor) {
23234 if (is_nullish(self.expression, compressor)) {
23235 let parent = compressor.parent();
23236 // It's valid to delete a nullish optional chain, but if we optimized
23237 // this to `delete undefined` then it would appear to be a syntax error
23238 // when we try to optimize the delete. Thankfully, `delete 0` is fine.
23239 if (parent instanceof AST_UnaryPrefix && parent.operator === "delete") {
23240 return make_node_from_constant(0, self);
23241 }
23242 return make_void_0(self).optimize(compressor);
23243 }
23244 if (
23245 self.expression instanceof AST_PropAccess
23246 || self.expression instanceof AST_Call
23247 ) {
23248 return self;
23249 } else {
23250 // Keep the AST valid, in case the child swapped itself
23251 return self.expression;
23252 }
23253});
23254
23255def_optimize(AST_Dot, function(self, compressor) {
23256 const parent = compressor.parent();
23257 if (compressor.is_lhs()) return self;
23258 if (compressor.option("unsafe_proto")
23259 && self.expression instanceof AST_Dot
23260 && self.expression.property == "prototype") {
23261 var exp = self.expression.expression;
23262 if (is_undeclared_ref(exp)) switch (exp.name) {
23263 case "Array":
23264 self.expression = make_node(AST_Array, self.expression, {
23265 elements: []
23266 });
23267 break;
23268 case "Function":
23269 self.expression = make_empty_function(self.expression);
23270 break;
23271 case "Number":
23272 self.expression = make_node(AST_Number, self.expression, {
23273 value: 0
23274 });
23275 break;
23276 case "Object":
23277 self.expression = make_node(AST_Object, self.expression, {
23278 properties: []
23279 });
23280 break;
23281 case "RegExp":
23282 self.expression = make_node(AST_RegExp, self.expression, {
23283 value: { source: "t", flags: "" }
23284 });
23285 break;
23286 case "String":
23287 self.expression = make_node(AST_String, self.expression, {
23288 value: ""
23289 });
23290 break;
23291 }
23292 }
23293 if (!(parent instanceof AST_Call) || !has_annotation(parent, _NOINLINE)) {
23294 const sub = self.flatten_object(self.property, compressor);
23295 if (sub) return sub.optimize(compressor);
23296 }
23297
23298 if (self.expression instanceof AST_PropAccess
23299 && parent instanceof AST_PropAccess) {
23300 return self;
23301 }
23302
23303 let ev = self.evaluate(compressor);
23304 if (ev !== self) {
23305 ev = make_node_from_constant(ev, self).optimize(compressor);
23306 return best_of(compressor, ev, self);
23307 }
23308 return self;
23309});
23310
23311function literals_in_boolean_context(self, compressor) {
23312 if (compressor.in_boolean_context()) {
23313 return best_of(compressor, self, make_sequence(self, [
23314 self,
23315 make_node(AST_True, self)
23316 ]).optimize(compressor));
23317 }
23318 return self;
23319}
23320
23321function inline_array_like_spread(elements) {
23322 for (var i = 0; i < elements.length; i++) {
23323 var el = elements[i];
23324 if (el instanceof AST_Expansion) {
23325 var expr = el.expression;
23326 if (
23327 expr instanceof AST_Array
23328 && !expr.elements.some(elm => elm instanceof AST_Hole)
23329 ) {
23330 elements.splice(i, 1, ...expr.elements);
23331 // Step back one, as the element at i is now new.
23332 i--;
23333 }
23334 // In array-like spread, spreading a non-iterable value is TypeError.
23335 // We therefore can’t optimize anything else, unlike with object spread.
23336 }
23337 }
23338}
23339
23340def_optimize(AST_Array, function(self, compressor) {
23341 var optimized = literals_in_boolean_context(self, compressor);
23342 if (optimized !== self) {
23343 return optimized;
23344 }
23345 inline_array_like_spread(self.elements);
23346 return self;
23347});
23348
23349function inline_object_prop_spread(props) {
23350 for (var i = 0; i < props.length; i++) {
23351 var prop = props[i];
23352 if (prop instanceof AST_Expansion) {
23353 const expr = prop.expression;
23354 if (
23355 expr instanceof AST_Object
23356 && expr.properties.every(prop => prop instanceof AST_ObjectKeyVal)
23357 ) {
23358 props.splice(i, 1, ...expr.properties);
23359 // Step back one, as the property at i is now new.
23360 i--;
23361 } else if ((
23362 // `expr.is_constant()` returns `false` for `AST_RegExp`, so need both.
23363 expr instanceof AST_Constant
23364 || expr.is_constant()
23365 ) && !(expr instanceof AST_String)) {
23366 // Unlike array-like spread, in object spread, spreading a
23367 // non-iterable value silently does nothing; it is thus safe
23368 // to remove. AST_String is the only iterable constant.
23369 props.splice(i, 1);
23370 i--;
23371 }
23372 }
23373 }
23374}
23375
23376def_optimize(AST_Object, function(self, compressor) {
23377 var optimized = literals_in_boolean_context(self, compressor);
23378 if (optimized !== self) {
23379 return optimized;
23380 }
23381 inline_object_prop_spread(self.properties);
23382 return self;
23383});
23384
23385def_optimize(AST_RegExp, literals_in_boolean_context);
23386
23387def_optimize(AST_Return, function(self, compressor) {
23388 if (self.value && is_undefined(self.value, compressor)) {
23389 self.value = null;
23390 }
23391 return self;
23392});
23393
23394def_optimize(AST_Arrow, opt_AST_Lambda);
23395
23396def_optimize(AST_Function, function(self, compressor) {
23397 self = opt_AST_Lambda(self, compressor);
23398 if (compressor.option("unsafe_arrows")
23399 && compressor.option("ecma") >= 2015
23400 && !self.name
23401 && !self.is_generator
23402 && !self.uses_arguments
23403 && !self.pinned()) {
23404 const uses_this = walk(self, node => {
23405 if (node instanceof AST_This) return walk_abort;
23406 });
23407 if (!uses_this) return make_node(AST_Arrow, self, self).optimize(compressor);
23408 }
23409 return self;
23410});
23411
23412def_optimize(AST_Class, function(self) {
23413 for (let i = 0; i < self.properties.length; i++) {
23414 const prop = self.properties[i];
23415 if (prop instanceof AST_ClassStaticBlock && prop.body.length == 0) {
23416 self.properties.splice(i, 1);
23417 i--;
23418 }
23419 }
23420
23421 return self;
23422});
23423
23424def_optimize(AST_ClassStaticBlock, function(self, compressor) {
23425 tighten_body(self.body, compressor);
23426 return self;
23427});
23428
23429def_optimize(AST_Yield, function(self, compressor) {
23430 if (self.expression && !self.is_star && is_undefined(self.expression, compressor)) {
23431 self.expression = null;
23432 }
23433 return self;
23434});
23435
23436def_optimize(AST_TemplateString, function(self, compressor) {
23437 if (
23438 !compressor.option("evaluate")
23439 || compressor.parent() instanceof AST_PrefixedTemplateString
23440 ) {
23441 return self;
23442 }
23443
23444 var segments = [];
23445 for (var i = 0; i < self.segments.length; i++) {
23446 var segment = self.segments[i];
23447 if (segment instanceof AST_Node) {
23448 var result = segment.evaluate(compressor);
23449 // Evaluate to constant value
23450 // Constant value shorter than ${segment}
23451 if (result !== segment && (result + "").length <= segment.size() + "${}".length) {
23452 // There should always be a previous and next segment if segment is a node
23453 segments[segments.length - 1].value = segments[segments.length - 1].value + result + self.segments[++i].value;
23454 continue;
23455 }
23456 // `before ${`innerBefore ${any} innerAfter`} after` => `before innerBefore ${any} innerAfter after`
23457 // TODO:
23458 // `before ${'test' + foo} after` => `before innerBefore ${any} innerAfter after`
23459 // `before ${foo + 'test} after` => `before innerBefore ${any} innerAfter after`
23460 if (segment instanceof AST_TemplateString) {
23461 var inners = segment.segments;
23462 segments[segments.length - 1].value += inners[0].value;
23463 for (var j = 1; j < inners.length; j++) {
23464 segment = inners[j];
23465 segments.push(segment);
23466 }
23467 continue;
23468 }
23469 }
23470 segments.push(segment);
23471 }
23472 self.segments = segments;
23473
23474 // `foo` => "foo"
23475 if (segments.length == 1) {
23476 return make_node(AST_String, self, segments[0]);
23477 }
23478
23479 if (
23480 segments.length === 3
23481 && segments[1] instanceof AST_Node
23482 && (
23483 segments[1].is_string(compressor)
23484 || segments[1].is_number_or_bigint(compressor)
23485 || is_nullish(segments[1], compressor)
23486 || compressor.option("unsafe")
23487 )
23488 ) {
23489 // `foo${bar}` => "foo" + bar
23490 if (segments[2].value === "") {
23491 return make_node(AST_Binary, self, {
23492 operator: "+",
23493 left: make_node(AST_String, self, {
23494 value: segments[0].value,
23495 }),
23496 right: segments[1],
23497 });
23498 }
23499 // `${bar}baz` => bar + "baz"
23500 if (segments[0].value === "") {
23501 return make_node(AST_Binary, self, {
23502 operator: "+",
23503 left: segments[1],
23504 right: make_node(AST_String, self, {
23505 value: segments[2].value,
23506 }),
23507 });
23508 }
23509 }
23510 return self;
23511});
23512
23513def_optimize(AST_PrefixedTemplateString, function(self) {
23514 return self;
23515});
23516
23517// ["p"]:1 ---> p:1
23518// [42]:1 ---> 42:1
23519function lift_key(self, compressor) {
23520 if (!compressor.option("computed_props")) return self;
23521 // save a comparison in the typical case
23522 if (!(self.key instanceof AST_Constant)) return self;
23523 // allow certain acceptable props as not all AST_Constants are true constants
23524 if (self.key instanceof AST_String || self.key instanceof AST_Number) {
23525 const key = self.key.value.toString();
23526
23527 if (key === "__proto__") return self;
23528 if (key == "constructor"
23529 && compressor.parent() instanceof AST_Class) return self;
23530 if (self instanceof AST_ObjectKeyVal) {
23531 self.quote = self.key.quote;
23532 self.key = key;
23533 } else if (self instanceof AST_ClassProperty) {
23534 self.quote = self.key.quote;
23535 self.key = make_node(AST_SymbolClassProperty, self.key, {
23536 name: key,
23537 });
23538 } else {
23539 self.quote = self.key.quote;
23540 self.key = make_node(AST_SymbolMethod, self.key, {
23541 name: key,
23542 });
23543 }
23544 }
23545 return self;
23546}
23547
23548def_optimize(AST_ObjectProperty, lift_key);
23549
23550def_optimize(AST_ConciseMethod, function(self, compressor) {
23551 lift_key(self, compressor);
23552 // p(){return x;} ---> p:()=>x
23553 if (compressor.option("arrows")
23554 && compressor.parent() instanceof AST_Object
23555 && !self.value.is_generator
23556 && !self.value.uses_arguments
23557 && !self.value.pinned()
23558 && self.value.body.length == 1
23559 && self.value.body[0] instanceof AST_Return
23560 && self.value.body[0].value
23561 && !self.value.contains_this()) {
23562 var arrow = make_node(AST_Arrow, self.value, self.value);
23563 arrow.async = self.value.async;
23564 arrow.is_generator = self.value.is_generator;
23565 return make_node(AST_ObjectKeyVal, self, {
23566 key: self.key instanceof AST_SymbolMethod ? self.key.name : self.key,
23567 value: arrow,
23568 quote: self.quote,
23569 });
23570 }
23571 return self;
23572});
23573
23574def_optimize(AST_ObjectKeyVal, function(self, compressor) {
23575 lift_key(self, compressor);
23576 // p:function(){} ---> p(){}
23577 // p:function*(){} ---> *p(){}
23578 // p:async function(){} ---> async p(){}
23579 // p:()=>{} ---> p(){}
23580 // p:async()=>{} ---> async p(){}
23581 var unsafe_methods = compressor.option("unsafe_methods");
23582 if (unsafe_methods
23583 && compressor.option("ecma") >= 2015
23584 && (!(unsafe_methods instanceof RegExp) || unsafe_methods.test(self.key + ""))) {
23585 var key = self.key;
23586 var value = self.value;
23587 var is_arrow_with_block = value instanceof AST_Arrow
23588 && Array.isArray(value.body)
23589 && !value.contains_this();
23590 if ((is_arrow_with_block || value instanceof AST_Function) && !value.name) {
23591 return make_node(AST_ConciseMethod, self, {
23592 key: key instanceof AST_Node ? key : make_node(AST_SymbolMethod, self, {
23593 name: key,
23594 }),
23595 value: make_node(AST_Accessor, value, value),
23596 quote: self.quote,
23597 });
23598 }
23599 }
23600 return self;
23601});
23602
23603def_optimize(AST_Destructuring, function(self, compressor) {
23604 if (compressor.option("pure_getters") == true
23605 && compressor.option("unused")
23606 && !self.is_array
23607 && Array.isArray(self.names)
23608 && !is_destructuring_export_decl(compressor)
23609 && !(self.names[self.names.length - 1] instanceof AST_Expansion)) {
23610 var keep = [];
23611 for (var i = 0; i < self.names.length; i++) {
23612 var elem = self.names[i];
23613 if (!(elem instanceof AST_ObjectKeyVal
23614 && typeof elem.key == "string"
23615 && elem.value instanceof AST_SymbolDeclaration
23616 && !should_retain(compressor, elem.value.definition()))) {
23617 keep.push(elem);
23618 }
23619 }
23620 if (keep.length != self.names.length) {
23621 self.names = keep;
23622 }
23623 }
23624 return self;
23625
23626 function is_destructuring_export_decl(compressor) {
23627 var ancestors = [/^VarDef$/, /^(Const|Let|Var)$/, /^Export$/];
23628 for (var a = 0, p = 0, len = ancestors.length; a < len; p++) {
23629 var parent = compressor.parent(p);
23630 if (!parent) return false;
23631 if (a === 0 && parent.TYPE == "Destructuring") continue;
23632 if (!ancestors[a].test(parent.TYPE)) {
23633 return false;
23634 }
23635 a++;
23636 }
23637 return true;
23638 }
23639
23640 function should_retain(compressor, def) {
23641 if (def.references.length) return true;
23642 if (!def.global) return false;
23643 if (compressor.toplevel.vars) {
23644 if (compressor.top_retain) {
23645 return compressor.top_retain(def);
23646 }
23647 return false;
23648 }
23649 return true;
23650 }
23651});
23652
23653/***********************************************************************
23654
23655 A JavaScript tokenizer / parser / beautifier / compressor.
23656 https://github.com/mishoo/UglifyJS2
23657
23658 -------------------------------- (C) ---------------------------------
23659
23660 Author: Mihai Bazon
23661 <mihai.bazon@gmail.com>
23662 http://mihai.bazon.net/blog
23663
23664 Distributed under the BSD license:
23665
23666 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
23667
23668 Redistribution and use in source and binary forms, with or without
23669 modification, are permitted provided that the following conditions
23670 are met:
23671
23672 * Redistributions of source code must retain the above
23673 copyright notice, this list of conditions and the following
23674 disclaimer.
23675
23676 * Redistributions in binary form must reproduce the above
23677 copyright notice, this list of conditions and the following
23678 disclaimer in the documentation and/or other materials
23679 provided with the distribution.
23680
23681 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
23682 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23683 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23684 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
23685 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
23686 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23687 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23688 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23689 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
23690 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
23691 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23692 SUCH DAMAGE.
23693
23694 ***********************************************************************/
23695
23696// a small wrapper around source-map and @jridgewell/source-map
23697function* SourceMap(options) {
23698 options = defaults(options, {
23699 file : null,
23700 root : null,
23701 orig : null,
23702 files: {},
23703 });
23704
23705 var orig_map;
23706 var generator = new sourceMap.SourceMapGenerator({
23707 file : options.file,
23708 sourceRoot : options.root
23709 });
23710
23711 let sourcesContent = {__proto__: null};
23712 let files = options.files;
23713 for (var name in files) if (HOP(files, name)) {
23714 sourcesContent[name] = files[name];
23715 }
23716 if (options.orig) {
23717 // We support both @jridgewell/source-map (which has a sync
23718 // SourceMapConsumer) and source-map (which has an async
23719 // SourceMapConsumer).
23720 orig_map = yield new sourceMap.SourceMapConsumer(options.orig);
23721 if (orig_map.sourcesContent) {
23722 orig_map.sources.forEach(function(source, i) {
23723 var content = orig_map.sourcesContent[i];
23724 if (content) {
23725 sourcesContent[source] = content;
23726 }
23727 });
23728 }
23729 }
23730
23731 function add(source, gen_line, gen_col, orig_line, orig_col, name) {
23732 let generatedPos = { line: gen_line, column: gen_col };
23733
23734 if (orig_map) {
23735 var info = orig_map.originalPositionFor({
23736 line: orig_line,
23737 column: orig_col
23738 });
23739 if (info.source === null) {
23740 generator.addMapping({
23741 generated: generatedPos,
23742 original: null,
23743 source: null,
23744 name: null
23745 });
23746 return;
23747 }
23748 source = info.source;
23749 orig_line = info.line;
23750 orig_col = info.column;
23751 name = info.name || name;
23752 }
23753 generator.addMapping({
23754 generated : generatedPos,
23755 original : { line: orig_line, column: orig_col },
23756 source : source,
23757 name : name
23758 });
23759 generator.setSourceContent(source, sourcesContent[source]);
23760 }
23761
23762 function clean(map) {
23763 const allNull = map.sourcesContent && map.sourcesContent.every(c => c == null);
23764 if (allNull) delete map.sourcesContent;
23765 if (map.file === undefined) delete map.file;
23766 if (map.sourceRoot === undefined) delete map.sourceRoot;
23767 return map;
23768 }
23769
23770 function getDecoded() {
23771 if (!generator.toDecodedMap) return null;
23772 return clean(generator.toDecodedMap());
23773 }
23774
23775 function getEncoded() {
23776 return clean(generator.toJSON());
23777 }
23778
23779 function destroy() {
23780 // @jridgewell/source-map's SourceMapConsumer does not need to be
23781 // manually freed.
23782 if (orig_map && orig_map.destroy) orig_map.destroy();
23783 }
23784
23785 return {
23786 add,
23787 getDecoded,
23788 getEncoded,
23789 destroy,
23790 };
23791}
23792
23793var domprops = [
23794 "$&",
23795 "$'",
23796 "$*",
23797 "$+",
23798 "$1",
23799 "$2",
23800 "$3",
23801 "$4",
23802 "$5",
23803 "$6",
23804 "$7",
23805 "$8",
23806 "$9",
23807 "$_",
23808 "$`",
23809 "$input",
23810 "-moz-animation",
23811 "-moz-animation-delay",
23812 "-moz-animation-direction",
23813 "-moz-animation-duration",
23814 "-moz-animation-fill-mode",
23815 "-moz-animation-iteration-count",
23816 "-moz-animation-name",
23817 "-moz-animation-play-state",
23818 "-moz-animation-timing-function",
23819 "-moz-appearance",
23820 "-moz-backface-visibility",
23821 "-moz-border-end",
23822 "-moz-border-end-color",
23823 "-moz-border-end-style",
23824 "-moz-border-end-width",
23825 "-moz-border-image",
23826 "-moz-border-start",
23827 "-moz-border-start-color",
23828 "-moz-border-start-style",
23829 "-moz-border-start-width",
23830 "-moz-box-align",
23831 "-moz-box-direction",
23832 "-moz-box-flex",
23833 "-moz-box-ordinal-group",
23834 "-moz-box-orient",
23835 "-moz-box-pack",
23836 "-moz-box-sizing",
23837 "-moz-float-edge",
23838 "-moz-font-feature-settings",
23839 "-moz-font-language-override",
23840 "-moz-force-broken-image-icon",
23841 "-moz-hyphens",
23842 "-moz-image-region",
23843 "-moz-margin-end",
23844 "-moz-margin-start",
23845 "-moz-orient",
23846 "-moz-osx-font-smoothing",
23847 "-moz-outline-radius",
23848 "-moz-outline-radius-bottomleft",
23849 "-moz-outline-radius-bottomright",
23850 "-moz-outline-radius-topleft",
23851 "-moz-outline-radius-topright",
23852 "-moz-padding-end",
23853 "-moz-padding-start",
23854 "-moz-perspective",
23855 "-moz-perspective-origin",
23856 "-moz-tab-size",
23857 "-moz-text-size-adjust",
23858 "-moz-transform",
23859 "-moz-transform-origin",
23860 "-moz-transform-style",
23861 "-moz-transition",
23862 "-moz-transition-delay",
23863 "-moz-transition-duration",
23864 "-moz-transition-property",
23865 "-moz-transition-timing-function",
23866 "-moz-user-focus",
23867 "-moz-user-input",
23868 "-moz-user-modify",
23869 "-moz-user-select",
23870 "-moz-window-dragging",
23871 "-webkit-align-content",
23872 "-webkit-align-items",
23873 "-webkit-align-self",
23874 "-webkit-animation",
23875 "-webkit-animation-delay",
23876 "-webkit-animation-direction",
23877 "-webkit-animation-duration",
23878 "-webkit-animation-fill-mode",
23879 "-webkit-animation-iteration-count",
23880 "-webkit-animation-name",
23881 "-webkit-animation-play-state",
23882 "-webkit-animation-timing-function",
23883 "-webkit-appearance",
23884 "-webkit-backface-visibility",
23885 "-webkit-background-clip",
23886 "-webkit-background-origin",
23887 "-webkit-background-size",
23888 "-webkit-border-bottom-left-radius",
23889 "-webkit-border-bottom-right-radius",
23890 "-webkit-border-image",
23891 "-webkit-border-radius",
23892 "-webkit-border-top-left-radius",
23893 "-webkit-border-top-right-radius",
23894 "-webkit-box-align",
23895 "-webkit-box-direction",
23896 "-webkit-box-flex",
23897 "-webkit-box-ordinal-group",
23898 "-webkit-box-orient",
23899 "-webkit-box-pack",
23900 "-webkit-box-shadow",
23901 "-webkit-box-sizing",
23902 "-webkit-clip-path",
23903 "-webkit-filter",
23904 "-webkit-flex",
23905 "-webkit-flex-basis",
23906 "-webkit-flex-direction",
23907 "-webkit-flex-flow",
23908 "-webkit-flex-grow",
23909 "-webkit-flex-shrink",
23910 "-webkit-flex-wrap",
23911 "-webkit-font-feature-settings",
23912 "-webkit-justify-content",
23913 "-webkit-line-clamp",
23914 "-webkit-mask",
23915 "-webkit-mask-clip",
23916 "-webkit-mask-composite",
23917 "-webkit-mask-image",
23918 "-webkit-mask-origin",
23919 "-webkit-mask-position",
23920 "-webkit-mask-position-x",
23921 "-webkit-mask-position-y",
23922 "-webkit-mask-repeat",
23923 "-webkit-mask-size",
23924 "-webkit-order",
23925 "-webkit-perspective",
23926 "-webkit-perspective-origin",
23927 "-webkit-text-fill-color",
23928 "-webkit-text-security",
23929 "-webkit-text-size-adjust",
23930 "-webkit-text-stroke",
23931 "-webkit-text-stroke-color",
23932 "-webkit-text-stroke-width",
23933 "-webkit-transform",
23934 "-webkit-transform-origin",
23935 "-webkit-transform-style",
23936 "-webkit-transition",
23937 "-webkit-transition-delay",
23938 "-webkit-transition-duration",
23939 "-webkit-transition-property",
23940 "-webkit-transition-timing-function",
23941 "-webkit-user-select",
23942 "@@iterator",
23943 "ABORT_ERR",
23944 "ACTIVE",
23945 "ACTIVE_ATTRIBUTES",
23946 "ACTIVE_TEXTURE",
23947 "ACTIVE_UNIFORMS",
23948 "ACTIVE_UNIFORM_BLOCKS",
23949 "ADDITION",
23950 "ALIASED_LINE_WIDTH_RANGE",
23951 "ALIASED_POINT_SIZE_RANGE",
23952 "ALL",
23953 "ALLOW_KEYBOARD_INPUT",
23954 "ALLPASS",
23955 "ALPHA",
23956 "ALPHA_BITS",
23957 "ALREADY_SIGNALED",
23958 "ALT_MASK",
23959 "ALWAYS",
23960 "ANY_SAMPLES_PASSED",
23961 "ANY_SAMPLES_PASSED_CONSERVATIVE",
23962 "ANY_TYPE",
23963 "ANY_UNORDERED_NODE_TYPE",
23964 "ARRAY_BUFFER",
23965 "ARRAY_BUFFER_BINDING",
23966 "ATTACHED_SHADERS",
23967 "ATTRIBUTE_NODE",
23968 "AT_TARGET",
23969 "AbortController",
23970 "AbortSignal",
23971 "AbsoluteOrientationSensor",
23972 "AbstractRange",
23973 "Accelerometer",
23974 "AddSearchProvider",
23975 "AggregateError",
23976 "AnalyserNode",
23977 "Animation",
23978 "AnimationEffect",
23979 "AnimationEvent",
23980 "AnimationPlaybackEvent",
23981 "AnimationTimeline",
23982 "AnonXMLHttpRequest",
23983 "Any",
23984 "AnyPermissions",
23985 "ApplicationCache",
23986 "ApplicationCacheErrorEvent",
23987 "Array",
23988 "ArrayBuffer",
23989 "ArrayType",
23990 "AsyncDisposableStack",
23991 "Atomics",
23992 "Attr",
23993 "Audio",
23994 "AudioBuffer",
23995 "AudioBufferSourceNode",
23996 "AudioContext",
23997 "AudioData",
23998 "AudioDecoder",
23999 "AudioDestinationNode",
24000 "AudioEncoder",
24001 "AudioListener",
24002 "AudioNode",
24003 "AudioParam",
24004 "AudioParamMap",
24005 "AudioProcessingEvent",
24006 "AudioScheduledSourceNode",
24007 "AudioSinkInfo",
24008 "AudioStreamTrack",
24009 "AudioWorklet",
24010 "AudioWorkletNode",
24011 "AuthenticatorAssertionResponse",
24012 "AuthenticatorAttestationResponse",
24013 "AuthenticatorResponse",
24014 "AutocompleteErrorEvent",
24015 "BACK",
24016 "BAD_BOUNDARYPOINTS_ERR",
24017 "BAD_REQUEST",
24018 "BANDPASS",
24019 "BLEND",
24020 "BLEND_COLOR",
24021 "BLEND_DST_ALPHA",
24022 "BLEND_DST_RGB",
24023 "BLEND_EQUATION",
24024 "BLEND_EQUATION_ALPHA",
24025 "BLEND_EQUATION_RGB",
24026 "BLEND_SRC_ALPHA",
24027 "BLEND_SRC_RGB",
24028 "BLUE",
24029 "BLUE_BITS",
24030 "BLUR",
24031 "BOOL",
24032 "BOOLEAN_TYPE",
24033 "BOOL_VEC2",
24034 "BOOL_VEC3",
24035 "BOOL_VEC4",
24036 "BOTH",
24037 "BROWSER_DEFAULT_WEBGL",
24038 "BUBBLING_PHASE",
24039 "BUFFER_SIZE",
24040 "BUFFER_USAGE",
24041 "BYTE",
24042 "BYTES_PER_ELEMENT",
24043 "BackgroundFetchManager",
24044 "BackgroundFetchRecord",
24045 "BackgroundFetchRegistration",
24046 "BarProp",
24047 "BarcodeDetector",
24048 "BaseAudioContext",
24049 "BaseHref",
24050 "BatteryManager",
24051 "BeforeInstallPromptEvent",
24052 "BeforeLoadEvent",
24053 "BeforeUnloadEvent",
24054 "BigInt",
24055 "BigInt64Array",
24056 "BigUint64Array",
24057 "BiquadFilterNode",
24058 "Blob",
24059 "BlobEvent",
24060 "Bluetooth",
24061 "BluetoothCharacteristicProperties",
24062 "BluetoothDevice",
24063 "BluetoothRemoteGATTCharacteristic",
24064 "BluetoothRemoteGATTDescriptor",
24065 "BluetoothRemoteGATTServer",
24066 "BluetoothRemoteGATTService",
24067 "BluetoothUUID",
24068 "Boolean",
24069 "BroadcastChannel",
24070 "BrowserCaptureMediaStreamTrack",
24071 "BrowserInfo",
24072 "ByteLengthQueuingStrategy",
24073 "CAPTURING_PHASE",
24074 "CCW",
24075 "CDATASection",
24076 "CDATA_SECTION_NODE",
24077 "CHANGE",
24078 "CHARSET_RULE",
24079 "CHECKING",
24080 "CLAMP_TO_EDGE",
24081 "CLICK",
24082 "CLOSED",
24083 "CLOSING",
24084 "COLOR",
24085 "COLOR_ATTACHMENT0",
24086 "COLOR_ATTACHMENT1",
24087 "COLOR_ATTACHMENT10",
24088 "COLOR_ATTACHMENT11",
24089 "COLOR_ATTACHMENT12",
24090 "COLOR_ATTACHMENT13",
24091 "COLOR_ATTACHMENT14",
24092 "COLOR_ATTACHMENT15",
24093 "COLOR_ATTACHMENT2",
24094 "COLOR_ATTACHMENT3",
24095 "COLOR_ATTACHMENT4",
24096 "COLOR_ATTACHMENT5",
24097 "COLOR_ATTACHMENT6",
24098 "COLOR_ATTACHMENT7",
24099 "COLOR_ATTACHMENT8",
24100 "COLOR_ATTACHMENT9",
24101 "COLOR_BUFFER_BIT",
24102 "COLOR_CLEAR_VALUE",
24103 "COLOR_WRITEMASK",
24104 "COMMENT_NODE",
24105 "COMPARE_REF_TO_TEXTURE",
24106 "COMPILE_STATUS",
24107 "COMPLETION_STATUS_KHR",
24108 "COMPRESSED_RGBA_S3TC_DXT1_EXT",
24109 "COMPRESSED_RGBA_S3TC_DXT3_EXT",
24110 "COMPRESSED_RGBA_S3TC_DXT5_EXT",
24111 "COMPRESSED_RGB_S3TC_DXT1_EXT",
24112 "COMPRESSED_TEXTURE_FORMATS",
24113 "COMPUTE",
24114 "CONDITION_SATISFIED",
24115 "CONFIGURATION_UNSUPPORTED",
24116 "CONNECTING",
24117 "CONSTANT_ALPHA",
24118 "CONSTANT_COLOR",
24119 "CONSTRAINT_ERR",
24120 "CONTEXT_LOST_WEBGL",
24121 "CONTROL_MASK",
24122 "COPY_DST",
24123 "COPY_READ_BUFFER",
24124 "COPY_READ_BUFFER_BINDING",
24125 "COPY_SRC",
24126 "COPY_WRITE_BUFFER",
24127 "COPY_WRITE_BUFFER_BINDING",
24128 "COUNTER_STYLE_RULE",
24129 "CSPViolationReportBody",
24130 "CSS",
24131 "CSS2Properties",
24132 "CSSAnimation",
24133 "CSSCharsetRule",
24134 "CSSConditionRule",
24135 "CSSContainerRule",
24136 "CSSCounterStyleRule",
24137 "CSSFontFaceRule",
24138 "CSSFontFeatureValuesRule",
24139 "CSSFontPaletteValuesRule",
24140 "CSSFunctionDeclarations",
24141 "CSSFunctionDescriptors",
24142 "CSSFunctionRule",
24143 "CSSGroupingRule",
24144 "CSSImageValue",
24145 "CSSImportRule",
24146 "CSSKeyframeRule",
24147 "CSSKeyframesRule",
24148 "CSSKeywordValue",
24149 "CSSLayerBlockRule",
24150 "CSSLayerStatementRule",
24151 "CSSMarginRule",
24152 "CSSMathClamp",
24153 "CSSMathInvert",
24154 "CSSMathMax",
24155 "CSSMathMin",
24156 "CSSMathNegate",
24157 "CSSMathProduct",
24158 "CSSMathSum",
24159 "CSSMathValue",
24160 "CSSMatrixComponent",
24161 "CSSMediaRule",
24162 "CSSMozDocumentRule",
24163 "CSSNameSpaceRule",
24164 "CSSNamespaceRule",
24165 "CSSNestedDeclarations",
24166 "CSSNumericArray",
24167 "CSSNumericValue",
24168 "CSSPageDescriptors",
24169 "CSSPageRule",
24170 "CSSPerspective",
24171 "CSSPositionTryDescriptors",
24172 "CSSPositionTryRule",
24173 "CSSPositionValue",
24174 "CSSPrimitiveValue",
24175 "CSSPropertyRule",
24176 "CSSRotate",
24177 "CSSRule",
24178 "CSSRuleList",
24179 "CSSScale",
24180 "CSSScopeRule",
24181 "CSSSkew",
24182 "CSSSkewX",
24183 "CSSSkewY",
24184 "CSSStartingStyleRule",
24185 "CSSStyleDeclaration",
24186 "CSSStyleProperties",
24187 "CSSStyleRule",
24188 "CSSStyleSheet",
24189 "CSSStyleValue",
24190 "CSSSupportsRule",
24191 "CSSTransformComponent",
24192 "CSSTransformValue",
24193 "CSSTransition",
24194 "CSSTranslate",
24195 "CSSUnitValue",
24196 "CSSUnknownRule",
24197 "CSSUnparsedValue",
24198 "CSSValue",
24199 "CSSValueList",
24200 "CSSVariableReferenceValue",
24201 "CSSVariablesDeclaration",
24202 "CSSVariablesRule",
24203 "CSSViewTransitionRule",
24204 "CSSViewportRule",
24205 "CSS_ATTR",
24206 "CSS_CM",
24207 "CSS_COUNTER",
24208 "CSS_CUSTOM",
24209 "CSS_DEG",
24210 "CSS_DIMENSION",
24211 "CSS_EMS",
24212 "CSS_EXS",
24213 "CSS_FILTER_BLUR",
24214 "CSS_FILTER_BRIGHTNESS",
24215 "CSS_FILTER_CONTRAST",
24216 "CSS_FILTER_CUSTOM",
24217 "CSS_FILTER_DROP_SHADOW",
24218 "CSS_FILTER_GRAYSCALE",
24219 "CSS_FILTER_HUE_ROTATE",
24220 "CSS_FILTER_INVERT",
24221 "CSS_FILTER_OPACITY",
24222 "CSS_FILTER_REFERENCE",
24223 "CSS_FILTER_SATURATE",
24224 "CSS_FILTER_SEPIA",
24225 "CSS_GRAD",
24226 "CSS_HZ",
24227 "CSS_IDENT",
24228 "CSS_IN",
24229 "CSS_INHERIT",
24230 "CSS_KHZ",
24231 "CSS_MATRIX",
24232 "CSS_MATRIX3D",
24233 "CSS_MM",
24234 "CSS_MS",
24235 "CSS_NUMBER",
24236 "CSS_PC",
24237 "CSS_PERCENTAGE",
24238 "CSS_PERSPECTIVE",
24239 "CSS_PRIMITIVE_VALUE",
24240 "CSS_PT",
24241 "CSS_PX",
24242 "CSS_RAD",
24243 "CSS_RECT",
24244 "CSS_RGBCOLOR",
24245 "CSS_ROTATE",
24246 "CSS_ROTATE3D",
24247 "CSS_ROTATEX",
24248 "CSS_ROTATEY",
24249 "CSS_ROTATEZ",
24250 "CSS_S",
24251 "CSS_SCALE",
24252 "CSS_SCALE3D",
24253 "CSS_SCALEX",
24254 "CSS_SCALEY",
24255 "CSS_SCALEZ",
24256 "CSS_SKEW",
24257 "CSS_SKEWX",
24258 "CSS_SKEWY",
24259 "CSS_STRING",
24260 "CSS_TRANSLATE",
24261 "CSS_TRANSLATE3D",
24262 "CSS_TRANSLATEX",
24263 "CSS_TRANSLATEY",
24264 "CSS_TRANSLATEZ",
24265 "CSS_UNKNOWN",
24266 "CSS_URI",
24267 "CSS_VALUE_LIST",
24268 "CSS_VH",
24269 "CSS_VMAX",
24270 "CSS_VMIN",
24271 "CSS_VW",
24272 "CULL_FACE",
24273 "CULL_FACE_MODE",
24274 "CURRENT_PROGRAM",
24275 "CURRENT_QUERY",
24276 "CURRENT_VERTEX_ATTRIB",
24277 "CUSTOM",
24278 "CW",
24279 "Cache",
24280 "CacheStorage",
24281 "CanvasCaptureMediaStream",
24282 "CanvasCaptureMediaStreamTrack",
24283 "CanvasGradient",
24284 "CanvasPattern",
24285 "CanvasRenderingContext2D",
24286 "CaptureController",
24287 "CaretPosition",
24288 "ChannelMergerNode",
24289 "ChannelSplitterNode",
24290 "ChapterInformation",
24291 "CharacterBoundsUpdateEvent",
24292 "CharacterData",
24293 "ClientRect",
24294 "ClientRectList",
24295 "Clipboard",
24296 "ClipboardEvent",
24297 "ClipboardItem",
24298 "CloseEvent",
24299 "CloseWatcher",
24300 "Collator",
24301 "ColorArray",
24302 "ColorValue",
24303 "CommandEvent",
24304 "Comment",
24305 "CompileError",
24306 "CompositionEvent",
24307 "CompressionStream",
24308 "Console",
24309 "ConstantSourceNode",
24310 "ContentVisibilityAutoStateChangeEvent",
24311 "ContextFilter",
24312 "ContextType",
24313 "Controllers",
24314 "ConvolverNode",
24315 "CookieChangeEvent",
24316 "CookieStore",
24317 "CookieStoreManager",
24318 "CountQueuingStrategy",
24319 "Counter",
24320 "CreateMonitor",
24321 "CreateType",
24322 "Credential",
24323 "CredentialsContainer",
24324 "CropTarget",
24325 "Crypto",
24326 "CryptoKey",
24327 "CustomElementRegistry",
24328 "CustomEvent",
24329 "CustomStateSet",
24330 "DATABASE_ERR",
24331 "DATA_CLONE_ERR",
24332 "DATA_ERR",
24333 "DBLCLICK",
24334 "DECR",
24335 "DECR_WRAP",
24336 "DELETE_STATUS",
24337 "DEPTH",
24338 "DEPTH24_STENCIL8",
24339 "DEPTH32F_STENCIL8",
24340 "DEPTH_ATTACHMENT",
24341 "DEPTH_BITS",
24342 "DEPTH_BUFFER_BIT",
24343 "DEPTH_CLEAR_VALUE",
24344 "DEPTH_COMPONENT",
24345 "DEPTH_COMPONENT16",
24346 "DEPTH_COMPONENT24",
24347 "DEPTH_COMPONENT32F",
24348 "DEPTH_FUNC",
24349 "DEPTH_RANGE",
24350 "DEPTH_STENCIL",
24351 "DEPTH_STENCIL_ATTACHMENT",
24352 "DEPTH_TEST",
24353 "DEPTH_WRITEMASK",
24354 "DEVICE_INELIGIBLE",
24355 "DIRECTION_DOWN",
24356 "DIRECTION_LEFT",
24357 "DIRECTION_RIGHT",
24358 "DIRECTION_UP",
24359 "DISABLED",
24360 "DISPATCH_REQUEST_ERR",
24361 "DITHER",
24362 "DOCUMENT_FRAGMENT_NODE",
24363 "DOCUMENT_NODE",
24364 "DOCUMENT_POSITION_CONTAINED_BY",
24365 "DOCUMENT_POSITION_CONTAINS",
24366 "DOCUMENT_POSITION_DISCONNECTED",
24367 "DOCUMENT_POSITION_FOLLOWING",
24368 "DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC",
24369 "DOCUMENT_POSITION_PRECEDING",
24370 "DOCUMENT_TYPE_NODE",
24371 "DOMCursor",
24372 "DOMError",
24373 "DOMException",
24374 "DOMImplementation",
24375 "DOMImplementationLS",
24376 "DOMMatrix",
24377 "DOMMatrixReadOnly",
24378 "DOMParser",
24379 "DOMPoint",
24380 "DOMPointReadOnly",
24381 "DOMQuad",
24382 "DOMRect",
24383 "DOMRectList",
24384 "DOMRectReadOnly",
24385 "DOMRequest",
24386 "DOMSTRING_SIZE_ERR",
24387 "DOMSettableTokenList",
24388 "DOMStringList",
24389 "DOMStringMap",
24390 "DOMTokenList",
24391 "DOMTransactionEvent",
24392 "DOM_DELTA_LINE",
24393 "DOM_DELTA_PAGE",
24394 "DOM_DELTA_PIXEL",
24395 "DOM_INPUT_METHOD_DROP",
24396 "DOM_INPUT_METHOD_HANDWRITING",
24397 "DOM_INPUT_METHOD_IME",
24398 "DOM_INPUT_METHOD_KEYBOARD",
24399 "DOM_INPUT_METHOD_MULTIMODAL",
24400 "DOM_INPUT_METHOD_OPTION",
24401 "DOM_INPUT_METHOD_PASTE",
24402 "DOM_INPUT_METHOD_SCRIPT",
24403 "DOM_INPUT_METHOD_UNKNOWN",
24404 "DOM_INPUT_METHOD_VOICE",
24405 "DOM_KEY_LOCATION_JOYSTICK",
24406 "DOM_KEY_LOCATION_LEFT",
24407 "DOM_KEY_LOCATION_MOBILE",
24408 "DOM_KEY_LOCATION_NUMPAD",
24409 "DOM_KEY_LOCATION_RIGHT",
24410 "DOM_KEY_LOCATION_STANDARD",
24411 "DOM_VK_0",
24412 "DOM_VK_1",
24413 "DOM_VK_2",
24414 "DOM_VK_3",
24415 "DOM_VK_4",
24416 "DOM_VK_5",
24417 "DOM_VK_6",
24418 "DOM_VK_7",
24419 "DOM_VK_8",
24420 "DOM_VK_9",
24421 "DOM_VK_A",
24422 "DOM_VK_ACCEPT",
24423 "DOM_VK_ADD",
24424 "DOM_VK_ALT",
24425 "DOM_VK_ALTGR",
24426 "DOM_VK_AMPERSAND",
24427 "DOM_VK_ASTERISK",
24428 "DOM_VK_AT",
24429 "DOM_VK_ATTN",
24430 "DOM_VK_B",
24431 "DOM_VK_BACKSPACE",
24432 "DOM_VK_BACK_QUOTE",
24433 "DOM_VK_BACK_SLASH",
24434 "DOM_VK_BACK_SPACE",
24435 "DOM_VK_C",
24436 "DOM_VK_CANCEL",
24437 "DOM_VK_CAPS_LOCK",
24438 "DOM_VK_CIRCUMFLEX",
24439 "DOM_VK_CLEAR",
24440 "DOM_VK_CLOSE_BRACKET",
24441 "DOM_VK_CLOSE_CURLY_BRACKET",
24442 "DOM_VK_CLOSE_PAREN",
24443 "DOM_VK_COLON",
24444 "DOM_VK_COMMA",
24445 "DOM_VK_CONTEXT_MENU",
24446 "DOM_VK_CONTROL",
24447 "DOM_VK_CONVERT",
24448 "DOM_VK_CRSEL",
24449 "DOM_VK_CTRL",
24450 "DOM_VK_D",
24451 "DOM_VK_DECIMAL",
24452 "DOM_VK_DELETE",
24453 "DOM_VK_DIVIDE",
24454 "DOM_VK_DOLLAR",
24455 "DOM_VK_DOUBLE_QUOTE",
24456 "DOM_VK_DOWN",
24457 "DOM_VK_E",
24458 "DOM_VK_EISU",
24459 "DOM_VK_END",
24460 "DOM_VK_ENTER",
24461 "DOM_VK_EQUALS",
24462 "DOM_VK_EREOF",
24463 "DOM_VK_ESCAPE",
24464 "DOM_VK_EXCLAMATION",
24465 "DOM_VK_EXECUTE",
24466 "DOM_VK_EXSEL",
24467 "DOM_VK_F",
24468 "DOM_VK_F1",
24469 "DOM_VK_F10",
24470 "DOM_VK_F11",
24471 "DOM_VK_F12",
24472 "DOM_VK_F13",
24473 "DOM_VK_F14",
24474 "DOM_VK_F15",
24475 "DOM_VK_F16",
24476 "DOM_VK_F17",
24477 "DOM_VK_F18",
24478 "DOM_VK_F19",
24479 "DOM_VK_F2",
24480 "DOM_VK_F20",
24481 "DOM_VK_F21",
24482 "DOM_VK_F22",
24483 "DOM_VK_F23",
24484 "DOM_VK_F24",
24485 "DOM_VK_F25",
24486 "DOM_VK_F26",
24487 "DOM_VK_F27",
24488 "DOM_VK_F28",
24489 "DOM_VK_F29",
24490 "DOM_VK_F3",
24491 "DOM_VK_F30",
24492 "DOM_VK_F31",
24493 "DOM_VK_F32",
24494 "DOM_VK_F33",
24495 "DOM_VK_F34",
24496 "DOM_VK_F35",
24497 "DOM_VK_F36",
24498 "DOM_VK_F4",
24499 "DOM_VK_F5",
24500 "DOM_VK_F6",
24501 "DOM_VK_F7",
24502 "DOM_VK_F8",
24503 "DOM_VK_F9",
24504 "DOM_VK_FINAL",
24505 "DOM_VK_FRONT",
24506 "DOM_VK_G",
24507 "DOM_VK_GREATER_THAN",
24508 "DOM_VK_H",
24509 "DOM_VK_HANGUL",
24510 "DOM_VK_HANJA",
24511 "DOM_VK_HASH",
24512 "DOM_VK_HELP",
24513 "DOM_VK_HK_TOGGLE",
24514 "DOM_VK_HOME",
24515 "DOM_VK_HYPHEN_MINUS",
24516 "DOM_VK_I",
24517 "DOM_VK_INSERT",
24518 "DOM_VK_J",
24519 "DOM_VK_JUNJA",
24520 "DOM_VK_K",
24521 "DOM_VK_KANA",
24522 "DOM_VK_KANJI",
24523 "DOM_VK_L",
24524 "DOM_VK_LEFT",
24525 "DOM_VK_LEFT_TAB",
24526 "DOM_VK_LESS_THAN",
24527 "DOM_VK_M",
24528 "DOM_VK_META",
24529 "DOM_VK_MODECHANGE",
24530 "DOM_VK_MULTIPLY",
24531 "DOM_VK_N",
24532 "DOM_VK_NONCONVERT",
24533 "DOM_VK_NUMPAD0",
24534 "DOM_VK_NUMPAD1",
24535 "DOM_VK_NUMPAD2",
24536 "DOM_VK_NUMPAD3",
24537 "DOM_VK_NUMPAD4",
24538 "DOM_VK_NUMPAD5",
24539 "DOM_VK_NUMPAD6",
24540 "DOM_VK_NUMPAD7",
24541 "DOM_VK_NUMPAD8",
24542 "DOM_VK_NUMPAD9",
24543 "DOM_VK_NUM_LOCK",
24544 "DOM_VK_O",
24545 "DOM_VK_OEM_1",
24546 "DOM_VK_OEM_102",
24547 "DOM_VK_OEM_2",
24548 "DOM_VK_OEM_3",
24549 "DOM_VK_OEM_4",
24550 "DOM_VK_OEM_5",
24551 "DOM_VK_OEM_6",
24552 "DOM_VK_OEM_7",
24553 "DOM_VK_OEM_8",
24554 "DOM_VK_OEM_COMMA",
24555 "DOM_VK_OEM_MINUS",
24556 "DOM_VK_OEM_PERIOD",
24557 "DOM_VK_OEM_PLUS",
24558 "DOM_VK_OPEN_BRACKET",
24559 "DOM_VK_OPEN_CURLY_BRACKET",
24560 "DOM_VK_OPEN_PAREN",
24561 "DOM_VK_P",
24562 "DOM_VK_PA1",
24563 "DOM_VK_PAGEDOWN",
24564 "DOM_VK_PAGEUP",
24565 "DOM_VK_PAGE_DOWN",
24566 "DOM_VK_PAGE_UP",
24567 "DOM_VK_PAUSE",
24568 "DOM_VK_PERCENT",
24569 "DOM_VK_PERIOD",
24570 "DOM_VK_PIPE",
24571 "DOM_VK_PLAY",
24572 "DOM_VK_PLUS",
24573 "DOM_VK_PRINT",
24574 "DOM_VK_PRINTSCREEN",
24575 "DOM_VK_PROCESSKEY",
24576 "DOM_VK_PROPERITES",
24577 "DOM_VK_Q",
24578 "DOM_VK_QUESTION_MARK",
24579 "DOM_VK_QUOTE",
24580 "DOM_VK_R",
24581 "DOM_VK_REDO",
24582 "DOM_VK_RETURN",
24583 "DOM_VK_RIGHT",
24584 "DOM_VK_S",
24585 "DOM_VK_SCROLL_LOCK",
24586 "DOM_VK_SELECT",
24587 "DOM_VK_SEMICOLON",
24588 "DOM_VK_SEPARATOR",
24589 "DOM_VK_SHIFT",
24590 "DOM_VK_SLASH",
24591 "DOM_VK_SLEEP",
24592 "DOM_VK_SPACE",
24593 "DOM_VK_SUBTRACT",
24594 "DOM_VK_T",
24595 "DOM_VK_TAB",
24596 "DOM_VK_TILDE",
24597 "DOM_VK_U",
24598 "DOM_VK_UNDERSCORE",
24599 "DOM_VK_UNDO",
24600 "DOM_VK_UNICODE",
24601 "DOM_VK_UP",
24602 "DOM_VK_V",
24603 "DOM_VK_VOLUME_DOWN",
24604 "DOM_VK_VOLUME_MUTE",
24605 "DOM_VK_VOLUME_UP",
24606 "DOM_VK_W",
24607 "DOM_VK_WIN",
24608 "DOM_VK_WINDOW",
24609 "DOM_VK_WIN_ICO_00",
24610 "DOM_VK_WIN_ICO_CLEAR",
24611 "DOM_VK_WIN_ICO_HELP",
24612 "DOM_VK_WIN_OEM_ATTN",
24613 "DOM_VK_WIN_OEM_AUTO",
24614 "DOM_VK_WIN_OEM_BACKTAB",
24615 "DOM_VK_WIN_OEM_CLEAR",
24616 "DOM_VK_WIN_OEM_COPY",
24617 "DOM_VK_WIN_OEM_CUSEL",
24618 "DOM_VK_WIN_OEM_ENLW",
24619 "DOM_VK_WIN_OEM_FINISH",
24620 "DOM_VK_WIN_OEM_FJ_JISHO",
24621 "DOM_VK_WIN_OEM_FJ_LOYA",
24622 "DOM_VK_WIN_OEM_FJ_MASSHOU",
24623 "DOM_VK_WIN_OEM_FJ_ROYA",
24624 "DOM_VK_WIN_OEM_FJ_TOUROKU",
24625 "DOM_VK_WIN_OEM_JUMP",
24626 "DOM_VK_WIN_OEM_PA1",
24627 "DOM_VK_WIN_OEM_PA2",
24628 "DOM_VK_WIN_OEM_PA3",
24629 "DOM_VK_WIN_OEM_RESET",
24630 "DOM_VK_WIN_OEM_WSCTRL",
24631 "DOM_VK_X",
24632 "DOM_VK_XF86XK_ADD_FAVORITE",
24633 "DOM_VK_XF86XK_APPLICATION_LEFT",
24634 "DOM_VK_XF86XK_APPLICATION_RIGHT",
24635 "DOM_VK_XF86XK_AUDIO_CYCLE_TRACK",
24636 "DOM_VK_XF86XK_AUDIO_FORWARD",
24637 "DOM_VK_XF86XK_AUDIO_LOWER_VOLUME",
24638 "DOM_VK_XF86XK_AUDIO_MEDIA",
24639 "DOM_VK_XF86XK_AUDIO_MUTE",
24640 "DOM_VK_XF86XK_AUDIO_NEXT",
24641 "DOM_VK_XF86XK_AUDIO_PAUSE",
24642 "DOM_VK_XF86XK_AUDIO_PLAY",
24643 "DOM_VK_XF86XK_AUDIO_PREV",
24644 "DOM_VK_XF86XK_AUDIO_RAISE_VOLUME",
24645 "DOM_VK_XF86XK_AUDIO_RANDOM_PLAY",
24646 "DOM_VK_XF86XK_AUDIO_RECORD",
24647 "DOM_VK_XF86XK_AUDIO_REPEAT",
24648 "DOM_VK_XF86XK_AUDIO_REWIND",
24649 "DOM_VK_XF86XK_AUDIO_STOP",
24650 "DOM_VK_XF86XK_AWAY",
24651 "DOM_VK_XF86XK_BACK",
24652 "DOM_VK_XF86XK_BACK_FORWARD",
24653 "DOM_VK_XF86XK_BATTERY",
24654 "DOM_VK_XF86XK_BLUE",
24655 "DOM_VK_XF86XK_BLUETOOTH",
24656 "DOM_VK_XF86XK_BOOK",
24657 "DOM_VK_XF86XK_BRIGHTNESS_ADJUST",
24658 "DOM_VK_XF86XK_CALCULATOR",
24659 "DOM_VK_XF86XK_CALENDAR",
24660 "DOM_VK_XF86XK_CD",
24661 "DOM_VK_XF86XK_CLOSE",
24662 "DOM_VK_XF86XK_COMMUNITY",
24663 "DOM_VK_XF86XK_CONTRAST_ADJUST",
24664 "DOM_VK_XF86XK_COPY",
24665 "DOM_VK_XF86XK_CUT",
24666 "DOM_VK_XF86XK_CYCLE_ANGLE",
24667 "DOM_VK_XF86XK_DISPLAY",
24668 "DOM_VK_XF86XK_DOCUMENTS",
24669 "DOM_VK_XF86XK_DOS",
24670 "DOM_VK_XF86XK_EJECT",
24671 "DOM_VK_XF86XK_EXCEL",
24672 "DOM_VK_XF86XK_EXPLORER",
24673 "DOM_VK_XF86XK_FAVORITES",
24674 "DOM_VK_XF86XK_FINANCE",
24675 "DOM_VK_XF86XK_FORWARD",
24676 "DOM_VK_XF86XK_FRAME_BACK",
24677 "DOM_VK_XF86XK_FRAME_FORWARD",
24678 "DOM_VK_XF86XK_GAME",
24679 "DOM_VK_XF86XK_GO",
24680 "DOM_VK_XF86XK_GREEN",
24681 "DOM_VK_XF86XK_HIBERNATE",
24682 "DOM_VK_XF86XK_HISTORY",
24683 "DOM_VK_XF86XK_HOME_PAGE",
24684 "DOM_VK_XF86XK_HOT_LINKS",
24685 "DOM_VK_XF86XK_I_TOUCH",
24686 "DOM_VK_XF86XK_KBD_BRIGHTNESS_DOWN",
24687 "DOM_VK_XF86XK_KBD_BRIGHTNESS_UP",
24688 "DOM_VK_XF86XK_KBD_LIGHT_ON_OFF",
24689 "DOM_VK_XF86XK_LAUNCH0",
24690 "DOM_VK_XF86XK_LAUNCH1",
24691 "DOM_VK_XF86XK_LAUNCH2",
24692 "DOM_VK_XF86XK_LAUNCH3",
24693 "DOM_VK_XF86XK_LAUNCH4",
24694 "DOM_VK_XF86XK_LAUNCH5",
24695 "DOM_VK_XF86XK_LAUNCH6",
24696 "DOM_VK_XF86XK_LAUNCH7",
24697 "DOM_VK_XF86XK_LAUNCH8",
24698 "DOM_VK_XF86XK_LAUNCH9",
24699 "DOM_VK_XF86XK_LAUNCH_A",
24700 "DOM_VK_XF86XK_LAUNCH_B",
24701 "DOM_VK_XF86XK_LAUNCH_C",
24702 "DOM_VK_XF86XK_LAUNCH_D",
24703 "DOM_VK_XF86XK_LAUNCH_E",
24704 "DOM_VK_XF86XK_LAUNCH_F",
24705 "DOM_VK_XF86XK_LIGHT_BULB",
24706 "DOM_VK_XF86XK_LOG_OFF",
24707 "DOM_VK_XF86XK_MAIL",
24708 "DOM_VK_XF86XK_MAIL_FORWARD",
24709 "DOM_VK_XF86XK_MARKET",
24710 "DOM_VK_XF86XK_MEETING",
24711 "DOM_VK_XF86XK_MEMO",
24712 "DOM_VK_XF86XK_MENU_KB",
24713 "DOM_VK_XF86XK_MENU_PB",
24714 "DOM_VK_XF86XK_MESSENGER",
24715 "DOM_VK_XF86XK_MON_BRIGHTNESS_DOWN",
24716 "DOM_VK_XF86XK_MON_BRIGHTNESS_UP",
24717 "DOM_VK_XF86XK_MUSIC",
24718 "DOM_VK_XF86XK_MY_COMPUTER",
24719 "DOM_VK_XF86XK_MY_SITES",
24720 "DOM_VK_XF86XK_NEW",
24721 "DOM_VK_XF86XK_NEWS",
24722 "DOM_VK_XF86XK_OFFICE_HOME",
24723 "DOM_VK_XF86XK_OPEN",
24724 "DOM_VK_XF86XK_OPEN_URL",
24725 "DOM_VK_XF86XK_OPTION",
24726 "DOM_VK_XF86XK_PASTE",
24727 "DOM_VK_XF86XK_PHONE",
24728 "DOM_VK_XF86XK_PICTURES",
24729 "DOM_VK_XF86XK_POWER_DOWN",
24730 "DOM_VK_XF86XK_POWER_OFF",
24731 "DOM_VK_XF86XK_RED",
24732 "DOM_VK_XF86XK_REFRESH",
24733 "DOM_VK_XF86XK_RELOAD",
24734 "DOM_VK_XF86XK_REPLY",
24735 "DOM_VK_XF86XK_ROCKER_DOWN",
24736 "DOM_VK_XF86XK_ROCKER_ENTER",
24737 "DOM_VK_XF86XK_ROCKER_UP",
24738 "DOM_VK_XF86XK_ROTATE_WINDOWS",
24739 "DOM_VK_XF86XK_ROTATION_KB",
24740 "DOM_VK_XF86XK_ROTATION_PB",
24741 "DOM_VK_XF86XK_SAVE",
24742 "DOM_VK_XF86XK_SCREEN_SAVER",
24743 "DOM_VK_XF86XK_SCROLL_CLICK",
24744 "DOM_VK_XF86XK_SCROLL_DOWN",
24745 "DOM_VK_XF86XK_SCROLL_UP",
24746 "DOM_VK_XF86XK_SEARCH",
24747 "DOM_VK_XF86XK_SEND",
24748 "DOM_VK_XF86XK_SHOP",
24749 "DOM_VK_XF86XK_SPELL",
24750 "DOM_VK_XF86XK_SPLIT_SCREEN",
24751 "DOM_VK_XF86XK_STANDBY",
24752 "DOM_VK_XF86XK_START",
24753 "DOM_VK_XF86XK_STOP",
24754 "DOM_VK_XF86XK_SUBTITLE",
24755 "DOM_VK_XF86XK_SUPPORT",
24756 "DOM_VK_XF86XK_SUSPEND",
24757 "DOM_VK_XF86XK_TASK_PANE",
24758 "DOM_VK_XF86XK_TERMINAL",
24759 "DOM_VK_XF86XK_TIME",
24760 "DOM_VK_XF86XK_TOOLS",
24761 "DOM_VK_XF86XK_TOP_MENU",
24762 "DOM_VK_XF86XK_TO_DO_LIST",
24763 "DOM_VK_XF86XK_TRAVEL",
24764 "DOM_VK_XF86XK_USER1KB",
24765 "DOM_VK_XF86XK_USER2KB",
24766 "DOM_VK_XF86XK_USER_PB",
24767 "DOM_VK_XF86XK_UWB",
24768 "DOM_VK_XF86XK_VENDOR_HOME",
24769 "DOM_VK_XF86XK_VIDEO",
24770 "DOM_VK_XF86XK_VIEW",
24771 "DOM_VK_XF86XK_WAKE_UP",
24772 "DOM_VK_XF86XK_WEB_CAM",
24773 "DOM_VK_XF86XK_WHEEL_BUTTON",
24774 "DOM_VK_XF86XK_WLAN",
24775 "DOM_VK_XF86XK_WORD",
24776 "DOM_VK_XF86XK_WWW",
24777 "DOM_VK_XF86XK_XFER",
24778 "DOM_VK_XF86XK_YELLOW",
24779 "DOM_VK_XF86XK_ZOOM_IN",
24780 "DOM_VK_XF86XK_ZOOM_OUT",
24781 "DOM_VK_Y",
24782 "DOM_VK_Z",
24783 "DOM_VK_ZOOM",
24784 "DONE",
24785 "DONT_CARE",
24786 "DOWNLOADING",
24787 "DRAGDROP",
24788 "DRAW_BUFFER0",
24789 "DRAW_BUFFER1",
24790 "DRAW_BUFFER10",
24791 "DRAW_BUFFER11",
24792 "DRAW_BUFFER12",
24793 "DRAW_BUFFER13",
24794 "DRAW_BUFFER14",
24795 "DRAW_BUFFER15",
24796 "DRAW_BUFFER2",
24797 "DRAW_BUFFER3",
24798 "DRAW_BUFFER4",
24799 "DRAW_BUFFER5",
24800 "DRAW_BUFFER6",
24801 "DRAW_BUFFER7",
24802 "DRAW_BUFFER8",
24803 "DRAW_BUFFER9",
24804 "DRAW_FRAMEBUFFER",
24805 "DRAW_FRAMEBUFFER_BINDING",
24806 "DST_ALPHA",
24807 "DST_COLOR",
24808 "DYNAMIC_COPY",
24809 "DYNAMIC_DRAW",
24810 "DYNAMIC_READ",
24811 "DataChannel",
24812 "DataTransfer",
24813 "DataTransferItem",
24814 "DataTransferItemList",
24815 "DataView",
24816 "Date",
24817 "DateTimeFormat",
24818 "DecompressionStream",
24819 "DelayNode",
24820 "DelegatedInkTrailPresenter",
24821 "DeprecationReportBody",
24822 "DesktopNotification",
24823 "DesktopNotificationCenter",
24824 "Details",
24825 "DeviceLightEvent",
24826 "DeviceMotionEvent",
24827 "DeviceMotionEventAcceleration",
24828 "DeviceMotionEventRotationRate",
24829 "DeviceOrientationEvent",
24830 "DevicePosture",
24831 "DeviceProximityEvent",
24832 "DeviceStorage",
24833 "DeviceStorageChangeEvent",
24834 "DigitalCredential",
24835 "Directory",
24836 "DisplayNames",
24837 "DisposableStack",
24838 "Document",
24839 "DocumentFragment",
24840 "DocumentPictureInPicture",
24841 "DocumentPictureInPictureEvent",
24842 "DocumentTimeline",
24843 "DocumentType",
24844 "DragEvent",
24845 "Duration",
24846 "DurationFormat",
24847 "DynamicsCompressorNode",
24848 "E",
24849 "ELEMENT_ARRAY_BUFFER",
24850 "ELEMENT_ARRAY_BUFFER_BINDING",
24851 "ELEMENT_NODE",
24852 "EMPTY",
24853 "ENCODING_ERR",
24854 "ENDED",
24855 "END_TO_END",
24856 "END_TO_START",
24857 "ENTITY_NODE",
24858 "ENTITY_REFERENCE_NODE",
24859 "EPSILON",
24860 "EQUAL",
24861 "EQUALPOWER",
24862 "ERROR",
24863 "EXPONENTIAL_DISTANCE",
24864 "EditContext",
24865 "Element",
24866 "ElementInternals",
24867 "ElementQuery",
24868 "EncodedAudioChunk",
24869 "EncodedVideoChunk",
24870 "EnterPictureInPictureEvent",
24871 "Entity",
24872 "EntityReference",
24873 "Error",
24874 "ErrorEvent",
24875 "EvalError",
24876 "Event",
24877 "EventCounts",
24878 "EventException",
24879 "EventSource",
24880 "EventTarget",
24881 "Exception",
24882 "ExtensionContext",
24883 "ExtensionDisabledReason",
24884 "ExtensionInfo",
24885 "ExtensionInstallType",
24886 "ExtensionType",
24887 "External",
24888 "EyeDropper",
24889 "FASTEST",
24890 "FIDOSDK",
24891 "FILTER_ACCEPT",
24892 "FILTER_INTERRUPT",
24893 "FILTER_REJECT",
24894 "FILTER_SKIP",
24895 "FINISHED_STATE",
24896 "FIRST_ORDERED_NODE_TYPE",
24897 "FLOAT",
24898 "FLOAT_32_UNSIGNED_INT_24_8_REV",
24899 "FLOAT_MAT2",
24900 "FLOAT_MAT2x3",
24901 "FLOAT_MAT2x4",
24902 "FLOAT_MAT3",
24903 "FLOAT_MAT3x2",
24904 "FLOAT_MAT3x4",
24905 "FLOAT_MAT4",
24906 "FLOAT_MAT4x2",
24907 "FLOAT_MAT4x3",
24908 "FLOAT_VEC2",
24909 "FLOAT_VEC3",
24910 "FLOAT_VEC4",
24911 "FOCUS",
24912 "FONT_FACE_RULE",
24913 "FONT_FEATURE_VALUES_RULE",
24914 "FRAGMENT",
24915 "FRAGMENT_SHADER",
24916 "FRAGMENT_SHADER_DERIVATIVE_HINT",
24917 "FRAGMENT_SHADER_DERIVATIVE_HINT_OES",
24918 "FRAMEBUFFER",
24919 "FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE",
24920 "FRAMEBUFFER_ATTACHMENT_BLUE_SIZE",
24921 "FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING",
24922 "FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE",
24923 "FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE",
24924 "FRAMEBUFFER_ATTACHMENT_GREEN_SIZE",
24925 "FRAMEBUFFER_ATTACHMENT_OBJECT_NAME",
24926 "FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE",
24927 "FRAMEBUFFER_ATTACHMENT_RED_SIZE",
24928 "FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE",
24929 "FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE",
24930 "FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER",
24931 "FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL",
24932 "FRAMEBUFFER_BINDING",
24933 "FRAMEBUFFER_COMPLETE",
24934 "FRAMEBUFFER_DEFAULT",
24935 "FRAMEBUFFER_INCOMPLETE_ATTACHMENT",
24936 "FRAMEBUFFER_INCOMPLETE_DIMENSIONS",
24937 "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT",
24938 "FRAMEBUFFER_INCOMPLETE_MULTISAMPLE",
24939 "FRAMEBUFFER_UNSUPPORTED",
24940 "FRONT",
24941 "FRONT_AND_BACK",
24942 "FRONT_FACE",
24943 "FUNC_ADD",
24944 "FUNC_REVERSE_SUBTRACT",
24945 "FUNC_SUBTRACT",
24946 "FeaturePolicy",
24947 "FeaturePolicyViolationReportBody",
24948 "FederatedCredential",
24949 "Feed",
24950 "FeedEntry",
24951 "Fence",
24952 "FencedFrameConfig",
24953 "FetchLaterResult",
24954 "File",
24955 "FileError",
24956 "FileList",
24957 "FileReader",
24958 "FileSystem",
24959 "FileSystemDirectoryEntry",
24960 "FileSystemDirectoryHandle",
24961 "FileSystemDirectoryReader",
24962 "FileSystemEntry",
24963 "FileSystemFileEntry",
24964 "FileSystemFileHandle",
24965 "FileSystemHandle",
24966 "FileSystemObserver",
24967 "FileSystemWritableFileStream",
24968 "FinalizationRegistry",
24969 "FindInPage",
24970 "Float16Array",
24971 "Float32Array",
24972 "Float64Array",
24973 "FocusEvent",
24974 "FontData",
24975 "FontFace",
24976 "FontFaceSet",
24977 "FontFaceSetLoadEvent",
24978 "FormData",
24979 "FormDataEvent",
24980 "FragmentDirective",
24981 "Function",
24982 "GENERATE_MIPMAP_HINT",
24983 "GEQUAL",
24984 "GPU",
24985 "GPUAdapter",
24986 "GPUAdapterInfo",
24987 "GPUBindGroup",
24988 "GPUBindGroupLayout",
24989 "GPUBuffer",
24990 "GPUBufferUsage",
24991 "GPUCanvasContext",
24992 "GPUColorWrite",
24993 "GPUCommandBuffer",
24994 "GPUCommandEncoder",
24995 "GPUCompilationInfo",
24996 "GPUCompilationMessage",
24997 "GPUComputePassEncoder",
24998 "GPUComputePipeline",
24999 "GPUDevice",
25000 "GPUDeviceLostInfo",
25001 "GPUError",
25002 "GPUExternalTexture",
25003 "GPUInternalError",
25004 "GPUMapMode",
25005 "GPUOutOfMemoryError",
25006 "GPUPipelineError",
25007 "GPUPipelineLayout",
25008 "GPUQuerySet",
25009 "GPUQueue",
25010 "GPURenderBundle",
25011 "GPURenderBundleEncoder",
25012 "GPURenderPassEncoder",
25013 "GPURenderPipeline",
25014 "GPUSampler",
25015 "GPUShaderModule",
25016 "GPUShaderStage",
25017 "GPUSupportedFeatures",
25018 "GPUSupportedLimits",
25019 "GPUTexture",
25020 "GPUTextureUsage",
25021 "GPUTextureView",
25022 "GPUUncapturedErrorEvent",
25023 "GPUValidationError",
25024 "GREATER",
25025 "GREEN",
25026 "GREEN_BITS",
25027 "GainNode",
25028 "Gamepad",
25029 "GamepadAxisMoveEvent",
25030 "GamepadButton",
25031 "GamepadButtonEvent",
25032 "GamepadEvent",
25033 "GamepadHapticActuator",
25034 "GamepadPose",
25035 "Geolocation",
25036 "GeolocationCoordinates",
25037 "GeolocationPosition",
25038 "GeolocationPositionError",
25039 "GestureEvent",
25040 "GetInfo",
25041 "Global",
25042 "GravitySensor",
25043 "Gyroscope",
25044 "HALF_FLOAT",
25045 "HAVE_CURRENT_DATA",
25046 "HAVE_ENOUGH_DATA",
25047 "HAVE_FUTURE_DATA",
25048 "HAVE_METADATA",
25049 "HAVE_NOTHING",
25050 "HEADERS_RECEIVED",
25051 "HID",
25052 "HIDConnectionEvent",
25053 "HIDDEN",
25054 "HIDDevice",
25055 "HIDInputReportEvent",
25056 "HIERARCHY_REQUEST_ERR",
25057 "HIGHPASS",
25058 "HIGHSHELF",
25059 "HIGH_FLOAT",
25060 "HIGH_INT",
25061 "HORIZONTAL",
25062 "HORIZONTAL_AXIS",
25063 "HRTF",
25064 "HTMLAllCollection",
25065 "HTMLAnchorElement",
25066 "HTMLAppletElement",
25067 "HTMLAreaElement",
25068 "HTMLAudioElement",
25069 "HTMLBRElement",
25070 "HTMLBaseElement",
25071 "HTMLBaseFontElement",
25072 "HTMLBlockquoteElement",
25073 "HTMLBodyElement",
25074 "HTMLButtonElement",
25075 "HTMLCanvasElement",
25076 "HTMLCollection",
25077 "HTMLCommandElement",
25078 "HTMLContentElement",
25079 "HTMLDListElement",
25080 "HTMLDataElement",
25081 "HTMLDataListElement",
25082 "HTMLDetailsElement",
25083 "HTMLDialogElement",
25084 "HTMLDirectoryElement",
25085 "HTMLDivElement",
25086 "HTMLDocument",
25087 "HTMLElement",
25088 "HTMLEmbedElement",
25089 "HTMLFencedFrameElement",
25090 "HTMLFieldSetElement",
25091 "HTMLFontElement",
25092 "HTMLFormControlsCollection",
25093 "HTMLFormElement",
25094 "HTMLFrameElement",
25095 "HTMLFrameSetElement",
25096 "HTMLHRElement",
25097 "HTMLHeadElement",
25098 "HTMLHeadingElement",
25099 "HTMLHtmlElement",
25100 "HTMLIFrameElement",
25101 "HTMLImageElement",
25102 "HTMLInputElement",
25103 "HTMLIsIndexElement",
25104 "HTMLKeygenElement",
25105 "HTMLLIElement",
25106 "HTMLLabelElement",
25107 "HTMLLegendElement",
25108 "HTMLLinkElement",
25109 "HTMLMapElement",
25110 "HTMLMarqueeElement",
25111 "HTMLMediaElement",
25112 "HTMLMenuElement",
25113 "HTMLMenuItemElement",
25114 "HTMLMetaElement",
25115 "HTMLMeterElement",
25116 "HTMLModElement",
25117 "HTMLOListElement",
25118 "HTMLObjectElement",
25119 "HTMLOptGroupElement",
25120 "HTMLOptionElement",
25121 "HTMLOptionsCollection",
25122 "HTMLOutputElement",
25123 "HTMLParagraphElement",
25124 "HTMLParamElement",
25125 "HTMLPictureElement",
25126 "HTMLPreElement",
25127 "HTMLProgressElement",
25128 "HTMLPropertiesCollection",
25129 "HTMLQuoteElement",
25130 "HTMLScriptElement",
25131 "HTMLSelectElement",
25132 "HTMLSelectedContentElement",
25133 "HTMLShadowElement",
25134 "HTMLSlotElement",
25135 "HTMLSourceElement",
25136 "HTMLSpanElement",
25137 "HTMLStyleElement",
25138 "HTMLTableCaptionElement",
25139 "HTMLTableCellElement",
25140 "HTMLTableColElement",
25141 "HTMLTableElement",
25142 "HTMLTableRowElement",
25143 "HTMLTableSectionElement",
25144 "HTMLTemplateElement",
25145 "HTMLTextAreaElement",
25146 "HTMLTimeElement",
25147 "HTMLTitleElement",
25148 "HTMLTrackElement",
25149 "HTMLUListElement",
25150 "HTMLUnknownElement",
25151 "HTMLVideoElement",
25152 "HashChangeEvent",
25153 "Headers",
25154 "Highlight",
25155 "HighlightRegistry",
25156 "History",
25157 "Hz",
25158 "ICE_CHECKING",
25159 "ICE_CLOSED",
25160 "ICE_COMPLETED",
25161 "ICE_CONNECTED",
25162 "ICE_FAILED",
25163 "ICE_GATHERING",
25164 "ICE_WAITING",
25165 "IDBCursor",
25166 "IDBCursorWithValue",
25167 "IDBDatabase",
25168 "IDBDatabaseException",
25169 "IDBFactory",
25170 "IDBFileHandle",
25171 "IDBFileRequest",
25172 "IDBIndex",
25173 "IDBKeyRange",
25174 "IDBMutableFile",
25175 "IDBObjectStore",
25176 "IDBOpenDBRequest",
25177 "IDBRecord",
25178 "IDBRequest",
25179 "IDBTransaction",
25180 "IDBVersionChangeEvent",
25181 "IDLE",
25182 "IIRFilterNode",
25183 "IMPLEMENTATION_COLOR_READ_FORMAT",
25184 "IMPLEMENTATION_COLOR_READ_TYPE",
25185 "IMPORT_RULE",
25186 "INCR",
25187 "INCR_WRAP",
25188 "INDEX",
25189 "INDEX_SIZE_ERR",
25190 "INDIRECT",
25191 "INT",
25192 "INTERLEAVED_ATTRIBS",
25193 "INT_2_10_10_10_REV",
25194 "INT_SAMPLER_2D",
25195 "INT_SAMPLER_2D_ARRAY",
25196 "INT_SAMPLER_3D",
25197 "INT_SAMPLER_CUBE",
25198 "INT_VEC2",
25199 "INT_VEC3",
25200 "INT_VEC4",
25201 "INUSE_ATTRIBUTE_ERR",
25202 "INVALID_ACCESS_ERR",
25203 "INVALID_CHARACTER_ERR",
25204 "INVALID_ENUM",
25205 "INVALID_EXPRESSION_ERR",
25206 "INVALID_FRAMEBUFFER_OPERATION",
25207 "INVALID_INDEX",
25208 "INVALID_MODIFICATION_ERR",
25209 "INVALID_NODE_TYPE_ERR",
25210 "INVALID_OPERATION",
25211 "INVALID_STATE_ERR",
25212 "INVALID_VALUE",
25213 "INVERSE_DISTANCE",
25214 "INVERT",
25215 "IceCandidate",
25216 "IconInfo",
25217 "IdentityCredential",
25218 "IdentityCredentialError",
25219 "IdentityProvider",
25220 "IdleDeadline",
25221 "IdleDetector",
25222 "Image",
25223 "ImageBitmap",
25224 "ImageBitmapRenderingContext",
25225 "ImageCapture",
25226 "ImageData",
25227 "ImageDataType",
25228 "ImageDecoder",
25229 "ImageTrack",
25230 "ImageTrackList",
25231 "Infinity",
25232 "Ink",
25233 "InputDeviceCapabilities",
25234 "InputDeviceInfo",
25235 "InputEvent",
25236 "InputMethodContext",
25237 "InstallTrigger",
25238 "InstallTriggerImpl",
25239 "Instance",
25240 "Instant",
25241 "Int16Array",
25242 "Int32Array",
25243 "Int8Array",
25244 "IntegrityViolationReportBody",
25245 "Intent",
25246 "InterestEvent",
25247 "InternalError",
25248 "IntersectionObserver",
25249 "IntersectionObserverEntry",
25250 "Intl",
25251 "IsSearchProviderInstalled",
25252 "Iterator",
25253 "JSON",
25254 "JSTag",
25255 "KEEP",
25256 "KEYDOWN",
25257 "KEYFRAMES_RULE",
25258 "KEYFRAME_RULE",
25259 "KEYPRESS",
25260 "KEYUP",
25261 "KeyEvent",
25262 "Keyboard",
25263 "KeyboardEvent",
25264 "KeyboardLayoutMap",
25265 "KeyframeEffect",
25266 "LENGTHADJUST_SPACING",
25267 "LENGTHADJUST_SPACINGANDGLYPHS",
25268 "LENGTHADJUST_UNKNOWN",
25269 "LEQUAL",
25270 "LESS",
25271 "LINEAR",
25272 "LINEAR_DISTANCE",
25273 "LINEAR_MIPMAP_LINEAR",
25274 "LINEAR_MIPMAP_NEAREST",
25275 "LINES",
25276 "LINE_LOOP",
25277 "LINE_STRIP",
25278 "LINE_WIDTH",
25279 "LINK_STATUS",
25280 "LIVE",
25281 "LN10",
25282 "LN2",
25283 "LOADED",
25284 "LOADING",
25285 "LOG10E",
25286 "LOG2E",
25287 "LOWPASS",
25288 "LOWSHELF",
25289 "LOW_FLOAT",
25290 "LOW_INT",
25291 "LSException",
25292 "LSParserFilter",
25293 "LUMINANCE",
25294 "LUMINANCE_ALPHA",
25295 "LanguageCode",
25296 "LanguageDetector",
25297 "LargestContentfulPaint",
25298 "LaunchParams",
25299 "LaunchQueue",
25300 "LaunchType",
25301 "LayoutShift",
25302 "LayoutShiftAttribution",
25303 "LinearAccelerationSensor",
25304 "LinkError",
25305 "ListFormat",
25306 "LocalMediaStream",
25307 "Locale",
25308 "Location",
25309 "Lock",
25310 "LockManager",
25311 "MAP_READ",
25312 "MAP_WRITE",
25313 "MARGIN_RULE",
25314 "MAX",
25315 "MAX_3D_TEXTURE_SIZE",
25316 "MAX_ARRAY_TEXTURE_LAYERS",
25317 "MAX_CAPTURE_VISIBLE_TAB_CALLS_PER_SECOND",
25318 "MAX_CLIENT_WAIT_TIMEOUT_WEBGL",
25319 "MAX_COLOR_ATTACHMENTS",
25320 "MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS",
25321 "MAX_COMBINED_TEXTURE_IMAGE_UNITS",
25322 "MAX_COMBINED_UNIFORM_BLOCKS",
25323 "MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS",
25324 "MAX_CUBE_MAP_TEXTURE_SIZE",
25325 "MAX_DRAW_BUFFERS",
25326 "MAX_ELEMENTS_INDICES",
25327 "MAX_ELEMENTS_VERTICES",
25328 "MAX_ELEMENT_INDEX",
25329 "MAX_FRAGMENT_INPUT_COMPONENTS",
25330 "MAX_FRAGMENT_UNIFORM_BLOCKS",
25331 "MAX_FRAGMENT_UNIFORM_COMPONENTS",
25332 "MAX_FRAGMENT_UNIFORM_VECTORS",
25333 "MAX_PROGRAM_TEXEL_OFFSET",
25334 "MAX_RENDERBUFFER_SIZE",
25335 "MAX_SAFE_INTEGER",
25336 "MAX_SAMPLES",
25337 "MAX_SERVER_WAIT_TIMEOUT",
25338 "MAX_TEXTURE_IMAGE_UNITS",
25339 "MAX_TEXTURE_LOD_BIAS",
25340 "MAX_TEXTURE_MAX_ANISOTROPY_EXT",
25341 "MAX_TEXTURE_SIZE",
25342 "MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS",
25343 "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS",
25344 "MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS",
25345 "MAX_UNIFORM_BLOCK_SIZE",
25346 "MAX_UNIFORM_BUFFER_BINDINGS",
25347 "MAX_VALUE",
25348 "MAX_VARYING_COMPONENTS",
25349 "MAX_VARYING_VECTORS",
25350 "MAX_VERTEX_ATTRIBS",
25351 "MAX_VERTEX_OUTPUT_COMPONENTS",
25352 "MAX_VERTEX_TEXTURE_IMAGE_UNITS",
25353 "MAX_VERTEX_UNIFORM_BLOCKS",
25354 "MAX_VERTEX_UNIFORM_COMPONENTS",
25355 "MAX_VERTEX_UNIFORM_VECTORS",
25356 "MAX_VIEWPORT_DIMS",
25357 "MEDIA_ERR_ABORTED",
25358 "MEDIA_ERR_DECODE",
25359 "MEDIA_ERR_ENCRYPTED",
25360 "MEDIA_ERR_NETWORK",
25361 "MEDIA_ERR_SRC_NOT_SUPPORTED",
25362 "MEDIA_KEYERR_CLIENT",
25363 "MEDIA_KEYERR_DOMAIN",
25364 "MEDIA_KEYERR_HARDWARECHANGE",
25365 "MEDIA_KEYERR_OUTPUT",
25366 "MEDIA_KEYERR_SERVICE",
25367 "MEDIA_KEYERR_UNKNOWN",
25368 "MEDIA_RULE",
25369 "MEDIUM_FLOAT",
25370 "MEDIUM_INT",
25371 "META_MASK",
25372 "MIDIAccess",
25373 "MIDIConnectionEvent",
25374 "MIDIInput",
25375 "MIDIInputMap",
25376 "MIDIMessageEvent",
25377 "MIDIOutput",
25378 "MIDIOutputMap",
25379 "MIDIPort",
25380 "MIN",
25381 "MIN_PROGRAM_TEXEL_OFFSET",
25382 "MIN_SAFE_INTEGER",
25383 "MIN_VALUE",
25384 "MIRRORED_REPEAT",
25385 "MODE_ASYNCHRONOUS",
25386 "MODE_SYNCHRONOUS",
25387 "MODIFICATION",
25388 "MOUSEDOWN",
25389 "MOUSEDRAG",
25390 "MOUSEMOVE",
25391 "MOUSEOUT",
25392 "MOUSEOVER",
25393 "MOUSEUP",
25394 "MOZ_KEYFRAMES_RULE",
25395 "MOZ_KEYFRAME_RULE",
25396 "MOZ_SOURCE_CURSOR",
25397 "MOZ_SOURCE_ERASER",
25398 "MOZ_SOURCE_KEYBOARD",
25399 "MOZ_SOURCE_MOUSE",
25400 "MOZ_SOURCE_PEN",
25401 "MOZ_SOURCE_TOUCH",
25402 "MOZ_SOURCE_UNKNOWN",
25403 "MSGESTURE_FLAG_BEGIN",
25404 "MSGESTURE_FLAG_CANCEL",
25405 "MSGESTURE_FLAG_END",
25406 "MSGESTURE_FLAG_INERTIA",
25407 "MSGESTURE_FLAG_NONE",
25408 "MSPOINTER_TYPE_MOUSE",
25409 "MSPOINTER_TYPE_PEN",
25410 "MSPOINTER_TYPE_TOUCH",
25411 "MS_ASYNC_CALLBACK_STATUS_ASSIGN_DELEGATE",
25412 "MS_ASYNC_CALLBACK_STATUS_CANCEL",
25413 "MS_ASYNC_CALLBACK_STATUS_CHOOSEANY",
25414 "MS_ASYNC_CALLBACK_STATUS_ERROR",
25415 "MS_ASYNC_CALLBACK_STATUS_JOIN",
25416 "MS_ASYNC_OP_STATUS_CANCELED",
25417 "MS_ASYNC_OP_STATUS_ERROR",
25418 "MS_ASYNC_OP_STATUS_SUCCESS",
25419 "MS_MANIPULATION_STATE_ACTIVE",
25420 "MS_MANIPULATION_STATE_CANCELLED",
25421 "MS_MANIPULATION_STATE_COMMITTED",
25422 "MS_MANIPULATION_STATE_DRAGGING",
25423 "MS_MANIPULATION_STATE_INERTIA",
25424 "MS_MANIPULATION_STATE_PRESELECT",
25425 "MS_MANIPULATION_STATE_SELECTING",
25426 "MS_MANIPULATION_STATE_STOPPED",
25427 "MS_MEDIA_ERR_ENCRYPTED",
25428 "MS_MEDIA_KEYERR_CLIENT",
25429 "MS_MEDIA_KEYERR_DOMAIN",
25430 "MS_MEDIA_KEYERR_HARDWARECHANGE",
25431 "MS_MEDIA_KEYERR_OUTPUT",
25432 "MS_MEDIA_KEYERR_SERVICE",
25433 "MS_MEDIA_KEYERR_UNKNOWN",
25434 "Map",
25435 "Math",
25436 "MathMLElement",
25437 "MediaCapabilities",
25438 "MediaCapabilitiesInfo",
25439 "MediaController",
25440 "MediaDeviceInfo",
25441 "MediaDevices",
25442 "MediaElementAudioSourceNode",
25443 "MediaEncryptedEvent",
25444 "MediaError",
25445 "MediaKeyError",
25446 "MediaKeyEvent",
25447 "MediaKeyMessageEvent",
25448 "MediaKeyNeededEvent",
25449 "MediaKeySession",
25450 "MediaKeyStatusMap",
25451 "MediaKeySystemAccess",
25452 "MediaKeys",
25453 "MediaList",
25454 "MediaMetadata",
25455 "MediaQueryList",
25456 "MediaQueryListEvent",
25457 "MediaRecorder",
25458 "MediaRecorderErrorEvent",
25459 "MediaSession",
25460 "MediaSettingsRange",
25461 "MediaSource",
25462 "MediaSourceHandle",
25463 "MediaStream",
25464 "MediaStreamAudioDestinationNode",
25465 "MediaStreamAudioSourceNode",
25466 "MediaStreamEvent",
25467 "MediaStreamTrack",
25468 "MediaStreamTrackAudioSourceNode",
25469 "MediaStreamTrackAudioStats",
25470 "MediaStreamTrackEvent",
25471 "MediaStreamTrackGenerator",
25472 "MediaStreamTrackProcessor",
25473 "MediaStreamTrackVideoStats",
25474 "Memory",
25475 "MessageChannel",
25476 "MessageEvent",
25477 "MessagePort",
25478 "MessageSender",
25479 "Methods",
25480 "MimeType",
25481 "MimeTypeArray",
25482 "Module",
25483 "MouseEvent",
25484 "MouseScrollEvent",
25485 "MozAnimation",
25486 "MozAnimationDelay",
25487 "MozAnimationDirection",
25488 "MozAnimationDuration",
25489 "MozAnimationFillMode",
25490 "MozAnimationIterationCount",
25491 "MozAnimationName",
25492 "MozAnimationPlayState",
25493 "MozAnimationTimingFunction",
25494 "MozAppearance",
25495 "MozBackfaceVisibility",
25496 "MozBinding",
25497 "MozBorderBottomColors",
25498 "MozBorderEnd",
25499 "MozBorderEndColor",
25500 "MozBorderEndStyle",
25501 "MozBorderEndWidth",
25502 "MozBorderImage",
25503 "MozBorderLeftColors",
25504 "MozBorderRightColors",
25505 "MozBorderStart",
25506 "MozBorderStartColor",
25507 "MozBorderStartStyle",
25508 "MozBorderStartWidth",
25509 "MozBorderTopColors",
25510 "MozBoxAlign",
25511 "MozBoxDirection",
25512 "MozBoxFlex",
25513 "MozBoxOrdinalGroup",
25514 "MozBoxOrient",
25515 "MozBoxPack",
25516 "MozBoxSizing",
25517 "MozCSSKeyframeRule",
25518 "MozCSSKeyframesRule",
25519 "MozColumnCount",
25520 "MozColumnFill",
25521 "MozColumnGap",
25522 "MozColumnRule",
25523 "MozColumnRuleColor",
25524 "MozColumnRuleStyle",
25525 "MozColumnRuleWidth",
25526 "MozColumnWidth",
25527 "MozColumns",
25528 "MozContactChangeEvent",
25529 "MozFloatEdge",
25530 "MozFontFeatureSettings",
25531 "MozFontLanguageOverride",
25532 "MozForceBrokenImageIcon",
25533 "MozHyphens",
25534 "MozImageRegion",
25535 "MozMarginEnd",
25536 "MozMarginStart",
25537 "MozMmsEvent",
25538 "MozMmsMessage",
25539 "MozMobileMessageThread",
25540 "MozOSXFontSmoothing",
25541 "MozOrient",
25542 "MozOsxFontSmoothing",
25543 "MozOutlineRadius",
25544 "MozOutlineRadiusBottomleft",
25545 "MozOutlineRadiusBottomright",
25546 "MozOutlineRadiusTopleft",
25547 "MozOutlineRadiusTopright",
25548 "MozPaddingEnd",
25549 "MozPaddingStart",
25550 "MozPerspective",
25551 "MozPerspectiveOrigin",
25552 "MozPowerManager",
25553 "MozSettingsEvent",
25554 "MozSmsEvent",
25555 "MozSmsMessage",
25556 "MozStackSizing",
25557 "MozTabSize",
25558 "MozTextAlignLast",
25559 "MozTextDecorationColor",
25560 "MozTextDecorationLine",
25561 "MozTextDecorationStyle",
25562 "MozTextSizeAdjust",
25563 "MozTransform",
25564 "MozTransformOrigin",
25565 "MozTransformStyle",
25566 "MozTransition",
25567 "MozTransitionDelay",
25568 "MozTransitionDuration",
25569 "MozTransitionProperty",
25570 "MozTransitionTimingFunction",
25571 "MozUserFocus",
25572 "MozUserInput",
25573 "MozUserModify",
25574 "MozUserSelect",
25575 "MozWindowDragging",
25576 "MozWindowShadow",
25577 "MutationEvent",
25578 "MutationObserver",
25579 "MutationRecord",
25580 "MutedInfo",
25581 "MutedInfoReason",
25582 "NAMESPACE_ERR",
25583 "NAMESPACE_RULE",
25584 "NEAREST",
25585 "NEAREST_MIPMAP_LINEAR",
25586 "NEAREST_MIPMAP_NEAREST",
25587 "NEGATIVE_INFINITY",
25588 "NETWORK_EMPTY",
25589 "NETWORK_ERR",
25590 "NETWORK_IDLE",
25591 "NETWORK_LOADED",
25592 "NETWORK_LOADING",
25593 "NETWORK_NO_SOURCE",
25594 "NEVER",
25595 "NEW",
25596 "NEXT",
25597 "NEXT_NO_DUPLICATE",
25598 "NICEST",
25599 "NODE_AFTER",
25600 "NODE_BEFORE",
25601 "NODE_BEFORE_AND_AFTER",
25602 "NODE_INSIDE",
25603 "NONE",
25604 "NON_TRANSIENT_ERR",
25605 "NOTATION_NODE",
25606 "NOTCH",
25607 "NOTEQUAL",
25608 "NOT_ALLOWED_ERR",
25609 "NOT_FOUND_ERR",
25610 "NOT_READABLE_ERR",
25611 "NOT_SUPPORTED_ERR",
25612 "NO_DATA_ALLOWED_ERR",
25613 "NO_ERR",
25614 "NO_ERROR",
25615 "NO_MODIFICATION_ALLOWED_ERR",
25616 "NUMBER_TYPE",
25617 "NUM_COMPRESSED_TEXTURE_FORMATS",
25618 "NaN",
25619 "NamedNodeMap",
25620 "NavigateEvent",
25621 "Navigation",
25622 "NavigationActivation",
25623 "NavigationCurrentEntryChangeEvent",
25624 "NavigationDestination",
25625 "NavigationHistoryEntry",
25626 "NavigationPrecommitController",
25627 "NavigationPreloadManager",
25628 "NavigationTransition",
25629 "Navigator",
25630 "NavigatorLogin",
25631 "NavigatorManagedData",
25632 "NavigatorUAData",
25633 "NearbyLinks",
25634 "NetworkInformation",
25635 "Node",
25636 "NodeFilter",
25637 "NodeIterator",
25638 "NodeList",
25639 "NotRestoredReasonDetails",
25640 "NotRestoredReasons",
25641 "Notation",
25642 "Notification",
25643 "NotifyPaintEvent",
25644 "Now",
25645 "Number",
25646 "NumberFormat",
25647 "OBJECT_TYPE",
25648 "OBSOLETE",
25649 "OK",
25650 "ONE",
25651 "ONE_MINUS_CONSTANT_ALPHA",
25652 "ONE_MINUS_CONSTANT_COLOR",
25653 "ONE_MINUS_DST_ALPHA",
25654 "ONE_MINUS_DST_COLOR",
25655 "ONE_MINUS_SRC_ALPHA",
25656 "ONE_MINUS_SRC_COLOR",
25657 "OPEN",
25658 "OPENED",
25659 "OPENING",
25660 "ORDERED_NODE_ITERATOR_TYPE",
25661 "ORDERED_NODE_SNAPSHOT_TYPE",
25662 "OTHER_ERROR",
25663 "OTPCredential",
25664 "OUT_OF_MEMORY",
25665 "Object",
25666 "Observable",
25667 "OfflineAudioCompletionEvent",
25668 "OfflineAudioContext",
25669 "OfflineResourceList",
25670 "OffscreenCanvas",
25671 "OffscreenCanvasRenderingContext2D",
25672 "OnClickData",
25673 "OnInstalledReason",
25674 "OnPerformanceWarningCategory",
25675 "OnPerformanceWarningSeverity",
25676 "OnRestartRequiredReason",
25677 "Option",
25678 "OrientationSensor",
25679 "OscillatorNode",
25680 "OverconstrainedError",
25681 "OverflowEvent",
25682 "PACK_ALIGNMENT",
25683 "PACK_ROW_LENGTH",
25684 "PACK_SKIP_PIXELS",
25685 "PACK_SKIP_ROWS",
25686 "PAGE_RULE",
25687 "PARSE_ERR",
25688 "PATHSEG_ARC_ABS",
25689 "PATHSEG_ARC_REL",
25690 "PATHSEG_CLOSEPATH",
25691 "PATHSEG_CURVETO_CUBIC_ABS",
25692 "PATHSEG_CURVETO_CUBIC_REL",
25693 "PATHSEG_CURVETO_CUBIC_SMOOTH_ABS",
25694 "PATHSEG_CURVETO_CUBIC_SMOOTH_REL",
25695 "PATHSEG_CURVETO_QUADRATIC_ABS",
25696 "PATHSEG_CURVETO_QUADRATIC_REL",
25697 "PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS",
25698 "PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL",
25699 "PATHSEG_LINETO_ABS",
25700 "PATHSEG_LINETO_HORIZONTAL_ABS",
25701 "PATHSEG_LINETO_HORIZONTAL_REL",
25702 "PATHSEG_LINETO_REL",
25703 "PATHSEG_LINETO_VERTICAL_ABS",
25704 "PATHSEG_LINETO_VERTICAL_REL",
25705 "PATHSEG_MOVETO_ABS",
25706 "PATHSEG_MOVETO_REL",
25707 "PATHSEG_UNKNOWN",
25708 "PATH_EXISTS_ERR",
25709 "PEAKING",
25710 "PERMISSION_DENIED",
25711 "PERSISTENT",
25712 "PI",
25713 "PIXEL_PACK_BUFFER",
25714 "PIXEL_PACK_BUFFER_BINDING",
25715 "PIXEL_UNPACK_BUFFER",
25716 "PIXEL_UNPACK_BUFFER_BINDING",
25717 "PLAYING_STATE",
25718 "POINTS",
25719 "POLYGON_OFFSET_FACTOR",
25720 "POLYGON_OFFSET_FILL",
25721 "POLYGON_OFFSET_UNITS",
25722 "POSITION_UNAVAILABLE",
25723 "POSITIVE_INFINITY",
25724 "PREV",
25725 "PREV_NO_DUPLICATE",
25726 "PROCESSING_INSTRUCTION_NODE",
25727 "PageChangeEvent",
25728 "PageRevealEvent",
25729 "PageSettings",
25730 "PageSwapEvent",
25731 "PageTransitionEvent",
25732 "PaintRequest",
25733 "PaintRequestList",
25734 "PannerNode",
25735 "PasswordCredential",
25736 "Path2D",
25737 "PaymentAddress",
25738 "PaymentInstruments",
25739 "PaymentManager",
25740 "PaymentMethodChangeEvent",
25741 "PaymentRequest",
25742 "PaymentRequestUpdateEvent",
25743 "PaymentResponse",
25744 "Performance",
25745 "PerformanceElementTiming",
25746 "PerformanceEntry",
25747 "PerformanceEventTiming",
25748 "PerformanceLongAnimationFrameTiming",
25749 "PerformanceLongTaskTiming",
25750 "PerformanceMark",
25751 "PerformanceMeasure",
25752 "PerformanceNavigation",
25753 "PerformanceNavigationTiming",
25754 "PerformanceObserver",
25755 "PerformanceObserverEntryList",
25756 "PerformancePaintTiming",
25757 "PerformanceResourceTiming",
25758 "PerformanceScriptTiming",
25759 "PerformanceServerTiming",
25760 "PerformanceTiming",
25761 "PeriodicSyncManager",
25762 "PeriodicWave",
25763 "PermissionStatus",
25764 "Permissions",
25765 "PhotoCapabilities",
25766 "PictureInPictureEvent",
25767 "PictureInPictureWindow",
25768 "PlainDate",
25769 "PlainDateTime",
25770 "PlainMonthDay",
25771 "PlainTime",
25772 "PlainYearMonth",
25773 "PlatformArch",
25774 "PlatformInfo",
25775 "PlatformNaclArch",
25776 "PlatformOs",
25777 "Plugin",
25778 "PluginArray",
25779 "PluralRules",
25780 "PointerEvent",
25781 "PopStateEvent",
25782 "PopupBlockedEvent",
25783 "Port",
25784 "Presentation",
25785 "PresentationAvailability",
25786 "PresentationConnection",
25787 "PresentationConnectionAvailableEvent",
25788 "PresentationConnectionCloseEvent",
25789 "PresentationConnectionList",
25790 "PresentationReceiver",
25791 "PresentationRequest",
25792 "PressureObserver",
25793 "PressureRecord",
25794 "ProcessingInstruction",
25795 "Profiler",
25796 "ProgressEvent",
25797 "Promise",
25798 "PromiseRejectionEvent",
25799 "PropertyNodeList",
25800 "ProtectedAudience",
25801 "Proxy",
25802 "PublicKeyCredential",
25803 "PushManager",
25804 "PushSubscription",
25805 "PushSubscriptionOptions",
25806 "Q",
25807 "QUERY_RESOLVE",
25808 "QUERY_RESULT",
25809 "QUERY_RESULT_AVAILABLE",
25810 "QUOTA_ERR",
25811 "QUOTA_EXCEEDED_ERR",
25812 "QueryInterface",
25813 "QuotaExceededError",
25814 "R11F_G11F_B10F",
25815 "R16F",
25816 "R16I",
25817 "R16UI",
25818 "R32F",
25819 "R32I",
25820 "R32UI",
25821 "R8",
25822 "R8I",
25823 "R8UI",
25824 "R8_SNORM",
25825 "RASTERIZER_DISCARD",
25826 "READ",
25827 "READ_BUFFER",
25828 "READ_FRAMEBUFFER",
25829 "READ_FRAMEBUFFER_BINDING",
25830 "READ_ONLY",
25831 "READ_ONLY_ERR",
25832 "READ_WRITE",
25833 "RED",
25834 "RED_BITS",
25835 "RED_INTEGER",
25836 "REMOVAL",
25837 "RENDERBUFFER",
25838 "RENDERBUFFER_ALPHA_SIZE",
25839 "RENDERBUFFER_BINDING",
25840 "RENDERBUFFER_BLUE_SIZE",
25841 "RENDERBUFFER_DEPTH_SIZE",
25842 "RENDERBUFFER_GREEN_SIZE",
25843 "RENDERBUFFER_HEIGHT",
25844 "RENDERBUFFER_INTERNAL_FORMAT",
25845 "RENDERBUFFER_RED_SIZE",
25846 "RENDERBUFFER_SAMPLES",
25847 "RENDERBUFFER_STENCIL_SIZE",
25848 "RENDERBUFFER_WIDTH",
25849 "RENDERER",
25850 "RENDERING_INTENT_ABSOLUTE_COLORIMETRIC",
25851 "RENDERING_INTENT_AUTO",
25852 "RENDERING_INTENT_PERCEPTUAL",
25853 "RENDERING_INTENT_RELATIVE_COLORIMETRIC",
25854 "RENDERING_INTENT_SATURATION",
25855 "RENDERING_INTENT_UNKNOWN",
25856 "RENDER_ATTACHMENT",
25857 "REPEAT",
25858 "REPLACE",
25859 "RG",
25860 "RG16F",
25861 "RG16I",
25862 "RG16UI",
25863 "RG32F",
25864 "RG32I",
25865 "RG32UI",
25866 "RG8",
25867 "RG8I",
25868 "RG8UI",
25869 "RG8_SNORM",
25870 "RGB",
25871 "RGB10_A2",
25872 "RGB10_A2UI",
25873 "RGB16F",
25874 "RGB16I",
25875 "RGB16UI",
25876 "RGB32F",
25877 "RGB32I",
25878 "RGB32UI",
25879 "RGB565",
25880 "RGB5_A1",
25881 "RGB8",
25882 "RGB8I",
25883 "RGB8UI",
25884 "RGB8_SNORM",
25885 "RGB9_E5",
25886 "RGBA",
25887 "RGBA16F",
25888 "RGBA16I",
25889 "RGBA16UI",
25890 "RGBA32F",
25891 "RGBA32I",
25892 "RGBA32UI",
25893 "RGBA4",
25894 "RGBA8",
25895 "RGBA8I",
25896 "RGBA8UI",
25897 "RGBA8_SNORM",
25898 "RGBA_INTEGER",
25899 "RGBColor",
25900 "RGB_INTEGER",
25901 "RG_INTEGER",
25902 "ROTATION_CLOCKWISE",
25903 "ROTATION_COUNTERCLOCKWISE",
25904 "RTCCertificate",
25905 "RTCDTMFSender",
25906 "RTCDTMFToneChangeEvent",
25907 "RTCDataChannel",
25908 "RTCDataChannelEvent",
25909 "RTCDtlsTransport",
25910 "RTCEncodedAudioFrame",
25911 "RTCEncodedVideoFrame",
25912 "RTCError",
25913 "RTCErrorEvent",
25914 "RTCIceCandidate",
25915 "RTCIceTransport",
25916 "RTCPeerConnection",
25917 "RTCPeerConnectionIceErrorEvent",
25918 "RTCPeerConnectionIceEvent",
25919 "RTCRtpReceiver",
25920 "RTCRtpScriptTransform",
25921 "RTCRtpSender",
25922 "RTCRtpTransceiver",
25923 "RTCSctpTransport",
25924 "RTCSessionDescription",
25925 "RTCStatsReport",
25926 "RTCTrackEvent",
25927 "RadioNodeList",
25928 "Range",
25929 "RangeError",
25930 "RangeException",
25931 "ReadableByteStreamController",
25932 "ReadableStream",
25933 "ReadableStreamBYOBReader",
25934 "ReadableStreamBYOBRequest",
25935 "ReadableStreamDefaultController",
25936 "ReadableStreamDefaultReader",
25937 "RecordErrorEvent",
25938 "Rect",
25939 "ReferenceError",
25940 "Reflect",
25941 "RegExp",
25942 "RelativeOrientationSensor",
25943 "RelativeTimeFormat",
25944 "RemotePlayback",
25945 "Report",
25946 "ReportBody",
25947 "ReportingObserver",
25948 "Request",
25949 "RequestUpdateCheckStatus",
25950 "ResizeObserver",
25951 "ResizeObserverEntry",
25952 "ResizeObserverSize",
25953 "Response",
25954 "RestrictionTarget",
25955 "RuntimeError",
25956 "SAMPLER_2D",
25957 "SAMPLER_2D_ARRAY",
25958 "SAMPLER_2D_ARRAY_SHADOW",
25959 "SAMPLER_2D_SHADOW",
25960 "SAMPLER_3D",
25961 "SAMPLER_BINDING",
25962 "SAMPLER_CUBE",
25963 "SAMPLER_CUBE_SHADOW",
25964 "SAMPLES",
25965 "SAMPLE_ALPHA_TO_COVERAGE",
25966 "SAMPLE_BUFFERS",
25967 "SAMPLE_COVERAGE",
25968 "SAMPLE_COVERAGE_INVERT",
25969 "SAMPLE_COVERAGE_VALUE",
25970 "SAWTOOTH",
25971 "SCHEDULED_STATE",
25972 "SCISSOR_BOX",
25973 "SCISSOR_TEST",
25974 "SCROLL_PAGE_DOWN",
25975 "SCROLL_PAGE_UP",
25976 "SDP_ANSWER",
25977 "SDP_OFFER",
25978 "SDP_PRANSWER",
25979 "SECURITY_ERR",
25980 "SELECT",
25981 "SEPARATE_ATTRIBS",
25982 "SERIALIZE_ERR",
25983 "SEVERITY_ERROR",
25984 "SEVERITY_FATAL_ERROR",
25985 "SEVERITY_WARNING",
25986 "SHADER_COMPILER",
25987 "SHADER_TYPE",
25988 "SHADING_LANGUAGE_VERSION",
25989 "SHIFT_MASK",
25990 "SHORT",
25991 "SHOWING",
25992 "SHOW_ALL",
25993 "SHOW_ATTRIBUTE",
25994 "SHOW_CDATA_SECTION",
25995 "SHOW_COMMENT",
25996 "SHOW_DOCUMENT",
25997 "SHOW_DOCUMENT_FRAGMENT",
25998 "SHOW_DOCUMENT_TYPE",
25999 "SHOW_ELEMENT",
26000 "SHOW_ENTITY",
26001 "SHOW_ENTITY_REFERENCE",
26002 "SHOW_NOTATION",
26003 "SHOW_PROCESSING_INSTRUCTION",
26004 "SHOW_TEXT",
26005 "SIGNALED",
26006 "SIGNED_NORMALIZED",
26007 "SINE",
26008 "SOUNDFIELD",
26009 "SQLException",
26010 "SQRT1_2",
26011 "SQRT2",
26012 "SQUARE",
26013 "SRC_ALPHA",
26014 "SRC_ALPHA_SATURATE",
26015 "SRC_COLOR",
26016 "SRGB",
26017 "SRGB8",
26018 "SRGB8_ALPHA8",
26019 "START_TO_END",
26020 "START_TO_START",
26021 "STATIC_COPY",
26022 "STATIC_DRAW",
26023 "STATIC_READ",
26024 "STENCIL",
26025 "STENCIL_ATTACHMENT",
26026 "STENCIL_BACK_FAIL",
26027 "STENCIL_BACK_FUNC",
26028 "STENCIL_BACK_PASS_DEPTH_FAIL",
26029 "STENCIL_BACK_PASS_DEPTH_PASS",
26030 "STENCIL_BACK_REF",
26031 "STENCIL_BACK_VALUE_MASK",
26032 "STENCIL_BACK_WRITEMASK",
26033 "STENCIL_BITS",
26034 "STENCIL_BUFFER_BIT",
26035 "STENCIL_CLEAR_VALUE",
26036 "STENCIL_FAIL",
26037 "STENCIL_FUNC",
26038 "STENCIL_INDEX",
26039 "STENCIL_INDEX8",
26040 "STENCIL_PASS_DEPTH_FAIL",
26041 "STENCIL_PASS_DEPTH_PASS",
26042 "STENCIL_REF",
26043 "STENCIL_TEST",
26044 "STENCIL_VALUE_MASK",
26045 "STENCIL_WRITEMASK",
26046 "STORAGE",
26047 "STORAGE_BINDING",
26048 "STREAM_COPY",
26049 "STREAM_DRAW",
26050 "STREAM_READ",
26051 "STRING_TYPE",
26052 "STYLE_RULE",
26053 "SUBPIXEL_BITS",
26054 "SUPPORTS_RULE",
26055 "SVGAElement",
26056 "SVGAltGlyphDefElement",
26057 "SVGAltGlyphElement",
26058 "SVGAltGlyphItemElement",
26059 "SVGAngle",
26060 "SVGAnimateColorElement",
26061 "SVGAnimateElement",
26062 "SVGAnimateMotionElement",
26063 "SVGAnimateTransformElement",
26064 "SVGAnimatedAngle",
26065 "SVGAnimatedBoolean",
26066 "SVGAnimatedEnumeration",
26067 "SVGAnimatedInteger",
26068 "SVGAnimatedLength",
26069 "SVGAnimatedLengthList",
26070 "SVGAnimatedNumber",
26071 "SVGAnimatedNumberList",
26072 "SVGAnimatedPreserveAspectRatio",
26073 "SVGAnimatedRect",
26074 "SVGAnimatedString",
26075 "SVGAnimatedTransformList",
26076 "SVGAnimationElement",
26077 "SVGCircleElement",
26078 "SVGClipPathElement",
26079 "SVGColor",
26080 "SVGComponentTransferFunctionElement",
26081 "SVGCursorElement",
26082 "SVGDefsElement",
26083 "SVGDescElement",
26084 "SVGDiscardElement",
26085 "SVGDocument",
26086 "SVGElement",
26087 "SVGElementInstance",
26088 "SVGElementInstanceList",
26089 "SVGEllipseElement",
26090 "SVGException",
26091 "SVGFEBlendElement",
26092 "SVGFEColorMatrixElement",
26093 "SVGFEComponentTransferElement",
26094 "SVGFECompositeElement",
26095 "SVGFEConvolveMatrixElement",
26096 "SVGFEDiffuseLightingElement",
26097 "SVGFEDisplacementMapElement",
26098 "SVGFEDistantLightElement",
26099 "SVGFEDropShadowElement",
26100 "SVGFEFloodElement",
26101 "SVGFEFuncAElement",
26102 "SVGFEFuncBElement",
26103 "SVGFEFuncGElement",
26104 "SVGFEFuncRElement",
26105 "SVGFEGaussianBlurElement",
26106 "SVGFEImageElement",
26107 "SVGFEMergeElement",
26108 "SVGFEMergeNodeElement",
26109 "SVGFEMorphologyElement",
26110 "SVGFEOffsetElement",
26111 "SVGFEPointLightElement",
26112 "SVGFESpecularLightingElement",
26113 "SVGFESpotLightElement",
26114 "SVGFETileElement",
26115 "SVGFETurbulenceElement",
26116 "SVGFilterElement",
26117 "SVGFontElement",
26118 "SVGFontFaceElement",
26119 "SVGFontFaceFormatElement",
26120 "SVGFontFaceNameElement",
26121 "SVGFontFaceSrcElement",
26122 "SVGFontFaceUriElement",
26123 "SVGForeignObjectElement",
26124 "SVGGElement",
26125 "SVGGeometryElement",
26126 "SVGGlyphElement",
26127 "SVGGlyphRefElement",
26128 "SVGGradientElement",
26129 "SVGGraphicsElement",
26130 "SVGHKernElement",
26131 "SVGImageElement",
26132 "SVGLength",
26133 "SVGLengthList",
26134 "SVGLineElement",
26135 "SVGLinearGradientElement",
26136 "SVGMPathElement",
26137 "SVGMarkerElement",
26138 "SVGMaskElement",
26139 "SVGMatrix",
26140 "SVGMetadataElement",
26141 "SVGMissingGlyphElement",
26142 "SVGNumber",
26143 "SVGNumberList",
26144 "SVGPaint",
26145 "SVGPathElement",
26146 "SVGPathSeg",
26147 "SVGPathSegArcAbs",
26148 "SVGPathSegArcRel",
26149 "SVGPathSegClosePath",
26150 "SVGPathSegCurvetoCubicAbs",
26151 "SVGPathSegCurvetoCubicRel",
26152 "SVGPathSegCurvetoCubicSmoothAbs",
26153 "SVGPathSegCurvetoCubicSmoothRel",
26154 "SVGPathSegCurvetoQuadraticAbs",
26155 "SVGPathSegCurvetoQuadraticRel",
26156 "SVGPathSegCurvetoQuadraticSmoothAbs",
26157 "SVGPathSegCurvetoQuadraticSmoothRel",
26158 "SVGPathSegLinetoAbs",
26159 "SVGPathSegLinetoHorizontalAbs",
26160 "SVGPathSegLinetoHorizontalRel",
26161 "SVGPathSegLinetoRel",
26162 "SVGPathSegLinetoVerticalAbs",
26163 "SVGPathSegLinetoVerticalRel",
26164 "SVGPathSegList",
26165 "SVGPathSegMovetoAbs",
26166 "SVGPathSegMovetoRel",
26167 "SVGPatternElement",
26168 "SVGPoint",
26169 "SVGPointList",
26170 "SVGPolygonElement",
26171 "SVGPolylineElement",
26172 "SVGPreserveAspectRatio",
26173 "SVGRadialGradientElement",
26174 "SVGRect",
26175 "SVGRectElement",
26176 "SVGRenderingIntent",
26177 "SVGSVGElement",
26178 "SVGScriptElement",
26179 "SVGSetElement",
26180 "SVGStopElement",
26181 "SVGStringList",
26182 "SVGStyleElement",
26183 "SVGSwitchElement",
26184 "SVGSymbolElement",
26185 "SVGTRefElement",
26186 "SVGTSpanElement",
26187 "SVGTextContentElement",
26188 "SVGTextElement",
26189 "SVGTextPathElement",
26190 "SVGTextPositioningElement",
26191 "SVGTitleElement",
26192 "SVGTransform",
26193 "SVGTransformList",
26194 "SVGUnitTypes",
26195 "SVGUseElement",
26196 "SVGVKernElement",
26197 "SVGViewElement",
26198 "SVGViewSpec",
26199 "SVGZoomAndPan",
26200 "SVGZoomEvent",
26201 "SVG_ANGLETYPE_DEG",
26202 "SVG_ANGLETYPE_GRAD",
26203 "SVG_ANGLETYPE_RAD",
26204 "SVG_ANGLETYPE_UNKNOWN",
26205 "SVG_ANGLETYPE_UNSPECIFIED",
26206 "SVG_CHANNEL_A",
26207 "SVG_CHANNEL_B",
26208 "SVG_CHANNEL_G",
26209 "SVG_CHANNEL_R",
26210 "SVG_CHANNEL_UNKNOWN",
26211 "SVG_COLORTYPE_CURRENTCOLOR",
26212 "SVG_COLORTYPE_RGBCOLOR",
26213 "SVG_COLORTYPE_RGBCOLOR_ICCCOLOR",
26214 "SVG_COLORTYPE_UNKNOWN",
26215 "SVG_EDGEMODE_DUPLICATE",
26216 "SVG_EDGEMODE_NONE",
26217 "SVG_EDGEMODE_UNKNOWN",
26218 "SVG_EDGEMODE_WRAP",
26219 "SVG_FEBLEND_MODE_COLOR",
26220 "SVG_FEBLEND_MODE_COLOR_BURN",
26221 "SVG_FEBLEND_MODE_COLOR_DODGE",
26222 "SVG_FEBLEND_MODE_DARKEN",
26223 "SVG_FEBLEND_MODE_DIFFERENCE",
26224 "SVG_FEBLEND_MODE_EXCLUSION",
26225 "SVG_FEBLEND_MODE_HARD_LIGHT",
26226 "SVG_FEBLEND_MODE_HUE",
26227 "SVG_FEBLEND_MODE_LIGHTEN",
26228 "SVG_FEBLEND_MODE_LUMINOSITY",
26229 "SVG_FEBLEND_MODE_MULTIPLY",
26230 "SVG_FEBLEND_MODE_NORMAL",
26231 "SVG_FEBLEND_MODE_OVERLAY",
26232 "SVG_FEBLEND_MODE_SATURATION",
26233 "SVG_FEBLEND_MODE_SCREEN",
26234 "SVG_FEBLEND_MODE_SOFT_LIGHT",
26235 "SVG_FEBLEND_MODE_UNKNOWN",
26236 "SVG_FECOLORMATRIX_TYPE_HUEROTATE",
26237 "SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA",
26238 "SVG_FECOLORMATRIX_TYPE_MATRIX",
26239 "SVG_FECOLORMATRIX_TYPE_SATURATE",
26240 "SVG_FECOLORMATRIX_TYPE_UNKNOWN",
26241 "SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE",
26242 "SVG_FECOMPONENTTRANSFER_TYPE_GAMMA",
26243 "SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY",
26244 "SVG_FECOMPONENTTRANSFER_TYPE_LINEAR",
26245 "SVG_FECOMPONENTTRANSFER_TYPE_TABLE",
26246 "SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN",
26247 "SVG_FECOMPOSITE_OPERATOR_ARITHMETIC",
26248 "SVG_FECOMPOSITE_OPERATOR_ATOP",
26249 "SVG_FECOMPOSITE_OPERATOR_IN",
26250 "SVG_FECOMPOSITE_OPERATOR_LIGHTER",
26251 "SVG_FECOMPOSITE_OPERATOR_OUT",
26252 "SVG_FECOMPOSITE_OPERATOR_OVER",
26253 "SVG_FECOMPOSITE_OPERATOR_UNKNOWN",
26254 "SVG_FECOMPOSITE_OPERATOR_XOR",
26255 "SVG_INVALID_VALUE_ERR",
26256 "SVG_LENGTHTYPE_CM",
26257 "SVG_LENGTHTYPE_EMS",
26258 "SVG_LENGTHTYPE_EXS",
26259 "SVG_LENGTHTYPE_IN",
26260 "SVG_LENGTHTYPE_MM",
26261 "SVG_LENGTHTYPE_NUMBER",
26262 "SVG_LENGTHTYPE_PC",
26263 "SVG_LENGTHTYPE_PERCENTAGE",
26264 "SVG_LENGTHTYPE_PT",
26265 "SVG_LENGTHTYPE_PX",
26266 "SVG_LENGTHTYPE_UNKNOWN",
26267 "SVG_MARKERUNITS_STROKEWIDTH",
26268 "SVG_MARKERUNITS_UNKNOWN",
26269 "SVG_MARKERUNITS_USERSPACEONUSE",
26270 "SVG_MARKER_ORIENT_ANGLE",
26271 "SVG_MARKER_ORIENT_AUTO",
26272 "SVG_MARKER_ORIENT_AUTO_START_REVERSE",
26273 "SVG_MARKER_ORIENT_UNKNOWN",
26274 "SVG_MASKTYPE_ALPHA",
26275 "SVG_MASKTYPE_LUMINANCE",
26276 "SVG_MATRIX_NOT_INVERTABLE",
26277 "SVG_MEETORSLICE_MEET",
26278 "SVG_MEETORSLICE_SLICE",
26279 "SVG_MEETORSLICE_UNKNOWN",
26280 "SVG_MORPHOLOGY_OPERATOR_DILATE",
26281 "SVG_MORPHOLOGY_OPERATOR_ERODE",
26282 "SVG_MORPHOLOGY_OPERATOR_UNKNOWN",
26283 "SVG_PAINTTYPE_CURRENTCOLOR",
26284 "SVG_PAINTTYPE_NONE",
26285 "SVG_PAINTTYPE_RGBCOLOR",
26286 "SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR",
26287 "SVG_PAINTTYPE_UNKNOWN",
26288 "SVG_PAINTTYPE_URI",
26289 "SVG_PAINTTYPE_URI_CURRENTCOLOR",
26290 "SVG_PAINTTYPE_URI_NONE",
26291 "SVG_PAINTTYPE_URI_RGBCOLOR",
26292 "SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR",
26293 "SVG_PRESERVEASPECTRATIO_NONE",
26294 "SVG_PRESERVEASPECTRATIO_UNKNOWN",
26295 "SVG_PRESERVEASPECTRATIO_XMAXYMAX",
26296 "SVG_PRESERVEASPECTRATIO_XMAXYMID",
26297 "SVG_PRESERVEASPECTRATIO_XMAXYMIN",
26298 "SVG_PRESERVEASPECTRATIO_XMIDYMAX",
26299 "SVG_PRESERVEASPECTRATIO_XMIDYMID",
26300 "SVG_PRESERVEASPECTRATIO_XMIDYMIN",
26301 "SVG_PRESERVEASPECTRATIO_XMINYMAX",
26302 "SVG_PRESERVEASPECTRATIO_XMINYMID",
26303 "SVG_PRESERVEASPECTRATIO_XMINYMIN",
26304 "SVG_SPREADMETHOD_PAD",
26305 "SVG_SPREADMETHOD_REFLECT",
26306 "SVG_SPREADMETHOD_REPEAT",
26307 "SVG_SPREADMETHOD_UNKNOWN",
26308 "SVG_STITCHTYPE_NOSTITCH",
26309 "SVG_STITCHTYPE_STITCH",
26310 "SVG_STITCHTYPE_UNKNOWN",
26311 "SVG_TRANSFORM_MATRIX",
26312 "SVG_TRANSFORM_ROTATE",
26313 "SVG_TRANSFORM_SCALE",
26314 "SVG_TRANSFORM_SKEWX",
26315 "SVG_TRANSFORM_SKEWY",
26316 "SVG_TRANSFORM_TRANSLATE",
26317 "SVG_TRANSFORM_UNKNOWN",
26318 "SVG_TURBULENCE_TYPE_FRACTALNOISE",
26319 "SVG_TURBULENCE_TYPE_TURBULENCE",
26320 "SVG_TURBULENCE_TYPE_UNKNOWN",
26321 "SVG_UNIT_TYPE_OBJECTBOUNDINGBOX",
26322 "SVG_UNIT_TYPE_UNKNOWN",
26323 "SVG_UNIT_TYPE_USERSPACEONUSE",
26324 "SVG_WRONG_TYPE_ERR",
26325 "SVG_ZOOMANDPAN_DISABLE",
26326 "SVG_ZOOMANDPAN_MAGNIFY",
26327 "SVG_ZOOMANDPAN_UNKNOWN",
26328 "SYNC_CONDITION",
26329 "SYNC_FENCE",
26330 "SYNC_FLAGS",
26331 "SYNC_FLUSH_COMMANDS_BIT",
26332 "SYNC_GPU_COMMANDS_COMPLETE",
26333 "SYNC_STATUS",
26334 "SYNTAX_ERR",
26335 "SavedPages",
26336 "Scheduler",
26337 "Scheduling",
26338 "Screen",
26339 "ScreenDetailed",
26340 "ScreenDetails",
26341 "ScreenOrientation",
26342 "Script",
26343 "ScriptProcessorNode",
26344 "ScrollAreaEvent",
26345 "ScrollTimeline",
26346 "SecurityPolicyViolationEvent",
26347 "Segmenter",
26348 "Selection",
26349 "Sensor",
26350 "SensorErrorEvent",
26351 "Serial",
26352 "SerialPort",
26353 "ServiceWorker",
26354 "ServiceWorkerContainer",
26355 "ServiceWorkerRegistration",
26356 "SessionDescription",
26357 "Set",
26358 "ShadowRoot",
26359 "SharedArrayBuffer",
26360 "SharedStorage",
26361 "SharedStorageAppendMethod",
26362 "SharedStorageClearMethod",
26363 "SharedStorageDeleteMethod",
26364 "SharedStorageModifierMethod",
26365 "SharedStorageSetMethod",
26366 "SharedStorageWorklet",
26367 "SharedWorker",
26368 "SharingState",
26369 "SimpleGestureEvent",
26370 "SnapEvent",
26371 "SourceBuffer",
26372 "SourceBufferList",
26373 "SpeechGrammar",
26374 "SpeechGrammarList",
26375 "SpeechRecognition",
26376 "SpeechRecognitionErrorEvent",
26377 "SpeechRecognitionEvent",
26378 "SpeechRecognitionPhrase",
26379 "SpeechSynthesis",
26380 "SpeechSynthesisErrorEvent",
26381 "SpeechSynthesisEvent",
26382 "SpeechSynthesisUtterance",
26383 "SpeechSynthesisVoice",
26384 "StaticRange",
26385 "StereoPannerNode",
26386 "StopIteration",
26387 "Storage",
26388 "StorageBucket",
26389 "StorageBucketManager",
26390 "StorageEvent",
26391 "StorageManager",
26392 "String",
26393 "StructType",
26394 "StylePropertyMap",
26395 "StylePropertyMapReadOnly",
26396 "StyleSheet",
26397 "StyleSheetList",
26398 "SubmitEvent",
26399 "Subscriber",
26400 "SubtleCrypto",
26401 "Summarizer",
26402 "SuppressedError",
26403 "SuspendError",
26404 "Suspending",
26405 "Symbol",
26406 "SyncManager",
26407 "SyntaxError",
26408 "TAB_ID_NONE",
26409 "TAB_INDEX_NONE",
26410 "TEMPORARY",
26411 "TEXTPATH_METHODTYPE_ALIGN",
26412 "TEXTPATH_METHODTYPE_STRETCH",
26413 "TEXTPATH_METHODTYPE_UNKNOWN",
26414 "TEXTPATH_SPACINGTYPE_AUTO",
26415 "TEXTPATH_SPACINGTYPE_EXACT",
26416 "TEXTPATH_SPACINGTYPE_UNKNOWN",
26417 "TEXTURE",
26418 "TEXTURE0",
26419 "TEXTURE1",
26420 "TEXTURE10",
26421 "TEXTURE11",
26422 "TEXTURE12",
26423 "TEXTURE13",
26424 "TEXTURE14",
26425 "TEXTURE15",
26426 "TEXTURE16",
26427 "TEXTURE17",
26428 "TEXTURE18",
26429 "TEXTURE19",
26430 "TEXTURE2",
26431 "TEXTURE20",
26432 "TEXTURE21",
26433 "TEXTURE22",
26434 "TEXTURE23",
26435 "TEXTURE24",
26436 "TEXTURE25",
26437 "TEXTURE26",
26438 "TEXTURE27",
26439 "TEXTURE28",
26440 "TEXTURE29",
26441 "TEXTURE3",
26442 "TEXTURE30",
26443 "TEXTURE31",
26444 "TEXTURE4",
26445 "TEXTURE5",
26446 "TEXTURE6",
26447 "TEXTURE7",
26448 "TEXTURE8",
26449 "TEXTURE9",
26450 "TEXTURE_2D",
26451 "TEXTURE_2D_ARRAY",
26452 "TEXTURE_3D",
26453 "TEXTURE_BASE_LEVEL",
26454 "TEXTURE_BINDING",
26455 "TEXTURE_BINDING_2D",
26456 "TEXTURE_BINDING_2D_ARRAY",
26457 "TEXTURE_BINDING_3D",
26458 "TEXTURE_BINDING_CUBE_MAP",
26459 "TEXTURE_COMPARE_FUNC",
26460 "TEXTURE_COMPARE_MODE",
26461 "TEXTURE_CUBE_MAP",
26462 "TEXTURE_CUBE_MAP_NEGATIVE_X",
26463 "TEXTURE_CUBE_MAP_NEGATIVE_Y",
26464 "TEXTURE_CUBE_MAP_NEGATIVE_Z",
26465 "TEXTURE_CUBE_MAP_POSITIVE_X",
26466 "TEXTURE_CUBE_MAP_POSITIVE_Y",
26467 "TEXTURE_CUBE_MAP_POSITIVE_Z",
26468 "TEXTURE_IMMUTABLE_FORMAT",
26469 "TEXTURE_IMMUTABLE_LEVELS",
26470 "TEXTURE_MAG_FILTER",
26471 "TEXTURE_MAX_ANISOTROPY_EXT",
26472 "TEXTURE_MAX_LEVEL",
26473 "TEXTURE_MAX_LOD",
26474 "TEXTURE_MIN_FILTER",
26475 "TEXTURE_MIN_LOD",
26476 "TEXTURE_WRAP_R",
26477 "TEXTURE_WRAP_S",
26478 "TEXTURE_WRAP_T",
26479 "TEXT_NODE",
26480 "TIMEOUT",
26481 "TIMEOUT_ERR",
26482 "TIMEOUT_EXPIRED",
26483 "TIMEOUT_IGNORED",
26484 "TOO_LARGE_ERR",
26485 "TRANSACTION_INACTIVE_ERR",
26486 "TRANSFORM_FEEDBACK",
26487 "TRANSFORM_FEEDBACK_ACTIVE",
26488 "TRANSFORM_FEEDBACK_BINDING",
26489 "TRANSFORM_FEEDBACK_BUFFER",
26490 "TRANSFORM_FEEDBACK_BUFFER_BINDING",
26491 "TRANSFORM_FEEDBACK_BUFFER_MODE",
26492 "TRANSFORM_FEEDBACK_BUFFER_SIZE",
26493 "TRANSFORM_FEEDBACK_BUFFER_START",
26494 "TRANSFORM_FEEDBACK_PAUSED",
26495 "TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN",
26496 "TRANSFORM_FEEDBACK_VARYINGS",
26497 "TRIANGLE",
26498 "TRIANGLES",
26499 "TRIANGLE_FAN",
26500 "TRIANGLE_STRIP",
26501 "TYPE_BACK_FORWARD",
26502 "TYPE_ERR",
26503 "TYPE_MISMATCH_ERR",
26504 "TYPE_NAVIGATE",
26505 "TYPE_RELOAD",
26506 "TYPE_RESERVED",
26507 "Tab",
26508 "TabStatus",
26509 "Table",
26510 "Tag",
26511 "TaskAttributionTiming",
26512 "TaskController",
26513 "TaskPriorityChangeEvent",
26514 "TaskSignal",
26515 "Temporal",
26516 "Text",
26517 "TextDecoder",
26518 "TextDecoderStream",
26519 "TextEncoder",
26520 "TextEncoderStream",
26521 "TextEvent",
26522 "TextFormat",
26523 "TextFormatUpdateEvent",
26524 "TextMetrics",
26525 "TextTrack",
26526 "TextTrackCue",
26527 "TextTrackCueList",
26528 "TextTrackList",
26529 "TextUpdateEvent",
26530 "TimeEvent",
26531 "TimeRanges",
26532 "ToggleEvent",
26533 "Touch",
26534 "TouchEvent",
26535 "TouchList",
26536 "TrackEvent",
26537 "TransformStream",
26538 "TransformStreamDefaultController",
26539 "TransitionEvent",
26540 "Translator",
26541 "TreeWalker",
26542 "TrustedHTML",
26543 "TrustedScript",
26544 "TrustedScriptURL",
26545 "TrustedTypePolicy",
26546 "TrustedTypePolicyFactory",
26547 "TypeError",
26548 "TypedObject",
26549 "U2F",
26550 "UIEvent",
26551 "UNCACHED",
26552 "UNIFORM",
26553 "UNIFORM_ARRAY_STRIDE",
26554 "UNIFORM_BLOCK_ACTIVE_UNIFORMS",
26555 "UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES",
26556 "UNIFORM_BLOCK_BINDING",
26557 "UNIFORM_BLOCK_DATA_SIZE",
26558 "UNIFORM_BLOCK_INDEX",
26559 "UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER",
26560 "UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER",
26561 "UNIFORM_BUFFER",
26562 "UNIFORM_BUFFER_BINDING",
26563 "UNIFORM_BUFFER_OFFSET_ALIGNMENT",
26564 "UNIFORM_BUFFER_SIZE",
26565 "UNIFORM_BUFFER_START",
26566 "UNIFORM_IS_ROW_MAJOR",
26567 "UNIFORM_MATRIX_STRIDE",
26568 "UNIFORM_OFFSET",
26569 "UNIFORM_SIZE",
26570 "UNIFORM_TYPE",
26571 "UNKNOWN_ERR",
26572 "UNKNOWN_RULE",
26573 "UNMASKED_RENDERER_WEBGL",
26574 "UNMASKED_VENDOR_WEBGL",
26575 "UNORDERED_NODE_ITERATOR_TYPE",
26576 "UNORDERED_NODE_SNAPSHOT_TYPE",
26577 "UNPACK_ALIGNMENT",
26578 "UNPACK_COLORSPACE_CONVERSION_WEBGL",
26579 "UNPACK_FLIP_Y_WEBGL",
26580 "UNPACK_IMAGE_HEIGHT",
26581 "UNPACK_PREMULTIPLY_ALPHA_WEBGL",
26582 "UNPACK_ROW_LENGTH",
26583 "UNPACK_SKIP_IMAGES",
26584 "UNPACK_SKIP_PIXELS",
26585 "UNPACK_SKIP_ROWS",
26586 "UNSCHEDULED_STATE",
26587 "UNSENT",
26588 "UNSIGNALED",
26589 "UNSIGNED_BYTE",
26590 "UNSIGNED_INT",
26591 "UNSIGNED_INT_10F_11F_11F_REV",
26592 "UNSIGNED_INT_24_8",
26593 "UNSIGNED_INT_2_10_10_10_REV",
26594 "UNSIGNED_INT_5_9_9_9_REV",
26595 "UNSIGNED_INT_SAMPLER_2D",
26596 "UNSIGNED_INT_SAMPLER_2D_ARRAY",
26597 "UNSIGNED_INT_SAMPLER_3D",
26598 "UNSIGNED_INT_SAMPLER_CUBE",
26599 "UNSIGNED_INT_VEC2",
26600 "UNSIGNED_INT_VEC3",
26601 "UNSIGNED_INT_VEC4",
26602 "UNSIGNED_NORMALIZED",
26603 "UNSIGNED_SHORT",
26604 "UNSIGNED_SHORT_4_4_4_4",
26605 "UNSIGNED_SHORT_5_5_5_1",
26606 "UNSIGNED_SHORT_5_6_5",
26607 "UNSPECIFIED_EVENT_TYPE_ERR",
26608 "UPDATEREADY",
26609 "URIError",
26610 "URL",
26611 "URLPattern",
26612 "URLSearchParams",
26613 "URLUnencoded",
26614 "URL_MISMATCH_ERR",
26615 "USB",
26616 "USBAlternateInterface",
26617 "USBConfiguration",
26618 "USBConnectionEvent",
26619 "USBDevice",
26620 "USBEndpoint",
26621 "USBInTransferResult",
26622 "USBInterface",
26623 "USBIsochronousInTransferPacket",
26624 "USBIsochronousInTransferResult",
26625 "USBIsochronousOutTransferPacket",
26626 "USBIsochronousOutTransferResult",
26627 "USBOutTransferResult",
26628 "UTC",
26629 "Uint16Array",
26630 "Uint32Array",
26631 "Uint8Array",
26632 "Uint8ClampedArray",
26633 "UpdateFilter",
26634 "UpdatePropertyName",
26635 "UserActivation",
26636 "UserMessageHandler",
26637 "UserMessageHandlersNamespace",
26638 "UserProximityEvent",
26639 "VALIDATE_STATUS",
26640 "VALIDATION_ERR",
26641 "VARIABLES_RULE",
26642 "VENDOR",
26643 "VERSION",
26644 "VERSION_CHANGE",
26645 "VERSION_ERR",
26646 "VERTEX",
26647 "VERTEX_ARRAY_BINDING",
26648 "VERTEX_ATTRIB_ARRAY_BUFFER_BINDING",
26649 "VERTEX_ATTRIB_ARRAY_DIVISOR",
26650 "VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE",
26651 "VERTEX_ATTRIB_ARRAY_ENABLED",
26652 "VERTEX_ATTRIB_ARRAY_INTEGER",
26653 "VERTEX_ATTRIB_ARRAY_NORMALIZED",
26654 "VERTEX_ATTRIB_ARRAY_POINTER",
26655 "VERTEX_ATTRIB_ARRAY_SIZE",
26656 "VERTEX_ATTRIB_ARRAY_STRIDE",
26657 "VERTEX_ATTRIB_ARRAY_TYPE",
26658 "VERTEX_SHADER",
26659 "VERTICAL",
26660 "VERTICAL_AXIS",
26661 "VER_ERR",
26662 "VIEWPORT",
26663 "VIEWPORT_RULE",
26664 "VRDisplay",
26665 "VRDisplayCapabilities",
26666 "VRDisplayEvent",
26667 "VREyeParameters",
26668 "VRFieldOfView",
26669 "VRFrameData",
26670 "VRPose",
26671 "VRStageParameters",
26672 "VTTCue",
26673 "VTTRegion",
26674 "ValidityState",
26675 "VideoColorSpace",
26676 "VideoDecoder",
26677 "VideoEncoder",
26678 "VideoFrame",
26679 "VideoPlaybackQuality",
26680 "VideoStreamTrack",
26681 "ViewTimeline",
26682 "ViewTransition",
26683 "ViewTransitionTypeSet",
26684 "ViewType",
26685 "Viewport",
26686 "VirtualKeyboard",
26687 "VirtualKeyboardGeometryChangeEvent",
26688 "VisibilityStateEntry",
26689 "VisualViewport",
26690 "WAIT_FAILED",
26691 "WEBKIT_FILTER_RULE",
26692 "WEBKIT_KEYFRAMES_RULE",
26693 "WEBKIT_KEYFRAME_RULE",
26694 "WEBKIT_REGION_RULE",
26695 "WGSLLanguageFeatures",
26696 "WINDOW_ID_CURRENT",
26697 "WINDOW_ID_NONE",
26698 "WRITE",
26699 "WRONG_DOCUMENT_ERR",
26700 "WakeLock",
26701 "WakeLockSentinel",
26702 "WasmAnyRef",
26703 "WaveShaperNode",
26704 "WeakMap",
26705 "WeakRef",
26706 "WeakSet",
26707 "WebAssembly",
26708 "WebGL2RenderingContext",
26709 "WebGLActiveInfo",
26710 "WebGLBuffer",
26711 "WebGLContextEvent",
26712 "WebGLFramebuffer",
26713 "WebGLObject",
26714 "WebGLProgram",
26715 "WebGLQuery",
26716 "WebGLRenderbuffer",
26717 "WebGLRenderingContext",
26718 "WebGLSampler",
26719 "WebGLShader",
26720 "WebGLShaderPrecisionFormat",
26721 "WebGLSync",
26722 "WebGLTexture",
26723 "WebGLTransformFeedback",
26724 "WebGLUniformLocation",
26725 "WebGLVertexArray",
26726 "WebGLVertexArrayObject",
26727 "WebKitAnimationEvent",
26728 "WebKitBlobBuilder",
26729 "WebKitCSSFilterRule",
26730 "WebKitCSSFilterValue",
26731 "WebKitCSSKeyframeRule",
26732 "WebKitCSSKeyframesRule",
26733 "WebKitCSSMatrix",
26734 "WebKitCSSRegionRule",
26735 "WebKitCSSTransformValue",
26736 "WebKitDataCue",
26737 "WebKitGamepad",
26738 "WebKitMediaKeyError",
26739 "WebKitMediaKeyMessageEvent",
26740 "WebKitMediaKeySession",
26741 "WebKitMediaKeys",
26742 "WebKitMediaSource",
26743 "WebKitMutationObserver",
26744 "WebKitNamespace",
26745 "WebKitPlaybackTargetAvailabilityEvent",
26746 "WebKitPoint",
26747 "WebKitShadowRoot",
26748 "WebKitSourceBuffer",
26749 "WebKitSourceBufferList",
26750 "WebKitTransitionEvent",
26751 "WebSocket",
26752 "WebSocketError",
26753 "WebSocketStream",
26754 "WebTransport",
26755 "WebTransportBidirectionalStream",
26756 "WebTransportDatagramDuplexStream",
26757 "WebTransportError",
26758 "WebTransportReceiveStream",
26759 "WebTransportSendStream",
26760 "WebkitAlignContent",
26761 "WebkitAlignItems",
26762 "WebkitAlignSelf",
26763 "WebkitAnimation",
26764 "WebkitAnimationDelay",
26765 "WebkitAnimationDirection",
26766 "WebkitAnimationDuration",
26767 "WebkitAnimationFillMode",
26768 "WebkitAnimationIterationCount",
26769 "WebkitAnimationName",
26770 "WebkitAnimationPlayState",
26771 "WebkitAnimationTimingFunction",
26772 "WebkitAppearance",
26773 "WebkitBackfaceVisibility",
26774 "WebkitBackgroundClip",
26775 "WebkitBackgroundOrigin",
26776 "WebkitBackgroundSize",
26777 "WebkitBorderBottomLeftRadius",
26778 "WebkitBorderBottomRightRadius",
26779 "WebkitBorderImage",
26780 "WebkitBorderRadius",
26781 "WebkitBorderTopLeftRadius",
26782 "WebkitBorderTopRightRadius",
26783 "WebkitBoxAlign",
26784 "WebkitBoxDirection",
26785 "WebkitBoxFlex",
26786 "WebkitBoxOrdinalGroup",
26787 "WebkitBoxOrient",
26788 "WebkitBoxPack",
26789 "WebkitBoxShadow",
26790 "WebkitBoxSizing",
26791 "WebkitClipPath",
26792 "WebkitFilter",
26793 "WebkitFlex",
26794 "WebkitFlexBasis",
26795 "WebkitFlexDirection",
26796 "WebkitFlexFlow",
26797 "WebkitFlexGrow",
26798 "WebkitFlexShrink",
26799 "WebkitFlexWrap",
26800 "WebkitFontFeatureSettings",
26801 "WebkitJustifyContent",
26802 "WebkitLineClamp",
26803 "WebkitMask",
26804 "WebkitMaskClip",
26805 "WebkitMaskComposite",
26806 "WebkitMaskImage",
26807 "WebkitMaskOrigin",
26808 "WebkitMaskPosition",
26809 "WebkitMaskPositionX",
26810 "WebkitMaskPositionY",
26811 "WebkitMaskRepeat",
26812 "WebkitMaskSize",
26813 "WebkitOrder",
26814 "WebkitPerspective",
26815 "WebkitPerspectiveOrigin",
26816 "WebkitTextFillColor",
26817 "WebkitTextSecurity",
26818 "WebkitTextSizeAdjust",
26819 "WebkitTextStroke",
26820 "WebkitTextStrokeColor",
26821 "WebkitTextStrokeWidth",
26822 "WebkitTransform",
26823 "WebkitTransformOrigin",
26824 "WebkitTransformStyle",
26825 "WebkitTransition",
26826 "WebkitTransitionDelay",
26827 "WebkitTransitionDuration",
26828 "WebkitTransitionProperty",
26829 "WebkitTransitionTimingFunction",
26830 "WebkitUserSelect",
26831 "WheelEvent",
26832 "Window",
26833 "WindowControlsOverlay",
26834 "WindowControlsOverlayGeometryChangeEvent",
26835 "WindowState",
26836 "WindowType",
26837 "Worker",
26838 "Worklet",
26839 "WritableStream",
26840 "WritableStreamDefaultController",
26841 "WritableStreamDefaultWriter",
26842 "XMLDocument",
26843 "XMLHttpRequest",
26844 "XMLHttpRequestEventTarget",
26845 "XMLHttpRequestException",
26846 "XMLHttpRequestProgressEvent",
26847 "XMLHttpRequestUpload",
26848 "XMLSerializer",
26849 "XMLStylesheetProcessingInstruction",
26850 "XPathEvaluator",
26851 "XPathException",
26852 "XPathExpression",
26853 "XPathNSResolver",
26854 "XPathResult",
26855 "XRAnchor",
26856 "XRAnchorSet",
26857 "XRBoundedReferenceSpace",
26858 "XRCPUDepthInformation",
26859 "XRCamera",
26860 "XRDOMOverlayState",
26861 "XRDepthInformation",
26862 "XRFrame",
26863 "XRHand",
26864 "XRHitTestResult",
26865 "XRHitTestSource",
26866 "XRInputSource",
26867 "XRInputSourceArray",
26868 "XRInputSourceEvent",
26869 "XRInputSourcesChangeEvent",
26870 "XRJointPose",
26871 "XRJointSpace",
26872 "XRLayer",
26873 "XRLightEstimate",
26874 "XRLightProbe",
26875 "XRPose",
26876 "XRRay",
26877 "XRReferenceSpace",
26878 "XRReferenceSpaceEvent",
26879 "XRRenderState",
26880 "XRRigidTransform",
26881 "XRSession",
26882 "XRSessionEvent",
26883 "XRSpace",
26884 "XRSystem",
26885 "XRTransientInputHitTestResult",
26886 "XRTransientInputHitTestSource",
26887 "XRView",
26888 "XRViewerPose",
26889 "XRViewport",
26890 "XRWebGLBinding",
26891 "XRWebGLDepthInformation",
26892 "XRWebGLLayer",
26893 "XSLTProcessor",
26894 "ZERO",
26895 "ZonedDateTime",
26896 "ZoomSettings",
26897 "ZoomSettingsMode",
26898 "ZoomSettingsScope",
26899 "_XD0M_",
26900 "_YD0M_",
26901 "__REACT_DEVTOOLS_GLOBAL_HOOK__",
26902 "__brand",
26903 "__defineGetter__",
26904 "__defineSetter__",
26905 "__lookupGetter__",
26906 "__lookupSetter__",
26907 "__opera",
26908 "__proto__",
26909 "_browserjsran",
26910 "a",
26911 "aLink",
26912 "abbr",
26913 "abort",
26914 "aborted",
26915 "aboutConfigPrefs",
26916 "abs",
26917 "absolute",
26918 "acceleration",
26919 "accelerationIncludingGravity",
26920 "accelerator",
26921 "accent-color",
26922 "accentColor",
26923 "accept",
26924 "acceptCharset",
26925 "acceptNode",
26926 "access",
26927 "accessKey",
26928 "accessKeyLabel",
26929 "accuracy",
26930 "acos",
26931 "acosh",
26932 "action",
26933 "actionURL",
26934 "actions",
26935 "activated",
26936 "activation",
26937 "activationStart",
26938 "active",
26939 "activeCues",
26940 "activeElement",
26941 "activeSourceBuffers",
26942 "activeSourceCount",
26943 "activeTexture",
26944 "activeVRDisplays",
26945 "activeViewTransition",
26946 "activityLog",
26947 "actualBoundingBoxAscent",
26948 "actualBoundingBoxDescent",
26949 "actualBoundingBoxLeft",
26950 "actualBoundingBoxRight",
26951 "adAuctionComponents",
26952 "adAuctionHeaders",
26953 "adapterInfo",
26954 "add",
26955 "addAll",
26956 "addBehavior",
26957 "addCandidate",
26958 "addColorStop",
26959 "addCue",
26960 "addElement",
26961 "addEventListener",
26962 "addFilter",
26963 "addFromString",
26964 "addFromUri",
26965 "addIceCandidate",
26966 "addImport",
26967 "addListener",
26968 "addModule",
26969 "addNamed",
26970 "addPageRule",
26971 "addPath",
26972 "addPointer",
26973 "addRange",
26974 "addRegion",
26975 "addRule",
26976 "addSearchEngine",
26977 "addSourceBuffer",
26978 "addStream",
26979 "addTeardown",
26980 "addTextTrack",
26981 "addTrack",
26982 "addTransceiver",
26983 "addWakeLockListener",
26984 "added",
26985 "addedNodes",
26986 "additionalName",
26987 "additiveSymbols",
26988 "addons",
26989 "address",
26990 "addressLine",
26991 "addressModeU",
26992 "addressModeV",
26993 "addressModeW",
26994 "adopt",
26995 "adoptNode",
26996 "adoptedCallback",
26997 "adoptedStyleSheets",
26998 "adr",
26999 "advance",
27000 "after",
27001 "alarms",
27002 "album",
27003 "alert",
27004 "algorithm",
27005 "align",
27006 "align-content",
27007 "align-items",
27008 "align-self",
27009 "alignContent",
27010 "alignItems",
27011 "alignSelf",
27012 "alignmentBaseline",
27013 "alinkColor",
27014 "all",
27015 "allSettled",
27016 "allocationSize",
27017 "allow",
27018 "allowFullscreen",
27019 "allowPaymentRequest",
27020 "allowedDirections",
27021 "allowedFeatures",
27022 "allowedToPlay",
27023 "allowsFeature",
27024 "alpha",
27025 "alphaMode",
27026 "alphaToCoverageEnabled",
27027 "alphabeticBaseline",
27028 "alt",
27029 "altGraphKey",
27030 "altHtml",
27031 "altKey",
27032 "altLeft",
27033 "alternate",
27034 "alternateSetting",
27035 "alternates",
27036 "altitude",
27037 "altitudeAccuracy",
27038 "altitudeAngle",
27039 "amplitude",
27040 "ancestorOrigins",
27041 "anchor",
27042 "anchorName",
27043 "anchorNode",
27044 "anchorOffset",
27045 "anchorScope",
27046 "anchorSpace",
27047 "anchors",
27048 "and",
27049 "angle",
27050 "angularAcceleration",
27051 "angularVelocity",
27052 "animVal",
27053 "animate",
27054 "animated",
27055 "animatedInstanceRoot",
27056 "animatedNormalizedPathSegList",
27057 "animatedPathSegList",
27058 "animatedPoints",
27059 "animation",
27060 "animation-composition",
27061 "animation-delay",
27062 "animation-direction",
27063 "animation-duration",
27064 "animation-fill-mode",
27065 "animation-iteration-count",
27066 "animation-name",
27067 "animation-play-state",
27068 "animation-timing-function",
27069 "animationComposition",
27070 "animationDelay",
27071 "animationDirection",
27072 "animationDuration",
27073 "animationFillMode",
27074 "animationIterationCount",
27075 "animationName",
27076 "animationPlayState",
27077 "animationStartTime",
27078 "animationTimingFunction",
27079 "animationsPaused",
27080 "anniversary",
27081 "annotation",
27082 "antialias",
27083 "anticipatedRemoval",
27084 "any",
27085 "app",
27086 "appCodeName",
27087 "appMinorVersion",
27088 "appName",
27089 "appNotifications",
27090 "appVersion",
27091 "appearance",
27092 "append",
27093 "appendBuffer",
27094 "appendChild",
27095 "appendData",
27096 "appendItem",
27097 "appendMedium",
27098 "appendNamed",
27099 "appendRule",
27100 "appendStream",
27101 "appendWindowEnd",
27102 "appendWindowStart",
27103 "applets",
27104 "applicationCache",
27105 "applicationServerKey",
27106 "apply",
27107 "applyConstraints",
27108 "applyElement",
27109 "arc",
27110 "arcTo",
27111 "arch",
27112 "architecture",
27113 "archive",
27114 "areas",
27115 "arguments",
27116 "ariaActiveDescendantElement",
27117 "ariaAtomic",
27118 "ariaAutoComplete",
27119 "ariaBrailleLabel",
27120 "ariaBrailleRoleDescription",
27121 "ariaBusy",
27122 "ariaChecked",
27123 "ariaColCount",
27124 "ariaColIndex",
27125 "ariaColIndexText",
27126 "ariaColSpan",
27127 "ariaControlsElements",
27128 "ariaCurrent",
27129 "ariaDescribedByElements",
27130 "ariaDescription",
27131 "ariaDetailsElements",
27132 "ariaDisabled",
27133 "ariaErrorMessageElements",
27134 "ariaExpanded",
27135 "ariaFlowToElements",
27136 "ariaHasPopup",
27137 "ariaHidden",
27138 "ariaInvalid",
27139 "ariaKeyShortcuts",
27140 "ariaLabel",
27141 "ariaLabelledByElements",
27142 "ariaLevel",
27143 "ariaLive",
27144 "ariaModal",
27145 "ariaMultiLine",
27146 "ariaMultiSelectable",
27147 "ariaNotify",
27148 "ariaOrientation",
27149 "ariaOwnsElements",
27150 "ariaPlaceholder",
27151 "ariaPosInSet",
27152 "ariaPressed",
27153 "ariaReadOnly",
27154 "ariaRelevant",
27155 "ariaRequired",
27156 "ariaRoleDescription",
27157 "ariaRowCount",
27158 "ariaRowIndex",
27159 "ariaRowIndexText",
27160 "ariaRowSpan",
27161 "ariaSelected",
27162 "ariaSetSize",
27163 "ariaSort",
27164 "ariaValueMax",
27165 "ariaValueMin",
27166 "ariaValueNow",
27167 "ariaValueText",
27168 "arrayBuffer",
27169 "arrayLayerCount",
27170 "arrayStride",
27171 "artist",
27172 "artwork",
27173 "as",
27174 "asIntN",
27175 "asUintN",
27176 "ascentOverride",
27177 "asin",
27178 "asinh",
27179 "aspect",
27180 "aspect-ratio",
27181 "aspectRatio",
27182 "assert",
27183 "assign",
27184 "assignedElements",
27185 "assignedNodes",
27186 "assignedSlot",
27187 "async",
27188 "asyncDispose",
27189 "asyncIterator",
27190 "at",
27191 "atEnd",
27192 "atan",
27193 "atan2",
27194 "atanh",
27195 "atob",
27196 "attachEvent",
27197 "attachInternals",
27198 "attachShader",
27199 "attachShadow",
27200 "attachedElements",
27201 "attachments",
27202 "attack",
27203 "attestationObject",
27204 "attrChange",
27205 "attrName",
27206 "attributeChangedCallback",
27207 "attributeFilter",
27208 "attributeName",
27209 "attributeNamespace",
27210 "attributeOldValue",
27211 "attributeStyleMap",
27212 "attributes",
27213 "attribution",
27214 "attributionSrc",
27215 "audioBitrateMode",
27216 "audioBitsPerSecond",
27217 "audioTracks",
27218 "audioWorklet",
27219 "authenticatedSignedWrites",
27220 "authenticatorAttachment",
27221 "authenticatorData",
27222 "autoIncrement",
27223 "autobuffer",
27224 "autocapitalize",
27225 "autocomplete",
27226 "autocorrect",
27227 "autofocus",
27228 "automationRate",
27229 "autoplay",
27230 "availHeight",
27231 "availLeft",
27232 "availTop",
27233 "availWidth",
27234 "availability",
27235 "available",
27236 "averageLatency",
27237 "aversion",
27238 "ax",
27239 "axes",
27240 "axis",
27241 "ay",
27242 "azimuth",
27243 "azimuthAngle",
27244 "b",
27245 "back",
27246 "backdrop-filter",
27247 "backdropFilter",
27248 "backends",
27249 "backface-visibility",
27250 "backfaceVisibility",
27251 "background",
27252 "background-attachment",
27253 "background-blend-mode",
27254 "background-clip",
27255 "background-color",
27256 "background-image",
27257 "background-origin",
27258 "background-position",
27259 "background-position-x",
27260 "background-position-y",
27261 "background-repeat",
27262 "background-size",
27263 "backgroundAttachment",
27264 "backgroundBlendMode",
27265 "backgroundClip",
27266 "backgroundColor",
27267 "backgroundFetch",
27268 "backgroundImage",
27269 "backgroundOrigin",
27270 "backgroundPosition",
27271 "backgroundPositionX",
27272 "backgroundPositionY",
27273 "backgroundRepeat",
27274 "backgroundSize",
27275 "badInput",
27276 "badge",
27277 "balance",
27278 "baseArrayLayer",
27279 "baseFrequencyX",
27280 "baseFrequencyY",
27281 "baseLatency",
27282 "baseLayer",
27283 "baseMipLevel",
27284 "baseNode",
27285 "baseOffset",
27286 "basePalette",
27287 "baseURI",
27288 "baseVal",
27289 "baseline-source",
27290 "baselineShift",
27291 "baselineSource",
27292 "batchUpdate",
27293 "battery",
27294 "bday",
27295 "before",
27296 "beginComputePass",
27297 "beginElement",
27298 "beginElementAt",
27299 "beginOcclusionQuery",
27300 "beginPath",
27301 "beginQuery",
27302 "beginRenderPass",
27303 "beginTransformFeedback",
27304 "beginningOfPassWriteIndex",
27305 "behavior",
27306 "behaviorCookie",
27307 "behaviorPart",
27308 "behaviorUrns",
27309 "beta",
27310 "bezierCurveTo",
27311 "bgColor",
27312 "bgProperties",
27313 "bias",
27314 "big",
27315 "bigint64",
27316 "biguint64",
27317 "binaryType",
27318 "bind",
27319 "bindAttribLocation",
27320 "bindBuffer",
27321 "bindBufferBase",
27322 "bindBufferRange",
27323 "bindFramebuffer",
27324 "bindGroupLayouts",
27325 "bindRenderbuffer",
27326 "bindSampler",
27327 "bindTexture",
27328 "bindTransformFeedback",
27329 "bindVertexArray",
27330 "binding",
27331 "bitness",
27332 "blend",
27333 "blendColor",
27334 "blendEquation",
27335 "blendEquationSeparate",
27336 "blendFunc",
27337 "blendFuncSeparate",
27338 "blink",
27339 "blitFramebuffer",
27340 "blob",
27341 "block-size",
27342 "blockDirection",
27343 "blockSize",
27344 "blockedURI",
27345 "blockedURL",
27346 "blocking",
27347 "blockingDuration",
27348 "blue",
27349 "bluetooth",
27350 "blur",
27351 "body",
27352 "bodyUsed",
27353 "bold",
27354 "bookmarks",
27355 "booleanValue",
27356 "boost",
27357 "border",
27358 "border-block",
27359 "border-block-color",
27360 "border-block-end",
27361 "border-block-end-color",
27362 "border-block-end-style",
27363 "border-block-end-width",
27364 "border-block-start",
27365 "border-block-start-color",
27366 "border-block-start-style",
27367 "border-block-start-width",
27368 "border-block-style",
27369 "border-block-width",
27370 "border-bottom",
27371 "border-bottom-color",
27372 "border-bottom-left-radius",
27373 "border-bottom-right-radius",
27374 "border-bottom-style",
27375 "border-bottom-width",
27376 "border-collapse",
27377 "border-color",
27378 "border-end-end-radius",
27379 "border-end-start-radius",
27380 "border-image",
27381 "border-image-outset",
27382 "border-image-repeat",
27383 "border-image-slice",
27384 "border-image-source",
27385 "border-image-width",
27386 "border-inline",
27387 "border-inline-color",
27388 "border-inline-end",
27389 "border-inline-end-color",
27390 "border-inline-end-style",
27391 "border-inline-end-width",
27392 "border-inline-start",
27393 "border-inline-start-color",
27394 "border-inline-start-style",
27395 "border-inline-start-width",
27396 "border-inline-style",
27397 "border-inline-width",
27398 "border-left",
27399 "border-left-color",
27400 "border-left-style",
27401 "border-left-width",
27402 "border-radius",
27403 "border-right",
27404 "border-right-color",
27405 "border-right-style",
27406 "border-right-width",
27407 "border-spacing",
27408 "border-start-end-radius",
27409 "border-start-start-radius",
27410 "border-style",
27411 "border-top",
27412 "border-top-color",
27413 "border-top-left-radius",
27414 "border-top-right-radius",
27415 "border-top-style",
27416 "border-top-width",
27417 "border-width",
27418 "borderBlock",
27419 "borderBlockColor",
27420 "borderBlockEnd",
27421 "borderBlockEndColor",
27422 "borderBlockEndStyle",
27423 "borderBlockEndWidth",
27424 "borderBlockStart",
27425 "borderBlockStartColor",
27426 "borderBlockStartStyle",
27427 "borderBlockStartWidth",
27428 "borderBlockStyle",
27429 "borderBlockWidth",
27430 "borderBottom",
27431 "borderBottomColor",
27432 "borderBottomLeftRadius",
27433 "borderBottomRightRadius",
27434 "borderBottomStyle",
27435 "borderBottomWidth",
27436 "borderBoxSize",
27437 "borderCollapse",
27438 "borderColor",
27439 "borderColorDark",
27440 "borderColorLight",
27441 "borderEndEndRadius",
27442 "borderEndStartRadius",
27443 "borderImage",
27444 "borderImageOutset",
27445 "borderImageRepeat",
27446 "borderImageSlice",
27447 "borderImageSource",
27448 "borderImageWidth",
27449 "borderInline",
27450 "borderInlineColor",
27451 "borderInlineEnd",
27452 "borderInlineEndColor",
27453 "borderInlineEndStyle",
27454 "borderInlineEndWidth",
27455 "borderInlineStart",
27456 "borderInlineStartColor",
27457 "borderInlineStartStyle",
27458 "borderInlineStartWidth",
27459 "borderInlineStyle",
27460 "borderInlineWidth",
27461 "borderLeft",
27462 "borderLeftColor",
27463 "borderLeftStyle",
27464 "borderLeftWidth",
27465 "borderRadius",
27466 "borderRight",
27467 "borderRightColor",
27468 "borderRightStyle",
27469 "borderRightWidth",
27470 "borderSpacing",
27471 "borderStartEndRadius",
27472 "borderStartStartRadius",
27473 "borderStyle",
27474 "borderTop",
27475 "borderTopColor",
27476 "borderTopLeftRadius",
27477 "borderTopRightRadius",
27478 "borderTopStyle",
27479 "borderTopWidth",
27480 "borderWidth",
27481 "bottom",
27482 "bottomMargin",
27483 "bound",
27484 "boundElements",
27485 "boundingClientRect",
27486 "boundingHeight",
27487 "boundingLeft",
27488 "boundingRect",
27489 "boundingTop",
27490 "boundingWidth",
27491 "bounds",
27492 "boundsGeometry",
27493 "box-decoration-break",
27494 "box-shadow",
27495 "box-sizing",
27496 "boxDecorationBreak",
27497 "boxShadow",
27498 "boxSizing",
27499 "brand",
27500 "brands",
27501 "break-after",
27502 "break-before",
27503 "break-inside",
27504 "breakAfter",
27505 "breakBefore",
27506 "breakInside",
27507 "broadcast",
27508 "browser",
27509 "browserLanguage",
27510 "browserSettings",
27511 "browsingData",
27512 "browsingTopics",
27513 "btoa",
27514 "bubbles",
27515 "buffer",
27516 "bufferData",
27517 "bufferDepth",
27518 "bufferSize",
27519 "bufferSubData",
27520 "buffered",
27521 "bufferedAmount",
27522 "bufferedAmountLowThreshold",
27523 "buffers",
27524 "buildID",
27525 "buildNumber",
27526 "button",
27527 "buttonID",
27528 "buttons",
27529 "byobRequest",
27530 "byteLength",
27531 "byteOffset",
27532 "bytes",
27533 "bytesPerRow",
27534 "bytesWritten",
27535 "c",
27536 "cache",
27537 "caches",
27538 "calendar",
27539 "call",
27540 "caller",
27541 "camera",
27542 "canBeFormatted",
27543 "canBeMounted",
27544 "canBeShared",
27545 "canConstructInDedicatedWorker",
27546 "canGoBack",
27547 "canGoForward",
27548 "canHaveChildren",
27549 "canHaveHTML",
27550 "canInsertDTMF",
27551 "canIntercept",
27552 "canLoadAdAuctionFencedFrame",
27553 "canLoadOpaqueURL",
27554 "canMakePayment",
27555 "canParse",
27556 "canPlayType",
27557 "canPresent",
27558 "canShare",
27559 "canTransition",
27560 "canTrickleIceCandidates",
27561 "cancel",
27562 "cancelAndHoldAtTime",
27563 "cancelAnimationFrame",
27564 "cancelBubble",
27565 "cancelIdleCallback",
27566 "cancelScheduledValues",
27567 "cancelVideoFrameCallback",
27568 "cancelWatchAvailability",
27569 "cancelable",
27570 "candidate",
27571 "canonicalUUID",
27572 "canvas",
27573 "cap",
27574 "capabilities",
27575 "caption",
27576 "caption-side",
27577 "captionSide",
27578 "captivePortal",
27579 "capture",
27580 "captureEvents",
27581 "captureStackTrace",
27582 "captureStream",
27583 "captureTab",
27584 "captureVisibleTab",
27585 "caret-color",
27586 "caretBidiLevel",
27587 "caretColor",
27588 "caretPositionFromPoint",
27589 "caretRangeFromPoint",
27590 "cast",
27591 "catch",
27592 "category",
27593 "cause",
27594 "cbrt",
27595 "cd",
27596 "ceil",
27597 "cellIndex",
27598 "cellPadding",
27599 "cellSpacing",
27600 "cells",
27601 "ch",
27602 "chOff",
27603 "chain",
27604 "challenge",
27605 "changeType",
27606 "changed",
27607 "changedTouches",
27608 "channel",
27609 "channelCount",
27610 "channelCountMode",
27611 "channelInterpretation",
27612 "chapterInfo",
27613 "char",
27614 "charAt",
27615 "charCode",
27616 "charCodeAt",
27617 "charIndex",
27618 "charLength",
27619 "characterBounds",
27620 "characterBoundsRangeStart",
27621 "characterData",
27622 "characterDataOldValue",
27623 "characterSet",
27624 "characterVariant",
27625 "characteristic",
27626 "charging",
27627 "chargingTime",
27628 "charset",
27629 "check",
27630 "checkDCE",
27631 "checkEnclosure",
27632 "checkFramebufferStatus",
27633 "checkIntersection",
27634 "checkValidity",
27635 "checkVisibility",
27636 "checked",
27637 "childElementCount",
27638 "childList",
27639 "childNodes",
27640 "children",
27641 "chrome",
27642 "ciphertext",
27643 "cite",
27644 "city",
27645 "claimInterface",
27646 "claimed",
27647 "classList",
27648 "className",
27649 "classid",
27650 "clear",
27651 "clearAppBadge",
27652 "clearAttributes",
27653 "clearBuffer",
27654 "clearBufferfi",
27655 "clearBufferfv",
27656 "clearBufferiv",
27657 "clearBufferuiv",
27658 "clearColor",
27659 "clearData",
27660 "clearDepth",
27661 "clearHalt",
27662 "clearImmediate",
27663 "clearInterval",
27664 "clearLiveSeekableRange",
27665 "clearMarks",
27666 "clearMaxGCPauseAccumulator",
27667 "clearMeasures",
27668 "clearOriginJoinedAdInterestGroups",
27669 "clearParameters",
27670 "clearRect",
27671 "clearResourceTimings",
27672 "clearShadow",
27673 "clearStencil",
27674 "clearTimeout",
27675 "clearValue",
27676 "clearWatch",
27677 "click",
27678 "clickCount",
27679 "clientDataJSON",
27680 "clientHeight",
27681 "clientInformation",
27682 "clientLeft",
27683 "clientRect",
27684 "clientRects",
27685 "clientTop",
27686 "clientWaitSync",
27687 "clientWidth",
27688 "clientX",
27689 "clientY",
27690 "clip",
27691 "clip-path",
27692 "clip-rule",
27693 "clipBottom",
27694 "clipLeft",
27695 "clipPath",
27696 "clipPathUnits",
27697 "clipRight",
27698 "clipRule",
27699 "clipTop",
27700 "clipboard",
27701 "clipboardData",
27702 "clonable",
27703 "clone",
27704 "cloneContents",
27705 "cloneNode",
27706 "cloneRange",
27707 "close",
27708 "closeCode",
27709 "closePath",
27710 "closed",
27711 "closedBy",
27712 "closest",
27713 "clz",
27714 "clz32",
27715 "cm",
27716 "cmp",
27717 "code",
27718 "codeBase",
27719 "codePointAt",
27720 "codeType",
27721 "codedHeight",
27722 "codedRect",
27723 "codedWidth",
27724 "colSpan",
27725 "collapse",
27726 "collapseToEnd",
27727 "collapseToStart",
27728 "collapsed",
27729 "collect",
27730 "collections",
27731 "colno",
27732 "color",
27733 "color-adjust",
27734 "color-interpolation",
27735 "color-interpolation-filters",
27736 "color-scheme",
27737 "colorAdjust",
27738 "colorAttachments",
27739 "colorDepth",
27740 "colorFormats",
27741 "colorInterpolation",
27742 "colorInterpolationFilters",
27743 "colorMask",
27744 "colorScheme",
27745 "colorSpace",
27746 "colorType",
27747 "cols",
27748 "column-count",
27749 "column-fill",
27750 "column-gap",
27751 "column-rule",
27752 "column-rule-color",
27753 "column-rule-style",
27754 "column-rule-width",
27755 "column-span",
27756 "column-width",
27757 "columnCount",
27758 "columnFill",
27759 "columnGap",
27760 "columnNumber",
27761 "columnRule",
27762 "columnRuleColor",
27763 "columnRuleStyle",
27764 "columnRuleWidth",
27765 "columnSpan",
27766 "columnWidth",
27767 "columns",
27768 "command",
27769 "commandForElement",
27770 "commands",
27771 "commit",
27772 "commitLoadTime",
27773 "commitPreferences",
27774 "commitStyles",
27775 "committed",
27776 "commonAncestorContainer",
27777 "compact",
27778 "compare",
27779 "compareBoundaryPoints",
27780 "compareDocumentPosition",
27781 "compareEndPoints",
27782 "compareExchange",
27783 "compareNode",
27784 "comparePoint",
27785 "compatMode",
27786 "compatible",
27787 "compile",
27788 "compileShader",
27789 "compileStreaming",
27790 "complete",
27791 "completed",
27792 "component",
27793 "componentFromPoint",
27794 "composed",
27795 "composedPath",
27796 "composite",
27797 "compositionEndOffset",
27798 "compositionStartOffset",
27799 "compressedTexImage2D",
27800 "compressedTexImage3D",
27801 "compressedTexSubImage2D",
27802 "compressedTexSubImage3D",
27803 "compute",
27804 "computedStyleMap",
27805 "concat",
27806 "conditionText",
27807 "coneInnerAngle",
27808 "coneOuterAngle",
27809 "coneOuterGain",
27810 "config",
27811 "configURL",
27812 "configurable",
27813 "configuration",
27814 "configurationName",
27815 "configurationValue",
27816 "configurations",
27817 "configure",
27818 "confirm",
27819 "confirmComposition",
27820 "confirmSiteSpecificTrackingException",
27821 "confirmWebWideTrackingException",
27822 "congestionControl",
27823 "connect",
27824 "connectEnd",
27825 "connectNative",
27826 "connectShark",
27827 "connectStart",
27828 "connected",
27829 "connectedCallback",
27830 "connectedMoveCallback",
27831 "connection",
27832 "connectionInfo",
27833 "connectionList",
27834 "connectionSpeed",
27835 "connectionState",
27836 "connections",
27837 "console",
27838 "consolidate",
27839 "constants",
27840 "constraint",
27841 "constrictionActive",
27842 "construct",
27843 "constructor",
27844 "contactID",
27845 "contain",
27846 "contain-intrinsic-block-size",
27847 "contain-intrinsic-height",
27848 "contain-intrinsic-inline-size",
27849 "contain-intrinsic-size",
27850 "contain-intrinsic-width",
27851 "containIntrinsicBlockSize",
27852 "containIntrinsicHeight",
27853 "containIntrinsicInlineSize",
27854 "containIntrinsicSize",
27855 "containIntrinsicWidth",
27856 "container",
27857 "container-name",
27858 "container-type",
27859 "containerId",
27860 "containerName",
27861 "containerQuery",
27862 "containerSrc",
27863 "containerType",
27864 "contains",
27865 "containsNode",
27866 "content",
27867 "content-visibility",
27868 "contentBoxSize",
27869 "contentDocument",
27870 "contentEditable",
27871 "contentEncoding",
27872 "contentHint",
27873 "contentOverflow",
27874 "contentRect",
27875 "contentScriptType",
27876 "contentStyleType",
27877 "contentType",
27878 "contentVisibility",
27879 "contentWindow",
27880 "context",
27881 "contextId",
27882 "contextIds",
27883 "contextMenu",
27884 "contextMenus",
27885 "contextType",
27886 "contextTypes",
27887 "contextmenu",
27888 "contextualIdentities",
27889 "continue",
27890 "continuePrimaryKey",
27891 "continuous",
27892 "control",
27893 "controlTransferIn",
27894 "controlTransferOut",
27895 "controller",
27896 "controls",
27897 "controlsList",
27898 "convertPointFromNode",
27899 "convertQuadFromNode",
27900 "convertRectFromNode",
27901 "convertToBlob",
27902 "convertToSpecifiedUnits",
27903 "cookie",
27904 "cookieEnabled",
27905 "cookieStore",
27906 "cookies",
27907 "coords",
27908 "copyBufferSubData",
27909 "copyBufferToBuffer",
27910 "copyBufferToTexture",
27911 "copyExternalImageToTexture",
27912 "copyFromChannel",
27913 "copyTexImage2D",
27914 "copyTexSubImage2D",
27915 "copyTexSubImage3D",
27916 "copyTextureToBuffer",
27917 "copyTextureToTexture",
27918 "copyTo",
27919 "copyToChannel",
27920 "copyWithin",
27921 "correspondingElement",
27922 "correspondingUseElement",
27923 "corruptedVideoFrames",
27924 "cos",
27925 "cosh",
27926 "count",
27927 "countReset",
27928 "counter-increment",
27929 "counter-reset",
27930 "counter-set",
27931 "counterIncrement",
27932 "counterReset",
27933 "counterSet",
27934 "country",
27935 "cpuClass",
27936 "cpuSleepAllowed",
27937 "cqb",
27938 "cqh",
27939 "cqi",
27940 "cqmax",
27941 "cqmin",
27942 "cqw",
27943 "create",
27944 "createAnalyser",
27945 "createAnchor",
27946 "createAnswer",
27947 "createAttribute",
27948 "createAttributeNS",
27949 "createAuctionNonce",
27950 "createBidirectionalStream",
27951 "createBindGroup",
27952 "createBindGroupLayout",
27953 "createBiquadFilter",
27954 "createBuffer",
27955 "createBufferSource",
27956 "createCDATASection",
27957 "createCSSStyleSheet",
27958 "createCaption",
27959 "createChannelMerger",
27960 "createChannelSplitter",
27961 "createCommandEncoder",
27962 "createComment",
27963 "createComputePipeline",
27964 "createComputePipelineAsync",
27965 "createConicGradient",
27966 "createConstantSource",
27967 "createContextualFragment",
27968 "createControlRange",
27969 "createConvolver",
27970 "createDTMFSender",
27971 "createDataChannel",
27972 "createDelay",
27973 "createDelayNode",
27974 "createDocument",
27975 "createDocumentFragment",
27976 "createDocumentType",
27977 "createDynamicsCompressor",
27978 "createElement",
27979 "createElementNS",
27980 "createEncodedStreams",
27981 "createEntityReference",
27982 "createEvent",
27983 "createEventObject",
27984 "createExpression",
27985 "createFramebuffer",
27986 "createFunction",
27987 "createGain",
27988 "createGainNode",
27989 "createHTML",
27990 "createHTMLDocument",
27991 "createIIRFilter",
27992 "createImageBitmap",
27993 "createImageData",
27994 "createIndex",
27995 "createJavaScriptNode",
27996 "createLinearGradient",
27997 "createMediaElementSource",
27998 "createMediaKeys",
27999 "createMediaStreamDestination",
28000 "createMediaStreamSource",
28001 "createMediaStreamTrackSource",
28002 "createMutableFile",
28003 "createNSResolver",
28004 "createNodeIterator",
28005 "createNotification",
28006 "createObjectStore",
28007 "createObjectURL",
28008 "createOffer",
28009 "createOscillator",
28010 "createPanner",
28011 "createPattern",
28012 "createPeriodicWave",
28013 "createPipelineLayout",
28014 "createPolicy",
28015 "createPopup",
28016 "createProcessingInstruction",
28017 "createProgram",
28018 "createQuery",
28019 "createQuerySet",
28020 "createRadialGradient",
28021 "createRange",
28022 "createRangeCollection",
28023 "createReader",
28024 "createRenderBundleEncoder",
28025 "createRenderPipeline",
28026 "createRenderPipelineAsync",
28027 "createRenderbuffer",
28028 "createSVGAngle",
28029 "createSVGLength",
28030 "createSVGMatrix",
28031 "createSVGNumber",
28032 "createSVGPathSegArcAbs",
28033 "createSVGPathSegArcRel",
28034 "createSVGPathSegClosePath",
28035 "createSVGPathSegCurvetoCubicAbs",
28036 "createSVGPathSegCurvetoCubicRel",
28037 "createSVGPathSegCurvetoCubicSmoothAbs",
28038 "createSVGPathSegCurvetoCubicSmoothRel",
28039 "createSVGPathSegCurvetoQuadraticAbs",
28040 "createSVGPathSegCurvetoQuadraticRel",
28041 "createSVGPathSegCurvetoQuadraticSmoothAbs",
28042 "createSVGPathSegCurvetoQuadraticSmoothRel",
28043 "createSVGPathSegLinetoAbs",
28044 "createSVGPathSegLinetoHorizontalAbs",
28045 "createSVGPathSegLinetoHorizontalRel",
28046 "createSVGPathSegLinetoRel",
28047 "createSVGPathSegLinetoVerticalAbs",
28048 "createSVGPathSegLinetoVerticalRel",
28049 "createSVGPathSegMovetoAbs",
28050 "createSVGPathSegMovetoRel",
28051 "createSVGPoint",
28052 "createSVGRect",
28053 "createSVGTransform",
28054 "createSVGTransformFromMatrix",
28055 "createSampler",
28056 "createScript",
28057 "createScriptProcessor",
28058 "createScriptURL",
28059 "createSession",
28060 "createShader",
28061 "createShaderModule",
28062 "createShadowRoot",
28063 "createStereoPanner",
28064 "createStyleSheet",
28065 "createTBody",
28066 "createTFoot",
28067 "createTHead",
28068 "createTask",
28069 "createTextNode",
28070 "createTextRange",
28071 "createTexture",
28072 "createTouch",
28073 "createTouchList",
28074 "createTransformFeedback",
28075 "createTreeWalker",
28076 "createUnidirectionalStream",
28077 "createVertexArray",
28078 "createView",
28079 "createWaveShaper",
28080 "createWorklet",
28081 "createWritable",
28082 "creationTime",
28083 "credentialless",
28084 "credentials",
28085 "criticalCHRestart",
28086 "cropTo",
28087 "crossOrigin",
28088 "crossOriginIsolated",
28089 "crypto",
28090 "csi",
28091 "csp",
28092 "cssFloat",
28093 "cssRules",
28094 "cssText",
28095 "cssValueType",
28096 "ctrlKey",
28097 "ctrlLeft",
28098 "cues",
28099 "cullFace",
28100 "cullMode",
28101 "currentCSSZoom",
28102 "currentDirection",
28103 "currentEntry",
28104 "currentLocalDescription",
28105 "currentNode",
28106 "currentPage",
28107 "currentRect",
28108 "currentRemoteDescription",
28109 "currentScale",
28110 "currentScreen",
28111 "currentScript",
28112 "currentSrc",
28113 "currentState",
28114 "currentStyle",
28115 "currentTarget",
28116 "currentTime",
28117 "currentTranslate",
28118 "currentView",
28119 "cursor",
28120 "curve",
28121 "customElements",
28122 "customError",
28123 "cx",
28124 "cy",
28125 "d",
28126 "data",
28127 "dataFld",
28128 "dataFormatAs",
28129 "dataLoss",
28130 "dataLossMessage",
28131 "dataPageSize",
28132 "dataSrc",
28133 "dataTransfer",
28134 "database",
28135 "databases",
28136 "datagrams",
28137 "dataset",
28138 "dateStyle",
28139 "dateTime",
28140 "day",
28141 "dayPeriod",
28142 "days",
28143 "db",
28144 "debug",
28145 "debuggerEnabled",
28146 "declarativeNetRequest",
28147 "declare",
28148 "decode",
28149 "decodeAudioData",
28150 "decodeQueueSize",
28151 "decodeURI",
28152 "decodeURIComponent",
28153 "decodedBodySize",
28154 "decoding",
28155 "decodingInfo",
28156 "decreaseZoomLevel",
28157 "decrypt",
28158 "default",
28159 "defaultCharset",
28160 "defaultChecked",
28161 "defaultMuted",
28162 "defaultPlaybackRate",
28163 "defaultPolicy",
28164 "defaultPrevented",
28165 "defaultQueue",
28166 "defaultRequest",
28167 "defaultSelected",
28168 "defaultStatus",
28169 "defaultURL",
28170 "defaultValue",
28171 "defaultView",
28172 "defaultstatus",
28173 "defer",
28174 "define",
28175 "defineMagicFunction",
28176 "defineMagicVariable",
28177 "defineProperties",
28178 "defineProperty",
28179 "deg",
28180 "delay",
28181 "delayTime",
28182 "delegatesFocus",
28183 "delete",
28184 "deleteBuffer",
28185 "deleteCaption",
28186 "deleteCell",
28187 "deleteContents",
28188 "deleteData",
28189 "deleteDatabase",
28190 "deleteFramebuffer",
28191 "deleteFromDocument",
28192 "deleteIndex",
28193 "deleteMedium",
28194 "deleteObjectStore",
28195 "deleteProgram",
28196 "deleteProperty",
28197 "deleteQuery",
28198 "deleteRenderbuffer",
28199 "deleteRow",
28200 "deleteRule",
28201 "deleteSampler",
28202 "deleteShader",
28203 "deleteSync",
28204 "deleteTFoot",
28205 "deleteTHead",
28206 "deleteTexture",
28207 "deleteTransformFeedback",
28208 "deleteVertexArray",
28209 "deleted",
28210 "deliverChangeRecords",
28211 "deliveredFrames",
28212 "deliveredFramesDuration",
28213 "delivery",
28214 "deliveryInfo",
28215 "deliveryStatus",
28216 "deliveryTimestamp",
28217 "deliveryType",
28218 "delta",
28219 "deltaMode",
28220 "deltaX",
28221 "deltaY",
28222 "deltaZ",
28223 "dependentLocality",
28224 "deprecatedReplaceInURN",
28225 "deprecatedRunAdAuctionEnforcesKAnonymity",
28226 "deprecatedURNToURL",
28227 "depthActive",
28228 "depthBias",
28229 "depthBiasClamp",
28230 "depthBiasSlopeScale",
28231 "depthClearValue",
28232 "depthCompare",
28233 "depthDataFormat",
28234 "depthFailOp",
28235 "depthFar",
28236 "depthFunc",
28237 "depthLoadOp",
28238 "depthMask",
28239 "depthNear",
28240 "depthOrArrayLayers",
28241 "depthRange",
28242 "depthReadOnly",
28243 "depthStencil",
28244 "depthStencilAttachment",
28245 "depthStencilFormat",
28246 "depthStoreOp",
28247 "depthType",
28248 "depthUsage",
28249 "depthWriteEnabled",
28250 "deref",
28251 "deriveBits",
28252 "deriveKey",
28253 "descentOverride",
28254 "description",
28255 "deselectAll",
28256 "designMode",
28257 "desiredSize",
28258 "destination",
28259 "destinationURL",
28260 "destroy",
28261 "detach",
28262 "detachEvent",
28263 "detachShader",
28264 "detached",
28265 "detail",
28266 "details",
28267 "detect",
28268 "detectLanguage",
28269 "detune",
28270 "device",
28271 "deviceClass",
28272 "deviceId",
28273 "deviceMemory",
28274 "devicePixelContentBoxSize",
28275 "devicePixelRatio",
28276 "devicePosture",
28277 "deviceProtocol",
28278 "deviceSubclass",
28279 "deviceVersionMajor",
28280 "deviceVersionMinor",
28281 "deviceVersionSubminor",
28282 "deviceXDPI",
28283 "deviceYDPI",
28284 "devtools",
28285 "devtools_panels",
28286 "didTimeout",
28287 "difference",
28288 "diffuseConstant",
28289 "digest",
28290 "dimension",
28291 "dimensions",
28292 "dir",
28293 "dirName",
28294 "direction",
28295 "dirxml",
28296 "disable",
28297 "disablePictureInPicture",
28298 "disableRemotePlayback",
28299 "disableVertexAttribArray",
28300 "disabled",
28301 "discard",
28302 "discardedFrames",
28303 "dischargingTime",
28304 "disconnect",
28305 "disconnectShark",
28306 "disconnectedCallback",
28307 "dispatchEvent",
28308 "dispatchWorkgroups",
28309 "dispatchWorkgroupsIndirect",
28310 "display",
28311 "displayHeight",
28312 "displayId",
28313 "displayName",
28314 "displayWidth",
28315 "dispose",
28316 "disposeAsync",
28317 "disposed",
28318 "disposition",
28319 "distanceModel",
28320 "div",
28321 "divisor",
28322 "djsapi",
28323 "djsproxy",
28324 "dns",
28325 "doImport",
28326 "doNotTrack",
28327 "doScroll",
28328 "doctype",
28329 "document",
28330 "documentElement",
28331 "documentId",
28332 "documentIds",
28333 "documentLifecycle",
28334 "documentMode",
28335 "documentOrigin",
28336 "documentOrigins",
28337 "documentPictureInPicture",
28338 "documentURI",
28339 "documentURL",
28340 "documentUrl",
28341 "documentUrls",
28342 "dolphin",
28343 "dolphinGameCenter",
28344 "dolphininfo",
28345 "dolphinmeta",
28346 "dom",
28347 "domComplete",
28348 "domContentLoadedEventEnd",
28349 "domContentLoadedEventStart",
28350 "domInteractive",
28351 "domLoading",
28352 "domOverlayState",
28353 "domain",
28354 "domainLookupEnd",
28355 "domainLookupStart",
28356 "dominant-baseline",
28357 "dominantBaseline",
28358 "done",
28359 "dopplerFactor",
28360 "dotAll",
28361 "downDegrees",
28362 "downlink",
28363 "download",
28364 "downloadRequest",
28365 "downloadTotal",
28366 "downloaded",
28367 "downloads",
28368 "dpcm",
28369 "dpi",
28370 "dppx",
28371 "dragDrop",
28372 "draggable",
28373 "draw",
28374 "drawArrays",
28375 "drawArraysInstanced",
28376 "drawArraysInstancedANGLE",
28377 "drawBuffers",
28378 "drawCustomFocusRing",
28379 "drawElements",
28380 "drawElementsInstanced",
28381 "drawElementsInstancedANGLE",
28382 "drawFocusIfNeeded",
28383 "drawImage",
28384 "drawImageFromRect",
28385 "drawIndexed",
28386 "drawIndexedIndirect",
28387 "drawIndirect",
28388 "drawRangeElements",
28389 "drawSystemFocusRing",
28390 "drawingBufferColorSpace",
28391 "drawingBufferFormat",
28392 "drawingBufferHeight",
28393 "drawingBufferStorage",
28394 "drawingBufferWidth",
28395 "drop",
28396 "dropEffect",
28397 "droppedVideoFrames",
28398 "dropzone",
28399 "dstFactor",
28400 "dtmf",
28401 "dump",
28402 "dumpProfile",
28403 "duplex",
28404 "duplicate",
28405 "durability",
28406 "duration",
28407 "dvb",
28408 "dvh",
28409 "dvi",
28410 "dvmax",
28411 "dvmin",
28412 "dvname",
28413 "dvnum",
28414 "dvw",
28415 "dx",
28416 "dy",
28417 "dynamicId",
28418 "dynsrc",
28419 "e",
28420 "edgeMode",
28421 "editContext",
28422 "effect",
28423 "effectAllowed",
28424 "effectiveDirective",
28425 "effectiveType",
28426 "effects",
28427 "elapsedTime",
28428 "element",
28429 "elementFromPoint",
28430 "elementTiming",
28431 "elements",
28432 "elementsFromPoint",
28433 "elevation",
28434 "ellipse",
28435 "em",
28436 "emHeightAscent",
28437 "emHeightDescent",
28438 "email",
28439 "embeds",
28440 "emit",
28441 "emma",
28442 "empty",
28443 "empty-cells",
28444 "emptyCells",
28445 "emptyHTML",
28446 "emptyScript",
28447 "emulatedPosition",
28448 "enable",
28449 "enableBackground",
28450 "enableDelegations",
28451 "enableStyleSheetsForSet",
28452 "enableVertexAttribArray",
28453 "enabled",
28454 "enabledFeatures",
28455 "enabledPlugin",
28456 "encode",
28457 "encodeInto",
28458 "encodeQueueSize",
28459 "encodeURI",
28460 "encodeURIComponent",
28461 "encodedBodySize",
28462 "encoding",
28463 "encodingInfo",
28464 "encrypt",
28465 "enctype",
28466 "end",
28467 "endContainer",
28468 "endElement",
28469 "endElementAt",
28470 "endOcclusionQuery",
28471 "endOfPassWriteIndex",
28472 "endOfStream",
28473 "endOffset",
28474 "endQuery",
28475 "endTime",
28476 "endTransformFeedback",
28477 "ended",
28478 "endpoint",
28479 "endpointNumber",
28480 "endpoints",
28481 "endsWith",
28482 "enqueue",
28483 "enterKeyHint",
28484 "entities",
28485 "entries",
28486 "entry",
28487 "entryPoint",
28488 "entryType",
28489 "enumerable",
28490 "enumerate",
28491 "enumerateDevices",
28492 "enumerateEditable",
28493 "environmentBlendMode",
28494 "equals",
28495 "era",
28496 "error",
28497 "errorCode",
28498 "errorDetail",
28499 "errorText",
28500 "escape",
28501 "estimate",
28502 "eval",
28503 "evaluate",
28504 "event",
28505 "eventCounts",
28506 "eventPhase",
28507 "events",
28508 "every",
28509 "ex",
28510 "exception",
28511 "exchange",
28512 "exec",
28513 "execCommand",
28514 "execCommandShowHelp",
28515 "execScript",
28516 "executeBundles",
28517 "executionStart",
28518 "exitFullscreen",
28519 "exitPictureInPicture",
28520 "exitPointerLock",
28521 "exitPresent",
28522 "exp",
28523 "expand",
28524 "expandEntityReferences",
28525 "expando",
28526 "expansion",
28527 "expectedContextLanguages",
28528 "expectedImprovement",
28529 "expectedInputLanguages",
28530 "experiments",
28531 "expiration",
28532 "expirationTime",
28533 "expires",
28534 "expiryDate",
28535 "explicitOriginalTarget",
28536 "expm1",
28537 "exponent",
28538 "exponentialRampToValueAtTime",
28539 "exportKey",
28540 "exports",
28541 "extend",
28542 "extension",
28543 "extensionTypes",
28544 "extensions",
28545 "extentNode",
28546 "extentOffset",
28547 "external",
28548 "externalResourcesRequired",
28549 "externalTexture",
28550 "extractContents",
28551 "extractable",
28552 "eye",
28553 "f",
28554 "f16round",
28555 "face",
28556 "factoryReset",
28557 "failOp",
28558 "failureReason",
28559 "fallback",
28560 "family",
28561 "familyName",
28562 "farthestViewportElement",
28563 "fastSeek",
28564 "fatal",
28565 "featureId",
28566 "featurePolicy",
28567 "featureSettings",
28568 "features",
28569 "fence",
28570 "fenceSync",
28571 "fetch",
28572 "fetchLater",
28573 "fetchPriority",
28574 "fetchStart",
28575 "fftSize",
28576 "fgColor",
28577 "fieldOfView",
28578 "file",
28579 "fileCreatedDate",
28580 "fileHandle",
28581 "fileModifiedDate",
28582 "fileName",
28583 "fileSize",
28584 "fileUpdatedDate",
28585 "filename",
28586 "files",
28587 "filesystem",
28588 "fill",
28589 "fill-opacity",
28590 "fill-rule",
28591 "fillJointRadii",
28592 "fillLightMode",
28593 "fillOpacity",
28594 "fillPoses",
28595 "fillRect",
28596 "fillRule",
28597 "fillStyle",
28598 "fillText",
28599 "filter",
28600 "filterResX",
28601 "filterResY",
28602 "filterUnits",
28603 "filters",
28604 "finalResponseHeadersStart",
28605 "finally",
28606 "find",
28607 "findIndex",
28608 "findLast",
28609 "findLastIndex",
28610 "findRule",
28611 "findText",
28612 "finish",
28613 "finishDocumentLoadTime",
28614 "finishLoadTime",
28615 "finished",
28616 "fireEvent",
28617 "firesTouchEvents",
28618 "first",
28619 "firstChild",
28620 "firstElementChild",
28621 "firstInterimResponseStart",
28622 "firstPage",
28623 "firstPaintAfterLoadTime",
28624 "firstPaintTime",
28625 "firstUIEventTimestamp",
28626 "fixed",
28627 "flags",
28628 "flat",
28629 "flatMap",
28630 "flex",
28631 "flex-basis",
28632 "flex-direction",
28633 "flex-flow",
28634 "flex-grow",
28635 "flex-shrink",
28636 "flex-wrap",
28637 "flexBasis",
28638 "flexDirection",
28639 "flexFlow",
28640 "flexGrow",
28641 "flexShrink",
28642 "flexWrap",
28643 "flip",
28644 "flipX",
28645 "flipY",
28646 "float",
28647 "float32",
28648 "float64",
28649 "flood-color",
28650 "flood-opacity",
28651 "floodColor",
28652 "floodOpacity",
28653 "floor",
28654 "flush",
28655 "focus",
28656 "focusNode",
28657 "focusOffset",
28658 "font",
28659 "font-family",
28660 "font-feature-settings",
28661 "font-kerning",
28662 "font-language-override",
28663 "font-optical-sizing",
28664 "font-palette",
28665 "font-size",
28666 "font-size-adjust",
28667 "font-stretch",
28668 "font-style",
28669 "font-synthesis",
28670 "font-synthesis-position",
28671 "font-synthesis-small-caps",
28672 "font-synthesis-style",
28673 "font-synthesis-weight",
28674 "font-variant",
28675 "font-variant-alternates",
28676 "font-variant-caps",
28677 "font-variant-east-asian",
28678 "font-variant-ligatures",
28679 "font-variant-numeric",
28680 "font-variant-position",
28681 "font-variation-settings",
28682 "font-weight",
28683 "fontBoundingBoxAscent",
28684 "fontBoundingBoxDescent",
28685 "fontFamily",
28686 "fontFeatureSettings",
28687 "fontKerning",
28688 "fontLanguageOverride",
28689 "fontOpticalSizing",
28690 "fontPalette",
28691 "fontSize",
28692 "fontSizeAdjust",
28693 "fontSmoothingEnabled",
28694 "fontStretch",
28695 "fontStyle",
28696 "fontSynthesis",
28697 "fontSynthesisPosition",
28698 "fontSynthesisSmallCaps",
28699 "fontSynthesisStyle",
28700 "fontSynthesisWeight",
28701 "fontVariant",
28702 "fontVariantAlternates",
28703 "fontVariantCaps",
28704 "fontVariantEastAsian",
28705 "fontVariantEmoji",
28706 "fontVariantLigatures",
28707 "fontVariantNumeric",
28708 "fontVariantPosition",
28709 "fontVariationSettings",
28710 "fontWeight",
28711 "fontcolor",
28712 "fontfaces",
28713 "fonts",
28714 "fontsize",
28715 "for",
28716 "forEach",
28717 "force",
28718 "forceFallbackAdapter",
28719 "forceRedraw",
28720 "forced-color-adjust",
28721 "forcedColorAdjust",
28722 "forcedStyleAndLayoutDuration",
28723 "forget",
28724 "form",
28725 "formAction",
28726 "formData",
28727 "formEnctype",
28728 "formMethod",
28729 "formNoValidate",
28730 "formTarget",
28731 "format",
28732 "formatToParts",
28733 "forms",
28734 "forward",
28735 "forwardWheel",
28736 "forwardX",
28737 "forwardY",
28738 "forwardZ",
28739 "foundation",
28740 "fr",
28741 "fractionalSecondDigits",
28742 "fragment",
28743 "fragmentDirective",
28744 "frame",
28745 "frameBorder",
28746 "frameCount",
28747 "frameElement",
28748 "frameId",
28749 "frameIds",
28750 "frameSpacing",
28751 "framebuffer",
28752 "framebufferHeight",
28753 "framebufferRenderbuffer",
28754 "framebufferTexture2D",
28755 "framebufferTextureLayer",
28756 "framebufferWidth",
28757 "frames",
28758 "freeSpace",
28759 "freeze",
28760 "frequency",
28761 "frequencyBinCount",
28762 "from",
28763 "fromAsync",
28764 "fromBase64",
28765 "fromCharCode",
28766 "fromCodePoint",
28767 "fromElement",
28768 "fromEntries",
28769 "fromFloat32Array",
28770 "fromFloat64Array",
28771 "fromHex",
28772 "fromMatrix",
28773 "fromPoint",
28774 "fromQuad",
28775 "fromRect",
28776 "frontFace",
28777 "fround",
28778 "fullName",
28779 "fullPath",
28780 "fullRange",
28781 "fullScreen",
28782 "fullVersionList",
28783 "fullscreen",
28784 "fullscreenElement",
28785 "fullscreenEnabled",
28786 "fx",
28787 "fy",
28788 "g",
28789 "gain",
28790 "gamepad",
28791 "gamma",
28792 "gap",
28793 "gatheringState",
28794 "gatt",
28795 "geckoProfiler",
28796 "genderIdentity",
28797 "generateCertificate",
28798 "generateKey",
28799 "generateMipmap",
28800 "generateRequest",
28801 "geolocation",
28802 "gestureObject",
28803 "get",
28804 "getAcceptLanguages",
28805 "getActiveAttrib",
28806 "getActiveUniform",
28807 "getActiveUniformBlockName",
28808 "getActiveUniformBlockParameter",
28809 "getActiveUniforms",
28810 "getAdjacentText",
28811 "getAll",
28812 "getAllKeys",
28813 "getAllRecords",
28814 "getAllResponseHeaders",
28815 "getAllowlistForFeature",
28816 "getAnimations",
28817 "getAsFile",
28818 "getAsFileSystemHandle",
28819 "getAsString",
28820 "getAttachedShaders",
28821 "getAttribLocation",
28822 "getAttribute",
28823 "getAttributeNS",
28824 "getAttributeNames",
28825 "getAttributeNode",
28826 "getAttributeNodeNS",
28827 "getAttributeType",
28828 "getAudioTracks",
28829 "getAuthenticatorData",
28830 "getAutoplayPolicy",
28831 "getAvailability",
28832 "getBBox",
28833 "getBackgroundPage",
28834 "getBadgeBackgroundColor",
28835 "getBadgeText",
28836 "getBadgeTextColor",
28837 "getBattery",
28838 "getBigInt64",
28839 "getBigUint64",
28840 "getBindGroupLayout",
28841 "getBlob",
28842 "getBookmark",
28843 "getBoundingClientRect",
28844 "getBounds",
28845 "getBoxQuads",
28846 "getBrowserInfo",
28847 "getBufferParameter",
28848 "getBufferSubData",
28849 "getByteFrequencyData",
28850 "getByteTimeDomainData",
28851 "getCSSCanvasContext",
28852 "getCTM",
28853 "getCameraImage",
28854 "getCandidateWindowClientRect",
28855 "getCanonicalLocales",
28856 "getCapabilities",
28857 "getCaptureHandle",
28858 "getChannelData",
28859 "getCharNumAtPosition",
28860 "getCharacteristic",
28861 "getCharacteristics",
28862 "getClientCapabilities",
28863 "getClientExtensionResults",
28864 "getClientRect",
28865 "getClientRects",
28866 "getCoalescedEvents",
28867 "getCompilationInfo",
28868 "getComposedRanges",
28869 "getCompositionAlternatives",
28870 "getComputedStyle",
28871 "getComputedTextLength",
28872 "getComputedTiming",
28873 "getConfiguration",
28874 "getConstraints",
28875 "getContext",
28876 "getContextAttributes",
28877 "getContexts",
28878 "getContributingSources",
28879 "getCounterValue",
28880 "getCueAsHTML",
28881 "getCueById",
28882 "getCurrent",
28883 "getCurrentPosition",
28884 "getCurrentTexture",
28885 "getCurrentTime",
28886 "getData",
28887 "getDatabaseNames",
28888 "getDate",
28889 "getDay",
28890 "getDefaultComputedStyle",
28891 "getDepthInMeters",
28892 "getDepthInformation",
28893 "getDescriptor",
28894 "getDescriptors",
28895 "getDestinationInsertionPoints",
28896 "getDevices",
28897 "getDirectory",
28898 "getDirectoryHandle",
28899 "getDisplayMedia",
28900 "getDistributedNodes",
28901 "getEditable",
28902 "getElementById",
28903 "getElementsByClassName",
28904 "getElementsByName",
28905 "getElementsByTagName",
28906 "getElementsByTagNameNS",
28907 "getEnclosureList",
28908 "getEndPositionOfChar",
28909 "getEntries",
28910 "getEntriesByName",
28911 "getEntriesByType",
28912 "getError",
28913 "getExtension",
28914 "getExtentOfChar",
28915 "getEyeParameters",
28916 "getFeature",
28917 "getFiberRoots",
28918 "getFile",
28919 "getFileHandle",
28920 "getFiles",
28921 "getFilesAndDirectories",
28922 "getFingerprints",
28923 "getFloat16",
28924 "getFloat32",
28925 "getFloat64",
28926 "getFloatFrequencyData",
28927 "getFloatTimeDomainData",
28928 "getFloatValue",
28929 "getFragDataLocation",
28930 "getFrameData",
28931 "getFrameId",
28932 "getFramebufferAttachmentParameter",
28933 "getFrequencyResponse",
28934 "getFullYear",
28935 "getGamepads",
28936 "getHTML",
28937 "getHeaderExtensionsToNegotiate",
28938 "getHighEntropyValues",
28939 "getHitTestResults",
28940 "getHitTestResultsForTransientInput",
28941 "getHours",
28942 "getIdentityAssertion",
28943 "getIds",
28944 "getImageData",
28945 "getIndexedParameter",
28946 "getInfo",
28947 "getInnerHTML",
28948 "getInstalledRelatedApps",
28949 "getInt16",
28950 "getInt32",
28951 "getInt8",
28952 "getInterestGroupAdAuctionData",
28953 "getInternalModuleRanges",
28954 "getInternalformatParameter",
28955 "getIntersectionList",
28956 "getItem",
28957 "getItems",
28958 "getJointPose",
28959 "getKey",
28960 "getKeyframes",
28961 "getLastFocused",
28962 "getLayers",
28963 "getLayoutMap",
28964 "getLightEstimate",
28965 "getLineDash",
28966 "getLocalCandidates",
28967 "getLocalParameters",
28968 "getLocalStreams",
28969 "getManagedConfiguration",
28970 "getManifest",
28971 "getMappedRange",
28972 "getMarks",
28973 "getMatchedCSSRules",
28974 "getMaxGCPauseSinceClear",
28975 "getMeasures",
28976 "getMessage",
28977 "getMetadata",
28978 "getMilliseconds",
28979 "getMinutes",
28980 "getModifierState",
28981 "getMonth",
28982 "getName",
28983 "getNamedItem",
28984 "getNamedItemNS",
28985 "getNativeFramebufferScaleFactor",
28986 "getNegotiatedHeaderExtensions",
28987 "getNestedConfigs",
28988 "getNotifications",
28989 "getNotifier",
28990 "getNumberOfChars",
28991 "getOffsetReferenceSpace",
28992 "getOrInsert",
28993 "getOrInsertComputed",
28994 "getOutputTimestamp",
28995 "getOverrideHistoryNavigationMode",
28996 "getOverrideStyle",
28997 "getOwnPropertyDescriptor",
28998 "getOwnPropertyDescriptors",
28999 "getOwnPropertyNames",
29000 "getOwnPropertySymbols",
29001 "getPackageDirectoryEntry",
29002 "getParameter",
29003 "getParameters",
29004 "getParent",
29005 "getPathData",
29006 "getPathSegAtLength",
29007 "getPathSegmentAtLength",
29008 "getPermissionWarningsByManifest",
29009 "getPhotoCapabilities",
29010 "getPhotoSettings",
29011 "getPlatformInfo",
29012 "getPointAtLength",
29013 "getPopup",
29014 "getPorts",
29015 "getPose",
29016 "getPredictedEvents",
29017 "getPreference",
29018 "getPreferenceDefault",
29019 "getPreferredCanvasFormat",
29020 "getPresentationAttribute",
29021 "getPreventDefault",
29022 "getPrimaryService",
29023 "getPrimaryServices",
29024 "getProgramInfoLog",
29025 "getProgramParameter",
29026 "getPropertyCSSValue",
29027 "getPropertyPriority",
29028 "getPropertyShorthand",
29029 "getPropertyType",
29030 "getPropertyValue",
29031 "getPrototypeOf",
29032 "getPublicKey",
29033 "getPublicKeyAlgorithm",
29034 "getQuery",
29035 "getQueryParameter",
29036 "getRGBColorValue",
29037 "getRandomValues",
29038 "getRangeAt",
29039 "getReader",
29040 "getReceivers",
29041 "getRectValue",
29042 "getReflectionCubeMap",
29043 "getRegistration",
29044 "getRegistrations",
29045 "getRemoteCandidates",
29046 "getRemoteCertificates",
29047 "getRemoteParameters",
29048 "getRemoteStreams",
29049 "getRenderbufferParameter",
29050 "getResponseHeader",
29051 "getRoot",
29052 "getRootNode",
29053 "getRotationOfChar",
29054 "getSVGDocument",
29055 "getSamplerParameter",
29056 "getScreenCTM",
29057 "getScreenDetails",
29058 "getSeconds",
29059 "getSelectedCandidatePair",
29060 "getSelection",
29061 "getSelf",
29062 "getSenders",
29063 "getService",
29064 "getSetCookie",
29065 "getSettings",
29066 "getShaderInfoLog",
29067 "getShaderParameter",
29068 "getShaderPrecisionFormat",
29069 "getShaderSource",
29070 "getSignals",
29071 "getSimpleDuration",
29072 "getSiteIcons",
29073 "getSources",
29074 "getSpeculativeParserUrls",
29075 "getStartPositionOfChar",
29076 "getStartTime",
29077 "getState",
29078 "getStats",
29079 "getStatusForPolicy",
29080 "getStorageUpdates",
29081 "getStreamById",
29082 "getStringValue",
29083 "getSubStringLength",
29084 "getSubscription",
29085 "getSubscriptions",
29086 "getSupportedConstraints",
29087 "getSupportedExtensions",
29088 "getSupportedFormats",
29089 "getSupportedZoomLevels",
29090 "getSyncParameter",
29091 "getSynchronizationSources",
29092 "getTags",
29093 "getTargetRanges",
29094 "getTexParameter",
29095 "getTextFormats",
29096 "getTime",
29097 "getTimezoneOffset",
29098 "getTiming",
29099 "getTitle",
29100 "getTitlebarAreaRect",
29101 "getTotalLength",
29102 "getTrackById",
29103 "getTracks",
29104 "getTransceivers",
29105 "getTransform",
29106 "getTransformFeedbackVarying",
29107 "getTransformToElement",
29108 "getTransports",
29109 "getType",
29110 "getTypeMapping",
29111 "getUILanguage",
29112 "getURL",
29113 "getUTCDate",
29114 "getUTCDay",
29115 "getUTCFullYear",
29116 "getUTCHours",
29117 "getUTCMilliseconds",
29118 "getUTCMinutes",
29119 "getUTCMonth",
29120 "getUTCSeconds",
29121 "getUint16",
29122 "getUint32",
29123 "getUint8",
29124 "getUniform",
29125 "getUniformBlockIndex",
29126 "getUniformIndices",
29127 "getUniformLocation",
29128 "getUserInfo",
29129 "getUserMedia",
29130 "getUserSettings",
29131 "getVRDisplays",
29132 "getValues",
29133 "getVarDate",
29134 "getVariableValue",
29135 "getVertexAttrib",
29136 "getVertexAttribOffset",
29137 "getVideoPlaybackQuality",
29138 "getVideoTracks",
29139 "getViewerPose",
29140 "getViewport",
29141 "getViews",
29142 "getVoices",
29143 "getWakeLockState",
29144 "getWriter",
29145 "getYear",
29146 "getZoom",
29147 "getZoomSettings",
29148 "givenName",
29149 "global",
29150 "globalAlpha",
29151 "globalCompositeOperation",
29152 "globalPrivacyControl",
29153 "globalThis",
29154 "glyphOrientationHorizontal",
29155 "glyphOrientationVertical",
29156 "glyphRef",
29157 "go",
29158 "goBack",
29159 "goForward",
29160 "gpu",
29161 "grabFrame",
29162 "grad",
29163 "gradientTransform",
29164 "gradientUnits",
29165 "grammars",
29166 "green",
29167 "grid",
29168 "grid-area",
29169 "grid-auto-columns",
29170 "grid-auto-flow",
29171 "grid-auto-rows",
29172 "grid-column",
29173 "grid-column-end",
29174 "grid-column-gap",
29175 "grid-column-start",
29176 "grid-gap",
29177 "grid-row",
29178 "grid-row-end",
29179 "grid-row-gap",
29180 "grid-row-start",
29181 "grid-template",
29182 "grid-template-areas",
29183 "grid-template-columns",
29184 "grid-template-rows",
29185 "gridArea",
29186 "gridAutoColumns",
29187 "gridAutoFlow",
29188 "gridAutoRows",
29189 "gridColumn",
29190 "gridColumnEnd",
29191 "gridColumnGap",
29192 "gridColumnStart",
29193 "gridGap",
29194 "gridRow",
29195 "gridRowEnd",
29196 "gridRowGap",
29197 "gridRowStart",
29198 "gridTemplate",
29199 "gridTemplateAreas",
29200 "gridTemplateColumns",
29201 "gridTemplateRows",
29202 "gripSpace",
29203 "group",
29204 "groupBy",
29205 "groupCollapsed",
29206 "groupEnd",
29207 "groupId",
29208 "groups",
29209 "grow",
29210 "growable",
29211 "guestProcessId",
29212 "guestRenderFrameRoutingId",
29213 "hadRecentInput",
29214 "hand",
29215 "handedness",
29216 "hangingBaseline",
29217 "hapticActuators",
29218 "hardwareConcurrency",
29219 "has",
29220 "hasAttribute",
29221 "hasAttributeNS",
29222 "hasAttributes",
29223 "hasBeenActive",
29224 "hasChildNodes",
29225 "hasComposition",
29226 "hasDynamicOffset",
29227 "hasEnrolledInstrument",
29228 "hasExtension",
29229 "hasExternalDisplay",
29230 "hasFeature",
29231 "hasFocus",
29232 "hasIndices",
29233 "hasInstance",
29234 "hasLayout",
29235 "hasOrientation",
29236 "hasOwn",
29237 "hasOwnProperty",
29238 "hasPointerCapture",
29239 "hasPosition",
29240 "hasPrivateToken",
29241 "hasReading",
29242 "hasRedemptionRecord",
29243 "hasRegExpGroups",
29244 "hasStorageAccess",
29245 "hasUAVisualTransition",
29246 "hasUnpartitionedCookieAccess",
29247 "hash",
29248 "hashChange",
29249 "head",
29250 "headers",
29251 "heading",
29252 "height",
29253 "hid",
29254 "hidden",
29255 "hide",
29256 "hideFocus",
29257 "hidePopover",
29258 "high",
29259 "highWaterMark",
29260 "highlight",
29261 "highlights",
29262 "highlightsFromPoint",
29263 "hint",
29264 "hints",
29265 "history",
29266 "honorificPrefix",
29267 "honorificSuffix",
29268 "horizontalOverflow",
29269 "host",
29270 "hostCandidate",
29271 "hostname",
29272 "hour",
29273 "hour12",
29274 "hourCycle",
29275 "hours",
29276 "href",
29277 "hrefTranslate",
29278 "hreflang",
29279 "hspace",
29280 "html5TagCheckInerface",
29281 "htmlFor",
29282 "htmlText",
29283 "httpEquiv",
29284 "httpRequestStatusCode",
29285 "hwTimestamp",
29286 "hyphenate-character",
29287 "hyphenateCharacter",
29288 "hyphenateLimitChars",
29289 "hyphens",
29290 "hypot",
29291 "i18n",
29292 "ic",
29293 "iccId",
29294 "iceConnectionState",
29295 "iceGatheringState",
29296 "iceTransport",
29297 "icon",
29298 "iconURL",
29299 "id",
29300 "identifier",
29301 "identity",
29302 "ideographicBaseline",
29303 "idle",
29304 "idpLoginUrl",
29305 "ignoreBOM",
29306 "ignoreCase",
29307 "ignoreDepthValues",
29308 "image",
29309 "image-orientation",
29310 "image-rendering",
29311 "imageHeight",
29312 "imageOrientation",
29313 "imageRendering",
29314 "imageSizes",
29315 "imageSmoothingEnabled",
29316 "imageSmoothingQuality",
29317 "imageSrcset",
29318 "imageWidth",
29319 "images",
29320 "ime-mode",
29321 "imeMode",
29322 "implementation",
29323 "importExternalTexture",
29324 "importKey",
29325 "importNode",
29326 "importStylesheet",
29327 "imports",
29328 "impp",
29329 "imul",
29330 "in",
29331 "in1",
29332 "in2",
29333 "inBandMetadataTrackDispatchType",
29334 "inIncognitoContext",
29335 "inRange",
29336 "includes",
29337 "incognito",
29338 "incomingBidirectionalStreams",
29339 "incomingHighWaterMark",
29340 "incomingMaxAge",
29341 "incomingUnidirectionalStreams",
29342 "increaseZoomLevel",
29343 "incremental",
29344 "indeterminate",
29345 "index",
29346 "indexNames",
29347 "indexOf",
29348 "indexedDB",
29349 "indicate",
29350 "indices",
29351 "inert",
29352 "inertiaDestinationX",
29353 "inertiaDestinationY",
29354 "info",
29355 "inherits",
29356 "init",
29357 "initAnimationEvent",
29358 "initBeforeLoadEvent",
29359 "initClipboardEvent",
29360 "initCloseEvent",
29361 "initCommandEvent",
29362 "initCompositionEvent",
29363 "initCustomEvent",
29364 "initData",
29365 "initDataType",
29366 "initDeviceMotionEvent",
29367 "initDeviceOrientationEvent",
29368 "initDragEvent",
29369 "initErrorEvent",
29370 "initEvent",
29371 "initFocusEvent",
29372 "initGestureEvent",
29373 "initHashChangeEvent",
29374 "initKeyEvent",
29375 "initKeyboardEvent",
29376 "initMSManipulationEvent",
29377 "initMessageEvent",
29378 "initMouseEvent",
29379 "initMouseScrollEvent",
29380 "initMouseWheelEvent",
29381 "initMutationEvent",
29382 "initNSMouseEvent",
29383 "initOverflowEvent",
29384 "initPageEvent",
29385 "initPageTransitionEvent",
29386 "initPointerEvent",
29387 "initPopStateEvent",
29388 "initProgressEvent",
29389 "initScrollAreaEvent",
29390 "initSimpleGestureEvent",
29391 "initStorageEvent",
29392 "initTextEvent",
29393 "initTimeEvent",
29394 "initTouchEvent",
29395 "initTransitionEvent",
29396 "initUIEvent",
29397 "initWebKitAnimationEvent",
29398 "initWebKitTransitionEvent",
29399 "initWebKitWheelEvent",
29400 "initWheelEvent",
29401 "initialTime",
29402 "initialValue",
29403 "initialize",
29404 "initiatorType",
29405 "inject",
29406 "ink",
29407 "inline-size",
29408 "inlineSize",
29409 "inlineVerticalFieldOfView",
29410 "inner",
29411 "innerHTML",
29412 "innerHeight",
29413 "innerText",
29414 "innerWidth",
29415 "input",
29416 "inputBuffer",
29417 "inputEncoding",
29418 "inputMethod",
29419 "inputMode",
29420 "inputQuota",
29421 "inputSource",
29422 "inputSources",
29423 "inputType",
29424 "inputs",
29425 "insertAdjacentElement",
29426 "insertAdjacentHTML",
29427 "insertAdjacentText",
29428 "insertBefore",
29429 "insertCell",
29430 "insertDTMF",
29431 "insertData",
29432 "insertDebugMarker",
29433 "insertItemBefore",
29434 "insertNode",
29435 "insertRow",
29436 "insertRule",
29437 "inset",
29438 "inset-block",
29439 "inset-block-end",
29440 "inset-block-start",
29441 "inset-inline",
29442 "inset-inline-end",
29443 "inset-inline-start",
29444 "insetBlock",
29445 "insetBlockEnd",
29446 "insetBlockStart",
29447 "insetInline",
29448 "insetInlineEnd",
29449 "insetInlineStart",
29450 "inspect",
29451 "install",
29452 "installing",
29453 "instanceRoot",
29454 "instantiate",
29455 "instantiateStreaming",
29456 "instruments",
29457 "int16",
29458 "int32",
29459 "int8",
29460 "integrity",
29461 "interactionCount",
29462 "interactionId",
29463 "interactionMode",
29464 "intercept",
29465 "interestForElement",
29466 "interfaceClass",
29467 "interfaceName",
29468 "interfaceNumber",
29469 "interfaceProtocol",
29470 "interfaceSubclass",
29471 "interfaces",
29472 "interimResults",
29473 "internalSubset",
29474 "interpretation",
29475 "intersection",
29476 "intersectionRatio",
29477 "intersectionRect",
29478 "intersectsNode",
29479 "interval",
29480 "invalidIteratorState",
29481 "invalidateFramebuffer",
29482 "invalidateSubFramebuffer",
29483 "inverse",
29484 "invertSelf",
29485 "invoker",
29486 "invokerType",
29487 "is",
29488 "is2D",
29489 "isActive",
29490 "isAllowedFileSchemeAccess",
29491 "isAllowedIncognitoAccess",
29492 "isAlternate",
29493 "isArray",
29494 "isAutoSelected",
29495 "isBingCurrentSearchDefault",
29496 "isBuffer",
29497 "isCandidateWindowVisible",
29498 "isChar",
29499 "isCollapsed",
29500 "isComposing",
29501 "isConcatSpreadable",
29502 "isConditionalMediationAvailable",
29503 "isConfigSupported",
29504 "isConnected",
29505 "isContentEditable",
29506 "isContentHandlerRegistered",
29507 "isContextLost",
29508 "isDefaultNamespace",
29509 "isDirectory",
29510 "isDisabled",
29511 "isDisjointFrom",
29512 "isEnabled",
29513 "isEqual",
29514 "isEqualNode",
29515 "isError",
29516 "isExtended",
29517 "isExtensible",
29518 "isExternalCTAP2SecurityKeySupported",
29519 "isFallbackAdapter",
29520 "isFile",
29521 "isFinite",
29522 "isFirstPersonObserver",
29523 "isFramebuffer",
29524 "isFrozen",
29525 "isGenerator",
29526 "isHTML",
29527 "isHistoryNavigation",
29528 "isId",
29529 "isIdentity",
29530 "isInjected",
29531 "isInputPending",
29532 "isInteger",
29533 "isInternal",
29534 "isIntersecting",
29535 "isLockFree",
29536 "isMap",
29537 "isMultiLine",
29538 "isNaN",
29539 "isOpen",
29540 "isPointInFill",
29541 "isPointInPath",
29542 "isPointInRange",
29543 "isPointInStroke",
29544 "isPrefAlternate",
29545 "isPresenting",
29546 "isPrimary",
29547 "isProgram",
29548 "isPropertyImplicit",
29549 "isProtocolHandlerRegistered",
29550 "isPrototypeOf",
29551 "isQuery",
29552 "isRawJSON",
29553 "isRenderbuffer",
29554 "isSafeInteger",
29555 "isSameEntry",
29556 "isSameNode",
29557 "isSampler",
29558 "isScript",
29559 "isScriptURL",
29560 "isSealed",
29561 "isSecureContext",
29562 "isSessionSupported",
29563 "isShader",
29564 "isSubsetOf",
29565 "isSupersetOf",
29566 "isSupported",
29567 "isSync",
29568 "isTextEdit",
29569 "isTexture",
29570 "isTransformFeedback",
29571 "isTrusted",
29572 "isTypeSupported",
29573 "isUserVerifyingPlatformAuthenticatorAvailable",
29574 "isVertexArray",
29575 "isView",
29576 "isVisible",
29577 "isWellFormed",
29578 "isochronousTransferIn",
29579 "isochronousTransferOut",
29580 "isolation",
29581 "italics",
29582 "item",
29583 "itemId",
29584 "itemProp",
29585 "itemRef",
29586 "itemScope",
29587 "itemType",
29588 "itemValue",
29589 "items",
29590 "iterateNext",
29591 "iterationComposite",
29592 "iterator",
29593 "javaEnabled",
29594 "jitterBufferTarget",
29595 "jobTitle",
29596 "join",
29597 "joinAdInterestGroup",
29598 "jointName",
29599 "json",
29600 "justify-content",
29601 "justify-items",
29602 "justify-self",
29603 "justifyContent",
29604 "justifyItems",
29605 "justifySelf",
29606 "k1",
29607 "k2",
29608 "k3",
29609 "k4",
29610 "kHz",
29611 "keepalive",
29612 "kernelMatrix",
29613 "kernelUnitLengthX",
29614 "kernelUnitLengthY",
29615 "kerning",
29616 "key",
29617 "keyCode",
29618 "keyFor",
29619 "keyIdentifier",
29620 "keyLightEnabled",
29621 "keyLocation",
29622 "keyPath",
29623 "keyStatuses",
29624 "keySystem",
29625 "keyText",
29626 "keyUsage",
29627 "keyboard",
29628 "keys",
29629 "keytype",
29630 "kind",
29631 "knee",
29632 "knownSources",
29633 "label",
29634 "labels",
29635 "lang",
29636 "language",
29637 "languages",
29638 "largeArcFlag",
29639 "last",
29640 "lastChild",
29641 "lastElementChild",
29642 "lastError",
29643 "lastEventId",
29644 "lastIndex",
29645 "lastIndexOf",
29646 "lastInputTime",
29647 "lastMatch",
29648 "lastMessageSubject",
29649 "lastMessageType",
29650 "lastModified",
29651 "lastModifiedDate",
29652 "lastPage",
29653 "lastParen",
29654 "lastState",
29655 "lastStyleSheetSet",
29656 "latency",
29657 "latitude",
29658 "launchQueue",
29659 "layerName",
29660 "layerX",
29661 "layerY",
29662 "layout",
29663 "layoutFlow",
29664 "layoutGrid",
29665 "layoutGridChar",
29666 "layoutGridLine",
29667 "layoutGridMode",
29668 "layoutGridType",
29669 "lbound",
29670 "leaveAdInterestGroup",
29671 "left",
29672 "leftContext",
29673 "leftDegrees",
29674 "leftMargin",
29675 "leftProjectionMatrix",
29676 "leftViewMatrix",
29677 "length",
29678 "lengthAdjust",
29679 "lengthComputable",
29680 "letter-spacing",
29681 "letterSpacing",
29682 "level",
29683 "lh",
29684 "lighting-color",
29685 "lightingColor",
29686 "limitingConeAngle",
29687 "limits",
29688 "line",
29689 "line-break",
29690 "line-height",
29691 "lineAlign",
29692 "lineBreak",
29693 "lineCap",
29694 "lineDashOffset",
29695 "lineGapOverride",
29696 "lineHeight",
29697 "lineJoin",
29698 "lineNum",
29699 "lineNumber",
29700 "linePos",
29701 "lineTo",
29702 "lineWidth",
29703 "linearAcceleration",
29704 "linearRampToValueAtTime",
29705 "linearVelocity",
29706 "lineno",
29707 "lines",
29708 "link",
29709 "linkColor",
29710 "linkProgram",
29711 "links",
29712 "list",
29713 "list-style",
29714 "list-style-image",
29715 "list-style-position",
29716 "list-style-type",
29717 "listStyle",
29718 "listStyleImage",
29719 "listStylePosition",
29720 "listStyleType",
29721 "listener",
29722 "listeners",
29723 "load",
29724 "loadEventEnd",
29725 "loadEventStart",
29726 "loadOp",
29727 "loadTime",
29728 "loadTimes",
29729 "loaded",
29730 "loading",
29731 "localDescription",
29732 "localName",
29733 "localService",
29734 "localStorage",
29735 "locale",
29736 "localeCompare",
29737 "location",
29738 "locationbar",
29739 "lock",
29740 "locked",
29741 "lockedFile",
29742 "locks",
29743 "lodMaxClamp",
29744 "lodMinClamp",
29745 "log",
29746 "log10",
29747 "log1p",
29748 "log2",
29749 "logicalXDPI",
29750 "logicalYDPI",
29751 "login",
29752 "loglevel",
29753 "longDesc",
29754 "longitude",
29755 "lookupNamespaceURI",
29756 "lookupPrefix",
29757 "loop",
29758 "loopEnd",
29759 "loopStart",
29760 "looping",
29761 "lost",
29762 "low",
29763 "lower",
29764 "lowerBound",
29765 "lowerOpen",
29766 "lowsrc",
29767 "lvb",
29768 "lvh",
29769 "lvi",
29770 "lvmax",
29771 "lvmin",
29772 "lvw",
29773 "m11",
29774 "m12",
29775 "m13",
29776 "m14",
29777 "m21",
29778 "m22",
29779 "m23",
29780 "m24",
29781 "m31",
29782 "m32",
29783 "m33",
29784 "m34",
29785 "m41",
29786 "m42",
29787 "m43",
29788 "m44",
29789 "magFilter",
29790 "makeXRCompatible",
29791 "managed",
29792 "management",
29793 "manifest",
29794 "manufacturer",
29795 "manufacturerName",
29796 "map",
29797 "mapAsync",
29798 "mapState",
29799 "mappedAtCreation",
29800 "mapping",
29801 "margin",
29802 "margin-block",
29803 "margin-block-end",
29804 "margin-block-start",
29805 "margin-bottom",
29806 "margin-inline",
29807 "margin-inline-end",
29808 "margin-inline-start",
29809 "margin-left",
29810 "margin-right",
29811 "margin-top",
29812 "marginBlock",
29813 "marginBlockEnd",
29814 "marginBlockStart",
29815 "marginBottom",
29816 "marginHeight",
29817 "marginInline",
29818 "marginInlineEnd",
29819 "marginInlineStart",
29820 "marginLeft",
29821 "marginRight",
29822 "marginTop",
29823 "marginWidth",
29824 "mark",
29825 "marker",
29826 "marker-end",
29827 "marker-mid",
29828 "marker-offset",
29829 "marker-start",
29830 "markerEnd",
29831 "markerHeight",
29832 "markerMid",
29833 "markerOffset",
29834 "markerStart",
29835 "markerUnits",
29836 "markerWidth",
29837 "marks",
29838 "mask",
29839 "mask-clip",
29840 "mask-composite",
29841 "mask-image",
29842 "mask-mode",
29843 "mask-origin",
29844 "mask-position",
29845 "mask-position-x",
29846 "mask-position-y",
29847 "mask-repeat",
29848 "mask-size",
29849 "mask-type",
29850 "maskClip",
29851 "maskComposite",
29852 "maskContentUnits",
29853 "maskImage",
29854 "maskMode",
29855 "maskOrigin",
29856 "maskPosition",
29857 "maskPositionX",
29858 "maskPositionY",
29859 "maskRepeat",
29860 "maskSize",
29861 "maskType",
29862 "maskUnits",
29863 "match",
29864 "matchAll",
29865 "matchMedia",
29866 "matchMedium",
29867 "matchPatterns",
29868 "matches",
29869 "math-depth",
29870 "math-style",
29871 "mathDepth",
29872 "mathShift",
29873 "mathStyle",
29874 "matrix",
29875 "matrixTransform",
29876 "max",
29877 "max-block-size",
29878 "max-height",
29879 "max-inline-size",
29880 "max-width",
29881 "maxActions",
29882 "maxAlternatives",
29883 "maxAnisotropy",
29884 "maxBindGroups",
29885 "maxBindGroupsPlusVertexBuffers",
29886 "maxBindingsPerBindGroup",
29887 "maxBlockSize",
29888 "maxBufferSize",
29889 "maxByteLength",
29890 "maxChannelCount",
29891 "maxChannels",
29892 "maxColorAttachmentBytesPerSample",
29893 "maxColorAttachments",
29894 "maxComputeInvocationsPerWorkgroup",
29895 "maxComputeWorkgroupSizeX",
29896 "maxComputeWorkgroupSizeY",
29897 "maxComputeWorkgroupSizeZ",
29898 "maxComputeWorkgroupStorageSize",
29899 "maxComputeWorkgroupsPerDimension",
29900 "maxConnectionsPerServer",
29901 "maxDatagramSize",
29902 "maxDecibels",
29903 "maxDistance",
29904 "maxDrawCount",
29905 "maxDynamicStorageBuffersPerPipelineLayout",
29906 "maxDynamicUniformBuffersPerPipelineLayout",
29907 "maxHeight",
29908 "maxInlineSize",
29909 "maxInterStageShaderComponents",
29910 "maxInterStageShaderVariables",
29911 "maxLayers",
29912 "maxLength",
29913 "maxMessageSize",
29914 "maxPacketLifeTime",
29915 "maxRetransmits",
29916 "maxSampledTexturesPerShaderStage",
29917 "maxSamplersPerShaderStage",
29918 "maxStorageBufferBindingSize",
29919 "maxStorageBuffersPerShaderStage",
29920 "maxStorageTexturesPerShaderStage",
29921 "maxTextureArrayLayers",
29922 "maxTextureDimension1D",
29923 "maxTextureDimension2D",
29924 "maxTextureDimension3D",
29925 "maxTouchPoints",
29926 "maxUniformBufferBindingSize",
29927 "maxUniformBuffersPerShaderStage",
29928 "maxValue",
29929 "maxVertexAttributes",
29930 "maxVertexBufferArrayStride",
29931 "maxVertexBuffers",
29932 "maxWidth",
29933 "maximumLatency",
29934 "measure",
29935 "measureInputUsage",
29936 "measureText",
29937 "media",
29938 "mediaCapabilities",
29939 "mediaDevices",
29940 "mediaElement",
29941 "mediaGroup",
29942 "mediaKeys",
29943 "mediaSession",
29944 "mediaStream",
29945 "mediaText",
29946 "meetOrSlice",
29947 "memory",
29948 "menubar",
29949 "menus",
29950 "menusChild",
29951 "menusInternal",
29952 "mergeAttributes",
29953 "message",
29954 "messageClass",
29955 "messageHandlers",
29956 "messageType",
29957 "messages",
29958 "metaKey",
29959 "metadata",
29960 "method",
29961 "methodDetails",
29962 "methodName",
29963 "microseconds",
29964 "mid",
29965 "milliseconds",
29966 "mimeType",
29967 "mimeTypes",
29968 "min",
29969 "min-block-size",
29970 "min-height",
29971 "min-inline-size",
29972 "min-width",
29973 "minBindingSize",
29974 "minBlockSize",
29975 "minDecibels",
29976 "minFilter",
29977 "minHeight",
29978 "minInlineSize",
29979 "minLength",
29980 "minStorageBufferOffsetAlignment",
29981 "minUniformBufferOffsetAlignment",
29982 "minValue",
29983 "minWidth",
29984 "minimumLatency",
29985 "minute",
29986 "minutes",
29987 "mipLevel",
29988 "mipLevelCount",
29989 "mipmapFilter",
29990 "miterLimit",
29991 "mix-blend-mode",
29992 "mixBlendMode",
29993 "mm",
29994 "mobile",
29995 "mode",
29996 "model",
29997 "modify",
29998 "module",
29999 "month",
30000 "months",
30001 "mount",
30002 "move",
30003 "moveBefore",
30004 "moveBy",
30005 "moveEnd",
30006 "moveFirst",
30007 "moveFocusDown",
30008 "moveFocusLeft",
30009 "moveFocusRight",
30010 "moveFocusUp",
30011 "moveInSuccession",
30012 "moveNext",
30013 "moveRow",
30014 "moveStart",
30015 "moveTo",
30016 "moveToBookmark",
30017 "moveToElementText",
30018 "moveToPoint",
30019 "movementX",
30020 "movementY",
30021 "mozAdd",
30022 "mozAnimationStartTime",
30023 "mozAnon",
30024 "mozApps",
30025 "mozAudioCaptured",
30026 "mozAudioChannelType",
30027 "mozAutoplayEnabled",
30028 "mozCancelAnimationFrame",
30029 "mozCancelFullScreen",
30030 "mozCancelRequestAnimationFrame",
30031 "mozCaptureStream",
30032 "mozCaptureStreamUntilEnded",
30033 "mozClearDataAt",
30034 "mozContact",
30035 "mozContacts",
30036 "mozCreateFileHandle",
30037 "mozCurrentTransform",
30038 "mozCurrentTransformInverse",
30039 "mozCursor",
30040 "mozDash",
30041 "mozDashOffset",
30042 "mozDecodedFrames",
30043 "mozExitPointerLock",
30044 "mozFillRule",
30045 "mozFragmentEnd",
30046 "mozFrameDelay",
30047 "mozFullScreen",
30048 "mozFullScreenElement",
30049 "mozFullScreenEnabled",
30050 "mozGetAll",
30051 "mozGetAllKeys",
30052 "mozGetAsFile",
30053 "mozGetDataAt",
30054 "mozGetMetadata",
30055 "mozGetUserMedia",
30056 "mozHasAudio",
30057 "mozHasItem",
30058 "mozHidden",
30059 "mozImageSmoothingEnabled",
30060 "mozIndexedDB",
30061 "mozInnerScreenX",
30062 "mozInnerScreenY",
30063 "mozInputSource",
30064 "mozIsTextField",
30065 "mozItem",
30066 "mozItemCount",
30067 "mozItems",
30068 "mozLength",
30069 "mozLockOrientation",
30070 "mozMatchesSelector",
30071 "mozMovementX",
30072 "mozMovementY",
30073 "mozOpaque",
30074 "mozOrientation",
30075 "mozPaintCount",
30076 "mozPaintedFrames",
30077 "mozParsedFrames",
30078 "mozPay",
30079 "mozPointerLockElement",
30080 "mozPresentedFrames",
30081 "mozPreservesPitch",
30082 "mozPressure",
30083 "mozPrintCallback",
30084 "mozRTCIceCandidate",
30085 "mozRTCPeerConnection",
30086 "mozRTCSessionDescription",
30087 "mozRemove",
30088 "mozRequestAnimationFrame",
30089 "mozRequestFullScreen",
30090 "mozRequestPointerLock",
30091 "mozSetDataAt",
30092 "mozSetImageElement",
30093 "mozSourceNode",
30094 "mozSrcObject",
30095 "mozSystem",
30096 "mozTCPSocket",
30097 "mozTextStyle",
30098 "mozTypesAt",
30099 "mozUnlockOrientation",
30100 "mozUserCancelled",
30101 "mozVisibilityState",
30102 "ms",
30103 "msAnimation",
30104 "msAnimationDelay",
30105 "msAnimationDirection",
30106 "msAnimationDuration",
30107 "msAnimationFillMode",
30108 "msAnimationIterationCount",
30109 "msAnimationName",
30110 "msAnimationPlayState",
30111 "msAnimationStartTime",
30112 "msAnimationTimingFunction",
30113 "msBackfaceVisibility",
30114 "msBlockProgression",
30115 "msCSSOMElementFloatMetrics",
30116 "msCaching",
30117 "msCachingEnabled",
30118 "msCancelRequestAnimationFrame",
30119 "msCapsLockWarningOff",
30120 "msClearImmediate",
30121 "msClose",
30122 "msContentZoomChaining",
30123 "msContentZoomFactor",
30124 "msContentZoomLimit",
30125 "msContentZoomLimitMax",
30126 "msContentZoomLimitMin",
30127 "msContentZoomSnap",
30128 "msContentZoomSnapPoints",
30129 "msContentZoomSnapType",
30130 "msContentZooming",
30131 "msConvertURL",
30132 "msCrypto",
30133 "msDoNotTrack",
30134 "msElementsFromPoint",
30135 "msElementsFromRect",
30136 "msExitFullscreen",
30137 "msExtendedCode",
30138 "msFillRule",
30139 "msFirstPaint",
30140 "msFlex",
30141 "msFlexAlign",
30142 "msFlexDirection",
30143 "msFlexFlow",
30144 "msFlexItemAlign",
30145 "msFlexLinePack",
30146 "msFlexNegative",
30147 "msFlexOrder",
30148 "msFlexPack",
30149 "msFlexPositive",
30150 "msFlexPreferredSize",
30151 "msFlexWrap",
30152 "msFlowFrom",
30153 "msFlowInto",
30154 "msFontFeatureSettings",
30155 "msFullscreenElement",
30156 "msFullscreenEnabled",
30157 "msGetInputContext",
30158 "msGetRegionContent",
30159 "msGetUntransformedBounds",
30160 "msGraphicsTrustStatus",
30161 "msGridColumn",
30162 "msGridColumnAlign",
30163 "msGridColumnSpan",
30164 "msGridColumns",
30165 "msGridRow",
30166 "msGridRowAlign",
30167 "msGridRowSpan",
30168 "msGridRows",
30169 "msHidden",
30170 "msHighContrastAdjust",
30171 "msHyphenateLimitChars",
30172 "msHyphenateLimitLines",
30173 "msHyphenateLimitZone",
30174 "msHyphens",
30175 "msImageSmoothingEnabled",
30176 "msImeAlign",
30177 "msIndexedDB",
30178 "msInterpolationMode",
30179 "msIsStaticHTML",
30180 "msKeySystem",
30181 "msKeys",
30182 "msLaunchUri",
30183 "msLockOrientation",
30184 "msManipulationViewsEnabled",
30185 "msMatchMedia",
30186 "msMatchesSelector",
30187 "msMaxTouchPoints",
30188 "msOrientation",
30189 "msOverflowStyle",
30190 "msPerspective",
30191 "msPerspectiveOrigin",
30192 "msPlayToDisabled",
30193 "msPlayToPreferredSourceUri",
30194 "msPlayToPrimary",
30195 "msPointerEnabled",
30196 "msRegionOverflow",
30197 "msReleasePointerCapture",
30198 "msRequestAnimationFrame",
30199 "msRequestFullscreen",
30200 "msSaveBlob",
30201 "msSaveOrOpenBlob",
30202 "msScrollChaining",
30203 "msScrollLimit",
30204 "msScrollLimitXMax",
30205 "msScrollLimitXMin",
30206 "msScrollLimitYMax",
30207 "msScrollLimitYMin",
30208 "msScrollRails",
30209 "msScrollSnapPointsX",
30210 "msScrollSnapPointsY",
30211 "msScrollSnapType",
30212 "msScrollSnapX",
30213 "msScrollSnapY",
30214 "msScrollTranslation",
30215 "msSetImmediate",
30216 "msSetMediaKeys",
30217 "msSetPointerCapture",
30218 "msTextCombineHorizontal",
30219 "msTextSizeAdjust",
30220 "msToBlob",
30221 "msTouchAction",
30222 "msTouchSelect",
30223 "msTraceAsyncCallbackCompleted",
30224 "msTraceAsyncCallbackStarting",
30225 "msTraceAsyncOperationCompleted",
30226 "msTraceAsyncOperationStarting",
30227 "msTransform",
30228 "msTransformOrigin",
30229 "msTransformStyle",
30230 "msTransition",
30231 "msTransitionDelay",
30232 "msTransitionDuration",
30233 "msTransitionProperty",
30234 "msTransitionTimingFunction",
30235 "msUnlockOrientation",
30236 "msUpdateAsyncCallbackRelation",
30237 "msUserSelect",
30238 "msVisibilityState",
30239 "msWrapFlow",
30240 "msWrapMargin",
30241 "msWrapThrough",
30242 "msWriteProfilerMark",
30243 "msZoom",
30244 "msZoomTo",
30245 "mt",
30246 "mul",
30247 "multiEntry",
30248 "multiSelectionObj",
30249 "multiline",
30250 "multiple",
30251 "multiply",
30252 "multiplySelf",
30253 "multisample",
30254 "multisampled",
30255 "mutableFile",
30256 "muted",
30257 "n",
30258 "nacl_arch",
30259 "name",
30260 "nameList",
30261 "nameProp",
30262 "namedItem",
30263 "namedRecordset",
30264 "names",
30265 "namespaceURI",
30266 "namespaces",
30267 "nanoseconds",
30268 "nativeApplication",
30269 "nativeMap",
30270 "nativeObjectCreate",
30271 "nativeSet",
30272 "nativeWeakMap",
30273 "naturalHeight",
30274 "naturalWidth",
30275 "navigate",
30276 "navigation",
30277 "navigationMode",
30278 "navigationPreload",
30279 "navigationStart",
30280 "navigationType",
30281 "navigator",
30282 "near",
30283 "nearestViewportElement",
30284 "negative",
30285 "negotiated",
30286 "netscape",
30287 "networkState",
30288 "networkStatus",
30289 "newScale",
30290 "newState",
30291 "newTranslate",
30292 "newURL",
30293 "newValue",
30294 "newValueSpecifiedUnits",
30295 "newVersion",
30296 "newhome",
30297 "next",
30298 "nextElementSibling",
30299 "nextHopProtocol",
30300 "nextNode",
30301 "nextPage",
30302 "nextSibling",
30303 "nickname",
30304 "noHref",
30305 "noModule",
30306 "noResize",
30307 "noShade",
30308 "noValidate",
30309 "noWrap",
30310 "node",
30311 "nodeName",
30312 "nodeType",
30313 "nodeValue",
30314 "nonce",
30315 "normDepthBufferFromNormView",
30316 "normalize",
30317 "normalizedPathSegList",
30318 "normandyAddonStudy",
30319 "notRestoredReasons",
30320 "notationName",
30321 "notations",
30322 "note",
30323 "noteGrainOn",
30324 "noteOff",
30325 "noteOn",
30326 "notifications",
30327 "notify",
30328 "now",
30329 "npnNegotiatedProtocol",
30330 "numOctaves",
30331 "number",
30332 "numberOfChannels",
30333 "numberOfFrames",
30334 "numberOfInputs",
30335 "numberOfItems",
30336 "numberOfOutputs",
30337 "numberValue",
30338 "numberingSystem",
30339 "numeric",
30340 "oMatchesSelector",
30341 "object",
30342 "object-fit",
30343 "object-position",
30344 "objectFit",
30345 "objectPosition",
30346 "objectStore",
30347 "objectStoreNames",
30348 "objectType",
30349 "observe",
30350 "observedAttributes",
30351 "occlusionQuerySet",
30352 "of",
30353 "off",
30354 "offscreenBuffering",
30355 "offset",
30356 "offset-anchor",
30357 "offset-distance",
30358 "offset-path",
30359 "offset-position",
30360 "offset-rotate",
30361 "offsetAnchor",
30362 "offsetDistance",
30363 "offsetHeight",
30364 "offsetLeft",
30365 "offsetNode",
30366 "offsetParent",
30367 "offsetPath",
30368 "offsetPosition",
30369 "offsetRotate",
30370 "offsetTop",
30371 "offsetWidth",
30372 "offsetX",
30373 "offsetY",
30374 "ok",
30375 "oldState",
30376 "oldURL",
30377 "oldValue",
30378 "oldVersion",
30379 "olderShadowRoot",
30380 "omnibox",
30381 "on",
30382 "onActivated",
30383 "onAdded",
30384 "onAttached",
30385 "onBoundsChanged",
30386 "onBrowserUpdateAvailable",
30387 "onClicked",
30388 "onCommitFiberRoot",
30389 "onCommitFiberUnmount",
30390 "onConnect",
30391 "onConnectExternal",
30392 "onConnectNative",
30393 "onCreated",
30394 "onDetached",
30395 "onDisabled",
30396 "onEnabled",
30397 "onFocusChanged",
30398 "onHighlighted",
30399 "onInstalled",
30400 "onLine",
30401 "onMessage",
30402 "onMessageExternal",
30403 "onMoved",
30404 "onPerformanceWarning",
30405 "onPostCommitFiberRoot",
30406 "onRemoved",
30407 "onReplaced",
30408 "onRestartRequired",
30409 "onStartup",
30410 "onSubmittedWorkDone",
30411 "onSuspend",
30412 "onSuspendCanceled",
30413 "onUninstalled",
30414 "onUpdateAvailable",
30415 "onUpdated",
30416 "onUserScriptConnect",
30417 "onUserScriptMessage",
30418 "onUserSettingsChanged",
30419 "onZoomChange",
30420 "onabort",
30421 "onabsolutedeviceorientation",
30422 "onactivate",
30423 "onactive",
30424 "onaddsourcebuffer",
30425 "onaddstream",
30426 "onaddtrack",
30427 "onafterprint",
30428 "onafterscriptexecute",
30429 "onafterupdate",
30430 "onanimationcancel",
30431 "onanimationend",
30432 "onanimationiteration",
30433 "onanimationstart",
30434 "onappinstalled",
30435 "onaudioend",
30436 "onaudioprocess",
30437 "onaudiostart",
30438 "onautocomplete",
30439 "onautocompleteerror",
30440 "onauxclick",
30441 "onbeforeactivate",
30442 "onbeforecopy",
30443 "onbeforecut",
30444 "onbeforedeactivate",
30445 "onbeforeeditfocus",
30446 "onbeforeinput",
30447 "onbeforeinstallprompt",
30448 "onbeforematch",
30449 "onbeforepaste",
30450 "onbeforeprint",
30451 "onbeforescriptexecute",
30452 "onbeforetoggle",
30453 "onbeforeunload",
30454 "onbeforeupdate",
30455 "onbeforexrselect",
30456 "onbegin",
30457 "onblocked",
30458 "onblur",
30459 "onbounce",
30460 "onboundary",
30461 "onbufferedamountlow",
30462 "oncached",
30463 "oncancel",
30464 "oncandidatewindowhide",
30465 "oncandidatewindowshow",
30466 "oncandidatewindowupdate",
30467 "oncanplay",
30468 "oncanplaythrough",
30469 "oncapturehandlechange",
30470 "once",
30471 "oncellchange",
30472 "onchange",
30473 "oncharacterboundsupdate",
30474 "oncharacteristicvaluechanged",
30475 "onchargingchange",
30476 "onchargingtimechange",
30477 "onchecking",
30478 "onclick",
30479 "onclose",
30480 "onclosing",
30481 "oncommand",
30482 "oncompassneedscalibration",
30483 "oncomplete",
30484 "oncompositionend",
30485 "oncompositionstart",
30486 "onconnect",
30487 "onconnecting",
30488 "onconnectionavailable",
30489 "onconnectionstatechange",
30490 "oncontentvisibilityautostatechange",
30491 "oncontextlost",
30492 "oncontextmenu",
30493 "oncontextrestored",
30494 "oncontrollerchange",
30495 "oncontrolselect",
30496 "oncopy",
30497 "oncuechange",
30498 "oncurrententrychange",
30499 "oncurrentscreenchange",
30500 "oncut",
30501 "ondataavailable",
30502 "ondatachannel",
30503 "ondatasetchanged",
30504 "ondatasetcomplete",
30505 "ondblclick",
30506 "ondeactivate",
30507 "ondequeue",
30508 "ondevicechange",
30509 "ondevicelight",
30510 "ondevicemotion",
30511 "ondeviceorientation",
30512 "ondeviceorientationabsolute",
30513 "ondeviceproximity",
30514 "ondischargingtimechange",
30515 "ondisconnect",
30516 "ondisplay",
30517 "ondispose",
30518 "ondownloading",
30519 "ondownloadprogress",
30520 "ondrag",
30521 "ondragend",
30522 "ondragenter",
30523 "ondragexit",
30524 "ondragleave",
30525 "ondragover",
30526 "ondragstart",
30527 "ondrop",
30528 "ondurationchange",
30529 "onemptied",
30530 "onencrypted",
30531 "onend",
30532 "onended",
30533 "onenter",
30534 "onenterpictureinpicture",
30535 "onerror",
30536 "onerrorupdate",
30537 "onexit",
30538 "onfencedtreeclick",
30539 "onfilterchange",
30540 "onfinish",
30541 "onfocus",
30542 "onfocusin",
30543 "onfocusout",
30544 "onformdata",
30545 "onfreeze",
30546 "onfullscreenchange",
30547 "onfullscreenerror",
30548 "ongamepadconnected",
30549 "ongamepaddisconnected",
30550 "ongatheringstatechange",
30551 "ongattserverdisconnected",
30552 "ongeometrychange",
30553 "ongesturechange",
30554 "ongestureend",
30555 "ongesturestart",
30556 "ongotpointercapture",
30557 "onhashchange",
30558 "onhelp",
30559 "onicecandidate",
30560 "onicecandidateerror",
30561 "oniceconnectionstatechange",
30562 "onicegatheringstatechange",
30563 "oninactive",
30564 "oninput",
30565 "oninputreport",
30566 "oninputsourceschange",
30567 "oninvalid",
30568 "onkeydown",
30569 "onkeypress",
30570 "onkeystatuseschange",
30571 "onkeyup",
30572 "onlanguagechange",
30573 "onlayoutcomplete",
30574 "onleavepictureinpicture",
30575 "onlevelchange",
30576 "onload",
30577 "onloadT",
30578 "onloadeddata",
30579 "onloadedmetadata",
30580 "onloadend",
30581 "onloading",
30582 "onloadingdone",
30583 "onloadingerror",
30584 "onloadstart",
30585 "onlosecapture",
30586 "onlostpointercapture",
30587 "only",
30588 "onmanagedconfigurationchange",
30589 "onmark",
30590 "onmessage",
30591 "onmessageerror",
30592 "onmidimessage",
30593 "onmousedown",
30594 "onmouseenter",
30595 "onmouseleave",
30596 "onmousemove",
30597 "onmouseout",
30598 "onmouseover",
30599 "onmouseup",
30600 "onmousewheel",
30601 "onmove",
30602 "onmoveend",
30603 "onmovestart",
30604 "onmozfullscreenchange",
30605 "onmozfullscreenerror",
30606 "onmozorientationchange",
30607 "onmozpointerlockchange",
30608 "onmozpointerlockerror",
30609 "onmscontentzoom",
30610 "onmsfullscreenchange",
30611 "onmsfullscreenerror",
30612 "onmsgesturechange",
30613 "onmsgesturedoubletap",
30614 "onmsgestureend",
30615 "onmsgesturehold",
30616 "onmsgesturestart",
30617 "onmsgesturetap",
30618 "onmsgotpointercapture",
30619 "onmsinertiastart",
30620 "onmslostpointercapture",
30621 "onmsmanipulationstatechanged",
30622 "onmsneedkey",
30623 "onmsorientationchange",
30624 "onmspointercancel",
30625 "onmspointerdown",
30626 "onmspointerenter",
30627 "onmspointerhover",
30628 "onmspointerleave",
30629 "onmspointermove",
30630 "onmspointerout",
30631 "onmspointerover",
30632 "onmspointerup",
30633 "onmssitemodejumplistitemremoved",
30634 "onmsthumbnailclick",
30635 "onmute",
30636 "onnavigate",
30637 "onnavigateerror",
30638 "onnavigatesuccess",
30639 "onnegotiationneeded",
30640 "onnomatch",
30641 "onnoupdate",
30642 "onobsolete",
30643 "onoffline",
30644 "ononline",
30645 "onopen",
30646 "onorientationchange",
30647 "onpagechange",
30648 "onpagehide",
30649 "onpagereveal",
30650 "onpageshow",
30651 "onpageswap",
30652 "onpaste",
30653 "onpause",
30654 "onpayerdetailchange",
30655 "onpaymentmethodchange",
30656 "onplay",
30657 "onplaying",
30658 "onpluginstreamstart",
30659 "onpointercancel",
30660 "onpointerdown",
30661 "onpointerenter",
30662 "onpointerleave",
30663 "onpointerlockchange",
30664 "onpointerlockerror",
30665 "onpointermove",
30666 "onpointerout",
30667 "onpointerover",
30668 "onpointerrawupdate",
30669 "onpointerup",
30670 "onpopstate",
30671 "onprerenderingchange",
30672 "onprioritychange",
30673 "onprocessorerror",
30674 "onprogress",
30675 "onpropertychange",
30676 "onratechange",
30677 "onreading",
30678 "onreadystatechange",
30679 "onreflectionchange",
30680 "onrejectionhandled",
30681 "onrelease",
30682 "onremove",
30683 "onremovesourcebuffer",
30684 "onremovestream",
30685 "onremovetrack",
30686 "onrepeat",
30687 "onreset",
30688 "onresize",
30689 "onresizeend",
30690 "onresizestart",
30691 "onresourcetimingbufferfull",
30692 "onresult",
30693 "onresume",
30694 "onrowenter",
30695 "onrowexit",
30696 "onrowsdelete",
30697 "onrowsinserted",
30698 "onscreenschange",
30699 "onscroll",
30700 "onscrollend",
30701 "onscrollsnapchange",
30702 "onscrollsnapchanging",
30703 "onsearch",
30704 "onsecuritypolicyviolation",
30705 "onseeked",
30706 "onseeking",
30707 "onselect",
30708 "onselectedcandidatepairchange",
30709 "onselectend",
30710 "onselectionchange",
30711 "onselectstart",
30712 "onshippingaddresschange",
30713 "onshippingoptionchange",
30714 "onshow",
30715 "onsignalingstatechange",
30716 "onsinkchange",
30717 "onslotchange",
30718 "onsoundend",
30719 "onsoundstart",
30720 "onsourceclose",
30721 "onsourceclosed",
30722 "onsourceended",
30723 "onsourceopen",
30724 "onspeechend",
30725 "onspeechstart",
30726 "onsqueeze",
30727 "onsqueezeend",
30728 "onsqueezestart",
30729 "onstalled",
30730 "onstart",
30731 "onstatechange",
30732 "onstop",
30733 "onstorage",
30734 "onstoragecommit",
30735 "onsubmit",
30736 "onsuccess",
30737 "onsuspend",
30738 "onterminate",
30739 "ontextformatupdate",
30740 "ontextinput",
30741 "ontextupdate",
30742 "ontimeout",
30743 "ontimeupdate",
30744 "ontoggle",
30745 "ontonechange",
30746 "ontouchcancel",
30747 "ontouchend",
30748 "ontouchmove",
30749 "ontouchstart",
30750 "ontrack",
30751 "ontransitioncancel",
30752 "ontransitionend",
30753 "ontransitionrun",
30754 "ontransitionstart",
30755 "onuncapturederror",
30756 "onunhandledrejection",
30757 "onunload",
30758 "onunmute",
30759 "onupdate",
30760 "onupdateend",
30761 "onupdatefound",
30762 "onupdateready",
30763 "onupdatestart",
30764 "onupgradeneeded",
30765 "onuserproximity",
30766 "onversionchange",
30767 "onvisibilitychange",
30768 "onvoiceschanged",
30769 "onvolumechange",
30770 "onvrdisplayactivate",
30771 "onvrdisplayconnect",
30772 "onvrdisplaydeactivate",
30773 "onvrdisplaydisconnect",
30774 "onvrdisplaypresentchange",
30775 "onwaiting",
30776 "onwaitingforkey",
30777 "onwarning",
30778 "onwebkitanimationend",
30779 "onwebkitanimationiteration",
30780 "onwebkitanimationstart",
30781 "onwebkitcurrentplaybacktargetiswirelesschanged",
30782 "onwebkitfullscreenchange",
30783 "onwebkitfullscreenerror",
30784 "onwebkitkeyadded",
30785 "onwebkitkeyerror",
30786 "onwebkitkeymessage",
30787 "onwebkitneedkey",
30788 "onwebkitorientationchange",
30789 "onwebkitplaybacktargetavailabilitychanged",
30790 "onwebkitpointerlockchange",
30791 "onwebkitpointerlockerror",
30792 "onwebkitresourcetimingbufferfull",
30793 "onwebkittransitionend",
30794 "onwheel",
30795 "onzoom",
30796 "onzoomlevelchange",
30797 "opacity",
30798 "open",
30799 "openCursor",
30800 "openDatabase",
30801 "openKeyCursor",
30802 "openOptionsPage",
30803 "openOrClosedShadowRoot",
30804 "openPopup",
30805 "opened",
30806 "opener",
30807 "opera",
30808 "operation",
30809 "operationType",
30810 "operator",
30811 "opr",
30812 "optimum",
30813 "options",
30814 "or",
30815 "order",
30816 "orderX",
30817 "orderY",
30818 "ordered",
30819 "org",
30820 "organization",
30821 "orient",
30822 "orientAngle",
30823 "orientType",
30824 "orientation",
30825 "orientationX",
30826 "orientationY",
30827 "orientationZ",
30828 "origin",
30829 "originAgentCluster",
30830 "originalPolicy",
30831 "originalTarget",
30832 "ornaments",
30833 "orphans",
30834 "os",
30835 "oscpu",
30836 "outerHTML",
30837 "outerHeight",
30838 "outerText",
30839 "outerWidth",
30840 "outgoingHighWaterMark",
30841 "outgoingMaxAge",
30842 "outline",
30843 "outline-color",
30844 "outline-offset",
30845 "outline-style",
30846 "outline-width",
30847 "outlineColor",
30848 "outlineOffset",
30849 "outlineStyle",
30850 "outlineWidth",
30851 "outputBuffer",
30852 "outputChannelCount",
30853 "outputLanguage",
30854 "outputLatency",
30855 "outputs",
30856 "overallProgress",
30857 "overflow",
30858 "overflow-anchor",
30859 "overflow-block",
30860 "overflow-clip-margin",
30861 "overflow-inline",
30862 "overflow-wrap",
30863 "overflow-x",
30864 "overflow-y",
30865 "overflowAnchor",
30866 "overflowBlock",
30867 "overflowClipMargin",
30868 "overflowInline",
30869 "overflowWrap",
30870 "overflowX",
30871 "overflowY",
30872 "overlaysContent",
30873 "overrideColors",
30874 "overrideMimeType",
30875 "oversample",
30876 "overscroll-behavior",
30877 "overscroll-behavior-block",
30878 "overscroll-behavior-inline",
30879 "overscroll-behavior-x",
30880 "overscroll-behavior-y",
30881 "overscrollBehavior",
30882 "overscrollBehaviorBlock",
30883 "overscrollBehaviorInline",
30884 "overscrollBehaviorX",
30885 "overscrollBehaviorY",
30886 "ownKeys",
30887 "ownerDocument",
30888 "ownerElement",
30889 "ownerNode",
30890 "ownerRule",
30891 "ownerSVGElement",
30892 "owningElement",
30893 "p1",
30894 "p2",
30895 "p3",
30896 "p4",
30897 "packetSize",
30898 "packets",
30899 "pad",
30900 "padEnd",
30901 "padStart",
30902 "padding",
30903 "padding-block",
30904 "padding-block-end",
30905 "padding-block-start",
30906 "padding-bottom",
30907 "padding-inline",
30908 "padding-inline-end",
30909 "padding-inline-start",
30910 "padding-left",
30911 "padding-right",
30912 "padding-top",
30913 "paddingBlock",
30914 "paddingBlockEnd",
30915 "paddingBlockStart",
30916 "paddingBottom",
30917 "paddingInline",
30918 "paddingInlineEnd",
30919 "paddingInlineStart",
30920 "paddingLeft",
30921 "paddingRight",
30922 "paddingTop",
30923 "page",
30924 "page-break-after",
30925 "page-break-before",
30926 "page-break-inside",
30927 "page-orientation",
30928 "pageAction",
30929 "pageBreakAfter",
30930 "pageBreakBefore",
30931 "pageBreakInside",
30932 "pageCount",
30933 "pageLeft",
30934 "pageOrientation",
30935 "pageT",
30936 "pageTop",
30937 "pageX",
30938 "pageXOffset",
30939 "pageY",
30940 "pageYOffset",
30941 "pages",
30942 "paint-order",
30943 "paintOrder",
30944 "paintRequests",
30945 "paintTime",
30946 "paintType",
30947 "paintWorklet",
30948 "palette",
30949 "pan",
30950 "panningModel",
30951 "parameterData",
30952 "parameters",
30953 "parent",
30954 "parentElement",
30955 "parentNode",
30956 "parentRule",
30957 "parentStyleSheet",
30958 "parentTextEdit",
30959 "parentWindow",
30960 "parse",
30961 "parseAll",
30962 "parseCreationOptionsFromJSON",
30963 "parseFloat",
30964 "parseFromString",
30965 "parseHTMLUnsafe",
30966 "parseInt",
30967 "parseRequestOptionsFromJSON",
30968 "part",
30969 "participants",
30970 "passOp",
30971 "passive",
30972 "password",
30973 "pasteHTML",
30974 "path",
30975 "pathLength",
30976 "pathSegList",
30977 "pathSegType",
30978 "pathSegTypeAsLetter",
30979 "pathname",
30980 "pattern",
30981 "patternContentUnits",
30982 "patternMismatch",
30983 "patternTransform",
30984 "patternUnits",
30985 "pause",
30986 "pauseAnimations",
30987 "pauseDepthSensing",
30988 "pauseDuration",
30989 "pauseOnExit",
30990 "pauseProfilers",
30991 "pauseTransformFeedback",
30992 "paused",
30993 "payerEmail",
30994 "payerName",
30995 "payerPhone",
30996 "paymentManager",
30997 "pc",
30998 "pdfViewerEnabled",
30999 "peerIdentity",
31000 "pending",
31001 "pendingLocalDescription",
31002 "pendingRemoteDescription",
31003 "percent",
31004 "performance",
31005 "periodicSync",
31006 "permission",
31007 "permissionState",
31008 "permissions",
31009 "persist",
31010 "persisted",
31011 "persistentDeviceId",
31012 "personalbar",
31013 "perspective",
31014 "perspective-origin",
31015 "perspectiveOrigin",
31016 "phone",
31017 "phoneticFamilyName",
31018 "phoneticGivenName",
31019 "photo",
31020 "phrase",
31021 "phrases",
31022 "pictureInPictureChild",
31023 "pictureInPictureElement",
31024 "pictureInPictureEnabled",
31025 "pictureInPictureWindow",
31026 "ping",
31027 "pipeThrough",
31028 "pipeTo",
31029 "pitch",
31030 "pixelBottom",
31031 "pixelDepth",
31032 "pixelFormat",
31033 "pixelHeight",
31034 "pixelLeft",
31035 "pixelRight",
31036 "pixelStorei",
31037 "pixelTop",
31038 "pixelUnitToMillimeterX",
31039 "pixelUnitToMillimeterY",
31040 "pixelWidth",
31041 "pkcs11",
31042 "place-content",
31043 "place-items",
31044 "place-self",
31045 "placeContent",
31046 "placeItems",
31047 "placeSelf",
31048 "placeholder",
31049 "platform",
31050 "platformVersion",
31051 "platforms",
31052 "play",
31053 "playEffect",
31054 "playState",
31055 "playbackRate",
31056 "playbackState",
31057 "playbackTime",
31058 "played",
31059 "playoutDelayHint",
31060 "playsInline",
31061 "plugins",
31062 "pluginspage",
31063 "pname",
31064 "pointer-events",
31065 "pointerBeforeReferenceNode",
31066 "pointerEnabled",
31067 "pointerEvents",
31068 "pointerId",
31069 "pointerLockElement",
31070 "pointerType",
31071 "points",
31072 "pointsAtX",
31073 "pointsAtY",
31074 "pointsAtZ",
31075 "polygonOffset",
31076 "pop",
31077 "popDebugGroup",
31078 "popErrorScope",
31079 "popover",
31080 "popoverTargetAction",
31081 "popoverTargetElement",
31082 "populateMatrix",
31083 "popupWindowFeatures",
31084 "popupWindowName",
31085 "popupWindowURI",
31086 "port",
31087 "port1",
31088 "port2",
31089 "ports",
31090 "posBottom",
31091 "posHeight",
31092 "posLeft",
31093 "posRight",
31094 "posTop",
31095 "posWidth",
31096 "pose",
31097 "position",
31098 "position-anchor",
31099 "position-area",
31100 "positionAlign",
31101 "positionAnchor",
31102 "positionArea",
31103 "positionTry",
31104 "positionTryFallbacks",
31105 "positionVisibility",
31106 "positionX",
31107 "positionY",
31108 "positionZ",
31109 "postError",
31110 "postMessage",
31111 "postTask",
31112 "postalCode",
31113 "poster",
31114 "postscriptName",
31115 "pow",
31116 "powerEfficient",
31117 "powerOff",
31118 "powerPreference",
31119 "preMultiplySelf",
31120 "precision",
31121 "preferredReflectionFormat",
31122 "preferredStyleSheetSet",
31123 "preferredStylesheetSet",
31124 "prefix",
31125 "preload",
31126 "premultipliedAlpha",
31127 "prepend",
31128 "prerendering",
31129 "presentation",
31130 "presentationArea",
31131 "presentationStyle",
31132 "presentationTime",
31133 "preserveAlpha",
31134 "preserveAspectRatio",
31135 "preserveAspectRatioString",
31136 "preservesPitch",
31137 "pressed",
31138 "pressure",
31139 "prevValue",
31140 "preventDefault",
31141 "preventExtensions",
31142 "preventSilentAccess",
31143 "previousElementSibling",
31144 "previousNode",
31145 "previousPage",
31146 "previousPriority",
31147 "previousRect",
31148 "previousScale",
31149 "previousSibling",
31150 "previousTranslate",
31151 "primaries",
31152 "primaryKey",
31153 "primaryLightDirection",
31154 "primaryLightIntensity",
31155 "primitive",
31156 "primitiveType",
31157 "primitiveUnits",
31158 "principals",
31159 "print",
31160 "print-color-adjust",
31161 "printColorAdjust",
31162 "printPreview",
31163 "priority",
31164 "privacy",
31165 "privateKey",
31166 "privateToken",
31167 "probablySupportsContext",
31168 "probeSpace",
31169 "process",
31170 "processIceMessage",
31171 "processLocally",
31172 "processingEnd",
31173 "processingStart",
31174 "processorOptions",
31175 "product",
31176 "productId",
31177 "productName",
31178 "productSub",
31179 "profile",
31180 "profileEnd",
31181 "profiles",
31182 "projectionMatrix",
31183 "promise",
31184 "promising",
31185 "prompt",
31186 "properties",
31187 "propertyIsEnumerable",
31188 "propertyName",
31189 "protectedAudience",
31190 "protocol",
31191 "protocolLong",
31192 "prototype",
31193 "provider",
31194 "proxy",
31195 "pseudoClass",
31196 "pseudoElement",
31197 "pt",
31198 "publicId",
31199 "publicKey",
31200 "published",
31201 "pulse",
31202 "push",
31203 "pushDebugGroup",
31204 "pushErrorScope",
31205 "pushManager",
31206 "pushNotification",
31207 "pushState",
31208 "put",
31209 "putImageData",
31210 "px",
31211 "quadraticCurveTo",
31212 "qualifier",
31213 "quaternion",
31214 "query",
31215 "queryCommandEnabled",
31216 "queryCommandIndeterm",
31217 "queryCommandState",
31218 "queryCommandSupported",
31219 "queryCommandText",
31220 "queryCommandValue",
31221 "queryFeatureSupport",
31222 "queryLocalFonts",
31223 "queryPermission",
31224 "querySelector",
31225 "querySelectorAll",
31226 "querySet",
31227 "queue",
31228 "queueMicrotask",
31229 "quota",
31230 "quote",
31231 "quotes",
31232 "r",
31233 "r1",
31234 "r2",
31235 "race",
31236 "rad",
31237 "radiogroup",
31238 "radius",
31239 "radiusX",
31240 "radiusY",
31241 "random",
31242 "randomUUID",
31243 "range",
31244 "rangeCount",
31245 "rangeEnd",
31246 "rangeMax",
31247 "rangeMin",
31248 "rangeOffset",
31249 "rangeOverflow",
31250 "rangeParent",
31251 "rangeStart",
31252 "rangeUnderflow",
31253 "rate",
31254 "ratio",
31255 "raw",
31256 "rawId",
31257 "rawJSON",
31258 "rawValueToMeters",
31259 "rcap",
31260 "rch",
31261 "read",
31262 "readAsArrayBuffer",
31263 "readAsBinaryString",
31264 "readAsBlob",
31265 "readAsDataURL",
31266 "readAsText",
31267 "readBuffer",
31268 "readEntries",
31269 "readOnly",
31270 "readPixels",
31271 "readReportRequested",
31272 "readText",
31273 "readValue",
31274 "readable",
31275 "ready",
31276 "readyState",
31277 "reason",
31278 "reasons",
31279 "reboot",
31280 "receiveFeatureReport",
31281 "receivedAlert",
31282 "receiver",
31283 "receivers",
31284 "recipient",
31285 "recommendedViewportScale",
31286 "reconnect",
31287 "recordNumber",
31288 "recordsAvailable",
31289 "recordset",
31290 "rect",
31291 "red",
31292 "redEyeReduction",
31293 "redirect",
31294 "redirectCount",
31295 "redirectEnd",
31296 "redirectStart",
31297 "redirected",
31298 "reduce",
31299 "reduceRight",
31300 "reduction",
31301 "refDistance",
31302 "refX",
31303 "refY",
31304 "referenceNode",
31305 "referenceSpace",
31306 "referrer",
31307 "referrerPolicy",
31308 "refresh",
31309 "region",
31310 "regionAnchorX",
31311 "regionAnchorY",
31312 "regionId",
31313 "regions",
31314 "register",
31315 "registerContentHandler",
31316 "registerElement",
31317 "registerInternalModuleStart",
31318 "registerInternalModuleStop",
31319 "registerProperty",
31320 "registerProtocolHandler",
31321 "reject",
31322 "rel",
31323 "relList",
31324 "relatedAddress",
31325 "relatedNode",
31326 "relatedPort",
31327 "relatedTarget",
31328 "relayProtocol",
31329 "release",
31330 "releaseCapture",
31331 "releaseEvents",
31332 "releaseInterface",
31333 "releaseLock",
31334 "releasePointerCapture",
31335 "releaseShaderCompiler",
31336 "released",
31337 "reliability",
31338 "reliable",
31339 "reliableWrite",
31340 "reload",
31341 "rem",
31342 "remainingSpace",
31343 "remote",
31344 "remoteDescription",
31345 "remove",
31346 "removeAllRanges",
31347 "removeAttribute",
31348 "removeAttributeNS",
31349 "removeAttributeNode",
31350 "removeBehavior",
31351 "removeChild",
31352 "removeCue",
31353 "removeEntry",
31354 "removeEventListener",
31355 "removeFilter",
31356 "removeImport",
31357 "removeItem",
31358 "removeListener",
31359 "removeNamedItem",
31360 "removeNamedItemNS",
31361 "removeNode",
31362 "removeParameter",
31363 "removeProperty",
31364 "removeRange",
31365 "removeRegion",
31366 "removeRule",
31367 "removeSiteSpecificTrackingException",
31368 "removeSourceBuffer",
31369 "removeStream",
31370 "removeTrack",
31371 "removeVariable",
31372 "removeWakeLockListener",
31373 "removeWebWideTrackingException",
31374 "removed",
31375 "removedNodes",
31376 "renderBlockingStatus",
31377 "renderHeight",
31378 "renderStart",
31379 "renderState",
31380 "renderTime",
31381 "renderWidth",
31382 "renderbufferStorage",
31383 "renderbufferStorageMultisample",
31384 "renderedBuffer",
31385 "rendererInterfaces",
31386 "renderers",
31387 "renderingMode",
31388 "renotify",
31389 "repeat",
31390 "repetitionCount",
31391 "replace",
31392 "replaceAdjacentText",
31393 "replaceAll",
31394 "replaceChild",
31395 "replaceChildren",
31396 "replaceData",
31397 "replaceId",
31398 "replaceItem",
31399 "replaceNode",
31400 "replaceState",
31401 "replaceSync",
31402 "replaceTrack",
31403 "replaceWholeText",
31404 "replaceWith",
31405 "reportError",
31406 "reportEvent",
31407 "reportId",
31408 "reportOnly",
31409 "reportValidity",
31410 "request",
31411 "requestAdapter",
31412 "requestAdapterInfo",
31413 "requestAnimationFrame",
31414 "requestAutocomplete",
31415 "requestClose",
31416 "requestData",
31417 "requestDevice",
31418 "requestFrame",
31419 "requestFullscreen",
31420 "requestHitTestSource",
31421 "requestHitTestSourceForTransientInput",
31422 "requestId",
31423 "requestIdleCallback",
31424 "requestLightProbe",
31425 "requestMIDIAccess",
31426 "requestMediaKeySystemAccess",
31427 "requestPermission",
31428 "requestPictureInPicture",
31429 "requestPointerLock",
31430 "requestPort",
31431 "requestPresent",
31432 "requestPresenter",
31433 "requestReferenceSpace",
31434 "requestSession",
31435 "requestStart",
31436 "requestStorageAccess",
31437 "requestStorageAccessFor",
31438 "requestSubmit",
31439 "requestTime",
31440 "requestUpdateCheck",
31441 "requestVideoFrameCallback",
31442 "requestViewportScale",
31443 "requestWindow",
31444 "requested",
31445 "requestingWindow",
31446 "requireInteraction",
31447 "required",
31448 "requiredExtensions",
31449 "requiredFeatures",
31450 "requiredLimits",
31451 "reset",
31452 "resetLatency",
31453 "resetPose",
31454 "resetTransform",
31455 "resetZoomLevel",
31456 "resizable",
31457 "resize",
31458 "resizeBy",
31459 "resizeTo",
31460 "resolve",
31461 "resolveQuerySet",
31462 "resolveTarget",
31463 "resource",
31464 "respond",
31465 "respondWithNewView",
31466 "response",
31467 "responseBody",
31468 "responseEnd",
31469 "responseReady",
31470 "responseStart",
31471 "responseStatus",
31472 "responseText",
31473 "responseType",
31474 "responseURL",
31475 "responseXML",
31476 "restart",
31477 "restartAfterDelay",
31478 "restartIce",
31479 "restore",
31480 "restrictTo",
31481 "result",
31482 "resultIndex",
31483 "resultType",
31484 "results",
31485 "resume",
31486 "resumeDepthSensing",
31487 "resumeProfilers",
31488 "resumeTransformFeedback",
31489 "retry",
31490 "returnType",
31491 "returnValue",
31492 "rev",
31493 "reverse",
31494 "reversed",
31495 "revocable",
31496 "revokeObjectURL",
31497 "rex",
31498 "rgbColor",
31499 "ric",
31500 "right",
31501 "rightContext",
31502 "rightDegrees",
31503 "rightMargin",
31504 "rightProjectionMatrix",
31505 "rightViewMatrix",
31506 "rlh",
31507 "role",
31508 "rolloffFactor",
31509 "root",
31510 "rootBounds",
31511 "rootElement",
31512 "rootMargin",
31513 "rotate",
31514 "rotateAxisAngle",
31515 "rotateAxisAngleSelf",
31516 "rotateFromVector",
31517 "rotateFromVectorSelf",
31518 "rotateSelf",
31519 "rotation",
31520 "rotationAngle",
31521 "rotationRate",
31522 "round",
31523 "roundRect",
31524 "row-gap",
31525 "rowGap",
31526 "rowIndex",
31527 "rowSpan",
31528 "rows",
31529 "rowsPerImage",
31530 "rtcpTransport",
31531 "rtt",
31532 "ruby-align",
31533 "ruby-position",
31534 "rubyAlign",
31535 "rubyOverhang",
31536 "rubyPosition",
31537 "rules",
31538 "run",
31539 "runAdAuction",
31540 "runtime",
31541 "runtimeStyle",
31542 "rx",
31543 "ry",
31544 "s",
31545 "safari",
31546 "sameDocument",
31547 "sample",
31548 "sampleCount",
31549 "sampleCoverage",
31550 "sampleInterval",
31551 "sampleRate",
31552 "sampleType",
31553 "sampler",
31554 "samplerParameterf",
31555 "samplerParameteri",
31556 "sandbox",
31557 "save",
31558 "saveAsPDF",
31559 "saveData",
31560 "scale",
31561 "scale3d",
31562 "scale3dSelf",
31563 "scaleNonUniform",
31564 "scaleNonUniformSelf",
31565 "scaleSelf",
31566 "scheduler",
31567 "scheduling",
31568 "scheme",
31569 "scissor",
31570 "scope",
31571 "scopeName",
31572 "scoped",
31573 "screen",
31574 "screenBrightness",
31575 "screenEnabled",
31576 "screenLeft",
31577 "screenPixelToMillimeterX",
31578 "screenPixelToMillimeterY",
31579 "screenState",
31580 "screenTop",
31581 "screenX",
31582 "screenY",
31583 "screens",
31584 "scriptURL",
31585 "scripting",
31586 "scripts",
31587 "scroll",
31588 "scroll-behavior",
31589 "scroll-margin",
31590 "scroll-margin-block",
31591 "scroll-margin-block-end",
31592 "scroll-margin-block-start",
31593 "scroll-margin-bottom",
31594 "scroll-margin-inline",
31595 "scroll-margin-inline-end",
31596 "scroll-margin-inline-start",
31597 "scroll-margin-left",
31598 "scroll-margin-right",
31599 "scroll-margin-top",
31600 "scroll-padding",
31601 "scroll-padding-block",
31602 "scroll-padding-block-end",
31603 "scroll-padding-block-start",
31604 "scroll-padding-bottom",
31605 "scroll-padding-inline",
31606 "scroll-padding-inline-end",
31607 "scroll-padding-inline-start",
31608 "scroll-padding-left",
31609 "scroll-padding-right",
31610 "scroll-padding-top",
31611 "scroll-snap-align",
31612 "scroll-snap-stop",
31613 "scroll-snap-type",
31614 "scrollAmount",
31615 "scrollBehavior",
31616 "scrollBy",
31617 "scrollByLines",
31618 "scrollByPages",
31619 "scrollDelay",
31620 "scrollHeight",
31621 "scrollIntoView",
31622 "scrollIntoViewIfNeeded",
31623 "scrollLeft",
31624 "scrollLeftMax",
31625 "scrollMargin",
31626 "scrollMarginBlock",
31627 "scrollMarginBlockEnd",
31628 "scrollMarginBlockStart",
31629 "scrollMarginBottom",
31630 "scrollMarginInline",
31631 "scrollMarginInlineEnd",
31632 "scrollMarginInlineStart",
31633 "scrollMarginLeft",
31634 "scrollMarginRight",
31635 "scrollMarginTop",
31636 "scrollMaxX",
31637 "scrollMaxY",
31638 "scrollPadding",
31639 "scrollPaddingBlock",
31640 "scrollPaddingBlockEnd",
31641 "scrollPaddingBlockStart",
31642 "scrollPaddingBottom",
31643 "scrollPaddingInline",
31644 "scrollPaddingInlineEnd",
31645 "scrollPaddingInlineStart",
31646 "scrollPaddingLeft",
31647 "scrollPaddingRight",
31648 "scrollPaddingTop",
31649 "scrollRestoration",
31650 "scrollSnapAlign",
31651 "scrollSnapStop",
31652 "scrollSnapType",
31653 "scrollTo",
31654 "scrollTop",
31655 "scrollTopMax",
31656 "scrollWidth",
31657 "scrollX",
31658 "scrollY",
31659 "scrollbar-color",
31660 "scrollbar-gutter",
31661 "scrollbar-width",
31662 "scrollbar3dLightColor",
31663 "scrollbarArrowColor",
31664 "scrollbarBaseColor",
31665 "scrollbarColor",
31666 "scrollbarDarkShadowColor",
31667 "scrollbarFaceColor",
31668 "scrollbarGutter",
31669 "scrollbarHighlightColor",
31670 "scrollbarShadowColor",
31671 "scrollbarTrackColor",
31672 "scrollbarWidth",
31673 "scrollbars",
31674 "scrolling",
31675 "scrollingElement",
31676 "sctp",
31677 "sctpCauseCode",
31678 "sdp",
31679 "sdpLineNumber",
31680 "sdpMLineIndex",
31681 "sdpMid",
31682 "seal",
31683 "search",
31684 "searchBox",
31685 "searchBoxJavaBridge_",
31686 "searchParams",
31687 "second",
31688 "seconds",
31689 "sectionRowIndex",
31690 "secureConnectionStart",
31691 "securePaymentConfirmationAvailability",
31692 "security",
31693 "seed",
31694 "seek",
31695 "seekToNextFrame",
31696 "seekable",
31697 "seeking",
31698 "segments",
31699 "select",
31700 "selectAllChildren",
31701 "selectAlternateInterface",
31702 "selectAudioOutput",
31703 "selectConfiguration",
31704 "selectNode",
31705 "selectNodeContents",
31706 "selectNodes",
31707 "selectSingleNode",
31708 "selectSubString",
31709 "selectURL",
31710 "selected",
31711 "selectedIndex",
31712 "selectedOptions",
31713 "selectedStyleSheetSet",
31714 "selectedStylesheetSet",
31715 "selectedTrack",
31716 "selection",
31717 "selectionDirection",
31718 "selectionEnd",
31719 "selectionStart",
31720 "selector",
31721 "selectorText",
31722 "self",
31723 "send",
31724 "sendAsBinary",
31725 "sendBeacon",
31726 "sendFeatureReport",
31727 "sendMessage",
31728 "sendNativeMessage",
31729 "sendOrder",
31730 "sendReport",
31731 "sender",
31732 "sentAlert",
31733 "sentTimestamp",
31734 "separator",
31735 "serial",
31736 "serialNumber",
31737 "serializable",
31738 "serializeToString",
31739 "serverTiming",
31740 "service",
31741 "serviceWorker",
31742 "session",
31743 "sessionId",
31744 "sessionStorage",
31745 "sessions",
31746 "set",
31747 "setActionHandler",
31748 "setActive",
31749 "setAlpha",
31750 "setAppBadge",
31751 "setAttribute",
31752 "setAttributeNS",
31753 "setAttributeNode",
31754 "setAttributeNodeNS",
31755 "setAttributionReporting",
31756 "setBadgeBackgroundColor",
31757 "setBadgeText",
31758 "setBadgeTextColor",
31759 "setBaseAndExtent",
31760 "setBigInt64",
31761 "setBigUint64",
31762 "setBindGroup",
31763 "setBingCurrentSearchDefault",
31764 "setBlendConstant",
31765 "setCameraActive",
31766 "setCapture",
31767 "setCaptureHandleConfig",
31768 "setCodecPreferences",
31769 "setColor",
31770 "setCompositeOperation",
31771 "setConfiguration",
31772 "setConsumer",
31773 "setCurrentTime",
31774 "setCustomValidity",
31775 "setData",
31776 "setDate",
31777 "setDragImage",
31778 "setEnabled",
31779 "setEnd",
31780 "setEndAfter",
31781 "setEndBefore",
31782 "setEndPoint",
31783 "setExpires",
31784 "setFillColor",
31785 "setFilterRes",
31786 "setFloat16",
31787 "setFloat32",
31788 "setFloat64",
31789 "setFloatValue",
31790 "setFocusBehavior",
31791 "setFormValue",
31792 "setFromBase64",
31793 "setFromHex",
31794 "setFullYear",
31795 "setHTMLUnsafe",
31796 "setHeaderExtensionsToNegotiate",
31797 "setHeaderValue",
31798 "setHours",
31799 "setIcon",
31800 "setIdentityProvider",
31801 "setImmediate",
31802 "setIndexBuffer",
31803 "setInt16",
31804 "setInt32",
31805 "setInt8",
31806 "setInterval",
31807 "setItem",
31808 "setKeyframes",
31809 "setLineCap",
31810 "setLineDash",
31811 "setLineJoin",
31812 "setLineWidth",
31813 "setLiveSeekableRange",
31814 "setLocalDescription",
31815 "setMatrix",
31816 "setMatrixValue",
31817 "setMediaKeys",
31818 "setMicrophoneActive",
31819 "setMilliseconds",
31820 "setMinutes",
31821 "setMiterLimit",
31822 "setMonth",
31823 "setNamedItem",
31824 "setNamedItemNS",
31825 "setNonUserCodeExceptions",
31826 "setOrientToAngle",
31827 "setOrientToAuto",
31828 "setOrientation",
31829 "setOverrideHistoryNavigationMode",
31830 "setPaint",
31831 "setParameter",
31832 "setParameters",
31833 "setPathData",
31834 "setPeriodicWave",
31835 "setPipeline",
31836 "setPointerCapture",
31837 "setPopup",
31838 "setPosition",
31839 "setPositionState",
31840 "setPreference",
31841 "setPriority",
31842 "setPrivateToken",
31843 "setProperty",
31844 "setPrototypeOf",
31845 "setRGBColor",
31846 "setRGBColorICCColor",
31847 "setRadius",
31848 "setRangeText",
31849 "setRemoteDescription",
31850 "setReportEventDataForAutomaticBeacons",
31851 "setRequestHeader",
31852 "setResizable",
31853 "setResourceTimingBufferSize",
31854 "setRotate",
31855 "setScale",
31856 "setScissorRect",
31857 "setSeconds",
31858 "setSelectionRange",
31859 "setServerCertificate",
31860 "setShadow",
31861 "setSharedStorageContext",
31862 "setSignals",
31863 "setSinkId",
31864 "setSkewX",
31865 "setSkewY",
31866 "setStart",
31867 "setStartAfter",
31868 "setStartBefore",
31869 "setStatus",
31870 "setStdDeviation",
31871 "setStencilReference",
31872 "setStreams",
31873 "setStrictMode",
31874 "setStringValue",
31875 "setStrokeColor",
31876 "setSuggestResult",
31877 "setTargetAtTime",
31878 "setTargetValueAtTime",
31879 "setTime",
31880 "setTimeout",
31881 "setTitle",
31882 "setTransform",
31883 "setTranslate",
31884 "setUTCDate",
31885 "setUTCFullYear",
31886 "setUTCHours",
31887 "setUTCMilliseconds",
31888 "setUTCMinutes",
31889 "setUTCMonth",
31890 "setUTCSeconds",
31891 "setUint16",
31892 "setUint32",
31893 "setUint8",
31894 "setUninstallURL",
31895 "setUpdateUrlData",
31896 "setUri",
31897 "setValidity",
31898 "setValueAtTime",
31899 "setValueCurveAtTime",
31900 "setVariable",
31901 "setVelocity",
31902 "setVersion",
31903 "setVertexBuffer",
31904 "setViewport",
31905 "setYear",
31906 "setZoom",
31907 "setZoomSettings",
31908 "settingName",
31909 "settingValue",
31910 "sex",
31911 "shaderLocation",
31912 "shaderSource",
31913 "shadowBlur",
31914 "shadowColor",
31915 "shadowOffsetX",
31916 "shadowOffsetY",
31917 "shadowRoot",
31918 "shadowRootClonable",
31919 "shadowRootDelegatesFocus",
31920 "shadowRootMode",
31921 "shadowRootSerializable",
31922 "shape",
31923 "shape-image-threshold",
31924 "shape-margin",
31925 "shape-outside",
31926 "shape-rendering",
31927 "shapeImageThreshold",
31928 "shapeMargin",
31929 "shapeOutside",
31930 "shapeRendering",
31931 "share",
31932 "sharedContext",
31933 "sharedStorage",
31934 "sharedStorageWritable",
31935 "sheet",
31936 "shift",
31937 "shiftKey",
31938 "shiftLeft",
31939 "shippingAddress",
31940 "shippingOption",
31941 "shippingType",
31942 "show",
31943 "showDirectoryPicker",
31944 "showHelp",
31945 "showModal",
31946 "showModalDialog",
31947 "showModelessDialog",
31948 "showNotification",
31949 "showOpenFilePicker",
31950 "showPicker",
31951 "showPopover",
31952 "showSaveFilePicker",
31953 "sidebar",
31954 "sidebarAction",
31955 "sign",
31956 "signal",
31957 "signalAllAcceptedCredentials",
31958 "signalCurrentUserDetails",
31959 "signalUnknownCredential",
31960 "signalingState",
31961 "signature",
31962 "silent",
31963 "sin",
31964 "singleNodeValue",
31965 "sinh",
31966 "sinkId",
31967 "sittingToStandingTransform",
31968 "size",
31969 "sizeAdjust",
31970 "sizeToContent",
31971 "sizeX",
31972 "sizeZ",
31973 "sizes",
31974 "skewX",
31975 "skewXSelf",
31976 "skewY",
31977 "skewYSelf",
31978 "skipTransition",
31979 "skipped",
31980 "slice",
31981 "slope",
31982 "slot",
31983 "slotAssignment",
31984 "small",
31985 "smil",
31986 "smooth",
31987 "smoothingTimeConstant",
31988 "snapTargetBlock",
31989 "snapTargetInline",
31990 "snapToLines",
31991 "snapshotItem",
31992 "snapshotLength",
31993 "some",
31994 "sort",
31995 "sortingCode",
31996 "source",
31997 "sourceBuffer",
31998 "sourceBuffers",
31999 "sourceCapabilities",
32000 "sourceCharPosition",
32001 "sourceElement",
32002 "sourceFile",
32003 "sourceFunctionName",
32004 "sourceIndex",
32005 "sourceLanguage",
32006 "sourceMap",
32007 "sourceURL",
32008 "sources",
32009 "spacing",
32010 "span",
32011 "speak",
32012 "speakAs",
32013 "speaking",
32014 "species",
32015 "specified",
32016 "specularConstant",
32017 "specularExponent",
32018 "speechSynthesis",
32019 "speed",
32020 "speedOfSound",
32021 "spellcheck",
32022 "sphericalHarmonicsCoefficients",
32023 "splice",
32024 "split",
32025 "splitText",
32026 "spreadMethod",
32027 "sqrt",
32028 "src",
32029 "srcElement",
32030 "srcFactor",
32031 "srcFilter",
32032 "srcObject",
32033 "srcUrn",
32034 "srcdoc",
32035 "srclang",
32036 "srcset",
32037 "stack",
32038 "stackTraceLimit",
32039 "stacktrace",
32040 "stageParameters",
32041 "standalone",
32042 "standby",
32043 "start",
32044 "startContainer",
32045 "startE",
32046 "startIce",
32047 "startLoadTime",
32048 "startMessages",
32049 "startNotifications",
32050 "startOffset",
32051 "startProfiling",
32052 "startRendering",
32053 "startShark",
32054 "startTime",
32055 "startViewTransition",
32056 "startsWith",
32057 "state",
32058 "states",
32059 "stats",
32060 "status",
32061 "statusCode",
32062 "statusMessage",
32063 "statusText",
32064 "statusbar",
32065 "stdDeviationX",
32066 "stdDeviationY",
32067 "stencilBack",
32068 "stencilClearValue",
32069 "stencilFront",
32070 "stencilFunc",
32071 "stencilFuncSeparate",
32072 "stencilLoadOp",
32073 "stencilMask",
32074 "stencilMaskSeparate",
32075 "stencilOp",
32076 "stencilOpSeparate",
32077 "stencilReadMask",
32078 "stencilReadOnly",
32079 "stencilStoreOp",
32080 "stencilWriteMask",
32081 "step",
32082 "stepDown",
32083 "stepMismatch",
32084 "stepMode",
32085 "stepUp",
32086 "sticky",
32087 "stitchTiles",
32088 "stop",
32089 "stop-color",
32090 "stop-opacity",
32091 "stopColor",
32092 "stopImmediatePropagation",
32093 "stopNotifications",
32094 "stopOpacity",
32095 "stopProfiling",
32096 "stopPropagation",
32097 "stopShark",
32098 "stopped",
32099 "storage",
32100 "storageArea",
32101 "storageBuckets",
32102 "storageName",
32103 "storageStatus",
32104 "storageTexture",
32105 "store",
32106 "storeOp",
32107 "storeSiteSpecificTrackingException",
32108 "storeWebWideTrackingException",
32109 "stpVersion",
32110 "stream",
32111 "streamErrorCode",
32112 "streams",
32113 "stretch",
32114 "strike",
32115 "string",
32116 "stringValue",
32117 "stringify",
32118 "stripIndexFormat",
32119 "stroke",
32120 "stroke-dasharray",
32121 "stroke-dashoffset",
32122 "stroke-linecap",
32123 "stroke-linejoin",
32124 "stroke-miterlimit",
32125 "stroke-opacity",
32126 "stroke-width",
32127 "strokeDasharray",
32128 "strokeDashoffset",
32129 "strokeLinecap",
32130 "strokeLinejoin",
32131 "strokeMiterlimit",
32132 "strokeOpacity",
32133 "strokeRect",
32134 "strokeStyle",
32135 "strokeText",
32136 "strokeWidth",
32137 "structuredClone",
32138 "style",
32139 "styleAndLayoutStart",
32140 "styleFloat",
32141 "styleMap",
32142 "styleMedia",
32143 "styleSheet",
32144 "styleSheetSets",
32145 "styleSheets",
32146 "styleset",
32147 "stylistic",
32148 "sub",
32149 "subarray",
32150 "subgroupMaxSize",
32151 "subgroupMinSize",
32152 "subject",
32153 "submit",
32154 "submitFrame",
32155 "submitter",
32156 "subscribe",
32157 "substr",
32158 "substring",
32159 "substringData",
32160 "subtle",
32161 "subtree",
32162 "suffix",
32163 "suffixes",
32164 "sumPrecise",
32165 "summarize",
32166 "summarizeStreaming",
32167 "summary",
32168 "sup",
32169 "supported",
32170 "supportedContentEncodings",
32171 "supportedEntryTypes",
32172 "supportedValuesOf",
32173 "supports",
32174 "supportsFiber",
32175 "supportsSession",
32176 "supportsText",
32177 "suppressed",
32178 "surfaceScale",
32179 "surroundContents",
32180 "suspend",
32181 "suspendRedraw",
32182 "svb",
32183 "svh",
32184 "svi",
32185 "svmax",
32186 "svmin",
32187 "svw",
32188 "swapCache",
32189 "swapNode",
32190 "swash",
32191 "sweepFlag",
32192 "switchMap",
32193 "symbols",
32194 "symmetricDifference",
32195 "sync",
32196 "syntax",
32197 "sysexEnabled",
32198 "system",
32199 "systemCode",
32200 "systemId",
32201 "systemLanguage",
32202 "systemXDPI",
32203 "systemYDPI",
32204 "tBodies",
32205 "tFoot",
32206 "tHead",
32207 "tab",
32208 "tab-size",
32209 "tabId",
32210 "tabIds",
32211 "tabIndex",
32212 "tabSize",
32213 "table",
32214 "table-layout",
32215 "tableLayout",
32216 "tableValues",
32217 "tabs",
32218 "tag",
32219 "tagName",
32220 "tagUrn",
32221 "tags",
32222 "taintEnabled",
32223 "take",
32224 "takePhoto",
32225 "takeRecords",
32226 "takeUntil",
32227 "tan",
32228 "tangentialPressure",
32229 "tanh",
32230 "target",
32231 "targetAddressSpace",
32232 "targetElement",
32233 "targetLanguage",
32234 "targetRayMode",
32235 "targetRaySpace",
32236 "targetTouches",
32237 "targetURL",
32238 "targetX",
32239 "targetY",
32240 "targets",
32241 "tcpType",
32242 "tee",
32243 "tel",
32244 "telemetry",
32245 "terminate",
32246 "test",
32247 "texImage2D",
32248 "texImage3D",
32249 "texParameterf",
32250 "texParameteri",
32251 "texStorage2D",
32252 "texStorage3D",
32253 "texSubImage2D",
32254 "texSubImage3D",
32255 "text",
32256 "text-align",
32257 "text-align-last",
32258 "text-anchor",
32259 "text-combine-upright",
32260 "text-decoration",
32261 "text-decoration-color",
32262 "text-decoration-line",
32263 "text-decoration-skip-ink",
32264 "text-decoration-style",
32265 "text-decoration-thickness",
32266 "text-emphasis",
32267 "text-emphasis-color",
32268 "text-emphasis-position",
32269 "text-emphasis-style",
32270 "text-indent",
32271 "text-justify",
32272 "text-orientation",
32273 "text-overflow",
32274 "text-rendering",
32275 "text-shadow",
32276 "text-transform",
32277 "text-underline-offset",
32278 "text-underline-position",
32279 "text-wrap",
32280 "text-wrap-mode",
32281 "text-wrap-style",
32282 "textAlign",
32283 "textAlignLast",
32284 "textAnchor",
32285 "textAutospace",
32286 "textBaseline",
32287 "textCombineUpright",
32288 "textContent",
32289 "textDecoration",
32290 "textDecorationBlink",
32291 "textDecorationColor",
32292 "textDecorationInset",
32293 "textDecorationLine",
32294 "textDecorationLineThrough",
32295 "textDecorationNone",
32296 "textDecorationOverline",
32297 "textDecorationSkipInk",
32298 "textDecorationStyle",
32299 "textDecorationThickness",
32300 "textDecorationUnderline",
32301 "textEmphasis",
32302 "textEmphasisColor",
32303 "textEmphasisPosition",
32304 "textEmphasisStyle",
32305 "textIndent",
32306 "textJustify",
32307 "textJustifyTrim",
32308 "textKashida",
32309 "textKashidaSpace",
32310 "textLength",
32311 "textOrientation",
32312 "textOverflow",
32313 "textRendering",
32314 "textShadow",
32315 "textTracks",
32316 "textTransform",
32317 "textUnderlineOffset",
32318 "textUnderlinePosition",
32319 "textWrap",
32320 "textWrapMode",
32321 "textWrapStyle",
32322 "texture",
32323 "theme",
32324 "then",
32325 "threadId",
32326 "threshold",
32327 "thresholds",
32328 "throwIfAborted",
32329 "tiltX",
32330 "tiltY",
32331 "time",
32332 "timeEnd",
32333 "timeLog",
32334 "timeOrigin",
32335 "timeRemaining",
32336 "timeStamp",
32337 "timeStyle",
32338 "timeZone",
32339 "timeZoneName",
32340 "timecode",
32341 "timeline",
32342 "timelineTime",
32343 "timeout",
32344 "timestamp",
32345 "timestampOffset",
32346 "timestampWrites",
32347 "timing",
32348 "title",
32349 "titlebarAreaRect",
32350 "tlsChannelId",
32351 "to",
32352 "toArray",
32353 "toBase64",
32354 "toBlob",
32355 "toDataURL",
32356 "toDateString",
32357 "toElement",
32358 "toExponential",
32359 "toFixed",
32360 "toFloat32Array",
32361 "toFloat64Array",
32362 "toGMTString",
32363 "toHex",
32364 "toISOString",
32365 "toJSON",
32366 "toLocaleDateString",
32367 "toLocaleFormat",
32368 "toLocaleLowerCase",
32369 "toLocaleString",
32370 "toLocaleTimeString",
32371 "toLocaleUpperCase",
32372 "toLowerCase",
32373 "toMatrix",
32374 "toMethod",
32375 "toPrecision",
32376 "toPrimitive",
32377 "toReversed",
32378 "toSdp",
32379 "toSorted",
32380 "toSource",
32381 "toSpliced",
32382 "toStaticHTML",
32383 "toString",
32384 "toStringTag",
32385 "toSum",
32386 "toTemporalInstant",
32387 "toTimeString",
32388 "toUTCString",
32389 "toUpperCase",
32390 "toWellFormed",
32391 "toggle",
32392 "toggleAttribute",
32393 "toggleLongPressEnabled",
32394 "togglePopover",
32395 "toggleReaderMode",
32396 "token",
32397 "tone",
32398 "toneBuffer",
32399 "tooLong",
32400 "tooShort",
32401 "toolbar",
32402 "top",
32403 "topMargin",
32404 "topSites",
32405 "topology",
32406 "total",
32407 "totalFrameDelay",
32408 "totalFrames",
32409 "totalFramesDuration",
32410 "totalVideoFrames",
32411 "touch-action",
32412 "touchAction",
32413 "touched",
32414 "touches",
32415 "trace",
32416 "track",
32417 "trackVisibility",
32418 "trackedAnchors",
32419 "tracks",
32420 "tran",
32421 "transaction",
32422 "transactions",
32423 "transceiver",
32424 "transfer",
32425 "transferControlToOffscreen",
32426 "transferFromImageBitmap",
32427 "transferImageBitmap",
32428 "transferIn",
32429 "transferOut",
32430 "transferSize",
32431 "transferToFixedLength",
32432 "transferToImageBitmap",
32433 "transform",
32434 "transform-box",
32435 "transform-origin",
32436 "transform-style",
32437 "transformBox",
32438 "transformFeedbackVaryings",
32439 "transformOrigin",
32440 "transformPoint",
32441 "transformString",
32442 "transformStyle",
32443 "transformToDocument",
32444 "transformToFragment",
32445 "transition",
32446 "transition-behavior",
32447 "transition-delay",
32448 "transition-duration",
32449 "transition-property",
32450 "transition-timing-function",
32451 "transitionBehavior",
32452 "transitionDelay",
32453 "transitionDuration",
32454 "transitionProperty",
32455 "transitionTimingFunction",
32456 "translate",
32457 "translateSelf",
32458 "translateStreaming",
32459 "translationX",
32460 "translationY",
32461 "transport",
32462 "traverseTo",
32463 "trim",
32464 "trimEnd",
32465 "trimLeft",
32466 "trimRight",
32467 "trimStart",
32468 "trueSpeed",
32469 "trunc",
32470 "truncate",
32471 "trustedTypes",
32472 "try",
32473 "turn",
32474 "twist",
32475 "type",
32476 "typeDetail",
32477 "typeMismatch",
32478 "typeMustMatch",
32479 "types",
32480 "u2f",
32481 "ubound",
32482 "uint16",
32483 "uint32",
32484 "uint8",
32485 "uint8Clamped",
32486 "unadjustedMovement",
32487 "unclippedDepth",
32488 "unconfigure",
32489 "undefined",
32490 "underlineStyle",
32491 "underlineThickness",
32492 "unescape",
32493 "uneval",
32494 "ungroup",
32495 "unicode",
32496 "unicode-bidi",
32497 "unicodeBidi",
32498 "unicodeRange",
32499 "unicodeSets",
32500 "uniform1f",
32501 "uniform1fv",
32502 "uniform1i",
32503 "uniform1iv",
32504 "uniform1ui",
32505 "uniform1uiv",
32506 "uniform2f",
32507 "uniform2fv",
32508 "uniform2i",
32509 "uniform2iv",
32510 "uniform2ui",
32511 "uniform2uiv",
32512 "uniform3f",
32513 "uniform3fv",
32514 "uniform3i",
32515 "uniform3iv",
32516 "uniform3ui",
32517 "uniform3uiv",
32518 "uniform4f",
32519 "uniform4fv",
32520 "uniform4i",
32521 "uniform4iv",
32522 "uniform4ui",
32523 "uniform4uiv",
32524 "uniformBlockBinding",
32525 "uniformMatrix2fv",
32526 "uniformMatrix2x3fv",
32527 "uniformMatrix2x4fv",
32528 "uniformMatrix3fv",
32529 "uniformMatrix3x2fv",
32530 "uniformMatrix3x4fv",
32531 "uniformMatrix4fv",
32532 "uniformMatrix4x2fv",
32533 "uniformMatrix4x3fv",
32534 "uninstallSelf",
32535 "union",
32536 "unique",
32537 "uniqueID",
32538 "uniqueNumber",
32539 "unit",
32540 "unitType",
32541 "units",
32542 "unloadEventEnd",
32543 "unloadEventStart",
32544 "unlock",
32545 "unmap",
32546 "unmount",
32547 "unobserve",
32548 "unpackColorSpace",
32549 "unpause",
32550 "unpauseAnimations",
32551 "unreadCount",
32552 "unregister",
32553 "unregisterContentHandler",
32554 "unregisterProtocolHandler",
32555 "unscopables",
32556 "unselectable",
32557 "unshift",
32558 "unsubscribe",
32559 "unsuspendRedraw",
32560 "unsuspendRedrawAll",
32561 "unwatch",
32562 "unwrapKey",
32563 "upDegrees",
32564 "upX",
32565 "upY",
32566 "upZ",
32567 "update",
32568 "updateAdInterestGroups",
32569 "updateCallbackDone",
32570 "updateCharacterBounds",
32571 "updateCommands",
32572 "updateControlBounds",
32573 "updateCurrentEntry",
32574 "updateIce",
32575 "updateInkTrailStartPoint",
32576 "updateInterval",
32577 "updatePlaybackRate",
32578 "updateRangeEnd",
32579 "updateRangeStart",
32580 "updateRenderState",
32581 "updateSelection",
32582 "updateSelectionBounds",
32583 "updateSettings",
32584 "updateText",
32585 "updateTiming",
32586 "updateViaCache",
32587 "updateWith",
32588 "updated",
32589 "updating",
32590 "upgrade",
32591 "upload",
32592 "uploadTotal",
32593 "uploaded",
32594 "upper",
32595 "upperBound",
32596 "upperOpen",
32597 "uri",
32598 "url",
32599 "urn",
32600 "urns",
32601 "usage",
32602 "usages",
32603 "usb",
32604 "usbVersionMajor",
32605 "usbVersionMinor",
32606 "usbVersionSubminor",
32607 "use",
32608 "useCurrentView",
32609 "useMap",
32610 "useProgram",
32611 "usedSpace",
32612 "user-select",
32613 "userActivation",
32614 "userAgent",
32615 "userAgentAllowsProtocol",
32616 "userAgentData",
32617 "userChoice",
32618 "userHandle",
32619 "userHint",
32620 "userInitiated",
32621 "userLanguage",
32622 "userSelect",
32623 "userState",
32624 "userVisibleOnly",
32625 "username",
32626 "usernameFragment",
32627 "utterance",
32628 "uuid",
32629 "v8BreakIterator",
32630 "vAlign",
32631 "vLink",
32632 "valid",
32633 "validate",
32634 "validateProgram",
32635 "validationMessage",
32636 "validity",
32637 "value",
32638 "valueAsDate",
32639 "valueAsNumber",
32640 "valueAsString",
32641 "valueInSpecifiedUnits",
32642 "valueMissing",
32643 "valueOf",
32644 "valueText",
32645 "valueType",
32646 "values",
32647 "variable",
32648 "variant",
32649 "variationSettings",
32650 "vb",
32651 "vector-effect",
32652 "vectorEffect",
32653 "velocityAngular",
32654 "velocityExpansion",
32655 "velocityX",
32656 "velocityY",
32657 "vendor",
32658 "vendorId",
32659 "vendorSub",
32660 "verify",
32661 "version",
32662 "vertex",
32663 "vertexAttrib1f",
32664 "vertexAttrib1fv",
32665 "vertexAttrib2f",
32666 "vertexAttrib2fv",
32667 "vertexAttrib3f",
32668 "vertexAttrib3fv",
32669 "vertexAttrib4f",
32670 "vertexAttrib4fv",
32671 "vertexAttribDivisor",
32672 "vertexAttribDivisorANGLE",
32673 "vertexAttribI4i",
32674 "vertexAttribI4iv",
32675 "vertexAttribI4ui",
32676 "vertexAttribI4uiv",
32677 "vertexAttribIPointer",
32678 "vertexAttribPointer",
32679 "vertical",
32680 "vertical-align",
32681 "verticalAlign",
32682 "verticalOverflow",
32683 "vh",
32684 "vi",
32685 "vibrate",
32686 "vibrationActuator",
32687 "videoBitsPerSecond",
32688 "videoHeight",
32689 "videoTracks",
32690 "videoWidth",
32691 "view",
32692 "viewBox",
32693 "viewBoxString",
32694 "viewDimension",
32695 "viewFormats",
32696 "viewTarget",
32697 "viewTargetString",
32698 "viewTransition",
32699 "viewTransitionClass",
32700 "viewTransitionName",
32701 "viewport",
32702 "viewportAnchorX",
32703 "viewportAnchorY",
32704 "viewportElement",
32705 "views",
32706 "violatedDirective",
32707 "virtualKeyboard",
32708 "virtualKeyboardPolicy",
32709 "visibility",
32710 "visibilityState",
32711 "visible",
32712 "visibleRect",
32713 "visualViewport",
32714 "vlinkColor",
32715 "vmax",
32716 "vmin",
32717 "voice",
32718 "voiceURI",
32719 "volume",
32720 "vrml",
32721 "vspace",
32722 "vw",
32723 "w",
32724 "wait",
32725 "waitAsync",
32726 "waitSync",
32727 "waiting",
32728 "wake",
32729 "wakeLock",
32730 "wand",
32731 "warmup",
32732 "warn",
32733 "wasAlternateProtocolAvailable",
32734 "wasClean",
32735 "wasDiscarded",
32736 "wasFetchedViaSpdy",
32737 "wasNpnNegotiated",
32738 "watch",
32739 "watchAvailability",
32740 "watchPosition",
32741 "webNavigation",
32742 "webRequest",
32743 "webdriver",
32744 "webkitAddKey",
32745 "webkitAlignContent",
32746 "webkitAlignItems",
32747 "webkitAlignSelf",
32748 "webkitAnimation",
32749 "webkitAnimationDelay",
32750 "webkitAnimationDirection",
32751 "webkitAnimationDuration",
32752 "webkitAnimationFillMode",
32753 "webkitAnimationIterationCount",
32754 "webkitAnimationName",
32755 "webkitAnimationPlayState",
32756 "webkitAnimationTimingFunction",
32757 "webkitAppearance",
32758 "webkitAudioContext",
32759 "webkitAudioDecodedByteCount",
32760 "webkitAudioPannerNode",
32761 "webkitBackfaceVisibility",
32762 "webkitBackground",
32763 "webkitBackgroundAttachment",
32764 "webkitBackgroundClip",
32765 "webkitBackgroundColor",
32766 "webkitBackgroundImage",
32767 "webkitBackgroundOrigin",
32768 "webkitBackgroundPosition",
32769 "webkitBackgroundPositionX",
32770 "webkitBackgroundPositionY",
32771 "webkitBackgroundRepeat",
32772 "webkitBackgroundSize",
32773 "webkitBackingStorePixelRatio",
32774 "webkitBorderBottomLeftRadius",
32775 "webkitBorderBottomRightRadius",
32776 "webkitBorderImage",
32777 "webkitBorderImageOutset",
32778 "webkitBorderImageRepeat",
32779 "webkitBorderImageSlice",
32780 "webkitBorderImageSource",
32781 "webkitBorderImageWidth",
32782 "webkitBorderRadius",
32783 "webkitBorderTopLeftRadius",
32784 "webkitBorderTopRightRadius",
32785 "webkitBoxAlign",
32786 "webkitBoxDirection",
32787 "webkitBoxFlex",
32788 "webkitBoxOrdinalGroup",
32789 "webkitBoxOrient",
32790 "webkitBoxPack",
32791 "webkitBoxShadow",
32792 "webkitBoxSizing",
32793 "webkitCancelAnimationFrame",
32794 "webkitCancelFullScreen",
32795 "webkitCancelKeyRequest",
32796 "webkitCancelRequestAnimationFrame",
32797 "webkitClearResourceTimings",
32798 "webkitClipPath",
32799 "webkitClosedCaptionsVisible",
32800 "webkitConvertPointFromNodeToPage",
32801 "webkitConvertPointFromPageToNode",
32802 "webkitCreateShadowRoot",
32803 "webkitCurrentFullScreenElement",
32804 "webkitCurrentPlaybackTargetIsWireless",
32805 "webkitDecodedFrameCount",
32806 "webkitDirectionInvertedFromDevice",
32807 "webkitDisplayingFullscreen",
32808 "webkitDroppedFrameCount",
32809 "webkitEnterFullScreen",
32810 "webkitEnterFullscreen",
32811 "webkitEntries",
32812 "webkitExitFullScreen",
32813 "webkitExitFullscreen",
32814 "webkitExitPointerLock",
32815 "webkitFilter",
32816 "webkitFlex",
32817 "webkitFlexBasis",
32818 "webkitFlexDirection",
32819 "webkitFlexFlow",
32820 "webkitFlexGrow",
32821 "webkitFlexShrink",
32822 "webkitFlexWrap",
32823 "webkitFontFeatureSettings",
32824 "webkitFullScreenKeyboardInputAllowed",
32825 "webkitFullscreenElement",
32826 "webkitFullscreenEnabled",
32827 "webkitGenerateKeyRequest",
32828 "webkitGetAsEntry",
32829 "webkitGetDatabaseNames",
32830 "webkitGetEntries",
32831 "webkitGetEntriesByName",
32832 "webkitGetEntriesByType",
32833 "webkitGetFlowByName",
32834 "webkitGetGamepads",
32835 "webkitGetImageDataHD",
32836 "webkitGetNamedFlows",
32837 "webkitGetRegionFlowRanges",
32838 "webkitGetUserMedia",
32839 "webkitHasClosedCaptions",
32840 "webkitHidden",
32841 "webkitIDBCursor",
32842 "webkitIDBDatabase",
32843 "webkitIDBDatabaseError",
32844 "webkitIDBDatabaseException",
32845 "webkitIDBFactory",
32846 "webkitIDBIndex",
32847 "webkitIDBKeyRange",
32848 "webkitIDBObjectStore",
32849 "webkitIDBRequest",
32850 "webkitIDBTransaction",
32851 "webkitImageSmoothingEnabled",
32852 "webkitIndexedDB",
32853 "webkitInitMessageEvent",
32854 "webkitIsFullScreen",
32855 "webkitJustifyContent",
32856 "webkitKeys",
32857 "webkitLineClamp",
32858 "webkitLineDashOffset",
32859 "webkitLockOrientation",
32860 "webkitMask",
32861 "webkitMaskClip",
32862 "webkitMaskComposite",
32863 "webkitMaskImage",
32864 "webkitMaskOrigin",
32865 "webkitMaskPosition",
32866 "webkitMaskPositionX",
32867 "webkitMaskPositionY",
32868 "webkitMaskRepeat",
32869 "webkitMaskSize",
32870 "webkitMatchesSelector",
32871 "webkitMediaStream",
32872 "webkitNotifications",
32873 "webkitOfflineAudioContext",
32874 "webkitOrder",
32875 "webkitOrientation",
32876 "webkitPeerConnection00",
32877 "webkitPersistentStorage",
32878 "webkitPerspective",
32879 "webkitPerspectiveOrigin",
32880 "webkitPointerLockElement",
32881 "webkitPostMessage",
32882 "webkitPreservesPitch",
32883 "webkitPutImageDataHD",
32884 "webkitRTCPeerConnection",
32885 "webkitRegionOverset",
32886 "webkitRelativePath",
32887 "webkitRequestAnimationFrame",
32888 "webkitRequestFileSystem",
32889 "webkitRequestFullScreen",
32890 "webkitRequestFullscreen",
32891 "webkitRequestPointerLock",
32892 "webkitResolveLocalFileSystemURL",
32893 "webkitSetMediaKeys",
32894 "webkitSetResourceTimingBufferSize",
32895 "webkitShadowRoot",
32896 "webkitShowPlaybackTargetPicker",
32897 "webkitSlice",
32898 "webkitSpeechGrammar",
32899 "webkitSpeechGrammarList",
32900 "webkitSpeechRecognition",
32901 "webkitSpeechRecognitionError",
32902 "webkitSpeechRecognitionEvent",
32903 "webkitStorageInfo",
32904 "webkitSupportsFullscreen",
32905 "webkitTemporaryStorage",
32906 "webkitTextFillColor",
32907 "webkitTextSecurity",
32908 "webkitTextSizeAdjust",
32909 "webkitTextStroke",
32910 "webkitTextStrokeColor",
32911 "webkitTextStrokeWidth",
32912 "webkitTransform",
32913 "webkitTransformOrigin",
32914 "webkitTransformStyle",
32915 "webkitTransition",
32916 "webkitTransitionDelay",
32917 "webkitTransitionDuration",
32918 "webkitTransitionProperty",
32919 "webkitTransitionTimingFunction",
32920 "webkitURL",
32921 "webkitUnlockOrientation",
32922 "webkitUserSelect",
32923 "webkitVideoDecodedByteCount",
32924 "webkitVisibilityState",
32925 "webkitWirelessVideoPlaybackDisabled",
32926 "webkitdirectory",
32927 "webkitdropzone",
32928 "webstore",
32929 "weekday",
32930 "weeks",
32931 "weight",
32932 "wgslLanguageFeatures",
32933 "whatToShow",
32934 "wheelDelta",
32935 "wheelDeltaX",
32936 "wheelDeltaY",
32937 "when",
32938 "whenDefined",
32939 "which",
32940 "white-space",
32941 "white-space-collapse",
32942 "whiteSpace",
32943 "whiteSpaceCollapse",
32944 "wholeText",
32945 "widows",
32946 "width",
32947 "will-change",
32948 "willChange",
32949 "willValidate",
32950 "window",
32951 "windowAttribution",
32952 "windowControlsOverlay",
32953 "windowId",
32954 "windowIds",
32955 "windows",
32956 "with",
32957 "withCredentials",
32958 "withResolvers",
32959 "word-break",
32960 "word-spacing",
32961 "word-wrap",
32962 "wordBreak",
32963 "wordSpacing",
32964 "wordWrap",
32965 "workerCacheLookupStart",
32966 "workerFinalSourceType",
32967 "workerMatchedSourceType",
32968 "workerRouterEvaluationStart",
32969 "workerStart",
32970 "worklet",
32971 "wow64",
32972 "wrap",
32973 "wrapKey",
32974 "writable",
32975 "writableAuxiliaries",
32976 "write",
32977 "writeBuffer",
32978 "writeMask",
32979 "writeText",
32980 "writeTexture",
32981 "writeTimestamp",
32982 "writeValue",
32983 "writeValueWithResponse",
32984 "writeValueWithoutResponse",
32985 "writeWithoutResponse",
32986 "writeln",
32987 "writing-mode",
32988 "writingMode",
32989 "writingSuggestions",
32990 "x",
32991 "x1",
32992 "x2",
32993 "xChannelSelector",
32994 "xmlEncoding",
32995 "xmlStandalone",
32996 "xmlVersion",
32997 "xmlbase",
32998 "xmllang",
32999 "xmlspace",
33000 "xor",
33001 "xr",
33002 "y",
33003 "y1",
33004 "y2",
33005 "yChannelSelector",
33006 "yandex",
33007 "year",
33008 "years",
33009 "yield",
33010 "z",
33011 "z-index",
33012 "zIndex",
33013 "zoom",
33014 "zoomAndPan",
33015 "zoomLevel",
33016 "zoomRectScreen",
33017];
33018
33019/***********************************************************************
33020
33021 A JavaScript tokenizer / parser / beautifier / compressor.
33022 https://github.com/mishoo/UglifyJS2
33023
33024 -------------------------------- (C) ---------------------------------
33025
33026 Author: Mihai Bazon
33027 <mihai.bazon@gmail.com>
33028 http://mihai.bazon.net/blog
33029
33030 Distributed under the BSD license:
33031
33032 Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
33033
33034 Redistribution and use in source and binary forms, with or without
33035 modification, are permitted provided that the following conditions
33036 are met:
33037
33038 * Redistributions of source code must retain the above
33039 copyright notice, this list of conditions and the following
33040 disclaimer.
33041
33042 * Redistributions in binary form must reproduce the above
33043 copyright notice, this list of conditions and the following
33044 disclaimer in the documentation and/or other materials
33045 provided with the distribution.
33046
33047 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
33048 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33049 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
33050 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
33051 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
33052 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33053 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33054 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33055 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
33056 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
33057 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33058 SUCH DAMAGE.
33059
33060 ***********************************************************************/
33061
33062function find_builtins(reserved) {
33063 domprops.forEach(add);
33064
33065 // Compatibility fix for some standard defined globals not defined on every js environment
33066 var new_globals = ["Symbol", "Map", "Promise", "Proxy", "Reflect", "Set", "WeakMap", "WeakSet"];
33067 var objects = {};
33068 var global_ref = typeof global === "object" ? global : self;
33069
33070 new_globals.forEach(function (new_global) {
33071 objects[new_global] = global_ref[new_global] || function() {};
33072 });
33073
33074 [
33075 "null",
33076 "true",
33077 "false",
33078 "NaN",
33079 "Infinity",
33080 "-Infinity",
33081 "undefined",
33082 ].forEach(add);
33083 [ Object, Array, Function, Number,
33084 String, Boolean, Error, Math,
33085 Date, RegExp, objects.Symbol, ArrayBuffer,
33086 DataView, decodeURI, decodeURIComponent,
33087 encodeURI, encodeURIComponent, eval, EvalError,
33088 Float32Array, Float64Array, Int8Array, Int16Array,
33089 Int32Array, isFinite, isNaN, JSON, objects.Map, parseFloat,
33090 parseInt, objects.Promise, objects.Proxy, RangeError, ReferenceError,
33091 objects.Reflect, objects.Set, SyntaxError, TypeError, Uint8Array,
33092 Uint8ClampedArray, Uint16Array, Uint32Array, URIError,
33093 objects.WeakMap, objects.WeakSet
33094 ].forEach(function(ctor) {
33095 Object.getOwnPropertyNames(ctor).map(add);
33096 if (ctor.prototype) {
33097 Object.getOwnPropertyNames(ctor.prototype).map(add);
33098 }
33099 });
33100 function add(name) {
33101 reserved.add(name);
33102 }
33103}
33104
33105function reserve_quoted_keys(ast, reserved) {
33106 function add(name) {
33107 push_uniq(reserved, name);
33108 }
33109
33110 ast.walk(new TreeWalker(function(node) {
33111 if (node instanceof AST_ObjectKeyVal && node.quote) {
33112 add(node.key);
33113 } else if (node instanceof AST_ObjectProperty && node.quote) {
33114 add(node.key.name);
33115 } else if (node instanceof AST_Sub) {
33116 addStrings(node.property, add);
33117 }
33118 }));
33119}
33120
33121function addStrings(node, add) {
33122 node.walk(new TreeWalker(function(node) {
33123 if (node instanceof AST_Sequence) {
33124 addStrings(node.tail_node(), add);
33125 } else if (node instanceof AST_String) {
33126 add(node.value);
33127 } else if (node instanceof AST_Conditional) {
33128 addStrings(node.consequent, add);
33129 addStrings(node.alternative, add);
33130 }
33131 return true;
33132 }));
33133}
33134
33135function mangle_private_properties(ast, options) {
33136 var cprivate = -1;
33137 var private_cache = new Map();
33138 var nth_identifier = options.nth_identifier || base54;
33139
33140 ast = ast.transform(new TreeTransformer(function(node) {
33141 if (
33142 node instanceof AST_ClassPrivateProperty
33143 || node instanceof AST_PrivateMethod
33144 || node instanceof AST_PrivateGetter
33145 || node instanceof AST_PrivateSetter
33146 || node instanceof AST_PrivateIn
33147 ) {
33148 node.key.name = mangle_private(node.key.name);
33149 } else if (node instanceof AST_DotHash) {
33150 node.property = mangle_private(node.property);
33151 }
33152 }));
33153 return ast;
33154
33155 function mangle_private(name) {
33156 let mangled = private_cache.get(name);
33157 if (!mangled) {
33158 mangled = nth_identifier.get(++cprivate);
33159 private_cache.set(name, mangled);
33160 }
33161
33162 return mangled;
33163 }
33164}
33165
33166function find_annotated_props(ast) {
33167 var annotated_props = new Set();
33168 walk(ast, node => {
33169 if (
33170 node instanceof AST_ClassPrivateProperty
33171 || node instanceof AST_PrivateMethod
33172 || node instanceof AST_PrivateGetter
33173 || node instanceof AST_PrivateSetter
33174 || node instanceof AST_DotHash
33175 ) ; else if (node instanceof AST_ObjectKeyVal) {
33176 if (typeof node.key == "string" && has_annotation(node, _MANGLEPROP)) {
33177 annotated_props.add(node.key);
33178 }
33179 } else if (node instanceof AST_ObjectProperty) {
33180 // setter or getter, since KeyVal is handled above
33181 if (has_annotation(node, _MANGLEPROP)) {
33182 annotated_props.add(node.key.name);
33183 }
33184 } else if (node instanceof AST_Dot) {
33185 if (has_annotation(node, _MANGLEPROP)) {
33186 annotated_props.add(node.property);
33187 }
33188 } else if (node instanceof AST_Sub) {
33189 if (node.property instanceof AST_String && has_annotation(node, _MANGLEPROP)) {
33190 annotated_props.add(node.property.value);
33191 }
33192 }
33193 });
33194 return annotated_props;
33195}
33196
33197function mangle_properties(ast, options, annotated_props = find_annotated_props(ast)) {
33198 options = defaults(options, {
33199 builtins: false,
33200 cache: null,
33201 debug: false,
33202 keep_quoted: false,
33203 nth_identifier: base54,
33204 only_cache: false,
33205 regex: null,
33206 reserved: null,
33207 undeclared: false,
33208 only_annotated: false,
33209 }, true);
33210
33211 var nth_identifier = options.nth_identifier;
33212
33213 var reserved_option = options.reserved;
33214 if (!Array.isArray(reserved_option)) reserved_option = [reserved_option];
33215 var reserved = new Set(reserved_option);
33216 if (!options.builtins) find_builtins(reserved);
33217
33218 var cname = -1;
33219
33220 var cache;
33221 if (options.cache) {
33222 cache = options.cache.props;
33223 } else {
33224 cache = new Map();
33225 }
33226
33227 var only_annotated = options.only_annotated;
33228 var regex = options.regex && new RegExp(options.regex);
33229
33230 // note debug is either false (disabled), or a string of the debug suffix to use (enabled).
33231 // note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
33232 // the same as passing an empty string.
33233 var debug = options.debug !== false;
33234 var debug_name_suffix;
33235 if (debug) {
33236 debug_name_suffix = (options.debug === true ? "" : options.debug);
33237 }
33238
33239 var names_to_mangle = new Set();
33240 var unmangleable = new Set();
33241 // Track each already-mangled name to prevent nth_identifier from generating
33242 // the same name.
33243 cache.forEach((mangled_name) => unmangleable.add(mangled_name));
33244
33245 var keep_quoted = !!options.keep_quoted;
33246
33247 // step 1: find candidates to mangle
33248 ast.walk(new TreeWalker(function(node) {
33249 if (
33250 node instanceof AST_ClassPrivateProperty
33251 || node instanceof AST_PrivateMethod
33252 || node instanceof AST_PrivateGetter
33253 || node instanceof AST_PrivateSetter
33254 || node instanceof AST_DotHash
33255 ) ; else if (node instanceof AST_ObjectKeyVal) {
33256 if (typeof node.key == "string" && (!keep_quoted || !node.quote)) {
33257 add(node.key);
33258 }
33259 } else if (node instanceof AST_ObjectProperty) {
33260 // setter or getter, since KeyVal is handled above
33261 if (!keep_quoted || !node.quote) {
33262 add(node.key.name);
33263 }
33264 } else if (node instanceof AST_Dot) {
33265 var declared = !!options.undeclared;
33266 if (!declared) {
33267 var root = node;
33268 while (root.expression) {
33269 root = root.expression;
33270 }
33271 declared = !(root.thedef && root.thedef.undeclared);
33272 }
33273 if (declared &&
33274 (!keep_quoted || !node.quote)) {
33275 add(node.property);
33276 }
33277 } else if (node instanceof AST_Sub) {
33278 if (!keep_quoted) {
33279 addStrings(node.property, add);
33280 }
33281 } else if (node instanceof AST_Call
33282 && node.expression.print_to_string() == "Object.defineProperty") {
33283 addStrings(node.args[1], add);
33284 } else if (node instanceof AST_Binary && node.operator === "in") {
33285 addStrings(node.left, add);
33286 } else if (node instanceof AST_String && has_annotation(node, _KEY)) {
33287 add(node.value);
33288 }
33289 }));
33290
33291 // step 2: transform the tree, renaming properties
33292 return ast.transform(new TreeTransformer(function(node) {
33293 if (
33294 node instanceof AST_ClassPrivateProperty
33295 || node instanceof AST_PrivateMethod
33296 || node instanceof AST_PrivateGetter
33297 || node instanceof AST_PrivateSetter
33298 || node instanceof AST_DotHash
33299 ) ; else if (node instanceof AST_ObjectKeyVal) {
33300 if (typeof node.key == "string" && (!keep_quoted || !node.quote)) {
33301 node.key = mangle(node.key);
33302 }
33303 } else if (node instanceof AST_ObjectProperty) {
33304 // setter, getter, method or class field
33305 if (!keep_quoted || !node.quote) {
33306 if (!node.computed_key()) {
33307 node.key.name = mangle(node.key.name);
33308 }
33309 }
33310 } else if (node instanceof AST_Dot) {
33311 if (!keep_quoted || !node.quote) {
33312 node.property = mangle(node.property);
33313 }
33314 } else if (!keep_quoted && node instanceof AST_Sub) {
33315 node.property = mangleStrings(node.property);
33316 } else if (node instanceof AST_Call
33317 && node.expression.print_to_string() == "Object.defineProperty") {
33318 node.args[1] = mangleStrings(node.args[1]);
33319 } else if (node instanceof AST_Binary && node.operator === "in") {
33320 node.left = mangleStrings(node.left);
33321 } else if (node instanceof AST_String && has_annotation(node, _KEY)) {
33322 // Clear _KEY annotation to prevent double mangling
33323 clear_annotation(node, _KEY);
33324 node.value = mangle(node.value);
33325 }
33326 }));
33327
33328 // only function declarations after this line
33329
33330 function can_mangle(name) {
33331 if (unmangleable.has(name)) return false;
33332 if (reserved.has(name)) return false;
33333 if (options.only_cache) {
33334 return cache.has(name);
33335 }
33336 if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
33337 return true;
33338 }
33339
33340 function should_mangle(name) {
33341 if (only_annotated && !annotated_props.has(name)) return false;
33342 if (regex && !regex.test(name)) {
33343 return annotated_props.has(name);
33344 }
33345 if (reserved.has(name)) return false;
33346 return cache.has(name)
33347 || names_to_mangle.has(name);
33348 }
33349
33350 function add(name) {
33351 if (can_mangle(name)) {
33352 names_to_mangle.add(name);
33353 }
33354
33355 if (!should_mangle(name)) {
33356 unmangleable.add(name);
33357 }
33358 }
33359
33360 function mangle(name) {
33361 if (!should_mangle(name)) {
33362 return name;
33363 }
33364
33365 var mangled = cache.get(name);
33366 if (!mangled) {
33367 if (debug) {
33368 // debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
33369 var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_";
33370
33371 if (can_mangle(debug_mangled)) {
33372 mangled = debug_mangled;
33373 }
33374 }
33375
33376 // either debug mode is off, or it is on and we could not use the mangled name
33377 if (!mangled) {
33378 do {
33379 mangled = nth_identifier.get(++cname);
33380 } while (!can_mangle(mangled));
33381 }
33382
33383 cache.set(name, mangled);
33384 }
33385 return mangled;
33386 }
33387
33388 function mangleStrings(node) {
33389 return node.transform(new TreeTransformer(function(node) {
33390 if (node instanceof AST_Sequence) {
33391 var last = node.expressions.length - 1;
33392 node.expressions[last] = mangleStrings(node.expressions[last]);
33393 } else if (node instanceof AST_String) {
33394 // Clear _KEY annotation to prevent double mangling
33395 clear_annotation(node, _KEY);
33396 node.value = mangle(node.value);
33397 } else if (node instanceof AST_Conditional) {
33398 node.consequent = mangleStrings(node.consequent);
33399 node.alternative = mangleStrings(node.alternative);
33400 }
33401 return node;
33402 }));
33403 }
33404}
33405
33406// to/from base64 functions
33407// Prefer built-in Buffer, if available, then use hack
33408// https://developer.mozilla.org/en-US/docs/Glossary/Base64#The_Unicode_Problem
33409var to_ascii = typeof Buffer !== "undefined"
33410 ? (b64) => Buffer.from(b64, "base64").toString()
33411 : (b64) => decodeURIComponent(escape(atob(b64)));
33412var to_base64 = typeof Buffer !== "undefined"
33413 ? (str) => Buffer.from(str).toString("base64")
33414 : (str) => btoa(unescape(encodeURIComponent(str)));
33415
33416function read_source_map(code) {
33417 var match = /(?:^|[^.])\/\/# sourceMappingURL=data:application\/json(;[\w=-]*)?;base64,([+/0-9A-Za-z]*=*)\s*$/.exec(code);
33418 if (!match) {
33419 console.warn("inline source map not found");
33420 return null;
33421 }
33422 return to_ascii(match[2]);
33423}
33424
33425function set_shorthand(name, options, keys) {
33426 if (options[name]) {
33427 keys.forEach(function(key) {
33428 if (options[key]) {
33429 if (typeof options[key] != "object") options[key] = {};
33430 if (!(name in options[key])) options[key][name] = options[name];
33431 }
33432 });
33433 }
33434}
33435
33436function init_cache(cache) {
33437 if (!cache) return;
33438 if (!("props" in cache)) {
33439 cache.props = new Map();
33440 } else if (!(cache.props instanceof Map)) {
33441 cache.props = map_from_object(cache.props);
33442 }
33443}
33444
33445function cache_to_json(cache) {
33446 return {
33447 props: map_to_object(cache.props)
33448 };
33449}
33450
33451function log_input(files, options, fs, debug_folder) {
33452 if (!(fs && fs.writeFileSync && fs.mkdirSync)) {
33453 return;
33454 }
33455
33456 try {
33457 fs.mkdirSync(debug_folder);
33458 } catch (e) {
33459 if (e.code !== "EEXIST") throw e;
33460 }
33461
33462 const log_path = `${debug_folder}/terser-debug-${(Math.random() * 9999999) | 0}.log`;
33463
33464 options = options || {};
33465
33466 const options_str = JSON.stringify(options, (_key, thing) => {
33467 if (typeof thing === "function") return "[Function " + thing.toString() + "]";
33468 if (thing instanceof RegExp) return "[RegExp " + thing.toString() + "]";
33469 return thing;
33470 }, 4);
33471
33472 const files_str = (file) => {
33473 if (typeof file === "object" && options.parse && options.parse.spidermonkey) {
33474 return JSON.stringify(file, null, 2);
33475 } else if (typeof file === "object") {
33476 return Object.keys(file)
33477 .map((key) => key + ": " + files_str(file[key]))
33478 .join("\n\n");
33479 } else if (typeof file === "string") {
33480 return "```\n" + file + "\n```";
33481 } else {
33482 return file; // What do?
33483 }
33484 };
33485
33486 fs.writeFileSync(log_path, "Options: \n" + options_str + "\n\nInput files:\n\n" + files_str(files) + "\n");
33487}
33488
33489function* minify_sync_or_async(files, options, _fs_module) {
33490 if (
33491 _fs_module
33492 && typeof process === "object"
33493 && process.env
33494 && typeof process.env.TERSER_DEBUG_DIR === "string"
33495 ) {
33496 log_input(files, options, _fs_module, process.env.TERSER_DEBUG_DIR);
33497 }
33498
33499 options = defaults(options, {
33500 compress: {},
33501 ecma: undefined,
33502 enclose: false,
33503 ie8: false,
33504 keep_classnames: undefined,
33505 keep_fnames: false,
33506 mangle: {},
33507 module: false,
33508 nameCache: null,
33509 output: null,
33510 format: null,
33511 parse: {},
33512 rename: undefined,
33513 safari10: false,
33514 sourceMap: false,
33515 spidermonkey: false,
33516 timings: false,
33517 toplevel: false,
33518 warnings: false,
33519 wrap: false,
33520 }, true);
33521
33522 var timings = options.timings && {
33523 start: Date.now()
33524 };
33525 if (options.keep_classnames === undefined) {
33526 options.keep_classnames = options.keep_fnames;
33527 }
33528 if (options.rename === undefined) {
33529 options.rename = options.compress && options.mangle;
33530 }
33531 if (options.output && options.format) {
33532 throw new Error("Please only specify either output or format option, preferrably format.");
33533 }
33534 options.format = options.format || options.output || {};
33535 set_shorthand("ecma", options, [ "parse", "compress", "format" ]);
33536 set_shorthand("ie8", options, [ "compress", "mangle", "format" ]);
33537 set_shorthand("keep_classnames", options, [ "compress", "mangle" ]);
33538 set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
33539 set_shorthand("module", options, [ "parse", "compress", "mangle" ]);
33540 set_shorthand("safari10", options, [ "mangle", "format" ]);
33541 set_shorthand("toplevel", options, [ "compress", "mangle" ]);
33542 set_shorthand("warnings", options, [ "compress" ]); // legacy
33543 var quoted_props;
33544 if (options.mangle) {
33545 options.mangle = defaults(options.mangle, {
33546 cache: options.nameCache && (options.nameCache.vars || {}),
33547 eval: false,
33548 ie8: false,
33549 keep_classnames: false,
33550 keep_fnames: false,
33551 module: false,
33552 nth_identifier: base54,
33553 properties: false,
33554 reserved: [],
33555 safari10: false,
33556 toplevel: false,
33557 }, true);
33558 if (options.mangle.properties) {
33559 if (typeof options.mangle.properties != "object") {
33560 options.mangle.properties = {};
33561 }
33562 if (options.mangle.properties.keep_quoted) {
33563 quoted_props = options.mangle.properties.reserved;
33564 if (!Array.isArray(quoted_props)) quoted_props = [];
33565 options.mangle.properties.reserved = quoted_props;
33566 }
33567 if (options.nameCache && !("cache" in options.mangle.properties)) {
33568 options.mangle.properties.cache = options.nameCache.props || {};
33569 }
33570 }
33571 init_cache(options.mangle.cache);
33572 init_cache(options.mangle.properties.cache);
33573 }
33574 if (options.sourceMap) {
33575 options.sourceMap = defaults(options.sourceMap, {
33576 asObject: false,
33577 content: null,
33578 filename: null,
33579 includeSources: false,
33580 root: null,
33581 url: null,
33582 }, true);
33583 }
33584
33585 // -- Parse phase --
33586 if (timings) timings.parse = Date.now();
33587 var toplevel;
33588 if (files instanceof AST_Toplevel) {
33589 toplevel = files;
33590 } else {
33591 if (typeof files == "string" || (options.parse.spidermonkey && !Array.isArray(files))) {
33592 files = [ files ];
33593 }
33594 options.parse = options.parse || {};
33595 options.parse.toplevel = null;
33596
33597 if (options.parse.spidermonkey) {
33598 options.parse.toplevel = AST_Node.from_mozilla_ast(Object.keys(files).reduce(function(toplevel, name) {
33599 if (!toplevel) return files[name];
33600 toplevel.body = toplevel.body.concat(files[name].body);
33601 return toplevel;
33602 }, null));
33603 } else {
33604 delete options.parse.spidermonkey;
33605
33606 for (var name in files) if (HOP(files, name)) {
33607 options.parse.filename = name;
33608 options.parse.toplevel = parse(files[name], options.parse);
33609 if (options.sourceMap && options.sourceMap.content == "inline") {
33610 if (Object.keys(files).length > 1)
33611 throw new Error("inline source map only works with singular input");
33612 options.sourceMap.content = read_source_map(files[name]);
33613 }
33614 }
33615 }
33616 if (options.parse.toplevel === null) {
33617 throw new Error("no source file given");
33618 }
33619
33620 toplevel = options.parse.toplevel;
33621 }
33622 if (quoted_props && options.mangle.properties.keep_quoted !== "strict") {
33623 reserve_quoted_keys(toplevel, quoted_props);
33624 }
33625 var annotated_props;
33626 if (options.mangle && options.mangle.properties) {
33627 annotated_props = find_annotated_props(toplevel);
33628 }
33629 if (options.wrap) {
33630 toplevel = toplevel.wrap_commonjs(options.wrap);
33631 }
33632 if (options.enclose) {
33633 toplevel = toplevel.wrap_enclose(options.enclose);
33634 }
33635 if (timings) timings.rename = Date.now();
33636
33637 // -- Compress phase --
33638 if (timings) timings.compress = Date.now();
33639 if (options.compress) {
33640 toplevel = new Compressor(options.compress, {
33641 mangle_options: options.mangle
33642 }).compress(toplevel);
33643 }
33644
33645 // -- Mangle phase --
33646 if (timings) timings.scope = Date.now();
33647 if (options.mangle) toplevel.figure_out_scope(options.mangle);
33648 if (timings) timings.mangle = Date.now();
33649 if (options.mangle) {
33650 toplevel.compute_char_frequency(options.mangle);
33651 toplevel.mangle_names(options.mangle);
33652 toplevel = mangle_private_properties(toplevel, options.mangle);
33653 }
33654 if (timings) timings.properties = Date.now();
33655 if (options.mangle && options.mangle.properties) {
33656 toplevel = mangle_properties(toplevel, options.mangle.properties, annotated_props);
33657 }
33658
33659 // Format phase
33660 if (timings) timings.format = Date.now();
33661 var result = {};
33662 if (options.format.ast) {
33663 result.ast = toplevel;
33664 }
33665 if (options.format.spidermonkey) {
33666 result.ast = toplevel.to_mozilla_ast();
33667 }
33668 let format_options;
33669 if (!HOP(options.format, "code") || options.format.code) {
33670 // Make a shallow copy so that we can modify without mutating the user's input.
33671 format_options = {...options.format};
33672 if (!format_options.ast) {
33673 // Destroy stuff to save RAM. (unless the deprecated `ast` option is on)
33674 format_options._destroy_ast = true;
33675
33676 walk(toplevel, node => {
33677 if (node instanceof AST_Scope) {
33678 node.variables = undefined;
33679 node.enclosed = undefined;
33680 node.parent_scope = undefined;
33681 }
33682 if (node.block_scope) {
33683 node.block_scope.variables = undefined;
33684 node.block_scope.enclosed = undefined;
33685 node.block_scope.parent_scope = undefined;
33686 }
33687 });
33688 }
33689
33690 if (options.sourceMap) {
33691 if (options.sourceMap.includeSources && files instanceof AST_Toplevel) {
33692 throw new Error("original source content unavailable");
33693 }
33694 format_options.source_map = yield* SourceMap({
33695 file: options.sourceMap.filename,
33696 orig: options.sourceMap.content,
33697 root: options.sourceMap.root,
33698 files: options.sourceMap.includeSources ? files : null,
33699 });
33700 }
33701 delete format_options.ast;
33702 delete format_options.code;
33703 delete format_options.spidermonkey;
33704 var stream = OutputStream(format_options);
33705 toplevel.print(stream);
33706 result.code = stream.get();
33707 if (options.sourceMap) {
33708 Object.defineProperty(result, "map", {
33709 configurable: true,
33710 enumerable: true,
33711 get() {
33712 const map = format_options.source_map.getEncoded();
33713 return (result.map = options.sourceMap.asObject ? map : JSON.stringify(map));
33714 },
33715 set(value) {
33716 Object.defineProperty(result, "map", {
33717 value,
33718 writable: true,
33719 });
33720 }
33721 });
33722 result.decoded_map = format_options.source_map.getDecoded();
33723 if (options.sourceMap.url == "inline") {
33724 var sourceMap = typeof result.map === "object" ? JSON.stringify(result.map) : result.map;
33725 result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(sourceMap);
33726 } else if (options.sourceMap.url) {
33727 result.code += "\n//# sourceMappingURL=" + options.sourceMap.url;
33728 }
33729 }
33730 }
33731 if (options.nameCache && options.mangle) {
33732 if (options.mangle.cache) options.nameCache.vars = cache_to_json(options.mangle.cache);
33733 if (options.mangle.properties && options.mangle.properties.cache) {
33734 options.nameCache.props = cache_to_json(options.mangle.properties.cache);
33735 }
33736 }
33737 if (format_options && format_options.source_map) {
33738 format_options.source_map.destroy();
33739 }
33740 if (timings) {
33741 timings.end = Date.now();
33742 result.timings = {
33743 parse: 1e-3 * (timings.rename - timings.parse),
33744 rename: 1e-3 * (timings.compress - timings.rename),
33745 compress: 1e-3 * (timings.scope - timings.compress),
33746 scope: 1e-3 * (timings.mangle - timings.scope),
33747 mangle: 1e-3 * (timings.properties - timings.mangle),
33748 properties: 1e-3 * (timings.format - timings.properties),
33749 format: 1e-3 * (timings.end - timings.format),
33750 total: 1e-3 * (timings.end - timings.start)
33751 };
33752 }
33753 return result;
33754}
33755
33756async function minify(files, options, _fs_module) {
33757 const gen = minify_sync_or_async(files, options, _fs_module);
33758
33759 let yielded;
33760 let val;
33761 do {
33762 val = gen.next(await yielded);
33763 yielded = val.value;
33764 } while (!val.done);
33765
33766 return val.value;
33767}
33768
33769function minify_sync(files, options, _fs_module) {
33770 const gen = minify_sync_or_async(files, options, _fs_module);
33771
33772 let yielded;
33773 let val;
33774 do {
33775 if (yielded && typeof yielded.then === "function") {
33776 throw new Error("minify_sync cannot be used with the legacy source-map module");
33777 }
33778 val = gen.next(yielded);
33779 yielded = val.value;
33780 } while (!val.done);
33781
33782 return val.value;
33783}
33784
33785async function run_cli({ program, packageJson, fs, path }) {
33786 const skip_keys = new Set([ "cname", "parent_scope", "scope", "uses_eval", "uses_with" ]);
33787 var files = {};
33788 var options = {
33789 compress: false,
33790 mangle: false
33791 };
33792 const default_options = await _default_options();
33793 program.version(packageJson.name + " " + packageJson.version);
33794 program.parseArgv = program.parse;
33795 program.parse = undefined;
33796
33797 if (process.argv.includes("ast")) program.helpInformation = describe_ast;
33798 else if (process.argv.includes("options")) program.helpInformation = function() {
33799 var text = [];
33800 for (var option in default_options) {
33801 text.push("--" + (option === "sourceMap" ? "source-map" : option) + " options:");
33802 text.push(format_object(default_options[option]));
33803 text.push("");
33804 }
33805 return text.join("\n");
33806 };
33807
33808 program.option("-p, --parse <options>", "Specify parser options.", parse_js());
33809 program.option("-c, --compress [options]", "Enable compressor/specify compressor options.", parse_js());
33810 program.option("-m, --mangle [options]", "Mangle names/specify mangler options.", parse_js());
33811 program.option("--mangle-props [options]", "Mangle properties/specify mangler options.", parse_js());
33812 program.option("-f, --format [options]", "Format options.", parse_js());
33813 program.option("-b, --beautify [options]", "Alias for --format.", parse_js());
33814 program.option("-o, --output <file>", "Output file (default STDOUT).");
33815 program.option("--comments [filter]", "Preserve copyright comments in the output.");
33816 program.option("--config-file <file>", "Read minify() options from JSON file.");
33817 program.option("-d, --define <expr>[=value]", "Global definitions.", parse_js("define"));
33818 program.option("--ecma <version>", "Specify ECMAScript release: 5, 2015, 2016 or 2017...");
33819 program.option("-e, --enclose [arg[,...][:value[,...]]]", "Embed output in a big function with configurable arguments and values.");
33820 program.option("--ie8", "Support non-standard Internet Explorer 8.");
33821 program.option("--keep-classnames", "Do not mangle/drop class names.");
33822 program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
33823 program.option("--module", "Input is an ES6 module");
33824 program.option("--name-cache <file>", "File to hold mangled name mappings.");
33825 program.option("--rename", "Force symbol expansion.");
33826 program.option("--no-rename", "Disable symbol expansion.");
33827 program.option("--safari10", "Support non-standard Safari 10.");
33828 program.option("--source-map [options]", "Enable source map/specify source map options.", parse_js());
33829 program.option("--timings", "Display operations run time on STDERR.");
33830 program.option("--toplevel", "Compress and/or mangle variables in toplevel scope.");
33831 program.option("--wrap <name>", "Embed everything as a function with “exports” corresponding to “name” globally.");
33832 program.arguments("[files...]").parseArgv(process.argv);
33833 if (program.configFile) {
33834 options = JSON.parse(read_file(program.configFile));
33835 }
33836 if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
33837 fatal("ERROR: cannot write source map to STDOUT");
33838 }
33839
33840 [
33841 "compress",
33842 "enclose",
33843 "ie8",
33844 "mangle",
33845 "module",
33846 "safari10",
33847 "sourceMap",
33848 "toplevel",
33849 "wrap"
33850 ].forEach(function(name) {
33851 if (name in program) {
33852 options[name] = program[name];
33853 }
33854 });
33855
33856 if ("ecma" in program) {
33857 if (program.ecma != (program.ecma | 0)) fatal("ERROR: ecma must be an integer");
33858 const ecma = program.ecma | 0;
33859 if (ecma > 5 && ecma < 2015)
33860 options.ecma = ecma + 2009;
33861 else
33862 options.ecma = ecma;
33863 }
33864 if (program.format || program.beautify) {
33865 const chosenOption = program.format || program.beautify;
33866 options.format = typeof chosenOption === "object" ? chosenOption : {};
33867 }
33868 if (program.comments) {
33869 if (typeof options.format != "object") options.format = {};
33870 options.format.comments = typeof program.comments == "string" ? (program.comments == "false" ? false : program.comments) : "some";
33871 }
33872 if (program.define) {
33873 if (typeof options.compress != "object") options.compress = {};
33874 if (typeof options.compress.global_defs != "object") options.compress.global_defs = {};
33875 for (var expr in program.define) {
33876 options.compress.global_defs[expr] = program.define[expr];
33877 }
33878 }
33879 if (program.keepClassnames) {
33880 options.keep_classnames = true;
33881 }
33882 if (program.keepFnames) {
33883 options.keep_fnames = true;
33884 }
33885 if (program.mangleProps) {
33886 if (program.mangleProps.domprops) {
33887 delete program.mangleProps.domprops;
33888 } else {
33889 if (typeof program.mangleProps != "object") program.mangleProps = {};
33890 if (!Array.isArray(program.mangleProps.reserved)) program.mangleProps.reserved = [];
33891 }
33892 if (typeof options.mangle != "object") options.mangle = {};
33893 options.mangle.properties = program.mangleProps;
33894 }
33895 if (program.nameCache) {
33896 options.nameCache = JSON.parse(read_file(program.nameCache, "{}"));
33897 }
33898 if (program.output == "ast") {
33899 options.format = {
33900 ast: true,
33901 code: false
33902 };
33903 }
33904 if (program.parse) {
33905 if (!program.parse.acorn && !program.parse.spidermonkey) {
33906 options.parse = program.parse;
33907 } else if (program.sourceMap && program.sourceMap.content == "inline") {
33908 fatal("ERROR: inline source map only works with built-in parser");
33909 }
33910 }
33911 if (~program.rawArgs.indexOf("--rename")) {
33912 options.rename = true;
33913 } else if (!program.rename) {
33914 options.rename = false;
33915 }
33916
33917 let convert_path = name => name;
33918 if (typeof program.sourceMap == "object" && "base" in program.sourceMap) {
33919 convert_path = function() {
33920 var base = program.sourceMap.base;
33921 delete options.sourceMap.base;
33922 return function(name) {
33923 return path.relative(base, name);
33924 };
33925 }();
33926 }
33927
33928 let filesList;
33929 if (options.files && options.files.length) {
33930 filesList = options.files;
33931
33932 delete options.files;
33933 } else if (program.args.length) {
33934 filesList = program.args;
33935 }
33936
33937 if (filesList) {
33938 simple_glob(filesList).forEach(function(name) {
33939 files[convert_path(name)] = read_file(name);
33940 });
33941 } else {
33942 await new Promise((resolve) => {
33943 var chunks = [];
33944 process.stdin.setEncoding("utf8");
33945 process.stdin.on("data", function(chunk) {
33946 chunks.push(chunk);
33947 }).on("end", function() {
33948 files = [ chunks.join("") ];
33949 resolve();
33950 });
33951 process.stdin.resume();
33952 });
33953 }
33954
33955 await run_cli();
33956
33957 function convert_ast(fn) {
33958 return AST_Node.from_mozilla_ast(Object.keys(files).reduce(fn, null));
33959 }
33960
33961 async function run_cli() {
33962 var content = program.sourceMap && program.sourceMap.content;
33963 if (content && content !== "inline") {
33964 options.sourceMap.content = read_file(content, content);
33965 }
33966 if (program.timings) options.timings = true;
33967
33968 try {
33969 if (program.parse) {
33970 if (program.parse.acorn) {
33971 files = convert_ast(function(toplevel, name) {
33972 return require("acorn").parse(files[name], {
33973 ecmaVersion: 2024,
33974 locations: true,
33975 program: toplevel,
33976 sourceFile: name,
33977 sourceType: options.module || program.parse.module ? "module" : "script"
33978 });
33979 });
33980 } else if (program.parse.spidermonkey) {
33981 files = convert_ast(function(toplevel, name) {
33982 var obj = JSON.parse(files[name]);
33983 if (!toplevel) return obj;
33984 toplevel.body = toplevel.body.concat(obj.body);
33985 return toplevel;
33986 });
33987 }
33988 }
33989 } catch (ex) {
33990 fatal(ex);
33991 }
33992
33993 let result;
33994 try {
33995 result = await minify(files, options, fs);
33996 } catch (ex) {
33997 if (ex.name == "SyntaxError") {
33998 print_error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
33999 var col = ex.col;
34000 var lines = files[ex.filename].split(/\r?\n/);
34001 var line = lines[ex.line - 1];
34002 if (!line && !col) {
34003 line = lines[ex.line - 2];
34004 col = line.length;
34005 }
34006 if (line) {
34007 var limit = 70;
34008 if (col > limit) {
34009 line = line.slice(col - limit);
34010 col = limit;
34011 }
34012 print_error(line.slice(0, 80));
34013 print_error(line.slice(0, col).replace(/\S/g, " ") + "^");
34014 }
34015 }
34016 if (ex.defs) {
34017 print_error("Supported options:");
34018 print_error(format_object(ex.defs));
34019 }
34020 fatal(ex);
34021 return;
34022 }
34023
34024 if (program.output == "ast") {
34025 if (!options.compress && !options.mangle) {
34026 result.ast.figure_out_scope({});
34027 }
34028 console.log(JSON.stringify(result.ast, function(key, value) {
34029 if (value) switch (key) {
34030 case "thedef":
34031 return symdef(value);
34032 case "enclosed":
34033 return value.length ? value.map(symdef) : undefined;
34034 case "variables":
34035 case "globals":
34036 return value.size ? collect_from_map(value, symdef) : undefined;
34037 }
34038 if (skip_keys.has(key)) return;
34039 if (value instanceof AST_Token) return;
34040 if (value instanceof Map) return;
34041 if (value instanceof AST_Node) {
34042 var result = {
34043 _class: "AST_" + value.TYPE
34044 };
34045 if (value.block_scope) {
34046 result.variables = value.block_scope.variables;
34047 result.enclosed = value.block_scope.enclosed;
34048 }
34049 value.CTOR.PROPS.forEach(function(prop) {
34050 if (prop !== "block_scope") {
34051 result[prop] = value[prop];
34052 }
34053 });
34054 return result;
34055 }
34056 return value;
34057 }, 2));
34058 } else if (program.output == "spidermonkey") {
34059 try {
34060 const minified = await minify(
34061 result.code,
34062 {
34063 compress: false,
34064 mangle: false,
34065 format: {
34066 ast: true,
34067 code: false
34068 }
34069 },
34070 fs
34071 );
34072 console.log(JSON.stringify(minified.ast.to_mozilla_ast(), null, 2));
34073 } catch (ex) {
34074 fatal(ex);
34075 return;
34076 }
34077 } else if (program.output) {
34078 fs.mkdirSync(path.dirname(program.output), { recursive: true });
34079 fs.writeFileSync(program.output, result.code);
34080 if (options.sourceMap && options.sourceMap.url !== "inline" && result.map) {
34081 fs.writeFileSync(program.output + ".map", result.map);
34082 }
34083 } else {
34084 console.log(result.code);
34085 }
34086 if (program.nameCache) {
34087 fs.writeFileSync(program.nameCache, JSON.stringify(options.nameCache));
34088 }
34089 if (result.timings) for (var phase in result.timings) {
34090 print_error("- " + phase + ": " + result.timings[phase].toFixed(3) + "s");
34091 }
34092 }
34093
34094 function fatal(message) {
34095 if (message instanceof Error) message = message.stack.replace(/^\S*?Error:/, "ERROR:");
34096 print_error(message);
34097 process.exit(1);
34098 }
34099
34100 // A file glob function that only supports "*" and "?" wildcards in the basename.
34101 // Example: "foo/bar/*baz??.*.js"
34102 // Argument `glob` may be a string or an array of strings.
34103 // Returns an array of strings. Garbage in, garbage out.
34104 function simple_glob(glob) {
34105 if (Array.isArray(glob)) {
34106 return [].concat.apply([], glob.map(simple_glob));
34107 }
34108 if (glob && glob.match(/[*?]/)) {
34109 var dir = path.dirname(glob);
34110 try {
34111 var entries = fs.readdirSync(dir);
34112 } catch (ex) {}
34113 if (entries) {
34114 var pattern = "^" + path.basename(glob)
34115 .replace(/[.+^$[\]\\(){}]/g, "\\$&")
34116 .replace(/\*/g, "[^/\\\\]*")
34117 .replace(/\?/g, "[^/\\\\]") + "$";
34118 var mod = process.platform === "win32" ? "i" : "";
34119 var rx = new RegExp(pattern, mod);
34120 var results = entries.filter(function(name) {
34121 return rx.test(name);
34122 }).map(function(name) {
34123 return path.join(dir, name);
34124 });
34125 if (results.length) return results;
34126 }
34127 }
34128 return [ glob ];
34129 }
34130
34131 function read_file(path, default_value) {
34132 try {
34133 return fs.readFileSync(path, "utf8");
34134 } catch (ex) {
34135 if ((ex.code == "ENOENT" || ex.code == "ENAMETOOLONG") && default_value != null) return default_value;
34136 fatal(ex);
34137 }
34138 }
34139
34140 function parse_js(flag) {
34141 return function(value, options) {
34142 options = options || {};
34143 try {
34144 walk(parse(value, { expression: true }), node => {
34145 if (node instanceof AST_Assign) {
34146 var name = node.left.print_to_string();
34147 var value = node.right;
34148 if (flag) {
34149 options[name] = value;
34150 } else if (value instanceof AST_Array) {
34151 options[name] = value.elements.map(to_string);
34152 } else if (value instanceof AST_RegExp) {
34153 value = value.value;
34154 options[name] = new RegExp(value.source, value.flags);
34155 } else {
34156 options[name] = to_string(value);
34157 }
34158 return true;
34159 }
34160 if (node instanceof AST_Symbol || node instanceof AST_PropAccess) {
34161 var name = node.print_to_string();
34162 options[name] = true;
34163 return true;
34164 }
34165 if (!(node instanceof AST_Sequence)) throw node;
34166
34167 function to_string(value) {
34168 return value instanceof AST_Constant ? value.getValue() : value.print_to_string({
34169 quote_keys: true
34170 });
34171 }
34172 });
34173 } catch(ex) {
34174 if (flag) {
34175 fatal("Error parsing arguments for '" + flag + "': " + value);
34176 } else {
34177 options[value] = null;
34178 }
34179 }
34180 return options;
34181 };
34182 }
34183
34184 function symdef(def) {
34185 var ret = (1e6 + def.id) + " " + def.name;
34186 if (def.mangled_name) ret += " " + def.mangled_name;
34187 return ret;
34188 }
34189
34190 function collect_from_map(map, callback) {
34191 var result = [];
34192 map.forEach(function (def) {
34193 result.push(callback(def));
34194 });
34195 return result;
34196 }
34197
34198 function format_object(obj) {
34199 var lines = [];
34200 var padding = "";
34201 Object.keys(obj).map(function(name) {
34202 if (padding.length < name.length) padding = Array(name.length + 1).join(" ");
34203 return [ name, JSON.stringify(obj[name]) ];
34204 }).forEach(function(tokens) {
34205 lines.push(" " + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]);
34206 });
34207 return lines.join("\n");
34208 }
34209
34210 function print_error(msg) {
34211 process.stderr.write(msg);
34212 process.stderr.write("\n");
34213 }
34214
34215 function describe_ast() {
34216 var out = OutputStream({ beautify: true });
34217 function doitem(ctor) {
34218 out.print("AST_" + ctor.TYPE);
34219 const props = ctor.SELF_PROPS.filter(prop => !/^\$/.test(prop));
34220
34221 if (props.length > 0) {
34222 out.space();
34223 out.with_parens(function() {
34224 props.forEach(function(prop, i) {
34225 if (i) out.space();
34226 out.print(prop);
34227 });
34228 });
34229 }
34230
34231 if (ctor.documentation) {
34232 out.space();
34233 out.print_string(ctor.documentation);
34234 }
34235
34236 if (ctor.SUBCLASSES.length > 0) {
34237 out.space();
34238 out.with_block(function() {
34239 ctor.SUBCLASSES.forEach(function(ctor) {
34240 out.indent();
34241 doitem(ctor);
34242 out.newline();
34243 });
34244 });
34245 }
34246 }
34247 doitem(AST_Node);
34248 return out + "\n";
34249 }
34250}
34251
34252async function _default_options() {
34253 const defs = {};
34254
34255 Object.keys(infer_options({ 0: 0 })).forEach((component) => {
34256 const options = infer_options({
34257 [component]: {0: 0}
34258 });
34259
34260 if (options) defs[component] = options;
34261 });
34262 return defs;
34263}
34264
34265async function infer_options(options) {
34266 try {
34267 await minify("", options);
34268 } catch (error) {
34269 return error.defs;
34270 }
34271}
34272
34273exports._default_options = _default_options;
34274exports._run_cli = run_cli;
34275exports.minify = minify;
34276exports.minify_sync = minify_sync;
34277
34278}));
Note: See TracBrowser for help on using the repository browser.