@monkey2582/thinconsole 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ !function(t,e){var o=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var o=arguments[e];for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])}return t};function n(t){return String(t).replace(/</g,"&lt;").replace(/>/g,"&gt;")}function i(t){var o=e.createElement("textarea");o.value=t,e.body.appendChild(o),o.select();try{e.execCommand("copy")}catch(t){}e.body.removeChild(o)}function s(t){return t.getHours()+":"+("0"+t.getMinutes()).slice(-2)+":"+("0"+t.getSeconds()).slice(-2)}function a(t){return'<i class="fa '+({info:"fa-info-circle",warn:"fa-exclamation-triangle",error:"fa-times-circle",log:"fa-info"}[t]||"fa-info")+'"></i>'}function l(t){if(!e.querySelector(".conbtn")){this.logs=[],this.systemLogs=[],this.lastLog=null,this.currentTab="console",this.activeFilter="all",this.searchQuery="";var n={position:{x:30,y:30},text:"thinConsole",color:"#007aff",width:"auto",height:"auto",id:"consoleBtn-"+Date.now(),autoShow:!0,theme:"light",maxLog:1e3};this.options=o({},n,t||{}),this.init()}}l.prototype.init=function(){this.injectCSS(),this.createButton(),this.createOverlay(),this.createNotification(),this.captureConsole(),this.bindEvents(),this.options.autoShow&&this.setInitialPosition(),t.thinConsole.instances=t.thinConsole.instances||{},t.thinConsole.instances[this.options.id]=this,this.renderContent()},l.prototype.injectCSS=function(){if(!e.getElementById("tc-lite-css")){var t=e.createElement("style");t.id="tc-lite-css",t.textContent='\n@import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css");\n.floating-console-btn{position:fixed;z-index:11000;padding:12px 20px;border:none;border-radius:5px;background:#007aff;color:#fff;font-size:14px;cursor:pointer;box-shadow:0 4px 12px rgba(0,0,0,.3);}\n.overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.85);z-index:99998;display:none;}\n.overlay.active{display:block;}\n.console-container{position:fixed;bottom:0;left:0;width:100%;height:90%;background:#f5f5f5;display:flex;flex-direction:column;box-shadow:0 -4px 20px rgba(0,0,0,.3);}\n.console-header{display:flex;justify-content:space-between;align-items:center;padding:10px 15px;background:#e0e0e0;}\n.console-title{display:flex;align-items:center;gap:8px;font-weight:bold;}\n.close-btn,.clear-all-btn{background:transparent;border:none;font-size:20px;cursor:pointer;padding:4px 8px;border-radius:3px;}\n.tabs{display:flex;background:#d0d0d0;border-bottom:1px solid #bbb;}\n.tab-btn{padding:8px 16px;border:none;background:transparent;cursor:pointer;}\n.tab-btn.active{background:#f5f5f5;font-weight:bold;}\n.controls{display:flex;padding:8px 12px;gap:8px;background:#e8e8e8;border-bottom:1px solid #ccc;}\n.filter-btn{padding:6px 10px;border:none;background:transparent;cursor:pointer;}\n.filter-btn.active{background:#007aff;color:#fff;border-radius:4px;}\n.search-box{flex:1;max-width:300px;}\n.search-box input{width:100%;padding:6px 10px;border:1px solid #ccc;border-radius:4px;}\n.console-content{flex:1;overflow:hidden;display:flex;flex-direction:column;}\n.console-output,.localstorage-view,.system-logs{flex:1;overflow-y:auto;padding:10px;font-family:monospace;font-size:13px;}\n.log-item{display:flex;gap:8px;padding:8px;margin-bottom:6px;border-left:3px solid #007aff;border-radius:4px;background:#fff;}\n.log-item.warn{border-left-color:#f0ad4e;}\n.log-item.error{border-left-color:#d9534f;}\n.log-icon{width:20px;text-align:center;}\n.log-content{flex:1;word-break:break-word;}\n.timestamp{color:#666;font-size:11px;margin-left:auto;}\n.log-actions{margin-top:4px;font-size:11px;}\n.log-action{cursor:pointer;margin-right:10px;color:#007aff;}\n.nolog{text-align:center;padding:40px;color:#666;}\n.ls-item{background:#fff;padding:10px;margin-bottom:8px;border-radius:4px;}\n.ls-key-row{display:flex;justify-content:space-between;margin-bottom:6px;}\n.ls-key{font-weight:bold;}\n.ls-actions{display:flex;gap:6px;}\n.ls-action-btn{padding:4px 6px;border:none;background:#007aff;color:#fff;border-radius:3px;cursor:pointer;font-size:12px;}\n.ls-value{background:#f6f8fa;padding:6px;border-radius:3px;white-space:pre-wrap;word-break:break-all;font-size:12px;}\n.ls-edit{display:none;margin-top:6px;}\n.ls-edit textarea{width:100%;height:60px;}\n.ls-edit-actions{text-align:right;margin-top:6px;}\n.notification{position:fixed;top:20px;right:20px;padding:8px 14px;background:#4caf50;color:#fff;border-radius:4px;z-index:99999;display:none;}\n.notification.show{display:block;}\n',e.head.appendChild(t)}},l.prototype.createButton=function(){var t=e.createElement("button");t.id=this.options.id,t.className="floating-console-btn conbtn",t.textContent=this.options.text,t.style.background=this.options.color,t.style.width=this.options.width,t.style.height=this.options.height,e.documentElement.appendChild(t),this.btn=t},l.prototype.createOverlay=function(){var t=e.createElement("div");t.className="overlay",t.innerHTML=`\n <div class="console-container">\n <div class="console-header">\n <div class="console-title"><i class="fa fa-terminal"></i> ${n(this.options.text)}</div>\n <button class="clear-all-btn" title="Clear all logs"><i class="fa fa-trash-alt"></i></button>\n <button class="close-btn" title="Close"><i class="fa fa-times"></i></button>\n </div>\n <div class="tabs">\n <button class="tab-btn active" data-tab="console"><i class="fa fa-terminal"></i> Console</button>\n <button class="tab-btn" data-tab="system"><i class="fa fa-server"></i> System</button>\n <button class="tab-btn" data-tab="localstorage"><i class="fa fa-database"></i> LocalStorage</button>\n </div>\n <div class="controls">\n <div class="filters">\n <button class="filter-btn active" data-type="all">All</button>\n <button class="filter-btn" data-type="log">Log</button>\n <button class="filter-btn" data-type="info">Info</button>\n <button class="filter-btn" data-type="warn">Warn</button>\n <button class="filter-btn" data-type="error">Error</button>\n </div>\n <div class="search-box"><input id="searchInput" placeholder="Search logs..."></div>\n </div>\n <div class="console-content">\n <div class="console-output" id="consoleOutput"></div>\n <div class="localstorage-view" id="localstorageView" style="display:none">\n <div class="ls-header"><button id="addLSItemBtn" class="ls-action-btn"><i class="fa fa-plus"></i> Add item</button></div>\n <div class="ls-items" id="lsItems"></div>\n </div>\n <div class="system-logs" id="systemLogs" style="display:none"></div>\n </div>\n </div>\n `,e.documentElement.appendChild(t),this.overlay=t,this.closeConsoleBtn=t.querySelector(".close-btn"),this.clearLogsBtn=t.querySelector(".clear-all-btn"),this.consoleOutput=t.querySelector("#consoleOutput"),this.localstorageView=t.querySelector("#localstorageView"),this.lsItems=t.querySelector("#lsItems"),this.systemLogsEl=t.querySelector("#systemLogs"),this.searchInput=t.querySelector("#searchInput");var o=this;this.closeConsoleBtn.onclick=function(){o.overlay.classList.remove("active")},this.clearLogsBtn.onclick=function(){o.clearAllLogs()},this.searchInput.oninput=function(){o.searchQuery=this.value.trim().toLowerCase(),o.renderContent()};for(var i=t.querySelectorAll(".tab-btn"),s=0;s<i.length;s++)i[s].onclick=function(){for(var t=0;t<i.length;t++)i[t].classList.remove("active");this.classList.add("active"),o.currentTab=this.dataset.tab,o.renderContent()};for(var a=t.querySelectorAll(".filter-btn"),l=0;l<a.length;l++)a[l].onclick=function(){for(var t=0;t<a.length;t++)a[t].classList.remove("active");this.classList.add("active"),o.activeFilter=this.dataset.type,o.renderContent()};t.querySelector("#addLSItemBtn").onclick=function(){o.addLSItem()}},l.prototype.createNotification=function(){var t=e.createElement("div");t.className="notification",e.body.appendChild(t),this.notification=t},l.prototype.showNotification=function(t,e){var o=this.notification;o.textContent=t,o.className="notification"+("warning"===e?" warning":""),o.style.display="block";setTimeout(function(){o.style.display="none"},2500)},l.prototype.setInitialPosition=function(){var t=this.btn;t.style.top="auto",t.style.bottom="30px",t.style.right="30px",t.style.left="auto"},l.prototype.bindEvents=function(){var o=this;this.btn.onclick=function(){o.overlay.classList.add("active"),o.renderContent()};var n=0,i=0,s=0,a=0;function l(e){e=e||t.event,n=s-e.clientX,i=a-e.clientY,s=e.clientX,a=e.clientY;var l=o.btn,r=l.offsetTop-i,c=l.offsetLeft-n,d=t.innerHeight-l.offsetHeight,p=t.innerWidth-l.offsetWidth;l.style.top=Math.max(0,Math.min(d,r))+"px",l.style.left=Math.max(0,Math.min(p,c))+"px"}function r(){e.onmouseup=null,e.onmousemove=null}this.btn.onmousedown=function(o){o=o||t.event,s=o.clientX,a=o.clientY,e.onmouseup=r,e.onmousemove=l}},l.prototype.captureConsole=function(){var e=this;function n(n){return function(){var i=Array.prototype.slice.call(arguments),s=i.length&&"string"==typeof i[0]&&0===i[0].indexOf("[system]"),a=i.map(function(t){return"object"==typeof t?function(){try{return JSON.stringify(t)}catch(t){return"{object}"}}():String(t)}).join(" "),l=n+"|"+a;if(e.lastLog&&e.lastLog.type===n&&e.lastLog.sign===l)e.lastLog.count++,e.lastLog.timestamp=new Date;else{var r={id:e.logs.length,type:n,args:i,content:a,timestamp:new Date,count:1,sign:l,isSystem:s};if(e.logs.push(r),e.lastLog=r,s){var c=o({},r,{id:e.systemLogs.length});e.systemLogs.push(c)}}e.originalConsole[n].apply(t.console,i),e.overlay&&e.overlay.classList.contains("active")&&e.renderContent()}}this.originalConsole={log:t.console.log,info:t.console.info,warn:t.console.warn,error:t.console.error},t.console.log=n("log"),t.console.info=n("info"),t.console.warn=n("warn"),t.console.error=n("error")},l.prototype.renderContent=function(){var t=this.currentTab;this.consoleOutput.style.display="console"===t?"block":"none",this.localstorageView.style.display="localstorage"===t?"block":"none",this.systemLogsEl.style.display="system"===t?"block":"none","console"===t&&this.renderLogs(),"system"===t&&this.renderSystemLogs(),"localstorage"===t&&this.renderLocalStorage()},l.prototype.renderLogs=function(){var t=this.consoleOutput,e=this.logs.filter(function(t){return!t.isSystem});if("all"!==this.activeFilter&&(e=e.filter(function(t){return t.type===this.activeFilter},this)),this.searchQuery&&(e=e.filter(function(t){return t.content.toLowerCase().indexOf(this.searchQuery)>-1},this)),e.length){for(var o="",i=e.length-1;i>=0;i--){var l=e[i];o+='<div class="log-item '+l.type+'"><div class="log-icon">'+a(l.type)+'</div><div class="log-content">'+n(l.content)+' <div class="log-actions"> <span class="log-action" onclick="thinConsole.instances[\''+this.options.id+"'].copyLog("+l.id+',false)">Copy</span> </div></div><div class="timestamp">'+s(l.timestamp)+"</div></div>"}t.innerHTML=o}else t.innerHTML='<div class="nolog">No logs</div>'},l.prototype.renderSystemLogs=function(){var t=this.systemLogsEl,e=this.systemLogs;if("all"!==this.activeFilter&&(e=e.filter(function(t){return t.type===this.activeFilter},this)),this.searchQuery&&(e=e.filter(function(t){return t.content.toLowerCase().indexOf(this.searchQuery)>-1},this)),e.length){for(var o="",i=e.length-1;i>=0;i--){var l=e[i];o+='<div class="log-item '+l.type+'"><div class="log-icon">'+a(l.type)+'</div><div class="log-content">'+n(l.content)+' <div class="log-actions"> <span class="log-action" onclick="thinConsole.instances[\''+this.options.id+"'].copyLog("+l.id+',true)">Copy</span> </div></div><div class="timestamp">'+s(l.timestamp)+"</div></div>"}t.innerHTML=o}else t.innerHTML='<div class="nolog">No system logs</div>'},l.prototype.copyLog=function(t,e){for(var o=e?this.systemLogs:this.logs,n=null,s=0;s<o.length;s++)if(o[s].id===t){n=o[s];break}n&&(i((n.count>1?"["+n.count+" repeats] ":"")+n.content),this.showNotification("Copied to clipboard"))},l.prototype.clearAllLogs=function(){confirm("Clear all logs? This cannot be undone.")&&(this.logs=[],this.systemLogs=[],this.lastLog=null,this.renderContent(),this.showNotification("Logs cleared","warning"))},l.prototype.renderLocalStorage=function(){var e=this.lsItems;if(e.innerHTML="",t.localStorage.length){for(var o=[],n=0;n<t.localStorage.length;n++)o.push(t.localStorage.key(n));o.sort();for(var i=0;i<o.length;i++)this.addLSItemToDOM(o[i],t.localStorage.getItem(o[i]))}else e.innerHTML='<div class="nolog">LocalStorage is empty</div>'},l.prototype.addLSItemToDOM=function(t,o){var i=e.createElement("div");i.className="ls-item",i.dataset.key=t;var s=!1,a=o;try{var l=JSON.parse(o);l&&"object"==typeof l&&(s=!0,a=JSON.stringify(l,null,2))}catch(t){}i.innerHTML='<div class="ls-key-row"> <div class="ls-key">'+n(t)+'</div> <div class="ls-actions"> <button class="ls-action-btn" onclick="thinConsole.instances[\''+this.options.id+"'].editLSItem('"+n(t)+'\')">Edit</button> <button class="ls-action-btn" onclick="thinConsole.instances[\''+this.options.id+"'].copyLSValue('"+n(t)+'\')">Copy</button> <button class="ls-action-btn" onclick="thinConsole.instances[\''+this.options.id+"'].removeLSItem('"+n(t)+'\')">Delete</button> </div></div><div class="ls-value">'+n(a)+'</div><div class="ls-value-type">Type: '+(s?"JSON":"string")+'</div><div class="ls-edit" style="display:none"> <textarea class="ls-edit-input" style="width:100%;height:60px;">'+n(o)+'</textarea> <div class="ls-edit-actions"> <button class="ls-action-btn" onclick="thinConsole.instances[\''+this.options.id+"'].cancelEditLSItem('"+n(t)+'\')">Cancel</button> <button class="ls-action-btn" onclick="thinConsole.instances[\''+this.options.id+"'].saveLSItem('"+n(t)+"')\">Save</button> </div></div>",this.lsItems.appendChild(i)},l.prototype.addLSItem=function(){var e=prompt("Enter key name:");if(e)if(null==t.localStorage.getItem(e)){var o=prompt("Enter value:");null!=o&&(t.localStorage.setItem(e,o),this.addLSItemToDOM(e,o),this.showNotification("Item added"))}else alert("Key already exists!")},l.prototype.editLSItem=function(t){var e=this.lsItems.querySelector('[data-key="'+t+'"]');e&&(e.querySelector(".ls-value").style.display="none",e.querySelector(".ls-edit").style.display="block")},l.prototype.saveLSItem=function(e){var o=this.lsItems.querySelector('[data-key="'+e+'"]');if(o){var n=o.querySelector(".ls-edit-input").value;t.localStorage.setItem(e,n),this.addLSItemToDOM(e,n),o.parentNode.replaceChild(this.lsItems.querySelector('[data-key="'+e+'"]'),o),this.showNotification("Item saved")}},l.prototype.cancelEditLSItem=function(t){var e=this.lsItems.querySelector('[data-key="'+t+'"]');e&&(e.querySelector(".ls-value").style.display="block",e.querySelector(".ls-edit").style.display="none")},l.prototype.removeLSItem=function(e){if(confirm('Delete key "'+e+'"?')){t.localStorage.removeItem(e);var o=this.lsItems.querySelector('[data-key="'+e+'"]');o&&o.parentNode.removeChild(o),this.showNotification("Item deleted","warning")}},l.prototype.copyLSValue=function(e){var o=t.localStorage.getItem(e);null!=o&&(i(o),this.showNotification("Value copied"))},l.prototype.setupGlobalEventHandlers=function(){var e=this;t.addEventListener("error",function(t){""===t.filename&&0===t.lineno&&0===t.colno||(e.error("[system] Script error",{Message:t.message||"No message",File:t.filename||"Unknown",Line:t.lineno,Column:t.colno}),t.preventDefault())}),t.addEventListener("unhandledrejection",function(t){e.error("[system] Unhandled promise",t.reason),t.preventDefault()})},t.thinConsole=l,t.thinConsole.instances=t.thinConsole.instances||{}}(window,document)
@@ -0,0 +1 @@
1
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):e.thinConsole=t()}("undefined"!=typeof self?self:this,function(){class e{constructor(t={}){if(e.tC)return console.warn("[thinConsole] thinConsoleinstance already exists"),e.tC;switch(t=this.sanitizeOptions(t),e.tC=this,this.version="1.2.0",this.options={text:"thinConsole",color:"#007aff",width:"auto",height:"auto",theme:"auto",plugins:!0,disabledPlugins:[],jsExecute:!0,maxLog:1e3,...t},this.options.theme){case"light":this.currentTheme="light";break;case"dark":this.currentTheme="dark";break;default:let e=()=>window.matchMedia("(prefers-color-scheme:dark)").matches?"dark":"light";this.currentTheme=e(),this.mediaQuery=window.matchMedia("(prefers-color-scheme:dark)"),this.themeChangeHandler=e=>{this.currentTheme=e.matches?"dark":"light",this.overlay&&this.overlay.classList.contains("tc-active")&&(this.overlay.className="tc-overlay tc-active tc-theme-"+this.currentTheme)},this.mediaQuery.addEventListener("change",this.themeChangeHandler)}this.currentTab="console",this.searchExpanded=!1,this.activeLSFilter="local",this.selectedElement=null,this.selectedShadowHostId=null,this.expandedElements=new WeakSet,this.mutedLogs=!1,this.mutedFilters={},this.netSending=!1,this.netNewVisible=!1,this.editorState={visible:!1,mode:"ls",key:"",oldKey:"",value:""},void 0===t.pos?.x&&void 0===t.pos?.y&&(this.options.pos=this.getSavedBtnPos()||{x:30,y:30}),this.pluginEnabled=this.options.plugins,this.disabledPlugins=this.options.disabledPlugins,this.plugins={},this.pluginTabs={},this.pluginViewContainers={},this.logs=[],this.lastLog=null,this.maxLog=this.options.maxLog,this.selectedLogId=null,this.customTabCount=0,this.jsonPageSize=200,this.jsonPageCache=new Map,this.jsonPageIndex=new Map,this.treeNodeRegistry=new Map,this.treeNodeRegId=0,this.expandedTreePaths=new Set,this.timerMap=new Map,this.countMap=new Map,this.networkRequests=[],this._netReqId=0,this.activeNetFilter="all",this.netDisabled=!1,this.netDisabledTypes=new Set,this.netDetailId=null,this.originalXHR=null,this.originalFetch=null,this.closedShadowRoots=new WeakMap,this.interceptShadowRoot(),this.createButton(),this.captureConsoleLogs(),this.createNotificationElement(),this.createOverlayElement(),this.createStyles(),this.setupGlobalEventHandlers(),this.setupSelfProtection(),this.renderContent()}interceptShadowRoot(){if(window.__tcShadowIntercepted)return;window.__tcShadowIntercepted=!0;let e=this,t=Element.prototype.attachShadow;Element.prototype.attachShadow=function(s){let i=t.call(this,s);return e.closedShadowRoots.set(this,{root:i,mode:s.mode||"open"}),i}}getShadowRoot(e){if(e.shadowRoot)return{root:e.shadowRoot,mode:"open"};return this.closedShadowRoots.get(e)||null}getSavedBtnPos(){let e=localStorage.getItem("tC-Button-pos");if(!e)return this.saveBtnPos({x:30,y:30}),null;let t=e.match(/^x:(.+?)\,y:(.+)$/);if(!t)return this.saveBtnPos({x:30,y:30}),null;let s=Number(t[1]),i=Number(t[2]);return isNaN(s)||isNaN(i)?(this.saveBtnPos({x:30,y:30}),null):{x:s,y:i}}saveBtnPos({x:e,y:t}){e=isNaN(Number(e))?30:Number(e),t=isNaN(Number(t))?30:Number(t),localStorage.setItem("tC-Button-pos",`x:${e},y:${t}`)}sanitizeOptions(e){let t={text:"thinConsole",color:"#007aff",width:"auto",height:"auto",theme:"auto",plugins:!0,disabledPlugins:[],jsExecute:!0,pos:null,maxLog:1e3,filters:null};if(!e||"object"!=typeof e)return{...t};let s={...t},i=(e,t=200)=>"string"==typeof e&&e.length<=t&&!/[<>"&]/.test(e)?e:void 0;for(let n of Object.keys(e)){if(!(n in t))continue;let o=e[n];switch(n){case"text":case"color":case"width":case"height":case"theme":{let e=i(o);void 0!==e&&(s[n]=e);break}case"plugins":case"jsExecute":"boolean"==typeof o&&(s[n]=o);break;case"disabledPlugins":Array.isArray(o)&&o.every(e=>"string"==typeof e)&&(s[n]=o.slice(0,100));break;case"pos":o&&"object"==typeof o&&"number"==typeof o.x&&"number"==typeof o.y&&(s.pos={x:o.x,y:o.y});break;case"maxLog":{let t=Number(e[n]);!isNaN(t)&&t>0&&(s[n]=Math.floor(t));break}case"filters":Array.isArray(o)&&o.every(e=>e&&"string"==typeof e.id&&"string"==typeof e.name)&&(s[n]=o)}}return s}createButton(){this.btn=document.createElement("button"),this.btn.id="tc-thinConsole-btn",this.btn.className="tc-floating-console-btn",this.btn.textContent=this.options.text.slice(0,11),this.btn.style.background=this.options.color,this.btn.style.width=this.options.width,this.btn.style.height=this.options.height,this.btn.style.bottom=(Number(this.options.pos.y)||30)+"px",this.btn.style.right=(Number(this.options.pos.x)||30)+"px",this.btn.title=this.options.text.slice(0,11),document.documentElement.append(this.btn);let e=!1,t=0,s=0,i=0,n=0,o=0,a=0,r=null,l=null,c=0,d=0,h=()=>{r&&(clearTimeout(r),r=null)},p=()=>{if(!e)return;let t=c-i,s=d-n;this.btn.style.transition="none",this.btn.style.transform=`translate3d(${t}px,${s}px,0)`,l=requestAnimationFrame(p)},u=r=>{if(!e)return;let l=r.touches?r.touches[0]:r,h=l.clientX-t,p=l.clientY-s;c=Math.max(o/2,Math.min(innerWidth-o/2,i+h)),d=Math.max(a/2,Math.min(innerHeight-a/2,n+p)),r.preventDefault()},f=()=>{if(h(),!e)return;e=!1,cancelAnimationFrame(l);let t=this.btn.getBoundingClientRect(),s=Math.round(innerWidth-t.right),i=Math.round(innerHeight-t.bottom);this.btn.style.right=Math.max(0,s)+"px",this.btn.style.bottom=Math.max(0,i)+"px",this.saveBtnPos({x:Math.max(0,s),y:Math.max(0,i)}),this.btn.style.transition="all 0.3s ease",this.btn.style.transform="",this.btn.dataset.right=Math.max(0,s),this.btn.dataset.bottom=Math.max(0,i),this.btn.removeEventListener("touchmove",u,{passive:!1}),this.btn.removeEventListener("touchend",f),this.btn.removeEventListener("mousemove",u),this.btn.removeEventListener("mouseup",f)},g=l=>{let h=l.touches?l.touches[0]:l;t=h.clientX,s=h.clientY;let g=this.btn.getBoundingClientRect();o=g.width,a=g.height,i=g.left+o/2,n=g.top+a/2,r=setTimeout(()=>{e=!0,c=i,d=n,p(),this.btn.addEventListener("touchmove",u,{passive:!1}),this.btn.addEventListener("touchend",f),this.btn.addEventListener("mousemove",u),this.btn.addEventListener("mouseup",f)},500)};this.btn.addEventListener("touchstart",g,{passive:!1}),this.btn.addEventListener("mousedown",g),this.btn.addEventListener("touchend",h),this.btn.addEventListener("mouseup",h),this.btn.addEventListener("mouseleave",h),this.btn.addEventListener("click",()=>{this.triggerGlobalHook("beforeOpen"),this.overlay.className="tc-overlay tc-active tc-theme-"+this.currentTheme,this.renderContent(),this.triggerGlobalHook("afterOpen")})}createOverlayElement(){this.overlay=document.createElement("div"),this.overlay.id="tc-consoleOverlay",this.overlay.className="tc-overlay";let e=`<div class="tc-splitter" id="tc-splitter"></div><div class="tc-console-container"><div class="tc-console-header" id="tc-consoleHeader"><div class="tc-console-title" id="tc-consoleTitle"><i class="fa fa-terminal"></i>${this.options.text.slice(0,11)}</div><div class="tc-header-actions"><button class="tc-header-icon-btn tc-el-header-btn" id="tc-elementPickBtn" title="Pick element" style="display:none"><i class="fa fa-mouse-pointer"></i></button><button class="tc-header-icon-btn tc-el-header-btn" id="tc-elCopyBtn" title="Copy element" style="display:none"><i class="fa fa-copy"></i></button><button class="tc-header-icon-btn tc-el-header-btn tc-el-delete-btn" id="tc-elDeleteBtn" title="Delete element" style="display:none"><i class="fa fa-trash-alt"></i></button><button class="tc-header-icon-btn" id="tc-logCopyBtn" title="Copy selected log" style="display:none"><i class="fa fa-copy"></i></button><button class="tc-header-icon-btn tc-ls-add-btn" id="tc-lsAddBtn" title="New" style="display:none"><i class="fa fa-plus"></i></button><button class="tc-header-icon-btn" id="tc-netNewBtn" title="New Request" style="display:none"><i class="fa fa-plus"></i></button><button class="tc-header-icon-btn" id="tc-searchToggleBtn" title="Search"><i class="fa fa-search"></i></button><button class="tc-clear-all-btn" title="Clear" id="tc-clearLogsBtn"><i class="fa fa-trash-alt"></i></button><button class="tc-close-btn" title="Close" id="tc-closeConsoleBtn"><i class="fa fa-times"></i></button></div></div><div class="tc-search-bar" id="tc-searchBar" style="display:none"><div class="tc-search-input-wrap"><i class="fa fa-search tc-search-bar-icon"></i><input type="text" id="tc-searchInput" placeholder="Search..."></div></div><div class="tc-tabs" id="tc-tabsContainer"></div><div class="tc-console-content" id="tc-contentArea"><div class="tc-controls" id="tc-consoleControls"><div class="tc-filters" id="tc-filtersContainer"></div><div class="tc-filters tc-ls-filters" id="tc-lsFiltersContainer" style="display:none"><button class="tc-filter-btn tc-active" title="Local Storage" data-ls-type="local" data-orig="Local Storage"><i class="fa fa-database"></i>Local Storage</button><button class="tc-filter-btn" title="Session Storage" data-ls-type="session" data-orig="Session Storage"><i class="fa fa-window-restore"></i>Session Storage</button><button class="tc-filter-btn" title="Cookies" data-ls-type="cookie" data-orig="Cookies"><i class="fa fa-cookie-bite"></i>Cookies</button></div><button class="tc-mute-btn" id="tc-muteBtn" title="Mute subsequent logs"><i class="fa fa-ban"></i></button></div><div class="tc-console-output" id="tc-consoleOutput"></div><div class="tc-localstorage-view" id="tc-localstorageView" style="display:none"><div class="tc-ls-items" id="tc-lsItems"></div></div><div class="tc-elements-view" id="tc-elementsView" style="display:none"><div class="tc-elements-tree" id="tc-elementsTree"></div></div><div class="tc-network-view" id="tc-networkView" style="display:none"><div class="tc-network-controls"><div class="tc-network-filters" id="tc-netFilters"></div><button class="tc-net-disable-btn" id="tc-netDisableBtn" title="Disable"><i class="fa fa-ban"></i></button></div><div class="tc-network-items" id="tc-networkItems"></div><div class="tc-net-detail-overlay" id="tc-netDetailOverlay"><div class="tc-net-detail-header"><button class="tc-net-back-btn" id="tc-netBackBtn" title="Back"><i class="fa fa-arrow-left"></i></button><div class="tc-net-detail-header-actions"><button class="tc-net-resend-icon-btn" id="tc-netResendIconBtn" title="Resend"><i class="fa fa-redo"></i></button></div></div><div class="tc-net-detail-body" id="tc-netDetailBody"></div></div><div class="tc-net-new-overlay" id="tc-netNewOverlay"><div class="tc-net-new-header"><button class="tc-net-back-btn" id="tc-netNewBackBtn"><i class="fa fa-arrow-left"></i></button><div class="tc-net-new-title">New Request</div></div><div class="tc-net-new-body"><div class="tc-net-form-group"><label class="tc-net-form-label">URL</label><input type="text" class="tc-net-form-input" id="tc-netNewUrl" placeholder="https://..." spellcheck="false"></div><div class="tc-net-form-group"><label class="tc-net-form-label">Method</label><select class="tc-net-form-select" id="tc-netNewMethod"><option value="GET">GET</option><option value="POST">POST</option><option value="PUT">PUT</option><option value="PATCH">PATCH</option><option value="DELETE">DELETE</option><option value="HEAD">HEAD</option><option value="OPTIONS">OPTIONS</option></select></div><div class="tc-net-form-group"><label class="tc-net-form-label">Body (optional)</label><textarea class="tc-net-form-textarea" id="tc-netNewBody" placeholder='{"key":"value"}' spellcheck="false"></textarea></div><div class="tc-net-form-group"><label class="tc-net-form-label">Headers (optional, one per line)</label><textarea class="tc-net-form-textarea" id="tc-netNewHeaders" placeholder="Content-Type: application/json" spellcheck="false"></textarea></div><button class="tc-net-send-btn" id="tc-netSendBtn"><i class="fa fa-paper-plane"></i> Send Request</button></div></div></div><div class="tc-ls-editor-overlay" id="tc-lsEditorOverlay" style="display:none"><div class="tc-ls-editor-header"><div class="tc-ls-editor-header-row"><input type="text" class="tc-ls-editor-key-input" id="tc-lsEditorKeyInput" placeholder="Key name..." spellcheck="false"><span class="tc-ls-editor-title" id="tc-lsEditorTitle"></span></div></div><div class="tc-ls-editor-body"><textarea id="tc-lsEditorInput" placeholder="Enter value..." spellcheck="false"></textarea></div><div class="tc-ls-editor-footer"><button class="tc-ls-editor-btn tc-cancel" id="tc-lsEditorCancel">Cancel</button><button class="tc-ls-editor-btn tc-save" id="tc-lsEditorSave">Save</button></div></div></div></div>`;this.overlay.innerHTML=e,document.querySelector("html").appendChild(this.overlay),this.tabButtonsContainer=this.overlay.querySelector("#tc-tabsContainer"),this.createBuiltinTabs(),this.closeConsoleBtn=this.overlay.querySelector("#tc-closeConsoleBtn"),this.consoleOutput=this.overlay.querySelector("#tc-consoleOutput"),this.title=this.overlay.querySelector("#tc-consoleTitle"),this.localstorageView=this.overlay.querySelector("#tc-localstorageView"),this.lsItems=this.overlay.querySelector("#tc-lsItems"),this.contentArea=this.overlay.querySelector("#tc-contentArea"),this.consoleContainer=this.overlay.querySelector(".tc-console-container"),this.renderFilters(),this.filterButtons=this.overlay.querySelectorAll("#tc-filtersContainer .tc-filter-btn"),this.searchInput=this.overlay.querySelector("#tc-searchInput"),this.clearLogsBtn=this.overlay.querySelector("#tc-clearLogsBtn"),this.tabButtons=this.overlay.querySelectorAll(".tc-tab-btn"),this.consoleControls=this.overlay.querySelector("#tc-consoleControls"),this.searchToggleBtn=this.overlay.querySelector("#tc-searchToggleBtn"),this.searchBar=this.overlay.querySelector("#tc-searchBar"),this.consoleHeader=this.overlay.querySelector("#tc-consoleHeader"),this.lsEditorOverlay=this.overlay.querySelector("#tc-lsEditorOverlay"),this.lsEditorTitle=this.overlay.querySelector("#tc-lsEditorTitle"),this.lsEditorKeyInput=this.overlay.querySelector("#tc-lsEditorKeyInput"),this.lsEditorInput=this.overlay.querySelector("#tc-lsEditorInput"),this.lsEditorCancel=this.overlay.querySelector("#tc-lsEditorCancel"),this.lsEditorSave=this.overlay.querySelector("#tc-lsEditorSave"),this.muteBtn=this.overlay.querySelector("#tc-muteBtn"),this.lsFiltersContainer=this.overlay.querySelector("#tc-lsFiltersContainer"),this.lsAddBtn=this.overlay.querySelector("#tc-lsAddBtn"),this.logCopyBtn=this.overlay.querySelector("#tc-logCopyBtn"),this.elementsView=this.overlay.querySelector("#tc-elementsView"),this.elementsTree=this.overlay.querySelector("#tc-elementsTree"),this.networkView=this.overlay.querySelector("#tc-networkView"),this.networkItems=this.overlay.querySelector("#tc-networkItems"),this.netFiltersEl=this.overlay.querySelector("#tc-netFilters"),this.netDisableBtn=this.overlay.querySelector("#tc-netDisableBtn"),this.netDetailOverlay=this.overlay.querySelector("#tc-netDetailOverlay"),this.netDetailBody=this.overlay.querySelector("#tc-netDetailBody"),this.netNewOverlay=this.overlay.querySelector("#tc-netNewOverlay"),this.netNewUrl=this.overlay.querySelector("#tc-netNewUrl"),this.netNewMethod=this.overlay.querySelector("#tc-netNewMethod"),this.netNewBody=this.overlay.querySelector("#tc-netNewBody"),this.netNewHeaders=this.overlay.querySelector("#tc-netNewHeaders"),this.netSendBtn=this.overlay.querySelector("#tc-netSendBtn"),this.netBackBtn=this.overlay.querySelector("#tc-netBackBtn"),this.netNewBackBtn=this.overlay.querySelector("#tc-netNewBackBtn"),this.netNewBtn=this.overlay.querySelector("#tc-netNewBtn"),this.elementPickBtn=this.overlay.querySelector("#tc-elementPickBtn"),this.splitter=this.overlay.querySelector("#tc-splitter"),this.splitter&&this.setupSplitter(),this.elementPickBtn.addEventListener("click",()=>this.startElementPicker()),this.elCopyBtn=this.overlay.querySelector("#tc-elCopyBtn"),this.elCopyBtn.addEventListener("click",()=>{this.selectedElement?this.copyElementHTML(this.selectedElement):this.showNotification("Please select an element first","warning")}),this.elDeleteBtn=this.overlay.querySelector("#tc-elDeleteBtn"),this.elDeleteBtn.addEventListener("click",()=>{this.selectedElement?this.deleteElement(this.selectedElement):this.showNotification("Please select an element first","warning")}),this.netDisableBtn&&this.netDisableBtn.addEventListener("click",()=>this.toggleNetDisable()),this.netBackBtn&&this.netBackBtn.addEventListener("click",()=>{this.netDetailOverlay.style.display="none",this.netDetailId=null}),this.netNewBackBtn&&this.netNewBackBtn.addEventListener("click",()=>{this.netNewVisible=!1,this.netNewOverlay.style.display="none"}),this.netNewBtn&&this.netNewBtn.addEventListener("click",()=>{if(this.editorState.visible){let e=this.editorState.mode;if("code"===e)return void this.showNotification("Code is running, cannot send request","warning");if("ls"===e)return void this.showNotification("Saving key-value, cannot send request","warning")}this.netNewVisible=!0,this.netNewOverlay.style.display="flex"}),this.netSendBtn&&this.netSendBtn.addEventListener("click",()=>this.sendNewRequest()),this.networkItems&&this.networkItems.addEventListener("click",e=>{let t=e.target.closest(".tc-net-item");if(!t)return;let s=parseInt(t.dataset.reqId);if(e.target.closest("[data-action=copy]")){e.stopPropagation(),e.preventDefault();let t=this.networkRequests.find(e=>e.id===s);if(t){let e={method:t.method,url:t.url,headers:t.reqHeaders,body:t.reqBody};navigator.clipboard.writeText(JSON.stringify(e,null,2)).then(()=>this.showNotification("Request JSON copied")).catch(()=>{})}return}return e.target.closest("[data-action=detail]")?(e.stopPropagation(),e.preventDefault(),void this.showNetDetail(s)):void 0}),this.captureNetworkRequests(),this.closeConsoleBtn.addEventListener("click",()=>{this.triggerGlobalHook("beforeClose"),this.overlay.classList.remove("tc-active"),this.triggerGlobalHook("afterClose")}),[this.consoleOutput,this.lsItems].forEach(e=>this.setupVirtualScroll(e)),this.lsItems.addEventListener("click",e=>{let t=e.target.closest(".tc-ls-action-btn");if(!t)return;let s=t.dataset.action,i=t.dataset.key;switch(s){case"edit":this.openLSEditor(i);break;case"copy":this.copyLog(i,"",!0);break;case"remove":this.removeLSItem(i)}}),this.title.title="Code execution has been disabled",this.title.style.cursor="not-allowed",this.options.jsExecute&&(this.title.title="Click title to enter code for execution",this.title.style.cursor="pointer",this.title.addEventListener("click",()=>this.onTitleClick())),this.overlay.addEventListener("click",e=>{let t=e.target.closest(".tc-json-page-btn");t&&this.changeJsonPage(parseInt(t.dataset.id),parseInt(t.dataset.page,10));let s=e.target.closest(".tc-tree-load-more");s&&this.loadMoreTreeChildren(s);let i=e.target.closest(".tc-elements-tree .tc-tree-label");if(i){let e=i.closest(".tc-tree-node[data-el-id]"),t=e?parseInt(e.dataset.elId):null,s=null!==t&&this.elRefMap?this.elRefMap.get(t):null;s&&(this.selectedElement=s,this.selectedShadowHostId=e.dataset.shadowHost?parseInt(e.dataset.shadowHost):null,this.elementsTree.querySelectorAll(".tc-el-selected").forEach(e=>e.classList.remove("tc-el-selected")),this.elementsTree.querySelectorAll(".tc-el-highlight").forEach(e=>e.classList.remove("tc-el-highlight")),e.classList.add("tc-el-selected"),e.classList.add("tc-el-highlight"),setTimeout(()=>e.classList.remove("tc-el-highlight"),3e3))}else"elements"!==this.currentTab||e.target.closest(".tc-tree-label")||e.target.closest(".tc-tree-toggle")||e.target.closest(".tc-el-header-btn")||e.target.closest(".tc-close-btn")||e.target.closest(".tc-header-icon-btn")||e.target.closest(".tc-console-header")||e.target.closest(".tc-tabs")||e.target.closest(".tc-controls")||e.target.closest(".tc-search-bar")||(this.selectedElement=null,this.selectedShadowHostId=null,this.elementsTree&&(this.elementsTree.querySelectorAll(".tc-el-selected").forEach(e=>e.classList.remove("tc-el-selected")),this.elementsTree.querySelectorAll(".tc-el-highlight").forEach(e=>e.classList.remove("tc-el-highlight"))));let n=e.target.closest(".tc-tree-toggle");if(n){let e=n.closest(".tc-tree-node");if(e){let t=e.dataset.elId,s=t&&this.elRefMap?this.elRefMap.get(parseInt(t)):null;if(e.classList.contains("tc-collapsed")){e.classList.remove("tc-collapsed"),e.classList.add("tc-expanded");let t=e.dataset.treePath;t&&this.expandedTreePaths.add(t);let i=n.querySelector("i");i&&(i.classList.remove("fa-angle-right"),i.classList.add("fa-angle-down")),s&&this.expandedElements.add(s);let o=e.querySelector(":scope > .tc-tree-children");if(o&&o.dataset.lazyId){let e=parseInt(o.dataset.lazyId),t=this.treeNodeRegistry.get(e);if(t){let s="";if("html"===t.type)s=this.renderDomChildrenLazy(t.children,(e,s,i)=>this.renderHTMLTree(e,"",t.path+"."+s,i),t.depth||0,"html",{path:t.path}),t.shadow&&(s+=this.buildShadowLazy(t.shadow,"html",t.path,t.depth||0));else if("html-shadow"===t.type)s=this.renderDomChildrenLazy(t.children,(e,s,i)=>this.renderHTMLTree(e,"",t.path+".shadow."+s,i),t.depth||0,"html-shadow",{});else if("element"===t.type)s=this.renderDomChildrenLazy(t.children,(e,t,s)=>this.renderElementTree(e,s),t.depth||0,"element",{}),t.shadow&&(s+=this.buildShadowLazy(t.shadow,"element",null,t.depth||0,t.elId));else if("element-shadow"===t.type)s=this.renderDomChildrenLazy(t.children,(e,t,s)=>this.renderElementTree(e,s),t.depth||0,"element-shadow",{});else if(t.isJsonValue)s=this.renderJSONValueChildren(t.children);else{let e=new WeakSet;t.chain.forEach(t=>e.add(t)),e.add(t.obj);let i=t.children;if(i.length>200){let n=this.treeNodeRegId++;this.treeNodeRegistry.set(n,{children:i,chain:t.chain.concat([t.obj]),noProto:t.noProto}),s=this.renderTreeChildrenBatch(i,e,0,200,t.chain.concat([t.obj]),t.path||"",1,t.noProto)+'<div class="tc-tree-load-more" data-reg-id="'+n+'" data-offset="200"><i class="fa fa-angle-down"></i> Load more ('+(i.length-200)+" items left)</div>"}else s=this.renderTreeChildrenBatch(i,e,0,i.length,t.chain.concat([t.obj]),t.path||"",1,t.noProto)}o.innerHTML=s,delete o.dataset.lazyId,this.treeNodeRegistry.delete(e)}}}else{e.classList.remove("tc-expanded"),e.classList.add("tc-collapsed");let t=e.dataset.treePath;t&&this.expandedTreePaths.delete(t);let i=n.querySelector("i");i&&(i.classList.remove("fa-angle-down"),i.classList.add("fa-angle-right")),s&&this.expandedElements.delete(s)}let i=n.closest(".tc-console-output, .tc-ls-items");i&&this.vsRefreshHeights(i)}}e.target===this.overlay&&(this.triggerGlobalHook("beforeClose"),this.overlay.classList.remove("tc-active"),this.triggerGlobalHook("afterClose"))}),this.filterButtons.forEach(e=>{e.addEventListener("click",()=>{this.filterButtons.forEach(e=>e.classList.remove("tc-active")),e.classList.add("tc-active"),this.activeFilter=e.dataset.type,this.updateFilterCounts(),this.renderContent(),this.scrollFilterIntoView(this.overlay.querySelector("#tc-filtersContainer"),e)})}),this.lsFiltersContainer&&this.lsFiltersContainer.querySelectorAll(".tc-filter-btn").forEach(e=>{e.addEventListener("click",()=>{this.lsFiltersContainer.querySelectorAll(".tc-filter-btn").forEach(e=>e.classList.remove("tc-active")),e.classList.add("tc-active"),this.activeLSFilter=e.dataset.lsType,this.renderContent(),this.scrollFilterIntoView(this.lsFiltersContainer,e)})}),this.lsAddBtn&&this.lsAddBtn.addEventListener("click",()=>this.onAddLSClick()),this.logCopyBtn&&this.logCopyBtn.addEventListener("click",()=>{null!==this.selectedLogId?this.copyLog(this.selectedLogId,!1):this.showNotification("Please select a log first","warning")}),this.consoleOutput&&this.consoleOutput.addEventListener("click",e=>{let t=e.target.closest(".tc-log-item");if(!t)return this.selectedLogId=null,this.consoleOutput.querySelectorAll(".tc-log-item.tc-selected").forEach(e=>e.classList.remove("tc-selected")),void(this.logCopyBtn&&(this.logCopyBtn.style.display="none"));let s=parseInt(t.id.replace("tc-log-item-",""));this.selectedLogId=s,this.consoleOutput.querySelectorAll(".tc-log-item.tc-selected").forEach(e=>e.classList.remove("tc-selected")),t.classList.add("tc-selected"),this.logCopyBtn&&(this.logCopyBtn.style.display="flex")}),this.searchInput.addEventListener("input",(e=>t=>{clearTimeout(e),e=setTimeout(()=>{if(this.searchQuery=t.target.value,"network"===this.currentTab)return this.renderNetworkList().trim(),this.renderContent()},300)})(0)),this.clearLogsBtn.addEventListener("click",()=>this.clearAllLogs()),this.searchToggleBtn.addEventListener("click",()=>this.toggleSearch()),this.lsEditorCancel.addEventListener("click",()=>this.closeLSEditor()),this.lsEditorSave.addEventListener("click",()=>this.onEditorSave()),this.muteBtn.addEventListener("click",()=>this.toggleMute()),this.lsEditorInput.addEventListener("input",()=>{this.editorState.value=this.lsEditorInput.value}),this.lsEditorKeyInput&&this.lsEditorKeyInput.addEventListener("input",()=>{this.editorState.key=this.lsEditorKeyInput.value.trim()}),this.setupFilterShadow(this.overlay.querySelector("#tc-filtersContainer")),this.setupFilterShadow(this.lsFiltersContainer),this.setupFilterShadow(this.netFiltersEl),this.setupGestures(),this.tabButtons.forEach(e=>{e.addEventListener("click",()=>{this.tabButtons.forEach(e=>e.classList.remove("tc-active")),e.classList.add("tc-active"),this.currentTab=e.dataset.tab,this.renderContent()})})}renderFilters(){let e=this.overlay.querySelector("#tc-filtersContainer");if(!e)return;let t=this.options.filters;t&&t.length||(t=[{id:"all",name:"All",icon:"fa fa-list"},{id:"log",name:"Logs",icon:"fa fa-info"},{id:"info",name:"Info",icon:"fa fa-info-circle"},{id:"warn",name:"Warnings",icon:"fa fa-exclamation-triangle"},{id:"error",name:"Errors",icon:"fa fa-times-circle"}]),e.innerHTML=t.map((e,t)=>`<button class="tc-filter-btn${0===t?" tc-active":""}" title="${this.escapeHtml(e.name)}" data-type="${this.escapeHtml(e.id)}">${e.icon?'<i class="'+this.escapeHtml(e.icon)+'"></i>':""}${this.escapeHtml(e.name)}</button>`).join(""),e.querySelectorAll(".tc-filter-btn").forEach(t=>{t.addEventListener("click",()=>{e.querySelectorAll(".tc-filter-btn").forEach(e=>e.classList.remove("tc-active")),t.classList.add("tc-active"),this.activeFilter=t.dataset.type,this.updateFilterCounts(),this.renderContent()})})}createBuiltinTabs(){[{id:"console",name:"Console",icon:"fa fa-terminal"},{id:"network",name:"Network",icon:"fa fa-wifi"},{id:"localstorage",name:"Storage",icon:"fa fa-database"},{id:"elements",name:"Elements",icon:"fa fa-code"}].forEach(e=>{let t=document.createElement("button");t.className="tc-tab-btn",t.dataset.tab=e.id,t.title=e.name,t.innerHTML=`<i class="${e.icon}"></i>${e.name}`,"console"===e.id&&t.classList.add("tc-active"),t.addEventListener("click",()=>{this.tabButtons=this.overlay.querySelectorAll(".tc-tab-btn"),this.tabButtons.forEach(e=>e.classList.remove("tc-active")),t.classList.add("tc-active"),this.currentTab=e.id,this.renderContent()}),this.tabButtonsContainer.appendChild(t)})}createPluginTab(e){let t=document.createElement("button");t.className="tc-tab-btn",t.dataset.tab=e.id?e.id:"newTab",e.title=e.name?e.name:"New Plugin",t.innerHTML=`<i class="${e.icon?e.icon:"fa fa-plug"}"></i>${e.name?e.name:"New Plugin"}`,this.tabButtonsContainer.appendChild(t),t.addEventListener("click",()=>{this.tabButtons=this.overlay.querySelectorAll(".tc-tab-btn"),this.tabButtons.forEach(e=>e.classList.remove("tc-active")),t.classList.add("tc-active"),this.currentTab=e.id,this.renderContent()});let s=document.createElement("div");s.id=`tc-${e.id}View`,s.innerHTML="No plugin view",s.className="tc-plug-view",s.style.display="none",this.contentArea.appendChild(s),this.pluginViewContainers[e.id]=s}createNotificationElement(){this.notification=document.createElement("div"),this.notification.id="tc-notification",this.notification.className="tc-notification",this.notification.style.display="none",document.documentElement.appendChild(this.notification)}createStyles(){let e=document.createElement("style");e.innerHTML="@import url(https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css);*{margin:0;padding:0;box-sizing:border-box}.tc-floating-console-btn{position:fixed;z-index:99997;touch-action:none;will-change:transform;padding:15px 25px;backdrop-filter:blur(5px);border-radius:5px;border:none;background:#007aff;color:#fff;font-size:1rem;cursor:move;display:flex;align-items:center;gap:10px;font-weight:500;box-shadow:0 8px 20px rgba(0,0,0,.4);transition:all .3s ease;user-select:none}.tc-floating-console-btn:active{transform:scale(.98)}.tc-floating-console-btn i{font-size:1.2rem}.tc-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.85);display:flex;align-items:center;justify-content:center;z-index:99998;opacity:0;visibility:hidden;transition:all .4s ease;backdrop-filter:blur(5px)}.tc-overlay.tc-active{opacity:1;visibility:visible}.tc-theme-dark{--selected-bg:rgba(74,74,230,.15);--console-bg:#1e1e1e;--header-bg:#252526;--text-color:#d4d4d4;--controls-bg:#2d2d2d;--border-color:rgba(255,255,255,0.05);--log-bg:#191919;--log-border-light:3px solid;--filter-active:#4a4ae6;--search-bg:#3e3e42;--json-bg:rgba(40,40,40,0.7);--json-key:#6aaeff;--json-string:#98c379;--json-number:#d19a66;--json-boolean:#56b6c2;--json-null:#be5046;--json-cmt:#707070;--action-bg:rgba(106,174,255,0.3);--action-hover:rgba(106,174,255,0.5);--log-icon-info:#4a4ae6;--log-bg-warn:rgba(255,193,7,0.1);--log-icon-warn:#d9a40d;--log-icon-error:#ff3b30;--clear-btn-color:#ff6b6b;--clear-btn-hover:#ff5252;--tab-bg:#333;--tab-active:#444;--tab-color:#ddd}.tc-theme-light{--selected-bg:rgba(30,107,184,.08);--console-bg:#ffffff;--header-bg:#f0f0f0;--text-color:#333;--controls-bg:#e0e0e0;--border-color:rgba(0,0,0,0.1);--log-bg:#f3f3f3;--log-border-light:3px solid;--filter-active:#4a4ae6;--search-bg:#f0f0f0;--json-bg:rgba(240,240,240,0.9);--json-key:#1e6bb8;--json-string:#22863a;--json-number:#d73a49;--json-boolean:#005cc5;--json-null:#6f42c1;--json-cmt:#707070;--action-bg:rgba(30,107,184,0.1);--action-hover:rgba(30,107,184,0.2);--log-bg-warn:rgba(255,243,205,0.75);--log-icon-info:#1e6bb8;--log-icon-warn:#e36209;--log-icon-error:#d73a49;--clear-btn-color:#ff5252;--clear-btn-hover:#ff3b30;--tab-bg:#e5e5e5;--tab-active:#ddd;--tab-color:#333}.tc-console-container{background:var(--console-bg);display:flex;flex-direction:column;box-shadow:0 15px 35px rgba(0,0,0,.3);position:fixed;z-index:99999;left:0;bottom:0;width:100%;height:90vh;transform:translateY(100%);transition:transform .4s cubic-bezier(.25,.8,.25,1)}@media(min-width:769px){.tc-overlay{flex-direction:row;align-items:stretch;justify-content:flex-end}.tc-console-container{position:relative;left:auto;bottom:auto;width:50%;height:100%;transform:translateX(100%);flex-shrink:0}.tc-overlay.tc-active .tc-console-container{transform:translateX(0)}.tc-overlay::before{content:'';flex:1;cursor:pointer}.tc-splitter{display:block;width:4px;background:var(--border-color);cursor:col-resize;flex-shrink:0;z-index:100001;position:relative}.tc-splitter:hover,.tc-splitter.tc-dragging{background:var(--filter-active)}}@media(max-width:768px){.tc-splitter{display:none}}@media(max-width:768px){.tc-overlay{flex-direction:column;align-items:center;justify-content:center}.tc-console-container{transform:translateY(100%)!important}.tc-overlay.tc-active .tc-console-container{transform:translateY(0)!important}}.tc-console-header{display:flex;justify-content:space-between;align-items:center;padding:8px 25px;background:var(--header-bg);border-bottom:1px solid var(--border-color);position:relative}.tc-console-title{color:var(--text-color);gap:10px;display:flex;align-items:center;font-size:18px}.tc-header-actions{display:flex;align-items:center;gap:2px}.tc-header-icon-btn{background:0 0;border:none;color:var(--text-color);font-size:18px;cursor:pointer;width:40px;height:40px;display:flex;align-items:center;justify-content:center;border-radius:5px;transition:all .3s}.tc-header-icon-btn:hover{background:rgba(106,174,255,0.2);color:var(--json-key)}.tc-push-btn{border:none;background:var(--filter-active);color:#fff;padding:10px;border-radius:5px;font-size:10px}.tc-close-btn{background:0 0;border:none;color:var(--text-color);font-size:20px;cursor:pointer;width:40px;height:40px;display:flex;align-items:center;justify-content:center;border-radius:5px;transition:all .3s}.tc-close-btn:hover{background:rgba(255,100,100,.2);color:#ff6464;transform:scale(1.1)}.tc-clear-all-btn{background:0 0;border:none;color:var(--text-color);font-size:20px;cursor:pointer;width:40px;height:40px;display:flex;align-items:center;justify-content:center;border-radius:5px;transition:all .3s}.tc-clear-all-btn:hover,.tc-clear-all-btn:active{background:rgba(255,100,100,.2);color:var(--clear-btn-hover)}.tc-tabs{display:block;white-space:nowrap;overflow-x:auto;background:var(--tab-bg);padding:5px 10px 0;border-bottom:1px solid var(--border-color)}.tc-tab-btn{padding:12px 20px;background:0 0;border-radius:5px 5px 0 0;border:none;color:var(--tab-color);cursor:pointer;position:relative;display:inline-flex;align-items:center;gap:8px}.tc-tab-btn.tc-active{color:var(--text-color);font-weight:600}.tc-tab-btn.tc-active::after{content:'';position:absolute;bottom:0;left:0;width:100%;height:2px;border-radius:3px;background:var(--filter-active)}.tc-tab-btn:hover:not(.tc-active){background:rgba(255,255,255,.05)}.tc-controls{display:flex;padding:6px 15px;background:var(--controls-bg);gap:10px;flex-wrap:wrap;border-bottom:1px solid var(--border-color);align-items:center}.tc-controls-float-toggle{display:none}.tc-filters{display:flex;flex-wrap:nowrap;margin-left:-5px}.tc-filter-btn>.fa{margin-right:5px;margin-top:2px}.tc-filter-btn{position:relative;padding:5px 8px;border:none;background:0 0;color:var(--text-color);cursor:pointer;font-size:12px;display:flex;width:100%;white-space:nowrap}.tc-filter-btn.tc-active::after{content:\"\";position:absolute;width:90%;left:3px;height:2px;top:90%;border-radius:3px;background:var(--filter-active);color:#fff}.tc-search-bar{display:flex;align-items:center;gap:8px;padding:10px 20px;background:var(--controls-bg);border-bottom:1px solid var(--border-color)}.tc-search-input-wrap{display:flex;align-items:center;flex:1;position:relative}.tc-search-bar-icon{position:absolute;left:10px;color:var(--text-color);opacity:.6;font-size:14px;pointer-events:none}.tc-search-bar input{flex:1;padding:8px 10px 8px 35px;border-radius:5px;border:none;background:var(--search-bg);color:var(--text-color);transition:all .3s ease;font-size:14px;border:1px solid var(--border-color)}.tc-search-bar input:focus{outline:0;border-color:#4a4ae6}.tc-search-bar-close{background:0 0;border:none;color:var(--text-color);font-size:16px;cursor:pointer;padding:4px 8px;border-radius:5px;opacity:.6;transition:all .3s}.tc-search-bar-close:hover{opacity:1;background:rgba(255,255,255,.1)}.tc-console-content{flex:1;overflow:auto;display:flex;flex-direction:column;position:relative}.tc-console-output{flex:1;overflow-y:auto;padding:20px;font-family:monospace;font-size:.95rem}.tc-localstorage-view{flex:1;padding:20px;font-family:monospace;font-size:.95rem;position:relative;overflow:hidden}.tc-ls-items{position:absolute;inset:0;overflow-y:auto;padding:20px}.tc-log-item{padding:8px 12px;margin-bottom:6px;display:flex;flex-direction:column;border-left:3px solid #4a4ae6;background:var(--log-bg);border-radius:5px;cursor:pointer;transition:background .2s;color:var(--text-color);user-select:none;-webkit-user-select:none;-webkit-tap-highlight-color:transparent}.tc-log-item .tc-log-icon i{color:inherit}.tc-log-item.tc-selected{border-left-color:var(--json-key);background:var(--selected-bg)}.tc-log-item.tc-log{border-left-color:#4a4ae6}.tc-log-item.tc-info{border-left-color:var(--log-icon-info)}.tc-log-item.tc-warn{border-left-color:var(--log-icon-warn);background:var(--log-bg-warn)}.tc-log-item.tc-error{border-left-color:var(--log-icon-error);background:rgba(255,59,48,.15)}.tc-log-count{background:#4a4ae6;color:#fff;border-radius:4px;min-width:20px;height:20px;display:inline-flex;align-items:center;justify-content:center;font-size:11px;margin-right:4px;padding:0 5px;flex-shrink:0}.tc-log-icon{flex-shrink:0;display:flex;align-items:center;font-size:13px;margin-right:2px}.tc-log-header{display:flex;align-items:center;gap:0;margin-bottom:2px}.tc-log-content{width:100%;font-size:13px;max-height:300px;overflow-y:auto;margin-top:4px;word-break:break-word;line-height:1.5;user-select:text;-webkit-user-select:text}.tc-timestamp{color:var(--json-cmt);font-size:11px;margin-left:4px;white-space:nowrap}.tc-json-preview{font-family:monospace;padding:10px;margin-top:5px;background:var(--json-bg);border-radius:5px;white-space:pre!important;max-height:400px;overflow:auto}.tc-json-tree-container{font-family:monospace;padding:2px 0;margin-top:2px;background:0 0;border-radius:0;max-height:300px;overflow:auto;font-size:12px;line-height:1.6}.tc-tree-node{position:relative}.tc-tree-node.tc-collapsed>.tc-tree-children{display:none}.tc-tree-toggle{display:inline-block;width:16px;cursor:pointer;color:var(--json-cmt);text-align:center}.tc-tree-spacer{display:inline-block;width:16px}.tc-tree-leaf{white-space:nowrap}.tc-tree-label{color:var(--json-cmt)}.tc-tree-children{margin-left:16px;padding-left:4px}.tc-tree-brace{color:var(--json-cmt)}.tc-tree-ellipsis{color:var(--json-cmt)}.tc-tree-load-more{color:var(--json-cmt);cursor:pointer;padding:4px 0;user-select:none;font-size:11px}.tc-tree-node.tc-collapsed>.tc-tree-open{display:none}.tc-tree-node.tc-collapsed>.tc-tree-close{display:none}.tc-tree-node.tc-expanded>.tc-tree-close{display:block;padding-left:16px}.tc-tree-node.tc-expanded>.tc-tree-collapsed{display:none}.tc-tree-node.tc-collapsed>.tc-tree-ellipsis{display:inline}.tc-tree-node.tc-expanded>.tc-tree-ellipsis{display:none}.tc-tree-node.tc-collapsed>.tc-tree-close-tag{display:inline}.tc-tree-node.tc-expanded>.tc-tree-close-tag{display:inline}.tc-json-page-btn,.tc-ls-json-page-btn{border:none}.tc-json-number{color:var(--json-number)}.tc-json-boolean{color:var(--json-boolean)}.tc-json-key{color:var(--json-key)}.tc-json-null{color:var(--json-null)}.tc-json-string{color:var(--json-string)}.tc-json-cmt{color:var(--json-cmt)}.tc-log-actions{margin-top:8px;display:flex;gap:10px;font-size:10px}.tc-log-action{color:var(--json-key);cursor:pointer;padding:5px 10px;background:var(--action-bg);transition:all .2s;display:inline-flex;align-items:center;gap:5px;border-radius:5px}.tc-log-action:hover{background:var(--action-hover)}.tc-log-action.tc-copy-btn{background:var(--action-bg)}.tc-log-action.tc-copy-btn:hover{background:var(--action-hover)}.tc-error-stack{font-family:monospace;padding:10px;margin-top:10px;background:rgba(255,59,48,.2);border-radius:5px;white-space:nowrap;font-size:.85rem;overflow:auto;max-height:400px}.tc-object-preview{font-family:monospace;padding:10px;margin-top:5px;background:var(--json-bg);color:var(--json-number);border-radius:5px;white-space:pre;max-height:600px;overflow:auto}.tc-function-preview{font-family:monospace;padding:10px;margin-top:5px;background:var(--json-bg);color:var(--json-boolean);border-radius:5px;white-space:pre;word-break:break-all;overflow-x:auto}.tc-ls-header{padding:15px 0;display:flex;justify-content:flex-end}.tc-ls-item{background:var(--log-bg);padding:15px;margin-bottom:15px;border-radius:8px}.tc-ls-key-row{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;border-bottom:1px solid var(--border-color);padding-bottom:10px}.tc-ls-key{color:var(--json-key);font-size:16px;max-width:60%;overflow-x:auto;white-space:nowrap}.tc-ls-actions{display:flex;gap:8px}.tc-ls-action-btn{background:var(--action-bg);border:none;color:var(--text-color);padding:5px 10px;border-radius:5px;cursor:pointer;transition:all .2s;display:flex;align-items:center;gap:5px}.tc-ls-action-btn:hover{background:var(--action-hover)}.tc-ls-value{white-space:normal;word-break:break-all;padding:10px;background:var(--json-bg);border-radius:5px;font-family:monospace;max-height:200px;overflow-y:auto;color:var(--text-color);font-size:13px}.tc-ls-edit{display:flex;flex-direction:column;gap:10px;margin-top:10px;display:none}.tc-ls-edit textarea{width:100%;min-height:100px;padding:10px;background:var(--search-bg);border:1px solid var(--border-color);border-radius:5px;color:var(--text-color);font-family:monospace;resize:vertical;outline:0;transition:all .3s ease;font-size:10px}.tc-ls-edit textarea:focus{border-color:#4a4ae6}.tc-ls-key-edit{display:none;width:60%;padding:6px 10px;border:1px solid var(--border-color);border-radius:5px;background:var(--search-bg);font-size:16px;outline:0;transition:border .2s;color:var(--json-key);font-family:monospace}.tc-ls-key-edit:focus{border-color:#4a4ae6}.tc-ls-item.tc-editing .tc-ls-key{display:none}.tc-ls-item.tc-editing .tc-ls-key-edit{display:block}.tc-ls-edit-actions{display:flex;gap:10px;justify-content:flex-end}.tc-ls-value-type{font-size:8px;opacity:.7;margin-top:5px;color:var(--text-color)}.tc-vs-spacer{width:100%;flex-shrink:0}.tc-ls-editor-overlay{position:absolute;inset:0;z-index:100;display:flex;flex-direction:column;background:var(--console-bg)}.tc-ls-editor-header{padding:12px 20px;background:var(--header-bg);border-bottom:1px solid var(--border-color)}.tc-ls-editor-header-row{display:flex;align-items:center;gap:10px}.tc-ls-editor-key-input{flex:1;padding:8px 12px;border:1px solid var(--border-color);border-radius:6px;background:var(--search-bg);color:var(--json-key);font-size:14px;font-family:monospace;outline:0;transition:border .2s}.tc-ls-editor-key-input:focus{border-color:var(--filter-active)}.tc-ls-editor-title{color:var(--text-color);font-size:15px;font-weight:600;white-space:nowrap}.tc-ls-editor-body{flex:1;padding:15px 20px;overflow:hidden;display:flex}.tc-ls-editor-body textarea{flex:1;width:100%;padding:12px;background:var(--search-bg);border:1px solid var(--border-color);border-radius:8px;color:var(--text-color);font-family:monospace;font-size:14px;resize:none;outline:0;transition:border .2s;line-height:1.5}.tc-ls-editor-body textarea:focus{border-color:var(--filter-active)}.tc-ls-editor-footer{display:flex;gap:10px;justify-content:flex-end;padding:12px 20px;background:var(--header-bg);border-top:1px solid var(--border-color)}.tc-ls-editor-btn{padding:8px 24px;border:none;border-radius:6px;font-size:14px;cursor:pointer;transition:all .2s;font-weight:500}.tc-ls-editor-btn.tc-cancel{background:var(--controls-bg);color:var(--text-color)}.tc-ls-editor-btn.tc-cancel:hover{background:var(--action-hover)}.tc-ls-editor-btn.tc-save{background:var(--filter-active);color:#fff}.tc-ls-editor-btn.tc-save:hover{opacity:.85}.tc-ls-editor-btn.tc-run{background:var(--filter-active);color:#fff}.tc-ls-editor-btn.tc-run:hover{opacity:.85}.tc-console-table-wrap{overflow-x:auto;margin-top:5px;-webkit-overflow-scrolling:touch;border-radius:8px;border:1px solid rgba(128,128,128,0.25)}.tc-console-table{border-collapse:separate;border-spacing:0;width:100%;font-size:12px;font-family:monospace;overflow:hidden}.tc-console-table th{background:var(--controls-bg);color:var(--json-key);padding:6px 10px;text-align:left;border-bottom:1px solid rgba(128,128,128,0.25);border-right:1px solid rgba(128,128,128,0.25);white-space:nowrap;position:sticky;top:0}.tc-console-table td{padding:5px 10px;border-bottom:1px solid rgba(128,128,128,0.25);border-right:1px solid rgba(128,128,128,0.25);color:var(--text-color);white-space:nowrap;max-width:200px;overflow:hidden;text-overflow:ellipsis}.tc-console-table tbody tr:nth-child(even){background:var(--log-bg)}.tc-console-table tbody tr:hover{background:var(--action-bg)}.tc-console-table th:last-child,.tc-console-table td:last-child{border-right:none}.tc-console-table tbody tr:last-child td{border-bottom:none}.tc-ls-add-btn{font-size:18px!important;opacity:1!important;width:40px!important;height:40px!important;padding:0!important;margin-left:0!important}.tc-mute-btn{background:0 0;border:none;color:var(--text-color);font-size:14px;cursor:pointer;padding:5px 8px;border-radius:5px;opacity:.6;transition:opacity .2s;margin-left:auto;flex-shrink:0}.tc-mute-btn:hover{opacity:1}.tc-mute-btn.tc-muted{opacity:1;filter:saturate(2)}.tc-elements-view{flex:1;overflow-y:auto;padding:10px;font-family:monospace;font-size:12px;line-height:1.6}.tc-elements-tree .tc-tree-node{white-space:normal;word-break:break-all}.tc-el-header-btn{width:40px!important;height:40px!important;font-size:18px!important}.tc-el-header-btn.tc-el-delete-btn:hover{color:var(--clear-btn-color);background:rgba(255,100,100,.15)}.tc-tree-node.tc-el-highlight>.tc-tree-label{display:inline-block!important;background:var(--action-hover)!important;border-radius:3px;padding:1px 4px}.tc-tree-node.tc-el-selected>.tc-tree-label{display:inline-block!important;background:rgba(106,174,255,0.4);border-radius:3px;padding:1px 4px}.tc-el-toolbar-actions{margin-left:auto;display:flex;gap:4px}.tc-el-toolbar-btn{background:0 0;border:none;color:var(--text-color);cursor:pointer;padding:6px 10px;border-radius:5px;font-size:14px;opacity:.7;transition:all .2s}.tc-el-toolbar-btn:hover{opacity:1;background:var(--action-bg)}.tc-el-toolbar-btn.tc-el-delete-btn:hover{color:var(--clear-btn-color);background:rgba(255,100,100,.15)}.tc-element-picker-overlay{position:fixed;top:0;left:0;width:100%;height:100%;z-index:100000;cursor:crosshair;background:transparent;pointer-events:none}@media(max-width:768px){.tc-controls{flex-direction:row;align-items:center;padding:5px 10px;overflow-x:auto;flex-wrap:nowrap}.tc-log-item{flex-wrap:nowrap}.tc-log-actions{flex-wrap:wrap}.tc-floating-console-btn{padding:12px 20px;font-size:.9rem;right:20px;bottom:20px}.tc-tab-btn{padding:8px 12px;font-size:14px}.tc-nolog{text-align:center;font-size:20px;color:var(--text-color);padding:40px 0}.tc-nolog>.fa{margin-right:5px}.tc-notification{position:fixed;top:20px;right:20px;padding:12px 20px;background:rgba(76,175,80,.6);backdrop-filter:blur(12px);color:#fff;border-radius:5px;box-shadow:0 2px 10px rgba(0,0,0,.2);z-index:99999;display:none;transform:translateX(150%);max-height:48px;max-width:calc(100vw - 40px);transition:transform .3s ease;font-size:15px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.tc-notification.tc-show{transform:translateX(0)}.tc-notification.tc-warning{background:rgba(255,152,0,.6);backdrop-filter:blur(12px)}.tc-network-view{display:none;flex:1;overflow:hidden;flex-direction:column}.tc-network-controls{display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--controls-bg);border-bottom:1px solid var(--border-color)}.tc-network-filters{display:flex;gap:2px;flex:1;overflow-x:auto;overflow-y:visible;scrollbar-width:thin;padding-bottom:2px}.tc-net-filter-btn{padding:4px 10px;border:none;background:0 0;color:var(--text-color);cursor:pointer;font-size:12px;white-space:nowrap;border-radius:4px;transition:all .2s;opacity:.7}.tc-net-filter-btn.tc-active{color:var(--text-color);font-weight:600;opacity:1;position:relative}.tc-net-filter-btn.tc-active::after{content:'';position:absolute;width:90%;left:5%;height:2px;bottom:0;border-radius:3px;background:var(--filter-active)}.tc-net-filter-btn:hover{opacity:1}.tc-net-disable-btn{padding:5px 8px;border:none;background:0 0;color:var(--text-color);cursor:pointer;font-size:12px;border-radius:4px;white-space:nowrap;transition:all .2s;opacity:.55}.tc-net-disable-btn:hover{opacity:1}.tc-net-disable-btn.tc-disabled{opacity:1;color:var(--text-color);filter:none}.tc-network-items{flex:1;overflow-y:auto;padding:8px 12px}.tc-net-item{padding:12px 14px;margin-bottom:8px;background:var(--log-bg);border-left:3px solid var(--json-boolean);border-radius:6px;cursor:default;transition:background .2s}.tc-net-item:hover{background:var(--selected-bg)}.tc-net-item.tc-net-failed{border-left-color:#ff5252}.tc-net-item.tc-net-success{border-left-color:#98c379}.tc-net-item-header{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.tc-net-row1{display:flex;align-items:center;gap:8px;margin-bottom:4px}.tc-net-row2{display:flex;align-items:center;gap:8px;margin-bottom:6px}.tc-net-row3{display:flex;gap:8px;align-items:center}.tc-net-copy-btn,.tc-net-detail-btn{display:inline-flex;align-items:center;gap:4px;padding:4px 10px;border:none;border-radius:4px;font-size:11px;cursor:pointer;transition:all .2s}.tc-net-copy-btn{background:var(--action-bg);color:var(--json-key)}.tc-net-copy-btn:hover{background:var(--action-hover)}.tc-net-detail-btn{background:var(--action-bg);color:var(--json-key)}.tc-net-detail-btn:hover{background:var(--action-hover)}.tc-net-method{font-size:10px;font-weight:700;padding:2px 6px;border-radius:3px;text-transform:uppercase}.tc-net-method-GET{background:rgba(106,174,255,.2);color:var(--json-key)}.tc-net-method-POST{background:rgba(152,195,121,.2);color:var(--json-string)}.tc-net-method-PUT{background:rgba(255,193,7,.2);color:#ffc107}.tc-net-method-DELETE{background:rgba(255,82,82,.2);color:#ff5252}.tc-net-method-PATCH{background:rgba(255,152,0,.2);color:#ff9800}.tc-net-method-HEAD{background:rgba(190,80,70,.2);color:var(--json-null)}.tc-net-method-OPTIONS{background:rgba(112,112,112,.2);color:var(--json-cmt)}.tc-net-url{flex:1;font-size:12px;color:var(--text-color);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:100px}.tc-net-status{font-size:11px;font-weight:700;padding:2px 6px;border-radius:3px}.tc-net-status-2xx{background:rgba(152,195,121,.2);color:#98c379}.tc-net-status-3xx{background:rgba(106,174,255,.2);color:var(--json-key)}.tc-net-status-4xx{background:rgba(255,152,0,.2);color:#ff9800}.tc-net-status-5xx{background:rgba(255,82,82,.2);color:#ff5252}.tc-net-status-pending{background:rgba(112,112,112,.2);color:var(--json-cmt)}.tc-net-time{font-size:11px;color:var(--json-cmt);white-space:nowrap}.tc-net-item-actions{display:flex;gap:4px;align-items:center}.tc-net-action-btn{background:0 0;border:none;color:var(--json-cmt);cursor:pointer;font-size:13px;padding:2px 6px;border-radius:3px;transition:all .2s}.tc-net-action-btn:hover{background:var(--action-bg);color:var(--json-key)}.tc-net-detail-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:var(--console-bg);z-index:100;display:none;flex-direction:column}.tc-net-detail-header{display:flex;align-items:center;gap:8px;padding:10px 12px;background:var(--header-bg);border-bottom:1px solid var(--border-color)}.tc-net-back-btn{background:0 0;border:none;color:var(--text-color);cursor:pointer;font-size:16px;padding:4px 8px;border-radius:4px}.tc-net-back-btn:hover{background:var(--action-bg)}.tc-net-detail-title{flex:1;font-size:13px;color:var(--text-color);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tc-net-detail-body{flex:1;overflow-y:auto;padding:12px}.tc-net-detail-section{margin-bottom:16px}.tc-net-detail-label{font-size:11px;color:var(--json-cmt);text-transform:uppercase;margin-bottom:4px}.tc-net-detail-value{font-size:13px;color:var(--text-color);word-break:break-all;background:var(--log-bg);padding:8px 10px;border-radius:4px}.tc-net-detail-value textarea{width:100%;min-height:80px;background:var(--log-bg);border:1px solid var(--border-color);color:var(--text-color);border-radius:4px;padding:8px;font-size:12px;font-family:monospace;resize:vertical}.tc-net-resend-btn{padding:6px 14px;border:none;background:var(--filter-active);color:#fff;cursor:pointer;border-radius:4px;font-size:12px;transition:all .2s}.tc-net-resend-btn:hover{opacity:.85}.tc-net-new-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:var(--console-bg);z-index:100;display:none;flex-direction:column}.tc-net-new-header{display:flex;align-items:center;gap:8px;padding:10px 12px;background:var(--header-bg);border-bottom:1px solid var(--border-color)}.tc-net-new-title{flex:1;font-size:14px;color:var(--text-color)}.tc-net-new-body{flex:1;overflow-y:auto;padding:16px}.tc-net-form-group{margin-bottom:14px}.tc-net-form-label{font-size:12px;color:var(--json-cmt);margin-bottom:4px;display:block}.tc-net-form-input,.tc-net-form-select,.tc-net-form-textarea{width:100%;background:var(--log-bg);border:1px solid var(--border-color);color:var(--text-color);border-radius:4px;padding:8px 10px;font-size:13px;font-family:monospace;outline:0;transition:border-color .2s}.tc-net-form-input:focus,.tc-net-form-select:focus,.tc-net-form-textarea:focus{border-color:var(--filter-active)}.tc-net-form-textarea{min-height:100px;resize:none}.tc-net-form-select{cursor:pointer}.tc-net-send-btn{padding:8px 20px;border:none;background:var(--filter-active);color:#fff;cursor:pointer;border-radius:4px;font-size:13px;transition:all .2s;margin-left:auto;display:block}.tc-net-send-btn:hover{opacity:.85}.tc-net-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:var(--json-cmt);font-size:14px;gap:8px}.tc-net-detail-section-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:4px}.tc-net-detail-copy-section{background:0 0;border:none;color:var(--json-cmt);cursor:pointer;font-size:13px;padding:2px 6px;border-radius:3px;transition:all .2s}.tc-net-detail-copy-section:hover{background:var(--action-bg);color:var(--json-key)}.tc-net-detail-empty{color:var(--json-cmt);opacity:.5;font-style:italic}.tc-net-detail-value.tc-net-detail-code{font-family:monospace;white-space:pre-wrap;word-break:break-all;overflow-x:auto;max-height:400px}.tc-net-detail-url-row{display:flex;align-items:center;gap:6px}.tc-net-detail-url-copy{background:0 0;border:none;color:var(--json-cmt);cursor:pointer;font-size:13px;padding:2px 6px;border-radius:3px;transition:all .2s;flex-shrink:0}.tc-net-detail-url-copy:hover{background:var(--action-bg);color:var(--json-key)}.tc-net-detail-header-actions{display:flex;align-items:center;gap:4px;margin-left:auto}.tc-net-resend-icon-btn{background:0 0;border:none;color:var(--text-color);cursor:pointer;font-size:16px;padding:4px 8px;border-radius:4px;transition:all .2s}.tc-net-resend-icon-btn:hover{background:var(--action-bg);color:var(--json-key)}.tc-net-new-btn-right{margin-left:auto;flex-shrink:0}.tc-network-controls{display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--controls-bg);border-bottom:1px solid var(--border-color)}.tc-filters,.tc-network-filters,.tc-plug-view .tc-filters{display:flex;flex-wrap:nowrap;gap:2px;margin-left:0;overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;position:relative;padding-bottom:2px;min-width:0;flex:0 1 auto;-webkit-overflow-scrolling:touch}.tc-network-filters{flex:1 1 auto}.tc-filter-btn,.tc-net-filter-btn{position:relative;padding:5px 10px;border:none;background:0 0;color:var(--text-color);cursor:pointer;font-size:12px;display:flex;width:auto;white-space:nowrap;border-radius:4px;opacity:.55;transition:opacity .2s,background .2s;flex-shrink:0}.tc-filter-btn>.fa,.tc-net-filter-btn>.fa{margin-right:5px;margin-top:2px}.tc-filter-btn:hover,.tc-net-filter-btn:hover{opacity:1;background:rgba(127,127,127,.14)}.tc-filter-btn.tc-active,.tc-net-filter-btn.tc-active{opacity:1;font-weight:600;background:transparent}.tc-filter-btn.tc-active::after,.tc-net-filter-btn.tc-active::after{content:'';position:absolute;width:80%;left:10%;right:auto;top:auto;height:2px;bottom:0;border-radius:3px;background:var(--filter-active)}.tc-controls{padding:6px 12px}.tc-network-controls{padding:6px 12px}.tc-elements-tree .tc-tree-leaf{white-space:normal;word-break:break-all;max-height:8em;overflow-y:auto}@media(max-width:768px){.tc-controls{overflow:visible;padding:5px 10px}.tc-network-controls{padding:5px 10px}}.tc-filters.tc-overflow-start:not(.tc-overflow-end),.tc-network-filters.tc-overflow-start:not(.tc-overflow-end),.tc-plug-view .tc-filters.tc-overflow-start:not(.tc-overflow-end){-webkit-mask-image:linear-gradient(to right,transparent,#000 40px);mask-image:linear-gradient(to right,transparent,#000 40px)}.tc-filters.tc-overflow-end:not(.tc-overflow-start),.tc-network-filters.tc-overflow-end:not(.tc-overflow-start),.tc-plug-view .tc-filters.tc-overflow-end:not(.tc-overflow-start){-webkit-mask-image:linear-gradient(to left,transparent,#000 40px);mask-image:linear-gradient(to left,transparent,#000 40px)}.tc-filters.tc-overflow-start.tc-overflow-end,.tc-network-filters.tc-overflow-start.tc-overflow-end,.tc-plug-view .tc-filters.tc-overflow-start.tc-overflow-end{-webkit-mask-image:linear-gradient(to right,transparent,#000 40px,#000 calc(100% - 40px),transparent);mask-image:linear-gradient(to right,transparent,#000 40px,#000 calc(100% - 40px),transparent)}.tc-tree-toggle>i{font-size:10px;color:var(--json-cmt);transition:transform .2s;cursor:pointer;width:16px;text-align:center;display:inline-block}",e.setAttribute("tcstyle",""),e.setAttribute("tc-lock",""),document.head.append(e)}setupSplitter(){let e=!1,t=0,s=0;const i=()=>{e=!1,this.splitter.classList.remove("tc-dragging"),document.body.style.cursor="",document.body.style.userSelect=""};this.splitter.addEventListener("mousedown",i=>{i.preventDefault(),e=!0,t=i.clientX,s=this.consoleContainer.offsetWidth||.5*window.innerWidth,this.splitter.classList.add("tc-dragging"),document.body.style.cursor="col-resize",document.body.style.userSelect="none"}),document.addEventListener("mousemove",i=>{if(!e)return;let n=i.clientX,o=window.innerWidth-(s+(t-n));o=Math.max(200,Math.min(window.innerWidth-50,o)),this.consoleContainer&&(this.consoleContainer.style.width=o+"px",this.consoleContainer.style.flex="none")}),document.addEventListener("mouseup",i),this.splitter.addEventListener("touchstart",t=>{t.preventDefault(),e=!0,s=this.consoleContainer.offsetWidth||.5*window.innerWidth,t.touches[0],this.splitter.classList.add("tc-dragging")}),document.addEventListener("touchmove",t=>{if(!e)return;let s=t.touches[0],i=window.innerWidth-s.clientX;i=Math.max(200,Math.min(window.innerWidth-50,i)),this.consoleContainer&&(this.consoleContainer.style.width=i+"px",this.consoleContainer.style.flex="none")}),document.addEventListener("touchend",i)}showNotification(e,t=""){this.notification.innerHTML=`<i class='fa fa-${"warning"==t?"exclamation":"check"}' style='display:inline-block;vertical-align:middle;margin-right:8px'></i>${e.replace(/</,"&lt;").replace(/>/,"&gt;")}`,this.notification.className="tc-notification","warning"===t&&this.notification.classList.add("tc-warning"),this.notification.style.display="block",this.notification.offsetHeight,this.notification.classList.add("tc-show"),clearTimeout(this._notifTimer),this._notifTimer=setTimeout(()=>{this.notification.classList.remove("tc-show"),setTimeout(()=>{this.notification.style.display="none"},300)},3e3)}captureConsoleLogs(){this.originalConsole={log:console.log,info:console.info,warn:console.warn,error:console.error,debug:console.debug,time:console.time,timeEnd:console.timeEnd,count:console.count,countReset:console.countReset,assert:console.assert,trace:console.trace,group:console.group,groupEnd:console.groupEnd,clear:console.clear,table:console.table},console.log=(...e)=>(this.captureConsole("log",...e),console),console.info=(...e)=>(this.captureConsole("info",...e),console),console.warn=(...e)=>(this.captureConsole("warn",...e),console),console.error=(...e)=>(this.captureConsole("error",...e),console),console.debug=(...e)=>(this.captureConsole("log",...e),console),console.table=(e,t)=>(this._captureSubType="table",this._captureExtra={columns:t},this.captureConsole("log",e),this._captureSubType=null,this._captureExtra=null,console),console.time=(e="time")=>{e=String(e);let t=performance.now();this.timerMap.has(e)&&clearTimeout(this.timerMap.get(e).timeoutId);let s=setTimeout(()=>{if(!this.timerMap.has(e))return;let{start:t}=this.timerMap.get(e);this.timerMap.delete(e),console.info(`[time] "${e}" elapsed: ${(performance.now()-t).toFixed(1)}ms(timed out)`)},3e5);this.timerMap.set(e,{start:t,timeoutId:s}),console},console.timeEnd=(e="time")=>{e=String(e);let t=this.timerMap.get(e);if(!t)return void console.error(`[timeEnd] label"${e}" does not exist`);t.timeoutId&&clearTimeout(t.timeoutId);let s=performance.now()-t.start;this.timerMap.delete(e),console.info(`[time] "${e}" elapsed: ${s.toFixed(1)}ms`),console},console.count=(e="count")=>{e=String(e);let t=(this.countMap.get(e)||0)+1;this.countMap.set(e,t),console.info(`[count] label"${e}" called ${t} times`),console},console.countReset=(e="count")=>{e=String(e),this.countMap.has(e)?this.countMap.delete(e):console.error(`[countReset] label"${e}" does not exist`),console},console.assert=(e,...t)=>{e||console.error("[assertion failed] ",...t),console},console.trace=(...e)=>{let t=(new Error).stack.split("\n").slice(2).join("\n");console.warn("[trace] ",...e,"\n"+t),console},console.group=e=>(this.captureConsole("log",`[Group ${e}]`),console),console.groupEnd=()=>(this.captureConsole("log","[GroupEnd]"),console),console.clear=()=>(this.clearAllLogs(!0),console)}isClass(e){return"function"==typeof e&&e.prototype&&e.prototype.constructor===e&&!1===Object.getOwnPropertyDescriptor(e,"prototype").writable}safeStringify(t,s=2){let i=new WeakSet,n=(e,t=new WeakSet)=>null===e||"object"!=typeof e?"bigint"==typeof e?""+e.toString()+"n":e:t.has(e)?"[Circular reference]":(t.add(e),e instanceof RegExp?""+e.toString():e instanceof Date?""+e.toISOString():"function"==typeof e?"ƒ "+(e.name||"anonymous")+"("+this.getParams(e)+")":e instanceof Error?"[Error: "+e.message+"]":e instanceof ArrayBuffer?"[ArrayBuffer "+e.byteLength+" bytes]":e instanceof WeakMap?"[WeakMap]":e instanceof WeakSet?"[WeakSet]":e instanceof Map?"[Map "+e.size+"]":e instanceof Set?"[Set "+e.size+"]":Array.isArray(e)?e.map(e=>n(e,t)):Object.fromEntries(Object.entries(e).map(([e,s])=>[e,n(s,t)])));return t=n(t),JSON.stringify(t,function(t,s){if(void 0===s)return"undefined";if("number"==typeof s){if(Number.isNaN(s))return"NaN";if(!isFinite(s))return""+(s>0?"Infinity":"-Infinity")}if("object"==typeof s&&null!==s){if(i.has(s))return"[Circular reference]";if(i.add(s),!Array.isArray(s)&&s.constructor===Object)return Object.keys(s).sort((e,t)=>{const s="[[Prototype]]"===e,i="[[Prototype]]"===t,n=e.endsWith("[[Prototype]]")&&"[[Prototype]]"!==e,o=t.endsWith("[[Prototype]]")&&"[[Prototype]]"!==t;if(s&&!i)return 1;if(!s&&i)return-1;if(n&&!o)return 1;if(!n&&o)return-1;const a=e.match(/^(_*)/)[0].length,r=t.match(/^(_*)/)[0].length;return a!==r?a-r:e.localeCompare(t,void 0,{numeric:!0,sensitivity:"base"})}).reduce((e,t)=>(e[t]=s[t],e),{});if(s instanceof Error)return{name:s.name,message:s.message,stack:s.stack};if(s instanceof Date)return s.toISOString();if(s instanceof HTMLElement)return`<${s.tagName.toLowerCase()}>${s.tagName.toLowerCase()}element</${s.tagName.toLowerCase()}>`}return"string"==typeof s?s.startsWith("")?s:""+s:"function"==typeof s?""+(e.tC.isClass(s)?`[Class ${s.name||"anonymous"}]`:`ƒ ${s.name||"anonymous"}(${e.tC.getParams(s)})`):s},s)}formatArgsForPlainText(e){return Array.from(e).map(e=>{if("object"==typeof e&&null!==e)try{return this.safeStringify(e)}catch{return"[Cannot serialize]"}return String(e)}).join(" ")}captureConsole(e,...t){this.triggerGlobalHook("beforeLog",e,...t);let s=!1;if(this.mutedFilters.console&&(this.mutedFilters.console.all||this.mutedFilters.console[e])&&(s=!0),this.mutedLogs||s)return void this.originalConsole[e].apply(console,t);let i=new Date,n=t.map(e=>{if("object"==typeof e&&null!==e)try{if(e instanceof HTMLElement)return`el:<${e.tagName.toLowerCase()}>`;if(e instanceof Date)return`d:${e.getTime()}`;if(e instanceof RegExp)return`re:${e.toString()}`;if(e instanceof Error)return`e:${e.message}`;let t=Object.entries(e).reduce((e,[t,s])=>{if("then"===t&&"function"==typeof s)return e;if("object"==typeof s&&null!==s)try{e[t]=JSON.stringify(s)}catch{e[t]="NestedObject"}else e[t]=s;return e},{});return`o:${JSON.stringify(t)}`}catch{return`u:${Math.random().toString(36).substring(2,10)}`}return`${typeof e}:${String(e)}`}).join("|");if(this.lastLog&&this.lastLog.type===e&&this.lastLog.contentSign===n&&(this.lastLog.subType||null)===(this._captureSubType||null)){if(this.lastLog.args=[...t],this.lastLog.timestamp=new Date,this.lastLog.count++,t.some(e=>"object"==typeof e&&null!==e)){let e=this.safeStringify(t[0]);this.jsonPageIndex.has(e)||(this.jsonPageIndex.set(e,0),this.getPagedJson(t[0],0))}let s=document.getElementById(`tc-log-item-${this.lastLog.id}`);if(s){let e=s.querySelector(".tc-log-count");if(e)e.textContent=this.lastLog.count;else{let e=s.querySelector(".tc-log-header");if(e){let t=document.createElement("div");t.className="tc-log-count",t.textContent=this.lastLog.count;let s=e.querySelector(".tc-log-icon");s?e.insertBefore(t,s):e.appendChild(t)}}}return this.originalConsole[e].apply(console,t),void this.updateFilterCounts()}{let s={id:this.logs.length,type:e,args:[...t],content:this.formatArgsForPlainText(t),timestamp:i,count:1,expandedJson:!1,contentSign:n,hasObject:t.some(e=>"object"==typeof e&&null!==e||"function"==typeof e),isError:"error"===e||t.some(e=>e instanceof Error),subType:this._captureSubType||null,subTypeData:this._captureExtra||null};this.logs.push(s),this.lastLog=s,this.triggerGlobalHook("afterLog",s)}this.originalConsole[e].apply(console,t),this.overlay?.classList.contains("tc-active")&&"console"===this.currentTab&&(this.updateFilterCounts(),this.renderLogList(this.logs,!1)),this.logs.length>this.maxLog&&this.logs.splice(0,this.logs.length-this.maxLog)}formatArgs(e,t){let s=t||"x",i=Array.from(e),n=i.map((e,t)=>"function"==typeof e?`<div class="tc-function-preview"><span class="tc-json-boolean">ƒ ${e.name||"anonymous"}</span><span class="tc-json-cmt">(${this.getParams(e)})</span></div>`:e instanceof Error?`<div class="tc-error-stack"><strong>${e.name}:</strong>${e.message}<div>${e.stack||"No stack info"}</div></div>`:e instanceof HTMLElement?'<div class="tc-json-tree-container">'+this.renderHTMLTree(e,"",s+":html")+"</div>":e instanceof Date?`<div class="tc-json-preview"><span class="tc-json-string">${e.toISOString()}</span></div>`:e instanceof RegExp?`<div class="tc-json-preview"><span class="tc-json-number">${e.toString()}</span></div>`:e instanceof Map?`<div class="tc-json-preview"><span class="tc-json-boolean">[Map ${e.size}]</span></div>`:e instanceof Set?`<div class="tc-json-preview"><span class="tc-json-boolean">[Set ${e.size}]</span></div>`:e instanceof WeakMap?'<div class="tc-json-preview"><span class="tc-json-boolean">[WeakMap]</span></div>':e instanceof WeakSet?'<div class="tc-json-preview"><span class="tc-json-boolean">[WeakSet]</span></div>':e instanceof ArrayBuffer?`<div class="tc-json-preview"><span class="tc-json-boolean">[ArrayBuffer ${e.byteLength} bytes]</span></div>`:"object"==typeof e&&null!==e?'<div class="tc-json-tree-container">'+this.renderJSONTree(e,"",null,null,s+":",0)+"</div>":"number"==typeof e?Number.isNaN(e)?'<span class="tc-json-cmt">NaN</span>':isFinite(e)?`<span class="tc-json-number">${e}</span>`:`<span class="tc-json-cmt">${e>0?"Infinity":"-Infinity"}</span>`:"boolean"==typeof e?`<span class="tc-json-boolean">${e}</span>`:String(e).replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\n/g,"<br>"));return i.splice(0,1),n.join(" ")}highlightHTML(e){let t=e.outerHTML.replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/&lt;br&gt;/g,"<br>"),s="",i=0;for(;i<t.length;)if(t.startsWith("&lt;",i)){let e=t[i+4];if(e&&("/"===e||/[a-zA-Z]/.test(e))){let e=t.indexOf("&gt;",i);if(-1!==e){let n=t.slice(i,e+4);n=n.replace(/([\w-]+)(=)("[^"]*")/g,'<span style="color:#56b6c2">$1</span><span class="tc-json-boolean">$2</span><span class="tc-json-string">$3</span>'),n=n.replace(/^(&lt;\/?)([\w-]+)/,'<span class="tc-json-boolean">$1</span><span class="tc-json-boolean">$2</span>'),n=n.replace(/(&gt;)$/,'<span class="tc-json-boolean">$1</span>'),s+=n,i=e+4;continue}}let n=t.indexOf("&lt;",i+4);-1===n&&(n=t.length);let o=t.slice(i,n);s+=o.trim()?`<span class="tc-json-cmt">${o}</span>`:o,i=n}else if(t.startsWith("<br>",i))s+="<br>",i+=4;else{let e=t.indexOf("&lt;",i);-1===e&&(e=t.length);let n=t.slice(i,e);s+=n.trim()?`<span class="tc-json-cmt">${n}</span>`:n,i=e}return s}highlightJson=e=>e&&e.replace(/("(?:\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(?:\s*:)?|\b(?:true|false|null)\b|-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?\b|[\{\}\[\],.:])/g,e=>{let t="tc-json-cmt";if("true"===e||"false"===e)t="tc-json-boolean";else if("null"===e)t="tc-json-null";else if(/^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(e))t="tc-json-number";else if(e.endsWith(":"))t="tc-json-key";else if(e.startsWith('"')){let s=e.slice(1,-1);if(/^\\u0002/.test(s))return`<span class="tc-json-string">"${s.slice(6)}"</span>`;if(/^\\u0003/.test(s)){let e=s.slice(6);if(/^-?\d+n$/.test(e))return`<span class="tc-json-number">${e}</span>`;if(/^\u0192\s/.test(e)){let t=e.match(/^(\u0192\s+\S+)(\(.*\))$/);return t?`<span class="tc-json-boolean">${t[1]}</span><span class="tc-json-cmt">${t[2]}</span>`:`<span class="tc-json-boolean">${e}</span>`}return/^\[(?:Class|ArrayBuffer|Map|Set|WeakMap|WeakSet|Error)/.test(e)?`<span class="tc-json-boolean">${e}</span>`:/^\/.*\/[gimsuy]*$/.test(e)?`<span class="tc-json-number">${e}</span>`:/^\d{4}-\d{2}-\d{2}T/.test(e)?`<span class="tc-json-string">${e}</span>`:/^(?:undefined|NaN|Infinity|-Infinity)$/.test(e)?`<span class="tc-json-null">${e}</span>`:`<span class="tc-json-string">${e}</span>`}t="tc-json-string"}return`<span class="${t}">${e}</span>`})||"";getJsonKeys(e){return Array.isArray(e)?e.map((e,t)=>t):"object"==typeof e&&null!==e?Object.keys(e):[]}renderJSONValue(e,t){if(null===e)return'<span class="tc-json-null">null</span>';if(void 0===e)return'<span class="tc-json-null">undefined</span>';if("string"==typeof e)return'<span class="tc-json-string">"'+this.escapeHtml(e)+'"</span>';if("number"==typeof e)return'<span class="tc-json-number">'+e+"</span>";if("boolean"==typeof e)return'<span class="tc-json-boolean">'+e+"</span>";let s=Array.isArray(e),i=s?"Array("+e.length+")":"Object",n=s?e.map((e,t)=>({name:String(t),value:e})):Object.keys(e).map(t=>({name:t,value:e[t]}));if(0===n.length)return'<span class="tc-json-cmt">'+(t?this.escapeHtml(t)+": ":"")+(s?"[]":"{}")+"</span>";let o='<div class="tc-tree-node tc-collapsed">';o+='<span class="tc-tree-toggle"><i class="fa fa-angle-right"></i></span>',t&&(o+='<span class="tc-json-key">'+this.escapeHtml(t)+":</span> "),o+='<span class="tc-tree-label">'+this.escapeHtml(i)+"</span>",o+='<span class="tc-tree-brace tc-tree-open">{</span><span class="tc-tree-brace tc-tree-collapsed">{...}</span>';let a=++this.treeNodeRegId;return this.treeNodeRegistry.set(a,{obj:e,children:n,isJsonValue:!0}),o+='<div class="tc-tree-children" data-lazy-id="'+a+'"></div>',o+='<span class="tc-tree-brace tc-tree-close">}</span>',o+="</div>",o}renderJSONValueChildren(e,t){let s="";for(let t of e){let e=t.value;s+=null===e||"object"!=typeof e?'<div class="tc-tree-leaf"><span class="tc-tree-spacer"></span><span class="tc-json-key">'+this.escapeHtml(t.name)+":</span> "+this.renderJSONValue(e,"")+"</div>":"<div>"+this.renderJSONValue(e,t.name)+"</div>"}return s}getPagedJson(e,t){let s=this.safeStringify(e);if(!this.jsonPageCache.has(s)){let t=this.getJsonKeys(e),i=[];for(let e=0;e<t.length;e+=this.jsonPageSize)i.push(t.slice(e,e+this.jsonPageSize));this.jsonPageCache.set(s,i)}let i=this.jsonPageCache.get(s)[t]||[];if(Array.isArray(e))return i.map(t=>e[t]);{let t={};return i.forEach(s=>t[s]=e[s]),t}}changeJsonPage(e,t){let s=`log-${e}`;this.jsonPageIndex.set(s,t);let i=this.logs.find(t=>t.id===e);if(i){let t=this.consoleOutput;t&&t._vs?(t._vs.heights=new Map,t._vs.lastStart=-1,t._vs.lastEnd=-1,this.renderViewport(t)):this.updateLogItem(e,!1)}}toggleExpandJson(e){}updateLogItem(e,t=!1){let s=this.logs.find(t=>t.id===e);if(!s)return;let i=document.getElementById(`tc-log-item-${e}`);if(!i)return;let n={info:"fa fa-info-circle",warn:"fa fa-exclamation-triangle",error:"fa fa-times-circle",log:"fa fa-info"}[s.type]||"fa fa-info",o=s.timestamp.toLocaleTimeString(),a=this.formatArgs(s.args,s.id);i.innerHTML=`<div class="tc-log-header">${s.count>1?`<div class="tc-log-count">${s.count}</div>`:""}<div class="tc-log-icon"><i class="${n}"></i></div><div class="tc-timestamp">${o}</div></div><div class="tc-log-content">${a}</div>`}updateControlsVisibility(){let e=this.overlay.querySelector("#tc-consoleControls"),t="console"===this.currentTab,s="localstorage"===this.currentTab,i="network"===this.currentTab,n=()=>{this.netNewBtn&&(this.netNewBtn.style.display="none")};t?(e.style.display="flex",this.overlay.querySelector("#tc-filtersContainer")&&(this.overlay.querySelector("#tc-filtersContainer").style.display="flex"),this.lsFiltersContainer&&(this.lsFiltersContainer.style.display="none"),this.muteBtn&&(this.muteBtn.style.display="flex"),this.logCopyBtn&&(this.logCopyBtn.style.display=null!==this.selectedLogId?"flex":"none"),this.lsAddBtn&&(this.lsAddBtn.style.display="none"),n(),this.elementPickBtn&&(this.elementPickBtn.style.display="none"),this.elCopyBtn&&(this.elCopyBtn.style.display="none"),this.elDeleteBtn&&(this.elDeleteBtn.style.display="none")):s?(e.style.display="flex",this.overlay.querySelector("#tc-filtersContainer")&&(this.overlay.querySelector("#tc-filtersContainer").style.display="none"),this.lsFiltersContainer&&(this.lsFiltersContainer.style.display="flex"),this.muteBtn&&(this.muteBtn.style.display="none"),this.logCopyBtn&&(this.logCopyBtn.style.display="none"),this.lsAddBtn&&(this.lsAddBtn.style.display="flex"),n(),this.elementPickBtn&&(this.elementPickBtn.style.display="none"),this.elCopyBtn&&(this.elCopyBtn.style.display="none"),this.elDeleteBtn&&(this.elDeleteBtn.style.display="none")):i?(e.style.display="none",this.logCopyBtn&&(this.logCopyBtn.style.display="none"),this.lsAddBtn&&(this.lsAddBtn.style.display="none"),this.netNewBtn&&(this.netNewBtn.style.display="flex"),this.searchBar&&(this.searchBar.style.display="flex"),this.searchToggleBtn&&(this.searchToggleBtn.style.display="flex"),this.elementPickBtn&&(this.elementPickBtn.style.display="none"),this.elCopyBtn&&(this.elCopyBtn.style.display="none"),this.elDeleteBtn&&(this.elDeleteBtn.style.display="none")):"elements"===this.currentTab?(e.style.display="none",this.logCopyBtn&&(this.logCopyBtn.style.display="none"),this.lsAddBtn&&(this.lsAddBtn.style.display="none"),n(),this.searchBar&&(this.searchBar.style.display="none"),this.searchToggleBtn&&(this.searchToggleBtn.style.display="none"),this.elementPickBtn&&(this.elementPickBtn.style.display="flex"),this.elCopyBtn&&(this.elCopyBtn.style.display="flex"),this.elDeleteBtn&&(this.elDeleteBtn.style.display="flex")):(e.style.display="none",this.logCopyBtn&&(this.logCopyBtn.style.display="none"),this.lsAddBtn&&(this.lsAddBtn.style.display="none"),n(),this.elementPickBtn&&(this.elementPickBtn.style.display="none"),this.elCopyBtn&&(this.elCopyBtn.style.display="none"),this.elDeleteBtn&&(this.elDeleteBtn.style.display="none")),this.searchBar&&"elements"!==this.currentTab&&(this.searchBar.style.display=this.searchExpanded?"flex":"none"),this.searchToggleBtn&&(this.searchToggleBtn.style.display="elements"===this.currentTab?"none":"flex"),this.updateEditorVisibility()}updateEditorVisibility(){if(!this.lsEditorOverlay)return;let e=this.editorState.visible;if(e&&"ls"===this.editorState.mode&&"localstorage"!==this.currentTab&&(e=!1),this.lsEditorOverlay.style.display=e?"flex":"none",e){let e="code"===this.editorState.mode;this.lsEditorKeyInput&&(this.lsEditorKeyInput.style.display=e?"none":"block"),this.lsEditorTitle.textContent=e?"Run Code":"",this.lsEditorInput.placeholder=e?"Enter code to execute...":"Enter value...",this.lsEditorSave.textContent=e?"Run":"Save",this.lsEditorSave.className="tc-ls-editor-btn "+(e?"tc-run":"tc-save"),this.lsEditorInput.value!==this.editorState.value&&(this.lsEditorInput.value=this.editorState.value),!e&&this.lsEditorKeyInput&&this.lsEditorKeyInput.value!==this.editorState.key&&(this.lsEditorKeyInput.value=this.editorState.key)}}setupVirtualScroll(e){if(!e)return;e._vs={items:[],renderItem:null,afterRender:null,avgHeight:70,estHeight:70,heights:new Map,lastStart:-1,lastEnd:-1,rafId:null,isAtBottom:!0,contentEl:null,topSpacer:null,bottomSpacer:null,fakeEl:null,hasStructure:!1,topSpaceHeight:0,lastScrollTop:0,lastTimestamp:0,speedToleranceFactor:100,maxSpeedTolerance:2e3,minSpeedTolerance:100};let t=document.createElement("div");t.className="tc-vs-spacer",t.style.cssText="width:100%;flex-shrink:0;height:0";let s=document.createElement("div");s.className="tc-vs-content",s.style.cssText="width:100%";let i=document.createElement("div");i.className="tc-vs-spacer",i.style.cssText="width:100%;flex-shrink:0;height:0";let n=document.createElement("div");n.style.cssText="position:absolute;visibility:hidden;left:0;top:0;width:100%;pointer-events:none",e.innerHTML="",e.appendChild(t),e.appendChild(s),e.appendChild(i),e.appendChild(n),e._vs.topSpacer=t,e._vs.contentEl=s,e._vs.bottomSpacer=i,e._vs.fakeEl=n,e._vs.hasStructure=!0,e.addEventListener("scroll",()=>{let t=e._vs;if(!t)return;let s=e.scrollHeight,i=e.clientHeight,n=e.scrollTop;t.isAtBottom=Math.abs(s-i-n)<2;let o,a,r=Date.now(),l=r-t.lastTimestamp,c=n-t.lastScrollTop,d=Math.abs(c/(l||1))*t.speedToleranceFactor;l>1e3&&(d=1e3),d>t.maxSpeedTolerance&&(d=t.maxSpeedTolerance),d<t.minSpeedTolerance&&(d=t.minSpeedTolerance),t.lastScrollTop=n,t.lastTimestamp=r,t.lastScrollTop<n?(o=t.minSpeedTolerance,a=d):(o=d,a=t.minSpeedTolerance),t.topSpaceHeight<n-o&&t.topSpaceHeight+t.contentEl.offsetHeight>n+i+a||(t.rafId&&(cancelAnimationFrame(t.rafId),t.rafId=null),t.rafId=requestAnimationFrame(()=>{t.rafId=null,this.renderViewport(e)}))},{passive:!0})}renderViewport(e){let t=e._vs;if(!t||!t.contentEl)return;if(!t.items||!t.items.length)return;let s=e.clientHeight||400,i=e.scrollTop,n=t.estHeight;n<10&&(n=70);let o=600,a=i-o,r=i+s+o,l=0,c=0,d=0,h=t.items.length,p=!1;for(let e=0;e<t.items.length;e++){let s=t.heights.get(e)||n;if(!p&&l+s>=a&&(d=e,p=!0),l>=r){h=e;break}l+=s}if(p){if(h===t.items.length){h=t.items.length;let e=h;for(;e>d&&c<s+o;)e--,c+=t.heights.get(e)||n;d=Math.max(0,Math.min(d,e))}}else d=0;let u=!1;for(let e=d;e<h;e++)if(!t.heights.has(e)){u=!0;break}if(u&&t.fakeEl){let s=t.fakeEl,i=e.clientWidth;i>0&&(s.style.width=i+"px");for(let e=d;e<h;e++)if(!t.heights.has(e)){s.innerHTML=t.renderItem(t.items[e],e);let i=0;s.firstChild&&(i=s.firstChild.offsetHeight+10),i<10&&(i=n),t.heights.set(e,i)}s.innerHTML=""}l=0,c=0,d=0,h=t.items.length,p=!1;for(let e=0;e<t.items.length;e++){let s=t.heights.get(e)||n;if(!p&&l+s>=a&&(d=e,p=!0),l>=r){h=e;break}l+=s}if(p){if(h===t.items.length){h=t.items.length;let e=h;for(;e>d&&c<s+o;)e--,c+=t.heights.get(e)||n;d=Math.max(0,Math.min(d,e))}}else d=0;if(d===t.lastStart&&h===t.lastEnd)return void(t.isAtBottom&&(e.scrollTop=1e7));t.lastStart=d,t.lastEnd=h;let f=0;for(let e=0;e<d;e++)f+=t.heights.get(e)||n;let g=0;for(let e=h;e<t.items.length;e++)g+=t.heights.get(e)||n;t.topSpacer.style.height=f+"px",t.bottomSpacer.style.height=g+"px",t.topSpaceHeight=f;let m=[];for(let e=d;e<h;e++)m.push(t.renderItem(t.items[e],e));t.contentEl.innerHTML=m.join("");let b=t.contentEl.children;if(b.length>=1)for(let e=0;e<b.length;e++){let s=b[e].offsetHeight+10;Math.abs(s-(t.heights.get(d+e)||n))>5&&t.heights.set(d+e,s)}if(0===g&&b.length>0){let i=0;for(let e=0;e<b.length;e++)i+=b[e].offsetHeight+10;if(i<s&&d>0){let o=Math.ceil((s-i)/n)+2;if(Math.max(0,d-o)<d)return t.lastStart=-1,t.lastEnd=-1,this.renderViewport(e)}}t.isAtBottom&&(e.scrollTop=1e7),t.afterRender&&t.afterRender()}vsSetItems(e,t,s,i,n){let o=e._vs;if(o){if(o.items=t,o.renderItem=s,o.avgHeight=i||70,o.heights=new Map,o.lastStart=-1,o.lastEnd=-1,o.isAtBottom=!1,!t||!t.length)return o.contentEl.innerHTML="",o.topSpacer.style.height="0",o.bottomSpacer.style.height="0",void(o.topSpaceHeight=0);e.scrollTop=0,this.renderViewport(e)}}vsRefreshHeights(e){let t=e._vs;if(!t||!t.contentEl)return;let s=t.contentEl.children;if(s.length>0){let e=0;for(let i=0;i<s.length;i++){let n=s[i].offsetHeight+10;t.heights.set(t.lastStart+i,n),e+=n}let i=e/s.length;i>20&&i<2e3&&(t.avgHeight=Math.round(.5*t.avgHeight+.5*i))}let i=0;for(let e=0;e<t.lastStart;e++)i+=t.heights.get(e)||t.avgHeight;let n=0;for(let e=t.lastEnd;e<t.items.length;e++)n+=t.heights.get(e)||t.avgHeight;t.topSpacer.style.height=i+"px",t.bottomSpacer.style.height=n+"px",t.topSpaceHeight=i,0===n&&t.isAtBottom&&(e.scrollTop=1e7)}vsShowMessage(e,t){let s=e._vs;s&&s.contentEl?(s.items=[],s.topSpacer.style.height="0",s.bottomSpacer.style.height="0",s.topSpaceHeight=0,s.contentEl.innerHTML=t,e.scrollTop=0,s.lastStart=-1,s.lastEnd=-1,s.isAtBottom=!0):e.innerHTML=t}isNearBottom(e){let t=e._vs;if(!t)return!0;let s=e.scrollHeight,i=e.clientHeight,n=e.scrollTop;return t.isAtBottom=Math.abs(s-i-n)<2,t.isAtBottom}renderSubTypeContent(e){let t=e.args&&e.args.length>0?e.args[0]:void 0;return"table"===e.subType?this.renderTableHTML(t,e.subTypeData?.columns):""}renderJSONTree(e,t,s,i,n,o,a){if(s||(s=new WeakSet),i||(i=[]),o=o||0,null===e)return'<span class="tc-json-null">null</span>';if(void 0===e)return'<span class="tc-json-null">undefined</span>';if("string"==typeof e)return'<span class="tc-json-string">"'+this.escapeHtml(e)+'"</span>';if("number"==typeof e)return'<span class="tc-json-number">'+e+"</span>";if("boolean"==typeof e)return'<span class="tc-json-boolean">'+e+"</span>";if("bigint"==typeof e)return'<span class="tc-json-number">'+e.toString()+"n</span>";if("symbol"==typeof e){let t=Object.create(Object.getPrototypeOf(Object(e)));Object.defineProperty(t,"value",{value:e.toString(),enumerable:!0,writable:!0,configurable:!0}),Object.defineProperty(t,"description",{value:e.description,enumerable:!0,writable:!0,configurable:!0}),e=t}if("function"==typeof e){let t=e.name||"anonymous";return this.isClass(e)?'<span class="tc-json-boolean">[Class '+this.escapeHtml(t)+"]</span>":'<span class="tc-json-boolean">ƒ '+this.escapeHtml(t)+'</span><span class="tc-json-cmt">('+this.getParams(e)+")</span>"}if(e instanceof Date)return'<span class="tc-json-string">'+e.toISOString()+"</span>";if(e instanceof RegExp)return'<span class="tc-json-number">'+e.toString()+"</span>";if(e instanceof Map)return'<span class="tc-json-boolean">[Map '+e.size+"]</span>";if(e instanceof Set)return'<span class="tc-json-boolean">[Set '+e.size+"]</span>";if(e instanceof WeakMap)return'<span class="tc-json-boolean">[WeakMap]</span>';if(e instanceof WeakSet)return'<span class="tc-json-boolean">[WeakSet]</span>';if(e instanceof ArrayBuffer)return'<span class="tc-json-boolean">[ArrayBuffer '+e.byteLength+" bytes]</span>";if(e instanceof Error)return'<span class="tc-json-boolean">[Error: '+this.escapeHtml(e.message)+"]</span>";if(e instanceof HTMLElement)return this.renderHTMLTree(e,t,n+".html");if(s.has(e))return'<span class="tc-json-cmt">[Circular reference]</span>';s.add(e);let r=i.concat([e]),l=Array.isArray(e),c=l?"Array("+e.length+")":e.constructor&&e.constructor.name?e.constructor.name:"Object",d=[];try{Reflect.ownKeys(e).forEach(t=>{let s=Object.getOwnPropertyDescriptor(e,t);s&&d.push({name:String(t),desc:s})})}catch(t){try{Object.keys(e).forEach(t=>{let s=Object.getOwnPropertyDescriptor(e,t);s&&d.push({name:String(t),desc:s})})}catch(t){return s.delete(e),'<span class="tc-json-boolean">['+this.escapeHtml(c)+"]</span>"}}let h=Object.getPrototypeOf(e);if(!a&&h&&null!==h&&d.push({name:"[[Prototype]]",desc:{value:h,enumerable:!0,writable:!0,configurable:!0}}),0===d.length)return s.delete(e),l?'<span class="tc-json-cmt">'+(t?this.escapeHtml(t)+": ":"")+"[]</span>":'<span class="tc-json-cmt">'+(t?this.escapeHtml(t)+": ":"")+"{}</span>";l||d.sort((e,t)=>{if("[[Prototype]]"===e.name)return 1;if("[[Prototype]]"===t.name)return-1;let s=!(!e.desc.get&&!e.desc.set),i=!(!t.desc.get&&!t.desc.set);if(s&&!i)return 1;if(!s&&i)return-1;let n=(e.name.match(/^(_*)/)||[""])[0].length,o=(t.name.match(/^(_*)/)||[""])[0].length;if(n!==o)return n-o;let a=/^[A-Z]/.test(e.name),r=/^[A-Z]/.test(t.name);return a&&!r?1:!a&&r?-1:e.name.localeCompare(t.name,void 0,{numeric:!0,sensitivity:"base"})});let p=n||"",u=this.expandedTreePaths.has(p),f='<div class="tc-tree-node'+(u?" tc-expanded":" tc-collapsed")+'" data-tree-path="'+this.escapeHtml(p)+'">';if(f+='<span class="tc-tree-toggle"><i class="fa '+(u?"fa-angle-down":"fa-angle-right")+'"></i></span>',t&&(f+='<span class="tc-json-key">'+this.escapeHtml(t)+":</span> "),f+='<span class="tc-tree-label">'+this.escapeHtml(c)+"</span>",f+='<span class="tc-tree-brace tc-tree-open">{</span><span class="tc-tree-brace tc-tree-collapsed">{...}</span>',u){f+='<div class="tc-tree-children">';let e=200;if(d.length>e){let t=this.treeNodeRegId++;this.treeNodeRegistry.set(t,{children:d,chain:r,noProto:a}),f+=this.renderTreeChildrenBatch(d,s,0,e,r,p,o+1,a),f+='<div class="tc-tree-load-more" data-reg-id="'+t+'" data-offset="'+e+'"><i class="fa fa-angle-down"></i> Load more ('+(d.length-e)+" items left)</div>"}else f+=this.renderTreeChildrenBatch(d,s,0,d.length,r,p,o+1,a);f+="</div>"}else{let t=this.treeNodeRegId++;this.treeNodeRegistry.set(t,{obj:e,children:d,chain:i,path:p,noProto:a}),f+='<div class="tc-tree-children" data-lazy-id="'+t+'"></div>'}return f+='<span class="tc-tree-brace tc-tree-close">}</span>',f+="</div>",s.delete(e),f}renderTreeChildrenBatch(e,t,s,i,n,o,a,r){a=a||0;let l="";for(let c=s;c<i&&c<e.length;c++){let s=e[c];if(s.desc.get||s.desc.set)s.desc.get&&(l+='<div class="tc-tree-leaf"><span class="tc-tree-spacer"></span><span class="tc-json-key">get '+this.escapeHtml(s.name)+":</span> "+this.renderJSONTree(s.desc.get,"",t,n,o+"."+s.name,a+1,r)+"</div>"),s.desc.set&&(l+='<div class="tc-tree-leaf"><span class="tc-tree-spacer"></span><span class="tc-json-key">set '+this.escapeHtml(s.name)+":</span> "+this.renderJSONTree(s.desc.set,"",t,n,o+"."+s.name,a+1,r)+"</div>");else{let e=s.desc.value;null===e||"object"!=typeof e||Array.isArray(e)||e instanceof Date||e instanceof RegExp||e instanceof Map||e instanceof Set||e instanceof WeakMap||e instanceof WeakSet||e instanceof ArrayBuffer||e instanceof Error||e instanceof HTMLElement||"function"==typeof e?l+='<div class="tc-tree-leaf"><span class="tc-tree-spacer"></span><span class="tc-json-key">'+this.escapeHtml(s.name)+":</span> "+this.renderJSONTree(e,"",t,n,o+"."+s.name,a+1,r)+"</div>":t.has(e)?l+='<div class="tc-tree-leaf"><span class="tc-tree-spacer"></span><span class="tc-json-key">'+this.escapeHtml(s.name)+':</span> <span class="tc-json-cmt">[Circular reference]</span></div>':l+="<div>"+this.renderJSONTree(e,s.name,t,n,o+"."+s.name,a+1,r)+"</div>"}}return l}renderDomChild(e,t,s,i){return 1===e.nodeType?"<div>"+t(e,s,i)+"</div>":3===e.nodeType?'<div class="tc-tree-leaf"><span class="tc-tree-spacer"></span><span class="tc-json-cmt">'+this.escapeHtml(e.textContent.trim())+"</span></div>":""}renderDomChildrenLazy(e,t,s,i,n){let o="";if(e.length>200){let a=this.treeNodeRegId++;this.treeNodeRegistry.set(a,Object.assign({type:i,children:e,depth:s},n));for(let i=0;i<200;i++)o+=this.renderDomChild(e[i],t,i,s+1);o+='<div class="tc-tree-load-more" data-reg-id="'+a+'" data-offset="200"><i class="fa fa-angle-down"></i> Load more ('+(e.length-200)+")</div>"}else{let i=0;for(let n of e)o+=this.renderDomChild(n,t,i,s+1),1===n.nodeType&&i++}return o}buildShadowLazy(e,t,s,i,n){let o='<div class="tc-tree-node tc-collapsed" ';if("element"===t){let t=++this.elRefId;this.elRefMap.set(t,e.root),o+='data-el-id="'+t+'" data-shadow-host="'+n+'"'}else o+='data-tree-path="'+this.escapeHtml(s+".shadow")+'" data-shadow-root="1"';o+='><span class="tc-tree-toggle"><i class="fa fa-angle-right"></i></span><span class="tc-tree-label tc-json-null">#shadow('+e.mode+")</span>";let a=Array.from(e.root.childNodes).filter(e=>1===e.nodeType||3===e.nodeType&&e.textContent.trim());if(a.length>0){let n=this.treeNodeRegId++;this.treeNodeRegistry.set(n,{type:t+"-shadow",shadowInfo:e,path:s,depth:i,children:a}),o+='<span class="tc-tree-ellipsis">...</span><div class="tc-tree-children" data-lazy-id="'+n+'"></div>'}return o+"</div>"}loadMoreTreeChildren(e){let t=parseInt(e.dataset.regId),s=parseInt(e.dataset.offset),i=this.treeNodeRegistry.get(t);if(!i)return;let n=e.closest(".tc-console-output, .tc-ls-items, .tc-elements-tree");if("html"===i.type){let t=Math.min(s+200,i.children.length),n="";for(let e=s;e<t;e++)n+=this.renderDomChild(i.children[e],(e,t)=>this.renderHTMLTree(e,"",i.path+"."+t,(i.depth||0)+1),e,0);e.insertAdjacentHTML("beforebegin",n)}else if("element"===i.type){let t=Math.min(s+200,i.children.length),n="";for(let e=s;e<t;e++)n+=this.renderDomChild(i.children[e],e=>this.renderElementTree(e,(i.depth||0)+1),e,0);e.insertAdjacentHTML("beforebegin",n)}else{let t=new WeakSet;i.chain.forEach(e=>t.add(e)),e.insertAdjacentHTML("beforebegin",this.renderTreeChildrenBatch(i.children,t,s,Math.min(s+200,i.children.length),i.chain,i.path||"",1,i.noProto))}let o=s+200;o<i.children.length?(e.dataset.offset=o,e.innerHTML='<i class="fa fa-angle-down"></i> Load more ('+(i.children.length-o)+")"):(e.remove(),this.treeNodeRegistry.delete(t)),n&&this.vsRefreshHeights(n)}renderHTMLTree(e,t,s,i){if((i=i||0)>30)return'<span class="tc-json-cmt">[depth limit]</span>';s=s||"";let n=e.tagName.toLowerCase(),o="";for(let t of e.attributes)o+=t.value?' <span style="color:#56b6c2">'+this.escapeHtml(t.name)+'</span><span class="tc-json-boolean">=</span><span class="tc-json-string">"'+this.escapeHtml(t.value)+'"</span>':' <span style="color:#56b6c2">'+this.escapeHtml(t.name)+"</span>";let a=Array.from(e.childNodes),r=this.getShadowRoot(e),l=r&&Array.from(r.root.childNodes).some(e=>1===e.nodeType||3===e.nodeType&&e.textContent.trim()),c=r&&(l||r.mode&&"closed"===r.mode),d=a.some(e=>1===e.nodeType)||a.filter(e=>3===e.nodeType&&e.textContent.trim()).length>0||!!c,h=this.expandedTreePaths.has(s),p='<div class="tc-tree-node'+(h?" tc-expanded":" tc-collapsed")+'" data-tree-path="'+this.escapeHtml(s)+'">';if(p+=d?'<span class="tc-tree-toggle"><i class="fa '+(h?"fa-angle-down":"fa-angle-right")+'"></i></span>':'<span class="tc-tree-spacer"></span>',t&&(p+='<span class="tc-json-key">'+this.escapeHtml(t)+":</span> "),p+='<span class="tc-tree-label tc-json-boolean">&lt;'+n+o+"&gt;</span>",d){if(p+='<span class="tc-tree-ellipsis">...</span>',h){p+='<div class="tc-tree-children">';let e=a.filter(e=>1===e.nodeType||3===e.nodeType&&e.textContent.trim());if(p+=this.renderDomChildrenLazy(e,(e,t,i)=>this.renderHTMLTree(e,"",s+"."+t,i),i,"html",{path:s}),c)if(this.expandedTreePaths.has(s+".shadow")){let e=Array.from(r.root.childNodes).filter(e=>1===e.nodeType||3===e.nodeType&&e.textContent.trim());p+='<div class="tc-tree-node tc-expanded" data-tree-path="'+this.escapeHtml(s+".shadow")+'" data-shadow-root="1"><span class="tc-tree-toggle"><i class="fa fa-angle-down"></i></span><span class="tc-tree-label tc-json-null">#shadow('+r.mode+')</span><span class="tc-tree-ellipsis">...</span><div class="tc-tree-children">'+this.renderDomChildrenLazy(e,(e,t,i)=>this.renderHTMLTree(e,"",s+".shadow."+t,i),i,"html-shadow",{shadowInfo:r,path:s})+"</div></div>"}else p+=this.buildShadowLazy(r,"html",s,i);p+="</div>"}else{let e=a.filter(e=>1===e.nodeType||3===e.nodeType&&e.textContent.trim()),t=this.treeNodeRegId++;this.treeNodeRegistry.set(t,{type:"html",children:e,path:s,depth:i,shadow:c?r:null}),p+='<div class="tc-tree-children" data-lazy-id="'+t+'"></div>'}p+='<span class="tc-tree-label tc-json-boolean tc-tree-close-tag">&lt;/'+n+"&gt;</span>"}else p+='<span class="tc-tree-label tc-json-boolean tc-tree-close-tag">&lt;/'+n+"&gt;</span>";return p+="</div>",p}renderElementsView(){if(!this.elementsTree)return;let e=document.documentElement;this.elRefMap=new Map,this.elRefId=0;let t=this.renderElementTree(e,0);this.elementsTree.innerHTML=t,this.pendingHighlight?this.expandToElement(this.pendingHighlight):this.selectedElement&&this.restoreElementSelection()}restoreElementSelection(){if(!this.selectedElement||!this.elementsTree)return;let e=null;for(let[t,s]of this.elRefMap)if(s===this.selectedElement){e=t;break}if(null===e)return;let t=this.elementsTree.querySelector('.tc-tree-node[data-el-id="'+e+'"]');if(!t)return;let s=t;for(;s&&s!==this.elementsTree;)s.classList.contains("tc-tree-node")&&(s.classList.remove("tc-collapsed"),s.classList.add("tc-expanded"),s.querySelector(":scope > .tc-tree-toggle > i")&&(s.querySelector(":scope > .tc-tree-toggle > i").classList.remove("fa-angle-right"),s.querySelector(":scope > .tc-tree-toggle > i").classList.add("fa-angle-down")),s.dataset.elId&&this.elRefMap&&this.elRefMap.get(parseInt(s.dataset.elId))&&this.expandedElements.add(this.elRefMap.get(parseInt(s.dataset.elId)))),s=s.parentElement;this.elementsTree.querySelectorAll(".tc-el-selected").forEach(e=>e.classList.remove("tc-el-selected")),t.classList.add("tc-el-selected"),t.classList.add("tc-el-highlight"),requestAnimationFrame(()=>{t.scrollIntoView({behavior:"smooth",block:"center"}),setTimeout(()=>t.classList.remove("tc-el-highlight"),3e3)})}renderElementTree(e,t){if(e===this.overlay||e===this.notification||e===this.btn)return"";if(e.nodeType&&3===e.nodeType){let t=e.textContent.trim();return t?'<div class="tc-tree-leaf"><span class="tc-tree-spacer"></span><span class="tc-json-cmt">'+this.escapeHtml(t)+"</span></div>":""}if(1!==e.nodeType)return"";let s=e.tagName.toLowerCase(),i="";for(let t of e.attributes)i+=t.value?' <span style="color:#56b6c2">'+this.escapeHtml(t.name)+'</span><span class="tc-json-boolean">=</span><span class="tc-json-string">"'+this.escapeHtml(t.value)+'"</span>':' <span style="color:#56b6c2">'+this.escapeHtml(t.name)+"</span>";let n=Array.from(e.childNodes).filter(e=>1===e.nodeType||3===e.nodeType&&e.textContent.trim()),o=this.getShadowRoot(e),a=o&&Array.from(o.root.childNodes).some(e=>1===e.nodeType||3===e.nodeType&&e.textContent.trim()),r=o&&(a||o.mode&&"closed"===o.mode),l=n.length>0||!!r,c=0===t||this.expandedElements.has(e),d=++this.elRefId;this.elRefMap.set(d,e);let h='<div class="tc-tree-node'+(c?" tc-expanded":" tc-collapsed")+'" data-el-id="'+d+'">';if(h+=l?'<span class="tc-tree-toggle"><i class="fa '+(c?"fa-angle-down":"fa-angle-right")+'"></i></span>':'<span class="tc-tree-spacer"></span>',h+='<span class="tc-tree-label tc-json-boolean">&lt;'+s+i+"&gt;</span>",l){if(h+='<span class="tc-tree-ellipsis">...</span>',c){if(h+='<div class="tc-tree-children">',h+=this.renderDomChildrenLazy(n,(e,t,s)=>this.renderElementTree(e,s),t,"element",{}),r)if(this.expandedElements.has(o.root)||0===t){let e=Array.from(o.root.childNodes).filter(e=>1===e.nodeType||3===e.nodeType&&e.textContent.trim()),s=++this.elRefId;this.elRefMap.set(s,o.root),h+='<div class="tc-tree-node tc-expanded" data-el-id="'+s+'" data-shadow-host="'+d+'"><span class="tc-tree-toggle"><i class="fa fa-angle-down"></i></span><span class="tc-tree-label tc-json-null">#shadow('+o.mode+')</span><span class="tc-tree-ellipsis">...</span><div class="tc-tree-children">'+this.renderDomChildrenLazy(e,(e,t,s)=>this.renderElementTree(e,s),t,"element-shadow",{})+"</div></div>"}else h+=this.buildShadowLazy(o,"element",null,t,d);h+="</div>"}else{let e=this.treeNodeRegId++;this.treeNodeRegistry.set(e,{type:"element",children:n,depth:t,shadow:r?o:null,elId:d}),h+='<div class="tc-tree-children" data-lazy-id="'+e+'"></div>'}h+='<span class="tc-tree-label tc-json-boolean tc-tree-close-tag">&lt;/'+s+"&gt;</span>"}else h+='<span class="tc-tree-label tc-json-boolean tc-tree-close-tag">&lt;/'+s+"&gt;</span>";return h+="</div>",h}startElementPicker(){this.elementPickBtn&&this.elementPickBtn.classList.add("tc-active"),this.triggerGlobalHook("beforeClose"),this.overlay.classList.remove("tc-active"),this.triggerGlobalHook("afterClose");let e=document.createElement("div");e.className="tc-element-picker-overlay",e.style.pointerEvents="none";let t=!1,s=n=>{if(t)return;t=!0,n.preventDefault(),n.stopPropagation();let o=n.target;e.remove(),document.removeEventListener("click",s,!0),document.removeEventListener("keydown",i,!0),this.pendingHighlight=o,this.switchTab("elements"),this.triggerGlobalHook("beforeOpen"),this.overlay.classList.add("tc-active","tc-theme-"+this.currentTheme),this.triggerGlobalHook("afterOpen"),this.elementPickBtn&&this.elementPickBtn.classList.remove("tc-active")},i=n=>{"Escape"!==n.key||t||(t=!0,e.remove(),document.removeEventListener("click",s,!0),document.removeEventListener("keydown",i,!0),this.triggerGlobalHook("beforeOpen"),this.overlay.classList.add("tc-active","tc-theme-"+this.currentTheme),this.triggerGlobalHook("afterOpen"),this.elementPickBtn&&this.elementPickBtn.classList.remove("tc-active"))};document.body.appendChild(e),setTimeout(()=>{document.addEventListener("click",s,!0),document.addEventListener("keydown",i,!0)},200)}expandToElement(e){if(!e||!this.elementsTree)return;this.pendingHighlight=null,this.selectedElement=e;let t=null;for(let[s,i]of this.elRefMap)if(i===e){t=s;break}if(null===t)return;let s=this.elementsTree.querySelector('.tc-tree-node[data-el-id="'+t+'"]');if(!s)return;let i=s;for(;i&&i!==this.elementsTree;){if(i.classList.contains("tc-tree-node")){i.classList.remove("tc-collapsed"),i.classList.add("tc-expanded");let e=i.querySelector(":scope > .tc-tree-toggle > i");if(e&&(e.classList.remove("fa-angle-right"),e.classList.add("fa-angle-down")),i.dataset.elId&&this.elRefMap){let e=this.elRefMap.get(parseInt(i.dataset.elId));e&&this.expandedElements.add(e)}let t=i.querySelector(":scope > .tc-tree-children[data-lazy-id]");if(t){let e=parseInt(t.dataset.lazyId),s=this.treeNodeRegistry.get(e);if(s){let i="";"element"===s.type?(i=this.renderDomChildrenLazy(s.children,(e,t,s)=>this.renderElementTree(e,s),s.depth||0,"element",{}),s.shadow&&(i+=this.buildShadowLazy(s.shadow,"element",null,s.depth||0,s.elId))):"element-shadow"===s.type&&(i=this.renderDomChildrenLazy(s.children,(e,t,s)=>this.renderElementTree(e,s),s.depth||0,"element-shadow",{})),t.innerHTML=i,delete t.dataset.lazyId,this.treeNodeRegistry.delete(e)}}}i=i.parentElement}this.elementsTree.querySelectorAll(".tc-el-selected").forEach(e=>e.classList.remove("tc-el-selected")),s.classList.add("tc-el-selected"),s.classList.add("tc-el-highlight"),requestAnimationFrame(()=>{s.scrollIntoView({behavior:"smooth",block:"center"}),setTimeout(()=>s.classList.remove("tc-el-highlight"),3e3)})}copyElementHTML(e){let t=e.outerHTML;navigator.clipboard?navigator.clipboard.writeText(t).then(()=>this.showNotification("Element copied")).catch(()=>this.fallbackCopy(t)):this.fallbackCopy(t)}fallbackCopy(e){let t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.select();try{document.execCommand("copy"),this.showNotification("Element copied")}catch(t){this.showNotification("Copy failed","warning")}t.remove()}deleteElement(e){if(e)if(null!==this.selectedShadowHostId){let e=this.elRefMap.get(this.selectedShadowHostId);if(e){let t=this.getShadowRoot(e);if(t){if("closed"===t.mode)return void this.showNotification("Cannot delete closed ShadowDOM","warning");try{for(e.shadowRoot&&(e.shadowRoot.innerHTML="");t.root.firstChild;)t.root.removeChild(t.root.lastChild)}catch{}this.selectedElement=null,this.selectedShadowHostId=null,this.showNotification("ShadowDOM deleted"),this.renderElementsView()}else this.showNotification("ShadowDOM no longer exists","warning")}else this.showNotification("Cannot delete this element","warning")}else e.parentNode?(e.parentNode.removeChild(e),this.showNotification("Element deleted"),this.selectedElement===e&&(this.selectedElement=null),this.renderElementsView()):e.parentElement?(e.parentElement.removeChild(e),this.showNotification("Element deleted"),this.selectedElement===e&&(this.selectedElement=null),this.renderElementsView()):this.showNotification("Cannot delete this element","warning")}renderTableHTML(e,t){if(!e||"object"!=typeof e)return`<div class="tc-console-table-wrap"><span class="tc-json-cmt">Not table data: ${this.escapeHtml(String(e))}</span></div>`;let s,i;s=Array.isArray(e)?e.map((e,t)=>{let s={"(idx)":t};return e&&"object"==typeof e?Object.assign(s,e):s.value=e,s}):Object.entries(e).map(([e,t])=>{let s={"(idx)":e};return t&&"object"==typeof t?Object.assign(s,t):s.value=t,s});let n=new Set;s.forEach(e=>Object.keys(e).forEach(e=>n.add(e))),i=["(idx)",...Array.from(n).filter(e=>"(idx)"!==e)],t&&Array.isArray(t)&&t.length&&(i=["(idx)",...t.filter(e=>"(idx)"!==e)]);let o=e=>{if(void 0===e)return"";if(null===e)return'<span class="tc-json-null">null</span>';if("string"==typeof e)return`<span class="tc-json-string">"${this.escapeHtml(e.substring(0,100))}"</span>`;if("number"==typeof e)return`<span class="tc-json-number">${e}</span>`;if("boolean"==typeof e)return`<span class="tc-json-boolean">${e}</span>`;if("function"==typeof e)return`<span class="tc-json-boolean">ƒ ${e.name||"anonymous"}</span>`;if("object"==typeof e)try{let t=this.safeStringify(e);return`<span class="tc-json-cmt">${this.escapeHtml(t.length>50?t.substring(0,50)+"…":t)}</span>`}catch{return'<span class="tc-json-cmt">{Object}</span>'}return this.escapeHtml(String(e))},a='<div class="tc-console-table-wrap"><table class="tc-console-table"><thead><tr>';return i.forEach(e=>a+=`<th>${this.escapeHtml(String(e))}</th>`),a+="</tr></thead><tbody>",s.forEach(e=>{a+="<tr>",i.forEach(t=>a+=`<td>${o(e[t])}</td>`),a+="</tr>"}),a+="</tbody></table></div>",a}renderLogItemHTML(e,t){if(e.subType){let t="fa fa-table",s=e.timestamp.toLocaleTimeString(),i=this.renderSubTypeContent(e);return`<div class="tc-log-item tc-${e.type}${this.selectedLogId===e.id?" tc-selected":""}" id="tc-log-item-${e.id}"><div class="tc-log-header">${e.count>1?`<div class="tc-log-count">${e.count}</div>`:""}<div class="tc-log-icon"><i class="${t}"></i></div><div class="tc-timestamp">${s}</div></div><div class="tc-log-content">${i}</div></div>`}let s;switch(e.type){case"info":s="fa fa-info-circle";break;case"warn":s="fa fa-exclamation-triangle";break;case"error":s="fa fa-times-circle";break;default:s="fa fa-info"}let i=e.timestamp.toLocaleTimeString();return`<div class="tc-log-item tc-${e.type}${this.selectedLogId===e.id?" tc-selected":""}" id="tc-log-item-${e.id}"><div class="tc-log-header">${e.count>1?`<div class="tc-log-count">${e.count}</div>`:""}<div class="tc-log-icon"><i class="${s}"></i></div><div class="tc-timestamp">${i}</div></div><div class="tc-log-content">${this.formatArgs(e.args,e.id)}</div></div>`}renderLSItemHTML(e,t){let s=this.escapeHtml(e),{displayValue:i,valueType:n,isJSON:o}=this.parseAndTypeCheck(t),a=o?this.highlightJson(i):this.escapeHtml(i),r="";if(o){let e=JSON.parse(t);r=`<div class="tc-ls-value tc-json-tree-container">${this.renderJSONValue(e,"")}</div>`}else r=`<div class="tc-ls-value" title="${this.escapeHtml(i)}"><span class="tc-json-${n}">${"string"===n?'"':""}${a}${"string"===n?'"':""}</span></div>`;return`<div class="tc-ls-item" data-key="${s}"><div class="tc-ls-key-row"><div class="tc-ls-key" title="${this.escapeHtml(s)}">${this.escapeHtml(s)}</div><div class="tc-ls-actions"><button class="tc-ls-action-btn" data-action="edit" data-key="${s}" title="Edit"><i class="fa fa-edit"></i></button><button class="tc-ls-action-btn" data-action="copy" data-key="${s}" title="Copy"><i class="fa fa-copy"></i></button><button class="tc-ls-action-btn" data-action="remove" data-key="${s}" title="Delete"><i class="fa fa-trash"></i></button></div></div>${r}<div class="tc-ls-value-type" title="${n}">Type: ${n}</div></div>`}toggleSearch(e){let t=void 0!==e?e:!this.searchExpanded;this.searchExpanded=t,this.searchBar&&(this.searchBar.style.display=t?"flex":"none"),t&&this.searchInput?this.searchInput.focus():t||(this.searchQuery="",this.searchInput&&(this.searchInput.value=""),this.renderContent())}onAddLSClick(){this.netSending=!1,this.netNewVisible=!1,this.editorState={visible:!0,mode:"ls",key:"",oldKey:"",value:""},this.updateEditorVisibility(),this.lsEditorKeyInput&&(this.lsEditorKeyInput.value="",this.lsEditorKeyInput.focus())}openLSEditor(e){if(this.netSending||this.netNewVisible)return void this.showNotification("Request is being sent, cannot save key-value","warning");let t=this.activeLSFilter||"local",s="";if("session"===t)s=sessionStorage.getItem(e)||"";else if("cookie"===t){let t=encodeURIComponent(e),i=document.cookie.match(new RegExp("(?:^|;\\s)"+t.replace(/([.*+?^${}()|[\]\\])/g,"\\$1")+"=([^;]*)"));s=i?decodeURIComponent(i[1]):""}else s=localStorage.getItem(e)||"";this.netSending=!1,this.netNewVisible=!1,this.editorState={visible:!0,mode:"ls",key:e,oldKey:e,value:s},this.updateEditorVisibility(),this.lsEditorInput&&this.lsEditorInput.focus()}closeLSEditor(){this.editorState.visible=!1,this.editorState.value="",this.updateEditorVisibility()}onEditorSave(){"code"===this.editorState.mode?this.runCode():this.saveLSFromEditor()}saveLSFromEditor(){if(this.netSending||this.netNewVisible)return void this.showNotification("Request is being sent, cannot save key-value","warning");let e,t=this.lsEditorKeyInput?this.lsEditorKeyInput.value.trim():this.editorState.key,s=this.editorState.oldKey,i=this.lsEditorInput?this.lsEditorInput.value:this.editorState.value;if(!t)return void this.showNotification("Key name cannot be empty","warning");try{e=JSON.stringify(JSON.parse(this.fixKeysOnly(i)))}catch{e=i}let n=this.activeLSFilter||"local",o="session"===n?sessionStorage:null;if("cookie"===n)return document.cookie=encodeURIComponent(t)+"="+encodeURIComponent(e)+";path=/",-1===document.cookie.indexOf(encodeURIComponent(t)+"=")&&(document.cookie=encodeURIComponent(t)+"="+encodeURIComponent(e)),this.closeLSEditor(),this.renderLocalStorage(),void this.showNotification('Cookie saved"'+t+'"');let a=o?o.getItem.bind(o):localStorage.getItem.bind(localStorage),r=o?o.setItem.bind(o):localStorage.setItem.bind(localStorage),l=o?o.removeItem.bind(o):localStorage.removeItem.bind(localStorage);if(s&&s!==t){if(null!==a(t))return void this.showNotification('key name"'+t+'" already exists!',"warning");l(s)}else if(!s&&null!==a(t))return void this.showNotification('key name"'+t+'" already exists!',"warning");r(t,e),this.closeLSEditor(),this.renderLocalStorage(),this.showNotification('Key saved"'+t+'"')}onTitleClick(){this.netSending||this.netNewVisible?this.showNotification("Request is being sent, cannot run code","warning"):this.editorState.visible&&"ls"===this.editorState.mode?this.showNotification("Saving key-value, cannot run code","warning"):(this.editorState.visible=!0,this.editorState.mode="code",this.updateEditorVisibility(),this.lsEditorInput&&this.lsEditorInput.focus())}toggleMute(){let e="console",t=this.activeFilter||"all";this.mutedFilters[e]||(this.mutedFilters[e]={}),this.mutedFilters[e][t]=!this.mutedFilters[e][t];let s=this.mutedFilters[e][t],i="all"===t?"all logs":t+" type logs";this.showNotification(s?i+" muted":i+"Resumed ",s?"warning":""),this.updateMuteBtnState()}updateMuteBtnState(){if(!this.muteBtn)return;let e="console",t=this.activeFilter||"all";this.mutedFilters[e]&&this.mutedFilters[e][t]?(this.muteBtn.classList.add("tc-muted"),this.muteBtn.title="Unmute logs"):(this.muteBtn.classList.remove("tc-muted"),this.muteBtn.title="Mute"+("all"===t?"subsequent logs":t+" type logs"))}runCode(){let e=this.lsEditorInput?this.lsEditorInput.value:"";if(e.trim())try{let t=window.eval(e);console.log(`${e}\n> `,t),this.showNotification("Code executed"),this.closeLSEditor()}catch(t){console.error(`${e}\n> Execution failed: ${t}`),this.showNotification("Code execution failed","warning"),this.closeLSEditor()}}setupGestures(){if(!this.contentArea||!this.consoleHeader)return;let e=this.contentArea,t=this.consoleHeader,s=null,i=0,n=0,o=0,a=0,r=!1,l=null,c=0,d=0,h=0,p=!1,u=()=>{let e=this.overlay.querySelectorAll(".tc-tab-btn");return Array.from(e).map(e=>e.dataset.tab)},f=()=>{if("console"===this.currentTab)return["all","log","info","warn","error"];if("network"===this.currentTab)return["all","get","post","put","success","failed"];if("localstorage"===this.currentTab)return["local","session","cookie"];let e=this.pluginViewContainers[this.currentTab];return e&&e.querySelectorAll(".tc-filter-btn").length>1?Array.from(e.querySelectorAll(".tc-filter-btn")).map(e=>e.dataset.type||e.dataset.filter||e.textContent.trim()):null},g=e=>{let t=u(),s=t.indexOf(this.currentTab),i=f();if(i)if("localstorage"===this.currentTab){let t=i.indexOf(this.activeLSFilter||"local")+e;if(t>=0&&t<i.length){this.activeLSFilter=i[t],this.lsFiltersContainer&&this.lsFiltersContainer.querySelectorAll(".tc-filter-btn").forEach(e=>e.classList.toggle("tc-active",e.dataset.lsType===this.activeLSFilter)),this.renderContent();let e=this.lsFiltersContainer&&this.lsFiltersContainer.querySelector('.tc-filter-btn[data-ls-type="'+this.activeLSFilter+'"]');return void this.scrollFilterIntoView(this.lsFiltersContainer,e)}}else if("console"===this.currentTab){let t=i.indexOf(this.activeFilter||"all")+e;if(t>=0&&t<i.length)return this.activeFilter=i[t],this.filterButtons.forEach(e=>e.classList.toggle("tc-active",e.dataset.type===this.activeFilter)),this.updateFilterCounts(),this.renderContent(),void this.scrollFilterIntoView(this.overlay.querySelector("#tc-filtersContainer"),this.filterButtons[t])}else{if("network"!==this.currentTab){let t=this.pluginViewContainers[this.currentTab];if(t){this.enhanceFilterContainers(t);let s=t.querySelectorAll(".tc-filter-btn");if(s.length>1){let t=-1;s.forEach((e,s)=>{e.classList.contains("tc-active")&&(t=s)});let i=t+e;i>=0&&i<s.length&&(s.forEach(e=>e.classList.remove("tc-active")),s[i].classList.add("tc-active"),s[i].click(),this.scrollFilterIntoView(s[i].parentElement,s[i]))}}return}{let t=i.indexOf(this.activeNetFilter||"all")+e;if(t>=0&&t<i.length){this.activeNetFilter=i[t],this.netFiltersEl&&this.netFiltersEl.querySelectorAll(".tc-net-filter-btn").forEach(e=>e.classList.toggle("tc-active",e.dataset.netFilter===this.activeNetFilter)),this.renderNetworkList(),this.updateNetDisableBtn(),this.updateNetFilterCounts();let e=this.netFiltersEl&&this.netFiltersEl.querySelector('.tc-net-filter-btn[data-net-filter="'+this.activeNetFilter+'"]');return void this.scrollFilterIntoView(this.netFiltersEl,e)}}}let n=s+e;if(n>=0&&n<t.length){let e=t[n];"console"===e?(this.activeFilter="all",this.filterButtons&&this.filterButtons.forEach(e=>e.classList.toggle("tc-active","all"===e.dataset.type))):"localstorage"===e&&(this.activeLSFilter="local",this.lsFiltersContainer&&this.lsFiltersContainer.querySelectorAll(".tc-filter-btn").forEach(e=>e.classList.toggle("tc-active","local"===e.dataset.lsType)));let s=this.overlay.querySelector(`.tc-tab-btn[data-tab="${e}"]`);s&&s.click()}};e.addEventListener("touchstart",e=>{if(1!==e.touches.length)return;if(this.editorState.visible)return;let t=e.target.closest(".tc-json-tree-container,.tc-json-preview,.tc-log-content,.tc-console-table-wrap,.tc-system-log-content,.tc-ls-value,.tc-object-preview,.tc-error-stack,.tc-function-preview,.tc-elements-tree");t&&t.scrollWidth>t.clientWidth?s=null:(s=e.touches[0],i=s.clientX,n=s.clientY,o=0,a=0,r=!1)},{passive:!0}),e.addEventListener("touchmove",e=>{if(!s||1!==e.touches.length)return;let t=e.touches[0];o=t.clientX-i,a=t.clientY-n,!r&&Math.abs(o)>15&&Math.abs(o)>1.5*Math.abs(a)&&(r=!0),r&&e.preventDefault()},{passive:!1}),e.addEventListener("touchend",()=>{if(s){if(r){let e=60;o<-e?g(1):o>e&&g(-1)}s=null,r=!1}}),t.addEventListener("touchstart",e=>{1===e.touches.length&&(l=e.touches[0],c=l.clientX,d=l.clientY,h=0,p=!1)},{passive:!0}),t.addEventListener("touchmove",e=>{if(!l||1!==e.touches.length)return;let t=e.touches[0];if(h=t.clientY-d,!p&&h>15&&h>1.5*Math.abs(t.clientX-c)&&(p=!0),p){e.preventDefault();let t=this.overlay.querySelector(".tc-console-container");t&&(t.style.transition="none",t.style.transform=`translateY(${h}px)`)}},{passive:!1}),t.addEventListener("touchend",()=>{if(l){if(p){let e=this.overlay.querySelector(".tc-console-container");h>80?(e&&(e.style.transition="transform .3s ease",e.style.transform="translateY(100%)"),setTimeout(()=>{this.triggerGlobalHook("beforeClose"),this.overlay.classList.remove("tc-active"),e&&(e.style.transition="",e.style.transform=""),this.triggerGlobalHook("afterClose")},300)):e&&(e.style.transition="transform .25s ease",e.style.transform="")}l=null,p=!1}})}updateFilterShadow(e){if(!e)return;let t=e.scrollWidth-e.clientWidth>1;e.classList.toggle("tc-overflow-start",t&&e.scrollLeft>1),e.classList.toggle("tc-overflow-end",t&&e.scrollLeft+e.clientWidth<e.scrollWidth-1)}setupFilterShadow(e){if(!e||e._tcFilterShadow)return;e._tcFilterShadow=!0;let t=()=>this.updateFilterShadow(e);if(e.addEventListener("scroll",t,{passive:!0}),window.ResizeObserver){let s=new ResizeObserver(t);s.observe(e),e._tcFilterRO=s}if(window.MutationObserver){let s=new MutationObserver(t);s.observe(e,{childList:!0,subtree:!0}),e._tcFilterMO=s}t()}scrollFilterIntoView(e,t){if(!e||!t)return;if(e.scrollWidth<=e.clientWidth)return void this.updateFilterShadow(e);let s=t.offsetLeft-(e.clientWidth-t.offsetWidth)/2;s=Math.max(0,Math.min(s,e.scrollWidth-e.clientWidth));try{e.scrollTo({left:s,behavior:"smooth"})}catch(e){}e.scrollLeft!==s&&(e.scrollLeft=s),this.updateFilterShadow(e),setTimeout(()=>this.updateFilterShadow(e),300)}enhanceFilterContainers(e){if(!e)return;let t=new Map;e.querySelectorAll(".tc-filter-btn").forEach(e=>{let s=e.parentElement;s&&!s.dataset.tcFilterEnhanced&&(t.has(s)||t.set(s,[]),t.get(s).push(e))}),t.forEach((e,t)=>{if(e.length>1){t.classList.contains("tc-filters")||t.classList.contains("tc-network-filters")||t.classList.add("tc-filters"),t.dataset.tcFilterEnhanced="1",this.setupFilterShadow(t);let s=t;e.forEach(e=>{e.dataset.orig||(e.dataset.orig=e.textContent.trim()),e.addEventListener("click",()=>this.scrollFilterIntoView(s,e))})}})}updatePluginFilterCounts(e){let t=this.pluginViewContainers[this.currentTab];if(!t)return;let s="object"==typeof e?e:null;t.querySelectorAll(".tc-filter-btn[data-orig]").forEach(e=>{let t=e.dataset.orig,i=e.querySelector("i")?e.querySelector("i").className:"",n=s&&s[e.dataset.type||e.dataset.filter||t]||0;if(e.classList.contains("tc-active")){let s=n>99?"99+":n;e.innerHTML=i?`<i class="${i}"></i> ${t} (${s})`:`${t} (${s})`}else e.innerHTML=i?`<i class="${i}"></i> ${t}`:t})}updateFilterCounts(){if(!this.filterButtons)return;let e=[];"console"===this.currentTab&&(e=this.logs);let t=(e,t)=>e.reduce((e,s)=>s.type===t?e+(s.count||1):e,0),s={all:e.reduce((e,t)=>e+(t.count||1),0),log:t(e,"log"),info:t(e,"info"),warn:t(e,"warn"),error:t(e,"error")};this.filterButtons.forEach(e=>{let t=e.dataset.type,i=s[t]||0;if(e.dataset.originalHtml||(e.dataset.originalHtml=e.innerHTML),e.classList.contains("tc-active")){let t=i>99?"99+":i;e.innerHTML=`${e.dataset.originalHtml} (${t})`}else e.innerHTML=e.dataset.originalHtml})}renderContent(){if(this.triggerGlobalHook("beforeRender",this.currentTab),this.updateControlsVisibility(),this.updateMuteBtnState(),this.consoleOutput.style.display="none",this.localstorageView.style.display="none",this.elementsView.style.display="none",this.networkView&&(this.networkView.style.display="none"),this.netDetailOverlay&&(this.netDetailOverlay.style.display="none"),this.netNewOverlay&&(this.netNewOverlay.style.display=this.netNewVisible?"flex":"none"),this.clearLogsBtn.style.display="none",Object.values(this.pluginViewContainers).forEach(e=>{e.style.display="none"}),["console","network","localstorage","elements"].includes(this.currentTab))switch(this.clearLogsBtn.style.display="block",this.currentTab){case"console":this.consoleOutput.style.display="block",this.renderLogList(this.logs,!1),this.updateFilterCounts();break;case"network":this.clearLogsBtn.style.display="block",this.networkView&&(this.networkView.style.display="flex"),this.renderNetworkPanel();break;case"localstorage":this.localstorageView.style.display="block",this.renderLocalStorage();break;case"elements":this.clearLogsBtn.style.display="none",this.elementsView.style.display="block",this.renderElementsView()}else if(this.pluginViewContainers[this.currentTab]){this.consoleControls.style.display="none";let e=this.pluginViewContainers[this.currentTab];e.style.display="block";let t=Object.keys(this.pluginTabs).find(e=>this.pluginTabs[e].id===this.currentTab);if(t){let s=this.plugins[t];s&&"function"==typeof s.onShow&&s.onShow(),s&&"function"==typeof s.render&&s.render(e),this.enhanceFilterContainers(e)}else{let e=this.pluginTabs[this.currentTab];e&&"function"==typeof e.onShow&&e.onShow()}}this.triggerGlobalHook("afterRender",this.currentTab)}renderLogList(e,t){let s=this.consoleOutput,i="log records";if(!s)return;if(0===e.length)return void this.vsShowMessage(s,`<div class="tc-nolog"><i class="fa fa-info-circle"></i>No ${i}</div>`);let n=[...e];if(this.activeFilter&&"all"!==this.activeFilter&&(n=n.filter(e=>e.type===this.activeFilter)),this.searchQuery){let e,t=this.searchQuery.trim(),s=!1;if(t.startsWith("/")&&t.endsWith("/"))try{let i=t.slice(1,-1),n=i.lastIndexOf("/"),o="";n>0?(o=i.slice(n+1),e=new RegExp(i.slice(0,n),o)):e=new RegExp(i),s=!0}catch{this.showNotification("Invalid regex: "+t),s=!1}let i=s?t:t.toLowerCase();n=n.filter(t=>t.args.some(t=>{let n;return n=t instanceof Error?"[error]":null==t?"null":void 0===t?"undefined":"object"==typeof t?'<span class="tc-json-cmt">{Object}</span>':String(t),s&&e?e.test(n):n.toLowerCase().includes(i.toLowerCase())}))}if(0===n.length)return void this.vsShowMessage(s,`<div class="tc-nolog"><i class="fa fa-search"></i>No matching ${i}</div>`);let o=this.isNearBottom(s),a=s._vs;if(!a)return;a.rafId&&(cancelAnimationFrame(a.rafId),a.rafId=null);let r=a.items&&a.items.length||0,l=r>0&&a.items[0]&&n[0]&&a.items[0].id!==n[0].id;if(a.items=n,a.renderItem=e=>this.renderLogItemHTML(e,t),a.avgHeight<10&&(a.avgHeight=80),a.afterRender=null,o)a.lastStart=-1,a.lastEnd=-1,this.renderViewport(s);else if(r>0&&n.length>=r&&!l&&a.lastEnd>=0){let e=0;for(let t=a.lastEnd;t<n.length;t++)e+=a.heights&&a.heights.get(t)||a.avgHeight;a.bottomSpacer.style.height=e+"px"}else if(l&&r>0){let e=0;for(let t=0;t<r&&t<n.length&&(!a.items[e]||!n[e]||a.items[e].id!==n[e].id);t++)e++;if(e>0&&e<r){let t=new Map;for(let[s,i]of a.heights){let o=s-e;o>=0&&o<n.length&&t.set(o,i)}a.heights=t,a.lastStart=Math.max(-1,a.lastStart-e),a.lastEnd=Math.max(-1,a.lastEnd-e);let i=s.scrollTop;return this.renderViewport(s),void(!a.isAtBottom&&i>0&&(s.scrollTop=i))}let t=s.scrollTop;a.lastStart=-1,a.lastEnd=-1,this.renderViewport(s),t>0&&!a.isAtBottom&&(s.scrollTop=t)}}getParams(e){let t=e.toString();if(/^\s*(?:class|function|async\s+function)/.test(t)){let e=t.indexOf("(");if(-1===e)return"";let s=1,i=e+1;for(;i<t.length;i++){const e=t[i];if("("===e)s++;else if(")"===e&&0===--s)break}return t.slice(e+1,i).replace(/\s+/g,"")}let s=t.indexOf("=>");if(s>0){let e=t.slice(0,s).trim().replace(/^async\s+/,"");if(e.startsWith("(")){let t=1,s=1;for(;s<e.length&&t>0;s++)"("===e[s]?t++:")"===e[s]&&t--;return e.slice(1,s-1).replace(/\s+/g,"")}return e.replace(/\s+/g,"")}return""}renderLogContent(e){let t=[...e.args];if(!t.length)return"";let s=[],i=[],n=0,o=(e=>null===e?'<span class="tc-json-null">null</span>':void 0===e?'<span class="tc-json-null">undefined</span>':e instanceof HTMLElement?`<span class="tc-json-number">${e.constructor.name} &lt;${e.tagName.toLowerCase()}&gt;</span>`:e instanceof Date?e.toISOString():e instanceof Error?`<strong>${e.name}:</strong>${e.message}`:"function"==typeof e?this.isClass(e)?`<span class='tc-json-boolean'>[Class ${e.name||"anonymous"}]</span>`:`<span class='tc-json-boolean'>ƒ ${e.name||"anonymous"}</span><span class='tc-json-cmt'>(${this.getParams(e)})</span>`:"object"==typeof e&&null!==e?`<span class="tc-json-cmt">${e.constructor.name||"Object"} {Object}</span>`:"number"==typeof e?Number.isNaN(e)?'<span class="tc-json-cmt">NaN</span>':isFinite(e)?`<span class="tc-json-number">${e}</span>`:`<span class="tc-json-cmt">${e>0?"Infinity":"-Infinity"}</span>`:"boolean"==typeof e?`<span class="tc-json-boolean">${e}</span>`:String(e).replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\n/g,"<br>"))(t.length>0?t[0]:"").replace(/%%/g,"").replace(/%([dfsioO%])/g,(e,i)=>{if("%"===i)return"%";if("o"===i||"O"===i)return"";let o=t[++n];if(null==o)return e;let a="d"===i||"i"===i?parseInt(o,10)||0:"f"===i?parseFloat(o)||0:String(o);return s.push(a),`{{v${s.length-1}}}`}).replace(/%c/g,()=>(i.push(String(t[++n]||"")),`{{c${i.length-1}}}`)).replace(/\x01/g,"%");s.forEach((e,t)=>o=o.replace(`{{v${t}}}`,e));let a=o.split(/{{c\d+}}/);o=a.map((e,t)=>{if(!t)return e;let s=i[t-1].replace(/"/g,"").split(/\s*;\s*/).filter(e=>e.trim()&&!/\b(position|fixed|absolute|sticky|relative|static|z-index|transform|top|left|right|bottom)\s*:/i.test(e)).join("; ");return s?`<span style="${s}">${e}</span>`:e}).join("");let r=t.slice(n+1);return o+=(o?" ":"")+r.map(e=>null===e?'<span class="tc-json-null">null</span>':void 0===e?'<span class="tc-json-null">undefined</span>':"function"==typeof e?this.isClass(e)?`<span class='tc-json-boolean'>[Class ${e.name||"anonymous"}]</span>`:`<span class='tc-json-boolean'>ƒ ${e.name||"anonymous"}</span><span class='tc-json-cmt'>(${this.getParams(e)})</span>`:e instanceof Error?`<strong>${e.name}:</strong>${e.message}`:e instanceof HTMLElement?`<span class="tc-json-number">${e.constructor.name} &lt;${e.tagName.toLowerCase()}&gt;</span>`:e instanceof Date?`<span class="tc-json-string">${e.toISOString()}</span>`:e instanceof RegExp?`<span class="tc-json-number">${e.toString()}</span>`:e instanceof Map?`<span class="tc-json-boolean">[Map ${e.size}]</span>`:e instanceof Set?`<span class="tc-json-boolean">[Set ${e.size}]</span>`:e instanceof WeakMap?'<span class="tc-json-boolean">[WeakMap]</span>':e instanceof WeakSet?'<span class="tc-json-boolean">[WeakSet]</span>':e instanceof ArrayBuffer?`<span class="tc-json-boolean">[ArrayBuffer ${e.byteLength} bytes]</span>`:e&&"object"==typeof e?`<span class="tc-json-cmt">${e.constructor.name||"Object"} {Object}</span>`:"number"==typeof e?Number.isNaN(e)?'<span class="tc-json-cmt">NaN</span>':isFinite(e)?`<span class="tc-json-number">${e}</span>`:`<span class="tc-json-cmt">${e>0?"Infinity":"-Infinity"}</span>`:"boolean"==typeof e?`<span class="tc-json-boolean">${e}</span>`:String(e).replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\n/g,"<br>")).join("")}copyLog(e,t=!1,s=!1){if(s){let t=this.activeLSFilter||"local",s="session"===t?sessionStorage.getItem(e):"cookie"===t?function(){let t=encodeURIComponent(e),s=document.cookie.match(new RegExp("(?:^|;\\s)"+t.replace(/([.*+?^${}()|[\]\\])/g,"\\$1")+"=([^;]*)"));return s?decodeURIComponent(s[1]):null}():localStorage.getItem(e);if(s)return navigator.clipboard.writeText(s).then(()=>this.showNotification(`Copied"${e}" value`)).catch(e=>console.error("Copy failed:",e))}let i=this.logs.find(t=>t.id===e);if(!i)return;let n="";i.count>1&&(n+=`[repeated ${i.count} times] `),i.args.forEach((e,t)=>{t>0&&(n+=" ");try{e instanceof HTMLElement?n+=e.outerHTML.replace(/>/g,">\n"):n+=null!==e&&"object"==typeof e?this.safeStringify(e).replace(/\\u000[23]/g,""):"function"==typeof e?`ƒ ${e.name||"anonymous"}(${this.getParams(e)})`:null===e?"null":void 0===e?"undefined":String(e)}catch{n+="{object}"}}),navigator.clipboard.writeText(n).then(()=>this.showNotification("Copied to clipboard")).catch(e=>console.error("Copy failed:",e))}clearAllLogs(e=!1){if(this.triggerGlobalHook("beforeClear"),"network"!==this.currentTab){if(e)return this.logs=[],this.lastLog=null,this.renderContent(),void this.updateFilterCounts();if("localstorage"==this.currentTab){let e=this.activeLSFilter||"local";return void(confirm("Are you sure you want to clear all "+("local"===e?"Local Storage":"session"===e?"Session Storage":"Cookie")+"? This action cannot be undone.")&&("local"===e?localStorage.clear():"session"===e?sessionStorage.clear():document.cookie.split(";").forEach(e=>{let t=e.split("=")[0].trim();t&&(document.cookie=t+"=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/",document.cookie=t+"=;expires=Thu, 01 Jan 1970 00:00:00 GMT")}),this.renderLocalStorage()))}confirm("Are you sure you want to clear all logs? This action cannot be undone.")&&(this.logs=[],this.lastLog=null,this.renderContent(),this.updateFilterCounts(),this.showNotification("All logs cleared","warning"),this.triggerGlobalHook("afterClear"))}else this.clearNetworkRequests()}updateLSFilterCounts(){if(!this.lsFiltersContainer)return;let e={local:localStorage.length,session:sessionStorage.length,cookie:document.cookie?document.cookie.split(";").filter(e=>e.trim()).length:0};this.lsFiltersContainer.querySelectorAll(".tc-filter-btn").forEach(t=>{let s=t.dataset.orig,i=e[t.dataset.lsType]||0,n=t.querySelector("i")?t.querySelector("i").className:"";if(t.classList.contains("tc-active")){let e=i>99?"99+":i;t.innerHTML=`<i class="${n}"></i>${s} (${e})`}else t.innerHTML=`<i class="${n}"></i>${s}`})}renderLocalStorage(){this.updateLSFilterCounts();let e=this.activeLSFilter||"local",t=[],s="No local storage";if("local"===e){if(!localStorage.length)return void this.vsShowMessage(this.lsItems,'<div class="tc-nolog"><i class="fa fa-database"></i>'+s+"</div>");for(let e=0;e<localStorage.length;e++){let s=localStorage.key(e);t.push({key:s,value:localStorage.getItem(s)})}}else if("session"===e){if(s="No session storage",!sessionStorage.length)return void this.vsShowMessage(this.lsItems,'<div class="tc-nolog"><i class="fa fa-window-restore"></i>'+s+"</div>");for(let e=0;e<sessionStorage.length;e++){let s=sessionStorage.key(e);t.push({key:s,value:sessionStorage.getItem(s)})}}else if("cookie"===e){s="No cookies";let e=document.cookie;if(!e)return void this.vsShowMessage(this.lsItems,'<div class="tc-nolog"><i class="fa fa-cookie-bite"></i>'+s+"</div>");e.split(";").forEach(e=>{let s=e.indexOf("=");if(s>0)try{t.push({key:decodeURIComponent(e.slice(0,s).trim()),value:decodeURIComponent(e.slice(s+1).trim())})}catch{t.push({key:e.slice(0,s).trim(),value:e.slice(s+1).trim()})}else e.trim()&&t.push({key:e.trim(),value:""})})}if(t.sort((e,t)=>e.key.localeCompare(t.key,void 0,{numeric:!0,sensitivity:"base"})),this.searchQuery){let e=this.searchQuery.toLowerCase();t=t.filter(t=>t.key.toLowerCase().includes(e)||(t.value||"").toLowerCase().includes(e))}0!==t.length?this.vsSetItems(this.lsItems,t,e=>this.renderLSItemHTML(e.key,e.value),130):this.vsShowMessage(this.lsItems,'<div class="tc-nolog"><i class="fa fa-search"></i>No matching local storage data</div>')}addLSItemToDOM(e,t){this.renderLocalStorage()}parseAndTypeCheck(e){try{let t=JSON.parse(e);return"object"==typeof t&&null!==t?{displayValue:this.safeStringify(t,2).replace(/</g,"&lt;").replace(/>/g,"&gt;"),valueType:Array.isArray(t)?"array":"object",isJSON:!0}:null==t?{displayValue:null,valueType:null,isJSON:!1}:{displayValue:e,valueType:typeof t,isJSON:!1}}catch{return{displayValue:e,valueType:"string",isJSON:!1}}}isLSEmpty(){let e=this.activeLSFilter||"local";return"local"===e?0===localStorage.length:"session"===e?0===sessionStorage.length:"cookie"===e?!document.cookie:!Array.from({length:localStorage.length},(e,t)=>localStorage.key(t)).some(e=>(e||"").trim())}escapeHtml(e){return String(e).replace(/</g,"&lt;").replace(/>/g,"&gt;")}addLSItem(){this.onAddLSClick()}editLSItem(e){this.openLSEditor(e)}saveLSItem(){this.onEditorSave()}fixKeysOnly(e){try{return JSON.parse(e),e}catch{return e.replace(/([{,])\s*([a-zA-Z_]\w*)\s*:/g,'$1"$2":').replace(/(":)\s*(?!true|false|null|\d+(\.\d+)?)([^\s,"{[}\]]+?)\s*(?=,|})/gs,'$1"$3"')}}cancelEditLSItem(){this.closeLSEditor()}removeLSItem(e){let t=this.activeLSFilter||"local",s="local"===t?"Local Storage":"session"===t?"Session Storage":"Cookie";if(confirm("Delete all "+s+"?\nOK=Delete all "+s+', Cancel=Delete only "'+e+'"'))"session"===t?sessionStorage.clear():"cookie"===t?document.cookie.split(";").forEach(e=>{let t=e.split("=")[0].trim();t&&(document.cookie=t+"=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/",document.cookie=t+"=;expires=Thu, 01 Jan 1970 00:00:00 GMT")}):localStorage.clear(),this.renderLocalStorage(),this.showNotification("Cleared "+s);else{if("session"===t)sessionStorage.removeItem(e);else if("cookie"===t){let t=encodeURIComponent(e);document.cookie=t+"=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/",document.cookie=t+"=;expires=Thu, 01 Jan 1970 00:00:00 GMT"}else localStorage.removeItem(e);this.renderLocalStorage(),this.showNotification('Deleted "'+e+'"')}}findLSItem(e){return this.overlay.querySelector(`.tc-ls-item[data-key="${e}"]`)}updateLSItemView(e){let t=this.findLSItem(e);if(!t)return;let s=localStorage.getItem(e);if(null===s)return void t.remove();let{displayValue:i,valueType:n,isJSON:o}=this.parseAndTypeCheck(s),a=o?this.highlightJson(i):this.escapeHtml(i),r="";if(o){let e=JSON.parse(s);r=`<div class="tc-ls-value tc-json-tree-container">${this.renderJSONValue(e,"")}</div>`}else r=`<div class="tc-ls-value" title="${this.escapeHtml(i)}"><span class="tc-json-${n}">${"string"===n?'"':""}${a}${"string"===n?'"':""}</span></div>`;let l=this.escapeHtml(e);t.innerHTML=`<div class="tc-ls-key-row"><div class="tc-ls-key" title="${l}">${l}</div><div class="tc-ls-actions"><button class="tc-ls-action-btn" data-action="edit" data-key="${l}" title="Edit"><i class="fa fa-edit"></i></button><button class="tc-ls-action-btn" data-action="copy" data-key="${l}" title="Copy"><i class="fa fa-copy"></i></button><button class="tc-ls-action-btn" data-action="remove" data-key="${l}" title="Delete"><i class="fa fa-trash"></i></button></div></div>${r}<div class="tc-ls-value-type" title="${n}">Type: ${n}</div>`}setupGlobalEventHandlers(){this.activeFilter="all",this.searchQuery="",this.tCError=e=>{""!==e.filename||0!==e.lineno||0!==e.colno?(console.error(e.error.toString(),{errorMessage:e.message||"No message",filename:e.filename||"unknown",location:`${e.lineno}:${e.colno}`||"0:0",isTrusted:e.isTrusted||!0,type:e.type||"error"}),e.preventDefault()):console.error("Script error")},this.tCUR=e=>{console.error("Unhandled Promise Rejection",e.reason),e.preventDefault()},this.RSError=e=>{let t=new Set(["IMG","SCRIPT","LINK","VIDEO","AUDIO","SOURCE","TRACK"]),s=e.target;if(!t.has(s.tagName))return;let i=s.src||s.href||s.currentSrc||"[unknown path]";console.error(`[Resource Error] <${s.tagName.toLowerCase()}> load failed: ${i}`)},document.addEventListener("error",this.RSError,!0),window.addEventListener("error",this.tCError),window.addEventListener("unhandledrejection",this.tCUR)}setupSelfProtection(){if(this.protectInterval)return;let e=this;this.protectInterval=setInterval(()=>{window.thinConsole&&window.thinConsole.tC!==e&&(window.thinConsole.tC=e);let t=document.getElementById("tc-thinConsole-btn");t&&document.documentElement.contains(t)?"flex"!==t.style.display&&(t.style.display="flex"):(e.btn=null,e.createButton());let s=document.getElementById("tc-consoleOverlay");s&&document.documentElement.contains(s)?"flex"!==s.style.display&&(s.style.display="flex"):(e.overlay=null,e.createOverlayElement(),e.createStyles());let i=document.head.querySelector("style[tcstyle]");(!i||!i.innerHTML||i.innerHTML.length<100)&&e.createStyles();let n=document.getElementById("tc-notification");n&&document.documentElement.contains(n)?"block"!==n.style.display&&(n.style.display="block"):(e.notification=null,e.createNotificationElement());let o=e=>{if(!e||1!==e.nodeType)return;let t=e=>{"false"!==e.contentEditable&&(e.contentEditable="false",e.setAttribute("tc-lock",""),a.observe(e,{attributes:!0,attributeFilter:["contenteditable"]}))};t(e),e.querySelectorAll("*").forEach(t)},a=new MutationObserver(e=>{e.forEach(e=>{"attributes"===e.type&&"contentEditable"===e.attributeName&&"true"===e.target.contentEditable&&e.target.hasAttribute("tc-lock")&&(e.target.contentEditable="false")})});setTimeout(()=>{o(e.btn),o(e.overlay),o(e.notification)},0)},5e3)}disablePlugin(e){return this.disabledPlugins.includes(e)||this.disabledPlugins.push(e),this.destroyPlugin(e),this}enablePlugin(e){return this.disabledPlugins=this.disabledPlugins.filter(t=>t!==e),this.loadSinglePlugin(e),this}loadSinglePlugin(t){if(!this.disabledPlugins.includes(t)&&e.plugins[t]&&!this.plugins[t]){try{let s=e.plugins[t],i=new s(this,s.config);if(i.init(),this.plugins[t]=i,i.addTab){let e=i.addTab();this.createPluginTab(e),this.pluginTabs[t]={id:e.id,name:e.name,icon:e.icon||"fa fa-plug",plugin:i}}this.triggerGlobalHook("pluginMount",t,i)}catch(e){console.error(`plugin"${t}" load failed: `,e)}return this}}initPlugins(){return Object.keys(e.plugins).forEach(e=>{this.disabledPlugins.includes(e)||this.loadSinglePlugin(e)}),this}destroyPlugin(e){let t=this.plugins[e];if(!t)return;"function"==typeof t.destroy&&t.destroy();let s=this.pluginTabs[e]?.id;if(s){let e=this.overlay.querySelector(`.tc-tab-btn[data-tab="${s}"]`);e?.remove();let t=this.pluginViewContainers[s];t?.remove(),delete this.pluginViewContainers[s]}return delete this.plugins[e],delete this.pluginTabs[e],this.triggerGlobalHook("pluginUnmount",e),this}triggerGlobalHook(t,...s){return e.hooks[t]&&e.hooks[t].forEach(e=>{try{e.call(this,...s)}catch(e){console.error(`hook"${t}"execution error:`,e)}}),this}destroy(){e.tC===this&&(Object.assign(console,this.originalConsole),Object.keys(this.plugins).forEach(e=>this.destroyPlugin(e)),clearInterval(this.protectInterval),clearInterval(this.themeChangeHandler),this.btn?.remove(),document.head.querySelector("style[tcstyle]")?.remove(),this.overlay?.remove(),this.notification?.remove(),document.removeEventListener("error",this.RSError,!0),window.removeEventListener("error",this.tCError),window.removeEventListener("unhandledrejection",this.tCUR),this.originalXHR&&(window.XMLHttpRequest=this.originalXHR),this.originalFetch&&(window.fetch=this.originalFetch),e.tC=null)}captureNetworkRequests(){this.originalXHR=this.originalXHR||window.XMLHttpRequest;let e=this,t=this.originalXHR;window.XMLHttpRequest=function(){let s=new t,i={id:++e._netReqId||1,url:"",method:"GET",status:0,statusText:"",reqHeaders:{},reqBody:null,resHeaders:{},resBody:null,startTime:0,endTime:0,duration:0,error:null};e._netReqId=e._netReqId||1;let n=s.open;s.open=function(e,t){return i.method=e.toUpperCase(),i.url=t,n.apply(s,arguments)};let o=s.send;s.send=function(t){if(e.netDisabledTypes.size>0){let t=i.method.toLowerCase();if(e.netDisabledTypes.has("all")||e.netDisabledTypes.has(t)||e.netDisabledTypes.has("success")||e.netDisabledTypes.has("failed"))return}i.reqBody=t,i.startTime=Date.now();let n={...i};return e.networkRequests.push(n),"network"===e.currentTab&&e.renderNetworkList(),s.addEventListener("loadend",function(){n.status=s.status,n.statusText=s.statusText,n.endTime=Date.now(),n.duration=n.endTime-n.startTime;try{n.resBody=s.responseText}catch(e){}try{let e={};s.getAllResponseHeaders().trim().split("\n").forEach(t=>{let s=t.indexOf(":");s>0&&(e[t.slice(0,s).trim()]=t.slice(s+1).trim())}),n.resHeaders=e}catch(e){}"network"===e.currentTab&&e.renderNetworkList()}),s.addEventListener("error",function(){n.error="Network Error",n.status=0,n.endTime=Date.now(),n.duration=n.endTime-n.startTime,"network"===e.currentTab&&e.renderNetworkList()}),o.apply(s,arguments)};let a=s.setRequestHeader;return s.setRequestHeader=function(e,t){return i.reqHeaders[e]=t,a.apply(s,arguments)},s},this.originalFetch=this.originalFetch||window.fetch;let s=this.originalFetch;window.fetch=function(t,i){let n="string"==typeof t?t:t.url,o=(i&&i.method||"GET").toUpperCase();if(e.netDisabledTypes.size>0){let t=o.toLowerCase();if(e.netDisabledTypes.has("all")||e.netDisabledTypes.has(t)||e.netDisabledTypes.has("success")||e.netDisabledTypes.has("failed"))return Promise.reject(new Error("Request disabled by thinConsole"))}let a={id:++e._netReqId,url:n,method:o,status:0,statusText:"",reqHeaders:{},reqBody:null,resHeaders:{},resBody:null,startTime:Date.now(),endTime:0,duration:0,error:null};return i&&i.headers&&(i.headers instanceof Headers?i.headers.forEach((e,t)=>a.reqHeaders[t]=e):"object"==typeof i.headers&&Object.assign(a.reqHeaders,i.headers)),i&&i.body&&(a.reqBody=i.body),e.networkRequests.push(a),"network"===e.currentTab&&e.renderNetworkList(),s.apply(window,arguments).then(t=>(this.netSending=!1,a.status=t.status,a.statusText=t.statusText,a.endTime=Date.now(),a.duration=a.endTime-a.startTime,t.clone().text().then(e=>{a.resBody=e}).catch(()=>{}),t.headers.forEach((e,t)=>a.resHeaders[t]=e),"network"===e.currentTab&&e.renderNetworkList(),t)).catch(t=>{throw this.netSending=!1,a.error=t.message,a.status=0,a.endTime=Date.now(),a.duration=a.endTime-a.startTime,"network"===e.currentTab&&e.renderNetworkList(),t})}}renderNetFilters(){this.netFiltersEl&&(this.netFiltersEl.innerHTML=[{id:"all",name:"All",icon:"fa fa-list"},{id:"get",name:"GET",icon:"fa fa-download"},{id:"post",name:"POST",icon:"fa fa-upload"},{id:"put",name:"PUT",icon:"fa fa-pen"},{id:"success",name:"Success",icon:"fa fa-check-circle"},{id:"failed",name:"Failed",icon:"fa fa-times-circle"}].map(e=>`<button class="tc-net-filter-btn ${this.activeNetFilter===e.id?"tc-active":""}" data-net-filter="${e.id}" data-orig="${e.name}"><i class="${e.icon}"></i> ${e.name}</button>`).join(""),this.netFiltersEl.querySelectorAll(".tc-net-filter-btn").forEach(e=>{e.addEventListener("click",()=>{this.netFiltersEl.querySelectorAll(".tc-net-filter-btn").forEach(e=>e.classList.remove("tc-active")),e.classList.add("tc-active"),this.activeNetFilter=e.dataset.netFilter,this.renderNetworkList(),this.updateNetDisableBtn(),this.scrollFilterIntoView(this.netFiltersEl,e)})}),this.updateNetFilterCounts())}updateNetFilterCounts(){if(!this.netFiltersEl)return;let e=this.networkRequests,t={all:e.length,get:e.filter(e=>"get"===e.method.toLowerCase()).length,post:e.filter(e=>"post"===e.method.toLowerCase()).length,put:e.filter(e=>"put"===e.method.toLowerCase()).length,success:e.filter(e=>e.status>=200&&e.status<400).length,failed:e.filter(e=>0===e.status||e.status>=400||e.error).length};this.netFiltersEl.querySelectorAll(".tc-net-filter-btn").forEach(e=>{let s=e.dataset.orig,i=t[e.dataset.netFilter]||0,n=e.querySelector("i")?e.querySelector("i").className:"";if(e.classList.contains("tc-active")){let t=i>99?"99+":i;e.innerHTML=`<i class="${n}"></i> ${s} (${t})`}else e.innerHTML=`<i class="${n}"></i> ${s}`})}updateNetDisableBtn(){if(!this.netDisableBtn)return;let e=this.activeNetFilter,t="";"all"===e?t="All":"get"===e?t="GET":"post"===e?t="POST":"put"===e?t="PUT":"success"===e?t="Success (All)":"failed"===e&&(t="Failed (All)");let s=this.netDisabledTypes.has(e);this.netDisableBtn.innerHTML='<i class="fa fa-ban"></i>',this.netDisableBtn.title=s?`Disabled ${t} requests`:`Disable ${t} requests`,this.netDisableBtn.classList.toggle("tc-disabled",s)}toggleNetDisable(){let e=this.activeNetFilter,t="";if("all"===e?t="All":"get"===e?t="GET":"post"===e?t="POST":"put"===e?t="PUT":"success"===e?t="Success (All)":"failed"===e&&(t="Failed (All)"),this.netDisabledTypes.has(e)){this.netDisabledTypes.delete(e);var s=!1}else this.netDisabledTypes.add(e),s=!0;this.updateNetDisableBtn(),this.showNotification(s?`Disabled ${t} requests`:`Resumed ${t} requests`,s?"warning":"")}getFilteredNetRequests(){let e=this.networkRequests;if(!this.activeNetFilter||"all"===this.activeNetFilter)return e;let t=this.activeNetFilter;return"get"===t||"post"===t||"put"===t?e.filter(e=>e.method.toLowerCase()===t):"success"===t?e.filter(e=>e.status>=200&&e.status<400):"failed"===t?e.filter(e=>0===e.status||e.status>=400||e.error):e}renderNetworkList(){if("network"!==this.currentTab)return;if(!this.networkItems)return;let e=this.getFilteredNetRequests();if(this.searchQuery){let t=this.searchQuery.toLowerCase();e=e.filter(e=>{if(e.url.toLowerCase().includes(t))return!0;if(e.method.toLowerCase().includes(t))return!0;try{if(this.safeStringify(e.reqHeaders).toLowerCase().includes(t))return!0}catch(e){}try{if(("string"==typeof e.reqBody?e.reqBody:this.safeStringify(e.reqBody)).toLowerCase().includes(t))return!0}catch(e){}try{if(this.safeStringify(e.resHeaders).toLowerCase().includes(t))return!0}catch(e){}return!!(e.resBody||"").toLowerCase().includes(t)})}if(this.updateNetFilterCounts(),0===e.length)return void(this.networkItems.innerHTML='<div class="tc-nolog"><i class="fa fa-wifi"></i>No network requests</div>');let t=this.networkItems,s=t.scrollHeight-t.scrollTop-t.clientHeight<50;t.innerHTML=e.slice(-200).map(e=>this.renderNetworkItem(e)).join(""),s&&(t.scrollTop=t.scrollHeight)}renderNetworkItem(e){let t=e.status>0?Math.floor(e.status/100)+"xx":"pending",s=e.error||e.status>=400?"tc-net-failed":e.status>=200&&e.status<400?"tc-net-success":"",i=e.status>0?String(e.status):e.error?"ERR":"...",n=e.duration>0?e.duration+"ms":"",o=n?i+" "+n:i,a="";try{a=new Date(e.startTime).toLocaleTimeString()}catch(e){a=""}return`<div class="tc-net-item ${s}" data-req-id="${e.id}"><div class="tc-net-row1"><span class="tc-net-method tc-net-method-${e.method}">${e.method}</span><span class="tc-net-time">${this.escapeHtml(a)}</span></div><div class="tc-net-row2"><span class="tc-net-url" title="${this.escapeHtml(e.url)}">${this.escapeHtml(e.url)}</span><span class="tc-net-status tc-net-status-${t}">${this.escapeHtml(o)}</span></div><div class="tc-net-row3"><button class="tc-net-copy-btn" data-action="copy" title="Copy request JSON"><i class="fa fa-copy"></i> Copy</button><button class="tc-net-detail-btn" data-action="detail" title="View Details"><i class="fa fa-eye"></i> Details</button></div></div>`}renderNetJsonTree(e,t){try{let s=JSON.parse(e);return null==s?this.highlightJson(this.escapeHtml(e)):'<div class="tc-json-tree-container">'+this.renderJSONTree(s,"",null,null,t,0,!0)+"</div>"}catch(t){return this.highlightJson(this.escapeHtml(e))}}showNetDetail(e){let t=this.networkRequests.find(t=>t.id===e);if(!t)return;this.netDetailId=e;let s=t.status>0?Math.floor(t.status/100)+"xx":"pending",i=t.status>0?t.status+" "+(t.statusText||""):t.error||"Pending...",n=t.duration>0?t.duration+"ms":"",o=n?i+" ("+n+")":i,a="";try{a=this.safeStringify(t.reqHeaders,2)}catch(e){a=String(t.reqHeaders||"")}let r=!a||"{}"===a||"null"===a,l=r?'<span class="tc-net-detail-empty">No request headers</span>':this.renderNetJsonTree(a,"net-"+e+"-reqHeaders"),c="";if(t.reqBody)try{c="string"==typeof t.reqBody?t.reqBody:this.safeStringify(t.reqBody,2)}catch(e){c=String(t.reqBody)}let d=!c||"null"===c||"undefined"===c,h=d?'<span class="tc-net-detail-empty">No request body</span>':this.renderNetJsonTree(c,"net-"+e+"-reqBody"),p="";try{p=this.safeStringify(t.resHeaders,2)}catch(e){p=String(t.resHeaders||"")}let u=!p||"{}"===p||"null"===p,f=u?'<span class="tc-net-detail-empty">No response headers</span>':this.renderNetJsonTree(p,"net-"+e+"-resHeaders"),g=t.resBody||"",m="";if(g)try{m=JSON.stringify(JSON.parse(g),null,2)}catch(e){m=g}let b=!m||"null"===m||"undefined"===m,y=b?'<span class="tc-net-detail-empty">No response body</span>':this.renderNetJsonTree(m,"net-"+e+"-resBody"),v=(e,t,s,i)=>`<div class="tc-net-detail-section"><div class="tc-net-detail-section-header"><div class="tc-net-detail-label">${e}</div>${i?"":`<button class="tc-net-detail-copy-section" data-copy-text="${this.escapeHtml(s)}" title="Copy"><i class="fa fa-copy"></i></button>`}</div><div class="${i||t.indexOf("tc-json-tree-container")>=0?"tc-net-detail-value":"tc-net-detail-value tc-net-detail-code"}">${t}</div></div>`,x=`<div class="tc-net-detail-section"><div class="tc-net-detail-section-header"><div class="tc-net-detail-label">URL</div><button class="tc-net-detail-copy-section" data-copy-text="${this.escapeHtml(t.url)}" title="Copy URL"><i class="fa fa-copy"></i></button></div><div class="tc-net-detail-value tc-net-detail-code">${this.escapeHtml(t.url)}</div></div>`,w=`<div class="tc-net-detail-section"><div class="tc-net-detail-section-header"><div class="tc-net-detail-label">Method</div></div><span class="tc-net-method tc-net-method-${t.method}">${t.method}</span></div>`,k=`<div class="tc-net-detail-section"><div class="tc-net-detail-section-header"><div class="tc-net-detail-label">Status</div></div><span class="tc-net-status tc-net-status-${s}">${this.escapeHtml(o)}</span></div>`,S=v("Request Headers",l,a,r),E=v("Request Body",h,c,d),T=v("Response Headers",f,p,u),L=v("Response Body",y,m,b);this.netDetailBody.innerHTML=x+w+k+S+E+T+L,this.netDetailBody.querySelectorAll(".tc-net-detail-copy-section").forEach(e=>{e.addEventListener("click",()=>{let t=e.getAttribute("data-copy-text")||"";navigator.clipboard.writeText(t).then(()=>this.showNotification("Copied")).catch(()=>{})})});let C=this.overlay.querySelector("#tc-netResendIconBtn");C&&C.addEventListener("click",()=>this.resendRequest(t)),this.netDetailOverlay.style.display="flex"}resendRequest(e){this.netDetailOverlay.style.display="none",this.netNewOverlay.style.display="flex",this.netNewUrl.value=e.url,this.netNewMethod.value=e.method;let t="";if(e.reqBody)try{t="string"==typeof e.reqBody?e.reqBody:JSON.stringify(e.reqBody,null,2)}catch(e){t=""}this.netNewBody.value=t||"";let s="";try{e.reqHeaders&&"object"==typeof e.reqHeaders&&(s=(Array.isArray(e.reqHeaders)?e.reqHeaders:Object.entries(e.reqHeaders)).map(e=>Array.isArray(e)?e[0]+": "+e[1]:e).join("\n"))}catch(e){}this.netNewHeaders.value=s||""}sendNewRequest(){if(this.editorState.visible){let e=this.editorState.mode;if("code"===e)return void this.showNotification("Code is running, cannot send request","warning");if("ls"===e)return void this.showNotification("Saving key-value, cannot send request","warning")}let e=this.netNewUrl.value.trim();if(!e)return void this.showNotification("Please enter URL","warning");let t=this.netNewMethod.value,s=this.netNewBody.value.trim(),i=this.netNewHeaders.value.trim(),n={};i&&i.split("\n").forEach(e=>{let t=e.indexOf(":");t>0&&(n[e.slice(0,t).trim()]=e.slice(t+1).trim())});let o={method:t,headers:n};if(s&&"GET"!==t&&"HEAD"!==t)try{o.body=JSON.stringify(JSON.parse(s)),n["Content-Type"]||(n["Content-Type"]="application/json")}catch(e){o.body=s}this.netSending=!0,this.netNewVisible=!1,this.netNewOverlay.style.display="none",this.showNotification("Sending request...");let a={id:++this._netReqId,url:e,method:t,status:0,statusText:"",reqHeaders:n,reqBody:o.body||null,resHeaders:{},resBody:null,startTime:Date.now(),endTime:0,duration:0,error:null};this.networkRequests.push(a),(this.originalFetch||window.fetch).call(window,e,o).then(e=>{this.netSending=!1,a.status=e.status,a.statusText=e.statusText,a.endTime=Date.now(),a.duration=a.endTime-a.startTime,e.clone().text().then(e=>{a.resBody=e}).catch(()=>{}),e.headers.forEach((e,t)=>a.resHeaders[t]=e),this.showNotification("Request completed: "+e.status,e.status>=400?"warning":""),"network"===this.currentTab&&this.renderNetworkList()}).catch(e=>{this.netSending=!1,a.error=e.message,a.status=0,a.endTime=Date.now(),a.duration=a.endTime-a.startTime,this.showNotification("Request failed: "+e.message,"warning"),"network"===this.currentTab&&this.renderNetworkList()})}renderNetworkPanel(){this.renderNetFilters(),this.updateNetDisableBtn(),this.renderNetworkList()}clearNetworkRequests(){let e=this.activeNetFilter||"all",t="";"all"===e?t="All":"get"===e?t="GET":"post"===e?t="POST":"put"===e?t="PUT":"success"===e?t="Success":"failed"===e&&(t="Failed");let s=this.getFilteredNetRequests();if(confirm("Are you sure you want to clear all "+t+" requests?\n"+s.length+" requests will be deleted. This action cannot be undone.")){if("all"===e)this.networkRequests=[];else{let t="get"===e||"post"===e||"put"===e?t=>t.method.toLowerCase()!==e:"success"===e?e=>!(e.status>=200&&e.status<400):e=>!(0===e.status||e.status>=400||e.error);this.networkRequests=this.networkRequests.filter(t)}this.renderNetworkList(),this.showNotification("Cleared "+t+" requests")}}switchTab(e){let t=Array.from(this.tabButtons).find(t=>t.dataset.tab===e);t&&t.click()}show(e="console"){return this.overlay||this.createOverlayElement(),this.switchTab(e),this.triggerGlobalHook("beforeOpen"),this.overlay.classList.add("tc-active","tc-theme-"+this.currentTheme),this.triggerGlobalHook("afterOpen"),this}hide(){return this.overlay&&(this.triggerGlobalHook("beforeClose"),this.overlay.classList.remove("tc-active"),this.triggerGlobalHook("afterClose")),this}}e.plugins={},window.thinConsole=e,e.tC=null,e.hooks={beforeRender:[],afterRender:[],beforeLog:[],afterLog:[],beforeOpen:[],afterOpen:[],beforeClose:[],afterClose:[],beforeClear:[],afterClear:[],pluginMount:[],pluginUnmount:[]},e.show=t=>(e.tC?.show(t),e),e.hide=()=>(e.tC?.hide(),e),e.destroy=()=>e.tC?.destroy(),e.log=(...t)=>(console.log(...t),e),e.info=(...t)=>(console.info(...t),e),e.warn=(...t)=>(console.warn(...t),e),e.error=(...t)=>(console.error(...t),e),e.addPlugin=function(s,i,n={}){if(e.tC){if(i.prototype instanceof t){if(i.config=n,e.plugins[s]=i,e.tC.disabledPlugins.includes(s))return;if(e.tC.pluginEnabled&&!e.tC.plugins[s])try{let t=new i(e.tC,n);if(t.init(),e.tC.plugins[s]=t,t.addTab){let i=t.addTab();e.tC.pluginTabs[s]={id:i.id,name:i.name,icon:i.icon||"fa fa-tool",plugin:t},e.tC.createPluginTab(i)}e.tC.triggerGlobalHook("pluginMount",s,t)}catch(i){console.error(`plugin"${s}"dynamic load failed:`,i)}}else{if("function"!=typeof i)throw new Error(`plugin"${s}"must be a class or functionType`);if(!e.tC.options.plugins||e.tC.disabledPlugins.includes(s))return;try{i.call(null,e.tC,n),e.tC.triggerGlobalHook("pluginMount",s,null)}catch(i){console.error(`Functionplugin"${s}"Execution failed: `,i)}}return e}},e.addTabs=function(t){if(!e.tC)return e;Array.isArray(t)||(t=[t]);for(let s of t){if(e.tC.customTabCount>=5){console.warn("Custom tab limit reached (5)");break}if(!s.id||!s.name){console.warn("Tab must contain id and name properties");continue}if(e.tC.pluginViewContainers[s.id]){console.warn("Tab ID '"+s.id+"' already exists");continue}e.tC.createPluginTab({id:s.id,name:s.name,icon:s.icon||"fa fa-plug"});let t=e.tC.pluginViewContainers[s.id];t&&(t.innerHTML="","function"==typeof s.render?s.render(t):s.html&&(t.innerHTML=s.html),s.onShow&&(e.tC.pluginTabs[s.id]={id:s.id,name:s.name,icon:s.icon||"fa fa-plug",onShow:s.onShow})),e.tC.customTabCount++}return e},e.addHook=function(t,s){return e.hooks[t]&&!e.hooks[t].includes(s)?e.hooks[t].push(s):console.warn(`unknownhook:${t}`),e},e.removeHook=function(t,s){return e.hooks[t]&&(e.hooks[t]=e.hooks[t].filter(e=>e!==s)),e},e.setFilterCounts=function(t){return e.tC&&e.tC.updatePluginFilterCounts(t),e};class t{constructor(t,s={}){if(!(t instanceof e))throw new Error("must be bound to a thinConsole instance");this.tC=t,this.config=s,this.id=this.constructor.name.toLowerCase()}init(){}iszh(){return!0}isen(){return!1}isMobile(){return/iPad|Android(?!.*Mobile)|Mobi|Android|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)}render(e){}onShow(){}onHide(){}destroy(){}}return e.tCPlugin=t,"undefined"!=typeof window&&(window.tCPlugin=t),e});
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "@monkey2582/thinconsole",
3
+ "version": "1.2.0",
4
+ "description": "thinConsole是一个轻量级、功能丰富的浏览器端 JavaScript 控制台增强库。它提供了一个可浮动的按钮,点击后可以展开一个功能强大的控制台面板,用于捕获和查看日志、管理本地存储(LocalStorage)、记录系统事件,并支持通过插件系统进行扩展。",
5
+ "keywords": [
6
+ "console",
7
+ "thinconsole",
8
+ "js",
9
+ "debug",
10
+ "jsdebug"
11
+ ],
12
+ "license": "MIT",
13
+ "author": "monkey2582",
14
+ "type": "commonjs",
15
+ "main": "thinConsole.min.js",
16
+ "scripts": {
17
+ "test": "echo \"Error: no test specified\" && exit 1"
18
+ }
19
+ }
@@ -0,0 +1,224 @@
1
+ // Type definitions for thinConsole v1.1.0
2
+ // Project: thinConsole - A lightweight mobile web debugging console
3
+ // UMD module: supports CommonJS, AMD, and global (browser window.thinConsole)
4
+
5
+ // Class + namespace merge: class provides the value & constructor,
6
+ // namespace provides additional types accessible as thinConsole.X
7
+ declare class thinConsole {
8
+ constructor(options?: thinConsole.Options);
9
+
10
+ // ---- Instance properties ----
11
+ version: string;
12
+ options: Required<
13
+ Omit<thinConsole.Options, "filters"> & { filters: thinConsole.Filter[] | null }
14
+ >;
15
+ currentTab: string;
16
+ currentTheme: "light" | "dark";
17
+ selectedElement: Node | null;
18
+ logs: thinConsole.LogEntry[];
19
+ networkRequests: thinConsole.NetworkRequest[];
20
+ maxLog: number;
21
+
22
+ // ---- Instance methods ----
23
+ show(tab?: string): thinConsole;
24
+ hide(): thinConsole;
25
+ destroy(): void;
26
+ switchTab(tab: string): void;
27
+ showNotification(message: string, type?: string): void;
28
+ toggleSearch(visible?: boolean): void;
29
+ toggleMute(): void;
30
+ clearAllLogs(silent?: boolean): void;
31
+ startElementPicker(): void;
32
+ deleteElement(element: Node): void;
33
+ copyElementHTML(element: Element): void;
34
+ expandToElement(element: Node): void;
35
+ getShadowRoot(element: Element): thinConsole.ShadowRootInfo | null;
36
+ registerPlugin(id: string, pluginClass: any, config?: any): thinConsole;
37
+ disablePlugin(id: string): thinConsole;
38
+ enablePlugin(id: string): thinConsole;
39
+ destroyPlugin(id: string): void;
40
+ triggerGlobalHook(name: thinConsole.HookName, ...args: any[]): thinConsole;
41
+ renderJSONTree(
42
+ obj: any,
43
+ key?: string,
44
+ path?: string,
45
+ chain?: any[],
46
+ noProto?: boolean
47
+ ): string;
48
+ renderHTMLTree(
49
+ element: Node,
50
+ key?: string,
51
+ path?: string,
52
+ depth?: number
53
+ ): string;
54
+ renderElementTree(element: Node, depth: number): string;
55
+ escapeHtml(str: string): string;
56
+ captureConsole(type: string, ...args: any[]): void;
57
+
58
+ // ---- Static properties ----
59
+ static readonly version: string;
60
+ static tC: thinConsole | null;
61
+ static plugins: Record<string, any>;
62
+ static hooks: Record<thinConsole.HookName, thinConsole.HookCallback[]>;
63
+
64
+ // ---- Static methods ----
65
+ static show(tab?: string): typeof thinConsole;
66
+ static hide(): typeof thinConsole;
67
+ static destroy(): void;
68
+ static log(...args: any[]): typeof thinConsole;
69
+ static info(...args: any[]): typeof thinConsole;
70
+ static warn(...args: any[]): typeof thinConsole;
71
+ static error(...args: any[]): typeof thinConsole;
72
+ static addPlugin(id: string, pluginClass: any, config?: any): typeof thinConsole;
73
+ static addTabs(
74
+ tabs: thinConsole.TabConfig | thinConsole.TabConfig[]
75
+ ): typeof thinConsole;
76
+ static addHook(
77
+ name: thinConsole.HookName,
78
+ callback: thinConsole.HookCallback
79
+ ): typeof thinConsole;
80
+ static removeHook(
81
+ name: thinConsole.HookName,
82
+ callback: thinConsole.HookCallback
83
+ ): typeof thinConsole;
84
+ static setFilterCounts(counts: Record<string, number>): typeof thinConsole;
85
+ }
86
+
87
+ declare namespace thinConsole {
88
+ // ============= Options & Config =============
89
+
90
+ interface Options {
91
+ /** Button text (max 11 chars, no HTML special chars) */
92
+ text?: string;
93
+ /** Button background color */
94
+ color?: string;
95
+ /** Button width (CSS value) */
96
+ width?: string;
97
+ /** Button height (CSS value) */
98
+ height?: string;
99
+ /** Theme mode */
100
+ theme?: "light" | "dark" | "auto";
101
+ /** Enable plugin system */
102
+ plugins?: boolean;
103
+ /** List of disabled plugin IDs */
104
+ disabledPlugins?: string[];
105
+ /** Enable JS code execution via title click */
106
+ jsExecute?: boolean;
107
+ /** Floating button position */
108
+ pos?: { x: number; y: number };
109
+ /** Maximum number of log entries to retain (default: 1000) */
110
+ maxLog?: number;
111
+ /** Custom console filter definitions */
112
+ filters?: Filter[];
113
+ }
114
+
115
+ interface Filter {
116
+ id: string;
117
+ name: string;
118
+ icon?: string;
119
+ }
120
+
121
+ interface TabConfig {
122
+ id: string;
123
+ name: string;
124
+ icon?: string;
125
+ /** Static HTML content for the tab */
126
+ html?: string;
127
+ /** Dynamic render function for the tab content */
128
+ render?: (container: HTMLElement) => void;
129
+ /** Called when the tab is shown */
130
+ onShow?: () => void;
131
+ }
132
+
133
+ interface PluginTab {
134
+ id: string;
135
+ name: string;
136
+ icon: string;
137
+ plugin?: tCPlugin;
138
+ onShow?: () => void;
139
+ }
140
+
141
+ // ============= Data Interfaces =============
142
+
143
+ interface NetworkRequest {
144
+ id: number;
145
+ url: string;
146
+ method: string;
147
+ status: number;
148
+ statusText: string;
149
+ reqHeaders: Record<string, string>;
150
+ reqBody: any;
151
+ resHeaders: Record<string, string>;
152
+ resBody: any;
153
+ startTime: number;
154
+ endTime: number;
155
+ duration: number;
156
+ error: any;
157
+ }
158
+
159
+ interface LogEntry {
160
+ id: number;
161
+ type: string;
162
+ args: any[];
163
+ time: number;
164
+ stack?: string;
165
+ subType?: string;
166
+ extra?: any;
167
+ }
168
+
169
+ interface ShadowRootInfo {
170
+ root: ShadowRoot;
171
+ mode: "open" | "closed";
172
+ }
173
+
174
+ // ============= Hooks =============
175
+
176
+ type HookName =
177
+ | "beforeRender"
178
+ | "afterRender"
179
+ | "beforeLog"
180
+ | "afterLog"
181
+ | "beforeOpen"
182
+ | "afterOpen"
183
+ | "beforeClose"
184
+ | "afterClose"
185
+ | "beforeClear"
186
+ | "afterClear"
187
+ | "pluginMount"
188
+ | "pluginUnmount";
189
+
190
+ type HookCallback = (...args: any[]) => void;
191
+
192
+ // ============= Plugin Base Class =============
193
+
194
+ class tCPlugin {
195
+ constructor(tC: thinConsole, config?: any);
196
+ /** The thinConsole instance this plugin is bound to */
197
+ tC: thinConsole;
198
+ /** Plugin configuration object */
199
+ config: any;
200
+ /** Plugin ID (auto-derived from class name, lowercased) */
201
+ id: string;
202
+ /** Initialize plugin — override in subclass */
203
+ init(): void;
204
+ /** Whether the current language is Chinese */
205
+ iszh(): boolean;
206
+ /** Whether the current language is English */
207
+ isen(): boolean;
208
+ /** Whether running on a mobile device */
209
+ isMobile(): boolean;
210
+ /** Render plugin content into container — override in subclass */
211
+ render(container: HTMLElement): void;
212
+ /** Called when plugin tab becomes visible — override in subclass */
213
+ onShow(): void;
214
+ /** Called when plugin tab becomes hidden — override in subclass */
215
+ onHide(): void;
216
+ /** Cleanup when plugin is destroyed — override in subclass */
217
+ destroy(): void;
218
+ /** Define a tab for this plugin — override in subclass */
219
+ addTab?(): PluginTab;
220
+ }
221
+ }
222
+
223
+ export = thinConsole;
224
+ export as namespace thinConsole;
@@ -0,0 +1 @@
1
+ !function(t,e){var o=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var o=arguments[e];for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])}return t};function n(t){return String(t).replace(/</g,"&lt;").replace(/>/g,"&gt;")}function i(t){var o=e.createElement("textarea");o.value=t,e.body.appendChild(o),o.select();try{e.execCommand("copy")}catch(t){}e.body.removeChild(o)}function s(t){return t.getHours()+":"+("0"+t.getMinutes()).slice(-2)+":"+("0"+t.getSeconds()).slice(-2)}function a(t){return'<i class="fa '+({info:"fa-info-circle",warn:"fa-exclamation-triangle",error:"fa-times-circle",log:"fa-info"}[t]||"fa-info")+'"></i>'}function l(t){if(!e.querySelector(".conbtn")){this.logs=[],this.systemLogs=[],this.lastLog=null,this.currentTab="console",this.activeFilter="all",this.searchQuery="";var n={position:{x:30,y:30},text:"thinConsole",color:"#007aff",width:"auto",height:"auto",id:"consoleBtn-"+Date.now(),autoShow:!0,theme:"light",maxLog:1e3};this.options=o({},n,t||{}),this.init()}}l.prototype.init=function(){this.injectCSS(),this.createButton(),this.createOverlay(),this.createNotification(),this.captureConsole(),this.bindEvents(),this.options.autoShow&&this.setInitialPosition(),t.thinConsole.tC=t.thinConsole.tC||{},t.thinConsole.tC[this.options.id]=this,this.renderContent()},l.prototype.injectCSS=function(){if(!e.getElementById("tc-lite-css")){var t=e.createElement("style");t.id="tc-lite-css";var o="dark"===this.options.theme,n=o?"#1e1e1e":"#f5f5f5",i=o?"#ccc":"#333",s=o?"#2c2c2c":"#e0e0e0",a=o?"#444":"#ccc",l=o?"#333":"#fff",r=o?"#ccc":"#333";t.textContent=`\n @import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css");\n .floating-console-btn{position:fixed;z-index:11000;padding:12px 20px;border:none;border-radius:5px;background:#007aff;color:#fff;font-size:14px;cursor:pointer;box-shadow:0 4px 12px rgba(0,0,0,.3);}\n .overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.85);z-index:99998;display:none;}\n .overlay.active{display:block;}\n .console-container{position:fixed;bottom:0;left:0;width:100%;height:90%;background:${n};color:${i};display:flex;flex-direction:column;box-shadow:0 -4px 20px rgba(0,0,0,.3);}\n .console-header{display:flex;justify-content:space-between;align-items:center;padding:10px 15px;background:${s};}\n .console-title{display:flex;align-items:center;gap:8px;font-weight:bold;}\n .close-btn,.clear-all-btn{background:transparent;border:none;font-size:20px;cursor:pointer;padding:4px 8px;border-radius:3px;color:${i};}\n .tabs{display:flex;background:${s};border-bottom:1px solid ${a};}\n .tab-btn{padding:8px 16px;border:none;background:transparent;color:${i};cursor:pointer;}\n .tab-btn.active{background:${n};font-weight:bold;}\n .controls{display:flex;padding:8px 12px;gap:8px;background:${s};border-bottom:1px solid ${a};}\n .filter-btn{padding:6px 10px;border:none;background:transparent;color:${i};cursor:pointer;}\n .filter-btn.active{background:#007aff;color:#fff;border-radius:4px;}\n .search-box{flex:1;max-width:300px;}\n .search-box input{width:100%;padding:6px 10px;border:1px solid ${a};border-radius:4px;background:${l};color:${r};}\n .console-content{flex:1;overflow:hidden;display:flex;flex-direction:column;}\n .console-output,.localstorage-view,.system-logs{flex:1;overflow-y:auto;padding:10px;font-family:monospace;font-size:13px;background:${n};color:${i};}\n .log-item{display:flex;gap:8px;padding:8px;margin-bottom:6px;border-left:3px solid #007aff;border-radius:4px;background:${l};}\n .log-item.warn{border-left-color:#f0ad4e;}\n .log-item.error{border-left-color:#d9534f;}\n .log-icon{width:20px;text-align:center;}\n .log-content{flex:1;word-break:break-word;color:${i};}\n .timestamp{color:#666;font-size:11px;margin-left:auto;}\n .log-actions{margin-top:4px;font-size:11px;}\n .log-action{cursor:pointer;margin-right:10px;color:#007aff;}\n .nolog{text-align:center;padding:40px;color:#666;}\n .ls-item{background:${l};padding:10px;margin-bottom:8px;border-radius:4px;color:${i};}\n .ls-key-row{display:flex;justify-content:space-between;margin-bottom:6px;}\n .ls-key{font-weight:bold;}\n .ls-actions{display:flex;gap:6px;}\n .ls-action-btn{padding:4px 6px;border:none;background:#007aff;color:#fff;border-radius:3px;cursor:pointer;font-size:12px;}\n .ls-value{background:${o?"#2a2a2a":"#f6f8fa"};padding:6px;border-radius:3px;white-space:pre-wrap;word-break:break-all;font-size:12px;color:${i};}\n .ls-edit{display:none;margin-top:6px;}\n .ls-edit textarea{width:100%;height:60px;background:${l};color:${r};}\n .ls-edit-actions{text-align:right;margin-top:6px;}\n .notification{position:fixed;top:20px;right:20px;padding:8px 14px;background:#4caf50;color:#fff;border-radius:4px;z-index:99999;display:none;}\n .notification.show{display:block;}\n `,e.head.appendChild(t)}},l.prototype.createButton=function(){var t=e.createElement("button");t.id=this.options.id,t.className="floating-console-btn conbtn",t.textContent=this.options.text,t.style.background=this.options.color,t.style.width=this.options.width,t.style.height=this.options.height,e.documentElement.appendChild(t),this.btn=t},l.prototype.createOverlay=function(){var t=e.createElement("div");t.className="overlay",t.innerHTML=`\n <div class="console-container">\n <div class="console-header">\n <div class="console-title"><i class="fa fa-terminal"></i> ${n(this.options.text)}</div>\n <button class="clear-all-btn" title="清空所有日志"><i class="fa fa-trash-alt"></i></button>\n <button class="close-btn" title="关闭"><i class="fa fa-times"></i></button>\n </div>\n <div class="tabs">\n <button class="tab-btn active" data-tab="console"><i class="fa fa-terminal"></i> 控制台</button>\n <button class="tab-btn" data-tab="system"><i class="fa fa-server"></i> 系统</button>\n <button class="tab-btn" data-tab="localstorage"><i class="fa fa-database"></i> 本地存储</button>\n </div>\n <div class="controls" id="controls">\n <div class="filters">\n <button class="filter-btn active" data-type="all">全部</button>\n <button class="filter-btn" data-type="log">日志</button>\n <button class="filter-btn" data-type="info">信息</button>\n <button class="filter-btn" data-type="warn">警告</button>\n <button class="filter-btn" data-type="error">错误</button>\n </div>\n <div class="search-box"><input id="searchInput" placeholder="搜索日志……"></div>\n </div>\n <div class="console-content">\n <div class="console-output" id="consoleOutput"></div>\n <div class="localstorage-view" id="localstorageView" style="display:none">\n <div class="ls-header"><button id="addLSItemBtn" class="ls-action-btn"><i class="fa fa-plus"></i> 新增条目</button></div>\n <div class="ls-items" id="lsItems"></div>\n </div>\n <div class="system-logs" id="systemLogs" style="display:none"></div>\n </div>\n </div>\n `,e.documentElement.appendChild(t),this.overlay=t,this.closeConsoleBtn=t.querySelector(".close-btn"),this.clearLogsBtn=t.querySelector(".clear-all-btn"),this.consoleOutput=t.querySelector("#consoleOutput"),this.localstorageView=t.querySelector("#localstorageView"),this.lsItems=t.querySelector("#lsItems"),this.systemLogsEl=t.querySelector("#systemLogs"),this.searchInput=t.querySelector("#searchInput"),this.controls=t.querySelector("#controls");var o=this;this.closeConsoleBtn.onclick=function(){o.overlay.classList.remove("active")},this.clearLogsBtn.onclick=function(){o.clearAllLogs()},this.searchInput.oninput=function(){o.searchQuery=this.value.trim().toLowerCase(),o.renderContent()},this.overlay.addEventListener("click",function(t){t.target===o.overlay&&o.overlay.classList.remove("active")});for(var i=t.querySelectorAll(".tab-btn"),s=0;s<i.length;s++)i[s].onclick=function(){for(var t=0;t<i.length;t++)i[t].classList.remove("active");this.classList.add("active"),o.currentTab=this.dataset.tab,o.controls.style.display="console"===o.currentTab?"flex":"none",o.renderContent()};for(var a=t.querySelectorAll(".filter-btn"),l=0;l<a.length;l++)a[l].onclick=function(){for(var t=0;t<a.length;t++)a[t].classList.remove("active");this.classList.add("active"),o.activeFilter=this.dataset.type,o.renderContent()};t.querySelector("#addLSItemBtn").onclick=function(){o.addLSItem()}},l.prototype.createNotification=function(){var t=e.createElement("div");t.className="notification",e.body.appendChild(t),this.notification=t},l.prototype.showNotification=function(t,e){var o=this.notification;o.textContent=t,o.className="notification"+("warning"===e?" warning":""),o.style.display="block",setTimeout(function(){o.style.display="none"},2500)},l.prototype.setInitialPosition=function(){var t=this.btn;t.style.top="auto",t.style.bottom="30px",t.style.right="30px",t.style.left="auto"},l.prototype.bindEvents=function(){var t=this;this.btn.onclick=function(){t.overlay.classList.add("active"),t.renderContent()}},l.prototype.captureConsole=function(){var e=this;function n(n){return function(){var i=Array.prototype.slice.call(arguments),s=i.length&&"string"==typeof i[0]&&0===i[0].indexOf("[system]"),a=i.map(function(t){return"object"==typeof t?JSON.stringify(t):""+t}).join(" "),l=n+"|"+a;if(e.lastLog&&e.lastLog.type===n&&e.lastLog.sign===l)e.lastLog.count++,e.lastLog.timestamp=new Date;else{var r={id:e.logs.length,type:n,args:i,content:a,timestamp:new Date,count:1,sign:l,isSystem:s};if(e.logs.push(r),e.lastLog=r,s){var c=o({},r,{id:e.systemLogs.length});e.systemLogs.push(c)}}e.originalConsole[n].apply(t.console,i),e.overlay&&e.overlay.classList.contains("active")&&e.renderContent()}}this.originalConsole={log:t.console.log,info:t.console.info,warn:t.console.warn,error:t.console.error},t.console.log=n("log"),t.console.info=n("info"),t.console.warn=n("warn"),t.console.error=n("error")},l.prototype.renderContent=function(){var t=this.currentTab;this.consoleOutput.style.display="console"===t?"block":"none",this.localstorageView.style.display="localstorage"===t?"block":"none",this.systemLogsEl.style.display="system"===t?"block":"none","console"===t&&this.renderLogs(),"system"===t&&this.renderSystemLogs(),"localstorage"===t&&this.renderLocalStorage()},l.prototype.renderLogs=function(){var t=this.consoleOutput,e=this.logs.filter(function(t){return!t.isSystem});if("all"!==this.activeFilter&&(e=e.filter(function(t){return t.type===this.activeFilter},this)),this.searchQuery&&(e=e.filter(function(t){return t.content.toLowerCase().indexOf(this.searchQuery)>-1},this)),e.length){for(var o="",i=e.length-1;i>=0;i--){var l=e[i],r=l.count>1?` [${l.count} 次重复]`:"";o+='<div class="log-item '+l.type+'"><div class="log-icon">'+a(l.type)+'</div><div class="log-content">'+n(l.content+r)+' <div class="log-actions"> <span class="log-action" onclick="thinConsole.tC[\''+this.options.id+"'].copyLog("+l.id+',false)">复制</span> </div></div><div class="timestamp">'+s(l.timestamp)+"</div></div>"}t.innerHTML=o}else t.innerHTML='<div class="nolog">暂无日志</div>'},l.prototype.renderSystemLogs=function(){var t=this.systemLogsEl,e=this.systemLogs;if("all"!==this.activeFilter&&(e=e.filter(function(t){return t.type===this.activeFilter},this)),this.searchQuery&&(e=e.filter(function(t){return t.content.toLowerCase().indexOf(this.searchQuery)>-1},this)),e.length){for(var o="",i=e.length-1;i>=0;i--){var l=e[i],r=l.count>1?` [${l.count} 次重复]`:"";o+='<div class="log-item '+l.type+'"><div class="log-icon">'+a(l.type)+'</div><div class="log-content">'+n(l.content+r)+' <div class="log-actions"> <span class="log-action" onclick="thinConsole.tC[\''+this.options.id+"'].copyLog("+l.id+',true)">复制</span> </div></div><div class="timestamp">'+s(l.timestamp)+"</div></div>"}t.innerHTML=o}else t.innerHTML='<div class="nolog">暂无系统日志</div>'},l.prototype.copyLog=function(t,e){for(var o=e?this.systemLogs:this.logs,n=null,i=0;i<o.length;i++)if(o[i].id===t){n=o[i];break}n&&(i((n.count>1?`[${n.count} 次重复] `:"")+n.content),this.showNotification("已复制到剪贴板"))},l.prototype.clearAllLogs=function(){confirm("确定清空所有日志?此操作不可撤销。")&&(this.logs=[],this.systemLogs=[],this.lastLog=null,this.renderContent(),this.showNotification("日志已清空","warning"))},l.prototype.renderLocalStorage=function(){var e=this.lsItems;if(e.innerHTML="",t.localStorage.length){for(var o=[],n=0;n<t.localStorage.length;n++)o.push(t.localStorage.key(n));o.sort();for(var i=0;i<o.length;i++)this.addLSItemToDOM(o[i],t.localStorage.getItem(o[i]))}else e.innerHTML='<div class="nolog">本地存储为空</div>'},l.prototype.addLSItemToDOM=function(t,o){var i=e.createElement("div");i.className="ls-item",i.dataset.key=t;var s=!1,a=o;try{var l=JSON.parse(o);l&&"object"==typeof l&&(s=!0,a=JSON.stringify(l,null,2))}catch(t){}i.innerHTML='<div class="ls-key-row"> <div class="ls-key">'+n(t)+'</div> <div class="ls-actions"> <button class="ls-action-btn" onclick="thinConsole.tC[\''+this.options.id+"'].editLSItem('"+n(t)+'\')">编辑</button> <button class="ls-action-btn" onclick="thinConsole.tC[\''+this.options.id+"'].copyLSValue('"+n(t)+'\')">复制</button> <button class="ls-action-btn" onclick="thinConsole.tC[\''+this.options.id+"'].removeLSItem('"+n(t)+'\')">删除</button> </div></div><div class="ls-value">'+n(a)+'</div><div class="ls-value-type">类型:'+(s?"JSON":"字符串")+'</div><div class="ls-edit" style="display:none"> <textarea class="ls-edit-input" style="width:100%;height:60px;">'+n(o)+'</textarea> <div class="ls-edit-actions"> <button class="ls-action-btn" onclick="thinConsole.tC[\''+this.options.id+"'].cancelEditLSItem('"+n(t)+'\')">取消</button> <button class="ls-action-btn" onclick="thinConsole.tC[\''+this.options.id+"'].saveLSItem('"+n(t)+"')\">保存</button> </div></div>",this.lsItems.appendChild(i)},l.prototype.addLSItem=function(){var e=prompt("请输入键名:");if(e){if(null!==t.localStorage.getItem(e))return void alert("键已存在!");var o=prompt("请输入值:");null!=o&&(t.localStorage.setItem(e,o),this.addLSItemToDOM(e,o),this.showNotification("条目已添加"))}},l.prototype.editLSItem=function(t){var e=this.lsItems.querySelector('[data-key="'+t+'"]');e&&(e.querySelector(".ls-value").style.display="none",e.querySelector(".ls-edit").style.display="block")},l.prototype.saveLSItem=function(e){var o=this.lsItems.querySelector('[data-key="'+e+'"]');if(o){var n=o.querySelector(".ls-edit-input").value;t.localStorage.setItem(e,n),this.addLSItemToDOM(e,n),this.showNotification("条目已保存")}},l.prototype.cancelEditLSItem=function(t){var e=this.lsItems.querySelector('[data-key="'+t+'"]');e&&(e.querySelector(".ls-value").style.display="block",e.querySelector(".ls-edit").style.display="none")},l.prototype.removeLSItem=function(e){if(confirm("确定删除键“"+e+"”?")){t.localStorage.removeItem(e);var o=this.lsItems.querySelector('[data-key="'+e+'"]');o&&o.parentNode.removeChild(o),this.showNotification("条目已删除","warning")}},l.prototype.copyLSValue=function(e){var o=t.localStorage.getItem(e);null!=o&&(i(o),this.showNotification("值已复制"))},l.prototype.setupGlobalEventHandlers=function(){var e=this;t.addEventListener("error",function(t){""===t.filename&&0===t.lineno&&0===t.colno||(e.error("[system] 脚本错误",{Message:t.message||"无具体信息",File:t.filename||"未知文件",Line:t.lineno,Column:t.colno}),t.preventDefault())}),t.addEventListener("unhandledrejection",function(t){e.error("[system] 未处理的 Promise",t.reason),t.preventDefault()})},t.thinConsole=l,t.thinConsole.tC=t.thinConsole.tC||{}}(window,document)
@@ -0,0 +1 @@
1
+ !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):t.thinConsole=e()}("undefined"!=typeof self?self:this,function(){class t{constructor(e={}){if(t.tC)return console.warn("[thinConsole] thinConsole实例已存在"),t.tC;switch(e=this.sanitizeOptions(e),t.tC=this,this.version="1.2.0",this.options={text:"thinConsole",color:"#007aff",width:"auto",height:"auto",theme:"auto",plugins:!0,disabledPlugins:[],jsExecute:!0,maxLog:1e3,...e},this.options.theme){case"light":this.currentTheme="light";break;case"dark":this.currentTheme="dark";break;default:let t=()=>window.matchMedia("(prefers-color-scheme:dark)").matches?"dark":"light";this.currentTheme=t(),this.mediaQuery=window.matchMedia("(prefers-color-scheme:dark)"),this.themeChangeHandler=t=>{this.currentTheme=t.matches?"dark":"light",this.overlay&&this.overlay.classList.contains("tc-active")&&(this.overlay.className="tc-overlay tc-active tc-theme-"+this.currentTheme)},this.mediaQuery.addEventListener("change",this.themeChangeHandler)}this.currentTab="console",this.searchExpanded=!1,this.activeLSFilter="local",this.selectedElement=null,this.selectedShadowHostId=null,this.expandedElements=new WeakSet,this.mutedLogs=!1,this.mutedFilters={},this.netSending=!1,this.netNewVisible=!1,this.editorState={visible:!1,mode:"ls",key:"",oldKey:"",value:""},void 0===e.pos?.x&&void 0===e.pos?.y&&(this.options.pos=this.getSavedBtnPos()||{x:30,y:30}),this.pluginEnabled=this.options.plugins,this.disabledPlugins=this.options.disabledPlugins,this.plugins={},this.pluginTabs={},this.pluginViewContainers={},this.logs=[],this.lastLog=null,this.maxLog=this.options.maxLog,this.selectedLogId=null,this.customTabCount=0,this.jsonPageSize=200,this.jsonPageCache=new Map,this.jsonPageIndex=new Map,this.treeNodeRegistry=new Map,this.treeNodeRegId=0,this.expandedTreePaths=new Set,this.timerMap=new Map,this.countMap=new Map,this.networkRequests=[],this._netReqId=0,this.activeNetFilter="all",this.netDisabled=!1,this.netDisabledTypes=new Set,this.netDetailId=null,this.originalXHR=null,this.originalFetch=null,this.closedShadowRoots=new WeakMap,this.interceptShadowRoot(),this.createButton(),this.captureConsoleLogs(),this.createNotificationElement(),this.createOverlayElement(),this.createStyles(),this.setupGlobalEventHandlers(),this.setupSelfProtection(),this.renderContent()}interceptShadowRoot(){if(window.__tcShadowIntercepted)return;window.__tcShadowIntercepted=!0;let t=this,e=Element.prototype.attachShadow;Element.prototype.attachShadow=function(s){let i=e.call(this,s);return t.closedShadowRoots.set(this,{root:i,mode:s.mode||"open"}),i}}getShadowRoot(t){if(t.shadowRoot)return{root:t.shadowRoot,mode:"open"};return this.closedShadowRoots.get(t)||null}getSavedBtnPos(){let t=localStorage.getItem("tC-Button-pos");if(!t)return this.saveBtnPos({x:30,y:30}),null;let e=t.match(/^x:(.+?)\,y:(.+)$/);if(!e)return this.saveBtnPos({x:30,y:30}),null;let s=Number(e[1]),i=Number(e[2]);return isNaN(s)||isNaN(i)?(this.saveBtnPos({x:30,y:30}),null):{x:s,y:i}}saveBtnPos({x:t,y:e}){t=isNaN(Number(t))?30:Number(t),e=isNaN(Number(e))?30:Number(e),localStorage.setItem("tC-Button-pos",`x:${t},y:${e}`)}sanitizeOptions(t){let e={text:"thinConsole",color:"#007aff",width:"auto",height:"auto",theme:"auto",plugins:!0,disabledPlugins:[],jsExecute:!0,pos:null,maxLog:1e3,filters:null};if(!t||"object"!=typeof t)return{...e};let s={...e},i=(t,e=200)=>"string"==typeof t&&t.length<=e&&!/[<>"&]/.test(t)?t:void 0;for(let n of Object.keys(t)){if(!(n in e))continue;let o=t[n];switch(n){case"text":case"color":case"width":case"height":case"theme":{let t=i(o);void 0!==t&&(s[n]=t);break}case"plugins":case"jsExecute":"boolean"==typeof o&&(s[n]=o);break;case"disabledPlugins":Array.isArray(o)&&o.every(t=>"string"==typeof t)&&(s[n]=o.slice(0,100));break;case"pos":o&&"object"==typeof o&&"number"==typeof o.x&&"number"==typeof o.y&&(s.pos={x:o.x,y:o.y});break;case"maxLog":{let e=Number(t[n]);!isNaN(e)&&e>0&&(s[n]=Math.floor(e));break}case"filters":Array.isArray(o)&&o.every(t=>t&&"string"==typeof t.id&&"string"==typeof t.name)&&(s[n]=o)}}return s}createButton(){this.btn=document.createElement("button"),this.btn.id="tc-thinConsole-btn",this.btn.className="tc-floating-console-btn",this.btn.textContent=this.options.text.slice(0,11),this.btn.style.background=this.options.color,this.btn.style.width=this.options.width,this.btn.style.height=this.options.height,this.btn.style.bottom=(Number(this.options.pos.y)||30)+"px",this.btn.style.right=(Number(this.options.pos.x)||30)+"px",this.btn.title=this.options.text.slice(0,11),document.documentElement.append(this.btn);let t=!1,e=0,s=0,i=0,n=0,o=0,a=0,r=null,l=null,c=0,d=0,h=()=>{r&&(clearTimeout(r),r=null)},p=()=>{if(!t)return;let e=c-i,s=d-n;this.btn.style.transition="none",this.btn.style.transform=`translate3d(${e}px,${s}px,0)`,l=requestAnimationFrame(p)},u=r=>{if(!t)return;let l=r.touches?r.touches[0]:r,h=l.clientX-e,p=l.clientY-s;c=Math.max(o/2,Math.min(innerWidth-o/2,i+h)),d=Math.max(a/2,Math.min(innerHeight-a/2,n+p)),r.preventDefault()},f=()=>{if(h(),!t)return;t=!1,cancelAnimationFrame(l);let e=this.btn.getBoundingClientRect(),s=Math.round(innerWidth-e.right),i=Math.round(innerHeight-e.bottom);this.btn.style.right=Math.max(0,s)+"px",this.btn.style.bottom=Math.max(0,i)+"px",this.saveBtnPos({x:Math.max(0,s),y:Math.max(0,i)}),this.btn.style.transition="all 0.3s ease",this.btn.style.transform="",this.btn.dataset.right=Math.max(0,s),this.btn.dataset.bottom=Math.max(0,i),this.btn.removeEventListener("touchmove",u,{passive:!1}),this.btn.removeEventListener("touchend",f),this.btn.removeEventListener("mousemove",u),this.btn.removeEventListener("mouseup",f)},g=l=>{let h=l.touches?l.touches[0]:l;e=h.clientX,s=h.clientY;let g=this.btn.getBoundingClientRect();o=g.width,a=g.height,i=g.left+o/2,n=g.top+a/2,r=setTimeout(()=>{t=!0,c=i,d=n,p(),this.btn.addEventListener("touchmove",u,{passive:!1}),this.btn.addEventListener("touchend",f),this.btn.addEventListener("mousemove",u),this.btn.addEventListener("mouseup",f)},500)};this.btn.addEventListener("touchstart",g,{passive:!1}),this.btn.addEventListener("mousedown",g),this.btn.addEventListener("touchend",h),this.btn.addEventListener("mouseup",h),this.btn.addEventListener("mouseleave",h),this.btn.addEventListener("click",()=>{this.triggerGlobalHook("beforeOpen"),this.overlay.className="tc-overlay tc-active tc-theme-"+this.currentTheme,this.renderContent(),this.triggerGlobalHook("afterOpen")})}createOverlayElement(){this.overlay=document.createElement("div"),this.overlay.id="tc-consoleOverlay",this.overlay.className="tc-overlay";let t=`<div class="tc-splitter" id="tc-splitter"></div><div class="tc-console-container"><div class="tc-console-header" id="tc-consoleHeader"><div class="tc-console-title" id="tc-consoleTitle"><i class="fa fa-terminal"></i>${this.options.text.slice(0,11)}</div><div class="tc-header-actions"><button class="tc-header-icon-btn tc-el-header-btn" id="tc-elementPickBtn" title="选择元素" style="display:none"><i class="fa fa-mouse-pointer"></i></button><button class="tc-header-icon-btn tc-el-header-btn" id="tc-elCopyBtn" title="复制元素" style="display:none"><i class="fa fa-copy"></i></button><button class="tc-header-icon-btn tc-el-header-btn tc-el-delete-btn" id="tc-elDeleteBtn" title="删除元素" style="display:none"><i class="fa fa-trash-alt"></i></button><button class="tc-header-icon-btn" id="tc-logCopyBtn" title="复制选中日志" style="display:none"><i class="fa fa-copy"></i></button><button class="tc-header-icon-btn tc-ls-add-btn" id="tc-lsAddBtn" title="新建" style="display:none"><i class="fa fa-plus"></i></button><button class="tc-header-icon-btn" id="tc-netNewBtn" title="新建请求" style="display:none"><i class="fa fa-plus"></i></button><button class="tc-header-icon-btn" id="tc-searchToggleBtn" title="搜索"><i class="fa fa-search"></i></button><button class="tc-clear-all-btn" title="清除" id="tc-clearLogsBtn"><i class="fa fa-trash-alt"></i></button><button class="tc-close-btn" title="关闭" id="tc-closeConsoleBtn"><i class="fa fa-times"></i></button></div></div><div class="tc-search-bar" id="tc-searchBar" style="display:none"><div class="tc-search-input-wrap"><i class="fa fa-search tc-search-bar-icon"></i><input type="text" id="tc-searchInput" placeholder="搜索..."></div></div><div class="tc-tabs" id="tc-tabsContainer"></div><div class="tc-console-content" id="tc-contentArea"><div class="tc-controls" id="tc-consoleControls"><div class="tc-filters" id="tc-filtersContainer"></div><div class="tc-filters tc-ls-filters" id="tc-lsFiltersContainer" style="display:none"><button class="tc-filter-btn tc-active" title="本地存储" data-ls-type="local" data-orig="本地存储"><i class="fa fa-database"></i>本地存储</button><button class="tc-filter-btn" title="会话存储" data-ls-type="session" data-orig="会话存储"><i class="fa fa-window-restore"></i>会话存储</button><button class="tc-filter-btn" title="Cookies" data-ls-type="cookie" data-orig="Cookies"><i class="fa fa-cookie-bite"></i>Cookies</button></div><button class="tc-mute-btn" id="tc-muteBtn" title="屏蔽后续日志"><i class="fa fa-ban"></i></button></div><div class="tc-console-output" id="tc-consoleOutput"></div><div class="tc-localstorage-view" id="tc-localstorageView" style="display:none"><div class="tc-ls-items" id="tc-lsItems"></div></div><div class="tc-elements-view" id="tc-elementsView" style="display:none"><div class="tc-elements-tree" id="tc-elementsTree"></div></div><div class="tc-network-view" id="tc-networkView" style="display:none"><div class="tc-network-controls"><div class="tc-network-filters" id="tc-netFilters"></div><button class="tc-net-disable-btn" id="tc-netDisableBtn" title="禁用"><i class="fa fa-ban"></i></button></div><div class="tc-network-items" id="tc-networkItems"></div><div class="tc-net-detail-overlay" id="tc-netDetailOverlay"><div class="tc-net-detail-header"><button class="tc-net-back-btn" id="tc-netBackBtn" title="返回"><i class="fa fa-arrow-left"></i></button><div class="tc-net-detail-header-actions"><button class="tc-net-resend-icon-btn" id="tc-netResendIconBtn" title="重发"><i class="fa fa-redo"></i></button></div></div><div class="tc-net-detail-body" id="tc-netDetailBody"></div></div><div class="tc-net-new-overlay" id="tc-netNewOverlay"><div class="tc-net-new-header"><button class="tc-net-back-btn" id="tc-netNewBackBtn"><i class="fa fa-arrow-left"></i></button><div class="tc-net-new-title">新建请求</div></div><div class="tc-net-new-body"><div class="tc-net-form-group"><label class="tc-net-form-label">网址</label><input type="text" class="tc-net-form-input" id="tc-netNewUrl" placeholder="https://..." spellcheck="false"></div><div class="tc-net-form-group"><label class="tc-net-form-label">类型</label><select class="tc-net-form-select" id="tc-netNewMethod"><option value="GET">GET</option><option value="POST">POST</option><option value="PUT">PUT</option><option value="PATCH">PATCH</option><option value="DELETE">DELETE</option><option value="HEAD">HEAD</option><option value="OPTIONS">OPTIONS</option></select></div><div class="tc-net-form-group"><label class="tc-net-form-label">请求内容 (可选)</label><textarea class="tc-net-form-textarea" id="tc-netNewBody" placeholder='{"key":"value"}' spellcheck="false"></textarea></div><div class="tc-net-form-group"><label class="tc-net-form-label">请求头 (可选, 每行一个)</label><textarea class="tc-net-form-textarea" id="tc-netNewHeaders" placeholder="Content-Type: application/json" spellcheck="false"></textarea></div><button class="tc-net-send-btn" id="tc-netSendBtn"><i class="fa fa-paper-plane"></i> 发送请求</button></div></div></div><div class="tc-ls-editor-overlay" id="tc-lsEditorOverlay" style="display:none"><div class="tc-ls-editor-header"><div class="tc-ls-editor-header-row"><input type="text" class="tc-ls-editor-key-input" id="tc-lsEditorKeyInput" placeholder="键名..." spellcheck="false"><span class="tc-ls-editor-title" id="tc-lsEditorTitle"></span></div></div><div class="tc-ls-editor-body"><textarea id="tc-lsEditorInput" placeholder="输入值..." spellcheck="false"></textarea></div><div class="tc-ls-editor-footer"><button class="tc-ls-editor-btn tc-cancel" id="tc-lsEditorCancel">取消</button><button class="tc-ls-editor-btn tc-save" id="tc-lsEditorSave">保存</button></div></div></div></div>`;this.overlay.innerHTML=t,document.querySelector("html").appendChild(this.overlay),this.tabButtonsContainer=this.overlay.querySelector("#tc-tabsContainer"),this.createBuiltinTabs(),this.closeConsoleBtn=this.overlay.querySelector("#tc-closeConsoleBtn"),this.consoleOutput=this.overlay.querySelector("#tc-consoleOutput"),this.title=this.overlay.querySelector("#tc-consoleTitle"),this.localstorageView=this.overlay.querySelector("#tc-localstorageView"),this.lsItems=this.overlay.querySelector("#tc-lsItems"),this.contentArea=this.overlay.querySelector("#tc-contentArea"),this.consoleContainer=this.overlay.querySelector(".tc-console-container"),this.renderFilters(),this.filterButtons=this.overlay.querySelectorAll("#tc-filtersContainer .tc-filter-btn"),this.searchInput=this.overlay.querySelector("#tc-searchInput"),this.clearLogsBtn=this.overlay.querySelector("#tc-clearLogsBtn"),this.tabButtons=this.overlay.querySelectorAll(".tc-tab-btn"),this.consoleControls=this.overlay.querySelector("#tc-consoleControls"),this.searchToggleBtn=this.overlay.querySelector("#tc-searchToggleBtn"),this.searchBar=this.overlay.querySelector("#tc-searchBar"),this.consoleHeader=this.overlay.querySelector("#tc-consoleHeader"),this.lsEditorOverlay=this.overlay.querySelector("#tc-lsEditorOverlay"),this.lsEditorTitle=this.overlay.querySelector("#tc-lsEditorTitle"),this.lsEditorKeyInput=this.overlay.querySelector("#tc-lsEditorKeyInput"),this.lsEditorInput=this.overlay.querySelector("#tc-lsEditorInput"),this.lsEditorCancel=this.overlay.querySelector("#tc-lsEditorCancel"),this.lsEditorSave=this.overlay.querySelector("#tc-lsEditorSave"),this.muteBtn=this.overlay.querySelector("#tc-muteBtn"),this.lsFiltersContainer=this.overlay.querySelector("#tc-lsFiltersContainer"),this.lsAddBtn=this.overlay.querySelector("#tc-lsAddBtn"),this.logCopyBtn=this.overlay.querySelector("#tc-logCopyBtn"),this.elementsView=this.overlay.querySelector("#tc-elementsView"),this.elementsTree=this.overlay.querySelector("#tc-elementsTree"),this.networkView=this.overlay.querySelector("#tc-networkView"),this.networkItems=this.overlay.querySelector("#tc-networkItems"),this.netFiltersEl=this.overlay.querySelector("#tc-netFilters"),this.netDisableBtn=this.overlay.querySelector("#tc-netDisableBtn"),this.netDetailOverlay=this.overlay.querySelector("#tc-netDetailOverlay"),this.netDetailBody=this.overlay.querySelector("#tc-netDetailBody"),this.netNewOverlay=this.overlay.querySelector("#tc-netNewOverlay"),this.netNewUrl=this.overlay.querySelector("#tc-netNewUrl"),this.netNewMethod=this.overlay.querySelector("#tc-netNewMethod"),this.netNewBody=this.overlay.querySelector("#tc-netNewBody"),this.netNewHeaders=this.overlay.querySelector("#tc-netNewHeaders"),this.netSendBtn=this.overlay.querySelector("#tc-netSendBtn"),this.netBackBtn=this.overlay.querySelector("#tc-netBackBtn"),this.netNewBackBtn=this.overlay.querySelector("#tc-netNewBackBtn"),this.netNewBtn=this.overlay.querySelector("#tc-netNewBtn"),this.elementPickBtn=this.overlay.querySelector("#tc-elementPickBtn"),this.splitter=this.overlay.querySelector("#tc-splitter"),this.splitter&&this.setupSplitter(),this.elementPickBtn.addEventListener("click",()=>this.startElementPicker()),this.elCopyBtn=this.overlay.querySelector("#tc-elCopyBtn"),this.elCopyBtn.addEventListener("click",()=>{this.selectedElement?this.copyElementHTML(this.selectedElement):this.showNotification("请先选择一个元素","warning")}),this.elDeleteBtn=this.overlay.querySelector("#tc-elDeleteBtn"),this.elDeleteBtn.addEventListener("click",()=>{this.selectedElement?this.deleteElement(this.selectedElement):this.showNotification("请先选择一个元素","warning")}),this.netDisableBtn&&this.netDisableBtn.addEventListener("click",()=>this.toggleNetDisable()),this.netBackBtn&&this.netBackBtn.addEventListener("click",()=>{this.netDetailOverlay.style.display="none",this.netDetailId=null}),this.netNewBackBtn&&this.netNewBackBtn.addEventListener("click",()=>{this.netNewVisible=!1,this.netNewOverlay.style.display="none"}),this.netNewBtn&&this.netNewBtn.addEventListener("click",()=>{if(this.editorState.visible){let t=this.editorState.mode;if("code"===t)return void this.showNotification("正在运行代码,无法发送请求","warning");if("ls"===t)return void this.showNotification("正在保存键值,无法发送请求","warning")}this.netNewVisible=!0,this.netNewOverlay.style.display="flex"}),this.netSendBtn&&this.netSendBtn.addEventListener("click",()=>this.sendNewRequest()),this.networkItems&&this.networkItems.addEventListener("click",t=>{let e=t.target.closest(".tc-net-item");if(!e)return;let s=parseInt(e.dataset.reqId);if(t.target.closest("[data-action=copy]")){t.stopPropagation(),t.preventDefault();let e=this.networkRequests.find(t=>t.id===s);if(e){let t={method:e.method,url:e.url,headers:e.reqHeaders,body:e.reqBody};navigator.clipboard.writeText(JSON.stringify(t,null,2)).then(()=>this.showNotification("已复制请求JSON")).catch(()=>{})}return}return t.target.closest("[data-action=detail]")?(t.stopPropagation(),t.preventDefault(),void this.showNetDetail(s)):void 0}),this.captureNetworkRequests(),this.closeConsoleBtn.addEventListener("click",()=>{this.triggerGlobalHook("beforeClose"),this.overlay.classList.remove("tc-active"),this.triggerGlobalHook("afterClose")}),[this.consoleOutput,this.lsItems].forEach(t=>this.setupVirtualScroll(t)),this.lsItems.addEventListener("click",t=>{let e=t.target.closest(".tc-ls-action-btn");if(!e)return;let s=e.dataset.action,i=e.dataset.key;switch(s){case"edit":this.openLSEditor(i);break;case"copy":this.copyLog(i,"",!0);break;case"remove":this.removeLSItem(i)}}),this.title.title="运行代码功能已被禁用",this.title.style.cursor="not-allowed",this.options.jsExecute&&(this.title.title="点击标题以输入代码执行",this.title.style.cursor="pointer",this.title.addEventListener("click",()=>this.onTitleClick())),this.overlay.addEventListener("click",t=>{let e=t.target.closest(".tc-json-page-btn");e&&this.changeJsonPage(parseInt(e.dataset.id),parseInt(e.dataset.page,10));let s=t.target.closest(".tc-tree-load-more");s&&this.loadMoreTreeChildren(s);let i=t.target.closest(".tc-elements-tree .tc-tree-label");if(i){let t=i.closest(".tc-tree-node[data-el-id]"),e=t?parseInt(t.dataset.elId):null,s=null!==e&&this.elRefMap?this.elRefMap.get(e):null;s&&(this.selectedElement=s,this.selectedShadowHostId=t.dataset.shadowHost?parseInt(t.dataset.shadowHost):null,this.elementsTree.querySelectorAll(".tc-el-selected").forEach(t=>t.classList.remove("tc-el-selected")),this.elementsTree.querySelectorAll(".tc-el-highlight").forEach(t=>t.classList.remove("tc-el-highlight")),t.classList.add("tc-el-selected"),t.classList.add("tc-el-highlight"),setTimeout(()=>t.classList.remove("tc-el-highlight"),3e3))}else"elements"!==this.currentTab||t.target.closest(".tc-tree-label")||t.target.closest(".tc-tree-toggle")||t.target.closest(".tc-el-header-btn")||t.target.closest(".tc-close-btn")||t.target.closest(".tc-header-icon-btn")||t.target.closest(".tc-console-header")||t.target.closest(".tc-tabs")||t.target.closest(".tc-controls")||t.target.closest(".tc-search-bar")||(this.selectedElement=null,this.selectedShadowHostId=null,this.elementsTree&&(this.elementsTree.querySelectorAll(".tc-el-selected").forEach(t=>t.classList.remove("tc-el-selected")),this.elementsTree.querySelectorAll(".tc-el-highlight").forEach(t=>t.classList.remove("tc-el-highlight"))));let n=t.target.closest(".tc-tree-toggle");if(n){let t=n.closest(".tc-tree-node");if(t){let e=t.dataset.elId,s=e&&this.elRefMap?this.elRefMap.get(parseInt(e)):null;if(t.classList.contains("tc-collapsed")){t.classList.remove("tc-collapsed"),t.classList.add("tc-expanded");let e=t.dataset.treePath;e&&this.expandedTreePaths.add(e);let i=n.querySelector("i");i&&(i.classList.remove("fa-angle-right"),i.classList.add("fa-angle-down")),s&&this.expandedElements.add(s);let o=t.querySelector(":scope > .tc-tree-children");if(o&&o.dataset.lazyId){let t=parseInt(o.dataset.lazyId),e=this.treeNodeRegistry.get(t);if(e){let s="";if("html"===e.type)s=this.renderDomChildrenLazy(e.children,(t,s,i)=>this.renderHTMLTree(t,"",e.path+"."+s,i),e.depth||0,"html",{path:e.path}),e.shadow&&(s+=this.buildShadowLazy(e.shadow,"html",e.path,e.depth||0));else if("html-shadow"===e.type)s=this.renderDomChildrenLazy(e.children,(t,s,i)=>this.renderHTMLTree(t,"",e.path+".shadow."+s,i),e.depth||0,"html-shadow",{});else if("element"===e.type)s=this.renderDomChildrenLazy(e.children,(t,e,s)=>this.renderElementTree(t,s),e.depth||0,"element",{}),e.shadow&&(s+=this.buildShadowLazy(e.shadow,"element",null,e.depth||0,e.elId));else if("element-shadow"===e.type)s=this.renderDomChildrenLazy(e.children,(t,e,s)=>this.renderElementTree(t,s),e.depth||0,"element-shadow",{});else if(e.isJsonValue)s=this.renderJSONValueChildren(e.children);else{let t=new WeakSet;e.chain.forEach(e=>t.add(e)),t.add(e.obj);let i=e.children;if(i.length>200){let n=this.treeNodeRegId++;this.treeNodeRegistry.set(n,{children:i,chain:e.chain.concat([e.obj]),noProto:e.noProto}),s=this.renderTreeChildrenBatch(i,t,0,200,e.chain.concat([e.obj]),e.path||"",1,e.noProto)+'<div class="tc-tree-load-more" data-reg-id="'+n+'" data-offset="200"><i class="fa fa-angle-down"></i> 展开更多 (剩余 '+(i.length-200)+" 项)</div>"}else s=this.renderTreeChildrenBatch(i,t,0,i.length,e.chain.concat([e.obj]),e.path||"",1,e.noProto)}o.innerHTML=s,delete o.dataset.lazyId,this.treeNodeRegistry.delete(t)}}}else{t.classList.remove("tc-expanded"),t.classList.add("tc-collapsed");let e=t.dataset.treePath;e&&this.expandedTreePaths.delete(e);let i=n.querySelector("i");i&&(i.classList.remove("fa-angle-down"),i.classList.add("fa-angle-right")),s&&this.expandedElements.delete(s)}let i=n.closest(".tc-console-output, .tc-ls-items");i&&this.vsRefreshHeights(i)}}t.target===this.overlay&&(this.triggerGlobalHook("beforeClose"),this.overlay.classList.remove("tc-active"),this.triggerGlobalHook("afterClose"))}),this.filterButtons.forEach(t=>{t.addEventListener("click",()=>{this.filterButtons.forEach(t=>t.classList.remove("tc-active")),t.classList.add("tc-active"),this.activeFilter=t.dataset.type,this.updateFilterCounts(),this.renderContent(),this.scrollFilterIntoView(this.overlay.querySelector("#tc-filtersContainer"),t)})}),this.lsFiltersContainer&&this.lsFiltersContainer.querySelectorAll(".tc-filter-btn").forEach(t=>{t.addEventListener("click",()=>{this.lsFiltersContainer.querySelectorAll(".tc-filter-btn").forEach(t=>t.classList.remove("tc-active")),t.classList.add("tc-active"),this.activeLSFilter=t.dataset.lsType,this.renderContent(),this.scrollFilterIntoView(this.lsFiltersContainer,t)})}),this.lsAddBtn&&this.lsAddBtn.addEventListener("click",()=>this.onAddLSClick()),this.logCopyBtn&&this.logCopyBtn.addEventListener("click",()=>{null!==this.selectedLogId?this.copyLog(this.selectedLogId,!1):this.showNotification("请先选中一条日志","warning")}),this.consoleOutput&&this.consoleOutput.addEventListener("click",t=>{let e=t.target.closest(".tc-log-item");if(!e)return this.selectedLogId=null,this.consoleOutput.querySelectorAll(".tc-log-item.tc-selected").forEach(t=>t.classList.remove("tc-selected")),void(this.logCopyBtn&&(this.logCopyBtn.style.display="none"));let s=parseInt(e.id.replace("tc-log-item-",""));this.selectedLogId=s,this.consoleOutput.querySelectorAll(".tc-log-item.tc-selected").forEach(t=>t.classList.remove("tc-selected")),e.classList.add("tc-selected"),this.logCopyBtn&&(this.logCopyBtn.style.display="flex")}),this.searchInput.addEventListener("input",(t=>e=>{clearTimeout(t),t=setTimeout(()=>{if(this.searchQuery=e.target.value,"network"===this.currentTab)return this.renderNetworkList().trim(),this.renderContent()},300)})(0)),this.clearLogsBtn.addEventListener("click",()=>this.clearAllLogs()),this.searchToggleBtn.addEventListener("click",()=>this.toggleSearch()),this.lsEditorCancel.addEventListener("click",()=>this.closeLSEditor()),this.lsEditorSave.addEventListener("click",()=>this.onEditorSave()),this.muteBtn.addEventListener("click",()=>this.toggleMute()),this.lsEditorInput.addEventListener("input",()=>{this.editorState.value=this.lsEditorInput.value}),this.lsEditorKeyInput&&this.lsEditorKeyInput.addEventListener("input",()=>{this.editorState.key=this.lsEditorKeyInput.value.trim()}),this.setupFilterShadow(this.overlay.querySelector("#tc-filtersContainer")),this.setupFilterShadow(this.lsFiltersContainer),this.setupFilterShadow(this.netFiltersEl),this.setupGestures(),this.tabButtons.forEach(t=>{t.addEventListener("click",()=>{this.tabButtons.forEach(t=>t.classList.remove("tc-active")),t.classList.add("tc-active"),this.currentTab=t.dataset.tab,this.renderContent()})})}renderFilters(){let t=this.overlay.querySelector("#tc-filtersContainer");if(!t)return;let e=this.options.filters;e&&e.length||(e=[{id:"all",name:"全部",icon:"fa fa-list"},{id:"log",name:"日志",icon:"fa fa-info"},{id:"info",name:"信息",icon:"fa fa-info-circle"},{id:"warn",name:"警告",icon:"fa fa-exclamation-triangle"},{id:"error",name:"错误",icon:"fa fa-times-circle"}]),t.innerHTML=e.map((t,e)=>`<button class="tc-filter-btn${0===e?" tc-active":""}" title="${this.escapeHtml(t.name)}" data-type="${this.escapeHtml(t.id)}">${t.icon?'<i class="'+this.escapeHtml(t.icon)+'"></i>':""}${this.escapeHtml(t.name)}</button>`).join(""),t.querySelectorAll(".tc-filter-btn").forEach(e=>{e.addEventListener("click",()=>{t.querySelectorAll(".tc-filter-btn").forEach(t=>t.classList.remove("tc-active")),e.classList.add("tc-active"),this.activeFilter=e.dataset.type,this.updateFilterCounts(),this.renderContent()})})}createBuiltinTabs(){[{id:"console",name:"控制台",icon:"fa fa-terminal"},{id:"network",name:"网络",icon:"fa fa-wifi"},{id:"localstorage",name:"存储",icon:"fa fa-database"},{id:"elements",name:"元素",icon:"fa fa-code"}].forEach(t=>{let e=document.createElement("button");e.className="tc-tab-btn",e.dataset.tab=t.id,e.title=t.name,e.innerHTML=`<i class="${t.icon}"></i>${t.name}`,"console"===t.id&&e.classList.add("tc-active"),e.addEventListener("click",()=>{this.tabButtons=this.overlay.querySelectorAll(".tc-tab-btn"),this.tabButtons.forEach(t=>t.classList.remove("tc-active")),e.classList.add("tc-active"),this.currentTab=t.id,this.renderContent()}),this.tabButtonsContainer.appendChild(e)})}createPluginTab(t){let e=document.createElement("button");e.className="tc-tab-btn",e.dataset.tab=t.id?t.id:"newTab",t.title=t.name?t.name:"新的插件",e.innerHTML=`<i class="${t.icon?t.icon:"fa fa-plug"}"></i>${t.name?t.name:"新的插件"}`,this.tabButtonsContainer.appendChild(e),e.addEventListener("click",()=>{this.tabButtons=this.overlay.querySelectorAll(".tc-tab-btn"),this.tabButtons.forEach(t=>t.classList.remove("tc-active")),e.classList.add("tc-active"),this.currentTab=t.id,this.renderContent()});let s=document.createElement("div");s.id=`tc-${t.id}View`,s.innerHTML="无插件视图",s.className="tc-plug-view",s.style.display="none",this.contentArea.appendChild(s),this.pluginViewContainers[t.id]=s}createNotificationElement(){this.notification=document.createElement("div"),this.notification.id="tc-notification",this.notification.className="tc-notification",this.notification.style.display="none",document.documentElement.appendChild(this.notification)}createStyles(){let t=document.createElement("style");t.innerHTML="@import url(https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css);*{margin:0;padding:0;box-sizing:border-box}.tc-floating-console-btn{position:fixed;z-index:99997;touch-action:none;will-change:transform;padding:15px 25px;backdrop-filter:blur(5px);border-radius:5px;border:none;background:#007aff;color:#fff;font-size:1rem;cursor:move;display:flex;align-items:center;gap:10px;font-weight:500;box-shadow:0 8px 20px rgba(0,0,0,.4);transition:all .3s ease;user-select:none}.tc-floating-console-btn:active{transform:scale(.98)}.tc-floating-console-btn i{font-size:1.2rem}.tc-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.85);display:flex;align-items:center;justify-content:center;z-index:99998;opacity:0;visibility:hidden;transition:all .4s ease;backdrop-filter:blur(5px)}.tc-overlay.tc-active{opacity:1;visibility:visible}.tc-theme-dark{--selected-bg:rgba(74,74,230,.15);--console-bg:#1e1e1e;--header-bg:#252526;--text-color:#d4d4d4;--controls-bg:#2d2d2d;--border-color:rgba(255,255,255,0.05);--log-bg:#191919;--log-border-light:3px solid;--filter-active:#4a4ae6;--search-bg:#3e3e42;--json-bg:rgba(40,40,40,0.7);--json-key:#6aaeff;--json-string:#98c379;--json-number:#d19a66;--json-boolean:#56b6c2;--json-null:#be5046;--json-cmt:#707070;--action-bg:rgba(106,174,255,0.3);--action-hover:rgba(106,174,255,0.5);--log-icon-info:#4a4ae6;--log-bg-warn:rgba(255,193,7,0.1);--log-icon-warn:#d9a40d;--log-icon-error:#ff3b30;--clear-btn-color:#ff6b6b;--clear-btn-hover:#ff5252;--tab-bg:#333;--tab-active:#444;--tab-color:#ddd}.tc-theme-light{--selected-bg:rgba(30,107,184,.08);--console-bg:#ffffff;--header-bg:#f0f0f0;--text-color:#333;--controls-bg:#e0e0e0;--border-color:rgba(0,0,0,0.1);--log-bg:#f3f3f3;--log-border-light:3px solid;--filter-active:#4a4ae6;--search-bg:#f0f0f0;--json-bg:rgba(240,240,240,0.9);--json-key:#1e6bb8;--json-string:#22863a;--json-number:#d73a49;--json-boolean:#005cc5;--json-null:#6f42c1;--json-cmt:#707070;--action-bg:rgba(30,107,184,0.1);--action-hover:rgba(30,107,184,0.2);--log-bg-warn:rgba(255,243,205,0.75);--log-icon-info:#1e6bb8;--log-icon-warn:#e36209;--log-icon-error:#d73a49;--clear-btn-color:#ff5252;--clear-btn-hover:#ff3b30;--tab-bg:#e5e5e5;--tab-active:#ddd;--tab-color:#333}.tc-console-container{background:var(--console-bg);display:flex;flex-direction:column;box-shadow:0 15px 35px rgba(0,0,0,.3);position:fixed;z-index:99999;left:0;bottom:0;width:100%;height:90vh;transform:translateY(100%);transition:transform .4s cubic-bezier(.25,.8,.25,1)}@media(min-width:769px){.tc-overlay{flex-direction:row;align-items:stretch;justify-content:flex-end}.tc-console-container{position:relative;left:auto;bottom:auto;width:50%;height:100%;transform:translateX(100%);flex-shrink:0}.tc-overlay.tc-active .tc-console-container{transform:translateX(0)}.tc-overlay::before{content:'';flex:1;cursor:pointer}.tc-splitter{display:block;width:4px;background:var(--border-color);cursor:col-resize;flex-shrink:0;z-index:100001;position:relative}.tc-splitter:hover,.tc-splitter.tc-dragging{background:var(--filter-active)}}@media(max-width:768px){.tc-splitter{display:none}}@media(max-width:768px){.tc-overlay{flex-direction:column;align-items:center;justify-content:center}.tc-console-container{transform:translateY(100%)!important}.tc-overlay.tc-active .tc-console-container{transform:translateY(0)!important}}.tc-console-header{display:flex;justify-content:space-between;align-items:center;padding:8px 25px;background:var(--header-bg);border-bottom:1px solid var(--border-color);position:relative}.tc-console-title{color:var(--text-color);gap:10px;display:flex;align-items:center;font-size:18px}.tc-header-actions{display:flex;align-items:center;gap:2px}.tc-header-icon-btn{background:0 0;border:none;color:var(--text-color);font-size:18px;cursor:pointer;width:40px;height:40px;display:flex;align-items:center;justify-content:center;border-radius:5px;transition:all .3s}.tc-header-icon-btn:hover{background:rgba(106,174,255,0.2);color:var(--json-key)}.tc-push-btn{border:none;background:var(--filter-active);color:#fff;padding:10px;border-radius:5px;font-size:10px}.tc-close-btn{background:0 0;border:none;color:var(--text-color);font-size:20px;cursor:pointer;width:40px;height:40px;display:flex;align-items:center;justify-content:center;border-radius:5px;transition:all .3s}.tc-close-btn:hover{background:rgba(255,100,100,.2);color:#ff6464;transform:scale(1.1)}.tc-clear-all-btn{background:0 0;border:none;color:var(--text-color);font-size:20px;cursor:pointer;width:40px;height:40px;display:flex;align-items:center;justify-content:center;border-radius:5px;transition:all .3s}.tc-clear-all-btn:hover,.tc-clear-all-btn:active{background:rgba(255,100,100,.2);color:var(--clear-btn-hover)}.tc-tabs{display:block;white-space:nowrap;overflow-x:auto;background:var(--tab-bg);padding:5px 10px 0;border-bottom:1px solid var(--border-color)}.tc-tab-btn{padding:12px 20px;background:0 0;border-radius:5px 5px 0 0;border:none;color:var(--tab-color);cursor:pointer;position:relative;display:inline-flex;align-items:center;gap:8px}.tc-tab-btn.tc-active{color:var(--text-color);font-weight:600}.tc-tab-btn.tc-active::after{content:'';position:absolute;bottom:0;left:0;width:100%;height:2px;border-radius:3px;background:var(--filter-active)}.tc-tab-btn:hover:not(.tc-active){background:rgba(255,255,255,.05)}.tc-controls{display:flex;padding:6px 15px;background:var(--controls-bg);gap:10px;flex-wrap:wrap;border-bottom:1px solid var(--border-color);align-items:center}.tc-controls-float-toggle{display:none}.tc-filters{display:flex;flex-wrap:nowrap;margin-left:-5px}.tc-filter-btn>.fa{margin-right:5px;margin-top:2px}.tc-filter-btn{position:relative;padding:5px 8px;border:none;background:0 0;color:var(--text-color);cursor:pointer;font-size:12px;display:flex;width:100%;white-space:nowrap}.tc-filter-btn.tc-active::after{content:\"\";position:absolute;width:90%;left:3px;height:2px;top:90%;border-radius:3px;background:var(--filter-active);color:#fff}.tc-search-bar{display:flex;align-items:center;gap:8px;padding:10px 20px;background:var(--controls-bg);border-bottom:1px solid var(--border-color)}.tc-search-input-wrap{display:flex;align-items:center;flex:1;position:relative}.tc-search-bar-icon{position:absolute;left:10px;color:var(--text-color);opacity:.6;font-size:14px;pointer-events:none}.tc-search-bar input{flex:1;padding:8px 10px 8px 35px;border-radius:5px;border:none;background:var(--search-bg);color:var(--text-color);transition:all .3s ease;font-size:14px;border:1px solid var(--border-color)}.tc-search-bar input:focus{outline:0;border-color:#4a4ae6}.tc-search-bar-close{background:0 0;border:none;color:var(--text-color);font-size:16px;cursor:pointer;padding:4px 8px;border-radius:5px;opacity:.6;transition:all .3s}.tc-search-bar-close:hover{opacity:1;background:rgba(255,255,255,.1)}.tc-console-content{flex:1;overflow:auto;display:flex;flex-direction:column;position:relative}.tc-console-output{flex:1;overflow-y:auto;padding:20px;font-family:monospace;font-size:.95rem}.tc-localstorage-view{flex:1;padding:20px;font-family:monospace;font-size:.95rem;position:relative;overflow:hidden}.tc-ls-items{position:absolute;inset:0;overflow-y:auto;padding:20px}.tc-log-item{padding:8px 12px;margin-bottom:6px;display:flex;flex-direction:column;border-left:3px solid #4a4ae6;background:var(--log-bg);border-radius:5px;cursor:pointer;transition:background .2s;color:var(--text-color);user-select:none;-webkit-user-select:none;-webkit-tap-highlight-color:transparent}.tc-log-item .tc-log-icon i{color:inherit}.tc-log-item.tc-selected{border-left-color:var(--json-key);background:var(--selected-bg)}.tc-log-item.tc-log{border-left-color:#4a4ae6}.tc-log-item.tc-info{border-left-color:var(--log-icon-info)}.tc-log-item.tc-warn{border-left-color:var(--log-icon-warn);background:var(--log-bg-warn)}.tc-log-item.tc-error{border-left-color:var(--log-icon-error);background:rgba(255,59,48,.15)}.tc-log-count{background:#4a4ae6;color:#fff;border-radius:4px;min-width:20px;height:20px;display:inline-flex;align-items:center;justify-content:center;font-size:11px;margin-right:4px;padding:0 5px;flex-shrink:0}.tc-log-icon{flex-shrink:0;display:flex;align-items:center;font-size:13px;margin-right:2px}.tc-log-header{display:flex;align-items:center;gap:0;margin-bottom:2px}.tc-log-content{width:100%;font-size:13px;max-height:300px;overflow-y:auto;margin-top:4px;word-break:break-word;line-height:1.5;user-select:text;-webkit-user-select:text}.tc-timestamp{color:var(--json-cmt);font-size:11px;margin-left:4px;white-space:nowrap}.tc-json-preview{font-family:monospace;padding:10px;margin-top:5px;background:var(--json-bg);border-radius:5px;white-space:pre!important;max-height:400px;overflow:auto}.tc-json-tree-container{font-family:monospace;padding:2px 0;margin-top:2px;background:0 0;border-radius:0;max-height:300px;overflow:auto;font-size:12px;line-height:1.6}.tc-tree-node{position:relative}.tc-tree-node.tc-collapsed>.tc-tree-children{display:none}.tc-tree-toggle{display:inline-block;width:16px;cursor:pointer;color:var(--json-cmt);text-align:center}.tc-tree-spacer{display:inline-block;width:16px}.tc-tree-leaf{white-space:nowrap}.tc-tree-label{color:var(--json-cmt)}.tc-tree-children{margin-left:16px;padding-left:4px}.tc-tree-brace{color:var(--json-cmt)}.tc-tree-ellipsis{color:var(--json-cmt)}.tc-tree-load-more{color:var(--json-cmt);cursor:pointer;padding:4px 0;user-select:none;font-size:11px}.tc-tree-node.tc-collapsed>.tc-tree-open{display:none}.tc-tree-node.tc-collapsed>.tc-tree-close{display:none}.tc-tree-node.tc-expanded>.tc-tree-close{display:block;padding-left:16px}.tc-tree-node.tc-expanded>.tc-tree-collapsed{display:none}.tc-tree-node.tc-collapsed>.tc-tree-ellipsis{display:inline}.tc-tree-node.tc-expanded>.tc-tree-ellipsis{display:none}.tc-tree-node.tc-collapsed>.tc-tree-close-tag{display:inline}.tc-tree-node.tc-expanded>.tc-tree-close-tag{display:inline}.tc-json-page-btn,.tc-ls-json-page-btn{border:none}.tc-json-number{color:var(--json-number)}.tc-json-boolean{color:var(--json-boolean)}.tc-json-key{color:var(--json-key)}.tc-json-null{color:var(--json-null)}.tc-json-string{color:var(--json-string)}.tc-json-cmt{color:var(--json-cmt)}.tc-log-actions{margin-top:8px;display:flex;gap:10px;font-size:10px}.tc-log-action{color:var(--json-key);cursor:pointer;padding:5px 10px;background:var(--action-bg);transition:all .2s;display:inline-flex;align-items:center;gap:5px;border-radius:5px}.tc-log-action:hover{background:var(--action-hover)}.tc-log-action.tc-copy-btn{background:var(--action-bg)}.tc-log-action.tc-copy-btn:hover{background:var(--action-hover)}.tc-error-stack{font-family:monospace;padding:10px;margin-top:10px;background:rgba(255,59,48,.2);border-radius:5px;white-space:nowrap;font-size:.85rem;overflow:auto;max-height:400px}.tc-object-preview{font-family:monospace;padding:10px;margin-top:5px;background:var(--json-bg);color:var(--json-number);border-radius:5px;white-space:pre;max-height:600px;overflow:auto}.tc-function-preview{font-family:monospace;padding:10px;margin-top:5px;background:var(--json-bg);color:var(--json-boolean);border-radius:5px;white-space:pre;word-break:break-all;overflow-x:auto}.tc-ls-header{padding:15px 0;display:flex;justify-content:flex-end}.tc-ls-item{background:var(--log-bg);padding:15px;margin-bottom:15px;border-radius:8px}.tc-ls-key-row{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;border-bottom:1px solid var(--border-color);padding-bottom:10px}.tc-ls-key{color:var(--json-key);font-size:16px;max-width:60%;overflow-x:auto;white-space:nowrap}.tc-ls-actions{display:flex;gap:8px}.tc-ls-action-btn{background:var(--action-bg);border:none;color:var(--text-color);padding:5px 10px;border-radius:5px;cursor:pointer;transition:all .2s;display:flex;align-items:center;gap:5px}.tc-ls-action-btn:hover{background:var(--action-hover)}.tc-ls-value{white-space:normal;word-break:break-all;padding:10px;background:var(--json-bg);border-radius:5px;font-family:monospace;max-height:200px;overflow-y:auto;color:var(--text-color);font-size:13px}.tc-ls-edit{display:flex;flex-direction:column;gap:10px;margin-top:10px;display:none}.tc-ls-edit textarea{width:100%;min-height:100px;padding:10px;background:var(--search-bg);border:1px solid var(--border-color);border-radius:5px;color:var(--text-color);font-family:monospace;resize:vertical;outline:0;transition:all .3s ease;font-size:10px}.tc-ls-edit textarea:focus{border-color:#4a4ae6}.tc-ls-key-edit{display:none;width:60%;padding:6px 10px;border:1px solid var(--border-color);border-radius:5px;background:var(--search-bg);font-size:16px;outline:0;transition:border .2s;color:var(--json-key);font-family:monospace}.tc-ls-key-edit:focus{border-color:#4a4ae6}.tc-ls-item.tc-editing .tc-ls-key{display:none}.tc-ls-item.tc-editing .tc-ls-key-edit{display:block}.tc-ls-edit-actions{display:flex;gap:10px;justify-content:flex-end}.tc-ls-value-type{font-size:8px;opacity:.7;margin-top:5px;color:var(--text-color)}.tc-vs-spacer{width:100%;flex-shrink:0}.tc-ls-editor-overlay{position:absolute;inset:0;z-index:100;display:flex;flex-direction:column;background:var(--console-bg)}.tc-ls-editor-header{padding:12px 20px;background:var(--header-bg);border-bottom:1px solid var(--border-color)}.tc-ls-editor-header-row{display:flex;align-items:center;gap:10px}.tc-ls-editor-key-input{flex:1;padding:8px 12px;border:1px solid var(--border-color);border-radius:6px;background:var(--search-bg);color:var(--json-key);font-size:14px;font-family:monospace;outline:0;transition:border .2s}.tc-ls-editor-key-input:focus{border-color:var(--filter-active)}.tc-ls-editor-title{color:var(--text-color);font-size:15px;font-weight:600;white-space:nowrap}.tc-ls-editor-body{flex:1;padding:15px 20px;overflow:hidden;display:flex}.tc-ls-editor-body textarea{flex:1;width:100%;padding:12px;background:var(--search-bg);border:1px solid var(--border-color);border-radius:8px;color:var(--text-color);font-family:monospace;font-size:14px;resize:none;outline:0;transition:border .2s;line-height:1.5}.tc-ls-editor-body textarea:focus{border-color:var(--filter-active)}.tc-ls-editor-footer{display:flex;gap:10px;justify-content:flex-end;padding:12px 20px;background:var(--header-bg);border-top:1px solid var(--border-color)}.tc-ls-editor-btn{padding:8px 24px;border:none;border-radius:6px;font-size:14px;cursor:pointer;transition:all .2s;font-weight:500}.tc-ls-editor-btn.tc-cancel{background:var(--controls-bg);color:var(--text-color)}.tc-ls-editor-btn.tc-cancel:hover{background:var(--action-hover)}.tc-ls-editor-btn.tc-save{background:var(--filter-active);color:#fff}.tc-ls-editor-btn.tc-save:hover{opacity:.85}.tc-ls-editor-btn.tc-run{background:var(--filter-active);color:#fff}.tc-ls-editor-btn.tc-run:hover{opacity:.85}.tc-console-table-wrap{overflow-x:auto;margin-top:5px;-webkit-overflow-scrolling:touch;border-radius:8px;border:1px solid rgba(128,128,128,0.25)}.tc-console-table{border-collapse:separate;border-spacing:0;width:100%;font-size:12px;font-family:monospace;overflow:hidden}.tc-console-table th{background:var(--controls-bg);color:var(--json-key);padding:6px 10px;text-align:left;border-bottom:1px solid rgba(128,128,128,0.25);border-right:1px solid rgba(128,128,128,0.25);white-space:nowrap;position:sticky;top:0}.tc-console-table td{padding:5px 10px;border-bottom:1px solid rgba(128,128,128,0.25);border-right:1px solid rgba(128,128,128,0.25);color:var(--text-color);white-space:nowrap;max-width:200px;overflow:hidden;text-overflow:ellipsis}.tc-console-table tbody tr:nth-child(even){background:var(--log-bg)}.tc-console-table tbody tr:hover{background:var(--action-bg)}.tc-console-table th:last-child,.tc-console-table td:last-child{border-right:none}.tc-console-table tbody tr:last-child td{border-bottom:none}.tc-ls-add-btn{font-size:18px!important;opacity:1!important;width:40px!important;height:40px!important;padding:0!important;margin-left:0!important}.tc-mute-btn{background:0 0;border:none;color:var(--text-color);font-size:14px;cursor:pointer;padding:5px 8px;border-radius:5px;opacity:.6;transition:opacity .2s;margin-left:auto;flex-shrink:0}.tc-mute-btn:hover{opacity:1}.tc-mute-btn.tc-muted{opacity:1;filter:saturate(2)}.tc-elements-view{flex:1;overflow-y:auto;padding:10px;font-family:monospace;font-size:12px;line-height:1.6}.tc-elements-tree .tc-tree-node{white-space:normal;word-break:break-all}.tc-el-header-btn{width:40px!important;height:40px!important;font-size:18px!important}.tc-el-header-btn.tc-el-delete-btn:hover{color:var(--clear-btn-color);background:rgba(255,100,100,.15)}.tc-tree-node.tc-el-highlight>.tc-tree-label{display:inline-block!important;background:var(--action-hover)!important;border-radius:3px;padding:1px 4px}.tc-tree-node.tc-el-selected>.tc-tree-label{display:inline-block!important;background:rgba(106,174,255,0.4);border-radius:3px;padding:1px 4px}.tc-el-toolbar-actions{margin-left:auto;display:flex;gap:4px}.tc-el-toolbar-btn{background:0 0;border:none;color:var(--text-color);cursor:pointer;padding:6px 10px;border-radius:5px;font-size:14px;opacity:.7;transition:all .2s}.tc-el-toolbar-btn:hover{opacity:1;background:var(--action-bg)}.tc-el-toolbar-btn.tc-el-delete-btn:hover{color:var(--clear-btn-color);background:rgba(255,100,100,.15)}.tc-element-picker-overlay{position:fixed;top:0;left:0;width:100%;height:100%;z-index:100000;cursor:crosshair;background:transparent;pointer-events:none}@media(max-width:768px){.tc-controls{flex-direction:row;align-items:center;padding:5px 10px;overflow-x:auto;flex-wrap:nowrap}.tc-log-item{flex-wrap:nowrap}.tc-log-actions{flex-wrap:wrap}.tc-floating-console-btn{padding:12px 20px;font-size:.9rem;right:20px;bottom:20px}.tc-tab-btn{padding:8px 12px;font-size:14px}.tc-nolog{text-align:center;font-size:20px;color:var(--text-color);padding:40px 0}.tc-nolog>.fa{margin-right:5px}.tc-notification{position:fixed;top:20px;right:20px;padding:12px 20px;background:rgba(76,175,80,.6);backdrop-filter:blur(12px);color:#fff;border-radius:5px;box-shadow:0 2px 10px rgba(0,0,0,.2);z-index:99999;display:none;transform:translateX(150%);max-height:48px;max-width:calc(100vw - 40px);transition:transform .3s ease;font-size:15px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.tc-notification.tc-show{transform:translateX(0)}.tc-notification.tc-warning{background:rgba(255,152,0,.6);backdrop-filter:blur(12px)}.tc-network-view{display:none;flex:1;overflow:hidden;flex-direction:column}.tc-network-controls{display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--controls-bg);border-bottom:1px solid var(--border-color)}.tc-network-filters{display:flex;gap:2px;flex:1;overflow-x:auto;overflow-y:visible;scrollbar-width:thin;padding-bottom:2px}.tc-net-filter-btn{padding:4px 10px;border:none;background:0 0;color:var(--text-color);cursor:pointer;font-size:12px;white-space:nowrap;border-radius:4px;transition:all .2s;opacity:.7}.tc-net-filter-btn.tc-active{color:var(--text-color);font-weight:600;opacity:1;position:relative}.tc-net-filter-btn.tc-active::after{content:'';position:absolute;width:90%;left:5%;height:2px;bottom:0;border-radius:3px;background:var(--filter-active)}.tc-net-filter-btn:hover{opacity:1}.tc-net-disable-btn{padding:5px 8px;border:none;background:0 0;color:var(--text-color);cursor:pointer;font-size:12px;border-radius:4px;white-space:nowrap;transition:all .2s;opacity:.55}.tc-net-disable-btn:hover{opacity:1}.tc-net-disable-btn.tc-disabled{opacity:1;color:var(--text-color);filter:none}.tc-network-items{flex:1;overflow-y:auto;padding:8px 12px}.tc-net-item{padding:12px 14px;margin-bottom:8px;background:var(--log-bg);border-left:3px solid var(--json-boolean);border-radius:6px;cursor:default;transition:background .2s}.tc-net-item:hover{background:var(--selected-bg)}.tc-net-item.tc-net-failed{border-left-color:#ff5252}.tc-net-item.tc-net-success{border-left-color:#98c379}.tc-net-item-header{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.tc-net-row1{display:flex;align-items:center;gap:8px;margin-bottom:4px}.tc-net-row2{display:flex;align-items:center;gap:8px;margin-bottom:6px}.tc-net-row3{display:flex;gap:8px;align-items:center}.tc-net-copy-btn,.tc-net-detail-btn{display:inline-flex;align-items:center;gap:4px;padding:4px 10px;border:none;border-radius:4px;font-size:11px;cursor:pointer;transition:all .2s}.tc-net-copy-btn{background:var(--action-bg);color:var(--json-key)}.tc-net-copy-btn:hover{background:var(--action-hover)}.tc-net-detail-btn{background:var(--action-bg);color:var(--json-key)}.tc-net-detail-btn:hover{background:var(--action-hover)}.tc-net-method{font-size:10px;font-weight:700;padding:2px 6px;border-radius:3px;text-transform:uppercase}.tc-net-method-GET{background:rgba(106,174,255,.2);color:var(--json-key)}.tc-net-method-POST{background:rgba(152,195,121,.2);color:var(--json-string)}.tc-net-method-PUT{background:rgba(255,193,7,.2);color:#ffc107}.tc-net-method-DELETE{background:rgba(255,82,82,.2);color:#ff5252}.tc-net-method-PATCH{background:rgba(255,152,0,.2);color:#ff9800}.tc-net-method-HEAD{background:rgba(190,80,70,.2);color:var(--json-null)}.tc-net-method-OPTIONS{background:rgba(112,112,112,.2);color:var(--json-cmt)}.tc-net-url{flex:1;font-size:12px;color:var(--text-color);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:100px}.tc-net-status{font-size:11px;font-weight:700;padding:2px 6px;border-radius:3px}.tc-net-status-2xx{background:rgba(152,195,121,.2);color:#98c379}.tc-net-status-3xx{background:rgba(106,174,255,.2);color:var(--json-key)}.tc-net-status-4xx{background:rgba(255,152,0,.2);color:#ff9800}.tc-net-status-5xx{background:rgba(255,82,82,.2);color:#ff5252}.tc-net-status-pending{background:rgba(112,112,112,.2);color:var(--json-cmt)}.tc-net-time{font-size:11px;color:var(--json-cmt);white-space:nowrap}.tc-net-item-actions{display:flex;gap:4px;align-items:center}.tc-net-action-btn{background:0 0;border:none;color:var(--json-cmt);cursor:pointer;font-size:13px;padding:2px 6px;border-radius:3px;transition:all .2s}.tc-net-action-btn:hover{background:var(--action-bg);color:var(--json-key)}.tc-net-detail-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:var(--console-bg);z-index:100;display:none;flex-direction:column}.tc-net-detail-header{display:flex;align-items:center;gap:8px;padding:10px 12px;background:var(--header-bg);border-bottom:1px solid var(--border-color)}.tc-net-back-btn{background:0 0;border:none;color:var(--text-color);cursor:pointer;font-size:16px;padding:4px 8px;border-radius:4px}.tc-net-back-btn:hover{background:var(--action-bg)}.tc-net-detail-title{flex:1;font-size:13px;color:var(--text-color);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tc-net-detail-body{flex:1;overflow-y:auto;padding:12px}.tc-net-detail-section{margin-bottom:16px}.tc-net-detail-label{font-size:11px;color:var(--json-cmt);text-transform:uppercase;margin-bottom:4px}.tc-net-detail-value{font-size:13px;color:var(--text-color);word-break:break-all;background:var(--log-bg);padding:8px 10px;border-radius:4px}.tc-net-detail-value textarea{width:100%;min-height:80px;background:var(--log-bg);border:1px solid var(--border-color);color:var(--text-color);border-radius:4px;padding:8px;font-size:12px;font-family:monospace;resize:vertical}.tc-net-resend-btn{padding:6px 14px;border:none;background:var(--filter-active);color:#fff;cursor:pointer;border-radius:4px;font-size:12px;transition:all .2s}.tc-net-resend-btn:hover{opacity:.85}.tc-net-new-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:var(--console-bg);z-index:100;display:none;flex-direction:column}.tc-net-new-header{display:flex;align-items:center;gap:8px;padding:10px 12px;background:var(--header-bg);border-bottom:1px solid var(--border-color)}.tc-net-new-title{flex:1;font-size:14px;color:var(--text-color)}.tc-net-new-body{flex:1;overflow-y:auto;padding:16px}.tc-net-form-group{margin-bottom:14px}.tc-net-form-label{font-size:12px;color:var(--json-cmt);margin-bottom:4px;display:block}.tc-net-form-input,.tc-net-form-select,.tc-net-form-textarea{width:100%;background:var(--log-bg);border:1px solid var(--border-color);color:var(--text-color);border-radius:4px;padding:8px 10px;font-size:13px;font-family:monospace;outline:0;transition:border-color .2s}.tc-net-form-input:focus,.tc-net-form-select:focus,.tc-net-form-textarea:focus{border-color:var(--filter-active)}.tc-net-form-textarea{min-height:100px;resize:none}.tc-net-form-select{cursor:pointer}.tc-net-send-btn{padding:8px 20px;border:none;background:var(--filter-active);color:#fff;cursor:pointer;border-radius:4px;font-size:13px;transition:all .2s;margin-left:auto;display:block}.tc-net-send-btn:hover{opacity:.85}.tc-net-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:var(--json-cmt);font-size:14px;gap:8px}.tc-net-detail-section-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:4px}.tc-net-detail-copy-section{background:0 0;border:none;color:var(--json-cmt);cursor:pointer;font-size:13px;padding:2px 6px;border-radius:3px;transition:all .2s}.tc-net-detail-copy-section:hover{background:var(--action-bg);color:var(--json-key)}.tc-net-detail-empty{color:var(--json-cmt);opacity:.5;font-style:italic}.tc-net-detail-value.tc-net-detail-code{font-family:monospace;white-space:pre-wrap;word-break:break-all;overflow-x:auto;max-height:400px}.tc-net-detail-url-row{display:flex;align-items:center;gap:6px}.tc-net-detail-url-copy{background:0 0;border:none;color:var(--json-cmt);cursor:pointer;font-size:13px;padding:2px 6px;border-radius:3px;transition:all .2s;flex-shrink:0}.tc-net-detail-url-copy:hover{background:var(--action-bg);color:var(--json-key)}.tc-net-detail-header-actions{display:flex;align-items:center;gap:4px;margin-left:auto}.tc-net-resend-icon-btn{background:0 0;border:none;color:var(--text-color);cursor:pointer;font-size:16px;padding:4px 8px;border-radius:4px;transition:all .2s}.tc-net-resend-icon-btn:hover{background:var(--action-bg);color:var(--json-key)}.tc-net-new-btn-right{margin-left:auto;flex-shrink:0}.tc-network-controls{display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--controls-bg);border-bottom:1px solid var(--border-color)}.tc-filters,.tc-network-filters,.tc-plug-view .tc-filters{display:flex;flex-wrap:nowrap;gap:2px;margin-left:0;overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;position:relative;padding-bottom:2px;min-width:0;flex:0 1 auto;-webkit-overflow-scrolling:touch}.tc-network-filters{flex:1 1 auto}.tc-filter-btn,.tc-net-filter-btn{position:relative;padding:5px 10px;border:none;background:0 0;color:var(--text-color);cursor:pointer;font-size:12px;display:flex;width:auto;white-space:nowrap;border-radius:4px;opacity:.55;transition:opacity .2s,background .2s;flex-shrink:0}.tc-filter-btn>.fa,.tc-net-filter-btn>.fa{margin-right:5px;margin-top:2px}.tc-filter-btn:hover,.tc-net-filter-btn:hover{opacity:1;background:rgba(127,127,127,.14)}.tc-filter-btn.tc-active,.tc-net-filter-btn.tc-active{opacity:1;font-weight:600;background:transparent}.tc-filter-btn.tc-active::after,.tc-net-filter-btn.tc-active::after{content:'';position:absolute;width:80%;left:10%;right:auto;top:auto;height:2px;bottom:0;border-radius:3px;background:var(--filter-active)}.tc-controls{padding:6px 12px}.tc-network-controls{padding:6px 12px}.tc-elements-tree .tc-tree-leaf{white-space:normal;word-break:break-all;max-height:8em;overflow-y:auto}@media(max-width:768px){.tc-controls{overflow:visible;padding:5px 10px}.tc-network-controls{padding:5px 10px}}.tc-filters.tc-overflow-start:not(.tc-overflow-end),.tc-network-filters.tc-overflow-start:not(.tc-overflow-end),.tc-plug-view .tc-filters.tc-overflow-start:not(.tc-overflow-end){-webkit-mask-image:linear-gradient(to right,transparent,#000 40px);mask-image:linear-gradient(to right,transparent,#000 40px)}.tc-filters.tc-overflow-end:not(.tc-overflow-start),.tc-network-filters.tc-overflow-end:not(.tc-overflow-start),.tc-plug-view .tc-filters.tc-overflow-end:not(.tc-overflow-start){-webkit-mask-image:linear-gradient(to left,transparent,#000 40px);mask-image:linear-gradient(to left,transparent,#000 40px)}.tc-filters.tc-overflow-start.tc-overflow-end,.tc-network-filters.tc-overflow-start.tc-overflow-end,.tc-plug-view .tc-filters.tc-overflow-start.tc-overflow-end{-webkit-mask-image:linear-gradient(to right,transparent,#000 40px,#000 calc(100% - 40px),transparent);mask-image:linear-gradient(to right,transparent,#000 40px,#000 calc(100% - 40px),transparent)}.tc-tree-toggle>i{font-size:10px;color:var(--json-cmt);transition:transform .2s;cursor:pointer;width:16px;text-align:center;display:inline-block}",t.setAttribute("tcstyle",""),t.setAttribute("tc-lock",""),document.head.append(t)}setupSplitter(){let t=!1,e=0,s=0;const i=()=>{t=!1,this.splitter.classList.remove("tc-dragging"),document.body.style.cursor="",document.body.style.userSelect=""};this.splitter.addEventListener("mousedown",i=>{i.preventDefault(),t=!0,e=i.clientX,s=this.consoleContainer.offsetWidth||.5*window.innerWidth,this.splitter.classList.add("tc-dragging"),document.body.style.cursor="col-resize",document.body.style.userSelect="none"}),document.addEventListener("mousemove",i=>{if(!t)return;let n=i.clientX,o=window.innerWidth-(s+(e-n));o=Math.max(200,Math.min(window.innerWidth-50,o)),this.consoleContainer&&(this.consoleContainer.style.width=o+"px",this.consoleContainer.style.flex="none")}),document.addEventListener("mouseup",i),this.splitter.addEventListener("touchstart",e=>{e.preventDefault(),t=!0,s=this.consoleContainer.offsetWidth||.5*window.innerWidth,e.touches[0],this.splitter.classList.add("tc-dragging")}),document.addEventListener("touchmove",e=>{if(!t)return;let s=e.touches[0],i=window.innerWidth-s.clientX;i=Math.max(200,Math.min(window.innerWidth-50,i)),this.consoleContainer&&(this.consoleContainer.style.width=i+"px",this.consoleContainer.style.flex="none")}),document.addEventListener("touchend",i)}showNotification(t,e=""){this.notification.innerHTML=`<i class='fa fa-${"warning"==e?"exclamation":"check"}' style='display:inline-block;vertical-align:middle;margin-right:8px'></i>${t.replace(/</,"&lt;").replace(/>/,"&gt;")}`,this.notification.className="tc-notification","warning"===e&&this.notification.classList.add("tc-warning"),this.notification.style.display="block",this.notification.offsetHeight,this.notification.classList.add("tc-show"),clearTimeout(this._notifTimer),this._notifTimer=setTimeout(()=>{this.notification.classList.remove("tc-show"),setTimeout(()=>{this.notification.style.display="none"},300)},3e3)}captureConsoleLogs(){this.originalConsole={log:console.log,info:console.info,warn:console.warn,error:console.error,debug:console.debug,time:console.time,timeEnd:console.timeEnd,count:console.count,countReset:console.countReset,assert:console.assert,trace:console.trace,group:console.group,groupEnd:console.groupEnd,clear:console.clear,table:console.table},console.log=(...t)=>(this.captureConsole("log",...t),console),console.info=(...t)=>(this.captureConsole("info",...t),console),console.warn=(...t)=>(this.captureConsole("warn",...t),console),console.error=(...t)=>(this.captureConsole("error",...t),console),console.debug=(...t)=>(this.captureConsole("log",...t),console),console.table=(t,e)=>(this._captureSubType="table",this._captureExtra={columns:e},this.captureConsole("log",t),this._captureSubType=null,this._captureExtra=null,console),console.time=(t="time")=>{t=String(t);let e=performance.now();this.timerMap.has(t)&&clearTimeout(this.timerMap.get(t).timeoutId);let s=setTimeout(()=>{if(!this.timerMap.has(t))return;let{start:e}=this.timerMap.get(t);this.timerMap.delete(t),console.info(`[time] "${t}"用时: ${(performance.now()-e).toFixed(1)}ms(已超时)`)},3e5);this.timerMap.set(t,{start:e,timeoutId:s}),console},console.timeEnd=(t="time")=>{t=String(t);let e=this.timerMap.get(t);if(!e)return void console.error(`[timeEnd] 标签"${t}"不存在`);e.timeoutId&&clearTimeout(e.timeoutId);let s=performance.now()-e.start;this.timerMap.delete(t),console.info(`[time] "${t}"用时: ${s.toFixed(1)}ms`),console},console.count=(t="count")=>{t=String(t);let e=(this.countMap.get(t)||0)+1;this.countMap.set(t,e),console.info(`[count] 标签"${t}"被调用了${e}次`),console},console.countReset=(t="count")=>{t=String(t),this.countMap.has(t)?this.countMap.delete(t):console.error(`[countReset] 标签"${t}"不存在`),console},console.assert=(t,...e)=>{t||console.error("[assertion failed] ",...e),console},console.trace=(...t)=>{let e=(new Error).stack.split("\n").slice(2).join("\n");console.warn("[trace] ",...t,"\n"+e),console},console.group=t=>(this.captureConsole("log",`[Group ${t}]`),console),console.groupEnd=()=>(this.captureConsole("log","[GroupEnd]"),console),console.clear=()=>(this.clearAllLogs(!0),console)}isClass(t){return"function"==typeof t&&t.prototype&&t.prototype.constructor===t&&!1===Object.getOwnPropertyDescriptor(t,"prototype").writable}safeStringify(e,s=2){let i=new WeakSet,n=(t,e=new WeakSet)=>null===t||"object"!=typeof t?"bigint"==typeof t?""+t.toString()+"n":t:e.has(t)?"[循环引用]":(e.add(t),t instanceof RegExp?""+t.toString():t instanceof Date?""+t.toISOString():"function"==typeof t?"ƒ "+(t.name||"anonymous")+"("+this.getParams(t)+")":t instanceof Error?"[Error: "+t.message+"]":t instanceof ArrayBuffer?"[ArrayBuffer "+t.byteLength+" bytes]":t instanceof WeakMap?"[WeakMap]":t instanceof WeakSet?"[WeakSet]":t instanceof Map?"[Map "+t.size+"]":t instanceof Set?"[Set "+t.size+"]":Array.isArray(t)?t.map(t=>n(t,e)):Object.fromEntries(Object.entries(t).map(([t,s])=>[t,n(s,e)])));return e=n(e),JSON.stringify(e,function(e,s){if(void 0===s)return"undefined";if("number"==typeof s){if(Number.isNaN(s))return"NaN";if(!isFinite(s))return""+(s>0?"Infinity":"-Infinity")}if("object"==typeof s&&null!==s){if(i.has(s))return"[循环引用]";if(i.add(s),!Array.isArray(s)&&s.constructor===Object)return Object.keys(s).sort((t,e)=>{const s="[[Prototype]]"===t,i="[[Prototype]]"===e,n=t.endsWith("[[Prototype]]")&&"[[Prototype]]"!==t,o=e.endsWith("[[Prototype]]")&&"[[Prototype]]"!==e;if(s&&!i)return 1;if(!s&&i)return-1;if(n&&!o)return 1;if(!n&&o)return-1;const a=t.match(/^(_*)/)[0].length,r=e.match(/^(_*)/)[0].length;return a!==r?a-r:t.localeCompare(e,void 0,{numeric:!0,sensitivity:"base"})}).reduce((t,e)=>(t[e]=s[e],t),{});if(s instanceof Error)return{"名称":s.name,"信息":s.message,"堆栈":s.stack};if(s instanceof Date)return s.toISOString();if(s instanceof HTMLElement)return`<${s.tagName.toLowerCase()}>${s.tagName.toLowerCase()}元素</${s.tagName.toLowerCase()}>`}return"string"==typeof s?s.startsWith("")?s:""+s:"function"==typeof s?""+(t.tC.isClass(s)?`[Class ${s.name||"anonymous"}]`:`ƒ ${s.name||"anonymous"}(${t.tC.getParams(s)})`):s},s)}formatArgsForPlainText(t){return Array.from(t).map(t=>{if("object"==typeof t&&null!==t)try{return this.safeStringify(t)}catch{return"[无法序列化]"}return String(t)}).join(" ")}captureConsole(t,...e){this.triggerGlobalHook("beforeLog",t,...e);let s=!1;if(this.mutedFilters.console&&(this.mutedFilters.console.all||this.mutedFilters.console[t])&&(s=!0),this.mutedLogs||s)return void this.originalConsole[t].apply(console,e);let i=new Date,n=e.map(t=>{if("object"==typeof t&&null!==t)try{if(t instanceof HTMLElement)return`el:<${t.tagName.toLowerCase()}>`;if(t instanceof Date)return`d:${t.getTime()}`;if(t instanceof RegExp)return`re:${t.toString()}`;if(t instanceof Error)return`e:${t.message}`;let e=Object.entries(t).reduce((t,[e,s])=>{if("then"===e&&"function"==typeof s)return t;if("object"==typeof s&&null!==s)try{t[e]=JSON.stringify(s)}catch{t[e]="NestedObject"}else t[e]=s;return t},{});return`o:${JSON.stringify(e)}`}catch{return`u:${Math.random().toString(36).substring(2,10)}`}return`${typeof t}:${String(t)}`}).join("|");if(this.lastLog&&this.lastLog.type===t&&this.lastLog.contentSign===n&&(this.lastLog.subType||null)===(this._captureSubType||null)){if(this.lastLog.args=[...e],this.lastLog.timestamp=new Date,this.lastLog.count++,e.some(t=>"object"==typeof t&&null!==t)){let t=this.safeStringify(e[0]);this.jsonPageIndex.has(t)||(this.jsonPageIndex.set(t,0),this.getPagedJson(e[0],0))}let s=document.getElementById(`tc-log-item-${this.lastLog.id}`);if(s){let t=s.querySelector(".tc-log-count");if(t)t.textContent=this.lastLog.count;else{let t=s.querySelector(".tc-log-header");if(t){let e=document.createElement("div");e.className="tc-log-count",e.textContent=this.lastLog.count;let s=t.querySelector(".tc-log-icon");s?t.insertBefore(e,s):t.appendChild(e)}}}return this.originalConsole[t].apply(console,e),void this.updateFilterCounts()}{let s={id:this.logs.length,type:t,args:[...e],content:this.formatArgsForPlainText(e),timestamp:i,count:1,expandedJson:!1,contentSign:n,hasObject:e.some(t=>"object"==typeof t&&null!==t||"function"==typeof t),isError:"error"===t||e.some(t=>t instanceof Error),subType:this._captureSubType||null,subTypeData:this._captureExtra||null};this.logs.push(s),this.lastLog=s,this.triggerGlobalHook("afterLog",s)}this.originalConsole[t].apply(console,e),this.overlay?.classList.contains("tc-active")&&"console"===this.currentTab&&(this.updateFilterCounts(),this.renderLogList(this.logs,!1)),this.logs.length>this.maxLog&&this.logs.splice(0,this.logs.length-this.maxLog)}formatArgs(t,e){let s=e||"x",i=Array.from(t),n=i.map((t,e)=>"function"==typeof t?`<div class="tc-function-preview"><span class="tc-json-boolean">ƒ ${t.name||"anonymous"}</span><span class="tc-json-cmt">(${this.getParams(t)})</span></div>`:t instanceof Error?`<div class="tc-error-stack"><strong>${t.name}:</strong>${t.message}<div>${t.stack||"无堆栈信息"}</div></div>`:t instanceof HTMLElement?'<div class="tc-json-tree-container">'+this.renderHTMLTree(t,"",s+":html")+"</div>":t instanceof Date?`<div class="tc-json-preview"><span class="tc-json-string">${t.toISOString()}</span></div>`:t instanceof RegExp?`<div class="tc-json-preview"><span class="tc-json-number">${t.toString()}</span></div>`:t instanceof Map?`<div class="tc-json-preview"><span class="tc-json-boolean">[Map ${t.size}]</span></div>`:t instanceof Set?`<div class="tc-json-preview"><span class="tc-json-boolean">[Set ${t.size}]</span></div>`:t instanceof WeakMap?'<div class="tc-json-preview"><span class="tc-json-boolean">[WeakMap]</span></div>':t instanceof WeakSet?'<div class="tc-json-preview"><span class="tc-json-boolean">[WeakSet]</span></div>':t instanceof ArrayBuffer?`<div class="tc-json-preview"><span class="tc-json-boolean">[ArrayBuffer ${t.byteLength} bytes]</span></div>`:"object"==typeof t&&null!==t?'<div class="tc-json-tree-container">'+this.renderJSONTree(t,"",null,null,s+":",0)+"</div>":"number"==typeof t?Number.isNaN(t)?'<span class="tc-json-cmt">NaN</span>':isFinite(t)?`<span class="tc-json-number">${t}</span>`:`<span class="tc-json-cmt">${t>0?"Infinity":"-Infinity"}</span>`:"boolean"==typeof t?`<span class="tc-json-boolean">${t}</span>`:String(t).replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\n/g,"<br>"));return i.splice(0,1),n.join(" ")}highlightHTML(t){let e=t.outerHTML.replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/&lt;br&gt;/g,"<br>"),s="",i=0;for(;i<e.length;)if(e.startsWith("&lt;",i)){let t=e[i+4];if(t&&("/"===t||/[a-zA-Z]/.test(t))){let t=e.indexOf("&gt;",i);if(-1!==t){let n=e.slice(i,t+4);n=n.replace(/([\w-]+)(=)("[^"]*")/g,'<span style="color:#56b6c2">$1</span><span class="tc-json-boolean">$2</span><span class="tc-json-string">$3</span>'),n=n.replace(/^(&lt;\/?)([\w-]+)/,'<span class="tc-json-boolean">$1</span><span class="tc-json-boolean">$2</span>'),n=n.replace(/(&gt;)$/,'<span class="tc-json-boolean">$1</span>'),s+=n,i=t+4;continue}}let n=e.indexOf("&lt;",i+4);-1===n&&(n=e.length);let o=e.slice(i,n);s+=o.trim()?`<span class="tc-json-cmt">${o}</span>`:o,i=n}else if(e.startsWith("<br>",i))s+="<br>",i+=4;else{let t=e.indexOf("&lt;",i);-1===t&&(t=e.length);let n=e.slice(i,t);s+=n.trim()?`<span class="tc-json-cmt">${n}</span>`:n,i=t}return s}highlightJson=t=>t&&t.replace(/("(?:\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(?:\s*:)?|\b(?:true|false|null)\b|-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?\b|[\{\}\[\],.:])/g,t=>{let e="tc-json-cmt";if("true"===t||"false"===t)e="tc-json-boolean";else if("null"===t)e="tc-json-null";else if(/^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(t))e="tc-json-number";else if(t.endsWith(":"))e="tc-json-key";else if(t.startsWith('"')){let s=t.slice(1,-1);if(/^\\u0002/.test(s))return`<span class="tc-json-string">"${s.slice(6)}"</span>`;if(/^\\u0003/.test(s)){let t=s.slice(6);if(/^-?\d+n$/.test(t))return`<span class="tc-json-number">${t}</span>`;if(/^\u0192\s/.test(t)){let e=t.match(/^(\u0192\s+\S+)(\(.*\))$/);return e?`<span class="tc-json-boolean">${e[1]}</span><span class="tc-json-cmt">${e[2]}</span>`:`<span class="tc-json-boolean">${t}</span>`}return/^\[(?:Class|ArrayBuffer|Map|Set|WeakMap|WeakSet|Error)/.test(t)?`<span class="tc-json-boolean">${t}</span>`:/^\/.*\/[gimsuy]*$/.test(t)?`<span class="tc-json-number">${t}</span>`:/^\d{4}-\d{2}-\d{2}T/.test(t)?`<span class="tc-json-string">${t}</span>`:/^(?:undefined|NaN|Infinity|-Infinity)$/.test(t)?`<span class="tc-json-null">${t}</span>`:`<span class="tc-json-string">${t}</span>`}e="tc-json-string"}return`<span class="${e}">${t}</span>`})||"";getJsonKeys(t){return Array.isArray(t)?t.map((t,e)=>e):"object"==typeof t&&null!==t?Object.keys(t):[]}renderJSONValue(t,e){if(null===t)return'<span class="tc-json-null">null</span>';if(void 0===t)return'<span class="tc-json-null">undefined</span>';if("string"==typeof t)return'<span class="tc-json-string">"'+this.escapeHtml(t)+'"</span>';if("number"==typeof t)return'<span class="tc-json-number">'+t+"</span>";if("boolean"==typeof t)return'<span class="tc-json-boolean">'+t+"</span>";let s=Array.isArray(t),i=s?"Array("+t.length+")":"Object",n=s?t.map((t,e)=>({name:String(e),value:t})):Object.keys(t).map(e=>({name:e,value:t[e]}));if(0===n.length)return'<span class="tc-json-cmt">'+(e?this.escapeHtml(e)+": ":"")+(s?"[]":"{}")+"</span>";let o='<div class="tc-tree-node tc-collapsed">';o+='<span class="tc-tree-toggle"><i class="fa fa-angle-right"></i></span>',e&&(o+='<span class="tc-json-key">'+this.escapeHtml(e)+":</span> "),o+='<span class="tc-tree-label">'+this.escapeHtml(i)+"</span>",o+='<span class="tc-tree-brace tc-tree-open">{</span><span class="tc-tree-brace tc-tree-collapsed">{...}</span>';let a=++this.treeNodeRegId;return this.treeNodeRegistry.set(a,{obj:t,children:n,isJsonValue:!0}),o+='<div class="tc-tree-children" data-lazy-id="'+a+'"></div>',o+='<span class="tc-tree-brace tc-tree-close">}</span>',o+="</div>",o}renderJSONValueChildren(t,e){let s="";for(let e of t){let t=e.value;s+=null===t||"object"!=typeof t?'<div class="tc-tree-leaf"><span class="tc-tree-spacer"></span><span class="tc-json-key">'+this.escapeHtml(e.name)+":</span> "+this.renderJSONValue(t,"")+"</div>":"<div>"+this.renderJSONValue(t,e.name)+"</div>"}return s}getPagedJson(t,e){let s=this.safeStringify(t);if(!this.jsonPageCache.has(s)){let e=this.getJsonKeys(t),i=[];for(let t=0;t<e.length;t+=this.jsonPageSize)i.push(e.slice(t,t+this.jsonPageSize));this.jsonPageCache.set(s,i)}let i=this.jsonPageCache.get(s)[e]||[];if(Array.isArray(t))return i.map(e=>t[e]);{let e={};return i.forEach(s=>e[s]=t[s]),e}}changeJsonPage(t,e){let s=`log-${t}`;this.jsonPageIndex.set(s,e);let i=this.logs.find(e=>e.id===t);if(i){let e=this.consoleOutput;e&&e._vs?(e._vs.heights=new Map,e._vs.lastStart=-1,e._vs.lastEnd=-1,this.renderViewport(e)):this.updateLogItem(t,!1)}}toggleExpandJson(t){}updateLogItem(t,e=!1){let s=this.logs.find(e=>e.id===t);if(!s)return;let i=document.getElementById(`tc-log-item-${t}`);if(!i)return;let n={info:"fa fa-info-circle",warn:"fa fa-exclamation-triangle",error:"fa fa-times-circle",log:"fa fa-info"}[s.type]||"fa fa-info",o=s.timestamp.toLocaleTimeString(),a=this.formatArgs(s.args,s.id);i.innerHTML=`<div class="tc-log-header">${s.count>1?`<div class="tc-log-count">${s.count}</div>`:""}<div class="tc-log-icon"><i class="${n}"></i></div><div class="tc-timestamp">${o}</div></div><div class="tc-log-content">${a}</div>`}updateControlsVisibility(){let t=this.overlay.querySelector("#tc-consoleControls"),e="console"===this.currentTab,s="localstorage"===this.currentTab,i="network"===this.currentTab,n=()=>{this.netNewBtn&&(this.netNewBtn.style.display="none")};e?(t.style.display="flex",this.overlay.querySelector("#tc-filtersContainer")&&(this.overlay.querySelector("#tc-filtersContainer").style.display="flex"),this.lsFiltersContainer&&(this.lsFiltersContainer.style.display="none"),this.muteBtn&&(this.muteBtn.style.display="flex"),this.logCopyBtn&&(this.logCopyBtn.style.display=null!==this.selectedLogId?"flex":"none"),this.lsAddBtn&&(this.lsAddBtn.style.display="none"),n(),this.elementPickBtn&&(this.elementPickBtn.style.display="none"),this.elCopyBtn&&(this.elCopyBtn.style.display="none"),this.elDeleteBtn&&(this.elDeleteBtn.style.display="none")):s?(t.style.display="flex",this.overlay.querySelector("#tc-filtersContainer")&&(this.overlay.querySelector("#tc-filtersContainer").style.display="none"),this.lsFiltersContainer&&(this.lsFiltersContainer.style.display="flex"),this.muteBtn&&(this.muteBtn.style.display="none"),this.logCopyBtn&&(this.logCopyBtn.style.display="none"),this.lsAddBtn&&(this.lsAddBtn.style.display="flex"),n(),this.elementPickBtn&&(this.elementPickBtn.style.display="none"),this.elCopyBtn&&(this.elCopyBtn.style.display="none"),this.elDeleteBtn&&(this.elDeleteBtn.style.display="none")):i?(t.style.display="none",this.logCopyBtn&&(this.logCopyBtn.style.display="none"),this.lsAddBtn&&(this.lsAddBtn.style.display="none"),this.netNewBtn&&(this.netNewBtn.style.display="flex"),this.searchBar&&(this.searchBar.style.display="flex"),this.searchToggleBtn&&(this.searchToggleBtn.style.display="flex"),this.elementPickBtn&&(this.elementPickBtn.style.display="none"),this.elCopyBtn&&(this.elCopyBtn.style.display="none"),this.elDeleteBtn&&(this.elDeleteBtn.style.display="none")):"elements"===this.currentTab?(t.style.display="none",this.logCopyBtn&&(this.logCopyBtn.style.display="none"),this.lsAddBtn&&(this.lsAddBtn.style.display="none"),n(),this.searchBar&&(this.searchBar.style.display="none"),this.searchToggleBtn&&(this.searchToggleBtn.style.display="none"),this.elementPickBtn&&(this.elementPickBtn.style.display="flex"),this.elCopyBtn&&(this.elCopyBtn.style.display="flex"),this.elDeleteBtn&&(this.elDeleteBtn.style.display="flex")):(t.style.display="none",this.logCopyBtn&&(this.logCopyBtn.style.display="none"),this.lsAddBtn&&(this.lsAddBtn.style.display="none"),n(),this.elementPickBtn&&(this.elementPickBtn.style.display="none"),this.elCopyBtn&&(this.elCopyBtn.style.display="none"),this.elDeleteBtn&&(this.elDeleteBtn.style.display="none")),this.searchBar&&"elements"!==this.currentTab&&(this.searchBar.style.display=this.searchExpanded?"flex":"none"),this.searchToggleBtn&&(this.searchToggleBtn.style.display="elements"===this.currentTab?"none":"flex"),this.updateEditorVisibility()}updateEditorVisibility(){if(!this.lsEditorOverlay)return;let t=this.editorState.visible;if(t&&"ls"===this.editorState.mode&&"localstorage"!==this.currentTab&&(t=!1),this.lsEditorOverlay.style.display=t?"flex":"none",t){let t="code"===this.editorState.mode;this.lsEditorKeyInput&&(this.lsEditorKeyInput.style.display=t?"none":"block"),this.lsEditorTitle.textContent=t?"运行代码":"",this.lsEditorInput.placeholder=t?"输入要执行的代码...":"输入值...",this.lsEditorSave.textContent=t?"运行":"保存",this.lsEditorSave.className="tc-ls-editor-btn "+(t?"tc-run":"tc-save"),this.lsEditorInput.value!==this.editorState.value&&(this.lsEditorInput.value=this.editorState.value),!t&&this.lsEditorKeyInput&&this.lsEditorKeyInput.value!==this.editorState.key&&(this.lsEditorKeyInput.value=this.editorState.key)}}setupVirtualScroll(t){if(!t)return;t._vs={items:[],renderItem:null,afterRender:null,avgHeight:70,estHeight:70,heights:new Map,lastStart:-1,lastEnd:-1,rafId:null,isAtBottom:!0,contentEl:null,topSpacer:null,bottomSpacer:null,fakeEl:null,hasStructure:!1,topSpaceHeight:0,lastScrollTop:0,lastTimestamp:0,speedToleranceFactor:100,maxSpeedTolerance:2e3,minSpeedTolerance:100};let e=document.createElement("div");e.className="tc-vs-spacer",e.style.cssText="width:100%;flex-shrink:0;height:0";let s=document.createElement("div");s.className="tc-vs-content",s.style.cssText="width:100%";let i=document.createElement("div");i.className="tc-vs-spacer",i.style.cssText="width:100%;flex-shrink:0;height:0";let n=document.createElement("div");n.style.cssText="position:absolute;visibility:hidden;left:0;top:0;width:100%;pointer-events:none",t.innerHTML="",t.appendChild(e),t.appendChild(s),t.appendChild(i),t.appendChild(n),t._vs.topSpacer=e,t._vs.contentEl=s,t._vs.bottomSpacer=i,t._vs.fakeEl=n,t._vs.hasStructure=!0,t.addEventListener("scroll",()=>{let e=t._vs;if(!e)return;let s=t.scrollHeight,i=t.clientHeight,n=t.scrollTop;e.isAtBottom=Math.abs(s-i-n)<2;let o,a,r=Date.now(),l=r-e.lastTimestamp,c=n-e.lastScrollTop,d=Math.abs(c/(l||1))*e.speedToleranceFactor;l>1e3&&(d=1e3),d>e.maxSpeedTolerance&&(d=e.maxSpeedTolerance),d<e.minSpeedTolerance&&(d=e.minSpeedTolerance),e.lastScrollTop=n,e.lastTimestamp=r,e.lastScrollTop<n?(o=e.minSpeedTolerance,a=d):(o=d,a=e.minSpeedTolerance),e.topSpaceHeight<n-o&&e.topSpaceHeight+e.contentEl.offsetHeight>n+i+a||(e.rafId&&(cancelAnimationFrame(e.rafId),e.rafId=null),e.rafId=requestAnimationFrame(()=>{e.rafId=null,this.renderViewport(t)}))},{passive:!0})}renderViewport(t){let e=t._vs;if(!e||!e.contentEl)return;if(!e.items||!e.items.length)return;let s=t.clientHeight||400,i=t.scrollTop,n=e.estHeight;n<10&&(n=70);let o=600,a=i-o,r=i+s+o,l=0,c=0,d=0,h=e.items.length,p=!1;for(let t=0;t<e.items.length;t++){let s=e.heights.get(t)||n;if(!p&&l+s>=a&&(d=t,p=!0),l>=r){h=t;break}l+=s}if(p){if(h===e.items.length){h=e.items.length;let t=h;for(;t>d&&c<s+o;)t--,c+=e.heights.get(t)||n;d=Math.max(0,Math.min(d,t))}}else d=0;let u=!1;for(let t=d;t<h;t++)if(!e.heights.has(t)){u=!0;break}if(u&&e.fakeEl){let s=e.fakeEl,i=t.clientWidth;i>0&&(s.style.width=i+"px");for(let t=d;t<h;t++)if(!e.heights.has(t)){s.innerHTML=e.renderItem(e.items[t],t);let i=0;s.firstChild&&(i=s.firstChild.offsetHeight+10),i<10&&(i=n),e.heights.set(t,i)}s.innerHTML=""}l=0,c=0,d=0,h=e.items.length,p=!1;for(let t=0;t<e.items.length;t++){let s=e.heights.get(t)||n;if(!p&&l+s>=a&&(d=t,p=!0),l>=r){h=t;break}l+=s}if(p){if(h===e.items.length){h=e.items.length;let t=h;for(;t>d&&c<s+o;)t--,c+=e.heights.get(t)||n;d=Math.max(0,Math.min(d,t))}}else d=0;if(d===e.lastStart&&h===e.lastEnd)return void(e.isAtBottom&&(t.scrollTop=1e7));e.lastStart=d,e.lastEnd=h;let f=0;for(let t=0;t<d;t++)f+=e.heights.get(t)||n;let g=0;for(let t=h;t<e.items.length;t++)g+=e.heights.get(t)||n;e.topSpacer.style.height=f+"px",e.bottomSpacer.style.height=g+"px",e.topSpaceHeight=f;let m=[];for(let t=d;t<h;t++)m.push(e.renderItem(e.items[t],t));e.contentEl.innerHTML=m.join("");let b=e.contentEl.children;if(b.length>=1)for(let t=0;t<b.length;t++){let s=b[t].offsetHeight+10;Math.abs(s-(e.heights.get(d+t)||n))>5&&e.heights.set(d+t,s)}if(0===g&&b.length>0){let i=0;for(let t=0;t<b.length;t++)i+=b[t].offsetHeight+10;if(i<s&&d>0){let o=Math.ceil((s-i)/n)+2;if(Math.max(0,d-o)<d)return e.lastStart=-1,e.lastEnd=-1,this.renderViewport(t)}}e.isAtBottom&&(t.scrollTop=1e7),e.afterRender&&e.afterRender()}vsSetItems(t,e,s,i,n){let o=t._vs;if(o){if(o.items=e,o.renderItem=s,o.avgHeight=i||70,o.heights=new Map,o.lastStart=-1,o.lastEnd=-1,o.isAtBottom=!1,!e||!e.length)return o.contentEl.innerHTML="",o.topSpacer.style.height="0",o.bottomSpacer.style.height="0",void(o.topSpaceHeight=0);t.scrollTop=0,this.renderViewport(t)}}vsRefreshHeights(t){let e=t._vs;if(!e||!e.contentEl)return;let s=e.contentEl.children;if(s.length>0){let t=0;for(let i=0;i<s.length;i++){let n=s[i].offsetHeight+10;e.heights.set(e.lastStart+i,n),t+=n}let i=t/s.length;i>20&&i<2e3&&(e.avgHeight=Math.round(.5*e.avgHeight+.5*i))}let i=0;for(let t=0;t<e.lastStart;t++)i+=e.heights.get(t)||e.avgHeight;let n=0;for(let t=e.lastEnd;t<e.items.length;t++)n+=e.heights.get(t)||e.avgHeight;e.topSpacer.style.height=i+"px",e.bottomSpacer.style.height=n+"px",e.topSpaceHeight=i,0===n&&e.isAtBottom&&(t.scrollTop=1e7)}vsShowMessage(t,e){let s=t._vs;s&&s.contentEl?(s.items=[],s.topSpacer.style.height="0",s.bottomSpacer.style.height="0",s.topSpaceHeight=0,s.contentEl.innerHTML=e,t.scrollTop=0,s.lastStart=-1,s.lastEnd=-1,s.isAtBottom=!0):t.innerHTML=e}isNearBottom(t){let e=t._vs;if(!e)return!0;let s=t.scrollHeight,i=t.clientHeight,n=t.scrollTop;return e.isAtBottom=Math.abs(s-i-n)<2,e.isAtBottom}renderSubTypeContent(t){let e=t.args&&t.args.length>0?t.args[0]:void 0;return"table"===t.subType?this.renderTableHTML(e,t.subTypeData?.columns):""}renderJSONTree(t,e,s,i,n,o,a){if(s||(s=new WeakSet),i||(i=[]),o=o||0,null===t)return'<span class="tc-json-null">null</span>';if(void 0===t)return'<span class="tc-json-null">undefined</span>';if("string"==typeof t)return'<span class="tc-json-string">"'+this.escapeHtml(t)+'"</span>';if("number"==typeof t)return'<span class="tc-json-number">'+t+"</span>";if("boolean"==typeof t)return'<span class="tc-json-boolean">'+t+"</span>";if("bigint"==typeof t)return'<span class="tc-json-number">'+t.toString()+"n</span>";if("symbol"==typeof t){let e=Object.create(Object.getPrototypeOf(Object(t)));Object.defineProperty(e,"value",{value:t.toString(),enumerable:!0,writable:!0,configurable:!0}),Object.defineProperty(e,"description",{value:t.description,enumerable:!0,writable:!0,configurable:!0}),t=e}if("function"==typeof t){let e=t.name||"anonymous";return this.isClass(t)?'<span class="tc-json-boolean">[Class '+this.escapeHtml(e)+"]</span>":'<span class="tc-json-boolean">ƒ '+this.escapeHtml(e)+'</span><span class="tc-json-cmt">('+this.getParams(t)+")</span>"}if(t instanceof Date)return'<span class="tc-json-string">'+t.toISOString()+"</span>";if(t instanceof RegExp)return'<span class="tc-json-number">'+t.toString()+"</span>";if(t instanceof Map)return'<span class="tc-json-boolean">[Map '+t.size+"]</span>";if(t instanceof Set)return'<span class="tc-json-boolean">[Set '+t.size+"]</span>";if(t instanceof WeakMap)return'<span class="tc-json-boolean">[WeakMap]</span>';if(t instanceof WeakSet)return'<span class="tc-json-boolean">[WeakSet]</span>';if(t instanceof ArrayBuffer)return'<span class="tc-json-boolean">[ArrayBuffer '+t.byteLength+" bytes]</span>";if(t instanceof Error)return'<span class="tc-json-boolean">[Error: '+this.escapeHtml(t.message)+"]</span>";if(t instanceof HTMLElement)return this.renderHTMLTree(t,e,n+".html");if(s.has(t))return'<span class="tc-json-cmt">[循环引用]</span>';s.add(t);let r=i.concat([t]),l=Array.isArray(t),c=l?"Array("+t.length+")":t.constructor&&t.constructor.name?t.constructor.name:"Object",d=[];try{Reflect.ownKeys(t).forEach(e=>{let s=Object.getOwnPropertyDescriptor(t,e);s&&d.push({name:String(e),desc:s})})}catch(e){try{Object.keys(t).forEach(e=>{let s=Object.getOwnPropertyDescriptor(t,e);s&&d.push({name:String(e),desc:s})})}catch(e){return s.delete(t),'<span class="tc-json-boolean">['+this.escapeHtml(c)+"]</span>"}}let h=Object.getPrototypeOf(t);if(!a&&h&&null!==h&&d.push({name:"[[Prototype]]",desc:{value:h,enumerable:!0,writable:!0,configurable:!0}}),0===d.length)return s.delete(t),l?'<span class="tc-json-cmt">'+(e?this.escapeHtml(e)+": ":"")+"[]</span>":'<span class="tc-json-cmt">'+(e?this.escapeHtml(e)+": ":"")+"{}</span>";l||d.sort((t,e)=>{if("[[Prototype]]"===t.name)return 1;if("[[Prototype]]"===e.name)return-1;let s=!(!t.desc.get&&!t.desc.set),i=!(!e.desc.get&&!e.desc.set);if(s&&!i)return 1;if(!s&&i)return-1;let n=(t.name.match(/^(_*)/)||[""])[0].length,o=(e.name.match(/^(_*)/)||[""])[0].length;if(n!==o)return n-o;let a=/^[A-Z]/.test(t.name),r=/^[A-Z]/.test(e.name);return a&&!r?1:!a&&r?-1:t.name.localeCompare(e.name,void 0,{numeric:!0,sensitivity:"base"})});let p=n||"",u=this.expandedTreePaths.has(p),f='<div class="tc-tree-node'+(u?" tc-expanded":" tc-collapsed")+'" data-tree-path="'+this.escapeHtml(p)+'">';if(f+='<span class="tc-tree-toggle"><i class="fa '+(u?"fa-angle-down":"fa-angle-right")+'"></i></span>',e&&(f+='<span class="tc-json-key">'+this.escapeHtml(e)+":</span> "),f+='<span class="tc-tree-label">'+this.escapeHtml(c)+"</span>",f+='<span class="tc-tree-brace tc-tree-open">{</span><span class="tc-tree-brace tc-tree-collapsed">{...}</span>',u){f+='<div class="tc-tree-children">';let t=200;if(d.length>t){let e=this.treeNodeRegId++;this.treeNodeRegistry.set(e,{children:d,chain:r,noProto:a}),f+=this.renderTreeChildrenBatch(d,s,0,t,r,p,o+1,a),f+='<div class="tc-tree-load-more" data-reg-id="'+e+'" data-offset="'+t+'"><i class="fa fa-angle-down"></i> 展开更多 (剩余 '+(d.length-t)+" 项)</div>"}else f+=this.renderTreeChildrenBatch(d,s,0,d.length,r,p,o+1,a);f+="</div>"}else{let e=this.treeNodeRegId++;this.treeNodeRegistry.set(e,{obj:t,children:d,chain:i,path:p,noProto:a}),f+='<div class="tc-tree-children" data-lazy-id="'+e+'"></div>'}return f+='<span class="tc-tree-brace tc-tree-close">}</span>',f+="</div>",s.delete(t),f}renderTreeChildrenBatch(t,e,s,i,n,o,a,r){a=a||0;let l="";for(let c=s;c<i&&c<t.length;c++){let s=t[c];if(s.desc.get||s.desc.set)s.desc.get&&(l+='<div class="tc-tree-leaf"><span class="tc-tree-spacer"></span><span class="tc-json-key">get '+this.escapeHtml(s.name)+":</span> "+this.renderJSONTree(s.desc.get,"",e,n,o+"."+s.name,a+1,r)+"</div>"),s.desc.set&&(l+='<div class="tc-tree-leaf"><span class="tc-tree-spacer"></span><span class="tc-json-key">set '+this.escapeHtml(s.name)+":</span> "+this.renderJSONTree(s.desc.set,"",e,n,o+"."+s.name,a+1,r)+"</div>");else{let t=s.desc.value;null===t||"object"!=typeof t||Array.isArray(t)||t instanceof Date||t instanceof RegExp||t instanceof Map||t instanceof Set||t instanceof WeakMap||t instanceof WeakSet||t instanceof ArrayBuffer||t instanceof Error||t instanceof HTMLElement||"function"==typeof t?l+='<div class="tc-tree-leaf"><span class="tc-tree-spacer"></span><span class="tc-json-key">'+this.escapeHtml(s.name)+":</span> "+this.renderJSONTree(t,"",e,n,o+"."+s.name,a+1,r)+"</div>":e.has(t)?l+='<div class="tc-tree-leaf"><span class="tc-tree-spacer"></span><span class="tc-json-key">'+this.escapeHtml(s.name)+':</span> <span class="tc-json-cmt">[循环引用]</span></div>':l+="<div>"+this.renderJSONTree(t,s.name,e,n,o+"."+s.name,a+1,r)+"</div>"}}return l}renderDomChild(t,e,s,i){return 1===t.nodeType?"<div>"+e(t,s,i)+"</div>":3===t.nodeType?'<div class="tc-tree-leaf"><span class="tc-tree-spacer"></span><span class="tc-json-cmt">'+this.escapeHtml(t.textContent.trim())+"</span></div>":""}renderDomChildrenLazy(t,e,s,i,n){let o="";if(t.length>200){let a=this.treeNodeRegId++;this.treeNodeRegistry.set(a,Object.assign({type:i,children:t,depth:s},n));for(let i=0;i<200;i++)o+=this.renderDomChild(t[i],e,i,s+1);o+='<div class="tc-tree-load-more" data-reg-id="'+a+'" data-offset="200"><i class="fa fa-angle-down"></i> 展开更多 ('+(t.length-200)+")</div>"}else{let i=0;for(let n of t)o+=this.renderDomChild(n,e,i,s+1),1===n.nodeType&&i++}return o}buildShadowLazy(t,e,s,i,n){let o='<div class="tc-tree-node tc-collapsed" ';if("element"===e){let e=++this.elRefId;this.elRefMap.set(e,t.root),o+='data-el-id="'+e+'" data-shadow-host="'+n+'"'}else o+='data-tree-path="'+this.escapeHtml(s+".shadow")+'" data-shadow-root="1"';o+='><span class="tc-tree-toggle"><i class="fa fa-angle-right"></i></span><span class="tc-tree-label tc-json-null">#shadow('+t.mode+")</span>";let a=Array.from(t.root.childNodes).filter(t=>1===t.nodeType||3===t.nodeType&&t.textContent.trim());if(a.length>0){let n=this.treeNodeRegId++;this.treeNodeRegistry.set(n,{type:e+"-shadow",shadowInfo:t,path:s,depth:i,children:a}),o+='<span class="tc-tree-ellipsis">...</span><div class="tc-tree-children" data-lazy-id="'+n+'"></div>'}return o+"</div>"}loadMoreTreeChildren(t){let e=parseInt(t.dataset.regId),s=parseInt(t.dataset.offset),i=this.treeNodeRegistry.get(e);if(!i)return;let n=t.closest(".tc-console-output, .tc-ls-items, .tc-elements-tree");if("html"===i.type){let e=Math.min(s+200,i.children.length),n="";for(let t=s;t<e;t++)n+=this.renderDomChild(i.children[t],(t,e)=>this.renderHTMLTree(t,"",i.path+"."+e,(i.depth||0)+1),t,0);t.insertAdjacentHTML("beforebegin",n)}else if("element"===i.type){let e=Math.min(s+200,i.children.length),n="";for(let t=s;t<e;t++)n+=this.renderDomChild(i.children[t],t=>this.renderElementTree(t,(i.depth||0)+1),t,0);t.insertAdjacentHTML("beforebegin",n)}else{let e=new WeakSet;i.chain.forEach(t=>e.add(t)),t.insertAdjacentHTML("beforebegin",this.renderTreeChildrenBatch(i.children,e,s,Math.min(s+200,i.children.length),i.chain,i.path||"",1,i.noProto))}let o=s+200;o<i.children.length?(t.dataset.offset=o,t.innerHTML='<i class="fa fa-angle-down"></i> 展开更多 ('+(i.children.length-o)+")"):(t.remove(),this.treeNodeRegistry.delete(e)),n&&this.vsRefreshHeights(n)}renderHTMLTree(t,e,s,i){if((i=i||0)>30)return'<span class="tc-json-cmt">[depth limit]</span>';s=s||"";let n=t.tagName.toLowerCase(),o="";for(let e of t.attributes)o+=e.value?' <span style="color:#56b6c2">'+this.escapeHtml(e.name)+'</span><span class="tc-json-boolean">=</span><span class="tc-json-string">"'+this.escapeHtml(e.value)+'"</span>':' <span style="color:#56b6c2">'+this.escapeHtml(e.name)+"</span>";let a=Array.from(t.childNodes),r=this.getShadowRoot(t),l=r&&Array.from(r.root.childNodes).some(t=>1===t.nodeType||3===t.nodeType&&t.textContent.trim()),c=r&&(l||r.mode&&"closed"===r.mode),d=a.some(t=>1===t.nodeType)||a.filter(t=>3===t.nodeType&&t.textContent.trim()).length>0||!!c,h=this.expandedTreePaths.has(s),p='<div class="tc-tree-node'+(h?" tc-expanded":" tc-collapsed")+'" data-tree-path="'+this.escapeHtml(s)+'">';if(p+=d?'<span class="tc-tree-toggle"><i class="fa '+(h?"fa-angle-down":"fa-angle-right")+'"></i></span>':'<span class="tc-tree-spacer"></span>',e&&(p+='<span class="tc-json-key">'+this.escapeHtml(e)+":</span> "),p+='<span class="tc-tree-label tc-json-boolean">&lt;'+n+o+"&gt;</span>",d){if(p+='<span class="tc-tree-ellipsis">...</span>',h){p+='<div class="tc-tree-children">';let t=a.filter(t=>1===t.nodeType||3===t.nodeType&&t.textContent.trim());if(p+=this.renderDomChildrenLazy(t,(t,e,i)=>this.renderHTMLTree(t,"",s+"."+e,i),i,"html",{path:s}),c)if(this.expandedTreePaths.has(s+".shadow")){let t=Array.from(r.root.childNodes).filter(t=>1===t.nodeType||3===t.nodeType&&t.textContent.trim());p+='<div class="tc-tree-node tc-expanded" data-tree-path="'+this.escapeHtml(s+".shadow")+'" data-shadow-root="1"><span class="tc-tree-toggle"><i class="fa fa-angle-down"></i></span><span class="tc-tree-label tc-json-null">#shadow('+r.mode+')</span><span class="tc-tree-ellipsis">...</span><div class="tc-tree-children">'+this.renderDomChildrenLazy(t,(t,e,i)=>this.renderHTMLTree(t,"",s+".shadow."+e,i),i,"html-shadow",{shadowInfo:r,path:s})+"</div></div>"}else p+=this.buildShadowLazy(r,"html",s,i);p+="</div>"}else{let t=a.filter(t=>1===t.nodeType||3===t.nodeType&&t.textContent.trim()),e=this.treeNodeRegId++;this.treeNodeRegistry.set(e,{type:"html",children:t,path:s,depth:i,shadow:c?r:null}),p+='<div class="tc-tree-children" data-lazy-id="'+e+'"></div>'}p+='<span class="tc-tree-label tc-json-boolean tc-tree-close-tag">&lt;/'+n+"&gt;</span>"}else p+='<span class="tc-tree-label tc-json-boolean tc-tree-close-tag">&lt;/'+n+"&gt;</span>";return p+="</div>",p}renderElementsView(){if(!this.elementsTree)return;let t=document.documentElement;this.elRefMap=new Map,this.elRefId=0;let e=this.renderElementTree(t,0);this.elementsTree.innerHTML=e,this.pendingHighlight?this.expandToElement(this.pendingHighlight):this.selectedElement&&this.restoreElementSelection()}restoreElementSelection(){if(!this.selectedElement||!this.elementsTree)return;let t=null;for(let[e,s]of this.elRefMap)if(s===this.selectedElement){t=e;break}if(null===t)return;let e=this.elementsTree.querySelector('.tc-tree-node[data-el-id="'+t+'"]');if(!e)return;let s=e;for(;s&&s!==this.elementsTree;)s.classList.contains("tc-tree-node")&&(s.classList.remove("tc-collapsed"),s.classList.add("tc-expanded"),s.querySelector(":scope > .tc-tree-toggle > i")&&(s.querySelector(":scope > .tc-tree-toggle > i").classList.remove("fa-angle-right"),s.querySelector(":scope > .tc-tree-toggle > i").classList.add("fa-angle-down")),s.dataset.elId&&this.elRefMap&&this.elRefMap.get(parseInt(s.dataset.elId))&&this.expandedElements.add(this.elRefMap.get(parseInt(s.dataset.elId)))),s=s.parentElement;this.elementsTree.querySelectorAll(".tc-el-selected").forEach(t=>t.classList.remove("tc-el-selected")),e.classList.add("tc-el-selected"),e.classList.add("tc-el-highlight"),requestAnimationFrame(()=>{e.scrollIntoView({behavior:"smooth",block:"center"}),setTimeout(()=>e.classList.remove("tc-el-highlight"),3e3)})}renderElementTree(t,e){if(t===this.overlay||t===this.notification||t===this.btn)return"";if(t.nodeType&&3===t.nodeType){let e=t.textContent.trim();return e?'<div class="tc-tree-leaf"><span class="tc-tree-spacer"></span><span class="tc-json-cmt">'+this.escapeHtml(e)+"</span></div>":""}if(1!==t.nodeType)return"";let s=t.tagName.toLowerCase(),i="";for(let e of t.attributes)i+=e.value?' <span style="color:#56b6c2">'+this.escapeHtml(e.name)+'</span><span class="tc-json-boolean">=</span><span class="tc-json-string">"'+this.escapeHtml(e.value)+'"</span>':' <span style="color:#56b6c2">'+this.escapeHtml(e.name)+"</span>";let n=Array.from(t.childNodes).filter(t=>1===t.nodeType||3===t.nodeType&&t.textContent.trim()),o=this.getShadowRoot(t),a=o&&Array.from(o.root.childNodes).some(t=>1===t.nodeType||3===t.nodeType&&t.textContent.trim()),r=o&&(a||o.mode&&"closed"===o.mode),l=n.length>0||!!r,c=0===e||this.expandedElements.has(t),d=++this.elRefId;this.elRefMap.set(d,t);let h='<div class="tc-tree-node'+(c?" tc-expanded":" tc-collapsed")+'" data-el-id="'+d+'">';if(h+=l?'<span class="tc-tree-toggle"><i class="fa '+(c?"fa-angle-down":"fa-angle-right")+'"></i></span>':'<span class="tc-tree-spacer"></span>',h+='<span class="tc-tree-label tc-json-boolean">&lt;'+s+i+"&gt;</span>",l){if(h+='<span class="tc-tree-ellipsis">...</span>',c){if(h+='<div class="tc-tree-children">',h+=this.renderDomChildrenLazy(n,(t,e,s)=>this.renderElementTree(t,s),e,"element",{}),r)if(this.expandedElements.has(o.root)||0===e){let t=Array.from(o.root.childNodes).filter(t=>1===t.nodeType||3===t.nodeType&&t.textContent.trim()),s=++this.elRefId;this.elRefMap.set(s,o.root),h+='<div class="tc-tree-node tc-expanded" data-el-id="'+s+'" data-shadow-host="'+d+'"><span class="tc-tree-toggle"><i class="fa fa-angle-down"></i></span><span class="tc-tree-label tc-json-null">#shadow('+o.mode+')</span><span class="tc-tree-ellipsis">...</span><div class="tc-tree-children">'+this.renderDomChildrenLazy(t,(t,e,s)=>this.renderElementTree(t,s),e,"element-shadow",{})+"</div></div>"}else h+=this.buildShadowLazy(o,"element",null,e,d);h+="</div>"}else{let t=this.treeNodeRegId++;this.treeNodeRegistry.set(t,{type:"element",children:n,depth:e,shadow:r?o:null,elId:d}),h+='<div class="tc-tree-children" data-lazy-id="'+t+'"></div>'}h+='<span class="tc-tree-label tc-json-boolean tc-tree-close-tag">&lt;/'+s+"&gt;</span>"}else h+='<span class="tc-tree-label tc-json-boolean tc-tree-close-tag">&lt;/'+s+"&gt;</span>";return h+="</div>",h}startElementPicker(){this.elementPickBtn&&this.elementPickBtn.classList.add("tc-active"),this.triggerGlobalHook("beforeClose"),this.overlay.classList.remove("tc-active"),this.triggerGlobalHook("afterClose");let t=document.createElement("div");t.className="tc-element-picker-overlay",t.style.pointerEvents="none";let e=!1,s=n=>{if(e)return;e=!0,n.preventDefault(),n.stopPropagation();let o=n.target;t.remove(),document.removeEventListener("click",s,!0),document.removeEventListener("keydown",i,!0),this.pendingHighlight=o,this.switchTab("elements"),this.triggerGlobalHook("beforeOpen"),this.overlay.classList.add("tc-active","tc-theme-"+this.currentTheme),this.triggerGlobalHook("afterOpen"),this.elementPickBtn&&this.elementPickBtn.classList.remove("tc-active")},i=n=>{"Escape"!==n.key||e||(e=!0,t.remove(),document.removeEventListener("click",s,!0),document.removeEventListener("keydown",i,!0),this.triggerGlobalHook("beforeOpen"),this.overlay.classList.add("tc-active","tc-theme-"+this.currentTheme),this.triggerGlobalHook("afterOpen"),this.elementPickBtn&&this.elementPickBtn.classList.remove("tc-active"))};document.body.appendChild(t),setTimeout(()=>{document.addEventListener("click",s,!0),document.addEventListener("keydown",i,!0)},200)}expandToElement(t){if(!t||!this.elementsTree)return;this.pendingHighlight=null,this.selectedElement=t;let e=null;for(let[s,i]of this.elRefMap)if(i===t){e=s;break}if(null===e)return;let s=this.elementsTree.querySelector('.tc-tree-node[data-el-id="'+e+'"]');if(!s)return;let i=s;for(;i&&i!==this.elementsTree;){if(i.classList.contains("tc-tree-node")){i.classList.remove("tc-collapsed"),i.classList.add("tc-expanded");let t=i.querySelector(":scope > .tc-tree-toggle > i");if(t&&(t.classList.remove("fa-angle-right"),t.classList.add("fa-angle-down")),i.dataset.elId&&this.elRefMap){let t=this.elRefMap.get(parseInt(i.dataset.elId));t&&this.expandedElements.add(t)}let e=i.querySelector(":scope > .tc-tree-children[data-lazy-id]");if(e){let t=parseInt(e.dataset.lazyId),s=this.treeNodeRegistry.get(t);if(s){let i="";"element"===s.type?(i=this.renderDomChildrenLazy(s.children,(t,e,s)=>this.renderElementTree(t,s),s.depth||0,"element",{}),s.shadow&&(i+=this.buildShadowLazy(s.shadow,"element",null,s.depth||0,s.elId))):"element-shadow"===s.type&&(i=this.renderDomChildrenLazy(s.children,(t,e,s)=>this.renderElementTree(t,s),s.depth||0,"element-shadow",{})),e.innerHTML=i,delete e.dataset.lazyId,this.treeNodeRegistry.delete(t)}}}i=i.parentElement}this.elementsTree.querySelectorAll(".tc-el-selected").forEach(t=>t.classList.remove("tc-el-selected")),s.classList.add("tc-el-selected"),s.classList.add("tc-el-highlight"),requestAnimationFrame(()=>{s.scrollIntoView({behavior:"smooth",block:"center"}),setTimeout(()=>s.classList.remove("tc-el-highlight"),3e3)})}copyElementHTML(t){let e=t.outerHTML;navigator.clipboard?navigator.clipboard.writeText(e).then(()=>this.showNotification("已复制元素")).catch(()=>this.fallbackCopy(e)):this.fallbackCopy(e)}fallbackCopy(t){let e=document.createElement("textarea");e.value=t,e.style.position="fixed",e.style.opacity="0",document.body.appendChild(e),e.select();try{document.execCommand("copy"),this.showNotification("已复制元素")}catch(e){this.showNotification("复制失败","warning")}e.remove()}deleteElement(t){if(t)if(null!==this.selectedShadowHostId){let t=this.elRefMap.get(this.selectedShadowHostId);if(t){let e=this.getShadowRoot(t);if(e){if("closed"===e.mode)return void this.showNotification("无法删除closed模式的ShadowDOM","warning");try{for(t.shadowRoot&&(t.shadowRoot.innerHTML="");e.root.firstChild;)e.root.removeChild(e.root.lastChild)}catch{}this.selectedElement=null,this.selectedShadowHostId=null,this.showNotification("ShadowDOM已删除"),this.renderElementsView()}else this.showNotification("ShadowDOM已不存在","warning")}else this.showNotification("无法删除此元素","warning")}else t.parentNode?(t.parentNode.removeChild(t),this.showNotification("元素已删除"),this.selectedElement===t&&(this.selectedElement=null),this.renderElementsView()):t.parentElement?(t.parentElement.removeChild(t),this.showNotification("元素已删除"),this.selectedElement===t&&(this.selectedElement=null),this.renderElementsView()):this.showNotification("无法删除此元素","warning")}renderTableHTML(t,e){if(!t||"object"!=typeof t)return`<div class="tc-console-table-wrap"><span class="tc-json-cmt">非表格数据: ${this.escapeHtml(String(t))}</span></div>`;let s,i;s=Array.isArray(t)?t.map((t,e)=>{let s={"(idx)":e};return t&&"object"==typeof t?Object.assign(s,t):s.value=t,s}):Object.entries(t).map(([t,e])=>{let s={"(idx)":t};return e&&"object"==typeof e?Object.assign(s,e):s.value=e,s});let n=new Set;s.forEach(t=>Object.keys(t).forEach(t=>n.add(t))),i=["(idx)",...Array.from(n).filter(t=>"(idx)"!==t)],e&&Array.isArray(e)&&e.length&&(i=["(idx)",...e.filter(t=>"(idx)"!==t)]);let o=t=>{if(void 0===t)return"";if(null===t)return'<span class="tc-json-null">null</span>';if("string"==typeof t)return`<span class="tc-json-string">"${this.escapeHtml(t.substring(0,100))}"</span>`;if("number"==typeof t)return`<span class="tc-json-number">${t}</span>`;if("boolean"==typeof t)return`<span class="tc-json-boolean">${t}</span>`;if("function"==typeof t)return`<span class="tc-json-boolean">ƒ ${t.name||"anonymous"}</span>`;if("object"==typeof t)try{let e=this.safeStringify(t);return`<span class="tc-json-cmt">${this.escapeHtml(e.length>50?e.substring(0,50)+"…":e)}</span>`}catch{return'<span class="tc-json-cmt">{Object}</span>'}return this.escapeHtml(String(t))},a='<div class="tc-console-table-wrap"><table class="tc-console-table"><thead><tr>';return i.forEach(t=>a+=`<th>${this.escapeHtml(String(t))}</th>`),a+="</tr></thead><tbody>",s.forEach(t=>{a+="<tr>",i.forEach(e=>a+=`<td>${o(t[e])}</td>`),a+="</tr>"}),a+="</tbody></table></div>",a}renderLogItemHTML(t,e){if(t.subType){let e="fa fa-table",s=t.timestamp.toLocaleTimeString(),i=this.renderSubTypeContent(t);return`<div class="tc-log-item tc-${t.type}${this.selectedLogId===t.id?" tc-selected":""}" id="tc-log-item-${t.id}"><div class="tc-log-header">${t.count>1?`<div class="tc-log-count">${t.count}</div>`:""}<div class="tc-log-icon"><i class="${e}"></i></div><div class="tc-timestamp">${s}</div></div><div class="tc-log-content">${i}</div></div>`}let s;switch(t.type){case"info":s="fa fa-info-circle";break;case"warn":s="fa fa-exclamation-triangle";break;case"error":s="fa fa-times-circle";break;default:s="fa fa-info"}let i=t.timestamp.toLocaleTimeString();return`<div class="tc-log-item tc-${t.type}${this.selectedLogId===t.id?" tc-selected":""}" id="tc-log-item-${t.id}"><div class="tc-log-header">${t.count>1?`<div class="tc-log-count">${t.count}</div>`:""}<div class="tc-log-icon"><i class="${s}"></i></div><div class="tc-timestamp">${i}</div></div><div class="tc-log-content">${this.formatArgs(t.args,t.id)}</div></div>`}renderLSItemHTML(t,e){let s=this.escapeHtml(t),{displayValue:i,valueType:n,isJSON:o}=this.parseAndTypeCheck(e),a=o?this.highlightJson(i):this.escapeHtml(i),r="";if(o){let t=JSON.parse(e);r=`<div class="tc-ls-value tc-json-tree-container">${this.renderJSONValue(t,"")}</div>`}else r=`<div class="tc-ls-value" title="${this.escapeHtml(i)}"><span class="tc-json-${n}">${"string"===n?'"':""}${a}${"string"===n?'"':""}</span></div>`;return`<div class="tc-ls-item" data-key="${s}"><div class="tc-ls-key-row"><div class="tc-ls-key" title="${this.escapeHtml(s)}">${this.escapeHtml(s)}</div><div class="tc-ls-actions"><button class="tc-ls-action-btn" data-action="edit" data-key="${s}" title="编辑"><i class="fa fa-edit"></i></button><button class="tc-ls-action-btn" data-action="copy" data-key="${s}" title="复制"><i class="fa fa-copy"></i></button><button class="tc-ls-action-btn" data-action="remove" data-key="${s}" title="删除"><i class="fa fa-trash"></i></button></div></div>${r}<div class="tc-ls-value-type" title="${n}">类型:${n}</div></div>`}toggleSearch(t){let e=void 0!==t?t:!this.searchExpanded;this.searchExpanded=e,this.searchBar&&(this.searchBar.style.display=e?"flex":"none"),e&&this.searchInput?this.searchInput.focus():e||(this.searchQuery="",this.searchInput&&(this.searchInput.value=""),this.renderContent())}onAddLSClick(){this.netSending=!1,this.netNewVisible=!1,this.editorState={visible:!0,mode:"ls",key:"",oldKey:"",value:""},this.updateEditorVisibility(),this.lsEditorKeyInput&&(this.lsEditorKeyInput.value="",this.lsEditorKeyInput.focus())}openLSEditor(t){if(this.netSending||this.netNewVisible)return void this.showNotification("正在发送请求,无法保存键值","warning");let e=this.activeLSFilter||"local",s="";if("session"===e)s=sessionStorage.getItem(t)||"";else if("cookie"===e){let e=encodeURIComponent(t),i=document.cookie.match(new RegExp("(?:^|;\\s)"+e.replace(/([.*+?^${}()|[\]\\])/g,"\\$1")+"=([^;]*)"));s=i?decodeURIComponent(i[1]):""}else s=localStorage.getItem(t)||"";this.netSending=!1,this.netNewVisible=!1,this.editorState={visible:!0,mode:"ls",key:t,oldKey:t,value:s},this.updateEditorVisibility(),this.lsEditorInput&&this.lsEditorInput.focus()}closeLSEditor(){this.editorState.visible=!1,this.editorState.value="",this.updateEditorVisibility()}onEditorSave(){"code"===this.editorState.mode?this.runCode():this.saveLSFromEditor()}saveLSFromEditor(){if(this.netSending||this.netNewVisible)return void this.showNotification("正在发送请求,无法保存键值","warning");let t,e=this.lsEditorKeyInput?this.lsEditorKeyInput.value.trim():this.editorState.key,s=this.editorState.oldKey,i=this.lsEditorInput?this.lsEditorInput.value:this.editorState.value;if(!e)return void this.showNotification("键名不能为空","warning");try{t=JSON.stringify(JSON.parse(this.fixKeysOnly(i)))}catch{t=i}let n=this.activeLSFilter||"local",o="session"===n?sessionStorage:null;if("cookie"===n)return document.cookie=encodeURIComponent(e)+"="+encodeURIComponent(t)+";path=/",-1===document.cookie.indexOf(encodeURIComponent(e)+"=")&&(document.cookie=encodeURIComponent(e)+"="+encodeURIComponent(t)),this.closeLSEditor(),this.renderLocalStorage(),void this.showNotification('已保存Cookie"'+e+'"');let a=o?o.getItem.bind(o):localStorage.getItem.bind(localStorage),r=o?o.setItem.bind(o):localStorage.setItem.bind(localStorage),l=o?o.removeItem.bind(o):localStorage.removeItem.bind(localStorage);if(s&&s!==e){if(null!==a(e))return void this.showNotification('键名"'+e+'"已存在!',"warning");l(s)}else if(!s&&null!==a(e))return void this.showNotification('键名"'+e+'"已存在!',"warning");r(e,t),this.closeLSEditor(),this.renderLocalStorage(),this.showNotification('已保存键"'+e+'"')}onTitleClick(){this.netSending||this.netNewVisible?this.showNotification("正在发送请求,无法运行代码","warning"):this.editorState.visible&&"ls"===this.editorState.mode?this.showNotification("正在保存键值,无法运行代码","warning"):(this.editorState.visible=!0,this.editorState.mode="code",this.updateEditorVisibility(),this.lsEditorInput&&this.lsEditorInput.focus())}toggleMute(){let t="console",e=this.activeFilter||"all";this.mutedFilters[t]||(this.mutedFilters[t]={}),this.mutedFilters[t][e]=!this.mutedFilters[t][e];let s=this.mutedFilters[t][e],i="all"===e?"所有日志":e+"类型日志";this.showNotification(s?i+"已屏蔽":i+"已恢复",s?"warning":""),this.updateMuteBtnState()}updateMuteBtnState(){if(!this.muteBtn)return;let t="console",e=this.activeFilter||"all";this.mutedFilters[t]&&this.mutedFilters[t][e]?(this.muteBtn.classList.add("tc-muted"),this.muteBtn.title="恢复日志"):(this.muteBtn.classList.remove("tc-muted"),this.muteBtn.title="屏蔽"+("all"===e?"后续日志":e+"类型日志"))}runCode(){let t=this.lsEditorInput?this.lsEditorInput.value:"";if(t.trim())try{let e=window.eval(t);console.log(`${t}\n> `,e),this.showNotification("代码已执行"),this.closeLSEditor()}catch(e){console.error(`${t}\n> 执行失败:${e}`),this.showNotification("代码执行失败","warning"),this.closeLSEditor()}}setupGestures(){if(!this.contentArea||!this.consoleHeader)return;let t=this.contentArea,e=this.consoleHeader,s=null,i=0,n=0,o=0,a=0,r=!1,l=null,c=0,d=0,h=0,p=!1,u=()=>{let t=this.overlay.querySelectorAll(".tc-tab-btn");return Array.from(t).map(t=>t.dataset.tab)},f=()=>{if("console"===this.currentTab)return["all","log","info","warn","error"];if("network"===this.currentTab)return["all","get","post","put","success","failed"];if("localstorage"===this.currentTab)return["local","session","cookie"];let t=this.pluginViewContainers[this.currentTab];return t&&t.querySelectorAll(".tc-filter-btn").length>1?Array.from(t.querySelectorAll(".tc-filter-btn")).map(t=>t.dataset.type||t.dataset.filter||t.textContent.trim()):null},g=t=>{let e=u(),s=e.indexOf(this.currentTab),i=f();if(i)if("localstorage"===this.currentTab){let e=i.indexOf(this.activeLSFilter||"local")+t;if(e>=0&&e<i.length){this.activeLSFilter=i[e],this.lsFiltersContainer&&this.lsFiltersContainer.querySelectorAll(".tc-filter-btn").forEach(t=>t.classList.toggle("tc-active",t.dataset.lsType===this.activeLSFilter)),this.renderContent();let t=this.lsFiltersContainer&&this.lsFiltersContainer.querySelector('.tc-filter-btn[data-ls-type="'+this.activeLSFilter+'"]');return void this.scrollFilterIntoView(this.lsFiltersContainer,t)}}else if("console"===this.currentTab){let e=i.indexOf(this.activeFilter||"all")+t;if(e>=0&&e<i.length)return this.activeFilter=i[e],this.filterButtons.forEach(t=>t.classList.toggle("tc-active",t.dataset.type===this.activeFilter)),this.updateFilterCounts(),this.renderContent(),void this.scrollFilterIntoView(this.overlay.querySelector("#tc-filtersContainer"),this.filterButtons[e])}else{if("network"!==this.currentTab){let e=this.pluginViewContainers[this.currentTab];if(e){this.enhanceFilterContainers(e);let s=e.querySelectorAll(".tc-filter-btn");if(s.length>1){let e=-1;s.forEach((t,s)=>{t.classList.contains("tc-active")&&(e=s)});let i=e+t;i>=0&&i<s.length&&(s.forEach(t=>t.classList.remove("tc-active")),s[i].classList.add("tc-active"),s[i].click(),this.scrollFilterIntoView(s[i].parentElement,s[i]))}}return}{let e=i.indexOf(this.activeNetFilter||"all")+t;if(e>=0&&e<i.length){this.activeNetFilter=i[e],this.netFiltersEl&&this.netFiltersEl.querySelectorAll(".tc-net-filter-btn").forEach(t=>t.classList.toggle("tc-active",t.dataset.netFilter===this.activeNetFilter)),this.renderNetworkList(),this.updateNetDisableBtn(),this.updateNetFilterCounts();let t=this.netFiltersEl&&this.netFiltersEl.querySelector('.tc-net-filter-btn[data-net-filter="'+this.activeNetFilter+'"]');return void this.scrollFilterIntoView(this.netFiltersEl,t)}}}let n=s+t;if(n>=0&&n<e.length){let t=e[n];"console"===t?(this.activeFilter="all",this.filterButtons&&this.filterButtons.forEach(t=>t.classList.toggle("tc-active","all"===t.dataset.type))):"localstorage"===t&&(this.activeLSFilter="local",this.lsFiltersContainer&&this.lsFiltersContainer.querySelectorAll(".tc-filter-btn").forEach(t=>t.classList.toggle("tc-active","local"===t.dataset.lsType)));let s=this.overlay.querySelector(`.tc-tab-btn[data-tab="${t}"]`);s&&s.click()}};t.addEventListener("touchstart",t=>{if(1!==t.touches.length)return;if(this.editorState.visible)return;let e=t.target.closest(".tc-json-tree-container,.tc-json-preview,.tc-log-content,.tc-console-table-wrap,.tc-system-log-content,.tc-ls-value,.tc-object-preview,.tc-error-stack,.tc-function-preview,.tc-elements-tree");e&&e.scrollWidth>e.clientWidth?s=null:(s=t.touches[0],i=s.clientX,n=s.clientY,o=0,a=0,r=!1)},{passive:!0}),t.addEventListener("touchmove",t=>{if(!s||1!==t.touches.length)return;let e=t.touches[0];o=e.clientX-i,a=e.clientY-n,!r&&Math.abs(o)>15&&Math.abs(o)>1.5*Math.abs(a)&&(r=!0),r&&t.preventDefault()},{passive:!1}),t.addEventListener("touchend",()=>{if(s){if(r){let t=60;o<-t?g(1):o>t&&g(-1)}s=null,r=!1}}),e.addEventListener("touchstart",t=>{1===t.touches.length&&(l=t.touches[0],c=l.clientX,d=l.clientY,h=0,p=!1)},{passive:!0}),e.addEventListener("touchmove",t=>{if(!l||1!==t.touches.length)return;let e=t.touches[0];if(h=e.clientY-d,!p&&h>15&&h>1.5*Math.abs(e.clientX-c)&&(p=!0),p){t.preventDefault();let e=this.overlay.querySelector(".tc-console-container");e&&(e.style.transition="none",e.style.transform=`translateY(${h}px)`)}},{passive:!1}),e.addEventListener("touchend",()=>{if(l){if(p){let t=this.overlay.querySelector(".tc-console-container");h>80?(t&&(t.style.transition="transform .3s ease",t.style.transform="translateY(100%)"),setTimeout(()=>{this.triggerGlobalHook("beforeClose"),this.overlay.classList.remove("tc-active"),t&&(t.style.transition="",t.style.transform=""),this.triggerGlobalHook("afterClose")},300)):t&&(t.style.transition="transform .25s ease",t.style.transform="")}l=null,p=!1}})}updateFilterShadow(t){if(!t)return;let e=t.scrollWidth-t.clientWidth>1;t.classList.toggle("tc-overflow-start",e&&t.scrollLeft>1),t.classList.toggle("tc-overflow-end",e&&t.scrollLeft+t.clientWidth<t.scrollWidth-1)}setupFilterShadow(t){if(!t||t._tcFilterShadow)return;t._tcFilterShadow=!0;let e=()=>this.updateFilterShadow(t);if(t.addEventListener("scroll",e,{passive:!0}),window.ResizeObserver){let s=new ResizeObserver(e);s.observe(t),t._tcFilterRO=s}if(window.MutationObserver){let s=new MutationObserver(e);s.observe(t,{childList:!0,subtree:!0}),t._tcFilterMO=s}e()}scrollFilterIntoView(t,e){if(!t||!e)return;if(t.scrollWidth<=t.clientWidth)return void this.updateFilterShadow(t);let s=e.offsetLeft-(t.clientWidth-e.offsetWidth)/2;s=Math.max(0,Math.min(s,t.scrollWidth-t.clientWidth));try{t.scrollTo({left:s,behavior:"smooth"})}catch(t){}t.scrollLeft!==s&&(t.scrollLeft=s),this.updateFilterShadow(t),setTimeout(()=>this.updateFilterShadow(t),300)}enhanceFilterContainers(t){if(!t)return;let e=new Map;t.querySelectorAll(".tc-filter-btn").forEach(t=>{let s=t.parentElement;s&&!s.dataset.tcFilterEnhanced&&(e.has(s)||e.set(s,[]),e.get(s).push(t))}),e.forEach((t,e)=>{if(t.length>1){e.classList.contains("tc-filters")||e.classList.contains("tc-network-filters")||e.classList.add("tc-filters"),e.dataset.tcFilterEnhanced="1",this.setupFilterShadow(e);let s=e;t.forEach(t=>{t.dataset.orig||(t.dataset.orig=t.textContent.trim()),t.addEventListener("click",()=>this.scrollFilterIntoView(s,t))})}})}updatePluginFilterCounts(t){let e=this.pluginViewContainers[this.currentTab];if(!e)return;let s="object"==typeof t?t:null;e.querySelectorAll(".tc-filter-btn[data-orig]").forEach(t=>{let e=t.dataset.orig,i=t.querySelector("i")?t.querySelector("i").className:"",n=s&&s[t.dataset.type||t.dataset.filter||e]||0;if(t.classList.contains("tc-active")){let s=n>99?"99+":n;t.innerHTML=i?`<i class="${i}"></i> ${e} (${s})`:`${e} (${s})`}else t.innerHTML=i?`<i class="${i}"></i> ${e}`:e})}updateFilterCounts(){if(!this.filterButtons)return;let t=[];"console"===this.currentTab&&(t=this.logs);let e=(t,e)=>t.reduce((t,s)=>s.type===e?t+(s.count||1):t,0),s={all:t.reduce((t,e)=>t+(e.count||1),0),log:e(t,"log"),info:e(t,"info"),warn:e(t,"warn"),error:e(t,"error")};this.filterButtons.forEach(t=>{let e=t.dataset.type,i=s[e]||0;if(t.dataset.originalHtml||(t.dataset.originalHtml=t.innerHTML),t.classList.contains("tc-active")){let e=i>99?"99+":i;t.innerHTML=`${t.dataset.originalHtml} (${e})`}else t.innerHTML=t.dataset.originalHtml})}renderContent(){if(this.triggerGlobalHook("beforeRender",this.currentTab),this.updateControlsVisibility(),this.updateMuteBtnState(),this.consoleOutput.style.display="none",this.localstorageView.style.display="none",this.elementsView.style.display="none",this.networkView&&(this.networkView.style.display="none"),this.netDetailOverlay&&(this.netDetailOverlay.style.display="none"),this.netNewOverlay&&(this.netNewOverlay.style.display=this.netNewVisible?"flex":"none"),this.clearLogsBtn.style.display="none",Object.values(this.pluginViewContainers).forEach(t=>{t.style.display="none"}),["console","network","localstorage","elements"].includes(this.currentTab))switch(this.clearLogsBtn.style.display="block",this.currentTab){case"console":this.consoleOutput.style.display="block",this.renderLogList(this.logs,!1),this.updateFilterCounts();break;case"network":this.clearLogsBtn.style.display="block",this.networkView&&(this.networkView.style.display="flex"),this.renderNetworkPanel();break;case"localstorage":this.localstorageView.style.display="block",this.renderLocalStorage();break;case"elements":this.clearLogsBtn.style.display="none",this.elementsView.style.display="block",this.renderElementsView()}else if(this.pluginViewContainers[this.currentTab]){this.consoleControls.style.display="none";let t=this.pluginViewContainers[this.currentTab];t.style.display="block";let e=Object.keys(this.pluginTabs).find(t=>this.pluginTabs[t].id===this.currentTab);if(e){let s=this.plugins[e];s&&"function"==typeof s.onShow&&s.onShow(),s&&"function"==typeof s.render&&s.render(t),this.enhanceFilterContainers(t)}else{let t=this.pluginTabs[this.currentTab];t&&"function"==typeof t.onShow&&t.onShow()}}this.triggerGlobalHook("afterRender",this.currentTab)}renderLogList(t,e){let s=this.consoleOutput,i="日志记录";if(!s)return;if(0===t.length)return void this.vsShowMessage(s,`<div class="tc-nolog"><i class="fa fa-info-circle"></i>无${i}</div>`);let n=[...t];if(this.activeFilter&&"all"!==this.activeFilter&&(n=n.filter(t=>t.type===this.activeFilter)),this.searchQuery){let t,e=this.searchQuery.trim(),s=!1;if(e.startsWith("/")&&e.endsWith("/"))try{let i=e.slice(1,-1),n=i.lastIndexOf("/"),o="";n>0?(o=i.slice(n+1),t=new RegExp(i.slice(0,n),o)):t=new RegExp(i),s=!0}catch{this.showNotification("无效的正则表达式:"+e),s=!1}let i=s?e:e.toLowerCase();n=n.filter(e=>e.args.some(e=>{let n;return n=e instanceof Error?"[error]":null==e?"null":void 0===e?"undefined":"object"==typeof e?'<span class="tc-json-cmt">{Object}</span>':String(e),s&&t?t.test(n):n.toLowerCase().includes(i.toLowerCase())}))}if(0===n.length)return void this.vsShowMessage(s,`<div class="tc-nolog"><i class="fa fa-search"></i>无匹配的${i}</div>`);let o=this.isNearBottom(s),a=s._vs;if(!a)return;a.rafId&&(cancelAnimationFrame(a.rafId),a.rafId=null);let r=a.items&&a.items.length||0,l=r>0&&a.items[0]&&n[0]&&a.items[0].id!==n[0].id;if(a.items=n,a.renderItem=t=>this.renderLogItemHTML(t,e),a.avgHeight<10&&(a.avgHeight=80),a.afterRender=null,o)a.lastStart=-1,a.lastEnd=-1,this.renderViewport(s);else if(r>0&&n.length>=r&&!l&&a.lastEnd>=0){let t=0;for(let e=a.lastEnd;e<n.length;e++)t+=a.heights&&a.heights.get(e)||a.avgHeight;a.bottomSpacer.style.height=t+"px"}else if(l&&r>0){let t=0;for(let e=0;e<r&&e<n.length&&(!a.items[t]||!n[t]||a.items[t].id!==n[t].id);e++)t++;if(t>0&&t<r){let e=new Map;for(let[s,i]of a.heights){let o=s-t;o>=0&&o<n.length&&e.set(o,i)}a.heights=e,a.lastStart=Math.max(-1,a.lastStart-t),a.lastEnd=Math.max(-1,a.lastEnd-t);let i=s.scrollTop;return this.renderViewport(s),void(!a.isAtBottom&&i>0&&(s.scrollTop=i))}let e=s.scrollTop;a.lastStart=-1,a.lastEnd=-1,this.renderViewport(s),e>0&&!a.isAtBottom&&(s.scrollTop=e)}}getParams(t){let e=t.toString();if(/^\s*(?:class|function|async\s+function)/.test(e)){let t=e.indexOf("(");if(-1===t)return"";let s=1,i=t+1;for(;i<e.length;i++){const t=e[i];if("("===t)s++;else if(")"===t&&0===--s)break}return e.slice(t+1,i).replace(/\s+/g,"")}let s=e.indexOf("=>");if(s>0){let t=e.slice(0,s).trim().replace(/^async\s+/,"");if(t.startsWith("(")){let e=1,s=1;for(;s<t.length&&e>0;s++)"("===t[s]?e++:")"===t[s]&&e--;return t.slice(1,s-1).replace(/\s+/g,"")}return t.replace(/\s+/g,"")}return""}renderLogContent(t){let e=[...t.args];if(!e.length)return"";let s=[],i=[],n=0,o=(t=>null===t?'<span class="tc-json-null">null</span>':void 0===t?'<span class="tc-json-null">undefined</span>':t instanceof HTMLElement?`<span class="tc-json-number">${t.constructor.name} &lt;${t.tagName.toLowerCase()}&gt;</span>`:t instanceof Date?t.toISOString():t instanceof Error?`<strong>${t.name}:</strong>${t.message}`:"function"==typeof t?this.isClass(t)?`<span class='tc-json-boolean'>[Class ${t.name||"anonymous"}]</span>`:`<span class='tc-json-boolean'>ƒ ${t.name||"anonymous"}</span><span class='tc-json-cmt'>(${this.getParams(t)})</span>`:"object"==typeof t&&null!==t?`<span class="tc-json-cmt">${t.constructor.name||"Object"} {Object}</span>`:"number"==typeof t?Number.isNaN(t)?'<span class="tc-json-cmt">NaN</span>':isFinite(t)?`<span class="tc-json-number">${t}</span>`:`<span class="tc-json-cmt">${t>0?"Infinity":"-Infinity"}</span>`:"boolean"==typeof t?`<span class="tc-json-boolean">${t}</span>`:String(t).replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\n/g,"<br>"))(e.length>0?e[0]:"").replace(/%%/g,"").replace(/%([dfsioO%])/g,(t,i)=>{if("%"===i)return"%";if("o"===i||"O"===i)return"";let o=e[++n];if(null==o)return t;let a="d"===i||"i"===i?parseInt(o,10)||0:"f"===i?parseFloat(o)||0:String(o);return s.push(a),`{{v${s.length-1}}}`}).replace(/%c/g,()=>(i.push(String(e[++n]||"")),`{{c${i.length-1}}}`)).replace(/\x01/g,"%");s.forEach((t,e)=>o=o.replace(`{{v${e}}}`,t));let a=o.split(/{{c\d+}}/);o=a.map((t,e)=>{if(!e)return t;let s=i[e-1].replace(/"/g,"").split(/\s*;\s*/).filter(t=>t.trim()&&!/\b(position|fixed|absolute|sticky|relative|static|z-index|transform|top|left|right|bottom)\s*:/i.test(t)).join("; ");return s?`<span style="${s}">${t}</span>`:t}).join("");let r=e.slice(n+1);return o+=(o?" ":"")+r.map(t=>null===t?'<span class="tc-json-null">null</span>':void 0===t?'<span class="tc-json-null">undefined</span>':"function"==typeof t?this.isClass(t)?`<span class='tc-json-boolean'>[Class ${t.name||"anonymous"}]</span>`:`<span class='tc-json-boolean'>ƒ ${t.name||"anonymous"}</span><span class='tc-json-cmt'>(${this.getParams(t)})</span>`:t instanceof Error?`<strong>${t.name}:</strong>${t.message}`:t instanceof HTMLElement?`<span class="tc-json-number">${t.constructor.name} &lt;${t.tagName.toLowerCase()}&gt;</span>`:t instanceof Date?`<span class="tc-json-string">${t.toISOString()}</span>`:t instanceof RegExp?`<span class="tc-json-number">${t.toString()}</span>`:t instanceof Map?`<span class="tc-json-boolean">[Map ${t.size}]</span>`:t instanceof Set?`<span class="tc-json-boolean">[Set ${t.size}]</span>`:t instanceof WeakMap?'<span class="tc-json-boolean">[WeakMap]</span>':t instanceof WeakSet?'<span class="tc-json-boolean">[WeakSet]</span>':t instanceof ArrayBuffer?`<span class="tc-json-boolean">[ArrayBuffer ${t.byteLength} bytes]</span>`:t&&"object"==typeof t?`<span class="tc-json-cmt">${t.constructor.name||"Object"} {Object}</span>`:"number"==typeof t?Number.isNaN(t)?'<span class="tc-json-cmt">NaN</span>':isFinite(t)?`<span class="tc-json-number">${t}</span>`:`<span class="tc-json-cmt">${t>0?"Infinity":"-Infinity"}</span>`:"boolean"==typeof t?`<span class="tc-json-boolean">${t}</span>`:String(t).replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\n/g,"<br>")).join("")}copyLog(t,e=!1,s=!1){if(s){let e=this.activeLSFilter||"local",s="session"===e?sessionStorage.getItem(t):"cookie"===e?function(){let e=encodeURIComponent(t),s=document.cookie.match(new RegExp("(?:^|;\\s)"+e.replace(/([.*+?^${}()|[\]\\])/g,"\\$1")+"=([^;]*)"));return s?decodeURIComponent(s[1]):null}():localStorage.getItem(t);if(s)return navigator.clipboard.writeText(s).then(()=>this.showNotification(`已复制"${t}"的值`)).catch(t=>console.error("复制失败:",t))}let i=this.logs.find(e=>e.id===t);if(!i)return;let n="";i.count>1&&(n+=`[重复${i.count}次] `),i.args.forEach((t,e)=>{e>0&&(n+=" ");try{t instanceof HTMLElement?n+=t.outerHTML.replace(/>/g,">\n"):n+=null!==t&&"object"==typeof t?this.safeStringify(t).replace(/\\u000[23]/g,""):"function"==typeof t?`ƒ ${t.name||"anonymous"}(${this.getParams(t)})`:null===t?"null":void 0===t?"undefined":String(t)}catch{n+="{object}"}}),navigator.clipboard.writeText(n).then(()=>this.showNotification("已复制到剪贴板")).catch(t=>console.error("复制失败:",t))}clearAllLogs(t=!1){if(this.triggerGlobalHook("beforeClear"),"network"!==this.currentTab){if(t)return this.logs=[],this.lastLog=null,this.renderContent(),void this.updateFilterCounts();if("localstorage"==this.currentTab){let t=this.activeLSFilter||"local";return void(confirm("确定要清除所有"+("local"===t?"本地存储":"session"===t?"会话存储":"Cookie")+"吗?此操作不可撤销。")&&("local"===t?localStorage.clear():"session"===t?sessionStorage.clear():document.cookie.split(";").forEach(t=>{let e=t.split("=")[0].trim();e&&(document.cookie=e+"=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/",document.cookie=e+"=;expires=Thu, 01 Jan 1970 00:00:00 GMT")}),this.renderLocalStorage()))}confirm("确定要清除所有日志吗?此操作不可撤销。")&&(this.logs=[],this.lastLog=null,this.renderContent(),this.updateFilterCounts(),this.showNotification("所有日志已清除","warning"),this.triggerGlobalHook("afterClear"))}else this.clearNetworkRequests()}updateLSFilterCounts(){if(!this.lsFiltersContainer)return;let t={local:localStorage.length,session:sessionStorage.length,cookie:document.cookie?document.cookie.split(";").filter(t=>t.trim()).length:0};this.lsFiltersContainer.querySelectorAll(".tc-filter-btn").forEach(e=>{let s=e.dataset.orig,i=t[e.dataset.lsType]||0,n=e.querySelector("i")?e.querySelector("i").className:"";if(e.classList.contains("tc-active")){let t=i>99?"99+":i;e.innerHTML=`<i class="${n}"></i>${s} (${t})`}else e.innerHTML=`<i class="${n}"></i>${s}`})}renderLocalStorage(){this.updateLSFilterCounts();let t=this.activeLSFilter||"local",e=[],s="无本地存储";if("local"===t){if(!localStorage.length)return void this.vsShowMessage(this.lsItems,'<div class="tc-nolog"><i class="fa fa-database"></i>'+s+"</div>");for(let t=0;t<localStorage.length;t++){let s=localStorage.key(t);e.push({key:s,value:localStorage.getItem(s)})}}else if("session"===t){if(s="无会话存储",!sessionStorage.length)return void this.vsShowMessage(this.lsItems,'<div class="tc-nolog"><i class="fa fa-window-restore"></i>'+s+"</div>");for(let t=0;t<sessionStorage.length;t++){let s=sessionStorage.key(t);e.push({key:s,value:sessionStorage.getItem(s)})}}else if("cookie"===t){s="无Cookies";let t=document.cookie;if(!t)return void this.vsShowMessage(this.lsItems,'<div class="tc-nolog"><i class="fa fa-cookie-bite"></i>'+s+"</div>");t.split(";").forEach(t=>{let s=t.indexOf("=");if(s>0)try{e.push({key:decodeURIComponent(t.slice(0,s).trim()),value:decodeURIComponent(t.slice(s+1).trim())})}catch{e.push({key:t.slice(0,s).trim(),value:t.slice(s+1).trim()})}else t.trim()&&e.push({key:t.trim(),value:""})})}if(e.sort((t,e)=>t.key.localeCompare(e.key,void 0,{numeric:!0,sensitivity:"base"})),this.searchQuery){let t=this.searchQuery.toLowerCase();e=e.filter(e=>e.key.toLowerCase().includes(t)||(e.value||"").toLowerCase().includes(t))}0!==e.length?this.vsSetItems(this.lsItems,e,t=>this.renderLSItemHTML(t.key,t.value),130):this.vsShowMessage(this.lsItems,'<div class="tc-nolog"><i class="fa fa-search"></i>无匹配的本地存储数据</div>')}addLSItemToDOM(t,e){this.renderLocalStorage()}parseAndTypeCheck(t){try{let e=JSON.parse(t);return"object"==typeof e&&null!==e?{displayValue:this.safeStringify(e,2).replace(/</g,"&lt;").replace(/>/g,"&gt;"),valueType:Array.isArray(e)?"array":"object",isJSON:!0}:null==e?{displayValue:null,valueType:null,isJSON:!1}:{displayValue:t,valueType:typeof e,isJSON:!1}}catch{return{displayValue:t,valueType:"string",isJSON:!1}}}isLSEmpty(){let t=this.activeLSFilter||"local";return"local"===t?0===localStorage.length:"session"===t?0===sessionStorage.length:"cookie"===t?!document.cookie:!Array.from({length:localStorage.length},(t,e)=>localStorage.key(e)).some(t=>(t||"").trim())}escapeHtml(t){return String(t).replace(/</g,"&lt;").replace(/>/g,"&gt;")}addLSItem(){this.onAddLSClick()}editLSItem(t){this.openLSEditor(t)}saveLSItem(){this.onEditorSave()}fixKeysOnly(t){try{return JSON.parse(t),t}catch{return t.replace(/([{,])\s*([a-zA-Z_]\w*)\s*:/g,'$1"$2":').replace(/(":)\s*(?!true|false|null|\d+(\.\d+)?)([^\s,"{[}\]]+?)\s*(?=,|})/gs,'$1"$3"')}}cancelEditLSItem(){this.closeLSEditor()}removeLSItem(t){let e=this.activeLSFilter||"local",s="local"===e?"本地存储":"session"===e?"会话存储":"Cookie";if(confirm("是否删除全部"+s+"?\n确定=删除全部"+s+',取消=仅删除"'+t+'"'))"session"===e?sessionStorage.clear():"cookie"===e?document.cookie.split(";").forEach(t=>{let e=t.split("=")[0].trim();e&&(document.cookie=e+"=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/",document.cookie=e+"=;expires=Thu, 01 Jan 1970 00:00:00 GMT")}):localStorage.clear(),this.renderLocalStorage(),this.showNotification("已清空"+s);else{if("session"===e)sessionStorage.removeItem(t);else if("cookie"===e){let e=encodeURIComponent(t);document.cookie=e+"=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/",document.cookie=e+"=;expires=Thu, 01 Jan 1970 00:00:00 GMT"}else localStorage.removeItem(t);this.renderLocalStorage(),this.showNotification('已删除"'+t+'"')}}findLSItem(t){return this.overlay.querySelector(`.tc-ls-item[data-key="${t}"]`)}updateLSItemView(t){let e=this.findLSItem(t);if(!e)return;let s=localStorage.getItem(t);if(null===s)return void e.remove();let{displayValue:i,valueType:n,isJSON:o}=this.parseAndTypeCheck(s),a=o?this.highlightJson(i):this.escapeHtml(i),r="";if(o){let t=JSON.parse(s);r=`<div class="tc-ls-value tc-json-tree-container">${this.renderJSONValue(t,"")}</div>`}else r=`<div class="tc-ls-value" title="${this.escapeHtml(i)}"><span class="tc-json-${n}">${"string"===n?'"':""}${a}${"string"===n?'"':""}</span></div>`;let l=this.escapeHtml(t);e.innerHTML=`<div class="tc-ls-key-row"><div class="tc-ls-key" title="${l}">${l}</div><div class="tc-ls-actions"><button class="tc-ls-action-btn" data-action="edit" data-key="${l}" title="编辑"><i class="fa fa-edit"></i></button><button class="tc-ls-action-btn" data-action="copy" data-key="${l}" title="复制"><i class="fa fa-copy"></i></button><button class="tc-ls-action-btn" data-action="remove" data-key="${l}" title="删除"><i class="fa fa-trash"></i></button></div></div>${r}<div class="tc-ls-value-type" title="${n}">类型:${n}</div>`}setupGlobalEventHandlers(){this.activeFilter="all",this.searchQuery="",this.tCError=t=>{""!==t.filename||0!==t.lineno||0!==t.colno?(console.error(t.error.toString(),{"错误信息":t.message||"无信息","文件名":t.filename||"未知","位置":`${t.lineno}:${t.colno}`||"0:0","是否可信":t.isTrusted||!0,"类型":t.type||"error"}),t.preventDefault()):console.error("脚本错误")},this.tCUR=t=>{console.error("未处理的Promise异常",t.reason),t.preventDefault()},this.RSError=t=>{let e=new Set(["IMG","SCRIPT","LINK","VIDEO","AUDIO","SOURCE","TRACK"]),s=t.target;if(!e.has(s.tagName))return;let i=s.src||s.href||s.currentSrc||"[未知路径]";console.error(`[资源错误] <${s.tagName.toLowerCase()}>加载失败:${i}`)},document.addEventListener("error",this.RSError,!0),window.addEventListener("error",this.tCError),window.addEventListener("unhandledrejection",this.tCUR)}setupSelfProtection(){if(this.protectInterval)return;let t=this;this.protectInterval=setInterval(()=>{window.thinConsole&&window.thinConsole.tC!==t&&(window.thinConsole.tC=t);let e=document.getElementById("tc-thinConsole-btn");e&&document.documentElement.contains(e)?"flex"!==e.style.display&&(e.style.display="flex"):(t.btn=null,t.createButton());let s=document.getElementById("tc-consoleOverlay");s&&document.documentElement.contains(s)?"flex"!==s.style.display&&(s.style.display="flex"):(t.overlay=null,t.createOverlayElement(),t.createStyles());let i=document.head.querySelector("style[tcstyle]");(!i||!i.innerHTML||i.innerHTML.length<100)&&t.createStyles();let n=document.getElementById("tc-notification");n&&document.documentElement.contains(n)?"block"!==n.style.display&&(n.style.display="block"):(t.notification=null,t.createNotificationElement());let o=t=>{if(!t||1!==t.nodeType)return;let e=t=>{"false"!==t.contentEditable&&(t.contentEditable="false",t.setAttribute("tc-lock",""),a.observe(t,{attributes:!0,attributeFilter:["contenteditable"]}))};e(t),t.querySelectorAll("*").forEach(e)},a=new MutationObserver(t=>{t.forEach(t=>{"attributes"===t.type&&"contentEditable"===t.attributeName&&"true"===t.target.contentEditable&&t.target.hasAttribute("tc-lock")&&(t.target.contentEditable="false")})});setTimeout(()=>{o(t.btn),o(t.overlay),o(t.notification)},0)},5e3)}disablePlugin(t){return this.disabledPlugins.includes(t)||this.disabledPlugins.push(t),this.destroyPlugin(t),this}enablePlugin(t){return this.disabledPlugins=this.disabledPlugins.filter(e=>e!==t),this.loadSinglePlugin(t),this}loadSinglePlugin(e){if(!this.disabledPlugins.includes(e)&&t.plugins[e]&&!this.plugins[e]){try{let s=t.plugins[e],i=new s(this,s.config);if(i.init(),this.plugins[e]=i,i.addTab){let t=i.addTab();this.createPluginTab(t),this.pluginTabs[e]={id:t.id,name:t.name,icon:t.icon||"fa fa-plug",plugin:i}}this.triggerGlobalHook("pluginMount",e,i)}catch(t){console.error(`插件"${e}"加载失败:`,t)}return this}}initPlugins(){return Object.keys(t.plugins).forEach(t=>{this.disabledPlugins.includes(t)||this.loadSinglePlugin(t)}),this}destroyPlugin(t){let e=this.plugins[t];if(!e)return;"function"==typeof e.destroy&&e.destroy();let s=this.pluginTabs[t]?.id;if(s){let t=this.overlay.querySelector(`.tc-tab-btn[data-tab="${s}"]`);t?.remove();let e=this.pluginViewContainers[s];e?.remove(),delete this.pluginViewContainers[s]}return delete this.plugins[t],delete this.pluginTabs[t],this.triggerGlobalHook("pluginUnmount",t),this}triggerGlobalHook(e,...s){return t.hooks[e]&&t.hooks[e].forEach(t=>{try{t.call(this,...s)}catch(t){console.error(`钩子"${e}"执行错误:`,t)}}),this}destroy(){t.tC===this&&(Object.assign(console,this.originalConsole),Object.keys(this.plugins).forEach(t=>this.destroyPlugin(t)),clearInterval(this.protectInterval),clearInterval(this.themeChangeHandler),this.btn?.remove(),document.head.querySelector("style[tcstyle]")?.remove(),this.overlay?.remove(),this.notification?.remove(),document.removeEventListener("error",this.RSError,!0),window.removeEventListener("error",this.tCError),window.removeEventListener("unhandledrejection",this.tCUR),this.originalXHR&&(window.XMLHttpRequest=this.originalXHR),this.originalFetch&&(window.fetch=this.originalFetch),t.tC=null)}captureNetworkRequests(){this.originalXHR=this.originalXHR||window.XMLHttpRequest;let t=this,e=this.originalXHR;window.XMLHttpRequest=function(){let s=new e,i={id:++t._netReqId||1,url:"",method:"GET",status:0,statusText:"",reqHeaders:{},reqBody:null,resHeaders:{},resBody:null,startTime:0,endTime:0,duration:0,error:null};t._netReqId=t._netReqId||1;let n=s.open;s.open=function(t,e){return i.method=t.toUpperCase(),i.url=e,n.apply(s,arguments)};let o=s.send;s.send=function(e){if(t.netDisabledTypes.size>0){let e=i.method.toLowerCase();if(t.netDisabledTypes.has("all")||t.netDisabledTypes.has(e)||t.netDisabledTypes.has("success")||t.netDisabledTypes.has("failed"))return}i.reqBody=e,i.startTime=Date.now();let n={...i};return t.networkRequests.push(n),"network"===t.currentTab&&t.renderNetworkList(),s.addEventListener("loadend",function(){n.status=s.status,n.statusText=s.statusText,n.endTime=Date.now(),n.duration=n.endTime-n.startTime;try{n.resBody=s.responseText}catch(t){}try{let t={};s.getAllResponseHeaders().trim().split("\n").forEach(e=>{let s=e.indexOf(":");s>0&&(t[e.slice(0,s).trim()]=e.slice(s+1).trim())}),n.resHeaders=t}catch(t){}"network"===t.currentTab&&t.renderNetworkList()}),s.addEventListener("error",function(){n.error="Network Error",n.status=0,n.endTime=Date.now(),n.duration=n.endTime-n.startTime,"network"===t.currentTab&&t.renderNetworkList()}),o.apply(s,arguments)};let a=s.setRequestHeader;return s.setRequestHeader=function(t,e){return i.reqHeaders[t]=e,a.apply(s,arguments)},s},this.originalFetch=this.originalFetch||window.fetch;let s=this.originalFetch;window.fetch=function(e,i){let n="string"==typeof e?e:e.url,o=(i&&i.method||"GET").toUpperCase();if(t.netDisabledTypes.size>0){let e=o.toLowerCase();if(t.netDisabledTypes.has("all")||t.netDisabledTypes.has(e)||t.netDisabledTypes.has("success")||t.netDisabledTypes.has("failed"))return Promise.reject(new Error("Request disabled by thinConsole"))}let a={id:++t._netReqId,url:n,method:o,status:0,statusText:"",reqHeaders:{},reqBody:null,resHeaders:{},resBody:null,startTime:Date.now(),endTime:0,duration:0,error:null};return i&&i.headers&&(i.headers instanceof Headers?i.headers.forEach((t,e)=>a.reqHeaders[e]=t):"object"==typeof i.headers&&Object.assign(a.reqHeaders,i.headers)),i&&i.body&&(a.reqBody=i.body),t.networkRequests.push(a),"network"===t.currentTab&&t.renderNetworkList(),s.apply(window,arguments).then(e=>(this.netSending=!1,a.status=e.status,a.statusText=e.statusText,a.endTime=Date.now(),a.duration=a.endTime-a.startTime,e.clone().text().then(t=>{a.resBody=t}).catch(()=>{}),e.headers.forEach((t,e)=>a.resHeaders[e]=t),"network"===t.currentTab&&t.renderNetworkList(),e)).catch(e=>{throw this.netSending=!1,a.error=e.message,a.status=0,a.endTime=Date.now(),a.duration=a.endTime-a.startTime,"network"===t.currentTab&&t.renderNetworkList(),e})}}renderNetFilters(){this.netFiltersEl&&(this.netFiltersEl.innerHTML=[{id:"all",name:"全部",icon:"fa fa-list"},{id:"get",name:"获取",icon:"fa fa-download"},{id:"post",name:"提交",icon:"fa fa-upload"},{id:"put",name:"更新",icon:"fa fa-pen"},{id:"success",name:"成功",icon:"fa fa-check-circle"},{id:"failed",name:"失败",icon:"fa fa-times-circle"}].map(t=>`<button class="tc-net-filter-btn ${this.activeNetFilter===t.id?"tc-active":""}" data-net-filter="${t.id}" data-orig="${t.name}"><i class="${t.icon}"></i> ${t.name}</button>`).join(""),this.netFiltersEl.querySelectorAll(".tc-net-filter-btn").forEach(t=>{t.addEventListener("click",()=>{this.netFiltersEl.querySelectorAll(".tc-net-filter-btn").forEach(t=>t.classList.remove("tc-active")),t.classList.add("tc-active"),this.activeNetFilter=t.dataset.netFilter,this.renderNetworkList(),this.updateNetDisableBtn(),this.scrollFilterIntoView(this.netFiltersEl,t)})}),this.updateNetFilterCounts())}updateNetFilterCounts(){if(!this.netFiltersEl)return;let t=this.networkRequests,e={all:t.length,get:t.filter(t=>"get"===t.method.toLowerCase()).length,post:t.filter(t=>"post"===t.method.toLowerCase()).length,put:t.filter(t=>"put"===t.method.toLowerCase()).length,success:t.filter(t=>t.status>=200&&t.status<400).length,failed:t.filter(t=>0===t.status||t.status>=400||t.error).length};this.netFiltersEl.querySelectorAll(".tc-net-filter-btn").forEach(t=>{let s=t.dataset.orig,i=e[t.dataset.netFilter]||0,n=t.querySelector("i")?t.querySelector("i").className:"";if(t.classList.contains("tc-active")){let e=i>99?"99+":i;t.innerHTML=`<i class="${n}"></i> ${s} (${e})`}else t.innerHTML=`<i class="${n}"></i> ${s}`})}updateNetDisableBtn(){if(!this.netDisableBtn)return;let t=this.activeNetFilter,e="";"all"===t?e="全部":"get"===t?e="获取":"post"===t?e="提交":"put"===t?e="更新":"success"===t?e="成功(全部)":"failed"===t&&(e="失败(全部)");let s=this.netDisabledTypes.has(t);this.netDisableBtn.innerHTML='<i class="fa fa-ban"></i>',this.netDisableBtn.title=s?`已禁用${e}请求`:`禁用${e}请求`,this.netDisableBtn.classList.toggle("tc-disabled",s)}toggleNetDisable(){let t=this.activeNetFilter,e="";if("all"===t?e="全部":"get"===t?e="获取":"post"===t?e="提交":"put"===t?e="更新":"success"===t?e="成功(全部)":"failed"===t&&(e="失败(全部)"),this.netDisabledTypes.has(t)){this.netDisabledTypes.delete(t);var s=!1}else this.netDisabledTypes.add(t),s=!0;this.updateNetDisableBtn(),this.showNotification(s?`已禁用${e}请求`:`已恢复${e}请求`,s?"warning":"")}getFilteredNetRequests(){let t=this.networkRequests;if(!this.activeNetFilter||"all"===this.activeNetFilter)return t;let e=this.activeNetFilter;return"get"===e||"post"===e||"put"===e?t.filter(t=>t.method.toLowerCase()===e):"success"===e?t.filter(t=>t.status>=200&&t.status<400):"failed"===e?t.filter(t=>0===t.status||t.status>=400||t.error):t}renderNetworkList(){if("network"!==this.currentTab)return;if(!this.networkItems)return;let t=this.getFilteredNetRequests();if(this.searchQuery){let e=this.searchQuery.toLowerCase();t=t.filter(t=>{if(t.url.toLowerCase().includes(e))return!0;if(t.method.toLowerCase().includes(e))return!0;try{if(this.safeStringify(t.reqHeaders).toLowerCase().includes(e))return!0}catch(t){}try{if(("string"==typeof t.reqBody?t.reqBody:this.safeStringify(t.reqBody)).toLowerCase().includes(e))return!0}catch(t){}try{if(this.safeStringify(t.resHeaders).toLowerCase().includes(e))return!0}catch(t){}return!!(t.resBody||"").toLowerCase().includes(e)})}if(this.updateNetFilterCounts(),0===t.length)return void(this.networkItems.innerHTML='<div class="tc-nolog"><i class="fa fa-wifi"></i>暂无网络请求</div>');let e=this.networkItems,s=e.scrollHeight-e.scrollTop-e.clientHeight<50;e.innerHTML=t.slice(-200).map(t=>this.renderNetworkItem(t)).join(""),s&&(e.scrollTop=e.scrollHeight)}renderNetworkItem(t){let e=t.status>0?Math.floor(t.status/100)+"xx":"pending",s=t.error||t.status>=400?"tc-net-failed":t.status>=200&&t.status<400?"tc-net-success":"",i=t.status>0?String(t.status):t.error?"ERR":"...",n=t.duration>0?t.duration+"ms":"",o=n?i+" "+n:i,a="";try{a=new Date(t.startTime).toLocaleTimeString()}catch(t){a=""}return`<div class="tc-net-item ${s}" data-req-id="${t.id}"><div class="tc-net-row1"><span class="tc-net-method tc-net-method-${t.method}">${t.method}</span><span class="tc-net-time">${this.escapeHtml(a)}</span></div><div class="tc-net-row2"><span class="tc-net-url" title="${this.escapeHtml(t.url)}">${this.escapeHtml(t.url)}</span><span class="tc-net-status tc-net-status-${e}">${this.escapeHtml(o)}</span></div><div class="tc-net-row3"><button class="tc-net-copy-btn" data-action="copy" title="复制请求JSON"><i class="fa fa-copy"></i> 复制</button><button class="tc-net-detail-btn" data-action="detail" title="查看详情"><i class="fa fa-eye"></i> 详情</button></div></div>`}renderNetJsonTree(t,e){try{let s=JSON.parse(t);return null==s?this.highlightJson(this.escapeHtml(t)):'<div class="tc-json-tree-container">'+this.renderJSONTree(s,"",null,null,e,0,!0)+"</div>"}catch(e){return this.highlightJson(this.escapeHtml(t))}}showNetDetail(t){let e=this.networkRequests.find(e=>e.id===t);if(!e)return;this.netDetailId=t;let s=e.status>0?Math.floor(e.status/100)+"xx":"pending",i=e.status>0?e.status+" "+(e.statusText||""):e.error||"等待中...",n=e.duration>0?e.duration+"ms":"",o=n?i+" ("+n+")":i,a="";try{a=this.safeStringify(e.reqHeaders,2)}catch(t){a=String(e.reqHeaders||"")}let r=!a||"{}"===a||"null"===a,l=r?'<span class="tc-net-detail-empty">无请求头</span>':this.renderNetJsonTree(a,"net-"+t+"-reqHeaders"),c="";if(e.reqBody)try{c="string"==typeof e.reqBody?e.reqBody:this.safeStringify(e.reqBody,2)}catch(t){c=String(e.reqBody)}let d=!c||"null"===c||"undefined"===c,h=d?'<span class="tc-net-detail-empty">无请求内容</span>':this.renderNetJsonTree(c,"net-"+t+"-reqBody"),p="";try{p=this.safeStringify(e.resHeaders,2)}catch(t){p=String(e.resHeaders||"")}let u=!p||"{}"===p||"null"===p,f=u?'<span class="tc-net-detail-empty">无响应头</span>':this.renderNetJsonTree(p,"net-"+t+"-resHeaders"),g=e.resBody||"",m="";if(g)try{m=JSON.stringify(JSON.parse(g),null,2)}catch(t){m=g}let b=!m||"null"===m||"undefined"===m,y=b?'<span class="tc-net-detail-empty">无响应内容</span>':this.renderNetJsonTree(m,"net-"+t+"-resBody"),v=(t,e,s,i)=>`<div class="tc-net-detail-section"><div class="tc-net-detail-section-header"><div class="tc-net-detail-label">${t}</div>${i?"":`<button class="tc-net-detail-copy-section" data-copy-text="${this.escapeHtml(s)}" title="复制"><i class="fa fa-copy"></i></button>`}</div><div class="${i||e.indexOf("tc-json-tree-container")>=0?"tc-net-detail-value":"tc-net-detail-value tc-net-detail-code"}">${e}</div></div>`,x=`<div class="tc-net-detail-section"><div class="tc-net-detail-section-header"><div class="tc-net-detail-label">网址</div><button class="tc-net-detail-copy-section" data-copy-text="${this.escapeHtml(e.url)}" title="复制网址"><i class="fa fa-copy"></i></button></div><div class="tc-net-detail-value tc-net-detail-code">${this.escapeHtml(e.url)}</div></div>`,w=`<div class="tc-net-detail-section"><div class="tc-net-detail-section-header"><div class="tc-net-detail-label">类型</div></div><span class="tc-net-method tc-net-method-${e.method}">${e.method}</span></div>`,k=`<div class="tc-net-detail-section"><div class="tc-net-detail-section-header"><div class="tc-net-detail-label">状态</div></div><span class="tc-net-status tc-net-status-${s}">${this.escapeHtml(o)}</span></div>`,S=v("请求头",l,a,r),E=v("请求内容",h,c,d),T=v("响应头",f,p,u),L=v("响应内容",y,m,b);this.netDetailBody.innerHTML=x+w+k+S+E+T+L,this.netDetailBody.querySelectorAll(".tc-net-detail-copy-section").forEach(t=>{t.addEventListener("click",()=>{let e=t.getAttribute("data-copy-text")||"";navigator.clipboard.writeText(e).then(()=>this.showNotification("已复制")).catch(()=>{})})});let C=this.overlay.querySelector("#tc-netResendIconBtn");C&&C.addEventListener("click",()=>this.resendRequest(e)),this.netDetailOverlay.style.display="flex"}resendRequest(t){this.netDetailOverlay.style.display="none",this.netNewOverlay.style.display="flex",this.netNewUrl.value=t.url,this.netNewMethod.value=t.method;let e="";if(t.reqBody)try{e="string"==typeof t.reqBody?t.reqBody:JSON.stringify(t.reqBody,null,2)}catch(t){e=""}this.netNewBody.value=e||"";let s="";try{t.reqHeaders&&"object"==typeof t.reqHeaders&&(s=(Array.isArray(t.reqHeaders)?t.reqHeaders:Object.entries(t.reqHeaders)).map(t=>Array.isArray(t)?t[0]+": "+t[1]:t).join("\n"))}catch(t){}this.netNewHeaders.value=s||""}sendNewRequest(){if(this.editorState.visible){let t=this.editorState.mode;if("code"===t)return void this.showNotification("正在运行代码,无法发送请求","warning");if("ls"===t)return void this.showNotification("正在保存键值,无法发送请求","warning")}let t=this.netNewUrl.value.trim();if(!t)return void this.showNotification("请输入网址","warning");let e=this.netNewMethod.value,s=this.netNewBody.value.trim(),i=this.netNewHeaders.value.trim(),n={};i&&i.split("\n").forEach(t=>{let e=t.indexOf(":");e>0&&(n[t.slice(0,e).trim()]=t.slice(e+1).trim())});let o={method:e,headers:n};if(s&&"GET"!==e&&"HEAD"!==e)try{o.body=JSON.stringify(JSON.parse(s)),n["Content-Type"]||(n["Content-Type"]="application/json")}catch(t){o.body=s}this.netSending=!0,this.netNewVisible=!1,this.netNewOverlay.style.display="none",this.showNotification("正在发送请求...");let a={id:++this._netReqId,url:t,method:e,status:0,statusText:"",reqHeaders:n,reqBody:o.body||null,resHeaders:{},resBody:null,startTime:Date.now(),endTime:0,duration:0,error:null};this.networkRequests.push(a),(this.originalFetch||window.fetch).call(window,t,o).then(t=>{this.netSending=!1,a.status=t.status,a.statusText=t.statusText,a.endTime=Date.now(),a.duration=a.endTime-a.startTime,t.clone().text().then(t=>{a.resBody=t}).catch(()=>{}),t.headers.forEach((t,e)=>a.resHeaders[e]=t),this.showNotification("请求完成: "+t.status,t.status>=400?"warning":""),"network"===this.currentTab&&this.renderNetworkList()}).catch(t=>{this.netSending=!1,a.error=t.message,a.status=0,a.endTime=Date.now(),a.duration=a.endTime-a.startTime,this.showNotification("请求失败: "+t.message,"warning"),"network"===this.currentTab&&this.renderNetworkList()})}renderNetworkPanel(){this.renderNetFilters(),this.updateNetDisableBtn(),this.renderNetworkList()}clearNetworkRequests(){let t=this.activeNetFilter||"all",e="";"all"===t?e="全部":"get"===t?e="获取":"post"===t?e="提交":"put"===t?e="更新":"success"===t?e="成功":"failed"===t&&(e="失败");let s=this.getFilteredNetRequests();if(confirm("确定要清除所有"+e+"请求吗?\n共 "+s.length+" 条请求将被删除,此操作不可撤销。")){if("all"===t)this.networkRequests=[];else{let e="get"===t||"post"===t||"put"===t?e=>e.method.toLowerCase()!==t:"success"===t?t=>!(t.status>=200&&t.status<400):t=>!(0===t.status||t.status>=400||t.error);this.networkRequests=this.networkRequests.filter(e)}this.renderNetworkList(),this.showNotification("已清空"+e+"请求")}}switchTab(t){let e=Array.from(this.tabButtons).find(e=>e.dataset.tab===t);e&&e.click()}show(t="console"){return this.overlay||this.createOverlayElement(),this.switchTab(t),this.triggerGlobalHook("beforeOpen"),this.overlay.classList.add("tc-active","tc-theme-"+this.currentTheme),this.triggerGlobalHook("afterOpen"),this}hide(){return this.overlay&&(this.triggerGlobalHook("beforeClose"),this.overlay.classList.remove("tc-active"),this.triggerGlobalHook("afterClose")),this}}t.plugins={},window.thinConsole=t,t.tC=null,t.hooks={beforeRender:[],afterRender:[],beforeLog:[],afterLog:[],beforeOpen:[],afterOpen:[],beforeClose:[],afterClose:[],beforeClear:[],afterClear:[],pluginMount:[],pluginUnmount:[]},t.show=e=>(t.tC?.show(e),t),t.hide=()=>(t.tC?.hide(),t),t.destroy=()=>t.tC?.destroy(),t.log=(...e)=>(console.log(...e),t),t.info=(...e)=>(console.info(...e),t),t.warn=(...e)=>(console.warn(...e),t),t.error=(...e)=>(console.error(...e),t),t.addPlugin=function(s,i,n={}){if(t.tC){if(i.prototype instanceof e){if(i.config=n,t.plugins[s]=i,t.tC.disabledPlugins.includes(s))return;if(t.tC.pluginEnabled&&!t.tC.plugins[s])try{let e=new i(t.tC,n);if(e.init(),t.tC.plugins[s]=e,e.addTab){let i=e.addTab();t.tC.pluginTabs[s]={id:i.id,name:i.name,icon:i.icon||"fa fa-tool",plugin:e},t.tC.createPluginTab(i)}t.tC.triggerGlobalHook("pluginMount",s,e)}catch(i){console.error(`插件"${s}"动态加载失败:`,i)}}else{if("function"!=typeof i)throw new Error(`插件"${s}"必须是类或函数类型`);if(!t.tC.options.plugins||t.tC.disabledPlugins.includes(s))return;try{i.call(null,t.tC,n),t.tC.triggerGlobalHook("pluginMount",s,null)}catch(i){console.error(`函数插件"${s}"执行失败:`,i)}}return t}},t.addTabs=function(e){if(!t.tC)return t;Array.isArray(e)||(e=[e]);for(let s of e){if(t.tC.customTabCount>=5){console.warn("自定义Tab数量已达上限(5个)");break}if(!s.id||!s.name){console.warn("Tab必须包含id和name属性");continue}if(t.tC.pluginViewContainers[s.id]){console.warn("Tab ID '"+s.id+"'已存在");continue}t.tC.createPluginTab({id:s.id,name:s.name,icon:s.icon||"fa fa-plug"});let e=t.tC.pluginViewContainers[s.id];e&&(e.innerHTML="","function"==typeof s.render?s.render(e):s.html&&(e.innerHTML=s.html),s.onShow&&(t.tC.pluginTabs[s.id]={id:s.id,name:s.name,icon:s.icon||"fa fa-plug",onShow:s.onShow})),t.tC.customTabCount++}return t},t.addHook=function(e,s){return t.hooks[e]&&!t.hooks[e].includes(s)?t.hooks[e].push(s):console.warn(`未知钩子:${e}`),t},t.removeHook=function(e,s){return t.hooks[e]&&(t.hooks[e]=t.hooks[e].filter(t=>t!==s)),t},t.setFilterCounts=function(e){return t.tC&&t.tC.updatePluginFilterCounts(e),t};class e{constructor(e,s={}){if(!(e instanceof t))throw new Error("插件必须绑定到thinConsole实例");this.tC=e,this.config=s,this.id=this.constructor.name.toLowerCase()}init(){}iszh(){return!0}isen(){return!1}isMobile(){return/iPad|Android(?!.*Mobile)|Mobi|Android|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)}render(t){}onShow(){}onHide(){}destroy(){}}return t.tCPlugin=e,"undefined"!=typeof window&&(window.tCPlugin=e),t});