UNPKG

js-use-core

Version:

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

1 lines 52.7 kB
function e(e){if(!e)return null;if((t=e)&&"object"==typeof t&&t.nodeType===Node.ELEMENT_NODE)return e;var t;if("string"==typeof e)try{return document.querySelector(e)}catch(e){return null}return null}class EventEmitter{constructor(){this.events=new Map,this.maxListeners=10}on(e,t,r){if("function"!=typeof t)throw new Error("Listener must be a function");const i={listener:t,once:r?.once||!1,priority:r?.priority||0};this.events.has(e)||this.events.set(e,[]);const a=this.events.get(e);a.length,this.maxListeners;let s=!1;for(let e=0;e<a.length;e++)if(i.priority>(a[e].priority||0)){a.splice(e,0,i),s=!0;break}return s||a.push(i),this}once(e,t,r){return this.on(e,t,{once:!0,priority:r})}off(e,t){if(!this.events.has(e))return this;const r=this.events.get(e);if(t){const i=r.findIndex(e=>e.listener===t);-1!==i&&(r.splice(i,1),0===r.length&&this.events.delete(e))}else this.events.delete(e);return this}emit(e,...t){if(!this.events.has(e))return!1;const r=this.events.get(e).slice(),i=[];for(const e of r)try{e.listener.apply(this,t),e.once&&i.push(e)}catch(e){}if(i.length>0){const t=this.events.get(e);if(t){for(const e of i){const r=t.indexOf(e);-1!==r&&t.splice(r,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 t,r,i,a,s,n;!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"}(t||(t={})),function(e){e.LOW="low",e.MEDIUM="medium",e.HIGH="high",e.CRITICAL="critical"}(r||(r={})),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"}(i||(i={})),function(e){e[e.DEBUG=0]="DEBUG",e[e.INFO=1]="INFO",e[e.WARN=2]="WARN",e[e.ERROR=3]="ERROR"}(a||(a={}));class Logger{constructor(e="Core",t){this.level=a.INFO,this.logs=[],this.maxLogs=1e3,this.enableConsole=!0,this.module=e,t&&(this.level=t.level??a.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(a.DEBUG,e,t)}info(e,t){this.log(a.INFO,e,t)}warn(e,t){this.log(a.WARN,e,t)}error(e,t){this.log(a.ERROR,e,t)}log(e,t,r){if(e<this.level)return;const i={level:e,message:t,timestamp:Date.now(),module:this.module,data:r};this.logs.push(i),this.logs.length>this.maxLogs&&this.logs.shift(),this.enableConsole&&this.outputToConsole(i)}outputToConsole(e){new Date(e.timestamp).toISOString(),a[e.level],e.module,e.message,void 0!==e.data&&e.data;switch(e.level){case a.DEBUG:case a.INFO:case a.WARN:case a.ERROR:}}getLogs(){return[...this.logs]}getLogsByLevel(e){return this.logs.filter(t=>t.level===e)}getLogsByTimeRange(e,t){return this.logs.filter(r=>r.timestamp>=e&&r.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 o extends Error{constructor(e,t,r){super(t),this.name="CustomError",this.type=e,this.code=r?.code,this.context=r?.context,this.recoverable=r?.recoverable??!1,r?.cause&&(this.cause=r.cause),Error.captureStackTrace&&Error.captureStackTrace(this,o)}}class ErrorHandler{constructor(e){this.errorSolutions=new Map,this.logger=e||new Logger("ErrorHandler"),this.initializeErrorSolutions()}handleError(e,t){const r=this.classifyError(e),i={module:"Unknown",method:"Unknown",timestamp:Date.now(),userAgent:"undefined"!=typeof navigator?navigator.userAgent:"Node.js",...t},a={type:r,severity:this.getErrorSeverity(r),message:e.message,userMessage:this.getUserFriendlyMessage(e,r),originalError:e,context:i,code:this.getErrorCode(e)||this.generateErrorCode(r),recoverable:this.isRecoverableError(e),solutions:this.getErrorSolutions(e),id:this.generateErrorId(),processedAt:Date.now(),relatedErrors:[]};return this.logger.error(`[${r}] ${a.message}`,{error:e.message,stack:e.stack,context:i,recoverable:a.recoverable}),a}createError(e,t,r){const i={module:"Unknown",method:"Unknown",timestamp:Date.now(),userAgent:"undefined"!=typeof navigator?navigator.userAgent:"Node.js",...r?.context};return new o(e,t,{code:r?.code,context:i,recoverable:r?.recoverable,cause:r?.cause})}isRecoverableError(e){if(e instanceof o)return e.recoverable;switch(this.classifyError(e)){case t.NETWORK_ERROR:case t.TIMEOUT_ERROR:return!0;case t.PERMISSION_ERROR:case t.SYSTEM_ERROR:return!1;case t.USER_ERROR:case t.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 r=this.classifyError(e);return this.getDefaultSolution(r)}getErrorSolutions(e){const t=this.getErrorSolution(e);return t?[{description:t,steps:[t],automatic:!1,priority:1}]:[]}getErrorSeverity(e){switch(e){case t.USER_ERROR:case t.CONFIG_ERROR:return r.LOW;case t.NETWORK_ERROR:case t.TIMEOUT_ERROR:return r.MEDIUM;case t.PERMISSION_ERROR:case t.VALIDATION_ERROR:return r.HIGH;case t.SYSTEM_ERROR:case t.INTERNAL_ERROR:return r.CRITICAL;default:return r.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,r]of Object.entries(e))this.errorSolutions.set(t,r)}classifyError(e){if(e instanceof o)return e.type;const r=(e.message||"").toLowerCase(),i=(e.name||"").toLowerCase();return r.includes("network")||r.includes("fetch")||r.includes("xhr")||i.includes("networkerror")?t.NETWORK_ERROR:r.includes("timeout")||r.includes("timed out")||i.includes("timeouterror")?t.TIMEOUT_ERROR:r.includes("permission")||r.includes("denied")||r.includes("unauthorized")||r.includes("forbidden")||i.includes("notallowederror")?t.PERMISSION_ERROR:r.includes("not supported")||r.includes("not available")||r.includes("not implemented")||i.includes("notsupportederror")?t.SYSTEM_ERROR:r.includes("invalid")||r.includes("configuration")||r.includes("config")||i.includes("configerror")?t.CONFIG_ERROR:e instanceof TypeError||e instanceof RangeError||r.includes("invalid argument")||r.includes("invalid parameter")?t.USER_ERROR:t.UNKNOWN_ERROR}getUserFriendlyMessage(e,r){switch(r){case t.NETWORK_ERROR:return"网络连接失败,请检查网络连接后重试";case t.TIMEOUT_ERROR:return"操作超时,请稍后重试";case t.PERMISSION_ERROR:return"权限不足,请检查浏览器权限设置";case t.SYSTEM_ERROR:return"当前浏览器不支持此功能,请使用其他浏览器或升级浏览器版本";case t.CONFIG_ERROR:return"配置参数错误,请检查配置";case t.USER_ERROR:return"输入参数错误,请检查输入参数";default:return e.message||"发生未知错误"}}getErrorCode(e){if(e instanceof o)return e.code;const t=e;return t.code||t.errno||void 0}getDefaultSolution(e){switch(e){case t.NETWORK_ERROR:return"请检查网络连接,确保网络正常后重试";case t.TIMEOUT_ERROR:return"请稍后重试,或增加超时时间设置";case t.PERMISSION_ERROR:return"请在浏览器设置中允许相关权限,或使用HTTPS协议";case t.SYSTEM_ERROR:return"请使用支持此功能的现代浏览器,或升级浏览器版本";case t.CONFIG_ERROR:return"请检查配置参数是否正确,参考文档进行配置";case t.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,r){const i=Date.now(),a={value:t,expireAt:i+(r??this.config.defaultTTL),createdAt:i,accessCount:0,lastAccessed:i};this.cache.size>=this.config.maxSize&&!this.cache.has(e)&&this.evictLRU(),this.cache.set(e,a)}get(e){const t=this.cache.get(e);if(!t)return;const r=Date.now();if(!(r>t.expireAt))return t.accessCount++,t.lastAccessed=r,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 r=this.cache.get(e);if(!r)return!1;const i=Date.now();if(i>r.expireAt)return this.cache.delete(e),!1;const a=t??this.config.defaultTTL;return r.expireAt=i+a,r.lastAccessed=i,!0}async getOrSet(e,t,r){const i=this.get(e);if(void 0!==i)return i;const a=await t();return this.set(e,a,r),a}mset(e,t){for(const[r,i]of e)this.set(r,i,t)}mget(e){return e.map(e=>this.get(e))}mdel(e){let t=0;for(const r of e)this.delete(r)&&t++;return t}getStats(){let e=0,t=0;const r=Date.now();for(const[i,a]of this.cache.entries())e+=a.accessCount,r>a.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[r,i]of this.cache.entries())e>i.expireAt&&(this.cache.delete(r),t++);return t}evictLRU(){if(!this.config.enableLRU||0===this.cache.size)return;let e=null,t=1/0;for(const[r,i]of this.cache.entries())i.lastAccessed<t&&(t=i.lastAccessed,e=r);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.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()}on(e,t,r){return this.eventEmitter.on(e,t,r),this}off(e,t){return this.eventEmitter.off(e,t),this}emit(e,...t){return this.eventEmitter.emit(e,...t)}once(e,t,r){return this.eventEmitter.once(e,t,r),this}listenerCount(e){return this.eventEmitter.listenerCount(e)}eventNames(){return this.eventEmitter.eventNames()}handleError(e,t){const r={module:this.constructor.name,method:t},i=this.errorHandler.handleError(e,r);return this.emit("error",i),i}validateInput(e,t){try{if(t.type){const r=typeof e;if(r!==t.type)throw this.errorHandler.createError("USER_ERROR",`Expected ${t.type}, got ${r}`,{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[r,i]of Object.entries(t.properties))if(!this.validateInput(e[r],i))return!1;return!0}catch(e){return this.handleError(e,"validateInput"),!1}}async safeExecute(e,t,r){const i=r??this.options.retries??0;let a=null;for(let r=0;r<=i;r++)try{const i=new Promise((e,r)=>{setTimeout(()=>{r(this.errorHandler.createError("TIMEOUT_ERROR",`Operation timed out after ${this.options.timeout}ms`,{context:{method:t}}))},this.options.timeout)}),a=await Promise.race([e(),i]);return r>0&&this.logger.info(`Operation succeeded after ${r} retries`,{context:t}),a}catch(e){if(a=e,r===i||!this.errorHandler.isRecoverableError(a))throw this.handleError(a,t);const s=Math.min(1e3*Math.pow(2,r),5e3);this.logger.warn(`Operation failed, retrying in ${s}ms (attempt ${r+1}/${i+1})`,{context:t,error:a.message}),await new Promise(e=>setTimeout(e,s))}throw this.handleError(a,t)}getCached(e){return this.cache?.get(e)}setCached(e,t,r){this.cache?.set(e,t,r)}async getOrSetCached(e,t,r){return this.cache?this.cache.getOrSet(e,t,r):t()}ensureInitialized(){if(!this.initialized)throw this.errorHandler.createError("SYSTEM_ERROR","Manager not initialized. Call initialize() first.",{context:{method:"ensureInitialized"}})}ensureNotDestroyed(){if(this.destroyed)throw this.errorHandler.createError("SYSTEM_ERROR","Manager has been destroyed and cannot be used.",{context:{method:"ensureNotDestroyed"}})}getStatus(){return{initialized:this.initialized,destroyed:this.destroyed,eventListeners:this.eventNames().reduce((e,t)=>e+this.listenerCount(t),0),cacheSize:this.cache?.size()}}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")})}baseDestroy(){this.destroyed||(this.emit("beforeDestroy"),this.eventEmitter.removeAllListeners(),this.cache?.destroy(),this.logger.clear(),this.destroyed=!0,this.initialized=!1,this.emit("destroyed"))}}!function(e){e.GRANTED="granted",e.DENIED="denied",e.PROMPT="prompt",e.UNKNOWN="unknown"}(s||(s={})),function(e){e.MODERN_API="modern",e.EXEC_COMMAND="execCommand",e.SELECTION_API="selection",e.INPUT_ELEMENT="input",e.TEXTAREA_ELEMENT="textarea"}(n||(n={}));class l extends BaseManager{constructor(e){super(e,"ClipboardManager"),this.dataConverters=new Map,this.permissionCache=new Map,this.eventListeners=new Map,this.initializeDataConverters()}getDefaultOptions(){return{debug:!1,timeout:5e3,retries:2,cache:!0,cacheTTL:3e4,defaultFormat:"text",enablePermissionCheck:!0,maxDataSize:10485760,enableDataValidation:!0,enableFallback:!0,permissionTimeout:3e3,enableHtmlSanitization:!0,supportedMimeTypes:["text/plain","text/html","text/rtf","image/png","image/jpeg","image/gif","image/webp"],autoRequestPermissions:!0,fallbackStrategies:["modern","execCommand","selection","input"],enableDataConversion:!0,maxFileCount:10,allowedFileTypes:["image/*","text/*",".pdf",".doc",".docx"]}}async initialize(){if(this.ensureNotDestroyed(),!this.initialized)try{this.logger.info("Initializing ClipboardManager"),await this.checkBrowserSupport(),this.options.enablePermissionCheck&&await this.checkPermissions(),this.setupEventListeners(),this.initializeValidationRules(),this.initialized=!0,this.emit("initialized"),this.logger.info("ClipboardManager initialized successfully")}catch(e){throw this.handleError(e,"initialize")}}destroy(){this.destroyed||(this.logger.info("Destroying ClipboardManager"),this.removeEventListeners(),this.permissionCache.clear(),this.dataConverters.clear(),this.eventListeners.clear(),this.baseDestroy(),this.logger.info("ClipboardManager destroyed"))}get isSupported(){return"undefined"!=typeof navigator&&"clipboard"in navigator&&"writeText"in navigator.clipboard}get canRead(){return"undefined"!=typeof navigator&&"clipboard"in navigator&&"readText"in navigator.clipboard}get canWrite(){return this.isSupported}async copyText(e,r={}){return this.ensureInitialized(),this.ensureNotDestroyed(),this.safeExecute(async()=>{if(!this.validateInput(e,{type:"string",required:!0}))throw this.errorHandler.createError(t.USER_ERROR,"Invalid text input for clipboard copy",{context:{method:"copyText"}});let i=e;this.options.enableDataValidation&&this.validateClipboardData(e,"text"),r.format&&"text"!==r.format&&(i=await this.convertData(e,"text",r.format,{enableCaching:this.options.cache,enableChunking:!0,maxProcessingTime:this.options.timeout}));const a=`copy_text_${this.hashString(i)}`,s=this.getCached(a);if(void 0!==s)return this.logger.debug("Using cached copy result"),s;let n=!1,o=null;try{if(this.options.enablePermissionCheck&&(o=await this.requestPermissionSmart("write"),!o.granted&&!o.fallbackAvailable))throw o.error||this.errorHandler.createError(t.PERMISSION_ERROR,"Clipboard write permission denied and no fallback available",{context:{method:"copyText"}});if(!this.canWrite||o&&!o.granted){if(!1===r.fallback||!this.options.enableFallback)throw this.errorHandler.createError(t.SYSTEM_ERROR,"Clipboard API not supported and fallback disabled",{context:{method:"copyText"}});n=await this.fallbackCopyText(i),this.logger.debug("Text copied using fallback method")}else await navigator.clipboard.writeText(i),n=!0,this.logger.debug("Text copied using modern API")}catch(e){if(!1===r.fallback||!this.options.enableFallback)throw e;try{n=await this.fallbackCopyText(i),this.logger.warn("Fallback to alternative method after API failure")}catch(t){throw e}}return this.setCached(a,n,5e3),n&&this.emit("copy",{type:"text",data:i,size:i.length,timestamp:Date.now(),mimeType:r.mimeType||"text/plain",encoding:r.encoding||"utf-8"}),n},"copyText")}async copyHTML(e,r={}){return this.ensureInitialized(),this.ensureNotDestroyed(),this.safeExecute(async()=>{if(!this.validateInput(e,{type:"string",required:!0}))throw this.errorHandler.createError(t.USER_ERROR,"Invalid HTML input for clipboard copy",{context:{method:"copyHTML"}});let i=e;this.options.enableDataValidation&&this.validateClipboardData(e,"html"),!1!==r.sanitizeHtml&&this.options.enableHtmlSanitization&&(i=this.sanitizeHtml(e)),r.format&&"html"!==r.format&&(i=await this.convertData(i,"html",r.format,{enableCaching:this.options.cache,enableChunking:!0,maxProcessingTime:this.options.timeout}));const a=`copy_html_${this.hashString(i)}`,s=this.getCached(a);if(void 0!==s)return this.logger.debug("Using cached HTML copy result"),s;let n=!1,o=null;try{if(this.options.enablePermissionCheck&&(o=await this.requestPermissionSmart("write"),!o.granted&&!o.fallbackAvailable))throw o.error||this.errorHandler.createError(t.PERMISSION_ERROR,"Clipboard write permission denied and no fallback available",{context:{method:"copyHTML"}});if(this.canWrite&&"write"in navigator.clipboard&&"undefined"!=typeof ClipboardItem&&(!o||o.granted)){const e=r.mimeType||"text/html",t=new Blob([i],{type:e}),a=[new ClipboardItem({[e]:t})];await navigator.clipboard.write(a),n=!0,this.logger.debug("HTML copied using modern API")}else{if(!1===r.fallback||!this.options.enableFallback)throw this.errorHandler.createError(t.SYSTEM_ERROR,"Clipboard HTML API not supported and fallback disabled",{context:{method:"copyHTML"}});n=await this.fallbackCopyHTML(i),this.logger.debug("HTML copied using fallback method")}}catch(e){if(!1===r.fallback||!this.options.enableFallback)throw e;try{n=await this.fallbackCopyHTML(i),this.logger.warn("Fallback to alternative method after HTML API failure")}catch(t){throw e}}return this.setCached(a,n,5e3),n&&this.emit("copy",{type:"html",data:i,size:i.length,timestamp:Date.now(),mimeType:r.mimeType||"text/html",encoding:r.encoding||"utf-8"}),n},"copyHTML")}async copyElement(r,i={}){return this.ensureInitialized(),this.ensureNotDestroyed(),this.safeExecute(async()=>{const a=e(r);if(!a)throw this.errorHandler.createError(t.USER_ERROR,"Invalid element provided for clipboard copy",{context:{method:"copyElement",input:r}});const{format:s=this.options.defaultFormat,fallback:n=this.options.enableFallback}=i;try{return"html"===s?await this.copyHTML(a.innerHTML,i):await this.copyText(a.textContent||"",i)}catch(e){if(n)return this.logger.warn("Attempting fallback element copy method"),await this.fallbackCopyElement(a,s);throw e}},"copyElement")}async readText(e={}){return this.ensureInitialized(),this.ensureNotDestroyed(),this.safeExecute(async()=>{if(!this.canRead)throw this.errorHandler.createError(t.SYSTEM_ERROR,"Clipboard reading not supported in this browser",{context:{method:"readText"}});let r=null;if(this.options.enablePermissionCheck&&(r=await this.requestPermissionSmart("read"),!r.granted))throw r.error||this.errorHandler.createError(t.PERMISSION_ERROR,"Clipboard read permission denied",{context:{method:"readText",extra:{permission:r.state}}});const i=await navigator.clipboard.readText();if(this.options.enableDataValidation&&this.validateClipboardData(i,"text"),e.maxSize&&i.length>e.maxSize)throw this.errorHandler.createError(t.USER_ERROR,`Clipboard text exceeds maximum size limit (${e.maxSize} characters)`,{context:{method:"readText",extra:{size:i.length,maxSize:e.maxSize}}});let a=i;return e.format&&"text"!==e.format&&(a=await this.convertData(i,"text",e.format,{enableCaching:this.options.cache,enableChunking:!0,maxProcessingTime:this.options.timeout})),"html"===e.format&&!1!==e.sanitizeHtml&&this.options.enableHtmlSanitization&&(a=this.sanitizeHtml(a)),this.logger.debug(`Read ${i.length} characters from clipboard`),this.emit("read",{type:"text",data:a,size:a.length,timestamp:Date.now(),mimeType:"text/plain",encoding:"utf-8"}),a},"readText")}async readHTML(e={}){return this.ensureInitialized(),this.ensureNotDestroyed(),this.safeExecute(async()=>{if(!this.canRead||!("read"in navigator.clipboard))throw this.errorHandler.createError(t.SYSTEM_ERROR,"Clipboard HTML reading not supported in this browser",{context:{method:"readHTML"}});if(this.options.enablePermissionCheck){const e=await this.checkReadPermission();if(e!==s.GRANTED)throw this.errorHandler.createError(t.PERMISSION_ERROR,"Clipboard read permission denied",{context:{method:"readHTML",extra:{permission:e}}})}const r=await navigator.clipboard.read();for(const i of r)if(i.types.includes("text/html")){const r=await i.getType("text/html"),a=await r.text();if(this.options.enableDataValidation&&this.validateClipboardData(a,"html"),e.maxSize&&a.length>e.maxSize)throw this.errorHandler.createError(t.USER_ERROR,`Clipboard HTML exceeds maximum size limit (${e.maxSize} characters)`,{context:{method:"readHTML",extra:{size:a.length,maxSize:e.maxSize}}});return this.logger.debug(`Read ${a.length} characters of HTML from clipboard`),this.emit("read",{type:"html",data:a,timestamp:Date.now()}),a}throw this.errorHandler.createError(t.USER_ERROR,"No HTML content found in clipboard",{context:{method:"readHTML"}})},"readHTML")}async copyFiles(e,r={}){return this.ensureInitialized(),this.ensureNotDestroyed(),this.safeExecute(async()=>{if(!Array.isArray(e)||0===e.length)throw this.errorHandler.createError(t.USER_ERROR,"Invalid files input for clipboard copy",{context:{method:"copyFiles"}});this.options.enableDataValidation&&this.validateClipboardData(e,"files");let r=null;if(this.options.enablePermissionCheck&&(r=await this.requestPermissionSmart("write"),!r.granted&&!r.fallbackAvailable))throw r.error||this.errorHandler.createError(t.PERMISSION_ERROR,"Clipboard write permission denied and no fallback available",{context:{method:"copyFiles"}});try{if(this.canWrite&&"write"in navigator.clipboard&&"undefined"!=typeof ClipboardItem){const t=[];for(const r of e)this.options.supportedMimeTypes.includes(r.type)||this.options.supportedMimeTypes.some(e=>e.includes("*")&&r.type.startsWith(e.split("/")[0]))?t.push(new ClipboardItem({[r.type]:r})):this.logger.warn(`File type ${r.type} not supported, skipping file: ${r.name}`);if(t.length>0)return await navigator.clipboard.write(t),this.logger.debug(`${t.length} files copied using modern API`),this.emit("copy",{type:"files",data:e,size:e.reduce((e,t)=>e+t.size,0),timestamp:Date.now()}),!0}throw this.errorHandler.createError(t.SYSTEM_ERROR,"File clipboard copying not supported in this browser",{context:{method:"copyFiles"}})}catch(e){throw this.logger.error("File copy failed:",e),e}},"copyFiles")}async readFiles(e={}){return this.ensureInitialized(),this.ensureNotDestroyed(),this.safeExecute(async()=>{if(!this.canRead||!("read"in navigator.clipboard))throw this.errorHandler.createError(t.SYSTEM_ERROR,"Clipboard file reading not supported in this browser",{context:{method:"readFiles"}});let r=null;if(this.options.enablePermissionCheck&&(r=await this.requestPermissionSmart("read"),!r.granted))throw r.error||this.errorHandler.createError(t.PERMISSION_ERROR,"Clipboard read permission denied",{context:{method:"readFiles",extra:{permission:r.state}}});const i=await navigator.clipboard.read(),a=[];for(const t of i)for(const r of t.types)if((!e.acceptedTypes||e.acceptedTypes.includes(r))&&this.isFileTypeAllowed(r))try{const e=await t.getType(r),i=new File([e],`clipboard-file.${this.getFileExtension(r)}`,{type:r});a.push(i)}catch(e){this.logger.warn(`Failed to read file of type ${r}:`,e)}return this.options.enableDataValidation&&a.length>0&&this.validateClipboardData(a,"files"),this.logger.debug(`Read ${a.length} files from clipboard`),a.length>0&&this.emit("read",{type:"files",data:a,size:a.reduce((e,t)=>e+t.size,0),timestamp:Date.now()}),a},"readFiles")}async read(e={}){return this.ensureInitialized(),this.ensureNotDestroyed(),this.safeExecute(async()=>{const{format:t=this.options.defaultFormat,fallback:r=this.options.enableFallback}=e;try{switch(t){case"html":const t=await this.readHTML(e);return{type:"html",data:t,size:t.length,timestamp:Date.now(),mimeType:"text/html",encoding:"utf-8"};case"files":const r=await this.readFiles(e);return{type:"files",data:r,size:r.reduce((e,t)=>e+t.size,0),timestamp:Date.now()};default:const i=await this.readText(e);return{type:"text",data:i,size:i.length,timestamp:Date.now(),mimeType:"text/plain",encoding:"utf-8"}}}catch(e){if(r)return this.logger.warn("Attempting fallback read method"),await this.fallbackRead(t);throw e}},"read")}getFileExtension(e){return{"text/plain":"txt","text/html":"html","text/css":"css","text/javascript":"js","application/json":"json","image/png":"png","image/jpeg":"jpg","image/gif":"gif","image/webp":"webp","image/svg+xml":"svg","application/pdf":"pdf","application/msword":"doc","application/vnd.openxmlformats-officedocument.wordprocessingml.document":"docx"}[e]||"bin"}async checkBrowserSupport(){if("undefined"==typeof navigator)throw this.errorHandler.createError(t.SYSTEM_ERROR,"Navigator not available - running in non-browser environment",{context:{method:"checkBrowserSupport"}});const e={clipboard:"clipboard"in navigator,writeText:this.canWrite,readText:this.canRead,write:this.canWrite&&"write"in navigator.clipboard,read:this.canRead&&"read"in navigator.clipboard,execCommand:"undefined"!=typeof document&&"execCommand"in document};if(this.logger.debug("Browser clipboard support:",e),!e.clipboard&&!e.execCommand)throw this.errorHandler.createError(t.SYSTEM_ERROR,"No clipboard support available in this browser",{context:{method:"checkBrowserSupport",extra:{support:e}}})}async checkPermissions(){if("permissions"in navigator)try{const e=await this.checkWritePermission(),t=await this.checkReadPermission();this.logger.debug("Clipboard permissions:",{write:e,read:t})}catch(e){this.logger.warn("Failed to check clipboard permissions:",e)}else this.logger.warn("Permissions API not available")}async checkWritePermission(){if(!("permissions"in navigator))return s.UNKNOWN;try{return(await navigator.permissions.query({name:"clipboard-write"})).state}catch(e){return this.logger.warn("Failed to check clipboard write permission:",e),s.UNKNOWN}}async checkReadPermission(){if(!("permissions"in navigator))return s.UNKNOWN;try{return(await navigator.permissions.query({name:"clipboard-read"})).state}catch(e){return this.logger.warn("Failed to check clipboard read permission:",e),s.UNKNOWN}}async requestPermissionSmart(e){const r=`permission_${e}`,i=this.permissionCache.get(r);if(i===s.GRANTED)return{granted:!0,state:i,fallbackAvailable:this.options.enableFallback};const a={granted:!1,state:s.UNKNOWN,fallbackAvailable:this.options.enableFallback};try{const i="read"===e?await this.checkReadPermission():await this.checkWritePermission();if(this.permissionCache.set(r,i),i===s.GRANTED)return a.granted=!0,a.state=i,a;if(i===s.DENIED&&!this.options.autoRequestPermissions)return a.state=i,a.error=this.errorHandler.createError(t.PERMISSION_ERROR,`Clipboard ${e} permission denied and auto-request disabled`,{context:{method:"requestPermissionSmart",extra:{operation:e}},recoverable:this.options.enableFallback}),a;"write"===e?await this.triggerWritePermissionRequest():await this.triggerReadPermissionRequest();const n="read"===e?await this.checkReadPermission():await this.checkWritePermission();this.permissionCache.set(r,n),a.granted=n===s.GRANTED,a.state=n,a.granted||(a.error=this.errorHandler.createError(t.PERMISSION_ERROR,this.getPermissionErrorMessage(e,n),{context:{method:"requestPermissionSmart",extra:{operation:e,state:n}},recoverable:this.options.enableFallback}))}catch(e){const t=this.handleError(e,"requestPermissionSmart");a.error=t.originalError}return a}initializeDataConverters(){this.registerDataConverter(new d),this.registerDataConverter(new h),this.registerDataConverter(new u),this.registerDataConverter(new p),this.registerDataConverter(new m),this.registerDataConverter(new g)}registerDataConverter(e){const t=`${e.fromType}-to-${e.toType}`;this.dataConverters.set(t,e),this.logger.debug(`Registered data converter: ${t}`)}initializeValidationRules(){const e=f.getInstance();e.addValidationRule("text",{name:"textLength",validate:e=>!(e.length>1e6)||"Text data is very large and may impact performance",errorMessage:"Text data size validation failed"}),e.addValidationRule("text",{name:"textEncoding",validate:e=>{try{return encodeURIComponent(e),!0}catch{return"Text contains invalid characters"}},errorMessage:"Text encoding validation failed"}),e.addValidationRule("html",{name:"htmlStructure",validate:e=>{const t=(e.match(/<[^\/][^>]*>/g)||[]).length,r=(e.match(/<\/[^>]*>/g)||[]).length;return!(Math.abs(t-r)>10)||"HTML structure appears to be malformed"},errorMessage:"HTML structure validation failed"}),e.addValidationRule("files",{name:"fileTypes",validate:e=>{const t=[".exe",".bat",".cmd",".scr",".vbs"];for(const r of e)if(t.some(e=>r.name.toLowerCase().endsWith(e)))return`Potentially dangerous file type detected: ${r.name}`;return!0},errorMessage:"File type security validation failed"}),e.addValidationRule("files",{name:"fileSizeDistribution",validate:e=>{const t=e.reduce((e,t)=>e+t.size,0),r=e.filter(e=>e.size>.8*t);return!(r.length>0)||`Large files detected that may impact performance: ${r.map(e=>e.name).join(", ")}`},errorMessage:"File size distribution validation failed"}),this.logger.debug("Default validation rules initialized")}async convertData(e,r,i,a={}){if(r===i)return e;const s=`convert_${r}_${i}_${this.hashString(JSON.stringify(e))}`;if(!1!==a.enableCaching&&this.options.cache){const e=this.getCached(s);if(void 0!==e)return this.logger.debug(`Using cached conversion result for ${r} to ${i}`),e}const n=`${r}-to-${i}`,o=this.dataConverters.get(n);if(!o||!o.canConvert(r,i))return this.logger.warn(`No converter available for ${r} to ${i}`),e;try{const t=Date.now();let n;if(o.supportsBigData&&this.isLargeData(e)){this.logger.debug(`Processing large data conversion: ${r} to ${i}`);const t=f.getInstance();n=(await t.processLargeData(e,async e=>await o.convert(e,r,i),a)).data.join("")}else n=await o.convert(e,r,i);const l=Date.now()-t;return this.logger.debug(`Data conversion completed in ${l}ms`),!1!==a.enableCaching&&this.options.cache&&this.setCached(s,n,a.cacheExpiry||this.options.cacheTTL),n}catch(e){throw this.logger.error(`Data conversion failed (${r} to ${i}):`,e),this.errorHandler.createError(t.INTERNAL_ERROR,`Failed to convert data from ${r} to ${i}: ${e.message}`,{context:{method:"convertData",extra:{from:r,to:i}},cause:e})}}isLargeData(e){const t=102400;return"string"==typeof e?e.length>t:e instanceof Blob?e.size>t:Array.isArray(e)?e.reduce((e,t)=>t instanceof File?e+t.size:"string"==typeof t?e+t.length:e+JSON.stringify(t).length,0)>t:JSON.stringify(e).length>t}validateClipboardData(e,r,i={}){const a=f.getInstance(),s=r||a.detectDataType(e),n=a.validateData(e,s,i);if(this.performBuiltInValidation(e,s,n),!n.valid)throw this.errorHandler.createError(t.VALIDATION_ERROR,`Data validation failed: ${n.errors.join(", ")}`,{context:{method:"validateClipboardData",extra:{type:s,errors:n.errors,warnings:n.warnings}}});return n.warnings.length>0&&this.logger.warn("Data validation warnings:",n.warnings),n}performBuiltInValidation(e,t,r){switch(t){case"text":"string"!=typeof e?(r.valid=!1,r.errors.push("Text data must be a string")):e.length>this.options.maxDataSize?(r.valid=!1,r.errors.push(`Text data exceeds maximum size limit (${this.options.maxDataSize} characters)`)):0===e.length&&r.warnings.push("Empty text data provided");break;case"html":if("string"!=typeof e)r.valid=!1,r.errors.push("HTML data must be a string");else if(e.length>this.options.maxDataSize&&(r.valid=!1,r.errors.push(`HTML data exceeds maximum size limit (${this.options.maxDataSize} characters)`)),this.options.enableHtmlSanitization){const t=[/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,/javascript:/gi,/on\w+\s*=/gi];for(const i of t)if(i.test(e)){r.warnings.push("Potentially dangerous HTML content detected");break}}break;case"files":if(Array.isArray(e)){e.length>this.options.maxFileCount&&(r.valid=!1,r.errors.push(`File count exceeds maximum limit (${this.options.maxFileCount})`));let t=0;for(const i of e)i instanceof File?(t+=i.size,i.size>this.options.maxDataSize&&(r.valid=!1,r.errors.push(`File "${i.name}" exceeds maximum size limit`)),this.isFileTypeAllowed(i.type)||(r.valid=!1,r.errors.push(`File type "${i.type}" is not allowed`))):(r.valid=!1,r.errors.push("Invalid file object in clipboard data"));t>this.options.maxDataSize&&(r.valid=!1,r.errors.push(`Total file size exceeds maximum limit (${this.options.maxDataSize} bytes)`))}else r.valid=!1,r.errors.push("Files data must be an array");break;case"image":e instanceof Blob&&e.type.startsWith("image/")?e.size>this.options.maxDataSize&&(r.valid=!1,r.errors.push(`Image size exceeds maximum limit (${this.options.maxDataSize} bytes)`)):(r.valid=!1,r.errors.push("Image data must be a Blob with image MIME type"));break;case"rtf":"string"!=typeof e?(r.valid=!1,r.errors.push("RTF data must be a string")):e.startsWith("{\\rtf")?e.length>this.options.maxDataSize&&(r.valid=!1,r.errors.push(`RTF data exceeds maximum size limit (${this.options.maxDataSize} characters)`)):(r.valid=!1,r.errors.push("Invalid RTF format"))}}async triggerWritePermissionRequest(){if(this.canWrite)try{await navigator.clipboard.writeText("")}catch(e){this.logger.debug("Write permission request triggered:",e)}}async triggerReadPermissionRequest(){if(this.canRead)try{await navigator.clipboard.readText()}catch(e){this.logger.debug("Read permission request triggered:",e)}}getPermissionErrorMessage(e,t){const r={[s.GRANTED]:"权限已授予。",[s.DENIED]:"权限被拒绝。请在浏览器设置中允许剪贴板访问权限,或使用HTTPS协议。",[s.PROMPT]:'需要用户授权。请在浏览器弹出的权限请求中点击"允许"。',[s.UNKNOWN]:"权限状态未知。可能是浏览器不支持权限API或运行在不安全的上下文中。"},i=this.options.enableFallback?" 系统将尝试使用降级方案。":" 请启用降级处理或使用支持的浏览器。";return`${{read:"剪贴板读取",write:"剪贴板写入"}[e]}${r[t]}${i}`}validateHtmlSafety(e){const t=[/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,/javascript:/gi,/on\w+\s*=/gi,/<iframe\b[^>]*>/gi,/<object\b[^>]*>/gi,/<embed\b[^>]*>/gi,/<form\b[^>]*>/gi,/<input\b[^>]*>/gi,/<meta\b[^>]*>/gi,/<link\b[^>]*>/gi];for(const r of t)if(r.test(e)){this.logger.warn("Potentially dangerous HTML content detected and will be sanitized");break}}sanitizeHtml(e){if(!this.options.enableHtmlSanitization)return e;let t=e.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"").replace(/javascript:/gi,"").replace(/on\w+\s*=\s*["'][^"']*["']/gi,"").replace(/on\w+\s*=\s*[^\s>]+/gi,"").replace(/<iframe\b[^>]*>/gi,"").replace(/<object\b[^>]*>/gi,"").replace(/<embed\b[^>]*>/gi,"").replace(/<form\b[^>]*>/gi,"").replace(/<input\b[^>]*>/gi,"").replace(/<meta\b[^>]*>/gi,"").replace(/<link\b[^>]*>/gi,"");return this.logger.debug("HTML content sanitized"),t}isFileTypeAllowed(e){return!this.options.allowedFileTypes.length||this.options.allowedFileTypes.some(t=>{if(t.includes("*")){const r=t.split("/")[0];return e.startsWith(r+"/")}return!t.startsWith(".")&&e===t})}hashString(e){let t=0;if(0===e.length)return t.toString();for(let r=0;r<e.length;r++){t=(t<<5)-t+e.charCodeAt(r),t&=t}return Math.abs(t).toString(36)}setupEventListeners(){"undefined"!=typeof document&&(document.addEventListener("copy",this.handleCopyEvent.bind(this)),document.addEventListener("paste",this.handlePasteEvent.bind(this)))}removeEventListeners(){"undefined"!=typeof document&&(document.removeEventListener("copy",this.handleCopyEvent.bind(this)),document.removeEventListener("paste",this.handlePasteEvent.bind(this)))}handleCopyEvent(e){this.emit("systemCopy",e)}handlePasteEvent(e){this.emit("systemPaste",e)}async fallbackCopyText(e){const r=this.options.fallbackStrategies;for(const t of r)try{if(await this.executeFallbackStrategy(t,"copy",e))return this.logger.debug(`Fallback text copy successful using ${t} strategy`),!0}catch(e){this.logger.warn(`Fallback strategy ${t} failed:`,e);continue}throw this.errorHandler.createError(t.SYSTEM_ERROR,"All fallback clipboard copy strategies failed",{context:{method:"fallbackCopyText",extra:{strategies:r}},recoverable:!1})}async executeFallbackStrategy(e,r,i){if("undefined"==typeof document)throw this.errorHandler.createError(t.SYSTEM_ERROR,"Document not available for fallback operations",{context:{method:"executeFallbackStrategy",extra:{strategy:e}}});switch(e){case"execCommand":return this.execCommandFallback(r,i);case"selection":return this.selectionApiFallback(r,i);case"input":return this.inputElementFallback(r,i);case"textarea":return this.textareaElementFallback(r,i);default:throw this.errorHandler.createError(t.CONFIG_ERROR,`Unknown fallback strategy: ${e}`,{context:{method:"executeFallbackStrategy",extra:{strategy:e}}})}}async execCommandFallback(e,t){if("read"===e)return!1;if(!document.execCommand)return!1;const r=document.createElement("textarea");r.value=t||"",r.style.position="fixed",r.style.left="-999999px",r.style.top="-999999px",r.style.opacity="0",r.style.pointerEvents="none",r.setAttribute("readonly",""),document.body.appendChild(r);try{r.focus(),r.select(),r.setSelectionRange(0,r.value.length);return document.execCommand("copy")}finally{document.body.removeChild(r)}}async selectionApiFallback(e,t){if("read"===e||"undefined"==typeof window)return!1;const r=window.getSelection();if(!r)return!1;const i=document.createElement("div");i.textContent=t||"",i.style.position="fixed",i.style.left="-999999px",i.style.top="-999999px",i.style.opacity="0",document.body.appendChild(i);try{const e=document.createRange();e.selectNodeContents(i),r.removeAllRanges(),r.addRange(e);const t=document.execCommand("copy");return r.removeAllRanges(),t}finally{document.body.removeChild(i)}}async inputElementFallback(e,t){if("read"===e)return!1;const r=document.createElement("input");r.type="text",r.value=t||"",r.style.position="fixed",r.style.left="-999999px",r.style.top="-999999px",r.style.opacity="0",r.setAttribute("readonly",""),document.body.appendChild(r);try{r.focus(),r.select(),r.setSelectionRange(0,r.value.length);return document.execCommand("copy")}finally{document.body.removeChild(r)}}async textareaElementFallback(e,t){if("read"===e)return!1;const r=document.createElement("textarea");r.value=t||"",r.style.position="fixed",r.style.left="-999999px",r.style.top="-999999px",r.style.opacity="0",r.style.resize="none",r.setAttribute("readonly",""),document.body.appendChild(r);try{r.focus(),r.select(),r.setSelectionRange(0,r.value.length);return document.execCommand("copy")}finally{document.body.removeChild(r)}}async fallbackCopyHTML(e){const r=["selection","execCommand"];for(const t of r)try{if(await this.executeHtmlFallbackStrategy(t,e))return this.logger.debug(`Fallback HTML copy successful using ${t} strategy`),!0}catch(e){this.logger.warn(`HTML fallback strategy ${t} failed:`,e);continue}try{const t=new h,r=await t.convert(e);if(await this.fallbackCopyText(r))return this.logger.debug("Fallback HTML copy successful using text conversion"),!0}catch(e){this.logger.warn("HTML to text fallback failed:",e)}throw this.errorHandler.createError(t.SYSTEM_ERROR,"All fallback HTML copy strategies failed",{context:{method:"fallbackCopyHTML",extra:{strategies:r}},recoverable:!1})}async executeHtmlFallbackStrategy(e,r){if("undefined"==typeof document||"undefined"==typeof window)throw this.errorHandler.createError(t.SYSTEM_ERROR,"Document/Window not available for HTML fallback operations",{context:{method:"executeHtmlFallbackStrategy",extra:{strategy:e}}});switch(e){case"selection":return this.selectionHtmlFallback(r);case"execCommand":return this.execCommandHtmlFallback(r);default:throw this.errorHandler.createError(t.CONFIG_ERROR,`Unknown HTML fallback strategy: ${e}`,{context:{method:"executeHtmlFallbackStrategy",extra:{strategy:e}}})}}async selectionHtmlFallback(e){const t=window.getSelection();if(!t)return!1;const r=document.createElement("div");r.innerHTML=e,r.style.position="fixed",r.style.left="-999999px",r.style.top="-999999px",r.style.opacity="0",r.style.pointerEvents="none",document.body.appendChild(r);try{const e=document.createRange();e.selectNodeContents(r),t.removeAllRanges(),t.addRange(e);const i=document.execCommand("copy");return t.removeAllRanges(),i}finally{document.body.removeChild(r)}}async execCommandHtmlFallback(e){if(!document.execCommand)return!1;const t=document.createElement("div");t.contentEditable="true",t.innerHTML=e,t.style.position="fixed",t.style.left="-999999px",t.style.top="-999999px",t.style.opacity="0",t.style.pointerEvents="none",document.body.appendChild(t);try{t.focus();const e=document.createRange();e.selectNodeContents(t);const r=window.getSelection();if(r){r.removeAllRanges(),r.addRange(e);const t=document.execCommand("copy");return r.removeAllRanges(),t}return!1}finally{document.body.removeChild(t)}}async fallbackCopyElement(e,r){if("undefined"==typeof document||"undefined"==typeof window)throw this.errorHandler.createError(t.SYSTEM_ERROR,"Document/Window not available for fallback element copy",{context:{method:"fallbackCopyElement"}});try{const t=document.createRange();t.selectNodeContents(e);const i=window.getSelection();if(i){i.removeAllRanges(),i.addRange(t);const e=document.execCommand("copy");return i.removeAllRanges(),e?this.logger.debug(`Fallback element copy successful (${r})`):this.logger.warn(`Fallback element copy failed (${r})`),e}return!1}catch(e){throw this.logger.error("Fallback element copy failed:",e),this.errorHandler.createError(t.SYSTEM_ERROR,"Fallback clipboard element copy failed",{context:{method:"fallbackCopyElement",extra:{format:r}},cause:e})}}async fallbackRead(e){throw this.errorHandler.createError(t.SYSTEM_ERROR,`Fallback reading for ${e} is not supported due to security restrictions`,{context:{method:"fallbackRead",extra:{format:e}}})}onCopy(e){this.on("copy",e)}onRead(e){this.on("read",e)}onSystemCopy(e){this.on("systemCopy",e)}onSystemPaste(e){this.on("systemPaste",e)}onPaste(e){if("undefined"==typeof document)return void this.logger.warn("Document not available for paste event listener");const t=t=>{const r=t.clipboardData;if(r)try{if(r.types.includes("text/html")){const t=r.getData("text/html");e({type:"html",data:t,size:t.length,timestamp:Date.now()})}else if(r.types.includes("text/plain")){const t=r.getData("text/plain");e({type:"text",data:t,size:t.length,timestamp:Date.now()})}}catch(e){this.handleError(e,"onPaste")}};document.addEventListener("paste",t),this.once("beforeDestroy",()=>{document.removeEventListener("paste",t)})}async getPermissionStatus(){this.ensureInitialized();return{write:await this.checkWritePermission(),read:await this.checkReadPermission()}}async requestPermissions(){this.ensureInitialized();try{const e=await this.requestPermissionSmart("write"),t=await this.requestPermissionSmart("read");return this.logger.debug("Permission request results:",{write:e.state,read:t.state}),e.granted}catch(e){return this.handleError(e,"requestPermissions"),!1}}async clear(){return this.ensureInitialized(),this.ensureNotDestroyed(),this.safeExecute(async()=>{try{return await this.copyText(""),this.logger.debug("Clipboard cleared"),this.emit("cleared"),!0}catch(e){return this.logger.warn("Failed to clear clipboard:",e),!1}},"clear")}addValidationRule(e,t){f.getInstance().addValidationRule(e,t),this.logger.debug(`Added custom validation rule for ${e}: ${t.name}`)}addDataConverter(e){this.registerDataConverter(e),this.logger.debug(`Added custom data converter: ${e.name}`)}detectDataType(e){return f.getInstance().detectDataType(e)}validateData(e,t,r){return this.validateClipboardData(e,t,r)}async convertDataFormat(e,t,r,i){return this.ensureInitialized(),this.convertData(e,t,r,i)}getProcessingStats(){const e=f.getInstance();return{converters:this.dataConverters.size,validationRules:e.validationRules?.size||0,cacheSize:this.cache?.size()||0}}}class c{constructor(){this.supportsBigData=!1}canConvert(e,t){return e===this.fromType&&t===this.toType}validateInput(e){return null!=e}getOptions(){return{}}async processInChunks(e,t,r=65536){const i=[];for(let a=0;a<e.length;a+=r){const s=e.slice(a,a+r);i.push(t(s))}return i}}class d extends c{constructor(){super(...arguments),this.fromType="text",this.toType="html",this.name="TextToHtmlConverter",this.supportsBigData=!0}async convert(e){if(!this.validateInput(e)||"string"!=typeof e)throw new Error("Invalid text data for HTML conversion");if(e.length>1e5){return(await this.processInChunks(e,this.convertTextChunk.bind(this))).join("")}return this.convertTextChunk(e)}convertTextChunk(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/\n/g,"<br>").replace(/\t/g,"&nbsp;&nbsp;&nbsp;&nbsp;").replace(/ /g,"&nbsp;&nbsp;")}validateInput(e){return"string"==typeof e}}class h extends c{constructor(){super(...arguments),this.fromType="html",this.toType="text",this.name="HtmlToTextConverter",this.supportsBigData=!0}async convert(e){if(!this.validateInput(e)||"string"!=typeof e)throw new Error("Invalid HTML data for text conversion");if(e.length>1e5){return(await this.processInChunks(e,this.convertHtmlChunk.bind(this))).join("")}return this.convertHtmlChunk(e)}convertHtmlChunk(e){if("undefined"!=typeof document){const t=document.createElement("div");return t.innerHTML=e,t.textContent||t.innerText||""}return e.replace(/<br\s*\/?>/gi,"\n").replace(/<\/p>/gi,"\n").replace(/<\/div>/gi,"\n").replace(/<[^>]*>/g,"").replace(/&nbsp;/g," ").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#39;/g,"'").replace(/\n\s*\n/g,"\n").trim()}validateInput(e){return"string"==typeof e}}class u extends c{constructor(){super(...arguments),this.fromType="text",this.toType="rtf",this.name="TextToRtfConverter"}async convert(e){if(!this.validateInput(e)||"string"!=typeof e)throw new Error("Invalid text data for RTF conversion");return`{\\rtf1\\ansi\\deff0 {\\fonttbl {\\f0 Times New Roman;}}\\f0\\fs24 ${e.replace(/\\/g,"\\\\").replace(/{/g,"\\{").replace(/}/g,"\\}").replace(/\n/g,"\\par ").replace(/\t/g,"\\tab ")}}`}validateInput(e){return"string"==typeof e}}class p extends c{constructor(){super(...arguments),this.fromType="rtf",this.toType="text",this.name="RtfToTextConverter"}async convert(e){if(!this.validateInput(e)||"string"!=typeof e)throw new Error("Invalid RTF data for text conversion");return e.replace(/\\par\s*/g,"\n").replace(/\\tab\s*/g,"\t").replace(/\\[a-z]+\d*\s*/g,"").replace(/{[^}]*}/g,"").replace(/\\\\/g,"\\").replace(/\\{/g,"{").replace(/\\}/g,"}").trim()}validateInput(e){return"string"==typeof e&&e.startsWith("{\\rtf")}}class m extends c{constructor(){super(...arguments),this.fromType="image",this.toType="text",this.name="ImageToBase64Converter"}async convert(e){if(!this.validateInput(e))throw new Error("Invalid image data for Base64 conversion");return new Promise((t,r)=>{const i=new FileReader;i.onload=()=>t(i.result),i.onerror=()=>r(new Error("Failed to read image data")),i.readAsDataURL(e)})}validateInput(e){return e instanceof Blob&&e.type.startsWith("image/")}}class g extends c{constructor(){super(...arguments),this.fromType="text",this.toType="image",this.name="Base64ToImageConverter"}async convert(e){if(!this.validateInput(e))throw new Error("Invalid Base64 data for image conversion");const t=e.match(/^data:([^;]+);base64,(.+)$/);if(!t)throw new Error("Invalid Base64 data URL format");const r=t[1],i=t[2],a=atob(i),s=new Uint8Array(a.length);for(let e=0;e<a.length;e++)s[e]=a.charCodeAt(e);return new Blob([s],{type:r})}validateInput(e){return"string"==typeof e&&e.startsWith("data:image/")&&e.includes(";base64,")}}cla