From 9c2a670dbf48dd54528794b262a5a7d0007f344d Mon Sep 17 00:00:00 2001 From: cilame Date: Fri, 11 Mar 2022 00:25:59 +0800 Subject: [PATCH] add --- inject.js | 23 ++++-- tools/temp.js | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 223 insertions(+), 7 deletions(-) create mode 100644 tools/temp.js diff --git a/inject.js b/inject.js index 1c995f9..0a92437 100644 --- a/inject.js +++ b/inject.js @@ -37,16 +37,25 @@ function injectfunc(e, window) { var v_env_cache = {} window.v_log_env = function (){ - v_log(v_env_cache) + return v_env_cache } - function v_cache_node(addr, clazz, func, type){ + function v_cache_node(_addr, clazz, func, type, r){ // addr 这里的格式有点乱,还会携带一些代码执行行号的信息,要处理成 url 的形式,方便选择。 + var exp = /http([^:]+:)\/\/([^/:?#]+)(:\d+)?([^?#:]*)?(\?[^#:]*)?(#[^:]*)?/ + if (exp.exec(_addr)){ + var addr = exp.exec(_addr)[0] + }else{ + var addr = _addr + } v_env_cache[addr] = v_env_cache[addr] || {} v_env_cache[addr][clazz] = v_env_cache[addr][clazz] || {} - v_env_cache[addr][clazz][func] = v_env_cache[addr][clazz][func] || [] - if (v_env_cache[addr][clazz][func].indexOf(type) == -1){ - v_env_cache[addr][clazz][func][type] = type + v_env_cache[addr][clazz][func] = v_env_cache[addr][clazz][func] || {} + v_env_cache[addr][clazz][func][type] = {} + if (typeof r == 'string' || typeof r == 'number' || typeof r == 'boolean'){ + v_env_cache[addr][clazz][func][type].value = r + }else{ + v_env_cache[addr][clazz][func][type].value = {} } } @@ -195,7 +204,7 @@ function injectfunc(e, window) { }else{ if (e["config-hook-cookie"] && e["config-hook-cookie-get"]){ if (expurl.v_test(expstr=Error().stack.v_split('\n')[2])){ - v_cache_node(expstr, "Document", "cookie", "get") + v_cache_node(expstr, "Document", "cookie", "get", r) window.v_log(..._mk_logs('[cookie get]', r, get_log_at(expstr.trim()))) } if (e["config-hook-cookie-add-debugger"]){ debugger } @@ -351,7 +360,7 @@ function make_domhooker_funcs(){ var r = _old_get.apply(this, arguments) if (e["config-hook-domobj"] && e["config-hook-domobj-get"] && e["config-hook-${obname}-${name}"]){ if (expurl.v_test(expstr=Error().stack.v_split('\\n')[2])){ - v_cache_node(expstr, "${obname}", "${name}", "get") + v_cache_node(expstr, "${obname}", "${name}", "get", r) window.v_log(..._mk_logs('[${obname} ${name} get]', r, get_log_at(expstr.trim()))) } } diff --git a/tools/temp.js b/tools/temp.js new file mode 100644 index 0000000..1d8a9b2 --- /dev/null +++ b/tools/temp.js @@ -0,0 +1,207 @@ +// 临时文件,尚未使用 + +var envs = {"https://www.geetest.com/demo/libs/gt.js":{"Document":{"getElementsByTagName":{"func":{"value":{}}},"getElementById":{"func":{"value":{}}},"createElement":{"func":{"value":{}}}},"Navigator":{"userAgent":{"get":{"value":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36"}}},"HTMLScriptElement":{"charset":{"set":{"value":{}}},"async":{"set":{"value":{}}},"src":{"set":{"value":{}}},"crossOrigin":{"set":{"value":{}}}},"HTMLElement":{"onerror":{"set":{"value":{}}},"onload":{"set":{"value":{}}}},"Node":{"appendChild":{"func":{"value":{}}}}},"https://apps.bdimg.com/libs/jquery/1.9.1/jquery.js":{"Node":{"nodeType":{"get":{"value":1}},"parentNode":{"get":{"value":{}}},"ownerDocument":{"get":{"value":{}}},"nodeName":{"get":{"value":"DIV"}},"appendChild":{"func":{"value":{}}},"firstChild":{"get":{"value":{}}},"removeChild":{"func":{"value":{}}},"contains":{"func":{"value":{}}},"childNodes":{"get":{"value":{}}}},"Document":{"defaultView":{"get":{"value":{}}},"body":{"get":{"value":{}}},"getElementsByTagName":{"func":{"value":{}}},"createElement":{"func":{"value":{}}},"getElementById":{"func":{"value":{}}},"documentElement":{"get":{"value":{}}},"createDocumentFragment":{"func":{"value":{}}}},"XMLHttpRequest":{"open":{"func":{"value":{}}},"setRequestHeader":{"func":{"value":{}}},"send":{"func":{"value":{}}},"readyState":{"get":{"value":4}},"onreadystatechange":{"set":{"value":{}}},"status":{"get":{"value":200}},"getAllResponseHeaders":{"func":{"value":{}}},"responseText":{"get":{"value":"{\"success\":1,\"challenge\":\"99bea9bcb066c15188819ad13bbd563d\",\"gt\":\"e52c06c937981b90b275d0aff1d40076\",\"new_captcha\":true}"}},"statusText":{"get":{"value":""}}},"EventTarget":{"removeEventListener":{"func":{"value":{}}},"addEventListener":{"func":{"value":{}}}},"HTMLElement":{"style":{"get":{"value":{}}},"offsetHeight":{"get":{"value":0}},"offsetWidth":{"get":{"value":3}},"offsetTop":{"get":{"value":0}}},"CSSStyleDeclaration":{"cssText":{"set":{"value":{}}},"getPropertyValue":{"func":{"value":{}}}},"Element":{"innerHTML":{"set":{"value":{}}},"getElementsByTagName":{"func":{"value":{}}},"id":{"get":{"value":"wait"}}},"NodeList":{"length":{"get":{"value":1}}},"HTMLCollection":{"length":{"get":{"value":0}}}}," at HTMLDocument.document.onkeydown (:105:17)":{"KeyboardEvent":{"key":{"get":{"value":"w"}}}}," at log ()":{"NodeList":{"length":{"get":{"value":0}}}},"https://static.geetest.com/static/js/fullpage.9.0.9.js":{"EventTarget":{"addEventListener":{"func":{"value":{}}},"removeEventListener":{"func":{"value":{}}}},"Document":{"body":{"get":{"value":{}}},"head":{"get":{"value":{}}},"documentElement":{"get":{"value":{}}},"createElement":{"func":{"value":{}}},"compatMode":{"get":{"value":"CSS1Compat"}},"getElementsByTagName":{"func":{"value":{}}},"createTextNode":{"func":{"value":{}}},"getElementById":{"func":{"value":{}}}},"HTMLCanvasElement":{"getContext":{"func":{"value":{}}},"width":{"set":{"value":{}}},"height":{"set":{"value":{}}},"toDataURL":{"func":{"value":{}}}},"Navigator":{"userAgent":{"get":{"value":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36"}},"appName":{"get":{"value":"Netscape"}},"webdriver":{"get":{"value":false}},"hardwareConcurrency":{"get":{"value":16}},"language":{"get":{"value":"zh-CN"}},"languages":{"get":{"value":{}}},"cookieEnabled":{"get":{"value":true}},"onLine":{"get":{"value":true}},"platform":{"get":{"value":"Win32"}},"doNotTrack":{"get":{"value":{}}},"plugins":{"get":{"value":{}}},"maxTouchPoints":{"get":{"value":0}},"javaEnabled":{"func":{"value":{}}}},"Crypto":{"getRandomValues":{"func":{"value":{}}}},"WebGLRenderingContext":{"getExtension":{"func":{"value":{}}},"getParameter":{"func":{"value":{}}},"createBuffer":{"func":{"value":{}}},"bindBuffer":{"func":{"value":{}}},"bufferData":{"func":{"value":{}}},"createProgram":{"func":{"value":{}}},"createShader":{"func":{"value":{}}},"shaderSource":{"func":{"value":{}}},"compileShader":{"func":{"value":{}}},"attachShader":{"func":{"value":{}}},"linkProgram":{"func":{"value":{}}},"useProgram":{"func":{"value":{}}},"getAttribLocation":{"func":{"value":{}}},"getUniformLocation":{"func":{"value":{}}},"enableVertexAttribArray":{"func":{"value":{}}},"vertexAttribPointer":{"func":{"value":{}}},"uniform2f":{"func":{"value":{}}},"drawArrays":{"func":{"value":{}}},"canvas":{"get":{"value":{}}},"getSupportedExtensions":{"func":{"value":{}}}},"Node":{"nodeType":{"get":{"value":1}},"childNodes":{"get":{"value":{}}},"nodeName":{"get":{"value":"SCRIPT"}},"textContent":{"get":{"value":"\n \n \n 一键通过模式\n \n body {\n margin: 50px 0;\n text-align: center;\n font-family: \"PingFangSC-Regular\", \"Open Sans\", Arial, \"Hiragino Sans GB\", \"Microsoft YaHei\", \"STHeiti\", \"WenQuanYi Micro Hei\", SimSun, sans-serif;\n }\n\n .inp {\n border: 1px solid #cccccc;\n border-radius: 2px;\n padding: 0 10px;\n width: 278px;\n height: 40px;\n font-size: 18px;\n }\n\n .btn {\n display: inline-block;\n box-sizing: border-box;\n border: 1px solid #cccccc;\n border-radius: 2px;\n width: 100px;\n height: 40px;\n line-height: 40px;\n font-size: 16px;\n color: #666;\n cursor: pointer;\n background: white linear-gradient(180deg, #ffffff 0%, #f3f3f3 100%);\n }\n\n .btn:hover {\n background: white linear-gradient(0deg, #ffffff 0%, #f3f3f3 100%)\n }\n\n #captcha {\n width: 300px;\n display: inline-block;\n }\n\n label {\n vertical-align: top;\n display: inline-block;\n width: 80px;\n text-align: right;\n }\n\n #text {\n height: 42px;\n width: 298px;\n text-align: center;\n border-radius: 2px;\n background-color: #F3F3F3;\n color: #BBBBBB;\n font-size: 14px;\n letter-spacing: 0.1px;\n line-height: 42px;\n }\n\n #wait {\n display: none;\n height: 42px;\n width: 298px;\n text-align: center;\n border-radius: 2px;\n background-color: #F3F3F3;\n }\n\n .loading {\n margin: auto;\n width: 70px;\n height: 20px;\n }\n\n .loading-dot {\n float: left;\n width: 8px;\n height: 8px;\n margin: 18px 4px;\n background: #ccc;\n\n -webkit-border-radius: 50%;\n -moz-border-radius: 50%;\n border-radius: 50%;\n\n opacity: 0;\n\n -webkit-box-shadow: 0 0 2px black;\n -moz-box-shadow: 0 0 2px black;\n -ms-box-shadow: 0 0 2px black;\n -o-box-shadow: 0 0 2px black;\n box-shadow: 0 0 2px black;\n\n -webkit-animation: loadingFade 1s infinite;\n -moz-animation: loadingFade 1s infinite;\n animation: loadingFade 1s infinite;\n }\n\n .loading-dot:nth-child(1) {\n -webkit-animation-delay: 0s;\n -moz-animation-delay: 0s;\n animation-delay: 0s;\n }\n\n .loading-dot:nth-child(2) {\n -webkit-animation-delay: 0.1s;\n -moz-animation-delay: 0.1s;\n animation-delay: 0.1s;\n }\n\n .loading-dot:nth-child(3) {\n -webkit-animation-delay: 0.2s;\n -moz-animation-delay: 0.2s;\n animation-delay: 0.2s;\n }\n\n .loading-dot:nth-child(4) {\n -webkit-animation-delay: 0.3s;\n -moz-animation-delay: 0.3s;\n animation-delay: 0.3s;\n }\n\n @-webkit-keyframes loadingFade {\n 0% { opacity: 0; }\n 50% { opacity: 0.8; }\n 100% { opacity: 0; }\n }\n\n @-moz-keyframes loadingFade {\n 0% { opacity: 0; }\n 50% { opacity: 0.8; }\n 100% { opacity: 0; }\n }\n\n @keyframes loadingFade {\n 0% { opacity: 0; }\n 50% { opacity: 0.8; }\n 100% { opacity: 0; }\n }\n \n\n\n返回\n一键通过模式\n\n \n 用户名:\n \n \n \n \n 密码:\n \n \n \n \n 完成验证:\n \n \n 行为验证™ 安全组件加载中\n \n \n \n \n \n \n \n \n \n \n \n \n 提交\n\n\n\n\n\n\n\n\n\n var handler = function (captchaObj) {\n captchaObj.appendTo('#captcha');\n captchaObj.onReady(function () {\n $(\"#wait\").hide();\n });\n $('#btn').click(function () {\n var result = captchaObj.getValidate();\n if (!result) {\n return alert('请完成验证');\n }\n $.ajax({\n url: 'gt/validate-fullpage',\n type: 'POST',\n dataType: 'json',\n data: {\n username: $('#username2').val(),\n password: $('#password2').val(),\n geetest_challenge: result.geetest_challenge,\n geetest_validate: result.geetest_validate,\n geetest_seccode: result.geetest_seccode\n },\n success: function (data) {\n if (data.status === 'success') {\n alert('登录成功');\n } else if (data.status === 'fail') {\n alert('登录失败,请完成验证');\n captchaObj.reset();\n }\n }\n });\n })\n // 更多接口说明请参见:http://docs.geetest.com/install/client/web-front/\n };\n\n\n $.ajax({\n url: \"gt/register-fullpage?t=\" + (new Date()).getTime(), // 加随机数防止缓存\n type: \"get\",\n dataType: \"json\",\n success: function (data) {\n $('#text').hide();\n $('#wait').show();\n\n // 调用 initGeetest 进行初始化\n // 参数1:配置参数\n // 参数2:回调,回调的第一个参数验证码对象,之后可以使用它调用相应的接口\n initGeetest({\n // 以下 4 个配置参数为必须,不能缺少\n gt: data.gt,\n challenge: data.challenge,\n offline: !data.success, // 表示用户后台检测极验服务器是否宕机\n new_captcha: data.new_captcha, // 用于宕机时表示是新验证码的宕机\n\n\n product: \"float\", // 产品形式,包括:float,popup\n width: \"300px\",\n https: true,\n api_server: \"apiv6.geetest.com\"\n // 更多配置参数说明请参见:http://docs.geetest.com/install/client/web-front/\n }, handler);\n }\n });\n\n\n\n"}},"appendChild":{"func":{"value":{}}},"removeChild":{"func":{"value":{}}}},"NodeList":{"length":{"get":{"value":0}}},"Element":{"innerHTML":{"get":{"value":"\n \n \n 一键通过模式\n \n\n\n

返回

\n

一键通过模式

\n
\n
\n \n \n
\n
\n
\n \n \n
\n
\n
\n \n
\n
\n 行为验证™ 安全组件加载中\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
提交
\n
\n\n\n\n\n\n\n\n\n"},"set":{"value":{}}},"className":{"set":{"value":{}},"get":{"value":"geetest_holder geetest_wind"}},"setAttribute":{"func":{"value":{}}},"tagName":{"get":{"value":"HTML"}},"getBoundingClientRect":{"func":{"value":{}}}},"Screen":{"colorDepth":{"get":{"value":24}},"width":{"get":{"value":1920}},"height":{"get":{"value":1200}},"availWidth":{"get":{"value":1920}},"availHeight":{"get":{"value":1160}},"availLeft":{"get":{"value":0}},"availTop":{"get":{"value":0}}},"HTMLElement":{"style":{"get":{"value":{}}},"offsetWidth":{"get":{"value":653}},"offsetHeight":{"get":{"value":82}},"onload":{"set":{"value":{}}},"onerror":{"set":{"value":{}}}},"CanvasRenderingContext2D":{"rect":{"func":{"value":{}}},"isPointInPath":{"func":{"value":{}}},"textBaseline":{"set":{"value":{}}},"fillStyle":{"set":{"value":{}}},"fillRect":{"func":{"value":{}}},"font":{"set":{"value":{}}},"fillText":{"func":{"value":{}}},"globalCompositeOperation":{"set":{"value":{}}},"beginPath":{"func":{"value":{}}},"arc":{"func":{"value":{}}},"closePath":{"func":{"value":{}}},"fill":{"func":{"value":{}}}},"PluginArray":{"length":{"get":{"value":5}}},"Plugin":{"filename":{"get":{"value":"internal-pdf-viewer"}}},"HTMLScriptElement":{"charset":{"set":{"value":{}}},"src":{"set":{"value":{}}}},"HTMLLinkElement":{"href":{"set":{"value":{}}},"rel":{"set":{"value":{}}}},"HTMLAnchorElement":{"target":{"set":{"value":{}}},"href":{"set":{"value":{}}}},"DOMRectReadOnly":{"right":{"get":{"value":0}},"left":{"get":{"value":868.21875}},"top":{"get":{"value":301.875}}},"MouseEvent":{"clientX":{"get":{"value":523}},"clientY":{"get":{"value":506}},"x":{"get":{"value":523}},"y":{"get":{"value":506}}},"Event":{"type":{"get":{"value":"pointerup"}},"target":{"get":{"value":{}}}}}," at HTMLDocument.document.onkeydown (:105:37)":{"KeyboardEvent":{"altKey":{"get":{"value":true}}}}} + +window = typeof window == 'undefined' ? global : window +// console.log(Object.keys(envs)) + +function make_v(envs, keys){ + function make_chain(name){ + var _name = name + var list = [] + if (window[_name]){ + list.push(_name) + } + while(window[_name]){ + _name = Object.getPrototypeOf(window[_name]).name + if (_name){ + list.push(_name) + } + } + return list + } + function is_iteral(value){ + var allc = ['string', 'number', 'boolean', 'undefined'] + return allc.indexOf(typeof value) != -1 || value === null + } + function get_class_name(obj){ + return /\[object ([^\]]+)\]/.exec(Object.prototype.toString.call(obj))[1] + } + function make_s(renv, clazz_f){ + var clazz = clazz_f[0] + var father = clazz_f[1] + if (!renv[clazz]){ + var lst = [] + }else{ + var lst = Object.keys(renv[clazz]) + } + var inner = [] + try{ + new window[clazz] + var cannew = true + }catch(e){ + var cannew = false + } + inner.push(` constructor(){ ${ + cannew ? (father ? 'super() ': ' ') + : (father ? 'super() ' : 'if (!v_new_toggle){ throw TypeError("Illegal constructor") } ') + }}`) + for (var i = 0; i < lst.length; i++) { + var name = lst[i] + var temp = renv[clazz][name] + if (temp.get){ + var value = JSON.stringify(temp.get.value) + var limit = 20 + var svalue = value.length > limit ? value.slice(0,limit)+'...' : value + inner.push(` get ${name}(){ if(!(this instanceof ${clazz})){throw TypeError('Illegal invocation')}; v_console_log('${clazz} get ${name} ${svalue}'); return ${value} }`) + } + if (temp.set){ + inner.push(` set ${name}(v){ v_console_log('${clazz} set ${name}', v) }`) + } + if (temp.func){ + inner.push(` ${name}(){ v_console_log('${clazz} func ${name}', [].slice.call(arguments)) }`) + } + } + var plist = Object.keys(window[clazz].prototype) + plist.push(Symbol.toStringTag) + var inner2 = [] + inner2.push(` [Symbol.toStringTag]: {value:"${clazz}",writable:false,enumerable:false,configurable:true},`) + var plist = Object.keys(window[clazz].prototype) + plist.push(Symbol.toStringTag) + for (var i = 0; i < plist.length; i++) { + try{ + var value = window[clazz].prototype[plist[i]] + if (is_iteral(value)){ + var _desc = Object.getOwnPropertyDescriptors(window[clazz].prototype)[plist[i]] + inner2.push(` ${plist[i]}: ${JSON.stringify(_desc)},`) + } + }catch(e){} + } + if (inner2.length){ + inner2.unshift(`Object.defineProperties(${clazz}.prototype, {`) + inner2.push(`})`) + } + var ls = [ + `class ${clazz}` + (father?` extends ${father}`:'') + '{', + ...inner, + '}', + `saf_class(${clazz})`, + ...inner2, + ] + return ls.join('\n') + } + + var ekeys = Object.keys(envs) + var renv = {} + var maxlen = 0 + if (!keys){ keys = ekeys } + if (typeof keys == 'string'){ keys = [keys] } + var collect = [] + for (var i = 0; i < keys.length; i++) { + var e = envs[keys[i]] + var temp = Object.keys(e) + for (var j = 0; j < temp.length; j++) { + renv[temp[j]] = renv[temp[j]] || {} + var funcs = Object.keys(e[temp[j]]) + for (var k = 0; k < funcs.length; k++) { + renv[temp[j]][funcs[k]] = renv[temp[j]][funcs[k]] || {} + var types = Object.keys(e[temp[j]][funcs[k]]) + for (var l = 0; l < types.length; l++) { + renv[temp[j]][funcs[k]][types[l]] = renv[temp[j]][funcs[k]][types[l]] || {} + renv[temp[j]][funcs[k]][types[l]].value = e[temp[j]][funcs[k]][types[l]].value + } + } + var ls = make_chain(temp[j]) + collect.push(ls) + maxlen = ls.length > maxlen ? ls.length : maxlen + } + } + if (!maxlen){ return } + for (var i = 0; i < collect.length; i++) { + var len = maxlen - collect[i].length + for (var j = 0; j < len; j++) { + collect[i].unshift(undefined) + } + } + var sorted = [] + var dicter = {} + dicter['Window'] = 1 + dicter['HTMLDocument'] = 1 + for (var i = maxlen - 1; i >= 0; i--) { + for (var j = 0; j < collect.length; j++) { + var temp = collect[j][i] + var pref = collect[j][i+1] + if (temp && sorted.indexOf(temp) == -1){ + dicter[temp] = [temp, pref] + sorted.push(temp) + } + } + } + var prefix = [ + 'var v_new_toggle = true', + 'var v_console_log = function(){if (!v_new_toggle){ console.log.apply(this, arguments) }}', + 'var v_new = function(v){var temp=v_new_toggle; v_new_toggle = true; var r = new v; v_new_toggle = temp; return r}', + ] + var defines = [] + for (var i = 0; i < sorted.length; i++) { + defines.push(make_s(renv, dicter[sorted[i]])) + } + defines.push(make_s(renv, make_chain('Window'))) + defines.push(make_s(renv, make_chain('HTMLDocument'))) + var _global = [] + var _gcache = [] + var _mpname = [] + var list = Object.keys(window) + var _list = [] + var _first = ['self', 'top', 'frames', 'parent'] + for (var i = 0; i < list.length; i++) { + if (_first.indexOf(list[i]) != -1){ + _list.unshift(list[i]) + }else if (list[i] != 'window'){ + _list.push(list[i]) + } + } + _list.unshift('window') + list = _list + for (var i = 0; i < list.length; i++) { + var obj = window[list[i]] + var name = get_class_name(obj) + if (dicter[name]){ + var idx = _gcache.indexOf(obj) + if (idx == -1){ + _gcache.push(obj) + _mpname.push(list[i]) + if (list[i] == 'window'){ + _global.push(`var __globalThis__ = typeof global != 'undefined' ? global : this`) + _global.push(`var window = new Proxy(v_new(Window), {`) + _global.push(` get(a,b){ v_console_log(\`window get \${b}\`); return a[b] || __globalThis__[b] },`) + _global.push(` set(a,b,c){ v_console_log(\`window set \${b}\`); __globalThis__[b] = a[b] = c },`) + _global.push(`})`) + _global.push(`Object.defineProperties(__globalThis__, {[Symbol.toStringTag]:{value:'Window'}})`) + _global.push(`Object.defineProperties(__globalThis__, Object.getOwnPropertyDescriptors(window))`) + }else{ + _global.push(`window.${list[i]} = v_new(${name})`) + } + }else{ + var vname = _mpname[idx] + _global.push(`window.${list[i]} = ${vname}`) + } + } + } + _global.push('v_new_toggle = saf = saf_class = undefined') + var rets = [ + `var saf,saf_class;!function(){var t=Function.toString,n=[],o=[],e=[].indexOf.bind(n),r=[].push.bind(n),i=[].push.bind(o);function c(t,n){return-1==e(t)&&(r(t),i(\`function \${n||t.name||""}() { [native code] }\`)),t}Object.defineProperty(Function.prototype,"toString",{enumerable:!1,configurable:!0,writable:!0,value:function(){return"function"==typeof this&&o[e(this)]||t.call(this)}}),c(Function.prototype.toString,"toString"),saf=c;var u=Object.getOwnPropertyDescriptors,f=Object.keys;saf_class=function(t){c(t);for(var n=u(t.prototype),o=f(n),e=0;e