1'use strict';
2
3var undefined;
4
5var $SyntaxError = SyntaxError;
6var $Function = Function;
7var $TypeError = TypeError;
8
9// eslint-disable-next-line consistent-return
10var getEvalledConstructor = function (expressionSyntax) {
11	try {
12		return $Function('"use strict"; return (' + expressionSyntax + ').constructor;')();
13	} catch (e) {}
14};
15
16var $gOPD = Object.getOwnPropertyDescriptor;
17if ($gOPD) {
18	try {
19		$gOPD({}, '');
20	} catch (e) {
21		$gOPD = null; // this is IE 8, which has a broken gOPD
22	}
23}
24
25var throwTypeError = function () {
26	throw new $TypeError();
27};
28var ThrowTypeError = $gOPD
29	? (function () {
30		try {
31			// eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties
32			arguments.callee; // IE 8 does not throw here
33			return throwTypeError;
34		} catch (calleeThrows) {
35			try {
36				// IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')
37				return $gOPD(arguments, 'callee').get;
38			} catch (gOPDthrows) {
39				return throwTypeError;
40			}
41		}
42	}())
43	: throwTypeError;
44
45var hasSymbols = require('has-symbols')();
46var hasProto = require('has-proto')();
47
48var getProto = Object.getPrototypeOf || (
49	hasProto
50		? function (x) { return x.__proto__; } // eslint-disable-line no-proto
51		: null
52);
53
54var needsEval = {};
55
56var TypedArray = typeof Uint8Array === 'undefined' || !getProto ? undefined : getProto(Uint8Array);
57
58var INTRINSICS = {
59	'%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError,
60	'%Array%': Array,
61	'%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,
62	'%ArrayIteratorPrototype%': hasSymbols && getProto ? getProto([][Symbol.iterator]()) : undefined,
63	'%AsyncFromSyncIteratorPrototype%': undefined,
64	'%AsyncFunction%': needsEval,
65	'%AsyncGenerator%': needsEval,
66	'%AsyncGeneratorFunction%': needsEval,
67	'%AsyncIteratorPrototype%': needsEval,
68	'%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,
69	'%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt,
70	'%BigInt64Array%': typeof BigInt64Array === 'undefined' ? undefined : BigInt64Array,
71	'%BigUint64Array%': typeof BigUint64Array === 'undefined' ? undefined : BigUint64Array,
72	'%Boolean%': Boolean,
73	'%DataView%': typeof DataView === 'undefined' ? undefined : DataView,
74	'%Date%': Date,
75	'%decodeURI%': decodeURI,
76	'%decodeURIComponent%': decodeURIComponent,
77	'%encodeURI%': encodeURI,
78	'%encodeURIComponent%': encodeURIComponent,
79	'%Error%': Error,
80	'%eval%': eval, // eslint-disable-line no-eval
81	'%EvalError%': EvalError,
82	'%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,
83	'%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,
84	'%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry,
85	'%Function%': $Function,
86	'%GeneratorFunction%': needsEval,
87	'%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,
88	'%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,
89	'%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,
90	'%isFinite%': isFinite,
91	'%isNaN%': isNaN,
92	'%IteratorPrototype%': hasSymbols && getProto ? getProto(getProto([][Symbol.iterator]())) : undefined,
93	'%JSON%': typeof JSON === 'object' ? JSON : undefined,
94	'%Map%': typeof Map === 'undefined' ? undefined : Map,
95	'%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols || !getProto ? undefined : getProto(new Map()[Symbol.iterator]()),
96	'%Math%': Math,
97	'%Number%': Number,
98	'%Object%': Object,
99	'%parseFloat%': parseFloat,
100	'%parseInt%': parseInt,
101	'%Promise%': typeof Promise === 'undefined' ? undefined : Promise,
102	'%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,
103	'%RangeError%': RangeError,
104	'%ReferenceError%': ReferenceError,
105	'%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,
106	'%RegExp%': RegExp,
107	'%Set%': typeof Set === 'undefined' ? undefined : Set,
108	'%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols || !getProto ? undefined : getProto(new Set()[Symbol.iterator]()),
109	'%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,
110	'%String%': String,
111	'%StringIteratorPrototype%': hasSymbols && getProto ? getProto(''[Symbol.iterator]()) : undefined,
112	'%Symbol%': hasSymbols ? Symbol : undefined,
113	'%SyntaxError%': $SyntaxError,
114	'%ThrowTypeError%': ThrowTypeError,
115	'%TypedArray%': TypedArray,
116	'%TypeError%': $TypeError,
117	'%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array,
118	'%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray,
119	'%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array,
120	'%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array,
121	'%URIError%': URIError,
122	'%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap,
123	'%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef,
124	'%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet
125};
126
127if (getProto) {
128	try {
129		null.error; // eslint-disable-line no-unused-expressions
130	} catch (e) {
131		// https://github.com/tc39/proposal-shadowrealm/pull/384#issuecomment-1364264229
132		var errorProto = getProto(getProto(e));
133		INTRINSICS['%Error.prototype%'] = errorProto;
134	}
135}
136
137var doEval = function doEval(name) {
138	var value;
139	if (name === '%AsyncFunction%') {
140		value = getEvalledConstructor('async function () {}');
141	} else if (name === '%GeneratorFunction%') {
142		value = getEvalledConstructor('function* () {}');
143	} else if (name === '%AsyncGeneratorFunction%') {
144		value = getEvalledConstructor('async function* () {}');
145	} else if (name === '%AsyncGenerator%') {
146		var fn = doEval('%AsyncGeneratorFunction%');
147		if (fn) {
148			value = fn.prototype;
149		}
150	} else if (name === '%AsyncIteratorPrototype%') {
151		var gen = doEval('%AsyncGenerator%');
152		if (gen && getProto) {
153			value = getProto(gen.prototype);
154		}
155	}
156
157	INTRINSICS[name] = value;
158
159	return value;
160};
161
162var LEGACY_ALIASES = {
163	'%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'],
164	'%ArrayPrototype%': ['Array', 'prototype'],
165	'%ArrayProto_entries%': ['Array', 'prototype', 'entries'],
166	'%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'],
167	'%ArrayProto_keys%': ['Array', 'prototype', 'keys'],
168	'%ArrayProto_values%': ['Array', 'prototype', 'values'],
169	'%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'],
170	'%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'],
171	'%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'],
172	'%BooleanPrototype%': ['Boolean', 'prototype'],
173	'%DataViewPrototype%': ['DataView', 'prototype'],
174	'%DatePrototype%': ['Date', 'prototype'],
175	'%ErrorPrototype%': ['Error', 'prototype'],
176	'%EvalErrorPrototype%': ['EvalError', 'prototype'],
177	'%Float32ArrayPrototype%': ['Float32Array', 'prototype'],
178	'%Float64ArrayPrototype%': ['Float64Array', 'prototype'],
179	'%FunctionPrototype%': ['Function', 'prototype'],
180	'%Generator%': ['GeneratorFunction', 'prototype'],
181	'%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'],
182	'%Int8ArrayPrototype%': ['Int8Array', 'prototype'],
183	'%Int16ArrayPrototype%': ['Int16Array', 'prototype'],
184	'%Int32ArrayPrototype%': ['Int32Array', 'prototype'],
185	'%JSONParse%': ['JSON', 'parse'],
186	'%JSONStringify%': ['JSON', 'stringify'],
187	'%MapPrototype%': ['Map', 'prototype'],
188	'%NumberPrototype%': ['Number', 'prototype'],
189	'%ObjectPrototype%': ['Object', 'prototype'],
190	'%ObjProto_toString%': ['Object', 'prototype', 'toString'],
191	'%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'],
192	'%PromisePrototype%': ['Promise', 'prototype'],
193	'%PromiseProto_then%': ['Promise', 'prototype', 'then'],
194	'%Promise_all%': ['Promise', 'all'],
195	'%Promise_reject%': ['Promise', 'reject'],
196	'%Promise_resolve%': ['Promise', 'resolve'],
197	'%RangeErrorPrototype%': ['RangeError', 'prototype'],
198	'%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'],
199	'%RegExpPrototype%': ['RegExp', 'prototype'],
200	'%SetPrototype%': ['Set', 'prototype'],
201	'%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'],
202	'%StringPrototype%': ['String', 'prototype'],
203	'%SymbolPrototype%': ['Symbol', 'prototype'],
204	'%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'],
205	'%TypedArrayPrototype%': ['TypedArray', 'prototype'],
206	'%TypeErrorPrototype%': ['TypeError', 'prototype'],
207	'%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'],
208	'%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'],
209	'%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'],
210	'%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'],
211	'%URIErrorPrototype%': ['URIError', 'prototype'],
212	'%WeakMapPrototype%': ['WeakMap', 'prototype'],
213	'%WeakSetPrototype%': ['WeakSet', 'prototype']
214};
215
216var bind = require('function-bind');
217var hasOwn = require('has');
218var $concat = bind.call(Function.call, Array.prototype.concat);
219var $spliceApply = bind.call(Function.apply, Array.prototype.splice);
220var $replace = bind.call(Function.call, String.prototype.replace);
221var $strSlice = bind.call(Function.call, String.prototype.slice);
222var $exec = bind.call(Function.call, RegExp.prototype.exec);
223
224/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */
225var rePropName = /[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g;
226var reEscapeChar = /\\(\\)?/g; /** Used to match backslashes in property paths. */
227var stringToPath = function stringToPath(string) {
228	var first = $strSlice(string, 0, 1);
229	var last = $strSlice(string, -1);
230	if (first === '%' && last !== '%') {
231		throw new $SyntaxError('invalid intrinsic syntax, expected closing `%`');
232	} else if (last === '%' && first !== '%') {
233		throw new $SyntaxError('invalid intrinsic syntax, expected opening `%`');
234	}
235	var result = [];
236	$replace(string, rePropName, function (match, number, quote, subString) {
237		result[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match;
238	});
239	return result;
240};
241/* end adaptation */
242
243var getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {
244	var intrinsicName = name;
245	var alias;
246	if (hasOwn(LEGACY_ALIASES, intrinsicName)) {
247		alias = LEGACY_ALIASES[intrinsicName];
248		intrinsicName = '%' + alias[0] + '%';
249	}
250
251	if (hasOwn(INTRINSICS, intrinsicName)) {
252		var value = INTRINSICS[intrinsicName];
253		if (value === needsEval) {
254			value = doEval(intrinsicName);
255		}
256		if (typeof value === 'undefined' && !allowMissing) {
257			throw new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!');
258		}
259
260		return {
261			alias: alias,
262			name: intrinsicName,
263			value: value
264		};
265	}
266
267	throw new $SyntaxError('intrinsic ' + name + ' does not exist!');
268};
269
270module.exports = function GetIntrinsic(name, allowMissing) {
271	if (typeof name !== 'string' || name.length === 0) {
272		throw new $TypeError('intrinsic name must be a non-empty string');
273	}
274	if (arguments.length > 1 && typeof allowMissing !== 'boolean') {
275		throw new $TypeError('"allowMissing" argument must be a boolean');
276	}
277
278	if ($exec(/^%?[^%]*%?$/, name) === null) {
279		throw new $SyntaxError('`%` may not be present anywhere but at the beginning and end of the intrinsic name');
280	}
281	var parts = stringToPath(name);
282	var intrinsicBaseName = parts.length > 0 ? parts[0] : '';
283
284	var intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing);
285	var intrinsicRealName = intrinsic.name;
286	var value = intrinsic.value;
287	var skipFurtherCaching = false;
288
289	var alias = intrinsic.alias;
290	if (alias) {
291		intrinsicBaseName = alias[0];
292		$spliceApply(parts, $concat([0, 1], alias));
293	}
294
295	for (var i = 1, isOwn = true; i < parts.length; i += 1) {
296		var part = parts[i];
297		var first = $strSlice(part, 0, 1);
298		var last = $strSlice(part, -1);
299		if (
300			(
301				(first === '"' || first === "'" || first === '`')
302				|| (last === '"' || last === "'" || last === '`')
303			)
304			&& first !== last
305		) {
306			throw new $SyntaxError('property names with quotes must have matching quotes');
307		}
308		if (part === 'constructor' || !isOwn) {
309			skipFurtherCaching = true;
310		}
311
312		intrinsicBaseName += '.' + part;
313		intrinsicRealName = '%' + intrinsicBaseName + '%';
314
315		if (hasOwn(INTRINSICS, intrinsicRealName)) {
316			value = INTRINSICS[intrinsicRealName];
317		} else if (value != null) {
318			if (!(part in value)) {
319				if (!allowMissing) {
320					throw new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.');
321				}
322				return void undefined;
323			}
324			if ($gOPD && (i + 1) >= parts.length) {
325				var desc = $gOPD(value, part);
326				isOwn = !!desc;
327
328				// By convention, when a data property is converted to an accessor
329				// property to emulate a data property that does not suffer from
330				// the override mistake, that accessor's getter is marked with
331				// an `originalValue` property. Here, when we detect this, we
332				// uphold the illusion by pretending to see that original data
333				// property, i.e., returning the value rather than the getter
334				// itself.
335				if (isOwn && 'get' in desc && !('originalValue' in desc.get)) {
336					value = desc.get;
337				} else {
338					value = value[part];
339				}
340			} else {
341				isOwn = hasOwn(value, part);
342				value = value[part];
343			}
344
345			if (isOwn && !skipFurtherCaching) {
346				INTRINSICS[intrinsicRealName] = value;
347			}
348		}
349	}
350	return value;
351};
352