@yui540/comimi 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1095,7 +1095,7 @@ var Se = 180, Ce = 2e3, we = class {
1095
1095
  return this.isPageTurnAnimating;
1096
1096
  }
1097
1097
  animatePageTurn(e, t, n) {
1098
- return window.clearTimeout(this.pageTurnTimer), !e.settings.pageTurnAnimation || this.isPageTurnAnimating || w(e, t, this.isMobileViewport()).length === 0 ? !1 : (this.isPageTurnAnimating = !0, this.setStageDragOffset(this.getPageTurnTargetOffset(e, t), !0), this.pageTurnTimer = window.setTimeout(() => {
1098
+ return window.clearTimeout(this.pageTurnTimer), !e.settings.pageTurnAnimation || e.autoPageTurnEnabled || this.isPageTurnAnimating || w(e, t, this.isMobileViewport()).length === 0 ? !1 : (this.isPageTurnAnimating = !0, this.setStageDragOffset(this.getPageTurnTargetOffset(e, t), !0), this.pageTurnTimer = window.setTimeout(() => {
1099
1099
  this.isPageTurnAnimating = !1, n();
1100
1100
  }, Se), !0);
1101
1101
  }
@@ -2341,4 +2341,4 @@ var MangaViewer=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`
2341
2341
  }
2342
2342
  }
2343
2343
  `,J=!1,xe=[ye,le,ve,me,de,ce,K,q,be,se,ue,ge,fe,pe,he,_e].join(`
2344
- `);function Se(){if(J||typeof document>`u`)return;let e=document.createElement(`style`);e.dataset.comimiViewer=`true`,e.textContent=xe,document.head.append(e),J=!0}var Ce=180,we=2e3,Te=class{container;callbacks;assetLoader;i18n;root;cleanup=[];mouseStart;touchStart;pinchStart;pageStage;pageTurnTimer;splashRemoveTimer;splash;isPageTurnAnimating=!1;suppressNextClick=!1;prevOverlayVisible=!1;overlayApplyRaf;menuPanel;viewModeSwitcher;controlsDock;resizeHandle;viewSizeObserver;constructor(e,t,n,r,i){this.container=e,this.callbacks=t,this.assetLoader=n,this.i18n=r,Se(),this.pageStage=new L({assetLoader:this.assetLoader,i18n:this.i18n,isMobileViewport:()=>this.isMobileViewport()}),this.root=G({className:i}),this.container.replaceChildren(this.root),this.observeViewSize()}observeViewSize(){let e=()=>{this.root.style.setProperty(`--view-width`,`${this.root.offsetWidth}px`),this.root.style.setProperty(`--view-height`,`${this.root.offsetHeight}px`)};e(),typeof ResizeObserver<`u`?(this.viewSizeObserver=new ResizeObserver(e),this.viewSizeObserver.observe(this.root)):(window.addEventListener(`resize`,e),this.cleanup.push(()=>window.removeEventListener(`resize`,e)))}update(e){if(this.isPageTurnAnimating)return;this.cleanup.forEach(e=>e()),this.cleanup=[],this.i18n.setLocale(e.settings.locale),this.root.dataset.layout=e.layout.mode,e.layout.mode===`theater`&&e.layout.theaterHeightPx?this.root.style.height=`${e.layout.theaterHeightPx}px`:this.root.style.height=``;let t=this.prevOverlayVisible!==e.overlayVisible,n=t?{...e,overlayVisible:this.prevOverlayVisible}:e;this.menuPanel||=new ie(this.callbacks,this.i18n),this.viewModeSwitcher||=new ae(this.callbacks,this.i18n),this.controlsDock||=new C(this.callbacks,this.i18n);let r=this.pageStage.getElement(),i=this.menuPanel.getElement(),a=this.viewModeSwitcher.getElement(),o=this.controlsDock.getElement();Array.from(this.root.children).forEach(e=>{e!==r&&e!==i&&e!==a&&e!==o&&e!==this.splash&&e.remove()}),r.parentNode!==this.root&&this.root.prepend(r),this.pageStage.update(e,this.isMobileViewport()),this.pageStage.snapTransform();let s=[ne(n,this.i18n),h({state:n,callbacks:this.callbacks}),z(e)];this.syncResizeHandle(e.layout.mode===`theater`);let c=i.parentNode===this.root?i:null;if(c?s.forEach(e=>this.root.insertBefore(e,c)):(s.forEach(e=>this.root.appendChild(e)),this.root.appendChild(i)),a.parentNode!==this.root&&this.root.appendChild(a),o.parentNode!==this.root&&this.root.appendChild(o),this.menuPanel.update(n),this.viewModeSwitcher.update(n),this.controlsDock.update(n,this.isMobileViewport()),this.splash&&this.splash.parentNode!==this.root&&this.root.append(this.splash),this.bindGestures(e),this.overlayApplyRaf!==void 0&&(cancelAnimationFrame(this.overlayApplyRaf),this.overlayApplyRaf=void 0),t){let t=e.overlayVisible;this.root.offsetWidth,this.overlayApplyRaf=requestAnimationFrame(()=>{this.overlayApplyRaf=void 0,this.applyOverlayVisibility(t)})}this.prevOverlayVisible=e.overlayVisible}applyOverlayVisibility(e){let t=String(e);this.root.querySelectorAll(`.comimi-arrows, .comimi-center-message, .comimi-menu-panel, .comimi-view-switcher, .comimi-controls-dock`).forEach(e=>{e.dataset.overlay=t})}showSplash(){this.splash||(this.splash=V(this.i18n),this.root.append(this.splash),this.splashRemoveTimer=window.setTimeout(()=>{this.splash?.remove(),this.splash=void 0},we))}destroy(){window.clearTimeout(this.pageTurnTimer),window.clearTimeout(this.splashRemoveTimer),this.overlayApplyRaf!==void 0&&(cancelAnimationFrame(this.overlayApplyRaf),this.overlayApplyRaf=void 0),this.cleanup.forEach(e=>e()),this.cleanup=[],this.viewSizeObserver?.disconnect(),this.viewSizeObserver=void 0,this.resizeHandle?.remove(),this.resizeHandle=void 0,this.root.remove()}getElement(){return this.root}isAnimatingPageTurn(){return this.isPageTurnAnimating}animatePageTurn(e,t,n){return window.clearTimeout(this.pageTurnTimer),!e.settings.pageTurnAnimation||this.isPageTurnAnimating||T(e,t,this.isMobileViewport()).length===0?!1:(this.isPageTurnAnimating=!0,this.setStageDragOffset(this.getPageTurnTargetOffset(e,t),!0),this.pageTurnTimer=window.setTimeout(()=>{this.isPageTurnAnimating=!1,n()},Ce),!0)}isMobileViewport(){return window.matchMedia(`(max-width: 767px)`).matches}clampPan(e,t,n,r){if(n<=1)return{x:0,y:0};let i=w(r,this.isMobileViewport()).length>1?this.root.offsetWidth/2:this.root.offsetWidth,a=this.root.offsetHeight,o=i*(n-1)/2,s=a*(n-1)/2;return{x:Math.min(Math.max(e,-o),o),y:Math.min(Math.max(t,-s),s)}}clampedZoom(e,t){return Math.min(Math.max(e,t.settings.zoom.min),t.settings.zoom.max)}syncResizeHandle(e){e?(this.resizeHandle||=this.createResizeHandle(),this.resizeHandle.parentNode!==this.container&&this.container.appendChild(this.resizeHandle)):this.resizeHandle&&this.resizeHandle.remove()}createResizeHandle(){let e=document.createElement(`div`);e.className=`comimi-resize-handle`,e.setAttribute(`role`,`separator`),e.setAttribute(`aria-orientation`,`horizontal`);let t=0,n=0,r,i=e=>{e.pointerId===r&&this.callbacks.setTheaterHeight(n+e.clientY-t)},a=e=>{e.pointerId===r&&(window.removeEventListener(`pointermove`,i),window.removeEventListener(`pointerup`,a),window.removeEventListener(`pointercancel`,a),r=void 0)};return e.addEventListener(`pointerdown`,e=>{e.preventDefault(),r=e.pointerId,t=e.clientY,n=this.root.getBoundingClientRect().height,window.addEventListener(`pointermove`,i),window.addEventListener(`pointerup`,a),window.addEventListener(`pointercancel`,a)}),e}bindGestures(e){let t=e=>{if(this.suppressNextClick||this.isPageTurnAnimating){this.suppressNextClick=!1,e.preventDefault(),e.stopPropagation();return}this.isInteractiveTarget(e.target)||this.callbacks.toggleOverlay()},n=t=>{if(this.isInteractiveTarget(t.target)||!t.ctrlKey&&!t.metaKey)return;t.preventDefault();let n=t.deltaY>0?-e.settings.zoom.step:e.settings.zoom.step,r=this.clampedZoom(e.zoomScale+n,e),i=this.clampPan(e.panX,e.panY,r,e);this.callbacks.setZoom(r,i.x,i.y)},r=t=>{this.isPageTurnAnimating||this.isInteractiveTarget(t.target)||t.button===0&&(this.mouseStart={x:t.clientX,y:t.clientY,panX:e.panX,panY:e.panY})},i=t=>{if(!this.mouseStart)return;t.preventDefault();let n=t.clientX-this.mouseStart.x,r=t.clientY-this.mouseStart.y;if((Math.abs(n)>6||Math.abs(r)>6)&&(this.suppressNextClick=!0),e.zoomScale<=1){this.setStageDragOffset(this.constrainDragOffset(n,r,e));return}let i=this.mouseStart.panX+t.clientX-this.mouseStart.x,a=this.mouseStart.panY+t.clientY-this.mouseStart.y,o=this.clampPan(i,a,e.zoomScale,e);this.callbacks.setPan(o.x,o.y)},a=t=>{if(!this.mouseStart)return;let n=t.clientX-this.mouseStart.x,r=t.clientY-this.mouseStart.y;this.handleSwipeEnd(n,r,e),this.mouseStart=void 0},o=t=>{if(this.isPageTurnAnimating)return;if(t.touches.length===2){t.preventDefault(),this.touchStart=void 0,this.pinchStart={distance:Y(t),scale:e.zoomScale};return}if(this.isInteractiveTarget(t.target))return;let n=t.touches[0];n&&(this.touchStart={x:n.clientX,y:n.clientY,panX:e.panX,panY:e.panY})},s=t=>{if(this.pinchStart&&t.touches.length===2){t.preventDefault();let n=this.pinchStart.scale*(Y(t)/this.pinchStart.distance),r=this.clampedZoom(n,e),i=this.clampPan(e.panX,e.panY,r,e);this.callbacks.setZoom(r,i.x,i.y);return}if(this.isInteractiveTarget(t.target))return;let n=t.touches[0];if(!n||!this.touchStart)return;t.preventDefault();let r=n.clientX-this.touchStart.x,i=n.clientY-this.touchStart.y;if((Math.abs(r)>6||Math.abs(i)>6)&&(this.suppressNextClick=!0),e.zoomScale<=1){this.setStageDragOffset(this.constrainDragOffset(r,i,e));return}let a=this.touchStart.panX+n.clientX-this.touchStart.x,o=this.touchStart.panY+n.clientY-this.touchStart.y,s=this.clampPan(a,o,e.zoomScale,e);this.callbacks.setPan(s.x,s.y)},c=t=>{t.touches.length<2&&(this.pinchStart=void 0);let n=t.changedTouches[0];if(!n||!this.touchStart){this.touchStart=void 0;return}let r=n.clientX-this.touchStart.x,i=n.clientY-this.touchStart.y;this.handleSwipeEnd(r,i,e),this.touchStart=void 0},l=t=>{this.isInteractiveTarget(t.target)||(e.zoomScale>1?this.callbacks.resetZoom():this.callbacks.setZoom(2))},u=t=>{if(this.suppressNextClick||this.isPageTurnAnimating||e.panel!==`settings`)return;let n=t.target;n instanceof Element&&(n.closest(`.comimi-settings`)||this.callbacks.setPanel(`none`))};this.root.addEventListener(`click`,u,!0),this.root.addEventListener(`click`,t),this.root.addEventListener(`wheel`,n,{passive:!1}),this.root.addEventListener(`mousedown`,r),window.addEventListener(`mousemove`,i),window.addEventListener(`mouseup`,a),this.root.addEventListener(`touchstart`,o,{passive:!1}),this.root.addEventListener(`touchmove`,s,{passive:!1}),this.root.addEventListener(`touchend`,c),this.root.addEventListener(`dblclick`,l),this.cleanup.push(()=>this.root.removeEventListener(`click`,u,!0),()=>this.root.removeEventListener(`click`,t),()=>this.root.removeEventListener(`wheel`,n),()=>this.root.removeEventListener(`mousedown`,r),()=>window.removeEventListener(`mousemove`,i),()=>window.removeEventListener(`mouseup`,a),()=>this.root.removeEventListener(`touchstart`,o),()=>this.root.removeEventListener(`touchmove`,s),()=>this.root.removeEventListener(`touchend`,c),()=>this.root.removeEventListener(`dblclick`,l))}handleSwipeEnd(e,t,n){if(window.clearTimeout(this.pageTurnTimer),!(n.zoomScale<=1&&Math.abs(e)>64&&Math.abs(e)>Math.abs(t))){this.setStageDragOffset(0,!0);return}let r=k(e,n.settings.readingDirection)?`next`:`previous`;if(!(T(n,r,this.isMobileViewport()).length>0)){this.setStageDragOffset(0,!0);return}this.requestPageTurn(n,r)||(r===`next`?this.callbacks.commitNextPage():this.callbacks.commitPreviousPage())}requestPageTurn(e,t){return this.animatePageTurn(e,t,()=>{t===`next`?this.callbacks.commitNextPage():this.callbacks.commitPreviousPage()})}constrainDragOffset(e,t,n){return Math.abs(t)>Math.abs(e)?0:T(n,k(e,n.settings.readingDirection)?`next`:`previous`,this.isMobileViewport()).length>0?e:this.applyEdgeResistance(e)}applyEdgeResistance(e){let t=Math.sign(e),n=Math.abs(e),r=Math.max(this.root.clientWidth,1),i=Math.min(r*.22,140);return t*(i*(1-Math.exp(-n/i)))}setStageDragOffset(e,t=!1){this.pageStage.setDragOffset(e,t)}getPageTurnTargetOffset(e,t){return O(e,t)===`left`?this.root.clientWidth:-this.root.clientWidth}isInteractiveTarget(e){return e instanceof Element?!!e.closest([`.comimi-arrow-button`,`.comimi-view-switcher`,`.comimi-controls-dock`,`.comimi-menu-panel`,`.comimi-settings-panel`,`button`,`input`,`select`,`textarea`,`a`,`iframe`].join(`,`)):!1}};function Y(e){let[t,n]=Array.from(e.touches);return!t||!n?1:Math.hypot(t.clientX-n.clientX,t.clientY-n.clientY)}var Ee=class{enabled;databaseName;dbPromise;constructor(e={}){this.enabled=e.enabled!==!1&&typeof indexedDB<`u`,this.databaseName=e.databaseName??`manga-viewer`}async getSettings(){return(await this.get(`settings`,`global`))?.value}async saveSettings(e){await this.put(`settings`,{id:`global`,value:e,updatedAt:Date.now()})}async getProgress(e){return(await this.get(`readingProgress`,e))?.pageIndex}async saveProgress(e,t){await this.put(`readingProgress`,{mangaId:e,pageIndex:t,updatedAt:Date.now()})}async saveLayout(e){await this.put(`layout`,{id:`global`,value:e,updatedAt:Date.now()})}async getLayout(){return(await this.get(`layout`,`global`))?.value}async get(e,t){if(this.enabled)return Z((await this.store(e,`readonly`)).get(t))}async put(e,t){this.enabled&&await Z((await this.store(e,`readwrite`)).put(t))}async delete(e,t){this.enabled&&await Z((await this.store(e,`readwrite`)).delete(t))}async store(e,t){return(await this.open()).transaction(e,t).objectStore(e)}open(){return this.enabled?(this.dbPromise??=new Promise((e,t)=>{let n=indexedDB.open(this.databaseName,1);n.onupgradeneeded=()=>{let e=n.result;X(e,`settings`,`id`),X(e,`readingProgress`,`mangaId`),X(e,`layout`,`id`)},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}),this.dbPromise):Promise.reject(Error(`IndexedDB is not available`))}};function X(e,t,n){e.objectStoreNames.contains(t)||e.createObjectStore(t,{keyPath:n})}function Z(e){return new Promise((t,n)=>{e.onsuccess=()=>t(e.result),e.onerror=()=>n(e.error)})}function Q(e,t){switch(t.type){case`setManga`:{let n=i(t.pageIndex??0,t.manga.pages.length);return $({...e,manga:t.manga,currentPageIndex:n,zoomScale:1,panX:0,panY:0})}case`goToPage`:{let n=i(t.pageIndex,e.manga.pages.length),r=e.zoomScale===1&&e.panX===0&&e.panY===0;return n===e.currentPageIndex&&r?e:$({...e,currentPageIndex:n,zoomScale:1,panX:0,panY:0})}case`nextPage`:{let t=a(e.settings,e.currentPageIndex);return Q(e,{type:`goToPage`,pageIndex:e.currentPageIndex+t})}case`previousPage`:{let t=a(e.settings,e.currentPageIndex);return Q(e,{type:`goToPage`,pageIndex:e.currentPageIndex-t})}case`setOverlayVisible`:return{...e,overlayVisible:t.visible,panel:t.visible?e.panel:`none`};case`toggleAutoPageTurn`:return{...e,autoPageTurnEnabled:!e.autoPageTurnEnabled};case`updateSettings`:{let n=r(e.settings,t.settings);return $({...e,settings:n,layout:{...e.layout,mode:n.layoutMode}})}case`setLayoutMode`:return Q(e,{type:`updateSettings`,settings:{layoutMode:t.layoutMode}});case`setTheaterHeight`:return{...e,layout:{...e.layout,theaterHeightPx:Math.max(240,Math.round(t.heightPx))}};case`setZoom`:return{...e,zoomScale:De(t.scale,e),panX:t.panX??e.panX,panY:t.panY??e.panY};case`setPan`:return{...e,panX:t.panX,panY:t.panY};case`resetZoom`:return{...e,zoomScale:1,panX:0,panY:0};case`setPanel`:return{...e,panel:t.panel,overlayVisible:t.panel===`none`?e.overlayVisible:!0};case`pushNotification`:return{...e,notifications:[t.notification]};case`removeNotification`:return{...e,notifications:e.notifications.filter(e=>e.id!==t.id)}}}function $(e){return{...e,visiblePageIndexes:o(e.currentPageIndex,e.manga.pages.length,e.settings)}}function De(e,t){return Math.min(Math.max(e,t.settings.zoom.min),t.settings.zoom.max)}var Oe=class{state;listeners=new Set;constructor(e){this.state=e}getState(){return this.state}dispatch(e){let t=this.state,n=Q(t,e);if(n!==t){this.state=n;for(let e of this.listeners)e(n,t)}}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}},ke=class{objectUrls=new Set;async resolveImageSource(e,t){return t.src}revokeAll(){for(let e of this.objectUrls)URL.revokeObjectURL(e);this.objectUrls.clear()}},Ae=class{handlers=new Map;on(e,t){let n=this.handlers.get(e);return n||(n=new Set,this.handlers.set(e,n)),n.add(t),()=>{n.delete(t)}}emit(e,t){let n=this.handlers.get(e);if(n)for(let e of n)try{e(t)}catch(e){console.error(e)}}clear(){this.handlers.clear()}},je=class{container;store;storage;assetLoader;renderer;i18n;events=new Ae;unsubscribers=[];notificationTimers=new Map;autoTimer;mobileMediaQuery;constructor(e,i){this.container=e;let a=r(t,{...i.settings,locale:i.locale??i.settings?.locale??t.locale});this.storage=new Ee(i.storage),this.assetLoader=new ke,this.i18n=new l(a.locale,i.translations),this.store=new Oe(n(i.manga,a,i.initialPageIndex));let o={goToPage:e=>this.goToPage(e),nextPage:()=>this.nextPage(),previousPage:()=>this.previousPage(),commitNextPage:()=>this.commitNextPage(),commitPreviousPage:()=>this.commitPreviousPage(),toggleOverlay:e=>this.toggleOverlay(e),toggleAutoPageTurn:()=>this.toggleAutoPageTurn(),updateSettings:e=>{this.updateSettings(e)},setLayoutMode:e=>void this.setLayoutMode(e),setTheaterHeight:e=>this.setTheaterHeight(e),setPanel:e=>{this.store.dispatch({type:`setPanel`,panel:e})},setZoom:(e,t,n)=>this.store.dispatch({type:`setZoom`,scale:e,panX:t,panY:n}),setPan:(e,t)=>this.store.dispatch({type:`setPan`,panX:e,panY:t}),resetZoom:()=>this.store.dispatch({type:`resetZoom`})};this.renderer=new Te(this.container,o,this.assetLoader,this.i18n,i.className);for(let[e,t]of Object.entries(i.events??{}))this.on(e,t);this.unsubscribers.push(this.store.subscribe((e,t)=>{this.renderer.update(e),this.afterStateChange(e,t)})),this.bindKeyboard(),this.bindViewportChange(),this.bootstrap()}destroy(){window.clearInterval(this.autoTimer);for(let e of this.notificationTimers.values())window.clearTimeout(e);this.notificationTimers.clear(),this.unsubscribers.forEach(e=>e()),this.assetLoader.revokeAll(),this.renderer.destroy(),this.events.emit(`destroy`,void 0),this.events.clear()}async setManga(e){let t=await this.storage.getProgress(e.id)??0;this.store.dispatch({type:`setManga`,manga:e,pageIndex:t})}async setPages(e){await this.setManga({...this.store.getState().manga,pages:e})}getState(){return this.store.getState()}async updateSettings(e){this.store.dispatch({type:`updateSettings`,settings:e});let t=this.store.getState().settings;this.i18n.setLocale(t.locale),await this.storage.saveSettings(t),this.events.emit(`settingsChange`,{settings:t})}goToPage(e){let t=this.store.getState().currentPageIndex;this.store.dispatch({type:`goToPage`,pageIndex:e});let n=this.store.getState().currentPageIndex;if(t!==n){let e=this.store.getState();this.storage.saveProgress(e.manga.id,n),this.events.emit(`pageChange`,{pageIndex:n,page:e.manga.pages[n]})}}nextPage(){if(this.renderer.isAnimatingPageTurn())return;let e=this.store.getState();this.renderer.animatePageTurn(e,`next`,()=>this.commitNextPage())||this.commitNextPage()}previousPage(){if(this.renderer.isAnimatingPageTurn())return;let e=this.store.getState();this.renderer.animatePageTurn(e,`previous`,()=>this.commitPreviousPage())||this.commitPreviousPage()}commitNextPage(){if(this.renderer.isMobileViewport()){this.goToPage(this.store.getState().currentPageIndex+1);return}let e=this.store.getState().currentPageIndex;this.store.dispatch({type:`nextPage`}),this.emitPageChangeIfNeeded(e)}commitPreviousPage(){if(this.renderer.isMobileViewport()){this.goToPage(this.store.getState().currentPageIndex-1);return}let e=this.store.getState().currentPageIndex;this.store.dispatch({type:`previousPage`}),this.emitPageChangeIfNeeded(e)}toggleOverlay(e){let t=this.store.getState().overlayVisible,n=e??!t;this.store.dispatch({type:`setOverlayVisible`,visible:n})}toggleAutoPageTurn(){this.store.dispatch({type:`toggleAutoPageTurn`}),this.syncAutoTimer();let e=this.store.getState().autoPageTurnEnabled;this.notify(this.i18n.t(e?`autoplay.start`:`autoplay.stop`))}async toggleFullscreen(){let e=this.store.getState();if(document.fullscreenElement){await document.exitFullscreen(),await this.setLayoutMode(`inline`);return}await this.setLayoutMode(e.layout.mode===`nativeFullscreen`?`inline`:`nativeFullscreen`)}on(e,t){return this.events.on(e,t)}async bootstrap(){let e=await this.storage.getSettings(),t=await this.storage.getLayout(),n=this.store.getState().manga.id,r=await this.storage.getProgress(n);e&&this.store.dispatch({type:`updateSettings`,settings:e}),t?.mode&&this.store.dispatch({type:`setLayoutMode`,layoutMode:t.mode}),t?.theaterHeightPx&&this.store.dispatch({type:`setTheaterHeight`,heightPx:t.theaterHeightPx}),typeof r==`number`&&this.store.dispatch({type:`goToPage`,pageIndex:r}),this.renderer.update(this.store.getState()),this.renderer.showSplash(),window.setTimeout(()=>{this.toggleOverlay(!0)},1550),this.events.emit(`ready`,{manga:this.store.getState().manga})}bindKeyboard(){this.renderer.getElement();let e=e=>{if(this.shouldHandleKeyboardEvent(e))switch(e.key){case`ArrowLeft`:e.preventDefault(),this.moveFromKey(`left`);break;case`ArrowRight`:e.preventDefault(),this.moveFromKey(`right`);break;case` `:e.preventDefault(),this.moveFromKey(e.shiftKey?`right`:`left`);break;case`a`:case`A`:e.preventDefault(),this.toggleAutoPageTurn();break;case`n`:case`N`:e.preventDefault(),this.setLayoutMode(`inline`);break;case`w`:case`W`:e.preventDefault(),this.setLayoutMode(`theater`);break;case`f`:case`F`:e.preventDefault(),this.setLayoutMode(`browserFullscreen`);break;case`m`:case`M`:{e.preventDefault();let t=this.store.getState().panel,n=t===`menu`||t===`pages`||t===`shortcuts`;this.store.dispatch({type:`setPanel`,panel:n?`none`:`menu`}),n||this.toggleOverlay(!0);break}case`p`:case`P`:e.preventDefault(),this.updateSettings({pageTurnMode:this.store.getState().settings.pageTurnMode===`spread`?`single`:`spread`});break;case`s`:case`S`:{e.preventDefault();let t=this.store.getState().panel===`settings`;this.store.dispatch({type:`setPanel`,panel:t?`none`:`settings`}),t||this.toggleOverlay(!0);break}case`Escape`:e.preventDefault(),this.store.dispatch({type:`setPanel`,panel:`none`}),document.fullscreenElement&&document.exitFullscreen();break}};window.addEventListener(`keydown`,e),this.unsubscribers.push(()=>window.removeEventListener(`keydown`,e))}shouldHandleKeyboardEvent(e){let t=e.target;return t instanceof Element?!t.closest(`input, select, textarea, [contenteditable='true']`):!0}bindViewportChange(){this.mobileMediaQuery=window.matchMedia(`(max-width: 676px)`);let e=()=>{this.renderer.update(this.store.getState())};this.mobileMediaQuery.addEventListener(`change`,e),this.unsubscribers.push(()=>this.mobileMediaQuery?.removeEventListener(`change`,e))}moveFromKey(e){this.store.getState().settings.readingDirection===`rtl`?e===`left`?this.nextPage():this.previousPage():e===`left`?this.previousPage():this.nextPage()}async setLayoutMode(e){if(e===`nativeFullscreen`)try{await this.renderer.getElement().requestFullscreen()}catch{e=`browserFullscreen`}else document.fullscreenElement&&await document.exitFullscreen();if(e===`theater`&&!this.store.getState().layout.theaterHeightPx){let e=this.renderer.getElement().offsetHeight;e>0&&this.store.dispatch({type:`setTheaterHeight`,heightPx:e})}this.store.dispatch({type:`setLayoutMode`,layoutMode:e}),await this.storage.saveSettings(this.store.getState().settings),await this.storage.saveLayout(this.store.getState().layout),this.events.emit(`layoutChange`,{layoutMode:e})}setTheaterHeight(e){this.store.dispatch({type:`setTheaterHeight`,heightPx:e}),this.storage.saveLayout(this.store.getState().layout)}afterStateChange(e,t){e.autoPageTurnEnabled!==t.autoPageTurnEnabled&&this.syncAutoTimer()}syncAutoTimer(){window.clearInterval(this.autoTimer),this.store.getState().autoPageTurnEnabled&&(this.autoTimer=window.setInterval(()=>{let e=this.store.getState(),t=a(e.settings,e.currentPageIndex);if(e.currentPageIndex+t>=e.manga.pages.length){this.toggleAutoPageTurn();return}this.nextPage()},this.store.getState().settings.autoPageTurnIntervalMs))}emitPageChangeIfNeeded(e){let t=this.store.getState();t.currentPageIndex!==e&&(this.storage.saveProgress(t.manga.id,t.currentPageIndex),this.events.emit(`pageChange`,{pageIndex:t.currentPageIndex,page:t.manga.pages[t.currentPageIndex]}))}notify(e,t=`info`){for(let e of this.notificationTimers.values())window.clearTimeout(e);this.notificationTimers.clear();let n=`${Date.now()}-${Math.random().toString(36).slice(2)}`;this.store.dispatch({type:`pushNotification`,notification:{id:n,message:e,tone:t,createdAt:Date.now()}});let r=window.setTimeout(()=>{this.store.dispatch({type:`removeNotification`,id:n}),this.notificationTimers.delete(n)},3e3);this.notificationTimers.set(n,r)}};function Me(e,t){return new je(e,t)}return e.createMangaViewer=Me,e})({});
2344
+ `);function Se(){if(J||typeof document>`u`)return;let e=document.createElement(`style`);e.dataset.comimiViewer=`true`,e.textContent=xe,document.head.append(e),J=!0}var Ce=180,we=2e3,Te=class{container;callbacks;assetLoader;i18n;root;cleanup=[];mouseStart;touchStart;pinchStart;pageStage;pageTurnTimer;splashRemoveTimer;splash;isPageTurnAnimating=!1;suppressNextClick=!1;prevOverlayVisible=!1;overlayApplyRaf;menuPanel;viewModeSwitcher;controlsDock;resizeHandle;viewSizeObserver;constructor(e,t,n,r,i){this.container=e,this.callbacks=t,this.assetLoader=n,this.i18n=r,Se(),this.pageStage=new L({assetLoader:this.assetLoader,i18n:this.i18n,isMobileViewport:()=>this.isMobileViewport()}),this.root=G({className:i}),this.container.replaceChildren(this.root),this.observeViewSize()}observeViewSize(){let e=()=>{this.root.style.setProperty(`--view-width`,`${this.root.offsetWidth}px`),this.root.style.setProperty(`--view-height`,`${this.root.offsetHeight}px`)};e(),typeof ResizeObserver<`u`?(this.viewSizeObserver=new ResizeObserver(e),this.viewSizeObserver.observe(this.root)):(window.addEventListener(`resize`,e),this.cleanup.push(()=>window.removeEventListener(`resize`,e)))}update(e){if(this.isPageTurnAnimating)return;this.cleanup.forEach(e=>e()),this.cleanup=[],this.i18n.setLocale(e.settings.locale),this.root.dataset.layout=e.layout.mode,e.layout.mode===`theater`&&e.layout.theaterHeightPx?this.root.style.height=`${e.layout.theaterHeightPx}px`:this.root.style.height=``;let t=this.prevOverlayVisible!==e.overlayVisible,n=t?{...e,overlayVisible:this.prevOverlayVisible}:e;this.menuPanel||=new ie(this.callbacks,this.i18n),this.viewModeSwitcher||=new ae(this.callbacks,this.i18n),this.controlsDock||=new C(this.callbacks,this.i18n);let r=this.pageStage.getElement(),i=this.menuPanel.getElement(),a=this.viewModeSwitcher.getElement(),o=this.controlsDock.getElement();Array.from(this.root.children).forEach(e=>{e!==r&&e!==i&&e!==a&&e!==o&&e!==this.splash&&e.remove()}),r.parentNode!==this.root&&this.root.prepend(r),this.pageStage.update(e,this.isMobileViewport()),this.pageStage.snapTransform();let s=[ne(n,this.i18n),h({state:n,callbacks:this.callbacks}),z(e)];this.syncResizeHandle(e.layout.mode===`theater`);let c=i.parentNode===this.root?i:null;if(c?s.forEach(e=>this.root.insertBefore(e,c)):(s.forEach(e=>this.root.appendChild(e)),this.root.appendChild(i)),a.parentNode!==this.root&&this.root.appendChild(a),o.parentNode!==this.root&&this.root.appendChild(o),this.menuPanel.update(n),this.viewModeSwitcher.update(n),this.controlsDock.update(n,this.isMobileViewport()),this.splash&&this.splash.parentNode!==this.root&&this.root.append(this.splash),this.bindGestures(e),this.overlayApplyRaf!==void 0&&(cancelAnimationFrame(this.overlayApplyRaf),this.overlayApplyRaf=void 0),t){let t=e.overlayVisible;this.root.offsetWidth,this.overlayApplyRaf=requestAnimationFrame(()=>{this.overlayApplyRaf=void 0,this.applyOverlayVisibility(t)})}this.prevOverlayVisible=e.overlayVisible}applyOverlayVisibility(e){let t=String(e);this.root.querySelectorAll(`.comimi-arrows, .comimi-center-message, .comimi-menu-panel, .comimi-view-switcher, .comimi-controls-dock`).forEach(e=>{e.dataset.overlay=t})}showSplash(){this.splash||(this.splash=V(this.i18n),this.root.append(this.splash),this.splashRemoveTimer=window.setTimeout(()=>{this.splash?.remove(),this.splash=void 0},we))}destroy(){window.clearTimeout(this.pageTurnTimer),window.clearTimeout(this.splashRemoveTimer),this.overlayApplyRaf!==void 0&&(cancelAnimationFrame(this.overlayApplyRaf),this.overlayApplyRaf=void 0),this.cleanup.forEach(e=>e()),this.cleanup=[],this.viewSizeObserver?.disconnect(),this.viewSizeObserver=void 0,this.resizeHandle?.remove(),this.resizeHandle=void 0,this.root.remove()}getElement(){return this.root}isAnimatingPageTurn(){return this.isPageTurnAnimating}animatePageTurn(e,t,n){return window.clearTimeout(this.pageTurnTimer),!e.settings.pageTurnAnimation||e.autoPageTurnEnabled||this.isPageTurnAnimating||T(e,t,this.isMobileViewport()).length===0?!1:(this.isPageTurnAnimating=!0,this.setStageDragOffset(this.getPageTurnTargetOffset(e,t),!0),this.pageTurnTimer=window.setTimeout(()=>{this.isPageTurnAnimating=!1,n()},Ce),!0)}isMobileViewport(){return window.matchMedia(`(max-width: 767px)`).matches}clampPan(e,t,n,r){if(n<=1)return{x:0,y:0};let i=w(r,this.isMobileViewport()).length>1?this.root.offsetWidth/2:this.root.offsetWidth,a=this.root.offsetHeight,o=i*(n-1)/2,s=a*(n-1)/2;return{x:Math.min(Math.max(e,-o),o),y:Math.min(Math.max(t,-s),s)}}clampedZoom(e,t){return Math.min(Math.max(e,t.settings.zoom.min),t.settings.zoom.max)}syncResizeHandle(e){e?(this.resizeHandle||=this.createResizeHandle(),this.resizeHandle.parentNode!==this.container&&this.container.appendChild(this.resizeHandle)):this.resizeHandle&&this.resizeHandle.remove()}createResizeHandle(){let e=document.createElement(`div`);e.className=`comimi-resize-handle`,e.setAttribute(`role`,`separator`),e.setAttribute(`aria-orientation`,`horizontal`);let t=0,n=0,r,i=e=>{e.pointerId===r&&this.callbacks.setTheaterHeight(n+e.clientY-t)},a=e=>{e.pointerId===r&&(window.removeEventListener(`pointermove`,i),window.removeEventListener(`pointerup`,a),window.removeEventListener(`pointercancel`,a),r=void 0)};return e.addEventListener(`pointerdown`,e=>{e.preventDefault(),r=e.pointerId,t=e.clientY,n=this.root.getBoundingClientRect().height,window.addEventListener(`pointermove`,i),window.addEventListener(`pointerup`,a),window.addEventListener(`pointercancel`,a)}),e}bindGestures(e){let t=e=>{if(this.suppressNextClick||this.isPageTurnAnimating){this.suppressNextClick=!1,e.preventDefault(),e.stopPropagation();return}this.isInteractiveTarget(e.target)||this.callbacks.toggleOverlay()},n=t=>{if(this.isInteractiveTarget(t.target)||!t.ctrlKey&&!t.metaKey)return;t.preventDefault();let n=t.deltaY>0?-e.settings.zoom.step:e.settings.zoom.step,r=this.clampedZoom(e.zoomScale+n,e),i=this.clampPan(e.panX,e.panY,r,e);this.callbacks.setZoom(r,i.x,i.y)},r=t=>{this.isPageTurnAnimating||this.isInteractiveTarget(t.target)||t.button===0&&(this.mouseStart={x:t.clientX,y:t.clientY,panX:e.panX,panY:e.panY})},i=t=>{if(!this.mouseStart)return;t.preventDefault();let n=t.clientX-this.mouseStart.x,r=t.clientY-this.mouseStart.y;if((Math.abs(n)>6||Math.abs(r)>6)&&(this.suppressNextClick=!0),e.zoomScale<=1){this.setStageDragOffset(this.constrainDragOffset(n,r,e));return}let i=this.mouseStart.panX+t.clientX-this.mouseStart.x,a=this.mouseStart.panY+t.clientY-this.mouseStart.y,o=this.clampPan(i,a,e.zoomScale,e);this.callbacks.setPan(o.x,o.y)},a=t=>{if(!this.mouseStart)return;let n=t.clientX-this.mouseStart.x,r=t.clientY-this.mouseStart.y;this.handleSwipeEnd(n,r,e),this.mouseStart=void 0},o=t=>{if(this.isPageTurnAnimating)return;if(t.touches.length===2){t.preventDefault(),this.touchStart=void 0,this.pinchStart={distance:Y(t),scale:e.zoomScale};return}if(this.isInteractiveTarget(t.target))return;let n=t.touches[0];n&&(this.touchStart={x:n.clientX,y:n.clientY,panX:e.panX,panY:e.panY})},s=t=>{if(this.pinchStart&&t.touches.length===2){t.preventDefault();let n=this.pinchStart.scale*(Y(t)/this.pinchStart.distance),r=this.clampedZoom(n,e),i=this.clampPan(e.panX,e.panY,r,e);this.callbacks.setZoom(r,i.x,i.y);return}if(this.isInteractiveTarget(t.target))return;let n=t.touches[0];if(!n||!this.touchStart)return;t.preventDefault();let r=n.clientX-this.touchStart.x,i=n.clientY-this.touchStart.y;if((Math.abs(r)>6||Math.abs(i)>6)&&(this.suppressNextClick=!0),e.zoomScale<=1){this.setStageDragOffset(this.constrainDragOffset(r,i,e));return}let a=this.touchStart.panX+n.clientX-this.touchStart.x,o=this.touchStart.panY+n.clientY-this.touchStart.y,s=this.clampPan(a,o,e.zoomScale,e);this.callbacks.setPan(s.x,s.y)},c=t=>{t.touches.length<2&&(this.pinchStart=void 0);let n=t.changedTouches[0];if(!n||!this.touchStart){this.touchStart=void 0;return}let r=n.clientX-this.touchStart.x,i=n.clientY-this.touchStart.y;this.handleSwipeEnd(r,i,e),this.touchStart=void 0},l=t=>{this.isInteractiveTarget(t.target)||(e.zoomScale>1?this.callbacks.resetZoom():this.callbacks.setZoom(2))},u=t=>{if(this.suppressNextClick||this.isPageTurnAnimating||e.panel!==`settings`)return;let n=t.target;n instanceof Element&&(n.closest(`.comimi-settings`)||this.callbacks.setPanel(`none`))};this.root.addEventListener(`click`,u,!0),this.root.addEventListener(`click`,t),this.root.addEventListener(`wheel`,n,{passive:!1}),this.root.addEventListener(`mousedown`,r),window.addEventListener(`mousemove`,i),window.addEventListener(`mouseup`,a),this.root.addEventListener(`touchstart`,o,{passive:!1}),this.root.addEventListener(`touchmove`,s,{passive:!1}),this.root.addEventListener(`touchend`,c),this.root.addEventListener(`dblclick`,l),this.cleanup.push(()=>this.root.removeEventListener(`click`,u,!0),()=>this.root.removeEventListener(`click`,t),()=>this.root.removeEventListener(`wheel`,n),()=>this.root.removeEventListener(`mousedown`,r),()=>window.removeEventListener(`mousemove`,i),()=>window.removeEventListener(`mouseup`,a),()=>this.root.removeEventListener(`touchstart`,o),()=>this.root.removeEventListener(`touchmove`,s),()=>this.root.removeEventListener(`touchend`,c),()=>this.root.removeEventListener(`dblclick`,l))}handleSwipeEnd(e,t,n){if(window.clearTimeout(this.pageTurnTimer),!(n.zoomScale<=1&&Math.abs(e)>64&&Math.abs(e)>Math.abs(t))){this.setStageDragOffset(0,!0);return}let r=k(e,n.settings.readingDirection)?`next`:`previous`;if(!(T(n,r,this.isMobileViewport()).length>0)){this.setStageDragOffset(0,!0);return}this.requestPageTurn(n,r)||(r===`next`?this.callbacks.commitNextPage():this.callbacks.commitPreviousPage())}requestPageTurn(e,t){return this.animatePageTurn(e,t,()=>{t===`next`?this.callbacks.commitNextPage():this.callbacks.commitPreviousPage()})}constrainDragOffset(e,t,n){return Math.abs(t)>Math.abs(e)?0:T(n,k(e,n.settings.readingDirection)?`next`:`previous`,this.isMobileViewport()).length>0?e:this.applyEdgeResistance(e)}applyEdgeResistance(e){let t=Math.sign(e),n=Math.abs(e),r=Math.max(this.root.clientWidth,1),i=Math.min(r*.22,140);return t*(i*(1-Math.exp(-n/i)))}setStageDragOffset(e,t=!1){this.pageStage.setDragOffset(e,t)}getPageTurnTargetOffset(e,t){return O(e,t)===`left`?this.root.clientWidth:-this.root.clientWidth}isInteractiveTarget(e){return e instanceof Element?!!e.closest([`.comimi-arrow-button`,`.comimi-view-switcher`,`.comimi-controls-dock`,`.comimi-menu-panel`,`.comimi-settings-panel`,`button`,`input`,`select`,`textarea`,`a`,`iframe`].join(`,`)):!1}};function Y(e){let[t,n]=Array.from(e.touches);return!t||!n?1:Math.hypot(t.clientX-n.clientX,t.clientY-n.clientY)}var Ee=class{enabled;databaseName;dbPromise;constructor(e={}){this.enabled=e.enabled!==!1&&typeof indexedDB<`u`,this.databaseName=e.databaseName??`manga-viewer`}async getSettings(){return(await this.get(`settings`,`global`))?.value}async saveSettings(e){await this.put(`settings`,{id:`global`,value:e,updatedAt:Date.now()})}async getProgress(e){return(await this.get(`readingProgress`,e))?.pageIndex}async saveProgress(e,t){await this.put(`readingProgress`,{mangaId:e,pageIndex:t,updatedAt:Date.now()})}async saveLayout(e){await this.put(`layout`,{id:`global`,value:e,updatedAt:Date.now()})}async getLayout(){return(await this.get(`layout`,`global`))?.value}async get(e,t){if(this.enabled)return Z((await this.store(e,`readonly`)).get(t))}async put(e,t){this.enabled&&await Z((await this.store(e,`readwrite`)).put(t))}async delete(e,t){this.enabled&&await Z((await this.store(e,`readwrite`)).delete(t))}async store(e,t){return(await this.open()).transaction(e,t).objectStore(e)}open(){return this.enabled?(this.dbPromise??=new Promise((e,t)=>{let n=indexedDB.open(this.databaseName,1);n.onupgradeneeded=()=>{let e=n.result;X(e,`settings`,`id`),X(e,`readingProgress`,`mangaId`),X(e,`layout`,`id`)},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}),this.dbPromise):Promise.reject(Error(`IndexedDB is not available`))}};function X(e,t,n){e.objectStoreNames.contains(t)||e.createObjectStore(t,{keyPath:n})}function Z(e){return new Promise((t,n)=>{e.onsuccess=()=>t(e.result),e.onerror=()=>n(e.error)})}function Q(e,t){switch(t.type){case`setManga`:{let n=i(t.pageIndex??0,t.manga.pages.length);return $({...e,manga:t.manga,currentPageIndex:n,zoomScale:1,panX:0,panY:0})}case`goToPage`:{let n=i(t.pageIndex,e.manga.pages.length),r=e.zoomScale===1&&e.panX===0&&e.panY===0;return n===e.currentPageIndex&&r?e:$({...e,currentPageIndex:n,zoomScale:1,panX:0,panY:0})}case`nextPage`:{let t=a(e.settings,e.currentPageIndex);return Q(e,{type:`goToPage`,pageIndex:e.currentPageIndex+t})}case`previousPage`:{let t=a(e.settings,e.currentPageIndex);return Q(e,{type:`goToPage`,pageIndex:e.currentPageIndex-t})}case`setOverlayVisible`:return{...e,overlayVisible:t.visible,panel:t.visible?e.panel:`none`};case`toggleAutoPageTurn`:return{...e,autoPageTurnEnabled:!e.autoPageTurnEnabled};case`updateSettings`:{let n=r(e.settings,t.settings);return $({...e,settings:n,layout:{...e.layout,mode:n.layoutMode}})}case`setLayoutMode`:return Q(e,{type:`updateSettings`,settings:{layoutMode:t.layoutMode}});case`setTheaterHeight`:return{...e,layout:{...e.layout,theaterHeightPx:Math.max(240,Math.round(t.heightPx))}};case`setZoom`:return{...e,zoomScale:De(t.scale,e),panX:t.panX??e.panX,panY:t.panY??e.panY};case`setPan`:return{...e,panX:t.panX,panY:t.panY};case`resetZoom`:return{...e,zoomScale:1,panX:0,panY:0};case`setPanel`:return{...e,panel:t.panel,overlayVisible:t.panel===`none`?e.overlayVisible:!0};case`pushNotification`:return{...e,notifications:[t.notification]};case`removeNotification`:return{...e,notifications:e.notifications.filter(e=>e.id!==t.id)}}}function $(e){return{...e,visiblePageIndexes:o(e.currentPageIndex,e.manga.pages.length,e.settings)}}function De(e,t){return Math.min(Math.max(e,t.settings.zoom.min),t.settings.zoom.max)}var Oe=class{state;listeners=new Set;constructor(e){this.state=e}getState(){return this.state}dispatch(e){let t=this.state,n=Q(t,e);if(n!==t){this.state=n;for(let e of this.listeners)e(n,t)}}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}},ke=class{objectUrls=new Set;async resolveImageSource(e,t){return t.src}revokeAll(){for(let e of this.objectUrls)URL.revokeObjectURL(e);this.objectUrls.clear()}},Ae=class{handlers=new Map;on(e,t){let n=this.handlers.get(e);return n||(n=new Set,this.handlers.set(e,n)),n.add(t),()=>{n.delete(t)}}emit(e,t){let n=this.handlers.get(e);if(n)for(let e of n)try{e(t)}catch(e){console.error(e)}}clear(){this.handlers.clear()}},je=class{container;store;storage;assetLoader;renderer;i18n;events=new Ae;unsubscribers=[];notificationTimers=new Map;autoTimer;mobileMediaQuery;constructor(e,i){this.container=e;let a=r(t,{...i.settings,locale:i.locale??i.settings?.locale??t.locale});this.storage=new Ee(i.storage),this.assetLoader=new ke,this.i18n=new l(a.locale,i.translations),this.store=new Oe(n(i.manga,a,i.initialPageIndex));let o={goToPage:e=>this.goToPage(e),nextPage:()=>this.nextPage(),previousPage:()=>this.previousPage(),commitNextPage:()=>this.commitNextPage(),commitPreviousPage:()=>this.commitPreviousPage(),toggleOverlay:e=>this.toggleOverlay(e),toggleAutoPageTurn:()=>this.toggleAutoPageTurn(),updateSettings:e=>{this.updateSettings(e)},setLayoutMode:e=>void this.setLayoutMode(e),setTheaterHeight:e=>this.setTheaterHeight(e),setPanel:e=>{this.store.dispatch({type:`setPanel`,panel:e})},setZoom:(e,t,n)=>this.store.dispatch({type:`setZoom`,scale:e,panX:t,panY:n}),setPan:(e,t)=>this.store.dispatch({type:`setPan`,panX:e,panY:t}),resetZoom:()=>this.store.dispatch({type:`resetZoom`})};this.renderer=new Te(this.container,o,this.assetLoader,this.i18n,i.className);for(let[e,t]of Object.entries(i.events??{}))this.on(e,t);this.unsubscribers.push(this.store.subscribe((e,t)=>{this.renderer.update(e),this.afterStateChange(e,t)})),this.bindKeyboard(),this.bindViewportChange(),this.bootstrap()}destroy(){window.clearInterval(this.autoTimer);for(let e of this.notificationTimers.values())window.clearTimeout(e);this.notificationTimers.clear(),this.unsubscribers.forEach(e=>e()),this.assetLoader.revokeAll(),this.renderer.destroy(),this.events.emit(`destroy`,void 0),this.events.clear()}async setManga(e){let t=await this.storage.getProgress(e.id)??0;this.store.dispatch({type:`setManga`,manga:e,pageIndex:t})}async setPages(e){await this.setManga({...this.store.getState().manga,pages:e})}getState(){return this.store.getState()}async updateSettings(e){this.store.dispatch({type:`updateSettings`,settings:e});let t=this.store.getState().settings;this.i18n.setLocale(t.locale),await this.storage.saveSettings(t),this.events.emit(`settingsChange`,{settings:t})}goToPage(e){let t=this.store.getState().currentPageIndex;this.store.dispatch({type:`goToPage`,pageIndex:e});let n=this.store.getState().currentPageIndex;if(t!==n){let e=this.store.getState();this.storage.saveProgress(e.manga.id,n),this.events.emit(`pageChange`,{pageIndex:n,page:e.manga.pages[n]})}}nextPage(){if(this.renderer.isAnimatingPageTurn())return;let e=this.store.getState();this.renderer.animatePageTurn(e,`next`,()=>this.commitNextPage())||this.commitNextPage()}previousPage(){if(this.renderer.isAnimatingPageTurn())return;let e=this.store.getState();this.renderer.animatePageTurn(e,`previous`,()=>this.commitPreviousPage())||this.commitPreviousPage()}commitNextPage(){if(this.renderer.isMobileViewport()){this.goToPage(this.store.getState().currentPageIndex+1);return}let e=this.store.getState().currentPageIndex;this.store.dispatch({type:`nextPage`}),this.emitPageChangeIfNeeded(e)}commitPreviousPage(){if(this.renderer.isMobileViewport()){this.goToPage(this.store.getState().currentPageIndex-1);return}let e=this.store.getState().currentPageIndex;this.store.dispatch({type:`previousPage`}),this.emitPageChangeIfNeeded(e)}toggleOverlay(e){let t=this.store.getState().overlayVisible,n=e??!t;this.store.dispatch({type:`setOverlayVisible`,visible:n})}toggleAutoPageTurn(){this.store.dispatch({type:`toggleAutoPageTurn`}),this.syncAutoTimer();let e=this.store.getState().autoPageTurnEnabled;this.notify(this.i18n.t(e?`autoplay.start`:`autoplay.stop`))}async toggleFullscreen(){let e=this.store.getState();if(document.fullscreenElement){await document.exitFullscreen(),await this.setLayoutMode(`inline`);return}await this.setLayoutMode(e.layout.mode===`nativeFullscreen`?`inline`:`nativeFullscreen`)}on(e,t){return this.events.on(e,t)}async bootstrap(){let e=await this.storage.getSettings(),t=await this.storage.getLayout(),n=this.store.getState().manga.id,r=await this.storage.getProgress(n);e&&this.store.dispatch({type:`updateSettings`,settings:e}),t?.mode&&this.store.dispatch({type:`setLayoutMode`,layoutMode:t.mode}),t?.theaterHeightPx&&this.store.dispatch({type:`setTheaterHeight`,heightPx:t.theaterHeightPx}),typeof r==`number`&&this.store.dispatch({type:`goToPage`,pageIndex:r}),this.renderer.update(this.store.getState()),this.renderer.showSplash(),window.setTimeout(()=>{this.toggleOverlay(!0)},1550),this.events.emit(`ready`,{manga:this.store.getState().manga})}bindKeyboard(){this.renderer.getElement();let e=e=>{if(this.shouldHandleKeyboardEvent(e))switch(e.key){case`ArrowLeft`:e.preventDefault(),this.moveFromKey(`left`);break;case`ArrowRight`:e.preventDefault(),this.moveFromKey(`right`);break;case` `:e.preventDefault(),this.moveFromKey(e.shiftKey?`right`:`left`);break;case`a`:case`A`:e.preventDefault(),this.toggleAutoPageTurn();break;case`n`:case`N`:e.preventDefault(),this.setLayoutMode(`inline`);break;case`w`:case`W`:e.preventDefault(),this.setLayoutMode(`theater`);break;case`f`:case`F`:e.preventDefault(),this.setLayoutMode(`browserFullscreen`);break;case`m`:case`M`:{e.preventDefault();let t=this.store.getState().panel,n=t===`menu`||t===`pages`||t===`shortcuts`;this.store.dispatch({type:`setPanel`,panel:n?`none`:`menu`}),n||this.toggleOverlay(!0);break}case`p`:case`P`:e.preventDefault(),this.updateSettings({pageTurnMode:this.store.getState().settings.pageTurnMode===`spread`?`single`:`spread`});break;case`s`:case`S`:{e.preventDefault();let t=this.store.getState().panel===`settings`;this.store.dispatch({type:`setPanel`,panel:t?`none`:`settings`}),t||this.toggleOverlay(!0);break}case`Escape`:e.preventDefault(),this.store.dispatch({type:`setPanel`,panel:`none`}),document.fullscreenElement&&document.exitFullscreen();break}};window.addEventListener(`keydown`,e),this.unsubscribers.push(()=>window.removeEventListener(`keydown`,e))}shouldHandleKeyboardEvent(e){let t=e.target;return t instanceof Element?!t.closest(`input, select, textarea, [contenteditable='true']`):!0}bindViewportChange(){this.mobileMediaQuery=window.matchMedia(`(max-width: 676px)`);let e=()=>{this.renderer.update(this.store.getState())};this.mobileMediaQuery.addEventListener(`change`,e),this.unsubscribers.push(()=>this.mobileMediaQuery?.removeEventListener(`change`,e))}moveFromKey(e){this.store.getState().settings.readingDirection===`rtl`?e===`left`?this.nextPage():this.previousPage():e===`left`?this.previousPage():this.nextPage()}async setLayoutMode(e){if(e===`nativeFullscreen`)try{await this.renderer.getElement().requestFullscreen()}catch{e=`browserFullscreen`}else document.fullscreenElement&&await document.exitFullscreen();if(e===`theater`&&!this.store.getState().layout.theaterHeightPx){let e=this.renderer.getElement().offsetHeight;e>0&&this.store.dispatch({type:`setTheaterHeight`,heightPx:e})}this.store.dispatch({type:`setLayoutMode`,layoutMode:e}),await this.storage.saveSettings(this.store.getState().settings),await this.storage.saveLayout(this.store.getState().layout),this.events.emit(`layoutChange`,{layoutMode:e})}setTheaterHeight(e){this.store.dispatch({type:`setTheaterHeight`,heightPx:e}),this.storage.saveLayout(this.store.getState().layout)}afterStateChange(e,t){e.autoPageTurnEnabled!==t.autoPageTurnEnabled&&this.syncAutoTimer()}syncAutoTimer(){window.clearInterval(this.autoTimer),this.store.getState().autoPageTurnEnabled&&(this.autoTimer=window.setInterval(()=>{let e=this.store.getState(),t=a(e.settings,e.currentPageIndex);if(e.currentPageIndex+t>=e.manga.pages.length){this.toggleAutoPageTurn();return}this.nextPage()},this.store.getState().settings.autoPageTurnIntervalMs))}emitPageChangeIfNeeded(e){let t=this.store.getState();t.currentPageIndex!==e&&(this.storage.saveProgress(t.manga.id,t.currentPageIndex),this.events.emit(`pageChange`,{pageIndex:t.currentPageIndex,page:t.manga.pages[t.currentPageIndex]}))}notify(e,t=`info`){for(let e of this.notificationTimers.values())window.clearTimeout(e);this.notificationTimers.clear();let n=`${Date.now()}-${Math.random().toString(36).slice(2)}`;this.store.dispatch({type:`pushNotification`,notification:{id:n,message:e,tone:t,createdAt:Date.now()}});let r=window.setTimeout(()=>{this.store.dispatch({type:`removeNotification`,id:n}),this.notificationTimers.delete(n)},3e3);this.notificationTimers.set(n,r)}};function Me(e,t){return new je(e,t)}return e.createMangaViewer=Me,e})({});
@@ -1 +1 @@
1
- {"version":3,"file":"viewer-renderer.d.ts","sourceRoot":"","sources":["../../src/renderer/viewer-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAgBnD,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAY9D,qBAAa,cAAc;IAqBvB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,IAAI;IAvBd,OAAO,CAAC,IAAI,CAAiB;IAC7B,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,UAAU,CAAC,CAAY;IAC/B,OAAO,CAAC,UAAU,CAAC,CAAY;IAC/B,OAAO,CAAC,UAAU,CAAC,CAAsC;IACzD,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,aAAa,CAAC,CAAS;IAC/B,OAAO,CAAC,iBAAiB,CAAC,CAAS;IACnC,OAAO,CAAC,MAAM,CAAC,CAAc;IAC7B,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,eAAe,CAAC,CAAS;IACjC,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,OAAO,CAAC,gBAAgB,CAAC,CAAmB;IAC5C,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,YAAY,CAAC,CAAiB;IACtC,OAAO,CAAC,gBAAgB,CAAC,CAAiB;gBAGhC,SAAS,EAAE,WAAW,EACtB,SAAS,EAAE,iBAAiB,EAC5B,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,IAAI,EAClB,SAAS,CAAC,EAAE,MAAM;IAapB,OAAO,CAAC,eAAe;IAqBvB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAyGhC,OAAO,CAAC,sBAAsB;IAW9B,UAAU,IAAI,IAAI;IAalB,OAAO,IAAI,IAAI;IAgBf,UAAU,IAAI,WAAW;IAIzB,mBAAmB,IAAI,OAAO;IAI9B,eAAe,CACb,KAAK,EAAE,WAAW,EAClB,SAAS,EAAE,UAAU,GAAG,MAAM,EAC9B,UAAU,EAAE,MAAM,IAAI,GACrB,OAAO;IAqBV,gBAAgB,IAAI,OAAO;IAI3B,OAAO,CAAC,QAAQ;IAwBhB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,kBAAkB;IAmC1B,OAAO,CAAC,YAAY;IA8NpB,OAAO,CAAC,cAAc;IAoCtB,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,mBAAmB;IAyB3B,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,uBAAuB;IAQ/B,OAAO,CAAC,mBAAmB;CAuB5B"}
1
+ {"version":3,"file":"viewer-renderer.d.ts","sourceRoot":"","sources":["../../src/renderer/viewer-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAgBnD,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAY9D,qBAAa,cAAc;IAqBvB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,IAAI;IAvBd,OAAO,CAAC,IAAI,CAAiB;IAC7B,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,UAAU,CAAC,CAAY;IAC/B,OAAO,CAAC,UAAU,CAAC,CAAY;IAC/B,OAAO,CAAC,UAAU,CAAC,CAAsC;IACzD,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,aAAa,CAAC,CAAS;IAC/B,OAAO,CAAC,iBAAiB,CAAC,CAAS;IACnC,OAAO,CAAC,MAAM,CAAC,CAAc;IAC7B,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,eAAe,CAAC,CAAS;IACjC,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,OAAO,CAAC,gBAAgB,CAAC,CAAmB;IAC5C,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,YAAY,CAAC,CAAiB;IACtC,OAAO,CAAC,gBAAgB,CAAC,CAAiB;gBAGhC,SAAS,EAAE,WAAW,EACtB,SAAS,EAAE,iBAAiB,EAC5B,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,IAAI,EAClB,SAAS,CAAC,EAAE,MAAM;IAapB,OAAO,CAAC,eAAe;IAqBvB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAyGhC,OAAO,CAAC,sBAAsB;IAW9B,UAAU,IAAI,IAAI;IAalB,OAAO,IAAI,IAAI;IAgBf,UAAU,IAAI,WAAW;IAIzB,mBAAmB,IAAI,OAAO;IAI9B,eAAe,CACb,KAAK,EAAE,WAAW,EAClB,SAAS,EAAE,UAAU,GAAG,MAAM,EAC9B,UAAU,EAAE,MAAM,IAAI,GACrB,OAAO;IAsBV,gBAAgB,IAAI,OAAO;IAI3B,OAAO,CAAC,QAAQ;IAwBhB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,kBAAkB;IAmC1B,OAAO,CAAC,YAAY;IA8NpB,OAAO,CAAC,cAAc;IAoCtB,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,mBAAmB;IAyB3B,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,uBAAuB;IAQ/B,OAAO,CAAC,mBAAmB;CAuB5B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yui540/comimi",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Open-source comic reader library for JS/TS",
5
5
  "keywords": [
6
6
  "manga",