UNPKG

js-use-core

Version:

JavaScript Comprehensive tool library, including full screen, copy and paste functions

2 lines (1 loc) 34.4 kB
var e,t,i,n,r;!function(e){e.MOBILE="mobile",e.TABLET="tablet",e.DESKTOP="desktop"}(e||(e={})),function(e){e.WINDOWS="windows",e.MACOS="macos",e.LINUX="linux",e.ANDROID="android",e.IOS="ios",e.UNKNOWN="unknown"}(t||(t={})),function(e){e.CHROME="chrome",e.FIREFOX="firefox",e.SAFARI="safari",e.EDGE="edge",e.IE="ie",e.OPERA="opera",e.UNKNOWN="unknown"}(i||(i={})),function(e){e.PORTRAIT="portrait",e.LANDSCAPE="landscape"}(n||(n={})),function(e){e.WIFI="wifi",e.CELLULAR="cellular",e.ETHERNET="ethernet",e.UNKNOWN="unknown"}(r||(r={}));const o=new Map,s=3e5;function a(){const e=Date.now();for(const[t,i]of o.entries())e-i.timestamp>s&&o.delete(t)}function c(e){a();const t=o.get(e);return t&&Date.now()-t.timestamp<s?t.result:null}function u(e,t){o.set(e,{result:t,timestamp:Date.now()})}function l(e){e||(e={});let t=e.ua;if(t||"undefined"==typeof navigator||(t=navigator.userAgent),t&&"object"==typeof t&&t.headers&&"string"==typeof t.headers["user-agent"]&&(t=t.headers["user-agent"]),"string"!=typeof t)return!1;const i=`mobile_${t}_${!!e.tablet}_${!!e.featureDetect}`,n=c(i);if(null!==n)return n;let r=/(android|bb\d+|meego).+mobile|armv7l|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series[46]0|samsungbrowser.*mobile|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino|android.+mobile/i.test(t)&&!/CrOS|Windows NT/.test(t)||!!e.tablet&&/android(?!.*mobile)|ipad|playbook|silk|kindle/i.test(t);if(!r&&e.featureDetect&&"undefined"!=typeof navigator&&(navigator.maxTouchPoints>1&&-1!==t.indexOf("Macintosh")&&-1!==t.indexOf("Safari")&&-1===t.indexOf("Chrome")&&(r=!!e.tablet),!r&&navigator.maxTouchPoints>0&&"undefined"!=typeof window)){const t=window.screen.width,i=window.screen.height,n=Math.min(t,i),o=Math.max(t,i);(n<768&&o<1024||e.tablet&&n>=768)&&(r=!0)}return u(i,r),r}function d(e){return l({...e,tablet:!0})&&!l(e)}function h(e){return!l({...e,tablet:!0})}function f(t){return d(t)?e.TABLET:l(t)?e.MOBILE:e.DESKTOP}function g(e){const i=e||("undefined"!=typeof navigator?navigator.userAgent:""),n=`os_${i}`,r=c(n);if(null!==r)return r;let o;return o=/iphone|ipad|ipod/i.test(i)?t.IOS:/android/i.test(i)?t.ANDROID:/windows nt|win32|win64|wow64/i.test(i)?t.WINDOWS:/macintosh|mac os x|darwin/i.test(i)?/iphone|ipad|ipod/i.test(i)?t.IOS:t.MACOS:/linux|x11/i.test(i)&&!/android/i.test(i)||/cros/i.test(i)?t.LINUX:t.UNKNOWN,u(n,o),o}function R(e){const t=e||("undefined"!=typeof navigator?navigator.userAgent:""),n=`browser_${t}`,r=c(n);if(null!==r)return r;let o;return o=/edg(?:e|ios|a)?/i.test(t)?i.EDGE:/opr\/|opera/i.test(t)?i.OPERA:/chrome|crios|crmo/i.test(t)&&!/edg/i.test(t)?i.CHROME:/firefox|fxios/i.test(t)?i.FIREFOX:/safari/i.test(t)&&!/chrome|crios|crmo|edg|opr|opera/i.test(t)?i.SAFARI:/msie|trident/i.test(t)?i.IE:i.UNKNOWN,u(n,o),o}function m(){return"undefined"!=typeof window&&("ontouchstart"in window||navigator.maxTouchPoints>0||navigator.msMaxTouchPoints>0)}function p(){return"undefined"!=typeof window&&window.devicePixelRatio>1}function w(){return"undefined"!=typeof window&&(window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches)}function E(){return new Promise(e=>{if("undefined"==typeof window)return void e(!1);const t=new Image;t.onload=t.onerror=()=>{e(2===t.height)},t.src="data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA"})}function A(){return new Promise(e=>{if("undefined"==typeof window)return void e(!1);const t=new Image;t.onload=t.onerror=()=>{e(2===t.height)},t.src="data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgABogQEAwgMg8f8D///8WfhwB8+ErK42A="})}function v(){o.clear()}function O(){return a(),{size:o.size,keys:Array.from(o.keys())}}function y(e){e||(e={});let t=e.ua;if(t||"undefined"==typeof navigator||(t=navigator.userAgent),t&&"object"==typeof t&&t.headers&&"string"==typeof t.headers["user-agent"]&&(t=t.headers["user-agent"]),"string"!=typeof t)return{isMobile:!1,isTablet:!1,confidence:0,method:"userAgent"};const i={isMobile:l(e),isTablet:d(e)};if(!e.featureDetect||"undefined"==typeof window)return{...i,confidence:.8,method:"userAgent"};const n="ontouchstart"in window||navigator.maxTouchPoints>0,r=window.screen.width,o=window.screen.height,s=Math.min(r,o),a=Math.max(r,o),c=window.devicePixelRatio||1;let u={isMobile:!1,isTablet:!1};n&&(s<=480&&a<=896?u.isMobile=!0:s>=768&&s<=1024?u.isTablet=!0:s>480&&s<768&&(c>=2?u.isMobile=!0:u.isTablet=!0));const h={isMobile:i.isMobile||u.isMobile,isTablet:i.isTablet||u.isTablet,confidence:.9,method:"hybrid"};return i.isMobile===u.isMobile&&i.isTablet===u.isTablet&&(h.confidence=.95),h}let b=null,I=0;function S(e=!1){if("undefined"==typeof window)return{width:0,height:0,pixelRatio:1};const t=Date.now();if(!e&&b&&t-I<3e4)return b;const i={width:window.screen.width,height:window.screen.height,pixelRatio:window.devicePixelRatio||1};return b=i,I=t,i}function T(){if("undefined"==typeof window)return{width:0,height:0,availWidth:0,availHeight:0,pixelRatio:1,colorDepth:24,pixelDepth:24,orientation:0};const e=window.screen;return{width:e.width,height:e.height,availWidth:e.availWidth,availHeight:e.availHeight,pixelRatio:window.devicePixelRatio||1,colorDepth:e.colorDepth||24,pixelDepth:e.pixelDepth||24,orientation:e.orientation?.angle||0}}function D(e=!1){return"undefined"==typeof window?{width:0,height:0}:e?{width:window.outerWidth||window.innerWidth||document.documentElement.clientWidth,height:window.outerHeight||window.innerHeight||document.documentElement.clientHeight}:{width:window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth,height:window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight}}function N(){return"undefined"==typeof window?{width:0,height:0}:"visualViewport"in window&&window.visualViewport?{width:window.visualViewport.width,height:window.visualViewport.height}:D()}function _(){const{width:e}=D();return e<576?"small":e<768?"medium":e<1200?"large":"xlarge"}function x(){if("undefined"==typeof window)return n.PORTRAIT;const{width:e,height:t}=D();return e>t?n.LANDSCAPE:n.PORTRAIT}function M(e){if("undefined"==typeof window)return()=>{};const t=()=>{e(x())};return window.addEventListener("orientationchange",t),window.addEventListener("resize",t),()=>{window.removeEventListener("orientationchange",t),window.removeEventListener("resize",t)}}function L(){if("undefined"==typeof navigator||!("connection"in navigator))return r.UNKNOWN;const e=navigator.connection||navigator.mozConnection||navigator.webkitConnection;if(!e)return r.UNKNOWN;const t=e.type||e.effectiveType;return"wifi"===t?r.WIFI:"cellular"===t||/^[2-4]g$/.test(t)?r.CELLULAR:"ethernet"===t?r.ETHERNET:r.UNKNOWN}function C(){if("undefined"==typeof navigator||!("connection"in navigator))return{downlink:0,rtt:0,effectiveType:"unknown"};const e=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return e?{downlink:e.downlink||0,rtt:e.rtt||0,effectiveType:e.effectiveType||"unknown"}:{downlink:0,rtt:0,effectiveType:"unknown"}}function U(){return"undefined"==typeof navigator||navigator.onLine}function z(e){if("undefined"==typeof window)return()=>{};const t=()=>e(!0),i=()=>e(!1);return window.addEventListener("online",t),window.addEventListener("offline",i),()=>{window.removeEventListener("online",t),window.removeEventListener("offline",i)}}async function W(){if("undefined"==typeof navigator||!("getBattery"in navigator))return null;try{const e=await navigator.getBattery();return{charging:e.charging,level:e.level,chargingTime:e.chargingTime,dischargingTime:e.dischargingTime}}catch{return null}}function k(){if("undefined"!=typeof performance&&"memory"in performance){const e=performance.memory;if(e)return{usedJSHeapSize:e.usedJSHeapSize,totalJSHeapSize:e.totalJSHeapSize,jsHeapSizeLimit:e.jsHeapSizeLimit}}return null}function P(){return"undefined"!=typeof navigator&&"serviceWorker"in navigator}function B(){return"undefined"!=typeof Worker}function H(){return"undefined"!=typeof WebAssembly}function F(){if("undefined"==typeof window)return!1;try{const e=document.createElement("canvas");return!!(e.getContext("webgl")||e.getContext("experimental-webgl"))}catch{return!1}}function G(){if("undefined"==typeof window)return!1;try{const e=document.createElement("canvas");return!!e.getContext("webgl2")}catch{return!1}}function K(){if("undefined"==typeof window)return null;try{const e=document.createElement("canvas"),t=e.getContext("webgl")||e.getContext("experimental-webgl");if(!t)return null;const i=t.getExtension("WEBGL_debug_renderer_info");return i?{vendor:t.getParameter(i.UNMASKED_VENDOR_WEBGL),renderer:t.getParameter(i.UNMASKED_RENDERER_WEBGL)}:null}catch{return null}}function $(){if("undefined"==typeof window)return{level:"unknown",score:0,memory:0,cores:0,gpu:null};let e=0,t="unknown";const i=navigator.hardwareConcurrency||1;e+=Math.min(10*i,40);const n=performance.memory;let r=0;n&&(r=n.jsHeapSizeLimit/1073741824,e+=Math.min(10*r,30));const o=K();if(o){const t=o.renderer.toLowerCase();t.includes("intel")&&t.includes("hd")?e+=10:t.includes("nvidia")||t.includes("amd")||t.includes("radeon")?e+=20:e+=15}const s=window.devicePixelRatio||1;return e+=Math.min(5*s,10),e>=60?t="high":e>=40?t="medium":e>=20&&(t="low"),{level:t,score:e,memory:r,cores:i,gpu:o}}function j(){return"undefined"==typeof window?{touch:!1,webgl:!1,webgl2:!1,webassembly:!1,serviceWorker:!1,webWorkers:!1,geolocation:!1,camera:!1,microphone:!1,notifications:!1,vibration:!1,battery:!1,deviceMotion:!1,deviceOrientation:!1}:{touch:Y(),webgl:F(),webgl2:G(),webassembly:H(),serviceWorker:P(),webWorkers:B(),geolocation:"geolocation"in navigator,camera:"mediaDevices"in navigator&&"getUserMedia"in navigator.mediaDevices,microphone:"mediaDevices"in navigator&&"getUserMedia"in navigator.mediaDevices,notifications:"Notification"in window,vibration:"vibrate"in navigator,battery:"getBattery"in navigator,deviceMotion:"DeviceMotionEvent"in window,deviceOrientation:"DeviceOrientationEvent"in window}}function Y(){return"undefined"!=typeof window&&("ontouchstart"in window||navigator.maxTouchPoints>0||navigator.msMaxTouchPoints>0||window.matchMedia&&window.matchMedia("(pointer: coarse)").matches)}function X(){return new Promise(e=>{const t={jsPerformance:0,renderPerformance:0,memoryPerformance:0},i=performance.now();if(t.jsPerformance=performance.now()-i,"undefined"!=typeof document){const i=performance.now(),n=document.createElement("div");n.style.width="100px",n.style.height="100px",n.style.backgroundColor="red",document.body.appendChild(n),requestAnimationFrame(()=>{t.renderPerformance=performance.now()-i,document.body.removeChild(n);const r=performance.memory;r&&(t.memoryPerformance=r.usedJSHeapSize/r.jsHeapSizeLimit),e(t)})}else e(t)})}function V(e,t=3e4){if("undefined"==typeof window)return()=>{};let i=!0;return(async()=>{for(;i;){const i=$();e(i),await new Promise(e=>setTimeout(e,t))}})(),()=>{i=!1}}function Q(){if("undefined"==typeof window)return!1;const e=$();return["low"===e.level,e.cores<=2,e.memory<2,window.devicePixelRatio<=1].filter(Boolean).length>=2}function J(){if("undefined"==typeof navigator)return"unknown";const e=navigator.thermal;if(e&&e.state)return e.state;const t=$();return"low"===t.level&&t.score<30?"serious":"normal"}function Z(){const e=$(),t=[],i={enableAnimations:!0,enableShadows:!0,enableBlur:!0,maxImageQuality:1,enableLazyLoading:!1};return Q()||"low"===e.level?(t.push("禁用复杂动画和过渡效果"),t.push("降低图片质量"),t.push("启用懒加载"),t.push("减少同时渲染的元素数量"),i.enableAnimations=!1,i.enableShadows=!1,i.enableBlur=!1,i.maxImageQuality=.7,i.enableLazyLoading=!0):"medium"===e.level?(t.push("适度使用动画效果"),t.push("优化图片加载"),i.maxImageQuality=.85,i.enableLazyLoading=!0):(t.push("可以使用所有视觉效果"),t.push("启用高质量渲染")),{level:"unknown"===e.level?"medium":e.level,suggestions:t,settings:i}}function q(e){return j()[e]}function ee(){const e=j(),t=$();let i=100;const n=[],r=[];return e.webgl||(i-=20,n.push("不支持WebGL,3D功能可能无法使用"),r.push("升级浏览器或使用支持WebGL的浏览器")),e.serviceWorker||(i-=15,n.push("不支持Service Worker,离线功能受限"),r.push("升级到现代浏览器")),e.webWorkers||(i-=10,n.push("不支持Web Workers,后台处理能力受限")),"low"===t.level&&(i-=25,n.push("设备性能较低,可能影响用户体验"),r.push("启用性能优化模式")),e.touch||"small"!==_()||(i-=5,n.push("小屏设备不支持触摸,交互体验可能不佳")),{score:Math.max(0,i),issues:n,recommendations:r}}class EventEmitter{constructor(){this.events=new Map,this.maxListeners=10}on(e,t,i){if("function"!=typeof t)throw new Error("Listener must be a function");const n={listener:t,once:i?.once||!1,priority:i?.priority||0};this.events.has(e)||this.events.set(e,[]);const r=this.events.get(e);r.length,this.maxListeners;let o=!1;for(let e=0;e<r.length;e++)if(n.priority>(r[e].priority||0)){r.splice(e,0,n),o=!0;break}return o||r.push(n),this}once(e,t,i){return this.on(e,t,{once:!0,priority:i})}off(e,t){if(!this.events.has(e))return this;const i=this.events.get(e);if(t){const n=i.findIndex(e=>e.listener===t);-1!==n&&(i.splice(n,1),0===i.length&&this.events.delete(e))}else this.events.delete(e);return this}emit(e,...t){if(!this.events.has(e))return!1;const i=this.events.get(e).slice(),n=[];for(const e of i)try{e.listener.apply(this,t),e.once&&n.push(e)}catch(e){}if(n.length>0){const t=this.events.get(e);if(t){for(const e of n){const i=t.indexOf(e);-1!==i&&t.splice(i,1)}0===t.length&&this.events.delete(e)}}return!0}listenerCount(e){return this.events.get(e)?.length||0}listeners(e){return this.events.get(e)?.map(e=>e.listener)||[]}eventNames(){return Array.from(this.events.keys())}removeAllListeners(e){return e?this.events.delete(e):this.events.clear(),this}setMaxListeners(e){if(e<0||!Number.isInteger(e))throw new Error("Max listeners must be a non-negative integer");return this.maxListeners=e,this}getMaxListeners(){return this.maxListeners}prependListener(e,t){return this.on(e,t,{priority:Number.MAX_SAFE_INTEGER})}prependOnceListener(e,t){return this.once(e,t,Number.MAX_SAFE_INTEGER)}}var te,ie,ne,re;!function(e){e.USER_ERROR="USER_ERROR",e.SYSTEM_ERROR="SYSTEM_ERROR",e.NETWORK_ERROR="NETWORK_ERROR",e.PERMISSION_ERROR="PERMISSION_ERROR",e.CONFIG_ERROR="CONFIG_ERROR",e.VALIDATION_ERROR="VALIDATION_ERROR",e.TIMEOUT_ERROR="TIMEOUT_ERROR",e.UNSUPPORTED_ERROR="UNSUPPORTED_ERROR",e.INTERNAL_ERROR="INTERNAL_ERROR",e.EXTERNAL_ERROR="EXTERNAL_ERROR",e.UNKNOWN_ERROR="UNKNOWN_ERROR"}(te||(te={})),function(e){e.LOW="low",e.MEDIUM="medium",e.HIGH="high",e.CRITICAL="critical"}(ie||(ie={})),function(e){e.USER_ERROR="USER_ERROR",e.SYSTEM_ERROR="SYSTEM_ERROR",e.NETWORK_ERROR="NETWORK_ERROR",e.PERMISSION_ERROR="PERMISSION_ERROR",e.CONFIG_ERROR="CONFIG_ERROR",e.TIMEOUT_ERROR="TIMEOUT_ERROR",e.VALIDATION_ERROR="VALIDATION_ERROR",e.INTERNAL_ERROR="INTERNAL_ERROR",e.UNKNOWN_ERROR="UNKNOWN_ERROR"}(ne||(ne={})),function(e){e[e.DEBUG=0]="DEBUG",e[e.INFO=1]="INFO",e[e.WARN=2]="WARN",e[e.ERROR=3]="ERROR"}(re||(re={}));class Logger{constructor(e="Core",t){this.level=re.INFO,this.logs=[],this.maxLogs=1e3,this.enableConsole=!0,this.module=e,t&&(this.level=t.level??re.INFO,this.maxLogs=t.maxLogs??1e3,this.enableConsole=t.enableConsole??!0)}setLevel(e){this.level=e}getLevel(){return this.level}debug(e,t){this.log(re.DEBUG,e,t)}info(e,t){this.log(re.INFO,e,t)}warn(e,t){this.log(re.WARN,e,t)}error(e,t){this.log(re.ERROR,e,t)}log(e,t,i){if(e<this.level)return;const n={level:e,message:t,timestamp:Date.now(),module:this.module,data:i};this.logs.push(n),this.logs.length>this.maxLogs&&this.logs.shift(),this.enableConsole&&this.outputToConsole(n)}outputToConsole(e){new Date(e.timestamp).toISOString(),re[e.level],e.module,e.message,void 0!==e.data&&e.data;switch(e.level){case re.DEBUG:case re.INFO:case re.WARN:case re.ERROR:}}getLogs(){return[...this.logs]}getLogsByLevel(e){return this.logs.filter(t=>t.level===e)}getLogsByTimeRange(e,t){return this.logs.filter(i=>i.timestamp>=e&&i.timestamp<=t)}clear(){this.logs=[]}setMaxLogs(e){if(e<0)throw new Error("Max logs must be non-negative");this.maxLogs=e,this.logs.length>e&&(this.logs=this.logs.slice(-e))}setConsoleOutput(e){this.enableConsole=e}exportLogs(){return JSON.stringify(this.logs,null,2)}importLogs(e){try{const t=JSON.parse(e);Array.isArray(t)&&(this.logs=t.filter(e=>e&&"number"==typeof e.level&&"string"==typeof e.message&&"number"==typeof e.timestamp))}catch(e){this.error("Failed to import logs",e)}}createChild(e){return new Logger(`${this.module}.${e}`,{level:this.level,maxLogs:this.maxLogs,enableConsole:this.enableConsole})}}class oe extends Error{constructor(e,t,i){super(t),this.name="CustomError",this.type=e,this.code=i?.code,this.context=i?.context,this.recoverable=i?.recoverable??!1,i?.cause&&(this.cause=i.cause),Error.captureStackTrace&&Error.captureStackTrace(this,oe)}}class ErrorHandler{constructor(e){this.errorSolutions=new Map,this.logger=e||new Logger("ErrorHandler"),this.initializeErrorSolutions()}handleError(e,t){const i=this.classifyError(e),n={module:"Unknown",method:"Unknown",timestamp:Date.now(),userAgent:"undefined"!=typeof navigator?navigator.userAgent:"Node.js",...t},r={type:i,severity:this.getErrorSeverity(i),message:e.message,userMessage:this.getUserFriendlyMessage(e,i),originalError:e,context:n,code:this.getErrorCode(e)||this.generateErrorCode(i),recoverable:this.isRecoverableError(e),solutions:this.getErrorSolutions(e),id:this.generateErrorId(),processedAt:Date.now(),relatedErrors:[]};return this.logger.error(`[${i}] ${r.message}`,{error:e.message,stack:e.stack,context:n,recoverable:r.recoverable}),r}createError(e,t,i){const n={module:"Unknown",method:"Unknown",timestamp:Date.now(),userAgent:"undefined"!=typeof navigator?navigator.userAgent:"Node.js",...i?.context};return new oe(e,t,{code:i?.code,context:n,recoverable:i?.recoverable,cause:i?.cause})}isRecoverableError(e){if(e instanceof oe)return e.recoverable;switch(this.classifyError(e)){case te.NETWORK_ERROR:case te.TIMEOUT_ERROR:return!0;case te.PERMISSION_ERROR:case te.SYSTEM_ERROR:return!1;case te.USER_ERROR:case te.CONFIG_ERROR:return!0;default:return!1}}getErrorSolution(e){const t=this.getErrorCode(e);if(t&&this.errorSolutions.has(t))return this.errorSolutions.get(t);const i=this.classifyError(e);return this.getDefaultSolution(i)}getErrorSolutions(e){const t=this.getErrorSolution(e);return t?[{description:t,steps:[t],automatic:!1,priority:1}]:[]}getErrorSeverity(e){switch(e){case te.USER_ERROR:case te.CONFIG_ERROR:return ie.LOW;case te.NETWORK_ERROR:case te.TIMEOUT_ERROR:return ie.MEDIUM;case te.PERMISSION_ERROR:case te.VALIDATION_ERROR:return ie.HIGH;case te.SYSTEM_ERROR:case te.INTERNAL_ERROR:return ie.CRITICAL;default:return ie.MEDIUM}}generateErrorCode(e){return`${e}_${Date.now().toString(36)}_${Math.random().toString(36).substr(2,5)}`.toUpperCase()}generateErrorId(){return`error_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}addErrorSolution(e,t){this.errorSolutions.set(e,t)}addErrorSolutions(e){for(const[t,i]of Object.entries(e))this.errorSolutions.set(t,i)}classifyError(e){if(e instanceof oe)return e.type;const t=(e.message||"").toLowerCase(),i=(e.name||"").toLowerCase();return t.includes("network")||t.includes("fetch")||t.includes("xhr")||i.includes("networkerror")?te.NETWORK_ERROR:t.includes("timeout")||t.includes("timed out")||i.includes("timeouterror")?te.TIMEOUT_ERROR:t.includes("permission")||t.includes("denied")||t.includes("unauthorized")||t.includes("forbidden")||i.includes("notallowederror")?te.PERMISSION_ERROR:t.includes("not supported")||t.includes("not available")||t.includes("not implemented")||i.includes("notsupportederror")?te.SYSTEM_ERROR:t.includes("invalid")||t.includes("configuration")||t.includes("config")||i.includes("configerror")?te.CONFIG_ERROR:e instanceof TypeError||e instanceof RangeError||t.includes("invalid argument")||t.includes("invalid parameter")?te.USER_ERROR:te.UNKNOWN_ERROR}getUserFriendlyMessage(e,t){switch(t){case te.NETWORK_ERROR:return"网络连接失败,请检查网络连接后重试";case te.TIMEOUT_ERROR:return"操作超时,请稍后重试";case te.PERMISSION_ERROR:return"权限不足,请检查浏览器权限设置";case te.SYSTEM_ERROR:return"当前浏览器不支持此功能,请使用其他浏览器或升级浏览器版本";case te.CONFIG_ERROR:return"配置参数错误,请检查配置";case te.USER_ERROR:return"输入参数错误,请检查输入参数";default:return e.message||"发生未知错误"}}getErrorCode(e){if(e instanceof oe)return e.code;const t=e;return t.code||t.errno||void 0}getDefaultSolution(e){switch(e){case te.NETWORK_ERROR:return"请检查网络连接,确保网络正常后重试";case te.TIMEOUT_ERROR:return"请稍后重试,或增加超时时间设置";case te.PERMISSION_ERROR:return"请在浏览器设置中允许相关权限,或使用HTTPS协议";case te.SYSTEM_ERROR:return"请使用支持此功能的现代浏览器,或升级浏览器版本";case te.CONFIG_ERROR:return"请检查配置参数是否正确,参考文档进行配置";case te.USER_ERROR:return"请检查输入参数的类型和格式是否正确";default:return null}}initializeErrorSolutions(){this.errorSolutions.set("ENOTFOUND","域名解析失败,请检查网络连接"),this.errorSolutions.set("ECONNREFUSED","连接被拒绝,请检查服务器状态"),this.errorSolutions.set("ETIMEDOUT","连接超时,请检查网络连接或稍后重试"),this.errorSolutions.set("CERT_UNTRUSTED","SSL证书不受信任,请检查证书配置"),this.errorSolutions.set("MIXED_CONTENT","混合内容错误,请使用HTTPS协议")}}class Cache{constructor(e){this.cache=new Map,this.config={maxSize:e?.maxSize??100,defaultTTL:e?.defaultTTL??3e5,enableLRU:e?.enableLRU??!0,cleanupInterval:e?.cleanupInterval??6e4},this.startCleanup()}set(e,t,i){const n=Date.now(),r={value:t,expireAt:n+(i??this.config.defaultTTL),createdAt:n,accessCount:0,lastAccessed:n};this.cache.size>=this.config.maxSize&&!this.cache.has(e)&&this.evictLRU(),this.cache.set(e,r)}get(e){const t=this.cache.get(e);if(!t)return;const i=Date.now();if(!(i>t.expireAt))return t.accessCount++,t.lastAccessed=i,t.value;this.cache.delete(e)}has(e){const t=this.cache.get(e);return!!t&&(!(Date.now()>t.expireAt)||(this.cache.delete(e),!1))}delete(e){return this.cache.delete(e)}clear(){this.cache.clear()}size(){return this.cache.size}keys(){return Array.from(this.cache.keys())}getInfo(e){const t=this.cache.get(e);if(t){if(!(Date.now()>t.expireAt))return{...t};this.cache.delete(e)}}touch(e,t){const i=this.cache.get(e);if(!i)return!1;const n=Date.now();if(n>i.expireAt)return this.cache.delete(e),!1;const r=t??this.config.defaultTTL;return i.expireAt=n+r,i.lastAccessed=n,!0}async getOrSet(e,t,i){const n=this.get(e);if(void 0!==n)return n;const r=await t();return this.set(e,r,i),r}mset(e,t){for(const[i,n]of e)this.set(i,n,t)}mget(e){return e.map(e=>this.get(e))}mdel(e){let t=0;for(const i of e)this.delete(i)&&t++;return t}getStats(){let e=0,t=0;const i=Date.now();for(const[n,r]of this.cache.entries())e+=r.accessCount,i>r.expireAt&&t++;return{size:this.cache.size,maxSize:this.config.maxSize,hitRate:e>0?(e-t)/e:0,totalAccess:e,expiredCount:t}}cleanup(){const e=Date.now();let t=0;for(const[i,n]of this.cache.entries())e>n.expireAt&&(this.cache.delete(i),t++);return t}evictLRU(){if(!this.config.enableLRU||0===this.cache.size)return;let e=null,t=1/0;for(const[i,n]of this.cache.entries())n.lastAccessed<t&&(t=n.lastAccessed,e=i);e&&this.cache.delete(e)}startCleanup(){this.cleanupTimer&&clearInterval(this.cleanupTimer),this.cleanupTimer=setInterval(()=>{this.cleanup()},this.config.cleanupInterval)}stopCleanup(){this.cleanupTimer&&(clearInterval(this.cleanupTimer),this.cleanupTimer=void 0)}updateConfig(e){if(this.config={...this.config,...e},void 0!==e.cleanupInterval&&this.startCleanup(),void 0!==e.maxSize&&this.cache.size>e.maxSize)for(;this.cache.size>e.maxSize;)this.evictLRU()}destroy(){this.stopCleanup(),this.clear()}}class BaseManager{constructor(e,t="BaseManager"){this.initialized=!1,this.destroyed=!1,this.initializing=!1,this.options=this.mergeDefaultOptions(e),this.logger=new Logger(t,{level:this.options.debug?0:1,enableConsole:this.options.debug}),this.eventEmitter=new EventEmitter,this.errorHandler=new ErrorHandler(this.logger),this.options.cache&&(this.cache=new Cache),this.setupErrorHandling(),this.startAutoInitialization()}on(e,t,i){return this.eventEmitter.on(e,t,i),this}off(e,t){return this.eventEmitter.off(e,t),this}emit(e,...t){return this.eventEmitter.emit(e,...t)}once(e,t,i){return this.eventEmitter.once(e,t,i),this}listenerCount(e){return this.eventEmitter.listenerCount(e)}eventNames(){return this.eventEmitter.eventNames()}handleError(e,t){const i={module:this.constructor.name,method:t},n=this.errorHandler.handleError(e,i);return this.emit("error",n),n}validateInput(e,t){try{if(t.type){const i=typeof e;if(i!==t.type)throw this.errorHandler.createError("USER_ERROR",`Expected ${t.type}, got ${i}`,{context:{method:"validateInput"}})}if(t.required&&null==e)throw this.errorHandler.createError("USER_ERROR","Required parameter is missing",{context:{method:"validateInput"}});if(t.isArray&&!Array.isArray(e))throw this.errorHandler.createError("USER_ERROR","Expected array",{context:{method:"validateInput"}});if(t.properties&&"object"==typeof e&&null!==e)for(const[i,n]of Object.entries(t.properties))if(!this.validateInput(e[i],n))return!1;return!0}catch(e){return this.handleError(e,"validateInput"),!1}}async safeExecute(e,t,i){const n=i??this.options.retries??0;let r=null;for(let i=0;i<=n;i++)try{const n=new Promise((e,i)=>{setTimeout(()=>{i(this.errorHandler.createError("TIMEOUT_ERROR",`Operation timed out after ${this.options.timeout}ms`,{context:{method:t}}))},this.options.timeout)}),r=await Promise.race([e(),n]);return i>0&&this.logger.info(`Operation succeeded after ${i} retries`,{context:t}),r}catch(e){if(r=e,i===n||!this.errorHandler.isRecoverableError(r))throw this.handleError(r,t);const o=Math.min(1e3*Math.pow(2,i),5e3);this.logger.warn(`Operation failed, retrying in ${o}ms (attempt ${i+1}/${n+1})`,{context:t,error:r.message}),await new Promise(e=>setTimeout(e,o))}throw this.handleError(r,t)}getCached(e){return this.cache?.get(e)}setCached(e,t,i){this.cache?.set(e,t,i)}async getOrSetCached(e,t,i){return this.cache?this.cache.getOrSet(e,t,i):t()}async ensureInitialized(){if(this.destroyed)throw this.errorHandler.createError("SYSTEM_ERROR","Manager has been destroyed and cannot be used.",{context:{method:"ensureInitialized"}});if(!this.initialized)if(this.initPromise)try{await this.initPromise,this.initPromise=void 0}catch(e){throw this.errorHandler.createError("SYSTEM_ERROR",`Manager initialization failed: ${e.message}`,{context:{method:"ensureInitialized"}})}else if(!this.initializing){this.initializing=!0;try{await this.initialize()}finally{this.initializing=!1}}}ensureInitializedSync(){if(!this.initialized)throw this.errorHandler.createError("SYSTEM_ERROR","Manager not initialized. Operations requiring initialization should be awaited.",{context:{method:"ensureInitializedSync"}})}ensureNotDestroyed(){if(this.destroyed)throw this.errorHandler.createError("SYSTEM_ERROR","Manager has been destroyed and cannot be used.",{context:{method:"ensureNotDestroyed"}})}async ready(){await this.ensureInitialized()}getStatus(){return{initialized:this.initialized,destroyed:this.destroyed,eventListeners:this.eventNames().reduce((e,t)=>e+this.listenerCount(t),0),cacheSize:this.cache?.size(),initializing:this.initializing||!!this.initPromise}}updateOptions(e){this.options={...this.options,...e},void 0!==e.debug&&(this.logger.setLevel(e.debug?0:1),this.logger.setConsoleOutput(e.debug)),this.emit("optionsUpdated",this.options)}mergeDefaultOptions(e){return{...this.getDefaultOptions(),...e}}setupErrorHandling(){"undefined"!=typeof window?window.addEventListener("unhandledrejection",e=>{this.handleError(new Error(e.reason),"unhandledrejection")}):"undefined"!=typeof process&&process.on("unhandledRejection",e=>{this.handleError(new Error(String(e)),"unhandledRejection")})}startAutoInitialization(){this.initPromise=this.initialize().catch(e=>(this.logger.error("Auto-initialization failed:",e),Promise.reject(e))),this.initPromise.catch(()=>{})}baseDestroy(){this.destroyed||(this.emit("beforeDestroy"),this.eventEmitter.removeAllListeners(),this.cache?.destroy(),this.logger.clear(),this.destroyed=!0,this.initialized=!1,this.emit("destroyed"))}}class se extends BaseManager{constructor(e={}){super(e,"DeviceDetector"),this._deviceInfo=null,this._detectionOptions={ua:e.ua,tablet:e.tablet,featureDetect:e.featureDetect}}getDefaultOptions(){return{debug:!1,timeout:5e3,retries:2,cache:!0,cacheTTL:3e5,ua:"",tablet:!1,featureDetect:!0,enablePerformanceMonitoring:!1}}async initialize(){if(!this.initialized)try{this.logger.info("Initializing DeviceDetector"),await this.safeExecute(async()=>{this._detectDevice()},"initialize"),this.initialized=!0,this.emit("initialized"),this.logger.info("DeviceDetector initialized successfully")}catch(e){throw this.handleError(e,"initialize"),e}}destroy(){this.destroyed||(this.logger.info("Destroying DeviceDetector"),this._deviceInfo=null,this.baseDestroy(),this.logger.info("DeviceDetector destroyed"))}async getDeviceInfo(){await this.ensureInitialized(),this.ensureNotDestroyed();const e="device_info";if(this.options.cache){const t=this.getCached(e);if(t)return this.logger.debug("Device info retrieved from cache"),t}return this.safeExecute(async()=>{const t=this._detectDevice();return this.options.cache&&this.setCached(e,t,this.options.cacheTTL),this.emit("deviceInfoDetected",t),t},"getDeviceInfo")}async refresh(){await this.ensureInitialized(),this.ensureNotDestroyed(),this.logger.debug("Refreshing device info"),this._deviceInfo=null,this.cache&&this.cache.delete("device_info");const e=await this.getDeviceInfo();return this.emit("deviceInfoRefreshed",e),e}_detectDevice(){const e=Date.now();try{const t=this._getUserAgent(),i=S(),n={type:f(this._detectionOptions),os:g(t),browser:R(t),isMobile:l(this._detectionOptions),isTablet:d(this._detectionOptions),isDesktop:h(this._detectionOptions),isTouchDevice:m(),userAgent:t,screen:i};if(this.options.enablePerformanceMonitoring){const t=Date.now()-e;this.logger.debug(`Device detection completed in ${t}ms`),this.emit("performanceMetric",{operation:"detection",time:t})}return n}catch(e){throw this.handleError(e,"_detectDevice")}}_getUserAgent(){if(this._detectionOptions.ua){if("string"==typeof this._detectionOptions.ua)return this._detectionOptions.ua.length>0?this._detectionOptions.ua:"undefined"!=typeof navigator?navigator.userAgent:"";if(this._detectionOptions.ua.headers&&this._detectionOptions.ua.headers["user-agent"])return this._detectionOptions.ua.headers["user-agent"]}return"undefined"!=typeof navigator?navigator.userAgent:""}setDetectionOptions(e){return this.ensureNotDestroyed(),this._detectionOptions={...this._detectionOptions,...e},this._deviceInfo=null,this.cache&&this.cache.delete("device_info"),this.emit("detectionOptionsUpdated",this._detectionOptions),this.logger.debug("Detection options updated",this._detectionOptions),this}getDetectionOptions(){return{...this._detectionOptions}}async checkDeviceType(e){const t=await this.getDeviceInfo();switch(e){case"mobile":return t.isMobile&&!t.isTablet;case"tablet":return t.isTablet;case"desktop":return t.isDesktop;default:throw this.errorHandler.createError("USER_ERROR",`Invalid device type: ${e}`,{context:{method:"checkDeviceType"}})}}async checkOS(e){return(await this.getDeviceInfo()).os.toLowerCase()===e.toLowerCase()}async checkBrowser(e){return(await this.getDeviceInfo()).browser.toLowerCase()===e.toLowerCase()}async getDeviceCapabilities(){const e=await this.getDeviceInfo();return{touchSupport:e.isTouchDevice,screenSize:e.screen,userAgent:e.userAgent,online:"undefined"==typeof navigator||navigator.onLine}}}async function ae(e){const t=new se(e);return await t.initialize(),t.getDeviceInfo()}function ce(e){const t="string"==typeof e?.ua?e.ua:"undefined"!=typeof navigator?navigator.userAgent:"",i=S();return{type:f(e),os:g(t),browser:R(t),isMobile:l(e),isTablet:d(e),isDesktop:h(e),isTouchDevice:m(),userAgent:t,screen:i}}function ue(e){return new se(e)}function le(e,t){switch(e){case"mobile":return l(t)&&!d(t);case"tablet":return d(t);case"desktop":return h(t);default:return!1}}var de={DeviceDetector:se,getDeviceInfo:ae,getDeviceInfoSync:ce,createDeviceDetector:ue,isDeviceType:le};export{i as BrowserType,se as DeviceDetector,e as DeviceType,r as NetworkType,t as OSType,n as ScreenOrientation,v as clearDetectionCache,ue as createDeviceDetector,de as default,R as detectBrowser,g as detectOS,y as enhancedMobileDetection,N as getActualViewportSize,W as getBatteryInfo,O as getCacheStats,ee as getCompatibilityReport,T as getDetailedScreenInfo,j as getDeviceCapabilities,ae as getDeviceInfo,ce as getDeviceInfoSync,$ as getDevicePerformanceInfo,J as getDeviceThermalState,f as getDeviceType,K as getGPUInfo,k as getMemoryInfo,C as getNetworkSpeed,L as getNetworkType,Z as getPerformanceOptimizationSuggestions,x as getScreenOrientation,S as getScreenSize,_ as getScreenSizeCategory,D as getViewportSize,w as isDarkMode,h as isDesktop,le as isDeviceType,Y as isEnhancedTouchDevice,Q as isLowPerformanceMode,l as isMobile,U as isOnline,p as isRetinaDisplay,d as isTablet,m as isTouchDevice,V as monitorDevicePerformance,z as onNetworkChange,M as onOrientationChange,X as runPerformanceBenchmark,A as supportsAVIF,q as supportsFeature,P as supportsServiceWorker,H as supportsWebAssembly,F as supportsWebGL,G as supportsWebGL2,E as supportsWebP,B as supportsWebWorkers};