/**
 * Skipped minification because the original files appears to be already minified.
 * Original file: /npm/picgo@2.0.3/dist/index.cjs.js
 *
 * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
 */
"use strict";require("dotenv/config");var e=require("fs-extra"),t=require("path"),n=require("events"),r=require("os"),i=require("commander"),s=require("inquirer"),o=require("image-size"),a=require("url"),c=require("lodash"),l=require("comment-json"),u=require("axios"),p=require("crypto"),g=require("chalk"),E=require("util"),d=require("dayjs"),h=require("mime-types"),_=require("node:crypto"),f=require("md5"),I=require("resolve"),C=require("child_process"),m=require("is-wsl"),S=require("form-data"),N=require("https"),L=require("tunnel"),P=require("@picgo/store"),D=require("cross-spawn"),U=require("js-yaml"),y=require("@picgo/i18n"),T=require("@hono/node-server"),A=require("@hono/node-server/serve-static"),O=require("hono"),R=require("hono/logger"),x=require("hono/cors");function w(e){var t=Object.create(null);return e&&Object.keys(e).forEach(function(n){if("default"!==n){var r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:function(){return e[n]}})}}),t.default=e,Object.freeze(t)}var B=w(_);const b=e=>{const t=`${!0===e.global?"g":""}${!0===e.ignoreCase?"i":""}`;return new RegExp(e.match,t)},G=(e,t,n)=>{if(e.imgUrl)for(const r of t){if(!(!1!==r.enable))continue;let t;try{t=b(r)}catch(e){n.log.error(e);continue}if(!t.test(e.imgUrl))continue;const i=e.imgUrl,s=i.replace(t,r.replace);if(s!==i&&void 0===e.originImgUrl&&(e.originImgUrl=i),e.imgUrl=s,""===s){const e=n.i18n?.translate("URL_REWRITE_EMPTY_RESULT")??"URL_REWRITE_EMPTY_RESULT";n.log.warn(e)}break}},v={handle:e=>{const t=e.cmd;t.program.command("install <plugins...>").description("install picgo plugin").alias("add").option("-p, --proxy <proxy>","Add proxy for installing plugins").option("-r, --registry <registry>","Choose a registry for installing plugins").action((t,n)=>{const{proxy:r,registry:i}=n,s={npmProxy:r,npmRegistry:i};e.pluginHandler.install(t,s).catch(t=>{e.log.error(t)})}),t.program.command("uninstall <plugins...>").alias("rm").description("uninstall picgo plugin").action(t=>{e.pluginHandler.uninstall(t).catch(t=>{e.log.error(t)})}),t.program.command("update <plugins...>").description("update picgo plugin").option("-p, --proxy <proxy>","Add proxy for installing plugins").option("-r, --registry <registry>","Choose a registry for installing plugins").action((t,n)=>{const{proxy:r,registry:i}=n,s={npmProxy:r,npmRegistry:i};e.pluginHandler.update(t,s).catch(t=>{e.log.error(t)})})}},M={handle:e=>{e.cmd.program.option("-c, --config <path>","set config path")}},$=e=>e.startsWith("http://")||e.startsWith("https://"),F=e=>{if(!e)return"";try{return new a.URL(e).href}catch(t){if(e.startsWith("//"))try{return new a.URL("http:"+e).href.slice(5)}catch(e){}return encodeURI(e)}},H=(...e)=>e.join("").replace(/\/{2,}/g,"/").split("/").map(e=>encodeURIComponent(e)).join("/"),k=e=>{try{const{width:t=0,height:n=0,type:r}=o.imageSize(e);return{real:!0,width:t,height:n,extname:r?`.${r}`:".png"}}catch(e){return{real:!1,width:200,height:200,extname:".png"}}},Y=async n=>{try{return{extname:t.extname(n),fileName:t.basename(n),filePath:n,buffer:await e.readFile(n),success:!0}}catch{return{reason:`read file ${n} error`,success:!1}}},q=async(e,n)=>{e=F(e);let r,i=!1,s="";const o=new Promise((o,c)=>{(async()=>{try{const c=await n.request({method:"get",url:e,resolveWithFullResponse:!0,responseType:"arraybuffer"}).then(e=>{const t=e.headers["content-type"];return t?.includes("image")&&(i=!0,s=`.${t.split("image/")[1]}`),e.data});clearTimeout(r);const l=new a.URL(e).pathname,u=decodeURIComponent(t.basename(l));o(i?{buffer:c,fileName:u,extname:s||t.extname(u)||".png",success:!0}:{buffer:c,fileName:u,extname:t.extname(u)||".png",success:!0})}catch(t){clearTimeout(r),o({success:!1,reason:`request ${e} error, ${t?.message??""}`})}})().catch(c)}),c=new Promise(t=>{r=setTimeout(()=>{t({success:!1,reason:`request ${e} timeout`})},1e4)});return Promise.race([o,c])},V=e=>/^@[^/]+\/picgo-plugin-/.test(e)?"scope":e.startsWith("picgo-plugin-")?"normal":K(e)?"simple":"unknown",K=n=>{if(t.isAbsolute(n))return!1;const r=t.join(process.cwd(),n);return!e.existsSync(r)&&(!n.includes("/")&&!n.includes("\\"))},j=(e,t="")=>t?`@${t}/picgo-plugin-${e}`:`picgo-plugin-${e}`,W=(n,r=console)=>{switch(V(n)){case"normal":case"scope":return n;case"simple":return j(n);default:{let i=n;return t.isAbsolute(n)&&e.existsSync(n)?z(i):(i=t.join(process.cwd(),n),e.existsSync(i)?z(i):(r.warn(`Can't find plugin ${n}`),""))}}},Q=(n,r=console)=>{switch(V(n)){case"normal":return J(n);case"scope":return J(n,!0);case"simple":return J(j(n));default:{if(!e.existsSync(n))return r.warn(`Can't find plugin: ${n}`),"";const i=t.posix.join(n,"package.json");if(e.existsSync(i)){const t=e.readJSONSync(i)||{};return t.name?.includes("picgo-plugin-")?t.name:(r.warn(`The plugin package.json's name filed is ${t.name||"empty"}, need to include the prefix: picgo-plugin-`),"")}return r.warn(`Can't find plugin: ${n}`),""}}},z=e=>e.split(t.sep).join("/"),J=(e,t=!1)=>{if(e.includes("@")){let n=/(.+\/)?(picgo-plugin-\w+)(@.+)*/;t&&(n=/(.+\/)?(^@[^/]+\/picgo-plugin-\w+)(@.+)*/);const r=e.match(n);return r?r[2]:(console.warn("can not remove plugin version"),e)}return e},X=[],Z=e=>X.some(t=>e.startsWith(t)),ee=e=>"object"==typeof e&&!Array.isArray(e)&&Object.keys(e).length>0;function te(e){try{return JSON.parse(e)}catch(t){return e}}const ne=(e=0)=>isNaN(Number(e))?0:Number(e),re=()=>"development"===process.env.NODE_ENV;var ie=Object.freeze({__proto__:null,configBlackList:X,forceNumber:ne,getFSFile:Y,getImageSize:k,getNormalPluginName:Q,getPluginNameType:V,getProcessPluginName:W,getURLFile:q,handleCompletePluginName:j,handleStreamlinePluginName:e=>/^@[^/]+\/picgo-plugin-/.test(e)?e.replace(/^@[^/]+\/picgo-plugin-/,""):e.replace(/picgo-plugin-/,""),handleUnixStylePath:z,handleUrlEncode:F,handleUrlPathSafeEncode:H,isConfigKeyInBlackList:Z,isDev:re,isInputConfigValid:ee,isProd:()=>"production"===process.env.NODE_ENV,isSimpleName:K,isUrl:$,removePluginVersion:J,safeParse:te});const se={handle:n=>{n.cmd.program.command("upload").description("upload, go go go").arguments("[input...]").alias("u").action(async r=>{try{const i=r.map(e=>$(e)?e:t.resolve(e)).filter(t=>{const r=e.existsSync(t)||$(t);return r||n.log.warn(`${t} does not exist.`),r});await n.upload(i)}catch(e){if(n.log.error(e),process.argv.includes("--debug"))throw e}})}};var oe,ae,ce,le,ue,pe;exports.SyncStatus=void 0,(oe=exports.SyncStatus||(exports.SyncStatus={})).SUCCESS="success",oe.CONFLICT="conflict",oe.FAILED="failed",exports.ConflictType=void 0,(ae=exports.ConflictType||(exports.ConflictType={})).CLEAN="clean",ae.CONFLICT="conflict",ae.ADDED="added",ae.DELETED="deleted",ae.MODIFIED="modified",exports.E2EVersion=void 0,(ce=exports.E2EVersion||(exports.E2EVersion={}))[ce.NONE=0]="NONE",ce[ce.V1=1]="V1",exports.EncryptionMethod=void 0,(le=exports.EncryptionMethod||(exports.EncryptionMethod={})).AUTO="auto",le.SSE="sse",le.E2EE="e2ee",exports.E2EAskPinReason=void 0,(ue=exports.E2EAskPinReason||(exports.E2EAskPinReason={})).SETUP="setup",ue.DECRYPT="decrypt",ue.RETRY="retry",function(e){e.GUI="gui",e.CLI="cli"}(pe||(pe={}));const ge=process.env.PICGO_API_URL||"https://api.picgo.app",Ee=process.env.PICGO_CLOUD_URL||"https://cloud.picgo.app";class de{ctx;baseURL;constructor(e,t=ge){this.ctx=e,this.baseURL=t}async request(e,t){const n=t??this.ctx.getConfig("settings.picgoCloud.token"),r=e.headers||{};n&&(r.Authorization=`Bearer ${n}`);return(await u.request({baseURL:this.baseURL,...e,headers:r})).data}}class he{client;ctx;appType=pe.CLI;constructor(e){this.client=new de(e),this.ctx=e}async fetchConfig(){this.appType=this.ctx.GUI_VERSION?pe.GUI:pe.CLI;try{const e=await this.client.request({method:"GET",url:"/api/config",params:{appType:this.appType}});return e?.config&&""!==e.config.trim()?e:null}catch(e){if(u.isAxiosError(e)){const t=e.response?.status;if(404===t)return null;const n=e.response?.data?.message??e.message;throw this.ctx.log.warn("[ConfigService] Failed to fetch config:",n),new Error(n)}throw e}}async updateConfig(e,t,n){this.appType=this.ctx.GUI_VERSION?pe.GUI:pe.CLI;try{return{success:!0,version:(await this.client.request({method:"PUT",url:"/api/config",data:{appType:this.appType,config:e,baseVersion:t,historyLimit:10,...n??{}}})).version}}catch(e){if(u.isAxiosError(e)){const n=e.response?.data;if("CONFIG_CONFLICT"===n?.code)return{success:!1,conflict:!0,version:"number"==typeof n.currentVersion?n.currentVersion:t};const r=n?.message??e.message;throw this.ctx.log.warn("[ConfigService] Failed to update config:",r),new Error(r)}throw e}}}const _e=(e,t)=>!(!e||"object"!=typeof e)&&Object.prototype.hasOwnProperty.call(e,t),fe=e=>{const t=Object.getPrototypeOf(e),n=Object.create(t);for(const t of Object.getOwnPropertySymbols(e)){const r=Object.getOwnPropertyDescriptor(e,t);r&&Object.defineProperty(n,t,r)}return n},Ie=(e,t)=>{const n=fe(e),r=[],i=new Set;for(const t of Object.keys(e))i.has(t)||(r.push(t),i.add(t));for(const e of Object.keys(t))i.has(e)||(r.push(e),i.add(e));for(const i of r){if(!_e(t,i)){delete n[i];continue}const r=_e(e,i)?e[i]:void 0,s=t[i];c.isPlainObject(r)&&c.isPlainObject(s)?n[i]=Ie(r,s):n[i]=s}return n},Ce=(e,t)=>c.isEqual(e,t)?exports.ConflictType.CLEAN:void 0===e&&void 0!==t?exports.ConflictType.ADDED:void 0!==e&&void 0===t?exports.ConflictType.DELETED:exports.ConflictType.MODIFIED;class me{static merge3Way(e,t,n,r="root"){if(c.isEqual(t,n)){const i=Ce(e,t);return{value:t,conflict:!1,diffNode:i===exports.ConflictType.CLEAN?void 0:{key:r,status:i,snapshotValue:e,localValue:t,remoteValue:n}}}const i=c.isPlainObject(t),s=c.isPlainObject(n),o=c.isPlainObject(e);if(c.isEqual(e,t)){if(i&&s){const i=Ie(t,n),s=Ce(e,i);return{value:i,conflict:!1,diffNode:s===exports.ConflictType.CLEAN?void 0:{key:r,status:s,snapshotValue:e,localValue:t,remoteValue:n}}}const o=Ce(e,n);return{value:n,conflict:!1,diffNode:o===exports.ConflictType.CLEAN?void 0:{key:r,status:o,snapshotValue:e,localValue:t,remoteValue:n}}}if(c.isEqual(e,n)){const i=Ce(e,t);return{value:t,conflict:!1,diffNode:i===exports.ConflictType.CLEAN?void 0:{key:r,status:i,snapshotValue:e,localValue:t,remoteValue:n}}}if(i&&s&&(o||null==e)){const i=o?e:{},s=t,a=n,c=[],l=new Set;for(const e of Object.keys(s))l.has(e)||(c.push(e),l.add(e));for(const e of Object.keys(a))l.has(e)||(c.push(e),l.add(e));for(const e of Object.keys(i))l.has(e)||(c.push(e),l.add(e));const u=fe(s),p=[];let g=!1;for(const e of c){const t=_e(i,e)?i[e]:void 0,n=_e(s,e)?s[e]:void 0,r=_e(a,e)?a[e]:void 0,o=me.merge3Way(t,n,r,e);o.conflict&&(g=!0),void 0===o.value?delete u[e]:u[e]=o.value,o.diffNode&&o.diffNode.status!==exports.ConflictType.CLEAN&&p.push(o.diffNode)}const E=g?exports.ConflictType.CONFLICT:Ce(e,u);return{value:u,conflict:g,diffNode:E===exports.ConflictType.CLEAN?void 0:{key:r,status:E,snapshotValue:e,localValue:t,remoteValue:n,children:p.length?p:void 0}}}return{value:t,conflict:!0,diffNode:{key:r,status:exports.ConflictType.CONFLICT,snapshotValue:e,localValue:t,remoteValue:n}}}}class Se extends Error{constructor(e){super(e),this.name=new.target.name}}class Ne extends Se{constructor(e="Encrypted config payload is corrupted"){super(e)}}class Le extends Se{constructor(e="Unsupported E2E version"){super(e)}}class Pe extends Se{constructor(e="PIN handler is required for E2E operations"){super(e)}}class De extends Se{constructor(e="Encryption switch confirmation handler is required"){super(e)}}class Ue extends Se{constructor(e="Invalid PIN input"){super(e)}}class ye extends Se{constructor(e="Maximum retry attempts exceeded"){super(e)}}class Te extends Se{constructor(e="Failed to decrypt payload"){super(e)}}class Ae extends Se{value;constructor(e){super("Invalid encryption method"),this.value=e}}const Oe=12,Re="aes-256-gcm";class xe{generateE2EPayload(e,t){const n=p.randomBytes(16),r=p.randomBytes(32),i=this.wrapDEK(r,t,n),s=this.encryptConfig(e,r);return{payload:{e2eVersion:exports.E2EVersion.V1,clientKekSalt:n.toString("base64"),clientDekEncrypted:i,config:s},dek:r}}encryptConfig(e,t){return this.encryptWithKey(Buffer.from(e,"utf8"),t)}decryptConfig(e,t){return this.decryptWithKey(e,t).toString("utf8")}wrapDEK(e,t,n){const r=this.deriveKEK(t,n);return this.encryptWithKey(e,r)}unwrapDEK(e,t,n){const r=this.deriveKEK(t,n);return this.decryptWithKey(e,r)}decodeSalt(e){const t=Buffer.from(e,"base64");if(16!==t.length)throw new Ne("Invalid salt length");return t}deriveKEK(e,t){return p.pbkdf2Sync(e,t,6e5,32,"sha256")}encryptWithKey(e,t){const n=p.randomBytes(Oe),r=p.createCipheriv(Re,t,n),i=Buffer.concat([r.update(e),r.final()]),s=r.getAuthTag();return Buffer.concat([n,s,i]).toString("base64")}decryptWithKey(e,t){const n=Buffer.from(e,"base64");if(n.length<28)throw new Ne("Encrypted payload is too short");const r=n.subarray(0,Oe),i=n.subarray(Oe,28),s=n.subarray(28);try{const e=p.createDecipheriv(Re,t,r);return e.setAuthTag(i),Buffer.concat([e.update(s),e.final()])}catch(e){const t=e instanceof Error?e.message:"Failed to decrypt payload";throw new Te(t)}}}const we="settings.picgoCloud.encryptionMethod",Be=["settings.picgoCloud.token",we],be=(e,t,n={})=>{const r=c.cloneDeep(e),i=!0===n.cleanupEmptyParents;return Be.forEach(e=>{const n=c.get(t,e);void 0!==n?c.set(r,e,n):(c.unset(r,e),i&&((e,t)=>{const n=t.split(".");for(let t=n.length-1;t>0;t-=1){const r=n.slice(0,t).join("."),i=c.get(e,r);if(!c.isPlainObject(i)||0!==Object.keys(i).length)break;c.unset(e,r)}})(r,e))}),r},Ge=(e,t)=>{if(e)return e;const n=(e=>{const t=c.get(e,we);if(void 0!==t){if(t===exports.EncryptionMethod.AUTO||t===exports.EncryptionMethod.SSE||t===exports.EncryptionMethod.E2EE)return t;throw new Ae(t)}})(t);return n??exports.EncryptionMethod.AUTO},ve=async t=>{if(await e.pathExists(t)){const n=await e.readFile(t,"utf8");return l.parse(n)}return{}},Me=async t=>{if(!await e.pathExists(t))return{version:0,updatedAt:"",data:{}};const n=await ve(t);return(e=>{if(!c.isPlainObject(e))return!1;const t=e;return"number"==typeof t.version&&Object.prototype.hasOwnProperty.call(t,"data")})(n)?{version:n.version,updatedAt:"string"==typeof n.updatedAt?n.updatedAt:"",data:n.data??{}}:{version:0,updatedAt:"",data:n}},$e=async(t,n,r)=>{await(async(t,n)=>{const r=l.stringify(n,null,2);await e.writeFile(t,r,"utf8")})(t,{version:r,updatedAt:(new Date).toISOString(),data:n})};class Fe{ctx;snapshotPath;configService;onAskPin;onAskEncryptionSwitch;e2eService;currentRemoteVersion=0;originalRemote=null;remoteE2EVersion=exports.E2EVersion.NONE;remoteClientKekSalt;remoteClientDekEncrypted;cachedDEK;cachedClientDekEncrypted;constructor(e,n={}){this.ctx=e,this.snapshotPath=t.join(e.baseDir,"config.snapshot.json"),this.configService=new he(e),this.onAskPin=n.onAskPin,this.onAskEncryptionSwitch=n.onAskEncryptionSwitch,this.e2eService=new xe}async sync(t={},n=0){try{const r=await ve(this.ctx.configPath);if(!c.isPlainObject(r))return{status:exports.SyncStatus.FAILED,message:"Local config is not a valid JSON object"};const i=r,s=Ge(t.encryptionMethod,i),o=await e.pathExists(this.snapshotPath),a=await Me(this.snapshotPath),l=await this.fetchRemoteConfig();if(l&&!c.isPlainObject(l))return{status:exports.SyncStatus.FAILED,message:"Remote config is not a valid JSON object"};if(this.originalRemote=l||null,!this.originalRemote){const e=!o;e?this.ctx.log.info("First time sync detected. Initializing remote config..."):this.ctx.log.warn("Remote config missing (sync chain broken). Re-initializing from Local...");try{const e=await this.buildPushPayload(i,s);await this.pushRemoteConfig(e.configStr,e.e2eFields)}catch(e){if("Remote config modified by another device"===(e instanceof Error?e.message:String(e)))return n<1?(this.ctx.log.warn("Conflict detected during sync. Retrying automatically..."),this.sync(t,n+1)):{status:exports.SyncStatus.FAILED,message:"Sync failed: Remote config is changing too frequently. Please try again later."};throw e}return await $e(this.snapshotPath,i,this.currentRemoteVersion),{status:exports.SyncStatus.SUCCESS,message:e?"Config sync initialized":"Remote config restored from local",mergedConfig:i}}if(this.originalRemote&&this.isEncryptionModeSwitch(s)&&!t.skipEncryptionSwitchConfirm){if(!await this.confirmEncryptionSwitch(s))return{status:exports.SyncStatus.FAILED,message:this.ctx.i18n.translate("CONFIG_SYNC_ENCRYPTION_SWITCH_CANCELLED")}}const u=be(this.originalRemote,i);this.ctx.log.info("Merging configs for sync...");const p=me.merge3Way(a.data,i,u);if(p.conflict)return{status:exports.SyncStatus.CONFLICT,message:"Config sync conflict detected",diffTree:p.diffNode};const g=p.value;!c.isEqual(i,g)&&this.ctx.saveConfig(g);const E=be(g,this.originalRemote,{cleanupEmptyParents:!0});if(this.isEncryptionModeSwitch(s)||!c.isEqual(this.originalRemote,E))try{const e=await this.buildPushPayload(E,s);await this.pushRemoteConfig(e.configStr,e.e2eFields)}catch(e){if("Remote config modified by another device"===(e instanceof Error?e.message:String(e)))return n<1?(this.ctx.log.warn("Conflict detected during sync. Retrying automatically..."),this.sync(t,n+1)):{status:exports.SyncStatus.FAILED,message:"Sync failed: Remote config is changing too frequently. Please try again later."};throw e}return await $e(this.snapshotPath,g,this.currentRemoteVersion),{status:exports.SyncStatus.SUCCESS,message:"Config sync success",mergedConfig:g}}catch(e){if(e instanceof Ae)return{status:exports.SyncStatus.FAILED,message:this.ctx.i18n.translate("CONFIG_SYNC_INVALID_ENCRYPTION_METHOD",{value:`"${String(e.value)}"`})};if(e instanceof De)return{status:exports.SyncStatus.FAILED,message:this.ctx.i18n.translate("CONFIG_SYNC_ENCRYPTION_SWITCH_MISSING_HANDLER")};const t=e instanceof Error?e.message:String(e);return{status:exports.SyncStatus.FAILED,message:t}}}async applyResolvedConfig(e,t={}){try{if(!c.isPlainObject(e))return{status:exports.SyncStatus.FAILED,message:"Resolved config is not a valid JSON object"};const n=await ve(this.ctx.configPath);if(!c.isPlainObject(n))return{status:exports.SyncStatus.FAILED,message:"Local config is not a valid JSON object"};const r=be(e,n);if(this.ctx.saveConfig(r),!this.originalRemote){const e=await this.fetchRemoteConfig();if(e&&!c.isPlainObject(e))return{status:exports.SyncStatus.FAILED,message:"Remote config is not a valid JSON object"};this.originalRemote=e||null}const i=this.originalRemote?be(r,this.originalRemote,{cleanupEmptyParents:!0}):r,s=t.useE2E??this.remoteE2EVersion===exports.E2EVersion.V1?exports.EncryptionMethod.E2EE:exports.EncryptionMethod.SSE,o=await this.buildPushPayload(i,s);return await this.pushRemoteConfig(o.configStr,o.e2eFields),await $e(this.snapshotPath,r,this.currentRemoteVersion),{status:exports.SyncStatus.SUCCESS,message:"Config conflict resolved",mergedConfig:r}}catch(e){const t=e instanceof Error?e.message:String(e);return{status:exports.SyncStatus.FAILED,message:t}}}async fetchRemoteConfig(){this.ctx.log.info("Fetching remote config for sync...");const e=await this.configService.fetchConfig();if(!e)return this.currentRemoteVersion=0,this.setRemoteE2EState(exports.E2EVersion.NONE),null;this.currentRemoteVersion=e.version;if((e=>{if(e===exports.E2EVersion.V1)return exports.E2EVersion.V1;if(e===exports.E2EVersion.NONE||void 0===e)return exports.E2EVersion.NONE;if("number"==typeof e)throw new Le(`Unsupported E2E version: ${e}`);return exports.E2EVersion.NONE})(e.encryption?.e2eVersion)===exports.E2EVersion.V1){const t=(e=>{if(!e.encryption?.clientKekSalt)throw new Ne("Missing clientKekSalt for encrypted config");return e.encryption.clientKekSalt})(e),n=(e=>{if(!e.encryption?.clientDekEncrypted)throw new Ne("Missing clientDekEncrypted for encrypted config");return e.encryption.clientDekEncrypted})(e);this.setRemoteE2EState(exports.E2EVersion.V1,t,n);const r=await this.decryptRemoteConfig(e.config,t,n);return l.parse(r)}return this.setRemoteE2EState(exports.E2EVersion.NONE),l.parse(e.config)}async pushRemoteConfig(e,t){this.ctx.log.info("Pushing merged config to remote...");const n=await this.configService.updateConfig(e,this.currentRemoteVersion,t);if(n.conflict)throw this.currentRemoteVersion=n.version,new Error("Remote config modified by another device");this.currentRemoteVersion=n.version,this.applyE2EStateAfterPush(t)}applyE2EStateAfterPush(e){e.e2eVersion===exports.E2EVersion.V1&&e.clientKekSalt&&e.clientDekEncrypted?this.setRemoteE2EState(exports.E2EVersion.V1,e.clientKekSalt,e.clientDekEncrypted):e.e2eVersion===exports.E2EVersion.NONE&&this.setRemoteE2EState(exports.E2EVersion.NONE)}setRemoteE2EState(e,t,n){this.remoteE2EVersion=e,this.remoteClientKekSalt=t,this.remoteClientDekEncrypted=n,n&&n===this.cachedClientDekEncrypted||(this.cachedDEK=void 0,this.cachedClientDekEncrypted=void 0)}async confirmEncryptionSwitch(e){if(!this.onAskEncryptionSwitch)throw new De;const t=this.remoteE2EVersion===exports.E2EVersion.V1?exports.EncryptionMethod.E2EE:exports.EncryptionMethod.SSE,n=this.shouldUseE2E(e)?exports.EncryptionMethod.E2EE:exports.EncryptionMethod.SSE;return this.onAskEncryptionSwitch({from:t,to:n})}async buildPushPayload(e,t){const n=l.stringify(e);if(!this.shouldUseE2E(t))return{configStr:n,e2eFields:{e2eVersion:exports.E2EVersion.NONE}};if(this.remoteE2EVersion===exports.E2EVersion.V1&&this.remoteClientKekSalt&&this.remoteClientDekEncrypted){const e=await this.ensureDEK(this.remoteClientKekSalt,this.remoteClientDekEncrypted);return{configStr:this.e2eService.encryptConfig(n,e),e2eFields:{e2eVersion:exports.E2EVersion.V1,clientKekSalt:this.remoteClientKekSalt,clientDekEncrypted:this.remoteClientDekEncrypted}}}const r=await this.askPin(exports.E2EAskPinReason.SETUP,0),{payload:i,dek:s}=this.e2eService.generateE2EPayload(n,r);return this.cachedDEK=s,this.cachedClientDekEncrypted=i.clientDekEncrypted,{configStr:i.config,e2eFields:{e2eVersion:i.e2eVersion,clientKekSalt:i.clientKekSalt,clientDekEncrypted:i.clientDekEncrypted}}}shouldUseE2E(e){return e===exports.EncryptionMethod.E2EE||e!==exports.EncryptionMethod.SSE&&this.remoteE2EVersion===exports.E2EVersion.V1}isEncryptionModeSwitch(e){return this.shouldUseE2E(e)!==(this.remoteE2EVersion===exports.E2EVersion.V1)}async decryptRemoteConfig(e,t,n){const r=await this.ensureDEK(t,n);try{return this.e2eService.decryptConfig(e,r)}catch(e){if(e instanceof Te)throw new Ne("Failed to decrypt remote config payload");throw e}}async ensureDEK(e,t){if(this.cachedDEK&&this.cachedClientDekEncrypted===t)return this.cachedDEK;const n=this.e2eService.decodeSalt(e);for(let e=0;e<4;e+=1){const r=0===e?exports.E2EAskPinReason.DECRYPT:exports.E2EAskPinReason.RETRY,i=await this.askPin(r,e);try{const e=this.e2eService.unwrapDEK(t,i,n);return this.cachedDEK=e,this.cachedClientDekEncrypted=t,e}catch(e){if(e instanceof Te)continue;throw e}}throw new ye}async askPin(e,t){if(!this.onAskPin)throw new Pe;const n=await this.onAskPin(e,t);if(null==n||0===n.length)throw new Ue;return n}}const He=e=>{if(void 0===e)return"undefined";try{return JSON.stringify(e)}catch{return E.inspect(e,{depth:4,breakLength:120,maxArrayLength:50})}},ke=(e,t=0)=>{const n=" ".repeat(2*t),r=e.status===exports.ConflictType.CONFLICT?g.red:e.status===exports.ConflictType.ADDED?g.green:e.status===exports.ConflictType.DELETED?g.gray:e.status===exports.ConflictType.MODIFIED?g.yellow:g.white;if(console.log(`${n}${r(`[${e.status}]`)} ${e.key}`),e.status!==exports.ConflictType.CONFLICT||e.children&&0!==e.children.length||(console.log(`${n}  ${g.gray("snapshot:")} ${He(e.snapshotValue)}`),console.log(`${n}  ${g.cyan("local :")} ${He(e.localValue)}`),console.log(`${n}  ${g.magenta("remote:")} ${He(e.remoteValue)}`)),e.children?.length)for(const n of e.children)ke(n,t+1)},Ye={handle:e=>{e.cmd.program.command("config").description("manage picgo config").command("sync").description("sync config with picgo cloud").option("--encrypt [method]","encryption method (auto|sse|e2ee)").option("--skip-encryption-switch-confirm","skip encryption switch confirmation").action(async t=>{const n=t.encrypt;let r;if(void 0!==n){const t="string"==typeof n?n:void 0;if(t!==exports.EncryptionMethod.AUTO&&t!==exports.EncryptionMethod.SSE&&t!==exports.EncryptionMethod.E2EE){const n=t??"undefined";return void e.log.error(e.i18n.translate("CONFIG_SYNC_INVALID_ENCRYPTION_METHOD",{value:`"${n}"`}))}r=t,e.saveConfig({"settings.picgoCloud.encryptionMethod":t})}const i=new Fe(e,{onAskPin:async(t,n)=>{if(t===exports.E2EAskPinReason.SETUP){for(let t=0;t<3;t+=1){const{pin:t}=await e.cmd.inquirer.prompt([{type:"password",name:"pin",message:"Set up E2E encryption. Enter PIN",mask:"*"}]),{confirmPin:n}=await e.cmd.inquirer.prompt([{type:"password",name:"confirmPin",message:"Confirm PIN",mask:"*"}]);if(t===n)return t;e.log.warn("PIN confirmation does not match. Please try again.")}return null}const r=t===exports.E2EAskPinReason.DECRYPT?"Enter PIN to decrypt config":`Incorrect PIN. Retry (${n}/3)`,{pin:i}=await e.cmd.inquirer.prompt([{type:"password",name:"pin",message:r,mask:"*"}]);return i},onAskEncryptionSwitch:async({from:t,to:n})=>{const r=e.i18n.translate(t===exports.EncryptionMethod.E2EE?"CONFIG_SYNC_ENCRYPTION_METHOD_E2EE":"CONFIG_SYNC_ENCRYPTION_METHOD_SSE"),i=e.i18n.translate(n===exports.EncryptionMethod.E2EE?"CONFIG_SYNC_ENCRYPTION_METHOD_E2EE":"CONFIG_SYNC_ENCRYPTION_METHOD_SSE"),s=e.i18n.translate("CONFIG_SYNC_ENCRYPTION_SWITCH_TITLE"),o=e.i18n.translate("CONFIG_SYNC_ENCRYPTION_SWITCH_BODY",{from:r,to:i}),{confirm:a}=await e.cmd.inquirer.prompt([{type:"list",name:"confirm",message:`${s}\n\n${o}`,choices:[{name:e.i18n.translate("CONFIG_SYNC_ENCRYPTION_SWITCH_CONFIRM"),value:!0},{name:e.i18n.translate("CONFIG_SYNC_ENCRYPTION_SWITCH_CANCEL"),value:!1}]}]);return a}}),s=await i.sync({encryptionMethod:r,skipEncryptionSwitchConfirm:t.skipEncryptionSwitchConfirm});if(s.status!==exports.SyncStatus.SUCCESS){if(s.status===exports.SyncStatus.CONFLICT){e.log.warn(s.message||"Config sync conflict detected."),s.diffTree&&ke(s.diffTree);const{strategy:t}=await e.cmd.inquirer.prompt([{type:"list",name:"strategy",message:"Choose a strategy to resolve conflicts",choices:[{name:"Use Local",value:"local"},{name:"Use Remote",value:"remote"},{name:"Abort",value:"abort"}]}]);if("abort"===t)return void e.log.warn("Config sync aborted.");const n="local"===t?s.diffTree?.localValue:s.diffTree?.remoteValue;if(!n||!c.isPlainObject(n))return void e.log.error("Invalid resolved config, please resolve it manually.");let o;if(r===exports.EncryptionMethod.E2EE)o={useE2E:!0};else if(r===exports.EncryptionMethod.SSE)o={useE2E:!1};else{const t=e.getConfig("settings.picgoCloud.encryptionMethod");t===exports.EncryptionMethod.E2EE?o={useE2E:!0}:t===exports.EncryptionMethod.SSE&&(o={useE2E:!1})}const a=await i.applyResolvedConfig(n,o);return a.status===exports.SyncStatus.SUCCESS?void e.log.success(a.message||"Config sync resolved!"):void e.log.error(a.message||"Failed to apply resolved config")}e.log.error(s.message||"Config sync failed")}else e.log.success(s.message||"Config sync success!")})}},qe=e=>e.trim(),Ve=e=>qe(e).toLowerCase(),Ke=(e,t)=>{const n=Ve(t);return e.find(e=>Ve(e)===n)},je=async(e,t,n,r)=>{const i=await e.cmd.inquirer.prompt(t),s="transformer"===n?`transformer.${r}`:r;e.saveConfig({[s]:i}),"transformer"===n&&e.saveConfig({"picBed.transformer":r})},We={handle:e=>{e.cmd.program.command("set").arguments("<module> [name] [configName]").description("configure config of picgo modules (uploader/transformer/plugin)").action(async(t,n,r)=>{try{switch(t){case"uploader":{const t=n||(await e.cmd.inquirer.prompt([{type:"list",name:"uploaderType",choices:e.helper.uploader.getIdList(),message:"Choose an uploader",default:e.getConfig("picBed.uploader")||e.getConfig("picBed.current")||"smms"}])).uploaderType,i=e.helper.uploader.get(t);if(!i)return e.log.error(`No uploader named ${t}`);if(!i.config)return e.log.error(`Uploader ${t} has no config`);const s=e.uploaderConfig.getConfigList(t),o=s.map(e=>e._configName);let a="string"==typeof r?qe(r):"";if(!a)if(o.length>0){const t=await e.cmd.inquirer.prompt([{type:"list",name:"configChoice",message:"Choose a config",choices:[{name:"[Create New Config]",value:"__CREATE__"},...o]}]);if("__CREATE__"===t.configChoice){const t=await e.cmd.inquirer.prompt([{type:"input",name:"newConfigName",message:"Enter config name",validate:e=>{const t=qe(e);return t?!Ke(o,t)||`Config name ${t} already exists`:"Config name can not be empty"}}]);a=qe(t.newConfigName)}else a=String(t.configChoice)}else{const t=await e.cmd.inquirer.prompt([{type:"input",name:"newConfigName",message:"Enter config name",validate:e=>!!qe(e)||"Config name can not be empty"}]);a=qe(t.newConfigName)}const c=Ke(o,a);if(c){const n=s.find(e=>Ve(e._configName)===Ve(c));n&&e.setConfig({[`picBed.${t}`]:n})}const l=await e.cmd.inquirer.prompt(i.config(e));e.uploaderConfig.createOrUpdate(t,a,l)}break;case"transformer":if(n){const r=e.helper.transformer.get(n);if(!r)return e.log.error(`No transformer named ${n}`);r.config&&await je(e,r.config(e),t,n)}else{const n=[{type:"list",name:"transformer",choices:e.helper.transformer.getIdList(),message:"Choose a transformer"}],r=await e.cmd.inquirer.prompt(n),i=e.helper.transformer.get(r.transformer);i?.config&&await je(e,i.config(e),t,r.transformer)}break;case"plugin":if(n){if(n.includes("picgo-plugin-")||(n=`picgo-plugin-${n}`),!Object.keys(e.getConfig("picgoPlugins")).includes(n))return e.log.error(`No plugin named ${n}`);e.pluginLoader.getPlugin(n)?.config&&await je(e,e.pluginLoader.getPlugin(n).config(e),"plugin",n)}else{const t=[{type:"list",name:"plugin",choices:e.pluginLoader.getFullList(),message:"Choose a plugin"}],n=await e.cmd.inquirer.prompt(t);e.pluginLoader.getPlugin(n.plugin)?.config&&await je(e,e.pluginLoader.getPlugin(n.plugin).config(e),"plugin",n.plugin)}break;default:return e.log.warn(`No module named ${t}`),e.log.warn("Available modules are uploader|transformer|plugin")}e.log.success("Configure config successfully!"),"plugin"===t&&e.log.info("If you want to use this config, please run 'picgo use plugins'")}catch(t){if(e.log.error(t),process.argv.includes("--debug"))throw t}})}},Qe={handle:async e=>{const t=e.cmd;t.program.command("use").arguments("[module] [name] [configName]").description("use a module (uploader/transformer/plugin) of picgo").action(async(n,r,i)=>{try{if("uploader"===n&&r)return e.uploaderConfig.use(r,i),void e.log.success("Activated config successfully!");const s=["uploader","transformer","plugins"];let o=[];const a={uploader:{type:"list",name:"uploader",message:"Use an uploader",choices:e.helper.uploader.getIdList(),default:e.getConfig("picBed.uploader")||e.getConfig("picBed.current")||"smms"},transformer:{type:"list",name:"transformer",message:"Use a transformer",choices:e.helper.transformer.getIdList(),default:e.getConfig("picBed.transformer")||"path"},plugins:{type:"checkbox",name:"plugins",message:"Use plugins",choices:e.pluginLoader.getFullList(),default:Object.keys(e.getConfig("picgoPlugins")).filter(t=>e.getConfig(`picgoPlugins.${t}`))}};if(n){if("uploader"!==n&&"transformer"!==n&&"plugins"!==n)return e.log.warn(`No module named ${n}`),e.log.warn(`Available modules are ${s.join("|")}`);o.push(a[n])}else o=s.map(e=>a[e]);const c=await t.inquirer.prompt(o);if(c.plugins){const t=c.plugins,n=e.getConfig("picgoPlugins");Object.keys(n).forEach(e=>{n[e]=t.includes(e)}),e.saveConfig({picgoPlugins:n})}if(c.uploader){const n=c.uploader,r=e.uploaderConfig.getConfigList(n);if(r.length>1){const i=e.uploaderConfig.getActiveConfig(n),s=await t.inquirer.prompt([{type:"list",name:"uploaderConfigName",message:"Use an uploader config",choices:r.map(e=>e._configName),default:i?._configName}]);e.uploaderConfig.use(n,s.uploaderConfigName)}else e.uploaderConfig.use(n)}void 0!==c.transformer&&e.saveConfig({"picBed.transformer":c.transformer||"path"}),e.log.success("Configure config successfully!")}catch(t){if(e.log.error(t),process.argv.includes("--debug"))throw t}})}},ze={handle:e=>{e.cmd.program.option("-p, --proxy <url>","set proxy for uploading",t=>{e.setConfig({"picBed.proxy":t})})}},Je={handle:e=>{e.cmd.program.command("i18n").arguments("[lang]").description("change picgo language").action(async(t="")=>{const n=e.i18n.getLanguageList();if(!t){const t=[{type:"list",name:"i18n",choices:n,message:"Choose a language",default:e.getConfig("settings.language")||"zh-CN"}],r=await e.cmd.inquirer.prompt(t);return e.i18n.setLanguage(r.i18n),void e.log.success(`Language set to ${r.i18n}`)}if(!n.includes(t))return e.log.warn("No such language");e.i18n.setLanguage(t),e.log.success(`Language set to ${t}`)})}},Xe={handle:e=>{e.cmd.program.command("server").description("run PicGo as a standalone server").helpOption("--help","display help for command").option("-p, --port <n>","server port").option("-h, --host <s>","server host").option("-i, --ignore-existing-external-server","ignore existing PicGo server instance").option("--secret <s>","server authentication secret").action(async t=>{try{const n=t.port?Number(t.port):void 0,r=t.host;await e.server.listen(n,r,t.ignoreExistingExternalServer,t.secret)}catch(t){e.log.error(t)}})}},Ze={handle:e=>{e.cmd.program.command("login").description("login to cloud.picgo.app").arguments("[token]").action(async t=>{try{await e.cloud.login(t)}catch(t){e.log.error(t)}})}},et={handle:e=>{e.cmd.program.command("logout").description("logout from cloud.picgo.app").action(async()=>{try{e.cloud.logout()}catch(t){e.log.error(t)}})}},tt=e=>e.trim(),nt=e=>tt(e).toLowerCase(),rt=(e,t)=>{const n=e.getConfig("picBed.current"),r=[];for(const i of t){n===i?r.push(g.green.bold(`+ ${i} [Current Uploader]`)):r.push(`+ ${i}`);const t=e.uploaderConfig.getConfigList(i);if(0===t.length){r.push(g.grey("  (No configs found)"));continue}const s=e.getConfig(`uploader.${i}.defaultId`);for(const e of t)e._id===s?r.push(g.blue(`  * ${e._configName} [Default Config]`)):r.push(`    ${e._configName}`)}return`\n${r.join("\n")}`},it={handle:e=>{const t=e.cmd,n=t.program.command("uploader").description("manage uploader configurations").action(async()=>{try{const n=[{name:"List all configurations",value:"list"},{name:"Rename config",value:"rename"},{name:"Copy config",value:"copy"},{name:"Delete config",value:"delete"}],r=await t.inquirer.prompt([{type:"list",name:"operation",message:"Choose an operation:",choices:n}]);if("list"===r.operation){const t=e.uploaderConfig.listUploaderTypes();return void console.log(rt(e,t))}const i=e.uploaderConfig.listUploaderTypes().filter(t=>e.uploaderConfig.getConfigList(t).length>0);if(0===i.length)return void e.log.warn("No configs found");const s=await t.inquirer.prompt([{type:"list",name:"type",message:"Choose an uploader:",choices:i}]),o=String(s.type),a=e.uploaderConfig.getConfigList(o).map(e=>e._configName),c=await t.inquirer.prompt([{type:"list",name:"configName",message:"rename"===r.operation?"Choose a config to rename:":"copy"===r.operation?"Choose a config to copy:":"Choose a config to delete:",choices:a}]),l=String(c.configName);if("rename"===r.operation){const n=await t.inquirer.prompt([{type:"input",name:"newName",message:"Enter new name:",validate:e=>{const t=tt(e);if(!t)return"Config name can not be empty";return!a.some(e=>nt(e)===nt(t)&&nt(e)!==nt(l))||`Config name ${t} already exists`}}]);return e.uploaderConfig.rename(o,l,String(n.newName)),void e.log.success("Rename config successfully!")}if("copy"===r.operation){const n=await t.inquirer.prompt([{type:"input",name:"newName",message:"Enter new name:",validate:e=>{const t=tt(e);if(!t)return"Config name can not be empty";return!a.some(e=>nt(e)===nt(t))||`Config name ${t} already exists`}}]);return e.uploaderConfig.copy(o,l,String(n.newName)),void e.log.success("Copy config successfully!")}if(!(await t.inquirer.prompt([{type:"confirm",name:"confirm",message:`Are you sure you want to delete ${l}?`,default:!1}])).confirm)return;e.uploaderConfig.remove(o,l),e.log.success("Delete config successfully!")}catch(t){if(e.log.error(t),process.argv.includes("--debug"))throw t}});n.command("list [type]").description("list uploader configurations").action(async t=>{try{const n=e.uploaderConfig.listUploaderTypes();if("string"==typeof t&&t)return n.includes(t)?void console.log(rt(e,[t])):void e.log.error(`Type ${t} not found`);console.log(rt(e,n))}catch(t){if(e.log.error(t),process.argv.includes("--debug"))throw t}}),n.command("rename <type> <oldName> <newName>").description("rename a config").action(async(t,n,r)=>{try{e.uploaderConfig.rename(t,n,r),e.log.success("Rename config successfully!")}catch(t){if(e.log.error(t),process.argv.includes("--debug"))throw t}}),n.command("copy <type> <configName> <newConfigName>").description("copy a config (does not switch current uploader)").action(async(t,n,r)=>{try{e.uploaderConfig.copy(t,n,r),e.log.success("Copy config successfully!")}catch(t){if(e.log.error(t),process.argv.includes("--debug"))throw t}}),n.command("rm <type> <configName>").description("remove a config").action(async(t,n)=>{try{e.uploaderConfig.remove(t,n),e.log.success("Delete config successfully!")}catch(t){if(e.log.error(t),process.argv.includes("--debug"))throw t}})}};class st{static currentPlugin;list;pluginIdMap;name;constructor(e){this.name=e,this.list=new Map,this.pluginIdMap=new Map}register(e,t){if(!e)throw new TypeError("id is required!");if("function"!=typeof t.handle)throw new TypeError("plugin.handle must be a function!");if(this.list.has(e))throw new TypeError(`${this.name} duplicate id: ${e}!`);this.list.set(e,t),st.currentPlugin&&(this.pluginIdMap.has(st.currentPlugin)?this.pluginIdMap.get(st.currentPlugin)?.push(e):this.pluginIdMap.set(st.currentPlugin,[e]))}unregister(e){if(this.pluginIdMap.has(e)){const t=this.pluginIdMap.get(e);t?.forEach(e=>{this.list.delete(e)})}}getName(){return this.name}get(e){return this.list.get(e)}getList(){return[...this.list.values()]}getIdList(){return[...this.list.keys()]}}const ot=(e=null)=>{st.currentPlugin=e};class at{name="commander";static currentPlugin;list=new Map;pluginIdMap=new Map;ctx;program;inquirer;constructor(e){this.program=new i.Command,this.inquirer=s,this.ctx=e}getName(){return this.name}init(){var e;this.program.version("2.0.3","-v, --version").option("-d, --debug","debug mode",()=>{this.ctx.setConfig({debug:!0})}).option("-s, --silent","silent mode",()=>{this.ctx.setConfig({silent:!0})}).on("command:*",()=>{this.ctx.log.error(`Invalid command: ${this.program.args.join(" ")}\nSee --help for a list of available commands.`),process.exit(1)}),(e=this.ctx).cmd.register("pluginHandler",v),e.cmd.register("configPath",M),e.cmd.register("config",Ye),e.cmd.register("setting",We),e.cmd.register("upload",se),e.cmd.register("use",Qe),e.cmd.register("proxy",ze),e.cmd.register("i18n",Je),e.cmd.register("server",Xe),e.cmd.register("login",Ze),e.cmd.register("logout",et),e.cmd.register("uploader",it)}register(e,t){if(!e)throw new TypeError("name is required!");if("function"!=typeof t.handle)throw new TypeError("plugin.handle must be a function!");if(this.list.has(e))throw new TypeError(`${this.name} plugin duplicate id: ${e}!`);this.list.set(e,t);const n=st.currentPlugin;null!==n&&(this.pluginIdMap.has(n)?this.pluginIdMap.get(n)?.push(e):this.pluginIdMap.set(n,[e]))}unregister(e){if(this.pluginIdMap.has(e)){const t=this.pluginIdMap.get(e);t?.forEach(e=>{this.list.delete(e)})}}loadCommands(){this.getList().forEach(e=>{try{e.handle(this.ctx)}catch(e){this.ctx.log.error(e)}})}get(e){return this.list.get(e)}getList(){return[...this.list.values()]}getIdList(){return[...this.list.keys()]}}var ct,lt;exports.ILogType=void 0,(ct=exports.ILogType||(exports.ILogType={})).success="success",ct.info="info",ct.warn="warn",ct.error="error",exports.IBuildInEvent=void 0,(lt=exports.IBuildInEvent||(exports.IBuildInEvent={})).UPLOAD_PROGRESS="uploadProgress",lt.FAILED="failed",lt.BEFORE_TRANSFORM="beforeTransform",lt.BEFORE_UPLOAD="beforeUpload",lt.AFTER_UPLOAD="afterUpload",lt.FINISHED="finished",lt.INSTALL="install",lt.UNINSTALL="uninstall",lt.UPDATE="update",lt.NOTIFICATION="notification",exports.IBusEvent=void 0,(exports.IBusEvent||(exports.IBusEvent={})).CONFIG_CHANGE="CONFIG_CHANGE";class ut{level={[exports.ILogType.success]:"green",[exports.ILogType.info]:"blue",[exports.ILogType.warn]:"yellow",[exports.ILogType.error]:"red"};ctx;logLevel;logPath;constructor(e){this.ctx=e}handleLog(e,...n){if(this.logLevel=this.ctx.getConfig("settings.logLevel"),!this.ctx.getConfig("silent")&&this.checkLogLevel(e,this.logLevel)){const r=g[this.level[e]](`[PicGo ${e.toUpperCase()}]:`);console.log(r,...n),this.logPath=this.ctx.getConfig("settings.logPath")||t.join(this.ctx.baseDir,"./picgo.log"),setTimeout(()=>{try{const t=this.checkLogFileIsLarge(this.logPath);if(t.isLarge){const e=`Log file is too large (> ${t.logFileSizeLimit/1024/1024||"10"} MB), recreate log file`;console.log(g.yellow("[PicGo WARN]:"),e),this.recreateLogFile(this.logPath),n.unshift(e)}this.handleWriteLog(this.logPath,e,...n)}catch(e){console.error("[PicGo Error] on checking log file size",e)}},0)}}checkLogFileIsLarge(t){if(e.existsSync(t)){const n=e.statSync(t).size,r=1024*ne(this.ctx.getConfig("settings.logFileSizeLimit")||10)*1024;return{isLarge:n>r,logFileSize:n,logFileSizeLimit:r}}return{isLarge:!1}}recreateLogFile(t){e.existsSync(t)&&(e.unlinkSync(t),e.createFileSync(t))}handleWriteLog(t,n,...r){try{let i=`${d().format("YYYY-MM-DD HH:mm:ss")} [PicGo ${n.toUpperCase()}] `;r.forEach(e=>{e instanceof Error&&"error"===n?i+=`\n------Error Stack Begin------\n${E.format(e?.stack)}\n-------Error Stack End------- `:("object"==typeof e&&(e=JSON.stringify(e,null,2)),i+=`${e} `)}),i+="\n",e.appendFileSync(t,i)}catch(e){console.error("[PicGo Error] on writing log file",e)}}checkLogLevel(e,t){return void 0===t||"all"===t||(Array.isArray(t)?t.some(t=>t===e||"all"===t):e===t)}success(...e){return this.handleLog(exports.ILogType.success,...e)}info(...e){return this.handleLog(exports.ILogType.info,...e)}error(...e){return this.handleLog(exports.ILogType.error,...e)}warn(...e){return this.handleLog(exports.ILogType.warn,...e)}debug(...e){re()&&this.handleLog(exports.ILogType.info,...e)}}class pt extends n.EventEmitter{ctx;constructor(e){super(),this.ctx=e}async start(e){const t=(e=>({configPath:e.configPath,baseDir:e.baseDir,log:e.log,cmd:e.cmd,server:e.server,cloud:e.cloud,uploaderConfig:e.uploaderConfig,output:[],input:[],pluginLoader:e.pluginLoader,pluginHandler:e.pluginHandler,Request:e.Request,helper:e.helper,VERSION:e.VERSION,GUI_VERSION:e.GUI_VERSION,request:e.request,openUrl:e.openUrl.bind(e),i18n:e.i18n,getConfig:e.getConfig.bind(e),saveConfig:e.saveConfig.bind(e),removeConfig:e.removeConfig.bind(e),setConfig:e.setConfig.bind(e),unsetConfig:e.unsetConfig.bind(e),upload:e.upload.bind(e),addListener:e.addListener.bind(e),on:e.on.bind(e),once:e.once.bind(e),removeListener:e.removeListener.bind(e),off:e.off.bind(e),removeAllListeners:e.removeAllListeners.bind(e),setMaxListeners:e.setMaxListeners.bind(e),getMaxListeners:e.getMaxListeners.bind(e),listeners:e.listeners.bind(e),rawListeners:e.rawListeners.bind(e),emit:e.emit.bind(e),listenerCount:e.listenerCount.bind(e),prependListener:e.prependListener.bind(e),prependOnceListener:e.prependOnceListener.bind(e),eventNames:e.eventNames.bind(e)}))(this.ctx);try{if(!Array.isArray(e))throw new Error("Input must be an array.");return t.input=e,t.output=[],await this.beforeTransform(t),await this.doTransform(t),await this.beforeUpload(t),await this.doUpload(t),await this.afterUpload(t),t}catch(e){if(t.log.warn(exports.IBuildInEvent.FAILED),t.emit(exports.IBuildInEvent.UPLOAD_PROGRESS,-1),t.emit(exports.IBuildInEvent.FAILED,e),t.log.error(e),t.getConfig("debug"))throw e;return t}}async beforeTransform(e){return e.emit(exports.IBuildInEvent.UPLOAD_PROGRESS,0),e.emit(exports.IBuildInEvent.BEFORE_TRANSFORM,e),e.log.info("Before transform"),await this.handlePlugins(e.helper.beforeTransformPlugins,e),e}async doTransform(e){e.emit(exports.IBuildInEvent.UPLOAD_PROGRESS,30);const t=e.getConfig("picBed.transformer")||"path";let n=t,r=e.helper.transformer.get(t);return r||(r=e.helper.transformer.get("path"),n="path",e.log.warn(`Can't find transformer - ${t}, switch to default transformer - path`)),e.log.info(`Transforming... Current transformer is [${n}]`),await(r?.handle(e)),e}async beforeUpload(e){return e.emit(exports.IBuildInEvent.UPLOAD_PROGRESS,60),e.log.info("Before upload"),e.emit(exports.IBuildInEvent.BEFORE_UPLOAD,e),await this.handlePlugins(e.helper.beforeUploadPlugins,e),e}async doUpload(e){let t=e.getConfig("picBed.uploader")||e.getConfig("picBed.current")||"smms",n=e.helper.uploader.get(t),r=t;n||(t="smms",r="smms",n=e.helper.uploader.get("smms"),e.log.warn(`Can't find uploader - ${t}, switch to default uploader - smms`)),e.log.info(`Uploading... Current uploader is [${r}]`),await(n?.handle(e));for(const n of e.output)n.type=t;return e}async afterUpload(e){e.emit(exports.IBuildInEvent.AFTER_UPLOAD,e),e.emit(exports.IBuildInEvent.UPLOAD_PROGRESS,100),(e=>{const t=e.getConfig("settings.urlRewrite.rules");if(Array.isArray(t)&&0!==t.length)for(const n of e.output)G(n,t,e)})(e),await this.handlePlugins(e.helper.afterUploadPlugins,e);let t="";const n=e.output.length,r=!0===e.getConfig("settings.encodeOutputURL");for(let i=0;i<n;i++)void 0!==e.output[i].imgUrl&&(t+=r?F(e.output[i].imgUrl):e.output[i].imgUrl,i!==n-1&&(t+="\n")),delete e.output[i].base64Image,delete e.output[i].buffer;return e.emit(exports.IBuildInEvent.FINISHED,e),e.log.success(`\n${t}`),e}async handlePlugins(e,t){const n=e.getList(),r=e.getIdList(),i=e.getName();return await Promise.all(n.map(async(e,n)=>{try{t.log.info(`${i}: ${r[n]} running`),await e.handle(t)}catch(e){throw t.log.error(`${i}: ${r[n]} error`),e}})),t}}const gt=(e,t,n,r="")=>{const i=r||"s.ee";return{method:"POST",url:`https://${i}${"s.ee"===i?"/api/v1/file/upload":"/api/v2/upload"}`,headers:{contentType:"multipart/form-data","User-Agent":"PicGo",Authorization:n},formData:{smfile:{value:t,options:{filename:e}}}}},Et=async e=>{const t=e.getConfig("picBed.smms");if(!t)throw new Error("Can not find smms config!");const n=e.output;for(const r of n)if(r.fileName&&r.buffer){let n=r.buffer;!n&&r.base64Image&&(n=Buffer.from(r.base64Image,"base64"));const i=gt(r.fileName,n,t?.token,t?.backupDomain);try{const t=await e.request(i),n=JSON.parse(t);if(200!==n.code&&"success"!==n.message)throw e.emit(exports.IBuildInEvent.NOTIFICATION,{title:e.i18n.translate("UPLOAD_FAILED"),body:n.message}),new Error(n.message);delete r.base64Image,delete r.buffer,r.imgUrl=n.data.url}catch(t){throw e.log.error(t),t}}return e},dt=e=>{const t=e.getConfig("picBed.smms")||{};return[{name:"token",message:"api token",type:"password",get alias(){return e.i18n.translate("PICBED_SMMS_TOKEN")},default:t.token||"",required:!0},{name:"backupDomain",type:"input",get prefix(){return e.i18n.translate("PICBED_SMMS_BACKUP_DOMAIN")},get message(){return e.i18n.translate("PICBED_SMMS_MESSAGE_BACKUP_DOMAIN")},get alias(){return e.i18n.translate("PICBED_SMMS_BACKUP_DOMAIN")},default:t.backupDomain||"",required:!1}]};const ht=e=>h.lookup(e)||"application/octet-stream",_t=(e,t,n,r)=>{const i=e.secretId,s=e.secretKey,o=e.appId,a=e.bucket;let c,l="";if(e.version&&"v4"!==e.version){const i=Math.floor((new Date).getTime()/1e3);l=`${i};${i+86400}`;const o=p.createHmac("sha1",s).update(l).digest("hex"),a=e.endpoint?e.endpoint:`cos.${e.area}.myqcloud.com`,g=`put\n/${e.path}${t}\n\ncontent-length=${r}&content-type=${u=n,encodeURIComponent(u).replace(/!/g,"%21").replace(/'/g,"%27").replace(/\(/g,"%28").replace(/\)/g,"%29").replace(/\*/g,"%2A")}&host=${e.bucket}.${a}\n`,E=`sha1\n${l}\n${p.createHash("sha1").update(g).digest("hex")}\n`;c=p.createHmac("sha1",o).update(E).digest("hex")}else{const e=Math.floor(1e10*Math.random()),t=Math.floor((new Date).getTime()/1e3)-1,n=`a=${o}&b=${a}&k=${i}&e=${t+3600}&t=${t}&r=${e}&f=`,r=p.createHmac("sha1",s).update(n).digest(),l=Buffer.concat([r,Buffer.from(n)]);c=Buffer.from(l).toString("base64")}var u;return{signature:c,appId:o,bucket:a,signTime:l}},ft=(e,t,n,r,i)=>{const s=e.area,o=e.path;if(e.version&&"v4"!==e.version){const s=e.endpoint?e.endpoint:`cos.${e.area}.myqcloud.com`;return{method:"PUT",url:`http://${e.bucket}.${s}/${H(o,t)}`,headers:{Host:`${e.bucket}.${s}`,Authorization:`q-sign-algorithm=sha1&q-ak=${e.secretId}&q-sign-time=${n.signTime}&q-key-time=${n.signTime}&q-header-list=content-length;content-type;host&q-url-param-list=&q-signature=${n.signature}`,contentType:ht(t),contentLength:r.byteLength,"User-Agent":`PicGo;${i};null;null`},body:r,resolveWithFullResponse:!0}}return{method:"POST",url:`http://${s}.file.myqcloud.com/files/v2/${n.appId}/${n.bucket}/${H(o,t)}`,headers:{Host:`${s}.file.myqcloud.com`,Authorization:n.signature,contentType:"multipart/form-data","User-Agent":`PicGo;${i};null;null`},formData:{op:"upload",filecontent:r},resolveWithFullResponse:!0}},It=async e=>{const t=e.getConfig("picBed.tcyun");if(!t)throw new Error("Can't find tencent COS config");try{const n=e.output,r=t.customUrl,i=t.path,s=!t.version||"v4"===t.version;for(const o of n)if(o.fileName&&o.buffer){let n=o.buffer;!n&&o.base64Image&&(n=Buffer.from(o.base64Image,"base64"));const a=_t(t,o.fileName,ht(o.fileName),n.byteLength);if(!a)return!1;const c=ft(t,o.fileName,a,n,e.GUI_VERSION||e.VERSION),l=await e.request(c).then(e=>e).catch(t=>({statusCode:400,body:{msg:e.i18n.translate("AUTH_FAILED"),err:t}}));let u;if(u=s&&"string"==typeof l?JSON.parse(l):l,400===u.statusCode)throw u?.body?.err?u.body.err:new Error(u?.body?.msg||u?.body?.message);const p=t.options||"",g=t.slim||"";if(s&&"SUCCESS"===u.message)delete o.base64Image,delete o.buffer,o.imgUrl=r?`${r}/${i}${o.fileName}`:`${u.data.source_url}${p}`;else{if(s||!u||200!==u.statusCode)throw new Error(l.body.msg);if(delete o.base64Image,delete o.buffer,r)o.imgUrl=`${r}/${encodeURI(i)}${H(o.fileName)}${p}`;else{const e=t.endpoint?t.endpoint:`cos.${t.area}.myqcloud.com`;o.imgUrl=`https://${t.bucket}.${e}/${encodeURI(i)}${H(o.fileName)}${p}`}}g&&(o.imgUrl+=p?"&imageSlim":"?imageSlim")}return e}catch(n){if(!t.version||"v4"===t.version)try{const t=JSON.parse(n.error);e.emit(exports.IBuildInEvent.NOTIFICATION,{title:e.i18n.translate("UPLOAD_FAILED"),body:e.i18n.translate("UPLOAD_FAILED_REASON",{code:t.code}),text:"https://cloud.tencent.com/document/product/436/8432"})}catch(e){}throw n}},Ct=e=>{const t=e.getConfig("picBed.tcyun")||{};return[{name:"version",type:"list",alias:e.i18n.translate("PICBED_TENCENTCLOUD_VERSION"),choices:["v4","v5"],default:"v5",required:!1},{name:"secretId",type:"input",get alias(){return e.i18n.translate("PICBED_TENCENTCLOUD_SECRETID")},default:t.secretId||"",required:!0},{name:"secretKey",type:"password",get alias(){return e.i18n.translate("PICBED_TENCENTCLOUD_SECRETKEY")},default:t.secretKey||"",required:!0},{name:"bucket",type:"input",get alias(){return e.i18n.translate("PICBED_TENCENTCLOUD_BUCKET")},default:t.bucket||"",required:!0},{name:"appId",type:"input",get prefix(){return e.i18n.translate("PICBED_TENCENTCLOUD_APPID")},get alias(){return e.i18n.translate("PICBED_TENCENTCLOUD_APPID")},default:t.appId||"",get message(){return e.i18n.translate("PICBED_TENCENTCLOUD_MESSAGE_APPID")},required:!0},{name:"area",type:"input",get prefix(){return e.i18n.translate("PICBED_TENCENTCLOUD_AREA")},get alias(){return e.i18n.translate("PICBED_TENCENTCLOUD_AREA")},default:t.area||"",get message(){return e.i18n.translate("PICBED_TENCENTCLOUD_MESSAGE_AREA")},required:!0},{name:"endpoint",type:"input",get prefix(){return e.i18n.translate("PICBED_TENCENTCLOUD_ENDPOINT")},get alias(){return e.i18n.translate("PICBED_TENCENTCLOUD_ENDPOINT")},default:t.endpoint||"",get message(){return e.i18n.translate("PICBED_TENCENTCLOUD_MESSAGE_ENDPOINT")},required:!1},{name:"path",type:"input",get prefix(){return e.i18n.translate("PICBED_TENCENTCLOUD_PATH")},get alias(){return e.i18n.translate("PICBED_TENCENTCLOUD_PATH")},default:t.path||"",get message(){return e.i18n.translate("PICBED_TENCENTCLOUD_MESSAGE_PATH")},required:!1},{name:"customUrl",type:"input",get prefix(){return e.i18n.translate("PICBED_TENCENTCLOUD_CUSTOMURL")},get alias(){return e.i18n.translate("PICBED_TENCENTCLOUD_CUSTOMURL")},default:t.customUrl||"",get message(){return e.i18n.translate("PICBED_TENCENTCLOUD_MESSAGE_CUSTOMURL")},required:!1},{name:"options",type:"input",default:t.options||"",get prefix(){return e.i18n.translate("PICBED_TENCENTCLOUD_OPTIONS")},get alias(){return e.i18n.translate("PICBED_TENCENTCLOUD_OPTIONS")},get message(){return e.i18n.translate("PICBED_TENCENTCLOUD_MESSAGE_OPTIONS")},required:!1},{name:"slim",type:"confirm",default:t.options||"",get prefix(){return e.i18n.translate("PICBED_TENCENTCLOUD_SLIM")},get alias(){return e.i18n.translate("PICBED_TENCENTCLOUD_SLIM")},required:!1,get confirmText(){return e.i18n.translate("PICBED_TENCENTCLOUD_SLIM_CONFIRM")},get cancelText(){return e.i18n.translate("PICBED_TENCENTCLOUD_SLIM_CANCEL")},get tips(){return e.i18n.translate("PICBED_TENCENTCLOUD_SLIM_TIP")}}]};const mt=(e,t,n)=>{const r=t.path||"",{token:i,repo:s}=t;return{method:"PUT",url:`https://api.github.com/repos/${s}/contents/${H(r,e)}`,headers:{Authorization:`token ${i}`,"User-Agent":"PicGo","Content-Type":h.lookup(e)},body:n,json:!0}},St=async e=>{const t=e.getConfig("picBed.github");if(!t)throw new Error("Can't find github config");try{const n=e.output;for(const r of n)if(r.fileName&&r.buffer){const n=r.base64Image||Buffer.from(r.buffer).toString("base64"),i={message:"Upload by PicGo",branch:t.branch,content:n,path:t.path+encodeURI(r.fileName)},s=mt(r.fileName,t,i);try{const n=await e.request(s);if(!n)throw new Error("Server error, please try again");delete r.base64Image,delete r.buffer,t.customUrl?r.imgUrl=`${t.customUrl}/${H(t.path||"",r.fileName)}`:r.imgUrl=n.content.download_url}catch(e){if(422!==e.statusCode)throw e;delete r.base64Image,delete r.buffer,t.customUrl?r.imgUrl=`${t.customUrl}/${H(t.path||"",r.fileName)}`:r.imgUrl=`https://raw.githubusercontent.com/${t.repo}/${t.branch}/${H(t.path||"",r.fileName)}`}}return e}catch(t){throw e.emit(exports.IBuildInEvent.NOTIFICATION,{title:e.i18n.translate("UPLOAD_FAILED"),body:e.i18n.translate("CHECK_SETTINGS_AND_NETWORK")}),t}},Nt=e=>{const t=e.getConfig("picBed.github")||{};return[{name:"repo",type:"input",get prefix(){return e.i18n.translate("PICBED_GITHUB_REPO")},get alias(){return e.i18n.translate("PICBED_GITHUB_REPO")},get message(){return e.i18n.translate("PICBED_GITHUB_MESSAGE_REPO")},default:t.repo||"",required:!0},{name:"branch",type:"input",get prefix(){return e.i18n.translate("PICBED_GITHUB_BRANCH")},get alias(){return e.i18n.translate("PICBED_GITHUB_BRANCH")},get message(){return e.i18n.translate("PICBED_GITHUB_MESSAGE_BRANCH")},default:t.branch||"master",required:!0},{name:"token",type:"password",get alias(){return e.i18n.translate("PICBED_GITHUB_TOKEN")},default:t.token||"",required:!0},{name:"path",type:"input",get prefix(){return e.i18n.translate("PICBED_GITHUB_PATH")},get alias(){return e.i18n.translate("PICBED_GITHUB_PATH")},get message(){return e.i18n.translate("PICBED_GITHUB_MESSAGE_PATH")},default:t.path||"",required:!1},{name:"customUrl",type:"input",get prefix(){return e.i18n.translate("PICBED_GITHUB_CUSTOMURL")},get alias(){return e.i18n.translate("PICBED_GITHUB_CUSTOMURL")},get message(){return e.i18n.translate("PICBED_GITHUB_MESSAGE_CUSTOMURL")},default:t.customUrl||"",required:!1}]};function Lt(e,t,n,r){const i=function(e){return"z0"===e?"":"-"+e}(e.area||"z0"),s=e.path||"";return{method:"POST",url:`http://upload${i}.qiniup.com/putb64/-1/key/${Buffer.from(s+t,"utf-8").toString("base64").replace(/\+/g,"-").replace(/\//g,"_")}`,headers:{Authorization:`UpToken ${n}`,"Content-Type":h.lookup(t)||"application/octet-stream"},body:r}}function Pt(e){return e.replace(/\//g,"_").replace(/\+/g,"-")}function Dt(e){const t=e.accessKey,n=e.secretKey,r={scope:e.bucket,deadline:3600+Math.floor(Date.now()/1e3)},i=(s=JSON.stringify(r),Pt(Buffer.from(s).toString("base64")));var s;const o=Pt(function(e,t){const n=_.createHmac("sha1",t);return n.update(e),n.digest("base64")}(i,n));return[t,o,i].join(":")}const Ut=async e=>{const t=e.getConfig("picBed.qiniu");if(!t)throw new Error("Can't find qiniu config");try{const n=e.output;for(const r of n)if(r.fileName&&r.buffer){const n=r.base64Image||Buffer.from(r.buffer).toString("base64"),i=Lt(t,r.fileName,Dt(t),n),s=await e.request(i),o=JSON.parse(s);if(!o?.key)throw e.emit(exports.IBuildInEvent.NOTIFICATION,{title:e.i18n.translate("UPLOAD_FAILED"),body:o.msg}),e.log.error("qiniu error",o),new Error("Upload failed");{delete r.base64Image,delete r.buffer;const e=t.url,n=t.options;r.imgUrl=`${e}/${o.key}${n}`}}return e}catch(t){if("Upload failed"!==t.message&&t.response){const n=t.response.body;e.emit(exports.IBuildInEvent.NOTIFICATION,{title:e.i18n.translate("UPLOAD_FAILED"),body:n.error})}throw t}},yt=e=>{const t=e.getConfig("picBed.qiniu")||{};return[{name:"accessKey",type:"input",get alias(){return e.i18n.translate("PICBED_QINIU_ACCESSKEY")},default:t.accessKey||"",required:!0},{name:"secretKey",type:"password",get alias(){return e.i18n.translate("PICBED_QINIU_SECRETKEY")},default:t.secretKey||"",required:!0},{name:"bucket",type:"input",get alias(){return e.i18n.translate("PICBED_QINIU_BUCKET")},default:t.bucket||"",required:!0},{name:"url",type:"input",get prefix(){return e.i18n.translate("PICBED_QINIU_URL")},get alias(){return e.i18n.translate("PICBED_QINIU_URL")},get message(){return e.i18n.translate("PICBED_QINIU_MESSAGE_URL")},default:t.url||"",required:!0},{name:"area",type:"input",get prefix(){return e.i18n.translate("PICBED_QINIU_AREA")},get alias(){return e.i18n.translate("PICBED_QINIU_AREA")},get message(){return e.i18n.translate("PICBED_QINIU_MESSAGE_AREA")},default:t.area||"",required:!0},{name:"options",type:"input",get prefix(){return e.i18n.translate("PICBED_QINIU_OPTIONS")},get alias(){return e.i18n.translate("PICBED_QINIU_OPTIONS")},get message(){return e.i18n.translate("PICBED_QINIU_MESSAGE_OPTIONS")},default:t.options||"",required:!1},{name:"path",type:"input",get prefix(){return e.i18n.translate("PICBED_QINIU_PATH")},get alias(){return e.i18n.translate("PICBED_QINIU_PATH")},get message(){return e.i18n.translate("PICBED_QINIU_MESSAGE_PATH")},default:t.path||"",required:!1}]};const Tt=(e,t,n)=>{const r={method:"POST",url:"https://api.imgur.com/3/image",headers:{Authorization:`Client-ID ${e.clientId}`,"content-type":"multipart/form-data",Host:"api.imgur.com","User-Agent":"PicGo"},formData:{image:n,type:"base64",name:t}};return e.proxy&&(r.proxy=e.proxy),r},At=async e=>{const t=e.getConfig("picBed.imgur");if(!t)throw new Error("Can't find imgur config");try{const n=e.output;for(const r of n)if(r.fileName&&r.buffer){const n=r.base64Image||Buffer.from(r.buffer).toString("base64"),i=Tt(t,r.fileName,n),s=await e.request(i),o="string"==typeof s?JSON.parse(s):s;if(!o.success)throw new Error("Server error, please try again");delete r.base64Image,delete r.buffer,r.imgUrl=o.data.link}return e}catch(t){throw e.emit(exports.IBuildInEvent.NOTIFICATION,{title:e.i18n.translate("UPLOAD_FAILED"),body:e.i18n.translate("CHECK_SETTINGS_AND_NETWORK"),text:"http://docs.imgur.com/api/errno/"}),t?.response?.data||t}},Ot=e=>{const t=e.getConfig("picBed.imgur")||{};return[{name:"clientId",type:"input",get alias(){return e.i18n.translate("PICBED_IMGUR_CLIENTID")},default:t.clientId||"",required:!0},{name:"proxy",type:"input",get prefix(){return e.i18n.translate("PICBED_IMGUR_PROXY")},get alias(){return e.i18n.translate("PICBED_IMGUR_PROXY")},get message(){return e.i18n.translate("PICBED_IMGUR_MESSAGE_PROXY")},default:t.proxy||"",required:!1}]};const Rt=(e,t)=>{const n=(new Date).toUTCString(),r=h.lookup(t);if(!r)throw Error(`No mime type found for file ${t}`);const i=`PUT\n\n${r}\n${n}\n/${e.bucket}/${e.path}${t}`,s=p.createHmac("sha1",e.accessKeySecret).update(i).digest("base64");return`OSS ${e.accessKeyId}:${s}`},xt=(e,t,n,r)=>{const i=e.path||"";return{method:"PUT",url:`https://${e.bucket}.${e.area}.aliyuncs.com/${H(i,t)}`,headers:{Host:`${e.bucket}.${e.area}.aliyuncs.com`,Authorization:n,Date:(new Date).toUTCString(),"Content-Type":h.lookup(t)},body:r,resolveWithFullResponse:!0}},wt=async e=>{const t=e.getConfig("picBed.aliyun");if(!t)throw new Error("Can't find aliYun OSS config");try{const n=e.output,r=t.customUrl,i=t.path||"";for(const s of n)if(s.fileName&&s.buffer){const n=Rt(t,s.fileName);let o=s.buffer;!o&&s.base64Image&&(o=Buffer.from(s.base64Image,"base64"));const a=xt(t,s.fileName,n,o);if(200!==(await e.request(a)).statusCode)throw new Error("Upload failed");{delete s.base64Image,delete s.buffer;const e=t.options||"";s.imgUrl=r?`${r}/${H(i,s.fileName)}${e}`:`https://${t.bucket}.${t.area}.aliyuncs.com/${H(i,s.fileName)}${e}`}}return e}catch(t){throw e.emit(exports.IBuildInEvent.NOTIFICATION,{title:e.i18n.translate("UPLOAD_FAILED"),body:e.i18n.translate("CHECK_SETTINGS")}),t}},Bt=e=>{const t=e.getConfig("picBed.aliyun")||{};return[{name:"accessKeyId",type:"input",get alias(){return e.i18n.translate("PICBED_ALICLOUD_ACCESSKEYID")},default:t.accessKeyId||"",required:!0},{name:"accessKeySecret",type:"password",get alias(){return e.i18n.translate("PICBED_ALICLOUD_ACCESSKEYSECRET")},default:t.accessKeySecret||"",required:!0},{name:"bucket",type:"input",get alias(){return e.i18n.translate("PICBED_ALICLOUD_BUCKET")},default:t.bucket||"",required:!0},{name:"area",type:"input",get prefix(){return e.i18n.translate("PICBED_ALICLOUD_AREA")},get alias(){return e.i18n.translate("PICBED_ALICLOUD_AREA")},default:t.area||"",get message(){return e.i18n.translate("PICBED_ALICLOUD_MESSAGE_AREA")},required:!0},{name:"path",type:"input",get prefix(){return e.i18n.translate("PICBED_ALICLOUD_PATH")},get alias(){return e.i18n.translate("PICBED_ALICLOUD_PATH")},get message(){return e.i18n.translate("PICBED_ALICLOUD_MESSAGE_PATH")},default:t.path||"",required:!1},{name:"customUrl",type:"input",get prefix(){return e.i18n.translate("PICBED_ALICLOUD_CUSTOMURL")},get alias(){return e.i18n.translate("PICBED_ALICLOUD_CUSTOMURL")},get message(){return e.i18n.translate("PICBED_ALICLOUD_MESSAGE_CUSTOMURL")},default:t.customUrl||"",required:!1},{name:"options",type:"input",get prefix(){return e.i18n.translate("PICBED_ALICLOUD_OPTIONS")},get alias(){return e.i18n.translate("PICBED_ALICLOUD_OPTIONS")},get message(){return e.i18n.translate("PICBED_ALICLOUD_MESSAGE_OPTIONS")},default:t.options||"",required:!1}]};const bt=(e,t)=>{const n=e.path||"",r=e.operator,i=e.password,s=f(i),o=(new Date).toUTCString(),a=`PUT&${`/${e.bucket}/${H(n,t)}`}&${o}`;return`UPYUN ${r}:${p.createHmac("sha1",s).update(a).digest("base64")}`},Gt=(e,t,n,r)=>{const i=e.bucket,s=e.path||"";return{method:"PUT",url:`https://v0.api.upyun.com/${i}/${H(s,t)}`,headers:{Authorization:n,Date:(new Date).toUTCString(),"Content-Type":h.lookup(t)||"application/octet-stream"},body:r,resolveWithFullResponse:!0}},vt=async e=>{const t=e.getConfig("picBed.upyun");if(!t)throw new Error("Can't find upYun config");try{const n=e.output,r=t.path||"";for(const i of n)if(i.fileName&&i.buffer){let n=i.buffer;!n&&i.base64Image&&(n=Buffer.from(i.base64Image,"base64"));const s=bt(t,i.fileName),o=Gt(t,i.fileName,s,n);if(200!==(await e.request(o)).statusCode)throw new Error("Upload failed");delete i.base64Image,delete i.buffer,i.imgUrl=`${t.url}/${H(r,i.fileName)}${t.options}`}return e}catch(t){if("Upload failed"===t.message)e.emit(exports.IBuildInEvent.NOTIFICATION,{title:e.i18n.translate("UPLOAD_FAILED"),body:e.i18n.translate("CHECK_SETTINGS")});else{const n=te(t.error);e.emit(exports.IBuildInEvent.NOTIFICATION,{title:e.i18n.translate("UPLOAD_FAILED"),body:e.i18n.translate("UPLOAD_FAILED_REASON",{code:"object"==typeof n?n.code:n}),text:"http://docs.upyun.com/api/errno/"})}throw t}},Mt=e=>{const t=e.getConfig("picBed.upyun")||{};return[{name:"bucket",type:"input",get alias(){return e.i18n.translate("PICBED_UPYUN_BUCKET")},default:t.bucket||"",required:!0},{name:"operator",type:"input",get alias(){return e.i18n.translate("PICBED_UPYUN_OPERATOR")},get prefix(){return e.i18n.translate("PICBED_UPYUN_OPERATOR")},get message(){return e.i18n.translate("PICBED_UPYUN_MESSAGE_OPERATOR")},default:t.operator||"",required:!0},{name:"password",type:"password",get prefix(){return e.i18n.translate("PICBED_UPYUN_MESSAGE_PASSWORD")},get alias(){return e.i18n.translate("PICBED_UPYUN_PASSWORD")},get message(){return e.i18n.translate("PICBED_UPYUN_MESSAGE_PASSWORD")},default:t.password||"",required:!0},{name:"url",type:"input",get alias(){return e.i18n.translate("PICBED_UPYUN_URL")},get message(){return e.i18n.translate("PICBED_UPYUN_MESSAGE_URL")},default:t.url||"",required:!0},{name:"options",type:"input",get prefix(){return e.i18n.translate("PICBED_UPYUN_OPTIONS")},get alias(){return e.i18n.translate("PICBED_UPYUN_OPTIONS")},get message(){return e.i18n.translate("PICBED_UPYUN_MESSAGE_OPTIONS")},default:t.options||"",required:!1},{name:"path",type:"input",get prefix(){return e.i18n.translate("PICBED_UPYUN_PATH")},get alias(){return e.i18n.translate("PICBED_UPYUN_PATH")},get message(){return e.i18n.translate("PICBED_UPYUN_MESSAGE_PATH")},default:t.path||"",required:!1}]};const $t=()=>({register(e){!function(e){e.helper.uploader.register("aliyun",{get name(){return e.i18n.translate("PICBED_ALICLOUD")},handle:wt,config:Bt})}(e),function(e){e.helper.uploader.register("tcyun",{get name(){return e.i18n.translate("PICBED_TENCENTCLOUD")},handle:It,config:Ct})}(e),function(e){e.helper.uploader.register("smms",{get name(){return e.i18n.translate("PICBED_SMMS")},handle:Et,config:dt})}(e),function(e){e.helper.uploader.register("github",{get name(){return e.i18n.translate("PICBED_GITHUB")},handle:St,config:Nt})}(e),function(e){e.helper.uploader.register("qiniu",{get name(){return e.i18n.translate("PICBED_QINIU")},handle:Ut,config:yt})}(e),function(e){e.helper.uploader.register("imgur",{get name(){return e.i18n.translate("PICBED_IMGUR")},handle:At,config:Ot})}(e),function(e){e.helper.uploader.register("upyun",{get name(){return e.i18n.translate("PICBED_UPYUN")},handle:vt,config:Mt})}(e)}}),Ft=(e,t,n)=>{const r=k(t);return r.real||("string"==typeof n?e.log.warn(`can't get ${n}'s image size`):e.log.warn("can't get image size"),e.log.warn("fallback to 200 * 200")),r};var Ht={handle:async e=>{const t=e.output;return await Promise.all(e.input.map(async(n,r)=>{let i;if(i=Buffer.isBuffer(n)?{success:!0,buffer:n,fileName:"",extname:""}:$(n)?await q(n,e):await Y(n),i.success&&i.buffer){const s=Ft(e,i.buffer,n),o=i.extname||s.extname||".png";t[r]={buffer:i.buffer,fileName:i.fileName||`${d().format("YYYYMMDDHHmmssSSS")}${o}}`,width:s.width,height:s.height,filePath:i.filePath,extname:o,size:i.buffer?.length||0,mimeType:h.lookup(o)||"application/octet-stream"}}else e.log.error(i.reason)})),e.output=t.filter(e=>e),e}};var kt={handle:async e=>(e.output.push(...e.input),e)};class Yt{ctx;list=[];fullList=new Set;pluginMap=new Map;constructor(e){this.ctx=e,this.init()}init(){const n=t.join(this.ctx.baseDir,"package.json");if(!e.existsSync(n)){const t={name:"picgo-plugins",description:"picgo-plugins",repository:"https://github.com/PicGo/PicGo-Core",license:"MIT"};e.writeFileSync(n,JSON.stringify(t),"utf8")}}resolvePlugin(e,n){try{return I.sync(n,{basedir:e.baseDir})}catch(r){return t.join(e.baseDir,"node_modules",n)}}load(){const n=t.join(this.ctx.baseDir,"package.json"),r=t.join(this.ctx.baseDir,"node_modules/");if(!e.existsSync(r))return!1;const i=e.readJSONSync(n),s=Object.keys(i.dependencies||{}),o=Object.keys(i.devDependencies||{}),a=s.concat(o).filter(t=>{if(!/^picgo-plugin-|^@[^/]+\/picgo-plugin-/.test(t))return!1;const n=this.resolvePlugin(this.ctx,t);return e.existsSync(n)});for(const e of a)this.registerPlugin(e);return!0}registerPlugin(e,t){if(e&&"string"==typeof e){this.fullList.add(e);try{if(t){this.list.push(e),ot(e);const n=t(this.ctx);this.pluginMap.set(e,n),n.register(this.ctx)}else if(!0===this.ctx.getConfig(`picgoPlugins.${e}`)||void 0===this.ctx.getConfig(`picgoPlugins.${e}`)){this.list.push(e),ot(e),this.getPlugin(e).register(this.ctx);const t=`picgoPlugins[${e}]`;this.ctx.saveConfig({[t]:!0})}}catch(t){this.pluginMap.delete(e),this.list=this.list.filter(t=>t!==e),this.fullList.delete(e),this.ctx.log.error(t),this.ctx.emit(exports.IBuildInEvent.NOTIFICATION,{title:`Plugin ${e} Load Error`,body:t})}}else this.ctx.log.warn("Please provide valid plugin")}unregisterPlugin(e){this.list=this.list.filter(t=>t!==e),this.fullList.delete(e),this.pluginMap.delete(e),ot(e),this.ctx.helper.uploader.unregister(e),this.ctx.helper.transformer.unregister(e),this.ctx.helper.beforeTransformPlugins.unregister(e),this.ctx.helper.beforeUploadPlugins.unregister(e),this.ctx.helper.afterUploadPlugins.unregister(e),this.ctx.cmd.unregister(e),this.ctx.removeConfig("picgoPlugins",e)}getPlugin(e){if(this.pluginMap.has(e))return this.pluginMap.get(e);const n=t.join(this.ctx.baseDir,"node_modules/"),r=require(n+e)(this.ctx);return this.pluginMap.set(e,r),r}getList(){return this.list}hasPlugin(e){return this.fullList.has(e)}getFullList(){return[...this.fullList]}}const qt="picgo-clipboard-images",Vt={darwin:'-- From https://github.com/mushanshitiancai/vscode-paste-image\nproperty fileTypes : {{«class PNGf», ".png"}}\n\non run argv\n\tif argv is {} then\n\t\treturn ""\n\tend if\n\n\tif ((clipboard info) as string) contains "«class furl»" then\n\t\treturn POSIX path of (the clipboard as «class furl»)\n\telse\n\t\tset imagePath to (item 1 of argv)\n\t\tset theType to getType()\n\n\t\tif theType is not missing value then\n\t\t\ttry\n\t\t\t\tset myFile to (open for access imagePath with write permission)\n\t\t\t\tset eof myFile to 0\n\t\t\t\twrite (the clipboard as (first item of theType)) to myFile\n\t\t\t\tclose access myFile\n\t\t\t\treturn (POSIX path of imagePath)\n\t\t\ton error\n\t\t\t\ttry\n\t\t\t\t\tclose access myFile\n\t\t\t\tend try\n\t\t\t\treturn "no image"\n\t\t\tend try\n\t\telse\n\t\t\treturn "no image"\n\t\tend if\n\tend if\nend run\n\non getType()\n\trepeat with aType in fileTypes\n\t\trepeat with theInfo in (clipboard info)\n\t\t\tif (first item of theInfo) is equal to (first item of aType) then return aType\n\t\tend repeat\n\tend repeat\n\treturn missing value\nend getType\n',win32:'\nparam($imagePath)\n\n# Adapted from https://github.com/octan3/img-clipboard-dump/blob/master/dump-clipboard-png.ps1\n\nAdd-Type -Assembly PresentationCore\n$img = [Windows.Clipboard]::GetImage()\n\nif ($img -eq $null) {\n    "no image"\n    Exit 1\n}\n\nif (-not $imagePath) {\n    "no image"\n    Exit 1\n}\n\n$fcb = new-object Windows.Media.Imaging.FormatConvertedBitmap($img, [Windows.Media.PixelFormats]::Rgb24, $null, 0)\n$stream = [IO.File]::Open($imagePath, "OpenOrCreate")\n$encoder = New-Object Windows.Media.Imaging.PngBitmapEncoder\n$encoder.Frames.Add([Windows.Media.Imaging.BitmapFrame]::Create($fcb)) | out-null\n$encoder.Save($stream) | out-null\n$stream.Dispose() | out-null\n\n$imagePath\n',win10:'# Adapted from https://github.com/octan3/img-clipboard-dump/blob/master/dump-clipboard-png.ps1\nparam($imagePath)\n\n# https://github.com/PowerShell/PowerShell/issues/7233\n# fix the output encoding bug\n[console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding\n\nAdd-Type -Assembly PresentationCore\nfunction main {\n    $img = [Windows.Clipboard]::GetImage()\n\n    if ($img -eq $null) {\n        "no image"\n        Exit 1\n    }\n\n    if (-not $imagePath) {\n        "no image"\n        Exit 1\n    }\n\n    $fcb = new-object Windows.Media.Imaging.FormatConvertedBitmap($img, [Windows.Media.PixelFormats]::Rgb24, $null, 0)\n    $stream = [IO.File]::Open($imagePath, "OpenOrCreate")\n    $encoder = New-Object Windows.Media.Imaging.PngBitmapEncoder\n    $encoder.Frames.Add([Windows.Media.Imaging.BitmapFrame]::Create($fcb)) | out-null\n    $encoder.Save($stream) | out-null\n    $stream.Dispose() | out-null\n\n    $imagePath\n    # fix windows 10 native cmd crash bug when "picgo upload"\n    # https://github.com/PicGo/PicGo-Core/issues/32\n    Exit 1\n}\n\ntry {\n    # For WIN10\n    $file = Get-Clipboard -Format FileDropList\n    if ($file -ne $null) {\n        Convert-Path $file\n        Exit 1\n    }\n} catch {\n    # For WIN7 WIN8 WIN10\n    main\n}\n\nmain',linux:'#!/bin/sh\nif [ "$XDG_SESSION_TYPE" = "x11" ]; then\n  # require xclip(see http://stackoverflow.com/questions/592620/check-if-a-program-exists-from-a-bash-script/677212#677212)\n  command -v xclip >/dev/null 2>&1 || { echo >&1 "no xclip"; exit 1; }\n  # write image in clipboard to file (see http://unix.stackexchange.com/questions/145131/copy-image-from-clipboard-to-file)\n  filePath=`xclip -selection clipboard -o 2>/dev/null | grep ^file:// | cut -c8-`\n  if [ ! -n "$filePath" ] ;then\n    if\n        xclip -selection clipboard -target image/png -o >/dev/null 2>&1\n    then\n        xclip -selection clipboard -target image/png -o >$1 2>/dev/null\n        echo $1\n    else\n        echo "no image"\n    fi\n  else\n    echo $filePath\n  fi\nelif [ "$XDG_SESSION_TYPE" = "wayland" ]; then\n  command -v wl-paste >/dev/null 2>&1 || { echo >&1 "no wl-clipboard"; exit 1; }\n  isImage=`wl-paste --list-types | grep image`\n  if [ -n "$isImage" ]; then\n    wl-paste --type image/png > $1 2>/dev/null\n    echo $1\n  else\n    echo "no image"\n    exit 1\n  fi\nelse\n  # fallback for unsupported session types\n  echo >&2 "Error: Unsupported session type \'$XDG_SESSION_TYPE\'."\n  echo >&2 "Solution: The variable of XDG_SESSION_TYPE must set as \'x11\' or \'wayland\'."\n  exit 1\nfi\n',wsl:'#!/bin/sh\n# grab the paths\nscriptPath=$(echo $0 | awk \'{ print substr( $0, 1, length($0)-6 ) }\')"windows10.ps1"\nimagePath=$(echo $1 | awk \'{ print substr( $0, 1, length($0)-18 ) }\')\nimageName=$(echo $1 | awk \'{ print substr( $0, length($0)-17, length($0) ) }\')\n\n# run the powershell script\nres=$(powershell.exe -noprofile -noninteractive -nologo -sta -executionpolicy unrestricted -file $(wslpath -w $scriptPath) $(wslpath -w $imagePath)"\\\\"$imageName)\n\n# note that there is a return symbol in powershell result\nnoImage=$(echo "no image\\r")\n\n# check whether image exists\nif [ "$res" = "$noImage" ] ;then\n    echo "no image"\nelse\n    echo $(wslpath -u -a "${res}")\nfi\n'},Kt={darwin:"mac.applescript",win32:"windows.ps1",win10:"windows10.ps1",linux:"linux.sh",wsl:"wsl.sh"};const jt=async n=>{!function(n){const r=t.join(n.baseDir,qt);e.existsSync(r)||e.mkdirSync(r)}(n);const i=t.join(n.baseDir,qt,`${d().format("YYYYMMDDHHmmssSSS")}.png`);return await new Promise((s,o)=>{const a=(()=>{const e=process.platform;if(m)return"wsl";if("win32"===e)return"10"===r.release().split(".")[0]?"win10":"win32";return"darwin"===e?"darwin":"linux"})(),c=t.join(n.baseDir,Kt[a]);let l;e.existsSync(c)||e.writeFileSync(c,Vt[a],"utf8"),l="darwin"===a?C.spawn("osascript",[c,i]):"win32"===a||"win10"===a?C.spawn("powershell",["-noprofile","-noninteractive","-nologo","-sta","-executionpolicy","unrestricted","-file",c,i]):C.spawn("sh",[c,i]),l.stdout.on("data",r=>{if("linux"===a&&"no xclip or wl-clipboard"===r.toString().trim())return n.emit(exports.IBuildInEvent.NOTIFICATION,{title:"xclip or wl-clipboard not found",body:"Please install xclip(for x11) or wl-clipboard(for wayland) before run picgo"}),o(new Error("Please install xclip(for x11) or wl-clipboard(for wayland) before run picgo"));const c=r.toString().trim();let l=!1;if(t.basename(c)!==t.basename(i)&&e.existsSync(c)&&(l=!0),"no image"!==c&&!e.existsSync(c))return o(new Error(`Can't find ${c}`));s({imgPath:c,shouldKeepAfterUploading:l})})})},Wt=new n.EventEmitter,Qt=new N.Agent({maxVersion:"TLSv1.2",minVersion:"TLSv1.2"});function zt(e,t,n){"object"==typeof n&&"value"in n&&"options"in n?e.append(t,n.value,n.options):e.append(t,n)}function Jt(e){return{...e,statusCode:e.status,body:e.data}}function Xt(e){const t={method:e?.config?.method?.toUpperCase()||"",url:e?.config?.url||"",statusCode:e?.response?.status||0,message:e?.message||"",stack:e?.stack||{},response:{status:e?.response?.status||0,statusCode:e?.response?.status||0,body:e?.response?.data||""}};return Promise.reject(t)}class Zt{ctx;proxy="";options={};constructor(e){this.ctx=e,this.init(),Wt.on(exports.IBusEvent.CONFIG_CHANGE,e=>{switch(e.configName){case"picBed":e.value?.proxy&&(this.proxy=e.value.proxy);break;case"picBed.proxy":this.proxy=e.value}})}init(){const e=this.ctx.getConfig("picBed.proxy");e&&(this.proxy=e)}handleProxy(){if(this.proxy)try{const e=new a.URL(this.proxy);return{host:e.hostname,port:parseInt(e.port||"0",10),protocol:e.protocol}}catch(e){}return!1}request(e){this.options.proxy=this.handleProxy(),this.options.headers=e.headers||{},this.options.maxBodyLength=1/0,this.options.maxContentLength=1/0,this.options.proxy&&e.url?.startsWith("https://")?(this.options.httpsAgent=L.httpsOverHttp({proxy:{host:this.options.proxy.host,port:this.options.proxy.port}}),this.options.proxy=!1):this.options.httpsAgent=Qt;const t=u.create(this.options);t.interceptors.response.use(Jt,Xt);const n=function(e){let t=!1;const n={...e,url:e.url||"",headers:e.headers||{}};if(e.proxy){let r=e.proxy;if("string"==typeof r){try{r=new a.URL(e.proxy)}catch(e){r=!1,n.proxy=!1,console.error(e)}t=!0}r&&(e.url?.startsWith("https://")?(n.proxy=!1,n.httpsAgent=L.httpsOverHttp({proxy:{host:r?.hostname,port:parseInt(r?.port,10)}})):n.proxy={host:r.hostname,port:parseInt(r.port,10),protocol:"http"})}if("formData"in e){const r=new S;for(const t in e.formData)zt(r,t,e.formData[t]);n.data=r,n.headers=Object.assign(n.headers||{},r.getHeaders()),t=!0,delete n.formData}return"body"in e&&(n.data=e.body,t=!0,delete n.body),"qs"in e&&(n.params=e.qs,t=!0),n.__isOldOptions=t,n}(e);return t.interceptors.request.use(function(e){let t="";return e?.headers?.contentType?(t=e.headers.contentType,delete e.headers.contentType):e?.headers?.ContentType?(t=e.headers.ContentType,delete e.headers.ContentType):e?.headers?.["content-type"]&&(t=e.headers["content-type"],delete e.headers["content-type"]),""!==t&&e.headers&&(e.headers["Content-Type"]=t),e}),"resolveWithFullResponse"in e&&e.resolveWithFullResponse?t.request(n):t.request(n).then(t=>n.__isOldOptions?"json"in e?e.json?t.data:void 0:JSON.stringify(t.data):t.data)}}class en{ctx;db;constructor(e){if(this.ctx=e,this.db=new P.JSONStore(this.ctx.configPath),!this.db.has("picBed"))try{this.db.set("picBed",{uploader:"smms",current:"smms"})}catch(e){throw this.ctx.log.error(e),e}if(!this.db.has("picgoPlugins"))try{this.db.set("picgoPlugins",{})}catch(e){throw this.ctx.log.error(e),e}}read(e){return this.db.read(e)}get(e=""){return this.read(!0),this.db.get(e)}set(e,t){return this.read(!0),this.db.set(e,t)}has(e){return this.read(!0),this.db.has(e)}unset(e,t){return this.read(!0),this.db.unset(e,t)}saveConfig(e){Object.keys(e).forEach(t=>{this.set(t,e[t])})}removeConfig(e){Object.keys(e).forEach(t=>{this.unset(t,e[t])})}}class tn{ctx;constructor(e){this.ctx=e}async install(e,t={},n){const r=[],i=e.map(e=>nn(this.ctx,e)).filter(e=>this.ctx.pluginLoader.hasPlugin(e.pkgName)?(r.push(e.pkgName),this.ctx.log.success(`PicGo has already installed ${e.pkgName}`),!1):!!e.success),s=i.map(e=>e.fullName),o=i.map(e=>e.pkgName);if(s.length>0){const e=await this.execCommand("install",s,this.ctx.baseDir,t,n);if(e.code){const t=this.ctx.i18n.translate("PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_REASON",{code:`${e.code}`,data:e.data});this.ctx.log.error(t),this.ctx.emit("installFailed",{title:this.ctx.i18n.translate("PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED"),body:t});return{success:!1,body:t}}o.forEach(e=>{this.ctx.pluginLoader.registerPlugin(e)}),this.ctx.log.success(this.ctx.i18n.translate("PLUGIN_HANDLER_PLUGIN_INSTALL_SUCCESS")),this.ctx.emit("installSuccess",{title:this.ctx.i18n.translate("PLUGIN_HANDLER_PLUGIN_INSTALL_SUCCESS"),body:[...o,...r]});return{success:!0,body:[...o,...r]}}if(0===r.length){const e=this.ctx.i18n.translate("PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_VALID");this.ctx.log.error(e),this.ctx.emit("installFailed",{title:this.ctx.i18n.translate("PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED"),body:e});return{success:!1,body:e}}this.ctx.log.success(this.ctx.i18n.translate("PLUGIN_HANDLER_PLUGIN_INSTALL_SUCCESS")),this.ctx.emit("installSuccess",{title:this.ctx.i18n.translate("PLUGIN_HANDLER_PLUGIN_INSTALL_SUCCESS"),body:[...o,...r]});return{success:!0,body:[...o,...r]}}async uninstall(e,t){const n=e.map(e=>nn(this.ctx,e)).filter(e=>e.success).map(e=>e.pkgName);if(n.length>0){const e=await this.execCommand("uninstall",n,this.ctx.baseDir,void 0,t);if(e.code){const t=this.ctx.i18n.translate("PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_REASON",{code:`${e.code}`,data:e.data});this.ctx.log.error(t),this.ctx.emit("uninstallFailed",{title:this.ctx.i18n.translate("PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED"),body:t});return{success:!1,body:t}}n.forEach(e=>{this.ctx.pluginLoader.unregisterPlugin(e)}),this.ctx.log.success(this.ctx.i18n.translate("PLUGIN_HANDLER_PLUGIN_UNINSTALL_SUCCESS")),this.ctx.emit("uninstallSuccess",{title:this.ctx.i18n.translate("PLUGIN_HANDLER_PLUGIN_UNINSTALL_SUCCESS"),body:n});return{success:!0,body:n}}{const e=this.ctx.i18n.translate("PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_VALID");this.ctx.log.error(e),this.ctx.emit("uninstallFailed",{title:this.ctx.i18n.translate("PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED"),body:e});return{success:!1,body:e}}}async update(e,t={},n){const r=e.map(e=>nn(this.ctx,e)).filter(e=>e.success).map(e=>e.pkgName);if(r.length>0){const e=await this.execCommand("update",r,this.ctx.baseDir,t,n);if(e.code){const t=this.ctx.i18n.translate("PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_REASON",{code:`${e.code}`,data:e.data});this.ctx.log.error(t),this.ctx.emit("updateFailed",{title:this.ctx.i18n.translate("PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED"),body:t});return{success:!1,body:t}}this.ctx.log.success(this.ctx.i18n.translate("PLUGIN_HANDLER_PLUGIN_UPDATE_SUCCESS")),this.ctx.emit("updateSuccess",{title:this.ctx.i18n.translate("PLUGIN_HANDLER_PLUGIN_UPDATE_SUCCESS"),body:r});return{success:!0,body:r}}{const e=this.ctx.i18n.translate("PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_VALID");this.ctx.log.error(e),this.ctx.emit("updateFailed",{title:this.ctx.i18n.translate("PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED"),body:e});return{success:!1,body:e}}}async execCommand(e,t,n,r={},i={}){const s=r.npmRegistry||this.ctx.getConfig("settings.npmRegistry"),o=r.npmProxy||this.ctx.getConfig("settings.npmProxy");return await new Promise(r=>{let a=[e].concat(t).concat("--color=always").concat("--save");s&&(a=a.concat(`--registry=${s}`)),o&&(a=a.concat(`--proxy=${o}`));try{const e=D("npm",a,{cwd:n,env:Object.assign({},process.env,i)});let t="";e.stdout?.on("data",e=>{t+=e}).pipe(process.stdout),e.stderr?.on("data",e=>{t+=e}).pipe(process.stderr),e.on("close",e=>{r(e?{code:e,data:t}:{code:0,data:t})}),e.on("error",e=>{this.ctx.log.error(e),this.ctx.log.error("NPM is not installed"),this.ctx.emit(exports.IBuildInEvent.FAILED,"NPM is not installed")})}catch(e){this.ctx.log.error(e),this.ctx.emit(exports.IBuildInEvent.FAILED,e)}})}}const nn=(e,t)=>{const n={success:!1,fullName:"",pkgName:""},r=W(t,e.log);if(!r)return n;const i=Q(r,e.log);return i?{success:!0,fullName:r,pkgName:i}:n},rn={"zh-CN":{UPLOAD_FAILED:"上传失败",CHECK_SETTINGS:"请检查你的配置项是否正确",CHECK_SETTINGS_AND_NETWORK:"请检查你的配置项以及网络",UPLOAD_FAILED_REASON:"错误码：${code}，请打开浏览器粘贴地址查看相关原因",SERVER_ERROR:"服务端出错，请重试",AUTH_FAILED:"认证失败",CLOUD_LOGIN_CANCELLED:"登录已取消",CLOUD_LOGIN_IN_PROGRESS:"登录正在进行中",CLOUD_LOGIN_INVALID_TOKEN:"无效的 token",CLOUD_LOGIN_SUCCESS:"登录成功！",CLOUD_LOGOUT_SUCCESS:"退出登录成功！",CLOUD_LOGIN_SERVER_START_FAILED:"启动登录服务失败",CLOUD_LOGIN_OPEN_BROWSER_FAILED:"无法自动打开浏览器：${message}",CLOUD_LOGIN_OPEN_BROWSER_TIP:"请在浏览器中打开该链接：${url}",CLOUD_LOGIN_STATE_MISMATCH_WARN:"State 校验失败或缺失，请求已拦截",CLOUD_LOGIN_STATE_INVALID:"State 无效，请重新登录。",CLOUD_LOGIN_TOKEN_MISSING:"回调中缺少 token。",CLOUD_LOGIN_CODE_MISSING:"回调中缺少 code。",CLOUD_LOGIN_EXCHANGE_FAILED:"登录 code 交换失败。",CLOUD_LOGIN_NOT_IN_PROGRESS:"当前没有进行中的登录流程。",CLOUD_LOGIN_PAGE_TITLE:"PicGo 登录",CLOUD_LOGIN_RESULT_SUCCESS_TITLE:"授权成功！",CLOUD_LOGIN_RESULT_FAILED_TITLE:"授权失败",CLOUD_LOGIN_RESULT_SUCCESS_MESSAGE:"你可以关闭此窗口并返回 PicGo。",SERVER_INVALID_JSON_BODY:"JSON 请求体无效",SERVER_INVALID_REQUEST_BODY_LIST_REQUIRED:"请求体无效：需要 { list: string[] }",SERVER_FORMDATA_NO_FILES_IN_FILES_FIELD:"form-data 的 files 字段未找到文件",SERVER_FORMDATA_FILES_MUST_BE_FILES:"form-data 无效：files 必须是文件",SERVER_AUTH_ENABLED:"[PicGo Server] 认证已启用。",SERVER_AUTH_DISABLED_WARNING:"[PicGo Server] 警告：认证已关闭，任何人都可以上传图片。",SERVER_AUTH_UNAUTHORIZED_REQUEST:"[PicGo Server] 未授权的请求，来源 ${ip}",SERVER_AUTH_QUERY_SECRET_WARNING:"[PicGo Server] 警告：通过 URL 参数传递 secret 不安全，请使用 Authorization Header。",URL_REWRITE_EMPTY_RESULT:"URL 重写结果为空，请检查你的规则配置",PICBED_SMMS:"SM.MS(S.EE)",PICBED_SMMS_TOKEN:"设定Token",PICBED_SMMS_BACKUP_DOMAIN:"备用上传域名",PICBED_SMMS_MESSAGE_BACKUP_DOMAIN:"例如 sm.ms",PICBED_ALICLOUD:"阿里云OSS",PICBED_ALICLOUD_ACCESSKEYID:"设定KeyId",PICBED_ALICLOUD_ACCESSKEYSECRET:"设定KeySecret",PICBED_ALICLOUD_BUCKET:"设定Bucket",PICBED_ALICLOUD_AREA:"设定存储区域",PICBED_ALICLOUD_PATH:"设定存储路径",PICBED_ALICLOUD_CUSTOMURL:"设定自定义域名",PICBED_ALICLOUD_OPTIONS:"设定网址后缀",PICBED_ALICLOUD_MESSAGE_AREA:"例如：oss-cn-beijing",PICBED_ALICLOUD_MESSAGE_PATH:"例如：test/",PICBED_ALICLOUD_MESSAGE_OPTIONS:"例如：?x-oss-process=xxx",PICBED_ALICLOUD_MESSAGE_CUSTOMURL:"例如：https://test.com",PICBED_TENCENTCLOUD:"腾讯云COS",PICBED_TENCENTCLOUD_VERSION:"COS版本",PICBED_TENCENTCLOUD_SECRETID:"设定SecretId",PICBED_TENCENTCLOUD_SECRETKEY:"设定SecretKey",PICBED_TENCENTCLOUD_APPID:"设定AppId",PICBED_TENCENTCLOUD_BUCKET:"设定Bucket",PICBED_TENCENTCLOUD_AREA:"设定存储区域",PICBED_TENCENTCLOUD_ENDPOINT:"设定Endpoint",PICBED_TENCENTCLOUD_PATH:"设定存储路径",PICBED_TENCENTCLOUD_OPTIONS:"设定网址后缀",PICBED_TENCENTCLOUD_CUSTOMURL:"设定自定义域名",PICBED_TENCENTCLOUD_SLIM:"极智压缩",PICBED_TENCENTCLOUD_SLIM_TIP:"图片极智压缩，详情请参考[文档说明](https://cloud.tencent.com/document/product/436/49259)",PICBED_TENCENTCLOUD_SLIM_CONFIRM:"开启",PICBED_TENCENTCLOUD_SLIM_CANCEL:"关闭",PICBED_TENCENTCLOUD_MESSAGE_APPID:"例如：1234567890",PICBED_TENCENTCLOUD_MESSAGE_AREA:"例如：ap-beijing",PICBED_TENCENTCLOUD_MESSAGE_ENDPOINT:"例如：cos-internal.accelerate.tencentcos.cn",PICBED_TENCENTCLOUD_MESSAGE_PATH:"例如：test/",PICBED_TENCENTCLOUD_MESSAGE_CUSTOMURL:"例如：https://test.com",PICBED_TENCENTCLOUD_MESSAGE_OPTIONS:"例如：?imageMogr2",PICBED_GITHUB:"GitHub",PICBED_GITHUB_TOKEN:"设定Token",PICBED_GITHUB_REPO:"设定仓库名",PICBED_GITHUB_PATH:"设定存储路径",PICBED_GITHUB_BRANCH:"设定分支名",PICBED_GITHUB_CUSTOMURL:"设定自定义域名",PICBED_GITHUB_MESSAGE_REPO:"格式：username/repo",PICBED_GITHUB_MESSAGE_BRANCH:"例如：main",PICBED_GITHUB_MESSAGE_PATH:"例如：test/",PICBED_GITHUB_MESSAGE_CUSTOMURL:"例如：https://test.com",PICBED_QINIU:"七牛云",PICBED_QINIU_ACCESSKEY:"设定AccessKey",PICBED_QINIU_SECRETKEY:"设定SecretKey",PICBED_QINIU_BUCKET:"设定Bucket",PICBED_QINIU_PATH:"设定存储路径",PICBED_QINIU_URL:"设定访问网址",PICBED_QINIU_OPTIONS:"设定网址后缀",PICBED_QINIU_AREA:"设定存储区域",PICBED_QINIU_MESSAGE_PATH:"例如：test/",PICBED_QINIU_MESSAGE_AREA:"例如：z0",PICBED_QINIU_MESSAGE_OPTIONS:"例如：?imageslim",PICBED_QINIU_MESSAGE_URL:"例如：https://xxx.yyy.glb.clouddn.com",PICBED_IMGUR:"Imgur",PICBED_IMGUR_CLIENTID:"设定ClientId",PICBED_IMGUR_PROXY:"设定代理",PICBED_IMGUR_MESSAGE_PROXY:"例如：http://127.0.0.1:1080",PICBED_UPYUN:"又拍云",PICBED_UPYUN_BUCKET:"设定Bucket",PICBED_UPYUN_OPERATOR:"设定操作员",PICBED_UPYUN_PASSWORD:"设定操作员密码",PICBED_UPYUN_PATH:"设定存储路径",PICBED_UPYUN_URL:"设定加速域名",PICBED_UPYUN_OPTIONS:"设定网址后缀",PICBED_UPYUN_MESSAGE_OPERATOR:"例如：me",PICBED_UPYUN_MESSAGE_PASSWORD:"输入操作员密码",PICBED_UPYUN_MESSAGE_URL:"例如：http://xxx.test.upcdn.net",PICBED_UPYUN_MESSAGE_OPTIONS:"例如：!imgslim",PICBED_UPYUN_MESSAGE_PATH:"例如：test/",PLUGIN_HANDLER_PLUGIN_INSTALL_SUCCESS:"插件安装成功",PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED:"插件安装失败",PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_REASON:"插件安装失败，失败码为${code}，错误日志为 \n ${data}",PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_PATH:"插件安装失败，请输入合法插件名或合法安装路径",PLUGIN_HANDLER_PLUGIN_UNINSTALL_SUCCESS:"插件卸载成功",PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED:"插件卸载失败",PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_REASON:"插件卸载失败，失败码为${code}，错误日志为 \n ${data}",PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_VALID:"插件卸载失败，请输入合法插件名",PLUGIN_HANDLER_PLUGIN_UPDATE_SUCCESS:"插件更新成功",PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED:"插件更新失败",PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_REASON:"插件更新失败，失败码为${code}，错误日志为 \n ${data}",PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_VALID:"插件更新失败，请输入合法插件名",CONFIG_SYNC_INVALID_ENCRYPTION_METHOD:'配置无效：settings.picgoCloud.encryptionMethod 必须是 "auto"、"sse" 或 "e2ee" 之一，当前为：${value}',CONFIG_SYNC_ENCRYPTION_METHOD_E2EE:"端到端加密",CONFIG_SYNC_ENCRYPTION_METHOD_SSE:"服务端加密",CONFIG_SYNC_ENCRYPTION_SWITCH_TITLE:"确认切换加密方式吗？",CONFIG_SYNC_ENCRYPTION_SWITCH_BODY:"您正在从“${from}”切换为“${to}”。\n\n注意：切换加密模式将清空您所有的云端历史版本记录。\n这是因为旧的历史版本无法在新模式下被解密或验证。\n切换后，系统将立即为您创建一份新的备份作为起点。",CONFIG_SYNC_ENCRYPTION_SWITCH_CONFIRM:"确认切换并清空历史",CONFIG_SYNC_ENCRYPTION_SWITCH_CANCEL:"取消",CONFIG_SYNC_ENCRYPTION_SWITCH_CANCELLED:"已取消切换加密方式",CONFIG_SYNC_ENCRYPTION_SWITCH_MISSING_HANDLER:"需要提供加密方式切换确认处理器"},"zh-TW":{UPLOAD_FAILED:"上傳失敗",CHECK_SETTINGS:"請檢查你的設定是否正確",CHECK_SETTINGS_AND_NETWORK:"請檢查你的設定及網路",UPLOAD_FAILED_REASON:"錯誤碼：${code}，請打開瀏覽器貼上地址查看相關原因",SERVER_ERROR:"伺服器出錯，請重試",AUTH_FAILED:"認證失敗",CLOUD_LOGIN_CANCELLED:"登入已取消",CLOUD_LOGIN_IN_PROGRESS:"登入正在進行中",CLOUD_LOGIN_INVALID_TOKEN:"無效的 token",CLOUD_LOGIN_SUCCESS:"登入成功！",CLOUD_LOGOUT_SUCCESS:"登出成功！",CLOUD_LOGIN_SERVER_START_FAILED:"啟動登入服務失敗",CLOUD_LOGIN_OPEN_BROWSER_FAILED:"無法自動打開瀏覽器：${message}",CLOUD_LOGIN_OPEN_BROWSER_TIP:"請在瀏覽器中打開此連結：${url}",CLOUD_LOGIN_STATE_MISMATCH_WARN:"State 驗證失敗或缺失，請求已攔截",CLOUD_LOGIN_STATE_INVALID:"State 無效，請重新登入。",CLOUD_LOGIN_TOKEN_MISSING:"回呼中缺少 token。",CLOUD_LOGIN_CODE_MISSING:"回呼中缺少 code。",CLOUD_LOGIN_EXCHANGE_FAILED:"登入 code 交換失敗。",CLOUD_LOGIN_NOT_IN_PROGRESS:"目前沒有進行中的登入流程。",CLOUD_LOGIN_PAGE_TITLE:"PicGo 登入",CLOUD_LOGIN_RESULT_SUCCESS_TITLE:"授權成功！",CLOUD_LOGIN_RESULT_FAILED_TITLE:"授權失敗",CLOUD_LOGIN_RESULT_SUCCESS_MESSAGE:"你可以關閉此視窗並返回 PicGo。",SERVER_INVALID_JSON_BODY:"JSON 請求內容無效",SERVER_INVALID_REQUEST_BODY_LIST_REQUIRED:"請求內容無效：需要 { list: string[] }",SERVER_FORMDATA_NO_FILES_IN_FILES_FIELD:"form-data 的 files 欄位未找到檔案",SERVER_FORMDATA_FILES_MUST_BE_FILES:"form-data 無效：files 必須是檔案",SERVER_AUTH_ENABLED:"[PicGo Server] 認證已啟用。",SERVER_AUTH_DISABLED_WARNING:"[PicGo Server] 警告：認證已關閉，任何人都可以上傳圖片。",SERVER_AUTH_UNAUTHORIZED_REQUEST:"[PicGo Server] 未授權的請求，來源 ${ip}",SERVER_AUTH_QUERY_SECRET_WARNING:"[PicGo Server] 警告：透過 URL 參數傳遞 secret 不安全，請使用 Authorization Header。",URL_REWRITE_EMPTY_RESULT:"URL 重寫結果為空，請檢查你的規則設定",PICBED_SMMS:"SM.MS(S.EE)",PICBED_SMMS_TOKEN:"設定Token",PICBED_SMMS_BACKUP_DOMAIN:"備用上傳網址",PICBED_SMMS_MESSAGE_BACKUP_DOMAIN:"例如 sm.ms",PICBED_ALICLOUD:"阿里云OSS",PICBED_ALICLOUD_ACCESSKEYID:"設定KeyId",PICBED_ALICLOUD_ACCESSKEYSECRET:"設定KeySecret",PICBED_ALICLOUD_BUCKET:"設定Bucket",PICBED_ALICLOUD_AREA:"設定儲存區域",PICBED_ALICLOUD_PATH:"設定儲存路徑",PICBED_ALICLOUD_CUSTOMURL:"設定自訂網址",PICBED_ALICLOUD_OPTIONS:"設定網址後綴",PICBED_ALICLOUD_MESSAGE_AREA:"例如：oss-cn-beijing",PICBED_ALICLOUD_MESSAGE_PATH:"例如：test/",PICBED_ALICLOUD_MESSAGE_OPTIONS:"例如：?x-oss-process=xxx",PICBED_ALICLOUD_MESSAGE_CUSTOMURL:"例如：https://test.com",PICBED_TENCENTCLOUD:"騰訊云COS",PICBED_TENCENTCLOUD_VERSION:"COS版本",PICBED_TENCENTCLOUD_SECRETID:"設定SecretId",PICBED_TENCENTCLOUD_SECRETKEY:"設定SecretKey",PICBED_TENCENTCLOUD_APPID:"設定AppId",PICBED_TENCENTCLOUD_BUCKET:"設定Bucket",PICBED_TENCENTCLOUD_AREA:"設定儲存區域",PICBED_TENCENTCLOUD_ENDPOINT:"設定Endpoint",PICBED_TENCENTCLOUD_PATH:"設定儲存路徑",PICBED_TENCENTCLOUD_OPTIONS:"設定網址後綴",PICBED_TENCENTCLOUD_SLIM:"極智壓縮",PICBED_TENCENTCLOUD_SLIM_CANCEL:"關閉",PICBED_TENCENTCLOUD_SLIM_CONFIRM:"開啓",PICBED_TENCENTCLOUD_SLIM_TIP:"圖片極智壓縮，詳情請參考[文檔說明](https://cloud.tencent.com/document/product/436/49259)",PICBED_TENCENTCLOUD_CUSTOMURL:"設定自訂網址",PICBED_TENCENTCLOUD_MESSAGE_APPID:"例如：1234567890",PICBED_TENCENTCLOUD_MESSAGE_AREA:"例如：ap-beijing",PICBED_TENCENTCLOUD_MESSAGE_ENDPOINT:"例如：cos-internal.accelerate.tencentcos.cn",PICBED_TENCENTCLOUD_MESSAGE_PATH:"例如：test/",PICBED_TENCENTCLOUD_MESSAGE_CUSTOMURL:"例如：https://test.com",PICBED_TENCENTCLOUD_MESSAGE_OPTIONS:"例如：?imageMogr2",PICBED_GITHUB:"GitHub",PICBED_GITHUB_TOKEN:"設定Token",PICBED_GITHUB_REPO:"設定倉庫名稱",PICBED_GITHUB_PATH:"設定儲存路徑",PICBED_GITHUB_BRANCH:"設定分支名稱",PICBED_GITHUB_CUSTOMURL:"設定自訂網址",PICBED_GITHUB_MESSAGE_REPO:"格式：username/repo",PICBED_GITHUB_MESSAGE_BRANCH:"例如：main",PICBED_GITHUB_MESSAGE_PATH:"例如：test/",PICBED_GITHUB_MESSAGE_CUSTOMURL:"例如：https://test.com",PICBED_QINIU:"七牛云",PICBED_QINIU_ACCESSKEY:"設定AccessKey",PICBED_QINIU_SECRETKEY:"設定SecretKey",PICBED_QINIU_BUCKET:"設定Bucket",PICBED_QINIU_PATH:"設定儲存路徑",PICBED_QINIU_URL:"設定訪問網址",PICBED_QINIU_OPTIONS:"設定網址後綴",PICBED_QINIU_AREA:"設定儲存區域",PICBED_QINIU_MESSAGE_PATH:"例如：test/",PICBED_QINIU_MESSAGE_AREA:"例如：z0",PICBED_QINIU_MESSAGE_OPTIONS:"例如：?imageslim",PICBED_QINIU_MESSAGE_URL:"例如：https://xxx.yyy.glb.clouddn.com",PICBED_IMGUR:"Imgur",PICBED_IMGUR_CLIENTID:"設定ClientId",PICBED_IMGUR_PROXY:"設定PROXY",PICBED_IMGUR_MESSAGE_PROXY:"例如：http://127.0.0.1:1080",PICBED_UPYUN:"又拍云",PICBED_UPYUN_BUCKET:"設定Bucket",PICBED_UPYUN_OPERATOR:"設定操作員",PICBED_UPYUN_PASSWORD:"設定操作員密碼",PICBED_UPYUN_PATH:"設定儲存路徑",PICBED_UPYUN_URL:"設定加速網址",PICBED_UPYUN_OPTIONS:"設定網址後綴",PICBED_UPYUN_MESSAGE_OPERATOR:"例如：me",PICBED_UPYUN_MESSAGE_PASSWORD:"輸入操作員密碼",PICBED_UPYUN_MESSAGE_URL:"例如：http://xxx.test.upcdn.net",PICBED_UPYUN_MESSAGE_OPTIONS:"例如：!imgslim",PICBED_UPYUN_MESSAGE_PATH:"例如：test/",PLUGIN_HANDLER_PLUGIN_INSTALL_SUCCESS:"插件安裝成功",PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED:"插件安裝失敗",PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_REASON:"插件安裝失敗，失敗碼為${code}，錯誤紀錄為 \n ${data}",PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_PATH:"插件安裝失敗，請輸入正確的插件名稱或正確的安裝路徑",PLUGIN_HANDLER_PLUGIN_UNINSTALL_SUCCESS:"插件卸載成功",PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED:"插件卸載失敗",PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_REASON:"插件卸載失敗，失敗碼為${code}，錯誤紀錄為 \n ${data}",PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_VALID:"插件卸載失敗，請輸入正確的插件名稱",PLUGIN_HANDLER_PLUGIN_UPDATE_SUCCESS:"插件更新成功",PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED:"插件更新失敗",PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_REASON:"插件更新失敗，失敗碼為${code}，錯誤紀錄為 \n ${data}",PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_VALID:"插件更新失敗，請輸入正確的插件名稱",CONFIG_SYNC_INVALID_ENCRYPTION_METHOD:"設定無效：settings.picgoCloud.encryptionMethod 必須是「auto」、「sse」或「e2ee」之一，目前為：${value}",CONFIG_SYNC_ENCRYPTION_METHOD_E2EE:"端對端加密",CONFIG_SYNC_ENCRYPTION_METHOD_SSE:"伺服器端加密",CONFIG_SYNC_ENCRYPTION_SWITCH_TITLE:"確認切換加密方式嗎？",CONFIG_SYNC_ENCRYPTION_SWITCH_BODY:"您正在從「${from}」切換為「${to}」。\n\n注意：切換加密模式將清空您所有的雲端歷史版本記錄。\n這是因為舊的歷史版本無法在新模式下被解密或驗證。\n切換後，系統將立即為您建立一份新的備份作為起點。",CONFIG_SYNC_ENCRYPTION_SWITCH_CONFIRM:"確認切換並清空歷史",CONFIG_SYNC_ENCRYPTION_SWITCH_CANCEL:"取消",CONFIG_SYNC_ENCRYPTION_SWITCH_CANCELLED:"已取消切換加密方式",CONFIG_SYNC_ENCRYPTION_SWITCH_MISSING_HANDLER:"需要提供加密方式切換確認處理器"},en:{UPLOAD_FAILED:"Upload failed",CHECK_SETTINGS:"Please check your settings",CHECK_SETTINGS_AND_NETWORK:"Please check your settings and network",UPLOAD_FAILED_REASON:"Error code: ${code}, please open the browser and paste the address to see the reason",SERVER_ERROR:"Server error, please try again later",AUTH_FAILED:"Authentication failed",CLOUD_LOGIN_CANCELLED:"Login cancelled",CLOUD_LOGIN_IN_PROGRESS:"Login is already in progress",CLOUD_LOGIN_INVALID_TOKEN:"Invalid token",CLOUD_LOGIN_SUCCESS:"Login success!",CLOUD_LOGOUT_SUCCESS:"Logout success!",CLOUD_LOGIN_SERVER_START_FAILED:"Failed to start PicGo server for login",CLOUD_LOGIN_OPEN_BROWSER_FAILED:"Failed to open browser automatically: ${message}",CLOUD_LOGIN_OPEN_BROWSER_TIP:"Please open this url in browser: ${url}",CLOUD_LOGIN_STATE_MISMATCH_WARN:"State mismatch or missing. Request blocked.",CLOUD_LOGIN_STATE_INVALID:"Invalid state. Please try logging in again.",CLOUD_LOGIN_TOKEN_MISSING:"Token missing in callback.",CLOUD_LOGIN_CODE_MISSING:"Code missing in callback.",CLOUD_LOGIN_EXCHANGE_FAILED:"Failed to exchange login code.",CLOUD_LOGIN_NOT_IN_PROGRESS:"Login flow is not in progress.",CLOUD_LOGIN_PAGE_TITLE:"PicGo Auth",CLOUD_LOGIN_RESULT_SUCCESS_TITLE:"Authorization Successful!",CLOUD_LOGIN_RESULT_FAILED_TITLE:"Authorization Failed",CLOUD_LOGIN_RESULT_SUCCESS_MESSAGE:"You can now close this window and return to PicGo.",SERVER_INVALID_JSON_BODY:"Invalid JSON body",SERVER_INVALID_REQUEST_BODY_LIST_REQUIRED:"Invalid request body: { list: string[] } required",SERVER_FORMDATA_NO_FILES_IN_FILES_FIELD:"No files found in form-data: files",SERVER_FORMDATA_FILES_MUST_BE_FILES:"Invalid form-data: files must be file(s)",SERVER_AUTH_ENABLED:"[PicGo Server] Authentication enabled.",SERVER_AUTH_DISABLED_WARNING:"[PicGo Server] Warning: Authentication disabled. Anyone can upload images.",SERVER_AUTH_UNAUTHORIZED_REQUEST:"[PicGo Server] Unauthorized request from ${ip}",SERVER_AUTH_QUERY_SECRET_WARNING:"[PicGo Server] Warning: Passing secret via URL query is insecure. Please use Authorization header.",URL_REWRITE_EMPTY_RESULT:"URL rewrite produced an empty result, please check your rule config",PICBED_SMMS:"SM.MS(S.EE)",PICBED_SMMS_TOKEN:"Set Token",PICBED_SMMS_BACKUP_DOMAIN:"Set Backup Upload Domain",PICBED_SMMS_MESSAGE_BACKUP_DOMAIN:"Ex. sm.ms",PICBED_ALICLOUD:"Ali Cloud",PICBED_ALICLOUD_ACCESSKEYID:"Set KeyId",PICBED_ALICLOUD_ACCESSKEYSECRET:"Set KeySecret",PICBED_ALICLOUD_BUCKET:"Set Bucket",PICBED_ALICLOUD_AREA:"Set Area",PICBED_ALICLOUD_PATH:"Set Path",PICBED_ALICLOUD_CUSTOMURL:"Set Custom URL",PICBED_ALICLOUD_OPTIONS:"Set URL Suffix",PICBED_ALICLOUD_MESSAGE_AREA:"Ex. oss-cn-beijing",PICBED_ALICLOUD_MESSAGE_PATH:"Ex. test/",PICBED_ALICLOUD_MESSAGE_OPTIONS:"Ex. ?x-oss-process=xxx",PICBED_ALICLOUD_MESSAGE_CUSTOMURL:"Ex. https://test.com",PICBED_TENCENTCLOUD:"Tencent Cloud",PICBED_TENCENTCLOUD_VERSION:"Choose COS version",PICBED_TENCENTCLOUD_SECRETID:"Set SecretId",PICBED_TENCENTCLOUD_SECRETKEY:"Set SecretKey",PICBED_TENCENTCLOUD_APPID:"Set AppId",PICBED_TENCENTCLOUD_BUCKET:"Set Bucket",PICBED_TENCENTCLOUD_AREA:"Set Area",PICBED_TENCENTCLOUD_ENDPOINT:"Set Endpoint",PICBED_TENCENTCLOUD_PATH:"Set Path",PICBED_TENCENTCLOUD_OPTIONS:"Set URL Suffix",PICBED_TENCENTCLOUD_SLIM:"Set ImageSlim",PICBED_TENCENTCLOUD_SLIM_TIP:"Image extremely intelligent compression, please refer to the [document description](https://cloud.tencent.com/document/product/436/49259)",PICBED_TENCENTCLOUD_SLIM_CONFIRM:"OPEN",PICBED_TENCENTCLOUD_SLIM_CANCEL:"CLOSE",PICBED_TENCENTCLOUD_CUSTOMURL:"Set Custom URL",PICBED_TENCENTCLOUD_MESSAGE_APPID:"Ex. 1234567890",PICBED_TENCENTCLOUD_MESSAGE_AREA:"Ex. ap-beijing",PICBED_TENCENTCLOUD_MESSAGE_ENDPOINT:"Ex. cos-internal.accelerate.tencentcos.cn",PICBED_TENCENTCLOUD_MESSAGE_PATH:"Ex. test/",PICBED_TENCENTCLOUD_MESSAGE_CUSTOMURL:"Ex. http://test.com",PICBED_TENCENTCLOUD_MESSAGE_OPTIONS:"Ex. ?imageMogr2",PICBED_GITHUB:"GitHub",PICBED_GITHUB_TOKEN:"Set Token",PICBED_GITHUB_REPO:"Set Repo Name",PICBED_GITHUB_PATH:"Set Path",PICBED_GITHUB_BRANCH:"Set Branch",PICBED_GITHUB_CUSTOMURL:"Set Custom URL",PICBED_GITHUB_MESSAGE_REPO:"Ex. username/repo",PICBED_GITHUB_MESSAGE_BRANCH:"Ex. main",PICBED_GITHUB_MESSAGE_PATH:"Ex. test/",PICBED_GITHUB_MESSAGE_CUSTOMURL:"Ex. https://test.com",PICBED_QINIU:"Qiniu",PICBED_QINIU_ACCESSKEY:"Set AccessKey",PICBED_QINIU_SECRETKEY:"Set SecretKey",PICBED_QINIU_BUCKET:"Set Bucket",PICBED_QINIU_PATH:"Set Path",PICBED_QINIU_URL:"Set URL",PICBED_QINIU_OPTIONS:"Set URL Suffix",PICBED_QINIU_AREA:"Set Area",PICBED_QINIU_MESSAGE_PATH:"Ex. test/",PICBED_QINIU_MESSAGE_AREA:"Ex. z0",PICBED_QINIU_MESSAGE_OPTIONS:"Ex. ?imageslim",PICBED_QINIU_MESSAGE_URL:"Ex. https://xxx.yyy.glb.clouddn.com",PICBED_IMGUR:"Imgur",PICBED_IMGUR_CLIENTID:"Set ClientId",PICBED_IMGUR_PROXY:"Set Proxy",PICBED_IMGUR_MESSAGE_PROXY:"Ex. http://127.0.0.1:1080",PICBED_UPYUN:"Upyun",PICBED_UPYUN_BUCKET:"Set Bucket",PICBED_UPYUN_OPERATOR:"Set Operator",PICBED_UPYUN_PASSWORD:"Set Operator Password",PICBED_UPYUN_PATH:"Set Path",PICBED_UPYUN_URL:"Set URL",PICBED_UPYUN_OPTIONS:"Set URL Suffix",PICBED_UPYUN_MESSAGE_OPERATOR:"Ex. me",PICBED_UPYUN_MESSAGE_PASSWORD:"Please type the operator password",PICBED_UPYUN_MESSAGE_URL:"Ex. http://xxx.test.upcdn.net",PICBED_UPYUN_MESSAGE_OPTIONS:"Ex. !imgslim",PICBED_UPYUN_MESSAGE_PATH:"Ex. test/",PLUGIN_HANDLER_PLUGIN_INSTALL_SUCCESS:"Plugin installed successfully",PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED:"Plugin installation failed",PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_REASON:"Plugin installation failed, error code is ${code}, error log is \n ${data}",PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_PATH:"Plugin installation failed, please enter a valid plugin name or valid installation path",PLUGIN_HANDLER_PLUGIN_UNINSTALL_SUCCESS:"Plugin uninstalled successfully",PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED:"Plugin uninstall failed",PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_REASON:"Plugin uninstall failed, error code is ${code}, error log is \n ${data}",PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_VALID:"Plugin uninstall failed, please enter a valid plugin name",PLUGIN_HANDLER_PLUGIN_UPDATE_SUCCESS:"Plugin updated successfully",PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED:"Plugin update failed",PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_REASON:"Plugin update failed, error code is ${code}, error log is \n ${data}",PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_VALID:"Plugin update failed, please enter a valid plugin name",CONFIG_SYNC_INVALID_ENCRYPTION_METHOD:"Invalid configuration: settings.picgoCloud.encryptionMethod must be one of 'auto', 'sse', 'e2ee'. Found: ${value}",CONFIG_SYNC_ENCRYPTION_METHOD_E2EE:"End-to-end encryption",CONFIG_SYNC_ENCRYPTION_METHOD_SSE:"Server-side encryption",CONFIG_SYNC_ENCRYPTION_SWITCH_TITLE:"Confirm switch encryption method?",CONFIG_SYNC_ENCRYPTION_SWITCH_BODY:'You are switching from "${from}" to "${to}".\n\nNote: Switching encryption modes will clear all your cloud history versions.\nThis is because older history versions cannot be decrypted or verified under the new mode.\nAfter switching, the system will immediately create a new backup as the starting point.',CONFIG_SYNC_ENCRYPTION_SWITCH_CONFIRM:"Confirm switch and clear history",CONFIG_SYNC_ENCRYPTION_SWITCH_CANCEL:"Cancel",CONFIG_SYNC_ENCRYPTION_SWITCH_CANCELLED:"Encryption switch cancelled by user",CONFIG_SYNC_ENCRYPTION_SWITCH_MISSING_HANDLER:"Encryption switch confirmation handler is required"}};class sn{i18n;objectAdapter;ctx;constructor(e){this.ctx=e,this.objectAdapter=new y.ObjectAdapter(rn);let t=this.ctx.getConfig("settings.language")||"en";rn[t]||(t="en"),this.i18n=new y.I18n({adapter:this.objectAdapter,defaultLanguage:t}),this.loadOutsideI18n()}loadOutsideI18n(){const n=this.getOutsideI18nFolder();e.readdirSync(n,{withFileTypes:!0}).forEach(r=>{if(r.isFile()&&r.name.endsWith(".yml")){const i=t.join(n,r.name),s=e.readFileSync(i,"utf8");try{const e=U.load(s);rn[r.name.replace(/\.yml$/,"")]=e}catch(e){console.error(e)}}})}getOutsideI18nFolder(){const n=t.join(this.ctx.baseDir,"i18n-cli");return e.pathExistsSync(n)||e.ensureDirSync(n),n}translate(e,t){return this.i18n.translate(e,t)||e}setLanguage(e){this.i18n.setLanguage(e),this.ctx.saveConfig({"settings.language":e})}addLocale(e,t){const n=this.objectAdapter.getLocale(e);if(!n)return!1;const r=c.merge(n,t);return this.objectAdapter.setLocale(e,r),!0}addLanguage(e,t){return!this.objectAdapter.getLocale(e)&&(this.objectAdapter.setLocale(e,t),rn[e]=t,!0)}getLanguageList(){return Object.keys(rn)}}var on;function an(e){return Object.values(on).includes(e)}!function(e){e.AUTH_CALLBACK="/auth/callback",e.UPLOAD="/upload",e.HEARTBEAT="/heartbeat"}(on||(on={}));const cn=e=>{if(e instanceof Error)return e.message;if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return String(e)}};var ln;!function(e){e[e.Clipboard=0]="Clipboard",e[e.List=1]="List",e[e.Invalid=2]="Invalid"}(ln||(ln={}));const un=e=>"object"==typeof e&&null!==e&&("arrayBuffer"in e&&"function"==typeof e.arrayBuffer),pn=e=>{const t=e.name;return"string"==typeof t&&""!==t.trim()?t:`${_.randomUUID()}.png`},gn=(n,r)=>{n.post(on.UPLOAD,async n=>{try{const i=n.req.raw.headers.get("content-type")||"",s=(e,t)=>r.i18n?.translate(e,t)??String(e);if(i.includes("multipart/form-data")){const i=t.join(r.baseDir,"picgo-form-images"),o=[];try{await e.ensureDir(i);const a=(await n.req.formData()).getAll("files");if(0===a.length)return n.json({success:!1,result:[],message:s("SERVER_FORMDATA_NO_FILES_IN_FILES_FIELD")},400);for(const r of a){if(!un(r))return n.json({success:!1,result:[],message:s("SERVER_FORMDATA_FILES_MUST_BE_FILES")},400);const a=pn(r),c=t.basename(a),l=t.join(i,c),u=Buffer.from(await r.arrayBuffer());await e.writeFile(l,u),o.push(l)}const c=await r.upload(o);if(c instanceof Error)return n.json({success:!1,result:[],message:c.message},500);const l=c.map(e=>e.imgUrl).filter(e=>"string"==typeof e&&""!==e);return n.json({success:!0,result:l})}catch(e){return r.log.error(e),n.json({success:!1,result:[],message:cn(e)},500)}finally{await Promise.allSettled(o.map(t=>e.remove(t)))}}const o=await n.req.raw.text().catch(()=>"");if(""===o.trim()){const e=await r.upload();if(e instanceof Error)return n.json({success:!1,result:[],message:e.message},500);const t=e.map(e=>e.imgUrl).filter(e=>"string"==typeof e&&""!==e);return n.json({success:!0,result:t})}let a;try{a=JSON.parse(o)}catch{return n.json({success:!1,result:[],message:s("SERVER_INVALID_JSON_BODY")},400)}const c=(e=>{if("object"!=typeof e||null===e)return{kind:ln.Invalid,messageKey:"SERVER_INVALID_REQUEST_BODY_LIST_REQUIRED"};if(!("list"in e))return{kind:ln.Clipboard};const t=e.list;return void 0===t?{kind:ln.Clipboard}:Array.isArray(t)?0===t.length?{kind:ln.Clipboard}:t.every(e=>"string"==typeof e&&""!==e.trim())?{kind:ln.List,list:t}:{kind:ln.Invalid,messageKey:"SERVER_INVALID_REQUEST_BODY_LIST_REQUIRED"}:{kind:ln.Invalid,messageKey:"SERVER_INVALID_REQUEST_BODY_LIST_REQUIRED"}})(a);if(c.kind===ln.Invalid)return n.json({success:!1,result:[],message:s(c.messageKey)},400);if(c.kind===ln.Clipboard){const e=await r.upload();if(e instanceof Error)return n.json({success:!1,result:[],message:e.message},500);const t=e.map(e=>e.imgUrl).filter(e=>"string"==typeof e&&""!==e);return n.json({success:!0,result:t})}const l=await r.upload(c.list);if(l instanceof Error)return n.json({success:!1,result:[],message:l.message},500);const u=l.map(e=>e.imgUrl).filter(e=>"string"==typeof e&&""!==e);return n.json({success:!0,result:u})}catch(e){return r.log.error(e),n.json({success:!1,result:[],message:cn(e)},500)}}),n.post(on.HEARTBEAT,e=>e.json({success:!0,result:"alive"}))};var En;!function(e){e.Authorization="authorization",e.Header="header",e.Query="query",e.None="none"}(En||(En={}));const dn=e=>{if("number"==typeof e&&Number.isFinite(e))return e;if("string"==typeof e&&""!==e.trim()){const t=Number(e);if(Number.isFinite(t))return t}},hn=e=>{if("string"!=typeof e)return;const t=e.trim();return""===t?void 0:t};class _n{app;ctx;server;listeningPort;listeningHost;authSecret;warnedQuerySecret=!1;staticRoutePrefixes=[];constructor(e){this.ctx=e,this.app=new O.Hono,this.initMiddleware(),this.initCoreRoutes()}registerGet(e,t,n=!1){this.handleRegister("get",e,t,n)}registerPost(e,t,n=!1){this.handleRegister("post",e,t,n)}registerPut(e,t,n=!1){this.handleRegister("put",e,t,n)}registerDelete(e,t,n=!1){this.handleRegister("delete",e,t,n)}registerMiddleware(e,t){this.app.use(e,t)}registerStatic(e,t){const n=e.endsWith("/*")?e:`${e}/*`,r=n.replace(/\/\*$/,"")||"/";this.staticRoutePrefixes.includes(r)||this.staticRoutePrefixes.push(r),this.app.use(n,A.serveStatic({root:t}))}handleRegister(e,t,n,r){!an(t)||r?this.app[e](t,n):this.ctx.log.warn(`[PicGo Server] Plugin attempted to overwrite builtin route: ${t}. Action denied.`)}mount(e,t){const n=new O.Hono;t(n),this.app.route(e,n)}getServerInfo(){return this.server&&this.listeningHost&&void 0!==this.listeningPort?`http://${this.listeningHost}:${this.listeningPort}/`:""}isListening(){return void 0!==this.server}initMiddleware(){this.app.use(x.cors()),this.app.use((e,t)=>this.handleAuth(e,t)),this.app.use(R.logger())}initCoreRoutes(){gn(this.app,this.ctx)}t(e,t){return this.ctx.i18n?.translate(e,t)??String(e)}getRequestPath(e){return"string"==typeof e.req.path?e.req.path:new URL(e.req.url).pathname}isStaticPath(e){return this.staticRoutePrefixes.some(t=>!!t&&("/"===t?"/"===e:e===t||e.startsWith(`${t}/`)))}shouldSkipAuth(e,t){return"OPTIONS"===e.toUpperCase()||(""===t||"/"===t||(!!this.isStaticPath(t)||!(!an(t)||t===on.UPLOAD)))}extractAuthToken(e){const t=e.req.raw.headers;if(t.has("authorization")){const e=(t.get("authorization")??"").match(/^\s*Bearer\s+(.+)$/i);return{source:En.Authorization,token:e?.[1]}}if(t.has("x-picgo-secret"))return{source:En.Header,token:t.get("x-picgo-secret")??""};const n=new URL(e.req.url);return n.searchParams.has("secret")?{source:En.Query,token:n.searchParams.get("secret")??""}:{source:En.None}}warnQuerySecretOnce(){this.warnedQuerySecret||(this.warnedQuerySecret=!0,this.ctx.log.warn(this.t("SERVER_AUTH_QUERY_SECRET_WARNING")))}getClientIp(e){const t=e.req.raw.headers.get("x-forwarded-for");if(t){const e=t.split(",")[0]?.trim();if(e)return e}const n=e.env,r=n.server??n;return r?.incoming?.socket?.remoteAddress??"unknown"}logUnauthorized(e){const t=this.getClientIp(e);this.ctx.log.warn(this.t("SERVER_AUTH_UNAUTHORIZED_REQUEST",{ip:t}))}async handleAuth(e,t){if(!this.authSecret)return await t();const n=e.req.method,r=this.getRequestPath(e);if(this.shouldSkipAuth(n,r))return await t();const{source:i,token:s}=this.extractAuthToken(e);return i===En.Query&&this.warnQuerySecretOnce(),s&&s===this.authSecret?await t():(this.ctx.log.warn(`[PicGo Server] Unauthorized request to ${n} ${r} with token from ${i}`),this.logUnauthorized(e),e.json({success:!1,message:"Unauthorized"},401))}async startServer(e,t){return await new Promise((n,r)=>{const i=T.serve({fetch:this.app.fetch,port:e,hostname:t},e=>{i.off("error",s),n({server:i,port:e.port})});function s(e){i.off("error",s),r(e)}i.once("error",s)})}async isExistingPicGoServer(e,t){const n=`http://${"0.0.0.0"===e||"::"===e?"127.0.0.1":e}:${t}/heartbeat`;try{const e=await u.post(n,void 0,{timeout:1e3});return!0===e?.data?.success&&"alive"===e?.data?.result}catch{return!1}}async listen(e,t,n=!1,r){if(this.server&&void 0!==this.listeningPort)return t&&this.listeningHost&&t!==this.listeningHost&&this.ctx.log.warn(`Server is already listening at http://${this.listeningHost}:${this.listeningPort}`),this.listeningPort;const i=this.ctx.getConfig("settings.server.port"),s=this.ctx.getConfig("settings.server.host"),o=this.ctx.getConfig("settings.server.secret"),a=dn(e)??dn(i)??36677,c=t??("string"==typeof s?s:void 0)??"127.0.0.1";this.authSecret=hn(r)??hn(process.env.PICGO_SERVER_SECRET)??hn(o),this.warnedQuerySecret=!1,this.app=((e,t)=>{const n=new O.Hono,r=[],i=new Map;return e.routes.forEach(e=>{if("ALL"===e.method)return void r.push(e);const n=`${e.method}::${e.path}`,s=i.get(n);if(void 0!==s)an(e.path)||t.log.warn(`Route conflict detected for [${e.method}] ${e.path}. Overriding previous handler.`),r[s]=e;else{const t=r.push(e)-1;i.set(n,t)}}),r.forEach(e=>{n.on(e.method,e.path,e.handler)}),n})(this.app,this.ctx);const l=async e=>{try{const{server:t,port:n}=await this.startServer(e,c);return this.server=t,this.listeningPort=n,this.listeningHost=c,this.authSecret?this.ctx.log.info(this.t("SERVER_AUTH_ENABLED")):this.ctx.log.warn(this.t("SERVER_AUTH_DISABLED_WARNING")),this.ctx.log.info(`[PicGo Server] Listening at http://${c}:${n}`),n}catch(t){if("EADDRINUSE"===t?.code){if(!n){if(await this.isExistingPicGoServer(c,e))return this.ctx.log.info(`[PicGo Server] Detected existing instance at http://${c}:${e}`),e}return this.ctx.log.warn(`[PicGo Server] port ${e} is busy, trying with port ${e+1}`),await l(e+1)}this.ctx.log.error(t)}};return await l(a)}shutdown(){try{this.server?.close()}catch{}finally{this.server=void 0,this.listeningPort=void 0,this.listeningHost=void 0,this.authSecret=void 0,this.warnedQuerySecret=!1}}}const fn=e=>{let t="";for(const n of e)t+=String.fromCharCode(n);return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")};class In{ctx;authState=null;pkceVerifier=null;pending;constructor(e){this.ctx=e,this.registerRoutes()}disposeLoginFlow(){const e=this.pending;if(!e)return;const t=this.ctx.i18n.translate("CLOUD_LOGIN_CANCELLED");e.abortController.abort(new Error(t))}async startLoginFlow(){if(this.pending)throw new Error(this.ctx.i18n.translate("CLOUD_LOGIN_IN_PROGRESS"));const e=this.ctx.server.isListening(),t=new AbortController,n=new Promise((n,r)=>{this.pending={resolve:n,reject:r,shouldShutdown:!e,abortController:t},t.signal.addEventListener("abort",()=>{const e=this.pending;if(!e||e.abortController!==t)return;this.pending=void 0,this.authState=null,this.pkceVerifier=null;const n=t.signal.reason,i=this.ctx.i18n.translate("CLOUD_LOGIN_CANCELLED"),s=n instanceof Error?n:new Error(String(n??i));r(s),e.shouldShutdown&&setTimeout(()=>{this.ctx.server.shutdown()},100)},{once:!0})});let r;try{r=await this.ctx.server.listen(void 0,"127.0.0.1",!0)}catch(e){const r=e instanceof Error?e:new Error(String(e));return t.abort(r),await n}if(void 0===r)return t.abort(new Error(this.ctx.i18n.translate("CLOUD_LOGIN_SERVER_START_FAILED"))),await n;if(t.signal.aborted)return await n;const i=encodeURIComponent(`http://127.0.0.1:${r}/auth/callback`);this.authState=B.randomUUID(),this.pkceVerifier=(()=>{const e=new Uint8Array(32);return _.webcrypto.getRandomValues(e),fn(e)})();const s=encodeURIComponent(await(async e=>{const t=(new TextEncoder).encode(e),n=await _.webcrypto.subtle.digest("SHA-256",t);return fn(new Uint8Array(n))})(this.pkceVerifier)),o=`${Ee}?callback=${i}&state=${encodeURIComponent(this.authState)}&challenge=${s}`;if(t.signal.aborted)return await n;try{await this.ctx.openUrl(o)}catch(e){const t=e instanceof Error?e.message:String(e);this.ctx.log.warn(this.ctx.i18n.translate("CLOUD_LOGIN_OPEN_BROWSER_FAILED",{message:t})),this.ctx.log.info(this.ctx.i18n.translate("CLOUD_LOGIN_OPEN_BROWSER_TIP",{url:o}))}return await n}renderResultPage(e,t){const n=e?"#2ecc71":"#e74c3c",r=e?this.ctx.i18n.translate("CLOUD_LOGIN_RESULT_SUCCESS_TITLE"):this.ctx.i18n.translate("CLOUD_LOGIN_RESULT_FAILED_TITLE"),i=e?"✓":"✕";return`\n      <!DOCTYPE html>\n      <html lang="en">\n        <head>\n          <title>${this.ctx.i18n.translate("CLOUD_LOGIN_PAGE_TITLE")}</title>\n          <meta charset="utf-8">\n          <meta name="viewport" content="width=device-width, initial-scale=1">\n          <style>\n            body {\n              font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;\n              display: flex;\n              justify-content: center;\n              align-items: center;\n              height: 100vh;\n              margin: 0;\n              background: #f0f2f5;\n            }\n            .card {\n              background: white;\n              padding: 40px;\n              border-radius: 8px;\n              box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n              text-align: center;\n              max-width: 440px;\n              width: calc(100% - 48px);\n            }\n            .icon {\n              width: 64px;\n              height: 64px;\n              border-radius: 50%;\n              display: flex;\n              align-items: center;\n              justify-content: center;\n              margin: 0 auto 16px;\n              background: ${n};\n              color: #fff;\n              font-size: 36px;\n              line-height: 1;\n            }\n            h1 {\n              color: ${n};\n              margin: 0 0 12px;\n              font-size: 24px;\n            }\n            p {\n              color: #666;\n              margin: 0 0 24px;\n              line-height: 1.5;\n            }\n            .btn {\n              display: inline-block;\n              padding: 10px 20px;\n              background: #333;\n              color: white;\n              text-decoration: none;\n              border-radius: 4px;\n              font-size: 14px;\n              cursor: pointer;\n              user-select: none;\n            }\n          </style>\n        </head>\n        <body>\n          <div class="card">\n            <div class="icon">${i}</div>\n            <h1>${r}</h1>\n            <p>${t}</p>\n          </div>\n        </body>\n      </html>\n    `}abortPendingLogin(e,t){e.abortController.signal.aborted||e.abortController.abort(new Error(t))}async handleCallback(e){const t=e.req.query("code"),n=e.req.query("state");if(!n||n!==this.authState)return this.ctx.log.warn(this.ctx.i18n.translate("CLOUD_LOGIN_STATE_MISMATCH_WARN")),e.html(this.renderResultPage(!1,this.ctx.i18n.translate("CLOUD_LOGIN_STATE_INVALID")),403);if(!t){const t=this.ctx.i18n.translate("CLOUD_LOGIN_CODE_MISSING"),n=this.pending;return n&&this.abortPendingLogin(n,t),e.html(this.renderResultPage(!1,t),400)}const r=this.pending;if(!r||r.abortController.signal.aborted)return e.html(this.renderResultPage(!1,this.ctx.i18n.translate("CLOUD_LOGIN_NOT_IN_PROGRESS")),409);const i=this.pkceVerifier;if(!i){this.ctx.log.error("PKCE verifier is missing during callback handling");const t=this.ctx.i18n.translate("CLOUD_LOGIN_EXCHANGE_FAILED");return this.abortPendingLogin(r,t),e.html(this.renderResultPage(!1,t),500)}try{this.ctx.log.info("API_BASE_URL",ge,"Exchanging login code for token...");const n=await(async(e,t)=>(await u.post("/api/tokens/exchange",{code:e,verifier:t},{baseURL:ge})).data)(t,i);if(!n.token){this.ctx.log.error("Token exchange failed without throwing an error");const t=n.message??this.ctx.i18n.translate("CLOUD_LOGIN_EXCHANGE_FAILED");return this.abortPendingLogin(r,t),e.html(this.renderResultPage(!1,t),500)}return this.ctx.saveConfig({"settings.picgoCloud.token":n.token}),this.authState=null,this.pkceVerifier=null,this.pending=void 0,r.resolve(n.token),r.shouldShutdown&&setTimeout(()=>{this.ctx.server.shutdown()},100),e.html(this.renderResultPage(!0,this.ctx.i18n.translate("CLOUD_LOGIN_RESULT_SUCCESS_MESSAGE")),200)}catch(t){let n,i;if(u.isAxiosError(t)){i=t.response?.status;const e=t.response?.data;(e=>"object"==typeof e&&null!==e&&"message"in e&&"string"==typeof e.message)(e)&&(n=e.message)}const s=this.ctx.i18n.translate("CLOUD_LOGIN_EXCHANGE_FAILED"),o=n??s,a=400===i?400:500;return this.abortPendingLogin(r,o),this.ctx.log.error(`Token exchange failed: ${o} (status: ${a})`,t),e.html(this.renderResultPage(!1,o),a)}}registerRoutes(){this.ctx.server.registerGet(on.AUTH_CALLBACK,this.handleCallback.bind(this),!0)}}class Cn{client;ctx;constructor(e){this.client=new de(e),this.ctx=e}async whoami(e){return await this.client.request({method:"GET",url:"/api/whoami"},e)}async verifyToken(e){try{const t=await this.whoami(e);return this.ctx.log.success("Welcome:",t.user),!0}catch{return!1}}async getUserConfig(e){try{const t=await this.client.request({method:"GET",url:"/api/config"},e);return JSON.parse(t.config)}catch{throw new Error("Failed to fetch user config from server")}}}class mn{ctx;auth;user;constructor(e){this.ctx=e,this.user=new Cn(e),this.auth=new In(e)}async login(e){if(e){if(!await this.user.verifyToken(e))throw new Error(this.ctx.i18n.translate("CLOUD_LOGIN_INVALID_TOKEN"));return this.ctx.saveConfig({"settings.picgoCloud.token":e}),void this.ctx.log.success(this.ctx.i18n.translate("CLOUD_LOGIN_SUCCESS"))}const t=this.ctx.getConfig("settings.picgoCloud.token");if(t){if(await this.user.verifyToken(t))return void this.ctx.log.success(this.ctx.i18n.translate("CLOUD_LOGIN_SUCCESS"))}await this.auth.startLoginFlow(),this.ctx.log.success(this.ctx.i18n.translate("CLOUD_LOGIN_SUCCESS"))}logout(){this.ctx.removeConfig("settings.picgoCloud","token"),this.ctx.log.success(this.ctx.i18n.translate("CLOUD_LOGOUT_SUCCESS"))}disposeLoginFlow(){this.auth.disposeLoginFlow()}async getUserInfo(){const e=this.ctx.getConfig("settings.picgoCloud.token");if(!e)return null;try{return await this.user.whoami(e)}catch(e){if(u.isAxiosError(e)){const t=e.response?.status;if(401===t||403===t)return this.ctx.removeConfig("settings.picgoCloud","token"),null;const n=e.response?.data?.message??e.message;if(n)throw new Error(`${e.code?`Error code: ${e.code}`:""}, ${n}`)}throw e}}}const Sn=()=>_.randomUUID(),Nn=new Set(["current","uploader","transformer","proxy","list"]),Ln=e=>"object"==typeof e&&null!==e&&!Array.isArray(e),Pn=e=>e.trim(),Dn=e=>Pn(e).toLowerCase();class Un{ctx;constructor(e){this.ctx=e,this.init()}init(){const e=this.ctx.getConfig("picBed"),t=this.ctx.getConfig("uploader"),n=Ln(e)?e:{},r=Ln(t)?t:{},i=new Set;for(const e of Object.keys(n))Nn.has(e)||i.add(e);for(const e of Object.keys(r))i.add(e);for(const e of i)this.migrateNormalizeAndSync(e)}listUploaderTypes(){return this.ctx.helper.uploader.getIdList()}getConfigList(e){return this.readTypeStore(e).configList}getActiveConfig(e){const t=this.readTypeStore(e);return this.getActiveConfigFromStore(t)}use(e,t){this.assertUploaderTypeExists(e);const n=this.readTypeStore(e);if(0===n.configList.length)return this.ctx.log.warn(`[UploaderConfigManager] No existing configs for uploader type "${e}". Creating a new metadata-only config`+(t?` named "${Pn(t)}"`:"")+". Please configure it before uploading."),this.createOrUpdate(e,t,{});const r="string"==typeof t?Pn(t):"";if(r){const i=this.findConfigByName(n.configList,r);if(!i)throw new Error(`Config ${t} not found in type ${e}`);return this.activate(e,n,i._id)}const{store:i,changed:s}=this.normalizeTypeStore(n),o=this.getActiveConfigFromStore(i);return o?this.persistTypeAndMirror(e,i,o,{setCurrent:!0,persistStore:s}):this.createOrUpdate(e,t,{})}createOrUpdate(e,t,n={}){this.assertUploaderTypeExists(e);const r=this.readTypeStore(e),i=Date.now(),s="string"==typeof t?Pn(t):"",o=s?this.findConfigByName(r.configList,s):void 0;if(o){const t={...o,...n,_id:o._id,_configName:o._configName,_createdAt:o._createdAt,_updatedAt:i},s={configList:r.configList.map(e=>e._id===o._id?t:e),defaultId:t._id};return this.persistTypeAndMirror(e,s,t,{setCurrent:!0,persistStore:!0})}const a=s?this.ensureUniqueNameOrThrow(r.configList,s):this.generateDefaultName(r.configList),c={...n,_id:Sn(),_configName:a,_createdAt:i,_updatedAt:i},l={configList:[...r.configList,c],defaultId:c._id};return this.persistTypeAndMirror(e,l,c,{setCurrent:!0,persistStore:!0})}copy(e,t,n){this.assertUploaderTypeExists(e);const r=this.readTypeStore(e),i=this.normalizeTypeStore(r).store,s=Pn(t),o=this.findConfigByName(i.configList,s);if(!o)throw new Error(`Config ${t} not found in type ${e}`);const a=Pn(n);if(!a)throw new Error("Config name can not be empty");const l=this.ensureUniqueNameOrThrow(i.configList,a),u=Date.now(),p={...o,_id:Sn(),_configName:l,_createdAt:u,_updatedAt:u},g={configList:[...i.configList,p],defaultId:i.defaultId},E={[`uploader.${e}`]:g},d=this.getActiveConfigFromStore(g);if(d){const t=this.ctx.getConfig(`picBed.${e}`);c.isEqual(t,d)||(E[`picBed.${e}`]=d)}return this.ctx.saveConfig(E),p}rename(e,t,n){this.assertUploaderTypeExists(e);const r=this.readTypeStore(e),i=Pn(t),s=Pn(n);if(!s)throw new Error("Config name can not be empty");const o=this.findConfigByName(r.configList,i);if(!o)throw new Error(`Config ${t} not found in type ${e}`);this.ensureUniqueNameOrThrow(r.configList,s,o._id);const a=Date.now(),c={...o,_configName:s,_updatedAt:a},l={configList:r.configList.map(e=>e._id===o._id?c:e),defaultId:r.defaultId};return r.defaultId===o._id?(this.persistTypeAndMirror(e,l,c,{setCurrent:!1,persistStore:!0}),c):(this.ctx.saveConfig({[`uploader.${e}`]:l}),c)}remove(e,t){this.assertUploaderTypeExists(e);const n=this.readTypeStore(e),r=Pn(t),i=this.findConfigByName(n.configList,r);if(!i)throw new Error(`Config ${t} not found in type ${e}`);const s=n.configList.filter(e=>e._id!==i._id);if(0===s.length)return this.ctx.saveConfig({[`uploader.${e}`]:{configList:[],defaultId:""}}),this.ctx.removeConfig("picBed",e),void(this.ctx.getConfig("picBed.current")===e&&this.ctx.log.warn(`You are currently using ${e} but have deleted its last config. Please switch to another uploader or create a new config.`));const o={configList:s,defaultId:n.defaultId===i._id?s[0]._id:n.defaultId},a=this.getActiveConfigFromStore(o);a?this.persistTypeAndMirror(e,o,a,{setCurrent:!1,persistStore:!0}):this.ctx.saveConfig({[`uploader.${e}`]:o})}migrateNormalizeAndSync(e){const t=this.ctx.getConfig(`picBed.${e}`);let n=this.readTypeStore(e),r=!1;if(0===n.configList.length&&Ln(t)){const e=Date.now(),i={...t,_id:"string"==typeof t._id&&t._id.trim()?t._id:Sn(),_configName:"string"==typeof t._configName&&Pn(t._configName)?Pn(t._configName):"Default",_createdAt:"number"==typeof t._createdAt?t._createdAt:e,_updatedAt:"number"==typeof t._updatedAt?t._updatedAt:e};n={configList:[i],defaultId:i._id},r=!0}const i=this.normalizeTypeStore(n);n=i.store,r=r||i.changed;const s={};r&&(s[`uploader.${e}`]=n);const o=this.getActiveConfigFromStore(n);if(o){const t=this.ctx.getConfig(`picBed.${e}`);c.isEqual(t,o)||(s[`picBed.${e}`]=o)}Object.keys(s).length>0&&this.ctx.saveConfig(s)}assertUploaderTypeExists(e){if(!this.listUploaderTypes().includes(e))throw new Error(`Type ${e} not found`)}readTypeStore(e){const t=this.ctx.getConfig(`uploader.${e}`);if(!Ln(t))return{configList:[],defaultId:""};const n=t.configList,r=t.defaultId,i=[];if(Array.isArray(n))for(const e of n)Ln(e)&&i.push(e);return{configList:i,defaultId:"string"==typeof r?r:""}}normalizeTypeStore(e){const t=Date.now();let n=!1;const r=new Set,i=new Set,s=e.configList.map(e=>{const s={...e};let o="string"==typeof s._id&&s._id.trim()?s._id:Sn();for(;i.has(o);)o=Sn();o!==s._id&&(s._id=o,n=!0),i.add(o);const a="number"==typeof s._createdAt?s._createdAt:t,c="number"==typeof s._updatedAt?s._updatedAt:t;a!==s._createdAt&&(s._createdAt=a,n=!0),c!==s._updatedAt&&(s._updatedAt=c,n=!0);let l=("string"==typeof s._configName?Pn(s._configName):"")||this.generateDefaultNameFromUsed(r),u=Dn(l);if(r.has(u)){const e=l;let i=1;for(;r.has(Dn(`${e}-${i}`));)i++;l=`${e}-${i}`,u=Dn(l),s._updatedAt=t,n=!0}return l!==s._configName&&(s._configName=l,n=!0),r.add(u),s});let o=e.defaultId;if(s.length>0){s.some(e=>e._id===o)||(o=s[0]._id,n=!0)}else""!==o&&(o="",n=!0);return{store:{configList:s,defaultId:o},changed:n}}generateDefaultName(e){const t=new Set(e.map(e=>Dn(e._configName)));return this.generateDefaultNameFromUsed(t)}generateDefaultNameFromUsed(e){const t="Default";if(!e.has(Dn(t)))return t;let n=1;for(;e.has(Dn(`${t}-${n}`));)n++;return`${t}-${n}`}ensureUniqueNameOrThrow(e,t,n){const r=Pn(t);if(!r)throw new Error("Config name can not be empty");const i=Dn(r);if(e.some(e=>e._id!==n&&Dn(e._configName)===i))throw new Error(`Config name ${t} already exists`);return r}findConfigByName(e,t){const n=Dn(t);return e.find(e=>Dn(e._configName)===n)}getActiveConfigFromStore(e){if(!e.defaultId)return e.configList[0];return e.configList.find(t=>t._id===e.defaultId)??e.configList[0]}activate(e,t,n){const r=t.configList.find(e=>e._id===n);if(!r)throw new Error(`Config not found for type ${e}`);const i={configList:t.configList,defaultId:n};return this.persistTypeAndMirror(e,i,r,{setCurrent:!0,persistStore:!0})}persistTypeAndMirror(e,t,n,r){const i={};if(r.persistStore&&(i[`uploader.${e}`]=t),n&&(i[`picBed.${e}`]=n),r.setCurrent&&(i["picBed.current"]=e,i["picBed.uploader"]=e),this.ctx.saveConfig(i),n)return n;const s=t.configList[0];if(!s)throw new Error(`No configs found in type ${e}`);return s}}class yn extends n.EventEmitter{_config;lifecycle;db;_pluginLoader;configPath;baseDir;helper;log;cmd;output;input;pluginHandler;server;cloud;uploaderConfig;Request;i18n;VERSION="2.0.3";GUI_VERSION;get pluginLoader(){return this._pluginLoader}constructor(e=""){super(),this.configPath=e,this.output=[],this.input=[],this.helper={transformer:new st("transformer"),uploader:new st("uploader"),beforeTransformPlugins:new st("beforeTransformPlugins"),beforeUploadPlugins:new st("beforeUploadPlugins"),afterUploadPlugins:new st("afterUploadPlugins")},this.initConfigPath(),this.log=new ut(this),this.cmd=new at(this),this.pluginHandler=new tn(this),this.initConfig(),this.init()}initConfigPath(){if(""===this.configPath&&(this.configPath=r.homedir()+"/.picgo/config.json"),".JSON"!==t.extname(this.configPath).toUpperCase())throw this.configPath="",Error("The configuration file only supports JSON format.");this.baseDir=t.dirname(this.configPath);e.pathExistsSync(this.configPath)||e.ensureFileSync(`${this.configPath}`)}initConfig(){this.db=new en(this),this._config=this.db.read(!0)}init(){try{this.i18n=new sn(this),this.Request=new Zt(this),this.server=new _n(this),this.cloud=new mn(this),this._pluginLoader=new Yt(this),ot("picgo"),$t().register(this),{register(e){e.helper.transformer.register("path",Ht),e.helper.transformer.register("base64",kt)}}.register(this),ot(""),this._pluginLoader.load(),this.uploaderConfig=new Un(this),this.lifecycle=new pt(this)}catch(e){throw this.emit(exports.IBuildInEvent.UPLOAD_PROGRESS,-1),this.log.error(e),e}}use(e,t){if(t)return this.pluginLoader.registerPlugin(t,e),this.pluginLoader.getPlugin(t);return e(this)}registerCommands(){""!==this.configPath&&(this.cmd.init(),this.cmd.loadCommands())}getConfig(e){return e?c.get(this._config,e):this._config}saveConfig(e){ee(e)?(this.setConfig(e),this.db.saveConfig(e)):this.log.warn("the format of config is invalid, please provide object")}removeConfig(e,t){e&&t&&(Z(e)?this.log.warn(`the config.${e} can't be removed`):(this.unsetConfig(e,t),this.db.unset(e,t)))}setConfig(e){ee(e)?Object.keys(e).forEach(t=>{Z(t)&&(this.log.warn(`the config.${t} can't be modified`),delete e[t]),c.set(this._config,t,e[t]),Wt.emit(exports.IBusEvent.CONFIG_CHANGE,{configName:t,value:e[t]})}):this.log.warn("the format of config is invalid, please provide object")}unsetConfig(e,t){e&&t&&(Z(e)?this.log.warn(`the config.${e} can't be unset`):c.unset(this.getConfig(e),t))}get request(){return this.Request.request.bind(this.Request)}async openUrl(e){const t=(await import("open")).default;this.log.info("Opening browser with URL:",e),await t(e)}async upload(t){if(""===this.configPath)return this.log.error("The configuration file only supports JSON format."),[];if(void 0!==t&&0!==t.length){const{output:e}=await this.lifecycle.start(t);return e}try{const{imgPath:t,shouldKeepAfterUploading:n}=await jt(this);if("no image"===t)throw new Error("image not found in clipboard");{this.once(exports.IBuildInEvent.FAILED,()=>{n||e.remove(t).catch(e=>{this.log.error(e)})}),this.once("finished",()=>{n||e.remove(t).catch(e=>{this.log.error(e)})});const{output:r}=await this.lifecycle.start([t]);return r}}catch(e){throw this.emit(exports.IBuildInEvent.FAILED,e),e}}}const Tn={...ie,applyUrlRewriteToImgInfo:G};exports.CloudManager=mn,exports.Commander=at,exports.ConfigMerger=me,exports.ConfigSyncManager=Fe,exports.CorruptedDataError=Ne,exports.DecryptionFailedError=Te,exports.InvalidPinError=Ue,exports.Lifecycle=pt,exports.LifecyclePlugins=st,exports.Logger=ut,exports.MaxRetryExceededError=ye,exports.MissingHandlerError=Pe,exports.PicGo=yn,exports.PicGoUtils=Tn,exports.PluginHandler=tn,exports.PluginLoader=Yt,exports.Request=Zt,exports.ServerManager=_n,exports.UnsupportedVersionError=Le;
//# sourceMappingURL=index.cjs.js.map
