diff --git a/src/assets/lib/kookit-extra-browser.min.js b/src/assets/lib/kookit-extra-browser.min.js index 67c0e366..eb4b01fc 100644 --- a/src/assets/lib/kookit-extra-browser.min.js +++ b/src/assets/lib/kookit-extra-browser.min.js @@ -1 +1 @@ -import e from"axios";import{createClient as t,AuthType as o}from"webdav/dist/web/index.js";function r(e,t,o,r){return new(o||(o=Promise))((function(i,s){function n(e){try{l(r.next(e))}catch(e){s(e)}}function a(e){try{l(r.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof o?t:new o((function(e){e(t)}))).then(n,a)}l((r=r.apply(e,t||[])).next())}))}const i="https://cloudtest.960960.xyz",s="https://web.koodoreader.com/",n="vnc67byrssocvy1",a="506df58a-29ab-4020-afc5-6f423dc80f35",l="1051055003225-ph1f5fvh328dhv7bco5jitlnfhg6ks2t.apps.googleusercontent.com";class c{constructor(e,t){this.config=e,this.thirdpartyRequest=t}listFiles(t){return r(this,void 0,void 0,(function*(){try{const o=yield this.refreshToken(),r=yield e.post("https://api.dropboxapi.com/2/files/list_folder",{path:"/"+t},{headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json"}});return console.log(r.data.entries.map((e=>e.name))),r.data.entries.map((e=>e.name))}catch(e){return console.error("Error listing files:",e),[]}}))}refreshToken(){return r(this,void 0,void 0,(function*(){if(this.config.access_token&&this.config.expires_at>(new Date).getTime())return this.config.access_token;let e=this.config.refresh_token,t=yield this.thirdpartyRequest.refreshThirdToken({provider:"dropbox",refresh_token:e});return this.config.access_token=t.data.access_token,this.config.expires_at=(new Date).getTime()+1e3*t.data.expires_in,t.data.access_token}))}authToken(e){return r(this,void 0,void 0,(function*(){let t=yield this.thirdpartyRequest.authThirdToken({provider:"dropbox",redirect_uri:s,code:e});return console.log(t),t.data.refresh_token}))}getAuthUrl(){return`https://www.dropbox.com/oauth2/authorize?response_type=code&token_access_type=offline&client_id=${n}&redirect_uri=${s}`}}class d extends c{constructor(e,t){super(e,t)}uploadFile(t,o){return new Promise(((i,s)=>r(this,void 0,void 0,(function*(){try{const r=yield this.refreshToken();console.log("accessToken",r);let s=o.split("/").pop()||"",n=new File([t],s,{lastModified:(new Date).getTime(),type:t.type});const a=yield e.post("https://content.dropboxapi.com/2/files/upload",n,{headers:{Authorization:`Bearer ${r}`,"Content-Type":"application/octet-stream","Dropbox-API-Arg":JSON.stringify({path:"/"+s,mode:"overwrite",autorename:!0,mute:!1})},maxContentLength:1/0,maxBodyLength:1/0});if(console.log("File uploaded successfully:",a),a.status>=300)return console.error("Error occurred during file download:",a),void i(!1);i(!0)}catch(e){console.error("Error uploading file:",e),i(!1)}}))))}downloadFile(t){return new Promise(((o,i)=>r(this,void 0,void 0,(function*(){try{const r=yield this.refreshToken(),i=yield e({url:"https://content.dropboxapi.com/2/files/download",method:"post",headers:{Authorization:`Bearer ${r}`,"Dropbox-API-Arg":JSON.stringify({path:"/"+t})},maxContentLength:1/0,maxBodyLength:1/0,responseType:"arraybuffer"});if(i.status>=300)return console.error("Error occurred during file download:",i),void o(new ArrayBuffer(0));o(i.data)}catch(e){console.error("Error occurred during file download:",e),i(e)}}))))}}class p{constructor(e,t){this.config=e,this.thirdpartyRequest=t}getFileId(t,o){return r(this,void 0,void 0,(function*(){const r=yield this.refreshToken(),i=`https://www.googleapis.com/drive/v3/files?q=name='${t}'+and+'${o}'+in+parents&spaces=appDataFolder&fields=files(id,name)`;try{const t=yield e.get(i,{headers:{Authorization:"Bearer "+r}});if(0===t.data.files.length)return"";const o=t.data.files;return console.log(o),o.length>0?o[0].id:null}catch(e){return console.error("Error occurred during file list retrieval:",e),""}}))}checkFolder(t){return r(this,void 0,void 0,(function*(){const o=yield this.refreshToken(),r=yield this.getFolderId(t);if(r)return console.log("Folder already exists:",r),r;const i={name:t,mimeType:"application/vnd.google-apps.folder",parents:["appDataFolder"]};try{const t=yield e.post("https://www.googleapis.com/drive/v3/files",i,{headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json"}});return console.log("Folder created:",t.data.id),t.data.id}catch(e){throw console.error("Error occurred during folder creation:",e),e}}))}getFolderId(t){return r(this,void 0,void 0,(function*(){const o=yield this.refreshToken(),r=`https://www.googleapis.com/drive/v3/files?q=name='${t}'+and+mimeType='application/vnd.google-apps.folder'+and+'appDataFolder'+in+parents&spaces=appDataFolder&fields=files(id,name)`;try{const t=(yield e.get(r,{headers:{Authorization:`Bearer ${o}`}})).data.files;return t.length>0?t[0].id:null}catch(e){throw console.error("Error occurred during fetching folder ID:",e),e}}))}listFiles(t){return r(this,void 0,void 0,(function*(){try{const o=yield this.refreshToken();let r=yield this.checkFolder(t);console.log(r);const i=`https://www.googleapis.com/drive/v3/files?q='${r}'+in+parents&spaces=appDataFolder&fields=files(id,name)`,s=yield e.get(i,{headers:{Authorization:`Bearer ${o}`}});return console.log("Files in folder:",s.data.files.map((e=>e.name))),s.data.files}catch(e){return console.error("Error listing files:",e),[]}}))}refreshToken(){return r(this,void 0,void 0,(function*(){if(this.config.access_token&&this.config.expires_at>(new Date).getTime())return this.config.access_token;let e=this.config.refresh_token,t=yield this.thirdpartyRequest.refreshThirdToken({provider:"google",refresh_token:e});return this.config.access_token=t.data.access_token,this.config.expires_at=(new Date).getTime()+1e3*t.data.expires_in,t.data.access_token}))}authToken(e){return r(this,void 0,void 0,(function*(){let t=yield this.thirdpartyRequest.authThirdToken({provider:"google",redirect_uri:s,code:e});return console.log(t),t.data.refresh_token}))}getAuthUrl(){return`https://accounts.google.com/o/oauth2/v2/auth?redirect_uri=${s}&prompt=consent&response_type=code&client_id=${l}&scope=https://www.googleapis.com/auth/drive.appdata&access_type=offline`}}const u=e=>"json"===e?"application/json":["jpg","jpeg","png","gif","bmp"].includes(e)?"image/"+e:"zip"===e?"application/zip":"epub"===e?"application/epub+zip":"txt"===e?"text/plain":"pdf"===e?"application/pdf":"mobi"===e?"application/x-mobipocket-ebook":"azw3"===e||"azw"===e?"application/vnd.amazon.ebook":"cbz"===e?"application/x-cbz":"cbr"===e?"application/x-cbr":"cbt"===e?"application/x-cbt":"cb7"===e?"application/x-cb7":"fb2"===e?"application/x-fictionbook+xml":"html"===e?"text/html":"css"===e?"text/css":"js"===e?"application/javascript":"xml"===e?"application/xml":"xhtml"===e?"application/xhtml+xml":"opf"===e?"application/oebps-package+xml":"ncx"===e?"application/x-dtbncx+xml":"mp3"===e?"audio/mpeg":"wav"===e?"audio/wav":"ogg"===e?"audio/ogg":"mp4"===e?"video/mp4":"webm"===e?"video/webm":"avi"===e?"video/x-msvideo":"wmv"===e?"video/x-ms-wmv":"flv"===e?"video/x-flv":"m3u8"===e?"application/x-mpegURL":"ts"===e?"video/MP2T":"3gp"===e?"video/3gpp":"3g2"===e?"video/3gpp2":"db"===e?"application/x-sqlite3":void 0;var h={getMimeType:u};class g extends p{constructor(e,t){super(e,t),this.getData=e=>new Promise(((t,o)=>{if(e){const r=new FileReader;r.onload=o=>t({fileName:e.name,mimeType:e.type,fileSize:e.size,data:o.target.result}),r.onerror=e=>o(e),r.readAsArrayBuffer(e)}else t({})}))}uploadFile(t,o){return new Promise(((i,s)=>r(this,void 0,void 0,(function*(){try{const r=yield this.refreshToken();console.log(r);let s=o.split("/").pop()||"",n=new File([t],s,{lastModified:(new Date).getTime(),type:t.type}),a=o.split(".").pop(),l=u(a||""),c=o.split("/")[0],d=yield this.checkFolder(c),p=yield this.getFileId(s||"",d);console.log(p,"fileId");const h={mimeType:l,name:s,parents:[d]},g=p?`https://www.googleapis.com/upload/drive/v3/files/${p}?uploadType=resumable`:"https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable";console.log(g);const y=(yield e({method:p?"PATCH":"POST",url:g,data:p?null:JSON.stringify(h),headers:{Authorization:"Bearer "+r,"Content-Type":"application/json; charset=UTF-8"}})).headers.location;console.log(y);const f=yield this.getData(n);if(0===Object.keys(f).length)return void console.log("No file.");const m=yield e.put(y,f.data,{headers:{Authorization:"Bearer "+r,"Content-Type":"application/zip","Content-Range":`bytes 0-${f.fileSize-1}/${f.fileSize}`},maxContentLength:1/0,maxBodyLength:1/0});if(console.log("File uploaded successfully:",m),m.status>=300)return console.error("Error occurred during file download:",m),void i(!1);i(!0)}catch(e){console.error("Error uploading file:",e),i(!1)}}))))}downloadFile(t){return new Promise(((o,i)=>r(this,void 0,void 0,(function*(){try{const r=yield this.refreshToken();let s=t.split("/").pop(),n=t.split("/")[0],a=yield this.checkFolder(n),l=yield this.getFileId(s||"",a);l||(console.error("File not found"),i(new Error("File not found")));const c=`https://www.googleapis.com/drive/v3/files/${l}?alt=media`,d=yield e.get(c,{headers:{Authorization:"Bearer "+r},maxContentLength:1/0,maxBodyLength:1/0,responseType:"arraybuffer"});o(d.data)}catch(e){console.error("Error occurred during file download:",e),i(e)}}))))}}class y{constructor(e,t){this.config=e,this.thirdpartyRequest=t}listFiles(t){return r(this,void 0,void 0,(function*(){try{const o=yield this.refreshToken(),r=yield e.get(`https://graph.microsoft.com/v1.0/me/drive/special/approot:/${t}:/children`,{headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json"}});return r.status>=300?[]:(console.log("Files in folder:",r.data.value.map((e=>e.name))),r.data.value.map((e=>e.name)))}catch(e){return console.error("Error listing files:",e),[]}}))}refreshToken(){return r(this,void 0,void 0,(function*(){if(this.config.access_token&&this.config.expires_at>(new Date).getTime())return this.config.access_token;let e=this.config.refresh_token,t=yield this.thirdpartyRequest.refreshThirdToken({provider:"microsoft",refresh_token:e});return this.config.access_token=t.data.access_token,this.config.expires_at=(new Date).getTime()+1e3*t.data.expires_in,t.data.access_token}))}authToken(e){return r(this,void 0,void 0,(function*(){console.log(e,"safdfsfd"),console.log({provider:"microsoft",redirect_uri:s,code:e}),console.log(this.thirdpartyRequest,"this.thirdpartyRequest");let t=yield this.thirdpartyRequest.authThirdToken({provider:"microsoft",redirect_uri:s,code:e});return console.log(t),t.data.refresh_token}))}getAuthUrl(){return`https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=${a}&scope=files.readwrite.appfolder offline_access&response_type=code&redirect_uri=${s}`}}class f extends y{constructor(e,t){super(e,t)}uploadFile(t,o){return new Promise(((i,s)=>r(this,void 0,void 0,(function*(){try{const r=yield this.refreshToken();console.log(r);let s=o.split("/").pop()||"",n=new File([t],s,{lastModified:(new Date).getTime(),type:t.type});const a="https://graph.microsoft.com/v1.0/me/drive/special/approot:/"+o+":/createUploadSession",l=(yield e.post(a,null,{headers:{Authorization:"Bearer "+r,"Content-Type":"application/json"}})).data.uploadUrl,c=yield e.put(l,n,{headers:{Authorization:"Bearer "+r,"Content-Type":n.type},maxContentLength:1/0,maxBodyLength:1/0});if(console.log("File uploaded successfully:",c),c.status>=300)return console.error("Error occurred during file download:",c),void i(!1);i(!0)}catch(e){console.error("Error uploading file:",e),i(!1)}}))))}downloadFile(t){return new Promise(((o,i)=>r(this,void 0,void 0,(function*(){try{const r=yield this.refreshToken(),i=`https://graph.microsoft.com/v1.0/me/drive/special/approot:/${t}:/content`,s=yield e.get(i,{responseType:"arraybuffer",headers:{Authorization:"Bearer "+r},maxContentLength:1/0,maxBodyLength:1/0});o(s.data)}catch(e){console.error("Error occurred during file download:",e),i(e)}}))))}}class m{downloadFile(e,t){return r(this,void 0,void 0,(function*(){return new Promise((e=>{e(!0)}))}))}uploadFile(e,t){return r(this,void 0,void 0,(function*(){return new Promise((e=>{e(!0)}))}))}listFiles(e){return r(this,void 0,void 0,(function*(){return new Promise((e=>{e([])}))}))}authToken(e){return r(this,void 0,void 0,(function*(){return new Promise((e=>{e("")}))}))}getAuthUrl(){return""}}class k{constructor(e,t){this.config=e,this.thirdpartyRequest=t}uploadFile(t,o){return new Promise(((i,s)=>r(this,void 0,void 0,(function*(){let{endpoint:r,region:s,bucketName:n,accessKeyId:a,secretAccessKey:l}=this.config;try{const c=(yield this.thirdpartyRequest.s3Upload({bucket_name:n,object_key:o,region:s,endpoint:r,access_key_id:a,secret_access_key:l})).data.url;let d=o.split("/").pop()||"",p=new File([t],d,{lastModified:(new Date).getTime(),type:t.type});const u=yield e.put(c,p,{headers:{}});console.log("File uploaded successfully:",u),i(!0)}catch(e){console.error("Error occurred during file upload:",e),i(!1)}}))))}downloadFile(t){return new Promise(((o,i)=>r(this,void 0,void 0,(function*(){let{endpoint:r,region:i,bucketName:s,accessKeyId:n,secretAccessKey:a}=this.config;try{const l=(yield this.thirdpartyRequest.s3Download({bucket_name:s,object_key:t,region:i,endpoint:r,access_key_id:n,secret_access_key:a})).data.url,c=yield e({url:l,method:"post",headers:{},responseType:"arraybuffer"});o(c.data)}catch(e){console.error("Error occurred during file download:",e),o(!1)}}))))}listFiles(e){return r(this,void 0,void 0,(function*(){let{endpoint:t,region:o,bucketName:r,accessKeyId:i,secretAccessKey:s}=this.config;try{let n=yield this.thirdpartyRequest.s3List({bucket_name:r,object_key:e,region:o,endpoint:t,access_key_id:i,secret_access_key:s});return console.log("Files in folder:",n.data.contents.map((e=>e.split("/").pop()))),n.data.contents.map((e=>e.split("/").pop()))}catch(e){return console.error("Error listing files:",e),[]}}))}}class v{constructor(e){let{username:r,password:i,url:s}=e;this.client=t(s,{authType:o.Password,username:r,password:i}),this.username=r,this.password=i}uploadFile(t,o){return new Promise(((i,s)=>r(this,void 0,void 0,(function*(){try{!1===(yield this.client.exists(o.substring(0,o.lastIndexOf("/"))))&&(yield this.client.createDirectory(o.substring(0,o.lastIndexOf("/"))));let r=o.split("/").pop()||"",s=new File([t],r,{lastModified:(new Date).getTime(),type:t.type}),n=this.client.getFileUploadLink(o);const a=new URL(n);a.search="",n=a.toString();const l=btoa(this.username+":"+this.password),c=yield e.put(n,s,{headers:{Authorization:"Basic "+l}});console.log("File uploaded successfully:",c),i(!0)}catch(e){console.error("Error uploading file:",e),i(!1)}}))))}downloadFile(t){return new Promise(((o,i)=>r(this,void 0,void 0,(function*(){try{const r=this.client.getFileDownloadLink(t);console.log(r);const i=btoa(this.username+":"+this.password),s=yield e({url:r,method:"get",headers:{Authorization:"Basic "+i},responseType:"arraybuffer"});if(s.status>=300)return console.error("Error occurred during file download:",s),void o(new ArrayBuffer(0));o(s.data)}catch(e){console.error("Error occurred during file download:",e),i(e)}}))))}listFiles(e){return r(this,void 0,void 0,(function*(){try{let t=yield this.client.getDirectoryContents(e);return console.log(t.map((e=>e.basename))),t.map((e=>e.basename))}catch(e){return console.error("Error listing files:",e),[]}}))}}const E=["book","config","cover","font"];class b{constructor(e,t,o){this.type=e,this.remote="dropbox"===e?new d(t,o):"microsoft"===e?new f(t,o):"google"===e?new g(t,o):"s3compatible"===e?new k(t,o):"webdav"===e?new v(t):new m}downloadFile(e,t){return r(this,void 0,void 0,(function*(){return yield this.remote.downloadFile(t+"/"+e)}))}uploadFile(e,t,o){return r(this,void 0,void 0,(function*(){return yield this.remote.uploadFile(o,t+"/"+e)}))}listFiles(e){return r(this,void 0,void 0,(function*(){return yield this.remote.listFiles(e)}))}downloadAllFiles(){return r(this,void 0,void 0,(function*(){for(let e of E){let t=yield this.listFiles(e);for(let o of t)yield this.downloadFile(o,e)}}))}authToken(e){return r(this,void 0,void 0,(function*(){return yield this.remote.authToken(e)}))}getAuthUrl(){return this.remote.getAuthUrl?this.remote.getAuthUrl():""}}const w={notes:"SELECT * FROM notes WHERE key = ?",bookmarks:"SELECT * FROM bookmarks WHERE key = ?",books:"SELECT * FROM books WHERE key = ?",plugins:"SELECT * FROM plugins WHERE key = ?",words:"SELECT * FROM words WHERE key = ?"},T={notes:"SELECT * FROM notes WHERE bookKey = ?",bookmarks:"SELECT * FROM bookmarks WHERE bookKey = ?",words:"SELECT * FROM words WHERE bookKey = ?",books:"SELECT * FROM books WHERE key = ?"},R={notes:"DELETE FROM notes WHERE bookKey = ?",bookmarks:"DELETE FROM bookmarks WHERE bookKey = ?",words:"DELETE FROM words WHERE bookKey = ?"};function x(e){for(const t in e)e.hasOwnProperty(t)&&(e[`temp-${t}`]=e[t]);return e}const F={notes:e=>{let t=Object.assign({},e);return t.date=JSON.parse(e.date),t.tag=JSON.parse(e.tag),t},bookmarks:e=>e,books:e=>e,plugins:e=>{let t=Object.assign({},e);return e.autoValue||delete t.autoValue,e.langList?t.langList=JSON.parse(e.langList):delete t.langList,e.voiceList?t.voiceList=JSON.parse(e.voiceList):delete t.voiceList,t.config=JSON.parse(e.config),t},words:e=>{let t=Object.assign({},e);return t.date=JSON.parse(e.date),t}};var L={sqlStatement:{createTableStatement:x({notes:'\n CREATE TABLE IF NOT EXISTS "notes" (\n "key" text PRIMARY KEY,\n "bookKey" text,\n "date" object,\n "chapter" text,\n "chapterIndex" integer,\n "text" text,\n "cfi" text,\n "range" text,\n "notes" text,\n "percentage" text,\n "color" integer,\n "tag" array\n )\n ',bookmarks:'\n CREATE TABLE IF NOT EXISTS "bookmarks" (\n "key" text PRIMARY KEY,\n "bookKey" text,\n "cfi" text,\n "label" text,\n "percentage" text,\n "chapter" text\n );\n ',books:'\n CREATE TABLE IF NOT EXISTS "books" (\n "key" text PRIMARY KEY,\n "name" text,\n "author" text,\n "description" text,\n "md5" text,\n "cover" text,\n "format" text,\n "publisher" text,\n "size" integer,\n "page" integer,\n "path" text,\n "charset" text\n );\n ',plugins:'\n CREATE TABLE IF NOT EXISTS "plugins" (\n "key" text PRIMARY KEY,\n "type" text,\n "displayName" text,\n "icon" text,\n "version" text,\n "config" object,\n "autoValue" string,\n "langList" text,\n "voiceList" text,\n "scriptSHA256" text,\n "script" text\n );\n ',words:'\n CREATE TABLE IF NOT EXISTS "words" (\n "key" text PRIMARY KEY,\n "bookKey" text,\n "date" object,\n "word" text,\n "chapter" text\n );\n '}),getAllStatement:x({notes:"SELECT * FROM notes",bookmarks:"SELECT * FROM bookmarks",books:"SELECT * FROM books",plugins:"SELECT * FROM plugins",words:"SELECT * FROM words"}),saveStatement:x({notes:"INSERT OR REPLACE INTO notes (key, bookKey, chapter, chapterIndex, text, cfi, range, notes, date, percentage, color, tag) VALUES (@key, @bookKey, @chapter, @chapterIndex, @text, @cfi, @range, @notes, @date, @percentage, @color, @tag)",bookmarks:"INSERT OR REPLACE INTO bookmarks (key, bookKey, cfi, label, percentage, chapter) VALUES (@key, @bookKey, @cfi, @label, @percentage, @chapter)",books:"INSERT OR REPLACE INTO books (key, name, author, description, md5, cover, format, publisher, size, page, path, charset) VALUES (@key, @name, @author, @description, @md5, @cover, @format, @publisher, @size, @page, @path, @charset)",plugins:"INSERT OR REPLACE INTO plugins (key, type, displayName, icon, version, config, autoValue, langList, voiceList, scriptSHA256, script) VALUES (@key, @type, @displayName, @icon, @version, @config, @autoValue, @langList, @voiceList, @scriptSHA256, @script)",words:"INSERT OR REPLACE INTO words (key, bookKey, date, word, chapter) VALUES (@key, @bookKey, @date, @word, @chapter)"}),deleteAllStatement:x({notes:"DELETE FROM notes",bookmarks:"DELETE FROM bookmarks",books:"DELETE FROM books",plugins:"DELETE FROM plugins",words:"DELETE FROM words"}),updateStatement:x({notes:"UPDATE notes SET bookKey = @bookKey, chapter = @chapter, chapterIndex = @chapterIndex, text = @text, cfi = @cfi, range = @range, notes = @notes, date = @date, percentage = @percentage, color = @color, tag = @tag WHERE key = @key",bookmarks:"UPDATE bookmarks SET bookKey = @bookKey, cfi = @cfi, label = @label, percentage = @percentage, chapter = @chapter WHERE key = @key",books:"UPDATE books SET name = @name, author = @author, description = @description, md5 = @md5, cover = @cover, format = @format, publisher = @publisher, size = @size, page = @page, path = @path, charset = @charset WHERE key = @key",plugins:"UPDATE plugins SET type = @type, displayName = @displayName, icon = @icon, version = @version, config = @config, autoValue = @autoValue, langList = @langList, voiceList = @voiceList, scriptSHA256 = @scriptSHA256, script = @script WHERE key = @key",words:"UPDATE words SET bookKey = @bookKey, date = @date, word = @word, chapter = @chapter WHERE key = @key"}),deleteStatement:x({notes:"DELETE FROM notes WHERE key = ?",bookmarks:"DELETE FROM bookmarks WHERE key = ?",books:"DELETE FROM books WHERE key = ?",plugins:"DELETE FROM plugins WHERE key = ?",words:"DELETE FROM words WHERE key = ?"}),getStatement:x(w),getByBookKeyStatement:x(T),getByBookKeysStatement:x({notes:e=>`SELECT * FROM notes WHERE bookKey IN (${e.map((()=>"?")).join(",")})`,bookmarks:e=>`SELECT * FROM bookmarks WHERE bookKey IN (${e.map((()=>"?")).join(",")})`,words:e=>`SELECT * FROM words WHERE bookKey IN (${e.map((()=>"?")).join(",")})`,books:e=>`SELECT * FROM books WHERE key IN (${e.map((()=>"?")).join(",")})`}),deleteByBookKeyStatement:x(R)},jsonToSqlite:x({notes:e=>{let t=Object.assign({},e);return t.date=JSON.stringify(e.date),t.tag=JSON.stringify(e.tag),t},bookmarks:e=>e,books:e=>{let t=Object.assign({},e);return t.page=e.page||0,t},plugins:e=>{let t=Object.assign({},e);return e.autoValue||(t.autoValue=null),e.langList?t.langList=JSON.stringify(e.langList):t.langList=null,e.voiceList?t.voiceList=JSON.stringify(e.voiceList):t.voiceList=null,t.config=JSON.stringify(e.config),t},words:e=>{let t=Object.assign({},e);return t.date=JSON.stringify(e.date),t}}),sqliteToJson:x(F)};class S{constructor(e,t,o,r,i,s,n,a,l,c,d,p){this.key=e,this.name=t,this.author=o,this.description=r,this.md5=i,this.cover=s,this.format=n,this.publisher=a,this.size=l,this.page=c,this.path=d,this.charset=p}}var _;class A{static generateBook(e,t,o,i,s,n,a){return new Promise(((l,c)=>r(this,void 0,void 0,(function*(){try{let r,c,d,p,u,h,g,y,f="";switch([c,d,u,p,h,g]=[e,"","","","",0],t){case"pdf":case"epub":case"mobi":case"azw":case"azw3":case"fb2":y=yield a.getMetadata(),[c,d,u,p,f]=[y.name||e,y.author||"",y.description||"",y.publisher||"",y.cover||""];break;case"cbr":case"cbt":case"cbz":case"cb7":y=yield a.getMetadata(),f=y.cover;break;case"txt":y=yield a.getMetadata(n),h=y.charset}let m=t.toUpperCase();r=(new Date).getTime()+"",l(new S(r,c,d,u,o,f,m,p,i,g,s,h))}catch(e){console.log(e),c(e)}}))))}}_=A,A.getRendtion=(e,t,o,r,i,s)=>{let n;var a,l;return"CACHE"===t?n=new s.CacheRender(e,o,i):"MOBI"===t||"AZW3"===t||"AZW"===t?n=new s.MobiRender(e,o,i):"EPUB"===t?n=new s.EpubRender(e,o,i):"TXT"===t?n=new s.TxtRender(e,o,i,r):"MD"===t?n=new s.MdRender(e,o,i):"PDF"===t?n=new s.PdfRender(e,o,i):"FB2"===t?n=new s.Fb2Render(e,o,i):"DOCX"===t?n=new s.DocxRender(e,o,i):"HTML"===t||"XHTML"===t||"MHTML"===t||"HTM"===t||"XML"===t?n=new s.HtmlRender(e,o,t,i):"CBR"!==t&&"CBT"!==t&&"CBZ"!==t&&"CB7"!==t||(n=new s.ComicRender((a=e,l=new ArrayBuffer(a.byteLength),new Uint8Array(l).set(new Uint8Array(a)),l),o,t,i)),n},A.addMobileBook=(e,t,o,i,s,n)=>r(void 0,void 0,void 0,(function*(){let r=(e=>{const t=atob(e),o=t.length,r=new Uint8Array(o);for(let e=0;e{let t="";const o=new Uint8Array(e),r=o.byteLength;for(let e=0;ee.name))),r.data.entries.map((e=>e.name))}catch(e){return console.error("Error listing files:",e),[]}}))}refreshToken(){return r(this,void 0,void 0,(function*(){if(this.config.access_token&&this.config.expires_at>(new Date).getTime())return this.config.access_token;let e=this.config.refresh_token,t=yield this.thirdpartyRequest.refreshThirdToken({provider:"dropbox",refresh_token:e});return this.config.access_token=t.data.access_token,this.config.expires_at=(new Date).getTime()+1e3*t.data.expires_in,t.data.access_token}))}authToken(e){return r(this,void 0,void 0,(function*(){let t=yield this.thirdpartyRequest.authThirdToken({provider:"dropbox",redirect_uri:s,code:e});return console.log(t),t.data.refresh_token}))}getAuthUrl(){return`https://www.dropbox.com/oauth2/authorize?response_type=code&token_access_type=offline&client_id=${n}&redirect_uri=${s}`}}class d extends c{constructor(e,t){super(e,t)}uploadFile(t,o){return new Promise(((i,s)=>r(this,void 0,void 0,(function*(){try{const r=yield this.refreshToken();console.log("accessToken",r);let s=o.split("/").pop()||"",n=new File([t],s,{lastModified:(new Date).getTime(),type:t.type});const a=yield e.post("https://content.dropboxapi.com/2/files/upload",n,{headers:{Authorization:`Bearer ${r}`,"Content-Type":"application/octet-stream","Dropbox-API-Arg":JSON.stringify({path:"/"+s,mode:"overwrite",autorename:!0,mute:!1})},maxContentLength:1/0,maxBodyLength:1/0});if(console.log("File uploaded successfully:",a),a.status>=300)return console.error("Error occurred during file download:",a),void i(!1);i(!0)}catch(e){console.error("Error uploading file:",e),i(!1)}}))))}downloadFile(t){return new Promise(((o,i)=>r(this,void 0,void 0,(function*(){try{const r=yield this.refreshToken(),i=yield e({url:"https://content.dropboxapi.com/2/files/download",method:"post",headers:{Authorization:`Bearer ${r}`,"Dropbox-API-Arg":JSON.stringify({path:"/"+t})},maxContentLength:1/0,maxBodyLength:1/0,responseType:"arraybuffer"});if(i.status>=300)return console.error("Error occurred during file download:",i),void o(new ArrayBuffer(0));o(i.data)}catch(e){console.error("Error occurred during file download:",e),i(e)}}))))}}class p{constructor(e,t){this.config=e,this.thirdpartyRequest=t}getFileId(t,o){return r(this,void 0,void 0,(function*(){const r=yield this.refreshToken(),i=`https://www.googleapis.com/drive/v3/files?q=name='${t}'+and+'${o}'+in+parents&spaces=appDataFolder&fields=files(id,name)`;try{const t=yield e.get(i,{headers:{Authorization:"Bearer "+r}});if(0===t.data.files.length)return"";const o=t.data.files;return console.log(o),o.length>0?o[0].id:null}catch(e){return console.error("Error occurred during file list retrieval:",e),""}}))}checkFolder(t){return r(this,void 0,void 0,(function*(){const o=yield this.refreshToken(),r=yield this.getFolderId(t);if(r)return console.log("Folder already exists:",r),r;const i={name:t,mimeType:"application/vnd.google-apps.folder",parents:["appDataFolder"]};try{const t=yield e.post("https://www.googleapis.com/drive/v3/files",i,{headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json"}});return console.log("Folder created:",t.data.id),t.data.id}catch(e){throw console.error("Error occurred during folder creation:",e),e}}))}getFolderId(t){return r(this,void 0,void 0,(function*(){const o=yield this.refreshToken(),r=`https://www.googleapis.com/drive/v3/files?q=name='${t}'+and+mimeType='application/vnd.google-apps.folder'+and+'appDataFolder'+in+parents&spaces=appDataFolder&fields=files(id,name)`;try{const t=(yield e.get(r,{headers:{Authorization:`Bearer ${o}`}})).data.files;return t.length>0?t[0].id:null}catch(e){throw console.error("Error occurred during fetching folder ID:",e),e}}))}listFiles(t){return r(this,void 0,void 0,(function*(){try{const o=yield this.refreshToken();let r=yield this.checkFolder(t);console.log(r);const i=`https://www.googleapis.com/drive/v3/files?q='${r}'+in+parents&spaces=appDataFolder&fields=files(id,name)`,s=yield e.get(i,{headers:{Authorization:`Bearer ${o}`}});return console.log("Files in folder:",s.data.files.map((e=>e.name))),s.data.files}catch(e){return console.error("Error listing files:",e),[]}}))}refreshToken(){return r(this,void 0,void 0,(function*(){if(this.config.access_token&&this.config.expires_at>(new Date).getTime())return this.config.access_token;let e=this.config.refresh_token,t=yield this.thirdpartyRequest.refreshThirdToken({provider:"google",refresh_token:e});return this.config.access_token=t.data.access_token,this.config.expires_at=(new Date).getTime()+1e3*t.data.expires_in,t.data.access_token}))}authToken(e){return r(this,void 0,void 0,(function*(){let t=yield this.thirdpartyRequest.authThirdToken({provider:"google",redirect_uri:s,code:e});return console.log(t),t.data.refresh_token}))}getAuthUrl(){return`https://accounts.google.com/o/oauth2/v2/auth?redirect_uri=${s}&prompt=consent&response_type=code&client_id=${l}&scope=https://www.googleapis.com/auth/drive.appdata&access_type=offline`}}const u=e=>"json"===e?"application/json":["jpg","jpeg","png","gif","bmp"].includes(e)?"image/"+e:"zip"===e?"application/zip":"epub"===e?"application/epub+zip":"txt"===e?"text/plain":"pdf"===e?"application/pdf":"mobi"===e?"application/x-mobipocket-ebook":"azw3"===e||"azw"===e?"application/vnd.amazon.ebook":"cbz"===e?"application/x-cbz":"cbr"===e?"application/x-cbr":"cbt"===e?"application/x-cbt":"cb7"===e?"application/x-cb7":"fb2"===e?"application/x-fictionbook+xml":"html"===e?"text/html":"css"===e?"text/css":"js"===e?"application/javascript":"xml"===e?"application/xml":"xhtml"===e?"application/xhtml+xml":"opf"===e?"application/oebps-package+xml":"ncx"===e?"application/x-dtbncx+xml":"mp3"===e?"audio/mpeg":"wav"===e?"audio/wav":"ogg"===e?"audio/ogg":"mp4"===e?"video/mp4":"webm"===e?"video/webm":"avi"===e?"video/x-msvideo":"wmv"===e?"video/x-ms-wmv":"flv"===e?"video/x-flv":"m3u8"===e?"application/x-mpegURL":"ts"===e?"video/MP2T":"3gp"===e?"video/3gpp":"3g2"===e?"video/3gpp2":"db"===e?"application/x-sqlite3":void 0;var h={getMimeType:u,databaseList:["books","notes","bookmarks","plugins","words"],configList:["readerConfig","themeColors","readingTime","recentBooks","deletedBooks","favoriteBooks","shelfList","noteTags","recordLocation","syncOptionList","customFont","sortedShelfList"]};class g extends p{constructor(e,t){super(e,t),this.getData=e=>new Promise(((t,o)=>{if(e){const r=new FileReader;r.onload=o=>t({fileName:e.name,mimeType:e.type,fileSize:e.size,data:o.target.result}),r.onerror=e=>o(e),r.readAsArrayBuffer(e)}else t({})}))}uploadFile(t,o){return new Promise(((i,s)=>r(this,void 0,void 0,(function*(){try{const r=yield this.refreshToken();console.log(r);let s=o.split("/").pop()||"",n=new File([t],s,{lastModified:(new Date).getTime(),type:t.type}),a=o.split(".").pop(),l=u(a||""),c=o.split("/")[0],d=yield this.checkFolder(c),p=yield this.getFileId(s||"",d);console.log(p,"fileId");const h={mimeType:l,name:s,parents:[d]},g=p?`https://www.googleapis.com/upload/drive/v3/files/${p}?uploadType=resumable`:"https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable";console.log(g);const y=(yield e({method:p?"PATCH":"POST",url:g,data:p?null:JSON.stringify(h),headers:{Authorization:"Bearer "+r,"Content-Type":"application/json; charset=UTF-8"}})).headers.location;console.log(y);const f=yield this.getData(n);if(0===Object.keys(f).length)return void console.log("No file.");const m=yield e.put(y,f.data,{headers:{Authorization:"Bearer "+r,"Content-Type":"application/zip","Content-Range":`bytes 0-${f.fileSize-1}/${f.fileSize}`},maxContentLength:1/0,maxBodyLength:1/0});if(console.log("File uploaded successfully:",m),m.status>=300)return console.error("Error occurred during file download:",m),void i(!1);i(!0)}catch(e){console.error("Error uploading file:",e),i(!1)}}))))}downloadFile(t){return new Promise(((o,i)=>r(this,void 0,void 0,(function*(){try{const r=yield this.refreshToken();let s=t.split("/").pop(),n=t.split("/")[0],a=yield this.checkFolder(n),l=yield this.getFileId(s||"",a);l||(console.error("File not found"),i(new Error("File not found")));const c=`https://www.googleapis.com/drive/v3/files/${l}?alt=media`,d=yield e.get(c,{headers:{Authorization:"Bearer "+r},maxContentLength:1/0,maxBodyLength:1/0,responseType:"arraybuffer"});o(d.data)}catch(e){console.error("Error occurred during file download:",e),i(e)}}))))}}class y{constructor(e,t){this.config=e,this.thirdpartyRequest=t}listFiles(t){return r(this,void 0,void 0,(function*(){try{const o=yield this.refreshToken(),r=yield e.get(`https://graph.microsoft.com/v1.0/me/drive/special/approot:/${t}:/children`,{headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json"}});return r.status>=300?[]:(console.log("Files in folder:",r.data.value.map((e=>e.name))),r.data.value.map((e=>e.name)))}catch(e){return console.error("Error listing files:",e),[]}}))}refreshToken(){return r(this,void 0,void 0,(function*(){if(this.config.access_token&&this.config.expires_at>(new Date).getTime())return this.config.access_token;let e=this.config.refresh_token,t=yield this.thirdpartyRequest.refreshThirdToken({provider:"microsoft",refresh_token:e});return this.config.access_token=t.data.access_token,this.config.expires_at=(new Date).getTime()+1e3*t.data.expires_in,t.data.access_token}))}authToken(e){return r(this,void 0,void 0,(function*(){console.log(e,"safdfsfd"),console.log({provider:"microsoft",redirect_uri:s,code:e}),console.log(this.thirdpartyRequest,"this.thirdpartyRequest");let t=yield this.thirdpartyRequest.authThirdToken({provider:"microsoft",redirect_uri:s,code:e});return console.log(t),t.data.refresh_token}))}getAuthUrl(){return`https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=${a}&scope=files.readwrite.appfolder offline_access&response_type=code&redirect_uri=${s}`}}class f extends y{constructor(e,t){super(e,t)}uploadFile(t,o){return new Promise(((i,s)=>r(this,void 0,void 0,(function*(){try{const r=yield this.refreshToken();console.log(r);let s=o.split("/").pop()||"",n=new File([t],s,{lastModified:(new Date).getTime(),type:t.type});const a="https://graph.microsoft.com/v1.0/me/drive/special/approot:/"+o+":/createUploadSession",l=(yield e.post(a,null,{headers:{Authorization:"Bearer "+r,"Content-Type":"application/json"}})).data.uploadUrl,c=yield e.put(l,n,{headers:{Authorization:"Bearer "+r,"Content-Type":n.type},maxContentLength:1/0,maxBodyLength:1/0});if(console.log("File uploaded successfully:",c),c.status>=300)return console.error("Error occurred during file download:",c),void i(!1);i(!0)}catch(e){console.error("Error uploading file:",e),i(!1)}}))))}downloadFile(t){return new Promise(((o,i)=>r(this,void 0,void 0,(function*(){try{const r=yield this.refreshToken(),i=`https://graph.microsoft.com/v1.0/me/drive/special/approot:/${t}:/content`,s=yield e.get(i,{responseType:"arraybuffer",headers:{Authorization:"Bearer "+r},maxContentLength:1/0,maxBodyLength:1/0});o(s.data)}catch(e){console.error("Error occurred during file download:",e),i(e)}}))))}}class m{downloadFile(e,t){return r(this,void 0,void 0,(function*(){return new Promise((e=>{e(!0)}))}))}uploadFile(e,t){return r(this,void 0,void 0,(function*(){return new Promise((e=>{e(!0)}))}))}listFiles(e){return r(this,void 0,void 0,(function*(){return new Promise((e=>{e([])}))}))}authToken(e){return r(this,void 0,void 0,(function*(){return new Promise((e=>{e("")}))}))}getAuthUrl(){return""}}class k{constructor(e,t){this.config=e,this.thirdpartyRequest=t}uploadFile(t,o){return new Promise(((i,s)=>r(this,void 0,void 0,(function*(){let{endpoint:r,region:s,bucketName:n,accessKeyId:a,secretAccessKey:l}=this.config;try{const c=(yield this.thirdpartyRequest.s3Upload({bucket_name:n,object_key:o,region:s,endpoint:r,access_key_id:a,secret_access_key:l})).data.url;let d=o.split("/").pop()||"",p=new File([t],d,{lastModified:(new Date).getTime(),type:t.type});const u=yield e.put(c,p,{headers:{}});console.log("File uploaded successfully:",u),i(!0)}catch(e){console.error("Error occurred during file upload:",e),i(!1)}}))))}downloadFile(t){return new Promise(((o,i)=>r(this,void 0,void 0,(function*(){let{endpoint:r,region:i,bucketName:s,accessKeyId:n,secretAccessKey:a}=this.config;try{const l=(yield this.thirdpartyRequest.s3Download({bucket_name:s,object_key:t,region:i,endpoint:r,access_key_id:n,secret_access_key:a})).data.url,c=yield e({url:l,method:"post",headers:{},responseType:"arraybuffer"});o(c.data)}catch(e){console.error("Error occurred during file download:",e),o(!1)}}))))}listFiles(e){return r(this,void 0,void 0,(function*(){let{endpoint:t,region:o,bucketName:r,accessKeyId:i,secretAccessKey:s}=this.config;try{let n=yield this.thirdpartyRequest.s3List({bucket_name:r,object_key:e,region:o,endpoint:t,access_key_id:i,secret_access_key:s});return console.log("Files in folder:",n.data.contents.map((e=>e.split("/").pop()))),n.data.contents.map((e=>e.split("/").pop()))}catch(e){return console.error("Error listing files:",e),[]}}))}}class v{constructor(e){let{username:r,password:i,url:s}=e;this.client=t(s,{authType:o.Password,username:r,password:i}),this.username=r,this.password=i}uploadFile(t,o){return new Promise(((i,s)=>r(this,void 0,void 0,(function*(){try{!1===(yield this.client.exists(o.substring(0,o.lastIndexOf("/"))))&&(yield this.client.createDirectory(o.substring(0,o.lastIndexOf("/"))));let r=o.split("/").pop()||"",s=new File([t],r,{lastModified:(new Date).getTime(),type:t.type}),n=this.client.getFileUploadLink(o);const a=new URL(n);a.search="",n=a.toString();const l=btoa(this.username+":"+this.password),c=yield e.put(n,s,{headers:{Authorization:"Basic "+l}});console.log("File uploaded successfully:",c),i(!0)}catch(e){console.error("Error uploading file:",e),i(!1)}}))))}downloadFile(t){return new Promise(((o,i)=>r(this,void 0,void 0,(function*(){try{const r=this.client.getFileDownloadLink(t);console.log(r);const i=btoa(this.username+":"+this.password),s=yield e({url:r,method:"get",headers:{Authorization:"Basic "+i},responseType:"arraybuffer"});if(s.status>=300)return console.error("Error occurred during file download:",s),void o(new ArrayBuffer(0));o(s.data)}catch(e){console.error("Error occurred during file download:",e),i(e)}}))))}listFiles(e){return r(this,void 0,void 0,(function*(){try{let t=yield this.client.getDirectoryContents(e);return console.log(t.map((e=>e.basename))),t.map((e=>e.basename))}catch(e){return console.error("Error listing files:",e),[]}}))}}const E=["book","config","cover","font"];class b{constructor(e,t,o){this.type=e,this.remote="dropbox"===e?new d(t,o):"microsoft"===e?new f(t,o):"google"===e?new g(t,o):"s3compatible"===e?new k(t,o):"webdav"===e?new v(t):new m}downloadFile(e,t){return r(this,void 0,void 0,(function*(){return yield this.remote.downloadFile(t+"/"+e)}))}uploadFile(e,t,o){return r(this,void 0,void 0,(function*(){return yield this.remote.uploadFile(o,t+"/"+e)}))}listFiles(e){return r(this,void 0,void 0,(function*(){return yield this.remote.listFiles(e)}))}downloadAllFiles(){return r(this,void 0,void 0,(function*(){for(let e of E){let t=yield this.listFiles(e);for(let o of t)yield this.downloadFile(o,e)}}))}authToken(e){return r(this,void 0,void 0,(function*(){return yield this.remote.authToken(e)}))}getAuthUrl(){return this.remote.getAuthUrl?this.remote.getAuthUrl():""}}const w={notes:"SELECT * FROM notes WHERE key = ?",bookmarks:"SELECT * FROM bookmarks WHERE key = ?",books:"SELECT * FROM books WHERE key = ?",plugins:"SELECT * FROM plugins WHERE key = ?",words:"SELECT * FROM words WHERE key = ?"},T={notes:"SELECT * FROM notes WHERE bookKey = ?",bookmarks:"SELECT * FROM bookmarks WHERE bookKey = ?",words:"SELECT * FROM words WHERE bookKey = ?",books:"SELECT * FROM books WHERE key = ?"},R={notes:"DELETE FROM notes WHERE bookKey = ?",bookmarks:"DELETE FROM bookmarks WHERE bookKey = ?",words:"DELETE FROM words WHERE bookKey = ?"};function x(e){for(const t in e)e.hasOwnProperty(t)&&(e[`temp-${t}`]=e[t]);return e}const L={notes:e=>{let t=Object.assign({},e);return t.date=JSON.parse(e.date),t.tag=JSON.parse(e.tag),t},bookmarks:e=>e,books:e=>e,plugins:e=>{let t=Object.assign({},e);return e.autoValue||delete t.autoValue,e.langList?t.langList=JSON.parse(e.langList):delete t.langList,e.voiceList?t.voiceList=JSON.parse(e.voiceList):delete t.voiceList,t.config=JSON.parse(e.config),t},words:e=>{let t=Object.assign({},e);return t.date=JSON.parse(e.date),t}};var F={sqlStatement:{createTableStatement:x({notes:'\n CREATE TABLE IF NOT EXISTS "notes" (\n "key" text PRIMARY KEY,\n "bookKey" text,\n "date" object,\n "chapter" text,\n "chapterIndex" integer,\n "text" text,\n "cfi" text,\n "range" text,\n "notes" text,\n "percentage" text,\n "color" integer,\n "tag" array\n )\n ',bookmarks:'\n CREATE TABLE IF NOT EXISTS "bookmarks" (\n "key" text PRIMARY KEY,\n "bookKey" text,\n "cfi" text,\n "label" text,\n "percentage" text,\n "chapter" text\n );\n ',books:'\n CREATE TABLE IF NOT EXISTS "books" (\n "key" text PRIMARY KEY,\n "name" text,\n "author" text,\n "description" text,\n "md5" text,\n "cover" text,\n "format" text,\n "publisher" text,\n "size" integer,\n "page" integer,\n "path" text,\n "charset" text\n );\n ',plugins:'\n CREATE TABLE IF NOT EXISTS "plugins" (\n "key" text PRIMARY KEY,\n "type" text,\n "displayName" text,\n "icon" text,\n "version" text,\n "config" object,\n "autoValue" string,\n "langList" text,\n "voiceList" text,\n "scriptSHA256" text,\n "script" text\n );\n ',words:'\n CREATE TABLE IF NOT EXISTS "words" (\n "key" text PRIMARY KEY,\n "bookKey" text,\n "date" object,\n "word" text,\n "chapter" text\n );\n '}),getAllStatement:x({notes:"SELECT * FROM notes",bookmarks:"SELECT * FROM bookmarks",books:"SELECT * FROM books",plugins:"SELECT * FROM plugins",words:"SELECT * FROM words"}),saveStatement:x({notes:"INSERT OR REPLACE INTO notes (key, bookKey, chapter, chapterIndex, text, cfi, range, notes, date, percentage, color, tag) VALUES (@key, @bookKey, @chapter, @chapterIndex, @text, @cfi, @range, @notes, @date, @percentage, @color, @tag)",bookmarks:"INSERT OR REPLACE INTO bookmarks (key, bookKey, cfi, label, percentage, chapter) VALUES (@key, @bookKey, @cfi, @label, @percentage, @chapter)",books:"INSERT OR REPLACE INTO books (key, name, author, description, md5, cover, format, publisher, size, page, path, charset) VALUES (@key, @name, @author, @description, @md5, @cover, @format, @publisher, @size, @page, @path, @charset)",plugins:"INSERT OR REPLACE INTO plugins (key, type, displayName, icon, version, config, autoValue, langList, voiceList, scriptSHA256, script) VALUES (@key, @type, @displayName, @icon, @version, @config, @autoValue, @langList, @voiceList, @scriptSHA256, @script)",words:"INSERT OR REPLACE INTO words (key, bookKey, date, word, chapter) VALUES (@key, @bookKey, @date, @word, @chapter)"}),deleteAllStatement:x({notes:"DELETE FROM notes",bookmarks:"DELETE FROM bookmarks",books:"DELETE FROM books",plugins:"DELETE FROM plugins",words:"DELETE FROM words"}),updateStatement:x({notes:"UPDATE notes SET bookKey = @bookKey, chapter = @chapter, chapterIndex = @chapterIndex, text = @text, cfi = @cfi, range = @range, notes = @notes, date = @date, percentage = @percentage, color = @color, tag = @tag WHERE key = @key",bookmarks:"UPDATE bookmarks SET bookKey = @bookKey, cfi = @cfi, label = @label, percentage = @percentage, chapter = @chapter WHERE key = @key",books:"UPDATE books SET name = @name, author = @author, description = @description, md5 = @md5, cover = @cover, format = @format, publisher = @publisher, size = @size, page = @page, path = @path, charset = @charset WHERE key = @key",plugins:"UPDATE plugins SET type = @type, displayName = @displayName, icon = @icon, version = @version, config = @config, autoValue = @autoValue, langList = @langList, voiceList = @voiceList, scriptSHA256 = @scriptSHA256, script = @script WHERE key = @key",words:"UPDATE words SET bookKey = @bookKey, date = @date, word = @word, chapter = @chapter WHERE key = @key"}),deleteStatement:x({notes:"DELETE FROM notes WHERE key = ?",bookmarks:"DELETE FROM bookmarks WHERE key = ?",books:"DELETE FROM books WHERE key = ?",plugins:"DELETE FROM plugins WHERE key = ?",words:"DELETE FROM words WHERE key = ?"}),getStatement:x(w),getByBookKeyStatement:x(T),getByBookKeysStatement:x({notes:e=>`SELECT * FROM notes WHERE bookKey IN (${e.map((()=>"?")).join(",")})`,bookmarks:e=>`SELECT * FROM bookmarks WHERE bookKey IN (${e.map((()=>"?")).join(",")})`,words:e=>`SELECT * FROM words WHERE bookKey IN (${e.map((()=>"?")).join(",")})`,books:e=>`SELECT * FROM books WHERE key IN (${e.map((()=>"?")).join(",")})`}),deleteByBookKeyStatement:x(R)},jsonToSqlite:x({notes:e=>{let t=Object.assign({},e);return t.date=JSON.stringify(e.date),t.tag=JSON.stringify(e.tag),t},bookmarks:e=>e,books:e=>{let t=Object.assign({},e);return t.page=e.page||0,t},plugins:e=>{let t=Object.assign({},e);return e.autoValue||(t.autoValue=null),e.langList?t.langList=JSON.stringify(e.langList):t.langList=null,e.voiceList?t.voiceList=JSON.stringify(e.voiceList):t.voiceList=null,t.config=JSON.stringify(e.config),t},words:e=>{let t=Object.assign({},e);return t.date=JSON.stringify(e.date),t}}),sqliteToJson:x(L)};class S{constructor(e,t,o,r,i,s,n,a,l,c,d,p){this.key=e,this.name=t,this.author=o,this.description=r,this.md5=i,this.cover=s,this.format=n,this.publisher=a,this.size=l,this.page=c,this.path=d,this.charset=p}}var _;class A{static generateBook(e,t,o,i,s,n,a){return new Promise(((l,c)=>r(this,void 0,void 0,(function*(){try{let r,c,d,p,u,h,g,y,f="";switch([c,d,u,p,h,g]=[e,"","","","",0],t){case"pdf":case"epub":case"mobi":case"azw":case"azw3":case"fb2":y=yield a.getMetadata(),[c,d,u,p,f]=[y.name||e,y.author||"",y.description||"",y.publisher||"",y.cover||""];break;case"cbr":case"cbt":case"cbz":case"cb7":y=yield a.getMetadata(),f=y.cover;break;case"txt":y=yield a.getMetadata(n),h=y.charset}let m=t.toUpperCase();r=(new Date).getTime()+"",l(new S(r,c,d,u,o,f,m,p,i,g,s,h))}catch(e){console.log(e),c(e)}}))))}}_=A,A.getRendtion=(e,t,o,r,i,s)=>{let n;var a,l;return"CACHE"===t?n=new s.CacheRender(e,o,i):"MOBI"===t||"AZW3"===t||"AZW"===t?n=new s.MobiRender(e,o,i):"EPUB"===t?n=new s.EpubRender(e,o,i):"TXT"===t?n=new s.TxtRender(e,o,i,r):"MD"===t?n=new s.MdRender(e,o,i):"PDF"===t?n=new s.PdfRender(e,o,i):"FB2"===t?n=new s.Fb2Render(e,o,i):"DOCX"===t?n=new s.DocxRender(e,o,i):"HTML"===t||"XHTML"===t||"MHTML"===t||"HTM"===t||"XML"===t?n=new s.HtmlRender(e,o,t,i):"CBR"!==t&&"CBT"!==t&&"CBZ"!==t&&"CB7"!==t||(n=new s.ComicRender((a=e,l=new ArrayBuffer(a.byteLength),new Uint8Array(l).set(new Uint8Array(a)),l),o,t,i)),n},A.addMobileBook=(e,t,o,i,s,n)=>r(void 0,void 0,void 0,(function*(){let r=(e=>{const t=atob(e),o=t.length,r=new Uint8Array(o);for(let e=0;e{let t="";const o=new Uint8Array(e),r=o.byteLength;for(let e=0;e { toast(this.props.t(message)); }; - handleBackup = (name: string) => { - this.setState({ currentDrive: name }, async () => { - if (name === "local") { - let result = await backup(name); - if (result) { - this.handleFinish(); - } else { - this.showMessage("Upload failed, check your connection"); - } - return; - } - if (name === "onedrive" || name === "googledrive" || name === "dropbox") { - if (!this.state.isDeveloperVer) { - this.showMessage( - "This feature is only available in the developer version" - ); - return; - } - } - if (!ConfigService.getReaderConfig(name + "_token") && name !== "local") { - this.props.handleTokenDialog(true); - return; - } - this.showMessage("Uploading, please wait"); - this.props.handleLoadingDialog(true); + handleBackup = async () => { + let name = this.state.currentDrive; + if (name === "local") { let result = await backup(name); if (result) { this.handleFinish(); } else { this.showMessage("Upload failed, check your connection"); } - }); + return; + } + + if (!ConfigService.getReaderConfig(name + "_token") && name !== "local") { + this.props.handleTokenDialog(true); + return; + } + this.showMessage("Uploading, please wait"); + this.props.handleLoadingDialog(true); + let result = await backup(name); + if (result) { + this.handleFinish(); + } else { + this.showMessage("Upload failed, check your connection"); + } }; - handleRestore = (name: string) => { - this.setState({ currentDrive: name }, async () => { - if (name === "local") { - let result = await restore(name); - if (result) { - this.handleFinish(); - } else { - this.showMessage("Download failed,network problem or no backup"); - this.props.handleLoadingDialog(false); - } - return; - } - if (name === "onedrive" || name === "googledrive" || name === "dropbox") { - if (!this.state.isDeveloperVer) { - this.showMessage( - "This feature is only available in the developer version" - ); - return; - } - } - - if (!ConfigService.getReaderConfig(name + "_token")) { - this.props.handleTokenDialog(true); - return; - } - this.props.handleLoadingDialog(true); - this.showMessage("Downloading, please wait"); - + handleRestore = async () => { + let name = this.state.currentDrive; + if (name === "local") { let result = await restore(name); if (result) { this.handleFinish(); @@ -127,123 +93,135 @@ class BackupDialog extends React.Component< this.showMessage("Download failed,network problem or no backup"); this.props.handleLoadingDialog(false); } - }); + return; + } + + if (!ConfigService.getReaderConfig(name + "_token")) { + this.props.handleTokenDialog(true); + return; + } + this.props.handleLoadingDialog(true); + this.showMessage("Downloading, please wait"); + + let result = await restore(name); + if (result) { + this.handleFinish(); + } else { + this.showMessage("Download failed,network problem or no backup"); + this.props.handleLoadingDialog(false); + } + }; + handleSelectSource = (event: any) => { + if ( + (event.target.value === "ftp" || + event.target.value === "webdav" || + event.target.value === "sftp") && + !isElectron + ) { + toast( + this.props.t( + "Koodo Reader's web version are limited by the browser, for more powerful features, please download the desktop version." + ) + ); + return; + } + if ( + event.target.value === "google" || + event.target.value === "s3compatible" || + event.target.value === "microsoft" || + event.target.value === "dropbox" + ) { + toast(this.props.t("This feature is not available in the free version")); + return; + } + if (event.target.value === "add") { + toast(this.props.t("Please add data source in the setting")); + return; + } + this.setState({ currentDrive: event.target.value }); }; render() { - const renderDrivePage = () => { - return driveList.map((item) => { - return ( -
  • { - //webdav is avavilible on desktop - if ( - (item.value === "ftp" || item.value === "sftp") && - !isElectron - ) { - toast( - this.props.t( - "Koodo Reader's web version are limited by the browser, for more powerful features, please download the desktop version." - ) - ); - return; - } - if (this.state.isBackup === "yes") { - this.handleBackup(item.value); - } else { - this.handleRestore(item.value); - } - }} - > -
    - - {ConfigService.getReaderConfig(item.value + "_token") ? ( -
    { - ConfigService.setReaderConfig(item.value + "_token", ""); - this.showMessage("Unauthorize successful"); - }} - style={{ color: "rgb(0, 120, 212)" }} - > - Unauthorize -
    - ) : ( -
    - {item.label} -
    - )} -
    -
  • - ); - }); - }; - let syncUtil = new SyncUtil(this.state.currentDrive, {}); - - const dialogProps = { - driveName: this.state.currentDrive, - url: syncUtil.getAuthUrl(), - title: - driveList[ - _.findLastIndex(driveList, { - value: this.state.currentDrive, - }) - ].label, - }; - return (
    - {this.props.isOpenTokenDialog ? : null} - {this.state.currentStep === 0 ? (
    -
    { - this.setState({ isBackup: "yes" }); - }} - > - -
    - Backup -
    -
    - -
    { - if (!isElectron) { - event.preventDefault(); - toast( - this.props.t( - "Koodo Reader's web version are limited by the browser, for more powerful features, please download the desktop version." +
    + { + this.setState({ currentStep: 1, isBackup: "yes" }); + this.handleBackup(); + }} + > +
    + Backup to + +
    +
    +
    + { + if (!isElectron) { + event.preventDefault(); + toast( + this.props.t( + "Koodo Reader's web version are limited by the browser, for more powerful features, please download the desktop version." + ) + ); + return; + } + this.setState({ currentStep: 1, isBackup: "no" }); + this.handleRestore(); + }} + > +
    + Restore from +
    -
    - ) : this.state.currentStep === 1 ? ( -
    -
    {renderDrivePage()}
    ) : (
    @@ -256,11 +234,6 @@ class BackupDialog extends React.Component< : "Restore successful"}
    - {this.state.isBackup ? null : ( -
    - Try refresh or restart -
    - )}
    )} diff --git a/src/components/dialogs/backupDialog/index.tsx b/src/components/dialogs/backupDialog/index.tsx index f9aa80c1..6d64e30e 100644 --- a/src/components/dialogs/backupDialog/index.tsx +++ b/src/components/dialogs/backupDialog/index.tsx @@ -17,6 +17,7 @@ const mapStateToProps = (state: stateType) => { notes: state.reader.notes, digests: state.reader.digests, isOpenTokenDialog: state.backupPage.isOpenTokenDialog, + dataSourceList: state.backupPage.dataSourceList, }; }; const actionCreator = { diff --git a/src/components/dialogs/backupDialog/interface.tsx b/src/components/dialogs/backupDialog/interface.tsx index 6c7aedaf..0e6149f5 100644 --- a/src/components/dialogs/backupDialog/interface.tsx +++ b/src/components/dialogs/backupDialog/interface.tsx @@ -14,6 +14,7 @@ export interface BackupDialogProps extends RouteComponentProps { books: BookModel[]; notes: NoteModel[]; digests: NoteModel[]; + dataSourceList: string[]; bookmarks: BookmarkModel[]; } export interface BackupDialogState { diff --git a/src/components/dialogs/settingDialog/component.tsx b/src/components/dialogs/settingDialog/component.tsx index 6d130a86..966a17e5 100644 --- a/src/components/dialogs/settingDialog/component.tsx +++ b/src/components/dialogs/settingDialog/component.tsx @@ -27,7 +27,8 @@ import { } from "../../../utils/common"; import { getStorageLocation, reloadManager } from "../../../utils/common"; import DatabaseService from "../../../utils/storage/databaseService"; -import { driveList } from "../../../constants/driveList"; +import { driveInputConfig, driveList } from "../../../constants/driveList"; +import { SyncUtil } from "../../../assets/lib/kookit-extra-browser.min"; declare var window: any; class SettingDialog extends React.Component< SettingInfoProps, @@ -72,18 +73,16 @@ class SettingDialog extends React.Component< }), storageLocation: getStorageLocation() || "", isAddNew: false, + currentDrive: "", + driveConfig: {}, }; } componentDidMount(): void { this.props.handleFetchPlugins(); this.loadFont(); - let dataSourceList = ConfigService.getReaderConfig("dataSourceList") || [ - "local", - ]; - if (dataSourceList) { - dataSourceList = JSON.parse(dataSourceList); - this.props.setDataSource(dataSourceList); - } + let dataSourceList = ConfigService.getAllListConfig("dataSourceList"); + + this.props.setDataSource(dataSourceList); } loadFont = () => { if (dropdownList[0].option.length <= 2) { @@ -207,6 +206,36 @@ class SettingDialog extends React.Component< } this.handleSetting("isOpenInMain"); }; + handleCancel = () => { + this.setState({ currentDrive: "" }); + }; + handleConfirm = async () => { + if ( + this.state.currentDrive === "webdav" || + this.state.currentDrive === "ftp" || + this.state.currentDrive === "sftp" || + this.state.currentDrive === "s3compatible" + ) { + ConfigService.setReaderConfig( + `${this.state.currentDrive}_token`, + JSON.stringify(this.state.driveConfig) + ); + } else { + let syncUtil = new SyncUtil(this.state.currentDrive, {}); + let refreshToken = await syncUtil.authToken(this.state.driveConfig.token); + ConfigService.setReaderConfig( + `${this.state.currentDrive}_token`, + JSON.stringify({ refresh_token: refreshToken }) + ); + } + ConfigService.setListConfig(this.state.currentDrive, "dataSourceList"); + this.props.setDataSource( + ConfigService.getAllListConfig("dataSourceList") || [] + ); + + this.setState({ currentDrive: "" }); + toast.success(this.props.t("Addition successful")); + }; render() { return (
    @@ -280,7 +309,7 @@ class SettingDialog extends React.Component< this.handleChangeTab("sync"); }} > - Sync and Backup + Sync and backup ) : this.state.currentTab === "sync" ? ( <> + {this.state.currentDrive && ( +
    + {this.state.currentDrive === "webdav" || + this.state.currentDrive === "ftp" || + this.state.currentDrive === "sftp" || + this.state.currentDrive === "s3compatible" ? ( + <> + {driveInputConfig[this.state.currentDrive].map((item) => { + return ( + { + this.setState((prevState) => ({ + driveConfig: { + ...prevState.driveConfig, + [item.value]: e.target.value, + }, + })); + }} + id={"token-dialog-" + item.value + "-box"} + className="token-dialog-username-box" + /> + ); + })} + + ) : ( + <> +