/*!
 * Microsoft Dynamic Proto Utility, 2.0.5
 * Copyright (c) Microsoft and contributors. All rights reserved.
 */
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, (global.Microsoft = global.Microsoft || {}, global.Microsoft["DynamicProto-JS"] = factory()));
})(this, (function () { 'use strict';

    /*! https://github.com/nevware21/ts-utils v0.14.0 */
    function _pureAssign(func1, func2) {
        return func1 || func2;
    }
    function _pureRef(value, name) {
        return value !== null && value !== undefined ? value[name] : undefined;
    }
    var UNDEF_VALUE = undefined;
    var NULL_VALUE = null;
    var EMPTY = "";
    var FUNCTION = "function";
    var OBJECT = "object";
    var PROTOTYPE = "prototype";
    var __PROTO__ = "__proto__";
    var UNDEFINED = "undefined";
    var SYMBOL = "Symbol";
    var LENGTH = "length";
    var CALL = "call";
    var TO_STRING = "toString";
    var GET_OWN_PROPERTY_DESCRIPTOR = "getOwnPropertyDescriptor";
    var GET_OWN_PROPERTY_NAMES = "getOwnPropertyNames";
    var GET_OWN_PROPERTY_SYMBOLS = "getOwnPropertySymbols";
    var ObjClass = ( _pureAssign(Object));
    var ObjProto = ( _pureRef(ObjClass, PROTOTYPE));
    var StrCls = ( _pureAssign(String));
    var StrProto = ( _pureRef(StrCls, PROTOTYPE));
    var MathCls = ( _pureAssign(Math));
    var ArrCls = ( _pureAssign(Array));
    var ArrProto = ( _pureRef(ArrCls, PROTOTYPE));
    var ArrSlice = ( _pureRef(ArrProto, "slice"));
    var NumberCls = ( _pureAssign(Number));
    ( _pureRef(NumberCls, PROTOTYPE));
    var FuncCls = ( _pureAssign(Function));
    ( _pureRef(FuncCls, PROTOTYPE));
    var DateCls = ( _pureAssign(Date));
    ( _pureRef(DateCls, PROTOTYPE));
    var RegExpCls = ( _pureAssign(RegExp));
    ( _pureRef(RegExpCls, PROTOTYPE));
    var BooleanCls = ( _pureAssign(Boolean));
    ( _pureRef(BooleanCls, PROTOTYPE));
    var ErrorCls = ( _pureAssign(Error));
    ( _pureRef(ErrorCls, PROTOTYPE));
    var POLYFILL_TAG = "_polyfill";
    var POLYFILL_TYPE_NAME = "__nw21$polytype__";
    function safe(func, argArray) {
        try {
            return {
                v: func.apply(this, argArray)
            };
        }
        catch (e) {
            return { e: e };
        }
    }
    function _createIs(theType) {
        return function (value) {
            return typeof value === theType;
        };
    }
    function _createObjIs(theName) {
        var theType = "[object " + theName + "]";
        return function (value) {
            return !!(value && objToString(value) === theType);
        };
    }
    function objToString(value) {
        return ObjProto[TO_STRING].call(value);
    }
    function isUndefined(value) {
        return typeof value === UNDEFINED || value === UNDEFINED;
    }
    function isStrictUndefined(arg) {
        return arg === UNDEF_VALUE;
    }
    function isNullOrUndefined(value) {
        return value === NULL_VALUE || isUndefined(value);
    }
    function isStrictNullOrUndefined(value) {
        return value === NULL_VALUE || value === UNDEF_VALUE;
    }
    var isString = ( _createIs("string"));
    var isFunction = ( _createIs(FUNCTION));
    function isObject(value) {
        if (!value && isNullOrUndefined(value)) {
            return false;
        }
        return !!value && typeof value === OBJECT;
    }
    var isArray = ( _pureRef(ArrCls, "isArray"));
    function isArrayLike(arg) {
        return !isStrictNullOrUndefined(arg) && !isFunction(arg) && isNumber(arg[LENGTH]) && arg[LENGTH] >= 0;
    }
    var isNumber = ( _createIs("number"));
    var isRegExp = ( _createObjIs("RegExp"));
    function _returnNothing() {
        return;
    }
    function _returnEmptyArray() {
        return [];
    }
    function _returnFalse() {
        return false;
    }
    var asString = ( _pureAssign(StrCls));
    var ERROR_TYPE = "[object Error]";
    function dumpObj(object, format) {
        var propertyValueDump = EMPTY;
        var objType = ObjProto[TO_STRING][CALL](object);
        if (objType === ERROR_TYPE) {
            object = { stack: asString(object.stack), message: asString(object.message), name: asString(object.name) };
        }
        try {
            propertyValueDump = JSON.stringify(object, NULL_VALUE, format ? ((typeof format === "number") ? format : 4) : UNDEF_VALUE);
            propertyValueDump = (propertyValueDump ? propertyValueDump.replace(/"(\w+)"\s*:\s{0,1}/g, "$1: ") : NULL_VALUE) || asString(object);
        }
        catch (e) {
            propertyValueDump = " - " + dumpObj(e, format);
        }
        return objType + ": " + propertyValueDump;
    }
    function throwTypeError(message) {
        throw new TypeError(message);
    }
    function throwRangeError(message) {
        throw new RangeError(message);
    }
    function _throwIfNullOrUndefined(obj) {
        if (isStrictNullOrUndefined(obj)) {
            throwTypeError("Cannot convert undefined or null to object");
        }
    }
    function _throwIfNotString(value) {
        if (!isString(value)) {
            throwTypeError("'" + dumpObj(value) + "' is not a string");
        }
    }
    function objHasOwnProperty(obj, prop) {
        return !!obj && ObjProto.hasOwnProperty[CALL](obj, prop);
    }
    var _objGetOwnPropertyDescriptor$2 = ( _pureAssign(( _pureRef(ObjClass, GET_OWN_PROPERTY_DESCRIPTOR)), _returnNothing));
    var objHasOwn = ( _pureAssign(( _pureRef(ObjClass, "hasOwn")), polyObjHasOwn));
    function polyObjHasOwn(obj, prop) {
        _throwIfNullOrUndefined(obj);
        return objHasOwnProperty(obj, prop) || !!_objGetOwnPropertyDescriptor$2(obj, prop);
    }
    function objForEachKey(theObject, callbackfn, thisArg) {
        if (theObject && (isObject(theObject) || isFunction(theObject))) {
            for (var prop in theObject) {
                if (objHasOwn(theObject, prop)) {
                    if (callbackfn[CALL](isStrictNullOrUndefined(thisArg) ? theObject : thisArg, prop, theObject[prop]) === -1) {
                        break;
                    }
                }
            }
        }
    }
    function arrForEach(theArray, callbackfn, thisArg) {
        if (theArray) {
            var len = theArray[LENGTH] >>> 0;
            for (var idx = 0; idx < len; idx++) {
                if (idx in theArray) {
                    if (callbackfn[CALL](isStrictNullOrUndefined(thisArg) ? theArray : thisArg, theArray[idx], idx, theArray) === -1) {
                        break;
                    }
                }
            }
        }
    }
    var _unwrapFunction = _unwrapFunctionWithPoly;
    function _unwrapFunctionWithPoly(funcName, clsProto, polyFunc) {
        var clsFn = clsProto ? clsProto[funcName] : NULL_VALUE;
        return function (thisArg) {
            var theFunc = (thisArg ? thisArg[funcName] : NULL_VALUE) || clsFn;
            if (theFunc || polyFunc) {
                var theArgs = arguments;
                return (theFunc || polyFunc).apply(thisArg, theFunc ? ArrSlice[CALL](theArgs, 1) : theArgs);
            }
            throwTypeError("\"" + asString(funcName) + "\" not defined for " + dumpObj(thisArg));
        };
    }
    function _unwrapFunctionNoInstWithPoly(funcName, clsProto, polyFunc) {
        var clsFn = clsProto ? clsProto[funcName] : NULL_VALUE;
        return function (thisArg) {
            var theFunc = clsFn;
            if (theFunc || polyFunc) {
                var theArgs = arguments;
                return (theFunc || polyFunc).apply(thisArg, theFunc ? ArrSlice[CALL](theArgs, 1) : theArgs);
            }
            throwTypeError("\"" + asString(funcName) + "\" not defined for " + dumpObj(thisArg));
        };
    }
    function _unwrapProp(propName) {
        return function (thisArg) {
            return thisArg[propName];
        };
    }
    function _objPropertyIsEnum(obj, propKey) {
        var desc;
        var fn = ObjClass.getOwnPropertyDescriptor;
        if (!isStrictNullOrUndefined(obj) && fn) {
            desc = safe(fn, [obj, propKey]).v || NULL_VALUE;
        }
        if (!desc && !isStrictNullOrUndefined(obj)) {
            desc = safe(function () {
                for (var key in obj) {
                    if (key == propKey) {
                        return { enumerable: objHasOwnProperty(obj, key) };
                    }
                }
            }).v;
        }
        return (desc && desc.enumerable) || false;
    }
    ( _unwrapFunctionWithPoly("propertyIsEnumerable", NULL_VALUE, _objPropertyIsEnum));
    ( _unwrapFunctionNoInstWithPoly("propertyIsEnumerable", ObjProto, _objPropertyIsEnum));
    var _objGetOwnPropertyDescriptor$1 = ( _pureAssign(( _pureRef(ObjClass, GET_OWN_PROPERTY_DESCRIPTOR)), _returnNothing));
    ( _pureAssign(( _pureRef(ObjClass, GET_OWN_PROPERTY_SYMBOLS)), _returnEmptyArray));
    var propMap = {
        e: "enumerable",
        c: "configurable",
        v: "value",
        w: "writable",
        g: "get",
        s: "set"
    };
    function _createProp(value) {
        var prop = {};
        prop[propMap["c"]] = true;
        prop[propMap["e"]] = true;
        if (value.l) {
            prop.get = function () { return value.l.v; };
            var desc = _objGetOwnPropertyDescriptor$1(value.l, "v");
            if (desc && desc.set) {
                prop.set = function (newValue) {
                    value.l.v = newValue;
                };
            }
        }
        objForEachKey(value, function (key, value) {
            prop[propMap[key]] = isStrictUndefined(value) ? prop[propMap[key]] : value;
        });
        return prop;
    }
    var objDefineProp = ( _pureRef(ObjClass, "defineProperty"));
    var objDefineProperties = ( _pureRef(ObjClass, "defineProperties"));
    function objDefine(target, key, propDesc) {
        return objDefineProp(target, key, _createProp(propDesc));
    }
    function _createKeyValueMap(values, keyType, valueType, completeFn, writable) {
        var theMap = {};
        objForEachKey(values, function (key, value) {
            _assignMapValue(theMap, key, keyType ? value : key);
            _assignMapValue(theMap, value, valueType ? value : key);
        });
        return completeFn ? completeFn(theMap) : theMap;
    }
    function _assignMapValue(theMap, key, value, writable) {
        objDefineProp(theMap, key, {
            value: value,
            enumerable: true,
            writable: false
        });
    }
    function _objIterateEntries(obj, mapper) {
        var result = [];
        objForEachKey(obj, function (key, val) {
            result.push(mapper(key, val));
        });
        return result;
    }
    function polyObjEntries(value) {
        return _objIterateEntries(value, function (k, v) { return [k, v]; });
    }
    function polyObjValues(value) {
        return _objIterateEntries(value, function (_, v) { return v; });
    }
    function polyObjIs(value1, value2) {
        if (value1 !== value1) {
            return value2 !== value2;
        }
        if (value1 === 0 && value2 === 0) {
            return 1 / value1 === 1 / value2;
        }
        return value1 === value2;
    }
    ( _pureAssign(( _pureRef(ObjClass, "isFrozen")), _returnFalse));
    ( _pureAssign(( _pureRef(ObjClass, "isSealed")), _returnFalse));
    var _objFreeze = ( _pureRef(ObjClass, "freeze"));
    function _doNothing(value) {
        return value;
    }
    function _getProto(value) {
        _throwIfNullOrUndefined(value);
        return value[__PROTO__] || NULL_VALUE;
    }
    ( _pureRef(ObjClass, "assign"));
    ( _pureRef(ObjClass, "keys"));
    var objFreeze = ( _pureAssign(_objFreeze, _doNothing));
    ( _pureAssign(( _pureRef(ObjClass, "seal")), _doNothing));
    ( _pureAssign(( _pureRef(ObjClass, "getPrototypeOf")), _getProto));
    ( _pureAssign(( _pureRef(ObjClass, "entries")), polyObjEntries));
    ( _pureAssign(( _pureRef(ObjClass, "values")), polyObjValues));
    ( _pureAssign(( _pureRef(ObjClass, "is")), polyObjIs));
    function createEnumKeyMap(values) {
        return _createKeyValueMap(values, 0 , 0 , objFreeze);
    }
    var _wellKnownSymbolMap = ( createEnumKeyMap({
        asyncIterator: 0 ,
        hasInstance: 1 ,
        isConcatSpreadable: 2 ,
        iterator: 3 ,
        match: 4 ,
        matchAll: 5 ,
        replace: 6 ,
        search: 7 ,
        species: 8 ,
        split: 9 ,
        toPrimitive: 10 ,
        toStringTag: 11 ,
        unscopables: 12
    }));
    var GLOBAL_CONFIG_KEY = "__tsUtils$gblCfg";
    var _globalCfg;
    function _getGlobalValue() {
        var result;
        if (typeof globalThis !== UNDEFINED) {
            result = globalThis;
        }
        if (!result && typeof self !== UNDEFINED) {
            result = self;
        }
        if (!result && typeof window !== UNDEFINED) {
            result = window;
        }
        if (!result && typeof global !== UNDEFINED) {
            result = global;
        }
        return result;
    }
    function _getGlobalConfig() {
        if (!_globalCfg) {
            var gbl = safe(_getGlobalValue).v || {};
            _globalCfg = gbl[GLOBAL_CONFIG_KEY] = gbl[GLOBAL_CONFIG_KEY] || {};
        }
        return _globalCfg;
    }
    var mathMin = ( _pureRef(MathCls, "min"));
    var mathMax = ( _pureRef(MathCls, "max"));
    var strSlice = ( _unwrapFunction("slice", StrProto));
    var strSubstring = ( _unwrapFunction("substring", StrProto));
    ( _unwrapFunctionWithPoly("substr", StrProto, polyStrSubstr));
    function polyStrSubstr(value, start, length) {
        _throwIfNullOrUndefined(value);
        if (length < 0) {
            return EMPTY;
        }
        start = start || 0;
        if (start < 0) {
            start = mathMax(start + value[LENGTH], 0);
        }
        if (isUndefined(length)) {
            return strSlice(value, start);
        }
        return strSlice(value, start, start + length);
    }
    function _tagAsPolyfill(target, polyfillTypeName) {
        if (target) {
            safe(function () {
                target[POLYFILL_TAG] = true;
                target[POLYFILL_TYPE_NAME] = polyfillTypeName;
            });
            safe(objDefine, [target, POLYFILL_TAG, {
                    v: true,
                    w: false,
                    e: false
                }]);
            safe(objDefine, [target, POLYFILL_TYPE_NAME, {
                    v: polyfillTypeName,
                    w: false,
                    e: false
                }]);
        }
        return target;
    }
    var objCreate = ( _pureAssign(( _pureRef(ObjClass, "create")), polyObjCreate));
    function polyObjCreate(obj, properties) {
        var newObj = null;
        function tempFunc() { }
        if (!isStrictNullOrUndefined(obj)) {
            var type = typeof obj;
            if (type !== OBJECT && type !== FUNCTION) {
                throwTypeError("Prototype must be an Object or function: " + dumpObj(obj));
            }
            tempFunc[PROTOTYPE] = obj;
            safe(function () {
                tempFunc[__PROTO__] = obj;
            });
            newObj = new tempFunc();
        }
        else {
            newObj = {};
        }
        if (properties) {
            safe(objDefineProperties, [newObj, properties]);
        }
        return newObj;
    }
    function utcNow() {
        return (Date.now || polyUtcNow)();
    }
    function polyUtcNow() {
        return new Date().getTime();
    }
    function fnApply(fn, thisArg, argArray) {
        return fn.apply(thisArg, argArray);
    }
    function fnCall(fn, thisArg) {
        return fn.apply(thisArg, ArrSlice[CALL](arguments, 2));
    }
    var _globalLazyTestHooks;
    function _initTestHooks() {
        _globalLazyTestHooks = _getGlobalConfig();
    }
    function getLazy(cb, argArray) {
        var lazyValue = {};
        !_globalLazyTestHooks && _initTestHooks();
        lazyValue.b = _globalLazyTestHooks.lzy;
        objDefineProp(lazyValue, "v", {
            configurable: true,
            get: function () {
                var result = fnApply(cb, null, argArray);
                if (!_globalLazyTestHooks.lzy) {
                    objDefineProp(lazyValue, "v", {
                        value: result
                    });
                }
                lazyValue.b = _globalLazyTestHooks.lzy;
                return result;
            }
        });
        return lazyValue;
    }
    var mathRandom = ( _pureRef(MathCls, "random"));
    var _uniqueInstanceId = ( getLazy(function () {
        var value = (utcNow().toString(36).slice(2));
        while (value.length < 16) {
            value += mathRandom().toString(36).slice(2);
        }
        value = value.substring(0, 16);
        return value;
    }));
    var POLY_SYM = "$nw21sym";
    var _polyId = 0;
    var _wellKnownSymbolCache;
    function polyNewSymbol(description) {
        var uniqueId = "_" + _polyId++ + "_" + _uniqueInstanceId.v;
        var symString = SYMBOL + "(" + description + ")";
        function _setProp(name, value) {
            objDefine(theSymbol, name, {
                v: value,
                e: false,
                w: false
            });
        }
        var theSymbol = objCreate(null);
        _setProp("description", asString(description));
        _setProp(TO_STRING, function () { return symString + POLY_SYM + uniqueId; });
        _setProp("valueOf", function () { return theSymbol; });
        _setProp("v", symString);
        _setProp("_uid", uniqueId);
        return _tagAsPolyfill(theSymbol, "symbol");
    }
    function polyGetKnownSymbol(name) {
        !_wellKnownSymbolCache && (_wellKnownSymbolCache = {});
        var result;
        var knownName = _wellKnownSymbolMap[name];
        if (knownName) {
            result = _wellKnownSymbolCache[knownName] = _wellKnownSymbolCache[knownName] || polyNewSymbol(SYMBOL + "." + knownName);
        }
        return result;
    }
    function createCachedValue(value) {
        return objDefineProp({
            toJSON: function () { return value; }
        }, "v", { value: value });
    }
    var WINDOW = "window";
    var _cachedGlobal;
    function getGlobal(useCached) {
        !_globalLazyTestHooks && _initTestHooks();
        if (!_cachedGlobal || useCached === false || _globalLazyTestHooks.lzy) {
            _cachedGlobal = createCachedValue(safe(_getGlobalValue).v || NULL_VALUE);
        }
        return _cachedGlobal.v;
    }
    function getInst(name, useCached) {
        var gbl;
        if (!_cachedGlobal || useCached === false) {
            gbl = getGlobal(useCached);
        }
        else {
            gbl = _cachedGlobal.v;
        }
        if (gbl && gbl[name]) {
            return gbl[name];
        }
        if (name === WINDOW) {
            try {
                return window;
            }
            catch (e) {
            }
        }
        return NULL_VALUE;
    }
    var _symbol;
    function _initSymbol() {
        _symbol = ( createCachedValue(safe((getInst), [SYMBOL]).v));
        return _symbol;
    }
    function getKnownSymbol(name, noPoly) {
        var knownName = _wellKnownSymbolMap[name];
        !_globalLazyTestHooks && _initTestHooks();
        var sym = ((!_globalLazyTestHooks.lzy ? _symbol : 0) || _initSymbol());
        return sym.v ? sym.v[knownName || name] : (!noPoly ? polyGetKnownSymbol(name) : UNDEF_VALUE);
    }
    function isIterator(value) {
        return !!value && isFunction(value.next);
    }
    function isIterable(value) {
        return !isStrictNullOrUndefined(value) && isFunction(value[getKnownSymbol(3 )]);
    }
    var _iterSymbol$1;
    function iterForOf(iter, callbackfn, thisArg) {
        if (iter) {
            if (!isIterator(iter)) {
                !_iterSymbol$1 && (_iterSymbol$1 = createCachedValue(getKnownSymbol(3 )));
                iter = iter[_iterSymbol$1.v] ? iter[_iterSymbol$1.v]() : NULL_VALUE;
            }
            if (isIterator(iter)) {
                var err = UNDEF_VALUE;
                var iterResult = UNDEF_VALUE;
                try {
                    var count = 0;
                    while (!(iterResult = iter.next()).done) {
                        if (callbackfn[CALL](isStrictNullOrUndefined(thisArg) ? iter : thisArg, iterResult.value, count, iter) === -1) {
                            break;
                        }
                        count++;
                    }
                }
                catch (failed) {
                    err = { e: failed };
                    if (iter.throw) {
                        iterResult = NULL_VALUE;
                        iter.throw(err);
                    }
                }
                finally {
                    try {
                        if (iterResult && !iterResult.done) {
                            iter.return && iter.return(iterResult);
                        }
                    }
                    finally {
                        if (err) {
                            throw err.e;
                        }
                    }
                }
            }
        }
    }
    _unwrapFunctionWithPoly("at", ArrProto, polyArrAt);
    function polyArrAt(theArray, index) {
        var result;
        if (isArrayLike(theArray)) {
            var len = theArray.length;
            var idx = index;
            if (idx < 0) {
                idx = len + idx;
            }
            if (idx >= 0 && idx < len) {
                result = theArray[idx];
            }
        }
        return result;
    }
    var arrIndexOf = ( _unwrapFunction("indexOf", ArrProto));
    ( _unwrapFunction("lastIndexOf", ArrProto));
    var arrMap = ( _unwrapFunction("map", ArrProto));
    function arrSlice(theArray, start, end) {
        return ((theArray ? theArray["slice"] : NULL_VALUE) || ArrSlice).apply(theArray, ArrSlice[CALL](arguments, 1));
    }
    function polyArrIncludes(theArray, searchElement, fromIndex) {
        return arrIndexOf(theArray, searchElement, fromIndex) !== -1;
    }
    function polyArrFind(theArray, callbackFn, thisArg) {
        var result;
        var idx = polyArrFindIndex(theArray, callbackFn, thisArg);
        return idx !== -1 ? theArray[idx] : result;
    }
    function polyArrFindIndex(theArray, callbackFn, thisArg) {
        var result = -1;
        arrForEach(theArray, function (value, index) {
            if (callbackFn[CALL](isStrictNullOrUndefined(thisArg) ? theArray : thisArg, value, index, theArray)) {
                result = index;
                return -1;
            }
        });
        return result;
    }
    function polyArrFindLast(theArray, callbackFn, thisArg) {
        var result;
        var idx = polyArrFindLastIndex(theArray, callbackFn, thisArg);
        return idx !== -1 ? theArray[idx] : result;
    }
    function polyArrFindLastIndex(theArray, callbackFn, thisArg) {
        var result = -1;
        var len = theArray[LENGTH] >>> 0;
        for (var idx = len - 1; idx >= 0; idx--) {
            if (idx in theArray && callbackFn[CALL](isStrictNullOrUndefined(thisArg) ? theArray : thisArg, theArray[idx], idx, theArray)) {
                result = idx;
                break;
            }
        }
        return result;
    }
    function polyArrFrom(theValue, mapFn, thisArg) {
        if (isArray(theValue)) {
            var result_1 = arrSlice(theValue);
            return mapFn ? arrMap(result_1, mapFn, thisArg) : result_1;
        }
        var result = [];
        iterForOf(theValue, function (value, cnt) {
            return result.push(mapFn ? mapFn[CALL](thisArg, value, cnt) : value);
        });
        return result;
    }
    ( _unwrapFunctionWithPoly("includes", ArrProto, polyArrIncludes));
    _unwrapFunction("every", ArrProto);
    _unwrapFunction("filter", ArrProto);
    var getLength = ( _unwrapProp(LENGTH));
    _unwrapFunctionWithPoly("fill", ArrProto, polyArrFill);
    function polyArrFill(theArray, value, start, end) {
        if (isArrayLike(theArray)) {
            var len = getLength(theArray);
            var startIdx = start === UNDEF_VALUE ? 0 : start;
            var endIdx = end === UNDEF_VALUE ? len : end;
            if (startIdx < 0) {
                startIdx = mathMax(len + startIdx, 0);
            }
            else {
                startIdx = mathMin(startIdx, len);
            }
            if (endIdx < 0) {
                endIdx = mathMax(len + endIdx, 0);
            }
            else {
                endIdx = mathMin(endIdx, len);
            }
            for (var i = startIdx; i < endIdx; i++) {
                theArray[i] = value;
            }
        }
        return theArray;
    }
    _unwrapFunctionWithPoly("find", ArrProto, polyArrFind);
    _unwrapFunctionWithPoly("findIndex", ArrProto, polyArrFindIndex);
    _unwrapFunctionWithPoly("findLast", ArrProto, polyArrFindLast);
    _unwrapFunctionWithPoly("findLastIndex", ArrProto, polyArrFindLastIndex);
    _unwrapFunctionWithPoly("flatMap", ArrProto, polyArrFlatMap);
    function polyArrFlatMap(theArray, callbackFn, thisArg) {
        _throwIfNullOrUndefined(theArray);
        if (!isFunction(callbackFn)) {
            throwTypeError("callbackFn must be a function");
        }
        var result = [];
        var callbackThis = arguments.length > 2 ? thisArg : undefined;
        arrForEach(theArray, function (theValue, index) {
            var value = fnCall(callbackFn, callbackThis, theValue, index, theArray);
            if (isArray(value)) {
                arrForEach(value, function (mappedValue) {
                    result.push(mappedValue);
                });
            }
            else {
                result.push(value);
            }
        });
        return result;
    }
    ( _pureAssign(( _pureRef(ArrCls, "from")), polyArrFrom));
    var mathFloor = ( _pureRef(MathCls, "floor"));
    var mathCeil = ( _pureRef(MathCls, "ceil"));
    var mathTrunc = ( _pureAssign(( _pureRef(MathCls, "trunc")), polyMathTrunc));
    function polyMathTrunc(value) {
        var theValue = +value;
        return (theValue > 0 ? mathFloor : mathCeil)(theValue);
    }
    function mathToInt(value, throwInfinity) {
        var result = +value;
        if (throwInfinity && (result === Infinity || result == Infinity)) {
            throwRangeError("invalid value [" + dumpObj(value) + "]");
        }
        return result !== result || result === 0 ? 0 : mathTrunc(result);
    }
    function createIterableIterator(ctx) {
        var iterator = createIterator(ctx);
        var itSymbol = getKnownSymbol(3 );
        function _createIterator() {
            return iterator;
        }
        iterator[itSymbol] = _createIterator;
        return iterator;
    }
    function createIterator(ctx) {
        var isDone = false;
        function _value() {
            return ctx.v;
        }
        function _next() {
            if (!isDone) {
                isDone = (ctx.n ? ctx.n(arguments) : true);
            }
            var result = {
                done: isDone
            };
            if (!isDone) {
                objDefine(result, "value", { g: _value });
            }
            return result;
        }
        function _return(value) {
            isDone = true;
            return {
                done: true,
                value: ctx.r && ctx.r(value)
            };
        }
        function _throw(e) {
            isDone = true;
            return {
                done: true,
                value: ctx.t && ctx.t(e)
            };
        }
        var theIterator = {
            next: _next
        };
        if (ctx.r) {
            theIterator.return = _return;
        }
        if (ctx.t) {
            theIterator.throw = _throw;
        }
        return theIterator;
    }
    _unwrapFunctionWithPoly("keys", ArrProto, polyArrKeys);
    function polyArrKeys(value) {
        _throwIfNullOrUndefined(value);
        var idx = -1;
        var len = mathToInt(value.length);
        if (len < 0) {
            len = 0;
        }
        return createIterableIterator({
            n: function () {
                idx++;
                var isDone = idx >= len;
                if (!isDone) {
                    this.v = idx;
                }
                return isDone;
            }
        });
    }
    ( _unwrapFunction("reduce", ArrProto));
    ( _unwrapFunction("reverse", ArrProto));
    ( _unwrapFunction("some", ArrProto));
    _unwrapFunctionWithPoly("with", ArrProto, polyArrWith);
    function polyArrWith(theArray, index, value) {
        var result;
        if (!isArrayLike(theArray)) {
            throwRangeError("Invalid array");
        }
        var len = getLength(theArray);
        var idx = index;
        if (idx < 0) {
            idx = len + idx;
        }
        if (idx < 0 || idx >= len) {
            throwRangeError("Index out of bounds");
        }
        result = arrSlice(theArray);
        result[idx] = value;
        return result;
    }
    var _isProtoArray;
    ( _pureAssign(( _pureRef(ObjClass, "setPrototypeOf")), _polyObjSetPrototypeOf));
    function _polyObjSetPrototypeOf(obj, proto) {
        var _a;
        !_isProtoArray && (_isProtoArray = createCachedValue((_a = {}, _a[__PROTO__] = [], _a) instanceof Array));
        _isProtoArray.v ? obj[__PROTO__] = proto : objForEachKey(proto, function (key, value) { return obj[key] = value; });
        return obj;
    }
    var strReplace = ( _unwrapFunction("replace", StrProto));
    function _createTrimFn(exp) {
        return function _doTrim(value) {
            _throwIfNullOrUndefined(value);
            value = asString(value);
            if (value) {
                value = strReplace(value, exp, EMPTY);
            }
            return value;
        };
    }
    var polyStrTrim = ( _createTrimFn(/^\s+|(?=\s)\s+$/g));
    var polyStrTrimStart = ( _createTrimFn(/^\s+/g));
    var polyStrTrimEnd = ( _createTrimFn(/(?=\s)\s+$/g));
    ( _unwrapFunctionWithPoly("trim", StrProto, polyStrTrim));
    ( _unwrapFunctionWithPoly("trimStart", StrProto, polyStrTrimStart));
    ( _unwrapFunctionWithPoly("trimEnd", StrProto, polyStrTrimEnd));
    ( _unwrapFunction("toUpperCase", StrProto));
    ( _unwrapFunction("toLowerCase", StrProto));
    var strRepeat = ( _unwrapFunctionWithPoly("repeat", StrProto, polyStrRepeat));
    function polyStrRepeat(value, count) {
        _throwIfNullOrUndefined(value);
        count = mathToInt(count, true);
        if (count < 0) {
            throwRangeError("invalid count must be >= 0 && < Infinity");
        }
        var pad = isString(value) ? value : asString(value);
        var result = EMPTY;
        for (; count > 0; (count >>>= 1) && (pad += pad)) {
            if (count & 1) {
                result += pad;
            }
        }
        return result;
    }
    function _padValue(value, targetLength, padString) {
        var result = EMPTY;
        targetLength = mathToInt(targetLength, true);
        targetLength >>= 0;
        var len = value[LENGTH];
        if (len < targetLength) {
            result = isNullOrUndefined(padString) ? " " : asString(padString);
            targetLength = targetLength - len;
            if (targetLength > result[LENGTH]) {
                result = strRepeat(result, mathCeil(targetLength / result[LENGTH]));
            }
            if (result[LENGTH] > targetLength) {
                result = strSubstring(result, 0, targetLength);
            }
        }
        return result;
    }
    ( _unwrapFunctionWithPoly("padStart", StrProto, polyStrPadStart));
    ( _unwrapFunctionWithPoly("padEnd", StrProto, polyStrPadEnd));
    function polyStrPadStart(value, targetLength, padString) {
        return _padValue(value, targetLength, padString) + value;
    }
    function polyStrPadEnd(value, targetLength, padString) {
        return value + _padValue(value, targetLength, padString);
    }
    var _recursionCheckOwnDescriptors;
    var _recursionCheckOwnSymbols;
    var _objGetOwnPropertyNames = ( _pureAssign(( _pureRef(ObjClass, GET_OWN_PROPERTY_NAMES)), _returnEmptyArray));
    var _objGetOwnPropertyDescriptor = ( _pureAssign(( _pureRef(ObjClass, GET_OWN_PROPERTY_DESCRIPTOR)), _returnNothing));
    function polyObjGetOwnPropertyDescriptors(obj) {
        var result = {};
        _throwIfNullOrUndefined(obj);
        if (!_recursionCheckOwnDescriptors) {
            try {
                _recursionCheckOwnDescriptors = true;
                arrForEach(_objGetOwnPropertyNames(obj), function (propName) {
                    var descriptor = _objGetOwnPropertyDescriptor(obj, propName);
                    if (descriptor !== undefined) {
                        result[propName] = descriptor;
                    }
                });
                arrForEach(_polyObjGetOwnPropertySymbols(obj), function (sym) {
                    var descriptor = _objGetOwnPropertyDescriptor(obj, sym);
                    if (descriptor !== undefined) {
                        result[sym] = descriptor;
                    }
                });
            }
            finally {
                _recursionCheckOwnDescriptors = false;
            }
        }
        return result;
    }
    function _polyObjGetOwnPropertySymbols(obj) {
        var result = [];
        var objHasOwn = ObjClass.hasOwn || polyObjHasOwn;
        if (!_recursionCheckOwnSymbols) {
            try {
                _recursionCheckOwnSymbols = true;
                var symEnum = 0 ;
                while (symEnum <= 12 ) {
                    var sym = getKnownSymbol(symEnum);
                    if (sym && objHasOwn(obj, sym)) {
                        result.push(sym);
                    }
                    symEnum++;
                }
            }
            finally {
                _recursionCheckOwnSymbols = false;
            }
        }
        return result;
    }
    ( _pureAssign(( _pureRef(ObjClass, GET_OWN_PROPERTY_DESCRIPTOR)), _returnNothing));
    ( _pureAssign(( _pureRef(ObjClass, "getOwnPropertyDescriptors")), polyObjGetOwnPropertyDescriptors));
    ( _pureAssign(( _pureRef(ObjClass, GET_OWN_PROPERTY_NAMES)), _returnEmptyArray));
    ( _pureAssign(( _pureRef(ObjClass, GET_OWN_PROPERTY_SYMBOLS)), _returnEmptyArray));
    function polyStrSymSplit(value, splitter, limit) {
        var splitFn = splitter ? splitter[getKnownSymbol(9 )] : UNDEF_VALUE;
        return splitFn ? splitFn(value, limit) : [value];
    }
    ( _unwrapFunction("split", StrProto));
    ( _unwrapFunctionWithPoly("split", StrProto, polyStrSymSplit));
    ( _pureAssign(( _pureRef(NumberCls, "isInteger")), _polyNumberIsInteger));
    function _polyNumberIsInteger(value) {
        return isNumber(value) && !isNaN(value) &&
            isFinite(value) &&
            mathFloor(value) === value;
    }
    function createLiteralRegex(matcher) {
        return new RegExp(strReplace(asString(matcher), /[.*+?^${}()|[\]\\]/g, "\\$&") || "(?:)", "g");
    }
    ( _pureRef(MathCls, "abs"));
    ( _pureRef(MathCls, "exp"));
    ( _pureRef(MathCls, "log"));
    ( _pureRef(MathCls, "asin"));
    ( _pureRef(MathCls, "acos"));
    ( _pureRef(MathCls, "atan"));
    ( _pureRef(MathCls, "atan2"));
    ( _pureRef(MathCls, "pow"));
    ( _pureRef(MathCls, "sqrt"));
    ( _pureRef(MathCls, "round"));
    ( _pureRef(MathCls, "sin"));
    ( _pureRef(MathCls, "cos"));
    ( _pureRef(MathCls, "tan"));
    function polyObjFromEntries(entries) {
        var result = {};
        function _defineProtoValue(value) {
            (function(obj, prop, descriptor) { /* ai_es3_polyfil defineProperty */ var func = Object["defineProperty"]; if (func) { try { return func(obj, prop, descriptor); } catch(e) { /* IE8 defines defineProperty, but will throw */ } } if (descriptor && typeof descriptor.value !== undefined) { obj[prop] = descriptor.value; } return obj; })(result, __PROTO__, {
                value: value,
                enumerable: true,
                configurable: true,
                writable: true
            });
        }
        function addEntry(entry) {
            if (isArray(entry) && entry.length >= 2) {
                if (entry[0] === __PROTO__) {
                    _defineProtoValue(entry[1]);
                }
                else {
                    result[entry[0]] = entry[1];
                }
            }
        }
        if (isArray(entries)) {
            arrForEach(entries, addEntry);
        }
        else if (isIterable(entries)) {
            iterForOf(entries, addEntry);
        }
        return result;
    }
    ( _pureAssign(( _pureRef(ObjClass, "fromEntries")), polyObjFromEntries));
    ( _pureAssign(( _pureRef(ObjClass, "preventExtensions")), _doNothing));
    ( _pureAssign(( _pureRef(ObjClass, "isExtensible")), _returnFalse));
    var strIndexOf = ( _unwrapFunction("indexOf", StrProto));
    ( _unwrapFunction("lastIndexOf", StrProto));
    ( _unwrapFunctionWithPoly("at", StrProto, polyStrAt));
    function polyStrAt(value, index) {
        _throwIfNullOrUndefined(value);
        return polyArrAt(asString(value), mathToInt(index));
    }
    ( _unwrapFunctionWithPoly("endsWith", StrProto, polyStrEndsWith));
    function polyStrEndsWith(value, searchString, length) {
        _throwIfNotString(value);
        var searchValue = isString(searchString) ? searchString : asString(searchString);
        var end = (!isUndefined(length) && length < value[LENGTH]) ? length : value[LENGTH];
        return strSubstring(value, end - searchValue[LENGTH], end) === searchValue;
    }
    ( _unwrapFunctionWithPoly("includes", StrProto, polyStrIncludes));
    function polyStrIncludes(value, searchString, position) {
        if (isRegExp(searchString)) {
            throwTypeError("'searchString' must not be a regular expression" + dumpObj(searchString));
        }
        return strIndexOf(value, asString(searchString), position) !== -1;
    }
    ( _unwrapFunctionWithPoly("matchAll", StrProto, polyStrMatchAll));
    function _cloneRegExp(theRegex) {
        var flags = theRegex.flags;
        if (flags === undefined) {
            flags = EMPTY;
            theRegex.global && (flags += "g");
            theRegex.ignoreCase && (flags += "i");
            theRegex.multiline && (flags += "m");
            theRegex.dotAll && (flags += "s");
            theRegex.unicode && (flags += "u");
            theRegex.sticky && (flags += "y");
        }
        var result = new RegExp(theRegex.source, flags);
        result.lastIndex = mathMax(0, theRegex.lastIndex);
        return result;
    }
    function _advanceStringIndex(value, index, unicode) {
        var newIndex = index + 1;
        if (unicode) {
            if (index < value.length) {
                var first = value.charCodeAt(index);
                if (first >= 0xD800 && first <= 0xDBFF) {
                    var second = value.charCodeAt(index + 1);
                    if (second >= 0xDC00 && second <= 0xDFFF) {
                        newIndex++;
                    }
                }
            }
        }
        return newIndex;
    }
    function polyStrMatchAll(value, matcher) {
        _throwIfNullOrUndefined(value);
        var result;
        var matchSym = getKnownSymbol(4 );
        var isMatcherRegExp = isRegExp(matcher)
            && (!matcher || isStrictNullOrUndefined(matcher[matchSym]) || matcher[matchSym] !== false);
        if (isMatcherRegExp && !matcher.global) {
            throwTypeError("matcher must be a global regular expression");
        }
        var theValue = asString(value);
        var matchAllFn = matcher && matcher[getKnownSymbol(5 )];
        if (isFunction(matchAllFn)) {
            result = matchAllFn.call(matcher, theValue);
        }
        else {
            var theRegex_1 = isMatcherRegExp ? _cloneRegExp(matcher) : new RegExp(matcher, "g");
            var ctx_1 = {
                n: function () {
                    var match = theRegex_1.exec(theValue);
                    if (!match) {
                        return true;
                    }
                    if (match[0] === EMPTY) {
                        theRegex_1.lastIndex = _advanceStringIndex(theValue, theRegex_1.lastIndex, !!theRegex_1.unicode);
                    }
                    ctx_1.v = match;
                    return false;
                },
                v: undefined
            };
            result = createIterableIterator(ctx_1);
        }
        return result;
    }
    ( _unwrapFunctionWithPoly("replaceAll", StrProto, polyStrReplaceAll));
    function polyStrReplaceAll(value, searchValue, replaceValue) {
        _throwIfNullOrUndefined(value);
        var matchSymbol = getKnownSymbol(4 );
        var replaceSymbol = getKnownSymbol(6 );
        var replaceFn;
        var matcher;
        var isRegex = isRegExp(searchValue);
        var theValue = isString(value) ? value : asString(value);
        var isSearchNotNull = searchValue || !isStrictNullOrUndefined(searchValue);
        if (isRegex && isSearchNotNull) {
            isRegex = searchValue[matchSymbol] !== false;
        }
        if (isRegex) {
            if (!searchValue.global) {
                throwTypeError("searchValue must be a global regular expression");
            }
            matcher = searchValue;
        }
        else {
            replaceFn = isSearchNotNull ? searchValue[replaceSymbol] : null;
            if (isFunction(replaceFn)) {
                return replaceFn.call(searchValue, theValue, replaceValue);
            }
            var search = isString(searchValue) ? searchValue : asString(searchValue);
            matcher = createLiteralRegex(search);
        }
        return strReplace(theValue, matcher, replaceValue);
    }
    ( _unwrapFunctionWithPoly("startsWith", StrProto, polyStrStartsWith));
    function polyStrStartsWith(value, searchString, position) {
        _throwIfNotString(value);
        var searchValue = isString(searchString) ? searchString : asString(searchString);
        var pos = position > 0 ? position : 0;
        return strSubstring(value, pos, pos + searchValue[LENGTH]) === searchValue;
    }

    var _a;
    var Constructor = 'constructor';
    var Prototype = 'prototype';
    var strFunction = 'function';
    var DynInstFuncTable = '_dynInstFuncs';
    var DynProxyTag = '_isDynProxy';
    var DynClassName = '_dynClass';
    var DynBaseProtoFuncs = '_dynBaseFuncs';
    var DynClassNamePrefix = '_dynCls$';
    var DynInstChkTag = '_dynInstChk';
    var DynAllowInstChkTag = DynInstChkTag;
    var DynResolvedCachePrefix = '_dyn_r$';
    var DynProtoDefaultOptions = '_dfOpts';
    var UnknownValue = '_unknown_';
    var str__Proto = "__proto__";
    var DynProtoBaseProto = "_dyn" + str__Proto;
    var DynProtoGlobalSettings = "__dynProto$Gbl";
    var DynProtoCurrent = "_dynInstProto";
    var strUseBaseInst = 'useBaseInst';
    var strSetInstFuncs = 'setInstFuncs';
    var Obj = Object;
    var _objGetPrototypeOf = Obj["getPrototypeOf"];
    var _objGetOwnProps = Obj["getOwnPropertyNames"];
    var _gbl = getGlobal();
    var _gblInst = _gbl[DynProtoGlobalSettings] || (_gbl[DynProtoGlobalSettings] = {
        o: (_a = {},
            _a[strSetInstFuncs] = true,
            _a[strUseBaseInst] = true,
            _a),
        n: 1000
    });
    function _isObjectOrArrayPrototype(target) {
        return target && (target === Obj[Prototype] || target === Array[Prototype]);
    }
    function _isObjectArrayOrFunctionPrototype(target) {
        return _isObjectOrArrayPrototype(target) || target === Function[Prototype];
    }
    function _getObjProto(target) {
        var newProto;
        if (target) {
            if (_objGetPrototypeOf) {
                return _objGetPrototypeOf(target);
            }
            var curProto = target[str__Proto] || target[Prototype] || (target[Constructor] ? target[Constructor][Prototype] : null);
            newProto = target[DynProtoBaseProto] || curProto;
            if (!objHasOwnProperty(target, DynProtoBaseProto)) {
                delete target[DynProtoCurrent];
                newProto = target[DynProtoBaseProto] = target[DynProtoCurrent] || target[DynProtoBaseProto];
                target[DynProtoCurrent] = curProto;
            }
        }
        return newProto;
    }
    function _forEachProp(target, func) {
        var props = [];
        if (_objGetOwnProps) {
            props = _objGetOwnProps(target);
        }
        else {
            for (var name_1 in target) {
                if (typeof name_1 === "string" && objHasOwnProperty(target, name_1)) {
                    props.push(name_1);
                }
            }
        }
        if (props && props.length > 0) {
            for (var lp = 0; lp < props.length; lp++) {
                func(props[lp]);
            }
        }
    }
    function _isDynamicCandidate(target, funcName, skipOwn) {
        return (funcName !== Constructor && typeof target[funcName] === strFunction && (skipOwn || objHasOwnProperty(target, funcName)) && funcName !== str__Proto && funcName !== Prototype);
    }
    function _throwTypeError(message) {
        throwTypeError("DynamicProto: " + message);
    }
    function _getInstanceFuncs(thisTarget) {
        var instFuncs = objCreate(null);
        _forEachProp(thisTarget, function (name) {
            if (!instFuncs[name] && _isDynamicCandidate(thisTarget, name, false)) {
                instFuncs[name] = thisTarget[name];
            }
        });
        return instFuncs;
    }
    function _hasVisited(values, value) {
        for (var lp = values.length - 1; lp >= 0; lp--) {
            if (values[lp] === value) {
                return true;
            }
        }
        return false;
    }
    function _getBaseProtoFuncs(classProto) {
        if (objHasOwnProperty(classProto, DynBaseProtoFuncs)) {
            return classProto[DynBaseProtoFuncs];
        }
        var baseFuncSources = objCreate(null);
        var baseProto = _getObjProto(classProto);
        var visited = [];
        while (baseProto && !_isObjectArrayOrFunctionPrototype(baseProto) && !_hasVisited(visited, baseProto)) {
            _forEachProp(baseProto, function (name) {
                if (!baseFuncSources[name] && _isDynamicCandidate(baseProto, name, !_objGetPrototypeOf)) {
                    baseFuncSources[name] = baseProto;
                }
            });
            visited.push(baseProto);
            baseProto = _getObjProto(baseProto);
        }
        classProto[DynBaseProtoFuncs] = baseFuncSources;
        return baseFuncSources;
    }
    function _getBaseFuncs(classProto, thisTarget, instFuncs, useBaseInst) {
        function _instFuncProxy(target, funcHost, funcName) {
            var theFunc = funcHost[funcName];
            if (theFunc[DynProxyTag] && useBaseInst) {
                var instFuncTable = target[DynInstFuncTable] || {};
                if (instFuncTable[DynAllowInstChkTag] !== false) {
                    theFunc = (instFuncTable[funcHost[DynClassName]] || {})[funcName] || theFunc;
                }
            }
            return function () {
                return theFunc.apply(target, arguments);
            };
        }
        var baseFuncs = objCreate(null);
        _forEachProp(instFuncs, function (name) {
            baseFuncs[name] = _instFuncProxy(thisTarget, instFuncs, name);
        });
        var baseFuncSources = _getBaseProtoFuncs(classProto);
        for (var name_2 in baseFuncSources) {
            if (!baseFuncs[name_2]) {
                baseFuncs[name_2] = _instFuncProxy(thisTarget, baseFuncSources[name_2], name_2);
            }
        }
        return baseFuncs;
    }
    function _getInstFunc(target, funcName, proto, currentDynProtoProxy) {
        var instFunc = null;
        if (target && objHasOwnProperty(proto, DynClassName)) {
            var instFuncTable = target[DynInstFuncTable] || objCreate(null);
            instFunc = (instFuncTable[proto[DynClassName]] || objCreate(null))[funcName];
            if (!instFunc) {
                _throwTypeError("Missing [" + funcName + "] " + strFunction);
            }
            if (!instFunc[DynInstChkTag] && instFuncTable[DynAllowInstChkTag] !== false) {
                var canAddInst = !objHasOwnProperty(target, funcName);
                if (canAddInst) {
                    var objProto = _getObjProto(target);
                    var visited = [];
                    while (objProto && !_isObjectArrayOrFunctionPrototype(objProto) && !_hasVisited(visited, objProto)) {
                        var protoFunc = objProto[funcName];
                        if (protoFunc) {
                            canAddInst = (protoFunc === currentDynProtoProxy);
                            break;
                        }
                        visited.push(objProto);
                        objProto = _getObjProto(objProto);
                    }
                }
                try {
                    if (canAddInst) {
                        target[funcName] = instFunc;
                    }
                    instFunc[DynInstChkTag] = 1;
                }
                catch (e) {
                    instFuncTable[DynAllowInstChkTag] = false;
                }
            }
        }
        return instFunc;
    }
    function _getProtoFunc(funcName, proto, currentDynProtoProxy) {
        var protoFunc = proto[funcName];
        if (protoFunc === currentDynProtoProxy) {
            protoFunc = _getObjProto(proto)[funcName];
        }
        if (typeof protoFunc !== strFunction) {
            _throwTypeError("[" + funcName + "] is not a " + strFunction);
        }
        return protoFunc;
    }
    function _populatePrototype(proto, className, target, baseInstFuncs, setInstanceFunc) {
        function _createDynamicPrototype(proto, funcName) {
            var cacheKey = DynResolvedCachePrefix + className + "." + funcName;
            var dynProtoProxy = function () {
                var instFuncTable = this[DynInstFuncTable];
                var instFunc = instFuncTable ? instFuncTable[cacheKey] : undefined;
                if (!instFunc) {
                    instFunc = _getInstFunc(this, funcName, proto, dynProtoProxy) || _getProtoFunc(funcName, proto, dynProtoProxy);
                    if (instFuncTable) {
                        instFuncTable[cacheKey] = instFunc;
                    }
                }
                return instFunc.apply(this, arguments);
            };
            dynProtoProxy[DynProxyTag] = 1;
            return dynProtoProxy;
        }
        if (!_isObjectOrArrayPrototype(proto)) {
            var instFuncTable_1 = target[DynInstFuncTable] = target[DynInstFuncTable] || objCreate(null);
            if (!_isObjectOrArrayPrototype(instFuncTable_1)) {
                var instFuncs_1 = instFuncTable_1[className] = (instFuncTable_1[className] || objCreate(null));
                if (instFuncTable_1[DynAllowInstChkTag] !== false) {
                    instFuncTable_1[DynAllowInstChkTag] = !!setInstanceFunc;
                }
                if (!_isObjectOrArrayPrototype(instFuncs_1)) {
                    _forEachProp(target, function (name) {
                        if (_isDynamicCandidate(target, name, false) && target[name] !== baseInstFuncs[name]) {
                            instFuncs_1[name] = target[name];
                            delete target[name];
                            delete instFuncTable_1[DynResolvedCachePrefix + className + "." + name];
                            if (!objHasOwnProperty(proto, name) || (proto[name] && !proto[name][DynProxyTag])) {
                                proto[name] = _createDynamicPrototype(proto, name);
                            }
                        }
                    });
                }
            }
        }
    }
    function _checkPrototype(classProto, thisTarget) {
        if (_objGetPrototypeOf) {
            var visited = [];
            var thisProto = _getObjProto(thisTarget);
            while (thisProto && !_isObjectArrayOrFunctionPrototype(thisProto) && !_hasVisited(visited, thisProto)) {
                if (thisProto === classProto) {
                    return true;
                }
                visited.push(thisProto);
                thisProto = _getObjProto(thisProto);
            }
            return false;
        }
        return true;
    }
    function _getObjName(target, unknownValue) {
        if (objHasOwnProperty(target, Prototype)) {
            return target.name || unknownValue || UnknownValue;
        }
        return (((target || {})[Constructor]) || {}).name || unknownValue || UnknownValue;
    }
    function dynamicProto(theClass, target, delegateFunc, options) {
        if (!objHasOwnProperty(theClass, Prototype)) {
            _throwTypeError("theClass is an invalid class definition.");
        }
        var classProto = theClass[Prototype];
        if (!_checkPrototype(classProto, target)) {
            _throwTypeError("[" + _getObjName(theClass) + "] not in hierarchy of [" + _getObjName(target) + "]");
        }
        var className = null;
        if (objHasOwnProperty(classProto, DynClassName)) {
            className = classProto[DynClassName];
        }
        else {
            className = DynClassNamePrefix + _getObjName(theClass, "_") + "$" + _gblInst.n;
            _gblInst.n++;
            classProto[DynClassName] = className;
        }
        var perfOptions = dynamicProto[DynProtoDefaultOptions];
        var useBaseInst = !!perfOptions[strUseBaseInst];
        if (useBaseInst && options && options[strUseBaseInst] !== undefined) {
            useBaseInst = !!options[strUseBaseInst];
        }
        var instFuncs = _getInstanceFuncs(target);
        var baseFuncs = _getBaseFuncs(classProto, target, instFuncs, useBaseInst);
        delegateFunc(target, baseFuncs);
        var setInstanceFunc = !!_objGetPrototypeOf && !!perfOptions[strSetInstFuncs];
        if (setInstanceFunc && options) {
            setInstanceFunc = !!options[strSetInstFuncs];
        }
        _populatePrototype(classProto, className, target, instFuncs, setInstanceFunc !== false);
    }
    dynamicProto[DynProtoDefaultOptions] = _gblInst.o;

    return dynamicProto;

}));
//# sourceMappingURL=dynamicproto-js.js.map
