diff --git a/dist/frontend.js b/dist/frontend.js
index 7b30c6e..4ed4c8f 100644
--- a/dist/frontend.js
+++ b/dist/frontend.js
@@ -67,7 +67,7 @@ class y{constructor(e,t,i){this.__parts=[],this.template=e,this.processor=t,this
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
-const _=e=>null===e||!("object"==typeof e||"function"==typeof e),$=e=>Array.isArray(e)||!(!e||!e[Symbol.iterator]);class T{constructor(e,t,i){this.dirty=!0,this.element=e,this.name=t,this.strings=i,this.parts=[];for(let e=0;e{try{const e={get capture(){return R=!0,!1}};window.addEventListener("test",e,e),window.removeEventListener("test",e,e)}catch(e){}})();class N{constructor(e,t,i){this.value=void 0,this.__pendingValue=void 0,this.element=e,this.eventName=t,this.eventContext=i,this.__boundHandleEvent=e=>this.handleEvent(e)}setValue(e){this.__pendingValue=e}commit(){for(;x(this.__pendingValue);){const e=this.__pendingValue;this.__pendingValue=w,e(this)}if(this.__pendingValue===w)return;const e=this.__pendingValue,t=this.value,i=null==e||null!=t&&(e.capture!==t.capture||e.once!==t.once||e.passive!==t.passive),a=null!=e&&(null==t||i);i&&this.element.removeEventListener(this.eventName,this.__boundHandleEvent,this.__options),a&&(this.__options=j(e),this.element.addEventListener(this.eventName,this.__boundHandleEvent,this.__options)),this.value=e,this.__pendingValue=w}handleEvent(e){"function"==typeof this.value?this.value.call(this.eventContext||this.element,e):this.value.handleEvent(e)}}const j=e=>e&&(R?{capture:e.capture,passive:e.passive,once:e.once}:e.capture)
+const _=e=>null===e||!("object"==typeof e||"function"==typeof e),$=e=>Array.isArray(e)||!(!e||!e[Symbol.iterator]);class T{constructor(e,t,i){this.dirty=!0,this.element=e,this.name=t,this.strings=i,this.parts=[];for(let e=0;e{try{const e={get capture(){return R=!0,!1}};window.addEventListener("test",e,e),window.removeEventListener("test",e,e)}catch(e){}})();class L{constructor(e,t,i){this.value=void 0,this.__pendingValue=void 0,this.element=e,this.eventName=t,this.eventContext=i,this.__boundHandleEvent=e=>this.handleEvent(e)}setValue(e){this.__pendingValue=e}commit(){for(;x(this.__pendingValue);){const e=this.__pendingValue;this.__pendingValue=w,e(this)}if(this.__pendingValue===w)return;const e=this.__pendingValue,t=this.value,i=null==e||null!=t&&(e.capture!==t.capture||e.once!==t.once||e.passive!==t.passive),a=null!=e&&(null==t||i);i&&this.element.removeEventListener(this.eventName,this.__boundHandleEvent,this.__options),a&&(this.__options=j(e),this.element.addEventListener(this.eventName,this.__boundHandleEvent,this.__options)),this.value=e,this.__pendingValue=w}handleEvent(e){"function"==typeof this.value?this.value.call(this.eventContext||this.element,e):this.value.handleEvent(e)}}const j=e=>e&&(R?{capture:e.capture,passive:e.passive,once:e.once}:e.capture)
/**
* @license
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
@@ -80,7 +80,7 @@ const _=e=>null===e||!("object"==typeof e||"function"==typeof e),$=e=>Array.isAr
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
- */;function L(e){let t=I.get(e.type);void 0===t&&(t={stringsArray:new WeakMap,keyString:new Map},I.set(e.type,t));let i=t.stringsArray.get(e.strings);if(void 0!==i)return i;const a=e.strings.join(n);return i=t.keyString.get(a),void 0===i&&(i=new d(e,e.getTemplateElement()),t.keyString.set(a,i)),t.stringsArray.set(e.strings,i),i}const I=new Map,G=new WeakMap;
+ */;function N(e){let t=I.get(e.type);void 0===t&&(t={stringsArray:new WeakMap,keyString:new Map},I.set(e.type,t));let i=t.stringsArray.get(e.strings);if(void 0!==i)return i;const a=e.strings.join(n);return i=t.keyString.get(a),void 0===i&&(i=new d(e,e.getTemplateElement()),t.keyString.set(a,i)),t.stringsArray.set(e.strings,i),i}const I=new Map,G=new WeakMap;
/**
* @license
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
@@ -107,7 +107,7 @@ const _=e=>null===e||!("object"==typeof e||"function"==typeof e),$=e=>Array.isAr
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
-class{handleAttributeExpressions(e,t,i,a){const r=t[0];if("."===r){return new A(e,t.slice(1),i).parts}return"@"===r?[new N(e,t.slice(1),a.eventContext)]:"?"===r?[new P(e,t.slice(1),i)]:new T(e,t,i).parts}handleTextExpression(e){return new U(e)}};
+class{handleAttributeExpressions(e,t,i,a){const r=t[0];if("."===r){return new P(e,t.slice(1),i).parts}return"@"===r?[new L(e,t.slice(1),a.eventContext)]:"?"===r?[new A(e,t.slice(1),i)]:new T(e,t,i).parts}handleTextExpression(e){return new U(e)}};
/**
* @license
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
@@ -145,7 +145,7 @@ const X="adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.pro
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
-(window.litElementVersions||(window.litElementVersions=[])).push("2.3.1");const te={};class ie extends J{static getStyles(){return this.styles}static _getUniqueStyles(){if(this.hasOwnProperty(JSCompiler_renameProperty("_styles",this)))return;const e=this.getStyles();if(void 0===e)this._styles=[];else if(Array.isArray(e)){const t=(e,i)=>e.reduceRight((e,i)=>Array.isArray(i)?t(i,e):(e.add(i),e),i),i=t(e,new Set),a=[];i.forEach(e=>a.unshift(e)),this._styles=a}else this._styles=[e]}initialize(){super.initialize(),this.constructor._getUniqueStyles(),this.renderRoot=this.createRenderRoot(),window.ShadowRoot&&this.renderRoot instanceof window.ShadowRoot&&this.adoptStyles()}createRenderRoot(){return this.attachShadow({mode:"open"})}adoptStyles(){const e=this.constructor._styles;0!==e.length&&(void 0===window.ShadyCSS||window.ShadyCSS.nativeShadow?X?this.renderRoot.adoptedStyleSheets=e.map(e=>e.styleSheet):this._needsShimAdoptedStyleSheets=!0:window.ShadyCSS.ScopingShim.prepareAdoptedCssText(e.map(e=>e.cssText),this.localName))}connectedCallback(){super.connectedCallback(),this.hasUpdated&&void 0!==window.ShadyCSS&&window.ShadyCSS.styleElement(this)}update(e){const t=this.render();super.update(e),t!==te&&this.constructor.render(t,this.renderRoot,{scopeName:this.localName,eventContext:this}),this._needsShimAdoptedStyleSheets&&(this._needsShimAdoptedStyleSheets=!1,this.constructor._styles.forEach(e=>{const t=document.createElement("style");t.textContent=e.cssText,this.renderRoot.appendChild(t)}))}render(){return te}}ie.finalized=!0,ie.render=(e,t,i)=>{if(!i||"object"!=typeof i||!i.scopeName)throw new Error("The `scopeName` option is required.");const a=i.scopeName,r=G.has(t),n=q&&11===t.nodeType&&!!t.host,s=n&&!H.has(a),l=s?document.createDocumentFragment():t;if(((e,t,i)=>{let a=G.get(t);void 0===a&&(o(t,t.firstChild),G.set(t,a=new U(Object.assign({templateFactory:L},i))),a.appendInto(t)),a.setValue(e),a.commit()})(e,l,Object.assign({templateFactory:B(a)},i)),s){const e=G.get(l);G.delete(l);const i=e.value instanceof y?e.value.template:void 0;F(a,l,i),o(t,t.firstChild),t.appendChild(l),G.set(t,e)}!r&&n&&window.ShadyCSS.styleElement(t.host)};
+(window.litElementVersions||(window.litElementVersions=[])).push("2.3.1");const te={};class ie extends J{static getStyles(){return this.styles}static _getUniqueStyles(){if(this.hasOwnProperty(JSCompiler_renameProperty("_styles",this)))return;const e=this.getStyles();if(void 0===e)this._styles=[];else if(Array.isArray(e)){const t=(e,i)=>e.reduceRight((e,i)=>Array.isArray(i)?t(i,e):(e.add(i),e),i),i=t(e,new Set),a=[];i.forEach(e=>a.unshift(e)),this._styles=a}else this._styles=[e]}initialize(){super.initialize(),this.constructor._getUniqueStyles(),this.renderRoot=this.createRenderRoot(),window.ShadowRoot&&this.renderRoot instanceof window.ShadowRoot&&this.adoptStyles()}createRenderRoot(){return this.attachShadow({mode:"open"})}adoptStyles(){const e=this.constructor._styles;0!==e.length&&(void 0===window.ShadyCSS||window.ShadyCSS.nativeShadow?X?this.renderRoot.adoptedStyleSheets=e.map(e=>e.styleSheet):this._needsShimAdoptedStyleSheets=!0:window.ShadyCSS.ScopingShim.prepareAdoptedCssText(e.map(e=>e.cssText),this.localName))}connectedCallback(){super.connectedCallback(),this.hasUpdated&&void 0!==window.ShadyCSS&&window.ShadyCSS.styleElement(this)}update(e){const t=this.render();super.update(e),t!==te&&this.constructor.render(t,this.renderRoot,{scopeName:this.localName,eventContext:this}),this._needsShimAdoptedStyleSheets&&(this._needsShimAdoptedStyleSheets=!1,this.constructor._styles.forEach(e=>{const t=document.createElement("style");t.textContent=e.cssText,this.renderRoot.appendChild(t)}))}render(){return te}}ie.finalized=!0,ie.render=(e,t,i)=>{if(!i||"object"!=typeof i||!i.scopeName)throw new Error("The `scopeName` option is required.");const a=i.scopeName,r=G.has(t),n=q&&11===t.nodeType&&!!t.host,s=n&&!H.has(a),l=s?document.createDocumentFragment():t;if(((e,t,i)=>{let a=G.get(t);void 0===a&&(o(t,t.firstChild),G.set(t,a=new U(Object.assign({templateFactory:N},i))),a.appendInto(t)),a.setValue(e),a.commit()})(e,l,Object.assign({templateFactory:B(a)},i)),s){const e=G.get(l);G.delete(l);const i=e.value instanceof y?e.value.template:void 0;F(a,l,i),o(t,t.firstChild),t.appendChild(l),G.set(t,e)}!r&&n&&window.ShadyCSS.styleElement(t.host)};
/**
* @license
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
@@ -159,7 +159,7 @@ const X="adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.pro
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
-const ae=new WeakMap,re=v(e=>t=>{if(!(t instanceof U))throw new Error("unsafeHTML can only be used in text bindings");const i=ae.get(t);if(void 0!==i&&_(e)&&e===i.value&&t.value===i.fragment)return;const a=document.createElement("template");a.innerHTML=e;const r=document.importNode(a.content,!0);t.setValue(r),ae.set(t,{value:e,fragment:r})}),oe=new WeakMap,ne=v(e=>t=>{if(!(t instanceof U))throw new Error("unsafeSVG can only be used in text bindings");const i=oe.get(t);if(void 0!==i&&_(e)&&e===i.value&&t.value===i.fragment)return;const a=document.createElement("template");a.innerHTML=``;const o=a.content,n=o.firstChild;o.removeChild(n),r(o,n.firstChild);const s=document.importNode(o,!0);t.setValue(s),oe.set(t,{value:e,fragment:s})}),se=new WeakMap,le=v(e=>t=>{if(!(t instanceof C)||t instanceof E||"style"!==t.committer.name||t.committer.parts.length>1)throw new Error("The `styleMap` directive must be used in the style attribute and must be the only part in the attribute.");const{committer:i}=t,{style:a}=i.element;let r=se.get(t);void 0===r&&(a.cssText=i.strings.join(" "),se.set(t,r=new Set)),r.forEach(t=>{t in e||(r.delete(t),-1===t.indexOf("-")?a[t]=null:a.removeProperty(t))});for(const t in e)r.add(t),-1===t.indexOf("-")?a[t]=e[t]:a.setProperty(t,e[t])});async function de(e){try{e=new URL(e,window.location.origin).href}catch(e){}return{url:e,coll:"id-"+(await async function(e,t){const i=(new TextEncoder).encode(e),a=await crypto.subtle.digest(t,i);return Array.from(new Uint8Array(a)).map(e=>e.toString(16).padStart(2,"0")).join("")}(e,"SHA-256")).slice(0,12)}}var ce;function be(e,t){void 0===t&&(t={});var i=t.registrationOptions;void 0===i&&(i={}),delete t.registrationOptions;var a=function(e){for(var i=[],a=arguments.length-1;a-- >0;)i[a]=arguments[a+1];t&&t[e]&&t[e].apply(t,i)};"serviceWorker"in navigator&&ce.then((function(){Boolean("localhost"===window.location.hostname||"[::1]"===window.location.hostname||window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/))?(!function(e,t,i){fetch(e).then((function(a){404===a.status?(t("error",new Error("Service worker not found at "+e)),ue()):-1===a.headers.get("content-type").indexOf("javascript")?(t("error",new Error("Expected "+e+" to have javascript content-type, but received "+a.headers.get("content-type"))),ue()):he(e,t,i)})).catch((function(e){return fe(t,e)}))}(e,a,i),navigator.serviceWorker.ready.then((function(e){a("ready",e)}))):(he(e,a,i),navigator.serviceWorker.ready.then((function(e){a("ready",e)})))}))}function fe(e,t){navigator.onLine||e("offline"),e("error",t)}function he(e,t,i){navigator.serviceWorker.register(e,i).then((function(e){t("registered",e),e.waiting?t("updated",e):e.onupdatefound=function(){t("updatefound",e);var i=e.installing;i.onstatechange=function(){"installed"===i.state&&(navigator.serviceWorker.controller?t("updated",e):t("cached",e))}}})).catch((function(e){return fe(t,e)}))}function ue(){"serviceWorker"in navigator&&navigator.serviceWorker.ready.then((function(e){e.unregister()}))}"undefined"!=typeof window&&(ce="undefined"!=typeof Promise?new Promise((function(e){return window.addEventListener("load",e)})):{then:function(e){return window.addEventListener("load",e)}});var me=i(70),pe=i.n(me),ge=i(71),ve=i.n(ge),xe=(i(92),i(72)),we=i.n(xe),ke=i(73),ye=i.n(ke),ze=i(74),Se=i.n(ze),_e=i(75),$e=i.n(_e),Te=i(76),Ce=i.n(Te),Ue=i(77),Pe=i.n(Ue),Ae=i(78),Ee=i.n(Ae),Re=i(79),Ne=i.n(Re);const je=(Le=we.a,new Q(String(Le),K));var Le;function Ie(e){return[je,e]}const Ge=new Worker("./sw.js");class Oe extends ie{constructor(){super(),this.sourceUrl=null,this.sourceLoaded=!1,this.showTerms=!1,this.pageParams={}}static get properties(){return{pageParams:{type:Object},sourceUrl:{type:String},navMenuShown:{type:Boolean},showTerms:{type:Boolean},sourceLoaded:{type:Boolean}}}static get styles(){return Ie(ee`
+const ae=new WeakMap,re=v(e=>t=>{if(!(t instanceof U))throw new Error("unsafeHTML can only be used in text bindings");const i=ae.get(t);if(void 0!==i&&_(e)&&e===i.value&&t.value===i.fragment)return;const a=document.createElement("template");a.innerHTML=e;const r=document.importNode(a.content,!0);t.setValue(r),ae.set(t,{value:e,fragment:r})}),oe=new WeakMap,ne=v(e=>t=>{if(!(t instanceof U))throw new Error("unsafeSVG can only be used in text bindings");const i=oe.get(t);if(void 0!==i&&_(e)&&e===i.value&&t.value===i.fragment)return;const a=document.createElement("template");a.innerHTML=``;const o=a.content,n=o.firstChild;o.removeChild(n),r(o,n.firstChild);const s=document.importNode(o,!0);t.setValue(s),oe.set(t,{value:e,fragment:s})}),se=new WeakMap,le=v(e=>t=>{if(!(t instanceof C)||t instanceof E||"style"!==t.committer.name||t.committer.parts.length>1)throw new Error("The `styleMap` directive must be used in the style attribute and must be the only part in the attribute.");const{committer:i}=t,{style:a}=i.element;let r=se.get(t);void 0===r&&(a.cssText=i.strings.join(" "),se.set(t,r=new Set)),r.forEach(t=>{t in e||(r.delete(t),-1===t.indexOf("-")?a[t]=null:a.removeProperty(t))});for(const t in e)r.add(t),-1===t.indexOf("-")?a[t]=e[t]:a.setProperty(t,e[t])});async function de(e){try{e=new URL(e,window.location.origin).href}catch(e){}return{url:e,coll:"id-"+(await async function(e,t){const i=(new TextEncoder).encode(e),a=await crypto.subtle.digest(t,i);return Array.from(new Uint8Array(a)).map(e=>e.toString(16).padStart(2,"0")).join("")}(e,"SHA-256")).slice(0,12)}}var ce;function be(e,t){void 0===t&&(t={});var i=t.registrationOptions;void 0===i&&(i={}),delete t.registrationOptions;var a=function(e){for(var i=[],a=arguments.length-1;a-- >0;)i[a]=arguments[a+1];t&&t[e]&&t[e].apply(t,i)};"serviceWorker"in navigator&&ce.then((function(){Boolean("localhost"===window.location.hostname||"[::1]"===window.location.hostname||window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/))?(!function(e,t,i){fetch(e).then((function(a){404===a.status?(t("error",new Error("Service worker not found at "+e)),ue()):-1===a.headers.get("content-type").indexOf("javascript")?(t("error",new Error("Expected "+e+" to have javascript content-type, but received "+a.headers.get("content-type"))),ue()):he(e,t,i)})).catch((function(e){return fe(t,e)}))}(e,a,i),navigator.serviceWorker.ready.then((function(e){a("ready",e)}))):(he(e,a,i),navigator.serviceWorker.ready.then((function(e){a("ready",e)})))}))}function fe(e,t){navigator.onLine||e("offline"),e("error",t)}function he(e,t,i){navigator.serviceWorker.register(e,i).then((function(e){t("registered",e),e.waiting?t("updated",e):e.onupdatefound=function(){t("updatefound",e);var i=e.installing;i.onstatechange=function(){"installed"===i.state&&(navigator.serviceWorker.controller?t("updated",e):t("cached",e))}}})).catch((function(e){return fe(t,e)}))}function ue(){"serviceWorker"in navigator&&navigator.serviceWorker.ready.then((function(e){e.unregister()}))}"undefined"!=typeof window&&(ce="undefined"!=typeof Promise?new Promise((function(e){return window.addEventListener("load",e)})):{then:function(e){return window.addEventListener("load",e)}});var me=i(70),pe=i.n(me),ge=i(71),ve=i.n(ge),xe=(i(92),i(72)),we=i.n(xe),ke=i(73),ye=i.n(ke),ze=i(74),Se=i.n(ze),_e=i(75),$e=i.n(_e),Te=i(76),Ce=i.n(Te),Ue=i(77),Ae=i.n(Ue),Pe=i(78),Ee=i.n(Pe),Re=i(79),Le=i.n(Re);const je=(Ne=we.a,new Q(String(Ne),K));var Ne;function Ie(e){return[je,e]}const Ge=new Worker("./sw.js");class Oe extends ie{constructor(){super(),this.sourceUrl=null,this.sourceLoaded=!1,this.showTerms=!1,this.pageParams={}}static get properties(){return{pageParams:{type:Object},sourceUrl:{type:String},navMenuShown:{type:Boolean},showTerms:{type:Boolean},sourceLoaded:{type:Boolean}}}static get styles(){return Ie(ee`
#logo {
max-height: 2.5rem;
margin-right: 8px;
@@ -232,14 +232,14 @@ const ae=new WeakMap,re=v(e=>t=>{if(!(t instanceof U))throw new Error("unsafeHTM
AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
INCLUDING WITHOUT LIMITATION ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- this.showTerms=!1}">Close
+ this.showTerms=!1}">Close
- `:""} `}firstUpdated(){this.initRoute()}updated(e){e.has("sourceUrl")&&(this.sourceLoaded=!1)}onFavIcons(e){const t=document.querySelector("head"),i=document.querySelectorAll("link[rel*='icon']");for(const e of i)t.removeChild(e);for(const i of e.detail.icons){const e=document.createElement("link");e.rel=i.rel,e.href=i.href,t.appendChild(e)}}onNavMenu(){this.navMenuShown=!this.navMenuShown}initRoute(){this.pageParams=new URLSearchParams(window.location.search);let e=this.pageParams.get("state");if(e)try{if(e=JSON.parse(e),e.ids instanceof Array&&e.userId&&"open"===e.action)return this.pageParams.set("source","googledrive://"+e.ids[0]),this.pageParams.delete("state"),void(window.location.search=this.pageParams.toString())}catch(e){console.log(e)}this.sourceUrl=this.pageParams.get("source")||"",this.pageParams.has("terms")&&(this.showTerms=!0)}onStartLoad(e){if(!e.detail.blobUrl)return this.pageParams.set("source",e.detail.sourceUrl),void(window.location.search=this.pageParams.toString());this.sourceUrl=e.detail.sourceUrl,this.loadInfo=e.detail}onCollLoaded(e){this.loadInfo=null,e.detail.alreadyLoaded?this.sourceLoaded=!0:(this.initRoute(),e.detail.sourceUrl!==this.sourceUrl&&(this.pageParams.set("source",e.detail.sourceUrl),window.location.search=this.pageParams.toString()))}}class Me extends ie{constructor(){super(),this.progress=0,this.total=0,this.percent=0,this.coll="",this.state="waiting",this.loadInfo=null}static get properties(){return{sourceUrl:{type:String},loadInfo:{type:Object},state:{type:String},progress:{type:Number},percent:{type:Number},error:{type:String},total:{type:Number},status:{type:String},coll:{type:String}}}firstUpdated(e){this.initMessages()}initMessages(){Ge.addEventListener("message",e=>{switch(e.data.msg_type){case"collProgress":e.data.name===this.coll&&(this.percent=e.data.percent,e.data.error&&(this.error=e.data.error,this.state="errored"));break;case"collAdded":e.data.name===this.coll&&(this.total||(this.total=100),this.progress=this.total,this.percent=100,this.dispatchEvent(new CustomEvent("coll-loaded",{detail:e.data})))}})}async doLoad(){let e=this.sourceUrl,t=null;try{const{scheme:i,host:a,path:r}=function(e){let t=e.indexOf("://"),i=0,a="",r="",o="";return t>=0?(a=e.slice(0,t),t+=3):(t++,e.startsWith("//")&&(t+=2)),i=e.indexOf("/",t),i>0?(r=e.slice(t,i),o=e.slice(i)):(r=e.slice(t),o=""),{scheme:a,host:r,path:o}}(e);switch(i){case"googledrive":this.state="googledrive",t=await this.googledriveInit();break;case"s3":e=`https://${a}.s3.amazonaws.com${r}`,t={sourceUrl:e,name:this.sourceUrl};break;case"file":if(!this.loadInfo)return this.state="errored",void(this.error="File URLs are local and can not be shared. You can choose a file to upload from the main page.");t={sourceUrl:this.loadInfo.blobUrl,name:this.loadInfo.name}}}catch(e){}t||(t={sourceUrl:e}),this.state="started";const i={msg_type:"addColl",name:this.coll,skipExisting:!0,file:t};Ge.postMessage(i)}googledriveInit(){return this._gdWait=new Promise(e=>this._gdResolve=e),this._gdWait}async onLoadReady(e){this._gdResolve&&this._gdResolve(e.detail)}updated(e){this.sourceUrl&&e.has("sourceUrl")&&this.doLoad()}static get styles(){return Ie(ee`
+ `:""} `}firstUpdated(){this.initRoute()}updated(e){e.has("sourceUrl")&&(this.sourceLoaded=!1)}onFavIcons(e){const t=document.querySelector("head"),i=document.querySelectorAll("link[rel*='icon']");for(const e of i)t.removeChild(e);for(const i of e.detail.icons){const e=document.createElement("link");e.rel=i.rel,e.href=i.href,t.appendChild(e)}}onNavMenu(){this.navMenuShown=!this.navMenuShown}initRoute(){this.pageParams=new URLSearchParams(window.location.search);let e=this.pageParams.get("state");if(e)try{if(e=JSON.parse(e),e.ids instanceof Array&&e.userId&&"open"===e.action)return this.pageParams.set("source","googledrive://"+e.ids[0]),this.pageParams.delete("state"),void(window.location.search=this.pageParams.toString())}catch(e){console.log(e)}this.sourceUrl=this.pageParams.get("source")||"",this.pageParams.has("terms")&&(this.showTerms=!0)}onStartLoad(e){if(!e.detail.blobUrl)return this.pageParams.set("source",e.detail.sourceUrl),void(window.location.search=this.pageParams.toString());this.sourceUrl=e.detail.sourceUrl,this.loadInfo=e.detail}onCollLoaded(e){this.loadInfo=null,e.detail.alreadyLoaded?this.sourceLoaded=!0:(this.initRoute(),e.detail.sourceUrl!==this.sourceUrl&&(this.pageParams.set("source",e.detail.sourceUrl),window.location.search=this.pageParams.toString()))}}class Me extends ie{constructor(){super(),this.progress=0,this.total=0,this.percent=0,this.coll="",this.state="waiting",this.loadInfo=null}static get properties(){return{sourceUrl:{type:String},loadInfo:{type:Object},state:{type:String},progress:{type:Number},percent:{type:Number},error:{type:String},total:{type:Number},status:{type:String},coll:{type:String}}}firstUpdated(e){this.initMessages()}initMessages(){Ge.addEventListener("message",e=>{switch(e.data.msg_type){case"collProgress":e.data.name===this.coll&&(this.percent=e.data.percent,e.data.error&&(this.error=e.data.error,this.state="errored"));break;case"collAdded":e.data.name===this.coll&&(this.total||(this.total=100),this.progress=this.total,this.percent=100,this.dispatchEvent(new CustomEvent("coll-loaded",{detail:e.data})))}})}async doLoad(){let e=this.sourceUrl,t=null;try{const{scheme:i,host:a,path:r}=function(e){let t=e.indexOf("://"),i=0,a="",r="",o="";return t>=0?(a=e.slice(0,t),t+=3):(t++,e.startsWith("//")&&(t+=2)),i=e.indexOf("/",t),i>0?(r=e.slice(t,i),o=e.slice(i)):(r=e.slice(t),o=""),{scheme:a,host:r,path:o}}(e);switch(i){case"googledrive":this.state="googledrive",t=await this.googledriveInit();break;case"s3":e=`https://${a}.s3.amazonaws.com${r}`,t={sourceUrl:e,name:this.sourceUrl};break;case"file":if(!this.loadInfo)return this.state="errored",void(this.error="File URLs can not be entered directly or shared.\nYou can select a file to upload from the main page by clicking the 'Choose File...' button.");t={sourceUrl:this.loadInfo.sourceUrl,extra:{blobUrl:this.loadInfo.blobUrl},name:this.loadInfo.name}}}catch(e){}t||(t={sourceUrl:e}),this.state="started";const i={msg_type:"addColl",name:this.coll,skipExisting:!0,file:t};Ge.postMessage(i)}googledriveInit(){return this._gdWait=new Promise(e=>this._gdResolve=e),this._gdWait}async onLoadReady(e){this._gdResolve&&this._gdResolve(e.detail)}updated(e){this.sourceUrl&&e.has("sourceUrl")&&this.doLoad()}static get styles(){return Ie(ee`
.logo {
width: 96px;
height: 96px;
@@ -262,7 +262,7 @@ const ae=new WeakMap,re=v(e=>t=>{if(!(t instanceof U))throw new Error("unsafeHTM
.error {
white-space: pre-wrap;
- text-align: left;
+ margin-bottom: 2em;
}
`)}render(){return M`
@@ -283,7 +283,11 @@ const ae=new WeakMap,re=v(e=>t=>{if(!(t instanceof U))throw new Error("unsafeHTM
- `;case"errored":return M`
${this.error}
`;case"waiting":default:return M``}}}class De extends ie{constructor(){super(),this.colls=[],this.fileDisplayName="",this.file=null,this._deleting={}}static get properties(){return{colls:{type:Array},fileDisplayName:{type:String},_deleting:{type:Object}}}firstUpdated(){this.loadColls()}async loadColls(){const e=await fetch("/wabac/api/index"),t=await e.json();this.colls=t.colls,this._deleting={}}async onDeleteColl(e){e.preventDefault();const t=Number(e.currentTarget.getAttribute("data-coll-index")),i=this.colls[t];if(!i||this._deleting[i.sourceUrl])return;this._deleting[i.sourceUrl]=!0,this.requestUpdate();const a=await fetch("/wabac/api/"+i.id,{method:"DELETE"});if(200===a.status){const e=await a.json();this.colls=e.colls}return!1}onChooseFile(e){0!==e.currentTarget.files.length&&(this.file=e.currentTarget.files[0],this.fileDisplayName="file://"+this.file.name,this.requestUpdate())}onStartLoad(e){e.preventDefault();const t={sourceUrl:this.fileDisplayName};return this.file&&(t.blobUrl=URL.createObjectURL(this.file),t.name=this.fileDisplayName),this.dispatchEvent(new CustomEvent("load-start",{detail:t})),!1}onInput(e){this.fileDisplayName=e.currentTarget.value,this.file&&this.fileDisplayName&&this.fileDisplayName.startsWith("file://")&&(this.file=null,this.fileDisplayName="")}static get styles(){return Ie(ee`
+ `;case"errored":return M`
+
@@ -315,13 +315,15 @@ class WrLoader extends LitElement
case "file":
if (!this.loadInfo) {
this.state = "errored";
- this.error = "File URLs are local and can not be shared. You can choose a file to upload from the main page.";
+ this.error = `\
+File URLs can not be entered directly or shared.
+You can select a file to upload from the main page by clicking the \'Choose File...\' button.`;
return;
}
source = {
- sourceUrl: this.loadInfo.blobUrl,
- //sourceId: this.loadInfo.name,
+ sourceUrl: this.loadInfo.sourceUrl,
+ extra: {blobUrl: this.loadInfo.blobUrl},
name: this.loadInfo.name
}
break;
@@ -384,7 +386,7 @@ class WrLoader extends LitElement
.error {
white-space: pre-wrap;
- text-align: left;
+ margin-bottom: 2em;
}
`);
}
@@ -421,7 +423,11 @@ class WrLoader extends LitElement
`;
case "errored":
- return html`