From f5b7dc73ca09d0355c72a00de82f133f256b565a Mon Sep 17 00:00:00 2001 From: WoodNeck Date: Mon, 27 Feb 2023 12:48:01 +0900 Subject: [PATCH] chore: Release 4.0.0-beta.4 --- CHANGELOG.md | 23 + demo/release/4.0.0-beta.4/css/base.css | 20 + demo/release/4.0.0-beta.4/css/base.min.css | 1 + demo/release/4.0.0-beta.4/css/control-bar.css | 353 + .../4.0.0-beta.4/css/control-bar.min.css | 1 + demo/release/4.0.0-beta.4/css/helper.css | 67 + demo/release/4.0.0-beta.4/css/helper.min.css | 1 + demo/release/4.0.0-beta.4/css/hotspot.css | 21 + demo/release/4.0.0-beta.4/css/hotspot.min.css | 1 + .../4.0.0-beta.4/css/loading-spinner.css | 37 + .../4.0.0-beta.4/css/loading-spinner.min.css | 1 + demo/release/4.0.0-beta.4/css/variable.css | 0 .../release/4.0.0-beta.4/css/variable.min.css | 0 demo/release/4.0.0-beta.4/css/view360.css | 511 + demo/release/4.0.0-beta.4/css/view360.min.css | 1 + demo/release/4.0.0-beta.4/css/vr.css | 8 + demo/release/4.0.0-beta.4/css/vr.min.css | 1 + demo/release/4.0.0-beta.4/dist/view360.esm.js | 7752 ++++++++++++ .../4.0.0-beta.4/dist/view360.esm.js.map | 1 + demo/release/4.0.0-beta.4/dist/view360.js | 7825 ++++++++++++ demo/release/4.0.0-beta.4/dist/view360.js.map | 1 + demo/release/4.0.0-beta.4/dist/view360.min.js | 2 + .../4.0.0-beta.4/dist/view360.min.js.map | 1 + .../release/4.0.0-beta.4/dist/view360.pkgd.js | 10532 ++++++++++++++++ .../4.0.0-beta.4/dist/view360.pkgd.js.map | 1 + .../4.0.0-beta.4/dist/view360.pkgd.min.js | 30 + .../4.0.0-beta.4/dist/view360.pkgd.min.js.map | 1 + demo/release/4.0.0-beta.4/sass/base.sass | 17 + .../4.0.0-beta.4/sass/control-bar.sass | 284 + demo/release/4.0.0-beta.4/sass/helper.sass | 51 + demo/release/4.0.0-beta.4/sass/hotspot.sass | 20 + .../4.0.0-beta.4/sass/loading-spinner.sass | 34 + demo/release/4.0.0-beta.4/sass/variable.sass | 2 + demo/release/4.0.0-beta.4/sass/view360.sass | 6 + demo/release/4.0.0-beta.4/sass/vr.sass | 10 + demo/release/latest/css/base.css | 20 + demo/release/latest/css/base.min.css | 1 + demo/release/latest/css/control-bar.css | 353 + demo/release/latest/css/control-bar.min.css | 1 + demo/release/latest/css/helper.css | 67 + demo/release/latest/css/helper.min.css | 1 + demo/release/latest/css/hotspot.css | 21 + demo/release/latest/css/hotspot.min.css | 1 + demo/release/latest/css/loading-spinner.css | 37 + .../latest/css/loading-spinner.min.css | 1 + demo/release/latest/css/variable.css | 0 demo/release/latest/css/variable.min.css | 0 demo/release/latest/css/view360.css | 511 + demo/release/latest/css/view360.min.css | 1 + demo/release/latest/css/vr.css | 8 + demo/release/latest/css/vr.min.css | 1 + demo/release/latest/dist/view360.esm.js | 7752 ++++++++++++ demo/release/latest/dist/view360.esm.js.map | 1 + demo/release/latest/dist/view360.js | 7825 ++++++++++++ demo/release/latest/dist/view360.js.map | 1 + demo/release/latest/dist/view360.min.js | 2 + demo/release/latest/dist/view360.min.js.map | 1 + demo/release/latest/dist/view360.pkgd.js | 10532 ++++++++++++++++ demo/release/latest/dist/view360.pkgd.js.map | 1 + demo/release/latest/dist/view360.pkgd.min.js | 30 + .../latest/dist/view360.pkgd.min.js.map | 1 + demo/release/latest/sass/base.sass | 17 + demo/release/latest/sass/control-bar.sass | 284 + demo/release/latest/sass/helper.sass | 51 + demo/release/latest/sass/hotspot.sass | 20 + demo/release/latest/sass/loading-spinner.sass | 34 + demo/release/latest/sass/variable.sass | 2 + demo/release/latest/sass/view360.sass | 6 + demo/release/latest/sass/vr.sass | 10 + .../projects/ngx-view360/CHANGELOG.md | 9 + packages/react-view360/CHANGELOG.md | 9 + packages/svelte-view360/CHANGELOG.md | 9 + packages/view360/CHANGELOG.md | 9 + packages/vue-view360/CHANGELOG.md | 9 + packages/vue3-view360/CHANGELOG.md | 9 + 75 files changed, 55265 insertions(+) create mode 100644 demo/release/4.0.0-beta.4/css/base.css create mode 100644 demo/release/4.0.0-beta.4/css/base.min.css create mode 100644 demo/release/4.0.0-beta.4/css/control-bar.css create mode 100644 demo/release/4.0.0-beta.4/css/control-bar.min.css create mode 100644 demo/release/4.0.0-beta.4/css/helper.css create mode 100644 demo/release/4.0.0-beta.4/css/helper.min.css create mode 100644 demo/release/4.0.0-beta.4/css/hotspot.css create mode 100644 demo/release/4.0.0-beta.4/css/hotspot.min.css create mode 100644 demo/release/4.0.0-beta.4/css/loading-spinner.css create mode 100644 demo/release/4.0.0-beta.4/css/loading-spinner.min.css create mode 100644 demo/release/4.0.0-beta.4/css/variable.css create mode 100644 demo/release/4.0.0-beta.4/css/variable.min.css create mode 100644 demo/release/4.0.0-beta.4/css/view360.css create mode 100644 demo/release/4.0.0-beta.4/css/view360.min.css create mode 100644 demo/release/4.0.0-beta.4/css/vr.css create mode 100644 demo/release/4.0.0-beta.4/css/vr.min.css create mode 100644 demo/release/4.0.0-beta.4/dist/view360.esm.js create mode 100644 demo/release/4.0.0-beta.4/dist/view360.esm.js.map create mode 100644 demo/release/4.0.0-beta.4/dist/view360.js create mode 100644 demo/release/4.0.0-beta.4/dist/view360.js.map create mode 100644 demo/release/4.0.0-beta.4/dist/view360.min.js create mode 100644 demo/release/4.0.0-beta.4/dist/view360.min.js.map create mode 100644 demo/release/4.0.0-beta.4/dist/view360.pkgd.js create mode 100644 demo/release/4.0.0-beta.4/dist/view360.pkgd.js.map create mode 100644 demo/release/4.0.0-beta.4/dist/view360.pkgd.min.js create mode 100644 demo/release/4.0.0-beta.4/dist/view360.pkgd.min.js.map create mode 100644 demo/release/4.0.0-beta.4/sass/base.sass create mode 100644 demo/release/4.0.0-beta.4/sass/control-bar.sass create mode 100644 demo/release/4.0.0-beta.4/sass/helper.sass create mode 100644 demo/release/4.0.0-beta.4/sass/hotspot.sass create mode 100644 demo/release/4.0.0-beta.4/sass/loading-spinner.sass create mode 100644 demo/release/4.0.0-beta.4/sass/variable.sass create mode 100644 demo/release/4.0.0-beta.4/sass/view360.sass create mode 100644 demo/release/4.0.0-beta.4/sass/vr.sass create mode 100644 demo/release/latest/css/base.css create mode 100644 demo/release/latest/css/base.min.css create mode 100644 demo/release/latest/css/control-bar.css create mode 100644 demo/release/latest/css/control-bar.min.css create mode 100644 demo/release/latest/css/helper.css create mode 100644 demo/release/latest/css/helper.min.css create mode 100644 demo/release/latest/css/hotspot.css create mode 100644 demo/release/latest/css/hotspot.min.css create mode 100644 demo/release/latest/css/loading-spinner.css create mode 100644 demo/release/latest/css/loading-spinner.min.css create mode 100644 demo/release/latest/css/variable.css create mode 100644 demo/release/latest/css/variable.min.css create mode 100644 demo/release/latest/css/view360.css create mode 100644 demo/release/latest/css/view360.min.css create mode 100644 demo/release/latest/css/vr.css create mode 100644 demo/release/latest/css/vr.min.css create mode 100644 demo/release/latest/dist/view360.esm.js create mode 100644 demo/release/latest/dist/view360.esm.js.map create mode 100644 demo/release/latest/dist/view360.js create mode 100644 demo/release/latest/dist/view360.js.map create mode 100644 demo/release/latest/dist/view360.min.js create mode 100644 demo/release/latest/dist/view360.min.js.map create mode 100644 demo/release/latest/dist/view360.pkgd.js create mode 100644 demo/release/latest/dist/view360.pkgd.js.map create mode 100644 demo/release/latest/dist/view360.pkgd.min.js create mode 100644 demo/release/latest/dist/view360.pkgd.min.js.map create mode 100644 demo/release/latest/sass/base.sass create mode 100644 demo/release/latest/sass/control-bar.sass create mode 100644 demo/release/latest/sass/helper.sass create mode 100644 demo/release/latest/sass/hotspot.sass create mode 100644 demo/release/latest/sass/loading-spinner.sass create mode 100644 demo/release/latest/sass/variable.sass create mode 100644 demo/release/latest/sass/view360.sass create mode 100644 demo/release/latest/sass/vr.sass diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ae572230..089676f59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,29 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.0.0-beta.4](https://github.com/naver/egjs-view360/compare/4.0.0-beta.0...4.0.0-beta.4) (2023-02-27) +### :sparkles: Packages +* `@egjs/ngx-view360` 4.0.0-beta.4 +* `@egjs/react-view360` 4.0.0-beta.4 +* `@egjs/svelte-view360` 4.0.0-beta.4 +* `@egjs/view360` 4.0.0-beta.4 +* `@egjs/vue-view360` 4.0.0-beta.4 +* `@egjs/vue3-view360` 4.0.0-beta.4 + + +### :memo: Documentation + +* fix vue3 example code ([3573da5](https://github.com/naver/egjs-view360/commit/3573da579cd1a8d939af96b87d9c5f75cf918a40)) +* update title style ([05308d3](https://github.com/naver/egjs-view360/commit/05308d3ff3890dbc2f9330c7a771557023d60303)) + + +### :mega: Other + +* All + * update packages versions ([64d704d](https://github.com/naver/egjs-view360/commit/64d704dde25002931fb7422a817a6322542b66eb)) + + + ## [4.0.0-beta.0](https://github.com/naver/egjs-view360/compare/3.6.3...4.0.0-beta.0) (2023-02-17) ### :sparkles: Packages * `@egjs/ngx-view360` 4.0.0-beta.0 diff --git a/demo/release/4.0.0-beta.4/css/base.css b/demo/release/4.0.0-beta.4/css/base.css new file mode 100644 index 000000000..009ab5d12 --- /dev/null +++ b/demo/release/4.0.0-beta.4/css/base.css @@ -0,0 +1,20 @@ +.view360-container { + position: relative; + touch-action: pan-y; + overflow: hidden; +} + +.view360-canvas { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + -ms-user-select: none; + user-select: none; + -webkit-user-drag: none; +} + +.view360-canvas.ctx-lost { + text-indent: 0.001px; +} diff --git a/demo/release/4.0.0-beta.4/css/base.min.css b/demo/release/4.0.0-beta.4/css/base.min.css new file mode 100644 index 000000000..0d9974270 --- /dev/null +++ b/demo/release/4.0.0-beta.4/css/base.min.css @@ -0,0 +1 @@ +.view360-container{position:relative;touch-action:pan-y;overflow:hidden}.view360-canvas{position:absolute;left:0;top:0;width:100%;height:100%;-ms-user-select:none;user-select:none;-webkit-user-drag:none}.view360-canvas.ctx-lost{text-indent:.001px} \ No newline at end of file diff --git a/demo/release/4.0.0-beta.4/css/control-bar.css b/demo/release/4.0.0-beta.4/css/control-bar.css new file mode 100644 index 000000000..7592a1a51 --- /dev/null +++ b/demo/release/4.0.0-beta.4/css/control-bar.css @@ -0,0 +1,353 @@ +.view360-controls { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + padding: 0; + margin: 0; + border: 0; + pointer-events: none; + -ms-user-select: none; + user-select: none; + -webkit-user-drag: none; + z-index: 1; +} + +.view360-main.view360-vr-presenting .view360-controls { + display: none; +} + +.view360-controls-float-left, +.view360-controls-float-right { + position: absolute; + display: flex; + flex-direction: column; +} + +.view360-controls-float-left { + left: 0px; + top: 0px; +} + +.view360-controls-float-right { + right: 0px; + top: 0px; +} + +.view360-controls-main { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + opacity: 1; + transition: none; +} + +.view360-controls-main.view360-controls-hidden { + opacity: 0; + transition: opacity 500ms; +} + +.view360-controls-main.view360-controls-hidden * { + pointer-events: none; +} + +.view360-controls-main.view360-controls-fixed { + opacity: 1; +} + +.view360-controls-background { + width: 100%; + height: calc(100% + 32px); + position: absolute; + left: 0; + bottom: 0; + background-image: linear-gradient(0deg, #323232, rgba(50, 50, 50, 0)); +} + +.view360-controls-background.view360-controls-hidden { + display: none; +} + +.view360-controls-mid { + display: flex; + flex-direction: row; + position: relative; +} + +.view360-controls-left { + display: flex; + flex: 1; + justify-content: flex-start; + align-items: center; + flex-direction: row; +} + +.view360-controls-right { + display: flex; + align-items: center; + flex-direction: row; +} + +.view360-controls-bottom { + display: flex; + align-items: center; + flex-direction: row; +} + +.view360-controls-button { + display: inline-block; + background-color: transparent; + cursor: pointer; + border: 0; + position: relative; + background-size: 24px 24px; + background-origin: content-box; + background-repeat: no-repeat; + box-sizing: border-box; + pointer-events: all; + border-radius: 20px; + transition: opacity 250ms; + width: 40px; + height: 40px; + margin: 6px; + padding: 8px; + opacity: 0.8; + /* + * Following background-image svgs are from tabler icons + * https://github.com/tabler/tabler-icons + * + * tabler icons is licensed under the MIT license + * https://github.com/tabler/tabler-icons/blob/master/LICENSE + */ + /* + * Following background-image svgs are from Google Material Icons + * https://fonts.google.com/icons + * + * Material Design Icons is licensed under the Apache License 2.0 + * https://github.com/google/material-design-icons/blob/master/LICENSE + */ +} + +.view360-controls-button:hover { + opacity: 1; +} + +.view360-controls-button.view360-controls-vr { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48' viewBox='0 0 100 100'%3E%3Cg%3E%3Cpath d='M5,30 L95,30 L95,80 L55,80 L50,70 L45,80 L5,80 L5,30' fill='transparent' stroke='%23fff' stroke-width='8' stroke-linejoin='round' stroke-linecap='round'/%3E%3Cpath d='M5,30 L15,10 L85,10 L95,30' fill='transparent' stroke='%23fff' stroke-width='8' stroke-linejoin='round' stroke-linecap='round'/%3E%3Ccircle cx='30' cy='55' r='10' stroke='%23fff' stroke-width='8' fill='transparent' /%3E%3Ccircle cx='70' cy='55' r='10' stroke='%23fff' stroke-width='8' fill='transparent' /%3E%3C/g%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-play { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M7 4v16l13 -8z'%3E%3C/path%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-pause { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Crect x='6' y='5' width='4' height='14' rx='1'%3E%3C/rect%3E%3Crect x='14' y='5' width='4' height='14' rx='1'%3E%3C/rect%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-unmuted { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M15 8a5 5 0 0 1 0 8'%3E%3C/path%3E%3Cpath d='M17.7 5a9 9 0 0 1 0 14'%3E%3C/path%3E%3Cpath d='M6 15h-2a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h2l3.5 -4.5a0.8 .8 0 0 1 1.5 .5v14a0.8 .8 0 0 1 -1.5 .5l-3.5 -4.5'%3E%3C/path%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-muted { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M6 15h-2a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h2l3.5 -4.5a0.8 .8 0 0 1 1.5 .5v14a0.8 .8 0 0 1 -1.5 .5l-3.5 -4.5'%3E%3C/path%3E%3Cpath d='M16 10l4 4m0 -4l-4 4'%3E%3C/path%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-fullscreen { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M4 8v-2a2 2 0 0 1 2 -2h2'%3E%3C/path%3E%3Cpath d='M4 16v2a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v2'%3E%3C/path%3E%3Cpath d='M16 20h2a2 2 0 0 0 2 -2v-2'%3E%3C/path%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-fullscreen-exit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M15 19v-2a2 2 0 0 1 2 -2h2'%3E%3C/path%3E%3Cpath d='M15 5v2a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3Cpath d='M5 15h2a2 2 0 0 1 2 2v2'%3E%3C/path%3E%3Cpath d='M5 9h2a2 2 0 0 0 2 -2v-2'%3E%3C/path%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-gyro-enabled { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48'%3E%3Cpath fill='%23fff' d='M22.5 7.6v2.95q-1 .15-1.975.475-.975.325-1.875.825L16.5 9.7q1.35-.9 2.875-1.4 1.525-.5 3.125-.7Zm15.35 15.35q-.2 1.6-.7 3.125-.5 1.525-1.4 2.875L33.6 26.8q.5-.9.825-1.875.325-.975.475-1.975Zm3.8 20.45L1.3 3.05 3.45.9 43.8 41.25ZM7 41.4q-1.25 0-2.125-.875T4 38.4v-8.6h3v8.6h8.6v3ZM41 13V4.4h-8.6v-3H41q1.25 0 2.125.875T44 4.4V13ZM4 13V4.4q0-.55.2-1.1t.6-1l2.1 2.1V13Zm28.4 28.4v-3h8.5l2.1 2.1q-.4.45-.925.675-.525.225-1.075.225Zm-21.2-37-3-3h7.4v3ZM44 37.2l-3-3v-4.4h3ZM10.15 22.95h2.95q.5 3.7 3.1 6.3 2.6 2.6 6.3 3.1v2.95q-4.9-.55-8.35-4-3.45-3.45-4-8.35Zm4-11.35 2.1 2.05q-1.3 1.3-2.1 2.9-.8 1.6-1.05 3.4h-2.95q.25-2.4 1.275-4.525Q12.45 13.3 14.15 11.6ZM31.8 29.2l2.05 2.1q-1.7 1.7-3.825 2.725Q27.9 35.05 25.5 35.3v-2.95q1.8-.25 3.4-1.05 1.6-.8 2.9-2.1ZM25.5 7.6q4.9.55 8.35 4 3.45 3.45 4 8.35H34.9q-.5-3.7-3.1-6.3-2.6-2.6-6.3-3.1Z'/%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-gyro-disabled { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48'%3E%3Cpath fill='%23fff' d='M7 44q-1.2 0-2.1-.9Q4 42.2 4 41v-8.6h3V41h8.6v3ZM4 15.6V7q0-1.2.9-2.1Q5.8 4 7 4h8.6v3H7v8.6Zm18.5 22.25q-4.9-.55-8.35-4-3.45-3.45-4-8.35h2.95q.5 3.7 3.125 6.3 2.625 2.6 6.275 3.1ZM10.15 22.5q.55-4.9 4-8.35 3.45-3.45 8.35-4v2.95q-3.7.5-6.3 3.1-2.6 2.6-3.1 6.3Zm13.85 5q-1.45 0-2.475-1.025Q20.5 25.45 20.5 24q0-1.45 1.025-2.475Q22.55 20.5 24 20.5q1.45 0 2.475 1.025Q27.5 22.55 27.5 24q0 1.45-1.025 2.475Q25.45 27.5 24 27.5Zm1.5 10.35V34.9q3.7-.5 6.3-3.125 2.6-2.625 3.1-6.275h2.95q-.55 4.9-4 8.35-3.45 3.45-8.35 4Zm9.4-15.35q-.5-3.7-3.1-6.3-2.6-2.6-6.3-3.1v-2.95q4.9.55 8.35 4 3.45 3.45 4 8.35ZM32.4 44v-3H41v-8.6h3V41q0 1.2-.9 2.1-.9.9-2.1.9ZM41 15.6V7h-8.6V4H41q1.2 0 2.1.9.9.9.9 2.1v8.6Z'/%3E%3C/svg%3E"); +} + +.view360-controls-time { + display: inline-block; + vertical-align: top; + white-space: nowrap; + color: white; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-weight: normal; + font-size: 14px; + z-index: 1; +} + +.view360-controls-time:first-child { + padding: 0 16px; +} + +.view360-controls-progress { + flex: 1; + width: 100%; + padding: 0 16px; + box-sizing: border-box; +} + +.view360-controls-progress:not(:first-child) { + padding-left: 0; +} + +.view360-controls-bottom .view360-controls-progress { + padding-bottom: 20px; +} + +.view360-controls-volume { + display: inline-flex; + flex-direction: row; + align-items: center; + transition: width 250ms, background-color 250ms; + overflow: hidden; +} + +.view360-controls-volume:not(:disabled):hover, .view360-controls-volume:not(:disabled).view360-controls-fixed { + width: 112px; +} + +.view360-controls-volume .view360-range { + flex: 1; + height: 100%; + padding: 0; +} + +.view360-controls-volume .view360-range .view360-range-track { + width: calc(100% - 12px); + transform: translateX(-4px); +} + +.view360-controls-volume .view360-controls-button { + margin: 0; + padding: 0; + width: 24px; + height: 24px; + flex-shrink: 0; +} + +.view360-controls-volume:disabled { + opacity: 0.5; + pointer-events: none; +} + +.view360-controls-volume:disabled * { + pointer-events: none; +} + +.view360-controls-pie { + width: 36px; + height: 36px; + margin: 6px; + padding: 0; + border-radius: 18px; + opacity: 0.8; + pointer-events: all; + cursor: pointer; + color: #fff; + position: relative; + transition: opacity 250ms; +} + +.view360-controls-pie > svg { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.view360-controls-pie:hover { + opacity: 1; +} + +.view360-range { + position: relative; + cursor: pointer; + pointer-events: all; + display: flex; + justify-content: center; + align-items: center; + touch-action: pan-y; +} + +.view360-range:hover .view360-range-thumb { + opacity: 1; +} + +.view360-range-track { + width: 100%; + height: 4px; + border-radius: 4px; + position: relative; + background-color: rgba(230, 230, 230, 0.4); +} + +.view360-range-filler, +.view360-range-load { + position: absolute; + left: 0; + top: 0; + width: 0; + height: 100%; + border-radius: 4px; +} + +.view360-range-filler { + background-color: #fff; +} + +.view360-range-load { + background-color: #757575; +} + +.view360-range-thumb { + width: 13px; + height: 13px; + position: absolute; + top: -5px; + left: -6.5px; + border-radius: 50%; + background-color: #fff; + box-sizing: border-box; + transition: opacity 250ms; + opacity: 0; +} + +.view360-range-thumb.view360-controls-fixed { + opacity: 1; +} + +.view360-controls-unavailable { + display: none !important; +} + +@media screen and (max-width: 768px) { + .view360-controls-button { + background-size: 18px 18px; + width: 30px; + height: 30px; + margin: 4.5px; + padding: 6px; + border-radius: 15px; + } + .view360-controls-volume .view360-controls-button { + width: 18px; + height: 18px; + } + .view360-controls-volume:not(:disabled):hover, .view360-controls-volume:not(:disabled).view360-controls-fixed { + width: 84px; + } + .view360-controls-pie { + width: 27px; + height: 27px; + margin: 4.5px; + padding: 0; + border-radius: 13.5px; + } +} diff --git a/demo/release/4.0.0-beta.4/css/control-bar.min.css b/demo/release/4.0.0-beta.4/css/control-bar.min.css new file mode 100644 index 000000000..fd73d81ab --- /dev/null +++ b/demo/release/4.0.0-beta.4/css/control-bar.min.css @@ -0,0 +1 @@ +.view360-controls{position:absolute;top:0;left:0;width:100%;height:100%;padding:0;margin:0;border:0;pointer-events:none;-ms-user-select:none;user-select:none;-webkit-user-drag:none;z-index:1}.view360-main.view360-vr-presenting .view360-controls{display:none}.view360-controls-float-left,.view360-controls-float-right{position:absolute;display:flex;flex-direction:column}.view360-controls-float-left{left:0;top:0}.view360-controls-float-right{right:0;top:0}.view360-controls-main{position:absolute;bottom:0;left:0;width:100%;opacity:1;transition:none}.view360-controls-main.view360-controls-hidden{opacity:0;transition:opacity .5s}.view360-controls-main.view360-controls-hidden *{pointer-events:none}.view360-controls-main.view360-controls-fixed{opacity:1}.view360-controls-background{width:100%;height:calc(100% + 32px);position:absolute;left:0;bottom:0;background-image:linear-gradient(0deg,#323232,rgba(50,50,50,0))}.view360-controls-background.view360-controls-hidden{display:none}.view360-controls-mid{display:flex;flex-direction:row;position:relative}.view360-controls-left{display:flex;flex:1;justify-content:flex-start;align-items:center;flex-direction:row}.view360-controls-right{display:flex;align-items:center;flex-direction:row}.view360-controls-bottom{display:flex;align-items:center;flex-direction:row}.view360-controls-button{display:inline-block;background-color:transparent;cursor:pointer;border:0;position:relative;background-size:24px 24px;background-origin:content-box;background-repeat:no-repeat;box-sizing:border-box;pointer-events:all;border-radius:20px;transition:opacity 250ms;width:40px;height:40px;margin:6px;padding:8px;opacity:.8}.view360-controls-button:hover{opacity:1}.view360-controls-button.view360-controls-vr{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48' viewBox='0 0 100 100'%3E%3Cg%3E%3Cpath d='M5,30 L95,30 L95,80 L55,80 L50,70 L45,80 L5,80 L5,30' fill='transparent' stroke='%23fff' stroke-width='8' stroke-linejoin='round' stroke-linecap='round'/%3E%3Cpath d='M5,30 L15,10 L85,10 L95,30' fill='transparent' stroke='%23fff' stroke-width='8' stroke-linejoin='round' stroke-linecap='round'/%3E%3Ccircle cx='30' cy='55' r='10' stroke='%23fff' stroke-width='8' fill='transparent' /%3E%3Ccircle cx='70' cy='55' r='10' stroke='%23fff' stroke-width='8' fill='transparent' /%3E%3C/g%3E%3C/svg%3E")}.view360-controls-button.view360-controls-play{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M7 4v16l13 -8z'%3E%3C/path%3E%3C/svg%3E")}.view360-controls-button.view360-controls-pause{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Crect x='6' y='5' width='4' height='14' rx='1'%3E%3C/rect%3E%3Crect x='14' y='5' width='4' height='14' rx='1'%3E%3C/rect%3E%3C/svg%3E")}.view360-controls-button.view360-controls-unmuted{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M15 8a5 5 0 0 1 0 8'%3E%3C/path%3E%3Cpath d='M17.7 5a9 9 0 0 1 0 14'%3E%3C/path%3E%3Cpath d='M6 15h-2a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h2l3.5 -4.5a0.8 .8 0 0 1 1.5 .5v14a0.8 .8 0 0 1 -1.5 .5l-3.5 -4.5'%3E%3C/path%3E%3C/svg%3E")}.view360-controls-button.view360-controls-muted{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M6 15h-2a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h2l3.5 -4.5a0.8 .8 0 0 1 1.5 .5v14a0.8 .8 0 0 1 -1.5 .5l-3.5 -4.5'%3E%3C/path%3E%3Cpath d='M16 10l4 4m0 -4l-4 4'%3E%3C/path%3E%3C/svg%3E")}.view360-controls-button.view360-controls-fullscreen{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M4 8v-2a2 2 0 0 1 2 -2h2'%3E%3C/path%3E%3Cpath d='M4 16v2a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v2'%3E%3C/path%3E%3Cpath d='M16 20h2a2 2 0 0 0 2 -2v-2'%3E%3C/path%3E%3C/svg%3E")}.view360-controls-button.view360-controls-fullscreen-exit{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M15 19v-2a2 2 0 0 1 2 -2h2'%3E%3C/path%3E%3Cpath d='M15 5v2a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3Cpath d='M5 15h2a2 2 0 0 1 2 2v2'%3E%3C/path%3E%3Cpath d='M5 9h2a2 2 0 0 0 2 -2v-2'%3E%3C/path%3E%3C/svg%3E")}.view360-controls-button.view360-controls-gyro-enabled{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48'%3E%3Cpath fill='%23fff' d='M22.5 7.6v2.95q-1 .15-1.975.475-.975.325-1.875.825L16.5 9.7q1.35-.9 2.875-1.4 1.525-.5 3.125-.7Zm15.35 15.35q-.2 1.6-.7 3.125-.5 1.525-1.4 2.875L33.6 26.8q.5-.9.825-1.875.325-.975.475-1.975Zm3.8 20.45L1.3 3.05 3.45.9 43.8 41.25ZM7 41.4q-1.25 0-2.125-.875T4 38.4v-8.6h3v8.6h8.6v3ZM41 13V4.4h-8.6v-3H41q1.25 0 2.125.875T44 4.4V13ZM4 13V4.4q0-.55.2-1.1t.6-1l2.1 2.1V13Zm28.4 28.4v-3h8.5l2.1 2.1q-.4.45-.925.675-.525.225-1.075.225Zm-21.2-37-3-3h7.4v3ZM44 37.2l-3-3v-4.4h3ZM10.15 22.95h2.95q.5 3.7 3.1 6.3 2.6 2.6 6.3 3.1v2.95q-4.9-.55-8.35-4-3.45-3.45-4-8.35Zm4-11.35 2.1 2.05q-1.3 1.3-2.1 2.9-.8 1.6-1.05 3.4h-2.95q.25-2.4 1.275-4.525Q12.45 13.3 14.15 11.6ZM31.8 29.2l2.05 2.1q-1.7 1.7-3.825 2.725Q27.9 35.05 25.5 35.3v-2.95q1.8-.25 3.4-1.05 1.6-.8 2.9-2.1ZM25.5 7.6q4.9.55 8.35 4 3.45 3.45 4 8.35H34.9q-.5-3.7-3.1-6.3-2.6-2.6-6.3-3.1Z'/%3E%3C/svg%3E")}.view360-controls-button.view360-controls-gyro-disabled{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48'%3E%3Cpath fill='%23fff' d='M7 44q-1.2 0-2.1-.9Q4 42.2 4 41v-8.6h3V41h8.6v3ZM4 15.6V7q0-1.2.9-2.1Q5.8 4 7 4h8.6v3H7v8.6Zm18.5 22.25q-4.9-.55-8.35-4-3.45-3.45-4-8.35h2.95q.5 3.7 3.125 6.3 2.625 2.6 6.275 3.1ZM10.15 22.5q.55-4.9 4-8.35 3.45-3.45 8.35-4v2.95q-3.7.5-6.3 3.1-2.6 2.6-3.1 6.3Zm13.85 5q-1.45 0-2.475-1.025Q20.5 25.45 20.5 24q0-1.45 1.025-2.475Q22.55 20.5 24 20.5q1.45 0 2.475 1.025Q27.5 22.55 27.5 24q0 1.45-1.025 2.475Q25.45 27.5 24 27.5Zm1.5 10.35V34.9q3.7-.5 6.3-3.125 2.6-2.625 3.1-6.275h2.95q-.55 4.9-4 8.35-3.45 3.45-8.35 4Zm9.4-15.35q-.5-3.7-3.1-6.3-2.6-2.6-6.3-3.1v-2.95q4.9.55 8.35 4 3.45 3.45 4 8.35ZM32.4 44v-3H41v-8.6h3V41q0 1.2-.9 2.1-.9.9-2.1.9ZM41 15.6V7h-8.6V4H41q1.2 0 2.1.9.9.9.9 2.1v8.6Z'/%3E%3C/svg%3E")}.view360-controls-time{display:inline-block;vertical-align:top;white-space:nowrap;color:#fff;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-weight:400;font-size:14px;z-index:1}.view360-controls-time:first-child{padding:0 16px}.view360-controls-progress{flex:1;width:100%;padding:0 16px;box-sizing:border-box}.view360-controls-progress:not(:first-child){padding-left:0}.view360-controls-bottom .view360-controls-progress{padding-bottom:20px}.view360-controls-volume{display:inline-flex;flex-direction:row;align-items:center;transition:width 250ms,background-color 250ms;overflow:hidden}.view360-controls-volume:not(:disabled).view360-controls-fixed,.view360-controls-volume:not(:disabled):hover{width:112px}.view360-controls-volume .view360-range{flex:1;height:100%;padding:0}.view360-controls-volume .view360-range .view360-range-track{width:calc(100% - 12px);transform:translateX(-4px)}.view360-controls-volume .view360-controls-button{margin:0;padding:0;width:24px;height:24px;flex-shrink:0}.view360-controls-volume:disabled{opacity:.5;pointer-events:none}.view360-controls-volume:disabled *{pointer-events:none}.view360-controls-pie{width:36px;height:36px;margin:6px;padding:0;border-radius:18px;opacity:.8;pointer-events:all;cursor:pointer;color:#fff;position:relative;transition:opacity 250ms}.view360-controls-pie>svg{position:absolute;top:0;left:0;width:100%;height:100%}.view360-controls-pie:hover{opacity:1}.view360-range{position:relative;cursor:pointer;pointer-events:all;display:flex;justify-content:center;align-items:center;touch-action:pan-y}.view360-range:hover .view360-range-thumb{opacity:1}.view360-range-track{width:100%;height:4px;border-radius:4px;position:relative;background-color:rgba(230,230,230,.4)}.view360-range-filler,.view360-range-load{position:absolute;left:0;top:0;width:0;height:100%;border-radius:4px}.view360-range-filler{background-color:#fff}.view360-range-load{background-color:#757575}.view360-range-thumb{width:13px;height:13px;position:absolute;top:-5px;left:-6.5px;border-radius:50%;background-color:#fff;box-sizing:border-box;transition:opacity 250ms;opacity:0}.view360-range-thumb.view360-controls-fixed{opacity:1}.view360-controls-unavailable{display:none!important}@media screen and (max-width:768px){.view360-controls-button{background-size:18px 18px;width:30px;height:30px;margin:4.5px;padding:6px;border-radius:15px}.view360-controls-volume .view360-controls-button{width:18px;height:18px}.view360-controls-volume:not(:disabled).view360-controls-fixed,.view360-controls-volume:not(:disabled):hover{width:84px}.view360-controls-pie{width:27px;height:27px;margin:4.5px;padding:0;border-radius:13.5px}} \ No newline at end of file diff --git a/demo/release/4.0.0-beta.4/css/helper.css b/demo/release/4.0.0-beta.4/css/helper.css new file mode 100644 index 000000000..66d55dac0 --- /dev/null +++ b/demo/release/4.0.0-beta.4/css/helper.css @@ -0,0 +1,67 @@ +.view360-container.is-square, .view360-container.is-1by1 { + padding-top: 100%; +} + +.view360-container.is-5by4 { + padding-top: 80%; +} + +.view360-container.is-4by3 { + padding-top: 75%; +} + +.view360-container.is-3by2 { + padding-top: 66.6666%; +} + +.view360-container.is-5by3 { + padding-top: 60%; +} + +.view360-container.is-16by9 { + padding-top: 56.25%; +} + +.view360-container.is-2by1 { + padding-top: 50%; +} + +.view360-container.is-3by1 { + padding-top: 33.3333%; +} + +.view360-container.is-4by5 { + padding-top: 125%; +} + +.view360-container.is-3by4 { + padding-top: 133.3333%; +} + +.view360-container.is-2by3 { + padding-top: 150%; +} + +.view360-container.is-3by5 { + padding-top: 166.6666%; +} + +.view360-container.is-9by16 { + padding-top: 177.7777%; +} + +.view360-container.is-1by2 { + padding-top: 200%; +} + +.view360-container.is-1by3 { + padding-top: 300%; +} + +.view360-container:-ms-fullscreen { + padding-top: 0%; +} + +.view360-container:fullscreen { + padding-top: 0%; +} diff --git a/demo/release/4.0.0-beta.4/css/helper.min.css b/demo/release/4.0.0-beta.4/css/helper.min.css new file mode 100644 index 000000000..4a2ff61eb --- /dev/null +++ b/demo/release/4.0.0-beta.4/css/helper.min.css @@ -0,0 +1 @@ +.view360-container.is-1by1,.view360-container.is-square{padding-top:100%}.view360-container.is-5by4{padding-top:80%}.view360-container.is-4by3{padding-top:75%}.view360-container.is-3by2{padding-top:66.6666%}.view360-container.is-5by3{padding-top:60%}.view360-container.is-16by9{padding-top:56.25%}.view360-container.is-2by1{padding-top:50%}.view360-container.is-3by1{padding-top:33.3333%}.view360-container.is-4by5{padding-top:125%}.view360-container.is-3by4{padding-top:133.3333%}.view360-container.is-2by3{padding-top:150%}.view360-container.is-3by5{padding-top:166.6666%}.view360-container.is-9by16{padding-top:177.7777%}.view360-container.is-1by2{padding-top:200%}.view360-container.is-1by3{padding-top:300%}.view360-container:-ms-fullscreen{padding-top:0}.view360-container:fullscreen{padding-top:0} \ No newline at end of file diff --git a/demo/release/4.0.0-beta.4/css/hotspot.css b/demo/release/4.0.0-beta.4/css/hotspot.css new file mode 100644 index 000000000..d0f07cf1e --- /dev/null +++ b/demo/release/4.0.0-beta.4/css/hotspot.css @@ -0,0 +1,21 @@ +.view360-hotspots { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + pointer-events: none; +} + +.view360-hotspot { + pointer-events: none; + visibility: hidden; + position: absolute; + top: 0; + left: 0; +} + +.view360-hotspot-visible { + visibility: visible; + pointer-events: all; +} diff --git a/demo/release/4.0.0-beta.4/css/hotspot.min.css b/demo/release/4.0.0-beta.4/css/hotspot.min.css new file mode 100644 index 000000000..e6612d921 --- /dev/null +++ b/demo/release/4.0.0-beta.4/css/hotspot.min.css @@ -0,0 +1 @@ +.view360-hotspots{width:100%;height:100%;position:absolute;top:0;left:0;pointer-events:none}.view360-hotspot{pointer-events:none;visibility:hidden;position:absolute;top:0;left:0}.view360-hotspot-visible{visibility:visible;pointer-events:all} \ No newline at end of file diff --git a/demo/release/4.0.0-beta.4/css/loading-spinner.css b/demo/release/4.0.0-beta.4/css/loading-spinner.css new file mode 100644 index 000000000..19bccd3e4 --- /dev/null +++ b/demo/release/4.0.0-beta.4/css/loading-spinner.css @@ -0,0 +1,37 @@ +.view360-spinner { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + background-color: rgba(0, 0, 0, 0.15); +} + +.view360-spinner-ring { + top: 0; + left: 0; + padding: 0; + margin: 0; + width: 64px; + height: 64px; + box-sizing: content-box; + background-color: transparent; + border-style: solid; + border-radius: 50%; + border-width: 10px; + border-color: #fff; + border-bottom-color: transparent; + animation: view360-spin-animation 1.2s linear infinite; +} + +@keyframes view360-spin-animation { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} diff --git a/demo/release/4.0.0-beta.4/css/loading-spinner.min.css b/demo/release/4.0.0-beta.4/css/loading-spinner.min.css new file mode 100644 index 000000000..fe6f71f8d --- /dev/null +++ b/demo/release/4.0.0-beta.4/css/loading-spinner.min.css @@ -0,0 +1 @@ +.view360-spinner{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;justify-content:center;align-items:center;background-color:rgba(0,0,0,.15)}.view360-spinner-ring{top:0;left:0;padding:0;margin:0;width:64px;height:64px;box-sizing:content-box;background-color:transparent;border-style:solid;border-radius:50%;border-width:10px;border-color:#fff;border-bottom-color:transparent;animation:view360-spin-animation 1.2s linear infinite}@keyframes view360-spin-animation{0%{transform:rotate(0)}100%{transform:rotate(360deg)}} \ No newline at end of file diff --git a/demo/release/4.0.0-beta.4/css/variable.css b/demo/release/4.0.0-beta.4/css/variable.css new file mode 100644 index 000000000..e69de29bb diff --git a/demo/release/4.0.0-beta.4/css/variable.min.css b/demo/release/4.0.0-beta.4/css/variable.min.css new file mode 100644 index 000000000..e69de29bb diff --git a/demo/release/4.0.0-beta.4/css/view360.css b/demo/release/4.0.0-beta.4/css/view360.css new file mode 100644 index 000000000..559344b7e --- /dev/null +++ b/demo/release/4.0.0-beta.4/css/view360.css @@ -0,0 +1,511 @@ +.view360-container { + position: relative; + touch-action: pan-y; + overflow: hidden; +} + +.view360-canvas { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + -ms-user-select: none; + user-select: none; + -webkit-user-drag: none; +} + +.view360-canvas.ctx-lost { + text-indent: 0.001px; +} + +.view360-container.is-square, .view360-container.is-1by1 { + padding-top: 100%; +} + +.view360-container.is-5by4 { + padding-top: 80%; +} + +.view360-container.is-4by3 { + padding-top: 75%; +} + +.view360-container.is-3by2 { + padding-top: 66.6666%; +} + +.view360-container.is-5by3 { + padding-top: 60%; +} + +.view360-container.is-16by9 { + padding-top: 56.25%; +} + +.view360-container.is-2by1 { + padding-top: 50%; +} + +.view360-container.is-3by1 { + padding-top: 33.3333%; +} + +.view360-container.is-4by5 { + padding-top: 125%; +} + +.view360-container.is-3by4 { + padding-top: 133.3333%; +} + +.view360-container.is-2by3 { + padding-top: 150%; +} + +.view360-container.is-3by5 { + padding-top: 166.6666%; +} + +.view360-container.is-9by16 { + padding-top: 177.7777%; +} + +.view360-container.is-1by2 { + padding-top: 200%; +} + +.view360-container.is-1by3 { + padding-top: 300%; +} + +.view360-container:-ms-fullscreen { + padding-top: 0%; +} + +.view360-container:fullscreen { + padding-top: 0%; +} + +.view360-controls { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + padding: 0; + margin: 0; + border: 0; + pointer-events: none; + -ms-user-select: none; + user-select: none; + -webkit-user-drag: none; + z-index: 1; +} + +.view360-main.view360-vr-presenting .view360-controls { + display: none; +} + +.view360-controls-float-left, +.view360-controls-float-right { + position: absolute; + display: flex; + flex-direction: column; +} + +.view360-controls-float-left { + left: 0px; + top: 0px; +} + +.view360-controls-float-right { + right: 0px; + top: 0px; +} + +.view360-controls-main { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + opacity: 1; + transition: none; +} + +.view360-controls-main.view360-controls-hidden { + opacity: 0; + transition: opacity 500ms; +} + +.view360-controls-main.view360-controls-hidden * { + pointer-events: none; +} + +.view360-controls-main.view360-controls-fixed { + opacity: 1; +} + +.view360-controls-background { + width: 100%; + height: calc(100% + 32px); + position: absolute; + left: 0; + bottom: 0; + background-image: linear-gradient(0deg, #323232, rgba(50, 50, 50, 0)); +} + +.view360-controls-background.view360-controls-hidden { + display: none; +} + +.view360-controls-mid { + display: flex; + flex-direction: row; + position: relative; +} + +.view360-controls-left { + display: flex; + flex: 1; + justify-content: flex-start; + align-items: center; + flex-direction: row; +} + +.view360-controls-right { + display: flex; + align-items: center; + flex-direction: row; +} + +.view360-controls-bottom { + display: flex; + align-items: center; + flex-direction: row; +} + +.view360-controls-button { + display: inline-block; + background-color: transparent; + cursor: pointer; + border: 0; + position: relative; + background-size: 24px 24px; + background-origin: content-box; + background-repeat: no-repeat; + box-sizing: border-box; + pointer-events: all; + border-radius: 20px; + transition: opacity 250ms; + width: 40px; + height: 40px; + margin: 6px; + padding: 8px; + opacity: 0.8; + /* + * Following background-image svgs are from tabler icons + * https://github.com/tabler/tabler-icons + * + * tabler icons is licensed under the MIT license + * https://github.com/tabler/tabler-icons/blob/master/LICENSE + */ + /* + * Following background-image svgs are from Google Material Icons + * https://fonts.google.com/icons + * + * Material Design Icons is licensed under the Apache License 2.0 + * https://github.com/google/material-design-icons/blob/master/LICENSE + */ +} + +.view360-controls-button:hover { + opacity: 1; +} + +.view360-controls-button.view360-controls-vr { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48' viewBox='0 0 100 100'%3E%3Cg%3E%3Cpath d='M5,30 L95,30 L95,80 L55,80 L50,70 L45,80 L5,80 L5,30' fill='transparent' stroke='%23fff' stroke-width='8' stroke-linejoin='round' stroke-linecap='round'/%3E%3Cpath d='M5,30 L15,10 L85,10 L95,30' fill='transparent' stroke='%23fff' stroke-width='8' stroke-linejoin='round' stroke-linecap='round'/%3E%3Ccircle cx='30' cy='55' r='10' stroke='%23fff' stroke-width='8' fill='transparent' /%3E%3Ccircle cx='70' cy='55' r='10' stroke='%23fff' stroke-width='8' fill='transparent' /%3E%3C/g%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-play { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M7 4v16l13 -8z'%3E%3C/path%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-pause { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Crect x='6' y='5' width='4' height='14' rx='1'%3E%3C/rect%3E%3Crect x='14' y='5' width='4' height='14' rx='1'%3E%3C/rect%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-unmuted { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M15 8a5 5 0 0 1 0 8'%3E%3C/path%3E%3Cpath d='M17.7 5a9 9 0 0 1 0 14'%3E%3C/path%3E%3Cpath d='M6 15h-2a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h2l3.5 -4.5a0.8 .8 0 0 1 1.5 .5v14a0.8 .8 0 0 1 -1.5 .5l-3.5 -4.5'%3E%3C/path%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-muted { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M6 15h-2a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h2l3.5 -4.5a0.8 .8 0 0 1 1.5 .5v14a0.8 .8 0 0 1 -1.5 .5l-3.5 -4.5'%3E%3C/path%3E%3Cpath d='M16 10l4 4m0 -4l-4 4'%3E%3C/path%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-fullscreen { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M4 8v-2a2 2 0 0 1 2 -2h2'%3E%3C/path%3E%3Cpath d='M4 16v2a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v2'%3E%3C/path%3E%3Cpath d='M16 20h2a2 2 0 0 0 2 -2v-2'%3E%3C/path%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-fullscreen-exit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M15 19v-2a2 2 0 0 1 2 -2h2'%3E%3C/path%3E%3Cpath d='M15 5v2a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3Cpath d='M5 15h2a2 2 0 0 1 2 2v2'%3E%3C/path%3E%3Cpath d='M5 9h2a2 2 0 0 0 2 -2v-2'%3E%3C/path%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-gyro-enabled { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48'%3E%3Cpath fill='%23fff' d='M22.5 7.6v2.95q-1 .15-1.975.475-.975.325-1.875.825L16.5 9.7q1.35-.9 2.875-1.4 1.525-.5 3.125-.7Zm15.35 15.35q-.2 1.6-.7 3.125-.5 1.525-1.4 2.875L33.6 26.8q.5-.9.825-1.875.325-.975.475-1.975Zm3.8 20.45L1.3 3.05 3.45.9 43.8 41.25ZM7 41.4q-1.25 0-2.125-.875T4 38.4v-8.6h3v8.6h8.6v3ZM41 13V4.4h-8.6v-3H41q1.25 0 2.125.875T44 4.4V13ZM4 13V4.4q0-.55.2-1.1t.6-1l2.1 2.1V13Zm28.4 28.4v-3h8.5l2.1 2.1q-.4.45-.925.675-.525.225-1.075.225Zm-21.2-37-3-3h7.4v3ZM44 37.2l-3-3v-4.4h3ZM10.15 22.95h2.95q.5 3.7 3.1 6.3 2.6 2.6 6.3 3.1v2.95q-4.9-.55-8.35-4-3.45-3.45-4-8.35Zm4-11.35 2.1 2.05q-1.3 1.3-2.1 2.9-.8 1.6-1.05 3.4h-2.95q.25-2.4 1.275-4.525Q12.45 13.3 14.15 11.6ZM31.8 29.2l2.05 2.1q-1.7 1.7-3.825 2.725Q27.9 35.05 25.5 35.3v-2.95q1.8-.25 3.4-1.05 1.6-.8 2.9-2.1ZM25.5 7.6q4.9.55 8.35 4 3.45 3.45 4 8.35H34.9q-.5-3.7-3.1-6.3-2.6-2.6-6.3-3.1Z'/%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-gyro-disabled { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48'%3E%3Cpath fill='%23fff' d='M7 44q-1.2 0-2.1-.9Q4 42.2 4 41v-8.6h3V41h8.6v3ZM4 15.6V7q0-1.2.9-2.1Q5.8 4 7 4h8.6v3H7v8.6Zm18.5 22.25q-4.9-.55-8.35-4-3.45-3.45-4-8.35h2.95q.5 3.7 3.125 6.3 2.625 2.6 6.275 3.1ZM10.15 22.5q.55-4.9 4-8.35 3.45-3.45 8.35-4v2.95q-3.7.5-6.3 3.1-2.6 2.6-3.1 6.3Zm13.85 5q-1.45 0-2.475-1.025Q20.5 25.45 20.5 24q0-1.45 1.025-2.475Q22.55 20.5 24 20.5q1.45 0 2.475 1.025Q27.5 22.55 27.5 24q0 1.45-1.025 2.475Q25.45 27.5 24 27.5Zm1.5 10.35V34.9q3.7-.5 6.3-3.125 2.6-2.625 3.1-6.275h2.95q-.55 4.9-4 8.35-3.45 3.45-8.35 4Zm9.4-15.35q-.5-3.7-3.1-6.3-2.6-2.6-6.3-3.1v-2.95q4.9.55 8.35 4 3.45 3.45 4 8.35ZM32.4 44v-3H41v-8.6h3V41q0 1.2-.9 2.1-.9.9-2.1.9ZM41 15.6V7h-8.6V4H41q1.2 0 2.1.9.9.9.9 2.1v8.6Z'/%3E%3C/svg%3E"); +} + +.view360-controls-time { + display: inline-block; + vertical-align: top; + white-space: nowrap; + color: white; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-weight: normal; + font-size: 14px; + z-index: 1; +} + +.view360-controls-time:first-child { + padding: 0 16px; +} + +.view360-controls-progress { + flex: 1; + width: 100%; + padding: 0 16px; + box-sizing: border-box; +} + +.view360-controls-progress:not(:first-child) { + padding-left: 0; +} + +.view360-controls-bottom .view360-controls-progress { + padding-bottom: 20px; +} + +.view360-controls-volume { + display: inline-flex; + flex-direction: row; + align-items: center; + transition: width 250ms, background-color 250ms; + overflow: hidden; +} + +.view360-controls-volume:not(:disabled):hover, .view360-controls-volume:not(:disabled).view360-controls-fixed { + width: 112px; +} + +.view360-controls-volume .view360-range { + flex: 1; + height: 100%; + padding: 0; +} + +.view360-controls-volume .view360-range .view360-range-track { + width: calc(100% - 12px); + transform: translateX(-4px); +} + +.view360-controls-volume .view360-controls-button { + margin: 0; + padding: 0; + width: 24px; + height: 24px; + flex-shrink: 0; +} + +.view360-controls-volume:disabled { + opacity: 0.5; + pointer-events: none; +} + +.view360-controls-volume:disabled * { + pointer-events: none; +} + +.view360-controls-pie { + width: 36px; + height: 36px; + margin: 6px; + padding: 0; + border-radius: 18px; + opacity: 0.8; + pointer-events: all; + cursor: pointer; + color: #fff; + position: relative; + transition: opacity 250ms; +} + +.view360-controls-pie > svg { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.view360-controls-pie:hover { + opacity: 1; +} + +.view360-range { + position: relative; + cursor: pointer; + pointer-events: all; + display: flex; + justify-content: center; + align-items: center; + touch-action: pan-y; +} + +.view360-range:hover .view360-range-thumb { + opacity: 1; +} + +.view360-range-track { + width: 100%; + height: 4px; + border-radius: 4px; + position: relative; + background-color: rgba(230, 230, 230, 0.4); +} + +.view360-range-filler, +.view360-range-load { + position: absolute; + left: 0; + top: 0; + width: 0; + height: 100%; + border-radius: 4px; +} + +.view360-range-filler { + background-color: #fff; +} + +.view360-range-load { + background-color: #757575; +} + +.view360-range-thumb { + width: 13px; + height: 13px; + position: absolute; + top: -5px; + left: -6.5px; + border-radius: 50%; + background-color: #fff; + box-sizing: border-box; + transition: opacity 250ms; + opacity: 0; +} + +.view360-range-thumb.view360-controls-fixed { + opacity: 1; +} + +.view360-controls-unavailable { + display: none !important; +} + +@media screen and (max-width: 768px) { + .view360-controls-button { + background-size: 18px 18px; + width: 30px; + height: 30px; + margin: 4.5px; + padding: 6px; + border-radius: 15px; + } + .view360-controls-volume .view360-controls-button { + width: 18px; + height: 18px; + } + .view360-controls-volume:not(:disabled):hover, .view360-controls-volume:not(:disabled).view360-controls-fixed { + width: 84px; + } + .view360-controls-pie { + width: 27px; + height: 27px; + margin: 4.5px; + padding: 0; + border-radius: 13.5px; + } +} + +.view360-spinner { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + background-color: rgba(0, 0, 0, 0.15); +} + +.view360-spinner-ring { + top: 0; + left: 0; + padding: 0; + margin: 0; + width: 64px; + height: 64px; + box-sizing: content-box; + background-color: transparent; + border-style: solid; + border-radius: 50%; + border-width: 10px; + border-color: #fff; + border-bottom-color: transparent; + animation: view360-spin-animation 1.2s linear infinite; +} + +@keyframes view360-spin-animation { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} + +.view360-container.view360-vr-presenting { + width: 100vw; + height: 100vh; + position: fixed; + left: 0; + top: 0; + z-index: 9999; +} + +.view360-hotspots { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + pointer-events: none; +} + +.view360-hotspot { + pointer-events: none; + visibility: hidden; + position: absolute; + top: 0; + left: 0; +} + +.view360-hotspot-visible { + visibility: visible; + pointer-events: all; +} diff --git a/demo/release/4.0.0-beta.4/css/view360.min.css b/demo/release/4.0.0-beta.4/css/view360.min.css new file mode 100644 index 000000000..0f3bb2112 --- /dev/null +++ b/demo/release/4.0.0-beta.4/css/view360.min.css @@ -0,0 +1 @@ +.view360-container{position:relative;touch-action:pan-y;overflow:hidden}.view360-canvas{position:absolute;left:0;top:0;width:100%;height:100%;-ms-user-select:none;user-select:none;-webkit-user-drag:none}.view360-canvas.ctx-lost{text-indent:.001px}.view360-container.is-1by1,.view360-container.is-square{padding-top:100%}.view360-container.is-5by4{padding-top:80%}.view360-container.is-4by3{padding-top:75%}.view360-container.is-3by2{padding-top:66.6666%}.view360-container.is-5by3{padding-top:60%}.view360-container.is-16by9{padding-top:56.25%}.view360-container.is-2by1{padding-top:50%}.view360-container.is-3by1{padding-top:33.3333%}.view360-container.is-4by5{padding-top:125%}.view360-container.is-3by4{padding-top:133.3333%}.view360-container.is-2by3{padding-top:150%}.view360-container.is-3by5{padding-top:166.6666%}.view360-container.is-9by16{padding-top:177.7777%}.view360-container.is-1by2{padding-top:200%}.view360-container.is-1by3{padding-top:300%}.view360-container:-ms-fullscreen{padding-top:0}.view360-container:fullscreen{padding-top:0}.view360-controls{position:absolute;top:0;left:0;width:100%;height:100%;padding:0;margin:0;border:0;pointer-events:none;-ms-user-select:none;user-select:none;-webkit-user-drag:none;z-index:1}.view360-main.view360-vr-presenting .view360-controls{display:none}.view360-controls-float-left,.view360-controls-float-right{position:absolute;display:flex;flex-direction:column}.view360-controls-float-left{left:0;top:0}.view360-controls-float-right{right:0;top:0}.view360-controls-main{position:absolute;bottom:0;left:0;width:100%;opacity:1;transition:none}.view360-controls-main.view360-controls-hidden{opacity:0;transition:opacity .5s}.view360-controls-main.view360-controls-hidden *{pointer-events:none}.view360-controls-main.view360-controls-fixed{opacity:1}.view360-controls-background{width:100%;height:calc(100% + 32px);position:absolute;left:0;bottom:0;background-image:linear-gradient(0deg,#323232,rgba(50,50,50,0))}.view360-controls-background.view360-controls-hidden{display:none}.view360-controls-mid{display:flex;flex-direction:row;position:relative}.view360-controls-left{display:flex;flex:1;justify-content:flex-start;align-items:center;flex-direction:row}.view360-controls-right{display:flex;align-items:center;flex-direction:row}.view360-controls-bottom{display:flex;align-items:center;flex-direction:row}.view360-controls-button{display:inline-block;background-color:transparent;cursor:pointer;border:0;position:relative;background-size:24px 24px;background-origin:content-box;background-repeat:no-repeat;box-sizing:border-box;pointer-events:all;border-radius:20px;transition:opacity 250ms;width:40px;height:40px;margin:6px;padding:8px;opacity:.8}.view360-controls-button:hover{opacity:1}.view360-controls-button.view360-controls-vr{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48' viewBox='0 0 100 100'%3E%3Cg%3E%3Cpath d='M5,30 L95,30 L95,80 L55,80 L50,70 L45,80 L5,80 L5,30' fill='transparent' stroke='%23fff' stroke-width='8' stroke-linejoin='round' stroke-linecap='round'/%3E%3Cpath d='M5,30 L15,10 L85,10 L95,30' fill='transparent' stroke='%23fff' stroke-width='8' stroke-linejoin='round' stroke-linecap='round'/%3E%3Ccircle cx='30' cy='55' r='10' stroke='%23fff' stroke-width='8' fill='transparent' /%3E%3Ccircle cx='70' cy='55' r='10' stroke='%23fff' stroke-width='8' fill='transparent' /%3E%3C/g%3E%3C/svg%3E")}.view360-controls-button.view360-controls-play{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M7 4v16l13 -8z'%3E%3C/path%3E%3C/svg%3E")}.view360-controls-button.view360-controls-pause{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Crect x='6' y='5' width='4' height='14' rx='1'%3E%3C/rect%3E%3Crect x='14' y='5' width='4' height='14' rx='1'%3E%3C/rect%3E%3C/svg%3E")}.view360-controls-button.view360-controls-unmuted{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M15 8a5 5 0 0 1 0 8'%3E%3C/path%3E%3Cpath d='M17.7 5a9 9 0 0 1 0 14'%3E%3C/path%3E%3Cpath d='M6 15h-2a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h2l3.5 -4.5a0.8 .8 0 0 1 1.5 .5v14a0.8 .8 0 0 1 -1.5 .5l-3.5 -4.5'%3E%3C/path%3E%3C/svg%3E")}.view360-controls-button.view360-controls-muted{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M6 15h-2a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h2l3.5 -4.5a0.8 .8 0 0 1 1.5 .5v14a0.8 .8 0 0 1 -1.5 .5l-3.5 -4.5'%3E%3C/path%3E%3Cpath d='M16 10l4 4m0 -4l-4 4'%3E%3C/path%3E%3C/svg%3E")}.view360-controls-button.view360-controls-fullscreen{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M4 8v-2a2 2 0 0 1 2 -2h2'%3E%3C/path%3E%3Cpath d='M4 16v2a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v2'%3E%3C/path%3E%3Cpath d='M16 20h2a2 2 0 0 0 2 -2v-2'%3E%3C/path%3E%3C/svg%3E")}.view360-controls-button.view360-controls-fullscreen-exit{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M15 19v-2a2 2 0 0 1 2 -2h2'%3E%3C/path%3E%3Cpath d='M15 5v2a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3Cpath d='M5 15h2a2 2 0 0 1 2 2v2'%3E%3C/path%3E%3Cpath d='M5 9h2a2 2 0 0 0 2 -2v-2'%3E%3C/path%3E%3C/svg%3E")}.view360-controls-button.view360-controls-gyro-enabled{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48'%3E%3Cpath fill='%23fff' d='M22.5 7.6v2.95q-1 .15-1.975.475-.975.325-1.875.825L16.5 9.7q1.35-.9 2.875-1.4 1.525-.5 3.125-.7Zm15.35 15.35q-.2 1.6-.7 3.125-.5 1.525-1.4 2.875L33.6 26.8q.5-.9.825-1.875.325-.975.475-1.975Zm3.8 20.45L1.3 3.05 3.45.9 43.8 41.25ZM7 41.4q-1.25 0-2.125-.875T4 38.4v-8.6h3v8.6h8.6v3ZM41 13V4.4h-8.6v-3H41q1.25 0 2.125.875T44 4.4V13ZM4 13V4.4q0-.55.2-1.1t.6-1l2.1 2.1V13Zm28.4 28.4v-3h8.5l2.1 2.1q-.4.45-.925.675-.525.225-1.075.225Zm-21.2-37-3-3h7.4v3ZM44 37.2l-3-3v-4.4h3ZM10.15 22.95h2.95q.5 3.7 3.1 6.3 2.6 2.6 6.3 3.1v2.95q-4.9-.55-8.35-4-3.45-3.45-4-8.35Zm4-11.35 2.1 2.05q-1.3 1.3-2.1 2.9-.8 1.6-1.05 3.4h-2.95q.25-2.4 1.275-4.525Q12.45 13.3 14.15 11.6ZM31.8 29.2l2.05 2.1q-1.7 1.7-3.825 2.725Q27.9 35.05 25.5 35.3v-2.95q1.8-.25 3.4-1.05 1.6-.8 2.9-2.1ZM25.5 7.6q4.9.55 8.35 4 3.45 3.45 4 8.35H34.9q-.5-3.7-3.1-6.3-2.6-2.6-6.3-3.1Z'/%3E%3C/svg%3E")}.view360-controls-button.view360-controls-gyro-disabled{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48'%3E%3Cpath fill='%23fff' d='M7 44q-1.2 0-2.1-.9Q4 42.2 4 41v-8.6h3V41h8.6v3ZM4 15.6V7q0-1.2.9-2.1Q5.8 4 7 4h8.6v3H7v8.6Zm18.5 22.25q-4.9-.55-8.35-4-3.45-3.45-4-8.35h2.95q.5 3.7 3.125 6.3 2.625 2.6 6.275 3.1ZM10.15 22.5q.55-4.9 4-8.35 3.45-3.45 8.35-4v2.95q-3.7.5-6.3 3.1-2.6 2.6-3.1 6.3Zm13.85 5q-1.45 0-2.475-1.025Q20.5 25.45 20.5 24q0-1.45 1.025-2.475Q22.55 20.5 24 20.5q1.45 0 2.475 1.025Q27.5 22.55 27.5 24q0 1.45-1.025 2.475Q25.45 27.5 24 27.5Zm1.5 10.35V34.9q3.7-.5 6.3-3.125 2.6-2.625 3.1-6.275h2.95q-.55 4.9-4 8.35-3.45 3.45-8.35 4Zm9.4-15.35q-.5-3.7-3.1-6.3-2.6-2.6-6.3-3.1v-2.95q4.9.55 8.35 4 3.45 3.45 4 8.35ZM32.4 44v-3H41v-8.6h3V41q0 1.2-.9 2.1-.9.9-2.1.9ZM41 15.6V7h-8.6V4H41q1.2 0 2.1.9.9.9.9 2.1v8.6Z'/%3E%3C/svg%3E")}.view360-controls-time{display:inline-block;vertical-align:top;white-space:nowrap;color:#fff;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-weight:400;font-size:14px;z-index:1}.view360-controls-time:first-child{padding:0 16px}.view360-controls-progress{flex:1;width:100%;padding:0 16px;box-sizing:border-box}.view360-controls-progress:not(:first-child){padding-left:0}.view360-controls-bottom .view360-controls-progress{padding-bottom:20px}.view360-controls-volume{display:inline-flex;flex-direction:row;align-items:center;transition:width 250ms,background-color 250ms;overflow:hidden}.view360-controls-volume:not(:disabled).view360-controls-fixed,.view360-controls-volume:not(:disabled):hover{width:112px}.view360-controls-volume .view360-range{flex:1;height:100%;padding:0}.view360-controls-volume .view360-range .view360-range-track{width:calc(100% - 12px);transform:translateX(-4px)}.view360-controls-volume .view360-controls-button{margin:0;padding:0;width:24px;height:24px;flex-shrink:0}.view360-controls-volume:disabled{opacity:.5;pointer-events:none}.view360-controls-volume:disabled *{pointer-events:none}.view360-controls-pie{width:36px;height:36px;margin:6px;padding:0;border-radius:18px;opacity:.8;pointer-events:all;cursor:pointer;color:#fff;position:relative;transition:opacity 250ms}.view360-controls-pie>svg{position:absolute;top:0;left:0;width:100%;height:100%}.view360-controls-pie:hover{opacity:1}.view360-range{position:relative;cursor:pointer;pointer-events:all;display:flex;justify-content:center;align-items:center;touch-action:pan-y}.view360-range:hover .view360-range-thumb{opacity:1}.view360-range-track{width:100%;height:4px;border-radius:4px;position:relative;background-color:rgba(230,230,230,.4)}.view360-range-filler,.view360-range-load{position:absolute;left:0;top:0;width:0;height:100%;border-radius:4px}.view360-range-filler{background-color:#fff}.view360-range-load{background-color:#757575}.view360-range-thumb{width:13px;height:13px;position:absolute;top:-5px;left:-6.5px;border-radius:50%;background-color:#fff;box-sizing:border-box;transition:opacity 250ms;opacity:0}.view360-range-thumb.view360-controls-fixed{opacity:1}.view360-controls-unavailable{display:none!important}@media screen and (max-width:768px){.view360-controls-button{background-size:18px 18px;width:30px;height:30px;margin:4.5px;padding:6px;border-radius:15px}.view360-controls-volume .view360-controls-button{width:18px;height:18px}.view360-controls-volume:not(:disabled).view360-controls-fixed,.view360-controls-volume:not(:disabled):hover{width:84px}.view360-controls-pie{width:27px;height:27px;margin:4.5px;padding:0;border-radius:13.5px}}.view360-spinner{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;justify-content:center;align-items:center;background-color:rgba(0,0,0,.15)}.view360-spinner-ring{top:0;left:0;padding:0;margin:0;width:64px;height:64px;box-sizing:content-box;background-color:transparent;border-style:solid;border-radius:50%;border-width:10px;border-color:#fff;border-bottom-color:transparent;animation:view360-spin-animation 1.2s linear infinite}@keyframes view360-spin-animation{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.view360-container.view360-vr-presenting{width:100vw;height:100vh;position:fixed;left:0;top:0;z-index:9999}.view360-hotspots{width:100%;height:100%;position:absolute;top:0;left:0;pointer-events:none}.view360-hotspot{pointer-events:none;visibility:hidden;position:absolute;top:0;left:0}.view360-hotspot-visible{visibility:visible;pointer-events:all} \ No newline at end of file diff --git a/demo/release/4.0.0-beta.4/css/vr.css b/demo/release/4.0.0-beta.4/css/vr.css new file mode 100644 index 000000000..dd06d3eeb --- /dev/null +++ b/demo/release/4.0.0-beta.4/css/vr.css @@ -0,0 +1,8 @@ +.view360-container.view360-vr-presenting { + width: 100vw; + height: 100vh; + position: fixed; + left: 0; + top: 0; + z-index: 9999; +} diff --git a/demo/release/4.0.0-beta.4/css/vr.min.css b/demo/release/4.0.0-beta.4/css/vr.min.css new file mode 100644 index 000000000..a5d6c06b9 --- /dev/null +++ b/demo/release/4.0.0-beta.4/css/vr.min.css @@ -0,0 +1 @@ +.view360-container.view360-vr-presenting{width:100vw;height:100vh;position:fixed;left:0;top:0;z-index:9999} \ No newline at end of file diff --git a/demo/release/4.0.0-beta.4/dist/view360.esm.js b/demo/release/4.0.0-beta.4/dist/view360.esm.js new file mode 100644 index 000000000..8c80a5553 --- /dev/null +++ b/demo/release/4.0.0-beta.4/dist/view360.esm.js @@ -0,0 +1,7752 @@ +/* +Copyright (c) 2023-present NAVER Corp. +name: @egjs/view360 +license: MIT +author: NAVER Corp. +repository: https://github.com/naver/egjs-view360 +version: 4.0.0-beta.4 +*/ +import Component from '@egjs/component'; +import { quat, vec3, mat4, vec2 } from 'gl-matrix'; +import ImReady from '@egjs/imready'; + +/****************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function (resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Error thrown by {@link View360} + * @ko {@link View360}이 발생시킨 에러 + * @since 4.0.0 + */ +class View360Error extends Error { + /** + * Create new instance of View360Error + * @ko View360Error의 인스턴스를 생성합니다. + * @param message - Error message {@ko 에러 메시지} + * @param code - Error code {@ko 에러 코드} + */ + constructor(message, code) { + super(message); + Object.setPrototypeOf(this, View360Error.prototype); + this.name = "View360Error"; + this.code = code; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Error codes of {@link View360Error} + * @ko {@link View360Error}가 가질 수 있는 에러 코드 값들 + * @since 4.0.0 + */ +const ERROR_CODES = { + /** + * The given value's type is not expected + * @ko 주어진 값의 타입이 잘못되었을 경우 + * @since 4.0.0 + */ + WRONG_TYPE: 0, + /** + * The given value is not a supported option + * @ko 잘못된 옵션을 받았을 경우 + * @since 4.0.0 + */ + WRONG_OPTION: 1, + /** + * The element with given CSS selector does not exist + * @ko 주어진 CSS 셀렉터로 엘리먼트를 찾지 못했을 경우 + * @since 4.0.0 + */ + ELEMENT_NOT_FOUND: 2, + /** + * Couldn't find canvas element inside the given container element. + * @ko 컨테이너 엘리먼트 내부에서 캔버스 엘리먼트를 찾지 못했을 경우 + * @since 4.0.0 + */ + CANVAS_NOT_FOUND: 3, + /** + * The browser does not support WebGL + * @ko 브라우저가 WebGL을 지원하지 않는 경우 + * @since 4.0.0 + */ + WEBGL_NOT_SUPPORTED: 4, + /** + * Failed creating canvas 2D context + * @ko 캔버스 2D 컨텍스트를 생성하지 못한 경우 + * @since 4.0.0 + */ + FAILED_CREATE_CONTEXT_2D: 5, + /** + * `init()` is called before setting {@link View360Options#projection} + * @ko {@link View360Options#projection}을 설정하기 전에 `init()`이 호출된 경우 + * @since 4.0.0 + */ + PROVIDE_PROJECTION_FIRST: 6, + /** + * Failed linking WebGL program. Only can be thrown when {@link View360Options#debug} is `true`. + * @ko WebGL 프로그램 링크에 실패한 경우. {@link View360Options#debug}를 `true`로 설정한 경우에만 발생할 수 있습니다. + * @since 4.0.0 + */ + FAILED_LINKING_PROGRAM: 7, + /** + * Arguments are not sufficient for the given property. + * @ko 프로퍼티에 값이 충분히 주어지지 않았을 때 + * @since 4.0.0 + */ + INSUFFICIENT_ARGS: 8 +}; +const MESSAGES = { + WRONG_TYPE: (val, types) => `${typeof val} is not a ${types.map(type => `"${type}"`).join(" or ")}.`, + WRONG_OPTION: (val, optionName) => `Bad option: given "${val}" for option "${optionName}".`, + ELEMENT_NOT_FOUND: query => `Element with selector "${query}" not found.`, + CANVAS_NOT_FOUND: "The canvas element was not found inside the given root element.", + WEBGL_NOT_SUPPORTED: "WebGL is not supported on this browser.", + FAILED_CREATE_CONTEXT_2D: "Failed to create canvas 2D context", + PROVIDE_PROJECTION_FIRST: "\"projection\" should be provided before initialization.", + FAILED_LINKING_PROGRAM: (msg, shaderLog) => `Failed linking WebGL program - "${msg}\nShader compile Log: ${shaderLog}`, + INSUFFICIENT_ARGS: (val, name) => `Insufficient arguments: given "${val}" for "${name}".` +}; +var ERROR = { + CODES: ERROR_CODES, + MESSAGES +}; + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +const EVENTS$1 = { + MOUSE_DOWN: "mousedown", + MOUSE_MOVE: "mousemove", + MOUSE_UP: "mouseup", + TOUCH_START: "touchstart", + TOUCH_MOVE: "touchmove", + TOUCH_END: "touchend", + WHEEL: "wheel", + RESIZE: "resize", + CONTEXT_MENU: "contextmenu", + MOUSE_ENTER: "mouseenter", + MOUSE_LEAVE: "mouseleave", + POINTER_DOWN: "pointerdown", + POINTER_MOVE: "pointermove", + POINTER_UP: "pointerup", + POINTER_CANCEL: "pointercancel", + POINTER_ENTER: "pointerenter", + POINTER_LEAVE: "pointerleave", + KEY_DOWN: "keydown", + KEY_UP: "keyup", + LOAD: "load", + ERROR: "error", + CLICK: "click", + DOUBLE_CLICK: "dblclick", + CONTEXT_CREATE_ERROR: "webglcontextcreationerror", + CONTEXT_LOST: "webglcontextlost", + CONTEXT_RESTORED: "webglcontextrestored", + DEVICE_ORIENTATION: "deviceorientation", + DEVICE_MOTION: "devicemotion", + ORIENTATION_CHANGE: "orientationchange", + VIDEO_PLAY: "play", + VIDEO_PAUSE: "pause", + VIDEO_LOADED_DATA: "loadeddata", + VIDEO_VOLUME_CHANGE: "volumechange", + VIDEO_TIME_UPDATE: "timeupdate", + VIDEO_DURATION_CHANGE: "durationchange", + VIDEO_CAN_PLAYTHROUGH: "canplaythrough", + TRANSITION_END: "transitionend", + XR_END: "end" +}; +const EL_DIV = "div"; +const EL_BUTTON = "button"; +// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button +var MOUSE_BUTTON; +(function (MOUSE_BUTTON) { + MOUSE_BUTTON[MOUSE_BUTTON["LEFT"] = 0] = "LEFT"; + MOUSE_BUTTON[MOUSE_BUTTON["MIDDLE"] = 1] = "MIDDLE"; + MOUSE_BUTTON[MOUSE_BUTTON["RIGHT"] = 2] = "RIGHT"; +})(MOUSE_BUTTON || (MOUSE_BUTTON = {})); +const CURSOR = { + GRAB: "grab", + GRABBING: "grabbing", + NONE: "" +}; +const KEY_DIRECTION = ["LEFT", "UP", "RIGHT", "DOWN"]; +var DIRECTION_KEY_CODE; +(function (DIRECTION_KEY_CODE) { + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["LEFT"] = 37] = "LEFT"; + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["UP"] = 38] = "UP"; + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["RIGHT"] = 39] = "RIGHT"; + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["DOWN"] = 40] = "DOWN"; +})(DIRECTION_KEY_CODE || (DIRECTION_KEY_CODE = {})); +const SPACE_KEY_CODE = 32; +const DIRECTION_KEY_NAME = { + LEFT: "ArrowLeft", + UP: "ArrowUp", + RIGHT: "ArrowRight", + DOWN: "ArrowDown" +}; +const SPACE_KEY_NAME = " "; +const FULLSCREEN_REQUEST = ["requestFullscreen", "webkitRequestFullscreen", "webkitRequestFullScreen", "webkitCancelFullScreen", "mozRequestFullScreen", "msRequestFullscreen"]; +const FULLSCREEN_ELEMENT = ["fullscreenElement", "webkitFullscreenElement", "webkitCurrentFullScreenElement", "mozFullScreenElement", "msFullscreenElement"]; +const FULLSCREEN_EXIT = ["exitFullscreen", "webkitExitFullscreen", "webkitCancelFullScreen", "mozCancelFullScreen", "msExitFullscreen"]; +const FULLSCREEN_CHANGE = ["fullscreenchange", "webkitfullscreenchange", "mozfullscreenchange", "MSFullscreenChange"]; + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Default class names + * @ko 기본 클래스 이름들 + * @since 4.0.0 + */ +const DEFAULT_CLASS = { + CONTAINER: "view360-container", + CANVAS: "view360-canvas", + CTX_LOST: "view360-ctx-lost", + IN_VR: "view360-vr-presenting", + HOTSPOT_CONTAINER: "view360-hotspots", + HOTSPOT: "view360-hotspot", + HOTSPOT_VISIBLE: "view360-hotspot-visible", + HOTSPOT_FLIP_X: "view360-hotspot-flip-x", + HOTSPOT_FLIP_Y: "view360-hotspot-flip-y" +}; +/** + * Event names + * @ko 이벤트 이름들 + * @since 4.0.0 + * @example + * ```ts + * import View360, { EVENTS } from "@egjs/view360"; + * + * const viewer = new View360("#el_id"); + * + * viewer.on(EVENTS.READY, evt => { + * console.log("View360 is ready!"); + * }); + * ``` + */ +const EVENTS = { + READY: "ready", + LOAD_START: "loadStart", + LOAD: "load", + PROJECTION_CHANGE: "projectionChange", + RESIZE: "resize", + BEFORE_RENDER: "beforeRender", + RENDER: "render", + INPUT_START: "inputStart", + INPUT_END: "inputEnd", + VIEW_CHANGE: "viewChange", + STATIC_CLICK: "staticClick", + VR_START: "vrStart", + VR_END: "vrEnd" +}; +/** + * Collection of predefined easing functions + * @ko 미리 정의된 easing 함수들 + */ +const EASING = { + LINEAR: x => x, + SINE_WAVE: x => Math.sin(x * Math.PI * 2), + EASE_OUT_CUBIC: x => 1 - Math.pow(1 - x, 3), + EASE_OUT_BOUNCE: x => { + const n1 = 7.5625; + const d1 = 2.75; + if (x < 1 / d1) { + return n1 * x * x; + } else if (x < 2 / d1) { + return n1 * (x -= 1.5 / d1) * x + 0.75; + } else if (x < 2.5 / d1) { + return n1 * (x -= 2.25 / d1) * x + 0.9375; + } else { + return n1 * (x -= 2.625 / d1) * x + 0.984375; + } + } +}; + +var _a; +const CAMERA_EVENTS = { + CHANGE: "change", + ANIMATION_END: "animationEnd" +}; +const CONTROL_EVENTS = { + INPUT_START: "inputStart", + CHANGE: "change", + INPUT_END: "inputEnd", + ENABLE: "enable", + DISABLE: "disable", + STATIC_CLICK: "staticClick" +}; +const DEG_TO_RAD = Math.PI / 180; +const RAD_TO_DEG = 180 / Math.PI; +const DEFAULT_EASING = EASING.EASE_OUT_CUBIC; +const DEFAULT_ANIMATION_DURATION = 300; +const INFINITE_RANGE = { + min: -Infinity, + max: Infinity +}; +const DEFAULT_PITCH_RANGE = { + min: -90, + max: 90 +}; +const DEFAULT_ZOOM_RANGE = { + min: 0.6, + max: 10 +}; +var ROTATE; +(function (ROTATE) { + ROTATE[ROTATE["ZERO"] = 0] = "ZERO"; + ROTATE[ROTATE["CW_90"] = 1] = "CW_90"; + ROTATE[ROTATE["CCW_90"] = 2] = "CCW_90"; + ROTATE[ROTATE["CW_180"] = 3] = "CW_180"; +})(ROTATE || (ROTATE = {})); +// Custom event name for video time change +const VIDEO_TIME_CHANGE_EVENT = "view360videotimechange"; +const SVG_NAMESPACE = "http://www.w3.org/2000/svg"; +const SESSION_VR = "immersive-vr"; +const XR_REFERENCE_SPACE = "local"; +const EPSILON = (_a = Number.EPSILON) !== null && _a !== void 0 ? _a : 2.220446049250313e-16; + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +const isString = val => typeof val === "string"; +const isElement = val => !!val && val.nodeType === Node.ELEMENT_NODE; +const createElement = (className, tag = EL_DIV) => { + const el = document.createElement(tag); + el.classList.add(className); + return el; +}; +const getNullableElement = (el, parent) => { + let targetEl = null; + if (isString(el)) { + const parentEl = parent ? parent : document; + const queryResult = parentEl.querySelector(el); + if (!queryResult) { + return null; + } + targetEl = queryResult; + } else if (isElement(el)) { + targetEl = el; + } + return targetEl; +}; +const getElement = (el, parent) => { + const targetEl = getNullableElement(el, parent); + if (!targetEl) { + if (isString(el)) { + throw new View360Error(ERROR.MESSAGES.ELEMENT_NOT_FOUND(el), ERROR.CODES.ELEMENT_NOT_FOUND); + } else { + throw new View360Error(ERROR.MESSAGES.WRONG_TYPE(el, ["HTMLElement", "string"]), ERROR.CODES.WRONG_TYPE); + } + } + return targetEl; +}; +const findCanvas = (root, selector) => { + const canvas = root.querySelector(selector); + if (!canvas) { + throw new View360Error(ERROR.MESSAGES.CANVAS_NOT_FOUND, ERROR.CODES.CANVAS_NOT_FOUND); + } + return canvas; +}; +const range = end => { + if (!end || end <= 0) { + return []; + } + return Array.apply(0, Array(end)).map((undef, idx) => idx); +}; +const clamp = (x, min, max) => Math.max(Math.min(x, max), min); +// Linear interpolation between a and b +const lerp = (a, b, t) => { + return a * (1 - t) + b * t; +}; +const circulate = (val, min, max) => { + const size = Math.abs(max - min); + if (val < min) { + const offset = (min - val) % size; + val = max - offset; + } else if (val > max) { + const offset = (val - max) % size; + val = min + offset; + } + return val; +}; +const findIndex = (array, checker) => { + for (let idx = 0; idx < array.length; idx++) { + if (checker(array[idx])) { + return idx; + } + } + return -1; +}; +const getObjectOption = val => typeof val === "object" ? val : {}; +const toVerticalFov = (fovRadian, aspect) => { + return Math.atan(Math.tan(fovRadian * 0.5) / aspect) * 2; +}; +const reorderCube = (arr, order, defaultOrder = "RLUDFB") => { + return defaultOrder.split("").map(face => order.indexOf(face)).map(index => arr[index]); +}; +const isFullscreen = () => { + if (!document) return false; + for (const key of FULLSCREEN_ELEMENT) { + if (document[key]) return true; + } + return false; +}; +const sensorCanBeEnabledIOS = () => { + return !!DeviceMotionEvent && "requestPermission" in DeviceMotionEvent && window.isSecureContext; +}; +const hfovToZoom = (baseFov, fov) => { + const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5); + const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5); + return renderingWidth / zoomedWidth; +}; +const eulerToQuat = (out, yaw, pitch, roll) => { + quat.identity(out); + const pitchThreshold = 0.01; + const pitchClamped = clamp(pitch, -90 + pitchThreshold, 90 - pitchThreshold); + quat.rotateY(out, out, yaw * DEG_TO_RAD); + quat.rotateX(out, out, pitchClamped * DEG_TO_RAD); + quat.rotateZ(out, out, roll * DEG_TO_RAD); + return out; +}; +/** + * Extract euler angles from the quaternion, except roll(z-axis rotation) + * @hidden + */ +const quatToEuler = quaternion => { + const x = quaternion[0]; + const y = quaternion[1]; + const z = quaternion[2]; + const w = quaternion[3]; + const x2 = x * x; + const y2 = y * y; + const z2 = z * z; + const w2 = w * w; + const unit = x2 + y2 + z2 + w2; + const test = x * w - y * z; + let pitch, yaw; + if (test > 0.499995 * unit) { + // singularity at the north pole + pitch = Math.PI / 2; + yaw = 2 * Math.atan2(y, x); + } else if (test < -0.499995 * unit) { + // singularity at the south pole + pitch = -Math.PI / 2; + yaw = -2 * Math.atan2(y, x); + } else { + const view = vec3.fromValues(0, 0, 1); + const up = vec3.fromValues(0, 1, 0); + vec3.transformQuat(view, view, quaternion); + vec3.transformQuat(up, up, quaternion); + const viewXZ = Math.sqrt(view[0] * view[0] + view[2] * view[2]); + pitch = Math.atan2(-view[1], viewXZ); + yaw = Math.atan2(view[0], view[2]); + } + return { + pitch: clamp(pitch * RAD_TO_DEG, -90, 90), + yaw: circulate(yaw * RAD_TO_DEG, 0, 360) + }; +}; + +/* + * Copyright (c) 2020 NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Interpolator between two values with duration + * @ko 특정 시간동안 두 값을 보간해주는 보간기 + * @since 4.0.0 + */ +class Motion { + /** + * Current interpolated value + * @ko 현재 보간된 값 + * @since 4.0.0 + */ + get val() { + return this._val; + } + /** + * Start(from) value of interpolation + * @ko 보간 시작 값 + * @since 4.0.0 + */ + get start() { + return this._start; + } + /** + * End(to) value of interpolation + * @ko 보간 끝 값 + * @since 4.0.0 + */ + get end() { + return this._end; + } + /** + * Interpolation progress value (0 ~ 1) + * @ko 현재 보간 진행정도 (0 ~ 1) + * @since 4.0.0 + */ + get progress() { + return this._progress; + } + /** + * Whether the interpolation is in active state. + * @ko 보간 진행중인지 여부. `true`일 경우 보간이 진행중입니다. + * @since 4.0.0 + */ + get activated() { + return this._activated; + } + /** + * Duration of the interpolation + * @ko 보간할 시간 + * @since 4.0.0 + */ + get duration() { + return this._duration; + } + set duration(val) { + this._duration = val; + } + /** + * Whether to loop interpolation on finish + * @ko 보간이 끝난 이후에 다시 시작할지 여부 + * @since 4.0.0 + */ + get loop() { + return this._loop; + } + set loop(val) { + this._loop = val; + } + /** + * Range of the interpolation + * @ko 보간 범위 + * @since 4.0.0 + */ + get range() { + return this._range; + } + /** + * Easing function of the interpolation + * @ko 보간에 사용되는 easing function + * @since 4.0.0 + */ + get easing() { + return this._easing; + } + set easing(val) { + this._easing = val; + } + /** + * Create new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options Options {@ko 옵션들} + * @param options.duration Duration of the interpolation {@ko 보간할 시간} + * @param options.loop Whether to loop interpolation on finish {@ko 보간이 끝난 이후에 다시 시작할지 여부} + * @param options.range Range of the interpolation {@ko 보간 범위} + * @param options.loop Easing function of the interpolation {@ko 보간에 사용되는 easing function} + */ + constructor({ + duration = DEFAULT_ANIMATION_DURATION, + loop = false, + range = { + min: 0, + max: 1 + }, + easing = DEFAULT_EASING + } = {}) { + this._duration = duration; + this._loop = loop; + this._range = range; + this._easing = easing; + this._activated = false; + this.reset(0); + } + /** + * Update motion and progress it by given deltaTime + * @ko 주어진 deltaTime만큼 보간을 진행합니다. + * @param deltaTime - number of milisec to update motion {@ko 보간을 진행할 시간, 밀리초 단위} + * @returns Difference(delta) of the value from the last update. {@ko 지난 업데이트 이후의 값 변화량} + * @since 4.0.0 + */ + update(deltaTime) { + if (!this._activated) { + this._val = this._end; + return 0; + } + const start = this._start; + const end = this._end; + const duration = this._duration; + const prev = this._val; + const loop = this._loop; + const nextProgress = this._progress + deltaTime / duration; + this._progress = loop ? circulate(nextProgress, 0, 1) : clamp(nextProgress, 0, 1); + const easedProgress = this._easing(this._progress); + this._val = lerp(start, end, easedProgress); + if (!loop && this._progress >= 1) { + this._activated = false; + } + return this._val - prev; + } + /** + * Set `start`, `end` to the given value and set `progress` to 0. + * @ko 주어진 값으로 시작 지점, 끝 지점을 초기화하고 progress를 0으로 세팅합니다. + * @param defaultVal - Value to reset {@ko 초기화할 값} + * @since 4.0.0 + */ + reset(defaultVal) { + const range = this._range; + const val = clamp(defaultVal, range.min, range.max); + this._start = val; + this._end = val; + this._val = val; + this._progress = 0; + this._activated = false; + } + /** + * Add delta to start & end and current value. + * @ko 현재 & 끝 및 현재 값에 주어진 값을 더합니다. + * @param delta - Delta value to add {@ko 추가할 값} + */ + add(delta) { + const range = this._range; + this._start = clamp(this._start + delta, range.min, range.max); + this._end = clamp(this._end + delta, range.min, range.max); + this._val = clamp(this._val + delta, range.min, range.max); + } + /** + * Set current value to start, and end to current value + delta, then reset progress to 0. + * @ko 현재 값을 시작 지점으로, 그에서 delta만큼 추가된 값을 끝점으로 하고 progress를 0으로 갱신합니다. + * @param delta - Delta value to add {@ko 추가할 값} + */ + setNewEndByDelta(delta) { + const range = this._range; + this._start = this._val; + this._end = clamp(this._end + delta, range.min, range.max); + this._progress = 0; + this._activated = true; + } + /** + * Set new range of the interpolation. + * @ko 보간의 범위를 변경합니다. + * @param min - New minimum range {@ko 변경할 범위의 최소값} + * @param max - New maximum range {@ko 변경할 범위의 최대값} + */ + setRange(min, max) { + this._start = clamp(this._start, min, max); + this._end = clamp(this._end, min, max); + this._range = { + min, + max + }; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Animation of the {@link Camera} + * @internal + * @ko {@link Camera}의 애니메이션 + * @since 4.0.0 + */ +class CameraAnimation { + /** + * Duration of the animation + * @ko 애니메이션 재생시간 + * @since 4.0.0 + */ + get duration() { + return this._motion.duration; + } + set duration(val) { + this._motion.duration = val; + } + /** + * Easing function of the animation + * @ko 애니메이션의 easing function + * @since 4.0.0 + */ + get easing() { + return this._motion.easing; + } + set easing(val) { + this._motion.easing = val; + } + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param camera - Camera to animate {@ko 애니메이션을 적용할 카메라} + * @param from - Start pose {@ko 애니메이션이 시작 시점의 카메라의 회전 및 줌} + * @param to - End pose {@ko 애니메이션이 끝났을 때 카메라의 회전 및 줌} + * @param options - Options {@ko 옵션들} + * @param options.duration - Animation duration {@ko 애니메이션 재생 시간} + * @param options.easing - Animation easing function {@ko 애니메이션 easing function} + */ + constructor(camera, from, to, { + duration = DEFAULT_ANIMATION_DURATION, + easing = DEFAULT_EASING + } = {}) { + this._camera = camera; + this._motion = new Motion({ + duration, + easing, + range: { + min: 0, + max: 1 + } + }); + this._from = from; + this._to = to; + this._finishPromise = new Promise(resolve => { + this._finish = resolve; + }); + // Enable motion + this._motion.setNewEndByDelta(1); + } + /** + * Return a promise that resolved on animation end. + * @ko 애니메이션 재생이 끝났을 때 resolve되는 Promise를 반환합니다. + * @since 4.0.0 + */ + getFinishPromise() { + return this._finishPromise; + } + /** + * Update animation by given deltaTime. + * @ko 주어진 시간만큼 애니메이션을 업데이트합니다. + * @param deltaTime Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위} + * @since 4.0.0 + */ + update(deltaTime) { + const camera = this._camera; + const from = this._from; + const to = this._to; + const motion = this._motion; + motion.update(deltaTime); + // Progress that easing is applied + const progress = motion.val; + const rotation = quat.create(); + const zoom = lerp(from.zoom, to.zoom, progress); + quat.slerp(rotation, from.rotation, to.rotation, progress); + camera.rotate(rotation, zoom); + if (progress >= 1) { + this._finish(); + } + } +} + +/** + * Camera for View360 + * @ko View360용 카메라 구현체 + * @version 4.0.0 + */ +class Camera extends Component { + /** + * Camera's width / height ratio + * @ko 카메라의 가로 / 세로 비율 + * @readonly + */ + get aspect() { + return this._aspect; + } + /** + * Whether the camera's rotation changed from the last frame. + * @ko 마지막 프레임 이후로 카메라의 회전값이 변경되었는지 나타내는 플래그. + * @readonly + */ + get changed() { + return this._changed; + } + /** + * @copy View360#yawRange + */ + get yawRange() { + return this._initialYawRange; + } + set yawRange(val) { + this._initialYawRange = val; + } + /** + * @copy View360#pitchRange + */ + get pitchRange() { + return this._initialPitchRange; + } + set pitchRange(val) { + this._initialPitchRange = val; + } + /** + * @copy View360#zoomRange + */ + get zoomRange() { + return this._initialZoomRange; + } + set zoomRange(val) { + this._initialZoomRange = val; + } + /** + * Create new instance of Camera + * @param options - Camera options {@ko 카메라 옵션들} + */ + constructor({ + initialYaw, + initialPitch, + initialZoom, + yawRange, + pitchRange, + zoomRange, + fov + }) { + super(); + this.yaw = initialYaw; + this.pitch = initialPitch; + this.zoom = initialZoom; + this.rollOffset = 0; + this.initialYaw = initialYaw; + this.initialPitch = initialPitch; + this.initialZoom = initialZoom; + this.position = vec3.create(); + this.animation = null; + this._up = vec3.fromValues(0, 1, 0); + this._aspect = 1; + this._initialYawRange = yawRange; + this._initialPitchRange = pitchRange; + this._initialZoomRange = zoomRange; + this._yawRange = yawRange; + this._pitchRange = pitchRange; + this._zoomRange = zoomRange; + this.quaternion = quat.create(); + this._updateQuaternion(); + this.viewMatrix = mat4.create(); + this.projectionMatrix = mat4.create(); + this.fov = fov; + this._maxRenderHeight = -1; + } + /** + * Destroy instance and detach all event listeners + * @ko 인스턴스를 삭제하고 모든 이벤트 리스너를 삭제합니다. + * @since 4.0.0 + */ + destroy() { + this.off(); + } + /** + * Refresh internal size value. + * @ko 내부 크기값을 갱신합니다. + * @param width - New width {@ko 변경된 너비값} + * @param height - New height {@ko 변경된 높이값} + * @since 4.0.0 + */ + resize(width, height) { + const prevAspect = this._aspect; + this._aspect = width / height; + if (this._aspect !== prevAspect) { + this.updateMatrix(); + } + } + /** + * Change camera's rotation with euler values. + * @ko 카메라 회전을 오일러 각 방향으로 변경합니다. + * @param rotation - Rotation values {@ko 회전 값} + * @param rotation.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값} + * @param rotation.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값} + * @param rotation.zoom - zoom value to apply {@ko 적용할 카메라 줌 값} + * @since 4.0.0 + */ + lookAt({ + yaw = this.yaw, + pitch = this.pitch, + zoom = this.zoom + }) { + const prevQuaternion = quat.clone(this.quaternion); + const prevZoom = this.zoom; + this.yaw = circulate(yaw, 0, 360); + this.pitch = clamp(pitch, -90, 90); + this.zoom = zoom; + this._updateQuaternion(); + const zoomDiff = Math.abs(zoom - prevZoom); + if (!quat.equals(this.quaternion, prevQuaternion) || zoomDiff >= EPSILON * 10 // ignore small changes + ) { + this.updateMatrix(); + } + } + /** + * Change camera's rotation with quaternion. + * @ko 카메라 회전을 Quaternion을 이용해서 변경합니다. + * @param rotation - Quaternion to apply {@ko 적용할 Quaternion} + * @param zoom - zoom value to apply {@ko 적용할 카메라 줌 값} + * @since 4.0.0 + */ + rotate(rotation, zoom = this.zoom) { + const normalized = quat.normalize(quat.create(), rotation); + const isSameRotation = quat.equals(this.quaternion, normalized); + quat.copy(this.quaternion, normalized); + const prevZoom = this.zoom; + const { + yaw, + pitch + } = quatToEuler(normalized); + this.yaw = yaw; + this.pitch = pitch; + this.zoom = zoom; + const zoomDiff = Math.abs(zoom - prevZoom); + if (!isSameRotation || zoomDiff >= EPSILON * 10) { + this.updateMatrix(); + } + } + /** + * Change camera's rotation to given euler values by the given duration. + * @ko 카메라를 주어진 방향으로 주어진 시간동안 서서히 이동시킵니다. + * @param options - Animation parameters {@ko 애니메이션 패러미터} + * @param options.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값} + * @param options.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값} + * @param options.zoom - zoom value to apply {@ko 적용할 카메라 줌 값} + * @param options.duration - Duration of the animation {@ko 애니메이션 시간} + * @param options.easing - Easing function for the animation {@ko 애니메이션에 적용할 easing function} + */ + animateTo({ + yaw = this.yaw, + pitch = this.pitch, + zoom = this.zoom, + duration = 0, + easing = DEFAULT_EASING + } = {}) { + return __awaiter(this, void 0, void 0, function* () { + if (this.yaw === yaw && this.pitch === pitch && this.zoom === zoom) return; + const from = { + rotation: quat.clone(this.quaternion), + zoom: this.zoom + }; + const to = { + rotation: eulerToQuat(quat.create(), yaw, pitch, this.rollOffset), + zoom + }; + const animation = new CameraAnimation(this, from, to, { + duration, + easing + }); + const finishPromise = animation.getFinishPromise(); + this.animation = animation; + finishPromise.then(() => { + this.animation = null; + this.trigger(CAMERA_EVENTS.ANIMATION_END, { + animation + }); + }); + return finishPromise; + }); + } + /** + * @hidden + */ + restrictYawRange(min, max) { + this._yawRange = { + min, + max + }; + } + /** + * @hidden + */ + restrictPitchRange(min, max) { + this._pitchRange = { + min, + max + }; + } + /** + * @hidden + */ + restrictZoomRange(min, max) { + this._zoomRange = { + min, + max + }; + } + /** + * @hidden + */ + restrictRenderHeight(height) { + this._maxRenderHeight = height; + } + /** + * @hidden + */ + resetRange() { + this._yawRange = this._initialYawRange; + this._pitchRange = this._initialPitchRange; + this._zoomRange = this._initialZoomRange; + this._maxRenderHeight = -1; + } + /** + * Get actual yaw range by the given zoom value. + * @ko 주어진 zoom 값에 대한 실제 yaw 범위값을 반환합니다. + * @since 4.0.0 + */ + getYawRange(zoom) { + const yawLimit = this._yawRange; + const maxRenderHeight = this._maxRenderHeight; + if (!yawLimit) return INFINITE_RANGE; + const halfHFov = this.getHorizontalFov(zoom) * 0.5; + let minYaw = yawLimit.min; + let maxYaw = yawLimit.max; + if (maxRenderHeight > 0) { + const halfVFovRad = toVerticalFov(halfHFov * DEG_TO_RAD, this._aspect); + const h = maxRenderHeight * 0.5; + const t = Math.tan(halfVFovRad); + const d = Math.sqrt((1 + h * h) / (1 + t * t)); + const theta = Math.atan(Math.tan(halfHFov * DEG_TO_RAD) * d) * RAD_TO_DEG; + minYaw = yawLimit.min + theta; + maxYaw = yawLimit.max - theta; + } + if (minYaw > maxYaw) { + minYaw = 0; + maxYaw = 0; + } + return { + min: minYaw, + max: maxYaw + }; + } + /** + * Get actual pitch range by the given zoom value. + * @ko 주어진 zoom 값에 대한 실제 pitch 범위값을 반환합니다. + * @since 4.0.0 + */ + getPitchRange(zoom) { + const pitchLimit = this._pitchRange; + const maxRenderHeight = this._maxRenderHeight; + if (!pitchLimit) return DEFAULT_PITCH_RANGE; + let minPitch = pitchLimit.min; + let maxPitch = pitchLimit.max; + if (maxRenderHeight > 0) { + const halfVFov = this.getVerticalFov(zoom) * 0.5; + minPitch = pitchLimit.min + halfVFov; + maxPitch = pitchLimit.max - halfVFov; + } + if (minPitch > maxPitch) { + minPitch = 0; + maxPitch = 0; + } + return { + min: Math.max(minPitch, -90), + max: Math.min(maxPitch, 90) + }; + } + /** + * Get actual zoom range in fov degrees. + * @ko 실제 줌 범위를 fov각의 범위로 반환합니다. + * @since 4.0.0 + */ + getZoomRange() { + var _a; + const limit = (_a = this._zoomRange) !== null && _a !== void 0 ? _a : DEFAULT_ZOOM_RANGE; + // max (zoom in) -> minimum fov + const minFov = this.getHorizontalFov(limit.max); + const maxFov = this.getHorizontalFov(limit.min); + const currentFov = this.getHorizontalFov(this.zoom); + return { + min: Math.max(minFov, 1), + max: Math.min(maxFov, 180), + current: currentFov + }; + } + /** + * Return horizontal fov value when the given zoom is applied. (in degrees, °) + * @ko 주어진 zoom 값이 적용되었을 때의 수평 fov값을 반환합니다. (도 단위, °) + * @returns Zoomed horizontal FOV {@ko 줌이 적용된 수평 fov값} + * @since 4.0.0 + */ + getHorizontalFov(zoom = this.zoom) { + return this._getZoomedHorizontalFov(zoom) * RAD_TO_DEG; + } + /** + * Return vertical fov value when the given zoom is applied. (in degrees, °) + * @ko 주어진 zoom 값이 적용되었을 때의 수직 fov값을 반환합니다. (도 단위, °) + * @returns Zoomed vertical FOV {@ko 줌이 적용된 수직 fov값} + * @since 4.0.0 + */ + getVerticalFov(zoom = this.zoom) { + const aspect = this._aspect; + const hFov = this._getZoomedHorizontalFov(zoom); // In radians + const vFov = toVerticalFov(hFov, aspect); + return vFov * RAD_TO_DEG; + } + /** + * Calculate zoom value for the given fov. + * @ko 주어진 fov값을 zoom값으로 변환합니다. + * @param fov horizontal fov (in degrees, °) {@ko 수평 fov 값 (도 단위, °)} + * @since 4.0.0 + */ + fovToZoom(fov) { + const baseFov = this.fov; + const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5); + const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5); + return renderingWidth / zoomedWidth; + } + /** + * Update inner matrixes. + * @ko 내부 행렬들을 업데이트합니다. + * @internal + * @since 4.0.0 + */ + updateMatrix() { + const up = this._up; + const aspect = this._aspect; + const viewMatrix = this.viewMatrix; + const projMatrix = this.projectionMatrix; + const position = this.position; + const rotation = this.quaternion; + const upDir = vec3.create(); + const viewDir = vec3.fromValues(0, 0, -1); + vec3.transformQuat(viewDir, viewDir, rotation); + vec3.transformQuat(upDir, up, rotation); + const hFov = this._getZoomedHorizontalFov(); // In radians + const vFov = toVerticalFov(hFov, aspect); + mat4.lookAt(viewMatrix, position, viewDir, upDir); + mat4.perspective(projMatrix, vFov, aspect, 0.1, 100); + this._changed = true; + } + /** + * @hidden + */ + onFrameRender() { + this._changed = false; + } + _updateQuaternion() { + eulerToQuat(this.quaternion, this.yaw, this.pitch, this.rollOffset); + } + /** + * @param zoom Current zoom value + * @returns horizontal fov including zoom, in radian + */ + _getZoomedHorizontalFov(zoom = this.zoom) { + return 2 * Math.atan(Math.tan(DEG_TO_RAD * this.fov * 0.5) / zoom); + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +class MouseInput extends Component { + constructor() { + super(); + this._onMouseDown = evt => { + const el = this._el; + if (!el || evt.button !== MOUSE_BUTTON.LEFT) return; + evt.preventDefault(); + if (el.focus) { + el.focus(); + } else { + window.focus(); + } + this._prevPos[0] = evt.clientX; + this._prevPos[1] = evt.clientY; + window.addEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove, false); + window.addEventListener(EVENTS$1.MOUSE_UP, this._onMouseUp, false); + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: false, + isKeyboard: false + }); + }; + this._onMouseMove = evt => { + evt.preventDefault(); + const x = evt.clientX; + const y = evt.clientY; + const prevPos = this._prevPos; + const deltaX = x - prevPos[0]; + const deltaY = y - prevPos[1]; + this.trigger(CONTROL_EVENTS.CHANGE, { + delta: { + x: deltaX, + y: deltaY + }, + isTouch: false, + isKeyboard: false + }); + prevPos[0] = x; + prevPos[1] = y; + }; + this._onMouseUp = () => { + this._prevPos[0] = 0; + this._prevPos[1] = 0; + window.removeEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove, false); + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onMouseUp, false); + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: false, + isKeyboard: false, + scrolling: false + }); + }; + this._el = null; + this._prevPos = [0, 0]; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.MOUSE_DOWN, this._onMouseDown); + this._el = element; + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.MOUSE_DOWN, this._onMouseDown); + window.removeEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove, false); + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onMouseUp, false); + this._el = null; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +class TouchInput extends Component { + get scrollable() { + return this._scrollable; + } + set scrollable(val) { + this._scrollable = val; + } + constructor() { + super(); + this._onTouchStart = evt => { + if (evt.touches.length > 1 || this._scrolling) return; + const touch = evt.touches[0]; + this._isFirstTouch = true; + this._prevPos[0] = touch.clientX; + this._prevPos[1] = touch.clientY; + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: true, + isKeyboard: false + }); + }; + this._onTouchMove = evt => { + // Only the one finger motion should be considered + if (evt.touches.length > 1 || this._scrolling) return; + const touch = evt.touches[0]; + const scrollable = this._scrollable; + const prevPos = this._prevPos; + const x = touch.clientX; + const y = touch.clientY; + const deltaX = x - prevPos[0]; + const deltaY = y - prevPos[1]; + if (this._isFirstTouch) { + if (scrollable && !isFullscreen()) { + if (Math.abs(deltaY) > Math.abs(deltaX)) { + // Assume Scrolling + this._scrolling = true; + return; + } + } + this._isFirstTouch = false; + } + if (evt.cancelable !== false) { + evt.preventDefault(); + } + this.trigger(CONTROL_EVENTS.CHANGE, { + delta: { + x: deltaX, + y: deltaY + }, + isTouch: true, + isKeyboard: false + }); + prevPos[0] = x; + prevPos[1] = y; + }; + this._onTouchEnd = evt => { + if (evt.touches.length !== 0) return; + const touch = evt.touches[0]; + const prevPos = this._prevPos; + if (touch) { + prevPos[0] = touch.clientX; + prevPos[1] = touch.clientY; + } else { + prevPos[0] = 0; + prevPos[1] = 0; + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: true, + isKeyboard: false, + scrolling: this._scrolling + }); + } + if (evt.cancelable !== false) { + evt.preventDefault(); + } + this._scrolling = false; + }; + this._el = null; + this._prevPos = [0, 0]; + this._isFirstTouch = false; + this._scrolling = false; + this._scrollable = false; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.TOUCH_START, this._onTouchStart, { + passive: false + }); + element.addEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove, { + passive: false + }); + element.addEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = element; + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.TOUCH_START, this._onTouchStart); + element.removeEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove); + element.removeEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = null; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +class KeyboardInput extends Component { + get active() { + const pressed = this._pressed; + return pressed.LEFT || pressed.UP || pressed.RIGHT || pressed.DOWN; + } + constructor() { + super(); + this._onKeyDown = evt => { + // Ignore all other keypress except main arrow keys + if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return; + this._updateKeyPress(evt, true); + const pressedCount = this._getPressedKeyCount(); + if (pressedCount <= 0) return; + evt.preventDefault(); + if (pressedCount === 1 && !evt.repeat) { + // On first keydown + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: false, + isKeyboard: true + }); + } + }; + this._onKeyUp = evt => { + // Ignore all other keypress except main arrow keys + if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return; + this._updateKeyPress(evt, false); + const pressedCount = this._getPressedKeyCount(); + if (pressedCount > 0) return; + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: false, + isKeyboard: true, + scrolling: false + }); + }; + this._el = null; + this._clearPressedKeys(); + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown); + element.addEventListener(EVENTS$1.KEY_UP, this._onKeyUp); + this._el = element; + this._clearPressedKeys(); + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown); + element.removeEventListener(EVENTS$1.KEY_UP, this._onKeyUp); + this._el = null; + this._clearPressedKeys(); + } + update() { + const delta = this._getDeltaByPressedKeys(); + if (delta.x !== 0 || delta.y !== 0) { + this.trigger(CONTROL_EVENTS.CHANGE, { + delta, + isTouch: false, + isKeyboard: true + }); + } + } + _clearPressedKeys() { + this._pressed = KEY_DIRECTION.reduce((obj, keyName) => { + return Object.assign(Object.assign({}, obj), { + [keyName]: false + }); + }, {}); + } + _updateKeyPress(event, isEnable) { + const pressed = this._pressed; + const keyToUpdate = event.keyCode != null ? DIRECTION_KEY_CODE[event.keyCode] : DIRECTION_KEY_NAME[event.key]; + if (!keyToUpdate) return; + pressed[keyToUpdate] = isEnable; + } + _getPressedKeyCount() { + return KEY_DIRECTION.filter(key => this._pressed[key]).length; + } + _getDeltaByPressedKeys() { + const pressed = this._pressed; + let x = 0; + let y = 0; + if (pressed.LEFT) { + x += 1; + } + if (pressed.RIGHT) { + x -= 1; + } + if (pressed.UP) { + y += 1; + } + if (pressed.DOWN) { + y -= 1; + } + return { + x, + y + }; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Camera's rotation control + * @ko 카메라의 회전을 담당하는 컨트롤 + * @since 4.0.0 + */ +class RotateControl extends Component { + /** + * @copy CameraControl#enabled + */ + get enabled() { + return this._enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * @copy CameraControl#animating + */ + get animating() { + return this._keyboardInput.active || this._xMotion.activated || this._yMotion.activated; + } + /** + * Current yaw value + * @ko 현재 yaw 값 + * @readonly + * @since 4.0.0 + */ + get yaw() { + return this._xMotion; + } + /** + * Current pitch value + * @ko 현재 pitch 값 + * @readonly + * @since 4.0.0 + */ + get pitch() { + return this._yMotion; + } + /** + * @copy View360#scrollable + */ + get scrollable() { + return this._touchInput.scrollable; + } + set scrollable(val) { + this._touchInput.scrollable = val; + } + /** + * Scale factor for mouse/touch rotation + * @ko 마우스/터치를 통한 회전 배율 + * @default [1, 1] + * @since 4.0.0 + */ + get pointerScale() { + return this._pointerScale; + } + set pointerScale(val) { + this._pointerScale = val; + } + /** + * Scale factor for keyboard rotation + * @ko 키보드를 통한 회전 배율 + * @default [1, 1] + * @since 4.0.0 + */ + get keyboardScale() { + return this._keyboardScale; + } + set keyboardScale(val) { + this._keyboardScale = val; + } + /** + * Duration of the input animation (ms) + * @ko 회전 애니메이션의 시간 (ms) + * @default 300 + */ + get duration() { + return this._duration; + } + set duration(val) { + this._duration = val; + this._xMotion.duration = val; + this._yMotion.duration = val; + } + /** + * Easing function of the animation + * @ko 회전 애니메이션에 적용할 easing 함수 + * @default EASING.EASE_OUT_CUBIC + * @see EASING + */ + get easing() { + return this._easing; + } + set easing(val) { + this._easing = val; + this._xMotion.easing = val; + this._yMotion.easing = val; + } + /** + * Disable X-axis(pitch) rotation. + * @ko x축 회전(pitch)을 비활성화합니다. + * @default false + */ + get disablePitch() { + return this._disablePitch; + } + set disablePitch(val) { + this._disablePitch = val; + } + /** + * Disable Y-axis(yaw) rotation. + * @ko y축 회전(yaw)을 비활성화합니다. + * @default false + */ + get disableYaw() { + return this._disableYaw; + } + set disableYaw(val) { + this._disableYaw = val; + } + /** + * Disable rotation by keyboard. + * @ko 키보드를 이용한 회전을 비활성화합니다. + * @default false + */ + get disableKeyboard() { + return this._disableKeyboard; + } + set disableKeyboard(val) { + this._disableKeyboard = val; + } + /** + * Create new RotateControl instance + * @ko RotateControl의 인스턴스를 생성합니다. + * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트} + * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부} + * @param options - Options for control {@ko 컨트롤 옵션들} + */ + constructor(controlEl, enableBlocked, { + duration = DEFAULT_ANIMATION_DURATION, + easing = DEFAULT_EASING, + pointerScale = [1, 1], + keyboardScale = [1, 1], + disablePitch = false, + disableYaw = false, + disableKeyboard = false + } = {}) { + super(); + this._onInputStart = evt => { + this._changedWhileDragging = false; + this.trigger(CONTROL_EVENTS.INPUT_START, Object.assign(Object.assign({}, evt), { + inputType: "rotate" + })); + }; + this._onChange = evt => { + const delta = evt.delta; + const invZoomScale = 1 / this._zoomScale; // Reduce speed on zoom + const screenScale = this._screenScale; + const keyboardScale = this._keyboardScale; + const pointerScale = this._pointerScale; + let scale; + if (evt.isKeyboard) { + scale = [keyboardScale[0] * invZoomScale, keyboardScale[1] * invZoomScale]; + } else { + scale = [pointerScale[0] * screenScale[0] * invZoomScale, pointerScale[1] * screenScale[1] * invZoomScale]; + } + const scaledX = delta.x * scale[0]; + const scaledY = delta.y * scale[1]; + this._xMotion.setNewEndByDelta(scaledX); + this._yMotion.setNewEndByDelta(scaledY); + this._changedWhileDragging = true; + }; + this._onInputEnd = evt => { + this.trigger(CONTROL_EVENTS.INPUT_END, Object.assign(Object.assign({}, evt), { + inputType: "rotate" + })); + if (!this._changedWhileDragging && !evt.isKeyboard && !evt.scrolling) { + this.trigger(CONTROL_EVENTS.STATIC_CLICK, { + isTouch: evt.isTouch + }); + } + this._changedWhileDragging = false; + }; + this._controlEl = controlEl; + this._pointerScale = pointerScale; + this._keyboardScale = keyboardScale; + this._duration = duration; + this._easing = easing; + this._disablePitch = disablePitch; + this._disableYaw = disableYaw; + this._disableKeyboard = disableKeyboard; + this._enableBlocked = enableBlocked; + this._mouseInput = new MouseInput(); + this._touchInput = new TouchInput(); + this._keyboardInput = new KeyboardInput(); + this._xMotion = new Motion({ + duration, + range: INFINITE_RANGE, + easing + }); + this._yMotion = new Motion({ + duration, + range: DEFAULT_PITCH_RANGE, + easing + }); + this._screenScale = [1, 1]; + this._zoomScale = 1; + this._enabled = false; + this._changedWhileDragging = false; + this._bindInputs(); + } + destroy() { + this.disable(); + this._mouseInput.off(); + this._touchInput.off(); + this._keyboardInput.off(); + this.off(); + this._changedWhileDragging = false; + } + /** + * @hidden + */ + update(delta) { + if (!this._enabled) return; + const xMotion = this._xMotion; + const yMotion = this._yMotion; + const keyboardInput = this._keyboardInput; + if (!this._disableKeyboard) { + keyboardInput.update(); + } + if (!this._disablePitch) { + yMotion.update(delta); + } + if (!this._disableYaw) { + xMotion.update(delta); + } + } + /** + * @hidden + */ + updateRange(camera, zoom) { + const yawRange = camera.getYawRange(zoom); + const pitchRange = camera.getPitchRange(zoom); + this._xMotion.setRange(yawRange.min, yawRange.max); + this._yMotion.setRange(pitchRange.min, pitchRange.max); + } + /** + * @hidden + */ + setZoomScale(val) { + this._zoomScale = val; + } + /** + * Resize control to match target size. + * @ko 컨트롤의 내부 크기를 갱신합니다. + * @param hfov - Camera horizontal fov in degrees {@ko 카메라의 수평방향 fov값 (도 단위)} + * @param aspect - Camera aspect {@ko 카메라 가로/세로 비율} + * @param width - New width {@ko 갱신된 너비} + * @param height - New height {@ko 갱신된 높이} + */ + resize(hfov, aspect, width, height) { + const vfov = toVerticalFov(hfov * DEG_TO_RAD, aspect) * RAD_TO_DEG; + this._screenScale[0] = hfov / width; + this._screenScale[1] = vfov / height; + } + enable() { + if (this._enabled) return; + const element = this._controlEl; + this._mouseInput.enable(element); + this._touchInput.enable(element); + this._keyboardInput.enable(element); + this._enabled = true; + this._enableBlocked = false; + this.trigger(CONTROL_EVENTS.ENABLE, { + control: this, + updateCursor: true + }); + } + disable() { + if (!this._enabled) return; + this._mouseInput.disable(); + this._touchInput.disable(); + this._keyboardInput.disable(); + this._enabled = false; + this.trigger(CONTROL_EVENTS.DISABLE, { + updateCursor: true + }); + } + sync(camera) { + this.updateRange(camera, camera.zoom); + this._xMotion.reset(camera.yaw); + this._yMotion.reset(camera.pitch); + } + _bindInputs() { + const mouseInput = this._mouseInput; + const touchInput = this._touchInput; + const keyboardInput = this._keyboardInput; + mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + touchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + touchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + keyboardInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + keyboardInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + keyboardInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +class WheelInput extends Component { + get scrollable() { + return this._scrollable; + } + set scrollable(val) { + this._scrollable = val; + } + constructor() { + super(); + this._onWheel = evt => { + const scrollable = this._scrollable; + if (evt.deltaY === 0 || scrollable) return; + evt.preventDefault(); + evt.stopPropagation(); + if (this._inputTimer < 0) { + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: false, + isKeyboard: false + }); + } else { + this._clearTimer(); + } + const delta = this._baseScale * evt.deltaY; + this.trigger(CONTROL_EVENTS.CHANGE, { + delta, + isTouch: false, + isKeyboard: false + }); + this._inputTimer = window.setTimeout(() => { + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: false, + isKeyboard: false, + scrolling: false + }); + this._inputTimer = -1; + }, DEFAULT_ANIMATION_DURATION); + }; + this._el = null; + this._baseScale = 0.04; + this._scrollable = false; + this._inputTimer = -1; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.WHEEL, this._onWheel, { + passive: false, + capture: false + }); + this._el = element; + this._clearTimer(); + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.WHEEL, this._onWheel, false); + this._el = null; + this._clearTimer(); + } + _clearTimer() { + window.clearTimeout(this._inputTimer); + this._inputTimer = -1; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +class PinchInput extends Component { + constructor() { + super(); + this._onTouchMove = evt => { + const touches = evt.touches; + if (touches.length !== 2) return; + if (!evt.cancelable) return; + evt.preventDefault(); + evt.stopPropagation(); + const prevDistance = this._prevDistance; + const diff = [touches[0].pageX - touches[1].pageX, touches[0].pageY - touches[1].pageY]; + const distance = Math.sqrt(diff[0] * diff[0] + diff[1] * diff[1]) * this._baseScale; + const delta = this._isFirstTouch ? 0 : distance - prevDistance; + if (this._isFirstTouch) { + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: true, + isKeyboard: false + }); + } + this._prevDistance = distance; + this._isFirstTouch = false; + this.trigger(CONTROL_EVENTS.CHANGE, { + delta, + isTouch: true, + isKeyboard: false + }); + }; + this._onTouchEnd = evt => { + if (evt.touches.length !== 0) return; + if (!this._isFirstTouch) { + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: true, + isKeyboard: false, + scrolling: false + }); + } + this._prevDistance = -1; + this._isFirstTouch = true; + }; + this._el = null; + this._baseScale = -0.2; + this._prevDistance = -1; + this._isFirstTouch = true; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove, { + passive: false, + capture: false + }); + element.addEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = element; + this._prevDistance = -1; + this._isFirstTouch = true; + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove, false); + element.removeEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = null; + } +} + +/* +* Copyright (c) 2023-present NAVER Corp. +* egjs projects are licensed under the MIT license +*/ +/** + * Camera's zoom control + * @ko 카메라의 줌 값을 담당하는 컨트롤 + * @since 4.0.0 + */ +class ZoomControl extends Component { + /** + * @copy CameraControl#enabled + */ + get enabled() { + return this._enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * @copy CameraControl#animating + */ + get animating() { + return this._motion.activated; + } + /** + * Current zoom value + * @ko 현재 줌 값 + * @since 4.0.0 + * @readonly + */ + get zoom() { + return this._motion.val; + } + /** + * @copy View360#wheelScrollable + */ + get scrollable() { + return this._wheelInput.scrollable; + } + set scrollable(val) { + this._wheelInput.scrollable = val; + } + /** + * @hidden + */ + get range() { + return this._motion.range; + } + /** + * Scale factor of the zoom + * @ko 입력에 의한 줌 배율 + * @default 1 + * @since 4.0.0 + */ + get scale() { + return this._scale; + } + set scale(val) { + this._scale = val; + } + /** + * Duration of the input animation (ms) + * @ko 회전 애니메이션의 시간 (ms) + * @default 300 + * @since 4.0.0 + */ + get duration() { + return this._motion.duration; + } + /** + * Easing function of the animation + * @ko 회전 애니메이션에 적용할 easing 함수 + * @default EASING.EASE_OUT_CUBIC + * @see EASING + * @since 4.0.0 + */ + get easing() { + return this._motion.easing; + } + /** + * Create new ZoomControl instance + * @ko ZoomControl의 인스턴스를 생성합니다. + * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트} + * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부} + * @param options - Options for control {@ko 컨트롤 옵션들} + */ + constructor(controlEl, enableBlocked, { + scale = 1, + duration = DEFAULT_ANIMATION_DURATION, + easing = DEFAULT_EASING + } = {}) { + super(); + this._onInputStart = evt => { + this.trigger(CONTROL_EVENTS.INPUT_START, Object.assign(Object.assign({}, evt), { + inputType: "zoom" + })); + }; + this._onChange = ({ + delta + }) => { + const scale = this._scale; + const scaledDelta = delta * scale; + this._motion.setNewEndByDelta(scaledDelta); + }; + this._onInputEnd = evt => { + this.trigger(CONTROL_EVENTS.INPUT_END, Object.assign(Object.assign({}, evt), { + inputType: "zoom" + })); + }; + this._scale = scale; + this._controlEl = controlEl; + this._enableBlocked = enableBlocked; + this._wheelInput = new WheelInput(); + this._pinchInput = new PinchInput(); + this._motion = new Motion({ + duration, + easing, + range: INFINITE_RANGE + }); + this._enabled = false; + this._bindInputs(); + } + destroy() { + this.disable(); + this._wheelInput.off(); + this._pinchInput.off(); + this.off(); + } + /** + * @hidden + */ + update(delta) { + if (!this._enabled) return; + const motion = this._motion; + motion.update(delta); + } + enable() { + if (this._enabled) return; + const element = this._controlEl; + this._wheelInput.enable(element); + this._pinchInput.enable(element); + this._enabled = true; + this._enableBlocked = false; + this.trigger(CONTROL_EVENTS.ENABLE, { + control: this, + updateCursor: false + }); + } + disable() { + if (!this._enabled) return; + this._wheelInput.disable(); + this._pinchInput.disable(); + this._enabled = false; + this.trigger(CONTROL_EVENTS.DISABLE, { + updateCursor: false + }); + } + sync(camera) { + const motion = this._motion; + const range = camera.getZoomRange(); + motion.setRange(range.min, range.max); + motion.reset(range.current); + } + _bindInputs() { + const wheelInput = this._wheelInput; + const pinchInput = this._pinchInput; + wheelInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + wheelInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + wheelInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + pinchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + pinchInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + pinchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +const ROTATE_CONSTANT = { + PITCH_DELTA: 1, + YAW_DELTA_BY_ROLL: 2, + YAW_DELTA_BY_YAW: 3 +}; +ROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = { + targetAxis: [0, 1, 0], + meshPoint: [0, 0, 1] +}; +ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = { + targetAxis: [0, 1, 0], + meshPoint: [1, 0, 0] +}; +ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = { + targetAxis: [1, 0, 0], + meshPoint: [0, 0, 1] +}; +class GyroInput extends Component { + get enabled() { + return this._enabled; + } + get orientationUpdated() { + return this._orientationUpdated; + } + get ignoreRoll() { + return this._ignoreRoll; + } + set ignoreRoll(val) { + this._ignoreRoll = val; + } + constructor() { + super(); + this._onDeviceOrientation = evt => { + const prevOrientation = this._orientation; + const { + alpha, + beta, + gamma + } = evt; + if (alpha == null || beta == null || gamma == null) return; + prevOrientation.alpha = alpha; + prevOrientation.beta = beta; + prevOrientation.gamma = gamma; + this._orientationUpdated = true; + if (this._needsCalibrate) { + this._needsCalibrate = false; + this._calibrateSensor(); + } + }; + this._updateScreenOrientation = () => { + if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) { + this._screenOrientation = screen.orientation.angle; + } else if (window.orientation !== undefined) { + this._screenOrientation = window.orientation >= 0 ? window.orientation : 360 + window.orientation; + } else { + this._screenOrientation = 0; + } + }; + this.quaternion = quat.create(); + this._orientation = { + alpha: 0, + beta: 90, + gamma: 0 + }; + this._yawOrigin = 0; + this._yawOffset = 0; + this._orientationUpdated = false; + this._screenOrientation = 0; + this._needsCalibrate = true; + this._enabled = false; + } + enable() { + if (this._enabled) return; + window.addEventListener(EVENTS$1.DEVICE_ORIENTATION, this._onDeviceOrientation); + window.addEventListener(EVENTS$1.ORIENTATION_CHANGE, this._updateScreenOrientation); + this._updateScreenOrientation(); + this._orientationUpdated = false; + this._needsCalibrate = true; + this._enabled = true; + } + disable() { + if (!this._enabled) return; + window.removeEventListener(EVENTS$1.DEVICE_ORIENTATION, this._onDeviceOrientation); + window.removeEventListener(EVENTS$1.ORIENTATION_CHANGE, this._updateScreenOrientation); + this._enabled = false; + } + update() { + this._updateRotation(); + this._orientationUpdated = false; + } + collectDelta() { + if (!this._orientationUpdated) { + return { + pitch: 0, + yaw: 0 + }; + } + const prevRotation = quat.clone(this.quaternion); + this._updateRotation(); + this._orientationUpdated = false; + return this._toEulerDelta(prevRotation, this.quaternion); + } + setInitialRotation(yaw) { + this._yawOrigin = yaw; + } + _calibrateSensor() { + const yawOrigin = this._yawOrigin; + const rotation = this.quaternion; + this._yawOffset = 0; + this._updateRotation(); + const { + yaw: sensorYaw + } = quatToEuler(rotation); + this._yawOffset = sensorYaw - yawOrigin; + this._updateRotation(); + this._needsCalibrate = false; + } + _updateRotation() { + const rotation = this.quaternion; + const { + alpha, + beta, + gamma + } = this._orientation; + quat.identity(rotation); + quat.rotateY(rotation, rotation, (alpha - this._yawOffset) * DEG_TO_RAD); + quat.rotateX(rotation, rotation, beta * DEG_TO_RAD); + quat.rotateZ(rotation, rotation, -gamma * DEG_TO_RAD); + const screen = quat.create(); + const screenAngle = -this._screenOrientation * 0.5 * DEG_TO_RAD; + const world = quat.fromValues(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5)); + quat.set(screen, 0, Math.sin(screenAngle), 0, Math.cos(screenAngle)); + quat.multiply(rotation, rotation, screen); + quat.multiply(rotation, rotation, world); + quat.normalize(rotation, rotation); + } + _toEulerDelta(prevQuat, currentQuat) { + return { + yaw: this._getDeltaYaw(prevQuat, currentQuat), + pitch: this._getDeltaPitch(prevQuat, currentQuat) + }; + } + _getDeltaYaw(prvQ, curQ) { + const yawDeltaByYaw = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW); + const yawDeltaByRoll = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) * Math.sin(this._extractPitchFromQuat(curQ)); + return yawDeltaByRoll + yawDeltaByYaw; + } + _getDeltaPitch(prvQ, curQ) { + return this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA); + } + _getRotationDelta(prevQ, curQ, rotateKind) { + const targetAxis = vec3.fromValues(ROTATE_CONSTANT[rotateKind].targetAxis[0], ROTATE_CONSTANT[rotateKind].targetAxis[1], ROTATE_CONSTANT[rotateKind].targetAxis[2]); + const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint; + const prevQuaternion = quat.clone(prevQ); + const curQuaternion = quat.clone(curQ); + quat.normalize(prevQuaternion, prevQuaternion); + quat.normalize(curQuaternion, curQuaternion); + let prevPoint = vec3.fromValues(0, 0, 1); + let curPoint = vec3.fromValues(0, 0, 1); + vec3.transformQuat(prevPoint, prevPoint, prevQuaternion); + vec3.transformQuat(curPoint, curPoint, curQuaternion); + vec3.transformQuat(targetAxis, targetAxis, curQuaternion); + const rotateDistance = vec3.dot(targetAxis, vec3.cross(vec3.create(), prevPoint, curPoint)); + const rotateDirection = rotateDistance > 0 ? 1 : -1; + // when counter clock wise, use vec3.fromValues(0,1,0) + // when clock wise, use vec3.fromValues(0,-1,0) + // const meshPoint1 = vec3.fromValues(0, 0, 0); + const meshPoint2 = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + let meshPoint3; + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + meshPoint3 = vec3.fromValues(0, rotateDirection, 0); + } else { + meshPoint3 = vec3.fromValues(rotateDirection, 0, 0); + } + vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion); + vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion); + const vecU = meshPoint2; + const vecV = meshPoint3; + const vecN = vec3.create(); + vec3.cross(vecN, vecU, vecV); + vec3.normalize(vecN, vecN); + const coefficientA = vecN[0]; + const coefficientB = vecN[1]; + const coefficientC = vecN[2]; + // a point on the plane + curPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + vec3.transformQuat(curPoint, curPoint, curQuaternion); + // a point should project on the plane + prevPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + vec3.transformQuat(prevPoint, prevPoint, prevQuaternion); + // distance between prevPoint and the plane + let distance = Math.abs(prevPoint[0] * coefficientA + prevPoint[1] * coefficientB + prevPoint[2] * coefficientC); + const projectedPrevPoint = vec3.create(); + vec3.subtract(projectedPrevPoint, prevPoint, vec3.scale(vec3.create(), vecN, distance)); + let trigonometricRatio = (projectedPrevPoint[0] * curPoint[0] + projectedPrevPoint[1] * curPoint[1] + projectedPrevPoint[2] * curPoint[2]) / (vec3.length(projectedPrevPoint) * vec3.length(curPoint)); + // defensive block + if (trigonometricRatio > 1) { + trigonometricRatio = 1; + } + const theta = Math.acos(trigonometricRatio); + const crossVec = vec3.cross(vec3.create(), curPoint, projectedPrevPoint); + distance = coefficientA * crossVec[0] + coefficientB * crossVec[1] + coefficientC * crossVec[2]; + let thetaDirection; + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + thetaDirection = distance > 0 ? 1 : -1; + } else { + thetaDirection = distance < 0 ? 1 : -1; + } + const deltaRadian = theta * thetaDirection * rotateDirection; + return deltaRadian * RAD_TO_DEG; + } + _extractPitchFromQuat(quaternion) { + const baseV = vec3.fromValues(0, 0, 1); + vec3.transformQuat(baseV, baseV, quaternion); + return -1 * Math.atan2(baseV[1], Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2))); + } +} + +/** + * Camera's rotation control by gyroscope + * @ko 자이로스코프를 이용한 회전 컨트롤 + * @since 4.0.0 + */ +class GyroControl extends Component { + /** + * @copy CameraControl#enabled + */ + get enabled() { + return this._input.enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * @copy CameraControl#animating + */ + get animating() { + return this._input.enabled && this._input.orientationUpdated; + } + /** + * When `true`, ignore gyroscope's roll(z-axis rotation) value. + * :::caution + * Setting `false` will ignore camera's range limit. + * Options like {@link View360Options#yawRange}, {@link View360Options#pitchRange} are ignored, and {@link CylinderProjection} also can't force it's camera range limit. + * ::: + * @ko `true`일 경우 자이로스코프 입력의 roll(z축 회전)값을 무시합니다. + * :::caution + * 이 값을 `false`로 설정할 경우 카메라 범위 제약을 무시합니다. + * {@link View360Options#yawRange}, {@link View360Options#pitchRange}와 같은 값은 무시되며, {@link CylinderProjection} 사용시에도 범위를 벗어날 수 있습니다. + * ::: + * @default true + * @since 4.0.0 + */ + get ignoreRoll() { + return this._ignoreRoll; + } + set ignoreRoll(val) { + this._ignoreRoll = val; + } + /** + * Return availability of the gyroscope. + * :::caution + * This will always return false until user permission under environments like iOS which requires user permission when using gyroscope. + * ::: + * @ko 자이로스코프 사용 가능 여부를 반환합니다. + * :::caution + * iOS와 같이 GyroScope 사용시 사용자 Permission을 요구하는 환경에서는 사용자 Permission을 받기 전까지 항상 `false`입니다. + * ::: + * @example + * ```ts + * const gyroAvailable = await GyroControl.isAvailable(); + * ``` + */ + static isAvailable() { + return __awaiter(this, void 0, void 0, function* () { + if (!DeviceMotionEvent) { + return false; + } + let onDeviceMotionChange; + const listenDeviceMotion = () => new Promise(res => { + onDeviceMotionChange = evt => { + res(evt.rotationRate && evt.rotationRate.alpha != null); + }; + window.addEventListener(EVENTS$1.DEVICE_MOTION, onDeviceMotionChange); + }); + const timeout = () => new Promise(res => { + setTimeout(() => res(false), 1000); + }); + return Promise.race([listenDeviceMotion(), timeout()]).then(available => { + window.removeEventListener(EVENTS$1.DEVICE_MOTION, onDeviceMotionChange); + return available; + }); + }); + } + /** + * Request user permission for gyroscope sensor. + * This can be used in environments like iOS which requires user permission when using gyroscope sensors. + * @ko 사용자의 sensor permission 취득을 요청합니다. + * iOS와 같이 gyroscope 사용시 사용자 Permission을 요구하는 환경에서 사용 가능합니다. + * @returns Whether the permission is granted {@ko 사용자 permission 취득 여부} + */ + static requestSensorPermission() { + return __awaiter(this, void 0, void 0, function* () { + // Request sensor permission, on iOS13+ + if (sensorCanBeEnabledIOS()) { + return DeviceMotionEvent.requestPermission().then(permissionState => { + return permissionState === "granted"; + }).catch(() => false); + } + return true; + }); + } + /** + * Create new GyroControl instance + * @ko GyroControl의 인스턴스를 생성합니다. + * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부} + * @param options - Options for control {@ko 컨트롤 옵션들} + */ + constructor(enableBlocked, { + ignoreRoll = true + } = {}) { + super(); + this._enableBlocked = enableBlocked; + this._ignoreRoll = ignoreRoll; + this._input = new GyroInput(); + } + /** + * @copy CameraControl#destroy + */ + destroy() { + this.disable(); + this._input.off(); + this.off(); + } + /** + * @hidden + */ + update(camera, yaw, pitch, zoom) { + if (!this._ignoreRoll) { + this._updateQuaternion(camera, zoom); + } else { + this._updateYawPitch(camera, yaw, pitch, zoom); + } + } + /** + * @copy CameraControl#enable + */ + enable() { + if (this._input.enabled) return; + this._input.enable(); + this._enableBlocked = false; + this.trigger(CONTROL_EVENTS.ENABLE, { + control: this, + updateCursor: false + }); + } + /** + * @copy CameraControl#disable + */ + disable() { + if (!this._input.enabled) return; + this._input.disable(); + this.trigger(CONTROL_EVENTS.DISABLE, { + updateCursor: false + }); + } + /** + * @copy CameraControl#sync + */ + sync() {} // eslint-disable-line @typescript-eslint/no-empty-function + _updateYawPitch(camera, yaw, pitch, zoom) { + const input = this._input; + if (!input.enabled) return; + const { + yaw: yawDelta, + pitch: pitchDelta + } = input.collectDelta(); + yaw.add(yawDelta); + pitch.add(pitchDelta); + camera.lookAt({ + yaw: yaw.val, + pitch: pitch.val, + zoom + }); + } + _updateQuaternion(camera, zoom) { + const input = this._input; + if (!input.enabled) return; + input.update(); + camera.rotate(input.quaternion, zoom); + } +} + +/** + * Panorama control for View360 + * @ko View360용 파노라마 컨트롤 + * @since 4.0.0 + */ +class PanoControl { + /** + * @copy View360#useGrabCursor + */ + get useGrabCursor() { + return this._useGrabCursor; + } + set useGrabCursor(val) { + if (val === this._useGrabCursor) return; + this._useGrabCursor = val; + if (val && this._enabled) { + this._setCursor(CURSOR.GRAB); + } else if (!val) { + this._setCursor(CURSOR.NONE); + } + } + /** + * @copy View360#disableContextMenu + */ + get disableContextMenu() { + return this._disableContextMenu; + } + set disableContextMenu(val) { + if (val === this._disableContextMenu) return; + this._disableContextMenu = val; + if (val && this._enabled) { + this._blockContextMenu(); + } else if (!val) { + this._restoreContextMenu(); + } + } + /** + * @copy View360#disableContextMenu + */ + get scrollable() { + return this._rotateControl.scrollable; + } + set scrollable(val) { + this._rotateControl.scrollable = val; + } + /** + * @copy View360#disableContextMenu + */ + get wheelScrollable() { + return this._zoomControl.scrollable; + } + set wheelScrollable(val) { + this._zoomControl.scrollable = val; + } + /** + * When `true`, disables rotation slow-down by zoom-value. + * @ko `true`일 경우 줌 된 정도에 따라 회전속도를 늦추는 동작을 비활성화합니다. + * @since 4.0.0 + */ + get ignoreZoomScale() { + return this._ignoreZoomScale; + } + set ignoreZoomScale(val) { + this._ignoreZoomScale = val; + } + /** + * Whether the control is enabled or not + * @ko 컨트롤 활성화 여부를 가리키는 값 + * @readonly + * @since 4.0.0 + */ + get enabled() { + return this._enabled; + } + /** + * @copy View360#rotate + */ + get rotate() { + return this._rotateControl; + } + /** + * @copy View360#zoom + */ + get zoom() { + return this._zoomControl; + } + /** + * @copy View360#gyro + */ + get gyro() { + return this._gyroControl; + } + /** + * Whether one of the controls is animating at the moment + * @ko 현재 컨트롤 중 하나라도 동작중인지 여부를 나타내는 값 + * @readonly + * @since 4.0.0 + */ + get animating() { + return this._rotateControl.animating || this._zoomControl.animating || this._gyroControl.animating; + } + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param element - Canvas element {@ko 캔버스 엘리먼트} + * @param camera - Camera instance {@ko Camera 인스턴스} + * @param options - Options for PanoControl {@ko PanoControl 옵션들} + */ + constructor(element, camera, { + useGrabCursor, + scrollable, + wheelScrollable, + disableContextMenu, + rotate, + zoom, + gyro + }) { + this._preventContextMenu = evt => { + evt.preventDefault(); + }; + this._onInputStart = evt => { + if (this._useGrabCursor && !evt.isKeyboard) { + this._setCursor(CURSOR.GRABBING); + } + }; + this._onInputEnd = evt => { + if (this._useGrabCursor && !evt.isKeyboard) { + this._setCursor(CURSOR.GRAB); + } + }; + this._onEnable = ({ + control, + updateCursor + }) => { + if (updateCursor && this._useGrabCursor) { + this._setCursor(CURSOR.GRAB); + } + control.sync(this._camera); + }; + this._onDisable = ({ + updateCursor + }) => { + if (updateCursor) { + this._setCursor(CURSOR.NONE); + } + }; + this._onCameraAnimationEnd = ({ + animation + }) => { + animation.getFinishPromise().then(() => { + this.sync(); + }); + }; + // Bind Options + this._useGrabCursor = useGrabCursor; + this._disableContextMenu = disableContextMenu; + // Set internal values + this._camera = camera; + this._controlEl = element; + this._ignoreZoomScale = false; + this._enabled = false; + this._rotateControl = new RotateControl(element, !rotate, getObjectOption(rotate)); + this._zoomControl = new ZoomControl(element, !zoom, getObjectOption(zoom)); + this._gyroControl = new GyroControl(!gyro, getObjectOption(gyro)); + this._rotateControl.scrollable = scrollable; + this._zoomControl.scrollable = wheelScrollable; + this._bindEvents(); + } + /** + * Destroy the instance and remove all event listeners attached. + * This also will reset CSS cursor to initial. + * @ko 인스턴스를 삭제하고 부착된 모든 이벤트 리스너를 제거합니다. + * 또한, 캔버스에 적용된 CSS cursor도 제거합니다. + * @since 4.0.0 + */ + destroy() { + this.disable(); + this._rotateControl.destroy(); + this._zoomControl.destroy(); + this._setCursor(CURSOR.NONE); + } + /** + * Resize control to match target size. + * @ko 컨트롤이 내부에 캐시하고 있는 크기값을 갱신합니다. + * @param width New width {@ko 변경된 너비} + * @param height New height {@ko 변경된 높이} + * @since 4.0.0 + */ + resize(width, height) { + const camera = this._camera; + this._rotateControl.resize(camera.fov, camera.aspect, width, height); + } + /** + * Enable this control and add event listeners. + * @ko 컨트롤을 활성화하고 이벤트 리스너들을 추가합니다. + * @since 4.0.0 + */ + enable() { + return __awaiter(this, void 0, void 0, function* () { + if (this._enabled) return; + if (!this._rotateControl.enableBlocked) { + this._rotateControl.enable(); + } + if (!this._zoomControl.enableBlocked) { + this._zoomControl.enable(); + } + if (!this._gyroControl.enableBlocked) { + if (yield GyroControl.isAvailable()) { + this._gyroControl.enable(); + } + } + this.sync(); + if (this._disableContextMenu) { + this._blockContextMenu(); + } + this._enabled = true; + }); + } + /** + * Disable this control and remove all event listeners + * @ko 컨트롤을 비활성화하고 모든 이벤트 리스너들을 제거합니다. + * @since 4.0.0 + */ + disable() { + if (!this._enabled) return; + this._rotateControl.disable(); + this._zoomControl.disable(); + this._gyroControl.disable(); + this._restoreContextMenu(); + this._enabled = false; + } + /** + * Update control by given deltaTime + * @ko 컨트롤을 주어진 시간만큼 업데이트합니다. + * @param delta Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위} + * @since 4.0.0 + * @internal + */ + update(delta) { + const camera = this._camera; + const rotateControl = this._rotateControl; + const zoomControl = this._zoomControl; + const gyroControl = this._gyroControl; + zoomControl.update(delta); + const zoom = hfovToZoom(camera.fov, zoomControl.zoom); + // Slow down rotation on zoom-in + const zoomScale = this._ignoreZoomScale ? 1 : Math.max(zoom, 1); + rotateControl.setZoomScale(zoomScale); + rotateControl.updateRange(camera, zoom); + rotateControl.update(delta); + const yaw = rotateControl.yaw; + const pitch = rotateControl.pitch; + if (gyroControl.enabled) { + gyroControl.update(camera, yaw, pitch, zoom); + } else { + camera.lookAt({ + yaw: yaw.val, + pitch: pitch.val, + zoom + }); + } + } + /** + * Synchronize this control's state to current camera state + * @ko 컨트롤을 카메라의 현재 상태와 동기화합니다. + * @since 4.0.0 + */ + sync() { + const camera = this._camera; + this._zoomControl.sync(camera); + this._rotateControl.sync(camera); + } + _blockContextMenu() { + const el = this._controlEl; + el.addEventListener(EVENTS$1.CONTEXT_MENU, this._preventContextMenu); + } + _restoreContextMenu() { + const el = this._controlEl; + el.removeEventListener(EVENTS$1.CONTEXT_MENU, this._preventContextMenu); + } + _setCursor(newCursor) { + if (!this._useGrabCursor && newCursor !== CURSOR.NONE) return; + const targetEl = this._controlEl; + targetEl.style.cursor = newCursor; + } + _bindEvents() { + const rotateControl = this._rotateControl; + const zoomControl = this._zoomControl; + rotateControl.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + rotateControl.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + rotateControl.on(CONTROL_EVENTS.ENABLE, this._onEnable); + rotateControl.on(CONTROL_EVENTS.DISABLE, this._onDisable); + zoomControl.on(CONTROL_EVENTS.ENABLE, this._onEnable); + zoomControl.on(CONTROL_EVENTS.DISABLE, this._onDisable); + this._camera.on(CAMERA_EVENTS.ANIMATION_END, this._onCameraAnimationEnd); + } +} + +/** + * @hidden + */ +class Texture { + constructor({ + width, + height, + flipY + }) { + this.width = width; + this.height = height; + this.flipY = flipY; + this.wrapS = WebGLRenderingContext.CLAMP_TO_EDGE; + this.wrapT = WebGLRenderingContext.CLAMP_TO_EDGE; + } + destroy() { + // DO_NOTHING + } + isVideo() { + return false; + } + isCube() { + return false; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * @hidden + */ +class Texture2D extends Texture { + constructor({ + source, + width, + height, + flipY + }) { + super({ + width, + height, + flipY + }); + this.source = source; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * @hidden + */ +class TextureVideo extends Texture2D { + destroy() { + const video = this.source; + video.pause(); + video.removeAttribute("src"); + video.load(); + } + isVideo() { + return true; + } + isPaused() { + const video = this.source; + return video.paused || video.ended || video.readyState <= 2; + } + hasAudio() { + const video = this.source; + if (video.audioTracks) { + return video.audioTracks.length > 0; + } + if (video.webkitAudioDecodedByteCount != null) { + return video.webkitAudioDecodedByteCount > 0; + } + if (video.mozHasAudio != null) { + return video.mozHasAudio; + } + // We don't know whether the video has audio or not, return true + return true; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * @hidden + */ +class TextureCube extends Texture { + constructor({ + sources, + width, + height, + flipY + }) { + super({ + width, + height, + flipY + }); + this.sources = sources; + } + isCube() { + return true; + } +} + +/** + * @hidden + */ +class TextureLoader { + constructor() { + this._loadChecker = new ImReady(); + } + load(src, video) { + return __awaiter(this, void 0, void 0, function* () { + if (video) { + return this.loadVideo(src, getObjectOption(video)); + } else { + if (Array.isArray(src) && src.length > 1) { + return this.loadCubeImage(src); + } else { + const imgSrc = Array.isArray(src) ? src[0] : src; + return this.loadImage(imgSrc); + } + } + }); + } + loadImage(src) { + return __awaiter(this, void 0, void 0, function* () { + const images = this._toImageArray(src); + return this._load(images, resolve => { + const image = images[0]; + resolve(new Texture2D({ + source: image, + width: image.naturalWidth, + height: image.naturalHeight, + flipY: true + })); + }); + }); + } + loadCubeImage(src) { + return __awaiter(this, void 0, void 0, function* () { + const images = this._toImageArray(src); + return this._load(images, resolve => { + resolve(new TextureCube({ + sources: images, + width: images[0].naturalWidth, + height: images[0].naturalHeight, + flipY: false + })); + }); + }); + } + loadVideo(src, videoConfig) { + return __awaiter(this, void 0, void 0, function* () { + const config = Object.assign({ + autoplay: true, + muted: true, + loop: false, + volume: 1 + }, videoConfig); + const video = this._toVideoElement(src, config); + return this._load([video], resolve => { + const { + autoplay, + muted + } = config; + video.currentTime = 0; + if (autoplay && muted) { + video.play().catch(() => void 0); + } + resolve(new TextureVideo({ + source: video, + width: video.videoWidth, + height: video.videoHeight, + flipY: true + })); + }); + }); + } + _load(content, onLoad) { + const loader = this._loadChecker; + return new Promise((resolve, reject) => { + loader.once("ready", evt => { + if (evt.errorCount > 0) return; + onLoad(resolve); + }); + loader.once("error", reject); + loader.check(content); + }); + } + _toImageArray(src) { + const srcs = Array.isArray(src) ? src : [src]; + return srcs.map(source => { + if (isString(source)) { + const imgEl = new Image(); + imgEl.crossOrigin = "anonymous"; + imgEl.src = source; + return imgEl; + } else { + return source; + } + }); + } + _toVideoElement(src, { + muted, + loop, + volume + }) { + if (src instanceof HTMLVideoElement) { + return src; + } + const video = document.createElement("video"); + video.crossOrigin = "anonymous"; + video.playsInline = true; + video.setAttribute("webkit-playsinline", ""); + video.muted = muted; + video.volume = volume; + video.loop = loop; + if (Array.isArray(src)) { + src.forEach(source => this._appendSourceElement(video, source)); + } else { + this._appendSourceElement(video, src); + } + const sourceCount = video.querySelectorAll("source").length; + if (sourceCount > 0 && video.readyState < 1) { + video.load(); + } + return video; + } + _appendSourceElement(video, src) { + if (src instanceof HTMLSourceElement) { + return src; + } + const sourceEl = document.createElement("source"); + sourceEl.src = src; + video.appendChild(sourceEl); + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * @internal + */ +class FrameAnimator { + /** */ + constructor(maxDeltaTime, context = window) { + this.maxDeltaTime = maxDeltaTime; + this._context = context; + this._rafId = -1; + this._rafTimer = -1; + this._lastUpdateTime = -1; + } + start(callback) { + const context = this._context; + // No context / callback set + if (!context || !callback) return; + // Animation already started + if (this._rafId >= 0 || this._rafTimer >= 0) return; + const loop = (_time, frame) => { + const time = Date.now(); + const delta = Math.min(time - this._lastUpdateTime, this.maxDeltaTime * 1000); + callback(delta, frame); + this._lastUpdateTime = time; + this._rafId = context.requestAnimationFrame(loop); + }; + this._lastUpdateTime = Date.now(); + this._rafId = context.requestAnimationFrame(loop); + } + stop() { + if (this._rafId >= 0) { + this._context.cancelAnimationFrame(this._rafId); + } + if (this._rafTimer >= 0) { + clearTimeout(this._rafTimer); + } + this._rafId = -1; + this._rafTimer = -1; + } + changeContext(context) { + this.stop(); + this._context = context; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Automatic resizer that uses both ResizeObserver and window resize event + */ +class AutoResizer { + get useResizeObserver() { + return this._useResizeObserver; + } + /** + * Returns whether AutoResizer is enabled + */ + get enabled() { + return this._enabled; + } + /** */ + constructor(useResizeObserver, onResize) { + // eslint-disable-next-line @typescript-eslint/member-ordering + this._skipFirstResize = (() => { + let isFirstResize = true; + return () => { + if (isFirstResize) { + isFirstResize = false; + return; + } + this._onResize(); + }; + })(); + this._useResizeObserver = useResizeObserver; + this._enabled = false; + this._resizeObserver = null; + this._onResize = onResize; + } + /** + * Enable resizer + */ + enable(element) { + if (this._enabled) { + this.disable(); + } + if (this._useResizeObserver && !!window.ResizeObserver) { + const bbox = element.getBoundingClientRect(); + const resizeImmediate = bbox.width !== 0 || bbox.height !== 0; + const resizeObserver = new ResizeObserver(resizeImmediate ? this._skipFirstResize : this._onResize); + resizeObserver.observe(element); + this._resizeObserver = resizeObserver; + } else { + window.addEventListener(EVENTS$1.RESIZE, this._onResize); + } + this._enabled = true; + return this; + } + /** + * Disable resizer + */ + disable() { + if (!this._enabled) return this; + const resizeObserver = this._resizeObserver; + if (resizeObserver) { + resizeObserver.disconnect(); + this._resizeObserver = null; + } else { + window.removeEventListener(EVENTS$1.RESIZE, this._onResize); + } + this._enabled = false; + return this; + } +} + +/** + * A manager class for autoplay feature. + * @ko Autoplay 기능의 매니저 클래스. + * @since 4.0.0 + */ +class Autoplay { + /** + * Whether autoplay is enabled or not + * @ko 자동재생 활성화 여부를 나타내는 값 + * @readonly + * @since 4.0.0 + */ + get enabled() { + return this._enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * Whether autoplay is updating the camera at the moment + * @ko 현재 자동재생이 동작중인지 여부를 나타내는 값 + * @readonly + * @since 4.0.0 + */ + get playing() { + return this._enabled && !this._interrupted; + } + /** + * Reactivation delay after mouse input in milisecond. + * @ko 재활성화되기까지의 시간 (밀리초 단위) + * @default 2000 + * @since 4.0.0 + */ + get delay() { + return this._delay; + } + set delay(val) { + this._delay = val; + } + /** + * Reactivation delay after mouse leave when using {@link AutoplayOptions#pauseOnHover} + * @ko {@link AutoplayOptions#pauseOnHover} 사용시 마우스가 캔버스 영역을 떠난 뒤 자동재생이 다시 활성화되기까지의 시간 + * @default 0 + * @since 4.0.0 + */ + get delayOnMouseLeave() { + return this._delayOnMouseLeave; + } + set delayOnMouseLeave(val) { + this._delayOnMouseLeave = val; + } + /** + * Y-axis(yaw) rotation speed + * @ko Y-축 회전(yaw)의 속도 + * @default 1 + * @since 4.0.0 + */ + get speed() { + return this._speed; + } + set speed(val) { + this._speed = val; + } + /** + * Whether to pause rotation on mouse hover + * @ko 마우스가 캔버스 영역에 들어왔을 때 자동재생을 정지할지 여부 + * @default false + * @since 4.0.0 + */ + get pauseOnHover() { + return this._pauseOnHover; + } + set pauseOnHover(val) { + this._pauseOnHover = val; + } + /** + * Whether user can interrupt the rotation with click/wheel input + * @ko 클릭이나 휠같은 사용자 인터랙션시 자동재생을 멈출지 여부 + * @default true + * @since 4.0.0 + */ + get canInterrupt() { + return this._canInterrupt; + } + set canInterrupt(val) { + this._canInterrupt = val; + } + /** + * Whether to disable autoplay on user interrupt + * @ko 사용자 동작에 의해 자동재생이 정지할 때, {@link Autoplay#disable}을 호출하여 자동재생을 영구히 정지할지 여부 + * @default false + * @since 4.0.0 + */ + get disableOnInterrupt() { + return this._disableOnInterrupt; + } + set disableOnInterrupt(val) { + this._disableOnInterrupt = val; + } + /** + * Create new AutoPlayer instance + * @param camera - Instance of the {@link Camera} {@ko Camera의 인스턴스} + * @param element - Canvas element {@ko 캔버스 엘리먼트} + * @param options - Autoplay options {@ko 자동재생 옵션들} + * @since 4.0.0 + */ + constructor(viewer, element, options) { + this._onInputStart = () => { + if (!this._canInterrupt) return; + this._interrupted = true; + this._clearTimeout(); + }; + this._onInputEnd = () => { + this._setUninterruptedAfterDelay(this._delay); + }; + this._onGyroEnable = () => { + this.disable(); + }; + this._onMouseEnter = () => { + if (!this._pauseOnHover) return; + this._interrupted = true; + this._hovering = true; + }; + this._onMouseLeave = () => { + if (!this._pauseOnHover) return; + this._hovering = false; + this._setUninterruptedAfterDelay(this._delayOnMouseLeave); + }; + this._camera = viewer.camera; + this._control = viewer.control; + this._element = element; + this._enabled = false; + this._interrupted = false; + this._interruptionTimer = -1; + this._hovering = false; + const { + delay = 2000, + delayOnMouseLeave = 0, + speed = 1, + pauseOnHover = false, + canInterrupt = true, + disableOnInterrupt = false + } = getObjectOption(options); + this._enableBlocked = !options; + this._delay = delay; + this._delayOnMouseLeave = delayOnMouseLeave; + this._speed = speed; + this._pauseOnHover = pauseOnHover; + this._canInterrupt = canInterrupt; + this._disableOnInterrupt = disableOnInterrupt; + } + /** + * Destroy the instance and remove all event listeners attached + * @ko 인스턴스를 제거하고 연결된 모든 이벤트 핸들러를 삭제합니다. + * @since 4.0.0 + */ + destroy() { + this.disable(); + } + /** + * Rotate camera by given deltaTime + * @ko 주어진 deltaTime만큼 카메라를 회전시킵니다. + * @param deltaTime - Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위} + * @since 4.0.0 + */ + update(deltaTime) { + if (!this._enabled) return; + if (this._interrupted) { + if (this._disableOnInterrupt) { + this.disable(); + } + return; + } + const camera = this._camera; + const delta = -this._speed * deltaTime / 100; + camera.yaw = circulate(camera.yaw + delta, 0, 360); + } + /** + * Enable autoplay and add event listeners. + * @ko 자동재생을 활성화하고 이벤트리스너들을 추가합니다. + * @since 4.0.0 + */ + enable() { + const control = this._control; + const element = this._element; + if (this._enabled || control.gyro.enabled) return; + control.rotate.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.rotate.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.zoom.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.zoom.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.gyro.on(CONTROL_EVENTS.ENABLE, this._onGyroEnable); + element.addEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter, false); + element.addEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave, false); + this._enabled = true; + this._enableBlocked = false; + } + /** + * Enable autoplay after current `delay` value. + * @ko 현재의 `delay`값만큼 시간이 지난 다음에 자동재생을 활성화합니다. + * @since 4.0.0 + */ + enableAfterDelay() { + this.enable(); + this._interrupted = true; + this._setUninterruptedAfterDelay(this._delay); + } + /** + * Disable autoplay and remove all event handlers. + * @ko 자동재생을 비활성화하고 모든 이벤트 핸들러를 제거합니다. + * @since 4.0.0 + */ + disable() { + if (!this._enabled) return; + const control = this._control; + const element = this._element; + control.rotate.off(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.rotate.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.zoom.off(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.zoom.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.gyro.off(CONTROL_EVENTS.ENABLE, this._onGyroEnable); + element.removeEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter, false); + element.removeEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave, false); + this._enabled = false; + this._interrupted = false; + this._hovering = false; + this._clearTimeout(); + } + _setUninterruptedAfterDelay(delay) { + if (this._hovering) return; + this._clearTimeout(); + if (delay > 0) { + this._interruptionTimer = window.setTimeout(() => { + this._interrupted = false; + this._interruptionTimer = -1; + }, delay); + } else { + this._interrupted = false; + this._interruptionTimer = -1; + } + } + _clearTimeout() { + if (this._interruptionTimer >= 0) { + window.clearTimeout(this._interruptionTimer); + this._interruptionTimer = -1; + } + } +} + +/** + * WebXR manager class + * @ko WebXR 매니저 클래스 + * @since 4.0.0 + */ +class XRManager extends Component { + /** + * Create new instance. + * 새 인스턴스를 생성합니다. + * @param ctx - Instance of WebGL context helper {@ko WebGL 콘텍스트 헬퍼의 인스턴스} + * @param options - Options {@ko 옵션들} + */ + constructor(ctx, options = {}) { + super(); + /** + * Destroy instance and end XR session if there was any. + * @ko 인스턴스를 제거하고, XR 세션이 존재할 경우 종료합니다. + * @since 4.0.0 + */ + this.destroy = () => { + this.exit(); + this.off(); + }; + this._onSessionEnd = () => { + this.exit(); + this.trigger(EVENTS.VR_END); + }; + this._xrSession = null; + this._xrRefSpace = null; + this._ctx = ctx; + this._options = options; + } + /** + * Returns WebXR availability. + * @ko WebXR 사용 가능 여부를 반환합니다. + * @since 4.0.0 + */ + isAvailable() { + return __awaiter(this, void 0, void 0, function* () { + // eslint-disable-next-line compat/compat + const xr = window.navigator.xr; + if (!xr) return false; + return xr.isSessionSupported(SESSION_VR).then(available => { + return available; + }).catch(() => { + return false; + }); + }); + } + /** + * Enter VR session + * @ko VR 세션에 진입합니다. + * @since 4.0.0 + */ + enter() { + return __awaiter(this, void 0, void 0, function* () { + const ctx = this._ctx; + // eslint-disable-next-line compat/compat + const xr = window.navigator.xr; + if (!xr) return; + yield GyroControl.requestSensorPermission(); + const options = Object.assign({ + requiredFeatures: [XR_REFERENCE_SPACE] + }, this._options); + yield ctx.makeXRCompatible(); + const session = yield xr.requestSession(SESSION_VR, options); + ctx.bindXRLayer(session); + const refSpace = yield session.requestReferenceSpace(XR_REFERENCE_SPACE); + this._setSession(session, refSpace); + this.trigger(EVENTS.VR_START, { + session + }); + }); + } + /** + * Exit VR session + * @ko VR 세션에서 나갑니다. + * @since 4.0.0 + */ + exit() { + const xrSession = this._xrSession; + if (xrSession) { + xrSession.end().catch(() => void 0); + } + this._xrSession = null; + this._xrRefSpace = null; + } + /** + * @hidden + */ + canRender(frame) { + const refSpace = this._xrRefSpace; + if (!refSpace) return false; + const pose = frame.getViewerPose(refSpace); + return !!pose; + } + /** + * @hidden + */ + getEyeParams(frame) { + const session = frame.session; + const pose = frame.getViewerPose(this._xrRefSpace); + if (!pose) return null; + const glLayer = session.renderState.baseLayer; + if (!glLayer) return null; + return pose.views.map(view => { + const viewport = glLayer.getViewport(view); + const vMatrix = view.transform.inverse.matrix; + return { + viewport, + vMatrix, + pMatrix: view.projectionMatrix + }; + }); + } + _setSession(session, refSpace) { + this._xrSession = session; + this._xrRefSpace = refSpace; + session.addEventListener(EVENTS$1.XR_END, this._onSessionEnd); + } +} + +/** + * Hotspot data + * @ko 핫스팟 데이터 + * @since 4.0.0 + */ +class Hotspot { + constructor(element, position) { + this.element = element; + this.position = position; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Hotspot renderer + * @ko Hotspot 렌더러 + * @since 4.0.0 + */ +class HotspotRenderer { + /** + * Create new instance + * @ko 새 인스턴스를 생성합니다. + * @param rootEl - Container element for hotspots {@ko 핫스팟들의 컨테이너 엘리먼트} + * @param renderer - instance of WebGLRenderer {@ko WebGLRenderer의 인스턴스} + * @param options - Hotspot options {@ko Hotspot 옵션들 } + */ + constructor(rootEl, renderer, { + zoom = false + }) { + this._containerEl = getNullableElement(`.${DEFAULT_CLASS.HOTSPOT_CONTAINER}`, rootEl); + this._renderer = renderer; + this._hotspots = []; + this._zoom = zoom; + } + /** + * Refresh hotspots by collecting hotspot elements from current hotspot root element + * @ko 현재 핫스팟 루트 엘리먼트 내에서 핫스팟 엘리먼트들을 수집하여 갱신합니다. + * @throws {ERROR_CODES.INSUFFICIENT_ARGS} if data-position doesn't include all x, y, z values {@ko data-position이 x, y, z좌표를 전부 포함하고 있지 않을 때} + */ + refresh() { + const container = this._containerEl; + if (!container) return; + const hotspotEls = [].slice.apply(container.querySelectorAll(`.${DEFAULT_CLASS.HOTSPOT}`)); + this._hotspots = hotspotEls.map(el => this._parseHotspot(el)); + } + /** + * Render hotspots + * @ko 핫스팟들을 렌더링합니다. + * @param camera - Instance of Camera {@ko Camera의 인스턴스} + */ + render(camera) { + const hotspots = this._hotspots; + const halfWidth = this._renderer.width * 0.5; + const halfHeight = this._renderer.height * 0.5; + const zoom = camera.zoom; + const centerTransform = "translate(-50%, -50%)"; + const zoomTransform = this._zoom ? `scale(${zoom})` : ""; + hotspots.forEach(hotspot => { + const position = hotspot.position; + const relPos = vec3.create(); + vec3.copy(relPos, position); + vec3.transformMat4(relPos, relPos, camera.viewMatrix); + vec3.transformMat4(relPos, relPos, camera.projectionMatrix); + if (relPos[2] > 1 || relPos[2] < 0) { + hotspot.element.classList.remove(DEFAULT_CLASS.HOTSPOT_VISIBLE); + return; + } + const screenPos = vec2.fromValues(relPos[0] * halfWidth + halfWidth, -relPos[1] * halfHeight + halfHeight); + hotspot.element.classList.add(DEFAULT_CLASS.HOTSPOT_VISIBLE); + hotspot.element.style.transform = [centerTransform, `translate(${screenPos[0]}px, ${screenPos[1]}px)`, zoomTransform].join(" "); + }); + } + _parseHotspot(element) { + const yawStr = element.dataset.yaw; + const pitchStr = element.dataset.pitch; + const positionStr = element.dataset.position; + if (yawStr || pitchStr) { + const yaw = yawStr ? parseFloat(yawStr) : 0; + const pitch = pitchStr ? parseFloat(pitchStr) : 0; + const position = this._yawPitchToVec3(yaw, pitch); + return new Hotspot(element, position); + } else if (positionStr) { + const pos = positionStr.split(" ").map(val => parseFloat(val)); + if (pos.length < 3) { + throw new View360Error(ERROR.MESSAGES.INSUFFICIENT_ARGS(positionStr, "hotspot attribute \"data-position\""), ERROR.CODES.INSUFFICIENT_ARGS); + } + return new Hotspot(element, vec3.fromValues(pos[0], pos[1], pos[2])); + } else { + // Place hotspot at yaw: 0, pitch: 0 + const defaultPos = vec3.fromValues(0, 0, -1); + return new Hotspot(element, defaultPos); + } + } + _yawPitchToVec3(yaw, pitch) { + const yawRad = yaw * DEG_TO_RAD; + const pitchRad = pitch * DEG_TO_RAD; + const position = vec3.create(); + position[1] = Math.sin(pitchRad); + position[2] = Math.cos(pitchRad); + position[0] = position[2] * Math.sin(-yawRad); + position[2] = -position[2] * Math.cos(-yawRad); + return position; + } +} + +/** + * @hidden + */ +class VertexArrayObject { + get count() { + return this.geometry.indicies.count; + } + constructor(obj, geometry, buffers) { + this.obj = obj; + this.geometry = geometry; + this.buffers = buffers; + } +} + +/** + * @hidden + */ +class WebGLContext { + get canvas() { + return this._canvas; + } + get maxTextureSize() { + return this._maxTextureSize; + } + get isWebGL2() { + return this._isWebGL2; + } + get supportVAO() { + return this._isWebGL2 || !!this._extensions.vao; + } + get lost() { + return this._contextLost; + } + get debug() { + return this._debug; + } + constructor(canvas, debug) { + this._onContextLost = () => { + const canvas = this._canvas; + canvas.classList.add(DEFAULT_CLASS.CTX_LOST); + this._contextLost = true; + }; + this._onContextRestore = () => { + const canvas = this._canvas; + canvas.classList.remove(DEFAULT_CLASS.CTX_LOST); + this._contextLost = false; + }; + this._canvas = canvas; + this._contextLost = false; + this._debug = debug; + this._extensions = { + vao: null, + loseContext: null + }; + } + init() { + const canvas = this._canvas; + const { + gl, + isWebGL2 + } = this._getContext(canvas); + this._gl = gl; + this._maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); + this._isWebGL2 = isWebGL2; + if (!this._isWebGL2) { + this._extensions.vao = gl.getExtension("OES_vertex_array_object"); + } + this._extensions.loseContext = gl.getExtension("WEBGL_lose_context"); + canvas.addEventListener(EVENTS$1.CONTEXT_LOST, this._onContextLost); + canvas.addEventListener(EVENTS$1.CONTEXT_RESTORED, this._onContextRestore); + // gl.enable(gl.DEPTH_TEST); + } + + destroy() { + const gl = this._gl; + const canvas = this._canvas; + if (gl) { + // gl is not defined when destroy is called before init + gl.bindBuffer(gl.ARRAY_BUFFER, null); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + } + canvas.removeEventListener(EVENTS$1.CONTEXT_LOST, this._onContextLost); + canvas.removeEventListener(EVENTS$1.CONTEXT_RESTORED, this._onContextRestore); + } + forceLoseContext() { + const extension = this._extensions.loseContext; + if (!extension) return; + extension.loseContext(); + } + forceRestoreContext() { + const extension = this._extensions.loseContext; + if (!extension) return; + extension.restoreContext(); + } + clear() { + const gl = this._gl; + gl.clear(gl.COLOR_BUFFER_BIT); + } + resize() { + const gl = this._gl; + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + } + viewport(x, y, width, height) { + const gl = this._gl; + gl.viewport(x, y, width, height); + } + createVAO(geometry, shaderProgram) { + const nativeVAO = this._createNativeVAO(); + const vao = new VertexArrayObject(nativeVAO, geometry, { + indicies: this._createBuffer(), + position: this._createBuffer(), + uv: this._createBuffer() + }); + if (nativeVAO) { + this._bindNativeVAO(nativeVAO); + this._supplyGeometryData(vao, shaderProgram); + this._bindNativeVAO(null); + this._unbindBuffers(); + } + return vao; + } + draw(vao, shaderProgram) { + const gl = this._gl; + if (vao.obj) { + this._bindNativeVAO(vao.obj); + } else { + this._supplyGeometryData(vao, shaderProgram); + } + gl.drawElements(gl.TRIANGLES, vao.count, gl.UNSIGNED_SHORT, 0); + if (vao.obj) { + this._bindNativeVAO(null); + } else { + this._unbindBuffers(); + } + } + releaseVAO(vao) { + if (vao.obj) { + this._deleteNativeVAO(vao.obj); + } + this._deleteBuffer(vao.buffers.indicies); + this._deleteBuffer(vao.buffers.position); + this._deleteBuffer(vao.buffers.uv); + } + getUniformLocations(program, uniforms) { + const gl = this._gl; + const uniformLocations = Object.keys(uniforms).reduce((locations, key) => { + locations[key] = gl.getUniformLocation(program, key); + return locations; + }, {}); + return Object.assign(Object.assign({}, this._getCommonUniformLocations(program)), uniformLocations); + } + updateCommonUniforms(entity, camera, shaderProgram) { + const gl = this._gl; + const uniformLocations = shaderProgram.uniformLocations; + // We're using "matrix"(=local matrix) here for efficiency + // As projection doesn't require world matrix, as it doesn't have any parent or child + const matrix = entity.matrix; + const mvMatrix = mat4.create(); + mat4.multiply(mvMatrix, camera.viewMatrix, matrix); + gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix); + gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, camera.projectionMatrix); + } + updateVRUniforms(shaderProgram, mvMatrix, pMatrix, eyeIndex) { + const gl = this._gl; + const uniformLocations = shaderProgram.uniformLocations; + gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix); + gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, pMatrix); + if (uniformLocations.uEye) { + gl.uniform1f(uniformLocations.uEye, eyeIndex); + } + } + updateUniforms(shaderProgram) { + const gl = this._gl; + const uniforms = shaderProgram.uniforms; + const uniformLocations = shaderProgram.uniformLocations; + for (const key in uniforms) { + const uniform = uniforms[key]; + const location = uniformLocations[key]; + if (!uniform) continue; + if (uniform.needsUpdate) { + uniform.update(gl, location, this._isWebGL2); + } + } + } + releaseShaderResources(shaderProgram) { + const gl = this._gl; + const uniforms = shaderProgram.uniforms; + for (const key in uniforms) { + const uniform = uniforms[key]; + if (!uniform) continue; + if (uniform.needsUpdate) { + uniform.destroy(gl); + } + } + gl.deleteProgram(shaderProgram.program); + } + useProgram(shaderProgram) { + const gl = this._gl; + gl.useProgram(shaderProgram.program); + } + createProgram(vertexShader, fragmentShader) { + const gl = this._gl; + const program = gl.createProgram(); + const vs = this._compileShader(gl.VERTEX_SHADER, vertexShader); + const fs = this._compileShader(gl.FRAGMENT_SHADER, fragmentShader); + gl.attachShader(program, vs); + gl.attachShader(program, fs); + gl.bindAttribLocation(program, 0, "position"); + gl.bindAttribLocation(program, 1, "uv"); + gl.linkProgram(program); + if (this._debug && !gl.getProgramParameter(program, gl.LINK_STATUS)) { + let shaderLog = null; + if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) { + shaderLog = gl.getShaderInfoLog(vs); + } else if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) { + shaderLog = gl.getShaderInfoLog(fs); + } + throw new View360Error(ERROR.MESSAGES.FAILED_LINKING_PROGRAM(gl.getProgramInfoLog(program), shaderLog), ERROR.CODES.FAILED_LINKING_PROGRAM); + } + gl.deleteShader(vs); + gl.deleteShader(fs); + return program; + } + createWebGLTexture(texData) { + const gl = this._gl; + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texData.wrapS); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texData.wrapT); + if (!texData.isVideo() && this._isWebGL2) { + const gl2 = gl; + gl2.texStorage2D(gl2.TEXTURE_2D, 1, gl2.RGBA8, texData.width, texData.height); + } + return texture; + } + createWebGLCubeTexture(texData, size) { + const gl = this._gl; + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, texData.wrapS); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, texData.wrapT); + if (this._isWebGL2) { + const gl2 = gl; + gl2.texStorage2D(gl2.TEXTURE_CUBE_MAP, 1, gl2.RGBA8, size, size); + } + return texture; + } + makeXRCompatible() { + return __awaiter(this, void 0, void 0, function* () { + const gl = this._gl; + const attributes = gl.getContextAttributes(); + if (attributes && attributes.xrCompatible !== true) { + yield gl.makeXRCompatible(); + } + }); + } + bindXRLayer(session) { + const gl = this._gl; + const xrLayer = new XRWebGLLayer(session, gl); + session.updateRenderState({ + baseLayer: xrLayer + }); + } + bindXRFrame(frame) { + const gl = this._gl; + const session = frame.session; + const baseLayer = session.renderState.baseLayer; + gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer); + } + useDefaultFrameBuffer() { + const gl = this._gl; + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + } + _createBuffer() { + return this._gl.createBuffer(); + } + _deleteBuffer(buffer) { + return this._gl.deleteBuffer(buffer); + } + _createNativeVAO() { + const gl = this._gl; + if (this._isWebGL2) { + return gl.createVertexArray(); + } else { + const ext = this._extensions.vao; + return (ext === null || ext === void 0 ? void 0 : ext.createVertexArrayOES()) || null; + } + } + _bindNativeVAO(vao) { + const gl = this._gl; + if (this._isWebGL2) { + gl.bindVertexArray(vao); + } else { + const ext = this._extensions.vao; + ext === null || ext === void 0 ? void 0 : ext.bindVertexArrayOES(vao); + } + } + _deleteNativeVAO(vao) { + const gl = this._gl; + if (this._isWebGL2) { + gl.deleteVertexArray(vao); + } else { + const ext = this._extensions.vao; + ext === null || ext === void 0 ? void 0 : ext.deleteVertexArrayOES(vao); + } + } + _supplyGeometryData(vao, shaderProgram) { + const geometry = vao.geometry; + this._supplyIndiciesData(geometry.indicies, vao.buffers.indicies); + this._supplyAttributeData(geometry.vertices, shaderProgram.program, "position", vao.buffers.position); + this._supplyAttributeData(geometry.uvs, shaderProgram.program, "uv", vao.buffers.uv); + } + _unbindBuffers() { + const gl = this._gl; + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + gl.bindBuffer(gl.ARRAY_BUFFER, null); + } + _supplyIndiciesData(indicies, buffer) { + const gl = this._gl; + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicies.data, gl.STATIC_DRAW); + } + _supplyAttributeData(attribute, program, name, buffer) { + const gl = this._gl; + const attribLocation = gl.getAttribLocation(program, name); + // Attribute not used + if (attribLocation < 0) return; + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData(gl.ARRAY_BUFFER, attribute.data, gl.STATIC_DRAW); + gl.vertexAttribPointer(attribLocation, attribute.itemSize, gl.FLOAT, false, 0, 0); + gl.enableVertexAttribArray(attribLocation); + } + _compileShader(type, src) { + const gl = this._gl; + const shader = gl.createShader(type); + gl.shaderSource(shader, src); + gl.compileShader(shader); + return shader; + } + _getCommonUniformLocations(program) { + const gl = this._gl; + return { + uMVMatrix: gl.getUniformLocation(program, "uMVMatrix"), + uPMatrix: gl.getUniformLocation(program, "uPMatrix") + }; + } + _getContext(canvas) { + const webglIdentifiers = ["webgl2", "webgl", "experimental-webgl", "webkit-3d", "moz-webgl"]; + let context = null; + let isWebGL2 = false; + const contextAttributes = { + preserveDrawingBuffer: false, + antialias: false + }; + const onWebglContextCreationError = e => e.statusMessage; + canvas.addEventListener(EVENTS$1.CONTEXT_CREATE_ERROR, onWebglContextCreationError); + for (const identifier of webglIdentifiers) { + try { + context = canvas.getContext(identifier, contextAttributes); + isWebGL2 = identifier === "webgl2"; + } catch (t) {} // eslint-disable-line no-empty + if (context) { + break; + } + } + canvas.removeEventListener(EVENTS$1.CONTEXT_CREATE_ERROR, onWebglContextCreationError); + if (!context) { + throw new View360Error(ERROR.MESSAGES.WEBGL_NOT_SUPPORTED, ERROR.CODES.WEBGL_NOT_SUPPORTED); + } + return { + gl: context, + isWebGL2 + }; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Projection renderer, based on WebGL + * @ko WebGL 기반의 프로젝션 렌더러 + * @since 4.0.0 + */ +class WebGLRenderer { + /** + * Canvas element + * @ko 캔버스 엘리먼트 + * @since 4.0.0 + */ + get canvas() { + return this._canvas; + } + /** + * Canvas's width (`devicePixelRatio` is not applied) + * @ko 캔버스의 보이는 너비 (`devicePixelRatio`가 적용되지 않은) + * @since 4.0.0 + */ + get width() { + return this._elementSize.x; + } + /** + * Canvas's height (`devicePixelRatio` is not applied) + * @ko 캔버스의 높이 (`devicePixelRatio`가 적용되지 않은) + * @since 4.0.0 + */ + get height() { + return this._elementSize.y; + } + /** + * Current `devicePixelRatio` value. + * @ko 현재 `devicePixelRatio` 값. + * @since 4.0.0 + * @example + * ```js + * cosnt renderingWidth = view360.renderer.width * view360.renderer.pixelRatio; + * ``` + */ + get pixelRatio() { + return this._pixelRatio; + } + /** + * Width / height ratio (= width / height) + * @ko 너비 / 높이의 비율 (= width / height) + * @since 4.0.0 + * @example + * ```js + * const aspect = view360.renderer.width / view360.renderer.pixelRatio; + * assert(aspect === view360.renderer.aspect); + * ``` + */ + get aspect() { + return this._elementSize.x / this._elementSize.y; + } + /** + * Create new instance + * @ko 새 인스턴스를 생성합니다. + * @param canvas - Canvas element {@ko 캔버스 엘리먼트} + * @param debug - Whether to enable WebGL debugging {@ko WebGL debug 활성화 여부 } + */ + constructor(canvas, debug) { + this._canvas = canvas; + this._elementSize = { + x: 0, + y: 0 + }; + this._pixelRatio = 1; + this.ctx = new WebGLContext(canvas, debug); + } + /** + * Destroy instance and release all resources. + * @ko 인스턴스를 제거하고 사용된 리소스를 전부 해제합니다. + * @since 4.0.0 + */ + destroy() { + const canvas = this._canvas; + this.ctx.destroy(); + canvas.width = 1; + canvas.height = 1; + } + /** + * Resize canvas and renew inner size cache. + * @ko 캔버스의 크기를 재계산해서 내부의 사이즈 캐시값을 갱신합니다. + * @since 4.0.0 + */ + resize() { + const canvas = this._canvas; + const canvasSize = this._elementSize; + const devicePixelRatio = window.devicePixelRatio; + canvasSize.x = canvas.clientWidth; + canvasSize.y = canvas.clientHeight; + canvas.width = canvasSize.x * devicePixelRatio; + canvas.height = canvasSize.y * devicePixelRatio; + this._pixelRatio = devicePixelRatio; + this.ctx.resize(); + } + /** + * Render projection + * @ko 프로젝션을 렌더링합니다. + * @param projection - Projection to render {@ko 렌더링할 프로젝션} + * @param cameraa - Camera instance {@ko 카메라의 인스턴스} + * @since 4.0.0 + */ + render(projection, camera) { + const ctx = this.ctx; + const mesh = projection.getMesh(); + if (ctx.lost || !mesh) return; + ctx.clear(); + ctx.useProgram(mesh.program); + ctx.updateCommonUniforms(mesh, camera, mesh.program); + projection.update(camera); + ctx.updateUniforms(mesh.program); + ctx.draw(mesh.vao, mesh.program); + } + /** + * Render VR frame, only used for rendering frames inside VR sessions. + * @ko VR 프레임을 렌더링합니다. VR 세션 진입 도중에만 사용됩니다. + * @internal + * @param projection - Projection to render {@ko 렌더링할 프로젝션} + * @param vr - Instance of XRManager {@ko XRManager의 인스턴스} + * @param frame - VR frame {@ko VR 프레임} + * @since 4.0.0 + */ + renderVR(projection, vr, frame) { + const ctx = this.ctx; + const mesh = projection.getMesh(); + const eyeParams = vr.getEyeParams(frame); + if (!eyeParams || !mesh) return; + ctx.bindXRFrame(frame); + ctx.useProgram(mesh.program); + ctx.updateUniforms(mesh.program); + eyeParams.forEach((eye, eyeIndex) => { + const viewport = eye.viewport; + // We're using "mesh.matrix"(=local matrix) here for efficiency + // As projection doesn't require world matrix, as it doesn't have any parent or child + const mvMatrix = mat4.multiply(mat4.create(), eye.vMatrix, mesh.matrix); + ctx.viewport(viewport.x, viewport.y, viewport.width, viewport.height); + ctx.updateVRUniforms(mesh.program, mvMatrix, eye.pMatrix, eyeIndex); + ctx.draw(mesh.vao, mesh.program); + }); + } +} + +/** + * Panorama 360 image viewer + * @ko 파노라마 360 이미지 뷰어 + * @since 4.0.0 + * @see View360Options + * @see View360Events + */ +class View360 extends Component { + /** + * Root element (`.view360-container`) + * @ko 루트 엘리먼트 (`.view360-container`) + * @since 4.0.0 + * @readonly + * @example + * ```html + *
+ * + *
+ * ``` + * ```ts + * import View360 from "@egjs/view360"; + * + * const viewer = new View360("#viewer"); + * console.log(viewer.rootEl); // Element with id "viewer" + * ``` + */ + get rootEl() { + return this._rootEl; + } + /** + * Projection renderer. + * @ko 프로젝션 렌더러. + * @since 4.0.0 + * @readonly + */ + get renderer() { + return this._renderer; + } + /** + * Projection camera. + * @ko 프로젝션 카메라. + * @since 4.0.0 + * @readonly + */ + get camera() { + return this._camera; + } + /** + * Rotate/Zoom Controller. + * @ko 회전/줌 컨트롤러. + * @since 4.0.0 + * @readonly + */ + get control() { + return this._control; + } + /** + * WebXR-based VR manager. + * @ko WebXR 기반의 VR 기능 매니저 인스턴스. + * @since 4.0.0 + * @readonly + * @example + * ```ts + * // Example: Enter VR + * // This must be called on user interaction, else will be rejected. + * viewer.vr.enter(); + * ``` + */ + get vr() { + return this._vr; + } + /** + * Hotspot renderer. + * You can also change options of {@link View360Options#hotspot} with this. + * @ko 핫스팟 렌더러 인스턴스. + * {@link View360Options#hotspot} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get hotspot() { + return this._hotspot; + } + /** + * An array of plugins added. + * @ko 추가된 플러그인의 배열 + * @since 4.0.0 + * @readonly + * @example + * ```ts + * const viewer = new View360("#el_id", { + * plugins: [new ControlBar()] + * }); + * + * console.log(viewer.plugins); // [ControlBar] + * + * viewer.addPlugins(new LoadingSpinner()) // [ControlBar, LoadingSpinner]; + * ``` + */ + get plugins() { + return this._plugins; + } + /** + * A instance of {@link Projection} that currently enabled. `null` if not initialized yet. + * You should call {@link View360#load} to change panorama src or projection type. + * @ko 현재 사용중인 {@link Projection}의 인스턴스. 프로젝션을 활성화하지 않았을 경우 `null`입니다. + * 파노라마 이미지 소스나 프로젝션 타입을 변경하려면 {@link View360#load}를 호출하면 됩니다. + * @since 4.0.0 + * @readonly + * @example + * ```ts + * const viewer = new View360 + * ``` + */ + get projection() { + return this._projection; + } + set projection(val) { + if (this._initialized && val) { + this.load(val); + } else { + this._projection = val; + } + } + /** + * A boolean value whether {@link View360#init init()} is called before. + * @ko {@link View360#init init()}이 호출되었는지 여부를 가리키는 값 + * @since 4.0.0 + * @readonly + * @example + * ```ts + * const viewer = new View360("#el", { autoInit: false }); + * + * console.log(viewer.initialized); // false + * + * await viewer.init(); + * + * console.log(viewer.initialized); // true + * ``` + */ + get initialized() { + return this._initialized; + } + /** + * Instance of the Autoplay manager. + * You can also change {@link View360Options#autoplay} options with this. + * @ko Autoplay 기능의 매니저 인스턴스. + * 이 인스턴스를 통해 {@link View360Options#autoplay} 옵션을 변경하는 것도 가능합니다. + * @since 4.0.0 + * @readonly + * @example + * ```ts + * // Disable autoplay + * viewer.autoplay.disable(); + * ``` + */ + get autoplay() { + return this._autoplay; + } + /** + * When this value is `true` and {@link View360Options#projection} is set, {@link View360#init init()} will be called automatically when instance is created. + * @ko 이 값이 `true`이고, {@link View360Options#projection}이 설정되었으면, 인스턴스 생성 시점에 자동으로 {@link View360#init init()}을 호출합니다. + * @default true + * @since 4.0.0 + * @example + * ```ts + * import View360, { EquirectProjection, EVENTS } from "@egjs/view360"; + * + * // viewer.init() is called on instance creation + * // But as `init` is asynchronous, you should wait for "ready" event if you want to do something after initialization. + * const viewer = new View360("#el_id", { + * autoInit: true, + * projection: new EquirectProjection({ src: "SRC_TO_URL" }) + * }); + * + * console.log(viewer.initialized); // false, as `init` is asynchronous + * + * viewer.once(EVENTS.READY, () => { + * console.log(viewer.initialized); // true + * }); + * ``` + */ + get autoInit() { + return this._autoInit; + } + /** + * When `true`, {@link View360#resize} is called when the canvas size is changed. + * @ko `true`일 경우, 캔버스의 크기가 변경되었을 때 자동으로 {@link View360#resize}를 호출합니다. + * @default true + * @since 4.0.0 + * @see View360#useResizeObserver + * @example + * ```ts + * const viewer = new View360("#el_id", { + * autoResize: true + * }); + * + * // This can trigger `viewer.resize()` if the canvas size was not 400px + * const canvas = viewer.renderer.canvas; + * canvas.style.width = "400px"; + * ``` + */ + get autoResize() { + return this._autoResize; + } + /** + * CSS selector for canvas element to render panorama image/video. + * The canvas element should be placed inside the root element. (Dont' have to be direct child) + * @ko 파노라마 이미지/비디오를 렌더링할 canvas 엘리먼트의 CSS 선택자 + * 캔버스 엘리먼트는 루트 엘리먼트 내부에 있어야합니다. 루트 엘리먼트의 직계 자식 엘리먼트(Direct child element)일 필요는 없습니다. + * @default "canvas" + * @since 4.0.0 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * + * ```ts + * const viewer = new View360("#el_id", { + * canvasSelector: "#canvas_to_select" + * }); + * ``` + */ + get canvasSelector() { + return this._canvasSelector; + } + /** + * When `true`, it will use {@link ResizeObserver} API to detect canvas size change when {@link View360Options#autoResize} is enabled. + * @ko `true`일 때 {@link View360Options#autoResize}가 활성화되었으면, 사용 가능한 환경에서 {@link ResizeObserver} API를 사용해서 캔버스 크기 변화를 추적합니다. + * @default true + * @since 4.0.0 + */ + get useResizeObserver() { + return this._useResizeObserver; + } + /** + * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} attribute for the canvas element. + * This is necessary for the keyboard controls. + * By default, `0` will be assigned. `null` to disable. + * @ko 캔버스 엘리먼트에 적용할 {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} 어트리뷰트의 값. + * 이 값을 설정해야만 키보드 컨트롤을 사용 가능합니다. + * 기본값으로 `0`이 설정됩니다. `null`로 지정하면 `tabindex`를 설정하지 않습니다. + * @see RotateControlOptions#disableKeyboard + * @default 0 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * tabindex: 5 + * }); + * ``` + * + * ```html + * + *
+ * + *
+ * ``` + */ + get tabIndex() { + return this._tabIndex; + } + set tabIndex(val) { + const canvas = this._renderer.canvas; + this._tabIndex = val; + if (val != null) { + canvas.tabIndex = val; + } else { + canvas.removeAttribute("tabindex"); + } + } + /** + * A maximum delta time between frames in seconds. + * It can prevent camera or control changing too fast when frame being late. + * @ko 프레임간 시간 차이의 최대값. (초 단위) + * 퍼포먼스 등의 이유로 프레임 렌더링이 늦어졌을 때, 화면이 갑작스럽게 바뀌는 것을 막아줍니다. + * @default 1 / 30 + * @since 4.0.0 + */ + get maxDeltaTime() { + return this._animator.maxDeltaTime; + } + set maxDeltaTime(val) { + this._animator.maxDeltaTime = val; + } + /** + * Enable WebGL debugging. Setting this to `true` can decrease performance. + * This is used internally on developing View360. + * @ko WebGL 디버깅을 활성화합니다. 이 값을 `true`로 할 경우 성능이 하락할 수 있습니다. + * 이 옵션은 View360을 개발하기 위해 내부적으로 사용됩니다. + * @default false + */ + get debug() { + return this._debug; + } + set debug(val) { + this._debug = val; + } + // Camera options + /** + * Initial yaw (y-axis rotation) value for camera. (in degrees, °) + * As View360 uses right-handed coordinate system internally, camera will rotate counter-clockwise by this value. + * @ko 카메라의 초기 yaw(y축 회전)값 (도 단위, °) + * View360은 오른손 좌표계를 사용하기 때문에, 카메라가 해당 값만큼 시계 반대방향으로 회전합니다. + * @default 0 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * initialYaw: 30 + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.yaw); // 30 + * }); + * ``` + */ + get initialYaw() { + return this._camera.initialYaw; + } + set initialYaw(val) { + this._camera.initialYaw = val; + } + /** + * Initial pitch (x-axis rotation) value for camera. (in degrees, °) + * As View360 uses right-handed coordinate system internally, positive value will make camera to look upside, while negative value will look down. + * @ko 카메라의 초기 pitch(x축 회전)값 (도 단위, °) + * View360은 오른손 좌표계를 사용하기 때문에, 양(+)의 값은 카메라가 위를 보게 하고, 음(-)의 값은 카메라가 아래를 보게 합니다. + * @default 0 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * initialPitch: 60 + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.pitch); // 60 + * }); + * ``` + */ + get initialPitch() { + return this._camera.initialPitch; + } + set initialPitch(val) { + this._camera.initialPitch = val; + } + /** + * Initial zoom value for camera. + * Setting this value to `2` will enlarge panorama 200% by width. + * @ko 카메라의 초기 줌 값. + * 이 값을 `2`로 설정할 경우 파노라마 이미지를 가로 기준 200%만큼 확대합니다. + * @default 1 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * initialZoom: 2 + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.zoom); // 2 + * }); + * ``` + */ + get initialZoom() { + return this._camera.initialZoom; + } + set initialZoom(val) { + this._camera.initialZoom = val; + } + /** + * Restrict yaw(y-axis rotation) range. (in degrees, °) + * @ko yaw(y축 회전) 범위를 제한합니다. (도 단위, °) + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * yawRange: [-30, 30] + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.yaw); // 0 + * viewer.camera.lookAt({ yaw: 60 }); + * console.log(viewer.camera.yaw); // 30 + * }); + * ``` + */ + get yawRange() { + return this._camera.yawRange; + } + set yawRange(val) { + this._camera.yawRange = val; + if (this._projection) this._projection.updateCamera(this._camera); + } + /** + * Restrict pitch(x-axis rotation) range. (in degrees, °) + * @ko pitch(x축 회전) 범위를 제한합니다. (도 단위, °) + * @default null + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * pitchRange: [-45, 45] + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.pitch); // 0 + * viewer.camera.lookAt({ pitch: 60 }); + * console.log(viewer.camera.pitch); // 45 + * }); + * ``` + */ + get pitchRange() { + return this._camera.pitchRange; + } + set pitchRange(val) { + this._camera.pitchRange = val; + if (this._projection) this._projection.updateCamera(this._camera); + } + /** + * Restrict camera zoom range. + * If `null`, a default zoom range from `0.6` to `10` will be used. + * @ko 카메라 줌 범위를 제한합니다. + * `null`일 경우 기본값으로 `0.6`에서 `10`의 범위를 사용합니다. + * @default null + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * zoomRange: [0.5, 4] + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.zoom); // 1 + * viewer.camera.lookAt({ zoom: 6 }); + * console.log(viewer.camera.zoom); // 4 + * }); + * ``` + */ + get zoomRange() { + return this._camera.zoomRange; + } + set zoomRange(val) { + this._camera.zoomRange = val; + if (this._projection) this._projection.updateCamera(this._camera); + } + /** + * Camera's horizontal FOV(Field of View). (in degrees, °) + * @ko 카메라의 수평 FOV(Field of View) 값. (도 단위, °) + * @default 90 + * @since 4.0.0 + * @example + * ```ts + * // Init with fov: 120 + * const viewer = new View360("#el_id", { fov: 120 }); + * + * // Back to 90 + * viewer.fov = 90; + * ``` + */ + get fov() { + return this._camera.fov; + } + set fov(val) { + const camera = this._camera; + const control = this._control; + camera.fov = val; + camera.updateMatrix(); + control.sync(); + } + // Control options + /** + * A control for camera rotation. + * You can also change options of {@link View360Options#rotate} with this. + * @ko 카메라 회전을 담당하는 컨트롤. + * {@link View360Options#rotate} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get rotate() { + return this._control.rotate; + } + /** + * A control for camera zoom. + * You can also change options of {@link View360Options#zoom} with this. + * @ko 카메라 줌을 담당하는 컨트롤. + * {@link View360Options#zoom} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get zoom() { + return this._control.zoom; + } + /** + * A control for camera rotation with gyroscope input. + * You can also change options of {@link View360Options#gyro} with this. + * @ko 자이로스코프를 통한 카메라 회전을 담당하는 컨트롤. + * {@link View360Options#gyro} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get gyro() { + return this._control.gyro; + } + /** + * Apply CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor} by current state of input when using mouse. + * If `true`, this will add CSS style to canvas element. It'll apply `cursor: "grab"` by default and `cursor: "grabbing"` when holding the mouse button. + * @ko 마우스 사용시 CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor}값을 자동으로 변경할지 여부. + * `true`일 경우 기본 상태에서 `cursor: "grab"`을, 입력 도중에 `cursor: "grabbing"`을 캔버스에 적용합니다. + * @default true + * @since 4.0.0 + */ + get useGrabCursor() { + return this._control.useGrabCursor; + } + set useGrabCursor(val) { + this._control.useGrabCursor = val; + } + /** + * Disable context menu which pops up on mouse right click. + * @ko 마우스 우클릭시 표시되는 컨텍스트 메뉴를 비활성화합니다. + * @default false + * @since 4.0.0 + */ + get disableContextMenu() { + return this._control.disableContextMenu; + } + set disableContextMenu(val) { + this._control.disableContextMenu = val; + } + /** + * If `true`, enables scroll on mobile(touch) devices on canvas. + * :::caution + * When this option is enabled, users must swipe horizontally first then vertically to change view up or down. + * ::: + * @ko `true`로 설정할 경우, 모바일(터치) 환경의 캔버스 영역 내에서 스크롤을 가능하게 합니다. + * :::caution + * 이 값을 활성화할 경우, 사용자가 카메라 뷰를 위/아래로 바꾸기 위해서는 먼저 가로로 스와이프한 이후에 세로로 스와이프해야만 합니다. + * ::: + * @since 4.0.0 + * @default true + */ + get scrollable() { + return this._control.scrollable; + } + set scrollable(val) { + this._control.scrollable = val; + } + /** + * If `true`, enables scroll by mouse wheel on canvas. + * :::caution + * When this option is enabled, zoom by mouse wheel will be disabled. + * ::: + * @ko `true`로 설정할 경우, 캔버스 영역 내에서 마우스 휠을 이용한 페이지 스크롤이 가능해집니다. + * :::caution + * 이 값을 활성화할 경우, 마우스 휠을 통한 줌이 불가능하게 됩니다. + * ::: + * @since 4.0.0 + * @default false + */ + get wheelScrollable() { + return this._control.wheelScrollable; + } + set wheelScrollable(val) { + this._control.wheelScrollable = val; + } + /** + * Create new instance of View360 + * @ko View360의 새로운 인스턴스를 생성합니다 + * @param root - Root element(`.view360-container`) to mount View360 + * Can be either a CSS selector or HTMLElement. + * {@ko View360을 마운트할 루트 엘리먼트, CSS 셀렉터나 HTMLElement를 지정 가능합니다.} + * @param options - Options to apply + * {@ko 적용할 옵션들} + * @example + * ```ts + * import View360, { EquirectProjection } from "@egjs/view360"; + * + * // Create new View360 instance + * const viewer = new View360("#id-of-a-container", { + * projection: new EquirectProjection({ + * src: "URL_TO_PANORAMA_IMAGE_OR_VIDEO", + * }) + * }); + * ``` + */ + constructor(root, { + projection = null, + initialYaw = 0, + initialPitch = 0, + initialZoom = 1, + yawRange = null, + pitchRange = null, + zoomRange = null, + fov = 90, + useGrabCursor = true, + disableContextMenu = false, + rotate = true, + zoom = true, + gyro = false, + scrollable = true, + wheelScrollable = false, + autoplay = false, + hotspot = {}, + autoInit = true, + autoResize = true, + canvasSelector = "canvas", + useResizeObserver = true, + on = {}, + plugins = [], + maxDeltaTime = 1 / 30, + tabIndex = 0, + debug = false + } = {}) { + super(); + /** + * Render a single panorama image/video frame. + * Rendering is performed automatically on demand, so you usually don't have to call this. + * Call this when a frame is not renewed after changing options. + * @ko 파노라마 이미지/비디오의 한 프레임을 렌더링합니다. + * 프레임 갱신은 보통 필요한 때에만 자동적으로 이루어지기 때문에, 보통은 이 메소드를 호출할 필요는 없습니다. + * 옵션 변경 이후에도 프레임 갱신이 이루어지지 않는다면, 이 메소드를 호출해주세요. + * @param delta Delta time in milisec. {@ko 프레임간 시간 차이, 밀리초 단위} + * @since 4.0.0 + */ + this.renderFrame = delta => { + const camera = this._camera; + const renderer = this._renderer; + const control = this._control; + const hotspot = this._hotspot; + const autoPlayer = this._autoplay; + const projection = this._projection; + if (!projection) return; + this._emit(EVENTS.BEFORE_RENDER); + if (autoPlayer.playing) { + autoPlayer.update(delta); + control.sync(); + } + if (camera.animation) { + camera.animation.update(delta); + } else { + control.update(delta); + } + renderer.render(projection, camera); + hotspot.render(camera); + if (camera.changed) { + this._emit(EVENTS.VIEW_CHANGE, { + yaw: camera.yaw, + pitch: camera.pitch, + zoom: camera.zoom, + quaternion: [camera.quaternion[0], camera.quaternion[1], camera.quaternion[2], camera.quaternion[3]] + }); + } + camera.onFrameRender(); + this._emit(EVENTS.RENDER); + }; + this._renderFrameOnDemand = delta => { + var _a; + const camera = this._camera; + const control = this._control; + const autoplay = this._autoplay; + const texture = (_a = this._projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (!this._initialized || !texture) return; + if (!camera.animation && !control.animating && !autoplay.playing && !texture.isVideo()) return; + this.renderFrame(delta); + }; + this._renderVRFrame = (_delta, frame) => { + const vr = this._vr; + const projection = this._projection; + const renderer = this._renderer; + if (!projection) return; + this._emit(EVENTS.BEFORE_RENDER); + renderer.renderVR(projection, vr, frame); + this._emit(EVENTS.RENDER); + }; + this._rootEl = getElement(root); + this._plugins = plugins; + this._initialized = false; + // Options + this._autoInit = autoInit; + this._autoResize = autoResize; + this._canvasSelector = canvasSelector; + this._useResizeObserver = useResizeObserver; + this._tabIndex = tabIndex; + this._debug = debug; + // Core components + const canvas = findCanvas(this._rootEl, canvasSelector); + this._renderer = new WebGLRenderer(canvas, debug); + this._camera = new Camera({ + initialYaw, + initialPitch, + initialZoom, + fov, + yawRange, + pitchRange, + zoomRange + }); + this._control = new PanoControl(canvas, this._camera, { + useGrabCursor, + scrollable, + wheelScrollable, + disableContextMenu, + rotate, + zoom, + gyro + }); + this._animator = new FrameAnimator(maxDeltaTime); + this._autoplay = new Autoplay(this, canvas, autoplay); + this._projection = projection; + this._autoResizer = new AutoResizer(useResizeObserver, () => this.resize()); + this._vr = new XRManager(this._renderer.ctx); + this._hotspot = new HotspotRenderer(this._rootEl, this._renderer, hotspot); + this._addEventHandlers(on); + if (projection && autoInit) { + this.init(); + } + } + /** + * Destroy instance and release all resources. + * @ko 인스턴스를 제거하고 모든 리소스를 해제합니다. + * @since 4.0.0 + */ + destroy() { + this._camera.destroy(); + this._animator.stop(); + this._renderer.destroy(); + this._control.destroy(); + this._autoResizer.disable(); + if (this._projection) { + this._projection.releaseAllResources(this._renderer.ctx); + this._projection = null; + } + this._plugins.forEach(plugin => plugin.destroy(this)); + this._initialized = false; + } + /** + * Initialize inner components and load projection src. + * @ko 내부 컴포넌트들을 초기화하고 프로젝션 소스를 로드합니다. + * @since 4.0.0 + */ + init() { + return __awaiter(this, void 0, void 0, function* () { + if (!this._projection) { + throw new View360Error(ERROR.MESSAGES.PROVIDE_PROJECTION_FIRST, ERROR.CODES.PROVIDE_PROJECTION_FIRST); + } + const renderer = this._renderer; + const camera = this._camera; + const control = this._control; + const animator = this._animator; + const hotspot = this._hotspot; + const projection = this._projection; + const canvas = renderer.canvas; + this._bindComponentEvents(); + renderer.ctx.init(); + this._resizeComponents(); + camera.updateMatrix(); + if (this._autoResize) { + this._autoResizer.enable(canvas); + } + if (!this._autoplay.enableBlocked) { + this._autoplay.enable(); + } + this._plugins.forEach(plugin => { + plugin.init(this); + }); + const texture = yield this._loadTexture(projection); + this._applyProjection(projection, texture, null); + hotspot.refresh(); + animator.start(this._renderFrameOnDemand); + yield control.enable(); + if (this._tabIndex != null && !canvas.hasAttribute("tabIndex")) { + canvas.tabIndex = this._tabIndex; + } + this._initialized = true; + this.renderFrame(0); + this._emit(EVENTS.READY); + }); + } + /** + * Load new panorama image/video and display it. + * This will {@link View360#init init()} View360 if it's not initialized yet. + * @ko 새로운 파노라마 이미지 혹은 비디오를 로드하고 표시합니다. + * 만약 View360이 아직 초기화되지 않았다면, {@link View360#init init()}을 호출합니다. + * @param projection - Projection & video options for new source. {@ko 새로운 파노라마 이미지/비디오에 적용할 옵션들} + * @returns `Promise` if load was successful. {@ko 프로젝션 로드에 성공했을 경우 `Promise`를 반환합니다. } + * @since 4.0.0 + * @example + * ```ts + * // Change to video + * viewer.load({ + * src: "URL_TO_NEW_VIDEO", + * video: true + * }); + * ``` + */ + load(projection) { + return __awaiter(this, void 0, void 0, function* () { + if (!projection) return false; + if (this._initialized) { + const texture = yield this._loadTexture(projection); + this._applyProjection(projection, texture, this._projection); + this.renderFrame(0); + } else { + // Should update internal options before init + this._projection = projection; + this.init(); + } + return true; + }); + } + /** + * Refresh component's size by current + * @ko View360이 내부적으로 캐시하고 있는 엘리먼트 크기를 현재 크기로 갱신합니다. + * @since 4.0.0 + */ + resize() { + if (!this._initialized) return; + this._resizeComponents(); + // To prevent flickering, render immediately after resizing components + this.renderFrame(0); + const { + width, + height + } = this._renderer; + this._emit(EVENTS.RESIZE, { + width, + height + }); + } + /** + * Add new plugins + * @ko 새로운 플러그인을 추가합니다. + * @param plugins Plugins to add {@ko 추가할 플러그인들} + * @see View360Options#plugins + * @since 4.0.0 + * @example + * ```ts + * // Add a single plugin + * viewer.addPlugins(new ControlBar()); + * + * // Add multiple plugins + * viewer.addPlugins(new ControlBar(), new LoadingSpinner()); + * ``` + */ + addPlugins(...plugins) { + if (this._initialized) { + plugins.forEach(plugin => { + plugin.init(this); + }); + } + this._plugins.push(...plugins); + } + /** + * Remove plugins. + * @ko 플러그인을 제거합니다. + * @param plugins Plugins to remove {@ko 제거할 플러그인들} + * @since 4.0.0 + * @example + * ```ts + * // Remove a single plugin + * viewer.removePlugins(plugin1); + * + * // Remove multiple plugins + * viewer.removePlugins(plugin2, plugin3); + * ``` + */ + removePlugins(...plugins) { + plugins.forEach(plugin => { + const pluginIdx = this._plugins.indexOf(plugin); + if (pluginIdx < 0) return; + plugin.destroy(this); + this._plugins.splice(pluginIdx, 1); + }); + } + _emit(eventName, ...params) { + const evtParams = params ? params[0] : {}; + this.trigger(eventName, Object.assign({ + type: eventName, + target: this + }, evtParams)); + } + _applyProjection(projection, texture, prevProjection) { + const camera = this._camera; + const control = this._control; + const renderer = this._renderer; + // Remove previous projection + if (prevProjection) { + prevProjection.releaseAllResources(this._renderer.ctx); + } + projection.applyTexture(renderer.ctx, texture); + projection.updateCamera(camera); + projection.updateControl(control); + this._projection = projection; + this._emit(EVENTS.PROJECTION_CHANGE, { + projection + }); + } + _loadTexture(projection) { + return __awaiter(this, void 0, void 0, function* () { + const contentLoader = new TextureLoader(); + const { + src, + video + } = projection; + this._emit(EVENTS.LOAD_START, { + src, + video + }); + const texture = yield contentLoader.load(src, video); + this._emit(EVENTS.LOAD, { + src, + video + }); + return texture; + }); + } + _resizeComponents() { + const renderer = this._renderer; + const camera = this._camera; + const control = this._control; + renderer.resize(); + camera.resize(renderer.width, renderer.height); + control.resize(renderer.width, renderer.height); + } + _addEventHandlers(events) { + // Bind option "on" + Object.keys(events).forEach(evtName => { + this.on(evtName, events[evtName]); + }); + } + _bindComponentEvents() { + // Bind internal component events + const root = this._rootEl; + const control = this._control; + const animator = this._animator; + const renderer = this._renderer; + const vr = this._vr; + const controlEventsToPropagate = [CONTROL_EVENTS.STATIC_CLICK, CONTROL_EVENTS.INPUT_START, CONTROL_EVENTS.INPUT_END]; + controlEventsToPropagate.forEach(evtName => { + control.rotate.on(evtName, evt => { + this._emit(evtName, evt); + }); + control.zoom.on(evtName, evt => { + this._emit(evtName, evt); + }); + }); + vr.on(EVENTS.VR_START, evt => { + root.classList.add(DEFAULT_CLASS.IN_VR); + animator.changeContext(evt.session); + animator.start(this._renderVRFrame); + this._emit(EVENTS.VR_START); + }); + vr.on(EVENTS.VR_END, () => { + root.classList.remove(DEFAULT_CLASS.IN_VR); + renderer.ctx.useDefaultFrameBuffer(); + animator.changeContext(window); + animator.start(this._renderFrameOnDemand); + this.resize(); + this._emit(EVENTS.VR_END); + }); + } +} +/** + * Current version string of the View360 + * @ko View360의 현재 버젼 문자열 + * @since 4.0.0 + * @readonly + * @example + * ```ts + * // If the installed version of the View360 is v4.0.0, View360.VERSION is equal to "4.0.0" + * console.log(View360.VERSION) // 4.0.0 + * ``` + */ +View360.VERSION = "4.0.0-beta.4"; + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Base class for 3D objects + * @ko 3D 오브젝트의 베이스 클래스 + * @since 4.0.0 + * @internal + */ +class Object3D { + /** + * Create new instance. + * @ko 새로운 인스턴스를 생성합니다. + */ + constructor() { + this.matrix = mat4.create(); + this.rotation = quat.create(); + this.position = vec3.fromValues(0, 0, 0); + this.scale = vec3.fromValues(1, 1, 1); + } + /** + * Update local matrix of the object. + * @ko 오브젝트의 local matrix를 갱신합니다. + * @since 4.0.0 + */ + updateMatrix() { + mat4.fromRotationTranslationScale(this.matrix, this.rotation, this.position, this.scale); + } +} + +/** + * A plugin that displays loading spinner while loading the projection. + * @ko 프로젝션 로딩중에 로딩 스피너를 보여주는 플러그인 + * @since 4.0.0 + * @category Plugin + */ +class LoadingSpinner { + /** + * Create a new instance of LoadingSpinner. {@ko LoadingSpinner의 새 인스턴스를 생성합니다.} + * @param options Options {@ko 옵션들} + */ + constructor({ + className = {} + } = {}) { + this._startLoading = ({ + target: viewer + }) => { + viewer.rootEl.appendChild(this._container); + if (viewer.initialized) { + viewer.once(EVENTS.LOAD, this._detachElements); + } else { + viewer.once(EVENTS.READY, this._detachElements); + } + }; + this._detachElements = ({ + target: viewer + }) => { + const container = this._container; + if (!container) return; + if (container.parentElement === viewer.rootEl) { + viewer.rootEl.removeChild(container); + } + }; + this.className = className; + this._container = this._createElements(); + } + init(viewer) { + viewer.on(EVENTS.LOAD_START, this._startLoading); + } + destroy(viewer) { + viewer.off(EVENTS.LOAD_START, this._startLoading); + this._detachElements({ + target: viewer + }); + } + _createElements() { + const className = Object.assign(Object.assign({}, this.className), LoadingSpinner.DEFAULT_CLASS); + const container = createElement(className.CONTAINER); + const ring = createElement(className.RING); + container.appendChild(ring); + return container; + } +} +/** + * Default class names that LoadingSpinner uses + * @ko LoadingSpinner가 사용하는 디폴트 클래스 이름 + * @since 4.0.0 + */ +LoadingSpinner.DEFAULT_CLASS = { + /** + * A class name for the container element + * @ko 컨테이너 엘리먼트의 클래스 이름 + * @since 4.0.0 + */ + CONTAINER: "view360-spinner", + /** + * A class name for the spinning ring element + * @ko 돌아가는 링 엘리먼트의 클래스 이름 + * @since 4.0.0 + */ + RING: "view360-spinner-ring" +}; + +/** + * Interface of the ControlBar items + * @ko 컨트롤바 아이템의 인터페이스 + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ +class ControlBarItem { + /** + * Create new instance of the ControlBarItem + * @ko ControlBarItem의 새로운 인스턴스를 생성합니다. + * @param options Options {@ko 옵션들} + */ + constructor(options) { + this.position = options.position; + this.order = options.order; + } +} + +const CONTROL_BAR_DEFAULT_CLASS = { + CONTROLS_ROOT: "view360-controls", + CONTROLS_BG: "view360-controls-background", + CONTROLS_MAIN: "view360-controls-main", + CONTROLS_TOP: "view360-controls-top", + CONTROLS_BOTTOM: "view360-controls-bottom", + CONTROLS_MID: "view360-controls-mid", + CONTROLS_LEFT: "view360-controls-left", + CONTROLS_RIGHT: "view360-controls-right", + CONTROLS_FLOAT_LEFT: "view360-controls-float-left", + CONTROLS_FLOAT_RIGHT: "view360-controls-float-right", + CONTROLS_BUTTON: "view360-controls-button", + PROGRESS_ROOT: "view360-controls-progress", + VOLUME_ROOT: "view360-controls-volume", + RANGE_ROOT: "view360-range", + RANGE_TRACK: "view360-range-track", + RANGE_THUMB: "view360-range-thumb", + RANGE_FILLER: "view360-range-filler", + PLAY_BUTTON: "view360-controls-play", + PAUSE_BUTTON: "view360-controls-pause", + UNMUTED_BUTTON: "view360-controls-unmuted", + MUTED_BUTTON: "view360-controls-muted", + FULLSCREEN_BUTTON: "view360-controls-fullscreen", + FULLSCREEN_EXIT_BUTTON: "view360-controls-fullscreen-exit", + VR_BUTTON: "view360-controls-vr", + GYRO_ENABLED: "view360-controls-gyro-enabled", + GYRO_DISABLED: "view360-controls-gyro-disabled", + VIDEO_TIME_DISPLAY: "view360-controls-time", + PIEVIEW_ROOT: "view360-controls-pie", + FIXED: "view360-controls-fixed", + UNAVAILABLE: "view360-controls-unavailable", + HIDDEN: "view360-controls-hidden" +}; +const CONTROL_BAR_ITEM_POSITION = { + /** + * Place control bar item floating at top-left corner + * @ko 아이템을 왼쪽 위 구석에 표시합니다. + * @since 4.0.0 + */ + TOP_LEFT: "top-left", + /** + * Place control bar item floating at top-right corner + * @ko 아이템을 오른쪽 위 구석에 표시합니다. + * @since 4.0.0 + */ + TOP_RIGHT: "top-right", + /** + * Place control bar item at upper block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 위쪽 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_TOP: "main-top", + /** + * Place control bar item at lower block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 하단 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_BOTTOM: "main-bottom", + /** + * Place control bar item at center-left block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 왼쪽 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_LEFT: "main-left", + /** + * Place control bar item at center-right block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 오른쪽 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_RIGHT: "main-right" +}; + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +class RangeControl extends Component { + /** + * + */ + constructor() { + super(); + this._onHold = ({ + srcEvent, + isTouch + }) => { + var _a; + const bbox = this._bbox; + if (!bbox) return; + const x = isTouch ? srcEvent.touches[0].pageX : srcEvent.pageX; + const elX = bbox.x + ((_a = window.scrollX) !== null && _a !== void 0 ? _a : window.pageXOffset); + const clamepdX = clamp(x, elX, elX + bbox.width); + const progress = (clamepdX - elX) / bbox.width; + this._motion.reset(clamepdX); + this.thumbEl.classList.add(this._fixedClass); + this.trigger(CONTROL_EVENTS.INPUT_START, progress); + }; + this._onChange = ({ + delta + }) => { + var _a; + const motion = this._motion; + const bbox = this._bbox; + if (!bbox) return; + motion.setNewEndByDelta(delta.x); + motion.update(1); + const elX = bbox.x + ((_a = window.scrollX) !== null && _a !== void 0 ? _a : window.pageXOffset); + const clampedX = clamp(motion.val, elX, elX + bbox.width); + const progress = (clampedX - elX) / bbox.width; + this.trigger(CONTROL_EVENTS.CHANGE, progress); + }; + this._onRelease = () => { + const bbox = this._bbox; + if (!bbox) return; + this.thumbEl.classList.remove(this._fixedClass); + this.trigger(CONTROL_EVENTS.INPUT_END); + }; + const root = document.createElement(EL_DIV); + const track = document.createElement(EL_DIV); + const thumb = document.createElement(EL_DIV); + const filler = document.createElement(EL_DIV); + root.draggable = false; + track.appendChild(filler); + track.appendChild(thumb); + root.appendChild(track); + this.rootEl = root; + this.trackEl = track; + this.thumbEl = thumb; + this.fillerEl = filler; + this._mouseInput = new MouseInput(); + this._touchInput = new TouchInput(); + this._motion = new Motion({ + duration: 1, + range: INFINITE_RANGE, + easing: x => x + }); + this._bbox = { + x: 0, + y: 0, + width: 0, + height: 0, + left: 0, + right: 0, + bottom: 0, + top: 0 + }; + this._fixedClass = CONTROL_BAR_DEFAULT_CLASS.FIXED; + } + init(className) { + const mouseInput = this._mouseInput; + const touchInput = this._touchInput; + this.rootEl.classList.add(className.RANGE_ROOT); + this.trackEl.classList.add(className.RANGE_TRACK); + this.thumbEl.classList.add(className.RANGE_THUMB); + this.fillerEl.classList.add(className.RANGE_FILLER); + this._fixedClass = className.FIXED; + mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onHold); + touchInput.on(CONTROL_EVENTS.INPUT_START, this._onHold); + mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + touchInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + mouseInput.enable(this.rootEl); + touchInput.enable(this.rootEl); + this.resize(); + } + destroy() { + const mouseInput = this._mouseInput; + const touchInput = this._touchInput; + this.rootEl.className = ""; + this.trackEl.className = ""; + this.thumbEl.className = ""; + this.fillerEl.className = ""; + mouseInput.off(); + touchInput.off(); + mouseInput.disable(); + touchInput.disable(); + } + resize() { + this._bbox = this.trackEl.getBoundingClientRect(); + } + updateStyle(progress) { + const width = this._bbox.width; + const clampedProgress = clamp(progress, 0, 1); + this.fillerEl.style.width = `${clampedProgress * 100}%`; + this.thumbEl.style.transform = `translateX(${clampedProgress * width}px)`; + } +} + +/** + * Show video progress bar. + * @ko 비디오의 프로그레스 바를 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ +class ProgressBar extends ControlBarItem { + get element() { + return this._rangeControl.rootEl; + } + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_TOP, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onResize = () => { + this._rangeControl.resize(); + }; + this._onTimeUpdate = () => { + const video = this._video; + if (!video) return; + this._currentTime = video.source.currentTime; + this._rangeControl.updateStyle(this._currentTime / this._duration); + }; + this._onDurationChange = () => { + const video = this._video; + if (!video) return; + this._duration = video.source.duration; + this._rangeControl.updateStyle(this._currentTime / this._duration); + }; + this._onHold = progress => { + const video = this._video; + const controlBar = this._controlBar; + if (!video || !controlBar) return; + const paused = video.isPaused(); + video.source.pause(); + const time = video.source.duration * progress; + video.source.currentTime = time; + video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { + detail: { + time + } + })); + controlBar.rootEl.classList.add(controlBar.className.FIXED); + this._wasPaused = !this._playPromise && paused; + }; + this._onControl = progress => { + const video = this._video; + if (!video) return; + const time = video.source.duration * progress; + video.source.currentTime = time; + video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { + detail: { + time + } + })); + }; + this._onRelease = () => { + const video = this._video; + const controlBar = this._controlBar; + if (video && controlBar) { + if (!this._wasPaused && !this._playPromise) { + this._playPromise = video.source.play().catch(() => void 0); + // This should not be chained + this._playPromise.then(() => { + this._playPromise = null; + }); + controlBar.rootEl.classList.remove(controlBar.className.FIXED); + } + } + this._wasPaused = false; + }; + this.position = position; + this.order = order; + this._controlBar = null; + this._rangeControl = new RangeControl(); + this._video = null; + this._wasPaused = false; + this._currentTime = 0; + this._duration = 0; + this._playPromise = null; + } + init(viewer, controlBar) { + var _a; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const element = this.element; + const rangeControl = this._rangeControl; + const unavailableClass = controlBar.className.UNAVAILABLE; + if (!video || !video.isVideo()) { + element.classList.add(unavailableClass); + return; + } + element.classList.remove(unavailableClass); + element.classList.add(controlBar.className.PROGRESS_ROOT); + viewer.on(EVENTS.RESIZE, this._onResize); + video.source.addEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.addEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate); + rangeControl.init(controlBar.className); + rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold); + rangeControl.on(CONTROL_EVENTS.CHANGE, this._onControl); + rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + this._video = video; + this._currentTime = video.source.currentTime; + this._duration = video.source.duration; + this._controlBar = controlBar; + rangeControl.updateStyle(this._currentTime / this._duration); + } + destroy(viewer) { + const video = this._video; + viewer.off(EVENTS.RESIZE, this._onResize); + if (video) { + video.source.removeEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.removeEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate); + } + this._rangeControl.destroy(); + this._video = null; + this._playPromise = null; + } +} + +/** + * Show video play / pause button. + * @ko 비디오 재생 / 일시정지 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ +class PlayButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const video = this._video; + if (!video) return; + if (this._paused) { + video.source.play(); + } else { + video.source.pause(); + } + }; + this._onPlay = () => { + if (!this._controlBar) return; + const element = this.element; + const className = this._controlBar.className; + element.classList.add(className.PAUSE_BUTTON); + element.classList.remove(className.PLAY_BUTTON); + element.title = "Pause Video"; + this._paused = false; + }; + this._onPause = () => { + if (!this._controlBar) return; + const element = this.element; + const className = this._controlBar.className; + element.classList.add(className.PLAY_BUTTON); + element.classList.remove(className.PAUSE_BUTTON); + element.title = "Play Video"; + this._paused = true; + }; + this.element = document.createElement(EL_BUTTON); + this._video = null; + this._paused = true; + this._controlBar = null; + } + init(viewer, controlBar) { + var _a; + const element = this.element; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const className = controlBar.className; + const unavailableClass = className.UNAVAILABLE; + if (!video || !video.isVideo()) { + element.classList.add(unavailableClass); + return; + } + element.classList.add(className.CONTROLS_BUTTON); + element.classList.remove(unavailableClass); + const paused = video.isPaused(); + this._video = video; + this._paused = paused; + this._controlBar = controlBar; + if (paused) { + this._onPause(); + } else { + this._onPlay(); + } + element.addEventListener(EVENTS$1.CLICK, this._onClick); + video.source.addEventListener(EVENTS$1.VIDEO_PLAY, this._onPlay); + video.source.addEventListener(EVENTS$1.VIDEO_PAUSE, this._onPause); + } + destroy() { + const video = this._video; + const element = this.element; + if (!video) return; + element.className = ""; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + video.source.removeEventListener(EVENTS$1.VIDEO_PLAY, this._onPlay); + video.source.removeEventListener(EVENTS$1.VIDEO_PAUSE, this._onPause); + this._video = null; + this._paused = true; + this._controlBar = null; + } +} + +/** + * Show video volume control. + * @ko 비디오 볼륨 조절 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ +class VolumeControl extends ControlBarItem { + get element() { + return this._rootEl; + } + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onResize = () => { + this._rangeControl.resize(); + this._updateDisplay(); + }; + this._onClick = () => { + const video = this._video; + if (!video || this._rootEl.disabled) return; + video.source.muted = !video.source.muted; + }; + this._onVolumeChange = () => { + const button = this._buttonEl; + const video = this._video; + const controlBar = this._controlBar; + if (!video || !controlBar) return; + const className = controlBar.className; + if (video.source.muted || video.source.volume === 0) { + button.classList.add(className.MUTED_BUTTON); + button.classList.remove(className.UNMUTED_BUTTON); + } else { + button.classList.add(className.UNMUTED_BUTTON); + button.classList.remove(className.MUTED_BUTTON); + } + this._updateDisplay(); + }; + this._onHold = progress => { + const video = this._video; + const controlBar = this._controlBar; + if (!video || !controlBar) return; + const className = controlBar.className; + video.source.volume = progress; + this._rootEl.classList.add(className.FIXED); + controlBar.containerEl.classList.add(className.FIXED); + this._updateDisplay(); + }; + this._onChange = progress => { + const video = this._video; + if (!video) return; + video.source.volume = progress; + if (progress > 0) { + video.source.muted = false; + } else { + video.source.muted = true; + } + this._updateDisplay(); + }; + this._onRelease = () => { + const controlBar = this._controlBar; + if (!controlBar) return; + const className = controlBar.className; + this._rootEl.classList.remove(className.FIXED); + controlBar.containerEl.classList.remove(className.FIXED); + }; + this._updateDisplay = () => { + const video = this._video; + const root = this._rootEl; + if (!video) return; + if (!video.hasAudio()) { + root.disabled = true; + return; + } + root.disabled = false; + const volume = video.source.muted ? 0 : video.source.volume; + this._rangeControl.updateStyle(volume); + }; + this._controlBar = null; + this._rangeControl = new RangeControl(); + this._createElements(); + this._video = null; + } + init(viewer, controlBar) { + var _a; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const root = this._rootEl; + const button = this._buttonEl; + const rangeControl = this._rangeControl; + const className = controlBar.className; + const unavailableClass = className.UNAVAILABLE; + if (!video || !video.isVideo()) { + root.classList.add(unavailableClass); + return; + } + root.classList.remove(unavailableClass); + root.classList.add(className.CONTROLS_BUTTON); + root.classList.add(className.VOLUME_ROOT); + button.classList.add(className.CONTROLS_BUTTON); + if (video.source.muted) { + button.classList.add(className.MUTED_BUTTON); + } else { + button.classList.add(className.UNMUTED_BUTTON); + } + viewer.on(EVENTS.RESIZE, this._onResize); + root.addEventListener(EVENTS$1.TRANSITION_END, this._onResize); + button.addEventListener(EVENTS$1.CLICK, this._onClick); + video.source.addEventListener(EVENTS$1.VIDEO_VOLUME_CHANGE, this._onVolumeChange); + video.source.addEventListener(EVENTS$1.VIDEO_LOADED_DATA, this._updateDisplay); + video.source.addEventListener(EVENTS$1.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay); + rangeControl.init(className); + rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold); + rangeControl.on(CONTROL_EVENTS.CHANGE, this._onChange); + rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + this._controlBar = controlBar; + this._video = video; + this._updateDisplay(); + } + destroy(viewer) { + const video = this._video; + const button = this._buttonEl; + const root = this._rootEl; + root.className = ""; + button.className = ""; + viewer.off(EVENTS.RESIZE, this._onResize); + root.removeEventListener(EVENTS$1.TRANSITION_END, this._onResize); + button.removeEventListener(EVENTS$1.CLICK, this._onClick); + if (video) { + video.source.removeEventListener(EVENTS$1.VIDEO_VOLUME_CHANGE, this._onVolumeChange); + video.source.removeEventListener(EVENTS$1.VIDEO_LOADED_DATA, this._updateDisplay); + video.source.removeEventListener(EVENTS$1.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay); + } + this._controlBar = null; + this._rangeControl.destroy(); + this._video = null; + } + _createElements() { + const root = document.createElement(EL_BUTTON); + const buttonEl = document.createElement(EL_DIV); + root.appendChild(this._rangeControl.rootEl); + root.appendChild(buttonEl); + root.title = "Toggle Mute"; + this._rootEl = root; + this._buttonEl = buttonEl; + } +} + +/** + * Show fullscreen enter / exit button. + * @ko 풀스크린 진입 / 해제 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ +class FullscreenButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const target = this._targetEl; + if (!target) return; + if (isFullscreen()) { + this._exitFullscreen(); + } else { + this._requestFullscreen(target); + } + }; + this._onFullscreenChange = () => { + const element = this.element; + const controlBar = this._controlBar; + if (!controlBar) return; + const className = controlBar.className; + if (isFullscreen()) { + element.classList.add(className.FULLSCREEN_EXIT_BUTTON); + element.classList.remove(className.FULLSCREEN_BUTTON); + } else { + element.classList.add(className.FULLSCREEN_BUTTON); + element.classList.remove(className.FULLSCREEN_EXIT_BUTTON); + } + }; + this.element = document.createElement(EL_BUTTON); + this.element.title = "Toggle Fullscreen"; + this._controlBar = null; + this._targetEl = null; + } + init(viewer, controlBar) { + const element = this.element; + const className = controlBar.className; + if (!this._fullscreenAvailable()) { + element.classList.add(className.UNAVAILABLE); + return; + } + element.classList.add(className.CONTROLS_BUTTON); + element.classList.remove(className.UNAVAILABLE); + element.addEventListener(EVENTS$1.CLICK, this._onClick); + this._addFullscreenHandlers(); + if (isFullscreen()) { + element.classList.add(className.FULLSCREEN_EXIT_BUTTON); + } else { + element.classList.add(className.FULLSCREEN_BUTTON); + } + this._controlBar = controlBar; + this._targetEl = viewer.rootEl; + } + destroy() { + const element = this.element; + element.className = ""; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + this._removeFullscreenHandlers(); + this._controlBar = null; + this._targetEl = null; + } + _fullscreenAvailable() { + return FULLSCREEN_REQUEST.some(key => !!document[key]); + } + _requestFullscreen(el) { + for (const key of FULLSCREEN_REQUEST) { + const request = el[key]; + if (request) { + request.call(el); + return; + } + } + } + _exitFullscreen() { + for (const key of FULLSCREEN_EXIT) { + const exit = document[key]; + if (exit) { + exit.call(document); + return; + } + } + } + _addFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.addEventListener(evtName, this._onFullscreenChange); + }); + } + _removeFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.removeEventListener(evtName, this._onFullscreenChange); + }); + } +} + +/** + * Show video current / total time. + * @ko 비디오의 현재 / 총 재생시간을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ +class VideoTime extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onTimeUpdate = () => { + const video = this._video; + if (!video) return; + this._currentTime = video.source.currentTime; + this._updateDisplay(); + }; + this._onDurationChange = () => { + const video = this._video; + if (!video) return; + this._duration = video.source.duration; + this._updateDisplay(); + }; + this._onCustomTimeChange = evt => { + this._currentTime = evt.detail.time; + this._updateDisplay(); + }; + this.element = document.createElement(EL_DIV); + this._video = null; + this._currentTime = 0; + this._duration = 0; + } + init(viewer, controlBar) { + var _a; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const element = this.element; + const className = controlBar.className; + if (!video || !video.isVideo()) { + element.classList.add(className.UNAVAILABLE); + return; + } + element.classList.add(className.VIDEO_TIME_DISPLAY); + element.classList.remove(className.UNAVAILABLE); + video.source.addEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.addEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange); + this._video = video; + this._currentTime = video.source.currentTime; + this._duration = video.source.duration; + this._updateDisplay(); + } + destroy() { + const video = this._video; + if (!video) return; + this.element.className = ""; + video.source.removeEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.removeEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange); + this._video = null; + } + _updateDisplay() { + const time = this._currentTime; + const timeMinute = Math.floor(time / 60); + const timeSeconds = Math.floor(time - timeMinute * 60); + const timeSecondsFormatted = timeSeconds < 10 ? `0${timeSeconds}` : timeSeconds; + const duration = this._duration; + const durationMinute = Math.floor(duration / 60); + const durationSeconds = Math.floor(duration - durationMinute * 60); + const durationSecondsFormatted = durationSeconds < 10 ? `0${durationSeconds}` : durationSeconds; + this.element.innerText = `${timeMinute}:${timeSecondsFormatted} / ${durationMinute}:${durationSecondsFormatted}`; + } +} + +/** + * Show camera direction/fov indicator. + * @ko 카메라가 향하는 방향 및 FOV를 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ +class PieView extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + resetCamera = true, + position = CONTROL_BAR_ITEM_POSITION.TOP_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const viewer = this._viewer; + const resetCamera = this.resetCamera; + if (!viewer || !resetCamera) return; + const { + yaw = viewer.initialYaw, + pitch = viewer.initialPitch, + zoom = viewer.initialZoom, + duration = 500 + } = getObjectOption(resetCamera); + viewer.camera.animateTo({ + yaw, + pitch, + zoom, + duration + }); + }; + this._updatePie = ({ + target: viewer + }) => { + const piePath = this._piePathEl; + const rangeCircle = this._rangeCircleEl; + const camera = viewer.camera; + const fov = camera.getHorizontalFov(); + const yawRange = camera.getYawRange(camera.zoom); + const halfFov = fov * 0.5; + const pieRadius = 24 * Math.PI; + const pieDeg = pieRadius * fov / 360; + const pieOffset = pieRadius * (camera.yaw + halfFov + 90) / 360; + piePath.setAttribute("stroke-dasharray", `${pieDeg} ${pieRadius - pieDeg}`); + piePath.setAttribute("stroke-dashoffset", `${pieOffset}`); + if (isFinite(yawRange.min) && isFinite(yawRange.max)) { + const radius = 45 * Math.PI; // 2 * PI * r + const min = (circulate(yawRange.min, -180, 180) - halfFov) / 360; + const max = (circulate(yawRange.max, -180, 180) + halfFov) / 360; + const rangeDiff = radius * Math.abs(max - min); + const offset = -radius * (min - 0.25); + rangeCircle.setAttribute("stroke-dasharray", `${rangeDiff} ${radius - rangeDiff}`); + rangeCircle.setAttribute("stroke-dashoffset", `${offset}`); + } else { + rangeCircle.setAttribute("stroke-dasharray", ""); + rangeCircle.setAttribute("stroke-dashoffset", ""); + } + }; + this.element = document.createElement(EL_DIV); + this.element.title = "Reset view"; + this.resetCamera = resetCamera; + this._createPieElements(); + this._viewer = null; + } + init(viewer, controlBar) { + const element = this.element; + if (!viewer.initialized) { + viewer.once(EVENTS.READY, this._updatePie); + } else { + this._updatePie({ + target: viewer + }); + } + const rootClass = controlBar.className.PIEVIEW_ROOT; + element.classList.add(rootClass); + if (this.resetCamera) { + element.addEventListener(EVENTS$1.CLICK, this._onClick); + } + viewer.on(EVENTS.VIEW_CHANGE, this._updatePie); + this._viewer = viewer; + } + destroy(viewer) { + const element = this.element; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + element.className = ""; + viewer.off(EVENTS.READY, this._updatePie); + viewer.off(EVENTS.VIEW_CHANGE, this._updatePie); + this._viewer = null; + } + _createPieElements() { + const root = this.element; + const pieSVG = document.createElementNS(SVG_NAMESPACE, "svg"); + pieSVG.setAttribute("viewBox", "0 0 48 48"); + pieSVG.setAttribute("width", "100%"); + pieSVG.setAttribute("height", "100%"); + const piePath = document.createElementNS(SVG_NAMESPACE, "circle"); + piePath.setAttribute("stroke", "currentColor"); + piePath.setAttribute("fill", "transparent"); + piePath.setAttribute("cx", "24"); + piePath.setAttribute("cy", "24"); + piePath.setAttribute("r", "12"); + piePath.setAttribute("stroke-width", "24"); + pieSVG.appendChild(piePath); + const rangeCircle = document.createElementNS(SVG_NAMESPACE, "circle"); + rangeCircle.setAttribute("stroke", "currentColor"); + rangeCircle.setAttribute("fill", "transparent"); + rangeCircle.setAttribute("cx", "24"); + rangeCircle.setAttribute("cy", "24"); + rangeCircle.setAttribute("r", "22.5"); + rangeCircle.setAttribute("stroke-width", "3"); + pieSVG.appendChild(rangeCircle); + root.appendChild(pieSVG); + this._piePathEl = piePath; + this._rangeCircleEl = rangeCircle; + } +} + +/** + * Show VR enter button. + * @ko VR 진입 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ +class VRButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const viewer = this._viewer; + if (!viewer) return; + viewer.vr.enter(); + }; + this.element = document.createElement(EL_BUTTON); + this.element.title = "Enter VR"; + this._viewer = null; + } + init(viewer, controlBar) { + const element = this.element; + const className = controlBar.className; + element.classList.add(className.UNAVAILABLE); + element.classList.add(className.VR_BUTTON); + element.classList.add(className.CONTROLS_BUTTON); + viewer.vr.isAvailable().then(available => { + if (available) { + element.classList.remove(className.UNAVAILABLE); + } + }); + element.addEventListener(EVENTS$1.CLICK, this._onClick); + this._viewer = viewer; + } + destroy() { + const element = this.element; + element.className = ""; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + this._viewer = null; + } +} + +/** + * Show gyroscope control enable / disable button + * @ko 자이로스코프 컨트롤 활성화 / 비활성화 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ +class GyroButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const viewer = this._viewer; + const controlBar = this._controlBar; + if (!viewer || !controlBar) return; + const gyroControl = viewer.control.gyro; + if (gyroControl.enabled) { + gyroControl.disable(); + } else { + GyroControl.requestSensorPermission().then(available => { + if (available) { + gyroControl.enable(); + } else { + this.element.classList.add(controlBar.className.UNAVAILABLE); + } + }); + } + }; + this._updateStyle = () => { + const element = this.element; + const viewer = this._viewer; + const controlBar = this._controlBar; + if (!viewer || !controlBar) return; + const gyroControl = viewer.control.gyro; + const className = controlBar.className; + if (gyroControl.enabled) { + element.classList.add(className.GYRO_ENABLED); + element.classList.remove(className.GYRO_DISABLED); + } else { + element.classList.add(className.GYRO_DISABLED); + element.classList.remove(className.GYRO_ENABLED); + } + }; + this.element = document.createElement(EL_DIV); + this.element.title = "Toggle gyroscope control"; + } + init(viewer, controlBar) { + const element = this.element; + const className = controlBar.className; + element.addEventListener(EVENTS$1.CLICK, this._onClick); + element.classList.add(className.CONTROLS_BUTTON); + element.classList.add(className.UNAVAILABLE); + const enableButton = () => { + element.classList.remove(className.UNAVAILABLE); + viewer.control.gyro.on(CONTROL_EVENTS.ENABLE, this._updateStyle); + viewer.control.gyro.on(CONTROL_EVENTS.DISABLE, this._updateStyle); + }; + if (sensorCanBeEnabledIOS()) { + enableButton(); + } else { + GyroControl.isAvailable().then(available => { + if (!available) return; + enableButton(); + }); + } + this._controlBar = controlBar; + this._viewer = viewer; + this._updateStyle(); + } + destroy(viewer) { + const element = this.element; + viewer.control.gyro.off(CONTROL_EVENTS.ENABLE, this._updateStyle); + viewer.control.gyro.off(CONTROL_EVENTS.DISABLE, this._updateStyle); + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + element.className = ""; + this._controlBar = null; + this._viewer = null; + } +} + +class AutoHide { + get enabled() { + return !!this._targetEl; + } + get hidden() { + return this._controlBar.containerEl.classList.contains(this._hiddenClass); + } + get _hiddenClass() { + return this._controlBar.className.HIDDEN; + } + get _fixedClass() { + return this._controlBar.className.FIXED; + } + constructor(controlBar, { + initialDelay = 3000, + delay = 0, + idleDelay: activationDelay = 3000 + }) { + this._onMouseEnter = () => { + this._isCursorInside = true; + this.show(); + }; + this._onMouseLeave = () => { + this._isCursorInside = false; + this._hideAfterDelay(); + }; + this._onMouseMove = () => { + if (!this._isFullscreen) return; + this.showTemporaliy(); + }; + this._onHold = evt => { + this._isGrabbing = true; + if (evt.pointerType === "mouse") { + this._isCursorInside = true; + } + window.addEventListener(EVENTS$1.MOUSE_UP, this._onRelease); + this.show(); + }; + this._onRelease = () => { + this._isGrabbing = false; + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onRelease); + this._hideAfterDelay(); + }; + this._onVideoPlay = () => { + const root = this._targetEl; + if (!root) return; + this._controlBar.containerEl.classList.remove(this._fixedClass); + }; + this._onVideoPause = () => { + const root = this._targetEl; + if (!root) return; + this._controlBar.containerEl.classList.add(this._fixedClass); + }; + this._onFullscreenChange = () => { + this._isFullscreen = isFullscreen(); + if (this._isFullscreen) { + this._hideAfterDelay(); + } + }; + this._controlBar = controlBar; + this._initialDelay = initialDelay; + this._delay = delay; + this._idleDelay = activationDelay; + this._timer = -1; + this._isCursorInside = false; + this._isGrabbing = false; + this._isFullscreen = false; + this._video = null; + this._targetEl = null; + } + enable(viewer) { + var _a; + if (this._targetEl) { + this.disable(viewer); + } + const initialDelay = this._initialDelay; + const root = viewer.rootEl; + this._targetEl = viewer.rootEl; + this._timer = window.setTimeout(() => { + this.hide(); + }, initialDelay); + root.addEventListener(EVENTS$1.MOUSE_DOWN, this._onHold); + root.addEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter); + root.addEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove); + root.addEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave); + this._addFullscreenHandlers(); + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (!video || !video.isVideo()) { + return; + } + if (video.isPaused()) { + this._controlBar.containerEl.classList.add(this._fixedClass); + } + video.source.addEventListener(EVENTS$1.VIDEO_PLAY, this._onVideoPlay); + video.source.addEventListener(EVENTS$1.VIDEO_PAUSE, this._onVideoPause); + this._video = video; + } + disable(viewer) { + if (!this._targetEl) return; + const controlBar = this._controlBar; + const root = viewer.rootEl; + const video = this._video; + root.removeEventListener(EVENTS$1.MOUSE_DOWN, this._onHold); + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onRelease); + root.removeEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter); + root.removeEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove); + root.removeEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave); + this._removeFullscreenHandlers(); + window.clearTimeout(this._timer); + controlBar.containerEl.classList.remove(this._fixedClass); + if (video) { + video.source.removeEventListener(EVENTS$1.VIDEO_PLAY, this._onVideoPlay); + video.source.removeEventListener(EVENTS$1.VIDEO_PAUSE, this._onVideoPause); + } + this._isCursorInside = false; + this._isGrabbing = false; + this._video = null; + this._targetEl = null; + } + show() { + this._clearHideTimer(); + this._controlBar.containerEl.classList.remove(this._hiddenClass); + } + showTemporaliy() { + this.show(); + this._hideAfterDelay(this._idleDelay); + } + hide() { + this._clearHideTimer(); + this._controlBar.containerEl.classList.add(this._hiddenClass); + } + _clearHideTimer() { + if (this._timer) { + window.clearTimeout(this._timer); + this._timer = -1; + } + } + _hideAfterDelay(delay = this._delay) { + if (this._isGrabbing || !this._isFullscreen && this._isCursorInside) return; + this._clearHideTimer(); + if (delay <= 0) { + this.hide(); + } else { + this._timer = window.setTimeout(() => { + this.hide(); + }, delay); + } + } + _addFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.addEventListener(evtName, this._onFullscreenChange); + }); + } + _removeFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.removeEventListener(evtName, this._onFullscreenChange); + }); + } +} + +class VideoControl { + constructor() { + this._onKeyDown = event => { + const video = this._video; + if (!video) return; + event.preventDefault(); + event.stopPropagation(); + const videoEl = video.source; + const keyPressed = event.keyCode != null ? DIRECTION_KEY_CODE[event.keyCode] : DIRECTION_KEY_NAME[event.key]; + switch (keyPressed) { + case "LEFT": + case "RIGHT": + return this._changeVideoTime(videoEl, keyPressed === "RIGHT"); + case "UP": + case "DOWN": + return this._changeVideoVolume(videoEl, keyPressed === "UP"); + } + const spacePressed = event.keyCode === SPACE_KEY_CODE || event.key === SPACE_KEY_NAME; + if (spacePressed) { + this._toggleVideo(video); + } + }; + } + enable(root, video) { + this._video = video; + // capture is needed for resolving conflict with keyboard control + root.addEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown, true); + } + disable(root) { + this._video = null; + root.removeEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown, true); + } + _changeVideoTime(video, forward) { + const delta = forward ? 5 : -5; + video.currentTime += delta; + video.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { + detail: { + time: video.currentTime + } + })); + } + _changeVideoVolume(video, increase) { + const delta = increase ? 0.1 : -0.1; + if (video.muted) { + video.volume = clamp(delta, 0, 1); + } else { + video.volume = clamp(video.volume + delta, 0, 1); + } + if (video.volume > 0) { + video.muted = false; + } else { + video.muted = true; + } + } + _toggleVideo(video) { + if (video.isPaused()) { + video.source.play(); + } else { + video.source.pause(); + } + } +} + +/** + * A plugin that displays extra buttons & controls that controls {@link View360}. + * @ko {@link View360}에 부가적인 버튼과 컨트롤을 추가해주는 플러그인. + * @category Plugin + * @since 4.0.0 + */ +class ControlBar { + /** + * Root element of the control bar + * @ko 컨트롤바의 루트 엘리먼트 + * @since 4.0.0 + */ + get rootEl() { + return this._rootEl; + } + /** + * Container element of the control bar + * @ko 컨트롤바의 컨테이너 엘리먼트 + * @since 4.0.0 + */ + get containerEl() { + return this._containerEl; + } + /** + * Background element of the control bar + * @ko 컨트롤바의 배경 엘리먼트 + * @since 4.0.0 + */ + get backgroundEl() { + return this._bgEl; + } + /** + * Control bar's default items created by {@link ControlBarOptions} + * @ko 주어진 {@link ControlBarOptions}에 의해 생성된 디폴트 아이템들 + * @since 4.0.0 + */ + get items() { + return this._items; + } + /** + * Custom control bar items + * @ko 커스텀 컨트롤바 아이템들을 추가합니다. + * @since 4.0.0 + */ + get customItems() { + return this._customItems; + } + /** + * Create new instance of ControlBar. + * @ko ControlBar의 새 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + autoHide, + showBackground, + clickToPlay = true, + keyboardControls = true, + progressBar = true, + playButton = true, + volumeButton = true, + fullscreenButton = true, + videoTime = true, + pieView = true, + vrButton = true, + gyroButton = true, + className = {}, + customItems = [] + } = {}) { + var _a; + this._onStaticClick = ({ + target: viewer, + isTouch + }) => { + var _a; + const autoHider = this._autoHider; + if (isTouch) { + if (!autoHider.enabled) return; + if (autoHider.hidden) { + autoHider.showTemporaliy(); + } else { + autoHider.hide(); + } + } else { + if (!this.clickToPlay) return; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (!video || !video.isVideo()) return; + if (video.isPaused()) { + video.source.play(); + } else { + video.source.pause(); + } + } + }; + this._onNewSrcLoad = ({ + target: viewer + }) => { + const items = this._items; + this._updateBackground(viewer); + this._updateAutoHide(viewer); + this._updateKeyboardHandler(viewer); + Object.keys(items).forEach(key => { + const category = items[key]; + category.forEach(item => { + item.destroy(viewer, this); + item.init(viewer, this); + }); + }); + }; + this.autoHide = autoHide; + this.showBackground = showBackground; + this.clickToPlay = clickToPlay; + this.keyboardControls = keyboardControls; + this.progressBar = progressBar; + this.playButton = playButton; + this.volumeButton = volumeButton; + this.fullscreenButton = fullscreenButton; + this.videoTime = videoTime; + this.pieView = pieView; + this.vrButton = vrButton; + this.gyroButton = gyroButton; + this.className = Object.assign(Object.assign({}, ControlBar.DEFAULT_CLASS), className); + const rootClass = (_a = className.CONTROLS_ROOT) !== null && _a !== void 0 ? _a : ControlBar.DEFAULT_CLASS.CONTROLS_ROOT; + this._rootEl = createElement(rootClass); + this._createPositionWrappers(); + this._items = Object.keys(ControlBar.POSITION).reduce((items, key) => { + items[ControlBar.POSITION[key]] = []; + return items; + }, {}); + this._customItems = customItems; + this._autoHider = new AutoHide(this, getObjectOption(autoHide)); + this._videoControl = new VideoControl(); + customItems.forEach(item => { + this._items[item.position].push(item); + }); + } + init(viewer) { + const panoRoot = viewer.rootEl; + const controlsRoot = this._rootEl; + const defaultItems = this._createDefaultItems(); + this._updateBackground(viewer); + this._updateAutoHide(viewer); + this._updateKeyboardHandler(viewer); + panoRoot.appendChild(controlsRoot); + this._addItem(viewer, defaultItems); + this._addItem(viewer, this._customItems); + viewer.on(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad); + viewer.on(EVENTS.STATIC_CLICK, this._onStaticClick); + } + destroy(viewer) { + // Remove controls root from pano root + const panoRoot = viewer.rootEl; + const controlsRoot = this._rootEl; + const items = this._items; + if (controlsRoot.parentElement === panoRoot) { + panoRoot.removeChild(controlsRoot); + } + Object.keys(items).forEach(key => { + const category = items[key]; + category.forEach(item => { + item.destroy(viewer, this); + }); + items[key] = []; + }); + this._clearItemElements(); + this._autoHider.disable(viewer); + this._videoControl.disable(panoRoot); + viewer.off(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad); + viewer.off(EVENTS.STATIC_CLICK, this._onStaticClick); + } + _addItem(viewer, items) { + for (const item of items) { + const category = this._items[item.position]; + const wrapper = this._wrapperEl[item.position]; + const nextSiblingIndex = findIndex(category, sibling => sibling.order > item.order); + if (nextSiblingIndex >= 0) { + const nextSibling = category[nextSiblingIndex].element; + category.splice(nextSiblingIndex, 0, item); + wrapper.insertBefore(item.element, nextSibling); + } else { + category.push(item); + wrapper.appendChild(item.element); + } + item.init(viewer, this); + } + } + _createPositionWrappers() { + const className = Object.assign(Object.assign({}, ControlBar.DEFAULT_CLASS), this.className); + const rootEl = this._rootEl; + // BG & FLOATING CONTROLS + const backgroundEl = createElement(className.CONTROLS_BG); + const floatLeftEl = createElement(className.CONTROLS_FLOAT_LEFT); + const floatRightEl = createElement(className.CONTROLS_FLOAT_RIGHT); + rootEl.appendChild(floatLeftEl); + rootEl.appendChild(floatRightEl); + // BOTTOM CONTROLS + const container = createElement(className.CONTROLS_MAIN); + const topWrapper = createElement(className.CONTROLS_TOP); + const bottomWrapper = createElement(className.CONTROLS_BOTTOM); + const midWrapper = createElement(className.CONTROLS_MID); + const leftControlsWrapper = createElement(className.CONTROLS_LEFT); + const rightControlsWrapper = createElement(className.CONTROLS_RIGHT); + midWrapper.appendChild(leftControlsWrapper); + midWrapper.appendChild(rightControlsWrapper); + container.appendChild(backgroundEl); + container.appendChild(topWrapper); + container.appendChild(midWrapper); + container.appendChild(bottomWrapper); + rootEl.appendChild(container); + this._bgEl = backgroundEl; + this._containerEl = container; + this._wrapperEl = { + [ControlBar.POSITION.MAIN_TOP]: topWrapper, + [ControlBar.POSITION.MAIN_LEFT]: leftControlsWrapper, + [ControlBar.POSITION.MAIN_RIGHT]: rightControlsWrapper, + [ControlBar.POSITION.MAIN_BOTTOM]: bottomWrapper, + [ControlBar.POSITION.TOP_LEFT]: floatLeftEl, + [ControlBar.POSITION.TOP_RIGHT]: floatRightEl + }; + } + _clearItemElements() { + const wrappers = Object.keys(ControlBar.POSITION).map(key => ControlBar.POSITION[key]); + // Remove all elements inside wrappers + wrappers.forEach(wrapper => { + while (wrapper.firstChild) { + wrapper.removeChild(wrapper.firstChild); + } + }); + } + _updateAutoHide(viewer) { + var _a; + const autoHide = this.autoHide; + const autoHider = this._autoHider; + if (autoHide != null) { + if (autoHide) { + autoHider.enable(viewer); + } else { + autoHider.disable(viewer); + } + } else { + // Automatically choose whether to show background by content type + const texture = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (texture && texture.isVideo()) { + // Enable auto hide when content type is video + autoHider.enable(viewer); + } else { + autoHider.disable(viewer); + } + } + } + _updateBackground(viewer) { + var _a, _b; + const background = this._bgEl; + const showBackground = this.showBackground; + const hiddenClass = (_a = this.className.HIDDEN) !== null && _a !== void 0 ? _a : ControlBar.DEFAULT_CLASS.HIDDEN; + if (showBackground != null) { + if (showBackground) { + background.classList.remove(hiddenClass); + } else { + background.classList.add(hiddenClass); + } + } else { + // Automatically choose whether to show background by content type + const texture = (_b = viewer.projection) === null || _b === void 0 ? void 0 : _b.getTexture(); + if (texture && texture.isVideo()) { + // Show bg when content type is video + background.classList.remove(hiddenClass); + } else { + background.classList.add(hiddenClass); + } + } + } + _updateKeyboardHandler(viewer) { + var _a; + const panoRoot = viewer.rootEl; + const videoControl = this._videoControl; + const texture = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (this.keyboardControls && texture && texture.isVideo()) { + videoControl.enable(panoRoot, texture); + } else { + videoControl.disable(panoRoot); + } + } + _createDefaultItems() { + const items = []; + if (this.progressBar) { + items.push(new ProgressBar(getObjectOption(this.progressBar))); + } + if (this.playButton) { + items.push(new PlayButton(getObjectOption(this.playButton))); + } + if (this.volumeButton) { + items.push(new VolumeControl(getObjectOption(this.volumeButton))); + } + if (this.gyroButton) { + items.push(new GyroButton(getObjectOption(this.gyroButton))); + } + if (this.vrButton) { + items.push(new VRButton(getObjectOption(this.vrButton))); + } + if (this.fullscreenButton) { + items.push(new FullscreenButton(getObjectOption(this.fullscreenButton))); + } + if (this.videoTime) { + items.push(new VideoTime(getObjectOption(this.videoTime))); + } + if (this.pieView) { + items.push(new PieView(getObjectOption(this.pieView))); + } + return items; + } +} +/** + * Default class names that ControlBar uses + * @ko ControlBar가 사용하는 디폴트 클래스 이름들 + * @since 4.0.0 + */ +ControlBar.DEFAULT_CLASS = CONTROL_BAR_DEFAULT_CLASS; +/** + * Constants for {@link ControlBarItemOptions#position} + * @ko {@link ControlBarItemOptions#position}에 사용 가능한 값들 + */ +ControlBar.POSITION = CONTROL_BAR_ITEM_POSITION; + +/** + * Base class for projections. + * @ko 프로젝션 베이스 클래스. + * @category Projection + * @since 4.0.0 + */ +class Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + src, + video = false + }) { + this.src = src; + this.video = video; + this._mesh = null; + } + /** + * Release all resources projection has. + * This is automatically called on projection change & View360's destroy call + * @ko 현재 갖고 있는 모든 리소스를 반환합니다. + * 이 메소드는 프로젝션 변경 및 View360의 destroy 호출 시 자동으로 호출됩니다. + * @param ctx + */ + releaseAllResources(ctx) { + var _a; + (_a = this._mesh) === null || _a === void 0 ? void 0 : _a.destroy(ctx); + } + /** + * Update camera to match projection's settings. + * @ko 현재 프로젝션의 세팅으로 카메라를 업데이트합니다. + * @param camera - Instance of the camera to update {@ko 업데이트할 카메라의 인스턴스} + * @since 4.0.0 + */ + updateCamera(camera) { + // Use default mode & no view restriction + camera.resetRange(); + } + /** + * Update control to match projection's settings. + * @ko 현재 프로젝션의 세팅으로 컨트롤을 업데이트합니다. + * @param control - Instance of the control to update {@ko 업데이트할 컨트롤의 인스턴스} + * @since 4.0.0 + */ + updateControl(control) { + control.ignoreZoomScale = false; + } + /** + * Update projection. + * @ko 현재 프로젝션 정보를 갱신합니다. + * @param camera - Instance of the camera to reference {@ko 참조할 카메라의 인스턴스} + * @since 4.0.0 + */ + update(camera) {} // eslint-disable-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars + /** + * Return active texture. + * @ko 현재 활성화된 텍스쳐를 반환합니다. + * @internal + * @since 4.0.0 + */ + getTexture() { + if (!this._mesh) return null; + return this._mesh.program.uniforms.uTexture.texture; + } + /** + * A 3D triangle mesh for projection. It's `null` until loading the `src`. + * @ko Projection을 표시하기 위한 Mesh, src를 로드하기 전까지는 `null`입니다. + * @since 4.0.0 + */ + getMesh() { + return this._mesh; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +class Uniform { + constructor() { + this.needsUpdate = true; + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + destroy(gl) { + // DO_NOTHING + } +} + +class UniformTextureCube extends Uniform { + constructor(ctx, texture, cubemapOrder) { + super(); + this.texture = texture; + this._webglTexture = ctx.createWebGLCubeTexture(texture, texture.width); + this._cubemapOrder = cubemapOrder; + } + destroy(gl) { + this.texture.destroy(); + gl.deleteTexture(this._webglTexture); + } + update(gl, location, isWebGL2) { + const texture = this.texture; + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY); + gl.uniform1i(location, 0); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture); + const sources = reorderCube(texture.sources, this._cubemapOrder); + sources.forEach((src, idx) => { + if (isWebGL2) { + gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src); + } else { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src); + } + }); + if (!texture.isVideo()) { + this.needsUpdate = false; + } + } +} + +/** @hidden */ +class CubeTexturePainter { + get size() { + return this._size; + } + constructor(texture, cubemapOrder) { + this.texture = texture; + this._renderingOrder = reorderCube(range(6), cubemapOrder); + const canvas = document.createElement("canvas"); + this._calcRenderingSize(); + canvas.width = this._size; + canvas.height = this._size; + this._canvas = canvas; + this._ctx = canvas.getContext("2d"); + } + destroy() { + const canvas = this._canvas; + // release memories + canvas.width = 1; + canvas.height = 1; + this._canvas = null; + } + draw(gl, isWebGL2) { + const size = this._size; + const texture = this.texture; + let surfaceIdx = 0; + for (let row = 0; row < this._row; row++) { + for (let column = 0; column < this._column; column++) { + const x = size * column; + const y = size * row; + const renderingFace = this._renderingOrder[surfaceIdx]; + this._ctx.drawImage(texture.source, x, y, size, size, 0, 0, size, size); + if (isWebGL2) { + gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas); + } else { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas); + } + surfaceIdx++; + } + } + } + _calcRenderingSize() { + const { + width, + height + } = this.texture; + const aspect = width / height; + if (aspect === 1 / 6) { + this._size = width; + this._row = 6; + this._column = 1; + } else if (aspect === 6) { + this._size = height; + this._row = 1; + this._column = 6; + } else if (aspect === 2 / 3) { + this._size = width * 0.5; + this._row = 3; + this._column = 2; + } else { + this._size = width / 3; + this._row = 2; + this._column = 3; + } + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +class UniformCanvasCube extends Uniform { + get texture() { + return this._painter.texture; + } + constructor(ctx, texture, cubemapOrder) { + super(); + this._painter = new CubeTexturePainter(texture, cubemapOrder); + this._webglTexture = ctx.createWebGLCubeTexture(texture, this._painter.size); + } + destroy(gl) { + gl.deleteTexture(this._webglTexture); + this._painter.destroy(); + } + update(gl, location, isWebGL2) { + const texture = this.texture; + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + gl.uniform1i(location, 0); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture); + this._painter.draw(gl, isWebGL2); + if (!texture.isVideo()) { + this.needsUpdate = false; + } + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * @hidden + */ +class TriangleMesh extends Object3D { + constructor(vao, program) { + super(); + this.vao = vao; + this.program = program; + } + destroy(ctx) { + ctx.releaseVAO(this.vao); + ctx.releaseShaderResources(this.program); + } +} + +class ShaderProgram { + constructor(ctx, vertexShader, fragmentShader, uniforms) { + this.program = ctx.createProgram(vertexShader, fragmentShader); + this.uniforms = uniforms; + this.uniformLocations = ctx.getUniformLocations(this.program, uniforms); + } +} + +/** + * @hidden + */ +class VertexData { + /** */ + constructor(data, itemSize) { + this.data = data; + this.itemSize = itemSize; + this.count = data.length / itemSize; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * @hidden + */ +class Geometry { + /** */ + constructor(vertices, indicies, uvs) { + this.vertices = new VertexData(new Float32Array(vertices), 3); + this.indicies = new VertexData(new Uint16Array(indicies), 1); + this.uvs = new VertexData(new Float32Array(uvs), 2); + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * @hidden + */ +class CubeGeometry extends Geometry { + constructor({ + order, + rotateUV + }) { + const vertices = [ + // back + 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, + // front + -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, + // up + -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, + // down + -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, + // right + 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, + // left + -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1]; + const indicies = [0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23]; + const oneThird = 1 / 3; + const coords = []; + for (let r = 1; r >= 0; r--) { + for (let c = 0; c < 3; c++) { + const coord = [c * oneThird, r * 0.5, (c + 1) * oneThird, r * 0.5, (c + 1) * oneThird, (r + 1) * 0.5, c * oneThird, (r + 1) * 0.5]; + coords.push(coord); + } + } + if (rotateUV) { + rotateUV.forEach((degree, idx) => { + if (degree === ROTATE.ZERO) return; + const coord = coords[idx]; + let newOrder; + if (degree === ROTATE.CW_90) { + newOrder = [1, 2, 3, 0]; + } else if (degree === ROTATE.CCW_90) { + newOrder = [3, 0, 1, 2]; + } else { + newOrder = [2, 3, 0, 1]; + } + const newCoords = Array(coord.length); + for (let uvIdx = 0; uvIdx < coord.length / 2; uvIdx++) { + newCoords[uvIdx * 2 + 0] = coord[newOrder[uvIdx] * 2 + 0]; + newCoords[uvIdx * 2 + 1] = coord[newOrder[uvIdx] * 2 + 1]; + } + coords[idx] = newCoords; + }); + } + const uvs = reorderCube(coords, order, "BFUDRL").reduce((acc, val) => acc.concat(val), []); + super(vertices, indicies, uvs); + } +} + +var vs$3 = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec3 vPos;void main(){vPos=position;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}"; // eslint-disable-line + +var fs$3 = "#define GLSLIFY 1\nuniform samplerCube uTexture;varying highp vec3 vPos;void main(){gl_FragColor=textureCube(uTexture,vec3(vPos.x,vPos.y,-vPos.z));}"; // eslint-disable-line + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Projection based on cubemap images, accepts both multiple or single images. + * @ko 큐브맵 이미지 기반의 프로젝션, 단일 혹은 여러 장의 이미지를 모두 사용 가능합니다. + * @since 4.0.0 + * @category Projection + */ +class CubemapProjection extends Projection { + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param options Options {@ko Options} + */ + constructor(options) { + super(options); + const { + cubemapOrder = "RLUDFB", + cubemapFlipX = false + } = options; + this._cubemapOrder = cubemapOrder; + this._cubemapFlipX = cubemapFlipX; + } + applyTexture(ctx, texture) { + const cubemapOrder = this._cubemapOrder; + const cubemapFlipX = this._cubemapFlipX; + const uniforms = { + uTexture: texture.isCube() ? new UniformTextureCube(ctx, texture, cubemapOrder) : new UniformCanvasCube(ctx, texture, cubemapOrder) + }; + const geometry = new CubeGeometry({ + order: cubemapOrder + }); + const program = new ShaderProgram(ctx, vs$3, fs$3, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + if (cubemapFlipX) { + mesh.scale[0] = -1; + } + mesh.updateMatrix(); + this._mesh = mesh; + } +} + +class UniformTexture2D extends Uniform { + constructor(ctx, texture) { + super(); + this.texture = texture; + this._webglTexture = ctx.createWebGLTexture(texture); + } + destroy(gl) { + this.texture.destroy(); + gl.deleteTexture(this._webglTexture); + } + update(gl, location, isWebGL2) { + const texture = this.texture; + const isVideo = texture.isVideo(); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY); + gl.uniform1i(location, 0); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, this._webglTexture); + if (!isVideo && isWebGL2) { + gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); + } + if (!isVideo) { + this.needsUpdate = false; + } + } +} + +var vs$2 = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec2 vUV;void main(){vUV=uv;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}"; // eslint-disable-line + +var fs$2 = "#define GLSLIFY 1\nuniform sampler2D uTexture;varying highp vec2 vUV;void main(){gl_FragColor=texture2D(uTexture,vUV.st);}"; // eslint-disable-line + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Projection based on cubemap strip. + * Slightly more efficient than {@link CubemapProjection} as it doesn't copy cubemap image to canvas while rendering. + * Accepts only single image. + * @ko 큐브맵 스트립 기반의 프로젝션. + * {@link CubemapProjection}와 달리 렌더링하는 과정에 캔버스에 이미지를 복사하는 과정이 없기 때문에 살짝 더 효율적입니다. + * 단일 이미지만 사용 가능합니다. + * @since 4.0.0 + * @category Projection + */ +class CubestripProjection extends Projection { + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param options Options {@ko Options} + */ + constructor(options) { + super(options); + const { + cubemapOrder = "RLUDFB", + cubemapFlipX = false + } = options; + this._cubemapOrder = cubemapOrder; + this._cubemapFlipX = cubemapFlipX; + } + applyTexture(ctx, texture) { + const cubemapOrder = this._cubemapOrder; + const cubemapFlipX = this._cubemapFlipX; + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture) + }; + const geometry = new CubeGeometry({ + order: cubemapOrder + }); + const program = new ShaderProgram(ctx, vs$2, fs$2, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + if (cubemapFlipX) { + mesh.scale[0] = -1; + } + mesh.updateMatrix(); + this._mesh = mesh; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * @hidden + */ +class CylinderGeometry extends Geometry { + constructor(maxTheta) { + const vertices = []; + const indicies = []; + const uvs = []; + const height = 1; + const radialSegments = 60; + const halfHeight = height * 0.5; + const heightSegments = [-halfHeight, halfHeight]; + const invRadialSegments = 1 / radialSegments; + const angleConst = maxTheta * invRadialSegments; + for (let yIdx = 0; yIdx < 2; yIdx++) { + const y = heightSegments[yIdx]; + for (let lngIdx = 0; lngIdx <= radialSegments; lngIdx++) { + const angle = lngIdx * angleConst + Math.PI - maxTheta * 0.5; + const x = Math.cos(angle); + const z = Math.sin(angle); + const u = lngIdx * invRadialSegments; + const v = yIdx; + uvs.push(u, v); + vertices.push(x, y, z); + if (yIdx === 0 && lngIdx < radialSegments) { + const a = lngIdx; + const b = a + radialSegments + 1; + indicies.push(a, b, a + 1, b, b + 1, a + 1); + } + } + } + super(vertices, indicies, uvs); + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license +*/ +/** + * Projection based on cylindrical projection. + * This can show panorama images taken from smartphones. + * @ko 원통 투영법 기반의 프로젝션. + * 일반적인 스마트폰 파노라마 사진을 표시하는데 사용될 수 있습니다. + * @since 4.0.0 + * @category Projection + */ +class CylindricalProjection extends Projection { + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param options Options {@ko Options} + */ + constructor(options) { + super(options); + const { + partial = false + } = options; + this._partial = partial; + } + applyTexture(ctx, texture) { + const partial = this._partial; + const { + width, + height + } = texture; + const aspect = width / height; + const halfVFov = 180 / aspect; + const cylinderHeight = partial ? 1 : 2 * Math.tan(halfVFov * DEG_TO_RAD); + const cylinderTheta = partial ? aspect : 2 * Math.PI; + const geometry = new CylinderGeometry(cylinderTheta); + const program = new ShaderProgram(ctx, vs$2, fs$2, { + uTexture: new UniformTexture2D(ctx, texture) + }); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + mesh.scale[1] = cylinderHeight; + quat.identity(mesh.rotation); + quat.rotateY(mesh.rotation, mesh.rotation, -Math.PI / 2); + mesh.updateMatrix(); + this._mesh = mesh; + } + updateCamera(camera) { + super.updateCamera(camera); + const mesh = this._mesh; + if (!mesh) return; + const uTexture = mesh.program.uniforms.uTexture; + const texture = uTexture.texture; + const { + width, + height + } = texture; + const aspect = width / height; + const halfHeight = mesh.scale[1] * 0.5; + if (this._partial) { + const restrictedYaw = 0.5 * aspect * RAD_TO_DEG; + camera.restrictYawRange(-restrictedYaw, restrictedYaw); + } + const restrictedPitch = Math.atan2(halfHeight, 1) * RAD_TO_DEG; + const minZoom = Math.tan(camera.fov * DEG_TO_RAD * 0.5) / (halfHeight * camera.aspect); + camera.restrictPitchRange(-restrictedPitch, restrictedPitch); + camera.restrictZoomRange(minZoom, Infinity); + camera.restrictRenderHeight(halfHeight * 2); + } +} + +var fs$1 = "#define PI 3.14159265359\nprecision mediump float;\n#define GLSLIFY 1\nuniform sampler2D uTexture;varying highp vec2 vUV;const vec2 OPERATE_COORDS_RANGE=vec2(-1.0,1.0);const vec2 TEXTURE_COORDS_RANGE=vec2(0.0,1.0);const float ONE_THIRD=1.0/3.0;const float EAC_CONST=2.0/PI;float scale(vec2 domainRange,vec2 targetRange,float val){float unit=1.0/(domainRange[1]-domainRange[0]);return targetRange[0]+(targetRange[1]-targetRange[0])*(val-domainRange[0])*unit;}void main(void){float transformedCoordX;float transformedCoordY;float texRangeXStart=floor(vUV.s*3.)*ONE_THIRD;float texRangeYStart=floor(vUV.t*2.)*0.5;vec2 orgTextureRangeX=vec2(texRangeXStart,texRangeXStart+ONE_THIRD);vec2 orgTextureRangeY=vec2(texRangeYStart,texRangeYStart+0.5);float px=scale(orgTextureRangeX,OPERATE_COORDS_RANGE,vUV.s);float py=scale(orgTextureRangeY,OPERATE_COORDS_RANGE,vUV.t);float qu=EAC_CONST*atan(px)+0.5;float qv=EAC_CONST*atan(py)+0.5;transformedCoordX=scale(TEXTURE_COORDS_RANGE,orgTextureRangeX,qu);transformedCoordY=scale(TEXTURE_COORDS_RANGE,orgTextureRangeY,qv);gl_FragColor=texture2D(uTexture,vec2(transformedCoordX,transformedCoordY));}"; // eslint-disable-line + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Equi-Angular Cubemap Projection. + * This format is used by Youtube's 360 videos. + * @ko Equi-Angular Cubemap 프로젝션. + * 이 포맷은 주로 Youtube의 360 비디오에 사용됩니다. + * @since 4.0.0 + * @category Projection + */ +class EquiangularProjection extends Projection { + applyTexture(ctx, texture) { + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture) + }; + const geometry = new CubeGeometry({ + order: "LFRDBU", + rotateUV: [ROTATE.ZERO, ROTATE.ZERO, ROTATE.ZERO, ROTATE.CW_90, ROTATE.CCW_90, ROTATE.CW_90] + }); + const program = new ShaderProgram(ctx, vs$2, fs$1, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * @hidden + */ +class SphereGeometry extends Geometry { + /** */ + constructor() { + // const radius = 1; + const widthSegments = 60; + const heightSegments = 60; + const ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI; + const uvs = []; + const vertices = []; + const indicies = []; + let latIdx; + let lngIdx; + for (latIdx = 0; latIdx <= widthSegments; latIdx++) { + const theta = (latIdx / widthSegments - 0.5) * Math.PI; + const sinTheta = Math.sin(theta); + const cosTheta = Math.cos(theta); + for (lngIdx = 0; lngIdx <= heightSegments; lngIdx++) { + const phi = (lngIdx / heightSegments - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN; + const sinPhi = Math.sin(phi); + const cosPhi = Math.cos(phi); + const x = cosPhi * cosTheta; + const y = sinTheta; + const z = sinPhi * cosTheta; + const u = lngIdx / heightSegments; + const v = latIdx / widthSegments; + uvs.push(u, v); + vertices.push(x, y, z); + if (lngIdx !== heightSegments && latIdx !== widthSegments) { + const a = latIdx * (heightSegments + 1) + lngIdx; + const b = a + heightSegments + 1; + indicies.push(a, a + 1, b, b, a + 1, b + 1); + } + } + } + super(vertices, indicies, uvs); + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Projection based on equirectangular projection. + * @ko 등 장방형 도법(Equirectangular projection) 기반의 프로젝션 + * @since 4.0.0 + * @category Projection + */ +class EquirectProjection extends Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor(options) { + super(options); + } + applyTexture(ctx, texture) { + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture) + }; + const geometry = new SphereGeometry(); + const program = new ShaderProgram(ctx, vs$2, fs$2, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +class UniformFloat extends Uniform { + constructor(val) { + super(); + this.val = val; + } + update(gl, location) { + gl.uniform1f(location, this.val); + this.needsUpdate = false; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * @hidden + */ +class PlaneGeometry extends Geometry { + /** */ + constructor(width = 2, height = 2, z = -1) { + const halfWidth = width * 0.5; + const halfHeight = height * 0.5; + const vertices = [-halfWidth, -halfHeight, z, halfWidth, -halfHeight, z, -halfWidth, halfHeight, z, halfWidth, halfHeight, z]; + const indicies = [0, 1, 2, 2, 1, 3]; + const uvs = [0, 0, 1, 0, 0, 1, 1, 1]; + super(vertices, indicies, uvs); + } +} + +var vs$1 = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec2 vUV;void main(){vUV=uv;gl_Position=vec4(position,1.0);}"; // eslint-disable-line + +var fs = "precision mediump float;\n#define GLSLIFY 1\nuniform sampler2D uTexture;uniform float uYaw;uniform float uPitch;uniform float uZoom;varying highp vec2 vUV;const float PI=3.1415926536;const float PI_2=PI*0.5;vec2 toStereographicUV(in vec2 uv,in vec2 center){float R=1.*uZoom;vec2 texLatLon=(uv*2.-1.)*vec2(PI,PI_2);vec2 central=(center*2.-1.)*vec2(PI,PI_2)+vec2(PI,0);float x=texLatLon.x;float y=texLatLon.y;float rou=sqrt(x*x+y*y);float c=2.0*atan(rou,R*0.5);float sin_c=sin(c);float cos_c=cos(c);float sin_cy=sin(central.y);float cos_cy=cos(central.y);float lat=asin(cos_c*sin_cy+(y*sin_c*cos_cy)/rou);float lon=central.x+atan(x*sin_c,rou*cos_cy*cos_c-y*sin_cy*sin_c);float u=(lon/PI+1.0)*0.5;float v=(lat/PI_2+1.0)*0.5;return vec2(u,v);}void main(){vec2 central=vec2(uYaw,uPitch);vec2 uv=toStereographicUV(vUV,central);gl_FragColor=texture2D(uTexture,uv);}"; // eslint-disable-line + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Projection based on so-called "Little planet" or "Tiny planet" effect. + * @ko "Little planet" 혹은 "Tiny planet"로 불리는 이펙트 기반의 프로젝션 + * @since 4.0.0 + * @category Projection + */ +class LittlePlanetProjection extends Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor(options) { + super(options); + } + applyTexture(ctx, texture) { + texture.wrapS = WebGLRenderingContext.REPEAT; + texture.wrapT = WebGLRenderingContext.REPEAT; + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture), + uYaw: new UniformFloat(0), + uPitch: new UniformFloat(0.5), + uZoom: new UniformFloat(1) + }; + const geometry = new PlaneGeometry(); + const program = new ShaderProgram(ctx, vs$1, fs, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } + updateControl(control) { + control.ignoreZoomScale = true; + } + update(camera) { + const mesh = this._mesh; + if (!mesh) return; + const uniforms = mesh.program.uniforms; + uniforms.uYaw.val = camera.yaw / 360; + // Range from 0 ~ 1 + uniforms.uPitch.val = camera.pitch / 180 + 0.5; + uniforms.uZoom.val = camera.zoom; + uniforms.uYaw.needsUpdate = true; + uniforms.uPitch.needsUpdate = true; + uniforms.uZoom.needsUpdate = true; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +class UniformVector4Array extends Uniform { + constructor(val) { + super(); + this.val = val; + } + update(gl, location) { + gl.uniform4fv(location, this.val.reduce((arr, vector) => [...arr, ...vector], [])); + this.needsUpdate = false; + } +} + +var vs = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;uniform vec4 uTexScaleOffset[2];uniform float uEye;varying highp vec2 vUV;void main(){vec4 scaleOffset=uTexScaleOffset[int(uEye)];vUV=uv.xy*scaleOffset.xy+scaleOffset.zw;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}"; // eslint-disable-line + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Projection based on stereo equirectangular images. + * @ko Stereo equirectangular 이미지 기반의 프로젝션 + * @since 4.0.0 + * @category Projection + */ +class StereoEquiProjection extends Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor(options) { + super(options); + this._mode = options.mode; + } + applyTexture(ctx, texture) { + let leftEye; + let rightEye; + switch (this._mode) { + case StereoEquiProjection.MODE.LEFT_RIGHT: + leftEye = [0.5, 1, 0, 0]; + rightEye = [0.5, 1, 0.5, 0]; + break; + default: + // Default, uses "top_bottom" + leftEye = [1, 0.5, 0, 0]; + rightEye = [1, 0.5, 0, 0.5]; + } + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture), + uEye: new UniformFloat(0), + uTexScaleOffset: new UniformVector4Array([leftEye, rightEye]) + }; + const geometry = new SphereGeometry(); + const program = new ShaderProgram(ctx, vs, fs$2, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } +} +/** + * Available stereoscopic modes + * @ko 사용가능한 스테레오스코픽 모드들 + * @since 4.0.0 + */ +StereoEquiProjection.MODE = { + /** + * @ko 이미지가 왼쪽/오른쪽으로 구성되어있을 경우 + * @since 4.0.0 + */ + LEFT_RIGHT: "left_right", + /** + * @ko 이미지가 위/아래로 구성되어있을 경우 + * @since 4.0.0 + */ + TOP_BOTTOM: "top_bottom" +}; + +/** + * @hidden + */ +const withMethods = (prototype, attr) => { + [Component.prototype, View360.prototype].forEach(proto => { + Object.getOwnPropertyNames(proto).filter(name => name.charAt(0) !== "_" && name !== "constructor").forEach(name => { + const descriptor = Object.getOwnPropertyDescriptor(proto, name); + if (descriptor.value) { + // Public Function + Object.defineProperty(prototype, name, { + value: function (...args) { + return descriptor.value.call(this[attr], ...args); + } + }); + } else { + const getterDescriptor = {}; + if (descriptor.get) { + getterDescriptor.get = function () { + var _a; + return this[attr] && ((_a = descriptor.get) === null || _a === void 0 ? void 0 : _a.call(this[attr])); + }; + } + if (descriptor.set) { + getterDescriptor.set = function (...args) { + var _a; + return (_a = descriptor.set) === null || _a === void 0 ? void 0 : _a.call(this[attr], ...args); + }; + } + Object.defineProperty(prototype, name, getterDescriptor); + } + }); + }); +}; + +/** + * @hidden + */ +const getValidProps = propsObj => { + return Object.keys(propsObj).reduce((props, propName) => { + if (propsObj[propName] != null) { + props[propName] = propsObj[propName]; + } + return props; + }, {}); +}; + +const VIEW360_METHODS = ["destroy", "init", "load", "resize", "addPlugins", "removePlugins", "renderFrame", +// @egjs/component methods +"on", "hasOn", "once", "off", "trigger"]; + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + +export { AutoResizer, Autoplay, Camera, CameraAnimation, ControlBar, ControlBarItem, CubemapProjection, CubestripProjection, CylindricalProjection, DEFAULT_CLASS, EASING, ERROR_CODES, EVENTS, EquiangularProjection, EquirectProjection, FullscreenButton, GyroControl, Hotspot, HotspotRenderer, LittlePlanetProjection, LoadingSpinner, Motion, Object3D, PanoControl, PieView, PlayButton, ProgressBar, Projection, RotateControl, StereoEquiProjection, VIEW360_METHODS, VideoTime, View360Error, VolumeControl, WebGLRenderer, XRManager, ZoomControl, View360 as default, getValidProps, withMethods }; +//# sourceMappingURL=view360.esm.js.map diff --git a/demo/release/4.0.0-beta.4/dist/view360.esm.js.map b/demo/release/4.0.0-beta.4/dist/view360.esm.js.map new file mode 100644 index 000000000..86bd2e15a --- /dev/null +++ b/demo/release/4.0.0-beta.4/dist/view360.esm.js.map @@ -0,0 +1 @@ +{"version":3,"file":"view360.esm.js","sources":["../src/core/View360Error.ts","../src/const/error.ts","../src/const/browser.ts","../src/const/external.ts","../src/const/internal.ts","../src/utils.ts","../src/core/Motion.ts","../src/core/CameraAnimation.ts","../src/core/Camera.ts","../src/control/input/MouseInput.ts","../src/control/input/TouchInput.ts","../src/control/input/KeyboardInput.ts","../src/control/RotateControl.ts","../src/control/input/WheelInput.ts","../src/control/input/PinchInput.ts","../src/control/ZoomControl.ts","../src/control/input/GyroInput.ts","../src/control/GyroControl.ts","../src/control/PanoControl.ts","../src/texture/Texture.ts","../src/texture/Texture2D.ts","../src/texture/TextureVideo.ts","../src/texture/TextureCube.ts","../src/core/TextureLoader.ts","../src/core/FrameAnimator.ts","../src/core/AutoResizer.ts","../src/core/Autoplay.ts","../src/core/XRManager.ts","../src/hotspot/Hotspot.ts","../src/hotspot/HotspotRenderer.ts","../src/core/VertexArrayObject.ts","../src/core/WebGLContext.ts","../src/core/WebGLRenderer.ts","../src/View360.ts","../src/core/Object3D.ts","../src/plugin/LoadingSpinner/LoadingSpinner.ts","../src/plugin/ControlBar/ControlBarItem.ts","../src/plugin/ControlBar/const.ts","../src/plugin/ControlBar/RangeControl.ts","../src/plugin/ControlBar/ProgressBar.ts","../src/plugin/ControlBar/PlayButton.ts","../src/plugin/ControlBar/VolumeControl.ts","../src/plugin/ControlBar/FullscreenButton.ts","../src/plugin/ControlBar/VideoTime.ts","../src/plugin/ControlBar/PieView.ts","../src/plugin/ControlBar/VRButton.ts","../src/plugin/ControlBar/GyroButton.ts","../src/plugin/ControlBar/AutoHide.ts","../src/plugin/ControlBar/VideoControl.ts","../src/plugin/ControlBar/ControlBar.ts","../src/projection/Projection.ts","../src/uniform/Uniform.ts","../src/uniform/UniformTextureCube.ts","../src/core/CubeTexturePainter.ts","../src/uniform/UniformCanvasCube.ts","../src/core/TriangleMesh.ts","../src/core/ShaderProgram.ts","../src/core/VertexData.ts","../src/geometry/Geometry.ts","../src/geometry/CubeGeometry.ts","../src/projection/CubemapProjection.ts","../src/uniform/UniformTexture2D.ts","../src/projection/CubestripProjection.ts","../src/geometry/CylinderGeometry.ts","../src/projection/CylindricalProjection.ts","../src/projection/EquiangularProjection.ts","../src/geometry/SphereGeometry.ts","../src/projection/EquirectProjection.ts","../src/uniform/UniformFloat.ts","../src/geometry/PlaneGeometry.ts","../src/projection/LittlePlanetProjection.ts","../src/uniform/UniformVector4Array.ts","../src/projection/StereoEquiProjection.ts","../src/cfc/withMethods.ts","../src/cfc/utils.ts","../src/cfc/const.ts","../src/index.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * Error thrown by {@link View360}\n * @ko {@link View360}이 발생시킨 에러\n * @since 4.0.0\n */\nclass View360Error extends Error {\n /**\n * Error code\n * @ko 에러 코드\n * @see ERROR_CODES\n */\n public code: number;\n\n /**\n * Create new instance of View360Error\n * @ko View360Error의 인스턴스를 생성합니다.\n * @param message - Error message {@ko 에러 메시지}\n * @param code - Error code {@ko 에러 코드}\n */\n public constructor(message: string, code: number) {\n super(message);\n\n Object.setPrototypeOf(this, View360Error.prototype);\n\n this.name = \"View360Error\";\n this.code = code;\n }\n}\n\nexport default View360Error;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * Error codes of {@link View360Error}\n * @ko {@link View360Error}가 가질 수 있는 에러 코드 값들\n * @since 4.0.0\n */\nexport const ERROR_CODES = {\n /**\n * The given value's type is not expected\n * @ko 주어진 값의 타입이 잘못되었을 경우\n * @since 4.0.0\n */\n WRONG_TYPE: 0,\n /**\n * The given value is not a supported option\n * @ko 잘못된 옵션을 받았을 경우\n * @since 4.0.0\n */\n WRONG_OPTION: 1,\n /**\n * The element with given CSS selector does not exist\n * @ko 주어진 CSS 셀렉터로 엘리먼트를 찾지 못했을 경우\n * @since 4.0.0\n */\n ELEMENT_NOT_FOUND: 2,\n /**\n * Couldn't find canvas element inside the given container element.\n * @ko 컨테이너 엘리먼트 내부에서 캔버스 엘리먼트를 찾지 못했을 경우\n * @since 4.0.0\n */\n CANVAS_NOT_FOUND: 3,\n /**\n * The browser does not support WebGL\n * @ko 브라우저가 WebGL을 지원하지 않는 경우\n * @since 4.0.0\n */\n WEBGL_NOT_SUPPORTED: 4,\n /**\n * Failed creating canvas 2D context\n * @ko 캔버스 2D 컨텍스트를 생성하지 못한 경우\n * @since 4.0.0\n */\n FAILED_CREATE_CONTEXT_2D: 5,\n /**\n * `init()` is called before setting {@link View360Options#projection}\n * @ko {@link View360Options#projection}을 설정하기 전에 `init()`이 호출된 경우\n * @since 4.0.0\n */\n PROVIDE_PROJECTION_FIRST: 6,\n /**\n * Failed linking WebGL program. Only can be thrown when {@link View360Options#debug} is `true`.\n * @ko WebGL 프로그램 링크에 실패한 경우. {@link View360Options#debug}를 `true`로 설정한 경우에만 발생할 수 있습니다.\n * @since 4.0.0\n */\n FAILED_LINKING_PROGRAM: 7,\n /**\n * Arguments are not sufficient for the given property.\n * @ko 프로퍼티에 값이 충분히 주어지지 않았을 때\n * @since 4.0.0\n */\n INSUFFICIENT_ARGS: 8\n} as const;\n\nexport const MESSAGES = {\n WRONG_TYPE: (val: any, types: string[]) => `${typeof val} is not a ${types.map(type => `\"${type}\"`).join(\" or \")}.`,\n WRONG_OPTION: (val: any, optionName: string) => `Bad option: given \"${val}\" for option \"${optionName}\".`,\n ELEMENT_NOT_FOUND: (query: string) => `Element with selector \"${query}\" not found.`,\n CANVAS_NOT_FOUND: \"The canvas element was not found inside the given root element.\",\n WEBGL_NOT_SUPPORTED: \"WebGL is not supported on this browser.\",\n FAILED_CREATE_CONTEXT_2D: \"Failed to create canvas 2D context\",\n PROVIDE_PROJECTION_FIRST: \"\\\"projection\\\" should be provided before initialization.\",\n FAILED_LINKING_PROGRAM: (msg: string | null, shaderLog: string | null) => `Failed linking WebGL program - \"${msg}\\nShader compile Log: ${shaderLog}`,\n INSUFFICIENT_ARGS: (val: any, name: string) => `Insufficient arguments: given \"${val}\" for \"${name}\".`\n};\n\nexport default {\n CODES: ERROR_CODES,\n MESSAGES\n};\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nexport const EVENTS = {\n MOUSE_DOWN: \"mousedown\",\n MOUSE_MOVE: \"mousemove\",\n MOUSE_UP: \"mouseup\",\n TOUCH_START: \"touchstart\",\n TOUCH_MOVE: \"touchmove\",\n TOUCH_END: \"touchend\",\n WHEEL: \"wheel\",\n RESIZE: \"resize\",\n CONTEXT_MENU: \"contextmenu\",\n MOUSE_ENTER: \"mouseenter\",\n MOUSE_LEAVE: \"mouseleave\",\n POINTER_DOWN: \"pointerdown\",\n POINTER_MOVE: \"pointermove\",\n POINTER_UP: \"pointerup\",\n POINTER_CANCEL: \"pointercancel\",\n POINTER_ENTER: \"pointerenter\",\n POINTER_LEAVE: \"pointerleave\",\n KEY_DOWN: \"keydown\",\n KEY_UP: \"keyup\",\n LOAD: \"load\",\n ERROR: \"error\",\n CLICK: \"click\",\n DOUBLE_CLICK: \"dblclick\",\n CONTEXT_CREATE_ERROR: \"webglcontextcreationerror\",\n CONTEXT_LOST: \"webglcontextlost\",\n CONTEXT_RESTORED: \"webglcontextrestored\",\n DEVICE_ORIENTATION: \"deviceorientation\",\n DEVICE_MOTION: \"devicemotion\",\n ORIENTATION_CHANGE: \"orientationchange\",\n VIDEO_PLAY: \"play\",\n VIDEO_PAUSE: \"pause\",\n VIDEO_LOADED_DATA: \"loadeddata\",\n VIDEO_VOLUME_CHANGE: \"volumechange\",\n VIDEO_TIME_UPDATE: \"timeupdate\",\n VIDEO_DURATION_CHANGE: \"durationchange\",\n VIDEO_CAN_PLAYTHROUGH: \"canplaythrough\",\n TRANSITION_END: \"transitionend\",\n XR_END: \"end\"\n} as const;\n\nexport const EL_DIV = \"div\";\nexport const EL_BUTTON = \"button\";\n\n// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button\nexport enum MOUSE_BUTTON {\n LEFT,\n MIDDLE,\n RIGHT\n}\n\nexport const CURSOR = {\n GRAB: \"grab\",\n GRABBING: \"grabbing\",\n NONE: \"\"\n} as const;\n\nexport const KEY_DIRECTION = [\"LEFT\", \"UP\", \"RIGHT\", \"DOWN\"] as const;\nexport enum DIRECTION_KEY_CODE {\n LEFT = 37,\n UP = 38,\n RIGHT = 39,\n DOWN = 40\n}\nexport const SPACE_KEY_CODE = 32;\n\nexport const DIRECTION_KEY_NAME = {\n LEFT: \"ArrowLeft\",\n UP: \"ArrowUp\",\n RIGHT: \"ArrowRight\",\n DOWN: \"ArrowDown\"\n} as const;\nexport const SPACE_KEY_NAME = \" \";\n\nexport const FULLSCREEN_REQUEST = [\n \"requestFullscreen\",\n \"webkitRequestFullscreen\",\n \"webkitRequestFullScreen\",\n \"webkitCancelFullScreen\",\n \"mozRequestFullScreen\",\n \"msRequestFullscreen\"\n];\n\nexport const FULLSCREEN_ELEMENT = [\n \"fullscreenElement\",\n \"webkitFullscreenElement\",\n \"webkitCurrentFullScreenElement\",\n \"mozFullScreenElement\",\n \"msFullscreenElement\"\n];\n\nexport const FULLSCREEN_EXIT = [\n \"exitFullscreen\",\n \"webkitExitFullscreen\",\n \"webkitCancelFullScreen\",\n \"mozCancelFullScreen\",\n \"msExitFullscreen\"\n];\n\nexport const FULLSCREEN_CHANGE = [\n \"fullscreenchange\",\n \"webkitfullscreenchange\",\n \"mozfullscreenchange\",\n \"MSFullscreenChange\"\n];\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nexport { ERROR_CODES } from \"./error\";\n\n/**\n * Default class names\n * @ko 기본 클래스 이름들\n * @since 4.0.0\n */\nexport const DEFAULT_CLASS = {\n CONTAINER: \"view360-container\",\n CANVAS: \"view360-canvas\",\n CTX_LOST: \"view360-ctx-lost\",\n IN_VR: \"view360-vr-presenting\",\n HOTSPOT_CONTAINER: \"view360-hotspots\",\n HOTSPOT: \"view360-hotspot\",\n HOTSPOT_VISIBLE: \"view360-hotspot-visible\",\n HOTSPOT_FLIP_X: \"view360-hotspot-flip-x\",\n HOTSPOT_FLIP_Y: \"view360-hotspot-flip-y\",\n} as const;\n\n/**\n * Event names\n * @ko 이벤트 이름들\n * @since 4.0.0\n * @example\n * ```ts\n * import View360, { EVENTS } from \"@egjs/view360\";\n *\n * const viewer = new View360(\"#el_id\");\n *\n * viewer.on(EVENTS.READY, evt => {\n * console.log(\"View360 is ready!\");\n * });\n * ```\n */\nexport const EVENTS = {\n READY: \"ready\",\n LOAD_START: \"loadStart\",\n LOAD: \"load\",\n PROJECTION_CHANGE: \"projectionChange\",\n RESIZE: \"resize\",\n BEFORE_RENDER: \"beforeRender\",\n RENDER: \"render\",\n INPUT_START: \"inputStart\",\n INPUT_END: \"inputEnd\",\n VIEW_CHANGE: \"viewChange\",\n STATIC_CLICK: \"staticClick\",\n VR_START: \"vrStart\",\n VR_END: \"vrEnd\"\n} as const;\n\n/**\n * Collection of predefined easing functions\n * @ko 미리 정의된 easing 함수들\n */\nexport const EASING = {\n LINEAR: (x: number) => x,\n SINE_WAVE: (x: number) => Math.sin(x * Math.PI * 2),\n EASE_OUT_CUBIC: (x: number) => 1 - Math.pow(1 - x, 3),\n EASE_OUT_BOUNCE: (x: number): number => {\n const n1 = 7.5625;\n const d1 = 2.75;\n\n if (x < 1 / d1) {\n return n1 * x * x;\n } else if (x < 2 / d1) {\n return n1 * (x -= 1.5 / d1) * x + 0.75;\n } else if (x < 2.5 / d1) {\n return n1 * (x -= 2.25 / d1) * x + 0.9375;\n } else {\n return n1 * (x -= 2.625 / d1) * x + 0.984375;\n }\n }\n} as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { EASING } from \"./external\";\nimport { Range } from \"../type/utils\";\n\nexport const CAMERA_EVENTS = {\n CHANGE: \"change\",\n ANIMATION_END: \"animationEnd\"\n} as const;\n\nexport const CONTROL_EVENTS = {\n INPUT_START: \"inputStart\",\n CHANGE: \"change\",\n INPUT_END: \"inputEnd\",\n ENABLE: \"enable\",\n DISABLE: \"disable\",\n STATIC_CLICK: \"staticClick\"\n} as const;\n\nexport const DEG_TO_RAD = Math.PI / 180;\nexport const RAD_TO_DEG = 180 / Math.PI;\nexport const DEFAULT_EASING = EASING.EASE_OUT_CUBIC;\nexport const DEFAULT_ANIMATION_DURATION = 300;\nexport const INFINITE_RANGE: Readonly = {\n min: -Infinity, max: Infinity\n} as const;\nexport const DEFAULT_PITCH_RANGE: Readonly = {\n min: -90, max: 90\n} as const;\nexport const DEFAULT_ZOOM_RANGE: Readonly = {\n min: 0.6, max: 10\n} as const;\n\nexport enum ROTATE {\n ZERO,\n CW_90,\n CCW_90,\n CW_180\n}\n\n// Custom event name for video time change\nexport const VIDEO_TIME_CHANGE_EVENT = \"view360videotimechange\";\nexport const SVG_NAMESPACE = \"http://www.w3.org/2000/svg\";\nexport const SESSION_VR = \"immersive-vr\";\nexport const XR_REFERENCE_SPACE = \"local\";\n\nexport const EPSILON = Number.EPSILON ?? 2.220446049250313e-16;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { quat, vec3 } from \"gl-matrix\";\nimport View360Error from \"./core/View360Error\";\nimport ERROR from \"./const/error\";\nimport * as BROWSER from \"./const/browser\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"./const/internal\";\nimport { NoBoolean } from \"./type/utils\";\n\nexport const isString = (val: any): val is string => typeof val === \"string\";\nexport const isElement = (val: any): val is Element => !!val && val.nodeType === Node.ELEMENT_NODE;\n\nexport const createElement = (className: string, tag = BROWSER.EL_DIV) => {\n const el = document.createElement(tag);\n\n el.classList.add(className);\n\n return el;\n};\n\nexport const getNullableElement = (el: HTMLElement | string | null, parent?: HTMLElement): HTMLElement | null => {\n let targetEl: HTMLElement | null = null;\n\n if (isString(el)) {\n const parentEl = parent ? parent : document;\n const queryResult = parentEl.querySelector(el);\n\n if (!queryResult) {\n return null;\n }\n\n targetEl = queryResult as HTMLElement;\n } else if (isElement(el)) {\n targetEl = el;\n }\n\n return targetEl;\n};\n\nexport const getElement = (el: HTMLElement | string, parent?: HTMLElement): HTMLElement => {\n const targetEl = getNullableElement(el, parent);\n\n if (!targetEl) {\n if (isString(el)) {\n throw new View360Error(ERROR.MESSAGES.ELEMENT_NOT_FOUND(el), ERROR.CODES.ELEMENT_NOT_FOUND);\n } else {\n throw new View360Error(ERROR.MESSAGES.WRONG_TYPE(el, [\"HTMLElement\", \"string\"]), ERROR.CODES.WRONG_TYPE);\n }\n }\n\n return targetEl;\n};\n\nexport const findCanvas = (root: HTMLElement, selector: string): HTMLCanvasElement => {\n const canvas = root.querySelector(selector) as HTMLCanvasElement;\n\n if (!canvas) {\n throw new View360Error(ERROR.MESSAGES.CANVAS_NOT_FOUND, ERROR.CODES.CANVAS_NOT_FOUND);\n }\n\n return canvas;\n};\n\nexport const range = (end: number): number[] => {\n if (!end || end <= 0) {\n return [];\n }\n\n return Array.apply(0, Array(end)).map((undef, idx) => idx);\n};\n\nexport const clamp = (x: number, min: number, max: number) => Math.max(Math.min(x, max), min);\n\n// Linear interpolation between a and b\nexport const lerp = (a: number, b: number, t: number) => {\n return a * (1 - t) + b * t;\n};\n\nexport const circulate = (val: number, min: number, max: number) => {\n const size = Math.abs(max - min);\n\n if (val < min) {\n const offset = (min - val) % size;\n val = max - offset;\n } else if (val > max) {\n const offset = (val - max) % size;\n val = min + offset;\n }\n\n return val;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const merge = (target: object, ...srcs: object[]): object => {\n srcs.forEach(source => {\n Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n });\n });\n\n return target;\n};\n\nexport const findIndex = (array: T[], checker: (val: T) => boolean): number => {\n for (let idx = 0; idx < array.length; idx++) {\n if (checker(array[idx])) {\n return idx;\n }\n }\n\n return -1;\n};\n\nexport const getObjectOption = >(val?: T): NoBoolean => typeof val === \"object\" ? val : {} as any;\nexport const toVerticalFov = (fovRadian: number, aspect: number) => {\n return Math.atan(Math.tan(fovRadian * 0.5) / aspect) * 2;\n};\n\nexport const reorderCube = (arr: T[], order: string, defaultOrder = \"RLUDFB\"): T[] => {\n return defaultOrder.split(\"\")\n .map(face => order.indexOf(face))\n .map(index => arr[index]);\n};\n\nexport const isFullscreen = () => {\n if (!document) return false;\n\n for (const key of BROWSER.FULLSCREEN_ELEMENT) {\n if (document[key]) return true;\n }\n\n return false;\n};\n\nexport const sensorCanBeEnabledIOS = () => {\n return !!DeviceMotionEvent && \"requestPermission\" in DeviceMotionEvent && window.isSecureContext;\n};\n\nexport const hfovToZoom = (baseFov: number, fov: number) => {\n const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5);\n const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5);\n\n return renderingWidth / zoomedWidth;\n};\n\nexport const eulerToQuat = (out: quat, yaw: number, pitch: number, roll: number): quat => {\n quat.identity(out);\n\n const pitchThreshold = 0.01;\n const pitchClamped = clamp(pitch, -90 + pitchThreshold, 90 - pitchThreshold);\n\n quat.rotateY(out, out, yaw * DEG_TO_RAD);\n quat.rotateX(out, out, pitchClamped * DEG_TO_RAD);\n quat.rotateZ(out, out, roll * DEG_TO_RAD);\n\n return out;\n};\n\n/**\n * Extract euler angles from the quaternion, except roll(z-axis rotation)\n * @hidden\n */\nexport const quatToEuler = (quaternion: quat) => {\n const x = quaternion[0];\n const y = quaternion[1];\n const z = quaternion[2];\n const w = quaternion[3];\n const x2 = x * x;\n const y2 = y * y;\n const z2 = z * z;\n const w2 = w * w;\n\n const unit = x2 + y2 + z2 + w2;\n const test = x * w - y * z;\n\n let pitch: number, yaw: number;\n\n if (test > 0.499995 * unit) {\n // singularity at the north pole\n pitch = Math.PI / 2;\n yaw = 2 * Math.atan2(y, x);\n } else if (test < -0.499995 * unit) {\n // singularity at the south pole\n pitch = -Math.PI / 2;\n yaw = -2 * Math.atan2(y, x);\n } else {\n const view = vec3.fromValues(0, 0, 1);\n const up = vec3.fromValues(0, 1, 0);\n\n vec3.transformQuat(view, view, quaternion);\n vec3.transformQuat(up, up, quaternion);\n\n const viewXZ = Math.sqrt(view[0] * view[0] + view[2] * view[2]);\n\n pitch = Math.atan2(-view[1], viewXZ);\n yaw = Math.atan2(view[0], view[2]);\n }\n\n return {\n pitch: clamp(pitch * RAD_TO_DEG, -90, 90),\n yaw: circulate(yaw * RAD_TO_DEG, 0, 360)\n };\n};\n","/*\n * Copyright (c) 2020 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport { clamp, lerp, circulate } from \"../utils\";\nimport { Range } from \"../type/utils\";\nimport { DEFAULT_ANIMATION_DURATION, DEFAULT_EASING } from \"../const/internal\";\n\n/**\n * Interpolator between two values with duration\n * @ko 특정 시간동안 두 값을 보간해주는 보간기\n * @since 4.0.0\n */\nclass Motion {\n // Options\n private _duration: number;\n private _loop: boolean;\n private _range: Range;\n private _easing: (x: number) => number;\n\n // Internal states\n private _progress: number;\n private _val: number;\n private _start: number;\n private _end: number;\n private _activated: boolean;\n\n /**\n * Current interpolated value\n * @ko 현재 보간된 값\n * @since 4.0.0\n */\n public get val() { return this._val; }\n /**\n * Start(from) value of interpolation\n * @ko 보간 시작 값\n * @since 4.0.0\n */\n public get start() { return this._start; }\n /**\n * End(to) value of interpolation\n * @ko 보간 끝 값\n * @since 4.0.0\n */\n public get end() { return this._end; }\n /**\n * Interpolation progress value (0 ~ 1)\n * @ko 현재 보간 진행정도 (0 ~ 1)\n * @since 4.0.0\n */\n public get progress() { return this._progress; }\n /**\n * Whether the interpolation is in active state.\n * @ko 보간 진행중인지 여부. `true`일 경우 보간이 진행중입니다.\n * @since 4.0.0\n */\n public get activated() { return this._activated; }\n\n /**\n * Duration of the interpolation\n * @ko 보간할 시간\n * @since 4.0.0\n */\n public get duration() { return this._duration; }\n public set duration(val: number) { this._duration = val; }\n\n /**\n * Whether to loop interpolation on finish\n * @ko 보간이 끝난 이후에 다시 시작할지 여부\n * @since 4.0.0\n */\n public get loop() { return this._loop; }\n public set loop(val: boolean) { this._loop = val; }\n\n /**\n * Range of the interpolation\n * @ko 보간 범위\n * @since 4.0.0\n */\n public get range() { return this._range; }\n\n /**\n * Easing function of the interpolation\n * @ko 보간에 사용되는 easing function\n * @since 4.0.0\n */\n public get easing() { return this._easing; }\n public set easing(val: (x: number) => number) { this._easing = val; }\n\n /**\n * Create new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options Options {@ko 옵션들}\n * @param options.duration Duration of the interpolation {@ko 보간할 시간}\n * @param options.loop Whether to loop interpolation on finish {@ko 보간이 끝난 이후에 다시 시작할지 여부}\n * @param options.range Range of the interpolation {@ko 보간 범위}\n * @param options.loop Easing function of the interpolation {@ko 보간에 사용되는 easing function}\n */\n public constructor({\n duration = DEFAULT_ANIMATION_DURATION,\n loop = false,\n range = { min: 0, max: 1 },\n easing = DEFAULT_EASING\n } = {}) {\n this._duration = duration;\n this._loop = loop;\n this._range = range;\n this._easing = easing;\n this._activated = false;\n this.reset(0);\n }\n\n /**\n * Update motion and progress it by given deltaTime\n * @ko 주어진 deltaTime만큼 보간을 진행합니다.\n * @param deltaTime - number of milisec to update motion {@ko 보간을 진행할 시간, 밀리초 단위}\n * @returns Difference(delta) of the value from the last update. {@ko 지난 업데이트 이후의 값 변화량}\n * @since 4.0.0\n */\n public update(deltaTime: number): number {\n if (!this._activated) {\n this._val = this._end;\n return 0;\n }\n\n const start = this._start;\n const end = this._end;\n const duration = this._duration;\n const prev = this._val;\n const loop = this._loop;\n\n const nextProgress = this._progress + deltaTime / duration;\n\n this._progress = loop\n ? circulate(nextProgress, 0, 1)\n : clamp(nextProgress, 0, 1);\n\n const easedProgress = this._easing(this._progress);\n this._val = lerp(start, end, easedProgress);\n\n if (!loop && this._progress >= 1) {\n this._activated = false;\n }\n\n return this._val - prev;\n }\n\n /**\n * Set `start`, `end` to the given value and set `progress` to 0.\n * @ko 주어진 값으로 시작 지점, 끝 지점을 초기화하고 progress를 0으로 세팅합니다.\n * @param defaultVal - Value to reset {@ko 초기화할 값}\n * @since 4.0.0\n */\n public reset(defaultVal: number): void {\n const range = this._range;\n const val = clamp(defaultVal, range.min, range.max);\n this._start = val;\n this._end = val;\n this._val = val;\n this._progress = 0;\n this._activated = false;\n }\n\n /**\n * Add delta to start & end and current value.\n * @ko 현재 & 끝 및 현재 값에 주어진 값을 더합니다.\n * @param delta - Delta value to add {@ko 추가할 값}\n */\n public add(delta: number) {\n const range = this._range;\n\n this._start = clamp(this._start + delta, range.min, range.max);\n this._end = clamp(this._end + delta, range.min, range.max);\n this._val = clamp(this._val + delta, range.min, range.max);\n }\n\n /**\n * Set current value to start, and end to current value + delta, then reset progress to 0.\n * @ko 현재 값을 시작 지점으로, 그에서 delta만큼 추가된 값을 끝점으로 하고 progress를 0으로 갱신합니다.\n * @param delta - Delta value to add {@ko 추가할 값}\n */\n public setNewEndByDelta(delta: number): void {\n const range = this._range;\n\n this._start = this._val;\n this._end = clamp(this._end + delta, range.min, range.max);\n this._progress = 0;\n this._activated = true;\n }\n\n /**\n * Set new range of the interpolation.\n * @ko 보간의 범위를 변경합니다.\n * @param min - New minimum range {@ko 변경할 범위의 최소값}\n * @param max - New maximum range {@ko 변경할 범위의 최대값}\n */\n public setRange(min: number, max: number) {\n this._start = clamp(this._start, min, max);\n this._end = clamp(this._end, min, max);\n this._range = { min, max };\n }\n}\n\nexport default Motion;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { quat } from \"gl-matrix\";\nimport Camera from \"./Camera\";\nimport Motion from \"./Motion\";\nimport { DEFAULT_ANIMATION_DURATION, DEFAULT_EASING } from \"../const/internal\";\nimport { lerp } from \"../utils\";\n\ntype CameraPose = {\n rotation: quat;\n zoom: number;\n}\n\n/**\n * Animation of the {@link Camera}\n * @internal\n * @ko {@link Camera}의 애니메이션\n * @since 4.0.0\n */\nclass CameraAnimation {\n // Options\n private _camera: Camera;\n private _from: CameraPose;\n private _to: CameraPose;\n\n // Internal values\n private _motion: Motion;\n private _finishPromise: Promise;\n private _finish: () => void;\n\n /**\n * Duration of the animation\n * @ko 애니메이션 재생시간\n * @since 4.0.0\n */\n public get duration() { return this._motion.duration; }\n public set duration(val: number) { this._motion.duration = val; }\n /**\n * Easing function of the animation\n * @ko 애니메이션의 easing function\n * @since 4.0.0\n */\n public get easing() { return this._motion.easing; }\n public set easing(val: (x: number) => number) { this._motion.easing = val; }\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param camera - Camera to animate {@ko 애니메이션을 적용할 카메라}\n * @param from - Start pose {@ko 애니메이션이 시작 시점의 카메라의 회전 및 줌}\n * @param to - End pose {@ko 애니메이션이 끝났을 때 카메라의 회전 및 줌}\n * @param options - Options {@ko 옵션들}\n * @param options.duration - Animation duration {@ko 애니메이션 재생 시간}\n * @param options.easing - Animation easing function {@ko 애니메이션 easing function}\n */\n public constructor(camera: Camera, from: CameraPose, to: CameraPose, {\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING\n } = {}) {\n this._camera = camera;\n this._motion = new Motion({ duration, easing, range: { min: 0, max: 1 } });\n this._from = from;\n this._to = to;\n this._finishPromise = new Promise(resolve => {\n this._finish = resolve as () => void;\n });\n\n // Enable motion\n this._motion.setNewEndByDelta(1);\n }\n\n /**\n * Return a promise that resolved on animation end.\n * @ko 애니메이션 재생이 끝났을 때 resolve되는 Promise를 반환합니다.\n * @since 4.0.0\n */\n public getFinishPromise() {\n return this._finishPromise;\n }\n\n /**\n * Update animation by given deltaTime.\n * @ko 주어진 시간만큼 애니메이션을 업데이트합니다.\n * @param deltaTime Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n */\n public update(deltaTime: number): void {\n const camera = this._camera;\n const from = this._from;\n const to = this._to;\n const motion = this._motion;\n motion.update(deltaTime);\n\n // Progress that easing is applied\n const progress = motion.val;\n const rotation = quat.create();\n const zoom = lerp(from.zoom, to.zoom, progress);\n\n quat.slerp(rotation, from.rotation, to.rotation, progress);\n camera.rotate(rotation, zoom);\n\n if (progress >= 1) {\n this._finish();\n }\n }\n}\n\nexport default CameraAnimation;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { mat4, quat, vec3 } from \"gl-matrix\";\nimport CameraAnimation from \"./CameraAnimation\";\nimport {\n CAMERA_EVENTS,\n DEG_TO_RAD,\n INFINITE_RANGE,\n DEFAULT_PITCH_RANGE,\n RAD_TO_DEG,\n DEFAULT_ZOOM_RANGE,\n DEFAULT_EASING,\n EPSILON\n} from \"../const/internal\";\nimport {\n circulate,\n clamp,\n eulerToQuat,\n quatToEuler,\n toVerticalFov\n} from \"../utils\";\nimport { Range } from \"../type/utils\";\n\n/**\n * Events that {@link Camera} can trigger\n * @ko {@link Camera}가 트리거할 수 있는 이벤트들\n * @since 4.0.0\n */\nexport interface CameraEvents {\n /**\n * An event that fires when camera's animation stops\n * @ko 카메라 애니메이션이 멈췄을 때 트리거되는 이벤트\n * @eventName animationEnd\n * @eventOf Camera\n * @version 4.0.0\n */\n [CAMERA_EVENTS.ANIMATION_END]: {\n animation: CameraAnimation\n };\n}\n\n/**\n * Options for {@link Camera}\n * @ko {@link Camera}용 옵션들\n * @since 4.0.0\n */\nexport interface CameraOptions {\n /**\n * @copy View360#initialYaw\n */\n initialYaw: number;\n /**\n * @copy View360#initialPitch\n */\n initialPitch: number;\n /**\n * @copy View360#initialZoom\n */\n initialZoom: number;\n /**\n * @copy View360#yawRange\n */\n yawRange: Range | null;\n /**\n * @copy View360#pitchRange\n */\n pitchRange: Range | null;\n /**\n * @copy View360#zoomRange\n */\n zoomRange: Range | null;\n /**\n * @copy View360#fov\n */\n fov: number;\n}\n\n/**\n * Camera for View360\n * @ko View360용 카메라 구현체\n * @version 4.0.0\n */\nclass Camera extends Component {\n /**\n * Current yaw(y-axis rotation) value\n * @ko 현재 yaw(y축 회전) 값\n * @since 4.0.0\n */\n public yaw: number;\n /**\n * Current pitch(x-axis rotation) value\n * @ko 현재 pitch(x축 회전) 값\n * @since 4.0.0\n */\n public pitch: number;\n /**\n * Current zoom value\n * @ko 현재 줌 값\n * @since 4.0.0\n */\n public zoom: number;\n\n /**\n * @copy View360#initialYaw\n */\n public initialYaw: number;\n /**\n * @copy View360#initialPitch\n */\n public initialPitch: number;\n /**\n * @copy View360#initialPitch\n */\n public initialZoom: number;\n /**\n * @hidden\n * TODO: Please add comment for this when `rollOffset` is added\n */\n public rollOffset: number;\n\n /**\n * Current camera quaternion\n * @ko 현재 회전을 나타내는 quaternion 값\n * @since 4.0.0\n * @internal\n */\n public quaternion: quat;\n /**\n * Current camera position\n * @ko 현재 카메라 위치 좌표\n * @since 4.0.0\n * @internal\n */\n public position: vec3;\n /**\n * Active camera animation, `null` if there isn't.\n * @ko 현재 활성화된 카메라 애니메이션, 없을 경우 `null`값을 가집니다.\n * @since 4.0.0\n */\n public animation: CameraAnimation | null;\n /**\n * Camera's view matrix\n * @ko 카메라의 뷰 변환 행렬\n * @internal\n * @since 4.0.0\n */\n public viewMatrix: mat4;\n /**\n * Camera's projection matrix\n * @ko 카메라의 프로젝션 변환 행렬\n * @internal\n * @since 4.0.0\n */\n public projectionMatrix: mat4;\n\n /**\n * Camera's horizontal FOV(Field of View) value\n * @ko 카메라의 수평 FOV(Field of View) 값\n * @internal\n * @since 4.0.0\n */\n public fov: number;\n\n private _initialYawRange: Range | null;\n private _initialPitchRange: Range | null;\n private _initialZoomRange: Range | null;\n\n private _yawRange: Range | null;\n private _pitchRange: Range | null;\n private _zoomRange: Range | null;\n\n private _up: vec3;\n private _aspect: number;\n private _changed: boolean;\n private _maxRenderHeight: number;\n\n /**\n * Camera's width / height ratio\n * @ko 카메라의 가로 / 세로 비율\n * @readonly\n */\n public get aspect() { return this._aspect; }\n /**\n * Whether the camera's rotation changed from the last frame.\n * @ko 마지막 프레임 이후로 카메라의 회전값이 변경되었는지 나타내는 플래그.\n * @readonly\n */\n public get changed() { return this._changed; }\n /**\n * @copy View360#yawRange\n */\n public get yawRange() { return this._initialYawRange; }\n public set yawRange(val: Range | null) {\n this._initialYawRange = val;\n }\n /**\n * @copy View360#pitchRange\n */\n public get pitchRange() { return this._initialPitchRange; }\n public set pitchRange(val: Range | null) {\n this._initialPitchRange = val;\n }\n /**\n * @copy View360#zoomRange\n */\n public get zoomRange() { return this._initialZoomRange; }\n public set zoomRange(val: Range | null) {\n this._initialZoomRange = val;\n }\n\n /**\n * Create new instance of Camera\n * @param options - Camera options {@ko 카메라 옵션들}\n */\n public constructor({\n initialYaw,\n initialPitch,\n initialZoom,\n yawRange,\n pitchRange,\n zoomRange,\n fov\n }: CameraOptions) {\n super();\n\n this.yaw = initialYaw;\n this.pitch = initialPitch;\n this.zoom = initialZoom;\n this.rollOffset = 0;\n\n this.initialYaw = initialYaw;\n this.initialPitch = initialPitch;\n this.initialZoom = initialZoom;\n\n this.position = vec3.create();\n this.animation = null;\n\n this._up = vec3.fromValues(0, 1, 0);\n this._aspect = 1;\n\n this._initialYawRange = yawRange;\n this._initialPitchRange = pitchRange;\n this._initialZoomRange = zoomRange;\n\n this._yawRange = yawRange;\n this._pitchRange = pitchRange;\n this._zoomRange = zoomRange;\n\n this.quaternion = quat.create();\n this._updateQuaternion();\n\n this.viewMatrix = mat4.create();\n this.projectionMatrix = mat4.create();\n this.fov = fov;\n\n this._maxRenderHeight = -1;\n }\n\n /**\n * Destroy instance and detach all event listeners\n * @ko 인스턴스를 삭제하고 모든 이벤트 리스너를 삭제합니다.\n * @since 4.0.0\n */\n public destroy() {\n this.off();\n }\n\n /**\n * Refresh internal size value.\n * @ko 내부 크기값을 갱신합니다.\n * @param width - New width {@ko 변경된 너비값}\n * @param height - New height {@ko 변경된 높이값}\n * @since 4.0.0\n */\n public resize(width: number, height: number) {\n const prevAspect = this._aspect;\n\n this._aspect = width / height;\n\n if (this._aspect !== prevAspect) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation with euler values.\n * @ko 카메라 회전을 오일러 각 방향으로 변경합니다.\n * @param rotation - Rotation values {@ko 회전 값}\n * @param rotation.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값}\n * @param rotation.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값}\n * @param rotation.zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @since 4.0.0\n */\n public lookAt({\n yaw = this.yaw,\n pitch = this.pitch,\n zoom = this.zoom\n }: Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n }>) {\n const prevQuaternion = quat.clone(this.quaternion);\n const prevZoom = this.zoom;\n\n this.yaw = circulate(yaw, 0, 360);\n this.pitch = clamp(pitch, -90, 90);\n this.zoom = zoom;\n\n this._updateQuaternion();\n\n const zoomDiff = Math.abs(zoom - prevZoom);\n\n if (\n !quat.equals(this.quaternion, prevQuaternion)\n || zoomDiff >= EPSILON * 10 // ignore small changes\n ) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation with quaternion.\n * @ko 카메라 회전을 Quaternion을 이용해서 변경합니다.\n * @param rotation - Quaternion to apply {@ko 적용할 Quaternion}\n * @param zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @since 4.0.0\n */\n public rotate(rotation: quat, zoom: number = this.zoom) {\n const normalized = quat.normalize(quat.create(), rotation);\n const isSameRotation = quat.equals(this.quaternion, normalized);\n quat.copy(this.quaternion, normalized);\n\n const prevZoom = this.zoom;\n const { yaw, pitch } = quatToEuler(normalized);\n\n this.yaw = yaw;\n this.pitch = pitch;\n this.zoom = zoom;\n\n const zoomDiff = Math.abs(zoom - prevZoom);\n\n if (!isSameRotation || zoomDiff >= EPSILON * 10) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation to given euler values by the given duration.\n * @ko 카메라를 주어진 방향으로 주어진 시간동안 서서히 이동시킵니다.\n * @param options - Animation parameters {@ko 애니메이션 패러미터}\n * @param options.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값}\n * @param options.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값}\n * @param options.zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @param options.duration - Duration of the animation {@ko 애니메이션 시간}\n * @param options.easing - Easing function for the animation {@ko 애니메이션에 적용할 easing function}\n */\n public async animateTo({\n yaw = this.yaw,\n pitch = this.pitch,\n zoom = this.zoom,\n duration = 0,\n easing = DEFAULT_EASING\n }: Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n duration: number;\n easing: (x: number) => number;\n }> = {}): Promise {\n if (\n this.yaw === yaw\n && this.pitch === pitch\n && this.zoom === zoom\n ) return;\n\n const from = {\n rotation: quat.clone(this.quaternion),\n zoom: this.zoom\n };\n const to = {\n rotation: eulerToQuat(quat.create(), yaw, pitch, this.rollOffset),\n zoom\n };\n\n const animation = new CameraAnimation(this, from, to, {\n duration,\n easing\n });\n const finishPromise = animation.getFinishPromise();\n\n this.animation = animation;\n finishPromise.then(() => {\n this.animation = null;\n this.trigger(CAMERA_EVENTS.ANIMATION_END, { animation });\n });\n\n return finishPromise;\n }\n\n /**\n * @hidden\n */\n public restrictYawRange(min: number, max: number) {\n this._yawRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictPitchRange(min: number, max: number) {\n this._pitchRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictZoomRange(min: number, max: number) {\n this._zoomRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictRenderHeight(height: number) {\n this._maxRenderHeight = height;\n }\n\n /**\n * @hidden\n */\n public resetRange() {\n this._yawRange = this._initialYawRange;\n this._pitchRange = this._initialPitchRange;\n this._zoomRange = this._initialZoomRange;\n this._maxRenderHeight = -1;\n }\n\n /**\n * Get actual yaw range by the given zoom value.\n * @ko 주어진 zoom 값에 대한 실제 yaw 범위값을 반환합니다.\n * @since 4.0.0\n */\n public getYawRange(zoom: number) {\n const yawLimit = this._yawRange;\n const maxRenderHeight = this._maxRenderHeight;\n if (!yawLimit) return INFINITE_RANGE;\n\n const halfHFov = this.getHorizontalFov(zoom) * 0.5;\n let minYaw = yawLimit.min;\n let maxYaw = yawLimit.max;\n\n if (maxRenderHeight > 0) {\n const halfVFovRad = toVerticalFov(halfHFov * DEG_TO_RAD, this._aspect);\n const h = maxRenderHeight * 0.5;\n const t = Math.tan(halfVFovRad);\n const d = Math.sqrt((1 + h * h) / (1 + t * t));\n const theta = Math.atan(Math.tan(halfHFov * DEG_TO_RAD) * d) * RAD_TO_DEG;\n\n minYaw = yawLimit.min + theta;\n maxYaw = yawLimit.max - theta;\n }\n\n if (minYaw > maxYaw) {\n minYaw = 0;\n maxYaw = 0;\n }\n\n return {\n min: minYaw,\n max: maxYaw\n };\n }\n\n /**\n * Get actual pitch range by the given zoom value.\n * @ko 주어진 zoom 값에 대한 실제 pitch 범위값을 반환합니다.\n * @since 4.0.0\n */\n public getPitchRange(zoom: number) {\n const pitchLimit = this._pitchRange;\n const maxRenderHeight = this._maxRenderHeight;\n\n if (!pitchLimit) return DEFAULT_PITCH_RANGE;\n\n let minPitch = pitchLimit.min;\n let maxPitch = pitchLimit.max;\n\n if (maxRenderHeight > 0) {\n const halfVFov = this.getVerticalFov(zoom) * 0.5;\n\n minPitch = pitchLimit.min + halfVFov;\n maxPitch = pitchLimit.max - halfVFov;\n }\n\n if (minPitch > maxPitch) {\n minPitch = 0;\n maxPitch = 0;\n }\n\n return {\n min: Math.max(minPitch, -90),\n max: Math.min(maxPitch, 90)\n };\n }\n\n /**\n * Get actual zoom range in fov degrees.\n * @ko 실제 줌 범위를 fov각의 범위로 반환합니다.\n * @since 4.0.0\n */\n public getZoomRange() {\n const limit = this._zoomRange ?? DEFAULT_ZOOM_RANGE;\n\n // max (zoom in) -> minimum fov\n const minFov = this.getHorizontalFov(limit.max);\n const maxFov = this.getHorizontalFov(limit.min);\n const currentFov = this.getHorizontalFov(this.zoom);\n\n return {\n min: Math.max(minFov, 1),\n max: Math.min(maxFov, 180),\n current: currentFov\n };\n }\n\n /**\n * Return horizontal fov value when the given zoom is applied. (in degrees, °)\n * @ko 주어진 zoom 값이 적용되었을 때의 수평 fov값을 반환합니다. (도 단위, °)\n * @returns Zoomed horizontal FOV {@ko 줌이 적용된 수평 fov값}\n * @since 4.0.0\n */\n public getHorizontalFov(zoom = this.zoom) {\n return this._getZoomedHorizontalFov(zoom) * RAD_TO_DEG;\n }\n\n /**\n * Return vertical fov value when the given zoom is applied. (in degrees, °)\n * @ko 주어진 zoom 값이 적용되었을 때의 수직 fov값을 반환합니다. (도 단위, °)\n * @returns Zoomed vertical FOV {@ko 줌이 적용된 수직 fov값}\n * @since 4.0.0\n */\n public getVerticalFov(zoom = this.zoom) {\n const aspect = this._aspect;\n const hFov = this._getZoomedHorizontalFov(zoom); // In radians\n const vFov = toVerticalFov(hFov, aspect);\n\n return vFov * RAD_TO_DEG;\n }\n\n /**\n * Calculate zoom value for the given fov.\n * @ko 주어진 fov값을 zoom값으로 변환합니다.\n * @param fov horizontal fov (in degrees, °) {@ko 수평 fov 값 (도 단위, °)}\n * @since 4.0.0\n */\n public fovToZoom(fov: number) {\n const baseFov = this.fov;\n const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5);\n const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5);\n\n return renderingWidth / zoomedWidth;\n }\n\n /**\n * Update inner matrixes.\n * @ko 내부 행렬들을 업데이트합니다.\n * @internal\n * @since 4.0.0\n */\n public updateMatrix() {\n const up = this._up;\n const aspect = this._aspect;\n const viewMatrix = this.viewMatrix;\n const projMatrix = this.projectionMatrix;\n const position = this.position;\n const rotation = this.quaternion;\n\n const upDir = vec3.create();\n const viewDir = vec3.fromValues(0, 0, -1);\n vec3.transformQuat(viewDir, viewDir, rotation);\n vec3.transformQuat(upDir, up, rotation);\n\n const hFov = this._getZoomedHorizontalFov(); // In radians\n const vFov = toVerticalFov(hFov, aspect);\n\n mat4.lookAt(viewMatrix, position, viewDir, upDir);\n mat4.perspective(projMatrix, vFov, aspect, 0.1, 100);\n\n this._changed = true;\n }\n\n /**\n * @hidden\n */\n public onFrameRender() {\n this._changed = false;\n }\n\n private _updateQuaternion() {\n eulerToQuat(this.quaternion, this.yaw, this.pitch, this.rollOffset);\n }\n\n /**\n * @param zoom Current zoom value\n * @returns horizontal fov including zoom, in radian\n */\n private _getZoomedHorizontalFov(zoom = this.zoom) {\n return 2 * Math.atan(Math.tan(DEG_TO_RAD * this.fov * 0.5) / zoom);\n }\n}\n\nexport default Camera;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass MouseInput extends Component> {\n private _el: HTMLElement | null;\n private _prevPos: [number, number];\n\n public constructor() {\n super();\n\n this._el = null;\n this._prevPos = [0, 0];\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onMouseDown);\n\n this._el = element;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onMouseDown);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this._el = null;\n }\n\n private _onMouseDown = (evt: MouseEvent) => {\n const el = this._el;\n if (!el || evt.button !== BROWSER.MOUSE_BUTTON.LEFT) return;\n\n evt.preventDefault();\n\n if (el.focus) {\n el.focus();\n } else {\n window.focus();\n }\n\n this._prevPos[0] = evt.clientX;\n this._prevPos[1] = evt.clientY;\n\n window.addEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.addEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: false\n });\n }\n\n private _onMouseMove = (evt: MouseEvent) => {\n evt.preventDefault();\n\n const x = evt.clientX;\n const y = evt.clientY;\n const prevPos = this._prevPos;\n const deltaX = x - prevPos[0];\n const deltaY = y - prevPos[1];\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta: {\n x: deltaX,\n y: deltaY\n },\n isTouch: false,\n isKeyboard: false\n });\n\n prevPos[0] = x;\n prevPos[1] = y;\n }\n\n private _onMouseUp = () => {\n this._prevPos[0] = 0;\n this._prevPos[1] = 0;\n\n window.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: false,\n scrolling: false\n });\n }\n}\n\nexport default MouseInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\nimport { isFullscreen } from \"../../utils\";\n\nclass TouchInput extends Component> {\n private _el: HTMLElement | null;\n private _prevPos: [number, number];\n private _isFirstTouch: boolean;\n private _scrolling: boolean;\n private _scrollable: boolean;\n\n public get scrollable() { return this._scrollable; }\n public set scrollable(val: boolean) { this._scrollable = val; }\n\n public constructor() {\n super();\n\n this._el = null;\n this._prevPos = [0, 0];\n this._isFirstTouch = false;\n this._scrolling = false;\n this._scrollable = false;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.TOUCH_START, this._onTouchStart, { passive: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, { passive: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = element;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.TOUCH_START, this._onTouchStart);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = null;\n }\n\n private _onTouchStart = (evt: TouchEvent) => {\n if (evt.touches.length > 1 || this._scrolling) return;\n\n const touch = evt.touches[0];\n\n this._isFirstTouch = true;\n this._prevPos[0] = touch.clientX;\n this._prevPos[1] = touch.clientY;\n\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: true,\n isKeyboard: false\n });\n };\n\n private _onTouchMove = (evt: TouchEvent) => {\n // Only the one finger motion should be considered\n if (evt.touches.length > 1 || this._scrolling) return;\n\n const touch = evt.touches[0];\n const scrollable = this._scrollable;\n const prevPos = this._prevPos;\n\n const x = touch.clientX;\n const y = touch.clientY;\n const deltaX = x - prevPos[0];\n const deltaY = y - prevPos[1];\n\n if (this._isFirstTouch) {\n if (scrollable && !isFullscreen()) {\n if (Math.abs(deltaY) > Math.abs(deltaX)) {\n // Assume Scrolling\n this._scrolling = true;\n return;\n }\n }\n\n this._isFirstTouch = false;\n }\n\n if (evt.cancelable !== false) {\n evt.preventDefault();\n }\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta: {\n x: deltaX,\n y: deltaY\n },\n isTouch: true,\n isKeyboard: false\n });\n\n prevPos[0] = x;\n prevPos[1] = y;\n };\n\n private _onTouchEnd = (evt: TouchEvent) => {\n if (evt.touches.length !== 0) return;\n\n const touch = evt.touches[0];\n const prevPos = this._prevPos;\n\n if (touch) {\n prevPos[0] = touch.clientX;\n prevPos[1] = touch.clientY;\n } else {\n prevPos[0] = 0;\n prevPos[1] = 0;\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: true,\n isKeyboard: false,\n scrolling: this._scrolling\n });\n }\n\n if (evt.cancelable !== false) {\n evt.preventDefault();\n }\n\n this._scrolling = false;\n };\n}\n\nexport default TouchInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass KeyboardInput extends Component> {\n private _el: HTMLElement | null;\n private _pressed: {\n LEFT: boolean;\n UP: boolean;\n RIGHT: boolean;\n DOWN: boolean;\n };\n\n public get active() {\n const pressed = this._pressed;\n return pressed.LEFT || pressed.UP || pressed.RIGHT || pressed.DOWN;\n }\n\n public constructor() {\n super();\n\n this._el = null;\n this._clearPressedKeys();\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown);\n element.addEventListener(BROWSER.EVENTS.KEY_UP, this._onKeyUp);\n\n this._el = element;\n this._clearPressedKeys();\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown);\n element.removeEventListener(BROWSER.EVENTS.KEY_UP, this._onKeyUp);\n\n this._el = null;\n this._clearPressedKeys();\n }\n\n public update() {\n const delta = this._getDeltaByPressedKeys();\n\n if (delta.x !== 0 || delta.y !== 0) {\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: false,\n isKeyboard: true\n });\n }\n }\n\n private _clearPressedKeys() {\n this._pressed = BROWSER.KEY_DIRECTION.reduce((obj, keyName) => {\n return {\n ...obj,\n [keyName]: false\n };\n }, {} as KeyboardInput[\"_pressed\"]);\n }\n\n private _updateKeyPress(event: KeyboardEvent, isEnable: boolean): void {\n const pressed = this._pressed;\n const keyToUpdate = event.keyCode != null\n ? BROWSER.DIRECTION_KEY_CODE[event.keyCode]\n : BROWSER.DIRECTION_KEY_NAME[event.key];\n\n if (!keyToUpdate) return;\n\n pressed[keyToUpdate] = isEnable;\n }\n\n private _getPressedKeyCount() {\n return BROWSER.KEY_DIRECTION.filter(key => this._pressed[key]).length;\n }\n\n private _getDeltaByPressedKeys() {\n const pressed = this._pressed;\n let x = 0;\n let y = 0;\n\n if (pressed.LEFT) {\n x += 1;\n }\n\n if (pressed.RIGHT) {\n x -= 1;\n }\n\n if (pressed.UP) {\n y += 1;\n }\n\n if (pressed.DOWN) {\n y -= 1;\n }\n\n return {\n x, y\n };\n }\n\n private _onKeyDown = (evt: KeyboardEvent) => {\n // Ignore all other keypress except main arrow keys\n if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return;\n\n this._updateKeyPress(evt, true);\n\n const pressedCount = this._getPressedKeyCount();\n if (pressedCount <= 0) return;\n\n evt.preventDefault();\n if (pressedCount === 1 && !evt.repeat) {\n // On first keydown\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: true\n });\n }\n };\n\n private _onKeyUp = (evt: KeyboardEvent) => {\n // Ignore all other keypress except main arrow keys\n if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return;\n\n this._updateKeyPress(evt, false);\n\n const pressedCount = this._getPressedKeyCount();\n if (pressedCount > 0) return;\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: true,\n scrolling: false\n });\n };\n}\n\nexport default KeyboardInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport MouseInput from \"./input/MouseInput\";\nimport TouchInput from \"./input/TouchInput\";\nimport KeyboardInput from \"./input/KeyboardInput\";\nimport Camera from \"../core/Camera\";\nimport Motion from \"../core/Motion\";\nimport { CONTROL_EVENTS, INFINITE_RANGE, DEFAULT_PITCH_RANGE, DEFAULT_ANIMATION_DURATION, DEFAULT_EASING, DEG_TO_RAD, RAD_TO_DEG } from \"../const/internal\";\nimport { toVerticalFov } from \"../utils\";\nimport { ControlEvents, InputEvents } from \"../type/internal\";\n\n/**\n * Options for {@link RotateControl}\n * @ko {@link RotateControl}용 옵션들\n * @since 4.0.0\n */\nexport interface RotateControlOptions {\n /**\n * @copy RotateControl#pointerScale\n */\n pointerScale: [number, number];\n /**\n * @copy RotateControl#keyboardScale\n */\n keyboardScale: [number, number];\n /**\n * @copy RotateControl#duration\n */\n duration: number;\n /**\n * @copy RotateControl#easing\n */\n easing: (x: number) => number;\n /**\n * @copy RotateControl#disablePitch\n */\n disablePitch: boolean;\n /**\n * @copy RotateControl#disableYaw\n */\n disableYaw: boolean;\n /**\n * @copy RotateControl#disableKeyboard\n */\n disableKeyboard: boolean;\n}\n\ntype RotateDeltaType = { x: number; y: number; };\nexport type RotateControlEvents = ControlEvents;\n\n/**\n * Camera's rotation control\n * @ko 카메라의 회전을 담당하는 컨트롤\n * @since 4.0.0\n */\nclass RotateControl extends Component implements CameraControl {\n // Options\n private _pointerScale: RotateControlOptions[\"pointerScale\"];\n private _keyboardScale: RotateControlOptions[\"keyboardScale\"];\n private _duration: RotateControlOptions[\"duration\"];\n private _easing: RotateControlOptions[\"easing\"];\n private _disablePitch: RotateControlOptions[\"disablePitch\"];\n private _disableYaw: RotateControlOptions[\"disableYaw\"];\n private _disableKeyboard: RotateControlOptions[\"disableKeyboard\"];\n\n // Internal values\n private _controlEl: HTMLElement;\n private _enableBlocked: boolean;\n private _mouseInput: MouseInput;\n private _touchInput: TouchInput;\n private _keyboardInput: KeyboardInput;\n private _xMotion: Motion;\n private _yMotion: Motion;\n private _screenScale: [number, number];\n private _zoomScale: number;\n private _enabled: boolean;\n private _changedWhileDragging: boolean;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() {\n return this._keyboardInput.active\n || this._xMotion.activated\n || this._yMotion.activated;\n }\n /**\n * Current yaw value\n * @ko 현재 yaw 값\n * @readonly\n * @since 4.0.0\n */\n public get yaw() { return this._xMotion; }\n /**\n * Current pitch value\n * @ko 현재 pitch 값\n * @readonly\n * @since 4.0.0\n */\n public get pitch() { return this._yMotion; }\n /**\n * @copy View360#scrollable\n */\n public get scrollable() { return this._touchInput.scrollable; }\n public set scrollable(val: boolean) {\n this._touchInput.scrollable = val;\n }\n\n /**\n * Scale factor for mouse/touch rotation\n * @ko 마우스/터치를 통한 회전 배율\n * @default [1, 1]\n * @since 4.0.0\n */\n public get pointerScale() { return this._pointerScale; }\n public set pointerScale(val: RotateControlOptions[\"pointerScale\"]) {\n this._pointerScale = val;\n }\n\n /**\n * Scale factor for keyboard rotation\n * @ko 키보드를 통한 회전 배율\n * @default [1, 1]\n * @since 4.0.0\n */\n public get keyboardScale() { return this._keyboardScale; }\n public set keyboardScale(val: RotateControlOptions[\"keyboardScale\"]) {\n this._keyboardScale = val;\n }\n\n /**\n * Duration of the input animation (ms)\n * @ko 회전 애니메이션의 시간 (ms)\n * @default 300\n */\n public get duration() { return this._duration; }\n public set duration(val: RotateControlOptions[\"duration\"]) {\n this._duration = val;\n this._xMotion.duration = val;\n this._yMotion.duration = val;\n }\n\n /**\n * Easing function of the animation\n * @ko 회전 애니메이션에 적용할 easing 함수\n * @default EASING.EASE_OUT_CUBIC\n * @see EASING\n */\n public get easing() { return this._easing; }\n public set easing(val: RotateControlOptions[\"easing\"]) {\n this._easing = val;\n this._xMotion.easing = val;\n this._yMotion.easing = val;\n }\n\n /**\n * Disable X-axis(pitch) rotation.\n * @ko x축 회전(pitch)을 비활성화합니다.\n * @default false\n */\n public get disablePitch() { return this._disablePitch; }\n public set disablePitch(val: RotateControlOptions[\"disablePitch\"]) { this._disablePitch = val; }\n\n /**\n * Disable Y-axis(yaw) rotation.\n * @ko y축 회전(yaw)을 비활성화합니다.\n * @default false\n */\n public get disableYaw() { return this._disableYaw; }\n public set disableYaw(val: RotateControlOptions[\"disableYaw\"]) { this._disableYaw = val; }\n\n /**\n * Disable rotation by keyboard.\n * @ko 키보드를 이용한 회전을 비활성화합니다.\n * @default false\n */\n public get disableKeyboard() { return this._disableKeyboard; }\n public set disableKeyboard(val: RotateControlOptions[\"disableKeyboard\"]) { this._disableKeyboard = val; }\n\n /**\n * Create new RotateControl instance\n * @ko RotateControl의 인스턴스를 생성합니다.\n * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트}\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(controlEl: HTMLElement, enableBlocked: boolean, {\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING,\n pointerScale = [1, 1],\n keyboardScale = [1, 1],\n disablePitch = false,\n disableYaw = false,\n disableKeyboard = false\n }: Partial = {}) {\n super();\n\n this._controlEl = controlEl;\n this._pointerScale = pointerScale;\n this._keyboardScale = keyboardScale;\n this._duration = duration;\n this._easing = easing;\n this._disablePitch = disablePitch;\n this._disableYaw = disableYaw;\n this._disableKeyboard = disableKeyboard;\n\n this._enableBlocked = enableBlocked;\n this._mouseInput = new MouseInput();\n this._touchInput = new TouchInput();\n this._keyboardInput = new KeyboardInput();\n this._xMotion = new Motion({ duration, range: INFINITE_RANGE, easing });\n this._yMotion = new Motion({ duration, range: DEFAULT_PITCH_RANGE, easing });\n this._screenScale = [1, 1];\n this._zoomScale = 1;\n this._enabled = false;\n this._changedWhileDragging = false;\n this._bindInputs();\n }\n\n public destroy(): void {\n this.disable();\n this._mouseInput.off();\n this._touchInput.off();\n this._keyboardInput.off();\n this.off();\n this._changedWhileDragging = false;\n }\n\n /**\n * @hidden\n */\n public update(delta: number): void {\n if (!this._enabled) return;\n\n const xMotion = this._xMotion;\n const yMotion = this._yMotion;\n const keyboardInput = this._keyboardInput;\n\n if (!this._disableKeyboard) {\n keyboardInput.update();\n }\n\n if (!this._disablePitch) {\n yMotion.update(delta);\n }\n\n if (!this._disableYaw) {\n xMotion.update(delta);\n }\n }\n\n /**\n * @hidden\n */\n public updateRange(camera: Camera, zoom: number) {\n const yawRange = camera.getYawRange(zoom);\n const pitchRange = camera.getPitchRange(zoom);\n\n this._xMotion.setRange(yawRange.min, yawRange.max);\n this._yMotion.setRange(pitchRange.min, pitchRange.max);\n }\n\n /**\n * @hidden\n */\n public setZoomScale(val: number) {\n this._zoomScale = val;\n }\n\n /**\n * Resize control to match target size.\n * @ko 컨트롤의 내부 크기를 갱신합니다.\n * @param hfov - Camera horizontal fov in degrees {@ko 카메라의 수평방향 fov값 (도 단위)}\n * @param aspect - Camera aspect {@ko 카메라 가로/세로 비율}\n * @param width - New width {@ko 갱신된 너비}\n * @param height - New height {@ko 갱신된 높이}\n */\n public resize(hfov: number, aspect: number, width: number, height: number) {\n const vfov = toVerticalFov(hfov * DEG_TO_RAD, aspect) * RAD_TO_DEG;\n\n this._screenScale[0] = hfov / width;\n this._screenScale[1] = vfov / height;\n }\n\n public enable(): void {\n if (this._enabled) return;\n\n const element = this._controlEl;\n\n this._mouseInput.enable(element);\n this._touchInput.enable(element);\n this._keyboardInput.enable(element);\n\n this._enabled = true;\n this._enableBlocked = false;\n\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: true });\n }\n\n public disable(): void {\n if (!this._enabled) return;\n\n this._mouseInput.disable();\n this._touchInput.disable();\n this._keyboardInput.disable();\n\n this._enabled = false;\n\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: true });\n }\n\n public sync(camera: Camera): void {\n this.updateRange(camera, camera.zoom);\n\n this._xMotion.reset(camera.yaw);\n this._yMotion.reset(camera.pitch);\n }\n\n private _bindInputs() {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n const keyboardInput = this._keyboardInput;\n\n mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n touchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n touchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n keyboardInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n keyboardInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n keyboardInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n }\n\n private _onInputStart = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n this._changedWhileDragging = false;\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n ...evt,\n inputType: \"rotate\"\n });\n };\n\n private _onChange = (evt: InputEvents[typeof CONTROL_EVENTS.CHANGE]) => {\n const delta = evt.delta;\n const invZoomScale = 1 / this._zoomScale; // Reduce speed on zoom\n const screenScale = this._screenScale;\n const keyboardScale = this._keyboardScale;\n const pointerScale = this._pointerScale;\n\n let scale: [number, number];\n\n if (evt.isKeyboard) {\n scale = [\n keyboardScale[0] * invZoomScale,\n keyboardScale[1] * invZoomScale\n ];\n } else {\n scale = [\n pointerScale[0] * screenScale[0] * invZoomScale,\n pointerScale[1] * screenScale[1] * invZoomScale\n ];\n }\n\n const scaledX = delta.x * scale[0];\n const scaledY = delta.y * scale[1];\n\n this._xMotion.setNewEndByDelta(scaledX);\n this._yMotion.setNewEndByDelta(scaledY);\n\n this._changedWhileDragging = true;\n }\n\n private _onInputEnd = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n ...evt,\n inputType: \"rotate\"\n });\n\n if (!this._changedWhileDragging && !evt.isKeyboard && !evt.scrolling) {\n this.trigger(CONTROL_EVENTS.STATIC_CLICK, {\n isTouch: evt.isTouch\n });\n }\n\n this._changedWhileDragging = false;\n };\n}\n\nexport default RotateControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS, DEFAULT_ANIMATION_DURATION } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass WheelInput extends Component> {\n private _el: HTMLElement | null;\n private _scrollable: boolean;\n private _baseScale: number;\n private _inputTimer: number;\n\n public get scrollable() { return this._scrollable; }\n public set scrollable(val: boolean) { this._scrollable = val; }\n\n public constructor() {\n super();\n\n this._el = null;\n this._baseScale = 0.04;\n this._scrollable = false;\n this._inputTimer = -1;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.WHEEL, this._onWheel, { passive: false, capture: false });\n\n this._el = element;\n this._clearTimer();\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.WHEEL, this._onWheel, false);\n\n this._el = null;\n this._clearTimer();\n }\n\n private _onWheel = (evt: WheelEvent) => {\n const scrollable = this._scrollable;\n\n if (evt.deltaY === 0 || scrollable) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n\n if (this._inputTimer < 0) {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: false\n });\n } else {\n this._clearTimer();\n }\n\n const delta = this._baseScale * evt.deltaY;\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: false,\n isKeyboard: false\n });\n\n this._inputTimer = window.setTimeout(() => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: false,\n scrolling: false\n });\n this._inputTimer = -1;\n }, DEFAULT_ANIMATION_DURATION);\n };\n\n private _clearTimer() {\n window.clearTimeout(this._inputTimer);\n this._inputTimer = -1;\n }\n}\n\nexport default WheelInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass PinchInput extends Component> {\n private _el: HTMLElement | null;\n private _baseScale: number;\n private _prevDistance: number;\n private _isFirstTouch: boolean;\n\n public constructor() {\n super();\n\n this._el = null;\n this._baseScale = -0.2;\n this._prevDistance = -1;\n this._isFirstTouch = true;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, { passive: false, capture: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = element;\n this._prevDistance = -1;\n this._isFirstTouch = true;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, false);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = null;\n }\n\n private _onTouchMove = (evt: TouchEvent) => {\n const touches = evt.touches;\n if (touches.length !== 2) return;\n\n if (!evt.cancelable) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n\n const prevDistance = this._prevDistance;\n\n const diff = [\n touches[0].pageX - touches[1].pageX,\n touches[0].pageY - touches[1].pageY\n ];\n\n const distance = Math.sqrt(diff[0] * diff[0] + diff[1] * diff[1]) * this._baseScale;\n const delta = this._isFirstTouch\n ? 0\n : distance - prevDistance;\n\n if (this._isFirstTouch) {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: true,\n isKeyboard: false\n });\n }\n\n this._prevDistance = distance;\n this._isFirstTouch = false;\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: true,\n isKeyboard: false\n });\n };\n\n private _onTouchEnd = (evt: TouchEvent) => {\n if (evt.touches.length !== 0) return;\n\n if (!this._isFirstTouch) {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: true,\n isKeyboard: false,\n scrolling: false\n });\n }\n\n this._prevDistance = -1;\n this._isFirstTouch = true;\n };\n}\n\nexport default PinchInput;\n","/*\n* Copyright (c) 2023-present NAVER Corp.\n* egjs projects are licensed under the MIT license\n*/\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport WheelInput from \"./input/WheelInput\";\nimport PinchInput from \"./input/PinchInput\";\nimport Camera from \"../core/Camera\";\nimport Motion from \"../core/Motion\";\nimport {\n CONTROL_EVENTS,\n DEFAULT_ANIMATION_DURATION,\n DEFAULT_EASING,\n INFINITE_RANGE\n} from \"../const/internal\";\nimport { ControlEvents, InputEvents } from \"../type/internal\";\n\n/**\n * Options for {@link ZoomControl}\n * @ko {@link ZoomControl}용 옵션들\n * @since 4.0.0\n */\nexport interface ZoomControlOptions {\n /**\n * @copy ZoomControl#scale\n */\n scale: number;\n /**\n * @copy ZoomControl#duration\n */\n duration: number;\n /**\n * @copy ZoomControl#easing\n */\n easing: (x: number) => number;\n}\n\ntype ZoomControlEvents = ControlEvents;\n\n/**\n * Camera's zoom control\n * @ko 카메라의 줌 값을 담당하는 컨트롤\n * @since 4.0.0\n */\nclass ZoomControl extends Component implements CameraControl {\n // Options\n private _scale: ZoomControlOptions[\"scale\"];\n\n // Internal values\n private _controlEl: HTMLElement;\n private _enableBlocked: boolean;\n private _wheelInput: WheelInput;\n private _pinchInput: PinchInput;\n private _motion: Motion;\n private _enabled: boolean;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() { return this._motion.activated; }\n /**\n * Current zoom value\n * @ko 현재 줌 값\n * @since 4.0.0\n * @readonly\n */\n public get zoom() { return this._motion.val; }\n /**\n * @copy View360#wheelScrollable\n */\n public get scrollable() { return this._wheelInput.scrollable; }\n public set scrollable(val: boolean) {\n this._wheelInput.scrollable = val;\n }\n /**\n * @hidden\n */\n public get range() { return this._motion.range; }\n\n /**\n * Scale factor of the zoom\n * @ko 입력에 의한 줌 배율\n * @default 1\n * @since 4.0.0\n */\n public get scale() { return this._scale; }\n public set scale(val: ZoomControlOptions[\"scale\"]) { this._scale = val; }\n\n /**\n * Duration of the input animation (ms)\n * @ko 회전 애니메이션의 시간 (ms)\n * @default 300\n * @since 4.0.0\n */\n public get duration() { return this._motion.duration; }\n\n /**\n * Easing function of the animation\n * @ko 회전 애니메이션에 적용할 easing 함수\n * @default EASING.EASE_OUT_CUBIC\n * @see EASING\n * @since 4.0.0\n */\n public get easing() { return this._motion.easing; }\n\n /**\n * Create new ZoomControl instance\n * @ko ZoomControl의 인스턴스를 생성합니다.\n * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트}\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(controlEl: HTMLElement, enableBlocked: boolean, {\n scale = 1,\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING\n }: Partial = {}) {\n super();\n\n this._scale = scale;\n\n this._controlEl = controlEl;\n this._enableBlocked = enableBlocked;\n this._wheelInput = new WheelInput();\n this._pinchInput = new PinchInput();\n this._motion = new Motion({\n duration,\n easing,\n range: INFINITE_RANGE\n });\n this._enabled = false;\n\n this._bindInputs();\n }\n\n public destroy(): void {\n this.disable();\n this._wheelInput.off();\n this._pinchInput.off();\n this.off();\n }\n\n /**\n * @hidden\n */\n public update(delta: number): void {\n if (!this._enabled) return;\n\n const motion = this._motion;\n motion.update(delta);\n }\n\n public enable(): void {\n if (this._enabled) return;\n\n const element = this._controlEl;\n this._wheelInput.enable(element);\n this._pinchInput.enable(element);\n\n this._enabled = true;\n this._enableBlocked = false;\n\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: false });\n }\n\n public disable(): void {\n if (!this._enabled) return;\n\n this._wheelInput.disable();\n this._pinchInput.disable();\n\n this._enabled = false;\n\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: false });\n }\n\n public sync(camera: Camera): void {\n const motion = this._motion;\n const range = camera.getZoomRange();\n\n motion.setRange(range.min, range.max);\n motion.reset(range.current);\n }\n\n private _bindInputs() {\n const wheelInput = this._wheelInput;\n const pinchInput = this._pinchInput;\n\n wheelInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n wheelInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n wheelInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n pinchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n pinchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n pinchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n }\n\n private _onInputStart = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n ...evt,\n inputType: \"zoom\"\n });\n };\n\n private _onChange = ({ delta }: InputEvents[typeof CONTROL_EVENTS.CHANGE]) => {\n const scale = this._scale;\n const scaledDelta = delta * scale;\n\n this._motion.setNewEndByDelta(scaledDelta);\n };\n\n private _onInputEnd = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n ...evt,\n inputType: \"zoom\"\n });\n };\n}\n\nexport default ZoomControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { quat, vec3 } from \"gl-matrix\";\nimport * as BROWSER from \"../../const/browser\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\nimport { quatToEuler } from \"../../utils\";\n\nexport const ROTATE_CONSTANT = {\n PITCH_DELTA: 1,\n YAW_DELTA_BY_ROLL: 2,\n YAW_DELTA_BY_YAW: 3\n} as const;\n\nROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = {\n targetAxis: [0, 1, 0],\n meshPoint: [0, 0, 1]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = {\n targetAxis: [0, 1, 0],\n meshPoint: [1, 0, 0]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = {\n targetAxis: [1, 0, 0],\n meshPoint: [0, 0, 1]\n};\n\nclass GyroInput extends Component> {\n public quaternion: quat;\n\n private _ignoreRoll: boolean;\n\n private _yawOrigin: number;\n private _yawOffset: number;\n private _orientation: {\n alpha: number;\n beta: number;\n gamma: number;\n }\n private _orientationUpdated: boolean;\n private _needsCalibrate: boolean;\n private _screenOrientation: number;\n private _enabled: boolean;\n\n public get enabled() { return this._enabled; }\n public get orientationUpdated() { return this._orientationUpdated; }\n public get ignoreRoll() { return this._ignoreRoll; }\n public set ignoreRoll(val: boolean) { this._ignoreRoll = val; }\n\n public constructor() {\n super();\n\n this.quaternion = quat.create();\n\n this._orientation = {\n alpha: 0,\n beta: 90,\n gamma: 0\n };\n this._yawOrigin = 0;\n this._yawOffset = 0;\n this._orientationUpdated = false;\n this._screenOrientation = 0;\n this._needsCalibrate = true;\n this._enabled = false;\n }\n\n public enable() {\n if (this._enabled) return;\n\n window.addEventListener(BROWSER.EVENTS.DEVICE_ORIENTATION, this._onDeviceOrientation);\n window.addEventListener(BROWSER.EVENTS.ORIENTATION_CHANGE, this._updateScreenOrientation);\n\n this._updateScreenOrientation();\n this._orientationUpdated = false;\n this._needsCalibrate = true;\n this._enabled = true;\n }\n\n public disable() {\n if (!this._enabled) return;\n\n window.removeEventListener(BROWSER.EVENTS.DEVICE_ORIENTATION, this._onDeviceOrientation);\n window.removeEventListener(BROWSER.EVENTS.ORIENTATION_CHANGE, this._updateScreenOrientation);\n\n this._enabled = false;\n }\n\n public update() {\n this._updateRotation();\n this._orientationUpdated = false;\n }\n\n public collectDelta() {\n if (!this._orientationUpdated) {\n return {\n pitch: 0,\n yaw: 0\n };\n }\n\n const prevRotation = quat.clone(this.quaternion);\n\n this._updateRotation();\n this._orientationUpdated = false;\n\n return this._toEulerDelta(prevRotation, this.quaternion);\n }\n\n public setInitialRotation(yaw: number) {\n this._yawOrigin = yaw;\n }\n\n private _onDeviceOrientation = (evt: DeviceOrientationEvent) => {\n const prevOrientation = this._orientation;\n const { alpha, beta, gamma } = evt;\n\n if (\n alpha == null\n || beta == null\n || gamma == null\n ) return;\n\n prevOrientation.alpha = alpha;\n prevOrientation.beta = beta;\n prevOrientation.gamma = gamma;\n\n this._orientationUpdated = true;\n\n if (this._needsCalibrate) {\n this._needsCalibrate = false;\n this._calibrateSensor();\n }\n };\n\n private _calibrateSensor() {\n const yawOrigin = this._yawOrigin;\n const rotation = this.quaternion;\n\n this._yawOffset = 0;\n this._updateRotation();\n\n const { yaw: sensorYaw } = quatToEuler(rotation);\n this._yawOffset = sensorYaw - yawOrigin;\n this._updateRotation();\n\n this._needsCalibrate = false;\n }\n\n private _updateRotation() {\n const rotation = this.quaternion;\n const { alpha, beta, gamma } = this._orientation;\n\n quat.identity(rotation);\n quat.rotateY(rotation, rotation, (alpha - this._yawOffset) * DEG_TO_RAD);\n quat.rotateX(rotation, rotation, beta * DEG_TO_RAD);\n quat.rotateZ(rotation, rotation, -gamma * DEG_TO_RAD);\n\n const screen = quat.create();\n const screenAngle = -this._screenOrientation * 0.5 * DEG_TO_RAD;\n const world = quat.fromValues(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5));\n\n quat.set(screen, 0, Math.sin(screenAngle), 0, Math.cos(screenAngle));\n quat.multiply(rotation, rotation, screen);\n quat.multiply(rotation, rotation, world);\n\n quat.normalize(rotation, rotation);\n }\n\n private _updateScreenOrientation = () => {\n if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) {\n this._screenOrientation = screen.orientation.angle;\n } else if (window.orientation !== undefined) {\n this._screenOrientation = window.orientation >= 0 ?\n window.orientation : 360 + window.orientation;\n } else {\n this._screenOrientation = 0;\n }\n }\n\n private _toEulerDelta(prevQuat: quat, currentQuat: quat) {\n return {\n yaw: this._getDeltaYaw(prevQuat, currentQuat),\n pitch: this._getDeltaPitch(prevQuat, currentQuat),\n };\n }\n\n private _getDeltaYaw(prvQ: quat, curQ: quat): number {\n const yawDeltaByYaw = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW);\n const yawDeltaByRoll = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL)\n * Math.sin(this._extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n }\n\n private _getDeltaPitch(prvQ: quat, curQ: quat): number {\n return this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n }\n\n private _getRotationDelta(prevQ: quat, curQ: quat, rotateKind: typeof ROTATE_CONSTANT[keyof typeof ROTATE_CONSTANT]) {\n const targetAxis = vec3.fromValues(\n ROTATE_CONSTANT[rotateKind].targetAxis[0],\n ROTATE_CONSTANT[rotateKind].targetAxis[1],\n ROTATE_CONSTANT[rotateKind].targetAxis[2]\n );\n const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint;\n\n const prevQuaternion = quat.clone(prevQ);\n const curQuaternion = quat.clone(curQ);\n\n quat.normalize(prevQuaternion, prevQuaternion);\n quat.normalize(curQuaternion, curQuaternion);\n\n let prevPoint = vec3.fromValues(0, 0, 1);\n let curPoint = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n vec3.transformQuat(targetAxis, targetAxis, curQuaternion);\n\n const rotateDistance = vec3.dot(targetAxis, vec3.cross(vec3.create(), prevPoint, curPoint));\n const rotateDirection = rotateDistance > 0 ? 1 : -1;\n\n // when counter clock wise, use vec3.fromValues(0,1,0)\n // when clock wise, use vec3.fromValues(0,-1,0)\n // const meshPoint1 = vec3.fromValues(0, 0, 0);\n const meshPoint2 = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n\n let meshPoint3;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n meshPoint3 = vec3.fromValues(0, rotateDirection, 0);\n } else {\n meshPoint3 = vec3.fromValues(rotateDirection, 0, 0);\n }\n\n vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion);\n vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion);\n\n const vecU = meshPoint2;\n const vecV = meshPoint3;\n const vecN = vec3.create();\n\n vec3.cross(vecN, vecU, vecV);\n vec3.normalize(vecN, vecN);\n\n const coefficientA = vecN[0];\n const coefficientB = vecN[1];\n const coefficientC = vecN[2];\n\n // a point on the plane\n curPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n\n // a point should project on the plane\n prevPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n\n // distance between prevPoint and the plane\n let distance = Math.abs(\n prevPoint[0] * coefficientA +\n prevPoint[1] * coefficientB +\n prevPoint[2] * coefficientC\n );\n\n const projectedPrevPoint = vec3.create();\n\n vec3.subtract(projectedPrevPoint, prevPoint, vec3.scale(vec3.create(), vecN, distance));\n\n let trigonometricRatio =\n (projectedPrevPoint[0] * curPoint[0] +\n projectedPrevPoint[1] * curPoint[1] +\n projectedPrevPoint[2] * curPoint[2]) /\n (vec3.length(projectedPrevPoint) * vec3.length(curPoint));\n\n // defensive block\n if (trigonometricRatio > 1) {\n trigonometricRatio = 1;\n }\n\n const theta = Math.acos(trigonometricRatio);\n\n const crossVec = vec3.cross(vec3.create(), curPoint, projectedPrevPoint);\n\n distance = coefficientA * crossVec[0]\n + coefficientB * crossVec[1]\n + coefficientC * crossVec[2];\n\n let thetaDirection: number;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n thetaDirection = distance > 0 ? 1 : -1;\n } else {\n thetaDirection = distance < 0 ? 1 : -1;\n }\n\n const deltaRadian = theta * thetaDirection * rotateDirection;\n\n return deltaRadian * RAD_TO_DEG;\n }\n\n private _extractPitchFromQuat(quaternion: quat) {\n const baseV = vec3.fromValues(0, 0, 1);\n vec3.transformQuat(baseV, baseV, quaternion);\n\n return -1 * Math.atan2(\n baseV[1],\n Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2)));\n }\n}\n\nexport default GyroInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport GyroInput from \"./input/GyroInput\";\nimport Motion from \"../core/Motion\";\nimport Camera from \"../core/Camera\";\nimport * as BROWSER from \"../const/browser\";\nimport { CONTROL_EVENTS } from \"../const/internal\";\nimport { ControlEvents } from \"../type/internal\";\nimport { sensorCanBeEnabledIOS } from \"../utils\";\n\n/**\n * Options for {@link GyroControl}\n * @ko {@link GyroControl}용 옵션들\n * @since 4.0.0\n */\nexport interface GyroControlOptions {\n /**\n * @copy GyroControl#ignoreRoll\n */\n ignoreRoll: boolean;\n}\n\nexport type GyroControlEvents = ControlEvents;\n\n/**\n * Camera's rotation control by gyroscope\n * @ko 자이로스코프를 이용한 회전 컨트롤\n * @since 4.0.0\n */\nclass GyroControl extends Component implements CameraControl {\n // Options\n private _ignoreRoll: GyroControlOptions[\"ignoreRoll\"];\n\n // Internal values\n private _enableBlocked: boolean;\n private _input: GyroInput;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._input.enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() {\n return this._input.enabled && this._input.orientationUpdated;\n }\n\n /**\n * When `true`, ignore gyroscope's roll(z-axis rotation) value.\n * :::caution\n * Setting `false` will ignore camera's range limit.\n * Options like {@link View360Options#yawRange}, {@link View360Options#pitchRange} are ignored, and {@link CylinderProjection} also can't force it's camera range limit.\n * :::\n * @ko `true`일 경우 자이로스코프 입력의 roll(z축 회전)값을 무시합니다.\n * :::caution\n * 이 값을 `false`로 설정할 경우 카메라 범위 제약을 무시합니다.\n * {@link View360Options#yawRange}, {@link View360Options#pitchRange}와 같은 값은 무시되며, {@link CylinderProjection} 사용시에도 범위를 벗어날 수 있습니다.\n * :::\n * @default true\n * @since 4.0.0\n */\n public get ignoreRoll() { return this._ignoreRoll; }\n public set ignoreRoll(val: GyroControlOptions[\"ignoreRoll\"]) { this._ignoreRoll = val; }\n\n /**\n * Return availability of the gyroscope.\n * :::caution\n * This will always return false until user permission under environments like iOS which requires user permission when using gyroscope.\n * :::\n * @ko 자이로스코프 사용 가능 여부를 반환합니다.\n * :::caution\n * iOS와 같이 GyroScope 사용시 사용자 Permission을 요구하는 환경에서는 사용자 Permission을 받기 전까지 항상 `false`입니다.\n * :::\n * @example\n * ```ts\n * const gyroAvailable = await GyroControl.isAvailable();\n * ```\n */\n public static async isAvailable(): Promise {\n if (!DeviceMotionEvent) {\n return false;\n }\n\n let onDeviceMotionChange: (evt: DeviceMotionEvent) => void;\n\n const listenDeviceMotion = () => new Promise(res => {\n onDeviceMotionChange = (evt: DeviceMotionEvent) => {\n res(evt.rotationRate && evt.rotationRate.alpha != null);\n };\n\n window.addEventListener(BROWSER.EVENTS.DEVICE_MOTION, onDeviceMotionChange);\n });\n\n const timeout = () => new Promise(res => {\n setTimeout(() => res(false), 1000);\n });\n\n return Promise.race([listenDeviceMotion(), timeout()])\n .then((available: boolean) => {\n window.removeEventListener(BROWSER.EVENTS.DEVICE_MOTION, onDeviceMotionChange);\n\n return available;\n });\n }\n\n /**\n * Request user permission for gyroscope sensor.\n * This can be used in environments like iOS which requires user permission when using gyroscope sensors.\n * @ko 사용자의 sensor permission 취득을 요청합니다.\n * iOS와 같이 gyroscope 사용시 사용자 Permission을 요구하는 환경에서 사용 가능합니다.\n * @returns Whether the permission is granted {@ko 사용자 permission 취득 여부}\n */\n public static async requestSensorPermission(): Promise {\n // Request sensor permission, on iOS13+\n if (sensorCanBeEnabledIOS()) {\n return (DeviceMotionEvent as typeof DeviceMotionEvent & {\n requestPermission: () => Promise;\n }).requestPermission().then(permissionState => {\n return permissionState === \"granted\";\n }).catch(() => false);\n }\n\n return true;\n }\n\n /**\n * Create new GyroControl instance\n * @ko GyroControl의 인스턴스를 생성합니다.\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(enableBlocked: boolean, {\n ignoreRoll = true\n }: Partial = {}) {\n super();\n\n this._enableBlocked = enableBlocked;\n this._ignoreRoll = ignoreRoll;\n this._input = new GyroInput();\n }\n\n /**\n * @copy CameraControl#destroy\n */\n public destroy(): void {\n this.disable();\n this._input.off();\n this.off();\n }\n\n /**\n * @hidden\n */\n public update(camera: Camera, yaw: Motion, pitch: Motion, zoom: number) {\n if (!this._ignoreRoll) {\n this._updateQuaternion(camera, zoom);\n } else {\n this._updateYawPitch(camera, yaw, pitch, zoom);\n }\n }\n\n /**\n * @copy CameraControl#enable\n */\n public enable(): void {\n if (this._input.enabled) return;\n\n this._input.enable();\n this._enableBlocked = false;\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: false });\n }\n\n /**\n * @copy CameraControl#disable\n */\n public disable(): void {\n if (!this._input.enabled) return;\n\n this._input.disable();\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: false });\n }\n\n /**\n * @copy CameraControl#sync\n */\n public sync(): void {} // eslint-disable-line @typescript-eslint/no-empty-function\n\n private _updateYawPitch(camera: Camera, yaw: Motion, pitch: Motion, zoom: number) {\n const input = this._input;\n if (!input.enabled) return;\n\n const {\n yaw: yawDelta,\n pitch: pitchDelta\n } = input.collectDelta();\n\n yaw.add(yawDelta);\n pitch.add(pitchDelta);\n\n camera.lookAt({\n yaw: yaw.val,\n pitch: pitch.val,\n zoom\n });\n }\n\n private _updateQuaternion(camera: Camera, zoom: number) {\n const input = this._input;\n if (!input.enabled) return;\n\n input.update();\n camera.rotate(input.quaternion, zoom);\n }\n}\n\nexport default GyroControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport CameraControl from \"./CameraControl\";\nimport RotateControl, { RotateControlEvents, RotateControlOptions } from \"./RotateControl\";\nimport ZoomControl, { ZoomControlOptions } from \"./ZoomControl\";\nimport GyroControl, { GyroControlOptions } from \"./GyroControl\";\nimport Camera from \"../core/Camera\";\nimport CameraAnimation from \"../core/CameraAnimation\";\nimport * as BROWSER from \"../const/browser\";\nimport { CAMERA_EVENTS, CONTROL_EVENTS } from \"../const/internal\";\nimport { ValueOf } from \"../type/utils\";\nimport { getObjectOption, hfovToZoom } from \"../utils\";\n\n/**\n * Options for {@link PanoControl}\n * @ko {@link PanoControl}용 옵션들\n * @since 4.0.0\n */\nexport interface PanoControlOptions {\n /**\n * @copy View360#useGrabCursor\n */\n useGrabCursor: boolean;\n /**\n * @copy View360#scrollable\n */\n scrollable: boolean;\n /**\n * @copy View360#wheelScrollable\n */\n wheelScrollable: boolean;\n /**\n * @copy View360#disableContextMenu\n */\n disableContextMenu: boolean;\n /**\n * Options for {@link RotateControl}.\n * `false` to disable rotation.\n * @ko {@link RotateControl}용 옵션들.\n * `false`일 경우 회전이 비활성화됩니다.\n * @since 4.0.0\n */\n rotate: boolean | Partial;\n /**\n * Options for {@link ZoomControl}.\n * `false` to disable zoom.\n * @ko {@link ZoomControl}용 옵션들.\n * `false`일 경우 줌이 비활성화됩니다.\n * @since 4.0.0\n */\n zoom: boolean | Partial;\n /**\n * Options for {@link GyroControl}.\n * `false` to disable gyroscope control.\n * @ko {@link GyroControl}용 옵션들.\n * `false`일 경우 자이로스코프를 통한 컨트롤이 비활성화됩니다.\n * @since 4.0.0\n */\n gyro: boolean | Partial;\n}\n\n/**\n * Panorama control for View360\n * @ko View360용 파노라마 컨트롤\n * @since 4.0.0\n */\nclass PanoControl {\n // Options\n private _useGrabCursor: PanoControlOptions[\"useGrabCursor\"];\n private _disableContextMenu: PanoControlOptions[\"disableContextMenu\"];\n\n // Internal Values\n private _camera: Camera;\n private _controlEl: HTMLElement;\n private _rotateControl: RotateControl;\n private _zoomControl: ZoomControl;\n private _gyroControl: GyroControl;\n private _ignoreZoomScale: boolean;\n private _enabled: boolean;\n\n /**\n * @copy View360#useGrabCursor\n */\n public get useGrabCursor() { return this._useGrabCursor; }\n public set useGrabCursor(val: PanoControlOptions[\"useGrabCursor\"]) {\n if (val === this._useGrabCursor) return;\n\n this._useGrabCursor = val;\n\n if (val && this._enabled) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n } else if (!val) {\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n }\n\n /**\n * @copy View360#disableContextMenu\n */\n public get disableContextMenu() { return this._disableContextMenu; }\n public set disableContextMenu(val: PanoControlOptions[\"disableContextMenu\"]) {\n if (val === this._disableContextMenu) return;\n\n this._disableContextMenu = val;\n\n if (val && this._enabled) {\n this._blockContextMenu();\n } else if (!val) {\n this._restoreContextMenu();\n }\n }\n\n /**\n * @copy View360#disableContextMenu\n */\n public get scrollable() { return this._rotateControl.scrollable; }\n public set scrollable(val: PanoControlOptions[\"scrollable\"]) { this._rotateControl.scrollable = val; }\n /**\n * @copy View360#disableContextMenu\n */\n public get wheelScrollable() { return this._zoomControl.scrollable; }\n public set wheelScrollable(val: PanoControlOptions[\"wheelScrollable\"]) { this._zoomControl.scrollable = val; }\n /**\n * When `true`, disables rotation slow-down by zoom-value.\n * @ko `true`일 경우 줌 된 정도에 따라 회전속도를 늦추는 동작을 비활성화합니다.\n * @since 4.0.0\n */\n public get ignoreZoomScale() { return this._ignoreZoomScale; }\n public set ignoreZoomScale(val: boolean) { this._ignoreZoomScale = val; }\n\n /**\n * Whether the control is enabled or not\n * @ko 컨트롤 활성화 여부를 가리키는 값\n * @readonly\n * @since 4.0.0\n */\n public get enabled() { return this._enabled; }\n /**\n * @copy View360#rotate\n */\n public get rotate() { return this._rotateControl; }\n /**\n * @copy View360#zoom\n */\n public get zoom() { return this._zoomControl; }\n /**\n * @copy View360#gyro\n */\n public get gyro() { return this._gyroControl; }\n\n /**\n * Whether one of the controls is animating at the moment\n * @ko 현재 컨트롤 중 하나라도 동작중인지 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get animating() {\n return this._rotateControl.animating\n || this._zoomControl.animating\n || this._gyroControl.animating;\n }\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param element - Canvas element {@ko 캔버스 엘리먼트}\n * @param camera - Camera instance {@ko Camera 인스턴스}\n * @param options - Options for PanoControl {@ko PanoControl 옵션들}\n */\n public constructor(element: HTMLElement, camera: Camera, {\n useGrabCursor,\n scrollable,\n wheelScrollable,\n disableContextMenu,\n rotate,\n zoom,\n gyro\n }: PanoControlOptions) {\n // Bind Options\n this._useGrabCursor = useGrabCursor;\n this._disableContextMenu = disableContextMenu;\n\n // Set internal values\n this._camera = camera;\n this._controlEl = element;\n this._ignoreZoomScale = false;\n this._enabled = false;\n\n this._rotateControl = new RotateControl(element, !rotate, getObjectOption(rotate));\n this._zoomControl = new ZoomControl(element, !zoom, getObjectOption(zoom));\n this._gyroControl = new GyroControl(!gyro, getObjectOption(gyro));\n\n this._rotateControl.scrollable = scrollable;\n this._zoomControl.scrollable = wheelScrollable;\n\n this._bindEvents();\n }\n\n /**\n * Destroy the instance and remove all event listeners attached.\n * This also will reset CSS cursor to initial.\n * @ko 인스턴스를 삭제하고 부착된 모든 이벤트 리스너를 제거합니다.\n * 또한, 캔버스에 적용된 CSS cursor도 제거합니다.\n * @since 4.0.0\n */\n public destroy(): void {\n this.disable();\n this._rotateControl.destroy();\n this._zoomControl.destroy();\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n\n /**\n * Resize control to match target size.\n * @ko 컨트롤이 내부에 캐시하고 있는 크기값을 갱신합니다.\n * @param width New width {@ko 변경된 너비}\n * @param height New height {@ko 변경된 높이}\n * @since 4.0.0\n */\n public resize(width: number, height: number): void {\n const camera = this._camera;\n\n this._rotateControl.resize(camera.fov, camera.aspect, width, height);\n }\n\n /**\n * Enable this control and add event listeners.\n * @ko 컨트롤을 활성화하고 이벤트 리스너들을 추가합니다.\n * @since 4.0.0\n */\n public async enable(): Promise {\n if (this._enabled) return;\n\n if (!this._rotateControl.enableBlocked) {\n this._rotateControl.enable();\n }\n\n if (!this._zoomControl.enableBlocked) {\n this._zoomControl.enable();\n }\n\n if (!this._gyroControl.enableBlocked) {\n if (await GyroControl.isAvailable()) {\n this._gyroControl.enable();\n }\n }\n\n this.sync();\n\n if (this._disableContextMenu) {\n this._blockContextMenu();\n }\n\n this._enabled = true;\n }\n\n /**\n * Disable this control and remove all event listeners\n * @ko 컨트롤을 비활성화하고 모든 이벤트 리스너들을 제거합니다.\n * @since 4.0.0\n */\n public disable(): void {\n if (!this._enabled) return;\n\n this._rotateControl.disable();\n this._zoomControl.disable();\n this._gyroControl.disable();\n\n this._restoreContextMenu();\n\n this._enabled = false;\n }\n\n /**\n * Update control by given deltaTime\n * @ko 컨트롤을 주어진 시간만큼 업데이트합니다.\n * @param delta Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n * @internal\n */\n public update(delta: number): void {\n const camera = this._camera;\n const rotateControl = this._rotateControl;\n const zoomControl = this._zoomControl;\n const gyroControl = this._gyroControl;\n\n zoomControl.update(delta);\n const zoom = hfovToZoom(camera.fov, zoomControl.zoom);\n\n // Slow down rotation on zoom-in\n const zoomScale = this._ignoreZoomScale ? 1 : Math.max(zoom, 1);\n rotateControl.setZoomScale(zoomScale);\n rotateControl.updateRange(camera, zoom);\n rotateControl.update(delta);\n\n const yaw = rotateControl.yaw;\n const pitch = rotateControl.pitch;\n\n if (gyroControl.enabled) {\n gyroControl.update(camera, yaw, pitch, zoom);\n } else {\n camera.lookAt({\n yaw: yaw.val,\n pitch: pitch.val,\n zoom\n });\n }\n }\n\n /**\n * Synchronize this control's state to current camera state\n * @ko 컨트롤을 카메라의 현재 상태와 동기화합니다.\n * @since 4.0.0\n */\n public sync(): void {\n const camera = this._camera;\n\n this._zoomControl.sync(camera);\n this._rotateControl.sync(camera);\n }\n\n private _blockContextMenu() {\n const el = this._controlEl;\n\n el.addEventListener(BROWSER.EVENTS.CONTEXT_MENU, this._preventContextMenu);\n }\n\n private _restoreContextMenu() {\n const el = this._controlEl;\n\n el.removeEventListener(BROWSER.EVENTS.CONTEXT_MENU, this._preventContextMenu);\n }\n\n private _preventContextMenu = (evt: MouseEvent) => {\n evt.preventDefault();\n };\n\n private _setCursor(newCursor: ValueOf) {\n if (!this._useGrabCursor && newCursor !== BROWSER.CURSOR.NONE) return;\n\n const targetEl = this._controlEl;\n targetEl.style.cursor = newCursor;\n }\n\n private _bindEvents() {\n const rotateControl = this._rotateControl;\n const zoomControl = this._zoomControl;\n\n rotateControl.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n rotateControl.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n rotateControl.on(CONTROL_EVENTS.ENABLE, this._onEnable);\n rotateControl.on(CONTROL_EVENTS.DISABLE, this._onDisable);\n zoomControl.on(CONTROL_EVENTS.ENABLE, this._onEnable);\n zoomControl.on(CONTROL_EVENTS.DISABLE, this._onDisable);\n this._camera.on(CAMERA_EVENTS.ANIMATION_END, this._onCameraAnimationEnd);\n }\n\n private _onInputStart = (evt: RotateControlEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n if (this._useGrabCursor && !evt.isKeyboard) {\n this._setCursor(BROWSER.CURSOR.GRABBING);\n }\n };\n\n private _onInputEnd = (evt: RotateControlEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n if (this._useGrabCursor && !evt.isKeyboard) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n }\n };\n\n private _onEnable = ({\n control,\n updateCursor\n }: {\n control: CameraControl;\n updateCursor: boolean;\n }) => {\n if (updateCursor && this._useGrabCursor) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n }\n\n control.sync(this._camera);\n };\n\n private _onDisable = ({\n updateCursor\n }: {\n updateCursor: boolean\n }) => {\n if (updateCursor) {\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n };\n\n private _onCameraAnimationEnd = ({ animation }: { animation: CameraAnimation }) => {\n animation.getFinishPromise().then(() => {\n this.sync();\n });\n };\n}\n\nexport default PanoControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport TextureVideo from \"./TextureVideo\";\nimport TextureCube from \"./TextureCube\";\n\n/**\n * @hidden\n */\nabstract class Texture {\n public width: number;\n public height: number;\n public flipY: boolean;\n public wrapS: number;\n public wrapT: number;\n\n public constructor({\n width,\n height,\n flipY\n }: {\n width: number;\n height: number;\n flipY: boolean;\n }) {\n this.width = width;\n this.height = height;\n this.flipY = flipY;\n this.wrapS = WebGLRenderingContext.CLAMP_TO_EDGE;\n this.wrapT = WebGLRenderingContext.CLAMP_TO_EDGE;\n }\n\n public destroy() {\n // DO_NOTHING\n }\n\n public isVideo(): this is TextureVideo {\n return false;\n }\n\n public isCube(): this is TextureCube {\n return false;\n }\n}\n\nexport default Texture;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture from \"./Texture\";\n\n/**\n * @hidden\n */\nclass Texture2D extends Texture {\n public source: Exclude;\n\n public constructor({\n source,\n width,\n height,\n flipY\n }: {\n source: Exclude;\n width: number;\n height: number;\n flipY: boolean;\n }) {\n super({\n width,\n height,\n flipY\n });\n\n this.source = source;\n }\n}\n\nexport default Texture2D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"./Texture2D\";\n\n/**\n * @hidden\n */\nclass TextureVideo extends Texture2D {\n public source: HTMLVideoElement;\n\n public destroy() {\n const video = this.source;\n\n video.pause();\n video.removeAttribute(\"src\");\n video.load();\n }\n\n public isVideo(): this is TextureVideo { return true; }\n\n public isPaused() {\n const video = this.source;\n\n return video.paused || video.ended || video.readyState <= 2;\n }\n\n public hasAudio() {\n const video = this.source as any;\n\n if (video.audioTracks) {\n return video.audioTracks.length > 0;\n }\n\n if (video.webkitAudioDecodedByteCount != null) {\n return video.webkitAudioDecodedByteCount > 0;\n }\n\n if (video.mozHasAudio != null) {\n return video.mozHasAudio;\n }\n\n // We don't know whether the video has audio or not, return true\n return true;\n }\n}\n\nexport default TextureVideo;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture from \"./Texture\";\n\n/**\n * @hidden\n */\nclass TextureCube extends Texture {\n public sources: TexImageSource[];\n\n public constructor({\n sources,\n width,\n height,\n flipY\n }: {\n sources: TexImageSource[];\n width: number;\n height: number;\n flipY: boolean;\n }) {\n super({\n width,\n height,\n flipY\n });\n\n this.sources = sources;\n }\n\n public isCube(): this is TextureCube { return true; }\n}\n\nexport default TextureCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ImReady from \"@egjs/imready\";\nimport Texture from \"../texture/Texture\";\nimport Texture2D from \"../texture/Texture2D\";\nimport TextureVideo from \"../texture/TextureVideo\";\nimport TextureCube from \"../texture/TextureCube\";\nimport { getObjectOption, isString } from \"../utils\";\nimport { VideoConfig } from \"../type/external\";\nimport { ProjectionOptions } from \"../projection/Projection\";\n\n/**\n * @hidden\n */\nclass TextureLoader {\n private _loadChecker: ImReady;\n\n constructor() {\n this._loadChecker = new ImReady();\n }\n\n public async load(src: ProjectionOptions[\"src\"], video: ProjectionOptions[\"video\"]): Promise {\n if (video) {\n return this.loadVideo(src, getObjectOption(video));\n } else {\n if (Array.isArray(src) && src.length > 1) {\n return this.loadCubeImage(src);\n } else {\n const imgSrc = Array.isArray(src) ? src[0] : src;\n return this.loadImage(imgSrc);\n }\n }\n }\n\n public async loadImage(src: string | HTMLElement): Promise {\n const images = this._toImageArray(src);\n\n return this._load(images, resolve => {\n const image = images[0];\n\n resolve(new Texture2D({\n source: image,\n width: image.naturalWidth,\n height: image.naturalHeight,\n flipY: true\n }));\n });\n }\n\n public async loadCubeImage(src: Array): Promise {\n const images = this._toImageArray(src);\n\n return this._load(images, resolve => {\n resolve(new TextureCube({\n sources: images,\n width: images[0].naturalWidth,\n height: images[0].naturalHeight,\n flipY: false\n }));\n });\n }\n\n public async loadVideo(src: ProjectionOptions[\"src\"], videoConfig: Partial): Promise {\n const config: VideoConfig = {\n autoplay: true,\n muted: true,\n loop: false,\n volume: 1,\n ...videoConfig,\n };\n const video = this._toVideoElement(src, config);\n\n return this._load([video], resolve => {\n const { autoplay, muted } = config;\n\n video.currentTime = 0;\n if (autoplay && muted) {\n video.play().catch(() => void 0);\n }\n\n resolve(new TextureVideo({\n source: video,\n width: video.videoWidth,\n height: video.videoHeight,\n flipY: true\n }));\n });\n }\n\n private _load(content: HTMLElement[], onLoad: (resolve: (value: T) => void) => void): Promise {\n const loader = this._loadChecker;\n\n return new Promise((resolve, reject) => {\n loader.once(\"ready\", evt => {\n if (evt.errorCount > 0) return;\n\n onLoad(resolve);\n });\n\n loader.once(\"error\", reject);\n loader.check(content);\n });\n }\n\n private _toImageArray(src: ProjectionOptions[\"src\"]): HTMLImageElement[] {\n const srcs = Array.isArray(src) ? src : [src];\n\n return srcs.map(source => {\n if (isString(source)) {\n const imgEl = new Image();\n\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = source;\n\n return imgEl;\n } else {\n return source as HTMLImageElement;\n }\n });\n }\n\n private _toVideoElement(src: ProjectionOptions[\"src\"], {\n muted,\n loop,\n volume\n }: VideoConfig): HTMLVideoElement {\n if (src instanceof HTMLVideoElement) {\n return src;\n }\n\n const video = document.createElement(\"video\");\n\n video.crossOrigin = \"anonymous\";\n video.playsInline = true;\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.muted = muted;\n video.volume = volume;\n video.loop = loop;\n\n if (Array.isArray(src)) {\n src.forEach(source => this._appendSourceElement(video, source));\n } else {\n this._appendSourceElement(video, src);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0 && video.readyState < 1) {\n video.load();\n }\n\n return video;\n }\n\n private _appendSourceElement(video: HTMLMediaElement, src: string | HTMLElement) {\n if (src instanceof HTMLSourceElement) {\n return src;\n }\n\n const sourceEl = document.createElement(\"source\");\n sourceEl.src = src as string;\n video.appendChild(sourceEl);\n }\n}\n\nexport default TextureLoader;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * @internal\n */\nclass FrameAnimator {\n public maxDeltaTime: number;\n\n private _context: Window | XRSession;\n private _rafId: number;\n private _rafTimer: number;\n private _lastUpdateTime: number;\n\n /** */\n public constructor(maxDeltaTime: number, context: Window | XRSession = window) {\n this.maxDeltaTime = maxDeltaTime;\n\n this._context = context;\n this._rafId = -1;\n this._rafTimer = -1;\n this._lastUpdateTime = -1;\n }\n\n public start(callback: (delta: number, ...args: any[]) => any) {\n const context = this._context;\n\n // No context / callback set\n if (!context || !callback) return;\n\n // Animation already started\n if (this._rafId >= 0 || this._rafTimer >= 0) return;\n\n const loop = (_time: number, frame?: XRFrame) => {\n const time = Date.now();\n const delta = Math.min(time - this._lastUpdateTime, this.maxDeltaTime * 1000);\n\n callback(delta, frame);\n\n this._lastUpdateTime = time;\n this._rafId = context.requestAnimationFrame(loop);\n };\n\n this._lastUpdateTime = Date.now();\n this._rafId = context.requestAnimationFrame(loop);\n }\n\n public stop() {\n if (this._rafId >= 0) {\n this._context.cancelAnimationFrame(this._rafId);\n }\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n }\n\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n public changeContext(context: Window | XRSession) {\n this.stop();\n this._context = context;\n }\n}\n\nexport default FrameAnimator;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport * as BROWSER from \"../const/browser\";\n\n/**\n * Automatic resizer that uses both ResizeObserver and window resize event\n */\nclass AutoResizer {\n private _enabled: boolean;\n private _resizeObserver: ResizeObserver | null;\n private _useResizeObserver: boolean;\n private _onResize: () => any;\n\n public get useResizeObserver() { return this._useResizeObserver; }\n\n /**\n * Returns whether AutoResizer is enabled\n */\n public get enabled() { return this._enabled; }\n\n /** */\n public constructor(useResizeObserver: boolean, onResize: () => any) {\n this._useResizeObserver = useResizeObserver;\n\n this._enabled = false;\n this._resizeObserver = null;\n this._onResize = onResize;\n }\n\n /**\n * Enable resizer\n */\n public enable(element: HTMLElement): this {\n if (this._enabled) {\n this.disable();\n }\n\n if (this._useResizeObserver && !!window.ResizeObserver) {\n const bbox = element.getBoundingClientRect();\n const resizeImmediate = bbox.width !== 0 || bbox.height !== 0;\n\n const resizeObserver = new ResizeObserver(resizeImmediate ? this._skipFirstResize : this._onResize);\n\n resizeObserver.observe(element);\n\n this._resizeObserver = resizeObserver;\n } else {\n window.addEventListener(BROWSER.EVENTS.RESIZE, this._onResize);\n }\n\n this._enabled = true;\n\n return this;\n }\n\n /**\n * Disable resizer\n */\n public disable(): this {\n if (!this._enabled) return this;\n\n const resizeObserver = this._resizeObserver;\n if (resizeObserver) {\n resizeObserver.disconnect();\n this._resizeObserver = null;\n } else {\n window.removeEventListener(BROWSER.EVENTS.RESIZE, this._onResize);\n }\n\n this._enabled = false;\n\n return this;\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n private _skipFirstResize = (() => {\n let isFirstResize = true;\n\n return (() => {\n if (isFirstResize) {\n isFirstResize = false;\n\n return;\n }\n this._onResize();\n });\n })();\n}\n\nexport default AutoResizer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Camera from \"./Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport View360 from \"../View360\";\nimport * as BROWSER from \"../const/browser\";\nimport { CONTROL_EVENTS } from \"../const/internal\";\nimport { circulate, getObjectOption } from \"../utils\";\n\n/**\n * Options for {@link Autoplay}\n * @ko {@link Autoplay}용 옵션들\n * @since 4.0.0\n */\nexport interface AutoplayOptions {\n /**\n * @copy Autoplay#delay\n */\n delay: number;\n /**\n * @copy Autoplay#delayOnMouseLeave\n */\n delayOnMouseLeave: number;\n /**\n * @copy Autoplay#speed\n */\n speed: number;\n /**\n * @copy Autoplay#pauseOnHover\n */\n pauseOnHover: boolean;\n /**\n * @copy Autoplay#canInterrupt\n */\n canInterrupt: boolean;\n /**\n * @copy Autoplay#disableOnInterrupt\n */\n disableOnInterrupt: boolean;\n}\n\n/**\n * A manager class for autoplay feature.\n * @ko Autoplay 기능의 매니저 클래스.\n * @since 4.0.0\n */\nclass Autoplay {\n // Options\n private _delay: number;\n private _delayOnMouseLeave: number;\n private _speed: number;\n private _pauseOnHover: boolean;\n private _canInterrupt: boolean;\n private _disableOnInterrupt: boolean;\n\n // Internal values\n private _enableBlocked: boolean;\n private _camera: Camera;\n private _control: PanoControl;\n private _element: HTMLElement;\n private _enabled: boolean;\n private _interrupted: boolean;\n private _interruptionTimer: number;\n private _hovering: boolean;\n\n /**\n * Whether autoplay is enabled or not\n * @ko 자동재생 활성화 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * Whether autoplay is updating the camera at the moment\n * @ko 현재 자동재생이 동작중인지 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get playing() {\n return this._enabled && !this._interrupted;\n }\n\n /**\n * Reactivation delay after mouse input in milisecond.\n * @ko 재활성화되기까지의 시간 (밀리초 단위)\n * @default 2000\n * @since 4.0.0\n */\n public get delay() { return this._delay; }\n public set delay(val: number) { this._delay = val; }\n\n /**\n * Reactivation delay after mouse leave when using {@link AutoplayOptions#pauseOnHover}\n * @ko {@link AutoplayOptions#pauseOnHover} 사용시 마우스가 캔버스 영역을 떠난 뒤 자동재생이 다시 활성화되기까지의 시간\n * @default 0\n * @since 4.0.0\n */\n public get delayOnMouseLeave() { return this._delayOnMouseLeave; }\n public set delayOnMouseLeave(val: number) { this._delayOnMouseLeave = val; }\n\n /**\n * Y-axis(yaw) rotation speed\n * @ko Y-축 회전(yaw)의 속도\n * @default 1\n * @since 4.0.0\n */\n public get speed() { return this._speed; }\n public set speed(val: number) { this._speed = val; }\n\n /**\n * Whether to pause rotation on mouse hover\n * @ko 마우스가 캔버스 영역에 들어왔을 때 자동재생을 정지할지 여부\n * @default false\n * @since 4.0.0\n */\n public get pauseOnHover() { return this._pauseOnHover; }\n public set pauseOnHover(val: boolean) { this._pauseOnHover = val; }\n\n /**\n * Whether user can interrupt the rotation with click/wheel input\n * @ko 클릭이나 휠같은 사용자 인터랙션시 자동재생을 멈출지 여부\n * @default true\n * @since 4.0.0\n */\n public get canInterrupt() { return this._canInterrupt; }\n public set canInterrupt(val: boolean) { this._canInterrupt = val; }\n\n /**\n * Whether to disable autoplay on user interrupt\n * @ko 사용자 동작에 의해 자동재생이 정지할 때, {@link Autoplay#disable}을 호출하여 자동재생을 영구히 정지할지 여부\n * @default false\n * @since 4.0.0\n */\n public get disableOnInterrupt() { return this._disableOnInterrupt; }\n public set disableOnInterrupt(val: boolean) { this._disableOnInterrupt = val; }\n\n /**\n * Create new AutoPlayer instance\n * @param camera - Instance of the {@link Camera} {@ko Camera의 인스턴스}\n * @param element - Canvas element {@ko 캔버스 엘리먼트}\n * @param options - Autoplay options {@ko 자동재생 옵션들}\n * @since 4.0.0\n */\n public constructor(viewer: View360, element: HTMLElement, options: boolean | Partial) {\n this._camera = viewer.camera;\n this._control = viewer.control;\n this._element = element;\n\n this._enabled = false;\n this._interrupted = false;\n this._interruptionTimer = -1;\n this._hovering = false;\n\n const {\n delay = 2000,\n delayOnMouseLeave = 0,\n speed = 1,\n pauseOnHover = false,\n canInterrupt = true,\n disableOnInterrupt = false\n } = getObjectOption(options);\n\n this._enableBlocked = !options;\n this._delay = delay;\n this._delayOnMouseLeave = delayOnMouseLeave;\n this._speed = speed;\n this._pauseOnHover = pauseOnHover;\n this._canInterrupt = canInterrupt;\n this._disableOnInterrupt = disableOnInterrupt;\n }\n\n /**\n * Destroy the instance and remove all event listeners attached\n * @ko 인스턴스를 제거하고 연결된 모든 이벤트 핸들러를 삭제합니다.\n * @since 4.0.0\n */\n public destroy(): void {\n this.disable();\n }\n\n /**\n * Rotate camera by given deltaTime\n * @ko 주어진 deltaTime만큼 카메라를 회전시킵니다.\n * @param deltaTime - Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n */\n public update(deltaTime: number): void {\n if (!this._enabled) return;\n if (this._interrupted) {\n if (this._disableOnInterrupt) {\n this.disable();\n }\n\n return;\n }\n\n const camera = this._camera;\n const delta = -this._speed * deltaTime / 100;\n\n camera.yaw = circulate(camera.yaw + delta, 0, 360);\n }\n\n /**\n * Enable autoplay and add event listeners.\n * @ko 자동재생을 활성화하고 이벤트리스너들을 추가합니다.\n * @since 4.0.0\n */\n public enable(): void {\n const control = this._control;\n const element = this._element;\n\n if (this._enabled || control.gyro.enabled) return;\n\n control.rotate.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.rotate.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.zoom.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.zoom.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.gyro.on(CONTROL_EVENTS.ENABLE, this._onGyroEnable);\n\n element.addEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter, false);\n element.addEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave, false);\n\n this._enabled = true;\n this._enableBlocked = false;\n }\n\n /**\n * Enable autoplay after current `delay` value.\n * @ko 현재의 `delay`값만큼 시간이 지난 다음에 자동재생을 활성화합니다.\n * @since 4.0.0\n */\n public enableAfterDelay() {\n this.enable();\n this._interrupted = true;\n this._setUninterruptedAfterDelay(this._delay);\n }\n\n /**\n * Disable autoplay and remove all event handlers.\n * @ko 자동재생을 비활성화하고 모든 이벤트 핸들러를 제거합니다.\n * @since 4.0.0\n */\n public disable(): void {\n if (!this._enabled) return;\n\n const control = this._control;\n const element = this._element;\n\n control.rotate.off(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.rotate.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.zoom.off(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.zoom.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.gyro.off(CONTROL_EVENTS.ENABLE, this._onGyroEnable);\n\n element.removeEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter, false);\n element.removeEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave, false);\n\n this._enabled = false;\n this._interrupted = false;\n this._hovering = false;\n\n this._clearTimeout();\n }\n\n private _onInputStart = () => {\n if (!this._canInterrupt) return;\n\n this._interrupted = true;\n this._clearTimeout();\n };\n\n private _onInputEnd = () => {\n this._setUninterruptedAfterDelay(this._delay);\n };\n\n private _onGyroEnable = () => {\n this.disable();\n };\n\n private _onMouseEnter = () => {\n if (!this._pauseOnHover) return;\n this._interrupted = true;\n this._hovering = true;\n };\n\n private _onMouseLeave = () => {\n if (!this._pauseOnHover) return;\n this._hovering = false;\n this._setUninterruptedAfterDelay(this._delayOnMouseLeave);\n };\n\n private _setUninterruptedAfterDelay(delay: number): void {\n if (this._hovering) return;\n\n this._clearTimeout();\n\n if (delay > 0) {\n this._interruptionTimer = window.setTimeout(() => {\n this._interrupted = false;\n this._interruptionTimer = -1;\n }, delay);\n } else {\n this._interrupted = false;\n this._interruptionTimer = -1;\n }\n }\n\n private _clearTimeout(): void {\n if (this._interruptionTimer >= 0) {\n window.clearTimeout(this._interruptionTimer);\n this._interruptionTimer = -1;\n }\n }\n}\n\nexport default Autoplay;\n","import { mat4 } from \"gl-matrix\";\nimport Component from \"@egjs/component\";\nimport WebGLContext from \"./WebGLContext\";\nimport GyroControl from \"../control/GyroControl\";\nimport * as BROWSER from \"../const/browser\";\nimport { SESSION_VR, XR_REFERENCE_SPACE } from \"../const/internal\";\nimport { EVENTS } from \"../const/external\";\n\ninterface XRSessionOptions extends XRSessionInit {\n [key: string]: any;\n}\n\n/**\n * WebXR manager class\n * @ko WebXR 매니저 클래스\n * @since 4.0.0\n */\nclass XRManager extends Component<{\n /**\n * An event that fires on entering VR session\n * @ko VR 세션 진입시에 트리거되는 이벤트\n * @eventName vrStart\n * @eventOf XRManager\n * @version 4.0.0\n */\n [EVENTS.VR_START]: {\n session: XRSession;\n };\n /**\n * An event that fires on exiting VR session\n * @ko VR 세션에서 나갈 때 트리거되는 이벤트\n * @eventName vrEnd\n * @eventOf XRManager\n * @version 4.0.0\n */\n [EVENTS.VR_END]: void;\n}> {\n private _ctx: WebGLContext;\n private _xrSession: XRSession | null;\n private _xrRefSpace: XRReferenceSpace | null;\n private _options: XRSessionOptions;\n\n /**\n * Create new instance.\n * 새 인스턴스를 생성합니다.\n * @param ctx - Instance of WebGL context helper {@ko WebGL 콘텍스트 헬퍼의 인스턴스}\n * @param options - Options {@ko 옵션들}\n */\n public constructor(ctx: WebGLContext, options: XRSessionOptions = {}) {\n super();\n\n this._xrSession = null;\n this._xrRefSpace = null;\n this._ctx = ctx;\n this._options = options;\n }\n\n /**\n * Destroy instance and end XR session if there was any.\n * @ko 인스턴스를 제거하고, XR 세션이 존재할 경우 종료합니다.\n * @since 4.0.0\n */\n public destroy = () => {\n this.exit();\n this.off();\n };\n\n /**\n * Returns WebXR availability.\n * @ko WebXR 사용 가능 여부를 반환합니다.\n * @since 4.0.0\n */\n public async isAvailable(): Promise {\n // eslint-disable-next-line compat/compat\n const xr = window.navigator.xr;\n if (!xr) return false;\n\n return xr.isSessionSupported(SESSION_VR)\n .then(available => {\n return available;\n }).catch(() => {\n return false;\n });\n }\n\n /**\n * Enter VR session\n * @ko VR 세션에 진입합니다.\n * @since 4.0.0\n */\n public async enter() {\n const ctx = this._ctx;\n\n // eslint-disable-next-line compat/compat\n const xr = window.navigator.xr;\n if (!xr) return;\n\n await GyroControl.requestSensorPermission();\n\n const options = {\n ...{\n requiredFeatures: [XR_REFERENCE_SPACE]\n },\n ...this._options\n };\n\n await ctx.makeXRCompatible();\n\n const session = await xr.requestSession(SESSION_VR, options);\n ctx.bindXRLayer(session);\n\n const refSpace = await session.requestReferenceSpace(XR_REFERENCE_SPACE);\n\n this._setSession(session, refSpace);\n\n this.trigger(EVENTS.VR_START, {\n session\n });\n }\n\n /**\n * Exit VR session\n * @ko VR 세션에서 나갑니다.\n * @since 4.0.0\n */\n public exit() {\n const xrSession = this._xrSession;\n\n if (xrSession) {\n xrSession.end()\n .catch(() => void 0);\n }\n\n this._xrSession = null;\n this._xrRefSpace = null;\n }\n\n /**\n * @hidden\n */\n public canRender(frame: XRFrame) {\n const refSpace = this._xrRefSpace;\n\n if (!refSpace) return false;\n\n const pose = frame.getViewerPose(refSpace);\n\n return !!pose;\n }\n\n /**\n * @hidden\n */\n public getEyeParams(frame: XRFrame): Array<{\n viewport: XRViewport;\n vMatrix: mat4;\n pMatrix: mat4;\n }> | null {\n const session = frame.session;\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n if (!pose) return null;\n\n const glLayer = session.renderState.baseLayer;\n\n if (!glLayer) return null;\n\n return pose.views.map(view => {\n const viewport = glLayer.getViewport(view)!;\n const vMatrix = view.transform.inverse.matrix;\n\n return {\n viewport,\n vMatrix,\n pMatrix: view.projectionMatrix\n };\n });\n }\n\n private _setSession(session: XRSession, refSpace: XRReferenceSpace) {\n this._xrSession = session;\n this._xrRefSpace = refSpace;\n\n session.addEventListener(BROWSER.EVENTS.XR_END, this._onSessionEnd);\n }\n\n private _onSessionEnd = () => {\n this.exit();\n this.trigger(EVENTS.VR_END);\n }\n}\n\nexport default XRManager;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { vec3 } from \"gl-matrix\";\n\n/**\n * Hotspot data\n * @ko 핫스팟 데이터\n * @since 4.0.0\n */\nclass Hotspot {\n /**\n * HTMLElement of the hotspot\n * @ko 핫스팟의 HTMLElement\n * @since 4.0.0\n */\n public readonly element: HTMLElement;\n /**\n * Position to render hotspot\n * @ko 핫스팟을 렌더링할 위치\n * @since 4.0.0\n */\n public readonly position: vec3;\n\n public constructor(element: HTMLElement, position: vec3) {\n this.element = element;\n this.position = position;\n }\n}\n\nexport default Hotspot;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { vec2, vec3 } from \"gl-matrix\";\nimport Hotspot from \"./Hotspot\";\nimport Camera from \"../core/Camera\";\nimport WebGLRenderer from \"../core/WebGLRenderer\";\nimport View360Error from \"../core/View360Error\";\nimport { getNullableElement } from \"../utils\";\nimport ERROR from \"../const/error\";\nimport { DEFAULT_CLASS } from \"../const/external\";\nimport { DEG_TO_RAD } from \"../const/internal\";\n\n/**\n * Options for {@link HotspotRenderer}\n * @ko {@link HotspotRenderer}용 옵션들\n * @since 4.0.0\n */\nexport interface HotspotOptions {\n /**\n * Apply scale for hotspots, makes their size sync with background panorama image.\n * @ko 핫스팟에 스케일을 적용해서 배경 파노라마 이미지의 크기 변화와 동일하게 크기를 조절합니다.\n * @since 4.0.0\n */\n zoom: boolean;\n}\n\n/**\n * Hotspot renderer\n * @ko Hotspot 렌더러\n * @since 4.0.0\n */\nclass HotspotRenderer {\n // Options\n private _zoom: HotspotOptions[\"zoom\"];\n\n // Internal properties\n private _containerEl: HTMLElement | null;\n private _renderer: WebGLRenderer;\n private _hotspots: Hotspot[];\n\n /**\n * Create new instance\n * @ko 새 인스턴스를 생성합니다.\n * @param rootEl - Container element for hotspots {@ko 핫스팟들의 컨테이너 엘리먼트}\n * @param renderer - instance of WebGLRenderer {@ko WebGLRenderer의 인스턴스}\n * @param options - Hotspot options {@ko Hotspot 옵션들 }\n */\n public constructor(rootEl: HTMLElement, renderer: WebGLRenderer, {\n zoom = false\n }: Partial) {\n this._containerEl = getNullableElement(`.${DEFAULT_CLASS.HOTSPOT_CONTAINER}`, rootEl);\n this._renderer = renderer;\n this._hotspots = [];\n\n this._zoom = zoom;\n }\n\n /**\n * Refresh hotspots by collecting hotspot elements from current hotspot root element\n * @ko 현재 핫스팟 루트 엘리먼트 내에서 핫스팟 엘리먼트들을 수집하여 갱신합니다.\n * @throws {ERROR_CODES.INSUFFICIENT_ARGS} if data-position doesn't include all x, y, z values {@ko data-position이 x, y, z좌표를 전부 포함하고 있지 않을 때}\n */\n public refresh() {\n const container = this._containerEl;\n if (!container) return;\n\n const hotspotEls = [].slice.apply(container.querySelectorAll(`.${DEFAULT_CLASS.HOTSPOT}`)) as HTMLElement[];\n this._hotspots = hotspotEls.map(el => this._parseHotspot(el));\n }\n\n /**\n * Render hotspots\n * @ko 핫스팟들을 렌더링합니다.\n * @param camera - Instance of Camera {@ko Camera의 인스턴스}\n */\n public render(camera: Camera) {\n const hotspots = this._hotspots;\n const halfWidth = this._renderer.width * 0.5;\n const halfHeight = this._renderer.height * 0.5;\n const zoom = camera.zoom;\n const centerTransform = \"translate(-50%, -50%)\";\n const zoomTransform = this._zoom ? `scale(${zoom})` : \"\";\n\n hotspots.forEach(hotspot => {\n const position = hotspot.position;\n const relPos = vec3.create();\n\n vec3.copy(relPos, position);\n vec3.transformMat4(relPos, relPos, camera.viewMatrix);\n vec3.transformMat4(relPos, relPos, camera.projectionMatrix);\n\n if (relPos[2] > 1 || relPos[2] < 0) {\n hotspot.element.classList.remove(DEFAULT_CLASS.HOTSPOT_VISIBLE);\n return;\n }\n\n const screenPos = vec2.fromValues(\n relPos[0] * halfWidth + halfWidth,\n -relPos[1] * halfHeight + halfHeight\n );\n\n hotspot.element.classList.add(DEFAULT_CLASS.HOTSPOT_VISIBLE);\n hotspot.element.style.transform = [\n centerTransform,\n `translate(${screenPos[0]}px, ${screenPos[1]}px)`,\n zoomTransform\n ].join(\" \");\n });\n }\n\n private _parseHotspot(element: HTMLElement): Hotspot {\n const yawStr = element.dataset.yaw;\n const pitchStr = element.dataset.pitch;\n const positionStr = element.dataset.position;\n\n if (yawStr || pitchStr) {\n const yaw = yawStr ? parseFloat(yawStr) : 0;\n const pitch = pitchStr ? parseFloat(pitchStr) : 0;\n\n const position = this._yawPitchToVec3(yaw, pitch);\n\n return new Hotspot(element, position);\n } else if (positionStr) {\n const pos: number[] = positionStr.split(\" \").map(val => parseFloat(val));\n if (pos.length < 3) {\n throw new View360Error(ERROR.MESSAGES.INSUFFICIENT_ARGS(positionStr, \"hotspot attribute \\\"data-position\\\"\"), ERROR.CODES.INSUFFICIENT_ARGS);\n }\n\n return new Hotspot(element, vec3.fromValues(pos[0], pos[1], pos[2]));\n } else {\n // Place hotspot at yaw: 0, pitch: 0\n const defaultPos = vec3.fromValues(0, 0, -1);\n\n return new Hotspot(element, defaultPos);\n }\n }\n\n private _yawPitchToVec3(yaw: number, pitch: number) {\n const yawRad = yaw * DEG_TO_RAD;\n const pitchRad = pitch * DEG_TO_RAD;\n const position = vec3.create();\n\n position[1] = Math.sin(pitchRad);\n position[2] = Math.cos(pitchRad);\n\n position[0] = position[2] * Math.sin(-yawRad);\n position[2] = -position[2] * Math.cos(-yawRad);\n\n return position;\n }\n}\n\nexport default HotspotRenderer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"../geometry/Geometry\";\nimport { VAO } from \"../type/internal\";\n\n/**\n * @hidden\n */\nclass VertexArrayObject {\n public readonly obj: VAO | null;\n public readonly geometry: Geometry;\n public readonly buffers: {\n indicies: WebGLBuffer;\n position: WebGLBuffer;\n uv: WebGLBuffer;\n }\n\n public get count() { return this.geometry.indicies.count; }\n\n constructor(obj: VAO | null, geometry: Geometry, buffers: VertexArrayObject[\"buffers\"]) {\n this.obj = obj;\n this.geometry = geometry;\n this.buffers = buffers;\n }\n}\n\nexport default VertexArrayObject;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4 } from \"gl-matrix\";\nimport Uniform from \"../uniform/Uniform\";\nimport Camera from \"./Camera\";\nimport Object3D from \"./Object3D\";\nimport ShaderProgram from \"./ShaderProgram\";\nimport View360Error from \"./View360Error\";\nimport VertexArrayObject from \"./VertexArrayObject\";\nimport VertexData from \"./VertexData\";\nimport Texture from \"../texture/Texture\";\nimport Geometry from \"../geometry/Geometry\";\nimport * as BROWSER from \"../const/browser\";\nimport ERROR from \"../const/error\";\nimport { DEFAULT_CLASS } from \"../const/external\";\nimport { UniformLocations } from \"../type/internal\";\n\n/**\n * @hidden\n */\nclass WebGLContext {\n private _canvas: HTMLCanvasElement;\n private _gl: WebGLRenderingContext | WebGL2RenderingContext;\n private _contextLost: boolean;\n private _maxTextureSize: number;\n private _isWebGL2: boolean;\n private _debug: boolean;\n private _extensions: {\n vao: OES_vertex_array_object | null;\n loseContext: WEBGL_lose_context | null;\n };\n\n public get canvas() { return this._canvas; }\n public get maxTextureSize() { return this._maxTextureSize; }\n public get isWebGL2() { return this._isWebGL2; }\n public get supportVAO() { return this._isWebGL2 || !!this._extensions.vao; }\n public get lost() { return this._contextLost; }\n public get debug() { return this._debug; }\n\n public constructor(canvas: HTMLCanvasElement, debug: boolean) {\n this._canvas = canvas;\n this._contextLost = false;\n this._debug = debug;\n this._extensions = {\n vao: null,\n loseContext: null\n };\n }\n\n public init() {\n const canvas = this._canvas;\n\n const { gl, isWebGL2 } = this._getContext(canvas);\n\n this._gl = gl;\n this._maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n this._isWebGL2 = isWebGL2;\n\n if (!this._isWebGL2) {\n this._extensions.vao = gl.getExtension(\"OES_vertex_array_object\");\n }\n\n this._extensions.loseContext = gl.getExtension(\"WEBGL_lose_context\");\n\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_LOST, this._onContextLost);\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_RESTORED, this._onContextRestore);\n\n // gl.enable(gl.DEPTH_TEST);\n }\n\n public destroy() {\n const gl = this._gl;\n const canvas = this._canvas;\n\n if (gl) {\n // gl is not defined when destroy is called before init\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n }\n\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_LOST, this._onContextLost);\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_RESTORED, this._onContextRestore);\n }\n\n public forceLoseContext() {\n const extension = this._extensions.loseContext;\n\n if (!extension) return;\n\n extension.loseContext();\n }\n\n public forceRestoreContext() {\n const extension = this._extensions.loseContext;\n\n if (!extension) return;\n\n extension.restoreContext();\n }\n\n public clear() {\n const gl = this._gl;\n\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n\n public resize() {\n const gl = this._gl;\n\n gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n }\n\n public viewport(x: number, y: number, width: number, height: number) {\n const gl = this._gl;\n\n gl.viewport(x, y, width, height);\n }\n\n public createVAO(geometry: Geometry, shaderProgram: ShaderProgram) {\n const nativeVAO = this._createNativeVAO();\n\n const vao = new VertexArrayObject(nativeVAO, geometry, {\n indicies: this._createBuffer(),\n position: this._createBuffer(),\n uv: this._createBuffer()\n });\n\n if (nativeVAO) {\n this._bindNativeVAO(nativeVAO);\n this._supplyGeometryData(vao, shaderProgram);\n this._bindNativeVAO(null);\n this._unbindBuffers();\n }\n\n return vao;\n }\n\n public draw(vao: VertexArrayObject, shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n if (vao.obj) {\n this._bindNativeVAO(vao.obj);\n } else {\n this._supplyGeometryData(vao, shaderProgram);\n }\n\n gl.drawElements(gl.TRIANGLES, vao.count, gl.UNSIGNED_SHORT, 0);\n\n if (vao.obj) {\n this._bindNativeVAO(null);\n } else {\n this._unbindBuffers();\n }\n }\n\n public releaseVAO(vao: VertexArrayObject) {\n if (vao.obj) {\n this._deleteNativeVAO(vao.obj);\n }\n\n this._deleteBuffer(vao.buffers.indicies);\n this._deleteBuffer(vao.buffers.position);\n this._deleteBuffer(vao.buffers.uv);\n }\n\n public getUniformLocations>(program: WebGLProgram, uniforms: T): UniformLocations {\n const gl = this._gl;\n\n const uniformLocations = Object.keys(uniforms).reduce((locations, key) => {\n locations[key as keyof T] = gl.getUniformLocation(program, key)!;\n\n return locations;\n }, {} as UniformLocations);\n\n return {\n ...this._getCommonUniformLocations(program),\n ...uniformLocations\n };\n }\n\n public updateCommonUniforms(entity: Object3D, camera: Camera, shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniformLocations = shaderProgram.uniformLocations;\n\n // We're using \"matrix\"(=local matrix) here for efficiency\n // As projection doesn't require world matrix, as it doesn't have any parent or child\n const matrix = entity.matrix;\n const mvMatrix = mat4.create();\n mat4.multiply(mvMatrix, camera.viewMatrix, matrix);\n\n gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix);\n gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, camera.projectionMatrix);\n }\n\n public updateVRUniforms(shaderProgram: ShaderProgram, mvMatrix: mat4, pMatrix: mat4, eyeIndex: number) {\n const gl = this._gl;\n\n const uniformLocations = shaderProgram.uniformLocations;\n\n gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix);\n gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, pMatrix);\n\n if (uniformLocations.uEye) {\n gl.uniform1f(uniformLocations.uEye, eyeIndex);\n }\n }\n\n public updateUniforms(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniforms = shaderProgram.uniforms;\n const uniformLocations = shaderProgram.uniformLocations;\n\n for (const key in uniforms) {\n const uniform = uniforms[key];\n const location = uniformLocations[key];\n\n if (!uniform) continue;\n\n if (uniform.needsUpdate) {\n uniform.update(gl, location, this._isWebGL2);\n }\n }\n }\n\n public releaseShaderResources(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniforms = shaderProgram.uniforms;\n\n for (const key in uniforms) {\n const uniform = uniforms[key];\n\n if (!uniform) continue;\n\n if (uniform.needsUpdate) {\n uniform.destroy(gl);\n }\n }\n\n gl.deleteProgram(shaderProgram.program);\n }\n\n public useProgram(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n gl.useProgram(shaderProgram.program);\n }\n\n public createProgram(vertexShader: string, fragmentShader: string) {\n const gl = this._gl;\n const program = gl.createProgram()!;\n\n const vs = this._compileShader(gl.VERTEX_SHADER, vertexShader);\n const fs = this._compileShader(gl.FRAGMENT_SHADER, fragmentShader);\n\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.bindAttribLocation(program, 0, \"position\");\n gl.bindAttribLocation(program, 1, \"uv\");\n gl.linkProgram(program);\n\n if (this._debug && !gl.getProgramParameter(program, gl.LINK_STATUS)) {\n let shaderLog: string | null = null;\n\n if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {\n shaderLog = gl.getShaderInfoLog(vs);\n } else if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {\n shaderLog = gl.getShaderInfoLog(fs);\n }\n\n throw new View360Error(ERROR.MESSAGES.FAILED_LINKING_PROGRAM(gl.getProgramInfoLog(program), shaderLog), ERROR.CODES.FAILED_LINKING_PROGRAM);\n }\n\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n\n return program;\n }\n\n public createWebGLTexture(texData: Texture): WebGLTexture {\n const gl = this._gl;\n const texture = gl.createTexture()!;\n\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texData.wrapS);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texData.wrapT);\n\n if (!texData.isVideo() && this._isWebGL2) {\n const gl2 = gl as WebGL2RenderingContext;\n\n gl2.texStorage2D(gl2.TEXTURE_2D, 1, gl2.RGBA8, texData.width, texData.height);\n }\n\n return texture;\n }\n\n public createWebGLCubeTexture(texData: Texture, size: number): WebGLTexture {\n const gl = this._gl;\n const texture = gl.createTexture()!;\n\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, texData.wrapS);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, texData.wrapT);\n\n if (this._isWebGL2) {\n const gl2 = gl as WebGL2RenderingContext;\n\n gl2.texStorage2D(gl2.TEXTURE_CUBE_MAP, 1, gl2.RGBA8, size, size);\n }\n\n return texture;\n }\n\n public async makeXRCompatible() {\n const gl = this._gl;\n const attributes = gl.getContextAttributes();\n\n if (attributes && attributes.xrCompatible !== true) {\n await gl.makeXRCompatible();\n }\n }\n\n public bindXRLayer(session: XRSession) {\n const gl = this._gl;\n const xrLayer = new XRWebGLLayer(session, gl);\n session.updateRenderState({ baseLayer: xrLayer });\n }\n\n public bindXRFrame(frame: XRFrame) {\n const gl = this._gl;\n const session = frame.session;\n const baseLayer = session.renderState.baseLayer!;\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer);\n }\n\n public useDefaultFrameBuffer() {\n const gl = this._gl;\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n private _createBuffer(): WebGLBuffer {\n return this._gl.createBuffer()!;\n }\n\n private _deleteBuffer(buffer: WebGLBuffer) {\n return this._gl.deleteBuffer(buffer);\n }\n\n private _createNativeVAO() {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n return (gl as WebGL2RenderingContext).createVertexArray()!;\n } else {\n const ext = this._extensions.vao;\n\n return ext?.createVertexArrayOES() || null;\n }\n }\n\n private _bindNativeVAO(vao: WebGLVertexArrayObject | null) {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n (gl as WebGL2RenderingContext).bindVertexArray(vao);\n } else {\n const ext = this._extensions.vao;\n\n ext?.bindVertexArrayOES(vao);\n }\n }\n\n private _deleteNativeVAO(vao: WebGLVertexArrayObject | null) {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n (gl as WebGL2RenderingContext).deleteVertexArray(vao);\n } else {\n const ext = this._extensions.vao;\n\n ext?.deleteVertexArrayOES(vao);\n }\n }\n\n private _supplyGeometryData(vao: VertexArrayObject, shaderProgram: ShaderProgram) {\n const geometry = vao.geometry;\n\n this._supplyIndiciesData(geometry.indicies, vao.buffers.indicies);\n this._supplyAttributeData(geometry.vertices, shaderProgram.program, \"position\", vao.buffers.position);\n this._supplyAttributeData(geometry.uvs, shaderProgram.program, \"uv\", vao.buffers.uv);\n }\n\n private _unbindBuffers() {\n const gl = this._gl;\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n }\n\n private _supplyIndiciesData(indicies: VertexData, buffer: WebGLBuffer) {\n const gl = this._gl;\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicies.data, gl.STATIC_DRAW);\n }\n\n private _supplyAttributeData(attribute: VertexData, program: WebGLProgram, name: string, buffer: WebGLBuffer) {\n const gl = this._gl;\n const attribLocation = gl.getAttribLocation(program, name);\n\n // Attribute not used\n if (attribLocation < 0) return;\n\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ARRAY_BUFFER, attribute.data, gl.STATIC_DRAW);\n gl.vertexAttribPointer(attribLocation, attribute.itemSize, gl.FLOAT, false, 0, 0);\n gl.enableVertexAttribArray(attribLocation);\n }\n\n private _compileShader(type: number, src: string) {\n const gl = this._gl;\n const shader = gl.createShader(type)!;\n\n gl.shaderSource(shader, src);\n gl.compileShader(shader);\n\n return shader;\n }\n\n private _getCommonUniformLocations(program: WebGLProgram) {\n const gl = this._gl;\n\n return {\n uMVMatrix: gl.getUniformLocation(program, \"uMVMatrix\")!,\n uPMatrix: gl.getUniformLocation(program, \"uPMatrix\")!\n };\n }\n\n private _getContext(canvas: HTMLCanvasElement): {\n gl: WebGLRenderingContext | WebGL2RenderingContext;\n isWebGL2: boolean;\n } {\n const webglIdentifiers = [\"webgl2\", \"webgl\", \"experimental-webgl\", \"webkit-3d\", \"moz-webgl\"];\n let context: WebGLRenderingContext | null = null;\n let isWebGL2 = false;\n const contextAttributes = {\n preserveDrawingBuffer: false,\n antialias: false\n };\n\n const onWebglContextCreationError = e => e.statusMessage;\n\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_CREATE_ERROR, onWebglContextCreationError);\n\n for (const identifier of webglIdentifiers) {\n try {\n context = canvas.getContext(identifier, contextAttributes) as WebGLRenderingContext;\n isWebGL2 = identifier === \"webgl2\";\n } catch (t) {} // eslint-disable-line no-empty\n if (context) {\n break;\n }\n }\n\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_CREATE_ERROR, onWebglContextCreationError);\n\n if (!context) {\n throw new View360Error(ERROR.MESSAGES.WEBGL_NOT_SUPPORTED, ERROR.CODES.WEBGL_NOT_SUPPORTED);\n }\n\n return {\n gl: context,\n isWebGL2\n };\n }\n\n private _onContextLost = () => {\n const canvas = this._canvas;\n canvas.classList.add(DEFAULT_CLASS.CTX_LOST);\n this._contextLost = true;\n };\n\n private _onContextRestore = () => {\n const canvas = this._canvas;\n canvas.classList.remove(DEFAULT_CLASS.CTX_LOST);\n this._contextLost = false;\n };\n}\n\nexport default WebGLContext;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4 } from \"gl-matrix\";\nimport Camera from \"./Camera\";\nimport Projection from \"../projection/Projection\";\nimport WebGLContext from \"./WebGLContext\";\nimport XRManager from \"./XRManager\";\n\n/**\n * Projection renderer, based on WebGL\n * @ko WebGL 기반의 프로젝션 렌더러\n * @since 4.0.0\n */\nclass WebGLRenderer {\n private _canvas: HTMLCanvasElement;\n private _elementSize: { x: number, y: number };\n private _pixelRatio: number;\n\n public readonly ctx: WebGLContext;\n\n /**\n * Canvas element\n * @ko 캔버스 엘리먼트\n * @since 4.0.0\n */\n public get canvas() { return this._canvas; }\n /**\n * Canvas's width (`devicePixelRatio` is not applied)\n * @ko 캔버스의 보이는 너비 (`devicePixelRatio`가 적용되지 않은)\n * @since 4.0.0\n */\n public get width() { return this._elementSize.x; }\n /**\n * Canvas's height (`devicePixelRatio` is not applied)\n * @ko 캔버스의 높이 (`devicePixelRatio`가 적용되지 않은)\n * @since 4.0.0\n */\n public get height() { return this._elementSize.y; }\n /**\n * Current `devicePixelRatio` value.\n * @ko 현재 `devicePixelRatio` 값.\n * @since 4.0.0\n * @example\n * ```js\n * cosnt renderingWidth = view360.renderer.width * view360.renderer.pixelRatio;\n * ```\n */\n public get pixelRatio() { return this._pixelRatio; }\n /**\n * Width / height ratio (= width / height)\n * @ko 너비 / 높이의 비율 (= width / height)\n * @since 4.0.0\n * @example\n * ```js\n * const aspect = view360.renderer.width / view360.renderer.pixelRatio;\n * assert(aspect === view360.renderer.aspect);\n * ```\n */\n public get aspect() { return this._elementSize.x / this._elementSize.y; }\n\n /**\n * Create new instance\n * @ko 새 인스턴스를 생성합니다.\n * @param canvas - Canvas element {@ko 캔버스 엘리먼트}\n * @param debug - Whether to enable WebGL debugging {@ko WebGL debug 활성화 여부 }\n */\n public constructor(canvas: HTMLCanvasElement, debug: boolean) {\n this._canvas = canvas;\n this._elementSize = { x: 0, y: 0 };\n this._pixelRatio = 1;\n this.ctx = new WebGLContext(canvas, debug);\n }\n\n /**\n * Destroy instance and release all resources.\n * @ko 인스턴스를 제거하고 사용된 리소스를 전부 해제합니다.\n * @since 4.0.0\n */\n public destroy() {\n const canvas = this._canvas;\n\n this.ctx.destroy();\n canvas.width = 1;\n canvas.height = 1;\n }\n\n /**\n * Resize canvas and renew inner size cache.\n * @ko 캔버스의 크기를 재계산해서 내부의 사이즈 캐시값을 갱신합니다.\n * @since 4.0.0\n */\n public resize() {\n const canvas = this._canvas;\n const canvasSize = this._elementSize;\n const devicePixelRatio = window.devicePixelRatio;\n\n canvasSize.x = canvas.clientWidth;\n canvasSize.y = canvas.clientHeight;\n\n canvas.width = canvasSize.x * devicePixelRatio;\n canvas.height = canvasSize.y * devicePixelRatio;\n\n this._pixelRatio = devicePixelRatio;\n this.ctx.resize();\n }\n\n /**\n * Render projection\n * @ko 프로젝션을 렌더링합니다.\n * @param projection - Projection to render {@ko 렌더링할 프로젝션}\n * @param cameraa - Camera instance {@ko 카메라의 인스턴스}\n * @since 4.0.0\n */\n public render(projection: Projection, camera: Camera) {\n const ctx = this.ctx;\n const mesh = projection.getMesh();\n if (ctx.lost || !mesh) return;\n\n ctx.clear();\n ctx.useProgram(mesh.program);\n ctx.updateCommonUniforms(mesh, camera, mesh.program);\n projection.update(camera);\n ctx.updateUniforms(mesh.program);\n ctx.draw(mesh.vao, mesh.program);\n }\n\n /**\n * Render VR frame, only used for rendering frames inside VR sessions.\n * @ko VR 프레임을 렌더링합니다. VR 세션 진입 도중에만 사용됩니다.\n * @internal\n * @param projection - Projection to render {@ko 렌더링할 프로젝션}\n * @param vr - Instance of XRManager {@ko XRManager의 인스턴스}\n * @param frame - VR frame {@ko VR 프레임}\n * @since 4.0.0\n */\n public renderVR(projection: Projection, vr: XRManager, frame: XRFrame) {\n const ctx = this.ctx;\n const mesh = projection.getMesh();\n const eyeParams = vr.getEyeParams(frame);\n\n if (!eyeParams || !mesh) return;\n\n ctx.bindXRFrame(frame);\n ctx.useProgram(mesh.program);\n ctx.updateUniforms(mesh.program);\n\n eyeParams.forEach((eye, eyeIndex) => {\n const viewport = eye.viewport;\n // We're using \"mesh.matrix\"(=local matrix) here for efficiency\n // As projection doesn't require world matrix, as it doesn't have any parent or child\n const mvMatrix = mat4.multiply(mat4.create(), eye.vMatrix, mesh.matrix);\n\n ctx.viewport(viewport.x, viewport.y, viewport.width, viewport.height);\n ctx.updateVRUniforms(mesh.program, mvMatrix, eye.pMatrix, eyeIndex);\n ctx.draw(mesh.vao, mesh.program);\n });\n }\n}\n\nexport default WebGLRenderer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport Camera, { CameraOptions } from \"./core/Camera\";\nimport PanoControl, { PanoControlOptions } from \"./control/PanoControl\";\nimport TextureLoader from \"./core/TextureLoader\";\nimport FrameAnimator from \"./core/FrameAnimator\";\nimport AutoResizer from \"./core/AutoResizer\";\nimport Autoplay, { AutoplayOptions } from \"./core/Autoplay\";\nimport XRManager from \"./core/XRManager\";\nimport View360Error from \"./core/View360Error\";\nimport Projection from \"./projection/Projection\";\nimport HotspotRenderer, { HotspotOptions } from \"./hotspot/HotspotRenderer\";\nimport WebGLRenderer from \"./core/WebGLRenderer\";\nimport Texture from \"./texture/Texture\";\nimport View360Plugin from \"./plugin/View360Plugin\";\nimport ERROR from \"./const/error\";\nimport { CONTROL_EVENTS } from \"./const/internal\";\nimport { DEFAULT_CLASS, EVENTS } from \"./const/external\";\nimport { findCanvas, getElement } from \"./utils\";\nimport * as EVENT_TYPES from \"./type/events\";\nimport { EventParams } from \"./type/utils\";\n\n/**\n * Events that {@link View360} can trigger\n * @ko {@link View360}가 트리거할 수 있는 이벤트들\n * @see [Detailed Example](/docs/events/ready)\n * @since 4.0.0\n */\nexport interface View360Events {\n [EVENTS.READY]: EVENT_TYPES.ReadyEvent;\n [EVENTS.LOAD_START]: EVENT_TYPES.LoadStartEvent;\n [EVENTS.LOAD]: EVENT_TYPES.LoadEvent;\n [EVENTS.PROJECTION_CHANGE]: EVENT_TYPES.ProjectionChangeEvent;\n [EVENTS.RESIZE]: EVENT_TYPES.ResizeEvent;\n [EVENTS.BEFORE_RENDER]: EVENT_TYPES.BeforeRenderEvent;\n [EVENTS.RENDER]: EVENT_TYPES.RenderEvent;\n [EVENTS.INPUT_START]: EVENT_TYPES.InputStartEvent;\n [EVENTS.INPUT_END]: EVENT_TYPES.InputEndEvent;\n [EVENTS.VIEW_CHANGE]: EVENT_TYPES.ViewChangeEvent;\n [EVENTS.STATIC_CLICK]: EVENT_TYPES.StaticClickEvent;\n [EVENTS.VR_START]: EVENT_TYPES.VRStartEvent;\n [EVENTS.VR_END]: EVENT_TYPES.VREndEvent;\n}\n\n/**\n * Options for {@link View360}\n * @ko {@link View360}용 옵션들\n * @see [Detailed Example](/docs/options)\n * @since 4.0.0\n */\nexport interface View360Options extends CameraOptions, PanoControlOptions {\n projection: Projection | null;\n hotspot: Partial;\n autoplay: boolean | Partial;\n autoInit: boolean;\n autoResize: boolean;\n canvasSelector: string;\n useResizeObserver: boolean;\n tabIndex: number | null;\n on: Partial<{ [key in keyof View360Events]: (evt: View360Events[key]) => any }>;\n plugins: View360Plugin[];\n maxDeltaTime: number;\n debug: boolean;\n}\n\n/**\n * Panorama 360 image viewer\n * @ko 파노라마 360 이미지 뷰어\n * @since 4.0.0\n * @see View360Options\n * @see View360Events\n */\nclass View360 extends Component {\n /**\n * Current version string of the View360\n * @ko View360의 현재 버젼 문자열\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // If the installed version of the View360 is v4.0.0, View360.VERSION is equal to \"4.0.0\"\n * console.log(View360.VERSION) // 4.0.0\n * ```\n */\n public static readonly VERSION = \"#__VERSION__#\";\n\n private _rootEl: HTMLElement;\n private _renderer: WebGLRenderer;\n private _camera: Camera;\n private _control: PanoControl;\n private _animator: FrameAnimator;\n private _autoplay: Autoplay;\n private _hotspot: HotspotRenderer;\n private _projection: Projection | null;\n private _autoResizer: AutoResizer;\n private _vr: XRManager;\n private _plugins: View360Plugin[];\n private _initialized: boolean;\n\n private _autoInit: View360Options[\"autoInit\"];\n private _autoResize: View360Options[\"autoResize\"];\n private _canvasSelector: View360Options[\"canvasSelector\"];\n private _useResizeObserver: View360Options[\"useResizeObserver\"];\n private _tabIndex: View360Options[\"tabIndex\"];\n private _debug: View360Options[\"debug\"];\n\n /**\n * Root element (`.view360-container`)\n * @ko 루트 엘리먼트 (`.view360-container`)\n * @since 4.0.0\n * @readonly\n * @example\n * ```html\n *
\n * \n *
\n * ```\n * ```ts\n * import View360 from \"@egjs/view360\";\n *\n * const viewer = new View360(\"#viewer\");\n * console.log(viewer.rootEl); // Element with id \"viewer\"\n * ```\n */\n public get rootEl() { return this._rootEl; }\n /**\n * Projection renderer.\n * @ko 프로젝션 렌더러.\n * @since 4.0.0\n * @readonly\n */\n public get renderer() { return this._renderer; }\n /**\n * Projection camera.\n * @ko 프로젝션 카메라.\n * @since 4.0.0\n * @readonly\n */\n public get camera() { return this._camera; }\n /**\n * Rotate/Zoom Controller.\n * @ko 회전/줌 컨트롤러.\n * @since 4.0.0\n * @readonly\n */\n public get control() { return this._control; }\n /**\n * WebXR-based VR manager.\n * @ko WebXR 기반의 VR 기능 매니저 인스턴스.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // Example: Enter VR\n * // This must be called on user interaction, else will be rejected.\n * viewer.vr.enter();\n * ```\n */\n public get vr() { return this._vr; }\n /**\n * Hotspot renderer.\n * You can also change options of {@link View360Options#hotspot} with this.\n * @ko 핫스팟 렌더러 인스턴스.\n * {@link View360Options#hotspot} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get hotspot() { return this._hotspot; }\n /**\n * An array of plugins added.\n * @ko 추가된 플러그인의 배열\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * plugins: [new ControlBar()]\n * });\n *\n * console.log(viewer.plugins); // [ControlBar]\n *\n * viewer.addPlugins(new LoadingSpinner()) // [ControlBar, LoadingSpinner];\n * ```\n */\n public get plugins() { return this._plugins; }\n /**\n * A instance of {@link Projection} that currently enabled. `null` if not initialized yet.\n * You should call {@link View360#load} to change panorama src or projection type.\n * @ko 현재 사용중인 {@link Projection}의 인스턴스. 프로젝션을 활성화하지 않았을 경우 `null`입니다.\n * 파노라마 이미지 소스나 프로젝션 타입을 변경하려면 {@link View360#load}를 호출하면 됩니다.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360\n * ```\n */\n public get projection() { return this._projection; }\n public set projection(val: View360Options[\"projection\"]) {\n if (this._initialized && val) {\n this.load(val);\n } else {\n this._projection = val;\n }\n }\n /**\n * A boolean value whether {@link View360#init init()} is called before.\n * @ko {@link View360#init init()}이 호출되었는지 여부를 가리키는 값\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360(\"#el\", { autoInit: false });\n *\n * console.log(viewer.initialized); // false\n *\n * await viewer.init();\n *\n * console.log(viewer.initialized); // true\n * ```\n */\n public get initialized() { return this._initialized; }\n /**\n * Instance of the Autoplay manager.\n * You can also change {@link View360Options#autoplay} options with this.\n * @ko Autoplay 기능의 매니저 인스턴스.\n * 이 인스턴스를 통해 {@link View360Options#autoplay} 옵션을 변경하는 것도 가능합니다.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // Disable autoplay\n * viewer.autoplay.disable();\n * ```\n */\n public get autoplay() { return this._autoplay; }\n /**\n * When this value is `true` and {@link View360Options#projection} is set, {@link View360#init init()} will be called automatically when instance is created.\n * @ko 이 값이 `true`이고, {@link View360Options#projection}이 설정되었으면, 인스턴스 생성 시점에 자동으로 {@link View360#init init()}을 호출합니다.\n * @default true\n * @since 4.0.0\n * @example\n * ```ts\n * import View360, { EquirectProjection, EVENTS } from \"@egjs/view360\";\n *\n * // viewer.init() is called on instance creation\n * // But as `init` is asynchronous, you should wait for \"ready\" event if you want to do something after initialization.\n * const viewer = new View360(\"#el_id\", {\n * autoInit: true,\n * projection: new EquirectProjection({ src: \"SRC_TO_URL\" })\n * });\n *\n * console.log(viewer.initialized); // false, as `init` is asynchronous\n *\n * viewer.once(EVENTS.READY, () => {\n * console.log(viewer.initialized); // true\n * });\n * ```\n */\n public get autoInit() { return this._autoInit; }\n /**\n * When `true`, {@link View360#resize} is called when the canvas size is changed.\n * @ko `true`일 경우, 캔버스의 크기가 변경되었을 때 자동으로 {@link View360#resize}를 호출합니다.\n * @default true\n * @since 4.0.0\n * @see View360#useResizeObserver\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * autoResize: true\n * });\n *\n * // This can trigger `viewer.resize()` if the canvas size was not 400px\n * const canvas = viewer.renderer.canvas;\n * canvas.style.width = \"400px\";\n * ```\n */\n public get autoResize() { return this._autoResize; }\n /**\n * CSS selector for canvas element to render panorama image/video.\n * The canvas element should be placed inside the root element. (Dont' have to be direct child)\n * @ko 파노라마 이미지/비디오를 렌더링할 canvas 엘리먼트의 CSS 선택자\n * 캔버스 엘리먼트는 루트 엘리먼트 내부에 있어야합니다. 루트 엘리먼트의 직계 자식 엘리먼트(Direct child element)일 필요는 없습니다.\n * @default \"canvas\"\n * @since 4.0.0\n * @example\n * ```html\n *
\n * \n * \n * \n *
\n * ```\n *\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * canvasSelector: \"#canvas_to_select\"\n * });\n * ```\n */\n public get canvasSelector() { return this._canvasSelector; }\n /**\n * When `true`, it will use {@link ResizeObserver} API to detect canvas size change when {@link View360Options#autoResize} is enabled.\n * @ko `true`일 때 {@link View360Options#autoResize}가 활성화되었으면, 사용 가능한 환경에서 {@link ResizeObserver} API를 사용해서 캔버스 크기 변화를 추적합니다.\n * @default true\n * @since 4.0.0\n */\n public get useResizeObserver() { return this._useResizeObserver; }\n /**\n * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} attribute for the canvas element.\n * This is necessary for the keyboard controls.\n * By default, `0` will be assigned. `null` to disable.\n * @ko 캔버스 엘리먼트에 적용할 {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} 어트리뷰트의 값.\n * 이 값을 설정해야만 키보드 컨트롤을 사용 가능합니다.\n * 기본값으로 `0`이 설정됩니다. `null`로 지정하면 `tabindex`를 설정하지 않습니다.\n * @see RotateControlOptions#disableKeyboard\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * tabindex: 5\n * });\n * ```\n *\n * ```html\n * \n *
\n * \n *
\n * ```\n */\n public get tabIndex() { return this._tabIndex; }\n public set tabIndex(val: View360Options[\"tabIndex\"]) {\n const canvas = this._renderer.canvas;\n this._tabIndex = val;\n\n if (val != null) {\n canvas.tabIndex = val;\n } else {\n canvas.removeAttribute(\"tabindex\");\n }\n }\n /**\n * A maximum delta time between frames in seconds.\n * It can prevent camera or control changing too fast when frame being late.\n * @ko 프레임간 시간 차이의 최대값. (초 단위)\n * 퍼포먼스 등의 이유로 프레임 렌더링이 늦어졌을 때, 화면이 갑작스럽게 바뀌는 것을 막아줍니다.\n * @default 1 / 30\n * @since 4.0.0\n */\n public get maxDeltaTime() { return this._animator.maxDeltaTime; }\n public set maxDeltaTime(val: View360Options[\"maxDeltaTime\"]) { this._animator.maxDeltaTime = val; }\n /**\n * Enable WebGL debugging. Setting this to `true` can decrease performance.\n * This is used internally on developing View360.\n * @ko WebGL 디버깅을 활성화합니다. 이 값을 `true`로 할 경우 성능이 하락할 수 있습니다.\n * 이 옵션은 View360을 개발하기 위해 내부적으로 사용됩니다.\n * @default false\n */\n public get debug() { return this._debug; }\n public set debug(val: View360Options[\"debug\"]) { this._debug = val; }\n\n // Camera options\n /**\n * Initial yaw (y-axis rotation) value for camera. (in degrees, °)\n * As View360 uses right-handed coordinate system internally, camera will rotate counter-clockwise by this value.\n * @ko 카메라의 초기 yaw(y축 회전)값 (도 단위, °)\n * View360은 오른손 좌표계를 사용하기 때문에, 카메라가 해당 값만큼 시계 반대방향으로 회전합니다.\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialYaw: 30\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.yaw); // 30\n * });\n * ```\n */\n public get initialYaw() { return this._camera.initialYaw; }\n public set initialYaw(val: View360Options[\"initialYaw\"]) { this._camera.initialYaw = val; }\n /**\n * Initial pitch (x-axis rotation) value for camera. (in degrees, °)\n * As View360 uses right-handed coordinate system internally, positive value will make camera to look upside, while negative value will look down.\n * @ko 카메라의 초기 pitch(x축 회전)값 (도 단위, °)\n * View360은 오른손 좌표계를 사용하기 때문에, 양(+)의 값은 카메라가 위를 보게 하고, 음(-)의 값은 카메라가 아래를 보게 합니다.\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialPitch: 60\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.pitch); // 60\n * });\n * ```\n */\n public get initialPitch() { return this._camera.initialPitch; }\n public set initialPitch(val: View360Options[\"initialPitch\"]) { this._camera.initialPitch = val; }\n /**\n * Initial zoom value for camera.\n * Setting this value to `2` will enlarge panorama 200% by width.\n * @ko 카메라의 초기 줌 값.\n * 이 값을 `2`로 설정할 경우 파노라마 이미지를 가로 기준 200%만큼 확대합니다.\n * @default 1\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialZoom: 2\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.zoom); // 2\n * });\n * ```\n */\n public get initialZoom() { return this._camera.initialZoom; }\n public set initialZoom(val: View360Options[\"initialZoom\"]) { this._camera.initialZoom = val; }\n /**\n * Restrict yaw(y-axis rotation) range. (in degrees, °)\n * @ko yaw(y축 회전) 범위를 제한합니다. (도 단위, °)\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * yawRange: [-30, 30]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.yaw); // 0\n * viewer.camera.lookAt({ yaw: 60 });\n * console.log(viewer.camera.yaw); // 30\n * });\n * ```\n */\n public get yawRange() { return this._camera.yawRange; }\n public set yawRange(val: View360Options[\"yawRange\"]) {\n this._camera.yawRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Restrict pitch(x-axis rotation) range. (in degrees, °)\n * @ko pitch(x축 회전) 범위를 제한합니다. (도 단위, °)\n * @default null\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * pitchRange: [-45, 45]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.pitch); // 0\n * viewer.camera.lookAt({ pitch: 60 });\n * console.log(viewer.camera.pitch); // 45\n * });\n * ```\n */\n public get pitchRange() { return this._camera.pitchRange; }\n public set pitchRange(val: View360Options[\"pitchRange\"]) {\n this._camera.pitchRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Restrict camera zoom range.\n * If `null`, a default zoom range from `0.6` to `10` will be used.\n * @ko 카메라 줌 범위를 제한합니다.\n * `null`일 경우 기본값으로 `0.6`에서 `10`의 범위를 사용합니다.\n * @default null\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * zoomRange: [0.5, 4]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.zoom); // 1\n * viewer.camera.lookAt({ zoom: 6 });\n * console.log(viewer.camera.zoom); // 4\n * });\n * ```\n */\n public get zoomRange() { return this._camera.zoomRange; }\n public set zoomRange(val: View360Options[\"zoomRange\"]) {\n this._camera.zoomRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Camera's horizontal FOV(Field of View). (in degrees, °)\n * @ko 카메라의 수평 FOV(Field of View) 값. (도 단위, °)\n * @default 90\n * @since 4.0.0\n * @example\n * ```ts\n * // Init with fov: 120\n * const viewer = new View360(\"#el_id\", { fov: 120 });\n *\n * // Back to 90\n * viewer.fov = 90;\n * ```\n */\n public get fov() { return this._camera.fov; }\n public set fov(val: View360Options[\"fov\"]) {\n const camera = this._camera;\n const control = this._control;\n\n camera.fov = val;\n camera.updateMatrix();\n control.sync();\n }\n\n // Control options\n /**\n * A control for camera rotation.\n * You can also change options of {@link View360Options#rotate} with this.\n * @ko 카메라 회전을 담당하는 컨트롤.\n * {@link View360Options#rotate} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get rotate() { return this._control.rotate; }\n /**\n * A control for camera zoom.\n * You can also change options of {@link View360Options#zoom} with this.\n * @ko 카메라 줌을 담당하는 컨트롤.\n * {@link View360Options#zoom} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get zoom() { return this._control.zoom; }\n /**\n * A control for camera rotation with gyroscope input.\n * You can also change options of {@link View360Options#gyro} with this.\n * @ko 자이로스코프를 통한 카메라 회전을 담당하는 컨트롤.\n * {@link View360Options#gyro} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get gyro() { return this._control.gyro; }\n /**\n * Apply CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor} by current state of input when using mouse.\n * If `true`, this will add CSS style to canvas element. It'll apply `cursor: \"grab\"` by default and `cursor: \"grabbing\"` when holding the mouse button.\n * @ko 마우스 사용시 CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor}값을 자동으로 변경할지 여부.\n * `true`일 경우 기본 상태에서 `cursor: \"grab\"`을, 입력 도중에 `cursor: \"grabbing\"`을 캔버스에 적용합니다.\n * @default true\n * @since 4.0.0\n */\n public get useGrabCursor() { return this._control.useGrabCursor; }\n public set useGrabCursor(val: View360Options[\"useGrabCursor\"]) { this._control.useGrabCursor = val; }\n /**\n * Disable context menu which pops up on mouse right click.\n * @ko 마우스 우클릭시 표시되는 컨텍스트 메뉴를 비활성화합니다.\n * @default false\n * @since 4.0.0\n */\n public get disableContextMenu() { return this._control.disableContextMenu; }\n public set disableContextMenu(val: View360Options[\"disableContextMenu\"]) { this._control.disableContextMenu = val; }\n /**\n * If `true`, enables scroll on mobile(touch) devices on canvas.\n * :::caution\n * When this option is enabled, users must swipe horizontally first then vertically to change view up or down.\n * :::\n * @ko `true`로 설정할 경우, 모바일(터치) 환경의 캔버스 영역 내에서 스크롤을 가능하게 합니다.\n * :::caution\n * 이 값을 활성화할 경우, 사용자가 카메라 뷰를 위/아래로 바꾸기 위해서는 먼저 가로로 스와이프한 이후에 세로로 스와이프해야만 합니다.\n * :::\n * @since 4.0.0\n * @default true\n */\n public get scrollable() { return this._control.scrollable; }\n public set scrollable(val: View360Options[\"scrollable\"]) { this._control.scrollable = val; }\n /**\n * If `true`, enables scroll by mouse wheel on canvas.\n * :::caution\n * When this option is enabled, zoom by mouse wheel will be disabled.\n * :::\n * @ko `true`로 설정할 경우, 캔버스 영역 내에서 마우스 휠을 이용한 페이지 스크롤이 가능해집니다.\n * :::caution\n * 이 값을 활성화할 경우, 마우스 휠을 통한 줌이 불가능하게 됩니다.\n * :::\n * @since 4.0.0\n * @default false\n */\n public get wheelScrollable() { return this._control.wheelScrollable; }\n public set wheelScrollable(val: View360Options[\"wheelScrollable\"]) { this._control.wheelScrollable = val; }\n\n /**\n * Create new instance of View360\n * @ko View360의 새로운 인스턴스를 생성합니다\n * @param root - Root element(`.view360-container`) to mount View360\n * Can be either a CSS selector or HTMLElement.\n * {@ko View360을 마운트할 루트 엘리먼트, CSS 셀렉터나 HTMLElement를 지정 가능합니다.}\n * @param options - Options to apply\n * {@ko 적용할 옵션들}\n * @example\n * ```ts\n * import View360, { EquirectProjection } from \"@egjs/view360\";\n *\n * // Create new View360 instance\n * const viewer = new View360(\"#id-of-a-container\", {\n * projection: new EquirectProjection({\n * src: \"URL_TO_PANORAMA_IMAGE_OR_VIDEO\",\n * })\n * });\n * ```\n */\n public constructor(root: string | HTMLElement, {\n projection = null,\n initialYaw = 0,\n initialPitch = 0,\n initialZoom = 1,\n yawRange = null,\n pitchRange = null,\n zoomRange = null,\n fov = 90,\n useGrabCursor = true,\n disableContextMenu = false,\n rotate = true,\n zoom = true,\n gyro = false,\n scrollable = true,\n wheelScrollable = false,\n autoplay = false,\n hotspot = {},\n autoInit = true,\n autoResize = true,\n canvasSelector = \"canvas\",\n useResizeObserver = true,\n on = {},\n plugins = [],\n maxDeltaTime = 1 / 30,\n tabIndex = 0,\n debug = false\n }: Partial = {}) {\n super();\n\n this._rootEl = getElement(root);\n this._plugins = plugins;\n this._initialized = false;\n\n // Options\n this._autoInit = autoInit;\n this._autoResize = autoResize;\n this._canvasSelector = canvasSelector;\n this._useResizeObserver = useResizeObserver;\n this._tabIndex = tabIndex;\n this._debug = debug;\n\n // Core components\n const canvas = findCanvas(this._rootEl, canvasSelector);\n this._renderer = new WebGLRenderer(canvas, debug);\n this._camera = new Camera({\n initialYaw,\n initialPitch,\n initialZoom,\n fov,\n yawRange,\n pitchRange,\n zoomRange\n });\n this._control = new PanoControl(canvas, this._camera, {\n useGrabCursor,\n scrollable,\n wheelScrollable,\n disableContextMenu,\n rotate,\n zoom,\n gyro\n });\n this._animator = new FrameAnimator(maxDeltaTime);\n this._autoplay = new Autoplay(this, canvas, autoplay);\n this._projection = projection;\n this._autoResizer = new AutoResizer(useResizeObserver, () => this.resize());\n this._vr = new XRManager(this._renderer.ctx);\n this._hotspot = new HotspotRenderer(this._rootEl, this._renderer, hotspot);\n\n this._addEventHandlers(on);\n\n if (projection && autoInit) {\n this.init();\n }\n }\n\n /**\n * Destroy instance and release all resources.\n * @ko 인스턴스를 제거하고 모든 리소스를 해제합니다.\n * @since 4.0.0\n */\n public destroy() {\n this._camera.destroy();\n this._animator.stop();\n this._renderer.destroy();\n this._control.destroy();\n this._autoResizer.disable();\n\n if (this._projection) {\n this._projection.releaseAllResources(this._renderer.ctx);\n this._projection = null;\n }\n\n this._plugins.forEach(plugin => plugin.destroy(this));\n\n this._initialized = false;\n }\n\n /**\n * Initialize inner components and load projection src.\n * @ko 내부 컴포넌트들을 초기화하고 프로젝션 소스를 로드합니다.\n * @since 4.0.0\n */\n public async init() {\n if (!this._projection) {\n throw new View360Error(ERROR.MESSAGES.PROVIDE_PROJECTION_FIRST, ERROR.CODES.PROVIDE_PROJECTION_FIRST);\n }\n\n const renderer = this._renderer;\n const camera = this._camera;\n const control = this._control;\n const animator = this._animator;\n const hotspot = this._hotspot;\n const projection = this._projection;\n const canvas = renderer.canvas;\n\n this._bindComponentEvents();\n renderer.ctx.init();\n this._resizeComponents();\n camera.updateMatrix();\n\n if (this._autoResize) {\n this._autoResizer.enable(canvas);\n }\n\n if (!this._autoplay.enableBlocked) {\n this._autoplay.enable();\n }\n\n this._plugins.forEach(plugin => {\n plugin.init(this);\n });\n\n const texture = await this._loadTexture(projection);\n this._applyProjection(projection, texture, null);\n hotspot.refresh();\n animator.start(this._renderFrameOnDemand);\n await control.enable();\n\n if (this._tabIndex != null && !canvas.hasAttribute(\"tabIndex\")) {\n canvas.tabIndex = this._tabIndex;\n }\n\n this._initialized = true;\n this.renderFrame(0);\n\n this._emit(EVENTS.READY);\n }\n\n /**\n * Load new panorama image/video and display it.\n * This will {@link View360#init init()} View360 if it's not initialized yet.\n * @ko 새로운 파노라마 이미지 혹은 비디오를 로드하고 표시합니다.\n * 만약 View360이 아직 초기화되지 않았다면, {@link View360#init init()}을 호출합니다.\n * @param projection - Projection & video options for new source. {@ko 새로운 파노라마 이미지/비디오에 적용할 옵션들}\n * @returns `Promise` if load was successful. {@ko 프로젝션 로드에 성공했을 경우 `Promise`를 반환합니다. }\n * @since 4.0.0\n * @example\n * ```ts\n * // Change to video\n * viewer.load({\n * src: \"URL_TO_NEW_VIDEO\",\n * video: true\n * });\n * ```\n */\n public async load(projection: Projection): Promise {\n if (!projection) return false;\n\n if (this._initialized) {\n const texture = await this._loadTexture(projection);\n this._applyProjection(projection, texture, this._projection);\n this.renderFrame(0);\n } else {\n // Should update internal options before init\n this._projection = projection;\n this.init();\n }\n\n return true;\n }\n\n /**\n * Refresh component's size by current\n * @ko View360이 내부적으로 캐시하고 있는 엘리먼트 크기를 현재 크기로 갱신합니다.\n * @since 4.0.0\n */\n public resize() {\n if (!this._initialized) return;\n\n this._resizeComponents();\n\n // To prevent flickering, render immediately after resizing components\n this.renderFrame(0);\n\n const { width, height } = this._renderer;\n\n this._emit(EVENTS.RESIZE, {\n width,\n height\n });\n }\n\n /**\n * Add new plugins\n * @ko 새로운 플러그인을 추가합니다.\n * @param plugins Plugins to add {@ko 추가할 플러그인들}\n * @see View360Options#plugins\n * @since 4.0.0\n * @example\n * ```ts\n * // Add a single plugin\n * viewer.addPlugins(new ControlBar());\n *\n * // Add multiple plugins\n * viewer.addPlugins(new ControlBar(), new LoadingSpinner());\n * ```\n */\n public addPlugins(...plugins: View360Plugin[]) {\n if (this._initialized) {\n plugins.forEach(plugin => { plugin.init(this); });\n }\n\n this._plugins.push(...plugins);\n }\n\n /**\n * Remove plugins.\n * @ko 플러그인을 제거합니다.\n * @param plugins Plugins to remove {@ko 제거할 플러그인들}\n * @since 4.0.0\n * @example\n * ```ts\n * // Remove a single plugin\n * viewer.removePlugins(plugin1);\n *\n * // Remove multiple plugins\n * viewer.removePlugins(plugin2, plugin3);\n * ```\n */\n public removePlugins(...plugins: View360Plugin[]) {\n plugins.forEach(plugin => {\n const pluginIdx = this._plugins.indexOf(plugin);\n\n if (pluginIdx < 0) return;\n\n plugin.destroy(this);\n this._plugins.splice(pluginIdx, 1);\n });\n }\n\n /**\n * Render a single panorama image/video frame.\n * Rendering is performed automatically on demand, so you usually don't have to call this.\n * Call this when a frame is not renewed after changing options.\n * @ko 파노라마 이미지/비디오의 한 프레임을 렌더링합니다.\n * 프레임 갱신은 보통 필요한 때에만 자동적으로 이루어지기 때문에, 보통은 이 메소드를 호출할 필요는 없습니다.\n * 옵션 변경 이후에도 프레임 갱신이 이루어지지 않는다면, 이 메소드를 호출해주세요.\n * @param delta Delta time in milisec. {@ko 프레임간 시간 차이, 밀리초 단위}\n * @since 4.0.0\n */\n public renderFrame = (delta: number) => {\n const camera = this._camera;\n const renderer = this._renderer;\n const control = this._control;\n const hotspot = this._hotspot;\n const autoPlayer = this._autoplay;\n const projection = this._projection;\n\n if (!projection) return;\n\n this._emit(EVENTS.BEFORE_RENDER);\n\n if (autoPlayer.playing) {\n autoPlayer.update(delta);\n control.sync();\n }\n\n if (camera.animation) {\n camera.animation.update(delta);\n } else {\n control.update(delta);\n }\n\n renderer.render(projection, camera);\n hotspot.render(camera);\n\n if (camera.changed) {\n this._emit(EVENTS.VIEW_CHANGE, {\n yaw: camera.yaw,\n pitch: camera.pitch,\n zoom: camera.zoom,\n quaternion: [\n camera.quaternion[0],\n camera.quaternion[1],\n camera.quaternion[2],\n camera.quaternion[3]\n ]\n });\n }\n camera.onFrameRender();\n\n this._emit(EVENTS.RENDER);\n };\n\n private _emit(eventName: K, ...params: EventParams) {\n const evtParams = params ? params[0] : {};\n\n this.trigger(eventName as any, {\n type: eventName,\n target: this,\n ...evtParams\n });\n }\n\n private _renderFrameOnDemand = (delta: number) => {\n const camera = this._camera;\n const control = this._control;\n const autoplay = this._autoplay;\n const texture = this._projection?.getTexture();\n\n if (!this._initialized || !texture) return;\n if (\n !camera.animation\n && !control.animating\n && !autoplay.playing\n && !texture.isVideo()\n ) return;\n\n this.renderFrame(delta);\n };\n\n private _renderVRFrame = (_delta: number, frame: XRFrame) => {\n const vr = this._vr;\n const projection = this._projection;\n const renderer = this._renderer;\n\n if (!projection) return;\n\n this._emit(EVENTS.BEFORE_RENDER);\n\n renderer.renderVR(projection, vr, frame);\n\n this._emit(EVENTS.RENDER);\n }\n\n private _applyProjection(projection: Projection, texture: Texture, prevProjection: Projection | null) {\n const camera = this._camera;\n const control = this._control;\n const renderer = this._renderer;\n\n // Remove previous projection\n if (prevProjection) {\n prevProjection.releaseAllResources(this._renderer.ctx);\n }\n\n projection.applyTexture(renderer.ctx, texture);\n projection.updateCamera(camera);\n projection.updateControl(control);\n\n this._projection = projection;\n this._emit(EVENTS.PROJECTION_CHANGE, {\n projection\n });\n }\n\n private async _loadTexture(projection: Projection): Promise {\n const contentLoader = new TextureLoader();\n const { src, video } = projection;\n\n this._emit(EVENTS.LOAD_START, {\n src,\n video\n });\n\n const texture = await contentLoader.load(src, video);\n\n this._emit(EVENTS.LOAD, {\n src,\n video\n });\n\n return texture;\n }\n\n private _resizeComponents() {\n const renderer = this._renderer;\n const camera = this._camera;\n const control = this._control;\n\n renderer.resize();\n camera.resize(renderer.width, renderer.height);\n control.resize(renderer.width, renderer.height);\n }\n\n private _addEventHandlers(events: View360Options[\"on\"]) {\n // Bind option \"on\"\n Object.keys(events).forEach((evtName: keyof typeof EVENT_TYPES) => {\n this.on(evtName, events[evtName]);\n });\n }\n\n private _bindComponentEvents() {\n // Bind internal component events\n const root = this._rootEl;\n const control = this._control;\n const animator = this._animator;\n const renderer = this._renderer;\n const vr = this._vr;\n\n const controlEventsToPropagate = [\n CONTROL_EVENTS.STATIC_CLICK,\n CONTROL_EVENTS.INPUT_START,\n CONTROL_EVENTS.INPUT_END\n ];\n\n controlEventsToPropagate.forEach(evtName => {\n control.rotate.on(evtName, evt => {\n this._emit(evtName, evt);\n });\n\n control.zoom.on(evtName, evt => {\n this._emit(evtName, evt);\n });\n });\n\n vr.on(EVENTS.VR_START, evt => {\n root.classList.add(DEFAULT_CLASS.IN_VR);\n\n animator.changeContext(evt.session);\n animator.start(this._renderVRFrame);\n\n this._emit(EVENTS.VR_START);\n });\n\n vr.on(EVENTS.VR_END, () => {\n root.classList.remove(DEFAULT_CLASS.IN_VR);\n\n renderer.ctx.useDefaultFrameBuffer();\n animator.changeContext(window);\n animator.start(this._renderFrameOnDemand);\n\n this.resize();\n\n this._emit(EVENTS.VR_END);\n });\n }\n}\n\nexport default View360;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4, quat, vec3 } from \"gl-matrix\";\n\n/**\n * Base class for 3D objects\n * @ko 3D 오브젝트의 베이스 클래스\n * @since 4.0.0\n * @internal\n */\nclass Object3D {\n /**\n * Local matrix of the object\n * @ko 오브젝트의 local matrix\n * @since 4.0.0\n */\n public matrix: mat4;\n /**\n * Rotation quaternion\n * @ko 현재 오브젝트의 회전을 나타내는 사원수 값\n * @since 4.0.0\n */\n public rotation: quat;\n /**\n * Position of the object\n * @ko 오브젝트의 위치\n * @since 4.0.0\n */\n public position: vec3;\n /**\n * A scale vector of the object\n * @ko 오브젝트가 각 축으로 확대된 정도를 나타내는 벡터\n * @since 4.0.0\n */\n public scale: vec3;\n\n /**\n * Create new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n */\n public constructor() {\n this.matrix = mat4.create();\n this.rotation = quat.create();\n this.position = vec3.fromValues(0, 0, 0);\n this.scale = vec3.fromValues(1, 1, 1);\n }\n\n /**\n * Update local matrix of the object.\n * @ko 오브젝트의 local matrix를 갱신합니다.\n * @since 4.0.0\n */\n public updateMatrix() {\n mat4.fromRotationTranslationScale(this.matrix, this.rotation, this.position, this.scale);\n }\n}\n\nexport default Object3D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360Plugin from \"../View360Plugin\";\nimport View360 from \"../../View360\";\nimport { EVENTS } from \"../../const/external\";\nimport { createElement } from \"../../utils\";\nimport { LoadStartEvent } from \"../../type/events\";\n\n/**\n * Options for {@link LoadingSpinner}\n * @ko {@link LoadingSpinner}용 옵션들\n * @since 4.0.0\n * @category Plugin\n */\nexport interface LoadingSpinnerOptions {\n /**\n * Override default class names.\n * @ko 디폴트 클래스 이름들을 오버라이드합니다.\n * @since 4.0.0\n */\n className: Partial<{ -readonly [key in keyof typeof LoadingSpinner.DEFAULT_CLASS]: string }>;\n}\n\n/**\n * A plugin that displays loading spinner while loading the projection.\n * @ko 프로젝션 로딩중에 로딩 스피너를 보여주는 플러그인\n * @since 4.0.0\n * @category Plugin\n */\nclass LoadingSpinner implements View360Plugin {\n /**\n * Default class names that LoadingSpinner uses\n * @ko LoadingSpinner가 사용하는 디폴트 클래스 이름\n * @since 4.0.0\n */\n public static readonly DEFAULT_CLASS = {\n /**\n * A class name for the container element\n * @ko 컨테이너 엘리먼트의 클래스 이름\n * @since 4.0.0\n */\n CONTAINER: \"view360-spinner\",\n /**\n * A class name for the spinning ring element\n * @ko 돌아가는 링 엘리먼트의 클래스 이름\n * @since 4.0.0\n */\n RING: \"view360-spinner-ring\"\n } as const;\n\n /**\n * A class names overriding\n * @ko 현재 오버라이드 중인 클래스 이름\n * @since 4.0.0\n */\n public readonly className: LoadingSpinnerOptions[\"className\"];\n\n private _container: HTMLElement;\n\n /**\n * Create a new instance of LoadingSpinner. {@ko LoadingSpinner의 새 인스턴스를 생성합니다.}\n * @param options Options {@ko 옵션들}\n */\n public constructor({\n className = {}\n }: Partial = {}) {\n this.className = className;\n this._container = this._createElements();\n }\n\n public init(viewer: View360) {\n viewer.on(EVENTS.LOAD_START, this._startLoading);\n }\n\n public destroy(viewer: View360): void {\n viewer.off(EVENTS.LOAD_START, this._startLoading);\n this._detachElements({ target: viewer });\n }\n\n private _startLoading = ({ target: viewer }: LoadStartEvent) => {\n viewer.rootEl.appendChild(this._container);\n\n if (viewer.initialized) {\n viewer.once(EVENTS.LOAD, this._detachElements);\n } else {\n viewer.once(EVENTS.READY, this._detachElements);\n }\n };\n\n private _detachElements = ({ target: viewer }: { target: View360 }) => {\n const container = this._container;\n if (!container) return;\n\n if (container.parentElement === viewer.rootEl) {\n viewer.rootEl.removeChild(container);\n }\n };\n\n private _createElements() {\n const className = {\n ...this.className,\n ...LoadingSpinner.DEFAULT_CLASS\n };\n\n const container = createElement(className.CONTAINER);\n const ring = createElement(className.RING);\n\n container.appendChild(ring);\n\n return container;\n }\n}\n\nexport default LoadingSpinner;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n/* eslint-disable @typescript-eslint/no-empty-function */\n/* eslint-disable @typescript-eslint/no-unused-vars */\nimport ControlBar from \"./ControlBar\";\nimport View360 from \"../../View360\";\n\n/**\n * Common options for {@link ControlBarItem}\n * @ko {@link ControlBarItem}의 공통 옵션들\n * @category Plugin\n * @since 4.0.0\n */\nexport interface ControlBarItemOptions {\n /**\n * @copy ControlBarItem#position\n */\n position: typeof ControlBar.POSITION[keyof typeof ControlBar.POSITION];\n /**\n * @copy ControlBarItem#order\n */\n order: number;\n}\n\n/**\n * Interface of the ControlBar items\n * @ko 컨트롤바 아이템의 인터페이스\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nabstract class ControlBarItem {\n /**\n * Element of the item.\n * @ko 아이템의 엘리먼트\n * @since 4.0.0\n */\n public abstract element: HTMLElement;\n\n /**\n * Position to display item.\n * @ko 아이템을 표시할 위치.\n * @since 4.0.0\n */\n public position: ControlBarItemOptions[\"position\"];\n /**\n * Order within the same position.\n * The lowest one will be shown first.\n * @ko 동일한 position 내에서의 순서, 작을수록 먼저 표시됩니다.\n * @since 4.0.0\n */\n public order: ControlBarItemOptions[\"order\"];\n\n /**\n * Create new instance of the ControlBarItem\n * @ko ControlBarItem의 새로운 인스턴스를 생성합니다.\n * @param options Options {@ko 옵션들}\n */\n public constructor(options: ControlBarItemOptions) {\n this.position = options.position;\n this.order = options.order;\n }\n\n /**\n * Initialize item.\n * @ko 아이템을 초기화합니다.\n * @param viewer - A instance of viewer to attach item {@ko 아이템을 부착할 뷰어의 인스턴스}\n * @param controlBar - A instance of control bar to attach item {@ko 아이템을 부착할 컨트롤바의 인스턴스}\n * @since 4.0.0\n */\n public abstract init(viewer: View360, controlBar: ControlBar): any;\n /**\n * Destroy item and release all resources & event handlers.\n * @ko 아이템을 제거하고 할당된 모든 리소스 및 이벤트 핸들러를 제거합니다.\n * @param viewer - A instance of viewer to detach item {@ko 아이템을 떼어 낼 뷰어의 인스턴스}\n * @param controlBar - A instance of control bar to detach item {@ko 아이템을 떼어 낼 컨트롤바의 인스턴스}\n * @since 4.0.0\n */\n public abstract destroy(viewer: View360, controlBar: ControlBar): any;\n}\n\nexport default ControlBarItem;\n","export const CONTROL_BAR_DEFAULT_CLASS = {\n CONTROLS_ROOT: \"view360-controls\",\n CONTROLS_BG: \"view360-controls-background\",\n CONTROLS_MAIN: \"view360-controls-main\",\n CONTROLS_TOP: \"view360-controls-top\",\n CONTROLS_BOTTOM: \"view360-controls-bottom\",\n CONTROLS_MID: \"view360-controls-mid\",\n CONTROLS_LEFT: \"view360-controls-left\",\n CONTROLS_RIGHT: \"view360-controls-right\",\n CONTROLS_FLOAT_LEFT: \"view360-controls-float-left\",\n CONTROLS_FLOAT_RIGHT: \"view360-controls-float-right\",\n CONTROLS_BUTTON: \"view360-controls-button\",\n PROGRESS_ROOT: \"view360-controls-progress\",\n VOLUME_ROOT: \"view360-controls-volume\",\n RANGE_ROOT: \"view360-range\",\n RANGE_TRACK: \"view360-range-track\",\n RANGE_THUMB: \"view360-range-thumb\",\n RANGE_FILLER: \"view360-range-filler\",\n PLAY_BUTTON: \"view360-controls-play\",\n PAUSE_BUTTON: \"view360-controls-pause\",\n UNMUTED_BUTTON: \"view360-controls-unmuted\",\n MUTED_BUTTON: \"view360-controls-muted\",\n FULLSCREEN_BUTTON: \"view360-controls-fullscreen\",\n FULLSCREEN_EXIT_BUTTON: \"view360-controls-fullscreen-exit\",\n VR_BUTTON: \"view360-controls-vr\",\n GYRO_ENABLED: \"view360-controls-gyro-enabled\",\n GYRO_DISABLED: \"view360-controls-gyro-disabled\",\n VIDEO_TIME_DISPLAY: \"view360-controls-time\",\n PIEVIEW_ROOT: \"view360-controls-pie\",\n FIXED: \"view360-controls-fixed\",\n UNAVAILABLE: \"view360-controls-unavailable\",\n HIDDEN: \"view360-controls-hidden\"\n} as const;\n\nexport const CONTROL_BAR_ITEM_POSITION = {\n /**\n * Place control bar item floating at top-left corner\n * @ko 아이템을 왼쪽 위 구석에 표시합니다.\n * @since 4.0.0\n */\n TOP_LEFT: \"top-left\",\n /**\n * Place control bar item floating at top-right corner\n * @ko 아이템을 오른쪽 위 구석에 표시합니다.\n * @since 4.0.0\n */\n TOP_RIGHT: \"top-right\",\n /**\n * Place control bar item at upper block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 위쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_TOP: \"main-top\",\n /**\n * Place control bar item at lower block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 하단 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_BOTTOM: \"main-bottom\",\n /**\n * Place control bar item at center-left block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 왼쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_LEFT: \"main-left\",\n /**\n * Place control bar item at center-right block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 오른쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_RIGHT: \"main-right\"\n} as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { ControlBarOptions } from \"./ControlBar\";\nimport { CONTROL_BAR_DEFAULT_CLASS } from \"./const\";\nimport Motion from \"../../core/Motion\";\nimport MouseInput from \"../../control/input/MouseInput\";\nimport TouchInput from \"../../control/input/TouchInput\";\nimport { CONTROL_EVENTS, INFINITE_RANGE } from \"../../const/internal\";\nimport { clamp } from \"../../utils\";\nimport { InputEvents } from \"../../type/internal\";\nimport { EL_DIV } from \"../../const/browser\";\n\nclass RangeControl extends Component<{\n [CONTROL_EVENTS.INPUT_START]: number;\n [CONTROL_EVENTS.CHANGE]: number;\n [CONTROL_EVENTS.INPUT_END]: void;\n}> {\n public readonly rootEl: HTMLElement;\n public readonly thumbEl: HTMLElement;\n public readonly trackEl: HTMLElement;\n public readonly fillerEl: HTMLElement;\n\n private _motion: Motion;\n private _mouseInput: MouseInput;\n private _touchInput: TouchInput;\n private _fixedClass: string;\n private _bbox: DOMRect;\n\n /**\n *\n */\n public constructor() {\n super();\n\n const root = document.createElement(EL_DIV);\n const track = document.createElement(EL_DIV);\n const thumb = document.createElement(EL_DIV);\n const filler = document.createElement(EL_DIV);\n\n root.draggable = false;\n\n track.appendChild(filler);\n track.appendChild(thumb);\n root.appendChild(track);\n\n this.rootEl = root;\n this.trackEl = track;\n this.thumbEl = thumb;\n this.fillerEl = filler;\n\n this._mouseInput = new MouseInput();\n this._touchInput = new TouchInput();\n this._motion = new Motion({ duration: 1, range: INFINITE_RANGE, easing: x => x });\n this._bbox = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n left: 0,\n right: 0,\n bottom: 0,\n top: 0\n } as DOMRect;\n this._fixedClass = CONTROL_BAR_DEFAULT_CLASS.FIXED;\n }\n\n public init(className: Required) {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n\n this.rootEl.classList.add(className.RANGE_ROOT);\n this.trackEl.classList.add(className.RANGE_TRACK);\n this.thumbEl.classList.add(className.RANGE_THUMB);\n this.fillerEl.classList.add(className.RANGE_FILLER);\n this._fixedClass = className.FIXED;\n\n mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n touchInput.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n\n mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n touchInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n\n mouseInput.enable(this.rootEl);\n touchInput.enable(this.rootEl);\n\n this.resize();\n }\n\n public destroy() {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n\n this.rootEl.className = \"\";\n this.trackEl.className = \"\";\n this.thumbEl.className = \"\";\n this.fillerEl.className = \"\";\n\n mouseInput.off();\n touchInput.off();\n mouseInput.disable();\n touchInput.disable();\n }\n\n public resize() {\n this._bbox = this.trackEl.getBoundingClientRect();\n }\n\n public updateStyle(progress: number) {\n const width = this._bbox.width;\n const clampedProgress = clamp(progress, 0, 1);\n\n this.fillerEl.style.width = `${clampedProgress * 100}%`;\n this.thumbEl.style.transform = `translateX(${clampedProgress * width}px)`;\n }\n\n private _onHold = ({ srcEvent, isTouch }: InputEvents<{ x: number; y: number }>[typeof CONTROL_EVENTS.INPUT_START]) => {\n const bbox = this._bbox;\n if (!bbox) return;\n\n const x = isTouch\n ? (srcEvent as TouchEvent).touches[0].pageX\n : (srcEvent as MouseEvent).pageX;\n const elX = bbox.x + (window.scrollX ?? window.pageXOffset);\n\n const clamepdX = clamp(x, elX, elX + bbox.width);\n const progress = (clamepdX - elX) / bbox.width;\n\n this._motion.reset(clamepdX);\n this.thumbEl.classList.add(this._fixedClass);\n\n this.trigger(CONTROL_EVENTS.INPUT_START, progress);\n };\n\n private _onChange = ({ delta }: InputEvents<{ x: number; y: number }>[typeof CONTROL_EVENTS.CHANGE]) => {\n const motion = this._motion;\n const bbox = this._bbox;\n if (!bbox) return;\n\n motion.setNewEndByDelta(delta.x);\n motion.update(1);\n\n const elX = bbox.x + (window.scrollX ?? window.pageXOffset);\n const clampedX = clamp(motion.val, elX, elX + bbox.width);\n const progress = (clampedX - elX) / bbox.width;\n\n this.trigger(CONTROL_EVENTS.CHANGE, progress);\n };\n\n private _onRelease = () => {\n const bbox = this._bbox;\n if (!bbox) return;\n\n this.thumbEl.classList.remove(this._fixedClass);\n\n this.trigger(CONTROL_EVENTS.INPUT_END);\n };\n}\n\nexport default RangeControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport RangeControl from \"./RangeControl\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport { CONTROL_EVENTS, VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport { EVENTS } from \"../../const/external\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show video progress bar.\n * @ko 비디오의 프로그레스 바를 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass ProgressBar extends ControlBarItem {\n public get element() { return this._rangeControl.rootEl; }\n\n private _controlBar: ControlBar | null;\n private _video: TextureVideo | null;\n private _rangeControl: RangeControl;\n\n private _wasPaused: boolean;\n private _currentTime: number;\n private _duration: number;\n private _playPromise: Promise | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_TOP,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.position = position;\n this.order = order;\n\n this._controlBar = null;\n this._rangeControl = new RangeControl();\n\n this._video = null;\n this._wasPaused = false;\n this._currentTime = 0;\n this._duration = 0;\n this._playPromise = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const element = this.element;\n const rangeControl = this._rangeControl;\n const unavailableClass = controlBar.className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n element.classList.add(unavailableClass);\n return;\n }\n\n element.classList.remove(unavailableClass);\n element.classList.add(controlBar.className.PROGRESS_ROOT);\n viewer.on(EVENTS.RESIZE, this._onResize);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate);\n rangeControl.init(controlBar.className);\n rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n rangeControl.on(CONTROL_EVENTS.CHANGE, this._onControl);\n rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n this._video = video;\n this._currentTime = video.source.currentTime;\n this._duration = video.source.duration;\n this._controlBar = controlBar;\n\n rangeControl.updateStyle(this._currentTime / this._duration);\n }\n\n public destroy(viewer: View360) {\n const video = this._video;\n\n viewer.off(EVENTS.RESIZE, this._onResize);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate);\n }\n\n this._rangeControl.destroy();\n this._video = null;\n this._playPromise = null;\n }\n\n private _onResize = () => {\n this._rangeControl.resize();\n }\n\n private _onTimeUpdate = () => {\n const video = this._video;\n if (!video) return;\n\n this._currentTime = video.source.currentTime;\n this._rangeControl.updateStyle(this._currentTime / this._duration);\n };\n\n private _onDurationChange = () => {\n const video = this._video;\n if (!video) return;\n\n this._duration = video.source.duration;\n this._rangeControl.updateStyle(this._currentTime / this._duration);\n };\n\n private _onHold = (progress: number) => {\n const video = this._video;\n const controlBar = this._controlBar;\n if (!video || !controlBar) return;\n\n const paused = video.isPaused();\n\n video.source.pause();\n\n const time = video.source.duration * progress;\n video.source.currentTime = time;\n video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time }}));\n\n controlBar.rootEl.classList.add(controlBar.className.FIXED);\n this._wasPaused = !this._playPromise && paused;\n };\n\n private _onControl = (progress: number) => {\n const video = this._video;\n if (!video) return;\n\n const time = video.source.duration * progress;\n video.source.currentTime = time;\n video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time }}));\n };\n\n private _onRelease = () => {\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (video && controlBar) {\n if (!this._wasPaused && !this._playPromise) {\n this._playPromise = video.source.play()\n .catch(() => void 0);\n\n // This should not be chained\n this._playPromise.then(() => {\n this._playPromise = null;\n });\n\n controlBar.rootEl.classList.remove(controlBar.className.FIXED);\n }\n }\n\n this._wasPaused = false;\n };\n}\n\nexport default ProgressBar;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show video play / pause button.\n * @ko 비디오 재생 / 일시정지 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass PlayButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _controlBar: ControlBar | null;\n private _video: TextureVideo | null;\n private _paused: boolean;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n\n this._video = null;\n this._paused = true;\n this._controlBar = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const video = viewer.projection?.getTexture();\n const className = controlBar.className;\n const unavailableClass = className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n element.classList.add(unavailableClass);\n return;\n }\n\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.remove(unavailableClass);\n\n const paused = video.isPaused();\n this._video = video;\n this._paused = paused;\n this._controlBar = controlBar;\n\n if (paused) {\n this._onPause();\n } else {\n this._onPlay();\n }\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onPlay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onPause);\n }\n\n public destroy() {\n const video = this._video;\n const element = this.element;\n\n if (!video) return;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onPlay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onPause);\n\n this._video = null;\n this._paused = true;\n this._controlBar = null;\n }\n\n private _onClick = () => {\n const video = this._video;\n if (!video) return;\n\n if (this._paused) {\n video.source.play();\n } else {\n video.source.pause();\n }\n };\n\n private _onPlay = () => {\n if (!this._controlBar) return;\n\n const element = this.element;\n const className = this._controlBar.className;\n\n element.classList.add(className.PAUSE_BUTTON);\n element.classList.remove(className.PLAY_BUTTON);\n element.title = \"Pause Video\";\n\n this._paused = false;\n };\n\n private _onPause = () => {\n if (!this._controlBar) return;\n\n const element = this.element;\n const className = this._controlBar.className;\n\n element.classList.add(className.PLAY_BUTTON);\n element.classList.remove(className.PAUSE_BUTTON);\n element.title = \"Play Video\";\n\n this._paused = true;\n };\n}\n\nexport default PlayButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport RangeControl from \"./RangeControl\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { EVENTS } from \"../../const/external\";\n\n/**\n * Show video volume control.\n * @ko 비디오 볼륨 조절 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VolumeControl extends ControlBarItem {\n public get element() { return this._rootEl; }\n\n private _controlBar: ControlBar | null;\n private _rootEl: HTMLButtonElement;\n private _buttonEl: HTMLElement;\n private _rangeControl: RangeControl;\n private _video: TextureVideo | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this._controlBar = null;\n this._rangeControl = new RangeControl();\n this._createElements();\n\n this._video = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const root = this._rootEl;\n const button = this._buttonEl;\n const rangeControl = this._rangeControl;\n const className = controlBar.className;\n const unavailableClass = className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n root.classList.add(unavailableClass);\n return;\n }\n\n root.classList.remove(unavailableClass);\n root.classList.add(className.CONTROLS_BUTTON);\n root.classList.add(className.VOLUME_ROOT);\n button.classList.add(className.CONTROLS_BUTTON);\n\n if (video.source.muted) {\n button.classList.add(className.MUTED_BUTTON);\n } else {\n button.classList.add(className.UNMUTED_BUTTON);\n }\n\n viewer.on(EVENTS.RESIZE, this._onResize);\n root.addEventListener(BROWSER.EVENTS.TRANSITION_END, this._onResize);\n button.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_VOLUME_CHANGE, this._onVolumeChange);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_LOADED_DATA, this._updateDisplay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay);\n\n rangeControl.init(className);\n rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n rangeControl.on(CONTROL_EVENTS.CHANGE, this._onChange);\n rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n this._controlBar = controlBar;\n this._video = video;\n\n this._updateDisplay();\n }\n\n public destroy(viewer: View360) {\n const video = this._video;\n const button = this._buttonEl;\n const root = this._rootEl;\n\n root.className = \"\";\n button.className = \"\";\n\n viewer.off(EVENTS.RESIZE, this._onResize);\n root.removeEventListener(BROWSER.EVENTS.TRANSITION_END, this._onResize);\n button.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_VOLUME_CHANGE, this._onVolumeChange);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_LOADED_DATA, this._updateDisplay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay);\n }\n\n this._controlBar = null;\n this._rangeControl.destroy();\n this._video = null;\n }\n\n private _onResize = () => {\n this._rangeControl.resize();\n this._updateDisplay();\n }\n\n private _onClick = () => {\n const video = this._video;\n if (!video || this._rootEl.disabled) return;\n\n video.source.muted = !video.source.muted;\n };\n\n private _onVolumeChange = () => {\n const button = this._buttonEl;\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (!video || !controlBar) return;\n\n const className = controlBar.className;\n\n if (video.source.muted || video.source.volume === 0) {\n button.classList.add(className.MUTED_BUTTON);\n button.classList.remove(className.UNMUTED_BUTTON);\n } else {\n button.classList.add(className.UNMUTED_BUTTON);\n button.classList.remove(className.MUTED_BUTTON);\n }\n\n this._updateDisplay();\n };\n\n private _createElements() {\n const root = document.createElement(BROWSER.EL_BUTTON);\n const buttonEl = document.createElement(BROWSER.EL_DIV);\n\n root.appendChild(this._rangeControl.rootEl);\n root.appendChild(buttonEl);\n root.title = \"Toggle Mute\";\n\n this._rootEl = root;\n this._buttonEl = buttonEl;\n }\n\n private _onHold = (progress: number) => {\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (!video || !controlBar) return;\n\n const className = controlBar.className;\n\n video.source.volume = progress;\n\n this._rootEl.classList.add(className.FIXED);\n controlBar.containerEl.classList.add(className.FIXED);\n\n this._updateDisplay();\n };\n\n private _onChange = (progress: number) => {\n const video = this._video;\n if (!video) return;\n\n video.source.volume = progress;\n if (progress > 0) {\n video.source.muted = false;\n } else {\n video.source.muted = true;\n }\n\n this._updateDisplay();\n };\n\n private _onRelease = () => {\n const controlBar = this._controlBar;\n if (!controlBar) return;\n\n const className = controlBar.className;\n\n this._rootEl.classList.remove(className.FIXED);\n controlBar.containerEl.classList.remove(className.FIXED);\n };\n\n private _updateDisplay = () => {\n const video = this._video;\n const root = this._rootEl;\n if (!video) return;\n\n if (!video.hasAudio()) {\n root.disabled = true;\n return;\n }\n\n root.disabled = false;\n\n const volume = video.source.muted ? 0 : video.source.volume;\n\n this._rangeControl.updateStyle(volume);\n };\n}\n\nexport default VolumeControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport { isFullscreen } from \"../../utils\";\n\n/**\n * Show fullscreen enter / exit button.\n * @ko 풀스크린 진입 / 해제 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass FullscreenButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _controlBar: ControlBar | null;\n private _targetEl: HTMLElement | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n this.element.title = \"Toggle Fullscreen\";\n this._controlBar = null;\n this._targetEl = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n if (!this._fullscreenAvailable()) {\n element.classList.add(className.UNAVAILABLE);\n return;\n }\n\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.remove(className.UNAVAILABLE);\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._addFullscreenHandlers();\n\n if (isFullscreen()) {\n element.classList.add(className.FULLSCREEN_EXIT_BUTTON);\n } else {\n element.classList.add(className.FULLSCREEN_BUTTON);\n }\n\n this._controlBar = controlBar;\n this._targetEl = viewer.rootEl;\n }\n\n public destroy() {\n const element = this.element;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._removeFullscreenHandlers();\n\n this._controlBar = null;\n this._targetEl = null;\n }\n\n private _onClick = () => {\n const target = this._targetEl;\n if (!target) return;\n\n if (isFullscreen()) {\n this._exitFullscreen();\n } else {\n this._requestFullscreen(target);\n }\n };\n\n private _fullscreenAvailable() {\n return BROWSER.FULLSCREEN_REQUEST.some(key => !!document[key]);\n }\n\n private _requestFullscreen(el: HTMLElement) {\n for (const key of BROWSER.FULLSCREEN_REQUEST) {\n const request = el[key];\n if (request) {\n request.call(el);\n return;\n }\n }\n }\n\n private _exitFullscreen() {\n for (const key of BROWSER.FULLSCREEN_EXIT) {\n const exit = document[key];\n\n if (exit) {\n exit.call(document);\n return;\n }\n }\n }\n\n private _addFullscreenHandlers() {\n BROWSER.FULLSCREEN_CHANGE.forEach(evtName => {\n document.addEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _removeFullscreenHandlers() {\n BROWSER.FULLSCREEN_CHANGE.forEach(evtName => {\n document.removeEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _onFullscreenChange = () => {\n const element = this.element;\n const controlBar = this._controlBar;\n\n if (!controlBar) return;\n\n const className = controlBar.className;\n\n if (isFullscreen()) {\n element.classList.add(className.FULLSCREEN_EXIT_BUTTON);\n element.classList.remove(className.FULLSCREEN_BUTTON);\n } else {\n element.classList.add(className.FULLSCREEN_BUTTON);\n element.classList.remove(className.FULLSCREEN_EXIT_BUTTON);\n }\n };\n}\n\nexport default FullscreenButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\n\n/**\n * Show video current / total time.\n * @ko 비디오의 현재 / 총 재생시간을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VideoTime extends ControlBarItem {\n public readonly element: HTMLElement;\n private _video: TextureVideo | null;\n private _currentTime: number;\n private _duration: number;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n\n this._video = null;\n this._currentTime = 0;\n this._duration = 0;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const element = this.element;\n const className = controlBar.className;\n\n if (!video || !video.isVideo()) {\n element.classList.add(className.UNAVAILABLE);\n return;\n }\n\n element.classList.add(className.VIDEO_TIME_DISPLAY);\n element.classList.remove(className.UNAVAILABLE);\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange);\n\n this._video = video;\n this._currentTime = video.source.currentTime;\n this._duration = video.source.duration;\n\n this._updateDisplay();\n }\n\n public destroy() {\n const video = this._video;\n\n if (!video) return;\n\n this.element.className = \"\";\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange);\n\n this._video = null;\n }\n\n private _onTimeUpdate = () => {\n const video = this._video;\n if (!video) return;\n\n this._currentTime = video.source.currentTime;\n this._updateDisplay();\n };\n\n private _onDurationChange = () => {\n const video = this._video;\n if (!video) return;\n\n this._duration = video.source.duration;\n this._updateDisplay();\n };\n\n private _onCustomTimeChange = (evt: CustomEvent<{ time: number }>) => {\n this._currentTime = evt.detail.time;\n this._updateDisplay();\n };\n\n private _updateDisplay() {\n const time = this._currentTime;\n const timeMinute = Math.floor(time / 60);\n const timeSeconds = Math.floor(time - timeMinute * 60);\n const timeSecondsFormatted = timeSeconds < 10 ? `0${timeSeconds}` : timeSeconds;\n\n const duration = this._duration;\n const durationMinute = Math.floor(duration / 60);\n const durationSeconds = Math.floor(duration - durationMinute * 60);\n const durationSecondsFormatted = durationSeconds < 10 ? `0${durationSeconds}` : durationSeconds;\n\n this.element.innerText = `${timeMinute}:${timeSecondsFormatted} / ${durationMinute}:${durationSecondsFormatted}`;\n }\n}\n\nexport default VideoTime;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport { circulate, getObjectOption } from \"../../utils\";\nimport * as BROWSER from \"../../const/browser\";\nimport { EVENTS } from \"../../const/external\";\nimport { SVG_NAMESPACE } from \"../../const/internal\";\n\n/**\n * Options for {@link PieView}\n * @ko {@link PieView}용 옵션들\n * @category Plugin\n */\nexport interface PieViewOptions extends ControlBarItemOptions {\n /**\n * @copy PieView#resetCamera\n */\n resetCamera: boolean | Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n duration: number;\n easing: (x: number) => number;\n }>;\n}\n\n/**\n * Show camera direction/fov indicator.\n * @ko 카메라가 향하는 방향 및 FOV를 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass PieView extends ControlBarItem {\n public readonly element: HTMLElement;\n\n /**\n * Set rotation to reset camera to when PieView is clicked.\n * `false` will disable this value, and `true` will enable with default options.\n * @ko PieView가 클릭되었을 때 카메라를 리셋할 방향을 지정합니다.\n * `false`일 경우 이 동작을 비활성화하며, `true`일 경우 기본값을 사용합니다.\n * @since 4.0.0\n */\n public resetCamera: PieViewOptions[\"resetCamera\"];\n\n private _viewer: View360 | null;\n private _piePathEl: SVGPathElement;\n private _rangeCircleEl: SVGCircleElement;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n resetCamera = true,\n position = CONTROL_BAR_ITEM_POSITION.TOP_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n this.element.title = \"Reset view\";\n this.resetCamera = resetCamera;\n this._createPieElements();\n this._viewer = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n\n if (!viewer.initialized) {\n viewer.once(EVENTS.READY, this._updatePie);\n } else {\n this._updatePie({ target: viewer });\n }\n\n const rootClass = controlBar.className.PIEVIEW_ROOT;\n element.classList.add(rootClass);\n\n if (this.resetCamera) {\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n }\n\n viewer.on(EVENTS.VIEW_CHANGE, this._updatePie);\n\n this._viewer = viewer;\n }\n\n public destroy(viewer: View360) {\n const element = this.element;\n\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.className = \"\";\n viewer.off(EVENTS.READY, this._updatePie);\n viewer.off(EVENTS.VIEW_CHANGE, this._updatePie);\n\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n const resetCamera = this.resetCamera;\n\n if (!viewer || !resetCamera) return;\n\n const {\n yaw = viewer.initialYaw,\n pitch = viewer.initialPitch,\n zoom = viewer.initialZoom,\n duration = 500\n } = getObjectOption(resetCamera);\n\n viewer.camera.animateTo({\n yaw,\n pitch,\n zoom,\n duration\n });\n };\n\n private _createPieElements() {\n const root = this.element;\n const pieSVG = document.createElementNS(SVG_NAMESPACE, \"svg\");\n pieSVG.setAttribute(\"viewBox\", \"0 0 48 48\");\n pieSVG.setAttribute(\"width\", \"100%\");\n pieSVG.setAttribute(\"height\", \"100%\");\n\n const piePath = document.createElementNS(SVG_NAMESPACE, \"circle\");\n\n piePath.setAttribute(\"stroke\", \"currentColor\");\n piePath.setAttribute(\"fill\", \"transparent\");\n piePath.setAttribute(\"cx\", \"24\");\n piePath.setAttribute(\"cy\", \"24\");\n piePath.setAttribute(\"r\", \"12\");\n piePath.setAttribute(\"stroke-width\", \"24\");\n pieSVG.appendChild(piePath);\n\n const rangeCircle = document.createElementNS(SVG_NAMESPACE, \"circle\");\n\n rangeCircle.setAttribute(\"stroke\", \"currentColor\");\n rangeCircle.setAttribute(\"fill\", \"transparent\");\n rangeCircle.setAttribute(\"cx\", \"24\");\n rangeCircle.setAttribute(\"cy\", \"24\");\n rangeCircle.setAttribute(\"r\", \"22.5\");\n rangeCircle.setAttribute(\"stroke-width\", \"3\");\n pieSVG.appendChild(rangeCircle);\n\n root.appendChild(pieSVG);\n\n this._piePathEl = piePath;\n this._rangeCircleEl = rangeCircle;\n }\n\n private _updatePie = ({ target: viewer }: { target: View360 }) => {\n const piePath = this._piePathEl;\n const rangeCircle = this._rangeCircleEl;\n const camera = viewer.camera;\n const fov = camera.getHorizontalFov();\n const yawRange = camera.getYawRange(camera.zoom);\n const halfFov = fov * 0.5;\n\n const pieRadius = 24 * Math.PI;\n const pieDeg = pieRadius * fov / 360;\n const pieOffset = pieRadius * (camera.yaw + halfFov + 90) / 360;\n\n piePath.setAttribute(\"stroke-dasharray\", `${pieDeg} ${pieRadius - pieDeg}`);\n piePath.setAttribute(\"stroke-dashoffset\", `${pieOffset}`);\n\n if (isFinite(yawRange.min) && isFinite(yawRange.max)) {\n const radius = 45 * Math.PI; // 2 * PI * r\n const min = (circulate(yawRange.min, -180, 180) - halfFov) / 360;\n const max = (circulate(yawRange.max, -180, 180) + halfFov) / 360;\n\n const rangeDiff = radius * Math.abs(max - min);\n const offset = -radius * (min - 0.25);\n\n rangeCircle.setAttribute(\"stroke-dasharray\", `${rangeDiff} ${radius - rangeDiff}`);\n rangeCircle.setAttribute(\"stroke-dashoffset\", `${offset}`);\n } else {\n rangeCircle.setAttribute(\"stroke-dasharray\", \"\");\n rangeCircle.setAttribute(\"stroke-dashoffset\", \"\");\n }\n };\n}\n\nexport default PieView;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show VR enter button.\n * @ko VR 진입 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VRButton extends ControlBarItem {\n public readonly element: HTMLElement;\n\n private _viewer: View360 | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n this.element.title = \"Enter VR\";\n this._viewer = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n element.classList.add(className.UNAVAILABLE);\n element.classList.add(className.VR_BUTTON);\n element.classList.add(className.CONTROLS_BUTTON);\n\n viewer.vr.isAvailable()\n .then(available => {\n if (available) {\n element.classList.remove(className.UNAVAILABLE);\n }\n });\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._viewer = viewer;\n }\n\n public destroy() {\n const element = this.element;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n if (!viewer) return;\n\n viewer.vr.enter();\n };\n}\n\nexport default VRButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport GyroControl from \"../../control/GyroControl\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { sensorCanBeEnabledIOS } from \"../../utils\";\n\n/**\n * Show gyroscope control enable / disable button\n * @ko 자이로스코프 컨트롤 활성화 / 비활성화 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass GyroButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _viewer: View360 | null;\n private _controlBar: ControlBar | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n this.element.title = \"Toggle gyroscope control\";\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.add(className.UNAVAILABLE);\n\n const enableButton = () => {\n element.classList.remove(className.UNAVAILABLE);\n viewer.control.gyro.on(CONTROL_EVENTS.ENABLE, this._updateStyle);\n viewer.control.gyro.on(CONTROL_EVENTS.DISABLE, this._updateStyle);\n };\n\n if (sensorCanBeEnabledIOS()) {\n enableButton();\n } else {\n GyroControl.isAvailable().then(available => {\n if (!available) return;\n enableButton();\n });\n }\n\n this._controlBar = controlBar;\n this._viewer = viewer;\n this._updateStyle();\n }\n\n public destroy(viewer: View360) {\n const element = this.element;\n\n viewer.control.gyro.off(CONTROL_EVENTS.ENABLE, this._updateStyle);\n viewer.control.gyro.off(CONTROL_EVENTS.DISABLE, this._updateStyle);\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.className = \"\";\n\n this._controlBar = null;\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n const controlBar = this._controlBar;\n\n if (!viewer || !controlBar) return;\n\n const gyroControl = viewer.control.gyro;\n if (gyroControl.enabled) {\n gyroControl.disable();\n } else {\n GyroControl.requestSensorPermission().then(available => {\n if (available) {\n gyroControl.enable();\n } else {\n this.element.classList.add(controlBar.className.UNAVAILABLE);\n }\n });\n }\n };\n\n private _updateStyle = () => {\n const element = this.element;\n const viewer = this._viewer;\n const controlBar = this._controlBar;\n\n if (!viewer || !controlBar) return;\n\n const gyroControl = viewer.control.gyro;\n const className = controlBar.className;\n\n if (gyroControl.enabled) {\n element.classList.add(className.GYRO_ENABLED);\n element.classList.remove(className.GYRO_DISABLED);\n } else {\n element.classList.add(className.GYRO_DISABLED);\n element.classList.remove(className.GYRO_ENABLED);\n }\n };\n}\n\nexport default GyroButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport { FULLSCREEN_CHANGE } from \"../../const/browser\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport { isFullscreen } from \"../../utils\";\n\n/**\n * Options for ControlBar's {@link ControlBarOptions#autoHide}\n * @ko ControlBar의 {@link ControlBarOptions#autoHide}용 옵션\n * @category Plugin\n * @since 4.0.0\n */\nexport interface AutoHideOptions {\n /**\n * Initial delay before the control bar hides (ms)\n * @ko 컨트롤바가 처음으로 표시되고 사라지기까지 걸리는 시간 (ms)\n * @default 3000\n * @since 4.0.0\n */\n initialDelay: number;\n /**\n * Delay time before hiding the control bar after mouse leave (ms)\n * @ko 마우스가 컨트롤바 영역을 떠난 뒤 컨트롤바가 사라지기까지 걸리는 시간 (ms)\n * @default 0\n * @since 4.0.0\n */\n delay: number;\n /**\n * Delay time before hiding the control bar becomes active, like touch on mobile device or mouse move in fullscreen mode (ms)\n * @ko 모바일이나 풀스크린 환경 등에서 사용자 입력이 없을 때 컨트롤바가 사라지기까지 걸리는 시간 (ms)\n * @default 3000\n * @since 4.0.0\n */\n idleDelay: number;\n}\n\nclass AutoHide {\n private _initialDelay: AutoHideOptions[\"initialDelay\"];\n private _delay: AutoHideOptions[\"delay\"];\n private _idleDelay: AutoHideOptions[\"idleDelay\"];\n\n private _controlBar: ControlBar;\n private _timer: number;\n private _isGrabbing: boolean;\n private _isCursorInside: boolean;\n private _isFullscreen: boolean;\n private _targetEl: HTMLElement | null;\n private _video: TextureVideo | null;\n\n public get enabled() { return !!this._targetEl; }\n public get hidden() { return this._controlBar.containerEl.classList.contains(this._hiddenClass); }\n\n private get _hiddenClass() { return this._controlBar.className.HIDDEN; }\n private get _fixedClass() { return this._controlBar.className.FIXED; }\n\n public constructor(controlBar: ControlBar, {\n initialDelay = 3000,\n delay = 0,\n idleDelay: activationDelay = 3000\n }: Partial) {\n this._controlBar = controlBar;\n this._initialDelay = initialDelay;\n this._delay = delay;\n this._idleDelay = activationDelay;\n this._timer = -1;\n this._isCursorInside = false;\n this._isGrabbing = false;\n this._isFullscreen = false;\n this._video = null;\n this._targetEl = null;\n }\n\n public enable(viewer: View360) {\n if (this._targetEl) {\n this.disable(viewer);\n }\n\n const initialDelay = this._initialDelay;\n const root = viewer.rootEl;\n\n this._targetEl = viewer.rootEl;\n this._timer = window.setTimeout(() => {\n this.hide();\n }, initialDelay);\n\n root.addEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onHold);\n root.addEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter);\n root.addEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove);\n root.addEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave);\n this._addFullscreenHandlers();\n\n const video = viewer.projection?.getTexture();\n if (!video || !video.isVideo()) {\n return;\n }\n\n if (video.isPaused()) {\n this._controlBar.containerEl.classList.add(this._fixedClass);\n }\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onVideoPlay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onVideoPause);\n\n this._video = video;\n }\n\n public disable(viewer: View360) {\n if (!this._targetEl) return;\n\n const controlBar = this._controlBar;\n const root = viewer.rootEl;\n const video = this._video;\n\n root.removeEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onHold);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave);\n this._removeFullscreenHandlers();\n\n window.clearTimeout(this._timer);\n controlBar.containerEl.classList.remove(this._fixedClass);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onVideoPlay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onVideoPause);\n }\n\n this._isCursorInside = false;\n this._isGrabbing = false;\n this._video = null;\n this._targetEl = null;\n }\n\n public show() {\n this._clearHideTimer();\n this._controlBar.containerEl.classList.remove(this._hiddenClass);\n }\n\n public showTemporaliy() {\n this.show();\n this._hideAfterDelay(this._idleDelay);\n }\n\n public hide() {\n this._clearHideTimer();\n this._controlBar.containerEl.classList.add(this._hiddenClass);\n }\n\n private _clearHideTimer() {\n if (this._timer) {\n window.clearTimeout(this._timer);\n this._timer = -1;\n }\n }\n\n private _hideAfterDelay(delay = this._delay) {\n if (this._isGrabbing || (!this._isFullscreen && this._isCursorInside)) return;\n\n this._clearHideTimer();\n if (delay <= 0) {\n this.hide();\n } else {\n this._timer = window.setTimeout(() => {\n this.hide();\n }, delay);\n }\n }\n\n private _onMouseEnter = () => {\n this._isCursorInside = true;\n this.show();\n };\n\n private _onMouseLeave = () => {\n this._isCursorInside = false;\n this._hideAfterDelay();\n };\n\n private _onMouseMove = () => {\n if (!this._isFullscreen) return;\n\n this.showTemporaliy();\n }\n\n private _onHold = (evt: PointerEvent) => {\n this._isGrabbing = true;\n\n if (evt.pointerType === \"mouse\") {\n this._isCursorInside = true;\n }\n\n window.addEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n\n this.show();\n };\n\n private _onRelease = () => {\n this._isGrabbing = false;\n\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n\n this._hideAfterDelay();\n };\n\n private _onVideoPlay = () => {\n const root = this._targetEl;\n if (!root) return;\n\n this._controlBar.containerEl.classList.remove(this._fixedClass);\n };\n\n private _onVideoPause = () => {\n const root = this._targetEl;\n if (!root) return;\n\n this._controlBar.containerEl.classList.add(this._fixedClass);\n };\n\n private _addFullscreenHandlers() {\n FULLSCREEN_CHANGE.forEach(evtName => {\n document.addEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _removeFullscreenHandlers() {\n FULLSCREEN_CHANGE.forEach(evtName => {\n document.removeEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _onFullscreenChange = () => {\n this._isFullscreen = isFullscreen();\n\n if (this._isFullscreen) {\n this._hideAfterDelay();\n }\n };\n}\n\nexport default AutoHide;\n","import TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { clamp } from \"../../utils\";\nimport { VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\n\nclass VideoControl {\n private _video: TextureVideo | null;\n\n public enable(root: HTMLElement, video: TextureVideo) {\n this._video = video;\n // capture is needed for resolving conflict with keyboard control\n root.addEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown, true);\n }\n\n public disable(root: HTMLElement) {\n this._video = null;\n root.removeEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown, true);\n }\n\n private _onKeyDown = (event: KeyboardEvent) => {\n const video = this._video;\n if (!video) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n const videoEl = video.source;\n const keyPressed = event.keyCode != null\n ? BROWSER.DIRECTION_KEY_CODE[event.keyCode]\n : BROWSER.DIRECTION_KEY_NAME[event.key];\n\n switch (keyPressed) {\n case \"LEFT\":\n case \"RIGHT\":\n return this._changeVideoTime(videoEl, keyPressed === \"RIGHT\");\n case \"UP\":\n case \"DOWN\":\n return this._changeVideoVolume(videoEl, keyPressed === \"UP\");\n }\n\n const spacePressed = event.keyCode === BROWSER.SPACE_KEY_CODE || event.key === BROWSER.SPACE_KEY_NAME;\n if (spacePressed) {\n this._toggleVideo(video);\n }\n }\n\n private _changeVideoTime(video: HTMLVideoElement, forward: boolean) {\n const delta = forward ? 5 : -5;\n\n video.currentTime += delta;\n video.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time: video.currentTime }}));\n }\n\n private _changeVideoVolume(video: HTMLVideoElement, increase: boolean) {\n const delta = increase ? 0.1 : -0.1;\n\n if (video.muted) {\n video.volume = clamp(delta, 0, 1);\n } else {\n video.volume = clamp(video.volume + delta, 0, 1);\n }\n\n if (video.volume > 0) {\n video.muted = false;\n } else {\n video.muted = true;\n }\n }\n\n private _toggleVideo(video: TextureVideo) {\n if (video.isPaused()) {\n video.source.play();\n } else {\n video.source.pause();\n }\n }\n}\n\nexport default VideoControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport ProgressBar from \"./ProgressBar\";\nimport PlayButton from \"./PlayButton\";\nimport VolumeControl from \"./VolumeControl\";\nimport FullscreenButton from \"./FullscreenButton\";\nimport VideoTime from \"./VideoTime\";\nimport PieView, { PieViewOptions } from \"./PieView\";\nimport VRButton from \"./VRButton\";\nimport GyroButton from \"./GyroButton\";\nimport AutoHide, { AutoHideOptions } from \"./AutoHide\";\nimport VideoControl from \"./VideoControl\";\nimport View360, { View360Events } from \"../../View360\";\nimport View360Plugin from \"../View360Plugin\";\nimport { EVENTS } from \"../../const/external\";\nimport { createElement, findIndex, getObjectOption } from \"../../utils\";\nimport { ValueOf } from \"../../type/utils\";\nimport { StaticClickEvent } from \"../../type/events\";\nimport { CONTROL_BAR_DEFAULT_CLASS, CONTROL_BAR_ITEM_POSITION } from \"./const\";\n\n/**\n * Options for {@link ControlBar}\n * @ko {@link ControlBar}용 옵션들\n * @category Plugin\n * @since 4.0.0\n */\nexport interface ControlBarOptions {\n /**\n * @copy ControlBar#autoHide\n */\n autoHide: boolean | Partial;\n /**\n * @copy ControlBar#showBackground\n */\n showBackground: boolean;\n /**\n * @copy ControlBar#clickToPlay\n */\n clickToPlay: boolean;\n /**\n * @copy ControlBar#keyboardControls\n */\n keyboardControls: boolean;\n /**\n * @copy ControlBar#progressBar\n */\n progressBar: boolean | Partial;\n /**\n * @copy ControlBar#playButton\n */\n playButton: boolean | Partial;\n /**\n * @copy ControlBar#volumeButton\n */\n volumeButton: boolean | Partial;\n /**\n * @copy ControlBar#fullscreenButton\n */\n fullscreenButton: boolean | Partial;\n /**\n * @copy ControlBar#videoTime\n */\n videoTime: boolean | Partial;\n /**\n * @copy ControlBar#pieView\n */\n pieView: boolean | Partial;\n /**\n * @copy ControlBar#vrButton\n */\n vrButton: boolean | Partial;\n /**\n * @copy ControlBar#gyroButton\n */\n gyroButton: boolean | Partial;\n /**\n * @copy ControlBar#className\n */\n className: Partial<{ -readonly [key in keyof typeof ControlBar.DEFAULT_CLASS]: string }>;\n /**\n * @copy ControlBar#customItems\n */\n customItems: ControlBarItem[];\n}\n\n/**\n * A plugin that displays extra buttons & controls that controls {@link View360}.\n * @ko {@link View360}에 부가적인 버튼과 컨트롤을 추가해주는 플러그인.\n * @category Plugin\n * @since 4.0.0\n */\nclass ControlBar implements View360Plugin {\n /**\n * Default class names that ControlBar uses\n * @ko ControlBar가 사용하는 디폴트 클래스 이름들\n * @since 4.0.0\n */\n public static readonly DEFAULT_CLASS = CONTROL_BAR_DEFAULT_CLASS;\n\n /**\n * Constants for {@link ControlBarItemOptions#position}\n * @ko {@link ControlBarItemOptions#position}에 사용 가능한 값들\n */\n public static readonly POSITION = CONTROL_BAR_ITEM_POSITION;\n\n /**\n * Automatically hide control bar on video plays.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 재생시 자동으로 컨트롤바를 숨깁니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly autoHide?: ControlBarOptions[\"autoHide\"];\n /**\n * Show background element.\n * @ko 배경 엘리먼트를 표시합니다.\n * @since 4.0.0\n */\n public readonly showBackground?: ControlBarOptions[\"showBackground\"];\n /**\n * Whether to play / pause video on canvas click\n * @ko 캔버스 클릭시에 비디오를 재생 / 일시정지 토글합니다.\n * @since 4.0.0\n */\n public readonly clickToPlay: ControlBarOptions[\"clickToPlay\"];\n /**\n * Enable keyboard controls for video.\n * Pressing up / down arrow will control video volume, and pressing left / right arrow will control video time.\n * @ko 비디오 키보드 컨트롤을 활성화합니다.\n * 위 / 아래 화살표키를 누를 시 비디오 볼륨을, 왼쪽 / 오른쪽 화살표키를 누를 시 비디오 시간을 조정합니다.\n * @since 4.0.0\n */\n public readonly keyboardControls: ControlBarOptions[\"keyboardControls\"];\n /**\n * Show video progress bar.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 프로그레스 바를 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly progressBar: ControlBarOptions[\"progressBar\"];\n /**\n * Show video play / pause button.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 재생 / 일시정지 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly playButton: ControlBarOptions[\"playButton\"];\n /**\n * Show video volume control button.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 볼륨 조절 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly volumeButton: ControlBarOptions[\"volumeButton\"];\n /**\n * Show fullscreen button.\n * `true` to enable with default values, `false` to disable.\n * @ko 풀스크린 진입 / 해제 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly fullscreenButton: ControlBarOptions[\"fullscreenButton\"];\n /**\n * Show video current / total time\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오의 현재 시간 / 총 시간을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly videoTime: ControlBarOptions[\"videoTime\"];\n /**\n * Show camera pie view.\n * `true` to enable with default values, `false` to disable.\n * @ko 현재 카메라가 가리키는 방향을 표시하는 파이 뷰를 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly pieView: ControlBarOptions[\"pieView\"];\n /**\n * Show VR button.\n * `true` to enable with default values, `false` to disable.\n * @ko VR 진입버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly vrButton: ControlBarOptions[\"vrButton\"];\n /**\n * Show gyroscope control enable / disable button.\n * `true` to enable with default values, `false` to disable.\n * @ko 자이로스코프 컨트롤을 활성화 / 비활성화하는 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly gyroButton: ControlBarOptions[\"gyroButton\"];\n /**\n * Override default class names.\n * @ko 디폴트 클래스 이름들을 오버라이드합니다.\n * @since 4.0.0\n */\n public readonly className: Required;\n\n /**\n * Root element of the control bar\n * @ko 컨트롤바의 루트 엘리먼트\n * @since 4.0.0\n */\n public get rootEl() { return this._rootEl; }\n /**\n * Container element of the control bar\n * @ko 컨트롤바의 컨테이너 엘리먼트\n * @since 4.0.0\n */\n public get containerEl() { return this._containerEl; }\n /**\n * Background element of the control bar\n * @ko 컨트롤바의 배경 엘리먼트\n * @since 4.0.0\n */\n public get backgroundEl() { return this._bgEl; }\n /**\n * Control bar's default items created by {@link ControlBarOptions}\n * @ko 주어진 {@link ControlBarOptions}에 의해 생성된 디폴트 아이템들\n * @since 4.0.0\n */\n public get items() { return this._items; }\n /**\n * Custom control bar items\n * @ko 커스텀 컨트롤바 아이템들을 추가합니다.\n * @since 4.0.0\n */\n public get customItems() { return this._customItems; }\n\n private _rootEl: HTMLElement;\n private _containerEl: HTMLElement;\n private _bgEl: HTMLElement;\n private _wrapperEl: Record, HTMLElement>;\n private _items: Record, ControlBarItem[]>;\n private _customItems: ControlBarItem[];\n private _autoHider: AutoHide;\n private _videoControl: VideoControl;\n\n /**\n * Create new instance of ControlBar.\n * @ko ControlBar의 새 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n autoHide,\n showBackground,\n clickToPlay = true,\n keyboardControls = true,\n progressBar = true,\n playButton = true,\n volumeButton = true,\n fullscreenButton = true,\n videoTime = true,\n pieView = true,\n vrButton = true,\n gyroButton = true,\n className = {},\n customItems = []\n }: Partial = {}) {\n this.autoHide = autoHide;\n this.showBackground = showBackground;\n this.clickToPlay = clickToPlay;\n this.keyboardControls = keyboardControls;\n this.progressBar = progressBar;\n this.playButton = playButton;\n this.volumeButton = volumeButton;\n this.fullscreenButton = fullscreenButton;\n this.videoTime = videoTime;\n this.pieView = pieView;\n this.vrButton = vrButton;\n this.gyroButton = gyroButton;\n this.className = {\n ...ControlBar.DEFAULT_CLASS,\n ...className\n };\n\n const rootClass = className.CONTROLS_ROOT ?? ControlBar.DEFAULT_CLASS.CONTROLS_ROOT;\n\n this._rootEl = createElement(rootClass);\n this._createPositionWrappers();\n this._items = Object.keys(ControlBar.POSITION).reduce((items, key) => {\n items[ControlBar.POSITION[key]] = [];\n return items;\n }, {}) as Record, ControlBarItem[]>;\n this._customItems = customItems;\n this._autoHider = new AutoHide(this, getObjectOption(autoHide));\n this._videoControl = new VideoControl();\n\n customItems.forEach(item => {\n this._items[item.position].push(item);\n });\n }\n\n public init(viewer: View360) {\n const panoRoot = viewer.rootEl;\n const controlsRoot = this._rootEl;\n const defaultItems = this._createDefaultItems();\n\n this._updateBackground(viewer);\n this._updateAutoHide(viewer);\n this._updateKeyboardHandler(viewer);\n\n panoRoot.appendChild(controlsRoot);\n this._addItem(viewer, defaultItems);\n this._addItem(viewer, this._customItems);\n\n viewer.on(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad);\n viewer.on(EVENTS.STATIC_CLICK, this._onStaticClick);\n }\n\n public destroy(viewer: View360): void {\n // Remove controls root from pano root\n const panoRoot = viewer.rootEl;\n const controlsRoot = this._rootEl;\n const items = this._items;\n\n if (controlsRoot.parentElement === panoRoot) {\n panoRoot.removeChild(controlsRoot);\n }\n\n Object.keys(items).forEach((key: ValueOf) => {\n const category = items[key];\n\n category.forEach(item => {\n item.destroy(viewer, this);\n });\n\n items[key] = [];\n });\n\n this._clearItemElements();\n this._autoHider.disable(viewer);\n this._videoControl.disable(panoRoot);\n\n viewer.off(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad);\n viewer.off(EVENTS.STATIC_CLICK, this._onStaticClick);\n }\n\n private _addItem(viewer: View360, items: ControlBarItem[]) {\n for (const item of items) {\n const category = this._items[item.position];\n const wrapper = this._wrapperEl[item.position];\n\n const nextSiblingIndex = findIndex(category, sibling => sibling.order > item.order);\n\n if (nextSiblingIndex >= 0) {\n const nextSibling = category[nextSiblingIndex].element;\n category.splice(nextSiblingIndex, 0, item);\n wrapper.insertBefore(item.element, nextSibling);\n } else {\n category.push(item);\n wrapper.appendChild(item.element);\n }\n\n item.init(viewer, this);\n }\n }\n\n private _createPositionWrappers() {\n const className = {\n ...ControlBar.DEFAULT_CLASS,\n ...this.className\n };\n const rootEl = this._rootEl;\n\n // BG & FLOATING CONTROLS\n const backgroundEl = createElement(className.CONTROLS_BG);\n const floatLeftEl = createElement(className.CONTROLS_FLOAT_LEFT);\n const floatRightEl = createElement(className.CONTROLS_FLOAT_RIGHT);\n\n rootEl.appendChild(floatLeftEl);\n rootEl.appendChild(floatRightEl);\n\n // BOTTOM CONTROLS\n const container = createElement(className.CONTROLS_MAIN);\n const topWrapper = createElement(className.CONTROLS_TOP);\n const bottomWrapper = createElement(className.CONTROLS_BOTTOM);\n const midWrapper = createElement(className.CONTROLS_MID);\n const leftControlsWrapper = createElement(className.CONTROLS_LEFT);\n const rightControlsWrapper = createElement(className.CONTROLS_RIGHT);\n\n midWrapper.appendChild(leftControlsWrapper);\n midWrapper.appendChild(rightControlsWrapper);\n container.appendChild(backgroundEl);\n container.appendChild(topWrapper);\n container.appendChild(midWrapper);\n container.appendChild(bottomWrapper);\n rootEl.appendChild(container);\n\n this._bgEl = backgroundEl;\n this._containerEl = container;\n this._wrapperEl = {\n [ControlBar.POSITION.MAIN_TOP]: topWrapper,\n [ControlBar.POSITION.MAIN_LEFT]: leftControlsWrapper,\n [ControlBar.POSITION.MAIN_RIGHT]: rightControlsWrapper,\n [ControlBar.POSITION.MAIN_BOTTOM]: bottomWrapper,\n [ControlBar.POSITION.TOP_LEFT]: floatLeftEl,\n [ControlBar.POSITION.TOP_RIGHT]: floatRightEl\n };\n }\n\n private _clearItemElements() {\n const wrappers = Object.keys(ControlBar.POSITION).map(key => ControlBar.POSITION[key]);\n\n // Remove all elements inside wrappers\n wrappers.forEach(wrapper => {\n while (wrapper.firstChild) {\n wrapper.removeChild(wrapper.firstChild);\n }\n });\n }\n\n private _onStaticClick = ({ target: viewer, isTouch }: StaticClickEvent) => {\n const autoHider = this._autoHider;\n\n if (isTouch) {\n if (!autoHider.enabled) return;\n\n if (autoHider.hidden) {\n autoHider.showTemporaliy();\n } else {\n autoHider.hide();\n }\n } else {\n if (!this.clickToPlay) return;\n\n const video = viewer.projection?.getTexture();\n if (!video || !video.isVideo()) return;\n\n if (video.isPaused()) {\n video.source.play();\n } else {\n video.source.pause();\n }\n }\n };\n\n private _onNewSrcLoad = ({ target: viewer }: View360Events[\"projectionChange\"]) => {\n const items = this._items;\n\n this._updateBackground(viewer);\n this._updateAutoHide(viewer);\n this._updateKeyboardHandler(viewer);\n\n Object.keys(items).forEach((key: ValueOf) => {\n const category = items[key];\n\n category.forEach(item => {\n item.destroy(viewer, this);\n item.init(viewer, this);\n });\n });\n };\n\n private _updateAutoHide(viewer: View360) {\n const autoHide = this.autoHide;\n const autoHider = this._autoHider;\n\n if (autoHide != null) {\n if (autoHide) {\n autoHider.enable(viewer);\n } else {\n autoHider.disable(viewer);\n }\n } else {\n // Automatically choose whether to show background by content type\n const texture = viewer.projection?.getTexture();\n\n if (texture && texture.isVideo()) {\n // Enable auto hide when content type is video\n autoHider.enable(viewer);\n } else {\n autoHider.disable(viewer);\n }\n }\n }\n\n private _updateBackground(viewer: View360) {\n const background = this._bgEl;\n const showBackground = this.showBackground;\n const hiddenClass = this.className.HIDDEN ?? ControlBar.DEFAULT_CLASS.HIDDEN;\n\n if (showBackground != null) {\n if (showBackground) {\n background.classList.remove(hiddenClass);\n } else {\n background.classList.add(hiddenClass);\n }\n } else {\n // Automatically choose whether to show background by content type\n const texture = viewer.projection?.getTexture();\n\n if (texture && texture.isVideo()) {\n // Show bg when content type is video\n background.classList.remove(hiddenClass);\n } else {\n background.classList.add(hiddenClass);\n }\n }\n }\n\n private _updateKeyboardHandler(viewer: View360) {\n const panoRoot = viewer.rootEl;\n const videoControl = this._videoControl;\n const texture = viewer.projection?.getTexture();\n\n if (this.keyboardControls && texture && texture.isVideo()) {\n videoControl.enable(panoRoot, texture);\n } else {\n videoControl.disable(panoRoot);\n }\n }\n\n private _createDefaultItems(): ControlBarItem[] {\n const items: ControlBarItem[] = [];\n\n if (this.progressBar) {\n items.push(new ProgressBar(getObjectOption(this.progressBar)));\n }\n\n if (this.playButton) {\n items.push(new PlayButton(getObjectOption(this.playButton)));\n }\n\n if (this.volumeButton) {\n items.push(new VolumeControl(getObjectOption(this.volumeButton)));\n }\n\n if (this.gyroButton) {\n items.push(new GyroButton(getObjectOption(this.gyroButton)));\n }\n\n if (this.vrButton) {\n items.push(new VRButton(getObjectOption(this.vrButton)));\n }\n\n if (this.fullscreenButton) {\n items.push(new FullscreenButton(getObjectOption(this.fullscreenButton)));\n }\n\n if (this.videoTime) {\n items.push(new VideoTime(getObjectOption(this.videoTime)));\n }\n\n if (this.pieView) {\n items.push(new PieView(getObjectOption(this.pieView)));\n }\n\n return items;\n }\n}\n\nexport default ControlBar;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Camera from \"../core/Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport Texture from \"../texture/Texture\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport { VideoConfig } from \"../type/external\";\nimport UniformCanvasCube from \"../uniform/UniformCanvasCube\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport UniformTextureCube from \"../uniform/UniformTextureCube\";\n\ntype CommonProjectionUniforms = {\n uTexture: UniformTexture2D | UniformTextureCube | UniformCanvasCube;\n}\n\n/**\n * Common option for {@link Projection}s\n * @ko {@link Projection}을 위한 공통 옵션들\n * @category Projection\n * @since 4.0.0\n */\nexport interface ProjectionOptions {\n /**\n * @copy Projection#src\n */\n src: string | HTMLElement | Array;\n /**\n * @copy Projection#video\n */\n video?: boolean | Partial;\n}\n\n/**\n * Base class for projections.\n * @ko 프로젝션 베이스 클래스.\n * @category Projection\n * @since 4.0.0\n */\nabstract class Projection {\n /**\n * Source URL to panorama image/video.\n * @ko 파노라마 이미지/비디오의 URL\n * @since 4.0.0\n */\n public readonly src: ProjectionOptions[\"src\"];\n /**\n * Properties for the video element.\n * Setting `false` will treat panorama source as an image, `true` will use default properties.\n * @ko 비디오 엘리먼트에 설정할 프로퍼티를 담는 객체.\n * @since 4.0.0\n * @example\n * Default properties\n * ```ts\n * autoplay: true\n * muted: true\n * loop: false\n * volume: 1\n * ```\n */\n public readonly video: ProjectionOptions[\"video\"];\n\n protected _mesh: TriangleMesh | null;\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n src,\n video = false\n }: ProjectionOptions) {\n this.src = src;\n this.video = video;\n this._mesh = null;\n }\n\n /**\n * Apply texture to current projection.\n * @ko 주어진 텍스쳐를 현재 프로젝션에 적용합니다.\n * @param ctx - Instance of the WebGLContext helper {@ko WebGL context 헬퍼의 인스턴스}\n * @param texture - New texture to apply {@ko 새로 적용할 텍스쳐}\n * @internal\n * @since 4.0.0\n */\n public abstract applyTexture(ctx: WebGLContext, texture: Texture): void;\n\n /**\n * Release all resources projection has.\n * This is automatically called on projection change & View360's destroy call\n * @ko 현재 갖고 있는 모든 리소스를 반환합니다.\n * 이 메소드는 프로젝션 변경 및 View360의 destroy 호출 시 자동으로 호출됩니다.\n * @param ctx\n */\n public releaseAllResources(ctx: WebGLContext) {\n this._mesh?.destroy(ctx);\n }\n\n /**\n * Update camera to match projection's settings.\n * @ko 현재 프로젝션의 세팅으로 카메라를 업데이트합니다.\n * @param camera - Instance of the camera to update {@ko 업데이트할 카메라의 인스턴스}\n * @since 4.0.0\n */\n public updateCamera(camera: Camera) {\n // Use default mode & no view restriction\n camera.resetRange();\n }\n\n /**\n * Update control to match projection's settings.\n * @ko 현재 프로젝션의 세팅으로 컨트롤을 업데이트합니다.\n * @param control - Instance of the control to update {@ko 업데이트할 컨트롤의 인스턴스}\n * @since 4.0.0\n */\n public updateControl(control: PanoControl) {\n control.ignoreZoomScale = false;\n }\n\n /**\n * Update projection.\n * @ko 현재 프로젝션 정보를 갱신합니다.\n * @param camera - Instance of the camera to reference {@ko 참조할 카메라의 인스턴스}\n * @since 4.0.0\n */\n public update(camera: Camera) {} // eslint-disable-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars\n\n /**\n * Return active texture.\n * @ko 현재 활성화된 텍스쳐를 반환합니다.\n * @internal\n * @since 4.0.0\n */\n public getTexture() {\n if (!this._mesh) return null;\n\n return this._mesh.program.uniforms.uTexture.texture;\n }\n\n /**\n * A 3D triangle mesh for projection. It's `null` until loading the `src`.\n * @ko Projection을 표시하기 위한 Mesh, src를 로드하기 전까지는 `null`입니다.\n * @since 4.0.0\n */\n public getMesh(): TriangleMesh | null {\n return this._mesh;\n }\n}\n\nexport default Projection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nabstract class Uniform {\n public needsUpdate: boolean;\n\n public constructor() {\n this.needsUpdate = true;\n }\n\n public abstract update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean): void;\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext) {\n // DO_NOTHING\n }\n}\n\nexport default Uniform;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport TextureCube from \"../texture/TextureCube\";\nimport { reorderCube } from \"../utils\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformTextureCube extends Uniform {\n public readonly texture: TextureCube;\n private _webglTexture: WebGLTexture;\n private _cubemapOrder: string;\n\n public constructor(ctx: WebGLContext, texture: TextureCube, cubemapOrder: string) {\n super();\n\n this.texture = texture;\n this._webglTexture = ctx.createWebGLCubeTexture(texture, texture.width);\n this._cubemapOrder = cubemapOrder;\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext): void {\n this.texture.destroy();\n gl.deleteTexture(this._webglTexture);\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture);\n\n const sources = reorderCube(texture.sources, this._cubemapOrder);\n sources.forEach((src, idx) => {\n if (isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src);\n } else {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src);\n }\n });\n\n if (!texture.isVideo()) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformTextureCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"../texture/Texture2D\";\nimport { range, reorderCube } from \"../utils\";\n\n/** @hidden */\nclass CubeTexturePainter {\n public readonly texture: Texture2D;\n private _renderingOrder: number[];\n private _canvas: HTMLCanvasElement;\n private _ctx: CanvasRenderingContext2D;\n private _row: number;\n private _column: number;\n private _size: number;\n\n public get size() { return this._size; }\n\n public constructor(texture: Texture2D, cubemapOrder: string) {\n this.texture = texture;\n this._renderingOrder = reorderCube(range(6), cubemapOrder);\n\n const canvas = document.createElement(\"canvas\");\n\n this._calcRenderingSize();\n\n canvas.width = this._size;\n canvas.height = this._size;\n\n this._canvas = canvas;\n this._ctx = canvas.getContext(\"2d\")!;\n }\n\n public destroy() {\n const canvas = this._canvas;\n\n // release memories\n canvas.width = 1;\n canvas.height = 1;\n this._canvas = null as any;\n }\n\n public draw(gl: WebGLRenderingContext | WebGL2RenderingContext, isWebGL2: boolean) {\n const size = this._size;\n const texture = this.texture;\n let surfaceIdx = 0;\n\n for (let row = 0; row < this._row; row++) {\n for (let column = 0; column < this._column; column++) {\n const x = size * column;\n const y = size * row;\n const renderingFace = this._renderingOrder[surfaceIdx];\n\n this._ctx.drawImage(texture.source as CanvasImageSource, x, y, size, size, 0, 0, size, size);\n\n if (isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas);\n } else {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas);\n }\n\n surfaceIdx++;\n }\n }\n }\n\n private _calcRenderingSize() {\n const {\n width,\n height\n } = this.texture;\n const aspect = width / height;\n\n if (aspect === 1 / 6) {\n this._size = width;\n this._row = 6;\n this._column = 1;\n } else if (aspect === 6) {\n this._size = height;\n this._row = 1;\n this._column = 6;\n } else if (aspect === 2 / 3) {\n this._size = width * 0.5;\n this._row = 3;\n this._column = 2;\n } else {\n this._size = width / 3;\n this._row = 2;\n this._column = 3;\n }\n }\n}\n\nexport default CubeTexturePainter;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport CubeTexturePainter from \"../core/CubeTexturePainter\";\nimport Texture2D from \"../texture/Texture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformCanvasCube extends Uniform {\n private _webglTexture: WebGLTexture;\n private _painter: CubeTexturePainter;\n\n public get texture() { return this._painter.texture; }\n\n public constructor(ctx: WebGLContext, texture: Texture2D, cubemapOrder: string) {\n super();\n\n this._painter = new CubeTexturePainter(texture as Texture2D, cubemapOrder);\n this._webglTexture = ctx.createWebGLCubeTexture(texture, this._painter.size);\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext) {\n gl.deleteTexture(this._webglTexture);\n this._painter.destroy();\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture);\n\n this._painter.draw(gl, isWebGL2);\n\n if (!texture.isVideo()) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformCanvasCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Object3D from \"./Object3D\";\nimport ShaderProgram from \"./ShaderProgram\";\nimport VertexArrayObject from \"./VertexArrayObject\";\nimport Uniform from \"../uniform/Uniform\";\nimport WebGLContext from \"./WebGLContext\";\n\n/**\n * @hidden\n */\nclass TriangleMesh = Record> extends Object3D {\n /**\n * @internal\n * Geometry data for projection\n */\n public readonly vao: VertexArrayObject;\n /**\n * @internal\n * Material(shader) data for projection\n */\n public readonly program: ShaderProgram;\n\n public constructor(vao: VertexArrayObject, program: ShaderProgram) {\n super();\n\n this.vao = vao;\n this.program = program;\n }\n\n public destroy(ctx: WebGLContext) {\n ctx.releaseVAO(this.vao);\n ctx.releaseShaderResources(this.program);\n }\n}\n\nexport default TriangleMesh;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"../uniform/Uniform\";\nimport WebGLContext from \"./WebGLContext\";\nimport { UniformLocations } from \"../type/internal\";\n\nclass ShaderProgram = Record> {\n public readonly program: WebGLProgram;\n public readonly uniforms: T;\n public readonly uniformLocations: UniformLocations;\n\n public constructor(ctx: WebGLContext, vertexShader: string, fragmentShader: string, uniforms: T) {\n this.program = ctx.createProgram(vertexShader, fragmentShader);\n this.uniforms = uniforms;\n this.uniformLocations = ctx.getUniformLocations(this.program, uniforms);\n }\n}\n\nexport default ShaderProgram;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { TypedArray } from \"../type/utils\";\n\n/**\n * @hidden\n */\nclass VertexData {\n public readonly data: T;\n public itemSize: number;\n public count: number;\n\n /** */\n public constructor(data: T, itemSize: number) {\n this.data = data;\n this.itemSize = itemSize;\n this.count = data.length / itemSize;\n }\n}\n\nexport default VertexData;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport VertexData from \"../core/VertexData\";\n\n/**\n * @hidden\n */\nabstract class Geometry {\n public readonly vertices: VertexData;\n public readonly indicies: VertexData;\n public readonly uvs: VertexData;\n\n /** */\n public constructor(vertices: number[], indicies: number[], uvs: number[]) {\n this.vertices = new VertexData(new Float32Array(vertices), 3);\n this.indicies = new VertexData(new Uint16Array(indicies), 1);\n this.uvs = new VertexData(new Float32Array(uvs), 2);\n }\n}\n\nexport default Geometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\nimport { ROTATE } from \"../const/internal\";\nimport { reorderCube } from \"../utils\";\n\n/**\n * @hidden\n */\nclass CubeGeometry extends Geometry {\n public constructor({\n order,\n rotateUV\n }: {\n order: string;\n rotateUV?: ROTATE[]\n }) {\n const vertices = [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // up\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // down\n -1, -1, 1,\n 1, -1, 1,\n 1, -1, -1,\n -1, -1, -1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n\n const indicies = [\n 0, 1, 2,\n 0, 2, 3,\n 4, 5, 6,\n 4, 6, 7,\n 8, 9, 10,\n 8, 10, 11,\n 12, 13, 14,\n 12, 14, 15,\n 16, 17, 18,\n 16, 18, 19,\n 20, 21, 22,\n 20, 22, 23\n ];\n\n const oneThird = 1 / 3;\n const coords: number[][] = [];\n\n for (let r = 1; r >= 0; r--) {\n for (let c = 0; c < 3; c++) {\n const coord = [\n c * oneThird, r * 0.5,\n (c + 1) * oneThird, r * 0.5,\n (c + 1) * oneThird, (r + 1) * 0.5,\n c * oneThird, (r + 1) * 0.5\n ];\n\n coords.push(coord);\n }\n }\n\n if (rotateUV) {\n rotateUV.forEach((degree, idx) => {\n if (degree === ROTATE.ZERO) return;\n\n const coord = coords[idx];\n let newOrder: number[];\n\n if (degree === ROTATE.CW_90) {\n newOrder = [1, 2, 3, 0];\n } else if (degree === ROTATE.CCW_90) {\n newOrder = [3, 0, 1, 2];\n } else {\n newOrder = [2, 3, 0, 1];\n }\n\n const newCoords = Array(coord.length);\n for (let uvIdx = 0; uvIdx < coord.length / 2; uvIdx++) {\n newCoords[uvIdx * 2 + 0] = coord[newOrder[uvIdx] * 2 + 0];\n newCoords[uvIdx * 2 + 1] = coord[newOrder[uvIdx] * 2 + 1];\n }\n\n coords[idx] = newCoords;\n });\n }\n\n const uvs = reorderCube(coords, order, \"BFUDRL\")\n .reduce((acc, val) => acc.concat(val), []);\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default CubeGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTextureCube from \"../uniform/UniformTextureCube\";\nimport UniformCanvasCube from \"../uniform/UniformCanvasCube\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport TextureCube from \"../texture/TextureCube\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/cube.vert\";\nimport fs from \"../shader/cube.frag\";\n\n/**\n * Options for {@link CubemapProjection}\n * @ko {@link CubemapProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CubemapProjectionOptions extends ProjectionOptions {\n /**\n * Order of the cubemap images.\n * @ko 큐브맵 이미지의 순서.\n * @since 4.0.0\n * @default \"RLUDFB\" (Right - Left - Up - Down - Front - Back)\n */\n cubemapOrder?: string;\n /**\n * Whether to flip cubemap image horizontally.\n * @ko 큐브맵 이미지를 좌우대칭할지 여부.\n * @since 4.0.0\n * @default false\n */\n cubemapFlipX?: boolean;\n}\n\n/**\n * Projection based on cubemap images, accepts both multiple or single images.\n * @ko 큐브맵 이미지 기반의 프로젝션, 단일 혹은 여러 장의 이미지를 모두 사용 가능합니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CubemapProjection extends Projection<{\n uTexture: UniformTextureCube | UniformCanvasCube;\n}> {\n private _cubemapOrder: NonNullable;\n private _cubemapFlipX: NonNullable;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CubemapProjectionOptions) {\n super(options);\n\n const {\n cubemapOrder = \"RLUDFB\",\n cubemapFlipX = false\n } = options;\n\n this._cubemapOrder = cubemapOrder;\n this._cubemapFlipX = cubemapFlipX;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const cubemapOrder = this._cubemapOrder;\n const cubemapFlipX = this._cubemapFlipX;\n const uniforms = {\n uTexture: texture.isCube()\n ? new UniformTextureCube(ctx, texture as TextureCube, cubemapOrder)\n : new UniformCanvasCube(ctx, texture as Texture2D, cubemapOrder)\n };\n\n const geometry = new CubeGeometry({\n order: cubemapOrder\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n if (cubemapFlipX) {\n mesh.scale[0] = -1;\n }\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n}\n\nexport default CubemapProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"../texture/Texture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformTexture2D extends Uniform {\n public readonly texture: Texture2D;\n private _webglTexture: WebGLTexture;\n\n public constructor(ctx: WebGLContext, texture: Texture2D) {\n super();\n\n this.texture = texture;\n this._webglTexture = ctx.createWebGLTexture(texture);\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext): void {\n this.texture.destroy();\n gl.deleteTexture(this._webglTexture);\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n const isVideo = texture.isVideo();\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._webglTexture);\n\n if (!isVideo && isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n } else {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n }\n\n if (!isVideo) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformTexture2D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link CubestripProjection}\n * @ko {@link CubestripProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CubestripProjectionOptions extends ProjectionOptions {\n /**\n * @copy CubemapProjectionOptions#cubemapOrder\n */\n cubemapOrder?: string;\n /**\n * @copy CubemapProjectionOptions#cubemapFlipX\n */\n cubemapFlipX?: boolean;\n}\n\n/**\n * Projection based on cubemap strip.\n * Slightly more efficient than {@link CubemapProjection} as it doesn't copy cubemap image to canvas while rendering.\n * Accepts only single image.\n * @ko 큐브맵 스트립 기반의 프로젝션.\n * {@link CubemapProjection}와 달리 렌더링하는 과정에 캔버스에 이미지를 복사하는 과정이 없기 때문에 살짝 더 효율적입니다.\n * 단일 이미지만 사용 가능합니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CubestripProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n private _cubemapOrder: NonNullable;\n private _cubemapFlipX: NonNullable;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CubestripProjectionOptions) {\n super(options);\n\n const {\n cubemapOrder = \"RLUDFB\",\n cubemapFlipX = false\n } = options;\n\n this._cubemapOrder = cubemapOrder;\n this._cubemapFlipX = cubemapFlipX;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const cubemapOrder = this._cubemapOrder;\n const cubemapFlipX = this._cubemapFlipX;\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n const geometry = new CubeGeometry({\n order: cubemapOrder\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n if (cubemapFlipX) {\n mesh.scale[0] = -1;\n }\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n}\n\nexport default CubestripProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass CylinderGeometry extends Geometry {\n public constructor(maxTheta: number) {\n const vertices: number[] = [];\n const indicies: number[] = [];\n const uvs: number[] = [];\n\n const height = 1;\n const radialSegments = 60;\n const halfHeight = height * 0.5;\n const heightSegments = [-halfHeight, halfHeight];\n const invRadialSegments = 1 / radialSegments;\n const angleConst = maxTheta * invRadialSegments;\n\n for (let yIdx = 0; yIdx < 2; yIdx++) {\n const y = heightSegments[yIdx];\n\n for (let lngIdx = 0; lngIdx <= radialSegments; lngIdx++) {\n const angle = lngIdx * angleConst + Math.PI - maxTheta * 0.5;\n const x = Math.cos(angle);\n const z = Math.sin(angle);\n const u = lngIdx * invRadialSegments;\n const v = yIdx;\n\n uvs.push(u, v);\n vertices.push(x, y, z);\n\n if (yIdx === 0 && lngIdx < radialSegments) {\n const a = lngIdx;\n const b = a + radialSegments + 1;\n\n indicies.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n }\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default CylinderGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n*/\nimport { quat } from \"gl-matrix\";\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport CylinderGeometry from \"../geometry/CylinderGeometry\";\nimport Camera from \"../core/Camera\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"../const/internal\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\nimport TriangleMesh from \"../core/TriangleMesh\";\n\n/**\n * Options for {@link CylindricalProjection}\n * @ko {@link CylindricalProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CylindricalProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n /**\n * Whether the panorama image covers full 360 degrees.\n * @ko 파노라마 이미지가 360도를 전부 커버하는지 여부\n * @since 4.0.0\n * @default false\n */\n partial?: boolean;\n}\n\n/**\n * Projection based on cylindrical projection.\n * This can show panorama images taken from smartphones.\n * @ko 원통 투영법 기반의 프로젝션.\n * 일반적인 스마트폰 파노라마 사진을 표시하는데 사용될 수 있습니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CylindricalProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n private _partial: boolean;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CylindricalProjectionOptions) {\n super(options);\n\n const {\n partial = false\n } = options;\n\n this._partial = partial;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const partial = this._partial;\n const { width, height } = texture;\n const aspect = width / height;\n const halfVFov = 180 / aspect;\n const cylinderHeight = partial\n ? 1\n : 2 * Math.tan(halfVFov * DEG_TO_RAD);\n const cylinderTheta = partial\n ? aspect\n : 2 * Math.PI;\n\n const geometry = new CylinderGeometry(cylinderTheta);\n const program = new ShaderProgram(ctx, vs, fs, {\n uTexture: new UniformTexture2D(ctx, texture)\n });\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n mesh.scale[1] = cylinderHeight;\n quat.identity(mesh.rotation);\n quat.rotateY(mesh.rotation, mesh.rotation, -Math.PI / 2);\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n\n public updateCamera(camera: Camera) {\n super.updateCamera(camera);\n\n const mesh = this._mesh;\n if (!mesh) return;\n\n const uTexture = mesh.program.uniforms.uTexture;\n const texture = uTexture.texture;\n const { width, height } = texture;\n const aspect = width / height;\n const halfHeight = mesh.scale[1] * 0.5;\n\n if (this._partial) {\n const restrictedYaw = 0.5 * aspect * RAD_TO_DEG;\n camera.restrictYawRange(-restrictedYaw, restrictedYaw);\n }\n\n const restrictedPitch = Math.atan2(halfHeight, 1) * RAD_TO_DEG;\n const minZoom = Math.tan(camera.fov * DEG_TO_RAD * 0.5) / (halfHeight * camera.aspect);\n\n camera.restrictPitchRange(-restrictedPitch, restrictedPitch);\n camera.restrictZoomRange(minZoom, Infinity);\n camera.restrictRenderHeight(halfHeight * 2);\n }\n}\n\nexport default CylindricalProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/eac.frag\";\nimport { ROTATE } from \"../const/internal\";\n\n/**\n * Options for {@link EquiangularProjection}\n * @ko {@link EquiangularProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface EquiangularProjectionOptions extends ProjectionOptions {}\n\n/**\n * Equi-Angular Cubemap Projection.\n * This format is used by Youtube's 360 videos.\n * @ko Equi-Angular Cubemap 프로젝션.\n * 이 포맷은 주로 Youtube의 360 비디오에 사용됩니다.\n * @since 4.0.0\n * @category Projection\n */\nclass EquiangularProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n const geometry = new CubeGeometry({\n order: \"LFRDBU\",\n rotateUV: [\n ROTATE.ZERO, ROTATE.ZERO, ROTATE.ZERO,\n ROTATE.CW_90, ROTATE.CCW_90, ROTATE.CW_90\n ]\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default EquiangularProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass SphereGeometry extends Geometry {\n /** */\n public constructor() {\n // const radius = 1;\n const widthSegments = 60;\n const heightSegments = 60;\n const ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI;\n\n const uvs: number[] = [];\n const vertices: number[] = [];\n const indicies: number[] = [];\n let latIdx: number;\n let lngIdx: number;\n\n for (latIdx = 0; latIdx <= widthSegments; latIdx++) {\n const theta = (latIdx / widthSegments - 0.5) * Math.PI;\n const sinTheta = Math.sin(theta);\n const cosTheta = Math.cos(theta);\n\n for (lngIdx = 0; lngIdx <= heightSegments; lngIdx++) {\n const phi = (lngIdx / heightSegments - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN;\n const sinPhi = Math.sin(phi);\n const cosPhi = Math.cos(phi);\n const x = cosPhi * cosTheta;\n const y = sinTheta;\n const z = sinPhi * cosTheta;\n const u = lngIdx / heightSegments;\n const v = latIdx / widthSegments;\n\n uvs.push(u, v);\n vertices.push(x, y, z);\n\n if (lngIdx !== heightSegments && latIdx !== widthSegments) {\n const a = latIdx * (heightSegments + 1) + lngIdx;\n const b = a + heightSegments + 1;\n\n indicies.push(a, a + 1, b, b, a + 1, b + 1);\n }\n }\n }\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default SphereGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport Texture2D from \"../texture/Texture2D\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport SphereGeometry from \"../geometry/SphereGeometry\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link EquirectProjection}\n * @ko {@link EquirectProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface EquirectProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n}\n\n/**\n * Projection based on equirectangular projection.\n * @ko 등 장방형 도법(Equirectangular projection) 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass EquirectProjection extends Projection<{\n uTexture: UniformTexture2D\n}> {\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: EquirectProjectionOptions) {\n super(options);\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n\n const geometry = new SphereGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default EquirectProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"./Uniform\";\n\nclass UniformFloat extends Uniform {\n public val: number;\n\n public constructor(val: number) {\n super();\n\n this.val = val;\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation) {\n gl.uniform1f(location, this.val);\n\n this.needsUpdate = false;\n }\n}\n\nexport default UniformFloat;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass PlaneGeometry extends Geometry {\n /** */\n public constructor(width: number = 2, height: number = 2, z: number = -1) {\n const halfWidth = width * 0.5;\n const halfHeight = height * 0.5;\n const vertices = [\n -halfWidth, -halfHeight, z,\n halfWidth, -halfHeight, z,\n -halfWidth, halfHeight, z,\n halfWidth, halfHeight, z\n ];\n const indicies = [\n 0, 1, 2,\n 2, 1, 3\n ];\n const uvs = [\n 0, 0,\n 1, 0,\n 0, 1,\n 1, 1\n ];\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default PlaneGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport UniformFloat from \"../uniform/UniformFloat\";\nimport Camera from \"../core/Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport Texture2D from \"../texture/Texture2D\";\nimport PlaneGeometry from \"../geometry/PlaneGeometry\";\nimport vs from \"../shader/little-planet.vert\";\nimport fs from \"../shader/little-planet.frag\";\nimport TriangleMesh from \"../core/TriangleMesh\";\n\n/**\n * Options for {@link LittlePlanetProjection}\n * @ko {@link LittlePlanetProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface LittlePlanetProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n}\n\n/**\n * Projection based on so-called \"Little planet\" or \"Tiny planet\" effect.\n * @ko \"Little planet\" 혹은 \"Tiny planet\"로 불리는 이펙트 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass LittlePlanetProjection extends Projection<{\n uTexture: UniformTexture2D;\n uYaw: UniformFloat;\n uPitch: UniformFloat;\n uZoom: UniformFloat;\n}> {\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: LittlePlanetProjectionOptions) {\n super(options);\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n texture.wrapS = WebGLRenderingContext.REPEAT;\n texture.wrapT = WebGLRenderingContext.REPEAT;\n\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture),\n uYaw: new UniformFloat(0),\n uPitch: new UniformFloat(0.5),\n uZoom: new UniformFloat(1)\n };\n\n const geometry = new PlaneGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n\n public updateControl(control: PanoControl) {\n control.ignoreZoomScale = true;\n }\n\n public update(camera: Camera) {\n const mesh = this._mesh;\n if (!mesh) return;\n\n const uniforms = mesh.program.uniforms;\n\n uniforms.uYaw.val = camera.yaw / 360;\n // Range from 0 ~ 1\n uniforms.uPitch.val = (camera.pitch / 180) + 0.5;\n uniforms.uZoom.val = camera.zoom;\n\n uniforms.uYaw.needsUpdate = true;\n uniforms.uPitch.needsUpdate = true;\n uniforms.uZoom.needsUpdate = true;\n }\n}\n\nexport default LittlePlanetProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"./Uniform\";\n\nclass UniformVector4Array extends Uniform {\n public val: number[][];\n\n public constructor(val: number[][]) {\n super();\n\n this.val = val;\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation) {\n gl.uniform4fv(location, this.val.reduce((arr, vector) => [...arr, ...vector], []));\n\n this.needsUpdate = false;\n }\n}\n\nexport default UniformVector4Array;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport SphereGeometry from \"../geometry/SphereGeometry\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport UniformVector4Array from \"../uniform/UniformVector4Array\";\nimport UniformFloat from \"../uniform/UniformFloat\";\nimport vs from \"../shader/stereoequi.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link StereoEquiProjection}\n * @ko {@link StereoEquiProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface StereoEquiProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n /**\n * Stereoscopic mode of the image\n * @ko 이미지의 스테레오스코픽 모드\n * @since 4.0.0\n * @default \"top_bottom\"\n */\n mode: typeof StereoEquiProjection.MODE[keyof typeof StereoEquiProjection.MODE]\n}\n\n/**\n * Projection based on stereo equirectangular images.\n * @ko Stereo equirectangular 이미지 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass StereoEquiProjection extends Projection<{\n uTexture: UniformTexture2D;\n uEye: UniformFloat;\n uTexScaleOffset: UniformVector4Array;\n}> {\n /**\n * Available stereoscopic modes\n * @ko 사용가능한 스테레오스코픽 모드들\n * @since 4.0.0\n */\n public static MODE = {\n /**\n * @ko 이미지가 왼쪽/오른쪽으로 구성되어있을 경우\n * @since 4.0.0\n */\n LEFT_RIGHT: \"left_right\",\n /**\n * @ko 이미지가 위/아래로 구성되어있을 경우\n * @since 4.0.0\n */\n TOP_BOTTOM: \"top_bottom\",\n } as const;\n\n private _mode: StereoEquiProjectionOptions[\"mode\"];\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: StereoEquiProjectionOptions) {\n super(options);\n\n this._mode = options.mode;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n let leftEye: number[];\n let rightEye: number[];\n\n switch (this._mode) {\n case StereoEquiProjection.MODE.LEFT_RIGHT:\n leftEye = [0.5, 1, 0, 0];\n rightEye = [0.5, 1, 0.5, 0];\n break;\n default:\n // Default, uses \"top_bottom\"\n leftEye = [1, 0.5, 0, 0];\n rightEye = [1, 0.5, 0, 0.5];\n }\n\n\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture),\n uEye: new UniformFloat(0),\n uTexScaleOffset: new UniformVector4Array([leftEye, rightEye])\n };\n\n const geometry = new SphereGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default StereoEquiProjection;\n","import Component from \"@egjs/component\";\nimport View360 from \"../View360\";\n\n/**\n * @hidden\n */\nconst withMethods = (prototype: any, attr: string) => {\n [Component.prototype, View360.prototype].forEach(proto => {\n Object.getOwnPropertyNames(proto)\n .filter(name => name.charAt(0) !== \"_\" && name !== \"constructor\")\n .forEach((name: string) => {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name)!;\n\n if (descriptor.value) {\n // Public Function\n Object.defineProperty(prototype, name, {\n value: function(...args) {\n return descriptor.value.call(this[attr], ...args);\n }\n });\n } else {\n const getterDescriptor: { get?: () => any; set?: (val: any) => void } = {};\n if (descriptor.get) {\n getterDescriptor.get = function() {\n return this[attr] && descriptor.get?.call(this[attr]);\n };\n }\n if (descriptor.set) {\n getterDescriptor.set = function(...args) {\n return descriptor.set?.call(this[attr], ...args);\n };\n }\n\n Object.defineProperty(prototype, name, getterDescriptor);\n }\n });\n });\n};\n\nexport default withMethods;\n","/**\n * @hidden\n */\nexport const getValidProps = (propsObj: any) => {\n return Object.keys(propsObj).reduce((props, propName) => {\n if (propsObj[propName] != null) {\n props[propName] = propsObj[propName];\n }\n\n return props;\n }, {});\n};\n","export const VIEW360_METHODS = [\n \"destroy\",\n \"init\",\n \"load\",\n \"resize\",\n \"addPlugins\",\n \"removePlugins\",\n \"renderFrame\",\n // @egjs/component methods\n \"on\",\n \"hasOn\",\n \"once\",\n \"off\",\n \"trigger\"\n] as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360, { View360Options, View360Events } from \"./View360\";\n\nexport * from \"./core\";\nexport * from \"./control\";\nexport * from \"./plugin\";\nexport * from \"./projection\";\nexport * from \"./hotspot\";\nexport * from \"./const/external\";\nexport * from \"./type/external\";\nexport * from \"./cfc\";\n\nexport type {\n View360Options,\n View360Events\n};\n\nexport default View360;\n"],"names":["View360Error","Error","constructor","message","code","Object","setPrototypeOf","prototype","name","ERROR_CODES","WRONG_TYPE","WRONG_OPTION","ELEMENT_NOT_FOUND","CANVAS_NOT_FOUND","WEBGL_NOT_SUPPORTED","FAILED_CREATE_CONTEXT_2D","PROVIDE_PROJECTION_FIRST","FAILED_LINKING_PROGRAM","INSUFFICIENT_ARGS","MESSAGES","val","types","map","type","join","optionName","query","msg","shaderLog","CODES","EVENTS","MOUSE_DOWN","MOUSE_MOVE","MOUSE_UP","TOUCH_START","TOUCH_MOVE","TOUCH_END","WHEEL","RESIZE","CONTEXT_MENU","MOUSE_ENTER","MOUSE_LEAVE","POINTER_DOWN","POINTER_MOVE","POINTER_UP","POINTER_CANCEL","POINTER_ENTER","POINTER_LEAVE","KEY_DOWN","KEY_UP","LOAD","ERROR","CLICK","DOUBLE_CLICK","CONTEXT_CREATE_ERROR","CONTEXT_LOST","CONTEXT_RESTORED","DEVICE_ORIENTATION","DEVICE_MOTION","ORIENTATION_CHANGE","VIDEO_PLAY","VIDEO_PAUSE","VIDEO_LOADED_DATA","VIDEO_VOLUME_CHANGE","VIDEO_TIME_UPDATE","VIDEO_DURATION_CHANGE","VIDEO_CAN_PLAYTHROUGH","TRANSITION_END","XR_END","EL_DIV","EL_BUTTON","MOUSE_BUTTON","CURSOR","GRAB","GRABBING","NONE","KEY_DIRECTION","DIRECTION_KEY_CODE","SPACE_KEY_CODE","DIRECTION_KEY_NAME","LEFT","UP","RIGHT","DOWN","SPACE_KEY_NAME","FULLSCREEN_REQUEST","FULLSCREEN_ELEMENT","FULLSCREEN_EXIT","FULLSCREEN_CHANGE","DEFAULT_CLASS","CONTAINER","CANVAS","CTX_LOST","IN_VR","HOTSPOT_CONTAINER","HOTSPOT","HOTSPOT_VISIBLE","HOTSPOT_FLIP_X","HOTSPOT_FLIP_Y","READY","LOAD_START","PROJECTION_CHANGE","BEFORE_RENDER","RENDER","INPUT_START","INPUT_END","VIEW_CHANGE","STATIC_CLICK","VR_START","VR_END","EASING","LINEAR","x","SINE_WAVE","Math","sin","PI","EASE_OUT_CUBIC","pow","EASE_OUT_BOUNCE","n1","d1","CAMERA_EVENTS","CHANGE","ANIMATION_END","CONTROL_EVENTS","ENABLE","DISABLE","DEG_TO_RAD","RAD_TO_DEG","DEFAULT_EASING","DEFAULT_ANIMATION_DURATION","INFINITE_RANGE","min","Infinity","max","DEFAULT_PITCH_RANGE","DEFAULT_ZOOM_RANGE","ROTATE","VIDEO_TIME_CHANGE_EVENT","SVG_NAMESPACE","SESSION_VR","XR_REFERENCE_SPACE","EPSILON","_a","Number","isString","isElement","nodeType","Node","ELEMENT_NODE","createElement","className","tag","BROWSER","el","document","classList","add","getNullableElement","parent","targetEl","parentEl","queryResult","querySelector","getElement","findCanvas","root","selector","canvas","range","end","Array","apply","undef","idx","clamp","lerp","a","b","t","circulate","size","abs","offset","findIndex","array","checker","length","getObjectOption","toVerticalFov","fovRadian","aspect","atan","tan","reorderCube","arr","order","defaultOrder","split","face","indexOf","index","isFullscreen","key","sensorCanBeEnabledIOS","DeviceMotionEvent","window","isSecureContext","hfovToZoom","baseFov","fov","renderingWidth","zoomedWidth","eulerToQuat","out","yaw","pitch","roll","quat","identity","pitchThreshold","pitchClamped","rotateY","rotateX","rotateZ","quatToEuler","quaternion","y","z","w","x2","y2","z2","w2","unit","test","atan2","view","vec3","fromValues","up","transformQuat","viewXZ","sqrt","Motion","_val","start","_start","_end","progress","_progress","activated","_activated","duration","_duration","loop","_loop","_range","easing","_easing","reset","update","deltaTime","prev","nextProgress","easedProgress","defaultVal","delta","setNewEndByDelta","setRange","CameraAnimation","_motion","camera","from","to","_camera","_from","_to","_finishPromise","Promise","resolve","_finish","getFinishPromise","motion","rotation","create","zoom","slerp","rotate","Camera","Component","_aspect","changed","_changed","yawRange","_initialYawRange","pitchRange","_initialPitchRange","zoomRange","_initialZoomRange","initialYaw","initialPitch","initialZoom","rollOffset","position","animation","_up","_yawRange","_pitchRange","_zoomRange","_updateQuaternion","viewMatrix","mat4","projectionMatrix","_maxRenderHeight","destroy","off","resize","width","height","prevAspect","updateMatrix","lookAt","prevQuaternion","clone","prevZoom","zoomDiff","equals","normalized","normalize","isSameRotation","copy","animateTo","finishPromise","then","trigger","restrictYawRange","restrictPitchRange","restrictZoomRange","restrictRenderHeight","resetRange","getYawRange","yawLimit","maxRenderHeight","halfHFov","getHorizontalFov","minYaw","maxYaw","halfVFovRad","h","d","theta","getPitchRange","pitchLimit","minPitch","maxPitch","halfVFov","getVerticalFov","getZoomRange","limit","minFov","maxFov","currentFov","current","_getZoomedHorizontalFov","hFov","vFov","fovToZoom","projMatrix","upDir","viewDir","perspective","onFrameRender","MouseInput","_onMouseDown","evt","_el","button","preventDefault","focus","_prevPos","clientX","clientY","addEventListener","_onMouseMove","_onMouseUp","srcEvent","isTouch","isKeyboard","prevPos","deltaX","deltaY","removeEventListener","scrolling","enable","element","disable","TouchInput","scrollable","_scrollable","_onTouchStart","touches","_scrolling","touch","_isFirstTouch","_onTouchMove","cancelable","_onTouchEnd","passive","KeyboardInput","active","pressed","_pressed","_onKeyDown","location","KeyboardEvent","DOM_KEY_LOCATION_STANDARD","_updateKeyPress","pressedCount","_getPressedKeyCount","repeat","_onKeyUp","_clearPressedKeys","_getDeltaByPressedKeys","reduce","obj","keyName","assign","event","isEnable","keyToUpdate","keyCode","filter","RotateControl","enabled","_enabled","enableBlocked","_enableBlocked","animating","_keyboardInput","_xMotion","_yMotion","_touchInput","pointerScale","_pointerScale","keyboardScale","_keyboardScale","disablePitch","_disablePitch","disableYaw","_disableYaw","disableKeyboard","_disableKeyboard","controlEl","_onInputStart","_changedWhileDragging","inputType","_onChange","invZoomScale","_zoomScale","screenScale","_screenScale","scale","scaledX","scaledY","_onInputEnd","_controlEl","_mouseInput","_bindInputs","xMotion","yMotion","keyboardInput","updateRange","setZoomScale","hfov","vfov","control","updateCursor","sync","mouseInput","touchInput","on","WheelInput","_onWheel","stopPropagation","_inputTimer","_clearTimer","_baseScale","setTimeout","capture","clearTimeout","PinchInput","prevDistance","_prevDistance","diff","pageX","pageY","distance","ZoomControl","_wheelInput","_scale","scaledDelta","_pinchInput","wheelInput","pinchInput","ROTATE_CONSTANT","PITCH_DELTA","YAW_DELTA_BY_ROLL","YAW_DELTA_BY_YAW","targetAxis","meshPoint","GyroInput","orientationUpdated","_orientationUpdated","ignoreRoll","_ignoreRoll","_onDeviceOrientation","prevOrientation","_orientation","alpha","beta","gamma","_needsCalibrate","_calibrateSensor","_updateScreenOrientation","screen","orientation","angle","undefined","_screenOrientation","_yawOrigin","_yawOffset","_updateRotation","collectDelta","prevRotation","_toEulerDelta","setInitialRotation","yawOrigin","sensorYaw","screenAngle","world","set","cos","multiply","prevQuat","currentQuat","_getDeltaYaw","_getDeltaPitch","prvQ","curQ","yawDeltaByYaw","_getRotationDelta","yawDeltaByRoll","_extractPitchFromQuat","prevQ","rotateKind","curQuaternion","prevPoint","curPoint","rotateDistance","dot","cross","rotateDirection","meshPoint2","meshPoint3","vecU","vecV","vecN","coefficientA","coefficientB","coefficientC","projectedPrevPoint","subtract","trigonometricRatio","acos","crossVec","thetaDirection","deltaRadian","baseV","GyroControl","_input","isAvailable","onDeviceMotionChange","listenDeviceMotion","res","rotationRate","timeout","race","available","requestSensorPermission","requestPermission","permissionState","catch","_updateYawPitch","input","yawDelta","pitchDelta","PanoControl","useGrabCursor","_useGrabCursor","_setCursor","disableContextMenu","_disableContextMenu","_blockContextMenu","_restoreContextMenu","_rotateControl","wheelScrollable","_zoomControl","ignoreZoomScale","_ignoreZoomScale","gyro","_gyroControl","_preventContextMenu","_onEnable","_onDisable","_onCameraAnimationEnd","_bindEvents","rotateControl","zoomControl","gyroControl","zoomScale","newCursor","style","cursor","Texture","flipY","wrapS","WebGLRenderingContext","CLAMP_TO_EDGE","wrapT","isVideo","isCube","Texture2D","source","TextureVideo","video","pause","removeAttribute","load","isPaused","paused","ended","readyState","hasAudio","audioTracks","webkitAudioDecodedByteCount","mozHasAudio","TextureCube","sources","TextureLoader","_loadChecker","ImReady","src","loadVideo","isArray","loadCubeImage","imgSrc","loadImage","images","_toImageArray","_load","image","naturalWidth","naturalHeight","videoConfig","config","autoplay","muted","volume","_toVideoElement","currentTime","play","videoWidth","videoHeight","content","onLoad","loader","reject","once","errorCount","check","srcs","imgEl","Image","crossOrigin","HTMLVideoElement","playsInline","setAttribute","forEach","_appendSourceElement","sourceCount","querySelectorAll","HTMLSourceElement","sourceEl","appendChild","FrameAnimator","maxDeltaTime","context","_context","_rafId","_rafTimer","_lastUpdateTime","callback","_time","frame","time","Date","now","requestAnimationFrame","stop","cancelAnimationFrame","changeContext","AutoResizer","useResizeObserver","_useResizeObserver","onResize","_skipFirstResize","isFirstResize","_onResize","_resizeObserver","ResizeObserver","bbox","getBoundingClientRect","resizeImmediate","resizeObserver","observe","disconnect","Autoplay","playing","_interrupted","delay","_delay","delayOnMouseLeave","_delayOnMouseLeave","speed","_speed","pauseOnHover","_pauseOnHover","canInterrupt","_canInterrupt","disableOnInterrupt","_disableOnInterrupt","viewer","options","_clearTimeout","_setUninterruptedAfterDelay","_onGyroEnable","_onMouseEnter","_hovering","_onMouseLeave","_control","_element","_interruptionTimer","enableAfterDelay","XRManager","ctx","exit","_onSessionEnd","_xrSession","_xrRefSpace","_ctx","_options","xr","navigator","isSessionSupported","enter","requiredFeatures","makeXRCompatible","session","requestSession","bindXRLayer","refSpace","requestReferenceSpace","_setSession","xrSession","canRender","pose","getViewerPose","getEyeParams","glLayer","renderState","baseLayer","views","viewport","getViewport","vMatrix","transform","inverse","matrix","pMatrix","Hotspot","HotspotRenderer","rootEl","renderer","_containerEl","_renderer","_hotspots","_zoom","refresh","container","hotspotEls","slice","_parseHotspot","render","hotspots","halfWidth","halfHeight","centerTransform","zoomTransform","hotspot","relPos","transformMat4","remove","screenPos","vec2","yawStr","dataset","pitchStr","positionStr","parseFloat","_yawPitchToVec3","pos","defaultPos","yawRad","pitchRad","VertexArrayObject","count","geometry","indicies","buffers","WebGLContext","_canvas","maxTextureSize","_maxTextureSize","isWebGL2","_isWebGL2","supportVAO","_extensions","vao","lost","_contextLost","debug","_debug","_onContextLost","_onContextRestore","loseContext","init","gl","_getContext","_gl","getParameter","MAX_TEXTURE_SIZE","getExtension","bindBuffer","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","forceLoseContext","extension","forceRestoreContext","restoreContext","clear","COLOR_BUFFER_BIT","drawingBufferWidth","drawingBufferHeight","createVAO","shaderProgram","nativeVAO","_createNativeVAO","_createBuffer","uv","_bindNativeVAO","_supplyGeometryData","_unbindBuffers","draw","drawElements","TRIANGLES","UNSIGNED_SHORT","releaseVAO","_deleteNativeVAO","_deleteBuffer","getUniformLocations","program","uniforms","uniformLocations","keys","locations","getUniformLocation","_getCommonUniformLocations","updateCommonUniforms","entity","mvMatrix","uniformMatrix4fv","uMVMatrix","uPMatrix","updateVRUniforms","eyeIndex","uEye","uniform1f","updateUniforms","uniform","needsUpdate","releaseShaderResources","deleteProgram","useProgram","createProgram","vertexShader","fragmentShader","vs","_compileShader","VERTEX_SHADER","fs","FRAGMENT_SHADER","attachShader","bindAttribLocation","linkProgram","getProgramParameter","LINK_STATUS","getShaderParameter","COMPILE_STATUS","getShaderInfoLog","getProgramInfoLog","deleteShader","createWebGLTexture","texData","texture","createTexture","bindTexture","TEXTURE_2D","texParameteri","TEXTURE_MIN_FILTER","TEXTURE_MAG_FILTER","TEXTURE_WRAP_S","TEXTURE_WRAP_T","gl2","texStorage2D","RGBA8","createWebGLCubeTexture","TEXTURE_CUBE_MAP","attributes","getContextAttributes","xrCompatible","xrLayer","XRWebGLLayer","updateRenderState","bindXRFrame","bindFramebuffer","FRAMEBUFFER","framebuffer","useDefaultFrameBuffer","createBuffer","buffer","deleteBuffer","createVertexArray","ext","createVertexArrayOES","bindVertexArray","bindVertexArrayOES","deleteVertexArray","deleteVertexArrayOES","_supplyIndiciesData","_supplyAttributeData","vertices","uvs","bufferData","data","STATIC_DRAW","attribute","attribLocation","getAttribLocation","vertexAttribPointer","itemSize","FLOAT","enableVertexAttribArray","shader","createShader","shaderSource","compileShader","webglIdentifiers","contextAttributes","preserveDrawingBuffer","antialias","onWebglContextCreationError","e","statusMessage","identifier","getContext","WebGLRenderer","_elementSize","pixelRatio","_pixelRatio","canvasSize","devicePixelRatio","clientWidth","clientHeight","projection","mesh","getMesh","renderVR","vr","eyeParams","eye","View360","_rootEl","_vr","_hotspot","plugins","_plugins","_projection","_initialized","initialized","_autoplay","autoInit","_autoInit","autoResize","_autoResize","canvasSelector","_canvasSelector","tabIndex","_tabIndex","_animator","updateCamera","renderFrame","autoPlayer","_emit","_renderFrameOnDemand","getTexture","_renderVRFrame","_delta","_autoResizer","_addEventHandlers","releaseAllResources","plugin","animator","_bindComponentEvents","_resizeComponents","_loadTexture","_applyProjection","hasAttribute","addPlugins","push","removePlugins","pluginIdx","splice","eventName","params","evtParams","target","prevProjection","applyTexture","updateControl","contentLoader","events","evtName","controlEventsToPropagate","VERSION","Object3D","fromRotationTranslationScale","LoadingSpinner","_startLoading","_container","_detachElements","parentElement","removeChild","_createElements","ring","RING","ControlBarItem","CONTROL_BAR_DEFAULT_CLASS","CONTROLS_ROOT","CONTROLS_BG","CONTROLS_MAIN","CONTROLS_TOP","CONTROLS_BOTTOM","CONTROLS_MID","CONTROLS_LEFT","CONTROLS_RIGHT","CONTROLS_FLOAT_LEFT","CONTROLS_FLOAT_RIGHT","CONTROLS_BUTTON","PROGRESS_ROOT","VOLUME_ROOT","RANGE_ROOT","RANGE_TRACK","RANGE_THUMB","RANGE_FILLER","PLAY_BUTTON","PAUSE_BUTTON","UNMUTED_BUTTON","MUTED_BUTTON","FULLSCREEN_BUTTON","FULLSCREEN_EXIT_BUTTON","VR_BUTTON","GYRO_ENABLED","GYRO_DISABLED","VIDEO_TIME_DISPLAY","PIEVIEW_ROOT","FIXED","UNAVAILABLE","HIDDEN","CONTROL_BAR_ITEM_POSITION","TOP_LEFT","TOP_RIGHT","MAIN_TOP","MAIN_BOTTOM","MAIN_LEFT","MAIN_RIGHT","RangeControl","_onHold","_bbox","elX","scrollX","pageXOffset","clamepdX","thumbEl","_fixedClass","clampedX","_onRelease","track","thumb","filler","draggable","trackEl","fillerEl","left","right","bottom","top","updateStyle","clampedProgress","ProgressBar","_rangeControl","_onTimeUpdate","_video","_currentTime","_onDurationChange","controlBar","_controlBar","dispatchEvent","CustomEvent","detail","_wasPaused","_playPromise","_onControl","rangeControl","unavailableClass","PlayButton","_onClick","_paused","_onPlay","title","_onPause","VolumeControl","_updateDisplay","disabled","_onVolumeChange","_buttonEl","containerEl","buttonEl","FullscreenButton","_targetEl","_exitFullscreen","_requestFullscreen","_onFullscreenChange","_fullscreenAvailable","_addFullscreenHandlers","_removeFullscreenHandlers","some","request","call","VideoTime","_onCustomTimeChange","timeMinute","floor","timeSeconds","timeSecondsFormatted","durationMinute","durationSeconds","durationSecondsFormatted","innerText","PieView","resetCamera","_viewer","_updatePie","piePath","_piePathEl","rangeCircle","_rangeCircleEl","halfFov","pieRadius","pieDeg","pieOffset","isFinite","radius","rangeDiff","_createPieElements","rootClass","pieSVG","createElementNS","VRButton","GyroButton","_updateStyle","enableButton","AutoHide","hidden","contains","_hiddenClass","initialDelay","idleDelay","activationDelay","_isCursorInside","show","_hideAfterDelay","_isFullscreen","showTemporaliy","_isGrabbing","pointerType","_onVideoPlay","_onVideoPause","_initialDelay","_idleDelay","_timer","hide","_clearHideTimer","VideoControl","videoEl","keyPressed","_changeVideoTime","_changeVideoVolume","spacePressed","_toggleVideo","forward","increase","ControlBar","backgroundEl","_bgEl","items","_items","customItems","_customItems","autoHide","showBackground","clickToPlay","keyboardControls","progressBar","playButton","volumeButton","fullscreenButton","videoTime","pieView","vrButton","gyroButton","_onStaticClick","autoHider","_autoHider","_onNewSrcLoad","_updateBackground","_updateAutoHide","_updateKeyboardHandler","category","item","_createPositionWrappers","POSITION","_videoControl","panoRoot","controlsRoot","defaultItems","_createDefaultItems","_addItem","_clearItemElements","wrapper","_wrapperEl","nextSiblingIndex","sibling","nextSibling","insertBefore","floatLeftEl","floatRightEl","topWrapper","bottomWrapper","midWrapper","leftControlsWrapper","rightControlsWrapper","wrappers","firstChild","background","hiddenClass","_b","videoControl","Projection","_mesh","uTexture","Uniform","UniformTextureCube","cubemapOrder","_webglTexture","_cubemapOrder","deleteTexture","pixelStorei","UNPACK_FLIP_Y_WEBGL","uniform1i","activeTexture","TEXTURE0","texSubImage2D","TEXTURE_CUBE_MAP_POSITIVE_X","RGBA","UNSIGNED_BYTE","texImage2D","CubeTexturePainter","_size","_renderingOrder","_calcRenderingSize","surfaceIdx","row","_row","column","_column","renderingFace","drawImage","UniformCanvasCube","_painter","TriangleMesh","ShaderProgram","VertexData","Geometry","Float32Array","Uint16Array","CubeGeometry","rotateUV","oneThird","coords","r","c","coord","degree","ZERO","newOrder","CW_90","CCW_90","newCoords","uvIdx","acc","concat","CubemapProjection","cubemapFlipX","_cubemapFlipX","UniformTexture2D","CubestripProjection","CylinderGeometry","maxTheta","radialSegments","heightSegments","invRadialSegments","angleConst","yIdx","lngIdx","u","v","CylindricalProjection","partial","_partial","cylinderHeight","cylinderTheta","restrictedYaw","restrictedPitch","minZoom","EquiangularProjection","SphereGeometry","widthSegments","ANGLE_CORRECTION_FOR_CENTER_ALIGN","latIdx","sinTheta","cosTheta","phi","sinPhi","cosPhi","EquirectProjection","UniformFloat","PlaneGeometry","LittlePlanetProjection","REPEAT","uYaw","uPitch","uZoom","UniformVector4Array","uniform4fv","vector","StereoEquiProjection","_mode","mode","leftEye","rightEye","MODE","LEFT_RIGHT","uTexScaleOffset","TOP_BOTTOM","withMethods","attr","proto","getOwnPropertyNames","charAt","descriptor","getOwnPropertyDescriptor","value","defineProperty","args","getterDescriptor","get","getValidProps","propsObj","props","propName","VIEW360_METHODS"],"mappings":"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"} \ No newline at end of file diff --git a/demo/release/4.0.0-beta.4/dist/view360.js b/demo/release/4.0.0-beta.4/dist/view360.js new file mode 100644 index 000000000..eef9ec416 --- /dev/null +++ b/demo/release/4.0.0-beta.4/dist/view360.js @@ -0,0 +1,7825 @@ +/* +Copyright (c) 2023-present NAVER Corp. +name: @egjs/view360 +license: MIT +author: NAVER Corp. +repository: https://github.com/naver/egjs-view360 +version: 4.0.0-beta.4 +*/ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@egjs/component'), require('gl-matrix'), require('@egjs/imready')) : + typeof define === 'function' && define.amd ? define(['@egjs/component', 'gl-matrix', '@egjs/imready'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.View360 = factory(global.Component, global.glMatrix, global.eg.ImReady)); +})(this, (function (Component, glMatrix, ImReady) { 'use strict'; + + function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; } + + var Component__default = /*#__PURE__*/_interopDefault(Component); + var ImReady__default = /*#__PURE__*/_interopDefault(ImReady); + + /****************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function (resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Error thrown by {@link View360} + * @ko {@link View360}이 발생시킨 에러 + * @since 4.0.0 + */ + class View360Error extends Error { + /** + * Create new instance of View360Error + * @ko View360Error의 인스턴스를 생성합니다. + * @param message - Error message {@ko 에러 메시지} + * @param code - Error code {@ko 에러 코드} + */ + constructor(message, code) { + super(message); + Object.setPrototypeOf(this, View360Error.prototype); + this.name = "View360Error"; + this.code = code; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Error codes of {@link View360Error} + * @ko {@link View360Error}가 가질 수 있는 에러 코드 값들 + * @since 4.0.0 + */ + const ERROR_CODES = { + /** + * The given value's type is not expected + * @ko 주어진 값의 타입이 잘못되었을 경우 + * @since 4.0.0 + */ + WRONG_TYPE: 0, + /** + * The given value is not a supported option + * @ko 잘못된 옵션을 받았을 경우 + * @since 4.0.0 + */ + WRONG_OPTION: 1, + /** + * The element with given CSS selector does not exist + * @ko 주어진 CSS 셀렉터로 엘리먼트를 찾지 못했을 경우 + * @since 4.0.0 + */ + ELEMENT_NOT_FOUND: 2, + /** + * Couldn't find canvas element inside the given container element. + * @ko 컨테이너 엘리먼트 내부에서 캔버스 엘리먼트를 찾지 못했을 경우 + * @since 4.0.0 + */ + CANVAS_NOT_FOUND: 3, + /** + * The browser does not support WebGL + * @ko 브라우저가 WebGL을 지원하지 않는 경우 + * @since 4.0.0 + */ + WEBGL_NOT_SUPPORTED: 4, + /** + * Failed creating canvas 2D context + * @ko 캔버스 2D 컨텍스트를 생성하지 못한 경우 + * @since 4.0.0 + */ + FAILED_CREATE_CONTEXT_2D: 5, + /** + * `init()` is called before setting {@link View360Options#projection} + * @ko {@link View360Options#projection}을 설정하기 전에 `init()`이 호출된 경우 + * @since 4.0.0 + */ + PROVIDE_PROJECTION_FIRST: 6, + /** + * Failed linking WebGL program. Only can be thrown when {@link View360Options#debug} is `true`. + * @ko WebGL 프로그램 링크에 실패한 경우. {@link View360Options#debug}를 `true`로 설정한 경우에만 발생할 수 있습니다. + * @since 4.0.0 + */ + FAILED_LINKING_PROGRAM: 7, + /** + * Arguments are not sufficient for the given property. + * @ko 프로퍼티에 값이 충분히 주어지지 않았을 때 + * @since 4.0.0 + */ + INSUFFICIENT_ARGS: 8 + }; + const MESSAGES = { + WRONG_TYPE: (val, types) => `${typeof val} is not a ${types.map(type => `"${type}"`).join(" or ")}.`, + WRONG_OPTION: (val, optionName) => `Bad option: given "${val}" for option "${optionName}".`, + ELEMENT_NOT_FOUND: query => `Element with selector "${query}" not found.`, + CANVAS_NOT_FOUND: "The canvas element was not found inside the given root element.", + WEBGL_NOT_SUPPORTED: "WebGL is not supported on this browser.", + FAILED_CREATE_CONTEXT_2D: "Failed to create canvas 2D context", + PROVIDE_PROJECTION_FIRST: "\"projection\" should be provided before initialization.", + FAILED_LINKING_PROGRAM: (msg, shaderLog) => `Failed linking WebGL program - "${msg}\nShader compile Log: ${shaderLog}`, + INSUFFICIENT_ARGS: (val, name) => `Insufficient arguments: given "${val}" for "${name}".` + }; + var ERROR = { + CODES: ERROR_CODES, + MESSAGES + }; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + const EVENTS$1 = { + MOUSE_DOWN: "mousedown", + MOUSE_MOVE: "mousemove", + MOUSE_UP: "mouseup", + TOUCH_START: "touchstart", + TOUCH_MOVE: "touchmove", + TOUCH_END: "touchend", + WHEEL: "wheel", + RESIZE: "resize", + CONTEXT_MENU: "contextmenu", + MOUSE_ENTER: "mouseenter", + MOUSE_LEAVE: "mouseleave", + POINTER_DOWN: "pointerdown", + POINTER_MOVE: "pointermove", + POINTER_UP: "pointerup", + POINTER_CANCEL: "pointercancel", + POINTER_ENTER: "pointerenter", + POINTER_LEAVE: "pointerleave", + KEY_DOWN: "keydown", + KEY_UP: "keyup", + LOAD: "load", + ERROR: "error", + CLICK: "click", + DOUBLE_CLICK: "dblclick", + CONTEXT_CREATE_ERROR: "webglcontextcreationerror", + CONTEXT_LOST: "webglcontextlost", + CONTEXT_RESTORED: "webglcontextrestored", + DEVICE_ORIENTATION: "deviceorientation", + DEVICE_MOTION: "devicemotion", + ORIENTATION_CHANGE: "orientationchange", + VIDEO_PLAY: "play", + VIDEO_PAUSE: "pause", + VIDEO_LOADED_DATA: "loadeddata", + VIDEO_VOLUME_CHANGE: "volumechange", + VIDEO_TIME_UPDATE: "timeupdate", + VIDEO_DURATION_CHANGE: "durationchange", + VIDEO_CAN_PLAYTHROUGH: "canplaythrough", + TRANSITION_END: "transitionend", + XR_END: "end" + }; + const EL_DIV = "div"; + const EL_BUTTON = "button"; + // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button + var MOUSE_BUTTON; + (function (MOUSE_BUTTON) { + MOUSE_BUTTON[MOUSE_BUTTON["LEFT"] = 0] = "LEFT"; + MOUSE_BUTTON[MOUSE_BUTTON["MIDDLE"] = 1] = "MIDDLE"; + MOUSE_BUTTON[MOUSE_BUTTON["RIGHT"] = 2] = "RIGHT"; + })(MOUSE_BUTTON || (MOUSE_BUTTON = {})); + const CURSOR = { + GRAB: "grab", + GRABBING: "grabbing", + NONE: "" + }; + const KEY_DIRECTION = ["LEFT", "UP", "RIGHT", "DOWN"]; + var DIRECTION_KEY_CODE; + (function (DIRECTION_KEY_CODE) { + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["LEFT"] = 37] = "LEFT"; + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["UP"] = 38] = "UP"; + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["RIGHT"] = 39] = "RIGHT"; + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["DOWN"] = 40] = "DOWN"; + })(DIRECTION_KEY_CODE || (DIRECTION_KEY_CODE = {})); + const SPACE_KEY_CODE = 32; + const DIRECTION_KEY_NAME = { + LEFT: "ArrowLeft", + UP: "ArrowUp", + RIGHT: "ArrowRight", + DOWN: "ArrowDown" + }; + const SPACE_KEY_NAME = " "; + const FULLSCREEN_REQUEST = ["requestFullscreen", "webkitRequestFullscreen", "webkitRequestFullScreen", "webkitCancelFullScreen", "mozRequestFullScreen", "msRequestFullscreen"]; + const FULLSCREEN_ELEMENT = ["fullscreenElement", "webkitFullscreenElement", "webkitCurrentFullScreenElement", "mozFullScreenElement", "msFullscreenElement"]; + const FULLSCREEN_EXIT = ["exitFullscreen", "webkitExitFullscreen", "webkitCancelFullScreen", "mozCancelFullScreen", "msExitFullscreen"]; + const FULLSCREEN_CHANGE = ["fullscreenchange", "webkitfullscreenchange", "mozfullscreenchange", "MSFullscreenChange"]; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Default class names + * @ko 기본 클래스 이름들 + * @since 4.0.0 + */ + const DEFAULT_CLASS = { + CONTAINER: "view360-container", + CANVAS: "view360-canvas", + CTX_LOST: "view360-ctx-lost", + IN_VR: "view360-vr-presenting", + HOTSPOT_CONTAINER: "view360-hotspots", + HOTSPOT: "view360-hotspot", + HOTSPOT_VISIBLE: "view360-hotspot-visible", + HOTSPOT_FLIP_X: "view360-hotspot-flip-x", + HOTSPOT_FLIP_Y: "view360-hotspot-flip-y" + }; + /** + * Event names + * @ko 이벤트 이름들 + * @since 4.0.0 + * @example + * ```ts + * import View360, { EVENTS } from "@egjs/view360"; + * + * const viewer = new View360("#el_id"); + * + * viewer.on(EVENTS.READY, evt => { + * console.log("View360 is ready!"); + * }); + * ``` + */ + const EVENTS = { + READY: "ready", + LOAD_START: "loadStart", + LOAD: "load", + PROJECTION_CHANGE: "projectionChange", + RESIZE: "resize", + BEFORE_RENDER: "beforeRender", + RENDER: "render", + INPUT_START: "inputStart", + INPUT_END: "inputEnd", + VIEW_CHANGE: "viewChange", + STATIC_CLICK: "staticClick", + VR_START: "vrStart", + VR_END: "vrEnd" + }; + /** + * Collection of predefined easing functions + * @ko 미리 정의된 easing 함수들 + */ + const EASING = { + LINEAR: x => x, + SINE_WAVE: x => Math.sin(x * Math.PI * 2), + EASE_OUT_CUBIC: x => 1 - Math.pow(1 - x, 3), + EASE_OUT_BOUNCE: x => { + const n1 = 7.5625; + const d1 = 2.75; + if (x < 1 / d1) { + return n1 * x * x; + } else if (x < 2 / d1) { + return n1 * (x -= 1.5 / d1) * x + 0.75; + } else if (x < 2.5 / d1) { + return n1 * (x -= 2.25 / d1) * x + 0.9375; + } else { + return n1 * (x -= 2.625 / d1) * x + 0.984375; + } + } + }; + + var _a; + const CAMERA_EVENTS = { + CHANGE: "change", + ANIMATION_END: "animationEnd" + }; + const CONTROL_EVENTS = { + INPUT_START: "inputStart", + CHANGE: "change", + INPUT_END: "inputEnd", + ENABLE: "enable", + DISABLE: "disable", + STATIC_CLICK: "staticClick" + }; + const DEG_TO_RAD = Math.PI / 180; + const RAD_TO_DEG = 180 / Math.PI; + const DEFAULT_EASING = EASING.EASE_OUT_CUBIC; + const DEFAULT_ANIMATION_DURATION = 300; + const INFINITE_RANGE = { + min: -Infinity, + max: Infinity + }; + const DEFAULT_PITCH_RANGE = { + min: -90, + max: 90 + }; + const DEFAULT_ZOOM_RANGE = { + min: 0.6, + max: 10 + }; + var ROTATE; + (function (ROTATE) { + ROTATE[ROTATE["ZERO"] = 0] = "ZERO"; + ROTATE[ROTATE["CW_90"] = 1] = "CW_90"; + ROTATE[ROTATE["CCW_90"] = 2] = "CCW_90"; + ROTATE[ROTATE["CW_180"] = 3] = "CW_180"; + })(ROTATE || (ROTATE = {})); + // Custom event name for video time change + const VIDEO_TIME_CHANGE_EVENT = "view360videotimechange"; + const SVG_NAMESPACE = "http://www.w3.org/2000/svg"; + const SESSION_VR = "immersive-vr"; + const XR_REFERENCE_SPACE = "local"; + const EPSILON = (_a = Number.EPSILON) !== null && _a !== void 0 ? _a : 2.220446049250313e-16; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + const isString = val => typeof val === "string"; + const isElement = val => !!val && val.nodeType === Node.ELEMENT_NODE; + const createElement = (className, tag = EL_DIV) => { + const el = document.createElement(tag); + el.classList.add(className); + return el; + }; + const getNullableElement = (el, parent) => { + let targetEl = null; + if (isString(el)) { + const parentEl = parent ? parent : document; + const queryResult = parentEl.querySelector(el); + if (!queryResult) { + return null; + } + targetEl = queryResult; + } else if (isElement(el)) { + targetEl = el; + } + return targetEl; + }; + const getElement = (el, parent) => { + const targetEl = getNullableElement(el, parent); + if (!targetEl) { + if (isString(el)) { + throw new View360Error(ERROR.MESSAGES.ELEMENT_NOT_FOUND(el), ERROR.CODES.ELEMENT_NOT_FOUND); + } else { + throw new View360Error(ERROR.MESSAGES.WRONG_TYPE(el, ["HTMLElement", "string"]), ERROR.CODES.WRONG_TYPE); + } + } + return targetEl; + }; + const findCanvas = (root, selector) => { + const canvas = root.querySelector(selector); + if (!canvas) { + throw new View360Error(ERROR.MESSAGES.CANVAS_NOT_FOUND, ERROR.CODES.CANVAS_NOT_FOUND); + } + return canvas; + }; + const range = end => { + if (!end || end <= 0) { + return []; + } + return Array.apply(0, Array(end)).map((undef, idx) => idx); + }; + const clamp = (x, min, max) => Math.max(Math.min(x, max), min); + // Linear interpolation between a and b + const lerp = (a, b, t) => { + return a * (1 - t) + b * t; + }; + const circulate = (val, min, max) => { + const size = Math.abs(max - min); + if (val < min) { + const offset = (min - val) % size; + val = max - offset; + } else if (val > max) { + const offset = (val - max) % size; + val = min + offset; + } + return val; + }; + // eslint-disable-next-line @typescript-eslint/ban-types + const merge = (target, ...srcs) => { + srcs.forEach(source => { + Object.keys(source).forEach(key => { + const value = source[key]; + if (Array.isArray(target[key]) && Array.isArray(value)) { + target[key] = [...target[key], ...value]; + } else { + target[key] = value; + } + }); + }); + return target; + }; + const findIndex = (array, checker) => { + for (let idx = 0; idx < array.length; idx++) { + if (checker(array[idx])) { + return idx; + } + } + return -1; + }; + const getObjectOption = val => typeof val === "object" ? val : {}; + const toVerticalFov = (fovRadian, aspect) => { + return Math.atan(Math.tan(fovRadian * 0.5) / aspect) * 2; + }; + const reorderCube = (arr, order, defaultOrder = "RLUDFB") => { + return defaultOrder.split("").map(face => order.indexOf(face)).map(index => arr[index]); + }; + const isFullscreen = () => { + if (!document) return false; + for (const key of FULLSCREEN_ELEMENT) { + if (document[key]) return true; + } + return false; + }; + const sensorCanBeEnabledIOS = () => { + return !!DeviceMotionEvent && "requestPermission" in DeviceMotionEvent && window.isSecureContext; + }; + const hfovToZoom = (baseFov, fov) => { + const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5); + const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5); + return renderingWidth / zoomedWidth; + }; + const eulerToQuat = (out, yaw, pitch, roll) => { + glMatrix.quat.identity(out); + const pitchThreshold = 0.01; + const pitchClamped = clamp(pitch, -90 + pitchThreshold, 90 - pitchThreshold); + glMatrix.quat.rotateY(out, out, yaw * DEG_TO_RAD); + glMatrix.quat.rotateX(out, out, pitchClamped * DEG_TO_RAD); + glMatrix.quat.rotateZ(out, out, roll * DEG_TO_RAD); + return out; + }; + /** + * Extract euler angles from the quaternion, except roll(z-axis rotation) + * @hidden + */ + const quatToEuler = quaternion => { + const x = quaternion[0]; + const y = quaternion[1]; + const z = quaternion[2]; + const w = quaternion[3]; + const x2 = x * x; + const y2 = y * y; + const z2 = z * z; + const w2 = w * w; + const unit = x2 + y2 + z2 + w2; + const test = x * w - y * z; + let pitch, yaw; + if (test > 0.499995 * unit) { + // singularity at the north pole + pitch = Math.PI / 2; + yaw = 2 * Math.atan2(y, x); + } else if (test < -0.499995 * unit) { + // singularity at the south pole + pitch = -Math.PI / 2; + yaw = -2 * Math.atan2(y, x); + } else { + const view = glMatrix.vec3.fromValues(0, 0, 1); + const up = glMatrix.vec3.fromValues(0, 1, 0); + glMatrix.vec3.transformQuat(view, view, quaternion); + glMatrix.vec3.transformQuat(up, up, quaternion); + const viewXZ = Math.sqrt(view[0] * view[0] + view[2] * view[2]); + pitch = Math.atan2(-view[1], viewXZ); + yaw = Math.atan2(view[0], view[2]); + } + return { + pitch: clamp(pitch * RAD_TO_DEG, -90, 90), + yaw: circulate(yaw * RAD_TO_DEG, 0, 360) + }; + }; + + /* + * Copyright (c) 2020 NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Interpolator between two values with duration + * @ko 특정 시간동안 두 값을 보간해주는 보간기 + * @since 4.0.0 + */ + class Motion { + /** + * Current interpolated value + * @ko 현재 보간된 값 + * @since 4.0.0 + */ + get val() { + return this._val; + } + /** + * Start(from) value of interpolation + * @ko 보간 시작 값 + * @since 4.0.0 + */ + get start() { + return this._start; + } + /** + * End(to) value of interpolation + * @ko 보간 끝 값 + * @since 4.0.0 + */ + get end() { + return this._end; + } + /** + * Interpolation progress value (0 ~ 1) + * @ko 현재 보간 진행정도 (0 ~ 1) + * @since 4.0.0 + */ + get progress() { + return this._progress; + } + /** + * Whether the interpolation is in active state. + * @ko 보간 진행중인지 여부. `true`일 경우 보간이 진행중입니다. + * @since 4.0.0 + */ + get activated() { + return this._activated; + } + /** + * Duration of the interpolation + * @ko 보간할 시간 + * @since 4.0.0 + */ + get duration() { + return this._duration; + } + set duration(val) { + this._duration = val; + } + /** + * Whether to loop interpolation on finish + * @ko 보간이 끝난 이후에 다시 시작할지 여부 + * @since 4.0.0 + */ + get loop() { + return this._loop; + } + set loop(val) { + this._loop = val; + } + /** + * Range of the interpolation + * @ko 보간 범위 + * @since 4.0.0 + */ + get range() { + return this._range; + } + /** + * Easing function of the interpolation + * @ko 보간에 사용되는 easing function + * @since 4.0.0 + */ + get easing() { + return this._easing; + } + set easing(val) { + this._easing = val; + } + /** + * Create new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options Options {@ko 옵션들} + * @param options.duration Duration of the interpolation {@ko 보간할 시간} + * @param options.loop Whether to loop interpolation on finish {@ko 보간이 끝난 이후에 다시 시작할지 여부} + * @param options.range Range of the interpolation {@ko 보간 범위} + * @param options.loop Easing function of the interpolation {@ko 보간에 사용되는 easing function} + */ + constructor({ + duration = DEFAULT_ANIMATION_DURATION, + loop = false, + range = { + min: 0, + max: 1 + }, + easing = DEFAULT_EASING + } = {}) { + this._duration = duration; + this._loop = loop; + this._range = range; + this._easing = easing; + this._activated = false; + this.reset(0); + } + /** + * Update motion and progress it by given deltaTime + * @ko 주어진 deltaTime만큼 보간을 진행합니다. + * @param deltaTime - number of milisec to update motion {@ko 보간을 진행할 시간, 밀리초 단위} + * @returns Difference(delta) of the value from the last update. {@ko 지난 업데이트 이후의 값 변화량} + * @since 4.0.0 + */ + update(deltaTime) { + if (!this._activated) { + this._val = this._end; + return 0; + } + const start = this._start; + const end = this._end; + const duration = this._duration; + const prev = this._val; + const loop = this._loop; + const nextProgress = this._progress + deltaTime / duration; + this._progress = loop ? circulate(nextProgress, 0, 1) : clamp(nextProgress, 0, 1); + const easedProgress = this._easing(this._progress); + this._val = lerp(start, end, easedProgress); + if (!loop && this._progress >= 1) { + this._activated = false; + } + return this._val - prev; + } + /** + * Set `start`, `end` to the given value and set `progress` to 0. + * @ko 주어진 값으로 시작 지점, 끝 지점을 초기화하고 progress를 0으로 세팅합니다. + * @param defaultVal - Value to reset {@ko 초기화할 값} + * @since 4.0.0 + */ + reset(defaultVal) { + const range = this._range; + const val = clamp(defaultVal, range.min, range.max); + this._start = val; + this._end = val; + this._val = val; + this._progress = 0; + this._activated = false; + } + /** + * Add delta to start & end and current value. + * @ko 현재 & 끝 및 현재 값에 주어진 값을 더합니다. + * @param delta - Delta value to add {@ko 추가할 값} + */ + add(delta) { + const range = this._range; + this._start = clamp(this._start + delta, range.min, range.max); + this._end = clamp(this._end + delta, range.min, range.max); + this._val = clamp(this._val + delta, range.min, range.max); + } + /** + * Set current value to start, and end to current value + delta, then reset progress to 0. + * @ko 현재 값을 시작 지점으로, 그에서 delta만큼 추가된 값을 끝점으로 하고 progress를 0으로 갱신합니다. + * @param delta - Delta value to add {@ko 추가할 값} + */ + setNewEndByDelta(delta) { + const range = this._range; + this._start = this._val; + this._end = clamp(this._end + delta, range.min, range.max); + this._progress = 0; + this._activated = true; + } + /** + * Set new range of the interpolation. + * @ko 보간의 범위를 변경합니다. + * @param min - New minimum range {@ko 변경할 범위의 최소값} + * @param max - New maximum range {@ko 변경할 범위의 최대값} + */ + setRange(min, max) { + this._start = clamp(this._start, min, max); + this._end = clamp(this._end, min, max); + this._range = { + min, + max + }; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Animation of the {@link Camera} + * @internal + * @ko {@link Camera}의 애니메이션 + * @since 4.0.0 + */ + class CameraAnimation { + /** + * Duration of the animation + * @ko 애니메이션 재생시간 + * @since 4.0.0 + */ + get duration() { + return this._motion.duration; + } + set duration(val) { + this._motion.duration = val; + } + /** + * Easing function of the animation + * @ko 애니메이션의 easing function + * @since 4.0.0 + */ + get easing() { + return this._motion.easing; + } + set easing(val) { + this._motion.easing = val; + } + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param camera - Camera to animate {@ko 애니메이션을 적용할 카메라} + * @param from - Start pose {@ko 애니메이션이 시작 시점의 카메라의 회전 및 줌} + * @param to - End pose {@ko 애니메이션이 끝났을 때 카메라의 회전 및 줌} + * @param options - Options {@ko 옵션들} + * @param options.duration - Animation duration {@ko 애니메이션 재생 시간} + * @param options.easing - Animation easing function {@ko 애니메이션 easing function} + */ + constructor(camera, from, to, { + duration = DEFAULT_ANIMATION_DURATION, + easing = DEFAULT_EASING + } = {}) { + this._camera = camera; + this._motion = new Motion({ + duration, + easing, + range: { + min: 0, + max: 1 + } + }); + this._from = from; + this._to = to; + this._finishPromise = new Promise(resolve => { + this._finish = resolve; + }); + // Enable motion + this._motion.setNewEndByDelta(1); + } + /** + * Return a promise that resolved on animation end. + * @ko 애니메이션 재생이 끝났을 때 resolve되는 Promise를 반환합니다. + * @since 4.0.0 + */ + getFinishPromise() { + return this._finishPromise; + } + /** + * Update animation by given deltaTime. + * @ko 주어진 시간만큼 애니메이션을 업데이트합니다. + * @param deltaTime Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위} + * @since 4.0.0 + */ + update(deltaTime) { + const camera = this._camera; + const from = this._from; + const to = this._to; + const motion = this._motion; + motion.update(deltaTime); + // Progress that easing is applied + const progress = motion.val; + const rotation = glMatrix.quat.create(); + const zoom = lerp(from.zoom, to.zoom, progress); + glMatrix.quat.slerp(rotation, from.rotation, to.rotation, progress); + camera.rotate(rotation, zoom); + if (progress >= 1) { + this._finish(); + } + } + } + + /** + * Camera for View360 + * @ko View360용 카메라 구현체 + * @version 4.0.0 + */ + class Camera extends Component__default["default"] { + /** + * Camera's width / height ratio + * @ko 카메라의 가로 / 세로 비율 + * @readonly + */ + get aspect() { + return this._aspect; + } + /** + * Whether the camera's rotation changed from the last frame. + * @ko 마지막 프레임 이후로 카메라의 회전값이 변경되었는지 나타내는 플래그. + * @readonly + */ + get changed() { + return this._changed; + } + /** + * @copy View360#yawRange + */ + get yawRange() { + return this._initialYawRange; + } + set yawRange(val) { + this._initialYawRange = val; + } + /** + * @copy View360#pitchRange + */ + get pitchRange() { + return this._initialPitchRange; + } + set pitchRange(val) { + this._initialPitchRange = val; + } + /** + * @copy View360#zoomRange + */ + get zoomRange() { + return this._initialZoomRange; + } + set zoomRange(val) { + this._initialZoomRange = val; + } + /** + * Create new instance of Camera + * @param options - Camera options {@ko 카메라 옵션들} + */ + constructor({ + initialYaw, + initialPitch, + initialZoom, + yawRange, + pitchRange, + zoomRange, + fov + }) { + super(); + this.yaw = initialYaw; + this.pitch = initialPitch; + this.zoom = initialZoom; + this.rollOffset = 0; + this.initialYaw = initialYaw; + this.initialPitch = initialPitch; + this.initialZoom = initialZoom; + this.position = glMatrix.vec3.create(); + this.animation = null; + this._up = glMatrix.vec3.fromValues(0, 1, 0); + this._aspect = 1; + this._initialYawRange = yawRange; + this._initialPitchRange = pitchRange; + this._initialZoomRange = zoomRange; + this._yawRange = yawRange; + this._pitchRange = pitchRange; + this._zoomRange = zoomRange; + this.quaternion = glMatrix.quat.create(); + this._updateQuaternion(); + this.viewMatrix = glMatrix.mat4.create(); + this.projectionMatrix = glMatrix.mat4.create(); + this.fov = fov; + this._maxRenderHeight = -1; + } + /** + * Destroy instance and detach all event listeners + * @ko 인스턴스를 삭제하고 모든 이벤트 리스너를 삭제합니다. + * @since 4.0.0 + */ + destroy() { + this.off(); + } + /** + * Refresh internal size value. + * @ko 내부 크기값을 갱신합니다. + * @param width - New width {@ko 변경된 너비값} + * @param height - New height {@ko 변경된 높이값} + * @since 4.0.0 + */ + resize(width, height) { + const prevAspect = this._aspect; + this._aspect = width / height; + if (this._aspect !== prevAspect) { + this.updateMatrix(); + } + } + /** + * Change camera's rotation with euler values. + * @ko 카메라 회전을 오일러 각 방향으로 변경합니다. + * @param rotation - Rotation values {@ko 회전 값} + * @param rotation.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값} + * @param rotation.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값} + * @param rotation.zoom - zoom value to apply {@ko 적용할 카메라 줌 값} + * @since 4.0.0 + */ + lookAt({ + yaw = this.yaw, + pitch = this.pitch, + zoom = this.zoom + }) { + const prevQuaternion = glMatrix.quat.clone(this.quaternion); + const prevZoom = this.zoom; + this.yaw = circulate(yaw, 0, 360); + this.pitch = clamp(pitch, -90, 90); + this.zoom = zoom; + this._updateQuaternion(); + const zoomDiff = Math.abs(zoom - prevZoom); + if (!glMatrix.quat.equals(this.quaternion, prevQuaternion) || zoomDiff >= EPSILON * 10 // ignore small changes + ) { + this.updateMatrix(); + } + } + /** + * Change camera's rotation with quaternion. + * @ko 카메라 회전을 Quaternion을 이용해서 변경합니다. + * @param rotation - Quaternion to apply {@ko 적용할 Quaternion} + * @param zoom - zoom value to apply {@ko 적용할 카메라 줌 값} + * @since 4.0.0 + */ + rotate(rotation, zoom = this.zoom) { + const normalized = glMatrix.quat.normalize(glMatrix.quat.create(), rotation); + const isSameRotation = glMatrix.quat.equals(this.quaternion, normalized); + glMatrix.quat.copy(this.quaternion, normalized); + const prevZoom = this.zoom; + const { + yaw, + pitch + } = quatToEuler(normalized); + this.yaw = yaw; + this.pitch = pitch; + this.zoom = zoom; + const zoomDiff = Math.abs(zoom - prevZoom); + if (!isSameRotation || zoomDiff >= EPSILON * 10) { + this.updateMatrix(); + } + } + /** + * Change camera's rotation to given euler values by the given duration. + * @ko 카메라를 주어진 방향으로 주어진 시간동안 서서히 이동시킵니다. + * @param options - Animation parameters {@ko 애니메이션 패러미터} + * @param options.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값} + * @param options.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값} + * @param options.zoom - zoom value to apply {@ko 적용할 카메라 줌 값} + * @param options.duration - Duration of the animation {@ko 애니메이션 시간} + * @param options.easing - Easing function for the animation {@ko 애니메이션에 적용할 easing function} + */ + animateTo({ + yaw = this.yaw, + pitch = this.pitch, + zoom = this.zoom, + duration = 0, + easing = DEFAULT_EASING + } = {}) { + return __awaiter(this, void 0, void 0, function* () { + if (this.yaw === yaw && this.pitch === pitch && this.zoom === zoom) return; + const from = { + rotation: glMatrix.quat.clone(this.quaternion), + zoom: this.zoom + }; + const to = { + rotation: eulerToQuat(glMatrix.quat.create(), yaw, pitch, this.rollOffset), + zoom + }; + const animation = new CameraAnimation(this, from, to, { + duration, + easing + }); + const finishPromise = animation.getFinishPromise(); + this.animation = animation; + finishPromise.then(() => { + this.animation = null; + this.trigger(CAMERA_EVENTS.ANIMATION_END, { + animation + }); + }); + return finishPromise; + }); + } + /** + * @hidden + */ + restrictYawRange(min, max) { + this._yawRange = { + min, + max + }; + } + /** + * @hidden + */ + restrictPitchRange(min, max) { + this._pitchRange = { + min, + max + }; + } + /** + * @hidden + */ + restrictZoomRange(min, max) { + this._zoomRange = { + min, + max + }; + } + /** + * @hidden + */ + restrictRenderHeight(height) { + this._maxRenderHeight = height; + } + /** + * @hidden + */ + resetRange() { + this._yawRange = this._initialYawRange; + this._pitchRange = this._initialPitchRange; + this._zoomRange = this._initialZoomRange; + this._maxRenderHeight = -1; + } + /** + * Get actual yaw range by the given zoom value. + * @ko 주어진 zoom 값에 대한 실제 yaw 범위값을 반환합니다. + * @since 4.0.0 + */ + getYawRange(zoom) { + const yawLimit = this._yawRange; + const maxRenderHeight = this._maxRenderHeight; + if (!yawLimit) return INFINITE_RANGE; + const halfHFov = this.getHorizontalFov(zoom) * 0.5; + let minYaw = yawLimit.min; + let maxYaw = yawLimit.max; + if (maxRenderHeight > 0) { + const halfVFovRad = toVerticalFov(halfHFov * DEG_TO_RAD, this._aspect); + const h = maxRenderHeight * 0.5; + const t = Math.tan(halfVFovRad); + const d = Math.sqrt((1 + h * h) / (1 + t * t)); + const theta = Math.atan(Math.tan(halfHFov * DEG_TO_RAD) * d) * RAD_TO_DEG; + minYaw = yawLimit.min + theta; + maxYaw = yawLimit.max - theta; + } + if (minYaw > maxYaw) { + minYaw = 0; + maxYaw = 0; + } + return { + min: minYaw, + max: maxYaw + }; + } + /** + * Get actual pitch range by the given zoom value. + * @ko 주어진 zoom 값에 대한 실제 pitch 범위값을 반환합니다. + * @since 4.0.0 + */ + getPitchRange(zoom) { + const pitchLimit = this._pitchRange; + const maxRenderHeight = this._maxRenderHeight; + if (!pitchLimit) return DEFAULT_PITCH_RANGE; + let minPitch = pitchLimit.min; + let maxPitch = pitchLimit.max; + if (maxRenderHeight > 0) { + const halfVFov = this.getVerticalFov(zoom) * 0.5; + minPitch = pitchLimit.min + halfVFov; + maxPitch = pitchLimit.max - halfVFov; + } + if (minPitch > maxPitch) { + minPitch = 0; + maxPitch = 0; + } + return { + min: Math.max(minPitch, -90), + max: Math.min(maxPitch, 90) + }; + } + /** + * Get actual zoom range in fov degrees. + * @ko 실제 줌 범위를 fov각의 범위로 반환합니다. + * @since 4.0.0 + */ + getZoomRange() { + var _a; + const limit = (_a = this._zoomRange) !== null && _a !== void 0 ? _a : DEFAULT_ZOOM_RANGE; + // max (zoom in) -> minimum fov + const minFov = this.getHorizontalFov(limit.max); + const maxFov = this.getHorizontalFov(limit.min); + const currentFov = this.getHorizontalFov(this.zoom); + return { + min: Math.max(minFov, 1), + max: Math.min(maxFov, 180), + current: currentFov + }; + } + /** + * Return horizontal fov value when the given zoom is applied. (in degrees, °) + * @ko 주어진 zoom 값이 적용되었을 때의 수평 fov값을 반환합니다. (도 단위, °) + * @returns Zoomed horizontal FOV {@ko 줌이 적용된 수평 fov값} + * @since 4.0.0 + */ + getHorizontalFov(zoom = this.zoom) { + return this._getZoomedHorizontalFov(zoom) * RAD_TO_DEG; + } + /** + * Return vertical fov value when the given zoom is applied. (in degrees, °) + * @ko 주어진 zoom 값이 적용되었을 때의 수직 fov값을 반환합니다. (도 단위, °) + * @returns Zoomed vertical FOV {@ko 줌이 적용된 수직 fov값} + * @since 4.0.0 + */ + getVerticalFov(zoom = this.zoom) { + const aspect = this._aspect; + const hFov = this._getZoomedHorizontalFov(zoom); // In radians + const vFov = toVerticalFov(hFov, aspect); + return vFov * RAD_TO_DEG; + } + /** + * Calculate zoom value for the given fov. + * @ko 주어진 fov값을 zoom값으로 변환합니다. + * @param fov horizontal fov (in degrees, °) {@ko 수평 fov 값 (도 단위, °)} + * @since 4.0.0 + */ + fovToZoom(fov) { + const baseFov = this.fov; + const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5); + const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5); + return renderingWidth / zoomedWidth; + } + /** + * Update inner matrixes. + * @ko 내부 행렬들을 업데이트합니다. + * @internal + * @since 4.0.0 + */ + updateMatrix() { + const up = this._up; + const aspect = this._aspect; + const viewMatrix = this.viewMatrix; + const projMatrix = this.projectionMatrix; + const position = this.position; + const rotation = this.quaternion; + const upDir = glMatrix.vec3.create(); + const viewDir = glMatrix.vec3.fromValues(0, 0, -1); + glMatrix.vec3.transformQuat(viewDir, viewDir, rotation); + glMatrix.vec3.transformQuat(upDir, up, rotation); + const hFov = this._getZoomedHorizontalFov(); // In radians + const vFov = toVerticalFov(hFov, aspect); + glMatrix.mat4.lookAt(viewMatrix, position, viewDir, upDir); + glMatrix.mat4.perspective(projMatrix, vFov, aspect, 0.1, 100); + this._changed = true; + } + /** + * @hidden + */ + onFrameRender() { + this._changed = false; + } + _updateQuaternion() { + eulerToQuat(this.quaternion, this.yaw, this.pitch, this.rollOffset); + } + /** + * @param zoom Current zoom value + * @returns horizontal fov including zoom, in radian + */ + _getZoomedHorizontalFov(zoom = this.zoom) { + return 2 * Math.atan(Math.tan(DEG_TO_RAD * this.fov * 0.5) / zoom); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class MouseInput extends Component__default["default"] { + constructor() { + super(); + this._onMouseDown = evt => { + const el = this._el; + if (!el || evt.button !== MOUSE_BUTTON.LEFT) return; + evt.preventDefault(); + if (el.focus) { + el.focus(); + } else { + window.focus(); + } + this._prevPos[0] = evt.clientX; + this._prevPos[1] = evt.clientY; + window.addEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove, false); + window.addEventListener(EVENTS$1.MOUSE_UP, this._onMouseUp, false); + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: false, + isKeyboard: false + }); + }; + this._onMouseMove = evt => { + evt.preventDefault(); + const x = evt.clientX; + const y = evt.clientY; + const prevPos = this._prevPos; + const deltaX = x - prevPos[0]; + const deltaY = y - prevPos[1]; + this.trigger(CONTROL_EVENTS.CHANGE, { + delta: { + x: deltaX, + y: deltaY + }, + isTouch: false, + isKeyboard: false + }); + prevPos[0] = x; + prevPos[1] = y; + }; + this._onMouseUp = () => { + this._prevPos[0] = 0; + this._prevPos[1] = 0; + window.removeEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove, false); + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onMouseUp, false); + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: false, + isKeyboard: false, + scrolling: false + }); + }; + this._el = null; + this._prevPos = [0, 0]; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.MOUSE_DOWN, this._onMouseDown); + this._el = element; + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.MOUSE_DOWN, this._onMouseDown); + window.removeEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove, false); + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onMouseUp, false); + this._el = null; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class TouchInput extends Component__default["default"] { + get scrollable() { + return this._scrollable; + } + set scrollable(val) { + this._scrollable = val; + } + constructor() { + super(); + this._onTouchStart = evt => { + if (evt.touches.length > 1 || this._scrolling) return; + const touch = evt.touches[0]; + this._isFirstTouch = true; + this._prevPos[0] = touch.clientX; + this._prevPos[1] = touch.clientY; + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: true, + isKeyboard: false + }); + }; + this._onTouchMove = evt => { + // Only the one finger motion should be considered + if (evt.touches.length > 1 || this._scrolling) return; + const touch = evt.touches[0]; + const scrollable = this._scrollable; + const prevPos = this._prevPos; + const x = touch.clientX; + const y = touch.clientY; + const deltaX = x - prevPos[0]; + const deltaY = y - prevPos[1]; + if (this._isFirstTouch) { + if (scrollable && !isFullscreen()) { + if (Math.abs(deltaY) > Math.abs(deltaX)) { + // Assume Scrolling + this._scrolling = true; + return; + } + } + this._isFirstTouch = false; + } + if (evt.cancelable !== false) { + evt.preventDefault(); + } + this.trigger(CONTROL_EVENTS.CHANGE, { + delta: { + x: deltaX, + y: deltaY + }, + isTouch: true, + isKeyboard: false + }); + prevPos[0] = x; + prevPos[1] = y; + }; + this._onTouchEnd = evt => { + if (evt.touches.length !== 0) return; + const touch = evt.touches[0]; + const prevPos = this._prevPos; + if (touch) { + prevPos[0] = touch.clientX; + prevPos[1] = touch.clientY; + } else { + prevPos[0] = 0; + prevPos[1] = 0; + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: true, + isKeyboard: false, + scrolling: this._scrolling + }); + } + if (evt.cancelable !== false) { + evt.preventDefault(); + } + this._scrolling = false; + }; + this._el = null; + this._prevPos = [0, 0]; + this._isFirstTouch = false; + this._scrolling = false; + this._scrollable = false; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.TOUCH_START, this._onTouchStart, { + passive: false + }); + element.addEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove, { + passive: false + }); + element.addEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = element; + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.TOUCH_START, this._onTouchStart); + element.removeEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove); + element.removeEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = null; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class KeyboardInput extends Component__default["default"] { + get active() { + const pressed = this._pressed; + return pressed.LEFT || pressed.UP || pressed.RIGHT || pressed.DOWN; + } + constructor() { + super(); + this._onKeyDown = evt => { + // Ignore all other keypress except main arrow keys + if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return; + this._updateKeyPress(evt, true); + const pressedCount = this._getPressedKeyCount(); + if (pressedCount <= 0) return; + evt.preventDefault(); + if (pressedCount === 1 && !evt.repeat) { + // On first keydown + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: false, + isKeyboard: true + }); + } + }; + this._onKeyUp = evt => { + // Ignore all other keypress except main arrow keys + if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return; + this._updateKeyPress(evt, false); + const pressedCount = this._getPressedKeyCount(); + if (pressedCount > 0) return; + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: false, + isKeyboard: true, + scrolling: false + }); + }; + this._el = null; + this._clearPressedKeys(); + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown); + element.addEventListener(EVENTS$1.KEY_UP, this._onKeyUp); + this._el = element; + this._clearPressedKeys(); + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown); + element.removeEventListener(EVENTS$1.KEY_UP, this._onKeyUp); + this._el = null; + this._clearPressedKeys(); + } + update() { + const delta = this._getDeltaByPressedKeys(); + if (delta.x !== 0 || delta.y !== 0) { + this.trigger(CONTROL_EVENTS.CHANGE, { + delta, + isTouch: false, + isKeyboard: true + }); + } + } + _clearPressedKeys() { + this._pressed = KEY_DIRECTION.reduce((obj, keyName) => { + return Object.assign(Object.assign({}, obj), { + [keyName]: false + }); + }, {}); + } + _updateKeyPress(event, isEnable) { + const pressed = this._pressed; + const keyToUpdate = event.keyCode != null ? DIRECTION_KEY_CODE[event.keyCode] : DIRECTION_KEY_NAME[event.key]; + if (!keyToUpdate) return; + pressed[keyToUpdate] = isEnable; + } + _getPressedKeyCount() { + return KEY_DIRECTION.filter(key => this._pressed[key]).length; + } + _getDeltaByPressedKeys() { + const pressed = this._pressed; + let x = 0; + let y = 0; + if (pressed.LEFT) { + x += 1; + } + if (pressed.RIGHT) { + x -= 1; + } + if (pressed.UP) { + y += 1; + } + if (pressed.DOWN) { + y -= 1; + } + return { + x, + y + }; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Camera's rotation control + * @ko 카메라의 회전을 담당하는 컨트롤 + * @since 4.0.0 + */ + class RotateControl extends Component__default["default"] { + /** + * @copy CameraControl#enabled + */ + get enabled() { + return this._enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * @copy CameraControl#animating + */ + get animating() { + return this._keyboardInput.active || this._xMotion.activated || this._yMotion.activated; + } + /** + * Current yaw value + * @ko 현재 yaw 값 + * @readonly + * @since 4.0.0 + */ + get yaw() { + return this._xMotion; + } + /** + * Current pitch value + * @ko 현재 pitch 값 + * @readonly + * @since 4.0.0 + */ + get pitch() { + return this._yMotion; + } + /** + * @copy View360#scrollable + */ + get scrollable() { + return this._touchInput.scrollable; + } + set scrollable(val) { + this._touchInput.scrollable = val; + } + /** + * Scale factor for mouse/touch rotation + * @ko 마우스/터치를 통한 회전 배율 + * @default [1, 1] + * @since 4.0.0 + */ + get pointerScale() { + return this._pointerScale; + } + set pointerScale(val) { + this._pointerScale = val; + } + /** + * Scale factor for keyboard rotation + * @ko 키보드를 통한 회전 배율 + * @default [1, 1] + * @since 4.0.0 + */ + get keyboardScale() { + return this._keyboardScale; + } + set keyboardScale(val) { + this._keyboardScale = val; + } + /** + * Duration of the input animation (ms) + * @ko 회전 애니메이션의 시간 (ms) + * @default 300 + */ + get duration() { + return this._duration; + } + set duration(val) { + this._duration = val; + this._xMotion.duration = val; + this._yMotion.duration = val; + } + /** + * Easing function of the animation + * @ko 회전 애니메이션에 적용할 easing 함수 + * @default EASING.EASE_OUT_CUBIC + * @see EASING + */ + get easing() { + return this._easing; + } + set easing(val) { + this._easing = val; + this._xMotion.easing = val; + this._yMotion.easing = val; + } + /** + * Disable X-axis(pitch) rotation. + * @ko x축 회전(pitch)을 비활성화합니다. + * @default false + */ + get disablePitch() { + return this._disablePitch; + } + set disablePitch(val) { + this._disablePitch = val; + } + /** + * Disable Y-axis(yaw) rotation. + * @ko y축 회전(yaw)을 비활성화합니다. + * @default false + */ + get disableYaw() { + return this._disableYaw; + } + set disableYaw(val) { + this._disableYaw = val; + } + /** + * Disable rotation by keyboard. + * @ko 키보드를 이용한 회전을 비활성화합니다. + * @default false + */ + get disableKeyboard() { + return this._disableKeyboard; + } + set disableKeyboard(val) { + this._disableKeyboard = val; + } + /** + * Create new RotateControl instance + * @ko RotateControl의 인스턴스를 생성합니다. + * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트} + * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부} + * @param options - Options for control {@ko 컨트롤 옵션들} + */ + constructor(controlEl, enableBlocked, { + duration = DEFAULT_ANIMATION_DURATION, + easing = DEFAULT_EASING, + pointerScale = [1, 1], + keyboardScale = [1, 1], + disablePitch = false, + disableYaw = false, + disableKeyboard = false + } = {}) { + super(); + this._onInputStart = evt => { + this._changedWhileDragging = false; + this.trigger(CONTROL_EVENTS.INPUT_START, Object.assign(Object.assign({}, evt), { + inputType: "rotate" + })); + }; + this._onChange = evt => { + const delta = evt.delta; + const invZoomScale = 1 / this._zoomScale; // Reduce speed on zoom + const screenScale = this._screenScale; + const keyboardScale = this._keyboardScale; + const pointerScale = this._pointerScale; + let scale; + if (evt.isKeyboard) { + scale = [keyboardScale[0] * invZoomScale, keyboardScale[1] * invZoomScale]; + } else { + scale = [pointerScale[0] * screenScale[0] * invZoomScale, pointerScale[1] * screenScale[1] * invZoomScale]; + } + const scaledX = delta.x * scale[0]; + const scaledY = delta.y * scale[1]; + this._xMotion.setNewEndByDelta(scaledX); + this._yMotion.setNewEndByDelta(scaledY); + this._changedWhileDragging = true; + }; + this._onInputEnd = evt => { + this.trigger(CONTROL_EVENTS.INPUT_END, Object.assign(Object.assign({}, evt), { + inputType: "rotate" + })); + if (!this._changedWhileDragging && !evt.isKeyboard && !evt.scrolling) { + this.trigger(CONTROL_EVENTS.STATIC_CLICK, { + isTouch: evt.isTouch + }); + } + this._changedWhileDragging = false; + }; + this._controlEl = controlEl; + this._pointerScale = pointerScale; + this._keyboardScale = keyboardScale; + this._duration = duration; + this._easing = easing; + this._disablePitch = disablePitch; + this._disableYaw = disableYaw; + this._disableKeyboard = disableKeyboard; + this._enableBlocked = enableBlocked; + this._mouseInput = new MouseInput(); + this._touchInput = new TouchInput(); + this._keyboardInput = new KeyboardInput(); + this._xMotion = new Motion({ + duration, + range: INFINITE_RANGE, + easing + }); + this._yMotion = new Motion({ + duration, + range: DEFAULT_PITCH_RANGE, + easing + }); + this._screenScale = [1, 1]; + this._zoomScale = 1; + this._enabled = false; + this._changedWhileDragging = false; + this._bindInputs(); + } + destroy() { + this.disable(); + this._mouseInput.off(); + this._touchInput.off(); + this._keyboardInput.off(); + this.off(); + this._changedWhileDragging = false; + } + /** + * @hidden + */ + update(delta) { + if (!this._enabled) return; + const xMotion = this._xMotion; + const yMotion = this._yMotion; + const keyboardInput = this._keyboardInput; + if (!this._disableKeyboard) { + keyboardInput.update(); + } + if (!this._disablePitch) { + yMotion.update(delta); + } + if (!this._disableYaw) { + xMotion.update(delta); + } + } + /** + * @hidden + */ + updateRange(camera, zoom) { + const yawRange = camera.getYawRange(zoom); + const pitchRange = camera.getPitchRange(zoom); + this._xMotion.setRange(yawRange.min, yawRange.max); + this._yMotion.setRange(pitchRange.min, pitchRange.max); + } + /** + * @hidden + */ + setZoomScale(val) { + this._zoomScale = val; + } + /** + * Resize control to match target size. + * @ko 컨트롤의 내부 크기를 갱신합니다. + * @param hfov - Camera horizontal fov in degrees {@ko 카메라의 수평방향 fov값 (도 단위)} + * @param aspect - Camera aspect {@ko 카메라 가로/세로 비율} + * @param width - New width {@ko 갱신된 너비} + * @param height - New height {@ko 갱신된 높이} + */ + resize(hfov, aspect, width, height) { + const vfov = toVerticalFov(hfov * DEG_TO_RAD, aspect) * RAD_TO_DEG; + this._screenScale[0] = hfov / width; + this._screenScale[1] = vfov / height; + } + enable() { + if (this._enabled) return; + const element = this._controlEl; + this._mouseInput.enable(element); + this._touchInput.enable(element); + this._keyboardInput.enable(element); + this._enabled = true; + this._enableBlocked = false; + this.trigger(CONTROL_EVENTS.ENABLE, { + control: this, + updateCursor: true + }); + } + disable() { + if (!this._enabled) return; + this._mouseInput.disable(); + this._touchInput.disable(); + this._keyboardInput.disable(); + this._enabled = false; + this.trigger(CONTROL_EVENTS.DISABLE, { + updateCursor: true + }); + } + sync(camera) { + this.updateRange(camera, camera.zoom); + this._xMotion.reset(camera.yaw); + this._yMotion.reset(camera.pitch); + } + _bindInputs() { + const mouseInput = this._mouseInput; + const touchInput = this._touchInput; + const keyboardInput = this._keyboardInput; + mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + touchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + touchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + keyboardInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + keyboardInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + keyboardInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class WheelInput extends Component__default["default"] { + get scrollable() { + return this._scrollable; + } + set scrollable(val) { + this._scrollable = val; + } + constructor() { + super(); + this._onWheel = evt => { + const scrollable = this._scrollable; + if (evt.deltaY === 0 || scrollable) return; + evt.preventDefault(); + evt.stopPropagation(); + if (this._inputTimer < 0) { + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: false, + isKeyboard: false + }); + } else { + this._clearTimer(); + } + const delta = this._baseScale * evt.deltaY; + this.trigger(CONTROL_EVENTS.CHANGE, { + delta, + isTouch: false, + isKeyboard: false + }); + this._inputTimer = window.setTimeout(() => { + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: false, + isKeyboard: false, + scrolling: false + }); + this._inputTimer = -1; + }, DEFAULT_ANIMATION_DURATION); + }; + this._el = null; + this._baseScale = 0.04; + this._scrollable = false; + this._inputTimer = -1; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.WHEEL, this._onWheel, { + passive: false, + capture: false + }); + this._el = element; + this._clearTimer(); + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.WHEEL, this._onWheel, false); + this._el = null; + this._clearTimer(); + } + _clearTimer() { + window.clearTimeout(this._inputTimer); + this._inputTimer = -1; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class PinchInput extends Component__default["default"] { + constructor() { + super(); + this._onTouchMove = evt => { + const touches = evt.touches; + if (touches.length !== 2) return; + if (!evt.cancelable) return; + evt.preventDefault(); + evt.stopPropagation(); + const prevDistance = this._prevDistance; + const diff = [touches[0].pageX - touches[1].pageX, touches[0].pageY - touches[1].pageY]; + const distance = Math.sqrt(diff[0] * diff[0] + diff[1] * diff[1]) * this._baseScale; + const delta = this._isFirstTouch ? 0 : distance - prevDistance; + if (this._isFirstTouch) { + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: true, + isKeyboard: false + }); + } + this._prevDistance = distance; + this._isFirstTouch = false; + this.trigger(CONTROL_EVENTS.CHANGE, { + delta, + isTouch: true, + isKeyboard: false + }); + }; + this._onTouchEnd = evt => { + if (evt.touches.length !== 0) return; + if (!this._isFirstTouch) { + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: true, + isKeyboard: false, + scrolling: false + }); + } + this._prevDistance = -1; + this._isFirstTouch = true; + }; + this._el = null; + this._baseScale = -0.2; + this._prevDistance = -1; + this._isFirstTouch = true; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove, { + passive: false, + capture: false + }); + element.addEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = element; + this._prevDistance = -1; + this._isFirstTouch = true; + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove, false); + element.removeEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = null; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Camera's zoom control + * @ko 카메라의 줌 값을 담당하는 컨트롤 + * @since 4.0.0 + */ + class ZoomControl extends Component__default["default"] { + /** + * @copy CameraControl#enabled + */ + get enabled() { + return this._enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * @copy CameraControl#animating + */ + get animating() { + return this._motion.activated; + } + /** + * Current zoom value + * @ko 현재 줌 값 + * @since 4.0.0 + * @readonly + */ + get zoom() { + return this._motion.val; + } + /** + * @copy View360#wheelScrollable + */ + get scrollable() { + return this._wheelInput.scrollable; + } + set scrollable(val) { + this._wheelInput.scrollable = val; + } + /** + * @hidden + */ + get range() { + return this._motion.range; + } + /** + * Scale factor of the zoom + * @ko 입력에 의한 줌 배율 + * @default 1 + * @since 4.0.0 + */ + get scale() { + return this._scale; + } + set scale(val) { + this._scale = val; + } + /** + * Duration of the input animation (ms) + * @ko 회전 애니메이션의 시간 (ms) + * @default 300 + * @since 4.0.0 + */ + get duration() { + return this._motion.duration; + } + /** + * Easing function of the animation + * @ko 회전 애니메이션에 적용할 easing 함수 + * @default EASING.EASE_OUT_CUBIC + * @see EASING + * @since 4.0.0 + */ + get easing() { + return this._motion.easing; + } + /** + * Create new ZoomControl instance + * @ko ZoomControl의 인스턴스를 생성합니다. + * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트} + * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부} + * @param options - Options for control {@ko 컨트롤 옵션들} + */ + constructor(controlEl, enableBlocked, { + scale = 1, + duration = DEFAULT_ANIMATION_DURATION, + easing = DEFAULT_EASING + } = {}) { + super(); + this._onInputStart = evt => { + this.trigger(CONTROL_EVENTS.INPUT_START, Object.assign(Object.assign({}, evt), { + inputType: "zoom" + })); + }; + this._onChange = ({ + delta + }) => { + const scale = this._scale; + const scaledDelta = delta * scale; + this._motion.setNewEndByDelta(scaledDelta); + }; + this._onInputEnd = evt => { + this.trigger(CONTROL_EVENTS.INPUT_END, Object.assign(Object.assign({}, evt), { + inputType: "zoom" + })); + }; + this._scale = scale; + this._controlEl = controlEl; + this._enableBlocked = enableBlocked; + this._wheelInput = new WheelInput(); + this._pinchInput = new PinchInput(); + this._motion = new Motion({ + duration, + easing, + range: INFINITE_RANGE + }); + this._enabled = false; + this._bindInputs(); + } + destroy() { + this.disable(); + this._wheelInput.off(); + this._pinchInput.off(); + this.off(); + } + /** + * @hidden + */ + update(delta) { + if (!this._enabled) return; + const motion = this._motion; + motion.update(delta); + } + enable() { + if (this._enabled) return; + const element = this._controlEl; + this._wheelInput.enable(element); + this._pinchInput.enable(element); + this._enabled = true; + this._enableBlocked = false; + this.trigger(CONTROL_EVENTS.ENABLE, { + control: this, + updateCursor: false + }); + } + disable() { + if (!this._enabled) return; + this._wheelInput.disable(); + this._pinchInput.disable(); + this._enabled = false; + this.trigger(CONTROL_EVENTS.DISABLE, { + updateCursor: false + }); + } + sync(camera) { + const motion = this._motion; + const range = camera.getZoomRange(); + motion.setRange(range.min, range.max); + motion.reset(range.current); + } + _bindInputs() { + const wheelInput = this._wheelInput; + const pinchInput = this._pinchInput; + wheelInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + wheelInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + wheelInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + pinchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + pinchInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + pinchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + const ROTATE_CONSTANT = { + PITCH_DELTA: 1, + YAW_DELTA_BY_ROLL: 2, + YAW_DELTA_BY_YAW: 3 + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = { + targetAxis: [0, 1, 0], + meshPoint: [0, 0, 1] + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = { + targetAxis: [0, 1, 0], + meshPoint: [1, 0, 0] + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = { + targetAxis: [1, 0, 0], + meshPoint: [0, 0, 1] + }; + class GyroInput extends Component__default["default"] { + get enabled() { + return this._enabled; + } + get orientationUpdated() { + return this._orientationUpdated; + } + get ignoreRoll() { + return this._ignoreRoll; + } + set ignoreRoll(val) { + this._ignoreRoll = val; + } + constructor() { + super(); + this._onDeviceOrientation = evt => { + const prevOrientation = this._orientation; + const { + alpha, + beta, + gamma + } = evt; + if (alpha == null || beta == null || gamma == null) return; + prevOrientation.alpha = alpha; + prevOrientation.beta = beta; + prevOrientation.gamma = gamma; + this._orientationUpdated = true; + if (this._needsCalibrate) { + this._needsCalibrate = false; + this._calibrateSensor(); + } + }; + this._updateScreenOrientation = () => { + if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) { + this._screenOrientation = screen.orientation.angle; + } else if (window.orientation !== undefined) { + this._screenOrientation = window.orientation >= 0 ? window.orientation : 360 + window.orientation; + } else { + this._screenOrientation = 0; + } + }; + this.quaternion = glMatrix.quat.create(); + this._orientation = { + alpha: 0, + beta: 90, + gamma: 0 + }; + this._yawOrigin = 0; + this._yawOffset = 0; + this._orientationUpdated = false; + this._screenOrientation = 0; + this._needsCalibrate = true; + this._enabled = false; + } + enable() { + if (this._enabled) return; + window.addEventListener(EVENTS$1.DEVICE_ORIENTATION, this._onDeviceOrientation); + window.addEventListener(EVENTS$1.ORIENTATION_CHANGE, this._updateScreenOrientation); + this._updateScreenOrientation(); + this._orientationUpdated = false; + this._needsCalibrate = true; + this._enabled = true; + } + disable() { + if (!this._enabled) return; + window.removeEventListener(EVENTS$1.DEVICE_ORIENTATION, this._onDeviceOrientation); + window.removeEventListener(EVENTS$1.ORIENTATION_CHANGE, this._updateScreenOrientation); + this._enabled = false; + } + update() { + this._updateRotation(); + this._orientationUpdated = false; + } + collectDelta() { + if (!this._orientationUpdated) { + return { + pitch: 0, + yaw: 0 + }; + } + const prevRotation = glMatrix.quat.clone(this.quaternion); + this._updateRotation(); + this._orientationUpdated = false; + return this._toEulerDelta(prevRotation, this.quaternion); + } + setInitialRotation(yaw) { + this._yawOrigin = yaw; + } + _calibrateSensor() { + const yawOrigin = this._yawOrigin; + const rotation = this.quaternion; + this._yawOffset = 0; + this._updateRotation(); + const { + yaw: sensorYaw + } = quatToEuler(rotation); + this._yawOffset = sensorYaw - yawOrigin; + this._updateRotation(); + this._needsCalibrate = false; + } + _updateRotation() { + const rotation = this.quaternion; + const { + alpha, + beta, + gamma + } = this._orientation; + glMatrix.quat.identity(rotation); + glMatrix.quat.rotateY(rotation, rotation, (alpha - this._yawOffset) * DEG_TO_RAD); + glMatrix.quat.rotateX(rotation, rotation, beta * DEG_TO_RAD); + glMatrix.quat.rotateZ(rotation, rotation, -gamma * DEG_TO_RAD); + const screen = glMatrix.quat.create(); + const screenAngle = -this._screenOrientation * 0.5 * DEG_TO_RAD; + const world = glMatrix.quat.fromValues(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5)); + glMatrix.quat.set(screen, 0, Math.sin(screenAngle), 0, Math.cos(screenAngle)); + glMatrix.quat.multiply(rotation, rotation, screen); + glMatrix.quat.multiply(rotation, rotation, world); + glMatrix.quat.normalize(rotation, rotation); + } + _toEulerDelta(prevQuat, currentQuat) { + return { + yaw: this._getDeltaYaw(prevQuat, currentQuat), + pitch: this._getDeltaPitch(prevQuat, currentQuat) + }; + } + _getDeltaYaw(prvQ, curQ) { + const yawDeltaByYaw = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW); + const yawDeltaByRoll = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) * Math.sin(this._extractPitchFromQuat(curQ)); + return yawDeltaByRoll + yawDeltaByYaw; + } + _getDeltaPitch(prvQ, curQ) { + return this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA); + } + _getRotationDelta(prevQ, curQ, rotateKind) { + const targetAxis = glMatrix.vec3.fromValues(ROTATE_CONSTANT[rotateKind].targetAxis[0], ROTATE_CONSTANT[rotateKind].targetAxis[1], ROTATE_CONSTANT[rotateKind].targetAxis[2]); + const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint; + const prevQuaternion = glMatrix.quat.clone(prevQ); + const curQuaternion = glMatrix.quat.clone(curQ); + glMatrix.quat.normalize(prevQuaternion, prevQuaternion); + glMatrix.quat.normalize(curQuaternion, curQuaternion); + let prevPoint = glMatrix.vec3.fromValues(0, 0, 1); + let curPoint = glMatrix.vec3.fromValues(0, 0, 1); + glMatrix.vec3.transformQuat(prevPoint, prevPoint, prevQuaternion); + glMatrix.vec3.transformQuat(curPoint, curPoint, curQuaternion); + glMatrix.vec3.transformQuat(targetAxis, targetAxis, curQuaternion); + const rotateDistance = glMatrix.vec3.dot(targetAxis, glMatrix.vec3.cross(glMatrix.vec3.create(), prevPoint, curPoint)); + const rotateDirection = rotateDistance > 0 ? 1 : -1; + // when counter clock wise, use vec3.fromValues(0,1,0) + // when clock wise, use vec3.fromValues(0,-1,0) + // const meshPoint1 = vec3.fromValues(0, 0, 0); + const meshPoint2 = glMatrix.vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + let meshPoint3; + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + meshPoint3 = glMatrix.vec3.fromValues(0, rotateDirection, 0); + } else { + meshPoint3 = glMatrix.vec3.fromValues(rotateDirection, 0, 0); + } + glMatrix.vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion); + glMatrix.vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion); + const vecU = meshPoint2; + const vecV = meshPoint3; + const vecN = glMatrix.vec3.create(); + glMatrix.vec3.cross(vecN, vecU, vecV); + glMatrix.vec3.normalize(vecN, vecN); + const coefficientA = vecN[0]; + const coefficientB = vecN[1]; + const coefficientC = vecN[2]; + // a point on the plane + curPoint = glMatrix.vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + glMatrix.vec3.transformQuat(curPoint, curPoint, curQuaternion); + // a point should project on the plane + prevPoint = glMatrix.vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + glMatrix.vec3.transformQuat(prevPoint, prevPoint, prevQuaternion); + // distance between prevPoint and the plane + let distance = Math.abs(prevPoint[0] * coefficientA + prevPoint[1] * coefficientB + prevPoint[2] * coefficientC); + const projectedPrevPoint = glMatrix.vec3.create(); + glMatrix.vec3.subtract(projectedPrevPoint, prevPoint, glMatrix.vec3.scale(glMatrix.vec3.create(), vecN, distance)); + let trigonometricRatio = (projectedPrevPoint[0] * curPoint[0] + projectedPrevPoint[1] * curPoint[1] + projectedPrevPoint[2] * curPoint[2]) / (glMatrix.vec3.length(projectedPrevPoint) * glMatrix.vec3.length(curPoint)); + // defensive block + if (trigonometricRatio > 1) { + trigonometricRatio = 1; + } + const theta = Math.acos(trigonometricRatio); + const crossVec = glMatrix.vec3.cross(glMatrix.vec3.create(), curPoint, projectedPrevPoint); + distance = coefficientA * crossVec[0] + coefficientB * crossVec[1] + coefficientC * crossVec[2]; + let thetaDirection; + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + thetaDirection = distance > 0 ? 1 : -1; + } else { + thetaDirection = distance < 0 ? 1 : -1; + } + const deltaRadian = theta * thetaDirection * rotateDirection; + return deltaRadian * RAD_TO_DEG; + } + _extractPitchFromQuat(quaternion) { + const baseV = glMatrix.vec3.fromValues(0, 0, 1); + glMatrix.vec3.transformQuat(baseV, baseV, quaternion); + return -1 * Math.atan2(baseV[1], Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2))); + } + } + + /** + * Camera's rotation control by gyroscope + * @ko 자이로스코프를 이용한 회전 컨트롤 + * @since 4.0.0 + */ + class GyroControl extends Component__default["default"] { + /** + * @copy CameraControl#enabled + */ + get enabled() { + return this._input.enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * @copy CameraControl#animating + */ + get animating() { + return this._input.enabled && this._input.orientationUpdated; + } + /** + * When `true`, ignore gyroscope's roll(z-axis rotation) value. + * :::caution + * Setting `false` will ignore camera's range limit. + * Options like {@link View360Options#yawRange}, {@link View360Options#pitchRange} are ignored, and {@link CylinderProjection} also can't force it's camera range limit. + * ::: + * @ko `true`일 경우 자이로스코프 입력의 roll(z축 회전)값을 무시합니다. + * :::caution + * 이 값을 `false`로 설정할 경우 카메라 범위 제약을 무시합니다. + * {@link View360Options#yawRange}, {@link View360Options#pitchRange}와 같은 값은 무시되며, {@link CylinderProjection} 사용시에도 범위를 벗어날 수 있습니다. + * ::: + * @default true + * @since 4.0.0 + */ + get ignoreRoll() { + return this._ignoreRoll; + } + set ignoreRoll(val) { + this._ignoreRoll = val; + } + /** + * Return availability of the gyroscope. + * :::caution + * This will always return false until user permission under environments like iOS which requires user permission when using gyroscope. + * ::: + * @ko 자이로스코프 사용 가능 여부를 반환합니다. + * :::caution + * iOS와 같이 GyroScope 사용시 사용자 Permission을 요구하는 환경에서는 사용자 Permission을 받기 전까지 항상 `false`입니다. + * ::: + * @example + * ```ts + * const gyroAvailable = await GyroControl.isAvailable(); + * ``` + */ + static isAvailable() { + return __awaiter(this, void 0, void 0, function* () { + if (!DeviceMotionEvent) { + return false; + } + let onDeviceMotionChange; + const listenDeviceMotion = () => new Promise(res => { + onDeviceMotionChange = evt => { + res(evt.rotationRate && evt.rotationRate.alpha != null); + }; + window.addEventListener(EVENTS$1.DEVICE_MOTION, onDeviceMotionChange); + }); + const timeout = () => new Promise(res => { + setTimeout(() => res(false), 1000); + }); + return Promise.race([listenDeviceMotion(), timeout()]).then(available => { + window.removeEventListener(EVENTS$1.DEVICE_MOTION, onDeviceMotionChange); + return available; + }); + }); + } + /** + * Request user permission for gyroscope sensor. + * This can be used in environments like iOS which requires user permission when using gyroscope sensors. + * @ko 사용자의 sensor permission 취득을 요청합니다. + * iOS와 같이 gyroscope 사용시 사용자 Permission을 요구하는 환경에서 사용 가능합니다. + * @returns Whether the permission is granted {@ko 사용자 permission 취득 여부} + */ + static requestSensorPermission() { + return __awaiter(this, void 0, void 0, function* () { + // Request sensor permission, on iOS13+ + if (sensorCanBeEnabledIOS()) { + return DeviceMotionEvent.requestPermission().then(permissionState => { + return permissionState === "granted"; + }).catch(() => false); + } + return true; + }); + } + /** + * Create new GyroControl instance + * @ko GyroControl의 인스턴스를 생성합니다. + * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부} + * @param options - Options for control {@ko 컨트롤 옵션들} + */ + constructor(enableBlocked, { + ignoreRoll = true + } = {}) { + super(); + this._enableBlocked = enableBlocked; + this._ignoreRoll = ignoreRoll; + this._input = new GyroInput(); + } + /** + * @copy CameraControl#destroy + */ + destroy() { + this.disable(); + this._input.off(); + this.off(); + } + /** + * @hidden + */ + update(camera, yaw, pitch, zoom) { + if (!this._ignoreRoll) { + this._updateQuaternion(camera, zoom); + } else { + this._updateYawPitch(camera, yaw, pitch, zoom); + } + } + /** + * @copy CameraControl#enable + */ + enable() { + if (this._input.enabled) return; + this._input.enable(); + this._enableBlocked = false; + this.trigger(CONTROL_EVENTS.ENABLE, { + control: this, + updateCursor: false + }); + } + /** + * @copy CameraControl#disable + */ + disable() { + if (!this._input.enabled) return; + this._input.disable(); + this.trigger(CONTROL_EVENTS.DISABLE, { + updateCursor: false + }); + } + /** + * @copy CameraControl#sync + */ + sync() {} // eslint-disable-line @typescript-eslint/no-empty-function + _updateYawPitch(camera, yaw, pitch, zoom) { + const input = this._input; + if (!input.enabled) return; + const { + yaw: yawDelta, + pitch: pitchDelta + } = input.collectDelta(); + yaw.add(yawDelta); + pitch.add(pitchDelta); + camera.lookAt({ + yaw: yaw.val, + pitch: pitch.val, + zoom + }); + } + _updateQuaternion(camera, zoom) { + const input = this._input; + if (!input.enabled) return; + input.update(); + camera.rotate(input.quaternion, zoom); + } + } + + /** + * Panorama control for View360 + * @ko View360용 파노라마 컨트롤 + * @since 4.0.0 + */ + class PanoControl { + /** + * @copy View360#useGrabCursor + */ + get useGrabCursor() { + return this._useGrabCursor; + } + set useGrabCursor(val) { + if (val === this._useGrabCursor) return; + this._useGrabCursor = val; + if (val && this._enabled) { + this._setCursor(CURSOR.GRAB); + } else if (!val) { + this._setCursor(CURSOR.NONE); + } + } + /** + * @copy View360#disableContextMenu + */ + get disableContextMenu() { + return this._disableContextMenu; + } + set disableContextMenu(val) { + if (val === this._disableContextMenu) return; + this._disableContextMenu = val; + if (val && this._enabled) { + this._blockContextMenu(); + } else if (!val) { + this._restoreContextMenu(); + } + } + /** + * @copy View360#disableContextMenu + */ + get scrollable() { + return this._rotateControl.scrollable; + } + set scrollable(val) { + this._rotateControl.scrollable = val; + } + /** + * @copy View360#disableContextMenu + */ + get wheelScrollable() { + return this._zoomControl.scrollable; + } + set wheelScrollable(val) { + this._zoomControl.scrollable = val; + } + /** + * When `true`, disables rotation slow-down by zoom-value. + * @ko `true`일 경우 줌 된 정도에 따라 회전속도를 늦추는 동작을 비활성화합니다. + * @since 4.0.0 + */ + get ignoreZoomScale() { + return this._ignoreZoomScale; + } + set ignoreZoomScale(val) { + this._ignoreZoomScale = val; + } + /** + * Whether the control is enabled or not + * @ko 컨트롤 활성화 여부를 가리키는 값 + * @readonly + * @since 4.0.0 + */ + get enabled() { + return this._enabled; + } + /** + * @copy View360#rotate + */ + get rotate() { + return this._rotateControl; + } + /** + * @copy View360#zoom + */ + get zoom() { + return this._zoomControl; + } + /** + * @copy View360#gyro + */ + get gyro() { + return this._gyroControl; + } + /** + * Whether one of the controls is animating at the moment + * @ko 현재 컨트롤 중 하나라도 동작중인지 여부를 나타내는 값 + * @readonly + * @since 4.0.0 + */ + get animating() { + return this._rotateControl.animating || this._zoomControl.animating || this._gyroControl.animating; + } + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param element - Canvas element {@ko 캔버스 엘리먼트} + * @param camera - Camera instance {@ko Camera 인스턴스} + * @param options - Options for PanoControl {@ko PanoControl 옵션들} + */ + constructor(element, camera, { + useGrabCursor, + scrollable, + wheelScrollable, + disableContextMenu, + rotate, + zoom, + gyro + }) { + this._preventContextMenu = evt => { + evt.preventDefault(); + }; + this._onInputStart = evt => { + if (this._useGrabCursor && !evt.isKeyboard) { + this._setCursor(CURSOR.GRABBING); + } + }; + this._onInputEnd = evt => { + if (this._useGrabCursor && !evt.isKeyboard) { + this._setCursor(CURSOR.GRAB); + } + }; + this._onEnable = ({ + control, + updateCursor + }) => { + if (updateCursor && this._useGrabCursor) { + this._setCursor(CURSOR.GRAB); + } + control.sync(this._camera); + }; + this._onDisable = ({ + updateCursor + }) => { + if (updateCursor) { + this._setCursor(CURSOR.NONE); + } + }; + this._onCameraAnimationEnd = ({ + animation + }) => { + animation.getFinishPromise().then(() => { + this.sync(); + }); + }; + // Bind Options + this._useGrabCursor = useGrabCursor; + this._disableContextMenu = disableContextMenu; + // Set internal values + this._camera = camera; + this._controlEl = element; + this._ignoreZoomScale = false; + this._enabled = false; + this._rotateControl = new RotateControl(element, !rotate, getObjectOption(rotate)); + this._zoomControl = new ZoomControl(element, !zoom, getObjectOption(zoom)); + this._gyroControl = new GyroControl(!gyro, getObjectOption(gyro)); + this._rotateControl.scrollable = scrollable; + this._zoomControl.scrollable = wheelScrollable; + this._bindEvents(); + } + /** + * Destroy the instance and remove all event listeners attached. + * This also will reset CSS cursor to initial. + * @ko 인스턴스를 삭제하고 부착된 모든 이벤트 리스너를 제거합니다. + * 또한, 캔버스에 적용된 CSS cursor도 제거합니다. + * @since 4.0.0 + */ + destroy() { + this.disable(); + this._rotateControl.destroy(); + this._zoomControl.destroy(); + this._setCursor(CURSOR.NONE); + } + /** + * Resize control to match target size. + * @ko 컨트롤이 내부에 캐시하고 있는 크기값을 갱신합니다. + * @param width New width {@ko 변경된 너비} + * @param height New height {@ko 변경된 높이} + * @since 4.0.0 + */ + resize(width, height) { + const camera = this._camera; + this._rotateControl.resize(camera.fov, camera.aspect, width, height); + } + /** + * Enable this control and add event listeners. + * @ko 컨트롤을 활성화하고 이벤트 리스너들을 추가합니다. + * @since 4.0.0 + */ + enable() { + return __awaiter(this, void 0, void 0, function* () { + if (this._enabled) return; + if (!this._rotateControl.enableBlocked) { + this._rotateControl.enable(); + } + if (!this._zoomControl.enableBlocked) { + this._zoomControl.enable(); + } + if (!this._gyroControl.enableBlocked) { + if (yield GyroControl.isAvailable()) { + this._gyroControl.enable(); + } + } + this.sync(); + if (this._disableContextMenu) { + this._blockContextMenu(); + } + this._enabled = true; + }); + } + /** + * Disable this control and remove all event listeners + * @ko 컨트롤을 비활성화하고 모든 이벤트 리스너들을 제거합니다. + * @since 4.0.0 + */ + disable() { + if (!this._enabled) return; + this._rotateControl.disable(); + this._zoomControl.disable(); + this._gyroControl.disable(); + this._restoreContextMenu(); + this._enabled = false; + } + /** + * Update control by given deltaTime + * @ko 컨트롤을 주어진 시간만큼 업데이트합니다. + * @param delta Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위} + * @since 4.0.0 + * @internal + */ + update(delta) { + const camera = this._camera; + const rotateControl = this._rotateControl; + const zoomControl = this._zoomControl; + const gyroControl = this._gyroControl; + zoomControl.update(delta); + const zoom = hfovToZoom(camera.fov, zoomControl.zoom); + // Slow down rotation on zoom-in + const zoomScale = this._ignoreZoomScale ? 1 : Math.max(zoom, 1); + rotateControl.setZoomScale(zoomScale); + rotateControl.updateRange(camera, zoom); + rotateControl.update(delta); + const yaw = rotateControl.yaw; + const pitch = rotateControl.pitch; + if (gyroControl.enabled) { + gyroControl.update(camera, yaw, pitch, zoom); + } else { + camera.lookAt({ + yaw: yaw.val, + pitch: pitch.val, + zoom + }); + } + } + /** + * Synchronize this control's state to current camera state + * @ko 컨트롤을 카메라의 현재 상태와 동기화합니다. + * @since 4.0.0 + */ + sync() { + const camera = this._camera; + this._zoomControl.sync(camera); + this._rotateControl.sync(camera); + } + _blockContextMenu() { + const el = this._controlEl; + el.addEventListener(EVENTS$1.CONTEXT_MENU, this._preventContextMenu); + } + _restoreContextMenu() { + const el = this._controlEl; + el.removeEventListener(EVENTS$1.CONTEXT_MENU, this._preventContextMenu); + } + _setCursor(newCursor) { + if (!this._useGrabCursor && newCursor !== CURSOR.NONE) return; + const targetEl = this._controlEl; + targetEl.style.cursor = newCursor; + } + _bindEvents() { + const rotateControl = this._rotateControl; + const zoomControl = this._zoomControl; + rotateControl.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + rotateControl.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + rotateControl.on(CONTROL_EVENTS.ENABLE, this._onEnable); + rotateControl.on(CONTROL_EVENTS.DISABLE, this._onDisable); + zoomControl.on(CONTROL_EVENTS.ENABLE, this._onEnable); + zoomControl.on(CONTROL_EVENTS.DISABLE, this._onDisable); + this._camera.on(CAMERA_EVENTS.ANIMATION_END, this._onCameraAnimationEnd); + } + } + + /** + * @hidden + */ + class Texture { + constructor({ + width, + height, + flipY + }) { + this.width = width; + this.height = height; + this.flipY = flipY; + this.wrapS = WebGLRenderingContext.CLAMP_TO_EDGE; + this.wrapT = WebGLRenderingContext.CLAMP_TO_EDGE; + } + destroy() { + // DO_NOTHING + } + isVideo() { + return false; + } + isCube() { + return false; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class Texture2D extends Texture { + constructor({ + source, + width, + height, + flipY + }) { + super({ + width, + height, + flipY + }); + this.source = source; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class TextureVideo extends Texture2D { + destroy() { + const video = this.source; + video.pause(); + video.removeAttribute("src"); + video.load(); + } + isVideo() { + return true; + } + isPaused() { + const video = this.source; + return video.paused || video.ended || video.readyState <= 2; + } + hasAudio() { + const video = this.source; + if (video.audioTracks) { + return video.audioTracks.length > 0; + } + if (video.webkitAudioDecodedByteCount != null) { + return video.webkitAudioDecodedByteCount > 0; + } + if (video.mozHasAudio != null) { + return video.mozHasAudio; + } + // We don't know whether the video has audio or not, return true + return true; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class TextureCube extends Texture { + constructor({ + sources, + width, + height, + flipY + }) { + super({ + width, + height, + flipY + }); + this.sources = sources; + } + isCube() { + return true; + } + } + + /** + * @hidden + */ + class TextureLoader { + constructor() { + this._loadChecker = new ImReady__default["default"](); + } + load(src, video) { + return __awaiter(this, void 0, void 0, function* () { + if (video) { + return this.loadVideo(src, getObjectOption(video)); + } else { + if (Array.isArray(src) && src.length > 1) { + return this.loadCubeImage(src); + } else { + const imgSrc = Array.isArray(src) ? src[0] : src; + return this.loadImage(imgSrc); + } + } + }); + } + loadImage(src) { + return __awaiter(this, void 0, void 0, function* () { + const images = this._toImageArray(src); + return this._load(images, resolve => { + const image = images[0]; + resolve(new Texture2D({ + source: image, + width: image.naturalWidth, + height: image.naturalHeight, + flipY: true + })); + }); + }); + } + loadCubeImage(src) { + return __awaiter(this, void 0, void 0, function* () { + const images = this._toImageArray(src); + return this._load(images, resolve => { + resolve(new TextureCube({ + sources: images, + width: images[0].naturalWidth, + height: images[0].naturalHeight, + flipY: false + })); + }); + }); + } + loadVideo(src, videoConfig) { + return __awaiter(this, void 0, void 0, function* () { + const config = Object.assign({ + autoplay: true, + muted: true, + loop: false, + volume: 1 + }, videoConfig); + const video = this._toVideoElement(src, config); + return this._load([video], resolve => { + const { + autoplay, + muted + } = config; + video.currentTime = 0; + if (autoplay && muted) { + video.play().catch(() => void 0); + } + resolve(new TextureVideo({ + source: video, + width: video.videoWidth, + height: video.videoHeight, + flipY: true + })); + }); + }); + } + _load(content, onLoad) { + const loader = this._loadChecker; + return new Promise((resolve, reject) => { + loader.once("ready", evt => { + if (evt.errorCount > 0) return; + onLoad(resolve); + }); + loader.once("error", reject); + loader.check(content); + }); + } + _toImageArray(src) { + const srcs = Array.isArray(src) ? src : [src]; + return srcs.map(source => { + if (isString(source)) { + const imgEl = new Image(); + imgEl.crossOrigin = "anonymous"; + imgEl.src = source; + return imgEl; + } else { + return source; + } + }); + } + _toVideoElement(src, { + muted, + loop, + volume + }) { + if (src instanceof HTMLVideoElement) { + return src; + } + const video = document.createElement("video"); + video.crossOrigin = "anonymous"; + video.playsInline = true; + video.setAttribute("webkit-playsinline", ""); + video.muted = muted; + video.volume = volume; + video.loop = loop; + if (Array.isArray(src)) { + src.forEach(source => this._appendSourceElement(video, source)); + } else { + this._appendSourceElement(video, src); + } + const sourceCount = video.querySelectorAll("source").length; + if (sourceCount > 0 && video.readyState < 1) { + video.load(); + } + return video; + } + _appendSourceElement(video, src) { + if (src instanceof HTMLSourceElement) { + return src; + } + const sourceEl = document.createElement("source"); + sourceEl.src = src; + video.appendChild(sourceEl); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @internal + */ + class FrameAnimator { + /** */ + constructor(maxDeltaTime, context = window) { + this.maxDeltaTime = maxDeltaTime; + this._context = context; + this._rafId = -1; + this._rafTimer = -1; + this._lastUpdateTime = -1; + } + start(callback) { + const context = this._context; + // No context / callback set + if (!context || !callback) return; + // Animation already started + if (this._rafId >= 0 || this._rafTimer >= 0) return; + const loop = (_time, frame) => { + const time = Date.now(); + const delta = Math.min(time - this._lastUpdateTime, this.maxDeltaTime * 1000); + callback(delta, frame); + this._lastUpdateTime = time; + this._rafId = context.requestAnimationFrame(loop); + }; + this._lastUpdateTime = Date.now(); + this._rafId = context.requestAnimationFrame(loop); + } + stop() { + if (this._rafId >= 0) { + this._context.cancelAnimationFrame(this._rafId); + } + if (this._rafTimer >= 0) { + clearTimeout(this._rafTimer); + } + this._rafId = -1; + this._rafTimer = -1; + } + changeContext(context) { + this.stop(); + this._context = context; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Automatic resizer that uses both ResizeObserver and window resize event + */ + class AutoResizer { + get useResizeObserver() { + return this._useResizeObserver; + } + /** + * Returns whether AutoResizer is enabled + */ + get enabled() { + return this._enabled; + } + /** */ + constructor(useResizeObserver, onResize) { + // eslint-disable-next-line @typescript-eslint/member-ordering + this._skipFirstResize = (() => { + let isFirstResize = true; + return () => { + if (isFirstResize) { + isFirstResize = false; + return; + } + this._onResize(); + }; + })(); + this._useResizeObserver = useResizeObserver; + this._enabled = false; + this._resizeObserver = null; + this._onResize = onResize; + } + /** + * Enable resizer + */ + enable(element) { + if (this._enabled) { + this.disable(); + } + if (this._useResizeObserver && !!window.ResizeObserver) { + const bbox = element.getBoundingClientRect(); + const resizeImmediate = bbox.width !== 0 || bbox.height !== 0; + const resizeObserver = new ResizeObserver(resizeImmediate ? this._skipFirstResize : this._onResize); + resizeObserver.observe(element); + this._resizeObserver = resizeObserver; + } else { + window.addEventListener(EVENTS$1.RESIZE, this._onResize); + } + this._enabled = true; + return this; + } + /** + * Disable resizer + */ + disable() { + if (!this._enabled) return this; + const resizeObserver = this._resizeObserver; + if (resizeObserver) { + resizeObserver.disconnect(); + this._resizeObserver = null; + } else { + window.removeEventListener(EVENTS$1.RESIZE, this._onResize); + } + this._enabled = false; + return this; + } + } + + /** + * A manager class for autoplay feature. + * @ko Autoplay 기능의 매니저 클래스. + * @since 4.0.0 + */ + class Autoplay { + /** + * Whether autoplay is enabled or not + * @ko 자동재생 활성화 여부를 나타내는 값 + * @readonly + * @since 4.0.0 + */ + get enabled() { + return this._enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * Whether autoplay is updating the camera at the moment + * @ko 현재 자동재생이 동작중인지 여부를 나타내는 값 + * @readonly + * @since 4.0.0 + */ + get playing() { + return this._enabled && !this._interrupted; + } + /** + * Reactivation delay after mouse input in milisecond. + * @ko 재활성화되기까지의 시간 (밀리초 단위) + * @default 2000 + * @since 4.0.0 + */ + get delay() { + return this._delay; + } + set delay(val) { + this._delay = val; + } + /** + * Reactivation delay after mouse leave when using {@link AutoplayOptions#pauseOnHover} + * @ko {@link AutoplayOptions#pauseOnHover} 사용시 마우스가 캔버스 영역을 떠난 뒤 자동재생이 다시 활성화되기까지의 시간 + * @default 0 + * @since 4.0.0 + */ + get delayOnMouseLeave() { + return this._delayOnMouseLeave; + } + set delayOnMouseLeave(val) { + this._delayOnMouseLeave = val; + } + /** + * Y-axis(yaw) rotation speed + * @ko Y-축 회전(yaw)의 속도 + * @default 1 + * @since 4.0.0 + */ + get speed() { + return this._speed; + } + set speed(val) { + this._speed = val; + } + /** + * Whether to pause rotation on mouse hover + * @ko 마우스가 캔버스 영역에 들어왔을 때 자동재생을 정지할지 여부 + * @default false + * @since 4.0.0 + */ + get pauseOnHover() { + return this._pauseOnHover; + } + set pauseOnHover(val) { + this._pauseOnHover = val; + } + /** + * Whether user can interrupt the rotation with click/wheel input + * @ko 클릭이나 휠같은 사용자 인터랙션시 자동재생을 멈출지 여부 + * @default true + * @since 4.0.0 + */ + get canInterrupt() { + return this._canInterrupt; + } + set canInterrupt(val) { + this._canInterrupt = val; + } + /** + * Whether to disable autoplay on user interrupt + * @ko 사용자 동작에 의해 자동재생이 정지할 때, {@link Autoplay#disable}을 호출하여 자동재생을 영구히 정지할지 여부 + * @default false + * @since 4.0.0 + */ + get disableOnInterrupt() { + return this._disableOnInterrupt; + } + set disableOnInterrupt(val) { + this._disableOnInterrupt = val; + } + /** + * Create new AutoPlayer instance + * @param camera - Instance of the {@link Camera} {@ko Camera의 인스턴스} + * @param element - Canvas element {@ko 캔버스 엘리먼트} + * @param options - Autoplay options {@ko 자동재생 옵션들} + * @since 4.0.0 + */ + constructor(viewer, element, options) { + this._onInputStart = () => { + if (!this._canInterrupt) return; + this._interrupted = true; + this._clearTimeout(); + }; + this._onInputEnd = () => { + this._setUninterruptedAfterDelay(this._delay); + }; + this._onGyroEnable = () => { + this.disable(); + }; + this._onMouseEnter = () => { + if (!this._pauseOnHover) return; + this._interrupted = true; + this._hovering = true; + }; + this._onMouseLeave = () => { + if (!this._pauseOnHover) return; + this._hovering = false; + this._setUninterruptedAfterDelay(this._delayOnMouseLeave); + }; + this._camera = viewer.camera; + this._control = viewer.control; + this._element = element; + this._enabled = false; + this._interrupted = false; + this._interruptionTimer = -1; + this._hovering = false; + const { + delay = 2000, + delayOnMouseLeave = 0, + speed = 1, + pauseOnHover = false, + canInterrupt = true, + disableOnInterrupt = false + } = getObjectOption(options); + this._enableBlocked = !options; + this._delay = delay; + this._delayOnMouseLeave = delayOnMouseLeave; + this._speed = speed; + this._pauseOnHover = pauseOnHover; + this._canInterrupt = canInterrupt; + this._disableOnInterrupt = disableOnInterrupt; + } + /** + * Destroy the instance and remove all event listeners attached + * @ko 인스턴스를 제거하고 연결된 모든 이벤트 핸들러를 삭제합니다. + * @since 4.0.0 + */ + destroy() { + this.disable(); + } + /** + * Rotate camera by given deltaTime + * @ko 주어진 deltaTime만큼 카메라를 회전시킵니다. + * @param deltaTime - Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위} + * @since 4.0.0 + */ + update(deltaTime) { + if (!this._enabled) return; + if (this._interrupted) { + if (this._disableOnInterrupt) { + this.disable(); + } + return; + } + const camera = this._camera; + const delta = -this._speed * deltaTime / 100; + camera.yaw = circulate(camera.yaw + delta, 0, 360); + } + /** + * Enable autoplay and add event listeners. + * @ko 자동재생을 활성화하고 이벤트리스너들을 추가합니다. + * @since 4.0.0 + */ + enable() { + const control = this._control; + const element = this._element; + if (this._enabled || control.gyro.enabled) return; + control.rotate.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.rotate.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.zoom.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.zoom.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.gyro.on(CONTROL_EVENTS.ENABLE, this._onGyroEnable); + element.addEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter, false); + element.addEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave, false); + this._enabled = true; + this._enableBlocked = false; + } + /** + * Enable autoplay after current `delay` value. + * @ko 현재의 `delay`값만큼 시간이 지난 다음에 자동재생을 활성화합니다. + * @since 4.0.0 + */ + enableAfterDelay() { + this.enable(); + this._interrupted = true; + this._setUninterruptedAfterDelay(this._delay); + } + /** + * Disable autoplay and remove all event handlers. + * @ko 자동재생을 비활성화하고 모든 이벤트 핸들러를 제거합니다. + * @since 4.0.0 + */ + disable() { + if (!this._enabled) return; + const control = this._control; + const element = this._element; + control.rotate.off(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.rotate.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.zoom.off(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.zoom.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.gyro.off(CONTROL_EVENTS.ENABLE, this._onGyroEnable); + element.removeEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter, false); + element.removeEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave, false); + this._enabled = false; + this._interrupted = false; + this._hovering = false; + this._clearTimeout(); + } + _setUninterruptedAfterDelay(delay) { + if (this._hovering) return; + this._clearTimeout(); + if (delay > 0) { + this._interruptionTimer = window.setTimeout(() => { + this._interrupted = false; + this._interruptionTimer = -1; + }, delay); + } else { + this._interrupted = false; + this._interruptionTimer = -1; + } + } + _clearTimeout() { + if (this._interruptionTimer >= 0) { + window.clearTimeout(this._interruptionTimer); + this._interruptionTimer = -1; + } + } + } + + /** + * WebXR manager class + * @ko WebXR 매니저 클래스 + * @since 4.0.0 + */ + class XRManager extends Component__default["default"] { + /** + * Create new instance. + * 새 인스턴스를 생성합니다. + * @param ctx - Instance of WebGL context helper {@ko WebGL 콘텍스트 헬퍼의 인스턴스} + * @param options - Options {@ko 옵션들} + */ + constructor(ctx, options = {}) { + super(); + /** + * Destroy instance and end XR session if there was any. + * @ko 인스턴스를 제거하고, XR 세션이 존재할 경우 종료합니다. + * @since 4.0.0 + */ + this.destroy = () => { + this.exit(); + this.off(); + }; + this._onSessionEnd = () => { + this.exit(); + this.trigger(EVENTS.VR_END); + }; + this._xrSession = null; + this._xrRefSpace = null; + this._ctx = ctx; + this._options = options; + } + /** + * Returns WebXR availability. + * @ko WebXR 사용 가능 여부를 반환합니다. + * @since 4.0.0 + */ + isAvailable() { + return __awaiter(this, void 0, void 0, function* () { + // eslint-disable-next-line compat/compat + const xr = window.navigator.xr; + if (!xr) return false; + return xr.isSessionSupported(SESSION_VR).then(available => { + return available; + }).catch(() => { + return false; + }); + }); + } + /** + * Enter VR session + * @ko VR 세션에 진입합니다. + * @since 4.0.0 + */ + enter() { + return __awaiter(this, void 0, void 0, function* () { + const ctx = this._ctx; + // eslint-disable-next-line compat/compat + const xr = window.navigator.xr; + if (!xr) return; + yield GyroControl.requestSensorPermission(); + const options = Object.assign({ + requiredFeatures: [XR_REFERENCE_SPACE] + }, this._options); + yield ctx.makeXRCompatible(); + const session = yield xr.requestSession(SESSION_VR, options); + ctx.bindXRLayer(session); + const refSpace = yield session.requestReferenceSpace(XR_REFERENCE_SPACE); + this._setSession(session, refSpace); + this.trigger(EVENTS.VR_START, { + session + }); + }); + } + /** + * Exit VR session + * @ko VR 세션에서 나갑니다. + * @since 4.0.0 + */ + exit() { + const xrSession = this._xrSession; + if (xrSession) { + xrSession.end().catch(() => void 0); + } + this._xrSession = null; + this._xrRefSpace = null; + } + /** + * @hidden + */ + canRender(frame) { + const refSpace = this._xrRefSpace; + if (!refSpace) return false; + const pose = frame.getViewerPose(refSpace); + return !!pose; + } + /** + * @hidden + */ + getEyeParams(frame) { + const session = frame.session; + const pose = frame.getViewerPose(this._xrRefSpace); + if (!pose) return null; + const glLayer = session.renderState.baseLayer; + if (!glLayer) return null; + return pose.views.map(view => { + const viewport = glLayer.getViewport(view); + const vMatrix = view.transform.inverse.matrix; + return { + viewport, + vMatrix, + pMatrix: view.projectionMatrix + }; + }); + } + _setSession(session, refSpace) { + this._xrSession = session; + this._xrRefSpace = refSpace; + session.addEventListener(EVENTS$1.XR_END, this._onSessionEnd); + } + } + + /** + * Hotspot data + * @ko 핫스팟 데이터 + * @since 4.0.0 + */ + class Hotspot { + constructor(element, position) { + this.element = element; + this.position = position; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Hotspot renderer + * @ko Hotspot 렌더러 + * @since 4.0.0 + */ + class HotspotRenderer { + /** + * Create new instance + * @ko 새 인스턴스를 생성합니다. + * @param rootEl - Container element for hotspots {@ko 핫스팟들의 컨테이너 엘리먼트} + * @param renderer - instance of WebGLRenderer {@ko WebGLRenderer의 인스턴스} + * @param options - Hotspot options {@ko Hotspot 옵션들 } + */ + constructor(rootEl, renderer, { + zoom = false + }) { + this._containerEl = getNullableElement(`.${DEFAULT_CLASS.HOTSPOT_CONTAINER}`, rootEl); + this._renderer = renderer; + this._hotspots = []; + this._zoom = zoom; + } + /** + * Refresh hotspots by collecting hotspot elements from current hotspot root element + * @ko 현재 핫스팟 루트 엘리먼트 내에서 핫스팟 엘리먼트들을 수집하여 갱신합니다. + * @throws {ERROR_CODES.INSUFFICIENT_ARGS} if data-position doesn't include all x, y, z values {@ko data-position이 x, y, z좌표를 전부 포함하고 있지 않을 때} + */ + refresh() { + const container = this._containerEl; + if (!container) return; + const hotspotEls = [].slice.apply(container.querySelectorAll(`.${DEFAULT_CLASS.HOTSPOT}`)); + this._hotspots = hotspotEls.map(el => this._parseHotspot(el)); + } + /** + * Render hotspots + * @ko 핫스팟들을 렌더링합니다. + * @param camera - Instance of Camera {@ko Camera의 인스턴스} + */ + render(camera) { + const hotspots = this._hotspots; + const halfWidth = this._renderer.width * 0.5; + const halfHeight = this._renderer.height * 0.5; + const zoom = camera.zoom; + const centerTransform = "translate(-50%, -50%)"; + const zoomTransform = this._zoom ? `scale(${zoom})` : ""; + hotspots.forEach(hotspot => { + const position = hotspot.position; + const relPos = glMatrix.vec3.create(); + glMatrix.vec3.copy(relPos, position); + glMatrix.vec3.transformMat4(relPos, relPos, camera.viewMatrix); + glMatrix.vec3.transformMat4(relPos, relPos, camera.projectionMatrix); + if (relPos[2] > 1 || relPos[2] < 0) { + hotspot.element.classList.remove(DEFAULT_CLASS.HOTSPOT_VISIBLE); + return; + } + const screenPos = glMatrix.vec2.fromValues(relPos[0] * halfWidth + halfWidth, -relPos[1] * halfHeight + halfHeight); + hotspot.element.classList.add(DEFAULT_CLASS.HOTSPOT_VISIBLE); + hotspot.element.style.transform = [centerTransform, `translate(${screenPos[0]}px, ${screenPos[1]}px)`, zoomTransform].join(" "); + }); + } + _parseHotspot(element) { + const yawStr = element.dataset.yaw; + const pitchStr = element.dataset.pitch; + const positionStr = element.dataset.position; + if (yawStr || pitchStr) { + const yaw = yawStr ? parseFloat(yawStr) : 0; + const pitch = pitchStr ? parseFloat(pitchStr) : 0; + const position = this._yawPitchToVec3(yaw, pitch); + return new Hotspot(element, position); + } else if (positionStr) { + const pos = positionStr.split(" ").map(val => parseFloat(val)); + if (pos.length < 3) { + throw new View360Error(ERROR.MESSAGES.INSUFFICIENT_ARGS(positionStr, "hotspot attribute \"data-position\""), ERROR.CODES.INSUFFICIENT_ARGS); + } + return new Hotspot(element, glMatrix.vec3.fromValues(pos[0], pos[1], pos[2])); + } else { + // Place hotspot at yaw: 0, pitch: 0 + const defaultPos = glMatrix.vec3.fromValues(0, 0, -1); + return new Hotspot(element, defaultPos); + } + } + _yawPitchToVec3(yaw, pitch) { + const yawRad = yaw * DEG_TO_RAD; + const pitchRad = pitch * DEG_TO_RAD; + const position = glMatrix.vec3.create(); + position[1] = Math.sin(pitchRad); + position[2] = Math.cos(pitchRad); + position[0] = position[2] * Math.sin(-yawRad); + position[2] = -position[2] * Math.cos(-yawRad); + return position; + } + } + + /** + * @hidden + */ + class VertexArrayObject { + get count() { + return this.geometry.indicies.count; + } + constructor(obj, geometry, buffers) { + this.obj = obj; + this.geometry = geometry; + this.buffers = buffers; + } + } + + /** + * @hidden + */ + class WebGLContext { + get canvas() { + return this._canvas; + } + get maxTextureSize() { + return this._maxTextureSize; + } + get isWebGL2() { + return this._isWebGL2; + } + get supportVAO() { + return this._isWebGL2 || !!this._extensions.vao; + } + get lost() { + return this._contextLost; + } + get debug() { + return this._debug; + } + constructor(canvas, debug) { + this._onContextLost = () => { + const canvas = this._canvas; + canvas.classList.add(DEFAULT_CLASS.CTX_LOST); + this._contextLost = true; + }; + this._onContextRestore = () => { + const canvas = this._canvas; + canvas.classList.remove(DEFAULT_CLASS.CTX_LOST); + this._contextLost = false; + }; + this._canvas = canvas; + this._contextLost = false; + this._debug = debug; + this._extensions = { + vao: null, + loseContext: null + }; + } + init() { + const canvas = this._canvas; + const { + gl, + isWebGL2 + } = this._getContext(canvas); + this._gl = gl; + this._maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); + this._isWebGL2 = isWebGL2; + if (!this._isWebGL2) { + this._extensions.vao = gl.getExtension("OES_vertex_array_object"); + } + this._extensions.loseContext = gl.getExtension("WEBGL_lose_context"); + canvas.addEventListener(EVENTS$1.CONTEXT_LOST, this._onContextLost); + canvas.addEventListener(EVENTS$1.CONTEXT_RESTORED, this._onContextRestore); + // gl.enable(gl.DEPTH_TEST); + } + + destroy() { + const gl = this._gl; + const canvas = this._canvas; + if (gl) { + // gl is not defined when destroy is called before init + gl.bindBuffer(gl.ARRAY_BUFFER, null); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + } + canvas.removeEventListener(EVENTS$1.CONTEXT_LOST, this._onContextLost); + canvas.removeEventListener(EVENTS$1.CONTEXT_RESTORED, this._onContextRestore); + } + forceLoseContext() { + const extension = this._extensions.loseContext; + if (!extension) return; + extension.loseContext(); + } + forceRestoreContext() { + const extension = this._extensions.loseContext; + if (!extension) return; + extension.restoreContext(); + } + clear() { + const gl = this._gl; + gl.clear(gl.COLOR_BUFFER_BIT); + } + resize() { + const gl = this._gl; + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + } + viewport(x, y, width, height) { + const gl = this._gl; + gl.viewport(x, y, width, height); + } + createVAO(geometry, shaderProgram) { + const nativeVAO = this._createNativeVAO(); + const vao = new VertexArrayObject(nativeVAO, geometry, { + indicies: this._createBuffer(), + position: this._createBuffer(), + uv: this._createBuffer() + }); + if (nativeVAO) { + this._bindNativeVAO(nativeVAO); + this._supplyGeometryData(vao, shaderProgram); + this._bindNativeVAO(null); + this._unbindBuffers(); + } + return vao; + } + draw(vao, shaderProgram) { + const gl = this._gl; + if (vao.obj) { + this._bindNativeVAO(vao.obj); + } else { + this._supplyGeometryData(vao, shaderProgram); + } + gl.drawElements(gl.TRIANGLES, vao.count, gl.UNSIGNED_SHORT, 0); + if (vao.obj) { + this._bindNativeVAO(null); + } else { + this._unbindBuffers(); + } + } + releaseVAO(vao) { + if (vao.obj) { + this._deleteNativeVAO(vao.obj); + } + this._deleteBuffer(vao.buffers.indicies); + this._deleteBuffer(vao.buffers.position); + this._deleteBuffer(vao.buffers.uv); + } + getUniformLocations(program, uniforms) { + const gl = this._gl; + const uniformLocations = Object.keys(uniforms).reduce((locations, key) => { + locations[key] = gl.getUniformLocation(program, key); + return locations; + }, {}); + return Object.assign(Object.assign({}, this._getCommonUniformLocations(program)), uniformLocations); + } + updateCommonUniforms(entity, camera, shaderProgram) { + const gl = this._gl; + const uniformLocations = shaderProgram.uniformLocations; + // We're using "matrix"(=local matrix) here for efficiency + // As projection doesn't require world matrix, as it doesn't have any parent or child + const matrix = entity.matrix; + const mvMatrix = glMatrix.mat4.create(); + glMatrix.mat4.multiply(mvMatrix, camera.viewMatrix, matrix); + gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix); + gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, camera.projectionMatrix); + } + updateVRUniforms(shaderProgram, mvMatrix, pMatrix, eyeIndex) { + const gl = this._gl; + const uniformLocations = shaderProgram.uniformLocations; + gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix); + gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, pMatrix); + if (uniformLocations.uEye) { + gl.uniform1f(uniformLocations.uEye, eyeIndex); + } + } + updateUniforms(shaderProgram) { + const gl = this._gl; + const uniforms = shaderProgram.uniforms; + const uniformLocations = shaderProgram.uniformLocations; + for (const key in uniforms) { + const uniform = uniforms[key]; + const location = uniformLocations[key]; + if (!uniform) continue; + if (uniform.needsUpdate) { + uniform.update(gl, location, this._isWebGL2); + } + } + } + releaseShaderResources(shaderProgram) { + const gl = this._gl; + const uniforms = shaderProgram.uniforms; + for (const key in uniforms) { + const uniform = uniforms[key]; + if (!uniform) continue; + if (uniform.needsUpdate) { + uniform.destroy(gl); + } + } + gl.deleteProgram(shaderProgram.program); + } + useProgram(shaderProgram) { + const gl = this._gl; + gl.useProgram(shaderProgram.program); + } + createProgram(vertexShader, fragmentShader) { + const gl = this._gl; + const program = gl.createProgram(); + const vs = this._compileShader(gl.VERTEX_SHADER, vertexShader); + const fs = this._compileShader(gl.FRAGMENT_SHADER, fragmentShader); + gl.attachShader(program, vs); + gl.attachShader(program, fs); + gl.bindAttribLocation(program, 0, "position"); + gl.bindAttribLocation(program, 1, "uv"); + gl.linkProgram(program); + if (this._debug && !gl.getProgramParameter(program, gl.LINK_STATUS)) { + let shaderLog = null; + if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) { + shaderLog = gl.getShaderInfoLog(vs); + } else if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) { + shaderLog = gl.getShaderInfoLog(fs); + } + throw new View360Error(ERROR.MESSAGES.FAILED_LINKING_PROGRAM(gl.getProgramInfoLog(program), shaderLog), ERROR.CODES.FAILED_LINKING_PROGRAM); + } + gl.deleteShader(vs); + gl.deleteShader(fs); + return program; + } + createWebGLTexture(texData) { + const gl = this._gl; + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texData.wrapS); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texData.wrapT); + if (!texData.isVideo() && this._isWebGL2) { + const gl2 = gl; + gl2.texStorage2D(gl2.TEXTURE_2D, 1, gl2.RGBA8, texData.width, texData.height); + } + return texture; + } + createWebGLCubeTexture(texData, size) { + const gl = this._gl; + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, texData.wrapS); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, texData.wrapT); + if (this._isWebGL2) { + const gl2 = gl; + gl2.texStorage2D(gl2.TEXTURE_CUBE_MAP, 1, gl2.RGBA8, size, size); + } + return texture; + } + makeXRCompatible() { + return __awaiter(this, void 0, void 0, function* () { + const gl = this._gl; + const attributes = gl.getContextAttributes(); + if (attributes && attributes.xrCompatible !== true) { + yield gl.makeXRCompatible(); + } + }); + } + bindXRLayer(session) { + const gl = this._gl; + const xrLayer = new XRWebGLLayer(session, gl); + session.updateRenderState({ + baseLayer: xrLayer + }); + } + bindXRFrame(frame) { + const gl = this._gl; + const session = frame.session; + const baseLayer = session.renderState.baseLayer; + gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer); + } + useDefaultFrameBuffer() { + const gl = this._gl; + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + } + _createBuffer() { + return this._gl.createBuffer(); + } + _deleteBuffer(buffer) { + return this._gl.deleteBuffer(buffer); + } + _createNativeVAO() { + const gl = this._gl; + if (this._isWebGL2) { + return gl.createVertexArray(); + } else { + const ext = this._extensions.vao; + return (ext === null || ext === void 0 ? void 0 : ext.createVertexArrayOES()) || null; + } + } + _bindNativeVAO(vao) { + const gl = this._gl; + if (this._isWebGL2) { + gl.bindVertexArray(vao); + } else { + const ext = this._extensions.vao; + ext === null || ext === void 0 ? void 0 : ext.bindVertexArrayOES(vao); + } + } + _deleteNativeVAO(vao) { + const gl = this._gl; + if (this._isWebGL2) { + gl.deleteVertexArray(vao); + } else { + const ext = this._extensions.vao; + ext === null || ext === void 0 ? void 0 : ext.deleteVertexArrayOES(vao); + } + } + _supplyGeometryData(vao, shaderProgram) { + const geometry = vao.geometry; + this._supplyIndiciesData(geometry.indicies, vao.buffers.indicies); + this._supplyAttributeData(geometry.vertices, shaderProgram.program, "position", vao.buffers.position); + this._supplyAttributeData(geometry.uvs, shaderProgram.program, "uv", vao.buffers.uv); + } + _unbindBuffers() { + const gl = this._gl; + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + gl.bindBuffer(gl.ARRAY_BUFFER, null); + } + _supplyIndiciesData(indicies, buffer) { + const gl = this._gl; + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicies.data, gl.STATIC_DRAW); + } + _supplyAttributeData(attribute, program, name, buffer) { + const gl = this._gl; + const attribLocation = gl.getAttribLocation(program, name); + // Attribute not used + if (attribLocation < 0) return; + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData(gl.ARRAY_BUFFER, attribute.data, gl.STATIC_DRAW); + gl.vertexAttribPointer(attribLocation, attribute.itemSize, gl.FLOAT, false, 0, 0); + gl.enableVertexAttribArray(attribLocation); + } + _compileShader(type, src) { + const gl = this._gl; + const shader = gl.createShader(type); + gl.shaderSource(shader, src); + gl.compileShader(shader); + return shader; + } + _getCommonUniformLocations(program) { + const gl = this._gl; + return { + uMVMatrix: gl.getUniformLocation(program, "uMVMatrix"), + uPMatrix: gl.getUniformLocation(program, "uPMatrix") + }; + } + _getContext(canvas) { + const webglIdentifiers = ["webgl2", "webgl", "experimental-webgl", "webkit-3d", "moz-webgl"]; + let context = null; + let isWebGL2 = false; + const contextAttributes = { + preserveDrawingBuffer: false, + antialias: false + }; + const onWebglContextCreationError = e => e.statusMessage; + canvas.addEventListener(EVENTS$1.CONTEXT_CREATE_ERROR, onWebglContextCreationError); + for (const identifier of webglIdentifiers) { + try { + context = canvas.getContext(identifier, contextAttributes); + isWebGL2 = identifier === "webgl2"; + } catch (t) {} // eslint-disable-line no-empty + if (context) { + break; + } + } + canvas.removeEventListener(EVENTS$1.CONTEXT_CREATE_ERROR, onWebglContextCreationError); + if (!context) { + throw new View360Error(ERROR.MESSAGES.WEBGL_NOT_SUPPORTED, ERROR.CODES.WEBGL_NOT_SUPPORTED); + } + return { + gl: context, + isWebGL2 + }; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection renderer, based on WebGL + * @ko WebGL 기반의 프로젝션 렌더러 + * @since 4.0.0 + */ + class WebGLRenderer { + /** + * Canvas element + * @ko 캔버스 엘리먼트 + * @since 4.0.0 + */ + get canvas() { + return this._canvas; + } + /** + * Canvas's width (`devicePixelRatio` is not applied) + * @ko 캔버스의 보이는 너비 (`devicePixelRatio`가 적용되지 않은) + * @since 4.0.0 + */ + get width() { + return this._elementSize.x; + } + /** + * Canvas's height (`devicePixelRatio` is not applied) + * @ko 캔버스의 높이 (`devicePixelRatio`가 적용되지 않은) + * @since 4.0.0 + */ + get height() { + return this._elementSize.y; + } + /** + * Current `devicePixelRatio` value. + * @ko 현재 `devicePixelRatio` 값. + * @since 4.0.0 + * @example + * ```js + * cosnt renderingWidth = view360.renderer.width * view360.renderer.pixelRatio; + * ``` + */ + get pixelRatio() { + return this._pixelRatio; + } + /** + * Width / height ratio (= width / height) + * @ko 너비 / 높이의 비율 (= width / height) + * @since 4.0.0 + * @example + * ```js + * const aspect = view360.renderer.width / view360.renderer.pixelRatio; + * assert(aspect === view360.renderer.aspect); + * ``` + */ + get aspect() { + return this._elementSize.x / this._elementSize.y; + } + /** + * Create new instance + * @ko 새 인스턴스를 생성합니다. + * @param canvas - Canvas element {@ko 캔버스 엘리먼트} + * @param debug - Whether to enable WebGL debugging {@ko WebGL debug 활성화 여부 } + */ + constructor(canvas, debug) { + this._canvas = canvas; + this._elementSize = { + x: 0, + y: 0 + }; + this._pixelRatio = 1; + this.ctx = new WebGLContext(canvas, debug); + } + /** + * Destroy instance and release all resources. + * @ko 인스턴스를 제거하고 사용된 리소스를 전부 해제합니다. + * @since 4.0.0 + */ + destroy() { + const canvas = this._canvas; + this.ctx.destroy(); + canvas.width = 1; + canvas.height = 1; + } + /** + * Resize canvas and renew inner size cache. + * @ko 캔버스의 크기를 재계산해서 내부의 사이즈 캐시값을 갱신합니다. + * @since 4.0.0 + */ + resize() { + const canvas = this._canvas; + const canvasSize = this._elementSize; + const devicePixelRatio = window.devicePixelRatio; + canvasSize.x = canvas.clientWidth; + canvasSize.y = canvas.clientHeight; + canvas.width = canvasSize.x * devicePixelRatio; + canvas.height = canvasSize.y * devicePixelRatio; + this._pixelRatio = devicePixelRatio; + this.ctx.resize(); + } + /** + * Render projection + * @ko 프로젝션을 렌더링합니다. + * @param projection - Projection to render {@ko 렌더링할 프로젝션} + * @param cameraa - Camera instance {@ko 카메라의 인스턴스} + * @since 4.0.0 + */ + render(projection, camera) { + const ctx = this.ctx; + const mesh = projection.getMesh(); + if (ctx.lost || !mesh) return; + ctx.clear(); + ctx.useProgram(mesh.program); + ctx.updateCommonUniforms(mesh, camera, mesh.program); + projection.update(camera); + ctx.updateUniforms(mesh.program); + ctx.draw(mesh.vao, mesh.program); + } + /** + * Render VR frame, only used for rendering frames inside VR sessions. + * @ko VR 프레임을 렌더링합니다. VR 세션 진입 도중에만 사용됩니다. + * @internal + * @param projection - Projection to render {@ko 렌더링할 프로젝션} + * @param vr - Instance of XRManager {@ko XRManager의 인스턴스} + * @param frame - VR frame {@ko VR 프레임} + * @since 4.0.0 + */ + renderVR(projection, vr, frame) { + const ctx = this.ctx; + const mesh = projection.getMesh(); + const eyeParams = vr.getEyeParams(frame); + if (!eyeParams || !mesh) return; + ctx.bindXRFrame(frame); + ctx.useProgram(mesh.program); + ctx.updateUniforms(mesh.program); + eyeParams.forEach((eye, eyeIndex) => { + const viewport = eye.viewport; + // We're using "mesh.matrix"(=local matrix) here for efficiency + // As projection doesn't require world matrix, as it doesn't have any parent or child + const mvMatrix = glMatrix.mat4.multiply(glMatrix.mat4.create(), eye.vMatrix, mesh.matrix); + ctx.viewport(viewport.x, viewport.y, viewport.width, viewport.height); + ctx.updateVRUniforms(mesh.program, mvMatrix, eye.pMatrix, eyeIndex); + ctx.draw(mesh.vao, mesh.program); + }); + } + } + + /** + * Panorama 360 image viewer + * @ko 파노라마 360 이미지 뷰어 + * @since 4.0.0 + * @see View360Options + * @see View360Events + */ + class View360 extends Component__default["default"] { + /** + * Root element (`.view360-container`) + * @ko 루트 엘리먼트 (`.view360-container`) + * @since 4.0.0 + * @readonly + * @example + * ```html + *
+ * + *
+ * ``` + * ```ts + * import View360 from "@egjs/view360"; + * + * const viewer = new View360("#viewer"); + * console.log(viewer.rootEl); // Element with id "viewer" + * ``` + */ + get rootEl() { + return this._rootEl; + } + /** + * Projection renderer. + * @ko 프로젝션 렌더러. + * @since 4.0.0 + * @readonly + */ + get renderer() { + return this._renderer; + } + /** + * Projection camera. + * @ko 프로젝션 카메라. + * @since 4.0.0 + * @readonly + */ + get camera() { + return this._camera; + } + /** + * Rotate/Zoom Controller. + * @ko 회전/줌 컨트롤러. + * @since 4.0.0 + * @readonly + */ + get control() { + return this._control; + } + /** + * WebXR-based VR manager. + * @ko WebXR 기반의 VR 기능 매니저 인스턴스. + * @since 4.0.0 + * @readonly + * @example + * ```ts + * // Example: Enter VR + * // This must be called on user interaction, else will be rejected. + * viewer.vr.enter(); + * ``` + */ + get vr() { + return this._vr; + } + /** + * Hotspot renderer. + * You can also change options of {@link View360Options#hotspot} with this. + * @ko 핫스팟 렌더러 인스턴스. + * {@link View360Options#hotspot} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get hotspot() { + return this._hotspot; + } + /** + * An array of plugins added. + * @ko 추가된 플러그인의 배열 + * @since 4.0.0 + * @readonly + * @example + * ```ts + * const viewer = new View360("#el_id", { + * plugins: [new ControlBar()] + * }); + * + * console.log(viewer.plugins); // [ControlBar] + * + * viewer.addPlugins(new LoadingSpinner()) // [ControlBar, LoadingSpinner]; + * ``` + */ + get plugins() { + return this._plugins; + } + /** + * A instance of {@link Projection} that currently enabled. `null` if not initialized yet. + * You should call {@link View360#load} to change panorama src or projection type. + * @ko 현재 사용중인 {@link Projection}의 인스턴스. 프로젝션을 활성화하지 않았을 경우 `null`입니다. + * 파노라마 이미지 소스나 프로젝션 타입을 변경하려면 {@link View360#load}를 호출하면 됩니다. + * @since 4.0.0 + * @readonly + * @example + * ```ts + * const viewer = new View360 + * ``` + */ + get projection() { + return this._projection; + } + set projection(val) { + if (this._initialized && val) { + this.load(val); + } else { + this._projection = val; + } + } + /** + * A boolean value whether {@link View360#init init()} is called before. + * @ko {@link View360#init init()}이 호출되었는지 여부를 가리키는 값 + * @since 4.0.0 + * @readonly + * @example + * ```ts + * const viewer = new View360("#el", { autoInit: false }); + * + * console.log(viewer.initialized); // false + * + * await viewer.init(); + * + * console.log(viewer.initialized); // true + * ``` + */ + get initialized() { + return this._initialized; + } + /** + * Instance of the Autoplay manager. + * You can also change {@link View360Options#autoplay} options with this. + * @ko Autoplay 기능의 매니저 인스턴스. + * 이 인스턴스를 통해 {@link View360Options#autoplay} 옵션을 변경하는 것도 가능합니다. + * @since 4.0.0 + * @readonly + * @example + * ```ts + * // Disable autoplay + * viewer.autoplay.disable(); + * ``` + */ + get autoplay() { + return this._autoplay; + } + /** + * When this value is `true` and {@link View360Options#projection} is set, {@link View360#init init()} will be called automatically when instance is created. + * @ko 이 값이 `true`이고, {@link View360Options#projection}이 설정되었으면, 인스턴스 생성 시점에 자동으로 {@link View360#init init()}을 호출합니다. + * @default true + * @since 4.0.0 + * @example + * ```ts + * import View360, { EquirectProjection, EVENTS } from "@egjs/view360"; + * + * // viewer.init() is called on instance creation + * // But as `init` is asynchronous, you should wait for "ready" event if you want to do something after initialization. + * const viewer = new View360("#el_id", { + * autoInit: true, + * projection: new EquirectProjection({ src: "SRC_TO_URL" }) + * }); + * + * console.log(viewer.initialized); // false, as `init` is asynchronous + * + * viewer.once(EVENTS.READY, () => { + * console.log(viewer.initialized); // true + * }); + * ``` + */ + get autoInit() { + return this._autoInit; + } + /** + * When `true`, {@link View360#resize} is called when the canvas size is changed. + * @ko `true`일 경우, 캔버스의 크기가 변경되었을 때 자동으로 {@link View360#resize}를 호출합니다. + * @default true + * @since 4.0.0 + * @see View360#useResizeObserver + * @example + * ```ts + * const viewer = new View360("#el_id", { + * autoResize: true + * }); + * + * // This can trigger `viewer.resize()` if the canvas size was not 400px + * const canvas = viewer.renderer.canvas; + * canvas.style.width = "400px"; + * ``` + */ + get autoResize() { + return this._autoResize; + } + /** + * CSS selector for canvas element to render panorama image/video. + * The canvas element should be placed inside the root element. (Dont' have to be direct child) + * @ko 파노라마 이미지/비디오를 렌더링할 canvas 엘리먼트의 CSS 선택자 + * 캔버스 엘리먼트는 루트 엘리먼트 내부에 있어야합니다. 루트 엘리먼트의 직계 자식 엘리먼트(Direct child element)일 필요는 없습니다. + * @default "canvas" + * @since 4.0.0 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * + * ```ts + * const viewer = new View360("#el_id", { + * canvasSelector: "#canvas_to_select" + * }); + * ``` + */ + get canvasSelector() { + return this._canvasSelector; + } + /** + * When `true`, it will use {@link ResizeObserver} API to detect canvas size change when {@link View360Options#autoResize} is enabled. + * @ko `true`일 때 {@link View360Options#autoResize}가 활성화되었으면, 사용 가능한 환경에서 {@link ResizeObserver} API를 사용해서 캔버스 크기 변화를 추적합니다. + * @default true + * @since 4.0.0 + */ + get useResizeObserver() { + return this._useResizeObserver; + } + /** + * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} attribute for the canvas element. + * This is necessary for the keyboard controls. + * By default, `0` will be assigned. `null` to disable. + * @ko 캔버스 엘리먼트에 적용할 {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} 어트리뷰트의 값. + * 이 값을 설정해야만 키보드 컨트롤을 사용 가능합니다. + * 기본값으로 `0`이 설정됩니다. `null`로 지정하면 `tabindex`를 설정하지 않습니다. + * @see RotateControlOptions#disableKeyboard + * @default 0 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * tabindex: 5 + * }); + * ``` + * + * ```html + * + *
+ * + *
+ * ``` + */ + get tabIndex() { + return this._tabIndex; + } + set tabIndex(val) { + const canvas = this._renderer.canvas; + this._tabIndex = val; + if (val != null) { + canvas.tabIndex = val; + } else { + canvas.removeAttribute("tabindex"); + } + } + /** + * A maximum delta time between frames in seconds. + * It can prevent camera or control changing too fast when frame being late. + * @ko 프레임간 시간 차이의 최대값. (초 단위) + * 퍼포먼스 등의 이유로 프레임 렌더링이 늦어졌을 때, 화면이 갑작스럽게 바뀌는 것을 막아줍니다. + * @default 1 / 30 + * @since 4.0.0 + */ + get maxDeltaTime() { + return this._animator.maxDeltaTime; + } + set maxDeltaTime(val) { + this._animator.maxDeltaTime = val; + } + /** + * Enable WebGL debugging. Setting this to `true` can decrease performance. + * This is used internally on developing View360. + * @ko WebGL 디버깅을 활성화합니다. 이 값을 `true`로 할 경우 성능이 하락할 수 있습니다. + * 이 옵션은 View360을 개발하기 위해 내부적으로 사용됩니다. + * @default false + */ + get debug() { + return this._debug; + } + set debug(val) { + this._debug = val; + } + // Camera options + /** + * Initial yaw (y-axis rotation) value for camera. (in degrees, °) + * As View360 uses right-handed coordinate system internally, camera will rotate counter-clockwise by this value. + * @ko 카메라의 초기 yaw(y축 회전)값 (도 단위, °) + * View360은 오른손 좌표계를 사용하기 때문에, 카메라가 해당 값만큼 시계 반대방향으로 회전합니다. + * @default 0 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * initialYaw: 30 + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.yaw); // 30 + * }); + * ``` + */ + get initialYaw() { + return this._camera.initialYaw; + } + set initialYaw(val) { + this._camera.initialYaw = val; + } + /** + * Initial pitch (x-axis rotation) value for camera. (in degrees, °) + * As View360 uses right-handed coordinate system internally, positive value will make camera to look upside, while negative value will look down. + * @ko 카메라의 초기 pitch(x축 회전)값 (도 단위, °) + * View360은 오른손 좌표계를 사용하기 때문에, 양(+)의 값은 카메라가 위를 보게 하고, 음(-)의 값은 카메라가 아래를 보게 합니다. + * @default 0 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * initialPitch: 60 + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.pitch); // 60 + * }); + * ``` + */ + get initialPitch() { + return this._camera.initialPitch; + } + set initialPitch(val) { + this._camera.initialPitch = val; + } + /** + * Initial zoom value for camera. + * Setting this value to `2` will enlarge panorama 200% by width. + * @ko 카메라의 초기 줌 값. + * 이 값을 `2`로 설정할 경우 파노라마 이미지를 가로 기준 200%만큼 확대합니다. + * @default 1 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * initialZoom: 2 + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.zoom); // 2 + * }); + * ``` + */ + get initialZoom() { + return this._camera.initialZoom; + } + set initialZoom(val) { + this._camera.initialZoom = val; + } + /** + * Restrict yaw(y-axis rotation) range. (in degrees, °) + * @ko yaw(y축 회전) 범위를 제한합니다. (도 단위, °) + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * yawRange: [-30, 30] + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.yaw); // 0 + * viewer.camera.lookAt({ yaw: 60 }); + * console.log(viewer.camera.yaw); // 30 + * }); + * ``` + */ + get yawRange() { + return this._camera.yawRange; + } + set yawRange(val) { + this._camera.yawRange = val; + if (this._projection) this._projection.updateCamera(this._camera); + } + /** + * Restrict pitch(x-axis rotation) range. (in degrees, °) + * @ko pitch(x축 회전) 범위를 제한합니다. (도 단위, °) + * @default null + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * pitchRange: [-45, 45] + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.pitch); // 0 + * viewer.camera.lookAt({ pitch: 60 }); + * console.log(viewer.camera.pitch); // 45 + * }); + * ``` + */ + get pitchRange() { + return this._camera.pitchRange; + } + set pitchRange(val) { + this._camera.pitchRange = val; + if (this._projection) this._projection.updateCamera(this._camera); + } + /** + * Restrict camera zoom range. + * If `null`, a default zoom range from `0.6` to `10` will be used. + * @ko 카메라 줌 범위를 제한합니다. + * `null`일 경우 기본값으로 `0.6`에서 `10`의 범위를 사용합니다. + * @default null + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * zoomRange: [0.5, 4] + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.zoom); // 1 + * viewer.camera.lookAt({ zoom: 6 }); + * console.log(viewer.camera.zoom); // 4 + * }); + * ``` + */ + get zoomRange() { + return this._camera.zoomRange; + } + set zoomRange(val) { + this._camera.zoomRange = val; + if (this._projection) this._projection.updateCamera(this._camera); + } + /** + * Camera's horizontal FOV(Field of View). (in degrees, °) + * @ko 카메라의 수평 FOV(Field of View) 값. (도 단위, °) + * @default 90 + * @since 4.0.0 + * @example + * ```ts + * // Init with fov: 120 + * const viewer = new View360("#el_id", { fov: 120 }); + * + * // Back to 90 + * viewer.fov = 90; + * ``` + */ + get fov() { + return this._camera.fov; + } + set fov(val) { + const camera = this._camera; + const control = this._control; + camera.fov = val; + camera.updateMatrix(); + control.sync(); + } + // Control options + /** + * A control for camera rotation. + * You can also change options of {@link View360Options#rotate} with this. + * @ko 카메라 회전을 담당하는 컨트롤. + * {@link View360Options#rotate} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get rotate() { + return this._control.rotate; + } + /** + * A control for camera zoom. + * You can also change options of {@link View360Options#zoom} with this. + * @ko 카메라 줌을 담당하는 컨트롤. + * {@link View360Options#zoom} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get zoom() { + return this._control.zoom; + } + /** + * A control for camera rotation with gyroscope input. + * You can also change options of {@link View360Options#gyro} with this. + * @ko 자이로스코프를 통한 카메라 회전을 담당하는 컨트롤. + * {@link View360Options#gyro} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get gyro() { + return this._control.gyro; + } + /** + * Apply CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor} by current state of input when using mouse. + * If `true`, this will add CSS style to canvas element. It'll apply `cursor: "grab"` by default and `cursor: "grabbing"` when holding the mouse button. + * @ko 마우스 사용시 CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor}값을 자동으로 변경할지 여부. + * `true`일 경우 기본 상태에서 `cursor: "grab"`을, 입력 도중에 `cursor: "grabbing"`을 캔버스에 적용합니다. + * @default true + * @since 4.0.0 + */ + get useGrabCursor() { + return this._control.useGrabCursor; + } + set useGrabCursor(val) { + this._control.useGrabCursor = val; + } + /** + * Disable context menu which pops up on mouse right click. + * @ko 마우스 우클릭시 표시되는 컨텍스트 메뉴를 비활성화합니다. + * @default false + * @since 4.0.0 + */ + get disableContextMenu() { + return this._control.disableContextMenu; + } + set disableContextMenu(val) { + this._control.disableContextMenu = val; + } + /** + * If `true`, enables scroll on mobile(touch) devices on canvas. + * :::caution + * When this option is enabled, users must swipe horizontally first then vertically to change view up or down. + * ::: + * @ko `true`로 설정할 경우, 모바일(터치) 환경의 캔버스 영역 내에서 스크롤을 가능하게 합니다. + * :::caution + * 이 값을 활성화할 경우, 사용자가 카메라 뷰를 위/아래로 바꾸기 위해서는 먼저 가로로 스와이프한 이후에 세로로 스와이프해야만 합니다. + * ::: + * @since 4.0.0 + * @default true + */ + get scrollable() { + return this._control.scrollable; + } + set scrollable(val) { + this._control.scrollable = val; + } + /** + * If `true`, enables scroll by mouse wheel on canvas. + * :::caution + * When this option is enabled, zoom by mouse wheel will be disabled. + * ::: + * @ko `true`로 설정할 경우, 캔버스 영역 내에서 마우스 휠을 이용한 페이지 스크롤이 가능해집니다. + * :::caution + * 이 값을 활성화할 경우, 마우스 휠을 통한 줌이 불가능하게 됩니다. + * ::: + * @since 4.0.0 + * @default false + */ + get wheelScrollable() { + return this._control.wheelScrollable; + } + set wheelScrollable(val) { + this._control.wheelScrollable = val; + } + /** + * Create new instance of View360 + * @ko View360의 새로운 인스턴스를 생성합니다 + * @param root - Root element(`.view360-container`) to mount View360 + * Can be either a CSS selector or HTMLElement. + * {@ko View360을 마운트할 루트 엘리먼트, CSS 셀렉터나 HTMLElement를 지정 가능합니다.} + * @param options - Options to apply + * {@ko 적용할 옵션들} + * @example + * ```ts + * import View360, { EquirectProjection } from "@egjs/view360"; + * + * // Create new View360 instance + * const viewer = new View360("#id-of-a-container", { + * projection: new EquirectProjection({ + * src: "URL_TO_PANORAMA_IMAGE_OR_VIDEO", + * }) + * }); + * ``` + */ + constructor(root, { + projection = null, + initialYaw = 0, + initialPitch = 0, + initialZoom = 1, + yawRange = null, + pitchRange = null, + zoomRange = null, + fov = 90, + useGrabCursor = true, + disableContextMenu = false, + rotate = true, + zoom = true, + gyro = false, + scrollable = true, + wheelScrollable = false, + autoplay = false, + hotspot = {}, + autoInit = true, + autoResize = true, + canvasSelector = "canvas", + useResizeObserver = true, + on = {}, + plugins = [], + maxDeltaTime = 1 / 30, + tabIndex = 0, + debug = false + } = {}) { + super(); + /** + * Render a single panorama image/video frame. + * Rendering is performed automatically on demand, so you usually don't have to call this. + * Call this when a frame is not renewed after changing options. + * @ko 파노라마 이미지/비디오의 한 프레임을 렌더링합니다. + * 프레임 갱신은 보통 필요한 때에만 자동적으로 이루어지기 때문에, 보통은 이 메소드를 호출할 필요는 없습니다. + * 옵션 변경 이후에도 프레임 갱신이 이루어지지 않는다면, 이 메소드를 호출해주세요. + * @param delta Delta time in milisec. {@ko 프레임간 시간 차이, 밀리초 단위} + * @since 4.0.0 + */ + this.renderFrame = delta => { + const camera = this._camera; + const renderer = this._renderer; + const control = this._control; + const hotspot = this._hotspot; + const autoPlayer = this._autoplay; + const projection = this._projection; + if (!projection) return; + this._emit(EVENTS.BEFORE_RENDER); + if (autoPlayer.playing) { + autoPlayer.update(delta); + control.sync(); + } + if (camera.animation) { + camera.animation.update(delta); + } else { + control.update(delta); + } + renderer.render(projection, camera); + hotspot.render(camera); + if (camera.changed) { + this._emit(EVENTS.VIEW_CHANGE, { + yaw: camera.yaw, + pitch: camera.pitch, + zoom: camera.zoom, + quaternion: [camera.quaternion[0], camera.quaternion[1], camera.quaternion[2], camera.quaternion[3]] + }); + } + camera.onFrameRender(); + this._emit(EVENTS.RENDER); + }; + this._renderFrameOnDemand = delta => { + var _a; + const camera = this._camera; + const control = this._control; + const autoplay = this._autoplay; + const texture = (_a = this._projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (!this._initialized || !texture) return; + if (!camera.animation && !control.animating && !autoplay.playing && !texture.isVideo()) return; + this.renderFrame(delta); + }; + this._renderVRFrame = (_delta, frame) => { + const vr = this._vr; + const projection = this._projection; + const renderer = this._renderer; + if (!projection) return; + this._emit(EVENTS.BEFORE_RENDER); + renderer.renderVR(projection, vr, frame); + this._emit(EVENTS.RENDER); + }; + this._rootEl = getElement(root); + this._plugins = plugins; + this._initialized = false; + // Options + this._autoInit = autoInit; + this._autoResize = autoResize; + this._canvasSelector = canvasSelector; + this._useResizeObserver = useResizeObserver; + this._tabIndex = tabIndex; + this._debug = debug; + // Core components + const canvas = findCanvas(this._rootEl, canvasSelector); + this._renderer = new WebGLRenderer(canvas, debug); + this._camera = new Camera({ + initialYaw, + initialPitch, + initialZoom, + fov, + yawRange, + pitchRange, + zoomRange + }); + this._control = new PanoControl(canvas, this._camera, { + useGrabCursor, + scrollable, + wheelScrollable, + disableContextMenu, + rotate, + zoom, + gyro + }); + this._animator = new FrameAnimator(maxDeltaTime); + this._autoplay = new Autoplay(this, canvas, autoplay); + this._projection = projection; + this._autoResizer = new AutoResizer(useResizeObserver, () => this.resize()); + this._vr = new XRManager(this._renderer.ctx); + this._hotspot = new HotspotRenderer(this._rootEl, this._renderer, hotspot); + this._addEventHandlers(on); + if (projection && autoInit) { + this.init(); + } + } + /** + * Destroy instance and release all resources. + * @ko 인스턴스를 제거하고 모든 리소스를 해제합니다. + * @since 4.0.0 + */ + destroy() { + this._camera.destroy(); + this._animator.stop(); + this._renderer.destroy(); + this._control.destroy(); + this._autoResizer.disable(); + if (this._projection) { + this._projection.releaseAllResources(this._renderer.ctx); + this._projection = null; + } + this._plugins.forEach(plugin => plugin.destroy(this)); + this._initialized = false; + } + /** + * Initialize inner components and load projection src. + * @ko 내부 컴포넌트들을 초기화하고 프로젝션 소스를 로드합니다. + * @since 4.0.0 + */ + init() { + return __awaiter(this, void 0, void 0, function* () { + if (!this._projection) { + throw new View360Error(ERROR.MESSAGES.PROVIDE_PROJECTION_FIRST, ERROR.CODES.PROVIDE_PROJECTION_FIRST); + } + const renderer = this._renderer; + const camera = this._camera; + const control = this._control; + const animator = this._animator; + const hotspot = this._hotspot; + const projection = this._projection; + const canvas = renderer.canvas; + this._bindComponentEvents(); + renderer.ctx.init(); + this._resizeComponents(); + camera.updateMatrix(); + if (this._autoResize) { + this._autoResizer.enable(canvas); + } + if (!this._autoplay.enableBlocked) { + this._autoplay.enable(); + } + this._plugins.forEach(plugin => { + plugin.init(this); + }); + const texture = yield this._loadTexture(projection); + this._applyProjection(projection, texture, null); + hotspot.refresh(); + animator.start(this._renderFrameOnDemand); + yield control.enable(); + if (this._tabIndex != null && !canvas.hasAttribute("tabIndex")) { + canvas.tabIndex = this._tabIndex; + } + this._initialized = true; + this.renderFrame(0); + this._emit(EVENTS.READY); + }); + } + /** + * Load new panorama image/video and display it. + * This will {@link View360#init init()} View360 if it's not initialized yet. + * @ko 새로운 파노라마 이미지 혹은 비디오를 로드하고 표시합니다. + * 만약 View360이 아직 초기화되지 않았다면, {@link View360#init init()}을 호출합니다. + * @param projection - Projection & video options for new source. {@ko 새로운 파노라마 이미지/비디오에 적용할 옵션들} + * @returns `Promise` if load was successful. {@ko 프로젝션 로드에 성공했을 경우 `Promise`를 반환합니다. } + * @since 4.0.0 + * @example + * ```ts + * // Change to video + * viewer.load({ + * src: "URL_TO_NEW_VIDEO", + * video: true + * }); + * ``` + */ + load(projection) { + return __awaiter(this, void 0, void 0, function* () { + if (!projection) return false; + if (this._initialized) { + const texture = yield this._loadTexture(projection); + this._applyProjection(projection, texture, this._projection); + this.renderFrame(0); + } else { + // Should update internal options before init + this._projection = projection; + this.init(); + } + return true; + }); + } + /** + * Refresh component's size by current + * @ko View360이 내부적으로 캐시하고 있는 엘리먼트 크기를 현재 크기로 갱신합니다. + * @since 4.0.0 + */ + resize() { + if (!this._initialized) return; + this._resizeComponents(); + // To prevent flickering, render immediately after resizing components + this.renderFrame(0); + const { + width, + height + } = this._renderer; + this._emit(EVENTS.RESIZE, { + width, + height + }); + } + /** + * Add new plugins + * @ko 새로운 플러그인을 추가합니다. + * @param plugins Plugins to add {@ko 추가할 플러그인들} + * @see View360Options#plugins + * @since 4.0.0 + * @example + * ```ts + * // Add a single plugin + * viewer.addPlugins(new ControlBar()); + * + * // Add multiple plugins + * viewer.addPlugins(new ControlBar(), new LoadingSpinner()); + * ``` + */ + addPlugins(...plugins) { + if (this._initialized) { + plugins.forEach(plugin => { + plugin.init(this); + }); + } + this._plugins.push(...plugins); + } + /** + * Remove plugins. + * @ko 플러그인을 제거합니다. + * @param plugins Plugins to remove {@ko 제거할 플러그인들} + * @since 4.0.0 + * @example + * ```ts + * // Remove a single plugin + * viewer.removePlugins(plugin1); + * + * // Remove multiple plugins + * viewer.removePlugins(plugin2, plugin3); + * ``` + */ + removePlugins(...plugins) { + plugins.forEach(plugin => { + const pluginIdx = this._plugins.indexOf(plugin); + if (pluginIdx < 0) return; + plugin.destroy(this); + this._plugins.splice(pluginIdx, 1); + }); + } + _emit(eventName, ...params) { + const evtParams = params ? params[0] : {}; + this.trigger(eventName, Object.assign({ + type: eventName, + target: this + }, evtParams)); + } + _applyProjection(projection, texture, prevProjection) { + const camera = this._camera; + const control = this._control; + const renderer = this._renderer; + // Remove previous projection + if (prevProjection) { + prevProjection.releaseAllResources(this._renderer.ctx); + } + projection.applyTexture(renderer.ctx, texture); + projection.updateCamera(camera); + projection.updateControl(control); + this._projection = projection; + this._emit(EVENTS.PROJECTION_CHANGE, { + projection + }); + } + _loadTexture(projection) { + return __awaiter(this, void 0, void 0, function* () { + const contentLoader = new TextureLoader(); + const { + src, + video + } = projection; + this._emit(EVENTS.LOAD_START, { + src, + video + }); + const texture = yield contentLoader.load(src, video); + this._emit(EVENTS.LOAD, { + src, + video + }); + return texture; + }); + } + _resizeComponents() { + const renderer = this._renderer; + const camera = this._camera; + const control = this._control; + renderer.resize(); + camera.resize(renderer.width, renderer.height); + control.resize(renderer.width, renderer.height); + } + _addEventHandlers(events) { + // Bind option "on" + Object.keys(events).forEach(evtName => { + this.on(evtName, events[evtName]); + }); + } + _bindComponentEvents() { + // Bind internal component events + const root = this._rootEl; + const control = this._control; + const animator = this._animator; + const renderer = this._renderer; + const vr = this._vr; + const controlEventsToPropagate = [CONTROL_EVENTS.STATIC_CLICK, CONTROL_EVENTS.INPUT_START, CONTROL_EVENTS.INPUT_END]; + controlEventsToPropagate.forEach(evtName => { + control.rotate.on(evtName, evt => { + this._emit(evtName, evt); + }); + control.zoom.on(evtName, evt => { + this._emit(evtName, evt); + }); + }); + vr.on(EVENTS.VR_START, evt => { + root.classList.add(DEFAULT_CLASS.IN_VR); + animator.changeContext(evt.session); + animator.start(this._renderVRFrame); + this._emit(EVENTS.VR_START); + }); + vr.on(EVENTS.VR_END, () => { + root.classList.remove(DEFAULT_CLASS.IN_VR); + renderer.ctx.useDefaultFrameBuffer(); + animator.changeContext(window); + animator.start(this._renderFrameOnDemand); + this.resize(); + this._emit(EVENTS.VR_END); + }); + } + } + /** + * Current version string of the View360 + * @ko View360의 현재 버젼 문자열 + * @since 4.0.0 + * @readonly + * @example + * ```ts + * // If the installed version of the View360 is v4.0.0, View360.VERSION is equal to "4.0.0" + * console.log(View360.VERSION) // 4.0.0 + * ``` + */ + View360.VERSION = "4.0.0-beta.4"; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Base class for 3D objects + * @ko 3D 오브젝트의 베이스 클래스 + * @since 4.0.0 + * @internal + */ + class Object3D { + /** + * Create new instance. + * @ko 새로운 인스턴스를 생성합니다. + */ + constructor() { + this.matrix = glMatrix.mat4.create(); + this.rotation = glMatrix.quat.create(); + this.position = glMatrix.vec3.fromValues(0, 0, 0); + this.scale = glMatrix.vec3.fromValues(1, 1, 1); + } + /** + * Update local matrix of the object. + * @ko 오브젝트의 local matrix를 갱신합니다. + * @since 4.0.0 + */ + updateMatrix() { + glMatrix.mat4.fromRotationTranslationScale(this.matrix, this.rotation, this.position, this.scale); + } + } + + /** + * A plugin that displays loading spinner while loading the projection. + * @ko 프로젝션 로딩중에 로딩 스피너를 보여주는 플러그인 + * @since 4.0.0 + * @category Plugin + */ + class LoadingSpinner { + /** + * Create a new instance of LoadingSpinner. {@ko LoadingSpinner의 새 인스턴스를 생성합니다.} + * @param options Options {@ko 옵션들} + */ + constructor({ + className = {} + } = {}) { + this._startLoading = ({ + target: viewer + }) => { + viewer.rootEl.appendChild(this._container); + if (viewer.initialized) { + viewer.once(EVENTS.LOAD, this._detachElements); + } else { + viewer.once(EVENTS.READY, this._detachElements); + } + }; + this._detachElements = ({ + target: viewer + }) => { + const container = this._container; + if (!container) return; + if (container.parentElement === viewer.rootEl) { + viewer.rootEl.removeChild(container); + } + }; + this.className = className; + this._container = this._createElements(); + } + init(viewer) { + viewer.on(EVENTS.LOAD_START, this._startLoading); + } + destroy(viewer) { + viewer.off(EVENTS.LOAD_START, this._startLoading); + this._detachElements({ + target: viewer + }); + } + _createElements() { + const className = Object.assign(Object.assign({}, this.className), LoadingSpinner.DEFAULT_CLASS); + const container = createElement(className.CONTAINER); + const ring = createElement(className.RING); + container.appendChild(ring); + return container; + } + } + /** + * Default class names that LoadingSpinner uses + * @ko LoadingSpinner가 사용하는 디폴트 클래스 이름 + * @since 4.0.0 + */ + LoadingSpinner.DEFAULT_CLASS = { + /** + * A class name for the container element + * @ko 컨테이너 엘리먼트의 클래스 이름 + * @since 4.0.0 + */ + CONTAINER: "view360-spinner", + /** + * A class name for the spinning ring element + * @ko 돌아가는 링 엘리먼트의 클래스 이름 + * @since 4.0.0 + */ + RING: "view360-spinner-ring" + }; + + /** + * Interface of the ControlBar items + * @ko 컨트롤바 아이템의 인터페이스 + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class ControlBarItem { + /** + * Create new instance of the ControlBarItem + * @ko ControlBarItem의 새로운 인스턴스를 생성합니다. + * @param options Options {@ko 옵션들} + */ + constructor(options) { + this.position = options.position; + this.order = options.order; + } + } + + const CONTROL_BAR_DEFAULT_CLASS = { + CONTROLS_ROOT: "view360-controls", + CONTROLS_BG: "view360-controls-background", + CONTROLS_MAIN: "view360-controls-main", + CONTROLS_TOP: "view360-controls-top", + CONTROLS_BOTTOM: "view360-controls-bottom", + CONTROLS_MID: "view360-controls-mid", + CONTROLS_LEFT: "view360-controls-left", + CONTROLS_RIGHT: "view360-controls-right", + CONTROLS_FLOAT_LEFT: "view360-controls-float-left", + CONTROLS_FLOAT_RIGHT: "view360-controls-float-right", + CONTROLS_BUTTON: "view360-controls-button", + PROGRESS_ROOT: "view360-controls-progress", + VOLUME_ROOT: "view360-controls-volume", + RANGE_ROOT: "view360-range", + RANGE_TRACK: "view360-range-track", + RANGE_THUMB: "view360-range-thumb", + RANGE_FILLER: "view360-range-filler", + PLAY_BUTTON: "view360-controls-play", + PAUSE_BUTTON: "view360-controls-pause", + UNMUTED_BUTTON: "view360-controls-unmuted", + MUTED_BUTTON: "view360-controls-muted", + FULLSCREEN_BUTTON: "view360-controls-fullscreen", + FULLSCREEN_EXIT_BUTTON: "view360-controls-fullscreen-exit", + VR_BUTTON: "view360-controls-vr", + GYRO_ENABLED: "view360-controls-gyro-enabled", + GYRO_DISABLED: "view360-controls-gyro-disabled", + VIDEO_TIME_DISPLAY: "view360-controls-time", + PIEVIEW_ROOT: "view360-controls-pie", + FIXED: "view360-controls-fixed", + UNAVAILABLE: "view360-controls-unavailable", + HIDDEN: "view360-controls-hidden" + }; + const CONTROL_BAR_ITEM_POSITION = { + /** + * Place control bar item floating at top-left corner + * @ko 아이템을 왼쪽 위 구석에 표시합니다. + * @since 4.0.0 + */ + TOP_LEFT: "top-left", + /** + * Place control bar item floating at top-right corner + * @ko 아이템을 오른쪽 위 구석에 표시합니다. + * @since 4.0.0 + */ + TOP_RIGHT: "top-right", + /** + * Place control bar item at upper block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 위쪽 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_TOP: "main-top", + /** + * Place control bar item at lower block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 하단 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_BOTTOM: "main-bottom", + /** + * Place control bar item at center-left block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 왼쪽 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_LEFT: "main-left", + /** + * Place control bar item at center-right block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 오른쪽 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_RIGHT: "main-right" + }; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class RangeControl extends Component__default["default"] { + /** + * + */ + constructor() { + super(); + this._onHold = ({ + srcEvent, + isTouch + }) => { + var _a; + const bbox = this._bbox; + if (!bbox) return; + const x = isTouch ? srcEvent.touches[0].pageX : srcEvent.pageX; + const elX = bbox.x + ((_a = window.scrollX) !== null && _a !== void 0 ? _a : window.pageXOffset); + const clamepdX = clamp(x, elX, elX + bbox.width); + const progress = (clamepdX - elX) / bbox.width; + this._motion.reset(clamepdX); + this.thumbEl.classList.add(this._fixedClass); + this.trigger(CONTROL_EVENTS.INPUT_START, progress); + }; + this._onChange = ({ + delta + }) => { + var _a; + const motion = this._motion; + const bbox = this._bbox; + if (!bbox) return; + motion.setNewEndByDelta(delta.x); + motion.update(1); + const elX = bbox.x + ((_a = window.scrollX) !== null && _a !== void 0 ? _a : window.pageXOffset); + const clampedX = clamp(motion.val, elX, elX + bbox.width); + const progress = (clampedX - elX) / bbox.width; + this.trigger(CONTROL_EVENTS.CHANGE, progress); + }; + this._onRelease = () => { + const bbox = this._bbox; + if (!bbox) return; + this.thumbEl.classList.remove(this._fixedClass); + this.trigger(CONTROL_EVENTS.INPUT_END); + }; + const root = document.createElement(EL_DIV); + const track = document.createElement(EL_DIV); + const thumb = document.createElement(EL_DIV); + const filler = document.createElement(EL_DIV); + root.draggable = false; + track.appendChild(filler); + track.appendChild(thumb); + root.appendChild(track); + this.rootEl = root; + this.trackEl = track; + this.thumbEl = thumb; + this.fillerEl = filler; + this._mouseInput = new MouseInput(); + this._touchInput = new TouchInput(); + this._motion = new Motion({ + duration: 1, + range: INFINITE_RANGE, + easing: x => x + }); + this._bbox = { + x: 0, + y: 0, + width: 0, + height: 0, + left: 0, + right: 0, + bottom: 0, + top: 0 + }; + this._fixedClass = CONTROL_BAR_DEFAULT_CLASS.FIXED; + } + init(className) { + const mouseInput = this._mouseInput; + const touchInput = this._touchInput; + this.rootEl.classList.add(className.RANGE_ROOT); + this.trackEl.classList.add(className.RANGE_TRACK); + this.thumbEl.classList.add(className.RANGE_THUMB); + this.fillerEl.classList.add(className.RANGE_FILLER); + this._fixedClass = className.FIXED; + mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onHold); + touchInput.on(CONTROL_EVENTS.INPUT_START, this._onHold); + mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + touchInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + mouseInput.enable(this.rootEl); + touchInput.enable(this.rootEl); + this.resize(); + } + destroy() { + const mouseInput = this._mouseInput; + const touchInput = this._touchInput; + this.rootEl.className = ""; + this.trackEl.className = ""; + this.thumbEl.className = ""; + this.fillerEl.className = ""; + mouseInput.off(); + touchInput.off(); + mouseInput.disable(); + touchInput.disable(); + } + resize() { + this._bbox = this.trackEl.getBoundingClientRect(); + } + updateStyle(progress) { + const width = this._bbox.width; + const clampedProgress = clamp(progress, 0, 1); + this.fillerEl.style.width = `${clampedProgress * 100}%`; + this.thumbEl.style.transform = `translateX(${clampedProgress * width}px)`; + } + } + + /** + * Show video progress bar. + * @ko 비디오의 프로그레스 바를 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class ProgressBar extends ControlBarItem { + get element() { + return this._rangeControl.rootEl; + } + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_TOP, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onResize = () => { + this._rangeControl.resize(); + }; + this._onTimeUpdate = () => { + const video = this._video; + if (!video) return; + this._currentTime = video.source.currentTime; + this._rangeControl.updateStyle(this._currentTime / this._duration); + }; + this._onDurationChange = () => { + const video = this._video; + if (!video) return; + this._duration = video.source.duration; + this._rangeControl.updateStyle(this._currentTime / this._duration); + }; + this._onHold = progress => { + const video = this._video; + const controlBar = this._controlBar; + if (!video || !controlBar) return; + const paused = video.isPaused(); + video.source.pause(); + const time = video.source.duration * progress; + video.source.currentTime = time; + video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { + detail: { + time + } + })); + controlBar.rootEl.classList.add(controlBar.className.FIXED); + this._wasPaused = !this._playPromise && paused; + }; + this._onControl = progress => { + const video = this._video; + if (!video) return; + const time = video.source.duration * progress; + video.source.currentTime = time; + video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { + detail: { + time + } + })); + }; + this._onRelease = () => { + const video = this._video; + const controlBar = this._controlBar; + if (video && controlBar) { + if (!this._wasPaused && !this._playPromise) { + this._playPromise = video.source.play().catch(() => void 0); + // This should not be chained + this._playPromise.then(() => { + this._playPromise = null; + }); + controlBar.rootEl.classList.remove(controlBar.className.FIXED); + } + } + this._wasPaused = false; + }; + this.position = position; + this.order = order; + this._controlBar = null; + this._rangeControl = new RangeControl(); + this._video = null; + this._wasPaused = false; + this._currentTime = 0; + this._duration = 0; + this._playPromise = null; + } + init(viewer, controlBar) { + var _a; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const element = this.element; + const rangeControl = this._rangeControl; + const unavailableClass = controlBar.className.UNAVAILABLE; + if (!video || !video.isVideo()) { + element.classList.add(unavailableClass); + return; + } + element.classList.remove(unavailableClass); + element.classList.add(controlBar.className.PROGRESS_ROOT); + viewer.on(EVENTS.RESIZE, this._onResize); + video.source.addEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.addEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate); + rangeControl.init(controlBar.className); + rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold); + rangeControl.on(CONTROL_EVENTS.CHANGE, this._onControl); + rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + this._video = video; + this._currentTime = video.source.currentTime; + this._duration = video.source.duration; + this._controlBar = controlBar; + rangeControl.updateStyle(this._currentTime / this._duration); + } + destroy(viewer) { + const video = this._video; + viewer.off(EVENTS.RESIZE, this._onResize); + if (video) { + video.source.removeEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.removeEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate); + } + this._rangeControl.destroy(); + this._video = null; + this._playPromise = null; + } + } + + /** + * Show video play / pause button. + * @ko 비디오 재생 / 일시정지 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class PlayButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const video = this._video; + if (!video) return; + if (this._paused) { + video.source.play(); + } else { + video.source.pause(); + } + }; + this._onPlay = () => { + if (!this._controlBar) return; + const element = this.element; + const className = this._controlBar.className; + element.classList.add(className.PAUSE_BUTTON); + element.classList.remove(className.PLAY_BUTTON); + element.title = "Pause Video"; + this._paused = false; + }; + this._onPause = () => { + if (!this._controlBar) return; + const element = this.element; + const className = this._controlBar.className; + element.classList.add(className.PLAY_BUTTON); + element.classList.remove(className.PAUSE_BUTTON); + element.title = "Play Video"; + this._paused = true; + }; + this.element = document.createElement(EL_BUTTON); + this._video = null; + this._paused = true; + this._controlBar = null; + } + init(viewer, controlBar) { + var _a; + const element = this.element; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const className = controlBar.className; + const unavailableClass = className.UNAVAILABLE; + if (!video || !video.isVideo()) { + element.classList.add(unavailableClass); + return; + } + element.classList.add(className.CONTROLS_BUTTON); + element.classList.remove(unavailableClass); + const paused = video.isPaused(); + this._video = video; + this._paused = paused; + this._controlBar = controlBar; + if (paused) { + this._onPause(); + } else { + this._onPlay(); + } + element.addEventListener(EVENTS$1.CLICK, this._onClick); + video.source.addEventListener(EVENTS$1.VIDEO_PLAY, this._onPlay); + video.source.addEventListener(EVENTS$1.VIDEO_PAUSE, this._onPause); + } + destroy() { + const video = this._video; + const element = this.element; + if (!video) return; + element.className = ""; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + video.source.removeEventListener(EVENTS$1.VIDEO_PLAY, this._onPlay); + video.source.removeEventListener(EVENTS$1.VIDEO_PAUSE, this._onPause); + this._video = null; + this._paused = true; + this._controlBar = null; + } + } + + /** + * Show video volume control. + * @ko 비디오 볼륨 조절 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class VolumeControl extends ControlBarItem { + get element() { + return this._rootEl; + } + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onResize = () => { + this._rangeControl.resize(); + this._updateDisplay(); + }; + this._onClick = () => { + const video = this._video; + if (!video || this._rootEl.disabled) return; + video.source.muted = !video.source.muted; + }; + this._onVolumeChange = () => { + const button = this._buttonEl; + const video = this._video; + const controlBar = this._controlBar; + if (!video || !controlBar) return; + const className = controlBar.className; + if (video.source.muted || video.source.volume === 0) { + button.classList.add(className.MUTED_BUTTON); + button.classList.remove(className.UNMUTED_BUTTON); + } else { + button.classList.add(className.UNMUTED_BUTTON); + button.classList.remove(className.MUTED_BUTTON); + } + this._updateDisplay(); + }; + this._onHold = progress => { + const video = this._video; + const controlBar = this._controlBar; + if (!video || !controlBar) return; + const className = controlBar.className; + video.source.volume = progress; + this._rootEl.classList.add(className.FIXED); + controlBar.containerEl.classList.add(className.FIXED); + this._updateDisplay(); + }; + this._onChange = progress => { + const video = this._video; + if (!video) return; + video.source.volume = progress; + if (progress > 0) { + video.source.muted = false; + } else { + video.source.muted = true; + } + this._updateDisplay(); + }; + this._onRelease = () => { + const controlBar = this._controlBar; + if (!controlBar) return; + const className = controlBar.className; + this._rootEl.classList.remove(className.FIXED); + controlBar.containerEl.classList.remove(className.FIXED); + }; + this._updateDisplay = () => { + const video = this._video; + const root = this._rootEl; + if (!video) return; + if (!video.hasAudio()) { + root.disabled = true; + return; + } + root.disabled = false; + const volume = video.source.muted ? 0 : video.source.volume; + this._rangeControl.updateStyle(volume); + }; + this._controlBar = null; + this._rangeControl = new RangeControl(); + this._createElements(); + this._video = null; + } + init(viewer, controlBar) { + var _a; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const root = this._rootEl; + const button = this._buttonEl; + const rangeControl = this._rangeControl; + const className = controlBar.className; + const unavailableClass = className.UNAVAILABLE; + if (!video || !video.isVideo()) { + root.classList.add(unavailableClass); + return; + } + root.classList.remove(unavailableClass); + root.classList.add(className.CONTROLS_BUTTON); + root.classList.add(className.VOLUME_ROOT); + button.classList.add(className.CONTROLS_BUTTON); + if (video.source.muted) { + button.classList.add(className.MUTED_BUTTON); + } else { + button.classList.add(className.UNMUTED_BUTTON); + } + viewer.on(EVENTS.RESIZE, this._onResize); + root.addEventListener(EVENTS$1.TRANSITION_END, this._onResize); + button.addEventListener(EVENTS$1.CLICK, this._onClick); + video.source.addEventListener(EVENTS$1.VIDEO_VOLUME_CHANGE, this._onVolumeChange); + video.source.addEventListener(EVENTS$1.VIDEO_LOADED_DATA, this._updateDisplay); + video.source.addEventListener(EVENTS$1.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay); + rangeControl.init(className); + rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold); + rangeControl.on(CONTROL_EVENTS.CHANGE, this._onChange); + rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + this._controlBar = controlBar; + this._video = video; + this._updateDisplay(); + } + destroy(viewer) { + const video = this._video; + const button = this._buttonEl; + const root = this._rootEl; + root.className = ""; + button.className = ""; + viewer.off(EVENTS.RESIZE, this._onResize); + root.removeEventListener(EVENTS$1.TRANSITION_END, this._onResize); + button.removeEventListener(EVENTS$1.CLICK, this._onClick); + if (video) { + video.source.removeEventListener(EVENTS$1.VIDEO_VOLUME_CHANGE, this._onVolumeChange); + video.source.removeEventListener(EVENTS$1.VIDEO_LOADED_DATA, this._updateDisplay); + video.source.removeEventListener(EVENTS$1.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay); + } + this._controlBar = null; + this._rangeControl.destroy(); + this._video = null; + } + _createElements() { + const root = document.createElement(EL_BUTTON); + const buttonEl = document.createElement(EL_DIV); + root.appendChild(this._rangeControl.rootEl); + root.appendChild(buttonEl); + root.title = "Toggle Mute"; + this._rootEl = root; + this._buttonEl = buttonEl; + } + } + + /** + * Show fullscreen enter / exit button. + * @ko 풀스크린 진입 / 해제 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class FullscreenButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const target = this._targetEl; + if (!target) return; + if (isFullscreen()) { + this._exitFullscreen(); + } else { + this._requestFullscreen(target); + } + }; + this._onFullscreenChange = () => { + const element = this.element; + const controlBar = this._controlBar; + if (!controlBar) return; + const className = controlBar.className; + if (isFullscreen()) { + element.classList.add(className.FULLSCREEN_EXIT_BUTTON); + element.classList.remove(className.FULLSCREEN_BUTTON); + } else { + element.classList.add(className.FULLSCREEN_BUTTON); + element.classList.remove(className.FULLSCREEN_EXIT_BUTTON); + } + }; + this.element = document.createElement(EL_BUTTON); + this.element.title = "Toggle Fullscreen"; + this._controlBar = null; + this._targetEl = null; + } + init(viewer, controlBar) { + const element = this.element; + const className = controlBar.className; + if (!this._fullscreenAvailable()) { + element.classList.add(className.UNAVAILABLE); + return; + } + element.classList.add(className.CONTROLS_BUTTON); + element.classList.remove(className.UNAVAILABLE); + element.addEventListener(EVENTS$1.CLICK, this._onClick); + this._addFullscreenHandlers(); + if (isFullscreen()) { + element.classList.add(className.FULLSCREEN_EXIT_BUTTON); + } else { + element.classList.add(className.FULLSCREEN_BUTTON); + } + this._controlBar = controlBar; + this._targetEl = viewer.rootEl; + } + destroy() { + const element = this.element; + element.className = ""; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + this._removeFullscreenHandlers(); + this._controlBar = null; + this._targetEl = null; + } + _fullscreenAvailable() { + return FULLSCREEN_REQUEST.some(key => !!document[key]); + } + _requestFullscreen(el) { + for (const key of FULLSCREEN_REQUEST) { + const request = el[key]; + if (request) { + request.call(el); + return; + } + } + } + _exitFullscreen() { + for (const key of FULLSCREEN_EXIT) { + const exit = document[key]; + if (exit) { + exit.call(document); + return; + } + } + } + _addFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.addEventListener(evtName, this._onFullscreenChange); + }); + } + _removeFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.removeEventListener(evtName, this._onFullscreenChange); + }); + } + } + + /** + * Show video current / total time. + * @ko 비디오의 현재 / 총 재생시간을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class VideoTime extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onTimeUpdate = () => { + const video = this._video; + if (!video) return; + this._currentTime = video.source.currentTime; + this._updateDisplay(); + }; + this._onDurationChange = () => { + const video = this._video; + if (!video) return; + this._duration = video.source.duration; + this._updateDisplay(); + }; + this._onCustomTimeChange = evt => { + this._currentTime = evt.detail.time; + this._updateDisplay(); + }; + this.element = document.createElement(EL_DIV); + this._video = null; + this._currentTime = 0; + this._duration = 0; + } + init(viewer, controlBar) { + var _a; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const element = this.element; + const className = controlBar.className; + if (!video || !video.isVideo()) { + element.classList.add(className.UNAVAILABLE); + return; + } + element.classList.add(className.VIDEO_TIME_DISPLAY); + element.classList.remove(className.UNAVAILABLE); + video.source.addEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.addEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange); + this._video = video; + this._currentTime = video.source.currentTime; + this._duration = video.source.duration; + this._updateDisplay(); + } + destroy() { + const video = this._video; + if (!video) return; + this.element.className = ""; + video.source.removeEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.removeEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange); + this._video = null; + } + _updateDisplay() { + const time = this._currentTime; + const timeMinute = Math.floor(time / 60); + const timeSeconds = Math.floor(time - timeMinute * 60); + const timeSecondsFormatted = timeSeconds < 10 ? `0${timeSeconds}` : timeSeconds; + const duration = this._duration; + const durationMinute = Math.floor(duration / 60); + const durationSeconds = Math.floor(duration - durationMinute * 60); + const durationSecondsFormatted = durationSeconds < 10 ? `0${durationSeconds}` : durationSeconds; + this.element.innerText = `${timeMinute}:${timeSecondsFormatted} / ${durationMinute}:${durationSecondsFormatted}`; + } + } + + /** + * Show camera direction/fov indicator. + * @ko 카메라가 향하는 방향 및 FOV를 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class PieView extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + resetCamera = true, + position = CONTROL_BAR_ITEM_POSITION.TOP_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const viewer = this._viewer; + const resetCamera = this.resetCamera; + if (!viewer || !resetCamera) return; + const { + yaw = viewer.initialYaw, + pitch = viewer.initialPitch, + zoom = viewer.initialZoom, + duration = 500 + } = getObjectOption(resetCamera); + viewer.camera.animateTo({ + yaw, + pitch, + zoom, + duration + }); + }; + this._updatePie = ({ + target: viewer + }) => { + const piePath = this._piePathEl; + const rangeCircle = this._rangeCircleEl; + const camera = viewer.camera; + const fov = camera.getHorizontalFov(); + const yawRange = camera.getYawRange(camera.zoom); + const halfFov = fov * 0.5; + const pieRadius = 24 * Math.PI; + const pieDeg = pieRadius * fov / 360; + const pieOffset = pieRadius * (camera.yaw + halfFov + 90) / 360; + piePath.setAttribute("stroke-dasharray", `${pieDeg} ${pieRadius - pieDeg}`); + piePath.setAttribute("stroke-dashoffset", `${pieOffset}`); + if (isFinite(yawRange.min) && isFinite(yawRange.max)) { + const radius = 45 * Math.PI; // 2 * PI * r + const min = (circulate(yawRange.min, -180, 180) - halfFov) / 360; + const max = (circulate(yawRange.max, -180, 180) + halfFov) / 360; + const rangeDiff = radius * Math.abs(max - min); + const offset = -radius * (min - 0.25); + rangeCircle.setAttribute("stroke-dasharray", `${rangeDiff} ${radius - rangeDiff}`); + rangeCircle.setAttribute("stroke-dashoffset", `${offset}`); + } else { + rangeCircle.setAttribute("stroke-dasharray", ""); + rangeCircle.setAttribute("stroke-dashoffset", ""); + } + }; + this.element = document.createElement(EL_DIV); + this.element.title = "Reset view"; + this.resetCamera = resetCamera; + this._createPieElements(); + this._viewer = null; + } + init(viewer, controlBar) { + const element = this.element; + if (!viewer.initialized) { + viewer.once(EVENTS.READY, this._updatePie); + } else { + this._updatePie({ + target: viewer + }); + } + const rootClass = controlBar.className.PIEVIEW_ROOT; + element.classList.add(rootClass); + if (this.resetCamera) { + element.addEventListener(EVENTS$1.CLICK, this._onClick); + } + viewer.on(EVENTS.VIEW_CHANGE, this._updatePie); + this._viewer = viewer; + } + destroy(viewer) { + const element = this.element; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + element.className = ""; + viewer.off(EVENTS.READY, this._updatePie); + viewer.off(EVENTS.VIEW_CHANGE, this._updatePie); + this._viewer = null; + } + _createPieElements() { + const root = this.element; + const pieSVG = document.createElementNS(SVG_NAMESPACE, "svg"); + pieSVG.setAttribute("viewBox", "0 0 48 48"); + pieSVG.setAttribute("width", "100%"); + pieSVG.setAttribute("height", "100%"); + const piePath = document.createElementNS(SVG_NAMESPACE, "circle"); + piePath.setAttribute("stroke", "currentColor"); + piePath.setAttribute("fill", "transparent"); + piePath.setAttribute("cx", "24"); + piePath.setAttribute("cy", "24"); + piePath.setAttribute("r", "12"); + piePath.setAttribute("stroke-width", "24"); + pieSVG.appendChild(piePath); + const rangeCircle = document.createElementNS(SVG_NAMESPACE, "circle"); + rangeCircle.setAttribute("stroke", "currentColor"); + rangeCircle.setAttribute("fill", "transparent"); + rangeCircle.setAttribute("cx", "24"); + rangeCircle.setAttribute("cy", "24"); + rangeCircle.setAttribute("r", "22.5"); + rangeCircle.setAttribute("stroke-width", "3"); + pieSVG.appendChild(rangeCircle); + root.appendChild(pieSVG); + this._piePathEl = piePath; + this._rangeCircleEl = rangeCircle; + } + } + + /** + * Show VR enter button. + * @ko VR 진입 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class VRButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const viewer = this._viewer; + if (!viewer) return; + viewer.vr.enter(); + }; + this.element = document.createElement(EL_BUTTON); + this.element.title = "Enter VR"; + this._viewer = null; + } + init(viewer, controlBar) { + const element = this.element; + const className = controlBar.className; + element.classList.add(className.UNAVAILABLE); + element.classList.add(className.VR_BUTTON); + element.classList.add(className.CONTROLS_BUTTON); + viewer.vr.isAvailable().then(available => { + if (available) { + element.classList.remove(className.UNAVAILABLE); + } + }); + element.addEventListener(EVENTS$1.CLICK, this._onClick); + this._viewer = viewer; + } + destroy() { + const element = this.element; + element.className = ""; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + this._viewer = null; + } + } + + /** + * Show gyroscope control enable / disable button + * @ko 자이로스코프 컨트롤 활성화 / 비활성화 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class GyroButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const viewer = this._viewer; + const controlBar = this._controlBar; + if (!viewer || !controlBar) return; + const gyroControl = viewer.control.gyro; + if (gyroControl.enabled) { + gyroControl.disable(); + } else { + GyroControl.requestSensorPermission().then(available => { + if (available) { + gyroControl.enable(); + } else { + this.element.classList.add(controlBar.className.UNAVAILABLE); + } + }); + } + }; + this._updateStyle = () => { + const element = this.element; + const viewer = this._viewer; + const controlBar = this._controlBar; + if (!viewer || !controlBar) return; + const gyroControl = viewer.control.gyro; + const className = controlBar.className; + if (gyroControl.enabled) { + element.classList.add(className.GYRO_ENABLED); + element.classList.remove(className.GYRO_DISABLED); + } else { + element.classList.add(className.GYRO_DISABLED); + element.classList.remove(className.GYRO_ENABLED); + } + }; + this.element = document.createElement(EL_DIV); + this.element.title = "Toggle gyroscope control"; + } + init(viewer, controlBar) { + const element = this.element; + const className = controlBar.className; + element.addEventListener(EVENTS$1.CLICK, this._onClick); + element.classList.add(className.CONTROLS_BUTTON); + element.classList.add(className.UNAVAILABLE); + const enableButton = () => { + element.classList.remove(className.UNAVAILABLE); + viewer.control.gyro.on(CONTROL_EVENTS.ENABLE, this._updateStyle); + viewer.control.gyro.on(CONTROL_EVENTS.DISABLE, this._updateStyle); + }; + if (sensorCanBeEnabledIOS()) { + enableButton(); + } else { + GyroControl.isAvailable().then(available => { + if (!available) return; + enableButton(); + }); + } + this._controlBar = controlBar; + this._viewer = viewer; + this._updateStyle(); + } + destroy(viewer) { + const element = this.element; + viewer.control.gyro.off(CONTROL_EVENTS.ENABLE, this._updateStyle); + viewer.control.gyro.off(CONTROL_EVENTS.DISABLE, this._updateStyle); + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + element.className = ""; + this._controlBar = null; + this._viewer = null; + } + } + + class AutoHide { + get enabled() { + return !!this._targetEl; + } + get hidden() { + return this._controlBar.containerEl.classList.contains(this._hiddenClass); + } + get _hiddenClass() { + return this._controlBar.className.HIDDEN; + } + get _fixedClass() { + return this._controlBar.className.FIXED; + } + constructor(controlBar, { + initialDelay = 3000, + delay = 0, + idleDelay: activationDelay = 3000 + }) { + this._onMouseEnter = () => { + this._isCursorInside = true; + this.show(); + }; + this._onMouseLeave = () => { + this._isCursorInside = false; + this._hideAfterDelay(); + }; + this._onMouseMove = () => { + if (!this._isFullscreen) return; + this.showTemporaliy(); + }; + this._onHold = evt => { + this._isGrabbing = true; + if (evt.pointerType === "mouse") { + this._isCursorInside = true; + } + window.addEventListener(EVENTS$1.MOUSE_UP, this._onRelease); + this.show(); + }; + this._onRelease = () => { + this._isGrabbing = false; + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onRelease); + this._hideAfterDelay(); + }; + this._onVideoPlay = () => { + const root = this._targetEl; + if (!root) return; + this._controlBar.containerEl.classList.remove(this._fixedClass); + }; + this._onVideoPause = () => { + const root = this._targetEl; + if (!root) return; + this._controlBar.containerEl.classList.add(this._fixedClass); + }; + this._onFullscreenChange = () => { + this._isFullscreen = isFullscreen(); + if (this._isFullscreen) { + this._hideAfterDelay(); + } + }; + this._controlBar = controlBar; + this._initialDelay = initialDelay; + this._delay = delay; + this._idleDelay = activationDelay; + this._timer = -1; + this._isCursorInside = false; + this._isGrabbing = false; + this._isFullscreen = false; + this._video = null; + this._targetEl = null; + } + enable(viewer) { + var _a; + if (this._targetEl) { + this.disable(viewer); + } + const initialDelay = this._initialDelay; + const root = viewer.rootEl; + this._targetEl = viewer.rootEl; + this._timer = window.setTimeout(() => { + this.hide(); + }, initialDelay); + root.addEventListener(EVENTS$1.MOUSE_DOWN, this._onHold); + root.addEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter); + root.addEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove); + root.addEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave); + this._addFullscreenHandlers(); + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (!video || !video.isVideo()) { + return; + } + if (video.isPaused()) { + this._controlBar.containerEl.classList.add(this._fixedClass); + } + video.source.addEventListener(EVENTS$1.VIDEO_PLAY, this._onVideoPlay); + video.source.addEventListener(EVENTS$1.VIDEO_PAUSE, this._onVideoPause); + this._video = video; + } + disable(viewer) { + if (!this._targetEl) return; + const controlBar = this._controlBar; + const root = viewer.rootEl; + const video = this._video; + root.removeEventListener(EVENTS$1.MOUSE_DOWN, this._onHold); + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onRelease); + root.removeEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter); + root.removeEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove); + root.removeEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave); + this._removeFullscreenHandlers(); + window.clearTimeout(this._timer); + controlBar.containerEl.classList.remove(this._fixedClass); + if (video) { + video.source.removeEventListener(EVENTS$1.VIDEO_PLAY, this._onVideoPlay); + video.source.removeEventListener(EVENTS$1.VIDEO_PAUSE, this._onVideoPause); + } + this._isCursorInside = false; + this._isGrabbing = false; + this._video = null; + this._targetEl = null; + } + show() { + this._clearHideTimer(); + this._controlBar.containerEl.classList.remove(this._hiddenClass); + } + showTemporaliy() { + this.show(); + this._hideAfterDelay(this._idleDelay); + } + hide() { + this._clearHideTimer(); + this._controlBar.containerEl.classList.add(this._hiddenClass); + } + _clearHideTimer() { + if (this._timer) { + window.clearTimeout(this._timer); + this._timer = -1; + } + } + _hideAfterDelay(delay = this._delay) { + if (this._isGrabbing || !this._isFullscreen && this._isCursorInside) return; + this._clearHideTimer(); + if (delay <= 0) { + this.hide(); + } else { + this._timer = window.setTimeout(() => { + this.hide(); + }, delay); + } + } + _addFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.addEventListener(evtName, this._onFullscreenChange); + }); + } + _removeFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.removeEventListener(evtName, this._onFullscreenChange); + }); + } + } + + class VideoControl { + constructor() { + this._onKeyDown = event => { + const video = this._video; + if (!video) return; + event.preventDefault(); + event.stopPropagation(); + const videoEl = video.source; + const keyPressed = event.keyCode != null ? DIRECTION_KEY_CODE[event.keyCode] : DIRECTION_KEY_NAME[event.key]; + switch (keyPressed) { + case "LEFT": + case "RIGHT": + return this._changeVideoTime(videoEl, keyPressed === "RIGHT"); + case "UP": + case "DOWN": + return this._changeVideoVolume(videoEl, keyPressed === "UP"); + } + const spacePressed = event.keyCode === SPACE_KEY_CODE || event.key === SPACE_KEY_NAME; + if (spacePressed) { + this._toggleVideo(video); + } + }; + } + enable(root, video) { + this._video = video; + // capture is needed for resolving conflict with keyboard control + root.addEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown, true); + } + disable(root) { + this._video = null; + root.removeEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown, true); + } + _changeVideoTime(video, forward) { + const delta = forward ? 5 : -5; + video.currentTime += delta; + video.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { + detail: { + time: video.currentTime + } + })); + } + _changeVideoVolume(video, increase) { + const delta = increase ? 0.1 : -0.1; + if (video.muted) { + video.volume = clamp(delta, 0, 1); + } else { + video.volume = clamp(video.volume + delta, 0, 1); + } + if (video.volume > 0) { + video.muted = false; + } else { + video.muted = true; + } + } + _toggleVideo(video) { + if (video.isPaused()) { + video.source.play(); + } else { + video.source.pause(); + } + } + } + + /** + * A plugin that displays extra buttons & controls that controls {@link View360}. + * @ko {@link View360}에 부가적인 버튼과 컨트롤을 추가해주는 플러그인. + * @category Plugin + * @since 4.0.0 + */ + class ControlBar { + /** + * Root element of the control bar + * @ko 컨트롤바의 루트 엘리먼트 + * @since 4.0.0 + */ + get rootEl() { + return this._rootEl; + } + /** + * Container element of the control bar + * @ko 컨트롤바의 컨테이너 엘리먼트 + * @since 4.0.0 + */ + get containerEl() { + return this._containerEl; + } + /** + * Background element of the control bar + * @ko 컨트롤바의 배경 엘리먼트 + * @since 4.0.0 + */ + get backgroundEl() { + return this._bgEl; + } + /** + * Control bar's default items created by {@link ControlBarOptions} + * @ko 주어진 {@link ControlBarOptions}에 의해 생성된 디폴트 아이템들 + * @since 4.0.0 + */ + get items() { + return this._items; + } + /** + * Custom control bar items + * @ko 커스텀 컨트롤바 아이템들을 추가합니다. + * @since 4.0.0 + */ + get customItems() { + return this._customItems; + } + /** + * Create new instance of ControlBar. + * @ko ControlBar의 새 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + autoHide, + showBackground, + clickToPlay = true, + keyboardControls = true, + progressBar = true, + playButton = true, + volumeButton = true, + fullscreenButton = true, + videoTime = true, + pieView = true, + vrButton = true, + gyroButton = true, + className = {}, + customItems = [] + } = {}) { + var _a; + this._onStaticClick = ({ + target: viewer, + isTouch + }) => { + var _a; + const autoHider = this._autoHider; + if (isTouch) { + if (!autoHider.enabled) return; + if (autoHider.hidden) { + autoHider.showTemporaliy(); + } else { + autoHider.hide(); + } + } else { + if (!this.clickToPlay) return; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (!video || !video.isVideo()) return; + if (video.isPaused()) { + video.source.play(); + } else { + video.source.pause(); + } + } + }; + this._onNewSrcLoad = ({ + target: viewer + }) => { + const items = this._items; + this._updateBackground(viewer); + this._updateAutoHide(viewer); + this._updateKeyboardHandler(viewer); + Object.keys(items).forEach(key => { + const category = items[key]; + category.forEach(item => { + item.destroy(viewer, this); + item.init(viewer, this); + }); + }); + }; + this.autoHide = autoHide; + this.showBackground = showBackground; + this.clickToPlay = clickToPlay; + this.keyboardControls = keyboardControls; + this.progressBar = progressBar; + this.playButton = playButton; + this.volumeButton = volumeButton; + this.fullscreenButton = fullscreenButton; + this.videoTime = videoTime; + this.pieView = pieView; + this.vrButton = vrButton; + this.gyroButton = gyroButton; + this.className = Object.assign(Object.assign({}, ControlBar.DEFAULT_CLASS), className); + const rootClass = (_a = className.CONTROLS_ROOT) !== null && _a !== void 0 ? _a : ControlBar.DEFAULT_CLASS.CONTROLS_ROOT; + this._rootEl = createElement(rootClass); + this._createPositionWrappers(); + this._items = Object.keys(ControlBar.POSITION).reduce((items, key) => { + items[ControlBar.POSITION[key]] = []; + return items; + }, {}); + this._customItems = customItems; + this._autoHider = new AutoHide(this, getObjectOption(autoHide)); + this._videoControl = new VideoControl(); + customItems.forEach(item => { + this._items[item.position].push(item); + }); + } + init(viewer) { + const panoRoot = viewer.rootEl; + const controlsRoot = this._rootEl; + const defaultItems = this._createDefaultItems(); + this._updateBackground(viewer); + this._updateAutoHide(viewer); + this._updateKeyboardHandler(viewer); + panoRoot.appendChild(controlsRoot); + this._addItem(viewer, defaultItems); + this._addItem(viewer, this._customItems); + viewer.on(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad); + viewer.on(EVENTS.STATIC_CLICK, this._onStaticClick); + } + destroy(viewer) { + // Remove controls root from pano root + const panoRoot = viewer.rootEl; + const controlsRoot = this._rootEl; + const items = this._items; + if (controlsRoot.parentElement === panoRoot) { + panoRoot.removeChild(controlsRoot); + } + Object.keys(items).forEach(key => { + const category = items[key]; + category.forEach(item => { + item.destroy(viewer, this); + }); + items[key] = []; + }); + this._clearItemElements(); + this._autoHider.disable(viewer); + this._videoControl.disable(panoRoot); + viewer.off(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad); + viewer.off(EVENTS.STATIC_CLICK, this._onStaticClick); + } + _addItem(viewer, items) { + for (const item of items) { + const category = this._items[item.position]; + const wrapper = this._wrapperEl[item.position]; + const nextSiblingIndex = findIndex(category, sibling => sibling.order > item.order); + if (nextSiblingIndex >= 0) { + const nextSibling = category[nextSiblingIndex].element; + category.splice(nextSiblingIndex, 0, item); + wrapper.insertBefore(item.element, nextSibling); + } else { + category.push(item); + wrapper.appendChild(item.element); + } + item.init(viewer, this); + } + } + _createPositionWrappers() { + const className = Object.assign(Object.assign({}, ControlBar.DEFAULT_CLASS), this.className); + const rootEl = this._rootEl; + // BG & FLOATING CONTROLS + const backgroundEl = createElement(className.CONTROLS_BG); + const floatLeftEl = createElement(className.CONTROLS_FLOAT_LEFT); + const floatRightEl = createElement(className.CONTROLS_FLOAT_RIGHT); + rootEl.appendChild(floatLeftEl); + rootEl.appendChild(floatRightEl); + // BOTTOM CONTROLS + const container = createElement(className.CONTROLS_MAIN); + const topWrapper = createElement(className.CONTROLS_TOP); + const bottomWrapper = createElement(className.CONTROLS_BOTTOM); + const midWrapper = createElement(className.CONTROLS_MID); + const leftControlsWrapper = createElement(className.CONTROLS_LEFT); + const rightControlsWrapper = createElement(className.CONTROLS_RIGHT); + midWrapper.appendChild(leftControlsWrapper); + midWrapper.appendChild(rightControlsWrapper); + container.appendChild(backgroundEl); + container.appendChild(topWrapper); + container.appendChild(midWrapper); + container.appendChild(bottomWrapper); + rootEl.appendChild(container); + this._bgEl = backgroundEl; + this._containerEl = container; + this._wrapperEl = { + [ControlBar.POSITION.MAIN_TOP]: topWrapper, + [ControlBar.POSITION.MAIN_LEFT]: leftControlsWrapper, + [ControlBar.POSITION.MAIN_RIGHT]: rightControlsWrapper, + [ControlBar.POSITION.MAIN_BOTTOM]: bottomWrapper, + [ControlBar.POSITION.TOP_LEFT]: floatLeftEl, + [ControlBar.POSITION.TOP_RIGHT]: floatRightEl + }; + } + _clearItemElements() { + const wrappers = Object.keys(ControlBar.POSITION).map(key => ControlBar.POSITION[key]); + // Remove all elements inside wrappers + wrappers.forEach(wrapper => { + while (wrapper.firstChild) { + wrapper.removeChild(wrapper.firstChild); + } + }); + } + _updateAutoHide(viewer) { + var _a; + const autoHide = this.autoHide; + const autoHider = this._autoHider; + if (autoHide != null) { + if (autoHide) { + autoHider.enable(viewer); + } else { + autoHider.disable(viewer); + } + } else { + // Automatically choose whether to show background by content type + const texture = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (texture && texture.isVideo()) { + // Enable auto hide when content type is video + autoHider.enable(viewer); + } else { + autoHider.disable(viewer); + } + } + } + _updateBackground(viewer) { + var _a, _b; + const background = this._bgEl; + const showBackground = this.showBackground; + const hiddenClass = (_a = this.className.HIDDEN) !== null && _a !== void 0 ? _a : ControlBar.DEFAULT_CLASS.HIDDEN; + if (showBackground != null) { + if (showBackground) { + background.classList.remove(hiddenClass); + } else { + background.classList.add(hiddenClass); + } + } else { + // Automatically choose whether to show background by content type + const texture = (_b = viewer.projection) === null || _b === void 0 ? void 0 : _b.getTexture(); + if (texture && texture.isVideo()) { + // Show bg when content type is video + background.classList.remove(hiddenClass); + } else { + background.classList.add(hiddenClass); + } + } + } + _updateKeyboardHandler(viewer) { + var _a; + const panoRoot = viewer.rootEl; + const videoControl = this._videoControl; + const texture = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (this.keyboardControls && texture && texture.isVideo()) { + videoControl.enable(panoRoot, texture); + } else { + videoControl.disable(panoRoot); + } + } + _createDefaultItems() { + const items = []; + if (this.progressBar) { + items.push(new ProgressBar(getObjectOption(this.progressBar))); + } + if (this.playButton) { + items.push(new PlayButton(getObjectOption(this.playButton))); + } + if (this.volumeButton) { + items.push(new VolumeControl(getObjectOption(this.volumeButton))); + } + if (this.gyroButton) { + items.push(new GyroButton(getObjectOption(this.gyroButton))); + } + if (this.vrButton) { + items.push(new VRButton(getObjectOption(this.vrButton))); + } + if (this.fullscreenButton) { + items.push(new FullscreenButton(getObjectOption(this.fullscreenButton))); + } + if (this.videoTime) { + items.push(new VideoTime(getObjectOption(this.videoTime))); + } + if (this.pieView) { + items.push(new PieView(getObjectOption(this.pieView))); + } + return items; + } + } + /** + * Default class names that ControlBar uses + * @ko ControlBar가 사용하는 디폴트 클래스 이름들 + * @since 4.0.0 + */ + ControlBar.DEFAULT_CLASS = CONTROL_BAR_DEFAULT_CLASS; + /** + * Constants for {@link ControlBarItemOptions#position} + * @ko {@link ControlBarItemOptions#position}에 사용 가능한 값들 + */ + ControlBar.POSITION = CONTROL_BAR_ITEM_POSITION; + + /** + * Base class for projections. + * @ko 프로젝션 베이스 클래스. + * @category Projection + * @since 4.0.0 + */ + class Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + src, + video = false + }) { + this.src = src; + this.video = video; + this._mesh = null; + } + /** + * Release all resources projection has. + * This is automatically called on projection change & View360's destroy call + * @ko 현재 갖고 있는 모든 리소스를 반환합니다. + * 이 메소드는 프로젝션 변경 및 View360의 destroy 호출 시 자동으로 호출됩니다. + * @param ctx + */ + releaseAllResources(ctx) { + var _a; + (_a = this._mesh) === null || _a === void 0 ? void 0 : _a.destroy(ctx); + } + /** + * Update camera to match projection's settings. + * @ko 현재 프로젝션의 세팅으로 카메라를 업데이트합니다. + * @param camera - Instance of the camera to update {@ko 업데이트할 카메라의 인스턴스} + * @since 4.0.0 + */ + updateCamera(camera) { + // Use default mode & no view restriction + camera.resetRange(); + } + /** + * Update control to match projection's settings. + * @ko 현재 프로젝션의 세팅으로 컨트롤을 업데이트합니다. + * @param control - Instance of the control to update {@ko 업데이트할 컨트롤의 인스턴스} + * @since 4.0.0 + */ + updateControl(control) { + control.ignoreZoomScale = false; + } + /** + * Update projection. + * @ko 현재 프로젝션 정보를 갱신합니다. + * @param camera - Instance of the camera to reference {@ko 참조할 카메라의 인스턴스} + * @since 4.0.0 + */ + update(camera) {} // eslint-disable-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars + /** + * Return active texture. + * @ko 현재 활성화된 텍스쳐를 반환합니다. + * @internal + * @since 4.0.0 + */ + getTexture() { + if (!this._mesh) return null; + return this._mesh.program.uniforms.uTexture.texture; + } + /** + * A 3D triangle mesh for projection. It's `null` until loading the `src`. + * @ko Projection을 표시하기 위한 Mesh, src를 로드하기 전까지는 `null`입니다. + * @since 4.0.0 + */ + getMesh() { + return this._mesh; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class Uniform { + constructor() { + this.needsUpdate = true; + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + destroy(gl) { + // DO_NOTHING + } + } + + class UniformTextureCube extends Uniform { + constructor(ctx, texture, cubemapOrder) { + super(); + this.texture = texture; + this._webglTexture = ctx.createWebGLCubeTexture(texture, texture.width); + this._cubemapOrder = cubemapOrder; + } + destroy(gl) { + this.texture.destroy(); + gl.deleteTexture(this._webglTexture); + } + update(gl, location, isWebGL2) { + const texture = this.texture; + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY); + gl.uniform1i(location, 0); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture); + const sources = reorderCube(texture.sources, this._cubemapOrder); + sources.forEach((src, idx) => { + if (isWebGL2) { + gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src); + } else { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src); + } + }); + if (!texture.isVideo()) { + this.needsUpdate = false; + } + } + } + + /** @hidden */ + class CubeTexturePainter { + get size() { + return this._size; + } + constructor(texture, cubemapOrder) { + this.texture = texture; + this._renderingOrder = reorderCube(range(6), cubemapOrder); + const canvas = document.createElement("canvas"); + this._calcRenderingSize(); + canvas.width = this._size; + canvas.height = this._size; + this._canvas = canvas; + this._ctx = canvas.getContext("2d"); + } + destroy() { + const canvas = this._canvas; + // release memories + canvas.width = 1; + canvas.height = 1; + this._canvas = null; + } + draw(gl, isWebGL2) { + const size = this._size; + const texture = this.texture; + let surfaceIdx = 0; + for (let row = 0; row < this._row; row++) { + for (let column = 0; column < this._column; column++) { + const x = size * column; + const y = size * row; + const renderingFace = this._renderingOrder[surfaceIdx]; + this._ctx.drawImage(texture.source, x, y, size, size, 0, 0, size, size); + if (isWebGL2) { + gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas); + } else { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas); + } + surfaceIdx++; + } + } + } + _calcRenderingSize() { + const { + width, + height + } = this.texture; + const aspect = width / height; + if (aspect === 1 / 6) { + this._size = width; + this._row = 6; + this._column = 1; + } else if (aspect === 6) { + this._size = height; + this._row = 1; + this._column = 6; + } else if (aspect === 2 / 3) { + this._size = width * 0.5; + this._row = 3; + this._column = 2; + } else { + this._size = width / 3; + this._row = 2; + this._column = 3; + } + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class UniformCanvasCube extends Uniform { + get texture() { + return this._painter.texture; + } + constructor(ctx, texture, cubemapOrder) { + super(); + this._painter = new CubeTexturePainter(texture, cubemapOrder); + this._webglTexture = ctx.createWebGLCubeTexture(texture, this._painter.size); + } + destroy(gl) { + gl.deleteTexture(this._webglTexture); + this._painter.destroy(); + } + update(gl, location, isWebGL2) { + const texture = this.texture; + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + gl.uniform1i(location, 0); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture); + this._painter.draw(gl, isWebGL2); + if (!texture.isVideo()) { + this.needsUpdate = false; + } + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class TriangleMesh extends Object3D { + constructor(vao, program) { + super(); + this.vao = vao; + this.program = program; + } + destroy(ctx) { + ctx.releaseVAO(this.vao); + ctx.releaseShaderResources(this.program); + } + } + + class ShaderProgram { + constructor(ctx, vertexShader, fragmentShader, uniforms) { + this.program = ctx.createProgram(vertexShader, fragmentShader); + this.uniforms = uniforms; + this.uniformLocations = ctx.getUniformLocations(this.program, uniforms); + } + } + + /** + * @hidden + */ + class VertexData { + /** */ + constructor(data, itemSize) { + this.data = data; + this.itemSize = itemSize; + this.count = data.length / itemSize; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class Geometry { + /** */ + constructor(vertices, indicies, uvs) { + this.vertices = new VertexData(new Float32Array(vertices), 3); + this.indicies = new VertexData(new Uint16Array(indicies), 1); + this.uvs = new VertexData(new Float32Array(uvs), 2); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class CubeGeometry extends Geometry { + constructor({ + order, + rotateUV + }) { + const vertices = [ + // back + 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, + // front + -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, + // up + -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, + // down + -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, + // right + 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, + // left + -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1]; + const indicies = [0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23]; + const oneThird = 1 / 3; + const coords = []; + for (let r = 1; r >= 0; r--) { + for (let c = 0; c < 3; c++) { + const coord = [c * oneThird, r * 0.5, (c + 1) * oneThird, r * 0.5, (c + 1) * oneThird, (r + 1) * 0.5, c * oneThird, (r + 1) * 0.5]; + coords.push(coord); + } + } + if (rotateUV) { + rotateUV.forEach((degree, idx) => { + if (degree === ROTATE.ZERO) return; + const coord = coords[idx]; + let newOrder; + if (degree === ROTATE.CW_90) { + newOrder = [1, 2, 3, 0]; + } else if (degree === ROTATE.CCW_90) { + newOrder = [3, 0, 1, 2]; + } else { + newOrder = [2, 3, 0, 1]; + } + const newCoords = Array(coord.length); + for (let uvIdx = 0; uvIdx < coord.length / 2; uvIdx++) { + newCoords[uvIdx * 2 + 0] = coord[newOrder[uvIdx] * 2 + 0]; + newCoords[uvIdx * 2 + 1] = coord[newOrder[uvIdx] * 2 + 1]; + } + coords[idx] = newCoords; + }); + } + const uvs = reorderCube(coords, order, "BFUDRL").reduce((acc, val) => acc.concat(val), []); + super(vertices, indicies, uvs); + } + } + + var vs$3 = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec3 vPos;void main(){vPos=position;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}"; // eslint-disable-line + + var fs$3 = "#define GLSLIFY 1\nuniform samplerCube uTexture;varying highp vec3 vPos;void main(){gl_FragColor=textureCube(uTexture,vec3(vPos.x,vPos.y,-vPos.z));}"; // eslint-disable-line + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on cubemap images, accepts both multiple or single images. + * @ko 큐브맵 이미지 기반의 프로젝션, 단일 혹은 여러 장의 이미지를 모두 사용 가능합니다. + * @since 4.0.0 + * @category Projection + */ + class CubemapProjection extends Projection { + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param options Options {@ko Options} + */ + constructor(options) { + super(options); + const { + cubemapOrder = "RLUDFB", + cubemapFlipX = false + } = options; + this._cubemapOrder = cubemapOrder; + this._cubemapFlipX = cubemapFlipX; + } + applyTexture(ctx, texture) { + const cubemapOrder = this._cubemapOrder; + const cubemapFlipX = this._cubemapFlipX; + const uniforms = { + uTexture: texture.isCube() ? new UniformTextureCube(ctx, texture, cubemapOrder) : new UniformCanvasCube(ctx, texture, cubemapOrder) + }; + const geometry = new CubeGeometry({ + order: cubemapOrder + }); + const program = new ShaderProgram(ctx, vs$3, fs$3, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + if (cubemapFlipX) { + mesh.scale[0] = -1; + } + mesh.updateMatrix(); + this._mesh = mesh; + } + } + + class UniformTexture2D extends Uniform { + constructor(ctx, texture) { + super(); + this.texture = texture; + this._webglTexture = ctx.createWebGLTexture(texture); + } + destroy(gl) { + this.texture.destroy(); + gl.deleteTexture(this._webglTexture); + } + update(gl, location, isWebGL2) { + const texture = this.texture; + const isVideo = texture.isVideo(); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY); + gl.uniform1i(location, 0); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, this._webglTexture); + if (!isVideo && isWebGL2) { + gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); + } + if (!isVideo) { + this.needsUpdate = false; + } + } + } + + var vs$2 = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec2 vUV;void main(){vUV=uv;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}"; // eslint-disable-line + + var fs$2 = "#define GLSLIFY 1\nuniform sampler2D uTexture;varying highp vec2 vUV;void main(){gl_FragColor=texture2D(uTexture,vUV.st);}"; // eslint-disable-line + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on cubemap strip. + * Slightly more efficient than {@link CubemapProjection} as it doesn't copy cubemap image to canvas while rendering. + * Accepts only single image. + * @ko 큐브맵 스트립 기반의 프로젝션. + * {@link CubemapProjection}와 달리 렌더링하는 과정에 캔버스에 이미지를 복사하는 과정이 없기 때문에 살짝 더 효율적입니다. + * 단일 이미지만 사용 가능합니다. + * @since 4.0.0 + * @category Projection + */ + class CubestripProjection extends Projection { + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param options Options {@ko Options} + */ + constructor(options) { + super(options); + const { + cubemapOrder = "RLUDFB", + cubemapFlipX = false + } = options; + this._cubemapOrder = cubemapOrder; + this._cubemapFlipX = cubemapFlipX; + } + applyTexture(ctx, texture) { + const cubemapOrder = this._cubemapOrder; + const cubemapFlipX = this._cubemapFlipX; + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture) + }; + const geometry = new CubeGeometry({ + order: cubemapOrder + }); + const program = new ShaderProgram(ctx, vs$2, fs$2, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + if (cubemapFlipX) { + mesh.scale[0] = -1; + } + mesh.updateMatrix(); + this._mesh = mesh; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class CylinderGeometry extends Geometry { + constructor(maxTheta) { + const vertices = []; + const indicies = []; + const uvs = []; + const height = 1; + const radialSegments = 60; + const halfHeight = height * 0.5; + const heightSegments = [-halfHeight, halfHeight]; + const invRadialSegments = 1 / radialSegments; + const angleConst = maxTheta * invRadialSegments; + for (let yIdx = 0; yIdx < 2; yIdx++) { + const y = heightSegments[yIdx]; + for (let lngIdx = 0; lngIdx <= radialSegments; lngIdx++) { + const angle = lngIdx * angleConst + Math.PI - maxTheta * 0.5; + const x = Math.cos(angle); + const z = Math.sin(angle); + const u = lngIdx * invRadialSegments; + const v = yIdx; + uvs.push(u, v); + vertices.push(x, y, z); + if (yIdx === 0 && lngIdx < radialSegments) { + const a = lngIdx; + const b = a + radialSegments + 1; + indicies.push(a, b, a + 1, b, b + 1, a + 1); + } + } + } + super(vertices, indicies, uvs); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on cylindrical projection. + * This can show panorama images taken from smartphones. + * @ko 원통 투영법 기반의 프로젝션. + * 일반적인 스마트폰 파노라마 사진을 표시하는데 사용될 수 있습니다. + * @since 4.0.0 + * @category Projection + */ + class CylindricalProjection extends Projection { + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param options Options {@ko Options} + */ + constructor(options) { + super(options); + const { + partial = false + } = options; + this._partial = partial; + } + applyTexture(ctx, texture) { + const partial = this._partial; + const { + width, + height + } = texture; + const aspect = width / height; + const halfVFov = 180 / aspect; + const cylinderHeight = partial ? 1 : 2 * Math.tan(halfVFov * DEG_TO_RAD); + const cylinderTheta = partial ? aspect : 2 * Math.PI; + const geometry = new CylinderGeometry(cylinderTheta); + const program = new ShaderProgram(ctx, vs$2, fs$2, { + uTexture: new UniformTexture2D(ctx, texture) + }); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + mesh.scale[1] = cylinderHeight; + glMatrix.quat.identity(mesh.rotation); + glMatrix.quat.rotateY(mesh.rotation, mesh.rotation, -Math.PI / 2); + mesh.updateMatrix(); + this._mesh = mesh; + } + updateCamera(camera) { + super.updateCamera(camera); + const mesh = this._mesh; + if (!mesh) return; + const uTexture = mesh.program.uniforms.uTexture; + const texture = uTexture.texture; + const { + width, + height + } = texture; + const aspect = width / height; + const halfHeight = mesh.scale[1] * 0.5; + if (this._partial) { + const restrictedYaw = 0.5 * aspect * RAD_TO_DEG; + camera.restrictYawRange(-restrictedYaw, restrictedYaw); + } + const restrictedPitch = Math.atan2(halfHeight, 1) * RAD_TO_DEG; + const minZoom = Math.tan(camera.fov * DEG_TO_RAD * 0.5) / (halfHeight * camera.aspect); + camera.restrictPitchRange(-restrictedPitch, restrictedPitch); + camera.restrictZoomRange(minZoom, Infinity); + camera.restrictRenderHeight(halfHeight * 2); + } + } + + var fs$1 = "#define PI 3.14159265359\nprecision mediump float;\n#define GLSLIFY 1\nuniform sampler2D uTexture;varying highp vec2 vUV;const vec2 OPERATE_COORDS_RANGE=vec2(-1.0,1.0);const vec2 TEXTURE_COORDS_RANGE=vec2(0.0,1.0);const float ONE_THIRD=1.0/3.0;const float EAC_CONST=2.0/PI;float scale(vec2 domainRange,vec2 targetRange,float val){float unit=1.0/(domainRange[1]-domainRange[0]);return targetRange[0]+(targetRange[1]-targetRange[0])*(val-domainRange[0])*unit;}void main(void){float transformedCoordX;float transformedCoordY;float texRangeXStart=floor(vUV.s*3.)*ONE_THIRD;float texRangeYStart=floor(vUV.t*2.)*0.5;vec2 orgTextureRangeX=vec2(texRangeXStart,texRangeXStart+ONE_THIRD);vec2 orgTextureRangeY=vec2(texRangeYStart,texRangeYStart+0.5);float px=scale(orgTextureRangeX,OPERATE_COORDS_RANGE,vUV.s);float py=scale(orgTextureRangeY,OPERATE_COORDS_RANGE,vUV.t);float qu=EAC_CONST*atan(px)+0.5;float qv=EAC_CONST*atan(py)+0.5;transformedCoordX=scale(TEXTURE_COORDS_RANGE,orgTextureRangeX,qu);transformedCoordY=scale(TEXTURE_COORDS_RANGE,orgTextureRangeY,qv);gl_FragColor=texture2D(uTexture,vec2(transformedCoordX,transformedCoordY));}"; // eslint-disable-line + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Equi-Angular Cubemap Projection. + * This format is used by Youtube's 360 videos. + * @ko Equi-Angular Cubemap 프로젝션. + * 이 포맷은 주로 Youtube의 360 비디오에 사용됩니다. + * @since 4.0.0 + * @category Projection + */ + class EquiangularProjection extends Projection { + applyTexture(ctx, texture) { + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture) + }; + const geometry = new CubeGeometry({ + order: "LFRDBU", + rotateUV: [ROTATE.ZERO, ROTATE.ZERO, ROTATE.ZERO, ROTATE.CW_90, ROTATE.CCW_90, ROTATE.CW_90] + }); + const program = new ShaderProgram(ctx, vs$2, fs$1, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class SphereGeometry extends Geometry { + /** */ + constructor() { + // const radius = 1; + const widthSegments = 60; + const heightSegments = 60; + const ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI; + const uvs = []; + const vertices = []; + const indicies = []; + let latIdx; + let lngIdx; + for (latIdx = 0; latIdx <= widthSegments; latIdx++) { + const theta = (latIdx / widthSegments - 0.5) * Math.PI; + const sinTheta = Math.sin(theta); + const cosTheta = Math.cos(theta); + for (lngIdx = 0; lngIdx <= heightSegments; lngIdx++) { + const phi = (lngIdx / heightSegments - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN; + const sinPhi = Math.sin(phi); + const cosPhi = Math.cos(phi); + const x = cosPhi * cosTheta; + const y = sinTheta; + const z = sinPhi * cosTheta; + const u = lngIdx / heightSegments; + const v = latIdx / widthSegments; + uvs.push(u, v); + vertices.push(x, y, z); + if (lngIdx !== heightSegments && latIdx !== widthSegments) { + const a = latIdx * (heightSegments + 1) + lngIdx; + const b = a + heightSegments + 1; + indicies.push(a, a + 1, b, b, a + 1, b + 1); + } + } + } + super(vertices, indicies, uvs); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on equirectangular projection. + * @ko 등 장방형 도법(Equirectangular projection) 기반의 프로젝션 + * @since 4.0.0 + * @category Projection + */ + class EquirectProjection extends Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor(options) { + super(options); + } + applyTexture(ctx, texture) { + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture) + }; + const geometry = new SphereGeometry(); + const program = new ShaderProgram(ctx, vs$2, fs$2, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class UniformFloat extends Uniform { + constructor(val) { + super(); + this.val = val; + } + update(gl, location) { + gl.uniform1f(location, this.val); + this.needsUpdate = false; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class PlaneGeometry extends Geometry { + /** */ + constructor(width = 2, height = 2, z = -1) { + const halfWidth = width * 0.5; + const halfHeight = height * 0.5; + const vertices = [-halfWidth, -halfHeight, z, halfWidth, -halfHeight, z, -halfWidth, halfHeight, z, halfWidth, halfHeight, z]; + const indicies = [0, 1, 2, 2, 1, 3]; + const uvs = [0, 0, 1, 0, 0, 1, 1, 1]; + super(vertices, indicies, uvs); + } + } + + var vs$1 = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec2 vUV;void main(){vUV=uv;gl_Position=vec4(position,1.0);}"; // eslint-disable-line + + var fs = "precision mediump float;\n#define GLSLIFY 1\nuniform sampler2D uTexture;uniform float uYaw;uniform float uPitch;uniform float uZoom;varying highp vec2 vUV;const float PI=3.1415926536;const float PI_2=PI*0.5;vec2 toStereographicUV(in vec2 uv,in vec2 center){float R=1.*uZoom;vec2 texLatLon=(uv*2.-1.)*vec2(PI,PI_2);vec2 central=(center*2.-1.)*vec2(PI,PI_2)+vec2(PI,0);float x=texLatLon.x;float y=texLatLon.y;float rou=sqrt(x*x+y*y);float c=2.0*atan(rou,R*0.5);float sin_c=sin(c);float cos_c=cos(c);float sin_cy=sin(central.y);float cos_cy=cos(central.y);float lat=asin(cos_c*sin_cy+(y*sin_c*cos_cy)/rou);float lon=central.x+atan(x*sin_c,rou*cos_cy*cos_c-y*sin_cy*sin_c);float u=(lon/PI+1.0)*0.5;float v=(lat/PI_2+1.0)*0.5;return vec2(u,v);}void main(){vec2 central=vec2(uYaw,uPitch);vec2 uv=toStereographicUV(vUV,central);gl_FragColor=texture2D(uTexture,uv);}"; // eslint-disable-line + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on so-called "Little planet" or "Tiny planet" effect. + * @ko "Little planet" 혹은 "Tiny planet"로 불리는 이펙트 기반의 프로젝션 + * @since 4.0.0 + * @category Projection + */ + class LittlePlanetProjection extends Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor(options) { + super(options); + } + applyTexture(ctx, texture) { + texture.wrapS = WebGLRenderingContext.REPEAT; + texture.wrapT = WebGLRenderingContext.REPEAT; + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture), + uYaw: new UniformFloat(0), + uPitch: new UniformFloat(0.5), + uZoom: new UniformFloat(1) + }; + const geometry = new PlaneGeometry(); + const program = new ShaderProgram(ctx, vs$1, fs, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } + updateControl(control) { + control.ignoreZoomScale = true; + } + update(camera) { + const mesh = this._mesh; + if (!mesh) return; + const uniforms = mesh.program.uniforms; + uniforms.uYaw.val = camera.yaw / 360; + // Range from 0 ~ 1 + uniforms.uPitch.val = camera.pitch / 180 + 0.5; + uniforms.uZoom.val = camera.zoom; + uniforms.uYaw.needsUpdate = true; + uniforms.uPitch.needsUpdate = true; + uniforms.uZoom.needsUpdate = true; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class UniformVector4Array extends Uniform { + constructor(val) { + super(); + this.val = val; + } + update(gl, location) { + gl.uniform4fv(location, this.val.reduce((arr, vector) => [...arr, ...vector], [])); + this.needsUpdate = false; + } + } + + var vs = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;uniform vec4 uTexScaleOffset[2];uniform float uEye;varying highp vec2 vUV;void main(){vec4 scaleOffset=uTexScaleOffset[int(uEye)];vUV=uv.xy*scaleOffset.xy+scaleOffset.zw;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}"; // eslint-disable-line + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on stereo equirectangular images. + * @ko Stereo equirectangular 이미지 기반의 프로젝션 + * @since 4.0.0 + * @category Projection + */ + class StereoEquiProjection extends Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor(options) { + super(options); + this._mode = options.mode; + } + applyTexture(ctx, texture) { + let leftEye; + let rightEye; + switch (this._mode) { + case StereoEquiProjection.MODE.LEFT_RIGHT: + leftEye = [0.5, 1, 0, 0]; + rightEye = [0.5, 1, 0.5, 0]; + break; + default: + // Default, uses "top_bottom" + leftEye = [1, 0.5, 0, 0]; + rightEye = [1, 0.5, 0, 0.5]; + } + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture), + uEye: new UniformFloat(0), + uTexScaleOffset: new UniformVector4Array([leftEye, rightEye]) + }; + const geometry = new SphereGeometry(); + const program = new ShaderProgram(ctx, vs, fs$2, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } + } + /** + * Available stereoscopic modes + * @ko 사용가능한 스테레오스코픽 모드들 + * @since 4.0.0 + */ + StereoEquiProjection.MODE = { + /** + * @ko 이미지가 왼쪽/오른쪽으로 구성되어있을 경우 + * @since 4.0.0 + */ + LEFT_RIGHT: "left_right", + /** + * @ko 이미지가 위/아래로 구성되어있을 경우 + * @since 4.0.0 + */ + TOP_BOTTOM: "top_bottom" + }; + + /** + * @hidden + */ + const withMethods = (prototype, attr) => { + [Component__default["default"].prototype, View360.prototype].forEach(proto => { + Object.getOwnPropertyNames(proto).filter(name => name.charAt(0) !== "_" && name !== "constructor").forEach(name => { + const descriptor = Object.getOwnPropertyDescriptor(proto, name); + if (descriptor.value) { + // Public Function + Object.defineProperty(prototype, name, { + value: function (...args) { + return descriptor.value.call(this[attr], ...args); + } + }); + } else { + const getterDescriptor = {}; + if (descriptor.get) { + getterDescriptor.get = function () { + var _a; + return this[attr] && ((_a = descriptor.get) === null || _a === void 0 ? void 0 : _a.call(this[attr])); + }; + } + if (descriptor.set) { + getterDescriptor.set = function (...args) { + var _a; + return (_a = descriptor.set) === null || _a === void 0 ? void 0 : _a.call(this[attr], ...args); + }; + } + Object.defineProperty(prototype, name, getterDescriptor); + } + }); + }); + }; + + /** + * @hidden + */ + const getValidProps = propsObj => { + return Object.keys(propsObj).reduce((props, propName) => { + if (propsObj[propName] != null) { + props[propName] = propsObj[propName]; + } + return props; + }, {}); + }; + + const VIEW360_METHODS = ["destroy", "init", "load", "resize", "addPlugins", "removePlugins", "renderFrame", + // @egjs/component methods + "on", "hasOn", "once", "off", "trigger"]; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + + var modules = { + __proto__: null, + 'default': View360, + Autoplay: Autoplay, + AutoResizer: AutoResizer, + Camera: Camera, + CameraAnimation: CameraAnimation, + Motion: Motion, + Object3D: Object3D, + View360Error: View360Error, + WebGLRenderer: WebGLRenderer, + XRManager: XRManager, + PanoControl: PanoControl, + RotateControl: RotateControl, + ZoomControl: ZoomControl, + GyroControl: GyroControl, + ControlBar: ControlBar, + ControlBarItem: ControlBarItem, + FullscreenButton: FullscreenButton, + PieView: PieView, + PlayButton: PlayButton, + ProgressBar: ProgressBar, + VideoTime: VideoTime, + VolumeControl: VolumeControl, + LoadingSpinner: LoadingSpinner, + Projection: Projection, + CubemapProjection: CubemapProjection, + CubestripProjection: CubestripProjection, + CylindricalProjection: CylindricalProjection, + EquiangularProjection: EquiangularProjection, + EquirectProjection: EquirectProjection, + LittlePlanetProjection: LittlePlanetProjection, + StereoEquiProjection: StereoEquiProjection, + Hotspot: Hotspot, + HotspotRenderer: HotspotRenderer, + ERROR_CODES: ERROR_CODES, + DEFAULT_CLASS: DEFAULT_CLASS, + EVENTS: EVENTS, + EASING: EASING, + getValidProps: getValidProps, + VIEW360_METHODS: VIEW360_METHODS, + withMethods: withMethods + }; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + merge(View360, modules); + + return View360; + +})); +//# sourceMappingURL=view360.js.map diff --git a/demo/release/4.0.0-beta.4/dist/view360.js.map b/demo/release/4.0.0-beta.4/dist/view360.js.map new file mode 100644 index 000000000..b4dbf8b0d --- /dev/null +++ b/demo/release/4.0.0-beta.4/dist/view360.js.map @@ -0,0 +1 @@ +{"version":3,"file":"view360.js","sources":["../src/core/View360Error.ts","../src/const/error.ts","../src/const/browser.ts","../src/const/external.ts","../src/const/internal.ts","../src/utils.ts","../src/core/Motion.ts","../src/core/CameraAnimation.ts","../src/core/Camera.ts","../src/control/input/MouseInput.ts","../src/control/input/TouchInput.ts","../src/control/input/KeyboardInput.ts","../src/control/RotateControl.ts","../src/control/input/WheelInput.ts","../src/control/input/PinchInput.ts","../src/control/ZoomControl.ts","../src/control/input/GyroInput.ts","../src/control/GyroControl.ts","../src/control/PanoControl.ts","../src/texture/Texture.ts","../src/texture/Texture2D.ts","../src/texture/TextureVideo.ts","../src/texture/TextureCube.ts","../src/core/TextureLoader.ts","../src/core/FrameAnimator.ts","../src/core/AutoResizer.ts","../src/core/Autoplay.ts","../src/core/XRManager.ts","../src/hotspot/Hotspot.ts","../src/hotspot/HotspotRenderer.ts","../src/core/VertexArrayObject.ts","../src/core/WebGLContext.ts","../src/core/WebGLRenderer.ts","../src/View360.ts","../src/core/Object3D.ts","../src/plugin/LoadingSpinner/LoadingSpinner.ts","../src/plugin/ControlBar/ControlBarItem.ts","../src/plugin/ControlBar/const.ts","../src/plugin/ControlBar/RangeControl.ts","../src/plugin/ControlBar/ProgressBar.ts","../src/plugin/ControlBar/PlayButton.ts","../src/plugin/ControlBar/VolumeControl.ts","../src/plugin/ControlBar/FullscreenButton.ts","../src/plugin/ControlBar/VideoTime.ts","../src/plugin/ControlBar/PieView.ts","../src/plugin/ControlBar/VRButton.ts","../src/plugin/ControlBar/GyroButton.ts","../src/plugin/ControlBar/AutoHide.ts","../src/plugin/ControlBar/VideoControl.ts","../src/plugin/ControlBar/ControlBar.ts","../src/projection/Projection.ts","../src/uniform/Uniform.ts","../src/uniform/UniformTextureCube.ts","../src/core/CubeTexturePainter.ts","../src/uniform/UniformCanvasCube.ts","../src/core/TriangleMesh.ts","../src/core/ShaderProgram.ts","../src/core/VertexData.ts","../src/geometry/Geometry.ts","../src/geometry/CubeGeometry.ts","../src/projection/CubemapProjection.ts","../src/uniform/UniformTexture2D.ts","../src/projection/CubestripProjection.ts","../src/geometry/CylinderGeometry.ts","../src/projection/CylindricalProjection.ts","../src/projection/EquiangularProjection.ts","../src/geometry/SphereGeometry.ts","../src/projection/EquirectProjection.ts","../src/uniform/UniformFloat.ts","../src/geometry/PlaneGeometry.ts","../src/projection/LittlePlanetProjection.ts","../src/uniform/UniformVector4Array.ts","../src/projection/StereoEquiProjection.ts","../src/cfc/withMethods.ts","../src/cfc/utils.ts","../src/cfc/const.ts","../src/index.ts","../src/index.umd.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * Error thrown by {@link View360}\n * @ko {@link View360}이 발생시킨 에러\n * @since 4.0.0\n */\nclass View360Error extends Error {\n /**\n * Error code\n * @ko 에러 코드\n * @see ERROR_CODES\n */\n public code: number;\n\n /**\n * Create new instance of View360Error\n * @ko View360Error의 인스턴스를 생성합니다.\n * @param message - Error message {@ko 에러 메시지}\n * @param code - Error code {@ko 에러 코드}\n */\n public constructor(message: string, code: number) {\n super(message);\n\n Object.setPrototypeOf(this, View360Error.prototype);\n\n this.name = \"View360Error\";\n this.code = code;\n }\n}\n\nexport default View360Error;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * Error codes of {@link View360Error}\n * @ko {@link View360Error}가 가질 수 있는 에러 코드 값들\n * @since 4.0.0\n */\nexport const ERROR_CODES = {\n /**\n * The given value's type is not expected\n * @ko 주어진 값의 타입이 잘못되었을 경우\n * @since 4.0.0\n */\n WRONG_TYPE: 0,\n /**\n * The given value is not a supported option\n * @ko 잘못된 옵션을 받았을 경우\n * @since 4.0.0\n */\n WRONG_OPTION: 1,\n /**\n * The element with given CSS selector does not exist\n * @ko 주어진 CSS 셀렉터로 엘리먼트를 찾지 못했을 경우\n * @since 4.0.0\n */\n ELEMENT_NOT_FOUND: 2,\n /**\n * Couldn't find canvas element inside the given container element.\n * @ko 컨테이너 엘리먼트 내부에서 캔버스 엘리먼트를 찾지 못했을 경우\n * @since 4.0.0\n */\n CANVAS_NOT_FOUND: 3,\n /**\n * The browser does not support WebGL\n * @ko 브라우저가 WebGL을 지원하지 않는 경우\n * @since 4.0.0\n */\n WEBGL_NOT_SUPPORTED: 4,\n /**\n * Failed creating canvas 2D context\n * @ko 캔버스 2D 컨텍스트를 생성하지 못한 경우\n * @since 4.0.0\n */\n FAILED_CREATE_CONTEXT_2D: 5,\n /**\n * `init()` is called before setting {@link View360Options#projection}\n * @ko {@link View360Options#projection}을 설정하기 전에 `init()`이 호출된 경우\n * @since 4.0.0\n */\n PROVIDE_PROJECTION_FIRST: 6,\n /**\n * Failed linking WebGL program. Only can be thrown when {@link View360Options#debug} is `true`.\n * @ko WebGL 프로그램 링크에 실패한 경우. {@link View360Options#debug}를 `true`로 설정한 경우에만 발생할 수 있습니다.\n * @since 4.0.0\n */\n FAILED_LINKING_PROGRAM: 7,\n /**\n * Arguments are not sufficient for the given property.\n * @ko 프로퍼티에 값이 충분히 주어지지 않았을 때\n * @since 4.0.0\n */\n INSUFFICIENT_ARGS: 8\n} as const;\n\nexport const MESSAGES = {\n WRONG_TYPE: (val: any, types: string[]) => `${typeof val} is not a ${types.map(type => `\"${type}\"`).join(\" or \")}.`,\n WRONG_OPTION: (val: any, optionName: string) => `Bad option: given \"${val}\" for option \"${optionName}\".`,\n ELEMENT_NOT_FOUND: (query: string) => `Element with selector \"${query}\" not found.`,\n CANVAS_NOT_FOUND: \"The canvas element was not found inside the given root element.\",\n WEBGL_NOT_SUPPORTED: \"WebGL is not supported on this browser.\",\n FAILED_CREATE_CONTEXT_2D: \"Failed to create canvas 2D context\",\n PROVIDE_PROJECTION_FIRST: \"\\\"projection\\\" should be provided before initialization.\",\n FAILED_LINKING_PROGRAM: (msg: string | null, shaderLog: string | null) => `Failed linking WebGL program - \"${msg}\\nShader compile Log: ${shaderLog}`,\n INSUFFICIENT_ARGS: (val: any, name: string) => `Insufficient arguments: given \"${val}\" for \"${name}\".`\n};\n\nexport default {\n CODES: ERROR_CODES,\n MESSAGES\n};\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nexport const EVENTS = {\n MOUSE_DOWN: \"mousedown\",\n MOUSE_MOVE: \"mousemove\",\n MOUSE_UP: \"mouseup\",\n TOUCH_START: \"touchstart\",\n TOUCH_MOVE: \"touchmove\",\n TOUCH_END: \"touchend\",\n WHEEL: \"wheel\",\n RESIZE: \"resize\",\n CONTEXT_MENU: \"contextmenu\",\n MOUSE_ENTER: \"mouseenter\",\n MOUSE_LEAVE: \"mouseleave\",\n POINTER_DOWN: \"pointerdown\",\n POINTER_MOVE: \"pointermove\",\n POINTER_UP: \"pointerup\",\n POINTER_CANCEL: \"pointercancel\",\n POINTER_ENTER: \"pointerenter\",\n POINTER_LEAVE: \"pointerleave\",\n KEY_DOWN: \"keydown\",\n KEY_UP: \"keyup\",\n LOAD: \"load\",\n ERROR: \"error\",\n CLICK: \"click\",\n DOUBLE_CLICK: \"dblclick\",\n CONTEXT_CREATE_ERROR: \"webglcontextcreationerror\",\n CONTEXT_LOST: \"webglcontextlost\",\n CONTEXT_RESTORED: \"webglcontextrestored\",\n DEVICE_ORIENTATION: \"deviceorientation\",\n DEVICE_MOTION: \"devicemotion\",\n ORIENTATION_CHANGE: \"orientationchange\",\n VIDEO_PLAY: \"play\",\n VIDEO_PAUSE: \"pause\",\n VIDEO_LOADED_DATA: \"loadeddata\",\n VIDEO_VOLUME_CHANGE: \"volumechange\",\n VIDEO_TIME_UPDATE: \"timeupdate\",\n VIDEO_DURATION_CHANGE: \"durationchange\",\n VIDEO_CAN_PLAYTHROUGH: \"canplaythrough\",\n TRANSITION_END: \"transitionend\",\n XR_END: \"end\"\n} as const;\n\nexport const EL_DIV = \"div\";\nexport const EL_BUTTON = \"button\";\n\n// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button\nexport enum MOUSE_BUTTON {\n LEFT,\n MIDDLE,\n RIGHT\n}\n\nexport const CURSOR = {\n GRAB: \"grab\",\n GRABBING: \"grabbing\",\n NONE: \"\"\n} as const;\n\nexport const KEY_DIRECTION = [\"LEFT\", \"UP\", \"RIGHT\", \"DOWN\"] as const;\nexport enum DIRECTION_KEY_CODE {\n LEFT = 37,\n UP = 38,\n RIGHT = 39,\n DOWN = 40\n}\nexport const SPACE_KEY_CODE = 32;\n\nexport const DIRECTION_KEY_NAME = {\n LEFT: \"ArrowLeft\",\n UP: \"ArrowUp\",\n RIGHT: \"ArrowRight\",\n DOWN: \"ArrowDown\"\n} as const;\nexport const SPACE_KEY_NAME = \" \";\n\nexport const FULLSCREEN_REQUEST = [\n \"requestFullscreen\",\n \"webkitRequestFullscreen\",\n \"webkitRequestFullScreen\",\n \"webkitCancelFullScreen\",\n \"mozRequestFullScreen\",\n \"msRequestFullscreen\"\n];\n\nexport const FULLSCREEN_ELEMENT = [\n \"fullscreenElement\",\n \"webkitFullscreenElement\",\n \"webkitCurrentFullScreenElement\",\n \"mozFullScreenElement\",\n \"msFullscreenElement\"\n];\n\nexport const FULLSCREEN_EXIT = [\n \"exitFullscreen\",\n \"webkitExitFullscreen\",\n \"webkitCancelFullScreen\",\n \"mozCancelFullScreen\",\n \"msExitFullscreen\"\n];\n\nexport const FULLSCREEN_CHANGE = [\n \"fullscreenchange\",\n \"webkitfullscreenchange\",\n \"mozfullscreenchange\",\n \"MSFullscreenChange\"\n];\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nexport { ERROR_CODES } from \"./error\";\n\n/**\n * Default class names\n * @ko 기본 클래스 이름들\n * @since 4.0.0\n */\nexport const DEFAULT_CLASS = {\n CONTAINER: \"view360-container\",\n CANVAS: \"view360-canvas\",\n CTX_LOST: \"view360-ctx-lost\",\n IN_VR: \"view360-vr-presenting\",\n HOTSPOT_CONTAINER: \"view360-hotspots\",\n HOTSPOT: \"view360-hotspot\",\n HOTSPOT_VISIBLE: \"view360-hotspot-visible\",\n HOTSPOT_FLIP_X: \"view360-hotspot-flip-x\",\n HOTSPOT_FLIP_Y: \"view360-hotspot-flip-y\",\n} as const;\n\n/**\n * Event names\n * @ko 이벤트 이름들\n * @since 4.0.0\n * @example\n * ```ts\n * import View360, { EVENTS } from \"@egjs/view360\";\n *\n * const viewer = new View360(\"#el_id\");\n *\n * viewer.on(EVENTS.READY, evt => {\n * console.log(\"View360 is ready!\");\n * });\n * ```\n */\nexport const EVENTS = {\n READY: \"ready\",\n LOAD_START: \"loadStart\",\n LOAD: \"load\",\n PROJECTION_CHANGE: \"projectionChange\",\n RESIZE: \"resize\",\n BEFORE_RENDER: \"beforeRender\",\n RENDER: \"render\",\n INPUT_START: \"inputStart\",\n INPUT_END: \"inputEnd\",\n VIEW_CHANGE: \"viewChange\",\n STATIC_CLICK: \"staticClick\",\n VR_START: \"vrStart\",\n VR_END: \"vrEnd\"\n} as const;\n\n/**\n * Collection of predefined easing functions\n * @ko 미리 정의된 easing 함수들\n */\nexport const EASING = {\n LINEAR: (x: number) => x,\n SINE_WAVE: (x: number) => Math.sin(x * Math.PI * 2),\n EASE_OUT_CUBIC: (x: number) => 1 - Math.pow(1 - x, 3),\n EASE_OUT_BOUNCE: (x: number): number => {\n const n1 = 7.5625;\n const d1 = 2.75;\n\n if (x < 1 / d1) {\n return n1 * x * x;\n } else if (x < 2 / d1) {\n return n1 * (x -= 1.5 / d1) * x + 0.75;\n } else if (x < 2.5 / d1) {\n return n1 * (x -= 2.25 / d1) * x + 0.9375;\n } else {\n return n1 * (x -= 2.625 / d1) * x + 0.984375;\n }\n }\n} as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { EASING } from \"./external\";\nimport { Range } from \"../type/utils\";\n\nexport const CAMERA_EVENTS = {\n CHANGE: \"change\",\n ANIMATION_END: \"animationEnd\"\n} as const;\n\nexport const CONTROL_EVENTS = {\n INPUT_START: \"inputStart\",\n CHANGE: \"change\",\n INPUT_END: \"inputEnd\",\n ENABLE: \"enable\",\n DISABLE: \"disable\",\n STATIC_CLICK: \"staticClick\"\n} as const;\n\nexport const DEG_TO_RAD = Math.PI / 180;\nexport const RAD_TO_DEG = 180 / Math.PI;\nexport const DEFAULT_EASING = EASING.EASE_OUT_CUBIC;\nexport const DEFAULT_ANIMATION_DURATION = 300;\nexport const INFINITE_RANGE: Readonly = {\n min: -Infinity, max: Infinity\n} as const;\nexport const DEFAULT_PITCH_RANGE: Readonly = {\n min: -90, max: 90\n} as const;\nexport const DEFAULT_ZOOM_RANGE: Readonly = {\n min: 0.6, max: 10\n} as const;\n\nexport enum ROTATE {\n ZERO,\n CW_90,\n CCW_90,\n CW_180\n}\n\n// Custom event name for video time change\nexport const VIDEO_TIME_CHANGE_EVENT = \"view360videotimechange\";\nexport const SVG_NAMESPACE = \"http://www.w3.org/2000/svg\";\nexport const SESSION_VR = \"immersive-vr\";\nexport const XR_REFERENCE_SPACE = \"local\";\n\nexport const EPSILON = Number.EPSILON ?? 2.220446049250313e-16;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { quat, vec3 } from \"gl-matrix\";\nimport View360Error from \"./core/View360Error\";\nimport ERROR from \"./const/error\";\nimport * as BROWSER from \"./const/browser\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"./const/internal\";\nimport { NoBoolean } from \"./type/utils\";\n\nexport const isString = (val: any): val is string => typeof val === \"string\";\nexport const isElement = (val: any): val is Element => !!val && val.nodeType === Node.ELEMENT_NODE;\n\nexport const createElement = (className: string, tag = BROWSER.EL_DIV) => {\n const el = document.createElement(tag);\n\n el.classList.add(className);\n\n return el;\n};\n\nexport const getNullableElement = (el: HTMLElement | string | null, parent?: HTMLElement): HTMLElement | null => {\n let targetEl: HTMLElement | null = null;\n\n if (isString(el)) {\n const parentEl = parent ? parent : document;\n const queryResult = parentEl.querySelector(el);\n\n if (!queryResult) {\n return null;\n }\n\n targetEl = queryResult as HTMLElement;\n } else if (isElement(el)) {\n targetEl = el;\n }\n\n return targetEl;\n};\n\nexport const getElement = (el: HTMLElement | string, parent?: HTMLElement): HTMLElement => {\n const targetEl = getNullableElement(el, parent);\n\n if (!targetEl) {\n if (isString(el)) {\n throw new View360Error(ERROR.MESSAGES.ELEMENT_NOT_FOUND(el), ERROR.CODES.ELEMENT_NOT_FOUND);\n } else {\n throw new View360Error(ERROR.MESSAGES.WRONG_TYPE(el, [\"HTMLElement\", \"string\"]), ERROR.CODES.WRONG_TYPE);\n }\n }\n\n return targetEl;\n};\n\nexport const findCanvas = (root: HTMLElement, selector: string): HTMLCanvasElement => {\n const canvas = root.querySelector(selector) as HTMLCanvasElement;\n\n if (!canvas) {\n throw new View360Error(ERROR.MESSAGES.CANVAS_NOT_FOUND, ERROR.CODES.CANVAS_NOT_FOUND);\n }\n\n return canvas;\n};\n\nexport const range = (end: number): number[] => {\n if (!end || end <= 0) {\n return [];\n }\n\n return Array.apply(0, Array(end)).map((undef, idx) => idx);\n};\n\nexport const clamp = (x: number, min: number, max: number) => Math.max(Math.min(x, max), min);\n\n// Linear interpolation between a and b\nexport const lerp = (a: number, b: number, t: number) => {\n return a * (1 - t) + b * t;\n};\n\nexport const circulate = (val: number, min: number, max: number) => {\n const size = Math.abs(max - min);\n\n if (val < min) {\n const offset = (min - val) % size;\n val = max - offset;\n } else if (val > max) {\n const offset = (val - max) % size;\n val = min + offset;\n }\n\n return val;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const merge = (target: object, ...srcs: object[]): object => {\n srcs.forEach(source => {\n Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n });\n });\n\n return target;\n};\n\nexport const findIndex = (array: T[], checker: (val: T) => boolean): number => {\n for (let idx = 0; idx < array.length; idx++) {\n if (checker(array[idx])) {\n return idx;\n }\n }\n\n return -1;\n};\n\nexport const getObjectOption = >(val?: T): NoBoolean => typeof val === \"object\" ? val : {} as any;\nexport const toVerticalFov = (fovRadian: number, aspect: number) => {\n return Math.atan(Math.tan(fovRadian * 0.5) / aspect) * 2;\n};\n\nexport const reorderCube = (arr: T[], order: string, defaultOrder = \"RLUDFB\"): T[] => {\n return defaultOrder.split(\"\")\n .map(face => order.indexOf(face))\n .map(index => arr[index]);\n};\n\nexport const isFullscreen = () => {\n if (!document) return false;\n\n for (const key of BROWSER.FULLSCREEN_ELEMENT) {\n if (document[key]) return true;\n }\n\n return false;\n};\n\nexport const sensorCanBeEnabledIOS = () => {\n return !!DeviceMotionEvent && \"requestPermission\" in DeviceMotionEvent && window.isSecureContext;\n};\n\nexport const hfovToZoom = (baseFov: number, fov: number) => {\n const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5);\n const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5);\n\n return renderingWidth / zoomedWidth;\n};\n\nexport const eulerToQuat = (out: quat, yaw: number, pitch: number, roll: number): quat => {\n quat.identity(out);\n\n const pitchThreshold = 0.01;\n const pitchClamped = clamp(pitch, -90 + pitchThreshold, 90 - pitchThreshold);\n\n quat.rotateY(out, out, yaw * DEG_TO_RAD);\n quat.rotateX(out, out, pitchClamped * DEG_TO_RAD);\n quat.rotateZ(out, out, roll * DEG_TO_RAD);\n\n return out;\n};\n\n/**\n * Extract euler angles from the quaternion, except roll(z-axis rotation)\n * @hidden\n */\nexport const quatToEuler = (quaternion: quat) => {\n const x = quaternion[0];\n const y = quaternion[1];\n const z = quaternion[2];\n const w = quaternion[3];\n const x2 = x * x;\n const y2 = y * y;\n const z2 = z * z;\n const w2 = w * w;\n\n const unit = x2 + y2 + z2 + w2;\n const test = x * w - y * z;\n\n let pitch: number, yaw: number;\n\n if (test > 0.499995 * unit) {\n // singularity at the north pole\n pitch = Math.PI / 2;\n yaw = 2 * Math.atan2(y, x);\n } else if (test < -0.499995 * unit) {\n // singularity at the south pole\n pitch = -Math.PI / 2;\n yaw = -2 * Math.atan2(y, x);\n } else {\n const view = vec3.fromValues(0, 0, 1);\n const up = vec3.fromValues(0, 1, 0);\n\n vec3.transformQuat(view, view, quaternion);\n vec3.transformQuat(up, up, quaternion);\n\n const viewXZ = Math.sqrt(view[0] * view[0] + view[2] * view[2]);\n\n pitch = Math.atan2(-view[1], viewXZ);\n yaw = Math.atan2(view[0], view[2]);\n }\n\n return {\n pitch: clamp(pitch * RAD_TO_DEG, -90, 90),\n yaw: circulate(yaw * RAD_TO_DEG, 0, 360)\n };\n};\n","/*\n * Copyright (c) 2020 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport { clamp, lerp, circulate } from \"../utils\";\nimport { Range } from \"../type/utils\";\nimport { DEFAULT_ANIMATION_DURATION, DEFAULT_EASING } from \"../const/internal\";\n\n/**\n * Interpolator between two values with duration\n * @ko 특정 시간동안 두 값을 보간해주는 보간기\n * @since 4.0.0\n */\nclass Motion {\n // Options\n private _duration: number;\n private _loop: boolean;\n private _range: Range;\n private _easing: (x: number) => number;\n\n // Internal states\n private _progress: number;\n private _val: number;\n private _start: number;\n private _end: number;\n private _activated: boolean;\n\n /**\n * Current interpolated value\n * @ko 현재 보간된 값\n * @since 4.0.0\n */\n public get val() { return this._val; }\n /**\n * Start(from) value of interpolation\n * @ko 보간 시작 값\n * @since 4.0.0\n */\n public get start() { return this._start; }\n /**\n * End(to) value of interpolation\n * @ko 보간 끝 값\n * @since 4.0.0\n */\n public get end() { return this._end; }\n /**\n * Interpolation progress value (0 ~ 1)\n * @ko 현재 보간 진행정도 (0 ~ 1)\n * @since 4.0.0\n */\n public get progress() { return this._progress; }\n /**\n * Whether the interpolation is in active state.\n * @ko 보간 진행중인지 여부. `true`일 경우 보간이 진행중입니다.\n * @since 4.0.0\n */\n public get activated() { return this._activated; }\n\n /**\n * Duration of the interpolation\n * @ko 보간할 시간\n * @since 4.0.0\n */\n public get duration() { return this._duration; }\n public set duration(val: number) { this._duration = val; }\n\n /**\n * Whether to loop interpolation on finish\n * @ko 보간이 끝난 이후에 다시 시작할지 여부\n * @since 4.0.0\n */\n public get loop() { return this._loop; }\n public set loop(val: boolean) { this._loop = val; }\n\n /**\n * Range of the interpolation\n * @ko 보간 범위\n * @since 4.0.0\n */\n public get range() { return this._range; }\n\n /**\n * Easing function of the interpolation\n * @ko 보간에 사용되는 easing function\n * @since 4.0.0\n */\n public get easing() { return this._easing; }\n public set easing(val: (x: number) => number) { this._easing = val; }\n\n /**\n * Create new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options Options {@ko 옵션들}\n * @param options.duration Duration of the interpolation {@ko 보간할 시간}\n * @param options.loop Whether to loop interpolation on finish {@ko 보간이 끝난 이후에 다시 시작할지 여부}\n * @param options.range Range of the interpolation {@ko 보간 범위}\n * @param options.loop Easing function of the interpolation {@ko 보간에 사용되는 easing function}\n */\n public constructor({\n duration = DEFAULT_ANIMATION_DURATION,\n loop = false,\n range = { min: 0, max: 1 },\n easing = DEFAULT_EASING\n } = {}) {\n this._duration = duration;\n this._loop = loop;\n this._range = range;\n this._easing = easing;\n this._activated = false;\n this.reset(0);\n }\n\n /**\n * Update motion and progress it by given deltaTime\n * @ko 주어진 deltaTime만큼 보간을 진행합니다.\n * @param deltaTime - number of milisec to update motion {@ko 보간을 진행할 시간, 밀리초 단위}\n * @returns Difference(delta) of the value from the last update. {@ko 지난 업데이트 이후의 값 변화량}\n * @since 4.0.0\n */\n public update(deltaTime: number): number {\n if (!this._activated) {\n this._val = this._end;\n return 0;\n }\n\n const start = this._start;\n const end = this._end;\n const duration = this._duration;\n const prev = this._val;\n const loop = this._loop;\n\n const nextProgress = this._progress + deltaTime / duration;\n\n this._progress = loop\n ? circulate(nextProgress, 0, 1)\n : clamp(nextProgress, 0, 1);\n\n const easedProgress = this._easing(this._progress);\n this._val = lerp(start, end, easedProgress);\n\n if (!loop && this._progress >= 1) {\n this._activated = false;\n }\n\n return this._val - prev;\n }\n\n /**\n * Set `start`, `end` to the given value and set `progress` to 0.\n * @ko 주어진 값으로 시작 지점, 끝 지점을 초기화하고 progress를 0으로 세팅합니다.\n * @param defaultVal - Value to reset {@ko 초기화할 값}\n * @since 4.0.0\n */\n public reset(defaultVal: number): void {\n const range = this._range;\n const val = clamp(defaultVal, range.min, range.max);\n this._start = val;\n this._end = val;\n this._val = val;\n this._progress = 0;\n this._activated = false;\n }\n\n /**\n * Add delta to start & end and current value.\n * @ko 현재 & 끝 및 현재 값에 주어진 값을 더합니다.\n * @param delta - Delta value to add {@ko 추가할 값}\n */\n public add(delta: number) {\n const range = this._range;\n\n this._start = clamp(this._start + delta, range.min, range.max);\n this._end = clamp(this._end + delta, range.min, range.max);\n this._val = clamp(this._val + delta, range.min, range.max);\n }\n\n /**\n * Set current value to start, and end to current value + delta, then reset progress to 0.\n * @ko 현재 값을 시작 지점으로, 그에서 delta만큼 추가된 값을 끝점으로 하고 progress를 0으로 갱신합니다.\n * @param delta - Delta value to add {@ko 추가할 값}\n */\n public setNewEndByDelta(delta: number): void {\n const range = this._range;\n\n this._start = this._val;\n this._end = clamp(this._end + delta, range.min, range.max);\n this._progress = 0;\n this._activated = true;\n }\n\n /**\n * Set new range of the interpolation.\n * @ko 보간의 범위를 변경합니다.\n * @param min - New minimum range {@ko 변경할 범위의 최소값}\n * @param max - New maximum range {@ko 변경할 범위의 최대값}\n */\n public setRange(min: number, max: number) {\n this._start = clamp(this._start, min, max);\n this._end = clamp(this._end, min, max);\n this._range = { min, max };\n }\n}\n\nexport default Motion;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { quat } from \"gl-matrix\";\nimport Camera from \"./Camera\";\nimport Motion from \"./Motion\";\nimport { DEFAULT_ANIMATION_DURATION, DEFAULT_EASING } from \"../const/internal\";\nimport { lerp } from \"../utils\";\n\ntype CameraPose = {\n rotation: quat;\n zoom: number;\n}\n\n/**\n * Animation of the {@link Camera}\n * @internal\n * @ko {@link Camera}의 애니메이션\n * @since 4.0.0\n */\nclass CameraAnimation {\n // Options\n private _camera: Camera;\n private _from: CameraPose;\n private _to: CameraPose;\n\n // Internal values\n private _motion: Motion;\n private _finishPromise: Promise;\n private _finish: () => void;\n\n /**\n * Duration of the animation\n * @ko 애니메이션 재생시간\n * @since 4.0.0\n */\n public get duration() { return this._motion.duration; }\n public set duration(val: number) { this._motion.duration = val; }\n /**\n * Easing function of the animation\n * @ko 애니메이션의 easing function\n * @since 4.0.0\n */\n public get easing() { return this._motion.easing; }\n public set easing(val: (x: number) => number) { this._motion.easing = val; }\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param camera - Camera to animate {@ko 애니메이션을 적용할 카메라}\n * @param from - Start pose {@ko 애니메이션이 시작 시점의 카메라의 회전 및 줌}\n * @param to - End pose {@ko 애니메이션이 끝났을 때 카메라의 회전 및 줌}\n * @param options - Options {@ko 옵션들}\n * @param options.duration - Animation duration {@ko 애니메이션 재생 시간}\n * @param options.easing - Animation easing function {@ko 애니메이션 easing function}\n */\n public constructor(camera: Camera, from: CameraPose, to: CameraPose, {\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING\n } = {}) {\n this._camera = camera;\n this._motion = new Motion({ duration, easing, range: { min: 0, max: 1 } });\n this._from = from;\n this._to = to;\n this._finishPromise = new Promise(resolve => {\n this._finish = resolve as () => void;\n });\n\n // Enable motion\n this._motion.setNewEndByDelta(1);\n }\n\n /**\n * Return a promise that resolved on animation end.\n * @ko 애니메이션 재생이 끝났을 때 resolve되는 Promise를 반환합니다.\n * @since 4.0.0\n */\n public getFinishPromise() {\n return this._finishPromise;\n }\n\n /**\n * Update animation by given deltaTime.\n * @ko 주어진 시간만큼 애니메이션을 업데이트합니다.\n * @param deltaTime Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n */\n public update(deltaTime: number): void {\n const camera = this._camera;\n const from = this._from;\n const to = this._to;\n const motion = this._motion;\n motion.update(deltaTime);\n\n // Progress that easing is applied\n const progress = motion.val;\n const rotation = quat.create();\n const zoom = lerp(from.zoom, to.zoom, progress);\n\n quat.slerp(rotation, from.rotation, to.rotation, progress);\n camera.rotate(rotation, zoom);\n\n if (progress >= 1) {\n this._finish();\n }\n }\n}\n\nexport default CameraAnimation;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { mat4, quat, vec3 } from \"gl-matrix\";\nimport CameraAnimation from \"./CameraAnimation\";\nimport {\n CAMERA_EVENTS,\n DEG_TO_RAD,\n INFINITE_RANGE,\n DEFAULT_PITCH_RANGE,\n RAD_TO_DEG,\n DEFAULT_ZOOM_RANGE,\n DEFAULT_EASING,\n EPSILON\n} from \"../const/internal\";\nimport {\n circulate,\n clamp,\n eulerToQuat,\n quatToEuler,\n toVerticalFov\n} from \"../utils\";\nimport { Range } from \"../type/utils\";\n\n/**\n * Events that {@link Camera} can trigger\n * @ko {@link Camera}가 트리거할 수 있는 이벤트들\n * @since 4.0.0\n */\nexport interface CameraEvents {\n /**\n * An event that fires when camera's animation stops\n * @ko 카메라 애니메이션이 멈췄을 때 트리거되는 이벤트\n * @eventName animationEnd\n * @eventOf Camera\n * @version 4.0.0\n */\n [CAMERA_EVENTS.ANIMATION_END]: {\n animation: CameraAnimation\n };\n}\n\n/**\n * Options for {@link Camera}\n * @ko {@link Camera}용 옵션들\n * @since 4.0.0\n */\nexport interface CameraOptions {\n /**\n * @copy View360#initialYaw\n */\n initialYaw: number;\n /**\n * @copy View360#initialPitch\n */\n initialPitch: number;\n /**\n * @copy View360#initialZoom\n */\n initialZoom: number;\n /**\n * @copy View360#yawRange\n */\n yawRange: Range | null;\n /**\n * @copy View360#pitchRange\n */\n pitchRange: Range | null;\n /**\n * @copy View360#zoomRange\n */\n zoomRange: Range | null;\n /**\n * @copy View360#fov\n */\n fov: number;\n}\n\n/**\n * Camera for View360\n * @ko View360용 카메라 구현체\n * @version 4.0.0\n */\nclass Camera extends Component {\n /**\n * Current yaw(y-axis rotation) value\n * @ko 현재 yaw(y축 회전) 값\n * @since 4.0.0\n */\n public yaw: number;\n /**\n * Current pitch(x-axis rotation) value\n * @ko 현재 pitch(x축 회전) 값\n * @since 4.0.0\n */\n public pitch: number;\n /**\n * Current zoom value\n * @ko 현재 줌 값\n * @since 4.0.0\n */\n public zoom: number;\n\n /**\n * @copy View360#initialYaw\n */\n public initialYaw: number;\n /**\n * @copy View360#initialPitch\n */\n public initialPitch: number;\n /**\n * @copy View360#initialPitch\n */\n public initialZoom: number;\n /**\n * @hidden\n * TODO: Please add comment for this when `rollOffset` is added\n */\n public rollOffset: number;\n\n /**\n * Current camera quaternion\n * @ko 현재 회전을 나타내는 quaternion 값\n * @since 4.0.0\n * @internal\n */\n public quaternion: quat;\n /**\n * Current camera position\n * @ko 현재 카메라 위치 좌표\n * @since 4.0.0\n * @internal\n */\n public position: vec3;\n /**\n * Active camera animation, `null` if there isn't.\n * @ko 현재 활성화된 카메라 애니메이션, 없을 경우 `null`값을 가집니다.\n * @since 4.0.0\n */\n public animation: CameraAnimation | null;\n /**\n * Camera's view matrix\n * @ko 카메라의 뷰 변환 행렬\n * @internal\n * @since 4.0.0\n */\n public viewMatrix: mat4;\n /**\n * Camera's projection matrix\n * @ko 카메라의 프로젝션 변환 행렬\n * @internal\n * @since 4.0.0\n */\n public projectionMatrix: mat4;\n\n /**\n * Camera's horizontal FOV(Field of View) value\n * @ko 카메라의 수평 FOV(Field of View) 값\n * @internal\n * @since 4.0.0\n */\n public fov: number;\n\n private _initialYawRange: Range | null;\n private _initialPitchRange: Range | null;\n private _initialZoomRange: Range | null;\n\n private _yawRange: Range | null;\n private _pitchRange: Range | null;\n private _zoomRange: Range | null;\n\n private _up: vec3;\n private _aspect: number;\n private _changed: boolean;\n private _maxRenderHeight: number;\n\n /**\n * Camera's width / height ratio\n * @ko 카메라의 가로 / 세로 비율\n * @readonly\n */\n public get aspect() { return this._aspect; }\n /**\n * Whether the camera's rotation changed from the last frame.\n * @ko 마지막 프레임 이후로 카메라의 회전값이 변경되었는지 나타내는 플래그.\n * @readonly\n */\n public get changed() { return this._changed; }\n /**\n * @copy View360#yawRange\n */\n public get yawRange() { return this._initialYawRange; }\n public set yawRange(val: Range | null) {\n this._initialYawRange = val;\n }\n /**\n * @copy View360#pitchRange\n */\n public get pitchRange() { return this._initialPitchRange; }\n public set pitchRange(val: Range | null) {\n this._initialPitchRange = val;\n }\n /**\n * @copy View360#zoomRange\n */\n public get zoomRange() { return this._initialZoomRange; }\n public set zoomRange(val: Range | null) {\n this._initialZoomRange = val;\n }\n\n /**\n * Create new instance of Camera\n * @param options - Camera options {@ko 카메라 옵션들}\n */\n public constructor({\n initialYaw,\n initialPitch,\n initialZoom,\n yawRange,\n pitchRange,\n zoomRange,\n fov\n }: CameraOptions) {\n super();\n\n this.yaw = initialYaw;\n this.pitch = initialPitch;\n this.zoom = initialZoom;\n this.rollOffset = 0;\n\n this.initialYaw = initialYaw;\n this.initialPitch = initialPitch;\n this.initialZoom = initialZoom;\n\n this.position = vec3.create();\n this.animation = null;\n\n this._up = vec3.fromValues(0, 1, 0);\n this._aspect = 1;\n\n this._initialYawRange = yawRange;\n this._initialPitchRange = pitchRange;\n this._initialZoomRange = zoomRange;\n\n this._yawRange = yawRange;\n this._pitchRange = pitchRange;\n this._zoomRange = zoomRange;\n\n this.quaternion = quat.create();\n this._updateQuaternion();\n\n this.viewMatrix = mat4.create();\n this.projectionMatrix = mat4.create();\n this.fov = fov;\n\n this._maxRenderHeight = -1;\n }\n\n /**\n * Destroy instance and detach all event listeners\n * @ko 인스턴스를 삭제하고 모든 이벤트 리스너를 삭제합니다.\n * @since 4.0.0\n */\n public destroy() {\n this.off();\n }\n\n /**\n * Refresh internal size value.\n * @ko 내부 크기값을 갱신합니다.\n * @param width - New width {@ko 변경된 너비값}\n * @param height - New height {@ko 변경된 높이값}\n * @since 4.0.0\n */\n public resize(width: number, height: number) {\n const prevAspect = this._aspect;\n\n this._aspect = width / height;\n\n if (this._aspect !== prevAspect) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation with euler values.\n * @ko 카메라 회전을 오일러 각 방향으로 변경합니다.\n * @param rotation - Rotation values {@ko 회전 값}\n * @param rotation.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값}\n * @param rotation.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값}\n * @param rotation.zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @since 4.0.0\n */\n public lookAt({\n yaw = this.yaw,\n pitch = this.pitch,\n zoom = this.zoom\n }: Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n }>) {\n const prevQuaternion = quat.clone(this.quaternion);\n const prevZoom = this.zoom;\n\n this.yaw = circulate(yaw, 0, 360);\n this.pitch = clamp(pitch, -90, 90);\n this.zoom = zoom;\n\n this._updateQuaternion();\n\n const zoomDiff = Math.abs(zoom - prevZoom);\n\n if (\n !quat.equals(this.quaternion, prevQuaternion)\n || zoomDiff >= EPSILON * 10 // ignore small changes\n ) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation with quaternion.\n * @ko 카메라 회전을 Quaternion을 이용해서 변경합니다.\n * @param rotation - Quaternion to apply {@ko 적용할 Quaternion}\n * @param zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @since 4.0.0\n */\n public rotate(rotation: quat, zoom: number = this.zoom) {\n const normalized = quat.normalize(quat.create(), rotation);\n const isSameRotation = quat.equals(this.quaternion, normalized);\n quat.copy(this.quaternion, normalized);\n\n const prevZoom = this.zoom;\n const { yaw, pitch } = quatToEuler(normalized);\n\n this.yaw = yaw;\n this.pitch = pitch;\n this.zoom = zoom;\n\n const zoomDiff = Math.abs(zoom - prevZoom);\n\n if (!isSameRotation || zoomDiff >= EPSILON * 10) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation to given euler values by the given duration.\n * @ko 카메라를 주어진 방향으로 주어진 시간동안 서서히 이동시킵니다.\n * @param options - Animation parameters {@ko 애니메이션 패러미터}\n * @param options.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값}\n * @param options.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값}\n * @param options.zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @param options.duration - Duration of the animation {@ko 애니메이션 시간}\n * @param options.easing - Easing function for the animation {@ko 애니메이션에 적용할 easing function}\n */\n public async animateTo({\n yaw = this.yaw,\n pitch = this.pitch,\n zoom = this.zoom,\n duration = 0,\n easing = DEFAULT_EASING\n }: Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n duration: number;\n easing: (x: number) => number;\n }> = {}): Promise {\n if (\n this.yaw === yaw\n && this.pitch === pitch\n && this.zoom === zoom\n ) return;\n\n const from = {\n rotation: quat.clone(this.quaternion),\n zoom: this.zoom\n };\n const to = {\n rotation: eulerToQuat(quat.create(), yaw, pitch, this.rollOffset),\n zoom\n };\n\n const animation = new CameraAnimation(this, from, to, {\n duration,\n easing\n });\n const finishPromise = animation.getFinishPromise();\n\n this.animation = animation;\n finishPromise.then(() => {\n this.animation = null;\n this.trigger(CAMERA_EVENTS.ANIMATION_END, { animation });\n });\n\n return finishPromise;\n }\n\n /**\n * @hidden\n */\n public restrictYawRange(min: number, max: number) {\n this._yawRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictPitchRange(min: number, max: number) {\n this._pitchRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictZoomRange(min: number, max: number) {\n this._zoomRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictRenderHeight(height: number) {\n this._maxRenderHeight = height;\n }\n\n /**\n * @hidden\n */\n public resetRange() {\n this._yawRange = this._initialYawRange;\n this._pitchRange = this._initialPitchRange;\n this._zoomRange = this._initialZoomRange;\n this._maxRenderHeight = -1;\n }\n\n /**\n * Get actual yaw range by the given zoom value.\n * @ko 주어진 zoom 값에 대한 실제 yaw 범위값을 반환합니다.\n * @since 4.0.0\n */\n public getYawRange(zoom: number) {\n const yawLimit = this._yawRange;\n const maxRenderHeight = this._maxRenderHeight;\n if (!yawLimit) return INFINITE_RANGE;\n\n const halfHFov = this.getHorizontalFov(zoom) * 0.5;\n let minYaw = yawLimit.min;\n let maxYaw = yawLimit.max;\n\n if (maxRenderHeight > 0) {\n const halfVFovRad = toVerticalFov(halfHFov * DEG_TO_RAD, this._aspect);\n const h = maxRenderHeight * 0.5;\n const t = Math.tan(halfVFovRad);\n const d = Math.sqrt((1 + h * h) / (1 + t * t));\n const theta = Math.atan(Math.tan(halfHFov * DEG_TO_RAD) * d) * RAD_TO_DEG;\n\n minYaw = yawLimit.min + theta;\n maxYaw = yawLimit.max - theta;\n }\n\n if (minYaw > maxYaw) {\n minYaw = 0;\n maxYaw = 0;\n }\n\n return {\n min: minYaw,\n max: maxYaw\n };\n }\n\n /**\n * Get actual pitch range by the given zoom value.\n * @ko 주어진 zoom 값에 대한 실제 pitch 범위값을 반환합니다.\n * @since 4.0.0\n */\n public getPitchRange(zoom: number) {\n const pitchLimit = this._pitchRange;\n const maxRenderHeight = this._maxRenderHeight;\n\n if (!pitchLimit) return DEFAULT_PITCH_RANGE;\n\n let minPitch = pitchLimit.min;\n let maxPitch = pitchLimit.max;\n\n if (maxRenderHeight > 0) {\n const halfVFov = this.getVerticalFov(zoom) * 0.5;\n\n minPitch = pitchLimit.min + halfVFov;\n maxPitch = pitchLimit.max - halfVFov;\n }\n\n if (minPitch > maxPitch) {\n minPitch = 0;\n maxPitch = 0;\n }\n\n return {\n min: Math.max(minPitch, -90),\n max: Math.min(maxPitch, 90)\n };\n }\n\n /**\n * Get actual zoom range in fov degrees.\n * @ko 실제 줌 범위를 fov각의 범위로 반환합니다.\n * @since 4.0.0\n */\n public getZoomRange() {\n const limit = this._zoomRange ?? DEFAULT_ZOOM_RANGE;\n\n // max (zoom in) -> minimum fov\n const minFov = this.getHorizontalFov(limit.max);\n const maxFov = this.getHorizontalFov(limit.min);\n const currentFov = this.getHorizontalFov(this.zoom);\n\n return {\n min: Math.max(minFov, 1),\n max: Math.min(maxFov, 180),\n current: currentFov\n };\n }\n\n /**\n * Return horizontal fov value when the given zoom is applied. (in degrees, °)\n * @ko 주어진 zoom 값이 적용되었을 때의 수평 fov값을 반환합니다. (도 단위, °)\n * @returns Zoomed horizontal FOV {@ko 줌이 적용된 수평 fov값}\n * @since 4.0.0\n */\n public getHorizontalFov(zoom = this.zoom) {\n return this._getZoomedHorizontalFov(zoom) * RAD_TO_DEG;\n }\n\n /**\n * Return vertical fov value when the given zoom is applied. (in degrees, °)\n * @ko 주어진 zoom 값이 적용되었을 때의 수직 fov값을 반환합니다. (도 단위, °)\n * @returns Zoomed vertical FOV {@ko 줌이 적용된 수직 fov값}\n * @since 4.0.0\n */\n public getVerticalFov(zoom = this.zoom) {\n const aspect = this._aspect;\n const hFov = this._getZoomedHorizontalFov(zoom); // In radians\n const vFov = toVerticalFov(hFov, aspect);\n\n return vFov * RAD_TO_DEG;\n }\n\n /**\n * Calculate zoom value for the given fov.\n * @ko 주어진 fov값을 zoom값으로 변환합니다.\n * @param fov horizontal fov (in degrees, °) {@ko 수평 fov 값 (도 단위, °)}\n * @since 4.0.0\n */\n public fovToZoom(fov: number) {\n const baseFov = this.fov;\n const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5);\n const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5);\n\n return renderingWidth / zoomedWidth;\n }\n\n /**\n * Update inner matrixes.\n * @ko 내부 행렬들을 업데이트합니다.\n * @internal\n * @since 4.0.0\n */\n public updateMatrix() {\n const up = this._up;\n const aspect = this._aspect;\n const viewMatrix = this.viewMatrix;\n const projMatrix = this.projectionMatrix;\n const position = this.position;\n const rotation = this.quaternion;\n\n const upDir = vec3.create();\n const viewDir = vec3.fromValues(0, 0, -1);\n vec3.transformQuat(viewDir, viewDir, rotation);\n vec3.transformQuat(upDir, up, rotation);\n\n const hFov = this._getZoomedHorizontalFov(); // In radians\n const vFov = toVerticalFov(hFov, aspect);\n\n mat4.lookAt(viewMatrix, position, viewDir, upDir);\n mat4.perspective(projMatrix, vFov, aspect, 0.1, 100);\n\n this._changed = true;\n }\n\n /**\n * @hidden\n */\n public onFrameRender() {\n this._changed = false;\n }\n\n private _updateQuaternion() {\n eulerToQuat(this.quaternion, this.yaw, this.pitch, this.rollOffset);\n }\n\n /**\n * @param zoom Current zoom value\n * @returns horizontal fov including zoom, in radian\n */\n private _getZoomedHorizontalFov(zoom = this.zoom) {\n return 2 * Math.atan(Math.tan(DEG_TO_RAD * this.fov * 0.5) / zoom);\n }\n}\n\nexport default Camera;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass MouseInput extends Component> {\n private _el: HTMLElement | null;\n private _prevPos: [number, number];\n\n public constructor() {\n super();\n\n this._el = null;\n this._prevPos = [0, 0];\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onMouseDown);\n\n this._el = element;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onMouseDown);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this._el = null;\n }\n\n private _onMouseDown = (evt: MouseEvent) => {\n const el = this._el;\n if (!el || evt.button !== BROWSER.MOUSE_BUTTON.LEFT) return;\n\n evt.preventDefault();\n\n if (el.focus) {\n el.focus();\n } else {\n window.focus();\n }\n\n this._prevPos[0] = evt.clientX;\n this._prevPos[1] = evt.clientY;\n\n window.addEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.addEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: false\n });\n }\n\n private _onMouseMove = (evt: MouseEvent) => {\n evt.preventDefault();\n\n const x = evt.clientX;\n const y = evt.clientY;\n const prevPos = this._prevPos;\n const deltaX = x - prevPos[0];\n const deltaY = y - prevPos[1];\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta: {\n x: deltaX,\n y: deltaY\n },\n isTouch: false,\n isKeyboard: false\n });\n\n prevPos[0] = x;\n prevPos[1] = y;\n }\n\n private _onMouseUp = () => {\n this._prevPos[0] = 0;\n this._prevPos[1] = 0;\n\n window.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: false,\n scrolling: false\n });\n }\n}\n\nexport default MouseInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\nimport { isFullscreen } from \"../../utils\";\n\nclass TouchInput extends Component> {\n private _el: HTMLElement | null;\n private _prevPos: [number, number];\n private _isFirstTouch: boolean;\n private _scrolling: boolean;\n private _scrollable: boolean;\n\n public get scrollable() { return this._scrollable; }\n public set scrollable(val: boolean) { this._scrollable = val; }\n\n public constructor() {\n super();\n\n this._el = null;\n this._prevPos = [0, 0];\n this._isFirstTouch = false;\n this._scrolling = false;\n this._scrollable = false;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.TOUCH_START, this._onTouchStart, { passive: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, { passive: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = element;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.TOUCH_START, this._onTouchStart);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = null;\n }\n\n private _onTouchStart = (evt: TouchEvent) => {\n if (evt.touches.length > 1 || this._scrolling) return;\n\n const touch = evt.touches[0];\n\n this._isFirstTouch = true;\n this._prevPos[0] = touch.clientX;\n this._prevPos[1] = touch.clientY;\n\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: true,\n isKeyboard: false\n });\n };\n\n private _onTouchMove = (evt: TouchEvent) => {\n // Only the one finger motion should be considered\n if (evt.touches.length > 1 || this._scrolling) return;\n\n const touch = evt.touches[0];\n const scrollable = this._scrollable;\n const prevPos = this._prevPos;\n\n const x = touch.clientX;\n const y = touch.clientY;\n const deltaX = x - prevPos[0];\n const deltaY = y - prevPos[1];\n\n if (this._isFirstTouch) {\n if (scrollable && !isFullscreen()) {\n if (Math.abs(deltaY) > Math.abs(deltaX)) {\n // Assume Scrolling\n this._scrolling = true;\n return;\n }\n }\n\n this._isFirstTouch = false;\n }\n\n if (evt.cancelable !== false) {\n evt.preventDefault();\n }\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta: {\n x: deltaX,\n y: deltaY\n },\n isTouch: true,\n isKeyboard: false\n });\n\n prevPos[0] = x;\n prevPos[1] = y;\n };\n\n private _onTouchEnd = (evt: TouchEvent) => {\n if (evt.touches.length !== 0) return;\n\n const touch = evt.touches[0];\n const prevPos = this._prevPos;\n\n if (touch) {\n prevPos[0] = touch.clientX;\n prevPos[1] = touch.clientY;\n } else {\n prevPos[0] = 0;\n prevPos[1] = 0;\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: true,\n isKeyboard: false,\n scrolling: this._scrolling\n });\n }\n\n if (evt.cancelable !== false) {\n evt.preventDefault();\n }\n\n this._scrolling = false;\n };\n}\n\nexport default TouchInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass KeyboardInput extends Component> {\n private _el: HTMLElement | null;\n private _pressed: {\n LEFT: boolean;\n UP: boolean;\n RIGHT: boolean;\n DOWN: boolean;\n };\n\n public get active() {\n const pressed = this._pressed;\n return pressed.LEFT || pressed.UP || pressed.RIGHT || pressed.DOWN;\n }\n\n public constructor() {\n super();\n\n this._el = null;\n this._clearPressedKeys();\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown);\n element.addEventListener(BROWSER.EVENTS.KEY_UP, this._onKeyUp);\n\n this._el = element;\n this._clearPressedKeys();\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown);\n element.removeEventListener(BROWSER.EVENTS.KEY_UP, this._onKeyUp);\n\n this._el = null;\n this._clearPressedKeys();\n }\n\n public update() {\n const delta = this._getDeltaByPressedKeys();\n\n if (delta.x !== 0 || delta.y !== 0) {\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: false,\n isKeyboard: true\n });\n }\n }\n\n private _clearPressedKeys() {\n this._pressed = BROWSER.KEY_DIRECTION.reduce((obj, keyName) => {\n return {\n ...obj,\n [keyName]: false\n };\n }, {} as KeyboardInput[\"_pressed\"]);\n }\n\n private _updateKeyPress(event: KeyboardEvent, isEnable: boolean): void {\n const pressed = this._pressed;\n const keyToUpdate = event.keyCode != null\n ? BROWSER.DIRECTION_KEY_CODE[event.keyCode]\n : BROWSER.DIRECTION_KEY_NAME[event.key];\n\n if (!keyToUpdate) return;\n\n pressed[keyToUpdate] = isEnable;\n }\n\n private _getPressedKeyCount() {\n return BROWSER.KEY_DIRECTION.filter(key => this._pressed[key]).length;\n }\n\n private _getDeltaByPressedKeys() {\n const pressed = this._pressed;\n let x = 0;\n let y = 0;\n\n if (pressed.LEFT) {\n x += 1;\n }\n\n if (pressed.RIGHT) {\n x -= 1;\n }\n\n if (pressed.UP) {\n y += 1;\n }\n\n if (pressed.DOWN) {\n y -= 1;\n }\n\n return {\n x, y\n };\n }\n\n private _onKeyDown = (evt: KeyboardEvent) => {\n // Ignore all other keypress except main arrow keys\n if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return;\n\n this._updateKeyPress(evt, true);\n\n const pressedCount = this._getPressedKeyCount();\n if (pressedCount <= 0) return;\n\n evt.preventDefault();\n if (pressedCount === 1 && !evt.repeat) {\n // On first keydown\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: true\n });\n }\n };\n\n private _onKeyUp = (evt: KeyboardEvent) => {\n // Ignore all other keypress except main arrow keys\n if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return;\n\n this._updateKeyPress(evt, false);\n\n const pressedCount = this._getPressedKeyCount();\n if (pressedCount > 0) return;\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: true,\n scrolling: false\n });\n };\n}\n\nexport default KeyboardInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport MouseInput from \"./input/MouseInput\";\nimport TouchInput from \"./input/TouchInput\";\nimport KeyboardInput from \"./input/KeyboardInput\";\nimport Camera from \"../core/Camera\";\nimport Motion from \"../core/Motion\";\nimport { CONTROL_EVENTS, INFINITE_RANGE, DEFAULT_PITCH_RANGE, DEFAULT_ANIMATION_DURATION, DEFAULT_EASING, DEG_TO_RAD, RAD_TO_DEG } from \"../const/internal\";\nimport { toVerticalFov } from \"../utils\";\nimport { ControlEvents, InputEvents } from \"../type/internal\";\n\n/**\n * Options for {@link RotateControl}\n * @ko {@link RotateControl}용 옵션들\n * @since 4.0.0\n */\nexport interface RotateControlOptions {\n /**\n * @copy RotateControl#pointerScale\n */\n pointerScale: [number, number];\n /**\n * @copy RotateControl#keyboardScale\n */\n keyboardScale: [number, number];\n /**\n * @copy RotateControl#duration\n */\n duration: number;\n /**\n * @copy RotateControl#easing\n */\n easing: (x: number) => number;\n /**\n * @copy RotateControl#disablePitch\n */\n disablePitch: boolean;\n /**\n * @copy RotateControl#disableYaw\n */\n disableYaw: boolean;\n /**\n * @copy RotateControl#disableKeyboard\n */\n disableKeyboard: boolean;\n}\n\ntype RotateDeltaType = { x: number; y: number; };\nexport type RotateControlEvents = ControlEvents;\n\n/**\n * Camera's rotation control\n * @ko 카메라의 회전을 담당하는 컨트롤\n * @since 4.0.0\n */\nclass RotateControl extends Component implements CameraControl {\n // Options\n private _pointerScale: RotateControlOptions[\"pointerScale\"];\n private _keyboardScale: RotateControlOptions[\"keyboardScale\"];\n private _duration: RotateControlOptions[\"duration\"];\n private _easing: RotateControlOptions[\"easing\"];\n private _disablePitch: RotateControlOptions[\"disablePitch\"];\n private _disableYaw: RotateControlOptions[\"disableYaw\"];\n private _disableKeyboard: RotateControlOptions[\"disableKeyboard\"];\n\n // Internal values\n private _controlEl: HTMLElement;\n private _enableBlocked: boolean;\n private _mouseInput: MouseInput;\n private _touchInput: TouchInput;\n private _keyboardInput: KeyboardInput;\n private _xMotion: Motion;\n private _yMotion: Motion;\n private _screenScale: [number, number];\n private _zoomScale: number;\n private _enabled: boolean;\n private _changedWhileDragging: boolean;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() {\n return this._keyboardInput.active\n || this._xMotion.activated\n || this._yMotion.activated;\n }\n /**\n * Current yaw value\n * @ko 현재 yaw 값\n * @readonly\n * @since 4.0.0\n */\n public get yaw() { return this._xMotion; }\n /**\n * Current pitch value\n * @ko 현재 pitch 값\n * @readonly\n * @since 4.0.0\n */\n public get pitch() { return this._yMotion; }\n /**\n * @copy View360#scrollable\n */\n public get scrollable() { return this._touchInput.scrollable; }\n public set scrollable(val: boolean) {\n this._touchInput.scrollable = val;\n }\n\n /**\n * Scale factor for mouse/touch rotation\n * @ko 마우스/터치를 통한 회전 배율\n * @default [1, 1]\n * @since 4.0.0\n */\n public get pointerScale() { return this._pointerScale; }\n public set pointerScale(val: RotateControlOptions[\"pointerScale\"]) {\n this._pointerScale = val;\n }\n\n /**\n * Scale factor for keyboard rotation\n * @ko 키보드를 통한 회전 배율\n * @default [1, 1]\n * @since 4.0.0\n */\n public get keyboardScale() { return this._keyboardScale; }\n public set keyboardScale(val: RotateControlOptions[\"keyboardScale\"]) {\n this._keyboardScale = val;\n }\n\n /**\n * Duration of the input animation (ms)\n * @ko 회전 애니메이션의 시간 (ms)\n * @default 300\n */\n public get duration() { return this._duration; }\n public set duration(val: RotateControlOptions[\"duration\"]) {\n this._duration = val;\n this._xMotion.duration = val;\n this._yMotion.duration = val;\n }\n\n /**\n * Easing function of the animation\n * @ko 회전 애니메이션에 적용할 easing 함수\n * @default EASING.EASE_OUT_CUBIC\n * @see EASING\n */\n public get easing() { return this._easing; }\n public set easing(val: RotateControlOptions[\"easing\"]) {\n this._easing = val;\n this._xMotion.easing = val;\n this._yMotion.easing = val;\n }\n\n /**\n * Disable X-axis(pitch) rotation.\n * @ko x축 회전(pitch)을 비활성화합니다.\n * @default false\n */\n public get disablePitch() { return this._disablePitch; }\n public set disablePitch(val: RotateControlOptions[\"disablePitch\"]) { this._disablePitch = val; }\n\n /**\n * Disable Y-axis(yaw) rotation.\n * @ko y축 회전(yaw)을 비활성화합니다.\n * @default false\n */\n public get disableYaw() { return this._disableYaw; }\n public set disableYaw(val: RotateControlOptions[\"disableYaw\"]) { this._disableYaw = val; }\n\n /**\n * Disable rotation by keyboard.\n * @ko 키보드를 이용한 회전을 비활성화합니다.\n * @default false\n */\n public get disableKeyboard() { return this._disableKeyboard; }\n public set disableKeyboard(val: RotateControlOptions[\"disableKeyboard\"]) { this._disableKeyboard = val; }\n\n /**\n * Create new RotateControl instance\n * @ko RotateControl의 인스턴스를 생성합니다.\n * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트}\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(controlEl: HTMLElement, enableBlocked: boolean, {\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING,\n pointerScale = [1, 1],\n keyboardScale = [1, 1],\n disablePitch = false,\n disableYaw = false,\n disableKeyboard = false\n }: Partial = {}) {\n super();\n\n this._controlEl = controlEl;\n this._pointerScale = pointerScale;\n this._keyboardScale = keyboardScale;\n this._duration = duration;\n this._easing = easing;\n this._disablePitch = disablePitch;\n this._disableYaw = disableYaw;\n this._disableKeyboard = disableKeyboard;\n\n this._enableBlocked = enableBlocked;\n this._mouseInput = new MouseInput();\n this._touchInput = new TouchInput();\n this._keyboardInput = new KeyboardInput();\n this._xMotion = new Motion({ duration, range: INFINITE_RANGE, easing });\n this._yMotion = new Motion({ duration, range: DEFAULT_PITCH_RANGE, easing });\n this._screenScale = [1, 1];\n this._zoomScale = 1;\n this._enabled = false;\n this._changedWhileDragging = false;\n this._bindInputs();\n }\n\n public destroy(): void {\n this.disable();\n this._mouseInput.off();\n this._touchInput.off();\n this._keyboardInput.off();\n this.off();\n this._changedWhileDragging = false;\n }\n\n /**\n * @hidden\n */\n public update(delta: number): void {\n if (!this._enabled) return;\n\n const xMotion = this._xMotion;\n const yMotion = this._yMotion;\n const keyboardInput = this._keyboardInput;\n\n if (!this._disableKeyboard) {\n keyboardInput.update();\n }\n\n if (!this._disablePitch) {\n yMotion.update(delta);\n }\n\n if (!this._disableYaw) {\n xMotion.update(delta);\n }\n }\n\n /**\n * @hidden\n */\n public updateRange(camera: Camera, zoom: number) {\n const yawRange = camera.getYawRange(zoom);\n const pitchRange = camera.getPitchRange(zoom);\n\n this._xMotion.setRange(yawRange.min, yawRange.max);\n this._yMotion.setRange(pitchRange.min, pitchRange.max);\n }\n\n /**\n * @hidden\n */\n public setZoomScale(val: number) {\n this._zoomScale = val;\n }\n\n /**\n * Resize control to match target size.\n * @ko 컨트롤의 내부 크기를 갱신합니다.\n * @param hfov - Camera horizontal fov in degrees {@ko 카메라의 수평방향 fov값 (도 단위)}\n * @param aspect - Camera aspect {@ko 카메라 가로/세로 비율}\n * @param width - New width {@ko 갱신된 너비}\n * @param height - New height {@ko 갱신된 높이}\n */\n public resize(hfov: number, aspect: number, width: number, height: number) {\n const vfov = toVerticalFov(hfov * DEG_TO_RAD, aspect) * RAD_TO_DEG;\n\n this._screenScale[0] = hfov / width;\n this._screenScale[1] = vfov / height;\n }\n\n public enable(): void {\n if (this._enabled) return;\n\n const element = this._controlEl;\n\n this._mouseInput.enable(element);\n this._touchInput.enable(element);\n this._keyboardInput.enable(element);\n\n this._enabled = true;\n this._enableBlocked = false;\n\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: true });\n }\n\n public disable(): void {\n if (!this._enabled) return;\n\n this._mouseInput.disable();\n this._touchInput.disable();\n this._keyboardInput.disable();\n\n this._enabled = false;\n\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: true });\n }\n\n public sync(camera: Camera): void {\n this.updateRange(camera, camera.zoom);\n\n this._xMotion.reset(camera.yaw);\n this._yMotion.reset(camera.pitch);\n }\n\n private _bindInputs() {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n const keyboardInput = this._keyboardInput;\n\n mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n touchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n touchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n keyboardInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n keyboardInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n keyboardInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n }\n\n private _onInputStart = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n this._changedWhileDragging = false;\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n ...evt,\n inputType: \"rotate\"\n });\n };\n\n private _onChange = (evt: InputEvents[typeof CONTROL_EVENTS.CHANGE]) => {\n const delta = evt.delta;\n const invZoomScale = 1 / this._zoomScale; // Reduce speed on zoom\n const screenScale = this._screenScale;\n const keyboardScale = this._keyboardScale;\n const pointerScale = this._pointerScale;\n\n let scale: [number, number];\n\n if (evt.isKeyboard) {\n scale = [\n keyboardScale[0] * invZoomScale,\n keyboardScale[1] * invZoomScale\n ];\n } else {\n scale = [\n pointerScale[0] * screenScale[0] * invZoomScale,\n pointerScale[1] * screenScale[1] * invZoomScale\n ];\n }\n\n const scaledX = delta.x * scale[0];\n const scaledY = delta.y * scale[1];\n\n this._xMotion.setNewEndByDelta(scaledX);\n this._yMotion.setNewEndByDelta(scaledY);\n\n this._changedWhileDragging = true;\n }\n\n private _onInputEnd = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n ...evt,\n inputType: \"rotate\"\n });\n\n if (!this._changedWhileDragging && !evt.isKeyboard && !evt.scrolling) {\n this.trigger(CONTROL_EVENTS.STATIC_CLICK, {\n isTouch: evt.isTouch\n });\n }\n\n this._changedWhileDragging = false;\n };\n}\n\nexport default RotateControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS, DEFAULT_ANIMATION_DURATION } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass WheelInput extends Component> {\n private _el: HTMLElement | null;\n private _scrollable: boolean;\n private _baseScale: number;\n private _inputTimer: number;\n\n public get scrollable() { return this._scrollable; }\n public set scrollable(val: boolean) { this._scrollable = val; }\n\n public constructor() {\n super();\n\n this._el = null;\n this._baseScale = 0.04;\n this._scrollable = false;\n this._inputTimer = -1;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.WHEEL, this._onWheel, { passive: false, capture: false });\n\n this._el = element;\n this._clearTimer();\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.WHEEL, this._onWheel, false);\n\n this._el = null;\n this._clearTimer();\n }\n\n private _onWheel = (evt: WheelEvent) => {\n const scrollable = this._scrollable;\n\n if (evt.deltaY === 0 || scrollable) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n\n if (this._inputTimer < 0) {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: false\n });\n } else {\n this._clearTimer();\n }\n\n const delta = this._baseScale * evt.deltaY;\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: false,\n isKeyboard: false\n });\n\n this._inputTimer = window.setTimeout(() => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: false,\n scrolling: false\n });\n this._inputTimer = -1;\n }, DEFAULT_ANIMATION_DURATION);\n };\n\n private _clearTimer() {\n window.clearTimeout(this._inputTimer);\n this._inputTimer = -1;\n }\n}\n\nexport default WheelInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass PinchInput extends Component> {\n private _el: HTMLElement | null;\n private _baseScale: number;\n private _prevDistance: number;\n private _isFirstTouch: boolean;\n\n public constructor() {\n super();\n\n this._el = null;\n this._baseScale = -0.2;\n this._prevDistance = -1;\n this._isFirstTouch = true;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, { passive: false, capture: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = element;\n this._prevDistance = -1;\n this._isFirstTouch = true;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, false);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = null;\n }\n\n private _onTouchMove = (evt: TouchEvent) => {\n const touches = evt.touches;\n if (touches.length !== 2) return;\n\n if (!evt.cancelable) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n\n const prevDistance = this._prevDistance;\n\n const diff = [\n touches[0].pageX - touches[1].pageX,\n touches[0].pageY - touches[1].pageY\n ];\n\n const distance = Math.sqrt(diff[0] * diff[0] + diff[1] * diff[1]) * this._baseScale;\n const delta = this._isFirstTouch\n ? 0\n : distance - prevDistance;\n\n if (this._isFirstTouch) {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: true,\n isKeyboard: false\n });\n }\n\n this._prevDistance = distance;\n this._isFirstTouch = false;\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: true,\n isKeyboard: false\n });\n };\n\n private _onTouchEnd = (evt: TouchEvent) => {\n if (evt.touches.length !== 0) return;\n\n if (!this._isFirstTouch) {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: true,\n isKeyboard: false,\n scrolling: false\n });\n }\n\n this._prevDistance = -1;\n this._isFirstTouch = true;\n };\n}\n\nexport default PinchInput;\n","/*\n* Copyright (c) 2023-present NAVER Corp.\n* egjs projects are licensed under the MIT license\n*/\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport WheelInput from \"./input/WheelInput\";\nimport PinchInput from \"./input/PinchInput\";\nimport Camera from \"../core/Camera\";\nimport Motion from \"../core/Motion\";\nimport {\n CONTROL_EVENTS,\n DEFAULT_ANIMATION_DURATION,\n DEFAULT_EASING,\n INFINITE_RANGE\n} from \"../const/internal\";\nimport { ControlEvents, InputEvents } from \"../type/internal\";\n\n/**\n * Options for {@link ZoomControl}\n * @ko {@link ZoomControl}용 옵션들\n * @since 4.0.0\n */\nexport interface ZoomControlOptions {\n /**\n * @copy ZoomControl#scale\n */\n scale: number;\n /**\n * @copy ZoomControl#duration\n */\n duration: number;\n /**\n * @copy ZoomControl#easing\n */\n easing: (x: number) => number;\n}\n\ntype ZoomControlEvents = ControlEvents;\n\n/**\n * Camera's zoom control\n * @ko 카메라의 줌 값을 담당하는 컨트롤\n * @since 4.0.0\n */\nclass ZoomControl extends Component implements CameraControl {\n // Options\n private _scale: ZoomControlOptions[\"scale\"];\n\n // Internal values\n private _controlEl: HTMLElement;\n private _enableBlocked: boolean;\n private _wheelInput: WheelInput;\n private _pinchInput: PinchInput;\n private _motion: Motion;\n private _enabled: boolean;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() { return this._motion.activated; }\n /**\n * Current zoom value\n * @ko 현재 줌 값\n * @since 4.0.0\n * @readonly\n */\n public get zoom() { return this._motion.val; }\n /**\n * @copy View360#wheelScrollable\n */\n public get scrollable() { return this._wheelInput.scrollable; }\n public set scrollable(val: boolean) {\n this._wheelInput.scrollable = val;\n }\n /**\n * @hidden\n */\n public get range() { return this._motion.range; }\n\n /**\n * Scale factor of the zoom\n * @ko 입력에 의한 줌 배율\n * @default 1\n * @since 4.0.0\n */\n public get scale() { return this._scale; }\n public set scale(val: ZoomControlOptions[\"scale\"]) { this._scale = val; }\n\n /**\n * Duration of the input animation (ms)\n * @ko 회전 애니메이션의 시간 (ms)\n * @default 300\n * @since 4.0.0\n */\n public get duration() { return this._motion.duration; }\n\n /**\n * Easing function of the animation\n * @ko 회전 애니메이션에 적용할 easing 함수\n * @default EASING.EASE_OUT_CUBIC\n * @see EASING\n * @since 4.0.0\n */\n public get easing() { return this._motion.easing; }\n\n /**\n * Create new ZoomControl instance\n * @ko ZoomControl의 인스턴스를 생성합니다.\n * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트}\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(controlEl: HTMLElement, enableBlocked: boolean, {\n scale = 1,\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING\n }: Partial = {}) {\n super();\n\n this._scale = scale;\n\n this._controlEl = controlEl;\n this._enableBlocked = enableBlocked;\n this._wheelInput = new WheelInput();\n this._pinchInput = new PinchInput();\n this._motion = new Motion({\n duration,\n easing,\n range: INFINITE_RANGE\n });\n this._enabled = false;\n\n this._bindInputs();\n }\n\n public destroy(): void {\n this.disable();\n this._wheelInput.off();\n this._pinchInput.off();\n this.off();\n }\n\n /**\n * @hidden\n */\n public update(delta: number): void {\n if (!this._enabled) return;\n\n const motion = this._motion;\n motion.update(delta);\n }\n\n public enable(): void {\n if (this._enabled) return;\n\n const element = this._controlEl;\n this._wheelInput.enable(element);\n this._pinchInput.enable(element);\n\n this._enabled = true;\n this._enableBlocked = false;\n\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: false });\n }\n\n public disable(): void {\n if (!this._enabled) return;\n\n this._wheelInput.disable();\n this._pinchInput.disable();\n\n this._enabled = false;\n\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: false });\n }\n\n public sync(camera: Camera): void {\n const motion = this._motion;\n const range = camera.getZoomRange();\n\n motion.setRange(range.min, range.max);\n motion.reset(range.current);\n }\n\n private _bindInputs() {\n const wheelInput = this._wheelInput;\n const pinchInput = this._pinchInput;\n\n wheelInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n wheelInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n wheelInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n pinchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n pinchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n pinchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n }\n\n private _onInputStart = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n ...evt,\n inputType: \"zoom\"\n });\n };\n\n private _onChange = ({ delta }: InputEvents[typeof CONTROL_EVENTS.CHANGE]) => {\n const scale = this._scale;\n const scaledDelta = delta * scale;\n\n this._motion.setNewEndByDelta(scaledDelta);\n };\n\n private _onInputEnd = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n ...evt,\n inputType: \"zoom\"\n });\n };\n}\n\nexport default ZoomControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { quat, vec3 } from \"gl-matrix\";\nimport * as BROWSER from \"../../const/browser\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\nimport { quatToEuler } from \"../../utils\";\n\nexport const ROTATE_CONSTANT = {\n PITCH_DELTA: 1,\n YAW_DELTA_BY_ROLL: 2,\n YAW_DELTA_BY_YAW: 3\n} as const;\n\nROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = {\n targetAxis: [0, 1, 0],\n meshPoint: [0, 0, 1]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = {\n targetAxis: [0, 1, 0],\n meshPoint: [1, 0, 0]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = {\n targetAxis: [1, 0, 0],\n meshPoint: [0, 0, 1]\n};\n\nclass GyroInput extends Component> {\n public quaternion: quat;\n\n private _ignoreRoll: boolean;\n\n private _yawOrigin: number;\n private _yawOffset: number;\n private _orientation: {\n alpha: number;\n beta: number;\n gamma: number;\n }\n private _orientationUpdated: boolean;\n private _needsCalibrate: boolean;\n private _screenOrientation: number;\n private _enabled: boolean;\n\n public get enabled() { return this._enabled; }\n public get orientationUpdated() { return this._orientationUpdated; }\n public get ignoreRoll() { return this._ignoreRoll; }\n public set ignoreRoll(val: boolean) { this._ignoreRoll = val; }\n\n public constructor() {\n super();\n\n this.quaternion = quat.create();\n\n this._orientation = {\n alpha: 0,\n beta: 90,\n gamma: 0\n };\n this._yawOrigin = 0;\n this._yawOffset = 0;\n this._orientationUpdated = false;\n this._screenOrientation = 0;\n this._needsCalibrate = true;\n this._enabled = false;\n }\n\n public enable() {\n if (this._enabled) return;\n\n window.addEventListener(BROWSER.EVENTS.DEVICE_ORIENTATION, this._onDeviceOrientation);\n window.addEventListener(BROWSER.EVENTS.ORIENTATION_CHANGE, this._updateScreenOrientation);\n\n this._updateScreenOrientation();\n this._orientationUpdated = false;\n this._needsCalibrate = true;\n this._enabled = true;\n }\n\n public disable() {\n if (!this._enabled) return;\n\n window.removeEventListener(BROWSER.EVENTS.DEVICE_ORIENTATION, this._onDeviceOrientation);\n window.removeEventListener(BROWSER.EVENTS.ORIENTATION_CHANGE, this._updateScreenOrientation);\n\n this._enabled = false;\n }\n\n public update() {\n this._updateRotation();\n this._orientationUpdated = false;\n }\n\n public collectDelta() {\n if (!this._orientationUpdated) {\n return {\n pitch: 0,\n yaw: 0\n };\n }\n\n const prevRotation = quat.clone(this.quaternion);\n\n this._updateRotation();\n this._orientationUpdated = false;\n\n return this._toEulerDelta(prevRotation, this.quaternion);\n }\n\n public setInitialRotation(yaw: number) {\n this._yawOrigin = yaw;\n }\n\n private _onDeviceOrientation = (evt: DeviceOrientationEvent) => {\n const prevOrientation = this._orientation;\n const { alpha, beta, gamma } = evt;\n\n if (\n alpha == null\n || beta == null\n || gamma == null\n ) return;\n\n prevOrientation.alpha = alpha;\n prevOrientation.beta = beta;\n prevOrientation.gamma = gamma;\n\n this._orientationUpdated = true;\n\n if (this._needsCalibrate) {\n this._needsCalibrate = false;\n this._calibrateSensor();\n }\n };\n\n private _calibrateSensor() {\n const yawOrigin = this._yawOrigin;\n const rotation = this.quaternion;\n\n this._yawOffset = 0;\n this._updateRotation();\n\n const { yaw: sensorYaw } = quatToEuler(rotation);\n this._yawOffset = sensorYaw - yawOrigin;\n this._updateRotation();\n\n this._needsCalibrate = false;\n }\n\n private _updateRotation() {\n const rotation = this.quaternion;\n const { alpha, beta, gamma } = this._orientation;\n\n quat.identity(rotation);\n quat.rotateY(rotation, rotation, (alpha - this._yawOffset) * DEG_TO_RAD);\n quat.rotateX(rotation, rotation, beta * DEG_TO_RAD);\n quat.rotateZ(rotation, rotation, -gamma * DEG_TO_RAD);\n\n const screen = quat.create();\n const screenAngle = -this._screenOrientation * 0.5 * DEG_TO_RAD;\n const world = quat.fromValues(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5));\n\n quat.set(screen, 0, Math.sin(screenAngle), 0, Math.cos(screenAngle));\n quat.multiply(rotation, rotation, screen);\n quat.multiply(rotation, rotation, world);\n\n quat.normalize(rotation, rotation);\n }\n\n private _updateScreenOrientation = () => {\n if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) {\n this._screenOrientation = screen.orientation.angle;\n } else if (window.orientation !== undefined) {\n this._screenOrientation = window.orientation >= 0 ?\n window.orientation : 360 + window.orientation;\n } else {\n this._screenOrientation = 0;\n }\n }\n\n private _toEulerDelta(prevQuat: quat, currentQuat: quat) {\n return {\n yaw: this._getDeltaYaw(prevQuat, currentQuat),\n pitch: this._getDeltaPitch(prevQuat, currentQuat),\n };\n }\n\n private _getDeltaYaw(prvQ: quat, curQ: quat): number {\n const yawDeltaByYaw = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW);\n const yawDeltaByRoll = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL)\n * Math.sin(this._extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n }\n\n private _getDeltaPitch(prvQ: quat, curQ: quat): number {\n return this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n }\n\n private _getRotationDelta(prevQ: quat, curQ: quat, rotateKind: typeof ROTATE_CONSTANT[keyof typeof ROTATE_CONSTANT]) {\n const targetAxis = vec3.fromValues(\n ROTATE_CONSTANT[rotateKind].targetAxis[0],\n ROTATE_CONSTANT[rotateKind].targetAxis[1],\n ROTATE_CONSTANT[rotateKind].targetAxis[2]\n );\n const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint;\n\n const prevQuaternion = quat.clone(prevQ);\n const curQuaternion = quat.clone(curQ);\n\n quat.normalize(prevQuaternion, prevQuaternion);\n quat.normalize(curQuaternion, curQuaternion);\n\n let prevPoint = vec3.fromValues(0, 0, 1);\n let curPoint = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n vec3.transformQuat(targetAxis, targetAxis, curQuaternion);\n\n const rotateDistance = vec3.dot(targetAxis, vec3.cross(vec3.create(), prevPoint, curPoint));\n const rotateDirection = rotateDistance > 0 ? 1 : -1;\n\n // when counter clock wise, use vec3.fromValues(0,1,0)\n // when clock wise, use vec3.fromValues(0,-1,0)\n // const meshPoint1 = vec3.fromValues(0, 0, 0);\n const meshPoint2 = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n\n let meshPoint3;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n meshPoint3 = vec3.fromValues(0, rotateDirection, 0);\n } else {\n meshPoint3 = vec3.fromValues(rotateDirection, 0, 0);\n }\n\n vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion);\n vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion);\n\n const vecU = meshPoint2;\n const vecV = meshPoint3;\n const vecN = vec3.create();\n\n vec3.cross(vecN, vecU, vecV);\n vec3.normalize(vecN, vecN);\n\n const coefficientA = vecN[0];\n const coefficientB = vecN[1];\n const coefficientC = vecN[2];\n\n // a point on the plane\n curPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n\n // a point should project on the plane\n prevPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n\n // distance between prevPoint and the plane\n let distance = Math.abs(\n prevPoint[0] * coefficientA +\n prevPoint[1] * coefficientB +\n prevPoint[2] * coefficientC\n );\n\n const projectedPrevPoint = vec3.create();\n\n vec3.subtract(projectedPrevPoint, prevPoint, vec3.scale(vec3.create(), vecN, distance));\n\n let trigonometricRatio =\n (projectedPrevPoint[0] * curPoint[0] +\n projectedPrevPoint[1] * curPoint[1] +\n projectedPrevPoint[2] * curPoint[2]) /\n (vec3.length(projectedPrevPoint) * vec3.length(curPoint));\n\n // defensive block\n if (trigonometricRatio > 1) {\n trigonometricRatio = 1;\n }\n\n const theta = Math.acos(trigonometricRatio);\n\n const crossVec = vec3.cross(vec3.create(), curPoint, projectedPrevPoint);\n\n distance = coefficientA * crossVec[0]\n + coefficientB * crossVec[1]\n + coefficientC * crossVec[2];\n\n let thetaDirection: number;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n thetaDirection = distance > 0 ? 1 : -1;\n } else {\n thetaDirection = distance < 0 ? 1 : -1;\n }\n\n const deltaRadian = theta * thetaDirection * rotateDirection;\n\n return deltaRadian * RAD_TO_DEG;\n }\n\n private _extractPitchFromQuat(quaternion: quat) {\n const baseV = vec3.fromValues(0, 0, 1);\n vec3.transformQuat(baseV, baseV, quaternion);\n\n return -1 * Math.atan2(\n baseV[1],\n Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2)));\n }\n}\n\nexport default GyroInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport GyroInput from \"./input/GyroInput\";\nimport Motion from \"../core/Motion\";\nimport Camera from \"../core/Camera\";\nimport * as BROWSER from \"../const/browser\";\nimport { CONTROL_EVENTS } from \"../const/internal\";\nimport { ControlEvents } from \"../type/internal\";\nimport { sensorCanBeEnabledIOS } from \"../utils\";\n\n/**\n * Options for {@link GyroControl}\n * @ko {@link GyroControl}용 옵션들\n * @since 4.0.0\n */\nexport interface GyroControlOptions {\n /**\n * @copy GyroControl#ignoreRoll\n */\n ignoreRoll: boolean;\n}\n\nexport type GyroControlEvents = ControlEvents;\n\n/**\n * Camera's rotation control by gyroscope\n * @ko 자이로스코프를 이용한 회전 컨트롤\n * @since 4.0.0\n */\nclass GyroControl extends Component implements CameraControl {\n // Options\n private _ignoreRoll: GyroControlOptions[\"ignoreRoll\"];\n\n // Internal values\n private _enableBlocked: boolean;\n private _input: GyroInput;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._input.enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() {\n return this._input.enabled && this._input.orientationUpdated;\n }\n\n /**\n * When `true`, ignore gyroscope's roll(z-axis rotation) value.\n * :::caution\n * Setting `false` will ignore camera's range limit.\n * Options like {@link View360Options#yawRange}, {@link View360Options#pitchRange} are ignored, and {@link CylinderProjection} also can't force it's camera range limit.\n * :::\n * @ko `true`일 경우 자이로스코프 입력의 roll(z축 회전)값을 무시합니다.\n * :::caution\n * 이 값을 `false`로 설정할 경우 카메라 범위 제약을 무시합니다.\n * {@link View360Options#yawRange}, {@link View360Options#pitchRange}와 같은 값은 무시되며, {@link CylinderProjection} 사용시에도 범위를 벗어날 수 있습니다.\n * :::\n * @default true\n * @since 4.0.0\n */\n public get ignoreRoll() { return this._ignoreRoll; }\n public set ignoreRoll(val: GyroControlOptions[\"ignoreRoll\"]) { this._ignoreRoll = val; }\n\n /**\n * Return availability of the gyroscope.\n * :::caution\n * This will always return false until user permission under environments like iOS which requires user permission when using gyroscope.\n * :::\n * @ko 자이로스코프 사용 가능 여부를 반환합니다.\n * :::caution\n * iOS와 같이 GyroScope 사용시 사용자 Permission을 요구하는 환경에서는 사용자 Permission을 받기 전까지 항상 `false`입니다.\n * :::\n * @example\n * ```ts\n * const gyroAvailable = await GyroControl.isAvailable();\n * ```\n */\n public static async isAvailable(): Promise {\n if (!DeviceMotionEvent) {\n return false;\n }\n\n let onDeviceMotionChange: (evt: DeviceMotionEvent) => void;\n\n const listenDeviceMotion = () => new Promise(res => {\n onDeviceMotionChange = (evt: DeviceMotionEvent) => {\n res(evt.rotationRate && evt.rotationRate.alpha != null);\n };\n\n window.addEventListener(BROWSER.EVENTS.DEVICE_MOTION, onDeviceMotionChange);\n });\n\n const timeout = () => new Promise(res => {\n setTimeout(() => res(false), 1000);\n });\n\n return Promise.race([listenDeviceMotion(), timeout()])\n .then((available: boolean) => {\n window.removeEventListener(BROWSER.EVENTS.DEVICE_MOTION, onDeviceMotionChange);\n\n return available;\n });\n }\n\n /**\n * Request user permission for gyroscope sensor.\n * This can be used in environments like iOS which requires user permission when using gyroscope sensors.\n * @ko 사용자의 sensor permission 취득을 요청합니다.\n * iOS와 같이 gyroscope 사용시 사용자 Permission을 요구하는 환경에서 사용 가능합니다.\n * @returns Whether the permission is granted {@ko 사용자 permission 취득 여부}\n */\n public static async requestSensorPermission(): Promise {\n // Request sensor permission, on iOS13+\n if (sensorCanBeEnabledIOS()) {\n return (DeviceMotionEvent as typeof DeviceMotionEvent & {\n requestPermission: () => Promise;\n }).requestPermission().then(permissionState => {\n return permissionState === \"granted\";\n }).catch(() => false);\n }\n\n return true;\n }\n\n /**\n * Create new GyroControl instance\n * @ko GyroControl의 인스턴스를 생성합니다.\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(enableBlocked: boolean, {\n ignoreRoll = true\n }: Partial = {}) {\n super();\n\n this._enableBlocked = enableBlocked;\n this._ignoreRoll = ignoreRoll;\n this._input = new GyroInput();\n }\n\n /**\n * @copy CameraControl#destroy\n */\n public destroy(): void {\n this.disable();\n this._input.off();\n this.off();\n }\n\n /**\n * @hidden\n */\n public update(camera: Camera, yaw: Motion, pitch: Motion, zoom: number) {\n if (!this._ignoreRoll) {\n this._updateQuaternion(camera, zoom);\n } else {\n this._updateYawPitch(camera, yaw, pitch, zoom);\n }\n }\n\n /**\n * @copy CameraControl#enable\n */\n public enable(): void {\n if (this._input.enabled) return;\n\n this._input.enable();\n this._enableBlocked = false;\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: false });\n }\n\n /**\n * @copy CameraControl#disable\n */\n public disable(): void {\n if (!this._input.enabled) return;\n\n this._input.disable();\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: false });\n }\n\n /**\n * @copy CameraControl#sync\n */\n public sync(): void {} // eslint-disable-line @typescript-eslint/no-empty-function\n\n private _updateYawPitch(camera: Camera, yaw: Motion, pitch: Motion, zoom: number) {\n const input = this._input;\n if (!input.enabled) return;\n\n const {\n yaw: yawDelta,\n pitch: pitchDelta\n } = input.collectDelta();\n\n yaw.add(yawDelta);\n pitch.add(pitchDelta);\n\n camera.lookAt({\n yaw: yaw.val,\n pitch: pitch.val,\n zoom\n });\n }\n\n private _updateQuaternion(camera: Camera, zoom: number) {\n const input = this._input;\n if (!input.enabled) return;\n\n input.update();\n camera.rotate(input.quaternion, zoom);\n }\n}\n\nexport default GyroControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport CameraControl from \"./CameraControl\";\nimport RotateControl, { RotateControlEvents, RotateControlOptions } from \"./RotateControl\";\nimport ZoomControl, { ZoomControlOptions } from \"./ZoomControl\";\nimport GyroControl, { GyroControlOptions } from \"./GyroControl\";\nimport Camera from \"../core/Camera\";\nimport CameraAnimation from \"../core/CameraAnimation\";\nimport * as BROWSER from \"../const/browser\";\nimport { CAMERA_EVENTS, CONTROL_EVENTS } from \"../const/internal\";\nimport { ValueOf } from \"../type/utils\";\nimport { getObjectOption, hfovToZoom } from \"../utils\";\n\n/**\n * Options for {@link PanoControl}\n * @ko {@link PanoControl}용 옵션들\n * @since 4.0.0\n */\nexport interface PanoControlOptions {\n /**\n * @copy View360#useGrabCursor\n */\n useGrabCursor: boolean;\n /**\n * @copy View360#scrollable\n */\n scrollable: boolean;\n /**\n * @copy View360#wheelScrollable\n */\n wheelScrollable: boolean;\n /**\n * @copy View360#disableContextMenu\n */\n disableContextMenu: boolean;\n /**\n * Options for {@link RotateControl}.\n * `false` to disable rotation.\n * @ko {@link RotateControl}용 옵션들.\n * `false`일 경우 회전이 비활성화됩니다.\n * @since 4.0.0\n */\n rotate: boolean | Partial;\n /**\n * Options for {@link ZoomControl}.\n * `false` to disable zoom.\n * @ko {@link ZoomControl}용 옵션들.\n * `false`일 경우 줌이 비활성화됩니다.\n * @since 4.0.0\n */\n zoom: boolean | Partial;\n /**\n * Options for {@link GyroControl}.\n * `false` to disable gyroscope control.\n * @ko {@link GyroControl}용 옵션들.\n * `false`일 경우 자이로스코프를 통한 컨트롤이 비활성화됩니다.\n * @since 4.0.0\n */\n gyro: boolean | Partial;\n}\n\n/**\n * Panorama control for View360\n * @ko View360용 파노라마 컨트롤\n * @since 4.0.0\n */\nclass PanoControl {\n // Options\n private _useGrabCursor: PanoControlOptions[\"useGrabCursor\"];\n private _disableContextMenu: PanoControlOptions[\"disableContextMenu\"];\n\n // Internal Values\n private _camera: Camera;\n private _controlEl: HTMLElement;\n private _rotateControl: RotateControl;\n private _zoomControl: ZoomControl;\n private _gyroControl: GyroControl;\n private _ignoreZoomScale: boolean;\n private _enabled: boolean;\n\n /**\n * @copy View360#useGrabCursor\n */\n public get useGrabCursor() { return this._useGrabCursor; }\n public set useGrabCursor(val: PanoControlOptions[\"useGrabCursor\"]) {\n if (val === this._useGrabCursor) return;\n\n this._useGrabCursor = val;\n\n if (val && this._enabled) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n } else if (!val) {\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n }\n\n /**\n * @copy View360#disableContextMenu\n */\n public get disableContextMenu() { return this._disableContextMenu; }\n public set disableContextMenu(val: PanoControlOptions[\"disableContextMenu\"]) {\n if (val === this._disableContextMenu) return;\n\n this._disableContextMenu = val;\n\n if (val && this._enabled) {\n this._blockContextMenu();\n } else if (!val) {\n this._restoreContextMenu();\n }\n }\n\n /**\n * @copy View360#disableContextMenu\n */\n public get scrollable() { return this._rotateControl.scrollable; }\n public set scrollable(val: PanoControlOptions[\"scrollable\"]) { this._rotateControl.scrollable = val; }\n /**\n * @copy View360#disableContextMenu\n */\n public get wheelScrollable() { return this._zoomControl.scrollable; }\n public set wheelScrollable(val: PanoControlOptions[\"wheelScrollable\"]) { this._zoomControl.scrollable = val; }\n /**\n * When `true`, disables rotation slow-down by zoom-value.\n * @ko `true`일 경우 줌 된 정도에 따라 회전속도를 늦추는 동작을 비활성화합니다.\n * @since 4.0.0\n */\n public get ignoreZoomScale() { return this._ignoreZoomScale; }\n public set ignoreZoomScale(val: boolean) { this._ignoreZoomScale = val; }\n\n /**\n * Whether the control is enabled or not\n * @ko 컨트롤 활성화 여부를 가리키는 값\n * @readonly\n * @since 4.0.0\n */\n public get enabled() { return this._enabled; }\n /**\n * @copy View360#rotate\n */\n public get rotate() { return this._rotateControl; }\n /**\n * @copy View360#zoom\n */\n public get zoom() { return this._zoomControl; }\n /**\n * @copy View360#gyro\n */\n public get gyro() { return this._gyroControl; }\n\n /**\n * Whether one of the controls is animating at the moment\n * @ko 현재 컨트롤 중 하나라도 동작중인지 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get animating() {\n return this._rotateControl.animating\n || this._zoomControl.animating\n || this._gyroControl.animating;\n }\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param element - Canvas element {@ko 캔버스 엘리먼트}\n * @param camera - Camera instance {@ko Camera 인스턴스}\n * @param options - Options for PanoControl {@ko PanoControl 옵션들}\n */\n public constructor(element: HTMLElement, camera: Camera, {\n useGrabCursor,\n scrollable,\n wheelScrollable,\n disableContextMenu,\n rotate,\n zoom,\n gyro\n }: PanoControlOptions) {\n // Bind Options\n this._useGrabCursor = useGrabCursor;\n this._disableContextMenu = disableContextMenu;\n\n // Set internal values\n this._camera = camera;\n this._controlEl = element;\n this._ignoreZoomScale = false;\n this._enabled = false;\n\n this._rotateControl = new RotateControl(element, !rotate, getObjectOption(rotate));\n this._zoomControl = new ZoomControl(element, !zoom, getObjectOption(zoom));\n this._gyroControl = new GyroControl(!gyro, getObjectOption(gyro));\n\n this._rotateControl.scrollable = scrollable;\n this._zoomControl.scrollable = wheelScrollable;\n\n this._bindEvents();\n }\n\n /**\n * Destroy the instance and remove all event listeners attached.\n * This also will reset CSS cursor to initial.\n * @ko 인스턴스를 삭제하고 부착된 모든 이벤트 리스너를 제거합니다.\n * 또한, 캔버스에 적용된 CSS cursor도 제거합니다.\n * @since 4.0.0\n */\n public destroy(): void {\n this.disable();\n this._rotateControl.destroy();\n this._zoomControl.destroy();\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n\n /**\n * Resize control to match target size.\n * @ko 컨트롤이 내부에 캐시하고 있는 크기값을 갱신합니다.\n * @param width New width {@ko 변경된 너비}\n * @param height New height {@ko 변경된 높이}\n * @since 4.0.0\n */\n public resize(width: number, height: number): void {\n const camera = this._camera;\n\n this._rotateControl.resize(camera.fov, camera.aspect, width, height);\n }\n\n /**\n * Enable this control and add event listeners.\n * @ko 컨트롤을 활성화하고 이벤트 리스너들을 추가합니다.\n * @since 4.0.0\n */\n public async enable(): Promise {\n if (this._enabled) return;\n\n if (!this._rotateControl.enableBlocked) {\n this._rotateControl.enable();\n }\n\n if (!this._zoomControl.enableBlocked) {\n this._zoomControl.enable();\n }\n\n if (!this._gyroControl.enableBlocked) {\n if (await GyroControl.isAvailable()) {\n this._gyroControl.enable();\n }\n }\n\n this.sync();\n\n if (this._disableContextMenu) {\n this._blockContextMenu();\n }\n\n this._enabled = true;\n }\n\n /**\n * Disable this control and remove all event listeners\n * @ko 컨트롤을 비활성화하고 모든 이벤트 리스너들을 제거합니다.\n * @since 4.0.0\n */\n public disable(): void {\n if (!this._enabled) return;\n\n this._rotateControl.disable();\n this._zoomControl.disable();\n this._gyroControl.disable();\n\n this._restoreContextMenu();\n\n this._enabled = false;\n }\n\n /**\n * Update control by given deltaTime\n * @ko 컨트롤을 주어진 시간만큼 업데이트합니다.\n * @param delta Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n * @internal\n */\n public update(delta: number): void {\n const camera = this._camera;\n const rotateControl = this._rotateControl;\n const zoomControl = this._zoomControl;\n const gyroControl = this._gyroControl;\n\n zoomControl.update(delta);\n const zoom = hfovToZoom(camera.fov, zoomControl.zoom);\n\n // Slow down rotation on zoom-in\n const zoomScale = this._ignoreZoomScale ? 1 : Math.max(zoom, 1);\n rotateControl.setZoomScale(zoomScale);\n rotateControl.updateRange(camera, zoom);\n rotateControl.update(delta);\n\n const yaw = rotateControl.yaw;\n const pitch = rotateControl.pitch;\n\n if (gyroControl.enabled) {\n gyroControl.update(camera, yaw, pitch, zoom);\n } else {\n camera.lookAt({\n yaw: yaw.val,\n pitch: pitch.val,\n zoom\n });\n }\n }\n\n /**\n * Synchronize this control's state to current camera state\n * @ko 컨트롤을 카메라의 현재 상태와 동기화합니다.\n * @since 4.0.0\n */\n public sync(): void {\n const camera = this._camera;\n\n this._zoomControl.sync(camera);\n this._rotateControl.sync(camera);\n }\n\n private _blockContextMenu() {\n const el = this._controlEl;\n\n el.addEventListener(BROWSER.EVENTS.CONTEXT_MENU, this._preventContextMenu);\n }\n\n private _restoreContextMenu() {\n const el = this._controlEl;\n\n el.removeEventListener(BROWSER.EVENTS.CONTEXT_MENU, this._preventContextMenu);\n }\n\n private _preventContextMenu = (evt: MouseEvent) => {\n evt.preventDefault();\n };\n\n private _setCursor(newCursor: ValueOf) {\n if (!this._useGrabCursor && newCursor !== BROWSER.CURSOR.NONE) return;\n\n const targetEl = this._controlEl;\n targetEl.style.cursor = newCursor;\n }\n\n private _bindEvents() {\n const rotateControl = this._rotateControl;\n const zoomControl = this._zoomControl;\n\n rotateControl.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n rotateControl.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n rotateControl.on(CONTROL_EVENTS.ENABLE, this._onEnable);\n rotateControl.on(CONTROL_EVENTS.DISABLE, this._onDisable);\n zoomControl.on(CONTROL_EVENTS.ENABLE, this._onEnable);\n zoomControl.on(CONTROL_EVENTS.DISABLE, this._onDisable);\n this._camera.on(CAMERA_EVENTS.ANIMATION_END, this._onCameraAnimationEnd);\n }\n\n private _onInputStart = (evt: RotateControlEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n if (this._useGrabCursor && !evt.isKeyboard) {\n this._setCursor(BROWSER.CURSOR.GRABBING);\n }\n };\n\n private _onInputEnd = (evt: RotateControlEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n if (this._useGrabCursor && !evt.isKeyboard) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n }\n };\n\n private _onEnable = ({\n control,\n updateCursor\n }: {\n control: CameraControl;\n updateCursor: boolean;\n }) => {\n if (updateCursor && this._useGrabCursor) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n }\n\n control.sync(this._camera);\n };\n\n private _onDisable = ({\n updateCursor\n }: {\n updateCursor: boolean\n }) => {\n if (updateCursor) {\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n };\n\n private _onCameraAnimationEnd = ({ animation }: { animation: CameraAnimation }) => {\n animation.getFinishPromise().then(() => {\n this.sync();\n });\n };\n}\n\nexport default PanoControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport TextureVideo from \"./TextureVideo\";\nimport TextureCube from \"./TextureCube\";\n\n/**\n * @hidden\n */\nabstract class Texture {\n public width: number;\n public height: number;\n public flipY: boolean;\n public wrapS: number;\n public wrapT: number;\n\n public constructor({\n width,\n height,\n flipY\n }: {\n width: number;\n height: number;\n flipY: boolean;\n }) {\n this.width = width;\n this.height = height;\n this.flipY = flipY;\n this.wrapS = WebGLRenderingContext.CLAMP_TO_EDGE;\n this.wrapT = WebGLRenderingContext.CLAMP_TO_EDGE;\n }\n\n public destroy() {\n // DO_NOTHING\n }\n\n public isVideo(): this is TextureVideo {\n return false;\n }\n\n public isCube(): this is TextureCube {\n return false;\n }\n}\n\nexport default Texture;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture from \"./Texture\";\n\n/**\n * @hidden\n */\nclass Texture2D extends Texture {\n public source: Exclude;\n\n public constructor({\n source,\n width,\n height,\n flipY\n }: {\n source: Exclude;\n width: number;\n height: number;\n flipY: boolean;\n }) {\n super({\n width,\n height,\n flipY\n });\n\n this.source = source;\n }\n}\n\nexport default Texture2D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"./Texture2D\";\n\n/**\n * @hidden\n */\nclass TextureVideo extends Texture2D {\n public source: HTMLVideoElement;\n\n public destroy() {\n const video = this.source;\n\n video.pause();\n video.removeAttribute(\"src\");\n video.load();\n }\n\n public isVideo(): this is TextureVideo { return true; }\n\n public isPaused() {\n const video = this.source;\n\n return video.paused || video.ended || video.readyState <= 2;\n }\n\n public hasAudio() {\n const video = this.source as any;\n\n if (video.audioTracks) {\n return video.audioTracks.length > 0;\n }\n\n if (video.webkitAudioDecodedByteCount != null) {\n return video.webkitAudioDecodedByteCount > 0;\n }\n\n if (video.mozHasAudio != null) {\n return video.mozHasAudio;\n }\n\n // We don't know whether the video has audio or not, return true\n return true;\n }\n}\n\nexport default TextureVideo;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture from \"./Texture\";\n\n/**\n * @hidden\n */\nclass TextureCube extends Texture {\n public sources: TexImageSource[];\n\n public constructor({\n sources,\n width,\n height,\n flipY\n }: {\n sources: TexImageSource[];\n width: number;\n height: number;\n flipY: boolean;\n }) {\n super({\n width,\n height,\n flipY\n });\n\n this.sources = sources;\n }\n\n public isCube(): this is TextureCube { return true; }\n}\n\nexport default TextureCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ImReady from \"@egjs/imready\";\nimport Texture from \"../texture/Texture\";\nimport Texture2D from \"../texture/Texture2D\";\nimport TextureVideo from \"../texture/TextureVideo\";\nimport TextureCube from \"../texture/TextureCube\";\nimport { getObjectOption, isString } from \"../utils\";\nimport { VideoConfig } from \"../type/external\";\nimport { ProjectionOptions } from \"../projection/Projection\";\n\n/**\n * @hidden\n */\nclass TextureLoader {\n private _loadChecker: ImReady;\n\n constructor() {\n this._loadChecker = new ImReady();\n }\n\n public async load(src: ProjectionOptions[\"src\"], video: ProjectionOptions[\"video\"]): Promise {\n if (video) {\n return this.loadVideo(src, getObjectOption(video));\n } else {\n if (Array.isArray(src) && src.length > 1) {\n return this.loadCubeImage(src);\n } else {\n const imgSrc = Array.isArray(src) ? src[0] : src;\n return this.loadImage(imgSrc);\n }\n }\n }\n\n public async loadImage(src: string | HTMLElement): Promise {\n const images = this._toImageArray(src);\n\n return this._load(images, resolve => {\n const image = images[0];\n\n resolve(new Texture2D({\n source: image,\n width: image.naturalWidth,\n height: image.naturalHeight,\n flipY: true\n }));\n });\n }\n\n public async loadCubeImage(src: Array): Promise {\n const images = this._toImageArray(src);\n\n return this._load(images, resolve => {\n resolve(new TextureCube({\n sources: images,\n width: images[0].naturalWidth,\n height: images[0].naturalHeight,\n flipY: false\n }));\n });\n }\n\n public async loadVideo(src: ProjectionOptions[\"src\"], videoConfig: Partial): Promise {\n const config: VideoConfig = {\n autoplay: true,\n muted: true,\n loop: false,\n volume: 1,\n ...videoConfig,\n };\n const video = this._toVideoElement(src, config);\n\n return this._load([video], resolve => {\n const { autoplay, muted } = config;\n\n video.currentTime = 0;\n if (autoplay && muted) {\n video.play().catch(() => void 0);\n }\n\n resolve(new TextureVideo({\n source: video,\n width: video.videoWidth,\n height: video.videoHeight,\n flipY: true\n }));\n });\n }\n\n private _load(content: HTMLElement[], onLoad: (resolve: (value: T) => void) => void): Promise {\n const loader = this._loadChecker;\n\n return new Promise((resolve, reject) => {\n loader.once(\"ready\", evt => {\n if (evt.errorCount > 0) return;\n\n onLoad(resolve);\n });\n\n loader.once(\"error\", reject);\n loader.check(content);\n });\n }\n\n private _toImageArray(src: ProjectionOptions[\"src\"]): HTMLImageElement[] {\n const srcs = Array.isArray(src) ? src : [src];\n\n return srcs.map(source => {\n if (isString(source)) {\n const imgEl = new Image();\n\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = source;\n\n return imgEl;\n } else {\n return source as HTMLImageElement;\n }\n });\n }\n\n private _toVideoElement(src: ProjectionOptions[\"src\"], {\n muted,\n loop,\n volume\n }: VideoConfig): HTMLVideoElement {\n if (src instanceof HTMLVideoElement) {\n return src;\n }\n\n const video = document.createElement(\"video\");\n\n video.crossOrigin = \"anonymous\";\n video.playsInline = true;\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.muted = muted;\n video.volume = volume;\n video.loop = loop;\n\n if (Array.isArray(src)) {\n src.forEach(source => this._appendSourceElement(video, source));\n } else {\n this._appendSourceElement(video, src);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0 && video.readyState < 1) {\n video.load();\n }\n\n return video;\n }\n\n private _appendSourceElement(video: HTMLMediaElement, src: string | HTMLElement) {\n if (src instanceof HTMLSourceElement) {\n return src;\n }\n\n const sourceEl = document.createElement(\"source\");\n sourceEl.src = src as string;\n video.appendChild(sourceEl);\n }\n}\n\nexport default TextureLoader;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * @internal\n */\nclass FrameAnimator {\n public maxDeltaTime: number;\n\n private _context: Window | XRSession;\n private _rafId: number;\n private _rafTimer: number;\n private _lastUpdateTime: number;\n\n /** */\n public constructor(maxDeltaTime: number, context: Window | XRSession = window) {\n this.maxDeltaTime = maxDeltaTime;\n\n this._context = context;\n this._rafId = -1;\n this._rafTimer = -1;\n this._lastUpdateTime = -1;\n }\n\n public start(callback: (delta: number, ...args: any[]) => any) {\n const context = this._context;\n\n // No context / callback set\n if (!context || !callback) return;\n\n // Animation already started\n if (this._rafId >= 0 || this._rafTimer >= 0) return;\n\n const loop = (_time: number, frame?: XRFrame) => {\n const time = Date.now();\n const delta = Math.min(time - this._lastUpdateTime, this.maxDeltaTime * 1000);\n\n callback(delta, frame);\n\n this._lastUpdateTime = time;\n this._rafId = context.requestAnimationFrame(loop);\n };\n\n this._lastUpdateTime = Date.now();\n this._rafId = context.requestAnimationFrame(loop);\n }\n\n public stop() {\n if (this._rafId >= 0) {\n this._context.cancelAnimationFrame(this._rafId);\n }\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n }\n\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n public changeContext(context: Window | XRSession) {\n this.stop();\n this._context = context;\n }\n}\n\nexport default FrameAnimator;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport * as BROWSER from \"../const/browser\";\n\n/**\n * Automatic resizer that uses both ResizeObserver and window resize event\n */\nclass AutoResizer {\n private _enabled: boolean;\n private _resizeObserver: ResizeObserver | null;\n private _useResizeObserver: boolean;\n private _onResize: () => any;\n\n public get useResizeObserver() { return this._useResizeObserver; }\n\n /**\n * Returns whether AutoResizer is enabled\n */\n public get enabled() { return this._enabled; }\n\n /** */\n public constructor(useResizeObserver: boolean, onResize: () => any) {\n this._useResizeObserver = useResizeObserver;\n\n this._enabled = false;\n this._resizeObserver = null;\n this._onResize = onResize;\n }\n\n /**\n * Enable resizer\n */\n public enable(element: HTMLElement): this {\n if (this._enabled) {\n this.disable();\n }\n\n if (this._useResizeObserver && !!window.ResizeObserver) {\n const bbox = element.getBoundingClientRect();\n const resizeImmediate = bbox.width !== 0 || bbox.height !== 0;\n\n const resizeObserver = new ResizeObserver(resizeImmediate ? this._skipFirstResize : this._onResize);\n\n resizeObserver.observe(element);\n\n this._resizeObserver = resizeObserver;\n } else {\n window.addEventListener(BROWSER.EVENTS.RESIZE, this._onResize);\n }\n\n this._enabled = true;\n\n return this;\n }\n\n /**\n * Disable resizer\n */\n public disable(): this {\n if (!this._enabled) return this;\n\n const resizeObserver = this._resizeObserver;\n if (resizeObserver) {\n resizeObserver.disconnect();\n this._resizeObserver = null;\n } else {\n window.removeEventListener(BROWSER.EVENTS.RESIZE, this._onResize);\n }\n\n this._enabled = false;\n\n return this;\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n private _skipFirstResize = (() => {\n let isFirstResize = true;\n\n return (() => {\n if (isFirstResize) {\n isFirstResize = false;\n\n return;\n }\n this._onResize();\n });\n })();\n}\n\nexport default AutoResizer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Camera from \"./Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport View360 from \"../View360\";\nimport * as BROWSER from \"../const/browser\";\nimport { CONTROL_EVENTS } from \"../const/internal\";\nimport { circulate, getObjectOption } from \"../utils\";\n\n/**\n * Options for {@link Autoplay}\n * @ko {@link Autoplay}용 옵션들\n * @since 4.0.0\n */\nexport interface AutoplayOptions {\n /**\n * @copy Autoplay#delay\n */\n delay: number;\n /**\n * @copy Autoplay#delayOnMouseLeave\n */\n delayOnMouseLeave: number;\n /**\n * @copy Autoplay#speed\n */\n speed: number;\n /**\n * @copy Autoplay#pauseOnHover\n */\n pauseOnHover: boolean;\n /**\n * @copy Autoplay#canInterrupt\n */\n canInterrupt: boolean;\n /**\n * @copy Autoplay#disableOnInterrupt\n */\n disableOnInterrupt: boolean;\n}\n\n/**\n * A manager class for autoplay feature.\n * @ko Autoplay 기능의 매니저 클래스.\n * @since 4.0.0\n */\nclass Autoplay {\n // Options\n private _delay: number;\n private _delayOnMouseLeave: number;\n private _speed: number;\n private _pauseOnHover: boolean;\n private _canInterrupt: boolean;\n private _disableOnInterrupt: boolean;\n\n // Internal values\n private _enableBlocked: boolean;\n private _camera: Camera;\n private _control: PanoControl;\n private _element: HTMLElement;\n private _enabled: boolean;\n private _interrupted: boolean;\n private _interruptionTimer: number;\n private _hovering: boolean;\n\n /**\n * Whether autoplay is enabled or not\n * @ko 자동재생 활성화 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * Whether autoplay is updating the camera at the moment\n * @ko 현재 자동재생이 동작중인지 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get playing() {\n return this._enabled && !this._interrupted;\n }\n\n /**\n * Reactivation delay after mouse input in milisecond.\n * @ko 재활성화되기까지의 시간 (밀리초 단위)\n * @default 2000\n * @since 4.0.0\n */\n public get delay() { return this._delay; }\n public set delay(val: number) { this._delay = val; }\n\n /**\n * Reactivation delay after mouse leave when using {@link AutoplayOptions#pauseOnHover}\n * @ko {@link AutoplayOptions#pauseOnHover} 사용시 마우스가 캔버스 영역을 떠난 뒤 자동재생이 다시 활성화되기까지의 시간\n * @default 0\n * @since 4.0.0\n */\n public get delayOnMouseLeave() { return this._delayOnMouseLeave; }\n public set delayOnMouseLeave(val: number) { this._delayOnMouseLeave = val; }\n\n /**\n * Y-axis(yaw) rotation speed\n * @ko Y-축 회전(yaw)의 속도\n * @default 1\n * @since 4.0.0\n */\n public get speed() { return this._speed; }\n public set speed(val: number) { this._speed = val; }\n\n /**\n * Whether to pause rotation on mouse hover\n * @ko 마우스가 캔버스 영역에 들어왔을 때 자동재생을 정지할지 여부\n * @default false\n * @since 4.0.0\n */\n public get pauseOnHover() { return this._pauseOnHover; }\n public set pauseOnHover(val: boolean) { this._pauseOnHover = val; }\n\n /**\n * Whether user can interrupt the rotation with click/wheel input\n * @ko 클릭이나 휠같은 사용자 인터랙션시 자동재생을 멈출지 여부\n * @default true\n * @since 4.0.0\n */\n public get canInterrupt() { return this._canInterrupt; }\n public set canInterrupt(val: boolean) { this._canInterrupt = val; }\n\n /**\n * Whether to disable autoplay on user interrupt\n * @ko 사용자 동작에 의해 자동재생이 정지할 때, {@link Autoplay#disable}을 호출하여 자동재생을 영구히 정지할지 여부\n * @default false\n * @since 4.0.0\n */\n public get disableOnInterrupt() { return this._disableOnInterrupt; }\n public set disableOnInterrupt(val: boolean) { this._disableOnInterrupt = val; }\n\n /**\n * Create new AutoPlayer instance\n * @param camera - Instance of the {@link Camera} {@ko Camera의 인스턴스}\n * @param element - Canvas element {@ko 캔버스 엘리먼트}\n * @param options - Autoplay options {@ko 자동재생 옵션들}\n * @since 4.0.0\n */\n public constructor(viewer: View360, element: HTMLElement, options: boolean | Partial) {\n this._camera = viewer.camera;\n this._control = viewer.control;\n this._element = element;\n\n this._enabled = false;\n this._interrupted = false;\n this._interruptionTimer = -1;\n this._hovering = false;\n\n const {\n delay = 2000,\n delayOnMouseLeave = 0,\n speed = 1,\n pauseOnHover = false,\n canInterrupt = true,\n disableOnInterrupt = false\n } = getObjectOption(options);\n\n this._enableBlocked = !options;\n this._delay = delay;\n this._delayOnMouseLeave = delayOnMouseLeave;\n this._speed = speed;\n this._pauseOnHover = pauseOnHover;\n this._canInterrupt = canInterrupt;\n this._disableOnInterrupt = disableOnInterrupt;\n }\n\n /**\n * Destroy the instance and remove all event listeners attached\n * @ko 인스턴스를 제거하고 연결된 모든 이벤트 핸들러를 삭제합니다.\n * @since 4.0.0\n */\n public destroy(): void {\n this.disable();\n }\n\n /**\n * Rotate camera by given deltaTime\n * @ko 주어진 deltaTime만큼 카메라를 회전시킵니다.\n * @param deltaTime - Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n */\n public update(deltaTime: number): void {\n if (!this._enabled) return;\n if (this._interrupted) {\n if (this._disableOnInterrupt) {\n this.disable();\n }\n\n return;\n }\n\n const camera = this._camera;\n const delta = -this._speed * deltaTime / 100;\n\n camera.yaw = circulate(camera.yaw + delta, 0, 360);\n }\n\n /**\n * Enable autoplay and add event listeners.\n * @ko 자동재생을 활성화하고 이벤트리스너들을 추가합니다.\n * @since 4.0.0\n */\n public enable(): void {\n const control = this._control;\n const element = this._element;\n\n if (this._enabled || control.gyro.enabled) return;\n\n control.rotate.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.rotate.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.zoom.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.zoom.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.gyro.on(CONTROL_EVENTS.ENABLE, this._onGyroEnable);\n\n element.addEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter, false);\n element.addEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave, false);\n\n this._enabled = true;\n this._enableBlocked = false;\n }\n\n /**\n * Enable autoplay after current `delay` value.\n * @ko 현재의 `delay`값만큼 시간이 지난 다음에 자동재생을 활성화합니다.\n * @since 4.0.0\n */\n public enableAfterDelay() {\n this.enable();\n this._interrupted = true;\n this._setUninterruptedAfterDelay(this._delay);\n }\n\n /**\n * Disable autoplay and remove all event handlers.\n * @ko 자동재생을 비활성화하고 모든 이벤트 핸들러를 제거합니다.\n * @since 4.0.0\n */\n public disable(): void {\n if (!this._enabled) return;\n\n const control = this._control;\n const element = this._element;\n\n control.rotate.off(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.rotate.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.zoom.off(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.zoom.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.gyro.off(CONTROL_EVENTS.ENABLE, this._onGyroEnable);\n\n element.removeEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter, false);\n element.removeEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave, false);\n\n this._enabled = false;\n this._interrupted = false;\n this._hovering = false;\n\n this._clearTimeout();\n }\n\n private _onInputStart = () => {\n if (!this._canInterrupt) return;\n\n this._interrupted = true;\n this._clearTimeout();\n };\n\n private _onInputEnd = () => {\n this._setUninterruptedAfterDelay(this._delay);\n };\n\n private _onGyroEnable = () => {\n this.disable();\n };\n\n private _onMouseEnter = () => {\n if (!this._pauseOnHover) return;\n this._interrupted = true;\n this._hovering = true;\n };\n\n private _onMouseLeave = () => {\n if (!this._pauseOnHover) return;\n this._hovering = false;\n this._setUninterruptedAfterDelay(this._delayOnMouseLeave);\n };\n\n private _setUninterruptedAfterDelay(delay: number): void {\n if (this._hovering) return;\n\n this._clearTimeout();\n\n if (delay > 0) {\n this._interruptionTimer = window.setTimeout(() => {\n this._interrupted = false;\n this._interruptionTimer = -1;\n }, delay);\n } else {\n this._interrupted = false;\n this._interruptionTimer = -1;\n }\n }\n\n private _clearTimeout(): void {\n if (this._interruptionTimer >= 0) {\n window.clearTimeout(this._interruptionTimer);\n this._interruptionTimer = -1;\n }\n }\n}\n\nexport default Autoplay;\n","import { mat4 } from \"gl-matrix\";\nimport Component from \"@egjs/component\";\nimport WebGLContext from \"./WebGLContext\";\nimport GyroControl from \"../control/GyroControl\";\nimport * as BROWSER from \"../const/browser\";\nimport { SESSION_VR, XR_REFERENCE_SPACE } from \"../const/internal\";\nimport { EVENTS } from \"../const/external\";\n\ninterface XRSessionOptions extends XRSessionInit {\n [key: string]: any;\n}\n\n/**\n * WebXR manager class\n * @ko WebXR 매니저 클래스\n * @since 4.0.0\n */\nclass XRManager extends Component<{\n /**\n * An event that fires on entering VR session\n * @ko VR 세션 진입시에 트리거되는 이벤트\n * @eventName vrStart\n * @eventOf XRManager\n * @version 4.0.0\n */\n [EVENTS.VR_START]: {\n session: XRSession;\n };\n /**\n * An event that fires on exiting VR session\n * @ko VR 세션에서 나갈 때 트리거되는 이벤트\n * @eventName vrEnd\n * @eventOf XRManager\n * @version 4.0.0\n */\n [EVENTS.VR_END]: void;\n}> {\n private _ctx: WebGLContext;\n private _xrSession: XRSession | null;\n private _xrRefSpace: XRReferenceSpace | null;\n private _options: XRSessionOptions;\n\n /**\n * Create new instance.\n * 새 인스턴스를 생성합니다.\n * @param ctx - Instance of WebGL context helper {@ko WebGL 콘텍스트 헬퍼의 인스턴스}\n * @param options - Options {@ko 옵션들}\n */\n public constructor(ctx: WebGLContext, options: XRSessionOptions = {}) {\n super();\n\n this._xrSession = null;\n this._xrRefSpace = null;\n this._ctx = ctx;\n this._options = options;\n }\n\n /**\n * Destroy instance and end XR session if there was any.\n * @ko 인스턴스를 제거하고, XR 세션이 존재할 경우 종료합니다.\n * @since 4.0.0\n */\n public destroy = () => {\n this.exit();\n this.off();\n };\n\n /**\n * Returns WebXR availability.\n * @ko WebXR 사용 가능 여부를 반환합니다.\n * @since 4.0.0\n */\n public async isAvailable(): Promise {\n // eslint-disable-next-line compat/compat\n const xr = window.navigator.xr;\n if (!xr) return false;\n\n return xr.isSessionSupported(SESSION_VR)\n .then(available => {\n return available;\n }).catch(() => {\n return false;\n });\n }\n\n /**\n * Enter VR session\n * @ko VR 세션에 진입합니다.\n * @since 4.0.0\n */\n public async enter() {\n const ctx = this._ctx;\n\n // eslint-disable-next-line compat/compat\n const xr = window.navigator.xr;\n if (!xr) return;\n\n await GyroControl.requestSensorPermission();\n\n const options = {\n ...{\n requiredFeatures: [XR_REFERENCE_SPACE]\n },\n ...this._options\n };\n\n await ctx.makeXRCompatible();\n\n const session = await xr.requestSession(SESSION_VR, options);\n ctx.bindXRLayer(session);\n\n const refSpace = await session.requestReferenceSpace(XR_REFERENCE_SPACE);\n\n this._setSession(session, refSpace);\n\n this.trigger(EVENTS.VR_START, {\n session\n });\n }\n\n /**\n * Exit VR session\n * @ko VR 세션에서 나갑니다.\n * @since 4.0.0\n */\n public exit() {\n const xrSession = this._xrSession;\n\n if (xrSession) {\n xrSession.end()\n .catch(() => void 0);\n }\n\n this._xrSession = null;\n this._xrRefSpace = null;\n }\n\n /**\n * @hidden\n */\n public canRender(frame: XRFrame) {\n const refSpace = this._xrRefSpace;\n\n if (!refSpace) return false;\n\n const pose = frame.getViewerPose(refSpace);\n\n return !!pose;\n }\n\n /**\n * @hidden\n */\n public getEyeParams(frame: XRFrame): Array<{\n viewport: XRViewport;\n vMatrix: mat4;\n pMatrix: mat4;\n }> | null {\n const session = frame.session;\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n if (!pose) return null;\n\n const glLayer = session.renderState.baseLayer;\n\n if (!glLayer) return null;\n\n return pose.views.map(view => {\n const viewport = glLayer.getViewport(view)!;\n const vMatrix = view.transform.inverse.matrix;\n\n return {\n viewport,\n vMatrix,\n pMatrix: view.projectionMatrix\n };\n });\n }\n\n private _setSession(session: XRSession, refSpace: XRReferenceSpace) {\n this._xrSession = session;\n this._xrRefSpace = refSpace;\n\n session.addEventListener(BROWSER.EVENTS.XR_END, this._onSessionEnd);\n }\n\n private _onSessionEnd = () => {\n this.exit();\n this.trigger(EVENTS.VR_END);\n }\n}\n\nexport default XRManager;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { vec3 } from \"gl-matrix\";\n\n/**\n * Hotspot data\n * @ko 핫스팟 데이터\n * @since 4.0.0\n */\nclass Hotspot {\n /**\n * HTMLElement of the hotspot\n * @ko 핫스팟의 HTMLElement\n * @since 4.0.0\n */\n public readonly element: HTMLElement;\n /**\n * Position to render hotspot\n * @ko 핫스팟을 렌더링할 위치\n * @since 4.0.0\n */\n public readonly position: vec3;\n\n public constructor(element: HTMLElement, position: vec3) {\n this.element = element;\n this.position = position;\n }\n}\n\nexport default Hotspot;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { vec2, vec3 } from \"gl-matrix\";\nimport Hotspot from \"./Hotspot\";\nimport Camera from \"../core/Camera\";\nimport WebGLRenderer from \"../core/WebGLRenderer\";\nimport View360Error from \"../core/View360Error\";\nimport { getNullableElement } from \"../utils\";\nimport ERROR from \"../const/error\";\nimport { DEFAULT_CLASS } from \"../const/external\";\nimport { DEG_TO_RAD } from \"../const/internal\";\n\n/**\n * Options for {@link HotspotRenderer}\n * @ko {@link HotspotRenderer}용 옵션들\n * @since 4.0.0\n */\nexport interface HotspotOptions {\n /**\n * Apply scale for hotspots, makes their size sync with background panorama image.\n * @ko 핫스팟에 스케일을 적용해서 배경 파노라마 이미지의 크기 변화와 동일하게 크기를 조절합니다.\n * @since 4.0.0\n */\n zoom: boolean;\n}\n\n/**\n * Hotspot renderer\n * @ko Hotspot 렌더러\n * @since 4.0.0\n */\nclass HotspotRenderer {\n // Options\n private _zoom: HotspotOptions[\"zoom\"];\n\n // Internal properties\n private _containerEl: HTMLElement | null;\n private _renderer: WebGLRenderer;\n private _hotspots: Hotspot[];\n\n /**\n * Create new instance\n * @ko 새 인스턴스를 생성합니다.\n * @param rootEl - Container element for hotspots {@ko 핫스팟들의 컨테이너 엘리먼트}\n * @param renderer - instance of WebGLRenderer {@ko WebGLRenderer의 인스턴스}\n * @param options - Hotspot options {@ko Hotspot 옵션들 }\n */\n public constructor(rootEl: HTMLElement, renderer: WebGLRenderer, {\n zoom = false\n }: Partial) {\n this._containerEl = getNullableElement(`.${DEFAULT_CLASS.HOTSPOT_CONTAINER}`, rootEl);\n this._renderer = renderer;\n this._hotspots = [];\n\n this._zoom = zoom;\n }\n\n /**\n * Refresh hotspots by collecting hotspot elements from current hotspot root element\n * @ko 현재 핫스팟 루트 엘리먼트 내에서 핫스팟 엘리먼트들을 수집하여 갱신합니다.\n * @throws {ERROR_CODES.INSUFFICIENT_ARGS} if data-position doesn't include all x, y, z values {@ko data-position이 x, y, z좌표를 전부 포함하고 있지 않을 때}\n */\n public refresh() {\n const container = this._containerEl;\n if (!container) return;\n\n const hotspotEls = [].slice.apply(container.querySelectorAll(`.${DEFAULT_CLASS.HOTSPOT}`)) as HTMLElement[];\n this._hotspots = hotspotEls.map(el => this._parseHotspot(el));\n }\n\n /**\n * Render hotspots\n * @ko 핫스팟들을 렌더링합니다.\n * @param camera - Instance of Camera {@ko Camera의 인스턴스}\n */\n public render(camera: Camera) {\n const hotspots = this._hotspots;\n const halfWidth = this._renderer.width * 0.5;\n const halfHeight = this._renderer.height * 0.5;\n const zoom = camera.zoom;\n const centerTransform = \"translate(-50%, -50%)\";\n const zoomTransform = this._zoom ? `scale(${zoom})` : \"\";\n\n hotspots.forEach(hotspot => {\n const position = hotspot.position;\n const relPos = vec3.create();\n\n vec3.copy(relPos, position);\n vec3.transformMat4(relPos, relPos, camera.viewMatrix);\n vec3.transformMat4(relPos, relPos, camera.projectionMatrix);\n\n if (relPos[2] > 1 || relPos[2] < 0) {\n hotspot.element.classList.remove(DEFAULT_CLASS.HOTSPOT_VISIBLE);\n return;\n }\n\n const screenPos = vec2.fromValues(\n relPos[0] * halfWidth + halfWidth,\n -relPos[1] * halfHeight + halfHeight\n );\n\n hotspot.element.classList.add(DEFAULT_CLASS.HOTSPOT_VISIBLE);\n hotspot.element.style.transform = [\n centerTransform,\n `translate(${screenPos[0]}px, ${screenPos[1]}px)`,\n zoomTransform\n ].join(\" \");\n });\n }\n\n private _parseHotspot(element: HTMLElement): Hotspot {\n const yawStr = element.dataset.yaw;\n const pitchStr = element.dataset.pitch;\n const positionStr = element.dataset.position;\n\n if (yawStr || pitchStr) {\n const yaw = yawStr ? parseFloat(yawStr) : 0;\n const pitch = pitchStr ? parseFloat(pitchStr) : 0;\n\n const position = this._yawPitchToVec3(yaw, pitch);\n\n return new Hotspot(element, position);\n } else if (positionStr) {\n const pos: number[] = positionStr.split(\" \").map(val => parseFloat(val));\n if (pos.length < 3) {\n throw new View360Error(ERROR.MESSAGES.INSUFFICIENT_ARGS(positionStr, \"hotspot attribute \\\"data-position\\\"\"), ERROR.CODES.INSUFFICIENT_ARGS);\n }\n\n return new Hotspot(element, vec3.fromValues(pos[0], pos[1], pos[2]));\n } else {\n // Place hotspot at yaw: 0, pitch: 0\n const defaultPos = vec3.fromValues(0, 0, -1);\n\n return new Hotspot(element, defaultPos);\n }\n }\n\n private _yawPitchToVec3(yaw: number, pitch: number) {\n const yawRad = yaw * DEG_TO_RAD;\n const pitchRad = pitch * DEG_TO_RAD;\n const position = vec3.create();\n\n position[1] = Math.sin(pitchRad);\n position[2] = Math.cos(pitchRad);\n\n position[0] = position[2] * Math.sin(-yawRad);\n position[2] = -position[2] * Math.cos(-yawRad);\n\n return position;\n }\n}\n\nexport default HotspotRenderer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"../geometry/Geometry\";\nimport { VAO } from \"../type/internal\";\n\n/**\n * @hidden\n */\nclass VertexArrayObject {\n public readonly obj: VAO | null;\n public readonly geometry: Geometry;\n public readonly buffers: {\n indicies: WebGLBuffer;\n position: WebGLBuffer;\n uv: WebGLBuffer;\n }\n\n public get count() { return this.geometry.indicies.count; }\n\n constructor(obj: VAO | null, geometry: Geometry, buffers: VertexArrayObject[\"buffers\"]) {\n this.obj = obj;\n this.geometry = geometry;\n this.buffers = buffers;\n }\n}\n\nexport default VertexArrayObject;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4 } from \"gl-matrix\";\nimport Uniform from \"../uniform/Uniform\";\nimport Camera from \"./Camera\";\nimport Object3D from \"./Object3D\";\nimport ShaderProgram from \"./ShaderProgram\";\nimport View360Error from \"./View360Error\";\nimport VertexArrayObject from \"./VertexArrayObject\";\nimport VertexData from \"./VertexData\";\nimport Texture from \"../texture/Texture\";\nimport Geometry from \"../geometry/Geometry\";\nimport * as BROWSER from \"../const/browser\";\nimport ERROR from \"../const/error\";\nimport { DEFAULT_CLASS } from \"../const/external\";\nimport { UniformLocations } from \"../type/internal\";\n\n/**\n * @hidden\n */\nclass WebGLContext {\n private _canvas: HTMLCanvasElement;\n private _gl: WebGLRenderingContext | WebGL2RenderingContext;\n private _contextLost: boolean;\n private _maxTextureSize: number;\n private _isWebGL2: boolean;\n private _debug: boolean;\n private _extensions: {\n vao: OES_vertex_array_object | null;\n loseContext: WEBGL_lose_context | null;\n };\n\n public get canvas() { return this._canvas; }\n public get maxTextureSize() { return this._maxTextureSize; }\n public get isWebGL2() { return this._isWebGL2; }\n public get supportVAO() { return this._isWebGL2 || !!this._extensions.vao; }\n public get lost() { return this._contextLost; }\n public get debug() { return this._debug; }\n\n public constructor(canvas: HTMLCanvasElement, debug: boolean) {\n this._canvas = canvas;\n this._contextLost = false;\n this._debug = debug;\n this._extensions = {\n vao: null,\n loseContext: null\n };\n }\n\n public init() {\n const canvas = this._canvas;\n\n const { gl, isWebGL2 } = this._getContext(canvas);\n\n this._gl = gl;\n this._maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n this._isWebGL2 = isWebGL2;\n\n if (!this._isWebGL2) {\n this._extensions.vao = gl.getExtension(\"OES_vertex_array_object\");\n }\n\n this._extensions.loseContext = gl.getExtension(\"WEBGL_lose_context\");\n\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_LOST, this._onContextLost);\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_RESTORED, this._onContextRestore);\n\n // gl.enable(gl.DEPTH_TEST);\n }\n\n public destroy() {\n const gl = this._gl;\n const canvas = this._canvas;\n\n if (gl) {\n // gl is not defined when destroy is called before init\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n }\n\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_LOST, this._onContextLost);\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_RESTORED, this._onContextRestore);\n }\n\n public forceLoseContext() {\n const extension = this._extensions.loseContext;\n\n if (!extension) return;\n\n extension.loseContext();\n }\n\n public forceRestoreContext() {\n const extension = this._extensions.loseContext;\n\n if (!extension) return;\n\n extension.restoreContext();\n }\n\n public clear() {\n const gl = this._gl;\n\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n\n public resize() {\n const gl = this._gl;\n\n gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n }\n\n public viewport(x: number, y: number, width: number, height: number) {\n const gl = this._gl;\n\n gl.viewport(x, y, width, height);\n }\n\n public createVAO(geometry: Geometry, shaderProgram: ShaderProgram) {\n const nativeVAO = this._createNativeVAO();\n\n const vao = new VertexArrayObject(nativeVAO, geometry, {\n indicies: this._createBuffer(),\n position: this._createBuffer(),\n uv: this._createBuffer()\n });\n\n if (nativeVAO) {\n this._bindNativeVAO(nativeVAO);\n this._supplyGeometryData(vao, shaderProgram);\n this._bindNativeVAO(null);\n this._unbindBuffers();\n }\n\n return vao;\n }\n\n public draw(vao: VertexArrayObject, shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n if (vao.obj) {\n this._bindNativeVAO(vao.obj);\n } else {\n this._supplyGeometryData(vao, shaderProgram);\n }\n\n gl.drawElements(gl.TRIANGLES, vao.count, gl.UNSIGNED_SHORT, 0);\n\n if (vao.obj) {\n this._bindNativeVAO(null);\n } else {\n this._unbindBuffers();\n }\n }\n\n public releaseVAO(vao: VertexArrayObject) {\n if (vao.obj) {\n this._deleteNativeVAO(vao.obj);\n }\n\n this._deleteBuffer(vao.buffers.indicies);\n this._deleteBuffer(vao.buffers.position);\n this._deleteBuffer(vao.buffers.uv);\n }\n\n public getUniformLocations>(program: WebGLProgram, uniforms: T): UniformLocations {\n const gl = this._gl;\n\n const uniformLocations = Object.keys(uniforms).reduce((locations, key) => {\n locations[key as keyof T] = gl.getUniformLocation(program, key)!;\n\n return locations;\n }, {} as UniformLocations);\n\n return {\n ...this._getCommonUniformLocations(program),\n ...uniformLocations\n };\n }\n\n public updateCommonUniforms(entity: Object3D, camera: Camera, shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniformLocations = shaderProgram.uniformLocations;\n\n // We're using \"matrix\"(=local matrix) here for efficiency\n // As projection doesn't require world matrix, as it doesn't have any parent or child\n const matrix = entity.matrix;\n const mvMatrix = mat4.create();\n mat4.multiply(mvMatrix, camera.viewMatrix, matrix);\n\n gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix);\n gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, camera.projectionMatrix);\n }\n\n public updateVRUniforms(shaderProgram: ShaderProgram, mvMatrix: mat4, pMatrix: mat4, eyeIndex: number) {\n const gl = this._gl;\n\n const uniformLocations = shaderProgram.uniformLocations;\n\n gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix);\n gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, pMatrix);\n\n if (uniformLocations.uEye) {\n gl.uniform1f(uniformLocations.uEye, eyeIndex);\n }\n }\n\n public updateUniforms(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniforms = shaderProgram.uniforms;\n const uniformLocations = shaderProgram.uniformLocations;\n\n for (const key in uniforms) {\n const uniform = uniforms[key];\n const location = uniformLocations[key];\n\n if (!uniform) continue;\n\n if (uniform.needsUpdate) {\n uniform.update(gl, location, this._isWebGL2);\n }\n }\n }\n\n public releaseShaderResources(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniforms = shaderProgram.uniforms;\n\n for (const key in uniforms) {\n const uniform = uniforms[key];\n\n if (!uniform) continue;\n\n if (uniform.needsUpdate) {\n uniform.destroy(gl);\n }\n }\n\n gl.deleteProgram(shaderProgram.program);\n }\n\n public useProgram(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n gl.useProgram(shaderProgram.program);\n }\n\n public createProgram(vertexShader: string, fragmentShader: string) {\n const gl = this._gl;\n const program = gl.createProgram()!;\n\n const vs = this._compileShader(gl.VERTEX_SHADER, vertexShader);\n const fs = this._compileShader(gl.FRAGMENT_SHADER, fragmentShader);\n\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.bindAttribLocation(program, 0, \"position\");\n gl.bindAttribLocation(program, 1, \"uv\");\n gl.linkProgram(program);\n\n if (this._debug && !gl.getProgramParameter(program, gl.LINK_STATUS)) {\n let shaderLog: string | null = null;\n\n if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {\n shaderLog = gl.getShaderInfoLog(vs);\n } else if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {\n shaderLog = gl.getShaderInfoLog(fs);\n }\n\n throw new View360Error(ERROR.MESSAGES.FAILED_LINKING_PROGRAM(gl.getProgramInfoLog(program), shaderLog), ERROR.CODES.FAILED_LINKING_PROGRAM);\n }\n\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n\n return program;\n }\n\n public createWebGLTexture(texData: Texture): WebGLTexture {\n const gl = this._gl;\n const texture = gl.createTexture()!;\n\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texData.wrapS);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texData.wrapT);\n\n if (!texData.isVideo() && this._isWebGL2) {\n const gl2 = gl as WebGL2RenderingContext;\n\n gl2.texStorage2D(gl2.TEXTURE_2D, 1, gl2.RGBA8, texData.width, texData.height);\n }\n\n return texture;\n }\n\n public createWebGLCubeTexture(texData: Texture, size: number): WebGLTexture {\n const gl = this._gl;\n const texture = gl.createTexture()!;\n\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, texData.wrapS);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, texData.wrapT);\n\n if (this._isWebGL2) {\n const gl2 = gl as WebGL2RenderingContext;\n\n gl2.texStorage2D(gl2.TEXTURE_CUBE_MAP, 1, gl2.RGBA8, size, size);\n }\n\n return texture;\n }\n\n public async makeXRCompatible() {\n const gl = this._gl;\n const attributes = gl.getContextAttributes();\n\n if (attributes && attributes.xrCompatible !== true) {\n await gl.makeXRCompatible();\n }\n }\n\n public bindXRLayer(session: XRSession) {\n const gl = this._gl;\n const xrLayer = new XRWebGLLayer(session, gl);\n session.updateRenderState({ baseLayer: xrLayer });\n }\n\n public bindXRFrame(frame: XRFrame) {\n const gl = this._gl;\n const session = frame.session;\n const baseLayer = session.renderState.baseLayer!;\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer);\n }\n\n public useDefaultFrameBuffer() {\n const gl = this._gl;\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n private _createBuffer(): WebGLBuffer {\n return this._gl.createBuffer()!;\n }\n\n private _deleteBuffer(buffer: WebGLBuffer) {\n return this._gl.deleteBuffer(buffer);\n }\n\n private _createNativeVAO() {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n return (gl as WebGL2RenderingContext).createVertexArray()!;\n } else {\n const ext = this._extensions.vao;\n\n return ext?.createVertexArrayOES() || null;\n }\n }\n\n private _bindNativeVAO(vao: WebGLVertexArrayObject | null) {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n (gl as WebGL2RenderingContext).bindVertexArray(vao);\n } else {\n const ext = this._extensions.vao;\n\n ext?.bindVertexArrayOES(vao);\n }\n }\n\n private _deleteNativeVAO(vao: WebGLVertexArrayObject | null) {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n (gl as WebGL2RenderingContext).deleteVertexArray(vao);\n } else {\n const ext = this._extensions.vao;\n\n ext?.deleteVertexArrayOES(vao);\n }\n }\n\n private _supplyGeometryData(vao: VertexArrayObject, shaderProgram: ShaderProgram) {\n const geometry = vao.geometry;\n\n this._supplyIndiciesData(geometry.indicies, vao.buffers.indicies);\n this._supplyAttributeData(geometry.vertices, shaderProgram.program, \"position\", vao.buffers.position);\n this._supplyAttributeData(geometry.uvs, shaderProgram.program, \"uv\", vao.buffers.uv);\n }\n\n private _unbindBuffers() {\n const gl = this._gl;\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n }\n\n private _supplyIndiciesData(indicies: VertexData, buffer: WebGLBuffer) {\n const gl = this._gl;\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicies.data, gl.STATIC_DRAW);\n }\n\n private _supplyAttributeData(attribute: VertexData, program: WebGLProgram, name: string, buffer: WebGLBuffer) {\n const gl = this._gl;\n const attribLocation = gl.getAttribLocation(program, name);\n\n // Attribute not used\n if (attribLocation < 0) return;\n\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ARRAY_BUFFER, attribute.data, gl.STATIC_DRAW);\n gl.vertexAttribPointer(attribLocation, attribute.itemSize, gl.FLOAT, false, 0, 0);\n gl.enableVertexAttribArray(attribLocation);\n }\n\n private _compileShader(type: number, src: string) {\n const gl = this._gl;\n const shader = gl.createShader(type)!;\n\n gl.shaderSource(shader, src);\n gl.compileShader(shader);\n\n return shader;\n }\n\n private _getCommonUniformLocations(program: WebGLProgram) {\n const gl = this._gl;\n\n return {\n uMVMatrix: gl.getUniformLocation(program, \"uMVMatrix\")!,\n uPMatrix: gl.getUniformLocation(program, \"uPMatrix\")!\n };\n }\n\n private _getContext(canvas: HTMLCanvasElement): {\n gl: WebGLRenderingContext | WebGL2RenderingContext;\n isWebGL2: boolean;\n } {\n const webglIdentifiers = [\"webgl2\", \"webgl\", \"experimental-webgl\", \"webkit-3d\", \"moz-webgl\"];\n let context: WebGLRenderingContext | null = null;\n let isWebGL2 = false;\n const contextAttributes = {\n preserveDrawingBuffer: false,\n antialias: false\n };\n\n const onWebglContextCreationError = e => e.statusMessage;\n\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_CREATE_ERROR, onWebglContextCreationError);\n\n for (const identifier of webglIdentifiers) {\n try {\n context = canvas.getContext(identifier, contextAttributes) as WebGLRenderingContext;\n isWebGL2 = identifier === \"webgl2\";\n } catch (t) {} // eslint-disable-line no-empty\n if (context) {\n break;\n }\n }\n\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_CREATE_ERROR, onWebglContextCreationError);\n\n if (!context) {\n throw new View360Error(ERROR.MESSAGES.WEBGL_NOT_SUPPORTED, ERROR.CODES.WEBGL_NOT_SUPPORTED);\n }\n\n return {\n gl: context,\n isWebGL2\n };\n }\n\n private _onContextLost = () => {\n const canvas = this._canvas;\n canvas.classList.add(DEFAULT_CLASS.CTX_LOST);\n this._contextLost = true;\n };\n\n private _onContextRestore = () => {\n const canvas = this._canvas;\n canvas.classList.remove(DEFAULT_CLASS.CTX_LOST);\n this._contextLost = false;\n };\n}\n\nexport default WebGLContext;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4 } from \"gl-matrix\";\nimport Camera from \"./Camera\";\nimport Projection from \"../projection/Projection\";\nimport WebGLContext from \"./WebGLContext\";\nimport XRManager from \"./XRManager\";\n\n/**\n * Projection renderer, based on WebGL\n * @ko WebGL 기반의 프로젝션 렌더러\n * @since 4.0.0\n */\nclass WebGLRenderer {\n private _canvas: HTMLCanvasElement;\n private _elementSize: { x: number, y: number };\n private _pixelRatio: number;\n\n public readonly ctx: WebGLContext;\n\n /**\n * Canvas element\n * @ko 캔버스 엘리먼트\n * @since 4.0.0\n */\n public get canvas() { return this._canvas; }\n /**\n * Canvas's width (`devicePixelRatio` is not applied)\n * @ko 캔버스의 보이는 너비 (`devicePixelRatio`가 적용되지 않은)\n * @since 4.0.0\n */\n public get width() { return this._elementSize.x; }\n /**\n * Canvas's height (`devicePixelRatio` is not applied)\n * @ko 캔버스의 높이 (`devicePixelRatio`가 적용되지 않은)\n * @since 4.0.0\n */\n public get height() { return this._elementSize.y; }\n /**\n * Current `devicePixelRatio` value.\n * @ko 현재 `devicePixelRatio` 값.\n * @since 4.0.0\n * @example\n * ```js\n * cosnt renderingWidth = view360.renderer.width * view360.renderer.pixelRatio;\n * ```\n */\n public get pixelRatio() { return this._pixelRatio; }\n /**\n * Width / height ratio (= width / height)\n * @ko 너비 / 높이의 비율 (= width / height)\n * @since 4.0.0\n * @example\n * ```js\n * const aspect = view360.renderer.width / view360.renderer.pixelRatio;\n * assert(aspect === view360.renderer.aspect);\n * ```\n */\n public get aspect() { return this._elementSize.x / this._elementSize.y; }\n\n /**\n * Create new instance\n * @ko 새 인스턴스를 생성합니다.\n * @param canvas - Canvas element {@ko 캔버스 엘리먼트}\n * @param debug - Whether to enable WebGL debugging {@ko WebGL debug 활성화 여부 }\n */\n public constructor(canvas: HTMLCanvasElement, debug: boolean) {\n this._canvas = canvas;\n this._elementSize = { x: 0, y: 0 };\n this._pixelRatio = 1;\n this.ctx = new WebGLContext(canvas, debug);\n }\n\n /**\n * Destroy instance and release all resources.\n * @ko 인스턴스를 제거하고 사용된 리소스를 전부 해제합니다.\n * @since 4.0.0\n */\n public destroy() {\n const canvas = this._canvas;\n\n this.ctx.destroy();\n canvas.width = 1;\n canvas.height = 1;\n }\n\n /**\n * Resize canvas and renew inner size cache.\n * @ko 캔버스의 크기를 재계산해서 내부의 사이즈 캐시값을 갱신합니다.\n * @since 4.0.0\n */\n public resize() {\n const canvas = this._canvas;\n const canvasSize = this._elementSize;\n const devicePixelRatio = window.devicePixelRatio;\n\n canvasSize.x = canvas.clientWidth;\n canvasSize.y = canvas.clientHeight;\n\n canvas.width = canvasSize.x * devicePixelRatio;\n canvas.height = canvasSize.y * devicePixelRatio;\n\n this._pixelRatio = devicePixelRatio;\n this.ctx.resize();\n }\n\n /**\n * Render projection\n * @ko 프로젝션을 렌더링합니다.\n * @param projection - Projection to render {@ko 렌더링할 프로젝션}\n * @param cameraa - Camera instance {@ko 카메라의 인스턴스}\n * @since 4.0.0\n */\n public render(projection: Projection, camera: Camera) {\n const ctx = this.ctx;\n const mesh = projection.getMesh();\n if (ctx.lost || !mesh) return;\n\n ctx.clear();\n ctx.useProgram(mesh.program);\n ctx.updateCommonUniforms(mesh, camera, mesh.program);\n projection.update(camera);\n ctx.updateUniforms(mesh.program);\n ctx.draw(mesh.vao, mesh.program);\n }\n\n /**\n * Render VR frame, only used for rendering frames inside VR sessions.\n * @ko VR 프레임을 렌더링합니다. VR 세션 진입 도중에만 사용됩니다.\n * @internal\n * @param projection - Projection to render {@ko 렌더링할 프로젝션}\n * @param vr - Instance of XRManager {@ko XRManager의 인스턴스}\n * @param frame - VR frame {@ko VR 프레임}\n * @since 4.0.0\n */\n public renderVR(projection: Projection, vr: XRManager, frame: XRFrame) {\n const ctx = this.ctx;\n const mesh = projection.getMesh();\n const eyeParams = vr.getEyeParams(frame);\n\n if (!eyeParams || !mesh) return;\n\n ctx.bindXRFrame(frame);\n ctx.useProgram(mesh.program);\n ctx.updateUniforms(mesh.program);\n\n eyeParams.forEach((eye, eyeIndex) => {\n const viewport = eye.viewport;\n // We're using \"mesh.matrix\"(=local matrix) here for efficiency\n // As projection doesn't require world matrix, as it doesn't have any parent or child\n const mvMatrix = mat4.multiply(mat4.create(), eye.vMatrix, mesh.matrix);\n\n ctx.viewport(viewport.x, viewport.y, viewport.width, viewport.height);\n ctx.updateVRUniforms(mesh.program, mvMatrix, eye.pMatrix, eyeIndex);\n ctx.draw(mesh.vao, mesh.program);\n });\n }\n}\n\nexport default WebGLRenderer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport Camera, { CameraOptions } from \"./core/Camera\";\nimport PanoControl, { PanoControlOptions } from \"./control/PanoControl\";\nimport TextureLoader from \"./core/TextureLoader\";\nimport FrameAnimator from \"./core/FrameAnimator\";\nimport AutoResizer from \"./core/AutoResizer\";\nimport Autoplay, { AutoplayOptions } from \"./core/Autoplay\";\nimport XRManager from \"./core/XRManager\";\nimport View360Error from \"./core/View360Error\";\nimport Projection from \"./projection/Projection\";\nimport HotspotRenderer, { HotspotOptions } from \"./hotspot/HotspotRenderer\";\nimport WebGLRenderer from \"./core/WebGLRenderer\";\nimport Texture from \"./texture/Texture\";\nimport View360Plugin from \"./plugin/View360Plugin\";\nimport ERROR from \"./const/error\";\nimport { CONTROL_EVENTS } from \"./const/internal\";\nimport { DEFAULT_CLASS, EVENTS } from \"./const/external\";\nimport { findCanvas, getElement } from \"./utils\";\nimport * as EVENT_TYPES from \"./type/events\";\nimport { EventParams } from \"./type/utils\";\n\n/**\n * Events that {@link View360} can trigger\n * @ko {@link View360}가 트리거할 수 있는 이벤트들\n * @see [Detailed Example](/docs/events/ready)\n * @since 4.0.0\n */\nexport interface View360Events {\n [EVENTS.READY]: EVENT_TYPES.ReadyEvent;\n [EVENTS.LOAD_START]: EVENT_TYPES.LoadStartEvent;\n [EVENTS.LOAD]: EVENT_TYPES.LoadEvent;\n [EVENTS.PROJECTION_CHANGE]: EVENT_TYPES.ProjectionChangeEvent;\n [EVENTS.RESIZE]: EVENT_TYPES.ResizeEvent;\n [EVENTS.BEFORE_RENDER]: EVENT_TYPES.BeforeRenderEvent;\n [EVENTS.RENDER]: EVENT_TYPES.RenderEvent;\n [EVENTS.INPUT_START]: EVENT_TYPES.InputStartEvent;\n [EVENTS.INPUT_END]: EVENT_TYPES.InputEndEvent;\n [EVENTS.VIEW_CHANGE]: EVENT_TYPES.ViewChangeEvent;\n [EVENTS.STATIC_CLICK]: EVENT_TYPES.StaticClickEvent;\n [EVENTS.VR_START]: EVENT_TYPES.VRStartEvent;\n [EVENTS.VR_END]: EVENT_TYPES.VREndEvent;\n}\n\n/**\n * Options for {@link View360}\n * @ko {@link View360}용 옵션들\n * @see [Detailed Example](/docs/options)\n * @since 4.0.0\n */\nexport interface View360Options extends CameraOptions, PanoControlOptions {\n projection: Projection | null;\n hotspot: Partial;\n autoplay: boolean | Partial;\n autoInit: boolean;\n autoResize: boolean;\n canvasSelector: string;\n useResizeObserver: boolean;\n tabIndex: number | null;\n on: Partial<{ [key in keyof View360Events]: (evt: View360Events[key]) => any }>;\n plugins: View360Plugin[];\n maxDeltaTime: number;\n debug: boolean;\n}\n\n/**\n * Panorama 360 image viewer\n * @ko 파노라마 360 이미지 뷰어\n * @since 4.0.0\n * @see View360Options\n * @see View360Events\n */\nclass View360 extends Component {\n /**\n * Current version string of the View360\n * @ko View360의 현재 버젼 문자열\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // If the installed version of the View360 is v4.0.0, View360.VERSION is equal to \"4.0.0\"\n * console.log(View360.VERSION) // 4.0.0\n * ```\n */\n public static readonly VERSION = \"#__VERSION__#\";\n\n private _rootEl: HTMLElement;\n private _renderer: WebGLRenderer;\n private _camera: Camera;\n private _control: PanoControl;\n private _animator: FrameAnimator;\n private _autoplay: Autoplay;\n private _hotspot: HotspotRenderer;\n private _projection: Projection | null;\n private _autoResizer: AutoResizer;\n private _vr: XRManager;\n private _plugins: View360Plugin[];\n private _initialized: boolean;\n\n private _autoInit: View360Options[\"autoInit\"];\n private _autoResize: View360Options[\"autoResize\"];\n private _canvasSelector: View360Options[\"canvasSelector\"];\n private _useResizeObserver: View360Options[\"useResizeObserver\"];\n private _tabIndex: View360Options[\"tabIndex\"];\n private _debug: View360Options[\"debug\"];\n\n /**\n * Root element (`.view360-container`)\n * @ko 루트 엘리먼트 (`.view360-container`)\n * @since 4.0.0\n * @readonly\n * @example\n * ```html\n *
\n * \n *
\n * ```\n * ```ts\n * import View360 from \"@egjs/view360\";\n *\n * const viewer = new View360(\"#viewer\");\n * console.log(viewer.rootEl); // Element with id \"viewer\"\n * ```\n */\n public get rootEl() { return this._rootEl; }\n /**\n * Projection renderer.\n * @ko 프로젝션 렌더러.\n * @since 4.0.0\n * @readonly\n */\n public get renderer() { return this._renderer; }\n /**\n * Projection camera.\n * @ko 프로젝션 카메라.\n * @since 4.0.0\n * @readonly\n */\n public get camera() { return this._camera; }\n /**\n * Rotate/Zoom Controller.\n * @ko 회전/줌 컨트롤러.\n * @since 4.0.0\n * @readonly\n */\n public get control() { return this._control; }\n /**\n * WebXR-based VR manager.\n * @ko WebXR 기반의 VR 기능 매니저 인스턴스.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // Example: Enter VR\n * // This must be called on user interaction, else will be rejected.\n * viewer.vr.enter();\n * ```\n */\n public get vr() { return this._vr; }\n /**\n * Hotspot renderer.\n * You can also change options of {@link View360Options#hotspot} with this.\n * @ko 핫스팟 렌더러 인스턴스.\n * {@link View360Options#hotspot} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get hotspot() { return this._hotspot; }\n /**\n * An array of plugins added.\n * @ko 추가된 플러그인의 배열\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * plugins: [new ControlBar()]\n * });\n *\n * console.log(viewer.plugins); // [ControlBar]\n *\n * viewer.addPlugins(new LoadingSpinner()) // [ControlBar, LoadingSpinner];\n * ```\n */\n public get plugins() { return this._plugins; }\n /**\n * A instance of {@link Projection} that currently enabled. `null` if not initialized yet.\n * You should call {@link View360#load} to change panorama src or projection type.\n * @ko 현재 사용중인 {@link Projection}의 인스턴스. 프로젝션을 활성화하지 않았을 경우 `null`입니다.\n * 파노라마 이미지 소스나 프로젝션 타입을 변경하려면 {@link View360#load}를 호출하면 됩니다.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360\n * ```\n */\n public get projection() { return this._projection; }\n public set projection(val: View360Options[\"projection\"]) {\n if (this._initialized && val) {\n this.load(val);\n } else {\n this._projection = val;\n }\n }\n /**\n * A boolean value whether {@link View360#init init()} is called before.\n * @ko {@link View360#init init()}이 호출되었는지 여부를 가리키는 값\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360(\"#el\", { autoInit: false });\n *\n * console.log(viewer.initialized); // false\n *\n * await viewer.init();\n *\n * console.log(viewer.initialized); // true\n * ```\n */\n public get initialized() { return this._initialized; }\n /**\n * Instance of the Autoplay manager.\n * You can also change {@link View360Options#autoplay} options with this.\n * @ko Autoplay 기능의 매니저 인스턴스.\n * 이 인스턴스를 통해 {@link View360Options#autoplay} 옵션을 변경하는 것도 가능합니다.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // Disable autoplay\n * viewer.autoplay.disable();\n * ```\n */\n public get autoplay() { return this._autoplay; }\n /**\n * When this value is `true` and {@link View360Options#projection} is set, {@link View360#init init()} will be called automatically when instance is created.\n * @ko 이 값이 `true`이고, {@link View360Options#projection}이 설정되었으면, 인스턴스 생성 시점에 자동으로 {@link View360#init init()}을 호출합니다.\n * @default true\n * @since 4.0.0\n * @example\n * ```ts\n * import View360, { EquirectProjection, EVENTS } from \"@egjs/view360\";\n *\n * // viewer.init() is called on instance creation\n * // But as `init` is asynchronous, you should wait for \"ready\" event if you want to do something after initialization.\n * const viewer = new View360(\"#el_id\", {\n * autoInit: true,\n * projection: new EquirectProjection({ src: \"SRC_TO_URL\" })\n * });\n *\n * console.log(viewer.initialized); // false, as `init` is asynchronous\n *\n * viewer.once(EVENTS.READY, () => {\n * console.log(viewer.initialized); // true\n * });\n * ```\n */\n public get autoInit() { return this._autoInit; }\n /**\n * When `true`, {@link View360#resize} is called when the canvas size is changed.\n * @ko `true`일 경우, 캔버스의 크기가 변경되었을 때 자동으로 {@link View360#resize}를 호출합니다.\n * @default true\n * @since 4.0.0\n * @see View360#useResizeObserver\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * autoResize: true\n * });\n *\n * // This can trigger `viewer.resize()` if the canvas size was not 400px\n * const canvas = viewer.renderer.canvas;\n * canvas.style.width = \"400px\";\n * ```\n */\n public get autoResize() { return this._autoResize; }\n /**\n * CSS selector for canvas element to render panorama image/video.\n * The canvas element should be placed inside the root element. (Dont' have to be direct child)\n * @ko 파노라마 이미지/비디오를 렌더링할 canvas 엘리먼트의 CSS 선택자\n * 캔버스 엘리먼트는 루트 엘리먼트 내부에 있어야합니다. 루트 엘리먼트의 직계 자식 엘리먼트(Direct child element)일 필요는 없습니다.\n * @default \"canvas\"\n * @since 4.0.0\n * @example\n * ```html\n *
\n * \n * \n * \n *
\n * ```\n *\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * canvasSelector: \"#canvas_to_select\"\n * });\n * ```\n */\n public get canvasSelector() { return this._canvasSelector; }\n /**\n * When `true`, it will use {@link ResizeObserver} API to detect canvas size change when {@link View360Options#autoResize} is enabled.\n * @ko `true`일 때 {@link View360Options#autoResize}가 활성화되었으면, 사용 가능한 환경에서 {@link ResizeObserver} API를 사용해서 캔버스 크기 변화를 추적합니다.\n * @default true\n * @since 4.0.0\n */\n public get useResizeObserver() { return this._useResizeObserver; }\n /**\n * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} attribute for the canvas element.\n * This is necessary for the keyboard controls.\n * By default, `0` will be assigned. `null` to disable.\n * @ko 캔버스 엘리먼트에 적용할 {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} 어트리뷰트의 값.\n * 이 값을 설정해야만 키보드 컨트롤을 사용 가능합니다.\n * 기본값으로 `0`이 설정됩니다. `null`로 지정하면 `tabindex`를 설정하지 않습니다.\n * @see RotateControlOptions#disableKeyboard\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * tabindex: 5\n * });\n * ```\n *\n * ```html\n * \n *
\n * \n *
\n * ```\n */\n public get tabIndex() { return this._tabIndex; }\n public set tabIndex(val: View360Options[\"tabIndex\"]) {\n const canvas = this._renderer.canvas;\n this._tabIndex = val;\n\n if (val != null) {\n canvas.tabIndex = val;\n } else {\n canvas.removeAttribute(\"tabindex\");\n }\n }\n /**\n * A maximum delta time between frames in seconds.\n * It can prevent camera or control changing too fast when frame being late.\n * @ko 프레임간 시간 차이의 최대값. (초 단위)\n * 퍼포먼스 등의 이유로 프레임 렌더링이 늦어졌을 때, 화면이 갑작스럽게 바뀌는 것을 막아줍니다.\n * @default 1 / 30\n * @since 4.0.0\n */\n public get maxDeltaTime() { return this._animator.maxDeltaTime; }\n public set maxDeltaTime(val: View360Options[\"maxDeltaTime\"]) { this._animator.maxDeltaTime = val; }\n /**\n * Enable WebGL debugging. Setting this to `true` can decrease performance.\n * This is used internally on developing View360.\n * @ko WebGL 디버깅을 활성화합니다. 이 값을 `true`로 할 경우 성능이 하락할 수 있습니다.\n * 이 옵션은 View360을 개발하기 위해 내부적으로 사용됩니다.\n * @default false\n */\n public get debug() { return this._debug; }\n public set debug(val: View360Options[\"debug\"]) { this._debug = val; }\n\n // Camera options\n /**\n * Initial yaw (y-axis rotation) value for camera. (in degrees, °)\n * As View360 uses right-handed coordinate system internally, camera will rotate counter-clockwise by this value.\n * @ko 카메라의 초기 yaw(y축 회전)값 (도 단위, °)\n * View360은 오른손 좌표계를 사용하기 때문에, 카메라가 해당 값만큼 시계 반대방향으로 회전합니다.\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialYaw: 30\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.yaw); // 30\n * });\n * ```\n */\n public get initialYaw() { return this._camera.initialYaw; }\n public set initialYaw(val: View360Options[\"initialYaw\"]) { this._camera.initialYaw = val; }\n /**\n * Initial pitch (x-axis rotation) value for camera. (in degrees, °)\n * As View360 uses right-handed coordinate system internally, positive value will make camera to look upside, while negative value will look down.\n * @ko 카메라의 초기 pitch(x축 회전)값 (도 단위, °)\n * View360은 오른손 좌표계를 사용하기 때문에, 양(+)의 값은 카메라가 위를 보게 하고, 음(-)의 값은 카메라가 아래를 보게 합니다.\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialPitch: 60\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.pitch); // 60\n * });\n * ```\n */\n public get initialPitch() { return this._camera.initialPitch; }\n public set initialPitch(val: View360Options[\"initialPitch\"]) { this._camera.initialPitch = val; }\n /**\n * Initial zoom value for camera.\n * Setting this value to `2` will enlarge panorama 200% by width.\n * @ko 카메라의 초기 줌 값.\n * 이 값을 `2`로 설정할 경우 파노라마 이미지를 가로 기준 200%만큼 확대합니다.\n * @default 1\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialZoom: 2\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.zoom); // 2\n * });\n * ```\n */\n public get initialZoom() { return this._camera.initialZoom; }\n public set initialZoom(val: View360Options[\"initialZoom\"]) { this._camera.initialZoom = val; }\n /**\n * Restrict yaw(y-axis rotation) range. (in degrees, °)\n * @ko yaw(y축 회전) 범위를 제한합니다. (도 단위, °)\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * yawRange: [-30, 30]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.yaw); // 0\n * viewer.camera.lookAt({ yaw: 60 });\n * console.log(viewer.camera.yaw); // 30\n * });\n * ```\n */\n public get yawRange() { return this._camera.yawRange; }\n public set yawRange(val: View360Options[\"yawRange\"]) {\n this._camera.yawRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Restrict pitch(x-axis rotation) range. (in degrees, °)\n * @ko pitch(x축 회전) 범위를 제한합니다. (도 단위, °)\n * @default null\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * pitchRange: [-45, 45]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.pitch); // 0\n * viewer.camera.lookAt({ pitch: 60 });\n * console.log(viewer.camera.pitch); // 45\n * });\n * ```\n */\n public get pitchRange() { return this._camera.pitchRange; }\n public set pitchRange(val: View360Options[\"pitchRange\"]) {\n this._camera.pitchRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Restrict camera zoom range.\n * If `null`, a default zoom range from `0.6` to `10` will be used.\n * @ko 카메라 줌 범위를 제한합니다.\n * `null`일 경우 기본값으로 `0.6`에서 `10`의 범위를 사용합니다.\n * @default null\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * zoomRange: [0.5, 4]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.zoom); // 1\n * viewer.camera.lookAt({ zoom: 6 });\n * console.log(viewer.camera.zoom); // 4\n * });\n * ```\n */\n public get zoomRange() { return this._camera.zoomRange; }\n public set zoomRange(val: View360Options[\"zoomRange\"]) {\n this._camera.zoomRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Camera's horizontal FOV(Field of View). (in degrees, °)\n * @ko 카메라의 수평 FOV(Field of View) 값. (도 단위, °)\n * @default 90\n * @since 4.0.0\n * @example\n * ```ts\n * // Init with fov: 120\n * const viewer = new View360(\"#el_id\", { fov: 120 });\n *\n * // Back to 90\n * viewer.fov = 90;\n * ```\n */\n public get fov() { return this._camera.fov; }\n public set fov(val: View360Options[\"fov\"]) {\n const camera = this._camera;\n const control = this._control;\n\n camera.fov = val;\n camera.updateMatrix();\n control.sync();\n }\n\n // Control options\n /**\n * A control for camera rotation.\n * You can also change options of {@link View360Options#rotate} with this.\n * @ko 카메라 회전을 담당하는 컨트롤.\n * {@link View360Options#rotate} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get rotate() { return this._control.rotate; }\n /**\n * A control for camera zoom.\n * You can also change options of {@link View360Options#zoom} with this.\n * @ko 카메라 줌을 담당하는 컨트롤.\n * {@link View360Options#zoom} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get zoom() { return this._control.zoom; }\n /**\n * A control for camera rotation with gyroscope input.\n * You can also change options of {@link View360Options#gyro} with this.\n * @ko 자이로스코프를 통한 카메라 회전을 담당하는 컨트롤.\n * {@link View360Options#gyro} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get gyro() { return this._control.gyro; }\n /**\n * Apply CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor} by current state of input when using mouse.\n * If `true`, this will add CSS style to canvas element. It'll apply `cursor: \"grab\"` by default and `cursor: \"grabbing\"` when holding the mouse button.\n * @ko 마우스 사용시 CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor}값을 자동으로 변경할지 여부.\n * `true`일 경우 기본 상태에서 `cursor: \"grab\"`을, 입력 도중에 `cursor: \"grabbing\"`을 캔버스에 적용합니다.\n * @default true\n * @since 4.0.0\n */\n public get useGrabCursor() { return this._control.useGrabCursor; }\n public set useGrabCursor(val: View360Options[\"useGrabCursor\"]) { this._control.useGrabCursor = val; }\n /**\n * Disable context menu which pops up on mouse right click.\n * @ko 마우스 우클릭시 표시되는 컨텍스트 메뉴를 비활성화합니다.\n * @default false\n * @since 4.0.0\n */\n public get disableContextMenu() { return this._control.disableContextMenu; }\n public set disableContextMenu(val: View360Options[\"disableContextMenu\"]) { this._control.disableContextMenu = val; }\n /**\n * If `true`, enables scroll on mobile(touch) devices on canvas.\n * :::caution\n * When this option is enabled, users must swipe horizontally first then vertically to change view up or down.\n * :::\n * @ko `true`로 설정할 경우, 모바일(터치) 환경의 캔버스 영역 내에서 스크롤을 가능하게 합니다.\n * :::caution\n * 이 값을 활성화할 경우, 사용자가 카메라 뷰를 위/아래로 바꾸기 위해서는 먼저 가로로 스와이프한 이후에 세로로 스와이프해야만 합니다.\n * :::\n * @since 4.0.0\n * @default true\n */\n public get scrollable() { return this._control.scrollable; }\n public set scrollable(val: View360Options[\"scrollable\"]) { this._control.scrollable = val; }\n /**\n * If `true`, enables scroll by mouse wheel on canvas.\n * :::caution\n * When this option is enabled, zoom by mouse wheel will be disabled.\n * :::\n * @ko `true`로 설정할 경우, 캔버스 영역 내에서 마우스 휠을 이용한 페이지 스크롤이 가능해집니다.\n * :::caution\n * 이 값을 활성화할 경우, 마우스 휠을 통한 줌이 불가능하게 됩니다.\n * :::\n * @since 4.0.0\n * @default false\n */\n public get wheelScrollable() { return this._control.wheelScrollable; }\n public set wheelScrollable(val: View360Options[\"wheelScrollable\"]) { this._control.wheelScrollable = val; }\n\n /**\n * Create new instance of View360\n * @ko View360의 새로운 인스턴스를 생성합니다\n * @param root - Root element(`.view360-container`) to mount View360\n * Can be either a CSS selector or HTMLElement.\n * {@ko View360을 마운트할 루트 엘리먼트, CSS 셀렉터나 HTMLElement를 지정 가능합니다.}\n * @param options - Options to apply\n * {@ko 적용할 옵션들}\n * @example\n * ```ts\n * import View360, { EquirectProjection } from \"@egjs/view360\";\n *\n * // Create new View360 instance\n * const viewer = new View360(\"#id-of-a-container\", {\n * projection: new EquirectProjection({\n * src: \"URL_TO_PANORAMA_IMAGE_OR_VIDEO\",\n * })\n * });\n * ```\n */\n public constructor(root: string | HTMLElement, {\n projection = null,\n initialYaw = 0,\n initialPitch = 0,\n initialZoom = 1,\n yawRange = null,\n pitchRange = null,\n zoomRange = null,\n fov = 90,\n useGrabCursor = true,\n disableContextMenu = false,\n rotate = true,\n zoom = true,\n gyro = false,\n scrollable = true,\n wheelScrollable = false,\n autoplay = false,\n hotspot = {},\n autoInit = true,\n autoResize = true,\n canvasSelector = \"canvas\",\n useResizeObserver = true,\n on = {},\n plugins = [],\n maxDeltaTime = 1 / 30,\n tabIndex = 0,\n debug = false\n }: Partial = {}) {\n super();\n\n this._rootEl = getElement(root);\n this._plugins = plugins;\n this._initialized = false;\n\n // Options\n this._autoInit = autoInit;\n this._autoResize = autoResize;\n this._canvasSelector = canvasSelector;\n this._useResizeObserver = useResizeObserver;\n this._tabIndex = tabIndex;\n this._debug = debug;\n\n // Core components\n const canvas = findCanvas(this._rootEl, canvasSelector);\n this._renderer = new WebGLRenderer(canvas, debug);\n this._camera = new Camera({\n initialYaw,\n initialPitch,\n initialZoom,\n fov,\n yawRange,\n pitchRange,\n zoomRange\n });\n this._control = new PanoControl(canvas, this._camera, {\n useGrabCursor,\n scrollable,\n wheelScrollable,\n disableContextMenu,\n rotate,\n zoom,\n gyro\n });\n this._animator = new FrameAnimator(maxDeltaTime);\n this._autoplay = new Autoplay(this, canvas, autoplay);\n this._projection = projection;\n this._autoResizer = new AutoResizer(useResizeObserver, () => this.resize());\n this._vr = new XRManager(this._renderer.ctx);\n this._hotspot = new HotspotRenderer(this._rootEl, this._renderer, hotspot);\n\n this._addEventHandlers(on);\n\n if (projection && autoInit) {\n this.init();\n }\n }\n\n /**\n * Destroy instance and release all resources.\n * @ko 인스턴스를 제거하고 모든 리소스를 해제합니다.\n * @since 4.0.0\n */\n public destroy() {\n this._camera.destroy();\n this._animator.stop();\n this._renderer.destroy();\n this._control.destroy();\n this._autoResizer.disable();\n\n if (this._projection) {\n this._projection.releaseAllResources(this._renderer.ctx);\n this._projection = null;\n }\n\n this._plugins.forEach(plugin => plugin.destroy(this));\n\n this._initialized = false;\n }\n\n /**\n * Initialize inner components and load projection src.\n * @ko 내부 컴포넌트들을 초기화하고 프로젝션 소스를 로드합니다.\n * @since 4.0.0\n */\n public async init() {\n if (!this._projection) {\n throw new View360Error(ERROR.MESSAGES.PROVIDE_PROJECTION_FIRST, ERROR.CODES.PROVIDE_PROJECTION_FIRST);\n }\n\n const renderer = this._renderer;\n const camera = this._camera;\n const control = this._control;\n const animator = this._animator;\n const hotspot = this._hotspot;\n const projection = this._projection;\n const canvas = renderer.canvas;\n\n this._bindComponentEvents();\n renderer.ctx.init();\n this._resizeComponents();\n camera.updateMatrix();\n\n if (this._autoResize) {\n this._autoResizer.enable(canvas);\n }\n\n if (!this._autoplay.enableBlocked) {\n this._autoplay.enable();\n }\n\n this._plugins.forEach(plugin => {\n plugin.init(this);\n });\n\n const texture = await this._loadTexture(projection);\n this._applyProjection(projection, texture, null);\n hotspot.refresh();\n animator.start(this._renderFrameOnDemand);\n await control.enable();\n\n if (this._tabIndex != null && !canvas.hasAttribute(\"tabIndex\")) {\n canvas.tabIndex = this._tabIndex;\n }\n\n this._initialized = true;\n this.renderFrame(0);\n\n this._emit(EVENTS.READY);\n }\n\n /**\n * Load new panorama image/video and display it.\n * This will {@link View360#init init()} View360 if it's not initialized yet.\n * @ko 새로운 파노라마 이미지 혹은 비디오를 로드하고 표시합니다.\n * 만약 View360이 아직 초기화되지 않았다면, {@link View360#init init()}을 호출합니다.\n * @param projection - Projection & video options for new source. {@ko 새로운 파노라마 이미지/비디오에 적용할 옵션들}\n * @returns `Promise` if load was successful. {@ko 프로젝션 로드에 성공했을 경우 `Promise`를 반환합니다. }\n * @since 4.0.0\n * @example\n * ```ts\n * // Change to video\n * viewer.load({\n * src: \"URL_TO_NEW_VIDEO\",\n * video: true\n * });\n * ```\n */\n public async load(projection: Projection): Promise {\n if (!projection) return false;\n\n if (this._initialized) {\n const texture = await this._loadTexture(projection);\n this._applyProjection(projection, texture, this._projection);\n this.renderFrame(0);\n } else {\n // Should update internal options before init\n this._projection = projection;\n this.init();\n }\n\n return true;\n }\n\n /**\n * Refresh component's size by current\n * @ko View360이 내부적으로 캐시하고 있는 엘리먼트 크기를 현재 크기로 갱신합니다.\n * @since 4.0.0\n */\n public resize() {\n if (!this._initialized) return;\n\n this._resizeComponents();\n\n // To prevent flickering, render immediately after resizing components\n this.renderFrame(0);\n\n const { width, height } = this._renderer;\n\n this._emit(EVENTS.RESIZE, {\n width,\n height\n });\n }\n\n /**\n * Add new plugins\n * @ko 새로운 플러그인을 추가합니다.\n * @param plugins Plugins to add {@ko 추가할 플러그인들}\n * @see View360Options#plugins\n * @since 4.0.0\n * @example\n * ```ts\n * // Add a single plugin\n * viewer.addPlugins(new ControlBar());\n *\n * // Add multiple plugins\n * viewer.addPlugins(new ControlBar(), new LoadingSpinner());\n * ```\n */\n public addPlugins(...plugins: View360Plugin[]) {\n if (this._initialized) {\n plugins.forEach(plugin => { plugin.init(this); });\n }\n\n this._plugins.push(...plugins);\n }\n\n /**\n * Remove plugins.\n * @ko 플러그인을 제거합니다.\n * @param plugins Plugins to remove {@ko 제거할 플러그인들}\n * @since 4.0.0\n * @example\n * ```ts\n * // Remove a single plugin\n * viewer.removePlugins(plugin1);\n *\n * // Remove multiple plugins\n * viewer.removePlugins(plugin2, plugin3);\n * ```\n */\n public removePlugins(...plugins: View360Plugin[]) {\n plugins.forEach(plugin => {\n const pluginIdx = this._plugins.indexOf(plugin);\n\n if (pluginIdx < 0) return;\n\n plugin.destroy(this);\n this._plugins.splice(pluginIdx, 1);\n });\n }\n\n /**\n * Render a single panorama image/video frame.\n * Rendering is performed automatically on demand, so you usually don't have to call this.\n * Call this when a frame is not renewed after changing options.\n * @ko 파노라마 이미지/비디오의 한 프레임을 렌더링합니다.\n * 프레임 갱신은 보통 필요한 때에만 자동적으로 이루어지기 때문에, 보통은 이 메소드를 호출할 필요는 없습니다.\n * 옵션 변경 이후에도 프레임 갱신이 이루어지지 않는다면, 이 메소드를 호출해주세요.\n * @param delta Delta time in milisec. {@ko 프레임간 시간 차이, 밀리초 단위}\n * @since 4.0.0\n */\n public renderFrame = (delta: number) => {\n const camera = this._camera;\n const renderer = this._renderer;\n const control = this._control;\n const hotspot = this._hotspot;\n const autoPlayer = this._autoplay;\n const projection = this._projection;\n\n if (!projection) return;\n\n this._emit(EVENTS.BEFORE_RENDER);\n\n if (autoPlayer.playing) {\n autoPlayer.update(delta);\n control.sync();\n }\n\n if (camera.animation) {\n camera.animation.update(delta);\n } else {\n control.update(delta);\n }\n\n renderer.render(projection, camera);\n hotspot.render(camera);\n\n if (camera.changed) {\n this._emit(EVENTS.VIEW_CHANGE, {\n yaw: camera.yaw,\n pitch: camera.pitch,\n zoom: camera.zoom,\n quaternion: [\n camera.quaternion[0],\n camera.quaternion[1],\n camera.quaternion[2],\n camera.quaternion[3]\n ]\n });\n }\n camera.onFrameRender();\n\n this._emit(EVENTS.RENDER);\n };\n\n private _emit(eventName: K, ...params: EventParams) {\n const evtParams = params ? params[0] : {};\n\n this.trigger(eventName as any, {\n type: eventName,\n target: this,\n ...evtParams\n });\n }\n\n private _renderFrameOnDemand = (delta: number) => {\n const camera = this._camera;\n const control = this._control;\n const autoplay = this._autoplay;\n const texture = this._projection?.getTexture();\n\n if (!this._initialized || !texture) return;\n if (\n !camera.animation\n && !control.animating\n && !autoplay.playing\n && !texture.isVideo()\n ) return;\n\n this.renderFrame(delta);\n };\n\n private _renderVRFrame = (_delta: number, frame: XRFrame) => {\n const vr = this._vr;\n const projection = this._projection;\n const renderer = this._renderer;\n\n if (!projection) return;\n\n this._emit(EVENTS.BEFORE_RENDER);\n\n renderer.renderVR(projection, vr, frame);\n\n this._emit(EVENTS.RENDER);\n }\n\n private _applyProjection(projection: Projection, texture: Texture, prevProjection: Projection | null) {\n const camera = this._camera;\n const control = this._control;\n const renderer = this._renderer;\n\n // Remove previous projection\n if (prevProjection) {\n prevProjection.releaseAllResources(this._renderer.ctx);\n }\n\n projection.applyTexture(renderer.ctx, texture);\n projection.updateCamera(camera);\n projection.updateControl(control);\n\n this._projection = projection;\n this._emit(EVENTS.PROJECTION_CHANGE, {\n projection\n });\n }\n\n private async _loadTexture(projection: Projection): Promise {\n const contentLoader = new TextureLoader();\n const { src, video } = projection;\n\n this._emit(EVENTS.LOAD_START, {\n src,\n video\n });\n\n const texture = await contentLoader.load(src, video);\n\n this._emit(EVENTS.LOAD, {\n src,\n video\n });\n\n return texture;\n }\n\n private _resizeComponents() {\n const renderer = this._renderer;\n const camera = this._camera;\n const control = this._control;\n\n renderer.resize();\n camera.resize(renderer.width, renderer.height);\n control.resize(renderer.width, renderer.height);\n }\n\n private _addEventHandlers(events: View360Options[\"on\"]) {\n // Bind option \"on\"\n Object.keys(events).forEach((evtName: keyof typeof EVENT_TYPES) => {\n this.on(evtName, events[evtName]);\n });\n }\n\n private _bindComponentEvents() {\n // Bind internal component events\n const root = this._rootEl;\n const control = this._control;\n const animator = this._animator;\n const renderer = this._renderer;\n const vr = this._vr;\n\n const controlEventsToPropagate = [\n CONTROL_EVENTS.STATIC_CLICK,\n CONTROL_EVENTS.INPUT_START,\n CONTROL_EVENTS.INPUT_END\n ];\n\n controlEventsToPropagate.forEach(evtName => {\n control.rotate.on(evtName, evt => {\n this._emit(evtName, evt);\n });\n\n control.zoom.on(evtName, evt => {\n this._emit(evtName, evt);\n });\n });\n\n vr.on(EVENTS.VR_START, evt => {\n root.classList.add(DEFAULT_CLASS.IN_VR);\n\n animator.changeContext(evt.session);\n animator.start(this._renderVRFrame);\n\n this._emit(EVENTS.VR_START);\n });\n\n vr.on(EVENTS.VR_END, () => {\n root.classList.remove(DEFAULT_CLASS.IN_VR);\n\n renderer.ctx.useDefaultFrameBuffer();\n animator.changeContext(window);\n animator.start(this._renderFrameOnDemand);\n\n this.resize();\n\n this._emit(EVENTS.VR_END);\n });\n }\n}\n\nexport default View360;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4, quat, vec3 } from \"gl-matrix\";\n\n/**\n * Base class for 3D objects\n * @ko 3D 오브젝트의 베이스 클래스\n * @since 4.0.0\n * @internal\n */\nclass Object3D {\n /**\n * Local matrix of the object\n * @ko 오브젝트의 local matrix\n * @since 4.0.0\n */\n public matrix: mat4;\n /**\n * Rotation quaternion\n * @ko 현재 오브젝트의 회전을 나타내는 사원수 값\n * @since 4.0.0\n */\n public rotation: quat;\n /**\n * Position of the object\n * @ko 오브젝트의 위치\n * @since 4.0.0\n */\n public position: vec3;\n /**\n * A scale vector of the object\n * @ko 오브젝트가 각 축으로 확대된 정도를 나타내는 벡터\n * @since 4.0.0\n */\n public scale: vec3;\n\n /**\n * Create new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n */\n public constructor() {\n this.matrix = mat4.create();\n this.rotation = quat.create();\n this.position = vec3.fromValues(0, 0, 0);\n this.scale = vec3.fromValues(1, 1, 1);\n }\n\n /**\n * Update local matrix of the object.\n * @ko 오브젝트의 local matrix를 갱신합니다.\n * @since 4.0.0\n */\n public updateMatrix() {\n mat4.fromRotationTranslationScale(this.matrix, this.rotation, this.position, this.scale);\n }\n}\n\nexport default Object3D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360Plugin from \"../View360Plugin\";\nimport View360 from \"../../View360\";\nimport { EVENTS } from \"../../const/external\";\nimport { createElement } from \"../../utils\";\nimport { LoadStartEvent } from \"../../type/events\";\n\n/**\n * Options for {@link LoadingSpinner}\n * @ko {@link LoadingSpinner}용 옵션들\n * @since 4.0.0\n * @category Plugin\n */\nexport interface LoadingSpinnerOptions {\n /**\n * Override default class names.\n * @ko 디폴트 클래스 이름들을 오버라이드합니다.\n * @since 4.0.0\n */\n className: Partial<{ -readonly [key in keyof typeof LoadingSpinner.DEFAULT_CLASS]: string }>;\n}\n\n/**\n * A plugin that displays loading spinner while loading the projection.\n * @ko 프로젝션 로딩중에 로딩 스피너를 보여주는 플러그인\n * @since 4.0.0\n * @category Plugin\n */\nclass LoadingSpinner implements View360Plugin {\n /**\n * Default class names that LoadingSpinner uses\n * @ko LoadingSpinner가 사용하는 디폴트 클래스 이름\n * @since 4.0.0\n */\n public static readonly DEFAULT_CLASS = {\n /**\n * A class name for the container element\n * @ko 컨테이너 엘리먼트의 클래스 이름\n * @since 4.0.0\n */\n CONTAINER: \"view360-spinner\",\n /**\n * A class name for the spinning ring element\n * @ko 돌아가는 링 엘리먼트의 클래스 이름\n * @since 4.0.0\n */\n RING: \"view360-spinner-ring\"\n } as const;\n\n /**\n * A class names overriding\n * @ko 현재 오버라이드 중인 클래스 이름\n * @since 4.0.0\n */\n public readonly className: LoadingSpinnerOptions[\"className\"];\n\n private _container: HTMLElement;\n\n /**\n * Create a new instance of LoadingSpinner. {@ko LoadingSpinner의 새 인스턴스를 생성합니다.}\n * @param options Options {@ko 옵션들}\n */\n public constructor({\n className = {}\n }: Partial = {}) {\n this.className = className;\n this._container = this._createElements();\n }\n\n public init(viewer: View360) {\n viewer.on(EVENTS.LOAD_START, this._startLoading);\n }\n\n public destroy(viewer: View360): void {\n viewer.off(EVENTS.LOAD_START, this._startLoading);\n this._detachElements({ target: viewer });\n }\n\n private _startLoading = ({ target: viewer }: LoadStartEvent) => {\n viewer.rootEl.appendChild(this._container);\n\n if (viewer.initialized) {\n viewer.once(EVENTS.LOAD, this._detachElements);\n } else {\n viewer.once(EVENTS.READY, this._detachElements);\n }\n };\n\n private _detachElements = ({ target: viewer }: { target: View360 }) => {\n const container = this._container;\n if (!container) return;\n\n if (container.parentElement === viewer.rootEl) {\n viewer.rootEl.removeChild(container);\n }\n };\n\n private _createElements() {\n const className = {\n ...this.className,\n ...LoadingSpinner.DEFAULT_CLASS\n };\n\n const container = createElement(className.CONTAINER);\n const ring = createElement(className.RING);\n\n container.appendChild(ring);\n\n return container;\n }\n}\n\nexport default LoadingSpinner;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n/* eslint-disable @typescript-eslint/no-empty-function */\n/* eslint-disable @typescript-eslint/no-unused-vars */\nimport ControlBar from \"./ControlBar\";\nimport View360 from \"../../View360\";\n\n/**\n * Common options for {@link ControlBarItem}\n * @ko {@link ControlBarItem}의 공통 옵션들\n * @category Plugin\n * @since 4.0.0\n */\nexport interface ControlBarItemOptions {\n /**\n * @copy ControlBarItem#position\n */\n position: typeof ControlBar.POSITION[keyof typeof ControlBar.POSITION];\n /**\n * @copy ControlBarItem#order\n */\n order: number;\n}\n\n/**\n * Interface of the ControlBar items\n * @ko 컨트롤바 아이템의 인터페이스\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nabstract class ControlBarItem {\n /**\n * Element of the item.\n * @ko 아이템의 엘리먼트\n * @since 4.0.0\n */\n public abstract element: HTMLElement;\n\n /**\n * Position to display item.\n * @ko 아이템을 표시할 위치.\n * @since 4.0.0\n */\n public position: ControlBarItemOptions[\"position\"];\n /**\n * Order within the same position.\n * The lowest one will be shown first.\n * @ko 동일한 position 내에서의 순서, 작을수록 먼저 표시됩니다.\n * @since 4.0.0\n */\n public order: ControlBarItemOptions[\"order\"];\n\n /**\n * Create new instance of the ControlBarItem\n * @ko ControlBarItem의 새로운 인스턴스를 생성합니다.\n * @param options Options {@ko 옵션들}\n */\n public constructor(options: ControlBarItemOptions) {\n this.position = options.position;\n this.order = options.order;\n }\n\n /**\n * Initialize item.\n * @ko 아이템을 초기화합니다.\n * @param viewer - A instance of viewer to attach item {@ko 아이템을 부착할 뷰어의 인스턴스}\n * @param controlBar - A instance of control bar to attach item {@ko 아이템을 부착할 컨트롤바의 인스턴스}\n * @since 4.0.0\n */\n public abstract init(viewer: View360, controlBar: ControlBar): any;\n /**\n * Destroy item and release all resources & event handlers.\n * @ko 아이템을 제거하고 할당된 모든 리소스 및 이벤트 핸들러를 제거합니다.\n * @param viewer - A instance of viewer to detach item {@ko 아이템을 떼어 낼 뷰어의 인스턴스}\n * @param controlBar - A instance of control bar to detach item {@ko 아이템을 떼어 낼 컨트롤바의 인스턴스}\n * @since 4.0.0\n */\n public abstract destroy(viewer: View360, controlBar: ControlBar): any;\n}\n\nexport default ControlBarItem;\n","export const CONTROL_BAR_DEFAULT_CLASS = {\n CONTROLS_ROOT: \"view360-controls\",\n CONTROLS_BG: \"view360-controls-background\",\n CONTROLS_MAIN: \"view360-controls-main\",\n CONTROLS_TOP: \"view360-controls-top\",\n CONTROLS_BOTTOM: \"view360-controls-bottom\",\n CONTROLS_MID: \"view360-controls-mid\",\n CONTROLS_LEFT: \"view360-controls-left\",\n CONTROLS_RIGHT: \"view360-controls-right\",\n CONTROLS_FLOAT_LEFT: \"view360-controls-float-left\",\n CONTROLS_FLOAT_RIGHT: \"view360-controls-float-right\",\n CONTROLS_BUTTON: \"view360-controls-button\",\n PROGRESS_ROOT: \"view360-controls-progress\",\n VOLUME_ROOT: \"view360-controls-volume\",\n RANGE_ROOT: \"view360-range\",\n RANGE_TRACK: \"view360-range-track\",\n RANGE_THUMB: \"view360-range-thumb\",\n RANGE_FILLER: \"view360-range-filler\",\n PLAY_BUTTON: \"view360-controls-play\",\n PAUSE_BUTTON: \"view360-controls-pause\",\n UNMUTED_BUTTON: \"view360-controls-unmuted\",\n MUTED_BUTTON: \"view360-controls-muted\",\n FULLSCREEN_BUTTON: \"view360-controls-fullscreen\",\n FULLSCREEN_EXIT_BUTTON: \"view360-controls-fullscreen-exit\",\n VR_BUTTON: \"view360-controls-vr\",\n GYRO_ENABLED: \"view360-controls-gyro-enabled\",\n GYRO_DISABLED: \"view360-controls-gyro-disabled\",\n VIDEO_TIME_DISPLAY: \"view360-controls-time\",\n PIEVIEW_ROOT: \"view360-controls-pie\",\n FIXED: \"view360-controls-fixed\",\n UNAVAILABLE: \"view360-controls-unavailable\",\n HIDDEN: \"view360-controls-hidden\"\n} as const;\n\nexport const CONTROL_BAR_ITEM_POSITION = {\n /**\n * Place control bar item floating at top-left corner\n * @ko 아이템을 왼쪽 위 구석에 표시합니다.\n * @since 4.0.0\n */\n TOP_LEFT: \"top-left\",\n /**\n * Place control bar item floating at top-right corner\n * @ko 아이템을 오른쪽 위 구석에 표시합니다.\n * @since 4.0.0\n */\n TOP_RIGHT: \"top-right\",\n /**\n * Place control bar item at upper block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 위쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_TOP: \"main-top\",\n /**\n * Place control bar item at lower block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 하단 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_BOTTOM: \"main-bottom\",\n /**\n * Place control bar item at center-left block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 왼쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_LEFT: \"main-left\",\n /**\n * Place control bar item at center-right block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 오른쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_RIGHT: \"main-right\"\n} as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { ControlBarOptions } from \"./ControlBar\";\nimport { CONTROL_BAR_DEFAULT_CLASS } from \"./const\";\nimport Motion from \"../../core/Motion\";\nimport MouseInput from \"../../control/input/MouseInput\";\nimport TouchInput from \"../../control/input/TouchInput\";\nimport { CONTROL_EVENTS, INFINITE_RANGE } from \"../../const/internal\";\nimport { clamp } from \"../../utils\";\nimport { InputEvents } from \"../../type/internal\";\nimport { EL_DIV } from \"../../const/browser\";\n\nclass RangeControl extends Component<{\n [CONTROL_EVENTS.INPUT_START]: number;\n [CONTROL_EVENTS.CHANGE]: number;\n [CONTROL_EVENTS.INPUT_END]: void;\n}> {\n public readonly rootEl: HTMLElement;\n public readonly thumbEl: HTMLElement;\n public readonly trackEl: HTMLElement;\n public readonly fillerEl: HTMLElement;\n\n private _motion: Motion;\n private _mouseInput: MouseInput;\n private _touchInput: TouchInput;\n private _fixedClass: string;\n private _bbox: DOMRect;\n\n /**\n *\n */\n public constructor() {\n super();\n\n const root = document.createElement(EL_DIV);\n const track = document.createElement(EL_DIV);\n const thumb = document.createElement(EL_DIV);\n const filler = document.createElement(EL_DIV);\n\n root.draggable = false;\n\n track.appendChild(filler);\n track.appendChild(thumb);\n root.appendChild(track);\n\n this.rootEl = root;\n this.trackEl = track;\n this.thumbEl = thumb;\n this.fillerEl = filler;\n\n this._mouseInput = new MouseInput();\n this._touchInput = new TouchInput();\n this._motion = new Motion({ duration: 1, range: INFINITE_RANGE, easing: x => x });\n this._bbox = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n left: 0,\n right: 0,\n bottom: 0,\n top: 0\n } as DOMRect;\n this._fixedClass = CONTROL_BAR_DEFAULT_CLASS.FIXED;\n }\n\n public init(className: Required) {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n\n this.rootEl.classList.add(className.RANGE_ROOT);\n this.trackEl.classList.add(className.RANGE_TRACK);\n this.thumbEl.classList.add(className.RANGE_THUMB);\n this.fillerEl.classList.add(className.RANGE_FILLER);\n this._fixedClass = className.FIXED;\n\n mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n touchInput.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n\n mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n touchInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n\n mouseInput.enable(this.rootEl);\n touchInput.enable(this.rootEl);\n\n this.resize();\n }\n\n public destroy() {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n\n this.rootEl.className = \"\";\n this.trackEl.className = \"\";\n this.thumbEl.className = \"\";\n this.fillerEl.className = \"\";\n\n mouseInput.off();\n touchInput.off();\n mouseInput.disable();\n touchInput.disable();\n }\n\n public resize() {\n this._bbox = this.trackEl.getBoundingClientRect();\n }\n\n public updateStyle(progress: number) {\n const width = this._bbox.width;\n const clampedProgress = clamp(progress, 0, 1);\n\n this.fillerEl.style.width = `${clampedProgress * 100}%`;\n this.thumbEl.style.transform = `translateX(${clampedProgress * width}px)`;\n }\n\n private _onHold = ({ srcEvent, isTouch }: InputEvents<{ x: number; y: number }>[typeof CONTROL_EVENTS.INPUT_START]) => {\n const bbox = this._bbox;\n if (!bbox) return;\n\n const x = isTouch\n ? (srcEvent as TouchEvent).touches[0].pageX\n : (srcEvent as MouseEvent).pageX;\n const elX = bbox.x + (window.scrollX ?? window.pageXOffset);\n\n const clamepdX = clamp(x, elX, elX + bbox.width);\n const progress = (clamepdX - elX) / bbox.width;\n\n this._motion.reset(clamepdX);\n this.thumbEl.classList.add(this._fixedClass);\n\n this.trigger(CONTROL_EVENTS.INPUT_START, progress);\n };\n\n private _onChange = ({ delta }: InputEvents<{ x: number; y: number }>[typeof CONTROL_EVENTS.CHANGE]) => {\n const motion = this._motion;\n const bbox = this._bbox;\n if (!bbox) return;\n\n motion.setNewEndByDelta(delta.x);\n motion.update(1);\n\n const elX = bbox.x + (window.scrollX ?? window.pageXOffset);\n const clampedX = clamp(motion.val, elX, elX + bbox.width);\n const progress = (clampedX - elX) / bbox.width;\n\n this.trigger(CONTROL_EVENTS.CHANGE, progress);\n };\n\n private _onRelease = () => {\n const bbox = this._bbox;\n if (!bbox) return;\n\n this.thumbEl.classList.remove(this._fixedClass);\n\n this.trigger(CONTROL_EVENTS.INPUT_END);\n };\n}\n\nexport default RangeControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport RangeControl from \"./RangeControl\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport { CONTROL_EVENTS, VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport { EVENTS } from \"../../const/external\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show video progress bar.\n * @ko 비디오의 프로그레스 바를 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass ProgressBar extends ControlBarItem {\n public get element() { return this._rangeControl.rootEl; }\n\n private _controlBar: ControlBar | null;\n private _video: TextureVideo | null;\n private _rangeControl: RangeControl;\n\n private _wasPaused: boolean;\n private _currentTime: number;\n private _duration: number;\n private _playPromise: Promise | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_TOP,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.position = position;\n this.order = order;\n\n this._controlBar = null;\n this._rangeControl = new RangeControl();\n\n this._video = null;\n this._wasPaused = false;\n this._currentTime = 0;\n this._duration = 0;\n this._playPromise = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const element = this.element;\n const rangeControl = this._rangeControl;\n const unavailableClass = controlBar.className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n element.classList.add(unavailableClass);\n return;\n }\n\n element.classList.remove(unavailableClass);\n element.classList.add(controlBar.className.PROGRESS_ROOT);\n viewer.on(EVENTS.RESIZE, this._onResize);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate);\n rangeControl.init(controlBar.className);\n rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n rangeControl.on(CONTROL_EVENTS.CHANGE, this._onControl);\n rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n this._video = video;\n this._currentTime = video.source.currentTime;\n this._duration = video.source.duration;\n this._controlBar = controlBar;\n\n rangeControl.updateStyle(this._currentTime / this._duration);\n }\n\n public destroy(viewer: View360) {\n const video = this._video;\n\n viewer.off(EVENTS.RESIZE, this._onResize);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate);\n }\n\n this._rangeControl.destroy();\n this._video = null;\n this._playPromise = null;\n }\n\n private _onResize = () => {\n this._rangeControl.resize();\n }\n\n private _onTimeUpdate = () => {\n const video = this._video;\n if (!video) return;\n\n this._currentTime = video.source.currentTime;\n this._rangeControl.updateStyle(this._currentTime / this._duration);\n };\n\n private _onDurationChange = () => {\n const video = this._video;\n if (!video) return;\n\n this._duration = video.source.duration;\n this._rangeControl.updateStyle(this._currentTime / this._duration);\n };\n\n private _onHold = (progress: number) => {\n const video = this._video;\n const controlBar = this._controlBar;\n if (!video || !controlBar) return;\n\n const paused = video.isPaused();\n\n video.source.pause();\n\n const time = video.source.duration * progress;\n video.source.currentTime = time;\n video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time }}));\n\n controlBar.rootEl.classList.add(controlBar.className.FIXED);\n this._wasPaused = !this._playPromise && paused;\n };\n\n private _onControl = (progress: number) => {\n const video = this._video;\n if (!video) return;\n\n const time = video.source.duration * progress;\n video.source.currentTime = time;\n video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time }}));\n };\n\n private _onRelease = () => {\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (video && controlBar) {\n if (!this._wasPaused && !this._playPromise) {\n this._playPromise = video.source.play()\n .catch(() => void 0);\n\n // This should not be chained\n this._playPromise.then(() => {\n this._playPromise = null;\n });\n\n controlBar.rootEl.classList.remove(controlBar.className.FIXED);\n }\n }\n\n this._wasPaused = false;\n };\n}\n\nexport default ProgressBar;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show video play / pause button.\n * @ko 비디오 재생 / 일시정지 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass PlayButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _controlBar: ControlBar | null;\n private _video: TextureVideo | null;\n private _paused: boolean;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n\n this._video = null;\n this._paused = true;\n this._controlBar = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const video = viewer.projection?.getTexture();\n const className = controlBar.className;\n const unavailableClass = className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n element.classList.add(unavailableClass);\n return;\n }\n\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.remove(unavailableClass);\n\n const paused = video.isPaused();\n this._video = video;\n this._paused = paused;\n this._controlBar = controlBar;\n\n if (paused) {\n this._onPause();\n } else {\n this._onPlay();\n }\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onPlay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onPause);\n }\n\n public destroy() {\n const video = this._video;\n const element = this.element;\n\n if (!video) return;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onPlay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onPause);\n\n this._video = null;\n this._paused = true;\n this._controlBar = null;\n }\n\n private _onClick = () => {\n const video = this._video;\n if (!video) return;\n\n if (this._paused) {\n video.source.play();\n } else {\n video.source.pause();\n }\n };\n\n private _onPlay = () => {\n if (!this._controlBar) return;\n\n const element = this.element;\n const className = this._controlBar.className;\n\n element.classList.add(className.PAUSE_BUTTON);\n element.classList.remove(className.PLAY_BUTTON);\n element.title = \"Pause Video\";\n\n this._paused = false;\n };\n\n private _onPause = () => {\n if (!this._controlBar) return;\n\n const element = this.element;\n const className = this._controlBar.className;\n\n element.classList.add(className.PLAY_BUTTON);\n element.classList.remove(className.PAUSE_BUTTON);\n element.title = \"Play Video\";\n\n this._paused = true;\n };\n}\n\nexport default PlayButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport RangeControl from \"./RangeControl\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { EVENTS } from \"../../const/external\";\n\n/**\n * Show video volume control.\n * @ko 비디오 볼륨 조절 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VolumeControl extends ControlBarItem {\n public get element() { return this._rootEl; }\n\n private _controlBar: ControlBar | null;\n private _rootEl: HTMLButtonElement;\n private _buttonEl: HTMLElement;\n private _rangeControl: RangeControl;\n private _video: TextureVideo | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this._controlBar = null;\n this._rangeControl = new RangeControl();\n this._createElements();\n\n this._video = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const root = this._rootEl;\n const button = this._buttonEl;\n const rangeControl = this._rangeControl;\n const className = controlBar.className;\n const unavailableClass = className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n root.classList.add(unavailableClass);\n return;\n }\n\n root.classList.remove(unavailableClass);\n root.classList.add(className.CONTROLS_BUTTON);\n root.classList.add(className.VOLUME_ROOT);\n button.classList.add(className.CONTROLS_BUTTON);\n\n if (video.source.muted) {\n button.classList.add(className.MUTED_BUTTON);\n } else {\n button.classList.add(className.UNMUTED_BUTTON);\n }\n\n viewer.on(EVENTS.RESIZE, this._onResize);\n root.addEventListener(BROWSER.EVENTS.TRANSITION_END, this._onResize);\n button.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_VOLUME_CHANGE, this._onVolumeChange);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_LOADED_DATA, this._updateDisplay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay);\n\n rangeControl.init(className);\n rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n rangeControl.on(CONTROL_EVENTS.CHANGE, this._onChange);\n rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n this._controlBar = controlBar;\n this._video = video;\n\n this._updateDisplay();\n }\n\n public destroy(viewer: View360) {\n const video = this._video;\n const button = this._buttonEl;\n const root = this._rootEl;\n\n root.className = \"\";\n button.className = \"\";\n\n viewer.off(EVENTS.RESIZE, this._onResize);\n root.removeEventListener(BROWSER.EVENTS.TRANSITION_END, this._onResize);\n button.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_VOLUME_CHANGE, this._onVolumeChange);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_LOADED_DATA, this._updateDisplay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay);\n }\n\n this._controlBar = null;\n this._rangeControl.destroy();\n this._video = null;\n }\n\n private _onResize = () => {\n this._rangeControl.resize();\n this._updateDisplay();\n }\n\n private _onClick = () => {\n const video = this._video;\n if (!video || this._rootEl.disabled) return;\n\n video.source.muted = !video.source.muted;\n };\n\n private _onVolumeChange = () => {\n const button = this._buttonEl;\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (!video || !controlBar) return;\n\n const className = controlBar.className;\n\n if (video.source.muted || video.source.volume === 0) {\n button.classList.add(className.MUTED_BUTTON);\n button.classList.remove(className.UNMUTED_BUTTON);\n } else {\n button.classList.add(className.UNMUTED_BUTTON);\n button.classList.remove(className.MUTED_BUTTON);\n }\n\n this._updateDisplay();\n };\n\n private _createElements() {\n const root = document.createElement(BROWSER.EL_BUTTON);\n const buttonEl = document.createElement(BROWSER.EL_DIV);\n\n root.appendChild(this._rangeControl.rootEl);\n root.appendChild(buttonEl);\n root.title = \"Toggle Mute\";\n\n this._rootEl = root;\n this._buttonEl = buttonEl;\n }\n\n private _onHold = (progress: number) => {\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (!video || !controlBar) return;\n\n const className = controlBar.className;\n\n video.source.volume = progress;\n\n this._rootEl.classList.add(className.FIXED);\n controlBar.containerEl.classList.add(className.FIXED);\n\n this._updateDisplay();\n };\n\n private _onChange = (progress: number) => {\n const video = this._video;\n if (!video) return;\n\n video.source.volume = progress;\n if (progress > 0) {\n video.source.muted = false;\n } else {\n video.source.muted = true;\n }\n\n this._updateDisplay();\n };\n\n private _onRelease = () => {\n const controlBar = this._controlBar;\n if (!controlBar) return;\n\n const className = controlBar.className;\n\n this._rootEl.classList.remove(className.FIXED);\n controlBar.containerEl.classList.remove(className.FIXED);\n };\n\n private _updateDisplay = () => {\n const video = this._video;\n const root = this._rootEl;\n if (!video) return;\n\n if (!video.hasAudio()) {\n root.disabled = true;\n return;\n }\n\n root.disabled = false;\n\n const volume = video.source.muted ? 0 : video.source.volume;\n\n this._rangeControl.updateStyle(volume);\n };\n}\n\nexport default VolumeControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport { isFullscreen } from \"../../utils\";\n\n/**\n * Show fullscreen enter / exit button.\n * @ko 풀스크린 진입 / 해제 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass FullscreenButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _controlBar: ControlBar | null;\n private _targetEl: HTMLElement | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n this.element.title = \"Toggle Fullscreen\";\n this._controlBar = null;\n this._targetEl = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n if (!this._fullscreenAvailable()) {\n element.classList.add(className.UNAVAILABLE);\n return;\n }\n\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.remove(className.UNAVAILABLE);\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._addFullscreenHandlers();\n\n if (isFullscreen()) {\n element.classList.add(className.FULLSCREEN_EXIT_BUTTON);\n } else {\n element.classList.add(className.FULLSCREEN_BUTTON);\n }\n\n this._controlBar = controlBar;\n this._targetEl = viewer.rootEl;\n }\n\n public destroy() {\n const element = this.element;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._removeFullscreenHandlers();\n\n this._controlBar = null;\n this._targetEl = null;\n }\n\n private _onClick = () => {\n const target = this._targetEl;\n if (!target) return;\n\n if (isFullscreen()) {\n this._exitFullscreen();\n } else {\n this._requestFullscreen(target);\n }\n };\n\n private _fullscreenAvailable() {\n return BROWSER.FULLSCREEN_REQUEST.some(key => !!document[key]);\n }\n\n private _requestFullscreen(el: HTMLElement) {\n for (const key of BROWSER.FULLSCREEN_REQUEST) {\n const request = el[key];\n if (request) {\n request.call(el);\n return;\n }\n }\n }\n\n private _exitFullscreen() {\n for (const key of BROWSER.FULLSCREEN_EXIT) {\n const exit = document[key];\n\n if (exit) {\n exit.call(document);\n return;\n }\n }\n }\n\n private _addFullscreenHandlers() {\n BROWSER.FULLSCREEN_CHANGE.forEach(evtName => {\n document.addEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _removeFullscreenHandlers() {\n BROWSER.FULLSCREEN_CHANGE.forEach(evtName => {\n document.removeEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _onFullscreenChange = () => {\n const element = this.element;\n const controlBar = this._controlBar;\n\n if (!controlBar) return;\n\n const className = controlBar.className;\n\n if (isFullscreen()) {\n element.classList.add(className.FULLSCREEN_EXIT_BUTTON);\n element.classList.remove(className.FULLSCREEN_BUTTON);\n } else {\n element.classList.add(className.FULLSCREEN_BUTTON);\n element.classList.remove(className.FULLSCREEN_EXIT_BUTTON);\n }\n };\n}\n\nexport default FullscreenButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\n\n/**\n * Show video current / total time.\n * @ko 비디오의 현재 / 총 재생시간을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VideoTime extends ControlBarItem {\n public readonly element: HTMLElement;\n private _video: TextureVideo | null;\n private _currentTime: number;\n private _duration: number;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n\n this._video = null;\n this._currentTime = 0;\n this._duration = 0;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const element = this.element;\n const className = controlBar.className;\n\n if (!video || !video.isVideo()) {\n element.classList.add(className.UNAVAILABLE);\n return;\n }\n\n element.classList.add(className.VIDEO_TIME_DISPLAY);\n element.classList.remove(className.UNAVAILABLE);\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange);\n\n this._video = video;\n this._currentTime = video.source.currentTime;\n this._duration = video.source.duration;\n\n this._updateDisplay();\n }\n\n public destroy() {\n const video = this._video;\n\n if (!video) return;\n\n this.element.className = \"\";\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange);\n\n this._video = null;\n }\n\n private _onTimeUpdate = () => {\n const video = this._video;\n if (!video) return;\n\n this._currentTime = video.source.currentTime;\n this._updateDisplay();\n };\n\n private _onDurationChange = () => {\n const video = this._video;\n if (!video) return;\n\n this._duration = video.source.duration;\n this._updateDisplay();\n };\n\n private _onCustomTimeChange = (evt: CustomEvent<{ time: number }>) => {\n this._currentTime = evt.detail.time;\n this._updateDisplay();\n };\n\n private _updateDisplay() {\n const time = this._currentTime;\n const timeMinute = Math.floor(time / 60);\n const timeSeconds = Math.floor(time - timeMinute * 60);\n const timeSecondsFormatted = timeSeconds < 10 ? `0${timeSeconds}` : timeSeconds;\n\n const duration = this._duration;\n const durationMinute = Math.floor(duration / 60);\n const durationSeconds = Math.floor(duration - durationMinute * 60);\n const durationSecondsFormatted = durationSeconds < 10 ? `0${durationSeconds}` : durationSeconds;\n\n this.element.innerText = `${timeMinute}:${timeSecondsFormatted} / ${durationMinute}:${durationSecondsFormatted}`;\n }\n}\n\nexport default VideoTime;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport { circulate, getObjectOption } from \"../../utils\";\nimport * as BROWSER from \"../../const/browser\";\nimport { EVENTS } from \"../../const/external\";\nimport { SVG_NAMESPACE } from \"../../const/internal\";\n\n/**\n * Options for {@link PieView}\n * @ko {@link PieView}용 옵션들\n * @category Plugin\n */\nexport interface PieViewOptions extends ControlBarItemOptions {\n /**\n * @copy PieView#resetCamera\n */\n resetCamera: boolean | Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n duration: number;\n easing: (x: number) => number;\n }>;\n}\n\n/**\n * Show camera direction/fov indicator.\n * @ko 카메라가 향하는 방향 및 FOV를 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass PieView extends ControlBarItem {\n public readonly element: HTMLElement;\n\n /**\n * Set rotation to reset camera to when PieView is clicked.\n * `false` will disable this value, and `true` will enable with default options.\n * @ko PieView가 클릭되었을 때 카메라를 리셋할 방향을 지정합니다.\n * `false`일 경우 이 동작을 비활성화하며, `true`일 경우 기본값을 사용합니다.\n * @since 4.0.0\n */\n public resetCamera: PieViewOptions[\"resetCamera\"];\n\n private _viewer: View360 | null;\n private _piePathEl: SVGPathElement;\n private _rangeCircleEl: SVGCircleElement;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n resetCamera = true,\n position = CONTROL_BAR_ITEM_POSITION.TOP_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n this.element.title = \"Reset view\";\n this.resetCamera = resetCamera;\n this._createPieElements();\n this._viewer = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n\n if (!viewer.initialized) {\n viewer.once(EVENTS.READY, this._updatePie);\n } else {\n this._updatePie({ target: viewer });\n }\n\n const rootClass = controlBar.className.PIEVIEW_ROOT;\n element.classList.add(rootClass);\n\n if (this.resetCamera) {\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n }\n\n viewer.on(EVENTS.VIEW_CHANGE, this._updatePie);\n\n this._viewer = viewer;\n }\n\n public destroy(viewer: View360) {\n const element = this.element;\n\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.className = \"\";\n viewer.off(EVENTS.READY, this._updatePie);\n viewer.off(EVENTS.VIEW_CHANGE, this._updatePie);\n\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n const resetCamera = this.resetCamera;\n\n if (!viewer || !resetCamera) return;\n\n const {\n yaw = viewer.initialYaw,\n pitch = viewer.initialPitch,\n zoom = viewer.initialZoom,\n duration = 500\n } = getObjectOption(resetCamera);\n\n viewer.camera.animateTo({\n yaw,\n pitch,\n zoom,\n duration\n });\n };\n\n private _createPieElements() {\n const root = this.element;\n const pieSVG = document.createElementNS(SVG_NAMESPACE, \"svg\");\n pieSVG.setAttribute(\"viewBox\", \"0 0 48 48\");\n pieSVG.setAttribute(\"width\", \"100%\");\n pieSVG.setAttribute(\"height\", \"100%\");\n\n const piePath = document.createElementNS(SVG_NAMESPACE, \"circle\");\n\n piePath.setAttribute(\"stroke\", \"currentColor\");\n piePath.setAttribute(\"fill\", \"transparent\");\n piePath.setAttribute(\"cx\", \"24\");\n piePath.setAttribute(\"cy\", \"24\");\n piePath.setAttribute(\"r\", \"12\");\n piePath.setAttribute(\"stroke-width\", \"24\");\n pieSVG.appendChild(piePath);\n\n const rangeCircle = document.createElementNS(SVG_NAMESPACE, \"circle\");\n\n rangeCircle.setAttribute(\"stroke\", \"currentColor\");\n rangeCircle.setAttribute(\"fill\", \"transparent\");\n rangeCircle.setAttribute(\"cx\", \"24\");\n rangeCircle.setAttribute(\"cy\", \"24\");\n rangeCircle.setAttribute(\"r\", \"22.5\");\n rangeCircle.setAttribute(\"stroke-width\", \"3\");\n pieSVG.appendChild(rangeCircle);\n\n root.appendChild(pieSVG);\n\n this._piePathEl = piePath;\n this._rangeCircleEl = rangeCircle;\n }\n\n private _updatePie = ({ target: viewer }: { target: View360 }) => {\n const piePath = this._piePathEl;\n const rangeCircle = this._rangeCircleEl;\n const camera = viewer.camera;\n const fov = camera.getHorizontalFov();\n const yawRange = camera.getYawRange(camera.zoom);\n const halfFov = fov * 0.5;\n\n const pieRadius = 24 * Math.PI;\n const pieDeg = pieRadius * fov / 360;\n const pieOffset = pieRadius * (camera.yaw + halfFov + 90) / 360;\n\n piePath.setAttribute(\"stroke-dasharray\", `${pieDeg} ${pieRadius - pieDeg}`);\n piePath.setAttribute(\"stroke-dashoffset\", `${pieOffset}`);\n\n if (isFinite(yawRange.min) && isFinite(yawRange.max)) {\n const radius = 45 * Math.PI; // 2 * PI * r\n const min = (circulate(yawRange.min, -180, 180) - halfFov) / 360;\n const max = (circulate(yawRange.max, -180, 180) + halfFov) / 360;\n\n const rangeDiff = radius * Math.abs(max - min);\n const offset = -radius * (min - 0.25);\n\n rangeCircle.setAttribute(\"stroke-dasharray\", `${rangeDiff} ${radius - rangeDiff}`);\n rangeCircle.setAttribute(\"stroke-dashoffset\", `${offset}`);\n } else {\n rangeCircle.setAttribute(\"stroke-dasharray\", \"\");\n rangeCircle.setAttribute(\"stroke-dashoffset\", \"\");\n }\n };\n}\n\nexport default PieView;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show VR enter button.\n * @ko VR 진입 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VRButton extends ControlBarItem {\n public readonly element: HTMLElement;\n\n private _viewer: View360 | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n this.element.title = \"Enter VR\";\n this._viewer = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n element.classList.add(className.UNAVAILABLE);\n element.classList.add(className.VR_BUTTON);\n element.classList.add(className.CONTROLS_BUTTON);\n\n viewer.vr.isAvailable()\n .then(available => {\n if (available) {\n element.classList.remove(className.UNAVAILABLE);\n }\n });\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._viewer = viewer;\n }\n\n public destroy() {\n const element = this.element;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n if (!viewer) return;\n\n viewer.vr.enter();\n };\n}\n\nexport default VRButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport GyroControl from \"../../control/GyroControl\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { sensorCanBeEnabledIOS } from \"../../utils\";\n\n/**\n * Show gyroscope control enable / disable button\n * @ko 자이로스코프 컨트롤 활성화 / 비활성화 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass GyroButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _viewer: View360 | null;\n private _controlBar: ControlBar | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n this.element.title = \"Toggle gyroscope control\";\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.add(className.UNAVAILABLE);\n\n const enableButton = () => {\n element.classList.remove(className.UNAVAILABLE);\n viewer.control.gyro.on(CONTROL_EVENTS.ENABLE, this._updateStyle);\n viewer.control.gyro.on(CONTROL_EVENTS.DISABLE, this._updateStyle);\n };\n\n if (sensorCanBeEnabledIOS()) {\n enableButton();\n } else {\n GyroControl.isAvailable().then(available => {\n if (!available) return;\n enableButton();\n });\n }\n\n this._controlBar = controlBar;\n this._viewer = viewer;\n this._updateStyle();\n }\n\n public destroy(viewer: View360) {\n const element = this.element;\n\n viewer.control.gyro.off(CONTROL_EVENTS.ENABLE, this._updateStyle);\n viewer.control.gyro.off(CONTROL_EVENTS.DISABLE, this._updateStyle);\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.className = \"\";\n\n this._controlBar = null;\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n const controlBar = this._controlBar;\n\n if (!viewer || !controlBar) return;\n\n const gyroControl = viewer.control.gyro;\n if (gyroControl.enabled) {\n gyroControl.disable();\n } else {\n GyroControl.requestSensorPermission().then(available => {\n if (available) {\n gyroControl.enable();\n } else {\n this.element.classList.add(controlBar.className.UNAVAILABLE);\n }\n });\n }\n };\n\n private _updateStyle = () => {\n const element = this.element;\n const viewer = this._viewer;\n const controlBar = this._controlBar;\n\n if (!viewer || !controlBar) return;\n\n const gyroControl = viewer.control.gyro;\n const className = controlBar.className;\n\n if (gyroControl.enabled) {\n element.classList.add(className.GYRO_ENABLED);\n element.classList.remove(className.GYRO_DISABLED);\n } else {\n element.classList.add(className.GYRO_DISABLED);\n element.classList.remove(className.GYRO_ENABLED);\n }\n };\n}\n\nexport default GyroButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport { FULLSCREEN_CHANGE } from \"../../const/browser\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport { isFullscreen } from \"../../utils\";\n\n/**\n * Options for ControlBar's {@link ControlBarOptions#autoHide}\n * @ko ControlBar의 {@link ControlBarOptions#autoHide}용 옵션\n * @category Plugin\n * @since 4.0.0\n */\nexport interface AutoHideOptions {\n /**\n * Initial delay before the control bar hides (ms)\n * @ko 컨트롤바가 처음으로 표시되고 사라지기까지 걸리는 시간 (ms)\n * @default 3000\n * @since 4.0.0\n */\n initialDelay: number;\n /**\n * Delay time before hiding the control bar after mouse leave (ms)\n * @ko 마우스가 컨트롤바 영역을 떠난 뒤 컨트롤바가 사라지기까지 걸리는 시간 (ms)\n * @default 0\n * @since 4.0.0\n */\n delay: number;\n /**\n * Delay time before hiding the control bar becomes active, like touch on mobile device or mouse move in fullscreen mode (ms)\n * @ko 모바일이나 풀스크린 환경 등에서 사용자 입력이 없을 때 컨트롤바가 사라지기까지 걸리는 시간 (ms)\n * @default 3000\n * @since 4.0.0\n */\n idleDelay: number;\n}\n\nclass AutoHide {\n private _initialDelay: AutoHideOptions[\"initialDelay\"];\n private _delay: AutoHideOptions[\"delay\"];\n private _idleDelay: AutoHideOptions[\"idleDelay\"];\n\n private _controlBar: ControlBar;\n private _timer: number;\n private _isGrabbing: boolean;\n private _isCursorInside: boolean;\n private _isFullscreen: boolean;\n private _targetEl: HTMLElement | null;\n private _video: TextureVideo | null;\n\n public get enabled() { return !!this._targetEl; }\n public get hidden() { return this._controlBar.containerEl.classList.contains(this._hiddenClass); }\n\n private get _hiddenClass() { return this._controlBar.className.HIDDEN; }\n private get _fixedClass() { return this._controlBar.className.FIXED; }\n\n public constructor(controlBar: ControlBar, {\n initialDelay = 3000,\n delay = 0,\n idleDelay: activationDelay = 3000\n }: Partial) {\n this._controlBar = controlBar;\n this._initialDelay = initialDelay;\n this._delay = delay;\n this._idleDelay = activationDelay;\n this._timer = -1;\n this._isCursorInside = false;\n this._isGrabbing = false;\n this._isFullscreen = false;\n this._video = null;\n this._targetEl = null;\n }\n\n public enable(viewer: View360) {\n if (this._targetEl) {\n this.disable(viewer);\n }\n\n const initialDelay = this._initialDelay;\n const root = viewer.rootEl;\n\n this._targetEl = viewer.rootEl;\n this._timer = window.setTimeout(() => {\n this.hide();\n }, initialDelay);\n\n root.addEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onHold);\n root.addEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter);\n root.addEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove);\n root.addEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave);\n this._addFullscreenHandlers();\n\n const video = viewer.projection?.getTexture();\n if (!video || !video.isVideo()) {\n return;\n }\n\n if (video.isPaused()) {\n this._controlBar.containerEl.classList.add(this._fixedClass);\n }\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onVideoPlay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onVideoPause);\n\n this._video = video;\n }\n\n public disable(viewer: View360) {\n if (!this._targetEl) return;\n\n const controlBar = this._controlBar;\n const root = viewer.rootEl;\n const video = this._video;\n\n root.removeEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onHold);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave);\n this._removeFullscreenHandlers();\n\n window.clearTimeout(this._timer);\n controlBar.containerEl.classList.remove(this._fixedClass);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onVideoPlay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onVideoPause);\n }\n\n this._isCursorInside = false;\n this._isGrabbing = false;\n this._video = null;\n this._targetEl = null;\n }\n\n public show() {\n this._clearHideTimer();\n this._controlBar.containerEl.classList.remove(this._hiddenClass);\n }\n\n public showTemporaliy() {\n this.show();\n this._hideAfterDelay(this._idleDelay);\n }\n\n public hide() {\n this._clearHideTimer();\n this._controlBar.containerEl.classList.add(this._hiddenClass);\n }\n\n private _clearHideTimer() {\n if (this._timer) {\n window.clearTimeout(this._timer);\n this._timer = -1;\n }\n }\n\n private _hideAfterDelay(delay = this._delay) {\n if (this._isGrabbing || (!this._isFullscreen && this._isCursorInside)) return;\n\n this._clearHideTimer();\n if (delay <= 0) {\n this.hide();\n } else {\n this._timer = window.setTimeout(() => {\n this.hide();\n }, delay);\n }\n }\n\n private _onMouseEnter = () => {\n this._isCursorInside = true;\n this.show();\n };\n\n private _onMouseLeave = () => {\n this._isCursorInside = false;\n this._hideAfterDelay();\n };\n\n private _onMouseMove = () => {\n if (!this._isFullscreen) return;\n\n this.showTemporaliy();\n }\n\n private _onHold = (evt: PointerEvent) => {\n this._isGrabbing = true;\n\n if (evt.pointerType === \"mouse\") {\n this._isCursorInside = true;\n }\n\n window.addEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n\n this.show();\n };\n\n private _onRelease = () => {\n this._isGrabbing = false;\n\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n\n this._hideAfterDelay();\n };\n\n private _onVideoPlay = () => {\n const root = this._targetEl;\n if (!root) return;\n\n this._controlBar.containerEl.classList.remove(this._fixedClass);\n };\n\n private _onVideoPause = () => {\n const root = this._targetEl;\n if (!root) return;\n\n this._controlBar.containerEl.classList.add(this._fixedClass);\n };\n\n private _addFullscreenHandlers() {\n FULLSCREEN_CHANGE.forEach(evtName => {\n document.addEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _removeFullscreenHandlers() {\n FULLSCREEN_CHANGE.forEach(evtName => {\n document.removeEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _onFullscreenChange = () => {\n this._isFullscreen = isFullscreen();\n\n if (this._isFullscreen) {\n this._hideAfterDelay();\n }\n };\n}\n\nexport default AutoHide;\n","import TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { clamp } from \"../../utils\";\nimport { VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\n\nclass VideoControl {\n private _video: TextureVideo | null;\n\n public enable(root: HTMLElement, video: TextureVideo) {\n this._video = video;\n // capture is needed for resolving conflict with keyboard control\n root.addEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown, true);\n }\n\n public disable(root: HTMLElement) {\n this._video = null;\n root.removeEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown, true);\n }\n\n private _onKeyDown = (event: KeyboardEvent) => {\n const video = this._video;\n if (!video) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n const videoEl = video.source;\n const keyPressed = event.keyCode != null\n ? BROWSER.DIRECTION_KEY_CODE[event.keyCode]\n : BROWSER.DIRECTION_KEY_NAME[event.key];\n\n switch (keyPressed) {\n case \"LEFT\":\n case \"RIGHT\":\n return this._changeVideoTime(videoEl, keyPressed === \"RIGHT\");\n case \"UP\":\n case \"DOWN\":\n return this._changeVideoVolume(videoEl, keyPressed === \"UP\");\n }\n\n const spacePressed = event.keyCode === BROWSER.SPACE_KEY_CODE || event.key === BROWSER.SPACE_KEY_NAME;\n if (spacePressed) {\n this._toggleVideo(video);\n }\n }\n\n private _changeVideoTime(video: HTMLVideoElement, forward: boolean) {\n const delta = forward ? 5 : -5;\n\n video.currentTime += delta;\n video.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time: video.currentTime }}));\n }\n\n private _changeVideoVolume(video: HTMLVideoElement, increase: boolean) {\n const delta = increase ? 0.1 : -0.1;\n\n if (video.muted) {\n video.volume = clamp(delta, 0, 1);\n } else {\n video.volume = clamp(video.volume + delta, 0, 1);\n }\n\n if (video.volume > 0) {\n video.muted = false;\n } else {\n video.muted = true;\n }\n }\n\n private _toggleVideo(video: TextureVideo) {\n if (video.isPaused()) {\n video.source.play();\n } else {\n video.source.pause();\n }\n }\n}\n\nexport default VideoControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport ProgressBar from \"./ProgressBar\";\nimport PlayButton from \"./PlayButton\";\nimport VolumeControl from \"./VolumeControl\";\nimport FullscreenButton from \"./FullscreenButton\";\nimport VideoTime from \"./VideoTime\";\nimport PieView, { PieViewOptions } from \"./PieView\";\nimport VRButton from \"./VRButton\";\nimport GyroButton from \"./GyroButton\";\nimport AutoHide, { AutoHideOptions } from \"./AutoHide\";\nimport VideoControl from \"./VideoControl\";\nimport View360, { View360Events } from \"../../View360\";\nimport View360Plugin from \"../View360Plugin\";\nimport { EVENTS } from \"../../const/external\";\nimport { createElement, findIndex, getObjectOption } from \"../../utils\";\nimport { ValueOf } from \"../../type/utils\";\nimport { StaticClickEvent } from \"../../type/events\";\nimport { CONTROL_BAR_DEFAULT_CLASS, CONTROL_BAR_ITEM_POSITION } from \"./const\";\n\n/**\n * Options for {@link ControlBar}\n * @ko {@link ControlBar}용 옵션들\n * @category Plugin\n * @since 4.0.0\n */\nexport interface ControlBarOptions {\n /**\n * @copy ControlBar#autoHide\n */\n autoHide: boolean | Partial;\n /**\n * @copy ControlBar#showBackground\n */\n showBackground: boolean;\n /**\n * @copy ControlBar#clickToPlay\n */\n clickToPlay: boolean;\n /**\n * @copy ControlBar#keyboardControls\n */\n keyboardControls: boolean;\n /**\n * @copy ControlBar#progressBar\n */\n progressBar: boolean | Partial;\n /**\n * @copy ControlBar#playButton\n */\n playButton: boolean | Partial;\n /**\n * @copy ControlBar#volumeButton\n */\n volumeButton: boolean | Partial;\n /**\n * @copy ControlBar#fullscreenButton\n */\n fullscreenButton: boolean | Partial;\n /**\n * @copy ControlBar#videoTime\n */\n videoTime: boolean | Partial;\n /**\n * @copy ControlBar#pieView\n */\n pieView: boolean | Partial;\n /**\n * @copy ControlBar#vrButton\n */\n vrButton: boolean | Partial;\n /**\n * @copy ControlBar#gyroButton\n */\n gyroButton: boolean | Partial;\n /**\n * @copy ControlBar#className\n */\n className: Partial<{ -readonly [key in keyof typeof ControlBar.DEFAULT_CLASS]: string }>;\n /**\n * @copy ControlBar#customItems\n */\n customItems: ControlBarItem[];\n}\n\n/**\n * A plugin that displays extra buttons & controls that controls {@link View360}.\n * @ko {@link View360}에 부가적인 버튼과 컨트롤을 추가해주는 플러그인.\n * @category Plugin\n * @since 4.0.0\n */\nclass ControlBar implements View360Plugin {\n /**\n * Default class names that ControlBar uses\n * @ko ControlBar가 사용하는 디폴트 클래스 이름들\n * @since 4.0.0\n */\n public static readonly DEFAULT_CLASS = CONTROL_BAR_DEFAULT_CLASS;\n\n /**\n * Constants for {@link ControlBarItemOptions#position}\n * @ko {@link ControlBarItemOptions#position}에 사용 가능한 값들\n */\n public static readonly POSITION = CONTROL_BAR_ITEM_POSITION;\n\n /**\n * Automatically hide control bar on video plays.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 재생시 자동으로 컨트롤바를 숨깁니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly autoHide?: ControlBarOptions[\"autoHide\"];\n /**\n * Show background element.\n * @ko 배경 엘리먼트를 표시합니다.\n * @since 4.0.0\n */\n public readonly showBackground?: ControlBarOptions[\"showBackground\"];\n /**\n * Whether to play / pause video on canvas click\n * @ko 캔버스 클릭시에 비디오를 재생 / 일시정지 토글합니다.\n * @since 4.0.0\n */\n public readonly clickToPlay: ControlBarOptions[\"clickToPlay\"];\n /**\n * Enable keyboard controls for video.\n * Pressing up / down arrow will control video volume, and pressing left / right arrow will control video time.\n * @ko 비디오 키보드 컨트롤을 활성화합니다.\n * 위 / 아래 화살표키를 누를 시 비디오 볼륨을, 왼쪽 / 오른쪽 화살표키를 누를 시 비디오 시간을 조정합니다.\n * @since 4.0.0\n */\n public readonly keyboardControls: ControlBarOptions[\"keyboardControls\"];\n /**\n * Show video progress bar.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 프로그레스 바를 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly progressBar: ControlBarOptions[\"progressBar\"];\n /**\n * Show video play / pause button.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 재생 / 일시정지 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly playButton: ControlBarOptions[\"playButton\"];\n /**\n * Show video volume control button.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 볼륨 조절 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly volumeButton: ControlBarOptions[\"volumeButton\"];\n /**\n * Show fullscreen button.\n * `true` to enable with default values, `false` to disable.\n * @ko 풀스크린 진입 / 해제 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly fullscreenButton: ControlBarOptions[\"fullscreenButton\"];\n /**\n * Show video current / total time\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오의 현재 시간 / 총 시간을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly videoTime: ControlBarOptions[\"videoTime\"];\n /**\n * Show camera pie view.\n * `true` to enable with default values, `false` to disable.\n * @ko 현재 카메라가 가리키는 방향을 표시하는 파이 뷰를 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly pieView: ControlBarOptions[\"pieView\"];\n /**\n * Show VR button.\n * `true` to enable with default values, `false` to disable.\n * @ko VR 진입버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly vrButton: ControlBarOptions[\"vrButton\"];\n /**\n * Show gyroscope control enable / disable button.\n * `true` to enable with default values, `false` to disable.\n * @ko 자이로스코프 컨트롤을 활성화 / 비활성화하는 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly gyroButton: ControlBarOptions[\"gyroButton\"];\n /**\n * Override default class names.\n * @ko 디폴트 클래스 이름들을 오버라이드합니다.\n * @since 4.0.0\n */\n public readonly className: Required;\n\n /**\n * Root element of the control bar\n * @ko 컨트롤바의 루트 엘리먼트\n * @since 4.0.0\n */\n public get rootEl() { return this._rootEl; }\n /**\n * Container element of the control bar\n * @ko 컨트롤바의 컨테이너 엘리먼트\n * @since 4.0.0\n */\n public get containerEl() { return this._containerEl; }\n /**\n * Background element of the control bar\n * @ko 컨트롤바의 배경 엘리먼트\n * @since 4.0.0\n */\n public get backgroundEl() { return this._bgEl; }\n /**\n * Control bar's default items created by {@link ControlBarOptions}\n * @ko 주어진 {@link ControlBarOptions}에 의해 생성된 디폴트 아이템들\n * @since 4.0.0\n */\n public get items() { return this._items; }\n /**\n * Custom control bar items\n * @ko 커스텀 컨트롤바 아이템들을 추가합니다.\n * @since 4.0.0\n */\n public get customItems() { return this._customItems; }\n\n private _rootEl: HTMLElement;\n private _containerEl: HTMLElement;\n private _bgEl: HTMLElement;\n private _wrapperEl: Record, HTMLElement>;\n private _items: Record, ControlBarItem[]>;\n private _customItems: ControlBarItem[];\n private _autoHider: AutoHide;\n private _videoControl: VideoControl;\n\n /**\n * Create new instance of ControlBar.\n * @ko ControlBar의 새 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n autoHide,\n showBackground,\n clickToPlay = true,\n keyboardControls = true,\n progressBar = true,\n playButton = true,\n volumeButton = true,\n fullscreenButton = true,\n videoTime = true,\n pieView = true,\n vrButton = true,\n gyroButton = true,\n className = {},\n customItems = []\n }: Partial = {}) {\n this.autoHide = autoHide;\n this.showBackground = showBackground;\n this.clickToPlay = clickToPlay;\n this.keyboardControls = keyboardControls;\n this.progressBar = progressBar;\n this.playButton = playButton;\n this.volumeButton = volumeButton;\n this.fullscreenButton = fullscreenButton;\n this.videoTime = videoTime;\n this.pieView = pieView;\n this.vrButton = vrButton;\n this.gyroButton = gyroButton;\n this.className = {\n ...ControlBar.DEFAULT_CLASS,\n ...className\n };\n\n const rootClass = className.CONTROLS_ROOT ?? ControlBar.DEFAULT_CLASS.CONTROLS_ROOT;\n\n this._rootEl = createElement(rootClass);\n this._createPositionWrappers();\n this._items = Object.keys(ControlBar.POSITION).reduce((items, key) => {\n items[ControlBar.POSITION[key]] = [];\n return items;\n }, {}) as Record, ControlBarItem[]>;\n this._customItems = customItems;\n this._autoHider = new AutoHide(this, getObjectOption(autoHide));\n this._videoControl = new VideoControl();\n\n customItems.forEach(item => {\n this._items[item.position].push(item);\n });\n }\n\n public init(viewer: View360) {\n const panoRoot = viewer.rootEl;\n const controlsRoot = this._rootEl;\n const defaultItems = this._createDefaultItems();\n\n this._updateBackground(viewer);\n this._updateAutoHide(viewer);\n this._updateKeyboardHandler(viewer);\n\n panoRoot.appendChild(controlsRoot);\n this._addItem(viewer, defaultItems);\n this._addItem(viewer, this._customItems);\n\n viewer.on(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad);\n viewer.on(EVENTS.STATIC_CLICK, this._onStaticClick);\n }\n\n public destroy(viewer: View360): void {\n // Remove controls root from pano root\n const panoRoot = viewer.rootEl;\n const controlsRoot = this._rootEl;\n const items = this._items;\n\n if (controlsRoot.parentElement === panoRoot) {\n panoRoot.removeChild(controlsRoot);\n }\n\n Object.keys(items).forEach((key: ValueOf) => {\n const category = items[key];\n\n category.forEach(item => {\n item.destroy(viewer, this);\n });\n\n items[key] = [];\n });\n\n this._clearItemElements();\n this._autoHider.disable(viewer);\n this._videoControl.disable(panoRoot);\n\n viewer.off(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad);\n viewer.off(EVENTS.STATIC_CLICK, this._onStaticClick);\n }\n\n private _addItem(viewer: View360, items: ControlBarItem[]) {\n for (const item of items) {\n const category = this._items[item.position];\n const wrapper = this._wrapperEl[item.position];\n\n const nextSiblingIndex = findIndex(category, sibling => sibling.order > item.order);\n\n if (nextSiblingIndex >= 0) {\n const nextSibling = category[nextSiblingIndex].element;\n category.splice(nextSiblingIndex, 0, item);\n wrapper.insertBefore(item.element, nextSibling);\n } else {\n category.push(item);\n wrapper.appendChild(item.element);\n }\n\n item.init(viewer, this);\n }\n }\n\n private _createPositionWrappers() {\n const className = {\n ...ControlBar.DEFAULT_CLASS,\n ...this.className\n };\n const rootEl = this._rootEl;\n\n // BG & FLOATING CONTROLS\n const backgroundEl = createElement(className.CONTROLS_BG);\n const floatLeftEl = createElement(className.CONTROLS_FLOAT_LEFT);\n const floatRightEl = createElement(className.CONTROLS_FLOAT_RIGHT);\n\n rootEl.appendChild(floatLeftEl);\n rootEl.appendChild(floatRightEl);\n\n // BOTTOM CONTROLS\n const container = createElement(className.CONTROLS_MAIN);\n const topWrapper = createElement(className.CONTROLS_TOP);\n const bottomWrapper = createElement(className.CONTROLS_BOTTOM);\n const midWrapper = createElement(className.CONTROLS_MID);\n const leftControlsWrapper = createElement(className.CONTROLS_LEFT);\n const rightControlsWrapper = createElement(className.CONTROLS_RIGHT);\n\n midWrapper.appendChild(leftControlsWrapper);\n midWrapper.appendChild(rightControlsWrapper);\n container.appendChild(backgroundEl);\n container.appendChild(topWrapper);\n container.appendChild(midWrapper);\n container.appendChild(bottomWrapper);\n rootEl.appendChild(container);\n\n this._bgEl = backgroundEl;\n this._containerEl = container;\n this._wrapperEl = {\n [ControlBar.POSITION.MAIN_TOP]: topWrapper,\n [ControlBar.POSITION.MAIN_LEFT]: leftControlsWrapper,\n [ControlBar.POSITION.MAIN_RIGHT]: rightControlsWrapper,\n [ControlBar.POSITION.MAIN_BOTTOM]: bottomWrapper,\n [ControlBar.POSITION.TOP_LEFT]: floatLeftEl,\n [ControlBar.POSITION.TOP_RIGHT]: floatRightEl\n };\n }\n\n private _clearItemElements() {\n const wrappers = Object.keys(ControlBar.POSITION).map(key => ControlBar.POSITION[key]);\n\n // Remove all elements inside wrappers\n wrappers.forEach(wrapper => {\n while (wrapper.firstChild) {\n wrapper.removeChild(wrapper.firstChild);\n }\n });\n }\n\n private _onStaticClick = ({ target: viewer, isTouch }: StaticClickEvent) => {\n const autoHider = this._autoHider;\n\n if (isTouch) {\n if (!autoHider.enabled) return;\n\n if (autoHider.hidden) {\n autoHider.showTemporaliy();\n } else {\n autoHider.hide();\n }\n } else {\n if (!this.clickToPlay) return;\n\n const video = viewer.projection?.getTexture();\n if (!video || !video.isVideo()) return;\n\n if (video.isPaused()) {\n video.source.play();\n } else {\n video.source.pause();\n }\n }\n };\n\n private _onNewSrcLoad = ({ target: viewer }: View360Events[\"projectionChange\"]) => {\n const items = this._items;\n\n this._updateBackground(viewer);\n this._updateAutoHide(viewer);\n this._updateKeyboardHandler(viewer);\n\n Object.keys(items).forEach((key: ValueOf) => {\n const category = items[key];\n\n category.forEach(item => {\n item.destroy(viewer, this);\n item.init(viewer, this);\n });\n });\n };\n\n private _updateAutoHide(viewer: View360) {\n const autoHide = this.autoHide;\n const autoHider = this._autoHider;\n\n if (autoHide != null) {\n if (autoHide) {\n autoHider.enable(viewer);\n } else {\n autoHider.disable(viewer);\n }\n } else {\n // Automatically choose whether to show background by content type\n const texture = viewer.projection?.getTexture();\n\n if (texture && texture.isVideo()) {\n // Enable auto hide when content type is video\n autoHider.enable(viewer);\n } else {\n autoHider.disable(viewer);\n }\n }\n }\n\n private _updateBackground(viewer: View360) {\n const background = this._bgEl;\n const showBackground = this.showBackground;\n const hiddenClass = this.className.HIDDEN ?? ControlBar.DEFAULT_CLASS.HIDDEN;\n\n if (showBackground != null) {\n if (showBackground) {\n background.classList.remove(hiddenClass);\n } else {\n background.classList.add(hiddenClass);\n }\n } else {\n // Automatically choose whether to show background by content type\n const texture = viewer.projection?.getTexture();\n\n if (texture && texture.isVideo()) {\n // Show bg when content type is video\n background.classList.remove(hiddenClass);\n } else {\n background.classList.add(hiddenClass);\n }\n }\n }\n\n private _updateKeyboardHandler(viewer: View360) {\n const panoRoot = viewer.rootEl;\n const videoControl = this._videoControl;\n const texture = viewer.projection?.getTexture();\n\n if (this.keyboardControls && texture && texture.isVideo()) {\n videoControl.enable(panoRoot, texture);\n } else {\n videoControl.disable(panoRoot);\n }\n }\n\n private _createDefaultItems(): ControlBarItem[] {\n const items: ControlBarItem[] = [];\n\n if (this.progressBar) {\n items.push(new ProgressBar(getObjectOption(this.progressBar)));\n }\n\n if (this.playButton) {\n items.push(new PlayButton(getObjectOption(this.playButton)));\n }\n\n if (this.volumeButton) {\n items.push(new VolumeControl(getObjectOption(this.volumeButton)));\n }\n\n if (this.gyroButton) {\n items.push(new GyroButton(getObjectOption(this.gyroButton)));\n }\n\n if (this.vrButton) {\n items.push(new VRButton(getObjectOption(this.vrButton)));\n }\n\n if (this.fullscreenButton) {\n items.push(new FullscreenButton(getObjectOption(this.fullscreenButton)));\n }\n\n if (this.videoTime) {\n items.push(new VideoTime(getObjectOption(this.videoTime)));\n }\n\n if (this.pieView) {\n items.push(new PieView(getObjectOption(this.pieView)));\n }\n\n return items;\n }\n}\n\nexport default ControlBar;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Camera from \"../core/Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport Texture from \"../texture/Texture\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport { VideoConfig } from \"../type/external\";\nimport UniformCanvasCube from \"../uniform/UniformCanvasCube\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport UniformTextureCube from \"../uniform/UniformTextureCube\";\n\ntype CommonProjectionUniforms = {\n uTexture: UniformTexture2D | UniformTextureCube | UniformCanvasCube;\n}\n\n/**\n * Common option for {@link Projection}s\n * @ko {@link Projection}을 위한 공통 옵션들\n * @category Projection\n * @since 4.0.0\n */\nexport interface ProjectionOptions {\n /**\n * @copy Projection#src\n */\n src: string | HTMLElement | Array;\n /**\n * @copy Projection#video\n */\n video?: boolean | Partial;\n}\n\n/**\n * Base class for projections.\n * @ko 프로젝션 베이스 클래스.\n * @category Projection\n * @since 4.0.0\n */\nabstract class Projection {\n /**\n * Source URL to panorama image/video.\n * @ko 파노라마 이미지/비디오의 URL\n * @since 4.0.0\n */\n public readonly src: ProjectionOptions[\"src\"];\n /**\n * Properties for the video element.\n * Setting `false` will treat panorama source as an image, `true` will use default properties.\n * @ko 비디오 엘리먼트에 설정할 프로퍼티를 담는 객체.\n * @since 4.0.0\n * @example\n * Default properties\n * ```ts\n * autoplay: true\n * muted: true\n * loop: false\n * volume: 1\n * ```\n */\n public readonly video: ProjectionOptions[\"video\"];\n\n protected _mesh: TriangleMesh | null;\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n src,\n video = false\n }: ProjectionOptions) {\n this.src = src;\n this.video = video;\n this._mesh = null;\n }\n\n /**\n * Apply texture to current projection.\n * @ko 주어진 텍스쳐를 현재 프로젝션에 적용합니다.\n * @param ctx - Instance of the WebGLContext helper {@ko WebGL context 헬퍼의 인스턴스}\n * @param texture - New texture to apply {@ko 새로 적용할 텍스쳐}\n * @internal\n * @since 4.0.0\n */\n public abstract applyTexture(ctx: WebGLContext, texture: Texture): void;\n\n /**\n * Release all resources projection has.\n * This is automatically called on projection change & View360's destroy call\n * @ko 현재 갖고 있는 모든 리소스를 반환합니다.\n * 이 메소드는 프로젝션 변경 및 View360의 destroy 호출 시 자동으로 호출됩니다.\n * @param ctx\n */\n public releaseAllResources(ctx: WebGLContext) {\n this._mesh?.destroy(ctx);\n }\n\n /**\n * Update camera to match projection's settings.\n * @ko 현재 프로젝션의 세팅으로 카메라를 업데이트합니다.\n * @param camera - Instance of the camera to update {@ko 업데이트할 카메라의 인스턴스}\n * @since 4.0.0\n */\n public updateCamera(camera: Camera) {\n // Use default mode & no view restriction\n camera.resetRange();\n }\n\n /**\n * Update control to match projection's settings.\n * @ko 현재 프로젝션의 세팅으로 컨트롤을 업데이트합니다.\n * @param control - Instance of the control to update {@ko 업데이트할 컨트롤의 인스턴스}\n * @since 4.0.0\n */\n public updateControl(control: PanoControl) {\n control.ignoreZoomScale = false;\n }\n\n /**\n * Update projection.\n * @ko 현재 프로젝션 정보를 갱신합니다.\n * @param camera - Instance of the camera to reference {@ko 참조할 카메라의 인스턴스}\n * @since 4.0.0\n */\n public update(camera: Camera) {} // eslint-disable-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars\n\n /**\n * Return active texture.\n * @ko 현재 활성화된 텍스쳐를 반환합니다.\n * @internal\n * @since 4.0.0\n */\n public getTexture() {\n if (!this._mesh) return null;\n\n return this._mesh.program.uniforms.uTexture.texture;\n }\n\n /**\n * A 3D triangle mesh for projection. It's `null` until loading the `src`.\n * @ko Projection을 표시하기 위한 Mesh, src를 로드하기 전까지는 `null`입니다.\n * @since 4.0.0\n */\n public getMesh(): TriangleMesh | null {\n return this._mesh;\n }\n}\n\nexport default Projection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nabstract class Uniform {\n public needsUpdate: boolean;\n\n public constructor() {\n this.needsUpdate = true;\n }\n\n public abstract update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean): void;\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext) {\n // DO_NOTHING\n }\n}\n\nexport default Uniform;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport TextureCube from \"../texture/TextureCube\";\nimport { reorderCube } from \"../utils\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformTextureCube extends Uniform {\n public readonly texture: TextureCube;\n private _webglTexture: WebGLTexture;\n private _cubemapOrder: string;\n\n public constructor(ctx: WebGLContext, texture: TextureCube, cubemapOrder: string) {\n super();\n\n this.texture = texture;\n this._webglTexture = ctx.createWebGLCubeTexture(texture, texture.width);\n this._cubemapOrder = cubemapOrder;\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext): void {\n this.texture.destroy();\n gl.deleteTexture(this._webglTexture);\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture);\n\n const sources = reorderCube(texture.sources, this._cubemapOrder);\n sources.forEach((src, idx) => {\n if (isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src);\n } else {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src);\n }\n });\n\n if (!texture.isVideo()) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformTextureCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"../texture/Texture2D\";\nimport { range, reorderCube } from \"../utils\";\n\n/** @hidden */\nclass CubeTexturePainter {\n public readonly texture: Texture2D;\n private _renderingOrder: number[];\n private _canvas: HTMLCanvasElement;\n private _ctx: CanvasRenderingContext2D;\n private _row: number;\n private _column: number;\n private _size: number;\n\n public get size() { return this._size; }\n\n public constructor(texture: Texture2D, cubemapOrder: string) {\n this.texture = texture;\n this._renderingOrder = reorderCube(range(6), cubemapOrder);\n\n const canvas = document.createElement(\"canvas\");\n\n this._calcRenderingSize();\n\n canvas.width = this._size;\n canvas.height = this._size;\n\n this._canvas = canvas;\n this._ctx = canvas.getContext(\"2d\")!;\n }\n\n public destroy() {\n const canvas = this._canvas;\n\n // release memories\n canvas.width = 1;\n canvas.height = 1;\n this._canvas = null as any;\n }\n\n public draw(gl: WebGLRenderingContext | WebGL2RenderingContext, isWebGL2: boolean) {\n const size = this._size;\n const texture = this.texture;\n let surfaceIdx = 0;\n\n for (let row = 0; row < this._row; row++) {\n for (let column = 0; column < this._column; column++) {\n const x = size * column;\n const y = size * row;\n const renderingFace = this._renderingOrder[surfaceIdx];\n\n this._ctx.drawImage(texture.source as CanvasImageSource, x, y, size, size, 0, 0, size, size);\n\n if (isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas);\n } else {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas);\n }\n\n surfaceIdx++;\n }\n }\n }\n\n private _calcRenderingSize() {\n const {\n width,\n height\n } = this.texture;\n const aspect = width / height;\n\n if (aspect === 1 / 6) {\n this._size = width;\n this._row = 6;\n this._column = 1;\n } else if (aspect === 6) {\n this._size = height;\n this._row = 1;\n this._column = 6;\n } else if (aspect === 2 / 3) {\n this._size = width * 0.5;\n this._row = 3;\n this._column = 2;\n } else {\n this._size = width / 3;\n this._row = 2;\n this._column = 3;\n }\n }\n}\n\nexport default CubeTexturePainter;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport CubeTexturePainter from \"../core/CubeTexturePainter\";\nimport Texture2D from \"../texture/Texture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformCanvasCube extends Uniform {\n private _webglTexture: WebGLTexture;\n private _painter: CubeTexturePainter;\n\n public get texture() { return this._painter.texture; }\n\n public constructor(ctx: WebGLContext, texture: Texture2D, cubemapOrder: string) {\n super();\n\n this._painter = new CubeTexturePainter(texture as Texture2D, cubemapOrder);\n this._webglTexture = ctx.createWebGLCubeTexture(texture, this._painter.size);\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext) {\n gl.deleteTexture(this._webglTexture);\n this._painter.destroy();\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture);\n\n this._painter.draw(gl, isWebGL2);\n\n if (!texture.isVideo()) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformCanvasCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Object3D from \"./Object3D\";\nimport ShaderProgram from \"./ShaderProgram\";\nimport VertexArrayObject from \"./VertexArrayObject\";\nimport Uniform from \"../uniform/Uniform\";\nimport WebGLContext from \"./WebGLContext\";\n\n/**\n * @hidden\n */\nclass TriangleMesh = Record> extends Object3D {\n /**\n * @internal\n * Geometry data for projection\n */\n public readonly vao: VertexArrayObject;\n /**\n * @internal\n * Material(shader) data for projection\n */\n public readonly program: ShaderProgram;\n\n public constructor(vao: VertexArrayObject, program: ShaderProgram) {\n super();\n\n this.vao = vao;\n this.program = program;\n }\n\n public destroy(ctx: WebGLContext) {\n ctx.releaseVAO(this.vao);\n ctx.releaseShaderResources(this.program);\n }\n}\n\nexport default TriangleMesh;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"../uniform/Uniform\";\nimport WebGLContext from \"./WebGLContext\";\nimport { UniformLocations } from \"../type/internal\";\n\nclass ShaderProgram = Record> {\n public readonly program: WebGLProgram;\n public readonly uniforms: T;\n public readonly uniformLocations: UniformLocations;\n\n public constructor(ctx: WebGLContext, vertexShader: string, fragmentShader: string, uniforms: T) {\n this.program = ctx.createProgram(vertexShader, fragmentShader);\n this.uniforms = uniforms;\n this.uniformLocations = ctx.getUniformLocations(this.program, uniforms);\n }\n}\n\nexport default ShaderProgram;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { TypedArray } from \"../type/utils\";\n\n/**\n * @hidden\n */\nclass VertexData {\n public readonly data: T;\n public itemSize: number;\n public count: number;\n\n /** */\n public constructor(data: T, itemSize: number) {\n this.data = data;\n this.itemSize = itemSize;\n this.count = data.length / itemSize;\n }\n}\n\nexport default VertexData;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport VertexData from \"../core/VertexData\";\n\n/**\n * @hidden\n */\nabstract class Geometry {\n public readonly vertices: VertexData;\n public readonly indicies: VertexData;\n public readonly uvs: VertexData;\n\n /** */\n public constructor(vertices: number[], indicies: number[], uvs: number[]) {\n this.vertices = new VertexData(new Float32Array(vertices), 3);\n this.indicies = new VertexData(new Uint16Array(indicies), 1);\n this.uvs = new VertexData(new Float32Array(uvs), 2);\n }\n}\n\nexport default Geometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\nimport { ROTATE } from \"../const/internal\";\nimport { reorderCube } from \"../utils\";\n\n/**\n * @hidden\n */\nclass CubeGeometry extends Geometry {\n public constructor({\n order,\n rotateUV\n }: {\n order: string;\n rotateUV?: ROTATE[]\n }) {\n const vertices = [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // up\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // down\n -1, -1, 1,\n 1, -1, 1,\n 1, -1, -1,\n -1, -1, -1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n\n const indicies = [\n 0, 1, 2,\n 0, 2, 3,\n 4, 5, 6,\n 4, 6, 7,\n 8, 9, 10,\n 8, 10, 11,\n 12, 13, 14,\n 12, 14, 15,\n 16, 17, 18,\n 16, 18, 19,\n 20, 21, 22,\n 20, 22, 23\n ];\n\n const oneThird = 1 / 3;\n const coords: number[][] = [];\n\n for (let r = 1; r >= 0; r--) {\n for (let c = 0; c < 3; c++) {\n const coord = [\n c * oneThird, r * 0.5,\n (c + 1) * oneThird, r * 0.5,\n (c + 1) * oneThird, (r + 1) * 0.5,\n c * oneThird, (r + 1) * 0.5\n ];\n\n coords.push(coord);\n }\n }\n\n if (rotateUV) {\n rotateUV.forEach((degree, idx) => {\n if (degree === ROTATE.ZERO) return;\n\n const coord = coords[idx];\n let newOrder: number[];\n\n if (degree === ROTATE.CW_90) {\n newOrder = [1, 2, 3, 0];\n } else if (degree === ROTATE.CCW_90) {\n newOrder = [3, 0, 1, 2];\n } else {\n newOrder = [2, 3, 0, 1];\n }\n\n const newCoords = Array(coord.length);\n for (let uvIdx = 0; uvIdx < coord.length / 2; uvIdx++) {\n newCoords[uvIdx * 2 + 0] = coord[newOrder[uvIdx] * 2 + 0];\n newCoords[uvIdx * 2 + 1] = coord[newOrder[uvIdx] * 2 + 1];\n }\n\n coords[idx] = newCoords;\n });\n }\n\n const uvs = reorderCube(coords, order, \"BFUDRL\")\n .reduce((acc, val) => acc.concat(val), []);\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default CubeGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTextureCube from \"../uniform/UniformTextureCube\";\nimport UniformCanvasCube from \"../uniform/UniformCanvasCube\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport TextureCube from \"../texture/TextureCube\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/cube.vert\";\nimport fs from \"../shader/cube.frag\";\n\n/**\n * Options for {@link CubemapProjection}\n * @ko {@link CubemapProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CubemapProjectionOptions extends ProjectionOptions {\n /**\n * Order of the cubemap images.\n * @ko 큐브맵 이미지의 순서.\n * @since 4.0.0\n * @default \"RLUDFB\" (Right - Left - Up - Down - Front - Back)\n */\n cubemapOrder?: string;\n /**\n * Whether to flip cubemap image horizontally.\n * @ko 큐브맵 이미지를 좌우대칭할지 여부.\n * @since 4.0.0\n * @default false\n */\n cubemapFlipX?: boolean;\n}\n\n/**\n * Projection based on cubemap images, accepts both multiple or single images.\n * @ko 큐브맵 이미지 기반의 프로젝션, 단일 혹은 여러 장의 이미지를 모두 사용 가능합니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CubemapProjection extends Projection<{\n uTexture: UniformTextureCube | UniformCanvasCube;\n}> {\n private _cubemapOrder: NonNullable;\n private _cubemapFlipX: NonNullable;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CubemapProjectionOptions) {\n super(options);\n\n const {\n cubemapOrder = \"RLUDFB\",\n cubemapFlipX = false\n } = options;\n\n this._cubemapOrder = cubemapOrder;\n this._cubemapFlipX = cubemapFlipX;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const cubemapOrder = this._cubemapOrder;\n const cubemapFlipX = this._cubemapFlipX;\n const uniforms = {\n uTexture: texture.isCube()\n ? new UniformTextureCube(ctx, texture as TextureCube, cubemapOrder)\n : new UniformCanvasCube(ctx, texture as Texture2D, cubemapOrder)\n };\n\n const geometry = new CubeGeometry({\n order: cubemapOrder\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n if (cubemapFlipX) {\n mesh.scale[0] = -1;\n }\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n}\n\nexport default CubemapProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"../texture/Texture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformTexture2D extends Uniform {\n public readonly texture: Texture2D;\n private _webglTexture: WebGLTexture;\n\n public constructor(ctx: WebGLContext, texture: Texture2D) {\n super();\n\n this.texture = texture;\n this._webglTexture = ctx.createWebGLTexture(texture);\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext): void {\n this.texture.destroy();\n gl.deleteTexture(this._webglTexture);\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n const isVideo = texture.isVideo();\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._webglTexture);\n\n if (!isVideo && isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n } else {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n }\n\n if (!isVideo) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformTexture2D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link CubestripProjection}\n * @ko {@link CubestripProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CubestripProjectionOptions extends ProjectionOptions {\n /**\n * @copy CubemapProjectionOptions#cubemapOrder\n */\n cubemapOrder?: string;\n /**\n * @copy CubemapProjectionOptions#cubemapFlipX\n */\n cubemapFlipX?: boolean;\n}\n\n/**\n * Projection based on cubemap strip.\n * Slightly more efficient than {@link CubemapProjection} as it doesn't copy cubemap image to canvas while rendering.\n * Accepts only single image.\n * @ko 큐브맵 스트립 기반의 프로젝션.\n * {@link CubemapProjection}와 달리 렌더링하는 과정에 캔버스에 이미지를 복사하는 과정이 없기 때문에 살짝 더 효율적입니다.\n * 단일 이미지만 사용 가능합니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CubestripProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n private _cubemapOrder: NonNullable;\n private _cubemapFlipX: NonNullable;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CubestripProjectionOptions) {\n super(options);\n\n const {\n cubemapOrder = \"RLUDFB\",\n cubemapFlipX = false\n } = options;\n\n this._cubemapOrder = cubemapOrder;\n this._cubemapFlipX = cubemapFlipX;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const cubemapOrder = this._cubemapOrder;\n const cubemapFlipX = this._cubemapFlipX;\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n const geometry = new CubeGeometry({\n order: cubemapOrder\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n if (cubemapFlipX) {\n mesh.scale[0] = -1;\n }\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n}\n\nexport default CubestripProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass CylinderGeometry extends Geometry {\n public constructor(maxTheta: number) {\n const vertices: number[] = [];\n const indicies: number[] = [];\n const uvs: number[] = [];\n\n const height = 1;\n const radialSegments = 60;\n const halfHeight = height * 0.5;\n const heightSegments = [-halfHeight, halfHeight];\n const invRadialSegments = 1 / radialSegments;\n const angleConst = maxTheta * invRadialSegments;\n\n for (let yIdx = 0; yIdx < 2; yIdx++) {\n const y = heightSegments[yIdx];\n\n for (let lngIdx = 0; lngIdx <= radialSegments; lngIdx++) {\n const angle = lngIdx * angleConst + Math.PI - maxTheta * 0.5;\n const x = Math.cos(angle);\n const z = Math.sin(angle);\n const u = lngIdx * invRadialSegments;\n const v = yIdx;\n\n uvs.push(u, v);\n vertices.push(x, y, z);\n\n if (yIdx === 0 && lngIdx < radialSegments) {\n const a = lngIdx;\n const b = a + radialSegments + 1;\n\n indicies.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n }\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default CylinderGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n*/\nimport { quat } from \"gl-matrix\";\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport CylinderGeometry from \"../geometry/CylinderGeometry\";\nimport Camera from \"../core/Camera\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"../const/internal\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\nimport TriangleMesh from \"../core/TriangleMesh\";\n\n/**\n * Options for {@link CylindricalProjection}\n * @ko {@link CylindricalProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CylindricalProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n /**\n * Whether the panorama image covers full 360 degrees.\n * @ko 파노라마 이미지가 360도를 전부 커버하는지 여부\n * @since 4.0.0\n * @default false\n */\n partial?: boolean;\n}\n\n/**\n * Projection based on cylindrical projection.\n * This can show panorama images taken from smartphones.\n * @ko 원통 투영법 기반의 프로젝션.\n * 일반적인 스마트폰 파노라마 사진을 표시하는데 사용될 수 있습니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CylindricalProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n private _partial: boolean;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CylindricalProjectionOptions) {\n super(options);\n\n const {\n partial = false\n } = options;\n\n this._partial = partial;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const partial = this._partial;\n const { width, height } = texture;\n const aspect = width / height;\n const halfVFov = 180 / aspect;\n const cylinderHeight = partial\n ? 1\n : 2 * Math.tan(halfVFov * DEG_TO_RAD);\n const cylinderTheta = partial\n ? aspect\n : 2 * Math.PI;\n\n const geometry = new CylinderGeometry(cylinderTheta);\n const program = new ShaderProgram(ctx, vs, fs, {\n uTexture: new UniformTexture2D(ctx, texture)\n });\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n mesh.scale[1] = cylinderHeight;\n quat.identity(mesh.rotation);\n quat.rotateY(mesh.rotation, mesh.rotation, -Math.PI / 2);\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n\n public updateCamera(camera: Camera) {\n super.updateCamera(camera);\n\n const mesh = this._mesh;\n if (!mesh) return;\n\n const uTexture = mesh.program.uniforms.uTexture;\n const texture = uTexture.texture;\n const { width, height } = texture;\n const aspect = width / height;\n const halfHeight = mesh.scale[1] * 0.5;\n\n if (this._partial) {\n const restrictedYaw = 0.5 * aspect * RAD_TO_DEG;\n camera.restrictYawRange(-restrictedYaw, restrictedYaw);\n }\n\n const restrictedPitch = Math.atan2(halfHeight, 1) * RAD_TO_DEG;\n const minZoom = Math.tan(camera.fov * DEG_TO_RAD * 0.5) / (halfHeight * camera.aspect);\n\n camera.restrictPitchRange(-restrictedPitch, restrictedPitch);\n camera.restrictZoomRange(minZoom, Infinity);\n camera.restrictRenderHeight(halfHeight * 2);\n }\n}\n\nexport default CylindricalProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/eac.frag\";\nimport { ROTATE } from \"../const/internal\";\n\n/**\n * Options for {@link EquiangularProjection}\n * @ko {@link EquiangularProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface EquiangularProjectionOptions extends ProjectionOptions {}\n\n/**\n * Equi-Angular Cubemap Projection.\n * This format is used by Youtube's 360 videos.\n * @ko Equi-Angular Cubemap 프로젝션.\n * 이 포맷은 주로 Youtube의 360 비디오에 사용됩니다.\n * @since 4.0.0\n * @category Projection\n */\nclass EquiangularProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n const geometry = new CubeGeometry({\n order: \"LFRDBU\",\n rotateUV: [\n ROTATE.ZERO, ROTATE.ZERO, ROTATE.ZERO,\n ROTATE.CW_90, ROTATE.CCW_90, ROTATE.CW_90\n ]\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default EquiangularProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass SphereGeometry extends Geometry {\n /** */\n public constructor() {\n // const radius = 1;\n const widthSegments = 60;\n const heightSegments = 60;\n const ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI;\n\n const uvs: number[] = [];\n const vertices: number[] = [];\n const indicies: number[] = [];\n let latIdx: number;\n let lngIdx: number;\n\n for (latIdx = 0; latIdx <= widthSegments; latIdx++) {\n const theta = (latIdx / widthSegments - 0.5) * Math.PI;\n const sinTheta = Math.sin(theta);\n const cosTheta = Math.cos(theta);\n\n for (lngIdx = 0; lngIdx <= heightSegments; lngIdx++) {\n const phi = (lngIdx / heightSegments - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN;\n const sinPhi = Math.sin(phi);\n const cosPhi = Math.cos(phi);\n const x = cosPhi * cosTheta;\n const y = sinTheta;\n const z = sinPhi * cosTheta;\n const u = lngIdx / heightSegments;\n const v = latIdx / widthSegments;\n\n uvs.push(u, v);\n vertices.push(x, y, z);\n\n if (lngIdx !== heightSegments && latIdx !== widthSegments) {\n const a = latIdx * (heightSegments + 1) + lngIdx;\n const b = a + heightSegments + 1;\n\n indicies.push(a, a + 1, b, b, a + 1, b + 1);\n }\n }\n }\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default SphereGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport Texture2D from \"../texture/Texture2D\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport SphereGeometry from \"../geometry/SphereGeometry\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link EquirectProjection}\n * @ko {@link EquirectProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface EquirectProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n}\n\n/**\n * Projection based on equirectangular projection.\n * @ko 등 장방형 도법(Equirectangular projection) 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass EquirectProjection extends Projection<{\n uTexture: UniformTexture2D\n}> {\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: EquirectProjectionOptions) {\n super(options);\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n\n const geometry = new SphereGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default EquirectProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"./Uniform\";\n\nclass UniformFloat extends Uniform {\n public val: number;\n\n public constructor(val: number) {\n super();\n\n this.val = val;\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation) {\n gl.uniform1f(location, this.val);\n\n this.needsUpdate = false;\n }\n}\n\nexport default UniformFloat;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass PlaneGeometry extends Geometry {\n /** */\n public constructor(width: number = 2, height: number = 2, z: number = -1) {\n const halfWidth = width * 0.5;\n const halfHeight = height * 0.5;\n const vertices = [\n -halfWidth, -halfHeight, z,\n halfWidth, -halfHeight, z,\n -halfWidth, halfHeight, z,\n halfWidth, halfHeight, z\n ];\n const indicies = [\n 0, 1, 2,\n 2, 1, 3\n ];\n const uvs = [\n 0, 0,\n 1, 0,\n 0, 1,\n 1, 1\n ];\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default PlaneGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport UniformFloat from \"../uniform/UniformFloat\";\nimport Camera from \"../core/Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport Texture2D from \"../texture/Texture2D\";\nimport PlaneGeometry from \"../geometry/PlaneGeometry\";\nimport vs from \"../shader/little-planet.vert\";\nimport fs from \"../shader/little-planet.frag\";\nimport TriangleMesh from \"../core/TriangleMesh\";\n\n/**\n * Options for {@link LittlePlanetProjection}\n * @ko {@link LittlePlanetProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface LittlePlanetProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n}\n\n/**\n * Projection based on so-called \"Little planet\" or \"Tiny planet\" effect.\n * @ko \"Little planet\" 혹은 \"Tiny planet\"로 불리는 이펙트 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass LittlePlanetProjection extends Projection<{\n uTexture: UniformTexture2D;\n uYaw: UniformFloat;\n uPitch: UniformFloat;\n uZoom: UniformFloat;\n}> {\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: LittlePlanetProjectionOptions) {\n super(options);\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n texture.wrapS = WebGLRenderingContext.REPEAT;\n texture.wrapT = WebGLRenderingContext.REPEAT;\n\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture),\n uYaw: new UniformFloat(0),\n uPitch: new UniformFloat(0.5),\n uZoom: new UniformFloat(1)\n };\n\n const geometry = new PlaneGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n\n public updateControl(control: PanoControl) {\n control.ignoreZoomScale = true;\n }\n\n public update(camera: Camera) {\n const mesh = this._mesh;\n if (!mesh) return;\n\n const uniforms = mesh.program.uniforms;\n\n uniforms.uYaw.val = camera.yaw / 360;\n // Range from 0 ~ 1\n uniforms.uPitch.val = (camera.pitch / 180) + 0.5;\n uniforms.uZoom.val = camera.zoom;\n\n uniforms.uYaw.needsUpdate = true;\n uniforms.uPitch.needsUpdate = true;\n uniforms.uZoom.needsUpdate = true;\n }\n}\n\nexport default LittlePlanetProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"./Uniform\";\n\nclass UniformVector4Array extends Uniform {\n public val: number[][];\n\n public constructor(val: number[][]) {\n super();\n\n this.val = val;\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation) {\n gl.uniform4fv(location, this.val.reduce((arr, vector) => [...arr, ...vector], []));\n\n this.needsUpdate = false;\n }\n}\n\nexport default UniformVector4Array;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport SphereGeometry from \"../geometry/SphereGeometry\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport UniformVector4Array from \"../uniform/UniformVector4Array\";\nimport UniformFloat from \"../uniform/UniformFloat\";\nimport vs from \"../shader/stereoequi.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link StereoEquiProjection}\n * @ko {@link StereoEquiProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface StereoEquiProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n /**\n * Stereoscopic mode of the image\n * @ko 이미지의 스테레오스코픽 모드\n * @since 4.0.0\n * @default \"top_bottom\"\n */\n mode: typeof StereoEquiProjection.MODE[keyof typeof StereoEquiProjection.MODE]\n}\n\n/**\n * Projection based on stereo equirectangular images.\n * @ko Stereo equirectangular 이미지 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass StereoEquiProjection extends Projection<{\n uTexture: UniformTexture2D;\n uEye: UniformFloat;\n uTexScaleOffset: UniformVector4Array;\n}> {\n /**\n * Available stereoscopic modes\n * @ko 사용가능한 스테레오스코픽 모드들\n * @since 4.0.0\n */\n public static MODE = {\n /**\n * @ko 이미지가 왼쪽/오른쪽으로 구성되어있을 경우\n * @since 4.0.0\n */\n LEFT_RIGHT: \"left_right\",\n /**\n * @ko 이미지가 위/아래로 구성되어있을 경우\n * @since 4.0.0\n */\n TOP_BOTTOM: \"top_bottom\",\n } as const;\n\n private _mode: StereoEquiProjectionOptions[\"mode\"];\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: StereoEquiProjectionOptions) {\n super(options);\n\n this._mode = options.mode;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n let leftEye: number[];\n let rightEye: number[];\n\n switch (this._mode) {\n case StereoEquiProjection.MODE.LEFT_RIGHT:\n leftEye = [0.5, 1, 0, 0];\n rightEye = [0.5, 1, 0.5, 0];\n break;\n default:\n // Default, uses \"top_bottom\"\n leftEye = [1, 0.5, 0, 0];\n rightEye = [1, 0.5, 0, 0.5];\n }\n\n\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture),\n uEye: new UniformFloat(0),\n uTexScaleOffset: new UniformVector4Array([leftEye, rightEye])\n };\n\n const geometry = new SphereGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default StereoEquiProjection;\n","import Component from \"@egjs/component\";\nimport View360 from \"../View360\";\n\n/**\n * @hidden\n */\nconst withMethods = (prototype: any, attr: string) => {\n [Component.prototype, View360.prototype].forEach(proto => {\n Object.getOwnPropertyNames(proto)\n .filter(name => name.charAt(0) !== \"_\" && name !== \"constructor\")\n .forEach((name: string) => {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name)!;\n\n if (descriptor.value) {\n // Public Function\n Object.defineProperty(prototype, name, {\n value: function(...args) {\n return descriptor.value.call(this[attr], ...args);\n }\n });\n } else {\n const getterDescriptor: { get?: () => any; set?: (val: any) => void } = {};\n if (descriptor.get) {\n getterDescriptor.get = function() {\n return this[attr] && descriptor.get?.call(this[attr]);\n };\n }\n if (descriptor.set) {\n getterDescriptor.set = function(...args) {\n return descriptor.set?.call(this[attr], ...args);\n };\n }\n\n Object.defineProperty(prototype, name, getterDescriptor);\n }\n });\n });\n};\n\nexport default withMethods;\n","/**\n * @hidden\n */\nexport const getValidProps = (propsObj: any) => {\n return Object.keys(propsObj).reduce((props, propName) => {\n if (propsObj[propName] != null) {\n props[propName] = propsObj[propName];\n }\n\n return props;\n }, {});\n};\n","export const VIEW360_METHODS = [\n \"destroy\",\n \"init\",\n \"load\",\n \"resize\",\n \"addPlugins\",\n \"removePlugins\",\n \"renderFrame\",\n // @egjs/component methods\n \"on\",\n \"hasOn\",\n \"once\",\n \"off\",\n \"trigger\"\n] as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360, { View360Options, View360Events } from \"./View360\";\n\nexport * from \"./core\";\nexport * from \"./control\";\nexport * from \"./plugin\";\nexport * from \"./projection\";\nexport * from \"./hotspot\";\nexport * from \"./const/external\";\nexport * from \"./type/external\";\nexport * from \"./cfc\";\n\nexport type {\n View360Options,\n View360Events\n};\n\nexport default View360;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360, * as modules from \"./index\";\nimport { merge } from \"./utils\";\n\nmerge(View360, modules);\n\nexport default View360;\n"],"names":["View360Error","Error","constructor","message","code","Object","setPrototypeOf","prototype","name","ERROR_CODES","WRONG_TYPE","WRONG_OPTION","ELEMENT_NOT_FOUND","CANVAS_NOT_FOUND","WEBGL_NOT_SUPPORTED","FAILED_CREATE_CONTEXT_2D","PROVIDE_PROJECTION_FIRST","FAILED_LINKING_PROGRAM","INSUFFICIENT_ARGS","MESSAGES","val","types","map","type","join","optionName","query","msg","shaderLog","CODES","EVENTS","MOUSE_DOWN","MOUSE_MOVE","MOUSE_UP","TOUCH_START","TOUCH_MOVE","TOUCH_END","WHEEL","RESIZE","CONTEXT_MENU","MOUSE_ENTER","MOUSE_LEAVE","POINTER_DOWN","POINTER_MOVE","POINTER_UP","POINTER_CANCEL","POINTER_ENTER","POINTER_LEAVE","KEY_DOWN","KEY_UP","LOAD","ERROR","CLICK","DOUBLE_CLICK","CONTEXT_CREATE_ERROR","CONTEXT_LOST","CONTEXT_RESTORED","DEVICE_ORIENTATION","DEVICE_MOTION","ORIENTATION_CHANGE","VIDEO_PLAY","VIDEO_PAUSE","VIDEO_LOADED_DATA","VIDEO_VOLUME_CHANGE","VIDEO_TIME_UPDATE","VIDEO_DURATION_CHANGE","VIDEO_CAN_PLAYTHROUGH","TRANSITION_END","XR_END","EL_DIV","EL_BUTTON","MOUSE_BUTTON","CURSOR","GRAB","GRABBING","NONE","KEY_DIRECTION","DIRECTION_KEY_CODE","SPACE_KEY_CODE","DIRECTION_KEY_NAME","LEFT","UP","RIGHT","DOWN","SPACE_KEY_NAME","FULLSCREEN_REQUEST","FULLSCREEN_ELEMENT","FULLSCREEN_EXIT","FULLSCREEN_CHANGE","DEFAULT_CLASS","CONTAINER","CANVAS","CTX_LOST","IN_VR","HOTSPOT_CONTAINER","HOTSPOT","HOTSPOT_VISIBLE","HOTSPOT_FLIP_X","HOTSPOT_FLIP_Y","READY","LOAD_START","PROJECTION_CHANGE","BEFORE_RENDER","RENDER","INPUT_START","INPUT_END","VIEW_CHANGE","STATIC_CLICK","VR_START","VR_END","EASING","LINEAR","x","SINE_WAVE","Math","sin","PI","EASE_OUT_CUBIC","pow","EASE_OUT_BOUNCE","n1","d1","CAMERA_EVENTS","CHANGE","ANIMATION_END","CONTROL_EVENTS","ENABLE","DISABLE","DEG_TO_RAD","RAD_TO_DEG","DEFAULT_EASING","DEFAULT_ANIMATION_DURATION","INFINITE_RANGE","min","Infinity","max","DEFAULT_PITCH_RANGE","DEFAULT_ZOOM_RANGE","ROTATE","VIDEO_TIME_CHANGE_EVENT","SVG_NAMESPACE","SESSION_VR","XR_REFERENCE_SPACE","EPSILON","_a","Number","isString","isElement","nodeType","Node","ELEMENT_NODE","createElement","className","tag","BROWSER","el","document","classList","add","getNullableElement","parent","targetEl","parentEl","queryResult","querySelector","getElement","findCanvas","root","selector","canvas","range","end","Array","apply","undef","idx","clamp","lerp","a","b","t","circulate","size","abs","offset","merge","target","srcs","forEach","source","keys","key","value","isArray","findIndex","array","checker","length","getObjectOption","toVerticalFov","fovRadian","aspect","atan","tan","reorderCube","arr","order","defaultOrder","split","face","indexOf","index","isFullscreen","sensorCanBeEnabledIOS","DeviceMotionEvent","window","isSecureContext","hfovToZoom","baseFov","fov","renderingWidth","zoomedWidth","eulerToQuat","out","yaw","pitch","roll","quat","identity","pitchThreshold","pitchClamped","rotateY","rotateX","rotateZ","quatToEuler","quaternion","y","z","w","x2","y2","z2","w2","unit","test","atan2","view","vec3","fromValues","up","transformQuat","viewXZ","sqrt","Motion","_val","start","_start","_end","progress","_progress","activated","_activated","duration","_duration","loop","_loop","_range","easing","_easing","reset","update","deltaTime","prev","nextProgress","easedProgress","defaultVal","delta","setNewEndByDelta","setRange","CameraAnimation","_motion","camera","from","to","_camera","_from","_to","_finishPromise","Promise","resolve","_finish","getFinishPromise","motion","rotation","create","zoom","slerp","rotate","Camera","Component","_aspect","changed","_changed","yawRange","_initialYawRange","pitchRange","_initialPitchRange","zoomRange","_initialZoomRange","initialYaw","initialPitch","initialZoom","rollOffset","position","animation","_up","_yawRange","_pitchRange","_zoomRange","_updateQuaternion","viewMatrix","mat4","projectionMatrix","_maxRenderHeight","destroy","off","resize","width","height","prevAspect","updateMatrix","lookAt","prevQuaternion","clone","prevZoom","zoomDiff","equals","normalized","normalize","isSameRotation","copy","animateTo","finishPromise","then","trigger","restrictYawRange","restrictPitchRange","restrictZoomRange","restrictRenderHeight","resetRange","getYawRange","yawLimit","maxRenderHeight","halfHFov","getHorizontalFov","minYaw","maxYaw","halfVFovRad","h","d","theta","getPitchRange","pitchLimit","minPitch","maxPitch","halfVFov","getVerticalFov","getZoomRange","limit","minFov","maxFov","currentFov","current","_getZoomedHorizontalFov","hFov","vFov","fovToZoom","projMatrix","upDir","viewDir","perspective","onFrameRender","MouseInput","_onMouseDown","evt","_el","button","preventDefault","focus","_prevPos","clientX","clientY","addEventListener","_onMouseMove","_onMouseUp","srcEvent","isTouch","isKeyboard","prevPos","deltaX","deltaY","removeEventListener","scrolling","enable","element","disable","TouchInput","scrollable","_scrollable","_onTouchStart","touches","_scrolling","touch","_isFirstTouch","_onTouchMove","cancelable","_onTouchEnd","passive","KeyboardInput","active","pressed","_pressed","_onKeyDown","location","KeyboardEvent","DOM_KEY_LOCATION_STANDARD","_updateKeyPress","pressedCount","_getPressedKeyCount","repeat","_onKeyUp","_clearPressedKeys","_getDeltaByPressedKeys","reduce","obj","keyName","assign","event","isEnable","keyToUpdate","keyCode","filter","RotateControl","enabled","_enabled","enableBlocked","_enableBlocked","animating","_keyboardInput","_xMotion","_yMotion","_touchInput","pointerScale","_pointerScale","keyboardScale","_keyboardScale","disablePitch","_disablePitch","disableYaw","_disableYaw","disableKeyboard","_disableKeyboard","controlEl","_onInputStart","_changedWhileDragging","inputType","_onChange","invZoomScale","_zoomScale","screenScale","_screenScale","scale","scaledX","scaledY","_onInputEnd","_controlEl","_mouseInput","_bindInputs","xMotion","yMotion","keyboardInput","updateRange","setZoomScale","hfov","vfov","control","updateCursor","sync","mouseInput","touchInput","on","WheelInput","_onWheel","stopPropagation","_inputTimer","_clearTimer","_baseScale","setTimeout","capture","clearTimeout","PinchInput","prevDistance","_prevDistance","diff","pageX","pageY","distance","ZoomControl","_wheelInput","_scale","scaledDelta","_pinchInput","wheelInput","pinchInput","ROTATE_CONSTANT","PITCH_DELTA","YAW_DELTA_BY_ROLL","YAW_DELTA_BY_YAW","targetAxis","meshPoint","GyroInput","orientationUpdated","_orientationUpdated","ignoreRoll","_ignoreRoll","_onDeviceOrientation","prevOrientation","_orientation","alpha","beta","gamma","_needsCalibrate","_calibrateSensor","_updateScreenOrientation","screen","orientation","angle","undefined","_screenOrientation","_yawOrigin","_yawOffset","_updateRotation","collectDelta","prevRotation","_toEulerDelta","setInitialRotation","yawOrigin","sensorYaw","screenAngle","world","set","cos","multiply","prevQuat","currentQuat","_getDeltaYaw","_getDeltaPitch","prvQ","curQ","yawDeltaByYaw","_getRotationDelta","yawDeltaByRoll","_extractPitchFromQuat","prevQ","rotateKind","curQuaternion","prevPoint","curPoint","rotateDistance","dot","cross","rotateDirection","meshPoint2","meshPoint3","vecU","vecV","vecN","coefficientA","coefficientB","coefficientC","projectedPrevPoint","subtract","trigonometricRatio","acos","crossVec","thetaDirection","deltaRadian","baseV","GyroControl","_input","isAvailable","onDeviceMotionChange","listenDeviceMotion","res","rotationRate","timeout","race","available","requestSensorPermission","requestPermission","permissionState","catch","_updateYawPitch","input","yawDelta","pitchDelta","PanoControl","useGrabCursor","_useGrabCursor","_setCursor","disableContextMenu","_disableContextMenu","_blockContextMenu","_restoreContextMenu","_rotateControl","wheelScrollable","_zoomControl","ignoreZoomScale","_ignoreZoomScale","gyro","_gyroControl","_preventContextMenu","_onEnable","_onDisable","_onCameraAnimationEnd","_bindEvents","rotateControl","zoomControl","gyroControl","zoomScale","newCursor","style","cursor","Texture","flipY","wrapS","WebGLRenderingContext","CLAMP_TO_EDGE","wrapT","isVideo","isCube","Texture2D","TextureVideo","video","pause","removeAttribute","load","isPaused","paused","ended","readyState","hasAudio","audioTracks","webkitAudioDecodedByteCount","mozHasAudio","TextureCube","sources","TextureLoader","_loadChecker","ImReady","src","loadVideo","loadCubeImage","imgSrc","loadImage","images","_toImageArray","_load","image","naturalWidth","naturalHeight","videoConfig","config","autoplay","muted","volume","_toVideoElement","currentTime","play","videoWidth","videoHeight","content","onLoad","loader","reject","once","errorCount","check","imgEl","Image","crossOrigin","HTMLVideoElement","playsInline","setAttribute","_appendSourceElement","sourceCount","querySelectorAll","HTMLSourceElement","sourceEl","appendChild","FrameAnimator","maxDeltaTime","context","_context","_rafId","_rafTimer","_lastUpdateTime","callback","_time","frame","time","Date","now","requestAnimationFrame","stop","cancelAnimationFrame","changeContext","AutoResizer","useResizeObserver","_useResizeObserver","onResize","_skipFirstResize","isFirstResize","_onResize","_resizeObserver","ResizeObserver","bbox","getBoundingClientRect","resizeImmediate","resizeObserver","observe","disconnect","Autoplay","playing","_interrupted","delay","_delay","delayOnMouseLeave","_delayOnMouseLeave","speed","_speed","pauseOnHover","_pauseOnHover","canInterrupt","_canInterrupt","disableOnInterrupt","_disableOnInterrupt","viewer","options","_clearTimeout","_setUninterruptedAfterDelay","_onGyroEnable","_onMouseEnter","_hovering","_onMouseLeave","_control","_element","_interruptionTimer","enableAfterDelay","XRManager","ctx","exit","_onSessionEnd","_xrSession","_xrRefSpace","_ctx","_options","xr","navigator","isSessionSupported","enter","requiredFeatures","makeXRCompatible","session","requestSession","bindXRLayer","refSpace","requestReferenceSpace","_setSession","xrSession","canRender","pose","getViewerPose","getEyeParams","glLayer","renderState","baseLayer","views","viewport","getViewport","vMatrix","transform","inverse","matrix","pMatrix","Hotspot","HotspotRenderer","rootEl","renderer","_containerEl","_renderer","_hotspots","_zoom","refresh","container","hotspotEls","slice","_parseHotspot","render","hotspots","halfWidth","halfHeight","centerTransform","zoomTransform","hotspot","relPos","transformMat4","remove","screenPos","vec2","yawStr","dataset","pitchStr","positionStr","parseFloat","_yawPitchToVec3","pos","defaultPos","yawRad","pitchRad","VertexArrayObject","count","geometry","indicies","buffers","WebGLContext","_canvas","maxTextureSize","_maxTextureSize","isWebGL2","_isWebGL2","supportVAO","_extensions","vao","lost","_contextLost","debug","_debug","_onContextLost","_onContextRestore","loseContext","init","gl","_getContext","_gl","getParameter","MAX_TEXTURE_SIZE","getExtension","bindBuffer","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","forceLoseContext","extension","forceRestoreContext","restoreContext","clear","COLOR_BUFFER_BIT","drawingBufferWidth","drawingBufferHeight","createVAO","shaderProgram","nativeVAO","_createNativeVAO","_createBuffer","uv","_bindNativeVAO","_supplyGeometryData","_unbindBuffers","draw","drawElements","TRIANGLES","UNSIGNED_SHORT","releaseVAO","_deleteNativeVAO","_deleteBuffer","getUniformLocations","program","uniforms","uniformLocations","locations","getUniformLocation","_getCommonUniformLocations","updateCommonUniforms","entity","mvMatrix","uniformMatrix4fv","uMVMatrix","uPMatrix","updateVRUniforms","eyeIndex","uEye","uniform1f","updateUniforms","uniform","needsUpdate","releaseShaderResources","deleteProgram","useProgram","createProgram","vertexShader","fragmentShader","vs","_compileShader","VERTEX_SHADER","fs","FRAGMENT_SHADER","attachShader","bindAttribLocation","linkProgram","getProgramParameter","LINK_STATUS","getShaderParameter","COMPILE_STATUS","getShaderInfoLog","getProgramInfoLog","deleteShader","createWebGLTexture","texData","texture","createTexture","bindTexture","TEXTURE_2D","texParameteri","TEXTURE_MIN_FILTER","TEXTURE_MAG_FILTER","TEXTURE_WRAP_S","TEXTURE_WRAP_T","gl2","texStorage2D","RGBA8","createWebGLCubeTexture","TEXTURE_CUBE_MAP","attributes","getContextAttributes","xrCompatible","xrLayer","XRWebGLLayer","updateRenderState","bindXRFrame","bindFramebuffer","FRAMEBUFFER","framebuffer","useDefaultFrameBuffer","createBuffer","buffer","deleteBuffer","createVertexArray","ext","createVertexArrayOES","bindVertexArray","bindVertexArrayOES","deleteVertexArray","deleteVertexArrayOES","_supplyIndiciesData","_supplyAttributeData","vertices","uvs","bufferData","data","STATIC_DRAW","attribute","attribLocation","getAttribLocation","vertexAttribPointer","itemSize","FLOAT","enableVertexAttribArray","shader","createShader","shaderSource","compileShader","webglIdentifiers","contextAttributes","preserveDrawingBuffer","antialias","onWebglContextCreationError","e","statusMessage","identifier","getContext","WebGLRenderer","_elementSize","pixelRatio","_pixelRatio","canvasSize","devicePixelRatio","clientWidth","clientHeight","projection","mesh","getMesh","renderVR","vr","eyeParams","eye","View360","_rootEl","_vr","_hotspot","plugins","_plugins","_projection","_initialized","initialized","_autoplay","autoInit","_autoInit","autoResize","_autoResize","canvasSelector","_canvasSelector","tabIndex","_tabIndex","_animator","updateCamera","renderFrame","autoPlayer","_emit","_renderFrameOnDemand","getTexture","_renderVRFrame","_delta","_autoResizer","_addEventHandlers","releaseAllResources","plugin","animator","_bindComponentEvents","_resizeComponents","_loadTexture","_applyProjection","hasAttribute","addPlugins","push","removePlugins","pluginIdx","splice","eventName","params","evtParams","prevProjection","applyTexture","updateControl","contentLoader","events","evtName","controlEventsToPropagate","VERSION","Object3D","fromRotationTranslationScale","LoadingSpinner","_startLoading","_container","_detachElements","parentElement","removeChild","_createElements","ring","RING","ControlBarItem","CONTROL_BAR_DEFAULT_CLASS","CONTROLS_ROOT","CONTROLS_BG","CONTROLS_MAIN","CONTROLS_TOP","CONTROLS_BOTTOM","CONTROLS_MID","CONTROLS_LEFT","CONTROLS_RIGHT","CONTROLS_FLOAT_LEFT","CONTROLS_FLOAT_RIGHT","CONTROLS_BUTTON","PROGRESS_ROOT","VOLUME_ROOT","RANGE_ROOT","RANGE_TRACK","RANGE_THUMB","RANGE_FILLER","PLAY_BUTTON","PAUSE_BUTTON","UNMUTED_BUTTON","MUTED_BUTTON","FULLSCREEN_BUTTON","FULLSCREEN_EXIT_BUTTON","VR_BUTTON","GYRO_ENABLED","GYRO_DISABLED","VIDEO_TIME_DISPLAY","PIEVIEW_ROOT","FIXED","UNAVAILABLE","HIDDEN","CONTROL_BAR_ITEM_POSITION","TOP_LEFT","TOP_RIGHT","MAIN_TOP","MAIN_BOTTOM","MAIN_LEFT","MAIN_RIGHT","RangeControl","_onHold","_bbox","elX","scrollX","pageXOffset","clamepdX","thumbEl","_fixedClass","clampedX","_onRelease","track","thumb","filler","draggable","trackEl","fillerEl","left","right","bottom","top","updateStyle","clampedProgress","ProgressBar","_rangeControl","_onTimeUpdate","_video","_currentTime","_onDurationChange","controlBar","_controlBar","dispatchEvent","CustomEvent","detail","_wasPaused","_playPromise","_onControl","rangeControl","unavailableClass","PlayButton","_onClick","_paused","_onPlay","title","_onPause","VolumeControl","_updateDisplay","disabled","_onVolumeChange","_buttonEl","containerEl","buttonEl","FullscreenButton","_targetEl","_exitFullscreen","_requestFullscreen","_onFullscreenChange","_fullscreenAvailable","_addFullscreenHandlers","_removeFullscreenHandlers","some","request","call","VideoTime","_onCustomTimeChange","timeMinute","floor","timeSeconds","timeSecondsFormatted","durationMinute","durationSeconds","durationSecondsFormatted","innerText","PieView","resetCamera","_viewer","_updatePie","piePath","_piePathEl","rangeCircle","_rangeCircleEl","halfFov","pieRadius","pieDeg","pieOffset","isFinite","radius","rangeDiff","_createPieElements","rootClass","pieSVG","createElementNS","VRButton","GyroButton","_updateStyle","enableButton","AutoHide","hidden","contains","_hiddenClass","initialDelay","idleDelay","activationDelay","_isCursorInside","show","_hideAfterDelay","_isFullscreen","showTemporaliy","_isGrabbing","pointerType","_onVideoPlay","_onVideoPause","_initialDelay","_idleDelay","_timer","hide","_clearHideTimer","VideoControl","videoEl","keyPressed","_changeVideoTime","_changeVideoVolume","spacePressed","_toggleVideo","forward","increase","ControlBar","backgroundEl","_bgEl","items","_items","customItems","_customItems","autoHide","showBackground","clickToPlay","keyboardControls","progressBar","playButton","volumeButton","fullscreenButton","videoTime","pieView","vrButton","gyroButton","_onStaticClick","autoHider","_autoHider","_onNewSrcLoad","_updateBackground","_updateAutoHide","_updateKeyboardHandler","category","item","_createPositionWrappers","POSITION","_videoControl","panoRoot","controlsRoot","defaultItems","_createDefaultItems","_addItem","_clearItemElements","wrapper","_wrapperEl","nextSiblingIndex","sibling","nextSibling","insertBefore","floatLeftEl","floatRightEl","topWrapper","bottomWrapper","midWrapper","leftControlsWrapper","rightControlsWrapper","wrappers","firstChild","background","hiddenClass","_b","videoControl","Projection","_mesh","uTexture","Uniform","UniformTextureCube","cubemapOrder","_webglTexture","_cubemapOrder","deleteTexture","pixelStorei","UNPACK_FLIP_Y_WEBGL","uniform1i","activeTexture","TEXTURE0","texSubImage2D","TEXTURE_CUBE_MAP_POSITIVE_X","RGBA","UNSIGNED_BYTE","texImage2D","CubeTexturePainter","_size","_renderingOrder","_calcRenderingSize","surfaceIdx","row","_row","column","_column","renderingFace","drawImage","UniformCanvasCube","_painter","TriangleMesh","ShaderProgram","VertexData","Geometry","Float32Array","Uint16Array","CubeGeometry","rotateUV","oneThird","coords","r","c","coord","degree","ZERO","newOrder","CW_90","CCW_90","newCoords","uvIdx","acc","concat","CubemapProjection","cubemapFlipX","_cubemapFlipX","UniformTexture2D","CubestripProjection","CylinderGeometry","maxTheta","radialSegments","heightSegments","invRadialSegments","angleConst","yIdx","lngIdx","u","v","CylindricalProjection","partial","_partial","cylinderHeight","cylinderTheta","restrictedYaw","restrictedPitch","minZoom","EquiangularProjection","SphereGeometry","widthSegments","ANGLE_CORRECTION_FOR_CENTER_ALIGN","latIdx","sinTheta","cosTheta","phi","sinPhi","cosPhi","EquirectProjection","UniformFloat","PlaneGeometry","LittlePlanetProjection","REPEAT","uYaw","uPitch","uZoom","UniformVector4Array","uniform4fv","vector","StereoEquiProjection","_mode","mode","leftEye","rightEye","MODE","LEFT_RIGHT","uTexScaleOffset","TOP_BOTTOM","withMethods","attr","proto","getOwnPropertyNames","charAt","descriptor","getOwnPropertyDescriptor","defineProperty","args","getterDescriptor","get","getValidProps","propsObj","props","propName","VIEW360_METHODS","modules"],"mappings":"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"} \ No newline at end of file diff --git a/demo/release/4.0.0-beta.4/dist/view360.min.js b/demo/release/4.0.0-beta.4/dist/view360.min.js new file mode 100644 index 000000000..734ac56a5 --- /dev/null +++ b/demo/release/4.0.0-beta.4/dist/view360.min.js @@ -0,0 +1,2 @@ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("@egjs/component"),require("gl-matrix"),require("@egjs/imready")):"function"==typeof define&&define.amd?define(["@egjs/component","gl-matrix","@egjs/imready"],e):(t="undefined"!=typeof globalThis?globalThis:t||self).View360=e(t.Component,t.glMatrix,t.eg.ImReady)}(this,(function(t,e,i){"use strict";function s(t){return t&&t.__esModule?t:{default:t}}var n=s(t),o=s(i);function r(t,e,i,s){return new(i||(i=Promise))((function(n,o){function r(t){try{h(s.next(t))}catch(t){o(t)}}function a(t){try{h(s.throw(t))}catch(t){o(t)}}function h(t){var e;t.done?n(t.value):(e=t.value,e instanceof i?e:new i((function(t){t(e)}))).then(r,a)}h((s=s.apply(t,e||[])).next())}))}class a extends Error{constructor(t,e){super(t),Object.setPrototypeOf(this,a.prototype),this.name="View360Error",this.code=e}}const h={WRONG_TYPE:0,WRONG_OPTION:1,ELEMENT_NOT_FOUND:2,CANVAS_NOT_FOUND:3,WEBGL_NOT_SUPPORTED:4,FAILED_CREATE_CONTEXT_2D:5,PROVIDE_PROJECTION_FIRST:6,FAILED_LINKING_PROGRAM:7,INSUFFICIENT_ARGS:8};var l=h,c={WRONG_TYPE:(t,e)=>`${typeof t} is not a ${e.map((t=>`"${t}"`)).join(" or ")}.`,WRONG_OPTION:(t,e)=>`Bad option: given "${t}" for option "${e}".`,ELEMENT_NOT_FOUND:t=>`Element with selector "${t}" not found.`,CANVAS_NOT_FOUND:"The canvas element was not found inside the given root element.",WEBGL_NOT_SUPPORTED:"WebGL is not supported on this browser.",FAILED_CREATE_CONTEXT_2D:"Failed to create canvas 2D context",PROVIDE_PROJECTION_FIRST:'"projection" should be provided before initialization.',FAILED_LINKING_PROGRAM:(t,e)=>`Failed linking WebGL program - "${t}\nShader compile Log: ${e}`,INSUFFICIENT_ARGS:(t,e)=>`Insufficient arguments: given "${t}" for "${e}".`};const u="mousedown",_="mousemove",d="mouseup",m="touchstart",p="touchmove",g="touchend",v="wheel",E="resize",T="contextmenu",b="mouseenter",f="mouseleave",R="keydown",y="keyup",w="click",L="webglcontextcreationerror",C="webglcontextlost",x="webglcontextrestored",O="deviceorientation",I="devicemotion",A="orientationchange",S="play",P="pause",N="loadeddata",M="volumechange",D="timeupdate",U="durationchange",B="canplaythrough",F="transitionend",z="end",V="div",G="button";var k;!function(t){t[t.LEFT=0]="LEFT",t[t.MIDDLE=1]="MIDDLE",t[t.RIGHT=2]="RIGHT"}(k||(k={}));const Y="grab",H="grabbing",X="",j=["LEFT","UP","RIGHT","DOWN"];var W;!function(t){t[t.LEFT=37]="LEFT",t[t.UP=38]="UP",t[t.RIGHT=39]="RIGHT",t[t.DOWN=40]="DOWN"}(W||(W={}));const q={LEFT:"ArrowLeft",UP:"ArrowUp",RIGHT:"ArrowRight",DOWN:"ArrowDown"},K=["requestFullscreen","webkitRequestFullscreen","webkitRequestFullScreen","webkitCancelFullScreen","mozRequestFullScreen","msRequestFullscreen"],Z=["fullscreenElement","webkitFullscreenElement","webkitCurrentFullScreenElement","mozFullScreenElement","msFullscreenElement"],$=["exitFullscreen","webkitExitFullscreen","webkitCancelFullScreen","mozCancelFullScreen","msExitFullscreen"],Q=["fullscreenchange","webkitfullscreenchange","mozfullscreenchange","MSFullscreenChange"],J={CONTAINER:"view360-container",CANVAS:"view360-canvas",CTX_LOST:"view360-ctx-lost",IN_VR:"view360-vr-presenting",HOTSPOT_CONTAINER:"view360-hotspots",HOTSPOT:"view360-hotspot",HOTSPOT_VISIBLE:"view360-hotspot-visible",HOTSPOT_FLIP_X:"view360-hotspot-flip-x",HOTSPOT_FLIP_Y:"view360-hotspot-flip-y"},tt={READY:"ready",LOAD_START:"loadStart",LOAD:"load",PROJECTION_CHANGE:"projectionChange",RESIZE:"resize",BEFORE_RENDER:"beforeRender",RENDER:"render",INPUT_START:"inputStart",INPUT_END:"inputEnd",VIEW_CHANGE:"viewChange",STATIC_CLICK:"staticClick",VR_START:"vrStart",VR_END:"vrEnd"},et={LINEAR:t=>t,SINE_WAVE:t=>Math.sin(t*Math.PI*2),EASE_OUT_CUBIC:t=>1-Math.pow(1-t,3),EASE_OUT_BOUNCE:t=>{const e=7.5625,i=2.75;return t<1/i?e*t*t:t<2/i?e*(t-=1.5/i)*t+.75:t<2.5/i?e*(t-=2.25/i)*t+.9375:e*(t-=2.625/i)*t+.984375}};var it;const st="animationEnd",nt="inputStart",ot="change",rt="inputEnd",at="enable",ht="disable",lt="staticClick",ct=Math.PI/180,ut=180/Math.PI,_t=et.EASE_OUT_CUBIC,dt=300,mt={min:-1/0,max:1/0},pt={min:-90,max:90},gt={min:.6,max:10};var vt;!function(t){t[t.ZERO=0]="ZERO",t[t.CW_90=1]="CW_90",t[t.CCW_90=2]="CCW_90",t[t.CW_180=3]="CW_180"}(vt||(vt={}));const Et="view360videotimechange",Tt="http://www.w3.org/2000/svg",bt="immersive-vr",ft="local",Rt=null!==(it=Number.EPSILON)&&void 0!==it?it:2220446049250313e-31,yt=t=>"string"==typeof t,wt=(t,e=V)=>{const i=document.createElement(e);return i.classList.add(t),i},Lt=(t,e)=>{let i=null;if(yt(t)){const s=(e||document).querySelector(t);if(!s)return null;i=s}else(s=t)&&s.nodeType===Node.ELEMENT_NODE&&(i=t);var s;return i},Ct=(t,e,i)=>Math.max(Math.min(t,i),e),xt=(t,e,i)=>t*(1-i)+e*i,Ot=(t,e,i)=>{const s=Math.abs(i-e);if(ti){t=e+(t-i)%s}return t},It=(t,e)=>{for(let i=0;i"object"==typeof t?t:{},St=(t,e)=>2*Math.atan(Math.tan(.5*t)/e),Pt=(t,e,i="RLUDFB")=>i.split("").map((t=>e.indexOf(t))).map((e=>t[e])),Nt=()=>{if(!document)return!1;for(const t of Z)if(document[t])return!0;return!1},Mt=()=>!!DeviceMotionEvent&&"requestPermission"in DeviceMotionEvent&&window.isSecureContext,Dt=(t,i,s,n)=>{e.quat.identity(t);const o=Ct(s,-89.99,89.99);return e.quat.rotateY(t,t,i*ct),e.quat.rotateX(t,t,o*ct),e.quat.rotateZ(t,t,n*ct),t},Ut=t=>{const i=t[0],s=t[1],n=t[2],o=t[3],r=i*i+s*s+n*n+o*o,a=i*o-s*n;let h,l;if(a>.499995*r)h=Math.PI/2,l=2*Math.atan2(s,i);else if(a<-.499995*r)h=-Math.PI/2,l=-2*Math.atan2(s,i);else{const i=e.vec3.fromValues(0,0,1),s=e.vec3.fromValues(0,1,0);e.vec3.transformQuat(i,i,t),e.vec3.transformQuat(s,s,t);const n=Math.sqrt(i[0]*i[0]+i[2]*i[2]);h=Math.atan2(-i[1],n),l=Math.atan2(i[0],i[2])}return{pitch:Ct(h*ut,-90,90),yaw:Ot(l*ut,0,360)}};class Bt{get val(){return this._val}get start(){return this._start}get end(){return this._end}get progress(){return this._progress}get activated(){return this._activated}get duration(){return this._duration}set duration(t){this._duration=t}get loop(){return this._loop}set loop(t){this._loop=t}get range(){return this._range}get easing(){return this._easing}set easing(t){this._easing=t}constructor({duration:t=300,loop:e=!1,range:i={min:0,max:1},easing:s=_t}={}){this._duration=t,this._loop=e,this._range=i,this._easing=s,this._activated=!1,this.reset(0)}update(t){if(!this._activated)return this._val=this._end,0;const e=this._start,i=this._end,s=this._duration,n=this._val,o=this._loop,r=this._progress+t/s;this._progress=o?Ot(r,0,1):Ct(r,0,1);const a=this._easing(this._progress);return this._val=xt(e,i,a),!o&&this._progress>=1&&(this._activated=!1),this._val-n}reset(t){const e=this._range,i=Ct(t,e.min,e.max);this._start=i,this._end=i,this._val=i,this._progress=0,this._activated=!1}add(t){const e=this._range;this._start=Ct(this._start+t,e.min,e.max),this._end=Ct(this._end+t,e.min,e.max),this._val=Ct(this._val+t,e.min,e.max)}setNewEndByDelta(t){const e=this._range;this._start=this._val,this._end=Ct(this._end+t,e.min,e.max),this._progress=0,this._activated=!0}setRange(t,e){this._start=Ct(this._start,t,e),this._end=Ct(this._end,t,e),this._range={min:t,max:e}}}class Ft{get duration(){return this._motion.duration}set duration(t){this._motion.duration=t}get easing(){return this._motion.easing}set easing(t){this._motion.easing=t}constructor(t,e,i,{duration:s=300,easing:n=_t}={}){this._camera=t,this._motion=new Bt({duration:s,easing:n,range:{min:0,max:1}}),this._from=e,this._to=i,this._finishPromise=new Promise((t=>{this._finish=t})),this._motion.setNewEndByDelta(1)}getFinishPromise(){return this._finishPromise}update(t){const i=this._camera,s=this._from,n=this._to,o=this._motion;o.update(t);const r=o.val,a=e.quat.create(),h=xt(s.zoom,n.zoom,r);e.quat.slerp(a,s.rotation,n.rotation,r),i.rotate(a,h),r>=1&&this._finish()}}class zt extends n.default{get aspect(){return this._aspect}get changed(){return this._changed}get yawRange(){return this._initialYawRange}set yawRange(t){this._initialYawRange=t}get pitchRange(){return this._initialPitchRange}set pitchRange(t){this._initialPitchRange=t}get zoomRange(){return this._initialZoomRange}set zoomRange(t){this._initialZoomRange=t}constructor({initialYaw:t,initialPitch:i,initialZoom:s,yawRange:n,pitchRange:o,zoomRange:r,fov:a}){super(),this.yaw=t,this.pitch=i,this.zoom=s,this.rollOffset=0,this.initialYaw=t,this.initialPitch=i,this.initialZoom=s,this.position=e.vec3.create(),this.animation=null,this._up=e.vec3.fromValues(0,1,0),this._aspect=1,this._initialYawRange=n,this._initialPitchRange=o,this._initialZoomRange=r,this._yawRange=n,this._pitchRange=o,this._zoomRange=r,this.quaternion=e.quat.create(),this._updateQuaternion(),this.viewMatrix=e.mat4.create(),this.projectionMatrix=e.mat4.create(),this.fov=a,this._maxRenderHeight=-1}destroy(){this.off()}resize(t,e){const i=this._aspect;this._aspect=t/e,this._aspect!==i&&this.updateMatrix()}lookAt({yaw:t=this.yaw,pitch:i=this.pitch,zoom:s=this.zoom}){const n=e.quat.clone(this.quaternion),o=this.zoom;this.yaw=Ot(t,0,360),this.pitch=Ct(i,-90,90),this.zoom=s,this._updateQuaternion();const r=Math.abs(s-o);(!e.quat.equals(this.quaternion,n)||r>=10*Rt)&&this.updateMatrix()}rotate(t,i=this.zoom){const s=e.quat.normalize(e.quat.create(),t),n=e.quat.equals(this.quaternion,s);e.quat.copy(this.quaternion,s);const o=this.zoom,{yaw:r,pitch:a}=Ut(s);this.yaw=r,this.pitch=a,this.zoom=i;const h=Math.abs(i-o);(!n||h>=10*Rt)&&this.updateMatrix()}animateTo({yaw:t=this.yaw,pitch:i=this.pitch,zoom:s=this.zoom,duration:n=0,easing:o=_t}={}){return r(this,void 0,void 0,(function*(){if(this.yaw===t&&this.pitch===i&&this.zoom===s)return;const r={rotation:e.quat.clone(this.quaternion),zoom:this.zoom},a={rotation:Dt(e.quat.create(),t,i,this.rollOffset),zoom:s},h=new Ft(this,r,a,{duration:n,easing:o}),l=h.getFinishPromise();return this.animation=h,l.then((()=>{this.animation=null,this.trigger(st,{animation:h})})),l}))}restrictYawRange(t,e){this._yawRange={min:t,max:e}}restrictPitchRange(t,e){this._pitchRange={min:t,max:e}}restrictZoomRange(t,e){this._zoomRange={min:t,max:e}}restrictRenderHeight(t){this._maxRenderHeight=t}resetRange(){this._yawRange=this._initialYawRange,this._pitchRange=this._initialPitchRange,this._zoomRange=this._initialZoomRange,this._maxRenderHeight=-1}getYawRange(t){const e=this._yawRange,i=this._maxRenderHeight;if(!e)return mt;const s=.5*this.getHorizontalFov(t);let n=e.min,o=e.max;if(i>0){const t=St(s*ct,this._aspect),r=.5*i,a=Math.tan(t),h=Math.sqrt((1+r*r)/(1+a*a)),l=Math.atan(Math.tan(s*ct)*h)*ut;n=e.min+l,o=e.max-l}return n>o&&(n=0,o=0),{min:n,max:o}}getPitchRange(t){const e=this._pitchRange,i=this._maxRenderHeight;if(!e)return pt;let s=e.min,n=e.max;if(i>0){const i=.5*this.getVerticalFov(t);s=e.min+i,n=e.max-i}return s>n&&(s=0,n=0),{min:Math.max(s,-90),max:Math.min(n,90)}}getZoomRange(){var t;const e=null!==(t=this._zoomRange)&&void 0!==t?t:gt,i=this.getHorizontalFov(e.max),s=this.getHorizontalFov(e.min),n=this.getHorizontalFov(this.zoom);return{min:Math.max(i,1),max:Math.min(s,180),current:n}}getHorizontalFov(t=this.zoom){return this._getZoomedHorizontalFov(t)*ut}getVerticalFov(t=this.zoom){const e=this._aspect,i=this._getZoomedHorizontalFov(t);return St(i,e)*ut}fovToZoom(t){const e=this.fov;return Math.tan(ct*e*.5)/Math.tan(ct*t*.5)}updateMatrix(){const t=this._up,i=this._aspect,s=this.viewMatrix,n=this.projectionMatrix,o=this.position,r=this.quaternion,a=e.vec3.create(),h=e.vec3.fromValues(0,0,-1);e.vec3.transformQuat(h,h,r),e.vec3.transformQuat(a,t,r);const l=this._getZoomedHorizontalFov(),c=St(l,i);e.mat4.lookAt(s,o,h,a),e.mat4.perspective(n,c,i,.1,100),this._changed=!0}onFrameRender(){this._changed=!1}_updateQuaternion(){Dt(this.quaternion,this.yaw,this.pitch,this.rollOffset)}_getZoomedHorizontalFov(t=this.zoom){return 2*Math.atan(Math.tan(ct*this.fov*.5)/t)}}class Vt extends n.default{constructor(){super(),this._onMouseDown=t=>{const e=this._el;e&&t.button===k.LEFT&&(t.preventDefault(),e.focus?e.focus():window.focus(),this._prevPos[0]=t.clientX,this._prevPos[1]=t.clientY,window.addEventListener(_,this._onMouseMove,!1),window.addEventListener(d,this._onMouseUp,!1),this.trigger(nt,{srcEvent:t,isTouch:!1,isKeyboard:!1}))},this._onMouseMove=t=>{t.preventDefault();const e=t.clientX,i=t.clientY,s=this._prevPos,n=e-s[0],o=i-s[1];this.trigger(ot,{delta:{x:n,y:o},isTouch:!1,isKeyboard:!1}),s[0]=e,s[1]=i},this._onMouseUp=()=>{this._prevPos[0]=0,this._prevPos[1]=0,window.removeEventListener(_,this._onMouseMove,!1),window.removeEventListener(d,this._onMouseUp,!1),this.trigger(rt,{isTouch:!1,isKeyboard:!1,scrolling:!1})},this._el=null,this._prevPos=[0,0]}enable(t){this._el||(t.addEventListener(u,this._onMouseDown),this._el=t)}disable(){const t=this._el;t&&(t.removeEventListener(u,this._onMouseDown),window.removeEventListener(_,this._onMouseMove,!1),window.removeEventListener(d,this._onMouseUp,!1),this._el=null)}}class Gt extends n.default{get scrollable(){return this._scrollable}set scrollable(t){this._scrollable=t}constructor(){super(),this._onTouchStart=t=>{if(t.touches.length>1||this._scrolling)return;const e=t.touches[0];this._isFirstTouch=!0,this._prevPos[0]=e.clientX,this._prevPos[1]=e.clientY,this.trigger(nt,{srcEvent:t,isTouch:!0,isKeyboard:!1})},this._onTouchMove=t=>{if(t.touches.length>1||this._scrolling)return;const e=t.touches[0],i=this._scrollable,s=this._prevPos,n=e.clientX,o=e.clientY,r=n-s[0],a=o-s[1];if(this._isFirstTouch){if(i&&!Nt()&&Math.abs(a)>Math.abs(r))return void(this._scrolling=!0);this._isFirstTouch=!1}!1!==t.cancelable&&t.preventDefault(),this.trigger(ot,{delta:{x:r,y:a},isTouch:!0,isKeyboard:!1}),s[0]=n,s[1]=o},this._onTouchEnd=t=>{if(0!==t.touches.length)return;const e=t.touches[0],i=this._prevPos;e?(i[0]=e.clientX,i[1]=e.clientY):(i[0]=0,i[1]=0,this.trigger(rt,{isTouch:!0,isKeyboard:!1,scrolling:this._scrolling})),!1!==t.cancelable&&t.preventDefault(),this._scrolling=!1},this._el=null,this._prevPos=[0,0],this._isFirstTouch=!1,this._scrolling=!1,this._scrollable=!1}enable(t){this._el||(t.addEventListener(m,this._onTouchStart,{passive:!1}),t.addEventListener(p,this._onTouchMove,{passive:!1}),t.addEventListener(g,this._onTouchEnd),this._el=t)}disable(){const t=this._el;t&&(t.removeEventListener(m,this._onTouchStart),t.removeEventListener(p,this._onTouchMove),t.removeEventListener(g,this._onTouchEnd),this._el=null)}}class kt extends n.default{get active(){const t=this._pressed;return t.LEFT||t.UP||t.RIGHT||t.DOWN}constructor(){super(),this._onKeyDown=t=>{if(t.location!==KeyboardEvent.DOM_KEY_LOCATION_STANDARD)return;this._updateKeyPress(t,!0);const e=this._getPressedKeyCount();e<=0||(t.preventDefault(),1!==e||t.repeat||this.trigger(nt,{srcEvent:t,isTouch:!1,isKeyboard:!0}))},this._onKeyUp=t=>{if(t.location!==KeyboardEvent.DOM_KEY_LOCATION_STANDARD)return;this._updateKeyPress(t,!1);this._getPressedKeyCount()>0||this.trigger(rt,{isTouch:!1,isKeyboard:!0,scrolling:!1})},this._el=null,this._clearPressedKeys()}enable(t){this._el||(t.addEventListener(R,this._onKeyDown),t.addEventListener(y,this._onKeyUp),this._el=t,this._clearPressedKeys())}disable(){const t=this._el;t&&(t.removeEventListener(R,this._onKeyDown),t.removeEventListener(y,this._onKeyUp),this._el=null,this._clearPressedKeys())}update(){const t=this._getDeltaByPressedKeys();0===t.x&&0===t.y||this.trigger(ot,{delta:t,isTouch:!1,isKeyboard:!0})}_clearPressedKeys(){this._pressed=j.reduce(((t,e)=>Object.assign(Object.assign({},t),{[e]:!1})),{})}_updateKeyPress(t,e){const i=this._pressed,s=null!=t.keyCode?W[t.keyCode]:q[t.key];s&&(i[s]=e)}_getPressedKeyCount(){return j.filter((t=>this._pressed[t])).length}_getDeltaByPressedKeys(){const t=this._pressed;let e=0,i=0;return t.LEFT&&(e+=1),t.RIGHT&&(e-=1),t.UP&&(i+=1),t.DOWN&&(i-=1),{x:e,y:i}}}class Yt extends n.default{get enabled(){return this._enabled}get enableBlocked(){return this._enableBlocked}get animating(){return this._keyboardInput.active||this._xMotion.activated||this._yMotion.activated}get yaw(){return this._xMotion}get pitch(){return this._yMotion}get scrollable(){return this._touchInput.scrollable}set scrollable(t){this._touchInput.scrollable=t}get pointerScale(){return this._pointerScale}set pointerScale(t){this._pointerScale=t}get keyboardScale(){return this._keyboardScale}set keyboardScale(t){this._keyboardScale=t}get duration(){return this._duration}set duration(t){this._duration=t,this._xMotion.duration=t,this._yMotion.duration=t}get easing(){return this._easing}set easing(t){this._easing=t,this._xMotion.easing=t,this._yMotion.easing=t}get disablePitch(){return this._disablePitch}set disablePitch(t){this._disablePitch=t}get disableYaw(){return this._disableYaw}set disableYaw(t){this._disableYaw=t}get disableKeyboard(){return this._disableKeyboard}set disableKeyboard(t){this._disableKeyboard=t}constructor(t,e,{duration:i=300,easing:s=_t,pointerScale:n=[1,1],keyboardScale:o=[1,1],disablePitch:r=!1,disableYaw:a=!1,disableKeyboard:h=!1}={}){super(),this._onInputStart=t=>{this._changedWhileDragging=!1,this.trigger(nt,Object.assign(Object.assign({},t),{inputType:"rotate"}))},this._onChange=t=>{const e=t.delta,i=1/this._zoomScale,s=this._screenScale,n=this._keyboardScale,o=this._pointerScale;let r;r=t.isKeyboard?[n[0]*i,n[1]*i]:[o[0]*s[0]*i,o[1]*s[1]*i];const a=e.x*r[0],h=e.y*r[1];this._xMotion.setNewEndByDelta(a),this._yMotion.setNewEndByDelta(h),this._changedWhileDragging=!0},this._onInputEnd=t=>{this.trigger(rt,Object.assign(Object.assign({},t),{inputType:"rotate"})),this._changedWhileDragging||t.isKeyboard||t.scrolling||this.trigger(lt,{isTouch:t.isTouch}),this._changedWhileDragging=!1},this._controlEl=t,this._pointerScale=n,this._keyboardScale=o,this._duration=i,this._easing=s,this._disablePitch=r,this._disableYaw=a,this._disableKeyboard=h,this._enableBlocked=e,this._mouseInput=new Vt,this._touchInput=new Gt,this._keyboardInput=new kt,this._xMotion=new Bt({duration:i,range:mt,easing:s}),this._yMotion=new Bt({duration:i,range:pt,easing:s}),this._screenScale=[1,1],this._zoomScale=1,this._enabled=!1,this._changedWhileDragging=!1,this._bindInputs()}destroy(){this.disable(),this._mouseInput.off(),this._touchInput.off(),this._keyboardInput.off(),this.off(),this._changedWhileDragging=!1}update(t){if(!this._enabled)return;const e=this._xMotion,i=this._yMotion,s=this._keyboardInput;this._disableKeyboard||s.update(),this._disablePitch||i.update(t),this._disableYaw||e.update(t)}updateRange(t,e){const i=t.getYawRange(e),s=t.getPitchRange(e);this._xMotion.setRange(i.min,i.max),this._yMotion.setRange(s.min,s.max)}setZoomScale(t){this._zoomScale=t}resize(t,e,i,s){const n=St(t*ct,e)*ut;this._screenScale[0]=t/i,this._screenScale[1]=n/s}enable(){if(this._enabled)return;const t=this._controlEl;this._mouseInput.enable(t),this._touchInput.enable(t),this._keyboardInput.enable(t),this._enabled=!0,this._enableBlocked=!1,this.trigger(at,{control:this,updateCursor:!0})}disable(){this._enabled&&(this._mouseInput.disable(),this._touchInput.disable(),this._keyboardInput.disable(),this._enabled=!1,this.trigger(ht,{updateCursor:!0}))}sync(t){this.updateRange(t,t.zoom),this._xMotion.reset(t.yaw),this._yMotion.reset(t.pitch)}_bindInputs(){const t=this._mouseInput,e=this._touchInput,i=this._keyboardInput;t.on(nt,this._onInputStart),t.on(ot,this._onChange),t.on(rt,this._onInputEnd),e.on(nt,this._onInputStart),e.on(ot,this._onChange),e.on(rt,this._onInputEnd),i.on(nt,this._onInputStart),i.on(ot,this._onChange),i.on(rt,this._onInputEnd)}}class Ht extends n.default{get scrollable(){return this._scrollable}set scrollable(t){this._scrollable=t}constructor(){super(),this._onWheel=t=>{const e=this._scrollable;if(0===t.deltaY||e)return;t.preventDefault(),t.stopPropagation(),this._inputTimer<0?this.trigger(nt,{srcEvent:t,isTouch:!1,isKeyboard:!1}):this._clearTimer();const i=this._baseScale*t.deltaY;this.trigger(ot,{delta:i,isTouch:!1,isKeyboard:!1}),this._inputTimer=window.setTimeout((()=>{this.trigger(rt,{isTouch:!1,isKeyboard:!1,scrolling:!1}),this._inputTimer=-1}),dt)},this._el=null,this._baseScale=.04,this._scrollable=!1,this._inputTimer=-1}enable(t){this._el||(t.addEventListener(v,this._onWheel,{passive:!1,capture:!1}),this._el=t,this._clearTimer())}disable(){const t=this._el;t&&(t.removeEventListener(v,this._onWheel,!1),this._el=null,this._clearTimer())}_clearTimer(){window.clearTimeout(this._inputTimer),this._inputTimer=-1}}class Xt extends n.default{constructor(){super(),this._onTouchMove=t=>{const e=t.touches;if(2!==e.length)return;if(!t.cancelable)return;t.preventDefault(),t.stopPropagation();const i=this._prevDistance,s=[e[0].pageX-e[1].pageX,e[0].pageY-e[1].pageY],n=Math.sqrt(s[0]*s[0]+s[1]*s[1])*this._baseScale,o=this._isFirstTouch?0:n-i;this._isFirstTouch&&this.trigger(nt,{srcEvent:t,isTouch:!0,isKeyboard:!1}),this._prevDistance=n,this._isFirstTouch=!1,this.trigger(ot,{delta:o,isTouch:!0,isKeyboard:!1})},this._onTouchEnd=t=>{0===t.touches.length&&(this._isFirstTouch||this.trigger(rt,{isTouch:!0,isKeyboard:!1,scrolling:!1}),this._prevDistance=-1,this._isFirstTouch=!0)},this._el=null,this._baseScale=-.2,this._prevDistance=-1,this._isFirstTouch=!0}enable(t){this._el||(t.addEventListener(p,this._onTouchMove,{passive:!1,capture:!1}),t.addEventListener(g,this._onTouchEnd),this._el=t,this._prevDistance=-1,this._isFirstTouch=!0)}disable(){const t=this._el;t&&(t.removeEventListener(p,this._onTouchMove,!1),t.removeEventListener(g,this._onTouchEnd),this._el=null)}}class jt extends n.default{get enabled(){return this._enabled}get enableBlocked(){return this._enableBlocked}get animating(){return this._motion.activated}get zoom(){return this._motion.val}get scrollable(){return this._wheelInput.scrollable}set scrollable(t){this._wheelInput.scrollable=t}get range(){return this._motion.range}get scale(){return this._scale}set scale(t){this._scale=t}get duration(){return this._motion.duration}get easing(){return this._motion.easing}constructor(t,e,{scale:i=1,duration:s=300,easing:n=_t}={}){super(),this._onInputStart=t=>{this.trigger(nt,Object.assign(Object.assign({},t),{inputType:"zoom"}))},this._onChange=({delta:t})=>{const e=t*this._scale;this._motion.setNewEndByDelta(e)},this._onInputEnd=t=>{this.trigger(rt,Object.assign(Object.assign({},t),{inputType:"zoom"}))},this._scale=i,this._controlEl=t,this._enableBlocked=e,this._wheelInput=new Ht,this._pinchInput=new Xt,this._motion=new Bt({duration:s,easing:n,range:mt}),this._enabled=!1,this._bindInputs()}destroy(){this.disable(),this._wheelInput.off(),this._pinchInput.off(),this.off()}update(t){if(!this._enabled)return;this._motion.update(t)}enable(){if(this._enabled)return;const t=this._controlEl;this._wheelInput.enable(t),this._pinchInput.enable(t),this._enabled=!0,this._enableBlocked=!1,this.trigger(at,{control:this,updateCursor:!1})}disable(){this._enabled&&(this._wheelInput.disable(),this._pinchInput.disable(),this._enabled=!1,this.trigger(ht,{updateCursor:!1}))}sync(t){const e=this._motion,i=t.getZoomRange();e.setRange(i.min,i.max),e.reset(i.current)}_bindInputs(){const t=this._wheelInput,e=this._pinchInput;t.on(nt,this._onInputStart),t.on(ot,this._onChange),t.on(rt,this._onInputEnd),e.on(nt,this._onInputStart),e.on(ot,this._onChange),e.on(rt,this._onInputEnd)}}const Wt={PITCH_DELTA:1,YAW_DELTA_BY_ROLL:2,YAW_DELTA_BY_YAW:3};Wt[Wt.PITCH_DELTA]={targetAxis:[0,1,0],meshPoint:[0,0,1]},Wt[Wt.YAW_DELTA_BY_ROLL]={targetAxis:[0,1,0],meshPoint:[1,0,0]},Wt[Wt.YAW_DELTA_BY_YAW]={targetAxis:[1,0,0],meshPoint:[0,0,1]};class qt extends n.default{get enabled(){return this._enabled}get orientationUpdated(){return this._orientationUpdated}get ignoreRoll(){return this._ignoreRoll}set ignoreRoll(t){this._ignoreRoll=t}constructor(){super(),this._onDeviceOrientation=t=>{const e=this._orientation,{alpha:i,beta:s,gamma:n}=t;null!=i&&null!=s&&null!=n&&(e.alpha=i,e.beta=s,e.gamma=n,this._orientationUpdated=!0,this._needsCalibrate&&(this._needsCalibrate=!1,this._calibrateSensor()))},this._updateScreenOrientation=()=>{window.screen&&window.screen.orientation&&void 0!==window.screen.orientation.angle?this._screenOrientation=screen.orientation.angle:void 0!==window.orientation?this._screenOrientation=window.orientation>=0?window.orientation:360+window.orientation:this._screenOrientation=0},this.quaternion=e.quat.create(),this._orientation={alpha:0,beta:90,gamma:0},this._yawOrigin=0,this._yawOffset=0,this._orientationUpdated=!1,this._screenOrientation=0,this._needsCalibrate=!0,this._enabled=!1}enable(){this._enabled||(window.addEventListener(O,this._onDeviceOrientation),window.addEventListener(A,this._updateScreenOrientation),this._updateScreenOrientation(),this._orientationUpdated=!1,this._needsCalibrate=!0,this._enabled=!0)}disable(){this._enabled&&(window.removeEventListener(O,this._onDeviceOrientation),window.removeEventListener(A,this._updateScreenOrientation),this._enabled=!1)}update(){this._updateRotation(),this._orientationUpdated=!1}collectDelta(){if(!this._orientationUpdated)return{pitch:0,yaw:0};const t=e.quat.clone(this.quaternion);return this._updateRotation(),this._orientationUpdated=!1,this._toEulerDelta(t,this.quaternion)}setInitialRotation(t){this._yawOrigin=t}_calibrateSensor(){const t=this._yawOrigin,e=this.quaternion;this._yawOffset=0,this._updateRotation();const{yaw:i}=Ut(e);this._yawOffset=i-t,this._updateRotation(),this._needsCalibrate=!1}_updateRotation(){const t=this.quaternion,{alpha:i,beta:s,gamma:n}=this._orientation;e.quat.identity(t),e.quat.rotateY(t,t,(i-this._yawOffset)*ct),e.quat.rotateX(t,t,s*ct),e.quat.rotateZ(t,t,-n*ct);const o=e.quat.create(),r=.5*-this._screenOrientation*ct,a=e.quat.fromValues(-Math.sqrt(.5),0,0,Math.sqrt(.5));e.quat.set(o,0,Math.sin(r),0,Math.cos(r)),e.quat.multiply(t,t,o),e.quat.multiply(t,t,a),e.quat.normalize(t,t)}_toEulerDelta(t,e){return{yaw:this._getDeltaYaw(t,e),pitch:this._getDeltaPitch(t,e)}}_getDeltaYaw(t,e){const i=this._getRotationDelta(t,e,Wt.YAW_DELTA_BY_YAW);return this._getRotationDelta(t,e,Wt.YAW_DELTA_BY_ROLL)*Math.sin(this._extractPitchFromQuat(e))+i}_getDeltaPitch(t,e){return this._getRotationDelta(t,e,Wt.PITCH_DELTA)}_getRotationDelta(t,i,s){const n=e.vec3.fromValues(Wt[s].targetAxis[0],Wt[s].targetAxis[1],Wt[s].targetAxis[2]),o=Wt[s].meshPoint,r=e.quat.clone(t),a=e.quat.clone(i);e.quat.normalize(r,r),e.quat.normalize(a,a);let h=e.vec3.fromValues(0,0,1),l=e.vec3.fromValues(0,0,1);e.vec3.transformQuat(h,h,r),e.vec3.transformQuat(l,l,a),e.vec3.transformQuat(n,n,a);const c=e.vec3.dot(n,e.vec3.cross(e.vec3.create(),h,l))>0?1:-1,u=e.vec3.fromValues(o[0],o[1],o[2]);let _;_=s!==Wt.YAW_DELTA_BY_YAW?e.vec3.fromValues(0,c,0):e.vec3.fromValues(c,0,0),e.vec3.transformQuat(u,u,a),e.vec3.transformQuat(_,_,a);const d=u,m=_,p=e.vec3.create();e.vec3.cross(p,d,m),e.vec3.normalize(p,p);const g=p[0],v=p[1],E=p[2];l=e.vec3.fromValues(o[0],o[1],o[2]),e.vec3.transformQuat(l,l,a),h=e.vec3.fromValues(o[0],o[1],o[2]),e.vec3.transformQuat(h,h,r);let T=Math.abs(h[0]*g+h[1]*v+h[2]*E);const b=e.vec3.create();e.vec3.subtract(b,h,e.vec3.scale(e.vec3.create(),p,T));let f=(b[0]*l[0]+b[1]*l[1]+b[2]*l[2])/(e.vec3.length(b)*e.vec3.length(l));f>1&&(f=1);const R=Math.acos(f),y=e.vec3.cross(e.vec3.create(),l,b);let w;T=g*y[0]+v*y[1]+E*y[2],w=s!==Wt.YAW_DELTA_BY_YAW?T>0?1:-1:T<0?1:-1;return R*w*c*ut}_extractPitchFromQuat(t){const i=e.vec3.fromValues(0,0,1);return e.vec3.transformQuat(i,i,t),-1*Math.atan2(i[1],Math.sqrt(Math.pow(i[0],2)+Math.pow(i[2],2)))}}class Kt extends n.default{get enabled(){return this._input.enabled}get enableBlocked(){return this._enableBlocked}get animating(){return this._input.enabled&&this._input.orientationUpdated}get ignoreRoll(){return this._ignoreRoll}set ignoreRoll(t){this._ignoreRoll=t}static isAvailable(){return r(this,void 0,void 0,(function*(){if(!DeviceMotionEvent)return!1;let t;return Promise.race([new Promise((e=>{t=t=>{e(t.rotationRate&&null!=t.rotationRate.alpha)},window.addEventListener(I,t)})),new Promise((t=>{setTimeout((()=>t(!1)),1e3)}))]).then((e=>(window.removeEventListener(I,t),e)))}))}static requestSensorPermission(){return r(this,void 0,void 0,(function*(){return!Mt()||DeviceMotionEvent.requestPermission().then((t=>"granted"===t)).catch((()=>!1))}))}constructor(t,{ignoreRoll:e=!0}={}){super(),this._enableBlocked=t,this._ignoreRoll=e,this._input=new qt}destroy(){this.disable(),this._input.off(),this.off()}update(t,e,i,s){this._ignoreRoll?this._updateYawPitch(t,e,i,s):this._updateQuaternion(t,s)}enable(){this._input.enabled||(this._input.enable(),this._enableBlocked=!1,this.trigger(at,{control:this,updateCursor:!1}))}disable(){this._input.enabled&&(this._input.disable(),this.trigger(ht,{updateCursor:!1}))}sync(){}_updateYawPitch(t,e,i,s){const n=this._input;if(!n.enabled)return;const{yaw:o,pitch:r}=n.collectDelta();e.add(o),i.add(r),t.lookAt({yaw:e.val,pitch:i.val,zoom:s})}_updateQuaternion(t,e){const i=this._input;i.enabled&&(i.update(),t.rotate(i.quaternion,e))}}class Zt{get useGrabCursor(){return this._useGrabCursor}set useGrabCursor(t){t!==this._useGrabCursor&&(this._useGrabCursor=t,t&&this._enabled?this._setCursor(Y):t||this._setCursor(X))}get disableContextMenu(){return this._disableContextMenu}set disableContextMenu(t){t!==this._disableContextMenu&&(this._disableContextMenu=t,t&&this._enabled?this._blockContextMenu():t||this._restoreContextMenu())}get scrollable(){return this._rotateControl.scrollable}set scrollable(t){this._rotateControl.scrollable=t}get wheelScrollable(){return this._zoomControl.scrollable}set wheelScrollable(t){this._zoomControl.scrollable=t}get ignoreZoomScale(){return this._ignoreZoomScale}set ignoreZoomScale(t){this._ignoreZoomScale=t}get enabled(){return this._enabled}get rotate(){return this._rotateControl}get zoom(){return this._zoomControl}get gyro(){return this._gyroControl}get animating(){return this._rotateControl.animating||this._zoomControl.animating||this._gyroControl.animating}constructor(t,e,{useGrabCursor:i,scrollable:s,wheelScrollable:n,disableContextMenu:o,rotate:r,zoom:a,gyro:h}){this._preventContextMenu=t=>{t.preventDefault()},this._onInputStart=t=>{this._useGrabCursor&&!t.isKeyboard&&this._setCursor(H)},this._onInputEnd=t=>{this._useGrabCursor&&!t.isKeyboard&&this._setCursor(Y)},this._onEnable=({control:t,updateCursor:e})=>{e&&this._useGrabCursor&&this._setCursor(Y),t.sync(this._camera)},this._onDisable=({updateCursor:t})=>{t&&this._setCursor(X)},this._onCameraAnimationEnd=({animation:t})=>{t.getFinishPromise().then((()=>{this.sync()}))},this._useGrabCursor=i,this._disableContextMenu=o,this._camera=e,this._controlEl=t,this._ignoreZoomScale=!1,this._enabled=!1,this._rotateControl=new Yt(t,!r,At(r)),this._zoomControl=new jt(t,!a,At(a)),this._gyroControl=new Kt(!h,At(h)),this._rotateControl.scrollable=s,this._zoomControl.scrollable=n,this._bindEvents()}destroy(){this.disable(),this._rotateControl.destroy(),this._zoomControl.destroy(),this._setCursor(X)}resize(t,e){const i=this._camera;this._rotateControl.resize(i.fov,i.aspect,t,e)}enable(){return r(this,void 0,void 0,(function*(){this._enabled||(this._rotateControl.enableBlocked||this._rotateControl.enable(),this._zoomControl.enableBlocked||this._zoomControl.enable(),this._gyroControl.enableBlocked||(yield Kt.isAvailable())&&this._gyroControl.enable(),this.sync(),this._disableContextMenu&&this._blockContextMenu(),this._enabled=!0)}))}disable(){this._enabled&&(this._rotateControl.disable(),this._zoomControl.disable(),this._gyroControl.disable(),this._restoreContextMenu(),this._enabled=!1)}update(t){const e=this._camera,i=this._rotateControl,s=this._zoomControl,n=this._gyroControl;s.update(t);const o=(r=e.fov,a=s.zoom,Math.tan(ct*r*.5)/Math.tan(ct*a*.5));var r,a;const h=this._ignoreZoomScale?1:Math.max(o,1);i.setZoomScale(h),i.updateRange(e,o),i.update(t);const l=i.yaw,c=i.pitch;n.enabled?n.update(e,l,c,o):e.lookAt({yaw:l.val,pitch:c.val,zoom:o})}sync(){const t=this._camera;this._zoomControl.sync(t),this._rotateControl.sync(t)}_blockContextMenu(){this._controlEl.addEventListener(T,this._preventContextMenu)}_restoreContextMenu(){this._controlEl.removeEventListener(T,this._preventContextMenu)}_setCursor(t){if(!this._useGrabCursor&&t!==X)return;this._controlEl.style.cursor=t}_bindEvents(){const t=this._rotateControl,e=this._zoomControl;t.on(nt,this._onInputStart),t.on(rt,this._onInputEnd),t.on(at,this._onEnable),t.on(ht,this._onDisable),e.on(at,this._onEnable),e.on(ht,this._onDisable),this._camera.on(st,this._onCameraAnimationEnd)}}class $t{constructor({width:t,height:e,flipY:i}){this.width=t,this.height=e,this.flipY=i,this.wrapS=WebGLRenderingContext.CLAMP_TO_EDGE,this.wrapT=WebGLRenderingContext.CLAMP_TO_EDGE}destroy(){}isVideo(){return!1}isCube(){return!1}}class Qt extends $t{constructor({source:t,width:e,height:i,flipY:s}){super({width:e,height:i,flipY:s}),this.source=t}}class Jt extends Qt{destroy(){const t=this.source;t.pause(),t.removeAttribute("src"),t.load()}isVideo(){return!0}isPaused(){const t=this.source;return t.paused||t.ended||t.readyState<=2}hasAudio(){const t=this.source;return t.audioTracks?t.audioTracks.length>0:null!=t.webkitAudioDecodedByteCount?t.webkitAudioDecodedByteCount>0:null==t.mozHasAudio||t.mozHasAudio}}class te extends $t{constructor({sources:t,width:e,height:i,flipY:s}){super({width:e,height:i,flipY:s}),this.sources=t}isCube(){return!0}}class ee{constructor(){this._loadChecker=new o.default}load(t,e){return r(this,void 0,void 0,(function*(){if(e)return this.loadVideo(t,At(e));if(Array.isArray(t)&&t.length>1)return this.loadCubeImage(t);{const e=Array.isArray(t)?t[0]:t;return this.loadImage(e)}}))}loadImage(t){return r(this,void 0,void 0,(function*(){const e=this._toImageArray(t);return this._load(e,(t=>{const i=e[0];t(new Qt({source:i,width:i.naturalWidth,height:i.naturalHeight,flipY:!0}))}))}))}loadCubeImage(t){return r(this,void 0,void 0,(function*(){const e=this._toImageArray(t);return this._load(e,(t=>{t(new te({sources:e,width:e[0].naturalWidth,height:e[0].naturalHeight,flipY:!1}))}))}))}loadVideo(t,e){return r(this,void 0,void 0,(function*(){const i=Object.assign({autoplay:!0,muted:!0,loop:!1,volume:1},e),s=this._toVideoElement(t,i);return this._load([s],(t=>{const{autoplay:e,muted:n}=i;s.currentTime=0,e&&n&&s.play().catch((()=>{})),t(new Jt({source:s,width:s.videoWidth,height:s.videoHeight,flipY:!0}))}))}))}_load(t,e){const i=this._loadChecker;return new Promise(((s,n)=>{i.once("ready",(t=>{t.errorCount>0||e(s)})),i.once("error",n),i.check(t)}))}_toImageArray(t){return(Array.isArray(t)?t:[t]).map((t=>{if(yt(t)){const e=new Image;return e.crossOrigin="anonymous",e.src=t,e}return t}))}_toVideoElement(t,{muted:e,loop:i,volume:s}){if(t instanceof HTMLVideoElement)return t;const n=document.createElement("video");n.crossOrigin="anonymous",n.playsInline=!0,n.setAttribute("webkit-playsinline",""),n.muted=e,n.volume=s,n.loop=i,Array.isArray(t)?t.forEach((t=>this._appendSourceElement(n,t))):this._appendSourceElement(n,t);return n.querySelectorAll("source").length>0&&n.readyState<1&&n.load(),n}_appendSourceElement(t,e){if(e instanceof HTMLSourceElement)return e;const i=document.createElement("source");i.src=e,t.appendChild(i)}}class ie{constructor(t,e=window){this.maxDeltaTime=t,this._context=e,this._rafId=-1,this._rafTimer=-1,this._lastUpdateTime=-1}start(t){const e=this._context;if(!e||!t)return;if(this._rafId>=0||this._rafTimer>=0)return;const i=(s,n)=>{const o=Date.now(),r=Math.min(o-this._lastUpdateTime,1e3*this.maxDeltaTime);t(r,n),this._lastUpdateTime=o,this._rafId=e.requestAnimationFrame(i)};this._lastUpdateTime=Date.now(),this._rafId=e.requestAnimationFrame(i)}stop(){this._rafId>=0&&this._context.cancelAnimationFrame(this._rafId),this._rafTimer>=0&&clearTimeout(this._rafTimer),this._rafId=-1,this._rafTimer=-1}changeContext(t){this.stop(),this._context=t}}class se{get useResizeObserver(){return this._useResizeObserver}get enabled(){return this._enabled}constructor(t,e){this._skipFirstResize=(()=>{let t=!0;return()=>{t?t=!1:this._onResize()}})(),this._useResizeObserver=t,this._enabled=!1,this._resizeObserver=null,this._onResize=e}enable(t){if(this._enabled&&this.disable(),this._useResizeObserver&&window.ResizeObserver){const e=t.getBoundingClientRect(),i=0!==e.width||0!==e.height,s=new ResizeObserver(i?this._skipFirstResize:this._onResize);s.observe(t),this._resizeObserver=s}else window.addEventListener(E,this._onResize);return this._enabled=!0,this}disable(){if(!this._enabled)return this;const t=this._resizeObserver;return t?(t.disconnect(),this._resizeObserver=null):window.removeEventListener(E,this._onResize),this._enabled=!1,this}}class ne{get enabled(){return this._enabled}get enableBlocked(){return this._enableBlocked}get playing(){return this._enabled&&!this._interrupted}get delay(){return this._delay}set delay(t){this._delay=t}get delayOnMouseLeave(){return this._delayOnMouseLeave}set delayOnMouseLeave(t){this._delayOnMouseLeave=t}get speed(){return this._speed}set speed(t){this._speed=t}get pauseOnHover(){return this._pauseOnHover}set pauseOnHover(t){this._pauseOnHover=t}get canInterrupt(){return this._canInterrupt}set canInterrupt(t){this._canInterrupt=t}get disableOnInterrupt(){return this._disableOnInterrupt}set disableOnInterrupt(t){this._disableOnInterrupt=t}constructor(t,e,i){this._onInputStart=()=>{this._canInterrupt&&(this._interrupted=!0,this._clearTimeout())},this._onInputEnd=()=>{this._setUninterruptedAfterDelay(this._delay)},this._onGyroEnable=()=>{this.disable()},this._onMouseEnter=()=>{this._pauseOnHover&&(this._interrupted=!0,this._hovering=!0)},this._onMouseLeave=()=>{this._pauseOnHover&&(this._hovering=!1,this._setUninterruptedAfterDelay(this._delayOnMouseLeave))},this._camera=t.camera,this._control=t.control,this._element=e,this._enabled=!1,this._interrupted=!1,this._interruptionTimer=-1,this._hovering=!1;const{delay:s=2e3,delayOnMouseLeave:n=0,speed:o=1,pauseOnHover:r=!1,canInterrupt:a=!0,disableOnInterrupt:h=!1}=At(i);this._enableBlocked=!i,this._delay=s,this._delayOnMouseLeave=n,this._speed=o,this._pauseOnHover=r,this._canInterrupt=a,this._disableOnInterrupt=h}destroy(){this.disable()}update(t){if(!this._enabled)return;if(this._interrupted)return void(this._disableOnInterrupt&&this.disable());const e=this._camera,i=-this._speed*t/100;e.yaw=Ot(e.yaw+i,0,360)}enable(){const t=this._control,e=this._element;this._enabled||t.gyro.enabled||(t.rotate.on(nt,this._onInputStart),t.rotate.on(rt,this._onInputEnd),t.zoom.on(nt,this._onInputStart),t.zoom.on(rt,this._onInputEnd),t.gyro.on(at,this._onGyroEnable),e.addEventListener(b,this._onMouseEnter,!1),e.addEventListener(f,this._onMouseLeave,!1),this._enabled=!0,this._enableBlocked=!1)}enableAfterDelay(){this.enable(),this._interrupted=!0,this._setUninterruptedAfterDelay(this._delay)}disable(){if(!this._enabled)return;const t=this._control,e=this._element;t.rotate.off(nt,this._onInputStart),t.rotate.off(rt,this._onInputEnd),t.zoom.off(nt,this._onInputStart),t.zoom.off(rt,this._onInputEnd),t.gyro.off(at,this._onGyroEnable),e.removeEventListener(b,this._onMouseEnter,!1),e.removeEventListener(f,this._onMouseLeave,!1),this._enabled=!1,this._interrupted=!1,this._hovering=!1,this._clearTimeout()}_setUninterruptedAfterDelay(t){this._hovering||(this._clearTimeout(),t>0?this._interruptionTimer=window.setTimeout((()=>{this._interrupted=!1,this._interruptionTimer=-1}),t):(this._interrupted=!1,this._interruptionTimer=-1))}_clearTimeout(){this._interruptionTimer>=0&&(window.clearTimeout(this._interruptionTimer),this._interruptionTimer=-1)}}class oe extends n.default{constructor(t,e={}){super(),this.destroy=()=>{this.exit(),this.off()},this._onSessionEnd=()=>{this.exit(),this.trigger(tt.VR_END)},this._xrSession=null,this._xrRefSpace=null,this._ctx=t,this._options=e}isAvailable(){return r(this,void 0,void 0,(function*(){const t=window.navigator.xr;return!!t&&t.isSessionSupported(bt).then((t=>t)).catch((()=>!1))}))}enter(){return r(this,void 0,void 0,(function*(){const t=this._ctx,e=window.navigator.xr;if(!e)return;yield Kt.requestSensorPermission();const i=Object.assign({requiredFeatures:[ft]},this._options);yield t.makeXRCompatible();const s=yield e.requestSession(bt,i);t.bindXRLayer(s);const n=yield s.requestReferenceSpace(ft);this._setSession(s,n),this.trigger(tt.VR_START,{session:s})}))}exit(){const t=this._xrSession;t&&t.end().catch((()=>{})),this._xrSession=null,this._xrRefSpace=null}canRender(t){const e=this._xrRefSpace;if(!e)return!1;return!!t.getViewerPose(e)}getEyeParams(t){const e=t.session,i=t.getViewerPose(this._xrRefSpace);if(!i)return null;const s=e.renderState.baseLayer;return s?i.views.map((t=>({viewport:s.getViewport(t),vMatrix:t.transform.inverse.matrix,pMatrix:t.projectionMatrix}))):null}_setSession(t,e){this._xrSession=t,this._xrRefSpace=e,t.addEventListener(z,this._onSessionEnd)}}class re{constructor(t,e){this.element=t,this.position=e}}class ae{constructor(t,e,{zoom:i=!1}){this._containerEl=Lt(`.${J.HOTSPOT_CONTAINER}`,t),this._renderer=e,this._hotspots=[],this._zoom=i}refresh(){const t=this._containerEl;if(!t)return;const e=[].slice.apply(t.querySelectorAll(`.${J.HOTSPOT}`));this._hotspots=e.map((t=>this._parseHotspot(t)))}render(t){const i=this._hotspots,s=.5*this._renderer.width,n=.5*this._renderer.height,o=t.zoom,r="translate(-50%, -50%)",a=this._zoom?`scale(${o})`:"";i.forEach((i=>{const o=i.position,h=e.vec3.create();if(e.vec3.copy(h,o),e.vec3.transformMat4(h,h,t.viewMatrix),e.vec3.transformMat4(h,h,t.projectionMatrix),h[2]>1||h[2]<0)return void i.element.classList.remove(J.HOTSPOT_VISIBLE);const l=e.vec2.fromValues(h[0]*s+s,-h[1]*n+n);i.element.classList.add(J.HOTSPOT_VISIBLE),i.element.style.transform=[r,`translate(${l[0]}px, ${l[1]}px)`,a].join(" ")}))}_parseHotspot(t){const i=t.dataset.yaw,s=t.dataset.pitch,n=t.dataset.position;if(i||s){const e=i?parseFloat(i):0,n=s?parseFloat(s):0,o=this._yawPitchToVec3(e,n);return new re(t,o)}if(n){const i=n.split(" ").map((t=>parseFloat(t)));if(i.length<3)throw new a(c.INSUFFICIENT_ARGS(n,'hotspot attribute "data-position"'),l.INSUFFICIENT_ARGS);return new re(t,e.vec3.fromValues(i[0],i[1],i[2]))}{const i=e.vec3.fromValues(0,0,-1);return new re(t,i)}}_yawPitchToVec3(t,i){const s=t*ct,n=i*ct,o=e.vec3.create();return o[1]=Math.sin(n),o[2]=Math.cos(n),o[0]=o[2]*Math.sin(-s),o[2]=-o[2]*Math.cos(-s),o}}class he{get count(){return this.geometry.indicies.count}constructor(t,e,i){this.obj=t,this.geometry=e,this.buffers=i}}class le{get canvas(){return this._canvas}get maxTextureSize(){return this._maxTextureSize}get isWebGL2(){return this._isWebGL2}get supportVAO(){return this._isWebGL2||!!this._extensions.vao}get lost(){return this._contextLost}get debug(){return this._debug}constructor(t,e){this._onContextLost=()=>{this._canvas.classList.add(J.CTX_LOST),this._contextLost=!0},this._onContextRestore=()=>{this._canvas.classList.remove(J.CTX_LOST),this._contextLost=!1},this._canvas=t,this._contextLost=!1,this._debug=e,this._extensions={vao:null,loseContext:null}}init(){const t=this._canvas,{gl:e,isWebGL2:i}=this._getContext(t);this._gl=e,this._maxTextureSize=e.getParameter(e.MAX_TEXTURE_SIZE),this._isWebGL2=i,this._isWebGL2||(this._extensions.vao=e.getExtension("OES_vertex_array_object")),this._extensions.loseContext=e.getExtension("WEBGL_lose_context"),t.addEventListener(C,this._onContextLost),t.addEventListener(x,this._onContextRestore)}destroy(){const t=this._gl,e=this._canvas;t&&(t.bindBuffer(t.ARRAY_BUFFER,null),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,null)),e.removeEventListener(C,this._onContextLost),e.removeEventListener(x,this._onContextRestore)}forceLoseContext(){const t=this._extensions.loseContext;t&&t.loseContext()}forceRestoreContext(){const t=this._extensions.loseContext;t&&t.restoreContext()}clear(){const t=this._gl;t.clear(t.COLOR_BUFFER_BIT)}resize(){const t=this._gl;t.viewport(0,0,t.drawingBufferWidth,t.drawingBufferHeight)}viewport(t,e,i,s){this._gl.viewport(t,e,i,s)}createVAO(t,e){const i=this._createNativeVAO(),s=new he(i,t,{indicies:this._createBuffer(),position:this._createBuffer(),uv:this._createBuffer()});return i&&(this._bindNativeVAO(i),this._supplyGeometryData(s,e),this._bindNativeVAO(null),this._unbindBuffers()),s}draw(t,e){const i=this._gl;t.obj?this._bindNativeVAO(t.obj):this._supplyGeometryData(t,e),i.drawElements(i.TRIANGLES,t.count,i.UNSIGNED_SHORT,0),t.obj?this._bindNativeVAO(null):this._unbindBuffers()}releaseVAO(t){t.obj&&this._deleteNativeVAO(t.obj),this._deleteBuffer(t.buffers.indicies),this._deleteBuffer(t.buffers.position),this._deleteBuffer(t.buffers.uv)}getUniformLocations(t,e){const i=this._gl,s=Object.keys(e).reduce(((e,s)=>(e[s]=i.getUniformLocation(t,s),e)),{});return Object.assign(Object.assign({},this._getCommonUniformLocations(t)),s)}updateCommonUniforms(t,i,s){const n=this._gl,o=s.uniformLocations,r=t.matrix,a=e.mat4.create();e.mat4.multiply(a,i.viewMatrix,r),n.uniformMatrix4fv(o.uMVMatrix,!1,a),n.uniformMatrix4fv(o.uPMatrix,!1,i.projectionMatrix)}updateVRUniforms(t,e,i,s){const n=this._gl,o=t.uniformLocations;n.uniformMatrix4fv(o.uMVMatrix,!1,e),n.uniformMatrix4fv(o.uPMatrix,!1,i),o.uEye&&n.uniform1f(o.uEye,s)}updateUniforms(t){const e=this._gl,i=t.uniforms,s=t.uniformLocations;for(const t in i){const n=i[t],o=s[t];n&&(n.needsUpdate&&n.update(e,o,this._isWebGL2))}}releaseShaderResources(t){const e=this._gl,i=t.uniforms;for(const t in i){const s=i[t];s&&(s.needsUpdate&&s.destroy(e))}e.deleteProgram(t.program)}useProgram(t){this._gl.useProgram(t.program)}createProgram(t,e){const i=this._gl,s=i.createProgram(),n=this._compileShader(i.VERTEX_SHADER,t),o=this._compileShader(i.FRAGMENT_SHADER,e);if(i.attachShader(s,n),i.attachShader(s,o),i.bindAttribLocation(s,0,"position"),i.bindAttribLocation(s,1,"uv"),i.linkProgram(s),this._debug&&!i.getProgramParameter(s,i.LINK_STATUS)){let t=null;throw i.getShaderParameter(n,i.COMPILE_STATUS)?i.getShaderParameter(o,i.COMPILE_STATUS)||(t=i.getShaderInfoLog(o)):t=i.getShaderInfoLog(n),new a(c.FAILED_LINKING_PROGRAM(i.getProgramInfoLog(s),t),l.FAILED_LINKING_PROGRAM)}return i.deleteShader(n),i.deleteShader(o),s}createWebGLTexture(t){const e=this._gl,i=e.createTexture();if(e.bindTexture(e.TEXTURE_2D,i),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,t.wrapS),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,t.wrapT),!t.isVideo()&&this._isWebGL2){const i=e;i.texStorage2D(i.TEXTURE_2D,1,i.RGBA8,t.width,t.height)}return i}createWebGLCubeTexture(t,e){const i=this._gl,s=i.createTexture();if(i.bindTexture(i.TEXTURE_CUBE_MAP,s),i.texParameteri(i.TEXTURE_CUBE_MAP,i.TEXTURE_MIN_FILTER,i.LINEAR),i.texParameteri(i.TEXTURE_CUBE_MAP,i.TEXTURE_MAG_FILTER,i.LINEAR),i.texParameteri(i.TEXTURE_CUBE_MAP,i.TEXTURE_WRAP_S,t.wrapS),i.texParameteri(i.TEXTURE_CUBE_MAP,i.TEXTURE_WRAP_T,t.wrapT),this._isWebGL2){const t=i;t.texStorage2D(t.TEXTURE_CUBE_MAP,1,t.RGBA8,e,e)}return s}makeXRCompatible(){return r(this,void 0,void 0,(function*(){const t=this._gl,e=t.getContextAttributes();e&&!0!==e.xrCompatible&&(yield t.makeXRCompatible())}))}bindXRLayer(t){const e=this._gl,i=new XRWebGLLayer(t,e);t.updateRenderState({baseLayer:i})}bindXRFrame(t){const e=this._gl,i=t.session.renderState.baseLayer;e.bindFramebuffer(e.FRAMEBUFFER,i.framebuffer)}useDefaultFrameBuffer(){const t=this._gl;t.bindFramebuffer(t.FRAMEBUFFER,null)}_createBuffer(){return this._gl.createBuffer()}_deleteBuffer(t){return this._gl.deleteBuffer(t)}_createNativeVAO(){const t=this._gl;if(this._isWebGL2)return t.createVertexArray();{const t=this._extensions.vao;return(null==t?void 0:t.createVertexArrayOES())||null}}_bindNativeVAO(t){const e=this._gl;if(this._isWebGL2)e.bindVertexArray(t);else{const e=this._extensions.vao;null==e||e.bindVertexArrayOES(t)}}_deleteNativeVAO(t){const e=this._gl;if(this._isWebGL2)e.deleteVertexArray(t);else{const e=this._extensions.vao;null==e||e.deleteVertexArrayOES(t)}}_supplyGeometryData(t,e){const i=t.geometry;this._supplyIndiciesData(i.indicies,t.buffers.indicies),this._supplyAttributeData(i.vertices,e.program,"position",t.buffers.position),this._supplyAttributeData(i.uvs,e.program,"uv",t.buffers.uv)}_unbindBuffers(){const t=this._gl;t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,null),t.bindBuffer(t.ARRAY_BUFFER,null)}_supplyIndiciesData(t,e){const i=this._gl;i.bindBuffer(i.ELEMENT_ARRAY_BUFFER,e),i.bufferData(i.ELEMENT_ARRAY_BUFFER,t.data,i.STATIC_DRAW)}_supplyAttributeData(t,e,i,s){const n=this._gl,o=n.getAttribLocation(e,i);o<0||(n.bindBuffer(n.ARRAY_BUFFER,s),n.bufferData(n.ARRAY_BUFFER,t.data,n.STATIC_DRAW),n.vertexAttribPointer(o,t.itemSize,n.FLOAT,!1,0,0),n.enableVertexAttribArray(o))}_compileShader(t,e){const i=this._gl,s=i.createShader(t);return i.shaderSource(s,e),i.compileShader(s),s}_getCommonUniformLocations(t){const e=this._gl;return{uMVMatrix:e.getUniformLocation(t,"uMVMatrix"),uPMatrix:e.getUniformLocation(t,"uPMatrix")}}_getContext(t){const e=["webgl2","webgl","experimental-webgl","webkit-3d","moz-webgl"];let i=null,s=!1;const n={preserveDrawingBuffer:!1,antialias:!1},o=t=>t.statusMessage;t.addEventListener(L,o);for(const o of e){try{i=t.getContext(o,n),s="webgl2"===o}catch(t){}if(i)break}if(t.removeEventListener(L,o),!i)throw new a(c.WEBGL_NOT_SUPPORTED,l.WEBGL_NOT_SUPPORTED);return{gl:i,isWebGL2:s}}}class ce{get canvas(){return this._canvas}get width(){return this._elementSize.x}get height(){return this._elementSize.y}get pixelRatio(){return this._pixelRatio}get aspect(){return this._elementSize.x/this._elementSize.y}constructor(t,e){this._canvas=t,this._elementSize={x:0,y:0},this._pixelRatio=1,this.ctx=new le(t,e)}destroy(){const t=this._canvas;this.ctx.destroy(),t.width=1,t.height=1}resize(){const t=this._canvas,e=this._elementSize,i=window.devicePixelRatio;e.x=t.clientWidth,e.y=t.clientHeight,t.width=e.x*i,t.height=e.y*i,this._pixelRatio=i,this.ctx.resize()}render(t,e){const i=this.ctx,s=t.getMesh();!i.lost&&s&&(i.clear(),i.useProgram(s.program),i.updateCommonUniforms(s,e,s.program),t.update(e),i.updateUniforms(s.program),i.draw(s.vao,s.program))}renderVR(t,i,s){const n=this.ctx,o=t.getMesh(),r=i.getEyeParams(s);r&&o&&(n.bindXRFrame(s),n.useProgram(o.program),n.updateUniforms(o.program),r.forEach(((t,i)=>{const s=t.viewport,r=e.mat4.multiply(e.mat4.create(),t.vMatrix,o.matrix);n.viewport(s.x,s.y,s.width,s.height),n.updateVRUniforms(o.program,r,t.pMatrix,i),n.draw(o.vao,o.program)})))}}class ue extends n.default{get rootEl(){return this._rootEl}get renderer(){return this._renderer}get camera(){return this._camera}get control(){return this._control}get vr(){return this._vr}get hotspot(){return this._hotspot}get plugins(){return this._plugins}get projection(){return this._projection}set projection(t){this._initialized&&t?this.load(t):this._projection=t}get initialized(){return this._initialized}get autoplay(){return this._autoplay}get autoInit(){return this._autoInit}get autoResize(){return this._autoResize}get canvasSelector(){return this._canvasSelector}get useResizeObserver(){return this._useResizeObserver}get tabIndex(){return this._tabIndex}set tabIndex(t){const e=this._renderer.canvas;this._tabIndex=t,null!=t?e.tabIndex=t:e.removeAttribute("tabindex")}get maxDeltaTime(){return this._animator.maxDeltaTime}set maxDeltaTime(t){this._animator.maxDeltaTime=t}get debug(){return this._debug}set debug(t){this._debug=t}get initialYaw(){return this._camera.initialYaw}set initialYaw(t){this._camera.initialYaw=t}get initialPitch(){return this._camera.initialPitch}set initialPitch(t){this._camera.initialPitch=t}get initialZoom(){return this._camera.initialZoom}set initialZoom(t){this._camera.initialZoom=t}get yawRange(){return this._camera.yawRange}set yawRange(t){this._camera.yawRange=t,this._projection&&this._projection.updateCamera(this._camera)}get pitchRange(){return this._camera.pitchRange}set pitchRange(t){this._camera.pitchRange=t,this._projection&&this._projection.updateCamera(this._camera)}get zoomRange(){return this._camera.zoomRange}set zoomRange(t){this._camera.zoomRange=t,this._projection&&this._projection.updateCamera(this._camera)}get fov(){return this._camera.fov}set fov(t){const e=this._camera,i=this._control;e.fov=t,e.updateMatrix(),i.sync()}get rotate(){return this._control.rotate}get zoom(){return this._control.zoom}get gyro(){return this._control.gyro}get useGrabCursor(){return this._control.useGrabCursor}set useGrabCursor(t){this._control.useGrabCursor=t}get disableContextMenu(){return this._control.disableContextMenu}set disableContextMenu(t){this._control.disableContextMenu=t}get scrollable(){return this._control.scrollable}set scrollable(t){this._control.scrollable=t}get wheelScrollable(){return this._control.wheelScrollable}set wheelScrollable(t){this._control.wheelScrollable=t}constructor(t,{projection:e=null,initialYaw:i=0,initialPitch:s=0,initialZoom:n=1,yawRange:o=null,pitchRange:r=null,zoomRange:h=null,fov:u=90,useGrabCursor:_=!0,disableContextMenu:d=!1,rotate:m=!0,zoom:p=!0,gyro:g=!1,scrollable:v=!0,wheelScrollable:E=!1,autoplay:T=!1,hotspot:b={},autoInit:f=!0,autoResize:R=!0,canvasSelector:y="canvas",useResizeObserver:w=!0,on:L={},plugins:C=[],maxDeltaTime:x=1/30,tabIndex:O=0,debug:I=!1}={}){super(),this.renderFrame=t=>{const e=this._camera,i=this._renderer,s=this._control,n=this._hotspot,o=this._autoplay,r=this._projection;r&&(this._emit(tt.BEFORE_RENDER),o.playing&&(o.update(t),s.sync()),e.animation?e.animation.update(t):s.update(t),i.render(r,e),n.render(e),e.changed&&this._emit(tt.VIEW_CHANGE,{yaw:e.yaw,pitch:e.pitch,zoom:e.zoom,quaternion:[e.quaternion[0],e.quaternion[1],e.quaternion[2],e.quaternion[3]]}),e.onFrameRender(),this._emit(tt.RENDER))},this._renderFrameOnDemand=t=>{var e;const i=this._camera,s=this._control,n=this._autoplay,o=null===(e=this._projection)||void 0===e?void 0:e.getTexture();this._initialized&&o&&(i.animation||s.animating||n.playing||o.isVideo())&&this.renderFrame(t)},this._renderVRFrame=(t,e)=>{const i=this._vr,s=this._projection,n=this._renderer;s&&(this._emit(tt.BEFORE_RENDER),n.renderVR(s,i,e),this._emit(tt.RENDER))},this._rootEl=((t,e)=>{const i=Lt(t,e);if(!i)throw yt(t)?new a(c.ELEMENT_NOT_FOUND(t),l.ELEMENT_NOT_FOUND):new a(c.WRONG_TYPE(t,["HTMLElement","string"]),l.WRONG_TYPE);return i})(t),this._plugins=C,this._initialized=!1,this._autoInit=f,this._autoResize=R,this._canvasSelector=y,this._useResizeObserver=w,this._tabIndex=O,this._debug=I;const A=((t,e)=>{const i=t.querySelector(e);if(!i)throw new a(c.CANVAS_NOT_FOUND,l.CANVAS_NOT_FOUND);return i})(this._rootEl,y);this._renderer=new ce(A,I),this._camera=new zt({initialYaw:i,initialPitch:s,initialZoom:n,fov:u,yawRange:o,pitchRange:r,zoomRange:h}),this._control=new Zt(A,this._camera,{useGrabCursor:_,scrollable:v,wheelScrollable:E,disableContextMenu:d,rotate:m,zoom:p,gyro:g}),this._animator=new ie(x),this._autoplay=new ne(this,A,T),this._projection=e,this._autoResizer=new se(w,(()=>this.resize())),this._vr=new oe(this._renderer.ctx),this._hotspot=new ae(this._rootEl,this._renderer,b),this._addEventHandlers(L),e&&f&&this.init()}destroy(){this._camera.destroy(),this._animator.stop(),this._renderer.destroy(),this._control.destroy(),this._autoResizer.disable(),this._projection&&(this._projection.releaseAllResources(this._renderer.ctx),this._projection=null),this._plugins.forEach((t=>t.destroy(this))),this._initialized=!1}init(){return r(this,void 0,void 0,(function*(){if(!this._projection)throw new a(c.PROVIDE_PROJECTION_FIRST,l.PROVIDE_PROJECTION_FIRST);const t=this._renderer,e=this._camera,i=this._control,s=this._animator,n=this._hotspot,o=this._projection,r=t.canvas;this._bindComponentEvents(),t.ctx.init(),this._resizeComponents(),e.updateMatrix(),this._autoResize&&this._autoResizer.enable(r),this._autoplay.enableBlocked||this._autoplay.enable(),this._plugins.forEach((t=>{t.init(this)}));const h=yield this._loadTexture(o);this._applyProjection(o,h,null),n.refresh(),s.start(this._renderFrameOnDemand),yield i.enable(),null==this._tabIndex||r.hasAttribute("tabIndex")||(r.tabIndex=this._tabIndex),this._initialized=!0,this.renderFrame(0),this._emit(tt.READY)}))}load(t){return r(this,void 0,void 0,(function*(){if(!t)return!1;if(this._initialized){const e=yield this._loadTexture(t);this._applyProjection(t,e,this._projection),this.renderFrame(0)}else this._projection=t,this.init();return!0}))}resize(){if(!this._initialized)return;this._resizeComponents(),this.renderFrame(0);const{width:t,height:e}=this._renderer;this._emit(tt.RESIZE,{width:t,height:e})}addPlugins(...t){this._initialized&&t.forEach((t=>{t.init(this)})),this._plugins.push(...t)}removePlugins(...t){t.forEach((t=>{const e=this._plugins.indexOf(t);e<0||(t.destroy(this),this._plugins.splice(e,1))}))}_emit(t,...e){const i=e?e[0]:{};this.trigger(t,Object.assign({type:t,target:this},i))}_applyProjection(t,e,i){const s=this._camera,n=this._control,o=this._renderer;i&&i.releaseAllResources(this._renderer.ctx),t.applyTexture(o.ctx,e),t.updateCamera(s),t.updateControl(n),this._projection=t,this._emit(tt.PROJECTION_CHANGE,{projection:t})}_loadTexture(t){return r(this,void 0,void 0,(function*(){const e=new ee,{src:i,video:s}=t;this._emit(tt.LOAD_START,{src:i,video:s});const n=yield e.load(i,s);return this._emit(tt.LOAD,{src:i,video:s}),n}))}_resizeComponents(){const t=this._renderer,e=this._camera,i=this._control;t.resize(),e.resize(t.width,t.height),i.resize(t.width,t.height)}_addEventHandlers(t){Object.keys(t).forEach((e=>{this.on(e,t[e])}))}_bindComponentEvents(){const t=this._rootEl,e=this._control,i=this._animator,s=this._renderer,n=this._vr;[lt,nt,rt].forEach((t=>{e.rotate.on(t,(e=>{this._emit(t,e)})),e.zoom.on(t,(e=>{this._emit(t,e)}))})),n.on(tt.VR_START,(e=>{t.classList.add(J.IN_VR),i.changeContext(e.session),i.start(this._renderVRFrame),this._emit(tt.VR_START)})),n.on(tt.VR_END,(()=>{t.classList.remove(J.IN_VR),s.ctx.useDefaultFrameBuffer(),i.changeContext(window),i.start(this._renderFrameOnDemand),this.resize(),this._emit(tt.VR_END)}))}}ue.VERSION="4.0.0-beta.4";class _e{constructor(){this.matrix=e.mat4.create(),this.rotation=e.quat.create(),this.position=e.vec3.fromValues(0,0,0),this.scale=e.vec3.fromValues(1,1,1)}updateMatrix(){e.mat4.fromRotationTranslationScale(this.matrix,this.rotation,this.position,this.scale)}}class de{constructor({className:t={}}={}){this._startLoading=({target:t})=>{t.rootEl.appendChild(this._container),t.initialized?t.once(tt.LOAD,this._detachElements):t.once(tt.READY,this._detachElements)},this._detachElements=({target:t})=>{const e=this._container;e&&e.parentElement===t.rootEl&&t.rootEl.removeChild(e)},this.className=t,this._container=this._createElements()}init(t){t.on(tt.LOAD_START,this._startLoading)}destroy(t){t.off(tt.LOAD_START,this._startLoading),this._detachElements({target:t})}_createElements(){const t=Object.assign(Object.assign({},this.className),de.DEFAULT_CLASS),e=wt(t.CONTAINER),i=wt(t.RING);return e.appendChild(i),e}}de.DEFAULT_CLASS={CONTAINER:"view360-spinner",RING:"view360-spinner-ring"};class me{constructor(t){this.position=t.position,this.order=t.order}}const pe={CONTROLS_ROOT:"view360-controls",CONTROLS_BG:"view360-controls-background",CONTROLS_MAIN:"view360-controls-main",CONTROLS_TOP:"view360-controls-top",CONTROLS_BOTTOM:"view360-controls-bottom",CONTROLS_MID:"view360-controls-mid",CONTROLS_LEFT:"view360-controls-left",CONTROLS_RIGHT:"view360-controls-right",CONTROLS_FLOAT_LEFT:"view360-controls-float-left",CONTROLS_FLOAT_RIGHT:"view360-controls-float-right",CONTROLS_BUTTON:"view360-controls-button",PROGRESS_ROOT:"view360-controls-progress",VOLUME_ROOT:"view360-controls-volume",RANGE_ROOT:"view360-range",RANGE_TRACK:"view360-range-track",RANGE_THUMB:"view360-range-thumb",RANGE_FILLER:"view360-range-filler",PLAY_BUTTON:"view360-controls-play",PAUSE_BUTTON:"view360-controls-pause",UNMUTED_BUTTON:"view360-controls-unmuted",MUTED_BUTTON:"view360-controls-muted",FULLSCREEN_BUTTON:"view360-controls-fullscreen",FULLSCREEN_EXIT_BUTTON:"view360-controls-fullscreen-exit",VR_BUTTON:"view360-controls-vr",GYRO_ENABLED:"view360-controls-gyro-enabled",GYRO_DISABLED:"view360-controls-gyro-disabled",VIDEO_TIME_DISPLAY:"view360-controls-time",PIEVIEW_ROOT:"view360-controls-pie",FIXED:"view360-controls-fixed",UNAVAILABLE:"view360-controls-unavailable",HIDDEN:"view360-controls-hidden"},ge={TOP_LEFT:"top-left",TOP_RIGHT:"top-right",MAIN_TOP:"main-top",MAIN_BOTTOM:"main-bottom",MAIN_LEFT:"main-left",MAIN_RIGHT:"main-right"};class ve extends n.default{constructor(){super(),this._onHold=({srcEvent:t,isTouch:e})=>{var i;const s=this._bbox;if(!s)return;const n=e?t.touches[0].pageX:t.pageX,o=s.x+(null!==(i=window.scrollX)&&void 0!==i?i:window.pageXOffset),r=Ct(n,o,o+s.width),a=(r-o)/s.width;this._motion.reset(r),this.thumbEl.classList.add(this._fixedClass),this.trigger(nt,a)},this._onChange=({delta:t})=>{var e;const i=this._motion,s=this._bbox;if(!s)return;i.setNewEndByDelta(t.x),i.update(1);const n=s.x+(null!==(e=window.scrollX)&&void 0!==e?e:window.pageXOffset),o=(Ct(i.val,n,n+s.width)-n)/s.width;this.trigger(ot,o)},this._onRelease=()=>{this._bbox&&(this.thumbEl.classList.remove(this._fixedClass),this.trigger(rt))};const t=document.createElement(V),e=document.createElement(V),i=document.createElement(V),s=document.createElement(V);t.draggable=!1,e.appendChild(s),e.appendChild(i),t.appendChild(e),this.rootEl=t,this.trackEl=e,this.thumbEl=i,this.fillerEl=s,this._mouseInput=new Vt,this._touchInput=new Gt,this._motion=new Bt({duration:1,range:mt,easing:t=>t}),this._bbox={x:0,y:0,width:0,height:0,left:0,right:0,bottom:0,top:0},this._fixedClass=pe.FIXED}init(t){const e=this._mouseInput,i=this._touchInput;this.rootEl.classList.add(t.RANGE_ROOT),this.trackEl.classList.add(t.RANGE_TRACK),this.thumbEl.classList.add(t.RANGE_THUMB),this.fillerEl.classList.add(t.RANGE_FILLER),this._fixedClass=t.FIXED,e.on(nt,this._onHold),i.on(nt,this._onHold),e.on(rt,this._onRelease),i.on(rt,this._onRelease),e.on(ot,this._onChange),i.on(ot,this._onChange),e.enable(this.rootEl),i.enable(this.rootEl),this.resize()}destroy(){const t=this._mouseInput,e=this._touchInput;this.rootEl.className="",this.trackEl.className="",this.thumbEl.className="",this.fillerEl.className="",t.off(),e.off(),t.disable(),e.disable()}resize(){this._bbox=this.trackEl.getBoundingClientRect()}updateStyle(t){const e=this._bbox.width,i=Ct(t,0,1);this.fillerEl.style.width=100*i+"%",this.thumbEl.style.transform=`translateX(${i*e}px)`}}class Ee extends me{get element(){return this._rangeControl.rootEl}constructor({position:t=ge.MAIN_TOP,order:e=9999}={}){super({position:t,order:e}),this._onResize=()=>{this._rangeControl.resize()},this._onTimeUpdate=()=>{const t=this._video;t&&(this._currentTime=t.source.currentTime,this._rangeControl.updateStyle(this._currentTime/this._duration))},this._onDurationChange=()=>{const t=this._video;t&&(this._duration=t.source.duration,this._rangeControl.updateStyle(this._currentTime/this._duration))},this._onHold=t=>{const e=this._video,i=this._controlBar;if(!e||!i)return;const s=e.isPaused();e.source.pause();const n=e.source.duration*t;e.source.currentTime=n,e.source.dispatchEvent(new CustomEvent(Et,{detail:{time:n}})),i.rootEl.classList.add(i.className.FIXED),this._wasPaused=!this._playPromise&&s},this._onControl=t=>{const e=this._video;if(!e)return;const i=e.source.duration*t;e.source.currentTime=i,e.source.dispatchEvent(new CustomEvent(Et,{detail:{time:i}}))},this._onRelease=()=>{const t=this._video,e=this._controlBar;t&&e&&(this._wasPaused||this._playPromise||(this._playPromise=t.source.play().catch((()=>{})),this._playPromise.then((()=>{this._playPromise=null})),e.rootEl.classList.remove(e.className.FIXED))),this._wasPaused=!1},this.position=t,this.order=e,this._controlBar=null,this._rangeControl=new ve,this._video=null,this._wasPaused=!1,this._currentTime=0,this._duration=0,this._playPromise=null}init(t,e){var i;const s=null===(i=t.projection)||void 0===i?void 0:i.getTexture(),n=this.element,o=this._rangeControl,r=e.className.UNAVAILABLE;s&&s.isVideo()?(n.classList.remove(r),n.classList.add(e.className.PROGRESS_ROOT),t.on(tt.RESIZE,this._onResize),s.source.addEventListener(D,this._onTimeUpdate),s.source.addEventListener(U,this._onDurationChange),s.source.addEventListener(Et,this._onTimeUpdate),o.init(e.className),o.on(nt,this._onHold),o.on(ot,this._onControl),o.on(rt,this._onRelease),this._video=s,this._currentTime=s.source.currentTime,this._duration=s.source.duration,this._controlBar=e,o.updateStyle(this._currentTime/this._duration)):n.classList.add(r)}destroy(t){const e=this._video;t.off(tt.RESIZE,this._onResize),e&&(e.source.removeEventListener(D,this._onTimeUpdate),e.source.removeEventListener(U,this._onDurationChange),e.source.removeEventListener(Et,this._onTimeUpdate)),this._rangeControl.destroy(),this._video=null,this._playPromise=null}}class Te extends me{constructor({position:t=ge.MAIN_LEFT,order:e=9999}={}){super({position:t,order:e}),this._onClick=()=>{const t=this._video;t&&(this._paused?t.source.play():t.source.pause())},this._onPlay=()=>{if(!this._controlBar)return;const t=this.element,e=this._controlBar.className;t.classList.add(e.PAUSE_BUTTON),t.classList.remove(e.PLAY_BUTTON),t.title="Pause Video",this._paused=!1},this._onPause=()=>{if(!this._controlBar)return;const t=this.element,e=this._controlBar.className;t.classList.add(e.PLAY_BUTTON),t.classList.remove(e.PAUSE_BUTTON),t.title="Play Video",this._paused=!0},this.element=document.createElement(G),this._video=null,this._paused=!0,this._controlBar=null}init(t,e){var i;const s=this.element,n=null===(i=t.projection)||void 0===i?void 0:i.getTexture(),o=e.className,r=o.UNAVAILABLE;if(!n||!n.isVideo())return void s.classList.add(r);s.classList.add(o.CONTROLS_BUTTON),s.classList.remove(r);const a=n.isPaused();this._video=n,this._paused=a,this._controlBar=e,a?this._onPause():this._onPlay(),s.addEventListener(w,this._onClick),n.source.addEventListener(S,this._onPlay),n.source.addEventListener(P,this._onPause)}destroy(){const t=this._video,e=this.element;t&&(e.className="",e.removeEventListener(w,this._onClick),t.source.removeEventListener(S,this._onPlay),t.source.removeEventListener(P,this._onPause),this._video=null,this._paused=!0,this._controlBar=null)}}class be extends me{get element(){return this._rootEl}constructor({position:t=ge.MAIN_RIGHT,order:e=9999}={}){super({position:t,order:e}),this._onResize=()=>{this._rangeControl.resize(),this._updateDisplay()},this._onClick=()=>{const t=this._video;t&&!this._rootEl.disabled&&(t.source.muted=!t.source.muted)},this._onVolumeChange=()=>{const t=this._buttonEl,e=this._video,i=this._controlBar;if(!e||!i)return;const s=i.className;e.source.muted||0===e.source.volume?(t.classList.add(s.MUTED_BUTTON),t.classList.remove(s.UNMUTED_BUTTON)):(t.classList.add(s.UNMUTED_BUTTON),t.classList.remove(s.MUTED_BUTTON)),this._updateDisplay()},this._onHold=t=>{const e=this._video,i=this._controlBar;if(!e||!i)return;const s=i.className;e.source.volume=t,this._rootEl.classList.add(s.FIXED),i.containerEl.classList.add(s.FIXED),this._updateDisplay()},this._onChange=t=>{const e=this._video;e&&(e.source.volume=t,e.source.muted=!(t>0),this._updateDisplay())},this._onRelease=()=>{const t=this._controlBar;if(!t)return;const e=t.className;this._rootEl.classList.remove(e.FIXED),t.containerEl.classList.remove(e.FIXED)},this._updateDisplay=()=>{const t=this._video,e=this._rootEl;if(!t)return;if(!t.hasAudio())return void(e.disabled=!0);e.disabled=!1;const i=t.source.muted?0:t.source.volume;this._rangeControl.updateStyle(i)},this._controlBar=null,this._rangeControl=new ve,this._createElements(),this._video=null}init(t,e){var i;const s=null===(i=t.projection)||void 0===i?void 0:i.getTexture(),n=this._rootEl,o=this._buttonEl,r=this._rangeControl,a=e.className,h=a.UNAVAILABLE;s&&s.isVideo()?(n.classList.remove(h),n.classList.add(a.CONTROLS_BUTTON),n.classList.add(a.VOLUME_ROOT),o.classList.add(a.CONTROLS_BUTTON),s.source.muted?o.classList.add(a.MUTED_BUTTON):o.classList.add(a.UNMUTED_BUTTON),t.on(tt.RESIZE,this._onResize),n.addEventListener(F,this._onResize),o.addEventListener(w,this._onClick),s.source.addEventListener(M,this._onVolumeChange),s.source.addEventListener(N,this._updateDisplay),s.source.addEventListener(B,this._updateDisplay),r.init(a),r.on(nt,this._onHold),r.on(ot,this._onChange),r.on(rt,this._onRelease),this._controlBar=e,this._video=s,this._updateDisplay()):n.classList.add(h)}destroy(t){const e=this._video,i=this._buttonEl,s=this._rootEl;s.className="",i.className="",t.off(tt.RESIZE,this._onResize),s.removeEventListener(F,this._onResize),i.removeEventListener(w,this._onClick),e&&(e.source.removeEventListener(M,this._onVolumeChange),e.source.removeEventListener(N,this._updateDisplay),e.source.removeEventListener(B,this._updateDisplay)),this._controlBar=null,this._rangeControl.destroy(),this._video=null}_createElements(){const t=document.createElement(G),e=document.createElement(V);t.appendChild(this._rangeControl.rootEl),t.appendChild(e),t.title="Toggle Mute",this._rootEl=t,this._buttonEl=e}}class fe extends me{constructor({position:t=ge.MAIN_RIGHT,order:e=9999}={}){super({position:t,order:e}),this._onClick=()=>{const t=this._targetEl;t&&(Nt()?this._exitFullscreen():this._requestFullscreen(t))},this._onFullscreenChange=()=>{const t=this.element,e=this._controlBar;if(!e)return;const i=e.className;Nt()?(t.classList.add(i.FULLSCREEN_EXIT_BUTTON),t.classList.remove(i.FULLSCREEN_BUTTON)):(t.classList.add(i.FULLSCREEN_BUTTON),t.classList.remove(i.FULLSCREEN_EXIT_BUTTON))},this.element=document.createElement(G),this.element.title="Toggle Fullscreen",this._controlBar=null,this._targetEl=null}init(t,e){const i=this.element,s=e.className;this._fullscreenAvailable()?(i.classList.add(s.CONTROLS_BUTTON),i.classList.remove(s.UNAVAILABLE),i.addEventListener(w,this._onClick),this._addFullscreenHandlers(),Nt()?i.classList.add(s.FULLSCREEN_EXIT_BUTTON):i.classList.add(s.FULLSCREEN_BUTTON),this._controlBar=e,this._targetEl=t.rootEl):i.classList.add(s.UNAVAILABLE)}destroy(){const t=this.element;t.className="",t.removeEventListener(w,this._onClick),this._removeFullscreenHandlers(),this._controlBar=null,this._targetEl=null}_fullscreenAvailable(){return K.some((t=>!!document[t]))}_requestFullscreen(t){for(const e of K){const i=t[e];if(i)return void i.call(t)}}_exitFullscreen(){for(const t of $){const e=document[t];if(e)return void e.call(document)}}_addFullscreenHandlers(){Q.forEach((t=>{document.addEventListener(t,this._onFullscreenChange)}))}_removeFullscreenHandlers(){Q.forEach((t=>{document.removeEventListener(t,this._onFullscreenChange)}))}}class Re extends me{constructor({position:t=ge.MAIN_LEFT,order:e=9999}={}){super({position:t,order:e}),this._onTimeUpdate=()=>{const t=this._video;t&&(this._currentTime=t.source.currentTime,this._updateDisplay())},this._onDurationChange=()=>{const t=this._video;t&&(this._duration=t.source.duration,this._updateDisplay())},this._onCustomTimeChange=t=>{this._currentTime=t.detail.time,this._updateDisplay()},this.element=document.createElement(V),this._video=null,this._currentTime=0,this._duration=0}init(t,e){var i;const s=null===(i=t.projection)||void 0===i?void 0:i.getTexture(),n=this.element,o=e.className;s&&s.isVideo()?(n.classList.add(o.VIDEO_TIME_DISPLAY),n.classList.remove(o.UNAVAILABLE),s.source.addEventListener(D,this._onTimeUpdate),s.source.addEventListener(U,this._onDurationChange),s.source.addEventListener(Et,this._onCustomTimeChange),this._video=s,this._currentTime=s.source.currentTime,this._duration=s.source.duration,this._updateDisplay()):n.classList.add(o.UNAVAILABLE)}destroy(){const t=this._video;t&&(this.element.className="",t.source.removeEventListener(D,this._onTimeUpdate),t.source.removeEventListener(U,this._onDurationChange),t.source.removeEventListener(Et,this._onCustomTimeChange),this._video=null)}_updateDisplay(){const t=this._currentTime,e=Math.floor(t/60),i=Math.floor(t-60*e),s=i<10?`0${i}`:i,n=this._duration,o=Math.floor(n/60),r=Math.floor(n-60*o),a=r<10?`0${r}`:r;this.element.innerText=`${e}:${s} / ${o}:${a}`}}class ye extends me{constructor({resetCamera:t=!0,position:e=ge.TOP_RIGHT,order:i=9999}={}){super({position:e,order:i}),this._onClick=()=>{const t=this._viewer,e=this.resetCamera;if(!t||!e)return;const{yaw:i=t.initialYaw,pitch:s=t.initialPitch,zoom:n=t.initialZoom,duration:o=500}=At(e);t.camera.animateTo({yaw:i,pitch:s,zoom:n,duration:o})},this._updatePie=({target:t})=>{const e=this._piePathEl,i=this._rangeCircleEl,s=t.camera,n=s.getHorizontalFov(),o=s.getYawRange(s.zoom),r=.5*n,a=24*Math.PI,h=a*n/360,l=a*(s.yaw+r+90)/360;if(e.setAttribute("stroke-dasharray",`${h} ${a-h}`),e.setAttribute("stroke-dashoffset",`${l}`),isFinite(o.min)&&isFinite(o.max)){const t=45*Math.PI,e=(Ot(o.min,-180,180)-r)/360,s=(Ot(o.max,-180,180)+r)/360,n=t*Math.abs(s-e),a=-t*(e-.25);i.setAttribute("stroke-dasharray",`${n} ${t-n}`),i.setAttribute("stroke-dashoffset",`${a}`)}else i.setAttribute("stroke-dasharray",""),i.setAttribute("stroke-dashoffset","")},this.element=document.createElement(V),this.element.title="Reset view",this.resetCamera=t,this._createPieElements(),this._viewer=null}init(t,e){const i=this.element;t.initialized?this._updatePie({target:t}):t.once(tt.READY,this._updatePie);const s=e.className.PIEVIEW_ROOT;i.classList.add(s),this.resetCamera&&i.addEventListener(w,this._onClick),t.on(tt.VIEW_CHANGE,this._updatePie),this._viewer=t}destroy(t){const e=this.element;e.removeEventListener(w,this._onClick),e.className="",t.off(tt.READY,this._updatePie),t.off(tt.VIEW_CHANGE,this._updatePie),this._viewer=null}_createPieElements(){const t=this.element,e=document.createElementNS(Tt,"svg");e.setAttribute("viewBox","0 0 48 48"),e.setAttribute("width","100%"),e.setAttribute("height","100%");const i=document.createElementNS(Tt,"circle");i.setAttribute("stroke","currentColor"),i.setAttribute("fill","transparent"),i.setAttribute("cx","24"),i.setAttribute("cy","24"),i.setAttribute("r","12"),i.setAttribute("stroke-width","24"),e.appendChild(i);const s=document.createElementNS(Tt,"circle");s.setAttribute("stroke","currentColor"),s.setAttribute("fill","transparent"),s.setAttribute("cx","24"),s.setAttribute("cy","24"),s.setAttribute("r","22.5"),s.setAttribute("stroke-width","3"),e.appendChild(s),t.appendChild(e),this._piePathEl=i,this._rangeCircleEl=s}}class we extends me{constructor({position:t=ge.MAIN_RIGHT,order:e=9999}={}){super({position:t,order:e}),this._onClick=()=>{const t=this._viewer;t&&t.vr.enter()},this.element=document.createElement(G),this.element.title="Enter VR",this._viewer=null}init(t,e){const i=this.element,s=e.className;i.classList.add(s.UNAVAILABLE),i.classList.add(s.VR_BUTTON),i.classList.add(s.CONTROLS_BUTTON),t.vr.isAvailable().then((t=>{t&&i.classList.remove(s.UNAVAILABLE)})),i.addEventListener(w,this._onClick),this._viewer=t}destroy(){const t=this.element;t.className="",t.removeEventListener(w,this._onClick),this._viewer=null}}class Le extends me{constructor({position:t=ge.MAIN_RIGHT,order:e=9999}={}){super({position:t,order:e}),this._onClick=()=>{const t=this._viewer,e=this._controlBar;if(!t||!e)return;const i=t.control.gyro;i.enabled?i.disable():Kt.requestSensorPermission().then((t=>{t?i.enable():this.element.classList.add(e.className.UNAVAILABLE)}))},this._updateStyle=()=>{const t=this.element,e=this._viewer,i=this._controlBar;if(!e||!i)return;const s=e.control.gyro,n=i.className;s.enabled?(t.classList.add(n.GYRO_ENABLED),t.classList.remove(n.GYRO_DISABLED)):(t.classList.add(n.GYRO_DISABLED),t.classList.remove(n.GYRO_ENABLED))},this.element=document.createElement(V),this.element.title="Toggle gyroscope control"}init(t,e){const i=this.element,s=e.className;i.addEventListener(w,this._onClick),i.classList.add(s.CONTROLS_BUTTON),i.classList.add(s.UNAVAILABLE);const n=()=>{i.classList.remove(s.UNAVAILABLE),t.control.gyro.on(at,this._updateStyle),t.control.gyro.on(ht,this._updateStyle)};Mt()?n():Kt.isAvailable().then((t=>{t&&n()})),this._controlBar=e,this._viewer=t,this._updateStyle()}destroy(t){const e=this.element;t.control.gyro.off(at,this._updateStyle),t.control.gyro.off(ht,this._updateStyle),e.removeEventListener(w,this._onClick),e.className="",this._controlBar=null,this._viewer=null}}class Ce{get enabled(){return!!this._targetEl}get hidden(){return this._controlBar.containerEl.classList.contains(this._hiddenClass)}get _hiddenClass(){return this._controlBar.className.HIDDEN}get _fixedClass(){return this._controlBar.className.FIXED}constructor(t,{initialDelay:e=3e3,delay:i=0,idleDelay:s=3e3}){this._onMouseEnter=()=>{this._isCursorInside=!0,this.show()},this._onMouseLeave=()=>{this._isCursorInside=!1,this._hideAfterDelay()},this._onMouseMove=()=>{this._isFullscreen&&this.showTemporaliy()},this._onHold=t=>{this._isGrabbing=!0,"mouse"===t.pointerType&&(this._isCursorInside=!0),window.addEventListener(d,this._onRelease),this.show()},this._onRelease=()=>{this._isGrabbing=!1,window.removeEventListener(d,this._onRelease),this._hideAfterDelay()},this._onVideoPlay=()=>{this._targetEl&&this._controlBar.containerEl.classList.remove(this._fixedClass)},this._onVideoPause=()=>{this._targetEl&&this._controlBar.containerEl.classList.add(this._fixedClass)},this._onFullscreenChange=()=>{this._isFullscreen=Nt(),this._isFullscreen&&this._hideAfterDelay()},this._controlBar=t,this._initialDelay=e,this._delay=i,this._idleDelay=s,this._timer=-1,this._isCursorInside=!1,this._isGrabbing=!1,this._isFullscreen=!1,this._video=null,this._targetEl=null}enable(t){var e;this._targetEl&&this.disable(t);const i=this._initialDelay,s=t.rootEl;this._targetEl=t.rootEl,this._timer=window.setTimeout((()=>{this.hide()}),i),s.addEventListener(u,this._onHold),s.addEventListener(b,this._onMouseEnter),s.addEventListener(_,this._onMouseMove),s.addEventListener(f,this._onMouseLeave),this._addFullscreenHandlers();const n=null===(e=t.projection)||void 0===e?void 0:e.getTexture();n&&n.isVideo()&&(n.isPaused()&&this._controlBar.containerEl.classList.add(this._fixedClass),n.source.addEventListener(S,this._onVideoPlay),n.source.addEventListener(P,this._onVideoPause),this._video=n)}disable(t){if(!this._targetEl)return;const e=this._controlBar,i=t.rootEl,s=this._video;i.removeEventListener(u,this._onHold),window.removeEventListener(d,this._onRelease),i.removeEventListener(b,this._onMouseEnter),i.removeEventListener(_,this._onMouseMove),i.removeEventListener(f,this._onMouseLeave),this._removeFullscreenHandlers(),window.clearTimeout(this._timer),e.containerEl.classList.remove(this._fixedClass),s&&(s.source.removeEventListener(S,this._onVideoPlay),s.source.removeEventListener(P,this._onVideoPause)),this._isCursorInside=!1,this._isGrabbing=!1,this._video=null,this._targetEl=null}show(){this._clearHideTimer(),this._controlBar.containerEl.classList.remove(this._hiddenClass)}showTemporaliy(){this.show(),this._hideAfterDelay(this._idleDelay)}hide(){this._clearHideTimer(),this._controlBar.containerEl.classList.add(this._hiddenClass)}_clearHideTimer(){this._timer&&(window.clearTimeout(this._timer),this._timer=-1)}_hideAfterDelay(t=this._delay){this._isGrabbing||!this._isFullscreen&&this._isCursorInside||(this._clearHideTimer(),t<=0?this.hide():this._timer=window.setTimeout((()=>{this.hide()}),t))}_addFullscreenHandlers(){Q.forEach((t=>{document.addEventListener(t,this._onFullscreenChange)}))}_removeFullscreenHandlers(){Q.forEach((t=>{document.removeEventListener(t,this._onFullscreenChange)}))}}class xe{constructor(){this._onKeyDown=t=>{const e=this._video;if(!e)return;t.preventDefault(),t.stopPropagation();const i=e.source,s=null!=t.keyCode?W[t.keyCode]:q[t.key];switch(s){case"LEFT":case"RIGHT":return this._changeVideoTime(i,"RIGHT"===s);case"UP":case"DOWN":return this._changeVideoVolume(i,"UP"===s)}(32===t.keyCode||" "===t.key)&&this._toggleVideo(e)}}enable(t,e){this._video=e,t.addEventListener(R,this._onKeyDown,!0)}disable(t){this._video=null,t.removeEventListener(R,this._onKeyDown,!0)}_changeVideoTime(t,e){const i=e?5:-5;t.currentTime+=i,t.dispatchEvent(new CustomEvent(Et,{detail:{time:t.currentTime}}))}_changeVideoVolume(t,e){const i=e?.1:-.1;t.muted?t.volume=Ct(i,0,1):t.volume=Ct(t.volume+i,0,1),t.volume>0?t.muted=!1:t.muted=!0}_toggleVideo(t){t.isPaused()?t.source.play():t.source.pause()}}class Oe{get rootEl(){return this._rootEl}get containerEl(){return this._containerEl}get backgroundEl(){return this._bgEl}get items(){return this._items}get customItems(){return this._customItems}constructor({autoHide:t,showBackground:e,clickToPlay:i=!0,keyboardControls:s=!0,progressBar:n=!0,playButton:o=!0,volumeButton:r=!0,fullscreenButton:a=!0,videoTime:h=!0,pieView:l=!0,vrButton:c=!0,gyroButton:u=!0,className:_={},customItems:d=[]}={}){var m;this._onStaticClick=({target:t,isTouch:e})=>{var i;const s=this._autoHider;if(e){if(!s.enabled)return;s.hidden?s.showTemporaliy():s.hide()}else{if(!this.clickToPlay)return;const e=null===(i=t.projection)||void 0===i?void 0:i.getTexture();if(!e||!e.isVideo())return;e.isPaused()?e.source.play():e.source.pause()}},this._onNewSrcLoad=({target:t})=>{const e=this._items;this._updateBackground(t),this._updateAutoHide(t),this._updateKeyboardHandler(t),Object.keys(e).forEach((i=>{e[i].forEach((e=>{e.destroy(t,this),e.init(t,this)}))}))},this.autoHide=t,this.showBackground=e,this.clickToPlay=i,this.keyboardControls=s,this.progressBar=n,this.playButton=o,this.volumeButton=r,this.fullscreenButton=a,this.videoTime=h,this.pieView=l,this.vrButton=c,this.gyroButton=u,this.className=Object.assign(Object.assign({},Oe.DEFAULT_CLASS),_);const p=null!==(m=_.CONTROLS_ROOT)&&void 0!==m?m:Oe.DEFAULT_CLASS.CONTROLS_ROOT;this._rootEl=wt(p),this._createPositionWrappers(),this._items=Object.keys(Oe.POSITION).reduce(((t,e)=>(t[Oe.POSITION[e]]=[],t)),{}),this._customItems=d,this._autoHider=new Ce(this,At(t)),this._videoControl=new xe,d.forEach((t=>{this._items[t.position].push(t)}))}init(t){const e=t.rootEl,i=this._rootEl,s=this._createDefaultItems();this._updateBackground(t),this._updateAutoHide(t),this._updateKeyboardHandler(t),e.appendChild(i),this._addItem(t,s),this._addItem(t,this._customItems),t.on(tt.PROJECTION_CHANGE,this._onNewSrcLoad),t.on(tt.STATIC_CLICK,this._onStaticClick)}destroy(t){const e=t.rootEl,i=this._rootEl,s=this._items;i.parentElement===e&&e.removeChild(i),Object.keys(s).forEach((e=>{s[e].forEach((e=>{e.destroy(t,this)})),s[e]=[]})),this._clearItemElements(),this._autoHider.disable(t),this._videoControl.disable(e),t.off(tt.PROJECTION_CHANGE,this._onNewSrcLoad),t.off(tt.STATIC_CLICK,this._onStaticClick)}_addItem(t,e){for(const i of e){const e=this._items[i.position],s=this._wrapperEl[i.position],n=It(e,(t=>t.order>i.order));if(n>=0){const t=e[n].element;e.splice(n,0,i),s.insertBefore(i.element,t)}else e.push(i),s.appendChild(i.element);i.init(t,this)}}_createPositionWrappers(){const t=Object.assign(Object.assign({},Oe.DEFAULT_CLASS),this.className),e=this._rootEl,i=wt(t.CONTROLS_BG),s=wt(t.CONTROLS_FLOAT_LEFT),n=wt(t.CONTROLS_FLOAT_RIGHT);e.appendChild(s),e.appendChild(n);const o=wt(t.CONTROLS_MAIN),r=wt(t.CONTROLS_TOP),a=wt(t.CONTROLS_BOTTOM),h=wt(t.CONTROLS_MID),l=wt(t.CONTROLS_LEFT),c=wt(t.CONTROLS_RIGHT);h.appendChild(l),h.appendChild(c),o.appendChild(i),o.appendChild(r),o.appendChild(h),o.appendChild(a),e.appendChild(o),this._bgEl=i,this._containerEl=o,this._wrapperEl={[Oe.POSITION.MAIN_TOP]:r,[Oe.POSITION.MAIN_LEFT]:l,[Oe.POSITION.MAIN_RIGHT]:c,[Oe.POSITION.MAIN_BOTTOM]:a,[Oe.POSITION.TOP_LEFT]:s,[Oe.POSITION.TOP_RIGHT]:n}}_clearItemElements(){Object.keys(Oe.POSITION).map((t=>Oe.POSITION[t])).forEach((t=>{for(;t.firstChild;)t.removeChild(t.firstChild)}))}_updateAutoHide(t){var e;const i=this.autoHide,s=this._autoHider;if(null!=i)i?s.enable(t):s.disable(t);else{const i=null===(e=t.projection)||void 0===e?void 0:e.getTexture();i&&i.isVideo()?s.enable(t):s.disable(t)}}_updateBackground(t){var e,i;const s=this._bgEl,n=this.showBackground,o=null!==(e=this.className.HIDDEN)&&void 0!==e?e:Oe.DEFAULT_CLASS.HIDDEN;if(null!=n)n?s.classList.remove(o):s.classList.add(o);else{const e=null===(i=t.projection)||void 0===i?void 0:i.getTexture();e&&e.isVideo()?s.classList.remove(o):s.classList.add(o)}}_updateKeyboardHandler(t){var e;const i=t.rootEl,s=this._videoControl,n=null===(e=t.projection)||void 0===e?void 0:e.getTexture();this.keyboardControls&&n&&n.isVideo()?s.enable(i,n):s.disable(i)}_createDefaultItems(){const t=[];return this.progressBar&&t.push(new Ee(At(this.progressBar))),this.playButton&&t.push(new Te(At(this.playButton))),this.volumeButton&&t.push(new be(At(this.volumeButton))),this.gyroButton&&t.push(new Le(At(this.gyroButton))),this.vrButton&&t.push(new we(At(this.vrButton))),this.fullscreenButton&&t.push(new fe(At(this.fullscreenButton))),this.videoTime&&t.push(new Re(At(this.videoTime))),this.pieView&&t.push(new ye(At(this.pieView))),t}}Oe.DEFAULT_CLASS=pe,Oe.POSITION=ge;class Ie{constructor({src:t,video:e=!1}){this.src=t,this.video=e,this._mesh=null}releaseAllResources(t){var e;null===(e=this._mesh)||void 0===e||e.destroy(t)}updateCamera(t){t.resetRange()}updateControl(t){t.ignoreZoomScale=!1}update(t){}getTexture(){return this._mesh?this._mesh.program.uniforms.uTexture.texture:null}getMesh(){return this._mesh}}class Ae{constructor(){this.needsUpdate=!0}destroy(t){}}class Se extends Ae{constructor(t,e,i){super(),this.texture=e,this._webglTexture=t.createWebGLCubeTexture(e,e.width),this._cubemapOrder=i}destroy(t){this.texture.destroy(),t.deleteTexture(this._webglTexture)}update(t,e,i){const s=this.texture;t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,s.flipY),t.uniform1i(e,0),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_CUBE_MAP,this._webglTexture);Pt(s.sources,this._cubemapOrder).forEach(((e,s)=>{i?t.texSubImage2D(t.TEXTURE_CUBE_MAP_POSITIVE_X+s,0,0,0,t.RGBA,t.UNSIGNED_BYTE,e):t.texImage2D(t.TEXTURE_CUBE_MAP_POSITIVE_X+s,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e)})),s.isVideo()||(this.needsUpdate=!1)}}class Pe{get size(){return this._size}constructor(t,e){var i;this.texture=t,this._renderingOrder=Pt(!(i=6)||i<=0?[]:Array.apply(0,Array(i)).map(((t,e)=>e)),e);const s=document.createElement("canvas");this._calcRenderingSize(),s.width=this._size,s.height=this._size,this._canvas=s,this._ctx=s.getContext("2d")}destroy(){const t=this._canvas;t.width=1,t.height=1,this._canvas=null}draw(t,e){const i=this._size,s=this.texture;let n=0;for(let o=0;o=0;t--)for(let e=0;e<3;e++){const n=[e*i,.5*t,(e+1)*i,.5*t,(e+1)*i,.5*(t+1),e*i,.5*(t+1)];s.push(n)}e&&e.forEach(((t,e)=>{if(t===vt.ZERO)return;const i=s[e];let n;n=t===vt.CW_90?[1,2,3,0]:t===vt.CCW_90?[3,0,1,2]:[2,3,0,1];const o=Array(i.length);for(let t=0;tt.concat(e)),[]))}}class ze extends Ae{constructor(t,e){super(),this.texture=e,this._webglTexture=t.createWebGLTexture(e)}destroy(t){this.texture.destroy(),t.deleteTexture(this._webglTexture)}update(t,e,i){const s=this.texture,n=s.isVideo();t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,s.flipY),t.uniform1i(e,0),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this._webglTexture),!n&&i?t.texSubImage2D(t.TEXTURE_2D,0,0,0,t.RGBA,t.UNSIGNED_BYTE,s.source):t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,s.source),n||(this.needsUpdate=!1)}}var Ve="#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec2 vUV;void main(){vUV=uv;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}",Ge="#define GLSLIFY 1\nuniform sampler2D uTexture;varying highp vec2 vUV;void main(){gl_FragColor=texture2D(uTexture,vUV.st);}";class ke extends Be{constructor(t){const e=[],i=[],s=[],n=[-.5,.5],o=1/60,r=t*o;for(let a=0;a<2;a++){const h=n[a];for(let n=0;n<=60;n++){const l=n*r+Math.PI-.5*t,c=Math.cos(l),u=Math.sin(l),_=n*o,d=a;if(s.push(_,d),e.push(c,h,u),0===a&&n<60){const t=n,e=t+60+1;i.push(t,e,t+1,e,e+1,t+1)}}}super(e,i,s)}}class Ye extends Be{constructor(){const t=60,e=-.5*Math.PI,i=[],s=[],n=[];let o,r;for(o=0;o<=60;o++){const a=(o/60-.5)*Math.PI,h=Math.sin(a),l=Math.cos(a);for(r=0;r<=t;r++){const a=2*(r/t-.5)*Math.PI+e,c=Math.sin(a),u=Math.cos(a)*l,_=h,d=c*l,m=r/t,p=o/60;if(i.push(m,p),s.push(u,_,d),r!==t&&60!==o){const e=61*o+r,i=e+t+1;n.push(e,e+1,i,i,e+1,i+1)}}}super(s,n,i)}}class He extends Ae{constructor(t){super(),this.val=t}update(t,e){t.uniform1f(e,this.val),this.needsUpdate=!1}}class Xe extends Be{constructor(t=2,e=2,i=-1){const s=.5*t,n=.5*e;super([-s,-n,i,s,-n,i,-s,n,i,s,n,i],[0,1,2,2,1,3],[0,0,1,0,0,1,1,1])}}class je extends Ae{constructor(t){super(),this.val=t}update(t,e){t.uniform4fv(e,this.val.reduce(((t,e)=>[...t,...e]),[])),this.needsUpdate=!1}}class We extends Ie{constructor(t){super(t),this._mode=t.mode}applyTexture(t,e){let i,s;if(this._mode===We.MODE.LEFT_RIGHT)i=[.5,1,0,0],s=[.5,1,.5,0];else i=[1,.5,0,0],s=[1,.5,0,.5];const n={uTexture:new ze(t,e),uEye:new He(0),uTexScaleOffset:new je([i,s])},o=new Ye,r=new De(t,"#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;uniform vec4 uTexScaleOffset[2];uniform float uEye;varying highp vec2 vUV;void main(){vec4 scaleOffset=uTexScaleOffset[int(uEye)];vUV=uv.xy*scaleOffset.xy+scaleOffset.zw;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}",Ge,n),a=t.createVAO(o,r),h=new Me(a,r);this._mesh=h}}We.MODE={LEFT_RIGHT:"left_right",TOP_BOTTOM:"top_bottom"};var qe={__proto__:null,default:ue,Autoplay:ne,AutoResizer:se,Camera:zt,CameraAnimation:Ft,Motion:Bt,Object3D:_e,View360Error:a,WebGLRenderer:ce,XRManager:oe,PanoControl:Zt,RotateControl:Yt,ZoomControl:jt,GyroControl:Kt,ControlBar:Oe,ControlBarItem:me,FullscreenButton:fe,PieView:ye,PlayButton:Te,ProgressBar:Ee,VideoTime:Re,VolumeControl:be,LoadingSpinner:de,Projection:Ie,CubemapProjection:class extends Ie{constructor(t){super(t);const{cubemapOrder:e="RLUDFB",cubemapFlipX:i=!1}=t;this._cubemapOrder=e,this._cubemapFlipX=i}applyTexture(t,e){const i=this._cubemapOrder,s=this._cubemapFlipX,n={uTexture:e.isCube()?new Se(t,e,i):new Ne(t,e,i)},o=new Fe({order:i}),r=new De(t,"#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec3 vPos;void main(){vPos=position;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}","#define GLSLIFY 1\nuniform samplerCube uTexture;varying highp vec3 vPos;void main(){gl_FragColor=textureCube(uTexture,vec3(vPos.x,vPos.y,-vPos.z));}",n),a=t.createVAO(o,r),h=new Me(a,r);s&&(h.scale[0]=-1),h.updateMatrix(),this._mesh=h}},CubestripProjection:class extends Ie{constructor(t){super(t);const{cubemapOrder:e="RLUDFB",cubemapFlipX:i=!1}=t;this._cubemapOrder=e,this._cubemapFlipX=i}applyTexture(t,e){const i=this._cubemapOrder,s=this._cubemapFlipX,n={uTexture:new ze(t,e)},o=new Fe({order:i}),r=new De(t,Ve,Ge,n),a=t.createVAO(o,r),h=new Me(a,r);s&&(h.scale[0]=-1),h.updateMatrix(),this._mesh=h}},CylindricalProjection:class extends Ie{constructor(t){super(t);const{partial:e=!1}=t;this._partial=e}applyTexture(t,i){const s=this._partial,{width:n,height:o}=i,r=n/o,a=180/r,h=s?1:2*Math.tan(a*ct),l=s?r:2*Math.PI,c=new ke(l),u=new De(t,Ve,Ge,{uTexture:new ze(t,i)}),_=t.createVAO(c,u),d=new Me(_,u);d.scale[1]=h,e.quat.identity(d.rotation),e.quat.rotateY(d.rotation,d.rotation,-Math.PI/2),d.updateMatrix(),this._mesh=d}updateCamera(t){super.updateCamera(t);const e=this._mesh;if(!e)return;const i=e.program.uniforms.uTexture.texture,{width:s,height:n}=i,o=s/n,r=.5*e.scale[1];if(this._partial){const e=.5*o*ut;t.restrictYawRange(-e,e)}const a=Math.atan2(r,1)*ut,h=Math.tan(t.fov*ct*.5)/(r*t.aspect);t.restrictPitchRange(-a,a),t.restrictZoomRange(h,1/0),t.restrictRenderHeight(2*r)}},EquiangularProjection:class extends Ie{applyTexture(t,e){const i={uTexture:new ze(t,e)},s=new Fe({order:"LFRDBU",rotateUV:[vt.ZERO,vt.ZERO,vt.ZERO,vt.CW_90,vt.CCW_90,vt.CW_90]}),n=new De(t,Ve,"#define PI 3.14159265359\nprecision mediump float;\n#define GLSLIFY 1\nuniform sampler2D uTexture;varying highp vec2 vUV;const vec2 OPERATE_COORDS_RANGE=vec2(-1.0,1.0);const vec2 TEXTURE_COORDS_RANGE=vec2(0.0,1.0);const float ONE_THIRD=1.0/3.0;const float EAC_CONST=2.0/PI;float scale(vec2 domainRange,vec2 targetRange,float val){float unit=1.0/(domainRange[1]-domainRange[0]);return targetRange[0]+(targetRange[1]-targetRange[0])*(val-domainRange[0])*unit;}void main(void){float transformedCoordX;float transformedCoordY;float texRangeXStart=floor(vUV.s*3.)*ONE_THIRD;float texRangeYStart=floor(vUV.t*2.)*0.5;vec2 orgTextureRangeX=vec2(texRangeXStart,texRangeXStart+ONE_THIRD);vec2 orgTextureRangeY=vec2(texRangeYStart,texRangeYStart+0.5);float px=scale(orgTextureRangeX,OPERATE_COORDS_RANGE,vUV.s);float py=scale(orgTextureRangeY,OPERATE_COORDS_RANGE,vUV.t);float qu=EAC_CONST*atan(px)+0.5;float qv=EAC_CONST*atan(py)+0.5;transformedCoordX=scale(TEXTURE_COORDS_RANGE,orgTextureRangeX,qu);transformedCoordY=scale(TEXTURE_COORDS_RANGE,orgTextureRangeY,qv);gl_FragColor=texture2D(uTexture,vec2(transformedCoordX,transformedCoordY));}",i),o=t.createVAO(s,n),r=new Me(o,n);this._mesh=r}},EquirectProjection:class extends Ie{constructor(t){super(t)}applyTexture(t,e){const i={uTexture:new ze(t,e)},s=new Ye,n=new De(t,Ve,Ge,i),o=t.createVAO(s,n),r=new Me(o,n);this._mesh=r}},LittlePlanetProjection:class extends Ie{constructor(t){super(t)}applyTexture(t,e){e.wrapS=WebGLRenderingContext.REPEAT,e.wrapT=WebGLRenderingContext.REPEAT;const i={uTexture:new ze(t,e),uYaw:new He(0),uPitch:new He(.5),uZoom:new He(1)},s=new Xe,n=new De(t,"#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec2 vUV;void main(){vUV=uv;gl_Position=vec4(position,1.0);}","precision mediump float;\n#define GLSLIFY 1\nuniform sampler2D uTexture;uniform float uYaw;uniform float uPitch;uniform float uZoom;varying highp vec2 vUV;const float PI=3.1415926536;const float PI_2=PI*0.5;vec2 toStereographicUV(in vec2 uv,in vec2 center){float R=1.*uZoom;vec2 texLatLon=(uv*2.-1.)*vec2(PI,PI_2);vec2 central=(center*2.-1.)*vec2(PI,PI_2)+vec2(PI,0);float x=texLatLon.x;float y=texLatLon.y;float rou=sqrt(x*x+y*y);float c=2.0*atan(rou,R*0.5);float sin_c=sin(c);float cos_c=cos(c);float sin_cy=sin(central.y);float cos_cy=cos(central.y);float lat=asin(cos_c*sin_cy+(y*sin_c*cos_cy)/rou);float lon=central.x+atan(x*sin_c,rou*cos_cy*cos_c-y*sin_cy*sin_c);float u=(lon/PI+1.0)*0.5;float v=(lat/PI_2+1.0)*0.5;return vec2(u,v);}void main(){vec2 central=vec2(uYaw,uPitch);vec2 uv=toStereographicUV(vUV,central);gl_FragColor=texture2D(uTexture,uv);}",i),o=t.createVAO(s,n),r=new Me(o,n);this._mesh=r}updateControl(t){t.ignoreZoomScale=!0}update(t){const e=this._mesh;if(!e)return;const i=e.program.uniforms;i.uYaw.val=t.yaw/360,i.uPitch.val=t.pitch/180+.5,i.uZoom.val=t.zoom,i.uYaw.needsUpdate=!0,i.uPitch.needsUpdate=!0,i.uZoom.needsUpdate=!0}},StereoEquiProjection:We,Hotspot:re,HotspotRenderer:ae,ERROR_CODES:h,DEFAULT_CLASS:J,EVENTS:tt,EASING:et,getValidProps:t=>Object.keys(t).reduce(((e,i)=>(null!=t[i]&&(e[i]=t[i]),e)),{}),VIEW360_METHODS:["destroy","init","load","resize","addPlugins","removePlugins","renderFrame","on","hasOn","once","off","trigger"],withMethods:(t,e)=>{[n.default.prototype,ue.prototype].forEach((i=>{Object.getOwnPropertyNames(i).filter((t=>"_"!==t.charAt(0)&&"constructor"!==t)).forEach((s=>{const n=Object.getOwnPropertyDescriptor(i,s);if(n.value)Object.defineProperty(t,s,{value:function(...t){return n.value.call(this[e],...t)}});else{const i={};n.get&&(i.get=function(){var t;return this[e]&&(null===(t=n.get)||void 0===t?void 0:t.call(this[e]))}),n.set&&(i.set=function(...t){var i;return null===(i=n.set)||void 0===i?void 0:i.call(this[e],...t)}),Object.defineProperty(t,s,i)}}))}))}};return((t,...e)=>{e.forEach((e=>{Object.keys(e).forEach((i=>{const s=e[i];Array.isArray(t[i])&&Array.isArray(s)?t[i]=[...t[i],...s]:t[i]=s}))}))})(ue,qe),ue})); +//# sourceMappingURL=view360.min.js.map diff --git a/demo/release/4.0.0-beta.4/dist/view360.min.js.map b/demo/release/4.0.0-beta.4/dist/view360.min.js.map new file mode 100644 index 000000000..d048a9773 --- /dev/null +++ b/demo/release/4.0.0-beta.4/dist/view360.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"view360.min.js","sources":["../src/core/View360Error.ts","../src/const/error.ts","../src/const/browser.ts","../src/const/external.ts","../src/const/internal.ts","../src/utils.ts","../src/core/Motion.ts","../src/core/CameraAnimation.ts","../src/core/Camera.ts","../src/control/input/MouseInput.ts","../src/control/input/TouchInput.ts","../src/control/input/KeyboardInput.ts","../src/control/RotateControl.ts","../src/control/input/WheelInput.ts","../src/control/input/PinchInput.ts","../src/control/ZoomControl.ts","../src/control/input/GyroInput.ts","../src/control/GyroControl.ts","../src/control/PanoControl.ts","../src/texture/Texture.ts","../src/texture/Texture2D.ts","../src/texture/TextureVideo.ts","../src/texture/TextureCube.ts","../src/core/TextureLoader.ts","../src/core/FrameAnimator.ts","../src/core/AutoResizer.ts","../src/core/Autoplay.ts","../src/core/XRManager.ts","../src/hotspot/Hotspot.ts","../src/hotspot/HotspotRenderer.ts","../src/core/VertexArrayObject.ts","../src/core/WebGLContext.ts","../src/core/WebGLRenderer.ts","../src/View360.ts","../src/core/Object3D.ts","../src/plugin/LoadingSpinner/LoadingSpinner.ts","../src/plugin/ControlBar/ControlBarItem.ts","../src/plugin/ControlBar/const.ts","../src/plugin/ControlBar/RangeControl.ts","../src/plugin/ControlBar/ProgressBar.ts","../src/plugin/ControlBar/PlayButton.ts","../src/plugin/ControlBar/VolumeControl.ts","../src/plugin/ControlBar/FullscreenButton.ts","../src/plugin/ControlBar/VideoTime.ts","../src/plugin/ControlBar/PieView.ts","../src/plugin/ControlBar/VRButton.ts","../src/plugin/ControlBar/GyroButton.ts","../src/plugin/ControlBar/AutoHide.ts","../src/plugin/ControlBar/VideoControl.ts","../src/plugin/ControlBar/ControlBar.ts","../src/projection/Projection.ts","../src/uniform/Uniform.ts","../src/uniform/UniformTextureCube.ts","../src/core/CubeTexturePainter.ts","../src/uniform/UniformCanvasCube.ts","../src/core/TriangleMesh.ts","../src/core/ShaderProgram.ts","../src/core/VertexData.ts","../src/geometry/Geometry.ts","../src/geometry/CubeGeometry.ts","../src/uniform/UniformTexture2D.ts","../src/geometry/CylinderGeometry.ts","../src/geometry/SphereGeometry.ts","../src/uniform/UniformFloat.ts","../src/geometry/PlaneGeometry.ts","../src/uniform/UniformVector4Array.ts","../src/projection/StereoEquiProjection.ts","../src/projection/CubemapProjection.ts","../src/projection/CubestripProjection.ts","../src/projection/CylindricalProjection.ts","../src/projection/EquiangularProjection.ts","../src/projection/EquirectProjection.ts","../src/projection/LittlePlanetProjection.ts","../src/cfc/utils.ts","../src/cfc/const.ts","../src/cfc/withMethods.ts","../src/index.umd.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * Error thrown by {@link View360}\n * @ko {@link View360}이 발생시킨 에러\n * @since 4.0.0\n */\nclass View360Error extends Error {\n /**\n * Error code\n * @ko 에러 코드\n * @see ERROR_CODES\n */\n public code: number;\n\n /**\n * Create new instance of View360Error\n * @ko View360Error의 인스턴스를 생성합니다.\n * @param message - Error message {@ko 에러 메시지}\n * @param code - Error code {@ko 에러 코드}\n */\n public constructor(message: string, code: number) {\n super(message);\n\n Object.setPrototypeOf(this, View360Error.prototype);\n\n this.name = \"View360Error\";\n this.code = code;\n }\n}\n\nexport default View360Error;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * Error codes of {@link View360Error}\n * @ko {@link View360Error}가 가질 수 있는 에러 코드 값들\n * @since 4.0.0\n */\nexport const ERROR_CODES = {\n /**\n * The given value's type is not expected\n * @ko 주어진 값의 타입이 잘못되었을 경우\n * @since 4.0.0\n */\n WRONG_TYPE: 0,\n /**\n * The given value is not a supported option\n * @ko 잘못된 옵션을 받았을 경우\n * @since 4.0.0\n */\n WRONG_OPTION: 1,\n /**\n * The element with given CSS selector does not exist\n * @ko 주어진 CSS 셀렉터로 엘리먼트를 찾지 못했을 경우\n * @since 4.0.0\n */\n ELEMENT_NOT_FOUND: 2,\n /**\n * Couldn't find canvas element inside the given container element.\n * @ko 컨테이너 엘리먼트 내부에서 캔버스 엘리먼트를 찾지 못했을 경우\n * @since 4.0.0\n */\n CANVAS_NOT_FOUND: 3,\n /**\n * The browser does not support WebGL\n * @ko 브라우저가 WebGL을 지원하지 않는 경우\n * @since 4.0.0\n */\n WEBGL_NOT_SUPPORTED: 4,\n /**\n * Failed creating canvas 2D context\n * @ko 캔버스 2D 컨텍스트를 생성하지 못한 경우\n * @since 4.0.0\n */\n FAILED_CREATE_CONTEXT_2D: 5,\n /**\n * `init()` is called before setting {@link View360Options#projection}\n * @ko {@link View360Options#projection}을 설정하기 전에 `init()`이 호출된 경우\n * @since 4.0.0\n */\n PROVIDE_PROJECTION_FIRST: 6,\n /**\n * Failed linking WebGL program. Only can be thrown when {@link View360Options#debug} is `true`.\n * @ko WebGL 프로그램 링크에 실패한 경우. {@link View360Options#debug}를 `true`로 설정한 경우에만 발생할 수 있습니다.\n * @since 4.0.0\n */\n FAILED_LINKING_PROGRAM: 7,\n /**\n * Arguments are not sufficient for the given property.\n * @ko 프로퍼티에 값이 충분히 주어지지 않았을 때\n * @since 4.0.0\n */\n INSUFFICIENT_ARGS: 8\n} as const;\n\nexport const MESSAGES = {\n WRONG_TYPE: (val: any, types: string[]) => `${typeof val} is not a ${types.map(type => `\"${type}\"`).join(\" or \")}.`,\n WRONG_OPTION: (val: any, optionName: string) => `Bad option: given \"${val}\" for option \"${optionName}\".`,\n ELEMENT_NOT_FOUND: (query: string) => `Element with selector \"${query}\" not found.`,\n CANVAS_NOT_FOUND: \"The canvas element was not found inside the given root element.\",\n WEBGL_NOT_SUPPORTED: \"WebGL is not supported on this browser.\",\n FAILED_CREATE_CONTEXT_2D: \"Failed to create canvas 2D context\",\n PROVIDE_PROJECTION_FIRST: \"\\\"projection\\\" should be provided before initialization.\",\n FAILED_LINKING_PROGRAM: (msg: string | null, shaderLog: string | null) => `Failed linking WebGL program - \"${msg}\\nShader compile Log: ${shaderLog}`,\n INSUFFICIENT_ARGS: (val: any, name: string) => `Insufficient arguments: given \"${val}\" for \"${name}\".`\n};\n\nexport default {\n CODES: ERROR_CODES,\n MESSAGES\n};\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nexport const EVENTS = {\n MOUSE_DOWN: \"mousedown\",\n MOUSE_MOVE: \"mousemove\",\n MOUSE_UP: \"mouseup\",\n TOUCH_START: \"touchstart\",\n TOUCH_MOVE: \"touchmove\",\n TOUCH_END: \"touchend\",\n WHEEL: \"wheel\",\n RESIZE: \"resize\",\n CONTEXT_MENU: \"contextmenu\",\n MOUSE_ENTER: \"mouseenter\",\n MOUSE_LEAVE: \"mouseleave\",\n POINTER_DOWN: \"pointerdown\",\n POINTER_MOVE: \"pointermove\",\n POINTER_UP: \"pointerup\",\n POINTER_CANCEL: \"pointercancel\",\n POINTER_ENTER: \"pointerenter\",\n POINTER_LEAVE: \"pointerleave\",\n KEY_DOWN: \"keydown\",\n KEY_UP: \"keyup\",\n LOAD: \"load\",\n ERROR: \"error\",\n CLICK: \"click\",\n DOUBLE_CLICK: \"dblclick\",\n CONTEXT_CREATE_ERROR: \"webglcontextcreationerror\",\n CONTEXT_LOST: \"webglcontextlost\",\n CONTEXT_RESTORED: \"webglcontextrestored\",\n DEVICE_ORIENTATION: \"deviceorientation\",\n DEVICE_MOTION: \"devicemotion\",\n ORIENTATION_CHANGE: \"orientationchange\",\n VIDEO_PLAY: \"play\",\n VIDEO_PAUSE: \"pause\",\n VIDEO_LOADED_DATA: \"loadeddata\",\n VIDEO_VOLUME_CHANGE: \"volumechange\",\n VIDEO_TIME_UPDATE: \"timeupdate\",\n VIDEO_DURATION_CHANGE: \"durationchange\",\n VIDEO_CAN_PLAYTHROUGH: \"canplaythrough\",\n TRANSITION_END: \"transitionend\",\n XR_END: \"end\"\n} as const;\n\nexport const EL_DIV = \"div\";\nexport const EL_BUTTON = \"button\";\n\n// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button\nexport enum MOUSE_BUTTON {\n LEFT,\n MIDDLE,\n RIGHT\n}\n\nexport const CURSOR = {\n GRAB: \"grab\",\n GRABBING: \"grabbing\",\n NONE: \"\"\n} as const;\n\nexport const KEY_DIRECTION = [\"LEFT\", \"UP\", \"RIGHT\", \"DOWN\"] as const;\nexport enum DIRECTION_KEY_CODE {\n LEFT = 37,\n UP = 38,\n RIGHT = 39,\n DOWN = 40\n}\nexport const SPACE_KEY_CODE = 32;\n\nexport const DIRECTION_KEY_NAME = {\n LEFT: \"ArrowLeft\",\n UP: \"ArrowUp\",\n RIGHT: \"ArrowRight\",\n DOWN: \"ArrowDown\"\n} as const;\nexport const SPACE_KEY_NAME = \" \";\n\nexport const FULLSCREEN_REQUEST = [\n \"requestFullscreen\",\n \"webkitRequestFullscreen\",\n \"webkitRequestFullScreen\",\n \"webkitCancelFullScreen\",\n \"mozRequestFullScreen\",\n \"msRequestFullscreen\"\n];\n\nexport const FULLSCREEN_ELEMENT = [\n \"fullscreenElement\",\n \"webkitFullscreenElement\",\n \"webkitCurrentFullScreenElement\",\n \"mozFullScreenElement\",\n \"msFullscreenElement\"\n];\n\nexport const FULLSCREEN_EXIT = [\n \"exitFullscreen\",\n \"webkitExitFullscreen\",\n \"webkitCancelFullScreen\",\n \"mozCancelFullScreen\",\n \"msExitFullscreen\"\n];\n\nexport const FULLSCREEN_CHANGE = [\n \"fullscreenchange\",\n \"webkitfullscreenchange\",\n \"mozfullscreenchange\",\n \"MSFullscreenChange\"\n];\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nexport { ERROR_CODES } from \"./error\";\n\n/**\n * Default class names\n * @ko 기본 클래스 이름들\n * @since 4.0.0\n */\nexport const DEFAULT_CLASS = {\n CONTAINER: \"view360-container\",\n CANVAS: \"view360-canvas\",\n CTX_LOST: \"view360-ctx-lost\",\n IN_VR: \"view360-vr-presenting\",\n HOTSPOT_CONTAINER: \"view360-hotspots\",\n HOTSPOT: \"view360-hotspot\",\n HOTSPOT_VISIBLE: \"view360-hotspot-visible\",\n HOTSPOT_FLIP_X: \"view360-hotspot-flip-x\",\n HOTSPOT_FLIP_Y: \"view360-hotspot-flip-y\",\n} as const;\n\n/**\n * Event names\n * @ko 이벤트 이름들\n * @since 4.0.0\n * @example\n * ```ts\n * import View360, { EVENTS } from \"@egjs/view360\";\n *\n * const viewer = new View360(\"#el_id\");\n *\n * viewer.on(EVENTS.READY, evt => {\n * console.log(\"View360 is ready!\");\n * });\n * ```\n */\nexport const EVENTS = {\n READY: \"ready\",\n LOAD_START: \"loadStart\",\n LOAD: \"load\",\n PROJECTION_CHANGE: \"projectionChange\",\n RESIZE: \"resize\",\n BEFORE_RENDER: \"beforeRender\",\n RENDER: \"render\",\n INPUT_START: \"inputStart\",\n INPUT_END: \"inputEnd\",\n VIEW_CHANGE: \"viewChange\",\n STATIC_CLICK: \"staticClick\",\n VR_START: \"vrStart\",\n VR_END: \"vrEnd\"\n} as const;\n\n/**\n * Collection of predefined easing functions\n * @ko 미리 정의된 easing 함수들\n */\nexport const EASING = {\n LINEAR: (x: number) => x,\n SINE_WAVE: (x: number) => Math.sin(x * Math.PI * 2),\n EASE_OUT_CUBIC: (x: number) => 1 - Math.pow(1 - x, 3),\n EASE_OUT_BOUNCE: (x: number): number => {\n const n1 = 7.5625;\n const d1 = 2.75;\n\n if (x < 1 / d1) {\n return n1 * x * x;\n } else if (x < 2 / d1) {\n return n1 * (x -= 1.5 / d1) * x + 0.75;\n } else if (x < 2.5 / d1) {\n return n1 * (x -= 2.25 / d1) * x + 0.9375;\n } else {\n return n1 * (x -= 2.625 / d1) * x + 0.984375;\n }\n }\n} as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { EASING } from \"./external\";\nimport { Range } from \"../type/utils\";\n\nexport const CAMERA_EVENTS = {\n CHANGE: \"change\",\n ANIMATION_END: \"animationEnd\"\n} as const;\n\nexport const CONTROL_EVENTS = {\n INPUT_START: \"inputStart\",\n CHANGE: \"change\",\n INPUT_END: \"inputEnd\",\n ENABLE: \"enable\",\n DISABLE: \"disable\",\n STATIC_CLICK: \"staticClick\"\n} as const;\n\nexport const DEG_TO_RAD = Math.PI / 180;\nexport const RAD_TO_DEG = 180 / Math.PI;\nexport const DEFAULT_EASING = EASING.EASE_OUT_CUBIC;\nexport const DEFAULT_ANIMATION_DURATION = 300;\nexport const INFINITE_RANGE: Readonly = {\n min: -Infinity, max: Infinity\n} as const;\nexport const DEFAULT_PITCH_RANGE: Readonly = {\n min: -90, max: 90\n} as const;\nexport const DEFAULT_ZOOM_RANGE: Readonly = {\n min: 0.6, max: 10\n} as const;\n\nexport enum ROTATE {\n ZERO,\n CW_90,\n CCW_90,\n CW_180\n}\n\n// Custom event name for video time change\nexport const VIDEO_TIME_CHANGE_EVENT = \"view360videotimechange\";\nexport const SVG_NAMESPACE = \"http://www.w3.org/2000/svg\";\nexport const SESSION_VR = \"immersive-vr\";\nexport const XR_REFERENCE_SPACE = \"local\";\n\nexport const EPSILON = Number.EPSILON ?? 2.220446049250313e-16;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { quat, vec3 } from \"gl-matrix\";\nimport View360Error from \"./core/View360Error\";\nimport ERROR from \"./const/error\";\nimport * as BROWSER from \"./const/browser\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"./const/internal\";\nimport { NoBoolean } from \"./type/utils\";\n\nexport const isString = (val: any): val is string => typeof val === \"string\";\nexport const isElement = (val: any): val is Element => !!val && val.nodeType === Node.ELEMENT_NODE;\n\nexport const createElement = (className: string, tag = BROWSER.EL_DIV) => {\n const el = document.createElement(tag);\n\n el.classList.add(className);\n\n return el;\n};\n\nexport const getNullableElement = (el: HTMLElement | string | null, parent?: HTMLElement): HTMLElement | null => {\n let targetEl: HTMLElement | null = null;\n\n if (isString(el)) {\n const parentEl = parent ? parent : document;\n const queryResult = parentEl.querySelector(el);\n\n if (!queryResult) {\n return null;\n }\n\n targetEl = queryResult as HTMLElement;\n } else if (isElement(el)) {\n targetEl = el;\n }\n\n return targetEl;\n};\n\nexport const getElement = (el: HTMLElement | string, parent?: HTMLElement): HTMLElement => {\n const targetEl = getNullableElement(el, parent);\n\n if (!targetEl) {\n if (isString(el)) {\n throw new View360Error(ERROR.MESSAGES.ELEMENT_NOT_FOUND(el), ERROR.CODES.ELEMENT_NOT_FOUND);\n } else {\n throw new View360Error(ERROR.MESSAGES.WRONG_TYPE(el, [\"HTMLElement\", \"string\"]), ERROR.CODES.WRONG_TYPE);\n }\n }\n\n return targetEl;\n};\n\nexport const findCanvas = (root: HTMLElement, selector: string): HTMLCanvasElement => {\n const canvas = root.querySelector(selector) as HTMLCanvasElement;\n\n if (!canvas) {\n throw new View360Error(ERROR.MESSAGES.CANVAS_NOT_FOUND, ERROR.CODES.CANVAS_NOT_FOUND);\n }\n\n return canvas;\n};\n\nexport const range = (end: number): number[] => {\n if (!end || end <= 0) {\n return [];\n }\n\n return Array.apply(0, Array(end)).map((undef, idx) => idx);\n};\n\nexport const clamp = (x: number, min: number, max: number) => Math.max(Math.min(x, max), min);\n\n// Linear interpolation between a and b\nexport const lerp = (a: number, b: number, t: number) => {\n return a * (1 - t) + b * t;\n};\n\nexport const circulate = (val: number, min: number, max: number) => {\n const size = Math.abs(max - min);\n\n if (val < min) {\n const offset = (min - val) % size;\n val = max - offset;\n } else if (val > max) {\n const offset = (val - max) % size;\n val = min + offset;\n }\n\n return val;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const merge = (target: object, ...srcs: object[]): object => {\n srcs.forEach(source => {\n Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n });\n });\n\n return target;\n};\n\nexport const findIndex = (array: T[], checker: (val: T) => boolean): number => {\n for (let idx = 0; idx < array.length; idx++) {\n if (checker(array[idx])) {\n return idx;\n }\n }\n\n return -1;\n};\n\nexport const getObjectOption = >(val?: T): NoBoolean => typeof val === \"object\" ? val : {} as any;\nexport const toVerticalFov = (fovRadian: number, aspect: number) => {\n return Math.atan(Math.tan(fovRadian * 0.5) / aspect) * 2;\n};\n\nexport const reorderCube = (arr: T[], order: string, defaultOrder = \"RLUDFB\"): T[] => {\n return defaultOrder.split(\"\")\n .map(face => order.indexOf(face))\n .map(index => arr[index]);\n};\n\nexport const isFullscreen = () => {\n if (!document) return false;\n\n for (const key of BROWSER.FULLSCREEN_ELEMENT) {\n if (document[key]) return true;\n }\n\n return false;\n};\n\nexport const sensorCanBeEnabledIOS = () => {\n return !!DeviceMotionEvent && \"requestPermission\" in DeviceMotionEvent && window.isSecureContext;\n};\n\nexport const hfovToZoom = (baseFov: number, fov: number) => {\n const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5);\n const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5);\n\n return renderingWidth / zoomedWidth;\n};\n\nexport const eulerToQuat = (out: quat, yaw: number, pitch: number, roll: number): quat => {\n quat.identity(out);\n\n const pitchThreshold = 0.01;\n const pitchClamped = clamp(pitch, -90 + pitchThreshold, 90 - pitchThreshold);\n\n quat.rotateY(out, out, yaw * DEG_TO_RAD);\n quat.rotateX(out, out, pitchClamped * DEG_TO_RAD);\n quat.rotateZ(out, out, roll * DEG_TO_RAD);\n\n return out;\n};\n\n/**\n * Extract euler angles from the quaternion, except roll(z-axis rotation)\n * @hidden\n */\nexport const quatToEuler = (quaternion: quat) => {\n const x = quaternion[0];\n const y = quaternion[1];\n const z = quaternion[2];\n const w = quaternion[3];\n const x2 = x * x;\n const y2 = y * y;\n const z2 = z * z;\n const w2 = w * w;\n\n const unit = x2 + y2 + z2 + w2;\n const test = x * w - y * z;\n\n let pitch: number, yaw: number;\n\n if (test > 0.499995 * unit) {\n // singularity at the north pole\n pitch = Math.PI / 2;\n yaw = 2 * Math.atan2(y, x);\n } else if (test < -0.499995 * unit) {\n // singularity at the south pole\n pitch = -Math.PI / 2;\n yaw = -2 * Math.atan2(y, x);\n } else {\n const view = vec3.fromValues(0, 0, 1);\n const up = vec3.fromValues(0, 1, 0);\n\n vec3.transformQuat(view, view, quaternion);\n vec3.transformQuat(up, up, quaternion);\n\n const viewXZ = Math.sqrt(view[0] * view[0] + view[2] * view[2]);\n\n pitch = Math.atan2(-view[1], viewXZ);\n yaw = Math.atan2(view[0], view[2]);\n }\n\n return {\n pitch: clamp(pitch * RAD_TO_DEG, -90, 90),\n yaw: circulate(yaw * RAD_TO_DEG, 0, 360)\n };\n};\n","/*\n * Copyright (c) 2020 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport { clamp, lerp, circulate } from \"../utils\";\nimport { Range } from \"../type/utils\";\nimport { DEFAULT_ANIMATION_DURATION, DEFAULT_EASING } from \"../const/internal\";\n\n/**\n * Interpolator between two values with duration\n * @ko 특정 시간동안 두 값을 보간해주는 보간기\n * @since 4.0.0\n */\nclass Motion {\n // Options\n private _duration: number;\n private _loop: boolean;\n private _range: Range;\n private _easing: (x: number) => number;\n\n // Internal states\n private _progress: number;\n private _val: number;\n private _start: number;\n private _end: number;\n private _activated: boolean;\n\n /**\n * Current interpolated value\n * @ko 현재 보간된 값\n * @since 4.0.0\n */\n public get val() { return this._val; }\n /**\n * Start(from) value of interpolation\n * @ko 보간 시작 값\n * @since 4.0.0\n */\n public get start() { return this._start; }\n /**\n * End(to) value of interpolation\n * @ko 보간 끝 값\n * @since 4.0.0\n */\n public get end() { return this._end; }\n /**\n * Interpolation progress value (0 ~ 1)\n * @ko 현재 보간 진행정도 (0 ~ 1)\n * @since 4.0.0\n */\n public get progress() { return this._progress; }\n /**\n * Whether the interpolation is in active state.\n * @ko 보간 진행중인지 여부. `true`일 경우 보간이 진행중입니다.\n * @since 4.0.0\n */\n public get activated() { return this._activated; }\n\n /**\n * Duration of the interpolation\n * @ko 보간할 시간\n * @since 4.0.0\n */\n public get duration() { return this._duration; }\n public set duration(val: number) { this._duration = val; }\n\n /**\n * Whether to loop interpolation on finish\n * @ko 보간이 끝난 이후에 다시 시작할지 여부\n * @since 4.0.0\n */\n public get loop() { return this._loop; }\n public set loop(val: boolean) { this._loop = val; }\n\n /**\n * Range of the interpolation\n * @ko 보간 범위\n * @since 4.0.0\n */\n public get range() { return this._range; }\n\n /**\n * Easing function of the interpolation\n * @ko 보간에 사용되는 easing function\n * @since 4.0.0\n */\n public get easing() { return this._easing; }\n public set easing(val: (x: number) => number) { this._easing = val; }\n\n /**\n * Create new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options Options {@ko 옵션들}\n * @param options.duration Duration of the interpolation {@ko 보간할 시간}\n * @param options.loop Whether to loop interpolation on finish {@ko 보간이 끝난 이후에 다시 시작할지 여부}\n * @param options.range Range of the interpolation {@ko 보간 범위}\n * @param options.loop Easing function of the interpolation {@ko 보간에 사용되는 easing function}\n */\n public constructor({\n duration = DEFAULT_ANIMATION_DURATION,\n loop = false,\n range = { min: 0, max: 1 },\n easing = DEFAULT_EASING\n } = {}) {\n this._duration = duration;\n this._loop = loop;\n this._range = range;\n this._easing = easing;\n this._activated = false;\n this.reset(0);\n }\n\n /**\n * Update motion and progress it by given deltaTime\n * @ko 주어진 deltaTime만큼 보간을 진행합니다.\n * @param deltaTime - number of milisec to update motion {@ko 보간을 진행할 시간, 밀리초 단위}\n * @returns Difference(delta) of the value from the last update. {@ko 지난 업데이트 이후의 값 변화량}\n * @since 4.0.0\n */\n public update(deltaTime: number): number {\n if (!this._activated) {\n this._val = this._end;\n return 0;\n }\n\n const start = this._start;\n const end = this._end;\n const duration = this._duration;\n const prev = this._val;\n const loop = this._loop;\n\n const nextProgress = this._progress + deltaTime / duration;\n\n this._progress = loop\n ? circulate(nextProgress, 0, 1)\n : clamp(nextProgress, 0, 1);\n\n const easedProgress = this._easing(this._progress);\n this._val = lerp(start, end, easedProgress);\n\n if (!loop && this._progress >= 1) {\n this._activated = false;\n }\n\n return this._val - prev;\n }\n\n /**\n * Set `start`, `end` to the given value and set `progress` to 0.\n * @ko 주어진 값으로 시작 지점, 끝 지점을 초기화하고 progress를 0으로 세팅합니다.\n * @param defaultVal - Value to reset {@ko 초기화할 값}\n * @since 4.0.0\n */\n public reset(defaultVal: number): void {\n const range = this._range;\n const val = clamp(defaultVal, range.min, range.max);\n this._start = val;\n this._end = val;\n this._val = val;\n this._progress = 0;\n this._activated = false;\n }\n\n /**\n * Add delta to start & end and current value.\n * @ko 현재 & 끝 및 현재 값에 주어진 값을 더합니다.\n * @param delta - Delta value to add {@ko 추가할 값}\n */\n public add(delta: number) {\n const range = this._range;\n\n this._start = clamp(this._start + delta, range.min, range.max);\n this._end = clamp(this._end + delta, range.min, range.max);\n this._val = clamp(this._val + delta, range.min, range.max);\n }\n\n /**\n * Set current value to start, and end to current value + delta, then reset progress to 0.\n * @ko 현재 값을 시작 지점으로, 그에서 delta만큼 추가된 값을 끝점으로 하고 progress를 0으로 갱신합니다.\n * @param delta - Delta value to add {@ko 추가할 값}\n */\n public setNewEndByDelta(delta: number): void {\n const range = this._range;\n\n this._start = this._val;\n this._end = clamp(this._end + delta, range.min, range.max);\n this._progress = 0;\n this._activated = true;\n }\n\n /**\n * Set new range of the interpolation.\n * @ko 보간의 범위를 변경합니다.\n * @param min - New minimum range {@ko 변경할 범위의 최소값}\n * @param max - New maximum range {@ko 변경할 범위의 최대값}\n */\n public setRange(min: number, max: number) {\n this._start = clamp(this._start, min, max);\n this._end = clamp(this._end, min, max);\n this._range = { min, max };\n }\n}\n\nexport default Motion;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { quat } from \"gl-matrix\";\nimport Camera from \"./Camera\";\nimport Motion from \"./Motion\";\nimport { DEFAULT_ANIMATION_DURATION, DEFAULT_EASING } from \"../const/internal\";\nimport { lerp } from \"../utils\";\n\ntype CameraPose = {\n rotation: quat;\n zoom: number;\n}\n\n/**\n * Animation of the {@link Camera}\n * @internal\n * @ko {@link Camera}의 애니메이션\n * @since 4.0.0\n */\nclass CameraAnimation {\n // Options\n private _camera: Camera;\n private _from: CameraPose;\n private _to: CameraPose;\n\n // Internal values\n private _motion: Motion;\n private _finishPromise: Promise;\n private _finish: () => void;\n\n /**\n * Duration of the animation\n * @ko 애니메이션 재생시간\n * @since 4.0.0\n */\n public get duration() { return this._motion.duration; }\n public set duration(val: number) { this._motion.duration = val; }\n /**\n * Easing function of the animation\n * @ko 애니메이션의 easing function\n * @since 4.0.0\n */\n public get easing() { return this._motion.easing; }\n public set easing(val: (x: number) => number) { this._motion.easing = val; }\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param camera - Camera to animate {@ko 애니메이션을 적용할 카메라}\n * @param from - Start pose {@ko 애니메이션이 시작 시점의 카메라의 회전 및 줌}\n * @param to - End pose {@ko 애니메이션이 끝났을 때 카메라의 회전 및 줌}\n * @param options - Options {@ko 옵션들}\n * @param options.duration - Animation duration {@ko 애니메이션 재생 시간}\n * @param options.easing - Animation easing function {@ko 애니메이션 easing function}\n */\n public constructor(camera: Camera, from: CameraPose, to: CameraPose, {\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING\n } = {}) {\n this._camera = camera;\n this._motion = new Motion({ duration, easing, range: { min: 0, max: 1 } });\n this._from = from;\n this._to = to;\n this._finishPromise = new Promise(resolve => {\n this._finish = resolve as () => void;\n });\n\n // Enable motion\n this._motion.setNewEndByDelta(1);\n }\n\n /**\n * Return a promise that resolved on animation end.\n * @ko 애니메이션 재생이 끝났을 때 resolve되는 Promise를 반환합니다.\n * @since 4.0.0\n */\n public getFinishPromise() {\n return this._finishPromise;\n }\n\n /**\n * Update animation by given deltaTime.\n * @ko 주어진 시간만큼 애니메이션을 업데이트합니다.\n * @param deltaTime Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n */\n public update(deltaTime: number): void {\n const camera = this._camera;\n const from = this._from;\n const to = this._to;\n const motion = this._motion;\n motion.update(deltaTime);\n\n // Progress that easing is applied\n const progress = motion.val;\n const rotation = quat.create();\n const zoom = lerp(from.zoom, to.zoom, progress);\n\n quat.slerp(rotation, from.rotation, to.rotation, progress);\n camera.rotate(rotation, zoom);\n\n if (progress >= 1) {\n this._finish();\n }\n }\n}\n\nexport default CameraAnimation;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { mat4, quat, vec3 } from \"gl-matrix\";\nimport CameraAnimation from \"./CameraAnimation\";\nimport {\n CAMERA_EVENTS,\n DEG_TO_RAD,\n INFINITE_RANGE,\n DEFAULT_PITCH_RANGE,\n RAD_TO_DEG,\n DEFAULT_ZOOM_RANGE,\n DEFAULT_EASING,\n EPSILON\n} from \"../const/internal\";\nimport {\n circulate,\n clamp,\n eulerToQuat,\n quatToEuler,\n toVerticalFov\n} from \"../utils\";\nimport { Range } from \"../type/utils\";\n\n/**\n * Events that {@link Camera} can trigger\n * @ko {@link Camera}가 트리거할 수 있는 이벤트들\n * @since 4.0.0\n */\nexport interface CameraEvents {\n /**\n * An event that fires when camera's animation stops\n * @ko 카메라 애니메이션이 멈췄을 때 트리거되는 이벤트\n * @eventName animationEnd\n * @eventOf Camera\n * @version 4.0.0\n */\n [CAMERA_EVENTS.ANIMATION_END]: {\n animation: CameraAnimation\n };\n}\n\n/**\n * Options for {@link Camera}\n * @ko {@link Camera}용 옵션들\n * @since 4.0.0\n */\nexport interface CameraOptions {\n /**\n * @copy View360#initialYaw\n */\n initialYaw: number;\n /**\n * @copy View360#initialPitch\n */\n initialPitch: number;\n /**\n * @copy View360#initialZoom\n */\n initialZoom: number;\n /**\n * @copy View360#yawRange\n */\n yawRange: Range | null;\n /**\n * @copy View360#pitchRange\n */\n pitchRange: Range | null;\n /**\n * @copy View360#zoomRange\n */\n zoomRange: Range | null;\n /**\n * @copy View360#fov\n */\n fov: number;\n}\n\n/**\n * Camera for View360\n * @ko View360용 카메라 구현체\n * @version 4.0.0\n */\nclass Camera extends Component {\n /**\n * Current yaw(y-axis rotation) value\n * @ko 현재 yaw(y축 회전) 값\n * @since 4.0.0\n */\n public yaw: number;\n /**\n * Current pitch(x-axis rotation) value\n * @ko 현재 pitch(x축 회전) 값\n * @since 4.0.0\n */\n public pitch: number;\n /**\n * Current zoom value\n * @ko 현재 줌 값\n * @since 4.0.0\n */\n public zoom: number;\n\n /**\n * @copy View360#initialYaw\n */\n public initialYaw: number;\n /**\n * @copy View360#initialPitch\n */\n public initialPitch: number;\n /**\n * @copy View360#initialPitch\n */\n public initialZoom: number;\n /**\n * @hidden\n * TODO: Please add comment for this when `rollOffset` is added\n */\n public rollOffset: number;\n\n /**\n * Current camera quaternion\n * @ko 현재 회전을 나타내는 quaternion 값\n * @since 4.0.0\n * @internal\n */\n public quaternion: quat;\n /**\n * Current camera position\n * @ko 현재 카메라 위치 좌표\n * @since 4.0.0\n * @internal\n */\n public position: vec3;\n /**\n * Active camera animation, `null` if there isn't.\n * @ko 현재 활성화된 카메라 애니메이션, 없을 경우 `null`값을 가집니다.\n * @since 4.0.0\n */\n public animation: CameraAnimation | null;\n /**\n * Camera's view matrix\n * @ko 카메라의 뷰 변환 행렬\n * @internal\n * @since 4.0.0\n */\n public viewMatrix: mat4;\n /**\n * Camera's projection matrix\n * @ko 카메라의 프로젝션 변환 행렬\n * @internal\n * @since 4.0.0\n */\n public projectionMatrix: mat4;\n\n /**\n * Camera's horizontal FOV(Field of View) value\n * @ko 카메라의 수평 FOV(Field of View) 값\n * @internal\n * @since 4.0.0\n */\n public fov: number;\n\n private _initialYawRange: Range | null;\n private _initialPitchRange: Range | null;\n private _initialZoomRange: Range | null;\n\n private _yawRange: Range | null;\n private _pitchRange: Range | null;\n private _zoomRange: Range | null;\n\n private _up: vec3;\n private _aspect: number;\n private _changed: boolean;\n private _maxRenderHeight: number;\n\n /**\n * Camera's width / height ratio\n * @ko 카메라의 가로 / 세로 비율\n * @readonly\n */\n public get aspect() { return this._aspect; }\n /**\n * Whether the camera's rotation changed from the last frame.\n * @ko 마지막 프레임 이후로 카메라의 회전값이 변경되었는지 나타내는 플래그.\n * @readonly\n */\n public get changed() { return this._changed; }\n /**\n * @copy View360#yawRange\n */\n public get yawRange() { return this._initialYawRange; }\n public set yawRange(val: Range | null) {\n this._initialYawRange = val;\n }\n /**\n * @copy View360#pitchRange\n */\n public get pitchRange() { return this._initialPitchRange; }\n public set pitchRange(val: Range | null) {\n this._initialPitchRange = val;\n }\n /**\n * @copy View360#zoomRange\n */\n public get zoomRange() { return this._initialZoomRange; }\n public set zoomRange(val: Range | null) {\n this._initialZoomRange = val;\n }\n\n /**\n * Create new instance of Camera\n * @param options - Camera options {@ko 카메라 옵션들}\n */\n public constructor({\n initialYaw,\n initialPitch,\n initialZoom,\n yawRange,\n pitchRange,\n zoomRange,\n fov\n }: CameraOptions) {\n super();\n\n this.yaw = initialYaw;\n this.pitch = initialPitch;\n this.zoom = initialZoom;\n this.rollOffset = 0;\n\n this.initialYaw = initialYaw;\n this.initialPitch = initialPitch;\n this.initialZoom = initialZoom;\n\n this.position = vec3.create();\n this.animation = null;\n\n this._up = vec3.fromValues(0, 1, 0);\n this._aspect = 1;\n\n this._initialYawRange = yawRange;\n this._initialPitchRange = pitchRange;\n this._initialZoomRange = zoomRange;\n\n this._yawRange = yawRange;\n this._pitchRange = pitchRange;\n this._zoomRange = zoomRange;\n\n this.quaternion = quat.create();\n this._updateQuaternion();\n\n this.viewMatrix = mat4.create();\n this.projectionMatrix = mat4.create();\n this.fov = fov;\n\n this._maxRenderHeight = -1;\n }\n\n /**\n * Destroy instance and detach all event listeners\n * @ko 인스턴스를 삭제하고 모든 이벤트 리스너를 삭제합니다.\n * @since 4.0.0\n */\n public destroy() {\n this.off();\n }\n\n /**\n * Refresh internal size value.\n * @ko 내부 크기값을 갱신합니다.\n * @param width - New width {@ko 변경된 너비값}\n * @param height - New height {@ko 변경된 높이값}\n * @since 4.0.0\n */\n public resize(width: number, height: number) {\n const prevAspect = this._aspect;\n\n this._aspect = width / height;\n\n if (this._aspect !== prevAspect) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation with euler values.\n * @ko 카메라 회전을 오일러 각 방향으로 변경합니다.\n * @param rotation - Rotation values {@ko 회전 값}\n * @param rotation.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값}\n * @param rotation.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값}\n * @param rotation.zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @since 4.0.0\n */\n public lookAt({\n yaw = this.yaw,\n pitch = this.pitch,\n zoom = this.zoom\n }: Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n }>) {\n const prevQuaternion = quat.clone(this.quaternion);\n const prevZoom = this.zoom;\n\n this.yaw = circulate(yaw, 0, 360);\n this.pitch = clamp(pitch, -90, 90);\n this.zoom = zoom;\n\n this._updateQuaternion();\n\n const zoomDiff = Math.abs(zoom - prevZoom);\n\n if (\n !quat.equals(this.quaternion, prevQuaternion)\n || zoomDiff >= EPSILON * 10 // ignore small changes\n ) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation with quaternion.\n * @ko 카메라 회전을 Quaternion을 이용해서 변경합니다.\n * @param rotation - Quaternion to apply {@ko 적용할 Quaternion}\n * @param zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @since 4.0.0\n */\n public rotate(rotation: quat, zoom: number = this.zoom) {\n const normalized = quat.normalize(quat.create(), rotation);\n const isSameRotation = quat.equals(this.quaternion, normalized);\n quat.copy(this.quaternion, normalized);\n\n const prevZoom = this.zoom;\n const { yaw, pitch } = quatToEuler(normalized);\n\n this.yaw = yaw;\n this.pitch = pitch;\n this.zoom = zoom;\n\n const zoomDiff = Math.abs(zoom - prevZoom);\n\n if (!isSameRotation || zoomDiff >= EPSILON * 10) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation to given euler values by the given duration.\n * @ko 카메라를 주어진 방향으로 주어진 시간동안 서서히 이동시킵니다.\n * @param options - Animation parameters {@ko 애니메이션 패러미터}\n * @param options.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값}\n * @param options.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값}\n * @param options.zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @param options.duration - Duration of the animation {@ko 애니메이션 시간}\n * @param options.easing - Easing function for the animation {@ko 애니메이션에 적용할 easing function}\n */\n public async animateTo({\n yaw = this.yaw,\n pitch = this.pitch,\n zoom = this.zoom,\n duration = 0,\n easing = DEFAULT_EASING\n }: Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n duration: number;\n easing: (x: number) => number;\n }> = {}): Promise {\n if (\n this.yaw === yaw\n && this.pitch === pitch\n && this.zoom === zoom\n ) return;\n\n const from = {\n rotation: quat.clone(this.quaternion),\n zoom: this.zoom\n };\n const to = {\n rotation: eulerToQuat(quat.create(), yaw, pitch, this.rollOffset),\n zoom\n };\n\n const animation = new CameraAnimation(this, from, to, {\n duration,\n easing\n });\n const finishPromise = animation.getFinishPromise();\n\n this.animation = animation;\n finishPromise.then(() => {\n this.animation = null;\n this.trigger(CAMERA_EVENTS.ANIMATION_END, { animation });\n });\n\n return finishPromise;\n }\n\n /**\n * @hidden\n */\n public restrictYawRange(min: number, max: number) {\n this._yawRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictPitchRange(min: number, max: number) {\n this._pitchRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictZoomRange(min: number, max: number) {\n this._zoomRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictRenderHeight(height: number) {\n this._maxRenderHeight = height;\n }\n\n /**\n * @hidden\n */\n public resetRange() {\n this._yawRange = this._initialYawRange;\n this._pitchRange = this._initialPitchRange;\n this._zoomRange = this._initialZoomRange;\n this._maxRenderHeight = -1;\n }\n\n /**\n * Get actual yaw range by the given zoom value.\n * @ko 주어진 zoom 값에 대한 실제 yaw 범위값을 반환합니다.\n * @since 4.0.0\n */\n public getYawRange(zoom: number) {\n const yawLimit = this._yawRange;\n const maxRenderHeight = this._maxRenderHeight;\n if (!yawLimit) return INFINITE_RANGE;\n\n const halfHFov = this.getHorizontalFov(zoom) * 0.5;\n let minYaw = yawLimit.min;\n let maxYaw = yawLimit.max;\n\n if (maxRenderHeight > 0) {\n const halfVFovRad = toVerticalFov(halfHFov * DEG_TO_RAD, this._aspect);\n const h = maxRenderHeight * 0.5;\n const t = Math.tan(halfVFovRad);\n const d = Math.sqrt((1 + h * h) / (1 + t * t));\n const theta = Math.atan(Math.tan(halfHFov * DEG_TO_RAD) * d) * RAD_TO_DEG;\n\n minYaw = yawLimit.min + theta;\n maxYaw = yawLimit.max - theta;\n }\n\n if (minYaw > maxYaw) {\n minYaw = 0;\n maxYaw = 0;\n }\n\n return {\n min: minYaw,\n max: maxYaw\n };\n }\n\n /**\n * Get actual pitch range by the given zoom value.\n * @ko 주어진 zoom 값에 대한 실제 pitch 범위값을 반환합니다.\n * @since 4.0.0\n */\n public getPitchRange(zoom: number) {\n const pitchLimit = this._pitchRange;\n const maxRenderHeight = this._maxRenderHeight;\n\n if (!pitchLimit) return DEFAULT_PITCH_RANGE;\n\n let minPitch = pitchLimit.min;\n let maxPitch = pitchLimit.max;\n\n if (maxRenderHeight > 0) {\n const halfVFov = this.getVerticalFov(zoom) * 0.5;\n\n minPitch = pitchLimit.min + halfVFov;\n maxPitch = pitchLimit.max - halfVFov;\n }\n\n if (minPitch > maxPitch) {\n minPitch = 0;\n maxPitch = 0;\n }\n\n return {\n min: Math.max(minPitch, -90),\n max: Math.min(maxPitch, 90)\n };\n }\n\n /**\n * Get actual zoom range in fov degrees.\n * @ko 실제 줌 범위를 fov각의 범위로 반환합니다.\n * @since 4.0.0\n */\n public getZoomRange() {\n const limit = this._zoomRange ?? DEFAULT_ZOOM_RANGE;\n\n // max (zoom in) -> minimum fov\n const minFov = this.getHorizontalFov(limit.max);\n const maxFov = this.getHorizontalFov(limit.min);\n const currentFov = this.getHorizontalFov(this.zoom);\n\n return {\n min: Math.max(minFov, 1),\n max: Math.min(maxFov, 180),\n current: currentFov\n };\n }\n\n /**\n * Return horizontal fov value when the given zoom is applied. (in degrees, °)\n * @ko 주어진 zoom 값이 적용되었을 때의 수평 fov값을 반환합니다. (도 단위, °)\n * @returns Zoomed horizontal FOV {@ko 줌이 적용된 수평 fov값}\n * @since 4.0.0\n */\n public getHorizontalFov(zoom = this.zoom) {\n return this._getZoomedHorizontalFov(zoom) * RAD_TO_DEG;\n }\n\n /**\n * Return vertical fov value when the given zoom is applied. (in degrees, °)\n * @ko 주어진 zoom 값이 적용되었을 때의 수직 fov값을 반환합니다. (도 단위, °)\n * @returns Zoomed vertical FOV {@ko 줌이 적용된 수직 fov값}\n * @since 4.0.0\n */\n public getVerticalFov(zoom = this.zoom) {\n const aspect = this._aspect;\n const hFov = this._getZoomedHorizontalFov(zoom); // In radians\n const vFov = toVerticalFov(hFov, aspect);\n\n return vFov * RAD_TO_DEG;\n }\n\n /**\n * Calculate zoom value for the given fov.\n * @ko 주어진 fov값을 zoom값으로 변환합니다.\n * @param fov horizontal fov (in degrees, °) {@ko 수평 fov 값 (도 단위, °)}\n * @since 4.0.0\n */\n public fovToZoom(fov: number) {\n const baseFov = this.fov;\n const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5);\n const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5);\n\n return renderingWidth / zoomedWidth;\n }\n\n /**\n * Update inner matrixes.\n * @ko 내부 행렬들을 업데이트합니다.\n * @internal\n * @since 4.0.0\n */\n public updateMatrix() {\n const up = this._up;\n const aspect = this._aspect;\n const viewMatrix = this.viewMatrix;\n const projMatrix = this.projectionMatrix;\n const position = this.position;\n const rotation = this.quaternion;\n\n const upDir = vec3.create();\n const viewDir = vec3.fromValues(0, 0, -1);\n vec3.transformQuat(viewDir, viewDir, rotation);\n vec3.transformQuat(upDir, up, rotation);\n\n const hFov = this._getZoomedHorizontalFov(); // In radians\n const vFov = toVerticalFov(hFov, aspect);\n\n mat4.lookAt(viewMatrix, position, viewDir, upDir);\n mat4.perspective(projMatrix, vFov, aspect, 0.1, 100);\n\n this._changed = true;\n }\n\n /**\n * @hidden\n */\n public onFrameRender() {\n this._changed = false;\n }\n\n private _updateQuaternion() {\n eulerToQuat(this.quaternion, this.yaw, this.pitch, this.rollOffset);\n }\n\n /**\n * @param zoom Current zoom value\n * @returns horizontal fov including zoom, in radian\n */\n private _getZoomedHorizontalFov(zoom = this.zoom) {\n return 2 * Math.atan(Math.tan(DEG_TO_RAD * this.fov * 0.5) / zoom);\n }\n}\n\nexport default Camera;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass MouseInput extends Component> {\n private _el: HTMLElement | null;\n private _prevPos: [number, number];\n\n public constructor() {\n super();\n\n this._el = null;\n this._prevPos = [0, 0];\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onMouseDown);\n\n this._el = element;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onMouseDown);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this._el = null;\n }\n\n private _onMouseDown = (evt: MouseEvent) => {\n const el = this._el;\n if (!el || evt.button !== BROWSER.MOUSE_BUTTON.LEFT) return;\n\n evt.preventDefault();\n\n if (el.focus) {\n el.focus();\n } else {\n window.focus();\n }\n\n this._prevPos[0] = evt.clientX;\n this._prevPos[1] = evt.clientY;\n\n window.addEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.addEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: false\n });\n }\n\n private _onMouseMove = (evt: MouseEvent) => {\n evt.preventDefault();\n\n const x = evt.clientX;\n const y = evt.clientY;\n const prevPos = this._prevPos;\n const deltaX = x - prevPos[0];\n const deltaY = y - prevPos[1];\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta: {\n x: deltaX,\n y: deltaY\n },\n isTouch: false,\n isKeyboard: false\n });\n\n prevPos[0] = x;\n prevPos[1] = y;\n }\n\n private _onMouseUp = () => {\n this._prevPos[0] = 0;\n this._prevPos[1] = 0;\n\n window.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: false,\n scrolling: false\n });\n }\n}\n\nexport default MouseInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\nimport { isFullscreen } from \"../../utils\";\n\nclass TouchInput extends Component> {\n private _el: HTMLElement | null;\n private _prevPos: [number, number];\n private _isFirstTouch: boolean;\n private _scrolling: boolean;\n private _scrollable: boolean;\n\n public get scrollable() { return this._scrollable; }\n public set scrollable(val: boolean) { this._scrollable = val; }\n\n public constructor() {\n super();\n\n this._el = null;\n this._prevPos = [0, 0];\n this._isFirstTouch = false;\n this._scrolling = false;\n this._scrollable = false;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.TOUCH_START, this._onTouchStart, { passive: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, { passive: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = element;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.TOUCH_START, this._onTouchStart);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = null;\n }\n\n private _onTouchStart = (evt: TouchEvent) => {\n if (evt.touches.length > 1 || this._scrolling) return;\n\n const touch = evt.touches[0];\n\n this._isFirstTouch = true;\n this._prevPos[0] = touch.clientX;\n this._prevPos[1] = touch.clientY;\n\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: true,\n isKeyboard: false\n });\n };\n\n private _onTouchMove = (evt: TouchEvent) => {\n // Only the one finger motion should be considered\n if (evt.touches.length > 1 || this._scrolling) return;\n\n const touch = evt.touches[0];\n const scrollable = this._scrollable;\n const prevPos = this._prevPos;\n\n const x = touch.clientX;\n const y = touch.clientY;\n const deltaX = x - prevPos[0];\n const deltaY = y - prevPos[1];\n\n if (this._isFirstTouch) {\n if (scrollable && !isFullscreen()) {\n if (Math.abs(deltaY) > Math.abs(deltaX)) {\n // Assume Scrolling\n this._scrolling = true;\n return;\n }\n }\n\n this._isFirstTouch = false;\n }\n\n if (evt.cancelable !== false) {\n evt.preventDefault();\n }\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta: {\n x: deltaX,\n y: deltaY\n },\n isTouch: true,\n isKeyboard: false\n });\n\n prevPos[0] = x;\n prevPos[1] = y;\n };\n\n private _onTouchEnd = (evt: TouchEvent) => {\n if (evt.touches.length !== 0) return;\n\n const touch = evt.touches[0];\n const prevPos = this._prevPos;\n\n if (touch) {\n prevPos[0] = touch.clientX;\n prevPos[1] = touch.clientY;\n } else {\n prevPos[0] = 0;\n prevPos[1] = 0;\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: true,\n isKeyboard: false,\n scrolling: this._scrolling\n });\n }\n\n if (evt.cancelable !== false) {\n evt.preventDefault();\n }\n\n this._scrolling = false;\n };\n}\n\nexport default TouchInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass KeyboardInput extends Component> {\n private _el: HTMLElement | null;\n private _pressed: {\n LEFT: boolean;\n UP: boolean;\n RIGHT: boolean;\n DOWN: boolean;\n };\n\n public get active() {\n const pressed = this._pressed;\n return pressed.LEFT || pressed.UP || pressed.RIGHT || pressed.DOWN;\n }\n\n public constructor() {\n super();\n\n this._el = null;\n this._clearPressedKeys();\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown);\n element.addEventListener(BROWSER.EVENTS.KEY_UP, this._onKeyUp);\n\n this._el = element;\n this._clearPressedKeys();\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown);\n element.removeEventListener(BROWSER.EVENTS.KEY_UP, this._onKeyUp);\n\n this._el = null;\n this._clearPressedKeys();\n }\n\n public update() {\n const delta = this._getDeltaByPressedKeys();\n\n if (delta.x !== 0 || delta.y !== 0) {\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: false,\n isKeyboard: true\n });\n }\n }\n\n private _clearPressedKeys() {\n this._pressed = BROWSER.KEY_DIRECTION.reduce((obj, keyName) => {\n return {\n ...obj,\n [keyName]: false\n };\n }, {} as KeyboardInput[\"_pressed\"]);\n }\n\n private _updateKeyPress(event: KeyboardEvent, isEnable: boolean): void {\n const pressed = this._pressed;\n const keyToUpdate = event.keyCode != null\n ? BROWSER.DIRECTION_KEY_CODE[event.keyCode]\n : BROWSER.DIRECTION_KEY_NAME[event.key];\n\n if (!keyToUpdate) return;\n\n pressed[keyToUpdate] = isEnable;\n }\n\n private _getPressedKeyCount() {\n return BROWSER.KEY_DIRECTION.filter(key => this._pressed[key]).length;\n }\n\n private _getDeltaByPressedKeys() {\n const pressed = this._pressed;\n let x = 0;\n let y = 0;\n\n if (pressed.LEFT) {\n x += 1;\n }\n\n if (pressed.RIGHT) {\n x -= 1;\n }\n\n if (pressed.UP) {\n y += 1;\n }\n\n if (pressed.DOWN) {\n y -= 1;\n }\n\n return {\n x, y\n };\n }\n\n private _onKeyDown = (evt: KeyboardEvent) => {\n // Ignore all other keypress except main arrow keys\n if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return;\n\n this._updateKeyPress(evt, true);\n\n const pressedCount = this._getPressedKeyCount();\n if (pressedCount <= 0) return;\n\n evt.preventDefault();\n if (pressedCount === 1 && !evt.repeat) {\n // On first keydown\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: true\n });\n }\n };\n\n private _onKeyUp = (evt: KeyboardEvent) => {\n // Ignore all other keypress except main arrow keys\n if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return;\n\n this._updateKeyPress(evt, false);\n\n const pressedCount = this._getPressedKeyCount();\n if (pressedCount > 0) return;\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: true,\n scrolling: false\n });\n };\n}\n\nexport default KeyboardInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport MouseInput from \"./input/MouseInput\";\nimport TouchInput from \"./input/TouchInput\";\nimport KeyboardInput from \"./input/KeyboardInput\";\nimport Camera from \"../core/Camera\";\nimport Motion from \"../core/Motion\";\nimport { CONTROL_EVENTS, INFINITE_RANGE, DEFAULT_PITCH_RANGE, DEFAULT_ANIMATION_DURATION, DEFAULT_EASING, DEG_TO_RAD, RAD_TO_DEG } from \"../const/internal\";\nimport { toVerticalFov } from \"../utils\";\nimport { ControlEvents, InputEvents } from \"../type/internal\";\n\n/**\n * Options for {@link RotateControl}\n * @ko {@link RotateControl}용 옵션들\n * @since 4.0.0\n */\nexport interface RotateControlOptions {\n /**\n * @copy RotateControl#pointerScale\n */\n pointerScale: [number, number];\n /**\n * @copy RotateControl#keyboardScale\n */\n keyboardScale: [number, number];\n /**\n * @copy RotateControl#duration\n */\n duration: number;\n /**\n * @copy RotateControl#easing\n */\n easing: (x: number) => number;\n /**\n * @copy RotateControl#disablePitch\n */\n disablePitch: boolean;\n /**\n * @copy RotateControl#disableYaw\n */\n disableYaw: boolean;\n /**\n * @copy RotateControl#disableKeyboard\n */\n disableKeyboard: boolean;\n}\n\ntype RotateDeltaType = { x: number; y: number; };\nexport type RotateControlEvents = ControlEvents;\n\n/**\n * Camera's rotation control\n * @ko 카메라의 회전을 담당하는 컨트롤\n * @since 4.0.0\n */\nclass RotateControl extends Component implements CameraControl {\n // Options\n private _pointerScale: RotateControlOptions[\"pointerScale\"];\n private _keyboardScale: RotateControlOptions[\"keyboardScale\"];\n private _duration: RotateControlOptions[\"duration\"];\n private _easing: RotateControlOptions[\"easing\"];\n private _disablePitch: RotateControlOptions[\"disablePitch\"];\n private _disableYaw: RotateControlOptions[\"disableYaw\"];\n private _disableKeyboard: RotateControlOptions[\"disableKeyboard\"];\n\n // Internal values\n private _controlEl: HTMLElement;\n private _enableBlocked: boolean;\n private _mouseInput: MouseInput;\n private _touchInput: TouchInput;\n private _keyboardInput: KeyboardInput;\n private _xMotion: Motion;\n private _yMotion: Motion;\n private _screenScale: [number, number];\n private _zoomScale: number;\n private _enabled: boolean;\n private _changedWhileDragging: boolean;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() {\n return this._keyboardInput.active\n || this._xMotion.activated\n || this._yMotion.activated;\n }\n /**\n * Current yaw value\n * @ko 현재 yaw 값\n * @readonly\n * @since 4.0.0\n */\n public get yaw() { return this._xMotion; }\n /**\n * Current pitch value\n * @ko 현재 pitch 값\n * @readonly\n * @since 4.0.0\n */\n public get pitch() { return this._yMotion; }\n /**\n * @copy View360#scrollable\n */\n public get scrollable() { return this._touchInput.scrollable; }\n public set scrollable(val: boolean) {\n this._touchInput.scrollable = val;\n }\n\n /**\n * Scale factor for mouse/touch rotation\n * @ko 마우스/터치를 통한 회전 배율\n * @default [1, 1]\n * @since 4.0.0\n */\n public get pointerScale() { return this._pointerScale; }\n public set pointerScale(val: RotateControlOptions[\"pointerScale\"]) {\n this._pointerScale = val;\n }\n\n /**\n * Scale factor for keyboard rotation\n * @ko 키보드를 통한 회전 배율\n * @default [1, 1]\n * @since 4.0.0\n */\n public get keyboardScale() { return this._keyboardScale; }\n public set keyboardScale(val: RotateControlOptions[\"keyboardScale\"]) {\n this._keyboardScale = val;\n }\n\n /**\n * Duration of the input animation (ms)\n * @ko 회전 애니메이션의 시간 (ms)\n * @default 300\n */\n public get duration() { return this._duration; }\n public set duration(val: RotateControlOptions[\"duration\"]) {\n this._duration = val;\n this._xMotion.duration = val;\n this._yMotion.duration = val;\n }\n\n /**\n * Easing function of the animation\n * @ko 회전 애니메이션에 적용할 easing 함수\n * @default EASING.EASE_OUT_CUBIC\n * @see EASING\n */\n public get easing() { return this._easing; }\n public set easing(val: RotateControlOptions[\"easing\"]) {\n this._easing = val;\n this._xMotion.easing = val;\n this._yMotion.easing = val;\n }\n\n /**\n * Disable X-axis(pitch) rotation.\n * @ko x축 회전(pitch)을 비활성화합니다.\n * @default false\n */\n public get disablePitch() { return this._disablePitch; }\n public set disablePitch(val: RotateControlOptions[\"disablePitch\"]) { this._disablePitch = val; }\n\n /**\n * Disable Y-axis(yaw) rotation.\n * @ko y축 회전(yaw)을 비활성화합니다.\n * @default false\n */\n public get disableYaw() { return this._disableYaw; }\n public set disableYaw(val: RotateControlOptions[\"disableYaw\"]) { this._disableYaw = val; }\n\n /**\n * Disable rotation by keyboard.\n * @ko 키보드를 이용한 회전을 비활성화합니다.\n * @default false\n */\n public get disableKeyboard() { return this._disableKeyboard; }\n public set disableKeyboard(val: RotateControlOptions[\"disableKeyboard\"]) { this._disableKeyboard = val; }\n\n /**\n * Create new RotateControl instance\n * @ko RotateControl의 인스턴스를 생성합니다.\n * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트}\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(controlEl: HTMLElement, enableBlocked: boolean, {\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING,\n pointerScale = [1, 1],\n keyboardScale = [1, 1],\n disablePitch = false,\n disableYaw = false,\n disableKeyboard = false\n }: Partial = {}) {\n super();\n\n this._controlEl = controlEl;\n this._pointerScale = pointerScale;\n this._keyboardScale = keyboardScale;\n this._duration = duration;\n this._easing = easing;\n this._disablePitch = disablePitch;\n this._disableYaw = disableYaw;\n this._disableKeyboard = disableKeyboard;\n\n this._enableBlocked = enableBlocked;\n this._mouseInput = new MouseInput();\n this._touchInput = new TouchInput();\n this._keyboardInput = new KeyboardInput();\n this._xMotion = new Motion({ duration, range: INFINITE_RANGE, easing });\n this._yMotion = new Motion({ duration, range: DEFAULT_PITCH_RANGE, easing });\n this._screenScale = [1, 1];\n this._zoomScale = 1;\n this._enabled = false;\n this._changedWhileDragging = false;\n this._bindInputs();\n }\n\n public destroy(): void {\n this.disable();\n this._mouseInput.off();\n this._touchInput.off();\n this._keyboardInput.off();\n this.off();\n this._changedWhileDragging = false;\n }\n\n /**\n * @hidden\n */\n public update(delta: number): void {\n if (!this._enabled) return;\n\n const xMotion = this._xMotion;\n const yMotion = this._yMotion;\n const keyboardInput = this._keyboardInput;\n\n if (!this._disableKeyboard) {\n keyboardInput.update();\n }\n\n if (!this._disablePitch) {\n yMotion.update(delta);\n }\n\n if (!this._disableYaw) {\n xMotion.update(delta);\n }\n }\n\n /**\n * @hidden\n */\n public updateRange(camera: Camera, zoom: number) {\n const yawRange = camera.getYawRange(zoom);\n const pitchRange = camera.getPitchRange(zoom);\n\n this._xMotion.setRange(yawRange.min, yawRange.max);\n this._yMotion.setRange(pitchRange.min, pitchRange.max);\n }\n\n /**\n * @hidden\n */\n public setZoomScale(val: number) {\n this._zoomScale = val;\n }\n\n /**\n * Resize control to match target size.\n * @ko 컨트롤의 내부 크기를 갱신합니다.\n * @param hfov - Camera horizontal fov in degrees {@ko 카메라의 수평방향 fov값 (도 단위)}\n * @param aspect - Camera aspect {@ko 카메라 가로/세로 비율}\n * @param width - New width {@ko 갱신된 너비}\n * @param height - New height {@ko 갱신된 높이}\n */\n public resize(hfov: number, aspect: number, width: number, height: number) {\n const vfov = toVerticalFov(hfov * DEG_TO_RAD, aspect) * RAD_TO_DEG;\n\n this._screenScale[0] = hfov / width;\n this._screenScale[1] = vfov / height;\n }\n\n public enable(): void {\n if (this._enabled) return;\n\n const element = this._controlEl;\n\n this._mouseInput.enable(element);\n this._touchInput.enable(element);\n this._keyboardInput.enable(element);\n\n this._enabled = true;\n this._enableBlocked = false;\n\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: true });\n }\n\n public disable(): void {\n if (!this._enabled) return;\n\n this._mouseInput.disable();\n this._touchInput.disable();\n this._keyboardInput.disable();\n\n this._enabled = false;\n\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: true });\n }\n\n public sync(camera: Camera): void {\n this.updateRange(camera, camera.zoom);\n\n this._xMotion.reset(camera.yaw);\n this._yMotion.reset(camera.pitch);\n }\n\n private _bindInputs() {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n const keyboardInput = this._keyboardInput;\n\n mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n touchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n touchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n keyboardInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n keyboardInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n keyboardInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n }\n\n private _onInputStart = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n this._changedWhileDragging = false;\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n ...evt,\n inputType: \"rotate\"\n });\n };\n\n private _onChange = (evt: InputEvents[typeof CONTROL_EVENTS.CHANGE]) => {\n const delta = evt.delta;\n const invZoomScale = 1 / this._zoomScale; // Reduce speed on zoom\n const screenScale = this._screenScale;\n const keyboardScale = this._keyboardScale;\n const pointerScale = this._pointerScale;\n\n let scale: [number, number];\n\n if (evt.isKeyboard) {\n scale = [\n keyboardScale[0] * invZoomScale,\n keyboardScale[1] * invZoomScale\n ];\n } else {\n scale = [\n pointerScale[0] * screenScale[0] * invZoomScale,\n pointerScale[1] * screenScale[1] * invZoomScale\n ];\n }\n\n const scaledX = delta.x * scale[0];\n const scaledY = delta.y * scale[1];\n\n this._xMotion.setNewEndByDelta(scaledX);\n this._yMotion.setNewEndByDelta(scaledY);\n\n this._changedWhileDragging = true;\n }\n\n private _onInputEnd = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n ...evt,\n inputType: \"rotate\"\n });\n\n if (!this._changedWhileDragging && !evt.isKeyboard && !evt.scrolling) {\n this.trigger(CONTROL_EVENTS.STATIC_CLICK, {\n isTouch: evt.isTouch\n });\n }\n\n this._changedWhileDragging = false;\n };\n}\n\nexport default RotateControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS, DEFAULT_ANIMATION_DURATION } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass WheelInput extends Component> {\n private _el: HTMLElement | null;\n private _scrollable: boolean;\n private _baseScale: number;\n private _inputTimer: number;\n\n public get scrollable() { return this._scrollable; }\n public set scrollable(val: boolean) { this._scrollable = val; }\n\n public constructor() {\n super();\n\n this._el = null;\n this._baseScale = 0.04;\n this._scrollable = false;\n this._inputTimer = -1;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.WHEEL, this._onWheel, { passive: false, capture: false });\n\n this._el = element;\n this._clearTimer();\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.WHEEL, this._onWheel, false);\n\n this._el = null;\n this._clearTimer();\n }\n\n private _onWheel = (evt: WheelEvent) => {\n const scrollable = this._scrollable;\n\n if (evt.deltaY === 0 || scrollable) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n\n if (this._inputTimer < 0) {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: false\n });\n } else {\n this._clearTimer();\n }\n\n const delta = this._baseScale * evt.deltaY;\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: false,\n isKeyboard: false\n });\n\n this._inputTimer = window.setTimeout(() => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: false,\n scrolling: false\n });\n this._inputTimer = -1;\n }, DEFAULT_ANIMATION_DURATION);\n };\n\n private _clearTimer() {\n window.clearTimeout(this._inputTimer);\n this._inputTimer = -1;\n }\n}\n\nexport default WheelInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass PinchInput extends Component> {\n private _el: HTMLElement | null;\n private _baseScale: number;\n private _prevDistance: number;\n private _isFirstTouch: boolean;\n\n public constructor() {\n super();\n\n this._el = null;\n this._baseScale = -0.2;\n this._prevDistance = -1;\n this._isFirstTouch = true;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, { passive: false, capture: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = element;\n this._prevDistance = -1;\n this._isFirstTouch = true;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, false);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = null;\n }\n\n private _onTouchMove = (evt: TouchEvent) => {\n const touches = evt.touches;\n if (touches.length !== 2) return;\n\n if (!evt.cancelable) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n\n const prevDistance = this._prevDistance;\n\n const diff = [\n touches[0].pageX - touches[1].pageX,\n touches[0].pageY - touches[1].pageY\n ];\n\n const distance = Math.sqrt(diff[0] * diff[0] + diff[1] * diff[1]) * this._baseScale;\n const delta = this._isFirstTouch\n ? 0\n : distance - prevDistance;\n\n if (this._isFirstTouch) {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: true,\n isKeyboard: false\n });\n }\n\n this._prevDistance = distance;\n this._isFirstTouch = false;\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: true,\n isKeyboard: false\n });\n };\n\n private _onTouchEnd = (evt: TouchEvent) => {\n if (evt.touches.length !== 0) return;\n\n if (!this._isFirstTouch) {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: true,\n isKeyboard: false,\n scrolling: false\n });\n }\n\n this._prevDistance = -1;\n this._isFirstTouch = true;\n };\n}\n\nexport default PinchInput;\n","/*\n* Copyright (c) 2023-present NAVER Corp.\n* egjs projects are licensed under the MIT license\n*/\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport WheelInput from \"./input/WheelInput\";\nimport PinchInput from \"./input/PinchInput\";\nimport Camera from \"../core/Camera\";\nimport Motion from \"../core/Motion\";\nimport {\n CONTROL_EVENTS,\n DEFAULT_ANIMATION_DURATION,\n DEFAULT_EASING,\n INFINITE_RANGE\n} from \"../const/internal\";\nimport { ControlEvents, InputEvents } from \"../type/internal\";\n\n/**\n * Options for {@link ZoomControl}\n * @ko {@link ZoomControl}용 옵션들\n * @since 4.0.0\n */\nexport interface ZoomControlOptions {\n /**\n * @copy ZoomControl#scale\n */\n scale: number;\n /**\n * @copy ZoomControl#duration\n */\n duration: number;\n /**\n * @copy ZoomControl#easing\n */\n easing: (x: number) => number;\n}\n\ntype ZoomControlEvents = ControlEvents;\n\n/**\n * Camera's zoom control\n * @ko 카메라의 줌 값을 담당하는 컨트롤\n * @since 4.0.0\n */\nclass ZoomControl extends Component implements CameraControl {\n // Options\n private _scale: ZoomControlOptions[\"scale\"];\n\n // Internal values\n private _controlEl: HTMLElement;\n private _enableBlocked: boolean;\n private _wheelInput: WheelInput;\n private _pinchInput: PinchInput;\n private _motion: Motion;\n private _enabled: boolean;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() { return this._motion.activated; }\n /**\n * Current zoom value\n * @ko 현재 줌 값\n * @since 4.0.0\n * @readonly\n */\n public get zoom() { return this._motion.val; }\n /**\n * @copy View360#wheelScrollable\n */\n public get scrollable() { return this._wheelInput.scrollable; }\n public set scrollable(val: boolean) {\n this._wheelInput.scrollable = val;\n }\n /**\n * @hidden\n */\n public get range() { return this._motion.range; }\n\n /**\n * Scale factor of the zoom\n * @ko 입력에 의한 줌 배율\n * @default 1\n * @since 4.0.0\n */\n public get scale() { return this._scale; }\n public set scale(val: ZoomControlOptions[\"scale\"]) { this._scale = val; }\n\n /**\n * Duration of the input animation (ms)\n * @ko 회전 애니메이션의 시간 (ms)\n * @default 300\n * @since 4.0.0\n */\n public get duration() { return this._motion.duration; }\n\n /**\n * Easing function of the animation\n * @ko 회전 애니메이션에 적용할 easing 함수\n * @default EASING.EASE_OUT_CUBIC\n * @see EASING\n * @since 4.0.0\n */\n public get easing() { return this._motion.easing; }\n\n /**\n * Create new ZoomControl instance\n * @ko ZoomControl의 인스턴스를 생성합니다.\n * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트}\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(controlEl: HTMLElement, enableBlocked: boolean, {\n scale = 1,\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING\n }: Partial = {}) {\n super();\n\n this._scale = scale;\n\n this._controlEl = controlEl;\n this._enableBlocked = enableBlocked;\n this._wheelInput = new WheelInput();\n this._pinchInput = new PinchInput();\n this._motion = new Motion({\n duration,\n easing,\n range: INFINITE_RANGE\n });\n this._enabled = false;\n\n this._bindInputs();\n }\n\n public destroy(): void {\n this.disable();\n this._wheelInput.off();\n this._pinchInput.off();\n this.off();\n }\n\n /**\n * @hidden\n */\n public update(delta: number): void {\n if (!this._enabled) return;\n\n const motion = this._motion;\n motion.update(delta);\n }\n\n public enable(): void {\n if (this._enabled) return;\n\n const element = this._controlEl;\n this._wheelInput.enable(element);\n this._pinchInput.enable(element);\n\n this._enabled = true;\n this._enableBlocked = false;\n\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: false });\n }\n\n public disable(): void {\n if (!this._enabled) return;\n\n this._wheelInput.disable();\n this._pinchInput.disable();\n\n this._enabled = false;\n\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: false });\n }\n\n public sync(camera: Camera): void {\n const motion = this._motion;\n const range = camera.getZoomRange();\n\n motion.setRange(range.min, range.max);\n motion.reset(range.current);\n }\n\n private _bindInputs() {\n const wheelInput = this._wheelInput;\n const pinchInput = this._pinchInput;\n\n wheelInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n wheelInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n wheelInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n pinchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n pinchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n pinchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n }\n\n private _onInputStart = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n ...evt,\n inputType: \"zoom\"\n });\n };\n\n private _onChange = ({ delta }: InputEvents[typeof CONTROL_EVENTS.CHANGE]) => {\n const scale = this._scale;\n const scaledDelta = delta * scale;\n\n this._motion.setNewEndByDelta(scaledDelta);\n };\n\n private _onInputEnd = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n ...evt,\n inputType: \"zoom\"\n });\n };\n}\n\nexport default ZoomControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { quat, vec3 } from \"gl-matrix\";\nimport * as BROWSER from \"../../const/browser\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\nimport { quatToEuler } from \"../../utils\";\n\nexport const ROTATE_CONSTANT = {\n PITCH_DELTA: 1,\n YAW_DELTA_BY_ROLL: 2,\n YAW_DELTA_BY_YAW: 3\n} as const;\n\nROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = {\n targetAxis: [0, 1, 0],\n meshPoint: [0, 0, 1]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = {\n targetAxis: [0, 1, 0],\n meshPoint: [1, 0, 0]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = {\n targetAxis: [1, 0, 0],\n meshPoint: [0, 0, 1]\n};\n\nclass GyroInput extends Component> {\n public quaternion: quat;\n\n private _ignoreRoll: boolean;\n\n private _yawOrigin: number;\n private _yawOffset: number;\n private _orientation: {\n alpha: number;\n beta: number;\n gamma: number;\n }\n private _orientationUpdated: boolean;\n private _needsCalibrate: boolean;\n private _screenOrientation: number;\n private _enabled: boolean;\n\n public get enabled() { return this._enabled; }\n public get orientationUpdated() { return this._orientationUpdated; }\n public get ignoreRoll() { return this._ignoreRoll; }\n public set ignoreRoll(val: boolean) { this._ignoreRoll = val; }\n\n public constructor() {\n super();\n\n this.quaternion = quat.create();\n\n this._orientation = {\n alpha: 0,\n beta: 90,\n gamma: 0\n };\n this._yawOrigin = 0;\n this._yawOffset = 0;\n this._orientationUpdated = false;\n this._screenOrientation = 0;\n this._needsCalibrate = true;\n this._enabled = false;\n }\n\n public enable() {\n if (this._enabled) return;\n\n window.addEventListener(BROWSER.EVENTS.DEVICE_ORIENTATION, this._onDeviceOrientation);\n window.addEventListener(BROWSER.EVENTS.ORIENTATION_CHANGE, this._updateScreenOrientation);\n\n this._updateScreenOrientation();\n this._orientationUpdated = false;\n this._needsCalibrate = true;\n this._enabled = true;\n }\n\n public disable() {\n if (!this._enabled) return;\n\n window.removeEventListener(BROWSER.EVENTS.DEVICE_ORIENTATION, this._onDeviceOrientation);\n window.removeEventListener(BROWSER.EVENTS.ORIENTATION_CHANGE, this._updateScreenOrientation);\n\n this._enabled = false;\n }\n\n public update() {\n this._updateRotation();\n this._orientationUpdated = false;\n }\n\n public collectDelta() {\n if (!this._orientationUpdated) {\n return {\n pitch: 0,\n yaw: 0\n };\n }\n\n const prevRotation = quat.clone(this.quaternion);\n\n this._updateRotation();\n this._orientationUpdated = false;\n\n return this._toEulerDelta(prevRotation, this.quaternion);\n }\n\n public setInitialRotation(yaw: number) {\n this._yawOrigin = yaw;\n }\n\n private _onDeviceOrientation = (evt: DeviceOrientationEvent) => {\n const prevOrientation = this._orientation;\n const { alpha, beta, gamma } = evt;\n\n if (\n alpha == null\n || beta == null\n || gamma == null\n ) return;\n\n prevOrientation.alpha = alpha;\n prevOrientation.beta = beta;\n prevOrientation.gamma = gamma;\n\n this._orientationUpdated = true;\n\n if (this._needsCalibrate) {\n this._needsCalibrate = false;\n this._calibrateSensor();\n }\n };\n\n private _calibrateSensor() {\n const yawOrigin = this._yawOrigin;\n const rotation = this.quaternion;\n\n this._yawOffset = 0;\n this._updateRotation();\n\n const { yaw: sensorYaw } = quatToEuler(rotation);\n this._yawOffset = sensorYaw - yawOrigin;\n this._updateRotation();\n\n this._needsCalibrate = false;\n }\n\n private _updateRotation() {\n const rotation = this.quaternion;\n const { alpha, beta, gamma } = this._orientation;\n\n quat.identity(rotation);\n quat.rotateY(rotation, rotation, (alpha - this._yawOffset) * DEG_TO_RAD);\n quat.rotateX(rotation, rotation, beta * DEG_TO_RAD);\n quat.rotateZ(rotation, rotation, -gamma * DEG_TO_RAD);\n\n const screen = quat.create();\n const screenAngle = -this._screenOrientation * 0.5 * DEG_TO_RAD;\n const world = quat.fromValues(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5));\n\n quat.set(screen, 0, Math.sin(screenAngle), 0, Math.cos(screenAngle));\n quat.multiply(rotation, rotation, screen);\n quat.multiply(rotation, rotation, world);\n\n quat.normalize(rotation, rotation);\n }\n\n private _updateScreenOrientation = () => {\n if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) {\n this._screenOrientation = screen.orientation.angle;\n } else if (window.orientation !== undefined) {\n this._screenOrientation = window.orientation >= 0 ?\n window.orientation : 360 + window.orientation;\n } else {\n this._screenOrientation = 0;\n }\n }\n\n private _toEulerDelta(prevQuat: quat, currentQuat: quat) {\n return {\n yaw: this._getDeltaYaw(prevQuat, currentQuat),\n pitch: this._getDeltaPitch(prevQuat, currentQuat),\n };\n }\n\n private _getDeltaYaw(prvQ: quat, curQ: quat): number {\n const yawDeltaByYaw = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW);\n const yawDeltaByRoll = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL)\n * Math.sin(this._extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n }\n\n private _getDeltaPitch(prvQ: quat, curQ: quat): number {\n return this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n }\n\n private _getRotationDelta(prevQ: quat, curQ: quat, rotateKind: typeof ROTATE_CONSTANT[keyof typeof ROTATE_CONSTANT]) {\n const targetAxis = vec3.fromValues(\n ROTATE_CONSTANT[rotateKind].targetAxis[0],\n ROTATE_CONSTANT[rotateKind].targetAxis[1],\n ROTATE_CONSTANT[rotateKind].targetAxis[2]\n );\n const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint;\n\n const prevQuaternion = quat.clone(prevQ);\n const curQuaternion = quat.clone(curQ);\n\n quat.normalize(prevQuaternion, prevQuaternion);\n quat.normalize(curQuaternion, curQuaternion);\n\n let prevPoint = vec3.fromValues(0, 0, 1);\n let curPoint = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n vec3.transformQuat(targetAxis, targetAxis, curQuaternion);\n\n const rotateDistance = vec3.dot(targetAxis, vec3.cross(vec3.create(), prevPoint, curPoint));\n const rotateDirection = rotateDistance > 0 ? 1 : -1;\n\n // when counter clock wise, use vec3.fromValues(0,1,0)\n // when clock wise, use vec3.fromValues(0,-1,0)\n // const meshPoint1 = vec3.fromValues(0, 0, 0);\n const meshPoint2 = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n\n let meshPoint3;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n meshPoint3 = vec3.fromValues(0, rotateDirection, 0);\n } else {\n meshPoint3 = vec3.fromValues(rotateDirection, 0, 0);\n }\n\n vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion);\n vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion);\n\n const vecU = meshPoint2;\n const vecV = meshPoint3;\n const vecN = vec3.create();\n\n vec3.cross(vecN, vecU, vecV);\n vec3.normalize(vecN, vecN);\n\n const coefficientA = vecN[0];\n const coefficientB = vecN[1];\n const coefficientC = vecN[2];\n\n // a point on the plane\n curPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n\n // a point should project on the plane\n prevPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n\n // distance between prevPoint and the plane\n let distance = Math.abs(\n prevPoint[0] * coefficientA +\n prevPoint[1] * coefficientB +\n prevPoint[2] * coefficientC\n );\n\n const projectedPrevPoint = vec3.create();\n\n vec3.subtract(projectedPrevPoint, prevPoint, vec3.scale(vec3.create(), vecN, distance));\n\n let trigonometricRatio =\n (projectedPrevPoint[0] * curPoint[0] +\n projectedPrevPoint[1] * curPoint[1] +\n projectedPrevPoint[2] * curPoint[2]) /\n (vec3.length(projectedPrevPoint) * vec3.length(curPoint));\n\n // defensive block\n if (trigonometricRatio > 1) {\n trigonometricRatio = 1;\n }\n\n const theta = Math.acos(trigonometricRatio);\n\n const crossVec = vec3.cross(vec3.create(), curPoint, projectedPrevPoint);\n\n distance = coefficientA * crossVec[0]\n + coefficientB * crossVec[1]\n + coefficientC * crossVec[2];\n\n let thetaDirection: number;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n thetaDirection = distance > 0 ? 1 : -1;\n } else {\n thetaDirection = distance < 0 ? 1 : -1;\n }\n\n const deltaRadian = theta * thetaDirection * rotateDirection;\n\n return deltaRadian * RAD_TO_DEG;\n }\n\n private _extractPitchFromQuat(quaternion: quat) {\n const baseV = vec3.fromValues(0, 0, 1);\n vec3.transformQuat(baseV, baseV, quaternion);\n\n return -1 * Math.atan2(\n baseV[1],\n Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2)));\n }\n}\n\nexport default GyroInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport GyroInput from \"./input/GyroInput\";\nimport Motion from \"../core/Motion\";\nimport Camera from \"../core/Camera\";\nimport * as BROWSER from \"../const/browser\";\nimport { CONTROL_EVENTS } from \"../const/internal\";\nimport { ControlEvents } from \"../type/internal\";\nimport { sensorCanBeEnabledIOS } from \"../utils\";\n\n/**\n * Options for {@link GyroControl}\n * @ko {@link GyroControl}용 옵션들\n * @since 4.0.0\n */\nexport interface GyroControlOptions {\n /**\n * @copy GyroControl#ignoreRoll\n */\n ignoreRoll: boolean;\n}\n\nexport type GyroControlEvents = ControlEvents;\n\n/**\n * Camera's rotation control by gyroscope\n * @ko 자이로스코프를 이용한 회전 컨트롤\n * @since 4.0.0\n */\nclass GyroControl extends Component implements CameraControl {\n // Options\n private _ignoreRoll: GyroControlOptions[\"ignoreRoll\"];\n\n // Internal values\n private _enableBlocked: boolean;\n private _input: GyroInput;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._input.enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() {\n return this._input.enabled && this._input.orientationUpdated;\n }\n\n /**\n * When `true`, ignore gyroscope's roll(z-axis rotation) value.\n * :::caution\n * Setting `false` will ignore camera's range limit.\n * Options like {@link View360Options#yawRange}, {@link View360Options#pitchRange} are ignored, and {@link CylinderProjection} also can't force it's camera range limit.\n * :::\n * @ko `true`일 경우 자이로스코프 입력의 roll(z축 회전)값을 무시합니다.\n * :::caution\n * 이 값을 `false`로 설정할 경우 카메라 범위 제약을 무시합니다.\n * {@link View360Options#yawRange}, {@link View360Options#pitchRange}와 같은 값은 무시되며, {@link CylinderProjection} 사용시에도 범위를 벗어날 수 있습니다.\n * :::\n * @default true\n * @since 4.0.0\n */\n public get ignoreRoll() { return this._ignoreRoll; }\n public set ignoreRoll(val: GyroControlOptions[\"ignoreRoll\"]) { this._ignoreRoll = val; }\n\n /**\n * Return availability of the gyroscope.\n * :::caution\n * This will always return false until user permission under environments like iOS which requires user permission when using gyroscope.\n * :::\n * @ko 자이로스코프 사용 가능 여부를 반환합니다.\n * :::caution\n * iOS와 같이 GyroScope 사용시 사용자 Permission을 요구하는 환경에서는 사용자 Permission을 받기 전까지 항상 `false`입니다.\n * :::\n * @example\n * ```ts\n * const gyroAvailable = await GyroControl.isAvailable();\n * ```\n */\n public static async isAvailable(): Promise {\n if (!DeviceMotionEvent) {\n return false;\n }\n\n let onDeviceMotionChange: (evt: DeviceMotionEvent) => void;\n\n const listenDeviceMotion = () => new Promise(res => {\n onDeviceMotionChange = (evt: DeviceMotionEvent) => {\n res(evt.rotationRate && evt.rotationRate.alpha != null);\n };\n\n window.addEventListener(BROWSER.EVENTS.DEVICE_MOTION, onDeviceMotionChange);\n });\n\n const timeout = () => new Promise(res => {\n setTimeout(() => res(false), 1000);\n });\n\n return Promise.race([listenDeviceMotion(), timeout()])\n .then((available: boolean) => {\n window.removeEventListener(BROWSER.EVENTS.DEVICE_MOTION, onDeviceMotionChange);\n\n return available;\n });\n }\n\n /**\n * Request user permission for gyroscope sensor.\n * This can be used in environments like iOS which requires user permission when using gyroscope sensors.\n * @ko 사용자의 sensor permission 취득을 요청합니다.\n * iOS와 같이 gyroscope 사용시 사용자 Permission을 요구하는 환경에서 사용 가능합니다.\n * @returns Whether the permission is granted {@ko 사용자 permission 취득 여부}\n */\n public static async requestSensorPermission(): Promise {\n // Request sensor permission, on iOS13+\n if (sensorCanBeEnabledIOS()) {\n return (DeviceMotionEvent as typeof DeviceMotionEvent & {\n requestPermission: () => Promise;\n }).requestPermission().then(permissionState => {\n return permissionState === \"granted\";\n }).catch(() => false);\n }\n\n return true;\n }\n\n /**\n * Create new GyroControl instance\n * @ko GyroControl의 인스턴스를 생성합니다.\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(enableBlocked: boolean, {\n ignoreRoll = true\n }: Partial = {}) {\n super();\n\n this._enableBlocked = enableBlocked;\n this._ignoreRoll = ignoreRoll;\n this._input = new GyroInput();\n }\n\n /**\n * @copy CameraControl#destroy\n */\n public destroy(): void {\n this.disable();\n this._input.off();\n this.off();\n }\n\n /**\n * @hidden\n */\n public update(camera: Camera, yaw: Motion, pitch: Motion, zoom: number) {\n if (!this._ignoreRoll) {\n this._updateQuaternion(camera, zoom);\n } else {\n this._updateYawPitch(camera, yaw, pitch, zoom);\n }\n }\n\n /**\n * @copy CameraControl#enable\n */\n public enable(): void {\n if (this._input.enabled) return;\n\n this._input.enable();\n this._enableBlocked = false;\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: false });\n }\n\n /**\n * @copy CameraControl#disable\n */\n public disable(): void {\n if (!this._input.enabled) return;\n\n this._input.disable();\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: false });\n }\n\n /**\n * @copy CameraControl#sync\n */\n public sync(): void {} // eslint-disable-line @typescript-eslint/no-empty-function\n\n private _updateYawPitch(camera: Camera, yaw: Motion, pitch: Motion, zoom: number) {\n const input = this._input;\n if (!input.enabled) return;\n\n const {\n yaw: yawDelta,\n pitch: pitchDelta\n } = input.collectDelta();\n\n yaw.add(yawDelta);\n pitch.add(pitchDelta);\n\n camera.lookAt({\n yaw: yaw.val,\n pitch: pitch.val,\n zoom\n });\n }\n\n private _updateQuaternion(camera: Camera, zoom: number) {\n const input = this._input;\n if (!input.enabled) return;\n\n input.update();\n camera.rotate(input.quaternion, zoom);\n }\n}\n\nexport default GyroControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport CameraControl from \"./CameraControl\";\nimport RotateControl, { RotateControlEvents, RotateControlOptions } from \"./RotateControl\";\nimport ZoomControl, { ZoomControlOptions } from \"./ZoomControl\";\nimport GyroControl, { GyroControlOptions } from \"./GyroControl\";\nimport Camera from \"../core/Camera\";\nimport CameraAnimation from \"../core/CameraAnimation\";\nimport * as BROWSER from \"../const/browser\";\nimport { CAMERA_EVENTS, CONTROL_EVENTS } from \"../const/internal\";\nimport { ValueOf } from \"../type/utils\";\nimport { getObjectOption, hfovToZoom } from \"../utils\";\n\n/**\n * Options for {@link PanoControl}\n * @ko {@link PanoControl}용 옵션들\n * @since 4.0.0\n */\nexport interface PanoControlOptions {\n /**\n * @copy View360#useGrabCursor\n */\n useGrabCursor: boolean;\n /**\n * @copy View360#scrollable\n */\n scrollable: boolean;\n /**\n * @copy View360#wheelScrollable\n */\n wheelScrollable: boolean;\n /**\n * @copy View360#disableContextMenu\n */\n disableContextMenu: boolean;\n /**\n * Options for {@link RotateControl}.\n * `false` to disable rotation.\n * @ko {@link RotateControl}용 옵션들.\n * `false`일 경우 회전이 비활성화됩니다.\n * @since 4.0.0\n */\n rotate: boolean | Partial;\n /**\n * Options for {@link ZoomControl}.\n * `false` to disable zoom.\n * @ko {@link ZoomControl}용 옵션들.\n * `false`일 경우 줌이 비활성화됩니다.\n * @since 4.0.0\n */\n zoom: boolean | Partial;\n /**\n * Options for {@link GyroControl}.\n * `false` to disable gyroscope control.\n * @ko {@link GyroControl}용 옵션들.\n * `false`일 경우 자이로스코프를 통한 컨트롤이 비활성화됩니다.\n * @since 4.0.0\n */\n gyro: boolean | Partial;\n}\n\n/**\n * Panorama control for View360\n * @ko View360용 파노라마 컨트롤\n * @since 4.0.0\n */\nclass PanoControl {\n // Options\n private _useGrabCursor: PanoControlOptions[\"useGrabCursor\"];\n private _disableContextMenu: PanoControlOptions[\"disableContextMenu\"];\n\n // Internal Values\n private _camera: Camera;\n private _controlEl: HTMLElement;\n private _rotateControl: RotateControl;\n private _zoomControl: ZoomControl;\n private _gyroControl: GyroControl;\n private _ignoreZoomScale: boolean;\n private _enabled: boolean;\n\n /**\n * @copy View360#useGrabCursor\n */\n public get useGrabCursor() { return this._useGrabCursor; }\n public set useGrabCursor(val: PanoControlOptions[\"useGrabCursor\"]) {\n if (val === this._useGrabCursor) return;\n\n this._useGrabCursor = val;\n\n if (val && this._enabled) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n } else if (!val) {\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n }\n\n /**\n * @copy View360#disableContextMenu\n */\n public get disableContextMenu() { return this._disableContextMenu; }\n public set disableContextMenu(val: PanoControlOptions[\"disableContextMenu\"]) {\n if (val === this._disableContextMenu) return;\n\n this._disableContextMenu = val;\n\n if (val && this._enabled) {\n this._blockContextMenu();\n } else if (!val) {\n this._restoreContextMenu();\n }\n }\n\n /**\n * @copy View360#disableContextMenu\n */\n public get scrollable() { return this._rotateControl.scrollable; }\n public set scrollable(val: PanoControlOptions[\"scrollable\"]) { this._rotateControl.scrollable = val; }\n /**\n * @copy View360#disableContextMenu\n */\n public get wheelScrollable() { return this._zoomControl.scrollable; }\n public set wheelScrollable(val: PanoControlOptions[\"wheelScrollable\"]) { this._zoomControl.scrollable = val; }\n /**\n * When `true`, disables rotation slow-down by zoom-value.\n * @ko `true`일 경우 줌 된 정도에 따라 회전속도를 늦추는 동작을 비활성화합니다.\n * @since 4.0.0\n */\n public get ignoreZoomScale() { return this._ignoreZoomScale; }\n public set ignoreZoomScale(val: boolean) { this._ignoreZoomScale = val; }\n\n /**\n * Whether the control is enabled or not\n * @ko 컨트롤 활성화 여부를 가리키는 값\n * @readonly\n * @since 4.0.0\n */\n public get enabled() { return this._enabled; }\n /**\n * @copy View360#rotate\n */\n public get rotate() { return this._rotateControl; }\n /**\n * @copy View360#zoom\n */\n public get zoom() { return this._zoomControl; }\n /**\n * @copy View360#gyro\n */\n public get gyro() { return this._gyroControl; }\n\n /**\n * Whether one of the controls is animating at the moment\n * @ko 현재 컨트롤 중 하나라도 동작중인지 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get animating() {\n return this._rotateControl.animating\n || this._zoomControl.animating\n || this._gyroControl.animating;\n }\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param element - Canvas element {@ko 캔버스 엘리먼트}\n * @param camera - Camera instance {@ko Camera 인스턴스}\n * @param options - Options for PanoControl {@ko PanoControl 옵션들}\n */\n public constructor(element: HTMLElement, camera: Camera, {\n useGrabCursor,\n scrollable,\n wheelScrollable,\n disableContextMenu,\n rotate,\n zoom,\n gyro\n }: PanoControlOptions) {\n // Bind Options\n this._useGrabCursor = useGrabCursor;\n this._disableContextMenu = disableContextMenu;\n\n // Set internal values\n this._camera = camera;\n this._controlEl = element;\n this._ignoreZoomScale = false;\n this._enabled = false;\n\n this._rotateControl = new RotateControl(element, !rotate, getObjectOption(rotate));\n this._zoomControl = new ZoomControl(element, !zoom, getObjectOption(zoom));\n this._gyroControl = new GyroControl(!gyro, getObjectOption(gyro));\n\n this._rotateControl.scrollable = scrollable;\n this._zoomControl.scrollable = wheelScrollable;\n\n this._bindEvents();\n }\n\n /**\n * Destroy the instance and remove all event listeners attached.\n * This also will reset CSS cursor to initial.\n * @ko 인스턴스를 삭제하고 부착된 모든 이벤트 리스너를 제거합니다.\n * 또한, 캔버스에 적용된 CSS cursor도 제거합니다.\n * @since 4.0.0\n */\n public destroy(): void {\n this.disable();\n this._rotateControl.destroy();\n this._zoomControl.destroy();\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n\n /**\n * Resize control to match target size.\n * @ko 컨트롤이 내부에 캐시하고 있는 크기값을 갱신합니다.\n * @param width New width {@ko 변경된 너비}\n * @param height New height {@ko 변경된 높이}\n * @since 4.0.0\n */\n public resize(width: number, height: number): void {\n const camera = this._camera;\n\n this._rotateControl.resize(camera.fov, camera.aspect, width, height);\n }\n\n /**\n * Enable this control and add event listeners.\n * @ko 컨트롤을 활성화하고 이벤트 리스너들을 추가합니다.\n * @since 4.0.0\n */\n public async enable(): Promise {\n if (this._enabled) return;\n\n if (!this._rotateControl.enableBlocked) {\n this._rotateControl.enable();\n }\n\n if (!this._zoomControl.enableBlocked) {\n this._zoomControl.enable();\n }\n\n if (!this._gyroControl.enableBlocked) {\n if (await GyroControl.isAvailable()) {\n this._gyroControl.enable();\n }\n }\n\n this.sync();\n\n if (this._disableContextMenu) {\n this._blockContextMenu();\n }\n\n this._enabled = true;\n }\n\n /**\n * Disable this control and remove all event listeners\n * @ko 컨트롤을 비활성화하고 모든 이벤트 리스너들을 제거합니다.\n * @since 4.0.0\n */\n public disable(): void {\n if (!this._enabled) return;\n\n this._rotateControl.disable();\n this._zoomControl.disable();\n this._gyroControl.disable();\n\n this._restoreContextMenu();\n\n this._enabled = false;\n }\n\n /**\n * Update control by given deltaTime\n * @ko 컨트롤을 주어진 시간만큼 업데이트합니다.\n * @param delta Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n * @internal\n */\n public update(delta: number): void {\n const camera = this._camera;\n const rotateControl = this._rotateControl;\n const zoomControl = this._zoomControl;\n const gyroControl = this._gyroControl;\n\n zoomControl.update(delta);\n const zoom = hfovToZoom(camera.fov, zoomControl.zoom);\n\n // Slow down rotation on zoom-in\n const zoomScale = this._ignoreZoomScale ? 1 : Math.max(zoom, 1);\n rotateControl.setZoomScale(zoomScale);\n rotateControl.updateRange(camera, zoom);\n rotateControl.update(delta);\n\n const yaw = rotateControl.yaw;\n const pitch = rotateControl.pitch;\n\n if (gyroControl.enabled) {\n gyroControl.update(camera, yaw, pitch, zoom);\n } else {\n camera.lookAt({\n yaw: yaw.val,\n pitch: pitch.val,\n zoom\n });\n }\n }\n\n /**\n * Synchronize this control's state to current camera state\n * @ko 컨트롤을 카메라의 현재 상태와 동기화합니다.\n * @since 4.0.0\n */\n public sync(): void {\n const camera = this._camera;\n\n this._zoomControl.sync(camera);\n this._rotateControl.sync(camera);\n }\n\n private _blockContextMenu() {\n const el = this._controlEl;\n\n el.addEventListener(BROWSER.EVENTS.CONTEXT_MENU, this._preventContextMenu);\n }\n\n private _restoreContextMenu() {\n const el = this._controlEl;\n\n el.removeEventListener(BROWSER.EVENTS.CONTEXT_MENU, this._preventContextMenu);\n }\n\n private _preventContextMenu = (evt: MouseEvent) => {\n evt.preventDefault();\n };\n\n private _setCursor(newCursor: ValueOf) {\n if (!this._useGrabCursor && newCursor !== BROWSER.CURSOR.NONE) return;\n\n const targetEl = this._controlEl;\n targetEl.style.cursor = newCursor;\n }\n\n private _bindEvents() {\n const rotateControl = this._rotateControl;\n const zoomControl = this._zoomControl;\n\n rotateControl.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n rotateControl.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n rotateControl.on(CONTROL_EVENTS.ENABLE, this._onEnable);\n rotateControl.on(CONTROL_EVENTS.DISABLE, this._onDisable);\n zoomControl.on(CONTROL_EVENTS.ENABLE, this._onEnable);\n zoomControl.on(CONTROL_EVENTS.DISABLE, this._onDisable);\n this._camera.on(CAMERA_EVENTS.ANIMATION_END, this._onCameraAnimationEnd);\n }\n\n private _onInputStart = (evt: RotateControlEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n if (this._useGrabCursor && !evt.isKeyboard) {\n this._setCursor(BROWSER.CURSOR.GRABBING);\n }\n };\n\n private _onInputEnd = (evt: RotateControlEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n if (this._useGrabCursor && !evt.isKeyboard) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n }\n };\n\n private _onEnable = ({\n control,\n updateCursor\n }: {\n control: CameraControl;\n updateCursor: boolean;\n }) => {\n if (updateCursor && this._useGrabCursor) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n }\n\n control.sync(this._camera);\n };\n\n private _onDisable = ({\n updateCursor\n }: {\n updateCursor: boolean\n }) => {\n if (updateCursor) {\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n };\n\n private _onCameraAnimationEnd = ({ animation }: { animation: CameraAnimation }) => {\n animation.getFinishPromise().then(() => {\n this.sync();\n });\n };\n}\n\nexport default PanoControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport TextureVideo from \"./TextureVideo\";\nimport TextureCube from \"./TextureCube\";\n\n/**\n * @hidden\n */\nabstract class Texture {\n public width: number;\n public height: number;\n public flipY: boolean;\n public wrapS: number;\n public wrapT: number;\n\n public constructor({\n width,\n height,\n flipY\n }: {\n width: number;\n height: number;\n flipY: boolean;\n }) {\n this.width = width;\n this.height = height;\n this.flipY = flipY;\n this.wrapS = WebGLRenderingContext.CLAMP_TO_EDGE;\n this.wrapT = WebGLRenderingContext.CLAMP_TO_EDGE;\n }\n\n public destroy() {\n // DO_NOTHING\n }\n\n public isVideo(): this is TextureVideo {\n return false;\n }\n\n public isCube(): this is TextureCube {\n return false;\n }\n}\n\nexport default Texture;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture from \"./Texture\";\n\n/**\n * @hidden\n */\nclass Texture2D extends Texture {\n public source: Exclude;\n\n public constructor({\n source,\n width,\n height,\n flipY\n }: {\n source: Exclude;\n width: number;\n height: number;\n flipY: boolean;\n }) {\n super({\n width,\n height,\n flipY\n });\n\n this.source = source;\n }\n}\n\nexport default Texture2D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"./Texture2D\";\n\n/**\n * @hidden\n */\nclass TextureVideo extends Texture2D {\n public source: HTMLVideoElement;\n\n public destroy() {\n const video = this.source;\n\n video.pause();\n video.removeAttribute(\"src\");\n video.load();\n }\n\n public isVideo(): this is TextureVideo { return true; }\n\n public isPaused() {\n const video = this.source;\n\n return video.paused || video.ended || video.readyState <= 2;\n }\n\n public hasAudio() {\n const video = this.source as any;\n\n if (video.audioTracks) {\n return video.audioTracks.length > 0;\n }\n\n if (video.webkitAudioDecodedByteCount != null) {\n return video.webkitAudioDecodedByteCount > 0;\n }\n\n if (video.mozHasAudio != null) {\n return video.mozHasAudio;\n }\n\n // We don't know whether the video has audio or not, return true\n return true;\n }\n}\n\nexport default TextureVideo;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture from \"./Texture\";\n\n/**\n * @hidden\n */\nclass TextureCube extends Texture {\n public sources: TexImageSource[];\n\n public constructor({\n sources,\n width,\n height,\n flipY\n }: {\n sources: TexImageSource[];\n width: number;\n height: number;\n flipY: boolean;\n }) {\n super({\n width,\n height,\n flipY\n });\n\n this.sources = sources;\n }\n\n public isCube(): this is TextureCube { return true; }\n}\n\nexport default TextureCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ImReady from \"@egjs/imready\";\nimport Texture from \"../texture/Texture\";\nimport Texture2D from \"../texture/Texture2D\";\nimport TextureVideo from \"../texture/TextureVideo\";\nimport TextureCube from \"../texture/TextureCube\";\nimport { getObjectOption, isString } from \"../utils\";\nimport { VideoConfig } from \"../type/external\";\nimport { ProjectionOptions } from \"../projection/Projection\";\n\n/**\n * @hidden\n */\nclass TextureLoader {\n private _loadChecker: ImReady;\n\n constructor() {\n this._loadChecker = new ImReady();\n }\n\n public async load(src: ProjectionOptions[\"src\"], video: ProjectionOptions[\"video\"]): Promise {\n if (video) {\n return this.loadVideo(src, getObjectOption(video));\n } else {\n if (Array.isArray(src) && src.length > 1) {\n return this.loadCubeImage(src);\n } else {\n const imgSrc = Array.isArray(src) ? src[0] : src;\n return this.loadImage(imgSrc);\n }\n }\n }\n\n public async loadImage(src: string | HTMLElement): Promise {\n const images = this._toImageArray(src);\n\n return this._load(images, resolve => {\n const image = images[0];\n\n resolve(new Texture2D({\n source: image,\n width: image.naturalWidth,\n height: image.naturalHeight,\n flipY: true\n }));\n });\n }\n\n public async loadCubeImage(src: Array): Promise {\n const images = this._toImageArray(src);\n\n return this._load(images, resolve => {\n resolve(new TextureCube({\n sources: images,\n width: images[0].naturalWidth,\n height: images[0].naturalHeight,\n flipY: false\n }));\n });\n }\n\n public async loadVideo(src: ProjectionOptions[\"src\"], videoConfig: Partial): Promise {\n const config: VideoConfig = {\n autoplay: true,\n muted: true,\n loop: false,\n volume: 1,\n ...videoConfig,\n };\n const video = this._toVideoElement(src, config);\n\n return this._load([video], resolve => {\n const { autoplay, muted } = config;\n\n video.currentTime = 0;\n if (autoplay && muted) {\n video.play().catch(() => void 0);\n }\n\n resolve(new TextureVideo({\n source: video,\n width: video.videoWidth,\n height: video.videoHeight,\n flipY: true\n }));\n });\n }\n\n private _load(content: HTMLElement[], onLoad: (resolve: (value: T) => void) => void): Promise {\n const loader = this._loadChecker;\n\n return new Promise((resolve, reject) => {\n loader.once(\"ready\", evt => {\n if (evt.errorCount > 0) return;\n\n onLoad(resolve);\n });\n\n loader.once(\"error\", reject);\n loader.check(content);\n });\n }\n\n private _toImageArray(src: ProjectionOptions[\"src\"]): HTMLImageElement[] {\n const srcs = Array.isArray(src) ? src : [src];\n\n return srcs.map(source => {\n if (isString(source)) {\n const imgEl = new Image();\n\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = source;\n\n return imgEl;\n } else {\n return source as HTMLImageElement;\n }\n });\n }\n\n private _toVideoElement(src: ProjectionOptions[\"src\"], {\n muted,\n loop,\n volume\n }: VideoConfig): HTMLVideoElement {\n if (src instanceof HTMLVideoElement) {\n return src;\n }\n\n const video = document.createElement(\"video\");\n\n video.crossOrigin = \"anonymous\";\n video.playsInline = true;\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.muted = muted;\n video.volume = volume;\n video.loop = loop;\n\n if (Array.isArray(src)) {\n src.forEach(source => this._appendSourceElement(video, source));\n } else {\n this._appendSourceElement(video, src);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0 && video.readyState < 1) {\n video.load();\n }\n\n return video;\n }\n\n private _appendSourceElement(video: HTMLMediaElement, src: string | HTMLElement) {\n if (src instanceof HTMLSourceElement) {\n return src;\n }\n\n const sourceEl = document.createElement(\"source\");\n sourceEl.src = src as string;\n video.appendChild(sourceEl);\n }\n}\n\nexport default TextureLoader;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * @internal\n */\nclass FrameAnimator {\n public maxDeltaTime: number;\n\n private _context: Window | XRSession;\n private _rafId: number;\n private _rafTimer: number;\n private _lastUpdateTime: number;\n\n /** */\n public constructor(maxDeltaTime: number, context: Window | XRSession = window) {\n this.maxDeltaTime = maxDeltaTime;\n\n this._context = context;\n this._rafId = -1;\n this._rafTimer = -1;\n this._lastUpdateTime = -1;\n }\n\n public start(callback: (delta: number, ...args: any[]) => any) {\n const context = this._context;\n\n // No context / callback set\n if (!context || !callback) return;\n\n // Animation already started\n if (this._rafId >= 0 || this._rafTimer >= 0) return;\n\n const loop = (_time: number, frame?: XRFrame) => {\n const time = Date.now();\n const delta = Math.min(time - this._lastUpdateTime, this.maxDeltaTime * 1000);\n\n callback(delta, frame);\n\n this._lastUpdateTime = time;\n this._rafId = context.requestAnimationFrame(loop);\n };\n\n this._lastUpdateTime = Date.now();\n this._rafId = context.requestAnimationFrame(loop);\n }\n\n public stop() {\n if (this._rafId >= 0) {\n this._context.cancelAnimationFrame(this._rafId);\n }\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n }\n\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n public changeContext(context: Window | XRSession) {\n this.stop();\n this._context = context;\n }\n}\n\nexport default FrameAnimator;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport * as BROWSER from \"../const/browser\";\n\n/**\n * Automatic resizer that uses both ResizeObserver and window resize event\n */\nclass AutoResizer {\n private _enabled: boolean;\n private _resizeObserver: ResizeObserver | null;\n private _useResizeObserver: boolean;\n private _onResize: () => any;\n\n public get useResizeObserver() { return this._useResizeObserver; }\n\n /**\n * Returns whether AutoResizer is enabled\n */\n public get enabled() { return this._enabled; }\n\n /** */\n public constructor(useResizeObserver: boolean, onResize: () => any) {\n this._useResizeObserver = useResizeObserver;\n\n this._enabled = false;\n this._resizeObserver = null;\n this._onResize = onResize;\n }\n\n /**\n * Enable resizer\n */\n public enable(element: HTMLElement): this {\n if (this._enabled) {\n this.disable();\n }\n\n if (this._useResizeObserver && !!window.ResizeObserver) {\n const bbox = element.getBoundingClientRect();\n const resizeImmediate = bbox.width !== 0 || bbox.height !== 0;\n\n const resizeObserver = new ResizeObserver(resizeImmediate ? this._skipFirstResize : this._onResize);\n\n resizeObserver.observe(element);\n\n this._resizeObserver = resizeObserver;\n } else {\n window.addEventListener(BROWSER.EVENTS.RESIZE, this._onResize);\n }\n\n this._enabled = true;\n\n return this;\n }\n\n /**\n * Disable resizer\n */\n public disable(): this {\n if (!this._enabled) return this;\n\n const resizeObserver = this._resizeObserver;\n if (resizeObserver) {\n resizeObserver.disconnect();\n this._resizeObserver = null;\n } else {\n window.removeEventListener(BROWSER.EVENTS.RESIZE, this._onResize);\n }\n\n this._enabled = false;\n\n return this;\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n private _skipFirstResize = (() => {\n let isFirstResize = true;\n\n return (() => {\n if (isFirstResize) {\n isFirstResize = false;\n\n return;\n }\n this._onResize();\n });\n })();\n}\n\nexport default AutoResizer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Camera from \"./Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport View360 from \"../View360\";\nimport * as BROWSER from \"../const/browser\";\nimport { CONTROL_EVENTS } from \"../const/internal\";\nimport { circulate, getObjectOption } from \"../utils\";\n\n/**\n * Options for {@link Autoplay}\n * @ko {@link Autoplay}용 옵션들\n * @since 4.0.0\n */\nexport interface AutoplayOptions {\n /**\n * @copy Autoplay#delay\n */\n delay: number;\n /**\n * @copy Autoplay#delayOnMouseLeave\n */\n delayOnMouseLeave: number;\n /**\n * @copy Autoplay#speed\n */\n speed: number;\n /**\n * @copy Autoplay#pauseOnHover\n */\n pauseOnHover: boolean;\n /**\n * @copy Autoplay#canInterrupt\n */\n canInterrupt: boolean;\n /**\n * @copy Autoplay#disableOnInterrupt\n */\n disableOnInterrupt: boolean;\n}\n\n/**\n * A manager class for autoplay feature.\n * @ko Autoplay 기능의 매니저 클래스.\n * @since 4.0.0\n */\nclass Autoplay {\n // Options\n private _delay: number;\n private _delayOnMouseLeave: number;\n private _speed: number;\n private _pauseOnHover: boolean;\n private _canInterrupt: boolean;\n private _disableOnInterrupt: boolean;\n\n // Internal values\n private _enableBlocked: boolean;\n private _camera: Camera;\n private _control: PanoControl;\n private _element: HTMLElement;\n private _enabled: boolean;\n private _interrupted: boolean;\n private _interruptionTimer: number;\n private _hovering: boolean;\n\n /**\n * Whether autoplay is enabled or not\n * @ko 자동재생 활성화 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * Whether autoplay is updating the camera at the moment\n * @ko 현재 자동재생이 동작중인지 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get playing() {\n return this._enabled && !this._interrupted;\n }\n\n /**\n * Reactivation delay after mouse input in milisecond.\n * @ko 재활성화되기까지의 시간 (밀리초 단위)\n * @default 2000\n * @since 4.0.0\n */\n public get delay() { return this._delay; }\n public set delay(val: number) { this._delay = val; }\n\n /**\n * Reactivation delay after mouse leave when using {@link AutoplayOptions#pauseOnHover}\n * @ko {@link AutoplayOptions#pauseOnHover} 사용시 마우스가 캔버스 영역을 떠난 뒤 자동재생이 다시 활성화되기까지의 시간\n * @default 0\n * @since 4.0.0\n */\n public get delayOnMouseLeave() { return this._delayOnMouseLeave; }\n public set delayOnMouseLeave(val: number) { this._delayOnMouseLeave = val; }\n\n /**\n * Y-axis(yaw) rotation speed\n * @ko Y-축 회전(yaw)의 속도\n * @default 1\n * @since 4.0.0\n */\n public get speed() { return this._speed; }\n public set speed(val: number) { this._speed = val; }\n\n /**\n * Whether to pause rotation on mouse hover\n * @ko 마우스가 캔버스 영역에 들어왔을 때 자동재생을 정지할지 여부\n * @default false\n * @since 4.0.0\n */\n public get pauseOnHover() { return this._pauseOnHover; }\n public set pauseOnHover(val: boolean) { this._pauseOnHover = val; }\n\n /**\n * Whether user can interrupt the rotation with click/wheel input\n * @ko 클릭이나 휠같은 사용자 인터랙션시 자동재생을 멈출지 여부\n * @default true\n * @since 4.0.0\n */\n public get canInterrupt() { return this._canInterrupt; }\n public set canInterrupt(val: boolean) { this._canInterrupt = val; }\n\n /**\n * Whether to disable autoplay on user interrupt\n * @ko 사용자 동작에 의해 자동재생이 정지할 때, {@link Autoplay#disable}을 호출하여 자동재생을 영구히 정지할지 여부\n * @default false\n * @since 4.0.0\n */\n public get disableOnInterrupt() { return this._disableOnInterrupt; }\n public set disableOnInterrupt(val: boolean) { this._disableOnInterrupt = val; }\n\n /**\n * Create new AutoPlayer instance\n * @param camera - Instance of the {@link Camera} {@ko Camera의 인스턴스}\n * @param element - Canvas element {@ko 캔버스 엘리먼트}\n * @param options - Autoplay options {@ko 자동재생 옵션들}\n * @since 4.0.0\n */\n public constructor(viewer: View360, element: HTMLElement, options: boolean | Partial) {\n this._camera = viewer.camera;\n this._control = viewer.control;\n this._element = element;\n\n this._enabled = false;\n this._interrupted = false;\n this._interruptionTimer = -1;\n this._hovering = false;\n\n const {\n delay = 2000,\n delayOnMouseLeave = 0,\n speed = 1,\n pauseOnHover = false,\n canInterrupt = true,\n disableOnInterrupt = false\n } = getObjectOption(options);\n\n this._enableBlocked = !options;\n this._delay = delay;\n this._delayOnMouseLeave = delayOnMouseLeave;\n this._speed = speed;\n this._pauseOnHover = pauseOnHover;\n this._canInterrupt = canInterrupt;\n this._disableOnInterrupt = disableOnInterrupt;\n }\n\n /**\n * Destroy the instance and remove all event listeners attached\n * @ko 인스턴스를 제거하고 연결된 모든 이벤트 핸들러를 삭제합니다.\n * @since 4.0.0\n */\n public destroy(): void {\n this.disable();\n }\n\n /**\n * Rotate camera by given deltaTime\n * @ko 주어진 deltaTime만큼 카메라를 회전시킵니다.\n * @param deltaTime - Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n */\n public update(deltaTime: number): void {\n if (!this._enabled) return;\n if (this._interrupted) {\n if (this._disableOnInterrupt) {\n this.disable();\n }\n\n return;\n }\n\n const camera = this._camera;\n const delta = -this._speed * deltaTime / 100;\n\n camera.yaw = circulate(camera.yaw + delta, 0, 360);\n }\n\n /**\n * Enable autoplay and add event listeners.\n * @ko 자동재생을 활성화하고 이벤트리스너들을 추가합니다.\n * @since 4.0.0\n */\n public enable(): void {\n const control = this._control;\n const element = this._element;\n\n if (this._enabled || control.gyro.enabled) return;\n\n control.rotate.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.rotate.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.zoom.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.zoom.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.gyro.on(CONTROL_EVENTS.ENABLE, this._onGyroEnable);\n\n element.addEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter, false);\n element.addEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave, false);\n\n this._enabled = true;\n this._enableBlocked = false;\n }\n\n /**\n * Enable autoplay after current `delay` value.\n * @ko 현재의 `delay`값만큼 시간이 지난 다음에 자동재생을 활성화합니다.\n * @since 4.0.0\n */\n public enableAfterDelay() {\n this.enable();\n this._interrupted = true;\n this._setUninterruptedAfterDelay(this._delay);\n }\n\n /**\n * Disable autoplay and remove all event handlers.\n * @ko 자동재생을 비활성화하고 모든 이벤트 핸들러를 제거합니다.\n * @since 4.0.0\n */\n public disable(): void {\n if (!this._enabled) return;\n\n const control = this._control;\n const element = this._element;\n\n control.rotate.off(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.rotate.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.zoom.off(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.zoom.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.gyro.off(CONTROL_EVENTS.ENABLE, this._onGyroEnable);\n\n element.removeEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter, false);\n element.removeEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave, false);\n\n this._enabled = false;\n this._interrupted = false;\n this._hovering = false;\n\n this._clearTimeout();\n }\n\n private _onInputStart = () => {\n if (!this._canInterrupt) return;\n\n this._interrupted = true;\n this._clearTimeout();\n };\n\n private _onInputEnd = () => {\n this._setUninterruptedAfterDelay(this._delay);\n };\n\n private _onGyroEnable = () => {\n this.disable();\n };\n\n private _onMouseEnter = () => {\n if (!this._pauseOnHover) return;\n this._interrupted = true;\n this._hovering = true;\n };\n\n private _onMouseLeave = () => {\n if (!this._pauseOnHover) return;\n this._hovering = false;\n this._setUninterruptedAfterDelay(this._delayOnMouseLeave);\n };\n\n private _setUninterruptedAfterDelay(delay: number): void {\n if (this._hovering) return;\n\n this._clearTimeout();\n\n if (delay > 0) {\n this._interruptionTimer = window.setTimeout(() => {\n this._interrupted = false;\n this._interruptionTimer = -1;\n }, delay);\n } else {\n this._interrupted = false;\n this._interruptionTimer = -1;\n }\n }\n\n private _clearTimeout(): void {\n if (this._interruptionTimer >= 0) {\n window.clearTimeout(this._interruptionTimer);\n this._interruptionTimer = -1;\n }\n }\n}\n\nexport default Autoplay;\n","import { mat4 } from \"gl-matrix\";\nimport Component from \"@egjs/component\";\nimport WebGLContext from \"./WebGLContext\";\nimport GyroControl from \"../control/GyroControl\";\nimport * as BROWSER from \"../const/browser\";\nimport { SESSION_VR, XR_REFERENCE_SPACE } from \"../const/internal\";\nimport { EVENTS } from \"../const/external\";\n\ninterface XRSessionOptions extends XRSessionInit {\n [key: string]: any;\n}\n\n/**\n * WebXR manager class\n * @ko WebXR 매니저 클래스\n * @since 4.0.0\n */\nclass XRManager extends Component<{\n /**\n * An event that fires on entering VR session\n * @ko VR 세션 진입시에 트리거되는 이벤트\n * @eventName vrStart\n * @eventOf XRManager\n * @version 4.0.0\n */\n [EVENTS.VR_START]: {\n session: XRSession;\n };\n /**\n * An event that fires on exiting VR session\n * @ko VR 세션에서 나갈 때 트리거되는 이벤트\n * @eventName vrEnd\n * @eventOf XRManager\n * @version 4.0.0\n */\n [EVENTS.VR_END]: void;\n}> {\n private _ctx: WebGLContext;\n private _xrSession: XRSession | null;\n private _xrRefSpace: XRReferenceSpace | null;\n private _options: XRSessionOptions;\n\n /**\n * Create new instance.\n * 새 인스턴스를 생성합니다.\n * @param ctx - Instance of WebGL context helper {@ko WebGL 콘텍스트 헬퍼의 인스턴스}\n * @param options - Options {@ko 옵션들}\n */\n public constructor(ctx: WebGLContext, options: XRSessionOptions = {}) {\n super();\n\n this._xrSession = null;\n this._xrRefSpace = null;\n this._ctx = ctx;\n this._options = options;\n }\n\n /**\n * Destroy instance and end XR session if there was any.\n * @ko 인스턴스를 제거하고, XR 세션이 존재할 경우 종료합니다.\n * @since 4.0.0\n */\n public destroy = () => {\n this.exit();\n this.off();\n };\n\n /**\n * Returns WebXR availability.\n * @ko WebXR 사용 가능 여부를 반환합니다.\n * @since 4.0.0\n */\n public async isAvailable(): Promise {\n // eslint-disable-next-line compat/compat\n const xr = window.navigator.xr;\n if (!xr) return false;\n\n return xr.isSessionSupported(SESSION_VR)\n .then(available => {\n return available;\n }).catch(() => {\n return false;\n });\n }\n\n /**\n * Enter VR session\n * @ko VR 세션에 진입합니다.\n * @since 4.0.0\n */\n public async enter() {\n const ctx = this._ctx;\n\n // eslint-disable-next-line compat/compat\n const xr = window.navigator.xr;\n if (!xr) return;\n\n await GyroControl.requestSensorPermission();\n\n const options = {\n ...{\n requiredFeatures: [XR_REFERENCE_SPACE]\n },\n ...this._options\n };\n\n await ctx.makeXRCompatible();\n\n const session = await xr.requestSession(SESSION_VR, options);\n ctx.bindXRLayer(session);\n\n const refSpace = await session.requestReferenceSpace(XR_REFERENCE_SPACE);\n\n this._setSession(session, refSpace);\n\n this.trigger(EVENTS.VR_START, {\n session\n });\n }\n\n /**\n * Exit VR session\n * @ko VR 세션에서 나갑니다.\n * @since 4.0.0\n */\n public exit() {\n const xrSession = this._xrSession;\n\n if (xrSession) {\n xrSession.end()\n .catch(() => void 0);\n }\n\n this._xrSession = null;\n this._xrRefSpace = null;\n }\n\n /**\n * @hidden\n */\n public canRender(frame: XRFrame) {\n const refSpace = this._xrRefSpace;\n\n if (!refSpace) return false;\n\n const pose = frame.getViewerPose(refSpace);\n\n return !!pose;\n }\n\n /**\n * @hidden\n */\n public getEyeParams(frame: XRFrame): Array<{\n viewport: XRViewport;\n vMatrix: mat4;\n pMatrix: mat4;\n }> | null {\n const session = frame.session;\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n if (!pose) return null;\n\n const glLayer = session.renderState.baseLayer;\n\n if (!glLayer) return null;\n\n return pose.views.map(view => {\n const viewport = glLayer.getViewport(view)!;\n const vMatrix = view.transform.inverse.matrix;\n\n return {\n viewport,\n vMatrix,\n pMatrix: view.projectionMatrix\n };\n });\n }\n\n private _setSession(session: XRSession, refSpace: XRReferenceSpace) {\n this._xrSession = session;\n this._xrRefSpace = refSpace;\n\n session.addEventListener(BROWSER.EVENTS.XR_END, this._onSessionEnd);\n }\n\n private _onSessionEnd = () => {\n this.exit();\n this.trigger(EVENTS.VR_END);\n }\n}\n\nexport default XRManager;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { vec3 } from \"gl-matrix\";\n\n/**\n * Hotspot data\n * @ko 핫스팟 데이터\n * @since 4.0.0\n */\nclass Hotspot {\n /**\n * HTMLElement of the hotspot\n * @ko 핫스팟의 HTMLElement\n * @since 4.0.0\n */\n public readonly element: HTMLElement;\n /**\n * Position to render hotspot\n * @ko 핫스팟을 렌더링할 위치\n * @since 4.0.0\n */\n public readonly position: vec3;\n\n public constructor(element: HTMLElement, position: vec3) {\n this.element = element;\n this.position = position;\n }\n}\n\nexport default Hotspot;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { vec2, vec3 } from \"gl-matrix\";\nimport Hotspot from \"./Hotspot\";\nimport Camera from \"../core/Camera\";\nimport WebGLRenderer from \"../core/WebGLRenderer\";\nimport View360Error from \"../core/View360Error\";\nimport { getNullableElement } from \"../utils\";\nimport ERROR from \"../const/error\";\nimport { DEFAULT_CLASS } from \"../const/external\";\nimport { DEG_TO_RAD } from \"../const/internal\";\n\n/**\n * Options for {@link HotspotRenderer}\n * @ko {@link HotspotRenderer}용 옵션들\n * @since 4.0.0\n */\nexport interface HotspotOptions {\n /**\n * Apply scale for hotspots, makes their size sync with background panorama image.\n * @ko 핫스팟에 스케일을 적용해서 배경 파노라마 이미지의 크기 변화와 동일하게 크기를 조절합니다.\n * @since 4.0.0\n */\n zoom: boolean;\n}\n\n/**\n * Hotspot renderer\n * @ko Hotspot 렌더러\n * @since 4.0.0\n */\nclass HotspotRenderer {\n // Options\n private _zoom: HotspotOptions[\"zoom\"];\n\n // Internal properties\n private _containerEl: HTMLElement | null;\n private _renderer: WebGLRenderer;\n private _hotspots: Hotspot[];\n\n /**\n * Create new instance\n * @ko 새 인스턴스를 생성합니다.\n * @param rootEl - Container element for hotspots {@ko 핫스팟들의 컨테이너 엘리먼트}\n * @param renderer - instance of WebGLRenderer {@ko WebGLRenderer의 인스턴스}\n * @param options - Hotspot options {@ko Hotspot 옵션들 }\n */\n public constructor(rootEl: HTMLElement, renderer: WebGLRenderer, {\n zoom = false\n }: Partial) {\n this._containerEl = getNullableElement(`.${DEFAULT_CLASS.HOTSPOT_CONTAINER}`, rootEl);\n this._renderer = renderer;\n this._hotspots = [];\n\n this._zoom = zoom;\n }\n\n /**\n * Refresh hotspots by collecting hotspot elements from current hotspot root element\n * @ko 현재 핫스팟 루트 엘리먼트 내에서 핫스팟 엘리먼트들을 수집하여 갱신합니다.\n * @throws {ERROR_CODES.INSUFFICIENT_ARGS} if data-position doesn't include all x, y, z values {@ko data-position이 x, y, z좌표를 전부 포함하고 있지 않을 때}\n */\n public refresh() {\n const container = this._containerEl;\n if (!container) return;\n\n const hotspotEls = [].slice.apply(container.querySelectorAll(`.${DEFAULT_CLASS.HOTSPOT}`)) as HTMLElement[];\n this._hotspots = hotspotEls.map(el => this._parseHotspot(el));\n }\n\n /**\n * Render hotspots\n * @ko 핫스팟들을 렌더링합니다.\n * @param camera - Instance of Camera {@ko Camera의 인스턴스}\n */\n public render(camera: Camera) {\n const hotspots = this._hotspots;\n const halfWidth = this._renderer.width * 0.5;\n const halfHeight = this._renderer.height * 0.5;\n const zoom = camera.zoom;\n const centerTransform = \"translate(-50%, -50%)\";\n const zoomTransform = this._zoom ? `scale(${zoom})` : \"\";\n\n hotspots.forEach(hotspot => {\n const position = hotspot.position;\n const relPos = vec3.create();\n\n vec3.copy(relPos, position);\n vec3.transformMat4(relPos, relPos, camera.viewMatrix);\n vec3.transformMat4(relPos, relPos, camera.projectionMatrix);\n\n if (relPos[2] > 1 || relPos[2] < 0) {\n hotspot.element.classList.remove(DEFAULT_CLASS.HOTSPOT_VISIBLE);\n return;\n }\n\n const screenPos = vec2.fromValues(\n relPos[0] * halfWidth + halfWidth,\n -relPos[1] * halfHeight + halfHeight\n );\n\n hotspot.element.classList.add(DEFAULT_CLASS.HOTSPOT_VISIBLE);\n hotspot.element.style.transform = [\n centerTransform,\n `translate(${screenPos[0]}px, ${screenPos[1]}px)`,\n zoomTransform\n ].join(\" \");\n });\n }\n\n private _parseHotspot(element: HTMLElement): Hotspot {\n const yawStr = element.dataset.yaw;\n const pitchStr = element.dataset.pitch;\n const positionStr = element.dataset.position;\n\n if (yawStr || pitchStr) {\n const yaw = yawStr ? parseFloat(yawStr) : 0;\n const pitch = pitchStr ? parseFloat(pitchStr) : 0;\n\n const position = this._yawPitchToVec3(yaw, pitch);\n\n return new Hotspot(element, position);\n } else if (positionStr) {\n const pos: number[] = positionStr.split(\" \").map(val => parseFloat(val));\n if (pos.length < 3) {\n throw new View360Error(ERROR.MESSAGES.INSUFFICIENT_ARGS(positionStr, \"hotspot attribute \\\"data-position\\\"\"), ERROR.CODES.INSUFFICIENT_ARGS);\n }\n\n return new Hotspot(element, vec3.fromValues(pos[0], pos[1], pos[2]));\n } else {\n // Place hotspot at yaw: 0, pitch: 0\n const defaultPos = vec3.fromValues(0, 0, -1);\n\n return new Hotspot(element, defaultPos);\n }\n }\n\n private _yawPitchToVec3(yaw: number, pitch: number) {\n const yawRad = yaw * DEG_TO_RAD;\n const pitchRad = pitch * DEG_TO_RAD;\n const position = vec3.create();\n\n position[1] = Math.sin(pitchRad);\n position[2] = Math.cos(pitchRad);\n\n position[0] = position[2] * Math.sin(-yawRad);\n position[2] = -position[2] * Math.cos(-yawRad);\n\n return position;\n }\n}\n\nexport default HotspotRenderer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"../geometry/Geometry\";\nimport { VAO } from \"../type/internal\";\n\n/**\n * @hidden\n */\nclass VertexArrayObject {\n public readonly obj: VAO | null;\n public readonly geometry: Geometry;\n public readonly buffers: {\n indicies: WebGLBuffer;\n position: WebGLBuffer;\n uv: WebGLBuffer;\n }\n\n public get count() { return this.geometry.indicies.count; }\n\n constructor(obj: VAO | null, geometry: Geometry, buffers: VertexArrayObject[\"buffers\"]) {\n this.obj = obj;\n this.geometry = geometry;\n this.buffers = buffers;\n }\n}\n\nexport default VertexArrayObject;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4 } from \"gl-matrix\";\nimport Uniform from \"../uniform/Uniform\";\nimport Camera from \"./Camera\";\nimport Object3D from \"./Object3D\";\nimport ShaderProgram from \"./ShaderProgram\";\nimport View360Error from \"./View360Error\";\nimport VertexArrayObject from \"./VertexArrayObject\";\nimport VertexData from \"./VertexData\";\nimport Texture from \"../texture/Texture\";\nimport Geometry from \"../geometry/Geometry\";\nimport * as BROWSER from \"../const/browser\";\nimport ERROR from \"../const/error\";\nimport { DEFAULT_CLASS } from \"../const/external\";\nimport { UniformLocations } from \"../type/internal\";\n\n/**\n * @hidden\n */\nclass WebGLContext {\n private _canvas: HTMLCanvasElement;\n private _gl: WebGLRenderingContext | WebGL2RenderingContext;\n private _contextLost: boolean;\n private _maxTextureSize: number;\n private _isWebGL2: boolean;\n private _debug: boolean;\n private _extensions: {\n vao: OES_vertex_array_object | null;\n loseContext: WEBGL_lose_context | null;\n };\n\n public get canvas() { return this._canvas; }\n public get maxTextureSize() { return this._maxTextureSize; }\n public get isWebGL2() { return this._isWebGL2; }\n public get supportVAO() { return this._isWebGL2 || !!this._extensions.vao; }\n public get lost() { return this._contextLost; }\n public get debug() { return this._debug; }\n\n public constructor(canvas: HTMLCanvasElement, debug: boolean) {\n this._canvas = canvas;\n this._contextLost = false;\n this._debug = debug;\n this._extensions = {\n vao: null,\n loseContext: null\n };\n }\n\n public init() {\n const canvas = this._canvas;\n\n const { gl, isWebGL2 } = this._getContext(canvas);\n\n this._gl = gl;\n this._maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n this._isWebGL2 = isWebGL2;\n\n if (!this._isWebGL2) {\n this._extensions.vao = gl.getExtension(\"OES_vertex_array_object\");\n }\n\n this._extensions.loseContext = gl.getExtension(\"WEBGL_lose_context\");\n\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_LOST, this._onContextLost);\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_RESTORED, this._onContextRestore);\n\n // gl.enable(gl.DEPTH_TEST);\n }\n\n public destroy() {\n const gl = this._gl;\n const canvas = this._canvas;\n\n if (gl) {\n // gl is not defined when destroy is called before init\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n }\n\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_LOST, this._onContextLost);\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_RESTORED, this._onContextRestore);\n }\n\n public forceLoseContext() {\n const extension = this._extensions.loseContext;\n\n if (!extension) return;\n\n extension.loseContext();\n }\n\n public forceRestoreContext() {\n const extension = this._extensions.loseContext;\n\n if (!extension) return;\n\n extension.restoreContext();\n }\n\n public clear() {\n const gl = this._gl;\n\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n\n public resize() {\n const gl = this._gl;\n\n gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n }\n\n public viewport(x: number, y: number, width: number, height: number) {\n const gl = this._gl;\n\n gl.viewport(x, y, width, height);\n }\n\n public createVAO(geometry: Geometry, shaderProgram: ShaderProgram) {\n const nativeVAO = this._createNativeVAO();\n\n const vao = new VertexArrayObject(nativeVAO, geometry, {\n indicies: this._createBuffer(),\n position: this._createBuffer(),\n uv: this._createBuffer()\n });\n\n if (nativeVAO) {\n this._bindNativeVAO(nativeVAO);\n this._supplyGeometryData(vao, shaderProgram);\n this._bindNativeVAO(null);\n this._unbindBuffers();\n }\n\n return vao;\n }\n\n public draw(vao: VertexArrayObject, shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n if (vao.obj) {\n this._bindNativeVAO(vao.obj);\n } else {\n this._supplyGeometryData(vao, shaderProgram);\n }\n\n gl.drawElements(gl.TRIANGLES, vao.count, gl.UNSIGNED_SHORT, 0);\n\n if (vao.obj) {\n this._bindNativeVAO(null);\n } else {\n this._unbindBuffers();\n }\n }\n\n public releaseVAO(vao: VertexArrayObject) {\n if (vao.obj) {\n this._deleteNativeVAO(vao.obj);\n }\n\n this._deleteBuffer(vao.buffers.indicies);\n this._deleteBuffer(vao.buffers.position);\n this._deleteBuffer(vao.buffers.uv);\n }\n\n public getUniformLocations>(program: WebGLProgram, uniforms: T): UniformLocations {\n const gl = this._gl;\n\n const uniformLocations = Object.keys(uniforms).reduce((locations, key) => {\n locations[key as keyof T] = gl.getUniformLocation(program, key)!;\n\n return locations;\n }, {} as UniformLocations);\n\n return {\n ...this._getCommonUniformLocations(program),\n ...uniformLocations\n };\n }\n\n public updateCommonUniforms(entity: Object3D, camera: Camera, shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniformLocations = shaderProgram.uniformLocations;\n\n // We're using \"matrix\"(=local matrix) here for efficiency\n // As projection doesn't require world matrix, as it doesn't have any parent or child\n const matrix = entity.matrix;\n const mvMatrix = mat4.create();\n mat4.multiply(mvMatrix, camera.viewMatrix, matrix);\n\n gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix);\n gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, camera.projectionMatrix);\n }\n\n public updateVRUniforms(shaderProgram: ShaderProgram, mvMatrix: mat4, pMatrix: mat4, eyeIndex: number) {\n const gl = this._gl;\n\n const uniformLocations = shaderProgram.uniformLocations;\n\n gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix);\n gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, pMatrix);\n\n if (uniformLocations.uEye) {\n gl.uniform1f(uniformLocations.uEye, eyeIndex);\n }\n }\n\n public updateUniforms(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniforms = shaderProgram.uniforms;\n const uniformLocations = shaderProgram.uniformLocations;\n\n for (const key in uniforms) {\n const uniform = uniforms[key];\n const location = uniformLocations[key];\n\n if (!uniform) continue;\n\n if (uniform.needsUpdate) {\n uniform.update(gl, location, this._isWebGL2);\n }\n }\n }\n\n public releaseShaderResources(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniforms = shaderProgram.uniforms;\n\n for (const key in uniforms) {\n const uniform = uniforms[key];\n\n if (!uniform) continue;\n\n if (uniform.needsUpdate) {\n uniform.destroy(gl);\n }\n }\n\n gl.deleteProgram(shaderProgram.program);\n }\n\n public useProgram(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n gl.useProgram(shaderProgram.program);\n }\n\n public createProgram(vertexShader: string, fragmentShader: string) {\n const gl = this._gl;\n const program = gl.createProgram()!;\n\n const vs = this._compileShader(gl.VERTEX_SHADER, vertexShader);\n const fs = this._compileShader(gl.FRAGMENT_SHADER, fragmentShader);\n\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.bindAttribLocation(program, 0, \"position\");\n gl.bindAttribLocation(program, 1, \"uv\");\n gl.linkProgram(program);\n\n if (this._debug && !gl.getProgramParameter(program, gl.LINK_STATUS)) {\n let shaderLog: string | null = null;\n\n if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {\n shaderLog = gl.getShaderInfoLog(vs);\n } else if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {\n shaderLog = gl.getShaderInfoLog(fs);\n }\n\n throw new View360Error(ERROR.MESSAGES.FAILED_LINKING_PROGRAM(gl.getProgramInfoLog(program), shaderLog), ERROR.CODES.FAILED_LINKING_PROGRAM);\n }\n\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n\n return program;\n }\n\n public createWebGLTexture(texData: Texture): WebGLTexture {\n const gl = this._gl;\n const texture = gl.createTexture()!;\n\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texData.wrapS);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texData.wrapT);\n\n if (!texData.isVideo() && this._isWebGL2) {\n const gl2 = gl as WebGL2RenderingContext;\n\n gl2.texStorage2D(gl2.TEXTURE_2D, 1, gl2.RGBA8, texData.width, texData.height);\n }\n\n return texture;\n }\n\n public createWebGLCubeTexture(texData: Texture, size: number): WebGLTexture {\n const gl = this._gl;\n const texture = gl.createTexture()!;\n\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, texData.wrapS);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, texData.wrapT);\n\n if (this._isWebGL2) {\n const gl2 = gl as WebGL2RenderingContext;\n\n gl2.texStorage2D(gl2.TEXTURE_CUBE_MAP, 1, gl2.RGBA8, size, size);\n }\n\n return texture;\n }\n\n public async makeXRCompatible() {\n const gl = this._gl;\n const attributes = gl.getContextAttributes();\n\n if (attributes && attributes.xrCompatible !== true) {\n await gl.makeXRCompatible();\n }\n }\n\n public bindXRLayer(session: XRSession) {\n const gl = this._gl;\n const xrLayer = new XRWebGLLayer(session, gl);\n session.updateRenderState({ baseLayer: xrLayer });\n }\n\n public bindXRFrame(frame: XRFrame) {\n const gl = this._gl;\n const session = frame.session;\n const baseLayer = session.renderState.baseLayer!;\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer);\n }\n\n public useDefaultFrameBuffer() {\n const gl = this._gl;\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n private _createBuffer(): WebGLBuffer {\n return this._gl.createBuffer()!;\n }\n\n private _deleteBuffer(buffer: WebGLBuffer) {\n return this._gl.deleteBuffer(buffer);\n }\n\n private _createNativeVAO() {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n return (gl as WebGL2RenderingContext).createVertexArray()!;\n } else {\n const ext = this._extensions.vao;\n\n return ext?.createVertexArrayOES() || null;\n }\n }\n\n private _bindNativeVAO(vao: WebGLVertexArrayObject | null) {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n (gl as WebGL2RenderingContext).bindVertexArray(vao);\n } else {\n const ext = this._extensions.vao;\n\n ext?.bindVertexArrayOES(vao);\n }\n }\n\n private _deleteNativeVAO(vao: WebGLVertexArrayObject | null) {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n (gl as WebGL2RenderingContext).deleteVertexArray(vao);\n } else {\n const ext = this._extensions.vao;\n\n ext?.deleteVertexArrayOES(vao);\n }\n }\n\n private _supplyGeometryData(vao: VertexArrayObject, shaderProgram: ShaderProgram) {\n const geometry = vao.geometry;\n\n this._supplyIndiciesData(geometry.indicies, vao.buffers.indicies);\n this._supplyAttributeData(geometry.vertices, shaderProgram.program, \"position\", vao.buffers.position);\n this._supplyAttributeData(geometry.uvs, shaderProgram.program, \"uv\", vao.buffers.uv);\n }\n\n private _unbindBuffers() {\n const gl = this._gl;\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n }\n\n private _supplyIndiciesData(indicies: VertexData, buffer: WebGLBuffer) {\n const gl = this._gl;\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicies.data, gl.STATIC_DRAW);\n }\n\n private _supplyAttributeData(attribute: VertexData, program: WebGLProgram, name: string, buffer: WebGLBuffer) {\n const gl = this._gl;\n const attribLocation = gl.getAttribLocation(program, name);\n\n // Attribute not used\n if (attribLocation < 0) return;\n\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ARRAY_BUFFER, attribute.data, gl.STATIC_DRAW);\n gl.vertexAttribPointer(attribLocation, attribute.itemSize, gl.FLOAT, false, 0, 0);\n gl.enableVertexAttribArray(attribLocation);\n }\n\n private _compileShader(type: number, src: string) {\n const gl = this._gl;\n const shader = gl.createShader(type)!;\n\n gl.shaderSource(shader, src);\n gl.compileShader(shader);\n\n return shader;\n }\n\n private _getCommonUniformLocations(program: WebGLProgram) {\n const gl = this._gl;\n\n return {\n uMVMatrix: gl.getUniformLocation(program, \"uMVMatrix\")!,\n uPMatrix: gl.getUniformLocation(program, \"uPMatrix\")!\n };\n }\n\n private _getContext(canvas: HTMLCanvasElement): {\n gl: WebGLRenderingContext | WebGL2RenderingContext;\n isWebGL2: boolean;\n } {\n const webglIdentifiers = [\"webgl2\", \"webgl\", \"experimental-webgl\", \"webkit-3d\", \"moz-webgl\"];\n let context: WebGLRenderingContext | null = null;\n let isWebGL2 = false;\n const contextAttributes = {\n preserveDrawingBuffer: false,\n antialias: false\n };\n\n const onWebglContextCreationError = e => e.statusMessage;\n\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_CREATE_ERROR, onWebglContextCreationError);\n\n for (const identifier of webglIdentifiers) {\n try {\n context = canvas.getContext(identifier, contextAttributes) as WebGLRenderingContext;\n isWebGL2 = identifier === \"webgl2\";\n } catch (t) {} // eslint-disable-line no-empty\n if (context) {\n break;\n }\n }\n\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_CREATE_ERROR, onWebglContextCreationError);\n\n if (!context) {\n throw new View360Error(ERROR.MESSAGES.WEBGL_NOT_SUPPORTED, ERROR.CODES.WEBGL_NOT_SUPPORTED);\n }\n\n return {\n gl: context,\n isWebGL2\n };\n }\n\n private _onContextLost = () => {\n const canvas = this._canvas;\n canvas.classList.add(DEFAULT_CLASS.CTX_LOST);\n this._contextLost = true;\n };\n\n private _onContextRestore = () => {\n const canvas = this._canvas;\n canvas.classList.remove(DEFAULT_CLASS.CTX_LOST);\n this._contextLost = false;\n };\n}\n\nexport default WebGLContext;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4 } from \"gl-matrix\";\nimport Camera from \"./Camera\";\nimport Projection from \"../projection/Projection\";\nimport WebGLContext from \"./WebGLContext\";\nimport XRManager from \"./XRManager\";\n\n/**\n * Projection renderer, based on WebGL\n * @ko WebGL 기반의 프로젝션 렌더러\n * @since 4.0.0\n */\nclass WebGLRenderer {\n private _canvas: HTMLCanvasElement;\n private _elementSize: { x: number, y: number };\n private _pixelRatio: number;\n\n public readonly ctx: WebGLContext;\n\n /**\n * Canvas element\n * @ko 캔버스 엘리먼트\n * @since 4.0.0\n */\n public get canvas() { return this._canvas; }\n /**\n * Canvas's width (`devicePixelRatio` is not applied)\n * @ko 캔버스의 보이는 너비 (`devicePixelRatio`가 적용되지 않은)\n * @since 4.0.0\n */\n public get width() { return this._elementSize.x; }\n /**\n * Canvas's height (`devicePixelRatio` is not applied)\n * @ko 캔버스의 높이 (`devicePixelRatio`가 적용되지 않은)\n * @since 4.0.0\n */\n public get height() { return this._elementSize.y; }\n /**\n * Current `devicePixelRatio` value.\n * @ko 현재 `devicePixelRatio` 값.\n * @since 4.0.0\n * @example\n * ```js\n * cosnt renderingWidth = view360.renderer.width * view360.renderer.pixelRatio;\n * ```\n */\n public get pixelRatio() { return this._pixelRatio; }\n /**\n * Width / height ratio (= width / height)\n * @ko 너비 / 높이의 비율 (= width / height)\n * @since 4.0.0\n * @example\n * ```js\n * const aspect = view360.renderer.width / view360.renderer.pixelRatio;\n * assert(aspect === view360.renderer.aspect);\n * ```\n */\n public get aspect() { return this._elementSize.x / this._elementSize.y; }\n\n /**\n * Create new instance\n * @ko 새 인스턴스를 생성합니다.\n * @param canvas - Canvas element {@ko 캔버스 엘리먼트}\n * @param debug - Whether to enable WebGL debugging {@ko WebGL debug 활성화 여부 }\n */\n public constructor(canvas: HTMLCanvasElement, debug: boolean) {\n this._canvas = canvas;\n this._elementSize = { x: 0, y: 0 };\n this._pixelRatio = 1;\n this.ctx = new WebGLContext(canvas, debug);\n }\n\n /**\n * Destroy instance and release all resources.\n * @ko 인스턴스를 제거하고 사용된 리소스를 전부 해제합니다.\n * @since 4.0.0\n */\n public destroy() {\n const canvas = this._canvas;\n\n this.ctx.destroy();\n canvas.width = 1;\n canvas.height = 1;\n }\n\n /**\n * Resize canvas and renew inner size cache.\n * @ko 캔버스의 크기를 재계산해서 내부의 사이즈 캐시값을 갱신합니다.\n * @since 4.0.0\n */\n public resize() {\n const canvas = this._canvas;\n const canvasSize = this._elementSize;\n const devicePixelRatio = window.devicePixelRatio;\n\n canvasSize.x = canvas.clientWidth;\n canvasSize.y = canvas.clientHeight;\n\n canvas.width = canvasSize.x * devicePixelRatio;\n canvas.height = canvasSize.y * devicePixelRatio;\n\n this._pixelRatio = devicePixelRatio;\n this.ctx.resize();\n }\n\n /**\n * Render projection\n * @ko 프로젝션을 렌더링합니다.\n * @param projection - Projection to render {@ko 렌더링할 프로젝션}\n * @param cameraa - Camera instance {@ko 카메라의 인스턴스}\n * @since 4.0.0\n */\n public render(projection: Projection, camera: Camera) {\n const ctx = this.ctx;\n const mesh = projection.getMesh();\n if (ctx.lost || !mesh) return;\n\n ctx.clear();\n ctx.useProgram(mesh.program);\n ctx.updateCommonUniforms(mesh, camera, mesh.program);\n projection.update(camera);\n ctx.updateUniforms(mesh.program);\n ctx.draw(mesh.vao, mesh.program);\n }\n\n /**\n * Render VR frame, only used for rendering frames inside VR sessions.\n * @ko VR 프레임을 렌더링합니다. VR 세션 진입 도중에만 사용됩니다.\n * @internal\n * @param projection - Projection to render {@ko 렌더링할 프로젝션}\n * @param vr - Instance of XRManager {@ko XRManager의 인스턴스}\n * @param frame - VR frame {@ko VR 프레임}\n * @since 4.0.0\n */\n public renderVR(projection: Projection, vr: XRManager, frame: XRFrame) {\n const ctx = this.ctx;\n const mesh = projection.getMesh();\n const eyeParams = vr.getEyeParams(frame);\n\n if (!eyeParams || !mesh) return;\n\n ctx.bindXRFrame(frame);\n ctx.useProgram(mesh.program);\n ctx.updateUniforms(mesh.program);\n\n eyeParams.forEach((eye, eyeIndex) => {\n const viewport = eye.viewport;\n // We're using \"mesh.matrix\"(=local matrix) here for efficiency\n // As projection doesn't require world matrix, as it doesn't have any parent or child\n const mvMatrix = mat4.multiply(mat4.create(), eye.vMatrix, mesh.matrix);\n\n ctx.viewport(viewport.x, viewport.y, viewport.width, viewport.height);\n ctx.updateVRUniforms(mesh.program, mvMatrix, eye.pMatrix, eyeIndex);\n ctx.draw(mesh.vao, mesh.program);\n });\n }\n}\n\nexport default WebGLRenderer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport Camera, { CameraOptions } from \"./core/Camera\";\nimport PanoControl, { PanoControlOptions } from \"./control/PanoControl\";\nimport TextureLoader from \"./core/TextureLoader\";\nimport FrameAnimator from \"./core/FrameAnimator\";\nimport AutoResizer from \"./core/AutoResizer\";\nimport Autoplay, { AutoplayOptions } from \"./core/Autoplay\";\nimport XRManager from \"./core/XRManager\";\nimport View360Error from \"./core/View360Error\";\nimport Projection from \"./projection/Projection\";\nimport HotspotRenderer, { HotspotOptions } from \"./hotspot/HotspotRenderer\";\nimport WebGLRenderer from \"./core/WebGLRenderer\";\nimport Texture from \"./texture/Texture\";\nimport View360Plugin from \"./plugin/View360Plugin\";\nimport ERROR from \"./const/error\";\nimport { CONTROL_EVENTS } from \"./const/internal\";\nimport { DEFAULT_CLASS, EVENTS } from \"./const/external\";\nimport { findCanvas, getElement } from \"./utils\";\nimport * as EVENT_TYPES from \"./type/events\";\nimport { EventParams } from \"./type/utils\";\n\n/**\n * Events that {@link View360} can trigger\n * @ko {@link View360}가 트리거할 수 있는 이벤트들\n * @see [Detailed Example](/docs/events/ready)\n * @since 4.0.0\n */\nexport interface View360Events {\n [EVENTS.READY]: EVENT_TYPES.ReadyEvent;\n [EVENTS.LOAD_START]: EVENT_TYPES.LoadStartEvent;\n [EVENTS.LOAD]: EVENT_TYPES.LoadEvent;\n [EVENTS.PROJECTION_CHANGE]: EVENT_TYPES.ProjectionChangeEvent;\n [EVENTS.RESIZE]: EVENT_TYPES.ResizeEvent;\n [EVENTS.BEFORE_RENDER]: EVENT_TYPES.BeforeRenderEvent;\n [EVENTS.RENDER]: EVENT_TYPES.RenderEvent;\n [EVENTS.INPUT_START]: EVENT_TYPES.InputStartEvent;\n [EVENTS.INPUT_END]: EVENT_TYPES.InputEndEvent;\n [EVENTS.VIEW_CHANGE]: EVENT_TYPES.ViewChangeEvent;\n [EVENTS.STATIC_CLICK]: EVENT_TYPES.StaticClickEvent;\n [EVENTS.VR_START]: EVENT_TYPES.VRStartEvent;\n [EVENTS.VR_END]: EVENT_TYPES.VREndEvent;\n}\n\n/**\n * Options for {@link View360}\n * @ko {@link View360}용 옵션들\n * @see [Detailed Example](/docs/options)\n * @since 4.0.0\n */\nexport interface View360Options extends CameraOptions, PanoControlOptions {\n projection: Projection | null;\n hotspot: Partial;\n autoplay: boolean | Partial;\n autoInit: boolean;\n autoResize: boolean;\n canvasSelector: string;\n useResizeObserver: boolean;\n tabIndex: number | null;\n on: Partial<{ [key in keyof View360Events]: (evt: View360Events[key]) => any }>;\n plugins: View360Plugin[];\n maxDeltaTime: number;\n debug: boolean;\n}\n\n/**\n * Panorama 360 image viewer\n * @ko 파노라마 360 이미지 뷰어\n * @since 4.0.0\n * @see View360Options\n * @see View360Events\n */\nclass View360 extends Component {\n /**\n * Current version string of the View360\n * @ko View360의 현재 버젼 문자열\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // If the installed version of the View360 is v4.0.0, View360.VERSION is equal to \"4.0.0\"\n * console.log(View360.VERSION) // 4.0.0\n * ```\n */\n public static readonly VERSION = \"#__VERSION__#\";\n\n private _rootEl: HTMLElement;\n private _renderer: WebGLRenderer;\n private _camera: Camera;\n private _control: PanoControl;\n private _animator: FrameAnimator;\n private _autoplay: Autoplay;\n private _hotspot: HotspotRenderer;\n private _projection: Projection | null;\n private _autoResizer: AutoResizer;\n private _vr: XRManager;\n private _plugins: View360Plugin[];\n private _initialized: boolean;\n\n private _autoInit: View360Options[\"autoInit\"];\n private _autoResize: View360Options[\"autoResize\"];\n private _canvasSelector: View360Options[\"canvasSelector\"];\n private _useResizeObserver: View360Options[\"useResizeObserver\"];\n private _tabIndex: View360Options[\"tabIndex\"];\n private _debug: View360Options[\"debug\"];\n\n /**\n * Root element (`.view360-container`)\n * @ko 루트 엘리먼트 (`.view360-container`)\n * @since 4.0.0\n * @readonly\n * @example\n * ```html\n *
\n * \n *
\n * ```\n * ```ts\n * import View360 from \"@egjs/view360\";\n *\n * const viewer = new View360(\"#viewer\");\n * console.log(viewer.rootEl); // Element with id \"viewer\"\n * ```\n */\n public get rootEl() { return this._rootEl; }\n /**\n * Projection renderer.\n * @ko 프로젝션 렌더러.\n * @since 4.0.0\n * @readonly\n */\n public get renderer() { return this._renderer; }\n /**\n * Projection camera.\n * @ko 프로젝션 카메라.\n * @since 4.0.0\n * @readonly\n */\n public get camera() { return this._camera; }\n /**\n * Rotate/Zoom Controller.\n * @ko 회전/줌 컨트롤러.\n * @since 4.0.0\n * @readonly\n */\n public get control() { return this._control; }\n /**\n * WebXR-based VR manager.\n * @ko WebXR 기반의 VR 기능 매니저 인스턴스.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // Example: Enter VR\n * // This must be called on user interaction, else will be rejected.\n * viewer.vr.enter();\n * ```\n */\n public get vr() { return this._vr; }\n /**\n * Hotspot renderer.\n * You can also change options of {@link View360Options#hotspot} with this.\n * @ko 핫스팟 렌더러 인스턴스.\n * {@link View360Options#hotspot} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get hotspot() { return this._hotspot; }\n /**\n * An array of plugins added.\n * @ko 추가된 플러그인의 배열\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * plugins: [new ControlBar()]\n * });\n *\n * console.log(viewer.plugins); // [ControlBar]\n *\n * viewer.addPlugins(new LoadingSpinner()) // [ControlBar, LoadingSpinner];\n * ```\n */\n public get plugins() { return this._plugins; }\n /**\n * A instance of {@link Projection} that currently enabled. `null` if not initialized yet.\n * You should call {@link View360#load} to change panorama src or projection type.\n * @ko 현재 사용중인 {@link Projection}의 인스턴스. 프로젝션을 활성화하지 않았을 경우 `null`입니다.\n * 파노라마 이미지 소스나 프로젝션 타입을 변경하려면 {@link View360#load}를 호출하면 됩니다.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360\n * ```\n */\n public get projection() { return this._projection; }\n public set projection(val: View360Options[\"projection\"]) {\n if (this._initialized && val) {\n this.load(val);\n } else {\n this._projection = val;\n }\n }\n /**\n * A boolean value whether {@link View360#init init()} is called before.\n * @ko {@link View360#init init()}이 호출되었는지 여부를 가리키는 값\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360(\"#el\", { autoInit: false });\n *\n * console.log(viewer.initialized); // false\n *\n * await viewer.init();\n *\n * console.log(viewer.initialized); // true\n * ```\n */\n public get initialized() { return this._initialized; }\n /**\n * Instance of the Autoplay manager.\n * You can also change {@link View360Options#autoplay} options with this.\n * @ko Autoplay 기능의 매니저 인스턴스.\n * 이 인스턴스를 통해 {@link View360Options#autoplay} 옵션을 변경하는 것도 가능합니다.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // Disable autoplay\n * viewer.autoplay.disable();\n * ```\n */\n public get autoplay() { return this._autoplay; }\n /**\n * When this value is `true` and {@link View360Options#projection} is set, {@link View360#init init()} will be called automatically when instance is created.\n * @ko 이 값이 `true`이고, {@link View360Options#projection}이 설정되었으면, 인스턴스 생성 시점에 자동으로 {@link View360#init init()}을 호출합니다.\n * @default true\n * @since 4.0.0\n * @example\n * ```ts\n * import View360, { EquirectProjection, EVENTS } from \"@egjs/view360\";\n *\n * // viewer.init() is called on instance creation\n * // But as `init` is asynchronous, you should wait for \"ready\" event if you want to do something after initialization.\n * const viewer = new View360(\"#el_id\", {\n * autoInit: true,\n * projection: new EquirectProjection({ src: \"SRC_TO_URL\" })\n * });\n *\n * console.log(viewer.initialized); // false, as `init` is asynchronous\n *\n * viewer.once(EVENTS.READY, () => {\n * console.log(viewer.initialized); // true\n * });\n * ```\n */\n public get autoInit() { return this._autoInit; }\n /**\n * When `true`, {@link View360#resize} is called when the canvas size is changed.\n * @ko `true`일 경우, 캔버스의 크기가 변경되었을 때 자동으로 {@link View360#resize}를 호출합니다.\n * @default true\n * @since 4.0.0\n * @see View360#useResizeObserver\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * autoResize: true\n * });\n *\n * // This can trigger `viewer.resize()` if the canvas size was not 400px\n * const canvas = viewer.renderer.canvas;\n * canvas.style.width = \"400px\";\n * ```\n */\n public get autoResize() { return this._autoResize; }\n /**\n * CSS selector for canvas element to render panorama image/video.\n * The canvas element should be placed inside the root element. (Dont' have to be direct child)\n * @ko 파노라마 이미지/비디오를 렌더링할 canvas 엘리먼트의 CSS 선택자\n * 캔버스 엘리먼트는 루트 엘리먼트 내부에 있어야합니다. 루트 엘리먼트의 직계 자식 엘리먼트(Direct child element)일 필요는 없습니다.\n * @default \"canvas\"\n * @since 4.0.0\n * @example\n * ```html\n *
\n * \n * \n * \n *
\n * ```\n *\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * canvasSelector: \"#canvas_to_select\"\n * });\n * ```\n */\n public get canvasSelector() { return this._canvasSelector; }\n /**\n * When `true`, it will use {@link ResizeObserver} API to detect canvas size change when {@link View360Options#autoResize} is enabled.\n * @ko `true`일 때 {@link View360Options#autoResize}가 활성화되었으면, 사용 가능한 환경에서 {@link ResizeObserver} API를 사용해서 캔버스 크기 변화를 추적합니다.\n * @default true\n * @since 4.0.0\n */\n public get useResizeObserver() { return this._useResizeObserver; }\n /**\n * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} attribute for the canvas element.\n * This is necessary for the keyboard controls.\n * By default, `0` will be assigned. `null` to disable.\n * @ko 캔버스 엘리먼트에 적용할 {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} 어트리뷰트의 값.\n * 이 값을 설정해야만 키보드 컨트롤을 사용 가능합니다.\n * 기본값으로 `0`이 설정됩니다. `null`로 지정하면 `tabindex`를 설정하지 않습니다.\n * @see RotateControlOptions#disableKeyboard\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * tabindex: 5\n * });\n * ```\n *\n * ```html\n * \n *
\n * \n *
\n * ```\n */\n public get tabIndex() { return this._tabIndex; }\n public set tabIndex(val: View360Options[\"tabIndex\"]) {\n const canvas = this._renderer.canvas;\n this._tabIndex = val;\n\n if (val != null) {\n canvas.tabIndex = val;\n } else {\n canvas.removeAttribute(\"tabindex\");\n }\n }\n /**\n * A maximum delta time between frames in seconds.\n * It can prevent camera or control changing too fast when frame being late.\n * @ko 프레임간 시간 차이의 최대값. (초 단위)\n * 퍼포먼스 등의 이유로 프레임 렌더링이 늦어졌을 때, 화면이 갑작스럽게 바뀌는 것을 막아줍니다.\n * @default 1 / 30\n * @since 4.0.0\n */\n public get maxDeltaTime() { return this._animator.maxDeltaTime; }\n public set maxDeltaTime(val: View360Options[\"maxDeltaTime\"]) { this._animator.maxDeltaTime = val; }\n /**\n * Enable WebGL debugging. Setting this to `true` can decrease performance.\n * This is used internally on developing View360.\n * @ko WebGL 디버깅을 활성화합니다. 이 값을 `true`로 할 경우 성능이 하락할 수 있습니다.\n * 이 옵션은 View360을 개발하기 위해 내부적으로 사용됩니다.\n * @default false\n */\n public get debug() { return this._debug; }\n public set debug(val: View360Options[\"debug\"]) { this._debug = val; }\n\n // Camera options\n /**\n * Initial yaw (y-axis rotation) value for camera. (in degrees, °)\n * As View360 uses right-handed coordinate system internally, camera will rotate counter-clockwise by this value.\n * @ko 카메라의 초기 yaw(y축 회전)값 (도 단위, °)\n * View360은 오른손 좌표계를 사용하기 때문에, 카메라가 해당 값만큼 시계 반대방향으로 회전합니다.\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialYaw: 30\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.yaw); // 30\n * });\n * ```\n */\n public get initialYaw() { return this._camera.initialYaw; }\n public set initialYaw(val: View360Options[\"initialYaw\"]) { this._camera.initialYaw = val; }\n /**\n * Initial pitch (x-axis rotation) value for camera. (in degrees, °)\n * As View360 uses right-handed coordinate system internally, positive value will make camera to look upside, while negative value will look down.\n * @ko 카메라의 초기 pitch(x축 회전)값 (도 단위, °)\n * View360은 오른손 좌표계를 사용하기 때문에, 양(+)의 값은 카메라가 위를 보게 하고, 음(-)의 값은 카메라가 아래를 보게 합니다.\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialPitch: 60\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.pitch); // 60\n * });\n * ```\n */\n public get initialPitch() { return this._camera.initialPitch; }\n public set initialPitch(val: View360Options[\"initialPitch\"]) { this._camera.initialPitch = val; }\n /**\n * Initial zoom value for camera.\n * Setting this value to `2` will enlarge panorama 200% by width.\n * @ko 카메라의 초기 줌 값.\n * 이 값을 `2`로 설정할 경우 파노라마 이미지를 가로 기준 200%만큼 확대합니다.\n * @default 1\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialZoom: 2\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.zoom); // 2\n * });\n * ```\n */\n public get initialZoom() { return this._camera.initialZoom; }\n public set initialZoom(val: View360Options[\"initialZoom\"]) { this._camera.initialZoom = val; }\n /**\n * Restrict yaw(y-axis rotation) range. (in degrees, °)\n * @ko yaw(y축 회전) 범위를 제한합니다. (도 단위, °)\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * yawRange: [-30, 30]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.yaw); // 0\n * viewer.camera.lookAt({ yaw: 60 });\n * console.log(viewer.camera.yaw); // 30\n * });\n * ```\n */\n public get yawRange() { return this._camera.yawRange; }\n public set yawRange(val: View360Options[\"yawRange\"]) {\n this._camera.yawRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Restrict pitch(x-axis rotation) range. (in degrees, °)\n * @ko pitch(x축 회전) 범위를 제한합니다. (도 단위, °)\n * @default null\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * pitchRange: [-45, 45]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.pitch); // 0\n * viewer.camera.lookAt({ pitch: 60 });\n * console.log(viewer.camera.pitch); // 45\n * });\n * ```\n */\n public get pitchRange() { return this._camera.pitchRange; }\n public set pitchRange(val: View360Options[\"pitchRange\"]) {\n this._camera.pitchRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Restrict camera zoom range.\n * If `null`, a default zoom range from `0.6` to `10` will be used.\n * @ko 카메라 줌 범위를 제한합니다.\n * `null`일 경우 기본값으로 `0.6`에서 `10`의 범위를 사용합니다.\n * @default null\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * zoomRange: [0.5, 4]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.zoom); // 1\n * viewer.camera.lookAt({ zoom: 6 });\n * console.log(viewer.camera.zoom); // 4\n * });\n * ```\n */\n public get zoomRange() { return this._camera.zoomRange; }\n public set zoomRange(val: View360Options[\"zoomRange\"]) {\n this._camera.zoomRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Camera's horizontal FOV(Field of View). (in degrees, °)\n * @ko 카메라의 수평 FOV(Field of View) 값. (도 단위, °)\n * @default 90\n * @since 4.0.0\n * @example\n * ```ts\n * // Init with fov: 120\n * const viewer = new View360(\"#el_id\", { fov: 120 });\n *\n * // Back to 90\n * viewer.fov = 90;\n * ```\n */\n public get fov() { return this._camera.fov; }\n public set fov(val: View360Options[\"fov\"]) {\n const camera = this._camera;\n const control = this._control;\n\n camera.fov = val;\n camera.updateMatrix();\n control.sync();\n }\n\n // Control options\n /**\n * A control for camera rotation.\n * You can also change options of {@link View360Options#rotate} with this.\n * @ko 카메라 회전을 담당하는 컨트롤.\n * {@link View360Options#rotate} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get rotate() { return this._control.rotate; }\n /**\n * A control for camera zoom.\n * You can also change options of {@link View360Options#zoom} with this.\n * @ko 카메라 줌을 담당하는 컨트롤.\n * {@link View360Options#zoom} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get zoom() { return this._control.zoom; }\n /**\n * A control for camera rotation with gyroscope input.\n * You can also change options of {@link View360Options#gyro} with this.\n * @ko 자이로스코프를 통한 카메라 회전을 담당하는 컨트롤.\n * {@link View360Options#gyro} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get gyro() { return this._control.gyro; }\n /**\n * Apply CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor} by current state of input when using mouse.\n * If `true`, this will add CSS style to canvas element. It'll apply `cursor: \"grab\"` by default and `cursor: \"grabbing\"` when holding the mouse button.\n * @ko 마우스 사용시 CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor}값을 자동으로 변경할지 여부.\n * `true`일 경우 기본 상태에서 `cursor: \"grab\"`을, 입력 도중에 `cursor: \"grabbing\"`을 캔버스에 적용합니다.\n * @default true\n * @since 4.0.0\n */\n public get useGrabCursor() { return this._control.useGrabCursor; }\n public set useGrabCursor(val: View360Options[\"useGrabCursor\"]) { this._control.useGrabCursor = val; }\n /**\n * Disable context menu which pops up on mouse right click.\n * @ko 마우스 우클릭시 표시되는 컨텍스트 메뉴를 비활성화합니다.\n * @default false\n * @since 4.0.0\n */\n public get disableContextMenu() { return this._control.disableContextMenu; }\n public set disableContextMenu(val: View360Options[\"disableContextMenu\"]) { this._control.disableContextMenu = val; }\n /**\n * If `true`, enables scroll on mobile(touch) devices on canvas.\n * :::caution\n * When this option is enabled, users must swipe horizontally first then vertically to change view up or down.\n * :::\n * @ko `true`로 설정할 경우, 모바일(터치) 환경의 캔버스 영역 내에서 스크롤을 가능하게 합니다.\n * :::caution\n * 이 값을 활성화할 경우, 사용자가 카메라 뷰를 위/아래로 바꾸기 위해서는 먼저 가로로 스와이프한 이후에 세로로 스와이프해야만 합니다.\n * :::\n * @since 4.0.0\n * @default true\n */\n public get scrollable() { return this._control.scrollable; }\n public set scrollable(val: View360Options[\"scrollable\"]) { this._control.scrollable = val; }\n /**\n * If `true`, enables scroll by mouse wheel on canvas.\n * :::caution\n * When this option is enabled, zoom by mouse wheel will be disabled.\n * :::\n * @ko `true`로 설정할 경우, 캔버스 영역 내에서 마우스 휠을 이용한 페이지 스크롤이 가능해집니다.\n * :::caution\n * 이 값을 활성화할 경우, 마우스 휠을 통한 줌이 불가능하게 됩니다.\n * :::\n * @since 4.0.0\n * @default false\n */\n public get wheelScrollable() { return this._control.wheelScrollable; }\n public set wheelScrollable(val: View360Options[\"wheelScrollable\"]) { this._control.wheelScrollable = val; }\n\n /**\n * Create new instance of View360\n * @ko View360의 새로운 인스턴스를 생성합니다\n * @param root - Root element(`.view360-container`) to mount View360\n * Can be either a CSS selector or HTMLElement.\n * {@ko View360을 마운트할 루트 엘리먼트, CSS 셀렉터나 HTMLElement를 지정 가능합니다.}\n * @param options - Options to apply\n * {@ko 적용할 옵션들}\n * @example\n * ```ts\n * import View360, { EquirectProjection } from \"@egjs/view360\";\n *\n * // Create new View360 instance\n * const viewer = new View360(\"#id-of-a-container\", {\n * projection: new EquirectProjection({\n * src: \"URL_TO_PANORAMA_IMAGE_OR_VIDEO\",\n * })\n * });\n * ```\n */\n public constructor(root: string | HTMLElement, {\n projection = null,\n initialYaw = 0,\n initialPitch = 0,\n initialZoom = 1,\n yawRange = null,\n pitchRange = null,\n zoomRange = null,\n fov = 90,\n useGrabCursor = true,\n disableContextMenu = false,\n rotate = true,\n zoom = true,\n gyro = false,\n scrollable = true,\n wheelScrollable = false,\n autoplay = false,\n hotspot = {},\n autoInit = true,\n autoResize = true,\n canvasSelector = \"canvas\",\n useResizeObserver = true,\n on = {},\n plugins = [],\n maxDeltaTime = 1 / 30,\n tabIndex = 0,\n debug = false\n }: Partial = {}) {\n super();\n\n this._rootEl = getElement(root);\n this._plugins = plugins;\n this._initialized = false;\n\n // Options\n this._autoInit = autoInit;\n this._autoResize = autoResize;\n this._canvasSelector = canvasSelector;\n this._useResizeObserver = useResizeObserver;\n this._tabIndex = tabIndex;\n this._debug = debug;\n\n // Core components\n const canvas = findCanvas(this._rootEl, canvasSelector);\n this._renderer = new WebGLRenderer(canvas, debug);\n this._camera = new Camera({\n initialYaw,\n initialPitch,\n initialZoom,\n fov,\n yawRange,\n pitchRange,\n zoomRange\n });\n this._control = new PanoControl(canvas, this._camera, {\n useGrabCursor,\n scrollable,\n wheelScrollable,\n disableContextMenu,\n rotate,\n zoom,\n gyro\n });\n this._animator = new FrameAnimator(maxDeltaTime);\n this._autoplay = new Autoplay(this, canvas, autoplay);\n this._projection = projection;\n this._autoResizer = new AutoResizer(useResizeObserver, () => this.resize());\n this._vr = new XRManager(this._renderer.ctx);\n this._hotspot = new HotspotRenderer(this._rootEl, this._renderer, hotspot);\n\n this._addEventHandlers(on);\n\n if (projection && autoInit) {\n this.init();\n }\n }\n\n /**\n * Destroy instance and release all resources.\n * @ko 인스턴스를 제거하고 모든 리소스를 해제합니다.\n * @since 4.0.0\n */\n public destroy() {\n this._camera.destroy();\n this._animator.stop();\n this._renderer.destroy();\n this._control.destroy();\n this._autoResizer.disable();\n\n if (this._projection) {\n this._projection.releaseAllResources(this._renderer.ctx);\n this._projection = null;\n }\n\n this._plugins.forEach(plugin => plugin.destroy(this));\n\n this._initialized = false;\n }\n\n /**\n * Initialize inner components and load projection src.\n * @ko 내부 컴포넌트들을 초기화하고 프로젝션 소스를 로드합니다.\n * @since 4.0.0\n */\n public async init() {\n if (!this._projection) {\n throw new View360Error(ERROR.MESSAGES.PROVIDE_PROJECTION_FIRST, ERROR.CODES.PROVIDE_PROJECTION_FIRST);\n }\n\n const renderer = this._renderer;\n const camera = this._camera;\n const control = this._control;\n const animator = this._animator;\n const hotspot = this._hotspot;\n const projection = this._projection;\n const canvas = renderer.canvas;\n\n this._bindComponentEvents();\n renderer.ctx.init();\n this._resizeComponents();\n camera.updateMatrix();\n\n if (this._autoResize) {\n this._autoResizer.enable(canvas);\n }\n\n if (!this._autoplay.enableBlocked) {\n this._autoplay.enable();\n }\n\n this._plugins.forEach(plugin => {\n plugin.init(this);\n });\n\n const texture = await this._loadTexture(projection);\n this._applyProjection(projection, texture, null);\n hotspot.refresh();\n animator.start(this._renderFrameOnDemand);\n await control.enable();\n\n if (this._tabIndex != null && !canvas.hasAttribute(\"tabIndex\")) {\n canvas.tabIndex = this._tabIndex;\n }\n\n this._initialized = true;\n this.renderFrame(0);\n\n this._emit(EVENTS.READY);\n }\n\n /**\n * Load new panorama image/video and display it.\n * This will {@link View360#init init()} View360 if it's not initialized yet.\n * @ko 새로운 파노라마 이미지 혹은 비디오를 로드하고 표시합니다.\n * 만약 View360이 아직 초기화되지 않았다면, {@link View360#init init()}을 호출합니다.\n * @param projection - Projection & video options for new source. {@ko 새로운 파노라마 이미지/비디오에 적용할 옵션들}\n * @returns `Promise` if load was successful. {@ko 프로젝션 로드에 성공했을 경우 `Promise`를 반환합니다. }\n * @since 4.0.0\n * @example\n * ```ts\n * // Change to video\n * viewer.load({\n * src: \"URL_TO_NEW_VIDEO\",\n * video: true\n * });\n * ```\n */\n public async load(projection: Projection): Promise {\n if (!projection) return false;\n\n if (this._initialized) {\n const texture = await this._loadTexture(projection);\n this._applyProjection(projection, texture, this._projection);\n this.renderFrame(0);\n } else {\n // Should update internal options before init\n this._projection = projection;\n this.init();\n }\n\n return true;\n }\n\n /**\n * Refresh component's size by current\n * @ko View360이 내부적으로 캐시하고 있는 엘리먼트 크기를 현재 크기로 갱신합니다.\n * @since 4.0.0\n */\n public resize() {\n if (!this._initialized) return;\n\n this._resizeComponents();\n\n // To prevent flickering, render immediately after resizing components\n this.renderFrame(0);\n\n const { width, height } = this._renderer;\n\n this._emit(EVENTS.RESIZE, {\n width,\n height\n });\n }\n\n /**\n * Add new plugins\n * @ko 새로운 플러그인을 추가합니다.\n * @param plugins Plugins to add {@ko 추가할 플러그인들}\n * @see View360Options#plugins\n * @since 4.0.0\n * @example\n * ```ts\n * // Add a single plugin\n * viewer.addPlugins(new ControlBar());\n *\n * // Add multiple plugins\n * viewer.addPlugins(new ControlBar(), new LoadingSpinner());\n * ```\n */\n public addPlugins(...plugins: View360Plugin[]) {\n if (this._initialized) {\n plugins.forEach(plugin => { plugin.init(this); });\n }\n\n this._plugins.push(...plugins);\n }\n\n /**\n * Remove plugins.\n * @ko 플러그인을 제거합니다.\n * @param plugins Plugins to remove {@ko 제거할 플러그인들}\n * @since 4.0.0\n * @example\n * ```ts\n * // Remove a single plugin\n * viewer.removePlugins(plugin1);\n *\n * // Remove multiple plugins\n * viewer.removePlugins(plugin2, plugin3);\n * ```\n */\n public removePlugins(...plugins: View360Plugin[]) {\n plugins.forEach(plugin => {\n const pluginIdx = this._plugins.indexOf(plugin);\n\n if (pluginIdx < 0) return;\n\n plugin.destroy(this);\n this._plugins.splice(pluginIdx, 1);\n });\n }\n\n /**\n * Render a single panorama image/video frame.\n * Rendering is performed automatically on demand, so you usually don't have to call this.\n * Call this when a frame is not renewed after changing options.\n * @ko 파노라마 이미지/비디오의 한 프레임을 렌더링합니다.\n * 프레임 갱신은 보통 필요한 때에만 자동적으로 이루어지기 때문에, 보통은 이 메소드를 호출할 필요는 없습니다.\n * 옵션 변경 이후에도 프레임 갱신이 이루어지지 않는다면, 이 메소드를 호출해주세요.\n * @param delta Delta time in milisec. {@ko 프레임간 시간 차이, 밀리초 단위}\n * @since 4.0.0\n */\n public renderFrame = (delta: number) => {\n const camera = this._camera;\n const renderer = this._renderer;\n const control = this._control;\n const hotspot = this._hotspot;\n const autoPlayer = this._autoplay;\n const projection = this._projection;\n\n if (!projection) return;\n\n this._emit(EVENTS.BEFORE_RENDER);\n\n if (autoPlayer.playing) {\n autoPlayer.update(delta);\n control.sync();\n }\n\n if (camera.animation) {\n camera.animation.update(delta);\n } else {\n control.update(delta);\n }\n\n renderer.render(projection, camera);\n hotspot.render(camera);\n\n if (camera.changed) {\n this._emit(EVENTS.VIEW_CHANGE, {\n yaw: camera.yaw,\n pitch: camera.pitch,\n zoom: camera.zoom,\n quaternion: [\n camera.quaternion[0],\n camera.quaternion[1],\n camera.quaternion[2],\n camera.quaternion[3]\n ]\n });\n }\n camera.onFrameRender();\n\n this._emit(EVENTS.RENDER);\n };\n\n private _emit(eventName: K, ...params: EventParams) {\n const evtParams = params ? params[0] : {};\n\n this.trigger(eventName as any, {\n type: eventName,\n target: this,\n ...evtParams\n });\n }\n\n private _renderFrameOnDemand = (delta: number) => {\n const camera = this._camera;\n const control = this._control;\n const autoplay = this._autoplay;\n const texture = this._projection?.getTexture();\n\n if (!this._initialized || !texture) return;\n if (\n !camera.animation\n && !control.animating\n && !autoplay.playing\n && !texture.isVideo()\n ) return;\n\n this.renderFrame(delta);\n };\n\n private _renderVRFrame = (_delta: number, frame: XRFrame) => {\n const vr = this._vr;\n const projection = this._projection;\n const renderer = this._renderer;\n\n if (!projection) return;\n\n this._emit(EVENTS.BEFORE_RENDER);\n\n renderer.renderVR(projection, vr, frame);\n\n this._emit(EVENTS.RENDER);\n }\n\n private _applyProjection(projection: Projection, texture: Texture, prevProjection: Projection | null) {\n const camera = this._camera;\n const control = this._control;\n const renderer = this._renderer;\n\n // Remove previous projection\n if (prevProjection) {\n prevProjection.releaseAllResources(this._renderer.ctx);\n }\n\n projection.applyTexture(renderer.ctx, texture);\n projection.updateCamera(camera);\n projection.updateControl(control);\n\n this._projection = projection;\n this._emit(EVENTS.PROJECTION_CHANGE, {\n projection\n });\n }\n\n private async _loadTexture(projection: Projection): Promise {\n const contentLoader = new TextureLoader();\n const { src, video } = projection;\n\n this._emit(EVENTS.LOAD_START, {\n src,\n video\n });\n\n const texture = await contentLoader.load(src, video);\n\n this._emit(EVENTS.LOAD, {\n src,\n video\n });\n\n return texture;\n }\n\n private _resizeComponents() {\n const renderer = this._renderer;\n const camera = this._camera;\n const control = this._control;\n\n renderer.resize();\n camera.resize(renderer.width, renderer.height);\n control.resize(renderer.width, renderer.height);\n }\n\n private _addEventHandlers(events: View360Options[\"on\"]) {\n // Bind option \"on\"\n Object.keys(events).forEach((evtName: keyof typeof EVENT_TYPES) => {\n this.on(evtName, events[evtName]);\n });\n }\n\n private _bindComponentEvents() {\n // Bind internal component events\n const root = this._rootEl;\n const control = this._control;\n const animator = this._animator;\n const renderer = this._renderer;\n const vr = this._vr;\n\n const controlEventsToPropagate = [\n CONTROL_EVENTS.STATIC_CLICK,\n CONTROL_EVENTS.INPUT_START,\n CONTROL_EVENTS.INPUT_END\n ];\n\n controlEventsToPropagate.forEach(evtName => {\n control.rotate.on(evtName, evt => {\n this._emit(evtName, evt);\n });\n\n control.zoom.on(evtName, evt => {\n this._emit(evtName, evt);\n });\n });\n\n vr.on(EVENTS.VR_START, evt => {\n root.classList.add(DEFAULT_CLASS.IN_VR);\n\n animator.changeContext(evt.session);\n animator.start(this._renderVRFrame);\n\n this._emit(EVENTS.VR_START);\n });\n\n vr.on(EVENTS.VR_END, () => {\n root.classList.remove(DEFAULT_CLASS.IN_VR);\n\n renderer.ctx.useDefaultFrameBuffer();\n animator.changeContext(window);\n animator.start(this._renderFrameOnDemand);\n\n this.resize();\n\n this._emit(EVENTS.VR_END);\n });\n }\n}\n\nexport default View360;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4, quat, vec3 } from \"gl-matrix\";\n\n/**\n * Base class for 3D objects\n * @ko 3D 오브젝트의 베이스 클래스\n * @since 4.0.0\n * @internal\n */\nclass Object3D {\n /**\n * Local matrix of the object\n * @ko 오브젝트의 local matrix\n * @since 4.0.0\n */\n public matrix: mat4;\n /**\n * Rotation quaternion\n * @ko 현재 오브젝트의 회전을 나타내는 사원수 값\n * @since 4.0.0\n */\n public rotation: quat;\n /**\n * Position of the object\n * @ko 오브젝트의 위치\n * @since 4.0.0\n */\n public position: vec3;\n /**\n * A scale vector of the object\n * @ko 오브젝트가 각 축으로 확대된 정도를 나타내는 벡터\n * @since 4.0.0\n */\n public scale: vec3;\n\n /**\n * Create new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n */\n public constructor() {\n this.matrix = mat4.create();\n this.rotation = quat.create();\n this.position = vec3.fromValues(0, 0, 0);\n this.scale = vec3.fromValues(1, 1, 1);\n }\n\n /**\n * Update local matrix of the object.\n * @ko 오브젝트의 local matrix를 갱신합니다.\n * @since 4.0.0\n */\n public updateMatrix() {\n mat4.fromRotationTranslationScale(this.matrix, this.rotation, this.position, this.scale);\n }\n}\n\nexport default Object3D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360Plugin from \"../View360Plugin\";\nimport View360 from \"../../View360\";\nimport { EVENTS } from \"../../const/external\";\nimport { createElement } from \"../../utils\";\nimport { LoadStartEvent } from \"../../type/events\";\n\n/**\n * Options for {@link LoadingSpinner}\n * @ko {@link LoadingSpinner}용 옵션들\n * @since 4.0.0\n * @category Plugin\n */\nexport interface LoadingSpinnerOptions {\n /**\n * Override default class names.\n * @ko 디폴트 클래스 이름들을 오버라이드합니다.\n * @since 4.0.0\n */\n className: Partial<{ -readonly [key in keyof typeof LoadingSpinner.DEFAULT_CLASS]: string }>;\n}\n\n/**\n * A plugin that displays loading spinner while loading the projection.\n * @ko 프로젝션 로딩중에 로딩 스피너를 보여주는 플러그인\n * @since 4.0.0\n * @category Plugin\n */\nclass LoadingSpinner implements View360Plugin {\n /**\n * Default class names that LoadingSpinner uses\n * @ko LoadingSpinner가 사용하는 디폴트 클래스 이름\n * @since 4.0.0\n */\n public static readonly DEFAULT_CLASS = {\n /**\n * A class name for the container element\n * @ko 컨테이너 엘리먼트의 클래스 이름\n * @since 4.0.0\n */\n CONTAINER: \"view360-spinner\",\n /**\n * A class name for the spinning ring element\n * @ko 돌아가는 링 엘리먼트의 클래스 이름\n * @since 4.0.0\n */\n RING: \"view360-spinner-ring\"\n } as const;\n\n /**\n * A class names overriding\n * @ko 현재 오버라이드 중인 클래스 이름\n * @since 4.0.0\n */\n public readonly className: LoadingSpinnerOptions[\"className\"];\n\n private _container: HTMLElement;\n\n /**\n * Create a new instance of LoadingSpinner. {@ko LoadingSpinner의 새 인스턴스를 생성합니다.}\n * @param options Options {@ko 옵션들}\n */\n public constructor({\n className = {}\n }: Partial = {}) {\n this.className = className;\n this._container = this._createElements();\n }\n\n public init(viewer: View360) {\n viewer.on(EVENTS.LOAD_START, this._startLoading);\n }\n\n public destroy(viewer: View360): void {\n viewer.off(EVENTS.LOAD_START, this._startLoading);\n this._detachElements({ target: viewer });\n }\n\n private _startLoading = ({ target: viewer }: LoadStartEvent) => {\n viewer.rootEl.appendChild(this._container);\n\n if (viewer.initialized) {\n viewer.once(EVENTS.LOAD, this._detachElements);\n } else {\n viewer.once(EVENTS.READY, this._detachElements);\n }\n };\n\n private _detachElements = ({ target: viewer }: { target: View360 }) => {\n const container = this._container;\n if (!container) return;\n\n if (container.parentElement === viewer.rootEl) {\n viewer.rootEl.removeChild(container);\n }\n };\n\n private _createElements() {\n const className = {\n ...this.className,\n ...LoadingSpinner.DEFAULT_CLASS\n };\n\n const container = createElement(className.CONTAINER);\n const ring = createElement(className.RING);\n\n container.appendChild(ring);\n\n return container;\n }\n}\n\nexport default LoadingSpinner;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n/* eslint-disable @typescript-eslint/no-empty-function */\n/* eslint-disable @typescript-eslint/no-unused-vars */\nimport ControlBar from \"./ControlBar\";\nimport View360 from \"../../View360\";\n\n/**\n * Common options for {@link ControlBarItem}\n * @ko {@link ControlBarItem}의 공통 옵션들\n * @category Plugin\n * @since 4.0.0\n */\nexport interface ControlBarItemOptions {\n /**\n * @copy ControlBarItem#position\n */\n position: typeof ControlBar.POSITION[keyof typeof ControlBar.POSITION];\n /**\n * @copy ControlBarItem#order\n */\n order: number;\n}\n\n/**\n * Interface of the ControlBar items\n * @ko 컨트롤바 아이템의 인터페이스\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nabstract class ControlBarItem {\n /**\n * Element of the item.\n * @ko 아이템의 엘리먼트\n * @since 4.0.0\n */\n public abstract element: HTMLElement;\n\n /**\n * Position to display item.\n * @ko 아이템을 표시할 위치.\n * @since 4.0.0\n */\n public position: ControlBarItemOptions[\"position\"];\n /**\n * Order within the same position.\n * The lowest one will be shown first.\n * @ko 동일한 position 내에서의 순서, 작을수록 먼저 표시됩니다.\n * @since 4.0.0\n */\n public order: ControlBarItemOptions[\"order\"];\n\n /**\n * Create new instance of the ControlBarItem\n * @ko ControlBarItem의 새로운 인스턴스를 생성합니다.\n * @param options Options {@ko 옵션들}\n */\n public constructor(options: ControlBarItemOptions) {\n this.position = options.position;\n this.order = options.order;\n }\n\n /**\n * Initialize item.\n * @ko 아이템을 초기화합니다.\n * @param viewer - A instance of viewer to attach item {@ko 아이템을 부착할 뷰어의 인스턴스}\n * @param controlBar - A instance of control bar to attach item {@ko 아이템을 부착할 컨트롤바의 인스턴스}\n * @since 4.0.0\n */\n public abstract init(viewer: View360, controlBar: ControlBar): any;\n /**\n * Destroy item and release all resources & event handlers.\n * @ko 아이템을 제거하고 할당된 모든 리소스 및 이벤트 핸들러를 제거합니다.\n * @param viewer - A instance of viewer to detach item {@ko 아이템을 떼어 낼 뷰어의 인스턴스}\n * @param controlBar - A instance of control bar to detach item {@ko 아이템을 떼어 낼 컨트롤바의 인스턴스}\n * @since 4.0.0\n */\n public abstract destroy(viewer: View360, controlBar: ControlBar): any;\n}\n\nexport default ControlBarItem;\n","export const CONTROL_BAR_DEFAULT_CLASS = {\n CONTROLS_ROOT: \"view360-controls\",\n CONTROLS_BG: \"view360-controls-background\",\n CONTROLS_MAIN: \"view360-controls-main\",\n CONTROLS_TOP: \"view360-controls-top\",\n CONTROLS_BOTTOM: \"view360-controls-bottom\",\n CONTROLS_MID: \"view360-controls-mid\",\n CONTROLS_LEFT: \"view360-controls-left\",\n CONTROLS_RIGHT: \"view360-controls-right\",\n CONTROLS_FLOAT_LEFT: \"view360-controls-float-left\",\n CONTROLS_FLOAT_RIGHT: \"view360-controls-float-right\",\n CONTROLS_BUTTON: \"view360-controls-button\",\n PROGRESS_ROOT: \"view360-controls-progress\",\n VOLUME_ROOT: \"view360-controls-volume\",\n RANGE_ROOT: \"view360-range\",\n RANGE_TRACK: \"view360-range-track\",\n RANGE_THUMB: \"view360-range-thumb\",\n RANGE_FILLER: \"view360-range-filler\",\n PLAY_BUTTON: \"view360-controls-play\",\n PAUSE_BUTTON: \"view360-controls-pause\",\n UNMUTED_BUTTON: \"view360-controls-unmuted\",\n MUTED_BUTTON: \"view360-controls-muted\",\n FULLSCREEN_BUTTON: \"view360-controls-fullscreen\",\n FULLSCREEN_EXIT_BUTTON: \"view360-controls-fullscreen-exit\",\n VR_BUTTON: \"view360-controls-vr\",\n GYRO_ENABLED: \"view360-controls-gyro-enabled\",\n GYRO_DISABLED: \"view360-controls-gyro-disabled\",\n VIDEO_TIME_DISPLAY: \"view360-controls-time\",\n PIEVIEW_ROOT: \"view360-controls-pie\",\n FIXED: \"view360-controls-fixed\",\n UNAVAILABLE: \"view360-controls-unavailable\",\n HIDDEN: \"view360-controls-hidden\"\n} as const;\n\nexport const CONTROL_BAR_ITEM_POSITION = {\n /**\n * Place control bar item floating at top-left corner\n * @ko 아이템을 왼쪽 위 구석에 표시합니다.\n * @since 4.0.0\n */\n TOP_LEFT: \"top-left\",\n /**\n * Place control bar item floating at top-right corner\n * @ko 아이템을 오른쪽 위 구석에 표시합니다.\n * @since 4.0.0\n */\n TOP_RIGHT: \"top-right\",\n /**\n * Place control bar item at upper block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 위쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_TOP: \"main-top\",\n /**\n * Place control bar item at lower block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 하단 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_BOTTOM: \"main-bottom\",\n /**\n * Place control bar item at center-left block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 왼쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_LEFT: \"main-left\",\n /**\n * Place control bar item at center-right block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 오른쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_RIGHT: \"main-right\"\n} as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { ControlBarOptions } from \"./ControlBar\";\nimport { CONTROL_BAR_DEFAULT_CLASS } from \"./const\";\nimport Motion from \"../../core/Motion\";\nimport MouseInput from \"../../control/input/MouseInput\";\nimport TouchInput from \"../../control/input/TouchInput\";\nimport { CONTROL_EVENTS, INFINITE_RANGE } from \"../../const/internal\";\nimport { clamp } from \"../../utils\";\nimport { InputEvents } from \"../../type/internal\";\nimport { EL_DIV } from \"../../const/browser\";\n\nclass RangeControl extends Component<{\n [CONTROL_EVENTS.INPUT_START]: number;\n [CONTROL_EVENTS.CHANGE]: number;\n [CONTROL_EVENTS.INPUT_END]: void;\n}> {\n public readonly rootEl: HTMLElement;\n public readonly thumbEl: HTMLElement;\n public readonly trackEl: HTMLElement;\n public readonly fillerEl: HTMLElement;\n\n private _motion: Motion;\n private _mouseInput: MouseInput;\n private _touchInput: TouchInput;\n private _fixedClass: string;\n private _bbox: DOMRect;\n\n /**\n *\n */\n public constructor() {\n super();\n\n const root = document.createElement(EL_DIV);\n const track = document.createElement(EL_DIV);\n const thumb = document.createElement(EL_DIV);\n const filler = document.createElement(EL_DIV);\n\n root.draggable = false;\n\n track.appendChild(filler);\n track.appendChild(thumb);\n root.appendChild(track);\n\n this.rootEl = root;\n this.trackEl = track;\n this.thumbEl = thumb;\n this.fillerEl = filler;\n\n this._mouseInput = new MouseInput();\n this._touchInput = new TouchInput();\n this._motion = new Motion({ duration: 1, range: INFINITE_RANGE, easing: x => x });\n this._bbox = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n left: 0,\n right: 0,\n bottom: 0,\n top: 0\n } as DOMRect;\n this._fixedClass = CONTROL_BAR_DEFAULT_CLASS.FIXED;\n }\n\n public init(className: Required) {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n\n this.rootEl.classList.add(className.RANGE_ROOT);\n this.trackEl.classList.add(className.RANGE_TRACK);\n this.thumbEl.classList.add(className.RANGE_THUMB);\n this.fillerEl.classList.add(className.RANGE_FILLER);\n this._fixedClass = className.FIXED;\n\n mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n touchInput.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n\n mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n touchInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n\n mouseInput.enable(this.rootEl);\n touchInput.enable(this.rootEl);\n\n this.resize();\n }\n\n public destroy() {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n\n this.rootEl.className = \"\";\n this.trackEl.className = \"\";\n this.thumbEl.className = \"\";\n this.fillerEl.className = \"\";\n\n mouseInput.off();\n touchInput.off();\n mouseInput.disable();\n touchInput.disable();\n }\n\n public resize() {\n this._bbox = this.trackEl.getBoundingClientRect();\n }\n\n public updateStyle(progress: number) {\n const width = this._bbox.width;\n const clampedProgress = clamp(progress, 0, 1);\n\n this.fillerEl.style.width = `${clampedProgress * 100}%`;\n this.thumbEl.style.transform = `translateX(${clampedProgress * width}px)`;\n }\n\n private _onHold = ({ srcEvent, isTouch }: InputEvents<{ x: number; y: number }>[typeof CONTROL_EVENTS.INPUT_START]) => {\n const bbox = this._bbox;\n if (!bbox) return;\n\n const x = isTouch\n ? (srcEvent as TouchEvent).touches[0].pageX\n : (srcEvent as MouseEvent).pageX;\n const elX = bbox.x + (window.scrollX ?? window.pageXOffset);\n\n const clamepdX = clamp(x, elX, elX + bbox.width);\n const progress = (clamepdX - elX) / bbox.width;\n\n this._motion.reset(clamepdX);\n this.thumbEl.classList.add(this._fixedClass);\n\n this.trigger(CONTROL_EVENTS.INPUT_START, progress);\n };\n\n private _onChange = ({ delta }: InputEvents<{ x: number; y: number }>[typeof CONTROL_EVENTS.CHANGE]) => {\n const motion = this._motion;\n const bbox = this._bbox;\n if (!bbox) return;\n\n motion.setNewEndByDelta(delta.x);\n motion.update(1);\n\n const elX = bbox.x + (window.scrollX ?? window.pageXOffset);\n const clampedX = clamp(motion.val, elX, elX + bbox.width);\n const progress = (clampedX - elX) / bbox.width;\n\n this.trigger(CONTROL_EVENTS.CHANGE, progress);\n };\n\n private _onRelease = () => {\n const bbox = this._bbox;\n if (!bbox) return;\n\n this.thumbEl.classList.remove(this._fixedClass);\n\n this.trigger(CONTROL_EVENTS.INPUT_END);\n };\n}\n\nexport default RangeControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport RangeControl from \"./RangeControl\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport { CONTROL_EVENTS, VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport { EVENTS } from \"../../const/external\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show video progress bar.\n * @ko 비디오의 프로그레스 바를 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass ProgressBar extends ControlBarItem {\n public get element() { return this._rangeControl.rootEl; }\n\n private _controlBar: ControlBar | null;\n private _video: TextureVideo | null;\n private _rangeControl: RangeControl;\n\n private _wasPaused: boolean;\n private _currentTime: number;\n private _duration: number;\n private _playPromise: Promise | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_TOP,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.position = position;\n this.order = order;\n\n this._controlBar = null;\n this._rangeControl = new RangeControl();\n\n this._video = null;\n this._wasPaused = false;\n this._currentTime = 0;\n this._duration = 0;\n this._playPromise = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const element = this.element;\n const rangeControl = this._rangeControl;\n const unavailableClass = controlBar.className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n element.classList.add(unavailableClass);\n return;\n }\n\n element.classList.remove(unavailableClass);\n element.classList.add(controlBar.className.PROGRESS_ROOT);\n viewer.on(EVENTS.RESIZE, this._onResize);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate);\n rangeControl.init(controlBar.className);\n rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n rangeControl.on(CONTROL_EVENTS.CHANGE, this._onControl);\n rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n this._video = video;\n this._currentTime = video.source.currentTime;\n this._duration = video.source.duration;\n this._controlBar = controlBar;\n\n rangeControl.updateStyle(this._currentTime / this._duration);\n }\n\n public destroy(viewer: View360) {\n const video = this._video;\n\n viewer.off(EVENTS.RESIZE, this._onResize);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate);\n }\n\n this._rangeControl.destroy();\n this._video = null;\n this._playPromise = null;\n }\n\n private _onResize = () => {\n this._rangeControl.resize();\n }\n\n private _onTimeUpdate = () => {\n const video = this._video;\n if (!video) return;\n\n this._currentTime = video.source.currentTime;\n this._rangeControl.updateStyle(this._currentTime / this._duration);\n };\n\n private _onDurationChange = () => {\n const video = this._video;\n if (!video) return;\n\n this._duration = video.source.duration;\n this._rangeControl.updateStyle(this._currentTime / this._duration);\n };\n\n private _onHold = (progress: number) => {\n const video = this._video;\n const controlBar = this._controlBar;\n if (!video || !controlBar) return;\n\n const paused = video.isPaused();\n\n video.source.pause();\n\n const time = video.source.duration * progress;\n video.source.currentTime = time;\n video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time }}));\n\n controlBar.rootEl.classList.add(controlBar.className.FIXED);\n this._wasPaused = !this._playPromise && paused;\n };\n\n private _onControl = (progress: number) => {\n const video = this._video;\n if (!video) return;\n\n const time = video.source.duration * progress;\n video.source.currentTime = time;\n video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time }}));\n };\n\n private _onRelease = () => {\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (video && controlBar) {\n if (!this._wasPaused && !this._playPromise) {\n this._playPromise = video.source.play()\n .catch(() => void 0);\n\n // This should not be chained\n this._playPromise.then(() => {\n this._playPromise = null;\n });\n\n controlBar.rootEl.classList.remove(controlBar.className.FIXED);\n }\n }\n\n this._wasPaused = false;\n };\n}\n\nexport default ProgressBar;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show video play / pause button.\n * @ko 비디오 재생 / 일시정지 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass PlayButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _controlBar: ControlBar | null;\n private _video: TextureVideo | null;\n private _paused: boolean;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n\n this._video = null;\n this._paused = true;\n this._controlBar = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const video = viewer.projection?.getTexture();\n const className = controlBar.className;\n const unavailableClass = className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n element.classList.add(unavailableClass);\n return;\n }\n\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.remove(unavailableClass);\n\n const paused = video.isPaused();\n this._video = video;\n this._paused = paused;\n this._controlBar = controlBar;\n\n if (paused) {\n this._onPause();\n } else {\n this._onPlay();\n }\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onPlay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onPause);\n }\n\n public destroy() {\n const video = this._video;\n const element = this.element;\n\n if (!video) return;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onPlay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onPause);\n\n this._video = null;\n this._paused = true;\n this._controlBar = null;\n }\n\n private _onClick = () => {\n const video = this._video;\n if (!video) return;\n\n if (this._paused) {\n video.source.play();\n } else {\n video.source.pause();\n }\n };\n\n private _onPlay = () => {\n if (!this._controlBar) return;\n\n const element = this.element;\n const className = this._controlBar.className;\n\n element.classList.add(className.PAUSE_BUTTON);\n element.classList.remove(className.PLAY_BUTTON);\n element.title = \"Pause Video\";\n\n this._paused = false;\n };\n\n private _onPause = () => {\n if (!this._controlBar) return;\n\n const element = this.element;\n const className = this._controlBar.className;\n\n element.classList.add(className.PLAY_BUTTON);\n element.classList.remove(className.PAUSE_BUTTON);\n element.title = \"Play Video\";\n\n this._paused = true;\n };\n}\n\nexport default PlayButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport RangeControl from \"./RangeControl\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { EVENTS } from \"../../const/external\";\n\n/**\n * Show video volume control.\n * @ko 비디오 볼륨 조절 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VolumeControl extends ControlBarItem {\n public get element() { return this._rootEl; }\n\n private _controlBar: ControlBar | null;\n private _rootEl: HTMLButtonElement;\n private _buttonEl: HTMLElement;\n private _rangeControl: RangeControl;\n private _video: TextureVideo | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this._controlBar = null;\n this._rangeControl = new RangeControl();\n this._createElements();\n\n this._video = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const root = this._rootEl;\n const button = this._buttonEl;\n const rangeControl = this._rangeControl;\n const className = controlBar.className;\n const unavailableClass = className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n root.classList.add(unavailableClass);\n return;\n }\n\n root.classList.remove(unavailableClass);\n root.classList.add(className.CONTROLS_BUTTON);\n root.classList.add(className.VOLUME_ROOT);\n button.classList.add(className.CONTROLS_BUTTON);\n\n if (video.source.muted) {\n button.classList.add(className.MUTED_BUTTON);\n } else {\n button.classList.add(className.UNMUTED_BUTTON);\n }\n\n viewer.on(EVENTS.RESIZE, this._onResize);\n root.addEventListener(BROWSER.EVENTS.TRANSITION_END, this._onResize);\n button.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_VOLUME_CHANGE, this._onVolumeChange);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_LOADED_DATA, this._updateDisplay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay);\n\n rangeControl.init(className);\n rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n rangeControl.on(CONTROL_EVENTS.CHANGE, this._onChange);\n rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n this._controlBar = controlBar;\n this._video = video;\n\n this._updateDisplay();\n }\n\n public destroy(viewer: View360) {\n const video = this._video;\n const button = this._buttonEl;\n const root = this._rootEl;\n\n root.className = \"\";\n button.className = \"\";\n\n viewer.off(EVENTS.RESIZE, this._onResize);\n root.removeEventListener(BROWSER.EVENTS.TRANSITION_END, this._onResize);\n button.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_VOLUME_CHANGE, this._onVolumeChange);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_LOADED_DATA, this._updateDisplay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay);\n }\n\n this._controlBar = null;\n this._rangeControl.destroy();\n this._video = null;\n }\n\n private _onResize = () => {\n this._rangeControl.resize();\n this._updateDisplay();\n }\n\n private _onClick = () => {\n const video = this._video;\n if (!video || this._rootEl.disabled) return;\n\n video.source.muted = !video.source.muted;\n };\n\n private _onVolumeChange = () => {\n const button = this._buttonEl;\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (!video || !controlBar) return;\n\n const className = controlBar.className;\n\n if (video.source.muted || video.source.volume === 0) {\n button.classList.add(className.MUTED_BUTTON);\n button.classList.remove(className.UNMUTED_BUTTON);\n } else {\n button.classList.add(className.UNMUTED_BUTTON);\n button.classList.remove(className.MUTED_BUTTON);\n }\n\n this._updateDisplay();\n };\n\n private _createElements() {\n const root = document.createElement(BROWSER.EL_BUTTON);\n const buttonEl = document.createElement(BROWSER.EL_DIV);\n\n root.appendChild(this._rangeControl.rootEl);\n root.appendChild(buttonEl);\n root.title = \"Toggle Mute\";\n\n this._rootEl = root;\n this._buttonEl = buttonEl;\n }\n\n private _onHold = (progress: number) => {\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (!video || !controlBar) return;\n\n const className = controlBar.className;\n\n video.source.volume = progress;\n\n this._rootEl.classList.add(className.FIXED);\n controlBar.containerEl.classList.add(className.FIXED);\n\n this._updateDisplay();\n };\n\n private _onChange = (progress: number) => {\n const video = this._video;\n if (!video) return;\n\n video.source.volume = progress;\n if (progress > 0) {\n video.source.muted = false;\n } else {\n video.source.muted = true;\n }\n\n this._updateDisplay();\n };\n\n private _onRelease = () => {\n const controlBar = this._controlBar;\n if (!controlBar) return;\n\n const className = controlBar.className;\n\n this._rootEl.classList.remove(className.FIXED);\n controlBar.containerEl.classList.remove(className.FIXED);\n };\n\n private _updateDisplay = () => {\n const video = this._video;\n const root = this._rootEl;\n if (!video) return;\n\n if (!video.hasAudio()) {\n root.disabled = true;\n return;\n }\n\n root.disabled = false;\n\n const volume = video.source.muted ? 0 : video.source.volume;\n\n this._rangeControl.updateStyle(volume);\n };\n}\n\nexport default VolumeControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport { isFullscreen } from \"../../utils\";\n\n/**\n * Show fullscreen enter / exit button.\n * @ko 풀스크린 진입 / 해제 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass FullscreenButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _controlBar: ControlBar | null;\n private _targetEl: HTMLElement | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n this.element.title = \"Toggle Fullscreen\";\n this._controlBar = null;\n this._targetEl = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n if (!this._fullscreenAvailable()) {\n element.classList.add(className.UNAVAILABLE);\n return;\n }\n\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.remove(className.UNAVAILABLE);\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._addFullscreenHandlers();\n\n if (isFullscreen()) {\n element.classList.add(className.FULLSCREEN_EXIT_BUTTON);\n } else {\n element.classList.add(className.FULLSCREEN_BUTTON);\n }\n\n this._controlBar = controlBar;\n this._targetEl = viewer.rootEl;\n }\n\n public destroy() {\n const element = this.element;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._removeFullscreenHandlers();\n\n this._controlBar = null;\n this._targetEl = null;\n }\n\n private _onClick = () => {\n const target = this._targetEl;\n if (!target) return;\n\n if (isFullscreen()) {\n this._exitFullscreen();\n } else {\n this._requestFullscreen(target);\n }\n };\n\n private _fullscreenAvailable() {\n return BROWSER.FULLSCREEN_REQUEST.some(key => !!document[key]);\n }\n\n private _requestFullscreen(el: HTMLElement) {\n for (const key of BROWSER.FULLSCREEN_REQUEST) {\n const request = el[key];\n if (request) {\n request.call(el);\n return;\n }\n }\n }\n\n private _exitFullscreen() {\n for (const key of BROWSER.FULLSCREEN_EXIT) {\n const exit = document[key];\n\n if (exit) {\n exit.call(document);\n return;\n }\n }\n }\n\n private _addFullscreenHandlers() {\n BROWSER.FULLSCREEN_CHANGE.forEach(evtName => {\n document.addEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _removeFullscreenHandlers() {\n BROWSER.FULLSCREEN_CHANGE.forEach(evtName => {\n document.removeEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _onFullscreenChange = () => {\n const element = this.element;\n const controlBar = this._controlBar;\n\n if (!controlBar) return;\n\n const className = controlBar.className;\n\n if (isFullscreen()) {\n element.classList.add(className.FULLSCREEN_EXIT_BUTTON);\n element.classList.remove(className.FULLSCREEN_BUTTON);\n } else {\n element.classList.add(className.FULLSCREEN_BUTTON);\n element.classList.remove(className.FULLSCREEN_EXIT_BUTTON);\n }\n };\n}\n\nexport default FullscreenButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\n\n/**\n * Show video current / total time.\n * @ko 비디오의 현재 / 총 재생시간을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VideoTime extends ControlBarItem {\n public readonly element: HTMLElement;\n private _video: TextureVideo | null;\n private _currentTime: number;\n private _duration: number;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n\n this._video = null;\n this._currentTime = 0;\n this._duration = 0;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const element = this.element;\n const className = controlBar.className;\n\n if (!video || !video.isVideo()) {\n element.classList.add(className.UNAVAILABLE);\n return;\n }\n\n element.classList.add(className.VIDEO_TIME_DISPLAY);\n element.classList.remove(className.UNAVAILABLE);\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange);\n\n this._video = video;\n this._currentTime = video.source.currentTime;\n this._duration = video.source.duration;\n\n this._updateDisplay();\n }\n\n public destroy() {\n const video = this._video;\n\n if (!video) return;\n\n this.element.className = \"\";\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange);\n\n this._video = null;\n }\n\n private _onTimeUpdate = () => {\n const video = this._video;\n if (!video) return;\n\n this._currentTime = video.source.currentTime;\n this._updateDisplay();\n };\n\n private _onDurationChange = () => {\n const video = this._video;\n if (!video) return;\n\n this._duration = video.source.duration;\n this._updateDisplay();\n };\n\n private _onCustomTimeChange = (evt: CustomEvent<{ time: number }>) => {\n this._currentTime = evt.detail.time;\n this._updateDisplay();\n };\n\n private _updateDisplay() {\n const time = this._currentTime;\n const timeMinute = Math.floor(time / 60);\n const timeSeconds = Math.floor(time - timeMinute * 60);\n const timeSecondsFormatted = timeSeconds < 10 ? `0${timeSeconds}` : timeSeconds;\n\n const duration = this._duration;\n const durationMinute = Math.floor(duration / 60);\n const durationSeconds = Math.floor(duration - durationMinute * 60);\n const durationSecondsFormatted = durationSeconds < 10 ? `0${durationSeconds}` : durationSeconds;\n\n this.element.innerText = `${timeMinute}:${timeSecondsFormatted} / ${durationMinute}:${durationSecondsFormatted}`;\n }\n}\n\nexport default VideoTime;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport { circulate, getObjectOption } from \"../../utils\";\nimport * as BROWSER from \"../../const/browser\";\nimport { EVENTS } from \"../../const/external\";\nimport { SVG_NAMESPACE } from \"../../const/internal\";\n\n/**\n * Options for {@link PieView}\n * @ko {@link PieView}용 옵션들\n * @category Plugin\n */\nexport interface PieViewOptions extends ControlBarItemOptions {\n /**\n * @copy PieView#resetCamera\n */\n resetCamera: boolean | Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n duration: number;\n easing: (x: number) => number;\n }>;\n}\n\n/**\n * Show camera direction/fov indicator.\n * @ko 카메라가 향하는 방향 및 FOV를 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass PieView extends ControlBarItem {\n public readonly element: HTMLElement;\n\n /**\n * Set rotation to reset camera to when PieView is clicked.\n * `false` will disable this value, and `true` will enable with default options.\n * @ko PieView가 클릭되었을 때 카메라를 리셋할 방향을 지정합니다.\n * `false`일 경우 이 동작을 비활성화하며, `true`일 경우 기본값을 사용합니다.\n * @since 4.0.0\n */\n public resetCamera: PieViewOptions[\"resetCamera\"];\n\n private _viewer: View360 | null;\n private _piePathEl: SVGPathElement;\n private _rangeCircleEl: SVGCircleElement;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n resetCamera = true,\n position = CONTROL_BAR_ITEM_POSITION.TOP_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n this.element.title = \"Reset view\";\n this.resetCamera = resetCamera;\n this._createPieElements();\n this._viewer = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n\n if (!viewer.initialized) {\n viewer.once(EVENTS.READY, this._updatePie);\n } else {\n this._updatePie({ target: viewer });\n }\n\n const rootClass = controlBar.className.PIEVIEW_ROOT;\n element.classList.add(rootClass);\n\n if (this.resetCamera) {\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n }\n\n viewer.on(EVENTS.VIEW_CHANGE, this._updatePie);\n\n this._viewer = viewer;\n }\n\n public destroy(viewer: View360) {\n const element = this.element;\n\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.className = \"\";\n viewer.off(EVENTS.READY, this._updatePie);\n viewer.off(EVENTS.VIEW_CHANGE, this._updatePie);\n\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n const resetCamera = this.resetCamera;\n\n if (!viewer || !resetCamera) return;\n\n const {\n yaw = viewer.initialYaw,\n pitch = viewer.initialPitch,\n zoom = viewer.initialZoom,\n duration = 500\n } = getObjectOption(resetCamera);\n\n viewer.camera.animateTo({\n yaw,\n pitch,\n zoom,\n duration\n });\n };\n\n private _createPieElements() {\n const root = this.element;\n const pieSVG = document.createElementNS(SVG_NAMESPACE, \"svg\");\n pieSVG.setAttribute(\"viewBox\", \"0 0 48 48\");\n pieSVG.setAttribute(\"width\", \"100%\");\n pieSVG.setAttribute(\"height\", \"100%\");\n\n const piePath = document.createElementNS(SVG_NAMESPACE, \"circle\");\n\n piePath.setAttribute(\"stroke\", \"currentColor\");\n piePath.setAttribute(\"fill\", \"transparent\");\n piePath.setAttribute(\"cx\", \"24\");\n piePath.setAttribute(\"cy\", \"24\");\n piePath.setAttribute(\"r\", \"12\");\n piePath.setAttribute(\"stroke-width\", \"24\");\n pieSVG.appendChild(piePath);\n\n const rangeCircle = document.createElementNS(SVG_NAMESPACE, \"circle\");\n\n rangeCircle.setAttribute(\"stroke\", \"currentColor\");\n rangeCircle.setAttribute(\"fill\", \"transparent\");\n rangeCircle.setAttribute(\"cx\", \"24\");\n rangeCircle.setAttribute(\"cy\", \"24\");\n rangeCircle.setAttribute(\"r\", \"22.5\");\n rangeCircle.setAttribute(\"stroke-width\", \"3\");\n pieSVG.appendChild(rangeCircle);\n\n root.appendChild(pieSVG);\n\n this._piePathEl = piePath;\n this._rangeCircleEl = rangeCircle;\n }\n\n private _updatePie = ({ target: viewer }: { target: View360 }) => {\n const piePath = this._piePathEl;\n const rangeCircle = this._rangeCircleEl;\n const camera = viewer.camera;\n const fov = camera.getHorizontalFov();\n const yawRange = camera.getYawRange(camera.zoom);\n const halfFov = fov * 0.5;\n\n const pieRadius = 24 * Math.PI;\n const pieDeg = pieRadius * fov / 360;\n const pieOffset = pieRadius * (camera.yaw + halfFov + 90) / 360;\n\n piePath.setAttribute(\"stroke-dasharray\", `${pieDeg} ${pieRadius - pieDeg}`);\n piePath.setAttribute(\"stroke-dashoffset\", `${pieOffset}`);\n\n if (isFinite(yawRange.min) && isFinite(yawRange.max)) {\n const radius = 45 * Math.PI; // 2 * PI * r\n const min = (circulate(yawRange.min, -180, 180) - halfFov) / 360;\n const max = (circulate(yawRange.max, -180, 180) + halfFov) / 360;\n\n const rangeDiff = radius * Math.abs(max - min);\n const offset = -radius * (min - 0.25);\n\n rangeCircle.setAttribute(\"stroke-dasharray\", `${rangeDiff} ${radius - rangeDiff}`);\n rangeCircle.setAttribute(\"stroke-dashoffset\", `${offset}`);\n } else {\n rangeCircle.setAttribute(\"stroke-dasharray\", \"\");\n rangeCircle.setAttribute(\"stroke-dashoffset\", \"\");\n }\n };\n}\n\nexport default PieView;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show VR enter button.\n * @ko VR 진입 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VRButton extends ControlBarItem {\n public readonly element: HTMLElement;\n\n private _viewer: View360 | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n this.element.title = \"Enter VR\";\n this._viewer = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n element.classList.add(className.UNAVAILABLE);\n element.classList.add(className.VR_BUTTON);\n element.classList.add(className.CONTROLS_BUTTON);\n\n viewer.vr.isAvailable()\n .then(available => {\n if (available) {\n element.classList.remove(className.UNAVAILABLE);\n }\n });\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._viewer = viewer;\n }\n\n public destroy() {\n const element = this.element;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n if (!viewer) return;\n\n viewer.vr.enter();\n };\n}\n\nexport default VRButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport GyroControl from \"../../control/GyroControl\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { sensorCanBeEnabledIOS } from \"../../utils\";\n\n/**\n * Show gyroscope control enable / disable button\n * @ko 자이로스코프 컨트롤 활성화 / 비활성화 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass GyroButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _viewer: View360 | null;\n private _controlBar: ControlBar | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n this.element.title = \"Toggle gyroscope control\";\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.add(className.UNAVAILABLE);\n\n const enableButton = () => {\n element.classList.remove(className.UNAVAILABLE);\n viewer.control.gyro.on(CONTROL_EVENTS.ENABLE, this._updateStyle);\n viewer.control.gyro.on(CONTROL_EVENTS.DISABLE, this._updateStyle);\n };\n\n if (sensorCanBeEnabledIOS()) {\n enableButton();\n } else {\n GyroControl.isAvailable().then(available => {\n if (!available) return;\n enableButton();\n });\n }\n\n this._controlBar = controlBar;\n this._viewer = viewer;\n this._updateStyle();\n }\n\n public destroy(viewer: View360) {\n const element = this.element;\n\n viewer.control.gyro.off(CONTROL_EVENTS.ENABLE, this._updateStyle);\n viewer.control.gyro.off(CONTROL_EVENTS.DISABLE, this._updateStyle);\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.className = \"\";\n\n this._controlBar = null;\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n const controlBar = this._controlBar;\n\n if (!viewer || !controlBar) return;\n\n const gyroControl = viewer.control.gyro;\n if (gyroControl.enabled) {\n gyroControl.disable();\n } else {\n GyroControl.requestSensorPermission().then(available => {\n if (available) {\n gyroControl.enable();\n } else {\n this.element.classList.add(controlBar.className.UNAVAILABLE);\n }\n });\n }\n };\n\n private _updateStyle = () => {\n const element = this.element;\n const viewer = this._viewer;\n const controlBar = this._controlBar;\n\n if (!viewer || !controlBar) return;\n\n const gyroControl = viewer.control.gyro;\n const className = controlBar.className;\n\n if (gyroControl.enabled) {\n element.classList.add(className.GYRO_ENABLED);\n element.classList.remove(className.GYRO_DISABLED);\n } else {\n element.classList.add(className.GYRO_DISABLED);\n element.classList.remove(className.GYRO_ENABLED);\n }\n };\n}\n\nexport default GyroButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport { FULLSCREEN_CHANGE } from \"../../const/browser\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport { isFullscreen } from \"../../utils\";\n\n/**\n * Options for ControlBar's {@link ControlBarOptions#autoHide}\n * @ko ControlBar의 {@link ControlBarOptions#autoHide}용 옵션\n * @category Plugin\n * @since 4.0.0\n */\nexport interface AutoHideOptions {\n /**\n * Initial delay before the control bar hides (ms)\n * @ko 컨트롤바가 처음으로 표시되고 사라지기까지 걸리는 시간 (ms)\n * @default 3000\n * @since 4.0.0\n */\n initialDelay: number;\n /**\n * Delay time before hiding the control bar after mouse leave (ms)\n * @ko 마우스가 컨트롤바 영역을 떠난 뒤 컨트롤바가 사라지기까지 걸리는 시간 (ms)\n * @default 0\n * @since 4.0.0\n */\n delay: number;\n /**\n * Delay time before hiding the control bar becomes active, like touch on mobile device or mouse move in fullscreen mode (ms)\n * @ko 모바일이나 풀스크린 환경 등에서 사용자 입력이 없을 때 컨트롤바가 사라지기까지 걸리는 시간 (ms)\n * @default 3000\n * @since 4.0.0\n */\n idleDelay: number;\n}\n\nclass AutoHide {\n private _initialDelay: AutoHideOptions[\"initialDelay\"];\n private _delay: AutoHideOptions[\"delay\"];\n private _idleDelay: AutoHideOptions[\"idleDelay\"];\n\n private _controlBar: ControlBar;\n private _timer: number;\n private _isGrabbing: boolean;\n private _isCursorInside: boolean;\n private _isFullscreen: boolean;\n private _targetEl: HTMLElement | null;\n private _video: TextureVideo | null;\n\n public get enabled() { return !!this._targetEl; }\n public get hidden() { return this._controlBar.containerEl.classList.contains(this._hiddenClass); }\n\n private get _hiddenClass() { return this._controlBar.className.HIDDEN; }\n private get _fixedClass() { return this._controlBar.className.FIXED; }\n\n public constructor(controlBar: ControlBar, {\n initialDelay = 3000,\n delay = 0,\n idleDelay: activationDelay = 3000\n }: Partial) {\n this._controlBar = controlBar;\n this._initialDelay = initialDelay;\n this._delay = delay;\n this._idleDelay = activationDelay;\n this._timer = -1;\n this._isCursorInside = false;\n this._isGrabbing = false;\n this._isFullscreen = false;\n this._video = null;\n this._targetEl = null;\n }\n\n public enable(viewer: View360) {\n if (this._targetEl) {\n this.disable(viewer);\n }\n\n const initialDelay = this._initialDelay;\n const root = viewer.rootEl;\n\n this._targetEl = viewer.rootEl;\n this._timer = window.setTimeout(() => {\n this.hide();\n }, initialDelay);\n\n root.addEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onHold);\n root.addEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter);\n root.addEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove);\n root.addEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave);\n this._addFullscreenHandlers();\n\n const video = viewer.projection?.getTexture();\n if (!video || !video.isVideo()) {\n return;\n }\n\n if (video.isPaused()) {\n this._controlBar.containerEl.classList.add(this._fixedClass);\n }\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onVideoPlay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onVideoPause);\n\n this._video = video;\n }\n\n public disable(viewer: View360) {\n if (!this._targetEl) return;\n\n const controlBar = this._controlBar;\n const root = viewer.rootEl;\n const video = this._video;\n\n root.removeEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onHold);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave);\n this._removeFullscreenHandlers();\n\n window.clearTimeout(this._timer);\n controlBar.containerEl.classList.remove(this._fixedClass);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onVideoPlay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onVideoPause);\n }\n\n this._isCursorInside = false;\n this._isGrabbing = false;\n this._video = null;\n this._targetEl = null;\n }\n\n public show() {\n this._clearHideTimer();\n this._controlBar.containerEl.classList.remove(this._hiddenClass);\n }\n\n public showTemporaliy() {\n this.show();\n this._hideAfterDelay(this._idleDelay);\n }\n\n public hide() {\n this._clearHideTimer();\n this._controlBar.containerEl.classList.add(this._hiddenClass);\n }\n\n private _clearHideTimer() {\n if (this._timer) {\n window.clearTimeout(this._timer);\n this._timer = -1;\n }\n }\n\n private _hideAfterDelay(delay = this._delay) {\n if (this._isGrabbing || (!this._isFullscreen && this._isCursorInside)) return;\n\n this._clearHideTimer();\n if (delay <= 0) {\n this.hide();\n } else {\n this._timer = window.setTimeout(() => {\n this.hide();\n }, delay);\n }\n }\n\n private _onMouseEnter = () => {\n this._isCursorInside = true;\n this.show();\n };\n\n private _onMouseLeave = () => {\n this._isCursorInside = false;\n this._hideAfterDelay();\n };\n\n private _onMouseMove = () => {\n if (!this._isFullscreen) return;\n\n this.showTemporaliy();\n }\n\n private _onHold = (evt: PointerEvent) => {\n this._isGrabbing = true;\n\n if (evt.pointerType === \"mouse\") {\n this._isCursorInside = true;\n }\n\n window.addEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n\n this.show();\n };\n\n private _onRelease = () => {\n this._isGrabbing = false;\n\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n\n this._hideAfterDelay();\n };\n\n private _onVideoPlay = () => {\n const root = this._targetEl;\n if (!root) return;\n\n this._controlBar.containerEl.classList.remove(this._fixedClass);\n };\n\n private _onVideoPause = () => {\n const root = this._targetEl;\n if (!root) return;\n\n this._controlBar.containerEl.classList.add(this._fixedClass);\n };\n\n private _addFullscreenHandlers() {\n FULLSCREEN_CHANGE.forEach(evtName => {\n document.addEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _removeFullscreenHandlers() {\n FULLSCREEN_CHANGE.forEach(evtName => {\n document.removeEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _onFullscreenChange = () => {\n this._isFullscreen = isFullscreen();\n\n if (this._isFullscreen) {\n this._hideAfterDelay();\n }\n };\n}\n\nexport default AutoHide;\n","import TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { clamp } from \"../../utils\";\nimport { VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\n\nclass VideoControl {\n private _video: TextureVideo | null;\n\n public enable(root: HTMLElement, video: TextureVideo) {\n this._video = video;\n // capture is needed for resolving conflict with keyboard control\n root.addEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown, true);\n }\n\n public disable(root: HTMLElement) {\n this._video = null;\n root.removeEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown, true);\n }\n\n private _onKeyDown = (event: KeyboardEvent) => {\n const video = this._video;\n if (!video) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n const videoEl = video.source;\n const keyPressed = event.keyCode != null\n ? BROWSER.DIRECTION_KEY_CODE[event.keyCode]\n : BROWSER.DIRECTION_KEY_NAME[event.key];\n\n switch (keyPressed) {\n case \"LEFT\":\n case \"RIGHT\":\n return this._changeVideoTime(videoEl, keyPressed === \"RIGHT\");\n case \"UP\":\n case \"DOWN\":\n return this._changeVideoVolume(videoEl, keyPressed === \"UP\");\n }\n\n const spacePressed = event.keyCode === BROWSER.SPACE_KEY_CODE || event.key === BROWSER.SPACE_KEY_NAME;\n if (spacePressed) {\n this._toggleVideo(video);\n }\n }\n\n private _changeVideoTime(video: HTMLVideoElement, forward: boolean) {\n const delta = forward ? 5 : -5;\n\n video.currentTime += delta;\n video.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time: video.currentTime }}));\n }\n\n private _changeVideoVolume(video: HTMLVideoElement, increase: boolean) {\n const delta = increase ? 0.1 : -0.1;\n\n if (video.muted) {\n video.volume = clamp(delta, 0, 1);\n } else {\n video.volume = clamp(video.volume + delta, 0, 1);\n }\n\n if (video.volume > 0) {\n video.muted = false;\n } else {\n video.muted = true;\n }\n }\n\n private _toggleVideo(video: TextureVideo) {\n if (video.isPaused()) {\n video.source.play();\n } else {\n video.source.pause();\n }\n }\n}\n\nexport default VideoControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport ProgressBar from \"./ProgressBar\";\nimport PlayButton from \"./PlayButton\";\nimport VolumeControl from \"./VolumeControl\";\nimport FullscreenButton from \"./FullscreenButton\";\nimport VideoTime from \"./VideoTime\";\nimport PieView, { PieViewOptions } from \"./PieView\";\nimport VRButton from \"./VRButton\";\nimport GyroButton from \"./GyroButton\";\nimport AutoHide, { AutoHideOptions } from \"./AutoHide\";\nimport VideoControl from \"./VideoControl\";\nimport View360, { View360Events } from \"../../View360\";\nimport View360Plugin from \"../View360Plugin\";\nimport { EVENTS } from \"../../const/external\";\nimport { createElement, findIndex, getObjectOption } from \"../../utils\";\nimport { ValueOf } from \"../../type/utils\";\nimport { StaticClickEvent } from \"../../type/events\";\nimport { CONTROL_BAR_DEFAULT_CLASS, CONTROL_BAR_ITEM_POSITION } from \"./const\";\n\n/**\n * Options for {@link ControlBar}\n * @ko {@link ControlBar}용 옵션들\n * @category Plugin\n * @since 4.0.0\n */\nexport interface ControlBarOptions {\n /**\n * @copy ControlBar#autoHide\n */\n autoHide: boolean | Partial;\n /**\n * @copy ControlBar#showBackground\n */\n showBackground: boolean;\n /**\n * @copy ControlBar#clickToPlay\n */\n clickToPlay: boolean;\n /**\n * @copy ControlBar#keyboardControls\n */\n keyboardControls: boolean;\n /**\n * @copy ControlBar#progressBar\n */\n progressBar: boolean | Partial;\n /**\n * @copy ControlBar#playButton\n */\n playButton: boolean | Partial;\n /**\n * @copy ControlBar#volumeButton\n */\n volumeButton: boolean | Partial;\n /**\n * @copy ControlBar#fullscreenButton\n */\n fullscreenButton: boolean | Partial;\n /**\n * @copy ControlBar#videoTime\n */\n videoTime: boolean | Partial;\n /**\n * @copy ControlBar#pieView\n */\n pieView: boolean | Partial;\n /**\n * @copy ControlBar#vrButton\n */\n vrButton: boolean | Partial;\n /**\n * @copy ControlBar#gyroButton\n */\n gyroButton: boolean | Partial;\n /**\n * @copy ControlBar#className\n */\n className: Partial<{ -readonly [key in keyof typeof ControlBar.DEFAULT_CLASS]: string }>;\n /**\n * @copy ControlBar#customItems\n */\n customItems: ControlBarItem[];\n}\n\n/**\n * A plugin that displays extra buttons & controls that controls {@link View360}.\n * @ko {@link View360}에 부가적인 버튼과 컨트롤을 추가해주는 플러그인.\n * @category Plugin\n * @since 4.0.0\n */\nclass ControlBar implements View360Plugin {\n /**\n * Default class names that ControlBar uses\n * @ko ControlBar가 사용하는 디폴트 클래스 이름들\n * @since 4.0.0\n */\n public static readonly DEFAULT_CLASS = CONTROL_BAR_DEFAULT_CLASS;\n\n /**\n * Constants for {@link ControlBarItemOptions#position}\n * @ko {@link ControlBarItemOptions#position}에 사용 가능한 값들\n */\n public static readonly POSITION = CONTROL_BAR_ITEM_POSITION;\n\n /**\n * Automatically hide control bar on video plays.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 재생시 자동으로 컨트롤바를 숨깁니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly autoHide?: ControlBarOptions[\"autoHide\"];\n /**\n * Show background element.\n * @ko 배경 엘리먼트를 표시합니다.\n * @since 4.0.0\n */\n public readonly showBackground?: ControlBarOptions[\"showBackground\"];\n /**\n * Whether to play / pause video on canvas click\n * @ko 캔버스 클릭시에 비디오를 재생 / 일시정지 토글합니다.\n * @since 4.0.0\n */\n public readonly clickToPlay: ControlBarOptions[\"clickToPlay\"];\n /**\n * Enable keyboard controls for video.\n * Pressing up / down arrow will control video volume, and pressing left / right arrow will control video time.\n * @ko 비디오 키보드 컨트롤을 활성화합니다.\n * 위 / 아래 화살표키를 누를 시 비디오 볼륨을, 왼쪽 / 오른쪽 화살표키를 누를 시 비디오 시간을 조정합니다.\n * @since 4.0.0\n */\n public readonly keyboardControls: ControlBarOptions[\"keyboardControls\"];\n /**\n * Show video progress bar.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 프로그레스 바를 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly progressBar: ControlBarOptions[\"progressBar\"];\n /**\n * Show video play / pause button.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 재생 / 일시정지 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly playButton: ControlBarOptions[\"playButton\"];\n /**\n * Show video volume control button.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 볼륨 조절 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly volumeButton: ControlBarOptions[\"volumeButton\"];\n /**\n * Show fullscreen button.\n * `true` to enable with default values, `false` to disable.\n * @ko 풀스크린 진입 / 해제 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly fullscreenButton: ControlBarOptions[\"fullscreenButton\"];\n /**\n * Show video current / total time\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오의 현재 시간 / 총 시간을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly videoTime: ControlBarOptions[\"videoTime\"];\n /**\n * Show camera pie view.\n * `true` to enable with default values, `false` to disable.\n * @ko 현재 카메라가 가리키는 방향을 표시하는 파이 뷰를 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly pieView: ControlBarOptions[\"pieView\"];\n /**\n * Show VR button.\n * `true` to enable with default values, `false` to disable.\n * @ko VR 진입버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly vrButton: ControlBarOptions[\"vrButton\"];\n /**\n * Show gyroscope control enable / disable button.\n * `true` to enable with default values, `false` to disable.\n * @ko 자이로스코프 컨트롤을 활성화 / 비활성화하는 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly gyroButton: ControlBarOptions[\"gyroButton\"];\n /**\n * Override default class names.\n * @ko 디폴트 클래스 이름들을 오버라이드합니다.\n * @since 4.0.0\n */\n public readonly className: Required;\n\n /**\n * Root element of the control bar\n * @ko 컨트롤바의 루트 엘리먼트\n * @since 4.0.0\n */\n public get rootEl() { return this._rootEl; }\n /**\n * Container element of the control bar\n * @ko 컨트롤바의 컨테이너 엘리먼트\n * @since 4.0.0\n */\n public get containerEl() { return this._containerEl; }\n /**\n * Background element of the control bar\n * @ko 컨트롤바의 배경 엘리먼트\n * @since 4.0.0\n */\n public get backgroundEl() { return this._bgEl; }\n /**\n * Control bar's default items created by {@link ControlBarOptions}\n * @ko 주어진 {@link ControlBarOptions}에 의해 생성된 디폴트 아이템들\n * @since 4.0.0\n */\n public get items() { return this._items; }\n /**\n * Custom control bar items\n * @ko 커스텀 컨트롤바 아이템들을 추가합니다.\n * @since 4.0.0\n */\n public get customItems() { return this._customItems; }\n\n private _rootEl: HTMLElement;\n private _containerEl: HTMLElement;\n private _bgEl: HTMLElement;\n private _wrapperEl: Record, HTMLElement>;\n private _items: Record, ControlBarItem[]>;\n private _customItems: ControlBarItem[];\n private _autoHider: AutoHide;\n private _videoControl: VideoControl;\n\n /**\n * Create new instance of ControlBar.\n * @ko ControlBar의 새 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n autoHide,\n showBackground,\n clickToPlay = true,\n keyboardControls = true,\n progressBar = true,\n playButton = true,\n volumeButton = true,\n fullscreenButton = true,\n videoTime = true,\n pieView = true,\n vrButton = true,\n gyroButton = true,\n className = {},\n customItems = []\n }: Partial = {}) {\n this.autoHide = autoHide;\n this.showBackground = showBackground;\n this.clickToPlay = clickToPlay;\n this.keyboardControls = keyboardControls;\n this.progressBar = progressBar;\n this.playButton = playButton;\n this.volumeButton = volumeButton;\n this.fullscreenButton = fullscreenButton;\n this.videoTime = videoTime;\n this.pieView = pieView;\n this.vrButton = vrButton;\n this.gyroButton = gyroButton;\n this.className = {\n ...ControlBar.DEFAULT_CLASS,\n ...className\n };\n\n const rootClass = className.CONTROLS_ROOT ?? ControlBar.DEFAULT_CLASS.CONTROLS_ROOT;\n\n this._rootEl = createElement(rootClass);\n this._createPositionWrappers();\n this._items = Object.keys(ControlBar.POSITION).reduce((items, key) => {\n items[ControlBar.POSITION[key]] = [];\n return items;\n }, {}) as Record, ControlBarItem[]>;\n this._customItems = customItems;\n this._autoHider = new AutoHide(this, getObjectOption(autoHide));\n this._videoControl = new VideoControl();\n\n customItems.forEach(item => {\n this._items[item.position].push(item);\n });\n }\n\n public init(viewer: View360) {\n const panoRoot = viewer.rootEl;\n const controlsRoot = this._rootEl;\n const defaultItems = this._createDefaultItems();\n\n this._updateBackground(viewer);\n this._updateAutoHide(viewer);\n this._updateKeyboardHandler(viewer);\n\n panoRoot.appendChild(controlsRoot);\n this._addItem(viewer, defaultItems);\n this._addItem(viewer, this._customItems);\n\n viewer.on(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad);\n viewer.on(EVENTS.STATIC_CLICK, this._onStaticClick);\n }\n\n public destroy(viewer: View360): void {\n // Remove controls root from pano root\n const panoRoot = viewer.rootEl;\n const controlsRoot = this._rootEl;\n const items = this._items;\n\n if (controlsRoot.parentElement === panoRoot) {\n panoRoot.removeChild(controlsRoot);\n }\n\n Object.keys(items).forEach((key: ValueOf) => {\n const category = items[key];\n\n category.forEach(item => {\n item.destroy(viewer, this);\n });\n\n items[key] = [];\n });\n\n this._clearItemElements();\n this._autoHider.disable(viewer);\n this._videoControl.disable(panoRoot);\n\n viewer.off(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad);\n viewer.off(EVENTS.STATIC_CLICK, this._onStaticClick);\n }\n\n private _addItem(viewer: View360, items: ControlBarItem[]) {\n for (const item of items) {\n const category = this._items[item.position];\n const wrapper = this._wrapperEl[item.position];\n\n const nextSiblingIndex = findIndex(category, sibling => sibling.order > item.order);\n\n if (nextSiblingIndex >= 0) {\n const nextSibling = category[nextSiblingIndex].element;\n category.splice(nextSiblingIndex, 0, item);\n wrapper.insertBefore(item.element, nextSibling);\n } else {\n category.push(item);\n wrapper.appendChild(item.element);\n }\n\n item.init(viewer, this);\n }\n }\n\n private _createPositionWrappers() {\n const className = {\n ...ControlBar.DEFAULT_CLASS,\n ...this.className\n };\n const rootEl = this._rootEl;\n\n // BG & FLOATING CONTROLS\n const backgroundEl = createElement(className.CONTROLS_BG);\n const floatLeftEl = createElement(className.CONTROLS_FLOAT_LEFT);\n const floatRightEl = createElement(className.CONTROLS_FLOAT_RIGHT);\n\n rootEl.appendChild(floatLeftEl);\n rootEl.appendChild(floatRightEl);\n\n // BOTTOM CONTROLS\n const container = createElement(className.CONTROLS_MAIN);\n const topWrapper = createElement(className.CONTROLS_TOP);\n const bottomWrapper = createElement(className.CONTROLS_BOTTOM);\n const midWrapper = createElement(className.CONTROLS_MID);\n const leftControlsWrapper = createElement(className.CONTROLS_LEFT);\n const rightControlsWrapper = createElement(className.CONTROLS_RIGHT);\n\n midWrapper.appendChild(leftControlsWrapper);\n midWrapper.appendChild(rightControlsWrapper);\n container.appendChild(backgroundEl);\n container.appendChild(topWrapper);\n container.appendChild(midWrapper);\n container.appendChild(bottomWrapper);\n rootEl.appendChild(container);\n\n this._bgEl = backgroundEl;\n this._containerEl = container;\n this._wrapperEl = {\n [ControlBar.POSITION.MAIN_TOP]: topWrapper,\n [ControlBar.POSITION.MAIN_LEFT]: leftControlsWrapper,\n [ControlBar.POSITION.MAIN_RIGHT]: rightControlsWrapper,\n [ControlBar.POSITION.MAIN_BOTTOM]: bottomWrapper,\n [ControlBar.POSITION.TOP_LEFT]: floatLeftEl,\n [ControlBar.POSITION.TOP_RIGHT]: floatRightEl\n };\n }\n\n private _clearItemElements() {\n const wrappers = Object.keys(ControlBar.POSITION).map(key => ControlBar.POSITION[key]);\n\n // Remove all elements inside wrappers\n wrappers.forEach(wrapper => {\n while (wrapper.firstChild) {\n wrapper.removeChild(wrapper.firstChild);\n }\n });\n }\n\n private _onStaticClick = ({ target: viewer, isTouch }: StaticClickEvent) => {\n const autoHider = this._autoHider;\n\n if (isTouch) {\n if (!autoHider.enabled) return;\n\n if (autoHider.hidden) {\n autoHider.showTemporaliy();\n } else {\n autoHider.hide();\n }\n } else {\n if (!this.clickToPlay) return;\n\n const video = viewer.projection?.getTexture();\n if (!video || !video.isVideo()) return;\n\n if (video.isPaused()) {\n video.source.play();\n } else {\n video.source.pause();\n }\n }\n };\n\n private _onNewSrcLoad = ({ target: viewer }: View360Events[\"projectionChange\"]) => {\n const items = this._items;\n\n this._updateBackground(viewer);\n this._updateAutoHide(viewer);\n this._updateKeyboardHandler(viewer);\n\n Object.keys(items).forEach((key: ValueOf) => {\n const category = items[key];\n\n category.forEach(item => {\n item.destroy(viewer, this);\n item.init(viewer, this);\n });\n });\n };\n\n private _updateAutoHide(viewer: View360) {\n const autoHide = this.autoHide;\n const autoHider = this._autoHider;\n\n if (autoHide != null) {\n if (autoHide) {\n autoHider.enable(viewer);\n } else {\n autoHider.disable(viewer);\n }\n } else {\n // Automatically choose whether to show background by content type\n const texture = viewer.projection?.getTexture();\n\n if (texture && texture.isVideo()) {\n // Enable auto hide when content type is video\n autoHider.enable(viewer);\n } else {\n autoHider.disable(viewer);\n }\n }\n }\n\n private _updateBackground(viewer: View360) {\n const background = this._bgEl;\n const showBackground = this.showBackground;\n const hiddenClass = this.className.HIDDEN ?? ControlBar.DEFAULT_CLASS.HIDDEN;\n\n if (showBackground != null) {\n if (showBackground) {\n background.classList.remove(hiddenClass);\n } else {\n background.classList.add(hiddenClass);\n }\n } else {\n // Automatically choose whether to show background by content type\n const texture = viewer.projection?.getTexture();\n\n if (texture && texture.isVideo()) {\n // Show bg when content type is video\n background.classList.remove(hiddenClass);\n } else {\n background.classList.add(hiddenClass);\n }\n }\n }\n\n private _updateKeyboardHandler(viewer: View360) {\n const panoRoot = viewer.rootEl;\n const videoControl = this._videoControl;\n const texture = viewer.projection?.getTexture();\n\n if (this.keyboardControls && texture && texture.isVideo()) {\n videoControl.enable(panoRoot, texture);\n } else {\n videoControl.disable(panoRoot);\n }\n }\n\n private _createDefaultItems(): ControlBarItem[] {\n const items: ControlBarItem[] = [];\n\n if (this.progressBar) {\n items.push(new ProgressBar(getObjectOption(this.progressBar)));\n }\n\n if (this.playButton) {\n items.push(new PlayButton(getObjectOption(this.playButton)));\n }\n\n if (this.volumeButton) {\n items.push(new VolumeControl(getObjectOption(this.volumeButton)));\n }\n\n if (this.gyroButton) {\n items.push(new GyroButton(getObjectOption(this.gyroButton)));\n }\n\n if (this.vrButton) {\n items.push(new VRButton(getObjectOption(this.vrButton)));\n }\n\n if (this.fullscreenButton) {\n items.push(new FullscreenButton(getObjectOption(this.fullscreenButton)));\n }\n\n if (this.videoTime) {\n items.push(new VideoTime(getObjectOption(this.videoTime)));\n }\n\n if (this.pieView) {\n items.push(new PieView(getObjectOption(this.pieView)));\n }\n\n return items;\n }\n}\n\nexport default ControlBar;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Camera from \"../core/Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport Texture from \"../texture/Texture\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport { VideoConfig } from \"../type/external\";\nimport UniformCanvasCube from \"../uniform/UniformCanvasCube\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport UniformTextureCube from \"../uniform/UniformTextureCube\";\n\ntype CommonProjectionUniforms = {\n uTexture: UniformTexture2D | UniformTextureCube | UniformCanvasCube;\n}\n\n/**\n * Common option for {@link Projection}s\n * @ko {@link Projection}을 위한 공통 옵션들\n * @category Projection\n * @since 4.0.0\n */\nexport interface ProjectionOptions {\n /**\n * @copy Projection#src\n */\n src: string | HTMLElement | Array;\n /**\n * @copy Projection#video\n */\n video?: boolean | Partial;\n}\n\n/**\n * Base class for projections.\n * @ko 프로젝션 베이스 클래스.\n * @category Projection\n * @since 4.0.0\n */\nabstract class Projection {\n /**\n * Source URL to panorama image/video.\n * @ko 파노라마 이미지/비디오의 URL\n * @since 4.0.0\n */\n public readonly src: ProjectionOptions[\"src\"];\n /**\n * Properties for the video element.\n * Setting `false` will treat panorama source as an image, `true` will use default properties.\n * @ko 비디오 엘리먼트에 설정할 프로퍼티를 담는 객체.\n * @since 4.0.0\n * @example\n * Default properties\n * ```ts\n * autoplay: true\n * muted: true\n * loop: false\n * volume: 1\n * ```\n */\n public readonly video: ProjectionOptions[\"video\"];\n\n protected _mesh: TriangleMesh | null;\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n src,\n video = false\n }: ProjectionOptions) {\n this.src = src;\n this.video = video;\n this._mesh = null;\n }\n\n /**\n * Apply texture to current projection.\n * @ko 주어진 텍스쳐를 현재 프로젝션에 적용합니다.\n * @param ctx - Instance of the WebGLContext helper {@ko WebGL context 헬퍼의 인스턴스}\n * @param texture - New texture to apply {@ko 새로 적용할 텍스쳐}\n * @internal\n * @since 4.0.0\n */\n public abstract applyTexture(ctx: WebGLContext, texture: Texture): void;\n\n /**\n * Release all resources projection has.\n * This is automatically called on projection change & View360's destroy call\n * @ko 현재 갖고 있는 모든 리소스를 반환합니다.\n * 이 메소드는 프로젝션 변경 및 View360의 destroy 호출 시 자동으로 호출됩니다.\n * @param ctx\n */\n public releaseAllResources(ctx: WebGLContext) {\n this._mesh?.destroy(ctx);\n }\n\n /**\n * Update camera to match projection's settings.\n * @ko 현재 프로젝션의 세팅으로 카메라를 업데이트합니다.\n * @param camera - Instance of the camera to update {@ko 업데이트할 카메라의 인스턴스}\n * @since 4.0.0\n */\n public updateCamera(camera: Camera) {\n // Use default mode & no view restriction\n camera.resetRange();\n }\n\n /**\n * Update control to match projection's settings.\n * @ko 현재 프로젝션의 세팅으로 컨트롤을 업데이트합니다.\n * @param control - Instance of the control to update {@ko 업데이트할 컨트롤의 인스턴스}\n * @since 4.0.0\n */\n public updateControl(control: PanoControl) {\n control.ignoreZoomScale = false;\n }\n\n /**\n * Update projection.\n * @ko 현재 프로젝션 정보를 갱신합니다.\n * @param camera - Instance of the camera to reference {@ko 참조할 카메라의 인스턴스}\n * @since 4.0.0\n */\n public update(camera: Camera) {} // eslint-disable-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars\n\n /**\n * Return active texture.\n * @ko 현재 활성화된 텍스쳐를 반환합니다.\n * @internal\n * @since 4.0.0\n */\n public getTexture() {\n if (!this._mesh) return null;\n\n return this._mesh.program.uniforms.uTexture.texture;\n }\n\n /**\n * A 3D triangle mesh for projection. It's `null` until loading the `src`.\n * @ko Projection을 표시하기 위한 Mesh, src를 로드하기 전까지는 `null`입니다.\n * @since 4.0.0\n */\n public getMesh(): TriangleMesh | null {\n return this._mesh;\n }\n}\n\nexport default Projection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nabstract class Uniform {\n public needsUpdate: boolean;\n\n public constructor() {\n this.needsUpdate = true;\n }\n\n public abstract update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean): void;\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext) {\n // DO_NOTHING\n }\n}\n\nexport default Uniform;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport TextureCube from \"../texture/TextureCube\";\nimport { reorderCube } from \"../utils\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformTextureCube extends Uniform {\n public readonly texture: TextureCube;\n private _webglTexture: WebGLTexture;\n private _cubemapOrder: string;\n\n public constructor(ctx: WebGLContext, texture: TextureCube, cubemapOrder: string) {\n super();\n\n this.texture = texture;\n this._webglTexture = ctx.createWebGLCubeTexture(texture, texture.width);\n this._cubemapOrder = cubemapOrder;\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext): void {\n this.texture.destroy();\n gl.deleteTexture(this._webglTexture);\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture);\n\n const sources = reorderCube(texture.sources, this._cubemapOrder);\n sources.forEach((src, idx) => {\n if (isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src);\n } else {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src);\n }\n });\n\n if (!texture.isVideo()) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformTextureCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"../texture/Texture2D\";\nimport { range, reorderCube } from \"../utils\";\n\n/** @hidden */\nclass CubeTexturePainter {\n public readonly texture: Texture2D;\n private _renderingOrder: number[];\n private _canvas: HTMLCanvasElement;\n private _ctx: CanvasRenderingContext2D;\n private _row: number;\n private _column: number;\n private _size: number;\n\n public get size() { return this._size; }\n\n public constructor(texture: Texture2D, cubemapOrder: string) {\n this.texture = texture;\n this._renderingOrder = reorderCube(range(6), cubemapOrder);\n\n const canvas = document.createElement(\"canvas\");\n\n this._calcRenderingSize();\n\n canvas.width = this._size;\n canvas.height = this._size;\n\n this._canvas = canvas;\n this._ctx = canvas.getContext(\"2d\")!;\n }\n\n public destroy() {\n const canvas = this._canvas;\n\n // release memories\n canvas.width = 1;\n canvas.height = 1;\n this._canvas = null as any;\n }\n\n public draw(gl: WebGLRenderingContext | WebGL2RenderingContext, isWebGL2: boolean) {\n const size = this._size;\n const texture = this.texture;\n let surfaceIdx = 0;\n\n for (let row = 0; row < this._row; row++) {\n for (let column = 0; column < this._column; column++) {\n const x = size * column;\n const y = size * row;\n const renderingFace = this._renderingOrder[surfaceIdx];\n\n this._ctx.drawImage(texture.source as CanvasImageSource, x, y, size, size, 0, 0, size, size);\n\n if (isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas);\n } else {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas);\n }\n\n surfaceIdx++;\n }\n }\n }\n\n private _calcRenderingSize() {\n const {\n width,\n height\n } = this.texture;\n const aspect = width / height;\n\n if (aspect === 1 / 6) {\n this._size = width;\n this._row = 6;\n this._column = 1;\n } else if (aspect === 6) {\n this._size = height;\n this._row = 1;\n this._column = 6;\n } else if (aspect === 2 / 3) {\n this._size = width * 0.5;\n this._row = 3;\n this._column = 2;\n } else {\n this._size = width / 3;\n this._row = 2;\n this._column = 3;\n }\n }\n}\n\nexport default CubeTexturePainter;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport CubeTexturePainter from \"../core/CubeTexturePainter\";\nimport Texture2D from \"../texture/Texture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformCanvasCube extends Uniform {\n private _webglTexture: WebGLTexture;\n private _painter: CubeTexturePainter;\n\n public get texture() { return this._painter.texture; }\n\n public constructor(ctx: WebGLContext, texture: Texture2D, cubemapOrder: string) {\n super();\n\n this._painter = new CubeTexturePainter(texture as Texture2D, cubemapOrder);\n this._webglTexture = ctx.createWebGLCubeTexture(texture, this._painter.size);\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext) {\n gl.deleteTexture(this._webglTexture);\n this._painter.destroy();\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture);\n\n this._painter.draw(gl, isWebGL2);\n\n if (!texture.isVideo()) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformCanvasCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Object3D from \"./Object3D\";\nimport ShaderProgram from \"./ShaderProgram\";\nimport VertexArrayObject from \"./VertexArrayObject\";\nimport Uniform from \"../uniform/Uniform\";\nimport WebGLContext from \"./WebGLContext\";\n\n/**\n * @hidden\n */\nclass TriangleMesh = Record> extends Object3D {\n /**\n * @internal\n * Geometry data for projection\n */\n public readonly vao: VertexArrayObject;\n /**\n * @internal\n * Material(shader) data for projection\n */\n public readonly program: ShaderProgram;\n\n public constructor(vao: VertexArrayObject, program: ShaderProgram) {\n super();\n\n this.vao = vao;\n this.program = program;\n }\n\n public destroy(ctx: WebGLContext) {\n ctx.releaseVAO(this.vao);\n ctx.releaseShaderResources(this.program);\n }\n}\n\nexport default TriangleMesh;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"../uniform/Uniform\";\nimport WebGLContext from \"./WebGLContext\";\nimport { UniformLocations } from \"../type/internal\";\n\nclass ShaderProgram = Record> {\n public readonly program: WebGLProgram;\n public readonly uniforms: T;\n public readonly uniformLocations: UniformLocations;\n\n public constructor(ctx: WebGLContext, vertexShader: string, fragmentShader: string, uniforms: T) {\n this.program = ctx.createProgram(vertexShader, fragmentShader);\n this.uniforms = uniforms;\n this.uniformLocations = ctx.getUniformLocations(this.program, uniforms);\n }\n}\n\nexport default ShaderProgram;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { TypedArray } from \"../type/utils\";\n\n/**\n * @hidden\n */\nclass VertexData {\n public readonly data: T;\n public itemSize: number;\n public count: number;\n\n /** */\n public constructor(data: T, itemSize: number) {\n this.data = data;\n this.itemSize = itemSize;\n this.count = data.length / itemSize;\n }\n}\n\nexport default VertexData;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport VertexData from \"../core/VertexData\";\n\n/**\n * @hidden\n */\nabstract class Geometry {\n public readonly vertices: VertexData;\n public readonly indicies: VertexData;\n public readonly uvs: VertexData;\n\n /** */\n public constructor(vertices: number[], indicies: number[], uvs: number[]) {\n this.vertices = new VertexData(new Float32Array(vertices), 3);\n this.indicies = new VertexData(new Uint16Array(indicies), 1);\n this.uvs = new VertexData(new Float32Array(uvs), 2);\n }\n}\n\nexport default Geometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\nimport { ROTATE } from \"../const/internal\";\nimport { reorderCube } from \"../utils\";\n\n/**\n * @hidden\n */\nclass CubeGeometry extends Geometry {\n public constructor({\n order,\n rotateUV\n }: {\n order: string;\n rotateUV?: ROTATE[]\n }) {\n const vertices = [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // up\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // down\n -1, -1, 1,\n 1, -1, 1,\n 1, -1, -1,\n -1, -1, -1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n\n const indicies = [\n 0, 1, 2,\n 0, 2, 3,\n 4, 5, 6,\n 4, 6, 7,\n 8, 9, 10,\n 8, 10, 11,\n 12, 13, 14,\n 12, 14, 15,\n 16, 17, 18,\n 16, 18, 19,\n 20, 21, 22,\n 20, 22, 23\n ];\n\n const oneThird = 1 / 3;\n const coords: number[][] = [];\n\n for (let r = 1; r >= 0; r--) {\n for (let c = 0; c < 3; c++) {\n const coord = [\n c * oneThird, r * 0.5,\n (c + 1) * oneThird, r * 0.5,\n (c + 1) * oneThird, (r + 1) * 0.5,\n c * oneThird, (r + 1) * 0.5\n ];\n\n coords.push(coord);\n }\n }\n\n if (rotateUV) {\n rotateUV.forEach((degree, idx) => {\n if (degree === ROTATE.ZERO) return;\n\n const coord = coords[idx];\n let newOrder: number[];\n\n if (degree === ROTATE.CW_90) {\n newOrder = [1, 2, 3, 0];\n } else if (degree === ROTATE.CCW_90) {\n newOrder = [3, 0, 1, 2];\n } else {\n newOrder = [2, 3, 0, 1];\n }\n\n const newCoords = Array(coord.length);\n for (let uvIdx = 0; uvIdx < coord.length / 2; uvIdx++) {\n newCoords[uvIdx * 2 + 0] = coord[newOrder[uvIdx] * 2 + 0];\n newCoords[uvIdx * 2 + 1] = coord[newOrder[uvIdx] * 2 + 1];\n }\n\n coords[idx] = newCoords;\n });\n }\n\n const uvs = reorderCube(coords, order, \"BFUDRL\")\n .reduce((acc, val) => acc.concat(val), []);\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default CubeGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"../texture/Texture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformTexture2D extends Uniform {\n public readonly texture: Texture2D;\n private _webglTexture: WebGLTexture;\n\n public constructor(ctx: WebGLContext, texture: Texture2D) {\n super();\n\n this.texture = texture;\n this._webglTexture = ctx.createWebGLTexture(texture);\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext): void {\n this.texture.destroy();\n gl.deleteTexture(this._webglTexture);\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n const isVideo = texture.isVideo();\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._webglTexture);\n\n if (!isVideo && isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n } else {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n }\n\n if (!isVideo) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformTexture2D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass CylinderGeometry extends Geometry {\n public constructor(maxTheta: number) {\n const vertices: number[] = [];\n const indicies: number[] = [];\n const uvs: number[] = [];\n\n const height = 1;\n const radialSegments = 60;\n const halfHeight = height * 0.5;\n const heightSegments = [-halfHeight, halfHeight];\n const invRadialSegments = 1 / radialSegments;\n const angleConst = maxTheta * invRadialSegments;\n\n for (let yIdx = 0; yIdx < 2; yIdx++) {\n const y = heightSegments[yIdx];\n\n for (let lngIdx = 0; lngIdx <= radialSegments; lngIdx++) {\n const angle = lngIdx * angleConst + Math.PI - maxTheta * 0.5;\n const x = Math.cos(angle);\n const z = Math.sin(angle);\n const u = lngIdx * invRadialSegments;\n const v = yIdx;\n\n uvs.push(u, v);\n vertices.push(x, y, z);\n\n if (yIdx === 0 && lngIdx < radialSegments) {\n const a = lngIdx;\n const b = a + radialSegments + 1;\n\n indicies.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n }\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default CylinderGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass SphereGeometry extends Geometry {\n /** */\n public constructor() {\n // const radius = 1;\n const widthSegments = 60;\n const heightSegments = 60;\n const ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI;\n\n const uvs: number[] = [];\n const vertices: number[] = [];\n const indicies: number[] = [];\n let latIdx: number;\n let lngIdx: number;\n\n for (latIdx = 0; latIdx <= widthSegments; latIdx++) {\n const theta = (latIdx / widthSegments - 0.5) * Math.PI;\n const sinTheta = Math.sin(theta);\n const cosTheta = Math.cos(theta);\n\n for (lngIdx = 0; lngIdx <= heightSegments; lngIdx++) {\n const phi = (lngIdx / heightSegments - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN;\n const sinPhi = Math.sin(phi);\n const cosPhi = Math.cos(phi);\n const x = cosPhi * cosTheta;\n const y = sinTheta;\n const z = sinPhi * cosTheta;\n const u = lngIdx / heightSegments;\n const v = latIdx / widthSegments;\n\n uvs.push(u, v);\n vertices.push(x, y, z);\n\n if (lngIdx !== heightSegments && latIdx !== widthSegments) {\n const a = latIdx * (heightSegments + 1) + lngIdx;\n const b = a + heightSegments + 1;\n\n indicies.push(a, a + 1, b, b, a + 1, b + 1);\n }\n }\n }\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default SphereGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"./Uniform\";\n\nclass UniformFloat extends Uniform {\n public val: number;\n\n public constructor(val: number) {\n super();\n\n this.val = val;\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation) {\n gl.uniform1f(location, this.val);\n\n this.needsUpdate = false;\n }\n}\n\nexport default UniformFloat;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass PlaneGeometry extends Geometry {\n /** */\n public constructor(width: number = 2, height: number = 2, z: number = -1) {\n const halfWidth = width * 0.5;\n const halfHeight = height * 0.5;\n const vertices = [\n -halfWidth, -halfHeight, z,\n halfWidth, -halfHeight, z,\n -halfWidth, halfHeight, z,\n halfWidth, halfHeight, z\n ];\n const indicies = [\n 0, 1, 2,\n 2, 1, 3\n ];\n const uvs = [\n 0, 0,\n 1, 0,\n 0, 1,\n 1, 1\n ];\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default PlaneGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"./Uniform\";\n\nclass UniformVector4Array extends Uniform {\n public val: number[][];\n\n public constructor(val: number[][]) {\n super();\n\n this.val = val;\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation) {\n gl.uniform4fv(location, this.val.reduce((arr, vector) => [...arr, ...vector], []));\n\n this.needsUpdate = false;\n }\n}\n\nexport default UniformVector4Array;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport SphereGeometry from \"../geometry/SphereGeometry\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport UniformVector4Array from \"../uniform/UniformVector4Array\";\nimport UniformFloat from \"../uniform/UniformFloat\";\nimport vs from \"../shader/stereoequi.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link StereoEquiProjection}\n * @ko {@link StereoEquiProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface StereoEquiProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n /**\n * Stereoscopic mode of the image\n * @ko 이미지의 스테레오스코픽 모드\n * @since 4.0.0\n * @default \"top_bottom\"\n */\n mode: typeof StereoEquiProjection.MODE[keyof typeof StereoEquiProjection.MODE]\n}\n\n/**\n * Projection based on stereo equirectangular images.\n * @ko Stereo equirectangular 이미지 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass StereoEquiProjection extends Projection<{\n uTexture: UniformTexture2D;\n uEye: UniformFloat;\n uTexScaleOffset: UniformVector4Array;\n}> {\n /**\n * Available stereoscopic modes\n * @ko 사용가능한 스테레오스코픽 모드들\n * @since 4.0.0\n */\n public static MODE = {\n /**\n * @ko 이미지가 왼쪽/오른쪽으로 구성되어있을 경우\n * @since 4.0.0\n */\n LEFT_RIGHT: \"left_right\",\n /**\n * @ko 이미지가 위/아래로 구성되어있을 경우\n * @since 4.0.0\n */\n TOP_BOTTOM: \"top_bottom\",\n } as const;\n\n private _mode: StereoEquiProjectionOptions[\"mode\"];\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: StereoEquiProjectionOptions) {\n super(options);\n\n this._mode = options.mode;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n let leftEye: number[];\n let rightEye: number[];\n\n switch (this._mode) {\n case StereoEquiProjection.MODE.LEFT_RIGHT:\n leftEye = [0.5, 1, 0, 0];\n rightEye = [0.5, 1, 0.5, 0];\n break;\n default:\n // Default, uses \"top_bottom\"\n leftEye = [1, 0.5, 0, 0];\n rightEye = [1, 0.5, 0, 0.5];\n }\n\n\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture),\n uEye: new UniformFloat(0),\n uTexScaleOffset: new UniformVector4Array([leftEye, rightEye])\n };\n\n const geometry = new SphereGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default StereoEquiProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTextureCube from \"../uniform/UniformTextureCube\";\nimport UniformCanvasCube from \"../uniform/UniformCanvasCube\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport TextureCube from \"../texture/TextureCube\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/cube.vert\";\nimport fs from \"../shader/cube.frag\";\n\n/**\n * Options for {@link CubemapProjection}\n * @ko {@link CubemapProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CubemapProjectionOptions extends ProjectionOptions {\n /**\n * Order of the cubemap images.\n * @ko 큐브맵 이미지의 순서.\n * @since 4.0.0\n * @default \"RLUDFB\" (Right - Left - Up - Down - Front - Back)\n */\n cubemapOrder?: string;\n /**\n * Whether to flip cubemap image horizontally.\n * @ko 큐브맵 이미지를 좌우대칭할지 여부.\n * @since 4.0.0\n * @default false\n */\n cubemapFlipX?: boolean;\n}\n\n/**\n * Projection based on cubemap images, accepts both multiple or single images.\n * @ko 큐브맵 이미지 기반의 프로젝션, 단일 혹은 여러 장의 이미지를 모두 사용 가능합니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CubemapProjection extends Projection<{\n uTexture: UniformTextureCube | UniformCanvasCube;\n}> {\n private _cubemapOrder: NonNullable;\n private _cubemapFlipX: NonNullable;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CubemapProjectionOptions) {\n super(options);\n\n const {\n cubemapOrder = \"RLUDFB\",\n cubemapFlipX = false\n } = options;\n\n this._cubemapOrder = cubemapOrder;\n this._cubemapFlipX = cubemapFlipX;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const cubemapOrder = this._cubemapOrder;\n const cubemapFlipX = this._cubemapFlipX;\n const uniforms = {\n uTexture: texture.isCube()\n ? new UniformTextureCube(ctx, texture as TextureCube, cubemapOrder)\n : new UniformCanvasCube(ctx, texture as Texture2D, cubemapOrder)\n };\n\n const geometry = new CubeGeometry({\n order: cubemapOrder\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n if (cubemapFlipX) {\n mesh.scale[0] = -1;\n }\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n}\n\nexport default CubemapProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link CubestripProjection}\n * @ko {@link CubestripProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CubestripProjectionOptions extends ProjectionOptions {\n /**\n * @copy CubemapProjectionOptions#cubemapOrder\n */\n cubemapOrder?: string;\n /**\n * @copy CubemapProjectionOptions#cubemapFlipX\n */\n cubemapFlipX?: boolean;\n}\n\n/**\n * Projection based on cubemap strip.\n * Slightly more efficient than {@link CubemapProjection} as it doesn't copy cubemap image to canvas while rendering.\n * Accepts only single image.\n * @ko 큐브맵 스트립 기반의 프로젝션.\n * {@link CubemapProjection}와 달리 렌더링하는 과정에 캔버스에 이미지를 복사하는 과정이 없기 때문에 살짝 더 효율적입니다.\n * 단일 이미지만 사용 가능합니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CubestripProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n private _cubemapOrder: NonNullable;\n private _cubemapFlipX: NonNullable;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CubestripProjectionOptions) {\n super(options);\n\n const {\n cubemapOrder = \"RLUDFB\",\n cubemapFlipX = false\n } = options;\n\n this._cubemapOrder = cubemapOrder;\n this._cubemapFlipX = cubemapFlipX;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const cubemapOrder = this._cubemapOrder;\n const cubemapFlipX = this._cubemapFlipX;\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n const geometry = new CubeGeometry({\n order: cubemapOrder\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n if (cubemapFlipX) {\n mesh.scale[0] = -1;\n }\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n}\n\nexport default CubestripProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n*/\nimport { quat } from \"gl-matrix\";\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport CylinderGeometry from \"../geometry/CylinderGeometry\";\nimport Camera from \"../core/Camera\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"../const/internal\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\nimport TriangleMesh from \"../core/TriangleMesh\";\n\n/**\n * Options for {@link CylindricalProjection}\n * @ko {@link CylindricalProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CylindricalProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n /**\n * Whether the panorama image covers full 360 degrees.\n * @ko 파노라마 이미지가 360도를 전부 커버하는지 여부\n * @since 4.0.0\n * @default false\n */\n partial?: boolean;\n}\n\n/**\n * Projection based on cylindrical projection.\n * This can show panorama images taken from smartphones.\n * @ko 원통 투영법 기반의 프로젝션.\n * 일반적인 스마트폰 파노라마 사진을 표시하는데 사용될 수 있습니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CylindricalProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n private _partial: boolean;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CylindricalProjectionOptions) {\n super(options);\n\n const {\n partial = false\n } = options;\n\n this._partial = partial;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const partial = this._partial;\n const { width, height } = texture;\n const aspect = width / height;\n const halfVFov = 180 / aspect;\n const cylinderHeight = partial\n ? 1\n : 2 * Math.tan(halfVFov * DEG_TO_RAD);\n const cylinderTheta = partial\n ? aspect\n : 2 * Math.PI;\n\n const geometry = new CylinderGeometry(cylinderTheta);\n const program = new ShaderProgram(ctx, vs, fs, {\n uTexture: new UniformTexture2D(ctx, texture)\n });\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n mesh.scale[1] = cylinderHeight;\n quat.identity(mesh.rotation);\n quat.rotateY(mesh.rotation, mesh.rotation, -Math.PI / 2);\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n\n public updateCamera(camera: Camera) {\n super.updateCamera(camera);\n\n const mesh = this._mesh;\n if (!mesh) return;\n\n const uTexture = mesh.program.uniforms.uTexture;\n const texture = uTexture.texture;\n const { width, height } = texture;\n const aspect = width / height;\n const halfHeight = mesh.scale[1] * 0.5;\n\n if (this._partial) {\n const restrictedYaw = 0.5 * aspect * RAD_TO_DEG;\n camera.restrictYawRange(-restrictedYaw, restrictedYaw);\n }\n\n const restrictedPitch = Math.atan2(halfHeight, 1) * RAD_TO_DEG;\n const minZoom = Math.tan(camera.fov * DEG_TO_RAD * 0.5) / (halfHeight * camera.aspect);\n\n camera.restrictPitchRange(-restrictedPitch, restrictedPitch);\n camera.restrictZoomRange(minZoom, Infinity);\n camera.restrictRenderHeight(halfHeight * 2);\n }\n}\n\nexport default CylindricalProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/eac.frag\";\nimport { ROTATE } from \"../const/internal\";\n\n/**\n * Options for {@link EquiangularProjection}\n * @ko {@link EquiangularProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface EquiangularProjectionOptions extends ProjectionOptions {}\n\n/**\n * Equi-Angular Cubemap Projection.\n * This format is used by Youtube's 360 videos.\n * @ko Equi-Angular Cubemap 프로젝션.\n * 이 포맷은 주로 Youtube의 360 비디오에 사용됩니다.\n * @since 4.0.0\n * @category Projection\n */\nclass EquiangularProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n const geometry = new CubeGeometry({\n order: \"LFRDBU\",\n rotateUV: [\n ROTATE.ZERO, ROTATE.ZERO, ROTATE.ZERO,\n ROTATE.CW_90, ROTATE.CCW_90, ROTATE.CW_90\n ]\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default EquiangularProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport Texture2D from \"../texture/Texture2D\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport SphereGeometry from \"../geometry/SphereGeometry\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link EquirectProjection}\n * @ko {@link EquirectProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface EquirectProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n}\n\n/**\n * Projection based on equirectangular projection.\n * @ko 등 장방형 도법(Equirectangular projection) 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass EquirectProjection extends Projection<{\n uTexture: UniformTexture2D\n}> {\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: EquirectProjectionOptions) {\n super(options);\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n\n const geometry = new SphereGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default EquirectProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport UniformFloat from \"../uniform/UniformFloat\";\nimport Camera from \"../core/Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport Texture2D from \"../texture/Texture2D\";\nimport PlaneGeometry from \"../geometry/PlaneGeometry\";\nimport vs from \"../shader/little-planet.vert\";\nimport fs from \"../shader/little-planet.frag\";\nimport TriangleMesh from \"../core/TriangleMesh\";\n\n/**\n * Options for {@link LittlePlanetProjection}\n * @ko {@link LittlePlanetProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface LittlePlanetProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n}\n\n/**\n * Projection based on so-called \"Little planet\" or \"Tiny planet\" effect.\n * @ko \"Little planet\" 혹은 \"Tiny planet\"로 불리는 이펙트 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass LittlePlanetProjection extends Projection<{\n uTexture: UniformTexture2D;\n uYaw: UniformFloat;\n uPitch: UniformFloat;\n uZoom: UniformFloat;\n}> {\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: LittlePlanetProjectionOptions) {\n super(options);\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n texture.wrapS = WebGLRenderingContext.REPEAT;\n texture.wrapT = WebGLRenderingContext.REPEAT;\n\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture),\n uYaw: new UniformFloat(0),\n uPitch: new UniformFloat(0.5),\n uZoom: new UniformFloat(1)\n };\n\n const geometry = new PlaneGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n\n public updateControl(control: PanoControl) {\n control.ignoreZoomScale = true;\n }\n\n public update(camera: Camera) {\n const mesh = this._mesh;\n if (!mesh) return;\n\n const uniforms = mesh.program.uniforms;\n\n uniforms.uYaw.val = camera.yaw / 360;\n // Range from 0 ~ 1\n uniforms.uPitch.val = (camera.pitch / 180) + 0.5;\n uniforms.uZoom.val = camera.zoom;\n\n uniforms.uYaw.needsUpdate = true;\n uniforms.uPitch.needsUpdate = true;\n uniforms.uZoom.needsUpdate = true;\n }\n}\n\nexport default LittlePlanetProjection;\n","/**\n * @hidden\n */\nexport const getValidProps = (propsObj: any) => {\n return Object.keys(propsObj).reduce((props, propName) => {\n if (propsObj[propName] != null) {\n props[propName] = propsObj[propName];\n }\n\n return props;\n }, {});\n};\n","export const VIEW360_METHODS = [\n \"destroy\",\n \"init\",\n \"load\",\n \"resize\",\n \"addPlugins\",\n \"removePlugins\",\n \"renderFrame\",\n // @egjs/component methods\n \"on\",\n \"hasOn\",\n \"once\",\n \"off\",\n \"trigger\"\n] as const;\n","import Component from \"@egjs/component\";\nimport View360 from \"../View360\";\n\n/**\n * @hidden\n */\nconst withMethods = (prototype: any, attr: string) => {\n [Component.prototype, View360.prototype].forEach(proto => {\n Object.getOwnPropertyNames(proto)\n .filter(name => name.charAt(0) !== \"_\" && name !== \"constructor\")\n .forEach((name: string) => {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name)!;\n\n if (descriptor.value) {\n // Public Function\n Object.defineProperty(prototype, name, {\n value: function(...args) {\n return descriptor.value.call(this[attr], ...args);\n }\n });\n } else {\n const getterDescriptor: { get?: () => any; set?: (val: any) => void } = {};\n if (descriptor.get) {\n getterDescriptor.get = function() {\n return this[attr] && descriptor.get?.call(this[attr]);\n };\n }\n if (descriptor.set) {\n getterDescriptor.set = function(...args) {\n return descriptor.set?.call(this[attr], ...args);\n };\n }\n\n Object.defineProperty(prototype, name, getterDescriptor);\n }\n });\n });\n};\n\nexport default withMethods;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360, * as modules from \"./index\";\nimport { merge } from \"./utils\";\n\nmerge(View360, modules);\n\nexport default View360;\n"],"names":["View360Error","Error","constructor","message","code","super","Object","setPrototypeOf","this","prototype","name","ERROR_CODES","WRONG_TYPE","WRONG_OPTION","ELEMENT_NOT_FOUND","CANVAS_NOT_FOUND","WEBGL_NOT_SUPPORTED","FAILED_CREATE_CONTEXT_2D","PROVIDE_PROJECTION_FIRST","FAILED_LINKING_PROGRAM","INSUFFICIENT_ARGS","ERROR","val","types","map","type","join","optionName","query","msg","shaderLog","EVENTS","EL_DIV","EL_BUTTON","MOUSE_BUTTON","CURSOR","KEY_DIRECTION","DIRECTION_KEY_CODE","DIRECTION_KEY_NAME","LEFT","UP","RIGHT","DOWN","FULLSCREEN_REQUEST","FULLSCREEN_ELEMENT","FULLSCREEN_EXIT","FULLSCREEN_CHANGE","DEFAULT_CLASS","CONTAINER","CANVAS","CTX_LOST","IN_VR","HOTSPOT_CONTAINER","HOTSPOT","HOTSPOT_VISIBLE","HOTSPOT_FLIP_X","HOTSPOT_FLIP_Y","READY","LOAD_START","LOAD","PROJECTION_CHANGE","RESIZE","BEFORE_RENDER","RENDER","INPUT_START","INPUT_END","VIEW_CHANGE","STATIC_CLICK","VR_START","VR_END","EASING","LINEAR","x","SINE_WAVE","Math","sin","PI","EASE_OUT_CUBIC","pow","EASE_OUT_BOUNCE","n1","d1","CAMERA_EVENTS","CONTROL_EVENTS","DEG_TO_RAD","RAD_TO_DEG","DEFAULT_EASING","DEFAULT_ANIMATION_DURATION","INFINITE_RANGE","min","Infinity","max","DEFAULT_PITCH_RANGE","DEFAULT_ZOOM_RANGE","ROTATE","VIDEO_TIME_CHANGE_EVENT","SVG_NAMESPACE","SESSION_VR","XR_REFERENCE_SPACE","EPSILON","_a","Number","isString","createElement","className","tag","BROWSER","el","document","classList","add","getNullableElement","parent","targetEl","queryResult","querySelector","nodeType","Node","ELEMENT_NODE","clamp","lerp","a","b","t","circulate","size","abs","findIndex","array","checker","idx","length","getObjectOption","toVerticalFov","fovRadian","aspect","atan","tan","reorderCube","arr","order","defaultOrder","split","face","indexOf","index","isFullscreen","key","sensorCanBeEnabledIOS","DeviceMotionEvent","window","isSecureContext","eulerToQuat","out","yaw","pitch","roll","quat","identity","pitchClamped","rotateY","rotateX","rotateZ","quatToEuler","quaternion","y","z","w","unit","test","atan2","view","vec3","fromValues","up","transformQuat","viewXZ","sqrt","Motion","_val","start","_start","end","_end","progress","_progress","activated","_activated","duration","_duration","loop","_loop","range","_range","easing","_easing","reset","update","deltaTime","prev","nextProgress","easedProgress","defaultVal","delta","setNewEndByDelta","setRange","CameraAnimation","_motion","camera","from","to","_camera","_from","_to","_finishPromise","Promise","resolve","_finish","getFinishPromise","motion","rotation","create","zoom","slerp","rotate","Camera","Component","_aspect","changed","_changed","yawRange","_initialYawRange","pitchRange","_initialPitchRange","zoomRange","_initialZoomRange","initialYaw","initialPitch","initialZoom","fov","rollOffset","position","animation","_up","_yawRange","_pitchRange","_zoomRange","_updateQuaternion","viewMatrix","mat4","projectionMatrix","_maxRenderHeight","destroy","off","resize","width","height","prevAspect","updateMatrix","lookAt","prevQuaternion","clone","prevZoom","zoomDiff","equals","normalized","normalize","isSameRotation","copy","animateTo","finishPromise","then","trigger","restrictYawRange","restrictPitchRange","restrictZoomRange","restrictRenderHeight","resetRange","getYawRange","yawLimit","maxRenderHeight","halfHFov","getHorizontalFov","minYaw","maxYaw","halfVFovRad","h","d","theta","getPitchRange","pitchLimit","minPitch","maxPitch","halfVFov","getVerticalFov","getZoomRange","limit","minFov","maxFov","currentFov","current","_getZoomedHorizontalFov","hFov","fovToZoom","baseFov","projMatrix","upDir","viewDir","vFov","perspective","onFrameRender","MouseInput","_onMouseDown","evt","_el","button","preventDefault","focus","_prevPos","clientX","clientY","addEventListener","_onMouseMove","_onMouseUp","srcEvent","isTouch","isKeyboard","prevPos","deltaX","deltaY","removeEventListener","scrolling","enable","element","disable","TouchInput","scrollable","_scrollable","_onTouchStart","touches","_scrolling","touch","_isFirstTouch","_onTouchMove","cancelable","_onTouchEnd","passive","KeyboardInput","active","pressed","_pressed","_onKeyDown","location","KeyboardEvent","DOM_KEY_LOCATION_STANDARD","_updateKeyPress","pressedCount","_getPressedKeyCount","repeat","_onKeyUp","_clearPressedKeys","_getDeltaByPressedKeys","reduce","obj","keyName","assign","event","isEnable","keyToUpdate","keyCode","filter","RotateControl","enabled","_enabled","enableBlocked","_enableBlocked","animating","_keyboardInput","_xMotion","_yMotion","_touchInput","pointerScale","_pointerScale","keyboardScale","_keyboardScale","disablePitch","_disablePitch","disableYaw","_disableYaw","disableKeyboard","_disableKeyboard","controlEl","_onInputStart","_changedWhileDragging","inputType","_onChange","invZoomScale","_zoomScale","screenScale","_screenScale","scale","scaledX","scaledY","_onInputEnd","_controlEl","_mouseInput","_bindInputs","xMotion","yMotion","keyboardInput","updateRange","setZoomScale","hfov","vfov","control","updateCursor","sync","mouseInput","touchInput","on","WheelInput","_onWheel","stopPropagation","_inputTimer","_clearTimer","_baseScale","setTimeout","capture","clearTimeout","PinchInput","prevDistance","_prevDistance","diff","pageX","pageY","distance","ZoomControl","_wheelInput","_scale","scaledDelta","_pinchInput","wheelInput","pinchInput","ROTATE_CONSTANT","PITCH_DELTA","YAW_DELTA_BY_ROLL","YAW_DELTA_BY_YAW","targetAxis","meshPoint","GyroInput","orientationUpdated","_orientationUpdated","ignoreRoll","_ignoreRoll","_onDeviceOrientation","prevOrientation","_orientation","alpha","beta","gamma","_needsCalibrate","_calibrateSensor","_updateScreenOrientation","screen","orientation","undefined","angle","_screenOrientation","_yawOrigin","_yawOffset","_updateRotation","collectDelta","prevRotation","_toEulerDelta","setInitialRotation","yawOrigin","sensorYaw","screenAngle","world","set","cos","multiply","prevQuat","currentQuat","_getDeltaYaw","_getDeltaPitch","prvQ","curQ","yawDeltaByYaw","_getRotationDelta","_extractPitchFromQuat","prevQ","rotateKind","curQuaternion","prevPoint","curPoint","rotateDirection","dot","cross","meshPoint2","meshPoint3","vecU","vecV","vecN","coefficientA","coefficientB","coefficientC","projectedPrevPoint","subtract","trigonometricRatio","acos","crossVec","thetaDirection","baseV","GyroControl","_input","static","onDeviceMotionChange","race","res","rotationRate","available","requestPermission","permissionState","catch","_updateYawPitch","input","yawDelta","pitchDelta","PanoControl","useGrabCursor","_useGrabCursor","_setCursor","disableContextMenu","_disableContextMenu","_blockContextMenu","_restoreContextMenu","_rotateControl","wheelScrollable","_zoomControl","ignoreZoomScale","_ignoreZoomScale","gyro","_gyroControl","_preventContextMenu","_onEnable","_onDisable","_onCameraAnimationEnd","_bindEvents","isAvailable","rotateControl","zoomControl","gyroControl","hfovToZoom","zoomScale","newCursor","style","cursor","Texture","flipY","wrapS","WebGLRenderingContext","CLAMP_TO_EDGE","wrapT","isVideo","isCube","Texture2D","source","TextureVideo","video","pause","removeAttribute","load","isPaused","paused","ended","readyState","hasAudio","audioTracks","webkitAudioDecodedByteCount","mozHasAudio","TextureCube","sources","TextureLoader","_loadChecker","ImReady","src","loadVideo","Array","isArray","loadCubeImage","imgSrc","loadImage","images","_toImageArray","_load","image","naturalWidth","naturalHeight","videoConfig","config","autoplay","muted","volume","_toVideoElement","currentTime","play","videoWidth","videoHeight","content","onLoad","loader","reject","once","errorCount","check","imgEl","Image","crossOrigin","HTMLVideoElement","playsInline","setAttribute","forEach","_appendSourceElement","querySelectorAll","HTMLSourceElement","sourceEl","appendChild","FrameAnimator","maxDeltaTime","context","_context","_rafId","_rafTimer","_lastUpdateTime","callback","_time","frame","time","Date","now","requestAnimationFrame","stop","cancelAnimationFrame","changeContext","AutoResizer","useResizeObserver","_useResizeObserver","onResize","_skipFirstResize","isFirstResize","_onResize","_resizeObserver","ResizeObserver","bbox","getBoundingClientRect","resizeImmediate","resizeObserver","observe","disconnect","Autoplay","playing","_interrupted","delay","_delay","delayOnMouseLeave","_delayOnMouseLeave","speed","_speed","pauseOnHover","_pauseOnHover","canInterrupt","_canInterrupt","disableOnInterrupt","_disableOnInterrupt","viewer","options","_clearTimeout","_setUninterruptedAfterDelay","_onGyroEnable","_onMouseEnter","_hovering","_onMouseLeave","_control","_element","_interruptionTimer","enableAfterDelay","XRManager","ctx","exit","_onSessionEnd","_xrSession","_xrRefSpace","_ctx","_options","xr","navigator","isSessionSupported","enter","requestSensorPermission","requiredFeatures","makeXRCompatible","session","requestSession","bindXRLayer","refSpace","requestReferenceSpace","_setSession","xrSession","canRender","getViewerPose","getEyeParams","pose","glLayer","renderState","baseLayer","views","viewport","getViewport","vMatrix","transform","inverse","matrix","pMatrix","Hotspot","HotspotRenderer","rootEl","renderer","_containerEl","_renderer","_hotspots","_zoom","refresh","container","hotspotEls","slice","apply","_parseHotspot","render","hotspots","halfWidth","halfHeight","centerTransform","zoomTransform","hotspot","relPos","transformMat4","remove","screenPos","vec2","yawStr","dataset","pitchStr","positionStr","parseFloat","_yawPitchToVec3","pos","defaultPos","yawRad","pitchRad","VertexArrayObject","count","geometry","indicies","buffers","WebGLContext","canvas","_canvas","maxTextureSize","_maxTextureSize","isWebGL2","_isWebGL2","supportVAO","_extensions","vao","lost","_contextLost","debug","_debug","_onContextLost","_onContextRestore","loseContext","init","gl","_getContext","_gl","getParameter","MAX_TEXTURE_SIZE","getExtension","bindBuffer","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","forceLoseContext","extension","forceRestoreContext","restoreContext","clear","COLOR_BUFFER_BIT","drawingBufferWidth","drawingBufferHeight","createVAO","shaderProgram","nativeVAO","_createNativeVAO","_createBuffer","uv","_bindNativeVAO","_supplyGeometryData","_unbindBuffers","draw","drawElements","TRIANGLES","UNSIGNED_SHORT","releaseVAO","_deleteNativeVAO","_deleteBuffer","getUniformLocations","program","uniforms","uniformLocations","keys","locations","getUniformLocation","_getCommonUniformLocations","updateCommonUniforms","entity","mvMatrix","uniformMatrix4fv","uMVMatrix","uPMatrix","updateVRUniforms","eyeIndex","uEye","uniform1f","updateUniforms","uniform","needsUpdate","releaseShaderResources","deleteProgram","useProgram","createProgram","vertexShader","fragmentShader","vs","_compileShader","VERTEX_SHADER","fs","FRAGMENT_SHADER","attachShader","bindAttribLocation","linkProgram","getProgramParameter","LINK_STATUS","getShaderParameter","COMPILE_STATUS","getShaderInfoLog","getProgramInfoLog","deleteShader","createWebGLTexture","texData","texture","createTexture","bindTexture","TEXTURE_2D","texParameteri","TEXTURE_MIN_FILTER","TEXTURE_MAG_FILTER","TEXTURE_WRAP_S","TEXTURE_WRAP_T","gl2","texStorage2D","RGBA8","createWebGLCubeTexture","TEXTURE_CUBE_MAP","attributes","getContextAttributes","xrCompatible","xrLayer","XRWebGLLayer","updateRenderState","bindXRFrame","bindFramebuffer","FRAMEBUFFER","framebuffer","useDefaultFrameBuffer","createBuffer","buffer","deleteBuffer","createVertexArray","ext","createVertexArrayOES","bindVertexArray","bindVertexArrayOES","deleteVertexArray","deleteVertexArrayOES","_supplyIndiciesData","_supplyAttributeData","vertices","uvs","bufferData","data","STATIC_DRAW","attribute","attribLocation","getAttribLocation","vertexAttribPointer","itemSize","FLOAT","enableVertexAttribArray","shader","createShader","shaderSource","compileShader","webglIdentifiers","contextAttributes","preserveDrawingBuffer","antialias","onWebglContextCreationError","e","statusMessage","identifier","getContext","WebGLRenderer","_elementSize","pixelRatio","_pixelRatio","canvasSize","devicePixelRatio","clientWidth","clientHeight","projection","mesh","getMesh","renderVR","vr","eyeParams","eye","View360","_rootEl","_vr","_hotspot","plugins","_plugins","_projection","_initialized","initialized","_autoplay","autoInit","_autoInit","autoResize","_autoResize","canvasSelector","_canvasSelector","tabIndex","_tabIndex","_animator","updateCamera","root","renderFrame","autoPlayer","_emit","_renderFrameOnDemand","getTexture","_renderVRFrame","_delta","getElement","findCanvas","selector","_autoResizer","_addEventHandlers","releaseAllResources","plugin","animator","_bindComponentEvents","_resizeComponents","_loadTexture","_applyProjection","hasAttribute","addPlugins","push","removePlugins","pluginIdx","splice","eventName","params","evtParams","target","prevProjection","applyTexture","updateControl","contentLoader","events","evtName","VERSION","Object3D","fromRotationTranslationScale","LoadingSpinner","_startLoading","_container","_detachElements","parentElement","removeChild","_createElements","ring","RING","ControlBarItem","CONTROL_BAR_DEFAULT_CLASS","CONTROLS_ROOT","CONTROLS_BG","CONTROLS_MAIN","CONTROLS_TOP","CONTROLS_BOTTOM","CONTROLS_MID","CONTROLS_LEFT","CONTROLS_RIGHT","CONTROLS_FLOAT_LEFT","CONTROLS_FLOAT_RIGHT","CONTROLS_BUTTON","PROGRESS_ROOT","VOLUME_ROOT","RANGE_ROOT","RANGE_TRACK","RANGE_THUMB","RANGE_FILLER","PLAY_BUTTON","PAUSE_BUTTON","UNMUTED_BUTTON","MUTED_BUTTON","FULLSCREEN_BUTTON","FULLSCREEN_EXIT_BUTTON","VR_BUTTON","GYRO_ENABLED","GYRO_DISABLED","VIDEO_TIME_DISPLAY","PIEVIEW_ROOT","FIXED","UNAVAILABLE","HIDDEN","CONTROL_BAR_ITEM_POSITION","TOP_LEFT","TOP_RIGHT","MAIN_TOP","MAIN_BOTTOM","MAIN_LEFT","MAIN_RIGHT","RangeControl","_onHold","_bbox","elX","scrollX","pageXOffset","clamepdX","thumbEl","_fixedClass","_onRelease","track","thumb","filler","draggable","trackEl","fillerEl","left","right","bottom","top","updateStyle","clampedProgress","ProgressBar","_rangeControl","_onTimeUpdate","_video","_currentTime","_onDurationChange","controlBar","_controlBar","dispatchEvent","CustomEvent","detail","_wasPaused","_playPromise","_onControl","rangeControl","unavailableClass","PlayButton","_onClick","_paused","_onPlay","title","_onPause","VolumeControl","_updateDisplay","disabled","_onVolumeChange","_buttonEl","containerEl","buttonEl","FullscreenButton","_targetEl","_exitFullscreen","_requestFullscreen","_onFullscreenChange","_fullscreenAvailable","_addFullscreenHandlers","_removeFullscreenHandlers","some","request","call","VideoTime","_onCustomTimeChange","timeMinute","floor","timeSeconds","timeSecondsFormatted","durationMinute","durationSeconds","durationSecondsFormatted","innerText","PieView","resetCamera","_viewer","_updatePie","piePath","_piePathEl","rangeCircle","_rangeCircleEl","halfFov","pieRadius","pieDeg","pieOffset","isFinite","radius","rangeDiff","offset","_createPieElements","rootClass","pieSVG","createElementNS","VRButton","GyroButton","_updateStyle","enableButton","AutoHide","hidden","contains","_hiddenClass","initialDelay","idleDelay","activationDelay","_isCursorInside","show","_hideAfterDelay","_isFullscreen","showTemporaliy","_isGrabbing","pointerType","_onVideoPlay","_onVideoPause","_initialDelay","_idleDelay","_timer","hide","_clearHideTimer","VideoControl","videoEl","keyPressed","_changeVideoTime","_changeVideoVolume","_toggleVideo","forward","increase","ControlBar","backgroundEl","_bgEl","items","_items","customItems","_customItems","autoHide","showBackground","clickToPlay","keyboardControls","progressBar","playButton","volumeButton","fullscreenButton","videoTime","pieView","vrButton","gyroButton","_onStaticClick","autoHider","_autoHider","_onNewSrcLoad","_updateBackground","_updateAutoHide","_updateKeyboardHandler","item","_createPositionWrappers","POSITION","_videoControl","panoRoot","controlsRoot","defaultItems","_createDefaultItems","_addItem","_clearItemElements","category","wrapper","_wrapperEl","nextSiblingIndex","sibling","nextSibling","insertBefore","floatLeftEl","floatRightEl","topWrapper","bottomWrapper","midWrapper","leftControlsWrapper","rightControlsWrapper","firstChild","background","hiddenClass","_b","videoControl","Projection","_mesh","uTexture","Uniform","UniformTextureCube","cubemapOrder","_webglTexture","_cubemapOrder","deleteTexture","pixelStorei","UNPACK_FLIP_Y_WEBGL","uniform1i","activeTexture","TEXTURE0","texSubImage2D","TEXTURE_CUBE_MAP_POSITIVE_X","RGBA","UNSIGNED_BYTE","texImage2D","CubeTexturePainter","_size","_renderingOrder","undef","_calcRenderingSize","surfaceIdx","row","_row","column","_column","renderingFace","drawImage","UniformCanvasCube","_painter","TriangleMesh","ShaderProgram","VertexData","Geometry","Float32Array","Uint16Array","CubeGeometry","rotateUV","oneThird","coords","r","c","coord","degree","ZERO","newOrder","CW_90","CCW_90","newCoords","uvIdx","acc","concat","UniformTexture2D","CylinderGeometry","maxTheta","heightSegments","invRadialSegments","angleConst","yIdx","lngIdx","u","v","SphereGeometry","ANGLE_CORRECTION_FOR_CENTER_ALIGN","latIdx","sinTheta","cosTheta","phi","sinPhi","UniformFloat","PlaneGeometry","UniformVector4Array","uniform4fv","vector","StereoEquiProjection","_mode","mode","leftEye","rightEye","MODE","LEFT_RIGHT","uTexScaleOffset","TOP_BOTTOM","cubemapFlipX","_cubemapFlipX","partial","_partial","cylinderHeight","cylinderTheta","restrictedYaw","restrictedPitch","minZoom","REPEAT","uYaw","uPitch","uZoom","propsObj","props","propName","withMethods","attr","proto","getOwnPropertyNames","charAt","descriptor","getOwnPropertyDescriptor","value","defineProperty","args","getterDescriptor","get","merge","srcs","modules"],"mappings":"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"} \ No newline at end of file diff --git a/demo/release/4.0.0-beta.4/dist/view360.pkgd.js b/demo/release/4.0.0-beta.4/dist/view360.pkgd.js new file mode 100644 index 000000000..1670f4248 --- /dev/null +++ b/demo/release/4.0.0-beta.4/dist/view360.pkgd.js @@ -0,0 +1,10532 @@ +/* +Copyright (c) 2023-present NAVER Corp. +name: @egjs/view360 +license: MIT +author: NAVER Corp. +repository: https://github.com/naver/egjs-view360 +version: 4.0.0-beta.4 +*/ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.View360 = factory()); +})(this, (function () { 'use strict'; + + /****************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function (resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + } + + /* + Copyright (c) NAVER Corp. + name: @egjs/component + license: MIT + author: NAVER Corp. + repository: https://github.com/naver/egjs-component + version: 3.0.4 + */ + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + function __values(o) { + var s = typeof Symbol === "function" && Symbol.iterator, + m = s && o[s], + i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { + value: o && o[i++], + done: !o + }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); + } + function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), + r, + ar = [], + e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } catch (error) { + e = { + error: error + }; + } finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } finally { + if (e) throw e.error; + } + } + return ar; + } + function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); + return ar; + } + + /* + * Copyright (c) 2015 NAVER Corp. + * egjs projects are licensed under the MIT license + */ + var isUndefined = function (value) { + return typeof value === "undefined"; + }; + + // This class name is not matched to file name intentionally + /** + * Event class to provide additional properties + * @ko Component에서 추가적인 프로퍼티를 제공하는 이벤트 클래스 + */ + var ComponentEvent = /*#__PURE__*/function () { + /** + * Create a new instance of ComponentEvent. + * @ko ComponentEvent의 새로운 인스턴스를 생성한다. + * @param eventType The name of the event.이벤트 이름. + * @param props An object that contains additional event properties.추가적인 이벤트 프로퍼티 오브젝트. + */ + function ComponentEvent(eventType, props) { + var e_1, _a; + this._canceled = false; + if (props) { + try { + for (var _b = __values(Object.keys(props)), _c = _b.next(); !_c.done; _c = _b.next()) { + var key = _c.value; + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + this[key] = props[key]; + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (_c && !_c.done && (_a = _b.return)) _a.call(_b); + } finally { + if (e_1) throw e_1.error; + } + } + } + this.eventType = eventType; + } + /** + * Stop the event. {@link ComponentEvent#isCanceled} will return `true` after. + * @ko 이벤트를 중단한다. 이후 {@link ComponentEvent#isCanceled}가 `true`를 반환한다. + */ + var __proto = ComponentEvent.prototype; + __proto.stop = function () { + this._canceled = true; + }; + /** + * Returns a boolean value that indicates whether {@link ComponentEvent#stop} is called before. + * @ko {@link ComponentEvent#stop}이 호출되었는지 여부를 반환한다. + * @return {boolean} A boolean value that indicates whether {@link ComponentEvent#stop} is called before.이전에 {@link ComponentEvent#stop}이 불려졌는지 여부를 반환한다. + */ + __proto.isCanceled = function () { + return this._canceled; + }; + return ComponentEvent; + }(); + + /** + * A class used to manage events in a component + * @ko 컴포넌트의 이벤트을 관리할 수 있게 하는 클래스 + */ + var Component = /*#__PURE__*/function () { + /** + * @support {"ie": "7+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.1+ (except 3.x)"} + */ + function Component() { + this._eventHandler = {}; + } + /** + * Trigger a custom event. + * @ko 커스텀 이벤트를 발생시킨다 + * @param {string | ComponentEvent} event The name of the custom event to be triggered or an instance of the ComponentEvent발생할 커스텀 이벤트의 이름 또는 ComponentEvent의 인스턴스 + * @param {any[]} params Event data to be sent when triggering a custom event 커스텀 이벤트가 발생할 때 전달할 데이터 + * @return An instance of the component itself컴포넌트 자신의 인스턴스 + * @example + * ```ts + * import Component, { ComponentEvent } from "@egjs/component"; + * + * class Some extends Component<{ + * beforeHi: ComponentEvent<{ foo: number; bar: string }>; + * hi: { foo: { a: number; b: boolean } }; + * someEvent: (foo: number, bar: string) => void; + * someOtherEvent: void; // When there's no event argument + * }> { + * some(){ + * if(this.trigger("beforeHi")){ // When event call to stop return false. + * this.trigger("hi");// fire hi event. + * } + * } + * } + * + * const some = new Some(); + * some.on("beforeHi", e => { + * if(condition){ + * e.stop(); // When event call to stop, `hi` event not call. + * } + * // `currentTarget` is component instance. + * console.log(some === e.currentTarget); // true + * + * typeof e.foo; // number + * typeof e.bar; // string + * }); + * some.on("hi", e => { + * typeof e.foo.b; // boolean + * }); + * // If you want to more know event design. You can see article. + * // https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F + * ``` + */ + var __proto = Component.prototype; + __proto.trigger = function (event) { + var params = []; + for (var _i = 1; _i < arguments.length; _i++) { + params[_i - 1] = arguments[_i]; + } + var eventName = event instanceof ComponentEvent ? event.eventType : event; + var handlers = __spread(this._eventHandler[eventName] || []); + if (handlers.length <= 0) { + return this; + } + if (event instanceof ComponentEvent) { + event.currentTarget = this; + handlers.forEach(function (handler) { + handler(event); + }); + } else { + handlers.forEach(function (handler) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + handler.apply(void 0, __spread(params)); + }); + } + return this; + }; + /** + * Executed event just one time. + * @ko 이벤트가 한번만 실행된다. + * @param {string} eventName The name of the event to be attached or an event name - event handler mapped object.등록할 이벤트의 이름 또는 이벤트 이름-핸들러 오브젝트 + * @param {function} handlerToAttach The handler function of the event to be attached 등록할 이벤트의 핸들러 함수 + * @return An instance of the component itself컴포넌트 자신의 인스턴스 + * @example + * ```ts + * import Component, { ComponentEvent } from "@egjs/component"; + * + * class Some extends Component<{ + * hi: ComponentEvent; + * }> { + * hi() { + * alert("hi"); + * } + * thing() { + * this.once("hi", this.hi); + * } + * } + * + * var some = new Some(); + * some.thing(); + * some.trigger(new ComponentEvent("hi")); + * // fire alert("hi"); + * some.trigger(new ComponentEvent("hi")); + * // Nothing happens + * ``` + */ + __proto.once = function (eventName, handlerToAttach) { + var _this = this; + if (typeof eventName === "object" && isUndefined(handlerToAttach)) { + var eventHash = eventName; + for (var key in eventHash) { + this.once(key, eventHash[key]); + } + return this; + } else if (typeof eventName === "string" && typeof handlerToAttach === "function") { + var listener_1 = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + handlerToAttach.apply(void 0, __spread(args)); + _this.off(eventName, listener_1); + }; + this.on(eventName, listener_1); + } + return this; + }; + /** + * Checks whether an event has been attached to a component. + * @ko 컴포넌트에 이벤트가 등록됐는지 확인한다. + * @param {string} eventName The name of the event to be attached 등록 여부를 확인할 이벤트의 이름 + * @return {boolean} Indicates whether the event is attached. 이벤트 등록 여부 + * @example + * ```ts + * import Component from "@egjs/component"; + * + * class Some extends Component<{ + * hi: void; + * }> { + * some() { + * this.hasOn("hi");// check hi event. + * } + * } + * ``` + */ + __proto.hasOn = function (eventName) { + return !!this._eventHandler[eventName]; + }; + /** + * Attaches an event to a component. + * @ko 컴포넌트에 이벤트를 등록한다. + * @param {string} eventName The name of the event to be attached or an event name - event handler mapped object.등록할 이벤트의 이름 또는 이벤트 이름-핸들러 오브젝트 + * @param {function} handlerToAttach The handler function of the event to be attached 등록할 이벤트의 핸들러 함수 + * @return An instance of a component itself컴포넌트 자신의 인스턴스 + * @example + * ```ts + * import Component, { ComponentEvent } from "@egjs/component"; + * + * class Some extends Component<{ + * hi: void; + * }> { + * hi() { + * console.log("hi"); + * } + * some() { + * this.on("hi",this.hi); //attach event + * } + * } + * ``` + */ + __proto.on = function (eventName, handlerToAttach) { + if (typeof eventName === "object" && isUndefined(handlerToAttach)) { + var eventHash = eventName; + for (var name in eventHash) { + this.on(name, eventHash[name]); + } + return this; + } else if (typeof eventName === "string" && typeof handlerToAttach === "function") { + var handlerList = this._eventHandler[eventName]; + if (isUndefined(handlerList)) { + this._eventHandler[eventName] = []; + handlerList = this._eventHandler[eventName]; + } + handlerList.push(handlerToAttach); + } + return this; + }; + /** + * Detaches an event from the component.
If the `eventName` is not given this will detach all event handlers attached.
If the `handlerToDetach` is not given, this will detach all event handlers for `eventName`. + * @ko 컴포넌트에 등록된 이벤트를 해제한다.
`eventName`이 주어지지 않았을 경우 모든 이벤트 핸들러를 제거한다.
`handlerToAttach`가 주어지지 않았을 경우 `eventName`에 해당하는 모든 이벤트 핸들러를 제거한다. + * @param {string?} eventName The name of the event to be detached 해제할 이벤트의 이름 + * @param {function?} handlerToDetach The handler function of the event to be detached 해제할 이벤트의 핸들러 함수 + * @return An instance of a component itself 컴포넌트 자신의 인스턴스 + * @example + * ```ts + * import Component, { ComponentEvent } from "@egjs/component"; + * + * class Some extends Component<{ + * hi: void; + * }> { + * hi() { + * console.log("hi"); + * } + * some() { + * this.off("hi",this.hi); //detach event + * } + * } + * ``` + */ + __proto.off = function (eventName, handlerToDetach) { + var e_1, _a; + // Detach all event handlers. + if (isUndefined(eventName)) { + this._eventHandler = {}; + return this; + } + // Detach all handlers for eventname or detach event handlers by object. + if (isUndefined(handlerToDetach)) { + if (typeof eventName === "string") { + delete this._eventHandler[eventName]; + return this; + } else { + var eventHash = eventName; + for (var name in eventHash) { + this.off(name, eventHash[name]); + } + return this; + } + } + // Detach single event handler + var handlerList = this._eventHandler[eventName]; + if (handlerList) { + var idx = 0; + try { + for (var handlerList_1 = __values(handlerList), handlerList_1_1 = handlerList_1.next(); !handlerList_1_1.done; handlerList_1_1 = handlerList_1.next()) { + var handlerFunction = handlerList_1_1.value; + if (handlerFunction === handlerToDetach) { + handlerList.splice(idx, 1); + if (handlerList.length <= 0) { + delete this._eventHandler[eventName]; + } + break; + } + idx++; + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (handlerList_1_1 && !handlerList_1_1.done && (_a = handlerList_1.return)) _a.call(handlerList_1); + } finally { + if (e_1) throw e_1.error; + } + } + } + return this; + }; + /** + * Version info string + * @ko 버전정보 문자열 + * @name VERSION + * @static + * @example + * Component.VERSION; // ex) 3.0.0 + * @memberof Component + */ + Component.VERSION = "3.0.4"; + return Component; + }(); + + /* + * Copyright (c) 2015 NAVER Corp. + * egjs projects are licensed under the MIT license + */ + // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-unsafe-assignment + var ComponentEvent$1 = ComponentEvent; + + /** + * Common utilities + * @module glMatrix + */ + // Configuration Constants + var EPSILON$1 = 0.000001; + var ARRAY_TYPE = typeof Float32Array !== 'undefined' ? Float32Array : Array; + if (!Math.hypot) Math.hypot = function () { + var y = 0, + i = arguments.length; + + while (i--) { + y += arguments[i] * arguments[i]; + } + + return Math.sqrt(y); + }; + + /** + * 3x3 Matrix + * @module mat3 + */ + + /** + * Creates a new identity mat3 + * + * @returns {mat3} a new 3x3 matrix + */ + + function create$5() { + var out = new ARRAY_TYPE(9); + + if (ARRAY_TYPE != Float32Array) { + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[5] = 0; + out[6] = 0; + out[7] = 0; + } + + out[0] = 1; + out[4] = 1; + out[8] = 1; + return out; + } + + /** + * 4x4 Matrix
Format: column-major, when typed out it looks like row-major
The matrices are being post multiplied. + * @module mat4 + */ + + /** + * Creates a new identity mat4 + * + * @returns {mat4} a new 4x4 matrix + */ + + function create$4() { + var out = new ARRAY_TYPE(16); + + if (ARRAY_TYPE != Float32Array) { + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + } + + out[0] = 1; + out[5] = 1; + out[10] = 1; + out[15] = 1; + return out; + } + /** + * Set a mat4 to the identity matrix + * + * @param {mat4} out the receiving matrix + * @returns {mat4} out + */ + + function identity$1(out) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = 1; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = 1; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Multiplies two mat4s + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the first operand + * @param {ReadonlyMat4} b the second operand + * @returns {mat4} out + */ + + function multiply$1(out, a, b) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a03 = a[3]; + var a10 = a[4], + a11 = a[5], + a12 = a[6], + a13 = a[7]; + var a20 = a[8], + a21 = a[9], + a22 = a[10], + a23 = a[11]; + var a30 = a[12], + a31 = a[13], + a32 = a[14], + a33 = a[15]; // Cache only the current line of the second matrix + + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3]; + out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + b0 = b[4]; + b1 = b[5]; + b2 = b[6]; + b3 = b[7]; + out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + b0 = b[8]; + b1 = b[9]; + b2 = b[10]; + b3 = b[11]; + out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + b0 = b[12]; + b1 = b[13]; + b2 = b[14]; + b3 = b[15]; + out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + return out; + } + /** + * Creates a matrix from a quaternion rotation, vector translation and vector scale + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.translate(dest, vec); + * let quatMat = mat4.create(); + * quat4.toMat4(quat, quatMat); + * mat4.multiply(dest, quatMat); + * mat4.scale(dest, scale) + * + * @param {mat4} out mat4 receiving operation result + * @param {quat4} q Rotation quaternion + * @param {ReadonlyVec3} v Translation vector + * @param {ReadonlyVec3} s Scaling vector + * @returns {mat4} out + */ + + function fromRotationTranslationScale(out, q, v, s) { + // Quaternion math + var x = q[0], + y = q[1], + z = q[2], + w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var xy = x * y2; + var xz = x * z2; + var yy = y * y2; + var yz = y * z2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + var sx = s[0]; + var sy = s[1]; + var sz = s[2]; + out[0] = (1 - (yy + zz)) * sx; + out[1] = (xy + wz) * sx; + out[2] = (xz - wy) * sx; + out[3] = 0; + out[4] = (xy - wz) * sy; + out[5] = (1 - (xx + zz)) * sy; + out[6] = (yz + wx) * sy; + out[7] = 0; + out[8] = (xz + wy) * sz; + out[9] = (yz - wx) * sz; + out[10] = (1 - (xx + yy)) * sz; + out[11] = 0; + out[12] = v[0]; + out[13] = v[1]; + out[14] = v[2]; + out[15] = 1; + return out; + } + /** + * Generates a perspective projection matrix with the given bounds. + * The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1], + * which matches WebGL/OpenGL's clip volume. + * Passing null/undefined/no value for far will generate infinite projection matrix. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {number} fovy Vertical field of view in radians + * @param {number} aspect Aspect ratio. typically viewport width/height + * @param {number} near Near bound of the frustum + * @param {number} far Far bound of the frustum, can be null or Infinity + * @returns {mat4} out + */ + + function perspectiveNO(out, fovy, aspect, near, far) { + var f = 1.0 / Math.tan(fovy / 2), + nf; + out[0] = f / aspect; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = f; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[11] = -1; + out[12] = 0; + out[13] = 0; + out[15] = 0; + + if (far != null && far !== Infinity) { + nf = 1 / (near - far); + out[10] = (far + near) * nf; + out[14] = 2 * far * near * nf; + } else { + out[10] = -1; + out[14] = -2 * near; + } + + return out; + } + /** + * Alias for {@link mat4.perspectiveNO} + * @function + */ + + var perspective = perspectiveNO; + /** + * Generates a look-at matrix with the given eye position, focal point, and up axis. + * If you want a matrix that actually makes an object look at another object, you should use targetTo instead. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {ReadonlyVec3} eye Position of the viewer + * @param {ReadonlyVec3} center Point the viewer is looking at + * @param {ReadonlyVec3} up vec3 pointing up + * @returns {mat4} out + */ + + function lookAt(out, eye, center, up) { + var x0, x1, x2, y0, y1, y2, z0, z1, z2, len; + var eyex = eye[0]; + var eyey = eye[1]; + var eyez = eye[2]; + var upx = up[0]; + var upy = up[1]; + var upz = up[2]; + var centerx = center[0]; + var centery = center[1]; + var centerz = center[2]; + + if (Math.abs(eyex - centerx) < EPSILON$1 && Math.abs(eyey - centery) < EPSILON$1 && Math.abs(eyez - centerz) < EPSILON$1) { + return identity$1(out); + } + + z0 = eyex - centerx; + z1 = eyey - centery; + z2 = eyez - centerz; + len = 1 / Math.hypot(z0, z1, z2); + z0 *= len; + z1 *= len; + z2 *= len; + x0 = upy * z2 - upz * z1; + x1 = upz * z0 - upx * z2; + x2 = upx * z1 - upy * z0; + len = Math.hypot(x0, x1, x2); + + if (!len) { + x0 = 0; + x1 = 0; + x2 = 0; + } else { + len = 1 / len; + x0 *= len; + x1 *= len; + x2 *= len; + } + + y0 = z1 * x2 - z2 * x1; + y1 = z2 * x0 - z0 * x2; + y2 = z0 * x1 - z1 * x0; + len = Math.hypot(y0, y1, y2); + + if (!len) { + y0 = 0; + y1 = 0; + y2 = 0; + } else { + len = 1 / len; + y0 *= len; + y1 *= len; + y2 *= len; + } + + out[0] = x0; + out[1] = y0; + out[2] = z0; + out[3] = 0; + out[4] = x1; + out[5] = y1; + out[6] = z1; + out[7] = 0; + out[8] = x2; + out[9] = y2; + out[10] = z2; + out[11] = 0; + out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez); + out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez); + out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez); + out[15] = 1; + return out; + } + + /** + * 3 Dimensional Vector + * @module vec3 + */ + + /** + * Creates a new, empty vec3 + * + * @returns {vec3} a new 3D vector + */ + + function create$3() { + var out = new ARRAY_TYPE(3); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + } + + return out; + } + /** + * Calculates the length of a vec3 + * + * @param {ReadonlyVec3} a vector to calculate length of + * @returns {Number} length of a + */ + + function length(a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + return Math.hypot(x, y, z); + } + /** + * Creates a new vec3 initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @returns {vec3} a new 3D vector + */ + + function fromValues$3(x, y, z) { + var out = new ARRAY_TYPE(3); + out[0] = x; + out[1] = y; + out[2] = z; + return out; + } + /** + * Copy the values from one vec3 to another + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the source vector + * @returns {vec3} out + */ + + function copy$2(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + return out; + } + /** + * Subtracts vector b from vector a + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function subtract(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + return out; + } + /** + * Scales a vec3 by a scalar number + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to scale + * @param {Number} b amount to scale the vector by + * @returns {vec3} out + */ + + function scale(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + return out; + } + /** + * Normalize a vec3 + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a vector to normalize + * @returns {vec3} out + */ + + function normalize$2(out, a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + var len = x * x + y * y + z * z; + + if (len > 0) { + //TODO: evaluate use of glm_invsqrt here? + len = 1 / Math.sqrt(len); + } + + out[0] = a[0] * len; + out[1] = a[1] * len; + out[2] = a[2] * len; + return out; + } + /** + * Calculates the dot product of two vec3's + * + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {Number} dot product of a and b + */ + + function dot(a, b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; + } + /** + * Computes the cross product of two vec3's + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function cross(out, a, b) { + var ax = a[0], + ay = a[1], + az = a[2]; + var bx = b[0], + by = b[1], + bz = b[2]; + out[0] = ay * bz - az * by; + out[1] = az * bx - ax * bz; + out[2] = ax * by - ay * bx; + return out; + } + /** + * Transforms the vec3 with a mat4. + * 4th vector component is implicitly '1' + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to transform + * @param {ReadonlyMat4} m matrix to transform with + * @returns {vec3} out + */ + + function transformMat4(out, a, m) { + var x = a[0], + y = a[1], + z = a[2]; + var w = m[3] * x + m[7] * y + m[11] * z + m[15]; + w = w || 1.0; + out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w; + out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w; + out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w; + return out; + } + /** + * Transforms the vec3 with a quat + * Can also be used for dual quaternions. (Multiply it with the real part) + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to transform + * @param {ReadonlyQuat} q quaternion to transform with + * @returns {vec3} out + */ + + function transformQuat(out, a, q) { + // benchmarks: https://jsperf.com/quaternion-transform-vec3-implementations-fixed + var qx = q[0], + qy = q[1], + qz = q[2], + qw = q[3]; + var x = a[0], + y = a[1], + z = a[2]; // var qvec = [qx, qy, qz]; + // var uv = vec3.cross([], qvec, a); + + var uvx = qy * z - qz * y, + uvy = qz * x - qx * z, + uvz = qx * y - qy * x; // var uuv = vec3.cross([], qvec, uv); + + var uuvx = qy * uvz - qz * uvy, + uuvy = qz * uvx - qx * uvz, + uuvz = qx * uvy - qy * uvx; // vec3.scale(uv, uv, 2 * w); + + var w2 = qw * 2; + uvx *= w2; + uvy *= w2; + uvz *= w2; // vec3.scale(uuv, uuv, 2); + + uuvx *= 2; + uuvy *= 2; + uuvz *= 2; // return vec3.add(out, a, vec3.add(out, uv, uuv)); + + out[0] = x + uvx + uuvx; + out[1] = y + uvy + uuvy; + out[2] = z + uvz + uuvz; + return out; + } + /** + * Alias for {@link vec3.length} + * @function + */ + + var len = length; + /** + * Perform some operation over an array of vec3s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ + + (function () { + var vec = create$3(); + return function (a, stride, offset, count, fn, arg) { + var i, l; + + if (!stride) { + stride = 3; + } + + if (!offset) { + offset = 0; + } + + if (count) { + l = Math.min(count * stride + offset, a.length); + } else { + l = a.length; + } + + for (i = offset; i < l; i += stride) { + vec[0] = a[i]; + vec[1] = a[i + 1]; + vec[2] = a[i + 2]; + fn(vec, vec, arg); + a[i] = vec[0]; + a[i + 1] = vec[1]; + a[i + 2] = vec[2]; + } + + return a; + }; + })(); + + /** + * 4 Dimensional Vector + * @module vec4 + */ + + /** + * Creates a new, empty vec4 + * + * @returns {vec4} a new 4D vector + */ + + function create$2() { + var out = new ARRAY_TYPE(4); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 0; + } + + return out; + } + /** + * Creates a new vec4 initialized with values from an existing vector + * + * @param {ReadonlyVec4} a vector to clone + * @returns {vec4} a new 4D vector + */ + + function clone$1(a) { + var out = new ARRAY_TYPE(4); + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + return out; + } + /** + * Creates a new vec4 initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {vec4} a new 4D vector + */ + + function fromValues$2(x, y, z, w) { + var out = new ARRAY_TYPE(4); + out[0] = x; + out[1] = y; + out[2] = z; + out[3] = w; + return out; + } + /** + * Copy the values from one vec4 to another + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the source vector + * @returns {vec4} out + */ + + function copy$1(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + return out; + } + /** + * Set the components of a vec4 to the given values + * + * @param {vec4} out the receiving vector + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {vec4} out + */ + + function set$1(out, x, y, z, w) { + out[0] = x; + out[1] = y; + out[2] = z; + out[3] = w; + return out; + } + /** + * Normalize a vec4 + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a vector to normalize + * @returns {vec4} out + */ + + function normalize$1(out, a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + var w = a[3]; + var len = x * x + y * y + z * z + w * w; + + if (len > 0) { + len = 1 / Math.sqrt(len); + } + + out[0] = x * len; + out[1] = y * len; + out[2] = z * len; + out[3] = w * len; + return out; + } + /** + * Returns whether or not the vectors have approximately the same elements in the same position. + * + * @param {ReadonlyVec4} a The first vector. + * @param {ReadonlyVec4} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + function equals$1(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3]; + return Math.abs(a0 - b0) <= EPSILON$1 * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON$1 * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON$1 * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON$1 * Math.max(1.0, Math.abs(a3), Math.abs(b3)); + } + /** + * Perform some operation over an array of vec4s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ + + (function () { + var vec = create$2(); + return function (a, stride, offset, count, fn, arg) { + var i, l; + + if (!stride) { + stride = 4; + } + + if (!offset) { + offset = 0; + } + + if (count) { + l = Math.min(count * stride + offset, a.length); + } else { + l = a.length; + } + + for (i = offset; i < l; i += stride) { + vec[0] = a[i]; + vec[1] = a[i + 1]; + vec[2] = a[i + 2]; + vec[3] = a[i + 3]; + fn(vec, vec, arg); + a[i] = vec[0]; + a[i + 1] = vec[1]; + a[i + 2] = vec[2]; + a[i + 3] = vec[3]; + } + + return a; + }; + })(); + + /** + * Quaternion + * @module quat + */ + + /** + * Creates a new identity quat + * + * @returns {quat} a new quaternion + */ + + function create$1() { + var out = new ARRAY_TYPE(4); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + } + + out[3] = 1; + return out; + } + /** + * Set a quat to the identity quaternion + * + * @param {quat} out the receiving quaternion + * @returns {quat} out + */ + + function identity(out) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 1; + return out; + } + /** + * Sets a quat from the given angle and rotation axis, + * then returns it. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyVec3} axis the axis around which to rotate + * @param {Number} rad the angle in radians + * @returns {quat} out + **/ + + function setAxisAngle(out, axis, rad) { + rad = rad * 0.5; + var s = Math.sin(rad); + out[0] = s * axis[0]; + out[1] = s * axis[1]; + out[2] = s * axis[2]; + out[3] = Math.cos(rad); + return out; + } + /** + * Multiplies two quat's + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @returns {quat} out + */ + + function multiply(out, a, b) { + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bx = b[0], + by = b[1], + bz = b[2], + bw = b[3]; + out[0] = ax * bw + aw * bx + ay * bz - az * by; + out[1] = ay * bw + aw * by + az * bx - ax * bz; + out[2] = az * bw + aw * bz + ax * by - ay * bx; + out[3] = aw * bw - ax * bx - ay * by - az * bz; + return out; + } + /** + * Rotates a quaternion by the given angle about the X axis + * + * @param {quat} out quat receiving operation result + * @param {ReadonlyQuat} a quat to rotate + * @param {number} rad angle (in radians) to rotate + * @returns {quat} out + */ + + function rotateX(out, a, rad) { + rad *= 0.5; + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bx = Math.sin(rad), + bw = Math.cos(rad); + out[0] = ax * bw + aw * bx; + out[1] = ay * bw + az * bx; + out[2] = az * bw - ay * bx; + out[3] = aw * bw - ax * bx; + return out; + } + /** + * Rotates a quaternion by the given angle about the Y axis + * + * @param {quat} out quat receiving operation result + * @param {ReadonlyQuat} a quat to rotate + * @param {number} rad angle (in radians) to rotate + * @returns {quat} out + */ + + function rotateY(out, a, rad) { + rad *= 0.5; + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var by = Math.sin(rad), + bw = Math.cos(rad); + out[0] = ax * bw - az * by; + out[1] = ay * bw + aw * by; + out[2] = az * bw + ax * by; + out[3] = aw * bw - ay * by; + return out; + } + /** + * Rotates a quaternion by the given angle about the Z axis + * + * @param {quat} out quat receiving operation result + * @param {ReadonlyQuat} a quat to rotate + * @param {number} rad angle (in radians) to rotate + * @returns {quat} out + */ + + function rotateZ(out, a, rad) { + rad *= 0.5; + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bz = Math.sin(rad), + bw = Math.cos(rad); + out[0] = ax * bw + ay * bz; + out[1] = ay * bw - ax * bz; + out[2] = az * bw + aw * bz; + out[3] = aw * bw - az * bz; + return out; + } + /** + * Performs a spherical linear interpolation between two quat + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {quat} out + */ + + function slerp(out, a, b, t) { + // benchmarks: + // http://jsperf.com/quaternion-slerp-implementations + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bx = b[0], + by = b[1], + bz = b[2], + bw = b[3]; + var omega, cosom, sinom, scale0, scale1; // calc cosine + + cosom = ax * bx + ay * by + az * bz + aw * bw; // adjust signs (if necessary) + + if (cosom < 0.0) { + cosom = -cosom; + bx = -bx; + by = -by; + bz = -bz; + bw = -bw; + } // calculate coefficients + + + if (1.0 - cosom > EPSILON$1) { + // standard case (slerp) + omega = Math.acos(cosom); + sinom = Math.sin(omega); + scale0 = Math.sin((1.0 - t) * omega) / sinom; + scale1 = Math.sin(t * omega) / sinom; + } else { + // "from" and "to" quaternions are very close + // ... so we can do a linear interpolation + scale0 = 1.0 - t; + scale1 = t; + } // calculate final values + + + out[0] = scale0 * ax + scale1 * bx; + out[1] = scale0 * ay + scale1 * by; + out[2] = scale0 * az + scale1 * bz; + out[3] = scale0 * aw + scale1 * bw; + return out; + } + /** + * Creates a quaternion from the given 3x3 rotation matrix. + * + * NOTE: The resultant quaternion is not normalized, so you should be sure + * to renormalize the quaternion yourself where necessary. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyMat3} m rotation matrix + * @returns {quat} out + * @function + */ + + function fromMat3(out, m) { + // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes + // article "Quaternion Calculus and Fast Animation". + var fTrace = m[0] + m[4] + m[8]; + var fRoot; + + if (fTrace > 0.0) { + // |w| > 1/2, may as well choose w > 1/2 + fRoot = Math.sqrt(fTrace + 1.0); // 2w + + out[3] = 0.5 * fRoot; + fRoot = 0.5 / fRoot; // 1/(4w) + + out[0] = (m[5] - m[7]) * fRoot; + out[1] = (m[6] - m[2]) * fRoot; + out[2] = (m[1] - m[3]) * fRoot; + } else { + // |w| <= 1/2 + var i = 0; + if (m[4] > m[0]) i = 1; + if (m[8] > m[i * 3 + i]) i = 2; + var j = (i + 1) % 3; + var k = (i + 2) % 3; + fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1.0); + out[i] = 0.5 * fRoot; + fRoot = 0.5 / fRoot; + out[3] = (m[j * 3 + k] - m[k * 3 + j]) * fRoot; + out[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot; + out[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot; + } + + return out; + } + /** + * Creates a new quat initialized with values from an existing quaternion + * + * @param {ReadonlyQuat} a quaternion to clone + * @returns {quat} a new quaternion + * @function + */ + + var clone = clone$1; + /** + * Creates a new quat initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {quat} a new quaternion + * @function + */ + + var fromValues$1 = fromValues$2; + /** + * Copy the values from one quat to another + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the source quaternion + * @returns {quat} out + * @function + */ + + var copy = copy$1; + /** + * Set the components of a quat to the given values + * + * @param {quat} out the receiving quaternion + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {quat} out + * @function + */ + + var set = set$1; + /** + * Normalize a quat + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a quaternion to normalize + * @returns {quat} out + * @function + */ + + var normalize = normalize$1; + /** + * Returns whether or not the quaternions have approximately the same elements in the same position. + * + * @param {ReadonlyQuat} a The first vector. + * @param {ReadonlyQuat} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + var equals = equals$1; + /** + * Sets a quaternion to represent the shortest rotation from one + * vector to another. + * + * Both vectors are assumed to be unit length. + * + * @param {quat} out the receiving quaternion. + * @param {ReadonlyVec3} a the initial vector + * @param {ReadonlyVec3} b the destination vector + * @returns {quat} out + */ + + (function () { + var tmpvec3 = create$3(); + var xUnitVec3 = fromValues$3(1, 0, 0); + var yUnitVec3 = fromValues$3(0, 1, 0); + return function (out, a, b) { + var dot$1 = dot(a, b); + + if (dot$1 < -0.999999) { + cross(tmpvec3, xUnitVec3, a); + if (len(tmpvec3) < 0.000001) cross(tmpvec3, yUnitVec3, a); + normalize$2(tmpvec3, tmpvec3); + setAxisAngle(out, tmpvec3, Math.PI); + return out; + } else if (dot$1 > 0.999999) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 1; + return out; + } else { + cross(tmpvec3, a, b); + out[0] = tmpvec3[0]; + out[1] = tmpvec3[1]; + out[2] = tmpvec3[2]; + out[3] = 1 + dot$1; + return normalize(out, out); + } + }; + })(); + /** + * Performs a spherical linear interpolation with two control points + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @param {ReadonlyQuat} c the third operand + * @param {ReadonlyQuat} d the fourth operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {quat} out + */ + + (function () { + var temp1 = create$1(); + var temp2 = create$1(); + return function (out, a, b, c, d, t) { + slerp(temp1, a, d, t); + slerp(temp2, b, c, t); + slerp(out, temp1, temp2, 2 * t * (1 - t)); + return out; + }; + })(); + /** + * Sets the specified quaternion with values corresponding to the given + * axes. Each axis is a vec3 and is expected to be unit length and + * perpendicular to all other specified axes. + * + * @param {ReadonlyVec3} view the vector representing the viewing direction + * @param {ReadonlyVec3} right the vector representing the local "right" direction + * @param {ReadonlyVec3} up the vector representing the local "up" direction + * @returns {quat} out + */ + + (function () { + var matr = create$5(); + return function (out, view, right, up) { + matr[0] = right[0]; + matr[3] = right[1]; + matr[6] = right[2]; + matr[1] = up[0]; + matr[4] = up[1]; + matr[7] = up[2]; + matr[2] = -view[0]; + matr[5] = -view[1]; + matr[8] = -view[2]; + return normalize(out, fromMat3(out, matr)); + }; + })(); + + /** + * 2 Dimensional Vector + * @module vec2 + */ + + /** + * Creates a new, empty vec2 + * + * @returns {vec2} a new 2D vector + */ + + function create() { + var out = new ARRAY_TYPE(2); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + } + + return out; + } + /** + * Creates a new vec2 initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @returns {vec2} a new 2D vector + */ + + function fromValues(x, y) { + var out = new ARRAY_TYPE(2); + out[0] = x; + out[1] = y; + return out; + } + /** + * Perform some operation over an array of vec2s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ + + (function () { + var vec = create(); + return function (a, stride, offset, count, fn, arg) { + var i, l; + + if (!stride) { + stride = 2; + } + + if (!offset) { + offset = 0; + } + + if (count) { + l = Math.min(count * stride + offset, a.length); + } else { + l = a.length; + } + + for (i = offset; i < l; i += stride) { + vec[0] = a[i]; + vec[1] = a[i + 1]; + fn(vec, vec, arg); + a[i] = vec[0]; + a[i + 1] = vec[1]; + } + + return a; + }; + })(); + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Error thrown by {@link View360} + * @ko {@link View360}이 발생시킨 에러 + * @since 4.0.0 + */ + class View360Error extends Error { + /** + * Create new instance of View360Error + * @ko View360Error의 인스턴스를 생성합니다. + * @param message - Error message {@ko 에러 메시지} + * @param code - Error code {@ko 에러 코드} + */ + constructor(message, code) { + super(message); + Object.setPrototypeOf(this, View360Error.prototype); + this.name = "View360Error"; + this.code = code; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Error codes of {@link View360Error} + * @ko {@link View360Error}가 가질 수 있는 에러 코드 값들 + * @since 4.0.0 + */ + const ERROR_CODES = { + /** + * The given value's type is not expected + * @ko 주어진 값의 타입이 잘못되었을 경우 + * @since 4.0.0 + */ + WRONG_TYPE: 0, + /** + * The given value is not a supported option + * @ko 잘못된 옵션을 받았을 경우 + * @since 4.0.0 + */ + WRONG_OPTION: 1, + /** + * The element with given CSS selector does not exist + * @ko 주어진 CSS 셀렉터로 엘리먼트를 찾지 못했을 경우 + * @since 4.0.0 + */ + ELEMENT_NOT_FOUND: 2, + /** + * Couldn't find canvas element inside the given container element. + * @ko 컨테이너 엘리먼트 내부에서 캔버스 엘리먼트를 찾지 못했을 경우 + * @since 4.0.0 + */ + CANVAS_NOT_FOUND: 3, + /** + * The browser does not support WebGL + * @ko 브라우저가 WebGL을 지원하지 않는 경우 + * @since 4.0.0 + */ + WEBGL_NOT_SUPPORTED: 4, + /** + * Failed creating canvas 2D context + * @ko 캔버스 2D 컨텍스트를 생성하지 못한 경우 + * @since 4.0.0 + */ + FAILED_CREATE_CONTEXT_2D: 5, + /** + * `init()` is called before setting {@link View360Options#projection} + * @ko {@link View360Options#projection}을 설정하기 전에 `init()`이 호출된 경우 + * @since 4.0.0 + */ + PROVIDE_PROJECTION_FIRST: 6, + /** + * Failed linking WebGL program. Only can be thrown when {@link View360Options#debug} is `true`. + * @ko WebGL 프로그램 링크에 실패한 경우. {@link View360Options#debug}를 `true`로 설정한 경우에만 발생할 수 있습니다. + * @since 4.0.0 + */ + FAILED_LINKING_PROGRAM: 7, + /** + * Arguments are not sufficient for the given property. + * @ko 프로퍼티에 값이 충분히 주어지지 않았을 때 + * @since 4.0.0 + */ + INSUFFICIENT_ARGS: 8 + }; + const MESSAGES = { + WRONG_TYPE: (val, types) => `${typeof val} is not a ${types.map(type => `"${type}"`).join(" or ")}.`, + WRONG_OPTION: (val, optionName) => `Bad option: given "${val}" for option "${optionName}".`, + ELEMENT_NOT_FOUND: query => `Element with selector "${query}" not found.`, + CANVAS_NOT_FOUND: "The canvas element was not found inside the given root element.", + WEBGL_NOT_SUPPORTED: "WebGL is not supported on this browser.", + FAILED_CREATE_CONTEXT_2D: "Failed to create canvas 2D context", + PROVIDE_PROJECTION_FIRST: "\"projection\" should be provided before initialization.", + FAILED_LINKING_PROGRAM: (msg, shaderLog) => `Failed linking WebGL program - "${msg}\nShader compile Log: ${shaderLog}`, + INSUFFICIENT_ARGS: (val, name) => `Insufficient arguments: given "${val}" for "${name}".` + }; + var ERROR = { + CODES: ERROR_CODES, + MESSAGES + }; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + const EVENTS$1 = { + MOUSE_DOWN: "mousedown", + MOUSE_MOVE: "mousemove", + MOUSE_UP: "mouseup", + TOUCH_START: "touchstart", + TOUCH_MOVE: "touchmove", + TOUCH_END: "touchend", + WHEEL: "wheel", + RESIZE: "resize", + CONTEXT_MENU: "contextmenu", + MOUSE_ENTER: "mouseenter", + MOUSE_LEAVE: "mouseleave", + POINTER_DOWN: "pointerdown", + POINTER_MOVE: "pointermove", + POINTER_UP: "pointerup", + POINTER_CANCEL: "pointercancel", + POINTER_ENTER: "pointerenter", + POINTER_LEAVE: "pointerleave", + KEY_DOWN: "keydown", + KEY_UP: "keyup", + LOAD: "load", + ERROR: "error", + CLICK: "click", + DOUBLE_CLICK: "dblclick", + CONTEXT_CREATE_ERROR: "webglcontextcreationerror", + CONTEXT_LOST: "webglcontextlost", + CONTEXT_RESTORED: "webglcontextrestored", + DEVICE_ORIENTATION: "deviceorientation", + DEVICE_MOTION: "devicemotion", + ORIENTATION_CHANGE: "orientationchange", + VIDEO_PLAY: "play", + VIDEO_PAUSE: "pause", + VIDEO_LOADED_DATA: "loadeddata", + VIDEO_VOLUME_CHANGE: "volumechange", + VIDEO_TIME_UPDATE: "timeupdate", + VIDEO_DURATION_CHANGE: "durationchange", + VIDEO_CAN_PLAYTHROUGH: "canplaythrough", + TRANSITION_END: "transitionend", + XR_END: "end" + }; + const EL_DIV = "div"; + const EL_BUTTON = "button"; + // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button + var MOUSE_BUTTON; + (function (MOUSE_BUTTON) { + MOUSE_BUTTON[MOUSE_BUTTON["LEFT"] = 0] = "LEFT"; + MOUSE_BUTTON[MOUSE_BUTTON["MIDDLE"] = 1] = "MIDDLE"; + MOUSE_BUTTON[MOUSE_BUTTON["RIGHT"] = 2] = "RIGHT"; + })(MOUSE_BUTTON || (MOUSE_BUTTON = {})); + const CURSOR = { + GRAB: "grab", + GRABBING: "grabbing", + NONE: "" + }; + const KEY_DIRECTION = ["LEFT", "UP", "RIGHT", "DOWN"]; + var DIRECTION_KEY_CODE; + (function (DIRECTION_KEY_CODE) { + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["LEFT"] = 37] = "LEFT"; + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["UP"] = 38] = "UP"; + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["RIGHT"] = 39] = "RIGHT"; + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["DOWN"] = 40] = "DOWN"; + })(DIRECTION_KEY_CODE || (DIRECTION_KEY_CODE = {})); + const SPACE_KEY_CODE = 32; + const DIRECTION_KEY_NAME = { + LEFT: "ArrowLeft", + UP: "ArrowUp", + RIGHT: "ArrowRight", + DOWN: "ArrowDown" + }; + const SPACE_KEY_NAME = " "; + const FULLSCREEN_REQUEST = ["requestFullscreen", "webkitRequestFullscreen", "webkitRequestFullScreen", "webkitCancelFullScreen", "mozRequestFullScreen", "msRequestFullscreen"]; + const FULLSCREEN_ELEMENT = ["fullscreenElement", "webkitFullscreenElement", "webkitCurrentFullScreenElement", "mozFullScreenElement", "msFullscreenElement"]; + const FULLSCREEN_EXIT = ["exitFullscreen", "webkitExitFullscreen", "webkitCancelFullScreen", "mozCancelFullScreen", "msExitFullscreen"]; + const FULLSCREEN_CHANGE = ["fullscreenchange", "webkitfullscreenchange", "mozfullscreenchange", "MSFullscreenChange"]; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Default class names + * @ko 기본 클래스 이름들 + * @since 4.0.0 + */ + const DEFAULT_CLASS = { + CONTAINER: "view360-container", + CANVAS: "view360-canvas", + CTX_LOST: "view360-ctx-lost", + IN_VR: "view360-vr-presenting", + HOTSPOT_CONTAINER: "view360-hotspots", + HOTSPOT: "view360-hotspot", + HOTSPOT_VISIBLE: "view360-hotspot-visible", + HOTSPOT_FLIP_X: "view360-hotspot-flip-x", + HOTSPOT_FLIP_Y: "view360-hotspot-flip-y" + }; + /** + * Event names + * @ko 이벤트 이름들 + * @since 4.0.0 + * @example + * ```ts + * import View360, { EVENTS } from "@egjs/view360"; + * + * const viewer = new View360("#el_id"); + * + * viewer.on(EVENTS.READY, evt => { + * console.log("View360 is ready!"); + * }); + * ``` + */ + const EVENTS = { + READY: "ready", + LOAD_START: "loadStart", + LOAD: "load", + PROJECTION_CHANGE: "projectionChange", + RESIZE: "resize", + BEFORE_RENDER: "beforeRender", + RENDER: "render", + INPUT_START: "inputStart", + INPUT_END: "inputEnd", + VIEW_CHANGE: "viewChange", + STATIC_CLICK: "staticClick", + VR_START: "vrStart", + VR_END: "vrEnd" + }; + /** + * Collection of predefined easing functions + * @ko 미리 정의된 easing 함수들 + */ + const EASING = { + LINEAR: x => x, + SINE_WAVE: x => Math.sin(x * Math.PI * 2), + EASE_OUT_CUBIC: x => 1 - Math.pow(1 - x, 3), + EASE_OUT_BOUNCE: x => { + const n1 = 7.5625; + const d1 = 2.75; + if (x < 1 / d1) { + return n1 * x * x; + } else if (x < 2 / d1) { + return n1 * (x -= 1.5 / d1) * x + 0.75; + } else if (x < 2.5 / d1) { + return n1 * (x -= 2.25 / d1) * x + 0.9375; + } else { + return n1 * (x -= 2.625 / d1) * x + 0.984375; + } + } + }; + + var _a; + const CAMERA_EVENTS = { + CHANGE: "change", + ANIMATION_END: "animationEnd" + }; + const CONTROL_EVENTS = { + INPUT_START: "inputStart", + CHANGE: "change", + INPUT_END: "inputEnd", + ENABLE: "enable", + DISABLE: "disable", + STATIC_CLICK: "staticClick" + }; + const DEG_TO_RAD = Math.PI / 180; + const RAD_TO_DEG = 180 / Math.PI; + const DEFAULT_EASING = EASING.EASE_OUT_CUBIC; + const DEFAULT_ANIMATION_DURATION = 300; + const INFINITE_RANGE = { + min: -Infinity, + max: Infinity + }; + const DEFAULT_PITCH_RANGE = { + min: -90, + max: 90 + }; + const DEFAULT_ZOOM_RANGE = { + min: 0.6, + max: 10 + }; + var ROTATE; + (function (ROTATE) { + ROTATE[ROTATE["ZERO"] = 0] = "ZERO"; + ROTATE[ROTATE["CW_90"] = 1] = "CW_90"; + ROTATE[ROTATE["CCW_90"] = 2] = "CCW_90"; + ROTATE[ROTATE["CW_180"] = 3] = "CW_180"; + })(ROTATE || (ROTATE = {})); + // Custom event name for video time change + const VIDEO_TIME_CHANGE_EVENT = "view360videotimechange"; + const SVG_NAMESPACE = "http://www.w3.org/2000/svg"; + const SESSION_VR = "immersive-vr"; + const XR_REFERENCE_SPACE = "local"; + const EPSILON = (_a = Number.EPSILON) !== null && _a !== void 0 ? _a : 2.220446049250313e-16; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + const isString = val => typeof val === "string"; + const isElement = val => !!val && val.nodeType === Node.ELEMENT_NODE; + const createElement = (className, tag = EL_DIV) => { + const el = document.createElement(tag); + el.classList.add(className); + return el; + }; + const getNullableElement = (el, parent) => { + let targetEl = null; + if (isString(el)) { + const parentEl = parent ? parent : document; + const queryResult = parentEl.querySelector(el); + if (!queryResult) { + return null; + } + targetEl = queryResult; + } else if (isElement(el)) { + targetEl = el; + } + return targetEl; + }; + const getElement = (el, parent) => { + const targetEl = getNullableElement(el, parent); + if (!targetEl) { + if (isString(el)) { + throw new View360Error(ERROR.MESSAGES.ELEMENT_NOT_FOUND(el), ERROR.CODES.ELEMENT_NOT_FOUND); + } else { + throw new View360Error(ERROR.MESSAGES.WRONG_TYPE(el, ["HTMLElement", "string"]), ERROR.CODES.WRONG_TYPE); + } + } + return targetEl; + }; + const findCanvas = (root, selector) => { + const canvas = root.querySelector(selector); + if (!canvas) { + throw new View360Error(ERROR.MESSAGES.CANVAS_NOT_FOUND, ERROR.CODES.CANVAS_NOT_FOUND); + } + return canvas; + }; + const range = end => { + if (!end || end <= 0) { + return []; + } + return Array.apply(0, Array(end)).map((undef, idx) => idx); + }; + const clamp = (x, min, max) => Math.max(Math.min(x, max), min); + // Linear interpolation between a and b + const lerp = (a, b, t) => { + return a * (1 - t) + b * t; + }; + const circulate = (val, min, max) => { + const size = Math.abs(max - min); + if (val < min) { + const offset = (min - val) % size; + val = max - offset; + } else if (val > max) { + const offset = (val - max) % size; + val = min + offset; + } + return val; + }; + // eslint-disable-next-line @typescript-eslint/ban-types + const merge = (target, ...srcs) => { + srcs.forEach(source => { + Object.keys(source).forEach(key => { + const value = source[key]; + if (Array.isArray(target[key]) && Array.isArray(value)) { + target[key] = [...target[key], ...value]; + } else { + target[key] = value; + } + }); + }); + return target; + }; + const findIndex = (array, checker) => { + for (let idx = 0; idx < array.length; idx++) { + if (checker(array[idx])) { + return idx; + } + } + return -1; + }; + const getObjectOption = val => typeof val === "object" ? val : {}; + const toVerticalFov = (fovRadian, aspect) => { + return Math.atan(Math.tan(fovRadian * 0.5) / aspect) * 2; + }; + const reorderCube = (arr, order, defaultOrder = "RLUDFB") => { + return defaultOrder.split("").map(face => order.indexOf(face)).map(index => arr[index]); + }; + const isFullscreen = () => { + if (!document) return false; + for (const key of FULLSCREEN_ELEMENT) { + if (document[key]) return true; + } + return false; + }; + const sensorCanBeEnabledIOS = () => { + return !!DeviceMotionEvent && "requestPermission" in DeviceMotionEvent && window.isSecureContext; + }; + const hfovToZoom = (baseFov, fov) => { + const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5); + const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5); + return renderingWidth / zoomedWidth; + }; + const eulerToQuat = (out, yaw, pitch, roll) => { + identity(out); + const pitchThreshold = 0.01; + const pitchClamped = clamp(pitch, -90 + pitchThreshold, 90 - pitchThreshold); + rotateY(out, out, yaw * DEG_TO_RAD); + rotateX(out, out, pitchClamped * DEG_TO_RAD); + rotateZ(out, out, roll * DEG_TO_RAD); + return out; + }; + /** + * Extract euler angles from the quaternion, except roll(z-axis rotation) + * @hidden + */ + const quatToEuler = quaternion => { + const x = quaternion[0]; + const y = quaternion[1]; + const z = quaternion[2]; + const w = quaternion[3]; + const x2 = x * x; + const y2 = y * y; + const z2 = z * z; + const w2 = w * w; + const unit = x2 + y2 + z2 + w2; + const test = x * w - y * z; + let pitch, yaw; + if (test > 0.499995 * unit) { + // singularity at the north pole + pitch = Math.PI / 2; + yaw = 2 * Math.atan2(y, x); + } else if (test < -0.499995 * unit) { + // singularity at the south pole + pitch = -Math.PI / 2; + yaw = -2 * Math.atan2(y, x); + } else { + const view = fromValues$3(0, 0, 1); + const up = fromValues$3(0, 1, 0); + transformQuat(view, view, quaternion); + transformQuat(up, up, quaternion); + const viewXZ = Math.sqrt(view[0] * view[0] + view[2] * view[2]); + pitch = Math.atan2(-view[1], viewXZ); + yaw = Math.atan2(view[0], view[2]); + } + return { + pitch: clamp(pitch * RAD_TO_DEG, -90, 90), + yaw: circulate(yaw * RAD_TO_DEG, 0, 360) + }; + }; + + /* + * Copyright (c) 2020 NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Interpolator between two values with duration + * @ko 특정 시간동안 두 값을 보간해주는 보간기 + * @since 4.0.0 + */ + class Motion { + /** + * Current interpolated value + * @ko 현재 보간된 값 + * @since 4.0.0 + */ + get val() { + return this._val; + } + /** + * Start(from) value of interpolation + * @ko 보간 시작 값 + * @since 4.0.0 + */ + get start() { + return this._start; + } + /** + * End(to) value of interpolation + * @ko 보간 끝 값 + * @since 4.0.0 + */ + get end() { + return this._end; + } + /** + * Interpolation progress value (0 ~ 1) + * @ko 현재 보간 진행정도 (0 ~ 1) + * @since 4.0.0 + */ + get progress() { + return this._progress; + } + /** + * Whether the interpolation is in active state. + * @ko 보간 진행중인지 여부. `true`일 경우 보간이 진행중입니다. + * @since 4.0.0 + */ + get activated() { + return this._activated; + } + /** + * Duration of the interpolation + * @ko 보간할 시간 + * @since 4.0.0 + */ + get duration() { + return this._duration; + } + set duration(val) { + this._duration = val; + } + /** + * Whether to loop interpolation on finish + * @ko 보간이 끝난 이후에 다시 시작할지 여부 + * @since 4.0.0 + */ + get loop() { + return this._loop; + } + set loop(val) { + this._loop = val; + } + /** + * Range of the interpolation + * @ko 보간 범위 + * @since 4.0.0 + */ + get range() { + return this._range; + } + /** + * Easing function of the interpolation + * @ko 보간에 사용되는 easing function + * @since 4.0.0 + */ + get easing() { + return this._easing; + } + set easing(val) { + this._easing = val; + } + /** + * Create new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options Options {@ko 옵션들} + * @param options.duration Duration of the interpolation {@ko 보간할 시간} + * @param options.loop Whether to loop interpolation on finish {@ko 보간이 끝난 이후에 다시 시작할지 여부} + * @param options.range Range of the interpolation {@ko 보간 범위} + * @param options.loop Easing function of the interpolation {@ko 보간에 사용되는 easing function} + */ + constructor({ + duration = DEFAULT_ANIMATION_DURATION, + loop = false, + range = { + min: 0, + max: 1 + }, + easing = DEFAULT_EASING + } = {}) { + this._duration = duration; + this._loop = loop; + this._range = range; + this._easing = easing; + this._activated = false; + this.reset(0); + } + /** + * Update motion and progress it by given deltaTime + * @ko 주어진 deltaTime만큼 보간을 진행합니다. + * @param deltaTime - number of milisec to update motion {@ko 보간을 진행할 시간, 밀리초 단위} + * @returns Difference(delta) of the value from the last update. {@ko 지난 업데이트 이후의 값 변화량} + * @since 4.0.0 + */ + update(deltaTime) { + if (!this._activated) { + this._val = this._end; + return 0; + } + const start = this._start; + const end = this._end; + const duration = this._duration; + const prev = this._val; + const loop = this._loop; + const nextProgress = this._progress + deltaTime / duration; + this._progress = loop ? circulate(nextProgress, 0, 1) : clamp(nextProgress, 0, 1); + const easedProgress = this._easing(this._progress); + this._val = lerp(start, end, easedProgress); + if (!loop && this._progress >= 1) { + this._activated = false; + } + return this._val - prev; + } + /** + * Set `start`, `end` to the given value and set `progress` to 0. + * @ko 주어진 값으로 시작 지점, 끝 지점을 초기화하고 progress를 0으로 세팅합니다. + * @param defaultVal - Value to reset {@ko 초기화할 값} + * @since 4.0.0 + */ + reset(defaultVal) { + const range = this._range; + const val = clamp(defaultVal, range.min, range.max); + this._start = val; + this._end = val; + this._val = val; + this._progress = 0; + this._activated = false; + } + /** + * Add delta to start & end and current value. + * @ko 현재 & 끝 및 현재 값에 주어진 값을 더합니다. + * @param delta - Delta value to add {@ko 추가할 값} + */ + add(delta) { + const range = this._range; + this._start = clamp(this._start + delta, range.min, range.max); + this._end = clamp(this._end + delta, range.min, range.max); + this._val = clamp(this._val + delta, range.min, range.max); + } + /** + * Set current value to start, and end to current value + delta, then reset progress to 0. + * @ko 현재 값을 시작 지점으로, 그에서 delta만큼 추가된 값을 끝점으로 하고 progress를 0으로 갱신합니다. + * @param delta - Delta value to add {@ko 추가할 값} + */ + setNewEndByDelta(delta) { + const range = this._range; + this._start = this._val; + this._end = clamp(this._end + delta, range.min, range.max); + this._progress = 0; + this._activated = true; + } + /** + * Set new range of the interpolation. + * @ko 보간의 범위를 변경합니다. + * @param min - New minimum range {@ko 변경할 범위의 최소값} + * @param max - New maximum range {@ko 변경할 범위의 최대값} + */ + setRange(min, max) { + this._start = clamp(this._start, min, max); + this._end = clamp(this._end, min, max); + this._range = { + min, + max + }; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Animation of the {@link Camera} + * @internal + * @ko {@link Camera}의 애니메이션 + * @since 4.0.0 + */ + class CameraAnimation { + /** + * Duration of the animation + * @ko 애니메이션 재생시간 + * @since 4.0.0 + */ + get duration() { + return this._motion.duration; + } + set duration(val) { + this._motion.duration = val; + } + /** + * Easing function of the animation + * @ko 애니메이션의 easing function + * @since 4.0.0 + */ + get easing() { + return this._motion.easing; + } + set easing(val) { + this._motion.easing = val; + } + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param camera - Camera to animate {@ko 애니메이션을 적용할 카메라} + * @param from - Start pose {@ko 애니메이션이 시작 시점의 카메라의 회전 및 줌} + * @param to - End pose {@ko 애니메이션이 끝났을 때 카메라의 회전 및 줌} + * @param options - Options {@ko 옵션들} + * @param options.duration - Animation duration {@ko 애니메이션 재생 시간} + * @param options.easing - Animation easing function {@ko 애니메이션 easing function} + */ + constructor(camera, from, to, { + duration = DEFAULT_ANIMATION_DURATION, + easing = DEFAULT_EASING + } = {}) { + this._camera = camera; + this._motion = new Motion({ + duration, + easing, + range: { + min: 0, + max: 1 + } + }); + this._from = from; + this._to = to; + this._finishPromise = new Promise(resolve => { + this._finish = resolve; + }); + // Enable motion + this._motion.setNewEndByDelta(1); + } + /** + * Return a promise that resolved on animation end. + * @ko 애니메이션 재생이 끝났을 때 resolve되는 Promise를 반환합니다. + * @since 4.0.0 + */ + getFinishPromise() { + return this._finishPromise; + } + /** + * Update animation by given deltaTime. + * @ko 주어진 시간만큼 애니메이션을 업데이트합니다. + * @param deltaTime Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위} + * @since 4.0.0 + */ + update(deltaTime) { + const camera = this._camera; + const from = this._from; + const to = this._to; + const motion = this._motion; + motion.update(deltaTime); + // Progress that easing is applied + const progress = motion.val; + const rotation = create$1(); + const zoom = lerp(from.zoom, to.zoom, progress); + slerp(rotation, from.rotation, to.rotation, progress); + camera.rotate(rotation, zoom); + if (progress >= 1) { + this._finish(); + } + } + } + + /** + * Camera for View360 + * @ko View360용 카메라 구현체 + * @version 4.0.0 + */ + class Camera extends Component { + /** + * Camera's width / height ratio + * @ko 카메라의 가로 / 세로 비율 + * @readonly + */ + get aspect() { + return this._aspect; + } + /** + * Whether the camera's rotation changed from the last frame. + * @ko 마지막 프레임 이후로 카메라의 회전값이 변경되었는지 나타내는 플래그. + * @readonly + */ + get changed() { + return this._changed; + } + /** + * @copy View360#yawRange + */ + get yawRange() { + return this._initialYawRange; + } + set yawRange(val) { + this._initialYawRange = val; + } + /** + * @copy View360#pitchRange + */ + get pitchRange() { + return this._initialPitchRange; + } + set pitchRange(val) { + this._initialPitchRange = val; + } + /** + * @copy View360#zoomRange + */ + get zoomRange() { + return this._initialZoomRange; + } + set zoomRange(val) { + this._initialZoomRange = val; + } + /** + * Create new instance of Camera + * @param options - Camera options {@ko 카메라 옵션들} + */ + constructor({ + initialYaw, + initialPitch, + initialZoom, + yawRange, + pitchRange, + zoomRange, + fov + }) { + super(); + this.yaw = initialYaw; + this.pitch = initialPitch; + this.zoom = initialZoom; + this.rollOffset = 0; + this.initialYaw = initialYaw; + this.initialPitch = initialPitch; + this.initialZoom = initialZoom; + this.position = create$3(); + this.animation = null; + this._up = fromValues$3(0, 1, 0); + this._aspect = 1; + this._initialYawRange = yawRange; + this._initialPitchRange = pitchRange; + this._initialZoomRange = zoomRange; + this._yawRange = yawRange; + this._pitchRange = pitchRange; + this._zoomRange = zoomRange; + this.quaternion = create$1(); + this._updateQuaternion(); + this.viewMatrix = create$4(); + this.projectionMatrix = create$4(); + this.fov = fov; + this._maxRenderHeight = -1; + } + /** + * Destroy instance and detach all event listeners + * @ko 인스턴스를 삭제하고 모든 이벤트 리스너를 삭제합니다. + * @since 4.0.0 + */ + destroy() { + this.off(); + } + /** + * Refresh internal size value. + * @ko 내부 크기값을 갱신합니다. + * @param width - New width {@ko 변경된 너비값} + * @param height - New height {@ko 변경된 높이값} + * @since 4.0.0 + */ + resize(width, height) { + const prevAspect = this._aspect; + this._aspect = width / height; + if (this._aspect !== prevAspect) { + this.updateMatrix(); + } + } + /** + * Change camera's rotation with euler values. + * @ko 카메라 회전을 오일러 각 방향으로 변경합니다. + * @param rotation - Rotation values {@ko 회전 값} + * @param rotation.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값} + * @param rotation.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값} + * @param rotation.zoom - zoom value to apply {@ko 적용할 카메라 줌 값} + * @since 4.0.0 + */ + lookAt({ + yaw = this.yaw, + pitch = this.pitch, + zoom = this.zoom + }) { + const prevQuaternion = clone(this.quaternion); + const prevZoom = this.zoom; + this.yaw = circulate(yaw, 0, 360); + this.pitch = clamp(pitch, -90, 90); + this.zoom = zoom; + this._updateQuaternion(); + const zoomDiff = Math.abs(zoom - prevZoom); + if (!equals(this.quaternion, prevQuaternion) || zoomDiff >= EPSILON * 10 // ignore small changes + ) { + this.updateMatrix(); + } + } + /** + * Change camera's rotation with quaternion. + * @ko 카메라 회전을 Quaternion을 이용해서 변경합니다. + * @param rotation - Quaternion to apply {@ko 적용할 Quaternion} + * @param zoom - zoom value to apply {@ko 적용할 카메라 줌 값} + * @since 4.0.0 + */ + rotate(rotation, zoom = this.zoom) { + const normalized = normalize(create$1(), rotation); + const isSameRotation = equals(this.quaternion, normalized); + copy(this.quaternion, normalized); + const prevZoom = this.zoom; + const { + yaw, + pitch + } = quatToEuler(normalized); + this.yaw = yaw; + this.pitch = pitch; + this.zoom = zoom; + const zoomDiff = Math.abs(zoom - prevZoom); + if (!isSameRotation || zoomDiff >= EPSILON * 10) { + this.updateMatrix(); + } + } + /** + * Change camera's rotation to given euler values by the given duration. + * @ko 카메라를 주어진 방향으로 주어진 시간동안 서서히 이동시킵니다. + * @param options - Animation parameters {@ko 애니메이션 패러미터} + * @param options.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값} + * @param options.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값} + * @param options.zoom - zoom value to apply {@ko 적용할 카메라 줌 값} + * @param options.duration - Duration of the animation {@ko 애니메이션 시간} + * @param options.easing - Easing function for the animation {@ko 애니메이션에 적용할 easing function} + */ + animateTo({ + yaw = this.yaw, + pitch = this.pitch, + zoom = this.zoom, + duration = 0, + easing = DEFAULT_EASING + } = {}) { + return __awaiter(this, void 0, void 0, function* () { + if (this.yaw === yaw && this.pitch === pitch && this.zoom === zoom) return; + const from = { + rotation: clone(this.quaternion), + zoom: this.zoom + }; + const to = { + rotation: eulerToQuat(create$1(), yaw, pitch, this.rollOffset), + zoom + }; + const animation = new CameraAnimation(this, from, to, { + duration, + easing + }); + const finishPromise = animation.getFinishPromise(); + this.animation = animation; + finishPromise.then(() => { + this.animation = null; + this.trigger(CAMERA_EVENTS.ANIMATION_END, { + animation + }); + }); + return finishPromise; + }); + } + /** + * @hidden + */ + restrictYawRange(min, max) { + this._yawRange = { + min, + max + }; + } + /** + * @hidden + */ + restrictPitchRange(min, max) { + this._pitchRange = { + min, + max + }; + } + /** + * @hidden + */ + restrictZoomRange(min, max) { + this._zoomRange = { + min, + max + }; + } + /** + * @hidden + */ + restrictRenderHeight(height) { + this._maxRenderHeight = height; + } + /** + * @hidden + */ + resetRange() { + this._yawRange = this._initialYawRange; + this._pitchRange = this._initialPitchRange; + this._zoomRange = this._initialZoomRange; + this._maxRenderHeight = -1; + } + /** + * Get actual yaw range by the given zoom value. + * @ko 주어진 zoom 값에 대한 실제 yaw 범위값을 반환합니다. + * @since 4.0.0 + */ + getYawRange(zoom) { + const yawLimit = this._yawRange; + const maxRenderHeight = this._maxRenderHeight; + if (!yawLimit) return INFINITE_RANGE; + const halfHFov = this.getHorizontalFov(zoom) * 0.5; + let minYaw = yawLimit.min; + let maxYaw = yawLimit.max; + if (maxRenderHeight > 0) { + const halfVFovRad = toVerticalFov(halfHFov * DEG_TO_RAD, this._aspect); + const h = maxRenderHeight * 0.5; + const t = Math.tan(halfVFovRad); + const d = Math.sqrt((1 + h * h) / (1 + t * t)); + const theta = Math.atan(Math.tan(halfHFov * DEG_TO_RAD) * d) * RAD_TO_DEG; + minYaw = yawLimit.min + theta; + maxYaw = yawLimit.max - theta; + } + if (minYaw > maxYaw) { + minYaw = 0; + maxYaw = 0; + } + return { + min: minYaw, + max: maxYaw + }; + } + /** + * Get actual pitch range by the given zoom value. + * @ko 주어진 zoom 값에 대한 실제 pitch 범위값을 반환합니다. + * @since 4.0.0 + */ + getPitchRange(zoom) { + const pitchLimit = this._pitchRange; + const maxRenderHeight = this._maxRenderHeight; + if (!pitchLimit) return DEFAULT_PITCH_RANGE; + let minPitch = pitchLimit.min; + let maxPitch = pitchLimit.max; + if (maxRenderHeight > 0) { + const halfVFov = this.getVerticalFov(zoom) * 0.5; + minPitch = pitchLimit.min + halfVFov; + maxPitch = pitchLimit.max - halfVFov; + } + if (minPitch > maxPitch) { + minPitch = 0; + maxPitch = 0; + } + return { + min: Math.max(minPitch, -90), + max: Math.min(maxPitch, 90) + }; + } + /** + * Get actual zoom range in fov degrees. + * @ko 실제 줌 범위를 fov각의 범위로 반환합니다. + * @since 4.0.0 + */ + getZoomRange() { + var _a; + const limit = (_a = this._zoomRange) !== null && _a !== void 0 ? _a : DEFAULT_ZOOM_RANGE; + // max (zoom in) -> minimum fov + const minFov = this.getHorizontalFov(limit.max); + const maxFov = this.getHorizontalFov(limit.min); + const currentFov = this.getHorizontalFov(this.zoom); + return { + min: Math.max(minFov, 1), + max: Math.min(maxFov, 180), + current: currentFov + }; + } + /** + * Return horizontal fov value when the given zoom is applied. (in degrees, °) + * @ko 주어진 zoom 값이 적용되었을 때의 수평 fov값을 반환합니다. (도 단위, °) + * @returns Zoomed horizontal FOV {@ko 줌이 적용된 수평 fov값} + * @since 4.0.0 + */ + getHorizontalFov(zoom = this.zoom) { + return this._getZoomedHorizontalFov(zoom) * RAD_TO_DEG; + } + /** + * Return vertical fov value when the given zoom is applied. (in degrees, °) + * @ko 주어진 zoom 값이 적용되었을 때의 수직 fov값을 반환합니다. (도 단위, °) + * @returns Zoomed vertical FOV {@ko 줌이 적용된 수직 fov값} + * @since 4.0.0 + */ + getVerticalFov(zoom = this.zoom) { + const aspect = this._aspect; + const hFov = this._getZoomedHorizontalFov(zoom); // In radians + const vFov = toVerticalFov(hFov, aspect); + return vFov * RAD_TO_DEG; + } + /** + * Calculate zoom value for the given fov. + * @ko 주어진 fov값을 zoom값으로 변환합니다. + * @param fov horizontal fov (in degrees, °) {@ko 수평 fov 값 (도 단위, °)} + * @since 4.0.0 + */ + fovToZoom(fov) { + const baseFov = this.fov; + const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5); + const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5); + return renderingWidth / zoomedWidth; + } + /** + * Update inner matrixes. + * @ko 내부 행렬들을 업데이트합니다. + * @internal + * @since 4.0.0 + */ + updateMatrix() { + const up = this._up; + const aspect = this._aspect; + const viewMatrix = this.viewMatrix; + const projMatrix = this.projectionMatrix; + const position = this.position; + const rotation = this.quaternion; + const upDir = create$3(); + const viewDir = fromValues$3(0, 0, -1); + transformQuat(viewDir, viewDir, rotation); + transformQuat(upDir, up, rotation); + const hFov = this._getZoomedHorizontalFov(); // In radians + const vFov = toVerticalFov(hFov, aspect); + lookAt(viewMatrix, position, viewDir, upDir); + perspective(projMatrix, vFov, aspect, 0.1, 100); + this._changed = true; + } + /** + * @hidden + */ + onFrameRender() { + this._changed = false; + } + _updateQuaternion() { + eulerToQuat(this.quaternion, this.yaw, this.pitch, this.rollOffset); + } + /** + * @param zoom Current zoom value + * @returns horizontal fov including zoom, in radian + */ + _getZoomedHorizontalFov(zoom = this.zoom) { + return 2 * Math.atan(Math.tan(DEG_TO_RAD * this.fov * 0.5) / zoom); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class MouseInput extends Component { + constructor() { + super(); + this._onMouseDown = evt => { + const el = this._el; + if (!el || evt.button !== MOUSE_BUTTON.LEFT) return; + evt.preventDefault(); + if (el.focus) { + el.focus(); + } else { + window.focus(); + } + this._prevPos[0] = evt.clientX; + this._prevPos[1] = evt.clientY; + window.addEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove, false); + window.addEventListener(EVENTS$1.MOUSE_UP, this._onMouseUp, false); + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: false, + isKeyboard: false + }); + }; + this._onMouseMove = evt => { + evt.preventDefault(); + const x = evt.clientX; + const y = evt.clientY; + const prevPos = this._prevPos; + const deltaX = x - prevPos[0]; + const deltaY = y - prevPos[1]; + this.trigger(CONTROL_EVENTS.CHANGE, { + delta: { + x: deltaX, + y: deltaY + }, + isTouch: false, + isKeyboard: false + }); + prevPos[0] = x; + prevPos[1] = y; + }; + this._onMouseUp = () => { + this._prevPos[0] = 0; + this._prevPos[1] = 0; + window.removeEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove, false); + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onMouseUp, false); + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: false, + isKeyboard: false, + scrolling: false + }); + }; + this._el = null; + this._prevPos = [0, 0]; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.MOUSE_DOWN, this._onMouseDown); + this._el = element; + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.MOUSE_DOWN, this._onMouseDown); + window.removeEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove, false); + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onMouseUp, false); + this._el = null; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class TouchInput extends Component { + get scrollable() { + return this._scrollable; + } + set scrollable(val) { + this._scrollable = val; + } + constructor() { + super(); + this._onTouchStart = evt => { + if (evt.touches.length > 1 || this._scrolling) return; + const touch = evt.touches[0]; + this._isFirstTouch = true; + this._prevPos[0] = touch.clientX; + this._prevPos[1] = touch.clientY; + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: true, + isKeyboard: false + }); + }; + this._onTouchMove = evt => { + // Only the one finger motion should be considered + if (evt.touches.length > 1 || this._scrolling) return; + const touch = evt.touches[0]; + const scrollable = this._scrollable; + const prevPos = this._prevPos; + const x = touch.clientX; + const y = touch.clientY; + const deltaX = x - prevPos[0]; + const deltaY = y - prevPos[1]; + if (this._isFirstTouch) { + if (scrollable && !isFullscreen()) { + if (Math.abs(deltaY) > Math.abs(deltaX)) { + // Assume Scrolling + this._scrolling = true; + return; + } + } + this._isFirstTouch = false; + } + if (evt.cancelable !== false) { + evt.preventDefault(); + } + this.trigger(CONTROL_EVENTS.CHANGE, { + delta: { + x: deltaX, + y: deltaY + }, + isTouch: true, + isKeyboard: false + }); + prevPos[0] = x; + prevPos[1] = y; + }; + this._onTouchEnd = evt => { + if (evt.touches.length !== 0) return; + const touch = evt.touches[0]; + const prevPos = this._prevPos; + if (touch) { + prevPos[0] = touch.clientX; + prevPos[1] = touch.clientY; + } else { + prevPos[0] = 0; + prevPos[1] = 0; + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: true, + isKeyboard: false, + scrolling: this._scrolling + }); + } + if (evt.cancelable !== false) { + evt.preventDefault(); + } + this._scrolling = false; + }; + this._el = null; + this._prevPos = [0, 0]; + this._isFirstTouch = false; + this._scrolling = false; + this._scrollable = false; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.TOUCH_START, this._onTouchStart, { + passive: false + }); + element.addEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove, { + passive: false + }); + element.addEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = element; + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.TOUCH_START, this._onTouchStart); + element.removeEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove); + element.removeEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = null; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class KeyboardInput extends Component { + get active() { + const pressed = this._pressed; + return pressed.LEFT || pressed.UP || pressed.RIGHT || pressed.DOWN; + } + constructor() { + super(); + this._onKeyDown = evt => { + // Ignore all other keypress except main arrow keys + if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return; + this._updateKeyPress(evt, true); + const pressedCount = this._getPressedKeyCount(); + if (pressedCount <= 0) return; + evt.preventDefault(); + if (pressedCount === 1 && !evt.repeat) { + // On first keydown + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: false, + isKeyboard: true + }); + } + }; + this._onKeyUp = evt => { + // Ignore all other keypress except main arrow keys + if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return; + this._updateKeyPress(evt, false); + const pressedCount = this._getPressedKeyCount(); + if (pressedCount > 0) return; + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: false, + isKeyboard: true, + scrolling: false + }); + }; + this._el = null; + this._clearPressedKeys(); + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown); + element.addEventListener(EVENTS$1.KEY_UP, this._onKeyUp); + this._el = element; + this._clearPressedKeys(); + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown); + element.removeEventListener(EVENTS$1.KEY_UP, this._onKeyUp); + this._el = null; + this._clearPressedKeys(); + } + update() { + const delta = this._getDeltaByPressedKeys(); + if (delta.x !== 0 || delta.y !== 0) { + this.trigger(CONTROL_EVENTS.CHANGE, { + delta, + isTouch: false, + isKeyboard: true + }); + } + } + _clearPressedKeys() { + this._pressed = KEY_DIRECTION.reduce((obj, keyName) => { + return Object.assign(Object.assign({}, obj), { + [keyName]: false + }); + }, {}); + } + _updateKeyPress(event, isEnable) { + const pressed = this._pressed; + const keyToUpdate = event.keyCode != null ? DIRECTION_KEY_CODE[event.keyCode] : DIRECTION_KEY_NAME[event.key]; + if (!keyToUpdate) return; + pressed[keyToUpdate] = isEnable; + } + _getPressedKeyCount() { + return KEY_DIRECTION.filter(key => this._pressed[key]).length; + } + _getDeltaByPressedKeys() { + const pressed = this._pressed; + let x = 0; + let y = 0; + if (pressed.LEFT) { + x += 1; + } + if (pressed.RIGHT) { + x -= 1; + } + if (pressed.UP) { + y += 1; + } + if (pressed.DOWN) { + y -= 1; + } + return { + x, + y + }; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Camera's rotation control + * @ko 카메라의 회전을 담당하는 컨트롤 + * @since 4.0.0 + */ + class RotateControl extends Component { + /** + * @copy CameraControl#enabled + */ + get enabled() { + return this._enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * @copy CameraControl#animating + */ + get animating() { + return this._keyboardInput.active || this._xMotion.activated || this._yMotion.activated; + } + /** + * Current yaw value + * @ko 현재 yaw 값 + * @readonly + * @since 4.0.0 + */ + get yaw() { + return this._xMotion; + } + /** + * Current pitch value + * @ko 현재 pitch 값 + * @readonly + * @since 4.0.0 + */ + get pitch() { + return this._yMotion; + } + /** + * @copy View360#scrollable + */ + get scrollable() { + return this._touchInput.scrollable; + } + set scrollable(val) { + this._touchInput.scrollable = val; + } + /** + * Scale factor for mouse/touch rotation + * @ko 마우스/터치를 통한 회전 배율 + * @default [1, 1] + * @since 4.0.0 + */ + get pointerScale() { + return this._pointerScale; + } + set pointerScale(val) { + this._pointerScale = val; + } + /** + * Scale factor for keyboard rotation + * @ko 키보드를 통한 회전 배율 + * @default [1, 1] + * @since 4.0.0 + */ + get keyboardScale() { + return this._keyboardScale; + } + set keyboardScale(val) { + this._keyboardScale = val; + } + /** + * Duration of the input animation (ms) + * @ko 회전 애니메이션의 시간 (ms) + * @default 300 + */ + get duration() { + return this._duration; + } + set duration(val) { + this._duration = val; + this._xMotion.duration = val; + this._yMotion.duration = val; + } + /** + * Easing function of the animation + * @ko 회전 애니메이션에 적용할 easing 함수 + * @default EASING.EASE_OUT_CUBIC + * @see EASING + */ + get easing() { + return this._easing; + } + set easing(val) { + this._easing = val; + this._xMotion.easing = val; + this._yMotion.easing = val; + } + /** + * Disable X-axis(pitch) rotation. + * @ko x축 회전(pitch)을 비활성화합니다. + * @default false + */ + get disablePitch() { + return this._disablePitch; + } + set disablePitch(val) { + this._disablePitch = val; + } + /** + * Disable Y-axis(yaw) rotation. + * @ko y축 회전(yaw)을 비활성화합니다. + * @default false + */ + get disableYaw() { + return this._disableYaw; + } + set disableYaw(val) { + this._disableYaw = val; + } + /** + * Disable rotation by keyboard. + * @ko 키보드를 이용한 회전을 비활성화합니다. + * @default false + */ + get disableKeyboard() { + return this._disableKeyboard; + } + set disableKeyboard(val) { + this._disableKeyboard = val; + } + /** + * Create new RotateControl instance + * @ko RotateControl의 인스턴스를 생성합니다. + * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트} + * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부} + * @param options - Options for control {@ko 컨트롤 옵션들} + */ + constructor(controlEl, enableBlocked, { + duration = DEFAULT_ANIMATION_DURATION, + easing = DEFAULT_EASING, + pointerScale = [1, 1], + keyboardScale = [1, 1], + disablePitch = false, + disableYaw = false, + disableKeyboard = false + } = {}) { + super(); + this._onInputStart = evt => { + this._changedWhileDragging = false; + this.trigger(CONTROL_EVENTS.INPUT_START, Object.assign(Object.assign({}, evt), { + inputType: "rotate" + })); + }; + this._onChange = evt => { + const delta = evt.delta; + const invZoomScale = 1 / this._zoomScale; // Reduce speed on zoom + const screenScale = this._screenScale; + const keyboardScale = this._keyboardScale; + const pointerScale = this._pointerScale; + let scale; + if (evt.isKeyboard) { + scale = [keyboardScale[0] * invZoomScale, keyboardScale[1] * invZoomScale]; + } else { + scale = [pointerScale[0] * screenScale[0] * invZoomScale, pointerScale[1] * screenScale[1] * invZoomScale]; + } + const scaledX = delta.x * scale[0]; + const scaledY = delta.y * scale[1]; + this._xMotion.setNewEndByDelta(scaledX); + this._yMotion.setNewEndByDelta(scaledY); + this._changedWhileDragging = true; + }; + this._onInputEnd = evt => { + this.trigger(CONTROL_EVENTS.INPUT_END, Object.assign(Object.assign({}, evt), { + inputType: "rotate" + })); + if (!this._changedWhileDragging && !evt.isKeyboard && !evt.scrolling) { + this.trigger(CONTROL_EVENTS.STATIC_CLICK, { + isTouch: evt.isTouch + }); + } + this._changedWhileDragging = false; + }; + this._controlEl = controlEl; + this._pointerScale = pointerScale; + this._keyboardScale = keyboardScale; + this._duration = duration; + this._easing = easing; + this._disablePitch = disablePitch; + this._disableYaw = disableYaw; + this._disableKeyboard = disableKeyboard; + this._enableBlocked = enableBlocked; + this._mouseInput = new MouseInput(); + this._touchInput = new TouchInput(); + this._keyboardInput = new KeyboardInput(); + this._xMotion = new Motion({ + duration, + range: INFINITE_RANGE, + easing + }); + this._yMotion = new Motion({ + duration, + range: DEFAULT_PITCH_RANGE, + easing + }); + this._screenScale = [1, 1]; + this._zoomScale = 1; + this._enabled = false; + this._changedWhileDragging = false; + this._bindInputs(); + } + destroy() { + this.disable(); + this._mouseInput.off(); + this._touchInput.off(); + this._keyboardInput.off(); + this.off(); + this._changedWhileDragging = false; + } + /** + * @hidden + */ + update(delta) { + if (!this._enabled) return; + const xMotion = this._xMotion; + const yMotion = this._yMotion; + const keyboardInput = this._keyboardInput; + if (!this._disableKeyboard) { + keyboardInput.update(); + } + if (!this._disablePitch) { + yMotion.update(delta); + } + if (!this._disableYaw) { + xMotion.update(delta); + } + } + /** + * @hidden + */ + updateRange(camera, zoom) { + const yawRange = camera.getYawRange(zoom); + const pitchRange = camera.getPitchRange(zoom); + this._xMotion.setRange(yawRange.min, yawRange.max); + this._yMotion.setRange(pitchRange.min, pitchRange.max); + } + /** + * @hidden + */ + setZoomScale(val) { + this._zoomScale = val; + } + /** + * Resize control to match target size. + * @ko 컨트롤의 내부 크기를 갱신합니다. + * @param hfov - Camera horizontal fov in degrees {@ko 카메라의 수평방향 fov값 (도 단위)} + * @param aspect - Camera aspect {@ko 카메라 가로/세로 비율} + * @param width - New width {@ko 갱신된 너비} + * @param height - New height {@ko 갱신된 높이} + */ + resize(hfov, aspect, width, height) { + const vfov = toVerticalFov(hfov * DEG_TO_RAD, aspect) * RAD_TO_DEG; + this._screenScale[0] = hfov / width; + this._screenScale[1] = vfov / height; + } + enable() { + if (this._enabled) return; + const element = this._controlEl; + this._mouseInput.enable(element); + this._touchInput.enable(element); + this._keyboardInput.enable(element); + this._enabled = true; + this._enableBlocked = false; + this.trigger(CONTROL_EVENTS.ENABLE, { + control: this, + updateCursor: true + }); + } + disable() { + if (!this._enabled) return; + this._mouseInput.disable(); + this._touchInput.disable(); + this._keyboardInput.disable(); + this._enabled = false; + this.trigger(CONTROL_EVENTS.DISABLE, { + updateCursor: true + }); + } + sync(camera) { + this.updateRange(camera, camera.zoom); + this._xMotion.reset(camera.yaw); + this._yMotion.reset(camera.pitch); + } + _bindInputs() { + const mouseInput = this._mouseInput; + const touchInput = this._touchInput; + const keyboardInput = this._keyboardInput; + mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + touchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + touchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + keyboardInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + keyboardInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + keyboardInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class WheelInput extends Component { + get scrollable() { + return this._scrollable; + } + set scrollable(val) { + this._scrollable = val; + } + constructor() { + super(); + this._onWheel = evt => { + const scrollable = this._scrollable; + if (evt.deltaY === 0 || scrollable) return; + evt.preventDefault(); + evt.stopPropagation(); + if (this._inputTimer < 0) { + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: false, + isKeyboard: false + }); + } else { + this._clearTimer(); + } + const delta = this._baseScale * evt.deltaY; + this.trigger(CONTROL_EVENTS.CHANGE, { + delta, + isTouch: false, + isKeyboard: false + }); + this._inputTimer = window.setTimeout(() => { + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: false, + isKeyboard: false, + scrolling: false + }); + this._inputTimer = -1; + }, DEFAULT_ANIMATION_DURATION); + }; + this._el = null; + this._baseScale = 0.04; + this._scrollable = false; + this._inputTimer = -1; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.WHEEL, this._onWheel, { + passive: false, + capture: false + }); + this._el = element; + this._clearTimer(); + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.WHEEL, this._onWheel, false); + this._el = null; + this._clearTimer(); + } + _clearTimer() { + window.clearTimeout(this._inputTimer); + this._inputTimer = -1; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class PinchInput extends Component { + constructor() { + super(); + this._onTouchMove = evt => { + const touches = evt.touches; + if (touches.length !== 2) return; + if (!evt.cancelable) return; + evt.preventDefault(); + evt.stopPropagation(); + const prevDistance = this._prevDistance; + const diff = [touches[0].pageX - touches[1].pageX, touches[0].pageY - touches[1].pageY]; + const distance = Math.sqrt(diff[0] * diff[0] + diff[1] * diff[1]) * this._baseScale; + const delta = this._isFirstTouch ? 0 : distance - prevDistance; + if (this._isFirstTouch) { + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: true, + isKeyboard: false + }); + } + this._prevDistance = distance; + this._isFirstTouch = false; + this.trigger(CONTROL_EVENTS.CHANGE, { + delta, + isTouch: true, + isKeyboard: false + }); + }; + this._onTouchEnd = evt => { + if (evt.touches.length !== 0) return; + if (!this._isFirstTouch) { + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: true, + isKeyboard: false, + scrolling: false + }); + } + this._prevDistance = -1; + this._isFirstTouch = true; + }; + this._el = null; + this._baseScale = -0.2; + this._prevDistance = -1; + this._isFirstTouch = true; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove, { + passive: false, + capture: false + }); + element.addEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = element; + this._prevDistance = -1; + this._isFirstTouch = true; + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove, false); + element.removeEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = null; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Camera's zoom control + * @ko 카메라의 줌 값을 담당하는 컨트롤 + * @since 4.0.0 + */ + class ZoomControl extends Component { + /** + * @copy CameraControl#enabled + */ + get enabled() { + return this._enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * @copy CameraControl#animating + */ + get animating() { + return this._motion.activated; + } + /** + * Current zoom value + * @ko 현재 줌 값 + * @since 4.0.0 + * @readonly + */ + get zoom() { + return this._motion.val; + } + /** + * @copy View360#wheelScrollable + */ + get scrollable() { + return this._wheelInput.scrollable; + } + set scrollable(val) { + this._wheelInput.scrollable = val; + } + /** + * @hidden + */ + get range() { + return this._motion.range; + } + /** + * Scale factor of the zoom + * @ko 입력에 의한 줌 배율 + * @default 1 + * @since 4.0.0 + */ + get scale() { + return this._scale; + } + set scale(val) { + this._scale = val; + } + /** + * Duration of the input animation (ms) + * @ko 회전 애니메이션의 시간 (ms) + * @default 300 + * @since 4.0.0 + */ + get duration() { + return this._motion.duration; + } + /** + * Easing function of the animation + * @ko 회전 애니메이션에 적용할 easing 함수 + * @default EASING.EASE_OUT_CUBIC + * @see EASING + * @since 4.0.0 + */ + get easing() { + return this._motion.easing; + } + /** + * Create new ZoomControl instance + * @ko ZoomControl의 인스턴스를 생성합니다. + * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트} + * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부} + * @param options - Options for control {@ko 컨트롤 옵션들} + */ + constructor(controlEl, enableBlocked, { + scale = 1, + duration = DEFAULT_ANIMATION_DURATION, + easing = DEFAULT_EASING + } = {}) { + super(); + this._onInputStart = evt => { + this.trigger(CONTROL_EVENTS.INPUT_START, Object.assign(Object.assign({}, evt), { + inputType: "zoom" + })); + }; + this._onChange = ({ + delta + }) => { + const scale = this._scale; + const scaledDelta = delta * scale; + this._motion.setNewEndByDelta(scaledDelta); + }; + this._onInputEnd = evt => { + this.trigger(CONTROL_EVENTS.INPUT_END, Object.assign(Object.assign({}, evt), { + inputType: "zoom" + })); + }; + this._scale = scale; + this._controlEl = controlEl; + this._enableBlocked = enableBlocked; + this._wheelInput = new WheelInput(); + this._pinchInput = new PinchInput(); + this._motion = new Motion({ + duration, + easing, + range: INFINITE_RANGE + }); + this._enabled = false; + this._bindInputs(); + } + destroy() { + this.disable(); + this._wheelInput.off(); + this._pinchInput.off(); + this.off(); + } + /** + * @hidden + */ + update(delta) { + if (!this._enabled) return; + const motion = this._motion; + motion.update(delta); + } + enable() { + if (this._enabled) return; + const element = this._controlEl; + this._wheelInput.enable(element); + this._pinchInput.enable(element); + this._enabled = true; + this._enableBlocked = false; + this.trigger(CONTROL_EVENTS.ENABLE, { + control: this, + updateCursor: false + }); + } + disable() { + if (!this._enabled) return; + this._wheelInput.disable(); + this._pinchInput.disable(); + this._enabled = false; + this.trigger(CONTROL_EVENTS.DISABLE, { + updateCursor: false + }); + } + sync(camera) { + const motion = this._motion; + const range = camera.getZoomRange(); + motion.setRange(range.min, range.max); + motion.reset(range.current); + } + _bindInputs() { + const wheelInput = this._wheelInput; + const pinchInput = this._pinchInput; + wheelInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + wheelInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + wheelInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + pinchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + pinchInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + pinchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + const ROTATE_CONSTANT = { + PITCH_DELTA: 1, + YAW_DELTA_BY_ROLL: 2, + YAW_DELTA_BY_YAW: 3 + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = { + targetAxis: [0, 1, 0], + meshPoint: [0, 0, 1] + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = { + targetAxis: [0, 1, 0], + meshPoint: [1, 0, 0] + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = { + targetAxis: [1, 0, 0], + meshPoint: [0, 0, 1] + }; + class GyroInput extends Component { + get enabled() { + return this._enabled; + } + get orientationUpdated() { + return this._orientationUpdated; + } + get ignoreRoll() { + return this._ignoreRoll; + } + set ignoreRoll(val) { + this._ignoreRoll = val; + } + constructor() { + super(); + this._onDeviceOrientation = evt => { + const prevOrientation = this._orientation; + const { + alpha, + beta, + gamma + } = evt; + if (alpha == null || beta == null || gamma == null) return; + prevOrientation.alpha = alpha; + prevOrientation.beta = beta; + prevOrientation.gamma = gamma; + this._orientationUpdated = true; + if (this._needsCalibrate) { + this._needsCalibrate = false; + this._calibrateSensor(); + } + }; + this._updateScreenOrientation = () => { + if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) { + this._screenOrientation = screen.orientation.angle; + } else if (window.orientation !== undefined) { + this._screenOrientation = window.orientation >= 0 ? window.orientation : 360 + window.orientation; + } else { + this._screenOrientation = 0; + } + }; + this.quaternion = create$1(); + this._orientation = { + alpha: 0, + beta: 90, + gamma: 0 + }; + this._yawOrigin = 0; + this._yawOffset = 0; + this._orientationUpdated = false; + this._screenOrientation = 0; + this._needsCalibrate = true; + this._enabled = false; + } + enable() { + if (this._enabled) return; + window.addEventListener(EVENTS$1.DEVICE_ORIENTATION, this._onDeviceOrientation); + window.addEventListener(EVENTS$1.ORIENTATION_CHANGE, this._updateScreenOrientation); + this._updateScreenOrientation(); + this._orientationUpdated = false; + this._needsCalibrate = true; + this._enabled = true; + } + disable() { + if (!this._enabled) return; + window.removeEventListener(EVENTS$1.DEVICE_ORIENTATION, this._onDeviceOrientation); + window.removeEventListener(EVENTS$1.ORIENTATION_CHANGE, this._updateScreenOrientation); + this._enabled = false; + } + update() { + this._updateRotation(); + this._orientationUpdated = false; + } + collectDelta() { + if (!this._orientationUpdated) { + return { + pitch: 0, + yaw: 0 + }; + } + const prevRotation = clone(this.quaternion); + this._updateRotation(); + this._orientationUpdated = false; + return this._toEulerDelta(prevRotation, this.quaternion); + } + setInitialRotation(yaw) { + this._yawOrigin = yaw; + } + _calibrateSensor() { + const yawOrigin = this._yawOrigin; + const rotation = this.quaternion; + this._yawOffset = 0; + this._updateRotation(); + const { + yaw: sensorYaw + } = quatToEuler(rotation); + this._yawOffset = sensorYaw - yawOrigin; + this._updateRotation(); + this._needsCalibrate = false; + } + _updateRotation() { + const rotation = this.quaternion; + const { + alpha, + beta, + gamma + } = this._orientation; + identity(rotation); + rotateY(rotation, rotation, (alpha - this._yawOffset) * DEG_TO_RAD); + rotateX(rotation, rotation, beta * DEG_TO_RAD); + rotateZ(rotation, rotation, -gamma * DEG_TO_RAD); + const screen = create$1(); + const screenAngle = -this._screenOrientation * 0.5 * DEG_TO_RAD; + const world = fromValues$1(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5)); + set(screen, 0, Math.sin(screenAngle), 0, Math.cos(screenAngle)); + multiply(rotation, rotation, screen); + multiply(rotation, rotation, world); + normalize(rotation, rotation); + } + _toEulerDelta(prevQuat, currentQuat) { + return { + yaw: this._getDeltaYaw(prevQuat, currentQuat), + pitch: this._getDeltaPitch(prevQuat, currentQuat) + }; + } + _getDeltaYaw(prvQ, curQ) { + const yawDeltaByYaw = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW); + const yawDeltaByRoll = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) * Math.sin(this._extractPitchFromQuat(curQ)); + return yawDeltaByRoll + yawDeltaByYaw; + } + _getDeltaPitch(prvQ, curQ) { + return this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA); + } + _getRotationDelta(prevQ, curQ, rotateKind) { + const targetAxis = fromValues$3(ROTATE_CONSTANT[rotateKind].targetAxis[0], ROTATE_CONSTANT[rotateKind].targetAxis[1], ROTATE_CONSTANT[rotateKind].targetAxis[2]); + const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint; + const prevQuaternion = clone(prevQ); + const curQuaternion = clone(curQ); + normalize(prevQuaternion, prevQuaternion); + normalize(curQuaternion, curQuaternion); + let prevPoint = fromValues$3(0, 0, 1); + let curPoint = fromValues$3(0, 0, 1); + transformQuat(prevPoint, prevPoint, prevQuaternion); + transformQuat(curPoint, curPoint, curQuaternion); + transformQuat(targetAxis, targetAxis, curQuaternion); + const rotateDistance = dot(targetAxis, cross(create$3(), prevPoint, curPoint)); + const rotateDirection = rotateDistance > 0 ? 1 : -1; + // when counter clock wise, use vec3.fromValues(0,1,0) + // when clock wise, use vec3.fromValues(0,-1,0) + // const meshPoint1 = vec3.fromValues(0, 0, 0); + const meshPoint2 = fromValues$3(meshPoint[0], meshPoint[1], meshPoint[2]); + let meshPoint3; + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + meshPoint3 = fromValues$3(0, rotateDirection, 0); + } else { + meshPoint3 = fromValues$3(rotateDirection, 0, 0); + } + transformQuat(meshPoint2, meshPoint2, curQuaternion); + transformQuat(meshPoint3, meshPoint3, curQuaternion); + const vecU = meshPoint2; + const vecV = meshPoint3; + const vecN = create$3(); + cross(vecN, vecU, vecV); + normalize$2(vecN, vecN); + const coefficientA = vecN[0]; + const coefficientB = vecN[1]; + const coefficientC = vecN[2]; + // a point on the plane + curPoint = fromValues$3(meshPoint[0], meshPoint[1], meshPoint[2]); + transformQuat(curPoint, curPoint, curQuaternion); + // a point should project on the plane + prevPoint = fromValues$3(meshPoint[0], meshPoint[1], meshPoint[2]); + transformQuat(prevPoint, prevPoint, prevQuaternion); + // distance between prevPoint and the plane + let distance = Math.abs(prevPoint[0] * coefficientA + prevPoint[1] * coefficientB + prevPoint[2] * coefficientC); + const projectedPrevPoint = create$3(); + subtract(projectedPrevPoint, prevPoint, scale(create$3(), vecN, distance)); + let trigonometricRatio = (projectedPrevPoint[0] * curPoint[0] + projectedPrevPoint[1] * curPoint[1] + projectedPrevPoint[2] * curPoint[2]) / (length(projectedPrevPoint) * length(curPoint)); + // defensive block + if (trigonometricRatio > 1) { + trigonometricRatio = 1; + } + const theta = Math.acos(trigonometricRatio); + const crossVec = cross(create$3(), curPoint, projectedPrevPoint); + distance = coefficientA * crossVec[0] + coefficientB * crossVec[1] + coefficientC * crossVec[2]; + let thetaDirection; + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + thetaDirection = distance > 0 ? 1 : -1; + } else { + thetaDirection = distance < 0 ? 1 : -1; + } + const deltaRadian = theta * thetaDirection * rotateDirection; + return deltaRadian * RAD_TO_DEG; + } + _extractPitchFromQuat(quaternion) { + const baseV = fromValues$3(0, 0, 1); + transformQuat(baseV, baseV, quaternion); + return -1 * Math.atan2(baseV[1], Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2))); + } + } + + /** + * Camera's rotation control by gyroscope + * @ko 자이로스코프를 이용한 회전 컨트롤 + * @since 4.0.0 + */ + class GyroControl extends Component { + /** + * @copy CameraControl#enabled + */ + get enabled() { + return this._input.enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * @copy CameraControl#animating + */ + get animating() { + return this._input.enabled && this._input.orientationUpdated; + } + /** + * When `true`, ignore gyroscope's roll(z-axis rotation) value. + * :::caution + * Setting `false` will ignore camera's range limit. + * Options like {@link View360Options#yawRange}, {@link View360Options#pitchRange} are ignored, and {@link CylinderProjection} also can't force it's camera range limit. + * ::: + * @ko `true`일 경우 자이로스코프 입력의 roll(z축 회전)값을 무시합니다. + * :::caution + * 이 값을 `false`로 설정할 경우 카메라 범위 제약을 무시합니다. + * {@link View360Options#yawRange}, {@link View360Options#pitchRange}와 같은 값은 무시되며, {@link CylinderProjection} 사용시에도 범위를 벗어날 수 있습니다. + * ::: + * @default true + * @since 4.0.0 + */ + get ignoreRoll() { + return this._ignoreRoll; + } + set ignoreRoll(val) { + this._ignoreRoll = val; + } + /** + * Return availability of the gyroscope. + * :::caution + * This will always return false until user permission under environments like iOS which requires user permission when using gyroscope. + * ::: + * @ko 자이로스코프 사용 가능 여부를 반환합니다. + * :::caution + * iOS와 같이 GyroScope 사용시 사용자 Permission을 요구하는 환경에서는 사용자 Permission을 받기 전까지 항상 `false`입니다. + * ::: + * @example + * ```ts + * const gyroAvailable = await GyroControl.isAvailable(); + * ``` + */ + static isAvailable() { + return __awaiter(this, void 0, void 0, function* () { + if (!DeviceMotionEvent) { + return false; + } + let onDeviceMotionChange; + const listenDeviceMotion = () => new Promise(res => { + onDeviceMotionChange = evt => { + res(evt.rotationRate && evt.rotationRate.alpha != null); + }; + window.addEventListener(EVENTS$1.DEVICE_MOTION, onDeviceMotionChange); + }); + const timeout = () => new Promise(res => { + setTimeout(() => res(false), 1000); + }); + return Promise.race([listenDeviceMotion(), timeout()]).then(available => { + window.removeEventListener(EVENTS$1.DEVICE_MOTION, onDeviceMotionChange); + return available; + }); + }); + } + /** + * Request user permission for gyroscope sensor. + * This can be used in environments like iOS which requires user permission when using gyroscope sensors. + * @ko 사용자의 sensor permission 취득을 요청합니다. + * iOS와 같이 gyroscope 사용시 사용자 Permission을 요구하는 환경에서 사용 가능합니다. + * @returns Whether the permission is granted {@ko 사용자 permission 취득 여부} + */ + static requestSensorPermission() { + return __awaiter(this, void 0, void 0, function* () { + // Request sensor permission, on iOS13+ + if (sensorCanBeEnabledIOS()) { + return DeviceMotionEvent.requestPermission().then(permissionState => { + return permissionState === "granted"; + }).catch(() => false); + } + return true; + }); + } + /** + * Create new GyroControl instance + * @ko GyroControl의 인스턴스를 생성합니다. + * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부} + * @param options - Options for control {@ko 컨트롤 옵션들} + */ + constructor(enableBlocked, { + ignoreRoll = true + } = {}) { + super(); + this._enableBlocked = enableBlocked; + this._ignoreRoll = ignoreRoll; + this._input = new GyroInput(); + } + /** + * @copy CameraControl#destroy + */ + destroy() { + this.disable(); + this._input.off(); + this.off(); + } + /** + * @hidden + */ + update(camera, yaw, pitch, zoom) { + if (!this._ignoreRoll) { + this._updateQuaternion(camera, zoom); + } else { + this._updateYawPitch(camera, yaw, pitch, zoom); + } + } + /** + * @copy CameraControl#enable + */ + enable() { + if (this._input.enabled) return; + this._input.enable(); + this._enableBlocked = false; + this.trigger(CONTROL_EVENTS.ENABLE, { + control: this, + updateCursor: false + }); + } + /** + * @copy CameraControl#disable + */ + disable() { + if (!this._input.enabled) return; + this._input.disable(); + this.trigger(CONTROL_EVENTS.DISABLE, { + updateCursor: false + }); + } + /** + * @copy CameraControl#sync + */ + sync() {} // eslint-disable-line @typescript-eslint/no-empty-function + _updateYawPitch(camera, yaw, pitch, zoom) { + const input = this._input; + if (!input.enabled) return; + const { + yaw: yawDelta, + pitch: pitchDelta + } = input.collectDelta(); + yaw.add(yawDelta); + pitch.add(pitchDelta); + camera.lookAt({ + yaw: yaw.val, + pitch: pitch.val, + zoom + }); + } + _updateQuaternion(camera, zoom) { + const input = this._input; + if (!input.enabled) return; + input.update(); + camera.rotate(input.quaternion, zoom); + } + } + + /** + * Panorama control for View360 + * @ko View360용 파노라마 컨트롤 + * @since 4.0.0 + */ + class PanoControl { + /** + * @copy View360#useGrabCursor + */ + get useGrabCursor() { + return this._useGrabCursor; + } + set useGrabCursor(val) { + if (val === this._useGrabCursor) return; + this._useGrabCursor = val; + if (val && this._enabled) { + this._setCursor(CURSOR.GRAB); + } else if (!val) { + this._setCursor(CURSOR.NONE); + } + } + /** + * @copy View360#disableContextMenu + */ + get disableContextMenu() { + return this._disableContextMenu; + } + set disableContextMenu(val) { + if (val === this._disableContextMenu) return; + this._disableContextMenu = val; + if (val && this._enabled) { + this._blockContextMenu(); + } else if (!val) { + this._restoreContextMenu(); + } + } + /** + * @copy View360#disableContextMenu + */ + get scrollable() { + return this._rotateControl.scrollable; + } + set scrollable(val) { + this._rotateControl.scrollable = val; + } + /** + * @copy View360#disableContextMenu + */ + get wheelScrollable() { + return this._zoomControl.scrollable; + } + set wheelScrollable(val) { + this._zoomControl.scrollable = val; + } + /** + * When `true`, disables rotation slow-down by zoom-value. + * @ko `true`일 경우 줌 된 정도에 따라 회전속도를 늦추는 동작을 비활성화합니다. + * @since 4.0.0 + */ + get ignoreZoomScale() { + return this._ignoreZoomScale; + } + set ignoreZoomScale(val) { + this._ignoreZoomScale = val; + } + /** + * Whether the control is enabled or not + * @ko 컨트롤 활성화 여부를 가리키는 값 + * @readonly + * @since 4.0.0 + */ + get enabled() { + return this._enabled; + } + /** + * @copy View360#rotate + */ + get rotate() { + return this._rotateControl; + } + /** + * @copy View360#zoom + */ + get zoom() { + return this._zoomControl; + } + /** + * @copy View360#gyro + */ + get gyro() { + return this._gyroControl; + } + /** + * Whether one of the controls is animating at the moment + * @ko 현재 컨트롤 중 하나라도 동작중인지 여부를 나타내는 값 + * @readonly + * @since 4.0.0 + */ + get animating() { + return this._rotateControl.animating || this._zoomControl.animating || this._gyroControl.animating; + } + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param element - Canvas element {@ko 캔버스 엘리먼트} + * @param camera - Camera instance {@ko Camera 인스턴스} + * @param options - Options for PanoControl {@ko PanoControl 옵션들} + */ + constructor(element, camera, { + useGrabCursor, + scrollable, + wheelScrollable, + disableContextMenu, + rotate, + zoom, + gyro + }) { + this._preventContextMenu = evt => { + evt.preventDefault(); + }; + this._onInputStart = evt => { + if (this._useGrabCursor && !evt.isKeyboard) { + this._setCursor(CURSOR.GRABBING); + } + }; + this._onInputEnd = evt => { + if (this._useGrabCursor && !evt.isKeyboard) { + this._setCursor(CURSOR.GRAB); + } + }; + this._onEnable = ({ + control, + updateCursor + }) => { + if (updateCursor && this._useGrabCursor) { + this._setCursor(CURSOR.GRAB); + } + control.sync(this._camera); + }; + this._onDisable = ({ + updateCursor + }) => { + if (updateCursor) { + this._setCursor(CURSOR.NONE); + } + }; + this._onCameraAnimationEnd = ({ + animation + }) => { + animation.getFinishPromise().then(() => { + this.sync(); + }); + }; + // Bind Options + this._useGrabCursor = useGrabCursor; + this._disableContextMenu = disableContextMenu; + // Set internal values + this._camera = camera; + this._controlEl = element; + this._ignoreZoomScale = false; + this._enabled = false; + this._rotateControl = new RotateControl(element, !rotate, getObjectOption(rotate)); + this._zoomControl = new ZoomControl(element, !zoom, getObjectOption(zoom)); + this._gyroControl = new GyroControl(!gyro, getObjectOption(gyro)); + this._rotateControl.scrollable = scrollable; + this._zoomControl.scrollable = wheelScrollable; + this._bindEvents(); + } + /** + * Destroy the instance and remove all event listeners attached. + * This also will reset CSS cursor to initial. + * @ko 인스턴스를 삭제하고 부착된 모든 이벤트 리스너를 제거합니다. + * 또한, 캔버스에 적용된 CSS cursor도 제거합니다. + * @since 4.0.0 + */ + destroy() { + this.disable(); + this._rotateControl.destroy(); + this._zoomControl.destroy(); + this._setCursor(CURSOR.NONE); + } + /** + * Resize control to match target size. + * @ko 컨트롤이 내부에 캐시하고 있는 크기값을 갱신합니다. + * @param width New width {@ko 변경된 너비} + * @param height New height {@ko 변경된 높이} + * @since 4.0.0 + */ + resize(width, height) { + const camera = this._camera; + this._rotateControl.resize(camera.fov, camera.aspect, width, height); + } + /** + * Enable this control and add event listeners. + * @ko 컨트롤을 활성화하고 이벤트 리스너들을 추가합니다. + * @since 4.0.0 + */ + enable() { + return __awaiter(this, void 0, void 0, function* () { + if (this._enabled) return; + if (!this._rotateControl.enableBlocked) { + this._rotateControl.enable(); + } + if (!this._zoomControl.enableBlocked) { + this._zoomControl.enable(); + } + if (!this._gyroControl.enableBlocked) { + if (yield GyroControl.isAvailable()) { + this._gyroControl.enable(); + } + } + this.sync(); + if (this._disableContextMenu) { + this._blockContextMenu(); + } + this._enabled = true; + }); + } + /** + * Disable this control and remove all event listeners + * @ko 컨트롤을 비활성화하고 모든 이벤트 리스너들을 제거합니다. + * @since 4.0.0 + */ + disable() { + if (!this._enabled) return; + this._rotateControl.disable(); + this._zoomControl.disable(); + this._gyroControl.disable(); + this._restoreContextMenu(); + this._enabled = false; + } + /** + * Update control by given deltaTime + * @ko 컨트롤을 주어진 시간만큼 업데이트합니다. + * @param delta Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위} + * @since 4.0.0 + * @internal + */ + update(delta) { + const camera = this._camera; + const rotateControl = this._rotateControl; + const zoomControl = this._zoomControl; + const gyroControl = this._gyroControl; + zoomControl.update(delta); + const zoom = hfovToZoom(camera.fov, zoomControl.zoom); + // Slow down rotation on zoom-in + const zoomScale = this._ignoreZoomScale ? 1 : Math.max(zoom, 1); + rotateControl.setZoomScale(zoomScale); + rotateControl.updateRange(camera, zoom); + rotateControl.update(delta); + const yaw = rotateControl.yaw; + const pitch = rotateControl.pitch; + if (gyroControl.enabled) { + gyroControl.update(camera, yaw, pitch, zoom); + } else { + camera.lookAt({ + yaw: yaw.val, + pitch: pitch.val, + zoom + }); + } + } + /** + * Synchronize this control's state to current camera state + * @ko 컨트롤을 카메라의 현재 상태와 동기화합니다. + * @since 4.0.0 + */ + sync() { + const camera = this._camera; + this._zoomControl.sync(camera); + this._rotateControl.sync(camera); + } + _blockContextMenu() { + const el = this._controlEl; + el.addEventListener(EVENTS$1.CONTEXT_MENU, this._preventContextMenu); + } + _restoreContextMenu() { + const el = this._controlEl; + el.removeEventListener(EVENTS$1.CONTEXT_MENU, this._preventContextMenu); + } + _setCursor(newCursor) { + if (!this._useGrabCursor && newCursor !== CURSOR.NONE) return; + const targetEl = this._controlEl; + targetEl.style.cursor = newCursor; + } + _bindEvents() { + const rotateControl = this._rotateControl; + const zoomControl = this._zoomControl; + rotateControl.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + rotateControl.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + rotateControl.on(CONTROL_EVENTS.ENABLE, this._onEnable); + rotateControl.on(CONTROL_EVENTS.DISABLE, this._onDisable); + zoomControl.on(CONTROL_EVENTS.ENABLE, this._onEnable); + zoomControl.on(CONTROL_EVENTS.DISABLE, this._onDisable); + this._camera.on(CAMERA_EVENTS.ANIMATION_END, this._onCameraAnimationEnd); + } + } + + /* + Copyright (c) 2020-present NAVER Corp. + name: @egjs/imready + license: MIT + author: NAVER Corp. + repository: https://github.com/naver/egjs-imready + version: 1.3.1 + */ + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + + /* global Reflect, Promise */ + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || { + __proto__: [] + } instanceof Array && function (d, b) { + d.__proto__ = b; + } || function (d, b) { + for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; + }; + + return extendStatics(d, b); + }; + + function __extends(d, b) { + extendStatics(d, b); + + function __() { + this.constructor = d; + } + + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + var __assign = function () { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + + return t; + }; + + return __assign.apply(this, arguments); + }; + function __spreadArrays() { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + + for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; + + return r; + } + + /* + egjs-imready + Copyright (c) 2020-present NAVER Corp. + MIT license + */ + var isWindow = typeof window !== "undefined"; + var ua = isWindow ? window.navigator.userAgent : ""; + var SUPPORT_COMPUTEDSTYLE = isWindow ? !!("getComputedStyle" in window) : false; + var IS_IE = /MSIE|Trident|Windows Phone|Edge/.test(ua); + var SUPPORT_ADDEVENTLISTENER = isWindow ? !!("addEventListener" in document) : false; + var WIDTH = "width"; + var HEIGHT = "height"; + + function getAttribute(el, name) { + return el.getAttribute(name) || ""; + } + function toArray(arr) { + return [].slice.call(arr); + } + function hasSizeAttribute(target, prefix) { + if (prefix === void 0) { + prefix = "data-"; + } + + return !!target.getAttribute(prefix + "width"); + } + function hasLoadingAttribute(target, prefix) { + if (prefix === void 0) { + prefix = "data-"; + } + + return "loading" in target && target.getAttribute("loading") === "lazy" || !!target.getAttribute(prefix + "lazy"); + } + function hasSkipAttribute(target, prefix) { + if (prefix === void 0) { + prefix = "data-"; + } + + return !!target.getAttribute(prefix + "skip"); + } + function addEvent(element, type, handler) { + if (SUPPORT_ADDEVENTLISTENER) { + element.addEventListener(type, handler, false); + } else if (element.attachEvent) { + element.attachEvent("on" + type, handler); + } else { + element["on" + type] = handler; + } + } + function removeEvent(element, type, handler) { + if (element.removeEventListener) { + element.removeEventListener(type, handler, false); + } else if (element.detachEvent) { + element.detachEvent("on" + type, handler); + } else { + element["on" + type] = null; + } + } + function innerWidth(el) { + return getSize(el, "Width"); + } + function innerHeight(el) { + return getSize(el, "Height"); + } + function getStyles(el) { + return (SUPPORT_COMPUTEDSTYLE ? window.getComputedStyle(el) : el.currentStyle) || {}; + } + + function getSize(el, name) { + var size = el["client" + name] || el["offset" + name]; + return parseFloat(size || getStyles(el)[name.toLowerCase()]) || 0; + } + + function getContentElements(element, tags, prefix) { + var skipElements = toArray(element.querySelectorAll(__spreadArrays(["[" + prefix + "skip] [" + prefix + "width]"], tags.map(function (tag) { + return ["[" + prefix + "skip] " + tag, tag + "[" + prefix + "skip]", "[" + prefix + "width] " + tag].join(", "); + })).join(", "))); + return toArray(element.querySelectorAll("[" + prefix + "width], " + tags.join(", "))).filter(function (el) { + return skipElements.indexOf(el) === -1; + }); + } + + /* + egjs-imready + Copyright (c) 2020-present NAVER Corp. + MIT license + */ + var elements = []; + function addAutoSizer(element, prefix) { + !elements.length && addEvent(window, "resize", resizeAllAutoSizers); + element.__PREFIX__ = prefix; + elements.push(element); + resize(element); + } + function removeAutoSizer(element, prefix) { + var index = elements.indexOf(element); + + if (index < 0) { + return; + } + + var fixed = getAttribute(element, prefix + "fixed"); + delete element.__PREFIX__; + element.style[fixed === HEIGHT ? WIDTH : HEIGHT] = ""; + elements.splice(index, 1); + !elements.length && removeEvent(window, "resize", resizeAllAutoSizers); + } + + function resize(element, prefix) { + if (prefix === void 0) { + prefix = "data-"; + } + + var elementPrefix = element.__PREFIX__ || prefix; + var dataWidth = parseInt(getAttribute(element, "" + elementPrefix + WIDTH), 10) || 0; + var dataHeight = parseInt(getAttribute(element, "" + elementPrefix + HEIGHT), 10) || 0; + var fixed = getAttribute(element, elementPrefix + "fixed"); + + if (fixed === HEIGHT) { + var size = innerHeight(element) || dataHeight; + element.style[WIDTH] = dataWidth / dataHeight * size + "px"; + } else { + var size = innerWidth(element) || dataWidth; + element.style[HEIGHT] = dataHeight / dataWidth * size + "px"; + } + } + + function resizeAllAutoSizers() { + elements.forEach(function (element) { + resize(element); + }); + } + + var Loader = + /*#__PURE__*/ + function (_super) { + __extends(Loader, _super); + + function Loader(element, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + _this.isReady = false; + _this.isPreReady = false; + _this.hasDataSize = false; + _this.hasLoading = false; + _this.isSkip = false; + + _this.onCheck = function (e) { + _this.clear(); + + if (e && e.type === "error") { + _this.onError(_this.element); + } + + if (_this.hasLoading && _this.checkElement()) { + // I'm not ready + return; + } // I'm pre-ready and ready! + + + var withPreReady = !_this.hasDataSize && !_this.hasLoading; + + _this.onReady(withPreReady); + }; + + _this.options = __assign({ + prefix: "data-" + }, options); + _this.element = element; + var prefix = _this.options.prefix; + _this.hasDataSize = hasSizeAttribute(element, prefix); + _this.isSkip = hasSkipAttribute(element, prefix); + _this.hasLoading = hasLoadingAttribute(element, prefix); + return _this; + } + + var __proto = Loader.prototype; + + __proto.check = function () { + if (this.isSkip || !this.checkElement()) { + // I'm Ready + this.onAlreadyReady(true); + return false; + } + + if (this.hasDataSize) { + addAutoSizer(this.element, this.options.prefix); + } + + if (this.hasDataSize || this.hasLoading) { + // I'm Pre Ready + this.onAlreadyPreReady(); + } // Wati Pre Ready, Ready + + + return true; + }; + + __proto.addEvents = function () { + var _this = this; + + var element = this.element; + this.constructor.EVENTS.forEach(function (name) { + addEvent(element, name, _this.onCheck); + }); + }; + + __proto.clear = function () { + var _this = this; + + var element = this.element; + this.constructor.EVENTS.forEach(function (name) { + removeEvent(element, name, _this.onCheck); + }); + this.removeAutoSizer(); + }; + + __proto.destroy = function () { + this.clear(); + this.off(); + }; + + __proto.removeAutoSizer = function () { + if (this.hasDataSize) { + // I'm already ready. + var prefix = this.options.prefix; + removeAutoSizer(this.element, prefix); + } + }; + + __proto.onError = function (target) { + this.trigger("error", { + element: this.element, + target: target + }); + }; + + __proto.onPreReady = function () { + if (this.isPreReady) { + return; + } + + this.isPreReady = true; + this.trigger("preReady", { + element: this.element, + hasLoading: this.hasLoading, + isSkip: this.isSkip + }); + }; + + __proto.onReady = function (withPreReady) { + if (this.isReady) { + return; + } + + withPreReady = !this.isPreReady && withPreReady; + + if (withPreReady) { + this.isPreReady = true; + } + + this.removeAutoSizer(); + this.isReady = true; + this.trigger("ready", { + element: this.element, + withPreReady: withPreReady, + hasLoading: this.hasLoading, + isSkip: this.isSkip + }); + }; + + __proto.onAlreadyError = function (target) { + var _this = this; + + setTimeout(function () { + _this.onError(target); + }); + }; + + __proto.onAlreadyPreReady = function () { + var _this = this; + + setTimeout(function () { + _this.onPreReady(); + }); + }; + + __proto.onAlreadyReady = function (withPreReady) { + var _this = this; + + setTimeout(function () { + _this.onReady(withPreReady); + }); + }; + + Loader.EVENTS = []; + return Loader; + }(Component); + + var ElementLoader = + /*#__PURE__*/ + function (_super) { + __extends(ElementLoader, _super); + + function ElementLoader() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = ElementLoader.prototype; + + __proto.setHasLoading = function (hasLoading) { + this.hasLoading = hasLoading; + }; + + __proto.check = function () { + if (this.isSkip) { + // I'm Ready + this.onAlreadyReady(true); + return false; + } + + if (this.hasDataSize) { + addAutoSizer(this.element, this.options.prefix); + this.onAlreadyPreReady(); + } else { + // has not data size + this.trigger("requestChildren"); + } + + return true; + }; + + __proto.checkElement = function () { + return true; + }; + + __proto.destroy = function () { + this.clear(); + this.trigger("requestDestroy"); + this.off(); + }; + + __proto.onAlreadyPreReady = function () { + // has data size + _super.prototype.onAlreadyPreReady.call(this); + + this.trigger("reqeustReadyChildren"); + }; + + ElementLoader.EVENTS = []; + return ElementLoader; + }(Loader); + + /** + * @alias eg.ImReady + * @extends eg.Component + */ + + var ImReadyManager = + /*#__PURE__*/ + function (_super) { + __extends(ImReadyManager, _super); + /** + * @param - ImReady's options + */ + + + function ImReadyManager(options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + _this.readyCount = 0; + _this.preReadyCount = 0; + _this.totalCount = 0; + _this.totalErrorCount = 0; + _this.isPreReadyOver = true; + _this.elementInfos = []; + _this.options = __assign({ + loaders: {}, + prefix: "data-" + }, options); + return _this; + } + /** + * Checks whether elements are in the ready state. + * @ko 엘리먼트가 준비 상태인지 체크한다. + * @elements - Elements to check ready status. 준비 상태를 체크할 엘리먼트들. + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check(document.querySelectorAll("img")).on({ + * preReadyElement: e => { + * // 1, 3 + * // 2, 3 + * // 3, 3 + * console.log(e.preReadyCount, e.totalCount), + * }, + * }); + * ``` + */ + + + var __proto = ImReadyManager.prototype; + + __proto.check = function (elements) { + var _this = this; + + var prefix = this.options.prefix; + this.clear(); + this.elementInfos = toArray(elements).map(function (element, index) { + var loader = _this.getLoader(element, { + prefix: prefix + }); + + loader.check(); + loader.on("error", function (e) { + _this.onError(index, e.target); + }).on("preReady", function (e) { + var info = _this.elementInfos[index]; + info.hasLoading = e.hasLoading; + info.isSkip = e.isSkip; + + var isPreReady = _this.checkPreReady(index); + + _this.onPreReadyElement(index); + + isPreReady && _this.onPreReady(); + }).on("ready", function (_a) { + var withPreReady = _a.withPreReady, + hasLoading = _a.hasLoading, + isSkip = _a.isSkip; + var info = _this.elementInfos[index]; + info.hasLoading = hasLoading; + info.isSkip = isSkip; + + var isPreReady = withPreReady && _this.checkPreReady(index); + + var isReady = _this.checkReady(index); // Pre-ready and ready occur simultaneously + + + withPreReady && _this.onPreReadyElement(index); + + _this.onReadyElement(index); + + isPreReady && _this.onPreReady(); + isReady && _this.onReady(); + }); + return { + loader: loader, + element: element, + hasLoading: false, + hasError: false, + isPreReady: false, + isReady: false, + isSkip: false + }; + }); + var length = this.elementInfos.length; + this.totalCount = length; + + if (!length) { + setTimeout(function () { + _this.onPreReady(); + + _this.onReady(); + }); + } + + return this; + }; + /** + * Gets the total count of elements to be checked. + * @ko 체크하는 element의 총 개수를 가져온다. + */ + + + __proto.getTotalCount = function () { + return this.totalCount; + }; + /** + * Whether the elements are all pre-ready. (all sizes are known) + * @ko 엘리먼트들이 모두 사전 준비가 됐는지 (사이즈를 전부 알 수 있는지) 여부. + */ + + + __proto.isPreReady = function () { + return this.elementInfos.every(function (info) { + return info.isPreReady; + }); + }; + /** + * Whether the elements are all ready. + * @ko 엘리먼트들이 모두 준비가 됐는지 여부. + */ + + + __proto.isReady = function () { + return this.elementInfos.every(function (info) { + return info.isReady; + }); + }; + /** + * Whether an error has occurred in the elements in the current state. + * @ko 현재 상태에서 엘리먼트들이 에러가 발생했는지 여부. + */ + + + __proto.hasError = function () { + return this.totalErrorCount > 0; + }; + /** + * Clears events of elements being checked. + * @ko 체크 중인 엘리먼트들의 이벤트를 해제 한다. + */ + + + __proto.clear = function () { + this.isPreReadyOver = false; + this.totalCount = 0; + this.preReadyCount = 0; + this.readyCount = 0; + this.totalErrorCount = 0; + this.elementInfos.forEach(function (info) { + if (info.loader) { + info.loader.destroy(); + } + }); + this.elementInfos = []; + }; + /** + * Destory all events. + * @ko 모든 이벤트를 해제 한다. + */ + + + __proto.destroy = function () { + this.clear(); + this.off(); + }; + + __proto.getLoader = function (element, options) { + var _this = this; + + var tagName = element.tagName.toLowerCase(); + var loaders = this.options.loaders; + var prefix = options.prefix; + var tags = Object.keys(loaders); + + if (loaders[tagName]) { + return new loaders[tagName](element, options); + } + + var loader = new ElementLoader(element, options); + var children = toArray(element.querySelectorAll(tags.join(", "))); + loader.setHasLoading(children.some(function (el) { + return hasLoadingAttribute(el, prefix); + })); + var withPreReady = false; + var childrenImReady = this.clone().on("error", function (e) { + loader.onError(e.target); + }).on("ready", function () { + loader.onReady(withPreReady); + }); + loader.on("requestChildren", function () { + // has not data size + var contentElements = getContentElements(element, tags, _this.options.prefix); + childrenImReady.check(contentElements).on("preReady", function (e) { + withPreReady = e.isReady; + + if (!withPreReady) { + loader.onPreReady(); + } + }); + }).on("reqeustReadyChildren", function () { + // has data size + // loader call preReady + // check only video, image elements + childrenImReady.check(children); + }).on("requestDestroy", function () { + childrenImReady.destroy(); + }); + return loader; + }; + + __proto.clone = function () { + return new ImReadyManager(__assign({}, this.options)); + }; + + __proto.checkPreReady = function (index) { + this.elementInfos[index].isPreReady = true; + ++this.preReadyCount; + + if (this.preReadyCount < this.totalCount) { + return false; + } + + return true; + }; + + __proto.checkReady = function (index) { + this.elementInfos[index].isReady = true; + ++this.readyCount; + + if (this.readyCount < this.totalCount) { + return false; + } + + return true; + }; + + __proto.onError = function (index, target) { + var info = this.elementInfos[index]; + info.hasError = true; + /** + * An event occurs if the image, video fails to load. + * @ko 이미지, 비디오가 로딩에 실패하면 이벤트가 발생한다. + * @event eg.ImReady#error + * @param {eg.ImReady.OnError} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check([document.querySelector("div")]).on({ + * error: e => { + * //
...
, 0, + * console.log(e.element, e.index, e.target), + * }, + * }); + * ``` + */ + + this.trigger(new ComponentEvent$1("error", { + element: info.element, + index: index, + target: target, + errorCount: this.getErrorCount(), + totalErrorCount: ++this.totalErrorCount + })); + }; + + __proto.onPreReadyElement = function (index) { + var info = this.elementInfos[index]; + /** + * An event occurs when the element is pre-ready (when the loading attribute is applied or the size is known) + * @ko 해당 엘리먼트가 사전 준비되었을 때(loading 속성이 적용되었거나 사이즈를 알 수 있을 때) 이벤트가 발생한다. + * @event eg.ImReady#preReadyElement + * @param {eg.ImReady.OnPreReadyElement} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check(document.querySelectorAll("img")).on({ + * preReadyElement: e => { + * // 1, 3 + * // 2, 3 + * // 3, 3 + * console.log(e.preReadyCount, e.totalCount), + * }, + * }); + * ``` + */ + + this.trigger(new ComponentEvent$1("preReadyElement", { + element: info.element, + index: index, + preReadyCount: this.preReadyCount, + readyCount: this.readyCount, + totalCount: this.totalCount, + isPreReady: this.isPreReady(), + isReady: this.isReady(), + hasLoading: info.hasLoading, + isSkip: info.isSkip + })); + }; + + __proto.onPreReady = function () { + this.isPreReadyOver = true; + /** + * An event occurs when all element are pre-ready (When all elements have the loading attribute applied or the size is known) + * @ko 모든 엘리먼트들이 사전 준비된 경우 (모든 엘리먼트들이 loading 속성이 적용되었거나 사이즈를 알 수 있는 경우) 이벤트가 발생한다. + * @event eg.ImReady#preReady + * @param {eg.ImReady.OnPreReady} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check(document.querySelectorAll("img")).on({ + * preReady: e => { + * // 0, 3 + * console.log(e.readyCount, e.totalCount), + * }, + * }); + * ``` + */ + + this.trigger(new ComponentEvent$1("preReady", { + readyCount: this.readyCount, + totalCount: this.totalCount, + isReady: this.isReady(), + hasLoading: this.hasLoading() + })); + }; + + __proto.onReadyElement = function (index) { + var info = this.elementInfos[index]; + /** + * An event occurs when the element is ready + * @ko 해당 엘리먼트가 준비가 되었을 때 이벤트가 발생한다. + * @event eg.ImReady#readyElement + * @param {eg.ImReady.OnReadyElement} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check(document.querySelectorAll("img")).on({ + * readyElement: e => { + * // 1, 0, false, 3 + * // 2, 1, false, 3 + * // 3, 2, true, 3 + * console.log(e.readyCount, e.index, e.hasError, e.totalCount), + * }, + * }); + * ``` + */ + + this.trigger(new ComponentEvent$1("readyElement", { + index: index, + element: info.element, + hasError: info.hasError, + errorCount: this.getErrorCount(), + totalErrorCount: this.totalErrorCount, + preReadyCount: this.preReadyCount, + readyCount: this.readyCount, + totalCount: this.totalCount, + isPreReady: this.isPreReady(), + isReady: this.isReady(), + hasLoading: info.hasLoading, + isPreReadyOver: this.isPreReadyOver, + isSkip: info.isSkip + })); + }; + + __proto.onReady = function () { + /** + * An event occurs when all element are ready + * @ko 모든 엘리먼트들이 준비된 경우 이벤트가 발생한다. + * @event eg.ImReady#ready + * @param {eg.ImReady.OnReady} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check(document.querySelectorAll("img")).on({ + * preReady: e => { + * // 0, 3 + * console.log(e.readyCount, e.totalCount), + * }, + * ready: e => { + * // 1, 3 + * console.log(e.errorCount, e.totalCount), + * }, + * }); + * ``` + */ + this.trigger(new ComponentEvent$1("ready", { + errorCount: this.getErrorCount(), + totalErrorCount: this.totalErrorCount, + totalCount: this.totalCount + })); + }; + + __proto.getErrorCount = function () { + return this.elementInfos.filter(function (info) { + return info.hasError; + }).length; + }; + + __proto.hasLoading = function () { + return this.elementInfos.some(function (info) { + return info.hasLoading; + }); + }; + + return ImReadyManager; + }(Component); + + var ImageLoader = + /*#__PURE__*/ + function (_super) { + __extends(ImageLoader, _super); + + function ImageLoader() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = ImageLoader.prototype; + + __proto.checkElement = function () { + var element = this.element; + var src = element.getAttribute("src"); + + if (element.complete) { + if (src) { + // complete + if (!element.naturalWidth) { + this.onAlreadyError(element); + } + + return false; + } else { + // Using an external lazy loading module + this.onAlreadyPreReady(); + } + } + + this.addEvents(); + IS_IE && element.setAttribute("src", src); + return true; + }; + + ImageLoader.EVENTS = ["load", "error"]; + return ImageLoader; + }(Loader); + + var VideoLoader = + /*#__PURE__*/ + function (_super) { + __extends(VideoLoader, _super); + + function VideoLoader() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = VideoLoader.prototype; + + __proto.checkElement = function () { + var element = this.element; // HAVE_NOTHING: 0, no information whether or not the audio/video is ready + // HAVE_METADATA: 1, HAVE_METADATA - metadata for the audio/video is ready + // HAVE_CURRENT_DATA: 2, data for the current playback position is available, but not enough data to play next frame/millisecond + // HAVE_FUTURE_DATA: 3, data for the current and at least the next frame is available + // HAVE_ENOUGH_DATA: 4, enough data available to start playing + + if (element.readyState >= 1) { + return false; + } + + if (element.error) { + this.onAlreadyError(element); + return false; + } + + this.addEvents(); + return true; + }; + + VideoLoader.EVENTS = ["loadedmetadata", "error"]; + return VideoLoader; + }(Loader); + + var ImReady = + /*#__PURE__*/ + function (_super) { + __extends(ImReady, _super); + + function ImReady(options) { + if (options === void 0) { + options = {}; + } + + return _super.call(this, __assign({ + loaders: { + img: ImageLoader, + video: VideoLoader + } + }, options)) || this; + } + + return ImReady; + }(ImReadyManager); + + /* + egjs-imready + Copyright (c) 2020-present NAVER Corp. + MIT license + */ + + var ImReady$1 = ImReady; + + /** + * @hidden + */ + class Texture { + constructor({ + width, + height, + flipY + }) { + this.width = width; + this.height = height; + this.flipY = flipY; + this.wrapS = WebGLRenderingContext.CLAMP_TO_EDGE; + this.wrapT = WebGLRenderingContext.CLAMP_TO_EDGE; + } + destroy() { + // DO_NOTHING + } + isVideo() { + return false; + } + isCube() { + return false; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class Texture2D extends Texture { + constructor({ + source, + width, + height, + flipY + }) { + super({ + width, + height, + flipY + }); + this.source = source; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class TextureVideo extends Texture2D { + destroy() { + const video = this.source; + video.pause(); + video.removeAttribute("src"); + video.load(); + } + isVideo() { + return true; + } + isPaused() { + const video = this.source; + return video.paused || video.ended || video.readyState <= 2; + } + hasAudio() { + const video = this.source; + if (video.audioTracks) { + return video.audioTracks.length > 0; + } + if (video.webkitAudioDecodedByteCount != null) { + return video.webkitAudioDecodedByteCount > 0; + } + if (video.mozHasAudio != null) { + return video.mozHasAudio; + } + // We don't know whether the video has audio or not, return true + return true; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class TextureCube extends Texture { + constructor({ + sources, + width, + height, + flipY + }) { + super({ + width, + height, + flipY + }); + this.sources = sources; + } + isCube() { + return true; + } + } + + /** + * @hidden + */ + class TextureLoader { + constructor() { + this._loadChecker = new ImReady$1(); + } + load(src, video) { + return __awaiter(this, void 0, void 0, function* () { + if (video) { + return this.loadVideo(src, getObjectOption(video)); + } else { + if (Array.isArray(src) && src.length > 1) { + return this.loadCubeImage(src); + } else { + const imgSrc = Array.isArray(src) ? src[0] : src; + return this.loadImage(imgSrc); + } + } + }); + } + loadImage(src) { + return __awaiter(this, void 0, void 0, function* () { + const images = this._toImageArray(src); + return this._load(images, resolve => { + const image = images[0]; + resolve(new Texture2D({ + source: image, + width: image.naturalWidth, + height: image.naturalHeight, + flipY: true + })); + }); + }); + } + loadCubeImage(src) { + return __awaiter(this, void 0, void 0, function* () { + const images = this._toImageArray(src); + return this._load(images, resolve => { + resolve(new TextureCube({ + sources: images, + width: images[0].naturalWidth, + height: images[0].naturalHeight, + flipY: false + })); + }); + }); + } + loadVideo(src, videoConfig) { + return __awaiter(this, void 0, void 0, function* () { + const config = Object.assign({ + autoplay: true, + muted: true, + loop: false, + volume: 1 + }, videoConfig); + const video = this._toVideoElement(src, config); + return this._load([video], resolve => { + const { + autoplay, + muted + } = config; + video.currentTime = 0; + if (autoplay && muted) { + video.play().catch(() => void 0); + } + resolve(new TextureVideo({ + source: video, + width: video.videoWidth, + height: video.videoHeight, + flipY: true + })); + }); + }); + } + _load(content, onLoad) { + const loader = this._loadChecker; + return new Promise((resolve, reject) => { + loader.once("ready", evt => { + if (evt.errorCount > 0) return; + onLoad(resolve); + }); + loader.once("error", reject); + loader.check(content); + }); + } + _toImageArray(src) { + const srcs = Array.isArray(src) ? src : [src]; + return srcs.map(source => { + if (isString(source)) { + const imgEl = new Image(); + imgEl.crossOrigin = "anonymous"; + imgEl.src = source; + return imgEl; + } else { + return source; + } + }); + } + _toVideoElement(src, { + muted, + loop, + volume + }) { + if (src instanceof HTMLVideoElement) { + return src; + } + const video = document.createElement("video"); + video.crossOrigin = "anonymous"; + video.playsInline = true; + video.setAttribute("webkit-playsinline", ""); + video.muted = muted; + video.volume = volume; + video.loop = loop; + if (Array.isArray(src)) { + src.forEach(source => this._appendSourceElement(video, source)); + } else { + this._appendSourceElement(video, src); + } + const sourceCount = video.querySelectorAll("source").length; + if (sourceCount > 0 && video.readyState < 1) { + video.load(); + } + return video; + } + _appendSourceElement(video, src) { + if (src instanceof HTMLSourceElement) { + return src; + } + const sourceEl = document.createElement("source"); + sourceEl.src = src; + video.appendChild(sourceEl); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @internal + */ + class FrameAnimator { + /** */ + constructor(maxDeltaTime, context = window) { + this.maxDeltaTime = maxDeltaTime; + this._context = context; + this._rafId = -1; + this._rafTimer = -1; + this._lastUpdateTime = -1; + } + start(callback) { + const context = this._context; + // No context / callback set + if (!context || !callback) return; + // Animation already started + if (this._rafId >= 0 || this._rafTimer >= 0) return; + const loop = (_time, frame) => { + const time = Date.now(); + const delta = Math.min(time - this._lastUpdateTime, this.maxDeltaTime * 1000); + callback(delta, frame); + this._lastUpdateTime = time; + this._rafId = context.requestAnimationFrame(loop); + }; + this._lastUpdateTime = Date.now(); + this._rafId = context.requestAnimationFrame(loop); + } + stop() { + if (this._rafId >= 0) { + this._context.cancelAnimationFrame(this._rafId); + } + if (this._rafTimer >= 0) { + clearTimeout(this._rafTimer); + } + this._rafId = -1; + this._rafTimer = -1; + } + changeContext(context) { + this.stop(); + this._context = context; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Automatic resizer that uses both ResizeObserver and window resize event + */ + class AutoResizer { + get useResizeObserver() { + return this._useResizeObserver; + } + /** + * Returns whether AutoResizer is enabled + */ + get enabled() { + return this._enabled; + } + /** */ + constructor(useResizeObserver, onResize) { + // eslint-disable-next-line @typescript-eslint/member-ordering + this._skipFirstResize = (() => { + let isFirstResize = true; + return () => { + if (isFirstResize) { + isFirstResize = false; + return; + } + this._onResize(); + }; + })(); + this._useResizeObserver = useResizeObserver; + this._enabled = false; + this._resizeObserver = null; + this._onResize = onResize; + } + /** + * Enable resizer + */ + enable(element) { + if (this._enabled) { + this.disable(); + } + if (this._useResizeObserver && !!window.ResizeObserver) { + const bbox = element.getBoundingClientRect(); + const resizeImmediate = bbox.width !== 0 || bbox.height !== 0; + const resizeObserver = new ResizeObserver(resizeImmediate ? this._skipFirstResize : this._onResize); + resizeObserver.observe(element); + this._resizeObserver = resizeObserver; + } else { + window.addEventListener(EVENTS$1.RESIZE, this._onResize); + } + this._enabled = true; + return this; + } + /** + * Disable resizer + */ + disable() { + if (!this._enabled) return this; + const resizeObserver = this._resizeObserver; + if (resizeObserver) { + resizeObserver.disconnect(); + this._resizeObserver = null; + } else { + window.removeEventListener(EVENTS$1.RESIZE, this._onResize); + } + this._enabled = false; + return this; + } + } + + /** + * A manager class for autoplay feature. + * @ko Autoplay 기능의 매니저 클래스. + * @since 4.0.0 + */ + class Autoplay { + /** + * Whether autoplay is enabled or not + * @ko 자동재생 활성화 여부를 나타내는 값 + * @readonly + * @since 4.0.0 + */ + get enabled() { + return this._enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * Whether autoplay is updating the camera at the moment + * @ko 현재 자동재생이 동작중인지 여부를 나타내는 값 + * @readonly + * @since 4.0.0 + */ + get playing() { + return this._enabled && !this._interrupted; + } + /** + * Reactivation delay after mouse input in milisecond. + * @ko 재활성화되기까지의 시간 (밀리초 단위) + * @default 2000 + * @since 4.0.0 + */ + get delay() { + return this._delay; + } + set delay(val) { + this._delay = val; + } + /** + * Reactivation delay after mouse leave when using {@link AutoplayOptions#pauseOnHover} + * @ko {@link AutoplayOptions#pauseOnHover} 사용시 마우스가 캔버스 영역을 떠난 뒤 자동재생이 다시 활성화되기까지의 시간 + * @default 0 + * @since 4.0.0 + */ + get delayOnMouseLeave() { + return this._delayOnMouseLeave; + } + set delayOnMouseLeave(val) { + this._delayOnMouseLeave = val; + } + /** + * Y-axis(yaw) rotation speed + * @ko Y-축 회전(yaw)의 속도 + * @default 1 + * @since 4.0.0 + */ + get speed() { + return this._speed; + } + set speed(val) { + this._speed = val; + } + /** + * Whether to pause rotation on mouse hover + * @ko 마우스가 캔버스 영역에 들어왔을 때 자동재생을 정지할지 여부 + * @default false + * @since 4.0.0 + */ + get pauseOnHover() { + return this._pauseOnHover; + } + set pauseOnHover(val) { + this._pauseOnHover = val; + } + /** + * Whether user can interrupt the rotation with click/wheel input + * @ko 클릭이나 휠같은 사용자 인터랙션시 자동재생을 멈출지 여부 + * @default true + * @since 4.0.0 + */ + get canInterrupt() { + return this._canInterrupt; + } + set canInterrupt(val) { + this._canInterrupt = val; + } + /** + * Whether to disable autoplay on user interrupt + * @ko 사용자 동작에 의해 자동재생이 정지할 때, {@link Autoplay#disable}을 호출하여 자동재생을 영구히 정지할지 여부 + * @default false + * @since 4.0.0 + */ + get disableOnInterrupt() { + return this._disableOnInterrupt; + } + set disableOnInterrupt(val) { + this._disableOnInterrupt = val; + } + /** + * Create new AutoPlayer instance + * @param camera - Instance of the {@link Camera} {@ko Camera의 인스턴스} + * @param element - Canvas element {@ko 캔버스 엘리먼트} + * @param options - Autoplay options {@ko 자동재생 옵션들} + * @since 4.0.0 + */ + constructor(viewer, element, options) { + this._onInputStart = () => { + if (!this._canInterrupt) return; + this._interrupted = true; + this._clearTimeout(); + }; + this._onInputEnd = () => { + this._setUninterruptedAfterDelay(this._delay); + }; + this._onGyroEnable = () => { + this.disable(); + }; + this._onMouseEnter = () => { + if (!this._pauseOnHover) return; + this._interrupted = true; + this._hovering = true; + }; + this._onMouseLeave = () => { + if (!this._pauseOnHover) return; + this._hovering = false; + this._setUninterruptedAfterDelay(this._delayOnMouseLeave); + }; + this._camera = viewer.camera; + this._control = viewer.control; + this._element = element; + this._enabled = false; + this._interrupted = false; + this._interruptionTimer = -1; + this._hovering = false; + const { + delay = 2000, + delayOnMouseLeave = 0, + speed = 1, + pauseOnHover = false, + canInterrupt = true, + disableOnInterrupt = false + } = getObjectOption(options); + this._enableBlocked = !options; + this._delay = delay; + this._delayOnMouseLeave = delayOnMouseLeave; + this._speed = speed; + this._pauseOnHover = pauseOnHover; + this._canInterrupt = canInterrupt; + this._disableOnInterrupt = disableOnInterrupt; + } + /** + * Destroy the instance and remove all event listeners attached + * @ko 인스턴스를 제거하고 연결된 모든 이벤트 핸들러를 삭제합니다. + * @since 4.0.0 + */ + destroy() { + this.disable(); + } + /** + * Rotate camera by given deltaTime + * @ko 주어진 deltaTime만큼 카메라를 회전시킵니다. + * @param deltaTime - Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위} + * @since 4.0.0 + */ + update(deltaTime) { + if (!this._enabled) return; + if (this._interrupted) { + if (this._disableOnInterrupt) { + this.disable(); + } + return; + } + const camera = this._camera; + const delta = -this._speed * deltaTime / 100; + camera.yaw = circulate(camera.yaw + delta, 0, 360); + } + /** + * Enable autoplay and add event listeners. + * @ko 자동재생을 활성화하고 이벤트리스너들을 추가합니다. + * @since 4.0.0 + */ + enable() { + const control = this._control; + const element = this._element; + if (this._enabled || control.gyro.enabled) return; + control.rotate.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.rotate.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.zoom.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.zoom.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.gyro.on(CONTROL_EVENTS.ENABLE, this._onGyroEnable); + element.addEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter, false); + element.addEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave, false); + this._enabled = true; + this._enableBlocked = false; + } + /** + * Enable autoplay after current `delay` value. + * @ko 현재의 `delay`값만큼 시간이 지난 다음에 자동재생을 활성화합니다. + * @since 4.0.0 + */ + enableAfterDelay() { + this.enable(); + this._interrupted = true; + this._setUninterruptedAfterDelay(this._delay); + } + /** + * Disable autoplay and remove all event handlers. + * @ko 자동재생을 비활성화하고 모든 이벤트 핸들러를 제거합니다. + * @since 4.0.0 + */ + disable() { + if (!this._enabled) return; + const control = this._control; + const element = this._element; + control.rotate.off(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.rotate.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.zoom.off(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.zoom.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.gyro.off(CONTROL_EVENTS.ENABLE, this._onGyroEnable); + element.removeEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter, false); + element.removeEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave, false); + this._enabled = false; + this._interrupted = false; + this._hovering = false; + this._clearTimeout(); + } + _setUninterruptedAfterDelay(delay) { + if (this._hovering) return; + this._clearTimeout(); + if (delay > 0) { + this._interruptionTimer = window.setTimeout(() => { + this._interrupted = false; + this._interruptionTimer = -1; + }, delay); + } else { + this._interrupted = false; + this._interruptionTimer = -1; + } + } + _clearTimeout() { + if (this._interruptionTimer >= 0) { + window.clearTimeout(this._interruptionTimer); + this._interruptionTimer = -1; + } + } + } + + /** + * WebXR manager class + * @ko WebXR 매니저 클래스 + * @since 4.0.0 + */ + class XRManager extends Component { + /** + * Create new instance. + * 새 인스턴스를 생성합니다. + * @param ctx - Instance of WebGL context helper {@ko WebGL 콘텍스트 헬퍼의 인스턴스} + * @param options - Options {@ko 옵션들} + */ + constructor(ctx, options = {}) { + super(); + /** + * Destroy instance and end XR session if there was any. + * @ko 인스턴스를 제거하고, XR 세션이 존재할 경우 종료합니다. + * @since 4.0.0 + */ + this.destroy = () => { + this.exit(); + this.off(); + }; + this._onSessionEnd = () => { + this.exit(); + this.trigger(EVENTS.VR_END); + }; + this._xrSession = null; + this._xrRefSpace = null; + this._ctx = ctx; + this._options = options; + } + /** + * Returns WebXR availability. + * @ko WebXR 사용 가능 여부를 반환합니다. + * @since 4.0.0 + */ + isAvailable() { + return __awaiter(this, void 0, void 0, function* () { + // eslint-disable-next-line compat/compat + const xr = window.navigator.xr; + if (!xr) return false; + return xr.isSessionSupported(SESSION_VR).then(available => { + return available; + }).catch(() => { + return false; + }); + }); + } + /** + * Enter VR session + * @ko VR 세션에 진입합니다. + * @since 4.0.0 + */ + enter() { + return __awaiter(this, void 0, void 0, function* () { + const ctx = this._ctx; + // eslint-disable-next-line compat/compat + const xr = window.navigator.xr; + if (!xr) return; + yield GyroControl.requestSensorPermission(); + const options = Object.assign({ + requiredFeatures: [XR_REFERENCE_SPACE] + }, this._options); + yield ctx.makeXRCompatible(); + const session = yield xr.requestSession(SESSION_VR, options); + ctx.bindXRLayer(session); + const refSpace = yield session.requestReferenceSpace(XR_REFERENCE_SPACE); + this._setSession(session, refSpace); + this.trigger(EVENTS.VR_START, { + session + }); + }); + } + /** + * Exit VR session + * @ko VR 세션에서 나갑니다. + * @since 4.0.0 + */ + exit() { + const xrSession = this._xrSession; + if (xrSession) { + xrSession.end().catch(() => void 0); + } + this._xrSession = null; + this._xrRefSpace = null; + } + /** + * @hidden + */ + canRender(frame) { + const refSpace = this._xrRefSpace; + if (!refSpace) return false; + const pose = frame.getViewerPose(refSpace); + return !!pose; + } + /** + * @hidden + */ + getEyeParams(frame) { + const session = frame.session; + const pose = frame.getViewerPose(this._xrRefSpace); + if (!pose) return null; + const glLayer = session.renderState.baseLayer; + if (!glLayer) return null; + return pose.views.map(view => { + const viewport = glLayer.getViewport(view); + const vMatrix = view.transform.inverse.matrix; + return { + viewport, + vMatrix, + pMatrix: view.projectionMatrix + }; + }); + } + _setSession(session, refSpace) { + this._xrSession = session; + this._xrRefSpace = refSpace; + session.addEventListener(EVENTS$1.XR_END, this._onSessionEnd); + } + } + + /** + * Hotspot data + * @ko 핫스팟 데이터 + * @since 4.0.0 + */ + class Hotspot { + constructor(element, position) { + this.element = element; + this.position = position; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Hotspot renderer + * @ko Hotspot 렌더러 + * @since 4.0.0 + */ + class HotspotRenderer { + /** + * Create new instance + * @ko 새 인스턴스를 생성합니다. + * @param rootEl - Container element for hotspots {@ko 핫스팟들의 컨테이너 엘리먼트} + * @param renderer - instance of WebGLRenderer {@ko WebGLRenderer의 인스턴스} + * @param options - Hotspot options {@ko Hotspot 옵션들 } + */ + constructor(rootEl, renderer, { + zoom = false + }) { + this._containerEl = getNullableElement(`.${DEFAULT_CLASS.HOTSPOT_CONTAINER}`, rootEl); + this._renderer = renderer; + this._hotspots = []; + this._zoom = zoom; + } + /** + * Refresh hotspots by collecting hotspot elements from current hotspot root element + * @ko 현재 핫스팟 루트 엘리먼트 내에서 핫스팟 엘리먼트들을 수집하여 갱신합니다. + * @throws {ERROR_CODES.INSUFFICIENT_ARGS} if data-position doesn't include all x, y, z values {@ko data-position이 x, y, z좌표를 전부 포함하고 있지 않을 때} + */ + refresh() { + const container = this._containerEl; + if (!container) return; + const hotspotEls = [].slice.apply(container.querySelectorAll(`.${DEFAULT_CLASS.HOTSPOT}`)); + this._hotspots = hotspotEls.map(el => this._parseHotspot(el)); + } + /** + * Render hotspots + * @ko 핫스팟들을 렌더링합니다. + * @param camera - Instance of Camera {@ko Camera의 인스턴스} + */ + render(camera) { + const hotspots = this._hotspots; + const halfWidth = this._renderer.width * 0.5; + const halfHeight = this._renderer.height * 0.5; + const zoom = camera.zoom; + const centerTransform = "translate(-50%, -50%)"; + const zoomTransform = this._zoom ? `scale(${zoom})` : ""; + hotspots.forEach(hotspot => { + const position = hotspot.position; + const relPos = create$3(); + copy$2(relPos, position); + transformMat4(relPos, relPos, camera.viewMatrix); + transformMat4(relPos, relPos, camera.projectionMatrix); + if (relPos[2] > 1 || relPos[2] < 0) { + hotspot.element.classList.remove(DEFAULT_CLASS.HOTSPOT_VISIBLE); + return; + } + const screenPos = fromValues(relPos[0] * halfWidth + halfWidth, -relPos[1] * halfHeight + halfHeight); + hotspot.element.classList.add(DEFAULT_CLASS.HOTSPOT_VISIBLE); + hotspot.element.style.transform = [centerTransform, `translate(${screenPos[0]}px, ${screenPos[1]}px)`, zoomTransform].join(" "); + }); + } + _parseHotspot(element) { + const yawStr = element.dataset.yaw; + const pitchStr = element.dataset.pitch; + const positionStr = element.dataset.position; + if (yawStr || pitchStr) { + const yaw = yawStr ? parseFloat(yawStr) : 0; + const pitch = pitchStr ? parseFloat(pitchStr) : 0; + const position = this._yawPitchToVec3(yaw, pitch); + return new Hotspot(element, position); + } else if (positionStr) { + const pos = positionStr.split(" ").map(val => parseFloat(val)); + if (pos.length < 3) { + throw new View360Error(ERROR.MESSAGES.INSUFFICIENT_ARGS(positionStr, "hotspot attribute \"data-position\""), ERROR.CODES.INSUFFICIENT_ARGS); + } + return new Hotspot(element, fromValues$3(pos[0], pos[1], pos[2])); + } else { + // Place hotspot at yaw: 0, pitch: 0 + const defaultPos = fromValues$3(0, 0, -1); + return new Hotspot(element, defaultPos); + } + } + _yawPitchToVec3(yaw, pitch) { + const yawRad = yaw * DEG_TO_RAD; + const pitchRad = pitch * DEG_TO_RAD; + const position = create$3(); + position[1] = Math.sin(pitchRad); + position[2] = Math.cos(pitchRad); + position[0] = position[2] * Math.sin(-yawRad); + position[2] = -position[2] * Math.cos(-yawRad); + return position; + } + } + + /** + * @hidden + */ + class VertexArrayObject { + get count() { + return this.geometry.indicies.count; + } + constructor(obj, geometry, buffers) { + this.obj = obj; + this.geometry = geometry; + this.buffers = buffers; + } + } + + /** + * @hidden + */ + class WebGLContext { + get canvas() { + return this._canvas; + } + get maxTextureSize() { + return this._maxTextureSize; + } + get isWebGL2() { + return this._isWebGL2; + } + get supportVAO() { + return this._isWebGL2 || !!this._extensions.vao; + } + get lost() { + return this._contextLost; + } + get debug() { + return this._debug; + } + constructor(canvas, debug) { + this._onContextLost = () => { + const canvas = this._canvas; + canvas.classList.add(DEFAULT_CLASS.CTX_LOST); + this._contextLost = true; + }; + this._onContextRestore = () => { + const canvas = this._canvas; + canvas.classList.remove(DEFAULT_CLASS.CTX_LOST); + this._contextLost = false; + }; + this._canvas = canvas; + this._contextLost = false; + this._debug = debug; + this._extensions = { + vao: null, + loseContext: null + }; + } + init() { + const canvas = this._canvas; + const { + gl, + isWebGL2 + } = this._getContext(canvas); + this._gl = gl; + this._maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); + this._isWebGL2 = isWebGL2; + if (!this._isWebGL2) { + this._extensions.vao = gl.getExtension("OES_vertex_array_object"); + } + this._extensions.loseContext = gl.getExtension("WEBGL_lose_context"); + canvas.addEventListener(EVENTS$1.CONTEXT_LOST, this._onContextLost); + canvas.addEventListener(EVENTS$1.CONTEXT_RESTORED, this._onContextRestore); + // gl.enable(gl.DEPTH_TEST); + } + + destroy() { + const gl = this._gl; + const canvas = this._canvas; + if (gl) { + // gl is not defined when destroy is called before init + gl.bindBuffer(gl.ARRAY_BUFFER, null); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + } + canvas.removeEventListener(EVENTS$1.CONTEXT_LOST, this._onContextLost); + canvas.removeEventListener(EVENTS$1.CONTEXT_RESTORED, this._onContextRestore); + } + forceLoseContext() { + const extension = this._extensions.loseContext; + if (!extension) return; + extension.loseContext(); + } + forceRestoreContext() { + const extension = this._extensions.loseContext; + if (!extension) return; + extension.restoreContext(); + } + clear() { + const gl = this._gl; + gl.clear(gl.COLOR_BUFFER_BIT); + } + resize() { + const gl = this._gl; + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + } + viewport(x, y, width, height) { + const gl = this._gl; + gl.viewport(x, y, width, height); + } + createVAO(geometry, shaderProgram) { + const nativeVAO = this._createNativeVAO(); + const vao = new VertexArrayObject(nativeVAO, geometry, { + indicies: this._createBuffer(), + position: this._createBuffer(), + uv: this._createBuffer() + }); + if (nativeVAO) { + this._bindNativeVAO(nativeVAO); + this._supplyGeometryData(vao, shaderProgram); + this._bindNativeVAO(null); + this._unbindBuffers(); + } + return vao; + } + draw(vao, shaderProgram) { + const gl = this._gl; + if (vao.obj) { + this._bindNativeVAO(vao.obj); + } else { + this._supplyGeometryData(vao, shaderProgram); + } + gl.drawElements(gl.TRIANGLES, vao.count, gl.UNSIGNED_SHORT, 0); + if (vao.obj) { + this._bindNativeVAO(null); + } else { + this._unbindBuffers(); + } + } + releaseVAO(vao) { + if (vao.obj) { + this._deleteNativeVAO(vao.obj); + } + this._deleteBuffer(vao.buffers.indicies); + this._deleteBuffer(vao.buffers.position); + this._deleteBuffer(vao.buffers.uv); + } + getUniformLocations(program, uniforms) { + const gl = this._gl; + const uniformLocations = Object.keys(uniforms).reduce((locations, key) => { + locations[key] = gl.getUniformLocation(program, key); + return locations; + }, {}); + return Object.assign(Object.assign({}, this._getCommonUniformLocations(program)), uniformLocations); + } + updateCommonUniforms(entity, camera, shaderProgram) { + const gl = this._gl; + const uniformLocations = shaderProgram.uniformLocations; + // We're using "matrix"(=local matrix) here for efficiency + // As projection doesn't require world matrix, as it doesn't have any parent or child + const matrix = entity.matrix; + const mvMatrix = create$4(); + multiply$1(mvMatrix, camera.viewMatrix, matrix); + gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix); + gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, camera.projectionMatrix); + } + updateVRUniforms(shaderProgram, mvMatrix, pMatrix, eyeIndex) { + const gl = this._gl; + const uniformLocations = shaderProgram.uniformLocations; + gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix); + gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, pMatrix); + if (uniformLocations.uEye) { + gl.uniform1f(uniformLocations.uEye, eyeIndex); + } + } + updateUniforms(shaderProgram) { + const gl = this._gl; + const uniforms = shaderProgram.uniforms; + const uniformLocations = shaderProgram.uniformLocations; + for (const key in uniforms) { + const uniform = uniforms[key]; + const location = uniformLocations[key]; + if (!uniform) continue; + if (uniform.needsUpdate) { + uniform.update(gl, location, this._isWebGL2); + } + } + } + releaseShaderResources(shaderProgram) { + const gl = this._gl; + const uniforms = shaderProgram.uniforms; + for (const key in uniforms) { + const uniform = uniforms[key]; + if (!uniform) continue; + if (uniform.needsUpdate) { + uniform.destroy(gl); + } + } + gl.deleteProgram(shaderProgram.program); + } + useProgram(shaderProgram) { + const gl = this._gl; + gl.useProgram(shaderProgram.program); + } + createProgram(vertexShader, fragmentShader) { + const gl = this._gl; + const program = gl.createProgram(); + const vs = this._compileShader(gl.VERTEX_SHADER, vertexShader); + const fs = this._compileShader(gl.FRAGMENT_SHADER, fragmentShader); + gl.attachShader(program, vs); + gl.attachShader(program, fs); + gl.bindAttribLocation(program, 0, "position"); + gl.bindAttribLocation(program, 1, "uv"); + gl.linkProgram(program); + if (this._debug && !gl.getProgramParameter(program, gl.LINK_STATUS)) { + let shaderLog = null; + if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) { + shaderLog = gl.getShaderInfoLog(vs); + } else if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) { + shaderLog = gl.getShaderInfoLog(fs); + } + throw new View360Error(ERROR.MESSAGES.FAILED_LINKING_PROGRAM(gl.getProgramInfoLog(program), shaderLog), ERROR.CODES.FAILED_LINKING_PROGRAM); + } + gl.deleteShader(vs); + gl.deleteShader(fs); + return program; + } + createWebGLTexture(texData) { + const gl = this._gl; + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texData.wrapS); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texData.wrapT); + if (!texData.isVideo() && this._isWebGL2) { + const gl2 = gl; + gl2.texStorage2D(gl2.TEXTURE_2D, 1, gl2.RGBA8, texData.width, texData.height); + } + return texture; + } + createWebGLCubeTexture(texData, size) { + const gl = this._gl; + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, texData.wrapS); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, texData.wrapT); + if (this._isWebGL2) { + const gl2 = gl; + gl2.texStorage2D(gl2.TEXTURE_CUBE_MAP, 1, gl2.RGBA8, size, size); + } + return texture; + } + makeXRCompatible() { + return __awaiter(this, void 0, void 0, function* () { + const gl = this._gl; + const attributes = gl.getContextAttributes(); + if (attributes && attributes.xrCompatible !== true) { + yield gl.makeXRCompatible(); + } + }); + } + bindXRLayer(session) { + const gl = this._gl; + const xrLayer = new XRWebGLLayer(session, gl); + session.updateRenderState({ + baseLayer: xrLayer + }); + } + bindXRFrame(frame) { + const gl = this._gl; + const session = frame.session; + const baseLayer = session.renderState.baseLayer; + gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer); + } + useDefaultFrameBuffer() { + const gl = this._gl; + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + } + _createBuffer() { + return this._gl.createBuffer(); + } + _deleteBuffer(buffer) { + return this._gl.deleteBuffer(buffer); + } + _createNativeVAO() { + const gl = this._gl; + if (this._isWebGL2) { + return gl.createVertexArray(); + } else { + const ext = this._extensions.vao; + return (ext === null || ext === void 0 ? void 0 : ext.createVertexArrayOES()) || null; + } + } + _bindNativeVAO(vao) { + const gl = this._gl; + if (this._isWebGL2) { + gl.bindVertexArray(vao); + } else { + const ext = this._extensions.vao; + ext === null || ext === void 0 ? void 0 : ext.bindVertexArrayOES(vao); + } + } + _deleteNativeVAO(vao) { + const gl = this._gl; + if (this._isWebGL2) { + gl.deleteVertexArray(vao); + } else { + const ext = this._extensions.vao; + ext === null || ext === void 0 ? void 0 : ext.deleteVertexArrayOES(vao); + } + } + _supplyGeometryData(vao, shaderProgram) { + const geometry = vao.geometry; + this._supplyIndiciesData(geometry.indicies, vao.buffers.indicies); + this._supplyAttributeData(geometry.vertices, shaderProgram.program, "position", vao.buffers.position); + this._supplyAttributeData(geometry.uvs, shaderProgram.program, "uv", vao.buffers.uv); + } + _unbindBuffers() { + const gl = this._gl; + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + gl.bindBuffer(gl.ARRAY_BUFFER, null); + } + _supplyIndiciesData(indicies, buffer) { + const gl = this._gl; + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicies.data, gl.STATIC_DRAW); + } + _supplyAttributeData(attribute, program, name, buffer) { + const gl = this._gl; + const attribLocation = gl.getAttribLocation(program, name); + // Attribute not used + if (attribLocation < 0) return; + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData(gl.ARRAY_BUFFER, attribute.data, gl.STATIC_DRAW); + gl.vertexAttribPointer(attribLocation, attribute.itemSize, gl.FLOAT, false, 0, 0); + gl.enableVertexAttribArray(attribLocation); + } + _compileShader(type, src) { + const gl = this._gl; + const shader = gl.createShader(type); + gl.shaderSource(shader, src); + gl.compileShader(shader); + return shader; + } + _getCommonUniformLocations(program) { + const gl = this._gl; + return { + uMVMatrix: gl.getUniformLocation(program, "uMVMatrix"), + uPMatrix: gl.getUniformLocation(program, "uPMatrix") + }; + } + _getContext(canvas) { + const webglIdentifiers = ["webgl2", "webgl", "experimental-webgl", "webkit-3d", "moz-webgl"]; + let context = null; + let isWebGL2 = false; + const contextAttributes = { + preserveDrawingBuffer: false, + antialias: false + }; + const onWebglContextCreationError = e => e.statusMessage; + canvas.addEventListener(EVENTS$1.CONTEXT_CREATE_ERROR, onWebglContextCreationError); + for (const identifier of webglIdentifiers) { + try { + context = canvas.getContext(identifier, contextAttributes); + isWebGL2 = identifier === "webgl2"; + } catch (t) {} // eslint-disable-line no-empty + if (context) { + break; + } + } + canvas.removeEventListener(EVENTS$1.CONTEXT_CREATE_ERROR, onWebglContextCreationError); + if (!context) { + throw new View360Error(ERROR.MESSAGES.WEBGL_NOT_SUPPORTED, ERROR.CODES.WEBGL_NOT_SUPPORTED); + } + return { + gl: context, + isWebGL2 + }; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection renderer, based on WebGL + * @ko WebGL 기반의 프로젝션 렌더러 + * @since 4.0.0 + */ + class WebGLRenderer { + /** + * Canvas element + * @ko 캔버스 엘리먼트 + * @since 4.0.0 + */ + get canvas() { + return this._canvas; + } + /** + * Canvas's width (`devicePixelRatio` is not applied) + * @ko 캔버스의 보이는 너비 (`devicePixelRatio`가 적용되지 않은) + * @since 4.0.0 + */ + get width() { + return this._elementSize.x; + } + /** + * Canvas's height (`devicePixelRatio` is not applied) + * @ko 캔버스의 높이 (`devicePixelRatio`가 적용되지 않은) + * @since 4.0.0 + */ + get height() { + return this._elementSize.y; + } + /** + * Current `devicePixelRatio` value. + * @ko 현재 `devicePixelRatio` 값. + * @since 4.0.0 + * @example + * ```js + * cosnt renderingWidth = view360.renderer.width * view360.renderer.pixelRatio; + * ``` + */ + get pixelRatio() { + return this._pixelRatio; + } + /** + * Width / height ratio (= width / height) + * @ko 너비 / 높이의 비율 (= width / height) + * @since 4.0.0 + * @example + * ```js + * const aspect = view360.renderer.width / view360.renderer.pixelRatio; + * assert(aspect === view360.renderer.aspect); + * ``` + */ + get aspect() { + return this._elementSize.x / this._elementSize.y; + } + /** + * Create new instance + * @ko 새 인스턴스를 생성합니다. + * @param canvas - Canvas element {@ko 캔버스 엘리먼트} + * @param debug - Whether to enable WebGL debugging {@ko WebGL debug 활성화 여부 } + */ + constructor(canvas, debug) { + this._canvas = canvas; + this._elementSize = { + x: 0, + y: 0 + }; + this._pixelRatio = 1; + this.ctx = new WebGLContext(canvas, debug); + } + /** + * Destroy instance and release all resources. + * @ko 인스턴스를 제거하고 사용된 리소스를 전부 해제합니다. + * @since 4.0.0 + */ + destroy() { + const canvas = this._canvas; + this.ctx.destroy(); + canvas.width = 1; + canvas.height = 1; + } + /** + * Resize canvas and renew inner size cache. + * @ko 캔버스의 크기를 재계산해서 내부의 사이즈 캐시값을 갱신합니다. + * @since 4.0.0 + */ + resize() { + const canvas = this._canvas; + const canvasSize = this._elementSize; + const devicePixelRatio = window.devicePixelRatio; + canvasSize.x = canvas.clientWidth; + canvasSize.y = canvas.clientHeight; + canvas.width = canvasSize.x * devicePixelRatio; + canvas.height = canvasSize.y * devicePixelRatio; + this._pixelRatio = devicePixelRatio; + this.ctx.resize(); + } + /** + * Render projection + * @ko 프로젝션을 렌더링합니다. + * @param projection - Projection to render {@ko 렌더링할 프로젝션} + * @param cameraa - Camera instance {@ko 카메라의 인스턴스} + * @since 4.0.0 + */ + render(projection, camera) { + const ctx = this.ctx; + const mesh = projection.getMesh(); + if (ctx.lost || !mesh) return; + ctx.clear(); + ctx.useProgram(mesh.program); + ctx.updateCommonUniforms(mesh, camera, mesh.program); + projection.update(camera); + ctx.updateUniforms(mesh.program); + ctx.draw(mesh.vao, mesh.program); + } + /** + * Render VR frame, only used for rendering frames inside VR sessions. + * @ko VR 프레임을 렌더링합니다. VR 세션 진입 도중에만 사용됩니다. + * @internal + * @param projection - Projection to render {@ko 렌더링할 프로젝션} + * @param vr - Instance of XRManager {@ko XRManager의 인스턴스} + * @param frame - VR frame {@ko VR 프레임} + * @since 4.0.0 + */ + renderVR(projection, vr, frame) { + const ctx = this.ctx; + const mesh = projection.getMesh(); + const eyeParams = vr.getEyeParams(frame); + if (!eyeParams || !mesh) return; + ctx.bindXRFrame(frame); + ctx.useProgram(mesh.program); + ctx.updateUniforms(mesh.program); + eyeParams.forEach((eye, eyeIndex) => { + const viewport = eye.viewport; + // We're using "mesh.matrix"(=local matrix) here for efficiency + // As projection doesn't require world matrix, as it doesn't have any parent or child + const mvMatrix = multiply$1(create$4(), eye.vMatrix, mesh.matrix); + ctx.viewport(viewport.x, viewport.y, viewport.width, viewport.height); + ctx.updateVRUniforms(mesh.program, mvMatrix, eye.pMatrix, eyeIndex); + ctx.draw(mesh.vao, mesh.program); + }); + } + } + + /** + * Panorama 360 image viewer + * @ko 파노라마 360 이미지 뷰어 + * @since 4.0.0 + * @see View360Options + * @see View360Events + */ + class View360 extends Component { + /** + * Root element (`.view360-container`) + * @ko 루트 엘리먼트 (`.view360-container`) + * @since 4.0.0 + * @readonly + * @example + * ```html + *
+ * + *
+ * ``` + * ```ts + * import View360 from "@egjs/view360"; + * + * const viewer = new View360("#viewer"); + * console.log(viewer.rootEl); // Element with id "viewer" + * ``` + */ + get rootEl() { + return this._rootEl; + } + /** + * Projection renderer. + * @ko 프로젝션 렌더러. + * @since 4.0.0 + * @readonly + */ + get renderer() { + return this._renderer; + } + /** + * Projection camera. + * @ko 프로젝션 카메라. + * @since 4.0.0 + * @readonly + */ + get camera() { + return this._camera; + } + /** + * Rotate/Zoom Controller. + * @ko 회전/줌 컨트롤러. + * @since 4.0.0 + * @readonly + */ + get control() { + return this._control; + } + /** + * WebXR-based VR manager. + * @ko WebXR 기반의 VR 기능 매니저 인스턴스. + * @since 4.0.0 + * @readonly + * @example + * ```ts + * // Example: Enter VR + * // This must be called on user interaction, else will be rejected. + * viewer.vr.enter(); + * ``` + */ + get vr() { + return this._vr; + } + /** + * Hotspot renderer. + * You can also change options of {@link View360Options#hotspot} with this. + * @ko 핫스팟 렌더러 인스턴스. + * {@link View360Options#hotspot} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get hotspot() { + return this._hotspot; + } + /** + * An array of plugins added. + * @ko 추가된 플러그인의 배열 + * @since 4.0.0 + * @readonly + * @example + * ```ts + * const viewer = new View360("#el_id", { + * plugins: [new ControlBar()] + * }); + * + * console.log(viewer.plugins); // [ControlBar] + * + * viewer.addPlugins(new LoadingSpinner()) // [ControlBar, LoadingSpinner]; + * ``` + */ + get plugins() { + return this._plugins; + } + /** + * A instance of {@link Projection} that currently enabled. `null` if not initialized yet. + * You should call {@link View360#load} to change panorama src or projection type. + * @ko 현재 사용중인 {@link Projection}의 인스턴스. 프로젝션을 활성화하지 않았을 경우 `null`입니다. + * 파노라마 이미지 소스나 프로젝션 타입을 변경하려면 {@link View360#load}를 호출하면 됩니다. + * @since 4.0.0 + * @readonly + * @example + * ```ts + * const viewer = new View360 + * ``` + */ + get projection() { + return this._projection; + } + set projection(val) { + if (this._initialized && val) { + this.load(val); + } else { + this._projection = val; + } + } + /** + * A boolean value whether {@link View360#init init()} is called before. + * @ko {@link View360#init init()}이 호출되었는지 여부를 가리키는 값 + * @since 4.0.0 + * @readonly + * @example + * ```ts + * const viewer = new View360("#el", { autoInit: false }); + * + * console.log(viewer.initialized); // false + * + * await viewer.init(); + * + * console.log(viewer.initialized); // true + * ``` + */ + get initialized() { + return this._initialized; + } + /** + * Instance of the Autoplay manager. + * You can also change {@link View360Options#autoplay} options with this. + * @ko Autoplay 기능의 매니저 인스턴스. + * 이 인스턴스를 통해 {@link View360Options#autoplay} 옵션을 변경하는 것도 가능합니다. + * @since 4.0.0 + * @readonly + * @example + * ```ts + * // Disable autoplay + * viewer.autoplay.disable(); + * ``` + */ + get autoplay() { + return this._autoplay; + } + /** + * When this value is `true` and {@link View360Options#projection} is set, {@link View360#init init()} will be called automatically when instance is created. + * @ko 이 값이 `true`이고, {@link View360Options#projection}이 설정되었으면, 인스턴스 생성 시점에 자동으로 {@link View360#init init()}을 호출합니다. + * @default true + * @since 4.0.0 + * @example + * ```ts + * import View360, { EquirectProjection, EVENTS } from "@egjs/view360"; + * + * // viewer.init() is called on instance creation + * // But as `init` is asynchronous, you should wait for "ready" event if you want to do something after initialization. + * const viewer = new View360("#el_id", { + * autoInit: true, + * projection: new EquirectProjection({ src: "SRC_TO_URL" }) + * }); + * + * console.log(viewer.initialized); // false, as `init` is asynchronous + * + * viewer.once(EVENTS.READY, () => { + * console.log(viewer.initialized); // true + * }); + * ``` + */ + get autoInit() { + return this._autoInit; + } + /** + * When `true`, {@link View360#resize} is called when the canvas size is changed. + * @ko `true`일 경우, 캔버스의 크기가 변경되었을 때 자동으로 {@link View360#resize}를 호출합니다. + * @default true + * @since 4.0.0 + * @see View360#useResizeObserver + * @example + * ```ts + * const viewer = new View360("#el_id", { + * autoResize: true + * }); + * + * // This can trigger `viewer.resize()` if the canvas size was not 400px + * const canvas = viewer.renderer.canvas; + * canvas.style.width = "400px"; + * ``` + */ + get autoResize() { + return this._autoResize; + } + /** + * CSS selector for canvas element to render panorama image/video. + * The canvas element should be placed inside the root element. (Dont' have to be direct child) + * @ko 파노라마 이미지/비디오를 렌더링할 canvas 엘리먼트의 CSS 선택자 + * 캔버스 엘리먼트는 루트 엘리먼트 내부에 있어야합니다. 루트 엘리먼트의 직계 자식 엘리먼트(Direct child element)일 필요는 없습니다. + * @default "canvas" + * @since 4.0.0 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * + * ```ts + * const viewer = new View360("#el_id", { + * canvasSelector: "#canvas_to_select" + * }); + * ``` + */ + get canvasSelector() { + return this._canvasSelector; + } + /** + * When `true`, it will use {@link ResizeObserver} API to detect canvas size change when {@link View360Options#autoResize} is enabled. + * @ko `true`일 때 {@link View360Options#autoResize}가 활성화되었으면, 사용 가능한 환경에서 {@link ResizeObserver} API를 사용해서 캔버스 크기 변화를 추적합니다. + * @default true + * @since 4.0.0 + */ + get useResizeObserver() { + return this._useResizeObserver; + } + /** + * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} attribute for the canvas element. + * This is necessary for the keyboard controls. + * By default, `0` will be assigned. `null` to disable. + * @ko 캔버스 엘리먼트에 적용할 {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} 어트리뷰트의 값. + * 이 값을 설정해야만 키보드 컨트롤을 사용 가능합니다. + * 기본값으로 `0`이 설정됩니다. `null`로 지정하면 `tabindex`를 설정하지 않습니다. + * @see RotateControlOptions#disableKeyboard + * @default 0 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * tabindex: 5 + * }); + * ``` + * + * ```html + * + *
+ * + *
+ * ``` + */ + get tabIndex() { + return this._tabIndex; + } + set tabIndex(val) { + const canvas = this._renderer.canvas; + this._tabIndex = val; + if (val != null) { + canvas.tabIndex = val; + } else { + canvas.removeAttribute("tabindex"); + } + } + /** + * A maximum delta time between frames in seconds. + * It can prevent camera or control changing too fast when frame being late. + * @ko 프레임간 시간 차이의 최대값. (초 단위) + * 퍼포먼스 등의 이유로 프레임 렌더링이 늦어졌을 때, 화면이 갑작스럽게 바뀌는 것을 막아줍니다. + * @default 1 / 30 + * @since 4.0.0 + */ + get maxDeltaTime() { + return this._animator.maxDeltaTime; + } + set maxDeltaTime(val) { + this._animator.maxDeltaTime = val; + } + /** + * Enable WebGL debugging. Setting this to `true` can decrease performance. + * This is used internally on developing View360. + * @ko WebGL 디버깅을 활성화합니다. 이 값을 `true`로 할 경우 성능이 하락할 수 있습니다. + * 이 옵션은 View360을 개발하기 위해 내부적으로 사용됩니다. + * @default false + */ + get debug() { + return this._debug; + } + set debug(val) { + this._debug = val; + } + // Camera options + /** + * Initial yaw (y-axis rotation) value for camera. (in degrees, °) + * As View360 uses right-handed coordinate system internally, camera will rotate counter-clockwise by this value. + * @ko 카메라의 초기 yaw(y축 회전)값 (도 단위, °) + * View360은 오른손 좌표계를 사용하기 때문에, 카메라가 해당 값만큼 시계 반대방향으로 회전합니다. + * @default 0 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * initialYaw: 30 + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.yaw); // 30 + * }); + * ``` + */ + get initialYaw() { + return this._camera.initialYaw; + } + set initialYaw(val) { + this._camera.initialYaw = val; + } + /** + * Initial pitch (x-axis rotation) value for camera. (in degrees, °) + * As View360 uses right-handed coordinate system internally, positive value will make camera to look upside, while negative value will look down. + * @ko 카메라의 초기 pitch(x축 회전)값 (도 단위, °) + * View360은 오른손 좌표계를 사용하기 때문에, 양(+)의 값은 카메라가 위를 보게 하고, 음(-)의 값은 카메라가 아래를 보게 합니다. + * @default 0 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * initialPitch: 60 + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.pitch); // 60 + * }); + * ``` + */ + get initialPitch() { + return this._camera.initialPitch; + } + set initialPitch(val) { + this._camera.initialPitch = val; + } + /** + * Initial zoom value for camera. + * Setting this value to `2` will enlarge panorama 200% by width. + * @ko 카메라의 초기 줌 값. + * 이 값을 `2`로 설정할 경우 파노라마 이미지를 가로 기준 200%만큼 확대합니다. + * @default 1 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * initialZoom: 2 + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.zoom); // 2 + * }); + * ``` + */ + get initialZoom() { + return this._camera.initialZoom; + } + set initialZoom(val) { + this._camera.initialZoom = val; + } + /** + * Restrict yaw(y-axis rotation) range. (in degrees, °) + * @ko yaw(y축 회전) 범위를 제한합니다. (도 단위, °) + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * yawRange: [-30, 30] + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.yaw); // 0 + * viewer.camera.lookAt({ yaw: 60 }); + * console.log(viewer.camera.yaw); // 30 + * }); + * ``` + */ + get yawRange() { + return this._camera.yawRange; + } + set yawRange(val) { + this._camera.yawRange = val; + if (this._projection) this._projection.updateCamera(this._camera); + } + /** + * Restrict pitch(x-axis rotation) range. (in degrees, °) + * @ko pitch(x축 회전) 범위를 제한합니다. (도 단위, °) + * @default null + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * pitchRange: [-45, 45] + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.pitch); // 0 + * viewer.camera.lookAt({ pitch: 60 }); + * console.log(viewer.camera.pitch); // 45 + * }); + * ``` + */ + get pitchRange() { + return this._camera.pitchRange; + } + set pitchRange(val) { + this._camera.pitchRange = val; + if (this._projection) this._projection.updateCamera(this._camera); + } + /** + * Restrict camera zoom range. + * If `null`, a default zoom range from `0.6` to `10` will be used. + * @ko 카메라 줌 범위를 제한합니다. + * `null`일 경우 기본값으로 `0.6`에서 `10`의 범위를 사용합니다. + * @default null + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * zoomRange: [0.5, 4] + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.zoom); // 1 + * viewer.camera.lookAt({ zoom: 6 }); + * console.log(viewer.camera.zoom); // 4 + * }); + * ``` + */ + get zoomRange() { + return this._camera.zoomRange; + } + set zoomRange(val) { + this._camera.zoomRange = val; + if (this._projection) this._projection.updateCamera(this._camera); + } + /** + * Camera's horizontal FOV(Field of View). (in degrees, °) + * @ko 카메라의 수평 FOV(Field of View) 값. (도 단위, °) + * @default 90 + * @since 4.0.0 + * @example + * ```ts + * // Init with fov: 120 + * const viewer = new View360("#el_id", { fov: 120 }); + * + * // Back to 90 + * viewer.fov = 90; + * ``` + */ + get fov() { + return this._camera.fov; + } + set fov(val) { + const camera = this._camera; + const control = this._control; + camera.fov = val; + camera.updateMatrix(); + control.sync(); + } + // Control options + /** + * A control for camera rotation. + * You can also change options of {@link View360Options#rotate} with this. + * @ko 카메라 회전을 담당하는 컨트롤. + * {@link View360Options#rotate} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get rotate() { + return this._control.rotate; + } + /** + * A control for camera zoom. + * You can also change options of {@link View360Options#zoom} with this. + * @ko 카메라 줌을 담당하는 컨트롤. + * {@link View360Options#zoom} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get zoom() { + return this._control.zoom; + } + /** + * A control for camera rotation with gyroscope input. + * You can also change options of {@link View360Options#gyro} with this. + * @ko 자이로스코프를 통한 카메라 회전을 담당하는 컨트롤. + * {@link View360Options#gyro} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get gyro() { + return this._control.gyro; + } + /** + * Apply CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor} by current state of input when using mouse. + * If `true`, this will add CSS style to canvas element. It'll apply `cursor: "grab"` by default and `cursor: "grabbing"` when holding the mouse button. + * @ko 마우스 사용시 CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor}값을 자동으로 변경할지 여부. + * `true`일 경우 기본 상태에서 `cursor: "grab"`을, 입력 도중에 `cursor: "grabbing"`을 캔버스에 적용합니다. + * @default true + * @since 4.0.0 + */ + get useGrabCursor() { + return this._control.useGrabCursor; + } + set useGrabCursor(val) { + this._control.useGrabCursor = val; + } + /** + * Disable context menu which pops up on mouse right click. + * @ko 마우스 우클릭시 표시되는 컨텍스트 메뉴를 비활성화합니다. + * @default false + * @since 4.0.0 + */ + get disableContextMenu() { + return this._control.disableContextMenu; + } + set disableContextMenu(val) { + this._control.disableContextMenu = val; + } + /** + * If `true`, enables scroll on mobile(touch) devices on canvas. + * :::caution + * When this option is enabled, users must swipe horizontally first then vertically to change view up or down. + * ::: + * @ko `true`로 설정할 경우, 모바일(터치) 환경의 캔버스 영역 내에서 스크롤을 가능하게 합니다. + * :::caution + * 이 값을 활성화할 경우, 사용자가 카메라 뷰를 위/아래로 바꾸기 위해서는 먼저 가로로 스와이프한 이후에 세로로 스와이프해야만 합니다. + * ::: + * @since 4.0.0 + * @default true + */ + get scrollable() { + return this._control.scrollable; + } + set scrollable(val) { + this._control.scrollable = val; + } + /** + * If `true`, enables scroll by mouse wheel on canvas. + * :::caution + * When this option is enabled, zoom by mouse wheel will be disabled. + * ::: + * @ko `true`로 설정할 경우, 캔버스 영역 내에서 마우스 휠을 이용한 페이지 스크롤이 가능해집니다. + * :::caution + * 이 값을 활성화할 경우, 마우스 휠을 통한 줌이 불가능하게 됩니다. + * ::: + * @since 4.0.0 + * @default false + */ + get wheelScrollable() { + return this._control.wheelScrollable; + } + set wheelScrollable(val) { + this._control.wheelScrollable = val; + } + /** + * Create new instance of View360 + * @ko View360의 새로운 인스턴스를 생성합니다 + * @param root - Root element(`.view360-container`) to mount View360 + * Can be either a CSS selector or HTMLElement. + * {@ko View360을 마운트할 루트 엘리먼트, CSS 셀렉터나 HTMLElement를 지정 가능합니다.} + * @param options - Options to apply + * {@ko 적용할 옵션들} + * @example + * ```ts + * import View360, { EquirectProjection } from "@egjs/view360"; + * + * // Create new View360 instance + * const viewer = new View360("#id-of-a-container", { + * projection: new EquirectProjection({ + * src: "URL_TO_PANORAMA_IMAGE_OR_VIDEO", + * }) + * }); + * ``` + */ + constructor(root, { + projection = null, + initialYaw = 0, + initialPitch = 0, + initialZoom = 1, + yawRange = null, + pitchRange = null, + zoomRange = null, + fov = 90, + useGrabCursor = true, + disableContextMenu = false, + rotate = true, + zoom = true, + gyro = false, + scrollable = true, + wheelScrollable = false, + autoplay = false, + hotspot = {}, + autoInit = true, + autoResize = true, + canvasSelector = "canvas", + useResizeObserver = true, + on = {}, + plugins = [], + maxDeltaTime = 1 / 30, + tabIndex = 0, + debug = false + } = {}) { + super(); + /** + * Render a single panorama image/video frame. + * Rendering is performed automatically on demand, so you usually don't have to call this. + * Call this when a frame is not renewed after changing options. + * @ko 파노라마 이미지/비디오의 한 프레임을 렌더링합니다. + * 프레임 갱신은 보통 필요한 때에만 자동적으로 이루어지기 때문에, 보통은 이 메소드를 호출할 필요는 없습니다. + * 옵션 변경 이후에도 프레임 갱신이 이루어지지 않는다면, 이 메소드를 호출해주세요. + * @param delta Delta time in milisec. {@ko 프레임간 시간 차이, 밀리초 단위} + * @since 4.0.0 + */ + this.renderFrame = delta => { + const camera = this._camera; + const renderer = this._renderer; + const control = this._control; + const hotspot = this._hotspot; + const autoPlayer = this._autoplay; + const projection = this._projection; + if (!projection) return; + this._emit(EVENTS.BEFORE_RENDER); + if (autoPlayer.playing) { + autoPlayer.update(delta); + control.sync(); + } + if (camera.animation) { + camera.animation.update(delta); + } else { + control.update(delta); + } + renderer.render(projection, camera); + hotspot.render(camera); + if (camera.changed) { + this._emit(EVENTS.VIEW_CHANGE, { + yaw: camera.yaw, + pitch: camera.pitch, + zoom: camera.zoom, + quaternion: [camera.quaternion[0], camera.quaternion[1], camera.quaternion[2], camera.quaternion[3]] + }); + } + camera.onFrameRender(); + this._emit(EVENTS.RENDER); + }; + this._renderFrameOnDemand = delta => { + var _a; + const camera = this._camera; + const control = this._control; + const autoplay = this._autoplay; + const texture = (_a = this._projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (!this._initialized || !texture) return; + if (!camera.animation && !control.animating && !autoplay.playing && !texture.isVideo()) return; + this.renderFrame(delta); + }; + this._renderVRFrame = (_delta, frame) => { + const vr = this._vr; + const projection = this._projection; + const renderer = this._renderer; + if (!projection) return; + this._emit(EVENTS.BEFORE_RENDER); + renderer.renderVR(projection, vr, frame); + this._emit(EVENTS.RENDER); + }; + this._rootEl = getElement(root); + this._plugins = plugins; + this._initialized = false; + // Options + this._autoInit = autoInit; + this._autoResize = autoResize; + this._canvasSelector = canvasSelector; + this._useResizeObserver = useResizeObserver; + this._tabIndex = tabIndex; + this._debug = debug; + // Core components + const canvas = findCanvas(this._rootEl, canvasSelector); + this._renderer = new WebGLRenderer(canvas, debug); + this._camera = new Camera({ + initialYaw, + initialPitch, + initialZoom, + fov, + yawRange, + pitchRange, + zoomRange + }); + this._control = new PanoControl(canvas, this._camera, { + useGrabCursor, + scrollable, + wheelScrollable, + disableContextMenu, + rotate, + zoom, + gyro + }); + this._animator = new FrameAnimator(maxDeltaTime); + this._autoplay = new Autoplay(this, canvas, autoplay); + this._projection = projection; + this._autoResizer = new AutoResizer(useResizeObserver, () => this.resize()); + this._vr = new XRManager(this._renderer.ctx); + this._hotspot = new HotspotRenderer(this._rootEl, this._renderer, hotspot); + this._addEventHandlers(on); + if (projection && autoInit) { + this.init(); + } + } + /** + * Destroy instance and release all resources. + * @ko 인스턴스를 제거하고 모든 리소스를 해제합니다. + * @since 4.0.0 + */ + destroy() { + this._camera.destroy(); + this._animator.stop(); + this._renderer.destroy(); + this._control.destroy(); + this._autoResizer.disable(); + if (this._projection) { + this._projection.releaseAllResources(this._renderer.ctx); + this._projection = null; + } + this._plugins.forEach(plugin => plugin.destroy(this)); + this._initialized = false; + } + /** + * Initialize inner components and load projection src. + * @ko 내부 컴포넌트들을 초기화하고 프로젝션 소스를 로드합니다. + * @since 4.0.0 + */ + init() { + return __awaiter(this, void 0, void 0, function* () { + if (!this._projection) { + throw new View360Error(ERROR.MESSAGES.PROVIDE_PROJECTION_FIRST, ERROR.CODES.PROVIDE_PROJECTION_FIRST); + } + const renderer = this._renderer; + const camera = this._camera; + const control = this._control; + const animator = this._animator; + const hotspot = this._hotspot; + const projection = this._projection; + const canvas = renderer.canvas; + this._bindComponentEvents(); + renderer.ctx.init(); + this._resizeComponents(); + camera.updateMatrix(); + if (this._autoResize) { + this._autoResizer.enable(canvas); + } + if (!this._autoplay.enableBlocked) { + this._autoplay.enable(); + } + this._plugins.forEach(plugin => { + plugin.init(this); + }); + const texture = yield this._loadTexture(projection); + this._applyProjection(projection, texture, null); + hotspot.refresh(); + animator.start(this._renderFrameOnDemand); + yield control.enable(); + if (this._tabIndex != null && !canvas.hasAttribute("tabIndex")) { + canvas.tabIndex = this._tabIndex; + } + this._initialized = true; + this.renderFrame(0); + this._emit(EVENTS.READY); + }); + } + /** + * Load new panorama image/video and display it. + * This will {@link View360#init init()} View360 if it's not initialized yet. + * @ko 새로운 파노라마 이미지 혹은 비디오를 로드하고 표시합니다. + * 만약 View360이 아직 초기화되지 않았다면, {@link View360#init init()}을 호출합니다. + * @param projection - Projection & video options for new source. {@ko 새로운 파노라마 이미지/비디오에 적용할 옵션들} + * @returns `Promise` if load was successful. {@ko 프로젝션 로드에 성공했을 경우 `Promise`를 반환합니다. } + * @since 4.0.0 + * @example + * ```ts + * // Change to video + * viewer.load({ + * src: "URL_TO_NEW_VIDEO", + * video: true + * }); + * ``` + */ + load(projection) { + return __awaiter(this, void 0, void 0, function* () { + if (!projection) return false; + if (this._initialized) { + const texture = yield this._loadTexture(projection); + this._applyProjection(projection, texture, this._projection); + this.renderFrame(0); + } else { + // Should update internal options before init + this._projection = projection; + this.init(); + } + return true; + }); + } + /** + * Refresh component's size by current + * @ko View360이 내부적으로 캐시하고 있는 엘리먼트 크기를 현재 크기로 갱신합니다. + * @since 4.0.0 + */ + resize() { + if (!this._initialized) return; + this._resizeComponents(); + // To prevent flickering, render immediately after resizing components + this.renderFrame(0); + const { + width, + height + } = this._renderer; + this._emit(EVENTS.RESIZE, { + width, + height + }); + } + /** + * Add new plugins + * @ko 새로운 플러그인을 추가합니다. + * @param plugins Plugins to add {@ko 추가할 플러그인들} + * @see View360Options#plugins + * @since 4.0.0 + * @example + * ```ts + * // Add a single plugin + * viewer.addPlugins(new ControlBar()); + * + * // Add multiple plugins + * viewer.addPlugins(new ControlBar(), new LoadingSpinner()); + * ``` + */ + addPlugins(...plugins) { + if (this._initialized) { + plugins.forEach(plugin => { + plugin.init(this); + }); + } + this._plugins.push(...plugins); + } + /** + * Remove plugins. + * @ko 플러그인을 제거합니다. + * @param plugins Plugins to remove {@ko 제거할 플러그인들} + * @since 4.0.0 + * @example + * ```ts + * // Remove a single plugin + * viewer.removePlugins(plugin1); + * + * // Remove multiple plugins + * viewer.removePlugins(plugin2, plugin3); + * ``` + */ + removePlugins(...plugins) { + plugins.forEach(plugin => { + const pluginIdx = this._plugins.indexOf(plugin); + if (pluginIdx < 0) return; + plugin.destroy(this); + this._plugins.splice(pluginIdx, 1); + }); + } + _emit(eventName, ...params) { + const evtParams = params ? params[0] : {}; + this.trigger(eventName, Object.assign({ + type: eventName, + target: this + }, evtParams)); + } + _applyProjection(projection, texture, prevProjection) { + const camera = this._camera; + const control = this._control; + const renderer = this._renderer; + // Remove previous projection + if (prevProjection) { + prevProjection.releaseAllResources(this._renderer.ctx); + } + projection.applyTexture(renderer.ctx, texture); + projection.updateCamera(camera); + projection.updateControl(control); + this._projection = projection; + this._emit(EVENTS.PROJECTION_CHANGE, { + projection + }); + } + _loadTexture(projection) { + return __awaiter(this, void 0, void 0, function* () { + const contentLoader = new TextureLoader(); + const { + src, + video + } = projection; + this._emit(EVENTS.LOAD_START, { + src, + video + }); + const texture = yield contentLoader.load(src, video); + this._emit(EVENTS.LOAD, { + src, + video + }); + return texture; + }); + } + _resizeComponents() { + const renderer = this._renderer; + const camera = this._camera; + const control = this._control; + renderer.resize(); + camera.resize(renderer.width, renderer.height); + control.resize(renderer.width, renderer.height); + } + _addEventHandlers(events) { + // Bind option "on" + Object.keys(events).forEach(evtName => { + this.on(evtName, events[evtName]); + }); + } + _bindComponentEvents() { + // Bind internal component events + const root = this._rootEl; + const control = this._control; + const animator = this._animator; + const renderer = this._renderer; + const vr = this._vr; + const controlEventsToPropagate = [CONTROL_EVENTS.STATIC_CLICK, CONTROL_EVENTS.INPUT_START, CONTROL_EVENTS.INPUT_END]; + controlEventsToPropagate.forEach(evtName => { + control.rotate.on(evtName, evt => { + this._emit(evtName, evt); + }); + control.zoom.on(evtName, evt => { + this._emit(evtName, evt); + }); + }); + vr.on(EVENTS.VR_START, evt => { + root.classList.add(DEFAULT_CLASS.IN_VR); + animator.changeContext(evt.session); + animator.start(this._renderVRFrame); + this._emit(EVENTS.VR_START); + }); + vr.on(EVENTS.VR_END, () => { + root.classList.remove(DEFAULT_CLASS.IN_VR); + renderer.ctx.useDefaultFrameBuffer(); + animator.changeContext(window); + animator.start(this._renderFrameOnDemand); + this.resize(); + this._emit(EVENTS.VR_END); + }); + } + } + /** + * Current version string of the View360 + * @ko View360의 현재 버젼 문자열 + * @since 4.0.0 + * @readonly + * @example + * ```ts + * // If the installed version of the View360 is v4.0.0, View360.VERSION is equal to "4.0.0" + * console.log(View360.VERSION) // 4.0.0 + * ``` + */ + View360.VERSION = "4.0.0-beta.4"; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Base class for 3D objects + * @ko 3D 오브젝트의 베이스 클래스 + * @since 4.0.0 + * @internal + */ + class Object3D { + /** + * Create new instance. + * @ko 새로운 인스턴스를 생성합니다. + */ + constructor() { + this.matrix = create$4(); + this.rotation = create$1(); + this.position = fromValues$3(0, 0, 0); + this.scale = fromValues$3(1, 1, 1); + } + /** + * Update local matrix of the object. + * @ko 오브젝트의 local matrix를 갱신합니다. + * @since 4.0.0 + */ + updateMatrix() { + fromRotationTranslationScale(this.matrix, this.rotation, this.position, this.scale); + } + } + + /** + * A plugin that displays loading spinner while loading the projection. + * @ko 프로젝션 로딩중에 로딩 스피너를 보여주는 플러그인 + * @since 4.0.0 + * @category Plugin + */ + class LoadingSpinner { + /** + * Create a new instance of LoadingSpinner. {@ko LoadingSpinner의 새 인스턴스를 생성합니다.} + * @param options Options {@ko 옵션들} + */ + constructor({ + className = {} + } = {}) { + this._startLoading = ({ + target: viewer + }) => { + viewer.rootEl.appendChild(this._container); + if (viewer.initialized) { + viewer.once(EVENTS.LOAD, this._detachElements); + } else { + viewer.once(EVENTS.READY, this._detachElements); + } + }; + this._detachElements = ({ + target: viewer + }) => { + const container = this._container; + if (!container) return; + if (container.parentElement === viewer.rootEl) { + viewer.rootEl.removeChild(container); + } + }; + this.className = className; + this._container = this._createElements(); + } + init(viewer) { + viewer.on(EVENTS.LOAD_START, this._startLoading); + } + destroy(viewer) { + viewer.off(EVENTS.LOAD_START, this._startLoading); + this._detachElements({ + target: viewer + }); + } + _createElements() { + const className = Object.assign(Object.assign({}, this.className), LoadingSpinner.DEFAULT_CLASS); + const container = createElement(className.CONTAINER); + const ring = createElement(className.RING); + container.appendChild(ring); + return container; + } + } + /** + * Default class names that LoadingSpinner uses + * @ko LoadingSpinner가 사용하는 디폴트 클래스 이름 + * @since 4.0.0 + */ + LoadingSpinner.DEFAULT_CLASS = { + /** + * A class name for the container element + * @ko 컨테이너 엘리먼트의 클래스 이름 + * @since 4.0.0 + */ + CONTAINER: "view360-spinner", + /** + * A class name for the spinning ring element + * @ko 돌아가는 링 엘리먼트의 클래스 이름 + * @since 4.0.0 + */ + RING: "view360-spinner-ring" + }; + + /** + * Interface of the ControlBar items + * @ko 컨트롤바 아이템의 인터페이스 + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class ControlBarItem { + /** + * Create new instance of the ControlBarItem + * @ko ControlBarItem의 새로운 인스턴스를 생성합니다. + * @param options Options {@ko 옵션들} + */ + constructor(options) { + this.position = options.position; + this.order = options.order; + } + } + + const CONTROL_BAR_DEFAULT_CLASS = { + CONTROLS_ROOT: "view360-controls", + CONTROLS_BG: "view360-controls-background", + CONTROLS_MAIN: "view360-controls-main", + CONTROLS_TOP: "view360-controls-top", + CONTROLS_BOTTOM: "view360-controls-bottom", + CONTROLS_MID: "view360-controls-mid", + CONTROLS_LEFT: "view360-controls-left", + CONTROLS_RIGHT: "view360-controls-right", + CONTROLS_FLOAT_LEFT: "view360-controls-float-left", + CONTROLS_FLOAT_RIGHT: "view360-controls-float-right", + CONTROLS_BUTTON: "view360-controls-button", + PROGRESS_ROOT: "view360-controls-progress", + VOLUME_ROOT: "view360-controls-volume", + RANGE_ROOT: "view360-range", + RANGE_TRACK: "view360-range-track", + RANGE_THUMB: "view360-range-thumb", + RANGE_FILLER: "view360-range-filler", + PLAY_BUTTON: "view360-controls-play", + PAUSE_BUTTON: "view360-controls-pause", + UNMUTED_BUTTON: "view360-controls-unmuted", + MUTED_BUTTON: "view360-controls-muted", + FULLSCREEN_BUTTON: "view360-controls-fullscreen", + FULLSCREEN_EXIT_BUTTON: "view360-controls-fullscreen-exit", + VR_BUTTON: "view360-controls-vr", + GYRO_ENABLED: "view360-controls-gyro-enabled", + GYRO_DISABLED: "view360-controls-gyro-disabled", + VIDEO_TIME_DISPLAY: "view360-controls-time", + PIEVIEW_ROOT: "view360-controls-pie", + FIXED: "view360-controls-fixed", + UNAVAILABLE: "view360-controls-unavailable", + HIDDEN: "view360-controls-hidden" + }; + const CONTROL_BAR_ITEM_POSITION = { + /** + * Place control bar item floating at top-left corner + * @ko 아이템을 왼쪽 위 구석에 표시합니다. + * @since 4.0.0 + */ + TOP_LEFT: "top-left", + /** + * Place control bar item floating at top-right corner + * @ko 아이템을 오른쪽 위 구석에 표시합니다. + * @since 4.0.0 + */ + TOP_RIGHT: "top-right", + /** + * Place control bar item at upper block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 위쪽 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_TOP: "main-top", + /** + * Place control bar item at lower block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 하단 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_BOTTOM: "main-bottom", + /** + * Place control bar item at center-left block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 왼쪽 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_LEFT: "main-left", + /** + * Place control bar item at center-right block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 오른쪽 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_RIGHT: "main-right" + }; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class RangeControl extends Component { + /** + * + */ + constructor() { + super(); + this._onHold = ({ + srcEvent, + isTouch + }) => { + var _a; + const bbox = this._bbox; + if (!bbox) return; + const x = isTouch ? srcEvent.touches[0].pageX : srcEvent.pageX; + const elX = bbox.x + ((_a = window.scrollX) !== null && _a !== void 0 ? _a : window.pageXOffset); + const clamepdX = clamp(x, elX, elX + bbox.width); + const progress = (clamepdX - elX) / bbox.width; + this._motion.reset(clamepdX); + this.thumbEl.classList.add(this._fixedClass); + this.trigger(CONTROL_EVENTS.INPUT_START, progress); + }; + this._onChange = ({ + delta + }) => { + var _a; + const motion = this._motion; + const bbox = this._bbox; + if (!bbox) return; + motion.setNewEndByDelta(delta.x); + motion.update(1); + const elX = bbox.x + ((_a = window.scrollX) !== null && _a !== void 0 ? _a : window.pageXOffset); + const clampedX = clamp(motion.val, elX, elX + bbox.width); + const progress = (clampedX - elX) / bbox.width; + this.trigger(CONTROL_EVENTS.CHANGE, progress); + }; + this._onRelease = () => { + const bbox = this._bbox; + if (!bbox) return; + this.thumbEl.classList.remove(this._fixedClass); + this.trigger(CONTROL_EVENTS.INPUT_END); + }; + const root = document.createElement(EL_DIV); + const track = document.createElement(EL_DIV); + const thumb = document.createElement(EL_DIV); + const filler = document.createElement(EL_DIV); + root.draggable = false; + track.appendChild(filler); + track.appendChild(thumb); + root.appendChild(track); + this.rootEl = root; + this.trackEl = track; + this.thumbEl = thumb; + this.fillerEl = filler; + this._mouseInput = new MouseInput(); + this._touchInput = new TouchInput(); + this._motion = new Motion({ + duration: 1, + range: INFINITE_RANGE, + easing: x => x + }); + this._bbox = { + x: 0, + y: 0, + width: 0, + height: 0, + left: 0, + right: 0, + bottom: 0, + top: 0 + }; + this._fixedClass = CONTROL_BAR_DEFAULT_CLASS.FIXED; + } + init(className) { + const mouseInput = this._mouseInput; + const touchInput = this._touchInput; + this.rootEl.classList.add(className.RANGE_ROOT); + this.trackEl.classList.add(className.RANGE_TRACK); + this.thumbEl.classList.add(className.RANGE_THUMB); + this.fillerEl.classList.add(className.RANGE_FILLER); + this._fixedClass = className.FIXED; + mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onHold); + touchInput.on(CONTROL_EVENTS.INPUT_START, this._onHold); + mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + touchInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + mouseInput.enable(this.rootEl); + touchInput.enable(this.rootEl); + this.resize(); + } + destroy() { + const mouseInput = this._mouseInput; + const touchInput = this._touchInput; + this.rootEl.className = ""; + this.trackEl.className = ""; + this.thumbEl.className = ""; + this.fillerEl.className = ""; + mouseInput.off(); + touchInput.off(); + mouseInput.disable(); + touchInput.disable(); + } + resize() { + this._bbox = this.trackEl.getBoundingClientRect(); + } + updateStyle(progress) { + const width = this._bbox.width; + const clampedProgress = clamp(progress, 0, 1); + this.fillerEl.style.width = `${clampedProgress * 100}%`; + this.thumbEl.style.transform = `translateX(${clampedProgress * width}px)`; + } + } + + /** + * Show video progress bar. + * @ko 비디오의 프로그레스 바를 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class ProgressBar extends ControlBarItem { + get element() { + return this._rangeControl.rootEl; + } + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_TOP, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onResize = () => { + this._rangeControl.resize(); + }; + this._onTimeUpdate = () => { + const video = this._video; + if (!video) return; + this._currentTime = video.source.currentTime; + this._rangeControl.updateStyle(this._currentTime / this._duration); + }; + this._onDurationChange = () => { + const video = this._video; + if (!video) return; + this._duration = video.source.duration; + this._rangeControl.updateStyle(this._currentTime / this._duration); + }; + this._onHold = progress => { + const video = this._video; + const controlBar = this._controlBar; + if (!video || !controlBar) return; + const paused = video.isPaused(); + video.source.pause(); + const time = video.source.duration * progress; + video.source.currentTime = time; + video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { + detail: { + time + } + })); + controlBar.rootEl.classList.add(controlBar.className.FIXED); + this._wasPaused = !this._playPromise && paused; + }; + this._onControl = progress => { + const video = this._video; + if (!video) return; + const time = video.source.duration * progress; + video.source.currentTime = time; + video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { + detail: { + time + } + })); + }; + this._onRelease = () => { + const video = this._video; + const controlBar = this._controlBar; + if (video && controlBar) { + if (!this._wasPaused && !this._playPromise) { + this._playPromise = video.source.play().catch(() => void 0); + // This should not be chained + this._playPromise.then(() => { + this._playPromise = null; + }); + controlBar.rootEl.classList.remove(controlBar.className.FIXED); + } + } + this._wasPaused = false; + }; + this.position = position; + this.order = order; + this._controlBar = null; + this._rangeControl = new RangeControl(); + this._video = null; + this._wasPaused = false; + this._currentTime = 0; + this._duration = 0; + this._playPromise = null; + } + init(viewer, controlBar) { + var _a; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const element = this.element; + const rangeControl = this._rangeControl; + const unavailableClass = controlBar.className.UNAVAILABLE; + if (!video || !video.isVideo()) { + element.classList.add(unavailableClass); + return; + } + element.classList.remove(unavailableClass); + element.classList.add(controlBar.className.PROGRESS_ROOT); + viewer.on(EVENTS.RESIZE, this._onResize); + video.source.addEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.addEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate); + rangeControl.init(controlBar.className); + rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold); + rangeControl.on(CONTROL_EVENTS.CHANGE, this._onControl); + rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + this._video = video; + this._currentTime = video.source.currentTime; + this._duration = video.source.duration; + this._controlBar = controlBar; + rangeControl.updateStyle(this._currentTime / this._duration); + } + destroy(viewer) { + const video = this._video; + viewer.off(EVENTS.RESIZE, this._onResize); + if (video) { + video.source.removeEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.removeEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate); + } + this._rangeControl.destroy(); + this._video = null; + this._playPromise = null; + } + } + + /** + * Show video play / pause button. + * @ko 비디오 재생 / 일시정지 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class PlayButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const video = this._video; + if (!video) return; + if (this._paused) { + video.source.play(); + } else { + video.source.pause(); + } + }; + this._onPlay = () => { + if (!this._controlBar) return; + const element = this.element; + const className = this._controlBar.className; + element.classList.add(className.PAUSE_BUTTON); + element.classList.remove(className.PLAY_BUTTON); + element.title = "Pause Video"; + this._paused = false; + }; + this._onPause = () => { + if (!this._controlBar) return; + const element = this.element; + const className = this._controlBar.className; + element.classList.add(className.PLAY_BUTTON); + element.classList.remove(className.PAUSE_BUTTON); + element.title = "Play Video"; + this._paused = true; + }; + this.element = document.createElement(EL_BUTTON); + this._video = null; + this._paused = true; + this._controlBar = null; + } + init(viewer, controlBar) { + var _a; + const element = this.element; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const className = controlBar.className; + const unavailableClass = className.UNAVAILABLE; + if (!video || !video.isVideo()) { + element.classList.add(unavailableClass); + return; + } + element.classList.add(className.CONTROLS_BUTTON); + element.classList.remove(unavailableClass); + const paused = video.isPaused(); + this._video = video; + this._paused = paused; + this._controlBar = controlBar; + if (paused) { + this._onPause(); + } else { + this._onPlay(); + } + element.addEventListener(EVENTS$1.CLICK, this._onClick); + video.source.addEventListener(EVENTS$1.VIDEO_PLAY, this._onPlay); + video.source.addEventListener(EVENTS$1.VIDEO_PAUSE, this._onPause); + } + destroy() { + const video = this._video; + const element = this.element; + if (!video) return; + element.className = ""; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + video.source.removeEventListener(EVENTS$1.VIDEO_PLAY, this._onPlay); + video.source.removeEventListener(EVENTS$1.VIDEO_PAUSE, this._onPause); + this._video = null; + this._paused = true; + this._controlBar = null; + } + } + + /** + * Show video volume control. + * @ko 비디오 볼륨 조절 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class VolumeControl extends ControlBarItem { + get element() { + return this._rootEl; + } + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onResize = () => { + this._rangeControl.resize(); + this._updateDisplay(); + }; + this._onClick = () => { + const video = this._video; + if (!video || this._rootEl.disabled) return; + video.source.muted = !video.source.muted; + }; + this._onVolumeChange = () => { + const button = this._buttonEl; + const video = this._video; + const controlBar = this._controlBar; + if (!video || !controlBar) return; + const className = controlBar.className; + if (video.source.muted || video.source.volume === 0) { + button.classList.add(className.MUTED_BUTTON); + button.classList.remove(className.UNMUTED_BUTTON); + } else { + button.classList.add(className.UNMUTED_BUTTON); + button.classList.remove(className.MUTED_BUTTON); + } + this._updateDisplay(); + }; + this._onHold = progress => { + const video = this._video; + const controlBar = this._controlBar; + if (!video || !controlBar) return; + const className = controlBar.className; + video.source.volume = progress; + this._rootEl.classList.add(className.FIXED); + controlBar.containerEl.classList.add(className.FIXED); + this._updateDisplay(); + }; + this._onChange = progress => { + const video = this._video; + if (!video) return; + video.source.volume = progress; + if (progress > 0) { + video.source.muted = false; + } else { + video.source.muted = true; + } + this._updateDisplay(); + }; + this._onRelease = () => { + const controlBar = this._controlBar; + if (!controlBar) return; + const className = controlBar.className; + this._rootEl.classList.remove(className.FIXED); + controlBar.containerEl.classList.remove(className.FIXED); + }; + this._updateDisplay = () => { + const video = this._video; + const root = this._rootEl; + if (!video) return; + if (!video.hasAudio()) { + root.disabled = true; + return; + } + root.disabled = false; + const volume = video.source.muted ? 0 : video.source.volume; + this._rangeControl.updateStyle(volume); + }; + this._controlBar = null; + this._rangeControl = new RangeControl(); + this._createElements(); + this._video = null; + } + init(viewer, controlBar) { + var _a; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const root = this._rootEl; + const button = this._buttonEl; + const rangeControl = this._rangeControl; + const className = controlBar.className; + const unavailableClass = className.UNAVAILABLE; + if (!video || !video.isVideo()) { + root.classList.add(unavailableClass); + return; + } + root.classList.remove(unavailableClass); + root.classList.add(className.CONTROLS_BUTTON); + root.classList.add(className.VOLUME_ROOT); + button.classList.add(className.CONTROLS_BUTTON); + if (video.source.muted) { + button.classList.add(className.MUTED_BUTTON); + } else { + button.classList.add(className.UNMUTED_BUTTON); + } + viewer.on(EVENTS.RESIZE, this._onResize); + root.addEventListener(EVENTS$1.TRANSITION_END, this._onResize); + button.addEventListener(EVENTS$1.CLICK, this._onClick); + video.source.addEventListener(EVENTS$1.VIDEO_VOLUME_CHANGE, this._onVolumeChange); + video.source.addEventListener(EVENTS$1.VIDEO_LOADED_DATA, this._updateDisplay); + video.source.addEventListener(EVENTS$1.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay); + rangeControl.init(className); + rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold); + rangeControl.on(CONTROL_EVENTS.CHANGE, this._onChange); + rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + this._controlBar = controlBar; + this._video = video; + this._updateDisplay(); + } + destroy(viewer) { + const video = this._video; + const button = this._buttonEl; + const root = this._rootEl; + root.className = ""; + button.className = ""; + viewer.off(EVENTS.RESIZE, this._onResize); + root.removeEventListener(EVENTS$1.TRANSITION_END, this._onResize); + button.removeEventListener(EVENTS$1.CLICK, this._onClick); + if (video) { + video.source.removeEventListener(EVENTS$1.VIDEO_VOLUME_CHANGE, this._onVolumeChange); + video.source.removeEventListener(EVENTS$1.VIDEO_LOADED_DATA, this._updateDisplay); + video.source.removeEventListener(EVENTS$1.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay); + } + this._controlBar = null; + this._rangeControl.destroy(); + this._video = null; + } + _createElements() { + const root = document.createElement(EL_BUTTON); + const buttonEl = document.createElement(EL_DIV); + root.appendChild(this._rangeControl.rootEl); + root.appendChild(buttonEl); + root.title = "Toggle Mute"; + this._rootEl = root; + this._buttonEl = buttonEl; + } + } + + /** + * Show fullscreen enter / exit button. + * @ko 풀스크린 진입 / 해제 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class FullscreenButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const target = this._targetEl; + if (!target) return; + if (isFullscreen()) { + this._exitFullscreen(); + } else { + this._requestFullscreen(target); + } + }; + this._onFullscreenChange = () => { + const element = this.element; + const controlBar = this._controlBar; + if (!controlBar) return; + const className = controlBar.className; + if (isFullscreen()) { + element.classList.add(className.FULLSCREEN_EXIT_BUTTON); + element.classList.remove(className.FULLSCREEN_BUTTON); + } else { + element.classList.add(className.FULLSCREEN_BUTTON); + element.classList.remove(className.FULLSCREEN_EXIT_BUTTON); + } + }; + this.element = document.createElement(EL_BUTTON); + this.element.title = "Toggle Fullscreen"; + this._controlBar = null; + this._targetEl = null; + } + init(viewer, controlBar) { + const element = this.element; + const className = controlBar.className; + if (!this._fullscreenAvailable()) { + element.classList.add(className.UNAVAILABLE); + return; + } + element.classList.add(className.CONTROLS_BUTTON); + element.classList.remove(className.UNAVAILABLE); + element.addEventListener(EVENTS$1.CLICK, this._onClick); + this._addFullscreenHandlers(); + if (isFullscreen()) { + element.classList.add(className.FULLSCREEN_EXIT_BUTTON); + } else { + element.classList.add(className.FULLSCREEN_BUTTON); + } + this._controlBar = controlBar; + this._targetEl = viewer.rootEl; + } + destroy() { + const element = this.element; + element.className = ""; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + this._removeFullscreenHandlers(); + this._controlBar = null; + this._targetEl = null; + } + _fullscreenAvailable() { + return FULLSCREEN_REQUEST.some(key => !!document[key]); + } + _requestFullscreen(el) { + for (const key of FULLSCREEN_REQUEST) { + const request = el[key]; + if (request) { + request.call(el); + return; + } + } + } + _exitFullscreen() { + for (const key of FULLSCREEN_EXIT) { + const exit = document[key]; + if (exit) { + exit.call(document); + return; + } + } + } + _addFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.addEventListener(evtName, this._onFullscreenChange); + }); + } + _removeFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.removeEventListener(evtName, this._onFullscreenChange); + }); + } + } + + /** + * Show video current / total time. + * @ko 비디오의 현재 / 총 재생시간을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class VideoTime extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onTimeUpdate = () => { + const video = this._video; + if (!video) return; + this._currentTime = video.source.currentTime; + this._updateDisplay(); + }; + this._onDurationChange = () => { + const video = this._video; + if (!video) return; + this._duration = video.source.duration; + this._updateDisplay(); + }; + this._onCustomTimeChange = evt => { + this._currentTime = evt.detail.time; + this._updateDisplay(); + }; + this.element = document.createElement(EL_DIV); + this._video = null; + this._currentTime = 0; + this._duration = 0; + } + init(viewer, controlBar) { + var _a; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const element = this.element; + const className = controlBar.className; + if (!video || !video.isVideo()) { + element.classList.add(className.UNAVAILABLE); + return; + } + element.classList.add(className.VIDEO_TIME_DISPLAY); + element.classList.remove(className.UNAVAILABLE); + video.source.addEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.addEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange); + this._video = video; + this._currentTime = video.source.currentTime; + this._duration = video.source.duration; + this._updateDisplay(); + } + destroy() { + const video = this._video; + if (!video) return; + this.element.className = ""; + video.source.removeEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.removeEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange); + this._video = null; + } + _updateDisplay() { + const time = this._currentTime; + const timeMinute = Math.floor(time / 60); + const timeSeconds = Math.floor(time - timeMinute * 60); + const timeSecondsFormatted = timeSeconds < 10 ? `0${timeSeconds}` : timeSeconds; + const duration = this._duration; + const durationMinute = Math.floor(duration / 60); + const durationSeconds = Math.floor(duration - durationMinute * 60); + const durationSecondsFormatted = durationSeconds < 10 ? `0${durationSeconds}` : durationSeconds; + this.element.innerText = `${timeMinute}:${timeSecondsFormatted} / ${durationMinute}:${durationSecondsFormatted}`; + } + } + + /** + * Show camera direction/fov indicator. + * @ko 카메라가 향하는 방향 및 FOV를 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class PieView extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + resetCamera = true, + position = CONTROL_BAR_ITEM_POSITION.TOP_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const viewer = this._viewer; + const resetCamera = this.resetCamera; + if (!viewer || !resetCamera) return; + const { + yaw = viewer.initialYaw, + pitch = viewer.initialPitch, + zoom = viewer.initialZoom, + duration = 500 + } = getObjectOption(resetCamera); + viewer.camera.animateTo({ + yaw, + pitch, + zoom, + duration + }); + }; + this._updatePie = ({ + target: viewer + }) => { + const piePath = this._piePathEl; + const rangeCircle = this._rangeCircleEl; + const camera = viewer.camera; + const fov = camera.getHorizontalFov(); + const yawRange = camera.getYawRange(camera.zoom); + const halfFov = fov * 0.5; + const pieRadius = 24 * Math.PI; + const pieDeg = pieRadius * fov / 360; + const pieOffset = pieRadius * (camera.yaw + halfFov + 90) / 360; + piePath.setAttribute("stroke-dasharray", `${pieDeg} ${pieRadius - pieDeg}`); + piePath.setAttribute("stroke-dashoffset", `${pieOffset}`); + if (isFinite(yawRange.min) && isFinite(yawRange.max)) { + const radius = 45 * Math.PI; // 2 * PI * r + const min = (circulate(yawRange.min, -180, 180) - halfFov) / 360; + const max = (circulate(yawRange.max, -180, 180) + halfFov) / 360; + const rangeDiff = radius * Math.abs(max - min); + const offset = -radius * (min - 0.25); + rangeCircle.setAttribute("stroke-dasharray", `${rangeDiff} ${radius - rangeDiff}`); + rangeCircle.setAttribute("stroke-dashoffset", `${offset}`); + } else { + rangeCircle.setAttribute("stroke-dasharray", ""); + rangeCircle.setAttribute("stroke-dashoffset", ""); + } + }; + this.element = document.createElement(EL_DIV); + this.element.title = "Reset view"; + this.resetCamera = resetCamera; + this._createPieElements(); + this._viewer = null; + } + init(viewer, controlBar) { + const element = this.element; + if (!viewer.initialized) { + viewer.once(EVENTS.READY, this._updatePie); + } else { + this._updatePie({ + target: viewer + }); + } + const rootClass = controlBar.className.PIEVIEW_ROOT; + element.classList.add(rootClass); + if (this.resetCamera) { + element.addEventListener(EVENTS$1.CLICK, this._onClick); + } + viewer.on(EVENTS.VIEW_CHANGE, this._updatePie); + this._viewer = viewer; + } + destroy(viewer) { + const element = this.element; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + element.className = ""; + viewer.off(EVENTS.READY, this._updatePie); + viewer.off(EVENTS.VIEW_CHANGE, this._updatePie); + this._viewer = null; + } + _createPieElements() { + const root = this.element; + const pieSVG = document.createElementNS(SVG_NAMESPACE, "svg"); + pieSVG.setAttribute("viewBox", "0 0 48 48"); + pieSVG.setAttribute("width", "100%"); + pieSVG.setAttribute("height", "100%"); + const piePath = document.createElementNS(SVG_NAMESPACE, "circle"); + piePath.setAttribute("stroke", "currentColor"); + piePath.setAttribute("fill", "transparent"); + piePath.setAttribute("cx", "24"); + piePath.setAttribute("cy", "24"); + piePath.setAttribute("r", "12"); + piePath.setAttribute("stroke-width", "24"); + pieSVG.appendChild(piePath); + const rangeCircle = document.createElementNS(SVG_NAMESPACE, "circle"); + rangeCircle.setAttribute("stroke", "currentColor"); + rangeCircle.setAttribute("fill", "transparent"); + rangeCircle.setAttribute("cx", "24"); + rangeCircle.setAttribute("cy", "24"); + rangeCircle.setAttribute("r", "22.5"); + rangeCircle.setAttribute("stroke-width", "3"); + pieSVG.appendChild(rangeCircle); + root.appendChild(pieSVG); + this._piePathEl = piePath; + this._rangeCircleEl = rangeCircle; + } + } + + /** + * Show VR enter button. + * @ko VR 진입 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class VRButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const viewer = this._viewer; + if (!viewer) return; + viewer.vr.enter(); + }; + this.element = document.createElement(EL_BUTTON); + this.element.title = "Enter VR"; + this._viewer = null; + } + init(viewer, controlBar) { + const element = this.element; + const className = controlBar.className; + element.classList.add(className.UNAVAILABLE); + element.classList.add(className.VR_BUTTON); + element.classList.add(className.CONTROLS_BUTTON); + viewer.vr.isAvailable().then(available => { + if (available) { + element.classList.remove(className.UNAVAILABLE); + } + }); + element.addEventListener(EVENTS$1.CLICK, this._onClick); + this._viewer = viewer; + } + destroy() { + const element = this.element; + element.className = ""; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + this._viewer = null; + } + } + + /** + * Show gyroscope control enable / disable button + * @ko 자이로스코프 컨트롤 활성화 / 비활성화 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class GyroButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const viewer = this._viewer; + const controlBar = this._controlBar; + if (!viewer || !controlBar) return; + const gyroControl = viewer.control.gyro; + if (gyroControl.enabled) { + gyroControl.disable(); + } else { + GyroControl.requestSensorPermission().then(available => { + if (available) { + gyroControl.enable(); + } else { + this.element.classList.add(controlBar.className.UNAVAILABLE); + } + }); + } + }; + this._updateStyle = () => { + const element = this.element; + const viewer = this._viewer; + const controlBar = this._controlBar; + if (!viewer || !controlBar) return; + const gyroControl = viewer.control.gyro; + const className = controlBar.className; + if (gyroControl.enabled) { + element.classList.add(className.GYRO_ENABLED); + element.classList.remove(className.GYRO_DISABLED); + } else { + element.classList.add(className.GYRO_DISABLED); + element.classList.remove(className.GYRO_ENABLED); + } + }; + this.element = document.createElement(EL_DIV); + this.element.title = "Toggle gyroscope control"; + } + init(viewer, controlBar) { + const element = this.element; + const className = controlBar.className; + element.addEventListener(EVENTS$1.CLICK, this._onClick); + element.classList.add(className.CONTROLS_BUTTON); + element.classList.add(className.UNAVAILABLE); + const enableButton = () => { + element.classList.remove(className.UNAVAILABLE); + viewer.control.gyro.on(CONTROL_EVENTS.ENABLE, this._updateStyle); + viewer.control.gyro.on(CONTROL_EVENTS.DISABLE, this._updateStyle); + }; + if (sensorCanBeEnabledIOS()) { + enableButton(); + } else { + GyroControl.isAvailable().then(available => { + if (!available) return; + enableButton(); + }); + } + this._controlBar = controlBar; + this._viewer = viewer; + this._updateStyle(); + } + destroy(viewer) { + const element = this.element; + viewer.control.gyro.off(CONTROL_EVENTS.ENABLE, this._updateStyle); + viewer.control.gyro.off(CONTROL_EVENTS.DISABLE, this._updateStyle); + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + element.className = ""; + this._controlBar = null; + this._viewer = null; + } + } + + class AutoHide { + get enabled() { + return !!this._targetEl; + } + get hidden() { + return this._controlBar.containerEl.classList.contains(this._hiddenClass); + } + get _hiddenClass() { + return this._controlBar.className.HIDDEN; + } + get _fixedClass() { + return this._controlBar.className.FIXED; + } + constructor(controlBar, { + initialDelay = 3000, + delay = 0, + idleDelay: activationDelay = 3000 + }) { + this._onMouseEnter = () => { + this._isCursorInside = true; + this.show(); + }; + this._onMouseLeave = () => { + this._isCursorInside = false; + this._hideAfterDelay(); + }; + this._onMouseMove = () => { + if (!this._isFullscreen) return; + this.showTemporaliy(); + }; + this._onHold = evt => { + this._isGrabbing = true; + if (evt.pointerType === "mouse") { + this._isCursorInside = true; + } + window.addEventListener(EVENTS$1.MOUSE_UP, this._onRelease); + this.show(); + }; + this._onRelease = () => { + this._isGrabbing = false; + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onRelease); + this._hideAfterDelay(); + }; + this._onVideoPlay = () => { + const root = this._targetEl; + if (!root) return; + this._controlBar.containerEl.classList.remove(this._fixedClass); + }; + this._onVideoPause = () => { + const root = this._targetEl; + if (!root) return; + this._controlBar.containerEl.classList.add(this._fixedClass); + }; + this._onFullscreenChange = () => { + this._isFullscreen = isFullscreen(); + if (this._isFullscreen) { + this._hideAfterDelay(); + } + }; + this._controlBar = controlBar; + this._initialDelay = initialDelay; + this._delay = delay; + this._idleDelay = activationDelay; + this._timer = -1; + this._isCursorInside = false; + this._isGrabbing = false; + this._isFullscreen = false; + this._video = null; + this._targetEl = null; + } + enable(viewer) { + var _a; + if (this._targetEl) { + this.disable(viewer); + } + const initialDelay = this._initialDelay; + const root = viewer.rootEl; + this._targetEl = viewer.rootEl; + this._timer = window.setTimeout(() => { + this.hide(); + }, initialDelay); + root.addEventListener(EVENTS$1.MOUSE_DOWN, this._onHold); + root.addEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter); + root.addEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove); + root.addEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave); + this._addFullscreenHandlers(); + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (!video || !video.isVideo()) { + return; + } + if (video.isPaused()) { + this._controlBar.containerEl.classList.add(this._fixedClass); + } + video.source.addEventListener(EVENTS$1.VIDEO_PLAY, this._onVideoPlay); + video.source.addEventListener(EVENTS$1.VIDEO_PAUSE, this._onVideoPause); + this._video = video; + } + disable(viewer) { + if (!this._targetEl) return; + const controlBar = this._controlBar; + const root = viewer.rootEl; + const video = this._video; + root.removeEventListener(EVENTS$1.MOUSE_DOWN, this._onHold); + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onRelease); + root.removeEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter); + root.removeEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove); + root.removeEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave); + this._removeFullscreenHandlers(); + window.clearTimeout(this._timer); + controlBar.containerEl.classList.remove(this._fixedClass); + if (video) { + video.source.removeEventListener(EVENTS$1.VIDEO_PLAY, this._onVideoPlay); + video.source.removeEventListener(EVENTS$1.VIDEO_PAUSE, this._onVideoPause); + } + this._isCursorInside = false; + this._isGrabbing = false; + this._video = null; + this._targetEl = null; + } + show() { + this._clearHideTimer(); + this._controlBar.containerEl.classList.remove(this._hiddenClass); + } + showTemporaliy() { + this.show(); + this._hideAfterDelay(this._idleDelay); + } + hide() { + this._clearHideTimer(); + this._controlBar.containerEl.classList.add(this._hiddenClass); + } + _clearHideTimer() { + if (this._timer) { + window.clearTimeout(this._timer); + this._timer = -1; + } + } + _hideAfterDelay(delay = this._delay) { + if (this._isGrabbing || !this._isFullscreen && this._isCursorInside) return; + this._clearHideTimer(); + if (delay <= 0) { + this.hide(); + } else { + this._timer = window.setTimeout(() => { + this.hide(); + }, delay); + } + } + _addFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.addEventListener(evtName, this._onFullscreenChange); + }); + } + _removeFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.removeEventListener(evtName, this._onFullscreenChange); + }); + } + } + + class VideoControl { + constructor() { + this._onKeyDown = event => { + const video = this._video; + if (!video) return; + event.preventDefault(); + event.stopPropagation(); + const videoEl = video.source; + const keyPressed = event.keyCode != null ? DIRECTION_KEY_CODE[event.keyCode] : DIRECTION_KEY_NAME[event.key]; + switch (keyPressed) { + case "LEFT": + case "RIGHT": + return this._changeVideoTime(videoEl, keyPressed === "RIGHT"); + case "UP": + case "DOWN": + return this._changeVideoVolume(videoEl, keyPressed === "UP"); + } + const spacePressed = event.keyCode === SPACE_KEY_CODE || event.key === SPACE_KEY_NAME; + if (spacePressed) { + this._toggleVideo(video); + } + }; + } + enable(root, video) { + this._video = video; + // capture is needed for resolving conflict with keyboard control + root.addEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown, true); + } + disable(root) { + this._video = null; + root.removeEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown, true); + } + _changeVideoTime(video, forward) { + const delta = forward ? 5 : -5; + video.currentTime += delta; + video.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { + detail: { + time: video.currentTime + } + })); + } + _changeVideoVolume(video, increase) { + const delta = increase ? 0.1 : -0.1; + if (video.muted) { + video.volume = clamp(delta, 0, 1); + } else { + video.volume = clamp(video.volume + delta, 0, 1); + } + if (video.volume > 0) { + video.muted = false; + } else { + video.muted = true; + } + } + _toggleVideo(video) { + if (video.isPaused()) { + video.source.play(); + } else { + video.source.pause(); + } + } + } + + /** + * A plugin that displays extra buttons & controls that controls {@link View360}. + * @ko {@link View360}에 부가적인 버튼과 컨트롤을 추가해주는 플러그인. + * @category Plugin + * @since 4.0.0 + */ + class ControlBar { + /** + * Root element of the control bar + * @ko 컨트롤바의 루트 엘리먼트 + * @since 4.0.0 + */ + get rootEl() { + return this._rootEl; + } + /** + * Container element of the control bar + * @ko 컨트롤바의 컨테이너 엘리먼트 + * @since 4.0.0 + */ + get containerEl() { + return this._containerEl; + } + /** + * Background element of the control bar + * @ko 컨트롤바의 배경 엘리먼트 + * @since 4.0.0 + */ + get backgroundEl() { + return this._bgEl; + } + /** + * Control bar's default items created by {@link ControlBarOptions} + * @ko 주어진 {@link ControlBarOptions}에 의해 생성된 디폴트 아이템들 + * @since 4.0.0 + */ + get items() { + return this._items; + } + /** + * Custom control bar items + * @ko 커스텀 컨트롤바 아이템들을 추가합니다. + * @since 4.0.0 + */ + get customItems() { + return this._customItems; + } + /** + * Create new instance of ControlBar. + * @ko ControlBar의 새 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + autoHide, + showBackground, + clickToPlay = true, + keyboardControls = true, + progressBar = true, + playButton = true, + volumeButton = true, + fullscreenButton = true, + videoTime = true, + pieView = true, + vrButton = true, + gyroButton = true, + className = {}, + customItems = [] + } = {}) { + var _a; + this._onStaticClick = ({ + target: viewer, + isTouch + }) => { + var _a; + const autoHider = this._autoHider; + if (isTouch) { + if (!autoHider.enabled) return; + if (autoHider.hidden) { + autoHider.showTemporaliy(); + } else { + autoHider.hide(); + } + } else { + if (!this.clickToPlay) return; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (!video || !video.isVideo()) return; + if (video.isPaused()) { + video.source.play(); + } else { + video.source.pause(); + } + } + }; + this._onNewSrcLoad = ({ + target: viewer + }) => { + const items = this._items; + this._updateBackground(viewer); + this._updateAutoHide(viewer); + this._updateKeyboardHandler(viewer); + Object.keys(items).forEach(key => { + const category = items[key]; + category.forEach(item => { + item.destroy(viewer, this); + item.init(viewer, this); + }); + }); + }; + this.autoHide = autoHide; + this.showBackground = showBackground; + this.clickToPlay = clickToPlay; + this.keyboardControls = keyboardControls; + this.progressBar = progressBar; + this.playButton = playButton; + this.volumeButton = volumeButton; + this.fullscreenButton = fullscreenButton; + this.videoTime = videoTime; + this.pieView = pieView; + this.vrButton = vrButton; + this.gyroButton = gyroButton; + this.className = Object.assign(Object.assign({}, ControlBar.DEFAULT_CLASS), className); + const rootClass = (_a = className.CONTROLS_ROOT) !== null && _a !== void 0 ? _a : ControlBar.DEFAULT_CLASS.CONTROLS_ROOT; + this._rootEl = createElement(rootClass); + this._createPositionWrappers(); + this._items = Object.keys(ControlBar.POSITION).reduce((items, key) => { + items[ControlBar.POSITION[key]] = []; + return items; + }, {}); + this._customItems = customItems; + this._autoHider = new AutoHide(this, getObjectOption(autoHide)); + this._videoControl = new VideoControl(); + customItems.forEach(item => { + this._items[item.position].push(item); + }); + } + init(viewer) { + const panoRoot = viewer.rootEl; + const controlsRoot = this._rootEl; + const defaultItems = this._createDefaultItems(); + this._updateBackground(viewer); + this._updateAutoHide(viewer); + this._updateKeyboardHandler(viewer); + panoRoot.appendChild(controlsRoot); + this._addItem(viewer, defaultItems); + this._addItem(viewer, this._customItems); + viewer.on(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad); + viewer.on(EVENTS.STATIC_CLICK, this._onStaticClick); + } + destroy(viewer) { + // Remove controls root from pano root + const panoRoot = viewer.rootEl; + const controlsRoot = this._rootEl; + const items = this._items; + if (controlsRoot.parentElement === panoRoot) { + panoRoot.removeChild(controlsRoot); + } + Object.keys(items).forEach(key => { + const category = items[key]; + category.forEach(item => { + item.destroy(viewer, this); + }); + items[key] = []; + }); + this._clearItemElements(); + this._autoHider.disable(viewer); + this._videoControl.disable(panoRoot); + viewer.off(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad); + viewer.off(EVENTS.STATIC_CLICK, this._onStaticClick); + } + _addItem(viewer, items) { + for (const item of items) { + const category = this._items[item.position]; + const wrapper = this._wrapperEl[item.position]; + const nextSiblingIndex = findIndex(category, sibling => sibling.order > item.order); + if (nextSiblingIndex >= 0) { + const nextSibling = category[nextSiblingIndex].element; + category.splice(nextSiblingIndex, 0, item); + wrapper.insertBefore(item.element, nextSibling); + } else { + category.push(item); + wrapper.appendChild(item.element); + } + item.init(viewer, this); + } + } + _createPositionWrappers() { + const className = Object.assign(Object.assign({}, ControlBar.DEFAULT_CLASS), this.className); + const rootEl = this._rootEl; + // BG & FLOATING CONTROLS + const backgroundEl = createElement(className.CONTROLS_BG); + const floatLeftEl = createElement(className.CONTROLS_FLOAT_LEFT); + const floatRightEl = createElement(className.CONTROLS_FLOAT_RIGHT); + rootEl.appendChild(floatLeftEl); + rootEl.appendChild(floatRightEl); + // BOTTOM CONTROLS + const container = createElement(className.CONTROLS_MAIN); + const topWrapper = createElement(className.CONTROLS_TOP); + const bottomWrapper = createElement(className.CONTROLS_BOTTOM); + const midWrapper = createElement(className.CONTROLS_MID); + const leftControlsWrapper = createElement(className.CONTROLS_LEFT); + const rightControlsWrapper = createElement(className.CONTROLS_RIGHT); + midWrapper.appendChild(leftControlsWrapper); + midWrapper.appendChild(rightControlsWrapper); + container.appendChild(backgroundEl); + container.appendChild(topWrapper); + container.appendChild(midWrapper); + container.appendChild(bottomWrapper); + rootEl.appendChild(container); + this._bgEl = backgroundEl; + this._containerEl = container; + this._wrapperEl = { + [ControlBar.POSITION.MAIN_TOP]: topWrapper, + [ControlBar.POSITION.MAIN_LEFT]: leftControlsWrapper, + [ControlBar.POSITION.MAIN_RIGHT]: rightControlsWrapper, + [ControlBar.POSITION.MAIN_BOTTOM]: bottomWrapper, + [ControlBar.POSITION.TOP_LEFT]: floatLeftEl, + [ControlBar.POSITION.TOP_RIGHT]: floatRightEl + }; + } + _clearItemElements() { + const wrappers = Object.keys(ControlBar.POSITION).map(key => ControlBar.POSITION[key]); + // Remove all elements inside wrappers + wrappers.forEach(wrapper => { + while (wrapper.firstChild) { + wrapper.removeChild(wrapper.firstChild); + } + }); + } + _updateAutoHide(viewer) { + var _a; + const autoHide = this.autoHide; + const autoHider = this._autoHider; + if (autoHide != null) { + if (autoHide) { + autoHider.enable(viewer); + } else { + autoHider.disable(viewer); + } + } else { + // Automatically choose whether to show background by content type + const texture = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (texture && texture.isVideo()) { + // Enable auto hide when content type is video + autoHider.enable(viewer); + } else { + autoHider.disable(viewer); + } + } + } + _updateBackground(viewer) { + var _a, _b; + const background = this._bgEl; + const showBackground = this.showBackground; + const hiddenClass = (_a = this.className.HIDDEN) !== null && _a !== void 0 ? _a : ControlBar.DEFAULT_CLASS.HIDDEN; + if (showBackground != null) { + if (showBackground) { + background.classList.remove(hiddenClass); + } else { + background.classList.add(hiddenClass); + } + } else { + // Automatically choose whether to show background by content type + const texture = (_b = viewer.projection) === null || _b === void 0 ? void 0 : _b.getTexture(); + if (texture && texture.isVideo()) { + // Show bg when content type is video + background.classList.remove(hiddenClass); + } else { + background.classList.add(hiddenClass); + } + } + } + _updateKeyboardHandler(viewer) { + var _a; + const panoRoot = viewer.rootEl; + const videoControl = this._videoControl; + const texture = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (this.keyboardControls && texture && texture.isVideo()) { + videoControl.enable(panoRoot, texture); + } else { + videoControl.disable(panoRoot); + } + } + _createDefaultItems() { + const items = []; + if (this.progressBar) { + items.push(new ProgressBar(getObjectOption(this.progressBar))); + } + if (this.playButton) { + items.push(new PlayButton(getObjectOption(this.playButton))); + } + if (this.volumeButton) { + items.push(new VolumeControl(getObjectOption(this.volumeButton))); + } + if (this.gyroButton) { + items.push(new GyroButton(getObjectOption(this.gyroButton))); + } + if (this.vrButton) { + items.push(new VRButton(getObjectOption(this.vrButton))); + } + if (this.fullscreenButton) { + items.push(new FullscreenButton(getObjectOption(this.fullscreenButton))); + } + if (this.videoTime) { + items.push(new VideoTime(getObjectOption(this.videoTime))); + } + if (this.pieView) { + items.push(new PieView(getObjectOption(this.pieView))); + } + return items; + } + } + /** + * Default class names that ControlBar uses + * @ko ControlBar가 사용하는 디폴트 클래스 이름들 + * @since 4.0.0 + */ + ControlBar.DEFAULT_CLASS = CONTROL_BAR_DEFAULT_CLASS; + /** + * Constants for {@link ControlBarItemOptions#position} + * @ko {@link ControlBarItemOptions#position}에 사용 가능한 값들 + */ + ControlBar.POSITION = CONTROL_BAR_ITEM_POSITION; + + /** + * Base class for projections. + * @ko 프로젝션 베이스 클래스. + * @category Projection + * @since 4.0.0 + */ + class Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + src, + video = false + }) { + this.src = src; + this.video = video; + this._mesh = null; + } + /** + * Release all resources projection has. + * This is automatically called on projection change & View360's destroy call + * @ko 현재 갖고 있는 모든 리소스를 반환합니다. + * 이 메소드는 프로젝션 변경 및 View360의 destroy 호출 시 자동으로 호출됩니다. + * @param ctx + */ + releaseAllResources(ctx) { + var _a; + (_a = this._mesh) === null || _a === void 0 ? void 0 : _a.destroy(ctx); + } + /** + * Update camera to match projection's settings. + * @ko 현재 프로젝션의 세팅으로 카메라를 업데이트합니다. + * @param camera - Instance of the camera to update {@ko 업데이트할 카메라의 인스턴스} + * @since 4.0.0 + */ + updateCamera(camera) { + // Use default mode & no view restriction + camera.resetRange(); + } + /** + * Update control to match projection's settings. + * @ko 현재 프로젝션의 세팅으로 컨트롤을 업데이트합니다. + * @param control - Instance of the control to update {@ko 업데이트할 컨트롤의 인스턴스} + * @since 4.0.0 + */ + updateControl(control) { + control.ignoreZoomScale = false; + } + /** + * Update projection. + * @ko 현재 프로젝션 정보를 갱신합니다. + * @param camera - Instance of the camera to reference {@ko 참조할 카메라의 인스턴스} + * @since 4.0.0 + */ + update(camera) {} // eslint-disable-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars + /** + * Return active texture. + * @ko 현재 활성화된 텍스쳐를 반환합니다. + * @internal + * @since 4.0.0 + */ + getTexture() { + if (!this._mesh) return null; + return this._mesh.program.uniforms.uTexture.texture; + } + /** + * A 3D triangle mesh for projection. It's `null` until loading the `src`. + * @ko Projection을 표시하기 위한 Mesh, src를 로드하기 전까지는 `null`입니다. + * @since 4.0.0 + */ + getMesh() { + return this._mesh; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class Uniform { + constructor() { + this.needsUpdate = true; + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + destroy(gl) { + // DO_NOTHING + } + } + + class UniformTextureCube extends Uniform { + constructor(ctx, texture, cubemapOrder) { + super(); + this.texture = texture; + this._webglTexture = ctx.createWebGLCubeTexture(texture, texture.width); + this._cubemapOrder = cubemapOrder; + } + destroy(gl) { + this.texture.destroy(); + gl.deleteTexture(this._webglTexture); + } + update(gl, location, isWebGL2) { + const texture = this.texture; + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY); + gl.uniform1i(location, 0); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture); + const sources = reorderCube(texture.sources, this._cubemapOrder); + sources.forEach((src, idx) => { + if (isWebGL2) { + gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src); + } else { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src); + } + }); + if (!texture.isVideo()) { + this.needsUpdate = false; + } + } + } + + /** @hidden */ + class CubeTexturePainter { + get size() { + return this._size; + } + constructor(texture, cubemapOrder) { + this.texture = texture; + this._renderingOrder = reorderCube(range(6), cubemapOrder); + const canvas = document.createElement("canvas"); + this._calcRenderingSize(); + canvas.width = this._size; + canvas.height = this._size; + this._canvas = canvas; + this._ctx = canvas.getContext("2d"); + } + destroy() { + const canvas = this._canvas; + // release memories + canvas.width = 1; + canvas.height = 1; + this._canvas = null; + } + draw(gl, isWebGL2) { + const size = this._size; + const texture = this.texture; + let surfaceIdx = 0; + for (let row = 0; row < this._row; row++) { + for (let column = 0; column < this._column; column++) { + const x = size * column; + const y = size * row; + const renderingFace = this._renderingOrder[surfaceIdx]; + this._ctx.drawImage(texture.source, x, y, size, size, 0, 0, size, size); + if (isWebGL2) { + gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas); + } else { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas); + } + surfaceIdx++; + } + } + } + _calcRenderingSize() { + const { + width, + height + } = this.texture; + const aspect = width / height; + if (aspect === 1 / 6) { + this._size = width; + this._row = 6; + this._column = 1; + } else if (aspect === 6) { + this._size = height; + this._row = 1; + this._column = 6; + } else if (aspect === 2 / 3) { + this._size = width * 0.5; + this._row = 3; + this._column = 2; + } else { + this._size = width / 3; + this._row = 2; + this._column = 3; + } + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class UniformCanvasCube extends Uniform { + get texture() { + return this._painter.texture; + } + constructor(ctx, texture, cubemapOrder) { + super(); + this._painter = new CubeTexturePainter(texture, cubemapOrder); + this._webglTexture = ctx.createWebGLCubeTexture(texture, this._painter.size); + } + destroy(gl) { + gl.deleteTexture(this._webglTexture); + this._painter.destroy(); + } + update(gl, location, isWebGL2) { + const texture = this.texture; + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + gl.uniform1i(location, 0); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture); + this._painter.draw(gl, isWebGL2); + if (!texture.isVideo()) { + this.needsUpdate = false; + } + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class TriangleMesh extends Object3D { + constructor(vao, program) { + super(); + this.vao = vao; + this.program = program; + } + destroy(ctx) { + ctx.releaseVAO(this.vao); + ctx.releaseShaderResources(this.program); + } + } + + class ShaderProgram { + constructor(ctx, vertexShader, fragmentShader, uniforms) { + this.program = ctx.createProgram(vertexShader, fragmentShader); + this.uniforms = uniforms; + this.uniformLocations = ctx.getUniformLocations(this.program, uniforms); + } + } + + /** + * @hidden + */ + class VertexData { + /** */ + constructor(data, itemSize) { + this.data = data; + this.itemSize = itemSize; + this.count = data.length / itemSize; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class Geometry { + /** */ + constructor(vertices, indicies, uvs) { + this.vertices = new VertexData(new Float32Array(vertices), 3); + this.indicies = new VertexData(new Uint16Array(indicies), 1); + this.uvs = new VertexData(new Float32Array(uvs), 2); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class CubeGeometry extends Geometry { + constructor({ + order, + rotateUV + }) { + const vertices = [ + // back + 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, + // front + -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, + // up + -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, + // down + -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, + // right + 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, + // left + -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1]; + const indicies = [0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23]; + const oneThird = 1 / 3; + const coords = []; + for (let r = 1; r >= 0; r--) { + for (let c = 0; c < 3; c++) { + const coord = [c * oneThird, r * 0.5, (c + 1) * oneThird, r * 0.5, (c + 1) * oneThird, (r + 1) * 0.5, c * oneThird, (r + 1) * 0.5]; + coords.push(coord); + } + } + if (rotateUV) { + rotateUV.forEach((degree, idx) => { + if (degree === ROTATE.ZERO) return; + const coord = coords[idx]; + let newOrder; + if (degree === ROTATE.CW_90) { + newOrder = [1, 2, 3, 0]; + } else if (degree === ROTATE.CCW_90) { + newOrder = [3, 0, 1, 2]; + } else { + newOrder = [2, 3, 0, 1]; + } + const newCoords = Array(coord.length); + for (let uvIdx = 0; uvIdx < coord.length / 2; uvIdx++) { + newCoords[uvIdx * 2 + 0] = coord[newOrder[uvIdx] * 2 + 0]; + newCoords[uvIdx * 2 + 1] = coord[newOrder[uvIdx] * 2 + 1]; + } + coords[idx] = newCoords; + }); + } + const uvs = reorderCube(coords, order, "BFUDRL").reduce((acc, val) => acc.concat(val), []); + super(vertices, indicies, uvs); + } + } + + var vs$3 = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec3 vPos;void main(){vPos=position;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}"; // eslint-disable-line + + var fs$3 = "#define GLSLIFY 1\nuniform samplerCube uTexture;varying highp vec3 vPos;void main(){gl_FragColor=textureCube(uTexture,vec3(vPos.x,vPos.y,-vPos.z));}"; // eslint-disable-line + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on cubemap images, accepts both multiple or single images. + * @ko 큐브맵 이미지 기반의 프로젝션, 단일 혹은 여러 장의 이미지를 모두 사용 가능합니다. + * @since 4.0.0 + * @category Projection + */ + class CubemapProjection extends Projection { + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param options Options {@ko Options} + */ + constructor(options) { + super(options); + const { + cubemapOrder = "RLUDFB", + cubemapFlipX = false + } = options; + this._cubemapOrder = cubemapOrder; + this._cubemapFlipX = cubemapFlipX; + } + applyTexture(ctx, texture) { + const cubemapOrder = this._cubemapOrder; + const cubemapFlipX = this._cubemapFlipX; + const uniforms = { + uTexture: texture.isCube() ? new UniformTextureCube(ctx, texture, cubemapOrder) : new UniformCanvasCube(ctx, texture, cubemapOrder) + }; + const geometry = new CubeGeometry({ + order: cubemapOrder + }); + const program = new ShaderProgram(ctx, vs$3, fs$3, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + if (cubemapFlipX) { + mesh.scale[0] = -1; + } + mesh.updateMatrix(); + this._mesh = mesh; + } + } + + class UniformTexture2D extends Uniform { + constructor(ctx, texture) { + super(); + this.texture = texture; + this._webglTexture = ctx.createWebGLTexture(texture); + } + destroy(gl) { + this.texture.destroy(); + gl.deleteTexture(this._webglTexture); + } + update(gl, location, isWebGL2) { + const texture = this.texture; + const isVideo = texture.isVideo(); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY); + gl.uniform1i(location, 0); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, this._webglTexture); + if (!isVideo && isWebGL2) { + gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); + } + if (!isVideo) { + this.needsUpdate = false; + } + } + } + + var vs$2 = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec2 vUV;void main(){vUV=uv;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}"; // eslint-disable-line + + var fs$2 = "#define GLSLIFY 1\nuniform sampler2D uTexture;varying highp vec2 vUV;void main(){gl_FragColor=texture2D(uTexture,vUV.st);}"; // eslint-disable-line + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on cubemap strip. + * Slightly more efficient than {@link CubemapProjection} as it doesn't copy cubemap image to canvas while rendering. + * Accepts only single image. + * @ko 큐브맵 스트립 기반의 프로젝션. + * {@link CubemapProjection}와 달리 렌더링하는 과정에 캔버스에 이미지를 복사하는 과정이 없기 때문에 살짝 더 효율적입니다. + * 단일 이미지만 사용 가능합니다. + * @since 4.0.0 + * @category Projection + */ + class CubestripProjection extends Projection { + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param options Options {@ko Options} + */ + constructor(options) { + super(options); + const { + cubemapOrder = "RLUDFB", + cubemapFlipX = false + } = options; + this._cubemapOrder = cubemapOrder; + this._cubemapFlipX = cubemapFlipX; + } + applyTexture(ctx, texture) { + const cubemapOrder = this._cubemapOrder; + const cubemapFlipX = this._cubemapFlipX; + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture) + }; + const geometry = new CubeGeometry({ + order: cubemapOrder + }); + const program = new ShaderProgram(ctx, vs$2, fs$2, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + if (cubemapFlipX) { + mesh.scale[0] = -1; + } + mesh.updateMatrix(); + this._mesh = mesh; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class CylinderGeometry extends Geometry { + constructor(maxTheta) { + const vertices = []; + const indicies = []; + const uvs = []; + const height = 1; + const radialSegments = 60; + const halfHeight = height * 0.5; + const heightSegments = [-halfHeight, halfHeight]; + const invRadialSegments = 1 / radialSegments; + const angleConst = maxTheta * invRadialSegments; + for (let yIdx = 0; yIdx < 2; yIdx++) { + const y = heightSegments[yIdx]; + for (let lngIdx = 0; lngIdx <= radialSegments; lngIdx++) { + const angle = lngIdx * angleConst + Math.PI - maxTheta * 0.5; + const x = Math.cos(angle); + const z = Math.sin(angle); + const u = lngIdx * invRadialSegments; + const v = yIdx; + uvs.push(u, v); + vertices.push(x, y, z); + if (yIdx === 0 && lngIdx < radialSegments) { + const a = lngIdx; + const b = a + radialSegments + 1; + indicies.push(a, b, a + 1, b, b + 1, a + 1); + } + } + } + super(vertices, indicies, uvs); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on cylindrical projection. + * This can show panorama images taken from smartphones. + * @ko 원통 투영법 기반의 프로젝션. + * 일반적인 스마트폰 파노라마 사진을 표시하는데 사용될 수 있습니다. + * @since 4.0.0 + * @category Projection + */ + class CylindricalProjection extends Projection { + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param options Options {@ko Options} + */ + constructor(options) { + super(options); + const { + partial = false + } = options; + this._partial = partial; + } + applyTexture(ctx, texture) { + const partial = this._partial; + const { + width, + height + } = texture; + const aspect = width / height; + const halfVFov = 180 / aspect; + const cylinderHeight = partial ? 1 : 2 * Math.tan(halfVFov * DEG_TO_RAD); + const cylinderTheta = partial ? aspect : 2 * Math.PI; + const geometry = new CylinderGeometry(cylinderTheta); + const program = new ShaderProgram(ctx, vs$2, fs$2, { + uTexture: new UniformTexture2D(ctx, texture) + }); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + mesh.scale[1] = cylinderHeight; + identity(mesh.rotation); + rotateY(mesh.rotation, mesh.rotation, -Math.PI / 2); + mesh.updateMatrix(); + this._mesh = mesh; + } + updateCamera(camera) { + super.updateCamera(camera); + const mesh = this._mesh; + if (!mesh) return; + const uTexture = mesh.program.uniforms.uTexture; + const texture = uTexture.texture; + const { + width, + height + } = texture; + const aspect = width / height; + const halfHeight = mesh.scale[1] * 0.5; + if (this._partial) { + const restrictedYaw = 0.5 * aspect * RAD_TO_DEG; + camera.restrictYawRange(-restrictedYaw, restrictedYaw); + } + const restrictedPitch = Math.atan2(halfHeight, 1) * RAD_TO_DEG; + const minZoom = Math.tan(camera.fov * DEG_TO_RAD * 0.5) / (halfHeight * camera.aspect); + camera.restrictPitchRange(-restrictedPitch, restrictedPitch); + camera.restrictZoomRange(minZoom, Infinity); + camera.restrictRenderHeight(halfHeight * 2); + } + } + + var fs$1 = "#define PI 3.14159265359\nprecision mediump float;\n#define GLSLIFY 1\nuniform sampler2D uTexture;varying highp vec2 vUV;const vec2 OPERATE_COORDS_RANGE=vec2(-1.0,1.0);const vec2 TEXTURE_COORDS_RANGE=vec2(0.0,1.0);const float ONE_THIRD=1.0/3.0;const float EAC_CONST=2.0/PI;float scale(vec2 domainRange,vec2 targetRange,float val){float unit=1.0/(domainRange[1]-domainRange[0]);return targetRange[0]+(targetRange[1]-targetRange[0])*(val-domainRange[0])*unit;}void main(void){float transformedCoordX;float transformedCoordY;float texRangeXStart=floor(vUV.s*3.)*ONE_THIRD;float texRangeYStart=floor(vUV.t*2.)*0.5;vec2 orgTextureRangeX=vec2(texRangeXStart,texRangeXStart+ONE_THIRD);vec2 orgTextureRangeY=vec2(texRangeYStart,texRangeYStart+0.5);float px=scale(orgTextureRangeX,OPERATE_COORDS_RANGE,vUV.s);float py=scale(orgTextureRangeY,OPERATE_COORDS_RANGE,vUV.t);float qu=EAC_CONST*atan(px)+0.5;float qv=EAC_CONST*atan(py)+0.5;transformedCoordX=scale(TEXTURE_COORDS_RANGE,orgTextureRangeX,qu);transformedCoordY=scale(TEXTURE_COORDS_RANGE,orgTextureRangeY,qv);gl_FragColor=texture2D(uTexture,vec2(transformedCoordX,transformedCoordY));}"; // eslint-disable-line + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Equi-Angular Cubemap Projection. + * This format is used by Youtube's 360 videos. + * @ko Equi-Angular Cubemap 프로젝션. + * 이 포맷은 주로 Youtube의 360 비디오에 사용됩니다. + * @since 4.0.0 + * @category Projection + */ + class EquiangularProjection extends Projection { + applyTexture(ctx, texture) { + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture) + }; + const geometry = new CubeGeometry({ + order: "LFRDBU", + rotateUV: [ROTATE.ZERO, ROTATE.ZERO, ROTATE.ZERO, ROTATE.CW_90, ROTATE.CCW_90, ROTATE.CW_90] + }); + const program = new ShaderProgram(ctx, vs$2, fs$1, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class SphereGeometry extends Geometry { + /** */ + constructor() { + // const radius = 1; + const widthSegments = 60; + const heightSegments = 60; + const ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI; + const uvs = []; + const vertices = []; + const indicies = []; + let latIdx; + let lngIdx; + for (latIdx = 0; latIdx <= widthSegments; latIdx++) { + const theta = (latIdx / widthSegments - 0.5) * Math.PI; + const sinTheta = Math.sin(theta); + const cosTheta = Math.cos(theta); + for (lngIdx = 0; lngIdx <= heightSegments; lngIdx++) { + const phi = (lngIdx / heightSegments - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN; + const sinPhi = Math.sin(phi); + const cosPhi = Math.cos(phi); + const x = cosPhi * cosTheta; + const y = sinTheta; + const z = sinPhi * cosTheta; + const u = lngIdx / heightSegments; + const v = latIdx / widthSegments; + uvs.push(u, v); + vertices.push(x, y, z); + if (lngIdx !== heightSegments && latIdx !== widthSegments) { + const a = latIdx * (heightSegments + 1) + lngIdx; + const b = a + heightSegments + 1; + indicies.push(a, a + 1, b, b, a + 1, b + 1); + } + } + } + super(vertices, indicies, uvs); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on equirectangular projection. + * @ko 등 장방형 도법(Equirectangular projection) 기반의 프로젝션 + * @since 4.0.0 + * @category Projection + */ + class EquirectProjection extends Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor(options) { + super(options); + } + applyTexture(ctx, texture) { + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture) + }; + const geometry = new SphereGeometry(); + const program = new ShaderProgram(ctx, vs$2, fs$2, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class UniformFloat extends Uniform { + constructor(val) { + super(); + this.val = val; + } + update(gl, location) { + gl.uniform1f(location, this.val); + this.needsUpdate = false; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class PlaneGeometry extends Geometry { + /** */ + constructor(width = 2, height = 2, z = -1) { + const halfWidth = width * 0.5; + const halfHeight = height * 0.5; + const vertices = [-halfWidth, -halfHeight, z, halfWidth, -halfHeight, z, -halfWidth, halfHeight, z, halfWidth, halfHeight, z]; + const indicies = [0, 1, 2, 2, 1, 3]; + const uvs = [0, 0, 1, 0, 0, 1, 1, 1]; + super(vertices, indicies, uvs); + } + } + + var vs$1 = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec2 vUV;void main(){vUV=uv;gl_Position=vec4(position,1.0);}"; // eslint-disable-line + + var fs = "precision mediump float;\n#define GLSLIFY 1\nuniform sampler2D uTexture;uniform float uYaw;uniform float uPitch;uniform float uZoom;varying highp vec2 vUV;const float PI=3.1415926536;const float PI_2=PI*0.5;vec2 toStereographicUV(in vec2 uv,in vec2 center){float R=1.*uZoom;vec2 texLatLon=(uv*2.-1.)*vec2(PI,PI_2);vec2 central=(center*2.-1.)*vec2(PI,PI_2)+vec2(PI,0);float x=texLatLon.x;float y=texLatLon.y;float rou=sqrt(x*x+y*y);float c=2.0*atan(rou,R*0.5);float sin_c=sin(c);float cos_c=cos(c);float sin_cy=sin(central.y);float cos_cy=cos(central.y);float lat=asin(cos_c*sin_cy+(y*sin_c*cos_cy)/rou);float lon=central.x+atan(x*sin_c,rou*cos_cy*cos_c-y*sin_cy*sin_c);float u=(lon/PI+1.0)*0.5;float v=(lat/PI_2+1.0)*0.5;return vec2(u,v);}void main(){vec2 central=vec2(uYaw,uPitch);vec2 uv=toStereographicUV(vUV,central);gl_FragColor=texture2D(uTexture,uv);}"; // eslint-disable-line + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on so-called "Little planet" or "Tiny planet" effect. + * @ko "Little planet" 혹은 "Tiny planet"로 불리는 이펙트 기반의 프로젝션 + * @since 4.0.0 + * @category Projection + */ + class LittlePlanetProjection extends Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor(options) { + super(options); + } + applyTexture(ctx, texture) { + texture.wrapS = WebGLRenderingContext.REPEAT; + texture.wrapT = WebGLRenderingContext.REPEAT; + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture), + uYaw: new UniformFloat(0), + uPitch: new UniformFloat(0.5), + uZoom: new UniformFloat(1) + }; + const geometry = new PlaneGeometry(); + const program = new ShaderProgram(ctx, vs$1, fs, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } + updateControl(control) { + control.ignoreZoomScale = true; + } + update(camera) { + const mesh = this._mesh; + if (!mesh) return; + const uniforms = mesh.program.uniforms; + uniforms.uYaw.val = camera.yaw / 360; + // Range from 0 ~ 1 + uniforms.uPitch.val = camera.pitch / 180 + 0.5; + uniforms.uZoom.val = camera.zoom; + uniforms.uYaw.needsUpdate = true; + uniforms.uPitch.needsUpdate = true; + uniforms.uZoom.needsUpdate = true; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class UniformVector4Array extends Uniform { + constructor(val) { + super(); + this.val = val; + } + update(gl, location) { + gl.uniform4fv(location, this.val.reduce((arr, vector) => [...arr, ...vector], [])); + this.needsUpdate = false; + } + } + + var vs = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;uniform vec4 uTexScaleOffset[2];uniform float uEye;varying highp vec2 vUV;void main(){vec4 scaleOffset=uTexScaleOffset[int(uEye)];vUV=uv.xy*scaleOffset.xy+scaleOffset.zw;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}"; // eslint-disable-line + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on stereo equirectangular images. + * @ko Stereo equirectangular 이미지 기반의 프로젝션 + * @since 4.0.0 + * @category Projection + */ + class StereoEquiProjection extends Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor(options) { + super(options); + this._mode = options.mode; + } + applyTexture(ctx, texture) { + let leftEye; + let rightEye; + switch (this._mode) { + case StereoEquiProjection.MODE.LEFT_RIGHT: + leftEye = [0.5, 1, 0, 0]; + rightEye = [0.5, 1, 0.5, 0]; + break; + default: + // Default, uses "top_bottom" + leftEye = [1, 0.5, 0, 0]; + rightEye = [1, 0.5, 0, 0.5]; + } + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture), + uEye: new UniformFloat(0), + uTexScaleOffset: new UniformVector4Array([leftEye, rightEye]) + }; + const geometry = new SphereGeometry(); + const program = new ShaderProgram(ctx, vs, fs$2, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } + } + /** + * Available stereoscopic modes + * @ko 사용가능한 스테레오스코픽 모드들 + * @since 4.0.0 + */ + StereoEquiProjection.MODE = { + /** + * @ko 이미지가 왼쪽/오른쪽으로 구성되어있을 경우 + * @since 4.0.0 + */ + LEFT_RIGHT: "left_right", + /** + * @ko 이미지가 위/아래로 구성되어있을 경우 + * @since 4.0.0 + */ + TOP_BOTTOM: "top_bottom" + }; + + /** + * @hidden + */ + const withMethods = (prototype, attr) => { + [Component.prototype, View360.prototype].forEach(proto => { + Object.getOwnPropertyNames(proto).filter(name => name.charAt(0) !== "_" && name !== "constructor").forEach(name => { + const descriptor = Object.getOwnPropertyDescriptor(proto, name); + if (descriptor.value) { + // Public Function + Object.defineProperty(prototype, name, { + value: function (...args) { + return descriptor.value.call(this[attr], ...args); + } + }); + } else { + const getterDescriptor = {}; + if (descriptor.get) { + getterDescriptor.get = function () { + var _a; + return this[attr] && ((_a = descriptor.get) === null || _a === void 0 ? void 0 : _a.call(this[attr])); + }; + } + if (descriptor.set) { + getterDescriptor.set = function (...args) { + var _a; + return (_a = descriptor.set) === null || _a === void 0 ? void 0 : _a.call(this[attr], ...args); + }; + } + Object.defineProperty(prototype, name, getterDescriptor); + } + }); + }); + }; + + /** + * @hidden + */ + const getValidProps = propsObj => { + return Object.keys(propsObj).reduce((props, propName) => { + if (propsObj[propName] != null) { + props[propName] = propsObj[propName]; + } + return props; + }, {}); + }; + + const VIEW360_METHODS = ["destroy", "init", "load", "resize", "addPlugins", "removePlugins", "renderFrame", + // @egjs/component methods + "on", "hasOn", "once", "off", "trigger"]; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + + var modules = { + __proto__: null, + 'default': View360, + Autoplay: Autoplay, + AutoResizer: AutoResizer, + Camera: Camera, + CameraAnimation: CameraAnimation, + Motion: Motion, + Object3D: Object3D, + View360Error: View360Error, + WebGLRenderer: WebGLRenderer, + XRManager: XRManager, + PanoControl: PanoControl, + RotateControl: RotateControl, + ZoomControl: ZoomControl, + GyroControl: GyroControl, + ControlBar: ControlBar, + ControlBarItem: ControlBarItem, + FullscreenButton: FullscreenButton, + PieView: PieView, + PlayButton: PlayButton, + ProgressBar: ProgressBar, + VideoTime: VideoTime, + VolumeControl: VolumeControl, + LoadingSpinner: LoadingSpinner, + Projection: Projection, + CubemapProjection: CubemapProjection, + CubestripProjection: CubestripProjection, + CylindricalProjection: CylindricalProjection, + EquiangularProjection: EquiangularProjection, + EquirectProjection: EquirectProjection, + LittlePlanetProjection: LittlePlanetProjection, + StereoEquiProjection: StereoEquiProjection, + Hotspot: Hotspot, + HotspotRenderer: HotspotRenderer, + ERROR_CODES: ERROR_CODES, + DEFAULT_CLASS: DEFAULT_CLASS, + EVENTS: EVENTS, + EASING: EASING, + getValidProps: getValidProps, + VIEW360_METHODS: VIEW360_METHODS, + withMethods: withMethods + }; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + merge(View360, modules); + + return View360; + +})); +//# sourceMappingURL=view360.pkgd.js.map diff --git a/demo/release/4.0.0-beta.4/dist/view360.pkgd.js.map b/demo/release/4.0.0-beta.4/dist/view360.pkgd.js.map new file mode 100644 index 000000000..3e34446c5 --- /dev/null +++ b/demo/release/4.0.0-beta.4/dist/view360.pkgd.js.map @@ -0,0 +1 @@ +{"version":3,"file":"view360.pkgd.js","sources":["../src/core/View360Error.ts","../src/const/error.ts","../src/const/browser.ts","../src/const/external.ts","../src/const/internal.ts","../src/utils.ts","../src/core/Motion.ts","../src/core/CameraAnimation.ts","../src/core/Camera.ts","../src/control/input/MouseInput.ts","../src/control/input/TouchInput.ts","../src/control/input/KeyboardInput.ts","../src/control/RotateControl.ts","../src/control/input/WheelInput.ts","../src/control/input/PinchInput.ts","../src/control/ZoomControl.ts","../src/control/input/GyroInput.ts","../src/control/GyroControl.ts","../src/control/PanoControl.ts","../src/texture/Texture.ts","../src/texture/Texture2D.ts","../src/texture/TextureVideo.ts","../src/texture/TextureCube.ts","../src/core/TextureLoader.ts","../src/core/FrameAnimator.ts","../src/core/AutoResizer.ts","../src/core/Autoplay.ts","../src/core/XRManager.ts","../src/hotspot/Hotspot.ts","../src/hotspot/HotspotRenderer.ts","../src/core/VertexArrayObject.ts","../src/core/WebGLContext.ts","../src/core/WebGLRenderer.ts","../src/View360.ts","../src/core/Object3D.ts","../src/plugin/LoadingSpinner/LoadingSpinner.ts","../src/plugin/ControlBar/ControlBarItem.ts","../src/plugin/ControlBar/const.ts","../src/plugin/ControlBar/RangeControl.ts","../src/plugin/ControlBar/ProgressBar.ts","../src/plugin/ControlBar/PlayButton.ts","../src/plugin/ControlBar/VolumeControl.ts","../src/plugin/ControlBar/FullscreenButton.ts","../src/plugin/ControlBar/VideoTime.ts","../src/plugin/ControlBar/PieView.ts","../src/plugin/ControlBar/VRButton.ts","../src/plugin/ControlBar/GyroButton.ts","../src/plugin/ControlBar/AutoHide.ts","../src/plugin/ControlBar/VideoControl.ts","../src/plugin/ControlBar/ControlBar.ts","../src/projection/Projection.ts","../src/uniform/Uniform.ts","../src/uniform/UniformTextureCube.ts","../src/core/CubeTexturePainter.ts","../src/uniform/UniformCanvasCube.ts","../src/core/TriangleMesh.ts","../src/core/ShaderProgram.ts","../src/core/VertexData.ts","../src/geometry/Geometry.ts","../src/geometry/CubeGeometry.ts","../src/projection/CubemapProjection.ts","../src/uniform/UniformTexture2D.ts","../src/projection/CubestripProjection.ts","../src/geometry/CylinderGeometry.ts","../src/projection/CylindricalProjection.ts","../src/projection/EquiangularProjection.ts","../src/geometry/SphereGeometry.ts","../src/projection/EquirectProjection.ts","../src/uniform/UniformFloat.ts","../src/geometry/PlaneGeometry.ts","../src/projection/LittlePlanetProjection.ts","../src/uniform/UniformVector4Array.ts","../src/projection/StereoEquiProjection.ts","../src/cfc/withMethods.ts","../src/cfc/utils.ts","../src/cfc/const.ts","../src/index.ts","../src/index.umd.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * Error thrown by {@link View360}\n * @ko {@link View360}이 발생시킨 에러\n * @since 4.0.0\n */\nclass View360Error extends Error {\n /**\n * Error code\n * @ko 에러 코드\n * @see ERROR_CODES\n */\n public code: number;\n\n /**\n * Create new instance of View360Error\n * @ko View360Error의 인스턴스를 생성합니다.\n * @param message - Error message {@ko 에러 메시지}\n * @param code - Error code {@ko 에러 코드}\n */\n public constructor(message: string, code: number) {\n super(message);\n\n Object.setPrototypeOf(this, View360Error.prototype);\n\n this.name = \"View360Error\";\n this.code = code;\n }\n}\n\nexport default View360Error;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * Error codes of {@link View360Error}\n * @ko {@link View360Error}가 가질 수 있는 에러 코드 값들\n * @since 4.0.0\n */\nexport const ERROR_CODES = {\n /**\n * The given value's type is not expected\n * @ko 주어진 값의 타입이 잘못되었을 경우\n * @since 4.0.0\n */\n WRONG_TYPE: 0,\n /**\n * The given value is not a supported option\n * @ko 잘못된 옵션을 받았을 경우\n * @since 4.0.0\n */\n WRONG_OPTION: 1,\n /**\n * The element with given CSS selector does not exist\n * @ko 주어진 CSS 셀렉터로 엘리먼트를 찾지 못했을 경우\n * @since 4.0.0\n */\n ELEMENT_NOT_FOUND: 2,\n /**\n * Couldn't find canvas element inside the given container element.\n * @ko 컨테이너 엘리먼트 내부에서 캔버스 엘리먼트를 찾지 못했을 경우\n * @since 4.0.0\n */\n CANVAS_NOT_FOUND: 3,\n /**\n * The browser does not support WebGL\n * @ko 브라우저가 WebGL을 지원하지 않는 경우\n * @since 4.0.0\n */\n WEBGL_NOT_SUPPORTED: 4,\n /**\n * Failed creating canvas 2D context\n * @ko 캔버스 2D 컨텍스트를 생성하지 못한 경우\n * @since 4.0.0\n */\n FAILED_CREATE_CONTEXT_2D: 5,\n /**\n * `init()` is called before setting {@link View360Options#projection}\n * @ko {@link View360Options#projection}을 설정하기 전에 `init()`이 호출된 경우\n * @since 4.0.0\n */\n PROVIDE_PROJECTION_FIRST: 6,\n /**\n * Failed linking WebGL program. Only can be thrown when {@link View360Options#debug} is `true`.\n * @ko WebGL 프로그램 링크에 실패한 경우. {@link View360Options#debug}를 `true`로 설정한 경우에만 발생할 수 있습니다.\n * @since 4.0.0\n */\n FAILED_LINKING_PROGRAM: 7,\n /**\n * Arguments are not sufficient for the given property.\n * @ko 프로퍼티에 값이 충분히 주어지지 않았을 때\n * @since 4.0.0\n */\n INSUFFICIENT_ARGS: 8\n} as const;\n\nexport const MESSAGES = {\n WRONG_TYPE: (val: any, types: string[]) => `${typeof val} is not a ${types.map(type => `\"${type}\"`).join(\" or \")}.`,\n WRONG_OPTION: (val: any, optionName: string) => `Bad option: given \"${val}\" for option \"${optionName}\".`,\n ELEMENT_NOT_FOUND: (query: string) => `Element with selector \"${query}\" not found.`,\n CANVAS_NOT_FOUND: \"The canvas element was not found inside the given root element.\",\n WEBGL_NOT_SUPPORTED: \"WebGL is not supported on this browser.\",\n FAILED_CREATE_CONTEXT_2D: \"Failed to create canvas 2D context\",\n PROVIDE_PROJECTION_FIRST: \"\\\"projection\\\" should be provided before initialization.\",\n FAILED_LINKING_PROGRAM: (msg: string | null, shaderLog: string | null) => `Failed linking WebGL program - \"${msg}\\nShader compile Log: ${shaderLog}`,\n INSUFFICIENT_ARGS: (val: any, name: string) => `Insufficient arguments: given \"${val}\" for \"${name}\".`\n};\n\nexport default {\n CODES: ERROR_CODES,\n MESSAGES\n};\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nexport const EVENTS = {\n MOUSE_DOWN: \"mousedown\",\n MOUSE_MOVE: \"mousemove\",\n MOUSE_UP: \"mouseup\",\n TOUCH_START: \"touchstart\",\n TOUCH_MOVE: \"touchmove\",\n TOUCH_END: \"touchend\",\n WHEEL: \"wheel\",\n RESIZE: \"resize\",\n CONTEXT_MENU: \"contextmenu\",\n MOUSE_ENTER: \"mouseenter\",\n MOUSE_LEAVE: \"mouseleave\",\n POINTER_DOWN: \"pointerdown\",\n POINTER_MOVE: \"pointermove\",\n POINTER_UP: \"pointerup\",\n POINTER_CANCEL: \"pointercancel\",\n POINTER_ENTER: \"pointerenter\",\n POINTER_LEAVE: \"pointerleave\",\n KEY_DOWN: \"keydown\",\n KEY_UP: \"keyup\",\n LOAD: \"load\",\n ERROR: \"error\",\n CLICK: \"click\",\n DOUBLE_CLICK: \"dblclick\",\n CONTEXT_CREATE_ERROR: \"webglcontextcreationerror\",\n CONTEXT_LOST: \"webglcontextlost\",\n CONTEXT_RESTORED: \"webglcontextrestored\",\n DEVICE_ORIENTATION: \"deviceorientation\",\n DEVICE_MOTION: \"devicemotion\",\n ORIENTATION_CHANGE: \"orientationchange\",\n VIDEO_PLAY: \"play\",\n VIDEO_PAUSE: \"pause\",\n VIDEO_LOADED_DATA: \"loadeddata\",\n VIDEO_VOLUME_CHANGE: \"volumechange\",\n VIDEO_TIME_UPDATE: \"timeupdate\",\n VIDEO_DURATION_CHANGE: \"durationchange\",\n VIDEO_CAN_PLAYTHROUGH: \"canplaythrough\",\n TRANSITION_END: \"transitionend\",\n XR_END: \"end\"\n} as const;\n\nexport const EL_DIV = \"div\";\nexport const EL_BUTTON = \"button\";\n\n// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button\nexport enum MOUSE_BUTTON {\n LEFT,\n MIDDLE,\n RIGHT\n}\n\nexport const CURSOR = {\n GRAB: \"grab\",\n GRABBING: \"grabbing\",\n NONE: \"\"\n} as const;\n\nexport const KEY_DIRECTION = [\"LEFT\", \"UP\", \"RIGHT\", \"DOWN\"] as const;\nexport enum DIRECTION_KEY_CODE {\n LEFT = 37,\n UP = 38,\n RIGHT = 39,\n DOWN = 40\n}\nexport const SPACE_KEY_CODE = 32;\n\nexport const DIRECTION_KEY_NAME = {\n LEFT: \"ArrowLeft\",\n UP: \"ArrowUp\",\n RIGHT: \"ArrowRight\",\n DOWN: \"ArrowDown\"\n} as const;\nexport const SPACE_KEY_NAME = \" \";\n\nexport const FULLSCREEN_REQUEST = [\n \"requestFullscreen\",\n \"webkitRequestFullscreen\",\n \"webkitRequestFullScreen\",\n \"webkitCancelFullScreen\",\n \"mozRequestFullScreen\",\n \"msRequestFullscreen\"\n];\n\nexport const FULLSCREEN_ELEMENT = [\n \"fullscreenElement\",\n \"webkitFullscreenElement\",\n \"webkitCurrentFullScreenElement\",\n \"mozFullScreenElement\",\n \"msFullscreenElement\"\n];\n\nexport const FULLSCREEN_EXIT = [\n \"exitFullscreen\",\n \"webkitExitFullscreen\",\n \"webkitCancelFullScreen\",\n \"mozCancelFullScreen\",\n \"msExitFullscreen\"\n];\n\nexport const FULLSCREEN_CHANGE = [\n \"fullscreenchange\",\n \"webkitfullscreenchange\",\n \"mozfullscreenchange\",\n \"MSFullscreenChange\"\n];\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nexport { ERROR_CODES } from \"./error\";\n\n/**\n * Default class names\n * @ko 기본 클래스 이름들\n * @since 4.0.0\n */\nexport const DEFAULT_CLASS = {\n CONTAINER: \"view360-container\",\n CANVAS: \"view360-canvas\",\n CTX_LOST: \"view360-ctx-lost\",\n IN_VR: \"view360-vr-presenting\",\n HOTSPOT_CONTAINER: \"view360-hotspots\",\n HOTSPOT: \"view360-hotspot\",\n HOTSPOT_VISIBLE: \"view360-hotspot-visible\",\n HOTSPOT_FLIP_X: \"view360-hotspot-flip-x\",\n HOTSPOT_FLIP_Y: \"view360-hotspot-flip-y\",\n} as const;\n\n/**\n * Event names\n * @ko 이벤트 이름들\n * @since 4.0.0\n * @example\n * ```ts\n * import View360, { EVENTS } from \"@egjs/view360\";\n *\n * const viewer = new View360(\"#el_id\");\n *\n * viewer.on(EVENTS.READY, evt => {\n * console.log(\"View360 is ready!\");\n * });\n * ```\n */\nexport const EVENTS = {\n READY: \"ready\",\n LOAD_START: \"loadStart\",\n LOAD: \"load\",\n PROJECTION_CHANGE: \"projectionChange\",\n RESIZE: \"resize\",\n BEFORE_RENDER: \"beforeRender\",\n RENDER: \"render\",\n INPUT_START: \"inputStart\",\n INPUT_END: \"inputEnd\",\n VIEW_CHANGE: \"viewChange\",\n STATIC_CLICK: \"staticClick\",\n VR_START: \"vrStart\",\n VR_END: \"vrEnd\"\n} as const;\n\n/**\n * Collection of predefined easing functions\n * @ko 미리 정의된 easing 함수들\n */\nexport const EASING = {\n LINEAR: (x: number) => x,\n SINE_WAVE: (x: number) => Math.sin(x * Math.PI * 2),\n EASE_OUT_CUBIC: (x: number) => 1 - Math.pow(1 - x, 3),\n EASE_OUT_BOUNCE: (x: number): number => {\n const n1 = 7.5625;\n const d1 = 2.75;\n\n if (x < 1 / d1) {\n return n1 * x * x;\n } else if (x < 2 / d1) {\n return n1 * (x -= 1.5 / d1) * x + 0.75;\n } else if (x < 2.5 / d1) {\n return n1 * (x -= 2.25 / d1) * x + 0.9375;\n } else {\n return n1 * (x -= 2.625 / d1) * x + 0.984375;\n }\n }\n} as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { EASING } from \"./external\";\nimport { Range } from \"../type/utils\";\n\nexport const CAMERA_EVENTS = {\n CHANGE: \"change\",\n ANIMATION_END: \"animationEnd\"\n} as const;\n\nexport const CONTROL_EVENTS = {\n INPUT_START: \"inputStart\",\n CHANGE: \"change\",\n INPUT_END: \"inputEnd\",\n ENABLE: \"enable\",\n DISABLE: \"disable\",\n STATIC_CLICK: \"staticClick\"\n} as const;\n\nexport const DEG_TO_RAD = Math.PI / 180;\nexport const RAD_TO_DEG = 180 / Math.PI;\nexport const DEFAULT_EASING = EASING.EASE_OUT_CUBIC;\nexport const DEFAULT_ANIMATION_DURATION = 300;\nexport const INFINITE_RANGE: Readonly = {\n min: -Infinity, max: Infinity\n} as const;\nexport const DEFAULT_PITCH_RANGE: Readonly = {\n min: -90, max: 90\n} as const;\nexport const DEFAULT_ZOOM_RANGE: Readonly = {\n min: 0.6, max: 10\n} as const;\n\nexport enum ROTATE {\n ZERO,\n CW_90,\n CCW_90,\n CW_180\n}\n\n// Custom event name for video time change\nexport const VIDEO_TIME_CHANGE_EVENT = \"view360videotimechange\";\nexport const SVG_NAMESPACE = \"http://www.w3.org/2000/svg\";\nexport const SESSION_VR = \"immersive-vr\";\nexport const XR_REFERENCE_SPACE = \"local\";\n\nexport const EPSILON = Number.EPSILON ?? 2.220446049250313e-16;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { quat, vec3 } from \"gl-matrix\";\nimport View360Error from \"./core/View360Error\";\nimport ERROR from \"./const/error\";\nimport * as BROWSER from \"./const/browser\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"./const/internal\";\nimport { NoBoolean } from \"./type/utils\";\n\nexport const isString = (val: any): val is string => typeof val === \"string\";\nexport const isElement = (val: any): val is Element => !!val && val.nodeType === Node.ELEMENT_NODE;\n\nexport const createElement = (className: string, tag = BROWSER.EL_DIV) => {\n const el = document.createElement(tag);\n\n el.classList.add(className);\n\n return el;\n};\n\nexport const getNullableElement = (el: HTMLElement | string | null, parent?: HTMLElement): HTMLElement | null => {\n let targetEl: HTMLElement | null = null;\n\n if (isString(el)) {\n const parentEl = parent ? parent : document;\n const queryResult = parentEl.querySelector(el);\n\n if (!queryResult) {\n return null;\n }\n\n targetEl = queryResult as HTMLElement;\n } else if (isElement(el)) {\n targetEl = el;\n }\n\n return targetEl;\n};\n\nexport const getElement = (el: HTMLElement | string, parent?: HTMLElement): HTMLElement => {\n const targetEl = getNullableElement(el, parent);\n\n if (!targetEl) {\n if (isString(el)) {\n throw new View360Error(ERROR.MESSAGES.ELEMENT_NOT_FOUND(el), ERROR.CODES.ELEMENT_NOT_FOUND);\n } else {\n throw new View360Error(ERROR.MESSAGES.WRONG_TYPE(el, [\"HTMLElement\", \"string\"]), ERROR.CODES.WRONG_TYPE);\n }\n }\n\n return targetEl;\n};\n\nexport const findCanvas = (root: HTMLElement, selector: string): HTMLCanvasElement => {\n const canvas = root.querySelector(selector) as HTMLCanvasElement;\n\n if (!canvas) {\n throw new View360Error(ERROR.MESSAGES.CANVAS_NOT_FOUND, ERROR.CODES.CANVAS_NOT_FOUND);\n }\n\n return canvas;\n};\n\nexport const range = (end: number): number[] => {\n if (!end || end <= 0) {\n return [];\n }\n\n return Array.apply(0, Array(end)).map((undef, idx) => idx);\n};\n\nexport const clamp = (x: number, min: number, max: number) => Math.max(Math.min(x, max), min);\n\n// Linear interpolation between a and b\nexport const lerp = (a: number, b: number, t: number) => {\n return a * (1 - t) + b * t;\n};\n\nexport const circulate = (val: number, min: number, max: number) => {\n const size = Math.abs(max - min);\n\n if (val < min) {\n const offset = (min - val) % size;\n val = max - offset;\n } else if (val > max) {\n const offset = (val - max) % size;\n val = min + offset;\n }\n\n return val;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const merge = (target: object, ...srcs: object[]): object => {\n srcs.forEach(source => {\n Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n });\n });\n\n return target;\n};\n\nexport const findIndex = (array: T[], checker: (val: T) => boolean): number => {\n for (let idx = 0; idx < array.length; idx++) {\n if (checker(array[idx])) {\n return idx;\n }\n }\n\n return -1;\n};\n\nexport const getObjectOption = >(val?: T): NoBoolean => typeof val === \"object\" ? val : {} as any;\nexport const toVerticalFov = (fovRadian: number, aspect: number) => {\n return Math.atan(Math.tan(fovRadian * 0.5) / aspect) * 2;\n};\n\nexport const reorderCube = (arr: T[], order: string, defaultOrder = \"RLUDFB\"): T[] => {\n return defaultOrder.split(\"\")\n .map(face => order.indexOf(face))\n .map(index => arr[index]);\n};\n\nexport const isFullscreen = () => {\n if (!document) return false;\n\n for (const key of BROWSER.FULLSCREEN_ELEMENT) {\n if (document[key]) return true;\n }\n\n return false;\n};\n\nexport const sensorCanBeEnabledIOS = () => {\n return !!DeviceMotionEvent && \"requestPermission\" in DeviceMotionEvent && window.isSecureContext;\n};\n\nexport const hfovToZoom = (baseFov: number, fov: number) => {\n const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5);\n const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5);\n\n return renderingWidth / zoomedWidth;\n};\n\nexport const eulerToQuat = (out: quat, yaw: number, pitch: number, roll: number): quat => {\n quat.identity(out);\n\n const pitchThreshold = 0.01;\n const pitchClamped = clamp(pitch, -90 + pitchThreshold, 90 - pitchThreshold);\n\n quat.rotateY(out, out, yaw * DEG_TO_RAD);\n quat.rotateX(out, out, pitchClamped * DEG_TO_RAD);\n quat.rotateZ(out, out, roll * DEG_TO_RAD);\n\n return out;\n};\n\n/**\n * Extract euler angles from the quaternion, except roll(z-axis rotation)\n * @hidden\n */\nexport const quatToEuler = (quaternion: quat) => {\n const x = quaternion[0];\n const y = quaternion[1];\n const z = quaternion[2];\n const w = quaternion[3];\n const x2 = x * x;\n const y2 = y * y;\n const z2 = z * z;\n const w2 = w * w;\n\n const unit = x2 + y2 + z2 + w2;\n const test = x * w - y * z;\n\n let pitch: number, yaw: number;\n\n if (test > 0.499995 * unit) {\n // singularity at the north pole\n pitch = Math.PI / 2;\n yaw = 2 * Math.atan2(y, x);\n } else if (test < -0.499995 * unit) {\n // singularity at the south pole\n pitch = -Math.PI / 2;\n yaw = -2 * Math.atan2(y, x);\n } else {\n const view = vec3.fromValues(0, 0, 1);\n const up = vec3.fromValues(0, 1, 0);\n\n vec3.transformQuat(view, view, quaternion);\n vec3.transformQuat(up, up, quaternion);\n\n const viewXZ = Math.sqrt(view[0] * view[0] + view[2] * view[2]);\n\n pitch = Math.atan2(-view[1], viewXZ);\n yaw = Math.atan2(view[0], view[2]);\n }\n\n return {\n pitch: clamp(pitch * RAD_TO_DEG, -90, 90),\n yaw: circulate(yaw * RAD_TO_DEG, 0, 360)\n };\n};\n","/*\n * Copyright (c) 2020 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport { clamp, lerp, circulate } from \"../utils\";\nimport { Range } from \"../type/utils\";\nimport { DEFAULT_ANIMATION_DURATION, DEFAULT_EASING } from \"../const/internal\";\n\n/**\n * Interpolator between two values with duration\n * @ko 특정 시간동안 두 값을 보간해주는 보간기\n * @since 4.0.0\n */\nclass Motion {\n // Options\n private _duration: number;\n private _loop: boolean;\n private _range: Range;\n private _easing: (x: number) => number;\n\n // Internal states\n private _progress: number;\n private _val: number;\n private _start: number;\n private _end: number;\n private _activated: boolean;\n\n /**\n * Current interpolated value\n * @ko 현재 보간된 값\n * @since 4.0.0\n */\n public get val() { return this._val; }\n /**\n * Start(from) value of interpolation\n * @ko 보간 시작 값\n * @since 4.0.0\n */\n public get start() { return this._start; }\n /**\n * End(to) value of interpolation\n * @ko 보간 끝 값\n * @since 4.0.0\n */\n public get end() { return this._end; }\n /**\n * Interpolation progress value (0 ~ 1)\n * @ko 현재 보간 진행정도 (0 ~ 1)\n * @since 4.0.0\n */\n public get progress() { return this._progress; }\n /**\n * Whether the interpolation is in active state.\n * @ko 보간 진행중인지 여부. `true`일 경우 보간이 진행중입니다.\n * @since 4.0.0\n */\n public get activated() { return this._activated; }\n\n /**\n * Duration of the interpolation\n * @ko 보간할 시간\n * @since 4.0.0\n */\n public get duration() { return this._duration; }\n public set duration(val: number) { this._duration = val; }\n\n /**\n * Whether to loop interpolation on finish\n * @ko 보간이 끝난 이후에 다시 시작할지 여부\n * @since 4.0.0\n */\n public get loop() { return this._loop; }\n public set loop(val: boolean) { this._loop = val; }\n\n /**\n * Range of the interpolation\n * @ko 보간 범위\n * @since 4.0.0\n */\n public get range() { return this._range; }\n\n /**\n * Easing function of the interpolation\n * @ko 보간에 사용되는 easing function\n * @since 4.0.0\n */\n public get easing() { return this._easing; }\n public set easing(val: (x: number) => number) { this._easing = val; }\n\n /**\n * Create new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options Options {@ko 옵션들}\n * @param options.duration Duration of the interpolation {@ko 보간할 시간}\n * @param options.loop Whether to loop interpolation on finish {@ko 보간이 끝난 이후에 다시 시작할지 여부}\n * @param options.range Range of the interpolation {@ko 보간 범위}\n * @param options.loop Easing function of the interpolation {@ko 보간에 사용되는 easing function}\n */\n public constructor({\n duration = DEFAULT_ANIMATION_DURATION,\n loop = false,\n range = { min: 0, max: 1 },\n easing = DEFAULT_EASING\n } = {}) {\n this._duration = duration;\n this._loop = loop;\n this._range = range;\n this._easing = easing;\n this._activated = false;\n this.reset(0);\n }\n\n /**\n * Update motion and progress it by given deltaTime\n * @ko 주어진 deltaTime만큼 보간을 진행합니다.\n * @param deltaTime - number of milisec to update motion {@ko 보간을 진행할 시간, 밀리초 단위}\n * @returns Difference(delta) of the value from the last update. {@ko 지난 업데이트 이후의 값 변화량}\n * @since 4.0.0\n */\n public update(deltaTime: number): number {\n if (!this._activated) {\n this._val = this._end;\n return 0;\n }\n\n const start = this._start;\n const end = this._end;\n const duration = this._duration;\n const prev = this._val;\n const loop = this._loop;\n\n const nextProgress = this._progress + deltaTime / duration;\n\n this._progress = loop\n ? circulate(nextProgress, 0, 1)\n : clamp(nextProgress, 0, 1);\n\n const easedProgress = this._easing(this._progress);\n this._val = lerp(start, end, easedProgress);\n\n if (!loop && this._progress >= 1) {\n this._activated = false;\n }\n\n return this._val - prev;\n }\n\n /**\n * Set `start`, `end` to the given value and set `progress` to 0.\n * @ko 주어진 값으로 시작 지점, 끝 지점을 초기화하고 progress를 0으로 세팅합니다.\n * @param defaultVal - Value to reset {@ko 초기화할 값}\n * @since 4.0.0\n */\n public reset(defaultVal: number): void {\n const range = this._range;\n const val = clamp(defaultVal, range.min, range.max);\n this._start = val;\n this._end = val;\n this._val = val;\n this._progress = 0;\n this._activated = false;\n }\n\n /**\n * Add delta to start & end and current value.\n * @ko 현재 & 끝 및 현재 값에 주어진 값을 더합니다.\n * @param delta - Delta value to add {@ko 추가할 값}\n */\n public add(delta: number) {\n const range = this._range;\n\n this._start = clamp(this._start + delta, range.min, range.max);\n this._end = clamp(this._end + delta, range.min, range.max);\n this._val = clamp(this._val + delta, range.min, range.max);\n }\n\n /**\n * Set current value to start, and end to current value + delta, then reset progress to 0.\n * @ko 현재 값을 시작 지점으로, 그에서 delta만큼 추가된 값을 끝점으로 하고 progress를 0으로 갱신합니다.\n * @param delta - Delta value to add {@ko 추가할 값}\n */\n public setNewEndByDelta(delta: number): void {\n const range = this._range;\n\n this._start = this._val;\n this._end = clamp(this._end + delta, range.min, range.max);\n this._progress = 0;\n this._activated = true;\n }\n\n /**\n * Set new range of the interpolation.\n * @ko 보간의 범위를 변경합니다.\n * @param min - New minimum range {@ko 변경할 범위의 최소값}\n * @param max - New maximum range {@ko 변경할 범위의 최대값}\n */\n public setRange(min: number, max: number) {\n this._start = clamp(this._start, min, max);\n this._end = clamp(this._end, min, max);\n this._range = { min, max };\n }\n}\n\nexport default Motion;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { quat } from \"gl-matrix\";\nimport Camera from \"./Camera\";\nimport Motion from \"./Motion\";\nimport { DEFAULT_ANIMATION_DURATION, DEFAULT_EASING } from \"../const/internal\";\nimport { lerp } from \"../utils\";\n\ntype CameraPose = {\n rotation: quat;\n zoom: number;\n}\n\n/**\n * Animation of the {@link Camera}\n * @internal\n * @ko {@link Camera}의 애니메이션\n * @since 4.0.0\n */\nclass CameraAnimation {\n // Options\n private _camera: Camera;\n private _from: CameraPose;\n private _to: CameraPose;\n\n // Internal values\n private _motion: Motion;\n private _finishPromise: Promise;\n private _finish: () => void;\n\n /**\n * Duration of the animation\n * @ko 애니메이션 재생시간\n * @since 4.0.0\n */\n public get duration() { return this._motion.duration; }\n public set duration(val: number) { this._motion.duration = val; }\n /**\n * Easing function of the animation\n * @ko 애니메이션의 easing function\n * @since 4.0.0\n */\n public get easing() { return this._motion.easing; }\n public set easing(val: (x: number) => number) { this._motion.easing = val; }\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param camera - Camera to animate {@ko 애니메이션을 적용할 카메라}\n * @param from - Start pose {@ko 애니메이션이 시작 시점의 카메라의 회전 및 줌}\n * @param to - End pose {@ko 애니메이션이 끝났을 때 카메라의 회전 및 줌}\n * @param options - Options {@ko 옵션들}\n * @param options.duration - Animation duration {@ko 애니메이션 재생 시간}\n * @param options.easing - Animation easing function {@ko 애니메이션 easing function}\n */\n public constructor(camera: Camera, from: CameraPose, to: CameraPose, {\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING\n } = {}) {\n this._camera = camera;\n this._motion = new Motion({ duration, easing, range: { min: 0, max: 1 } });\n this._from = from;\n this._to = to;\n this._finishPromise = new Promise(resolve => {\n this._finish = resolve as () => void;\n });\n\n // Enable motion\n this._motion.setNewEndByDelta(1);\n }\n\n /**\n * Return a promise that resolved on animation end.\n * @ko 애니메이션 재생이 끝났을 때 resolve되는 Promise를 반환합니다.\n * @since 4.0.0\n */\n public getFinishPromise() {\n return this._finishPromise;\n }\n\n /**\n * Update animation by given deltaTime.\n * @ko 주어진 시간만큼 애니메이션을 업데이트합니다.\n * @param deltaTime Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n */\n public update(deltaTime: number): void {\n const camera = this._camera;\n const from = this._from;\n const to = this._to;\n const motion = this._motion;\n motion.update(deltaTime);\n\n // Progress that easing is applied\n const progress = motion.val;\n const rotation = quat.create();\n const zoom = lerp(from.zoom, to.zoom, progress);\n\n quat.slerp(rotation, from.rotation, to.rotation, progress);\n camera.rotate(rotation, zoom);\n\n if (progress >= 1) {\n this._finish();\n }\n }\n}\n\nexport default CameraAnimation;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { mat4, quat, vec3 } from \"gl-matrix\";\nimport CameraAnimation from \"./CameraAnimation\";\nimport {\n CAMERA_EVENTS,\n DEG_TO_RAD,\n INFINITE_RANGE,\n DEFAULT_PITCH_RANGE,\n RAD_TO_DEG,\n DEFAULT_ZOOM_RANGE,\n DEFAULT_EASING,\n EPSILON\n} from \"../const/internal\";\nimport {\n circulate,\n clamp,\n eulerToQuat,\n quatToEuler,\n toVerticalFov\n} from \"../utils\";\nimport { Range } from \"../type/utils\";\n\n/**\n * Events that {@link Camera} can trigger\n * @ko {@link Camera}가 트리거할 수 있는 이벤트들\n * @since 4.0.0\n */\nexport interface CameraEvents {\n /**\n * An event that fires when camera's animation stops\n * @ko 카메라 애니메이션이 멈췄을 때 트리거되는 이벤트\n * @eventName animationEnd\n * @eventOf Camera\n * @version 4.0.0\n */\n [CAMERA_EVENTS.ANIMATION_END]: {\n animation: CameraAnimation\n };\n}\n\n/**\n * Options for {@link Camera}\n * @ko {@link Camera}용 옵션들\n * @since 4.0.0\n */\nexport interface CameraOptions {\n /**\n * @copy View360#initialYaw\n */\n initialYaw: number;\n /**\n * @copy View360#initialPitch\n */\n initialPitch: number;\n /**\n * @copy View360#initialZoom\n */\n initialZoom: number;\n /**\n * @copy View360#yawRange\n */\n yawRange: Range | null;\n /**\n * @copy View360#pitchRange\n */\n pitchRange: Range | null;\n /**\n * @copy View360#zoomRange\n */\n zoomRange: Range | null;\n /**\n * @copy View360#fov\n */\n fov: number;\n}\n\n/**\n * Camera for View360\n * @ko View360용 카메라 구현체\n * @version 4.0.0\n */\nclass Camera extends Component {\n /**\n * Current yaw(y-axis rotation) value\n * @ko 현재 yaw(y축 회전) 값\n * @since 4.0.0\n */\n public yaw: number;\n /**\n * Current pitch(x-axis rotation) value\n * @ko 현재 pitch(x축 회전) 값\n * @since 4.0.0\n */\n public pitch: number;\n /**\n * Current zoom value\n * @ko 현재 줌 값\n * @since 4.0.0\n */\n public zoom: number;\n\n /**\n * @copy View360#initialYaw\n */\n public initialYaw: number;\n /**\n * @copy View360#initialPitch\n */\n public initialPitch: number;\n /**\n * @copy View360#initialPitch\n */\n public initialZoom: number;\n /**\n * @hidden\n * TODO: Please add comment for this when `rollOffset` is added\n */\n public rollOffset: number;\n\n /**\n * Current camera quaternion\n * @ko 현재 회전을 나타내는 quaternion 값\n * @since 4.0.0\n * @internal\n */\n public quaternion: quat;\n /**\n * Current camera position\n * @ko 현재 카메라 위치 좌표\n * @since 4.0.0\n * @internal\n */\n public position: vec3;\n /**\n * Active camera animation, `null` if there isn't.\n * @ko 현재 활성화된 카메라 애니메이션, 없을 경우 `null`값을 가집니다.\n * @since 4.0.0\n */\n public animation: CameraAnimation | null;\n /**\n * Camera's view matrix\n * @ko 카메라의 뷰 변환 행렬\n * @internal\n * @since 4.0.0\n */\n public viewMatrix: mat4;\n /**\n * Camera's projection matrix\n * @ko 카메라의 프로젝션 변환 행렬\n * @internal\n * @since 4.0.0\n */\n public projectionMatrix: mat4;\n\n /**\n * Camera's horizontal FOV(Field of View) value\n * @ko 카메라의 수평 FOV(Field of View) 값\n * @internal\n * @since 4.0.0\n */\n public fov: number;\n\n private _initialYawRange: Range | null;\n private _initialPitchRange: Range | null;\n private _initialZoomRange: Range | null;\n\n private _yawRange: Range | null;\n private _pitchRange: Range | null;\n private _zoomRange: Range | null;\n\n private _up: vec3;\n private _aspect: number;\n private _changed: boolean;\n private _maxRenderHeight: number;\n\n /**\n * Camera's width / height ratio\n * @ko 카메라의 가로 / 세로 비율\n * @readonly\n */\n public get aspect() { return this._aspect; }\n /**\n * Whether the camera's rotation changed from the last frame.\n * @ko 마지막 프레임 이후로 카메라의 회전값이 변경되었는지 나타내는 플래그.\n * @readonly\n */\n public get changed() { return this._changed; }\n /**\n * @copy View360#yawRange\n */\n public get yawRange() { return this._initialYawRange; }\n public set yawRange(val: Range | null) {\n this._initialYawRange = val;\n }\n /**\n * @copy View360#pitchRange\n */\n public get pitchRange() { return this._initialPitchRange; }\n public set pitchRange(val: Range | null) {\n this._initialPitchRange = val;\n }\n /**\n * @copy View360#zoomRange\n */\n public get zoomRange() { return this._initialZoomRange; }\n public set zoomRange(val: Range | null) {\n this._initialZoomRange = val;\n }\n\n /**\n * Create new instance of Camera\n * @param options - Camera options {@ko 카메라 옵션들}\n */\n public constructor({\n initialYaw,\n initialPitch,\n initialZoom,\n yawRange,\n pitchRange,\n zoomRange,\n fov\n }: CameraOptions) {\n super();\n\n this.yaw = initialYaw;\n this.pitch = initialPitch;\n this.zoom = initialZoom;\n this.rollOffset = 0;\n\n this.initialYaw = initialYaw;\n this.initialPitch = initialPitch;\n this.initialZoom = initialZoom;\n\n this.position = vec3.create();\n this.animation = null;\n\n this._up = vec3.fromValues(0, 1, 0);\n this._aspect = 1;\n\n this._initialYawRange = yawRange;\n this._initialPitchRange = pitchRange;\n this._initialZoomRange = zoomRange;\n\n this._yawRange = yawRange;\n this._pitchRange = pitchRange;\n this._zoomRange = zoomRange;\n\n this.quaternion = quat.create();\n this._updateQuaternion();\n\n this.viewMatrix = mat4.create();\n this.projectionMatrix = mat4.create();\n this.fov = fov;\n\n this._maxRenderHeight = -1;\n }\n\n /**\n * Destroy instance and detach all event listeners\n * @ko 인스턴스를 삭제하고 모든 이벤트 리스너를 삭제합니다.\n * @since 4.0.0\n */\n public destroy() {\n this.off();\n }\n\n /**\n * Refresh internal size value.\n * @ko 내부 크기값을 갱신합니다.\n * @param width - New width {@ko 변경된 너비값}\n * @param height - New height {@ko 변경된 높이값}\n * @since 4.0.0\n */\n public resize(width: number, height: number) {\n const prevAspect = this._aspect;\n\n this._aspect = width / height;\n\n if (this._aspect !== prevAspect) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation with euler values.\n * @ko 카메라 회전을 오일러 각 방향으로 변경합니다.\n * @param rotation - Rotation values {@ko 회전 값}\n * @param rotation.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값}\n * @param rotation.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값}\n * @param rotation.zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @since 4.0.0\n */\n public lookAt({\n yaw = this.yaw,\n pitch = this.pitch,\n zoom = this.zoom\n }: Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n }>) {\n const prevQuaternion = quat.clone(this.quaternion);\n const prevZoom = this.zoom;\n\n this.yaw = circulate(yaw, 0, 360);\n this.pitch = clamp(pitch, -90, 90);\n this.zoom = zoom;\n\n this._updateQuaternion();\n\n const zoomDiff = Math.abs(zoom - prevZoom);\n\n if (\n !quat.equals(this.quaternion, prevQuaternion)\n || zoomDiff >= EPSILON * 10 // ignore small changes\n ) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation with quaternion.\n * @ko 카메라 회전을 Quaternion을 이용해서 변경합니다.\n * @param rotation - Quaternion to apply {@ko 적용할 Quaternion}\n * @param zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @since 4.0.0\n */\n public rotate(rotation: quat, zoom: number = this.zoom) {\n const normalized = quat.normalize(quat.create(), rotation);\n const isSameRotation = quat.equals(this.quaternion, normalized);\n quat.copy(this.quaternion, normalized);\n\n const prevZoom = this.zoom;\n const { yaw, pitch } = quatToEuler(normalized);\n\n this.yaw = yaw;\n this.pitch = pitch;\n this.zoom = zoom;\n\n const zoomDiff = Math.abs(zoom - prevZoom);\n\n if (!isSameRotation || zoomDiff >= EPSILON * 10) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation to given euler values by the given duration.\n * @ko 카메라를 주어진 방향으로 주어진 시간동안 서서히 이동시킵니다.\n * @param options - Animation parameters {@ko 애니메이션 패러미터}\n * @param options.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값}\n * @param options.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값}\n * @param options.zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @param options.duration - Duration of the animation {@ko 애니메이션 시간}\n * @param options.easing - Easing function for the animation {@ko 애니메이션에 적용할 easing function}\n */\n public async animateTo({\n yaw = this.yaw,\n pitch = this.pitch,\n zoom = this.zoom,\n duration = 0,\n easing = DEFAULT_EASING\n }: Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n duration: number;\n easing: (x: number) => number;\n }> = {}): Promise {\n if (\n this.yaw === yaw\n && this.pitch === pitch\n && this.zoom === zoom\n ) return;\n\n const from = {\n rotation: quat.clone(this.quaternion),\n zoom: this.zoom\n };\n const to = {\n rotation: eulerToQuat(quat.create(), yaw, pitch, this.rollOffset),\n zoom\n };\n\n const animation = new CameraAnimation(this, from, to, {\n duration,\n easing\n });\n const finishPromise = animation.getFinishPromise();\n\n this.animation = animation;\n finishPromise.then(() => {\n this.animation = null;\n this.trigger(CAMERA_EVENTS.ANIMATION_END, { animation });\n });\n\n return finishPromise;\n }\n\n /**\n * @hidden\n */\n public restrictYawRange(min: number, max: number) {\n this._yawRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictPitchRange(min: number, max: number) {\n this._pitchRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictZoomRange(min: number, max: number) {\n this._zoomRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictRenderHeight(height: number) {\n this._maxRenderHeight = height;\n }\n\n /**\n * @hidden\n */\n public resetRange() {\n this._yawRange = this._initialYawRange;\n this._pitchRange = this._initialPitchRange;\n this._zoomRange = this._initialZoomRange;\n this._maxRenderHeight = -1;\n }\n\n /**\n * Get actual yaw range by the given zoom value.\n * @ko 주어진 zoom 값에 대한 실제 yaw 범위값을 반환합니다.\n * @since 4.0.0\n */\n public getYawRange(zoom: number) {\n const yawLimit = this._yawRange;\n const maxRenderHeight = this._maxRenderHeight;\n if (!yawLimit) return INFINITE_RANGE;\n\n const halfHFov = this.getHorizontalFov(zoom) * 0.5;\n let minYaw = yawLimit.min;\n let maxYaw = yawLimit.max;\n\n if (maxRenderHeight > 0) {\n const halfVFovRad = toVerticalFov(halfHFov * DEG_TO_RAD, this._aspect);\n const h = maxRenderHeight * 0.5;\n const t = Math.tan(halfVFovRad);\n const d = Math.sqrt((1 + h * h) / (1 + t * t));\n const theta = Math.atan(Math.tan(halfHFov * DEG_TO_RAD) * d) * RAD_TO_DEG;\n\n minYaw = yawLimit.min + theta;\n maxYaw = yawLimit.max - theta;\n }\n\n if (minYaw > maxYaw) {\n minYaw = 0;\n maxYaw = 0;\n }\n\n return {\n min: minYaw,\n max: maxYaw\n };\n }\n\n /**\n * Get actual pitch range by the given zoom value.\n * @ko 주어진 zoom 값에 대한 실제 pitch 범위값을 반환합니다.\n * @since 4.0.0\n */\n public getPitchRange(zoom: number) {\n const pitchLimit = this._pitchRange;\n const maxRenderHeight = this._maxRenderHeight;\n\n if (!pitchLimit) return DEFAULT_PITCH_RANGE;\n\n let minPitch = pitchLimit.min;\n let maxPitch = pitchLimit.max;\n\n if (maxRenderHeight > 0) {\n const halfVFov = this.getVerticalFov(zoom) * 0.5;\n\n minPitch = pitchLimit.min + halfVFov;\n maxPitch = pitchLimit.max - halfVFov;\n }\n\n if (minPitch > maxPitch) {\n minPitch = 0;\n maxPitch = 0;\n }\n\n return {\n min: Math.max(minPitch, -90),\n max: Math.min(maxPitch, 90)\n };\n }\n\n /**\n * Get actual zoom range in fov degrees.\n * @ko 실제 줌 범위를 fov각의 범위로 반환합니다.\n * @since 4.0.0\n */\n public getZoomRange() {\n const limit = this._zoomRange ?? DEFAULT_ZOOM_RANGE;\n\n // max (zoom in) -> minimum fov\n const minFov = this.getHorizontalFov(limit.max);\n const maxFov = this.getHorizontalFov(limit.min);\n const currentFov = this.getHorizontalFov(this.zoom);\n\n return {\n min: Math.max(minFov, 1),\n max: Math.min(maxFov, 180),\n current: currentFov\n };\n }\n\n /**\n * Return horizontal fov value when the given zoom is applied. (in degrees, °)\n * @ko 주어진 zoom 값이 적용되었을 때의 수평 fov값을 반환합니다. (도 단위, °)\n * @returns Zoomed horizontal FOV {@ko 줌이 적용된 수평 fov값}\n * @since 4.0.0\n */\n public getHorizontalFov(zoom = this.zoom) {\n return this._getZoomedHorizontalFov(zoom) * RAD_TO_DEG;\n }\n\n /**\n * Return vertical fov value when the given zoom is applied. (in degrees, °)\n * @ko 주어진 zoom 값이 적용되었을 때의 수직 fov값을 반환합니다. (도 단위, °)\n * @returns Zoomed vertical FOV {@ko 줌이 적용된 수직 fov값}\n * @since 4.0.0\n */\n public getVerticalFov(zoom = this.zoom) {\n const aspect = this._aspect;\n const hFov = this._getZoomedHorizontalFov(zoom); // In radians\n const vFov = toVerticalFov(hFov, aspect);\n\n return vFov * RAD_TO_DEG;\n }\n\n /**\n * Calculate zoom value for the given fov.\n * @ko 주어진 fov값을 zoom값으로 변환합니다.\n * @param fov horizontal fov (in degrees, °) {@ko 수평 fov 값 (도 단위, °)}\n * @since 4.0.0\n */\n public fovToZoom(fov: number) {\n const baseFov = this.fov;\n const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5);\n const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5);\n\n return renderingWidth / zoomedWidth;\n }\n\n /**\n * Update inner matrixes.\n * @ko 내부 행렬들을 업데이트합니다.\n * @internal\n * @since 4.0.0\n */\n public updateMatrix() {\n const up = this._up;\n const aspect = this._aspect;\n const viewMatrix = this.viewMatrix;\n const projMatrix = this.projectionMatrix;\n const position = this.position;\n const rotation = this.quaternion;\n\n const upDir = vec3.create();\n const viewDir = vec3.fromValues(0, 0, -1);\n vec3.transformQuat(viewDir, viewDir, rotation);\n vec3.transformQuat(upDir, up, rotation);\n\n const hFov = this._getZoomedHorizontalFov(); // In radians\n const vFov = toVerticalFov(hFov, aspect);\n\n mat4.lookAt(viewMatrix, position, viewDir, upDir);\n mat4.perspective(projMatrix, vFov, aspect, 0.1, 100);\n\n this._changed = true;\n }\n\n /**\n * @hidden\n */\n public onFrameRender() {\n this._changed = false;\n }\n\n private _updateQuaternion() {\n eulerToQuat(this.quaternion, this.yaw, this.pitch, this.rollOffset);\n }\n\n /**\n * @param zoom Current zoom value\n * @returns horizontal fov including zoom, in radian\n */\n private _getZoomedHorizontalFov(zoom = this.zoom) {\n return 2 * Math.atan(Math.tan(DEG_TO_RAD * this.fov * 0.5) / zoom);\n }\n}\n\nexport default Camera;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass MouseInput extends Component> {\n private _el: HTMLElement | null;\n private _prevPos: [number, number];\n\n public constructor() {\n super();\n\n this._el = null;\n this._prevPos = [0, 0];\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onMouseDown);\n\n this._el = element;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onMouseDown);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this._el = null;\n }\n\n private _onMouseDown = (evt: MouseEvent) => {\n const el = this._el;\n if (!el || evt.button !== BROWSER.MOUSE_BUTTON.LEFT) return;\n\n evt.preventDefault();\n\n if (el.focus) {\n el.focus();\n } else {\n window.focus();\n }\n\n this._prevPos[0] = evt.clientX;\n this._prevPos[1] = evt.clientY;\n\n window.addEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.addEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: false\n });\n }\n\n private _onMouseMove = (evt: MouseEvent) => {\n evt.preventDefault();\n\n const x = evt.clientX;\n const y = evt.clientY;\n const prevPos = this._prevPos;\n const deltaX = x - prevPos[0];\n const deltaY = y - prevPos[1];\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta: {\n x: deltaX,\n y: deltaY\n },\n isTouch: false,\n isKeyboard: false\n });\n\n prevPos[0] = x;\n prevPos[1] = y;\n }\n\n private _onMouseUp = () => {\n this._prevPos[0] = 0;\n this._prevPos[1] = 0;\n\n window.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: false,\n scrolling: false\n });\n }\n}\n\nexport default MouseInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\nimport { isFullscreen } from \"../../utils\";\n\nclass TouchInput extends Component> {\n private _el: HTMLElement | null;\n private _prevPos: [number, number];\n private _isFirstTouch: boolean;\n private _scrolling: boolean;\n private _scrollable: boolean;\n\n public get scrollable() { return this._scrollable; }\n public set scrollable(val: boolean) { this._scrollable = val; }\n\n public constructor() {\n super();\n\n this._el = null;\n this._prevPos = [0, 0];\n this._isFirstTouch = false;\n this._scrolling = false;\n this._scrollable = false;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.TOUCH_START, this._onTouchStart, { passive: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, { passive: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = element;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.TOUCH_START, this._onTouchStart);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = null;\n }\n\n private _onTouchStart = (evt: TouchEvent) => {\n if (evt.touches.length > 1 || this._scrolling) return;\n\n const touch = evt.touches[0];\n\n this._isFirstTouch = true;\n this._prevPos[0] = touch.clientX;\n this._prevPos[1] = touch.clientY;\n\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: true,\n isKeyboard: false\n });\n };\n\n private _onTouchMove = (evt: TouchEvent) => {\n // Only the one finger motion should be considered\n if (evt.touches.length > 1 || this._scrolling) return;\n\n const touch = evt.touches[0];\n const scrollable = this._scrollable;\n const prevPos = this._prevPos;\n\n const x = touch.clientX;\n const y = touch.clientY;\n const deltaX = x - prevPos[0];\n const deltaY = y - prevPos[1];\n\n if (this._isFirstTouch) {\n if (scrollable && !isFullscreen()) {\n if (Math.abs(deltaY) > Math.abs(deltaX)) {\n // Assume Scrolling\n this._scrolling = true;\n return;\n }\n }\n\n this._isFirstTouch = false;\n }\n\n if (evt.cancelable !== false) {\n evt.preventDefault();\n }\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta: {\n x: deltaX,\n y: deltaY\n },\n isTouch: true,\n isKeyboard: false\n });\n\n prevPos[0] = x;\n prevPos[1] = y;\n };\n\n private _onTouchEnd = (evt: TouchEvent) => {\n if (evt.touches.length !== 0) return;\n\n const touch = evt.touches[0];\n const prevPos = this._prevPos;\n\n if (touch) {\n prevPos[0] = touch.clientX;\n prevPos[1] = touch.clientY;\n } else {\n prevPos[0] = 0;\n prevPos[1] = 0;\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: true,\n isKeyboard: false,\n scrolling: this._scrolling\n });\n }\n\n if (evt.cancelable !== false) {\n evt.preventDefault();\n }\n\n this._scrolling = false;\n };\n}\n\nexport default TouchInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass KeyboardInput extends Component> {\n private _el: HTMLElement | null;\n private _pressed: {\n LEFT: boolean;\n UP: boolean;\n RIGHT: boolean;\n DOWN: boolean;\n };\n\n public get active() {\n const pressed = this._pressed;\n return pressed.LEFT || pressed.UP || pressed.RIGHT || pressed.DOWN;\n }\n\n public constructor() {\n super();\n\n this._el = null;\n this._clearPressedKeys();\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown);\n element.addEventListener(BROWSER.EVENTS.KEY_UP, this._onKeyUp);\n\n this._el = element;\n this._clearPressedKeys();\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown);\n element.removeEventListener(BROWSER.EVENTS.KEY_UP, this._onKeyUp);\n\n this._el = null;\n this._clearPressedKeys();\n }\n\n public update() {\n const delta = this._getDeltaByPressedKeys();\n\n if (delta.x !== 0 || delta.y !== 0) {\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: false,\n isKeyboard: true\n });\n }\n }\n\n private _clearPressedKeys() {\n this._pressed = BROWSER.KEY_DIRECTION.reduce((obj, keyName) => {\n return {\n ...obj,\n [keyName]: false\n };\n }, {} as KeyboardInput[\"_pressed\"]);\n }\n\n private _updateKeyPress(event: KeyboardEvent, isEnable: boolean): void {\n const pressed = this._pressed;\n const keyToUpdate = event.keyCode != null\n ? BROWSER.DIRECTION_KEY_CODE[event.keyCode]\n : BROWSER.DIRECTION_KEY_NAME[event.key];\n\n if (!keyToUpdate) return;\n\n pressed[keyToUpdate] = isEnable;\n }\n\n private _getPressedKeyCount() {\n return BROWSER.KEY_DIRECTION.filter(key => this._pressed[key]).length;\n }\n\n private _getDeltaByPressedKeys() {\n const pressed = this._pressed;\n let x = 0;\n let y = 0;\n\n if (pressed.LEFT) {\n x += 1;\n }\n\n if (pressed.RIGHT) {\n x -= 1;\n }\n\n if (pressed.UP) {\n y += 1;\n }\n\n if (pressed.DOWN) {\n y -= 1;\n }\n\n return {\n x, y\n };\n }\n\n private _onKeyDown = (evt: KeyboardEvent) => {\n // Ignore all other keypress except main arrow keys\n if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return;\n\n this._updateKeyPress(evt, true);\n\n const pressedCount = this._getPressedKeyCount();\n if (pressedCount <= 0) return;\n\n evt.preventDefault();\n if (pressedCount === 1 && !evt.repeat) {\n // On first keydown\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: true\n });\n }\n };\n\n private _onKeyUp = (evt: KeyboardEvent) => {\n // Ignore all other keypress except main arrow keys\n if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return;\n\n this._updateKeyPress(evt, false);\n\n const pressedCount = this._getPressedKeyCount();\n if (pressedCount > 0) return;\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: true,\n scrolling: false\n });\n };\n}\n\nexport default KeyboardInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport MouseInput from \"./input/MouseInput\";\nimport TouchInput from \"./input/TouchInput\";\nimport KeyboardInput from \"./input/KeyboardInput\";\nimport Camera from \"../core/Camera\";\nimport Motion from \"../core/Motion\";\nimport { CONTROL_EVENTS, INFINITE_RANGE, DEFAULT_PITCH_RANGE, DEFAULT_ANIMATION_DURATION, DEFAULT_EASING, DEG_TO_RAD, RAD_TO_DEG } from \"../const/internal\";\nimport { toVerticalFov } from \"../utils\";\nimport { ControlEvents, InputEvents } from \"../type/internal\";\n\n/**\n * Options for {@link RotateControl}\n * @ko {@link RotateControl}용 옵션들\n * @since 4.0.0\n */\nexport interface RotateControlOptions {\n /**\n * @copy RotateControl#pointerScale\n */\n pointerScale: [number, number];\n /**\n * @copy RotateControl#keyboardScale\n */\n keyboardScale: [number, number];\n /**\n * @copy RotateControl#duration\n */\n duration: number;\n /**\n * @copy RotateControl#easing\n */\n easing: (x: number) => number;\n /**\n * @copy RotateControl#disablePitch\n */\n disablePitch: boolean;\n /**\n * @copy RotateControl#disableYaw\n */\n disableYaw: boolean;\n /**\n * @copy RotateControl#disableKeyboard\n */\n disableKeyboard: boolean;\n}\n\ntype RotateDeltaType = { x: number; y: number; };\nexport type RotateControlEvents = ControlEvents;\n\n/**\n * Camera's rotation control\n * @ko 카메라의 회전을 담당하는 컨트롤\n * @since 4.0.0\n */\nclass RotateControl extends Component implements CameraControl {\n // Options\n private _pointerScale: RotateControlOptions[\"pointerScale\"];\n private _keyboardScale: RotateControlOptions[\"keyboardScale\"];\n private _duration: RotateControlOptions[\"duration\"];\n private _easing: RotateControlOptions[\"easing\"];\n private _disablePitch: RotateControlOptions[\"disablePitch\"];\n private _disableYaw: RotateControlOptions[\"disableYaw\"];\n private _disableKeyboard: RotateControlOptions[\"disableKeyboard\"];\n\n // Internal values\n private _controlEl: HTMLElement;\n private _enableBlocked: boolean;\n private _mouseInput: MouseInput;\n private _touchInput: TouchInput;\n private _keyboardInput: KeyboardInput;\n private _xMotion: Motion;\n private _yMotion: Motion;\n private _screenScale: [number, number];\n private _zoomScale: number;\n private _enabled: boolean;\n private _changedWhileDragging: boolean;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() {\n return this._keyboardInput.active\n || this._xMotion.activated\n || this._yMotion.activated;\n }\n /**\n * Current yaw value\n * @ko 현재 yaw 값\n * @readonly\n * @since 4.0.0\n */\n public get yaw() { return this._xMotion; }\n /**\n * Current pitch value\n * @ko 현재 pitch 값\n * @readonly\n * @since 4.0.0\n */\n public get pitch() { return this._yMotion; }\n /**\n * @copy View360#scrollable\n */\n public get scrollable() { return this._touchInput.scrollable; }\n public set scrollable(val: boolean) {\n this._touchInput.scrollable = val;\n }\n\n /**\n * Scale factor for mouse/touch rotation\n * @ko 마우스/터치를 통한 회전 배율\n * @default [1, 1]\n * @since 4.0.0\n */\n public get pointerScale() { return this._pointerScale; }\n public set pointerScale(val: RotateControlOptions[\"pointerScale\"]) {\n this._pointerScale = val;\n }\n\n /**\n * Scale factor for keyboard rotation\n * @ko 키보드를 통한 회전 배율\n * @default [1, 1]\n * @since 4.0.0\n */\n public get keyboardScale() { return this._keyboardScale; }\n public set keyboardScale(val: RotateControlOptions[\"keyboardScale\"]) {\n this._keyboardScale = val;\n }\n\n /**\n * Duration of the input animation (ms)\n * @ko 회전 애니메이션의 시간 (ms)\n * @default 300\n */\n public get duration() { return this._duration; }\n public set duration(val: RotateControlOptions[\"duration\"]) {\n this._duration = val;\n this._xMotion.duration = val;\n this._yMotion.duration = val;\n }\n\n /**\n * Easing function of the animation\n * @ko 회전 애니메이션에 적용할 easing 함수\n * @default EASING.EASE_OUT_CUBIC\n * @see EASING\n */\n public get easing() { return this._easing; }\n public set easing(val: RotateControlOptions[\"easing\"]) {\n this._easing = val;\n this._xMotion.easing = val;\n this._yMotion.easing = val;\n }\n\n /**\n * Disable X-axis(pitch) rotation.\n * @ko x축 회전(pitch)을 비활성화합니다.\n * @default false\n */\n public get disablePitch() { return this._disablePitch; }\n public set disablePitch(val: RotateControlOptions[\"disablePitch\"]) { this._disablePitch = val; }\n\n /**\n * Disable Y-axis(yaw) rotation.\n * @ko y축 회전(yaw)을 비활성화합니다.\n * @default false\n */\n public get disableYaw() { return this._disableYaw; }\n public set disableYaw(val: RotateControlOptions[\"disableYaw\"]) { this._disableYaw = val; }\n\n /**\n * Disable rotation by keyboard.\n * @ko 키보드를 이용한 회전을 비활성화합니다.\n * @default false\n */\n public get disableKeyboard() { return this._disableKeyboard; }\n public set disableKeyboard(val: RotateControlOptions[\"disableKeyboard\"]) { this._disableKeyboard = val; }\n\n /**\n * Create new RotateControl instance\n * @ko RotateControl의 인스턴스를 생성합니다.\n * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트}\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(controlEl: HTMLElement, enableBlocked: boolean, {\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING,\n pointerScale = [1, 1],\n keyboardScale = [1, 1],\n disablePitch = false,\n disableYaw = false,\n disableKeyboard = false\n }: Partial = {}) {\n super();\n\n this._controlEl = controlEl;\n this._pointerScale = pointerScale;\n this._keyboardScale = keyboardScale;\n this._duration = duration;\n this._easing = easing;\n this._disablePitch = disablePitch;\n this._disableYaw = disableYaw;\n this._disableKeyboard = disableKeyboard;\n\n this._enableBlocked = enableBlocked;\n this._mouseInput = new MouseInput();\n this._touchInput = new TouchInput();\n this._keyboardInput = new KeyboardInput();\n this._xMotion = new Motion({ duration, range: INFINITE_RANGE, easing });\n this._yMotion = new Motion({ duration, range: DEFAULT_PITCH_RANGE, easing });\n this._screenScale = [1, 1];\n this._zoomScale = 1;\n this._enabled = false;\n this._changedWhileDragging = false;\n this._bindInputs();\n }\n\n public destroy(): void {\n this.disable();\n this._mouseInput.off();\n this._touchInput.off();\n this._keyboardInput.off();\n this.off();\n this._changedWhileDragging = false;\n }\n\n /**\n * @hidden\n */\n public update(delta: number): void {\n if (!this._enabled) return;\n\n const xMotion = this._xMotion;\n const yMotion = this._yMotion;\n const keyboardInput = this._keyboardInput;\n\n if (!this._disableKeyboard) {\n keyboardInput.update();\n }\n\n if (!this._disablePitch) {\n yMotion.update(delta);\n }\n\n if (!this._disableYaw) {\n xMotion.update(delta);\n }\n }\n\n /**\n * @hidden\n */\n public updateRange(camera: Camera, zoom: number) {\n const yawRange = camera.getYawRange(zoom);\n const pitchRange = camera.getPitchRange(zoom);\n\n this._xMotion.setRange(yawRange.min, yawRange.max);\n this._yMotion.setRange(pitchRange.min, pitchRange.max);\n }\n\n /**\n * @hidden\n */\n public setZoomScale(val: number) {\n this._zoomScale = val;\n }\n\n /**\n * Resize control to match target size.\n * @ko 컨트롤의 내부 크기를 갱신합니다.\n * @param hfov - Camera horizontal fov in degrees {@ko 카메라의 수평방향 fov값 (도 단위)}\n * @param aspect - Camera aspect {@ko 카메라 가로/세로 비율}\n * @param width - New width {@ko 갱신된 너비}\n * @param height - New height {@ko 갱신된 높이}\n */\n public resize(hfov: number, aspect: number, width: number, height: number) {\n const vfov = toVerticalFov(hfov * DEG_TO_RAD, aspect) * RAD_TO_DEG;\n\n this._screenScale[0] = hfov / width;\n this._screenScale[1] = vfov / height;\n }\n\n public enable(): void {\n if (this._enabled) return;\n\n const element = this._controlEl;\n\n this._mouseInput.enable(element);\n this._touchInput.enable(element);\n this._keyboardInput.enable(element);\n\n this._enabled = true;\n this._enableBlocked = false;\n\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: true });\n }\n\n public disable(): void {\n if (!this._enabled) return;\n\n this._mouseInput.disable();\n this._touchInput.disable();\n this._keyboardInput.disable();\n\n this._enabled = false;\n\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: true });\n }\n\n public sync(camera: Camera): void {\n this.updateRange(camera, camera.zoom);\n\n this._xMotion.reset(camera.yaw);\n this._yMotion.reset(camera.pitch);\n }\n\n private _bindInputs() {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n const keyboardInput = this._keyboardInput;\n\n mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n touchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n touchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n keyboardInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n keyboardInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n keyboardInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n }\n\n private _onInputStart = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n this._changedWhileDragging = false;\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n ...evt,\n inputType: \"rotate\"\n });\n };\n\n private _onChange = (evt: InputEvents[typeof CONTROL_EVENTS.CHANGE]) => {\n const delta = evt.delta;\n const invZoomScale = 1 / this._zoomScale; // Reduce speed on zoom\n const screenScale = this._screenScale;\n const keyboardScale = this._keyboardScale;\n const pointerScale = this._pointerScale;\n\n let scale: [number, number];\n\n if (evt.isKeyboard) {\n scale = [\n keyboardScale[0] * invZoomScale,\n keyboardScale[1] * invZoomScale\n ];\n } else {\n scale = [\n pointerScale[0] * screenScale[0] * invZoomScale,\n pointerScale[1] * screenScale[1] * invZoomScale\n ];\n }\n\n const scaledX = delta.x * scale[0];\n const scaledY = delta.y * scale[1];\n\n this._xMotion.setNewEndByDelta(scaledX);\n this._yMotion.setNewEndByDelta(scaledY);\n\n this._changedWhileDragging = true;\n }\n\n private _onInputEnd = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n ...evt,\n inputType: \"rotate\"\n });\n\n if (!this._changedWhileDragging && !evt.isKeyboard && !evt.scrolling) {\n this.trigger(CONTROL_EVENTS.STATIC_CLICK, {\n isTouch: evt.isTouch\n });\n }\n\n this._changedWhileDragging = false;\n };\n}\n\nexport default RotateControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS, DEFAULT_ANIMATION_DURATION } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass WheelInput extends Component> {\n private _el: HTMLElement | null;\n private _scrollable: boolean;\n private _baseScale: number;\n private _inputTimer: number;\n\n public get scrollable() { return this._scrollable; }\n public set scrollable(val: boolean) { this._scrollable = val; }\n\n public constructor() {\n super();\n\n this._el = null;\n this._baseScale = 0.04;\n this._scrollable = false;\n this._inputTimer = -1;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.WHEEL, this._onWheel, { passive: false, capture: false });\n\n this._el = element;\n this._clearTimer();\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.WHEEL, this._onWheel, false);\n\n this._el = null;\n this._clearTimer();\n }\n\n private _onWheel = (evt: WheelEvent) => {\n const scrollable = this._scrollable;\n\n if (evt.deltaY === 0 || scrollable) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n\n if (this._inputTimer < 0) {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: false\n });\n } else {\n this._clearTimer();\n }\n\n const delta = this._baseScale * evt.deltaY;\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: false,\n isKeyboard: false\n });\n\n this._inputTimer = window.setTimeout(() => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: false,\n scrolling: false\n });\n this._inputTimer = -1;\n }, DEFAULT_ANIMATION_DURATION);\n };\n\n private _clearTimer() {\n window.clearTimeout(this._inputTimer);\n this._inputTimer = -1;\n }\n}\n\nexport default WheelInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass PinchInput extends Component> {\n private _el: HTMLElement | null;\n private _baseScale: number;\n private _prevDistance: number;\n private _isFirstTouch: boolean;\n\n public constructor() {\n super();\n\n this._el = null;\n this._baseScale = -0.2;\n this._prevDistance = -1;\n this._isFirstTouch = true;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, { passive: false, capture: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = element;\n this._prevDistance = -1;\n this._isFirstTouch = true;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, false);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = null;\n }\n\n private _onTouchMove = (evt: TouchEvent) => {\n const touches = evt.touches;\n if (touches.length !== 2) return;\n\n if (!evt.cancelable) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n\n const prevDistance = this._prevDistance;\n\n const diff = [\n touches[0].pageX - touches[1].pageX,\n touches[0].pageY - touches[1].pageY\n ];\n\n const distance = Math.sqrt(diff[0] * diff[0] + diff[1] * diff[1]) * this._baseScale;\n const delta = this._isFirstTouch\n ? 0\n : distance - prevDistance;\n\n if (this._isFirstTouch) {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: true,\n isKeyboard: false\n });\n }\n\n this._prevDistance = distance;\n this._isFirstTouch = false;\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: true,\n isKeyboard: false\n });\n };\n\n private _onTouchEnd = (evt: TouchEvent) => {\n if (evt.touches.length !== 0) return;\n\n if (!this._isFirstTouch) {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: true,\n isKeyboard: false,\n scrolling: false\n });\n }\n\n this._prevDistance = -1;\n this._isFirstTouch = true;\n };\n}\n\nexport default PinchInput;\n","/*\n* Copyright (c) 2023-present NAVER Corp.\n* egjs projects are licensed under the MIT license\n*/\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport WheelInput from \"./input/WheelInput\";\nimport PinchInput from \"./input/PinchInput\";\nimport Camera from \"../core/Camera\";\nimport Motion from \"../core/Motion\";\nimport {\n CONTROL_EVENTS,\n DEFAULT_ANIMATION_DURATION,\n DEFAULT_EASING,\n INFINITE_RANGE\n} from \"../const/internal\";\nimport { ControlEvents, InputEvents } from \"../type/internal\";\n\n/**\n * Options for {@link ZoomControl}\n * @ko {@link ZoomControl}용 옵션들\n * @since 4.0.0\n */\nexport interface ZoomControlOptions {\n /**\n * @copy ZoomControl#scale\n */\n scale: number;\n /**\n * @copy ZoomControl#duration\n */\n duration: number;\n /**\n * @copy ZoomControl#easing\n */\n easing: (x: number) => number;\n}\n\ntype ZoomControlEvents = ControlEvents;\n\n/**\n * Camera's zoom control\n * @ko 카메라의 줌 값을 담당하는 컨트롤\n * @since 4.0.0\n */\nclass ZoomControl extends Component implements CameraControl {\n // Options\n private _scale: ZoomControlOptions[\"scale\"];\n\n // Internal values\n private _controlEl: HTMLElement;\n private _enableBlocked: boolean;\n private _wheelInput: WheelInput;\n private _pinchInput: PinchInput;\n private _motion: Motion;\n private _enabled: boolean;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() { return this._motion.activated; }\n /**\n * Current zoom value\n * @ko 현재 줌 값\n * @since 4.0.0\n * @readonly\n */\n public get zoom() { return this._motion.val; }\n /**\n * @copy View360#wheelScrollable\n */\n public get scrollable() { return this._wheelInput.scrollable; }\n public set scrollable(val: boolean) {\n this._wheelInput.scrollable = val;\n }\n /**\n * @hidden\n */\n public get range() { return this._motion.range; }\n\n /**\n * Scale factor of the zoom\n * @ko 입력에 의한 줌 배율\n * @default 1\n * @since 4.0.0\n */\n public get scale() { return this._scale; }\n public set scale(val: ZoomControlOptions[\"scale\"]) { this._scale = val; }\n\n /**\n * Duration of the input animation (ms)\n * @ko 회전 애니메이션의 시간 (ms)\n * @default 300\n * @since 4.0.0\n */\n public get duration() { return this._motion.duration; }\n\n /**\n * Easing function of the animation\n * @ko 회전 애니메이션에 적용할 easing 함수\n * @default EASING.EASE_OUT_CUBIC\n * @see EASING\n * @since 4.0.0\n */\n public get easing() { return this._motion.easing; }\n\n /**\n * Create new ZoomControl instance\n * @ko ZoomControl의 인스턴스를 생성합니다.\n * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트}\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(controlEl: HTMLElement, enableBlocked: boolean, {\n scale = 1,\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING\n }: Partial = {}) {\n super();\n\n this._scale = scale;\n\n this._controlEl = controlEl;\n this._enableBlocked = enableBlocked;\n this._wheelInput = new WheelInput();\n this._pinchInput = new PinchInput();\n this._motion = new Motion({\n duration,\n easing,\n range: INFINITE_RANGE\n });\n this._enabled = false;\n\n this._bindInputs();\n }\n\n public destroy(): void {\n this.disable();\n this._wheelInput.off();\n this._pinchInput.off();\n this.off();\n }\n\n /**\n * @hidden\n */\n public update(delta: number): void {\n if (!this._enabled) return;\n\n const motion = this._motion;\n motion.update(delta);\n }\n\n public enable(): void {\n if (this._enabled) return;\n\n const element = this._controlEl;\n this._wheelInput.enable(element);\n this._pinchInput.enable(element);\n\n this._enabled = true;\n this._enableBlocked = false;\n\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: false });\n }\n\n public disable(): void {\n if (!this._enabled) return;\n\n this._wheelInput.disable();\n this._pinchInput.disable();\n\n this._enabled = false;\n\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: false });\n }\n\n public sync(camera: Camera): void {\n const motion = this._motion;\n const range = camera.getZoomRange();\n\n motion.setRange(range.min, range.max);\n motion.reset(range.current);\n }\n\n private _bindInputs() {\n const wheelInput = this._wheelInput;\n const pinchInput = this._pinchInput;\n\n wheelInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n wheelInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n wheelInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n pinchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n pinchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n pinchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n }\n\n private _onInputStart = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n ...evt,\n inputType: \"zoom\"\n });\n };\n\n private _onChange = ({ delta }: InputEvents[typeof CONTROL_EVENTS.CHANGE]) => {\n const scale = this._scale;\n const scaledDelta = delta * scale;\n\n this._motion.setNewEndByDelta(scaledDelta);\n };\n\n private _onInputEnd = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n ...evt,\n inputType: \"zoom\"\n });\n };\n}\n\nexport default ZoomControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { quat, vec3 } from \"gl-matrix\";\nimport * as BROWSER from \"../../const/browser\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\nimport { quatToEuler } from \"../../utils\";\n\nexport const ROTATE_CONSTANT = {\n PITCH_DELTA: 1,\n YAW_DELTA_BY_ROLL: 2,\n YAW_DELTA_BY_YAW: 3\n} as const;\n\nROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = {\n targetAxis: [0, 1, 0],\n meshPoint: [0, 0, 1]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = {\n targetAxis: [0, 1, 0],\n meshPoint: [1, 0, 0]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = {\n targetAxis: [1, 0, 0],\n meshPoint: [0, 0, 1]\n};\n\nclass GyroInput extends Component> {\n public quaternion: quat;\n\n private _ignoreRoll: boolean;\n\n private _yawOrigin: number;\n private _yawOffset: number;\n private _orientation: {\n alpha: number;\n beta: number;\n gamma: number;\n }\n private _orientationUpdated: boolean;\n private _needsCalibrate: boolean;\n private _screenOrientation: number;\n private _enabled: boolean;\n\n public get enabled() { return this._enabled; }\n public get orientationUpdated() { return this._orientationUpdated; }\n public get ignoreRoll() { return this._ignoreRoll; }\n public set ignoreRoll(val: boolean) { this._ignoreRoll = val; }\n\n public constructor() {\n super();\n\n this.quaternion = quat.create();\n\n this._orientation = {\n alpha: 0,\n beta: 90,\n gamma: 0\n };\n this._yawOrigin = 0;\n this._yawOffset = 0;\n this._orientationUpdated = false;\n this._screenOrientation = 0;\n this._needsCalibrate = true;\n this._enabled = false;\n }\n\n public enable() {\n if (this._enabled) return;\n\n window.addEventListener(BROWSER.EVENTS.DEVICE_ORIENTATION, this._onDeviceOrientation);\n window.addEventListener(BROWSER.EVENTS.ORIENTATION_CHANGE, this._updateScreenOrientation);\n\n this._updateScreenOrientation();\n this._orientationUpdated = false;\n this._needsCalibrate = true;\n this._enabled = true;\n }\n\n public disable() {\n if (!this._enabled) return;\n\n window.removeEventListener(BROWSER.EVENTS.DEVICE_ORIENTATION, this._onDeviceOrientation);\n window.removeEventListener(BROWSER.EVENTS.ORIENTATION_CHANGE, this._updateScreenOrientation);\n\n this._enabled = false;\n }\n\n public update() {\n this._updateRotation();\n this._orientationUpdated = false;\n }\n\n public collectDelta() {\n if (!this._orientationUpdated) {\n return {\n pitch: 0,\n yaw: 0\n };\n }\n\n const prevRotation = quat.clone(this.quaternion);\n\n this._updateRotation();\n this._orientationUpdated = false;\n\n return this._toEulerDelta(prevRotation, this.quaternion);\n }\n\n public setInitialRotation(yaw: number) {\n this._yawOrigin = yaw;\n }\n\n private _onDeviceOrientation = (evt: DeviceOrientationEvent) => {\n const prevOrientation = this._orientation;\n const { alpha, beta, gamma } = evt;\n\n if (\n alpha == null\n || beta == null\n || gamma == null\n ) return;\n\n prevOrientation.alpha = alpha;\n prevOrientation.beta = beta;\n prevOrientation.gamma = gamma;\n\n this._orientationUpdated = true;\n\n if (this._needsCalibrate) {\n this._needsCalibrate = false;\n this._calibrateSensor();\n }\n };\n\n private _calibrateSensor() {\n const yawOrigin = this._yawOrigin;\n const rotation = this.quaternion;\n\n this._yawOffset = 0;\n this._updateRotation();\n\n const { yaw: sensorYaw } = quatToEuler(rotation);\n this._yawOffset = sensorYaw - yawOrigin;\n this._updateRotation();\n\n this._needsCalibrate = false;\n }\n\n private _updateRotation() {\n const rotation = this.quaternion;\n const { alpha, beta, gamma } = this._orientation;\n\n quat.identity(rotation);\n quat.rotateY(rotation, rotation, (alpha - this._yawOffset) * DEG_TO_RAD);\n quat.rotateX(rotation, rotation, beta * DEG_TO_RAD);\n quat.rotateZ(rotation, rotation, -gamma * DEG_TO_RAD);\n\n const screen = quat.create();\n const screenAngle = -this._screenOrientation * 0.5 * DEG_TO_RAD;\n const world = quat.fromValues(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5));\n\n quat.set(screen, 0, Math.sin(screenAngle), 0, Math.cos(screenAngle));\n quat.multiply(rotation, rotation, screen);\n quat.multiply(rotation, rotation, world);\n\n quat.normalize(rotation, rotation);\n }\n\n private _updateScreenOrientation = () => {\n if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) {\n this._screenOrientation = screen.orientation.angle;\n } else if (window.orientation !== undefined) {\n this._screenOrientation = window.orientation >= 0 ?\n window.orientation : 360 + window.orientation;\n } else {\n this._screenOrientation = 0;\n }\n }\n\n private _toEulerDelta(prevQuat: quat, currentQuat: quat) {\n return {\n yaw: this._getDeltaYaw(prevQuat, currentQuat),\n pitch: this._getDeltaPitch(prevQuat, currentQuat),\n };\n }\n\n private _getDeltaYaw(prvQ: quat, curQ: quat): number {\n const yawDeltaByYaw = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW);\n const yawDeltaByRoll = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL)\n * Math.sin(this._extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n }\n\n private _getDeltaPitch(prvQ: quat, curQ: quat): number {\n return this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n }\n\n private _getRotationDelta(prevQ: quat, curQ: quat, rotateKind: typeof ROTATE_CONSTANT[keyof typeof ROTATE_CONSTANT]) {\n const targetAxis = vec3.fromValues(\n ROTATE_CONSTANT[rotateKind].targetAxis[0],\n ROTATE_CONSTANT[rotateKind].targetAxis[1],\n ROTATE_CONSTANT[rotateKind].targetAxis[2]\n );\n const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint;\n\n const prevQuaternion = quat.clone(prevQ);\n const curQuaternion = quat.clone(curQ);\n\n quat.normalize(prevQuaternion, prevQuaternion);\n quat.normalize(curQuaternion, curQuaternion);\n\n let prevPoint = vec3.fromValues(0, 0, 1);\n let curPoint = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n vec3.transformQuat(targetAxis, targetAxis, curQuaternion);\n\n const rotateDistance = vec3.dot(targetAxis, vec3.cross(vec3.create(), prevPoint, curPoint));\n const rotateDirection = rotateDistance > 0 ? 1 : -1;\n\n // when counter clock wise, use vec3.fromValues(0,1,0)\n // when clock wise, use vec3.fromValues(0,-1,0)\n // const meshPoint1 = vec3.fromValues(0, 0, 0);\n const meshPoint2 = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n\n let meshPoint3;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n meshPoint3 = vec3.fromValues(0, rotateDirection, 0);\n } else {\n meshPoint3 = vec3.fromValues(rotateDirection, 0, 0);\n }\n\n vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion);\n vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion);\n\n const vecU = meshPoint2;\n const vecV = meshPoint3;\n const vecN = vec3.create();\n\n vec3.cross(vecN, vecU, vecV);\n vec3.normalize(vecN, vecN);\n\n const coefficientA = vecN[0];\n const coefficientB = vecN[1];\n const coefficientC = vecN[2];\n\n // a point on the plane\n curPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n\n // a point should project on the plane\n prevPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n\n // distance between prevPoint and the plane\n let distance = Math.abs(\n prevPoint[0] * coefficientA +\n prevPoint[1] * coefficientB +\n prevPoint[2] * coefficientC\n );\n\n const projectedPrevPoint = vec3.create();\n\n vec3.subtract(projectedPrevPoint, prevPoint, vec3.scale(vec3.create(), vecN, distance));\n\n let trigonometricRatio =\n (projectedPrevPoint[0] * curPoint[0] +\n projectedPrevPoint[1] * curPoint[1] +\n projectedPrevPoint[2] * curPoint[2]) /\n (vec3.length(projectedPrevPoint) * vec3.length(curPoint));\n\n // defensive block\n if (trigonometricRatio > 1) {\n trigonometricRatio = 1;\n }\n\n const theta = Math.acos(trigonometricRatio);\n\n const crossVec = vec3.cross(vec3.create(), curPoint, projectedPrevPoint);\n\n distance = coefficientA * crossVec[0]\n + coefficientB * crossVec[1]\n + coefficientC * crossVec[2];\n\n let thetaDirection: number;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n thetaDirection = distance > 0 ? 1 : -1;\n } else {\n thetaDirection = distance < 0 ? 1 : -1;\n }\n\n const deltaRadian = theta * thetaDirection * rotateDirection;\n\n return deltaRadian * RAD_TO_DEG;\n }\n\n private _extractPitchFromQuat(quaternion: quat) {\n const baseV = vec3.fromValues(0, 0, 1);\n vec3.transformQuat(baseV, baseV, quaternion);\n\n return -1 * Math.atan2(\n baseV[1],\n Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2)));\n }\n}\n\nexport default GyroInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport GyroInput from \"./input/GyroInput\";\nimport Motion from \"../core/Motion\";\nimport Camera from \"../core/Camera\";\nimport * as BROWSER from \"../const/browser\";\nimport { CONTROL_EVENTS } from \"../const/internal\";\nimport { ControlEvents } from \"../type/internal\";\nimport { sensorCanBeEnabledIOS } from \"../utils\";\n\n/**\n * Options for {@link GyroControl}\n * @ko {@link GyroControl}용 옵션들\n * @since 4.0.0\n */\nexport interface GyroControlOptions {\n /**\n * @copy GyroControl#ignoreRoll\n */\n ignoreRoll: boolean;\n}\n\nexport type GyroControlEvents = ControlEvents;\n\n/**\n * Camera's rotation control by gyroscope\n * @ko 자이로스코프를 이용한 회전 컨트롤\n * @since 4.0.0\n */\nclass GyroControl extends Component implements CameraControl {\n // Options\n private _ignoreRoll: GyroControlOptions[\"ignoreRoll\"];\n\n // Internal values\n private _enableBlocked: boolean;\n private _input: GyroInput;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._input.enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() {\n return this._input.enabled && this._input.orientationUpdated;\n }\n\n /**\n * When `true`, ignore gyroscope's roll(z-axis rotation) value.\n * :::caution\n * Setting `false` will ignore camera's range limit.\n * Options like {@link View360Options#yawRange}, {@link View360Options#pitchRange} are ignored, and {@link CylinderProjection} also can't force it's camera range limit.\n * :::\n * @ko `true`일 경우 자이로스코프 입력의 roll(z축 회전)값을 무시합니다.\n * :::caution\n * 이 값을 `false`로 설정할 경우 카메라 범위 제약을 무시합니다.\n * {@link View360Options#yawRange}, {@link View360Options#pitchRange}와 같은 값은 무시되며, {@link CylinderProjection} 사용시에도 범위를 벗어날 수 있습니다.\n * :::\n * @default true\n * @since 4.0.0\n */\n public get ignoreRoll() { return this._ignoreRoll; }\n public set ignoreRoll(val: GyroControlOptions[\"ignoreRoll\"]) { this._ignoreRoll = val; }\n\n /**\n * Return availability of the gyroscope.\n * :::caution\n * This will always return false until user permission under environments like iOS which requires user permission when using gyroscope.\n * :::\n * @ko 자이로스코프 사용 가능 여부를 반환합니다.\n * :::caution\n * iOS와 같이 GyroScope 사용시 사용자 Permission을 요구하는 환경에서는 사용자 Permission을 받기 전까지 항상 `false`입니다.\n * :::\n * @example\n * ```ts\n * const gyroAvailable = await GyroControl.isAvailable();\n * ```\n */\n public static async isAvailable(): Promise {\n if (!DeviceMotionEvent) {\n return false;\n }\n\n let onDeviceMotionChange: (evt: DeviceMotionEvent) => void;\n\n const listenDeviceMotion = () => new Promise(res => {\n onDeviceMotionChange = (evt: DeviceMotionEvent) => {\n res(evt.rotationRate && evt.rotationRate.alpha != null);\n };\n\n window.addEventListener(BROWSER.EVENTS.DEVICE_MOTION, onDeviceMotionChange);\n });\n\n const timeout = () => new Promise(res => {\n setTimeout(() => res(false), 1000);\n });\n\n return Promise.race([listenDeviceMotion(), timeout()])\n .then((available: boolean) => {\n window.removeEventListener(BROWSER.EVENTS.DEVICE_MOTION, onDeviceMotionChange);\n\n return available;\n });\n }\n\n /**\n * Request user permission for gyroscope sensor.\n * This can be used in environments like iOS which requires user permission when using gyroscope sensors.\n * @ko 사용자의 sensor permission 취득을 요청합니다.\n * iOS와 같이 gyroscope 사용시 사용자 Permission을 요구하는 환경에서 사용 가능합니다.\n * @returns Whether the permission is granted {@ko 사용자 permission 취득 여부}\n */\n public static async requestSensorPermission(): Promise {\n // Request sensor permission, on iOS13+\n if (sensorCanBeEnabledIOS()) {\n return (DeviceMotionEvent as typeof DeviceMotionEvent & {\n requestPermission: () => Promise;\n }).requestPermission().then(permissionState => {\n return permissionState === \"granted\";\n }).catch(() => false);\n }\n\n return true;\n }\n\n /**\n * Create new GyroControl instance\n * @ko GyroControl의 인스턴스를 생성합니다.\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(enableBlocked: boolean, {\n ignoreRoll = true\n }: Partial = {}) {\n super();\n\n this._enableBlocked = enableBlocked;\n this._ignoreRoll = ignoreRoll;\n this._input = new GyroInput();\n }\n\n /**\n * @copy CameraControl#destroy\n */\n public destroy(): void {\n this.disable();\n this._input.off();\n this.off();\n }\n\n /**\n * @hidden\n */\n public update(camera: Camera, yaw: Motion, pitch: Motion, zoom: number) {\n if (!this._ignoreRoll) {\n this._updateQuaternion(camera, zoom);\n } else {\n this._updateYawPitch(camera, yaw, pitch, zoom);\n }\n }\n\n /**\n * @copy CameraControl#enable\n */\n public enable(): void {\n if (this._input.enabled) return;\n\n this._input.enable();\n this._enableBlocked = false;\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: false });\n }\n\n /**\n * @copy CameraControl#disable\n */\n public disable(): void {\n if (!this._input.enabled) return;\n\n this._input.disable();\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: false });\n }\n\n /**\n * @copy CameraControl#sync\n */\n public sync(): void {} // eslint-disable-line @typescript-eslint/no-empty-function\n\n private _updateYawPitch(camera: Camera, yaw: Motion, pitch: Motion, zoom: number) {\n const input = this._input;\n if (!input.enabled) return;\n\n const {\n yaw: yawDelta,\n pitch: pitchDelta\n } = input.collectDelta();\n\n yaw.add(yawDelta);\n pitch.add(pitchDelta);\n\n camera.lookAt({\n yaw: yaw.val,\n pitch: pitch.val,\n zoom\n });\n }\n\n private _updateQuaternion(camera: Camera, zoom: number) {\n const input = this._input;\n if (!input.enabled) return;\n\n input.update();\n camera.rotate(input.quaternion, zoom);\n }\n}\n\nexport default GyroControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport CameraControl from \"./CameraControl\";\nimport RotateControl, { RotateControlEvents, RotateControlOptions } from \"./RotateControl\";\nimport ZoomControl, { ZoomControlOptions } from \"./ZoomControl\";\nimport GyroControl, { GyroControlOptions } from \"./GyroControl\";\nimport Camera from \"../core/Camera\";\nimport CameraAnimation from \"../core/CameraAnimation\";\nimport * as BROWSER from \"../const/browser\";\nimport { CAMERA_EVENTS, CONTROL_EVENTS } from \"../const/internal\";\nimport { ValueOf } from \"../type/utils\";\nimport { getObjectOption, hfovToZoom } from \"../utils\";\n\n/**\n * Options for {@link PanoControl}\n * @ko {@link PanoControl}용 옵션들\n * @since 4.0.0\n */\nexport interface PanoControlOptions {\n /**\n * @copy View360#useGrabCursor\n */\n useGrabCursor: boolean;\n /**\n * @copy View360#scrollable\n */\n scrollable: boolean;\n /**\n * @copy View360#wheelScrollable\n */\n wheelScrollable: boolean;\n /**\n * @copy View360#disableContextMenu\n */\n disableContextMenu: boolean;\n /**\n * Options for {@link RotateControl}.\n * `false` to disable rotation.\n * @ko {@link RotateControl}용 옵션들.\n * `false`일 경우 회전이 비활성화됩니다.\n * @since 4.0.0\n */\n rotate: boolean | Partial;\n /**\n * Options for {@link ZoomControl}.\n * `false` to disable zoom.\n * @ko {@link ZoomControl}용 옵션들.\n * `false`일 경우 줌이 비활성화됩니다.\n * @since 4.0.0\n */\n zoom: boolean | Partial;\n /**\n * Options for {@link GyroControl}.\n * `false` to disable gyroscope control.\n * @ko {@link GyroControl}용 옵션들.\n * `false`일 경우 자이로스코프를 통한 컨트롤이 비활성화됩니다.\n * @since 4.0.0\n */\n gyro: boolean | Partial;\n}\n\n/**\n * Panorama control for View360\n * @ko View360용 파노라마 컨트롤\n * @since 4.0.0\n */\nclass PanoControl {\n // Options\n private _useGrabCursor: PanoControlOptions[\"useGrabCursor\"];\n private _disableContextMenu: PanoControlOptions[\"disableContextMenu\"];\n\n // Internal Values\n private _camera: Camera;\n private _controlEl: HTMLElement;\n private _rotateControl: RotateControl;\n private _zoomControl: ZoomControl;\n private _gyroControl: GyroControl;\n private _ignoreZoomScale: boolean;\n private _enabled: boolean;\n\n /**\n * @copy View360#useGrabCursor\n */\n public get useGrabCursor() { return this._useGrabCursor; }\n public set useGrabCursor(val: PanoControlOptions[\"useGrabCursor\"]) {\n if (val === this._useGrabCursor) return;\n\n this._useGrabCursor = val;\n\n if (val && this._enabled) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n } else if (!val) {\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n }\n\n /**\n * @copy View360#disableContextMenu\n */\n public get disableContextMenu() { return this._disableContextMenu; }\n public set disableContextMenu(val: PanoControlOptions[\"disableContextMenu\"]) {\n if (val === this._disableContextMenu) return;\n\n this._disableContextMenu = val;\n\n if (val && this._enabled) {\n this._blockContextMenu();\n } else if (!val) {\n this._restoreContextMenu();\n }\n }\n\n /**\n * @copy View360#disableContextMenu\n */\n public get scrollable() { return this._rotateControl.scrollable; }\n public set scrollable(val: PanoControlOptions[\"scrollable\"]) { this._rotateControl.scrollable = val; }\n /**\n * @copy View360#disableContextMenu\n */\n public get wheelScrollable() { return this._zoomControl.scrollable; }\n public set wheelScrollable(val: PanoControlOptions[\"wheelScrollable\"]) { this._zoomControl.scrollable = val; }\n /**\n * When `true`, disables rotation slow-down by zoom-value.\n * @ko `true`일 경우 줌 된 정도에 따라 회전속도를 늦추는 동작을 비활성화합니다.\n * @since 4.0.0\n */\n public get ignoreZoomScale() { return this._ignoreZoomScale; }\n public set ignoreZoomScale(val: boolean) { this._ignoreZoomScale = val; }\n\n /**\n * Whether the control is enabled or not\n * @ko 컨트롤 활성화 여부를 가리키는 값\n * @readonly\n * @since 4.0.0\n */\n public get enabled() { return this._enabled; }\n /**\n * @copy View360#rotate\n */\n public get rotate() { return this._rotateControl; }\n /**\n * @copy View360#zoom\n */\n public get zoom() { return this._zoomControl; }\n /**\n * @copy View360#gyro\n */\n public get gyro() { return this._gyroControl; }\n\n /**\n * Whether one of the controls is animating at the moment\n * @ko 현재 컨트롤 중 하나라도 동작중인지 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get animating() {\n return this._rotateControl.animating\n || this._zoomControl.animating\n || this._gyroControl.animating;\n }\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param element - Canvas element {@ko 캔버스 엘리먼트}\n * @param camera - Camera instance {@ko Camera 인스턴스}\n * @param options - Options for PanoControl {@ko PanoControl 옵션들}\n */\n public constructor(element: HTMLElement, camera: Camera, {\n useGrabCursor,\n scrollable,\n wheelScrollable,\n disableContextMenu,\n rotate,\n zoom,\n gyro\n }: PanoControlOptions) {\n // Bind Options\n this._useGrabCursor = useGrabCursor;\n this._disableContextMenu = disableContextMenu;\n\n // Set internal values\n this._camera = camera;\n this._controlEl = element;\n this._ignoreZoomScale = false;\n this._enabled = false;\n\n this._rotateControl = new RotateControl(element, !rotate, getObjectOption(rotate));\n this._zoomControl = new ZoomControl(element, !zoom, getObjectOption(zoom));\n this._gyroControl = new GyroControl(!gyro, getObjectOption(gyro));\n\n this._rotateControl.scrollable = scrollable;\n this._zoomControl.scrollable = wheelScrollable;\n\n this._bindEvents();\n }\n\n /**\n * Destroy the instance and remove all event listeners attached.\n * This also will reset CSS cursor to initial.\n * @ko 인스턴스를 삭제하고 부착된 모든 이벤트 리스너를 제거합니다.\n * 또한, 캔버스에 적용된 CSS cursor도 제거합니다.\n * @since 4.0.0\n */\n public destroy(): void {\n this.disable();\n this._rotateControl.destroy();\n this._zoomControl.destroy();\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n\n /**\n * Resize control to match target size.\n * @ko 컨트롤이 내부에 캐시하고 있는 크기값을 갱신합니다.\n * @param width New width {@ko 변경된 너비}\n * @param height New height {@ko 변경된 높이}\n * @since 4.0.0\n */\n public resize(width: number, height: number): void {\n const camera = this._camera;\n\n this._rotateControl.resize(camera.fov, camera.aspect, width, height);\n }\n\n /**\n * Enable this control and add event listeners.\n * @ko 컨트롤을 활성화하고 이벤트 리스너들을 추가합니다.\n * @since 4.0.0\n */\n public async enable(): Promise {\n if (this._enabled) return;\n\n if (!this._rotateControl.enableBlocked) {\n this._rotateControl.enable();\n }\n\n if (!this._zoomControl.enableBlocked) {\n this._zoomControl.enable();\n }\n\n if (!this._gyroControl.enableBlocked) {\n if (await GyroControl.isAvailable()) {\n this._gyroControl.enable();\n }\n }\n\n this.sync();\n\n if (this._disableContextMenu) {\n this._blockContextMenu();\n }\n\n this._enabled = true;\n }\n\n /**\n * Disable this control and remove all event listeners\n * @ko 컨트롤을 비활성화하고 모든 이벤트 리스너들을 제거합니다.\n * @since 4.0.0\n */\n public disable(): void {\n if (!this._enabled) return;\n\n this._rotateControl.disable();\n this._zoomControl.disable();\n this._gyroControl.disable();\n\n this._restoreContextMenu();\n\n this._enabled = false;\n }\n\n /**\n * Update control by given deltaTime\n * @ko 컨트롤을 주어진 시간만큼 업데이트합니다.\n * @param delta Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n * @internal\n */\n public update(delta: number): void {\n const camera = this._camera;\n const rotateControl = this._rotateControl;\n const zoomControl = this._zoomControl;\n const gyroControl = this._gyroControl;\n\n zoomControl.update(delta);\n const zoom = hfovToZoom(camera.fov, zoomControl.zoom);\n\n // Slow down rotation on zoom-in\n const zoomScale = this._ignoreZoomScale ? 1 : Math.max(zoom, 1);\n rotateControl.setZoomScale(zoomScale);\n rotateControl.updateRange(camera, zoom);\n rotateControl.update(delta);\n\n const yaw = rotateControl.yaw;\n const pitch = rotateControl.pitch;\n\n if (gyroControl.enabled) {\n gyroControl.update(camera, yaw, pitch, zoom);\n } else {\n camera.lookAt({\n yaw: yaw.val,\n pitch: pitch.val,\n zoom\n });\n }\n }\n\n /**\n * Synchronize this control's state to current camera state\n * @ko 컨트롤을 카메라의 현재 상태와 동기화합니다.\n * @since 4.0.0\n */\n public sync(): void {\n const camera = this._camera;\n\n this._zoomControl.sync(camera);\n this._rotateControl.sync(camera);\n }\n\n private _blockContextMenu() {\n const el = this._controlEl;\n\n el.addEventListener(BROWSER.EVENTS.CONTEXT_MENU, this._preventContextMenu);\n }\n\n private _restoreContextMenu() {\n const el = this._controlEl;\n\n el.removeEventListener(BROWSER.EVENTS.CONTEXT_MENU, this._preventContextMenu);\n }\n\n private _preventContextMenu = (evt: MouseEvent) => {\n evt.preventDefault();\n };\n\n private _setCursor(newCursor: ValueOf) {\n if (!this._useGrabCursor && newCursor !== BROWSER.CURSOR.NONE) return;\n\n const targetEl = this._controlEl;\n targetEl.style.cursor = newCursor;\n }\n\n private _bindEvents() {\n const rotateControl = this._rotateControl;\n const zoomControl = this._zoomControl;\n\n rotateControl.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n rotateControl.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n rotateControl.on(CONTROL_EVENTS.ENABLE, this._onEnable);\n rotateControl.on(CONTROL_EVENTS.DISABLE, this._onDisable);\n zoomControl.on(CONTROL_EVENTS.ENABLE, this._onEnable);\n zoomControl.on(CONTROL_EVENTS.DISABLE, this._onDisable);\n this._camera.on(CAMERA_EVENTS.ANIMATION_END, this._onCameraAnimationEnd);\n }\n\n private _onInputStart = (evt: RotateControlEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n if (this._useGrabCursor && !evt.isKeyboard) {\n this._setCursor(BROWSER.CURSOR.GRABBING);\n }\n };\n\n private _onInputEnd = (evt: RotateControlEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n if (this._useGrabCursor && !evt.isKeyboard) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n }\n };\n\n private _onEnable = ({\n control,\n updateCursor\n }: {\n control: CameraControl;\n updateCursor: boolean;\n }) => {\n if (updateCursor && this._useGrabCursor) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n }\n\n control.sync(this._camera);\n };\n\n private _onDisable = ({\n updateCursor\n }: {\n updateCursor: boolean\n }) => {\n if (updateCursor) {\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n };\n\n private _onCameraAnimationEnd = ({ animation }: { animation: CameraAnimation }) => {\n animation.getFinishPromise().then(() => {\n this.sync();\n });\n };\n}\n\nexport default PanoControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport TextureVideo from \"./TextureVideo\";\nimport TextureCube from \"./TextureCube\";\n\n/**\n * @hidden\n */\nabstract class Texture {\n public width: number;\n public height: number;\n public flipY: boolean;\n public wrapS: number;\n public wrapT: number;\n\n public constructor({\n width,\n height,\n flipY\n }: {\n width: number;\n height: number;\n flipY: boolean;\n }) {\n this.width = width;\n this.height = height;\n this.flipY = flipY;\n this.wrapS = WebGLRenderingContext.CLAMP_TO_EDGE;\n this.wrapT = WebGLRenderingContext.CLAMP_TO_EDGE;\n }\n\n public destroy() {\n // DO_NOTHING\n }\n\n public isVideo(): this is TextureVideo {\n return false;\n }\n\n public isCube(): this is TextureCube {\n return false;\n }\n}\n\nexport default Texture;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture from \"./Texture\";\n\n/**\n * @hidden\n */\nclass Texture2D extends Texture {\n public source: Exclude;\n\n public constructor({\n source,\n width,\n height,\n flipY\n }: {\n source: Exclude;\n width: number;\n height: number;\n flipY: boolean;\n }) {\n super({\n width,\n height,\n flipY\n });\n\n this.source = source;\n }\n}\n\nexport default Texture2D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"./Texture2D\";\n\n/**\n * @hidden\n */\nclass TextureVideo extends Texture2D {\n public source: HTMLVideoElement;\n\n public destroy() {\n const video = this.source;\n\n video.pause();\n video.removeAttribute(\"src\");\n video.load();\n }\n\n public isVideo(): this is TextureVideo { return true; }\n\n public isPaused() {\n const video = this.source;\n\n return video.paused || video.ended || video.readyState <= 2;\n }\n\n public hasAudio() {\n const video = this.source as any;\n\n if (video.audioTracks) {\n return video.audioTracks.length > 0;\n }\n\n if (video.webkitAudioDecodedByteCount != null) {\n return video.webkitAudioDecodedByteCount > 0;\n }\n\n if (video.mozHasAudio != null) {\n return video.mozHasAudio;\n }\n\n // We don't know whether the video has audio or not, return true\n return true;\n }\n}\n\nexport default TextureVideo;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture from \"./Texture\";\n\n/**\n * @hidden\n */\nclass TextureCube extends Texture {\n public sources: TexImageSource[];\n\n public constructor({\n sources,\n width,\n height,\n flipY\n }: {\n sources: TexImageSource[];\n width: number;\n height: number;\n flipY: boolean;\n }) {\n super({\n width,\n height,\n flipY\n });\n\n this.sources = sources;\n }\n\n public isCube(): this is TextureCube { return true; }\n}\n\nexport default TextureCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ImReady from \"@egjs/imready\";\nimport Texture from \"../texture/Texture\";\nimport Texture2D from \"../texture/Texture2D\";\nimport TextureVideo from \"../texture/TextureVideo\";\nimport TextureCube from \"../texture/TextureCube\";\nimport { getObjectOption, isString } from \"../utils\";\nimport { VideoConfig } from \"../type/external\";\nimport { ProjectionOptions } from \"../projection/Projection\";\n\n/**\n * @hidden\n */\nclass TextureLoader {\n private _loadChecker: ImReady;\n\n constructor() {\n this._loadChecker = new ImReady();\n }\n\n public async load(src: ProjectionOptions[\"src\"], video: ProjectionOptions[\"video\"]): Promise {\n if (video) {\n return this.loadVideo(src, getObjectOption(video));\n } else {\n if (Array.isArray(src) && src.length > 1) {\n return this.loadCubeImage(src);\n } else {\n const imgSrc = Array.isArray(src) ? src[0] : src;\n return this.loadImage(imgSrc);\n }\n }\n }\n\n public async loadImage(src: string | HTMLElement): Promise {\n const images = this._toImageArray(src);\n\n return this._load(images, resolve => {\n const image = images[0];\n\n resolve(new Texture2D({\n source: image,\n width: image.naturalWidth,\n height: image.naturalHeight,\n flipY: true\n }));\n });\n }\n\n public async loadCubeImage(src: Array): Promise {\n const images = this._toImageArray(src);\n\n return this._load(images, resolve => {\n resolve(new TextureCube({\n sources: images,\n width: images[0].naturalWidth,\n height: images[0].naturalHeight,\n flipY: false\n }));\n });\n }\n\n public async loadVideo(src: ProjectionOptions[\"src\"], videoConfig: Partial): Promise {\n const config: VideoConfig = {\n autoplay: true,\n muted: true,\n loop: false,\n volume: 1,\n ...videoConfig,\n };\n const video = this._toVideoElement(src, config);\n\n return this._load([video], resolve => {\n const { autoplay, muted } = config;\n\n video.currentTime = 0;\n if (autoplay && muted) {\n video.play().catch(() => void 0);\n }\n\n resolve(new TextureVideo({\n source: video,\n width: video.videoWidth,\n height: video.videoHeight,\n flipY: true\n }));\n });\n }\n\n private _load(content: HTMLElement[], onLoad: (resolve: (value: T) => void) => void): Promise {\n const loader = this._loadChecker;\n\n return new Promise((resolve, reject) => {\n loader.once(\"ready\", evt => {\n if (evt.errorCount > 0) return;\n\n onLoad(resolve);\n });\n\n loader.once(\"error\", reject);\n loader.check(content);\n });\n }\n\n private _toImageArray(src: ProjectionOptions[\"src\"]): HTMLImageElement[] {\n const srcs = Array.isArray(src) ? src : [src];\n\n return srcs.map(source => {\n if (isString(source)) {\n const imgEl = new Image();\n\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = source;\n\n return imgEl;\n } else {\n return source as HTMLImageElement;\n }\n });\n }\n\n private _toVideoElement(src: ProjectionOptions[\"src\"], {\n muted,\n loop,\n volume\n }: VideoConfig): HTMLVideoElement {\n if (src instanceof HTMLVideoElement) {\n return src;\n }\n\n const video = document.createElement(\"video\");\n\n video.crossOrigin = \"anonymous\";\n video.playsInline = true;\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.muted = muted;\n video.volume = volume;\n video.loop = loop;\n\n if (Array.isArray(src)) {\n src.forEach(source => this._appendSourceElement(video, source));\n } else {\n this._appendSourceElement(video, src);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0 && video.readyState < 1) {\n video.load();\n }\n\n return video;\n }\n\n private _appendSourceElement(video: HTMLMediaElement, src: string | HTMLElement) {\n if (src instanceof HTMLSourceElement) {\n return src;\n }\n\n const sourceEl = document.createElement(\"source\");\n sourceEl.src = src as string;\n video.appendChild(sourceEl);\n }\n}\n\nexport default TextureLoader;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * @internal\n */\nclass FrameAnimator {\n public maxDeltaTime: number;\n\n private _context: Window | XRSession;\n private _rafId: number;\n private _rafTimer: number;\n private _lastUpdateTime: number;\n\n /** */\n public constructor(maxDeltaTime: number, context: Window | XRSession = window) {\n this.maxDeltaTime = maxDeltaTime;\n\n this._context = context;\n this._rafId = -1;\n this._rafTimer = -1;\n this._lastUpdateTime = -1;\n }\n\n public start(callback: (delta: number, ...args: any[]) => any) {\n const context = this._context;\n\n // No context / callback set\n if (!context || !callback) return;\n\n // Animation already started\n if (this._rafId >= 0 || this._rafTimer >= 0) return;\n\n const loop = (_time: number, frame?: XRFrame) => {\n const time = Date.now();\n const delta = Math.min(time - this._lastUpdateTime, this.maxDeltaTime * 1000);\n\n callback(delta, frame);\n\n this._lastUpdateTime = time;\n this._rafId = context.requestAnimationFrame(loop);\n };\n\n this._lastUpdateTime = Date.now();\n this._rafId = context.requestAnimationFrame(loop);\n }\n\n public stop() {\n if (this._rafId >= 0) {\n this._context.cancelAnimationFrame(this._rafId);\n }\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n }\n\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n public changeContext(context: Window | XRSession) {\n this.stop();\n this._context = context;\n }\n}\n\nexport default FrameAnimator;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport * as BROWSER from \"../const/browser\";\n\n/**\n * Automatic resizer that uses both ResizeObserver and window resize event\n */\nclass AutoResizer {\n private _enabled: boolean;\n private _resizeObserver: ResizeObserver | null;\n private _useResizeObserver: boolean;\n private _onResize: () => any;\n\n public get useResizeObserver() { return this._useResizeObserver; }\n\n /**\n * Returns whether AutoResizer is enabled\n */\n public get enabled() { return this._enabled; }\n\n /** */\n public constructor(useResizeObserver: boolean, onResize: () => any) {\n this._useResizeObserver = useResizeObserver;\n\n this._enabled = false;\n this._resizeObserver = null;\n this._onResize = onResize;\n }\n\n /**\n * Enable resizer\n */\n public enable(element: HTMLElement): this {\n if (this._enabled) {\n this.disable();\n }\n\n if (this._useResizeObserver && !!window.ResizeObserver) {\n const bbox = element.getBoundingClientRect();\n const resizeImmediate = bbox.width !== 0 || bbox.height !== 0;\n\n const resizeObserver = new ResizeObserver(resizeImmediate ? this._skipFirstResize : this._onResize);\n\n resizeObserver.observe(element);\n\n this._resizeObserver = resizeObserver;\n } else {\n window.addEventListener(BROWSER.EVENTS.RESIZE, this._onResize);\n }\n\n this._enabled = true;\n\n return this;\n }\n\n /**\n * Disable resizer\n */\n public disable(): this {\n if (!this._enabled) return this;\n\n const resizeObserver = this._resizeObserver;\n if (resizeObserver) {\n resizeObserver.disconnect();\n this._resizeObserver = null;\n } else {\n window.removeEventListener(BROWSER.EVENTS.RESIZE, this._onResize);\n }\n\n this._enabled = false;\n\n return this;\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n private _skipFirstResize = (() => {\n let isFirstResize = true;\n\n return (() => {\n if (isFirstResize) {\n isFirstResize = false;\n\n return;\n }\n this._onResize();\n });\n })();\n}\n\nexport default AutoResizer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Camera from \"./Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport View360 from \"../View360\";\nimport * as BROWSER from \"../const/browser\";\nimport { CONTROL_EVENTS } from \"../const/internal\";\nimport { circulate, getObjectOption } from \"../utils\";\n\n/**\n * Options for {@link Autoplay}\n * @ko {@link Autoplay}용 옵션들\n * @since 4.0.0\n */\nexport interface AutoplayOptions {\n /**\n * @copy Autoplay#delay\n */\n delay: number;\n /**\n * @copy Autoplay#delayOnMouseLeave\n */\n delayOnMouseLeave: number;\n /**\n * @copy Autoplay#speed\n */\n speed: number;\n /**\n * @copy Autoplay#pauseOnHover\n */\n pauseOnHover: boolean;\n /**\n * @copy Autoplay#canInterrupt\n */\n canInterrupt: boolean;\n /**\n * @copy Autoplay#disableOnInterrupt\n */\n disableOnInterrupt: boolean;\n}\n\n/**\n * A manager class for autoplay feature.\n * @ko Autoplay 기능의 매니저 클래스.\n * @since 4.0.0\n */\nclass Autoplay {\n // Options\n private _delay: number;\n private _delayOnMouseLeave: number;\n private _speed: number;\n private _pauseOnHover: boolean;\n private _canInterrupt: boolean;\n private _disableOnInterrupt: boolean;\n\n // Internal values\n private _enableBlocked: boolean;\n private _camera: Camera;\n private _control: PanoControl;\n private _element: HTMLElement;\n private _enabled: boolean;\n private _interrupted: boolean;\n private _interruptionTimer: number;\n private _hovering: boolean;\n\n /**\n * Whether autoplay is enabled or not\n * @ko 자동재생 활성화 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * Whether autoplay is updating the camera at the moment\n * @ko 현재 자동재생이 동작중인지 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get playing() {\n return this._enabled && !this._interrupted;\n }\n\n /**\n * Reactivation delay after mouse input in milisecond.\n * @ko 재활성화되기까지의 시간 (밀리초 단위)\n * @default 2000\n * @since 4.0.0\n */\n public get delay() { return this._delay; }\n public set delay(val: number) { this._delay = val; }\n\n /**\n * Reactivation delay after mouse leave when using {@link AutoplayOptions#pauseOnHover}\n * @ko {@link AutoplayOptions#pauseOnHover} 사용시 마우스가 캔버스 영역을 떠난 뒤 자동재생이 다시 활성화되기까지의 시간\n * @default 0\n * @since 4.0.0\n */\n public get delayOnMouseLeave() { return this._delayOnMouseLeave; }\n public set delayOnMouseLeave(val: number) { this._delayOnMouseLeave = val; }\n\n /**\n * Y-axis(yaw) rotation speed\n * @ko Y-축 회전(yaw)의 속도\n * @default 1\n * @since 4.0.0\n */\n public get speed() { return this._speed; }\n public set speed(val: number) { this._speed = val; }\n\n /**\n * Whether to pause rotation on mouse hover\n * @ko 마우스가 캔버스 영역에 들어왔을 때 자동재생을 정지할지 여부\n * @default false\n * @since 4.0.0\n */\n public get pauseOnHover() { return this._pauseOnHover; }\n public set pauseOnHover(val: boolean) { this._pauseOnHover = val; }\n\n /**\n * Whether user can interrupt the rotation with click/wheel input\n * @ko 클릭이나 휠같은 사용자 인터랙션시 자동재생을 멈출지 여부\n * @default true\n * @since 4.0.0\n */\n public get canInterrupt() { return this._canInterrupt; }\n public set canInterrupt(val: boolean) { this._canInterrupt = val; }\n\n /**\n * Whether to disable autoplay on user interrupt\n * @ko 사용자 동작에 의해 자동재생이 정지할 때, {@link Autoplay#disable}을 호출하여 자동재생을 영구히 정지할지 여부\n * @default false\n * @since 4.0.0\n */\n public get disableOnInterrupt() { return this._disableOnInterrupt; }\n public set disableOnInterrupt(val: boolean) { this._disableOnInterrupt = val; }\n\n /**\n * Create new AutoPlayer instance\n * @param camera - Instance of the {@link Camera} {@ko Camera의 인스턴스}\n * @param element - Canvas element {@ko 캔버스 엘리먼트}\n * @param options - Autoplay options {@ko 자동재생 옵션들}\n * @since 4.0.0\n */\n public constructor(viewer: View360, element: HTMLElement, options: boolean | Partial) {\n this._camera = viewer.camera;\n this._control = viewer.control;\n this._element = element;\n\n this._enabled = false;\n this._interrupted = false;\n this._interruptionTimer = -1;\n this._hovering = false;\n\n const {\n delay = 2000,\n delayOnMouseLeave = 0,\n speed = 1,\n pauseOnHover = false,\n canInterrupt = true,\n disableOnInterrupt = false\n } = getObjectOption(options);\n\n this._enableBlocked = !options;\n this._delay = delay;\n this._delayOnMouseLeave = delayOnMouseLeave;\n this._speed = speed;\n this._pauseOnHover = pauseOnHover;\n this._canInterrupt = canInterrupt;\n this._disableOnInterrupt = disableOnInterrupt;\n }\n\n /**\n * Destroy the instance and remove all event listeners attached\n * @ko 인스턴스를 제거하고 연결된 모든 이벤트 핸들러를 삭제합니다.\n * @since 4.0.0\n */\n public destroy(): void {\n this.disable();\n }\n\n /**\n * Rotate camera by given deltaTime\n * @ko 주어진 deltaTime만큼 카메라를 회전시킵니다.\n * @param deltaTime - Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n */\n public update(deltaTime: number): void {\n if (!this._enabled) return;\n if (this._interrupted) {\n if (this._disableOnInterrupt) {\n this.disable();\n }\n\n return;\n }\n\n const camera = this._camera;\n const delta = -this._speed * deltaTime / 100;\n\n camera.yaw = circulate(camera.yaw + delta, 0, 360);\n }\n\n /**\n * Enable autoplay and add event listeners.\n * @ko 자동재생을 활성화하고 이벤트리스너들을 추가합니다.\n * @since 4.0.0\n */\n public enable(): void {\n const control = this._control;\n const element = this._element;\n\n if (this._enabled || control.gyro.enabled) return;\n\n control.rotate.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.rotate.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.zoom.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.zoom.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.gyro.on(CONTROL_EVENTS.ENABLE, this._onGyroEnable);\n\n element.addEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter, false);\n element.addEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave, false);\n\n this._enabled = true;\n this._enableBlocked = false;\n }\n\n /**\n * Enable autoplay after current `delay` value.\n * @ko 현재의 `delay`값만큼 시간이 지난 다음에 자동재생을 활성화합니다.\n * @since 4.0.0\n */\n public enableAfterDelay() {\n this.enable();\n this._interrupted = true;\n this._setUninterruptedAfterDelay(this._delay);\n }\n\n /**\n * Disable autoplay and remove all event handlers.\n * @ko 자동재생을 비활성화하고 모든 이벤트 핸들러를 제거합니다.\n * @since 4.0.0\n */\n public disable(): void {\n if (!this._enabled) return;\n\n const control = this._control;\n const element = this._element;\n\n control.rotate.off(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.rotate.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.zoom.off(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.zoom.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.gyro.off(CONTROL_EVENTS.ENABLE, this._onGyroEnable);\n\n element.removeEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter, false);\n element.removeEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave, false);\n\n this._enabled = false;\n this._interrupted = false;\n this._hovering = false;\n\n this._clearTimeout();\n }\n\n private _onInputStart = () => {\n if (!this._canInterrupt) return;\n\n this._interrupted = true;\n this._clearTimeout();\n };\n\n private _onInputEnd = () => {\n this._setUninterruptedAfterDelay(this._delay);\n };\n\n private _onGyroEnable = () => {\n this.disable();\n };\n\n private _onMouseEnter = () => {\n if (!this._pauseOnHover) return;\n this._interrupted = true;\n this._hovering = true;\n };\n\n private _onMouseLeave = () => {\n if (!this._pauseOnHover) return;\n this._hovering = false;\n this._setUninterruptedAfterDelay(this._delayOnMouseLeave);\n };\n\n private _setUninterruptedAfterDelay(delay: number): void {\n if (this._hovering) return;\n\n this._clearTimeout();\n\n if (delay > 0) {\n this._interruptionTimer = window.setTimeout(() => {\n this._interrupted = false;\n this._interruptionTimer = -1;\n }, delay);\n } else {\n this._interrupted = false;\n this._interruptionTimer = -1;\n }\n }\n\n private _clearTimeout(): void {\n if (this._interruptionTimer >= 0) {\n window.clearTimeout(this._interruptionTimer);\n this._interruptionTimer = -1;\n }\n }\n}\n\nexport default Autoplay;\n","import { mat4 } from \"gl-matrix\";\nimport Component from \"@egjs/component\";\nimport WebGLContext from \"./WebGLContext\";\nimport GyroControl from \"../control/GyroControl\";\nimport * as BROWSER from \"../const/browser\";\nimport { SESSION_VR, XR_REFERENCE_SPACE } from \"../const/internal\";\nimport { EVENTS } from \"../const/external\";\n\ninterface XRSessionOptions extends XRSessionInit {\n [key: string]: any;\n}\n\n/**\n * WebXR manager class\n * @ko WebXR 매니저 클래스\n * @since 4.0.0\n */\nclass XRManager extends Component<{\n /**\n * An event that fires on entering VR session\n * @ko VR 세션 진입시에 트리거되는 이벤트\n * @eventName vrStart\n * @eventOf XRManager\n * @version 4.0.0\n */\n [EVENTS.VR_START]: {\n session: XRSession;\n };\n /**\n * An event that fires on exiting VR session\n * @ko VR 세션에서 나갈 때 트리거되는 이벤트\n * @eventName vrEnd\n * @eventOf XRManager\n * @version 4.0.0\n */\n [EVENTS.VR_END]: void;\n}> {\n private _ctx: WebGLContext;\n private _xrSession: XRSession | null;\n private _xrRefSpace: XRReferenceSpace | null;\n private _options: XRSessionOptions;\n\n /**\n * Create new instance.\n * 새 인스턴스를 생성합니다.\n * @param ctx - Instance of WebGL context helper {@ko WebGL 콘텍스트 헬퍼의 인스턴스}\n * @param options - Options {@ko 옵션들}\n */\n public constructor(ctx: WebGLContext, options: XRSessionOptions = {}) {\n super();\n\n this._xrSession = null;\n this._xrRefSpace = null;\n this._ctx = ctx;\n this._options = options;\n }\n\n /**\n * Destroy instance and end XR session if there was any.\n * @ko 인스턴스를 제거하고, XR 세션이 존재할 경우 종료합니다.\n * @since 4.0.0\n */\n public destroy = () => {\n this.exit();\n this.off();\n };\n\n /**\n * Returns WebXR availability.\n * @ko WebXR 사용 가능 여부를 반환합니다.\n * @since 4.0.0\n */\n public async isAvailable(): Promise {\n // eslint-disable-next-line compat/compat\n const xr = window.navigator.xr;\n if (!xr) return false;\n\n return xr.isSessionSupported(SESSION_VR)\n .then(available => {\n return available;\n }).catch(() => {\n return false;\n });\n }\n\n /**\n * Enter VR session\n * @ko VR 세션에 진입합니다.\n * @since 4.0.0\n */\n public async enter() {\n const ctx = this._ctx;\n\n // eslint-disable-next-line compat/compat\n const xr = window.navigator.xr;\n if (!xr) return;\n\n await GyroControl.requestSensorPermission();\n\n const options = {\n ...{\n requiredFeatures: [XR_REFERENCE_SPACE]\n },\n ...this._options\n };\n\n await ctx.makeXRCompatible();\n\n const session = await xr.requestSession(SESSION_VR, options);\n ctx.bindXRLayer(session);\n\n const refSpace = await session.requestReferenceSpace(XR_REFERENCE_SPACE);\n\n this._setSession(session, refSpace);\n\n this.trigger(EVENTS.VR_START, {\n session\n });\n }\n\n /**\n * Exit VR session\n * @ko VR 세션에서 나갑니다.\n * @since 4.0.0\n */\n public exit() {\n const xrSession = this._xrSession;\n\n if (xrSession) {\n xrSession.end()\n .catch(() => void 0);\n }\n\n this._xrSession = null;\n this._xrRefSpace = null;\n }\n\n /**\n * @hidden\n */\n public canRender(frame: XRFrame) {\n const refSpace = this._xrRefSpace;\n\n if (!refSpace) return false;\n\n const pose = frame.getViewerPose(refSpace);\n\n return !!pose;\n }\n\n /**\n * @hidden\n */\n public getEyeParams(frame: XRFrame): Array<{\n viewport: XRViewport;\n vMatrix: mat4;\n pMatrix: mat4;\n }> | null {\n const session = frame.session;\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n if (!pose) return null;\n\n const glLayer = session.renderState.baseLayer;\n\n if (!glLayer) return null;\n\n return pose.views.map(view => {\n const viewport = glLayer.getViewport(view)!;\n const vMatrix = view.transform.inverse.matrix;\n\n return {\n viewport,\n vMatrix,\n pMatrix: view.projectionMatrix\n };\n });\n }\n\n private _setSession(session: XRSession, refSpace: XRReferenceSpace) {\n this._xrSession = session;\n this._xrRefSpace = refSpace;\n\n session.addEventListener(BROWSER.EVENTS.XR_END, this._onSessionEnd);\n }\n\n private _onSessionEnd = () => {\n this.exit();\n this.trigger(EVENTS.VR_END);\n }\n}\n\nexport default XRManager;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { vec3 } from \"gl-matrix\";\n\n/**\n * Hotspot data\n * @ko 핫스팟 데이터\n * @since 4.0.0\n */\nclass Hotspot {\n /**\n * HTMLElement of the hotspot\n * @ko 핫스팟의 HTMLElement\n * @since 4.0.0\n */\n public readonly element: HTMLElement;\n /**\n * Position to render hotspot\n * @ko 핫스팟을 렌더링할 위치\n * @since 4.0.0\n */\n public readonly position: vec3;\n\n public constructor(element: HTMLElement, position: vec3) {\n this.element = element;\n this.position = position;\n }\n}\n\nexport default Hotspot;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { vec2, vec3 } from \"gl-matrix\";\nimport Hotspot from \"./Hotspot\";\nimport Camera from \"../core/Camera\";\nimport WebGLRenderer from \"../core/WebGLRenderer\";\nimport View360Error from \"../core/View360Error\";\nimport { getNullableElement } from \"../utils\";\nimport ERROR from \"../const/error\";\nimport { DEFAULT_CLASS } from \"../const/external\";\nimport { DEG_TO_RAD } from \"../const/internal\";\n\n/**\n * Options for {@link HotspotRenderer}\n * @ko {@link HotspotRenderer}용 옵션들\n * @since 4.0.0\n */\nexport interface HotspotOptions {\n /**\n * Apply scale for hotspots, makes their size sync with background panorama image.\n * @ko 핫스팟에 스케일을 적용해서 배경 파노라마 이미지의 크기 변화와 동일하게 크기를 조절합니다.\n * @since 4.0.0\n */\n zoom: boolean;\n}\n\n/**\n * Hotspot renderer\n * @ko Hotspot 렌더러\n * @since 4.0.0\n */\nclass HotspotRenderer {\n // Options\n private _zoom: HotspotOptions[\"zoom\"];\n\n // Internal properties\n private _containerEl: HTMLElement | null;\n private _renderer: WebGLRenderer;\n private _hotspots: Hotspot[];\n\n /**\n * Create new instance\n * @ko 새 인스턴스를 생성합니다.\n * @param rootEl - Container element for hotspots {@ko 핫스팟들의 컨테이너 엘리먼트}\n * @param renderer - instance of WebGLRenderer {@ko WebGLRenderer의 인스턴스}\n * @param options - Hotspot options {@ko Hotspot 옵션들 }\n */\n public constructor(rootEl: HTMLElement, renderer: WebGLRenderer, {\n zoom = false\n }: Partial) {\n this._containerEl = getNullableElement(`.${DEFAULT_CLASS.HOTSPOT_CONTAINER}`, rootEl);\n this._renderer = renderer;\n this._hotspots = [];\n\n this._zoom = zoom;\n }\n\n /**\n * Refresh hotspots by collecting hotspot elements from current hotspot root element\n * @ko 현재 핫스팟 루트 엘리먼트 내에서 핫스팟 엘리먼트들을 수집하여 갱신합니다.\n * @throws {ERROR_CODES.INSUFFICIENT_ARGS} if data-position doesn't include all x, y, z values {@ko data-position이 x, y, z좌표를 전부 포함하고 있지 않을 때}\n */\n public refresh() {\n const container = this._containerEl;\n if (!container) return;\n\n const hotspotEls = [].slice.apply(container.querySelectorAll(`.${DEFAULT_CLASS.HOTSPOT}`)) as HTMLElement[];\n this._hotspots = hotspotEls.map(el => this._parseHotspot(el));\n }\n\n /**\n * Render hotspots\n * @ko 핫스팟들을 렌더링합니다.\n * @param camera - Instance of Camera {@ko Camera의 인스턴스}\n */\n public render(camera: Camera) {\n const hotspots = this._hotspots;\n const halfWidth = this._renderer.width * 0.5;\n const halfHeight = this._renderer.height * 0.5;\n const zoom = camera.zoom;\n const centerTransform = \"translate(-50%, -50%)\";\n const zoomTransform = this._zoom ? `scale(${zoom})` : \"\";\n\n hotspots.forEach(hotspot => {\n const position = hotspot.position;\n const relPos = vec3.create();\n\n vec3.copy(relPos, position);\n vec3.transformMat4(relPos, relPos, camera.viewMatrix);\n vec3.transformMat4(relPos, relPos, camera.projectionMatrix);\n\n if (relPos[2] > 1 || relPos[2] < 0) {\n hotspot.element.classList.remove(DEFAULT_CLASS.HOTSPOT_VISIBLE);\n return;\n }\n\n const screenPos = vec2.fromValues(\n relPos[0] * halfWidth + halfWidth,\n -relPos[1] * halfHeight + halfHeight\n );\n\n hotspot.element.classList.add(DEFAULT_CLASS.HOTSPOT_VISIBLE);\n hotspot.element.style.transform = [\n centerTransform,\n `translate(${screenPos[0]}px, ${screenPos[1]}px)`,\n zoomTransform\n ].join(\" \");\n });\n }\n\n private _parseHotspot(element: HTMLElement): Hotspot {\n const yawStr = element.dataset.yaw;\n const pitchStr = element.dataset.pitch;\n const positionStr = element.dataset.position;\n\n if (yawStr || pitchStr) {\n const yaw = yawStr ? parseFloat(yawStr) : 0;\n const pitch = pitchStr ? parseFloat(pitchStr) : 0;\n\n const position = this._yawPitchToVec3(yaw, pitch);\n\n return new Hotspot(element, position);\n } else if (positionStr) {\n const pos: number[] = positionStr.split(\" \").map(val => parseFloat(val));\n if (pos.length < 3) {\n throw new View360Error(ERROR.MESSAGES.INSUFFICIENT_ARGS(positionStr, \"hotspot attribute \\\"data-position\\\"\"), ERROR.CODES.INSUFFICIENT_ARGS);\n }\n\n return new Hotspot(element, vec3.fromValues(pos[0], pos[1], pos[2]));\n } else {\n // Place hotspot at yaw: 0, pitch: 0\n const defaultPos = vec3.fromValues(0, 0, -1);\n\n return new Hotspot(element, defaultPos);\n }\n }\n\n private _yawPitchToVec3(yaw: number, pitch: number) {\n const yawRad = yaw * DEG_TO_RAD;\n const pitchRad = pitch * DEG_TO_RAD;\n const position = vec3.create();\n\n position[1] = Math.sin(pitchRad);\n position[2] = Math.cos(pitchRad);\n\n position[0] = position[2] * Math.sin(-yawRad);\n position[2] = -position[2] * Math.cos(-yawRad);\n\n return position;\n }\n}\n\nexport default HotspotRenderer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"../geometry/Geometry\";\nimport { VAO } from \"../type/internal\";\n\n/**\n * @hidden\n */\nclass VertexArrayObject {\n public readonly obj: VAO | null;\n public readonly geometry: Geometry;\n public readonly buffers: {\n indicies: WebGLBuffer;\n position: WebGLBuffer;\n uv: WebGLBuffer;\n }\n\n public get count() { return this.geometry.indicies.count; }\n\n constructor(obj: VAO | null, geometry: Geometry, buffers: VertexArrayObject[\"buffers\"]) {\n this.obj = obj;\n this.geometry = geometry;\n this.buffers = buffers;\n }\n}\n\nexport default VertexArrayObject;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4 } from \"gl-matrix\";\nimport Uniform from \"../uniform/Uniform\";\nimport Camera from \"./Camera\";\nimport Object3D from \"./Object3D\";\nimport ShaderProgram from \"./ShaderProgram\";\nimport View360Error from \"./View360Error\";\nimport VertexArrayObject from \"./VertexArrayObject\";\nimport VertexData from \"./VertexData\";\nimport Texture from \"../texture/Texture\";\nimport Geometry from \"../geometry/Geometry\";\nimport * as BROWSER from \"../const/browser\";\nimport ERROR from \"../const/error\";\nimport { DEFAULT_CLASS } from \"../const/external\";\nimport { UniformLocations } from \"../type/internal\";\n\n/**\n * @hidden\n */\nclass WebGLContext {\n private _canvas: HTMLCanvasElement;\n private _gl: WebGLRenderingContext | WebGL2RenderingContext;\n private _contextLost: boolean;\n private _maxTextureSize: number;\n private _isWebGL2: boolean;\n private _debug: boolean;\n private _extensions: {\n vao: OES_vertex_array_object | null;\n loseContext: WEBGL_lose_context | null;\n };\n\n public get canvas() { return this._canvas; }\n public get maxTextureSize() { return this._maxTextureSize; }\n public get isWebGL2() { return this._isWebGL2; }\n public get supportVAO() { return this._isWebGL2 || !!this._extensions.vao; }\n public get lost() { return this._contextLost; }\n public get debug() { return this._debug; }\n\n public constructor(canvas: HTMLCanvasElement, debug: boolean) {\n this._canvas = canvas;\n this._contextLost = false;\n this._debug = debug;\n this._extensions = {\n vao: null,\n loseContext: null\n };\n }\n\n public init() {\n const canvas = this._canvas;\n\n const { gl, isWebGL2 } = this._getContext(canvas);\n\n this._gl = gl;\n this._maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n this._isWebGL2 = isWebGL2;\n\n if (!this._isWebGL2) {\n this._extensions.vao = gl.getExtension(\"OES_vertex_array_object\");\n }\n\n this._extensions.loseContext = gl.getExtension(\"WEBGL_lose_context\");\n\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_LOST, this._onContextLost);\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_RESTORED, this._onContextRestore);\n\n // gl.enable(gl.DEPTH_TEST);\n }\n\n public destroy() {\n const gl = this._gl;\n const canvas = this._canvas;\n\n if (gl) {\n // gl is not defined when destroy is called before init\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n }\n\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_LOST, this._onContextLost);\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_RESTORED, this._onContextRestore);\n }\n\n public forceLoseContext() {\n const extension = this._extensions.loseContext;\n\n if (!extension) return;\n\n extension.loseContext();\n }\n\n public forceRestoreContext() {\n const extension = this._extensions.loseContext;\n\n if (!extension) return;\n\n extension.restoreContext();\n }\n\n public clear() {\n const gl = this._gl;\n\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n\n public resize() {\n const gl = this._gl;\n\n gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n }\n\n public viewport(x: number, y: number, width: number, height: number) {\n const gl = this._gl;\n\n gl.viewport(x, y, width, height);\n }\n\n public createVAO(geometry: Geometry, shaderProgram: ShaderProgram) {\n const nativeVAO = this._createNativeVAO();\n\n const vao = new VertexArrayObject(nativeVAO, geometry, {\n indicies: this._createBuffer(),\n position: this._createBuffer(),\n uv: this._createBuffer()\n });\n\n if (nativeVAO) {\n this._bindNativeVAO(nativeVAO);\n this._supplyGeometryData(vao, shaderProgram);\n this._bindNativeVAO(null);\n this._unbindBuffers();\n }\n\n return vao;\n }\n\n public draw(vao: VertexArrayObject, shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n if (vao.obj) {\n this._bindNativeVAO(vao.obj);\n } else {\n this._supplyGeometryData(vao, shaderProgram);\n }\n\n gl.drawElements(gl.TRIANGLES, vao.count, gl.UNSIGNED_SHORT, 0);\n\n if (vao.obj) {\n this._bindNativeVAO(null);\n } else {\n this._unbindBuffers();\n }\n }\n\n public releaseVAO(vao: VertexArrayObject) {\n if (vao.obj) {\n this._deleteNativeVAO(vao.obj);\n }\n\n this._deleteBuffer(vao.buffers.indicies);\n this._deleteBuffer(vao.buffers.position);\n this._deleteBuffer(vao.buffers.uv);\n }\n\n public getUniformLocations>(program: WebGLProgram, uniforms: T): UniformLocations {\n const gl = this._gl;\n\n const uniformLocations = Object.keys(uniforms).reduce((locations, key) => {\n locations[key as keyof T] = gl.getUniformLocation(program, key)!;\n\n return locations;\n }, {} as UniformLocations);\n\n return {\n ...this._getCommonUniformLocations(program),\n ...uniformLocations\n };\n }\n\n public updateCommonUniforms(entity: Object3D, camera: Camera, shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniformLocations = shaderProgram.uniformLocations;\n\n // We're using \"matrix\"(=local matrix) here for efficiency\n // As projection doesn't require world matrix, as it doesn't have any parent or child\n const matrix = entity.matrix;\n const mvMatrix = mat4.create();\n mat4.multiply(mvMatrix, camera.viewMatrix, matrix);\n\n gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix);\n gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, camera.projectionMatrix);\n }\n\n public updateVRUniforms(shaderProgram: ShaderProgram, mvMatrix: mat4, pMatrix: mat4, eyeIndex: number) {\n const gl = this._gl;\n\n const uniformLocations = shaderProgram.uniformLocations;\n\n gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix);\n gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, pMatrix);\n\n if (uniformLocations.uEye) {\n gl.uniform1f(uniformLocations.uEye, eyeIndex);\n }\n }\n\n public updateUniforms(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniforms = shaderProgram.uniforms;\n const uniformLocations = shaderProgram.uniformLocations;\n\n for (const key in uniforms) {\n const uniform = uniforms[key];\n const location = uniformLocations[key];\n\n if (!uniform) continue;\n\n if (uniform.needsUpdate) {\n uniform.update(gl, location, this._isWebGL2);\n }\n }\n }\n\n public releaseShaderResources(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniforms = shaderProgram.uniforms;\n\n for (const key in uniforms) {\n const uniform = uniforms[key];\n\n if (!uniform) continue;\n\n if (uniform.needsUpdate) {\n uniform.destroy(gl);\n }\n }\n\n gl.deleteProgram(shaderProgram.program);\n }\n\n public useProgram(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n gl.useProgram(shaderProgram.program);\n }\n\n public createProgram(vertexShader: string, fragmentShader: string) {\n const gl = this._gl;\n const program = gl.createProgram()!;\n\n const vs = this._compileShader(gl.VERTEX_SHADER, vertexShader);\n const fs = this._compileShader(gl.FRAGMENT_SHADER, fragmentShader);\n\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.bindAttribLocation(program, 0, \"position\");\n gl.bindAttribLocation(program, 1, \"uv\");\n gl.linkProgram(program);\n\n if (this._debug && !gl.getProgramParameter(program, gl.LINK_STATUS)) {\n let shaderLog: string | null = null;\n\n if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {\n shaderLog = gl.getShaderInfoLog(vs);\n } else if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {\n shaderLog = gl.getShaderInfoLog(fs);\n }\n\n throw new View360Error(ERROR.MESSAGES.FAILED_LINKING_PROGRAM(gl.getProgramInfoLog(program), shaderLog), ERROR.CODES.FAILED_LINKING_PROGRAM);\n }\n\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n\n return program;\n }\n\n public createWebGLTexture(texData: Texture): WebGLTexture {\n const gl = this._gl;\n const texture = gl.createTexture()!;\n\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texData.wrapS);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texData.wrapT);\n\n if (!texData.isVideo() && this._isWebGL2) {\n const gl2 = gl as WebGL2RenderingContext;\n\n gl2.texStorage2D(gl2.TEXTURE_2D, 1, gl2.RGBA8, texData.width, texData.height);\n }\n\n return texture;\n }\n\n public createWebGLCubeTexture(texData: Texture, size: number): WebGLTexture {\n const gl = this._gl;\n const texture = gl.createTexture()!;\n\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, texData.wrapS);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, texData.wrapT);\n\n if (this._isWebGL2) {\n const gl2 = gl as WebGL2RenderingContext;\n\n gl2.texStorage2D(gl2.TEXTURE_CUBE_MAP, 1, gl2.RGBA8, size, size);\n }\n\n return texture;\n }\n\n public async makeXRCompatible() {\n const gl = this._gl;\n const attributes = gl.getContextAttributes();\n\n if (attributes && attributes.xrCompatible !== true) {\n await gl.makeXRCompatible();\n }\n }\n\n public bindXRLayer(session: XRSession) {\n const gl = this._gl;\n const xrLayer = new XRWebGLLayer(session, gl);\n session.updateRenderState({ baseLayer: xrLayer });\n }\n\n public bindXRFrame(frame: XRFrame) {\n const gl = this._gl;\n const session = frame.session;\n const baseLayer = session.renderState.baseLayer!;\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer);\n }\n\n public useDefaultFrameBuffer() {\n const gl = this._gl;\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n private _createBuffer(): WebGLBuffer {\n return this._gl.createBuffer()!;\n }\n\n private _deleteBuffer(buffer: WebGLBuffer) {\n return this._gl.deleteBuffer(buffer);\n }\n\n private _createNativeVAO() {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n return (gl as WebGL2RenderingContext).createVertexArray()!;\n } else {\n const ext = this._extensions.vao;\n\n return ext?.createVertexArrayOES() || null;\n }\n }\n\n private _bindNativeVAO(vao: WebGLVertexArrayObject | null) {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n (gl as WebGL2RenderingContext).bindVertexArray(vao);\n } else {\n const ext = this._extensions.vao;\n\n ext?.bindVertexArrayOES(vao);\n }\n }\n\n private _deleteNativeVAO(vao: WebGLVertexArrayObject | null) {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n (gl as WebGL2RenderingContext).deleteVertexArray(vao);\n } else {\n const ext = this._extensions.vao;\n\n ext?.deleteVertexArrayOES(vao);\n }\n }\n\n private _supplyGeometryData(vao: VertexArrayObject, shaderProgram: ShaderProgram) {\n const geometry = vao.geometry;\n\n this._supplyIndiciesData(geometry.indicies, vao.buffers.indicies);\n this._supplyAttributeData(geometry.vertices, shaderProgram.program, \"position\", vao.buffers.position);\n this._supplyAttributeData(geometry.uvs, shaderProgram.program, \"uv\", vao.buffers.uv);\n }\n\n private _unbindBuffers() {\n const gl = this._gl;\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n }\n\n private _supplyIndiciesData(indicies: VertexData, buffer: WebGLBuffer) {\n const gl = this._gl;\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicies.data, gl.STATIC_DRAW);\n }\n\n private _supplyAttributeData(attribute: VertexData, program: WebGLProgram, name: string, buffer: WebGLBuffer) {\n const gl = this._gl;\n const attribLocation = gl.getAttribLocation(program, name);\n\n // Attribute not used\n if (attribLocation < 0) return;\n\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ARRAY_BUFFER, attribute.data, gl.STATIC_DRAW);\n gl.vertexAttribPointer(attribLocation, attribute.itemSize, gl.FLOAT, false, 0, 0);\n gl.enableVertexAttribArray(attribLocation);\n }\n\n private _compileShader(type: number, src: string) {\n const gl = this._gl;\n const shader = gl.createShader(type)!;\n\n gl.shaderSource(shader, src);\n gl.compileShader(shader);\n\n return shader;\n }\n\n private _getCommonUniformLocations(program: WebGLProgram) {\n const gl = this._gl;\n\n return {\n uMVMatrix: gl.getUniformLocation(program, \"uMVMatrix\")!,\n uPMatrix: gl.getUniformLocation(program, \"uPMatrix\")!\n };\n }\n\n private _getContext(canvas: HTMLCanvasElement): {\n gl: WebGLRenderingContext | WebGL2RenderingContext;\n isWebGL2: boolean;\n } {\n const webglIdentifiers = [\"webgl2\", \"webgl\", \"experimental-webgl\", \"webkit-3d\", \"moz-webgl\"];\n let context: WebGLRenderingContext | null = null;\n let isWebGL2 = false;\n const contextAttributes = {\n preserveDrawingBuffer: false,\n antialias: false\n };\n\n const onWebglContextCreationError = e => e.statusMessage;\n\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_CREATE_ERROR, onWebglContextCreationError);\n\n for (const identifier of webglIdentifiers) {\n try {\n context = canvas.getContext(identifier, contextAttributes) as WebGLRenderingContext;\n isWebGL2 = identifier === \"webgl2\";\n } catch (t) {} // eslint-disable-line no-empty\n if (context) {\n break;\n }\n }\n\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_CREATE_ERROR, onWebglContextCreationError);\n\n if (!context) {\n throw new View360Error(ERROR.MESSAGES.WEBGL_NOT_SUPPORTED, ERROR.CODES.WEBGL_NOT_SUPPORTED);\n }\n\n return {\n gl: context,\n isWebGL2\n };\n }\n\n private _onContextLost = () => {\n const canvas = this._canvas;\n canvas.classList.add(DEFAULT_CLASS.CTX_LOST);\n this._contextLost = true;\n };\n\n private _onContextRestore = () => {\n const canvas = this._canvas;\n canvas.classList.remove(DEFAULT_CLASS.CTX_LOST);\n this._contextLost = false;\n };\n}\n\nexport default WebGLContext;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4 } from \"gl-matrix\";\nimport Camera from \"./Camera\";\nimport Projection from \"../projection/Projection\";\nimport WebGLContext from \"./WebGLContext\";\nimport XRManager from \"./XRManager\";\n\n/**\n * Projection renderer, based on WebGL\n * @ko WebGL 기반의 프로젝션 렌더러\n * @since 4.0.0\n */\nclass WebGLRenderer {\n private _canvas: HTMLCanvasElement;\n private _elementSize: { x: number, y: number };\n private _pixelRatio: number;\n\n public readonly ctx: WebGLContext;\n\n /**\n * Canvas element\n * @ko 캔버스 엘리먼트\n * @since 4.0.0\n */\n public get canvas() { return this._canvas; }\n /**\n * Canvas's width (`devicePixelRatio` is not applied)\n * @ko 캔버스의 보이는 너비 (`devicePixelRatio`가 적용되지 않은)\n * @since 4.0.0\n */\n public get width() { return this._elementSize.x; }\n /**\n * Canvas's height (`devicePixelRatio` is not applied)\n * @ko 캔버스의 높이 (`devicePixelRatio`가 적용되지 않은)\n * @since 4.0.0\n */\n public get height() { return this._elementSize.y; }\n /**\n * Current `devicePixelRatio` value.\n * @ko 현재 `devicePixelRatio` 값.\n * @since 4.0.0\n * @example\n * ```js\n * cosnt renderingWidth = view360.renderer.width * view360.renderer.pixelRatio;\n * ```\n */\n public get pixelRatio() { return this._pixelRatio; }\n /**\n * Width / height ratio (= width / height)\n * @ko 너비 / 높이의 비율 (= width / height)\n * @since 4.0.0\n * @example\n * ```js\n * const aspect = view360.renderer.width / view360.renderer.pixelRatio;\n * assert(aspect === view360.renderer.aspect);\n * ```\n */\n public get aspect() { return this._elementSize.x / this._elementSize.y; }\n\n /**\n * Create new instance\n * @ko 새 인스턴스를 생성합니다.\n * @param canvas - Canvas element {@ko 캔버스 엘리먼트}\n * @param debug - Whether to enable WebGL debugging {@ko WebGL debug 활성화 여부 }\n */\n public constructor(canvas: HTMLCanvasElement, debug: boolean) {\n this._canvas = canvas;\n this._elementSize = { x: 0, y: 0 };\n this._pixelRatio = 1;\n this.ctx = new WebGLContext(canvas, debug);\n }\n\n /**\n * Destroy instance and release all resources.\n * @ko 인스턴스를 제거하고 사용된 리소스를 전부 해제합니다.\n * @since 4.0.0\n */\n public destroy() {\n const canvas = this._canvas;\n\n this.ctx.destroy();\n canvas.width = 1;\n canvas.height = 1;\n }\n\n /**\n * Resize canvas and renew inner size cache.\n * @ko 캔버스의 크기를 재계산해서 내부의 사이즈 캐시값을 갱신합니다.\n * @since 4.0.0\n */\n public resize() {\n const canvas = this._canvas;\n const canvasSize = this._elementSize;\n const devicePixelRatio = window.devicePixelRatio;\n\n canvasSize.x = canvas.clientWidth;\n canvasSize.y = canvas.clientHeight;\n\n canvas.width = canvasSize.x * devicePixelRatio;\n canvas.height = canvasSize.y * devicePixelRatio;\n\n this._pixelRatio = devicePixelRatio;\n this.ctx.resize();\n }\n\n /**\n * Render projection\n * @ko 프로젝션을 렌더링합니다.\n * @param projection - Projection to render {@ko 렌더링할 프로젝션}\n * @param cameraa - Camera instance {@ko 카메라의 인스턴스}\n * @since 4.0.0\n */\n public render(projection: Projection, camera: Camera) {\n const ctx = this.ctx;\n const mesh = projection.getMesh();\n if (ctx.lost || !mesh) return;\n\n ctx.clear();\n ctx.useProgram(mesh.program);\n ctx.updateCommonUniforms(mesh, camera, mesh.program);\n projection.update(camera);\n ctx.updateUniforms(mesh.program);\n ctx.draw(mesh.vao, mesh.program);\n }\n\n /**\n * Render VR frame, only used for rendering frames inside VR sessions.\n * @ko VR 프레임을 렌더링합니다. VR 세션 진입 도중에만 사용됩니다.\n * @internal\n * @param projection - Projection to render {@ko 렌더링할 프로젝션}\n * @param vr - Instance of XRManager {@ko XRManager의 인스턴스}\n * @param frame - VR frame {@ko VR 프레임}\n * @since 4.0.0\n */\n public renderVR(projection: Projection, vr: XRManager, frame: XRFrame) {\n const ctx = this.ctx;\n const mesh = projection.getMesh();\n const eyeParams = vr.getEyeParams(frame);\n\n if (!eyeParams || !mesh) return;\n\n ctx.bindXRFrame(frame);\n ctx.useProgram(mesh.program);\n ctx.updateUniforms(mesh.program);\n\n eyeParams.forEach((eye, eyeIndex) => {\n const viewport = eye.viewport;\n // We're using \"mesh.matrix\"(=local matrix) here for efficiency\n // As projection doesn't require world matrix, as it doesn't have any parent or child\n const mvMatrix = mat4.multiply(mat4.create(), eye.vMatrix, mesh.matrix);\n\n ctx.viewport(viewport.x, viewport.y, viewport.width, viewport.height);\n ctx.updateVRUniforms(mesh.program, mvMatrix, eye.pMatrix, eyeIndex);\n ctx.draw(mesh.vao, mesh.program);\n });\n }\n}\n\nexport default WebGLRenderer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport Camera, { CameraOptions } from \"./core/Camera\";\nimport PanoControl, { PanoControlOptions } from \"./control/PanoControl\";\nimport TextureLoader from \"./core/TextureLoader\";\nimport FrameAnimator from \"./core/FrameAnimator\";\nimport AutoResizer from \"./core/AutoResizer\";\nimport Autoplay, { AutoplayOptions } from \"./core/Autoplay\";\nimport XRManager from \"./core/XRManager\";\nimport View360Error from \"./core/View360Error\";\nimport Projection from \"./projection/Projection\";\nimport HotspotRenderer, { HotspotOptions } from \"./hotspot/HotspotRenderer\";\nimport WebGLRenderer from \"./core/WebGLRenderer\";\nimport Texture from \"./texture/Texture\";\nimport View360Plugin from \"./plugin/View360Plugin\";\nimport ERROR from \"./const/error\";\nimport { CONTROL_EVENTS } from \"./const/internal\";\nimport { DEFAULT_CLASS, EVENTS } from \"./const/external\";\nimport { findCanvas, getElement } from \"./utils\";\nimport * as EVENT_TYPES from \"./type/events\";\nimport { EventParams } from \"./type/utils\";\n\n/**\n * Events that {@link View360} can trigger\n * @ko {@link View360}가 트리거할 수 있는 이벤트들\n * @see [Detailed Example](/docs/events/ready)\n * @since 4.0.0\n */\nexport interface View360Events {\n [EVENTS.READY]: EVENT_TYPES.ReadyEvent;\n [EVENTS.LOAD_START]: EVENT_TYPES.LoadStartEvent;\n [EVENTS.LOAD]: EVENT_TYPES.LoadEvent;\n [EVENTS.PROJECTION_CHANGE]: EVENT_TYPES.ProjectionChangeEvent;\n [EVENTS.RESIZE]: EVENT_TYPES.ResizeEvent;\n [EVENTS.BEFORE_RENDER]: EVENT_TYPES.BeforeRenderEvent;\n [EVENTS.RENDER]: EVENT_TYPES.RenderEvent;\n [EVENTS.INPUT_START]: EVENT_TYPES.InputStartEvent;\n [EVENTS.INPUT_END]: EVENT_TYPES.InputEndEvent;\n [EVENTS.VIEW_CHANGE]: EVENT_TYPES.ViewChangeEvent;\n [EVENTS.STATIC_CLICK]: EVENT_TYPES.StaticClickEvent;\n [EVENTS.VR_START]: EVENT_TYPES.VRStartEvent;\n [EVENTS.VR_END]: EVENT_TYPES.VREndEvent;\n}\n\n/**\n * Options for {@link View360}\n * @ko {@link View360}용 옵션들\n * @see [Detailed Example](/docs/options)\n * @since 4.0.0\n */\nexport interface View360Options extends CameraOptions, PanoControlOptions {\n projection: Projection | null;\n hotspot: Partial;\n autoplay: boolean | Partial;\n autoInit: boolean;\n autoResize: boolean;\n canvasSelector: string;\n useResizeObserver: boolean;\n tabIndex: number | null;\n on: Partial<{ [key in keyof View360Events]: (evt: View360Events[key]) => any }>;\n plugins: View360Plugin[];\n maxDeltaTime: number;\n debug: boolean;\n}\n\n/**\n * Panorama 360 image viewer\n * @ko 파노라마 360 이미지 뷰어\n * @since 4.0.0\n * @see View360Options\n * @see View360Events\n */\nclass View360 extends Component {\n /**\n * Current version string of the View360\n * @ko View360의 현재 버젼 문자열\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // If the installed version of the View360 is v4.0.0, View360.VERSION is equal to \"4.0.0\"\n * console.log(View360.VERSION) // 4.0.0\n * ```\n */\n public static readonly VERSION = \"#__VERSION__#\";\n\n private _rootEl: HTMLElement;\n private _renderer: WebGLRenderer;\n private _camera: Camera;\n private _control: PanoControl;\n private _animator: FrameAnimator;\n private _autoplay: Autoplay;\n private _hotspot: HotspotRenderer;\n private _projection: Projection | null;\n private _autoResizer: AutoResizer;\n private _vr: XRManager;\n private _plugins: View360Plugin[];\n private _initialized: boolean;\n\n private _autoInit: View360Options[\"autoInit\"];\n private _autoResize: View360Options[\"autoResize\"];\n private _canvasSelector: View360Options[\"canvasSelector\"];\n private _useResizeObserver: View360Options[\"useResizeObserver\"];\n private _tabIndex: View360Options[\"tabIndex\"];\n private _debug: View360Options[\"debug\"];\n\n /**\n * Root element (`.view360-container`)\n * @ko 루트 엘리먼트 (`.view360-container`)\n * @since 4.0.0\n * @readonly\n * @example\n * ```html\n *
\n * \n *
\n * ```\n * ```ts\n * import View360 from \"@egjs/view360\";\n *\n * const viewer = new View360(\"#viewer\");\n * console.log(viewer.rootEl); // Element with id \"viewer\"\n * ```\n */\n public get rootEl() { return this._rootEl; }\n /**\n * Projection renderer.\n * @ko 프로젝션 렌더러.\n * @since 4.0.0\n * @readonly\n */\n public get renderer() { return this._renderer; }\n /**\n * Projection camera.\n * @ko 프로젝션 카메라.\n * @since 4.0.0\n * @readonly\n */\n public get camera() { return this._camera; }\n /**\n * Rotate/Zoom Controller.\n * @ko 회전/줌 컨트롤러.\n * @since 4.0.0\n * @readonly\n */\n public get control() { return this._control; }\n /**\n * WebXR-based VR manager.\n * @ko WebXR 기반의 VR 기능 매니저 인스턴스.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // Example: Enter VR\n * // This must be called on user interaction, else will be rejected.\n * viewer.vr.enter();\n * ```\n */\n public get vr() { return this._vr; }\n /**\n * Hotspot renderer.\n * You can also change options of {@link View360Options#hotspot} with this.\n * @ko 핫스팟 렌더러 인스턴스.\n * {@link View360Options#hotspot} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get hotspot() { return this._hotspot; }\n /**\n * An array of plugins added.\n * @ko 추가된 플러그인의 배열\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * plugins: [new ControlBar()]\n * });\n *\n * console.log(viewer.plugins); // [ControlBar]\n *\n * viewer.addPlugins(new LoadingSpinner()) // [ControlBar, LoadingSpinner];\n * ```\n */\n public get plugins() { return this._plugins; }\n /**\n * A instance of {@link Projection} that currently enabled. `null` if not initialized yet.\n * You should call {@link View360#load} to change panorama src or projection type.\n * @ko 현재 사용중인 {@link Projection}의 인스턴스. 프로젝션을 활성화하지 않았을 경우 `null`입니다.\n * 파노라마 이미지 소스나 프로젝션 타입을 변경하려면 {@link View360#load}를 호출하면 됩니다.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360\n * ```\n */\n public get projection() { return this._projection; }\n public set projection(val: View360Options[\"projection\"]) {\n if (this._initialized && val) {\n this.load(val);\n } else {\n this._projection = val;\n }\n }\n /**\n * A boolean value whether {@link View360#init init()} is called before.\n * @ko {@link View360#init init()}이 호출되었는지 여부를 가리키는 값\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360(\"#el\", { autoInit: false });\n *\n * console.log(viewer.initialized); // false\n *\n * await viewer.init();\n *\n * console.log(viewer.initialized); // true\n * ```\n */\n public get initialized() { return this._initialized; }\n /**\n * Instance of the Autoplay manager.\n * You can also change {@link View360Options#autoplay} options with this.\n * @ko Autoplay 기능의 매니저 인스턴스.\n * 이 인스턴스를 통해 {@link View360Options#autoplay} 옵션을 변경하는 것도 가능합니다.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // Disable autoplay\n * viewer.autoplay.disable();\n * ```\n */\n public get autoplay() { return this._autoplay; }\n /**\n * When this value is `true` and {@link View360Options#projection} is set, {@link View360#init init()} will be called automatically when instance is created.\n * @ko 이 값이 `true`이고, {@link View360Options#projection}이 설정되었으면, 인스턴스 생성 시점에 자동으로 {@link View360#init init()}을 호출합니다.\n * @default true\n * @since 4.0.0\n * @example\n * ```ts\n * import View360, { EquirectProjection, EVENTS } from \"@egjs/view360\";\n *\n * // viewer.init() is called on instance creation\n * // But as `init` is asynchronous, you should wait for \"ready\" event if you want to do something after initialization.\n * const viewer = new View360(\"#el_id\", {\n * autoInit: true,\n * projection: new EquirectProjection({ src: \"SRC_TO_URL\" })\n * });\n *\n * console.log(viewer.initialized); // false, as `init` is asynchronous\n *\n * viewer.once(EVENTS.READY, () => {\n * console.log(viewer.initialized); // true\n * });\n * ```\n */\n public get autoInit() { return this._autoInit; }\n /**\n * When `true`, {@link View360#resize} is called when the canvas size is changed.\n * @ko `true`일 경우, 캔버스의 크기가 변경되었을 때 자동으로 {@link View360#resize}를 호출합니다.\n * @default true\n * @since 4.0.0\n * @see View360#useResizeObserver\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * autoResize: true\n * });\n *\n * // This can trigger `viewer.resize()` if the canvas size was not 400px\n * const canvas = viewer.renderer.canvas;\n * canvas.style.width = \"400px\";\n * ```\n */\n public get autoResize() { return this._autoResize; }\n /**\n * CSS selector for canvas element to render panorama image/video.\n * The canvas element should be placed inside the root element. (Dont' have to be direct child)\n * @ko 파노라마 이미지/비디오를 렌더링할 canvas 엘리먼트의 CSS 선택자\n * 캔버스 엘리먼트는 루트 엘리먼트 내부에 있어야합니다. 루트 엘리먼트의 직계 자식 엘리먼트(Direct child element)일 필요는 없습니다.\n * @default \"canvas\"\n * @since 4.0.0\n * @example\n * ```html\n *
\n * \n * \n * \n *
\n * ```\n *\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * canvasSelector: \"#canvas_to_select\"\n * });\n * ```\n */\n public get canvasSelector() { return this._canvasSelector; }\n /**\n * When `true`, it will use {@link ResizeObserver} API to detect canvas size change when {@link View360Options#autoResize} is enabled.\n * @ko `true`일 때 {@link View360Options#autoResize}가 활성화되었으면, 사용 가능한 환경에서 {@link ResizeObserver} API를 사용해서 캔버스 크기 변화를 추적합니다.\n * @default true\n * @since 4.0.0\n */\n public get useResizeObserver() { return this._useResizeObserver; }\n /**\n * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} attribute for the canvas element.\n * This is necessary for the keyboard controls.\n * By default, `0` will be assigned. `null` to disable.\n * @ko 캔버스 엘리먼트에 적용할 {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} 어트리뷰트의 값.\n * 이 값을 설정해야만 키보드 컨트롤을 사용 가능합니다.\n * 기본값으로 `0`이 설정됩니다. `null`로 지정하면 `tabindex`를 설정하지 않습니다.\n * @see RotateControlOptions#disableKeyboard\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * tabindex: 5\n * });\n * ```\n *\n * ```html\n * \n *
\n * \n *
\n * ```\n */\n public get tabIndex() { return this._tabIndex; }\n public set tabIndex(val: View360Options[\"tabIndex\"]) {\n const canvas = this._renderer.canvas;\n this._tabIndex = val;\n\n if (val != null) {\n canvas.tabIndex = val;\n } else {\n canvas.removeAttribute(\"tabindex\");\n }\n }\n /**\n * A maximum delta time between frames in seconds.\n * It can prevent camera or control changing too fast when frame being late.\n * @ko 프레임간 시간 차이의 최대값. (초 단위)\n * 퍼포먼스 등의 이유로 프레임 렌더링이 늦어졌을 때, 화면이 갑작스럽게 바뀌는 것을 막아줍니다.\n * @default 1 / 30\n * @since 4.0.0\n */\n public get maxDeltaTime() { return this._animator.maxDeltaTime; }\n public set maxDeltaTime(val: View360Options[\"maxDeltaTime\"]) { this._animator.maxDeltaTime = val; }\n /**\n * Enable WebGL debugging. Setting this to `true` can decrease performance.\n * This is used internally on developing View360.\n * @ko WebGL 디버깅을 활성화합니다. 이 값을 `true`로 할 경우 성능이 하락할 수 있습니다.\n * 이 옵션은 View360을 개발하기 위해 내부적으로 사용됩니다.\n * @default false\n */\n public get debug() { return this._debug; }\n public set debug(val: View360Options[\"debug\"]) { this._debug = val; }\n\n // Camera options\n /**\n * Initial yaw (y-axis rotation) value for camera. (in degrees, °)\n * As View360 uses right-handed coordinate system internally, camera will rotate counter-clockwise by this value.\n * @ko 카메라의 초기 yaw(y축 회전)값 (도 단위, °)\n * View360은 오른손 좌표계를 사용하기 때문에, 카메라가 해당 값만큼 시계 반대방향으로 회전합니다.\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialYaw: 30\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.yaw); // 30\n * });\n * ```\n */\n public get initialYaw() { return this._camera.initialYaw; }\n public set initialYaw(val: View360Options[\"initialYaw\"]) { this._camera.initialYaw = val; }\n /**\n * Initial pitch (x-axis rotation) value for camera. (in degrees, °)\n * As View360 uses right-handed coordinate system internally, positive value will make camera to look upside, while negative value will look down.\n * @ko 카메라의 초기 pitch(x축 회전)값 (도 단위, °)\n * View360은 오른손 좌표계를 사용하기 때문에, 양(+)의 값은 카메라가 위를 보게 하고, 음(-)의 값은 카메라가 아래를 보게 합니다.\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialPitch: 60\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.pitch); // 60\n * });\n * ```\n */\n public get initialPitch() { return this._camera.initialPitch; }\n public set initialPitch(val: View360Options[\"initialPitch\"]) { this._camera.initialPitch = val; }\n /**\n * Initial zoom value for camera.\n * Setting this value to `2` will enlarge panorama 200% by width.\n * @ko 카메라의 초기 줌 값.\n * 이 값을 `2`로 설정할 경우 파노라마 이미지를 가로 기준 200%만큼 확대합니다.\n * @default 1\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialZoom: 2\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.zoom); // 2\n * });\n * ```\n */\n public get initialZoom() { return this._camera.initialZoom; }\n public set initialZoom(val: View360Options[\"initialZoom\"]) { this._camera.initialZoom = val; }\n /**\n * Restrict yaw(y-axis rotation) range. (in degrees, °)\n * @ko yaw(y축 회전) 범위를 제한합니다. (도 단위, °)\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * yawRange: [-30, 30]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.yaw); // 0\n * viewer.camera.lookAt({ yaw: 60 });\n * console.log(viewer.camera.yaw); // 30\n * });\n * ```\n */\n public get yawRange() { return this._camera.yawRange; }\n public set yawRange(val: View360Options[\"yawRange\"]) {\n this._camera.yawRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Restrict pitch(x-axis rotation) range. (in degrees, °)\n * @ko pitch(x축 회전) 범위를 제한합니다. (도 단위, °)\n * @default null\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * pitchRange: [-45, 45]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.pitch); // 0\n * viewer.camera.lookAt({ pitch: 60 });\n * console.log(viewer.camera.pitch); // 45\n * });\n * ```\n */\n public get pitchRange() { return this._camera.pitchRange; }\n public set pitchRange(val: View360Options[\"pitchRange\"]) {\n this._camera.pitchRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Restrict camera zoom range.\n * If `null`, a default zoom range from `0.6` to `10` will be used.\n * @ko 카메라 줌 범위를 제한합니다.\n * `null`일 경우 기본값으로 `0.6`에서 `10`의 범위를 사용합니다.\n * @default null\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * zoomRange: [0.5, 4]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.zoom); // 1\n * viewer.camera.lookAt({ zoom: 6 });\n * console.log(viewer.camera.zoom); // 4\n * });\n * ```\n */\n public get zoomRange() { return this._camera.zoomRange; }\n public set zoomRange(val: View360Options[\"zoomRange\"]) {\n this._camera.zoomRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Camera's horizontal FOV(Field of View). (in degrees, °)\n * @ko 카메라의 수평 FOV(Field of View) 값. (도 단위, °)\n * @default 90\n * @since 4.0.0\n * @example\n * ```ts\n * // Init with fov: 120\n * const viewer = new View360(\"#el_id\", { fov: 120 });\n *\n * // Back to 90\n * viewer.fov = 90;\n * ```\n */\n public get fov() { return this._camera.fov; }\n public set fov(val: View360Options[\"fov\"]) {\n const camera = this._camera;\n const control = this._control;\n\n camera.fov = val;\n camera.updateMatrix();\n control.sync();\n }\n\n // Control options\n /**\n * A control for camera rotation.\n * You can also change options of {@link View360Options#rotate} with this.\n * @ko 카메라 회전을 담당하는 컨트롤.\n * {@link View360Options#rotate} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get rotate() { return this._control.rotate; }\n /**\n * A control for camera zoom.\n * You can also change options of {@link View360Options#zoom} with this.\n * @ko 카메라 줌을 담당하는 컨트롤.\n * {@link View360Options#zoom} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get zoom() { return this._control.zoom; }\n /**\n * A control for camera rotation with gyroscope input.\n * You can also change options of {@link View360Options#gyro} with this.\n * @ko 자이로스코프를 통한 카메라 회전을 담당하는 컨트롤.\n * {@link View360Options#gyro} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get gyro() { return this._control.gyro; }\n /**\n * Apply CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor} by current state of input when using mouse.\n * If `true`, this will add CSS style to canvas element. It'll apply `cursor: \"grab\"` by default and `cursor: \"grabbing\"` when holding the mouse button.\n * @ko 마우스 사용시 CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor}값을 자동으로 변경할지 여부.\n * `true`일 경우 기본 상태에서 `cursor: \"grab\"`을, 입력 도중에 `cursor: \"grabbing\"`을 캔버스에 적용합니다.\n * @default true\n * @since 4.0.0\n */\n public get useGrabCursor() { return this._control.useGrabCursor; }\n public set useGrabCursor(val: View360Options[\"useGrabCursor\"]) { this._control.useGrabCursor = val; }\n /**\n * Disable context menu which pops up on mouse right click.\n * @ko 마우스 우클릭시 표시되는 컨텍스트 메뉴를 비활성화합니다.\n * @default false\n * @since 4.0.0\n */\n public get disableContextMenu() { return this._control.disableContextMenu; }\n public set disableContextMenu(val: View360Options[\"disableContextMenu\"]) { this._control.disableContextMenu = val; }\n /**\n * If `true`, enables scroll on mobile(touch) devices on canvas.\n * :::caution\n * When this option is enabled, users must swipe horizontally first then vertically to change view up or down.\n * :::\n * @ko `true`로 설정할 경우, 모바일(터치) 환경의 캔버스 영역 내에서 스크롤을 가능하게 합니다.\n * :::caution\n * 이 값을 활성화할 경우, 사용자가 카메라 뷰를 위/아래로 바꾸기 위해서는 먼저 가로로 스와이프한 이후에 세로로 스와이프해야만 합니다.\n * :::\n * @since 4.0.0\n * @default true\n */\n public get scrollable() { return this._control.scrollable; }\n public set scrollable(val: View360Options[\"scrollable\"]) { this._control.scrollable = val; }\n /**\n * If `true`, enables scroll by mouse wheel on canvas.\n * :::caution\n * When this option is enabled, zoom by mouse wheel will be disabled.\n * :::\n * @ko `true`로 설정할 경우, 캔버스 영역 내에서 마우스 휠을 이용한 페이지 스크롤이 가능해집니다.\n * :::caution\n * 이 값을 활성화할 경우, 마우스 휠을 통한 줌이 불가능하게 됩니다.\n * :::\n * @since 4.0.0\n * @default false\n */\n public get wheelScrollable() { return this._control.wheelScrollable; }\n public set wheelScrollable(val: View360Options[\"wheelScrollable\"]) { this._control.wheelScrollable = val; }\n\n /**\n * Create new instance of View360\n * @ko View360의 새로운 인스턴스를 생성합니다\n * @param root - Root element(`.view360-container`) to mount View360\n * Can be either a CSS selector or HTMLElement.\n * {@ko View360을 마운트할 루트 엘리먼트, CSS 셀렉터나 HTMLElement를 지정 가능합니다.}\n * @param options - Options to apply\n * {@ko 적용할 옵션들}\n * @example\n * ```ts\n * import View360, { EquirectProjection } from \"@egjs/view360\";\n *\n * // Create new View360 instance\n * const viewer = new View360(\"#id-of-a-container\", {\n * projection: new EquirectProjection({\n * src: \"URL_TO_PANORAMA_IMAGE_OR_VIDEO\",\n * })\n * });\n * ```\n */\n public constructor(root: string | HTMLElement, {\n projection = null,\n initialYaw = 0,\n initialPitch = 0,\n initialZoom = 1,\n yawRange = null,\n pitchRange = null,\n zoomRange = null,\n fov = 90,\n useGrabCursor = true,\n disableContextMenu = false,\n rotate = true,\n zoom = true,\n gyro = false,\n scrollable = true,\n wheelScrollable = false,\n autoplay = false,\n hotspot = {},\n autoInit = true,\n autoResize = true,\n canvasSelector = \"canvas\",\n useResizeObserver = true,\n on = {},\n plugins = [],\n maxDeltaTime = 1 / 30,\n tabIndex = 0,\n debug = false\n }: Partial = {}) {\n super();\n\n this._rootEl = getElement(root);\n this._plugins = plugins;\n this._initialized = false;\n\n // Options\n this._autoInit = autoInit;\n this._autoResize = autoResize;\n this._canvasSelector = canvasSelector;\n this._useResizeObserver = useResizeObserver;\n this._tabIndex = tabIndex;\n this._debug = debug;\n\n // Core components\n const canvas = findCanvas(this._rootEl, canvasSelector);\n this._renderer = new WebGLRenderer(canvas, debug);\n this._camera = new Camera({\n initialYaw,\n initialPitch,\n initialZoom,\n fov,\n yawRange,\n pitchRange,\n zoomRange\n });\n this._control = new PanoControl(canvas, this._camera, {\n useGrabCursor,\n scrollable,\n wheelScrollable,\n disableContextMenu,\n rotate,\n zoom,\n gyro\n });\n this._animator = new FrameAnimator(maxDeltaTime);\n this._autoplay = new Autoplay(this, canvas, autoplay);\n this._projection = projection;\n this._autoResizer = new AutoResizer(useResizeObserver, () => this.resize());\n this._vr = new XRManager(this._renderer.ctx);\n this._hotspot = new HotspotRenderer(this._rootEl, this._renderer, hotspot);\n\n this._addEventHandlers(on);\n\n if (projection && autoInit) {\n this.init();\n }\n }\n\n /**\n * Destroy instance and release all resources.\n * @ko 인스턴스를 제거하고 모든 리소스를 해제합니다.\n * @since 4.0.0\n */\n public destroy() {\n this._camera.destroy();\n this._animator.stop();\n this._renderer.destroy();\n this._control.destroy();\n this._autoResizer.disable();\n\n if (this._projection) {\n this._projection.releaseAllResources(this._renderer.ctx);\n this._projection = null;\n }\n\n this._plugins.forEach(plugin => plugin.destroy(this));\n\n this._initialized = false;\n }\n\n /**\n * Initialize inner components and load projection src.\n * @ko 내부 컴포넌트들을 초기화하고 프로젝션 소스를 로드합니다.\n * @since 4.0.0\n */\n public async init() {\n if (!this._projection) {\n throw new View360Error(ERROR.MESSAGES.PROVIDE_PROJECTION_FIRST, ERROR.CODES.PROVIDE_PROJECTION_FIRST);\n }\n\n const renderer = this._renderer;\n const camera = this._camera;\n const control = this._control;\n const animator = this._animator;\n const hotspot = this._hotspot;\n const projection = this._projection;\n const canvas = renderer.canvas;\n\n this._bindComponentEvents();\n renderer.ctx.init();\n this._resizeComponents();\n camera.updateMatrix();\n\n if (this._autoResize) {\n this._autoResizer.enable(canvas);\n }\n\n if (!this._autoplay.enableBlocked) {\n this._autoplay.enable();\n }\n\n this._plugins.forEach(plugin => {\n plugin.init(this);\n });\n\n const texture = await this._loadTexture(projection);\n this._applyProjection(projection, texture, null);\n hotspot.refresh();\n animator.start(this._renderFrameOnDemand);\n await control.enable();\n\n if (this._tabIndex != null && !canvas.hasAttribute(\"tabIndex\")) {\n canvas.tabIndex = this._tabIndex;\n }\n\n this._initialized = true;\n this.renderFrame(0);\n\n this._emit(EVENTS.READY);\n }\n\n /**\n * Load new panorama image/video and display it.\n * This will {@link View360#init init()} View360 if it's not initialized yet.\n * @ko 새로운 파노라마 이미지 혹은 비디오를 로드하고 표시합니다.\n * 만약 View360이 아직 초기화되지 않았다면, {@link View360#init init()}을 호출합니다.\n * @param projection - Projection & video options for new source. {@ko 새로운 파노라마 이미지/비디오에 적용할 옵션들}\n * @returns `Promise` if load was successful. {@ko 프로젝션 로드에 성공했을 경우 `Promise`를 반환합니다. }\n * @since 4.0.0\n * @example\n * ```ts\n * // Change to video\n * viewer.load({\n * src: \"URL_TO_NEW_VIDEO\",\n * video: true\n * });\n * ```\n */\n public async load(projection: Projection): Promise {\n if (!projection) return false;\n\n if (this._initialized) {\n const texture = await this._loadTexture(projection);\n this._applyProjection(projection, texture, this._projection);\n this.renderFrame(0);\n } else {\n // Should update internal options before init\n this._projection = projection;\n this.init();\n }\n\n return true;\n }\n\n /**\n * Refresh component's size by current\n * @ko View360이 내부적으로 캐시하고 있는 엘리먼트 크기를 현재 크기로 갱신합니다.\n * @since 4.0.0\n */\n public resize() {\n if (!this._initialized) return;\n\n this._resizeComponents();\n\n // To prevent flickering, render immediately after resizing components\n this.renderFrame(0);\n\n const { width, height } = this._renderer;\n\n this._emit(EVENTS.RESIZE, {\n width,\n height\n });\n }\n\n /**\n * Add new plugins\n * @ko 새로운 플러그인을 추가합니다.\n * @param plugins Plugins to add {@ko 추가할 플러그인들}\n * @see View360Options#plugins\n * @since 4.0.0\n * @example\n * ```ts\n * // Add a single plugin\n * viewer.addPlugins(new ControlBar());\n *\n * // Add multiple plugins\n * viewer.addPlugins(new ControlBar(), new LoadingSpinner());\n * ```\n */\n public addPlugins(...plugins: View360Plugin[]) {\n if (this._initialized) {\n plugins.forEach(plugin => { plugin.init(this); });\n }\n\n this._plugins.push(...plugins);\n }\n\n /**\n * Remove plugins.\n * @ko 플러그인을 제거합니다.\n * @param plugins Plugins to remove {@ko 제거할 플러그인들}\n * @since 4.0.0\n * @example\n * ```ts\n * // Remove a single plugin\n * viewer.removePlugins(plugin1);\n *\n * // Remove multiple plugins\n * viewer.removePlugins(plugin2, plugin3);\n * ```\n */\n public removePlugins(...plugins: View360Plugin[]) {\n plugins.forEach(plugin => {\n const pluginIdx = this._plugins.indexOf(plugin);\n\n if (pluginIdx < 0) return;\n\n plugin.destroy(this);\n this._plugins.splice(pluginIdx, 1);\n });\n }\n\n /**\n * Render a single panorama image/video frame.\n * Rendering is performed automatically on demand, so you usually don't have to call this.\n * Call this when a frame is not renewed after changing options.\n * @ko 파노라마 이미지/비디오의 한 프레임을 렌더링합니다.\n * 프레임 갱신은 보통 필요한 때에만 자동적으로 이루어지기 때문에, 보통은 이 메소드를 호출할 필요는 없습니다.\n * 옵션 변경 이후에도 프레임 갱신이 이루어지지 않는다면, 이 메소드를 호출해주세요.\n * @param delta Delta time in milisec. {@ko 프레임간 시간 차이, 밀리초 단위}\n * @since 4.0.0\n */\n public renderFrame = (delta: number) => {\n const camera = this._camera;\n const renderer = this._renderer;\n const control = this._control;\n const hotspot = this._hotspot;\n const autoPlayer = this._autoplay;\n const projection = this._projection;\n\n if (!projection) return;\n\n this._emit(EVENTS.BEFORE_RENDER);\n\n if (autoPlayer.playing) {\n autoPlayer.update(delta);\n control.sync();\n }\n\n if (camera.animation) {\n camera.animation.update(delta);\n } else {\n control.update(delta);\n }\n\n renderer.render(projection, camera);\n hotspot.render(camera);\n\n if (camera.changed) {\n this._emit(EVENTS.VIEW_CHANGE, {\n yaw: camera.yaw,\n pitch: camera.pitch,\n zoom: camera.zoom,\n quaternion: [\n camera.quaternion[0],\n camera.quaternion[1],\n camera.quaternion[2],\n camera.quaternion[3]\n ]\n });\n }\n camera.onFrameRender();\n\n this._emit(EVENTS.RENDER);\n };\n\n private _emit(eventName: K, ...params: EventParams) {\n const evtParams = params ? params[0] : {};\n\n this.trigger(eventName as any, {\n type: eventName,\n target: this,\n ...evtParams\n });\n }\n\n private _renderFrameOnDemand = (delta: number) => {\n const camera = this._camera;\n const control = this._control;\n const autoplay = this._autoplay;\n const texture = this._projection?.getTexture();\n\n if (!this._initialized || !texture) return;\n if (\n !camera.animation\n && !control.animating\n && !autoplay.playing\n && !texture.isVideo()\n ) return;\n\n this.renderFrame(delta);\n };\n\n private _renderVRFrame = (_delta: number, frame: XRFrame) => {\n const vr = this._vr;\n const projection = this._projection;\n const renderer = this._renderer;\n\n if (!projection) return;\n\n this._emit(EVENTS.BEFORE_RENDER);\n\n renderer.renderVR(projection, vr, frame);\n\n this._emit(EVENTS.RENDER);\n }\n\n private _applyProjection(projection: Projection, texture: Texture, prevProjection: Projection | null) {\n const camera = this._camera;\n const control = this._control;\n const renderer = this._renderer;\n\n // Remove previous projection\n if (prevProjection) {\n prevProjection.releaseAllResources(this._renderer.ctx);\n }\n\n projection.applyTexture(renderer.ctx, texture);\n projection.updateCamera(camera);\n projection.updateControl(control);\n\n this._projection = projection;\n this._emit(EVENTS.PROJECTION_CHANGE, {\n projection\n });\n }\n\n private async _loadTexture(projection: Projection): Promise {\n const contentLoader = new TextureLoader();\n const { src, video } = projection;\n\n this._emit(EVENTS.LOAD_START, {\n src,\n video\n });\n\n const texture = await contentLoader.load(src, video);\n\n this._emit(EVENTS.LOAD, {\n src,\n video\n });\n\n return texture;\n }\n\n private _resizeComponents() {\n const renderer = this._renderer;\n const camera = this._camera;\n const control = this._control;\n\n renderer.resize();\n camera.resize(renderer.width, renderer.height);\n control.resize(renderer.width, renderer.height);\n }\n\n private _addEventHandlers(events: View360Options[\"on\"]) {\n // Bind option \"on\"\n Object.keys(events).forEach((evtName: keyof typeof EVENT_TYPES) => {\n this.on(evtName, events[evtName]);\n });\n }\n\n private _bindComponentEvents() {\n // Bind internal component events\n const root = this._rootEl;\n const control = this._control;\n const animator = this._animator;\n const renderer = this._renderer;\n const vr = this._vr;\n\n const controlEventsToPropagate = [\n CONTROL_EVENTS.STATIC_CLICK,\n CONTROL_EVENTS.INPUT_START,\n CONTROL_EVENTS.INPUT_END\n ];\n\n controlEventsToPropagate.forEach(evtName => {\n control.rotate.on(evtName, evt => {\n this._emit(evtName, evt);\n });\n\n control.zoom.on(evtName, evt => {\n this._emit(evtName, evt);\n });\n });\n\n vr.on(EVENTS.VR_START, evt => {\n root.classList.add(DEFAULT_CLASS.IN_VR);\n\n animator.changeContext(evt.session);\n animator.start(this._renderVRFrame);\n\n this._emit(EVENTS.VR_START);\n });\n\n vr.on(EVENTS.VR_END, () => {\n root.classList.remove(DEFAULT_CLASS.IN_VR);\n\n renderer.ctx.useDefaultFrameBuffer();\n animator.changeContext(window);\n animator.start(this._renderFrameOnDemand);\n\n this.resize();\n\n this._emit(EVENTS.VR_END);\n });\n }\n}\n\nexport default View360;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4, quat, vec3 } from \"gl-matrix\";\n\n/**\n * Base class for 3D objects\n * @ko 3D 오브젝트의 베이스 클래스\n * @since 4.0.0\n * @internal\n */\nclass Object3D {\n /**\n * Local matrix of the object\n * @ko 오브젝트의 local matrix\n * @since 4.0.0\n */\n public matrix: mat4;\n /**\n * Rotation quaternion\n * @ko 현재 오브젝트의 회전을 나타내는 사원수 값\n * @since 4.0.0\n */\n public rotation: quat;\n /**\n * Position of the object\n * @ko 오브젝트의 위치\n * @since 4.0.0\n */\n public position: vec3;\n /**\n * A scale vector of the object\n * @ko 오브젝트가 각 축으로 확대된 정도를 나타내는 벡터\n * @since 4.0.0\n */\n public scale: vec3;\n\n /**\n * Create new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n */\n public constructor() {\n this.matrix = mat4.create();\n this.rotation = quat.create();\n this.position = vec3.fromValues(0, 0, 0);\n this.scale = vec3.fromValues(1, 1, 1);\n }\n\n /**\n * Update local matrix of the object.\n * @ko 오브젝트의 local matrix를 갱신합니다.\n * @since 4.0.0\n */\n public updateMatrix() {\n mat4.fromRotationTranslationScale(this.matrix, this.rotation, this.position, this.scale);\n }\n}\n\nexport default Object3D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360Plugin from \"../View360Plugin\";\nimport View360 from \"../../View360\";\nimport { EVENTS } from \"../../const/external\";\nimport { createElement } from \"../../utils\";\nimport { LoadStartEvent } from \"../../type/events\";\n\n/**\n * Options for {@link LoadingSpinner}\n * @ko {@link LoadingSpinner}용 옵션들\n * @since 4.0.0\n * @category Plugin\n */\nexport interface LoadingSpinnerOptions {\n /**\n * Override default class names.\n * @ko 디폴트 클래스 이름들을 오버라이드합니다.\n * @since 4.0.0\n */\n className: Partial<{ -readonly [key in keyof typeof LoadingSpinner.DEFAULT_CLASS]: string }>;\n}\n\n/**\n * A plugin that displays loading spinner while loading the projection.\n * @ko 프로젝션 로딩중에 로딩 스피너를 보여주는 플러그인\n * @since 4.0.0\n * @category Plugin\n */\nclass LoadingSpinner implements View360Plugin {\n /**\n * Default class names that LoadingSpinner uses\n * @ko LoadingSpinner가 사용하는 디폴트 클래스 이름\n * @since 4.0.0\n */\n public static readonly DEFAULT_CLASS = {\n /**\n * A class name for the container element\n * @ko 컨테이너 엘리먼트의 클래스 이름\n * @since 4.0.0\n */\n CONTAINER: \"view360-spinner\",\n /**\n * A class name for the spinning ring element\n * @ko 돌아가는 링 엘리먼트의 클래스 이름\n * @since 4.0.0\n */\n RING: \"view360-spinner-ring\"\n } as const;\n\n /**\n * A class names overriding\n * @ko 현재 오버라이드 중인 클래스 이름\n * @since 4.0.0\n */\n public readonly className: LoadingSpinnerOptions[\"className\"];\n\n private _container: HTMLElement;\n\n /**\n * Create a new instance of LoadingSpinner. {@ko LoadingSpinner의 새 인스턴스를 생성합니다.}\n * @param options Options {@ko 옵션들}\n */\n public constructor({\n className = {}\n }: Partial = {}) {\n this.className = className;\n this._container = this._createElements();\n }\n\n public init(viewer: View360) {\n viewer.on(EVENTS.LOAD_START, this._startLoading);\n }\n\n public destroy(viewer: View360): void {\n viewer.off(EVENTS.LOAD_START, this._startLoading);\n this._detachElements({ target: viewer });\n }\n\n private _startLoading = ({ target: viewer }: LoadStartEvent) => {\n viewer.rootEl.appendChild(this._container);\n\n if (viewer.initialized) {\n viewer.once(EVENTS.LOAD, this._detachElements);\n } else {\n viewer.once(EVENTS.READY, this._detachElements);\n }\n };\n\n private _detachElements = ({ target: viewer }: { target: View360 }) => {\n const container = this._container;\n if (!container) return;\n\n if (container.parentElement === viewer.rootEl) {\n viewer.rootEl.removeChild(container);\n }\n };\n\n private _createElements() {\n const className = {\n ...this.className,\n ...LoadingSpinner.DEFAULT_CLASS\n };\n\n const container = createElement(className.CONTAINER);\n const ring = createElement(className.RING);\n\n container.appendChild(ring);\n\n return container;\n }\n}\n\nexport default LoadingSpinner;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n/* eslint-disable @typescript-eslint/no-empty-function */\n/* eslint-disable @typescript-eslint/no-unused-vars */\nimport ControlBar from \"./ControlBar\";\nimport View360 from \"../../View360\";\n\n/**\n * Common options for {@link ControlBarItem}\n * @ko {@link ControlBarItem}의 공통 옵션들\n * @category Plugin\n * @since 4.0.0\n */\nexport interface ControlBarItemOptions {\n /**\n * @copy ControlBarItem#position\n */\n position: typeof ControlBar.POSITION[keyof typeof ControlBar.POSITION];\n /**\n * @copy ControlBarItem#order\n */\n order: number;\n}\n\n/**\n * Interface of the ControlBar items\n * @ko 컨트롤바 아이템의 인터페이스\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nabstract class ControlBarItem {\n /**\n * Element of the item.\n * @ko 아이템의 엘리먼트\n * @since 4.0.0\n */\n public abstract element: HTMLElement;\n\n /**\n * Position to display item.\n * @ko 아이템을 표시할 위치.\n * @since 4.0.0\n */\n public position: ControlBarItemOptions[\"position\"];\n /**\n * Order within the same position.\n * The lowest one will be shown first.\n * @ko 동일한 position 내에서의 순서, 작을수록 먼저 표시됩니다.\n * @since 4.0.0\n */\n public order: ControlBarItemOptions[\"order\"];\n\n /**\n * Create new instance of the ControlBarItem\n * @ko ControlBarItem의 새로운 인스턴스를 생성합니다.\n * @param options Options {@ko 옵션들}\n */\n public constructor(options: ControlBarItemOptions) {\n this.position = options.position;\n this.order = options.order;\n }\n\n /**\n * Initialize item.\n * @ko 아이템을 초기화합니다.\n * @param viewer - A instance of viewer to attach item {@ko 아이템을 부착할 뷰어의 인스턴스}\n * @param controlBar - A instance of control bar to attach item {@ko 아이템을 부착할 컨트롤바의 인스턴스}\n * @since 4.0.0\n */\n public abstract init(viewer: View360, controlBar: ControlBar): any;\n /**\n * Destroy item and release all resources & event handlers.\n * @ko 아이템을 제거하고 할당된 모든 리소스 및 이벤트 핸들러를 제거합니다.\n * @param viewer - A instance of viewer to detach item {@ko 아이템을 떼어 낼 뷰어의 인스턴스}\n * @param controlBar - A instance of control bar to detach item {@ko 아이템을 떼어 낼 컨트롤바의 인스턴스}\n * @since 4.0.0\n */\n public abstract destroy(viewer: View360, controlBar: ControlBar): any;\n}\n\nexport default ControlBarItem;\n","export const CONTROL_BAR_DEFAULT_CLASS = {\n CONTROLS_ROOT: \"view360-controls\",\n CONTROLS_BG: \"view360-controls-background\",\n CONTROLS_MAIN: \"view360-controls-main\",\n CONTROLS_TOP: \"view360-controls-top\",\n CONTROLS_BOTTOM: \"view360-controls-bottom\",\n CONTROLS_MID: \"view360-controls-mid\",\n CONTROLS_LEFT: \"view360-controls-left\",\n CONTROLS_RIGHT: \"view360-controls-right\",\n CONTROLS_FLOAT_LEFT: \"view360-controls-float-left\",\n CONTROLS_FLOAT_RIGHT: \"view360-controls-float-right\",\n CONTROLS_BUTTON: \"view360-controls-button\",\n PROGRESS_ROOT: \"view360-controls-progress\",\n VOLUME_ROOT: \"view360-controls-volume\",\n RANGE_ROOT: \"view360-range\",\n RANGE_TRACK: \"view360-range-track\",\n RANGE_THUMB: \"view360-range-thumb\",\n RANGE_FILLER: \"view360-range-filler\",\n PLAY_BUTTON: \"view360-controls-play\",\n PAUSE_BUTTON: \"view360-controls-pause\",\n UNMUTED_BUTTON: \"view360-controls-unmuted\",\n MUTED_BUTTON: \"view360-controls-muted\",\n FULLSCREEN_BUTTON: \"view360-controls-fullscreen\",\n FULLSCREEN_EXIT_BUTTON: \"view360-controls-fullscreen-exit\",\n VR_BUTTON: \"view360-controls-vr\",\n GYRO_ENABLED: \"view360-controls-gyro-enabled\",\n GYRO_DISABLED: \"view360-controls-gyro-disabled\",\n VIDEO_TIME_DISPLAY: \"view360-controls-time\",\n PIEVIEW_ROOT: \"view360-controls-pie\",\n FIXED: \"view360-controls-fixed\",\n UNAVAILABLE: \"view360-controls-unavailable\",\n HIDDEN: \"view360-controls-hidden\"\n} as const;\n\nexport const CONTROL_BAR_ITEM_POSITION = {\n /**\n * Place control bar item floating at top-left corner\n * @ko 아이템을 왼쪽 위 구석에 표시합니다.\n * @since 4.0.0\n */\n TOP_LEFT: \"top-left\",\n /**\n * Place control bar item floating at top-right corner\n * @ko 아이템을 오른쪽 위 구석에 표시합니다.\n * @since 4.0.0\n */\n TOP_RIGHT: \"top-right\",\n /**\n * Place control bar item at upper block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 위쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_TOP: \"main-top\",\n /**\n * Place control bar item at lower block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 하단 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_BOTTOM: \"main-bottom\",\n /**\n * Place control bar item at center-left block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 왼쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_LEFT: \"main-left\",\n /**\n * Place control bar item at center-right block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 오른쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_RIGHT: \"main-right\"\n} as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { ControlBarOptions } from \"./ControlBar\";\nimport { CONTROL_BAR_DEFAULT_CLASS } from \"./const\";\nimport Motion from \"../../core/Motion\";\nimport MouseInput from \"../../control/input/MouseInput\";\nimport TouchInput from \"../../control/input/TouchInput\";\nimport { CONTROL_EVENTS, INFINITE_RANGE } from \"../../const/internal\";\nimport { clamp } from \"../../utils\";\nimport { InputEvents } from \"../../type/internal\";\nimport { EL_DIV } from \"../../const/browser\";\n\nclass RangeControl extends Component<{\n [CONTROL_EVENTS.INPUT_START]: number;\n [CONTROL_EVENTS.CHANGE]: number;\n [CONTROL_EVENTS.INPUT_END]: void;\n}> {\n public readonly rootEl: HTMLElement;\n public readonly thumbEl: HTMLElement;\n public readonly trackEl: HTMLElement;\n public readonly fillerEl: HTMLElement;\n\n private _motion: Motion;\n private _mouseInput: MouseInput;\n private _touchInput: TouchInput;\n private _fixedClass: string;\n private _bbox: DOMRect;\n\n /**\n *\n */\n public constructor() {\n super();\n\n const root = document.createElement(EL_DIV);\n const track = document.createElement(EL_DIV);\n const thumb = document.createElement(EL_DIV);\n const filler = document.createElement(EL_DIV);\n\n root.draggable = false;\n\n track.appendChild(filler);\n track.appendChild(thumb);\n root.appendChild(track);\n\n this.rootEl = root;\n this.trackEl = track;\n this.thumbEl = thumb;\n this.fillerEl = filler;\n\n this._mouseInput = new MouseInput();\n this._touchInput = new TouchInput();\n this._motion = new Motion({ duration: 1, range: INFINITE_RANGE, easing: x => x });\n this._bbox = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n left: 0,\n right: 0,\n bottom: 0,\n top: 0\n } as DOMRect;\n this._fixedClass = CONTROL_BAR_DEFAULT_CLASS.FIXED;\n }\n\n public init(className: Required) {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n\n this.rootEl.classList.add(className.RANGE_ROOT);\n this.trackEl.classList.add(className.RANGE_TRACK);\n this.thumbEl.classList.add(className.RANGE_THUMB);\n this.fillerEl.classList.add(className.RANGE_FILLER);\n this._fixedClass = className.FIXED;\n\n mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n touchInput.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n\n mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n touchInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n\n mouseInput.enable(this.rootEl);\n touchInput.enable(this.rootEl);\n\n this.resize();\n }\n\n public destroy() {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n\n this.rootEl.className = \"\";\n this.trackEl.className = \"\";\n this.thumbEl.className = \"\";\n this.fillerEl.className = \"\";\n\n mouseInput.off();\n touchInput.off();\n mouseInput.disable();\n touchInput.disable();\n }\n\n public resize() {\n this._bbox = this.trackEl.getBoundingClientRect();\n }\n\n public updateStyle(progress: number) {\n const width = this._bbox.width;\n const clampedProgress = clamp(progress, 0, 1);\n\n this.fillerEl.style.width = `${clampedProgress * 100}%`;\n this.thumbEl.style.transform = `translateX(${clampedProgress * width}px)`;\n }\n\n private _onHold = ({ srcEvent, isTouch }: InputEvents<{ x: number; y: number }>[typeof CONTROL_EVENTS.INPUT_START]) => {\n const bbox = this._bbox;\n if (!bbox) return;\n\n const x = isTouch\n ? (srcEvent as TouchEvent).touches[0].pageX\n : (srcEvent as MouseEvent).pageX;\n const elX = bbox.x + (window.scrollX ?? window.pageXOffset);\n\n const clamepdX = clamp(x, elX, elX + bbox.width);\n const progress = (clamepdX - elX) / bbox.width;\n\n this._motion.reset(clamepdX);\n this.thumbEl.classList.add(this._fixedClass);\n\n this.trigger(CONTROL_EVENTS.INPUT_START, progress);\n };\n\n private _onChange = ({ delta }: InputEvents<{ x: number; y: number }>[typeof CONTROL_EVENTS.CHANGE]) => {\n const motion = this._motion;\n const bbox = this._bbox;\n if (!bbox) return;\n\n motion.setNewEndByDelta(delta.x);\n motion.update(1);\n\n const elX = bbox.x + (window.scrollX ?? window.pageXOffset);\n const clampedX = clamp(motion.val, elX, elX + bbox.width);\n const progress = (clampedX - elX) / bbox.width;\n\n this.trigger(CONTROL_EVENTS.CHANGE, progress);\n };\n\n private _onRelease = () => {\n const bbox = this._bbox;\n if (!bbox) return;\n\n this.thumbEl.classList.remove(this._fixedClass);\n\n this.trigger(CONTROL_EVENTS.INPUT_END);\n };\n}\n\nexport default RangeControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport RangeControl from \"./RangeControl\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport { CONTROL_EVENTS, VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport { EVENTS } from \"../../const/external\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show video progress bar.\n * @ko 비디오의 프로그레스 바를 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass ProgressBar extends ControlBarItem {\n public get element() { return this._rangeControl.rootEl; }\n\n private _controlBar: ControlBar | null;\n private _video: TextureVideo | null;\n private _rangeControl: RangeControl;\n\n private _wasPaused: boolean;\n private _currentTime: number;\n private _duration: number;\n private _playPromise: Promise | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_TOP,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.position = position;\n this.order = order;\n\n this._controlBar = null;\n this._rangeControl = new RangeControl();\n\n this._video = null;\n this._wasPaused = false;\n this._currentTime = 0;\n this._duration = 0;\n this._playPromise = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const element = this.element;\n const rangeControl = this._rangeControl;\n const unavailableClass = controlBar.className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n element.classList.add(unavailableClass);\n return;\n }\n\n element.classList.remove(unavailableClass);\n element.classList.add(controlBar.className.PROGRESS_ROOT);\n viewer.on(EVENTS.RESIZE, this._onResize);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate);\n rangeControl.init(controlBar.className);\n rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n rangeControl.on(CONTROL_EVENTS.CHANGE, this._onControl);\n rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n this._video = video;\n this._currentTime = video.source.currentTime;\n this._duration = video.source.duration;\n this._controlBar = controlBar;\n\n rangeControl.updateStyle(this._currentTime / this._duration);\n }\n\n public destroy(viewer: View360) {\n const video = this._video;\n\n viewer.off(EVENTS.RESIZE, this._onResize);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate);\n }\n\n this._rangeControl.destroy();\n this._video = null;\n this._playPromise = null;\n }\n\n private _onResize = () => {\n this._rangeControl.resize();\n }\n\n private _onTimeUpdate = () => {\n const video = this._video;\n if (!video) return;\n\n this._currentTime = video.source.currentTime;\n this._rangeControl.updateStyle(this._currentTime / this._duration);\n };\n\n private _onDurationChange = () => {\n const video = this._video;\n if (!video) return;\n\n this._duration = video.source.duration;\n this._rangeControl.updateStyle(this._currentTime / this._duration);\n };\n\n private _onHold = (progress: number) => {\n const video = this._video;\n const controlBar = this._controlBar;\n if (!video || !controlBar) return;\n\n const paused = video.isPaused();\n\n video.source.pause();\n\n const time = video.source.duration * progress;\n video.source.currentTime = time;\n video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time }}));\n\n controlBar.rootEl.classList.add(controlBar.className.FIXED);\n this._wasPaused = !this._playPromise && paused;\n };\n\n private _onControl = (progress: number) => {\n const video = this._video;\n if (!video) return;\n\n const time = video.source.duration * progress;\n video.source.currentTime = time;\n video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time }}));\n };\n\n private _onRelease = () => {\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (video && controlBar) {\n if (!this._wasPaused && !this._playPromise) {\n this._playPromise = video.source.play()\n .catch(() => void 0);\n\n // This should not be chained\n this._playPromise.then(() => {\n this._playPromise = null;\n });\n\n controlBar.rootEl.classList.remove(controlBar.className.FIXED);\n }\n }\n\n this._wasPaused = false;\n };\n}\n\nexport default ProgressBar;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show video play / pause button.\n * @ko 비디오 재생 / 일시정지 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass PlayButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _controlBar: ControlBar | null;\n private _video: TextureVideo | null;\n private _paused: boolean;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n\n this._video = null;\n this._paused = true;\n this._controlBar = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const video = viewer.projection?.getTexture();\n const className = controlBar.className;\n const unavailableClass = className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n element.classList.add(unavailableClass);\n return;\n }\n\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.remove(unavailableClass);\n\n const paused = video.isPaused();\n this._video = video;\n this._paused = paused;\n this._controlBar = controlBar;\n\n if (paused) {\n this._onPause();\n } else {\n this._onPlay();\n }\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onPlay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onPause);\n }\n\n public destroy() {\n const video = this._video;\n const element = this.element;\n\n if (!video) return;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onPlay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onPause);\n\n this._video = null;\n this._paused = true;\n this._controlBar = null;\n }\n\n private _onClick = () => {\n const video = this._video;\n if (!video) return;\n\n if (this._paused) {\n video.source.play();\n } else {\n video.source.pause();\n }\n };\n\n private _onPlay = () => {\n if (!this._controlBar) return;\n\n const element = this.element;\n const className = this._controlBar.className;\n\n element.classList.add(className.PAUSE_BUTTON);\n element.classList.remove(className.PLAY_BUTTON);\n element.title = \"Pause Video\";\n\n this._paused = false;\n };\n\n private _onPause = () => {\n if (!this._controlBar) return;\n\n const element = this.element;\n const className = this._controlBar.className;\n\n element.classList.add(className.PLAY_BUTTON);\n element.classList.remove(className.PAUSE_BUTTON);\n element.title = \"Play Video\";\n\n this._paused = true;\n };\n}\n\nexport default PlayButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport RangeControl from \"./RangeControl\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { EVENTS } from \"../../const/external\";\n\n/**\n * Show video volume control.\n * @ko 비디오 볼륨 조절 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VolumeControl extends ControlBarItem {\n public get element() { return this._rootEl; }\n\n private _controlBar: ControlBar | null;\n private _rootEl: HTMLButtonElement;\n private _buttonEl: HTMLElement;\n private _rangeControl: RangeControl;\n private _video: TextureVideo | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this._controlBar = null;\n this._rangeControl = new RangeControl();\n this._createElements();\n\n this._video = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const root = this._rootEl;\n const button = this._buttonEl;\n const rangeControl = this._rangeControl;\n const className = controlBar.className;\n const unavailableClass = className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n root.classList.add(unavailableClass);\n return;\n }\n\n root.classList.remove(unavailableClass);\n root.classList.add(className.CONTROLS_BUTTON);\n root.classList.add(className.VOLUME_ROOT);\n button.classList.add(className.CONTROLS_BUTTON);\n\n if (video.source.muted) {\n button.classList.add(className.MUTED_BUTTON);\n } else {\n button.classList.add(className.UNMUTED_BUTTON);\n }\n\n viewer.on(EVENTS.RESIZE, this._onResize);\n root.addEventListener(BROWSER.EVENTS.TRANSITION_END, this._onResize);\n button.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_VOLUME_CHANGE, this._onVolumeChange);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_LOADED_DATA, this._updateDisplay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay);\n\n rangeControl.init(className);\n rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n rangeControl.on(CONTROL_EVENTS.CHANGE, this._onChange);\n rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n this._controlBar = controlBar;\n this._video = video;\n\n this._updateDisplay();\n }\n\n public destroy(viewer: View360) {\n const video = this._video;\n const button = this._buttonEl;\n const root = this._rootEl;\n\n root.className = \"\";\n button.className = \"\";\n\n viewer.off(EVENTS.RESIZE, this._onResize);\n root.removeEventListener(BROWSER.EVENTS.TRANSITION_END, this._onResize);\n button.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_VOLUME_CHANGE, this._onVolumeChange);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_LOADED_DATA, this._updateDisplay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay);\n }\n\n this._controlBar = null;\n this._rangeControl.destroy();\n this._video = null;\n }\n\n private _onResize = () => {\n this._rangeControl.resize();\n this._updateDisplay();\n }\n\n private _onClick = () => {\n const video = this._video;\n if (!video || this._rootEl.disabled) return;\n\n video.source.muted = !video.source.muted;\n };\n\n private _onVolumeChange = () => {\n const button = this._buttonEl;\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (!video || !controlBar) return;\n\n const className = controlBar.className;\n\n if (video.source.muted || video.source.volume === 0) {\n button.classList.add(className.MUTED_BUTTON);\n button.classList.remove(className.UNMUTED_BUTTON);\n } else {\n button.classList.add(className.UNMUTED_BUTTON);\n button.classList.remove(className.MUTED_BUTTON);\n }\n\n this._updateDisplay();\n };\n\n private _createElements() {\n const root = document.createElement(BROWSER.EL_BUTTON);\n const buttonEl = document.createElement(BROWSER.EL_DIV);\n\n root.appendChild(this._rangeControl.rootEl);\n root.appendChild(buttonEl);\n root.title = \"Toggle Mute\";\n\n this._rootEl = root;\n this._buttonEl = buttonEl;\n }\n\n private _onHold = (progress: number) => {\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (!video || !controlBar) return;\n\n const className = controlBar.className;\n\n video.source.volume = progress;\n\n this._rootEl.classList.add(className.FIXED);\n controlBar.containerEl.classList.add(className.FIXED);\n\n this._updateDisplay();\n };\n\n private _onChange = (progress: number) => {\n const video = this._video;\n if (!video) return;\n\n video.source.volume = progress;\n if (progress > 0) {\n video.source.muted = false;\n } else {\n video.source.muted = true;\n }\n\n this._updateDisplay();\n };\n\n private _onRelease = () => {\n const controlBar = this._controlBar;\n if (!controlBar) return;\n\n const className = controlBar.className;\n\n this._rootEl.classList.remove(className.FIXED);\n controlBar.containerEl.classList.remove(className.FIXED);\n };\n\n private _updateDisplay = () => {\n const video = this._video;\n const root = this._rootEl;\n if (!video) return;\n\n if (!video.hasAudio()) {\n root.disabled = true;\n return;\n }\n\n root.disabled = false;\n\n const volume = video.source.muted ? 0 : video.source.volume;\n\n this._rangeControl.updateStyle(volume);\n };\n}\n\nexport default VolumeControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport { isFullscreen } from \"../../utils\";\n\n/**\n * Show fullscreen enter / exit button.\n * @ko 풀스크린 진입 / 해제 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass FullscreenButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _controlBar: ControlBar | null;\n private _targetEl: HTMLElement | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n this.element.title = \"Toggle Fullscreen\";\n this._controlBar = null;\n this._targetEl = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n if (!this._fullscreenAvailable()) {\n element.classList.add(className.UNAVAILABLE);\n return;\n }\n\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.remove(className.UNAVAILABLE);\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._addFullscreenHandlers();\n\n if (isFullscreen()) {\n element.classList.add(className.FULLSCREEN_EXIT_BUTTON);\n } else {\n element.classList.add(className.FULLSCREEN_BUTTON);\n }\n\n this._controlBar = controlBar;\n this._targetEl = viewer.rootEl;\n }\n\n public destroy() {\n const element = this.element;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._removeFullscreenHandlers();\n\n this._controlBar = null;\n this._targetEl = null;\n }\n\n private _onClick = () => {\n const target = this._targetEl;\n if (!target) return;\n\n if (isFullscreen()) {\n this._exitFullscreen();\n } else {\n this._requestFullscreen(target);\n }\n };\n\n private _fullscreenAvailable() {\n return BROWSER.FULLSCREEN_REQUEST.some(key => !!document[key]);\n }\n\n private _requestFullscreen(el: HTMLElement) {\n for (const key of BROWSER.FULLSCREEN_REQUEST) {\n const request = el[key];\n if (request) {\n request.call(el);\n return;\n }\n }\n }\n\n private _exitFullscreen() {\n for (const key of BROWSER.FULLSCREEN_EXIT) {\n const exit = document[key];\n\n if (exit) {\n exit.call(document);\n return;\n }\n }\n }\n\n private _addFullscreenHandlers() {\n BROWSER.FULLSCREEN_CHANGE.forEach(evtName => {\n document.addEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _removeFullscreenHandlers() {\n BROWSER.FULLSCREEN_CHANGE.forEach(evtName => {\n document.removeEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _onFullscreenChange = () => {\n const element = this.element;\n const controlBar = this._controlBar;\n\n if (!controlBar) return;\n\n const className = controlBar.className;\n\n if (isFullscreen()) {\n element.classList.add(className.FULLSCREEN_EXIT_BUTTON);\n element.classList.remove(className.FULLSCREEN_BUTTON);\n } else {\n element.classList.add(className.FULLSCREEN_BUTTON);\n element.classList.remove(className.FULLSCREEN_EXIT_BUTTON);\n }\n };\n}\n\nexport default FullscreenButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\n\n/**\n * Show video current / total time.\n * @ko 비디오의 현재 / 총 재생시간을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VideoTime extends ControlBarItem {\n public readonly element: HTMLElement;\n private _video: TextureVideo | null;\n private _currentTime: number;\n private _duration: number;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n\n this._video = null;\n this._currentTime = 0;\n this._duration = 0;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const element = this.element;\n const className = controlBar.className;\n\n if (!video || !video.isVideo()) {\n element.classList.add(className.UNAVAILABLE);\n return;\n }\n\n element.classList.add(className.VIDEO_TIME_DISPLAY);\n element.classList.remove(className.UNAVAILABLE);\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange);\n\n this._video = video;\n this._currentTime = video.source.currentTime;\n this._duration = video.source.duration;\n\n this._updateDisplay();\n }\n\n public destroy() {\n const video = this._video;\n\n if (!video) return;\n\n this.element.className = \"\";\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange);\n\n this._video = null;\n }\n\n private _onTimeUpdate = () => {\n const video = this._video;\n if (!video) return;\n\n this._currentTime = video.source.currentTime;\n this._updateDisplay();\n };\n\n private _onDurationChange = () => {\n const video = this._video;\n if (!video) return;\n\n this._duration = video.source.duration;\n this._updateDisplay();\n };\n\n private _onCustomTimeChange = (evt: CustomEvent<{ time: number }>) => {\n this._currentTime = evt.detail.time;\n this._updateDisplay();\n };\n\n private _updateDisplay() {\n const time = this._currentTime;\n const timeMinute = Math.floor(time / 60);\n const timeSeconds = Math.floor(time - timeMinute * 60);\n const timeSecondsFormatted = timeSeconds < 10 ? `0${timeSeconds}` : timeSeconds;\n\n const duration = this._duration;\n const durationMinute = Math.floor(duration / 60);\n const durationSeconds = Math.floor(duration - durationMinute * 60);\n const durationSecondsFormatted = durationSeconds < 10 ? `0${durationSeconds}` : durationSeconds;\n\n this.element.innerText = `${timeMinute}:${timeSecondsFormatted} / ${durationMinute}:${durationSecondsFormatted}`;\n }\n}\n\nexport default VideoTime;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport { circulate, getObjectOption } from \"../../utils\";\nimport * as BROWSER from \"../../const/browser\";\nimport { EVENTS } from \"../../const/external\";\nimport { SVG_NAMESPACE } from \"../../const/internal\";\n\n/**\n * Options for {@link PieView}\n * @ko {@link PieView}용 옵션들\n * @category Plugin\n */\nexport interface PieViewOptions extends ControlBarItemOptions {\n /**\n * @copy PieView#resetCamera\n */\n resetCamera: boolean | Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n duration: number;\n easing: (x: number) => number;\n }>;\n}\n\n/**\n * Show camera direction/fov indicator.\n * @ko 카메라가 향하는 방향 및 FOV를 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass PieView extends ControlBarItem {\n public readonly element: HTMLElement;\n\n /**\n * Set rotation to reset camera to when PieView is clicked.\n * `false` will disable this value, and `true` will enable with default options.\n * @ko PieView가 클릭되었을 때 카메라를 리셋할 방향을 지정합니다.\n * `false`일 경우 이 동작을 비활성화하며, `true`일 경우 기본값을 사용합니다.\n * @since 4.0.0\n */\n public resetCamera: PieViewOptions[\"resetCamera\"];\n\n private _viewer: View360 | null;\n private _piePathEl: SVGPathElement;\n private _rangeCircleEl: SVGCircleElement;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n resetCamera = true,\n position = CONTROL_BAR_ITEM_POSITION.TOP_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n this.element.title = \"Reset view\";\n this.resetCamera = resetCamera;\n this._createPieElements();\n this._viewer = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n\n if (!viewer.initialized) {\n viewer.once(EVENTS.READY, this._updatePie);\n } else {\n this._updatePie({ target: viewer });\n }\n\n const rootClass = controlBar.className.PIEVIEW_ROOT;\n element.classList.add(rootClass);\n\n if (this.resetCamera) {\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n }\n\n viewer.on(EVENTS.VIEW_CHANGE, this._updatePie);\n\n this._viewer = viewer;\n }\n\n public destroy(viewer: View360) {\n const element = this.element;\n\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.className = \"\";\n viewer.off(EVENTS.READY, this._updatePie);\n viewer.off(EVENTS.VIEW_CHANGE, this._updatePie);\n\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n const resetCamera = this.resetCamera;\n\n if (!viewer || !resetCamera) return;\n\n const {\n yaw = viewer.initialYaw,\n pitch = viewer.initialPitch,\n zoom = viewer.initialZoom,\n duration = 500\n } = getObjectOption(resetCamera);\n\n viewer.camera.animateTo({\n yaw,\n pitch,\n zoom,\n duration\n });\n };\n\n private _createPieElements() {\n const root = this.element;\n const pieSVG = document.createElementNS(SVG_NAMESPACE, \"svg\");\n pieSVG.setAttribute(\"viewBox\", \"0 0 48 48\");\n pieSVG.setAttribute(\"width\", \"100%\");\n pieSVG.setAttribute(\"height\", \"100%\");\n\n const piePath = document.createElementNS(SVG_NAMESPACE, \"circle\");\n\n piePath.setAttribute(\"stroke\", \"currentColor\");\n piePath.setAttribute(\"fill\", \"transparent\");\n piePath.setAttribute(\"cx\", \"24\");\n piePath.setAttribute(\"cy\", \"24\");\n piePath.setAttribute(\"r\", \"12\");\n piePath.setAttribute(\"stroke-width\", \"24\");\n pieSVG.appendChild(piePath);\n\n const rangeCircle = document.createElementNS(SVG_NAMESPACE, \"circle\");\n\n rangeCircle.setAttribute(\"stroke\", \"currentColor\");\n rangeCircle.setAttribute(\"fill\", \"transparent\");\n rangeCircle.setAttribute(\"cx\", \"24\");\n rangeCircle.setAttribute(\"cy\", \"24\");\n rangeCircle.setAttribute(\"r\", \"22.5\");\n rangeCircle.setAttribute(\"stroke-width\", \"3\");\n pieSVG.appendChild(rangeCircle);\n\n root.appendChild(pieSVG);\n\n this._piePathEl = piePath;\n this._rangeCircleEl = rangeCircle;\n }\n\n private _updatePie = ({ target: viewer }: { target: View360 }) => {\n const piePath = this._piePathEl;\n const rangeCircle = this._rangeCircleEl;\n const camera = viewer.camera;\n const fov = camera.getHorizontalFov();\n const yawRange = camera.getYawRange(camera.zoom);\n const halfFov = fov * 0.5;\n\n const pieRadius = 24 * Math.PI;\n const pieDeg = pieRadius * fov / 360;\n const pieOffset = pieRadius * (camera.yaw + halfFov + 90) / 360;\n\n piePath.setAttribute(\"stroke-dasharray\", `${pieDeg} ${pieRadius - pieDeg}`);\n piePath.setAttribute(\"stroke-dashoffset\", `${pieOffset}`);\n\n if (isFinite(yawRange.min) && isFinite(yawRange.max)) {\n const radius = 45 * Math.PI; // 2 * PI * r\n const min = (circulate(yawRange.min, -180, 180) - halfFov) / 360;\n const max = (circulate(yawRange.max, -180, 180) + halfFov) / 360;\n\n const rangeDiff = radius * Math.abs(max - min);\n const offset = -radius * (min - 0.25);\n\n rangeCircle.setAttribute(\"stroke-dasharray\", `${rangeDiff} ${radius - rangeDiff}`);\n rangeCircle.setAttribute(\"stroke-dashoffset\", `${offset}`);\n } else {\n rangeCircle.setAttribute(\"stroke-dasharray\", \"\");\n rangeCircle.setAttribute(\"stroke-dashoffset\", \"\");\n }\n };\n}\n\nexport default PieView;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show VR enter button.\n * @ko VR 진입 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VRButton extends ControlBarItem {\n public readonly element: HTMLElement;\n\n private _viewer: View360 | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n this.element.title = \"Enter VR\";\n this._viewer = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n element.classList.add(className.UNAVAILABLE);\n element.classList.add(className.VR_BUTTON);\n element.classList.add(className.CONTROLS_BUTTON);\n\n viewer.vr.isAvailable()\n .then(available => {\n if (available) {\n element.classList.remove(className.UNAVAILABLE);\n }\n });\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._viewer = viewer;\n }\n\n public destroy() {\n const element = this.element;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n if (!viewer) return;\n\n viewer.vr.enter();\n };\n}\n\nexport default VRButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport GyroControl from \"../../control/GyroControl\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { sensorCanBeEnabledIOS } from \"../../utils\";\n\n/**\n * Show gyroscope control enable / disable button\n * @ko 자이로스코프 컨트롤 활성화 / 비활성화 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass GyroButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _viewer: View360 | null;\n private _controlBar: ControlBar | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n this.element.title = \"Toggle gyroscope control\";\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.add(className.UNAVAILABLE);\n\n const enableButton = () => {\n element.classList.remove(className.UNAVAILABLE);\n viewer.control.gyro.on(CONTROL_EVENTS.ENABLE, this._updateStyle);\n viewer.control.gyro.on(CONTROL_EVENTS.DISABLE, this._updateStyle);\n };\n\n if (sensorCanBeEnabledIOS()) {\n enableButton();\n } else {\n GyroControl.isAvailable().then(available => {\n if (!available) return;\n enableButton();\n });\n }\n\n this._controlBar = controlBar;\n this._viewer = viewer;\n this._updateStyle();\n }\n\n public destroy(viewer: View360) {\n const element = this.element;\n\n viewer.control.gyro.off(CONTROL_EVENTS.ENABLE, this._updateStyle);\n viewer.control.gyro.off(CONTROL_EVENTS.DISABLE, this._updateStyle);\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.className = \"\";\n\n this._controlBar = null;\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n const controlBar = this._controlBar;\n\n if (!viewer || !controlBar) return;\n\n const gyroControl = viewer.control.gyro;\n if (gyroControl.enabled) {\n gyroControl.disable();\n } else {\n GyroControl.requestSensorPermission().then(available => {\n if (available) {\n gyroControl.enable();\n } else {\n this.element.classList.add(controlBar.className.UNAVAILABLE);\n }\n });\n }\n };\n\n private _updateStyle = () => {\n const element = this.element;\n const viewer = this._viewer;\n const controlBar = this._controlBar;\n\n if (!viewer || !controlBar) return;\n\n const gyroControl = viewer.control.gyro;\n const className = controlBar.className;\n\n if (gyroControl.enabled) {\n element.classList.add(className.GYRO_ENABLED);\n element.classList.remove(className.GYRO_DISABLED);\n } else {\n element.classList.add(className.GYRO_DISABLED);\n element.classList.remove(className.GYRO_ENABLED);\n }\n };\n}\n\nexport default GyroButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport { FULLSCREEN_CHANGE } from \"../../const/browser\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport { isFullscreen } from \"../../utils\";\n\n/**\n * Options for ControlBar's {@link ControlBarOptions#autoHide}\n * @ko ControlBar의 {@link ControlBarOptions#autoHide}용 옵션\n * @category Plugin\n * @since 4.0.0\n */\nexport interface AutoHideOptions {\n /**\n * Initial delay before the control bar hides (ms)\n * @ko 컨트롤바가 처음으로 표시되고 사라지기까지 걸리는 시간 (ms)\n * @default 3000\n * @since 4.0.0\n */\n initialDelay: number;\n /**\n * Delay time before hiding the control bar after mouse leave (ms)\n * @ko 마우스가 컨트롤바 영역을 떠난 뒤 컨트롤바가 사라지기까지 걸리는 시간 (ms)\n * @default 0\n * @since 4.0.0\n */\n delay: number;\n /**\n * Delay time before hiding the control bar becomes active, like touch on mobile device or mouse move in fullscreen mode (ms)\n * @ko 모바일이나 풀스크린 환경 등에서 사용자 입력이 없을 때 컨트롤바가 사라지기까지 걸리는 시간 (ms)\n * @default 3000\n * @since 4.0.0\n */\n idleDelay: number;\n}\n\nclass AutoHide {\n private _initialDelay: AutoHideOptions[\"initialDelay\"];\n private _delay: AutoHideOptions[\"delay\"];\n private _idleDelay: AutoHideOptions[\"idleDelay\"];\n\n private _controlBar: ControlBar;\n private _timer: number;\n private _isGrabbing: boolean;\n private _isCursorInside: boolean;\n private _isFullscreen: boolean;\n private _targetEl: HTMLElement | null;\n private _video: TextureVideo | null;\n\n public get enabled() { return !!this._targetEl; }\n public get hidden() { return this._controlBar.containerEl.classList.contains(this._hiddenClass); }\n\n private get _hiddenClass() { return this._controlBar.className.HIDDEN; }\n private get _fixedClass() { return this._controlBar.className.FIXED; }\n\n public constructor(controlBar: ControlBar, {\n initialDelay = 3000,\n delay = 0,\n idleDelay: activationDelay = 3000\n }: Partial) {\n this._controlBar = controlBar;\n this._initialDelay = initialDelay;\n this._delay = delay;\n this._idleDelay = activationDelay;\n this._timer = -1;\n this._isCursorInside = false;\n this._isGrabbing = false;\n this._isFullscreen = false;\n this._video = null;\n this._targetEl = null;\n }\n\n public enable(viewer: View360) {\n if (this._targetEl) {\n this.disable(viewer);\n }\n\n const initialDelay = this._initialDelay;\n const root = viewer.rootEl;\n\n this._targetEl = viewer.rootEl;\n this._timer = window.setTimeout(() => {\n this.hide();\n }, initialDelay);\n\n root.addEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onHold);\n root.addEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter);\n root.addEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove);\n root.addEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave);\n this._addFullscreenHandlers();\n\n const video = viewer.projection?.getTexture();\n if (!video || !video.isVideo()) {\n return;\n }\n\n if (video.isPaused()) {\n this._controlBar.containerEl.classList.add(this._fixedClass);\n }\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onVideoPlay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onVideoPause);\n\n this._video = video;\n }\n\n public disable(viewer: View360) {\n if (!this._targetEl) return;\n\n const controlBar = this._controlBar;\n const root = viewer.rootEl;\n const video = this._video;\n\n root.removeEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onHold);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave);\n this._removeFullscreenHandlers();\n\n window.clearTimeout(this._timer);\n controlBar.containerEl.classList.remove(this._fixedClass);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onVideoPlay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onVideoPause);\n }\n\n this._isCursorInside = false;\n this._isGrabbing = false;\n this._video = null;\n this._targetEl = null;\n }\n\n public show() {\n this._clearHideTimer();\n this._controlBar.containerEl.classList.remove(this._hiddenClass);\n }\n\n public showTemporaliy() {\n this.show();\n this._hideAfterDelay(this._idleDelay);\n }\n\n public hide() {\n this._clearHideTimer();\n this._controlBar.containerEl.classList.add(this._hiddenClass);\n }\n\n private _clearHideTimer() {\n if (this._timer) {\n window.clearTimeout(this._timer);\n this._timer = -1;\n }\n }\n\n private _hideAfterDelay(delay = this._delay) {\n if (this._isGrabbing || (!this._isFullscreen && this._isCursorInside)) return;\n\n this._clearHideTimer();\n if (delay <= 0) {\n this.hide();\n } else {\n this._timer = window.setTimeout(() => {\n this.hide();\n }, delay);\n }\n }\n\n private _onMouseEnter = () => {\n this._isCursorInside = true;\n this.show();\n };\n\n private _onMouseLeave = () => {\n this._isCursorInside = false;\n this._hideAfterDelay();\n };\n\n private _onMouseMove = () => {\n if (!this._isFullscreen) return;\n\n this.showTemporaliy();\n }\n\n private _onHold = (evt: PointerEvent) => {\n this._isGrabbing = true;\n\n if (evt.pointerType === \"mouse\") {\n this._isCursorInside = true;\n }\n\n window.addEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n\n this.show();\n };\n\n private _onRelease = () => {\n this._isGrabbing = false;\n\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n\n this._hideAfterDelay();\n };\n\n private _onVideoPlay = () => {\n const root = this._targetEl;\n if (!root) return;\n\n this._controlBar.containerEl.classList.remove(this._fixedClass);\n };\n\n private _onVideoPause = () => {\n const root = this._targetEl;\n if (!root) return;\n\n this._controlBar.containerEl.classList.add(this._fixedClass);\n };\n\n private _addFullscreenHandlers() {\n FULLSCREEN_CHANGE.forEach(evtName => {\n document.addEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _removeFullscreenHandlers() {\n FULLSCREEN_CHANGE.forEach(evtName => {\n document.removeEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _onFullscreenChange = () => {\n this._isFullscreen = isFullscreen();\n\n if (this._isFullscreen) {\n this._hideAfterDelay();\n }\n };\n}\n\nexport default AutoHide;\n","import TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { clamp } from \"../../utils\";\nimport { VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\n\nclass VideoControl {\n private _video: TextureVideo | null;\n\n public enable(root: HTMLElement, video: TextureVideo) {\n this._video = video;\n // capture is needed for resolving conflict with keyboard control\n root.addEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown, true);\n }\n\n public disable(root: HTMLElement) {\n this._video = null;\n root.removeEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown, true);\n }\n\n private _onKeyDown = (event: KeyboardEvent) => {\n const video = this._video;\n if (!video) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n const videoEl = video.source;\n const keyPressed = event.keyCode != null\n ? BROWSER.DIRECTION_KEY_CODE[event.keyCode]\n : BROWSER.DIRECTION_KEY_NAME[event.key];\n\n switch (keyPressed) {\n case \"LEFT\":\n case \"RIGHT\":\n return this._changeVideoTime(videoEl, keyPressed === \"RIGHT\");\n case \"UP\":\n case \"DOWN\":\n return this._changeVideoVolume(videoEl, keyPressed === \"UP\");\n }\n\n const spacePressed = event.keyCode === BROWSER.SPACE_KEY_CODE || event.key === BROWSER.SPACE_KEY_NAME;\n if (spacePressed) {\n this._toggleVideo(video);\n }\n }\n\n private _changeVideoTime(video: HTMLVideoElement, forward: boolean) {\n const delta = forward ? 5 : -5;\n\n video.currentTime += delta;\n video.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time: video.currentTime }}));\n }\n\n private _changeVideoVolume(video: HTMLVideoElement, increase: boolean) {\n const delta = increase ? 0.1 : -0.1;\n\n if (video.muted) {\n video.volume = clamp(delta, 0, 1);\n } else {\n video.volume = clamp(video.volume + delta, 0, 1);\n }\n\n if (video.volume > 0) {\n video.muted = false;\n } else {\n video.muted = true;\n }\n }\n\n private _toggleVideo(video: TextureVideo) {\n if (video.isPaused()) {\n video.source.play();\n } else {\n video.source.pause();\n }\n }\n}\n\nexport default VideoControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport ProgressBar from \"./ProgressBar\";\nimport PlayButton from \"./PlayButton\";\nimport VolumeControl from \"./VolumeControl\";\nimport FullscreenButton from \"./FullscreenButton\";\nimport VideoTime from \"./VideoTime\";\nimport PieView, { PieViewOptions } from \"./PieView\";\nimport VRButton from \"./VRButton\";\nimport GyroButton from \"./GyroButton\";\nimport AutoHide, { AutoHideOptions } from \"./AutoHide\";\nimport VideoControl from \"./VideoControl\";\nimport View360, { View360Events } from \"../../View360\";\nimport View360Plugin from \"../View360Plugin\";\nimport { EVENTS } from \"../../const/external\";\nimport { createElement, findIndex, getObjectOption } from \"../../utils\";\nimport { ValueOf } from \"../../type/utils\";\nimport { StaticClickEvent } from \"../../type/events\";\nimport { CONTROL_BAR_DEFAULT_CLASS, CONTROL_BAR_ITEM_POSITION } from \"./const\";\n\n/**\n * Options for {@link ControlBar}\n * @ko {@link ControlBar}용 옵션들\n * @category Plugin\n * @since 4.0.0\n */\nexport interface ControlBarOptions {\n /**\n * @copy ControlBar#autoHide\n */\n autoHide: boolean | Partial;\n /**\n * @copy ControlBar#showBackground\n */\n showBackground: boolean;\n /**\n * @copy ControlBar#clickToPlay\n */\n clickToPlay: boolean;\n /**\n * @copy ControlBar#keyboardControls\n */\n keyboardControls: boolean;\n /**\n * @copy ControlBar#progressBar\n */\n progressBar: boolean | Partial;\n /**\n * @copy ControlBar#playButton\n */\n playButton: boolean | Partial;\n /**\n * @copy ControlBar#volumeButton\n */\n volumeButton: boolean | Partial;\n /**\n * @copy ControlBar#fullscreenButton\n */\n fullscreenButton: boolean | Partial;\n /**\n * @copy ControlBar#videoTime\n */\n videoTime: boolean | Partial;\n /**\n * @copy ControlBar#pieView\n */\n pieView: boolean | Partial;\n /**\n * @copy ControlBar#vrButton\n */\n vrButton: boolean | Partial;\n /**\n * @copy ControlBar#gyroButton\n */\n gyroButton: boolean | Partial;\n /**\n * @copy ControlBar#className\n */\n className: Partial<{ -readonly [key in keyof typeof ControlBar.DEFAULT_CLASS]: string }>;\n /**\n * @copy ControlBar#customItems\n */\n customItems: ControlBarItem[];\n}\n\n/**\n * A plugin that displays extra buttons & controls that controls {@link View360}.\n * @ko {@link View360}에 부가적인 버튼과 컨트롤을 추가해주는 플러그인.\n * @category Plugin\n * @since 4.0.0\n */\nclass ControlBar implements View360Plugin {\n /**\n * Default class names that ControlBar uses\n * @ko ControlBar가 사용하는 디폴트 클래스 이름들\n * @since 4.0.0\n */\n public static readonly DEFAULT_CLASS = CONTROL_BAR_DEFAULT_CLASS;\n\n /**\n * Constants for {@link ControlBarItemOptions#position}\n * @ko {@link ControlBarItemOptions#position}에 사용 가능한 값들\n */\n public static readonly POSITION = CONTROL_BAR_ITEM_POSITION;\n\n /**\n * Automatically hide control bar on video plays.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 재생시 자동으로 컨트롤바를 숨깁니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly autoHide?: ControlBarOptions[\"autoHide\"];\n /**\n * Show background element.\n * @ko 배경 엘리먼트를 표시합니다.\n * @since 4.0.0\n */\n public readonly showBackground?: ControlBarOptions[\"showBackground\"];\n /**\n * Whether to play / pause video on canvas click\n * @ko 캔버스 클릭시에 비디오를 재생 / 일시정지 토글합니다.\n * @since 4.0.0\n */\n public readonly clickToPlay: ControlBarOptions[\"clickToPlay\"];\n /**\n * Enable keyboard controls for video.\n * Pressing up / down arrow will control video volume, and pressing left / right arrow will control video time.\n * @ko 비디오 키보드 컨트롤을 활성화합니다.\n * 위 / 아래 화살표키를 누를 시 비디오 볼륨을, 왼쪽 / 오른쪽 화살표키를 누를 시 비디오 시간을 조정합니다.\n * @since 4.0.0\n */\n public readonly keyboardControls: ControlBarOptions[\"keyboardControls\"];\n /**\n * Show video progress bar.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 프로그레스 바를 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly progressBar: ControlBarOptions[\"progressBar\"];\n /**\n * Show video play / pause button.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 재생 / 일시정지 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly playButton: ControlBarOptions[\"playButton\"];\n /**\n * Show video volume control button.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 볼륨 조절 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly volumeButton: ControlBarOptions[\"volumeButton\"];\n /**\n * Show fullscreen button.\n * `true` to enable with default values, `false` to disable.\n * @ko 풀스크린 진입 / 해제 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly fullscreenButton: ControlBarOptions[\"fullscreenButton\"];\n /**\n * Show video current / total time\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오의 현재 시간 / 총 시간을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly videoTime: ControlBarOptions[\"videoTime\"];\n /**\n * Show camera pie view.\n * `true` to enable with default values, `false` to disable.\n * @ko 현재 카메라가 가리키는 방향을 표시하는 파이 뷰를 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly pieView: ControlBarOptions[\"pieView\"];\n /**\n * Show VR button.\n * `true` to enable with default values, `false` to disable.\n * @ko VR 진입버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly vrButton: ControlBarOptions[\"vrButton\"];\n /**\n * Show gyroscope control enable / disable button.\n * `true` to enable with default values, `false` to disable.\n * @ko 자이로스코프 컨트롤을 활성화 / 비활성화하는 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly gyroButton: ControlBarOptions[\"gyroButton\"];\n /**\n * Override default class names.\n * @ko 디폴트 클래스 이름들을 오버라이드합니다.\n * @since 4.0.0\n */\n public readonly className: Required;\n\n /**\n * Root element of the control bar\n * @ko 컨트롤바의 루트 엘리먼트\n * @since 4.0.0\n */\n public get rootEl() { return this._rootEl; }\n /**\n * Container element of the control bar\n * @ko 컨트롤바의 컨테이너 엘리먼트\n * @since 4.0.0\n */\n public get containerEl() { return this._containerEl; }\n /**\n * Background element of the control bar\n * @ko 컨트롤바의 배경 엘리먼트\n * @since 4.0.0\n */\n public get backgroundEl() { return this._bgEl; }\n /**\n * Control bar's default items created by {@link ControlBarOptions}\n * @ko 주어진 {@link ControlBarOptions}에 의해 생성된 디폴트 아이템들\n * @since 4.0.0\n */\n public get items() { return this._items; }\n /**\n * Custom control bar items\n * @ko 커스텀 컨트롤바 아이템들을 추가합니다.\n * @since 4.0.0\n */\n public get customItems() { return this._customItems; }\n\n private _rootEl: HTMLElement;\n private _containerEl: HTMLElement;\n private _bgEl: HTMLElement;\n private _wrapperEl: Record, HTMLElement>;\n private _items: Record, ControlBarItem[]>;\n private _customItems: ControlBarItem[];\n private _autoHider: AutoHide;\n private _videoControl: VideoControl;\n\n /**\n * Create new instance of ControlBar.\n * @ko ControlBar의 새 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n autoHide,\n showBackground,\n clickToPlay = true,\n keyboardControls = true,\n progressBar = true,\n playButton = true,\n volumeButton = true,\n fullscreenButton = true,\n videoTime = true,\n pieView = true,\n vrButton = true,\n gyroButton = true,\n className = {},\n customItems = []\n }: Partial = {}) {\n this.autoHide = autoHide;\n this.showBackground = showBackground;\n this.clickToPlay = clickToPlay;\n this.keyboardControls = keyboardControls;\n this.progressBar = progressBar;\n this.playButton = playButton;\n this.volumeButton = volumeButton;\n this.fullscreenButton = fullscreenButton;\n this.videoTime = videoTime;\n this.pieView = pieView;\n this.vrButton = vrButton;\n this.gyroButton = gyroButton;\n this.className = {\n ...ControlBar.DEFAULT_CLASS,\n ...className\n };\n\n const rootClass = className.CONTROLS_ROOT ?? ControlBar.DEFAULT_CLASS.CONTROLS_ROOT;\n\n this._rootEl = createElement(rootClass);\n this._createPositionWrappers();\n this._items = Object.keys(ControlBar.POSITION).reduce((items, key) => {\n items[ControlBar.POSITION[key]] = [];\n return items;\n }, {}) as Record, ControlBarItem[]>;\n this._customItems = customItems;\n this._autoHider = new AutoHide(this, getObjectOption(autoHide));\n this._videoControl = new VideoControl();\n\n customItems.forEach(item => {\n this._items[item.position].push(item);\n });\n }\n\n public init(viewer: View360) {\n const panoRoot = viewer.rootEl;\n const controlsRoot = this._rootEl;\n const defaultItems = this._createDefaultItems();\n\n this._updateBackground(viewer);\n this._updateAutoHide(viewer);\n this._updateKeyboardHandler(viewer);\n\n panoRoot.appendChild(controlsRoot);\n this._addItem(viewer, defaultItems);\n this._addItem(viewer, this._customItems);\n\n viewer.on(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad);\n viewer.on(EVENTS.STATIC_CLICK, this._onStaticClick);\n }\n\n public destroy(viewer: View360): void {\n // Remove controls root from pano root\n const panoRoot = viewer.rootEl;\n const controlsRoot = this._rootEl;\n const items = this._items;\n\n if (controlsRoot.parentElement === panoRoot) {\n panoRoot.removeChild(controlsRoot);\n }\n\n Object.keys(items).forEach((key: ValueOf) => {\n const category = items[key];\n\n category.forEach(item => {\n item.destroy(viewer, this);\n });\n\n items[key] = [];\n });\n\n this._clearItemElements();\n this._autoHider.disable(viewer);\n this._videoControl.disable(panoRoot);\n\n viewer.off(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad);\n viewer.off(EVENTS.STATIC_CLICK, this._onStaticClick);\n }\n\n private _addItem(viewer: View360, items: ControlBarItem[]) {\n for (const item of items) {\n const category = this._items[item.position];\n const wrapper = this._wrapperEl[item.position];\n\n const nextSiblingIndex = findIndex(category, sibling => sibling.order > item.order);\n\n if (nextSiblingIndex >= 0) {\n const nextSibling = category[nextSiblingIndex].element;\n category.splice(nextSiblingIndex, 0, item);\n wrapper.insertBefore(item.element, nextSibling);\n } else {\n category.push(item);\n wrapper.appendChild(item.element);\n }\n\n item.init(viewer, this);\n }\n }\n\n private _createPositionWrappers() {\n const className = {\n ...ControlBar.DEFAULT_CLASS,\n ...this.className\n };\n const rootEl = this._rootEl;\n\n // BG & FLOATING CONTROLS\n const backgroundEl = createElement(className.CONTROLS_BG);\n const floatLeftEl = createElement(className.CONTROLS_FLOAT_LEFT);\n const floatRightEl = createElement(className.CONTROLS_FLOAT_RIGHT);\n\n rootEl.appendChild(floatLeftEl);\n rootEl.appendChild(floatRightEl);\n\n // BOTTOM CONTROLS\n const container = createElement(className.CONTROLS_MAIN);\n const topWrapper = createElement(className.CONTROLS_TOP);\n const bottomWrapper = createElement(className.CONTROLS_BOTTOM);\n const midWrapper = createElement(className.CONTROLS_MID);\n const leftControlsWrapper = createElement(className.CONTROLS_LEFT);\n const rightControlsWrapper = createElement(className.CONTROLS_RIGHT);\n\n midWrapper.appendChild(leftControlsWrapper);\n midWrapper.appendChild(rightControlsWrapper);\n container.appendChild(backgroundEl);\n container.appendChild(topWrapper);\n container.appendChild(midWrapper);\n container.appendChild(bottomWrapper);\n rootEl.appendChild(container);\n\n this._bgEl = backgroundEl;\n this._containerEl = container;\n this._wrapperEl = {\n [ControlBar.POSITION.MAIN_TOP]: topWrapper,\n [ControlBar.POSITION.MAIN_LEFT]: leftControlsWrapper,\n [ControlBar.POSITION.MAIN_RIGHT]: rightControlsWrapper,\n [ControlBar.POSITION.MAIN_BOTTOM]: bottomWrapper,\n [ControlBar.POSITION.TOP_LEFT]: floatLeftEl,\n [ControlBar.POSITION.TOP_RIGHT]: floatRightEl\n };\n }\n\n private _clearItemElements() {\n const wrappers = Object.keys(ControlBar.POSITION).map(key => ControlBar.POSITION[key]);\n\n // Remove all elements inside wrappers\n wrappers.forEach(wrapper => {\n while (wrapper.firstChild) {\n wrapper.removeChild(wrapper.firstChild);\n }\n });\n }\n\n private _onStaticClick = ({ target: viewer, isTouch }: StaticClickEvent) => {\n const autoHider = this._autoHider;\n\n if (isTouch) {\n if (!autoHider.enabled) return;\n\n if (autoHider.hidden) {\n autoHider.showTemporaliy();\n } else {\n autoHider.hide();\n }\n } else {\n if (!this.clickToPlay) return;\n\n const video = viewer.projection?.getTexture();\n if (!video || !video.isVideo()) return;\n\n if (video.isPaused()) {\n video.source.play();\n } else {\n video.source.pause();\n }\n }\n };\n\n private _onNewSrcLoad = ({ target: viewer }: View360Events[\"projectionChange\"]) => {\n const items = this._items;\n\n this._updateBackground(viewer);\n this._updateAutoHide(viewer);\n this._updateKeyboardHandler(viewer);\n\n Object.keys(items).forEach((key: ValueOf) => {\n const category = items[key];\n\n category.forEach(item => {\n item.destroy(viewer, this);\n item.init(viewer, this);\n });\n });\n };\n\n private _updateAutoHide(viewer: View360) {\n const autoHide = this.autoHide;\n const autoHider = this._autoHider;\n\n if (autoHide != null) {\n if (autoHide) {\n autoHider.enable(viewer);\n } else {\n autoHider.disable(viewer);\n }\n } else {\n // Automatically choose whether to show background by content type\n const texture = viewer.projection?.getTexture();\n\n if (texture && texture.isVideo()) {\n // Enable auto hide when content type is video\n autoHider.enable(viewer);\n } else {\n autoHider.disable(viewer);\n }\n }\n }\n\n private _updateBackground(viewer: View360) {\n const background = this._bgEl;\n const showBackground = this.showBackground;\n const hiddenClass = this.className.HIDDEN ?? ControlBar.DEFAULT_CLASS.HIDDEN;\n\n if (showBackground != null) {\n if (showBackground) {\n background.classList.remove(hiddenClass);\n } else {\n background.classList.add(hiddenClass);\n }\n } else {\n // Automatically choose whether to show background by content type\n const texture = viewer.projection?.getTexture();\n\n if (texture && texture.isVideo()) {\n // Show bg when content type is video\n background.classList.remove(hiddenClass);\n } else {\n background.classList.add(hiddenClass);\n }\n }\n }\n\n private _updateKeyboardHandler(viewer: View360) {\n const panoRoot = viewer.rootEl;\n const videoControl = this._videoControl;\n const texture = viewer.projection?.getTexture();\n\n if (this.keyboardControls && texture && texture.isVideo()) {\n videoControl.enable(panoRoot, texture);\n } else {\n videoControl.disable(panoRoot);\n }\n }\n\n private _createDefaultItems(): ControlBarItem[] {\n const items: ControlBarItem[] = [];\n\n if (this.progressBar) {\n items.push(new ProgressBar(getObjectOption(this.progressBar)));\n }\n\n if (this.playButton) {\n items.push(new PlayButton(getObjectOption(this.playButton)));\n }\n\n if (this.volumeButton) {\n items.push(new VolumeControl(getObjectOption(this.volumeButton)));\n }\n\n if (this.gyroButton) {\n items.push(new GyroButton(getObjectOption(this.gyroButton)));\n }\n\n if (this.vrButton) {\n items.push(new VRButton(getObjectOption(this.vrButton)));\n }\n\n if (this.fullscreenButton) {\n items.push(new FullscreenButton(getObjectOption(this.fullscreenButton)));\n }\n\n if (this.videoTime) {\n items.push(new VideoTime(getObjectOption(this.videoTime)));\n }\n\n if (this.pieView) {\n items.push(new PieView(getObjectOption(this.pieView)));\n }\n\n return items;\n }\n}\n\nexport default ControlBar;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Camera from \"../core/Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport Texture from \"../texture/Texture\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport { VideoConfig } from \"../type/external\";\nimport UniformCanvasCube from \"../uniform/UniformCanvasCube\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport UniformTextureCube from \"../uniform/UniformTextureCube\";\n\ntype CommonProjectionUniforms = {\n uTexture: UniformTexture2D | UniformTextureCube | UniformCanvasCube;\n}\n\n/**\n * Common option for {@link Projection}s\n * @ko {@link Projection}을 위한 공통 옵션들\n * @category Projection\n * @since 4.0.0\n */\nexport interface ProjectionOptions {\n /**\n * @copy Projection#src\n */\n src: string | HTMLElement | Array;\n /**\n * @copy Projection#video\n */\n video?: boolean | Partial;\n}\n\n/**\n * Base class for projections.\n * @ko 프로젝션 베이스 클래스.\n * @category Projection\n * @since 4.0.0\n */\nabstract class Projection {\n /**\n * Source URL to panorama image/video.\n * @ko 파노라마 이미지/비디오의 URL\n * @since 4.0.0\n */\n public readonly src: ProjectionOptions[\"src\"];\n /**\n * Properties for the video element.\n * Setting `false` will treat panorama source as an image, `true` will use default properties.\n * @ko 비디오 엘리먼트에 설정할 프로퍼티를 담는 객체.\n * @since 4.0.0\n * @example\n * Default properties\n * ```ts\n * autoplay: true\n * muted: true\n * loop: false\n * volume: 1\n * ```\n */\n public readonly video: ProjectionOptions[\"video\"];\n\n protected _mesh: TriangleMesh | null;\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n src,\n video = false\n }: ProjectionOptions) {\n this.src = src;\n this.video = video;\n this._mesh = null;\n }\n\n /**\n * Apply texture to current projection.\n * @ko 주어진 텍스쳐를 현재 프로젝션에 적용합니다.\n * @param ctx - Instance of the WebGLContext helper {@ko WebGL context 헬퍼의 인스턴스}\n * @param texture - New texture to apply {@ko 새로 적용할 텍스쳐}\n * @internal\n * @since 4.0.0\n */\n public abstract applyTexture(ctx: WebGLContext, texture: Texture): void;\n\n /**\n * Release all resources projection has.\n * This is automatically called on projection change & View360's destroy call\n * @ko 현재 갖고 있는 모든 리소스를 반환합니다.\n * 이 메소드는 프로젝션 변경 및 View360의 destroy 호출 시 자동으로 호출됩니다.\n * @param ctx\n */\n public releaseAllResources(ctx: WebGLContext) {\n this._mesh?.destroy(ctx);\n }\n\n /**\n * Update camera to match projection's settings.\n * @ko 현재 프로젝션의 세팅으로 카메라를 업데이트합니다.\n * @param camera - Instance of the camera to update {@ko 업데이트할 카메라의 인스턴스}\n * @since 4.0.0\n */\n public updateCamera(camera: Camera) {\n // Use default mode & no view restriction\n camera.resetRange();\n }\n\n /**\n * Update control to match projection's settings.\n * @ko 현재 프로젝션의 세팅으로 컨트롤을 업데이트합니다.\n * @param control - Instance of the control to update {@ko 업데이트할 컨트롤의 인스턴스}\n * @since 4.0.0\n */\n public updateControl(control: PanoControl) {\n control.ignoreZoomScale = false;\n }\n\n /**\n * Update projection.\n * @ko 현재 프로젝션 정보를 갱신합니다.\n * @param camera - Instance of the camera to reference {@ko 참조할 카메라의 인스턴스}\n * @since 4.0.0\n */\n public update(camera: Camera) {} // eslint-disable-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars\n\n /**\n * Return active texture.\n * @ko 현재 활성화된 텍스쳐를 반환합니다.\n * @internal\n * @since 4.0.0\n */\n public getTexture() {\n if (!this._mesh) return null;\n\n return this._mesh.program.uniforms.uTexture.texture;\n }\n\n /**\n * A 3D triangle mesh for projection. It's `null` until loading the `src`.\n * @ko Projection을 표시하기 위한 Mesh, src를 로드하기 전까지는 `null`입니다.\n * @since 4.0.0\n */\n public getMesh(): TriangleMesh | null {\n return this._mesh;\n }\n}\n\nexport default Projection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nabstract class Uniform {\n public needsUpdate: boolean;\n\n public constructor() {\n this.needsUpdate = true;\n }\n\n public abstract update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean): void;\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext) {\n // DO_NOTHING\n }\n}\n\nexport default Uniform;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport TextureCube from \"../texture/TextureCube\";\nimport { reorderCube } from \"../utils\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformTextureCube extends Uniform {\n public readonly texture: TextureCube;\n private _webglTexture: WebGLTexture;\n private _cubemapOrder: string;\n\n public constructor(ctx: WebGLContext, texture: TextureCube, cubemapOrder: string) {\n super();\n\n this.texture = texture;\n this._webglTexture = ctx.createWebGLCubeTexture(texture, texture.width);\n this._cubemapOrder = cubemapOrder;\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext): void {\n this.texture.destroy();\n gl.deleteTexture(this._webglTexture);\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture);\n\n const sources = reorderCube(texture.sources, this._cubemapOrder);\n sources.forEach((src, idx) => {\n if (isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src);\n } else {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src);\n }\n });\n\n if (!texture.isVideo()) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformTextureCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"../texture/Texture2D\";\nimport { range, reorderCube } from \"../utils\";\n\n/** @hidden */\nclass CubeTexturePainter {\n public readonly texture: Texture2D;\n private _renderingOrder: number[];\n private _canvas: HTMLCanvasElement;\n private _ctx: CanvasRenderingContext2D;\n private _row: number;\n private _column: number;\n private _size: number;\n\n public get size() { return this._size; }\n\n public constructor(texture: Texture2D, cubemapOrder: string) {\n this.texture = texture;\n this._renderingOrder = reorderCube(range(6), cubemapOrder);\n\n const canvas = document.createElement(\"canvas\");\n\n this._calcRenderingSize();\n\n canvas.width = this._size;\n canvas.height = this._size;\n\n this._canvas = canvas;\n this._ctx = canvas.getContext(\"2d\")!;\n }\n\n public destroy() {\n const canvas = this._canvas;\n\n // release memories\n canvas.width = 1;\n canvas.height = 1;\n this._canvas = null as any;\n }\n\n public draw(gl: WebGLRenderingContext | WebGL2RenderingContext, isWebGL2: boolean) {\n const size = this._size;\n const texture = this.texture;\n let surfaceIdx = 0;\n\n for (let row = 0; row < this._row; row++) {\n for (let column = 0; column < this._column; column++) {\n const x = size * column;\n const y = size * row;\n const renderingFace = this._renderingOrder[surfaceIdx];\n\n this._ctx.drawImage(texture.source as CanvasImageSource, x, y, size, size, 0, 0, size, size);\n\n if (isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas);\n } else {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas);\n }\n\n surfaceIdx++;\n }\n }\n }\n\n private _calcRenderingSize() {\n const {\n width,\n height\n } = this.texture;\n const aspect = width / height;\n\n if (aspect === 1 / 6) {\n this._size = width;\n this._row = 6;\n this._column = 1;\n } else if (aspect === 6) {\n this._size = height;\n this._row = 1;\n this._column = 6;\n } else if (aspect === 2 / 3) {\n this._size = width * 0.5;\n this._row = 3;\n this._column = 2;\n } else {\n this._size = width / 3;\n this._row = 2;\n this._column = 3;\n }\n }\n}\n\nexport default CubeTexturePainter;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport CubeTexturePainter from \"../core/CubeTexturePainter\";\nimport Texture2D from \"../texture/Texture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformCanvasCube extends Uniform {\n private _webglTexture: WebGLTexture;\n private _painter: CubeTexturePainter;\n\n public get texture() { return this._painter.texture; }\n\n public constructor(ctx: WebGLContext, texture: Texture2D, cubemapOrder: string) {\n super();\n\n this._painter = new CubeTexturePainter(texture as Texture2D, cubemapOrder);\n this._webglTexture = ctx.createWebGLCubeTexture(texture, this._painter.size);\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext) {\n gl.deleteTexture(this._webglTexture);\n this._painter.destroy();\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture);\n\n this._painter.draw(gl, isWebGL2);\n\n if (!texture.isVideo()) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformCanvasCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Object3D from \"./Object3D\";\nimport ShaderProgram from \"./ShaderProgram\";\nimport VertexArrayObject from \"./VertexArrayObject\";\nimport Uniform from \"../uniform/Uniform\";\nimport WebGLContext from \"./WebGLContext\";\n\n/**\n * @hidden\n */\nclass TriangleMesh = Record> extends Object3D {\n /**\n * @internal\n * Geometry data for projection\n */\n public readonly vao: VertexArrayObject;\n /**\n * @internal\n * Material(shader) data for projection\n */\n public readonly program: ShaderProgram;\n\n public constructor(vao: VertexArrayObject, program: ShaderProgram) {\n super();\n\n this.vao = vao;\n this.program = program;\n }\n\n public destroy(ctx: WebGLContext) {\n ctx.releaseVAO(this.vao);\n ctx.releaseShaderResources(this.program);\n }\n}\n\nexport default TriangleMesh;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"../uniform/Uniform\";\nimport WebGLContext from \"./WebGLContext\";\nimport { UniformLocations } from \"../type/internal\";\n\nclass ShaderProgram = Record> {\n public readonly program: WebGLProgram;\n public readonly uniforms: T;\n public readonly uniformLocations: UniformLocations;\n\n public constructor(ctx: WebGLContext, vertexShader: string, fragmentShader: string, uniforms: T) {\n this.program = ctx.createProgram(vertexShader, fragmentShader);\n this.uniforms = uniforms;\n this.uniformLocations = ctx.getUniformLocations(this.program, uniforms);\n }\n}\n\nexport default ShaderProgram;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { TypedArray } from \"../type/utils\";\n\n/**\n * @hidden\n */\nclass VertexData {\n public readonly data: T;\n public itemSize: number;\n public count: number;\n\n /** */\n public constructor(data: T, itemSize: number) {\n this.data = data;\n this.itemSize = itemSize;\n this.count = data.length / itemSize;\n }\n}\n\nexport default VertexData;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport VertexData from \"../core/VertexData\";\n\n/**\n * @hidden\n */\nabstract class Geometry {\n public readonly vertices: VertexData;\n public readonly indicies: VertexData;\n public readonly uvs: VertexData;\n\n /** */\n public constructor(vertices: number[], indicies: number[], uvs: number[]) {\n this.vertices = new VertexData(new Float32Array(vertices), 3);\n this.indicies = new VertexData(new Uint16Array(indicies), 1);\n this.uvs = new VertexData(new Float32Array(uvs), 2);\n }\n}\n\nexport default Geometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\nimport { ROTATE } from \"../const/internal\";\nimport { reorderCube } from \"../utils\";\n\n/**\n * @hidden\n */\nclass CubeGeometry extends Geometry {\n public constructor({\n order,\n rotateUV\n }: {\n order: string;\n rotateUV?: ROTATE[]\n }) {\n const vertices = [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // up\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // down\n -1, -1, 1,\n 1, -1, 1,\n 1, -1, -1,\n -1, -1, -1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n\n const indicies = [\n 0, 1, 2,\n 0, 2, 3,\n 4, 5, 6,\n 4, 6, 7,\n 8, 9, 10,\n 8, 10, 11,\n 12, 13, 14,\n 12, 14, 15,\n 16, 17, 18,\n 16, 18, 19,\n 20, 21, 22,\n 20, 22, 23\n ];\n\n const oneThird = 1 / 3;\n const coords: number[][] = [];\n\n for (let r = 1; r >= 0; r--) {\n for (let c = 0; c < 3; c++) {\n const coord = [\n c * oneThird, r * 0.5,\n (c + 1) * oneThird, r * 0.5,\n (c + 1) * oneThird, (r + 1) * 0.5,\n c * oneThird, (r + 1) * 0.5\n ];\n\n coords.push(coord);\n }\n }\n\n if (rotateUV) {\n rotateUV.forEach((degree, idx) => {\n if (degree === ROTATE.ZERO) return;\n\n const coord = coords[idx];\n let newOrder: number[];\n\n if (degree === ROTATE.CW_90) {\n newOrder = [1, 2, 3, 0];\n } else if (degree === ROTATE.CCW_90) {\n newOrder = [3, 0, 1, 2];\n } else {\n newOrder = [2, 3, 0, 1];\n }\n\n const newCoords = Array(coord.length);\n for (let uvIdx = 0; uvIdx < coord.length / 2; uvIdx++) {\n newCoords[uvIdx * 2 + 0] = coord[newOrder[uvIdx] * 2 + 0];\n newCoords[uvIdx * 2 + 1] = coord[newOrder[uvIdx] * 2 + 1];\n }\n\n coords[idx] = newCoords;\n });\n }\n\n const uvs = reorderCube(coords, order, \"BFUDRL\")\n .reduce((acc, val) => acc.concat(val), []);\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default CubeGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTextureCube from \"../uniform/UniformTextureCube\";\nimport UniformCanvasCube from \"../uniform/UniformCanvasCube\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport TextureCube from \"../texture/TextureCube\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/cube.vert\";\nimport fs from \"../shader/cube.frag\";\n\n/**\n * Options for {@link CubemapProjection}\n * @ko {@link CubemapProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CubemapProjectionOptions extends ProjectionOptions {\n /**\n * Order of the cubemap images.\n * @ko 큐브맵 이미지의 순서.\n * @since 4.0.0\n * @default \"RLUDFB\" (Right - Left - Up - Down - Front - Back)\n */\n cubemapOrder?: string;\n /**\n * Whether to flip cubemap image horizontally.\n * @ko 큐브맵 이미지를 좌우대칭할지 여부.\n * @since 4.0.0\n * @default false\n */\n cubemapFlipX?: boolean;\n}\n\n/**\n * Projection based on cubemap images, accepts both multiple or single images.\n * @ko 큐브맵 이미지 기반의 프로젝션, 단일 혹은 여러 장의 이미지를 모두 사용 가능합니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CubemapProjection extends Projection<{\n uTexture: UniformTextureCube | UniformCanvasCube;\n}> {\n private _cubemapOrder: NonNullable;\n private _cubemapFlipX: NonNullable;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CubemapProjectionOptions) {\n super(options);\n\n const {\n cubemapOrder = \"RLUDFB\",\n cubemapFlipX = false\n } = options;\n\n this._cubemapOrder = cubemapOrder;\n this._cubemapFlipX = cubemapFlipX;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const cubemapOrder = this._cubemapOrder;\n const cubemapFlipX = this._cubemapFlipX;\n const uniforms = {\n uTexture: texture.isCube()\n ? new UniformTextureCube(ctx, texture as TextureCube, cubemapOrder)\n : new UniformCanvasCube(ctx, texture as Texture2D, cubemapOrder)\n };\n\n const geometry = new CubeGeometry({\n order: cubemapOrder\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n if (cubemapFlipX) {\n mesh.scale[0] = -1;\n }\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n}\n\nexport default CubemapProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"../texture/Texture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformTexture2D extends Uniform {\n public readonly texture: Texture2D;\n private _webglTexture: WebGLTexture;\n\n public constructor(ctx: WebGLContext, texture: Texture2D) {\n super();\n\n this.texture = texture;\n this._webglTexture = ctx.createWebGLTexture(texture);\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext): void {\n this.texture.destroy();\n gl.deleteTexture(this._webglTexture);\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n const isVideo = texture.isVideo();\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._webglTexture);\n\n if (!isVideo && isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n } else {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n }\n\n if (!isVideo) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformTexture2D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link CubestripProjection}\n * @ko {@link CubestripProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CubestripProjectionOptions extends ProjectionOptions {\n /**\n * @copy CubemapProjectionOptions#cubemapOrder\n */\n cubemapOrder?: string;\n /**\n * @copy CubemapProjectionOptions#cubemapFlipX\n */\n cubemapFlipX?: boolean;\n}\n\n/**\n * Projection based on cubemap strip.\n * Slightly more efficient than {@link CubemapProjection} as it doesn't copy cubemap image to canvas while rendering.\n * Accepts only single image.\n * @ko 큐브맵 스트립 기반의 프로젝션.\n * {@link CubemapProjection}와 달리 렌더링하는 과정에 캔버스에 이미지를 복사하는 과정이 없기 때문에 살짝 더 효율적입니다.\n * 단일 이미지만 사용 가능합니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CubestripProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n private _cubemapOrder: NonNullable;\n private _cubemapFlipX: NonNullable;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CubestripProjectionOptions) {\n super(options);\n\n const {\n cubemapOrder = \"RLUDFB\",\n cubemapFlipX = false\n } = options;\n\n this._cubemapOrder = cubemapOrder;\n this._cubemapFlipX = cubemapFlipX;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const cubemapOrder = this._cubemapOrder;\n const cubemapFlipX = this._cubemapFlipX;\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n const geometry = new CubeGeometry({\n order: cubemapOrder\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n if (cubemapFlipX) {\n mesh.scale[0] = -1;\n }\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n}\n\nexport default CubestripProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass CylinderGeometry extends Geometry {\n public constructor(maxTheta: number) {\n const vertices: number[] = [];\n const indicies: number[] = [];\n const uvs: number[] = [];\n\n const height = 1;\n const radialSegments = 60;\n const halfHeight = height * 0.5;\n const heightSegments = [-halfHeight, halfHeight];\n const invRadialSegments = 1 / radialSegments;\n const angleConst = maxTheta * invRadialSegments;\n\n for (let yIdx = 0; yIdx < 2; yIdx++) {\n const y = heightSegments[yIdx];\n\n for (let lngIdx = 0; lngIdx <= radialSegments; lngIdx++) {\n const angle = lngIdx * angleConst + Math.PI - maxTheta * 0.5;\n const x = Math.cos(angle);\n const z = Math.sin(angle);\n const u = lngIdx * invRadialSegments;\n const v = yIdx;\n\n uvs.push(u, v);\n vertices.push(x, y, z);\n\n if (yIdx === 0 && lngIdx < radialSegments) {\n const a = lngIdx;\n const b = a + radialSegments + 1;\n\n indicies.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n }\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default CylinderGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n*/\nimport { quat } from \"gl-matrix\";\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport CylinderGeometry from \"../geometry/CylinderGeometry\";\nimport Camera from \"../core/Camera\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"../const/internal\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\nimport TriangleMesh from \"../core/TriangleMesh\";\n\n/**\n * Options for {@link CylindricalProjection}\n * @ko {@link CylindricalProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CylindricalProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n /**\n * Whether the panorama image covers full 360 degrees.\n * @ko 파노라마 이미지가 360도를 전부 커버하는지 여부\n * @since 4.0.0\n * @default false\n */\n partial?: boolean;\n}\n\n/**\n * Projection based on cylindrical projection.\n * This can show panorama images taken from smartphones.\n * @ko 원통 투영법 기반의 프로젝션.\n * 일반적인 스마트폰 파노라마 사진을 표시하는데 사용될 수 있습니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CylindricalProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n private _partial: boolean;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CylindricalProjectionOptions) {\n super(options);\n\n const {\n partial = false\n } = options;\n\n this._partial = partial;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const partial = this._partial;\n const { width, height } = texture;\n const aspect = width / height;\n const halfVFov = 180 / aspect;\n const cylinderHeight = partial\n ? 1\n : 2 * Math.tan(halfVFov * DEG_TO_RAD);\n const cylinderTheta = partial\n ? aspect\n : 2 * Math.PI;\n\n const geometry = new CylinderGeometry(cylinderTheta);\n const program = new ShaderProgram(ctx, vs, fs, {\n uTexture: new UniformTexture2D(ctx, texture)\n });\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n mesh.scale[1] = cylinderHeight;\n quat.identity(mesh.rotation);\n quat.rotateY(mesh.rotation, mesh.rotation, -Math.PI / 2);\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n\n public updateCamera(camera: Camera) {\n super.updateCamera(camera);\n\n const mesh = this._mesh;\n if (!mesh) return;\n\n const uTexture = mesh.program.uniforms.uTexture;\n const texture = uTexture.texture;\n const { width, height } = texture;\n const aspect = width / height;\n const halfHeight = mesh.scale[1] * 0.5;\n\n if (this._partial) {\n const restrictedYaw = 0.5 * aspect * RAD_TO_DEG;\n camera.restrictYawRange(-restrictedYaw, restrictedYaw);\n }\n\n const restrictedPitch = Math.atan2(halfHeight, 1) * RAD_TO_DEG;\n const minZoom = Math.tan(camera.fov * DEG_TO_RAD * 0.5) / (halfHeight * camera.aspect);\n\n camera.restrictPitchRange(-restrictedPitch, restrictedPitch);\n camera.restrictZoomRange(minZoom, Infinity);\n camera.restrictRenderHeight(halfHeight * 2);\n }\n}\n\nexport default CylindricalProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/eac.frag\";\nimport { ROTATE } from \"../const/internal\";\n\n/**\n * Options for {@link EquiangularProjection}\n * @ko {@link EquiangularProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface EquiangularProjectionOptions extends ProjectionOptions {}\n\n/**\n * Equi-Angular Cubemap Projection.\n * This format is used by Youtube's 360 videos.\n * @ko Equi-Angular Cubemap 프로젝션.\n * 이 포맷은 주로 Youtube의 360 비디오에 사용됩니다.\n * @since 4.0.0\n * @category Projection\n */\nclass EquiangularProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n const geometry = new CubeGeometry({\n order: \"LFRDBU\",\n rotateUV: [\n ROTATE.ZERO, ROTATE.ZERO, ROTATE.ZERO,\n ROTATE.CW_90, ROTATE.CCW_90, ROTATE.CW_90\n ]\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default EquiangularProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass SphereGeometry extends Geometry {\n /** */\n public constructor() {\n // const radius = 1;\n const widthSegments = 60;\n const heightSegments = 60;\n const ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI;\n\n const uvs: number[] = [];\n const vertices: number[] = [];\n const indicies: number[] = [];\n let latIdx: number;\n let lngIdx: number;\n\n for (latIdx = 0; latIdx <= widthSegments; latIdx++) {\n const theta = (latIdx / widthSegments - 0.5) * Math.PI;\n const sinTheta = Math.sin(theta);\n const cosTheta = Math.cos(theta);\n\n for (lngIdx = 0; lngIdx <= heightSegments; lngIdx++) {\n const phi = (lngIdx / heightSegments - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN;\n const sinPhi = Math.sin(phi);\n const cosPhi = Math.cos(phi);\n const x = cosPhi * cosTheta;\n const y = sinTheta;\n const z = sinPhi * cosTheta;\n const u = lngIdx / heightSegments;\n const v = latIdx / widthSegments;\n\n uvs.push(u, v);\n vertices.push(x, y, z);\n\n if (lngIdx !== heightSegments && latIdx !== widthSegments) {\n const a = latIdx * (heightSegments + 1) + lngIdx;\n const b = a + heightSegments + 1;\n\n indicies.push(a, a + 1, b, b, a + 1, b + 1);\n }\n }\n }\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default SphereGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport Texture2D from \"../texture/Texture2D\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport SphereGeometry from \"../geometry/SphereGeometry\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link EquirectProjection}\n * @ko {@link EquirectProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface EquirectProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n}\n\n/**\n * Projection based on equirectangular projection.\n * @ko 등 장방형 도법(Equirectangular projection) 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass EquirectProjection extends Projection<{\n uTexture: UniformTexture2D\n}> {\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: EquirectProjectionOptions) {\n super(options);\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n\n const geometry = new SphereGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default EquirectProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"./Uniform\";\n\nclass UniformFloat extends Uniform {\n public val: number;\n\n public constructor(val: number) {\n super();\n\n this.val = val;\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation) {\n gl.uniform1f(location, this.val);\n\n this.needsUpdate = false;\n }\n}\n\nexport default UniformFloat;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass PlaneGeometry extends Geometry {\n /** */\n public constructor(width: number = 2, height: number = 2, z: number = -1) {\n const halfWidth = width * 0.5;\n const halfHeight = height * 0.5;\n const vertices = [\n -halfWidth, -halfHeight, z,\n halfWidth, -halfHeight, z,\n -halfWidth, halfHeight, z,\n halfWidth, halfHeight, z\n ];\n const indicies = [\n 0, 1, 2,\n 2, 1, 3\n ];\n const uvs = [\n 0, 0,\n 1, 0,\n 0, 1,\n 1, 1\n ];\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default PlaneGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport UniformFloat from \"../uniform/UniformFloat\";\nimport Camera from \"../core/Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport Texture2D from \"../texture/Texture2D\";\nimport PlaneGeometry from \"../geometry/PlaneGeometry\";\nimport vs from \"../shader/little-planet.vert\";\nimport fs from \"../shader/little-planet.frag\";\nimport TriangleMesh from \"../core/TriangleMesh\";\n\n/**\n * Options for {@link LittlePlanetProjection}\n * @ko {@link LittlePlanetProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface LittlePlanetProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n}\n\n/**\n * Projection based on so-called \"Little planet\" or \"Tiny planet\" effect.\n * @ko \"Little planet\" 혹은 \"Tiny planet\"로 불리는 이펙트 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass LittlePlanetProjection extends Projection<{\n uTexture: UniformTexture2D;\n uYaw: UniformFloat;\n uPitch: UniformFloat;\n uZoom: UniformFloat;\n}> {\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: LittlePlanetProjectionOptions) {\n super(options);\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n texture.wrapS = WebGLRenderingContext.REPEAT;\n texture.wrapT = WebGLRenderingContext.REPEAT;\n\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture),\n uYaw: new UniformFloat(0),\n uPitch: new UniformFloat(0.5),\n uZoom: new UniformFloat(1)\n };\n\n const geometry = new PlaneGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n\n public updateControl(control: PanoControl) {\n control.ignoreZoomScale = true;\n }\n\n public update(camera: Camera) {\n const mesh = this._mesh;\n if (!mesh) return;\n\n const uniforms = mesh.program.uniforms;\n\n uniforms.uYaw.val = camera.yaw / 360;\n // Range from 0 ~ 1\n uniforms.uPitch.val = (camera.pitch / 180) + 0.5;\n uniforms.uZoom.val = camera.zoom;\n\n uniforms.uYaw.needsUpdate = true;\n uniforms.uPitch.needsUpdate = true;\n uniforms.uZoom.needsUpdate = true;\n }\n}\n\nexport default LittlePlanetProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"./Uniform\";\n\nclass UniformVector4Array extends Uniform {\n public val: number[][];\n\n public constructor(val: number[][]) {\n super();\n\n this.val = val;\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation) {\n gl.uniform4fv(location, this.val.reduce((arr, vector) => [...arr, ...vector], []));\n\n this.needsUpdate = false;\n }\n}\n\nexport default UniformVector4Array;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport SphereGeometry from \"../geometry/SphereGeometry\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport UniformVector4Array from \"../uniform/UniformVector4Array\";\nimport UniformFloat from \"../uniform/UniformFloat\";\nimport vs from \"../shader/stereoequi.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link StereoEquiProjection}\n * @ko {@link StereoEquiProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface StereoEquiProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n /**\n * Stereoscopic mode of the image\n * @ko 이미지의 스테레오스코픽 모드\n * @since 4.0.0\n * @default \"top_bottom\"\n */\n mode: typeof StereoEquiProjection.MODE[keyof typeof StereoEquiProjection.MODE]\n}\n\n/**\n * Projection based on stereo equirectangular images.\n * @ko Stereo equirectangular 이미지 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass StereoEquiProjection extends Projection<{\n uTexture: UniformTexture2D;\n uEye: UniformFloat;\n uTexScaleOffset: UniformVector4Array;\n}> {\n /**\n * Available stereoscopic modes\n * @ko 사용가능한 스테레오스코픽 모드들\n * @since 4.0.0\n */\n public static MODE = {\n /**\n * @ko 이미지가 왼쪽/오른쪽으로 구성되어있을 경우\n * @since 4.0.0\n */\n LEFT_RIGHT: \"left_right\",\n /**\n * @ko 이미지가 위/아래로 구성되어있을 경우\n * @since 4.0.0\n */\n TOP_BOTTOM: \"top_bottom\",\n } as const;\n\n private _mode: StereoEquiProjectionOptions[\"mode\"];\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: StereoEquiProjectionOptions) {\n super(options);\n\n this._mode = options.mode;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n let leftEye: number[];\n let rightEye: number[];\n\n switch (this._mode) {\n case StereoEquiProjection.MODE.LEFT_RIGHT:\n leftEye = [0.5, 1, 0, 0];\n rightEye = [0.5, 1, 0.5, 0];\n break;\n default:\n // Default, uses \"top_bottom\"\n leftEye = [1, 0.5, 0, 0];\n rightEye = [1, 0.5, 0, 0.5];\n }\n\n\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture),\n uEye: new UniformFloat(0),\n uTexScaleOffset: new UniformVector4Array([leftEye, rightEye])\n };\n\n const geometry = new SphereGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default StereoEquiProjection;\n","import Component from \"@egjs/component\";\nimport View360 from \"../View360\";\n\n/**\n * @hidden\n */\nconst withMethods = (prototype: any, attr: string) => {\n [Component.prototype, View360.prototype].forEach(proto => {\n Object.getOwnPropertyNames(proto)\n .filter(name => name.charAt(0) !== \"_\" && name !== \"constructor\")\n .forEach((name: string) => {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name)!;\n\n if (descriptor.value) {\n // Public Function\n Object.defineProperty(prototype, name, {\n value: function(...args) {\n return descriptor.value.call(this[attr], ...args);\n }\n });\n } else {\n const getterDescriptor: { get?: () => any; set?: (val: any) => void } = {};\n if (descriptor.get) {\n getterDescriptor.get = function() {\n return this[attr] && descriptor.get?.call(this[attr]);\n };\n }\n if (descriptor.set) {\n getterDescriptor.set = function(...args) {\n return descriptor.set?.call(this[attr], ...args);\n };\n }\n\n Object.defineProperty(prototype, name, getterDescriptor);\n }\n });\n });\n};\n\nexport default withMethods;\n","/**\n * @hidden\n */\nexport const getValidProps = (propsObj: any) => {\n return Object.keys(propsObj).reduce((props, propName) => {\n if (propsObj[propName] != null) {\n props[propName] = propsObj[propName];\n }\n\n return props;\n }, {});\n};\n","export const VIEW360_METHODS = [\n \"destroy\",\n \"init\",\n \"load\",\n \"resize\",\n \"addPlugins\",\n \"removePlugins\",\n \"renderFrame\",\n // @egjs/component methods\n \"on\",\n \"hasOn\",\n \"once\",\n \"off\",\n \"trigger\"\n] as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360, { View360Options, View360Events } from \"./View360\";\n\nexport * from \"./core\";\nexport * from \"./control\";\nexport * from \"./plugin\";\nexport * from \"./projection\";\nexport * from \"./hotspot\";\nexport * from \"./const/external\";\nexport * from \"./type/external\";\nexport * from \"./cfc\";\n\nexport type {\n View360Options,\n View360Events\n};\n\nexport default View360;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360, * as modules from \"./index\";\nimport { merge } from \"./utils\";\n\nmerge(View360, modules);\n\nexport default View360;\n"],"names":["View360Error","Error","constructor","message","code","Object","setPrototypeOf","prototype","name","ERROR_CODES","WRONG_TYPE","WRONG_OPTION","ELEMENT_NOT_FOUND","CANVAS_NOT_FOUND","WEBGL_NOT_SUPPORTED","FAILED_CREATE_CONTEXT_2D","PROVIDE_PROJECTION_FIRST","FAILED_LINKING_PROGRAM","INSUFFICIENT_ARGS","MESSAGES","val","types","map","type","join","optionName","query","msg","shaderLog","CODES","EVENTS","MOUSE_DOWN","MOUSE_MOVE","MOUSE_UP","TOUCH_START","TOUCH_MOVE","TOUCH_END","WHEEL","RESIZE","CONTEXT_MENU","MOUSE_ENTER","MOUSE_LEAVE","POINTER_DOWN","POINTER_MOVE","POINTER_UP","POINTER_CANCEL","POINTER_ENTER","POINTER_LEAVE","KEY_DOWN","KEY_UP","LOAD","ERROR","CLICK","DOUBLE_CLICK","CONTEXT_CREATE_ERROR","CONTEXT_LOST","CONTEXT_RESTORED","DEVICE_ORIENTATION","DEVICE_MOTION","ORIENTATION_CHANGE","VIDEO_PLAY","VIDEO_PAUSE","VIDEO_LOADED_DATA","VIDEO_VOLUME_CHANGE","VIDEO_TIME_UPDATE","VIDEO_DURATION_CHANGE","VIDEO_CAN_PLAYTHROUGH","TRANSITION_END","XR_END","EL_DIV","EL_BUTTON","MOUSE_BUTTON","CURSOR","GRAB","GRABBING","NONE","KEY_DIRECTION","DIRECTION_KEY_CODE","SPACE_KEY_CODE","DIRECTION_KEY_NAME","LEFT","UP","RIGHT","DOWN","SPACE_KEY_NAME","FULLSCREEN_REQUEST","FULLSCREEN_ELEMENT","FULLSCREEN_EXIT","FULLSCREEN_CHANGE","DEFAULT_CLASS","CONTAINER","CANVAS","CTX_LOST","IN_VR","HOTSPOT_CONTAINER","HOTSPOT","HOTSPOT_VISIBLE","HOTSPOT_FLIP_X","HOTSPOT_FLIP_Y","READY","LOAD_START","PROJECTION_CHANGE","BEFORE_RENDER","RENDER","INPUT_START","INPUT_END","VIEW_CHANGE","STATIC_CLICK","VR_START","VR_END","EASING","LINEAR","x","SINE_WAVE","Math","sin","PI","EASE_OUT_CUBIC","pow","EASE_OUT_BOUNCE","n1","d1","CAMERA_EVENTS","CHANGE","ANIMATION_END","CONTROL_EVENTS","ENABLE","DISABLE","DEG_TO_RAD","RAD_TO_DEG","DEFAULT_EASING","DEFAULT_ANIMATION_DURATION","INFINITE_RANGE","min","Infinity","max","DEFAULT_PITCH_RANGE","DEFAULT_ZOOM_RANGE","ROTATE","VIDEO_TIME_CHANGE_EVENT","SVG_NAMESPACE","SESSION_VR","XR_REFERENCE_SPACE","EPSILON","_a","Number","isString","isElement","nodeType","Node","ELEMENT_NODE","createElement","className","tag","BROWSER","el","document","classList","add","getNullableElement","parent","targetEl","parentEl","queryResult","querySelector","getElement","findCanvas","root","selector","canvas","range","end","Array","apply","undef","idx","clamp","lerp","a","b","t","circulate","size","abs","offset","merge","target","srcs","forEach","source","keys","key","value","isArray","findIndex","array","checker","length","getObjectOption","toVerticalFov","fovRadian","aspect","atan","tan","reorderCube","arr","order","defaultOrder","split","face","indexOf","index","isFullscreen","sensorCanBeEnabledIOS","DeviceMotionEvent","window","isSecureContext","hfovToZoom","baseFov","fov","renderingWidth","zoomedWidth","eulerToQuat","out","yaw","pitch","roll","quat","pitchThreshold","pitchClamped","quatToEuler","quaternion","y","z","w","x2","y2","z2","w2","unit","test","atan2","view","vec3","up","viewXZ","sqrt","Motion","_val","start","_start","_end","progress","_progress","activated","_activated","duration","_duration","loop","_loop","_range","easing","_easing","reset","update","deltaTime","prev","nextProgress","easedProgress","defaultVal","delta","setNewEndByDelta","setRange","CameraAnimation","_motion","camera","from","to","_camera","_from","_to","_finishPromise","Promise","resolve","_finish","getFinishPromise","motion","rotation","zoom","rotate","Camera","Component","_aspect","changed","_changed","yawRange","_initialYawRange","pitchRange","_initialPitchRange","zoomRange","_initialZoomRange","initialYaw","initialPitch","initialZoom","rollOffset","position","animation","_up","_yawRange","_pitchRange","_zoomRange","_updateQuaternion","viewMatrix","mat4","projectionMatrix","_maxRenderHeight","destroy","off","resize","width","height","prevAspect","updateMatrix","lookAt","prevQuaternion","prevZoom","zoomDiff","normalized","isSameRotation","animateTo","finishPromise","then","trigger","restrictYawRange","restrictPitchRange","restrictZoomRange","restrictRenderHeight","resetRange","getYawRange","yawLimit","maxRenderHeight","halfHFov","getHorizontalFov","minYaw","maxYaw","halfVFovRad","h","d","theta","getPitchRange","pitchLimit","minPitch","maxPitch","halfVFov","getVerticalFov","getZoomRange","limit","minFov","maxFov","currentFov","current","_getZoomedHorizontalFov","hFov","vFov","fovToZoom","projMatrix","upDir","viewDir","onFrameRender","MouseInput","_onMouseDown","evt","_el","button","preventDefault","focus","_prevPos","clientX","clientY","addEventListener","_onMouseMove","_onMouseUp","srcEvent","isTouch","isKeyboard","prevPos","deltaX","deltaY","removeEventListener","scrolling","enable","element","disable","TouchInput","scrollable","_scrollable","_onTouchStart","touches","_scrolling","touch","_isFirstTouch","_onTouchMove","cancelable","_onTouchEnd","passive","KeyboardInput","active","pressed","_pressed","_onKeyDown","location","KeyboardEvent","DOM_KEY_LOCATION_STANDARD","_updateKeyPress","pressedCount","_getPressedKeyCount","repeat","_onKeyUp","_clearPressedKeys","_getDeltaByPressedKeys","reduce","obj","keyName","assign","event","isEnable","keyToUpdate","keyCode","filter","RotateControl","enabled","_enabled","enableBlocked","_enableBlocked","animating","_keyboardInput","_xMotion","_yMotion","_touchInput","pointerScale","_pointerScale","keyboardScale","_keyboardScale","disablePitch","_disablePitch","disableYaw","_disableYaw","disableKeyboard","_disableKeyboard","controlEl","_onInputStart","_changedWhileDragging","inputType","_onChange","invZoomScale","_zoomScale","screenScale","_screenScale","scale","scaledX","scaledY","_onInputEnd","_controlEl","_mouseInput","_bindInputs","xMotion","yMotion","keyboardInput","updateRange","setZoomScale","hfov","vfov","control","updateCursor","sync","mouseInput","touchInput","on","WheelInput","_onWheel","stopPropagation","_inputTimer","_clearTimer","_baseScale","setTimeout","capture","clearTimeout","PinchInput","prevDistance","_prevDistance","diff","pageX","pageY","distance","ZoomControl","_wheelInput","_scale","scaledDelta","_pinchInput","wheelInput","pinchInput","ROTATE_CONSTANT","PITCH_DELTA","YAW_DELTA_BY_ROLL","YAW_DELTA_BY_YAW","targetAxis","meshPoint","GyroInput","orientationUpdated","_orientationUpdated","ignoreRoll","_ignoreRoll","_onDeviceOrientation","prevOrientation","_orientation","alpha","beta","gamma","_needsCalibrate","_calibrateSensor","_updateScreenOrientation","screen","orientation","angle","undefined","_screenOrientation","_yawOrigin","_yawOffset","_updateRotation","collectDelta","prevRotation","_toEulerDelta","setInitialRotation","yawOrigin","sensorYaw","screenAngle","world","cos","prevQuat","currentQuat","_getDeltaYaw","_getDeltaPitch","prvQ","curQ","yawDeltaByYaw","_getRotationDelta","yawDeltaByRoll","_extractPitchFromQuat","prevQ","rotateKind","curQuaternion","prevPoint","curPoint","rotateDistance","rotateDirection","meshPoint2","meshPoint3","vecU","vecV","vecN","coefficientA","coefficientB","coefficientC","projectedPrevPoint","trigonometricRatio","acos","crossVec","thetaDirection","deltaRadian","baseV","GyroControl","_input","isAvailable","onDeviceMotionChange","listenDeviceMotion","res","rotationRate","timeout","race","available","requestSensorPermission","requestPermission","permissionState","catch","_updateYawPitch","input","yawDelta","pitchDelta","PanoControl","useGrabCursor","_useGrabCursor","_setCursor","disableContextMenu","_disableContextMenu","_blockContextMenu","_restoreContextMenu","_rotateControl","wheelScrollable","_zoomControl","ignoreZoomScale","_ignoreZoomScale","gyro","_gyroControl","_preventContextMenu","_onEnable","_onDisable","_onCameraAnimationEnd","_bindEvents","rotateControl","zoomControl","gyroControl","zoomScale","newCursor","style","cursor","Texture","flipY","wrapS","WebGLRenderingContext","CLAMP_TO_EDGE","wrapT","isVideo","isCube","Texture2D","TextureVideo","video","pause","removeAttribute","load","isPaused","paused","ended","readyState","hasAudio","audioTracks","webkitAudioDecodedByteCount","mozHasAudio","TextureCube","sources","TextureLoader","_loadChecker","ImReady","src","loadVideo","loadCubeImage","imgSrc","loadImage","images","_toImageArray","_load","image","naturalWidth","naturalHeight","videoConfig","config","autoplay","muted","volume","_toVideoElement","currentTime","play","videoWidth","videoHeight","content","onLoad","loader","reject","once","errorCount","check","imgEl","Image","crossOrigin","HTMLVideoElement","playsInline","setAttribute","_appendSourceElement","sourceCount","querySelectorAll","HTMLSourceElement","sourceEl","appendChild","FrameAnimator","maxDeltaTime","context","_context","_rafId","_rafTimer","_lastUpdateTime","callback","_time","frame","time","Date","now","requestAnimationFrame","stop","cancelAnimationFrame","changeContext","AutoResizer","useResizeObserver","_useResizeObserver","onResize","_skipFirstResize","isFirstResize","_onResize","_resizeObserver","ResizeObserver","bbox","getBoundingClientRect","resizeImmediate","resizeObserver","observe","disconnect","Autoplay","playing","_interrupted","delay","_delay","delayOnMouseLeave","_delayOnMouseLeave","speed","_speed","pauseOnHover","_pauseOnHover","canInterrupt","_canInterrupt","disableOnInterrupt","_disableOnInterrupt","viewer","options","_clearTimeout","_setUninterruptedAfterDelay","_onGyroEnable","_onMouseEnter","_hovering","_onMouseLeave","_control","_element","_interruptionTimer","enableAfterDelay","XRManager","ctx","exit","_onSessionEnd","_xrSession","_xrRefSpace","_ctx","_options","xr","navigator","isSessionSupported","enter","requiredFeatures","makeXRCompatible","session","requestSession","bindXRLayer","refSpace","requestReferenceSpace","_setSession","xrSession","canRender","pose","getViewerPose","getEyeParams","glLayer","renderState","baseLayer","views","viewport","getViewport","vMatrix","transform","inverse","matrix","pMatrix","Hotspot","HotspotRenderer","rootEl","renderer","_containerEl","_renderer","_hotspots","_zoom","refresh","container","hotspotEls","slice","_parseHotspot","render","hotspots","halfWidth","halfHeight","centerTransform","zoomTransform","hotspot","relPos","remove","screenPos","vec2","yawStr","dataset","pitchStr","positionStr","parseFloat","_yawPitchToVec3","pos","defaultPos","yawRad","pitchRad","VertexArrayObject","count","geometry","indicies","buffers","WebGLContext","_canvas","maxTextureSize","_maxTextureSize","isWebGL2","_isWebGL2","supportVAO","_extensions","vao","lost","_contextLost","debug","_debug","_onContextLost","_onContextRestore","loseContext","init","gl","_getContext","_gl","getParameter","MAX_TEXTURE_SIZE","getExtension","bindBuffer","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","forceLoseContext","extension","forceRestoreContext","restoreContext","clear","COLOR_BUFFER_BIT","drawingBufferWidth","drawingBufferHeight","createVAO","shaderProgram","nativeVAO","_createNativeVAO","_createBuffer","uv","_bindNativeVAO","_supplyGeometryData","_unbindBuffers","draw","drawElements","TRIANGLES","UNSIGNED_SHORT","releaseVAO","_deleteNativeVAO","_deleteBuffer","getUniformLocations","program","uniforms","uniformLocations","locations","getUniformLocation","_getCommonUniformLocations","updateCommonUniforms","entity","mvMatrix","uniformMatrix4fv","uMVMatrix","uPMatrix","updateVRUniforms","eyeIndex","uEye","uniform1f","updateUniforms","uniform","needsUpdate","releaseShaderResources","deleteProgram","useProgram","createProgram","vertexShader","fragmentShader","vs","_compileShader","VERTEX_SHADER","fs","FRAGMENT_SHADER","attachShader","bindAttribLocation","linkProgram","getProgramParameter","LINK_STATUS","getShaderParameter","COMPILE_STATUS","getShaderInfoLog","getProgramInfoLog","deleteShader","createWebGLTexture","texData","texture","createTexture","bindTexture","TEXTURE_2D","texParameteri","TEXTURE_MIN_FILTER","TEXTURE_MAG_FILTER","TEXTURE_WRAP_S","TEXTURE_WRAP_T","gl2","texStorage2D","RGBA8","createWebGLCubeTexture","TEXTURE_CUBE_MAP","attributes","getContextAttributes","xrCompatible","xrLayer","XRWebGLLayer","updateRenderState","bindXRFrame","bindFramebuffer","FRAMEBUFFER","framebuffer","useDefaultFrameBuffer","createBuffer","buffer","deleteBuffer","createVertexArray","ext","createVertexArrayOES","bindVertexArray","bindVertexArrayOES","deleteVertexArray","deleteVertexArrayOES","_supplyIndiciesData","_supplyAttributeData","vertices","uvs","bufferData","data","STATIC_DRAW","attribute","attribLocation","getAttribLocation","vertexAttribPointer","itemSize","FLOAT","enableVertexAttribArray","shader","createShader","shaderSource","compileShader","webglIdentifiers","contextAttributes","preserveDrawingBuffer","antialias","onWebglContextCreationError","e","statusMessage","identifier","getContext","WebGLRenderer","_elementSize","pixelRatio","_pixelRatio","canvasSize","devicePixelRatio","clientWidth","clientHeight","projection","mesh","getMesh","renderVR","vr","eyeParams","eye","View360","_rootEl","_vr","_hotspot","plugins","_plugins","_projection","_initialized","initialized","_autoplay","autoInit","_autoInit","autoResize","_autoResize","canvasSelector","_canvasSelector","tabIndex","_tabIndex","_animator","updateCamera","renderFrame","autoPlayer","_emit","_renderFrameOnDemand","getTexture","_renderVRFrame","_delta","_autoResizer","_addEventHandlers","releaseAllResources","plugin","animator","_bindComponentEvents","_resizeComponents","_loadTexture","_applyProjection","hasAttribute","addPlugins","push","removePlugins","pluginIdx","splice","eventName","params","evtParams","prevProjection","applyTexture","updateControl","contentLoader","events","evtName","controlEventsToPropagate","VERSION","Object3D","LoadingSpinner","_startLoading","_container","_detachElements","parentElement","removeChild","_createElements","ring","RING","ControlBarItem","CONTROL_BAR_DEFAULT_CLASS","CONTROLS_ROOT","CONTROLS_BG","CONTROLS_MAIN","CONTROLS_TOP","CONTROLS_BOTTOM","CONTROLS_MID","CONTROLS_LEFT","CONTROLS_RIGHT","CONTROLS_FLOAT_LEFT","CONTROLS_FLOAT_RIGHT","CONTROLS_BUTTON","PROGRESS_ROOT","VOLUME_ROOT","RANGE_ROOT","RANGE_TRACK","RANGE_THUMB","RANGE_FILLER","PLAY_BUTTON","PAUSE_BUTTON","UNMUTED_BUTTON","MUTED_BUTTON","FULLSCREEN_BUTTON","FULLSCREEN_EXIT_BUTTON","VR_BUTTON","GYRO_ENABLED","GYRO_DISABLED","VIDEO_TIME_DISPLAY","PIEVIEW_ROOT","FIXED","UNAVAILABLE","HIDDEN","CONTROL_BAR_ITEM_POSITION","TOP_LEFT","TOP_RIGHT","MAIN_TOP","MAIN_BOTTOM","MAIN_LEFT","MAIN_RIGHT","RangeControl","_onHold","_bbox","elX","scrollX","pageXOffset","clamepdX","thumbEl","_fixedClass","clampedX","_onRelease","track","thumb","filler","draggable","trackEl","fillerEl","left","right","bottom","top","updateStyle","clampedProgress","ProgressBar","_rangeControl","_onTimeUpdate","_video","_currentTime","_onDurationChange","controlBar","_controlBar","dispatchEvent","CustomEvent","detail","_wasPaused","_playPromise","_onControl","rangeControl","unavailableClass","PlayButton","_onClick","_paused","_onPlay","title","_onPause","VolumeControl","_updateDisplay","disabled","_onVolumeChange","_buttonEl","containerEl","buttonEl","FullscreenButton","_targetEl","_exitFullscreen","_requestFullscreen","_onFullscreenChange","_fullscreenAvailable","_addFullscreenHandlers","_removeFullscreenHandlers","some","request","call","VideoTime","_onCustomTimeChange","timeMinute","floor","timeSeconds","timeSecondsFormatted","durationMinute","durationSeconds","durationSecondsFormatted","innerText","PieView","resetCamera","_viewer","_updatePie","piePath","_piePathEl","rangeCircle","_rangeCircleEl","halfFov","pieRadius","pieDeg","pieOffset","isFinite","radius","rangeDiff","_createPieElements","rootClass","pieSVG","createElementNS","VRButton","GyroButton","_updateStyle","enableButton","AutoHide","hidden","contains","_hiddenClass","initialDelay","idleDelay","activationDelay","_isCursorInside","show","_hideAfterDelay","_isFullscreen","showTemporaliy","_isGrabbing","pointerType","_onVideoPlay","_onVideoPause","_initialDelay","_idleDelay","_timer","hide","_clearHideTimer","VideoControl","videoEl","keyPressed","_changeVideoTime","_changeVideoVolume","spacePressed","_toggleVideo","forward","increase","ControlBar","backgroundEl","_bgEl","items","_items","customItems","_customItems","autoHide","showBackground","clickToPlay","keyboardControls","progressBar","playButton","volumeButton","fullscreenButton","videoTime","pieView","vrButton","gyroButton","_onStaticClick","autoHider","_autoHider","_onNewSrcLoad","_updateBackground","_updateAutoHide","_updateKeyboardHandler","category","item","_createPositionWrappers","POSITION","_videoControl","panoRoot","controlsRoot","defaultItems","_createDefaultItems","_addItem","_clearItemElements","wrapper","_wrapperEl","nextSiblingIndex","sibling","nextSibling","insertBefore","floatLeftEl","floatRightEl","topWrapper","bottomWrapper","midWrapper","leftControlsWrapper","rightControlsWrapper","wrappers","firstChild","background","hiddenClass","_b","videoControl","Projection","_mesh","uTexture","Uniform","UniformTextureCube","cubemapOrder","_webglTexture","_cubemapOrder","deleteTexture","pixelStorei","UNPACK_FLIP_Y_WEBGL","uniform1i","activeTexture","TEXTURE0","texSubImage2D","TEXTURE_CUBE_MAP_POSITIVE_X","RGBA","UNSIGNED_BYTE","texImage2D","CubeTexturePainter","_size","_renderingOrder","_calcRenderingSize","surfaceIdx","row","_row","column","_column","renderingFace","drawImage","UniformCanvasCube","_painter","TriangleMesh","ShaderProgram","VertexData","Geometry","Float32Array","Uint16Array","CubeGeometry","rotateUV","oneThird","coords","r","c","coord","degree","ZERO","newOrder","CW_90","CCW_90","newCoords","uvIdx","acc","concat","CubemapProjection","cubemapFlipX","_cubemapFlipX","UniformTexture2D","CubestripProjection","CylinderGeometry","maxTheta","radialSegments","heightSegments","invRadialSegments","angleConst","yIdx","lngIdx","u","v","CylindricalProjection","partial","_partial","cylinderHeight","cylinderTheta","restrictedYaw","restrictedPitch","minZoom","EquiangularProjection","SphereGeometry","widthSegments","ANGLE_CORRECTION_FOR_CENTER_ALIGN","latIdx","sinTheta","cosTheta","phi","sinPhi","cosPhi","EquirectProjection","UniformFloat","PlaneGeometry","LittlePlanetProjection","REPEAT","uYaw","uPitch","uZoom","UniformVector4Array","uniform4fv","vector","StereoEquiProjection","_mode","mode","leftEye","rightEye","MODE","LEFT_RIGHT","uTexScaleOffset","TOP_BOTTOM","withMethods","attr","proto","getOwnPropertyNames","charAt","descriptor","getOwnPropertyDescriptor","defineProperty","args","getterDescriptor","get","set","getValidProps","propsObj","props","propName","VIEW360_METHODS","modules"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"} \ No newline at end of file diff --git a/demo/release/4.0.0-beta.4/dist/view360.pkgd.min.js b/demo/release/4.0.0-beta.4/dist/view360.pkgd.min.js new file mode 100644 index 000000000..bdec0cabd --- /dev/null +++ b/demo/release/4.0.0-beta.4/dist/view360.pkgd.min.js @@ -0,0 +1,30 @@ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).View360=e()}(this,(function(){"use strict";function t(t,e,i,s){return new(i||(i=Promise))((function(n,r){function o(t){try{h(s.next(t))}catch(t){r(t)}}function a(t){try{h(s.throw(t))}catch(t){r(t)}}function h(t){var e;t.done?n(t.value):(e=t.value,e instanceof i?e:new i((function(t){t(e)}))).then(o,a)}h((s=s.apply(t,e||[])).next())}))} +/*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */function e(t){var e="function"==typeof Symbol&&Symbol.iterator,i=e&&t[e],s=0;if(i)return i.call(t);if(t&&"number"==typeof t.length)return{next:function(){return t&&s>=t.length&&(t=void 0),{value:t&&t[s++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}function i(t,e){var i="function"==typeof Symbol&&t[Symbol.iterator];if(!i)return t;var s,n,r=i.call(t),o=[];try{for(;(void 0===e||e-- >0)&&!(s=r.next()).done;)o.push(s.value)}catch(t){n={error:t}}finally{try{s&&!s.done&&(i=r.return)&&i.call(r)}finally{if(n)throw n.error}}return o}function s(){for(var t=[],e=0;e0&&(r=1/Math.sqrt(r)),t[0]=e[0]*r,t[1]=e[1]*r,t[2]=e[2]*r,t}function v(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function E(t,e,i){var s=e[0],n=e[1],r=e[2],o=i[0],a=i[1],h=i[2];return t[0]=n*h-r*a,t[1]=r*o-s*h,t[2]=s*a-n*o,t}function f(t,e,i){var s=e[0],n=e[1],r=e[2],o=i[3]*s+i[7]*n+i[11]*r+i[15];return o=o||1,t[0]=(i[0]*s+i[4]*n+i[8]*r+i[12])/o,t[1]=(i[1]*s+i[5]*n+i[9]*r+i[13])/o,t[2]=(i[2]*s+i[6]*n+i[10]*r+i[14])/o,t}function y(t,e,i){var s=i[0],n=i[1],r=i[2],o=i[3],a=e[0],h=e[1],l=e[2],c=n*l-r*h,u=r*a-s*l,_=s*h-n*a,d=n*_-r*u,m=r*c-s*_,p=s*u-n*c,g=2*o;return c*=g,u*=g,_*=g,d*=2,m*=2,p*=2,t[0]=a+c+d,t[1]=h+u+m,t[2]=l+_+p,t}function b(){var t=new l(4);return l!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t[3]=1,t}function T(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t}function R(t,e,i){var s=e[0],n=e[1],r=e[2],o=e[3],a=i[0],h=i[1],l=i[2],c=i[3];return t[0]=s*c+o*a+n*l-r*h,t[1]=n*c+o*h+r*a-s*l,t[2]=r*c+o*l+s*h-n*a,t[3]=o*c-s*a-n*h-r*l,t}function w(t,e,i){i*=.5;var s=e[0],n=e[1],r=e[2],o=e[3],a=Math.sin(i),h=Math.cos(i);return t[0]=s*h+o*a,t[1]=n*h+r*a,t[2]=r*h-n*a,t[3]=o*h-s*a,t}function C(t,e,i){i*=.5;var s=e[0],n=e[1],r=e[2],o=e[3],a=Math.sin(i),h=Math.cos(i);return t[0]=s*h-r*a,t[1]=n*h+o*a,t[2]=r*h+s*a,t[3]=o*h-n*a,t}function L(t,e,i){i*=.5;var s=e[0],n=e[1],r=e[2],o=e[3],a=Math.sin(i),h=Math.cos(i);return t[0]=s*h+n*a,t[1]=n*h-s*a,t[2]=r*h+o*a,t[3]=o*h-r*a,t}function x(t,e,i,s){var n,r,o,a,l,c=e[0],u=e[1],_=e[2],d=e[3],m=i[0],p=i[1],g=i[2],v=i[3];return(r=c*m+u*p+_*g+d*v)<0&&(r=-r,m=-m,p=-p,g=-g,v=-v),1-r>h?(n=Math.acos(r),o=Math.sin(n),a=Math.sin((1-s)*n)/o,l=Math.sin(s*n)/o):(a=1-s,l=s),t[0]=a*c+l*m,t[1]=a*u+l*p,t[2]=a*_+l*g,t[3]=a*d+l*v,t}d(),function(){var t,e=(t=new l(4),l!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0,t[3]=0),t)}();var O,A=function(t){var e=new l(4);return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e},I=function(t,e,i,s){var n=new l(4);return n[0]=t,n[1]=e,n[2]=i,n[3]=s,n},S=function(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t},P=function(t,e,i,s,n){return t[0]=e,t[1]=i,t[2]=s,t[3]=n,t},N=function(t,e){var i=e[0],s=e[1],n=e[2],r=e[3],o=i*i+s*s+n*n+r*r;return o>0&&(o=1/Math.sqrt(o)),t[0]=i*o,t[1]=s*o,t[2]=n*o,t[3]=r*o,t},M=function(t,e){var i=t[0],s=t[1],n=t[2],r=t[3],o=e[0],a=e[1],l=e[2],c=e[3];return Math.abs(i-o)<=h*Math.max(1,Math.abs(i),Math.abs(o))&&Math.abs(s-a)<=h*Math.max(1,Math.abs(s),Math.abs(a))&&Math.abs(n-l)<=h*Math.max(1,Math.abs(n),Math.abs(l))&&Math.abs(r-c)<=h*Math.max(1,Math.abs(r),Math.abs(c))};d(),p(1,0,0),p(0,1,0),b(),b(),O=new l(9),l!=Float32Array&&(O[1]=0,O[2]=0,O[3]=0,O[5]=0,O[6]=0,O[7]=0),O[0]=1,O[4]=1,O[8]=1,function(){var t=function(){var t=new l(2);return l!=Float32Array&&(t[0]=0,t[1]=0),t}()}();class D extends Error{constructor(t,e){super(t),Object.setPrototypeOf(this,D.prototype),this.name="View360Error",this.code=e}}const U={WRONG_TYPE:0,WRONG_OPTION:1,ELEMENT_NOT_FOUND:2,CANVAS_NOT_FOUND:3,WEBGL_NOT_SUPPORTED:4,FAILED_CREATE_CONTEXT_2D:5,PROVIDE_PROJECTION_FIRST:6,FAILED_LINKING_PROGRAM:7,INSUFFICIENT_ARGS:8};var B=U,F={WRONG_TYPE:(t,e)=>`${typeof t} is not a ${e.map((t=>`"${t}"`)).join(" or ")}.`,WRONG_OPTION:(t,e)=>`Bad option: given "${t}" for option "${e}".`,ELEMENT_NOT_FOUND:t=>`Element with selector "${t}" not found.`,CANVAS_NOT_FOUND:"The canvas element was not found inside the given root element.",WEBGL_NOT_SUPPORTED:"WebGL is not supported on this browser.",FAILED_CREATE_CONTEXT_2D:"Failed to create canvas 2D context",PROVIDE_PROJECTION_FIRST:'"projection" should be provided before initialization.',FAILED_LINKING_PROGRAM:(t,e)=>`Failed linking WebGL program - "${t}\nShader compile Log: ${e}`,INSUFFICIENT_ARGS:(t,e)=>`Insufficient arguments: given "${t}" for "${e}".`};const z="mousedown",V="mousemove",k="mouseup",G="touchstart",H="touchmove",Y="touchend",j="wheel",W="resize",X="contextmenu",K="mouseenter",q="mouseleave",Z="keydown",$="keyup",J="click",Q="webglcontextcreationerror",tt="webglcontextlost",et="webglcontextrestored",it="deviceorientation",st="devicemotion",nt="orientationchange",rt="play",ot="pause",at="loadeddata",ht="volumechange",lt="timeupdate",ct="durationchange",ut="canplaythrough",_t="transitionend",dt="end",mt="div",pt="button";var gt;!function(t){t[t.LEFT=0]="LEFT",t[t.MIDDLE=1]="MIDDLE",t[t.RIGHT=2]="RIGHT"}(gt||(gt={}));const vt="grab",Et="grabbing",ft="",yt=["LEFT","UP","RIGHT","DOWN"];var bt;!function(t){t[t.LEFT=37]="LEFT",t[t.UP=38]="UP",t[t.RIGHT=39]="RIGHT",t[t.DOWN=40]="DOWN"}(bt||(bt={}));const Tt={LEFT:"ArrowLeft",UP:"ArrowUp",RIGHT:"ArrowRight",DOWN:"ArrowDown"},Rt=["requestFullscreen","webkitRequestFullscreen","webkitRequestFullScreen","webkitCancelFullScreen","mozRequestFullScreen","msRequestFullscreen"],wt=["fullscreenElement","webkitFullscreenElement","webkitCurrentFullScreenElement","mozFullScreenElement","msFullscreenElement"],Ct=["exitFullscreen","webkitExitFullscreen","webkitCancelFullScreen","mozCancelFullScreen","msExitFullscreen"],Lt=["fullscreenchange","webkitfullscreenchange","mozfullscreenchange","MSFullscreenChange"],xt={CONTAINER:"view360-container",CANVAS:"view360-canvas",CTX_LOST:"view360-ctx-lost",IN_VR:"view360-vr-presenting",HOTSPOT_CONTAINER:"view360-hotspots",HOTSPOT:"view360-hotspot",HOTSPOT_VISIBLE:"view360-hotspot-visible",HOTSPOT_FLIP_X:"view360-hotspot-flip-x",HOTSPOT_FLIP_Y:"view360-hotspot-flip-y"},Ot={READY:"ready",LOAD_START:"loadStart",LOAD:"load",PROJECTION_CHANGE:"projectionChange",RESIZE:"resize",BEFORE_RENDER:"beforeRender",RENDER:"render",INPUT_START:"inputStart",INPUT_END:"inputEnd",VIEW_CHANGE:"viewChange",STATIC_CLICK:"staticClick",VR_START:"vrStart",VR_END:"vrEnd"},At={LINEAR:t=>t,SINE_WAVE:t=>Math.sin(t*Math.PI*2),EASE_OUT_CUBIC:t=>1-Math.pow(1-t,3),EASE_OUT_BOUNCE:t=>{const e=7.5625,i=2.75;return t<1/i?e*t*t:t<2/i?e*(t-=1.5/i)*t+.75:t<2.5/i?e*(t-=2.25/i)*t+.9375:e*(t-=2.625/i)*t+.984375}};var It;const St="animationEnd",Pt="inputStart",Nt="change",Mt="inputEnd",Dt="enable",Ut="disable",Bt="staticClick",Ft=Math.PI/180,zt=180/Math.PI,Vt=At.EASE_OUT_CUBIC,kt=300,Gt={min:-1/0,max:1/0},Ht={min:-90,max:90},Yt={min:.6,max:10};var jt;!function(t){t[t.ZERO=0]="ZERO",t[t.CW_90=1]="CW_90",t[t.CCW_90=2]="CCW_90",t[t.CW_180=3]="CW_180"}(jt||(jt={}));const Wt="view360videotimechange",Xt="http://www.w3.org/2000/svg",Kt="immersive-vr",qt="local",Zt=null!==(It=Number.EPSILON)&&void 0!==It?It:2220446049250313e-31,$t=t=>"string"==typeof t,Jt=(t,e=mt)=>{const i=document.createElement(e);return i.classList.add(t),i},Qt=(t,e)=>{let i=null;if($t(t)){const s=(e||document).querySelector(t);if(!s)return null;i=s}else(s=t)&&s.nodeType===Node.ELEMENT_NODE&&(i=t);var s;return i},te=(t,e,i)=>Math.max(Math.min(t,i),e),ee=(t,e,i)=>t*(1-i)+e*i,ie=(t,e,i)=>{const s=Math.abs(i-e);if(ti){t=e+(t-i)%s}return t},se=(t,e)=>{for(let i=0;i"object"==typeof t?t:{},re=(t,e)=>2*Math.atan(Math.tan(.5*t)/e),oe=(t,e,i="RLUDFB")=>i.split("").map((t=>e.indexOf(t))).map((e=>t[e])),ae=()=>{if(!document)return!1;for(const t of wt)if(document[t])return!0;return!1},he=()=>!!DeviceMotionEvent&&"requestPermission"in DeviceMotionEvent&&window.isSecureContext,le=(t,e,i,s)=>{T(t);const n=te(i,-89.99,89.99);return C(t,t,e*Ft),w(t,t,n*Ft),L(t,t,s*Ft),t},ce=t=>{const e=t[0],i=t[1],s=t[2],n=t[3],r=e*e+i*i+s*s+n*n,o=e*n-i*s;let a,h;if(o>.499995*r)a=Math.PI/2,h=2*Math.atan2(i,e);else if(o<-.499995*r)a=-Math.PI/2,h=-2*Math.atan2(i,e);else{const e=p(0,0,1),i=p(0,1,0);y(e,e,t),y(i,i,t);const s=Math.sqrt(e[0]*e[0]+e[2]*e[2]);a=Math.atan2(-e[1],s),h=Math.atan2(e[0],e[2])}return{pitch:te(a*zt,-90,90),yaw:ie(h*zt,0,360)}};class ue{get val(){return this._val}get start(){return this._start}get end(){return this._end}get progress(){return this._progress}get activated(){return this._activated}get duration(){return this._duration}set duration(t){this._duration=t}get loop(){return this._loop}set loop(t){this._loop=t}get range(){return this._range}get easing(){return this._easing}set easing(t){this._easing=t}constructor({duration:t=300,loop:e=!1,range:i={min:0,max:1},easing:s=Vt}={}){this._duration=t,this._loop=e,this._range=i,this._easing=s,this._activated=!1,this.reset(0)}update(t){if(!this._activated)return this._val=this._end,0;const e=this._start,i=this._end,s=this._duration,n=this._val,r=this._loop,o=this._progress+t/s;this._progress=r?ie(o,0,1):te(o,0,1);const a=this._easing(this._progress);return this._val=ee(e,i,a),!r&&this._progress>=1&&(this._activated=!1),this._val-n}reset(t){const e=this._range,i=te(t,e.min,e.max);this._start=i,this._end=i,this._val=i,this._progress=0,this._activated=!1}add(t){const e=this._range;this._start=te(this._start+t,e.min,e.max),this._end=te(this._end+t,e.min,e.max),this._val=te(this._val+t,e.min,e.max)}setNewEndByDelta(t){const e=this._range;this._start=this._val,this._end=te(this._end+t,e.min,e.max),this._progress=0,this._activated=!0}setRange(t,e){this._start=te(this._start,t,e),this._end=te(this._end,t,e),this._range={min:t,max:e}}}class _e{get duration(){return this._motion.duration}set duration(t){this._motion.duration=t}get easing(){return this._motion.easing}set easing(t){this._motion.easing=t}constructor(t,e,i,{duration:s=300,easing:n=Vt}={}){this._camera=t,this._motion=new ue({duration:s,easing:n,range:{min:0,max:1}}),this._from=e,this._to=i,this._finishPromise=new Promise((t=>{this._finish=t})),this._motion.setNewEndByDelta(1)}getFinishPromise(){return this._finishPromise}update(t){const e=this._camera,i=this._from,s=this._to,n=this._motion;n.update(t);const r=n.val,o=b(),a=ee(i.zoom,s.zoom,r);x(o,i.rotation,s.rotation,r),e.rotate(o,a),r>=1&&this._finish()}}class de extends o{get aspect(){return this._aspect}get changed(){return this._changed}get yawRange(){return this._initialYawRange}set yawRange(t){this._initialYawRange=t}get pitchRange(){return this._initialPitchRange}set pitchRange(t){this._initialPitchRange=t}get zoomRange(){return this._initialZoomRange}set zoomRange(t){this._initialZoomRange=t}constructor({initialYaw:t,initialPitch:e,initialZoom:i,yawRange:s,pitchRange:n,zoomRange:r,fov:o}){super(),this.yaw=t,this.pitch=e,this.zoom=i,this.rollOffset=0,this.initialYaw=t,this.initialPitch=e,this.initialZoom=i,this.position=d(),this.animation=null,this._up=p(0,1,0),this._aspect=1,this._initialYawRange=s,this._initialPitchRange=n,this._initialZoomRange=r,this._yawRange=s,this._pitchRange=n,this._zoomRange=r,this.quaternion=b(),this._updateQuaternion(),this.viewMatrix=c(),this.projectionMatrix=c(),this.fov=o,this._maxRenderHeight=-1}destroy(){this.off()}resize(t,e){const i=this._aspect;this._aspect=t/e,this._aspect!==i&&this.updateMatrix()}lookAt({yaw:t=this.yaw,pitch:e=this.pitch,zoom:i=this.zoom}){const s=A(this.quaternion),n=this.zoom;this.yaw=ie(t,0,360),this.pitch=te(e,-90,90),this.zoom=i,this._updateQuaternion();const r=Math.abs(i-n);(!M(this.quaternion,s)||r>=10*Zt)&&this.updateMatrix()}rotate(t,e=this.zoom){const i=N(b(),t),s=M(this.quaternion,i);S(this.quaternion,i);const n=this.zoom,{yaw:r,pitch:o}=ce(i);this.yaw=r,this.pitch=o,this.zoom=e;const a=Math.abs(e-n);(!s||a>=10*Zt)&&this.updateMatrix()}animateTo({yaw:e=this.yaw,pitch:i=this.pitch,zoom:s=this.zoom,duration:n=0,easing:r=Vt}={}){return t(this,void 0,void 0,(function*(){if(this.yaw===e&&this.pitch===i&&this.zoom===s)return;const t={rotation:A(this.quaternion),zoom:this.zoom},o={rotation:le(b(),e,i,this.rollOffset),zoom:s},a=new _e(this,t,o,{duration:n,easing:r}),h=a.getFinishPromise();return this.animation=a,h.then((()=>{this.animation=null,this.trigger(St,{animation:a})})),h}))}restrictYawRange(t,e){this._yawRange={min:t,max:e}}restrictPitchRange(t,e){this._pitchRange={min:t,max:e}}restrictZoomRange(t,e){this._zoomRange={min:t,max:e}}restrictRenderHeight(t){this._maxRenderHeight=t}resetRange(){this._yawRange=this._initialYawRange,this._pitchRange=this._initialPitchRange,this._zoomRange=this._initialZoomRange,this._maxRenderHeight=-1}getYawRange(t){const e=this._yawRange,i=this._maxRenderHeight;if(!e)return Gt;const s=.5*this.getHorizontalFov(t);let n=e.min,r=e.max;if(i>0){const t=re(s*Ft,this._aspect),o=.5*i,a=Math.tan(t),h=Math.sqrt((1+o*o)/(1+a*a)),l=Math.atan(Math.tan(s*Ft)*h)*zt;n=e.min+l,r=e.max-l}return n>r&&(n=0,r=0),{min:n,max:r}}getPitchRange(t){const e=this._pitchRange,i=this._maxRenderHeight;if(!e)return Ht;let s=e.min,n=e.max;if(i>0){const i=.5*this.getVerticalFov(t);s=e.min+i,n=e.max-i}return s>n&&(s=0,n=0),{min:Math.max(s,-90),max:Math.min(n,90)}}getZoomRange(){var t;const e=null!==(t=this._zoomRange)&&void 0!==t?t:Yt,i=this.getHorizontalFov(e.max),s=this.getHorizontalFov(e.min),n=this.getHorizontalFov(this.zoom);return{min:Math.max(i,1),max:Math.min(s,180),current:n}}getHorizontalFov(t=this.zoom){return this._getZoomedHorizontalFov(t)*zt}getVerticalFov(t=this.zoom){const e=this._aspect,i=this._getZoomedHorizontalFov(t);return re(i,e)*zt}fovToZoom(t){const e=this.fov;return Math.tan(Ft*e*.5)/Math.tan(Ft*t*.5)}updateMatrix(){const t=this._up,e=this._aspect,i=this.viewMatrix,s=this.projectionMatrix,n=this.position,r=this.quaternion,o=d(),a=p(0,0,-1);y(a,a,r),y(o,t,r);const l=this._getZoomedHorizontalFov(),c=re(l,e);!function(t,e,i,s){var n,r,o,a,l,c,u,_,d,m,p=e[0],g=e[1],v=e[2],E=s[0],f=s[1],y=s[2],b=i[0],T=i[1],R=i[2];Math.abs(p-b){const e=this._el;e&&t.button===gt.LEFT&&(t.preventDefault(),e.focus?e.focus():window.focus(),this._prevPos[0]=t.clientX,this._prevPos[1]=t.clientY,window.addEventListener(V,this._onMouseMove,!1),window.addEventListener(k,this._onMouseUp,!1),this.trigger(Pt,{srcEvent:t,isTouch:!1,isKeyboard:!1}))},this._onMouseMove=t=>{t.preventDefault();const e=t.clientX,i=t.clientY,s=this._prevPos,n=e-s[0],r=i-s[1];this.trigger(Nt,{delta:{x:n,y:r},isTouch:!1,isKeyboard:!1}),s[0]=e,s[1]=i},this._onMouseUp=()=>{this._prevPos[0]=0,this._prevPos[1]=0,window.removeEventListener(V,this._onMouseMove,!1),window.removeEventListener(k,this._onMouseUp,!1),this.trigger(Mt,{isTouch:!1,isKeyboard:!1,scrolling:!1})},this._el=null,this._prevPos=[0,0]}enable(t){this._el||(t.addEventListener(z,this._onMouseDown),this._el=t)}disable(){const t=this._el;t&&(t.removeEventListener(z,this._onMouseDown),window.removeEventListener(V,this._onMouseMove,!1),window.removeEventListener(k,this._onMouseUp,!1),this._el=null)}}class pe extends o{get scrollable(){return this._scrollable}set scrollable(t){this._scrollable=t}constructor(){super(),this._onTouchStart=t=>{if(t.touches.length>1||this._scrolling)return;const e=t.touches[0];this._isFirstTouch=!0,this._prevPos[0]=e.clientX,this._prevPos[1]=e.clientY,this.trigger(Pt,{srcEvent:t,isTouch:!0,isKeyboard:!1})},this._onTouchMove=t=>{if(t.touches.length>1||this._scrolling)return;const e=t.touches[0],i=this._scrollable,s=this._prevPos,n=e.clientX,r=e.clientY,o=n-s[0],a=r-s[1];if(this._isFirstTouch){if(i&&!ae()&&Math.abs(a)>Math.abs(o))return void(this._scrolling=!0);this._isFirstTouch=!1}!1!==t.cancelable&&t.preventDefault(),this.trigger(Nt,{delta:{x:o,y:a},isTouch:!0,isKeyboard:!1}),s[0]=n,s[1]=r},this._onTouchEnd=t=>{if(0!==t.touches.length)return;const e=t.touches[0],i=this._prevPos;e?(i[0]=e.clientX,i[1]=e.clientY):(i[0]=0,i[1]=0,this.trigger(Mt,{isTouch:!0,isKeyboard:!1,scrolling:this._scrolling})),!1!==t.cancelable&&t.preventDefault(),this._scrolling=!1},this._el=null,this._prevPos=[0,0],this._isFirstTouch=!1,this._scrolling=!1,this._scrollable=!1}enable(t){this._el||(t.addEventListener(G,this._onTouchStart,{passive:!1}),t.addEventListener(H,this._onTouchMove,{passive:!1}),t.addEventListener(Y,this._onTouchEnd),this._el=t)}disable(){const t=this._el;t&&(t.removeEventListener(G,this._onTouchStart),t.removeEventListener(H,this._onTouchMove),t.removeEventListener(Y,this._onTouchEnd),this._el=null)}}class ge extends o{get active(){const t=this._pressed;return t.LEFT||t.UP||t.RIGHT||t.DOWN}constructor(){super(),this._onKeyDown=t=>{if(t.location!==KeyboardEvent.DOM_KEY_LOCATION_STANDARD)return;this._updateKeyPress(t,!0);const e=this._getPressedKeyCount();e<=0||(t.preventDefault(),1!==e||t.repeat||this.trigger(Pt,{srcEvent:t,isTouch:!1,isKeyboard:!0}))},this._onKeyUp=t=>{if(t.location!==KeyboardEvent.DOM_KEY_LOCATION_STANDARD)return;this._updateKeyPress(t,!1);this._getPressedKeyCount()>0||this.trigger(Mt,{isTouch:!1,isKeyboard:!0,scrolling:!1})},this._el=null,this._clearPressedKeys()}enable(t){this._el||(t.addEventListener(Z,this._onKeyDown),t.addEventListener($,this._onKeyUp),this._el=t,this._clearPressedKeys())}disable(){const t=this._el;t&&(t.removeEventListener(Z,this._onKeyDown),t.removeEventListener($,this._onKeyUp),this._el=null,this._clearPressedKeys())}update(){const t=this._getDeltaByPressedKeys();0===t.x&&0===t.y||this.trigger(Nt,{delta:t,isTouch:!1,isKeyboard:!0})}_clearPressedKeys(){this._pressed=yt.reduce(((t,e)=>Object.assign(Object.assign({},t),{[e]:!1})),{})}_updateKeyPress(t,e){const i=this._pressed,s=null!=t.keyCode?bt[t.keyCode]:Tt[t.key];s&&(i[s]=e)}_getPressedKeyCount(){return yt.filter((t=>this._pressed[t])).length}_getDeltaByPressedKeys(){const t=this._pressed;let e=0,i=0;return t.LEFT&&(e+=1),t.RIGHT&&(e-=1),t.UP&&(i+=1),t.DOWN&&(i-=1),{x:e,y:i}}}class ve extends o{get enabled(){return this._enabled}get enableBlocked(){return this._enableBlocked}get animating(){return this._keyboardInput.active||this._xMotion.activated||this._yMotion.activated}get yaw(){return this._xMotion}get pitch(){return this._yMotion}get scrollable(){return this._touchInput.scrollable}set scrollable(t){this._touchInput.scrollable=t}get pointerScale(){return this._pointerScale}set pointerScale(t){this._pointerScale=t}get keyboardScale(){return this._keyboardScale}set keyboardScale(t){this._keyboardScale=t}get duration(){return this._duration}set duration(t){this._duration=t,this._xMotion.duration=t,this._yMotion.duration=t}get easing(){return this._easing}set easing(t){this._easing=t,this._xMotion.easing=t,this._yMotion.easing=t}get disablePitch(){return this._disablePitch}set disablePitch(t){this._disablePitch=t}get disableYaw(){return this._disableYaw}set disableYaw(t){this._disableYaw=t}get disableKeyboard(){return this._disableKeyboard}set disableKeyboard(t){this._disableKeyboard=t}constructor(t,e,{duration:i=300,easing:s=Vt,pointerScale:n=[1,1],keyboardScale:r=[1,1],disablePitch:o=!1,disableYaw:a=!1,disableKeyboard:h=!1}={}){super(),this._onInputStart=t=>{this._changedWhileDragging=!1,this.trigger(Pt,Object.assign(Object.assign({},t),{inputType:"rotate"}))},this._onChange=t=>{const e=t.delta,i=1/this._zoomScale,s=this._screenScale,n=this._keyboardScale,r=this._pointerScale;let o;o=t.isKeyboard?[n[0]*i,n[1]*i]:[r[0]*s[0]*i,r[1]*s[1]*i];const a=e.x*o[0],h=e.y*o[1];this._xMotion.setNewEndByDelta(a),this._yMotion.setNewEndByDelta(h),this._changedWhileDragging=!0},this._onInputEnd=t=>{this.trigger(Mt,Object.assign(Object.assign({},t),{inputType:"rotate"})),this._changedWhileDragging||t.isKeyboard||t.scrolling||this.trigger(Bt,{isTouch:t.isTouch}),this._changedWhileDragging=!1},this._controlEl=t,this._pointerScale=n,this._keyboardScale=r,this._duration=i,this._easing=s,this._disablePitch=o,this._disableYaw=a,this._disableKeyboard=h,this._enableBlocked=e,this._mouseInput=new me,this._touchInput=new pe,this._keyboardInput=new ge,this._xMotion=new ue({duration:i,range:Gt,easing:s}),this._yMotion=new ue({duration:i,range:Ht,easing:s}),this._screenScale=[1,1],this._zoomScale=1,this._enabled=!1,this._changedWhileDragging=!1,this._bindInputs()}destroy(){this.disable(),this._mouseInput.off(),this._touchInput.off(),this._keyboardInput.off(),this.off(),this._changedWhileDragging=!1}update(t){if(!this._enabled)return;const e=this._xMotion,i=this._yMotion,s=this._keyboardInput;this._disableKeyboard||s.update(),this._disablePitch||i.update(t),this._disableYaw||e.update(t)}updateRange(t,e){const i=t.getYawRange(e),s=t.getPitchRange(e);this._xMotion.setRange(i.min,i.max),this._yMotion.setRange(s.min,s.max)}setZoomScale(t){this._zoomScale=t}resize(t,e,i,s){const n=re(t*Ft,e)*zt;this._screenScale[0]=t/i,this._screenScale[1]=n/s}enable(){if(this._enabled)return;const t=this._controlEl;this._mouseInput.enable(t),this._touchInput.enable(t),this._keyboardInput.enable(t),this._enabled=!0,this._enableBlocked=!1,this.trigger(Dt,{control:this,updateCursor:!0})}disable(){this._enabled&&(this._mouseInput.disable(),this._touchInput.disable(),this._keyboardInput.disable(),this._enabled=!1,this.trigger(Ut,{updateCursor:!0}))}sync(t){this.updateRange(t,t.zoom),this._xMotion.reset(t.yaw),this._yMotion.reset(t.pitch)}_bindInputs(){const t=this._mouseInput,e=this._touchInput,i=this._keyboardInput;t.on(Pt,this._onInputStart),t.on(Nt,this._onChange),t.on(Mt,this._onInputEnd),e.on(Pt,this._onInputStart),e.on(Nt,this._onChange),e.on(Mt,this._onInputEnd),i.on(Pt,this._onInputStart),i.on(Nt,this._onChange),i.on(Mt,this._onInputEnd)}}class Ee extends o{get scrollable(){return this._scrollable}set scrollable(t){this._scrollable=t}constructor(){super(),this._onWheel=t=>{const e=this._scrollable;if(0===t.deltaY||e)return;t.preventDefault(),t.stopPropagation(),this._inputTimer<0?this.trigger(Pt,{srcEvent:t,isTouch:!1,isKeyboard:!1}):this._clearTimer();const i=this._baseScale*t.deltaY;this.trigger(Nt,{delta:i,isTouch:!1,isKeyboard:!1}),this._inputTimer=window.setTimeout((()=>{this.trigger(Mt,{isTouch:!1,isKeyboard:!1,scrolling:!1}),this._inputTimer=-1}),kt)},this._el=null,this._baseScale=.04,this._scrollable=!1,this._inputTimer=-1}enable(t){this._el||(t.addEventListener(j,this._onWheel,{passive:!1,capture:!1}),this._el=t,this._clearTimer())}disable(){const t=this._el;t&&(t.removeEventListener(j,this._onWheel,!1),this._el=null,this._clearTimer())}_clearTimer(){window.clearTimeout(this._inputTimer),this._inputTimer=-1}}class fe extends o{constructor(){super(),this._onTouchMove=t=>{const e=t.touches;if(2!==e.length)return;if(!t.cancelable)return;t.preventDefault(),t.stopPropagation();const i=this._prevDistance,s=[e[0].pageX-e[1].pageX,e[0].pageY-e[1].pageY],n=Math.sqrt(s[0]*s[0]+s[1]*s[1])*this._baseScale,r=this._isFirstTouch?0:n-i;this._isFirstTouch&&this.trigger(Pt,{srcEvent:t,isTouch:!0,isKeyboard:!1}),this._prevDistance=n,this._isFirstTouch=!1,this.trigger(Nt,{delta:r,isTouch:!0,isKeyboard:!1})},this._onTouchEnd=t=>{0===t.touches.length&&(this._isFirstTouch||this.trigger(Mt,{isTouch:!0,isKeyboard:!1,scrolling:!1}),this._prevDistance=-1,this._isFirstTouch=!0)},this._el=null,this._baseScale=-.2,this._prevDistance=-1,this._isFirstTouch=!0}enable(t){this._el||(t.addEventListener(H,this._onTouchMove,{passive:!1,capture:!1}),t.addEventListener(Y,this._onTouchEnd),this._el=t,this._prevDistance=-1,this._isFirstTouch=!0)}disable(){const t=this._el;t&&(t.removeEventListener(H,this._onTouchMove,!1),t.removeEventListener(Y,this._onTouchEnd),this._el=null)}}class ye extends o{get enabled(){return this._enabled}get enableBlocked(){return this._enableBlocked}get animating(){return this._motion.activated}get zoom(){return this._motion.val}get scrollable(){return this._wheelInput.scrollable}set scrollable(t){this._wheelInput.scrollable=t}get range(){return this._motion.range}get scale(){return this._scale}set scale(t){this._scale=t}get duration(){return this._motion.duration}get easing(){return this._motion.easing}constructor(t,e,{scale:i=1,duration:s=300,easing:n=Vt}={}){super(),this._onInputStart=t=>{this.trigger(Pt,Object.assign(Object.assign({},t),{inputType:"zoom"}))},this._onChange=({delta:t})=>{const e=t*this._scale;this._motion.setNewEndByDelta(e)},this._onInputEnd=t=>{this.trigger(Mt,Object.assign(Object.assign({},t),{inputType:"zoom"}))},this._scale=i,this._controlEl=t,this._enableBlocked=e,this._wheelInput=new Ee,this._pinchInput=new fe,this._motion=new ue({duration:s,easing:n,range:Gt}),this._enabled=!1,this._bindInputs()}destroy(){this.disable(),this._wheelInput.off(),this._pinchInput.off(),this.off()}update(t){if(!this._enabled)return;this._motion.update(t)}enable(){if(this._enabled)return;const t=this._controlEl;this._wheelInput.enable(t),this._pinchInput.enable(t),this._enabled=!0,this._enableBlocked=!1,this.trigger(Dt,{control:this,updateCursor:!1})}disable(){this._enabled&&(this._wheelInput.disable(),this._pinchInput.disable(),this._enabled=!1,this.trigger(Ut,{updateCursor:!1}))}sync(t){const e=this._motion,i=t.getZoomRange();e.setRange(i.min,i.max),e.reset(i.current)}_bindInputs(){const t=this._wheelInput,e=this._pinchInput;t.on(Pt,this._onInputStart),t.on(Nt,this._onChange),t.on(Mt,this._onInputEnd),e.on(Pt,this._onInputStart),e.on(Nt,this._onChange),e.on(Mt,this._onInputEnd)}}const be={PITCH_DELTA:1,YAW_DELTA_BY_ROLL:2,YAW_DELTA_BY_YAW:3};be[be.PITCH_DELTA]={targetAxis:[0,1,0],meshPoint:[0,0,1]},be[be.YAW_DELTA_BY_ROLL]={targetAxis:[0,1,0],meshPoint:[1,0,0]},be[be.YAW_DELTA_BY_YAW]={targetAxis:[1,0,0],meshPoint:[0,0,1]};class Te extends o{get enabled(){return this._enabled}get orientationUpdated(){return this._orientationUpdated}get ignoreRoll(){return this._ignoreRoll}set ignoreRoll(t){this._ignoreRoll=t}constructor(){super(),this._onDeviceOrientation=t=>{const e=this._orientation,{alpha:i,beta:s,gamma:n}=t;null!=i&&null!=s&&null!=n&&(e.alpha=i,e.beta=s,e.gamma=n,this._orientationUpdated=!0,this._needsCalibrate&&(this._needsCalibrate=!1,this._calibrateSensor()))},this._updateScreenOrientation=()=>{window.screen&&window.screen.orientation&&void 0!==window.screen.orientation.angle?this._screenOrientation=screen.orientation.angle:void 0!==window.orientation?this._screenOrientation=window.orientation>=0?window.orientation:360+window.orientation:this._screenOrientation=0},this.quaternion=b(),this._orientation={alpha:0,beta:90,gamma:0},this._yawOrigin=0,this._yawOffset=0,this._orientationUpdated=!1,this._screenOrientation=0,this._needsCalibrate=!0,this._enabled=!1}enable(){this._enabled||(window.addEventListener(it,this._onDeviceOrientation),window.addEventListener(nt,this._updateScreenOrientation),this._updateScreenOrientation(),this._orientationUpdated=!1,this._needsCalibrate=!0,this._enabled=!0)}disable(){this._enabled&&(window.removeEventListener(it,this._onDeviceOrientation),window.removeEventListener(nt,this._updateScreenOrientation),this._enabled=!1)}update(){this._updateRotation(),this._orientationUpdated=!1}collectDelta(){if(!this._orientationUpdated)return{pitch:0,yaw:0};const t=A(this.quaternion);return this._updateRotation(),this._orientationUpdated=!1,this._toEulerDelta(t,this.quaternion)}setInitialRotation(t){this._yawOrigin=t}_calibrateSensor(){const t=this._yawOrigin,e=this.quaternion;this._yawOffset=0,this._updateRotation();const{yaw:i}=ce(e);this._yawOffset=i-t,this._updateRotation(),this._needsCalibrate=!1}_updateRotation(){const t=this.quaternion,{alpha:e,beta:i,gamma:s}=this._orientation;T(t),C(t,t,(e-this._yawOffset)*Ft),w(t,t,i*Ft),L(t,t,-s*Ft);const n=b(),r=.5*-this._screenOrientation*Ft,o=I(-Math.sqrt(.5),0,0,Math.sqrt(.5));P(n,0,Math.sin(r),0,Math.cos(r)),R(t,t,n),R(t,t,o),N(t,t)}_toEulerDelta(t,e){return{yaw:this._getDeltaYaw(t,e),pitch:this._getDeltaPitch(t,e)}}_getDeltaYaw(t,e){const i=this._getRotationDelta(t,e,be.YAW_DELTA_BY_YAW);return this._getRotationDelta(t,e,be.YAW_DELTA_BY_ROLL)*Math.sin(this._extractPitchFromQuat(e))+i}_getDeltaPitch(t,e){return this._getRotationDelta(t,e,be.PITCH_DELTA)}_getRotationDelta(t,e,i){const s=p(be[i].targetAxis[0],be[i].targetAxis[1],be[i].targetAxis[2]),n=be[i].meshPoint,r=A(t),o=A(e);N(r,r),N(o,o);let a=p(0,0,1),h=p(0,0,1);y(a,a,r),y(h,h,o),y(s,s,o);const l=v(s,E(d(),a,h))>0?1:-1,c=p(n[0],n[1],n[2]);let u;u=i!==be.YAW_DELTA_BY_YAW?p(0,l,0):p(l,0,0),y(c,c,o),y(u,u,o);const _=c,f=u,b=d();E(b,_,f),g(b,b);const T=b[0],R=b[1],w=b[2];h=p(n[0],n[1],n[2]),y(h,h,o),a=p(n[0],n[1],n[2]),y(a,a,r);let C=Math.abs(a[0]*T+a[1]*R+a[2]*w);const L=d();!function(t,e,i){t[0]=e[0]-i[0],t[1]=e[1]-i[1],t[2]=e[2]-i[2]}(L,a,function(t,e,i){return t[0]=e[0]*i,t[1]=e[1]*i,t[2]=e[2]*i,t}(d(),b,C));let x=(L[0]*h[0]+L[1]*h[1]+L[2]*h[2])/(m(L)*m(h));x>1&&(x=1);const O=Math.acos(x),I=E(d(),h,L);let S;C=T*I[0]+R*I[1]+w*I[2],S=i!==be.YAW_DELTA_BY_YAW?C>0?1:-1:C<0?1:-1;return O*S*l*zt}_extractPitchFromQuat(t){const e=p(0,0,1);return y(e,e,t),-1*Math.atan2(e[1],Math.sqrt(Math.pow(e[0],2)+Math.pow(e[2],2)))}}class Re extends o{get enabled(){return this._input.enabled}get enableBlocked(){return this._enableBlocked}get animating(){return this._input.enabled&&this._input.orientationUpdated}get ignoreRoll(){return this._ignoreRoll}set ignoreRoll(t){this._ignoreRoll=t}static isAvailable(){return t(this,void 0,void 0,(function*(){if(!DeviceMotionEvent)return!1;let t;return Promise.race([new Promise((e=>{t=t=>{e(t.rotationRate&&null!=t.rotationRate.alpha)},window.addEventListener(st,t)})),new Promise((t=>{setTimeout((()=>t(!1)),1e3)}))]).then((e=>(window.removeEventListener(st,t),e)))}))}static requestSensorPermission(){return t(this,void 0,void 0,(function*(){return!he()||DeviceMotionEvent.requestPermission().then((t=>"granted"===t)).catch((()=>!1))}))}constructor(t,{ignoreRoll:e=!0}={}){super(),this._enableBlocked=t,this._ignoreRoll=e,this._input=new Te}destroy(){this.disable(),this._input.off(),this.off()}update(t,e,i,s){this._ignoreRoll?this._updateYawPitch(t,e,i,s):this._updateQuaternion(t,s)}enable(){this._input.enabled||(this._input.enable(),this._enableBlocked=!1,this.trigger(Dt,{control:this,updateCursor:!1}))}disable(){this._input.enabled&&(this._input.disable(),this.trigger(Ut,{updateCursor:!1}))}sync(){}_updateYawPitch(t,e,i,s){const n=this._input;if(!n.enabled)return;const{yaw:r,pitch:o}=n.collectDelta();e.add(r),i.add(o),t.lookAt({yaw:e.val,pitch:i.val,zoom:s})}_updateQuaternion(t,e){const i=this._input;i.enabled&&(i.update(),t.rotate(i.quaternion,e))}}class we{get useGrabCursor(){return this._useGrabCursor}set useGrabCursor(t){t!==this._useGrabCursor&&(this._useGrabCursor=t,t&&this._enabled?this._setCursor(vt):t||this._setCursor(ft))}get disableContextMenu(){return this._disableContextMenu}set disableContextMenu(t){t!==this._disableContextMenu&&(this._disableContextMenu=t,t&&this._enabled?this._blockContextMenu():t||this._restoreContextMenu())}get scrollable(){return this._rotateControl.scrollable}set scrollable(t){this._rotateControl.scrollable=t}get wheelScrollable(){return this._zoomControl.scrollable}set wheelScrollable(t){this._zoomControl.scrollable=t}get ignoreZoomScale(){return this._ignoreZoomScale}set ignoreZoomScale(t){this._ignoreZoomScale=t}get enabled(){return this._enabled}get rotate(){return this._rotateControl}get zoom(){return this._zoomControl}get gyro(){return this._gyroControl}get animating(){return this._rotateControl.animating||this._zoomControl.animating||this._gyroControl.animating}constructor(t,e,{useGrabCursor:i,scrollable:s,wheelScrollable:n,disableContextMenu:r,rotate:o,zoom:a,gyro:h}){this._preventContextMenu=t=>{t.preventDefault()},this._onInputStart=t=>{this._useGrabCursor&&!t.isKeyboard&&this._setCursor(Et)},this._onInputEnd=t=>{this._useGrabCursor&&!t.isKeyboard&&this._setCursor(vt)},this._onEnable=({control:t,updateCursor:e})=>{e&&this._useGrabCursor&&this._setCursor(vt),t.sync(this._camera)},this._onDisable=({updateCursor:t})=>{t&&this._setCursor(ft)},this._onCameraAnimationEnd=({animation:t})=>{t.getFinishPromise().then((()=>{this.sync()}))},this._useGrabCursor=i,this._disableContextMenu=r,this._camera=e,this._controlEl=t,this._ignoreZoomScale=!1,this._enabled=!1,this._rotateControl=new ve(t,!o,ne(o)),this._zoomControl=new ye(t,!a,ne(a)),this._gyroControl=new Re(!h,ne(h)),this._rotateControl.scrollable=s,this._zoomControl.scrollable=n,this._bindEvents()}destroy(){this.disable(),this._rotateControl.destroy(),this._zoomControl.destroy(),this._setCursor(ft)}resize(t,e){const i=this._camera;this._rotateControl.resize(i.fov,i.aspect,t,e)}enable(){return t(this,void 0,void 0,(function*(){this._enabled||(this._rotateControl.enableBlocked||this._rotateControl.enable(),this._zoomControl.enableBlocked||this._zoomControl.enable(),this._gyroControl.enableBlocked||(yield Re.isAvailable())&&this._gyroControl.enable(),this.sync(),this._disableContextMenu&&this._blockContextMenu(),this._enabled=!0)}))}disable(){this._enabled&&(this._rotateControl.disable(),this._zoomControl.disable(),this._gyroControl.disable(),this._restoreContextMenu(),this._enabled=!1)}update(t){const e=this._camera,i=this._rotateControl,s=this._zoomControl,n=this._gyroControl;s.update(t);const r=(o=e.fov,a=s.zoom,Math.tan(Ft*o*.5)/Math.tan(Ft*a*.5));var o,a;const h=this._ignoreZoomScale?1:Math.max(r,1);i.setZoomScale(h),i.updateRange(e,r),i.update(t);const l=i.yaw,c=i.pitch;n.enabled?n.update(e,l,c,r):e.lookAt({yaw:l.val,pitch:c.val,zoom:r})}sync(){const t=this._camera;this._zoomControl.sync(t),this._rotateControl.sync(t)}_blockContextMenu(){this._controlEl.addEventListener(X,this._preventContextMenu)}_restoreContextMenu(){this._controlEl.removeEventListener(X,this._preventContextMenu)}_setCursor(t){if(!this._useGrabCursor&&t!==ft)return;this._controlEl.style.cursor=t}_bindEvents(){const t=this._rotateControl,e=this._zoomControl;t.on(Pt,this._onInputStart),t.on(Mt,this._onInputEnd),t.on(Dt,this._onEnable),t.on(Ut,this._onDisable),e.on(Dt,this._onEnable),e.on(Ut,this._onDisable),this._camera.on(St,this._onCameraAnimationEnd)}} +/*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */var Ce=function(t,e){return Ce=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},Ce(t,e)};function Le(t,e){function i(){this.constructor=t}Ce(t,e),t.prototype=null===e?Object.create(e):(i.prototype=e.prototype,new i)}var xe=function(){return xe=Object.assign||function(t){for(var e,i=1,s=arguments.length;i0},i.clear=function(){this.isPreReadyOver=!1,this.totalCount=0,this.preReadyCount=0,this.readyCount=0,this.totalErrorCount=0,this.elementInfos.forEach((function(t){t.loader&&t.loader.destroy()})),this.elementInfos=[]},i.destroy=function(){this.clear(),this.off()},i.getLoader=function(t,e){var i=this,s=t.tagName.toLowerCase(),n=this.options.loaders,r=e.prefix,o=Object.keys(n);if(n[s])return new n[s](t,e);var a=new Xe(t,e),h=Ue(t.querySelectorAll(o.join(", ")));a.setHasLoading(h.some((function(t){return Be(t,r)})));var l=!1,c=this.clone().on("error",(function(t){a.onError(t.target)})).on("ready",(function(){a.onReady(l)}));return a.on("requestChildren",(function(){var e=ke(t,o,i.options.prefix);c.check(e).on("preReady",(function(t){(l=t.isReady)||a.onPreReady()}))})).on("reqeustReadyChildren",(function(){c.check(h)})).on("requestDestroy",(function(){c.destroy()})),a},i.clone=function(){return new e(xe({},this.options))},i.checkPreReady=function(t){return this.elementInfos[t].isPreReady=!0,++this.preReadyCount,!(this.preReadyCount=1)&&(t.error?(this.onAlreadyError(t),!1):(this.addEvents(),!0))},e.EVENTS=["loadedmetadata","error"],e}(We),$e=function(t){function e(e){return void 0===e&&(e={}),t.call(this,xe({loaders:{img:qe,video:Ze}},e))||this}return Le(e,t),e}(Ke);class Je{constructor({width:t,height:e,flipY:i}){this.width=t,this.height=e,this.flipY=i,this.wrapS=WebGLRenderingContext.CLAMP_TO_EDGE,this.wrapT=WebGLRenderingContext.CLAMP_TO_EDGE}destroy(){}isVideo(){return!1}isCube(){return!1}}class Qe extends Je{constructor({source:t,width:e,height:i,flipY:s}){super({width:e,height:i,flipY:s}),this.source=t}}class ti extends Qe{destroy(){const t=this.source;t.pause(),t.removeAttribute("src"),t.load()}isVideo(){return!0}isPaused(){const t=this.source;return t.paused||t.ended||t.readyState<=2}hasAudio(){const t=this.source;return t.audioTracks?t.audioTracks.length>0:null!=t.webkitAudioDecodedByteCount?t.webkitAudioDecodedByteCount>0:null==t.mozHasAudio||t.mozHasAudio}}class ei extends Je{constructor({sources:t,width:e,height:i,flipY:s}){super({width:e,height:i,flipY:s}),this.sources=t}isCube(){return!0}}class ii{constructor(){this._loadChecker=new $e}load(e,i){return t(this,void 0,void 0,(function*(){if(i)return this.loadVideo(e,ne(i));if(Array.isArray(e)&&e.length>1)return this.loadCubeImage(e);{const t=Array.isArray(e)?e[0]:e;return this.loadImage(t)}}))}loadImage(e){return t(this,void 0,void 0,(function*(){const t=this._toImageArray(e);return this._load(t,(e=>{const i=t[0];e(new Qe({source:i,width:i.naturalWidth,height:i.naturalHeight,flipY:!0}))}))}))}loadCubeImage(e){return t(this,void 0,void 0,(function*(){const t=this._toImageArray(e);return this._load(t,(e=>{e(new ei({sources:t,width:t[0].naturalWidth,height:t[0].naturalHeight,flipY:!1}))}))}))}loadVideo(e,i){return t(this,void 0,void 0,(function*(){const t=Object.assign({autoplay:!0,muted:!0,loop:!1,volume:1},i),s=this._toVideoElement(e,t);return this._load([s],(e=>{const{autoplay:i,muted:n}=t;s.currentTime=0,i&&n&&s.play().catch((()=>{})),e(new ti({source:s,width:s.videoWidth,height:s.videoHeight,flipY:!0}))}))}))}_load(t,e){const i=this._loadChecker;return new Promise(((s,n)=>{i.once("ready",(t=>{t.errorCount>0||e(s)})),i.once("error",n),i.check(t)}))}_toImageArray(t){return(Array.isArray(t)?t:[t]).map((t=>{if($t(t)){const e=new Image;return e.crossOrigin="anonymous",e.src=t,e}return t}))}_toVideoElement(t,{muted:e,loop:i,volume:s}){if(t instanceof HTMLVideoElement)return t;const n=document.createElement("video");n.crossOrigin="anonymous",n.playsInline=!0,n.setAttribute("webkit-playsinline",""),n.muted=e,n.volume=s,n.loop=i,Array.isArray(t)?t.forEach((t=>this._appendSourceElement(n,t))):this._appendSourceElement(n,t);return n.querySelectorAll("source").length>0&&n.readyState<1&&n.load(),n}_appendSourceElement(t,e){if(e instanceof HTMLSourceElement)return e;const i=document.createElement("source");i.src=e,t.appendChild(i)}}class si{constructor(t,e=window){this.maxDeltaTime=t,this._context=e,this._rafId=-1,this._rafTimer=-1,this._lastUpdateTime=-1}start(t){const e=this._context;if(!e||!t)return;if(this._rafId>=0||this._rafTimer>=0)return;const i=(s,n)=>{const r=Date.now(),o=Math.min(r-this._lastUpdateTime,1e3*this.maxDeltaTime);t(o,n),this._lastUpdateTime=r,this._rafId=e.requestAnimationFrame(i)};this._lastUpdateTime=Date.now(),this._rafId=e.requestAnimationFrame(i)}stop(){this._rafId>=0&&this._context.cancelAnimationFrame(this._rafId),this._rafTimer>=0&&clearTimeout(this._rafTimer),this._rafId=-1,this._rafTimer=-1}changeContext(t){this.stop(),this._context=t}}class ni{get useResizeObserver(){return this._useResizeObserver}get enabled(){return this._enabled}constructor(t,e){this._skipFirstResize=(()=>{let t=!0;return()=>{t?t=!1:this._onResize()}})(),this._useResizeObserver=t,this._enabled=!1,this._resizeObserver=null,this._onResize=e}enable(t){if(this._enabled&&this.disable(),this._useResizeObserver&&window.ResizeObserver){const e=t.getBoundingClientRect(),i=0!==e.width||0!==e.height,s=new ResizeObserver(i?this._skipFirstResize:this._onResize);s.observe(t),this._resizeObserver=s}else window.addEventListener(W,this._onResize);return this._enabled=!0,this}disable(){if(!this._enabled)return this;const t=this._resizeObserver;return t?(t.disconnect(),this._resizeObserver=null):window.removeEventListener(W,this._onResize),this._enabled=!1,this}}class ri{get enabled(){return this._enabled}get enableBlocked(){return this._enableBlocked}get playing(){return this._enabled&&!this._interrupted}get delay(){return this._delay}set delay(t){this._delay=t}get delayOnMouseLeave(){return this._delayOnMouseLeave}set delayOnMouseLeave(t){this._delayOnMouseLeave=t}get speed(){return this._speed}set speed(t){this._speed=t}get pauseOnHover(){return this._pauseOnHover}set pauseOnHover(t){this._pauseOnHover=t}get canInterrupt(){return this._canInterrupt}set canInterrupt(t){this._canInterrupt=t}get disableOnInterrupt(){return this._disableOnInterrupt}set disableOnInterrupt(t){this._disableOnInterrupt=t}constructor(t,e,i){this._onInputStart=()=>{this._canInterrupt&&(this._interrupted=!0,this._clearTimeout())},this._onInputEnd=()=>{this._setUninterruptedAfterDelay(this._delay)},this._onGyroEnable=()=>{this.disable()},this._onMouseEnter=()=>{this._pauseOnHover&&(this._interrupted=!0,this._hovering=!0)},this._onMouseLeave=()=>{this._pauseOnHover&&(this._hovering=!1,this._setUninterruptedAfterDelay(this._delayOnMouseLeave))},this._camera=t.camera,this._control=t.control,this._element=e,this._enabled=!1,this._interrupted=!1,this._interruptionTimer=-1,this._hovering=!1;const{delay:s=2e3,delayOnMouseLeave:n=0,speed:r=1,pauseOnHover:o=!1,canInterrupt:a=!0,disableOnInterrupt:h=!1}=ne(i);this._enableBlocked=!i,this._delay=s,this._delayOnMouseLeave=n,this._speed=r,this._pauseOnHover=o,this._canInterrupt=a,this._disableOnInterrupt=h}destroy(){this.disable()}update(t){if(!this._enabled)return;if(this._interrupted)return void(this._disableOnInterrupt&&this.disable());const e=this._camera,i=-this._speed*t/100;e.yaw=ie(e.yaw+i,0,360)}enable(){const t=this._control,e=this._element;this._enabled||t.gyro.enabled||(t.rotate.on(Pt,this._onInputStart),t.rotate.on(Mt,this._onInputEnd),t.zoom.on(Pt,this._onInputStart),t.zoom.on(Mt,this._onInputEnd),t.gyro.on(Dt,this._onGyroEnable),e.addEventListener(K,this._onMouseEnter,!1),e.addEventListener(q,this._onMouseLeave,!1),this._enabled=!0,this._enableBlocked=!1)}enableAfterDelay(){this.enable(),this._interrupted=!0,this._setUninterruptedAfterDelay(this._delay)}disable(){if(!this._enabled)return;const t=this._control,e=this._element;t.rotate.off(Pt,this._onInputStart),t.rotate.off(Mt,this._onInputEnd),t.zoom.off(Pt,this._onInputStart),t.zoom.off(Mt,this._onInputEnd),t.gyro.off(Dt,this._onGyroEnable),e.removeEventListener(K,this._onMouseEnter,!1),e.removeEventListener(q,this._onMouseLeave,!1),this._enabled=!1,this._interrupted=!1,this._hovering=!1,this._clearTimeout()}_setUninterruptedAfterDelay(t){this._hovering||(this._clearTimeout(),t>0?this._interruptionTimer=window.setTimeout((()=>{this._interrupted=!1,this._interruptionTimer=-1}),t):(this._interrupted=!1,this._interruptionTimer=-1))}_clearTimeout(){this._interruptionTimer>=0&&(window.clearTimeout(this._interruptionTimer),this._interruptionTimer=-1)}}class oi extends o{constructor(t,e={}){super(),this.destroy=()=>{this.exit(),this.off()},this._onSessionEnd=()=>{this.exit(),this.trigger(Ot.VR_END)},this._xrSession=null,this._xrRefSpace=null,this._ctx=t,this._options=e}isAvailable(){return t(this,void 0,void 0,(function*(){const t=window.navigator.xr;return!!t&&t.isSessionSupported(Kt).then((t=>t)).catch((()=>!1))}))}enter(){return t(this,void 0,void 0,(function*(){const t=this._ctx,e=window.navigator.xr;if(!e)return;yield Re.requestSensorPermission();const i=Object.assign({requiredFeatures:[qt]},this._options);yield t.makeXRCompatible();const s=yield e.requestSession(Kt,i);t.bindXRLayer(s);const n=yield s.requestReferenceSpace(qt);this._setSession(s,n),this.trigger(Ot.VR_START,{session:s})}))}exit(){const t=this._xrSession;t&&t.end().catch((()=>{})),this._xrSession=null,this._xrRefSpace=null}canRender(t){const e=this._xrRefSpace;if(!e)return!1;return!!t.getViewerPose(e)}getEyeParams(t){const e=t.session,i=t.getViewerPose(this._xrRefSpace);if(!i)return null;const s=e.renderState.baseLayer;return s?i.views.map((t=>({viewport:s.getViewport(t),vMatrix:t.transform.inverse.matrix,pMatrix:t.projectionMatrix}))):null}_setSession(t,e){this._xrSession=t,this._xrRefSpace=e,t.addEventListener(dt,this._onSessionEnd)}}class ai{constructor(t,e){this.element=t,this.position=e}}class hi{constructor(t,e,{zoom:i=!1}){this._containerEl=Qt(`.${xt.HOTSPOT_CONTAINER}`,t),this._renderer=e,this._hotspots=[],this._zoom=i}refresh(){const t=this._containerEl;if(!t)return;const e=[].slice.apply(t.querySelectorAll(`.${xt.HOTSPOT}`));this._hotspots=e.map((t=>this._parseHotspot(t)))}render(t){const e=this._hotspots,i=.5*this._renderer.width,s=.5*this._renderer.height,n=t.zoom,r="translate(-50%, -50%)",o=this._zoom?`scale(${n})`:"";e.forEach((e=>{const n=e.position,a=d();if(function(t,e){t[0]=e[0],t[1]=e[1],t[2]=e[2]}(a,n),f(a,a,t.viewMatrix),f(a,a,t.projectionMatrix),a[2]>1||a[2]<0)return void e.element.classList.remove(xt.HOTSPOT_VISIBLE);const h=function(t,e){var i=new l(2);return i[0]=t,i[1]=e,i}(a[0]*i+i,-a[1]*s+s);e.element.classList.add(xt.HOTSPOT_VISIBLE),e.element.style.transform=[r,`translate(${h[0]}px, ${h[1]}px)`,o].join(" ")}))}_parseHotspot(t){const e=t.dataset.yaw,i=t.dataset.pitch,s=t.dataset.position;if(e||i){const s=e?parseFloat(e):0,n=i?parseFloat(i):0,r=this._yawPitchToVec3(s,n);return new ai(t,r)}if(s){const e=s.split(" ").map((t=>parseFloat(t)));if(e.length<3)throw new D(F.INSUFFICIENT_ARGS(s,'hotspot attribute "data-position"'),B.INSUFFICIENT_ARGS);return new ai(t,p(e[0],e[1],e[2]))}{const e=p(0,0,-1);return new ai(t,e)}}_yawPitchToVec3(t,e){const i=t*Ft,s=e*Ft,n=d();return n[1]=Math.sin(s),n[2]=Math.cos(s),n[0]=n[2]*Math.sin(-i),n[2]=-n[2]*Math.cos(-i),n}}class li{get count(){return this.geometry.indicies.count}constructor(t,e,i){this.obj=t,this.geometry=e,this.buffers=i}}class ci{get canvas(){return this._canvas}get maxTextureSize(){return this._maxTextureSize}get isWebGL2(){return this._isWebGL2}get supportVAO(){return this._isWebGL2||!!this._extensions.vao}get lost(){return this._contextLost}get debug(){return this._debug}constructor(t,e){this._onContextLost=()=>{this._canvas.classList.add(xt.CTX_LOST),this._contextLost=!0},this._onContextRestore=()=>{this._canvas.classList.remove(xt.CTX_LOST),this._contextLost=!1},this._canvas=t,this._contextLost=!1,this._debug=e,this._extensions={vao:null,loseContext:null}}init(){const t=this._canvas,{gl:e,isWebGL2:i}=this._getContext(t);this._gl=e,this._maxTextureSize=e.getParameter(e.MAX_TEXTURE_SIZE),this._isWebGL2=i,this._isWebGL2||(this._extensions.vao=e.getExtension("OES_vertex_array_object")),this._extensions.loseContext=e.getExtension("WEBGL_lose_context"),t.addEventListener(tt,this._onContextLost),t.addEventListener(et,this._onContextRestore)}destroy(){const t=this._gl,e=this._canvas;t&&(t.bindBuffer(t.ARRAY_BUFFER,null),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,null)),e.removeEventListener(tt,this._onContextLost),e.removeEventListener(et,this._onContextRestore)}forceLoseContext(){const t=this._extensions.loseContext;t&&t.loseContext()}forceRestoreContext(){const t=this._extensions.loseContext;t&&t.restoreContext()}clear(){const t=this._gl;t.clear(t.COLOR_BUFFER_BIT)}resize(){const t=this._gl;t.viewport(0,0,t.drawingBufferWidth,t.drawingBufferHeight)}viewport(t,e,i,s){this._gl.viewport(t,e,i,s)}createVAO(t,e){const i=this._createNativeVAO(),s=new li(i,t,{indicies:this._createBuffer(),position:this._createBuffer(),uv:this._createBuffer()});return i&&(this._bindNativeVAO(i),this._supplyGeometryData(s,e),this._bindNativeVAO(null),this._unbindBuffers()),s}draw(t,e){const i=this._gl;t.obj?this._bindNativeVAO(t.obj):this._supplyGeometryData(t,e),i.drawElements(i.TRIANGLES,t.count,i.UNSIGNED_SHORT,0),t.obj?this._bindNativeVAO(null):this._unbindBuffers()}releaseVAO(t){t.obj&&this._deleteNativeVAO(t.obj),this._deleteBuffer(t.buffers.indicies),this._deleteBuffer(t.buffers.position),this._deleteBuffer(t.buffers.uv)}getUniformLocations(t,e){const i=this._gl,s=Object.keys(e).reduce(((e,s)=>(e[s]=i.getUniformLocation(t,s),e)),{});return Object.assign(Object.assign({},this._getCommonUniformLocations(t)),s)}updateCommonUniforms(t,e,i){const s=this._gl,n=i.uniformLocations,r=t.matrix,o=c();u(o,e.viewMatrix,r),s.uniformMatrix4fv(n.uMVMatrix,!1,o),s.uniformMatrix4fv(n.uPMatrix,!1,e.projectionMatrix)}updateVRUniforms(t,e,i,s){const n=this._gl,r=t.uniformLocations;n.uniformMatrix4fv(r.uMVMatrix,!1,e),n.uniformMatrix4fv(r.uPMatrix,!1,i),r.uEye&&n.uniform1f(r.uEye,s)}updateUniforms(t){const e=this._gl,i=t.uniforms,s=t.uniformLocations;for(const t in i){const n=i[t],r=s[t];n&&(n.needsUpdate&&n.update(e,r,this._isWebGL2))}}releaseShaderResources(t){const e=this._gl,i=t.uniforms;for(const t in i){const s=i[t];s&&(s.needsUpdate&&s.destroy(e))}e.deleteProgram(t.program)}useProgram(t){this._gl.useProgram(t.program)}createProgram(t,e){const i=this._gl,s=i.createProgram(),n=this._compileShader(i.VERTEX_SHADER,t),r=this._compileShader(i.FRAGMENT_SHADER,e);if(i.attachShader(s,n),i.attachShader(s,r),i.bindAttribLocation(s,0,"position"),i.bindAttribLocation(s,1,"uv"),i.linkProgram(s),this._debug&&!i.getProgramParameter(s,i.LINK_STATUS)){let t=null;throw i.getShaderParameter(n,i.COMPILE_STATUS)?i.getShaderParameter(r,i.COMPILE_STATUS)||(t=i.getShaderInfoLog(r)):t=i.getShaderInfoLog(n),new D(F.FAILED_LINKING_PROGRAM(i.getProgramInfoLog(s),t),B.FAILED_LINKING_PROGRAM)}return i.deleteShader(n),i.deleteShader(r),s}createWebGLTexture(t){const e=this._gl,i=e.createTexture();if(e.bindTexture(e.TEXTURE_2D,i),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,t.wrapS),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,t.wrapT),!t.isVideo()&&this._isWebGL2){const i=e;i.texStorage2D(i.TEXTURE_2D,1,i.RGBA8,t.width,t.height)}return i}createWebGLCubeTexture(t,e){const i=this._gl,s=i.createTexture();if(i.bindTexture(i.TEXTURE_CUBE_MAP,s),i.texParameteri(i.TEXTURE_CUBE_MAP,i.TEXTURE_MIN_FILTER,i.LINEAR),i.texParameteri(i.TEXTURE_CUBE_MAP,i.TEXTURE_MAG_FILTER,i.LINEAR),i.texParameteri(i.TEXTURE_CUBE_MAP,i.TEXTURE_WRAP_S,t.wrapS),i.texParameteri(i.TEXTURE_CUBE_MAP,i.TEXTURE_WRAP_T,t.wrapT),this._isWebGL2){const t=i;t.texStorage2D(t.TEXTURE_CUBE_MAP,1,t.RGBA8,e,e)}return s}makeXRCompatible(){return t(this,void 0,void 0,(function*(){const t=this._gl,e=t.getContextAttributes();e&&!0!==e.xrCompatible&&(yield t.makeXRCompatible())}))}bindXRLayer(t){const e=this._gl,i=new XRWebGLLayer(t,e);t.updateRenderState({baseLayer:i})}bindXRFrame(t){const e=this._gl,i=t.session.renderState.baseLayer;e.bindFramebuffer(e.FRAMEBUFFER,i.framebuffer)}useDefaultFrameBuffer(){const t=this._gl;t.bindFramebuffer(t.FRAMEBUFFER,null)}_createBuffer(){return this._gl.createBuffer()}_deleteBuffer(t){return this._gl.deleteBuffer(t)}_createNativeVAO(){const t=this._gl;if(this._isWebGL2)return t.createVertexArray();{const t=this._extensions.vao;return(null==t?void 0:t.createVertexArrayOES())||null}}_bindNativeVAO(t){const e=this._gl;if(this._isWebGL2)e.bindVertexArray(t);else{const e=this._extensions.vao;null==e||e.bindVertexArrayOES(t)}}_deleteNativeVAO(t){const e=this._gl;if(this._isWebGL2)e.deleteVertexArray(t);else{const e=this._extensions.vao;null==e||e.deleteVertexArrayOES(t)}}_supplyGeometryData(t,e){const i=t.geometry;this._supplyIndiciesData(i.indicies,t.buffers.indicies),this._supplyAttributeData(i.vertices,e.program,"position",t.buffers.position),this._supplyAttributeData(i.uvs,e.program,"uv",t.buffers.uv)}_unbindBuffers(){const t=this._gl;t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,null),t.bindBuffer(t.ARRAY_BUFFER,null)}_supplyIndiciesData(t,e){const i=this._gl;i.bindBuffer(i.ELEMENT_ARRAY_BUFFER,e),i.bufferData(i.ELEMENT_ARRAY_BUFFER,t.data,i.STATIC_DRAW)}_supplyAttributeData(t,e,i,s){const n=this._gl,r=n.getAttribLocation(e,i);r<0||(n.bindBuffer(n.ARRAY_BUFFER,s),n.bufferData(n.ARRAY_BUFFER,t.data,n.STATIC_DRAW),n.vertexAttribPointer(r,t.itemSize,n.FLOAT,!1,0,0),n.enableVertexAttribArray(r))}_compileShader(t,e){const i=this._gl,s=i.createShader(t);return i.shaderSource(s,e),i.compileShader(s),s}_getCommonUniformLocations(t){const e=this._gl;return{uMVMatrix:e.getUniformLocation(t,"uMVMatrix"),uPMatrix:e.getUniformLocation(t,"uPMatrix")}}_getContext(t){const e=["webgl2","webgl","experimental-webgl","webkit-3d","moz-webgl"];let i=null,s=!1;const n={preserveDrawingBuffer:!1,antialias:!1},r=t=>t.statusMessage;t.addEventListener(Q,r);for(const r of e){try{i=t.getContext(r,n),s="webgl2"===r}catch(t){}if(i)break}if(t.removeEventListener(Q,r),!i)throw new D(F.WEBGL_NOT_SUPPORTED,B.WEBGL_NOT_SUPPORTED);return{gl:i,isWebGL2:s}}}class ui{get canvas(){return this._canvas}get width(){return this._elementSize.x}get height(){return this._elementSize.y}get pixelRatio(){return this._pixelRatio}get aspect(){return this._elementSize.x/this._elementSize.y}constructor(t,e){this._canvas=t,this._elementSize={x:0,y:0},this._pixelRatio=1,this.ctx=new ci(t,e)}destroy(){const t=this._canvas;this.ctx.destroy(),t.width=1,t.height=1}resize(){const t=this._canvas,e=this._elementSize,i=window.devicePixelRatio;e.x=t.clientWidth,e.y=t.clientHeight,t.width=e.x*i,t.height=e.y*i,this._pixelRatio=i,this.ctx.resize()}render(t,e){const i=this.ctx,s=t.getMesh();!i.lost&&s&&(i.clear(),i.useProgram(s.program),i.updateCommonUniforms(s,e,s.program),t.update(e),i.updateUniforms(s.program),i.draw(s.vao,s.program))}renderVR(t,e,i){const s=this.ctx,n=t.getMesh(),r=e.getEyeParams(i);r&&n&&(s.bindXRFrame(i),s.useProgram(n.program),s.updateUniforms(n.program),r.forEach(((t,e)=>{const i=t.viewport,r=u(c(),t.vMatrix,n.matrix);s.viewport(i.x,i.y,i.width,i.height),s.updateVRUniforms(n.program,r,t.pMatrix,e),s.draw(n.vao,n.program)})))}}class _i extends o{get rootEl(){return this._rootEl}get renderer(){return this._renderer}get camera(){return this._camera}get control(){return this._control}get vr(){return this._vr}get hotspot(){return this._hotspot}get plugins(){return this._plugins}get projection(){return this._projection}set projection(t){this._initialized&&t?this.load(t):this._projection=t}get initialized(){return this._initialized}get autoplay(){return this._autoplay}get autoInit(){return this._autoInit}get autoResize(){return this._autoResize}get canvasSelector(){return this._canvasSelector}get useResizeObserver(){return this._useResizeObserver}get tabIndex(){return this._tabIndex}set tabIndex(t){const e=this._renderer.canvas;this._tabIndex=t,null!=t?e.tabIndex=t:e.removeAttribute("tabindex")}get maxDeltaTime(){return this._animator.maxDeltaTime}set maxDeltaTime(t){this._animator.maxDeltaTime=t}get debug(){return this._debug}set debug(t){this._debug=t}get initialYaw(){return this._camera.initialYaw}set initialYaw(t){this._camera.initialYaw=t}get initialPitch(){return this._camera.initialPitch}set initialPitch(t){this._camera.initialPitch=t}get initialZoom(){return this._camera.initialZoom}set initialZoom(t){this._camera.initialZoom=t}get yawRange(){return this._camera.yawRange}set yawRange(t){this._camera.yawRange=t,this._projection&&this._projection.updateCamera(this._camera)}get pitchRange(){return this._camera.pitchRange}set pitchRange(t){this._camera.pitchRange=t,this._projection&&this._projection.updateCamera(this._camera)}get zoomRange(){return this._camera.zoomRange}set zoomRange(t){this._camera.zoomRange=t,this._projection&&this._projection.updateCamera(this._camera)}get fov(){return this._camera.fov}set fov(t){const e=this._camera,i=this._control;e.fov=t,e.updateMatrix(),i.sync()}get rotate(){return this._control.rotate}get zoom(){return this._control.zoom}get gyro(){return this._control.gyro}get useGrabCursor(){return this._control.useGrabCursor}set useGrabCursor(t){this._control.useGrabCursor=t}get disableContextMenu(){return this._control.disableContextMenu}set disableContextMenu(t){this._control.disableContextMenu=t}get scrollable(){return this._control.scrollable}set scrollable(t){this._control.scrollable=t}get wheelScrollable(){return this._control.wheelScrollable}set wheelScrollable(t){this._control.wheelScrollable=t}constructor(t,{projection:e=null,initialYaw:i=0,initialPitch:s=0,initialZoom:n=1,yawRange:r=null,pitchRange:o=null,zoomRange:a=null,fov:h=90,useGrabCursor:l=!0,disableContextMenu:c=!1,rotate:u=!0,zoom:_=!0,gyro:d=!1,scrollable:m=!0,wheelScrollable:p=!1,autoplay:g=!1,hotspot:v={},autoInit:E=!0,autoResize:f=!0,canvasSelector:y="canvas",useResizeObserver:b=!0,on:T={},plugins:R=[],maxDeltaTime:w=1/30,tabIndex:C=0,debug:L=!1}={}){super(),this.renderFrame=t=>{const e=this._camera,i=this._renderer,s=this._control,n=this._hotspot,r=this._autoplay,o=this._projection;o&&(this._emit(Ot.BEFORE_RENDER),r.playing&&(r.update(t),s.sync()),e.animation?e.animation.update(t):s.update(t),i.render(o,e),n.render(e),e.changed&&this._emit(Ot.VIEW_CHANGE,{yaw:e.yaw,pitch:e.pitch,zoom:e.zoom,quaternion:[e.quaternion[0],e.quaternion[1],e.quaternion[2],e.quaternion[3]]}),e.onFrameRender(),this._emit(Ot.RENDER))},this._renderFrameOnDemand=t=>{var e;const i=this._camera,s=this._control,n=this._autoplay,r=null===(e=this._projection)||void 0===e?void 0:e.getTexture();this._initialized&&r&&(i.animation||s.animating||n.playing||r.isVideo())&&this.renderFrame(t)},this._renderVRFrame=(t,e)=>{const i=this._vr,s=this._projection,n=this._renderer;s&&(this._emit(Ot.BEFORE_RENDER),n.renderVR(s,i,e),this._emit(Ot.RENDER))},this._rootEl=((t,e)=>{const i=Qt(t,e);if(!i)throw $t(t)?new D(F.ELEMENT_NOT_FOUND(t),B.ELEMENT_NOT_FOUND):new D(F.WRONG_TYPE(t,["HTMLElement","string"]),B.WRONG_TYPE);return i})(t),this._plugins=R,this._initialized=!1,this._autoInit=E,this._autoResize=f,this._canvasSelector=y,this._useResizeObserver=b,this._tabIndex=C,this._debug=L;const x=((t,e)=>{const i=t.querySelector(e);if(!i)throw new D(F.CANVAS_NOT_FOUND,B.CANVAS_NOT_FOUND);return i})(this._rootEl,y);this._renderer=new ui(x,L),this._camera=new de({initialYaw:i,initialPitch:s,initialZoom:n,fov:h,yawRange:r,pitchRange:o,zoomRange:a}),this._control=new we(x,this._camera,{useGrabCursor:l,scrollable:m,wheelScrollable:p,disableContextMenu:c,rotate:u,zoom:_,gyro:d}),this._animator=new si(w),this._autoplay=new ri(this,x,g),this._projection=e,this._autoResizer=new ni(b,(()=>this.resize())),this._vr=new oi(this._renderer.ctx),this._hotspot=new hi(this._rootEl,this._renderer,v),this._addEventHandlers(T),e&&E&&this.init()}destroy(){this._camera.destroy(),this._animator.stop(),this._renderer.destroy(),this._control.destroy(),this._autoResizer.disable(),this._projection&&(this._projection.releaseAllResources(this._renderer.ctx),this._projection=null),this._plugins.forEach((t=>t.destroy(this))),this._initialized=!1}init(){return t(this,void 0,void 0,(function*(){if(!this._projection)throw new D(F.PROVIDE_PROJECTION_FIRST,B.PROVIDE_PROJECTION_FIRST);const t=this._renderer,e=this._camera,i=this._control,s=this._animator,n=this._hotspot,r=this._projection,o=t.canvas;this._bindComponentEvents(),t.ctx.init(),this._resizeComponents(),e.updateMatrix(),this._autoResize&&this._autoResizer.enable(o),this._autoplay.enableBlocked||this._autoplay.enable(),this._plugins.forEach((t=>{t.init(this)}));const a=yield this._loadTexture(r);this._applyProjection(r,a,null),n.refresh(),s.start(this._renderFrameOnDemand),yield i.enable(),null==this._tabIndex||o.hasAttribute("tabIndex")||(o.tabIndex=this._tabIndex),this._initialized=!0,this.renderFrame(0),this._emit(Ot.READY)}))}load(e){return t(this,void 0,void 0,(function*(){if(!e)return!1;if(this._initialized){const t=yield this._loadTexture(e);this._applyProjection(e,t,this._projection),this.renderFrame(0)}else this._projection=e,this.init();return!0}))}resize(){if(!this._initialized)return;this._resizeComponents(),this.renderFrame(0);const{width:t,height:e}=this._renderer;this._emit(Ot.RESIZE,{width:t,height:e})}addPlugins(...t){this._initialized&&t.forEach((t=>{t.init(this)})),this._plugins.push(...t)}removePlugins(...t){t.forEach((t=>{const e=this._plugins.indexOf(t);e<0||(t.destroy(this),this._plugins.splice(e,1))}))}_emit(t,...e){const i=e?e[0]:{};this.trigger(t,Object.assign({type:t,target:this},i))}_applyProjection(t,e,i){const s=this._camera,n=this._control,r=this._renderer;i&&i.releaseAllResources(this._renderer.ctx),t.applyTexture(r.ctx,e),t.updateCamera(s),t.updateControl(n),this._projection=t,this._emit(Ot.PROJECTION_CHANGE,{projection:t})}_loadTexture(e){return t(this,void 0,void 0,(function*(){const t=new ii,{src:i,video:s}=e;this._emit(Ot.LOAD_START,{src:i,video:s});const n=yield t.load(i,s);return this._emit(Ot.LOAD,{src:i,video:s}),n}))}_resizeComponents(){const t=this._renderer,e=this._camera,i=this._control;t.resize(),e.resize(t.width,t.height),i.resize(t.width,t.height)}_addEventHandlers(t){Object.keys(t).forEach((e=>{this.on(e,t[e])}))}_bindComponentEvents(){const t=this._rootEl,e=this._control,i=this._animator,s=this._renderer,n=this._vr;[Bt,Pt,Mt].forEach((t=>{e.rotate.on(t,(e=>{this._emit(t,e)})),e.zoom.on(t,(e=>{this._emit(t,e)}))})),n.on(Ot.VR_START,(e=>{t.classList.add(xt.IN_VR),i.changeContext(e.session),i.start(this._renderVRFrame),this._emit(Ot.VR_START)})),n.on(Ot.VR_END,(()=>{t.classList.remove(xt.IN_VR),s.ctx.useDefaultFrameBuffer(),i.changeContext(window),i.start(this._renderFrameOnDemand),this.resize(),this._emit(Ot.VR_END)}))}}_i.VERSION="4.0.0-beta.4";class di{constructor(){this.matrix=c(),this.rotation=b(),this.position=p(0,0,0),this.scale=p(1,1,1)}updateMatrix(){!function(t,e,i,s){var n=e[0],r=e[1],o=e[2],a=e[3],h=n+n,l=r+r,c=o+o,u=n*h,_=n*l,d=n*c,m=r*l,p=r*c,g=o*c,v=a*h,E=a*l,f=a*c,y=s[0],b=s[1],T=s[2];t[0]=(1-(m+g))*y,t[1]=(_+f)*y,t[2]=(d-E)*y,t[3]=0,t[4]=(_-f)*b,t[5]=(1-(u+g))*b,t[6]=(p+v)*b,t[7]=0,t[8]=(d+E)*T,t[9]=(p-v)*T,t[10]=(1-(u+m))*T,t[11]=0,t[12]=i[0],t[13]=i[1],t[14]=i[2],t[15]=1}(this.matrix,this.rotation,this.position,this.scale)}}class mi{constructor({className:t={}}={}){this._startLoading=({target:t})=>{t.rootEl.appendChild(this._container),t.initialized?t.once(Ot.LOAD,this._detachElements):t.once(Ot.READY,this._detachElements)},this._detachElements=({target:t})=>{const e=this._container;e&&e.parentElement===t.rootEl&&t.rootEl.removeChild(e)},this.className=t,this._container=this._createElements()}init(t){t.on(Ot.LOAD_START,this._startLoading)}destroy(t){t.off(Ot.LOAD_START,this._startLoading),this._detachElements({target:t})}_createElements(){const t=Object.assign(Object.assign({},this.className),mi.DEFAULT_CLASS),e=Jt(t.CONTAINER),i=Jt(t.RING);return e.appendChild(i),e}}mi.DEFAULT_CLASS={CONTAINER:"view360-spinner",RING:"view360-spinner-ring"};class pi{constructor(t){this.position=t.position,this.order=t.order}}const gi={CONTROLS_ROOT:"view360-controls",CONTROLS_BG:"view360-controls-background",CONTROLS_MAIN:"view360-controls-main",CONTROLS_TOP:"view360-controls-top",CONTROLS_BOTTOM:"view360-controls-bottom",CONTROLS_MID:"view360-controls-mid",CONTROLS_LEFT:"view360-controls-left",CONTROLS_RIGHT:"view360-controls-right",CONTROLS_FLOAT_LEFT:"view360-controls-float-left",CONTROLS_FLOAT_RIGHT:"view360-controls-float-right",CONTROLS_BUTTON:"view360-controls-button",PROGRESS_ROOT:"view360-controls-progress",VOLUME_ROOT:"view360-controls-volume",RANGE_ROOT:"view360-range",RANGE_TRACK:"view360-range-track",RANGE_THUMB:"view360-range-thumb",RANGE_FILLER:"view360-range-filler",PLAY_BUTTON:"view360-controls-play",PAUSE_BUTTON:"view360-controls-pause",UNMUTED_BUTTON:"view360-controls-unmuted",MUTED_BUTTON:"view360-controls-muted",FULLSCREEN_BUTTON:"view360-controls-fullscreen",FULLSCREEN_EXIT_BUTTON:"view360-controls-fullscreen-exit",VR_BUTTON:"view360-controls-vr",GYRO_ENABLED:"view360-controls-gyro-enabled",GYRO_DISABLED:"view360-controls-gyro-disabled",VIDEO_TIME_DISPLAY:"view360-controls-time",PIEVIEW_ROOT:"view360-controls-pie",FIXED:"view360-controls-fixed",UNAVAILABLE:"view360-controls-unavailable",HIDDEN:"view360-controls-hidden"},vi={TOP_LEFT:"top-left",TOP_RIGHT:"top-right",MAIN_TOP:"main-top",MAIN_BOTTOM:"main-bottom",MAIN_LEFT:"main-left",MAIN_RIGHT:"main-right"};class Ei extends o{constructor(){super(),this._onHold=({srcEvent:t,isTouch:e})=>{var i;const s=this._bbox;if(!s)return;const n=e?t.touches[0].pageX:t.pageX,r=s.x+(null!==(i=window.scrollX)&&void 0!==i?i:window.pageXOffset),o=te(n,r,r+s.width),a=(o-r)/s.width;this._motion.reset(o),this.thumbEl.classList.add(this._fixedClass),this.trigger(Pt,a)},this._onChange=({delta:t})=>{var e;const i=this._motion,s=this._bbox;if(!s)return;i.setNewEndByDelta(t.x),i.update(1);const n=s.x+(null!==(e=window.scrollX)&&void 0!==e?e:window.pageXOffset),r=(te(i.val,n,n+s.width)-n)/s.width;this.trigger(Nt,r)},this._onRelease=()=>{this._bbox&&(this.thumbEl.classList.remove(this._fixedClass),this.trigger(Mt))};const t=document.createElement(mt),e=document.createElement(mt),i=document.createElement(mt),s=document.createElement(mt);t.draggable=!1,e.appendChild(s),e.appendChild(i),t.appendChild(e),this.rootEl=t,this.trackEl=e,this.thumbEl=i,this.fillerEl=s,this._mouseInput=new me,this._touchInput=new pe,this._motion=new ue({duration:1,range:Gt,easing:t=>t}),this._bbox={x:0,y:0,width:0,height:0,left:0,right:0,bottom:0,top:0},this._fixedClass=gi.FIXED}init(t){const e=this._mouseInput,i=this._touchInput;this.rootEl.classList.add(t.RANGE_ROOT),this.trackEl.classList.add(t.RANGE_TRACK),this.thumbEl.classList.add(t.RANGE_THUMB),this.fillerEl.classList.add(t.RANGE_FILLER),this._fixedClass=t.FIXED,e.on(Pt,this._onHold),i.on(Pt,this._onHold),e.on(Mt,this._onRelease),i.on(Mt,this._onRelease),e.on(Nt,this._onChange),i.on(Nt,this._onChange),e.enable(this.rootEl),i.enable(this.rootEl),this.resize()}destroy(){const t=this._mouseInput,e=this._touchInput;this.rootEl.className="",this.trackEl.className="",this.thumbEl.className="",this.fillerEl.className="",t.off(),e.off(),t.disable(),e.disable()}resize(){this._bbox=this.trackEl.getBoundingClientRect()}updateStyle(t){const e=this._bbox.width,i=te(t,0,1);this.fillerEl.style.width=100*i+"%",this.thumbEl.style.transform=`translateX(${i*e}px)`}}class fi extends pi{get element(){return this._rangeControl.rootEl}constructor({position:t=vi.MAIN_TOP,order:e=9999}={}){super({position:t,order:e}),this._onResize=()=>{this._rangeControl.resize()},this._onTimeUpdate=()=>{const t=this._video;t&&(this._currentTime=t.source.currentTime,this._rangeControl.updateStyle(this._currentTime/this._duration))},this._onDurationChange=()=>{const t=this._video;t&&(this._duration=t.source.duration,this._rangeControl.updateStyle(this._currentTime/this._duration))},this._onHold=t=>{const e=this._video,i=this._controlBar;if(!e||!i)return;const s=e.isPaused();e.source.pause();const n=e.source.duration*t;e.source.currentTime=n,e.source.dispatchEvent(new CustomEvent(Wt,{detail:{time:n}})),i.rootEl.classList.add(i.className.FIXED),this._wasPaused=!this._playPromise&&s},this._onControl=t=>{const e=this._video;if(!e)return;const i=e.source.duration*t;e.source.currentTime=i,e.source.dispatchEvent(new CustomEvent(Wt,{detail:{time:i}}))},this._onRelease=()=>{const t=this._video,e=this._controlBar;t&&e&&(this._wasPaused||this._playPromise||(this._playPromise=t.source.play().catch((()=>{})),this._playPromise.then((()=>{this._playPromise=null})),e.rootEl.classList.remove(e.className.FIXED))),this._wasPaused=!1},this.position=t,this.order=e,this._controlBar=null,this._rangeControl=new Ei,this._video=null,this._wasPaused=!1,this._currentTime=0,this._duration=0,this._playPromise=null}init(t,e){var i;const s=null===(i=t.projection)||void 0===i?void 0:i.getTexture(),n=this.element,r=this._rangeControl,o=e.className.UNAVAILABLE;s&&s.isVideo()?(n.classList.remove(o),n.classList.add(e.className.PROGRESS_ROOT),t.on(Ot.RESIZE,this._onResize),s.source.addEventListener(lt,this._onTimeUpdate),s.source.addEventListener(ct,this._onDurationChange),s.source.addEventListener(Wt,this._onTimeUpdate),r.init(e.className),r.on(Pt,this._onHold),r.on(Nt,this._onControl),r.on(Mt,this._onRelease),this._video=s,this._currentTime=s.source.currentTime,this._duration=s.source.duration,this._controlBar=e,r.updateStyle(this._currentTime/this._duration)):n.classList.add(o)}destroy(t){const e=this._video;t.off(Ot.RESIZE,this._onResize),e&&(e.source.removeEventListener(lt,this._onTimeUpdate),e.source.removeEventListener(ct,this._onDurationChange),e.source.removeEventListener(Wt,this._onTimeUpdate)),this._rangeControl.destroy(),this._video=null,this._playPromise=null}}class yi extends pi{constructor({position:t=vi.MAIN_LEFT,order:e=9999}={}){super({position:t,order:e}),this._onClick=()=>{const t=this._video;t&&(this._paused?t.source.play():t.source.pause())},this._onPlay=()=>{if(!this._controlBar)return;const t=this.element,e=this._controlBar.className;t.classList.add(e.PAUSE_BUTTON),t.classList.remove(e.PLAY_BUTTON),t.title="Pause Video",this._paused=!1},this._onPause=()=>{if(!this._controlBar)return;const t=this.element,e=this._controlBar.className;t.classList.add(e.PLAY_BUTTON),t.classList.remove(e.PAUSE_BUTTON),t.title="Play Video",this._paused=!0},this.element=document.createElement(pt),this._video=null,this._paused=!0,this._controlBar=null}init(t,e){var i;const s=this.element,n=null===(i=t.projection)||void 0===i?void 0:i.getTexture(),r=e.className,o=r.UNAVAILABLE;if(!n||!n.isVideo())return void s.classList.add(o);s.classList.add(r.CONTROLS_BUTTON),s.classList.remove(o);const a=n.isPaused();this._video=n,this._paused=a,this._controlBar=e,a?this._onPause():this._onPlay(),s.addEventListener(J,this._onClick),n.source.addEventListener(rt,this._onPlay),n.source.addEventListener(ot,this._onPause)}destroy(){const t=this._video,e=this.element;t&&(e.className="",e.removeEventListener(J,this._onClick),t.source.removeEventListener(rt,this._onPlay),t.source.removeEventListener(ot,this._onPause),this._video=null,this._paused=!0,this._controlBar=null)}}class bi extends pi{get element(){return this._rootEl}constructor({position:t=vi.MAIN_RIGHT,order:e=9999}={}){super({position:t,order:e}),this._onResize=()=>{this._rangeControl.resize(),this._updateDisplay()},this._onClick=()=>{const t=this._video;t&&!this._rootEl.disabled&&(t.source.muted=!t.source.muted)},this._onVolumeChange=()=>{const t=this._buttonEl,e=this._video,i=this._controlBar;if(!e||!i)return;const s=i.className;e.source.muted||0===e.source.volume?(t.classList.add(s.MUTED_BUTTON),t.classList.remove(s.UNMUTED_BUTTON)):(t.classList.add(s.UNMUTED_BUTTON),t.classList.remove(s.MUTED_BUTTON)),this._updateDisplay()},this._onHold=t=>{const e=this._video,i=this._controlBar;if(!e||!i)return;const s=i.className;e.source.volume=t,this._rootEl.classList.add(s.FIXED),i.containerEl.classList.add(s.FIXED),this._updateDisplay()},this._onChange=t=>{const e=this._video;e&&(e.source.volume=t,e.source.muted=!(t>0),this._updateDisplay())},this._onRelease=()=>{const t=this._controlBar;if(!t)return;const e=t.className;this._rootEl.classList.remove(e.FIXED),t.containerEl.classList.remove(e.FIXED)},this._updateDisplay=()=>{const t=this._video,e=this._rootEl;if(!t)return;if(!t.hasAudio())return void(e.disabled=!0);e.disabled=!1;const i=t.source.muted?0:t.source.volume;this._rangeControl.updateStyle(i)},this._controlBar=null,this._rangeControl=new Ei,this._createElements(),this._video=null}init(t,e){var i;const s=null===(i=t.projection)||void 0===i?void 0:i.getTexture(),n=this._rootEl,r=this._buttonEl,o=this._rangeControl,a=e.className,h=a.UNAVAILABLE;s&&s.isVideo()?(n.classList.remove(h),n.classList.add(a.CONTROLS_BUTTON),n.classList.add(a.VOLUME_ROOT),r.classList.add(a.CONTROLS_BUTTON),s.source.muted?r.classList.add(a.MUTED_BUTTON):r.classList.add(a.UNMUTED_BUTTON),t.on(Ot.RESIZE,this._onResize),n.addEventListener(_t,this._onResize),r.addEventListener(J,this._onClick),s.source.addEventListener(ht,this._onVolumeChange),s.source.addEventListener(at,this._updateDisplay),s.source.addEventListener(ut,this._updateDisplay),o.init(a),o.on(Pt,this._onHold),o.on(Nt,this._onChange),o.on(Mt,this._onRelease),this._controlBar=e,this._video=s,this._updateDisplay()):n.classList.add(h)}destroy(t){const e=this._video,i=this._buttonEl,s=this._rootEl;s.className="",i.className="",t.off(Ot.RESIZE,this._onResize),s.removeEventListener(_t,this._onResize),i.removeEventListener(J,this._onClick),e&&(e.source.removeEventListener(ht,this._onVolumeChange),e.source.removeEventListener(at,this._updateDisplay),e.source.removeEventListener(ut,this._updateDisplay)),this._controlBar=null,this._rangeControl.destroy(),this._video=null}_createElements(){const t=document.createElement(pt),e=document.createElement(mt);t.appendChild(this._rangeControl.rootEl),t.appendChild(e),t.title="Toggle Mute",this._rootEl=t,this._buttonEl=e}}class Ti extends pi{constructor({position:t=vi.MAIN_RIGHT,order:e=9999}={}){super({position:t,order:e}),this._onClick=()=>{const t=this._targetEl;t&&(ae()?this._exitFullscreen():this._requestFullscreen(t))},this._onFullscreenChange=()=>{const t=this.element,e=this._controlBar;if(!e)return;const i=e.className;ae()?(t.classList.add(i.FULLSCREEN_EXIT_BUTTON),t.classList.remove(i.FULLSCREEN_BUTTON)):(t.classList.add(i.FULLSCREEN_BUTTON),t.classList.remove(i.FULLSCREEN_EXIT_BUTTON))},this.element=document.createElement(pt),this.element.title="Toggle Fullscreen",this._controlBar=null,this._targetEl=null}init(t,e){const i=this.element,s=e.className;this._fullscreenAvailable()?(i.classList.add(s.CONTROLS_BUTTON),i.classList.remove(s.UNAVAILABLE),i.addEventListener(J,this._onClick),this._addFullscreenHandlers(),ae()?i.classList.add(s.FULLSCREEN_EXIT_BUTTON):i.classList.add(s.FULLSCREEN_BUTTON),this._controlBar=e,this._targetEl=t.rootEl):i.classList.add(s.UNAVAILABLE)}destroy(){const t=this.element;t.className="",t.removeEventListener(J,this._onClick),this._removeFullscreenHandlers(),this._controlBar=null,this._targetEl=null}_fullscreenAvailable(){return Rt.some((t=>!!document[t]))}_requestFullscreen(t){for(const e of Rt){const i=t[e];if(i)return void i.call(t)}}_exitFullscreen(){for(const t of Ct){const e=document[t];if(e)return void e.call(document)}}_addFullscreenHandlers(){Lt.forEach((t=>{document.addEventListener(t,this._onFullscreenChange)}))}_removeFullscreenHandlers(){Lt.forEach((t=>{document.removeEventListener(t,this._onFullscreenChange)}))}}class Ri extends pi{constructor({position:t=vi.MAIN_LEFT,order:e=9999}={}){super({position:t,order:e}),this._onTimeUpdate=()=>{const t=this._video;t&&(this._currentTime=t.source.currentTime,this._updateDisplay())},this._onDurationChange=()=>{const t=this._video;t&&(this._duration=t.source.duration,this._updateDisplay())},this._onCustomTimeChange=t=>{this._currentTime=t.detail.time,this._updateDisplay()},this.element=document.createElement(mt),this._video=null,this._currentTime=0,this._duration=0}init(t,e){var i;const s=null===(i=t.projection)||void 0===i?void 0:i.getTexture(),n=this.element,r=e.className;s&&s.isVideo()?(n.classList.add(r.VIDEO_TIME_DISPLAY),n.classList.remove(r.UNAVAILABLE),s.source.addEventListener(lt,this._onTimeUpdate),s.source.addEventListener(ct,this._onDurationChange),s.source.addEventListener(Wt,this._onCustomTimeChange),this._video=s,this._currentTime=s.source.currentTime,this._duration=s.source.duration,this._updateDisplay()):n.classList.add(r.UNAVAILABLE)}destroy(){const t=this._video;t&&(this.element.className="",t.source.removeEventListener(lt,this._onTimeUpdate),t.source.removeEventListener(ct,this._onDurationChange),t.source.removeEventListener(Wt,this._onCustomTimeChange),this._video=null)}_updateDisplay(){const t=this._currentTime,e=Math.floor(t/60),i=Math.floor(t-60*e),s=i<10?`0${i}`:i,n=this._duration,r=Math.floor(n/60),o=Math.floor(n-60*r),a=o<10?`0${o}`:o;this.element.innerText=`${e}:${s} / ${r}:${a}`}}class wi extends pi{constructor({resetCamera:t=!0,position:e=vi.TOP_RIGHT,order:i=9999}={}){super({position:e,order:i}),this._onClick=()=>{const t=this._viewer,e=this.resetCamera;if(!t||!e)return;const{yaw:i=t.initialYaw,pitch:s=t.initialPitch,zoom:n=t.initialZoom,duration:r=500}=ne(e);t.camera.animateTo({yaw:i,pitch:s,zoom:n,duration:r})},this._updatePie=({target:t})=>{const e=this._piePathEl,i=this._rangeCircleEl,s=t.camera,n=s.getHorizontalFov(),r=s.getYawRange(s.zoom),o=.5*n,a=24*Math.PI,h=a*n/360,l=a*(s.yaw+o+90)/360;if(e.setAttribute("stroke-dasharray",`${h} ${a-h}`),e.setAttribute("stroke-dashoffset",`${l}`),isFinite(r.min)&&isFinite(r.max)){const t=45*Math.PI,e=(ie(r.min,-180,180)-o)/360,s=(ie(r.max,-180,180)+o)/360,n=t*Math.abs(s-e),a=-t*(e-.25);i.setAttribute("stroke-dasharray",`${n} ${t-n}`),i.setAttribute("stroke-dashoffset",`${a}`)}else i.setAttribute("stroke-dasharray",""),i.setAttribute("stroke-dashoffset","")},this.element=document.createElement(mt),this.element.title="Reset view",this.resetCamera=t,this._createPieElements(),this._viewer=null}init(t,e){const i=this.element;t.initialized?this._updatePie({target:t}):t.once(Ot.READY,this._updatePie);const s=e.className.PIEVIEW_ROOT;i.classList.add(s),this.resetCamera&&i.addEventListener(J,this._onClick),t.on(Ot.VIEW_CHANGE,this._updatePie),this._viewer=t}destroy(t){const e=this.element;e.removeEventListener(J,this._onClick),e.className="",t.off(Ot.READY,this._updatePie),t.off(Ot.VIEW_CHANGE,this._updatePie),this._viewer=null}_createPieElements(){const t=this.element,e=document.createElementNS(Xt,"svg");e.setAttribute("viewBox","0 0 48 48"),e.setAttribute("width","100%"),e.setAttribute("height","100%");const i=document.createElementNS(Xt,"circle");i.setAttribute("stroke","currentColor"),i.setAttribute("fill","transparent"),i.setAttribute("cx","24"),i.setAttribute("cy","24"),i.setAttribute("r","12"),i.setAttribute("stroke-width","24"),e.appendChild(i);const s=document.createElementNS(Xt,"circle");s.setAttribute("stroke","currentColor"),s.setAttribute("fill","transparent"),s.setAttribute("cx","24"),s.setAttribute("cy","24"),s.setAttribute("r","22.5"),s.setAttribute("stroke-width","3"),e.appendChild(s),t.appendChild(e),this._piePathEl=i,this._rangeCircleEl=s}}class Ci extends pi{constructor({position:t=vi.MAIN_RIGHT,order:e=9999}={}){super({position:t,order:e}),this._onClick=()=>{const t=this._viewer;t&&t.vr.enter()},this.element=document.createElement(pt),this.element.title="Enter VR",this._viewer=null}init(t,e){const i=this.element,s=e.className;i.classList.add(s.UNAVAILABLE),i.classList.add(s.VR_BUTTON),i.classList.add(s.CONTROLS_BUTTON),t.vr.isAvailable().then((t=>{t&&i.classList.remove(s.UNAVAILABLE)})),i.addEventListener(J,this._onClick),this._viewer=t}destroy(){const t=this.element;t.className="",t.removeEventListener(J,this._onClick),this._viewer=null}}class Li extends pi{constructor({position:t=vi.MAIN_RIGHT,order:e=9999}={}){super({position:t,order:e}),this._onClick=()=>{const t=this._viewer,e=this._controlBar;if(!t||!e)return;const i=t.control.gyro;i.enabled?i.disable():Re.requestSensorPermission().then((t=>{t?i.enable():this.element.classList.add(e.className.UNAVAILABLE)}))},this._updateStyle=()=>{const t=this.element,e=this._viewer,i=this._controlBar;if(!e||!i)return;const s=e.control.gyro,n=i.className;s.enabled?(t.classList.add(n.GYRO_ENABLED),t.classList.remove(n.GYRO_DISABLED)):(t.classList.add(n.GYRO_DISABLED),t.classList.remove(n.GYRO_ENABLED))},this.element=document.createElement(mt),this.element.title="Toggle gyroscope control"}init(t,e){const i=this.element,s=e.className;i.addEventListener(J,this._onClick),i.classList.add(s.CONTROLS_BUTTON),i.classList.add(s.UNAVAILABLE);const n=()=>{i.classList.remove(s.UNAVAILABLE),t.control.gyro.on(Dt,this._updateStyle),t.control.gyro.on(Ut,this._updateStyle)};he()?n():Re.isAvailable().then((t=>{t&&n()})),this._controlBar=e,this._viewer=t,this._updateStyle()}destroy(t){const e=this.element;t.control.gyro.off(Dt,this._updateStyle),t.control.gyro.off(Ut,this._updateStyle),e.removeEventListener(J,this._onClick),e.className="",this._controlBar=null,this._viewer=null}}class xi{get enabled(){return!!this._targetEl}get hidden(){return this._controlBar.containerEl.classList.contains(this._hiddenClass)}get _hiddenClass(){return this._controlBar.className.HIDDEN}get _fixedClass(){return this._controlBar.className.FIXED}constructor(t,{initialDelay:e=3e3,delay:i=0,idleDelay:s=3e3}){this._onMouseEnter=()=>{this._isCursorInside=!0,this.show()},this._onMouseLeave=()=>{this._isCursorInside=!1,this._hideAfterDelay()},this._onMouseMove=()=>{this._isFullscreen&&this.showTemporaliy()},this._onHold=t=>{this._isGrabbing=!0,"mouse"===t.pointerType&&(this._isCursorInside=!0),window.addEventListener(k,this._onRelease),this.show()},this._onRelease=()=>{this._isGrabbing=!1,window.removeEventListener(k,this._onRelease),this._hideAfterDelay()},this._onVideoPlay=()=>{this._targetEl&&this._controlBar.containerEl.classList.remove(this._fixedClass)},this._onVideoPause=()=>{this._targetEl&&this._controlBar.containerEl.classList.add(this._fixedClass)},this._onFullscreenChange=()=>{this._isFullscreen=ae(),this._isFullscreen&&this._hideAfterDelay()},this._controlBar=t,this._initialDelay=e,this._delay=i,this._idleDelay=s,this._timer=-1,this._isCursorInside=!1,this._isGrabbing=!1,this._isFullscreen=!1,this._video=null,this._targetEl=null}enable(t){var e;this._targetEl&&this.disable(t);const i=this._initialDelay,s=t.rootEl;this._targetEl=t.rootEl,this._timer=window.setTimeout((()=>{this.hide()}),i),s.addEventListener(z,this._onHold),s.addEventListener(K,this._onMouseEnter),s.addEventListener(V,this._onMouseMove),s.addEventListener(q,this._onMouseLeave),this._addFullscreenHandlers();const n=null===(e=t.projection)||void 0===e?void 0:e.getTexture();n&&n.isVideo()&&(n.isPaused()&&this._controlBar.containerEl.classList.add(this._fixedClass),n.source.addEventListener(rt,this._onVideoPlay),n.source.addEventListener(ot,this._onVideoPause),this._video=n)}disable(t){if(!this._targetEl)return;const e=this._controlBar,i=t.rootEl,s=this._video;i.removeEventListener(z,this._onHold),window.removeEventListener(k,this._onRelease),i.removeEventListener(K,this._onMouseEnter),i.removeEventListener(V,this._onMouseMove),i.removeEventListener(q,this._onMouseLeave),this._removeFullscreenHandlers(),window.clearTimeout(this._timer),e.containerEl.classList.remove(this._fixedClass),s&&(s.source.removeEventListener(rt,this._onVideoPlay),s.source.removeEventListener(ot,this._onVideoPause)),this._isCursorInside=!1,this._isGrabbing=!1,this._video=null,this._targetEl=null}show(){this._clearHideTimer(),this._controlBar.containerEl.classList.remove(this._hiddenClass)}showTemporaliy(){this.show(),this._hideAfterDelay(this._idleDelay)}hide(){this._clearHideTimer(),this._controlBar.containerEl.classList.add(this._hiddenClass)}_clearHideTimer(){this._timer&&(window.clearTimeout(this._timer),this._timer=-1)}_hideAfterDelay(t=this._delay){this._isGrabbing||!this._isFullscreen&&this._isCursorInside||(this._clearHideTimer(),t<=0?this.hide():this._timer=window.setTimeout((()=>{this.hide()}),t))}_addFullscreenHandlers(){Lt.forEach((t=>{document.addEventListener(t,this._onFullscreenChange)}))}_removeFullscreenHandlers(){Lt.forEach((t=>{document.removeEventListener(t,this._onFullscreenChange)}))}}class Oi{constructor(){this._onKeyDown=t=>{const e=this._video;if(!e)return;t.preventDefault(),t.stopPropagation();const i=e.source,s=null!=t.keyCode?bt[t.keyCode]:Tt[t.key];switch(s){case"LEFT":case"RIGHT":return this._changeVideoTime(i,"RIGHT"===s);case"UP":case"DOWN":return this._changeVideoVolume(i,"UP"===s)}(32===t.keyCode||" "===t.key)&&this._toggleVideo(e)}}enable(t,e){this._video=e,t.addEventListener(Z,this._onKeyDown,!0)}disable(t){this._video=null,t.removeEventListener(Z,this._onKeyDown,!0)}_changeVideoTime(t,e){const i=e?5:-5;t.currentTime+=i,t.dispatchEvent(new CustomEvent(Wt,{detail:{time:t.currentTime}}))}_changeVideoVolume(t,e){const i=e?.1:-.1;t.muted?t.volume=te(i,0,1):t.volume=te(t.volume+i,0,1),t.volume>0?t.muted=!1:t.muted=!0}_toggleVideo(t){t.isPaused()?t.source.play():t.source.pause()}}class Ai{get rootEl(){return this._rootEl}get containerEl(){return this._containerEl}get backgroundEl(){return this._bgEl}get items(){return this._items}get customItems(){return this._customItems}constructor({autoHide:t,showBackground:e,clickToPlay:i=!0,keyboardControls:s=!0,progressBar:n=!0,playButton:r=!0,volumeButton:o=!0,fullscreenButton:a=!0,videoTime:h=!0,pieView:l=!0,vrButton:c=!0,gyroButton:u=!0,className:_={},customItems:d=[]}={}){var m;this._onStaticClick=({target:t,isTouch:e})=>{var i;const s=this._autoHider;if(e){if(!s.enabled)return;s.hidden?s.showTemporaliy():s.hide()}else{if(!this.clickToPlay)return;const e=null===(i=t.projection)||void 0===i?void 0:i.getTexture();if(!e||!e.isVideo())return;e.isPaused()?e.source.play():e.source.pause()}},this._onNewSrcLoad=({target:t})=>{const e=this._items;this._updateBackground(t),this._updateAutoHide(t),this._updateKeyboardHandler(t),Object.keys(e).forEach((i=>{e[i].forEach((e=>{e.destroy(t,this),e.init(t,this)}))}))},this.autoHide=t,this.showBackground=e,this.clickToPlay=i,this.keyboardControls=s,this.progressBar=n,this.playButton=r,this.volumeButton=o,this.fullscreenButton=a,this.videoTime=h,this.pieView=l,this.vrButton=c,this.gyroButton=u,this.className=Object.assign(Object.assign({},Ai.DEFAULT_CLASS),_);const p=null!==(m=_.CONTROLS_ROOT)&&void 0!==m?m:Ai.DEFAULT_CLASS.CONTROLS_ROOT;this._rootEl=Jt(p),this._createPositionWrappers(),this._items=Object.keys(Ai.POSITION).reduce(((t,e)=>(t[Ai.POSITION[e]]=[],t)),{}),this._customItems=d,this._autoHider=new xi(this,ne(t)),this._videoControl=new Oi,d.forEach((t=>{this._items[t.position].push(t)}))}init(t){const e=t.rootEl,i=this._rootEl,s=this._createDefaultItems();this._updateBackground(t),this._updateAutoHide(t),this._updateKeyboardHandler(t),e.appendChild(i),this._addItem(t,s),this._addItem(t,this._customItems),t.on(Ot.PROJECTION_CHANGE,this._onNewSrcLoad),t.on(Ot.STATIC_CLICK,this._onStaticClick)}destroy(t){const e=t.rootEl,i=this._rootEl,s=this._items;i.parentElement===e&&e.removeChild(i),Object.keys(s).forEach((e=>{s[e].forEach((e=>{e.destroy(t,this)})),s[e]=[]})),this._clearItemElements(),this._autoHider.disable(t),this._videoControl.disable(e),t.off(Ot.PROJECTION_CHANGE,this._onNewSrcLoad),t.off(Ot.STATIC_CLICK,this._onStaticClick)}_addItem(t,e){for(const i of e){const e=this._items[i.position],s=this._wrapperEl[i.position],n=se(e,(t=>t.order>i.order));if(n>=0){const t=e[n].element;e.splice(n,0,i),s.insertBefore(i.element,t)}else e.push(i),s.appendChild(i.element);i.init(t,this)}}_createPositionWrappers(){const t=Object.assign(Object.assign({},Ai.DEFAULT_CLASS),this.className),e=this._rootEl,i=Jt(t.CONTROLS_BG),s=Jt(t.CONTROLS_FLOAT_LEFT),n=Jt(t.CONTROLS_FLOAT_RIGHT);e.appendChild(s),e.appendChild(n);const r=Jt(t.CONTROLS_MAIN),o=Jt(t.CONTROLS_TOP),a=Jt(t.CONTROLS_BOTTOM),h=Jt(t.CONTROLS_MID),l=Jt(t.CONTROLS_LEFT),c=Jt(t.CONTROLS_RIGHT);h.appendChild(l),h.appendChild(c),r.appendChild(i),r.appendChild(o),r.appendChild(h),r.appendChild(a),e.appendChild(r),this._bgEl=i,this._containerEl=r,this._wrapperEl={[Ai.POSITION.MAIN_TOP]:o,[Ai.POSITION.MAIN_LEFT]:l,[Ai.POSITION.MAIN_RIGHT]:c,[Ai.POSITION.MAIN_BOTTOM]:a,[Ai.POSITION.TOP_LEFT]:s,[Ai.POSITION.TOP_RIGHT]:n}}_clearItemElements(){Object.keys(Ai.POSITION).map((t=>Ai.POSITION[t])).forEach((t=>{for(;t.firstChild;)t.removeChild(t.firstChild)}))}_updateAutoHide(t){var e;const i=this.autoHide,s=this._autoHider;if(null!=i)i?s.enable(t):s.disable(t);else{const i=null===(e=t.projection)||void 0===e?void 0:e.getTexture();i&&i.isVideo()?s.enable(t):s.disable(t)}}_updateBackground(t){var e,i;const s=this._bgEl,n=this.showBackground,r=null!==(e=this.className.HIDDEN)&&void 0!==e?e:Ai.DEFAULT_CLASS.HIDDEN;if(null!=n)n?s.classList.remove(r):s.classList.add(r);else{const e=null===(i=t.projection)||void 0===i?void 0:i.getTexture();e&&e.isVideo()?s.classList.remove(r):s.classList.add(r)}}_updateKeyboardHandler(t){var e;const i=t.rootEl,s=this._videoControl,n=null===(e=t.projection)||void 0===e?void 0:e.getTexture();this.keyboardControls&&n&&n.isVideo()?s.enable(i,n):s.disable(i)}_createDefaultItems(){const t=[];return this.progressBar&&t.push(new fi(ne(this.progressBar))),this.playButton&&t.push(new yi(ne(this.playButton))),this.volumeButton&&t.push(new bi(ne(this.volumeButton))),this.gyroButton&&t.push(new Li(ne(this.gyroButton))),this.vrButton&&t.push(new Ci(ne(this.vrButton))),this.fullscreenButton&&t.push(new Ti(ne(this.fullscreenButton))),this.videoTime&&t.push(new Ri(ne(this.videoTime))),this.pieView&&t.push(new wi(ne(this.pieView))),t}}Ai.DEFAULT_CLASS=gi,Ai.POSITION=vi;class Ii{constructor({src:t,video:e=!1}){this.src=t,this.video=e,this._mesh=null}releaseAllResources(t){var e;null===(e=this._mesh)||void 0===e||e.destroy(t)}updateCamera(t){t.resetRange()}updateControl(t){t.ignoreZoomScale=!1}update(t){}getTexture(){return this._mesh?this._mesh.program.uniforms.uTexture.texture:null}getMesh(){return this._mesh}}class Si{constructor(){this.needsUpdate=!0}destroy(t){}}class Pi extends Si{constructor(t,e,i){super(),this.texture=e,this._webglTexture=t.createWebGLCubeTexture(e,e.width),this._cubemapOrder=i}destroy(t){this.texture.destroy(),t.deleteTexture(this._webglTexture)}update(t,e,i){const s=this.texture;t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,s.flipY),t.uniform1i(e,0),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_CUBE_MAP,this._webglTexture);oe(s.sources,this._cubemapOrder).forEach(((e,s)=>{i?t.texSubImage2D(t.TEXTURE_CUBE_MAP_POSITIVE_X+s,0,0,0,t.RGBA,t.UNSIGNED_BYTE,e):t.texImage2D(t.TEXTURE_CUBE_MAP_POSITIVE_X+s,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e)})),s.isVideo()||(this.needsUpdate=!1)}}class Ni{get size(){return this._size}constructor(t,e){var i;this.texture=t,this._renderingOrder=oe(!(i=6)||i<=0?[]:Array.apply(0,Array(i)).map(((t,e)=>e)),e);const s=document.createElement("canvas");this._calcRenderingSize(),s.width=this._size,s.height=this._size,this._canvas=s,this._ctx=s.getContext("2d")}destroy(){const t=this._canvas;t.width=1,t.height=1,this._canvas=null}draw(t,e){const i=this._size,s=this.texture;let n=0;for(let r=0;r=0;t--)for(let e=0;e<3;e++){const n=[e*i,.5*t,(e+1)*i,.5*t,(e+1)*i,.5*(t+1),e*i,.5*(t+1)];s.push(n)}e&&e.forEach(((t,e)=>{if(t===jt.ZERO)return;const i=s[e];let n;n=t===jt.CW_90?[1,2,3,0]:t===jt.CCW_90?[3,0,1,2]:[2,3,0,1];const r=Array(i.length);for(let t=0;tt.concat(e)),[]))}}class Vi extends Si{constructor(t,e){super(),this.texture=e,this._webglTexture=t.createWebGLTexture(e)}destroy(t){this.texture.destroy(),t.deleteTexture(this._webglTexture)}update(t,e,i){const s=this.texture,n=s.isVideo();t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,s.flipY),t.uniform1i(e,0),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this._webglTexture),!n&&i?t.texSubImage2D(t.TEXTURE_2D,0,0,0,t.RGBA,t.UNSIGNED_BYTE,s.source):t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,s.source),n||(this.needsUpdate=!1)}}var ki="#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec2 vUV;void main(){vUV=uv;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}",Gi="#define GLSLIFY 1\nuniform sampler2D uTexture;varying highp vec2 vUV;void main(){gl_FragColor=texture2D(uTexture,vUV.st);}";class Hi extends Fi{constructor(t){const e=[],i=[],s=[],n=[-.5,.5],r=1/60,o=t*r;for(let a=0;a<2;a++){const h=n[a];for(let n=0;n<=60;n++){const l=n*o+Math.PI-.5*t,c=Math.cos(l),u=Math.sin(l),_=n*r,d=a;if(s.push(_,d),e.push(c,h,u),0===a&&n<60){const t=n,e=t+60+1;i.push(t,e,t+1,e,e+1,t+1)}}}super(e,i,s)}}class Yi extends Fi{constructor(){const t=60,e=-.5*Math.PI,i=[],s=[],n=[];let r,o;for(r=0;r<=60;r++){const a=(r/60-.5)*Math.PI,h=Math.sin(a),l=Math.cos(a);for(o=0;o<=t;o++){const a=2*(o/t-.5)*Math.PI+e,c=Math.sin(a),u=Math.cos(a)*l,_=h,d=c*l,m=o/t,p=r/60;if(i.push(m,p),s.push(u,_,d),o!==t&&60!==r){const e=61*r+o,i=e+t+1;n.push(e,e+1,i,i,e+1,i+1)}}}super(s,n,i)}}class ji extends Si{constructor(t){super(),this.val=t}update(t,e){t.uniform1f(e,this.val),this.needsUpdate=!1}}class Wi extends Fi{constructor(t=2,e=2,i=-1){const s=.5*t,n=.5*e;super([-s,-n,i,s,-n,i,-s,n,i,s,n,i],[0,1,2,2,1,3],[0,0,1,0,0,1,1,1])}}class Xi extends Si{constructor(t){super(),this.val=t}update(t,e){t.uniform4fv(e,this.val.reduce(((t,e)=>[...t,...e]),[])),this.needsUpdate=!1}}class Ki extends Ii{constructor(t){super(t),this._mode=t.mode}applyTexture(t,e){let i,s;if(this._mode===Ki.MODE.LEFT_RIGHT)i=[.5,1,0,0],s=[.5,1,.5,0];else i=[1,.5,0,0],s=[1,.5,0,.5];const n={uTexture:new Vi(t,e),uEye:new ji(0),uTexScaleOffset:new Xi([i,s])},r=new Yi,o=new Ui(t,"#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;uniform vec4 uTexScaleOffset[2];uniform float uEye;varying highp vec2 vUV;void main(){vec4 scaleOffset=uTexScaleOffset[int(uEye)];vUV=uv.xy*scaleOffset.xy+scaleOffset.zw;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}",Gi,n),a=t.createVAO(r,o),h=new Di(a,o);this._mesh=h}}Ki.MODE={LEFT_RIGHT:"left_right",TOP_BOTTOM:"top_bottom"};var qi={__proto__:null,default:_i,Autoplay:ri,AutoResizer:ni,Camera:de,CameraAnimation:_e,Motion:ue,Object3D:di,View360Error:D,WebGLRenderer:ui,XRManager:oi,PanoControl:we,RotateControl:ve,ZoomControl:ye,GyroControl:Re,ControlBar:Ai,ControlBarItem:pi,FullscreenButton:Ti,PieView:wi,PlayButton:yi,ProgressBar:fi,VideoTime:Ri,VolumeControl:bi,LoadingSpinner:mi,Projection:Ii,CubemapProjection:class extends Ii{constructor(t){super(t);const{cubemapOrder:e="RLUDFB",cubemapFlipX:i=!1}=t;this._cubemapOrder=e,this._cubemapFlipX=i}applyTexture(t,e){const i=this._cubemapOrder,s=this._cubemapFlipX,n={uTexture:e.isCube()?new Pi(t,e,i):new Mi(t,e,i)},r=new zi({order:i}),o=new Ui(t,"#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec3 vPos;void main(){vPos=position;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}","#define GLSLIFY 1\nuniform samplerCube uTexture;varying highp vec3 vPos;void main(){gl_FragColor=textureCube(uTexture,vec3(vPos.x,vPos.y,-vPos.z));}",n),a=t.createVAO(r,o),h=new Di(a,o);s&&(h.scale[0]=-1),h.updateMatrix(),this._mesh=h}},CubestripProjection:class extends Ii{constructor(t){super(t);const{cubemapOrder:e="RLUDFB",cubemapFlipX:i=!1}=t;this._cubemapOrder=e,this._cubemapFlipX=i}applyTexture(t,e){const i=this._cubemapOrder,s=this._cubemapFlipX,n={uTexture:new Vi(t,e)},r=new zi({order:i}),o=new Ui(t,ki,Gi,n),a=t.createVAO(r,o),h=new Di(a,o);s&&(h.scale[0]=-1),h.updateMatrix(),this._mesh=h}},CylindricalProjection:class extends Ii{constructor(t){super(t);const{partial:e=!1}=t;this._partial=e}applyTexture(t,e){const i=this._partial,{width:s,height:n}=e,r=s/n,o=180/r,a=i?1:2*Math.tan(o*Ft),h=i?r:2*Math.PI,l=new Hi(h),c=new Ui(t,ki,Gi,{uTexture:new Vi(t,e)}),u=t.createVAO(l,c),_=new Di(u,c);_.scale[1]=a,T(_.rotation),C(_.rotation,_.rotation,-Math.PI/2),_.updateMatrix(),this._mesh=_}updateCamera(t){super.updateCamera(t);const e=this._mesh;if(!e)return;const i=e.program.uniforms.uTexture.texture,{width:s,height:n}=i,r=s/n,o=.5*e.scale[1];if(this._partial){const e=.5*r*zt;t.restrictYawRange(-e,e)}const a=Math.atan2(o,1)*zt,h=Math.tan(t.fov*Ft*.5)/(o*t.aspect);t.restrictPitchRange(-a,a),t.restrictZoomRange(h,1/0),t.restrictRenderHeight(2*o)}},EquiangularProjection:class extends Ii{applyTexture(t,e){const i={uTexture:new Vi(t,e)},s=new zi({order:"LFRDBU",rotateUV:[jt.ZERO,jt.ZERO,jt.ZERO,jt.CW_90,jt.CCW_90,jt.CW_90]}),n=new Ui(t,ki,"#define PI 3.14159265359\nprecision mediump float;\n#define GLSLIFY 1\nuniform sampler2D uTexture;varying highp vec2 vUV;const vec2 OPERATE_COORDS_RANGE=vec2(-1.0,1.0);const vec2 TEXTURE_COORDS_RANGE=vec2(0.0,1.0);const float ONE_THIRD=1.0/3.0;const float EAC_CONST=2.0/PI;float scale(vec2 domainRange,vec2 targetRange,float val){float unit=1.0/(domainRange[1]-domainRange[0]);return targetRange[0]+(targetRange[1]-targetRange[0])*(val-domainRange[0])*unit;}void main(void){float transformedCoordX;float transformedCoordY;float texRangeXStart=floor(vUV.s*3.)*ONE_THIRD;float texRangeYStart=floor(vUV.t*2.)*0.5;vec2 orgTextureRangeX=vec2(texRangeXStart,texRangeXStart+ONE_THIRD);vec2 orgTextureRangeY=vec2(texRangeYStart,texRangeYStart+0.5);float px=scale(orgTextureRangeX,OPERATE_COORDS_RANGE,vUV.s);float py=scale(orgTextureRangeY,OPERATE_COORDS_RANGE,vUV.t);float qu=EAC_CONST*atan(px)+0.5;float qv=EAC_CONST*atan(py)+0.5;transformedCoordX=scale(TEXTURE_COORDS_RANGE,orgTextureRangeX,qu);transformedCoordY=scale(TEXTURE_COORDS_RANGE,orgTextureRangeY,qv);gl_FragColor=texture2D(uTexture,vec2(transformedCoordX,transformedCoordY));}",i),r=t.createVAO(s,n),o=new Di(r,n);this._mesh=o}},EquirectProjection:class extends Ii{constructor(t){super(t)}applyTexture(t,e){const i={uTexture:new Vi(t,e)},s=new Yi,n=new Ui(t,ki,Gi,i),r=t.createVAO(s,n),o=new Di(r,n);this._mesh=o}},LittlePlanetProjection:class extends Ii{constructor(t){super(t)}applyTexture(t,e){e.wrapS=WebGLRenderingContext.REPEAT,e.wrapT=WebGLRenderingContext.REPEAT;const i={uTexture:new Vi(t,e),uYaw:new ji(0),uPitch:new ji(.5),uZoom:new ji(1)},s=new Wi,n=new Ui(t,"#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec2 vUV;void main(){vUV=uv;gl_Position=vec4(position,1.0);}","precision mediump float;\n#define GLSLIFY 1\nuniform sampler2D uTexture;uniform float uYaw;uniform float uPitch;uniform float uZoom;varying highp vec2 vUV;const float PI=3.1415926536;const float PI_2=PI*0.5;vec2 toStereographicUV(in vec2 uv,in vec2 center){float R=1.*uZoom;vec2 texLatLon=(uv*2.-1.)*vec2(PI,PI_2);vec2 central=(center*2.-1.)*vec2(PI,PI_2)+vec2(PI,0);float x=texLatLon.x;float y=texLatLon.y;float rou=sqrt(x*x+y*y);float c=2.0*atan(rou,R*0.5);float sin_c=sin(c);float cos_c=cos(c);float sin_cy=sin(central.y);float cos_cy=cos(central.y);float lat=asin(cos_c*sin_cy+(y*sin_c*cos_cy)/rou);float lon=central.x+atan(x*sin_c,rou*cos_cy*cos_c-y*sin_cy*sin_c);float u=(lon/PI+1.0)*0.5;float v=(lat/PI_2+1.0)*0.5;return vec2(u,v);}void main(){vec2 central=vec2(uYaw,uPitch);vec2 uv=toStereographicUV(vUV,central);gl_FragColor=texture2D(uTexture,uv);}",i),r=t.createVAO(s,n),o=new Di(r,n);this._mesh=o}updateControl(t){t.ignoreZoomScale=!0}update(t){const e=this._mesh;if(!e)return;const i=e.program.uniforms;i.uYaw.val=t.yaw/360,i.uPitch.val=t.pitch/180+.5,i.uZoom.val=t.zoom,i.uYaw.needsUpdate=!0,i.uPitch.needsUpdate=!0,i.uZoom.needsUpdate=!0}},StereoEquiProjection:Ki,Hotspot:ai,HotspotRenderer:hi,ERROR_CODES:U,DEFAULT_CLASS:xt,EVENTS:Ot,EASING:At,getValidProps:t=>Object.keys(t).reduce(((e,i)=>(null!=t[i]&&(e[i]=t[i]),e)),{}),VIEW360_METHODS:["destroy","init","load","resize","addPlugins","removePlugins","renderFrame","on","hasOn","once","off","trigger"],withMethods:(t,e)=>{[o.prototype,_i.prototype].forEach((i=>{Object.getOwnPropertyNames(i).filter((t=>"_"!==t.charAt(0)&&"constructor"!==t)).forEach((s=>{const n=Object.getOwnPropertyDescriptor(i,s);if(n.value)Object.defineProperty(t,s,{value:function(...t){return n.value.call(this[e],...t)}});else{const i={};n.get&&(i.get=function(){var t;return this[e]&&(null===(t=n.get)||void 0===t?void 0:t.call(this[e]))}),n.set&&(i.set=function(...t){var i;return null===(i=n.set)||void 0===i?void 0:i.call(this[e],...t)}),Object.defineProperty(t,s,i)}}))}))}};return((t,...e)=>{e.forEach((e=>{Object.keys(e).forEach((i=>{const s=e[i];Array.isArray(t[i])&&Array.isArray(s)?t[i]=[...t[i],...s]:t[i]=s}))}))})(_i,qi),_i})); +//# sourceMappingURL=view360.pkgd.min.js.map diff --git a/demo/release/4.0.0-beta.4/dist/view360.pkgd.min.js.map b/demo/release/4.0.0-beta.4/dist/view360.pkgd.min.js.map new file mode 100644 index 000000000..3e5ef0a23 --- /dev/null +++ b/demo/release/4.0.0-beta.4/dist/view360.pkgd.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"view360.pkgd.min.js","sources":["../src/core/View360Error.ts","../src/const/error.ts","../src/const/browser.ts","../src/const/external.ts","../src/const/internal.ts","../src/utils.ts","../src/core/Motion.ts","../src/core/CameraAnimation.ts","../src/core/Camera.ts","../src/control/input/MouseInput.ts","../src/control/input/TouchInput.ts","../src/control/input/KeyboardInput.ts","../src/control/RotateControl.ts","../src/control/input/WheelInput.ts","../src/control/input/PinchInput.ts","../src/control/ZoomControl.ts","../src/control/input/GyroInput.ts","../src/control/GyroControl.ts","../src/control/PanoControl.ts","../src/texture/Texture.ts","../src/texture/Texture2D.ts","../src/texture/TextureVideo.ts","../src/texture/TextureCube.ts","../src/core/TextureLoader.ts","../src/core/FrameAnimator.ts","../src/core/AutoResizer.ts","../src/core/Autoplay.ts","../src/core/XRManager.ts","../src/hotspot/Hotspot.ts","../src/hotspot/HotspotRenderer.ts","../src/core/VertexArrayObject.ts","../src/core/WebGLContext.ts","../src/core/WebGLRenderer.ts","../src/View360.ts","../src/core/Object3D.ts","../src/plugin/LoadingSpinner/LoadingSpinner.ts","../src/plugin/ControlBar/ControlBarItem.ts","../src/plugin/ControlBar/const.ts","../src/plugin/ControlBar/RangeControl.ts","../src/plugin/ControlBar/ProgressBar.ts","../src/plugin/ControlBar/PlayButton.ts","../src/plugin/ControlBar/VolumeControl.ts","../src/plugin/ControlBar/FullscreenButton.ts","../src/plugin/ControlBar/VideoTime.ts","../src/plugin/ControlBar/PieView.ts","../src/plugin/ControlBar/VRButton.ts","../src/plugin/ControlBar/GyroButton.ts","../src/plugin/ControlBar/AutoHide.ts","../src/plugin/ControlBar/VideoControl.ts","../src/plugin/ControlBar/ControlBar.ts","../src/projection/Projection.ts","../src/uniform/Uniform.ts","../src/uniform/UniformTextureCube.ts","../src/core/CubeTexturePainter.ts","../src/uniform/UniformCanvasCube.ts","../src/core/TriangleMesh.ts","../src/core/ShaderProgram.ts","../src/core/VertexData.ts","../src/geometry/Geometry.ts","../src/geometry/CubeGeometry.ts","../src/uniform/UniformTexture2D.ts","../src/geometry/CylinderGeometry.ts","../src/geometry/SphereGeometry.ts","../src/uniform/UniformFloat.ts","../src/geometry/PlaneGeometry.ts","../src/uniform/UniformVector4Array.ts","../src/projection/StereoEquiProjection.ts","../src/projection/CubemapProjection.ts","../src/projection/CubestripProjection.ts","../src/projection/CylindricalProjection.ts","../src/projection/EquiangularProjection.ts","../src/projection/EquirectProjection.ts","../src/projection/LittlePlanetProjection.ts","../src/cfc/utils.ts","../src/cfc/const.ts","../src/cfc/withMethods.ts","../src/index.umd.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * Error thrown by {@link View360}\n * @ko {@link View360}이 발생시킨 에러\n * @since 4.0.0\n */\nclass View360Error extends Error {\n /**\n * Error code\n * @ko 에러 코드\n * @see ERROR_CODES\n */\n public code: number;\n\n /**\n * Create new instance of View360Error\n * @ko View360Error의 인스턴스를 생성합니다.\n * @param message - Error message {@ko 에러 메시지}\n * @param code - Error code {@ko 에러 코드}\n */\n public constructor(message: string, code: number) {\n super(message);\n\n Object.setPrototypeOf(this, View360Error.prototype);\n\n this.name = \"View360Error\";\n this.code = code;\n }\n}\n\nexport default View360Error;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * Error codes of {@link View360Error}\n * @ko {@link View360Error}가 가질 수 있는 에러 코드 값들\n * @since 4.0.0\n */\nexport const ERROR_CODES = {\n /**\n * The given value's type is not expected\n * @ko 주어진 값의 타입이 잘못되었을 경우\n * @since 4.0.0\n */\n WRONG_TYPE: 0,\n /**\n * The given value is not a supported option\n * @ko 잘못된 옵션을 받았을 경우\n * @since 4.0.0\n */\n WRONG_OPTION: 1,\n /**\n * The element with given CSS selector does not exist\n * @ko 주어진 CSS 셀렉터로 엘리먼트를 찾지 못했을 경우\n * @since 4.0.0\n */\n ELEMENT_NOT_FOUND: 2,\n /**\n * Couldn't find canvas element inside the given container element.\n * @ko 컨테이너 엘리먼트 내부에서 캔버스 엘리먼트를 찾지 못했을 경우\n * @since 4.0.0\n */\n CANVAS_NOT_FOUND: 3,\n /**\n * The browser does not support WebGL\n * @ko 브라우저가 WebGL을 지원하지 않는 경우\n * @since 4.0.0\n */\n WEBGL_NOT_SUPPORTED: 4,\n /**\n * Failed creating canvas 2D context\n * @ko 캔버스 2D 컨텍스트를 생성하지 못한 경우\n * @since 4.0.0\n */\n FAILED_CREATE_CONTEXT_2D: 5,\n /**\n * `init()` is called before setting {@link View360Options#projection}\n * @ko {@link View360Options#projection}을 설정하기 전에 `init()`이 호출된 경우\n * @since 4.0.0\n */\n PROVIDE_PROJECTION_FIRST: 6,\n /**\n * Failed linking WebGL program. Only can be thrown when {@link View360Options#debug} is `true`.\n * @ko WebGL 프로그램 링크에 실패한 경우. {@link View360Options#debug}를 `true`로 설정한 경우에만 발생할 수 있습니다.\n * @since 4.0.0\n */\n FAILED_LINKING_PROGRAM: 7,\n /**\n * Arguments are not sufficient for the given property.\n * @ko 프로퍼티에 값이 충분히 주어지지 않았을 때\n * @since 4.0.0\n */\n INSUFFICIENT_ARGS: 8\n} as const;\n\nexport const MESSAGES = {\n WRONG_TYPE: (val: any, types: string[]) => `${typeof val} is not a ${types.map(type => `\"${type}\"`).join(\" or \")}.`,\n WRONG_OPTION: (val: any, optionName: string) => `Bad option: given \"${val}\" for option \"${optionName}\".`,\n ELEMENT_NOT_FOUND: (query: string) => `Element with selector \"${query}\" not found.`,\n CANVAS_NOT_FOUND: \"The canvas element was not found inside the given root element.\",\n WEBGL_NOT_SUPPORTED: \"WebGL is not supported on this browser.\",\n FAILED_CREATE_CONTEXT_2D: \"Failed to create canvas 2D context\",\n PROVIDE_PROJECTION_FIRST: \"\\\"projection\\\" should be provided before initialization.\",\n FAILED_LINKING_PROGRAM: (msg: string | null, shaderLog: string | null) => `Failed linking WebGL program - \"${msg}\\nShader compile Log: ${shaderLog}`,\n INSUFFICIENT_ARGS: (val: any, name: string) => `Insufficient arguments: given \"${val}\" for \"${name}\".`\n};\n\nexport default {\n CODES: ERROR_CODES,\n MESSAGES\n};\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nexport const EVENTS = {\n MOUSE_DOWN: \"mousedown\",\n MOUSE_MOVE: \"mousemove\",\n MOUSE_UP: \"mouseup\",\n TOUCH_START: \"touchstart\",\n TOUCH_MOVE: \"touchmove\",\n TOUCH_END: \"touchend\",\n WHEEL: \"wheel\",\n RESIZE: \"resize\",\n CONTEXT_MENU: \"contextmenu\",\n MOUSE_ENTER: \"mouseenter\",\n MOUSE_LEAVE: \"mouseleave\",\n POINTER_DOWN: \"pointerdown\",\n POINTER_MOVE: \"pointermove\",\n POINTER_UP: \"pointerup\",\n POINTER_CANCEL: \"pointercancel\",\n POINTER_ENTER: \"pointerenter\",\n POINTER_LEAVE: \"pointerleave\",\n KEY_DOWN: \"keydown\",\n KEY_UP: \"keyup\",\n LOAD: \"load\",\n ERROR: \"error\",\n CLICK: \"click\",\n DOUBLE_CLICK: \"dblclick\",\n CONTEXT_CREATE_ERROR: \"webglcontextcreationerror\",\n CONTEXT_LOST: \"webglcontextlost\",\n CONTEXT_RESTORED: \"webglcontextrestored\",\n DEVICE_ORIENTATION: \"deviceorientation\",\n DEVICE_MOTION: \"devicemotion\",\n ORIENTATION_CHANGE: \"orientationchange\",\n VIDEO_PLAY: \"play\",\n VIDEO_PAUSE: \"pause\",\n VIDEO_LOADED_DATA: \"loadeddata\",\n VIDEO_VOLUME_CHANGE: \"volumechange\",\n VIDEO_TIME_UPDATE: \"timeupdate\",\n VIDEO_DURATION_CHANGE: \"durationchange\",\n VIDEO_CAN_PLAYTHROUGH: \"canplaythrough\",\n TRANSITION_END: \"transitionend\",\n XR_END: \"end\"\n} as const;\n\nexport const EL_DIV = \"div\";\nexport const EL_BUTTON = \"button\";\n\n// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button\nexport enum MOUSE_BUTTON {\n LEFT,\n MIDDLE,\n RIGHT\n}\n\nexport const CURSOR = {\n GRAB: \"grab\",\n GRABBING: \"grabbing\",\n NONE: \"\"\n} as const;\n\nexport const KEY_DIRECTION = [\"LEFT\", \"UP\", \"RIGHT\", \"DOWN\"] as const;\nexport enum DIRECTION_KEY_CODE {\n LEFT = 37,\n UP = 38,\n RIGHT = 39,\n DOWN = 40\n}\nexport const SPACE_KEY_CODE = 32;\n\nexport const DIRECTION_KEY_NAME = {\n LEFT: \"ArrowLeft\",\n UP: \"ArrowUp\",\n RIGHT: \"ArrowRight\",\n DOWN: \"ArrowDown\"\n} as const;\nexport const SPACE_KEY_NAME = \" \";\n\nexport const FULLSCREEN_REQUEST = [\n \"requestFullscreen\",\n \"webkitRequestFullscreen\",\n \"webkitRequestFullScreen\",\n \"webkitCancelFullScreen\",\n \"mozRequestFullScreen\",\n \"msRequestFullscreen\"\n];\n\nexport const FULLSCREEN_ELEMENT = [\n \"fullscreenElement\",\n \"webkitFullscreenElement\",\n \"webkitCurrentFullScreenElement\",\n \"mozFullScreenElement\",\n \"msFullscreenElement\"\n];\n\nexport const FULLSCREEN_EXIT = [\n \"exitFullscreen\",\n \"webkitExitFullscreen\",\n \"webkitCancelFullScreen\",\n \"mozCancelFullScreen\",\n \"msExitFullscreen\"\n];\n\nexport const FULLSCREEN_CHANGE = [\n \"fullscreenchange\",\n \"webkitfullscreenchange\",\n \"mozfullscreenchange\",\n \"MSFullscreenChange\"\n];\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nexport { ERROR_CODES } from \"./error\";\n\n/**\n * Default class names\n * @ko 기본 클래스 이름들\n * @since 4.0.0\n */\nexport const DEFAULT_CLASS = {\n CONTAINER: \"view360-container\",\n CANVAS: \"view360-canvas\",\n CTX_LOST: \"view360-ctx-lost\",\n IN_VR: \"view360-vr-presenting\",\n HOTSPOT_CONTAINER: \"view360-hotspots\",\n HOTSPOT: \"view360-hotspot\",\n HOTSPOT_VISIBLE: \"view360-hotspot-visible\",\n HOTSPOT_FLIP_X: \"view360-hotspot-flip-x\",\n HOTSPOT_FLIP_Y: \"view360-hotspot-flip-y\",\n} as const;\n\n/**\n * Event names\n * @ko 이벤트 이름들\n * @since 4.0.0\n * @example\n * ```ts\n * import View360, { EVENTS } from \"@egjs/view360\";\n *\n * const viewer = new View360(\"#el_id\");\n *\n * viewer.on(EVENTS.READY, evt => {\n * console.log(\"View360 is ready!\");\n * });\n * ```\n */\nexport const EVENTS = {\n READY: \"ready\",\n LOAD_START: \"loadStart\",\n LOAD: \"load\",\n PROJECTION_CHANGE: \"projectionChange\",\n RESIZE: \"resize\",\n BEFORE_RENDER: \"beforeRender\",\n RENDER: \"render\",\n INPUT_START: \"inputStart\",\n INPUT_END: \"inputEnd\",\n VIEW_CHANGE: \"viewChange\",\n STATIC_CLICK: \"staticClick\",\n VR_START: \"vrStart\",\n VR_END: \"vrEnd\"\n} as const;\n\n/**\n * Collection of predefined easing functions\n * @ko 미리 정의된 easing 함수들\n */\nexport const EASING = {\n LINEAR: (x: number) => x,\n SINE_WAVE: (x: number) => Math.sin(x * Math.PI * 2),\n EASE_OUT_CUBIC: (x: number) => 1 - Math.pow(1 - x, 3),\n EASE_OUT_BOUNCE: (x: number): number => {\n const n1 = 7.5625;\n const d1 = 2.75;\n\n if (x < 1 / d1) {\n return n1 * x * x;\n } else if (x < 2 / d1) {\n return n1 * (x -= 1.5 / d1) * x + 0.75;\n } else if (x < 2.5 / d1) {\n return n1 * (x -= 2.25 / d1) * x + 0.9375;\n } else {\n return n1 * (x -= 2.625 / d1) * x + 0.984375;\n }\n }\n} as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { EASING } from \"./external\";\nimport { Range } from \"../type/utils\";\n\nexport const CAMERA_EVENTS = {\n CHANGE: \"change\",\n ANIMATION_END: \"animationEnd\"\n} as const;\n\nexport const CONTROL_EVENTS = {\n INPUT_START: \"inputStart\",\n CHANGE: \"change\",\n INPUT_END: \"inputEnd\",\n ENABLE: \"enable\",\n DISABLE: \"disable\",\n STATIC_CLICK: \"staticClick\"\n} as const;\n\nexport const DEG_TO_RAD = Math.PI / 180;\nexport const RAD_TO_DEG = 180 / Math.PI;\nexport const DEFAULT_EASING = EASING.EASE_OUT_CUBIC;\nexport const DEFAULT_ANIMATION_DURATION = 300;\nexport const INFINITE_RANGE: Readonly = {\n min: -Infinity, max: Infinity\n} as const;\nexport const DEFAULT_PITCH_RANGE: Readonly = {\n min: -90, max: 90\n} as const;\nexport const DEFAULT_ZOOM_RANGE: Readonly = {\n min: 0.6, max: 10\n} as const;\n\nexport enum ROTATE {\n ZERO,\n CW_90,\n CCW_90,\n CW_180\n}\n\n// Custom event name for video time change\nexport const VIDEO_TIME_CHANGE_EVENT = \"view360videotimechange\";\nexport const SVG_NAMESPACE = \"http://www.w3.org/2000/svg\";\nexport const SESSION_VR = \"immersive-vr\";\nexport const XR_REFERENCE_SPACE = \"local\";\n\nexport const EPSILON = Number.EPSILON ?? 2.220446049250313e-16;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { quat, vec3 } from \"gl-matrix\";\nimport View360Error from \"./core/View360Error\";\nimport ERROR from \"./const/error\";\nimport * as BROWSER from \"./const/browser\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"./const/internal\";\nimport { NoBoolean } from \"./type/utils\";\n\nexport const isString = (val: any): val is string => typeof val === \"string\";\nexport const isElement = (val: any): val is Element => !!val && val.nodeType === Node.ELEMENT_NODE;\n\nexport const createElement = (className: string, tag = BROWSER.EL_DIV) => {\n const el = document.createElement(tag);\n\n el.classList.add(className);\n\n return el;\n};\n\nexport const getNullableElement = (el: HTMLElement | string | null, parent?: HTMLElement): HTMLElement | null => {\n let targetEl: HTMLElement | null = null;\n\n if (isString(el)) {\n const parentEl = parent ? parent : document;\n const queryResult = parentEl.querySelector(el);\n\n if (!queryResult) {\n return null;\n }\n\n targetEl = queryResult as HTMLElement;\n } else if (isElement(el)) {\n targetEl = el;\n }\n\n return targetEl;\n};\n\nexport const getElement = (el: HTMLElement | string, parent?: HTMLElement): HTMLElement => {\n const targetEl = getNullableElement(el, parent);\n\n if (!targetEl) {\n if (isString(el)) {\n throw new View360Error(ERROR.MESSAGES.ELEMENT_NOT_FOUND(el), ERROR.CODES.ELEMENT_NOT_FOUND);\n } else {\n throw new View360Error(ERROR.MESSAGES.WRONG_TYPE(el, [\"HTMLElement\", \"string\"]), ERROR.CODES.WRONG_TYPE);\n }\n }\n\n return targetEl;\n};\n\nexport const findCanvas = (root: HTMLElement, selector: string): HTMLCanvasElement => {\n const canvas = root.querySelector(selector) as HTMLCanvasElement;\n\n if (!canvas) {\n throw new View360Error(ERROR.MESSAGES.CANVAS_NOT_FOUND, ERROR.CODES.CANVAS_NOT_FOUND);\n }\n\n return canvas;\n};\n\nexport const range = (end: number): number[] => {\n if (!end || end <= 0) {\n return [];\n }\n\n return Array.apply(0, Array(end)).map((undef, idx) => idx);\n};\n\nexport const clamp = (x: number, min: number, max: number) => Math.max(Math.min(x, max), min);\n\n// Linear interpolation between a and b\nexport const lerp = (a: number, b: number, t: number) => {\n return a * (1 - t) + b * t;\n};\n\nexport const circulate = (val: number, min: number, max: number) => {\n const size = Math.abs(max - min);\n\n if (val < min) {\n const offset = (min - val) % size;\n val = max - offset;\n } else if (val > max) {\n const offset = (val - max) % size;\n val = min + offset;\n }\n\n return val;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const merge = (target: object, ...srcs: object[]): object => {\n srcs.forEach(source => {\n Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n });\n });\n\n return target;\n};\n\nexport const findIndex = (array: T[], checker: (val: T) => boolean): number => {\n for (let idx = 0; idx < array.length; idx++) {\n if (checker(array[idx])) {\n return idx;\n }\n }\n\n return -1;\n};\n\nexport const getObjectOption = >(val?: T): NoBoolean => typeof val === \"object\" ? val : {} as any;\nexport const toVerticalFov = (fovRadian: number, aspect: number) => {\n return Math.atan(Math.tan(fovRadian * 0.5) / aspect) * 2;\n};\n\nexport const reorderCube = (arr: T[], order: string, defaultOrder = \"RLUDFB\"): T[] => {\n return defaultOrder.split(\"\")\n .map(face => order.indexOf(face))\n .map(index => arr[index]);\n};\n\nexport const isFullscreen = () => {\n if (!document) return false;\n\n for (const key of BROWSER.FULLSCREEN_ELEMENT) {\n if (document[key]) return true;\n }\n\n return false;\n};\n\nexport const sensorCanBeEnabledIOS = () => {\n return !!DeviceMotionEvent && \"requestPermission\" in DeviceMotionEvent && window.isSecureContext;\n};\n\nexport const hfovToZoom = (baseFov: number, fov: number) => {\n const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5);\n const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5);\n\n return renderingWidth / zoomedWidth;\n};\n\nexport const eulerToQuat = (out: quat, yaw: number, pitch: number, roll: number): quat => {\n quat.identity(out);\n\n const pitchThreshold = 0.01;\n const pitchClamped = clamp(pitch, -90 + pitchThreshold, 90 - pitchThreshold);\n\n quat.rotateY(out, out, yaw * DEG_TO_RAD);\n quat.rotateX(out, out, pitchClamped * DEG_TO_RAD);\n quat.rotateZ(out, out, roll * DEG_TO_RAD);\n\n return out;\n};\n\n/**\n * Extract euler angles from the quaternion, except roll(z-axis rotation)\n * @hidden\n */\nexport const quatToEuler = (quaternion: quat) => {\n const x = quaternion[0];\n const y = quaternion[1];\n const z = quaternion[2];\n const w = quaternion[3];\n const x2 = x * x;\n const y2 = y * y;\n const z2 = z * z;\n const w2 = w * w;\n\n const unit = x2 + y2 + z2 + w2;\n const test = x * w - y * z;\n\n let pitch: number, yaw: number;\n\n if (test > 0.499995 * unit) {\n // singularity at the north pole\n pitch = Math.PI / 2;\n yaw = 2 * Math.atan2(y, x);\n } else if (test < -0.499995 * unit) {\n // singularity at the south pole\n pitch = -Math.PI / 2;\n yaw = -2 * Math.atan2(y, x);\n } else {\n const view = vec3.fromValues(0, 0, 1);\n const up = vec3.fromValues(0, 1, 0);\n\n vec3.transformQuat(view, view, quaternion);\n vec3.transformQuat(up, up, quaternion);\n\n const viewXZ = Math.sqrt(view[0] * view[0] + view[2] * view[2]);\n\n pitch = Math.atan2(-view[1], viewXZ);\n yaw = Math.atan2(view[0], view[2]);\n }\n\n return {\n pitch: clamp(pitch * RAD_TO_DEG, -90, 90),\n yaw: circulate(yaw * RAD_TO_DEG, 0, 360)\n };\n};\n","/*\n * Copyright (c) 2020 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport { clamp, lerp, circulate } from \"../utils\";\nimport { Range } from \"../type/utils\";\nimport { DEFAULT_ANIMATION_DURATION, DEFAULT_EASING } from \"../const/internal\";\n\n/**\n * Interpolator between two values with duration\n * @ko 특정 시간동안 두 값을 보간해주는 보간기\n * @since 4.0.0\n */\nclass Motion {\n // Options\n private _duration: number;\n private _loop: boolean;\n private _range: Range;\n private _easing: (x: number) => number;\n\n // Internal states\n private _progress: number;\n private _val: number;\n private _start: number;\n private _end: number;\n private _activated: boolean;\n\n /**\n * Current interpolated value\n * @ko 현재 보간된 값\n * @since 4.0.0\n */\n public get val() { return this._val; }\n /**\n * Start(from) value of interpolation\n * @ko 보간 시작 값\n * @since 4.0.0\n */\n public get start() { return this._start; }\n /**\n * End(to) value of interpolation\n * @ko 보간 끝 값\n * @since 4.0.0\n */\n public get end() { return this._end; }\n /**\n * Interpolation progress value (0 ~ 1)\n * @ko 현재 보간 진행정도 (0 ~ 1)\n * @since 4.0.0\n */\n public get progress() { return this._progress; }\n /**\n * Whether the interpolation is in active state.\n * @ko 보간 진행중인지 여부. `true`일 경우 보간이 진행중입니다.\n * @since 4.0.0\n */\n public get activated() { return this._activated; }\n\n /**\n * Duration of the interpolation\n * @ko 보간할 시간\n * @since 4.0.0\n */\n public get duration() { return this._duration; }\n public set duration(val: number) { this._duration = val; }\n\n /**\n * Whether to loop interpolation on finish\n * @ko 보간이 끝난 이후에 다시 시작할지 여부\n * @since 4.0.0\n */\n public get loop() { return this._loop; }\n public set loop(val: boolean) { this._loop = val; }\n\n /**\n * Range of the interpolation\n * @ko 보간 범위\n * @since 4.0.0\n */\n public get range() { return this._range; }\n\n /**\n * Easing function of the interpolation\n * @ko 보간에 사용되는 easing function\n * @since 4.0.0\n */\n public get easing() { return this._easing; }\n public set easing(val: (x: number) => number) { this._easing = val; }\n\n /**\n * Create new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options Options {@ko 옵션들}\n * @param options.duration Duration of the interpolation {@ko 보간할 시간}\n * @param options.loop Whether to loop interpolation on finish {@ko 보간이 끝난 이후에 다시 시작할지 여부}\n * @param options.range Range of the interpolation {@ko 보간 범위}\n * @param options.loop Easing function of the interpolation {@ko 보간에 사용되는 easing function}\n */\n public constructor({\n duration = DEFAULT_ANIMATION_DURATION,\n loop = false,\n range = { min: 0, max: 1 },\n easing = DEFAULT_EASING\n } = {}) {\n this._duration = duration;\n this._loop = loop;\n this._range = range;\n this._easing = easing;\n this._activated = false;\n this.reset(0);\n }\n\n /**\n * Update motion and progress it by given deltaTime\n * @ko 주어진 deltaTime만큼 보간을 진행합니다.\n * @param deltaTime - number of milisec to update motion {@ko 보간을 진행할 시간, 밀리초 단위}\n * @returns Difference(delta) of the value from the last update. {@ko 지난 업데이트 이후의 값 변화량}\n * @since 4.0.0\n */\n public update(deltaTime: number): number {\n if (!this._activated) {\n this._val = this._end;\n return 0;\n }\n\n const start = this._start;\n const end = this._end;\n const duration = this._duration;\n const prev = this._val;\n const loop = this._loop;\n\n const nextProgress = this._progress + deltaTime / duration;\n\n this._progress = loop\n ? circulate(nextProgress, 0, 1)\n : clamp(nextProgress, 0, 1);\n\n const easedProgress = this._easing(this._progress);\n this._val = lerp(start, end, easedProgress);\n\n if (!loop && this._progress >= 1) {\n this._activated = false;\n }\n\n return this._val - prev;\n }\n\n /**\n * Set `start`, `end` to the given value and set `progress` to 0.\n * @ko 주어진 값으로 시작 지점, 끝 지점을 초기화하고 progress를 0으로 세팅합니다.\n * @param defaultVal - Value to reset {@ko 초기화할 값}\n * @since 4.0.0\n */\n public reset(defaultVal: number): void {\n const range = this._range;\n const val = clamp(defaultVal, range.min, range.max);\n this._start = val;\n this._end = val;\n this._val = val;\n this._progress = 0;\n this._activated = false;\n }\n\n /**\n * Add delta to start & end and current value.\n * @ko 현재 & 끝 및 현재 값에 주어진 값을 더합니다.\n * @param delta - Delta value to add {@ko 추가할 값}\n */\n public add(delta: number) {\n const range = this._range;\n\n this._start = clamp(this._start + delta, range.min, range.max);\n this._end = clamp(this._end + delta, range.min, range.max);\n this._val = clamp(this._val + delta, range.min, range.max);\n }\n\n /**\n * Set current value to start, and end to current value + delta, then reset progress to 0.\n * @ko 현재 값을 시작 지점으로, 그에서 delta만큼 추가된 값을 끝점으로 하고 progress를 0으로 갱신합니다.\n * @param delta - Delta value to add {@ko 추가할 값}\n */\n public setNewEndByDelta(delta: number): void {\n const range = this._range;\n\n this._start = this._val;\n this._end = clamp(this._end + delta, range.min, range.max);\n this._progress = 0;\n this._activated = true;\n }\n\n /**\n * Set new range of the interpolation.\n * @ko 보간의 범위를 변경합니다.\n * @param min - New minimum range {@ko 변경할 범위의 최소값}\n * @param max - New maximum range {@ko 변경할 범위의 최대값}\n */\n public setRange(min: number, max: number) {\n this._start = clamp(this._start, min, max);\n this._end = clamp(this._end, min, max);\n this._range = { min, max };\n }\n}\n\nexport default Motion;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { quat } from \"gl-matrix\";\nimport Camera from \"./Camera\";\nimport Motion from \"./Motion\";\nimport { DEFAULT_ANIMATION_DURATION, DEFAULT_EASING } from \"../const/internal\";\nimport { lerp } from \"../utils\";\n\ntype CameraPose = {\n rotation: quat;\n zoom: number;\n}\n\n/**\n * Animation of the {@link Camera}\n * @internal\n * @ko {@link Camera}의 애니메이션\n * @since 4.0.0\n */\nclass CameraAnimation {\n // Options\n private _camera: Camera;\n private _from: CameraPose;\n private _to: CameraPose;\n\n // Internal values\n private _motion: Motion;\n private _finishPromise: Promise;\n private _finish: () => void;\n\n /**\n * Duration of the animation\n * @ko 애니메이션 재생시간\n * @since 4.0.0\n */\n public get duration() { return this._motion.duration; }\n public set duration(val: number) { this._motion.duration = val; }\n /**\n * Easing function of the animation\n * @ko 애니메이션의 easing function\n * @since 4.0.0\n */\n public get easing() { return this._motion.easing; }\n public set easing(val: (x: number) => number) { this._motion.easing = val; }\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param camera - Camera to animate {@ko 애니메이션을 적용할 카메라}\n * @param from - Start pose {@ko 애니메이션이 시작 시점의 카메라의 회전 및 줌}\n * @param to - End pose {@ko 애니메이션이 끝났을 때 카메라의 회전 및 줌}\n * @param options - Options {@ko 옵션들}\n * @param options.duration - Animation duration {@ko 애니메이션 재생 시간}\n * @param options.easing - Animation easing function {@ko 애니메이션 easing function}\n */\n public constructor(camera: Camera, from: CameraPose, to: CameraPose, {\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING\n } = {}) {\n this._camera = camera;\n this._motion = new Motion({ duration, easing, range: { min: 0, max: 1 } });\n this._from = from;\n this._to = to;\n this._finishPromise = new Promise(resolve => {\n this._finish = resolve as () => void;\n });\n\n // Enable motion\n this._motion.setNewEndByDelta(1);\n }\n\n /**\n * Return a promise that resolved on animation end.\n * @ko 애니메이션 재생이 끝났을 때 resolve되는 Promise를 반환합니다.\n * @since 4.0.0\n */\n public getFinishPromise() {\n return this._finishPromise;\n }\n\n /**\n * Update animation by given deltaTime.\n * @ko 주어진 시간만큼 애니메이션을 업데이트합니다.\n * @param deltaTime Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n */\n public update(deltaTime: number): void {\n const camera = this._camera;\n const from = this._from;\n const to = this._to;\n const motion = this._motion;\n motion.update(deltaTime);\n\n // Progress that easing is applied\n const progress = motion.val;\n const rotation = quat.create();\n const zoom = lerp(from.zoom, to.zoom, progress);\n\n quat.slerp(rotation, from.rotation, to.rotation, progress);\n camera.rotate(rotation, zoom);\n\n if (progress >= 1) {\n this._finish();\n }\n }\n}\n\nexport default CameraAnimation;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { mat4, quat, vec3 } from \"gl-matrix\";\nimport CameraAnimation from \"./CameraAnimation\";\nimport {\n CAMERA_EVENTS,\n DEG_TO_RAD,\n INFINITE_RANGE,\n DEFAULT_PITCH_RANGE,\n RAD_TO_DEG,\n DEFAULT_ZOOM_RANGE,\n DEFAULT_EASING,\n EPSILON\n} from \"../const/internal\";\nimport {\n circulate,\n clamp,\n eulerToQuat,\n quatToEuler,\n toVerticalFov\n} from \"../utils\";\nimport { Range } from \"../type/utils\";\n\n/**\n * Events that {@link Camera} can trigger\n * @ko {@link Camera}가 트리거할 수 있는 이벤트들\n * @since 4.0.0\n */\nexport interface CameraEvents {\n /**\n * An event that fires when camera's animation stops\n * @ko 카메라 애니메이션이 멈췄을 때 트리거되는 이벤트\n * @eventName animationEnd\n * @eventOf Camera\n * @version 4.0.0\n */\n [CAMERA_EVENTS.ANIMATION_END]: {\n animation: CameraAnimation\n };\n}\n\n/**\n * Options for {@link Camera}\n * @ko {@link Camera}용 옵션들\n * @since 4.0.0\n */\nexport interface CameraOptions {\n /**\n * @copy View360#initialYaw\n */\n initialYaw: number;\n /**\n * @copy View360#initialPitch\n */\n initialPitch: number;\n /**\n * @copy View360#initialZoom\n */\n initialZoom: number;\n /**\n * @copy View360#yawRange\n */\n yawRange: Range | null;\n /**\n * @copy View360#pitchRange\n */\n pitchRange: Range | null;\n /**\n * @copy View360#zoomRange\n */\n zoomRange: Range | null;\n /**\n * @copy View360#fov\n */\n fov: number;\n}\n\n/**\n * Camera for View360\n * @ko View360용 카메라 구현체\n * @version 4.0.0\n */\nclass Camera extends Component {\n /**\n * Current yaw(y-axis rotation) value\n * @ko 현재 yaw(y축 회전) 값\n * @since 4.0.0\n */\n public yaw: number;\n /**\n * Current pitch(x-axis rotation) value\n * @ko 현재 pitch(x축 회전) 값\n * @since 4.0.0\n */\n public pitch: number;\n /**\n * Current zoom value\n * @ko 현재 줌 값\n * @since 4.0.0\n */\n public zoom: number;\n\n /**\n * @copy View360#initialYaw\n */\n public initialYaw: number;\n /**\n * @copy View360#initialPitch\n */\n public initialPitch: number;\n /**\n * @copy View360#initialPitch\n */\n public initialZoom: number;\n /**\n * @hidden\n * TODO: Please add comment for this when `rollOffset` is added\n */\n public rollOffset: number;\n\n /**\n * Current camera quaternion\n * @ko 현재 회전을 나타내는 quaternion 값\n * @since 4.0.0\n * @internal\n */\n public quaternion: quat;\n /**\n * Current camera position\n * @ko 현재 카메라 위치 좌표\n * @since 4.0.0\n * @internal\n */\n public position: vec3;\n /**\n * Active camera animation, `null` if there isn't.\n * @ko 현재 활성화된 카메라 애니메이션, 없을 경우 `null`값을 가집니다.\n * @since 4.0.0\n */\n public animation: CameraAnimation | null;\n /**\n * Camera's view matrix\n * @ko 카메라의 뷰 변환 행렬\n * @internal\n * @since 4.0.0\n */\n public viewMatrix: mat4;\n /**\n * Camera's projection matrix\n * @ko 카메라의 프로젝션 변환 행렬\n * @internal\n * @since 4.0.0\n */\n public projectionMatrix: mat4;\n\n /**\n * Camera's horizontal FOV(Field of View) value\n * @ko 카메라의 수평 FOV(Field of View) 값\n * @internal\n * @since 4.0.0\n */\n public fov: number;\n\n private _initialYawRange: Range | null;\n private _initialPitchRange: Range | null;\n private _initialZoomRange: Range | null;\n\n private _yawRange: Range | null;\n private _pitchRange: Range | null;\n private _zoomRange: Range | null;\n\n private _up: vec3;\n private _aspect: number;\n private _changed: boolean;\n private _maxRenderHeight: number;\n\n /**\n * Camera's width / height ratio\n * @ko 카메라의 가로 / 세로 비율\n * @readonly\n */\n public get aspect() { return this._aspect; }\n /**\n * Whether the camera's rotation changed from the last frame.\n * @ko 마지막 프레임 이후로 카메라의 회전값이 변경되었는지 나타내는 플래그.\n * @readonly\n */\n public get changed() { return this._changed; }\n /**\n * @copy View360#yawRange\n */\n public get yawRange() { return this._initialYawRange; }\n public set yawRange(val: Range | null) {\n this._initialYawRange = val;\n }\n /**\n * @copy View360#pitchRange\n */\n public get pitchRange() { return this._initialPitchRange; }\n public set pitchRange(val: Range | null) {\n this._initialPitchRange = val;\n }\n /**\n * @copy View360#zoomRange\n */\n public get zoomRange() { return this._initialZoomRange; }\n public set zoomRange(val: Range | null) {\n this._initialZoomRange = val;\n }\n\n /**\n * Create new instance of Camera\n * @param options - Camera options {@ko 카메라 옵션들}\n */\n public constructor({\n initialYaw,\n initialPitch,\n initialZoom,\n yawRange,\n pitchRange,\n zoomRange,\n fov\n }: CameraOptions) {\n super();\n\n this.yaw = initialYaw;\n this.pitch = initialPitch;\n this.zoom = initialZoom;\n this.rollOffset = 0;\n\n this.initialYaw = initialYaw;\n this.initialPitch = initialPitch;\n this.initialZoom = initialZoom;\n\n this.position = vec3.create();\n this.animation = null;\n\n this._up = vec3.fromValues(0, 1, 0);\n this._aspect = 1;\n\n this._initialYawRange = yawRange;\n this._initialPitchRange = pitchRange;\n this._initialZoomRange = zoomRange;\n\n this._yawRange = yawRange;\n this._pitchRange = pitchRange;\n this._zoomRange = zoomRange;\n\n this.quaternion = quat.create();\n this._updateQuaternion();\n\n this.viewMatrix = mat4.create();\n this.projectionMatrix = mat4.create();\n this.fov = fov;\n\n this._maxRenderHeight = -1;\n }\n\n /**\n * Destroy instance and detach all event listeners\n * @ko 인스턴스를 삭제하고 모든 이벤트 리스너를 삭제합니다.\n * @since 4.0.0\n */\n public destroy() {\n this.off();\n }\n\n /**\n * Refresh internal size value.\n * @ko 내부 크기값을 갱신합니다.\n * @param width - New width {@ko 변경된 너비값}\n * @param height - New height {@ko 변경된 높이값}\n * @since 4.0.0\n */\n public resize(width: number, height: number) {\n const prevAspect = this._aspect;\n\n this._aspect = width / height;\n\n if (this._aspect !== prevAspect) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation with euler values.\n * @ko 카메라 회전을 오일러 각 방향으로 변경합니다.\n * @param rotation - Rotation values {@ko 회전 값}\n * @param rotation.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값}\n * @param rotation.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값}\n * @param rotation.zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @since 4.0.0\n */\n public lookAt({\n yaw = this.yaw,\n pitch = this.pitch,\n zoom = this.zoom\n }: Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n }>) {\n const prevQuaternion = quat.clone(this.quaternion);\n const prevZoom = this.zoom;\n\n this.yaw = circulate(yaw, 0, 360);\n this.pitch = clamp(pitch, -90, 90);\n this.zoom = zoom;\n\n this._updateQuaternion();\n\n const zoomDiff = Math.abs(zoom - prevZoom);\n\n if (\n !quat.equals(this.quaternion, prevQuaternion)\n || zoomDiff >= EPSILON * 10 // ignore small changes\n ) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation with quaternion.\n * @ko 카메라 회전을 Quaternion을 이용해서 변경합니다.\n * @param rotation - Quaternion to apply {@ko 적용할 Quaternion}\n * @param zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @since 4.0.0\n */\n public rotate(rotation: quat, zoom: number = this.zoom) {\n const normalized = quat.normalize(quat.create(), rotation);\n const isSameRotation = quat.equals(this.quaternion, normalized);\n quat.copy(this.quaternion, normalized);\n\n const prevZoom = this.zoom;\n const { yaw, pitch } = quatToEuler(normalized);\n\n this.yaw = yaw;\n this.pitch = pitch;\n this.zoom = zoom;\n\n const zoomDiff = Math.abs(zoom - prevZoom);\n\n if (!isSameRotation || zoomDiff >= EPSILON * 10) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation to given euler values by the given duration.\n * @ko 카메라를 주어진 방향으로 주어진 시간동안 서서히 이동시킵니다.\n * @param options - Animation parameters {@ko 애니메이션 패러미터}\n * @param options.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값}\n * @param options.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값}\n * @param options.zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @param options.duration - Duration of the animation {@ko 애니메이션 시간}\n * @param options.easing - Easing function for the animation {@ko 애니메이션에 적용할 easing function}\n */\n public async animateTo({\n yaw = this.yaw,\n pitch = this.pitch,\n zoom = this.zoom,\n duration = 0,\n easing = DEFAULT_EASING\n }: Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n duration: number;\n easing: (x: number) => number;\n }> = {}): Promise {\n if (\n this.yaw === yaw\n && this.pitch === pitch\n && this.zoom === zoom\n ) return;\n\n const from = {\n rotation: quat.clone(this.quaternion),\n zoom: this.zoom\n };\n const to = {\n rotation: eulerToQuat(quat.create(), yaw, pitch, this.rollOffset),\n zoom\n };\n\n const animation = new CameraAnimation(this, from, to, {\n duration,\n easing\n });\n const finishPromise = animation.getFinishPromise();\n\n this.animation = animation;\n finishPromise.then(() => {\n this.animation = null;\n this.trigger(CAMERA_EVENTS.ANIMATION_END, { animation });\n });\n\n return finishPromise;\n }\n\n /**\n * @hidden\n */\n public restrictYawRange(min: number, max: number) {\n this._yawRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictPitchRange(min: number, max: number) {\n this._pitchRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictZoomRange(min: number, max: number) {\n this._zoomRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictRenderHeight(height: number) {\n this._maxRenderHeight = height;\n }\n\n /**\n * @hidden\n */\n public resetRange() {\n this._yawRange = this._initialYawRange;\n this._pitchRange = this._initialPitchRange;\n this._zoomRange = this._initialZoomRange;\n this._maxRenderHeight = -1;\n }\n\n /**\n * Get actual yaw range by the given zoom value.\n * @ko 주어진 zoom 값에 대한 실제 yaw 범위값을 반환합니다.\n * @since 4.0.0\n */\n public getYawRange(zoom: number) {\n const yawLimit = this._yawRange;\n const maxRenderHeight = this._maxRenderHeight;\n if (!yawLimit) return INFINITE_RANGE;\n\n const halfHFov = this.getHorizontalFov(zoom) * 0.5;\n let minYaw = yawLimit.min;\n let maxYaw = yawLimit.max;\n\n if (maxRenderHeight > 0) {\n const halfVFovRad = toVerticalFov(halfHFov * DEG_TO_RAD, this._aspect);\n const h = maxRenderHeight * 0.5;\n const t = Math.tan(halfVFovRad);\n const d = Math.sqrt((1 + h * h) / (1 + t * t));\n const theta = Math.atan(Math.tan(halfHFov * DEG_TO_RAD) * d) * RAD_TO_DEG;\n\n minYaw = yawLimit.min + theta;\n maxYaw = yawLimit.max - theta;\n }\n\n if (minYaw > maxYaw) {\n minYaw = 0;\n maxYaw = 0;\n }\n\n return {\n min: minYaw,\n max: maxYaw\n };\n }\n\n /**\n * Get actual pitch range by the given zoom value.\n * @ko 주어진 zoom 값에 대한 실제 pitch 범위값을 반환합니다.\n * @since 4.0.0\n */\n public getPitchRange(zoom: number) {\n const pitchLimit = this._pitchRange;\n const maxRenderHeight = this._maxRenderHeight;\n\n if (!pitchLimit) return DEFAULT_PITCH_RANGE;\n\n let minPitch = pitchLimit.min;\n let maxPitch = pitchLimit.max;\n\n if (maxRenderHeight > 0) {\n const halfVFov = this.getVerticalFov(zoom) * 0.5;\n\n minPitch = pitchLimit.min + halfVFov;\n maxPitch = pitchLimit.max - halfVFov;\n }\n\n if (minPitch > maxPitch) {\n minPitch = 0;\n maxPitch = 0;\n }\n\n return {\n min: Math.max(minPitch, -90),\n max: Math.min(maxPitch, 90)\n };\n }\n\n /**\n * Get actual zoom range in fov degrees.\n * @ko 실제 줌 범위를 fov각의 범위로 반환합니다.\n * @since 4.0.0\n */\n public getZoomRange() {\n const limit = this._zoomRange ?? DEFAULT_ZOOM_RANGE;\n\n // max (zoom in) -> minimum fov\n const minFov = this.getHorizontalFov(limit.max);\n const maxFov = this.getHorizontalFov(limit.min);\n const currentFov = this.getHorizontalFov(this.zoom);\n\n return {\n min: Math.max(minFov, 1),\n max: Math.min(maxFov, 180),\n current: currentFov\n };\n }\n\n /**\n * Return horizontal fov value when the given zoom is applied. (in degrees, °)\n * @ko 주어진 zoom 값이 적용되었을 때의 수평 fov값을 반환합니다. (도 단위, °)\n * @returns Zoomed horizontal FOV {@ko 줌이 적용된 수평 fov값}\n * @since 4.0.0\n */\n public getHorizontalFov(zoom = this.zoom) {\n return this._getZoomedHorizontalFov(zoom) * RAD_TO_DEG;\n }\n\n /**\n * Return vertical fov value when the given zoom is applied. (in degrees, °)\n * @ko 주어진 zoom 값이 적용되었을 때의 수직 fov값을 반환합니다. (도 단위, °)\n * @returns Zoomed vertical FOV {@ko 줌이 적용된 수직 fov값}\n * @since 4.0.0\n */\n public getVerticalFov(zoom = this.zoom) {\n const aspect = this._aspect;\n const hFov = this._getZoomedHorizontalFov(zoom); // In radians\n const vFov = toVerticalFov(hFov, aspect);\n\n return vFov * RAD_TO_DEG;\n }\n\n /**\n * Calculate zoom value for the given fov.\n * @ko 주어진 fov값을 zoom값으로 변환합니다.\n * @param fov horizontal fov (in degrees, °) {@ko 수평 fov 값 (도 단위, °)}\n * @since 4.0.0\n */\n public fovToZoom(fov: number) {\n const baseFov = this.fov;\n const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5);\n const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5);\n\n return renderingWidth / zoomedWidth;\n }\n\n /**\n * Update inner matrixes.\n * @ko 내부 행렬들을 업데이트합니다.\n * @internal\n * @since 4.0.0\n */\n public updateMatrix() {\n const up = this._up;\n const aspect = this._aspect;\n const viewMatrix = this.viewMatrix;\n const projMatrix = this.projectionMatrix;\n const position = this.position;\n const rotation = this.quaternion;\n\n const upDir = vec3.create();\n const viewDir = vec3.fromValues(0, 0, -1);\n vec3.transformQuat(viewDir, viewDir, rotation);\n vec3.transformQuat(upDir, up, rotation);\n\n const hFov = this._getZoomedHorizontalFov(); // In radians\n const vFov = toVerticalFov(hFov, aspect);\n\n mat4.lookAt(viewMatrix, position, viewDir, upDir);\n mat4.perspective(projMatrix, vFov, aspect, 0.1, 100);\n\n this._changed = true;\n }\n\n /**\n * @hidden\n */\n public onFrameRender() {\n this._changed = false;\n }\n\n private _updateQuaternion() {\n eulerToQuat(this.quaternion, this.yaw, this.pitch, this.rollOffset);\n }\n\n /**\n * @param zoom Current zoom value\n * @returns horizontal fov including zoom, in radian\n */\n private _getZoomedHorizontalFov(zoom = this.zoom) {\n return 2 * Math.atan(Math.tan(DEG_TO_RAD * this.fov * 0.5) / zoom);\n }\n}\n\nexport default Camera;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass MouseInput extends Component> {\n private _el: HTMLElement | null;\n private _prevPos: [number, number];\n\n public constructor() {\n super();\n\n this._el = null;\n this._prevPos = [0, 0];\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onMouseDown);\n\n this._el = element;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onMouseDown);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this._el = null;\n }\n\n private _onMouseDown = (evt: MouseEvent) => {\n const el = this._el;\n if (!el || evt.button !== BROWSER.MOUSE_BUTTON.LEFT) return;\n\n evt.preventDefault();\n\n if (el.focus) {\n el.focus();\n } else {\n window.focus();\n }\n\n this._prevPos[0] = evt.clientX;\n this._prevPos[1] = evt.clientY;\n\n window.addEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.addEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: false\n });\n }\n\n private _onMouseMove = (evt: MouseEvent) => {\n evt.preventDefault();\n\n const x = evt.clientX;\n const y = evt.clientY;\n const prevPos = this._prevPos;\n const deltaX = x - prevPos[0];\n const deltaY = y - prevPos[1];\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta: {\n x: deltaX,\n y: deltaY\n },\n isTouch: false,\n isKeyboard: false\n });\n\n prevPos[0] = x;\n prevPos[1] = y;\n }\n\n private _onMouseUp = () => {\n this._prevPos[0] = 0;\n this._prevPos[1] = 0;\n\n window.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: false,\n scrolling: false\n });\n }\n}\n\nexport default MouseInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\nimport { isFullscreen } from \"../../utils\";\n\nclass TouchInput extends Component> {\n private _el: HTMLElement | null;\n private _prevPos: [number, number];\n private _isFirstTouch: boolean;\n private _scrolling: boolean;\n private _scrollable: boolean;\n\n public get scrollable() { return this._scrollable; }\n public set scrollable(val: boolean) { this._scrollable = val; }\n\n public constructor() {\n super();\n\n this._el = null;\n this._prevPos = [0, 0];\n this._isFirstTouch = false;\n this._scrolling = false;\n this._scrollable = false;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.TOUCH_START, this._onTouchStart, { passive: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, { passive: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = element;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.TOUCH_START, this._onTouchStart);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = null;\n }\n\n private _onTouchStart = (evt: TouchEvent) => {\n if (evt.touches.length > 1 || this._scrolling) return;\n\n const touch = evt.touches[0];\n\n this._isFirstTouch = true;\n this._prevPos[0] = touch.clientX;\n this._prevPos[1] = touch.clientY;\n\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: true,\n isKeyboard: false\n });\n };\n\n private _onTouchMove = (evt: TouchEvent) => {\n // Only the one finger motion should be considered\n if (evt.touches.length > 1 || this._scrolling) return;\n\n const touch = evt.touches[0];\n const scrollable = this._scrollable;\n const prevPos = this._prevPos;\n\n const x = touch.clientX;\n const y = touch.clientY;\n const deltaX = x - prevPos[0];\n const deltaY = y - prevPos[1];\n\n if (this._isFirstTouch) {\n if (scrollable && !isFullscreen()) {\n if (Math.abs(deltaY) > Math.abs(deltaX)) {\n // Assume Scrolling\n this._scrolling = true;\n return;\n }\n }\n\n this._isFirstTouch = false;\n }\n\n if (evt.cancelable !== false) {\n evt.preventDefault();\n }\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta: {\n x: deltaX,\n y: deltaY\n },\n isTouch: true,\n isKeyboard: false\n });\n\n prevPos[0] = x;\n prevPos[1] = y;\n };\n\n private _onTouchEnd = (evt: TouchEvent) => {\n if (evt.touches.length !== 0) return;\n\n const touch = evt.touches[0];\n const prevPos = this._prevPos;\n\n if (touch) {\n prevPos[0] = touch.clientX;\n prevPos[1] = touch.clientY;\n } else {\n prevPos[0] = 0;\n prevPos[1] = 0;\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: true,\n isKeyboard: false,\n scrolling: this._scrolling\n });\n }\n\n if (evt.cancelable !== false) {\n evt.preventDefault();\n }\n\n this._scrolling = false;\n };\n}\n\nexport default TouchInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass KeyboardInput extends Component> {\n private _el: HTMLElement | null;\n private _pressed: {\n LEFT: boolean;\n UP: boolean;\n RIGHT: boolean;\n DOWN: boolean;\n };\n\n public get active() {\n const pressed = this._pressed;\n return pressed.LEFT || pressed.UP || pressed.RIGHT || pressed.DOWN;\n }\n\n public constructor() {\n super();\n\n this._el = null;\n this._clearPressedKeys();\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown);\n element.addEventListener(BROWSER.EVENTS.KEY_UP, this._onKeyUp);\n\n this._el = element;\n this._clearPressedKeys();\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown);\n element.removeEventListener(BROWSER.EVENTS.KEY_UP, this._onKeyUp);\n\n this._el = null;\n this._clearPressedKeys();\n }\n\n public update() {\n const delta = this._getDeltaByPressedKeys();\n\n if (delta.x !== 0 || delta.y !== 0) {\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: false,\n isKeyboard: true\n });\n }\n }\n\n private _clearPressedKeys() {\n this._pressed = BROWSER.KEY_DIRECTION.reduce((obj, keyName) => {\n return {\n ...obj,\n [keyName]: false\n };\n }, {} as KeyboardInput[\"_pressed\"]);\n }\n\n private _updateKeyPress(event: KeyboardEvent, isEnable: boolean): void {\n const pressed = this._pressed;\n const keyToUpdate = event.keyCode != null\n ? BROWSER.DIRECTION_KEY_CODE[event.keyCode]\n : BROWSER.DIRECTION_KEY_NAME[event.key];\n\n if (!keyToUpdate) return;\n\n pressed[keyToUpdate] = isEnable;\n }\n\n private _getPressedKeyCount() {\n return BROWSER.KEY_DIRECTION.filter(key => this._pressed[key]).length;\n }\n\n private _getDeltaByPressedKeys() {\n const pressed = this._pressed;\n let x = 0;\n let y = 0;\n\n if (pressed.LEFT) {\n x += 1;\n }\n\n if (pressed.RIGHT) {\n x -= 1;\n }\n\n if (pressed.UP) {\n y += 1;\n }\n\n if (pressed.DOWN) {\n y -= 1;\n }\n\n return {\n x, y\n };\n }\n\n private _onKeyDown = (evt: KeyboardEvent) => {\n // Ignore all other keypress except main arrow keys\n if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return;\n\n this._updateKeyPress(evt, true);\n\n const pressedCount = this._getPressedKeyCount();\n if (pressedCount <= 0) return;\n\n evt.preventDefault();\n if (pressedCount === 1 && !evt.repeat) {\n // On first keydown\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: true\n });\n }\n };\n\n private _onKeyUp = (evt: KeyboardEvent) => {\n // Ignore all other keypress except main arrow keys\n if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return;\n\n this._updateKeyPress(evt, false);\n\n const pressedCount = this._getPressedKeyCount();\n if (pressedCount > 0) return;\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: true,\n scrolling: false\n });\n };\n}\n\nexport default KeyboardInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport MouseInput from \"./input/MouseInput\";\nimport TouchInput from \"./input/TouchInput\";\nimport KeyboardInput from \"./input/KeyboardInput\";\nimport Camera from \"../core/Camera\";\nimport Motion from \"../core/Motion\";\nimport { CONTROL_EVENTS, INFINITE_RANGE, DEFAULT_PITCH_RANGE, DEFAULT_ANIMATION_DURATION, DEFAULT_EASING, DEG_TO_RAD, RAD_TO_DEG } from \"../const/internal\";\nimport { toVerticalFov } from \"../utils\";\nimport { ControlEvents, InputEvents } from \"../type/internal\";\n\n/**\n * Options for {@link RotateControl}\n * @ko {@link RotateControl}용 옵션들\n * @since 4.0.0\n */\nexport interface RotateControlOptions {\n /**\n * @copy RotateControl#pointerScale\n */\n pointerScale: [number, number];\n /**\n * @copy RotateControl#keyboardScale\n */\n keyboardScale: [number, number];\n /**\n * @copy RotateControl#duration\n */\n duration: number;\n /**\n * @copy RotateControl#easing\n */\n easing: (x: number) => number;\n /**\n * @copy RotateControl#disablePitch\n */\n disablePitch: boolean;\n /**\n * @copy RotateControl#disableYaw\n */\n disableYaw: boolean;\n /**\n * @copy RotateControl#disableKeyboard\n */\n disableKeyboard: boolean;\n}\n\ntype RotateDeltaType = { x: number; y: number; };\nexport type RotateControlEvents = ControlEvents;\n\n/**\n * Camera's rotation control\n * @ko 카메라의 회전을 담당하는 컨트롤\n * @since 4.0.0\n */\nclass RotateControl extends Component implements CameraControl {\n // Options\n private _pointerScale: RotateControlOptions[\"pointerScale\"];\n private _keyboardScale: RotateControlOptions[\"keyboardScale\"];\n private _duration: RotateControlOptions[\"duration\"];\n private _easing: RotateControlOptions[\"easing\"];\n private _disablePitch: RotateControlOptions[\"disablePitch\"];\n private _disableYaw: RotateControlOptions[\"disableYaw\"];\n private _disableKeyboard: RotateControlOptions[\"disableKeyboard\"];\n\n // Internal values\n private _controlEl: HTMLElement;\n private _enableBlocked: boolean;\n private _mouseInput: MouseInput;\n private _touchInput: TouchInput;\n private _keyboardInput: KeyboardInput;\n private _xMotion: Motion;\n private _yMotion: Motion;\n private _screenScale: [number, number];\n private _zoomScale: number;\n private _enabled: boolean;\n private _changedWhileDragging: boolean;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() {\n return this._keyboardInput.active\n || this._xMotion.activated\n || this._yMotion.activated;\n }\n /**\n * Current yaw value\n * @ko 현재 yaw 값\n * @readonly\n * @since 4.0.0\n */\n public get yaw() { return this._xMotion; }\n /**\n * Current pitch value\n * @ko 현재 pitch 값\n * @readonly\n * @since 4.0.0\n */\n public get pitch() { return this._yMotion; }\n /**\n * @copy View360#scrollable\n */\n public get scrollable() { return this._touchInput.scrollable; }\n public set scrollable(val: boolean) {\n this._touchInput.scrollable = val;\n }\n\n /**\n * Scale factor for mouse/touch rotation\n * @ko 마우스/터치를 통한 회전 배율\n * @default [1, 1]\n * @since 4.0.0\n */\n public get pointerScale() { return this._pointerScale; }\n public set pointerScale(val: RotateControlOptions[\"pointerScale\"]) {\n this._pointerScale = val;\n }\n\n /**\n * Scale factor for keyboard rotation\n * @ko 키보드를 통한 회전 배율\n * @default [1, 1]\n * @since 4.0.0\n */\n public get keyboardScale() { return this._keyboardScale; }\n public set keyboardScale(val: RotateControlOptions[\"keyboardScale\"]) {\n this._keyboardScale = val;\n }\n\n /**\n * Duration of the input animation (ms)\n * @ko 회전 애니메이션의 시간 (ms)\n * @default 300\n */\n public get duration() { return this._duration; }\n public set duration(val: RotateControlOptions[\"duration\"]) {\n this._duration = val;\n this._xMotion.duration = val;\n this._yMotion.duration = val;\n }\n\n /**\n * Easing function of the animation\n * @ko 회전 애니메이션에 적용할 easing 함수\n * @default EASING.EASE_OUT_CUBIC\n * @see EASING\n */\n public get easing() { return this._easing; }\n public set easing(val: RotateControlOptions[\"easing\"]) {\n this._easing = val;\n this._xMotion.easing = val;\n this._yMotion.easing = val;\n }\n\n /**\n * Disable X-axis(pitch) rotation.\n * @ko x축 회전(pitch)을 비활성화합니다.\n * @default false\n */\n public get disablePitch() { return this._disablePitch; }\n public set disablePitch(val: RotateControlOptions[\"disablePitch\"]) { this._disablePitch = val; }\n\n /**\n * Disable Y-axis(yaw) rotation.\n * @ko y축 회전(yaw)을 비활성화합니다.\n * @default false\n */\n public get disableYaw() { return this._disableYaw; }\n public set disableYaw(val: RotateControlOptions[\"disableYaw\"]) { this._disableYaw = val; }\n\n /**\n * Disable rotation by keyboard.\n * @ko 키보드를 이용한 회전을 비활성화합니다.\n * @default false\n */\n public get disableKeyboard() { return this._disableKeyboard; }\n public set disableKeyboard(val: RotateControlOptions[\"disableKeyboard\"]) { this._disableKeyboard = val; }\n\n /**\n * Create new RotateControl instance\n * @ko RotateControl의 인스턴스를 생성합니다.\n * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트}\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(controlEl: HTMLElement, enableBlocked: boolean, {\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING,\n pointerScale = [1, 1],\n keyboardScale = [1, 1],\n disablePitch = false,\n disableYaw = false,\n disableKeyboard = false\n }: Partial = {}) {\n super();\n\n this._controlEl = controlEl;\n this._pointerScale = pointerScale;\n this._keyboardScale = keyboardScale;\n this._duration = duration;\n this._easing = easing;\n this._disablePitch = disablePitch;\n this._disableYaw = disableYaw;\n this._disableKeyboard = disableKeyboard;\n\n this._enableBlocked = enableBlocked;\n this._mouseInput = new MouseInput();\n this._touchInput = new TouchInput();\n this._keyboardInput = new KeyboardInput();\n this._xMotion = new Motion({ duration, range: INFINITE_RANGE, easing });\n this._yMotion = new Motion({ duration, range: DEFAULT_PITCH_RANGE, easing });\n this._screenScale = [1, 1];\n this._zoomScale = 1;\n this._enabled = false;\n this._changedWhileDragging = false;\n this._bindInputs();\n }\n\n public destroy(): void {\n this.disable();\n this._mouseInput.off();\n this._touchInput.off();\n this._keyboardInput.off();\n this.off();\n this._changedWhileDragging = false;\n }\n\n /**\n * @hidden\n */\n public update(delta: number): void {\n if (!this._enabled) return;\n\n const xMotion = this._xMotion;\n const yMotion = this._yMotion;\n const keyboardInput = this._keyboardInput;\n\n if (!this._disableKeyboard) {\n keyboardInput.update();\n }\n\n if (!this._disablePitch) {\n yMotion.update(delta);\n }\n\n if (!this._disableYaw) {\n xMotion.update(delta);\n }\n }\n\n /**\n * @hidden\n */\n public updateRange(camera: Camera, zoom: number) {\n const yawRange = camera.getYawRange(zoom);\n const pitchRange = camera.getPitchRange(zoom);\n\n this._xMotion.setRange(yawRange.min, yawRange.max);\n this._yMotion.setRange(pitchRange.min, pitchRange.max);\n }\n\n /**\n * @hidden\n */\n public setZoomScale(val: number) {\n this._zoomScale = val;\n }\n\n /**\n * Resize control to match target size.\n * @ko 컨트롤의 내부 크기를 갱신합니다.\n * @param hfov - Camera horizontal fov in degrees {@ko 카메라의 수평방향 fov값 (도 단위)}\n * @param aspect - Camera aspect {@ko 카메라 가로/세로 비율}\n * @param width - New width {@ko 갱신된 너비}\n * @param height - New height {@ko 갱신된 높이}\n */\n public resize(hfov: number, aspect: number, width: number, height: number) {\n const vfov = toVerticalFov(hfov * DEG_TO_RAD, aspect) * RAD_TO_DEG;\n\n this._screenScale[0] = hfov / width;\n this._screenScale[1] = vfov / height;\n }\n\n public enable(): void {\n if (this._enabled) return;\n\n const element = this._controlEl;\n\n this._mouseInput.enable(element);\n this._touchInput.enable(element);\n this._keyboardInput.enable(element);\n\n this._enabled = true;\n this._enableBlocked = false;\n\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: true });\n }\n\n public disable(): void {\n if (!this._enabled) return;\n\n this._mouseInput.disable();\n this._touchInput.disable();\n this._keyboardInput.disable();\n\n this._enabled = false;\n\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: true });\n }\n\n public sync(camera: Camera): void {\n this.updateRange(camera, camera.zoom);\n\n this._xMotion.reset(camera.yaw);\n this._yMotion.reset(camera.pitch);\n }\n\n private _bindInputs() {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n const keyboardInput = this._keyboardInput;\n\n mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n touchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n touchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n keyboardInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n keyboardInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n keyboardInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n }\n\n private _onInputStart = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n this._changedWhileDragging = false;\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n ...evt,\n inputType: \"rotate\"\n });\n };\n\n private _onChange = (evt: InputEvents[typeof CONTROL_EVENTS.CHANGE]) => {\n const delta = evt.delta;\n const invZoomScale = 1 / this._zoomScale; // Reduce speed on zoom\n const screenScale = this._screenScale;\n const keyboardScale = this._keyboardScale;\n const pointerScale = this._pointerScale;\n\n let scale: [number, number];\n\n if (evt.isKeyboard) {\n scale = [\n keyboardScale[0] * invZoomScale,\n keyboardScale[1] * invZoomScale\n ];\n } else {\n scale = [\n pointerScale[0] * screenScale[0] * invZoomScale,\n pointerScale[1] * screenScale[1] * invZoomScale\n ];\n }\n\n const scaledX = delta.x * scale[0];\n const scaledY = delta.y * scale[1];\n\n this._xMotion.setNewEndByDelta(scaledX);\n this._yMotion.setNewEndByDelta(scaledY);\n\n this._changedWhileDragging = true;\n }\n\n private _onInputEnd = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n ...evt,\n inputType: \"rotate\"\n });\n\n if (!this._changedWhileDragging && !evt.isKeyboard && !evt.scrolling) {\n this.trigger(CONTROL_EVENTS.STATIC_CLICK, {\n isTouch: evt.isTouch\n });\n }\n\n this._changedWhileDragging = false;\n };\n}\n\nexport default RotateControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS, DEFAULT_ANIMATION_DURATION } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass WheelInput extends Component> {\n private _el: HTMLElement | null;\n private _scrollable: boolean;\n private _baseScale: number;\n private _inputTimer: number;\n\n public get scrollable() { return this._scrollable; }\n public set scrollable(val: boolean) { this._scrollable = val; }\n\n public constructor() {\n super();\n\n this._el = null;\n this._baseScale = 0.04;\n this._scrollable = false;\n this._inputTimer = -1;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.WHEEL, this._onWheel, { passive: false, capture: false });\n\n this._el = element;\n this._clearTimer();\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.WHEEL, this._onWheel, false);\n\n this._el = null;\n this._clearTimer();\n }\n\n private _onWheel = (evt: WheelEvent) => {\n const scrollable = this._scrollable;\n\n if (evt.deltaY === 0 || scrollable) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n\n if (this._inputTimer < 0) {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: false\n });\n } else {\n this._clearTimer();\n }\n\n const delta = this._baseScale * evt.deltaY;\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: false,\n isKeyboard: false\n });\n\n this._inputTimer = window.setTimeout(() => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: false,\n scrolling: false\n });\n this._inputTimer = -1;\n }, DEFAULT_ANIMATION_DURATION);\n };\n\n private _clearTimer() {\n window.clearTimeout(this._inputTimer);\n this._inputTimer = -1;\n }\n}\n\nexport default WheelInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass PinchInput extends Component> {\n private _el: HTMLElement | null;\n private _baseScale: number;\n private _prevDistance: number;\n private _isFirstTouch: boolean;\n\n public constructor() {\n super();\n\n this._el = null;\n this._baseScale = -0.2;\n this._prevDistance = -1;\n this._isFirstTouch = true;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, { passive: false, capture: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = element;\n this._prevDistance = -1;\n this._isFirstTouch = true;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, false);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = null;\n }\n\n private _onTouchMove = (evt: TouchEvent) => {\n const touches = evt.touches;\n if (touches.length !== 2) return;\n\n if (!evt.cancelable) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n\n const prevDistance = this._prevDistance;\n\n const diff = [\n touches[0].pageX - touches[1].pageX,\n touches[0].pageY - touches[1].pageY\n ];\n\n const distance = Math.sqrt(diff[0] * diff[0] + diff[1] * diff[1]) * this._baseScale;\n const delta = this._isFirstTouch\n ? 0\n : distance - prevDistance;\n\n if (this._isFirstTouch) {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: true,\n isKeyboard: false\n });\n }\n\n this._prevDistance = distance;\n this._isFirstTouch = false;\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: true,\n isKeyboard: false\n });\n };\n\n private _onTouchEnd = (evt: TouchEvent) => {\n if (evt.touches.length !== 0) return;\n\n if (!this._isFirstTouch) {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: true,\n isKeyboard: false,\n scrolling: false\n });\n }\n\n this._prevDistance = -1;\n this._isFirstTouch = true;\n };\n}\n\nexport default PinchInput;\n","/*\n* Copyright (c) 2023-present NAVER Corp.\n* egjs projects are licensed under the MIT license\n*/\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport WheelInput from \"./input/WheelInput\";\nimport PinchInput from \"./input/PinchInput\";\nimport Camera from \"../core/Camera\";\nimport Motion from \"../core/Motion\";\nimport {\n CONTROL_EVENTS,\n DEFAULT_ANIMATION_DURATION,\n DEFAULT_EASING,\n INFINITE_RANGE\n} from \"../const/internal\";\nimport { ControlEvents, InputEvents } from \"../type/internal\";\n\n/**\n * Options for {@link ZoomControl}\n * @ko {@link ZoomControl}용 옵션들\n * @since 4.0.0\n */\nexport interface ZoomControlOptions {\n /**\n * @copy ZoomControl#scale\n */\n scale: number;\n /**\n * @copy ZoomControl#duration\n */\n duration: number;\n /**\n * @copy ZoomControl#easing\n */\n easing: (x: number) => number;\n}\n\ntype ZoomControlEvents = ControlEvents;\n\n/**\n * Camera's zoom control\n * @ko 카메라의 줌 값을 담당하는 컨트롤\n * @since 4.0.0\n */\nclass ZoomControl extends Component implements CameraControl {\n // Options\n private _scale: ZoomControlOptions[\"scale\"];\n\n // Internal values\n private _controlEl: HTMLElement;\n private _enableBlocked: boolean;\n private _wheelInput: WheelInput;\n private _pinchInput: PinchInput;\n private _motion: Motion;\n private _enabled: boolean;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() { return this._motion.activated; }\n /**\n * Current zoom value\n * @ko 현재 줌 값\n * @since 4.0.0\n * @readonly\n */\n public get zoom() { return this._motion.val; }\n /**\n * @copy View360#wheelScrollable\n */\n public get scrollable() { return this._wheelInput.scrollable; }\n public set scrollable(val: boolean) {\n this._wheelInput.scrollable = val;\n }\n /**\n * @hidden\n */\n public get range() { return this._motion.range; }\n\n /**\n * Scale factor of the zoom\n * @ko 입력에 의한 줌 배율\n * @default 1\n * @since 4.0.0\n */\n public get scale() { return this._scale; }\n public set scale(val: ZoomControlOptions[\"scale\"]) { this._scale = val; }\n\n /**\n * Duration of the input animation (ms)\n * @ko 회전 애니메이션의 시간 (ms)\n * @default 300\n * @since 4.0.0\n */\n public get duration() { return this._motion.duration; }\n\n /**\n * Easing function of the animation\n * @ko 회전 애니메이션에 적용할 easing 함수\n * @default EASING.EASE_OUT_CUBIC\n * @see EASING\n * @since 4.0.0\n */\n public get easing() { return this._motion.easing; }\n\n /**\n * Create new ZoomControl instance\n * @ko ZoomControl의 인스턴스를 생성합니다.\n * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트}\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(controlEl: HTMLElement, enableBlocked: boolean, {\n scale = 1,\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING\n }: Partial = {}) {\n super();\n\n this._scale = scale;\n\n this._controlEl = controlEl;\n this._enableBlocked = enableBlocked;\n this._wheelInput = new WheelInput();\n this._pinchInput = new PinchInput();\n this._motion = new Motion({\n duration,\n easing,\n range: INFINITE_RANGE\n });\n this._enabled = false;\n\n this._bindInputs();\n }\n\n public destroy(): void {\n this.disable();\n this._wheelInput.off();\n this._pinchInput.off();\n this.off();\n }\n\n /**\n * @hidden\n */\n public update(delta: number): void {\n if (!this._enabled) return;\n\n const motion = this._motion;\n motion.update(delta);\n }\n\n public enable(): void {\n if (this._enabled) return;\n\n const element = this._controlEl;\n this._wheelInput.enable(element);\n this._pinchInput.enable(element);\n\n this._enabled = true;\n this._enableBlocked = false;\n\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: false });\n }\n\n public disable(): void {\n if (!this._enabled) return;\n\n this._wheelInput.disable();\n this._pinchInput.disable();\n\n this._enabled = false;\n\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: false });\n }\n\n public sync(camera: Camera): void {\n const motion = this._motion;\n const range = camera.getZoomRange();\n\n motion.setRange(range.min, range.max);\n motion.reset(range.current);\n }\n\n private _bindInputs() {\n const wheelInput = this._wheelInput;\n const pinchInput = this._pinchInput;\n\n wheelInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n wheelInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n wheelInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n pinchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n pinchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n pinchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n }\n\n private _onInputStart = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n ...evt,\n inputType: \"zoom\"\n });\n };\n\n private _onChange = ({ delta }: InputEvents[typeof CONTROL_EVENTS.CHANGE]) => {\n const scale = this._scale;\n const scaledDelta = delta * scale;\n\n this._motion.setNewEndByDelta(scaledDelta);\n };\n\n private _onInputEnd = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n ...evt,\n inputType: \"zoom\"\n });\n };\n}\n\nexport default ZoomControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { quat, vec3 } from \"gl-matrix\";\nimport * as BROWSER from \"../../const/browser\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\nimport { quatToEuler } from \"../../utils\";\n\nexport const ROTATE_CONSTANT = {\n PITCH_DELTA: 1,\n YAW_DELTA_BY_ROLL: 2,\n YAW_DELTA_BY_YAW: 3\n} as const;\n\nROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = {\n targetAxis: [0, 1, 0],\n meshPoint: [0, 0, 1]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = {\n targetAxis: [0, 1, 0],\n meshPoint: [1, 0, 0]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = {\n targetAxis: [1, 0, 0],\n meshPoint: [0, 0, 1]\n};\n\nclass GyroInput extends Component> {\n public quaternion: quat;\n\n private _ignoreRoll: boolean;\n\n private _yawOrigin: number;\n private _yawOffset: number;\n private _orientation: {\n alpha: number;\n beta: number;\n gamma: number;\n }\n private _orientationUpdated: boolean;\n private _needsCalibrate: boolean;\n private _screenOrientation: number;\n private _enabled: boolean;\n\n public get enabled() { return this._enabled; }\n public get orientationUpdated() { return this._orientationUpdated; }\n public get ignoreRoll() { return this._ignoreRoll; }\n public set ignoreRoll(val: boolean) { this._ignoreRoll = val; }\n\n public constructor() {\n super();\n\n this.quaternion = quat.create();\n\n this._orientation = {\n alpha: 0,\n beta: 90,\n gamma: 0\n };\n this._yawOrigin = 0;\n this._yawOffset = 0;\n this._orientationUpdated = false;\n this._screenOrientation = 0;\n this._needsCalibrate = true;\n this._enabled = false;\n }\n\n public enable() {\n if (this._enabled) return;\n\n window.addEventListener(BROWSER.EVENTS.DEVICE_ORIENTATION, this._onDeviceOrientation);\n window.addEventListener(BROWSER.EVENTS.ORIENTATION_CHANGE, this._updateScreenOrientation);\n\n this._updateScreenOrientation();\n this._orientationUpdated = false;\n this._needsCalibrate = true;\n this._enabled = true;\n }\n\n public disable() {\n if (!this._enabled) return;\n\n window.removeEventListener(BROWSER.EVENTS.DEVICE_ORIENTATION, this._onDeviceOrientation);\n window.removeEventListener(BROWSER.EVENTS.ORIENTATION_CHANGE, this._updateScreenOrientation);\n\n this._enabled = false;\n }\n\n public update() {\n this._updateRotation();\n this._orientationUpdated = false;\n }\n\n public collectDelta() {\n if (!this._orientationUpdated) {\n return {\n pitch: 0,\n yaw: 0\n };\n }\n\n const prevRotation = quat.clone(this.quaternion);\n\n this._updateRotation();\n this._orientationUpdated = false;\n\n return this._toEulerDelta(prevRotation, this.quaternion);\n }\n\n public setInitialRotation(yaw: number) {\n this._yawOrigin = yaw;\n }\n\n private _onDeviceOrientation = (evt: DeviceOrientationEvent) => {\n const prevOrientation = this._orientation;\n const { alpha, beta, gamma } = evt;\n\n if (\n alpha == null\n || beta == null\n || gamma == null\n ) return;\n\n prevOrientation.alpha = alpha;\n prevOrientation.beta = beta;\n prevOrientation.gamma = gamma;\n\n this._orientationUpdated = true;\n\n if (this._needsCalibrate) {\n this._needsCalibrate = false;\n this._calibrateSensor();\n }\n };\n\n private _calibrateSensor() {\n const yawOrigin = this._yawOrigin;\n const rotation = this.quaternion;\n\n this._yawOffset = 0;\n this._updateRotation();\n\n const { yaw: sensorYaw } = quatToEuler(rotation);\n this._yawOffset = sensorYaw - yawOrigin;\n this._updateRotation();\n\n this._needsCalibrate = false;\n }\n\n private _updateRotation() {\n const rotation = this.quaternion;\n const { alpha, beta, gamma } = this._orientation;\n\n quat.identity(rotation);\n quat.rotateY(rotation, rotation, (alpha - this._yawOffset) * DEG_TO_RAD);\n quat.rotateX(rotation, rotation, beta * DEG_TO_RAD);\n quat.rotateZ(rotation, rotation, -gamma * DEG_TO_RAD);\n\n const screen = quat.create();\n const screenAngle = -this._screenOrientation * 0.5 * DEG_TO_RAD;\n const world = quat.fromValues(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5));\n\n quat.set(screen, 0, Math.sin(screenAngle), 0, Math.cos(screenAngle));\n quat.multiply(rotation, rotation, screen);\n quat.multiply(rotation, rotation, world);\n\n quat.normalize(rotation, rotation);\n }\n\n private _updateScreenOrientation = () => {\n if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) {\n this._screenOrientation = screen.orientation.angle;\n } else if (window.orientation !== undefined) {\n this._screenOrientation = window.orientation >= 0 ?\n window.orientation : 360 + window.orientation;\n } else {\n this._screenOrientation = 0;\n }\n }\n\n private _toEulerDelta(prevQuat: quat, currentQuat: quat) {\n return {\n yaw: this._getDeltaYaw(prevQuat, currentQuat),\n pitch: this._getDeltaPitch(prevQuat, currentQuat),\n };\n }\n\n private _getDeltaYaw(prvQ: quat, curQ: quat): number {\n const yawDeltaByYaw = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW);\n const yawDeltaByRoll = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL)\n * Math.sin(this._extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n }\n\n private _getDeltaPitch(prvQ: quat, curQ: quat): number {\n return this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n }\n\n private _getRotationDelta(prevQ: quat, curQ: quat, rotateKind: typeof ROTATE_CONSTANT[keyof typeof ROTATE_CONSTANT]) {\n const targetAxis = vec3.fromValues(\n ROTATE_CONSTANT[rotateKind].targetAxis[0],\n ROTATE_CONSTANT[rotateKind].targetAxis[1],\n ROTATE_CONSTANT[rotateKind].targetAxis[2]\n );\n const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint;\n\n const prevQuaternion = quat.clone(prevQ);\n const curQuaternion = quat.clone(curQ);\n\n quat.normalize(prevQuaternion, prevQuaternion);\n quat.normalize(curQuaternion, curQuaternion);\n\n let prevPoint = vec3.fromValues(0, 0, 1);\n let curPoint = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n vec3.transformQuat(targetAxis, targetAxis, curQuaternion);\n\n const rotateDistance = vec3.dot(targetAxis, vec3.cross(vec3.create(), prevPoint, curPoint));\n const rotateDirection = rotateDistance > 0 ? 1 : -1;\n\n // when counter clock wise, use vec3.fromValues(0,1,0)\n // when clock wise, use vec3.fromValues(0,-1,0)\n // const meshPoint1 = vec3.fromValues(0, 0, 0);\n const meshPoint2 = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n\n let meshPoint3;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n meshPoint3 = vec3.fromValues(0, rotateDirection, 0);\n } else {\n meshPoint3 = vec3.fromValues(rotateDirection, 0, 0);\n }\n\n vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion);\n vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion);\n\n const vecU = meshPoint2;\n const vecV = meshPoint3;\n const vecN = vec3.create();\n\n vec3.cross(vecN, vecU, vecV);\n vec3.normalize(vecN, vecN);\n\n const coefficientA = vecN[0];\n const coefficientB = vecN[1];\n const coefficientC = vecN[2];\n\n // a point on the plane\n curPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n\n // a point should project on the plane\n prevPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n\n // distance between prevPoint and the plane\n let distance = Math.abs(\n prevPoint[0] * coefficientA +\n prevPoint[1] * coefficientB +\n prevPoint[2] * coefficientC\n );\n\n const projectedPrevPoint = vec3.create();\n\n vec3.subtract(projectedPrevPoint, prevPoint, vec3.scale(vec3.create(), vecN, distance));\n\n let trigonometricRatio =\n (projectedPrevPoint[0] * curPoint[0] +\n projectedPrevPoint[1] * curPoint[1] +\n projectedPrevPoint[2] * curPoint[2]) /\n (vec3.length(projectedPrevPoint) * vec3.length(curPoint));\n\n // defensive block\n if (trigonometricRatio > 1) {\n trigonometricRatio = 1;\n }\n\n const theta = Math.acos(trigonometricRatio);\n\n const crossVec = vec3.cross(vec3.create(), curPoint, projectedPrevPoint);\n\n distance = coefficientA * crossVec[0]\n + coefficientB * crossVec[1]\n + coefficientC * crossVec[2];\n\n let thetaDirection: number;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n thetaDirection = distance > 0 ? 1 : -1;\n } else {\n thetaDirection = distance < 0 ? 1 : -1;\n }\n\n const deltaRadian = theta * thetaDirection * rotateDirection;\n\n return deltaRadian * RAD_TO_DEG;\n }\n\n private _extractPitchFromQuat(quaternion: quat) {\n const baseV = vec3.fromValues(0, 0, 1);\n vec3.transformQuat(baseV, baseV, quaternion);\n\n return -1 * Math.atan2(\n baseV[1],\n Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2)));\n }\n}\n\nexport default GyroInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport GyroInput from \"./input/GyroInput\";\nimport Motion from \"../core/Motion\";\nimport Camera from \"../core/Camera\";\nimport * as BROWSER from \"../const/browser\";\nimport { CONTROL_EVENTS } from \"../const/internal\";\nimport { ControlEvents } from \"../type/internal\";\nimport { sensorCanBeEnabledIOS } from \"../utils\";\n\n/**\n * Options for {@link GyroControl}\n * @ko {@link GyroControl}용 옵션들\n * @since 4.0.0\n */\nexport interface GyroControlOptions {\n /**\n * @copy GyroControl#ignoreRoll\n */\n ignoreRoll: boolean;\n}\n\nexport type GyroControlEvents = ControlEvents;\n\n/**\n * Camera's rotation control by gyroscope\n * @ko 자이로스코프를 이용한 회전 컨트롤\n * @since 4.0.0\n */\nclass GyroControl extends Component implements CameraControl {\n // Options\n private _ignoreRoll: GyroControlOptions[\"ignoreRoll\"];\n\n // Internal values\n private _enableBlocked: boolean;\n private _input: GyroInput;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._input.enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() {\n return this._input.enabled && this._input.orientationUpdated;\n }\n\n /**\n * When `true`, ignore gyroscope's roll(z-axis rotation) value.\n * :::caution\n * Setting `false` will ignore camera's range limit.\n * Options like {@link View360Options#yawRange}, {@link View360Options#pitchRange} are ignored, and {@link CylinderProjection} also can't force it's camera range limit.\n * :::\n * @ko `true`일 경우 자이로스코프 입력의 roll(z축 회전)값을 무시합니다.\n * :::caution\n * 이 값을 `false`로 설정할 경우 카메라 범위 제약을 무시합니다.\n * {@link View360Options#yawRange}, {@link View360Options#pitchRange}와 같은 값은 무시되며, {@link CylinderProjection} 사용시에도 범위를 벗어날 수 있습니다.\n * :::\n * @default true\n * @since 4.0.0\n */\n public get ignoreRoll() { return this._ignoreRoll; }\n public set ignoreRoll(val: GyroControlOptions[\"ignoreRoll\"]) { this._ignoreRoll = val; }\n\n /**\n * Return availability of the gyroscope.\n * :::caution\n * This will always return false until user permission under environments like iOS which requires user permission when using gyroscope.\n * :::\n * @ko 자이로스코프 사용 가능 여부를 반환합니다.\n * :::caution\n * iOS와 같이 GyroScope 사용시 사용자 Permission을 요구하는 환경에서는 사용자 Permission을 받기 전까지 항상 `false`입니다.\n * :::\n * @example\n * ```ts\n * const gyroAvailable = await GyroControl.isAvailable();\n * ```\n */\n public static async isAvailable(): Promise {\n if (!DeviceMotionEvent) {\n return false;\n }\n\n let onDeviceMotionChange: (evt: DeviceMotionEvent) => void;\n\n const listenDeviceMotion = () => new Promise(res => {\n onDeviceMotionChange = (evt: DeviceMotionEvent) => {\n res(evt.rotationRate && evt.rotationRate.alpha != null);\n };\n\n window.addEventListener(BROWSER.EVENTS.DEVICE_MOTION, onDeviceMotionChange);\n });\n\n const timeout = () => new Promise(res => {\n setTimeout(() => res(false), 1000);\n });\n\n return Promise.race([listenDeviceMotion(), timeout()])\n .then((available: boolean) => {\n window.removeEventListener(BROWSER.EVENTS.DEVICE_MOTION, onDeviceMotionChange);\n\n return available;\n });\n }\n\n /**\n * Request user permission for gyroscope sensor.\n * This can be used in environments like iOS which requires user permission when using gyroscope sensors.\n * @ko 사용자의 sensor permission 취득을 요청합니다.\n * iOS와 같이 gyroscope 사용시 사용자 Permission을 요구하는 환경에서 사용 가능합니다.\n * @returns Whether the permission is granted {@ko 사용자 permission 취득 여부}\n */\n public static async requestSensorPermission(): Promise {\n // Request sensor permission, on iOS13+\n if (sensorCanBeEnabledIOS()) {\n return (DeviceMotionEvent as typeof DeviceMotionEvent & {\n requestPermission: () => Promise;\n }).requestPermission().then(permissionState => {\n return permissionState === \"granted\";\n }).catch(() => false);\n }\n\n return true;\n }\n\n /**\n * Create new GyroControl instance\n * @ko GyroControl의 인스턴스를 생성합니다.\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(enableBlocked: boolean, {\n ignoreRoll = true\n }: Partial = {}) {\n super();\n\n this._enableBlocked = enableBlocked;\n this._ignoreRoll = ignoreRoll;\n this._input = new GyroInput();\n }\n\n /**\n * @copy CameraControl#destroy\n */\n public destroy(): void {\n this.disable();\n this._input.off();\n this.off();\n }\n\n /**\n * @hidden\n */\n public update(camera: Camera, yaw: Motion, pitch: Motion, zoom: number) {\n if (!this._ignoreRoll) {\n this._updateQuaternion(camera, zoom);\n } else {\n this._updateYawPitch(camera, yaw, pitch, zoom);\n }\n }\n\n /**\n * @copy CameraControl#enable\n */\n public enable(): void {\n if (this._input.enabled) return;\n\n this._input.enable();\n this._enableBlocked = false;\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: false });\n }\n\n /**\n * @copy CameraControl#disable\n */\n public disable(): void {\n if (!this._input.enabled) return;\n\n this._input.disable();\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: false });\n }\n\n /**\n * @copy CameraControl#sync\n */\n public sync(): void {} // eslint-disable-line @typescript-eslint/no-empty-function\n\n private _updateYawPitch(camera: Camera, yaw: Motion, pitch: Motion, zoom: number) {\n const input = this._input;\n if (!input.enabled) return;\n\n const {\n yaw: yawDelta,\n pitch: pitchDelta\n } = input.collectDelta();\n\n yaw.add(yawDelta);\n pitch.add(pitchDelta);\n\n camera.lookAt({\n yaw: yaw.val,\n pitch: pitch.val,\n zoom\n });\n }\n\n private _updateQuaternion(camera: Camera, zoom: number) {\n const input = this._input;\n if (!input.enabled) return;\n\n input.update();\n camera.rotate(input.quaternion, zoom);\n }\n}\n\nexport default GyroControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport CameraControl from \"./CameraControl\";\nimport RotateControl, { RotateControlEvents, RotateControlOptions } from \"./RotateControl\";\nimport ZoomControl, { ZoomControlOptions } from \"./ZoomControl\";\nimport GyroControl, { GyroControlOptions } from \"./GyroControl\";\nimport Camera from \"../core/Camera\";\nimport CameraAnimation from \"../core/CameraAnimation\";\nimport * as BROWSER from \"../const/browser\";\nimport { CAMERA_EVENTS, CONTROL_EVENTS } from \"../const/internal\";\nimport { ValueOf } from \"../type/utils\";\nimport { getObjectOption, hfovToZoom } from \"../utils\";\n\n/**\n * Options for {@link PanoControl}\n * @ko {@link PanoControl}용 옵션들\n * @since 4.0.0\n */\nexport interface PanoControlOptions {\n /**\n * @copy View360#useGrabCursor\n */\n useGrabCursor: boolean;\n /**\n * @copy View360#scrollable\n */\n scrollable: boolean;\n /**\n * @copy View360#wheelScrollable\n */\n wheelScrollable: boolean;\n /**\n * @copy View360#disableContextMenu\n */\n disableContextMenu: boolean;\n /**\n * Options for {@link RotateControl}.\n * `false` to disable rotation.\n * @ko {@link RotateControl}용 옵션들.\n * `false`일 경우 회전이 비활성화됩니다.\n * @since 4.0.0\n */\n rotate: boolean | Partial;\n /**\n * Options for {@link ZoomControl}.\n * `false` to disable zoom.\n * @ko {@link ZoomControl}용 옵션들.\n * `false`일 경우 줌이 비활성화됩니다.\n * @since 4.0.0\n */\n zoom: boolean | Partial;\n /**\n * Options for {@link GyroControl}.\n * `false` to disable gyroscope control.\n * @ko {@link GyroControl}용 옵션들.\n * `false`일 경우 자이로스코프를 통한 컨트롤이 비활성화됩니다.\n * @since 4.0.0\n */\n gyro: boolean | Partial;\n}\n\n/**\n * Panorama control for View360\n * @ko View360용 파노라마 컨트롤\n * @since 4.0.0\n */\nclass PanoControl {\n // Options\n private _useGrabCursor: PanoControlOptions[\"useGrabCursor\"];\n private _disableContextMenu: PanoControlOptions[\"disableContextMenu\"];\n\n // Internal Values\n private _camera: Camera;\n private _controlEl: HTMLElement;\n private _rotateControl: RotateControl;\n private _zoomControl: ZoomControl;\n private _gyroControl: GyroControl;\n private _ignoreZoomScale: boolean;\n private _enabled: boolean;\n\n /**\n * @copy View360#useGrabCursor\n */\n public get useGrabCursor() { return this._useGrabCursor; }\n public set useGrabCursor(val: PanoControlOptions[\"useGrabCursor\"]) {\n if (val === this._useGrabCursor) return;\n\n this._useGrabCursor = val;\n\n if (val && this._enabled) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n } else if (!val) {\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n }\n\n /**\n * @copy View360#disableContextMenu\n */\n public get disableContextMenu() { return this._disableContextMenu; }\n public set disableContextMenu(val: PanoControlOptions[\"disableContextMenu\"]) {\n if (val === this._disableContextMenu) return;\n\n this._disableContextMenu = val;\n\n if (val && this._enabled) {\n this._blockContextMenu();\n } else if (!val) {\n this._restoreContextMenu();\n }\n }\n\n /**\n * @copy View360#disableContextMenu\n */\n public get scrollable() { return this._rotateControl.scrollable; }\n public set scrollable(val: PanoControlOptions[\"scrollable\"]) { this._rotateControl.scrollable = val; }\n /**\n * @copy View360#disableContextMenu\n */\n public get wheelScrollable() { return this._zoomControl.scrollable; }\n public set wheelScrollable(val: PanoControlOptions[\"wheelScrollable\"]) { this._zoomControl.scrollable = val; }\n /**\n * When `true`, disables rotation slow-down by zoom-value.\n * @ko `true`일 경우 줌 된 정도에 따라 회전속도를 늦추는 동작을 비활성화합니다.\n * @since 4.0.0\n */\n public get ignoreZoomScale() { return this._ignoreZoomScale; }\n public set ignoreZoomScale(val: boolean) { this._ignoreZoomScale = val; }\n\n /**\n * Whether the control is enabled or not\n * @ko 컨트롤 활성화 여부를 가리키는 값\n * @readonly\n * @since 4.0.0\n */\n public get enabled() { return this._enabled; }\n /**\n * @copy View360#rotate\n */\n public get rotate() { return this._rotateControl; }\n /**\n * @copy View360#zoom\n */\n public get zoom() { return this._zoomControl; }\n /**\n * @copy View360#gyro\n */\n public get gyro() { return this._gyroControl; }\n\n /**\n * Whether one of the controls is animating at the moment\n * @ko 현재 컨트롤 중 하나라도 동작중인지 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get animating() {\n return this._rotateControl.animating\n || this._zoomControl.animating\n || this._gyroControl.animating;\n }\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param element - Canvas element {@ko 캔버스 엘리먼트}\n * @param camera - Camera instance {@ko Camera 인스턴스}\n * @param options - Options for PanoControl {@ko PanoControl 옵션들}\n */\n public constructor(element: HTMLElement, camera: Camera, {\n useGrabCursor,\n scrollable,\n wheelScrollable,\n disableContextMenu,\n rotate,\n zoom,\n gyro\n }: PanoControlOptions) {\n // Bind Options\n this._useGrabCursor = useGrabCursor;\n this._disableContextMenu = disableContextMenu;\n\n // Set internal values\n this._camera = camera;\n this._controlEl = element;\n this._ignoreZoomScale = false;\n this._enabled = false;\n\n this._rotateControl = new RotateControl(element, !rotate, getObjectOption(rotate));\n this._zoomControl = new ZoomControl(element, !zoom, getObjectOption(zoom));\n this._gyroControl = new GyroControl(!gyro, getObjectOption(gyro));\n\n this._rotateControl.scrollable = scrollable;\n this._zoomControl.scrollable = wheelScrollable;\n\n this._bindEvents();\n }\n\n /**\n * Destroy the instance and remove all event listeners attached.\n * This also will reset CSS cursor to initial.\n * @ko 인스턴스를 삭제하고 부착된 모든 이벤트 리스너를 제거합니다.\n * 또한, 캔버스에 적용된 CSS cursor도 제거합니다.\n * @since 4.0.0\n */\n public destroy(): void {\n this.disable();\n this._rotateControl.destroy();\n this._zoomControl.destroy();\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n\n /**\n * Resize control to match target size.\n * @ko 컨트롤이 내부에 캐시하고 있는 크기값을 갱신합니다.\n * @param width New width {@ko 변경된 너비}\n * @param height New height {@ko 변경된 높이}\n * @since 4.0.0\n */\n public resize(width: number, height: number): void {\n const camera = this._camera;\n\n this._rotateControl.resize(camera.fov, camera.aspect, width, height);\n }\n\n /**\n * Enable this control and add event listeners.\n * @ko 컨트롤을 활성화하고 이벤트 리스너들을 추가합니다.\n * @since 4.0.0\n */\n public async enable(): Promise {\n if (this._enabled) return;\n\n if (!this._rotateControl.enableBlocked) {\n this._rotateControl.enable();\n }\n\n if (!this._zoomControl.enableBlocked) {\n this._zoomControl.enable();\n }\n\n if (!this._gyroControl.enableBlocked) {\n if (await GyroControl.isAvailable()) {\n this._gyroControl.enable();\n }\n }\n\n this.sync();\n\n if (this._disableContextMenu) {\n this._blockContextMenu();\n }\n\n this._enabled = true;\n }\n\n /**\n * Disable this control and remove all event listeners\n * @ko 컨트롤을 비활성화하고 모든 이벤트 리스너들을 제거합니다.\n * @since 4.0.0\n */\n public disable(): void {\n if (!this._enabled) return;\n\n this._rotateControl.disable();\n this._zoomControl.disable();\n this._gyroControl.disable();\n\n this._restoreContextMenu();\n\n this._enabled = false;\n }\n\n /**\n * Update control by given deltaTime\n * @ko 컨트롤을 주어진 시간만큼 업데이트합니다.\n * @param delta Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n * @internal\n */\n public update(delta: number): void {\n const camera = this._camera;\n const rotateControl = this._rotateControl;\n const zoomControl = this._zoomControl;\n const gyroControl = this._gyroControl;\n\n zoomControl.update(delta);\n const zoom = hfovToZoom(camera.fov, zoomControl.zoom);\n\n // Slow down rotation on zoom-in\n const zoomScale = this._ignoreZoomScale ? 1 : Math.max(zoom, 1);\n rotateControl.setZoomScale(zoomScale);\n rotateControl.updateRange(camera, zoom);\n rotateControl.update(delta);\n\n const yaw = rotateControl.yaw;\n const pitch = rotateControl.pitch;\n\n if (gyroControl.enabled) {\n gyroControl.update(camera, yaw, pitch, zoom);\n } else {\n camera.lookAt({\n yaw: yaw.val,\n pitch: pitch.val,\n zoom\n });\n }\n }\n\n /**\n * Synchronize this control's state to current camera state\n * @ko 컨트롤을 카메라의 현재 상태와 동기화합니다.\n * @since 4.0.0\n */\n public sync(): void {\n const camera = this._camera;\n\n this._zoomControl.sync(camera);\n this._rotateControl.sync(camera);\n }\n\n private _blockContextMenu() {\n const el = this._controlEl;\n\n el.addEventListener(BROWSER.EVENTS.CONTEXT_MENU, this._preventContextMenu);\n }\n\n private _restoreContextMenu() {\n const el = this._controlEl;\n\n el.removeEventListener(BROWSER.EVENTS.CONTEXT_MENU, this._preventContextMenu);\n }\n\n private _preventContextMenu = (evt: MouseEvent) => {\n evt.preventDefault();\n };\n\n private _setCursor(newCursor: ValueOf) {\n if (!this._useGrabCursor && newCursor !== BROWSER.CURSOR.NONE) return;\n\n const targetEl = this._controlEl;\n targetEl.style.cursor = newCursor;\n }\n\n private _bindEvents() {\n const rotateControl = this._rotateControl;\n const zoomControl = this._zoomControl;\n\n rotateControl.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n rotateControl.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n rotateControl.on(CONTROL_EVENTS.ENABLE, this._onEnable);\n rotateControl.on(CONTROL_EVENTS.DISABLE, this._onDisable);\n zoomControl.on(CONTROL_EVENTS.ENABLE, this._onEnable);\n zoomControl.on(CONTROL_EVENTS.DISABLE, this._onDisable);\n this._camera.on(CAMERA_EVENTS.ANIMATION_END, this._onCameraAnimationEnd);\n }\n\n private _onInputStart = (evt: RotateControlEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n if (this._useGrabCursor && !evt.isKeyboard) {\n this._setCursor(BROWSER.CURSOR.GRABBING);\n }\n };\n\n private _onInputEnd = (evt: RotateControlEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n if (this._useGrabCursor && !evt.isKeyboard) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n }\n };\n\n private _onEnable = ({\n control,\n updateCursor\n }: {\n control: CameraControl;\n updateCursor: boolean;\n }) => {\n if (updateCursor && this._useGrabCursor) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n }\n\n control.sync(this._camera);\n };\n\n private _onDisable = ({\n updateCursor\n }: {\n updateCursor: boolean\n }) => {\n if (updateCursor) {\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n };\n\n private _onCameraAnimationEnd = ({ animation }: { animation: CameraAnimation }) => {\n animation.getFinishPromise().then(() => {\n this.sync();\n });\n };\n}\n\nexport default PanoControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport TextureVideo from \"./TextureVideo\";\nimport TextureCube from \"./TextureCube\";\n\n/**\n * @hidden\n */\nabstract class Texture {\n public width: number;\n public height: number;\n public flipY: boolean;\n public wrapS: number;\n public wrapT: number;\n\n public constructor({\n width,\n height,\n flipY\n }: {\n width: number;\n height: number;\n flipY: boolean;\n }) {\n this.width = width;\n this.height = height;\n this.flipY = flipY;\n this.wrapS = WebGLRenderingContext.CLAMP_TO_EDGE;\n this.wrapT = WebGLRenderingContext.CLAMP_TO_EDGE;\n }\n\n public destroy() {\n // DO_NOTHING\n }\n\n public isVideo(): this is TextureVideo {\n return false;\n }\n\n public isCube(): this is TextureCube {\n return false;\n }\n}\n\nexport default Texture;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture from \"./Texture\";\n\n/**\n * @hidden\n */\nclass Texture2D extends Texture {\n public source: Exclude;\n\n public constructor({\n source,\n width,\n height,\n flipY\n }: {\n source: Exclude;\n width: number;\n height: number;\n flipY: boolean;\n }) {\n super({\n width,\n height,\n flipY\n });\n\n this.source = source;\n }\n}\n\nexport default Texture2D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"./Texture2D\";\n\n/**\n * @hidden\n */\nclass TextureVideo extends Texture2D {\n public source: HTMLVideoElement;\n\n public destroy() {\n const video = this.source;\n\n video.pause();\n video.removeAttribute(\"src\");\n video.load();\n }\n\n public isVideo(): this is TextureVideo { return true; }\n\n public isPaused() {\n const video = this.source;\n\n return video.paused || video.ended || video.readyState <= 2;\n }\n\n public hasAudio() {\n const video = this.source as any;\n\n if (video.audioTracks) {\n return video.audioTracks.length > 0;\n }\n\n if (video.webkitAudioDecodedByteCount != null) {\n return video.webkitAudioDecodedByteCount > 0;\n }\n\n if (video.mozHasAudio != null) {\n return video.mozHasAudio;\n }\n\n // We don't know whether the video has audio or not, return true\n return true;\n }\n}\n\nexport default TextureVideo;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture from \"./Texture\";\n\n/**\n * @hidden\n */\nclass TextureCube extends Texture {\n public sources: TexImageSource[];\n\n public constructor({\n sources,\n width,\n height,\n flipY\n }: {\n sources: TexImageSource[];\n width: number;\n height: number;\n flipY: boolean;\n }) {\n super({\n width,\n height,\n flipY\n });\n\n this.sources = sources;\n }\n\n public isCube(): this is TextureCube { return true; }\n}\n\nexport default TextureCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ImReady from \"@egjs/imready\";\nimport Texture from \"../texture/Texture\";\nimport Texture2D from \"../texture/Texture2D\";\nimport TextureVideo from \"../texture/TextureVideo\";\nimport TextureCube from \"../texture/TextureCube\";\nimport { getObjectOption, isString } from \"../utils\";\nimport { VideoConfig } from \"../type/external\";\nimport { ProjectionOptions } from \"../projection/Projection\";\n\n/**\n * @hidden\n */\nclass TextureLoader {\n private _loadChecker: ImReady;\n\n constructor() {\n this._loadChecker = new ImReady();\n }\n\n public async load(src: ProjectionOptions[\"src\"], video: ProjectionOptions[\"video\"]): Promise {\n if (video) {\n return this.loadVideo(src, getObjectOption(video));\n } else {\n if (Array.isArray(src) && src.length > 1) {\n return this.loadCubeImage(src);\n } else {\n const imgSrc = Array.isArray(src) ? src[0] : src;\n return this.loadImage(imgSrc);\n }\n }\n }\n\n public async loadImage(src: string | HTMLElement): Promise {\n const images = this._toImageArray(src);\n\n return this._load(images, resolve => {\n const image = images[0];\n\n resolve(new Texture2D({\n source: image,\n width: image.naturalWidth,\n height: image.naturalHeight,\n flipY: true\n }));\n });\n }\n\n public async loadCubeImage(src: Array): Promise {\n const images = this._toImageArray(src);\n\n return this._load(images, resolve => {\n resolve(new TextureCube({\n sources: images,\n width: images[0].naturalWidth,\n height: images[0].naturalHeight,\n flipY: false\n }));\n });\n }\n\n public async loadVideo(src: ProjectionOptions[\"src\"], videoConfig: Partial): Promise {\n const config: VideoConfig = {\n autoplay: true,\n muted: true,\n loop: false,\n volume: 1,\n ...videoConfig,\n };\n const video = this._toVideoElement(src, config);\n\n return this._load([video], resolve => {\n const { autoplay, muted } = config;\n\n video.currentTime = 0;\n if (autoplay && muted) {\n video.play().catch(() => void 0);\n }\n\n resolve(new TextureVideo({\n source: video,\n width: video.videoWidth,\n height: video.videoHeight,\n flipY: true\n }));\n });\n }\n\n private _load(content: HTMLElement[], onLoad: (resolve: (value: T) => void) => void): Promise {\n const loader = this._loadChecker;\n\n return new Promise((resolve, reject) => {\n loader.once(\"ready\", evt => {\n if (evt.errorCount > 0) return;\n\n onLoad(resolve);\n });\n\n loader.once(\"error\", reject);\n loader.check(content);\n });\n }\n\n private _toImageArray(src: ProjectionOptions[\"src\"]): HTMLImageElement[] {\n const srcs = Array.isArray(src) ? src : [src];\n\n return srcs.map(source => {\n if (isString(source)) {\n const imgEl = new Image();\n\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = source;\n\n return imgEl;\n } else {\n return source as HTMLImageElement;\n }\n });\n }\n\n private _toVideoElement(src: ProjectionOptions[\"src\"], {\n muted,\n loop,\n volume\n }: VideoConfig): HTMLVideoElement {\n if (src instanceof HTMLVideoElement) {\n return src;\n }\n\n const video = document.createElement(\"video\");\n\n video.crossOrigin = \"anonymous\";\n video.playsInline = true;\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.muted = muted;\n video.volume = volume;\n video.loop = loop;\n\n if (Array.isArray(src)) {\n src.forEach(source => this._appendSourceElement(video, source));\n } else {\n this._appendSourceElement(video, src);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0 && video.readyState < 1) {\n video.load();\n }\n\n return video;\n }\n\n private _appendSourceElement(video: HTMLMediaElement, src: string | HTMLElement) {\n if (src instanceof HTMLSourceElement) {\n return src;\n }\n\n const sourceEl = document.createElement(\"source\");\n sourceEl.src = src as string;\n video.appendChild(sourceEl);\n }\n}\n\nexport default TextureLoader;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * @internal\n */\nclass FrameAnimator {\n public maxDeltaTime: number;\n\n private _context: Window | XRSession;\n private _rafId: number;\n private _rafTimer: number;\n private _lastUpdateTime: number;\n\n /** */\n public constructor(maxDeltaTime: number, context: Window | XRSession = window) {\n this.maxDeltaTime = maxDeltaTime;\n\n this._context = context;\n this._rafId = -1;\n this._rafTimer = -1;\n this._lastUpdateTime = -1;\n }\n\n public start(callback: (delta: number, ...args: any[]) => any) {\n const context = this._context;\n\n // No context / callback set\n if (!context || !callback) return;\n\n // Animation already started\n if (this._rafId >= 0 || this._rafTimer >= 0) return;\n\n const loop = (_time: number, frame?: XRFrame) => {\n const time = Date.now();\n const delta = Math.min(time - this._lastUpdateTime, this.maxDeltaTime * 1000);\n\n callback(delta, frame);\n\n this._lastUpdateTime = time;\n this._rafId = context.requestAnimationFrame(loop);\n };\n\n this._lastUpdateTime = Date.now();\n this._rafId = context.requestAnimationFrame(loop);\n }\n\n public stop() {\n if (this._rafId >= 0) {\n this._context.cancelAnimationFrame(this._rafId);\n }\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n }\n\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n public changeContext(context: Window | XRSession) {\n this.stop();\n this._context = context;\n }\n}\n\nexport default FrameAnimator;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport * as BROWSER from \"../const/browser\";\n\n/**\n * Automatic resizer that uses both ResizeObserver and window resize event\n */\nclass AutoResizer {\n private _enabled: boolean;\n private _resizeObserver: ResizeObserver | null;\n private _useResizeObserver: boolean;\n private _onResize: () => any;\n\n public get useResizeObserver() { return this._useResizeObserver; }\n\n /**\n * Returns whether AutoResizer is enabled\n */\n public get enabled() { return this._enabled; }\n\n /** */\n public constructor(useResizeObserver: boolean, onResize: () => any) {\n this._useResizeObserver = useResizeObserver;\n\n this._enabled = false;\n this._resizeObserver = null;\n this._onResize = onResize;\n }\n\n /**\n * Enable resizer\n */\n public enable(element: HTMLElement): this {\n if (this._enabled) {\n this.disable();\n }\n\n if (this._useResizeObserver && !!window.ResizeObserver) {\n const bbox = element.getBoundingClientRect();\n const resizeImmediate = bbox.width !== 0 || bbox.height !== 0;\n\n const resizeObserver = new ResizeObserver(resizeImmediate ? this._skipFirstResize : this._onResize);\n\n resizeObserver.observe(element);\n\n this._resizeObserver = resizeObserver;\n } else {\n window.addEventListener(BROWSER.EVENTS.RESIZE, this._onResize);\n }\n\n this._enabled = true;\n\n return this;\n }\n\n /**\n * Disable resizer\n */\n public disable(): this {\n if (!this._enabled) return this;\n\n const resizeObserver = this._resizeObserver;\n if (resizeObserver) {\n resizeObserver.disconnect();\n this._resizeObserver = null;\n } else {\n window.removeEventListener(BROWSER.EVENTS.RESIZE, this._onResize);\n }\n\n this._enabled = false;\n\n return this;\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n private _skipFirstResize = (() => {\n let isFirstResize = true;\n\n return (() => {\n if (isFirstResize) {\n isFirstResize = false;\n\n return;\n }\n this._onResize();\n });\n })();\n}\n\nexport default AutoResizer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Camera from \"./Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport View360 from \"../View360\";\nimport * as BROWSER from \"../const/browser\";\nimport { CONTROL_EVENTS } from \"../const/internal\";\nimport { circulate, getObjectOption } from \"../utils\";\n\n/**\n * Options for {@link Autoplay}\n * @ko {@link Autoplay}용 옵션들\n * @since 4.0.0\n */\nexport interface AutoplayOptions {\n /**\n * @copy Autoplay#delay\n */\n delay: number;\n /**\n * @copy Autoplay#delayOnMouseLeave\n */\n delayOnMouseLeave: number;\n /**\n * @copy Autoplay#speed\n */\n speed: number;\n /**\n * @copy Autoplay#pauseOnHover\n */\n pauseOnHover: boolean;\n /**\n * @copy Autoplay#canInterrupt\n */\n canInterrupt: boolean;\n /**\n * @copy Autoplay#disableOnInterrupt\n */\n disableOnInterrupt: boolean;\n}\n\n/**\n * A manager class for autoplay feature.\n * @ko Autoplay 기능의 매니저 클래스.\n * @since 4.0.0\n */\nclass Autoplay {\n // Options\n private _delay: number;\n private _delayOnMouseLeave: number;\n private _speed: number;\n private _pauseOnHover: boolean;\n private _canInterrupt: boolean;\n private _disableOnInterrupt: boolean;\n\n // Internal values\n private _enableBlocked: boolean;\n private _camera: Camera;\n private _control: PanoControl;\n private _element: HTMLElement;\n private _enabled: boolean;\n private _interrupted: boolean;\n private _interruptionTimer: number;\n private _hovering: boolean;\n\n /**\n * Whether autoplay is enabled or not\n * @ko 자동재생 활성화 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * Whether autoplay is updating the camera at the moment\n * @ko 현재 자동재생이 동작중인지 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get playing() {\n return this._enabled && !this._interrupted;\n }\n\n /**\n * Reactivation delay after mouse input in milisecond.\n * @ko 재활성화되기까지의 시간 (밀리초 단위)\n * @default 2000\n * @since 4.0.0\n */\n public get delay() { return this._delay; }\n public set delay(val: number) { this._delay = val; }\n\n /**\n * Reactivation delay after mouse leave when using {@link AutoplayOptions#pauseOnHover}\n * @ko {@link AutoplayOptions#pauseOnHover} 사용시 마우스가 캔버스 영역을 떠난 뒤 자동재생이 다시 활성화되기까지의 시간\n * @default 0\n * @since 4.0.0\n */\n public get delayOnMouseLeave() { return this._delayOnMouseLeave; }\n public set delayOnMouseLeave(val: number) { this._delayOnMouseLeave = val; }\n\n /**\n * Y-axis(yaw) rotation speed\n * @ko Y-축 회전(yaw)의 속도\n * @default 1\n * @since 4.0.0\n */\n public get speed() { return this._speed; }\n public set speed(val: number) { this._speed = val; }\n\n /**\n * Whether to pause rotation on mouse hover\n * @ko 마우스가 캔버스 영역에 들어왔을 때 자동재생을 정지할지 여부\n * @default false\n * @since 4.0.0\n */\n public get pauseOnHover() { return this._pauseOnHover; }\n public set pauseOnHover(val: boolean) { this._pauseOnHover = val; }\n\n /**\n * Whether user can interrupt the rotation with click/wheel input\n * @ko 클릭이나 휠같은 사용자 인터랙션시 자동재생을 멈출지 여부\n * @default true\n * @since 4.0.0\n */\n public get canInterrupt() { return this._canInterrupt; }\n public set canInterrupt(val: boolean) { this._canInterrupt = val; }\n\n /**\n * Whether to disable autoplay on user interrupt\n * @ko 사용자 동작에 의해 자동재생이 정지할 때, {@link Autoplay#disable}을 호출하여 자동재생을 영구히 정지할지 여부\n * @default false\n * @since 4.0.0\n */\n public get disableOnInterrupt() { return this._disableOnInterrupt; }\n public set disableOnInterrupt(val: boolean) { this._disableOnInterrupt = val; }\n\n /**\n * Create new AutoPlayer instance\n * @param camera - Instance of the {@link Camera} {@ko Camera의 인스턴스}\n * @param element - Canvas element {@ko 캔버스 엘리먼트}\n * @param options - Autoplay options {@ko 자동재생 옵션들}\n * @since 4.0.0\n */\n public constructor(viewer: View360, element: HTMLElement, options: boolean | Partial) {\n this._camera = viewer.camera;\n this._control = viewer.control;\n this._element = element;\n\n this._enabled = false;\n this._interrupted = false;\n this._interruptionTimer = -1;\n this._hovering = false;\n\n const {\n delay = 2000,\n delayOnMouseLeave = 0,\n speed = 1,\n pauseOnHover = false,\n canInterrupt = true,\n disableOnInterrupt = false\n } = getObjectOption(options);\n\n this._enableBlocked = !options;\n this._delay = delay;\n this._delayOnMouseLeave = delayOnMouseLeave;\n this._speed = speed;\n this._pauseOnHover = pauseOnHover;\n this._canInterrupt = canInterrupt;\n this._disableOnInterrupt = disableOnInterrupt;\n }\n\n /**\n * Destroy the instance and remove all event listeners attached\n * @ko 인스턴스를 제거하고 연결된 모든 이벤트 핸들러를 삭제합니다.\n * @since 4.0.0\n */\n public destroy(): void {\n this.disable();\n }\n\n /**\n * Rotate camera by given deltaTime\n * @ko 주어진 deltaTime만큼 카메라를 회전시킵니다.\n * @param deltaTime - Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n */\n public update(deltaTime: number): void {\n if (!this._enabled) return;\n if (this._interrupted) {\n if (this._disableOnInterrupt) {\n this.disable();\n }\n\n return;\n }\n\n const camera = this._camera;\n const delta = -this._speed * deltaTime / 100;\n\n camera.yaw = circulate(camera.yaw + delta, 0, 360);\n }\n\n /**\n * Enable autoplay and add event listeners.\n * @ko 자동재생을 활성화하고 이벤트리스너들을 추가합니다.\n * @since 4.0.0\n */\n public enable(): void {\n const control = this._control;\n const element = this._element;\n\n if (this._enabled || control.gyro.enabled) return;\n\n control.rotate.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.rotate.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.zoom.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.zoom.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.gyro.on(CONTROL_EVENTS.ENABLE, this._onGyroEnable);\n\n element.addEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter, false);\n element.addEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave, false);\n\n this._enabled = true;\n this._enableBlocked = false;\n }\n\n /**\n * Enable autoplay after current `delay` value.\n * @ko 현재의 `delay`값만큼 시간이 지난 다음에 자동재생을 활성화합니다.\n * @since 4.0.0\n */\n public enableAfterDelay() {\n this.enable();\n this._interrupted = true;\n this._setUninterruptedAfterDelay(this._delay);\n }\n\n /**\n * Disable autoplay and remove all event handlers.\n * @ko 자동재생을 비활성화하고 모든 이벤트 핸들러를 제거합니다.\n * @since 4.0.0\n */\n public disable(): void {\n if (!this._enabled) return;\n\n const control = this._control;\n const element = this._element;\n\n control.rotate.off(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.rotate.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.zoom.off(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.zoom.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.gyro.off(CONTROL_EVENTS.ENABLE, this._onGyroEnable);\n\n element.removeEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter, false);\n element.removeEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave, false);\n\n this._enabled = false;\n this._interrupted = false;\n this._hovering = false;\n\n this._clearTimeout();\n }\n\n private _onInputStart = () => {\n if (!this._canInterrupt) return;\n\n this._interrupted = true;\n this._clearTimeout();\n };\n\n private _onInputEnd = () => {\n this._setUninterruptedAfterDelay(this._delay);\n };\n\n private _onGyroEnable = () => {\n this.disable();\n };\n\n private _onMouseEnter = () => {\n if (!this._pauseOnHover) return;\n this._interrupted = true;\n this._hovering = true;\n };\n\n private _onMouseLeave = () => {\n if (!this._pauseOnHover) return;\n this._hovering = false;\n this._setUninterruptedAfterDelay(this._delayOnMouseLeave);\n };\n\n private _setUninterruptedAfterDelay(delay: number): void {\n if (this._hovering) return;\n\n this._clearTimeout();\n\n if (delay > 0) {\n this._interruptionTimer = window.setTimeout(() => {\n this._interrupted = false;\n this._interruptionTimer = -1;\n }, delay);\n } else {\n this._interrupted = false;\n this._interruptionTimer = -1;\n }\n }\n\n private _clearTimeout(): void {\n if (this._interruptionTimer >= 0) {\n window.clearTimeout(this._interruptionTimer);\n this._interruptionTimer = -1;\n }\n }\n}\n\nexport default Autoplay;\n","import { mat4 } from \"gl-matrix\";\nimport Component from \"@egjs/component\";\nimport WebGLContext from \"./WebGLContext\";\nimport GyroControl from \"../control/GyroControl\";\nimport * as BROWSER from \"../const/browser\";\nimport { SESSION_VR, XR_REFERENCE_SPACE } from \"../const/internal\";\nimport { EVENTS } from \"../const/external\";\n\ninterface XRSessionOptions extends XRSessionInit {\n [key: string]: any;\n}\n\n/**\n * WebXR manager class\n * @ko WebXR 매니저 클래스\n * @since 4.0.0\n */\nclass XRManager extends Component<{\n /**\n * An event that fires on entering VR session\n * @ko VR 세션 진입시에 트리거되는 이벤트\n * @eventName vrStart\n * @eventOf XRManager\n * @version 4.0.0\n */\n [EVENTS.VR_START]: {\n session: XRSession;\n };\n /**\n * An event that fires on exiting VR session\n * @ko VR 세션에서 나갈 때 트리거되는 이벤트\n * @eventName vrEnd\n * @eventOf XRManager\n * @version 4.0.0\n */\n [EVENTS.VR_END]: void;\n}> {\n private _ctx: WebGLContext;\n private _xrSession: XRSession | null;\n private _xrRefSpace: XRReferenceSpace | null;\n private _options: XRSessionOptions;\n\n /**\n * Create new instance.\n * 새 인스턴스를 생성합니다.\n * @param ctx - Instance of WebGL context helper {@ko WebGL 콘텍스트 헬퍼의 인스턴스}\n * @param options - Options {@ko 옵션들}\n */\n public constructor(ctx: WebGLContext, options: XRSessionOptions = {}) {\n super();\n\n this._xrSession = null;\n this._xrRefSpace = null;\n this._ctx = ctx;\n this._options = options;\n }\n\n /**\n * Destroy instance and end XR session if there was any.\n * @ko 인스턴스를 제거하고, XR 세션이 존재할 경우 종료합니다.\n * @since 4.0.0\n */\n public destroy = () => {\n this.exit();\n this.off();\n };\n\n /**\n * Returns WebXR availability.\n * @ko WebXR 사용 가능 여부를 반환합니다.\n * @since 4.0.0\n */\n public async isAvailable(): Promise {\n // eslint-disable-next-line compat/compat\n const xr = window.navigator.xr;\n if (!xr) return false;\n\n return xr.isSessionSupported(SESSION_VR)\n .then(available => {\n return available;\n }).catch(() => {\n return false;\n });\n }\n\n /**\n * Enter VR session\n * @ko VR 세션에 진입합니다.\n * @since 4.0.0\n */\n public async enter() {\n const ctx = this._ctx;\n\n // eslint-disable-next-line compat/compat\n const xr = window.navigator.xr;\n if (!xr) return;\n\n await GyroControl.requestSensorPermission();\n\n const options = {\n ...{\n requiredFeatures: [XR_REFERENCE_SPACE]\n },\n ...this._options\n };\n\n await ctx.makeXRCompatible();\n\n const session = await xr.requestSession(SESSION_VR, options);\n ctx.bindXRLayer(session);\n\n const refSpace = await session.requestReferenceSpace(XR_REFERENCE_SPACE);\n\n this._setSession(session, refSpace);\n\n this.trigger(EVENTS.VR_START, {\n session\n });\n }\n\n /**\n * Exit VR session\n * @ko VR 세션에서 나갑니다.\n * @since 4.0.0\n */\n public exit() {\n const xrSession = this._xrSession;\n\n if (xrSession) {\n xrSession.end()\n .catch(() => void 0);\n }\n\n this._xrSession = null;\n this._xrRefSpace = null;\n }\n\n /**\n * @hidden\n */\n public canRender(frame: XRFrame) {\n const refSpace = this._xrRefSpace;\n\n if (!refSpace) return false;\n\n const pose = frame.getViewerPose(refSpace);\n\n return !!pose;\n }\n\n /**\n * @hidden\n */\n public getEyeParams(frame: XRFrame): Array<{\n viewport: XRViewport;\n vMatrix: mat4;\n pMatrix: mat4;\n }> | null {\n const session = frame.session;\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n if (!pose) return null;\n\n const glLayer = session.renderState.baseLayer;\n\n if (!glLayer) return null;\n\n return pose.views.map(view => {\n const viewport = glLayer.getViewport(view)!;\n const vMatrix = view.transform.inverse.matrix;\n\n return {\n viewport,\n vMatrix,\n pMatrix: view.projectionMatrix\n };\n });\n }\n\n private _setSession(session: XRSession, refSpace: XRReferenceSpace) {\n this._xrSession = session;\n this._xrRefSpace = refSpace;\n\n session.addEventListener(BROWSER.EVENTS.XR_END, this._onSessionEnd);\n }\n\n private _onSessionEnd = () => {\n this.exit();\n this.trigger(EVENTS.VR_END);\n }\n}\n\nexport default XRManager;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { vec3 } from \"gl-matrix\";\n\n/**\n * Hotspot data\n * @ko 핫스팟 데이터\n * @since 4.0.0\n */\nclass Hotspot {\n /**\n * HTMLElement of the hotspot\n * @ko 핫스팟의 HTMLElement\n * @since 4.0.0\n */\n public readonly element: HTMLElement;\n /**\n * Position to render hotspot\n * @ko 핫스팟을 렌더링할 위치\n * @since 4.0.0\n */\n public readonly position: vec3;\n\n public constructor(element: HTMLElement, position: vec3) {\n this.element = element;\n this.position = position;\n }\n}\n\nexport default Hotspot;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { vec2, vec3 } from \"gl-matrix\";\nimport Hotspot from \"./Hotspot\";\nimport Camera from \"../core/Camera\";\nimport WebGLRenderer from \"../core/WebGLRenderer\";\nimport View360Error from \"../core/View360Error\";\nimport { getNullableElement } from \"../utils\";\nimport ERROR from \"../const/error\";\nimport { DEFAULT_CLASS } from \"../const/external\";\nimport { DEG_TO_RAD } from \"../const/internal\";\n\n/**\n * Options for {@link HotspotRenderer}\n * @ko {@link HotspotRenderer}용 옵션들\n * @since 4.0.0\n */\nexport interface HotspotOptions {\n /**\n * Apply scale for hotspots, makes their size sync with background panorama image.\n * @ko 핫스팟에 스케일을 적용해서 배경 파노라마 이미지의 크기 변화와 동일하게 크기를 조절합니다.\n * @since 4.0.0\n */\n zoom: boolean;\n}\n\n/**\n * Hotspot renderer\n * @ko Hotspot 렌더러\n * @since 4.0.0\n */\nclass HotspotRenderer {\n // Options\n private _zoom: HotspotOptions[\"zoom\"];\n\n // Internal properties\n private _containerEl: HTMLElement | null;\n private _renderer: WebGLRenderer;\n private _hotspots: Hotspot[];\n\n /**\n * Create new instance\n * @ko 새 인스턴스를 생성합니다.\n * @param rootEl - Container element for hotspots {@ko 핫스팟들의 컨테이너 엘리먼트}\n * @param renderer - instance of WebGLRenderer {@ko WebGLRenderer의 인스턴스}\n * @param options - Hotspot options {@ko Hotspot 옵션들 }\n */\n public constructor(rootEl: HTMLElement, renderer: WebGLRenderer, {\n zoom = false\n }: Partial) {\n this._containerEl = getNullableElement(`.${DEFAULT_CLASS.HOTSPOT_CONTAINER}`, rootEl);\n this._renderer = renderer;\n this._hotspots = [];\n\n this._zoom = zoom;\n }\n\n /**\n * Refresh hotspots by collecting hotspot elements from current hotspot root element\n * @ko 현재 핫스팟 루트 엘리먼트 내에서 핫스팟 엘리먼트들을 수집하여 갱신합니다.\n * @throws {ERROR_CODES.INSUFFICIENT_ARGS} if data-position doesn't include all x, y, z values {@ko data-position이 x, y, z좌표를 전부 포함하고 있지 않을 때}\n */\n public refresh() {\n const container = this._containerEl;\n if (!container) return;\n\n const hotspotEls = [].slice.apply(container.querySelectorAll(`.${DEFAULT_CLASS.HOTSPOT}`)) as HTMLElement[];\n this._hotspots = hotspotEls.map(el => this._parseHotspot(el));\n }\n\n /**\n * Render hotspots\n * @ko 핫스팟들을 렌더링합니다.\n * @param camera - Instance of Camera {@ko Camera의 인스턴스}\n */\n public render(camera: Camera) {\n const hotspots = this._hotspots;\n const halfWidth = this._renderer.width * 0.5;\n const halfHeight = this._renderer.height * 0.5;\n const zoom = camera.zoom;\n const centerTransform = \"translate(-50%, -50%)\";\n const zoomTransform = this._zoom ? `scale(${zoom})` : \"\";\n\n hotspots.forEach(hotspot => {\n const position = hotspot.position;\n const relPos = vec3.create();\n\n vec3.copy(relPos, position);\n vec3.transformMat4(relPos, relPos, camera.viewMatrix);\n vec3.transformMat4(relPos, relPos, camera.projectionMatrix);\n\n if (relPos[2] > 1 || relPos[2] < 0) {\n hotspot.element.classList.remove(DEFAULT_CLASS.HOTSPOT_VISIBLE);\n return;\n }\n\n const screenPos = vec2.fromValues(\n relPos[0] * halfWidth + halfWidth,\n -relPos[1] * halfHeight + halfHeight\n );\n\n hotspot.element.classList.add(DEFAULT_CLASS.HOTSPOT_VISIBLE);\n hotspot.element.style.transform = [\n centerTransform,\n `translate(${screenPos[0]}px, ${screenPos[1]}px)`,\n zoomTransform\n ].join(\" \");\n });\n }\n\n private _parseHotspot(element: HTMLElement): Hotspot {\n const yawStr = element.dataset.yaw;\n const pitchStr = element.dataset.pitch;\n const positionStr = element.dataset.position;\n\n if (yawStr || pitchStr) {\n const yaw = yawStr ? parseFloat(yawStr) : 0;\n const pitch = pitchStr ? parseFloat(pitchStr) : 0;\n\n const position = this._yawPitchToVec3(yaw, pitch);\n\n return new Hotspot(element, position);\n } else if (positionStr) {\n const pos: number[] = positionStr.split(\" \").map(val => parseFloat(val));\n if (pos.length < 3) {\n throw new View360Error(ERROR.MESSAGES.INSUFFICIENT_ARGS(positionStr, \"hotspot attribute \\\"data-position\\\"\"), ERROR.CODES.INSUFFICIENT_ARGS);\n }\n\n return new Hotspot(element, vec3.fromValues(pos[0], pos[1], pos[2]));\n } else {\n // Place hotspot at yaw: 0, pitch: 0\n const defaultPos = vec3.fromValues(0, 0, -1);\n\n return new Hotspot(element, defaultPos);\n }\n }\n\n private _yawPitchToVec3(yaw: number, pitch: number) {\n const yawRad = yaw * DEG_TO_RAD;\n const pitchRad = pitch * DEG_TO_RAD;\n const position = vec3.create();\n\n position[1] = Math.sin(pitchRad);\n position[2] = Math.cos(pitchRad);\n\n position[0] = position[2] * Math.sin(-yawRad);\n position[2] = -position[2] * Math.cos(-yawRad);\n\n return position;\n }\n}\n\nexport default HotspotRenderer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"../geometry/Geometry\";\nimport { VAO } from \"../type/internal\";\n\n/**\n * @hidden\n */\nclass VertexArrayObject {\n public readonly obj: VAO | null;\n public readonly geometry: Geometry;\n public readonly buffers: {\n indicies: WebGLBuffer;\n position: WebGLBuffer;\n uv: WebGLBuffer;\n }\n\n public get count() { return this.geometry.indicies.count; }\n\n constructor(obj: VAO | null, geometry: Geometry, buffers: VertexArrayObject[\"buffers\"]) {\n this.obj = obj;\n this.geometry = geometry;\n this.buffers = buffers;\n }\n}\n\nexport default VertexArrayObject;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4 } from \"gl-matrix\";\nimport Uniform from \"../uniform/Uniform\";\nimport Camera from \"./Camera\";\nimport Object3D from \"./Object3D\";\nimport ShaderProgram from \"./ShaderProgram\";\nimport View360Error from \"./View360Error\";\nimport VertexArrayObject from \"./VertexArrayObject\";\nimport VertexData from \"./VertexData\";\nimport Texture from \"../texture/Texture\";\nimport Geometry from \"../geometry/Geometry\";\nimport * as BROWSER from \"../const/browser\";\nimport ERROR from \"../const/error\";\nimport { DEFAULT_CLASS } from \"../const/external\";\nimport { UniformLocations } from \"../type/internal\";\n\n/**\n * @hidden\n */\nclass WebGLContext {\n private _canvas: HTMLCanvasElement;\n private _gl: WebGLRenderingContext | WebGL2RenderingContext;\n private _contextLost: boolean;\n private _maxTextureSize: number;\n private _isWebGL2: boolean;\n private _debug: boolean;\n private _extensions: {\n vao: OES_vertex_array_object | null;\n loseContext: WEBGL_lose_context | null;\n };\n\n public get canvas() { return this._canvas; }\n public get maxTextureSize() { return this._maxTextureSize; }\n public get isWebGL2() { return this._isWebGL2; }\n public get supportVAO() { return this._isWebGL2 || !!this._extensions.vao; }\n public get lost() { return this._contextLost; }\n public get debug() { return this._debug; }\n\n public constructor(canvas: HTMLCanvasElement, debug: boolean) {\n this._canvas = canvas;\n this._contextLost = false;\n this._debug = debug;\n this._extensions = {\n vao: null,\n loseContext: null\n };\n }\n\n public init() {\n const canvas = this._canvas;\n\n const { gl, isWebGL2 } = this._getContext(canvas);\n\n this._gl = gl;\n this._maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n this._isWebGL2 = isWebGL2;\n\n if (!this._isWebGL2) {\n this._extensions.vao = gl.getExtension(\"OES_vertex_array_object\");\n }\n\n this._extensions.loseContext = gl.getExtension(\"WEBGL_lose_context\");\n\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_LOST, this._onContextLost);\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_RESTORED, this._onContextRestore);\n\n // gl.enable(gl.DEPTH_TEST);\n }\n\n public destroy() {\n const gl = this._gl;\n const canvas = this._canvas;\n\n if (gl) {\n // gl is not defined when destroy is called before init\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n }\n\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_LOST, this._onContextLost);\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_RESTORED, this._onContextRestore);\n }\n\n public forceLoseContext() {\n const extension = this._extensions.loseContext;\n\n if (!extension) return;\n\n extension.loseContext();\n }\n\n public forceRestoreContext() {\n const extension = this._extensions.loseContext;\n\n if (!extension) return;\n\n extension.restoreContext();\n }\n\n public clear() {\n const gl = this._gl;\n\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n\n public resize() {\n const gl = this._gl;\n\n gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n }\n\n public viewport(x: number, y: number, width: number, height: number) {\n const gl = this._gl;\n\n gl.viewport(x, y, width, height);\n }\n\n public createVAO(geometry: Geometry, shaderProgram: ShaderProgram) {\n const nativeVAO = this._createNativeVAO();\n\n const vao = new VertexArrayObject(nativeVAO, geometry, {\n indicies: this._createBuffer(),\n position: this._createBuffer(),\n uv: this._createBuffer()\n });\n\n if (nativeVAO) {\n this._bindNativeVAO(nativeVAO);\n this._supplyGeometryData(vao, shaderProgram);\n this._bindNativeVAO(null);\n this._unbindBuffers();\n }\n\n return vao;\n }\n\n public draw(vao: VertexArrayObject, shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n if (vao.obj) {\n this._bindNativeVAO(vao.obj);\n } else {\n this._supplyGeometryData(vao, shaderProgram);\n }\n\n gl.drawElements(gl.TRIANGLES, vao.count, gl.UNSIGNED_SHORT, 0);\n\n if (vao.obj) {\n this._bindNativeVAO(null);\n } else {\n this._unbindBuffers();\n }\n }\n\n public releaseVAO(vao: VertexArrayObject) {\n if (vao.obj) {\n this._deleteNativeVAO(vao.obj);\n }\n\n this._deleteBuffer(vao.buffers.indicies);\n this._deleteBuffer(vao.buffers.position);\n this._deleteBuffer(vao.buffers.uv);\n }\n\n public getUniformLocations>(program: WebGLProgram, uniforms: T): UniformLocations {\n const gl = this._gl;\n\n const uniformLocations = Object.keys(uniforms).reduce((locations, key) => {\n locations[key as keyof T] = gl.getUniformLocation(program, key)!;\n\n return locations;\n }, {} as UniformLocations);\n\n return {\n ...this._getCommonUniformLocations(program),\n ...uniformLocations\n };\n }\n\n public updateCommonUniforms(entity: Object3D, camera: Camera, shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniformLocations = shaderProgram.uniformLocations;\n\n // We're using \"matrix\"(=local matrix) here for efficiency\n // As projection doesn't require world matrix, as it doesn't have any parent or child\n const matrix = entity.matrix;\n const mvMatrix = mat4.create();\n mat4.multiply(mvMatrix, camera.viewMatrix, matrix);\n\n gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix);\n gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, camera.projectionMatrix);\n }\n\n public updateVRUniforms(shaderProgram: ShaderProgram, mvMatrix: mat4, pMatrix: mat4, eyeIndex: number) {\n const gl = this._gl;\n\n const uniformLocations = shaderProgram.uniformLocations;\n\n gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix);\n gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, pMatrix);\n\n if (uniformLocations.uEye) {\n gl.uniform1f(uniformLocations.uEye, eyeIndex);\n }\n }\n\n public updateUniforms(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniforms = shaderProgram.uniforms;\n const uniformLocations = shaderProgram.uniformLocations;\n\n for (const key in uniforms) {\n const uniform = uniforms[key];\n const location = uniformLocations[key];\n\n if (!uniform) continue;\n\n if (uniform.needsUpdate) {\n uniform.update(gl, location, this._isWebGL2);\n }\n }\n }\n\n public releaseShaderResources(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniforms = shaderProgram.uniforms;\n\n for (const key in uniforms) {\n const uniform = uniforms[key];\n\n if (!uniform) continue;\n\n if (uniform.needsUpdate) {\n uniform.destroy(gl);\n }\n }\n\n gl.deleteProgram(shaderProgram.program);\n }\n\n public useProgram(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n gl.useProgram(shaderProgram.program);\n }\n\n public createProgram(vertexShader: string, fragmentShader: string) {\n const gl = this._gl;\n const program = gl.createProgram()!;\n\n const vs = this._compileShader(gl.VERTEX_SHADER, vertexShader);\n const fs = this._compileShader(gl.FRAGMENT_SHADER, fragmentShader);\n\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.bindAttribLocation(program, 0, \"position\");\n gl.bindAttribLocation(program, 1, \"uv\");\n gl.linkProgram(program);\n\n if (this._debug && !gl.getProgramParameter(program, gl.LINK_STATUS)) {\n let shaderLog: string | null = null;\n\n if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {\n shaderLog = gl.getShaderInfoLog(vs);\n } else if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {\n shaderLog = gl.getShaderInfoLog(fs);\n }\n\n throw new View360Error(ERROR.MESSAGES.FAILED_LINKING_PROGRAM(gl.getProgramInfoLog(program), shaderLog), ERROR.CODES.FAILED_LINKING_PROGRAM);\n }\n\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n\n return program;\n }\n\n public createWebGLTexture(texData: Texture): WebGLTexture {\n const gl = this._gl;\n const texture = gl.createTexture()!;\n\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texData.wrapS);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texData.wrapT);\n\n if (!texData.isVideo() && this._isWebGL2) {\n const gl2 = gl as WebGL2RenderingContext;\n\n gl2.texStorage2D(gl2.TEXTURE_2D, 1, gl2.RGBA8, texData.width, texData.height);\n }\n\n return texture;\n }\n\n public createWebGLCubeTexture(texData: Texture, size: number): WebGLTexture {\n const gl = this._gl;\n const texture = gl.createTexture()!;\n\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, texData.wrapS);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, texData.wrapT);\n\n if (this._isWebGL2) {\n const gl2 = gl as WebGL2RenderingContext;\n\n gl2.texStorage2D(gl2.TEXTURE_CUBE_MAP, 1, gl2.RGBA8, size, size);\n }\n\n return texture;\n }\n\n public async makeXRCompatible() {\n const gl = this._gl;\n const attributes = gl.getContextAttributes();\n\n if (attributes && attributes.xrCompatible !== true) {\n await gl.makeXRCompatible();\n }\n }\n\n public bindXRLayer(session: XRSession) {\n const gl = this._gl;\n const xrLayer = new XRWebGLLayer(session, gl);\n session.updateRenderState({ baseLayer: xrLayer });\n }\n\n public bindXRFrame(frame: XRFrame) {\n const gl = this._gl;\n const session = frame.session;\n const baseLayer = session.renderState.baseLayer!;\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer);\n }\n\n public useDefaultFrameBuffer() {\n const gl = this._gl;\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n private _createBuffer(): WebGLBuffer {\n return this._gl.createBuffer()!;\n }\n\n private _deleteBuffer(buffer: WebGLBuffer) {\n return this._gl.deleteBuffer(buffer);\n }\n\n private _createNativeVAO() {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n return (gl as WebGL2RenderingContext).createVertexArray()!;\n } else {\n const ext = this._extensions.vao;\n\n return ext?.createVertexArrayOES() || null;\n }\n }\n\n private _bindNativeVAO(vao: WebGLVertexArrayObject | null) {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n (gl as WebGL2RenderingContext).bindVertexArray(vao);\n } else {\n const ext = this._extensions.vao;\n\n ext?.bindVertexArrayOES(vao);\n }\n }\n\n private _deleteNativeVAO(vao: WebGLVertexArrayObject | null) {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n (gl as WebGL2RenderingContext).deleteVertexArray(vao);\n } else {\n const ext = this._extensions.vao;\n\n ext?.deleteVertexArrayOES(vao);\n }\n }\n\n private _supplyGeometryData(vao: VertexArrayObject, shaderProgram: ShaderProgram) {\n const geometry = vao.geometry;\n\n this._supplyIndiciesData(geometry.indicies, vao.buffers.indicies);\n this._supplyAttributeData(geometry.vertices, shaderProgram.program, \"position\", vao.buffers.position);\n this._supplyAttributeData(geometry.uvs, shaderProgram.program, \"uv\", vao.buffers.uv);\n }\n\n private _unbindBuffers() {\n const gl = this._gl;\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n }\n\n private _supplyIndiciesData(indicies: VertexData, buffer: WebGLBuffer) {\n const gl = this._gl;\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicies.data, gl.STATIC_DRAW);\n }\n\n private _supplyAttributeData(attribute: VertexData, program: WebGLProgram, name: string, buffer: WebGLBuffer) {\n const gl = this._gl;\n const attribLocation = gl.getAttribLocation(program, name);\n\n // Attribute not used\n if (attribLocation < 0) return;\n\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ARRAY_BUFFER, attribute.data, gl.STATIC_DRAW);\n gl.vertexAttribPointer(attribLocation, attribute.itemSize, gl.FLOAT, false, 0, 0);\n gl.enableVertexAttribArray(attribLocation);\n }\n\n private _compileShader(type: number, src: string) {\n const gl = this._gl;\n const shader = gl.createShader(type)!;\n\n gl.shaderSource(shader, src);\n gl.compileShader(shader);\n\n return shader;\n }\n\n private _getCommonUniformLocations(program: WebGLProgram) {\n const gl = this._gl;\n\n return {\n uMVMatrix: gl.getUniformLocation(program, \"uMVMatrix\")!,\n uPMatrix: gl.getUniformLocation(program, \"uPMatrix\")!\n };\n }\n\n private _getContext(canvas: HTMLCanvasElement): {\n gl: WebGLRenderingContext | WebGL2RenderingContext;\n isWebGL2: boolean;\n } {\n const webglIdentifiers = [\"webgl2\", \"webgl\", \"experimental-webgl\", \"webkit-3d\", \"moz-webgl\"];\n let context: WebGLRenderingContext | null = null;\n let isWebGL2 = false;\n const contextAttributes = {\n preserveDrawingBuffer: false,\n antialias: false\n };\n\n const onWebglContextCreationError = e => e.statusMessage;\n\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_CREATE_ERROR, onWebglContextCreationError);\n\n for (const identifier of webglIdentifiers) {\n try {\n context = canvas.getContext(identifier, contextAttributes) as WebGLRenderingContext;\n isWebGL2 = identifier === \"webgl2\";\n } catch (t) {} // eslint-disable-line no-empty\n if (context) {\n break;\n }\n }\n\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_CREATE_ERROR, onWebglContextCreationError);\n\n if (!context) {\n throw new View360Error(ERROR.MESSAGES.WEBGL_NOT_SUPPORTED, ERROR.CODES.WEBGL_NOT_SUPPORTED);\n }\n\n return {\n gl: context,\n isWebGL2\n };\n }\n\n private _onContextLost = () => {\n const canvas = this._canvas;\n canvas.classList.add(DEFAULT_CLASS.CTX_LOST);\n this._contextLost = true;\n };\n\n private _onContextRestore = () => {\n const canvas = this._canvas;\n canvas.classList.remove(DEFAULT_CLASS.CTX_LOST);\n this._contextLost = false;\n };\n}\n\nexport default WebGLContext;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4 } from \"gl-matrix\";\nimport Camera from \"./Camera\";\nimport Projection from \"../projection/Projection\";\nimport WebGLContext from \"./WebGLContext\";\nimport XRManager from \"./XRManager\";\n\n/**\n * Projection renderer, based on WebGL\n * @ko WebGL 기반의 프로젝션 렌더러\n * @since 4.0.0\n */\nclass WebGLRenderer {\n private _canvas: HTMLCanvasElement;\n private _elementSize: { x: number, y: number };\n private _pixelRatio: number;\n\n public readonly ctx: WebGLContext;\n\n /**\n * Canvas element\n * @ko 캔버스 엘리먼트\n * @since 4.0.0\n */\n public get canvas() { return this._canvas; }\n /**\n * Canvas's width (`devicePixelRatio` is not applied)\n * @ko 캔버스의 보이는 너비 (`devicePixelRatio`가 적용되지 않은)\n * @since 4.0.0\n */\n public get width() { return this._elementSize.x; }\n /**\n * Canvas's height (`devicePixelRatio` is not applied)\n * @ko 캔버스의 높이 (`devicePixelRatio`가 적용되지 않은)\n * @since 4.0.0\n */\n public get height() { return this._elementSize.y; }\n /**\n * Current `devicePixelRatio` value.\n * @ko 현재 `devicePixelRatio` 값.\n * @since 4.0.0\n * @example\n * ```js\n * cosnt renderingWidth = view360.renderer.width * view360.renderer.pixelRatio;\n * ```\n */\n public get pixelRatio() { return this._pixelRatio; }\n /**\n * Width / height ratio (= width / height)\n * @ko 너비 / 높이의 비율 (= width / height)\n * @since 4.0.0\n * @example\n * ```js\n * const aspect = view360.renderer.width / view360.renderer.pixelRatio;\n * assert(aspect === view360.renderer.aspect);\n * ```\n */\n public get aspect() { return this._elementSize.x / this._elementSize.y; }\n\n /**\n * Create new instance\n * @ko 새 인스턴스를 생성합니다.\n * @param canvas - Canvas element {@ko 캔버스 엘리먼트}\n * @param debug - Whether to enable WebGL debugging {@ko WebGL debug 활성화 여부 }\n */\n public constructor(canvas: HTMLCanvasElement, debug: boolean) {\n this._canvas = canvas;\n this._elementSize = { x: 0, y: 0 };\n this._pixelRatio = 1;\n this.ctx = new WebGLContext(canvas, debug);\n }\n\n /**\n * Destroy instance and release all resources.\n * @ko 인스턴스를 제거하고 사용된 리소스를 전부 해제합니다.\n * @since 4.0.0\n */\n public destroy() {\n const canvas = this._canvas;\n\n this.ctx.destroy();\n canvas.width = 1;\n canvas.height = 1;\n }\n\n /**\n * Resize canvas and renew inner size cache.\n * @ko 캔버스의 크기를 재계산해서 내부의 사이즈 캐시값을 갱신합니다.\n * @since 4.0.0\n */\n public resize() {\n const canvas = this._canvas;\n const canvasSize = this._elementSize;\n const devicePixelRatio = window.devicePixelRatio;\n\n canvasSize.x = canvas.clientWidth;\n canvasSize.y = canvas.clientHeight;\n\n canvas.width = canvasSize.x * devicePixelRatio;\n canvas.height = canvasSize.y * devicePixelRatio;\n\n this._pixelRatio = devicePixelRatio;\n this.ctx.resize();\n }\n\n /**\n * Render projection\n * @ko 프로젝션을 렌더링합니다.\n * @param projection - Projection to render {@ko 렌더링할 프로젝션}\n * @param cameraa - Camera instance {@ko 카메라의 인스턴스}\n * @since 4.0.0\n */\n public render(projection: Projection, camera: Camera) {\n const ctx = this.ctx;\n const mesh = projection.getMesh();\n if (ctx.lost || !mesh) return;\n\n ctx.clear();\n ctx.useProgram(mesh.program);\n ctx.updateCommonUniforms(mesh, camera, mesh.program);\n projection.update(camera);\n ctx.updateUniforms(mesh.program);\n ctx.draw(mesh.vao, mesh.program);\n }\n\n /**\n * Render VR frame, only used for rendering frames inside VR sessions.\n * @ko VR 프레임을 렌더링합니다. VR 세션 진입 도중에만 사용됩니다.\n * @internal\n * @param projection - Projection to render {@ko 렌더링할 프로젝션}\n * @param vr - Instance of XRManager {@ko XRManager의 인스턴스}\n * @param frame - VR frame {@ko VR 프레임}\n * @since 4.0.0\n */\n public renderVR(projection: Projection, vr: XRManager, frame: XRFrame) {\n const ctx = this.ctx;\n const mesh = projection.getMesh();\n const eyeParams = vr.getEyeParams(frame);\n\n if (!eyeParams || !mesh) return;\n\n ctx.bindXRFrame(frame);\n ctx.useProgram(mesh.program);\n ctx.updateUniforms(mesh.program);\n\n eyeParams.forEach((eye, eyeIndex) => {\n const viewport = eye.viewport;\n // We're using \"mesh.matrix\"(=local matrix) here for efficiency\n // As projection doesn't require world matrix, as it doesn't have any parent or child\n const mvMatrix = mat4.multiply(mat4.create(), eye.vMatrix, mesh.matrix);\n\n ctx.viewport(viewport.x, viewport.y, viewport.width, viewport.height);\n ctx.updateVRUniforms(mesh.program, mvMatrix, eye.pMatrix, eyeIndex);\n ctx.draw(mesh.vao, mesh.program);\n });\n }\n}\n\nexport default WebGLRenderer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport Camera, { CameraOptions } from \"./core/Camera\";\nimport PanoControl, { PanoControlOptions } from \"./control/PanoControl\";\nimport TextureLoader from \"./core/TextureLoader\";\nimport FrameAnimator from \"./core/FrameAnimator\";\nimport AutoResizer from \"./core/AutoResizer\";\nimport Autoplay, { AutoplayOptions } from \"./core/Autoplay\";\nimport XRManager from \"./core/XRManager\";\nimport View360Error from \"./core/View360Error\";\nimport Projection from \"./projection/Projection\";\nimport HotspotRenderer, { HotspotOptions } from \"./hotspot/HotspotRenderer\";\nimport WebGLRenderer from \"./core/WebGLRenderer\";\nimport Texture from \"./texture/Texture\";\nimport View360Plugin from \"./plugin/View360Plugin\";\nimport ERROR from \"./const/error\";\nimport { CONTROL_EVENTS } from \"./const/internal\";\nimport { DEFAULT_CLASS, EVENTS } from \"./const/external\";\nimport { findCanvas, getElement } from \"./utils\";\nimport * as EVENT_TYPES from \"./type/events\";\nimport { EventParams } from \"./type/utils\";\n\n/**\n * Events that {@link View360} can trigger\n * @ko {@link View360}가 트리거할 수 있는 이벤트들\n * @see [Detailed Example](/docs/events/ready)\n * @since 4.0.0\n */\nexport interface View360Events {\n [EVENTS.READY]: EVENT_TYPES.ReadyEvent;\n [EVENTS.LOAD_START]: EVENT_TYPES.LoadStartEvent;\n [EVENTS.LOAD]: EVENT_TYPES.LoadEvent;\n [EVENTS.PROJECTION_CHANGE]: EVENT_TYPES.ProjectionChangeEvent;\n [EVENTS.RESIZE]: EVENT_TYPES.ResizeEvent;\n [EVENTS.BEFORE_RENDER]: EVENT_TYPES.BeforeRenderEvent;\n [EVENTS.RENDER]: EVENT_TYPES.RenderEvent;\n [EVENTS.INPUT_START]: EVENT_TYPES.InputStartEvent;\n [EVENTS.INPUT_END]: EVENT_TYPES.InputEndEvent;\n [EVENTS.VIEW_CHANGE]: EVENT_TYPES.ViewChangeEvent;\n [EVENTS.STATIC_CLICK]: EVENT_TYPES.StaticClickEvent;\n [EVENTS.VR_START]: EVENT_TYPES.VRStartEvent;\n [EVENTS.VR_END]: EVENT_TYPES.VREndEvent;\n}\n\n/**\n * Options for {@link View360}\n * @ko {@link View360}용 옵션들\n * @see [Detailed Example](/docs/options)\n * @since 4.0.0\n */\nexport interface View360Options extends CameraOptions, PanoControlOptions {\n projection: Projection | null;\n hotspot: Partial;\n autoplay: boolean | Partial;\n autoInit: boolean;\n autoResize: boolean;\n canvasSelector: string;\n useResizeObserver: boolean;\n tabIndex: number | null;\n on: Partial<{ [key in keyof View360Events]: (evt: View360Events[key]) => any }>;\n plugins: View360Plugin[];\n maxDeltaTime: number;\n debug: boolean;\n}\n\n/**\n * Panorama 360 image viewer\n * @ko 파노라마 360 이미지 뷰어\n * @since 4.0.0\n * @see View360Options\n * @see View360Events\n */\nclass View360 extends Component {\n /**\n * Current version string of the View360\n * @ko View360의 현재 버젼 문자열\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // If the installed version of the View360 is v4.0.0, View360.VERSION is equal to \"4.0.0\"\n * console.log(View360.VERSION) // 4.0.0\n * ```\n */\n public static readonly VERSION = \"#__VERSION__#\";\n\n private _rootEl: HTMLElement;\n private _renderer: WebGLRenderer;\n private _camera: Camera;\n private _control: PanoControl;\n private _animator: FrameAnimator;\n private _autoplay: Autoplay;\n private _hotspot: HotspotRenderer;\n private _projection: Projection | null;\n private _autoResizer: AutoResizer;\n private _vr: XRManager;\n private _plugins: View360Plugin[];\n private _initialized: boolean;\n\n private _autoInit: View360Options[\"autoInit\"];\n private _autoResize: View360Options[\"autoResize\"];\n private _canvasSelector: View360Options[\"canvasSelector\"];\n private _useResizeObserver: View360Options[\"useResizeObserver\"];\n private _tabIndex: View360Options[\"tabIndex\"];\n private _debug: View360Options[\"debug\"];\n\n /**\n * Root element (`.view360-container`)\n * @ko 루트 엘리먼트 (`.view360-container`)\n * @since 4.0.0\n * @readonly\n * @example\n * ```html\n *
\n * \n *
\n * ```\n * ```ts\n * import View360 from \"@egjs/view360\";\n *\n * const viewer = new View360(\"#viewer\");\n * console.log(viewer.rootEl); // Element with id \"viewer\"\n * ```\n */\n public get rootEl() { return this._rootEl; }\n /**\n * Projection renderer.\n * @ko 프로젝션 렌더러.\n * @since 4.0.0\n * @readonly\n */\n public get renderer() { return this._renderer; }\n /**\n * Projection camera.\n * @ko 프로젝션 카메라.\n * @since 4.0.0\n * @readonly\n */\n public get camera() { return this._camera; }\n /**\n * Rotate/Zoom Controller.\n * @ko 회전/줌 컨트롤러.\n * @since 4.0.0\n * @readonly\n */\n public get control() { return this._control; }\n /**\n * WebXR-based VR manager.\n * @ko WebXR 기반의 VR 기능 매니저 인스턴스.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // Example: Enter VR\n * // This must be called on user interaction, else will be rejected.\n * viewer.vr.enter();\n * ```\n */\n public get vr() { return this._vr; }\n /**\n * Hotspot renderer.\n * You can also change options of {@link View360Options#hotspot} with this.\n * @ko 핫스팟 렌더러 인스턴스.\n * {@link View360Options#hotspot} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get hotspot() { return this._hotspot; }\n /**\n * An array of plugins added.\n * @ko 추가된 플러그인의 배열\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * plugins: [new ControlBar()]\n * });\n *\n * console.log(viewer.plugins); // [ControlBar]\n *\n * viewer.addPlugins(new LoadingSpinner()) // [ControlBar, LoadingSpinner];\n * ```\n */\n public get plugins() { return this._plugins; }\n /**\n * A instance of {@link Projection} that currently enabled. `null` if not initialized yet.\n * You should call {@link View360#load} to change panorama src or projection type.\n * @ko 현재 사용중인 {@link Projection}의 인스턴스. 프로젝션을 활성화하지 않았을 경우 `null`입니다.\n * 파노라마 이미지 소스나 프로젝션 타입을 변경하려면 {@link View360#load}를 호출하면 됩니다.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360\n * ```\n */\n public get projection() { return this._projection; }\n public set projection(val: View360Options[\"projection\"]) {\n if (this._initialized && val) {\n this.load(val);\n } else {\n this._projection = val;\n }\n }\n /**\n * A boolean value whether {@link View360#init init()} is called before.\n * @ko {@link View360#init init()}이 호출되었는지 여부를 가리키는 값\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360(\"#el\", { autoInit: false });\n *\n * console.log(viewer.initialized); // false\n *\n * await viewer.init();\n *\n * console.log(viewer.initialized); // true\n * ```\n */\n public get initialized() { return this._initialized; }\n /**\n * Instance of the Autoplay manager.\n * You can also change {@link View360Options#autoplay} options with this.\n * @ko Autoplay 기능의 매니저 인스턴스.\n * 이 인스턴스를 통해 {@link View360Options#autoplay} 옵션을 변경하는 것도 가능합니다.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // Disable autoplay\n * viewer.autoplay.disable();\n * ```\n */\n public get autoplay() { return this._autoplay; }\n /**\n * When this value is `true` and {@link View360Options#projection} is set, {@link View360#init init()} will be called automatically when instance is created.\n * @ko 이 값이 `true`이고, {@link View360Options#projection}이 설정되었으면, 인스턴스 생성 시점에 자동으로 {@link View360#init init()}을 호출합니다.\n * @default true\n * @since 4.0.0\n * @example\n * ```ts\n * import View360, { EquirectProjection, EVENTS } from \"@egjs/view360\";\n *\n * // viewer.init() is called on instance creation\n * // But as `init` is asynchronous, you should wait for \"ready\" event if you want to do something after initialization.\n * const viewer = new View360(\"#el_id\", {\n * autoInit: true,\n * projection: new EquirectProjection({ src: \"SRC_TO_URL\" })\n * });\n *\n * console.log(viewer.initialized); // false, as `init` is asynchronous\n *\n * viewer.once(EVENTS.READY, () => {\n * console.log(viewer.initialized); // true\n * });\n * ```\n */\n public get autoInit() { return this._autoInit; }\n /**\n * When `true`, {@link View360#resize} is called when the canvas size is changed.\n * @ko `true`일 경우, 캔버스의 크기가 변경되었을 때 자동으로 {@link View360#resize}를 호출합니다.\n * @default true\n * @since 4.0.0\n * @see View360#useResizeObserver\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * autoResize: true\n * });\n *\n * // This can trigger `viewer.resize()` if the canvas size was not 400px\n * const canvas = viewer.renderer.canvas;\n * canvas.style.width = \"400px\";\n * ```\n */\n public get autoResize() { return this._autoResize; }\n /**\n * CSS selector for canvas element to render panorama image/video.\n * The canvas element should be placed inside the root element. (Dont' have to be direct child)\n * @ko 파노라마 이미지/비디오를 렌더링할 canvas 엘리먼트의 CSS 선택자\n * 캔버스 엘리먼트는 루트 엘리먼트 내부에 있어야합니다. 루트 엘리먼트의 직계 자식 엘리먼트(Direct child element)일 필요는 없습니다.\n * @default \"canvas\"\n * @since 4.0.0\n * @example\n * ```html\n *
\n * \n * \n * \n *
\n * ```\n *\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * canvasSelector: \"#canvas_to_select\"\n * });\n * ```\n */\n public get canvasSelector() { return this._canvasSelector; }\n /**\n * When `true`, it will use {@link ResizeObserver} API to detect canvas size change when {@link View360Options#autoResize} is enabled.\n * @ko `true`일 때 {@link View360Options#autoResize}가 활성화되었으면, 사용 가능한 환경에서 {@link ResizeObserver} API를 사용해서 캔버스 크기 변화를 추적합니다.\n * @default true\n * @since 4.0.0\n */\n public get useResizeObserver() { return this._useResizeObserver; }\n /**\n * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} attribute for the canvas element.\n * This is necessary for the keyboard controls.\n * By default, `0` will be assigned. `null` to disable.\n * @ko 캔버스 엘리먼트에 적용할 {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} 어트리뷰트의 값.\n * 이 값을 설정해야만 키보드 컨트롤을 사용 가능합니다.\n * 기본값으로 `0`이 설정됩니다. `null`로 지정하면 `tabindex`를 설정하지 않습니다.\n * @see RotateControlOptions#disableKeyboard\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * tabindex: 5\n * });\n * ```\n *\n * ```html\n * \n *
\n * \n *
\n * ```\n */\n public get tabIndex() { return this._tabIndex; }\n public set tabIndex(val: View360Options[\"tabIndex\"]) {\n const canvas = this._renderer.canvas;\n this._tabIndex = val;\n\n if (val != null) {\n canvas.tabIndex = val;\n } else {\n canvas.removeAttribute(\"tabindex\");\n }\n }\n /**\n * A maximum delta time between frames in seconds.\n * It can prevent camera or control changing too fast when frame being late.\n * @ko 프레임간 시간 차이의 최대값. (초 단위)\n * 퍼포먼스 등의 이유로 프레임 렌더링이 늦어졌을 때, 화면이 갑작스럽게 바뀌는 것을 막아줍니다.\n * @default 1 / 30\n * @since 4.0.0\n */\n public get maxDeltaTime() { return this._animator.maxDeltaTime; }\n public set maxDeltaTime(val: View360Options[\"maxDeltaTime\"]) { this._animator.maxDeltaTime = val; }\n /**\n * Enable WebGL debugging. Setting this to `true` can decrease performance.\n * This is used internally on developing View360.\n * @ko WebGL 디버깅을 활성화합니다. 이 값을 `true`로 할 경우 성능이 하락할 수 있습니다.\n * 이 옵션은 View360을 개발하기 위해 내부적으로 사용됩니다.\n * @default false\n */\n public get debug() { return this._debug; }\n public set debug(val: View360Options[\"debug\"]) { this._debug = val; }\n\n // Camera options\n /**\n * Initial yaw (y-axis rotation) value for camera. (in degrees, °)\n * As View360 uses right-handed coordinate system internally, camera will rotate counter-clockwise by this value.\n * @ko 카메라의 초기 yaw(y축 회전)값 (도 단위, °)\n * View360은 오른손 좌표계를 사용하기 때문에, 카메라가 해당 값만큼 시계 반대방향으로 회전합니다.\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialYaw: 30\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.yaw); // 30\n * });\n * ```\n */\n public get initialYaw() { return this._camera.initialYaw; }\n public set initialYaw(val: View360Options[\"initialYaw\"]) { this._camera.initialYaw = val; }\n /**\n * Initial pitch (x-axis rotation) value for camera. (in degrees, °)\n * As View360 uses right-handed coordinate system internally, positive value will make camera to look upside, while negative value will look down.\n * @ko 카메라의 초기 pitch(x축 회전)값 (도 단위, °)\n * View360은 오른손 좌표계를 사용하기 때문에, 양(+)의 값은 카메라가 위를 보게 하고, 음(-)의 값은 카메라가 아래를 보게 합니다.\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialPitch: 60\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.pitch); // 60\n * });\n * ```\n */\n public get initialPitch() { return this._camera.initialPitch; }\n public set initialPitch(val: View360Options[\"initialPitch\"]) { this._camera.initialPitch = val; }\n /**\n * Initial zoom value for camera.\n * Setting this value to `2` will enlarge panorama 200% by width.\n * @ko 카메라의 초기 줌 값.\n * 이 값을 `2`로 설정할 경우 파노라마 이미지를 가로 기준 200%만큼 확대합니다.\n * @default 1\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialZoom: 2\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.zoom); // 2\n * });\n * ```\n */\n public get initialZoom() { return this._camera.initialZoom; }\n public set initialZoom(val: View360Options[\"initialZoom\"]) { this._camera.initialZoom = val; }\n /**\n * Restrict yaw(y-axis rotation) range. (in degrees, °)\n * @ko yaw(y축 회전) 범위를 제한합니다. (도 단위, °)\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * yawRange: [-30, 30]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.yaw); // 0\n * viewer.camera.lookAt({ yaw: 60 });\n * console.log(viewer.camera.yaw); // 30\n * });\n * ```\n */\n public get yawRange() { return this._camera.yawRange; }\n public set yawRange(val: View360Options[\"yawRange\"]) {\n this._camera.yawRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Restrict pitch(x-axis rotation) range. (in degrees, °)\n * @ko pitch(x축 회전) 범위를 제한합니다. (도 단위, °)\n * @default null\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * pitchRange: [-45, 45]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.pitch); // 0\n * viewer.camera.lookAt({ pitch: 60 });\n * console.log(viewer.camera.pitch); // 45\n * });\n * ```\n */\n public get pitchRange() { return this._camera.pitchRange; }\n public set pitchRange(val: View360Options[\"pitchRange\"]) {\n this._camera.pitchRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Restrict camera zoom range.\n * If `null`, a default zoom range from `0.6` to `10` will be used.\n * @ko 카메라 줌 범위를 제한합니다.\n * `null`일 경우 기본값으로 `0.6`에서 `10`의 범위를 사용합니다.\n * @default null\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * zoomRange: [0.5, 4]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.zoom); // 1\n * viewer.camera.lookAt({ zoom: 6 });\n * console.log(viewer.camera.zoom); // 4\n * });\n * ```\n */\n public get zoomRange() { return this._camera.zoomRange; }\n public set zoomRange(val: View360Options[\"zoomRange\"]) {\n this._camera.zoomRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Camera's horizontal FOV(Field of View). (in degrees, °)\n * @ko 카메라의 수평 FOV(Field of View) 값. (도 단위, °)\n * @default 90\n * @since 4.0.0\n * @example\n * ```ts\n * // Init with fov: 120\n * const viewer = new View360(\"#el_id\", { fov: 120 });\n *\n * // Back to 90\n * viewer.fov = 90;\n * ```\n */\n public get fov() { return this._camera.fov; }\n public set fov(val: View360Options[\"fov\"]) {\n const camera = this._camera;\n const control = this._control;\n\n camera.fov = val;\n camera.updateMatrix();\n control.sync();\n }\n\n // Control options\n /**\n * A control for camera rotation.\n * You can also change options of {@link View360Options#rotate} with this.\n * @ko 카메라 회전을 담당하는 컨트롤.\n * {@link View360Options#rotate} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get rotate() { return this._control.rotate; }\n /**\n * A control for camera zoom.\n * You can also change options of {@link View360Options#zoom} with this.\n * @ko 카메라 줌을 담당하는 컨트롤.\n * {@link View360Options#zoom} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get zoom() { return this._control.zoom; }\n /**\n * A control for camera rotation with gyroscope input.\n * You can also change options of {@link View360Options#gyro} with this.\n * @ko 자이로스코프를 통한 카메라 회전을 담당하는 컨트롤.\n * {@link View360Options#gyro} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get gyro() { return this._control.gyro; }\n /**\n * Apply CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor} by current state of input when using mouse.\n * If `true`, this will add CSS style to canvas element. It'll apply `cursor: \"grab\"` by default and `cursor: \"grabbing\"` when holding the mouse button.\n * @ko 마우스 사용시 CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor}값을 자동으로 변경할지 여부.\n * `true`일 경우 기본 상태에서 `cursor: \"grab\"`을, 입력 도중에 `cursor: \"grabbing\"`을 캔버스에 적용합니다.\n * @default true\n * @since 4.0.0\n */\n public get useGrabCursor() { return this._control.useGrabCursor; }\n public set useGrabCursor(val: View360Options[\"useGrabCursor\"]) { this._control.useGrabCursor = val; }\n /**\n * Disable context menu which pops up on mouse right click.\n * @ko 마우스 우클릭시 표시되는 컨텍스트 메뉴를 비활성화합니다.\n * @default false\n * @since 4.0.0\n */\n public get disableContextMenu() { return this._control.disableContextMenu; }\n public set disableContextMenu(val: View360Options[\"disableContextMenu\"]) { this._control.disableContextMenu = val; }\n /**\n * If `true`, enables scroll on mobile(touch) devices on canvas.\n * :::caution\n * When this option is enabled, users must swipe horizontally first then vertically to change view up or down.\n * :::\n * @ko `true`로 설정할 경우, 모바일(터치) 환경의 캔버스 영역 내에서 스크롤을 가능하게 합니다.\n * :::caution\n * 이 값을 활성화할 경우, 사용자가 카메라 뷰를 위/아래로 바꾸기 위해서는 먼저 가로로 스와이프한 이후에 세로로 스와이프해야만 합니다.\n * :::\n * @since 4.0.0\n * @default true\n */\n public get scrollable() { return this._control.scrollable; }\n public set scrollable(val: View360Options[\"scrollable\"]) { this._control.scrollable = val; }\n /**\n * If `true`, enables scroll by mouse wheel on canvas.\n * :::caution\n * When this option is enabled, zoom by mouse wheel will be disabled.\n * :::\n * @ko `true`로 설정할 경우, 캔버스 영역 내에서 마우스 휠을 이용한 페이지 스크롤이 가능해집니다.\n * :::caution\n * 이 값을 활성화할 경우, 마우스 휠을 통한 줌이 불가능하게 됩니다.\n * :::\n * @since 4.0.0\n * @default false\n */\n public get wheelScrollable() { return this._control.wheelScrollable; }\n public set wheelScrollable(val: View360Options[\"wheelScrollable\"]) { this._control.wheelScrollable = val; }\n\n /**\n * Create new instance of View360\n * @ko View360의 새로운 인스턴스를 생성합니다\n * @param root - Root element(`.view360-container`) to mount View360\n * Can be either a CSS selector or HTMLElement.\n * {@ko View360을 마운트할 루트 엘리먼트, CSS 셀렉터나 HTMLElement를 지정 가능합니다.}\n * @param options - Options to apply\n * {@ko 적용할 옵션들}\n * @example\n * ```ts\n * import View360, { EquirectProjection } from \"@egjs/view360\";\n *\n * // Create new View360 instance\n * const viewer = new View360(\"#id-of-a-container\", {\n * projection: new EquirectProjection({\n * src: \"URL_TO_PANORAMA_IMAGE_OR_VIDEO\",\n * })\n * });\n * ```\n */\n public constructor(root: string | HTMLElement, {\n projection = null,\n initialYaw = 0,\n initialPitch = 0,\n initialZoom = 1,\n yawRange = null,\n pitchRange = null,\n zoomRange = null,\n fov = 90,\n useGrabCursor = true,\n disableContextMenu = false,\n rotate = true,\n zoom = true,\n gyro = false,\n scrollable = true,\n wheelScrollable = false,\n autoplay = false,\n hotspot = {},\n autoInit = true,\n autoResize = true,\n canvasSelector = \"canvas\",\n useResizeObserver = true,\n on = {},\n plugins = [],\n maxDeltaTime = 1 / 30,\n tabIndex = 0,\n debug = false\n }: Partial = {}) {\n super();\n\n this._rootEl = getElement(root);\n this._plugins = plugins;\n this._initialized = false;\n\n // Options\n this._autoInit = autoInit;\n this._autoResize = autoResize;\n this._canvasSelector = canvasSelector;\n this._useResizeObserver = useResizeObserver;\n this._tabIndex = tabIndex;\n this._debug = debug;\n\n // Core components\n const canvas = findCanvas(this._rootEl, canvasSelector);\n this._renderer = new WebGLRenderer(canvas, debug);\n this._camera = new Camera({\n initialYaw,\n initialPitch,\n initialZoom,\n fov,\n yawRange,\n pitchRange,\n zoomRange\n });\n this._control = new PanoControl(canvas, this._camera, {\n useGrabCursor,\n scrollable,\n wheelScrollable,\n disableContextMenu,\n rotate,\n zoom,\n gyro\n });\n this._animator = new FrameAnimator(maxDeltaTime);\n this._autoplay = new Autoplay(this, canvas, autoplay);\n this._projection = projection;\n this._autoResizer = new AutoResizer(useResizeObserver, () => this.resize());\n this._vr = new XRManager(this._renderer.ctx);\n this._hotspot = new HotspotRenderer(this._rootEl, this._renderer, hotspot);\n\n this._addEventHandlers(on);\n\n if (projection && autoInit) {\n this.init();\n }\n }\n\n /**\n * Destroy instance and release all resources.\n * @ko 인스턴스를 제거하고 모든 리소스를 해제합니다.\n * @since 4.0.0\n */\n public destroy() {\n this._camera.destroy();\n this._animator.stop();\n this._renderer.destroy();\n this._control.destroy();\n this._autoResizer.disable();\n\n if (this._projection) {\n this._projection.releaseAllResources(this._renderer.ctx);\n this._projection = null;\n }\n\n this._plugins.forEach(plugin => plugin.destroy(this));\n\n this._initialized = false;\n }\n\n /**\n * Initialize inner components and load projection src.\n * @ko 내부 컴포넌트들을 초기화하고 프로젝션 소스를 로드합니다.\n * @since 4.0.0\n */\n public async init() {\n if (!this._projection) {\n throw new View360Error(ERROR.MESSAGES.PROVIDE_PROJECTION_FIRST, ERROR.CODES.PROVIDE_PROJECTION_FIRST);\n }\n\n const renderer = this._renderer;\n const camera = this._camera;\n const control = this._control;\n const animator = this._animator;\n const hotspot = this._hotspot;\n const projection = this._projection;\n const canvas = renderer.canvas;\n\n this._bindComponentEvents();\n renderer.ctx.init();\n this._resizeComponents();\n camera.updateMatrix();\n\n if (this._autoResize) {\n this._autoResizer.enable(canvas);\n }\n\n if (!this._autoplay.enableBlocked) {\n this._autoplay.enable();\n }\n\n this._plugins.forEach(plugin => {\n plugin.init(this);\n });\n\n const texture = await this._loadTexture(projection);\n this._applyProjection(projection, texture, null);\n hotspot.refresh();\n animator.start(this._renderFrameOnDemand);\n await control.enable();\n\n if (this._tabIndex != null && !canvas.hasAttribute(\"tabIndex\")) {\n canvas.tabIndex = this._tabIndex;\n }\n\n this._initialized = true;\n this.renderFrame(0);\n\n this._emit(EVENTS.READY);\n }\n\n /**\n * Load new panorama image/video and display it.\n * This will {@link View360#init init()} View360 if it's not initialized yet.\n * @ko 새로운 파노라마 이미지 혹은 비디오를 로드하고 표시합니다.\n * 만약 View360이 아직 초기화되지 않았다면, {@link View360#init init()}을 호출합니다.\n * @param projection - Projection & video options for new source. {@ko 새로운 파노라마 이미지/비디오에 적용할 옵션들}\n * @returns `Promise` if load was successful. {@ko 프로젝션 로드에 성공했을 경우 `Promise`를 반환합니다. }\n * @since 4.0.0\n * @example\n * ```ts\n * // Change to video\n * viewer.load({\n * src: \"URL_TO_NEW_VIDEO\",\n * video: true\n * });\n * ```\n */\n public async load(projection: Projection): Promise {\n if (!projection) return false;\n\n if (this._initialized) {\n const texture = await this._loadTexture(projection);\n this._applyProjection(projection, texture, this._projection);\n this.renderFrame(0);\n } else {\n // Should update internal options before init\n this._projection = projection;\n this.init();\n }\n\n return true;\n }\n\n /**\n * Refresh component's size by current\n * @ko View360이 내부적으로 캐시하고 있는 엘리먼트 크기를 현재 크기로 갱신합니다.\n * @since 4.0.0\n */\n public resize() {\n if (!this._initialized) return;\n\n this._resizeComponents();\n\n // To prevent flickering, render immediately after resizing components\n this.renderFrame(0);\n\n const { width, height } = this._renderer;\n\n this._emit(EVENTS.RESIZE, {\n width,\n height\n });\n }\n\n /**\n * Add new plugins\n * @ko 새로운 플러그인을 추가합니다.\n * @param plugins Plugins to add {@ko 추가할 플러그인들}\n * @see View360Options#plugins\n * @since 4.0.0\n * @example\n * ```ts\n * // Add a single plugin\n * viewer.addPlugins(new ControlBar());\n *\n * // Add multiple plugins\n * viewer.addPlugins(new ControlBar(), new LoadingSpinner());\n * ```\n */\n public addPlugins(...plugins: View360Plugin[]) {\n if (this._initialized) {\n plugins.forEach(plugin => { plugin.init(this); });\n }\n\n this._plugins.push(...plugins);\n }\n\n /**\n * Remove plugins.\n * @ko 플러그인을 제거합니다.\n * @param plugins Plugins to remove {@ko 제거할 플러그인들}\n * @since 4.0.0\n * @example\n * ```ts\n * // Remove a single plugin\n * viewer.removePlugins(plugin1);\n *\n * // Remove multiple plugins\n * viewer.removePlugins(plugin2, plugin3);\n * ```\n */\n public removePlugins(...plugins: View360Plugin[]) {\n plugins.forEach(plugin => {\n const pluginIdx = this._plugins.indexOf(plugin);\n\n if (pluginIdx < 0) return;\n\n plugin.destroy(this);\n this._plugins.splice(pluginIdx, 1);\n });\n }\n\n /**\n * Render a single panorama image/video frame.\n * Rendering is performed automatically on demand, so you usually don't have to call this.\n * Call this when a frame is not renewed after changing options.\n * @ko 파노라마 이미지/비디오의 한 프레임을 렌더링합니다.\n * 프레임 갱신은 보통 필요한 때에만 자동적으로 이루어지기 때문에, 보통은 이 메소드를 호출할 필요는 없습니다.\n * 옵션 변경 이후에도 프레임 갱신이 이루어지지 않는다면, 이 메소드를 호출해주세요.\n * @param delta Delta time in milisec. {@ko 프레임간 시간 차이, 밀리초 단위}\n * @since 4.0.0\n */\n public renderFrame = (delta: number) => {\n const camera = this._camera;\n const renderer = this._renderer;\n const control = this._control;\n const hotspot = this._hotspot;\n const autoPlayer = this._autoplay;\n const projection = this._projection;\n\n if (!projection) return;\n\n this._emit(EVENTS.BEFORE_RENDER);\n\n if (autoPlayer.playing) {\n autoPlayer.update(delta);\n control.sync();\n }\n\n if (camera.animation) {\n camera.animation.update(delta);\n } else {\n control.update(delta);\n }\n\n renderer.render(projection, camera);\n hotspot.render(camera);\n\n if (camera.changed) {\n this._emit(EVENTS.VIEW_CHANGE, {\n yaw: camera.yaw,\n pitch: camera.pitch,\n zoom: camera.zoom,\n quaternion: [\n camera.quaternion[0],\n camera.quaternion[1],\n camera.quaternion[2],\n camera.quaternion[3]\n ]\n });\n }\n camera.onFrameRender();\n\n this._emit(EVENTS.RENDER);\n };\n\n private _emit(eventName: K, ...params: EventParams) {\n const evtParams = params ? params[0] : {};\n\n this.trigger(eventName as any, {\n type: eventName,\n target: this,\n ...evtParams\n });\n }\n\n private _renderFrameOnDemand = (delta: number) => {\n const camera = this._camera;\n const control = this._control;\n const autoplay = this._autoplay;\n const texture = this._projection?.getTexture();\n\n if (!this._initialized || !texture) return;\n if (\n !camera.animation\n && !control.animating\n && !autoplay.playing\n && !texture.isVideo()\n ) return;\n\n this.renderFrame(delta);\n };\n\n private _renderVRFrame = (_delta: number, frame: XRFrame) => {\n const vr = this._vr;\n const projection = this._projection;\n const renderer = this._renderer;\n\n if (!projection) return;\n\n this._emit(EVENTS.BEFORE_RENDER);\n\n renderer.renderVR(projection, vr, frame);\n\n this._emit(EVENTS.RENDER);\n }\n\n private _applyProjection(projection: Projection, texture: Texture, prevProjection: Projection | null) {\n const camera = this._camera;\n const control = this._control;\n const renderer = this._renderer;\n\n // Remove previous projection\n if (prevProjection) {\n prevProjection.releaseAllResources(this._renderer.ctx);\n }\n\n projection.applyTexture(renderer.ctx, texture);\n projection.updateCamera(camera);\n projection.updateControl(control);\n\n this._projection = projection;\n this._emit(EVENTS.PROJECTION_CHANGE, {\n projection\n });\n }\n\n private async _loadTexture(projection: Projection): Promise {\n const contentLoader = new TextureLoader();\n const { src, video } = projection;\n\n this._emit(EVENTS.LOAD_START, {\n src,\n video\n });\n\n const texture = await contentLoader.load(src, video);\n\n this._emit(EVENTS.LOAD, {\n src,\n video\n });\n\n return texture;\n }\n\n private _resizeComponents() {\n const renderer = this._renderer;\n const camera = this._camera;\n const control = this._control;\n\n renderer.resize();\n camera.resize(renderer.width, renderer.height);\n control.resize(renderer.width, renderer.height);\n }\n\n private _addEventHandlers(events: View360Options[\"on\"]) {\n // Bind option \"on\"\n Object.keys(events).forEach((evtName: keyof typeof EVENT_TYPES) => {\n this.on(evtName, events[evtName]);\n });\n }\n\n private _bindComponentEvents() {\n // Bind internal component events\n const root = this._rootEl;\n const control = this._control;\n const animator = this._animator;\n const renderer = this._renderer;\n const vr = this._vr;\n\n const controlEventsToPropagate = [\n CONTROL_EVENTS.STATIC_CLICK,\n CONTROL_EVENTS.INPUT_START,\n CONTROL_EVENTS.INPUT_END\n ];\n\n controlEventsToPropagate.forEach(evtName => {\n control.rotate.on(evtName, evt => {\n this._emit(evtName, evt);\n });\n\n control.zoom.on(evtName, evt => {\n this._emit(evtName, evt);\n });\n });\n\n vr.on(EVENTS.VR_START, evt => {\n root.classList.add(DEFAULT_CLASS.IN_VR);\n\n animator.changeContext(evt.session);\n animator.start(this._renderVRFrame);\n\n this._emit(EVENTS.VR_START);\n });\n\n vr.on(EVENTS.VR_END, () => {\n root.classList.remove(DEFAULT_CLASS.IN_VR);\n\n renderer.ctx.useDefaultFrameBuffer();\n animator.changeContext(window);\n animator.start(this._renderFrameOnDemand);\n\n this.resize();\n\n this._emit(EVENTS.VR_END);\n });\n }\n}\n\nexport default View360;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4, quat, vec3 } from \"gl-matrix\";\n\n/**\n * Base class for 3D objects\n * @ko 3D 오브젝트의 베이스 클래스\n * @since 4.0.0\n * @internal\n */\nclass Object3D {\n /**\n * Local matrix of the object\n * @ko 오브젝트의 local matrix\n * @since 4.0.0\n */\n public matrix: mat4;\n /**\n * Rotation quaternion\n * @ko 현재 오브젝트의 회전을 나타내는 사원수 값\n * @since 4.0.0\n */\n public rotation: quat;\n /**\n * Position of the object\n * @ko 오브젝트의 위치\n * @since 4.0.0\n */\n public position: vec3;\n /**\n * A scale vector of the object\n * @ko 오브젝트가 각 축으로 확대된 정도를 나타내는 벡터\n * @since 4.0.0\n */\n public scale: vec3;\n\n /**\n * Create new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n */\n public constructor() {\n this.matrix = mat4.create();\n this.rotation = quat.create();\n this.position = vec3.fromValues(0, 0, 0);\n this.scale = vec3.fromValues(1, 1, 1);\n }\n\n /**\n * Update local matrix of the object.\n * @ko 오브젝트의 local matrix를 갱신합니다.\n * @since 4.0.0\n */\n public updateMatrix() {\n mat4.fromRotationTranslationScale(this.matrix, this.rotation, this.position, this.scale);\n }\n}\n\nexport default Object3D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360Plugin from \"../View360Plugin\";\nimport View360 from \"../../View360\";\nimport { EVENTS } from \"../../const/external\";\nimport { createElement } from \"../../utils\";\nimport { LoadStartEvent } from \"../../type/events\";\n\n/**\n * Options for {@link LoadingSpinner}\n * @ko {@link LoadingSpinner}용 옵션들\n * @since 4.0.0\n * @category Plugin\n */\nexport interface LoadingSpinnerOptions {\n /**\n * Override default class names.\n * @ko 디폴트 클래스 이름들을 오버라이드합니다.\n * @since 4.0.0\n */\n className: Partial<{ -readonly [key in keyof typeof LoadingSpinner.DEFAULT_CLASS]: string }>;\n}\n\n/**\n * A plugin that displays loading spinner while loading the projection.\n * @ko 프로젝션 로딩중에 로딩 스피너를 보여주는 플러그인\n * @since 4.0.0\n * @category Plugin\n */\nclass LoadingSpinner implements View360Plugin {\n /**\n * Default class names that LoadingSpinner uses\n * @ko LoadingSpinner가 사용하는 디폴트 클래스 이름\n * @since 4.0.0\n */\n public static readonly DEFAULT_CLASS = {\n /**\n * A class name for the container element\n * @ko 컨테이너 엘리먼트의 클래스 이름\n * @since 4.0.0\n */\n CONTAINER: \"view360-spinner\",\n /**\n * A class name for the spinning ring element\n * @ko 돌아가는 링 엘리먼트의 클래스 이름\n * @since 4.0.0\n */\n RING: \"view360-spinner-ring\"\n } as const;\n\n /**\n * A class names overriding\n * @ko 현재 오버라이드 중인 클래스 이름\n * @since 4.0.0\n */\n public readonly className: LoadingSpinnerOptions[\"className\"];\n\n private _container: HTMLElement;\n\n /**\n * Create a new instance of LoadingSpinner. {@ko LoadingSpinner의 새 인스턴스를 생성합니다.}\n * @param options Options {@ko 옵션들}\n */\n public constructor({\n className = {}\n }: Partial = {}) {\n this.className = className;\n this._container = this._createElements();\n }\n\n public init(viewer: View360) {\n viewer.on(EVENTS.LOAD_START, this._startLoading);\n }\n\n public destroy(viewer: View360): void {\n viewer.off(EVENTS.LOAD_START, this._startLoading);\n this._detachElements({ target: viewer });\n }\n\n private _startLoading = ({ target: viewer }: LoadStartEvent) => {\n viewer.rootEl.appendChild(this._container);\n\n if (viewer.initialized) {\n viewer.once(EVENTS.LOAD, this._detachElements);\n } else {\n viewer.once(EVENTS.READY, this._detachElements);\n }\n };\n\n private _detachElements = ({ target: viewer }: { target: View360 }) => {\n const container = this._container;\n if (!container) return;\n\n if (container.parentElement === viewer.rootEl) {\n viewer.rootEl.removeChild(container);\n }\n };\n\n private _createElements() {\n const className = {\n ...this.className,\n ...LoadingSpinner.DEFAULT_CLASS\n };\n\n const container = createElement(className.CONTAINER);\n const ring = createElement(className.RING);\n\n container.appendChild(ring);\n\n return container;\n }\n}\n\nexport default LoadingSpinner;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n/* eslint-disable @typescript-eslint/no-empty-function */\n/* eslint-disable @typescript-eslint/no-unused-vars */\nimport ControlBar from \"./ControlBar\";\nimport View360 from \"../../View360\";\n\n/**\n * Common options for {@link ControlBarItem}\n * @ko {@link ControlBarItem}의 공통 옵션들\n * @category Plugin\n * @since 4.0.0\n */\nexport interface ControlBarItemOptions {\n /**\n * @copy ControlBarItem#position\n */\n position: typeof ControlBar.POSITION[keyof typeof ControlBar.POSITION];\n /**\n * @copy ControlBarItem#order\n */\n order: number;\n}\n\n/**\n * Interface of the ControlBar items\n * @ko 컨트롤바 아이템의 인터페이스\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nabstract class ControlBarItem {\n /**\n * Element of the item.\n * @ko 아이템의 엘리먼트\n * @since 4.0.0\n */\n public abstract element: HTMLElement;\n\n /**\n * Position to display item.\n * @ko 아이템을 표시할 위치.\n * @since 4.0.0\n */\n public position: ControlBarItemOptions[\"position\"];\n /**\n * Order within the same position.\n * The lowest one will be shown first.\n * @ko 동일한 position 내에서의 순서, 작을수록 먼저 표시됩니다.\n * @since 4.0.0\n */\n public order: ControlBarItemOptions[\"order\"];\n\n /**\n * Create new instance of the ControlBarItem\n * @ko ControlBarItem의 새로운 인스턴스를 생성합니다.\n * @param options Options {@ko 옵션들}\n */\n public constructor(options: ControlBarItemOptions) {\n this.position = options.position;\n this.order = options.order;\n }\n\n /**\n * Initialize item.\n * @ko 아이템을 초기화합니다.\n * @param viewer - A instance of viewer to attach item {@ko 아이템을 부착할 뷰어의 인스턴스}\n * @param controlBar - A instance of control bar to attach item {@ko 아이템을 부착할 컨트롤바의 인스턴스}\n * @since 4.0.0\n */\n public abstract init(viewer: View360, controlBar: ControlBar): any;\n /**\n * Destroy item and release all resources & event handlers.\n * @ko 아이템을 제거하고 할당된 모든 리소스 및 이벤트 핸들러를 제거합니다.\n * @param viewer - A instance of viewer to detach item {@ko 아이템을 떼어 낼 뷰어의 인스턴스}\n * @param controlBar - A instance of control bar to detach item {@ko 아이템을 떼어 낼 컨트롤바의 인스턴스}\n * @since 4.0.0\n */\n public abstract destroy(viewer: View360, controlBar: ControlBar): any;\n}\n\nexport default ControlBarItem;\n","export const CONTROL_BAR_DEFAULT_CLASS = {\n CONTROLS_ROOT: \"view360-controls\",\n CONTROLS_BG: \"view360-controls-background\",\n CONTROLS_MAIN: \"view360-controls-main\",\n CONTROLS_TOP: \"view360-controls-top\",\n CONTROLS_BOTTOM: \"view360-controls-bottom\",\n CONTROLS_MID: \"view360-controls-mid\",\n CONTROLS_LEFT: \"view360-controls-left\",\n CONTROLS_RIGHT: \"view360-controls-right\",\n CONTROLS_FLOAT_LEFT: \"view360-controls-float-left\",\n CONTROLS_FLOAT_RIGHT: \"view360-controls-float-right\",\n CONTROLS_BUTTON: \"view360-controls-button\",\n PROGRESS_ROOT: \"view360-controls-progress\",\n VOLUME_ROOT: \"view360-controls-volume\",\n RANGE_ROOT: \"view360-range\",\n RANGE_TRACK: \"view360-range-track\",\n RANGE_THUMB: \"view360-range-thumb\",\n RANGE_FILLER: \"view360-range-filler\",\n PLAY_BUTTON: \"view360-controls-play\",\n PAUSE_BUTTON: \"view360-controls-pause\",\n UNMUTED_BUTTON: \"view360-controls-unmuted\",\n MUTED_BUTTON: \"view360-controls-muted\",\n FULLSCREEN_BUTTON: \"view360-controls-fullscreen\",\n FULLSCREEN_EXIT_BUTTON: \"view360-controls-fullscreen-exit\",\n VR_BUTTON: \"view360-controls-vr\",\n GYRO_ENABLED: \"view360-controls-gyro-enabled\",\n GYRO_DISABLED: \"view360-controls-gyro-disabled\",\n VIDEO_TIME_DISPLAY: \"view360-controls-time\",\n PIEVIEW_ROOT: \"view360-controls-pie\",\n FIXED: \"view360-controls-fixed\",\n UNAVAILABLE: \"view360-controls-unavailable\",\n HIDDEN: \"view360-controls-hidden\"\n} as const;\n\nexport const CONTROL_BAR_ITEM_POSITION = {\n /**\n * Place control bar item floating at top-left corner\n * @ko 아이템을 왼쪽 위 구석에 표시합니다.\n * @since 4.0.0\n */\n TOP_LEFT: \"top-left\",\n /**\n * Place control bar item floating at top-right corner\n * @ko 아이템을 오른쪽 위 구석에 표시합니다.\n * @since 4.0.0\n */\n TOP_RIGHT: \"top-right\",\n /**\n * Place control bar item at upper block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 위쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_TOP: \"main-top\",\n /**\n * Place control bar item at lower block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 하단 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_BOTTOM: \"main-bottom\",\n /**\n * Place control bar item at center-left block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 왼쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_LEFT: \"main-left\",\n /**\n * Place control bar item at center-right block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 오른쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_RIGHT: \"main-right\"\n} as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { ControlBarOptions } from \"./ControlBar\";\nimport { CONTROL_BAR_DEFAULT_CLASS } from \"./const\";\nimport Motion from \"../../core/Motion\";\nimport MouseInput from \"../../control/input/MouseInput\";\nimport TouchInput from \"../../control/input/TouchInput\";\nimport { CONTROL_EVENTS, INFINITE_RANGE } from \"../../const/internal\";\nimport { clamp } from \"../../utils\";\nimport { InputEvents } from \"../../type/internal\";\nimport { EL_DIV } from \"../../const/browser\";\n\nclass RangeControl extends Component<{\n [CONTROL_EVENTS.INPUT_START]: number;\n [CONTROL_EVENTS.CHANGE]: number;\n [CONTROL_EVENTS.INPUT_END]: void;\n}> {\n public readonly rootEl: HTMLElement;\n public readonly thumbEl: HTMLElement;\n public readonly trackEl: HTMLElement;\n public readonly fillerEl: HTMLElement;\n\n private _motion: Motion;\n private _mouseInput: MouseInput;\n private _touchInput: TouchInput;\n private _fixedClass: string;\n private _bbox: DOMRect;\n\n /**\n *\n */\n public constructor() {\n super();\n\n const root = document.createElement(EL_DIV);\n const track = document.createElement(EL_DIV);\n const thumb = document.createElement(EL_DIV);\n const filler = document.createElement(EL_DIV);\n\n root.draggable = false;\n\n track.appendChild(filler);\n track.appendChild(thumb);\n root.appendChild(track);\n\n this.rootEl = root;\n this.trackEl = track;\n this.thumbEl = thumb;\n this.fillerEl = filler;\n\n this._mouseInput = new MouseInput();\n this._touchInput = new TouchInput();\n this._motion = new Motion({ duration: 1, range: INFINITE_RANGE, easing: x => x });\n this._bbox = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n left: 0,\n right: 0,\n bottom: 0,\n top: 0\n } as DOMRect;\n this._fixedClass = CONTROL_BAR_DEFAULT_CLASS.FIXED;\n }\n\n public init(className: Required) {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n\n this.rootEl.classList.add(className.RANGE_ROOT);\n this.trackEl.classList.add(className.RANGE_TRACK);\n this.thumbEl.classList.add(className.RANGE_THUMB);\n this.fillerEl.classList.add(className.RANGE_FILLER);\n this._fixedClass = className.FIXED;\n\n mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n touchInput.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n\n mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n touchInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n\n mouseInput.enable(this.rootEl);\n touchInput.enable(this.rootEl);\n\n this.resize();\n }\n\n public destroy() {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n\n this.rootEl.className = \"\";\n this.trackEl.className = \"\";\n this.thumbEl.className = \"\";\n this.fillerEl.className = \"\";\n\n mouseInput.off();\n touchInput.off();\n mouseInput.disable();\n touchInput.disable();\n }\n\n public resize() {\n this._bbox = this.trackEl.getBoundingClientRect();\n }\n\n public updateStyle(progress: number) {\n const width = this._bbox.width;\n const clampedProgress = clamp(progress, 0, 1);\n\n this.fillerEl.style.width = `${clampedProgress * 100}%`;\n this.thumbEl.style.transform = `translateX(${clampedProgress * width}px)`;\n }\n\n private _onHold = ({ srcEvent, isTouch }: InputEvents<{ x: number; y: number }>[typeof CONTROL_EVENTS.INPUT_START]) => {\n const bbox = this._bbox;\n if (!bbox) return;\n\n const x = isTouch\n ? (srcEvent as TouchEvent).touches[0].pageX\n : (srcEvent as MouseEvent).pageX;\n const elX = bbox.x + (window.scrollX ?? window.pageXOffset);\n\n const clamepdX = clamp(x, elX, elX + bbox.width);\n const progress = (clamepdX - elX) / bbox.width;\n\n this._motion.reset(clamepdX);\n this.thumbEl.classList.add(this._fixedClass);\n\n this.trigger(CONTROL_EVENTS.INPUT_START, progress);\n };\n\n private _onChange = ({ delta }: InputEvents<{ x: number; y: number }>[typeof CONTROL_EVENTS.CHANGE]) => {\n const motion = this._motion;\n const bbox = this._bbox;\n if (!bbox) return;\n\n motion.setNewEndByDelta(delta.x);\n motion.update(1);\n\n const elX = bbox.x + (window.scrollX ?? window.pageXOffset);\n const clampedX = clamp(motion.val, elX, elX + bbox.width);\n const progress = (clampedX - elX) / bbox.width;\n\n this.trigger(CONTROL_EVENTS.CHANGE, progress);\n };\n\n private _onRelease = () => {\n const bbox = this._bbox;\n if (!bbox) return;\n\n this.thumbEl.classList.remove(this._fixedClass);\n\n this.trigger(CONTROL_EVENTS.INPUT_END);\n };\n}\n\nexport default RangeControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport RangeControl from \"./RangeControl\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport { CONTROL_EVENTS, VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport { EVENTS } from \"../../const/external\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show video progress bar.\n * @ko 비디오의 프로그레스 바를 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass ProgressBar extends ControlBarItem {\n public get element() { return this._rangeControl.rootEl; }\n\n private _controlBar: ControlBar | null;\n private _video: TextureVideo | null;\n private _rangeControl: RangeControl;\n\n private _wasPaused: boolean;\n private _currentTime: number;\n private _duration: number;\n private _playPromise: Promise | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_TOP,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.position = position;\n this.order = order;\n\n this._controlBar = null;\n this._rangeControl = new RangeControl();\n\n this._video = null;\n this._wasPaused = false;\n this._currentTime = 0;\n this._duration = 0;\n this._playPromise = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const element = this.element;\n const rangeControl = this._rangeControl;\n const unavailableClass = controlBar.className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n element.classList.add(unavailableClass);\n return;\n }\n\n element.classList.remove(unavailableClass);\n element.classList.add(controlBar.className.PROGRESS_ROOT);\n viewer.on(EVENTS.RESIZE, this._onResize);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate);\n rangeControl.init(controlBar.className);\n rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n rangeControl.on(CONTROL_EVENTS.CHANGE, this._onControl);\n rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n this._video = video;\n this._currentTime = video.source.currentTime;\n this._duration = video.source.duration;\n this._controlBar = controlBar;\n\n rangeControl.updateStyle(this._currentTime / this._duration);\n }\n\n public destroy(viewer: View360) {\n const video = this._video;\n\n viewer.off(EVENTS.RESIZE, this._onResize);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate);\n }\n\n this._rangeControl.destroy();\n this._video = null;\n this._playPromise = null;\n }\n\n private _onResize = () => {\n this._rangeControl.resize();\n }\n\n private _onTimeUpdate = () => {\n const video = this._video;\n if (!video) return;\n\n this._currentTime = video.source.currentTime;\n this._rangeControl.updateStyle(this._currentTime / this._duration);\n };\n\n private _onDurationChange = () => {\n const video = this._video;\n if (!video) return;\n\n this._duration = video.source.duration;\n this._rangeControl.updateStyle(this._currentTime / this._duration);\n };\n\n private _onHold = (progress: number) => {\n const video = this._video;\n const controlBar = this._controlBar;\n if (!video || !controlBar) return;\n\n const paused = video.isPaused();\n\n video.source.pause();\n\n const time = video.source.duration * progress;\n video.source.currentTime = time;\n video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time }}));\n\n controlBar.rootEl.classList.add(controlBar.className.FIXED);\n this._wasPaused = !this._playPromise && paused;\n };\n\n private _onControl = (progress: number) => {\n const video = this._video;\n if (!video) return;\n\n const time = video.source.duration * progress;\n video.source.currentTime = time;\n video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time }}));\n };\n\n private _onRelease = () => {\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (video && controlBar) {\n if (!this._wasPaused && !this._playPromise) {\n this._playPromise = video.source.play()\n .catch(() => void 0);\n\n // This should not be chained\n this._playPromise.then(() => {\n this._playPromise = null;\n });\n\n controlBar.rootEl.classList.remove(controlBar.className.FIXED);\n }\n }\n\n this._wasPaused = false;\n };\n}\n\nexport default ProgressBar;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show video play / pause button.\n * @ko 비디오 재생 / 일시정지 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass PlayButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _controlBar: ControlBar | null;\n private _video: TextureVideo | null;\n private _paused: boolean;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n\n this._video = null;\n this._paused = true;\n this._controlBar = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const video = viewer.projection?.getTexture();\n const className = controlBar.className;\n const unavailableClass = className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n element.classList.add(unavailableClass);\n return;\n }\n\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.remove(unavailableClass);\n\n const paused = video.isPaused();\n this._video = video;\n this._paused = paused;\n this._controlBar = controlBar;\n\n if (paused) {\n this._onPause();\n } else {\n this._onPlay();\n }\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onPlay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onPause);\n }\n\n public destroy() {\n const video = this._video;\n const element = this.element;\n\n if (!video) return;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onPlay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onPause);\n\n this._video = null;\n this._paused = true;\n this._controlBar = null;\n }\n\n private _onClick = () => {\n const video = this._video;\n if (!video) return;\n\n if (this._paused) {\n video.source.play();\n } else {\n video.source.pause();\n }\n };\n\n private _onPlay = () => {\n if (!this._controlBar) return;\n\n const element = this.element;\n const className = this._controlBar.className;\n\n element.classList.add(className.PAUSE_BUTTON);\n element.classList.remove(className.PLAY_BUTTON);\n element.title = \"Pause Video\";\n\n this._paused = false;\n };\n\n private _onPause = () => {\n if (!this._controlBar) return;\n\n const element = this.element;\n const className = this._controlBar.className;\n\n element.classList.add(className.PLAY_BUTTON);\n element.classList.remove(className.PAUSE_BUTTON);\n element.title = \"Play Video\";\n\n this._paused = true;\n };\n}\n\nexport default PlayButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport RangeControl from \"./RangeControl\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { EVENTS } from \"../../const/external\";\n\n/**\n * Show video volume control.\n * @ko 비디오 볼륨 조절 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VolumeControl extends ControlBarItem {\n public get element() { return this._rootEl; }\n\n private _controlBar: ControlBar | null;\n private _rootEl: HTMLButtonElement;\n private _buttonEl: HTMLElement;\n private _rangeControl: RangeControl;\n private _video: TextureVideo | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this._controlBar = null;\n this._rangeControl = new RangeControl();\n this._createElements();\n\n this._video = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const root = this._rootEl;\n const button = this._buttonEl;\n const rangeControl = this._rangeControl;\n const className = controlBar.className;\n const unavailableClass = className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n root.classList.add(unavailableClass);\n return;\n }\n\n root.classList.remove(unavailableClass);\n root.classList.add(className.CONTROLS_BUTTON);\n root.classList.add(className.VOLUME_ROOT);\n button.classList.add(className.CONTROLS_BUTTON);\n\n if (video.source.muted) {\n button.classList.add(className.MUTED_BUTTON);\n } else {\n button.classList.add(className.UNMUTED_BUTTON);\n }\n\n viewer.on(EVENTS.RESIZE, this._onResize);\n root.addEventListener(BROWSER.EVENTS.TRANSITION_END, this._onResize);\n button.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_VOLUME_CHANGE, this._onVolumeChange);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_LOADED_DATA, this._updateDisplay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay);\n\n rangeControl.init(className);\n rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n rangeControl.on(CONTROL_EVENTS.CHANGE, this._onChange);\n rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n this._controlBar = controlBar;\n this._video = video;\n\n this._updateDisplay();\n }\n\n public destroy(viewer: View360) {\n const video = this._video;\n const button = this._buttonEl;\n const root = this._rootEl;\n\n root.className = \"\";\n button.className = \"\";\n\n viewer.off(EVENTS.RESIZE, this._onResize);\n root.removeEventListener(BROWSER.EVENTS.TRANSITION_END, this._onResize);\n button.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_VOLUME_CHANGE, this._onVolumeChange);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_LOADED_DATA, this._updateDisplay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay);\n }\n\n this._controlBar = null;\n this._rangeControl.destroy();\n this._video = null;\n }\n\n private _onResize = () => {\n this._rangeControl.resize();\n this._updateDisplay();\n }\n\n private _onClick = () => {\n const video = this._video;\n if (!video || this._rootEl.disabled) return;\n\n video.source.muted = !video.source.muted;\n };\n\n private _onVolumeChange = () => {\n const button = this._buttonEl;\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (!video || !controlBar) return;\n\n const className = controlBar.className;\n\n if (video.source.muted || video.source.volume === 0) {\n button.classList.add(className.MUTED_BUTTON);\n button.classList.remove(className.UNMUTED_BUTTON);\n } else {\n button.classList.add(className.UNMUTED_BUTTON);\n button.classList.remove(className.MUTED_BUTTON);\n }\n\n this._updateDisplay();\n };\n\n private _createElements() {\n const root = document.createElement(BROWSER.EL_BUTTON);\n const buttonEl = document.createElement(BROWSER.EL_DIV);\n\n root.appendChild(this._rangeControl.rootEl);\n root.appendChild(buttonEl);\n root.title = \"Toggle Mute\";\n\n this._rootEl = root;\n this._buttonEl = buttonEl;\n }\n\n private _onHold = (progress: number) => {\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (!video || !controlBar) return;\n\n const className = controlBar.className;\n\n video.source.volume = progress;\n\n this._rootEl.classList.add(className.FIXED);\n controlBar.containerEl.classList.add(className.FIXED);\n\n this._updateDisplay();\n };\n\n private _onChange = (progress: number) => {\n const video = this._video;\n if (!video) return;\n\n video.source.volume = progress;\n if (progress > 0) {\n video.source.muted = false;\n } else {\n video.source.muted = true;\n }\n\n this._updateDisplay();\n };\n\n private _onRelease = () => {\n const controlBar = this._controlBar;\n if (!controlBar) return;\n\n const className = controlBar.className;\n\n this._rootEl.classList.remove(className.FIXED);\n controlBar.containerEl.classList.remove(className.FIXED);\n };\n\n private _updateDisplay = () => {\n const video = this._video;\n const root = this._rootEl;\n if (!video) return;\n\n if (!video.hasAudio()) {\n root.disabled = true;\n return;\n }\n\n root.disabled = false;\n\n const volume = video.source.muted ? 0 : video.source.volume;\n\n this._rangeControl.updateStyle(volume);\n };\n}\n\nexport default VolumeControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport { isFullscreen } from \"../../utils\";\n\n/**\n * Show fullscreen enter / exit button.\n * @ko 풀스크린 진입 / 해제 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass FullscreenButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _controlBar: ControlBar | null;\n private _targetEl: HTMLElement | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n this.element.title = \"Toggle Fullscreen\";\n this._controlBar = null;\n this._targetEl = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n if (!this._fullscreenAvailable()) {\n element.classList.add(className.UNAVAILABLE);\n return;\n }\n\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.remove(className.UNAVAILABLE);\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._addFullscreenHandlers();\n\n if (isFullscreen()) {\n element.classList.add(className.FULLSCREEN_EXIT_BUTTON);\n } else {\n element.classList.add(className.FULLSCREEN_BUTTON);\n }\n\n this._controlBar = controlBar;\n this._targetEl = viewer.rootEl;\n }\n\n public destroy() {\n const element = this.element;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._removeFullscreenHandlers();\n\n this._controlBar = null;\n this._targetEl = null;\n }\n\n private _onClick = () => {\n const target = this._targetEl;\n if (!target) return;\n\n if (isFullscreen()) {\n this._exitFullscreen();\n } else {\n this._requestFullscreen(target);\n }\n };\n\n private _fullscreenAvailable() {\n return BROWSER.FULLSCREEN_REQUEST.some(key => !!document[key]);\n }\n\n private _requestFullscreen(el: HTMLElement) {\n for (const key of BROWSER.FULLSCREEN_REQUEST) {\n const request = el[key];\n if (request) {\n request.call(el);\n return;\n }\n }\n }\n\n private _exitFullscreen() {\n for (const key of BROWSER.FULLSCREEN_EXIT) {\n const exit = document[key];\n\n if (exit) {\n exit.call(document);\n return;\n }\n }\n }\n\n private _addFullscreenHandlers() {\n BROWSER.FULLSCREEN_CHANGE.forEach(evtName => {\n document.addEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _removeFullscreenHandlers() {\n BROWSER.FULLSCREEN_CHANGE.forEach(evtName => {\n document.removeEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _onFullscreenChange = () => {\n const element = this.element;\n const controlBar = this._controlBar;\n\n if (!controlBar) return;\n\n const className = controlBar.className;\n\n if (isFullscreen()) {\n element.classList.add(className.FULLSCREEN_EXIT_BUTTON);\n element.classList.remove(className.FULLSCREEN_BUTTON);\n } else {\n element.classList.add(className.FULLSCREEN_BUTTON);\n element.classList.remove(className.FULLSCREEN_EXIT_BUTTON);\n }\n };\n}\n\nexport default FullscreenButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\n\n/**\n * Show video current / total time.\n * @ko 비디오의 현재 / 총 재생시간을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VideoTime extends ControlBarItem {\n public readonly element: HTMLElement;\n private _video: TextureVideo | null;\n private _currentTime: number;\n private _duration: number;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n\n this._video = null;\n this._currentTime = 0;\n this._duration = 0;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const element = this.element;\n const className = controlBar.className;\n\n if (!video || !video.isVideo()) {\n element.classList.add(className.UNAVAILABLE);\n return;\n }\n\n element.classList.add(className.VIDEO_TIME_DISPLAY);\n element.classList.remove(className.UNAVAILABLE);\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange);\n\n this._video = video;\n this._currentTime = video.source.currentTime;\n this._duration = video.source.duration;\n\n this._updateDisplay();\n }\n\n public destroy() {\n const video = this._video;\n\n if (!video) return;\n\n this.element.className = \"\";\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange);\n\n this._video = null;\n }\n\n private _onTimeUpdate = () => {\n const video = this._video;\n if (!video) return;\n\n this._currentTime = video.source.currentTime;\n this._updateDisplay();\n };\n\n private _onDurationChange = () => {\n const video = this._video;\n if (!video) return;\n\n this._duration = video.source.duration;\n this._updateDisplay();\n };\n\n private _onCustomTimeChange = (evt: CustomEvent<{ time: number }>) => {\n this._currentTime = evt.detail.time;\n this._updateDisplay();\n };\n\n private _updateDisplay() {\n const time = this._currentTime;\n const timeMinute = Math.floor(time / 60);\n const timeSeconds = Math.floor(time - timeMinute * 60);\n const timeSecondsFormatted = timeSeconds < 10 ? `0${timeSeconds}` : timeSeconds;\n\n const duration = this._duration;\n const durationMinute = Math.floor(duration / 60);\n const durationSeconds = Math.floor(duration - durationMinute * 60);\n const durationSecondsFormatted = durationSeconds < 10 ? `0${durationSeconds}` : durationSeconds;\n\n this.element.innerText = `${timeMinute}:${timeSecondsFormatted} / ${durationMinute}:${durationSecondsFormatted}`;\n }\n}\n\nexport default VideoTime;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport { circulate, getObjectOption } from \"../../utils\";\nimport * as BROWSER from \"../../const/browser\";\nimport { EVENTS } from \"../../const/external\";\nimport { SVG_NAMESPACE } from \"../../const/internal\";\n\n/**\n * Options for {@link PieView}\n * @ko {@link PieView}용 옵션들\n * @category Plugin\n */\nexport interface PieViewOptions extends ControlBarItemOptions {\n /**\n * @copy PieView#resetCamera\n */\n resetCamera: boolean | Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n duration: number;\n easing: (x: number) => number;\n }>;\n}\n\n/**\n * Show camera direction/fov indicator.\n * @ko 카메라가 향하는 방향 및 FOV를 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass PieView extends ControlBarItem {\n public readonly element: HTMLElement;\n\n /**\n * Set rotation to reset camera to when PieView is clicked.\n * `false` will disable this value, and `true` will enable with default options.\n * @ko PieView가 클릭되었을 때 카메라를 리셋할 방향을 지정합니다.\n * `false`일 경우 이 동작을 비활성화하며, `true`일 경우 기본값을 사용합니다.\n * @since 4.0.0\n */\n public resetCamera: PieViewOptions[\"resetCamera\"];\n\n private _viewer: View360 | null;\n private _piePathEl: SVGPathElement;\n private _rangeCircleEl: SVGCircleElement;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n resetCamera = true,\n position = CONTROL_BAR_ITEM_POSITION.TOP_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n this.element.title = \"Reset view\";\n this.resetCamera = resetCamera;\n this._createPieElements();\n this._viewer = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n\n if (!viewer.initialized) {\n viewer.once(EVENTS.READY, this._updatePie);\n } else {\n this._updatePie({ target: viewer });\n }\n\n const rootClass = controlBar.className.PIEVIEW_ROOT;\n element.classList.add(rootClass);\n\n if (this.resetCamera) {\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n }\n\n viewer.on(EVENTS.VIEW_CHANGE, this._updatePie);\n\n this._viewer = viewer;\n }\n\n public destroy(viewer: View360) {\n const element = this.element;\n\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.className = \"\";\n viewer.off(EVENTS.READY, this._updatePie);\n viewer.off(EVENTS.VIEW_CHANGE, this._updatePie);\n\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n const resetCamera = this.resetCamera;\n\n if (!viewer || !resetCamera) return;\n\n const {\n yaw = viewer.initialYaw,\n pitch = viewer.initialPitch,\n zoom = viewer.initialZoom,\n duration = 500\n } = getObjectOption(resetCamera);\n\n viewer.camera.animateTo({\n yaw,\n pitch,\n zoom,\n duration\n });\n };\n\n private _createPieElements() {\n const root = this.element;\n const pieSVG = document.createElementNS(SVG_NAMESPACE, \"svg\");\n pieSVG.setAttribute(\"viewBox\", \"0 0 48 48\");\n pieSVG.setAttribute(\"width\", \"100%\");\n pieSVG.setAttribute(\"height\", \"100%\");\n\n const piePath = document.createElementNS(SVG_NAMESPACE, \"circle\");\n\n piePath.setAttribute(\"stroke\", \"currentColor\");\n piePath.setAttribute(\"fill\", \"transparent\");\n piePath.setAttribute(\"cx\", \"24\");\n piePath.setAttribute(\"cy\", \"24\");\n piePath.setAttribute(\"r\", \"12\");\n piePath.setAttribute(\"stroke-width\", \"24\");\n pieSVG.appendChild(piePath);\n\n const rangeCircle = document.createElementNS(SVG_NAMESPACE, \"circle\");\n\n rangeCircle.setAttribute(\"stroke\", \"currentColor\");\n rangeCircle.setAttribute(\"fill\", \"transparent\");\n rangeCircle.setAttribute(\"cx\", \"24\");\n rangeCircle.setAttribute(\"cy\", \"24\");\n rangeCircle.setAttribute(\"r\", \"22.5\");\n rangeCircle.setAttribute(\"stroke-width\", \"3\");\n pieSVG.appendChild(rangeCircle);\n\n root.appendChild(pieSVG);\n\n this._piePathEl = piePath;\n this._rangeCircleEl = rangeCircle;\n }\n\n private _updatePie = ({ target: viewer }: { target: View360 }) => {\n const piePath = this._piePathEl;\n const rangeCircle = this._rangeCircleEl;\n const camera = viewer.camera;\n const fov = camera.getHorizontalFov();\n const yawRange = camera.getYawRange(camera.zoom);\n const halfFov = fov * 0.5;\n\n const pieRadius = 24 * Math.PI;\n const pieDeg = pieRadius * fov / 360;\n const pieOffset = pieRadius * (camera.yaw + halfFov + 90) / 360;\n\n piePath.setAttribute(\"stroke-dasharray\", `${pieDeg} ${pieRadius - pieDeg}`);\n piePath.setAttribute(\"stroke-dashoffset\", `${pieOffset}`);\n\n if (isFinite(yawRange.min) && isFinite(yawRange.max)) {\n const radius = 45 * Math.PI; // 2 * PI * r\n const min = (circulate(yawRange.min, -180, 180) - halfFov) / 360;\n const max = (circulate(yawRange.max, -180, 180) + halfFov) / 360;\n\n const rangeDiff = radius * Math.abs(max - min);\n const offset = -radius * (min - 0.25);\n\n rangeCircle.setAttribute(\"stroke-dasharray\", `${rangeDiff} ${radius - rangeDiff}`);\n rangeCircle.setAttribute(\"stroke-dashoffset\", `${offset}`);\n } else {\n rangeCircle.setAttribute(\"stroke-dasharray\", \"\");\n rangeCircle.setAttribute(\"stroke-dashoffset\", \"\");\n }\n };\n}\n\nexport default PieView;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show VR enter button.\n * @ko VR 진입 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VRButton extends ControlBarItem {\n public readonly element: HTMLElement;\n\n private _viewer: View360 | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n this.element.title = \"Enter VR\";\n this._viewer = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n element.classList.add(className.UNAVAILABLE);\n element.classList.add(className.VR_BUTTON);\n element.classList.add(className.CONTROLS_BUTTON);\n\n viewer.vr.isAvailable()\n .then(available => {\n if (available) {\n element.classList.remove(className.UNAVAILABLE);\n }\n });\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._viewer = viewer;\n }\n\n public destroy() {\n const element = this.element;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n if (!viewer) return;\n\n viewer.vr.enter();\n };\n}\n\nexport default VRButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport GyroControl from \"../../control/GyroControl\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { sensorCanBeEnabledIOS } from \"../../utils\";\n\n/**\n * Show gyroscope control enable / disable button\n * @ko 자이로스코프 컨트롤 활성화 / 비활성화 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass GyroButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _viewer: View360 | null;\n private _controlBar: ControlBar | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n this.element.title = \"Toggle gyroscope control\";\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.add(className.UNAVAILABLE);\n\n const enableButton = () => {\n element.classList.remove(className.UNAVAILABLE);\n viewer.control.gyro.on(CONTROL_EVENTS.ENABLE, this._updateStyle);\n viewer.control.gyro.on(CONTROL_EVENTS.DISABLE, this._updateStyle);\n };\n\n if (sensorCanBeEnabledIOS()) {\n enableButton();\n } else {\n GyroControl.isAvailable().then(available => {\n if (!available) return;\n enableButton();\n });\n }\n\n this._controlBar = controlBar;\n this._viewer = viewer;\n this._updateStyle();\n }\n\n public destroy(viewer: View360) {\n const element = this.element;\n\n viewer.control.gyro.off(CONTROL_EVENTS.ENABLE, this._updateStyle);\n viewer.control.gyro.off(CONTROL_EVENTS.DISABLE, this._updateStyle);\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.className = \"\";\n\n this._controlBar = null;\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n const controlBar = this._controlBar;\n\n if (!viewer || !controlBar) return;\n\n const gyroControl = viewer.control.gyro;\n if (gyroControl.enabled) {\n gyroControl.disable();\n } else {\n GyroControl.requestSensorPermission().then(available => {\n if (available) {\n gyroControl.enable();\n } else {\n this.element.classList.add(controlBar.className.UNAVAILABLE);\n }\n });\n }\n };\n\n private _updateStyle = () => {\n const element = this.element;\n const viewer = this._viewer;\n const controlBar = this._controlBar;\n\n if (!viewer || !controlBar) return;\n\n const gyroControl = viewer.control.gyro;\n const className = controlBar.className;\n\n if (gyroControl.enabled) {\n element.classList.add(className.GYRO_ENABLED);\n element.classList.remove(className.GYRO_DISABLED);\n } else {\n element.classList.add(className.GYRO_DISABLED);\n element.classList.remove(className.GYRO_ENABLED);\n }\n };\n}\n\nexport default GyroButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport { FULLSCREEN_CHANGE } from \"../../const/browser\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport { isFullscreen } from \"../../utils\";\n\n/**\n * Options for ControlBar's {@link ControlBarOptions#autoHide}\n * @ko ControlBar의 {@link ControlBarOptions#autoHide}용 옵션\n * @category Plugin\n * @since 4.0.0\n */\nexport interface AutoHideOptions {\n /**\n * Initial delay before the control bar hides (ms)\n * @ko 컨트롤바가 처음으로 표시되고 사라지기까지 걸리는 시간 (ms)\n * @default 3000\n * @since 4.0.0\n */\n initialDelay: number;\n /**\n * Delay time before hiding the control bar after mouse leave (ms)\n * @ko 마우스가 컨트롤바 영역을 떠난 뒤 컨트롤바가 사라지기까지 걸리는 시간 (ms)\n * @default 0\n * @since 4.0.0\n */\n delay: number;\n /**\n * Delay time before hiding the control bar becomes active, like touch on mobile device or mouse move in fullscreen mode (ms)\n * @ko 모바일이나 풀스크린 환경 등에서 사용자 입력이 없을 때 컨트롤바가 사라지기까지 걸리는 시간 (ms)\n * @default 3000\n * @since 4.0.0\n */\n idleDelay: number;\n}\n\nclass AutoHide {\n private _initialDelay: AutoHideOptions[\"initialDelay\"];\n private _delay: AutoHideOptions[\"delay\"];\n private _idleDelay: AutoHideOptions[\"idleDelay\"];\n\n private _controlBar: ControlBar;\n private _timer: number;\n private _isGrabbing: boolean;\n private _isCursorInside: boolean;\n private _isFullscreen: boolean;\n private _targetEl: HTMLElement | null;\n private _video: TextureVideo | null;\n\n public get enabled() { return !!this._targetEl; }\n public get hidden() { return this._controlBar.containerEl.classList.contains(this._hiddenClass); }\n\n private get _hiddenClass() { return this._controlBar.className.HIDDEN; }\n private get _fixedClass() { return this._controlBar.className.FIXED; }\n\n public constructor(controlBar: ControlBar, {\n initialDelay = 3000,\n delay = 0,\n idleDelay: activationDelay = 3000\n }: Partial) {\n this._controlBar = controlBar;\n this._initialDelay = initialDelay;\n this._delay = delay;\n this._idleDelay = activationDelay;\n this._timer = -1;\n this._isCursorInside = false;\n this._isGrabbing = false;\n this._isFullscreen = false;\n this._video = null;\n this._targetEl = null;\n }\n\n public enable(viewer: View360) {\n if (this._targetEl) {\n this.disable(viewer);\n }\n\n const initialDelay = this._initialDelay;\n const root = viewer.rootEl;\n\n this._targetEl = viewer.rootEl;\n this._timer = window.setTimeout(() => {\n this.hide();\n }, initialDelay);\n\n root.addEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onHold);\n root.addEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter);\n root.addEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove);\n root.addEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave);\n this._addFullscreenHandlers();\n\n const video = viewer.projection?.getTexture();\n if (!video || !video.isVideo()) {\n return;\n }\n\n if (video.isPaused()) {\n this._controlBar.containerEl.classList.add(this._fixedClass);\n }\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onVideoPlay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onVideoPause);\n\n this._video = video;\n }\n\n public disable(viewer: View360) {\n if (!this._targetEl) return;\n\n const controlBar = this._controlBar;\n const root = viewer.rootEl;\n const video = this._video;\n\n root.removeEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onHold);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave);\n this._removeFullscreenHandlers();\n\n window.clearTimeout(this._timer);\n controlBar.containerEl.classList.remove(this._fixedClass);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onVideoPlay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onVideoPause);\n }\n\n this._isCursorInside = false;\n this._isGrabbing = false;\n this._video = null;\n this._targetEl = null;\n }\n\n public show() {\n this._clearHideTimer();\n this._controlBar.containerEl.classList.remove(this._hiddenClass);\n }\n\n public showTemporaliy() {\n this.show();\n this._hideAfterDelay(this._idleDelay);\n }\n\n public hide() {\n this._clearHideTimer();\n this._controlBar.containerEl.classList.add(this._hiddenClass);\n }\n\n private _clearHideTimer() {\n if (this._timer) {\n window.clearTimeout(this._timer);\n this._timer = -1;\n }\n }\n\n private _hideAfterDelay(delay = this._delay) {\n if (this._isGrabbing || (!this._isFullscreen && this._isCursorInside)) return;\n\n this._clearHideTimer();\n if (delay <= 0) {\n this.hide();\n } else {\n this._timer = window.setTimeout(() => {\n this.hide();\n }, delay);\n }\n }\n\n private _onMouseEnter = () => {\n this._isCursorInside = true;\n this.show();\n };\n\n private _onMouseLeave = () => {\n this._isCursorInside = false;\n this._hideAfterDelay();\n };\n\n private _onMouseMove = () => {\n if (!this._isFullscreen) return;\n\n this.showTemporaliy();\n }\n\n private _onHold = (evt: PointerEvent) => {\n this._isGrabbing = true;\n\n if (evt.pointerType === \"mouse\") {\n this._isCursorInside = true;\n }\n\n window.addEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n\n this.show();\n };\n\n private _onRelease = () => {\n this._isGrabbing = false;\n\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n\n this._hideAfterDelay();\n };\n\n private _onVideoPlay = () => {\n const root = this._targetEl;\n if (!root) return;\n\n this._controlBar.containerEl.classList.remove(this._fixedClass);\n };\n\n private _onVideoPause = () => {\n const root = this._targetEl;\n if (!root) return;\n\n this._controlBar.containerEl.classList.add(this._fixedClass);\n };\n\n private _addFullscreenHandlers() {\n FULLSCREEN_CHANGE.forEach(evtName => {\n document.addEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _removeFullscreenHandlers() {\n FULLSCREEN_CHANGE.forEach(evtName => {\n document.removeEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _onFullscreenChange = () => {\n this._isFullscreen = isFullscreen();\n\n if (this._isFullscreen) {\n this._hideAfterDelay();\n }\n };\n}\n\nexport default AutoHide;\n","import TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { clamp } from \"../../utils\";\nimport { VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\n\nclass VideoControl {\n private _video: TextureVideo | null;\n\n public enable(root: HTMLElement, video: TextureVideo) {\n this._video = video;\n // capture is needed for resolving conflict with keyboard control\n root.addEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown, true);\n }\n\n public disable(root: HTMLElement) {\n this._video = null;\n root.removeEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown, true);\n }\n\n private _onKeyDown = (event: KeyboardEvent) => {\n const video = this._video;\n if (!video) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n const videoEl = video.source;\n const keyPressed = event.keyCode != null\n ? BROWSER.DIRECTION_KEY_CODE[event.keyCode]\n : BROWSER.DIRECTION_KEY_NAME[event.key];\n\n switch (keyPressed) {\n case \"LEFT\":\n case \"RIGHT\":\n return this._changeVideoTime(videoEl, keyPressed === \"RIGHT\");\n case \"UP\":\n case \"DOWN\":\n return this._changeVideoVolume(videoEl, keyPressed === \"UP\");\n }\n\n const spacePressed = event.keyCode === BROWSER.SPACE_KEY_CODE || event.key === BROWSER.SPACE_KEY_NAME;\n if (spacePressed) {\n this._toggleVideo(video);\n }\n }\n\n private _changeVideoTime(video: HTMLVideoElement, forward: boolean) {\n const delta = forward ? 5 : -5;\n\n video.currentTime += delta;\n video.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time: video.currentTime }}));\n }\n\n private _changeVideoVolume(video: HTMLVideoElement, increase: boolean) {\n const delta = increase ? 0.1 : -0.1;\n\n if (video.muted) {\n video.volume = clamp(delta, 0, 1);\n } else {\n video.volume = clamp(video.volume + delta, 0, 1);\n }\n\n if (video.volume > 0) {\n video.muted = false;\n } else {\n video.muted = true;\n }\n }\n\n private _toggleVideo(video: TextureVideo) {\n if (video.isPaused()) {\n video.source.play();\n } else {\n video.source.pause();\n }\n }\n}\n\nexport default VideoControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport ProgressBar from \"./ProgressBar\";\nimport PlayButton from \"./PlayButton\";\nimport VolumeControl from \"./VolumeControl\";\nimport FullscreenButton from \"./FullscreenButton\";\nimport VideoTime from \"./VideoTime\";\nimport PieView, { PieViewOptions } from \"./PieView\";\nimport VRButton from \"./VRButton\";\nimport GyroButton from \"./GyroButton\";\nimport AutoHide, { AutoHideOptions } from \"./AutoHide\";\nimport VideoControl from \"./VideoControl\";\nimport View360, { View360Events } from \"../../View360\";\nimport View360Plugin from \"../View360Plugin\";\nimport { EVENTS } from \"../../const/external\";\nimport { createElement, findIndex, getObjectOption } from \"../../utils\";\nimport { ValueOf } from \"../../type/utils\";\nimport { StaticClickEvent } from \"../../type/events\";\nimport { CONTROL_BAR_DEFAULT_CLASS, CONTROL_BAR_ITEM_POSITION } from \"./const\";\n\n/**\n * Options for {@link ControlBar}\n * @ko {@link ControlBar}용 옵션들\n * @category Plugin\n * @since 4.0.0\n */\nexport interface ControlBarOptions {\n /**\n * @copy ControlBar#autoHide\n */\n autoHide: boolean | Partial;\n /**\n * @copy ControlBar#showBackground\n */\n showBackground: boolean;\n /**\n * @copy ControlBar#clickToPlay\n */\n clickToPlay: boolean;\n /**\n * @copy ControlBar#keyboardControls\n */\n keyboardControls: boolean;\n /**\n * @copy ControlBar#progressBar\n */\n progressBar: boolean | Partial;\n /**\n * @copy ControlBar#playButton\n */\n playButton: boolean | Partial;\n /**\n * @copy ControlBar#volumeButton\n */\n volumeButton: boolean | Partial;\n /**\n * @copy ControlBar#fullscreenButton\n */\n fullscreenButton: boolean | Partial;\n /**\n * @copy ControlBar#videoTime\n */\n videoTime: boolean | Partial;\n /**\n * @copy ControlBar#pieView\n */\n pieView: boolean | Partial;\n /**\n * @copy ControlBar#vrButton\n */\n vrButton: boolean | Partial;\n /**\n * @copy ControlBar#gyroButton\n */\n gyroButton: boolean | Partial;\n /**\n * @copy ControlBar#className\n */\n className: Partial<{ -readonly [key in keyof typeof ControlBar.DEFAULT_CLASS]: string }>;\n /**\n * @copy ControlBar#customItems\n */\n customItems: ControlBarItem[];\n}\n\n/**\n * A plugin that displays extra buttons & controls that controls {@link View360}.\n * @ko {@link View360}에 부가적인 버튼과 컨트롤을 추가해주는 플러그인.\n * @category Plugin\n * @since 4.0.0\n */\nclass ControlBar implements View360Plugin {\n /**\n * Default class names that ControlBar uses\n * @ko ControlBar가 사용하는 디폴트 클래스 이름들\n * @since 4.0.0\n */\n public static readonly DEFAULT_CLASS = CONTROL_BAR_DEFAULT_CLASS;\n\n /**\n * Constants for {@link ControlBarItemOptions#position}\n * @ko {@link ControlBarItemOptions#position}에 사용 가능한 값들\n */\n public static readonly POSITION = CONTROL_BAR_ITEM_POSITION;\n\n /**\n * Automatically hide control bar on video plays.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 재생시 자동으로 컨트롤바를 숨깁니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly autoHide?: ControlBarOptions[\"autoHide\"];\n /**\n * Show background element.\n * @ko 배경 엘리먼트를 표시합니다.\n * @since 4.0.0\n */\n public readonly showBackground?: ControlBarOptions[\"showBackground\"];\n /**\n * Whether to play / pause video on canvas click\n * @ko 캔버스 클릭시에 비디오를 재생 / 일시정지 토글합니다.\n * @since 4.0.0\n */\n public readonly clickToPlay: ControlBarOptions[\"clickToPlay\"];\n /**\n * Enable keyboard controls for video.\n * Pressing up / down arrow will control video volume, and pressing left / right arrow will control video time.\n * @ko 비디오 키보드 컨트롤을 활성화합니다.\n * 위 / 아래 화살표키를 누를 시 비디오 볼륨을, 왼쪽 / 오른쪽 화살표키를 누를 시 비디오 시간을 조정합니다.\n * @since 4.0.0\n */\n public readonly keyboardControls: ControlBarOptions[\"keyboardControls\"];\n /**\n * Show video progress bar.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 프로그레스 바를 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly progressBar: ControlBarOptions[\"progressBar\"];\n /**\n * Show video play / pause button.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 재생 / 일시정지 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly playButton: ControlBarOptions[\"playButton\"];\n /**\n * Show video volume control button.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 볼륨 조절 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly volumeButton: ControlBarOptions[\"volumeButton\"];\n /**\n * Show fullscreen button.\n * `true` to enable with default values, `false` to disable.\n * @ko 풀스크린 진입 / 해제 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly fullscreenButton: ControlBarOptions[\"fullscreenButton\"];\n /**\n * Show video current / total time\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오의 현재 시간 / 총 시간을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly videoTime: ControlBarOptions[\"videoTime\"];\n /**\n * Show camera pie view.\n * `true` to enable with default values, `false` to disable.\n * @ko 현재 카메라가 가리키는 방향을 표시하는 파이 뷰를 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly pieView: ControlBarOptions[\"pieView\"];\n /**\n * Show VR button.\n * `true` to enable with default values, `false` to disable.\n * @ko VR 진입버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly vrButton: ControlBarOptions[\"vrButton\"];\n /**\n * Show gyroscope control enable / disable button.\n * `true` to enable with default values, `false` to disable.\n * @ko 자이로스코프 컨트롤을 활성화 / 비활성화하는 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly gyroButton: ControlBarOptions[\"gyroButton\"];\n /**\n * Override default class names.\n * @ko 디폴트 클래스 이름들을 오버라이드합니다.\n * @since 4.0.0\n */\n public readonly className: Required;\n\n /**\n * Root element of the control bar\n * @ko 컨트롤바의 루트 엘리먼트\n * @since 4.0.0\n */\n public get rootEl() { return this._rootEl; }\n /**\n * Container element of the control bar\n * @ko 컨트롤바의 컨테이너 엘리먼트\n * @since 4.0.0\n */\n public get containerEl() { return this._containerEl; }\n /**\n * Background element of the control bar\n * @ko 컨트롤바의 배경 엘리먼트\n * @since 4.0.0\n */\n public get backgroundEl() { return this._bgEl; }\n /**\n * Control bar's default items created by {@link ControlBarOptions}\n * @ko 주어진 {@link ControlBarOptions}에 의해 생성된 디폴트 아이템들\n * @since 4.0.0\n */\n public get items() { return this._items; }\n /**\n * Custom control bar items\n * @ko 커스텀 컨트롤바 아이템들을 추가합니다.\n * @since 4.0.0\n */\n public get customItems() { return this._customItems; }\n\n private _rootEl: HTMLElement;\n private _containerEl: HTMLElement;\n private _bgEl: HTMLElement;\n private _wrapperEl: Record, HTMLElement>;\n private _items: Record, ControlBarItem[]>;\n private _customItems: ControlBarItem[];\n private _autoHider: AutoHide;\n private _videoControl: VideoControl;\n\n /**\n * Create new instance of ControlBar.\n * @ko ControlBar의 새 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n autoHide,\n showBackground,\n clickToPlay = true,\n keyboardControls = true,\n progressBar = true,\n playButton = true,\n volumeButton = true,\n fullscreenButton = true,\n videoTime = true,\n pieView = true,\n vrButton = true,\n gyroButton = true,\n className = {},\n customItems = []\n }: Partial = {}) {\n this.autoHide = autoHide;\n this.showBackground = showBackground;\n this.clickToPlay = clickToPlay;\n this.keyboardControls = keyboardControls;\n this.progressBar = progressBar;\n this.playButton = playButton;\n this.volumeButton = volumeButton;\n this.fullscreenButton = fullscreenButton;\n this.videoTime = videoTime;\n this.pieView = pieView;\n this.vrButton = vrButton;\n this.gyroButton = gyroButton;\n this.className = {\n ...ControlBar.DEFAULT_CLASS,\n ...className\n };\n\n const rootClass = className.CONTROLS_ROOT ?? ControlBar.DEFAULT_CLASS.CONTROLS_ROOT;\n\n this._rootEl = createElement(rootClass);\n this._createPositionWrappers();\n this._items = Object.keys(ControlBar.POSITION).reduce((items, key) => {\n items[ControlBar.POSITION[key]] = [];\n return items;\n }, {}) as Record, ControlBarItem[]>;\n this._customItems = customItems;\n this._autoHider = new AutoHide(this, getObjectOption(autoHide));\n this._videoControl = new VideoControl();\n\n customItems.forEach(item => {\n this._items[item.position].push(item);\n });\n }\n\n public init(viewer: View360) {\n const panoRoot = viewer.rootEl;\n const controlsRoot = this._rootEl;\n const defaultItems = this._createDefaultItems();\n\n this._updateBackground(viewer);\n this._updateAutoHide(viewer);\n this._updateKeyboardHandler(viewer);\n\n panoRoot.appendChild(controlsRoot);\n this._addItem(viewer, defaultItems);\n this._addItem(viewer, this._customItems);\n\n viewer.on(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad);\n viewer.on(EVENTS.STATIC_CLICK, this._onStaticClick);\n }\n\n public destroy(viewer: View360): void {\n // Remove controls root from pano root\n const panoRoot = viewer.rootEl;\n const controlsRoot = this._rootEl;\n const items = this._items;\n\n if (controlsRoot.parentElement === panoRoot) {\n panoRoot.removeChild(controlsRoot);\n }\n\n Object.keys(items).forEach((key: ValueOf) => {\n const category = items[key];\n\n category.forEach(item => {\n item.destroy(viewer, this);\n });\n\n items[key] = [];\n });\n\n this._clearItemElements();\n this._autoHider.disable(viewer);\n this._videoControl.disable(panoRoot);\n\n viewer.off(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad);\n viewer.off(EVENTS.STATIC_CLICK, this._onStaticClick);\n }\n\n private _addItem(viewer: View360, items: ControlBarItem[]) {\n for (const item of items) {\n const category = this._items[item.position];\n const wrapper = this._wrapperEl[item.position];\n\n const nextSiblingIndex = findIndex(category, sibling => sibling.order > item.order);\n\n if (nextSiblingIndex >= 0) {\n const nextSibling = category[nextSiblingIndex].element;\n category.splice(nextSiblingIndex, 0, item);\n wrapper.insertBefore(item.element, nextSibling);\n } else {\n category.push(item);\n wrapper.appendChild(item.element);\n }\n\n item.init(viewer, this);\n }\n }\n\n private _createPositionWrappers() {\n const className = {\n ...ControlBar.DEFAULT_CLASS,\n ...this.className\n };\n const rootEl = this._rootEl;\n\n // BG & FLOATING CONTROLS\n const backgroundEl = createElement(className.CONTROLS_BG);\n const floatLeftEl = createElement(className.CONTROLS_FLOAT_LEFT);\n const floatRightEl = createElement(className.CONTROLS_FLOAT_RIGHT);\n\n rootEl.appendChild(floatLeftEl);\n rootEl.appendChild(floatRightEl);\n\n // BOTTOM CONTROLS\n const container = createElement(className.CONTROLS_MAIN);\n const topWrapper = createElement(className.CONTROLS_TOP);\n const bottomWrapper = createElement(className.CONTROLS_BOTTOM);\n const midWrapper = createElement(className.CONTROLS_MID);\n const leftControlsWrapper = createElement(className.CONTROLS_LEFT);\n const rightControlsWrapper = createElement(className.CONTROLS_RIGHT);\n\n midWrapper.appendChild(leftControlsWrapper);\n midWrapper.appendChild(rightControlsWrapper);\n container.appendChild(backgroundEl);\n container.appendChild(topWrapper);\n container.appendChild(midWrapper);\n container.appendChild(bottomWrapper);\n rootEl.appendChild(container);\n\n this._bgEl = backgroundEl;\n this._containerEl = container;\n this._wrapperEl = {\n [ControlBar.POSITION.MAIN_TOP]: topWrapper,\n [ControlBar.POSITION.MAIN_LEFT]: leftControlsWrapper,\n [ControlBar.POSITION.MAIN_RIGHT]: rightControlsWrapper,\n [ControlBar.POSITION.MAIN_BOTTOM]: bottomWrapper,\n [ControlBar.POSITION.TOP_LEFT]: floatLeftEl,\n [ControlBar.POSITION.TOP_RIGHT]: floatRightEl\n };\n }\n\n private _clearItemElements() {\n const wrappers = Object.keys(ControlBar.POSITION).map(key => ControlBar.POSITION[key]);\n\n // Remove all elements inside wrappers\n wrappers.forEach(wrapper => {\n while (wrapper.firstChild) {\n wrapper.removeChild(wrapper.firstChild);\n }\n });\n }\n\n private _onStaticClick = ({ target: viewer, isTouch }: StaticClickEvent) => {\n const autoHider = this._autoHider;\n\n if (isTouch) {\n if (!autoHider.enabled) return;\n\n if (autoHider.hidden) {\n autoHider.showTemporaliy();\n } else {\n autoHider.hide();\n }\n } else {\n if (!this.clickToPlay) return;\n\n const video = viewer.projection?.getTexture();\n if (!video || !video.isVideo()) return;\n\n if (video.isPaused()) {\n video.source.play();\n } else {\n video.source.pause();\n }\n }\n };\n\n private _onNewSrcLoad = ({ target: viewer }: View360Events[\"projectionChange\"]) => {\n const items = this._items;\n\n this._updateBackground(viewer);\n this._updateAutoHide(viewer);\n this._updateKeyboardHandler(viewer);\n\n Object.keys(items).forEach((key: ValueOf) => {\n const category = items[key];\n\n category.forEach(item => {\n item.destroy(viewer, this);\n item.init(viewer, this);\n });\n });\n };\n\n private _updateAutoHide(viewer: View360) {\n const autoHide = this.autoHide;\n const autoHider = this._autoHider;\n\n if (autoHide != null) {\n if (autoHide) {\n autoHider.enable(viewer);\n } else {\n autoHider.disable(viewer);\n }\n } else {\n // Automatically choose whether to show background by content type\n const texture = viewer.projection?.getTexture();\n\n if (texture && texture.isVideo()) {\n // Enable auto hide when content type is video\n autoHider.enable(viewer);\n } else {\n autoHider.disable(viewer);\n }\n }\n }\n\n private _updateBackground(viewer: View360) {\n const background = this._bgEl;\n const showBackground = this.showBackground;\n const hiddenClass = this.className.HIDDEN ?? ControlBar.DEFAULT_CLASS.HIDDEN;\n\n if (showBackground != null) {\n if (showBackground) {\n background.classList.remove(hiddenClass);\n } else {\n background.classList.add(hiddenClass);\n }\n } else {\n // Automatically choose whether to show background by content type\n const texture = viewer.projection?.getTexture();\n\n if (texture && texture.isVideo()) {\n // Show bg when content type is video\n background.classList.remove(hiddenClass);\n } else {\n background.classList.add(hiddenClass);\n }\n }\n }\n\n private _updateKeyboardHandler(viewer: View360) {\n const panoRoot = viewer.rootEl;\n const videoControl = this._videoControl;\n const texture = viewer.projection?.getTexture();\n\n if (this.keyboardControls && texture && texture.isVideo()) {\n videoControl.enable(panoRoot, texture);\n } else {\n videoControl.disable(panoRoot);\n }\n }\n\n private _createDefaultItems(): ControlBarItem[] {\n const items: ControlBarItem[] = [];\n\n if (this.progressBar) {\n items.push(new ProgressBar(getObjectOption(this.progressBar)));\n }\n\n if (this.playButton) {\n items.push(new PlayButton(getObjectOption(this.playButton)));\n }\n\n if (this.volumeButton) {\n items.push(new VolumeControl(getObjectOption(this.volumeButton)));\n }\n\n if (this.gyroButton) {\n items.push(new GyroButton(getObjectOption(this.gyroButton)));\n }\n\n if (this.vrButton) {\n items.push(new VRButton(getObjectOption(this.vrButton)));\n }\n\n if (this.fullscreenButton) {\n items.push(new FullscreenButton(getObjectOption(this.fullscreenButton)));\n }\n\n if (this.videoTime) {\n items.push(new VideoTime(getObjectOption(this.videoTime)));\n }\n\n if (this.pieView) {\n items.push(new PieView(getObjectOption(this.pieView)));\n }\n\n return items;\n }\n}\n\nexport default ControlBar;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Camera from \"../core/Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport Texture from \"../texture/Texture\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport { VideoConfig } from \"../type/external\";\nimport UniformCanvasCube from \"../uniform/UniformCanvasCube\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport UniformTextureCube from \"../uniform/UniformTextureCube\";\n\ntype CommonProjectionUniforms = {\n uTexture: UniformTexture2D | UniformTextureCube | UniformCanvasCube;\n}\n\n/**\n * Common option for {@link Projection}s\n * @ko {@link Projection}을 위한 공통 옵션들\n * @category Projection\n * @since 4.0.0\n */\nexport interface ProjectionOptions {\n /**\n * @copy Projection#src\n */\n src: string | HTMLElement | Array;\n /**\n * @copy Projection#video\n */\n video?: boolean | Partial;\n}\n\n/**\n * Base class for projections.\n * @ko 프로젝션 베이스 클래스.\n * @category Projection\n * @since 4.0.0\n */\nabstract class Projection {\n /**\n * Source URL to panorama image/video.\n * @ko 파노라마 이미지/비디오의 URL\n * @since 4.0.0\n */\n public readonly src: ProjectionOptions[\"src\"];\n /**\n * Properties for the video element.\n * Setting `false` will treat panorama source as an image, `true` will use default properties.\n * @ko 비디오 엘리먼트에 설정할 프로퍼티를 담는 객체.\n * @since 4.0.0\n * @example\n * Default properties\n * ```ts\n * autoplay: true\n * muted: true\n * loop: false\n * volume: 1\n * ```\n */\n public readonly video: ProjectionOptions[\"video\"];\n\n protected _mesh: TriangleMesh | null;\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n src,\n video = false\n }: ProjectionOptions) {\n this.src = src;\n this.video = video;\n this._mesh = null;\n }\n\n /**\n * Apply texture to current projection.\n * @ko 주어진 텍스쳐를 현재 프로젝션에 적용합니다.\n * @param ctx - Instance of the WebGLContext helper {@ko WebGL context 헬퍼의 인스턴스}\n * @param texture - New texture to apply {@ko 새로 적용할 텍스쳐}\n * @internal\n * @since 4.0.0\n */\n public abstract applyTexture(ctx: WebGLContext, texture: Texture): void;\n\n /**\n * Release all resources projection has.\n * This is automatically called on projection change & View360's destroy call\n * @ko 현재 갖고 있는 모든 리소스를 반환합니다.\n * 이 메소드는 프로젝션 변경 및 View360의 destroy 호출 시 자동으로 호출됩니다.\n * @param ctx\n */\n public releaseAllResources(ctx: WebGLContext) {\n this._mesh?.destroy(ctx);\n }\n\n /**\n * Update camera to match projection's settings.\n * @ko 현재 프로젝션의 세팅으로 카메라를 업데이트합니다.\n * @param camera - Instance of the camera to update {@ko 업데이트할 카메라의 인스턴스}\n * @since 4.0.0\n */\n public updateCamera(camera: Camera) {\n // Use default mode & no view restriction\n camera.resetRange();\n }\n\n /**\n * Update control to match projection's settings.\n * @ko 현재 프로젝션의 세팅으로 컨트롤을 업데이트합니다.\n * @param control - Instance of the control to update {@ko 업데이트할 컨트롤의 인스턴스}\n * @since 4.0.0\n */\n public updateControl(control: PanoControl) {\n control.ignoreZoomScale = false;\n }\n\n /**\n * Update projection.\n * @ko 현재 프로젝션 정보를 갱신합니다.\n * @param camera - Instance of the camera to reference {@ko 참조할 카메라의 인스턴스}\n * @since 4.0.0\n */\n public update(camera: Camera) {} // eslint-disable-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars\n\n /**\n * Return active texture.\n * @ko 현재 활성화된 텍스쳐를 반환합니다.\n * @internal\n * @since 4.0.0\n */\n public getTexture() {\n if (!this._mesh) return null;\n\n return this._mesh.program.uniforms.uTexture.texture;\n }\n\n /**\n * A 3D triangle mesh for projection. It's `null` until loading the `src`.\n * @ko Projection을 표시하기 위한 Mesh, src를 로드하기 전까지는 `null`입니다.\n * @since 4.0.0\n */\n public getMesh(): TriangleMesh | null {\n return this._mesh;\n }\n}\n\nexport default Projection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nabstract class Uniform {\n public needsUpdate: boolean;\n\n public constructor() {\n this.needsUpdate = true;\n }\n\n public abstract update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean): void;\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext) {\n // DO_NOTHING\n }\n}\n\nexport default Uniform;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport TextureCube from \"../texture/TextureCube\";\nimport { reorderCube } from \"../utils\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformTextureCube extends Uniform {\n public readonly texture: TextureCube;\n private _webglTexture: WebGLTexture;\n private _cubemapOrder: string;\n\n public constructor(ctx: WebGLContext, texture: TextureCube, cubemapOrder: string) {\n super();\n\n this.texture = texture;\n this._webglTexture = ctx.createWebGLCubeTexture(texture, texture.width);\n this._cubemapOrder = cubemapOrder;\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext): void {\n this.texture.destroy();\n gl.deleteTexture(this._webglTexture);\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture);\n\n const sources = reorderCube(texture.sources, this._cubemapOrder);\n sources.forEach((src, idx) => {\n if (isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src);\n } else {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src);\n }\n });\n\n if (!texture.isVideo()) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformTextureCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"../texture/Texture2D\";\nimport { range, reorderCube } from \"../utils\";\n\n/** @hidden */\nclass CubeTexturePainter {\n public readonly texture: Texture2D;\n private _renderingOrder: number[];\n private _canvas: HTMLCanvasElement;\n private _ctx: CanvasRenderingContext2D;\n private _row: number;\n private _column: number;\n private _size: number;\n\n public get size() { return this._size; }\n\n public constructor(texture: Texture2D, cubemapOrder: string) {\n this.texture = texture;\n this._renderingOrder = reorderCube(range(6), cubemapOrder);\n\n const canvas = document.createElement(\"canvas\");\n\n this._calcRenderingSize();\n\n canvas.width = this._size;\n canvas.height = this._size;\n\n this._canvas = canvas;\n this._ctx = canvas.getContext(\"2d\")!;\n }\n\n public destroy() {\n const canvas = this._canvas;\n\n // release memories\n canvas.width = 1;\n canvas.height = 1;\n this._canvas = null as any;\n }\n\n public draw(gl: WebGLRenderingContext | WebGL2RenderingContext, isWebGL2: boolean) {\n const size = this._size;\n const texture = this.texture;\n let surfaceIdx = 0;\n\n for (let row = 0; row < this._row; row++) {\n for (let column = 0; column < this._column; column++) {\n const x = size * column;\n const y = size * row;\n const renderingFace = this._renderingOrder[surfaceIdx];\n\n this._ctx.drawImage(texture.source as CanvasImageSource, x, y, size, size, 0, 0, size, size);\n\n if (isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas);\n } else {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas);\n }\n\n surfaceIdx++;\n }\n }\n }\n\n private _calcRenderingSize() {\n const {\n width,\n height\n } = this.texture;\n const aspect = width / height;\n\n if (aspect === 1 / 6) {\n this._size = width;\n this._row = 6;\n this._column = 1;\n } else if (aspect === 6) {\n this._size = height;\n this._row = 1;\n this._column = 6;\n } else if (aspect === 2 / 3) {\n this._size = width * 0.5;\n this._row = 3;\n this._column = 2;\n } else {\n this._size = width / 3;\n this._row = 2;\n this._column = 3;\n }\n }\n}\n\nexport default CubeTexturePainter;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport CubeTexturePainter from \"../core/CubeTexturePainter\";\nimport Texture2D from \"../texture/Texture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformCanvasCube extends Uniform {\n private _webglTexture: WebGLTexture;\n private _painter: CubeTexturePainter;\n\n public get texture() { return this._painter.texture; }\n\n public constructor(ctx: WebGLContext, texture: Texture2D, cubemapOrder: string) {\n super();\n\n this._painter = new CubeTexturePainter(texture as Texture2D, cubemapOrder);\n this._webglTexture = ctx.createWebGLCubeTexture(texture, this._painter.size);\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext) {\n gl.deleteTexture(this._webglTexture);\n this._painter.destroy();\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture);\n\n this._painter.draw(gl, isWebGL2);\n\n if (!texture.isVideo()) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformCanvasCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Object3D from \"./Object3D\";\nimport ShaderProgram from \"./ShaderProgram\";\nimport VertexArrayObject from \"./VertexArrayObject\";\nimport Uniform from \"../uniform/Uniform\";\nimport WebGLContext from \"./WebGLContext\";\n\n/**\n * @hidden\n */\nclass TriangleMesh = Record> extends Object3D {\n /**\n * @internal\n * Geometry data for projection\n */\n public readonly vao: VertexArrayObject;\n /**\n * @internal\n * Material(shader) data for projection\n */\n public readonly program: ShaderProgram;\n\n public constructor(vao: VertexArrayObject, program: ShaderProgram) {\n super();\n\n this.vao = vao;\n this.program = program;\n }\n\n public destroy(ctx: WebGLContext) {\n ctx.releaseVAO(this.vao);\n ctx.releaseShaderResources(this.program);\n }\n}\n\nexport default TriangleMesh;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"../uniform/Uniform\";\nimport WebGLContext from \"./WebGLContext\";\nimport { UniformLocations } from \"../type/internal\";\n\nclass ShaderProgram = Record> {\n public readonly program: WebGLProgram;\n public readonly uniforms: T;\n public readonly uniformLocations: UniformLocations;\n\n public constructor(ctx: WebGLContext, vertexShader: string, fragmentShader: string, uniforms: T) {\n this.program = ctx.createProgram(vertexShader, fragmentShader);\n this.uniforms = uniforms;\n this.uniformLocations = ctx.getUniformLocations(this.program, uniforms);\n }\n}\n\nexport default ShaderProgram;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { TypedArray } from \"../type/utils\";\n\n/**\n * @hidden\n */\nclass VertexData {\n public readonly data: T;\n public itemSize: number;\n public count: number;\n\n /** */\n public constructor(data: T, itemSize: number) {\n this.data = data;\n this.itemSize = itemSize;\n this.count = data.length / itemSize;\n }\n}\n\nexport default VertexData;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport VertexData from \"../core/VertexData\";\n\n/**\n * @hidden\n */\nabstract class Geometry {\n public readonly vertices: VertexData;\n public readonly indicies: VertexData;\n public readonly uvs: VertexData;\n\n /** */\n public constructor(vertices: number[], indicies: number[], uvs: number[]) {\n this.vertices = new VertexData(new Float32Array(vertices), 3);\n this.indicies = new VertexData(new Uint16Array(indicies), 1);\n this.uvs = new VertexData(new Float32Array(uvs), 2);\n }\n}\n\nexport default Geometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\nimport { ROTATE } from \"../const/internal\";\nimport { reorderCube } from \"../utils\";\n\n/**\n * @hidden\n */\nclass CubeGeometry extends Geometry {\n public constructor({\n order,\n rotateUV\n }: {\n order: string;\n rotateUV?: ROTATE[]\n }) {\n const vertices = [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // up\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // down\n -1, -1, 1,\n 1, -1, 1,\n 1, -1, -1,\n -1, -1, -1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n\n const indicies = [\n 0, 1, 2,\n 0, 2, 3,\n 4, 5, 6,\n 4, 6, 7,\n 8, 9, 10,\n 8, 10, 11,\n 12, 13, 14,\n 12, 14, 15,\n 16, 17, 18,\n 16, 18, 19,\n 20, 21, 22,\n 20, 22, 23\n ];\n\n const oneThird = 1 / 3;\n const coords: number[][] = [];\n\n for (let r = 1; r >= 0; r--) {\n for (let c = 0; c < 3; c++) {\n const coord = [\n c * oneThird, r * 0.5,\n (c + 1) * oneThird, r * 0.5,\n (c + 1) * oneThird, (r + 1) * 0.5,\n c * oneThird, (r + 1) * 0.5\n ];\n\n coords.push(coord);\n }\n }\n\n if (rotateUV) {\n rotateUV.forEach((degree, idx) => {\n if (degree === ROTATE.ZERO) return;\n\n const coord = coords[idx];\n let newOrder: number[];\n\n if (degree === ROTATE.CW_90) {\n newOrder = [1, 2, 3, 0];\n } else if (degree === ROTATE.CCW_90) {\n newOrder = [3, 0, 1, 2];\n } else {\n newOrder = [2, 3, 0, 1];\n }\n\n const newCoords = Array(coord.length);\n for (let uvIdx = 0; uvIdx < coord.length / 2; uvIdx++) {\n newCoords[uvIdx * 2 + 0] = coord[newOrder[uvIdx] * 2 + 0];\n newCoords[uvIdx * 2 + 1] = coord[newOrder[uvIdx] * 2 + 1];\n }\n\n coords[idx] = newCoords;\n });\n }\n\n const uvs = reorderCube(coords, order, \"BFUDRL\")\n .reduce((acc, val) => acc.concat(val), []);\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default CubeGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"../texture/Texture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformTexture2D extends Uniform {\n public readonly texture: Texture2D;\n private _webglTexture: WebGLTexture;\n\n public constructor(ctx: WebGLContext, texture: Texture2D) {\n super();\n\n this.texture = texture;\n this._webglTexture = ctx.createWebGLTexture(texture);\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext): void {\n this.texture.destroy();\n gl.deleteTexture(this._webglTexture);\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n const isVideo = texture.isVideo();\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._webglTexture);\n\n if (!isVideo && isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n } else {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n }\n\n if (!isVideo) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformTexture2D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass CylinderGeometry extends Geometry {\n public constructor(maxTheta: number) {\n const vertices: number[] = [];\n const indicies: number[] = [];\n const uvs: number[] = [];\n\n const height = 1;\n const radialSegments = 60;\n const halfHeight = height * 0.5;\n const heightSegments = [-halfHeight, halfHeight];\n const invRadialSegments = 1 / radialSegments;\n const angleConst = maxTheta * invRadialSegments;\n\n for (let yIdx = 0; yIdx < 2; yIdx++) {\n const y = heightSegments[yIdx];\n\n for (let lngIdx = 0; lngIdx <= radialSegments; lngIdx++) {\n const angle = lngIdx * angleConst + Math.PI - maxTheta * 0.5;\n const x = Math.cos(angle);\n const z = Math.sin(angle);\n const u = lngIdx * invRadialSegments;\n const v = yIdx;\n\n uvs.push(u, v);\n vertices.push(x, y, z);\n\n if (yIdx === 0 && lngIdx < radialSegments) {\n const a = lngIdx;\n const b = a + radialSegments + 1;\n\n indicies.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n }\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default CylinderGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass SphereGeometry extends Geometry {\n /** */\n public constructor() {\n // const radius = 1;\n const widthSegments = 60;\n const heightSegments = 60;\n const ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI;\n\n const uvs: number[] = [];\n const vertices: number[] = [];\n const indicies: number[] = [];\n let latIdx: number;\n let lngIdx: number;\n\n for (latIdx = 0; latIdx <= widthSegments; latIdx++) {\n const theta = (latIdx / widthSegments - 0.5) * Math.PI;\n const sinTheta = Math.sin(theta);\n const cosTheta = Math.cos(theta);\n\n for (lngIdx = 0; lngIdx <= heightSegments; lngIdx++) {\n const phi = (lngIdx / heightSegments - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN;\n const sinPhi = Math.sin(phi);\n const cosPhi = Math.cos(phi);\n const x = cosPhi * cosTheta;\n const y = sinTheta;\n const z = sinPhi * cosTheta;\n const u = lngIdx / heightSegments;\n const v = latIdx / widthSegments;\n\n uvs.push(u, v);\n vertices.push(x, y, z);\n\n if (lngIdx !== heightSegments && latIdx !== widthSegments) {\n const a = latIdx * (heightSegments + 1) + lngIdx;\n const b = a + heightSegments + 1;\n\n indicies.push(a, a + 1, b, b, a + 1, b + 1);\n }\n }\n }\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default SphereGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"./Uniform\";\n\nclass UniformFloat extends Uniform {\n public val: number;\n\n public constructor(val: number) {\n super();\n\n this.val = val;\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation) {\n gl.uniform1f(location, this.val);\n\n this.needsUpdate = false;\n }\n}\n\nexport default UniformFloat;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass PlaneGeometry extends Geometry {\n /** */\n public constructor(width: number = 2, height: number = 2, z: number = -1) {\n const halfWidth = width * 0.5;\n const halfHeight = height * 0.5;\n const vertices = [\n -halfWidth, -halfHeight, z,\n halfWidth, -halfHeight, z,\n -halfWidth, halfHeight, z,\n halfWidth, halfHeight, z\n ];\n const indicies = [\n 0, 1, 2,\n 2, 1, 3\n ];\n const uvs = [\n 0, 0,\n 1, 0,\n 0, 1,\n 1, 1\n ];\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default PlaneGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"./Uniform\";\n\nclass UniformVector4Array extends Uniform {\n public val: number[][];\n\n public constructor(val: number[][]) {\n super();\n\n this.val = val;\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation) {\n gl.uniform4fv(location, this.val.reduce((arr, vector) => [...arr, ...vector], []));\n\n this.needsUpdate = false;\n }\n}\n\nexport default UniformVector4Array;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport SphereGeometry from \"../geometry/SphereGeometry\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport UniformVector4Array from \"../uniform/UniformVector4Array\";\nimport UniformFloat from \"../uniform/UniformFloat\";\nimport vs from \"../shader/stereoequi.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link StereoEquiProjection}\n * @ko {@link StereoEquiProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface StereoEquiProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n /**\n * Stereoscopic mode of the image\n * @ko 이미지의 스테레오스코픽 모드\n * @since 4.0.0\n * @default \"top_bottom\"\n */\n mode: typeof StereoEquiProjection.MODE[keyof typeof StereoEquiProjection.MODE]\n}\n\n/**\n * Projection based on stereo equirectangular images.\n * @ko Stereo equirectangular 이미지 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass StereoEquiProjection extends Projection<{\n uTexture: UniformTexture2D;\n uEye: UniformFloat;\n uTexScaleOffset: UniformVector4Array;\n}> {\n /**\n * Available stereoscopic modes\n * @ko 사용가능한 스테레오스코픽 모드들\n * @since 4.0.0\n */\n public static MODE = {\n /**\n * @ko 이미지가 왼쪽/오른쪽으로 구성되어있을 경우\n * @since 4.0.0\n */\n LEFT_RIGHT: \"left_right\",\n /**\n * @ko 이미지가 위/아래로 구성되어있을 경우\n * @since 4.0.0\n */\n TOP_BOTTOM: \"top_bottom\",\n } as const;\n\n private _mode: StereoEquiProjectionOptions[\"mode\"];\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: StereoEquiProjectionOptions) {\n super(options);\n\n this._mode = options.mode;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n let leftEye: number[];\n let rightEye: number[];\n\n switch (this._mode) {\n case StereoEquiProjection.MODE.LEFT_RIGHT:\n leftEye = [0.5, 1, 0, 0];\n rightEye = [0.5, 1, 0.5, 0];\n break;\n default:\n // Default, uses \"top_bottom\"\n leftEye = [1, 0.5, 0, 0];\n rightEye = [1, 0.5, 0, 0.5];\n }\n\n\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture),\n uEye: new UniformFloat(0),\n uTexScaleOffset: new UniformVector4Array([leftEye, rightEye])\n };\n\n const geometry = new SphereGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default StereoEquiProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTextureCube from \"../uniform/UniformTextureCube\";\nimport UniformCanvasCube from \"../uniform/UniformCanvasCube\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport TextureCube from \"../texture/TextureCube\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/cube.vert\";\nimport fs from \"../shader/cube.frag\";\n\n/**\n * Options for {@link CubemapProjection}\n * @ko {@link CubemapProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CubemapProjectionOptions extends ProjectionOptions {\n /**\n * Order of the cubemap images.\n * @ko 큐브맵 이미지의 순서.\n * @since 4.0.0\n * @default \"RLUDFB\" (Right - Left - Up - Down - Front - Back)\n */\n cubemapOrder?: string;\n /**\n * Whether to flip cubemap image horizontally.\n * @ko 큐브맵 이미지를 좌우대칭할지 여부.\n * @since 4.0.0\n * @default false\n */\n cubemapFlipX?: boolean;\n}\n\n/**\n * Projection based on cubemap images, accepts both multiple or single images.\n * @ko 큐브맵 이미지 기반의 프로젝션, 단일 혹은 여러 장의 이미지를 모두 사용 가능합니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CubemapProjection extends Projection<{\n uTexture: UniformTextureCube | UniformCanvasCube;\n}> {\n private _cubemapOrder: NonNullable;\n private _cubemapFlipX: NonNullable;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CubemapProjectionOptions) {\n super(options);\n\n const {\n cubemapOrder = \"RLUDFB\",\n cubemapFlipX = false\n } = options;\n\n this._cubemapOrder = cubemapOrder;\n this._cubemapFlipX = cubemapFlipX;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const cubemapOrder = this._cubemapOrder;\n const cubemapFlipX = this._cubemapFlipX;\n const uniforms = {\n uTexture: texture.isCube()\n ? new UniformTextureCube(ctx, texture as TextureCube, cubemapOrder)\n : new UniformCanvasCube(ctx, texture as Texture2D, cubemapOrder)\n };\n\n const geometry = new CubeGeometry({\n order: cubemapOrder\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n if (cubemapFlipX) {\n mesh.scale[0] = -1;\n }\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n}\n\nexport default CubemapProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link CubestripProjection}\n * @ko {@link CubestripProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CubestripProjectionOptions extends ProjectionOptions {\n /**\n * @copy CubemapProjectionOptions#cubemapOrder\n */\n cubemapOrder?: string;\n /**\n * @copy CubemapProjectionOptions#cubemapFlipX\n */\n cubemapFlipX?: boolean;\n}\n\n/**\n * Projection based on cubemap strip.\n * Slightly more efficient than {@link CubemapProjection} as it doesn't copy cubemap image to canvas while rendering.\n * Accepts only single image.\n * @ko 큐브맵 스트립 기반의 프로젝션.\n * {@link CubemapProjection}와 달리 렌더링하는 과정에 캔버스에 이미지를 복사하는 과정이 없기 때문에 살짝 더 효율적입니다.\n * 단일 이미지만 사용 가능합니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CubestripProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n private _cubemapOrder: NonNullable;\n private _cubemapFlipX: NonNullable;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CubestripProjectionOptions) {\n super(options);\n\n const {\n cubemapOrder = \"RLUDFB\",\n cubemapFlipX = false\n } = options;\n\n this._cubemapOrder = cubemapOrder;\n this._cubemapFlipX = cubemapFlipX;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const cubemapOrder = this._cubemapOrder;\n const cubemapFlipX = this._cubemapFlipX;\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n const geometry = new CubeGeometry({\n order: cubemapOrder\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n if (cubemapFlipX) {\n mesh.scale[0] = -1;\n }\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n}\n\nexport default CubestripProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n*/\nimport { quat } from \"gl-matrix\";\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport CylinderGeometry from \"../geometry/CylinderGeometry\";\nimport Camera from \"../core/Camera\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"../const/internal\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\nimport TriangleMesh from \"../core/TriangleMesh\";\n\n/**\n * Options for {@link CylindricalProjection}\n * @ko {@link CylindricalProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CylindricalProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n /**\n * Whether the panorama image covers full 360 degrees.\n * @ko 파노라마 이미지가 360도를 전부 커버하는지 여부\n * @since 4.0.0\n * @default false\n */\n partial?: boolean;\n}\n\n/**\n * Projection based on cylindrical projection.\n * This can show panorama images taken from smartphones.\n * @ko 원통 투영법 기반의 프로젝션.\n * 일반적인 스마트폰 파노라마 사진을 표시하는데 사용될 수 있습니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CylindricalProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n private _partial: boolean;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CylindricalProjectionOptions) {\n super(options);\n\n const {\n partial = false\n } = options;\n\n this._partial = partial;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const partial = this._partial;\n const { width, height } = texture;\n const aspect = width / height;\n const halfVFov = 180 / aspect;\n const cylinderHeight = partial\n ? 1\n : 2 * Math.tan(halfVFov * DEG_TO_RAD);\n const cylinderTheta = partial\n ? aspect\n : 2 * Math.PI;\n\n const geometry = new CylinderGeometry(cylinderTheta);\n const program = new ShaderProgram(ctx, vs, fs, {\n uTexture: new UniformTexture2D(ctx, texture)\n });\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n mesh.scale[1] = cylinderHeight;\n quat.identity(mesh.rotation);\n quat.rotateY(mesh.rotation, mesh.rotation, -Math.PI / 2);\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n\n public updateCamera(camera: Camera) {\n super.updateCamera(camera);\n\n const mesh = this._mesh;\n if (!mesh) return;\n\n const uTexture = mesh.program.uniforms.uTexture;\n const texture = uTexture.texture;\n const { width, height } = texture;\n const aspect = width / height;\n const halfHeight = mesh.scale[1] * 0.5;\n\n if (this._partial) {\n const restrictedYaw = 0.5 * aspect * RAD_TO_DEG;\n camera.restrictYawRange(-restrictedYaw, restrictedYaw);\n }\n\n const restrictedPitch = Math.atan2(halfHeight, 1) * RAD_TO_DEG;\n const minZoom = Math.tan(camera.fov * DEG_TO_RAD * 0.5) / (halfHeight * camera.aspect);\n\n camera.restrictPitchRange(-restrictedPitch, restrictedPitch);\n camera.restrictZoomRange(minZoom, Infinity);\n camera.restrictRenderHeight(halfHeight * 2);\n }\n}\n\nexport default CylindricalProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/eac.frag\";\nimport { ROTATE } from \"../const/internal\";\n\n/**\n * Options for {@link EquiangularProjection}\n * @ko {@link EquiangularProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface EquiangularProjectionOptions extends ProjectionOptions {}\n\n/**\n * Equi-Angular Cubemap Projection.\n * This format is used by Youtube's 360 videos.\n * @ko Equi-Angular Cubemap 프로젝션.\n * 이 포맷은 주로 Youtube의 360 비디오에 사용됩니다.\n * @since 4.0.0\n * @category Projection\n */\nclass EquiangularProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n const geometry = new CubeGeometry({\n order: \"LFRDBU\",\n rotateUV: [\n ROTATE.ZERO, ROTATE.ZERO, ROTATE.ZERO,\n ROTATE.CW_90, ROTATE.CCW_90, ROTATE.CW_90\n ]\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default EquiangularProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport Texture2D from \"../texture/Texture2D\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport SphereGeometry from \"../geometry/SphereGeometry\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link EquirectProjection}\n * @ko {@link EquirectProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface EquirectProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n}\n\n/**\n * Projection based on equirectangular projection.\n * @ko 등 장방형 도법(Equirectangular projection) 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass EquirectProjection extends Projection<{\n uTexture: UniformTexture2D\n}> {\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: EquirectProjectionOptions) {\n super(options);\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n\n const geometry = new SphereGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default EquirectProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport UniformFloat from \"../uniform/UniformFloat\";\nimport Camera from \"../core/Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport Texture2D from \"../texture/Texture2D\";\nimport PlaneGeometry from \"../geometry/PlaneGeometry\";\nimport vs from \"../shader/little-planet.vert\";\nimport fs from \"../shader/little-planet.frag\";\nimport TriangleMesh from \"../core/TriangleMesh\";\n\n/**\n * Options for {@link LittlePlanetProjection}\n * @ko {@link LittlePlanetProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface LittlePlanetProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n}\n\n/**\n * Projection based on so-called \"Little planet\" or \"Tiny planet\" effect.\n * @ko \"Little planet\" 혹은 \"Tiny planet\"로 불리는 이펙트 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass LittlePlanetProjection extends Projection<{\n uTexture: UniformTexture2D;\n uYaw: UniformFloat;\n uPitch: UniformFloat;\n uZoom: UniformFloat;\n}> {\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: LittlePlanetProjectionOptions) {\n super(options);\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n texture.wrapS = WebGLRenderingContext.REPEAT;\n texture.wrapT = WebGLRenderingContext.REPEAT;\n\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture),\n uYaw: new UniformFloat(0),\n uPitch: new UniformFloat(0.5),\n uZoom: new UniformFloat(1)\n };\n\n const geometry = new PlaneGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n\n public updateControl(control: PanoControl) {\n control.ignoreZoomScale = true;\n }\n\n public update(camera: Camera) {\n const mesh = this._mesh;\n if (!mesh) return;\n\n const uniforms = mesh.program.uniforms;\n\n uniforms.uYaw.val = camera.yaw / 360;\n // Range from 0 ~ 1\n uniforms.uPitch.val = (camera.pitch / 180) + 0.5;\n uniforms.uZoom.val = camera.zoom;\n\n uniforms.uYaw.needsUpdate = true;\n uniforms.uPitch.needsUpdate = true;\n uniforms.uZoom.needsUpdate = true;\n }\n}\n\nexport default LittlePlanetProjection;\n","/**\n * @hidden\n */\nexport const getValidProps = (propsObj: any) => {\n return Object.keys(propsObj).reduce((props, propName) => {\n if (propsObj[propName] != null) {\n props[propName] = propsObj[propName];\n }\n\n return props;\n }, {});\n};\n","export const VIEW360_METHODS = [\n \"destroy\",\n \"init\",\n \"load\",\n \"resize\",\n \"addPlugins\",\n \"removePlugins\",\n \"renderFrame\",\n // @egjs/component methods\n \"on\",\n \"hasOn\",\n \"once\",\n \"off\",\n \"trigger\"\n] as const;\n","import Component from \"@egjs/component\";\nimport View360 from \"../View360\";\n\n/**\n * @hidden\n */\nconst withMethods = (prototype: any, attr: string) => {\n [Component.prototype, View360.prototype].forEach(proto => {\n Object.getOwnPropertyNames(proto)\n .filter(name => name.charAt(0) !== \"_\" && name !== \"constructor\")\n .forEach((name: string) => {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name)!;\n\n if (descriptor.value) {\n // Public Function\n Object.defineProperty(prototype, name, {\n value: function(...args) {\n return descriptor.value.call(this[attr], ...args);\n }\n });\n } else {\n const getterDescriptor: { get?: () => any; set?: (val: any) => void } = {};\n if (descriptor.get) {\n getterDescriptor.get = function() {\n return this[attr] && descriptor.get?.call(this[attr]);\n };\n }\n if (descriptor.set) {\n getterDescriptor.set = function(...args) {\n return descriptor.set?.call(this[attr], ...args);\n };\n }\n\n Object.defineProperty(prototype, name, getterDescriptor);\n }\n });\n });\n};\n\nexport default withMethods;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360, * as modules from \"./index\";\nimport { merge } from \"./utils\";\n\nmerge(View360, modules);\n\nexport default View360;\n"],"names":["View360Error","Error","constructor","message","code","super","Object","setPrototypeOf","this","prototype","name","ERROR_CODES","WRONG_TYPE","WRONG_OPTION","ELEMENT_NOT_FOUND","CANVAS_NOT_FOUND","WEBGL_NOT_SUPPORTED","FAILED_CREATE_CONTEXT_2D","PROVIDE_PROJECTION_FIRST","FAILED_LINKING_PROGRAM","INSUFFICIENT_ARGS","ERROR","val","types","map","type","join","optionName","query","msg","shaderLog","EVENTS","EL_DIV","EL_BUTTON","MOUSE_BUTTON","CURSOR","KEY_DIRECTION","DIRECTION_KEY_CODE","DIRECTION_KEY_NAME","LEFT","UP","RIGHT","DOWN","FULLSCREEN_REQUEST","FULLSCREEN_ELEMENT","FULLSCREEN_EXIT","FULLSCREEN_CHANGE","DEFAULT_CLASS","CONTAINER","CANVAS","CTX_LOST","IN_VR","HOTSPOT_CONTAINER","HOTSPOT","HOTSPOT_VISIBLE","HOTSPOT_FLIP_X","HOTSPOT_FLIP_Y","READY","LOAD_START","LOAD","PROJECTION_CHANGE","RESIZE","BEFORE_RENDER","RENDER","INPUT_START","INPUT_END","VIEW_CHANGE","STATIC_CLICK","VR_START","VR_END","EASING","LINEAR","x","SINE_WAVE","Math","sin","PI","EASE_OUT_CUBIC","pow","EASE_OUT_BOUNCE","n1","d1","CAMERA_EVENTS","CONTROL_EVENTS","DEG_TO_RAD","RAD_TO_DEG","DEFAULT_EASING","DEFAULT_ANIMATION_DURATION","INFINITE_RANGE","min","Infinity","max","DEFAULT_PITCH_RANGE","DEFAULT_ZOOM_RANGE","ROTATE","VIDEO_TIME_CHANGE_EVENT","SVG_NAMESPACE","SESSION_VR","XR_REFERENCE_SPACE","EPSILON","_a","Number","isString","createElement","className","tag","BROWSER","el","document","classList","add","getNullableElement","parent","targetEl","queryResult","querySelector","nodeType","Node","ELEMENT_NODE","clamp","lerp","a","b","t","circulate","size","abs","findIndex","array","checker","idx","length","getObjectOption","toVerticalFov","fovRadian","aspect","atan","tan","reorderCube","arr","order","defaultOrder","split","face","indexOf","index","isFullscreen","key","sensorCanBeEnabledIOS","DeviceMotionEvent","window","isSecureContext","eulerToQuat","out","yaw","pitch","roll","quat","pitchClamped","quatToEuler","quaternion","y","z","w","unit","test","atan2","view","vec3","up","viewXZ","sqrt","Motion","_val","start","_start","end","_end","progress","_progress","activated","_activated","duration","_duration","loop","_loop","range","_range","easing","_easing","reset","update","deltaTime","prev","nextProgress","easedProgress","defaultVal","delta","setNewEndByDelta","setRange","CameraAnimation","_motion","camera","from","to","_camera","_from","_to","_finishPromise","Promise","resolve","_finish","getFinishPromise","motion","rotation","zoom","rotate","Camera","Component","_aspect","changed","_changed","yawRange","_initialYawRange","pitchRange","_initialPitchRange","zoomRange","_initialZoomRange","initialYaw","initialPitch","initialZoom","fov","rollOffset","position","animation","_up","_yawRange","_pitchRange","_zoomRange","_updateQuaternion","viewMatrix","mat4","projectionMatrix","_maxRenderHeight","destroy","off","resize","width","height","prevAspect","updateMatrix","lookAt","prevQuaternion","prevZoom","zoomDiff","normalized","isSameRotation","animateTo","finishPromise","then","trigger","restrictYawRange","restrictPitchRange","restrictZoomRange","restrictRenderHeight","resetRange","getYawRange","yawLimit","maxRenderHeight","halfHFov","getHorizontalFov","minYaw","maxYaw","halfVFovRad","h","d","theta","getPitchRange","pitchLimit","minPitch","maxPitch","halfVFov","getVerticalFov","getZoomRange","limit","minFov","maxFov","currentFov","current","_getZoomedHorizontalFov","hFov","fovToZoom","baseFov","projMatrix","upDir","viewDir","vFov","onFrameRender","MouseInput","_onMouseDown","evt","_el","button","preventDefault","focus","_prevPos","clientX","clientY","addEventListener","_onMouseMove","_onMouseUp","srcEvent","isTouch","isKeyboard","prevPos","deltaX","deltaY","removeEventListener","scrolling","enable","element","disable","TouchInput","scrollable","_scrollable","_onTouchStart","touches","_scrolling","touch","_isFirstTouch","_onTouchMove","cancelable","_onTouchEnd","passive","KeyboardInput","active","pressed","_pressed","_onKeyDown","location","KeyboardEvent","DOM_KEY_LOCATION_STANDARD","_updateKeyPress","pressedCount","_getPressedKeyCount","repeat","_onKeyUp","_clearPressedKeys","_getDeltaByPressedKeys","reduce","obj","keyName","assign","event","isEnable","keyToUpdate","keyCode","filter","RotateControl","enabled","_enabled","enableBlocked","_enableBlocked","animating","_keyboardInput","_xMotion","_yMotion","_touchInput","pointerScale","_pointerScale","keyboardScale","_keyboardScale","disablePitch","_disablePitch","disableYaw","_disableYaw","disableKeyboard","_disableKeyboard","controlEl","_onInputStart","_changedWhileDragging","inputType","_onChange","invZoomScale","_zoomScale","screenScale","_screenScale","scale","scaledX","scaledY","_onInputEnd","_controlEl","_mouseInput","_bindInputs","xMotion","yMotion","keyboardInput","updateRange","setZoomScale","hfov","vfov","control","updateCursor","sync","mouseInput","touchInput","on","WheelInput","_onWheel","stopPropagation","_inputTimer","_clearTimer","_baseScale","setTimeout","capture","clearTimeout","PinchInput","prevDistance","_prevDistance","diff","pageX","pageY","distance","ZoomControl","_wheelInput","_scale","scaledDelta","_pinchInput","wheelInput","pinchInput","ROTATE_CONSTANT","PITCH_DELTA","YAW_DELTA_BY_ROLL","YAW_DELTA_BY_YAW","targetAxis","meshPoint","GyroInput","orientationUpdated","_orientationUpdated","ignoreRoll","_ignoreRoll","_onDeviceOrientation","prevOrientation","_orientation","alpha","beta","gamma","_needsCalibrate","_calibrateSensor","_updateScreenOrientation","screen","orientation","undefined","angle","_screenOrientation","_yawOrigin","_yawOffset","_updateRotation","collectDelta","prevRotation","_toEulerDelta","setInitialRotation","yawOrigin","sensorYaw","screenAngle","world","cos","prevQuat","currentQuat","_getDeltaYaw","_getDeltaPitch","prvQ","curQ","yawDeltaByYaw","_getRotationDelta","_extractPitchFromQuat","prevQ","rotateKind","curQuaternion","prevPoint","curPoint","rotateDirection","meshPoint2","meshPoint3","vecU","vecV","vecN","coefficientA","coefficientB","coefficientC","projectedPrevPoint","trigonometricRatio","acos","crossVec","thetaDirection","baseV","GyroControl","_input","static","onDeviceMotionChange","race","res","rotationRate","available","requestPermission","permissionState","catch","_updateYawPitch","input","yawDelta","pitchDelta","PanoControl","useGrabCursor","_useGrabCursor","_setCursor","disableContextMenu","_disableContextMenu","_blockContextMenu","_restoreContextMenu","_rotateControl","wheelScrollable","_zoomControl","ignoreZoomScale","_ignoreZoomScale","gyro","_gyroControl","_preventContextMenu","_onEnable","_onDisable","_onCameraAnimationEnd","_bindEvents","isAvailable","rotateControl","zoomControl","gyroControl","hfovToZoom","zoomScale","newCursor","style","cursor","Texture","flipY","wrapS","WebGLRenderingContext","CLAMP_TO_EDGE","wrapT","isVideo","isCube","Texture2D","source","TextureVideo","video","pause","removeAttribute","load","isPaused","paused","ended","readyState","hasAudio","audioTracks","webkitAudioDecodedByteCount","mozHasAudio","TextureCube","sources","TextureLoader","_loadChecker","ImReady","src","loadVideo","Array","isArray","loadCubeImage","imgSrc","loadImage","images","_toImageArray","_load","image","naturalWidth","naturalHeight","videoConfig","config","autoplay","muted","volume","_toVideoElement","currentTime","play","videoWidth","videoHeight","content","onLoad","loader","reject","once","errorCount","check","imgEl","Image","crossOrigin","HTMLVideoElement","playsInline","setAttribute","forEach","_appendSourceElement","querySelectorAll","HTMLSourceElement","sourceEl","appendChild","FrameAnimator","maxDeltaTime","context","_context","_rafId","_rafTimer","_lastUpdateTime","callback","_time","frame","time","Date","now","requestAnimationFrame","stop","cancelAnimationFrame","changeContext","AutoResizer","useResizeObserver","_useResizeObserver","onResize","_skipFirstResize","isFirstResize","_onResize","_resizeObserver","ResizeObserver","bbox","getBoundingClientRect","resizeImmediate","resizeObserver","observe","disconnect","Autoplay","playing","_interrupted","delay","_delay","delayOnMouseLeave","_delayOnMouseLeave","speed","_speed","pauseOnHover","_pauseOnHover","canInterrupt","_canInterrupt","disableOnInterrupt","_disableOnInterrupt","viewer","options","_clearTimeout","_setUninterruptedAfterDelay","_onGyroEnable","_onMouseEnter","_hovering","_onMouseLeave","_control","_element","_interruptionTimer","enableAfterDelay","XRManager","ctx","exit","_onSessionEnd","_xrSession","_xrRefSpace","_ctx","_options","xr","navigator","isSessionSupported","enter","requestSensorPermission","requiredFeatures","makeXRCompatible","session","requestSession","bindXRLayer","refSpace","requestReferenceSpace","_setSession","xrSession","canRender","getViewerPose","getEyeParams","pose","glLayer","renderState","baseLayer","views","viewport","getViewport","vMatrix","transform","inverse","matrix","pMatrix","Hotspot","HotspotRenderer","rootEl","renderer","_containerEl","_renderer","_hotspots","_zoom","refresh","container","hotspotEls","slice","apply","_parseHotspot","render","hotspots","halfWidth","halfHeight","centerTransform","zoomTransform","hotspot","relPos","remove","screenPos","vec2","yawStr","dataset","pitchStr","positionStr","parseFloat","_yawPitchToVec3","pos","defaultPos","yawRad","pitchRad","VertexArrayObject","count","geometry","indicies","buffers","WebGLContext","canvas","_canvas","maxTextureSize","_maxTextureSize","isWebGL2","_isWebGL2","supportVAO","_extensions","vao","lost","_contextLost","debug","_debug","_onContextLost","_onContextRestore","loseContext","init","gl","_getContext","_gl","getParameter","MAX_TEXTURE_SIZE","getExtension","bindBuffer","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","forceLoseContext","extension","forceRestoreContext","restoreContext","clear","COLOR_BUFFER_BIT","drawingBufferWidth","drawingBufferHeight","createVAO","shaderProgram","nativeVAO","_createNativeVAO","_createBuffer","uv","_bindNativeVAO","_supplyGeometryData","_unbindBuffers","draw","drawElements","TRIANGLES","UNSIGNED_SHORT","releaseVAO","_deleteNativeVAO","_deleteBuffer","getUniformLocations","program","uniforms","uniformLocations","keys","locations","getUniformLocation","_getCommonUniformLocations","updateCommonUniforms","entity","mvMatrix","uniformMatrix4fv","uMVMatrix","uPMatrix","updateVRUniforms","eyeIndex","uEye","uniform1f","updateUniforms","uniform","needsUpdate","releaseShaderResources","deleteProgram","useProgram","createProgram","vertexShader","fragmentShader","vs","_compileShader","VERTEX_SHADER","fs","FRAGMENT_SHADER","attachShader","bindAttribLocation","linkProgram","getProgramParameter","LINK_STATUS","getShaderParameter","COMPILE_STATUS","getShaderInfoLog","getProgramInfoLog","deleteShader","createWebGLTexture","texData","texture","createTexture","bindTexture","TEXTURE_2D","texParameteri","TEXTURE_MIN_FILTER","TEXTURE_MAG_FILTER","TEXTURE_WRAP_S","TEXTURE_WRAP_T","gl2","texStorage2D","RGBA8","createWebGLCubeTexture","TEXTURE_CUBE_MAP","attributes","getContextAttributes","xrCompatible","xrLayer","XRWebGLLayer","updateRenderState","bindXRFrame","bindFramebuffer","FRAMEBUFFER","framebuffer","useDefaultFrameBuffer","createBuffer","buffer","deleteBuffer","createVertexArray","ext","createVertexArrayOES","bindVertexArray","bindVertexArrayOES","deleteVertexArray","deleteVertexArrayOES","_supplyIndiciesData","_supplyAttributeData","vertices","uvs","bufferData","data","STATIC_DRAW","attribute","attribLocation","getAttribLocation","vertexAttribPointer","itemSize","FLOAT","enableVertexAttribArray","shader","createShader","shaderSource","compileShader","webglIdentifiers","contextAttributes","preserveDrawingBuffer","antialias","onWebglContextCreationError","e","statusMessage","identifier","getContext","WebGLRenderer","_elementSize","pixelRatio","_pixelRatio","canvasSize","devicePixelRatio","clientWidth","clientHeight","projection","mesh","getMesh","renderVR","vr","eyeParams","eye","View360","_rootEl","_vr","_hotspot","plugins","_plugins","_projection","_initialized","initialized","_autoplay","autoInit","_autoInit","autoResize","_autoResize","canvasSelector","_canvasSelector","tabIndex","_tabIndex","_animator","updateCamera","root","renderFrame","autoPlayer","_emit","_renderFrameOnDemand","getTexture","_renderVRFrame","_delta","getElement","findCanvas","selector","_autoResizer","_addEventHandlers","releaseAllResources","plugin","animator","_bindComponentEvents","_resizeComponents","_loadTexture","_applyProjection","hasAttribute","addPlugins","push","removePlugins","pluginIdx","splice","eventName","params","evtParams","target","prevProjection","applyTexture","updateControl","contentLoader","events","evtName","VERSION","Object3D","LoadingSpinner","_startLoading","_container","_detachElements","parentElement","removeChild","_createElements","ring","RING","ControlBarItem","CONTROL_BAR_DEFAULT_CLASS","CONTROLS_ROOT","CONTROLS_BG","CONTROLS_MAIN","CONTROLS_TOP","CONTROLS_BOTTOM","CONTROLS_MID","CONTROLS_LEFT","CONTROLS_RIGHT","CONTROLS_FLOAT_LEFT","CONTROLS_FLOAT_RIGHT","CONTROLS_BUTTON","PROGRESS_ROOT","VOLUME_ROOT","RANGE_ROOT","RANGE_TRACK","RANGE_THUMB","RANGE_FILLER","PLAY_BUTTON","PAUSE_BUTTON","UNMUTED_BUTTON","MUTED_BUTTON","FULLSCREEN_BUTTON","FULLSCREEN_EXIT_BUTTON","VR_BUTTON","GYRO_ENABLED","GYRO_DISABLED","VIDEO_TIME_DISPLAY","PIEVIEW_ROOT","FIXED","UNAVAILABLE","HIDDEN","CONTROL_BAR_ITEM_POSITION","TOP_LEFT","TOP_RIGHT","MAIN_TOP","MAIN_BOTTOM","MAIN_LEFT","MAIN_RIGHT","RangeControl","_onHold","_bbox","elX","scrollX","pageXOffset","clamepdX","thumbEl","_fixedClass","_onRelease","track","thumb","filler","draggable","trackEl","fillerEl","left","right","bottom","top","updateStyle","clampedProgress","ProgressBar","_rangeControl","_onTimeUpdate","_video","_currentTime","_onDurationChange","controlBar","_controlBar","dispatchEvent","CustomEvent","detail","_wasPaused","_playPromise","_onControl","rangeControl","unavailableClass","PlayButton","_onClick","_paused","_onPlay","title","_onPause","VolumeControl","_updateDisplay","disabled","_onVolumeChange","_buttonEl","containerEl","buttonEl","FullscreenButton","_targetEl","_exitFullscreen","_requestFullscreen","_onFullscreenChange","_fullscreenAvailable","_addFullscreenHandlers","_removeFullscreenHandlers","some","request","call","VideoTime","_onCustomTimeChange","timeMinute","floor","timeSeconds","timeSecondsFormatted","durationMinute","durationSeconds","durationSecondsFormatted","innerText","PieView","resetCamera","_viewer","_updatePie","piePath","_piePathEl","rangeCircle","_rangeCircleEl","halfFov","pieRadius","pieDeg","pieOffset","isFinite","radius","rangeDiff","offset","_createPieElements","rootClass","pieSVG","createElementNS","VRButton","GyroButton","_updateStyle","enableButton","AutoHide","hidden","contains","_hiddenClass","initialDelay","idleDelay","activationDelay","_isCursorInside","show","_hideAfterDelay","_isFullscreen","showTemporaliy","_isGrabbing","pointerType","_onVideoPlay","_onVideoPause","_initialDelay","_idleDelay","_timer","hide","_clearHideTimer","VideoControl","videoEl","keyPressed","_changeVideoTime","_changeVideoVolume","_toggleVideo","forward","increase","ControlBar","backgroundEl","_bgEl","items","_items","customItems","_customItems","autoHide","showBackground","clickToPlay","keyboardControls","progressBar","playButton","volumeButton","fullscreenButton","videoTime","pieView","vrButton","gyroButton","_onStaticClick","autoHider","_autoHider","_onNewSrcLoad","_updateBackground","_updateAutoHide","_updateKeyboardHandler","item","_createPositionWrappers","POSITION","_videoControl","panoRoot","controlsRoot","defaultItems","_createDefaultItems","_addItem","_clearItemElements","category","wrapper","_wrapperEl","nextSiblingIndex","sibling","nextSibling","insertBefore","floatLeftEl","floatRightEl","topWrapper","bottomWrapper","midWrapper","leftControlsWrapper","rightControlsWrapper","firstChild","background","hiddenClass","_b","videoControl","Projection","_mesh","uTexture","Uniform","UniformTextureCube","cubemapOrder","_webglTexture","_cubemapOrder","deleteTexture","pixelStorei","UNPACK_FLIP_Y_WEBGL","uniform1i","activeTexture","TEXTURE0","texSubImage2D","TEXTURE_CUBE_MAP_POSITIVE_X","RGBA","UNSIGNED_BYTE","texImage2D","CubeTexturePainter","_size","_renderingOrder","undef","_calcRenderingSize","surfaceIdx","row","_row","column","_column","renderingFace","drawImage","UniformCanvasCube","_painter","TriangleMesh","ShaderProgram","VertexData","Geometry","Float32Array","Uint16Array","CubeGeometry","rotateUV","oneThird","coords","r","c","coord","degree","ZERO","newOrder","CW_90","CCW_90","newCoords","uvIdx","acc","concat","UniformTexture2D","CylinderGeometry","maxTheta","heightSegments","invRadialSegments","angleConst","yIdx","lngIdx","u","v","SphereGeometry","ANGLE_CORRECTION_FOR_CENTER_ALIGN","latIdx","sinTheta","cosTheta","phi","sinPhi","UniformFloat","PlaneGeometry","UniformVector4Array","uniform4fv","vector","StereoEquiProjection","_mode","mode","leftEye","rightEye","MODE","LEFT_RIGHT","uTexScaleOffset","TOP_BOTTOM","cubemapFlipX","_cubemapFlipX","partial","_partial","cylinderHeight","cylinderTheta","restrictedYaw","restrictedPitch","minZoom","REPEAT","uYaw","uPitch","uZoom","propsObj","props","propName","withMethods","attr","proto","getOwnPropertyNames","charAt","descriptor","getOwnPropertyDescriptor","value","defineProperty","args","getterDescriptor","get","set","merge","srcs","modules"],"mappings":";;;;;;;;;;;;;;gpNAUA,MAAMA,UAAqBC,MAczBC,YAAmBC,EAAiBC,GAClCC,MAAMF,GAENG,OAAOC,eAAeC,KAAMR,EAAaS,WAEzCD,KAAKE,KAAO,eACZF,KAAKJ,KAAOA,CACd,ECrBK,MAAMO,EAAc,CAMzBC,WAAY,EAMZC,aAAc,EAMdC,kBAAmB,EAMnBC,iBAAkB,EAMlBC,oBAAqB,EAMrBC,yBAA0B,EAM1BC,yBAA0B,EAM1BC,uBAAwB,EAMxBC,kBAAmB,GAeN,IAAAC,EACNV,EADMU,EAZS,CACtBT,WAAYA,CAACU,EAAUC,IAAuB,UAAOD,cAAgBC,EAAMC,KAAIC,GAAY,IAAAA,OAASC,KAAK,WACzGb,aAAcA,CAACS,EAAUK,IAA6C,sBAAAL,kBAAoBK,MAC1Fb,kBAAoBc,GAAkB,0BAA0BA,gBAChEb,iBAAkB,kEAClBC,oBAAqB,0CACrBC,yBAA0B,qCAC1BC,yBAA0B,yDAC1BC,uBAAwBA,CAACU,EAAoBC,IAAgE,mCAAAD,0BAA4BC,IACzIV,kBAAmBA,CAACE,EAAUZ,IAAmD,kCAAAY,WAAaZ,OCxEzF,MAAMqB,EACC,YADDA,EAEC,YAFDA,EAGD,UAHCA,EAIE,aAJFA,EAKC,YALDA,EAMA,WANAA,EAOJ,QAPIA,EAQH,SARGA,EASG,cATHA,EAUE,aAVFA,EAWE,aAXFA,EAkBD,UAlBCA,EAmBH,QAnBGA,EAsBJ,QAtBIA,EAwBW,4BAxBXA,GAyBG,mBAzBHA,GA0BO,uBA1BPA,GA2BS,oBA3BTA,GA4BI,eA5BJA,GA6BS,oBA7BTA,GA8BC,OA9BDA,GA+BE,QA/BFA,GAgCQ,aAhCRA,GAiCU,eAjCVA,GAkCQ,aAlCRA,GAmCY,iBAnCZA,GAoCY,iBApCZA,GAqCK,gBArCLA,GAsCH,MAGGC,GAAS,MACTC,GAAY,SAGzB,IAAYC,IAAZ,SAAYA,GACVA,EAAAA,EAAA,KAAA,GAAA,OACAA,EAAAA,EAAA,OAAA,GAAA,SACAA,EAAAA,EAAA,MAAA,GAAA,OACD,CAJD,CAAYA,KAAAA,GAIX,CAAA,IAEM,MAAMC,GACL,OADKA,GAED,WAFCA,GAGL,GAGKC,GAAgB,CAAC,OAAQ,KAAM,QAAS,QACrD,IAAYC,IAAZ,SAAYA,GACVA,EAAAA,EAAA,KAAA,IAAA,OACAA,EAAAA,EAAA,GAAA,IAAA,KACAA,EAAAA,EAAA,MAAA,IAAA,QACAA,EAAAA,EAAA,KAAA,IAAA,MACD,CALD,CAAYA,KAAAA,GAKX,CAAA,IACM,MAEMC,GAAqB,CAChCC,KAAM,YACNC,GAAI,UACJC,MAAO,aACPC,KAAM,aAIKC,GAAqB,CAChC,oBACA,0BACA,0BACA,yBACA,uBACA,uBAGWC,GAAqB,CAChC,oBACA,0BACA,iCACA,uBACA,uBAGWC,GAAkB,CAC7B,iBACA,uBACA,yBACA,sBACA,oBAGWC,GAAoB,CAC/B,mBACA,yBACA,sBACA,sBChGWC,GAAgB,CAC3BC,UAAW,oBACXC,OAAQ,iBACRC,SAAU,mBACVC,MAAO,wBACPC,kBAAmB,mBACnBC,QAAS,kBACTC,gBAAiB,0BACjBC,eAAgB,yBAChBC,eAAgB,0BAkBLzB,GAAS,CACpB0B,MAAO,QACPC,WAAY,YACZC,KAAM,OACNC,kBAAmB,mBACnBC,OAAQ,SACRC,cAAe,eACfC,OAAQ,SACRC,YAAa,aACbC,UAAW,WACXC,YAAa,aACbC,aAAc,cACdC,SAAU,UACVC,OAAQ,SAOGC,GAAS,CACpBC,OAASC,GAAcA,EACvBC,UAAYD,GAAcE,KAAKC,IAAIH,EAAIE,KAAKE,GAAK,GACjDC,eAAiBL,GAAc,EAAIE,KAAKI,IAAI,EAAIN,EAAG,GACnDO,gBAAkBP,IAChB,MAAMQ,EAAK,OACLC,EAAK,KAEX,OAAIT,EAAI,EAAIS,EACHD,EAAKR,EAAIA,EACPA,EAAI,EAAIS,EACVD,GAAMR,GAAK,IAAMS,GAAMT,EAAI,IACzBA,EAAI,IAAMS,EACZD,GAAMR,GAAK,KAAOS,GAAMT,EAAI,MAE5BQ,GAAMR,GAAK,MAAQS,GAAMT,EAAI,OACrC,UCnEE,MAAMU,GAEI,eAGJC,GACE,aADFA,GAEH,SAFGA,GAGA,WAHAA,GAIH,SAJGA,GAKF,UALEA,GAMG,cAGHC,GAAaV,KAAKE,GAAK,IACvBS,GAAa,IAAMX,KAAKE,GACxBU,GAAiBhB,GAAOO,eACxBU,GAA6B,IAC7BC,GAAkC,CAC7CC,KAAMC,IAAUC,IAAKD,KAEVE,GAAuC,CAClDH,KAAM,GAAIE,IAAK,IAEJE,GAAsC,CACjDJ,IAAK,GAAKE,IAAK,IAGjB,IAAYG,IAAZ,SAAYA,GACVA,EAAAA,EAAA,KAAA,GAAA,OACAA,EAAAA,EAAA,MAAA,GAAA,QACAA,EAAAA,EAAA,OAAA,GAAA,SACAA,EAAAA,EAAA,OAAA,GAAA,QACD,CALD,CAAYA,KAAAA,GAKX,CAAA,IAGM,MAAMC,GAA0B,yBAC1BC,GAAgB,6BAChBC,GAAa,eACbC,GAAqB,QAErBC,GAA4B,QAAlBC,GAAAC,OAAOF,eAAW,IAAAC,GAAAA,GAAA,qBCrC5BE,GAAYhF,GAA2C,iBAARA,EAG/CiF,GAAgBA,CAACC,EAAmBC,EAAMC,MACrD,MAAMC,EAAKC,SAASL,cAAcE,GAIlC,OAFAE,EAAGE,UAAUC,IAAIN,GAEVG,CAAE,EAGEI,GAAqBA,CAACJ,EAAiCK,KAClE,IAAIC,EAA+B,KAEnC,GAAIX,GAASK,GAAK,CAChB,MACMO,GADWF,GAAkBJ,UACNO,cAAcR,GAE3C,IAAKO,EACH,OAAO,KAGTD,EAAWC,CACZ,MAtBuB5F,EAsBHqF,IAtByCrF,EAAI8F,WAAaC,KAAKC,eAuBlFL,EAAWN,GAvBWrF,MA0BxB,OAAO2F,CAAQ,EAmCJM,GAAQA,CAAC/C,EAAWiB,EAAaE,IAAgBjB,KAAKiB,IAAIjB,KAAKe,IAAIjB,EAAGmB,GAAMF,GAG5E+B,GAAOA,CAACC,EAAWC,EAAWC,IAClCF,GAAK,EAAIE,GAAKD,EAAIC,EAGdC,GAAYA,CAACtG,EAAamE,EAAaE,KAClD,MAAMkC,EAAOnD,KAAKoD,IAAInC,EAAMF,GAE5B,GAAInE,EAAMmE,EAAK,CAEbnE,EAAMqE,GADUF,EAAMnE,GAAOuG,CAE9B,MAAM,GAAIvG,EAAMqE,EAAK,CAEpBrE,EAAMmE,GADUnE,EAAMqE,GAAOkC,CAE9B,CAED,OAAOvG,CAAG,EAmBCyG,GAAYA,CAAIC,EAAYC,KACvC,IAAK,IAAIC,EAAM,EAAGA,EAAMF,EAAMG,OAAQD,IACpC,GAAID,EAAQD,EAAME,IAChB,OAAOA,EAIX,OAAQ,CAAC,EAGEE,GAAwD9G,GAAyC,iBAARA,EAAmBA,EAAM,CAAA,EAClH+G,GAAgBA,CAACC,EAAmBC,IACQ,EAAhD7D,KAAK8D,KAAK9D,KAAK+D,IAAgB,GAAZH,GAAmBC,GAGlCG,GAAcA,CAAIC,EAAUC,EAAeC,EAAe,WAC9DA,EAAaC,MAAM,IACvBtH,KAAIuH,GAAQH,EAAMI,QAAQD,KAC1BvH,KAAIyH,GAASN,EAAIM,KAGTC,GAAeA,KAC1B,IAAKtC,SAAU,OAAO,EAEtB,IAAK,MAAMuC,KAAOzC,GAChB,GAAIE,SAASuC,GAAM,OAAO,EAG5B,OAAO,CAAK,EAGDC,GAAwBA,MAC1BC,mBAAqB,sBAAuBA,mBAAqBC,OAAOC,gBAUtEC,GAAcA,CAACC,EAAWC,EAAaC,EAAeC,KACjEC,EAAcJ,GAEd,MACMK,EAAevC,GAAMoC,GAAO,MAAsB,OAMxD,OAJAE,EAAaJ,EAAKA,EAAKC,EAAMtE,IAC7ByE,EAAaJ,EAAKA,EAAKK,EAAe1E,IACtCyE,EAAaJ,EAAKA,EAAKG,EAAOxE,IAEvBqE,CAAG,EAOCM,GAAeC,IAC1B,MAAMxF,EAAIwF,EAAW,GACfC,EAAID,EAAW,GACfE,EAAIF,EAAW,GACfG,EAAIH,EAAW,GAMfI,EALK5F,EAAIA,EACJyF,EAAIA,EACJC,EAAIA,EACJC,EAAIA,EAGTE,EAAO7F,EAAI2F,EAAIF,EAAIC,EAEzB,IAAIP,EAAeD,EAEnB,GAAIW,EAAO,QAAWD,EAEpBT,EAAQjF,KAAKE,GAAK,EAClB8E,EAAM,EAAIhF,KAAK4F,MAAML,EAAGzF,QACnB,GAAI6F,GAAQ,QAAWD,EAE5BT,GAASjF,KAAKE,GAAK,EACnB8E,GAAO,EAAIhF,KAAK4F,MAAML,EAAGzF,OACpB,CACL,MAAM+F,EAAOC,EAAgB,EAAG,EAAG,GAC7BC,EAAKD,EAAgB,EAAG,EAAG,GAEjCA,EAAmBD,EAAMA,EAAMP,GAC/BQ,EAAmBC,EAAIA,EAAIT,GAE3B,MAAMU,EAAShG,KAAKiG,KAAKJ,EAAK,GAAKA,EAAK,GAAKA,EAAK,GAAKA,EAAK,IAE5DZ,EAAQjF,KAAK4F,OAAOC,EAAK,GAAIG,GAC7BhB,EAAMhF,KAAK4F,MAAMC,EAAK,GAAIA,EAAK,GAChC,CAED,MAAO,CACLZ,MAAOpC,GAAMoC,EAAQtE,IAAa,GAAI,IACtCqE,IAAK9B,GAAU8B,EAAMrE,GAAY,EAAG,KACrC,EClMH,MAAMuF,GAmBOtJ,UAAQ,OAAOd,KAAKqK,IAAM,CAM1BC,YAAU,OAAOtK,KAAKuK,MAAQ,CAM9BC,UAAQ,OAAOxK,KAAKyK,IAAM,CAM1BC,eAAa,OAAO1K,KAAK2K,SAAW,CAMpCC,gBAAc,OAAO5K,KAAK6K,UAAY,CAOtCC,eAAa,OAAO9K,KAAK+K,SAAW,CACpCD,aAAShK,GAAed,KAAK+K,UAAYjK,CAAK,CAO9CkK,WAAS,OAAOhL,KAAKiL,KAAO,CAC5BD,SAAKlK,GAAgBd,KAAKiL,MAAQnK,CAAK,CAOvCoK,YAAU,OAAOlL,KAAKmL,MAAQ,CAO9BC,aAAW,OAAOpL,KAAKqL,OAAS,CAChCD,WAAOtK,GAA8Bd,KAAKqL,QAAUvK,CAAK,CAWpEpB,aAAmBoL,SACjBA,EAAW/F,IAA0BiG,KACrCA,GAAO,EAAKE,MACZA,EAAQ,CAAEjG,IAAK,EAAGE,IAAK,GAAGiG,OAC1BA,EAAStG,IACP,IACF9E,KAAK+K,UAAYD,EACjB9K,KAAKiL,MAAQD,EACbhL,KAAKmL,OAASD,EACdlL,KAAKqL,QAAUD,EACfpL,KAAK6K,YAAa,EAClB7K,KAAKsL,MAAM,EACb,CASOC,OAAOC,GACZ,IAAKxL,KAAK6K,WAER,OADA7K,KAAKqK,KAAOrK,KAAKyK,KACV,EAGT,MAAMH,EAAQtK,KAAKuK,OACbC,EAAMxK,KAAKyK,KACXK,EAAW9K,KAAK+K,UAChBU,EAAOzL,KAAKqK,KACZW,EAAOhL,KAAKiL,MAEZS,EAAe1L,KAAK2K,UAAYa,EAAYV,EAElD9K,KAAK2K,UAAYK,EACb5D,GAAUsE,EAAc,EAAG,GAC3B3E,GAAM2E,EAAc,EAAG,GAE3B,MAAMC,EAAgB3L,KAAKqL,QAAQrL,KAAK2K,WAOxC,OANA3K,KAAKqK,KAAOrD,GAAKsD,EAAOE,EAAKmB,IAExBX,GAAQhL,KAAK2K,WAAa,IAC7B3K,KAAK6K,YAAa,GAGb7K,KAAKqK,KAAOoB,CACrB,CAQOH,MAAMM,GACX,MAAMV,EAAQlL,KAAKmL,OACbrK,EAAMiG,GAAM6E,EAAYV,EAAMjG,IAAKiG,EAAM/F,KAC/CnF,KAAKuK,OAASzJ,EACdd,KAAKyK,KAAO3J,EACZd,KAAKqK,KAAOvJ,EACZd,KAAK2K,UAAY,EACjB3K,KAAK6K,YAAa,CACpB,CAOOvE,IAAIuF,GACT,MAAMX,EAAQlL,KAAKmL,OAEnBnL,KAAKuK,OAASxD,GAAM/G,KAAKuK,OAASsB,EAAOX,EAAMjG,IAAKiG,EAAM/F,KAC1DnF,KAAKyK,KAAO1D,GAAM/G,KAAKyK,KAAOoB,EAAOX,EAAMjG,IAAKiG,EAAM/F,KACtDnF,KAAKqK,KAAOtD,GAAM/G,KAAKqK,KAAOwB,EAAOX,EAAMjG,IAAKiG,EAAM/F,IACxD,CAOO2G,iBAAiBD,GACtB,MAAMX,EAAQlL,KAAKmL,OAEnBnL,KAAKuK,OAASvK,KAAKqK,KACnBrK,KAAKyK,KAAO1D,GAAM/G,KAAKyK,KAAOoB,EAAOX,EAAMjG,IAAKiG,EAAM/F,KACtDnF,KAAK2K,UAAY,EACjB3K,KAAK6K,YAAa,CACpB,CAQOkB,SAAS9G,EAAaE,GAC3BnF,KAAKuK,OAASxD,GAAM/G,KAAKuK,OAAQtF,EAAKE,GACtCnF,KAAKyK,KAAO1D,GAAM/G,KAAKyK,KAAMxF,EAAKE,GAClCnF,KAAKmL,OAAS,CAAElG,MAAKE,MACvB,ECpLF,MAAM6G,GAgBOlB,eAAa,OAAO9K,KAAKiM,QAAQnB,QAAU,CAC3CA,aAAShK,GAAed,KAAKiM,QAAQnB,SAAWhK,CAAK,CAMrDsK,aAAW,OAAOpL,KAAKiM,QAAQb,MAAQ,CACvCA,WAAOtK,GAA8Bd,KAAKiM,QAAQb,OAAStK,CAAK,CAY3EpB,YAAmBwM,EAAgBC,EAAkBC,GAAgBtB,SACnEA,EAAW/F,IAA0BqG,OACrCA,EAAStG,IACP,IACF9E,KAAKqM,QAAUH,EACflM,KAAKiM,QAAU,IAAI7B,GAAO,CAAEU,WAAUM,SAAQF,MAAO,CAAEjG,IAAK,EAAGE,IAAK,KACpEnF,KAAKsM,MAAQH,EACbnM,KAAKuM,IAAMH,EACXpM,KAAKwM,eAAiB,IAAIC,SAAQC,IAChC1M,KAAK2M,QAAUD,CAAqB,IAItC1M,KAAKiM,QAAQH,iBAAiB,EAChC,CAOOc,mBACL,OAAO5M,KAAKwM,cACd,CAQOjB,OAAOC,GACZ,MAAMU,EAASlM,KAAKqM,QACdF,EAAOnM,KAAKsM,MACZF,EAAKpM,KAAKuM,IACVM,EAAS7M,KAAKiM,QACpBY,EAAOtB,OAAOC,GAGd,MAAMd,EAAWmC,EAAO/L,IAClBgM,EAAWzD,IACX0D,EAAO/F,GAAKmF,EAAKY,KAAMX,EAAGW,KAAMrC,GAEtCrB,EAAWyD,EAAUX,EAAKW,SAAUV,EAAGU,SAAUpC,GACjDwB,EAAOc,OAAOF,EAAUC,GAEpBrC,GAAY,GACd1K,KAAK2M,SAET,ECrBF,MAAMM,WAAeC,EAmGRnF,aAAW,OAAO/H,KAAKmN,OAAS,CAMhCC,cAAY,OAAOpN,KAAKqN,QAAU,CAIlCC,eAAa,OAAOtN,KAAKuN,gBAAkB,CAC3CD,aAASxM,GAClBd,KAAKuN,iBAAmBzM,CAC1B,CAIW0M,iBAAe,OAAOxN,KAAKyN,kBAAoB,CAC/CD,eAAW1M,GACpBd,KAAKyN,mBAAqB3M,CAC5B,CAIW4M,gBAAc,OAAO1N,KAAK2N,iBAAmB,CAC7CD,cAAU5M,GACnBd,KAAK2N,kBAAoB7M,CAC3B,CAMApB,aAAmBkO,WACjBA,EAAUC,aACVA,EAAYC,YACZA,EAAWR,SACXA,EAAQE,WACRA,EAAUE,UACVA,EAASK,IACTA,IAEAlO,QAEAG,KAAKkJ,IAAM0E,EACX5N,KAAKmJ,MAAQ0E,EACb7N,KAAK+M,KAAOe,EACZ9N,KAAKgO,WAAa,EAElBhO,KAAK4N,WAAaA,EAClB5N,KAAK6N,aAAeA,EACpB7N,KAAK8N,YAAcA,EAEnB9N,KAAKiO,SAAWjE,IAChBhK,KAAKkO,UAAY,KAEjBlO,KAAKmO,IAAMnE,EAAgB,EAAG,EAAG,GACjChK,KAAKmN,QAAU,EAEfnN,KAAKuN,iBAAmBD,EACxBtN,KAAKyN,mBAAqBD,EAC1BxN,KAAK2N,kBAAoBD,EAEzB1N,KAAKoO,UAAYd,EACjBtN,KAAKqO,YAAcb,EACnBxN,KAAKsO,WAAaZ,EAElB1N,KAAKwJ,WAAaH,IAClBrJ,KAAKuO,oBAELvO,KAAKwO,WAAaC,IAClBzO,KAAK0O,iBAAmBD,IACxBzO,KAAK+N,IAAMA,EAEX/N,KAAK2O,kBAAoB,CAC3B,CAOOC,UACL5O,KAAK6O,KACP,CASOC,OAAOC,EAAeC,GAC3B,MAAMC,EAAajP,KAAKmN,QAExBnN,KAAKmN,QAAU4B,EAAQC,EAEnBhP,KAAKmN,UAAY8B,GACnBjP,KAAKkP,cAET,CAWOC,QAAOjG,IACZA,EAAMlJ,KAAKkJ,IAAGC,MACdA,EAAQnJ,KAAKmJ,MAAK4D,KAClBA,EAAO/M,KAAK+M,OAMZ,MAAMqC,EAAiB/F,EAAWrJ,KAAKwJ,YACjC6F,EAAWrP,KAAK+M,KAEtB/M,KAAKkJ,IAAM9B,GAAU8B,EAAK,EAAG,KAC7BlJ,KAAKmJ,MAAQpC,GAAMoC,GAAQ,GAAI,IAC/BnJ,KAAK+M,KAAOA,EAEZ/M,KAAKuO,oBAEL,MAAMe,EAAWpL,KAAKoD,IAAIyF,EAAOsC,KAG9BhG,EAAYrJ,KAAKwJ,WAAY4F,IAC3BE,GAAsB,GAAV3J,KAEf3F,KAAKkP,cAET,CASOlC,OAAOF,EAAgBC,EAAe/M,KAAK+M,MAChD,MAAMwC,EAAalG,EAAeA,IAAeyD,GAC3C0C,EAAiBnG,EAAYrJ,KAAKwJ,WAAY+F,GACpDlG,EAAUrJ,KAAKwJ,WAAY+F,GAE3B,MAAMF,EAAWrP,KAAK+M,MAChB7D,IAAEA,EAAGC,MAAEA,GAAUI,GAAYgG,GAEnCvP,KAAKkJ,IAAMA,EACXlJ,KAAKmJ,MAAQA,EACbnJ,KAAK+M,KAAOA,EAEZ,MAAMuC,EAAWpL,KAAKoD,IAAIyF,EAAOsC,KAE5BG,GAAkBF,GAAsB,GAAV3J,KACjC3F,KAAKkP,cAET,CAYaO,WAAUvG,IACrBA,EAAMlJ,KAAKkJ,IAAGC,MACdA,EAAQnJ,KAAKmJ,MAAK4D,KAClBA,EAAO/M,KAAK+M,KAAIjC,SAChBA,EAAW,EAACM,OACZA,EAAStG,IAON,6CACH,GACE9E,KAAKkJ,MAAQA,GACVlJ,KAAKmJ,QAAUA,GACfnJ,KAAK+M,OAASA,EACjB,OAEF,MAAMZ,EAAO,CACXW,SAAUzD,EAAWrJ,KAAKwJ,YAC1BuD,KAAM/M,KAAK+M,MAEPX,EAAK,CACTU,SAAU9D,GAAYK,IAAeH,EAAKC,EAAOnJ,KAAKgO,YACtDjB,QAGImB,EAAY,IAAIlC,GAAgBhM,KAAMmM,EAAMC,EAAI,CACpDtB,WACAM,WAEIsE,EAAgBxB,EAAUtB,mBAQhC,OANA5M,KAAKkO,UAAYA,EACjBwB,EAAcC,MAAK,KACjB3P,KAAKkO,UAAY,KACjBlO,KAAK4P,QAAQlL,GAA6B,CAAEwJ,aAAY,IAGnDwB,CACT,GAAC,CAKMG,iBAAiB5K,EAAaE,GACnCnF,KAAKoO,UAAY,CAAEnJ,MAAKE,MAC1B,CAKO2K,mBAAmB7K,EAAaE,GACrCnF,KAAKqO,YAAc,CAAEpJ,MAAKE,MAC5B,CAKO4K,kBAAkB9K,EAAaE,GACpCnF,KAAKsO,WAAa,CAAErJ,MAAKE,MAC3B,CAKO6K,qBAAqBhB,GAC1BhP,KAAK2O,iBAAmBK,CAC1B,CAKOiB,aACLjQ,KAAKoO,UAAYpO,KAAKuN,iBACtBvN,KAAKqO,YAAcrO,KAAKyN,mBACxBzN,KAAKsO,WAAatO,KAAK2N,kBACvB3N,KAAK2O,kBAAoB,CAC3B,CAOOuB,YAAYnD,GACjB,MAAMoD,EAAWnQ,KAAKoO,UAChBgC,EAAkBpQ,KAAK2O,iBAC7B,IAAKwB,EAAU,OAAOnL,GAEtB,MAAMqL,EAAyC,GAA9BrQ,KAAKsQ,iBAAiBvD,GACvC,IAAIwD,EAASJ,EAASlL,IAClBuL,EAASL,EAAShL,IAEtB,GAAIiL,EAAkB,EAAG,CACvB,MAAMK,EAAc5I,GAAcwI,EAAWzL,GAAY5E,KAAKmN,SACxDuD,EAAsB,GAAlBN,EACJjJ,EAAIjD,KAAK+D,IAAIwI,GACbE,EAAIzM,KAAKiG,MAAM,EAAIuG,EAAIA,IAAM,EAAIvJ,EAAIA,IACrCyJ,EAAQ1M,KAAK8D,KAAK9D,KAAK+D,IAAIoI,EAAWzL,IAAc+L,GAAK9L,GAE/D0L,EAASJ,EAASlL,IAAM2L,EACxBJ,EAASL,EAAShL,IAAMyL,CACzB,CAOD,OALIL,EAASC,IACXD,EAAS,EACTC,EAAS,GAGJ,CACLvL,IAAKsL,EACLpL,IAAKqL,EAET,CAOOK,cAAc9D,GACnB,MAAM+D,EAAa9Q,KAAKqO,YAClB+B,EAAkBpQ,KAAK2O,iBAE7B,IAAKmC,EAAY,OAAO1L,GAExB,IAAI2L,EAAWD,EAAW7L,IACtB+L,EAAWF,EAAW3L,IAE1B,GAAIiL,EAAkB,EAAG,CACvB,MAAMa,EAAuC,GAA5BjR,KAAKkR,eAAenE,GAErCgE,EAAWD,EAAW7L,IAAMgM,EAC5BD,EAAWF,EAAW3L,IAAM8L,CAC7B,CAOD,OALIF,EAAWC,IACbD,EAAW,EACXC,EAAW,GAGN,CACL/L,IAAKf,KAAKiB,IAAI4L,GAAW,IACzB5L,IAAKjB,KAAKe,IAAI+L,EAAU,IAE5B,CAOOG,qBACL,MAAMC,EAAuB,QAAfxL,EAAA5F,KAAKsO,kBAAU,IAAA1I,EAAAA,EAAIP,GAG3BgM,EAASrR,KAAKsQ,iBAAiBc,EAAMjM,KACrCmM,EAAStR,KAAKsQ,iBAAiBc,EAAMnM,KACrCsM,EAAavR,KAAKsQ,iBAAiBtQ,KAAK+M,MAE9C,MAAO,CACL9H,IAAKf,KAAKiB,IAAIkM,EAAQ,GACtBlM,IAAKjB,KAAKe,IAAIqM,EAAQ,KACtBE,QAASD,EAEb,CAQOjB,iBAAiBvD,EAAO/M,KAAK+M,MAClC,OAAO/M,KAAKyR,wBAAwB1E,GAAQlI,EAC9C,CAQOqM,eAAenE,EAAO/M,KAAK+M,MAChC,MAAMhF,EAAS/H,KAAKmN,QACduE,EAAO1R,KAAKyR,wBAAwB1E,GAG1C,OAFalF,GAAc6J,EAAM3J,GAEnBlD,EAChB,CAQO8M,UAAU5D,GACf,MAAM6D,EAAU5R,KAAK+N,IAIrB,OAHuB7J,KAAK+D,IAAIrD,GAAagN,EAAU,IACnC1N,KAAK+D,IAAIrD,GAAamJ,EAAM,GAGlD,CAQOmB,eACL,MAAMjF,EAAKjK,KAAKmO,IACVpG,EAAS/H,KAAKmN,QACdqB,EAAaxO,KAAKwO,WAClBqD,EAAa7R,KAAK0O,iBAClBT,EAAWjO,KAAKiO,SAChBnB,EAAW9M,KAAKwJ,WAEhBsI,EAAQ9H,IACR+H,EAAU/H,EAAgB,EAAG,GAAI,GACvCA,EAAmB+H,EAASA,EAASjF,GACrC9C,EAAmB8H,EAAO7H,EAAI6C,GAE9B,MAAM4E,EAAO1R,KAAKyR,0BACZO,EAAOnK,GAAc6J,EAAM3J,uqBAEjC0G,CAAYD,EAAYP,EAAU8D,EAASD,GAC3CrD,EAAiBoD,EAAYG,EAAMjK,EAAQ,GAAK,KAEhD/H,KAAKqN,UAAW,CAClB,CAKO4E,gBACLjS,KAAKqN,UAAW,CAClB,CAEQkB,oBACNvF,GAAYhJ,KAAKwJ,WAAYxJ,KAAKkJ,IAAKlJ,KAAKmJ,MAAOnJ,KAAKgO,WAC1D,CAMQyD,wBAAwB1E,EAAO/M,KAAK+M,MAC1C,OAAO,EAAI7I,KAAK8D,KAAK9D,KAAK+D,IAAIrD,GAAa5E,KAAK+N,IAAM,IAAOhB,EAC/D,EC3lBF,MAAMmF,WAAmBhF,EAIvBxN,cACEG,QAyBMG,KAAAmS,aAAgBC,IACtB,MAAMjM,EAAKnG,KAAKqS,IACXlM,GAAMiM,EAAIE,SAAWpM,GAAqBnE,OAE/CqQ,EAAIG,iBAEApM,EAAGqM,MACLrM,EAAGqM,QAEH1J,OAAO0J,QAGTxS,KAAKyS,SAAS,GAAKL,EAAIM,QACvB1S,KAAKyS,SAAS,GAAKL,EAAIO,QAEvB7J,OAAO8J,iBAAiB1M,EAA2BlG,KAAK6S,cAAc,GACtE/J,OAAO8J,iBAAiB1M,EAAyBlG,KAAK8S,YAAY,GAElE9S,KAAK4P,QAAQjL,GAA4B,CACvCoO,SAAUX,EACVY,SAAS,EACTC,YAAY,IACZ,EAGIjT,KAAA6S,aAAgBT,IACtBA,EAAIG,iBAEJ,MAAMvO,EAAIoO,EAAIM,QACRjJ,EAAI2I,EAAIO,QACRO,EAAUlT,KAAKyS,SACfU,EAASnP,EAAIkP,EAAQ,GACrBE,EAAS3J,EAAIyJ,EAAQ,GAE3BlT,KAAK4P,QAAQjL,GAAuB,CAClCkH,MAAO,CACL7H,EAAGmP,EACH1J,EAAG2J,GAELJ,SAAS,EACTC,YAAY,IAGdC,EAAQ,GAAKlP,EACbkP,EAAQ,GAAKzJ,CAAC,EAGRzJ,KAAU8S,WAAG,KACnB9S,KAAKyS,SAAS,GAAK,EACnBzS,KAAKyS,SAAS,GAAK,EAEnB3J,OAAOuK,oBAAoBnN,EAA2BlG,KAAK6S,cAAc,GACzE/J,OAAOuK,oBAAoBnN,EAAyBlG,KAAK8S,YAAY,GAErE9S,KAAK4P,QAAQjL,GAA0B,CACrCqO,SAAS,EACTC,YAAY,EACZK,WAAW,GACX,EAjFFtT,KAAKqS,IAAM,KACXrS,KAAKyS,SAAW,CAAC,EAAG,EACtB,CAEOc,OAAOC,GACRxT,KAAKqS,MAETmB,EAAQZ,iBAAiB1M,EAA2BlG,KAAKmS,cAEzDnS,KAAKqS,IAAMmB,EACb,CAEOC,UACL,MAAMD,EAAUxT,KAAKqS,IAChBmB,IAELA,EAAQH,oBAAoBnN,EAA2BlG,KAAKmS,cAC5DrJ,OAAOuK,oBAAoBnN,EAA2BlG,KAAK6S,cAAc,GACzE/J,OAAOuK,oBAAoBnN,EAAyBlG,KAAK8S,YAAY,GAErE9S,KAAKqS,IAAM,KACb,EC3BF,MAAMqB,WAAmBxG,EAOZyG,iBAAe,OAAO3T,KAAK4T,WAAa,CACxCD,eAAW7S,GAAgBd,KAAK4T,YAAc9S,CAAK,CAE9DpB,cACEG,QA8BMG,KAAA6T,cAAiBzB,IACvB,GAAIA,EAAI0B,QAAQnM,OAAS,GAAK3H,KAAK+T,WAAY,OAE/C,MAAMC,EAAQ5B,EAAI0B,QAAQ,GAE1B9T,KAAKiU,eAAgB,EACrBjU,KAAKyS,SAAS,GAAKuB,EAAMtB,QACzB1S,KAAKyS,SAAS,GAAKuB,EAAMrB,QAEzB3S,KAAK4P,QAAQjL,GAA4B,CACvCoO,SAAUX,EACVY,SAAS,EACTC,YAAY,GACZ,EAGIjT,KAAAkU,aAAgB9B,IAEtB,GAAIA,EAAI0B,QAAQnM,OAAS,GAAK3H,KAAK+T,WAAY,OAE/C,MAAMC,EAAQ5B,EAAI0B,QAAQ,GACpBH,EAAa3T,KAAK4T,YAClBV,EAAUlT,KAAKyS,SAEfzO,EAAIgQ,EAAMtB,QACVjJ,EAAIuK,EAAMrB,QACVQ,EAASnP,EAAIkP,EAAQ,GACrBE,EAAS3J,EAAIyJ,EAAQ,GAE3B,GAAIlT,KAAKiU,cAAe,CACtB,GAAIN,IAAejL,MACbxE,KAAKoD,IAAI8L,GAAUlP,KAAKoD,IAAI6L,GAG9B,YADAnT,KAAK+T,YAAa,GAKtB/T,KAAKiU,eAAgB,CACtB,EAEsB,IAAnB7B,EAAI+B,YACN/B,EAAIG,iBAGNvS,KAAK4P,QAAQjL,GAAuB,CAClCkH,MAAO,CACL7H,EAAGmP,EACH1J,EAAG2J,GAELJ,SAAS,EACTC,YAAY,IAGdC,EAAQ,GAAKlP,EACbkP,EAAQ,GAAKzJ,CAAC,EAGRzJ,KAAAoU,YAAehC,IACrB,GAA2B,IAAvBA,EAAI0B,QAAQnM,OAAc,OAE9B,MAAMqM,EAAQ5B,EAAI0B,QAAQ,GACpBZ,EAAUlT,KAAKyS,SAEjBuB,GACFd,EAAQ,GAAKc,EAAMtB,QACnBQ,EAAQ,GAAKc,EAAMrB,UAEnBO,EAAQ,GAAK,EACbA,EAAQ,GAAK,EAEblT,KAAK4P,QAAQjL,GAA0B,CACrCqO,SAAS,EACTC,YAAY,EACZK,UAAWtT,KAAK+T,eAIG,IAAnB3B,EAAI+B,YACN/B,EAAIG,iBAGNvS,KAAK+T,YAAa,CAAK,EA9GvB/T,KAAKqS,IAAM,KACXrS,KAAKyS,SAAW,CAAC,EAAG,GACpBzS,KAAKiU,eAAgB,EACrBjU,KAAK+T,YAAa,EAClB/T,KAAK4T,aAAc,CACrB,CAEOL,OAAOC,GACRxT,KAAKqS,MAETmB,EAAQZ,iBAAiB1M,EAA4BlG,KAAK6T,cAAe,CAAEQ,SAAS,IACpFb,EAAQZ,iBAAiB1M,EAA2BlG,KAAKkU,aAAc,CAAEG,SAAS,IAClFb,EAAQZ,iBAAiB1M,EAA0BlG,KAAKoU,aAExDpU,KAAKqS,IAAMmB,EACb,CAEOC,UACL,MAAMD,EAAUxT,KAAKqS,IAChBmB,IAELA,EAAQH,oBAAoBnN,EAA4BlG,KAAK6T,eAC7DL,EAAQH,oBAAoBnN,EAA2BlG,KAAKkU,cAC5DV,EAAQH,oBAAoBnN,EAA0BlG,KAAKoU,aAE3DpU,KAAKqS,IAAM,KACb,ECxCF,MAAMiC,WAAsBpH,EASfqH,aACT,MAAMC,EAAUxU,KAAKyU,SACrB,OAAOD,EAAQzS,MAAQyS,EAAQxS,IAAMwS,EAAQvS,OAASuS,EAAQtS,IAChE,CAEAxC,cACEG,QAyFMG,KAAA0U,WAActC,IAEpB,GAAIA,EAAIuC,WAAaC,cAAcC,0BAA2B,OAE9D7U,KAAK8U,gBAAgB1C,GAAK,GAE1B,MAAM2C,EAAe/U,KAAKgV,sBACtBD,GAAgB,IAEpB3C,EAAIG,iBACiB,IAAjBwC,GAAuB3C,EAAI6C,QAE7BjV,KAAK4P,QAAQjL,GAA4B,CACvCoO,SAAUX,EACVY,SAAS,EACTC,YAAY,IAEf,EAGKjT,KAAAkV,SAAY9C,IAElB,GAAIA,EAAIuC,WAAaC,cAAcC,0BAA2B,OAE9D7U,KAAK8U,gBAAgB1C,GAAK,GAELpS,KAAKgV,sBACP,GAEnBhV,KAAK4P,QAAQjL,GAA0B,CACrCqO,SAAS,EACTC,YAAY,EACZK,WAAW,GACX,EAxHFtT,KAAKqS,IAAM,KACXrS,KAAKmV,mBACP,CAEO5B,OAAOC,GACRxT,KAAKqS,MAETmB,EAAQZ,iBAAiB1M,EAAyBlG,KAAK0U,YACvDlB,EAAQZ,iBAAiB1M,EAAuBlG,KAAKkV,UAErDlV,KAAKqS,IAAMmB,EACXxT,KAAKmV,oBACP,CAEO1B,UACL,MAAMD,EAAUxT,KAAKqS,IAChBmB,IAELA,EAAQH,oBAAoBnN,EAAyBlG,KAAK0U,YAC1DlB,EAAQH,oBAAoBnN,EAAuBlG,KAAKkV,UAExDlV,KAAKqS,IAAM,KACXrS,KAAKmV,oBACP,CAEO5J,SACL,MAAMM,EAAQ7L,KAAKoV,yBAEH,IAAZvJ,EAAM7H,GAAuB,IAAZ6H,EAAMpC,GACzBzJ,KAAK4P,QAAQjL,GAAuB,CAClCkH,QACAmH,SAAS,EACTC,YAAY,GAGlB,CAEQkC,oBACNnV,KAAKyU,SAAWvO,GAAsBmP,QAAO,CAACC,EAAKC,IACjDzV,OAAA0V,OAAA1V,OAAA0V,OAAA,CAAA,EACKF,GACH,CAAAC,CAACA,IAAU,KAEZ,CAA+B,EACpC,CAEQT,gBAAgBW,EAAsBC,GAC5C,MAAMlB,EAAUxU,KAAKyU,SACfkB,EAA+B,MAAjBF,EAAMG,QACtB1P,GAA2BuP,EAAMG,SACjC1P,GAA2BuP,EAAM9M,KAEhCgN,IAELnB,EAAQmB,GAAeD,EACzB,CAEQV,sBACN,OAAO9O,GAAsB2P,QAAOlN,GAAO3I,KAAKyU,SAAS9L,KAAMhB,MACjE,CAEQyN,yBACN,MAAMZ,EAAUxU,KAAKyU,SACrB,IAAIzQ,EAAI,EACJyF,EAAI,EAkBR,OAhBI+K,EAAQzS,OACViC,GAAK,GAGHwQ,EAAQvS,QACV+B,GAAK,GAGHwQ,EAAQxS,KACVyH,GAAK,GAGH+K,EAAQtS,OACVuH,GAAK,GAGA,CACLzF,IAAGyF,IAEP,ECpDF,MAAMqM,WAAsB5I,EA0Bf6I,cAAY,OAAO/V,KAAKgW,QAAU,CAIlCC,oBAAkB,OAAOjW,KAAKkW,cAAgB,CAI9CC,gBACT,OAAOnW,KAAKoW,eAAe7B,QACtBvU,KAAKqW,SAASzL,WACd5K,KAAKsW,SAAS1L,SACrB,CAOW1B,UAAQ,OAAOlJ,KAAKqW,QAAU,CAO9BlN,YAAU,OAAOnJ,KAAKsW,QAAU,CAIhC3C,iBAAe,OAAO3T,KAAKuW,YAAY5C,UAAY,CACnDA,eAAW7S,GACpBd,KAAKuW,YAAY5C,WAAa7S,CAChC,CAQW0V,mBAAiB,OAAOxW,KAAKyW,aAAe,CAC5CD,iBAAa1V,GACtBd,KAAKyW,cAAgB3V,CACvB,CAQW4V,oBAAkB,OAAO1W,KAAK2W,cAAgB,CAC9CD,kBAAc5V,GACvBd,KAAK2W,eAAiB7V,CACxB,CAOWgK,eAAa,OAAO9K,KAAK+K,SAAW,CACpCD,aAAShK,GAClBd,KAAK+K,UAAYjK,EACjBd,KAAKqW,SAASvL,SAAWhK,EACzBd,KAAKsW,SAASxL,SAAWhK,CAC3B,CAQWsK,aAAW,OAAOpL,KAAKqL,OAAS,CAChCD,WAAOtK,GAChBd,KAAKqL,QAAUvK,EACfd,KAAKqW,SAASjL,OAAStK,EACvBd,KAAKsW,SAASlL,OAAStK,CACzB,CAOW8V,mBAAiB,OAAO5W,KAAK6W,aAAe,CAC5CD,iBAAa9V,GAA6Cd,KAAK6W,cAAgB/V,CAAK,CAOpFgW,iBAAe,OAAO9W,KAAK+W,WAAa,CACxCD,eAAWhW,GAA2Cd,KAAK+W,YAAcjW,CAAK,CAO9EkW,sBAAoB,OAAOhX,KAAKiX,gBAAkB,CAClDD,oBAAgBlW,GAAgDd,KAAKiX,iBAAmBnW,CAAK,CASxGpB,YAAmBwX,EAAwBjB,GAAwBnL,SACjEA,EAAW/F,IAA0BqG,OACrCA,EAAStG,GAAc0R,aACvBA,EAAe,CAAC,EAAG,GAAEE,cACrBA,EAAgB,CAAC,EAAG,GAAEE,aACtBA,GAAe,EAAKE,WACpBA,GAAa,EAAKE,gBAClBA,GAAkB,GACe,IACjCnX,QA6IMG,KAAAmX,cAAiB/E,IACvBpS,KAAKoX,uBAAwB,EAC7BpX,KAAK4P,QAAQjL,GACR7E,OAAA0V,OAAA1V,OAAA0V,OAAA,GAAApD,GACH,CAAAiF,UAAW,WACX,EAGIrX,KAAAsX,UAAalF,IACnB,MAAMvG,EAAQuG,EAAIvG,MACZ0L,EAAe,EAAIvX,KAAKwX,WACxBC,EAAczX,KAAK0X,aACnBhB,EAAgB1W,KAAK2W,eACrBH,EAAexW,KAAKyW,cAE1B,IAAIkB,EAGFA,EADEvF,EAAIa,WACE,CACNyD,EAAc,GAAKa,EACnBb,EAAc,GAAKa,GAGb,CACNf,EAAa,GAAKiB,EAAY,GAAKF,EACnCf,EAAa,GAAKiB,EAAY,GAAKF,GAIvC,MAAMK,EAAU/L,EAAM7H,EAAI2T,EAAM,GAC1BE,EAAUhM,EAAMpC,EAAIkO,EAAM,GAEhC3X,KAAKqW,SAASvK,iBAAiB8L,GAC/B5X,KAAKsW,SAASxK,iBAAiB+L,GAE/B7X,KAAKoX,uBAAwB,CAAI,EAG3BpX,KAAA8X,YAAe1F,IACrBpS,KAAK4P,QAAQjL,GACR7E,OAAA0V,OAAA1V,OAAA0V,OAAA,GAAApD,GACH,CAAAiF,UAAW,YAGRrX,KAAKoX,uBAA0BhF,EAAIa,YAAeb,EAAIkB,WACzDtT,KAAK4P,QAAQjL,GAA6B,CACxCqO,QAASZ,EAAIY,UAIjBhT,KAAKoX,uBAAwB,CAAK,EA7LlCpX,KAAK+X,WAAab,EAClBlX,KAAKyW,cAAgBD,EACrBxW,KAAK2W,eAAiBD,EACtB1W,KAAK+K,UAAYD,EACjB9K,KAAKqL,QAAUD,EACfpL,KAAK6W,cAAgBD,EACrB5W,KAAK+W,YAAcD,EACnB9W,KAAKiX,iBAAmBD,EAExBhX,KAAKkW,eAAiBD,EACtBjW,KAAKgY,YAAc,IAAI9F,GACvBlS,KAAKuW,YAAc,IAAI7C,GACvB1T,KAAKoW,eAAiB,IAAI9B,GAC1BtU,KAAKqW,SAAW,IAAIjM,GAAO,CAAEU,WAAUI,MAAOlG,GAAgBoG,WAC9DpL,KAAKsW,SAAW,IAAIlM,GAAO,CAAEU,WAAUI,MAAO9F,GAAqBgG,WACnEpL,KAAK0X,aAAe,CAAC,EAAG,GACxB1X,KAAKwX,WAAa,EAClBxX,KAAKgW,UAAW,EAChBhW,KAAKoX,uBAAwB,EAC7BpX,KAAKiY,aACP,CAEOrJ,UACL5O,KAAKyT,UACLzT,KAAKgY,YAAYnJ,MACjB7O,KAAKuW,YAAY1H,MACjB7O,KAAKoW,eAAevH,MACpB7O,KAAK6O,MACL7O,KAAKoX,uBAAwB,CAC/B,CAKO7L,OAAOM,GACZ,IAAK7L,KAAKgW,SAAU,OAEpB,MAAMkC,EAAUlY,KAAKqW,SACf8B,EAAUnY,KAAKsW,SACf8B,EAAgBpY,KAAKoW,eAEtBpW,KAAKiX,kBACRmB,EAAc7M,SAGXvL,KAAK6W,eACRsB,EAAQ5M,OAAOM,GAGZ7L,KAAK+W,aACRmB,EAAQ3M,OAAOM,EAEnB,CAKOwM,YAAYnM,EAAgBa,GACjC,MAAMO,EAAWpB,EAAOgE,YAAYnD,GAC9BS,EAAatB,EAAO2E,cAAc9D,GAExC/M,KAAKqW,SAAStK,SAASuB,EAASrI,IAAKqI,EAASnI,KAC9CnF,KAAKsW,SAASvK,SAASyB,EAAWvI,IAAKuI,EAAWrI,IACpD,CAKOmT,aAAaxX,GAClBd,KAAKwX,WAAa1W,CACpB,CAUOgO,OAAOyJ,EAAcxQ,EAAgBgH,EAAeC,GACzD,MAAMwJ,EAAO3Q,GAAc0Q,EAAO3T,GAAYmD,GAAUlD,GAExD7E,KAAK0X,aAAa,GAAKa,EAAOxJ,EAC9B/O,KAAK0X,aAAa,GAAKc,EAAOxJ,CAChC,CAEOuE,SACL,GAAIvT,KAAKgW,SAAU,OAEnB,MAAMxC,EAAUxT,KAAK+X,WAErB/X,KAAKgY,YAAYzE,OAAOC,GACxBxT,KAAKuW,YAAYhD,OAAOC,GACxBxT,KAAKoW,eAAe7C,OAAOC,GAE3BxT,KAAKgW,UAAW,EAChBhW,KAAKkW,gBAAiB,EAEtBlW,KAAK4P,QAAQjL,GAAuB,CAAE8T,QAASzY,KAAM0Y,cAAc,GACrE,CAEOjF,UACAzT,KAAKgW,WAEVhW,KAAKgY,YAAYvE,UACjBzT,KAAKuW,YAAY9C,UACjBzT,KAAKoW,eAAe3C,UAEpBzT,KAAKgW,UAAW,EAEhBhW,KAAK4P,QAAQjL,GAAwB,CAAE+T,cAAc,IACvD,CAEOC,KAAKzM,GACVlM,KAAKqY,YAAYnM,EAAQA,EAAOa,MAEhC/M,KAAKqW,SAAS/K,MAAMY,EAAOhD,KAC3BlJ,KAAKsW,SAAShL,MAAMY,EAAO/C,MAC7B,CAEQ8O,cACN,MAAMW,EAAa5Y,KAAKgY,YAClBa,EAAa7Y,KAAKuW,YAClB6B,EAAgBpY,KAAKoW,eAE3BwC,EAAWE,GAAGnU,GAA4B3E,KAAKmX,eAC/CyB,EAAWE,GAAGnU,GAAuB3E,KAAKsX,WAC1CsB,EAAWE,GAAGnU,GAA0B3E,KAAK8X,aAE7Ce,EAAWC,GAAGnU,GAA4B3E,KAAKmX,eAC/C0B,EAAWC,GAAGnU,GAAuB3E,KAAKsX,WAC1CuB,EAAWC,GAAGnU,GAA0B3E,KAAK8X,aAE7CM,EAAcU,GAAGnU,GAA4B3E,KAAKmX,eAClDiB,EAAcU,GAAGnU,GAAuB3E,KAAKsX,WAC7Cc,EAAcU,GAAGnU,GAA0B3E,KAAK8X,YAClD,ECjVF,MAAMiB,WAAmB7L,EAMZyG,iBAAe,OAAO3T,KAAK4T,WAAa,CACxCD,eAAW7S,GAAgBd,KAAK4T,YAAc9S,CAAK,CAE9DpB,cACEG,QA2BMG,KAAAgZ,SAAY5G,IAClB,MAAMuB,EAAa3T,KAAK4T,YAExB,GAAmB,IAAfxB,EAAIgB,QAAgBO,EAAY,OAEpCvB,EAAIG,iBACJH,EAAI6G,kBAEAjZ,KAAKkZ,YAAc,EACrBlZ,KAAK4P,QAAQjL,GAA4B,CACvCoO,SAAUX,EACVY,SAAS,EACTC,YAAY,IAGdjT,KAAKmZ,cAGP,MAAMtN,EAAQ7L,KAAKoZ,WAAahH,EAAIgB,OAEpCpT,KAAK4P,QAAQjL,GAAuB,CAClCkH,QACAmH,SAAS,EACTC,YAAY,IAGdjT,KAAKkZ,YAAcpQ,OAAOuQ,YAAW,KACnCrZ,KAAK4P,QAAQjL,GAA0B,CACrCqO,SAAS,EACTC,YAAY,EACZK,WAAW,IAEbtT,KAAKkZ,aAAe,CAAC,GACpBnU,GAA2B,EA1D9B/E,KAAKqS,IAAM,KACXrS,KAAKoZ,WAAa,IAClBpZ,KAAK4T,aAAc,EACnB5T,KAAKkZ,aAAe,CACtB,CAEO3F,OAAOC,GACRxT,KAAKqS,MAETmB,EAAQZ,iBAAiB1M,EAAsBlG,KAAKgZ,SAAU,CAAE3E,SAAS,EAAOiF,SAAS,IAEzFtZ,KAAKqS,IAAMmB,EACXxT,KAAKmZ,cACP,CAEO1F,UACL,MAAMD,EAAUxT,KAAKqS,IAChBmB,IAELA,EAAQH,oBAAoBnN,EAAsBlG,KAAKgZ,UAAU,GAEjEhZ,KAAKqS,IAAM,KACXrS,KAAKmZ,cACP,CAsCQA,cACNrQ,OAAOyQ,aAAavZ,KAAKkZ,aACzBlZ,KAAKkZ,aAAe,CACtB,EC5EF,MAAMM,WAAmBtM,EAMvBxN,cACEG,QA6BMG,KAAAkU,aAAgB9B,IACtB,MAAM0B,EAAU1B,EAAI0B,QACpB,GAAuB,IAAnBA,EAAQnM,OAAc,OAE1B,IAAKyK,EAAI+B,WAAY,OAErB/B,EAAIG,iBACJH,EAAI6G,kBAEJ,MAAMQ,EAAezZ,KAAK0Z,cAEpBC,EAAO,CACX7F,EAAQ,GAAG8F,MAAQ9F,EAAQ,GAAG8F,MAC9B9F,EAAQ,GAAG+F,MAAQ/F,EAAQ,GAAG+F,OAG1BC,EAAW5V,KAAKiG,KAAKwP,EAAK,GAAKA,EAAK,GAAKA,EAAK,GAAKA,EAAK,IAAM3Z,KAAKoZ,WACnEvN,EAAQ7L,KAAKiU,cACf,EACA6F,EAAWL,EAEXzZ,KAAKiU,eACPjU,KAAK4P,QAAQjL,GAA4B,CACvCoO,SAAUX,EACVY,SAAS,EACTC,YAAY,IAIhBjT,KAAK0Z,cAAgBI,EACrB9Z,KAAKiU,eAAgB,EAErBjU,KAAK4P,QAAQjL,GAAuB,CAClCkH,QACAmH,SAAS,EACTC,YAAY,GACZ,EAGIjT,KAAAoU,YAAehC,IACM,IAAvBA,EAAI0B,QAAQnM,SAEX3H,KAAKiU,eACRjU,KAAK4P,QAAQjL,GAA0B,CACrCqO,SAAS,EACTC,YAAY,EACZK,WAAW,IAIftT,KAAK0Z,eAAiB,EACtB1Z,KAAKiU,eAAgB,EAAI,EA9EzBjU,KAAKqS,IAAM,KACXrS,KAAKoZ,YAAc,GACnBpZ,KAAK0Z,eAAiB,EACtB1Z,KAAKiU,eAAgB,CACvB,CAEOV,OAAOC,GACRxT,KAAKqS,MAETmB,EAAQZ,iBAAiB1M,EAA2BlG,KAAKkU,aAAc,CAAEG,SAAS,EAAOiF,SAAS,IAClG9F,EAAQZ,iBAAiB1M,EAA0BlG,KAAKoU,aAExDpU,KAAKqS,IAAMmB,EACXxT,KAAK0Z,eAAiB,EACtB1Z,KAAKiU,eAAgB,EACvB,CAEOR,UACL,MAAMD,EAAUxT,KAAKqS,IAChBmB,IAELA,EAAQH,oBAAoBnN,EAA2BlG,KAAKkU,cAAc,GAC1EV,EAAQH,oBAAoBnN,EAA0BlG,KAAKoU,aAE3DpU,KAAKqS,IAAM,KACb,ECEF,MAAM0H,WAAoB7M,EAeb6I,cAAY,OAAO/V,KAAKgW,QAAU,CAIlCC,oBAAkB,OAAOjW,KAAKkW,cAAgB,CAI9CC,gBAAc,OAAOnW,KAAKiM,QAAQrB,SAAW,CAO7CmC,WAAS,OAAO/M,KAAKiM,QAAQnL,GAAK,CAIlC6S,iBAAe,OAAO3T,KAAKga,YAAYrG,UAAY,CACnDA,eAAW7S,GACpBd,KAAKga,YAAYrG,WAAa7S,CAChC,CAIWoK,YAAU,OAAOlL,KAAKiM,QAAQf,KAAO,CAQrCyM,YAAU,OAAO3X,KAAKia,MAAQ,CAC9BtC,UAAM7W,GAAoCd,KAAKia,OAASnZ,CAAK,CAQ7DgK,eAAa,OAAO9K,KAAKiM,QAAQnB,QAAU,CAS3CM,aAAW,OAAOpL,KAAKiM,QAAQb,MAAQ,CASlD1L,YAAmBwX,EAAwBjB,GAAwB0B,MACjEA,EAAQ,EAAC7M,SACTA,EAAW/F,IAA0BqG,OACrCA,EAAStG,IACsB,IAC/BjF,QAgFMG,KAAAmX,cAAiB/E,IACvBpS,KAAK4P,QAAQjL,GACR7E,OAAA0V,OAAA1V,OAAA0V,OAAA,GAAApD,GACH,CAAAiF,UAAW,SACX,EAGIrX,KAAAsX,UAAY,EAAGzL,YACrB,MACMqO,EAAcrO,EADN7L,KAAKia,OAGnBja,KAAKiM,QAAQH,iBAAiBoO,EAAY,EAGpCla,KAAA8X,YAAe1F,IACrBpS,KAAK4P,QAAQjL,GACR7E,OAAA0V,OAAA1V,OAAA0V,OAAA,GAAApD,GACH,CAAAiF,UAAW,SACX,EAhGFrX,KAAKia,OAAStC,EAEd3X,KAAK+X,WAAab,EAClBlX,KAAKkW,eAAiBD,EACtBjW,KAAKga,YAAc,IAAIjB,GACvB/Y,KAAKma,YAAc,IAAIX,GACvBxZ,KAAKiM,QAAU,IAAI7B,GAAO,CACxBU,WACAM,SACAF,MAAOlG,KAEThF,KAAKgW,UAAW,EAEhBhW,KAAKiY,aACP,CAEOrJ,UACL5O,KAAKyT,UACLzT,KAAKga,YAAYnL,MACjB7O,KAAKma,YAAYtL,MACjB7O,KAAK6O,KACP,CAKOtD,OAAOM,GACZ,IAAK7L,KAAKgW,SAAU,OAELhW,KAAKiM,QACbV,OAAOM,EAChB,CAEO0H,SACL,GAAIvT,KAAKgW,SAAU,OAEnB,MAAMxC,EAAUxT,KAAK+X,WACrB/X,KAAKga,YAAYzG,OAAOC,GACxBxT,KAAKma,YAAY5G,OAAOC,GAExBxT,KAAKgW,UAAW,EAChBhW,KAAKkW,gBAAiB,EAEtBlW,KAAK4P,QAAQjL,GAAuB,CAAE8T,QAASzY,KAAM0Y,cAAc,GACrE,CAEOjF,UACAzT,KAAKgW,WAEVhW,KAAKga,YAAYvG,UACjBzT,KAAKma,YAAY1G,UAEjBzT,KAAKgW,UAAW,EAEhBhW,KAAK4P,QAAQjL,GAAwB,CAAE+T,cAAc,IACvD,CAEOC,KAAKzM,GACV,MAAMW,EAAS7M,KAAKiM,QACdf,EAAQgB,EAAOiF,eAErBtE,EAAOd,SAASb,EAAMjG,IAAKiG,EAAM/F,KACjC0H,EAAOvB,MAAMJ,EAAMsG,QACrB,CAEQyG,cACN,MAAMmC,EAAapa,KAAKga,YAClBK,EAAara,KAAKma,YAExBC,EAAWtB,GAAGnU,GAA4B3E,KAAKmX,eAC/CiD,EAAWtB,GAAGnU,GAAuB3E,KAAKsX,WAC1C8C,EAAWtB,GAAGnU,GAA0B3E,KAAK8X,aAE7CuC,EAAWvB,GAAGnU,GAA4B3E,KAAKmX,eAC/CkD,EAAWvB,GAAGnU,GAAuB3E,KAAKsX,WAC1C+C,EAAWvB,GAAGnU,GAA0B3E,KAAK8X,YAC/C,ECjMK,MAAMwC,GAAkB,CAC7BC,YAAa,EACbC,kBAAmB,EACnBC,iBAAkB,GAGpBH,GAAgBA,GAAgBC,aAAe,CAC7CG,WAAY,CAAC,EAAG,EAAG,GACnBC,UAAW,CAAC,EAAG,EAAG,IAEpBL,GAAgBA,GAAgBE,mBAAqB,CACnDE,WAAY,CAAC,EAAG,EAAG,GACnBC,UAAW,CAAC,EAAG,EAAG,IAEpBL,GAAgBA,GAAgBG,kBAAoB,CAClDC,WAAY,CAAC,EAAG,EAAG,GACnBC,UAAW,CAAC,EAAG,EAAG,IAGpB,MAAMC,WAAkB1N,EAiBX6I,cAAY,OAAO/V,KAAKgW,QAAU,CAClC6E,yBAAuB,OAAO7a,KAAK8a,mBAAqB,CACxDC,iBAAe,OAAO/a,KAAKgb,WAAa,CACxCD,eAAWja,GAAgBd,KAAKgb,YAAcla,CAAK,CAE9DpB,cACEG,QA+DMG,KAAAib,qBAAwB7I,IAC9B,MAAM8I,EAAkBlb,KAAKmb,cACvBC,MAAEA,EAAKC,KAAEA,EAAIC,MAAEA,GAAUlJ,EAGpB,MAATgJ,GACW,MAARC,GACS,MAATC,IAGLJ,EAAgBE,MAAQA,EACxBF,EAAgBG,KAAOA,EACvBH,EAAgBI,MAAQA,EAExBtb,KAAK8a,qBAAsB,EAEvB9a,KAAKub,kBACPvb,KAAKub,iBAAkB,EACvBvb,KAAKwb,oBACN,EAqCKxb,KAAwByb,yBAAG,KAC7B3S,OAAO4S,QAAU5S,OAAO4S,OAAOC,kBAAmDC,IAApC9S,OAAO4S,OAAOC,YAAYE,MAC1E7b,KAAK8b,mBAAqBJ,OAAOC,YAAYE,WACbD,IAAvB9S,OAAO6S,YAChB3b,KAAK8b,mBAAqBhT,OAAO6S,aAAe,EAC9C7S,OAAO6S,YAAc,IAAM7S,OAAO6S,YAEpC3b,KAAK8b,mBAAqB,CAC3B,EA7HD9b,KAAKwJ,WAAaH,IAElBrJ,KAAKmb,aAAe,CAClBC,MAAO,EACPC,KAAM,GACNC,MAAO,GAETtb,KAAK+b,WAAa,EAClB/b,KAAKgc,WAAa,EAClBhc,KAAK8a,qBAAsB,EAC3B9a,KAAK8b,mBAAqB,EAC1B9b,KAAKub,iBAAkB,EACvBvb,KAAKgW,UAAW,CAClB,CAEOzC,SACDvT,KAAKgW,WAETlN,OAAO8J,iBAAiB1M,GAAmClG,KAAKib,sBAChEnS,OAAO8J,iBAAiB1M,GAAmClG,KAAKyb,0BAEhEzb,KAAKyb,2BACLzb,KAAK8a,qBAAsB,EAC3B9a,KAAKub,iBAAkB,EACvBvb,KAAKgW,UAAW,EAClB,CAEOvC,UACAzT,KAAKgW,WAEVlN,OAAOuK,oBAAoBnN,GAAmClG,KAAKib,sBACnEnS,OAAOuK,oBAAoBnN,GAAmClG,KAAKyb,0BAEnEzb,KAAKgW,UAAW,EAClB,CAEOzK,SACLvL,KAAKic,kBACLjc,KAAK8a,qBAAsB,CAC7B,CAEOoB,eACL,IAAKlc,KAAK8a,oBACR,MAAO,CACL3R,MAAO,EACPD,IAAK,GAIT,MAAMiT,EAAe9S,EAAWrJ,KAAKwJ,YAKrC,OAHAxJ,KAAKic,kBACLjc,KAAK8a,qBAAsB,EAEpB9a,KAAKoc,cAAcD,EAAcnc,KAAKwJ,WAC/C,CAEO6S,mBAAmBnT,GACxBlJ,KAAK+b,WAAa7S,CACpB,CAwBQsS,mBACN,MAAMc,EAAYtc,KAAK+b,WACjBjP,EAAW9M,KAAKwJ,WAEtBxJ,KAAKgc,WAAa,EAClBhc,KAAKic,kBAEL,MAAQ/S,IAAKqT,GAAchT,GAAYuD,GACvC9M,KAAKgc,WAAaO,EAAYD,EAC9Btc,KAAKic,kBAELjc,KAAKub,iBAAkB,CACzB,CAEQU,kBACN,MAAMnP,EAAW9M,KAAKwJ,YAChB4R,MAAEA,EAAKC,KAAEA,EAAIC,MAAEA,GAAUtb,KAAKmb,aAEpC9R,EAAcyD,GACdzD,EAAayD,EAAUA,GAAWsO,EAAQpb,KAAKgc,YAAcpX,IAC7DyE,EAAayD,EAAUA,EAAUuO,EAAOzW,IACxCyE,EAAayD,EAAUA,GAAWwO,EAAQ1W,IAE1C,MAAM8W,EAASrS,IACTmT,EAAyC,IAA1Bxc,KAAK8b,mBAA2BlX,GAC/C6X,EAAQpT,GAAiBnF,KAAKiG,KAAK,IAAM,EAAG,EAAGjG,KAAKiG,KAAK,KAE/Dd,EAASqS,EAAQ,EAAGxX,KAAKC,IAAIqY,GAAc,EAAGtY,KAAKwY,IAAIF,IACvDnT,EAAcyD,EAAUA,EAAU4O,GAClCrS,EAAcyD,EAAUA,EAAU2P,GAElCpT,EAAeyD,EAAUA,EAC3B,CAaQsP,cAAcO,EAAgBC,GACpC,MAAO,CACL1T,IAAKlJ,KAAK6c,aAAaF,EAAUC,GACjCzT,MAAOnJ,KAAK8c,eAAeH,EAAUC,GAEzC,CAEQC,aAAaE,EAAYC,GAC/B,MAAMC,EAAgBjd,KAAKkd,kBAAkBH,EAAMC,EAAM1C,GAAgBG,kBAIzE,OAHuBza,KAAKkd,kBAAkBH,EAAMC,EAAM1C,GAAgBE,mBACtEtW,KAAKC,IAAInE,KAAKmd,sBAAsBH,IAEhBC,CAC1B,CAEQH,eAAeC,EAAYC,GACjC,OAAOhd,KAAKkd,kBAAkBH,EAAMC,EAAM1C,GAAgBC,YAC5D,CAEQ2C,kBAAkBE,EAAaJ,EAAYK,GACjD,MAAM3C,EAAa1Q,EACjBsQ,GAAgB+C,GAAY3C,WAAW,GACvCJ,GAAgB+C,GAAY3C,WAAW,GACvCJ,GAAgB+C,GAAY3C,WAAW,IAEnCC,EAAYL,GAAgB+C,GAAY1C,UAExCvL,EAAiB/F,EAAW+T,GAC5BE,EAAgBjU,EAAW2T,GAEjC3T,EAAe+F,EAAgBA,GAC/B/F,EAAeiU,EAAeA,GAE9B,IAAIC,EAAYvT,EAAgB,EAAG,EAAG,GAClCwT,EAAWxT,EAAgB,EAAG,EAAG,GAErCA,EAAmBuT,EAAWA,EAAWnO,GACzCpF,EAAmBwT,EAAUA,EAAUF,GACvCtT,EAAmB0Q,EAAYA,EAAY4C,GAE3C,MACMG,EADiBzT,EAAS0Q,EAAY1Q,EAAWA,IAAeuT,EAAWC,IACxC,EAAI,GAAK,EAK5CE,EAAa1T,EAAgB2Q,EAAU,GAAIA,EAAU,GAAIA,EAAU,IAEzE,IAAIgD,EAGFA,EADEN,IAAe/C,GAAgBG,iBACpBzQ,EAAgB,EAAGyT,EAAiB,GAEpCzT,EAAgByT,EAAiB,EAAG,GAGnDzT,EAAmB0T,EAAYA,EAAYJ,GAC3CtT,EAAmB2T,EAAYA,EAAYL,GAE3C,MAAMM,EAAOF,EACPG,EAAOF,EACPG,EAAO9T,IAEbA,EAAW8T,EAAMF,EAAMC,GACvB7T,EAAe8T,EAAMA,GAErB,MAAMC,EAAeD,EAAK,GACpBE,EAAeF,EAAK,GACpBG,EAAeH,EAAK,GAG1BN,EAAWxT,EAAgB2Q,EAAU,GAAIA,EAAU,GAAIA,EAAU,IACjE3Q,EAAmBwT,EAAUA,EAAUF,GAGvCC,EAAYvT,EAAgB2Q,EAAU,GAAIA,EAAU,GAAIA,EAAU,IAClE3Q,EAAmBuT,EAAWA,EAAWnO,GAGzC,IAAI0K,EAAW5V,KAAKoD,IAClBiW,EAAU,GAAKQ,EACfR,EAAU,GAAKS,EACfT,EAAU,GAAKU,GAGjB,MAAMC,EAAqBlU,kEAE3BA,CAAckU,EAAoBX,+DAAWvT,CAAWA,IAAe8T,EAAMhE,IAE7E,IAAIqE,GACDD,EAAmB,GAAKV,EAAS,GAClCU,EAAmB,GAAKV,EAAS,GACjCU,EAAmB,GAAKV,EAAS,KAChCxT,EAAYkU,GAAsBlU,EAAYwT,IAG7CW,EAAqB,IACvBA,EAAqB,GAGvB,MAAMvN,EAAQ1M,KAAKka,KAAKD,GAElBE,EAAWrU,EAAWA,IAAewT,EAAUU,GAMrD,IAAII,EAJJxE,EAAWiE,EAAeM,EAAS,GAC/BL,EAAeK,EAAS,GACxBJ,EAAeI,EAAS,GAK1BC,EADEjB,IAAe/C,GAAgBG,iBAChBX,EAAW,EAAI,GAAK,EAEpBA,EAAW,EAAI,GAAK,EAKvC,OAFoBlJ,EAAQ0N,EAAiBb,EAExB5Y,EACvB,CAEQsY,sBAAsB3T,GAC5B,MAAM+U,EAAQvU,EAAgB,EAAG,EAAG,GAGpC,OAFAA,EAAmBuU,EAAOA,EAAO/U,IAEzB,EAAItF,KAAK4F,MACfyU,EAAM,GACNra,KAAKiG,KAAKjG,KAAKI,IAAIia,EAAM,GAAI,GAAKra,KAAKI,IAAIia,EAAM,GAAI,IACzD,ECtRF,MAAMC,WAAoBtR,EAWb6I,cAAY,OAAO/V,KAAKye,OAAO1I,OAAS,CAIxCE,oBAAkB,OAAOjW,KAAKkW,cAAgB,CAI9CC,gBACT,OAAOnW,KAAKye,OAAO1I,SAAW/V,KAAKye,OAAO5D,kBAC5C,CAgBWE,iBAAe,OAAO/a,KAAKgb,WAAa,CACxCD,eAAWja,GAAyCd,KAAKgb,YAAcla,CAAK,CAgBhF4d,8DACL,IAAK7V,kBACH,OAAO,EAGT,IAAI8V,EAcJ,OAAOlS,QAAQmS,KAAK,CAZa,IAAInS,SAAQoS,IAC3CF,EAAwBvM,IACtByM,EAAIzM,EAAI0M,cAA0C,MAA1B1M,EAAI0M,aAAa1D,MAAc,EAGzDtS,OAAO8J,iBAAiB1M,GAA8ByY,EAAqB,IAGvD,IAAIlS,SAAQoS,IAChCxF,YAAW,IAAMwF,GAAI,IAAQ,IAAK,MAIjClP,MAAMoP,IACLjW,OAAOuK,oBAAoBnN,GAA8ByY,GAElDI,IAEb,GAAC,CASML,0EAEL,OAAI9V,MACMC,kBAELmW,oBAAoBrP,MAAKsP,GACC,YAApBA,IACNC,OAAM,KAAM,GAInB,GAAC,CAQDxf,YAAmBuW,GAAwB8E,WACzCA,GAAa,GACkB,IAC/Blb,QAEAG,KAAKkW,eAAiBD,EACtBjW,KAAKgb,YAAcD,EACnB/a,KAAKye,OAAS,IAAI7D,EACpB,CAKOhM,UACL5O,KAAKyT,UACLzT,KAAKye,OAAO5P,MACZ7O,KAAK6O,KACP,CAKOtD,OAAOW,EAAgBhD,EAAaC,EAAe4D,GACnD/M,KAAKgb,YAGRhb,KAAKmf,gBAAgBjT,EAAQhD,EAAKC,EAAO4D,GAFzC/M,KAAKuO,kBAAkBrC,EAAQa,EAInC,CAKOwG,SACDvT,KAAKye,OAAO1I,UAEhB/V,KAAKye,OAAOlL,SACZvT,KAAKkW,gBAAiB,EACtBlW,KAAK4P,QAAQjL,GAAuB,CAAE8T,QAASzY,KAAM0Y,cAAc,IACrE,CAKOjF,UACAzT,KAAKye,OAAO1I,UAEjB/V,KAAKye,OAAOhL,UACZzT,KAAK4P,QAAQjL,GAAwB,CAAE+T,cAAc,IACvD,CAKOC,OAAe,CAEdwG,gBAAgBjT,EAAgBhD,EAAaC,EAAe4D,GAClE,MAAMqS,EAAQpf,KAAKye,OACnB,IAAKW,EAAMrJ,QAAS,OAEpB,MACE7M,IAAKmW,EACLlW,MAAOmW,GACLF,EAAMlD,eAEVhT,EAAI5C,IAAI+Y,GACRlW,EAAM7C,IAAIgZ,GAEVpT,EAAOiD,OAAO,CACZjG,IAAKA,EAAIpI,IACTqI,MAAOA,EAAMrI,IACbiM,QAEJ,CAEQwB,kBAAkBrC,EAAgBa,GACxC,MAAMqS,EAAQpf,KAAKye,OACdW,EAAMrJ,UAEXqJ,EAAM7T,SACNW,EAAOc,OAAOoS,EAAM5V,WAAYuD,GAClC,ECzJF,MAAMwS,GAiBOC,oBAAkB,OAAOxf,KAAKyf,cAAgB,CAC9CD,kBAAc1e,GACnBA,IAAQd,KAAKyf,iBAEjBzf,KAAKyf,eAAiB3e,EAElBA,GAAOd,KAAKgW,SACdhW,KAAK0f,WAAWxZ,IACNpF,GACVd,KAAK0f,WAAWxZ,IAEpB,CAKWyZ,yBAAuB,OAAO3f,KAAK4f,mBAAqB,CACxDD,uBAAmB7e,GACxBA,IAAQd,KAAK4f,sBAEjB5f,KAAK4f,oBAAsB9e,EAEvBA,GAAOd,KAAKgW,SACdhW,KAAK6f,oBACK/e,GACVd,KAAK8f,sBAET,CAKWnM,iBAAe,OAAO3T,KAAK+f,eAAepM,UAAY,CACtDA,eAAW7S,GAAyCd,KAAK+f,eAAepM,WAAa7S,CAAK,CAI1Fkf,sBAAoB,OAAOhgB,KAAKigB,aAAatM,UAAY,CACzDqM,oBAAgBlf,GAA8Cd,KAAKigB,aAAatM,WAAa7S,CAAK,CAMlGof,sBAAoB,OAAOlgB,KAAKmgB,gBAAkB,CAClDD,oBAAgBpf,GAAgBd,KAAKmgB,iBAAmBrf,CAAK,CAQ7DiV,cAAY,OAAO/V,KAAKgW,QAAU,CAIlChJ,aAAW,OAAOhN,KAAK+f,cAAgB,CAIvChT,WAAS,OAAO/M,KAAKigB,YAAc,CAInCG,WAAS,OAAOpgB,KAAKqgB,YAAc,CAQnClK,gBACT,OAAOnW,KAAK+f,eAAe5J,WACtBnW,KAAKigB,aAAa9J,WAClBnW,KAAKqgB,aAAalK,SACzB,CASAzW,YAAmB8T,EAAsBtH,GAAgBsT,cACvDA,EAAa7L,WACbA,EAAUqM,gBACVA,EAAeL,mBACfA,EAAkB3S,OAClBA,EAAMD,KACNA,EAAIqT,KACJA,IA6JMpgB,KAAAsgB,oBAAuBlO,IAC7BA,EAAIG,gBAAgB,EAuBdvS,KAAAmX,cAAiB/E,IACnBpS,KAAKyf,iBAAmBrN,EAAIa,YAC9BjT,KAAK0f,WAAWxZ,GACjB,EAGKlG,KAAA8X,YAAe1F,IACjBpS,KAAKyf,iBAAmBrN,EAAIa,YAC9BjT,KAAK0f,WAAWxZ,GACjB,EAGKlG,KAASugB,UAAG,EAClB9H,UACAC,mBAKIA,GAAgB1Y,KAAKyf,gBACvBzf,KAAK0f,WAAWxZ,IAGlBuS,EAAQE,KAAK3Y,KAAKqM,QAAQ,EAGpBrM,KAAAwgB,WAAa,EACnB9H,mBAIIA,GACF1Y,KAAK0f,WAAWxZ,GACjB,EAGKlG,KAAAygB,sBAAwB,EAAGvS,gBACjCA,EAAUtB,mBAAmB+C,MAAK,KAChC3P,KAAK2Y,MAAM,GACX,EAzNF3Y,KAAKyf,eAAiBD,EACtBxf,KAAK4f,oBAAsBD,EAG3B3f,KAAKqM,QAAUH,EACflM,KAAK+X,WAAavE,EAClBxT,KAAKmgB,kBAAmB,EACxBngB,KAAKgW,UAAW,EAEhBhW,KAAK+f,eAAiB,IAAIjK,GAActC,GAAUxG,EAAQpF,GAAgBoF,IAC1EhN,KAAKigB,aAAe,IAAIlG,GAAYvG,GAAUzG,EAAMnF,GAAgBmF,IACpE/M,KAAKqgB,aAAe,IAAI7B,IAAa4B,EAAMxY,GAAgBwY,IAE3DpgB,KAAK+f,eAAepM,WAAaA,EACjC3T,KAAKigB,aAAatM,WAAaqM,EAE/BhgB,KAAK0gB,aACP,CASO9R,UACL5O,KAAKyT,UACLzT,KAAK+f,eAAenR,UACpB5O,KAAKigB,aAAarR,UAClB5O,KAAK0f,WAAWxZ,GAClB,CASO4I,OAAOC,EAAeC,GAC3B,MAAM9C,EAASlM,KAAKqM,QAEpBrM,KAAK+f,eAAejR,OAAO5C,EAAO6B,IAAK7B,EAAOnE,OAAQgH,EAAOC,EAC/D,CAOauE,kDACPvT,KAAKgW,WAEJhW,KAAK+f,eAAe9J,eACvBjW,KAAK+f,eAAexM,SAGjBvT,KAAKigB,aAAahK,eACrBjW,KAAKigB,aAAa1M,SAGfvT,KAAKqgB,aAAapK,sBACXuI,GAAYmC,gBACpB3gB,KAAKqgB,aAAa9M,SAItBvT,KAAK2Y,OAED3Y,KAAK4f,qBACP5f,KAAK6f,oBAGP7f,KAAKgW,UAAW,EAClB,GAAC,CAOMvC,UACAzT,KAAKgW,WAEVhW,KAAK+f,eAAetM,UACpBzT,KAAKigB,aAAaxM,UAClBzT,KAAKqgB,aAAa5M,UAElBzT,KAAK8f,sBAEL9f,KAAKgW,UAAW,EAClB,CASOzK,OAAOM,GACZ,MAAMK,EAASlM,KAAKqM,QACduU,EAAgB5gB,KAAK+f,eACrBc,EAAc7gB,KAAKigB,aACnBa,EAAc9gB,KAAKqgB,aAEzBQ,EAAYtV,OAAOM,GACnB,MAAMkB,GbhJiB6E,EagJC1F,EAAO6B,IbhJSA,EagJJ8S,EAAY9T,Kb/I3B7I,KAAK+D,IAAIrD,GAAagN,EAAU,IACnC1N,KAAK+D,IAAIrD,GAAamJ,EAAM,KAFxBgT,IAACnP,EAAiB7D,EamJxC,MAAMiT,EAAYhhB,KAAKmgB,iBAAmB,EAAIjc,KAAKiB,IAAI4H,EAAM,GAC7D6T,EAActI,aAAa0I,GAC3BJ,EAAcvI,YAAYnM,EAAQa,GAClC6T,EAAcrV,OAAOM,GAErB,MAAM3C,EAAM0X,EAAc1X,IACpBC,EAAQyX,EAAczX,MAExB2X,EAAY/K,QACd+K,EAAYvV,OAAOW,EAAQhD,EAAKC,EAAO4D,GAEvCb,EAAOiD,OAAO,CACZjG,IAAKA,EAAIpI,IACTqI,MAAOA,EAAMrI,IACbiM,QAGN,CAOO4L,OACL,MAAMzM,EAASlM,KAAKqM,QAEpBrM,KAAKigB,aAAatH,KAAKzM,GACvBlM,KAAK+f,eAAepH,KAAKzM,EAC3B,CAEQ2T,oBACK7f,KAAK+X,WAEbnF,iBAAiB1M,EAA6BlG,KAAKsgB,oBACxD,CAEQR,sBACK9f,KAAK+X,WAEb1E,oBAAoBnN,EAA6BlG,KAAKsgB,oBAC3D,CAMQZ,WAAWuB,GACjB,IAAKjhB,KAAKyf,gBAAkBwB,IAAc/a,GAAqB,OAE9ClG,KAAK+X,WACbmJ,MAAMC,OAASF,CAC1B,CAEQP,cACN,MAAME,EAAgB5gB,KAAK+f,eACrBc,EAAc7gB,KAAKigB,aAEzBW,EAAc9H,GAAGnU,GAA4B3E,KAAKmX,eAClDyJ,EAAc9H,GAAGnU,GAA0B3E,KAAK8X,aAChD8I,EAAc9H,GAAGnU,GAAuB3E,KAAKugB,WAC7CK,EAAc9H,GAAGnU,GAAwB3E,KAAKwgB,YAC9CK,EAAY/H,GAAGnU,GAAuB3E,KAAKugB,WAC3CM,EAAY/H,GAAGnU,GAAwB3E,KAAKwgB,YAC5CxgB,KAAKqM,QAAQyM,GAAGpU,GAA6B1E,KAAKygB,sBACpD;;;;;;;;;;;;;;ulTC3VF,MAAeW,GAOb1hB,aAAmBqP,MACjBA,EAAKC,OACLA,EAAMqS,MACNA,IAMArhB,KAAK+O,MAAQA,EACb/O,KAAKgP,OAASA,EACdhP,KAAKqhB,MAAQA,EACbrhB,KAAKshB,MAAQC,sBAAsBC,cACnCxhB,KAAKyhB,MAAQF,sBAAsBC,aACrC,CAEO5S,UACL,CAGK8S,UACL,OAAO,CACT,CAEOC,SACL,OAAO,CACT,EClCF,MAAMC,WAAkBR,GAGtB1hB,aAAmBmiB,OACjBA,EAAM9S,MACNA,EAAKC,OACLA,EAAMqS,MACNA,IAOAxhB,MAAM,CACJkP,QACAC,SACAqS,UAGFrhB,KAAK6hB,OAASA,CAChB,ECrBF,MAAMC,WAAqBF,GAGlBhT,UACL,MAAMmT,EAAQ/hB,KAAK6hB,OAEnBE,EAAMC,QACND,EAAME,gBAAgB,OACtBF,EAAMG,MACR,CAEOR,UAAkC,OAAO,CAAM,CAE/CS,WACL,MAAMJ,EAAQ/hB,KAAK6hB,OAEnB,OAAOE,EAAMK,QAAUL,EAAMM,OAASN,EAAMO,YAAc,CAC5D,CAEOC,WACL,MAAMR,EAAQ/hB,KAAK6hB,OAEnB,OAAIE,EAAMS,YACDT,EAAMS,YAAY7a,OAAS,EAGK,MAArCoa,EAAMU,4BACDV,EAAMU,4BAA8B,EAGpB,MAArBV,EAAMW,aACDX,EAAMW,WAKjB,ECpCF,MAAMC,WAAoBvB,GAGxB1hB,aAAmBkjB,QACjBA,EAAO7T,MACPA,EAAKC,OACLA,EAAMqS,MACNA,IAOAxhB,MAAM,CACJkP,QACAC,SACAqS,UAGFrhB,KAAK4iB,QAAUA,CACjB,CAEOjB,SAAgC,OAAO,CAAM,EChBtD,MAAMkB,GAGJnjB,cACEM,KAAK8iB,aAAe,IAAIC,EAC1B,CAEab,KAAKc,EAA+BjB,4CAC/C,GAAIA,EACF,OAAO/hB,KAAKijB,UAAUD,EAAKpb,GAAgBma,IAE3C,GAAImB,MAAMC,QAAQH,IAAQA,EAAIrb,OAAS,EACrC,OAAO3H,KAAKojB,cAAcJ,GACrB,CACL,MAAMK,EAASH,MAAMC,QAAQH,GAAOA,EAAI,GAAKA,EAC7C,OAAOhjB,KAAKsjB,UAAUD,EACvB,CAEL,GAAC,CAEYC,UAAUN,4CACrB,MAAMO,EAASvjB,KAAKwjB,cAAcR,GAElC,OAAOhjB,KAAKyjB,MAAMF,GAAQ7W,IACxB,MAAMgX,EAAQH,EAAO,GAErB7W,EAAQ,IAAIkV,GAAU,CACpBC,OAAQ6B,EACR3U,MAAO2U,EAAMC,aACb3U,OAAQ0U,EAAME,cACdvC,OAAO,IACN,GAEP,GAAC,CAEY+B,cAAcJ,4CACzB,MAAMO,EAASvjB,KAAKwjB,cAAcR,GAElC,OAAOhjB,KAAKyjB,MAAMF,GAAQ7W,IACxBA,EAAQ,IAAIiW,GAAY,CACtBC,QAASW,EACTxU,MAAOwU,EAAO,GAAGI,aACjB3U,OAAQuU,EAAO,GAAGK,cAClBvC,OAAO,IACN,GAEP,GAAC,CAEY4B,UAAUD,EAA+Ba,4CACpD,MAAMC,iBACJC,UAAU,EACVC,OAAO,EACPhZ,MAAM,EACNiZ,OAAQ,GACLJ,GAEC9B,EAAQ/hB,KAAKkkB,gBAAgBlB,EAAKc,GAExC,OAAO9jB,KAAKyjB,MAAM,CAAC1B,IAAQrV,IACzB,MAAMqX,SAAEA,EAAQC,MAAEA,GAAUF,EAE5B/B,EAAMoC,YAAc,EAChBJ,GAAYC,GACdjC,EAAMqC,OAAOlF,OAAM,KAAY,IAGjCxS,EAAQ,IAAIoV,GAAa,CACvBD,OAAQE,EACRhT,MAAOgT,EAAMsC,WACbrV,OAAQ+S,EAAMuC,YACdjD,OAAO,IACN,GAEP,GAAC,CAEOoC,MAASc,EAAwBC,GACvC,MAAMC,EAASzkB,KAAK8iB,aAEpB,OAAO,IAAIrW,SAAQ,CAACC,EAASgY,KAC3BD,EAAOE,KAAK,SAASvS,IACfA,EAAIwS,WAAa,GAErBJ,EAAO9X,EAAQ,IAGjB+X,EAAOE,KAAK,QAASD,GACrBD,EAAOI,MAAMN,EAAQ,GAEzB,CAEQf,cAAcR,GAGpB,OAFaE,MAAMC,QAAQH,GAAOA,EAAM,CAACA,IAE7BhiB,KAAI6gB,IACd,GAAI/b,GAAS+b,GAAS,CACpB,MAAMiD,EAAQ,IAAIC,MAKlB,OAHAD,EAAME,YAAc,YACpBF,EAAM9B,IAAMnB,EAELiD,CACR,CACC,OAAOjD,CACR,GAEL,CAEQqC,gBAAgBlB,GAA+BgB,MACrDA,EAAKhZ,KACLA,EAAIiZ,OACJA,IAEA,GAAIjB,aAAeiC,iBACjB,OAAOjC,EAGT,MAAMjB,EAAQ3b,SAASL,cAAc,SAErCgc,EAAMiD,YAAc,YACpBjD,EAAMmD,aAAc,EACpBnD,EAAMoD,aAAa,qBAAsB,IACzCpD,EAAMiC,MAAQA,EACdjC,EAAMkC,OAASA,EACflC,EAAM/W,KAAOA,EAETkY,MAAMC,QAAQH,GAChBA,EAAIoC,SAAQvD,GAAU7hB,KAAKqlB,qBAAqBtD,EAAOF,KAEvD7hB,KAAKqlB,qBAAqBtD,EAAOiB,GAQnC,OALoBjB,EAAMuD,iBAAiB,UAAU3d,OACnC,GAAKoa,EAAMO,WAAa,GACxCP,EAAMG,OAGDH,CACT,CAEQsD,qBAAqBtD,EAAyBiB,GACpD,GAAIA,aAAeuC,kBACjB,OAAOvC,EAGT,MAAMwC,EAAWpf,SAASL,cAAc,UACxCyf,EAASxC,IAAMA,EACfjB,EAAM0D,YAAYD,EACpB,EC3JF,MAAME,GASJhmB,YAAmBimB,EAAsBC,EAA8B9c,QACrE9I,KAAK2lB,aAAeA,EAEpB3lB,KAAK6lB,SAAWD,EAChB5lB,KAAK8lB,QAAU,EACf9lB,KAAK+lB,WAAa,EAClB/lB,KAAKgmB,iBAAmB,CAC1B,CAEO1b,MAAM2b,GACX,MAAML,EAAU5lB,KAAK6lB,SAGrB,IAAKD,IAAYK,EAAU,OAG3B,GAAIjmB,KAAK8lB,QAAU,GAAK9lB,KAAK+lB,WAAa,EAAG,OAE7C,MAAM/a,EAAOA,CAACkb,EAAeC,KAC3B,MAAMC,EAAOC,KAAKC,MACZza,EAAQ3H,KAAKe,IAAImhB,EAAOpmB,KAAKgmB,gBAAqC,IAApBhmB,KAAK2lB,cAEzDM,EAASpa,EAAOsa,GAEhBnmB,KAAKgmB,gBAAkBI,EACvBpmB,KAAK8lB,OAASF,EAAQW,sBAAsBvb,EAAK,EAGnDhL,KAAKgmB,gBAAkBK,KAAKC,MAC5BtmB,KAAK8lB,OAASF,EAAQW,sBAAsBvb,EAC9C,CAEOwb,OACDxmB,KAAK8lB,QAAU,GACjB9lB,KAAK6lB,SAASY,qBAAqBzmB,KAAK8lB,QAGtC9lB,KAAK+lB,WAAa,GACpBxM,aAAavZ,KAAK+lB,WAGpB/lB,KAAK8lB,QAAU,EACf9lB,KAAK+lB,WAAa,CACpB,CAEOW,cAAcd,GACnB5lB,KAAKwmB,OACLxmB,KAAK6lB,SAAWD,CAClB,ECxDF,MAAMe,GAMOC,wBAAsB,OAAO5mB,KAAK6mB,kBAAoB,CAKtD9Q,cAAY,OAAO/V,KAAKgW,QAAU,CAG7CtW,YAAmBknB,EAA4BE,GAsDvC9mB,KAAgB+mB,iBAAG,MACzB,IAAIC,GAAgB,EAEpB,MAAQ,KACFA,EACFA,GAAgB,EAIlBhnB,KAAKinB,WAAW,CAEnB,EAX0B,GArDzBjnB,KAAK6mB,mBAAqBD,EAE1B5mB,KAAKgW,UAAW,EAChBhW,KAAKknB,gBAAkB,KACvBlnB,KAAKinB,UAAYH,CACnB,CAKOvT,OAAOC,GAKZ,GAJIxT,KAAKgW,UACPhW,KAAKyT,UAGHzT,KAAK6mB,oBAAwB/d,OAAOqe,eAAgB,CACtD,MAAMC,EAAO5T,EAAQ6T,wBACfC,EAAiC,IAAfF,EAAKrY,OAA+B,IAAhBqY,EAAKpY,OAE3CuY,EAAiB,IAAIJ,eAAeG,EAAkBtnB,KAAK+mB,iBAAmB/mB,KAAKinB,WAEzFM,EAAeC,QAAQhU,GAEvBxT,KAAKknB,gBAAkBK,CACxB,MACCze,OAAO8J,iBAAiB1M,EAAuBlG,KAAKinB,WAKtD,OAFAjnB,KAAKgW,UAAW,EAEThW,IACT,CAKOyT,UACL,IAAKzT,KAAKgW,SAAU,OAAOhW,KAE3B,MAAMunB,EAAiBvnB,KAAKknB,gBAU5B,OATIK,GACFA,EAAeE,aACfznB,KAAKknB,gBAAkB,MAEvBpe,OAAOuK,oBAAoBnN,EAAuBlG,KAAKinB,WAGzDjnB,KAAKgW,UAAW,EAEThW,IACT,EC1BF,MAAM0nB,GAyBO3R,cAAY,OAAO/V,KAAKgW,QAAU,CAIlCC,oBAAkB,OAAOjW,KAAKkW,cAAgB,CAO9CyR,cACT,OAAO3nB,KAAKgW,WAAahW,KAAK4nB,YAChC,CAQWC,YAAU,OAAO7nB,KAAK8nB,MAAQ,CAC9BD,UAAM/mB,GAAed,KAAK8nB,OAAShnB,CAAK,CAQxCinB,wBAAsB,OAAO/nB,KAAKgoB,kBAAoB,CACtDD,sBAAkBjnB,GAAed,KAAKgoB,mBAAqBlnB,CAAK,CAQhEmnB,YAAU,OAAOjoB,KAAKkoB,MAAQ,CAC9BD,UAAMnnB,GAAed,KAAKkoB,OAASpnB,CAAK,CAQxCqnB,mBAAiB,OAAOnoB,KAAKooB,aAAe,CAC5CD,iBAAarnB,GAAgBd,KAAKooB,cAAgBtnB,CAAK,CAQvDunB,mBAAiB,OAAOroB,KAAKsoB,aAAe,CAC5CD,iBAAavnB,GAAgBd,KAAKsoB,cAAgBxnB,CAAK,CAQvDynB,yBAAuB,OAAOvoB,KAAKwoB,mBAAqB,CACxDD,uBAAmBznB,GAAgBd,KAAKwoB,oBAAsB1nB,CAAK,CAS9EpB,YAAmB+oB,EAAiBjV,EAAsBkV,GA6HlD1oB,KAAamX,cAAG,KACjBnX,KAAKsoB,gBAEVtoB,KAAK4nB,cAAe,EACpB5nB,KAAK2oB,gBAAe,EAGd3oB,KAAW8X,YAAG,KACpB9X,KAAK4oB,4BAA4B5oB,KAAK8nB,OAAO,EAGvC9nB,KAAa6oB,cAAG,KACtB7oB,KAAKyT,SAAS,EAGRzT,KAAa8oB,cAAG,KACjB9oB,KAAKooB,gBACVpoB,KAAK4nB,cAAe,EACpB5nB,KAAK+oB,WAAY,EAAI,EAGf/oB,KAAagpB,cAAG,KACjBhpB,KAAKooB,gBACVpoB,KAAK+oB,WAAY,EACjB/oB,KAAK4oB,4BAA4B5oB,KAAKgoB,oBAAmB,EApJzDhoB,KAAKqM,QAAUoc,EAAOvc,OACtBlM,KAAKipB,SAAWR,EAAOhQ,QACvBzY,KAAKkpB,SAAW1V,EAEhBxT,KAAKgW,UAAW,EAChBhW,KAAK4nB,cAAe,EACpB5nB,KAAKmpB,oBAAsB,EAC3BnpB,KAAK+oB,WAAY,EAEjB,MAAMlB,MACJA,EAAQ,IAAIE,kBACZA,EAAoB,EAACE,MACrBA,EAAQ,EAACE,aACTA,GAAe,EAAKE,aACpBA,GAAe,EAAIE,mBACnBA,GAAqB,GACnB3gB,GAAgB8gB,GAEpB1oB,KAAKkW,gBAAkBwS,EACvB1oB,KAAK8nB,OAASD,EACd7nB,KAAKgoB,mBAAqBD,EAC1B/nB,KAAKkoB,OAASD,EACdjoB,KAAKooB,cAAgBD,EACrBnoB,KAAKsoB,cAAgBD,EACrBroB,KAAKwoB,oBAAsBD,CAC7B,CAOO3Z,UACL5O,KAAKyT,SACP,CAQOlI,OAAOC,GACZ,IAAKxL,KAAKgW,SAAU,OACpB,GAAIhW,KAAK4nB,aAKP,YAJI5nB,KAAKwoB,qBACPxoB,KAAKyT,WAMT,MAAMvH,EAASlM,KAAKqM,QACdR,GAAS7L,KAAKkoB,OAAS1c,EAAY,IAEzCU,EAAOhD,IAAM9B,GAAU8E,EAAOhD,IAAM2C,EAAO,EAAG,IAChD,CAOO0H,SACL,MAAMkF,EAAUzY,KAAKipB,SACfzV,EAAUxT,KAAKkpB,SAEjBlpB,KAAKgW,UAAYyC,EAAQ2H,KAAKrK,UAElC0C,EAAQzL,OAAO8L,GAAGnU,GAA4B3E,KAAKmX,eACnDsB,EAAQzL,OAAO8L,GAAGnU,GAA0B3E,KAAK8X,aAEjDW,EAAQ1L,KAAK+L,GAAGnU,GAA4B3E,KAAKmX,eACjDsB,EAAQ1L,KAAK+L,GAAGnU,GAA0B3E,KAAK8X,aAE/CW,EAAQ2H,KAAKtH,GAAGnU,GAAuB3E,KAAK6oB,eAE5CrV,EAAQZ,iBAAiB1M,EAA4BlG,KAAK8oB,eAAe,GACzEtV,EAAQZ,iBAAiB1M,EAA4BlG,KAAKgpB,eAAe,GAEzEhpB,KAAKgW,UAAW,EAChBhW,KAAKkW,gBAAiB,EACxB,CAOOkT,mBACLppB,KAAKuT,SACLvT,KAAK4nB,cAAe,EACpB5nB,KAAK4oB,4BAA4B5oB,KAAK8nB,OACxC,CAOOrU,UACL,IAAKzT,KAAKgW,SAAU,OAEpB,MAAMyC,EAAUzY,KAAKipB,SACfzV,EAAUxT,KAAKkpB,SAErBzQ,EAAQzL,OAAO6B,IAAIlK,GAA4B3E,KAAKmX,eACpDsB,EAAQzL,OAAO6B,IAAIlK,GAA0B3E,KAAK8X,aAElDW,EAAQ1L,KAAK8B,IAAIlK,GAA4B3E,KAAKmX,eAClDsB,EAAQ1L,KAAK8B,IAAIlK,GAA0B3E,KAAK8X,aAEhDW,EAAQ2H,KAAKvR,IAAIlK,GAAuB3E,KAAK6oB,eAE7CrV,EAAQH,oBAAoBnN,EAA4BlG,KAAK8oB,eAAe,GAC5EtV,EAAQH,oBAAoBnN,EAA4BlG,KAAKgpB,eAAe,GAE5EhpB,KAAKgW,UAAW,EAChBhW,KAAK4nB,cAAe,EACpB5nB,KAAK+oB,WAAY,EAEjB/oB,KAAK2oB,eACP,CA6BQC,4BAA4Bf,GAC9B7nB,KAAK+oB,YAET/oB,KAAK2oB,gBAEDd,EAAQ,EACV7nB,KAAKmpB,mBAAqBrgB,OAAOuQ,YAAW,KAC1CrZ,KAAK4nB,cAAe,EACpB5nB,KAAKmpB,oBAAsB,CAAC,GAC3BtB,IAEH7nB,KAAK4nB,cAAe,EACpB5nB,KAAKmpB,oBAAsB,GAE/B,CAEQR,gBACF3oB,KAAKmpB,oBAAsB,IAC7BrgB,OAAOyQ,aAAavZ,KAAKmpB,oBACzBnpB,KAAKmpB,oBAAsB,EAE/B,ECjTF,MAAME,WAAkBnc,EA+BtBxN,YAAmB4pB,EAAmBZ,EAA4B,IAChE7oB,QAaKG,KAAO4O,QAAG,KACf5O,KAAKupB,OACLvpB,KAAK6O,KAAK,EA0HJ7O,KAAawpB,cAAG,KACtBxpB,KAAKupB,OACLvpB,KAAK4P,QAAQrO,GAAOsC,OAAO,EAzI3B7D,KAAKypB,WAAa,KAClBzpB,KAAK0pB,YAAc,KACnB1pB,KAAK2pB,KAAOL,EACZtpB,KAAK4pB,SAAWlB,CAClB,CAiBa/H,uDAEX,MAAMkJ,EAAK/gB,OAAOghB,UAAUD,GAC5B,QAAKA,GAEEA,EAAGE,mBAAmBtkB,IAC1BkK,MAAKoP,GACGA,IACNG,OAAM,KACA,GAEb,GAAC,CAOY8K,iDACX,MAAMV,EAAMtpB,KAAK2pB,KAGXE,EAAK/gB,OAAOghB,UAAUD,GAC5B,IAAKA,EAAI,aAEHrL,GAAYyL,0BAElB,MAAMvB,EACD5oB,OAAA0V,OAAA,CACD0U,iBAAkB,CAACxkB,KAElB1F,KAAK4pB,gBAGJN,EAAIa,mBAEV,MAAMC,QAAgBP,EAAGQ,eAAe5kB,GAAYijB,GACpDY,EAAIgB,YAAYF,GAEhB,MAAMG,QAAiBH,EAAQI,sBAAsB9kB,IAErD1F,KAAKyqB,YAAYL,EAASG,GAE1BvqB,KAAK4P,QAAQrO,GAAOqC,SAAU,CAC5BwmB,WAEJ,GAAC,CAOMb,OACL,MAAMmB,EAAY1qB,KAAKypB,WAEnBiB,GACFA,EAAUlgB,MACP0U,OAAM,KAAY,IAGvBlf,KAAKypB,WAAa,KAClBzpB,KAAK0pB,YAAc,IACrB,CAKOiB,UAAUxE,GACf,MAAMoE,EAAWvqB,KAAK0pB,YAEtB,IAAKa,EAAU,OAAO,EAItB,QAFapE,EAAMyE,cAAcL,EAGnC,CAKOM,aAAa1E,GAKlB,MAAMiE,EAAUjE,EAAMiE,QAChBU,EAAO3E,EAAMyE,cAAc5qB,KAAK0pB,aAEtC,IAAKoB,EAAM,OAAO,KAElB,MAAMC,EAAUX,EAAQY,YAAYC,UAEpC,OAAKF,EAEED,EAAKI,MAAMlqB,KAAI+I,IAIb,CACLohB,SAJeJ,EAAQK,YAAYrhB,GAKnCshB,QAJcthB,EAAKuhB,UAAUC,QAAQC,OAKrCC,QAAS1hB,EAAK2E,qBATG,IAYvB,CAEQ+b,YAAYL,EAAoBG,GACtCvqB,KAAKypB,WAAaW,EAClBpqB,KAAK0pB,YAAca,EAEnBH,EAAQxX,iBAAiB1M,GAAuBlG,KAAKwpB,cACvD,EC7KF,MAAMkC,GAcJhsB,YAAmB8T,EAAsBvF,GACvCjO,KAAKwT,QAAUA,EACfxT,KAAKiO,SAAWA,CAClB,ECKF,MAAM0d,GAgBJjsB,YAAmBksB,EAAqBC,GAAyB9e,KAC/DA,GAAO,IAEP/M,KAAK8rB,aAAevlB,GAAmB,IAAIhE,GAAcK,oBAAqBgpB,GAC9E5rB,KAAK+rB,UAAYF,EACjB7rB,KAAKgsB,UAAY,GAEjBhsB,KAAKisB,MAAQlf,CACf,CAOOmf,UACL,MAAMC,EAAYnsB,KAAK8rB,aACvB,IAAKK,EAAW,OAEhB,MAAMC,EAAa,GAAGC,MAAMC,MAAMH,EAAU7G,qBAAqB/iB,GAAcM,YAC/E7C,KAAKgsB,UAAYI,EAAWprB,KAAImF,GAAMnG,KAAKusB,cAAcpmB,IAC3D,CAOOqmB,OAAOtgB,GACZ,MAAMugB,EAAWzsB,KAAKgsB,UAChBU,EAAmC,GAAvB1sB,KAAK+rB,UAAUhd,MAC3B4d,EAAqC,GAAxB3sB,KAAK+rB,UAAU/c,OAC5BjC,EAAOb,EAAOa,KACd6f,EAAkB,wBAClBC,EAAgB7sB,KAAKisB,MAAQ,SAASlf,KAAU,GAEtD0f,EAASrH,SAAQ0H,IACf,MAAM7e,EAAW6e,EAAQ7e,SACnB8e,EAAS/iB,IAMf,+CAJAA,CAAU+iB,EAAQ9e,GAClBjE,EAAmB+iB,EAAQA,EAAQ7gB,EAAOsC,YAC1CxE,EAAmB+iB,EAAQA,EAAQ7gB,EAAOwC,kBAEtCqe,EAAO,GAAK,GAAKA,EAAO,GAAK,EAE/B,YADAD,EAAQtZ,QAAQnN,UAAU2mB,OAAOzqB,GAAcO,iBAIjD,MAAMmqB,sDAAYC,CAChBH,EAAO,GAAKL,EAAYA,GACvBK,EAAO,GAAKJ,EAAaA,GAG5BG,EAAQtZ,QAAQnN,UAAUC,IAAI/D,GAAcO,iBAC5CgqB,EAAQtZ,QAAQ0N,MAAMoK,UAAY,CAChCsB,EACa,aAAAK,EAAU,SAASA,EAAU,QAC1CJ,GACA3rB,KAAK,IAAI,GAEf,CAEQqrB,cAAc/Y,GACpB,MAAM2Z,EAAS3Z,EAAQ4Z,QAAQlkB,IACzBmkB,EAAW7Z,EAAQ4Z,QAAQjkB,MAC3BmkB,EAAc9Z,EAAQ4Z,QAAQnf,SAEpC,GAAIkf,GAAUE,EAAU,CACtB,MAAMnkB,EAAMikB,EAASI,WAAWJ,GAAU,EACpChkB,EAAQkkB,EAAWE,WAAWF,GAAY,EAE1Cpf,EAAWjO,KAAKwtB,gBAAgBtkB,EAAKC,GAE3C,OAAO,IAAIuiB,GAAQlY,EAASvF,EAC7B,CAAM,GAAIqf,EAAa,CACtB,MAAMG,EAAgBH,EAAYhlB,MAAM,KAAKtH,KAAIF,GAAOysB,WAAWzsB,KACnE,GAAI2sB,EAAI9lB,OAAS,EACf,MAAM,IAAInI,EAAaqB,EAAeD,kBAAkB0sB,EAAa,qCAAwCzsB,EAAYD,mBAG3H,OAAO,IAAI8qB,GAAQlY,EAASxJ,EAAgByjB,EAAI,GAAIA,EAAI,GAAIA,EAAI,IACjE,CAAM,CAEL,MAAMC,EAAa1jB,EAAgB,EAAG,GAAI,GAE1C,OAAO,IAAI0hB,GAAQlY,EAASka,EAC7B,CACH,CAEQF,gBAAgBtkB,EAAaC,GACnC,MAAMwkB,EAASzkB,EAAMtE,GACfgpB,EAAWzkB,EAAQvE,GACnBqJ,EAAWjE,IAQjB,OANAiE,EAAS,GAAK/J,KAAKC,IAAIypB,GACvB3f,EAAS,GAAK/J,KAAKwY,IAAIkR,GAEvB3f,EAAS,GAAKA,EAAS,GAAK/J,KAAKC,KAAKwpB,GACtC1f,EAAS,IAAMA,EAAS,GAAK/J,KAAKwY,KAAKiR,GAEhC1f,CACT,EC7IF,MAAM4f,GASOC,YAAU,OAAO9tB,KAAK+tB,SAASC,SAASF,KAAO,CAE1DpuB,YAAY4V,EAAiByY,EAAoBE,GAC/CjuB,KAAKsV,IAAMA,EACXtV,KAAK+tB,SAAWA,EAChB/tB,KAAKiuB,QAAUA,CACjB,ECHF,MAAMC,GAYOC,aAAW,OAAOnuB,KAAKouB,OAAS,CAChCC,qBAAmB,OAAOruB,KAAKsuB,eAAiB,CAChDC,eAAa,OAAOvuB,KAAKwuB,SAAW,CACpCC,iBAAe,OAAOzuB,KAAKwuB,aAAexuB,KAAK0uB,YAAYC,GAAK,CAChEC,WAAS,OAAO5uB,KAAK6uB,YAAc,CACnCC,YAAU,OAAO9uB,KAAK+uB,MAAQ,CAEzCrvB,YAAmByuB,EAA2BW,GA4btC9uB,KAAcgvB,eAAG,KACRhvB,KAAKouB,QACb/nB,UAAUC,IAAI/D,GAAcG,UACnC1C,KAAK6uB,cAAe,CAAI,EAGlB7uB,KAAiBivB,kBAAG,KACXjvB,KAAKouB,QACb/nB,UAAU2mB,OAAOzqB,GAAcG,UACtC1C,KAAK6uB,cAAe,CAAK,EApczB7uB,KAAKouB,QAAUD,EACfnuB,KAAK6uB,cAAe,EACpB7uB,KAAK+uB,OAASD,EACd9uB,KAAK0uB,YAAc,CACjBC,IAAK,KACLO,YAAa,KAEjB,CAEOC,OACL,MAAMhB,EAASnuB,KAAKouB,SAEdgB,GAAEA,EAAEb,SAAEA,GAAavuB,KAAKqvB,YAAYlB,GAE1CnuB,KAAKsvB,IAAMF,EACXpvB,KAAKsuB,gBAAkBc,EAAGG,aAAaH,EAAGI,kBAC1CxvB,KAAKwuB,UAAYD,EAEZvuB,KAAKwuB,YACRxuB,KAAK0uB,YAAYC,IAAMS,EAAGK,aAAa,4BAGzCzvB,KAAK0uB,YAAYQ,YAAcE,EAAGK,aAAa,sBAE/CtB,EAAOvb,iBAAiB1M,GAA6BlG,KAAKgvB,gBAC1Db,EAAOvb,iBAAiB1M,GAAiClG,KAAKivB,kBAGhE,CAEOrgB,UACL,MAAMwgB,EAAKpvB,KAAKsvB,IACVnB,EAASnuB,KAAKouB,QAEhBgB,IAEFA,EAAGM,WAAWN,EAAGO,aAAc,MAC/BP,EAAGM,WAAWN,EAAGQ,qBAAsB,OAGzCzB,EAAO9a,oBAAoBnN,GAA6BlG,KAAKgvB,gBAC7Db,EAAO9a,oBAAoBnN,GAAiClG,KAAKivB,kBACnE,CAEOY,mBACL,MAAMC,EAAY9vB,KAAK0uB,YAAYQ,YAE9BY,GAELA,EAAUZ,aACZ,CAEOa,sBACL,MAAMD,EAAY9vB,KAAK0uB,YAAYQ,YAE9BY,GAELA,EAAUE,gBACZ,CAEOC,QACL,MAAMb,EAAKpvB,KAAKsvB,IAEhBF,EAAGa,MAAMb,EAAGc,iBACd,CAEOphB,SACL,MAAMsgB,EAAKpvB,KAAKsvB,IAEhBF,EAAGjE,SAAS,EAAG,EAAGiE,EAAGe,mBAAoBf,EAAGgB,oBAC9C,CAEOjF,SAASnnB,EAAWyF,EAAWsF,EAAeC,GACxChP,KAAKsvB,IAEbnE,SAASnnB,EAAGyF,EAAGsF,EAAOC,EAC3B,CAEOqhB,UAAUtC,EAAoBuC,GACnC,MAAMC,EAAYvwB,KAAKwwB,mBAEjB7B,EAAM,IAAId,GAAkB0C,EAAWxC,EAAU,CACrDC,SAAUhuB,KAAKywB,gBACfxiB,SAAUjO,KAAKywB,gBACfC,GAAI1wB,KAAKywB,kBAUX,OAPIF,IACFvwB,KAAK2wB,eAAeJ,GACpBvwB,KAAK4wB,oBAAoBjC,EAAK2B,GAC9BtwB,KAAK2wB,eAAe,MACpB3wB,KAAK6wB,kBAGAlC,CACT,CAEOmC,KAAKnC,EAAwB2B,GAClC,MAAMlB,EAAKpvB,KAAKsvB,IAEZX,EAAIrZ,IACNtV,KAAK2wB,eAAehC,EAAIrZ,KAExBtV,KAAK4wB,oBAAoBjC,EAAK2B,GAGhClB,EAAG2B,aAAa3B,EAAG4B,UAAWrC,EAAIb,MAAOsB,EAAG6B,eAAgB,GAExDtC,EAAIrZ,IACNtV,KAAK2wB,eAAe,MAEpB3wB,KAAK6wB,gBAET,CAEOK,WAAWvC,GACZA,EAAIrZ,KACNtV,KAAKmxB,iBAAiBxC,EAAIrZ,KAG5BtV,KAAKoxB,cAAczC,EAAIV,QAAQD,UAC/BhuB,KAAKoxB,cAAczC,EAAIV,QAAQhgB,UAC/BjO,KAAKoxB,cAAczC,EAAIV,QAAQyC,GACjC,CAEOW,oBAAuDC,EAAuBC,GACnF,MAAMnC,EAAKpvB,KAAKsvB,IAEVkC,EAAmB1xB,OAAO2xB,KAAKF,GAAUlc,QAAO,CAACqc,EAAW/oB,KAChE+oB,EAAU/oB,GAAkBymB,EAAGuC,mBAAmBL,EAAS3oB,GAEpD+oB,IACN,CAAyB,GAE5B,OACK5xB,OAAA0V,OAAA1V,OAAA0V,OAAA,CAAA,EAAAxV,KAAK4xB,2BAA2BN,IAChCE,EAEP,CAEOK,qBAAqBC,EAAkB5lB,EAAgBokB,GAC5D,MAAMlB,EAAKpvB,KAAKsvB,IAEVkC,EAAmBlB,EAAckB,iBAIjChG,EAASsG,EAAOtG,OAChBuG,EAAWtjB,IACjBA,EAAcsjB,EAAU7lB,EAAOsC,WAAYgd,GAE3C4D,EAAG4C,iBAAiBR,EAAiBS,WAAW,EAAOF,GACvD3C,EAAG4C,iBAAiBR,EAAiBU,UAAU,EAAOhmB,EAAOwC,iBAC/D,CAEOyjB,iBAAiB7B,EAA8ByB,EAAgBtG,EAAe2G,GACnF,MAAMhD,EAAKpvB,KAAKsvB,IAEVkC,EAAmBlB,EAAckB,iBAEvCpC,EAAG4C,iBAAiBR,EAAiBS,WAAW,EAAOF,GACvD3C,EAAG4C,iBAAiBR,EAAiBU,UAAU,EAAOzG,GAElD+F,EAAiBa,MACnBjD,EAAGkD,UAAUd,EAAiBa,KAAMD,EAExC,CAEOG,eAAejC,GACpB,MAAMlB,EAAKpvB,KAAKsvB,IAEViC,EAAWjB,EAAciB,SACzBC,EAAmBlB,EAAckB,iBAEvC,IAAK,MAAM7oB,KAAO4oB,EAAU,CAC1B,MAAMiB,EAAUjB,EAAS5oB,GACnBgM,EAAW6c,EAAiB7oB,GAE7B6pB,IAEDA,EAAQC,aACVD,EAAQjnB,OAAO6jB,EAAIza,EAAU3U,KAAKwuB,WAErC,CACH,CAEOkE,uBAAuBpC,GAC5B,MAAMlB,EAAKpvB,KAAKsvB,IAEViC,EAAWjB,EAAciB,SAE/B,IAAK,MAAM5oB,KAAO4oB,EAAU,CAC1B,MAAMiB,EAAUjB,EAAS5oB,GAEpB6pB,IAEDA,EAAQC,aACVD,EAAQ5jB,QAAQwgB,GAEnB,CAEDA,EAAGuD,cAAcrC,EAAcgB,QACjC,CAEOsB,WAAWtC,GACLtwB,KAAKsvB,IAEbsD,WAAWtC,EAAcgB,QAC9B,CAEOuB,cAAcC,EAAsBC,GACzC,MAAM3D,EAAKpvB,KAAKsvB,IACVgC,EAAUlC,EAAGyD,gBAEbG,EAAKhzB,KAAKizB,eAAe7D,EAAG8D,cAAeJ,GAC3CK,EAAKnzB,KAAKizB,eAAe7D,EAAGgE,gBAAiBL,GAQnD,GANA3D,EAAGiE,aAAa/B,EAAS0B,GACzB5D,EAAGiE,aAAa/B,EAAS6B,GACzB/D,EAAGkE,mBAAmBhC,EAAS,EAAG,YAClClC,EAAGkE,mBAAmBhC,EAAS,EAAG,MAClClC,EAAGmE,YAAYjC,GAEXtxB,KAAK+uB,SAAWK,EAAGoE,oBAAoBlC,EAASlC,EAAGqE,aAAc,CACnE,IAAInyB,EAA2B,KAQ/B,MANK8tB,EAAGsE,mBAAmBV,EAAI5D,EAAGuE,gBAEtBvE,EAAGsE,mBAAmBP,EAAI/D,EAAGuE,kBACvCryB,EAAY8tB,EAAGwE,iBAAiBT,IAFhC7xB,EAAY8tB,EAAGwE,iBAAiBZ,GAK5B,IAAIxzB,EAAaqB,EAAeF,uBAAuByuB,EAAGyE,kBAAkBvC,GAAUhwB,GAAYT,EAAYF,uBACrH,CAKD,OAHAyuB,EAAG0E,aAAad,GAChB5D,EAAG0E,aAAaX,GAET7B,CACT,CAEOyC,mBAAmBC,GACxB,MAAM5E,EAAKpvB,KAAKsvB,IACV2E,EAAU7E,EAAG8E,gBAQnB,GANA9E,EAAG+E,YAAY/E,EAAGgF,WAAYH,GAC9B7E,EAAGiF,cAAcjF,EAAGgF,WAAYhF,EAAGkF,mBAAoBlF,EAAGrrB,QAC1DqrB,EAAGiF,cAAcjF,EAAGgF,WAAYhF,EAAGmF,mBAAoBnF,EAAGrrB,QAC1DqrB,EAAGiF,cAAcjF,EAAGgF,WAAYhF,EAAGoF,eAAgBR,EAAQ1S,OAC3D8N,EAAGiF,cAAcjF,EAAGgF,WAAYhF,EAAGqF,eAAgBT,EAAQvS,QAEtDuS,EAAQtS,WAAa1hB,KAAKwuB,UAAW,CACxC,MAAMkG,EAAMtF,EAEZsF,EAAIC,aAAaD,EAAIN,WAAY,EAAGM,EAAIE,MAAOZ,EAAQjlB,MAAOilB,EAAQhlB,OACvE,CAED,OAAOilB,CACT,CAEOY,uBAAuBb,EAAkB3sB,GAC9C,MAAM+nB,EAAKpvB,KAAKsvB,IACV2E,EAAU7E,EAAG8E,gBAQnB,GANA9E,EAAG+E,YAAY/E,EAAG0F,iBAAkBb,GACpC7E,EAAGiF,cAAcjF,EAAG0F,iBAAkB1F,EAAGkF,mBAAoBlF,EAAGrrB,QAChEqrB,EAAGiF,cAAcjF,EAAG0F,iBAAkB1F,EAAGmF,mBAAoBnF,EAAGrrB,QAChEqrB,EAAGiF,cAAcjF,EAAG0F,iBAAkB1F,EAAGoF,eAAgBR,EAAQ1S,OACjE8N,EAAGiF,cAAcjF,EAAG0F,iBAAkB1F,EAAGqF,eAAgBT,EAAQvS,OAE7DzhB,KAAKwuB,UAAW,CAClB,MAAMkG,EAAMtF,EAEZsF,EAAIC,aAAaD,EAAII,iBAAkB,EAAGJ,EAAIE,MAAOvtB,EAAMA,EAC5D,CAED,OAAO4sB,CACT,CAEa9J,4DACX,MAAMiF,EAAKpvB,KAAKsvB,IACVyF,EAAa3F,EAAG4F,uBAElBD,IAA0C,IAA5BA,EAAWE,qBACrB7F,EAAGjF,mBAEb,GAAC,CAEMG,YAAYF,GACjB,MAAMgF,EAAKpvB,KAAKsvB,IACV4F,EAAU,IAAIC,aAAa/K,EAASgF,GAC1ChF,EAAQgL,kBAAkB,CAAEnK,UAAWiK,GACzC,CAEOG,YAAYlP,GACjB,MAAMiJ,EAAKpvB,KAAKsvB,IAEVrE,EADU9E,EAAMiE,QACIY,YAAYC,UAEtCmE,EAAGkG,gBAAgBlG,EAAGmG,YAAatK,EAAUuK,YAC/C,CAEOC,wBACL,MAAMrG,EAAKpvB,KAAKsvB,IAChBF,EAAGkG,gBAAgBlG,EAAGmG,YAAa,KACrC,CAEQ9E,gBACN,OAAOzwB,KAAKsvB,IAAIoG,cAClB,CAEQtE,cAAcuE,GACpB,OAAO31B,KAAKsvB,IAAIsG,aAAaD,EAC/B,CAEQnF,mBACN,MAAMpB,EAAKpvB,KAAKsvB,IAEhB,GAAItvB,KAAKwuB,UACP,OAAQY,EAA8ByG,oBACjC,CACL,MAAMC,EAAM91B,KAAK0uB,YAAYC,IAE7B,OAAOmH,aAAG,EAAHA,EAAKC,yBAA0B,IACvC,CACH,CAEQpF,eAAehC,GACrB,MAAMS,EAAKpvB,KAAKsvB,IAEhB,GAAItvB,KAAKwuB,UACNY,EAA8B4G,gBAAgBrH,OAC1C,CACL,MAAMmH,EAAM91B,KAAK0uB,YAAYC,IAE7BmH,SAAAA,EAAKG,mBAAmBtH,EACzB,CACH,CAEQwC,iBAAiBxC,GACvB,MAAMS,EAAKpvB,KAAKsvB,IAEhB,GAAItvB,KAAKwuB,UACNY,EAA8B8G,kBAAkBvH,OAC5C,CACL,MAAMmH,EAAM91B,KAAK0uB,YAAYC,IAE7BmH,SAAAA,EAAKK,qBAAqBxH,EAC3B,CACH,CAEQiC,oBAAoBjC,EAAwB2B,GAClD,MAAMvC,EAAWY,EAAIZ,SAErB/tB,KAAKo2B,oBAAoBrI,EAASC,SAAUW,EAAIV,QAAQD,UACxDhuB,KAAKq2B,qBAAqBtI,EAASuI,SAAUhG,EAAcgB,QAAS,WAAY3C,EAAIV,QAAQhgB,UAC5FjO,KAAKq2B,qBAAqBtI,EAASwI,IAAKjG,EAAcgB,QAAS,KAAM3C,EAAIV,QAAQyC,GACnF,CAEQG,iBACN,MAAMzB,EAAKpvB,KAAKsvB,IAEhBF,EAAGM,WAAWN,EAAGQ,qBAAsB,MACvCR,EAAGM,WAAWN,EAAGO,aAAc,KACjC,CAEQyG,oBAAoBpI,EAAmC2H,GAC7D,MAAMvG,EAAKpvB,KAAKsvB,IAEhBF,EAAGM,WAAWN,EAAGQ,qBAAsB+F,GACvCvG,EAAGoH,WAAWpH,EAAGQ,qBAAsB5B,EAASyI,KAAMrH,EAAGsH,YAC3D,CAEQL,qBAAqBM,EAAqCrF,EAAuBpxB,EAAcy1B,GACrG,MAAMvG,EAAKpvB,KAAKsvB,IACVsH,EAAiBxH,EAAGyH,kBAAkBvF,EAASpxB,GAGjD02B,EAAiB,IAErBxH,EAAGM,WAAWN,EAAGO,aAAcgG,GAC/BvG,EAAGoH,WAAWpH,EAAGO,aAAcgH,EAAUF,KAAMrH,EAAGsH,aAClDtH,EAAG0H,oBAAoBF,EAAgBD,EAAUI,SAAU3H,EAAG4H,OAAO,EAAO,EAAG,GAC/E5H,EAAG6H,wBAAwBL,GAC7B,CAEQ3D,eAAehyB,EAAc+hB,GACnC,MAAMoM,EAAKpvB,KAAKsvB,IACV4H,EAAS9H,EAAG+H,aAAal2B,GAK/B,OAHAmuB,EAAGgI,aAAaF,EAAQlU,GACxBoM,EAAGiI,cAAcH,GAEVA,CACT,CAEQtF,2BAA2BN,GACjC,MAAMlC,EAAKpvB,KAAKsvB,IAEhB,MAAO,CACL2C,UAAW7C,EAAGuC,mBAAmBL,EAAS,aAC1CY,SAAU9C,EAAGuC,mBAAmBL,EAAS,YAE7C,CAEQjC,YAAYlB,GAIlB,MAAMmJ,EAAmB,CAAC,SAAU,QAAS,qBAAsB,YAAa,aAChF,IAAI1R,EAAwC,KACxC2I,GAAW,EACf,MAAMgJ,EAAoB,CACxBC,uBAAuB,EACvBC,WAAW,GAGPC,EAA8BC,GAAKA,EAAEC,cAE3CzJ,EAAOvb,iBAAiB1M,EAAqCwxB,GAE7D,IAAK,MAAMG,KAAcP,EAAkB,CACzC,IACE1R,EAAUuI,EAAO2J,WAAWD,EAAYN,GACxChJ,EAA0B,WAAfsJ,CACZ,CAAC,MAAO1wB,GAAK,CACd,GAAIye,EACF,KAEH,CAID,GAFAuI,EAAO9a,oBAAoBnN,EAAqCwxB,IAE3D9R,EACH,MAAM,IAAIpmB,EAAaqB,EAAeL,oBAAqBK,EAAYL,qBAGzE,MAAO,CACL4uB,GAAIxJ,EACJ2I,WAEJ,ECpdF,MAAMwJ,GAYO5J,aAAW,OAAOnuB,KAAKouB,OAAS,CAMhCrf,YAAU,OAAO/O,KAAKg4B,aAAah0B,CAAG,CAMtCgL,aAAW,OAAOhP,KAAKg4B,aAAavuB,CAAG,CAUvCwuB,iBAAe,OAAOj4B,KAAKk4B,WAAa,CAWxCnwB,aAAW,OAAO/H,KAAKg4B,aAAah0B,EAAIhE,KAAKg4B,aAAavuB,CAAG,CAQxE/J,YAAmByuB,EAA2BW,GAC5C9uB,KAAKouB,QAAUD,EACfnuB,KAAKg4B,aAAe,CAAEh0B,EAAG,EAAGyF,EAAG,GAC/BzJ,KAAKk4B,YAAc,EACnBl4B,KAAKspB,IAAM,IAAI4E,GAAaC,EAAQW,EACtC,CAOOlgB,UACL,MAAMuf,EAASnuB,KAAKouB,QAEpBpuB,KAAKspB,IAAI1a,UACTuf,EAAOpf,MAAQ,EACfof,EAAOnf,OAAS,CAClB,CAOOF,SACL,MAAMqf,EAASnuB,KAAKouB,QACd+J,EAAan4B,KAAKg4B,aAClBI,EAAmBtvB,OAAOsvB,iBAEhCD,EAAWn0B,EAAImqB,EAAOkK,YACtBF,EAAW1uB,EAAI0kB,EAAOmK,aAEtBnK,EAAOpf,MAAQopB,EAAWn0B,EAAIo0B,EAC9BjK,EAAOnf,OAASmpB,EAAW1uB,EAAI2uB,EAE/Bp4B,KAAKk4B,YAAcE,EACnBp4B,KAAKspB,IAAIxa,QACX,CASO0d,OAAO+L,EAAwBrsB,GACpC,MAAMod,EAAMtpB,KAAKspB,IACXkP,EAAOD,EAAWE,WACpBnP,EAAIsF,MAAS4J,IAEjBlP,EAAI2G,QACJ3G,EAAIsJ,WAAW4F,EAAKlH,SACpBhI,EAAIuI,qBAAqB2G,EAAMtsB,EAAQssB,EAAKlH,SAC5CiH,EAAWhtB,OAAOW,GAClBod,EAAIiJ,eAAeiG,EAAKlH,SACxBhI,EAAIwH,KAAK0H,EAAK7J,IAAK6J,EAAKlH,SAC1B,CAWOoH,SAASH,EAAwBI,EAAexS,GACrD,MAAMmD,EAAMtpB,KAAKspB,IACXkP,EAAOD,EAAWE,UAClBG,EAAYD,EAAG9N,aAAa1E,GAE7ByS,GAAcJ,IAEnBlP,EAAI+L,YAAYlP,GAChBmD,EAAIsJ,WAAW4F,EAAKlH,SACpBhI,EAAIiJ,eAAeiG,EAAKlH,SAExBsH,EAAUxT,SAAQ,CAACyT,EAAKzG,KACtB,MAAMjH,EAAW0N,EAAI1N,SAGf4G,EAAWtjB,EAAcA,IAAeoqB,EAAIxN,QAASmN,EAAKhN,QAEhElC,EAAI6B,SAASA,EAASnnB,EAAGmnB,EAAS1hB,EAAG0hB,EAASpc,MAAOoc,EAASnc,QAC9Dsa,EAAI6I,iBAAiBqG,EAAKlH,QAASS,EAAU8G,EAAIpN,QAAS2G,GAC1D9I,EAAIwH,KAAK0H,EAAK7J,IAAK6J,EAAKlH,QAAQ,IAEpC,ECnFF,MAAMwH,WAAgB5rB,EAoDT0e,aAAW,OAAO5rB,KAAK+4B,OAAS,CAOhClN,eAAa,OAAO7rB,KAAK+rB,SAAW,CAOpC7f,aAAW,OAAOlM,KAAKqM,OAAS,CAOhCoM,cAAY,OAAOzY,KAAKipB,QAAU,CAalC0P,SAAO,OAAO34B,KAAKg5B,GAAK,CASxBlM,cAAY,OAAO9sB,KAAKi5B,QAAU,CAiBlCC,cAAY,OAAOl5B,KAAKm5B,QAAU,CAalCZ,iBAAe,OAAOv4B,KAAKo5B,WAAa,CACxCb,eAAWz3B,GAChBd,KAAKq5B,cAAgBv4B,EACvBd,KAAKkiB,KAAKphB,GAEVd,KAAKo5B,YAAct4B,CAEvB,CAiBWw4B,kBAAgB,OAAOt5B,KAAKq5B,YAAc,CAc1CtV,eAAa,OAAO/jB,KAAKu5B,SAAW,CAwBpCC,eAAa,OAAOx5B,KAAKy5B,SAAW,CAkBpCC,iBAAe,OAAO15B,KAAK25B,WAAa,CAuBxCC,qBAAmB,OAAO55B,KAAK65B,eAAiB,CAOhDjT,wBAAsB,OAAO5mB,KAAK6mB,kBAAoB,CAyBtDiT,eAAa,OAAO95B,KAAK+5B,SAAW,CACpCD,aAASh5B,GAClB,MAAMqtB,EAASnuB,KAAK+rB,UAAUoC,OAC9BnuB,KAAK+5B,UAAYj5B,EAEN,MAAPA,EACFqtB,EAAO2L,SAAWh5B,EAElBqtB,EAAOlM,gBAAgB,WAE3B,CASW0D,mBAAiB,OAAO3lB,KAAKg6B,UAAUrU,YAAc,CACrDA,iBAAa7kB,GAAuCd,KAAKg6B,UAAUrU,aAAe7kB,CAAK,CAQvFguB,YAAU,OAAO9uB,KAAK+uB,MAAQ,CAC9BD,UAAMhuB,GAAgCd,KAAK+uB,OAASjuB,CAAK,CAqBzD8M,iBAAe,OAAO5N,KAAKqM,QAAQuB,UAAY,CAC/CA,eAAW9M,GAAqCd,KAAKqM,QAAQuB,WAAa9M,CAAK,CAmB/E+M,mBAAiB,OAAO7N,KAAKqM,QAAQwB,YAAc,CACnDA,iBAAa/M,GAAuCd,KAAKqM,QAAQwB,aAAe/M,CAAK,CAmBrFgN,kBAAgB,OAAO9N,KAAKqM,QAAQyB,WAAa,CACjDA,gBAAYhN,GAAsCd,KAAKqM,QAAQyB,YAAchN,CAAK,CAkBlFwM,eAAa,OAAOtN,KAAKqM,QAAQiB,QAAU,CAC3CA,aAASxM,GAClBd,KAAKqM,QAAQiB,SAAWxM,EACpBd,KAAKo5B,aAAap5B,KAAKo5B,YAAYa,aAAaj6B,KAAKqM,QAC3D,CAmBWmB,iBAAe,OAAOxN,KAAKqM,QAAQmB,UAAY,CAC/CA,eAAW1M,GACpBd,KAAKqM,QAAQmB,WAAa1M,EACtBd,KAAKo5B,aAAap5B,KAAKo5B,YAAYa,aAAaj6B,KAAKqM,QAC3D,CAqBWqB,gBAAc,OAAO1N,KAAKqM,QAAQqB,SAAW,CAC7CA,cAAU5M,GACnBd,KAAKqM,QAAQqB,UAAY5M,EACrBd,KAAKo5B,aAAap5B,KAAKo5B,YAAYa,aAAaj6B,KAAKqM,QAC3D,CAeW0B,UAAQ,OAAO/N,KAAKqM,QAAQ0B,GAAK,CACjCA,QAAIjN,GACb,MAAMoL,EAASlM,KAAKqM,QACdoM,EAAUzY,KAAKipB,SAErB/c,EAAO6B,IAAMjN,EACboL,EAAOgD,eACPuJ,EAAQE,MACV,CAWW3L,aAAW,OAAOhN,KAAKipB,SAASjc,MAAQ,CASxCD,WAAS,OAAO/M,KAAKipB,SAASlc,IAAM,CASpCqT,WAAS,OAAOpgB,KAAKipB,SAAS7I,IAAM,CASpCZ,oBAAkB,OAAOxf,KAAKipB,SAASzJ,aAAe,CACtDA,kBAAc1e,GAAwCd,KAAKipB,SAASzJ,cAAgB1e,CAAK,CAOzF6e,yBAAuB,OAAO3f,KAAKipB,SAAStJ,kBAAoB,CAChEA,uBAAmB7e,GAA6Cd,KAAKipB,SAAStJ,mBAAqB7e,CAAK,CAaxG6S,iBAAe,OAAO3T,KAAKipB,SAAStV,UAAY,CAChDA,eAAW7S,GAAqCd,KAAKipB,SAAStV,WAAa7S,CAAK,CAahFkf,sBAAoB,OAAOhgB,KAAKipB,SAASjJ,eAAiB,CAC1DA,oBAAgBlf,GAA0Cd,KAAKipB,SAASjJ,gBAAkBlf,CAAK,CAsB1GpB,YAAmBw6B,GAA4B3B,WAC7CA,EAAa,KAAI3qB,WACjBA,EAAa,EAACC,aACdA,EAAe,EAACC,YAChBA,EAAc,EAACR,SACfA,EAAW,KAAIE,WACfA,EAAa,KAAIE,UACjBA,EAAY,KAAIK,IAChBA,EAAM,GAAEyR,cACRA,GAAgB,EAAIG,mBACpBA,GAAqB,EAAK3S,OAC1BA,GAAS,EAAID,KACbA,GAAO,EAAIqT,KACXA,GAAO,EAAKzM,WACZA,GAAa,EAAIqM,gBACjBA,GAAkB,EAAK+D,SACvBA,GAAW,EAAK+I,QAChBA,EAAU,CAAE,EAAA0M,SACZA,GAAW,EAAIE,WACfA,GAAa,EAAIE,eACjBA,EAAiB,SAAQhT,kBACzBA,GAAoB,EAAI9N,GACxBA,EAAK,CAAE,EAAAogB,QACPA,EAAU,GAAEvT,aACZA,EAAe,EAAI,GAAEmU,SACrBA,EAAW,EAAChL,MACZA,GAAQ,GACmB,IAC3BjvB,QA0OKG,KAAAm6B,YAAetuB,IACpB,MAAMK,EAASlM,KAAKqM,QACdwf,EAAW7rB,KAAK+rB,UAChBtT,EAAUzY,KAAKipB,SACf6D,EAAU9sB,KAAKi5B,SACfmB,EAAap6B,KAAKu5B,UAClBhB,EAAav4B,KAAKo5B,YAEnBb,IAELv4B,KAAKq6B,MAAM94B,GAAO+B,eAEd82B,EAAWzS,UACbyS,EAAW7uB,OAAOM,GAClB4M,EAAQE,QAGNzM,EAAOgC,UACThC,EAAOgC,UAAU3C,OAAOM,GAExB4M,EAAQlN,OAAOM,GAGjBggB,EAASW,OAAO+L,EAAYrsB,GAC5B4gB,EAAQN,OAAOtgB,GAEXA,EAAOkB,SACTpN,KAAKq6B,MAAM94B,GAAOmC,YAAa,CAC7BwF,IAAKgD,EAAOhD,IACZC,MAAO+C,EAAO/C,MACd4D,KAAMb,EAAOa,KACbvD,WAAY,CACV0C,EAAO1C,WAAW,GAClB0C,EAAO1C,WAAW,GAClB0C,EAAO1C,WAAW,GAClB0C,EAAO1C,WAAW,MAIxB0C,EAAO+F,gBAEPjS,KAAKq6B,MAAM94B,GAAOgC,QAAO,EAanBvD,KAAAs6B,qBAAwBzuB,UAC9B,MAAMK,EAASlM,KAAKqM,QACdoM,EAAUzY,KAAKipB,SACflF,EAAW/jB,KAAKu5B,UAChBtF,EAA0B,QAAhBruB,EAAA5F,KAAKo5B,mBAAW,IAAAxzB,OAAA,EAAAA,EAAE20B,aAE7Bv6B,KAAKq5B,cAAiBpF,IAExB/nB,EAAOgC,WACJuK,EAAQtC,WACR4N,EAAS4D,SACTsM,EAAQvS,YAGd1hB,KAAKm6B,YAAYtuB,EAAM,EAGjB7L,KAAAw6B,eAAiB,CAACC,EAAgBtU,KACxC,MAAMwS,EAAK34B,KAAKg5B,IACVT,EAAav4B,KAAKo5B,YAClBvN,EAAW7rB,KAAK+rB,UAEjBwM,IAELv4B,KAAKq6B,MAAM94B,GAAO+B,eAElBuoB,EAAS6M,SAASH,EAAYI,EAAIxS,GAElCnmB,KAAKq6B,MAAM94B,GAAOgC,QAAO,EA1TzBvD,KAAK+4B,Q5B7lBiB2B,EAACv0B,EAA0BK,KACnD,MAAMC,EAAWF,GAAmBJ,EAAIK,GAExC,IAAKC,EACH,MAAIX,GAASK,GACL,IAAI3G,EAAaqB,EAAeP,kBAAkB6F,GAAKtF,EAAYP,mBAEnE,IAAId,EAAaqB,EAAeT,WAAW+F,EAAI,CAAC,cAAe,WAAYtF,EAAYT,YAIjG,OAAOqG,CAAQ,E4BklBEi0B,CAAWR,GAC1Bl6B,KAAKm5B,SAAWD,EAChBl5B,KAAKq5B,cAAe,EAGpBr5B,KAAKy5B,UAAYD,EACjBx5B,KAAK25B,YAAcD,EACnB15B,KAAK65B,gBAAkBD,EACvB55B,KAAK6mB,mBAAqBD,EAC1B5mB,KAAK+5B,UAAYD,EACjB95B,KAAK+uB,OAASD,EAGd,MAAMX,E5B5lBgBwM,EAACT,EAAmBU,KAC5C,MAAMzM,EAAS+L,EAAKvzB,cAAci0B,GAElC,IAAKzM,EACH,MAAM,IAAI3uB,EAAaqB,EAAeN,iBAAkBM,EAAYN,kBAGtE,OAAO4tB,CAAM,E4BqlBIwM,CAAW36B,KAAK+4B,QAASa,GACxC55B,KAAK+rB,UAAY,IAAIgM,GAAc5J,EAAQW,GAC3C9uB,KAAKqM,QAAU,IAAIY,GAAO,CACxBW,aACAC,eACAC,cACAC,MACAT,WACAE,aACAE,cAEF1N,KAAKipB,SAAW,IAAI1J,GAAY4O,EAAQnuB,KAAKqM,QAAS,CACpDmT,gBACA7L,aACAqM,kBACAL,qBACA3S,SACAD,OACAqT,SAEFpgB,KAAKg6B,UAAY,IAAItU,GAAcC,GACnC3lB,KAAKu5B,UAAY,IAAI7R,GAAS1nB,KAAMmuB,EAAQpK,GAC5C/jB,KAAKo5B,YAAcb,EACnBv4B,KAAK66B,aAAe,IAAIlU,GAAYC,GAAmB,IAAM5mB,KAAK8O,WAClE9O,KAAKg5B,IAAM,IAAI3P,GAAUrpB,KAAK+rB,UAAUzC,KACxCtpB,KAAKi5B,SAAW,IAAItN,GAAgB3rB,KAAK+4B,QAAS/4B,KAAK+rB,UAAWe,GAElE9sB,KAAK86B,kBAAkBhiB,GAEnByf,GAAciB,GAChBx5B,KAAKmvB,MAET,CAOOvgB,UACL5O,KAAKqM,QAAQuC,UACb5O,KAAKg6B,UAAUxT,OACfxmB,KAAK+rB,UAAUnd,UACf5O,KAAKipB,SAASra,UACd5O,KAAK66B,aAAapnB,UAEdzT,KAAKo5B,cACPp5B,KAAKo5B,YAAY2B,oBAAoB/6B,KAAK+rB,UAAUzC,KACpDtpB,KAAKo5B,YAAc,MAGrBp5B,KAAKm5B,SAAS/T,SAAQ4V,GAAUA,EAAOpsB,QAAQ5O,QAE/CA,KAAKq5B,cAAe,CACtB,CAOalK,gDACX,IAAKnvB,KAAKo5B,YACR,MAAM,IAAI55B,EAAaqB,EAAeH,yBAA0BG,EAAYH,0BAG9E,MAAMmrB,EAAW7rB,KAAK+rB,UAChB7f,EAASlM,KAAKqM,QACdoM,EAAUzY,KAAKipB,SACfgS,EAAWj7B,KAAKg6B,UAChBlN,EAAU9sB,KAAKi5B,SACfV,EAAav4B,KAAKo5B,YAClBjL,EAAStC,EAASsC,OAExBnuB,KAAKk7B,uBACLrP,EAASvC,IAAI6F,OACbnvB,KAAKm7B,oBACLjvB,EAAOgD,eAEHlP,KAAK25B,aACP35B,KAAK66B,aAAatnB,OAAO4a,GAGtBnuB,KAAKu5B,UAAUtjB,eAClBjW,KAAKu5B,UAAUhmB,SAGjBvT,KAAKm5B,SAAS/T,SAAQ4V,IACpBA,EAAO7L,KAAKnvB,KAAK,IAGnB,MAAMi0B,QAAgBj0B,KAAKo7B,aAAa7C,GACxCv4B,KAAKq7B,iBAAiB9C,EAAYtE,EAAS,MAC3CnH,EAAQZ,UACR+O,EAAS3wB,MAAMtK,KAAKs6B,4BACd7hB,EAAQlF,SAEQ,MAAlBvT,KAAK+5B,WAAsB5L,EAAOmN,aAAa,cACjDnN,EAAO2L,SAAW95B,KAAK+5B,WAGzB/5B,KAAKq5B,cAAe,EACpBr5B,KAAKm6B,YAAY,GAEjBn6B,KAAKq6B,MAAM94B,GAAO0B,MACpB,GAAC,CAmBYif,KAAKqW,4CAChB,IAAKA,EAAY,OAAO,EAExB,GAAIv4B,KAAKq5B,aAAc,CACrB,MAAMpF,QAAgBj0B,KAAKo7B,aAAa7C,GACxCv4B,KAAKq7B,iBAAiB9C,EAAYtE,EAASj0B,KAAKo5B,aAChDp5B,KAAKm6B,YAAY,EAClB,MAECn6B,KAAKo5B,YAAcb,EACnBv4B,KAAKmvB,OAGP,OAAO,CACT,GAAC,CAOMrgB,SACL,IAAK9O,KAAKq5B,aAAc,OAExBr5B,KAAKm7B,oBAGLn7B,KAAKm6B,YAAY,GAEjB,MAAMprB,MAAEA,EAAKC,OAAEA,GAAWhP,KAAK+rB,UAE/B/rB,KAAKq6B,MAAM94B,GAAO8B,OAAQ,CACxB0L,QACAC,UAEJ,CAiBOusB,cAAcrC,GACfl5B,KAAKq5B,cACPH,EAAQ9T,SAAQ4V,IAAYA,EAAO7L,KAAKnvB,KAAK,IAG/CA,KAAKm5B,SAASqC,QAAQtC,EACxB,CAgBOuC,iBAAiBvC,GACtBA,EAAQ9T,SAAQ4V,IACd,MAAMU,EAAY17B,KAAKm5B,SAAS3wB,QAAQwyB,GAEpCU,EAAY,IAEhBV,EAAOpsB,QAAQ5O,MACfA,KAAKm5B,SAASwC,OAAOD,EAAW,GAAE,GAEtC,CAwDQrB,MAAqCuB,KAAiBC,GAC5D,MAAMC,EAAYD,EAASA,EAAO,GAAK,CAAA,EAEvC77B,KAAK4P,QAAQgsB,iBACX36B,KAAM26B,EACNG,OAAQ/7B,MACL87B,GAEP,CAiCQT,iBAAiB9C,EAAwBtE,EAAkB+H,GACjE,MAAM9vB,EAASlM,KAAKqM,QACdoM,EAAUzY,KAAKipB,SACf4C,EAAW7rB,KAAK+rB,UAGlBiQ,GACFA,EAAejB,oBAAoB/6B,KAAK+rB,UAAUzC,KAGpDiP,EAAW0D,aAAapQ,EAASvC,IAAK2K,GACtCsE,EAAW0B,aAAa/tB,GACxBqsB,EAAW2D,cAAczjB,GAEzBzY,KAAKo5B,YAAcb,EACnBv4B,KAAKq6B,MAAM94B,GAAO6B,kBAAmB,CACnCm1B,cAEJ,CAEc6C,aAAa7C,4CACzB,MAAM4D,EAAgB,IAAItZ,IACpBG,IAAEA,EAAGjB,MAAEA,GAAUwW,EAEvBv4B,KAAKq6B,MAAM94B,GAAO2B,WAAY,CAC5B8f,MACAjB,UAGF,MAAMkS,QAAgBkI,EAAcja,KAAKc,EAAKjB,GAO9C,OALA/hB,KAAKq6B,MAAM94B,GAAO4B,KAAM,CACtB6f,MACAjB,UAGKkS,CACT,GAAC,CAEOkH,oBACN,MAAMtP,EAAW7rB,KAAK+rB,UAChB7f,EAASlM,KAAKqM,QACdoM,EAAUzY,KAAKipB,SAErB4C,EAAS/c,SACT5C,EAAO4C,OAAO+c,EAAS9c,MAAO8c,EAAS7c,QACvCyJ,EAAQ3J,OAAO+c,EAAS9c,MAAO8c,EAAS7c,OAC1C,CAEQ8rB,kBAAkBsB,GAExBt8B,OAAO2xB,KAAK2K,GAAQhX,SAASiX,IAC3Br8B,KAAK8Y,GAAGujB,EAASD,EAAOC,GAAS,GAErC,CAEQnB,uBAEN,MAAMhB,EAAOl6B,KAAK+4B,QACZtgB,EAAUzY,KAAKipB,SACfgS,EAAWj7B,KAAKg6B,UAChBnO,EAAW7rB,KAAK+rB,UAChB4M,EAAK34B,KAAKg5B,IAEiB,CAC/Br0B,GACAA,GACAA,IAGuBygB,SAAQiX,IAC/B5jB,EAAQzL,OAAO8L,GAAGujB,GAASjqB,IACzBpS,KAAKq6B,MAAMgC,EAASjqB,EAAI,IAG1BqG,EAAQ1L,KAAK+L,GAAGujB,GAASjqB,IACvBpS,KAAKq6B,MAAMgC,EAASjqB,EAAI,GACxB,IAGJumB,EAAG7f,GAAGvX,GAAOqC,UAAUwO,IACrB8nB,EAAK7zB,UAAUC,IAAI/D,GAAcI,OAEjCs4B,EAASvU,cAActU,EAAIgY,SAC3B6Q,EAAS3wB,MAAMtK,KAAKw6B,gBAEpBx6B,KAAKq6B,MAAM94B,GAAOqC,SAAS,IAG7B+0B,EAAG7f,GAAGvX,GAAOsC,QAAQ,KACnBq2B,EAAK7zB,UAAU2mB,OAAOzqB,GAAcI,OAEpCkpB,EAASvC,IAAImM,wBACbwF,EAASvU,cAAc5d,QACvBmyB,EAAS3wB,MAAMtK,KAAKs6B,sBAEpBt6B,KAAK8O,SAEL9O,KAAKq6B,MAAM94B,GAAOsC,OAAO,GAE7B,EAh9BuBi1B,GAAOwD,QAAG,eC3EnC,MAAMC,GA8BJ78B,cACEM,KAAKwrB,OAAS/c,IACdzO,KAAK8M,SAAWzD,IAChBrJ,KAAKiO,SAAWjE,EAAgB,EAAG,EAAG,GACtChK,KAAK2X,MAAQ3N,EAAgB,EAAG,EAAG,EACrC,CAOOkF,gWACLT,CAAkCzO,KAAKwrB,OAAQxrB,KAAK8M,SAAU9M,KAAKiO,SAAUjO,KAAK2X,MACpF,ECzBF,MAAM6kB,GAkCJ98B,aAAmBsG,UACjBA,EAAY,CAAA,GACsB,IAc5BhG,KAAay8B,cAAG,EAAGV,OAAQtT,MACjCA,EAAOmD,OAAOnG,YAAYzlB,KAAK08B,YAE3BjU,EAAO6Q,YACT7Q,EAAO9D,KAAKpjB,GAAO4B,KAAMnD,KAAK28B,iBAE9BlU,EAAO9D,KAAKpjB,GAAO0B,MAAOjD,KAAK28B,gBAChC,EAGK38B,KAAe28B,gBAAG,EAAGZ,OAAQtT,MACnC,MAAM0D,EAAYnsB,KAAK08B,WAClBvQ,GAEDA,EAAUyQ,gBAAkBnU,EAAOmD,QACrCnD,EAAOmD,OAAOiR,YAAY1Q,EAC3B,EA7BDnsB,KAAKgG,UAAYA,EACjBhG,KAAK08B,WAAa18B,KAAK88B,iBACzB,CAEO3N,KAAK1G,GACVA,EAAO3P,GAAGvX,GAAO2B,WAAYlD,KAAKy8B,cACpC,CAEO7tB,QAAQ6Z,GACbA,EAAO5Z,IAAItN,GAAO2B,WAAYlD,KAAKy8B,eACnCz8B,KAAK28B,gBAAgB,CAAEZ,OAAQtT,GACjC,CAqBQqU,kBACN,MAAM92B,EACDlG,OAAA0V,OAAA1V,OAAA0V,OAAA,GAAAxV,KAAKgG,WACLw2B,GAAej6B,eAGd4pB,EAAYpmB,GAAcC,EAAUxD,WACpCu6B,EAAOh3B,GAAcC,EAAUg3B,MAIrC,OAFA7Q,EAAU1G,YAAYsX,GAEf5Q,CACT,EA3EuBqQ,GAAAj6B,cAAgB,CAMrCC,UAAW,kBAMXw6B,KAAM,wBChBV,MAAeC,GA2Bbv9B,YAAmBgpB,GACjB1oB,KAAKiO,SAAWya,EAAQza,SACxBjO,KAAKoI,MAAQsgB,EAAQtgB,KACvB,EC/DK,MAAM80B,GAA4B,CACvCC,cAAe,mBACfC,YAAa,8BACbC,cAAe,wBACfC,aAAc,uBACdC,gBAAiB,0BACjBC,aAAc,uBACdC,cAAe,wBACfC,eAAgB,yBAChBC,oBAAqB,8BACrBC,qBAAsB,+BACtBC,gBAAiB,0BACjBC,cAAe,4BACfC,YAAa,0BACbC,WAAY,gBACZC,YAAa,sBACbC,YAAa,sBACbC,aAAc,uBACdC,YAAa,wBACbC,aAAc,yBACdC,eAAgB,2BAChBC,aAAc,yBACdC,kBAAmB,8BACnBC,uBAAwB,mCACxBC,UAAW,sBACXC,aAAc,gCACdC,cAAe,iCACfC,mBAAoB,wBACpBC,aAAc,uBACdC,MAAO,yBACPC,YAAa,+BACbC,OAAQ,2BAGGC,GAA4B,CAMvCC,SAAU,WAMVC,UAAW,YAMXC,SAAU,WAMVC,YAAa,cAMbC,UAAW,YAMXC,WAAY,cCvDd,MAAMC,WAAqBvyB,EAmBzBxN,cACEG,QAsFMG,KAAO0/B,QAAG,EAAG3sB,WAAUC,oBAC7B,MAAMoU,EAAOpnB,KAAK2/B,MAClB,IAAKvY,EAAM,OAEX,MAAMpjB,EAAIgP,EACLD,EAAwBe,QAAQ,GAAG8F,MACnC7G,EAAwB6G,MACvBgmB,EAAMxY,EAAKpjB,GAAuB,QAAlB4B,EAAAkD,OAAO+2B,eAAW,IAAAj6B,EAAAA,EAAAkD,OAAOg3B,aAEzCC,EAAWh5B,GAAM/C,EAAG47B,EAAKA,EAAMxY,EAAKrY,OACpCrE,GAAYq1B,EAAWH,GAAOxY,EAAKrY,MAEzC/O,KAAKiM,QAAQX,MAAMy0B,GACnB//B,KAAKggC,QAAQ35B,UAAUC,IAAItG,KAAKigC,aAEhCjgC,KAAK4P,QAAQjL,GAA4B+F,EAAS,EAG5C1K,KAAAsX,UAAY,EAAGzL,kBACrB,MAAMgB,EAAS7M,KAAKiM,QACdmb,EAAOpnB,KAAK2/B,MAClB,IAAKvY,EAAM,OAEXva,EAAOf,iBAAiBD,EAAM7H,GAC9B6I,EAAOtB,OAAO,GAEd,MAAMq0B,EAAMxY,EAAKpjB,GAAuB,QAAlB4B,EAAAkD,OAAO+2B,eAAW,IAAAj6B,EAAAA,EAAAkD,OAAOg3B,aAEzCp1B,GADW3D,GAAM8F,EAAO/L,IAAK8+B,EAAKA,EAAMxY,EAAKrY,OACtB6wB,GAAOxY,EAAKrY,MAEzC/O,KAAK4P,QAAQjL,GAAuB+F,EAAS,EAGvC1K,KAAUkgC,WAAG,KACNlgC,KAAK2/B,QAGlB3/B,KAAKggC,QAAQ35B,UAAU2mB,OAAOhtB,KAAKigC,aAEnCjgC,KAAK4P,QAAQjL,IAAyB,EA3HtC,MAAMu1B,EAAO9zB,SAASL,cAAcvE,IAC9B2+B,EAAQ/5B,SAASL,cAAcvE,IAC/B4+B,EAAQh6B,SAASL,cAAcvE,IAC/B6+B,EAASj6B,SAASL,cAAcvE,IAEtC04B,EAAKoG,WAAY,EAEjBH,EAAM1a,YAAY4a,GAClBF,EAAM1a,YAAY2a,GAClBlG,EAAKzU,YAAY0a,GAEjBngC,KAAK4rB,OAASsO,EACdl6B,KAAKugC,QAAUJ,EACfngC,KAAKggC,QAAUI,EACfpgC,KAAKwgC,SAAWH,EAEhBrgC,KAAKgY,YAAc,IAAI9F,GACvBlS,KAAKuW,YAAc,IAAI7C,GACvB1T,KAAKiM,QAAU,IAAI7B,GAAO,CAAEU,SAAU,EAAGI,MAAOlG,GAAgBoG,OAAQpH,GAAKA,IAC7EhE,KAAK2/B,MAAQ,CACX37B,EAAG,EACHyF,EAAG,EACHsF,MAAO,EACPC,OAAQ,EACRyxB,KAAM,EACNC,MAAO,EACPC,OAAQ,EACRC,IAAK,GAEP5gC,KAAKigC,YAAc/C,GAA0B6B,KAC/C,CAEO5P,KAAKnpB,GACV,MAAM4S,EAAa5Y,KAAKgY,YAClBa,EAAa7Y,KAAKuW,YAExBvW,KAAK4rB,OAAOvlB,UAAUC,IAAIN,EAAUg4B,YACpCh+B,KAAKugC,QAAQl6B,UAAUC,IAAIN,EAAUi4B,aACrCj+B,KAAKggC,QAAQ35B,UAAUC,IAAIN,EAAUk4B,aACrCl+B,KAAKwgC,SAASn6B,UAAUC,IAAIN,EAAUm4B,cACtCn+B,KAAKigC,YAAcj6B,EAAU+4B,MAE7BnmB,EAAWE,GAAGnU,GAA4B3E,KAAK0/B,SAC/C7mB,EAAWC,GAAGnU,GAA4B3E,KAAK0/B,SAE/C9mB,EAAWE,GAAGnU,GAA0B3E,KAAKkgC,YAC7CrnB,EAAWC,GAAGnU,GAA0B3E,KAAKkgC,YAE7CtnB,EAAWE,GAAGnU,GAAuB3E,KAAKsX,WAC1CuB,EAAWC,GAAGnU,GAAuB3E,KAAKsX,WAE1CsB,EAAWrF,OAAOvT,KAAK4rB,QACvB/S,EAAWtF,OAAOvT,KAAK4rB,QAEvB5rB,KAAK8O,QACP,CAEOF,UACL,MAAMgK,EAAa5Y,KAAKgY,YAClBa,EAAa7Y,KAAKuW,YAExBvW,KAAK4rB,OAAO5lB,UAAY,GACxBhG,KAAKugC,QAAQv6B,UAAY,GACzBhG,KAAKggC,QAAQh6B,UAAY,GACzBhG,KAAKwgC,SAASx6B,UAAY,GAE1B4S,EAAW/J,MACXgK,EAAWhK,MACX+J,EAAWnF,UACXoF,EAAWpF,SACb,CAEO3E,SACL9O,KAAK2/B,MAAQ3/B,KAAKugC,QAAQlZ,uBAC5B,CAEOwZ,YAAYn2B,GACjB,MAAMqE,EAAQ/O,KAAK2/B,MAAM5wB,MACnB+xB,EAAkB/5B,GAAM2D,EAAU,EAAG,GAE3C1K,KAAKwgC,SAAStf,MAAMnS,MAA6B,IAAlB+xB,EAAH,IAC5B9gC,KAAKggC,QAAQ9e,MAAMoK,UAAY,cAAcwV,EAAkB/xB,MACjE,EClGF,MAAMgyB,WAAoB9D,GACbzpB,cAAY,OAAOxT,KAAKghC,cAAcpV,MAAQ,CAgBzDlsB,aAAmBuO,SACjBA,EAAWixB,GAA0BG,SAAQj3B,MAC7CA,EAAQ,MAC0B,IAClCvI,MAAM,CACJoO,WACA7F,UA8DIpI,KAASinB,UAAG,KAClBjnB,KAAKghC,cAAclyB,QAAQ,EAGrB9O,KAAaihC,cAAG,KACtB,MAAMlf,EAAQ/hB,KAAKkhC,OACdnf,IAEL/hB,KAAKmhC,aAAepf,EAAMF,OAAOsC,YACjCnkB,KAAKghC,cAAcH,YAAY7gC,KAAKmhC,aAAenhC,KAAK+K,WAAU,EAG5D/K,KAAiBohC,kBAAG,KAC1B,MAAMrf,EAAQ/hB,KAAKkhC,OACdnf,IAEL/hB,KAAK+K,UAAYgX,EAAMF,OAAO/W,SAC9B9K,KAAKghC,cAAcH,YAAY7gC,KAAKmhC,aAAenhC,KAAK+K,WAAU,EAG5D/K,KAAA0/B,QAAWh1B,IACjB,MAAMqX,EAAQ/hB,KAAKkhC,OACbG,EAAarhC,KAAKshC,YACxB,IAAKvf,IAAUsf,EAAY,OAE3B,MAAMjf,EAASL,EAAMI,WAErBJ,EAAMF,OAAOG,QAEb,MAAMoE,EAAOrE,EAAMF,OAAO/W,SAAWJ,EACrCqX,EAAMF,OAAOsC,YAAciC,EAC3BrE,EAAMF,OAAO0f,cAAc,IAAIC,YAAYj8B,GAAyB,CAAEk8B,OAAQ,CAAErb,WAEhFib,EAAWzV,OAAOvlB,UAAUC,IAAI+6B,EAAWr7B,UAAU+4B,OACrD/+B,KAAK0hC,YAAc1hC,KAAK2hC,cAAgBvf,CAAM,EAGxCpiB,KAAA4hC,WAAcl3B,IACpB,MAAMqX,EAAQ/hB,KAAKkhC,OACnB,IAAKnf,EAAO,OAEZ,MAAMqE,EAAOrE,EAAMF,OAAO/W,SAAWJ,EACrCqX,EAAMF,OAAOsC,YAAciC,EAC3BrE,EAAMF,OAAO0f,cAAc,IAAIC,YAAYj8B,GAAyB,CAAEk8B,OAAQ,CAAErb,UAAS,EAGnFpmB,KAAUkgC,WAAG,KACnB,MAAMne,EAAQ/hB,KAAKkhC,OACbG,EAAarhC,KAAKshC,YAEpBvf,GAASsf,IACNrhC,KAAK0hC,YAAe1hC,KAAK2hC,eAC5B3hC,KAAK2hC,aAAe5f,EAAMF,OAAOuC,OAC9BlF,OAAM,KAAY,IAGrBlf,KAAK2hC,aAAahyB,MAAK,KACrB3P,KAAK2hC,aAAe,IAAI,IAG1BN,EAAWzV,OAAOvlB,UAAU2mB,OAAOqU,EAAWr7B,UAAU+4B,SAI5D/+B,KAAK0hC,YAAa,CAAK,EA3HvB1hC,KAAKiO,SAAWA,EAChBjO,KAAKoI,MAAQA,EAEbpI,KAAKshC,YAAc,KACnBthC,KAAKghC,cAAgB,IAAIvB,GAEzBz/B,KAAKkhC,OAAS,KACdlhC,KAAK0hC,YAAa,EAClB1hC,KAAKmhC,aAAe,EACpBnhC,KAAK+K,UAAY,EACjB/K,KAAK2hC,aAAe,IACtB,CAEOxS,KAAK1G,EAAiB4Y,SAC3B,MAAMtf,EAAyB,QAAjBnc,EAAA6iB,EAAO8P,kBAAU,IAAA3yB,OAAA,EAAAA,EAAE20B,aAC3B/mB,EAAUxT,KAAKwT,QACfquB,EAAe7hC,KAAKghC,cACpBc,EAAmBT,EAAWr7B,UAAUg5B,YAEzCjd,GAAUA,EAAML,WAKrBlO,EAAQnN,UAAU2mB,OAAO8U,GACzBtuB,EAAQnN,UAAUC,IAAI+6B,EAAWr7B,UAAU83B,eAC3CrV,EAAO3P,GAAGvX,GAAO8B,OAAQrD,KAAKinB,WAC9BlF,EAAMF,OAAOjP,iBAAiB1M,GAAkClG,KAAKihC,eACrElf,EAAMF,OAAOjP,iBAAiB1M,GAAsClG,KAAKohC,mBACzErf,EAAMF,OAAOjP,iBAAiBrN,GAAyBvF,KAAKihC,eAC5DY,EAAa1S,KAAKkS,EAAWr7B,WAC7B67B,EAAa/oB,GAAGnU,GAA4B3E,KAAK0/B,SACjDmC,EAAa/oB,GAAGnU,GAAuB3E,KAAK4hC,YAC5CC,EAAa/oB,GAAGnU,GAA0B3E,KAAKkgC,YAE/ClgC,KAAKkhC,OAASnf,EACd/hB,KAAKmhC,aAAepf,EAAMF,OAAOsC,YACjCnkB,KAAK+K,UAAYgX,EAAMF,OAAO/W,SAC9B9K,KAAKshC,YAAcD,EAEnBQ,EAAahB,YAAY7gC,KAAKmhC,aAAenhC,KAAK+K,YApBhDyI,EAAQnN,UAAUC,IAAIw7B,EAqB1B,CAEOlzB,QAAQ6Z,GACb,MAAM1G,EAAQ/hB,KAAKkhC,OAEnBzY,EAAO5Z,IAAItN,GAAO8B,OAAQrD,KAAKinB,WAE3BlF,IACFA,EAAMF,OAAOxO,oBAAoBnN,GAAkClG,KAAKihC,eACxElf,EAAMF,OAAOxO,oBAAoBnN,GAAsClG,KAAKohC,mBAC5Erf,EAAMF,OAAOxO,oBAAoB9N,GAAyBvF,KAAKihC,gBAGjEjhC,KAAKghC,cAAcpyB,UACnB5O,KAAKkhC,OAAS,KACdlhC,KAAK2hC,aAAe,IACtB,ECtFF,MAAMI,WAAmB9E,GAWvBv9B,aAAmBuO,SACjBA,EAAWixB,GAA0BK,UAASn3B,MAC9CA,EAAQ,MAC0B,IAClCvI,MAAM,CACJoO,WACA7F,UAwDIpI,KAAQgiC,SAAG,KACjB,MAAMjgB,EAAQ/hB,KAAKkhC,OACdnf,IAED/hB,KAAKiiC,QACPlgB,EAAMF,OAAOuC,OAEbrC,EAAMF,OAAOG,QACd,EAGKhiB,KAAOkiC,QAAG,KAChB,IAAKliC,KAAKshC,YAAa,OAEvB,MAAM9tB,EAAUxT,KAAKwT,QACfxN,EAAYhG,KAAKshC,YAAYt7B,UAEnCwN,EAAQnN,UAAUC,IAAIN,EAAUq4B,cAChC7qB,EAAQnN,UAAU2mB,OAAOhnB,EAAUo4B,aACnC5qB,EAAQ2uB,MAAQ,cAEhBniC,KAAKiiC,SAAU,CAAK,EAGdjiC,KAAQoiC,SAAG,KACjB,IAAKpiC,KAAKshC,YAAa,OAEvB,MAAM9tB,EAAUxT,KAAKwT,QACfxN,EAAYhG,KAAKshC,YAAYt7B,UAEnCwN,EAAQnN,UAAUC,IAAIN,EAAUo4B,aAChC5qB,EAAQnN,UAAU2mB,OAAOhnB,EAAUq4B,cACnC7qB,EAAQ2uB,MAAQ,aAEhBniC,KAAKiiC,SAAU,CAAI,EAvFnBjiC,KAAKwT,QAAUpN,SAASL,cAAcG,IAEtClG,KAAKkhC,OAAS,KACdlhC,KAAKiiC,SAAU,EACfjiC,KAAKshC,YAAc,IACrB,CAEOnS,KAAK1G,EAAiB4Y,SAC3B,MAAM7tB,EAAUxT,KAAKwT,QACfuO,EAAyB,QAAjBnc,EAAA6iB,EAAO8P,kBAAU,IAAA3yB,OAAA,EAAAA,EAAE20B,aAC3Bv0B,EAAYq7B,EAAWr7B,UACvB87B,EAAmB97B,EAAUg5B,YAEnC,IAAKjd,IAAUA,EAAML,UAEnB,YADAlO,EAAQnN,UAAUC,IAAIw7B,GAIxBtuB,EAAQnN,UAAUC,IAAIN,EAAU63B,iBAChCrqB,EAAQnN,UAAU2mB,OAAO8U,GAEzB,MAAM1f,EAASL,EAAMI,WACrBniB,KAAKkhC,OAASnf,EACd/hB,KAAKiiC,QAAU7f,EACfpiB,KAAKshC,YAAcD,EAEfjf,EACFpiB,KAAKoiC,WAELpiC,KAAKkiC,UAGP1uB,EAAQZ,iBAAiB1M,EAAsBlG,KAAKgiC,UACpDjgB,EAAMF,OAAOjP,iBAAiB1M,GAA2BlG,KAAKkiC,SAC9DngB,EAAMF,OAAOjP,iBAAiB1M,GAA4BlG,KAAKoiC,SACjE,CAEOxzB,UACL,MAAMmT,EAAQ/hB,KAAKkhC,OACb1tB,EAAUxT,KAAKwT,QAEhBuO,IAELvO,EAAQxN,UAAY,GACpBwN,EAAQH,oBAAoBnN,EAAsBlG,KAAKgiC,UACvDjgB,EAAMF,OAAOxO,oBAAoBnN,GAA2BlG,KAAKkiC,SACjEngB,EAAMF,OAAOxO,oBAAoBnN,GAA4BlG,KAAKoiC,UAElEpiC,KAAKkhC,OAAS,KACdlhC,KAAKiiC,SAAU,EACfjiC,KAAKshC,YAAc,KACrB,ECpEF,MAAMe,WAAsBpF,GACfzpB,cAAY,OAAOxT,KAAK+4B,OAAS,CAa5Cr5B,aAAmBuO,SACjBA,EAAWixB,GAA0BM,WAAUp3B,MAC/CA,EAAQ,MAC0B,IAClCvI,MAAM,CACJoO,WACA7F,UA4EIpI,KAASinB,UAAG,KAClBjnB,KAAKghC,cAAclyB,SACnB9O,KAAKsiC,gBAAgB,EAGftiC,KAAQgiC,SAAG,KACjB,MAAMjgB,EAAQ/hB,KAAKkhC,OACdnf,IAAS/hB,KAAK+4B,QAAQwJ,WAE3BxgB,EAAMF,OAAOmC,OAASjC,EAAMF,OAAOmC,MAAK,EAGlChkB,KAAewiC,gBAAG,KACxB,MAAMlwB,EAAStS,KAAKyiC,UACd1gB,EAAQ/hB,KAAKkhC,OACbG,EAAarhC,KAAKshC,YAExB,IAAKvf,IAAUsf,EAAY,OAE3B,MAAMr7B,EAAYq7B,EAAWr7B,UAEzB+b,EAAMF,OAAOmC,OAAiC,IAAxBjC,EAAMF,OAAOoC,QACrC3R,EAAOjM,UAAUC,IAAIN,EAAUu4B,cAC/BjsB,EAAOjM,UAAU2mB,OAAOhnB,EAAUs4B,kBAElChsB,EAAOjM,UAAUC,IAAIN,EAAUs4B,gBAC/BhsB,EAAOjM,UAAU2mB,OAAOhnB,EAAUu4B,eAGpCv+B,KAAKsiC,gBAAgB,EAeftiC,KAAA0/B,QAAWh1B,IACjB,MAAMqX,EAAQ/hB,KAAKkhC,OACbG,EAAarhC,KAAKshC,YAExB,IAAKvf,IAAUsf,EAAY,OAE3B,MAAMr7B,EAAYq7B,EAAWr7B,UAE7B+b,EAAMF,OAAOoC,OAASvZ,EAEtB1K,KAAK+4B,QAAQ1yB,UAAUC,IAAIN,EAAU+4B,OACrCsC,EAAWqB,YAAYr8B,UAAUC,IAAIN,EAAU+4B,OAE/C/+B,KAAKsiC,gBAAgB,EAGftiC,KAAAsX,UAAa5M,IACnB,MAAMqX,EAAQ/hB,KAAKkhC,OACdnf,IAELA,EAAMF,OAAOoC,OAASvZ,EAEpBqX,EAAMF,OAAOmC,QADXtZ,EAAW,GAMf1K,KAAKsiC,iBAAgB,EAGftiC,KAAUkgC,WAAG,KACnB,MAAMmB,EAAarhC,KAAKshC,YACxB,IAAKD,EAAY,OAEjB,MAAMr7B,EAAYq7B,EAAWr7B,UAE7BhG,KAAK+4B,QAAQ1yB,UAAU2mB,OAAOhnB,EAAU+4B,OACxCsC,EAAWqB,YAAYr8B,UAAU2mB,OAAOhnB,EAAU+4B,MAAM,EAGlD/+B,KAAcsiC,eAAG,KACvB,MAAMvgB,EAAQ/hB,KAAKkhC,OACbhH,EAAOl6B,KAAK+4B,QAClB,IAAKhX,EAAO,OAEZ,IAAKA,EAAMQ,WAET,YADA2X,EAAKqI,UAAW,GAIlBrI,EAAKqI,UAAW,EAEhB,MAAMte,EAASlC,EAAMF,OAAOmC,MAAQ,EAAIjC,EAAMF,OAAOoC,OAErDjkB,KAAKghC,cAAcH,YAAY5c,EAAO,EA3KtCjkB,KAAKshC,YAAc,KACnBthC,KAAKghC,cAAgB,IAAIvB,GACzBz/B,KAAK88B,kBAEL98B,KAAKkhC,OAAS,IAChB,CAEO/R,KAAK1G,EAAiB4Y,SAC3B,MAAMtf,EAAyB,QAAjBnc,EAAA6iB,EAAO8P,kBAAU,IAAA3yB,OAAA,EAAAA,EAAE20B,aAC3BL,EAAOl6B,KAAK+4B,QACZzmB,EAAStS,KAAKyiC,UACdZ,EAAe7hC,KAAKghC,cACpBh7B,EAAYq7B,EAAWr7B,UACvB87B,EAAmB97B,EAAUg5B,YAE9Bjd,GAAUA,EAAML,WAKrBwY,EAAK7zB,UAAU2mB,OAAO8U,GACtB5H,EAAK7zB,UAAUC,IAAIN,EAAU63B,iBAC7B3D,EAAK7zB,UAAUC,IAAIN,EAAU+3B,aAC7BzrB,EAAOjM,UAAUC,IAAIN,EAAU63B,iBAE3B9b,EAAMF,OAAOmC,MACf1R,EAAOjM,UAAUC,IAAIN,EAAUu4B,cAE/BjsB,EAAOjM,UAAUC,IAAIN,EAAUs4B,gBAGjC7V,EAAO3P,GAAGvX,GAAO8B,OAAQrD,KAAKinB,WAC9BiT,EAAKtnB,iBAAiB1M,GAA+BlG,KAAKinB,WAC1D3U,EAAOM,iBAAiB1M,EAAsBlG,KAAKgiC,UAEnDjgB,EAAMF,OAAOjP,iBAAiB1M,GAAoClG,KAAKwiC,iBACvEzgB,EAAMF,OAAOjP,iBAAiB1M,GAAkClG,KAAKsiC,gBACrEvgB,EAAMF,OAAOjP,iBAAiB1M,GAAsClG,KAAKsiC,gBAEzET,EAAa1S,KAAKnpB,GAClB67B,EAAa/oB,GAAGnU,GAA4B3E,KAAK0/B,SACjDmC,EAAa/oB,GAAGnU,GAAuB3E,KAAKsX,WAC5CuqB,EAAa/oB,GAAGnU,GAA0B3E,KAAKkgC,YAE/ClgC,KAAKshC,YAAcD,EACnBrhC,KAAKkhC,OAASnf,EAEd/hB,KAAKsiC,kBA/BHpI,EAAK7zB,UAAUC,IAAIw7B,EAgCvB,CAEOlzB,QAAQ6Z,GACb,MAAM1G,EAAQ/hB,KAAKkhC,OACb5uB,EAAStS,KAAKyiC,UACdvI,EAAOl6B,KAAK+4B,QAElBmB,EAAKl0B,UAAY,GACjBsM,EAAOtM,UAAY,GAEnByiB,EAAO5Z,IAAItN,GAAO8B,OAAQrD,KAAKinB,WAC/BiT,EAAK7mB,oBAAoBnN,GAA+BlG,KAAKinB,WAC7D3U,EAAOe,oBAAoBnN,EAAsBlG,KAAKgiC,UAElDjgB,IACFA,EAAMF,OAAOxO,oBAAoBnN,GAAoClG,KAAKwiC,iBAC1EzgB,EAAMF,OAAOxO,oBAAoBnN,GAAkClG,KAAKsiC,gBACxEvgB,EAAMF,OAAOxO,oBAAoBnN,GAAsClG,KAAKsiC,iBAG9EtiC,KAAKshC,YAAc,KACnBthC,KAAKghC,cAAcpyB,UACnB5O,KAAKkhC,OAAS,IAChB,CAkCQpE,kBACN,MAAM5C,EAAO9zB,SAASL,cAAcG,IAC9By8B,EAAWv8B,SAASL,cAAcG,IAExCg0B,EAAKzU,YAAYzlB,KAAKghC,cAAcpV,QACpCsO,EAAKzU,YAAYkd,GACjBzI,EAAKiI,MAAQ,cAEbniC,KAAK+4B,QAAUmB,EACfl6B,KAAKyiC,UAAYE,CACnB,EC7IF,MAAMC,WAAyB3F,GAU7Bv9B,aAAmBuO,SACjBA,EAAWixB,GAA0BM,WAAUp3B,MAC/CA,EAAQ,MAC0B,IAClCvI,MAAM,CACJoO,WACA7F,UA4CIpI,KAAQgiC,SAAG,KACjB,MAAMjG,EAAS/7B,KAAK6iC,UACf9G,IAEDrzB,KACF1I,KAAK8iC,kBAEL9iC,KAAK+iC,mBAAmBhH,GACzB,EAwCK/7B,KAAmBgjC,oBAAG,KAC5B,MAAMxvB,EAAUxT,KAAKwT,QACf6tB,EAAarhC,KAAKshC,YAExB,IAAKD,EAAY,OAEjB,MAAMr7B,EAAYq7B,EAAWr7B,UAEzB0C,MACF8K,EAAQnN,UAAUC,IAAIN,EAAUy4B,wBAChCjrB,EAAQnN,UAAU2mB,OAAOhnB,EAAUw4B,qBAEnChrB,EAAQnN,UAAUC,IAAIN,EAAUw4B,mBAChChrB,EAAQnN,UAAU2mB,OAAOhnB,EAAUy4B,wBACpC,EAvGDz+B,KAAKwT,QAAUpN,SAASL,cAAcG,IACtClG,KAAKwT,QAAQ2uB,MAAQ,oBACrBniC,KAAKshC,YAAc,KACnBthC,KAAK6iC,UAAY,IACnB,CAEO1T,KAAK1G,EAAiB4Y,GAC3B,MAAM7tB,EAAUxT,KAAKwT,QACfxN,EAAYq7B,EAAWr7B,UAExBhG,KAAKijC,wBAKVzvB,EAAQnN,UAAUC,IAAIN,EAAU63B,iBAChCrqB,EAAQnN,UAAU2mB,OAAOhnB,EAAUg5B,aACnCxrB,EAAQZ,iBAAiB1M,EAAsBlG,KAAKgiC,UACpDhiC,KAAKkjC,yBAEDx6B,KACF8K,EAAQnN,UAAUC,IAAIN,EAAUy4B,wBAEhCjrB,EAAQnN,UAAUC,IAAIN,EAAUw4B,mBAGlCx+B,KAAKshC,YAAcD,EACnBrhC,KAAK6iC,UAAYpa,EAAOmD,QAhBtBpY,EAAQnN,UAAUC,IAAIN,EAAUg5B,YAiBpC,CAEOpwB,UACL,MAAM4E,EAAUxT,KAAKwT,QAErBA,EAAQxN,UAAY,GACpBwN,EAAQH,oBAAoBnN,EAAsBlG,KAAKgiC,UACvDhiC,KAAKmjC,4BAELnjC,KAAKshC,YAAc,KACnBthC,KAAK6iC,UAAY,IACnB,CAaQI,uBACN,OAAO/8B,GAA2Bk9B,MAAKz6B,KAASvC,SAASuC,IAC3D,CAEQo6B,mBAAmB58B,GACzB,IAAK,MAAMwC,KAAOzC,GAA4B,CAC5C,MAAMm9B,EAAUl9B,EAAGwC,GACnB,GAAI06B,EAEF,YADAA,EAAQC,KAAKn9B,EAGhB,CACH,CAEQ28B,kBACN,IAAK,MAAMn6B,KAAOzC,GAAyB,CACzC,MAAMqjB,EAAOnjB,SAASuC,GAEtB,GAAI4gB,EAEF,YADAA,EAAK+Z,KAAKl9B,SAGb,CACH,CAEQ88B,yBACNh9B,GAA0Bkf,SAAQiX,IAChCj2B,SAASwM,iBAAiBypB,EAASr8B,KAAKgjC,oBAAoB,GAEhE,CAEQG,4BACNj9B,GAA0Bkf,SAAQiX,IAChCj2B,SAASiN,oBAAoBgpB,EAASr8B,KAAKgjC,oBAAoB,GAEnE,ECzGF,MAAMO,WAAkBtG,GAWtBv9B,aAAmBuO,SACjBA,EAAWixB,GAA0BK,UAASn3B,MAC9CA,EAAQ,MAC0B,IAClCvI,MAAM,CACJoO,WACA7F,UA+CIpI,KAAaihC,cAAG,KACtB,MAAMlf,EAAQ/hB,KAAKkhC,OACdnf,IAEL/hB,KAAKmhC,aAAepf,EAAMF,OAAOsC,YACjCnkB,KAAKsiC,iBAAgB,EAGftiC,KAAiBohC,kBAAG,KAC1B,MAAMrf,EAAQ/hB,KAAKkhC,OACdnf,IAEL/hB,KAAK+K,UAAYgX,EAAMF,OAAO/W,SAC9B9K,KAAKsiC,iBAAgB,EAGftiC,KAAAwjC,oBAAuBpxB,IAC7BpS,KAAKmhC,aAAe/uB,EAAIqvB,OAAOrb,KAC/BpmB,KAAKsiC,gBAAgB,EA9DrBtiC,KAAKwT,QAAUpN,SAASL,cAAcG,IAEtClG,KAAKkhC,OAAS,KACdlhC,KAAKmhC,aAAe,EACpBnhC,KAAK+K,UAAY,CACnB,CAEOokB,KAAK1G,EAAiB4Y,SAC3B,MAAMtf,EAAyB,QAAjBnc,EAAA6iB,EAAO8P,kBAAU,IAAA3yB,OAAA,EAAAA,EAAE20B,aAC3B/mB,EAAUxT,KAAKwT,QACfxN,EAAYq7B,EAAWr7B,UAExB+b,GAAUA,EAAML,WAKrBlO,EAAQnN,UAAUC,IAAIN,EAAU64B,oBAChCrrB,EAAQnN,UAAU2mB,OAAOhnB,EAAUg5B,aAEnCjd,EAAMF,OAAOjP,iBAAiB1M,GAAkClG,KAAKihC,eACrElf,EAAMF,OAAOjP,iBAAiB1M,GAAsClG,KAAKohC,mBACzErf,EAAMF,OAAOjP,iBAAiBrN,GAAyBvF,KAAKwjC,qBAE5DxjC,KAAKkhC,OAASnf,EACd/hB,KAAKmhC,aAAepf,EAAMF,OAAOsC,YACjCnkB,KAAK+K,UAAYgX,EAAMF,OAAO/W,SAE9B9K,KAAKsiC,kBAfH9uB,EAAQnN,UAAUC,IAAIN,EAAUg5B,YAgBpC,CAEOpwB,UACL,MAAMmT,EAAQ/hB,KAAKkhC,OAEdnf,IAEL/hB,KAAKwT,QAAQxN,UAAY,GACzB+b,EAAMF,OAAOxO,oBAAoBnN,GAAkClG,KAAKihC,eACxElf,EAAMF,OAAOxO,oBAAoBnN,GAAsClG,KAAKohC,mBAC5Erf,EAAMF,OAAOxO,oBAAoB9N,GAAyBvF,KAAKwjC,qBAE/DxjC,KAAKkhC,OAAS,KAChB,CAuBQoB,iBACN,MAAMlc,EAAOpmB,KAAKmhC,aACZsC,EAAav/B,KAAKw/B,MAAMtd,EAAO,IAC/Bud,EAAcz/B,KAAKw/B,MAAMtd,EAAoB,GAAbqd,GAChCG,EAAuBD,EAAc,GAAK,IAAIA,IAAgBA,EAE9D74B,EAAW9K,KAAK+K,UAChB84B,EAAiB3/B,KAAKw/B,MAAM54B,EAAW,IACvCg5B,EAAkB5/B,KAAKw/B,MAAM54B,EAA4B,GAAjB+4B,GACxCE,EAA2BD,EAAkB,GAAK,IAAIA,IAAoBA,EAEhF9jC,KAAKwT,QAAQwwB,UAAe,GAAAP,KAAcG,OAA0BC,KAAkBE,GACxF,EC9EF,MAAME,WAAgBhH,GAqBpBv9B,aAAmBwkC,YACjBA,GAAc,EAAIj2B,SAClBA,EAAWixB,GAA0BE,UAASh3B,MAC9CA,EAAQ,MACmB,IAC3BvI,MAAM,CACJoO,WACA7F,UA0CIpI,KAAQgiC,SAAG,KACjB,MAAMvZ,EAASzoB,KAAKmkC,QACdD,EAAclkC,KAAKkkC,YAEzB,IAAKzb,IAAWyb,EAAa,OAE7B,MAAMh7B,IACJA,EAAMuf,EAAO7a,WAAUzE,MACvBA,EAAQsf,EAAO5a,aAAYd,KAC3BA,EAAO0b,EAAO3a,YAAWhD,SACzBA,EAAW,KACTlD,GAAgBs8B,GAEpBzb,EAAOvc,OAAOuD,UAAU,CACtBvG,MACAC,QACA4D,OACAjC,YACA,EAoCI9K,KAAUokC,WAAG,EAAGrI,OAAQtT,MAC9B,MAAM4b,EAAUrkC,KAAKskC,WACfC,EAAcvkC,KAAKwkC,eACnBt4B,EAASuc,EAAOvc,OAChB6B,EAAM7B,EAAOoE,mBACbhD,EAAWpB,EAAOgE,YAAYhE,EAAOa,MACrC03B,EAAgB,GAAN12B,EAEV22B,EAAY,GAAKxgC,KAAKE,GACtBugC,EAASD,EAAY32B,EAAM,IAC3B62B,EAAYF,GAAax4B,EAAOhD,IAAMu7B,EAAU,IAAM,IAK5D,GAHAJ,EAAQlf,aAAa,mBAAoB,GAAGwf,KAAUD,EAAYC,KAClEN,EAAQlf,aAAa,oBAAwB,GAAAyf,KAEzCC,SAASv3B,EAASrI,MAAQ4/B,SAASv3B,EAASnI,KAAM,CACpD,MAAM2/B,EAAS,GAAK5gC,KAAKE,GACnBa,GAAOmC,GAAUkG,EAASrI,KAAM,IAAK,KAAOw/B,GAAW,IACvDt/B,GAAOiC,GAAUkG,EAASnI,KAAM,IAAK,KAAOs/B,GAAW,IAEvDM,EAAYD,EAAS5gC,KAAKoD,IAAInC,EAAMF,GACpC+/B,GAAUF,GAAU7/B,EAAM,KAEhCs/B,EAAYpf,aAAa,mBAAoB,GAAG4f,KAAaD,EAASC,KACtER,EAAYpf,aAAa,oBAAwB,GAAA6f,IAClD,MACCT,EAAYpf,aAAa,mBAAoB,IAC7Cof,EAAYpf,aAAa,oBAAqB,GAC/C,EAzHDnlB,KAAKwT,QAAUpN,SAASL,cAAcG,IACtClG,KAAKwT,QAAQ2uB,MAAQ,aACrBniC,KAAKkkC,YAAcA,EACnBlkC,KAAKilC,qBACLjlC,KAAKmkC,QAAU,IACjB,CAEOhV,KAAK1G,EAAiB4Y,GAC3B,MAAM7tB,EAAUxT,KAAKwT,QAEhBiV,EAAO6Q,YAGVt5B,KAAKokC,WAAW,CAAErI,OAAQtT,IAF1BA,EAAO9D,KAAKpjB,GAAO0B,MAAOjD,KAAKokC,YAKjC,MAAMc,EAAY7D,EAAWr7B,UAAU84B,aACvCtrB,EAAQnN,UAAUC,IAAI4+B,GAElBllC,KAAKkkC,aACP1wB,EAAQZ,iBAAiB1M,EAAsBlG,KAAKgiC,UAGtDvZ,EAAO3P,GAAGvX,GAAOmC,YAAa1D,KAAKokC,YAEnCpkC,KAAKmkC,QAAU1b,CACjB,CAEO7Z,QAAQ6Z,GACb,MAAMjV,EAAUxT,KAAKwT,QAErBA,EAAQH,oBAAoBnN,EAAsBlG,KAAKgiC,UACvDxuB,EAAQxN,UAAY,GACpByiB,EAAO5Z,IAAItN,GAAO0B,MAAOjD,KAAKokC,YAC9B3b,EAAO5Z,IAAItN,GAAOmC,YAAa1D,KAAKokC,YAEpCpkC,KAAKmkC,QAAU,IACjB,CAuBQc,qBACN,MAAM/K,EAAOl6B,KAAKwT,QACZ2xB,EAAS/+B,SAASg/B,gBAAgB5/B,GAAe,OACvD2/B,EAAOhgB,aAAa,UAAW,aAC/BggB,EAAOhgB,aAAa,QAAS,QAC7BggB,EAAOhgB,aAAa,SAAU,QAE9B,MAAMkf,EAAUj+B,SAASg/B,gBAAgB5/B,GAAe,UAExD6+B,EAAQlf,aAAa,SAAU,gBAC/Bkf,EAAQlf,aAAa,OAAQ,eAC7Bkf,EAAQlf,aAAa,KAAM,MAC3Bkf,EAAQlf,aAAa,KAAM,MAC3Bkf,EAAQlf,aAAa,IAAK,MAC1Bkf,EAAQlf,aAAa,eAAgB,MACrCggB,EAAO1f,YAAY4e,GAEnB,MAAME,EAAcn+B,SAASg/B,gBAAgB5/B,GAAe,UAE5D++B,EAAYpf,aAAa,SAAU,gBACnCof,EAAYpf,aAAa,OAAQ,eACjCof,EAAYpf,aAAa,KAAM,MAC/Bof,EAAYpf,aAAa,KAAM,MAC/Bof,EAAYpf,aAAa,IAAK,QAC9Bof,EAAYpf,aAAa,eAAgB,KACzCggB,EAAO1f,YAAY8e,GAEnBrK,EAAKzU,YAAY0f,GAEjBnlC,KAAKskC,WAAaD,EAClBrkC,KAAKwkC,eAAiBD,CACxB,EC/IF,MAAMc,WAAiBpI,GAUrBv9B,aAAmBuO,SACjBA,EAAWixB,GAA0BM,WAAUp3B,MAC/CA,EAAQ,MAC0B,IAClCvI,MAAM,CACJoO,WACA7F,UAoCIpI,KAAQgiC,SAAG,KACjB,MAAMvZ,EAASzoB,KAAKmkC,QACf1b,GAELA,EAAOkQ,GAAG3O,OAAO,EArCjBhqB,KAAKwT,QAAUpN,SAASL,cAAcG,IACtClG,KAAKwT,QAAQ2uB,MAAQ,WACrBniC,KAAKmkC,QAAU,IACjB,CAEOhV,KAAK1G,EAAiB4Y,GAC3B,MAAM7tB,EAAUxT,KAAKwT,QACfxN,EAAYq7B,EAAWr7B,UAE7BwN,EAAQnN,UAAUC,IAAIN,EAAUg5B,aAChCxrB,EAAQnN,UAAUC,IAAIN,EAAU04B,WAChClrB,EAAQnN,UAAUC,IAAIN,EAAU63B,iBAEhCpV,EAAOkQ,GAAGhY,cACPhR,MAAKoP,IACAA,GACFvL,EAAQnN,UAAU2mB,OAAOhnB,EAAUg5B,YACpC,IAGLxrB,EAAQZ,iBAAiB1M,EAAsBlG,KAAKgiC,UACpDhiC,KAAKmkC,QAAU1b,CACjB,CAEO7Z,UACL,MAAM4E,EAAUxT,KAAKwT,QAErBA,EAAQxN,UAAY,GACpBwN,EAAQH,oBAAoBnN,EAAsBlG,KAAKgiC,UAEvDhiC,KAAKmkC,QAAU,IACjB,EC/CF,MAAMmB,WAAmBrI,GAUvBv9B,aAAmBuO,SACjBA,EAAWixB,GAA0BM,WAAUp3B,MAC/CA,EAAQ,MAC0B,IAClCvI,MAAM,CACJoO,WACA7F,UA+CIpI,KAAQgiC,SAAG,KACjB,MAAMvZ,EAASzoB,KAAKmkC,QACd9C,EAAarhC,KAAKshC,YAExB,IAAK7Y,IAAW4Y,EAAY,OAE5B,MAAMvgB,EAAc2H,EAAOhQ,QAAQ2H,KAC/BU,EAAY/K,QACd+K,EAAYrN,UAEZ+K,GAAYyL,0BAA0Bta,MAAKoP,IACrCA,EACF+B,EAAYvN,SAEZvT,KAAKwT,QAAQnN,UAAUC,IAAI+6B,EAAWr7B,UAAUg5B,YACjD,GAEJ,EAGKh/B,KAAYulC,aAAG,KACrB,MAAM/xB,EAAUxT,KAAKwT,QACfiV,EAASzoB,KAAKmkC,QACd9C,EAAarhC,KAAKshC,YAExB,IAAK7Y,IAAW4Y,EAAY,OAE5B,MAAMvgB,EAAc2H,EAAOhQ,QAAQ2H,KAC7Bpa,EAAYq7B,EAAWr7B,UAEzB8a,EAAY/K,SACdvC,EAAQnN,UAAUC,IAAIN,EAAU24B,cAChCnrB,EAAQnN,UAAU2mB,OAAOhnB,EAAU44B,iBAEnCprB,EAAQnN,UAAUC,IAAIN,EAAU44B,eAChCprB,EAAQnN,UAAU2mB,OAAOhnB,EAAU24B,cACpC,EAhFD3+B,KAAKwT,QAAUpN,SAASL,cAAcG,IACtClG,KAAKwT,QAAQ2uB,MAAQ,0BACvB,CAEOhT,KAAK1G,EAAiB4Y,GAC3B,MAAM7tB,EAAUxT,KAAKwT,QACfxN,EAAYq7B,EAAWr7B,UAE7BwN,EAAQZ,iBAAiB1M,EAAsBlG,KAAKgiC,UACpDxuB,EAAQnN,UAAUC,IAAIN,EAAU63B,iBAChCrqB,EAAQnN,UAAUC,IAAIN,EAAUg5B,aAEhC,MAAMwG,EAAeA,KACnBhyB,EAAQnN,UAAU2mB,OAAOhnB,EAAUg5B,aACnCvW,EAAOhQ,QAAQ2H,KAAKtH,GAAGnU,GAAuB3E,KAAKulC,cACnD9c,EAAOhQ,QAAQ2H,KAAKtH,GAAGnU,GAAwB3E,KAAKulC,aAAa,EAG/D38B,KACF48B,IAEAhnB,GAAYmC,cAAchR,MAAKoP,IACxBA,GACLymB,GAAc,IAIlBxlC,KAAKshC,YAAcD,EACnBrhC,KAAKmkC,QAAU1b,EACfzoB,KAAKulC,cACP,CAEO32B,QAAQ6Z,GACb,MAAMjV,EAAUxT,KAAKwT,QAErBiV,EAAOhQ,QAAQ2H,KAAKvR,IAAIlK,GAAuB3E,KAAKulC,cACpD9c,EAAOhQ,QAAQ2H,KAAKvR,IAAIlK,GAAwB3E,KAAKulC,cACrD/xB,EAAQH,oBAAoBnN,EAAsBlG,KAAKgiC,UACvDxuB,EAAQxN,UAAY,GAEpBhG,KAAKshC,YAAc,KACnBthC,KAAKmkC,QAAU,IACjB,ECxCF,MAAMsB,GAaO1vB,cAAY,QAAS/V,KAAK6iC,SAAW,CACrC6C,aAAW,OAAO1lC,KAAKshC,YAAYoB,YAAYr8B,UAAUs/B,SAAS3lC,KAAK4lC,aAAe,CAErFA,mBAAiB,OAAO5lC,KAAKshC,YAAYt7B,UAAUi5B,MAAQ,CAC3DgB,kBAAgB,OAAOjgC,KAAKshC,YAAYt7B,UAAU+4B,KAAO,CAErEr/B,YAAmB2hC,GAAwBwE,aACzCA,EAAe,IAAIhe,MACnBA,EAAQ,EACRie,UAAWC,EAAkB,MA+GvB/lC,KAAa8oB,cAAG,KACtB9oB,KAAKgmC,iBAAkB,EACvBhmC,KAAKimC,MAAM,EAGLjmC,KAAagpB,cAAG,KACtBhpB,KAAKgmC,iBAAkB,EACvBhmC,KAAKkmC,iBAAiB,EAGhBlmC,KAAY6S,aAAG,KAChB7S,KAAKmmC,eAEVnmC,KAAKomC,gBAAgB,EAGfpmC,KAAA0/B,QAAWttB,IACjBpS,KAAKqmC,aAAc,EAEK,UAApBj0B,EAAIk0B,cACNtmC,KAAKgmC,iBAAkB,GAGzBl9B,OAAO8J,iBAAiB1M,EAAyBlG,KAAKkgC,YAEtDlgC,KAAKimC,MAAM,EAGLjmC,KAAUkgC,WAAG,KACnBlgC,KAAKqmC,aAAc,EAEnBv9B,OAAOuK,oBAAoBnN,EAAyBlG,KAAKkgC,YAEzDlgC,KAAKkmC,iBAAiB,EAGhBlmC,KAAYumC,aAAG,KACRvmC,KAAK6iC,WAGlB7iC,KAAKshC,YAAYoB,YAAYr8B,UAAU2mB,OAAOhtB,KAAKigC,YAAY,EAGzDjgC,KAAawmC,cAAG,KACTxmC,KAAK6iC,WAGlB7iC,KAAKshC,YAAYoB,YAAYr8B,UAAUC,IAAItG,KAAKigC,YAAY,EAetDjgC,KAAmBgjC,oBAAG,KAC5BhjC,KAAKmmC,cAAgBz9B,KAEjB1I,KAAKmmC,eACPnmC,KAAKkmC,iBACN,EAhLDlmC,KAAKshC,YAAcD,EACnBrhC,KAAKymC,cAAgBZ,EACrB7lC,KAAK8nB,OAASD,EACd7nB,KAAK0mC,WAAaX,EAClB/lC,KAAK2mC,QAAU,EACf3mC,KAAKgmC,iBAAkB,EACvBhmC,KAAKqmC,aAAc,EACnBrmC,KAAKmmC,eAAgB,EACrBnmC,KAAKkhC,OAAS,KACdlhC,KAAK6iC,UAAY,IACnB,CAEOtvB,OAAOkV,SACRzoB,KAAK6iC,WACP7iC,KAAKyT,QAAQgV,GAGf,MAAMod,EAAe7lC,KAAKymC,cACpBvM,EAAOzR,EAAOmD,OAEpB5rB,KAAK6iC,UAAYpa,EAAOmD,OACxB5rB,KAAK2mC,OAAS79B,OAAOuQ,YAAW,KAC9BrZ,KAAK4mC,MAAM,GACVf,GAEH3L,EAAKtnB,iBAAiB1M,EAA2BlG,KAAK0/B,SACtDxF,EAAKtnB,iBAAiB1M,EAA4BlG,KAAK8oB,eACvDoR,EAAKtnB,iBAAiB1M,EAA2BlG,KAAK6S,cACtDqnB,EAAKtnB,iBAAiB1M,EAA4BlG,KAAKgpB,eACvDhpB,KAAKkjC,yBAEL,MAAMnhB,EAAyB,QAAjBnc,EAAA6iB,EAAO8P,kBAAU,IAAA3yB,OAAA,EAAAA,EAAE20B,aAC5BxY,GAAUA,EAAML,YAIjBK,EAAMI,YACRniB,KAAKshC,YAAYoB,YAAYr8B,UAAUC,IAAItG,KAAKigC,aAGlDle,EAAMF,OAAOjP,iBAAiB1M,GAA2BlG,KAAKumC,cAC9DxkB,EAAMF,OAAOjP,iBAAiB1M,GAA4BlG,KAAKwmC,eAE/DxmC,KAAKkhC,OAASnf,EAChB,CAEOtO,QAAQgV,GACb,IAAKzoB,KAAK6iC,UAAW,OAErB,MAAMxB,EAAarhC,KAAKshC,YAClBpH,EAAOzR,EAAOmD,OACd7J,EAAQ/hB,KAAKkhC,OAEnBhH,EAAK7mB,oBAAoBnN,EAA2BlG,KAAK0/B,SACzD52B,OAAOuK,oBAAoBnN,EAAyBlG,KAAKkgC,YACzDhG,EAAK7mB,oBAAoBnN,EAA4BlG,KAAK8oB,eAC1DoR,EAAK7mB,oBAAoBnN,EAA2BlG,KAAK6S,cACzDqnB,EAAK7mB,oBAAoBnN,EAA4BlG,KAAKgpB,eAC1DhpB,KAAKmjC,4BAELr6B,OAAOyQ,aAAavZ,KAAK2mC,QACzBtF,EAAWqB,YAAYr8B,UAAU2mB,OAAOhtB,KAAKigC,aAEzCle,IACFA,EAAMF,OAAOxO,oBAAoBnN,GAA2BlG,KAAKumC,cACjExkB,EAAMF,OAAOxO,oBAAoBnN,GAA4BlG,KAAKwmC,gBAGpExmC,KAAKgmC,iBAAkB,EACvBhmC,KAAKqmC,aAAc,EACnBrmC,KAAKkhC,OAAS,KACdlhC,KAAK6iC,UAAY,IACnB,CAEOoD,OACLjmC,KAAK6mC,kBACL7mC,KAAKshC,YAAYoB,YAAYr8B,UAAU2mB,OAAOhtB,KAAK4lC,aACrD,CAEOQ,iBACLpmC,KAAKimC,OACLjmC,KAAKkmC,gBAAgBlmC,KAAK0mC,WAC5B,CAEOE,OACL5mC,KAAK6mC,kBACL7mC,KAAKshC,YAAYoB,YAAYr8B,UAAUC,IAAItG,KAAK4lC,aAClD,CAEQiB,kBACF7mC,KAAK2mC,SACP79B,OAAOyQ,aAAavZ,KAAK2mC,QACzB3mC,KAAK2mC,QAAU,EAEnB,CAEQT,gBAAgBre,EAAQ7nB,KAAK8nB,QAC/B9nB,KAAKqmC,cAAiBrmC,KAAKmmC,eAAiBnmC,KAAKgmC,kBAErDhmC,KAAK6mC,kBACDhf,GAAS,EACX7nB,KAAK4mC,OAEL5mC,KAAK2mC,OAAS79B,OAAOuQ,YAAW,KAC9BrZ,KAAK4mC,MAAM,GACV/e,GAEP,CAoDQqb,yBACN5gC,GAAkB8iB,SAAQiX,IACxBj2B,SAASwM,iBAAiBypB,EAASr8B,KAAKgjC,oBAAoB,GAEhE,CAEQG,4BACN7gC,GAAkB8iB,SAAQiX,IACxBj2B,SAASiN,oBAAoBgpB,EAASr8B,KAAKgjC,oBAAoB,GAEnE,ECrOF,MAAM8D,GAANpnC,cAcUM,KAAA0U,WAAce,IACpB,MAAMsM,EAAQ/hB,KAAKkhC,OACnB,IAAKnf,EAAO,OAEZtM,EAAMlD,iBACNkD,EAAMwD,kBAEN,MAAM8tB,EAAUhlB,EAAMF,OAChBmlB,EAA8B,MAAjBvxB,EAAMG,QACrB1P,GAA2BuP,EAAMG,SACjC1P,GAA2BuP,EAAM9M,KAErC,OAAQq+B,GACN,IAAK,OACL,IAAK,QACH,OAAOhnC,KAAKinC,iBAAiBF,EAAwB,UAAfC,GACxC,IAAK,KACL,IAAK,OACH,OAAOhnC,KAAKknC,mBAAmBH,EAAwB,OAAfC,I9C+BlB,K8C5BLvxB,EAAMG,S9CoCD,M8CpCuCH,EAAM9M,MAErE3I,KAAKmnC,aAAaplB,EACnB,CAiCL,CApESxO,OAAO2mB,EAAmBnY,GAC/B/hB,KAAKkhC,OAASnf,EAEdmY,EAAKtnB,iBAAiB1M,EAAyBlG,KAAK0U,YAAY,EAClE,CAEOjB,QAAQymB,GACbl6B,KAAKkhC,OAAS,KACdhH,EAAK7mB,oBAAoBnN,EAAyBlG,KAAK0U,YAAY,EACrE,CA6BQuyB,iBAAiBllB,EAAyBqlB,GAChD,MAAMv7B,EAAQu7B,EAAU,GAAK,EAE7BrlB,EAAMoC,aAAetY,EACrBkW,EAAMwf,cAAc,IAAIC,YAAYj8B,GAAyB,CAAEk8B,OAAQ,CAAErb,KAAMrE,EAAMoC,eACvF,CAEQ+iB,mBAAmBnlB,EAAyBslB,GAClD,MAAMx7B,EAAQw7B,EAAW,IAAO,GAE5BtlB,EAAMiC,MACRjC,EAAMkC,OAASld,GAAM8E,EAAO,EAAG,GAE/BkW,EAAMkC,OAASld,GAAMgb,EAAMkC,OAASpY,EAAO,EAAG,GAG5CkW,EAAMkC,OAAS,EACjBlC,EAAMiC,OAAQ,EAEdjC,EAAMiC,OAAQ,CAElB,CAEQmjB,aAAaplB,GACfA,EAAMI,WACRJ,EAAMF,OAAOuC,OAEbrC,EAAMF,OAAOG,OAEjB,ECmBF,MAAMslB,GAsHO1b,aAAW,OAAO5rB,KAAK+4B,OAAS,CAMhC2J,kBAAgB,OAAO1iC,KAAK8rB,YAAc,CAM1Cyb,mBAAiB,OAAOvnC,KAAKwnC,KAAO,CAMpCC,YAAU,OAAOznC,KAAK0nC,MAAQ,CAM9BC,kBAAgB,OAAO3nC,KAAK4nC,YAAc,CAgBrDloC,aAAmBmoC,SACjBA,EAAQC,eACRA,EAAcC,YACdA,GAAc,EAAIC,iBAClBA,GAAmB,EAAIC,YACvBA,GAAc,EAAIC,WAClBA,GAAa,EAAIC,aACjBA,GAAe,EAAIC,iBACnBA,GAAmB,EAAIC,UACvBA,GAAY,EAAIC,QAChBA,GAAU,EAAIC,SACdA,GAAW,EAAIC,WACfA,GAAa,EAAIxiC,UACjBA,EAAY,CAAE,EAAA2hC,YACdA,EAAc,IACgB,UA0JxB3nC,KAAcyoC,eAAG,EAAG1M,OAAQtT,EAAQzV,oBAC1C,MAAM01B,EAAY1oC,KAAK2oC,WAEvB,GAAI31B,EAAS,CACX,IAAK01B,EAAU3yB,QAAS,OAEpB2yB,EAAUhD,OACZgD,EAAUtC,iBAEVsC,EAAU9B,MAEb,KAAM,CACL,IAAK5mC,KAAK+nC,YAAa,OAEvB,MAAMhmB,EAAyB,QAAjBnc,EAAA6iB,EAAO8P,kBAAU,IAAA3yB,OAAA,EAAAA,EAAE20B,aACjC,IAAKxY,IAAUA,EAAML,UAAW,OAE5BK,EAAMI,WACRJ,EAAMF,OAAOuC,OAEbrC,EAAMF,OAAOG,OAEhB,GAGKhiB,KAAa4oC,cAAG,EAAG7M,OAAQtT,MACjC,MAAMgf,EAAQznC,KAAK0nC,OAEnB1nC,KAAK6oC,kBAAkBpgB,GACvBzoB,KAAK8oC,gBAAgBrgB,GACrBzoB,KAAK+oC,uBAAuBtgB,GAE5B3oB,OAAO2xB,KAAKgW,GAAOriB,SAASzc,IACT8+B,EAAM9+B,GAEdyc,SAAQ4jB,IACfA,EAAKp6B,QAAQ6Z,EAAQzoB,MACrBgpC,EAAK7Z,KAAK1G,EAAQzoB,KAAK,GACvB,GACF,EAhMFA,KAAK6nC,SAAWA,EAChB7nC,KAAK8nC,eAAiBA,EACtB9nC,KAAK+nC,YAAcA,EACnB/nC,KAAKgoC,iBAAmBA,EACxBhoC,KAAKioC,YAAcA,EACnBjoC,KAAKkoC,WAAaA,EAClBloC,KAAKmoC,aAAeA,EACpBnoC,KAAKooC,iBAAmBA,EACxBpoC,KAAKqoC,UAAYA,EACjBroC,KAAKsoC,QAAUA,EACftoC,KAAKuoC,SAAWA,EAChBvoC,KAAKwoC,WAAaA,EAClBxoC,KAAKgG,UACAlG,OAAA0V,OAAA1V,OAAA0V,OAAA,CAAA,EAAA8xB,GAAW/kC,eACXyD,GAGL,MAAMk/B,EAAuC,QAA3Bt/B,EAAAI,EAAUm3B,qBAAiB,IAAAv3B,EAAAA,EAAA0hC,GAAW/kC,cAAc46B,cAEtEn9B,KAAK+4B,QAAUhzB,GAAcm/B,GAC7BllC,KAAKipC,0BACLjpC,KAAK0nC,OAAS5nC,OAAO2xB,KAAK6V,GAAW4B,UAAU7zB,QAAO,CAACoyB,EAAO9+B,KAC5D8+B,EAAMH,GAAW4B,SAASvgC,IAAQ,GAC3B8+B,IACN,CAAE,GACLznC,KAAK4nC,aAAeD,EACpB3nC,KAAK2oC,WAAa,IAAIlD,GAASzlC,KAAM4H,GAAgBigC,IACrD7nC,KAAKmpC,cAAgB,IAAIrC,GAEzBa,EAAYviB,SAAQ4jB,IAClBhpC,KAAK0nC,OAAOsB,EAAK/6B,UAAUutB,KAAKwN,EAAK,GAEzC,CAEO7Z,KAAK1G,GACV,MAAM2gB,EAAW3gB,EAAOmD,OAClByd,EAAerpC,KAAK+4B,QACpBuQ,EAAetpC,KAAKupC,sBAE1BvpC,KAAK6oC,kBAAkBpgB,GACvBzoB,KAAK8oC,gBAAgBrgB,GACrBzoB,KAAK+oC,uBAAuBtgB,GAE5B2gB,EAAS3jB,YAAY4jB,GACrBrpC,KAAKwpC,SAAS/gB,EAAQ6gB,GACtBtpC,KAAKwpC,SAAS/gB,EAAQzoB,KAAK4nC,cAE3Bnf,EAAO3P,GAAGvX,GAAO6B,kBAAmBpD,KAAK4oC,eACzCngB,EAAO3P,GAAGvX,GAAOoC,aAAc3D,KAAKyoC,eACtC,CAEO75B,QAAQ6Z,GAEb,MAAM2gB,EAAW3gB,EAAOmD,OAClByd,EAAerpC,KAAK+4B,QACpB0O,EAAQznC,KAAK0nC,OAEf2B,EAAazM,gBAAkBwM,GACjCA,EAASvM,YAAYwM,GAGvBvpC,OAAO2xB,KAAKgW,GAAOriB,SAASzc,IACT8+B,EAAM9+B,GAEdyc,SAAQ4jB,IACfA,EAAKp6B,QAAQ6Z,EAAQzoB,KAAK,IAG5BynC,EAAM9+B,GAAO,EAAE,IAGjB3I,KAAKypC,qBACLzpC,KAAK2oC,WAAWl1B,QAAQgV,GACxBzoB,KAAKmpC,cAAc11B,QAAQ21B,GAE3B3gB,EAAO5Z,IAAItN,GAAO6B,kBAAmBpD,KAAK4oC,eAC1CngB,EAAO5Z,IAAItN,GAAOoC,aAAc3D,KAAKyoC,eACvC,CAEQe,SAAS/gB,EAAiBgf,GAChC,IAAK,MAAMuB,KAAQvB,EAAO,CACxB,MAAMiC,EAAW1pC,KAAK0nC,OAAOsB,EAAK/6B,UAC5B07B,EAAU3pC,KAAK4pC,WAAWZ,EAAK/6B,UAE/B47B,EAAmBtiC,GAAUmiC,GAAUI,GAAWA,EAAQ1hC,MAAQ4gC,EAAK5gC,QAE7E,GAAIyhC,GAAoB,EAAG,CACzB,MAAME,EAAcL,EAASG,GAAkBr2B,QAC/Ck2B,EAAS/N,OAAOkO,EAAkB,EAAGb,GACrCW,EAAQK,aAAahB,EAAKx1B,QAASu2B,EACpC,MACCL,EAASlO,KAAKwN,GACdW,EAAQlkB,YAAYujB,EAAKx1B,SAG3Bw1B,EAAK7Z,KAAK1G,EAAQzoB,KACnB,CACH,CAEQipC,0BACN,MAAMjjC,EACDlG,OAAA0V,OAAA1V,OAAA0V,OAAA,GAAA8xB,GAAW/kC,eACXvC,KAAKgG,WAEJ4lB,EAAS5rB,KAAK+4B,QAGdwO,EAAexhC,GAAcC,EAAUo3B,aACvC6M,EAAclkC,GAAcC,EAAU23B,qBACtCuM,EAAenkC,GAAcC,EAAU43B,sBAE7ChS,EAAOnG,YAAYwkB,GACnBre,EAAOnG,YAAYykB,GAGnB,MAAM/d,EAAYpmB,GAAcC,EAAUq3B,eACpC8M,EAAapkC,GAAcC,EAAUs3B,cACrC8M,EAAgBrkC,GAAcC,EAAUu3B,iBACxC8M,EAAatkC,GAAcC,EAAUw3B,cACrC8M,EAAsBvkC,GAAcC,EAAUy3B,eAC9C8M,EAAuBxkC,GAAcC,EAAU03B,gBAErD2M,EAAW5kB,YAAY6kB,GACvBD,EAAW5kB,YAAY8kB,GACvBpe,EAAU1G,YAAY8hB,GACtBpb,EAAU1G,YAAY0kB,GACtBhe,EAAU1G,YAAY4kB,GACtBle,EAAU1G,YAAY2kB,GACtBxe,EAAOnG,YAAY0G,GAEnBnsB,KAAKwnC,MAAQD,EACbvnC,KAAK8rB,aAAeK,EACpBnsB,KAAK4pC,WAAa,CAChB,CAACtC,GAAW4B,SAAS7J,UAAW8K,EAChC,CAAC7C,GAAW4B,SAAS3J,WAAY+K,EACjC,CAAChD,GAAW4B,SAAS1J,YAAa+K,EAClC,CAACjD,GAAW4B,SAAS5J,aAAc8K,EACnC,CAAC9C,GAAW4B,SAAS/J,UAAW8K,EAChC,CAAC3C,GAAW4B,SAAS9J,WAAY8K,EAErC,CAEQT,qBACW3pC,OAAO2xB,KAAK6V,GAAW4B,UAAUloC,KAAI2H,GAAO2+B,GAAW4B,SAASvgC,KAGxEyc,SAAQukB,IACf,KAAOA,EAAQa,YACbb,EAAQ9M,YAAY8M,EAAQa,WAC7B,GAEL,CA4CQ1B,gBAAgBrgB,SACtB,MAAMof,EAAW7nC,KAAK6nC,SAChBa,EAAY1oC,KAAK2oC,WAEvB,GAAgB,MAAZd,EACEA,EACFa,EAAUn1B,OAAOkV,GAEjBigB,EAAUj1B,QAAQgV,OAEf,CAEL,MAAMwL,EAA2B,QAAjBruB,EAAA6iB,EAAO8P,kBAAU,IAAA3yB,OAAA,EAAAA,EAAE20B,aAE/BtG,GAAWA,EAAQvS,UAErBgnB,EAAUn1B,OAAOkV,GAEjBigB,EAAUj1B,QAAQgV,EAErB,CACH,CAEQogB,kBAAkBpgB,WACxB,MAAMgiB,EAAazqC,KAAKwnC,MAClBM,EAAiB9nC,KAAK8nC,eACtB4C,EAAmC,QAArB9kC,EAAA5F,KAAKgG,UAAUi5B,cAAM,IAAAr5B,EAAAA,EAAI0hC,GAAW/kC,cAAc08B,OAEtE,GAAsB,MAAlB6I,EACEA,EACF2C,EAAWpkC,UAAU2mB,OAAO0d,GAE5BD,EAAWpkC,UAAUC,IAAIokC,OAEtB,CAEL,MAAMzW,EAA2B,QAAjB0W,EAAAliB,EAAO8P,kBAAU,IAAAoS,OAAA,EAAAA,EAAEpQ,aAE/BtG,GAAWA,EAAQvS,UAErB+oB,EAAWpkC,UAAU2mB,OAAO0d,GAE5BD,EAAWpkC,UAAUC,IAAIokC,EAE5B,CACH,CAEQ3B,uBAAuBtgB,SAC7B,MAAM2gB,EAAW3gB,EAAOmD,OAClBgf,EAAe5qC,KAAKmpC,cACpBlV,EAA2B,QAAjBruB,EAAA6iB,EAAO8P,kBAAU,IAAA3yB,OAAA,EAAAA,EAAE20B,aAE/Bv6B,KAAKgoC,kBAAoB/T,GAAWA,EAAQvS,UAC9CkpB,EAAar3B,OAAO61B,EAAUnV,GAE9B2W,EAAan3B,QAAQ21B,EAEzB,CAEQG,sBACN,MAAM9B,EAA0B,GAkChC,OAhCIznC,KAAKioC,aACPR,EAAMjM,KAAK,IAAIuF,GAAYn5B,GAAgB5H,KAAKioC,eAG9CjoC,KAAKkoC,YACPT,EAAMjM,KAAK,IAAIuG,GAAWn6B,GAAgB5H,KAAKkoC,cAG7CloC,KAAKmoC,cACPV,EAAMjM,KAAK,IAAI6G,GAAcz6B,GAAgB5H,KAAKmoC,gBAGhDnoC,KAAKwoC,YACPf,EAAMjM,KAAK,IAAI8J,GAAW19B,GAAgB5H,KAAKwoC,cAG7CxoC,KAAKuoC,UACPd,EAAMjM,KAAK,IAAI6J,GAASz9B,GAAgB5H,KAAKuoC,YAG3CvoC,KAAKooC,kBACPX,EAAMjM,KAAK,IAAIoH,GAAiBh7B,GAAgB5H,KAAKooC,oBAGnDpoC,KAAKqoC,WACPZ,EAAMjM,KAAK,IAAI+H,GAAU37B,GAAgB5H,KAAKqoC,aAG5CroC,KAAKsoC,SACPb,EAAMjM,KAAK,IAAIyI,GAAQr8B,GAAgB5H,KAAKsoC,WAGvCb,CACT,EA1cuBH,GAAa/kC,cAAG26B,GAMhBoK,GAAQ4B,SAAGhK,GCjEpC,MAAe2L,GA8BbnrC,aAAmBsjB,IACjBA,EAAGjB,MACHA,GAAQ,IAER/hB,KAAKgjB,IAAMA,EACXhjB,KAAK+hB,MAAQA,EACb/hB,KAAK8qC,MAAQ,IACf,CAmBO/P,oBAAoBzR,SACf,QAAV1jB,EAAA5F,KAAK8qC,aAAK,IAAAllC,GAAAA,EAAEgJ,QAAQ0a,EACtB,CAQO2Q,aAAa/tB,GAElBA,EAAO+D,YACT,CAQOisB,cAAczjB,GACnBA,EAAQyH,iBAAkB,CAC5B,CAQO3U,OAAOW,GAAkB,CAQzBquB,aACL,OAAKv6B,KAAK8qC,MAEH9qC,KAAK8qC,MAAMxZ,QAAQC,SAASwZ,SAAS9W,QAFpB,IAG1B,CAOOwE,UACL,OAAOz4B,KAAK8qC,KACd,ECjJF,MAAeE,GAGbtrC,cACEM,KAAKyyB,aAAc,CACrB,CAKO7jB,QAAQwgB,GACb,ECNJ,MAAM6b,WAA2BD,GAK/BtrC,YAAmB4pB,EAAmB2K,EAAsBiX,GAC1DrrC,QAEAG,KAAKi0B,QAAUA,EACfj0B,KAAKmrC,cAAgB7hB,EAAIuL,uBAAuBZ,EAASA,EAAQllB,OACjE/O,KAAKorC,cAAgBF,CACvB,CAEOt8B,QAAQwgB,GACbpvB,KAAKi0B,QAAQrlB,UACbwgB,EAAGic,cAAcrrC,KAAKmrC,cACxB,CAEO5/B,OAAO6jB,EAAoDza,EAAgC4Z,GAChG,MAAM0F,EAAUj0B,KAAKi0B,QAErB7E,EAAGkc,YAAYlc,EAAGmc,oBAAqBtX,EAAQ5S,OAC/C+N,EAAGoc,UAAU72B,EAAU,GACvBya,EAAGqc,cAAcrc,EAAGsc,UACpBtc,EAAG+E,YAAY/E,EAAG0F,iBAAkB90B,KAAKmrC,eAEzBjjC,GAAY+rB,EAAQrR,QAAS5iB,KAAKorC,eAC1ChmB,SAAQ,CAACpC,EAAKtb,KAChB6mB,EACFa,EAAGuc,cAAcvc,EAAGwc,4BAA8BlkC,EAAK,EAAG,EAAG,EAAG0nB,EAAGyc,KAAMzc,EAAG0c,cAAe9oB,GAE3FoM,EAAG2c,WAAW3c,EAAGwc,4BAA8BlkC,EAAK,EAAG0nB,EAAGyc,KAAMzc,EAAGyc,KAAMzc,EAAG0c,cAAe9oB,EAC5F,IAGEiR,EAAQvS,YACX1hB,KAAKyyB,aAAc,EAEvB,ECvCF,MAAMuZ,GASO3kC,WAAS,OAAOrH,KAAKisC,KAAO,CAEvCvsC,YAAmBu0B,EAAoBiX,GhD8CnB1gC,MgD7ClBxK,KAAKi0B,QAAUA,EACfj0B,KAAKksC,gBAAkBhkC,KhD4CLsC,EgD5CuB,IhD6C/BA,GAAO,EACV,GAGF0Y,MAAMoJ,MAAM,EAAGpJ,MAAM1Y,IAAMxJ,KAAI,CAACmrC,EAAOzkC,IAAQA,IgDjDPwjC,GAE7C,MAAM/c,EAAS/nB,SAASL,cAAc,UAEtC/F,KAAKosC,qBAELje,EAAOpf,MAAQ/O,KAAKisC,MACpB9d,EAAOnf,OAAShP,KAAKisC,MAErBjsC,KAAKouB,QAAUD,EACfnuB,KAAK2pB,KAAOwE,EAAO2J,WAAW,KAChC,CAEOlpB,UACL,MAAMuf,EAASnuB,KAAKouB,QAGpBD,EAAOpf,MAAQ,EACfof,EAAOnf,OAAS,EAChBhP,KAAKouB,QAAU,IACjB,CAEO0C,KAAK1B,EAAoDb,GAC9D,MAAMlnB,EAAOrH,KAAKisC,MACZhY,EAAUj0B,KAAKi0B,QACrB,IAAIoY,EAAa,EAEjB,IAAK,IAAIC,EAAM,EAAGA,EAAMtsC,KAAKusC,KAAMD,IACjC,IAAK,IAAIE,EAAS,EAAGA,EAASxsC,KAAKysC,QAASD,IAAU,CACpD,MAAMxoC,EAAIqD,EAAOmlC,EACX/iC,EAAIpC,EAAOilC,EACXI,EAAgB1sC,KAAKksC,gBAAgBG,GAE3CrsC,KAAK2pB,KAAKgjB,UAAU1Y,EAAQpS,OAA6B7d,EAAGyF,EAAGpC,EAAMA,EAAM,EAAG,EAAGA,EAAMA,GAEnFknB,EACFa,EAAGuc,cAAcvc,EAAGwc,4BAA8Bc,EAAe,EAAG,EAAG,EAAGtd,EAAGyc,KAAMzc,EAAG0c,cAAe9rC,KAAKouB,SAE1GgB,EAAG2c,WAAW3c,EAAGwc,4BAA8Bc,EAAe,EAAGtd,EAAGyc,KAAMzc,EAAGyc,KAAMzc,EAAG0c,cAAe9rC,KAAKouB,SAG5Gie,GACD,CAEL,CAEQD,qBACN,MAAMr9B,MACJA,EAAKC,OACLA,GACEhP,KAAKi0B,QACHlsB,EAASgH,EAAQC,EAEnBjH,IAAW,EAAI,GACjB/H,KAAKisC,MAAQl9B,EACb/O,KAAKusC,KAAO,EACZvsC,KAAKysC,QAAU,GACK,IAAX1kC,GACT/H,KAAKisC,MAAQj9B,EACbhP,KAAKusC,KAAO,EACZvsC,KAAKysC,QAAU,GACN1kC,IAAW,EAAI,GACxB/H,KAAKisC,MAAgB,GAARl9B,EACb/O,KAAKusC,KAAO,EACZvsC,KAAKysC,QAAU,IAEfzsC,KAAKisC,MAAQl9B,EAAQ,EACrB/O,KAAKusC,KAAO,EACZvsC,KAAKysC,QAAU,EAEnB,EClFF,MAAMG,WAA0B5B,GAInB/W,cAAY,OAAOj0B,KAAK6sC,SAAS5Y,OAAS,CAErDv0B,YAAmB4pB,EAAmB2K,EAAoBiX,GACxDrrC,QAEAG,KAAK6sC,SAAW,IAAIb,GAAmB/X,EAAsBiX,GAC7DlrC,KAAKmrC,cAAgB7hB,EAAIuL,uBAAuBZ,EAASj0B,KAAK6sC,SAASxlC,KACzE,CAEOuH,QAAQwgB,GACbA,EAAGic,cAAcrrC,KAAKmrC,eACtBnrC,KAAK6sC,SAASj+B,SAChB,CAEOrD,OAAO6jB,EAAoDza,EAAgC4Z,GAChG,MAAM0F,EAAUj0B,KAAKi0B,QAErB7E,EAAGkc,YAAYlc,EAAGmc,qBAAqB,GACvCnc,EAAGoc,UAAU72B,EAAU,GACvBya,EAAGqc,cAAcrc,EAAGsc,UACpBtc,EAAG+E,YAAY/E,EAAG0F,iBAAkB90B,KAAKmrC,eAEzCnrC,KAAK6sC,SAAS/b,KAAK1B,EAAIb,GAElB0F,EAAQvS,YACX1hB,KAAKyyB,aAAc,EAEvB,EC3BF,MAAMqa,WAAgFvQ,GAYpF78B,YAAmBivB,EAAwB2C,GACzCzxB,QAEAG,KAAK2uB,IAAMA,EACX3uB,KAAKsxB,QAAUA,CACjB,CAEO1iB,QAAQ0a,GACbA,EAAI4H,WAAWlxB,KAAK2uB,KACpBrF,EAAIoJ,uBAAuB1yB,KAAKsxB,QAClC,EC3BF,MAAMyb,GAKJrtC,YAAmB4pB,EAAmBwJ,EAAsBC,EAAwBxB,GAClFvxB,KAAKsxB,QAAUhI,EAAIuJ,cAAcC,EAAcC,GAC/C/yB,KAAKuxB,SAAWA,EAChBvxB,KAAKwxB,iBAAmBlI,EAAI+H,oBAAoBrxB,KAAKsxB,QAASC,EAChE,ECRF,MAAMyb,GAMJttC,YAAmB+2B,EAASM,GAC1B/2B,KAAKy2B,KAAOA,EACZz2B,KAAK+2B,SAAWA,EAChB/2B,KAAK8tB,MAAQ2I,EAAK9uB,OAASovB,CAC7B,ECVF,MAAekW,GAMbvtC,YAAmB42B,EAAoBtI,EAAoBuI,GACzDv2B,KAAKs2B,SAAW,IAAI0W,GAAW,IAAIE,aAAa5W,GAAW,GAC3Dt2B,KAAKguB,SAAW,IAAIgf,GAAW,IAAIG,YAAYnf,GAAW,GAC1DhuB,KAAKu2B,IAAM,IAAIyW,GAAW,IAAIE,aAAa3W,GAAM,EACnD,ECRF,MAAM6W,WAAqBH,GACzBvtC,aAAmB0I,MACjBA,EAAKilC,SACLA,IAKA,MAqDMC,EAAW,EAAI,EACfC,EAAqB,GAE3B,IAAK,IAAIC,EAAI,EAAGA,GAAK,EAAGA,IACtB,IAAK,IAAIC,EAAI,EAAGA,EAAI,EAAGA,IAAK,CAC1B,MAAMC,EAAQ,CACZD,EAAIH,EAAc,GAAJE,GACbC,EAAI,GAAKH,EAAc,GAAJE,GACnBC,EAAI,GAAKH,EAAoB,IAATE,EAAI,GACzBC,EAAIH,EAAoB,IAATE,EAAI,IAGrBD,EAAO/R,KAAKkS,EACb,CAGCL,GACFA,EAASjoB,SAAQ,CAACuoB,EAAQjmC,KACxB,GAAIimC,IAAWroC,GAAOsoC,KAAM,OAE5B,MAAMF,EAAQH,EAAO7lC,GACrB,IAAImmC,EAGFA,EADEF,IAAWroC,GAAOwoC,MACT,CAAC,EAAG,EAAG,EAAG,GACZH,IAAWroC,GAAOyoC,OAChB,CAAC,EAAG,EAAG,EAAG,GAEV,CAAC,EAAG,EAAG,EAAG,GAGvB,MAAMC,EAAY9qB,MAAcwqB,EAAM/lC,QACtC,IAAK,IAAIsmC,EAAQ,EAAGA,EAAQP,EAAM/lC,OAAS,EAAGsmC,IAC5CD,EAAkB,EAARC,EAAY,GAAKP,EAAwB,EAAlBG,EAASI,GAAa,GACvDD,EAAkB,EAARC,EAAY,GAAKP,EAAwB,EAAlBG,EAASI,GAAa,GAGzDV,EAAO7lC,GAAOsmC,CAAS,IAO3BnuC,MAjGiB,CAEf,GAAI,EAAG,GACN,GAAI,EAAG,GACP,EAAG,EAAG,EACP,EAAG,EAAG,GAGL,GAAI,GAAI,EACT,GAAI,GAAI,EACR,EAAG,GAAI,GACN,EAAG,GAAI,GAGP,EAAG,GAAI,EACR,EAAG,GAAI,EACP,EAAG,EAAG,GACL,EAAG,EAAG,GAGN,GAAI,EAAG,EACR,GAAI,EAAG,EACP,GAAI,GAAI,GACP,GAAI,GAAI,EAGT,GAAI,GAAI,EACR,GAAI,EAAG,EACP,EAAG,EAAG,EACN,EAAG,GAAI,GAGN,GAAI,EAAG,GACP,GAAI,GAAI,GACR,EAAG,GAAI,GACP,EAAG,EAAG,GAGQ,CACf,EAAG,EAAG,EACN,EAAG,EAAG,EACN,EAAG,EAAG,EACN,EAAG,EAAG,EACN,EAAG,EAAG,GACN,EAAG,GAAI,GACP,GAAI,GAAI,GACR,GAAI,GAAI,GACR,GAAI,GAAI,GACR,GAAI,GAAI,GACR,GAAI,GAAI,GACR,GAAI,GAAI,IA4CEqI,GAAYqlC,EAAQnlC,EAAO,UACpCiN,QAAO,CAAC64B,EAAKptC,IAAQotC,EAAIC,OAAOrtC,IAAM,IAG3C,EC7GF,MAAMstC,WAAyBpD,GAI7BtrC,YAAmB4pB,EAAmB2K,GACpCp0B,QAEAG,KAAKi0B,QAAUA,EACfj0B,KAAKmrC,cAAgB7hB,EAAIyK,mBAAmBE,EAC9C,CAEOrlB,QAAQwgB,GACbpvB,KAAKi0B,QAAQrlB,UACbwgB,EAAGic,cAAcrrC,KAAKmrC,cACxB,CAEO5/B,OAAO6jB,EAAoDza,EAAgC4Z,GAChG,MAAM0F,EAAUj0B,KAAKi0B,QACfvS,EAAUuS,EAAQvS,UAExB0N,EAAGkc,YAAYlc,EAAGmc,oBAAqBtX,EAAQ5S,OAC/C+N,EAAGoc,UAAU72B,EAAU,GACvBya,EAAGqc,cAAcrc,EAAGsc,UACpBtc,EAAG+E,YAAY/E,EAAGgF,WAAYp0B,KAAKmrC,gBAE9BzpB,GAAW6M,EACda,EAAGuc,cAAcvc,EAAGgF,WAAY,EAAG,EAAG,EAAGhF,EAAGyc,KAAMzc,EAAG0c,cAAe7X,EAAQpS,QAE5EuN,EAAG2c,WAAW3c,EAAGgF,WAAY,EAAGhF,EAAGyc,KAAMzc,EAAGyc,KAAMzc,EAAG0c,cAAe7X,EAAQpS,QAGzEH,IACH1hB,KAAKyyB,aAAc,EAEvB,mVCjCF,MAAM4b,WAAyBpB,GAC7BvtC,YAAmB4uC,GACjB,MAAMhY,EAAqB,GACrBtI,EAAqB,GACrBuI,EAAgB,GAKhBgY,EAAiB,EADJv/B,OAEbw/B,EAAoB,EAHH,GAIjBC,EAAaH,EAAWE,EAE9B,IAAK,IAAIE,EAAO,EAAGA,EAAO,EAAGA,IAAQ,CACnC,MAAMjlC,EAAI8kC,EAAeG,GAEzB,IAAK,IAAIC,EAAS,EAAGA,GATA,GAS0BA,IAAU,CACvD,MAAM9yB,EAAQ8yB,EAASF,EAAavqC,KAAKE,GAAgB,GAAXkqC,EACxCtqC,EAAIE,KAAKwY,IAAIb,GACbnS,EAAIxF,KAAKC,IAAI0X,GACb+yB,EAAID,EAASH,EACbK,EAAIH,EAKV,GAHAnY,EAAIiF,KAAKoT,EAAGC,GACZvY,EAASkF,KAAKx3B,EAAGyF,EAAGC,GAEP,IAATglC,GAAcC,EAnBC,GAmBwB,CACzC,MAAM1nC,EAAI0nC,EACJznC,EAAID,EArBO,GAqBc,EAE/B+mB,EAASwN,KAAKv0B,EAAGC,EAAGD,EAAI,EAAGC,EAAGA,EAAI,EAAGD,EAAI,EAC1C,CACF,CACF,CAEDpH,MAAMy2B,EAAUtI,EAAUuI,EAC5B,ECpCF,MAAMuY,WAAuB7B,GAE3BvtC,cAEE,MACM6uC,EAAiB,GACjBQ,GAAqC,GAAM7qC,KAAKE,GAEhDmyB,EAAgB,GAChBD,EAAqB,GACrBtI,EAAqB,GAC3B,IAAIghB,EACAL,EAEJ,IAAKK,EAAS,EAAGA,GAVK,GAUoBA,IAAU,CAClD,MAAMp+B,GAASo+B,EAXK,GAWoB,IAAO9qC,KAAKE,GAC9C6qC,EAAW/qC,KAAKC,IAAIyM,GACpBs+B,EAAWhrC,KAAKwY,IAAI9L,GAE1B,IAAK+9B,EAAS,EAAGA,GAAUJ,EAAgBI,IAAU,CACnD,MAAMQ,EAAwC,GAAjCR,EAASJ,EAAiB,IAAWrqC,KAAKE,GAAK2qC,EACtDK,EAASlrC,KAAKC,IAAIgrC,GAElBnrC,EADSE,KAAKwY,IAAIyyB,GACLD,EACbzlC,EAAIwlC,EACJvlC,EAAI0lC,EAASF,EACbN,EAAID,EAASJ,EACbM,EAAIG,EAvBQ,GA4BlB,GAHAzY,EAAIiF,KAAKoT,EAAGC,GACZvY,EAASkF,KAAKx3B,EAAGyF,EAAGC,GAEhBilC,IAAWJ,GA5BG,KA4BeS,EAA0B,CACzD,MAAM/nC,EAAU,GAAN+nC,EAAgCL,EACpCznC,EAAID,EAAIsnC,EAAiB,EAE/BvgB,EAASwN,KAAKv0B,EAAGA,EAAI,EAAGC,EAAGA,EAAGD,EAAI,EAAGC,EAAI,EAC1C,CACF,CACF,CAEDrH,MAAMy2B,EAAUtI,EAAUuI,EAC5B,EC7CF,MAAM8Y,WAAqBrE,GAGzBtrC,YAAmBoB,GACjBjB,QAEAG,KAAKc,IAAMA,CACb,CAEOyK,OAAO6jB,EAAoDza,GAChEya,EAAGkD,UAAU3d,EAAU3U,KAAKc,KAE5Bd,KAAKyyB,aAAc,CACrB,ECVF,MAAM6c,WAAsBrC,GAE1BvtC,YAAmBqP,EAAgB,EAAGC,EAAiB,EAAGtF,GAAY,GACpE,MAAMgjB,EAAoB,GAAR3d,EACZ4d,EAAsB,GAAT3d,EAkBnBnP,MAjBiB,EACd6sB,GAAYC,EAAYjjB,EACzBgjB,GAAYC,EAAYjjB,GACvBgjB,EAAWC,EAAYjjB,EACxBgjB,EAAWC,EAAYjjB,GAER,CACf,EAAG,EAAG,EACN,EAAG,EAAG,GAEI,CACV,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,GAIP,EC1BF,MAAM6lC,WAA4BvE,GAGhCtrC,YAAmBoB,GACjBjB,QAEAG,KAAKc,IAAMA,CACb,CAEOyK,OAAO6jB,EAAoDza,GAChEya,EAAGogB,WAAW76B,EAAU3U,KAAKc,IAAIuU,QAAO,CAAClN,EAAKsnC,IAAW,IAAItnC,KAAQsnC,IAAS,KAE9EzvC,KAAKyyB,aAAc,CACrB,ECoBF,MAAMid,WAA6B7E,GA8BjCnrC,YAAmBgpB,GACjB7oB,MAAM6oB,GAEN1oB,KAAK2vC,MAAQjnB,EAAQknB,IACvB,CAEO3T,aAAa3S,EAAmB2K,GACrC,IAAI4b,EACAC,EAEJ,GAAQ9vC,KAAK2vC,QACND,GAAqBK,KAAKC,WAC7BH,EAAU,CAAC,GAAK,EAAG,EAAG,GACtBC,EAAW,CAAC,GAAK,EAAG,GAAK,QAIzBD,EAAU,CAAC,EAAG,GAAK,EAAG,GACtBC,EAAW,CAAC,EAAG,GAAK,EAAG,IAI3B,MAAMve,EAAW,CACfwZ,SAAU,IAAIqD,GAAiB9kB,EAAK2K,GACpC5B,KAAM,IAAIgd,GAAa,GACvBY,gBAAiB,IAAIV,GAAoB,CAACM,EAASC,KAG/C/hB,EAAW,IAAI+gB,GACfxd,EAAU,IAAIyb,GAAczjB,4UAAS6J,GAAI5B,GAEzC5C,EAAMrF,EAAI+G,UAAUtC,EAAUuD,GAC9BkH,EAAO,IAAIsU,GAAane,EAAK2C,GAEnCtxB,KAAK8qC,MAAQtS,CACf,EAvDckX,GAAAK,KAAO,CAKnBC,WAAY,aAKZE,WAAY,qZCdhB,cAAgCrF,GAW9BnrC,YAAmBgpB,GACjB7oB,MAAM6oB,GAEN,MAAMwiB,aACJA,EAAe,SAAQiF,aACvBA,GAAe,GACbznB,EAEJ1oB,KAAKorC,cAAgBF,EACrBlrC,KAAKowC,cAAgBD,CACvB,CAEOlU,aAAa3S,EAAmB2K,GACrC,MAAMiX,EAAelrC,KAAKorC,cACpB+E,EAAenwC,KAAKowC,cACpB7e,EAAW,CACfwZ,SAAU9W,EAAQtS,SACd,IAAIspB,GAAmB3hB,EAAK2K,EAAwBiX,GACpD,IAAI0B,GAAkBtjB,EAAK2K,EAAsBiX,IAGjDnd,EAAW,IAAIqf,GAAa,CAChChlC,MAAO8iC,IAEH5Z,EAAU,IAAIyb,GAAczjB,2WAAaiI,GACzC5C,EAAMrF,EAAI+G,UAAUtC,EAAUuD,GAC9BkH,EAAO,IAAIsU,GAAane,EAAK2C,GAE/B6e,IACF3X,EAAK7gB,MAAM,IAAM,GAEnB6gB,EAAKtpB,eAELlP,KAAK8qC,MAAQtS,CACf,uBCjDF,cAAkCqS,GAWhCnrC,YAAmBgpB,GACjB7oB,MAAM6oB,GAEN,MAAMwiB,aACJA,EAAe,SAAQiF,aACvBA,GAAe,GACbznB,EAEJ1oB,KAAKorC,cAAgBF,EACrBlrC,KAAKowC,cAAgBD,CACvB,CAEOlU,aAAa3S,EAAmB2K,GACrC,MAAMiX,EAAelrC,KAAKorC,cACpB+E,EAAenwC,KAAKowC,cACpB7e,EAAW,CACfwZ,SAAU,IAAIqD,GAAiB9kB,EAAK2K,IAEhClG,EAAW,IAAIqf,GAAa,CAChChlC,MAAO8iC,IAEH5Z,EAAU,IAAIyb,GAAczjB,EAAK0J,GAAIG,GAAI5B,GACzC5C,EAAMrF,EAAI+G,UAAUtC,EAAUuD,GAC9BkH,EAAO,IAAIsU,GAAane,EAAK2C,GAE/B6e,IACF3X,EAAK7gB,MAAM,IAAM,GAEnB6gB,EAAKtpB,eAELlP,KAAK8qC,MAAQtS,CACf,yBCzCF,cAAoCqS,GAUlCnrC,YAAmBgpB,GACjB7oB,MAAM6oB,GAEN,MAAM2nB,QACJA,GAAU,GACR3nB,EAEJ1oB,KAAKswC,SAAWD,CAClB,CAEOpU,aAAa3S,EAAmB2K,GACrC,MAAMoc,EAAUrwC,KAAKswC,UACfvhC,MAAEA,EAAKC,OAAEA,GAAWilB,EACpBlsB,EAASgH,EAAQC,EACjBiC,EAAW,IAAMlJ,EACjBwoC,EAAiBF,EACnB,EACA,EAAInsC,KAAK+D,IAAIgJ,EAAWrM,IACtB4rC,EAAgBH,EAClBtoC,EACA,EAAI7D,KAAKE,GAEP2pB,EAAW,IAAIsgB,GAAiBmC,GAChClf,EAAU,IAAIyb,GAAczjB,EAAK0J,GAAIG,GAAI,CAC7C4X,SAAU,IAAIqD,GAAiB9kB,EAAK2K,KAEhCtF,EAAMrF,EAAI+G,UAAUtC,EAAUuD,GAC9BkH,EAAO,IAAIsU,GAAane,EAAK2C,GAEnCkH,EAAK7gB,MAAM,GAAK44B,EAChBlnC,EAAcmvB,EAAK1rB,UACnBzD,EAAamvB,EAAK1rB,SAAU0rB,EAAK1rB,UAAW5I,KAAKE,GAAK,GACtDo0B,EAAKtpB,eAELlP,KAAK8qC,MAAQtS,CACf,CAEOyB,aAAa/tB,GAClBrM,MAAMo6B,aAAa/tB,GAEnB,MAAMssB,EAAOx4B,KAAK8qC,MAClB,IAAKtS,EAAM,OAEX,MACMvE,EADWuE,EAAKlH,QAAQC,SAASwZ,SACd9W,SACnBllB,MAAEA,EAAKC,OAAEA,GAAWilB,EACpBlsB,EAASgH,EAAQC,EACjB2d,EAA6B,GAAhB6L,EAAK7gB,MAAM,GAE9B,GAAI3X,KAAKswC,SAAU,CACjB,MAAMG,EAAgB,GAAM1oC,EAASlD,GACrCqH,EAAO2D,kBAAkB4gC,EAAeA,EACzC,CAED,MAAMC,EAAkBxsC,KAAK4F,MAAM6iB,EAAY,GAAK9nB,GAC9C8rC,EAAUzsC,KAAK+D,IAAIiE,EAAO6B,IAAMnJ,GAAa,KAAQ+nB,EAAazgB,EAAOnE,QAE/EmE,EAAO4D,oBAAoB4gC,EAAiBA,GAC5CxkC,EAAO6D,kBAAkB4gC,EAASzrC,KAClCgH,EAAO8D,qBAAkC,EAAb2c,EAC9B,yBCjFF,cAAoCke,GAG3B5O,aAAa3S,EAAmB2K,GACrC,MAAM1C,EAAW,CACfwZ,SAAU,IAAIqD,GAAiB9kB,EAAK2K,IAEhClG,EAAW,IAAIqf,GAAa,CAChChlC,MAAO,SACPilC,SAAU,CACR/nC,GAAOsoC,KAAMtoC,GAAOsoC,KAAMtoC,GAAOsoC,KACjCtoC,GAAOwoC,MAAOxoC,GAAOyoC,OAAQzoC,GAAOwoC,SAGlCxc,EAAU,IAAIyb,GAAczjB,EAAK0J,knCAAQzB,GACzC5C,EAAMrF,EAAI+G,UAAUtC,EAAUuD,GAC9BkH,EAAO,IAAIsU,GAAane,EAAK2C,GAEnCtxB,KAAK8qC,MAAQtS,CACf,sBCpBF,cAAiCqS,GAQ/BnrC,YAAmBgpB,GACjB7oB,MAAM6oB,EACR,CAEOuT,aAAa3S,EAAmB2K,GACrC,MAAM1C,EAAW,CACfwZ,SAAU,IAAIqD,GAAiB9kB,EAAK2K,IAGhClG,EAAW,IAAI+gB,GACfxd,EAAU,IAAIyb,GAAczjB,EAAK0J,GAAIG,GAAI5B,GAEzC5C,EAAMrF,EAAI+G,UAAUtC,EAAUuD,GAC9BkH,EAAO,IAAIsU,GAAane,EAAK2C,GAEnCtxB,KAAK8qC,MAAQtS,CACf,0BCrBF,cAAqCqS,GAWnCnrC,YAAmBgpB,GACjB7oB,MAAM6oB,EACR,CAEOuT,aAAa3S,EAAmB2K,GACrCA,EAAQ3S,MAAQC,sBAAsBqvB,OACtC3c,EAAQxS,MAAQF,sBAAsBqvB,OAEtC,MAAMrf,EAAW,CACfwZ,SAAU,IAAIqD,GAAiB9kB,EAAK2K,GACpC4c,KAAM,IAAIxB,GAAa,GACvByB,OAAQ,IAAIzB,GAAa,IACzB0B,MAAO,IAAI1B,GAAa,IAGpBthB,EAAW,IAAIuhB,GACfhe,EAAU,IAAIyb,GAAczjB,shCAAaiI,GAEzC5C,EAAMrF,EAAI+G,UAAUtC,EAAUuD,GAC9BkH,EAAO,IAAIsU,GAAane,EAAK2C,GAEnCtxB,KAAK8qC,MAAQtS,CACf,CAEO0D,cAAczjB,GACnBA,EAAQyH,iBAAkB,CAC5B,CAEO3U,OAAOW,GACZ,MAAMssB,EAAOx4B,KAAK8qC,MAClB,IAAKtS,EAAM,OAEX,MAAMjH,EAAWiH,EAAKlH,QAAQC,SAE9BA,EAASsf,KAAK/vC,IAAMoL,EAAOhD,IAAM,IAEjCqoB,EAASuf,OAAOhwC,IAAOoL,EAAO/C,MAAQ,IAAO,GAC7CooB,EAASwf,MAAMjwC,IAAMoL,EAAOa,KAE5BwkB,EAASsf,KAAKpe,aAAc,EAC5BlB,EAASuf,OAAOre,aAAc,EAC9BlB,EAASwf,MAAMte,aAAc,CAC/B,0HCnF4Bue,GACrBlxC,OAAO2xB,KAAKuf,GAAU37B,QAAO,CAAC47B,EAAOC,KAChB,MAAtBF,EAASE,KACXD,EAAMC,GAAYF,EAASE,IAGtBD,IACN,CAAE,mBCVwB,CAC7B,UACA,OACA,OACA,SACA,aACA,gBACA,cAEA,KACA,QACA,OACA,MACA,uBCPkBE,CAAClxC,EAAgBmxC,KACnC,CAAClkC,EAAUjN,UAAW64B,GAAQ74B,WAAWmlB,SAAQisB,IAC/CvxC,OAAOwxC,oBAAoBD,GACxBx7B,QAAO3V,GAA2B,MAAnBA,EAAKqxC,OAAO,IAAuB,gBAATrxC,IACzCklB,SAASllB,IACR,MAAMsxC,EAAa1xC,OAAO2xC,yBAAyBJ,EAAOnxC,GAE1D,GAAIsxC,EAAWE,MAEb5xC,OAAO6xC,eAAe1xC,EAAWC,EAAM,CACrCwxC,MAAO,YAAYE,GACjB,OAAOJ,EAAWE,MAAMpO,KAAKtjC,KAAKoxC,MAAUQ,EAC9C,QAEG,CACL,MAAMC,EAAkE,CAAA,EACpEL,EAAWM,MACbD,EAAiBC,IAAM,iBACrB,OAAO9xC,KAAKoxC,KAAyB,QAAhBxrC,EAAA4rC,EAAWM,WAAK,IAAAlsC,OAAA,EAAAA,EAAA09B,KAAKtjC,KAAKoxC,OAG/CI,EAAWO,MACbF,EAAiBE,IAAM,YAAYH,SACjC,eAAOhsC,EAAA4rC,EAAWO,0BAAKzO,KAAKtjC,KAAKoxC,MAAUQ,KAI/C9xC,OAAO6xC,eAAe1xC,EAAWC,EAAM2xC,EACxC,IACD,GACJ,StE2DiBG,EAACjW,KAAmBkW,KACvCA,EAAK7sB,SAAQvD,IACX/hB,OAAO2xB,KAAK5P,GAAQuD,SAAQzc,IAC1B,MAAM+oC,EAAQ7vB,EAAOlZ,GACjBua,MAAMC,QAAQ4Y,EAAOpzB,KAASua,MAAMC,QAAQuuB,GAC9C3V,EAAOpzB,GAAO,IAAIozB,EAAOpzB,MAAS+oC,GAElC3V,EAAOpzB,GAAO+oC,CACf,GACD,GAGS,EuEpGfM,CAAMlZ,GAASoZ"} \ No newline at end of file diff --git a/demo/release/4.0.0-beta.4/sass/base.sass b/demo/release/4.0.0-beta.4/sass/base.sass new file mode 100644 index 000000000..5160e86d7 --- /dev/null +++ b/demo/release/4.0.0-beta.4/sass/base.sass @@ -0,0 +1,17 @@ +@import variable + +.#{$view360-prefix}-container + position: relative + touch-action: pan-y + overflow: hidden + +.#{$view360-prefix}-canvas + position: absolute + left: 0 + top: 0 + width: 100% + height: 100% + user-select: none + -webkit-user-drag: none + &.ctx-lost + text-indent: 0.001px diff --git a/demo/release/4.0.0-beta.4/sass/control-bar.sass b/demo/release/4.0.0-beta.4/sass/control-bar.sass new file mode 100644 index 000000000..97806b111 --- /dev/null +++ b/demo/release/4.0.0-beta.4/sass/control-bar.sass @@ -0,0 +1,284 @@ +@import variable + +.#{$view360-prefix}-controls + position: absolute + top: 0 + left: 0 + width: 100% + height: 100% + padding: 0 + margin: 0 + border: 0 + pointer-events: none + user-select: none + -webkit-user-drag: none + z-index: 1 +.#{$view360-prefix}-main + &.#{$view360-prefix}-vr-presenting + .#{$view360-prefix}-controls + display: none + +.#{$view360-prefix}-controls-float-left, +.#{$view360-prefix}-controls-float-right + position: absolute + display: flex + flex-direction: column + +.#{$view360-prefix}-controls-float-left + left: 0px + top: 0px + +.#{$view360-prefix}-controls-float-right + right: 0px + top: 0px + +.#{$view360-prefix}-controls-main + position: absolute + bottom: 0 + left: 0 + width: 100% + opacity: 1 + transition: none + &.#{$view360-prefix}-controls-hidden + opacity: 0 + transition: opacity 500ms + * + pointer-events: none + &.#{$view360-prefix}-controls-fixed + opacity: 1 + +.#{$view360-prefix}-controls-background + width: 100% + height: calc(100% + 32px) + position: absolute + left: 0 + bottom: 0 + background-image: linear-gradient(0deg, rgba(50, 50, 50, 1), rgba(50, 50, 50, 0)) + &.#{$view360-prefix}-controls-hidden + display: none + +.#{$view360-prefix}-controls-mid + display: flex + flex-direction: row + position: relative + +.#{$view360-prefix}-controls-left + display: flex + flex: 1 + justify-content: flex-start + align-items: center + flex-direction: row + +.#{$view360-prefix}-controls-right + display: flex + align-items: center + flex-direction: row + +.#{$view360-prefix}-controls-bottom + display: flex + align-items: center + flex-direction: row + +.#{$view360-prefix}-controls-button + display: inline-block + background-color: transparent + cursor: pointer + border: 0 + position: relative + background-size: 24px 24px + background-origin: content-box + background-repeat: no-repeat + box-sizing: border-box + pointer-events: all + border-radius: 20px + transition: opacity 250ms + width: 40px + height: 40px + margin: 6px + padding: 8px + opacity: 0.8 + &:hover + opacity: 1 + &.#{$view360-prefix}-controls-vr + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48' viewBox='0 0 100 100'%3E%3Cg%3E%3Cpath d='M5,30 L95,30 L95,80 L55,80 L50,70 L45,80 L5,80 L5,30' fill='transparent' stroke='%23fff' stroke-width='8' stroke-linejoin='round' stroke-linecap='round'/%3E%3Cpath d='M5,30 L15,10 L85,10 L95,30' fill='transparent' stroke='%23fff' stroke-width='8' stroke-linejoin='round' stroke-linecap='round'/%3E%3Ccircle cx='30' cy='55' r='10' stroke='%23fff' stroke-width='8' fill='transparent' /%3E%3Ccircle cx='70' cy='55' r='10' stroke='%23fff' stroke-width='8' fill='transparent' /%3E%3C/g%3E%3C/svg%3E") + /* + * Following background-image svgs are from tabler icons + * https://github.com/tabler/tabler-icons + * + * tabler icons is licensed under the MIT license + * https://github.com/tabler/tabler-icons/blob/master/LICENSE + */ + &.#{$view360-prefix}-controls-play + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M7 4v16l13 -8z'%3E%3C/path%3E%3C/svg%3E") + &.#{$view360-prefix}-controls-pause + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Crect x='6' y='5' width='4' height='14' rx='1'%3E%3C/rect%3E%3Crect x='14' y='5' width='4' height='14' rx='1'%3E%3C/rect%3E%3C/svg%3E") + &.#{$view360-prefix}-controls-unmuted + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M15 8a5 5 0 0 1 0 8'%3E%3C/path%3E%3Cpath d='M17.7 5a9 9 0 0 1 0 14'%3E%3C/path%3E%3Cpath d='M6 15h-2a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h2l3.5 -4.5a0.8 .8 0 0 1 1.5 .5v14a0.8 .8 0 0 1 -1.5 .5l-3.5 -4.5'%3E%3C/path%3E%3C/svg%3E") + &.#{$view360-prefix}-controls-muted + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M6 15h-2a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h2l3.5 -4.5a0.8 .8 0 0 1 1.5 .5v14a0.8 .8 0 0 1 -1.5 .5l-3.5 -4.5'%3E%3C/path%3E%3Cpath d='M16 10l4 4m0 -4l-4 4'%3E%3C/path%3E%3C/svg%3E") + &.#{$view360-prefix}-controls-fullscreen + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M4 8v-2a2 2 0 0 1 2 -2h2'%3E%3C/path%3E%3Cpath d='M4 16v2a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v2'%3E%3C/path%3E%3Cpath d='M16 20h2a2 2 0 0 0 2 -2v-2'%3E%3C/path%3E%3C/svg%3E") + &.#{$view360-prefix}-controls-fullscreen-exit + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M15 19v-2a2 2 0 0 1 2 -2h2'%3E%3C/path%3E%3Cpath d='M15 5v2a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3Cpath d='M5 15h2a2 2 0 0 1 2 2v2'%3E%3C/path%3E%3Cpath d='M5 9h2a2 2 0 0 0 2 -2v-2'%3E%3C/path%3E%3C/svg%3E") + /* + * Following background-image svgs are from Google Material Icons + * https://fonts.google.com/icons + * + * Material Design Icons is licensed under the Apache License 2.0 + * https://github.com/google/material-design-icons/blob/master/LICENSE + */ + &.#{$view360-prefix}-controls-gyro-enabled + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48'%3E%3Cpath fill='%23fff' d='M22.5 7.6v2.95q-1 .15-1.975.475-.975.325-1.875.825L16.5 9.7q1.35-.9 2.875-1.4 1.525-.5 3.125-.7Zm15.35 15.35q-.2 1.6-.7 3.125-.5 1.525-1.4 2.875L33.6 26.8q.5-.9.825-1.875.325-.975.475-1.975Zm3.8 20.45L1.3 3.05 3.45.9 43.8 41.25ZM7 41.4q-1.25 0-2.125-.875T4 38.4v-8.6h3v8.6h8.6v3ZM41 13V4.4h-8.6v-3H41q1.25 0 2.125.875T44 4.4V13ZM4 13V4.4q0-.55.2-1.1t.6-1l2.1 2.1V13Zm28.4 28.4v-3h8.5l2.1 2.1q-.4.45-.925.675-.525.225-1.075.225Zm-21.2-37-3-3h7.4v3ZM44 37.2l-3-3v-4.4h3ZM10.15 22.95h2.95q.5 3.7 3.1 6.3 2.6 2.6 6.3 3.1v2.95q-4.9-.55-8.35-4-3.45-3.45-4-8.35Zm4-11.35 2.1 2.05q-1.3 1.3-2.1 2.9-.8 1.6-1.05 3.4h-2.95q.25-2.4 1.275-4.525Q12.45 13.3 14.15 11.6ZM31.8 29.2l2.05 2.1q-1.7 1.7-3.825 2.725Q27.9 35.05 25.5 35.3v-2.95q1.8-.25 3.4-1.05 1.6-.8 2.9-2.1ZM25.5 7.6q4.9.55 8.35 4 3.45 3.45 4 8.35H34.9q-.5-3.7-3.1-6.3-2.6-2.6-6.3-3.1Z'/%3E%3C/svg%3E") + &.#{$view360-prefix}-controls-gyro-disabled + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48'%3E%3Cpath fill='%23fff' d='M7 44q-1.2 0-2.1-.9Q4 42.2 4 41v-8.6h3V41h8.6v3ZM4 15.6V7q0-1.2.9-2.1Q5.8 4 7 4h8.6v3H7v8.6Zm18.5 22.25q-4.9-.55-8.35-4-3.45-3.45-4-8.35h2.95q.5 3.7 3.125 6.3 2.625 2.6 6.275 3.1ZM10.15 22.5q.55-4.9 4-8.35 3.45-3.45 8.35-4v2.95q-3.7.5-6.3 3.1-2.6 2.6-3.1 6.3Zm13.85 5q-1.45 0-2.475-1.025Q20.5 25.45 20.5 24q0-1.45 1.025-2.475Q22.55 20.5 24 20.5q1.45 0 2.475 1.025Q27.5 22.55 27.5 24q0 1.45-1.025 2.475Q25.45 27.5 24 27.5Zm1.5 10.35V34.9q3.7-.5 6.3-3.125 2.6-2.625 3.1-6.275h2.95q-.55 4.9-4 8.35-3.45 3.45-8.35 4Zm9.4-15.35q-.5-3.7-3.1-6.3-2.6-2.6-6.3-3.1v-2.95q4.9.55 8.35 4 3.45 3.45 4 8.35ZM32.4 44v-3H41v-8.6h3V41q0 1.2-.9 2.1-.9.9-2.1.9ZM41 15.6V7h-8.6V4H41q1.2 0 2.1.9.9.9.9 2.1v8.6Z'/%3E%3C/svg%3E") + +.#{$view360-prefix}-controls-time + display: inline-block + vertical-align: top + white-space: nowrap + color: white + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" + font-weight: normal + font-size: 14px + z-index: 1 + &:first-child + padding: 0 16px + +.#{$view360-prefix}-controls-progress + flex: 1 + width: 100% + padding: 0 16px + box-sizing: border-box + &:not(:first-child) + padding-left: 0 +.#{$view360-prefix}-controls-bottom + .#{$view360-prefix}-controls-progress + padding-bottom: 20px + +.#{$view360-prefix}-controls-volume + display: inline-flex + flex-direction: row + align-items: center + transition: width 250ms, background-color 250ms + overflow: hidden + &:not(:disabled) + &:hover, + &.#{$view360-prefix}-controls-fixed + width: 112px + .#{$view360-prefix}-range + flex: 1 + height: 100% + padding: 0 + .#{$view360-prefix}-range-track + width: calc(100% - 12px) + transform: translateX(-4px) + .#{$view360-prefix}-controls-button + margin: 0 + padding: 0 + width: 24px + height: 24px + flex-shrink: 0 + &:disabled + opacity: 0.5 + pointer-events: none + * + pointer-events: none + +.#{$view360-prefix}-controls-pie + width: 36px + height: 36px + margin: 6px + padding: 0 + border-radius: 18px + opacity: 0.8 + pointer-events: all + cursor: pointer + color: #fff + position: relative + transition: opacity 250ms + > svg + position: absolute + top: 0 + left: 0 + width: 100% + height: 100% + &:hover + opacity: 1 + +.#{$view360-prefix}-range + position: relative + cursor: pointer + pointer-events: all + display: flex + justify-content: center + align-items: center + touch-action: pan-y + &:hover + .#{$view360-prefix}-range-thumb + opacity: 1 + +.#{$view360-prefix}-range-track + width: 100% + height: 4px + border-radius: 4px + position: relative + background-color: rgba(230, 230, 230, 0.4) + +.#{$view360-prefix}-range-filler, +.#{$view360-prefix}-range-load + position: absolute + left: 0 + top: 0 + width: 0 + height: 100% + border-radius: 4px + +.#{$view360-prefix}-range-filler + background-color: #fff + +.#{$view360-prefix}-range-load + background-color: #757575 + +.#{$view360-prefix}-range-thumb + width: 13px + height: 13px + position: absolute + top: -5px + left: -6.5px + border-radius: 50% + background-color: #fff + box-sizing: border-box + transition: opacity 250ms + opacity: 0 + &.#{$view360-prefix}-controls-fixed + opacity: 1 + +.#{$view360-prefix}-controls-unavailable + display: none !important + +@media screen and (max-width: 768px) + .#{$view360-prefix}-controls-button + background-size: 18px 18px + width: 30px + height: 30px + margin: 4.5px + padding: 6px + border-radius: 15px + + .#{$view360-prefix}-controls-volume + .#{$view360-prefix}-controls-button + width: 18px + height: 18px + + .#{$view360-prefix}-controls-volume + &:not(:disabled) + &:hover, + &.#{$view360-prefix}-controls-fixed + width: 84px + + .#{$view360-prefix}-controls-pie + width: 27px + height: 27px + margin: 4.5px + padding: 0 + border-radius: 13.5px diff --git a/demo/release/4.0.0-beta.4/sass/helper.sass b/demo/release/4.0.0-beta.4/sass/helper.sass new file mode 100644 index 000000000..1b6e364de --- /dev/null +++ b/demo/release/4.0.0-beta.4/sass/helper.sass @@ -0,0 +1,51 @@ +@import variable + +.#{$view360-prefix}-container + &.#{$view360-helper-prefix}-square, + &.#{$view360-helper-prefix}-1by1 + padding-top: 100% + + &.#{$view360-helper-prefix}-5by4 + padding-top: 80% + + &.#{$view360-helper-prefix}-4by3 + padding-top: 75% + + &.#{$view360-helper-prefix}-3by2 + padding-top: 66.6666% + + &.#{$view360-helper-prefix}-5by3 + padding-top: 60% + + &.#{$view360-helper-prefix}-16by9 + padding-top: 56.25% + + &.#{$view360-helper-prefix}-2by1 + padding-top: 50% + + &.#{$view360-helper-prefix}-3by1 + padding-top: 33.3333% + + &.#{$view360-helper-prefix}-4by5 + padding-top: 125% + + &.#{$view360-helper-prefix}-3by4 + padding-top: 133.3333% + + &.#{$view360-helper-prefix}-2by3 + padding-top: 150% + + &.#{$view360-helper-prefix}-3by5 + padding-top: 166.6666% + + &.#{$view360-helper-prefix}-9by16 + padding-top: 177.7777% + + &.#{$view360-helper-prefix}-1by2 + padding-top: 200% + + &.#{$view360-helper-prefix}-1by3 + padding-top: 300% + + &:fullscreen + padding-top: 0% diff --git a/demo/release/4.0.0-beta.4/sass/hotspot.sass b/demo/release/4.0.0-beta.4/sass/hotspot.sass new file mode 100644 index 000000000..74e235d9e --- /dev/null +++ b/demo/release/4.0.0-beta.4/sass/hotspot.sass @@ -0,0 +1,20 @@ +@import variable + +.#{$view360-prefix}-hotspots + width: 100% + height: 100% + position: absolute + top: 0 + left: 0 + pointer-events: none + +.#{$view360-prefix}-hotspot + pointer-events: none + visibility: hidden + position: absolute + top: 0 + left: 0 + +.#{$view360-prefix}-hotspot-visible + visibility: visible + pointer-events: all diff --git a/demo/release/4.0.0-beta.4/sass/loading-spinner.sass b/demo/release/4.0.0-beta.4/sass/loading-spinner.sass new file mode 100644 index 000000000..89612c129 --- /dev/null +++ b/demo/release/4.0.0-beta.4/sass/loading-spinner.sass @@ -0,0 +1,34 @@ +@import variable + +.#{$view360-prefix}-spinner + position: absolute + top: 0 + left: 0 + width: 100% + height: 100% + display: flex + justify-content: center + align-items: center + background-color: rgba(0, 0, 0, 0.15) + +.#{$view360-prefix}-spinner-ring + top: 0 + left: 0 + padding: 0 + margin: 0 + width: 64px + height: 64px + box-sizing: content-box + background-color: transparent + border-style: solid + border-radius: 50% + border-width: 10px + border-color: #fff + border-bottom-color: transparent + animation: view360-spin-animation 1.2s linear infinite + +@keyframes view360-spin-animation + 0% + transform: rotate(0deg) + 100% + transform: rotate(360deg) diff --git a/demo/release/4.0.0-beta.4/sass/variable.sass b/demo/release/4.0.0-beta.4/sass/variable.sass new file mode 100644 index 000000000..9ba2beb24 --- /dev/null +++ b/demo/release/4.0.0-beta.4/sass/variable.sass @@ -0,0 +1,2 @@ +$view360-prefix: view360 !default +$view360-helper-prefix: is !default diff --git a/demo/release/4.0.0-beta.4/sass/view360.sass b/demo/release/4.0.0-beta.4/sass/view360.sass new file mode 100644 index 000000000..ae3545abe --- /dev/null +++ b/demo/release/4.0.0-beta.4/sass/view360.sass @@ -0,0 +1,6 @@ +@import 'base' +@import 'helper' +@import 'control-bar' +@import 'loading-spinner' +@import 'vr' +@import 'hotspot' diff --git a/demo/release/4.0.0-beta.4/sass/vr.sass b/demo/release/4.0.0-beta.4/sass/vr.sass new file mode 100644 index 000000000..3a1581b72 --- /dev/null +++ b/demo/release/4.0.0-beta.4/sass/vr.sass @@ -0,0 +1,10 @@ +@import variable + +.#{$view360-prefix}-container + &.#{$view360-prefix}-vr-presenting + width: 100vw + height: 100vh + position: fixed + left: 0 + top: 0 + z-index: 9999 diff --git a/demo/release/latest/css/base.css b/demo/release/latest/css/base.css new file mode 100644 index 000000000..009ab5d12 --- /dev/null +++ b/demo/release/latest/css/base.css @@ -0,0 +1,20 @@ +.view360-container { + position: relative; + touch-action: pan-y; + overflow: hidden; +} + +.view360-canvas { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + -ms-user-select: none; + user-select: none; + -webkit-user-drag: none; +} + +.view360-canvas.ctx-lost { + text-indent: 0.001px; +} diff --git a/demo/release/latest/css/base.min.css b/demo/release/latest/css/base.min.css new file mode 100644 index 000000000..0d9974270 --- /dev/null +++ b/demo/release/latest/css/base.min.css @@ -0,0 +1 @@ +.view360-container{position:relative;touch-action:pan-y;overflow:hidden}.view360-canvas{position:absolute;left:0;top:0;width:100%;height:100%;-ms-user-select:none;user-select:none;-webkit-user-drag:none}.view360-canvas.ctx-lost{text-indent:.001px} \ No newline at end of file diff --git a/demo/release/latest/css/control-bar.css b/demo/release/latest/css/control-bar.css new file mode 100644 index 000000000..7592a1a51 --- /dev/null +++ b/demo/release/latest/css/control-bar.css @@ -0,0 +1,353 @@ +.view360-controls { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + padding: 0; + margin: 0; + border: 0; + pointer-events: none; + -ms-user-select: none; + user-select: none; + -webkit-user-drag: none; + z-index: 1; +} + +.view360-main.view360-vr-presenting .view360-controls { + display: none; +} + +.view360-controls-float-left, +.view360-controls-float-right { + position: absolute; + display: flex; + flex-direction: column; +} + +.view360-controls-float-left { + left: 0px; + top: 0px; +} + +.view360-controls-float-right { + right: 0px; + top: 0px; +} + +.view360-controls-main { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + opacity: 1; + transition: none; +} + +.view360-controls-main.view360-controls-hidden { + opacity: 0; + transition: opacity 500ms; +} + +.view360-controls-main.view360-controls-hidden * { + pointer-events: none; +} + +.view360-controls-main.view360-controls-fixed { + opacity: 1; +} + +.view360-controls-background { + width: 100%; + height: calc(100% + 32px); + position: absolute; + left: 0; + bottom: 0; + background-image: linear-gradient(0deg, #323232, rgba(50, 50, 50, 0)); +} + +.view360-controls-background.view360-controls-hidden { + display: none; +} + +.view360-controls-mid { + display: flex; + flex-direction: row; + position: relative; +} + +.view360-controls-left { + display: flex; + flex: 1; + justify-content: flex-start; + align-items: center; + flex-direction: row; +} + +.view360-controls-right { + display: flex; + align-items: center; + flex-direction: row; +} + +.view360-controls-bottom { + display: flex; + align-items: center; + flex-direction: row; +} + +.view360-controls-button { + display: inline-block; + background-color: transparent; + cursor: pointer; + border: 0; + position: relative; + background-size: 24px 24px; + background-origin: content-box; + background-repeat: no-repeat; + box-sizing: border-box; + pointer-events: all; + border-radius: 20px; + transition: opacity 250ms; + width: 40px; + height: 40px; + margin: 6px; + padding: 8px; + opacity: 0.8; + /* + * Following background-image svgs are from tabler icons + * https://github.com/tabler/tabler-icons + * + * tabler icons is licensed under the MIT license + * https://github.com/tabler/tabler-icons/blob/master/LICENSE + */ + /* + * Following background-image svgs are from Google Material Icons + * https://fonts.google.com/icons + * + * Material Design Icons is licensed under the Apache License 2.0 + * https://github.com/google/material-design-icons/blob/master/LICENSE + */ +} + +.view360-controls-button:hover { + opacity: 1; +} + +.view360-controls-button.view360-controls-vr { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48' viewBox='0 0 100 100'%3E%3Cg%3E%3Cpath d='M5,30 L95,30 L95,80 L55,80 L50,70 L45,80 L5,80 L5,30' fill='transparent' stroke='%23fff' stroke-width='8' stroke-linejoin='round' stroke-linecap='round'/%3E%3Cpath d='M5,30 L15,10 L85,10 L95,30' fill='transparent' stroke='%23fff' stroke-width='8' stroke-linejoin='round' stroke-linecap='round'/%3E%3Ccircle cx='30' cy='55' r='10' stroke='%23fff' stroke-width='8' fill='transparent' /%3E%3Ccircle cx='70' cy='55' r='10' stroke='%23fff' stroke-width='8' fill='transparent' /%3E%3C/g%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-play { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M7 4v16l13 -8z'%3E%3C/path%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-pause { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Crect x='6' y='5' width='4' height='14' rx='1'%3E%3C/rect%3E%3Crect x='14' y='5' width='4' height='14' rx='1'%3E%3C/rect%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-unmuted { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M15 8a5 5 0 0 1 0 8'%3E%3C/path%3E%3Cpath d='M17.7 5a9 9 0 0 1 0 14'%3E%3C/path%3E%3Cpath d='M6 15h-2a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h2l3.5 -4.5a0.8 .8 0 0 1 1.5 .5v14a0.8 .8 0 0 1 -1.5 .5l-3.5 -4.5'%3E%3C/path%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-muted { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M6 15h-2a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h2l3.5 -4.5a0.8 .8 0 0 1 1.5 .5v14a0.8 .8 0 0 1 -1.5 .5l-3.5 -4.5'%3E%3C/path%3E%3Cpath d='M16 10l4 4m0 -4l-4 4'%3E%3C/path%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-fullscreen { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M4 8v-2a2 2 0 0 1 2 -2h2'%3E%3C/path%3E%3Cpath d='M4 16v2a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v2'%3E%3C/path%3E%3Cpath d='M16 20h2a2 2 0 0 0 2 -2v-2'%3E%3C/path%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-fullscreen-exit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M15 19v-2a2 2 0 0 1 2 -2h2'%3E%3C/path%3E%3Cpath d='M15 5v2a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3Cpath d='M5 15h2a2 2 0 0 1 2 2v2'%3E%3C/path%3E%3Cpath d='M5 9h2a2 2 0 0 0 2 -2v-2'%3E%3C/path%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-gyro-enabled { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48'%3E%3Cpath fill='%23fff' d='M22.5 7.6v2.95q-1 .15-1.975.475-.975.325-1.875.825L16.5 9.7q1.35-.9 2.875-1.4 1.525-.5 3.125-.7Zm15.35 15.35q-.2 1.6-.7 3.125-.5 1.525-1.4 2.875L33.6 26.8q.5-.9.825-1.875.325-.975.475-1.975Zm3.8 20.45L1.3 3.05 3.45.9 43.8 41.25ZM7 41.4q-1.25 0-2.125-.875T4 38.4v-8.6h3v8.6h8.6v3ZM41 13V4.4h-8.6v-3H41q1.25 0 2.125.875T44 4.4V13ZM4 13V4.4q0-.55.2-1.1t.6-1l2.1 2.1V13Zm28.4 28.4v-3h8.5l2.1 2.1q-.4.45-.925.675-.525.225-1.075.225Zm-21.2-37-3-3h7.4v3ZM44 37.2l-3-3v-4.4h3ZM10.15 22.95h2.95q.5 3.7 3.1 6.3 2.6 2.6 6.3 3.1v2.95q-4.9-.55-8.35-4-3.45-3.45-4-8.35Zm4-11.35 2.1 2.05q-1.3 1.3-2.1 2.9-.8 1.6-1.05 3.4h-2.95q.25-2.4 1.275-4.525Q12.45 13.3 14.15 11.6ZM31.8 29.2l2.05 2.1q-1.7 1.7-3.825 2.725Q27.9 35.05 25.5 35.3v-2.95q1.8-.25 3.4-1.05 1.6-.8 2.9-2.1ZM25.5 7.6q4.9.55 8.35 4 3.45 3.45 4 8.35H34.9q-.5-3.7-3.1-6.3-2.6-2.6-6.3-3.1Z'/%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-gyro-disabled { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48'%3E%3Cpath fill='%23fff' d='M7 44q-1.2 0-2.1-.9Q4 42.2 4 41v-8.6h3V41h8.6v3ZM4 15.6V7q0-1.2.9-2.1Q5.8 4 7 4h8.6v3H7v8.6Zm18.5 22.25q-4.9-.55-8.35-4-3.45-3.45-4-8.35h2.95q.5 3.7 3.125 6.3 2.625 2.6 6.275 3.1ZM10.15 22.5q.55-4.9 4-8.35 3.45-3.45 8.35-4v2.95q-3.7.5-6.3 3.1-2.6 2.6-3.1 6.3Zm13.85 5q-1.45 0-2.475-1.025Q20.5 25.45 20.5 24q0-1.45 1.025-2.475Q22.55 20.5 24 20.5q1.45 0 2.475 1.025Q27.5 22.55 27.5 24q0 1.45-1.025 2.475Q25.45 27.5 24 27.5Zm1.5 10.35V34.9q3.7-.5 6.3-3.125 2.6-2.625 3.1-6.275h2.95q-.55 4.9-4 8.35-3.45 3.45-8.35 4Zm9.4-15.35q-.5-3.7-3.1-6.3-2.6-2.6-6.3-3.1v-2.95q4.9.55 8.35 4 3.45 3.45 4 8.35ZM32.4 44v-3H41v-8.6h3V41q0 1.2-.9 2.1-.9.9-2.1.9ZM41 15.6V7h-8.6V4H41q1.2 0 2.1.9.9.9.9 2.1v8.6Z'/%3E%3C/svg%3E"); +} + +.view360-controls-time { + display: inline-block; + vertical-align: top; + white-space: nowrap; + color: white; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-weight: normal; + font-size: 14px; + z-index: 1; +} + +.view360-controls-time:first-child { + padding: 0 16px; +} + +.view360-controls-progress { + flex: 1; + width: 100%; + padding: 0 16px; + box-sizing: border-box; +} + +.view360-controls-progress:not(:first-child) { + padding-left: 0; +} + +.view360-controls-bottom .view360-controls-progress { + padding-bottom: 20px; +} + +.view360-controls-volume { + display: inline-flex; + flex-direction: row; + align-items: center; + transition: width 250ms, background-color 250ms; + overflow: hidden; +} + +.view360-controls-volume:not(:disabled):hover, .view360-controls-volume:not(:disabled).view360-controls-fixed { + width: 112px; +} + +.view360-controls-volume .view360-range { + flex: 1; + height: 100%; + padding: 0; +} + +.view360-controls-volume .view360-range .view360-range-track { + width: calc(100% - 12px); + transform: translateX(-4px); +} + +.view360-controls-volume .view360-controls-button { + margin: 0; + padding: 0; + width: 24px; + height: 24px; + flex-shrink: 0; +} + +.view360-controls-volume:disabled { + opacity: 0.5; + pointer-events: none; +} + +.view360-controls-volume:disabled * { + pointer-events: none; +} + +.view360-controls-pie { + width: 36px; + height: 36px; + margin: 6px; + padding: 0; + border-radius: 18px; + opacity: 0.8; + pointer-events: all; + cursor: pointer; + color: #fff; + position: relative; + transition: opacity 250ms; +} + +.view360-controls-pie > svg { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.view360-controls-pie:hover { + opacity: 1; +} + +.view360-range { + position: relative; + cursor: pointer; + pointer-events: all; + display: flex; + justify-content: center; + align-items: center; + touch-action: pan-y; +} + +.view360-range:hover .view360-range-thumb { + opacity: 1; +} + +.view360-range-track { + width: 100%; + height: 4px; + border-radius: 4px; + position: relative; + background-color: rgba(230, 230, 230, 0.4); +} + +.view360-range-filler, +.view360-range-load { + position: absolute; + left: 0; + top: 0; + width: 0; + height: 100%; + border-radius: 4px; +} + +.view360-range-filler { + background-color: #fff; +} + +.view360-range-load { + background-color: #757575; +} + +.view360-range-thumb { + width: 13px; + height: 13px; + position: absolute; + top: -5px; + left: -6.5px; + border-radius: 50%; + background-color: #fff; + box-sizing: border-box; + transition: opacity 250ms; + opacity: 0; +} + +.view360-range-thumb.view360-controls-fixed { + opacity: 1; +} + +.view360-controls-unavailable { + display: none !important; +} + +@media screen and (max-width: 768px) { + .view360-controls-button { + background-size: 18px 18px; + width: 30px; + height: 30px; + margin: 4.5px; + padding: 6px; + border-radius: 15px; + } + .view360-controls-volume .view360-controls-button { + width: 18px; + height: 18px; + } + .view360-controls-volume:not(:disabled):hover, .view360-controls-volume:not(:disabled).view360-controls-fixed { + width: 84px; + } + .view360-controls-pie { + width: 27px; + height: 27px; + margin: 4.5px; + padding: 0; + border-radius: 13.5px; + } +} diff --git a/demo/release/latest/css/control-bar.min.css b/demo/release/latest/css/control-bar.min.css new file mode 100644 index 000000000..fd73d81ab --- /dev/null +++ b/demo/release/latest/css/control-bar.min.css @@ -0,0 +1 @@ +.view360-controls{position:absolute;top:0;left:0;width:100%;height:100%;padding:0;margin:0;border:0;pointer-events:none;-ms-user-select:none;user-select:none;-webkit-user-drag:none;z-index:1}.view360-main.view360-vr-presenting .view360-controls{display:none}.view360-controls-float-left,.view360-controls-float-right{position:absolute;display:flex;flex-direction:column}.view360-controls-float-left{left:0;top:0}.view360-controls-float-right{right:0;top:0}.view360-controls-main{position:absolute;bottom:0;left:0;width:100%;opacity:1;transition:none}.view360-controls-main.view360-controls-hidden{opacity:0;transition:opacity .5s}.view360-controls-main.view360-controls-hidden *{pointer-events:none}.view360-controls-main.view360-controls-fixed{opacity:1}.view360-controls-background{width:100%;height:calc(100% + 32px);position:absolute;left:0;bottom:0;background-image:linear-gradient(0deg,#323232,rgba(50,50,50,0))}.view360-controls-background.view360-controls-hidden{display:none}.view360-controls-mid{display:flex;flex-direction:row;position:relative}.view360-controls-left{display:flex;flex:1;justify-content:flex-start;align-items:center;flex-direction:row}.view360-controls-right{display:flex;align-items:center;flex-direction:row}.view360-controls-bottom{display:flex;align-items:center;flex-direction:row}.view360-controls-button{display:inline-block;background-color:transparent;cursor:pointer;border:0;position:relative;background-size:24px 24px;background-origin:content-box;background-repeat:no-repeat;box-sizing:border-box;pointer-events:all;border-radius:20px;transition:opacity 250ms;width:40px;height:40px;margin:6px;padding:8px;opacity:.8}.view360-controls-button:hover{opacity:1}.view360-controls-button.view360-controls-vr{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48' viewBox='0 0 100 100'%3E%3Cg%3E%3Cpath d='M5,30 L95,30 L95,80 L55,80 L50,70 L45,80 L5,80 L5,30' fill='transparent' stroke='%23fff' stroke-width='8' stroke-linejoin='round' stroke-linecap='round'/%3E%3Cpath d='M5,30 L15,10 L85,10 L95,30' fill='transparent' stroke='%23fff' stroke-width='8' stroke-linejoin='round' stroke-linecap='round'/%3E%3Ccircle cx='30' cy='55' r='10' stroke='%23fff' stroke-width='8' fill='transparent' /%3E%3Ccircle cx='70' cy='55' r='10' stroke='%23fff' stroke-width='8' fill='transparent' /%3E%3C/g%3E%3C/svg%3E")}.view360-controls-button.view360-controls-play{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M7 4v16l13 -8z'%3E%3C/path%3E%3C/svg%3E")}.view360-controls-button.view360-controls-pause{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Crect x='6' y='5' width='4' height='14' rx='1'%3E%3C/rect%3E%3Crect x='14' y='5' width='4' height='14' rx='1'%3E%3C/rect%3E%3C/svg%3E")}.view360-controls-button.view360-controls-unmuted{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M15 8a5 5 0 0 1 0 8'%3E%3C/path%3E%3Cpath d='M17.7 5a9 9 0 0 1 0 14'%3E%3C/path%3E%3Cpath d='M6 15h-2a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h2l3.5 -4.5a0.8 .8 0 0 1 1.5 .5v14a0.8 .8 0 0 1 -1.5 .5l-3.5 -4.5'%3E%3C/path%3E%3C/svg%3E")}.view360-controls-button.view360-controls-muted{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M6 15h-2a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h2l3.5 -4.5a0.8 .8 0 0 1 1.5 .5v14a0.8 .8 0 0 1 -1.5 .5l-3.5 -4.5'%3E%3C/path%3E%3Cpath d='M16 10l4 4m0 -4l-4 4'%3E%3C/path%3E%3C/svg%3E")}.view360-controls-button.view360-controls-fullscreen{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M4 8v-2a2 2 0 0 1 2 -2h2'%3E%3C/path%3E%3Cpath d='M4 16v2a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v2'%3E%3C/path%3E%3Cpath d='M16 20h2a2 2 0 0 0 2 -2v-2'%3E%3C/path%3E%3C/svg%3E")}.view360-controls-button.view360-controls-fullscreen-exit{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M15 19v-2a2 2 0 0 1 2 -2h2'%3E%3C/path%3E%3Cpath d='M15 5v2a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3Cpath d='M5 15h2a2 2 0 0 1 2 2v2'%3E%3C/path%3E%3Cpath d='M5 9h2a2 2 0 0 0 2 -2v-2'%3E%3C/path%3E%3C/svg%3E")}.view360-controls-button.view360-controls-gyro-enabled{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48'%3E%3Cpath fill='%23fff' d='M22.5 7.6v2.95q-1 .15-1.975.475-.975.325-1.875.825L16.5 9.7q1.35-.9 2.875-1.4 1.525-.5 3.125-.7Zm15.35 15.35q-.2 1.6-.7 3.125-.5 1.525-1.4 2.875L33.6 26.8q.5-.9.825-1.875.325-.975.475-1.975Zm3.8 20.45L1.3 3.05 3.45.9 43.8 41.25ZM7 41.4q-1.25 0-2.125-.875T4 38.4v-8.6h3v8.6h8.6v3ZM41 13V4.4h-8.6v-3H41q1.25 0 2.125.875T44 4.4V13ZM4 13V4.4q0-.55.2-1.1t.6-1l2.1 2.1V13Zm28.4 28.4v-3h8.5l2.1 2.1q-.4.45-.925.675-.525.225-1.075.225Zm-21.2-37-3-3h7.4v3ZM44 37.2l-3-3v-4.4h3ZM10.15 22.95h2.95q.5 3.7 3.1 6.3 2.6 2.6 6.3 3.1v2.95q-4.9-.55-8.35-4-3.45-3.45-4-8.35Zm4-11.35 2.1 2.05q-1.3 1.3-2.1 2.9-.8 1.6-1.05 3.4h-2.95q.25-2.4 1.275-4.525Q12.45 13.3 14.15 11.6ZM31.8 29.2l2.05 2.1q-1.7 1.7-3.825 2.725Q27.9 35.05 25.5 35.3v-2.95q1.8-.25 3.4-1.05 1.6-.8 2.9-2.1ZM25.5 7.6q4.9.55 8.35 4 3.45 3.45 4 8.35H34.9q-.5-3.7-3.1-6.3-2.6-2.6-6.3-3.1Z'/%3E%3C/svg%3E")}.view360-controls-button.view360-controls-gyro-disabled{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48'%3E%3Cpath fill='%23fff' d='M7 44q-1.2 0-2.1-.9Q4 42.2 4 41v-8.6h3V41h8.6v3ZM4 15.6V7q0-1.2.9-2.1Q5.8 4 7 4h8.6v3H7v8.6Zm18.5 22.25q-4.9-.55-8.35-4-3.45-3.45-4-8.35h2.95q.5 3.7 3.125 6.3 2.625 2.6 6.275 3.1ZM10.15 22.5q.55-4.9 4-8.35 3.45-3.45 8.35-4v2.95q-3.7.5-6.3 3.1-2.6 2.6-3.1 6.3Zm13.85 5q-1.45 0-2.475-1.025Q20.5 25.45 20.5 24q0-1.45 1.025-2.475Q22.55 20.5 24 20.5q1.45 0 2.475 1.025Q27.5 22.55 27.5 24q0 1.45-1.025 2.475Q25.45 27.5 24 27.5Zm1.5 10.35V34.9q3.7-.5 6.3-3.125 2.6-2.625 3.1-6.275h2.95q-.55 4.9-4 8.35-3.45 3.45-8.35 4Zm9.4-15.35q-.5-3.7-3.1-6.3-2.6-2.6-6.3-3.1v-2.95q4.9.55 8.35 4 3.45 3.45 4 8.35ZM32.4 44v-3H41v-8.6h3V41q0 1.2-.9 2.1-.9.9-2.1.9ZM41 15.6V7h-8.6V4H41q1.2 0 2.1.9.9.9.9 2.1v8.6Z'/%3E%3C/svg%3E")}.view360-controls-time{display:inline-block;vertical-align:top;white-space:nowrap;color:#fff;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-weight:400;font-size:14px;z-index:1}.view360-controls-time:first-child{padding:0 16px}.view360-controls-progress{flex:1;width:100%;padding:0 16px;box-sizing:border-box}.view360-controls-progress:not(:first-child){padding-left:0}.view360-controls-bottom .view360-controls-progress{padding-bottom:20px}.view360-controls-volume{display:inline-flex;flex-direction:row;align-items:center;transition:width 250ms,background-color 250ms;overflow:hidden}.view360-controls-volume:not(:disabled).view360-controls-fixed,.view360-controls-volume:not(:disabled):hover{width:112px}.view360-controls-volume .view360-range{flex:1;height:100%;padding:0}.view360-controls-volume .view360-range .view360-range-track{width:calc(100% - 12px);transform:translateX(-4px)}.view360-controls-volume .view360-controls-button{margin:0;padding:0;width:24px;height:24px;flex-shrink:0}.view360-controls-volume:disabled{opacity:.5;pointer-events:none}.view360-controls-volume:disabled *{pointer-events:none}.view360-controls-pie{width:36px;height:36px;margin:6px;padding:0;border-radius:18px;opacity:.8;pointer-events:all;cursor:pointer;color:#fff;position:relative;transition:opacity 250ms}.view360-controls-pie>svg{position:absolute;top:0;left:0;width:100%;height:100%}.view360-controls-pie:hover{opacity:1}.view360-range{position:relative;cursor:pointer;pointer-events:all;display:flex;justify-content:center;align-items:center;touch-action:pan-y}.view360-range:hover .view360-range-thumb{opacity:1}.view360-range-track{width:100%;height:4px;border-radius:4px;position:relative;background-color:rgba(230,230,230,.4)}.view360-range-filler,.view360-range-load{position:absolute;left:0;top:0;width:0;height:100%;border-radius:4px}.view360-range-filler{background-color:#fff}.view360-range-load{background-color:#757575}.view360-range-thumb{width:13px;height:13px;position:absolute;top:-5px;left:-6.5px;border-radius:50%;background-color:#fff;box-sizing:border-box;transition:opacity 250ms;opacity:0}.view360-range-thumb.view360-controls-fixed{opacity:1}.view360-controls-unavailable{display:none!important}@media screen and (max-width:768px){.view360-controls-button{background-size:18px 18px;width:30px;height:30px;margin:4.5px;padding:6px;border-radius:15px}.view360-controls-volume .view360-controls-button{width:18px;height:18px}.view360-controls-volume:not(:disabled).view360-controls-fixed,.view360-controls-volume:not(:disabled):hover{width:84px}.view360-controls-pie{width:27px;height:27px;margin:4.5px;padding:0;border-radius:13.5px}} \ No newline at end of file diff --git a/demo/release/latest/css/helper.css b/demo/release/latest/css/helper.css new file mode 100644 index 000000000..66d55dac0 --- /dev/null +++ b/demo/release/latest/css/helper.css @@ -0,0 +1,67 @@ +.view360-container.is-square, .view360-container.is-1by1 { + padding-top: 100%; +} + +.view360-container.is-5by4 { + padding-top: 80%; +} + +.view360-container.is-4by3 { + padding-top: 75%; +} + +.view360-container.is-3by2 { + padding-top: 66.6666%; +} + +.view360-container.is-5by3 { + padding-top: 60%; +} + +.view360-container.is-16by9 { + padding-top: 56.25%; +} + +.view360-container.is-2by1 { + padding-top: 50%; +} + +.view360-container.is-3by1 { + padding-top: 33.3333%; +} + +.view360-container.is-4by5 { + padding-top: 125%; +} + +.view360-container.is-3by4 { + padding-top: 133.3333%; +} + +.view360-container.is-2by3 { + padding-top: 150%; +} + +.view360-container.is-3by5 { + padding-top: 166.6666%; +} + +.view360-container.is-9by16 { + padding-top: 177.7777%; +} + +.view360-container.is-1by2 { + padding-top: 200%; +} + +.view360-container.is-1by3 { + padding-top: 300%; +} + +.view360-container:-ms-fullscreen { + padding-top: 0%; +} + +.view360-container:fullscreen { + padding-top: 0%; +} diff --git a/demo/release/latest/css/helper.min.css b/demo/release/latest/css/helper.min.css new file mode 100644 index 000000000..4a2ff61eb --- /dev/null +++ b/demo/release/latest/css/helper.min.css @@ -0,0 +1 @@ +.view360-container.is-1by1,.view360-container.is-square{padding-top:100%}.view360-container.is-5by4{padding-top:80%}.view360-container.is-4by3{padding-top:75%}.view360-container.is-3by2{padding-top:66.6666%}.view360-container.is-5by3{padding-top:60%}.view360-container.is-16by9{padding-top:56.25%}.view360-container.is-2by1{padding-top:50%}.view360-container.is-3by1{padding-top:33.3333%}.view360-container.is-4by5{padding-top:125%}.view360-container.is-3by4{padding-top:133.3333%}.view360-container.is-2by3{padding-top:150%}.view360-container.is-3by5{padding-top:166.6666%}.view360-container.is-9by16{padding-top:177.7777%}.view360-container.is-1by2{padding-top:200%}.view360-container.is-1by3{padding-top:300%}.view360-container:-ms-fullscreen{padding-top:0}.view360-container:fullscreen{padding-top:0} \ No newline at end of file diff --git a/demo/release/latest/css/hotspot.css b/demo/release/latest/css/hotspot.css new file mode 100644 index 000000000..d0f07cf1e --- /dev/null +++ b/demo/release/latest/css/hotspot.css @@ -0,0 +1,21 @@ +.view360-hotspots { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + pointer-events: none; +} + +.view360-hotspot { + pointer-events: none; + visibility: hidden; + position: absolute; + top: 0; + left: 0; +} + +.view360-hotspot-visible { + visibility: visible; + pointer-events: all; +} diff --git a/demo/release/latest/css/hotspot.min.css b/demo/release/latest/css/hotspot.min.css new file mode 100644 index 000000000..e6612d921 --- /dev/null +++ b/demo/release/latest/css/hotspot.min.css @@ -0,0 +1 @@ +.view360-hotspots{width:100%;height:100%;position:absolute;top:0;left:0;pointer-events:none}.view360-hotspot{pointer-events:none;visibility:hidden;position:absolute;top:0;left:0}.view360-hotspot-visible{visibility:visible;pointer-events:all} \ No newline at end of file diff --git a/demo/release/latest/css/loading-spinner.css b/demo/release/latest/css/loading-spinner.css new file mode 100644 index 000000000..19bccd3e4 --- /dev/null +++ b/demo/release/latest/css/loading-spinner.css @@ -0,0 +1,37 @@ +.view360-spinner { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + background-color: rgba(0, 0, 0, 0.15); +} + +.view360-spinner-ring { + top: 0; + left: 0; + padding: 0; + margin: 0; + width: 64px; + height: 64px; + box-sizing: content-box; + background-color: transparent; + border-style: solid; + border-radius: 50%; + border-width: 10px; + border-color: #fff; + border-bottom-color: transparent; + animation: view360-spin-animation 1.2s linear infinite; +} + +@keyframes view360-spin-animation { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} diff --git a/demo/release/latest/css/loading-spinner.min.css b/demo/release/latest/css/loading-spinner.min.css new file mode 100644 index 000000000..fe6f71f8d --- /dev/null +++ b/demo/release/latest/css/loading-spinner.min.css @@ -0,0 +1 @@ +.view360-spinner{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;justify-content:center;align-items:center;background-color:rgba(0,0,0,.15)}.view360-spinner-ring{top:0;left:0;padding:0;margin:0;width:64px;height:64px;box-sizing:content-box;background-color:transparent;border-style:solid;border-radius:50%;border-width:10px;border-color:#fff;border-bottom-color:transparent;animation:view360-spin-animation 1.2s linear infinite}@keyframes view360-spin-animation{0%{transform:rotate(0)}100%{transform:rotate(360deg)}} \ No newline at end of file diff --git a/demo/release/latest/css/variable.css b/demo/release/latest/css/variable.css new file mode 100644 index 000000000..e69de29bb diff --git a/demo/release/latest/css/variable.min.css b/demo/release/latest/css/variable.min.css new file mode 100644 index 000000000..e69de29bb diff --git a/demo/release/latest/css/view360.css b/demo/release/latest/css/view360.css new file mode 100644 index 000000000..559344b7e --- /dev/null +++ b/demo/release/latest/css/view360.css @@ -0,0 +1,511 @@ +.view360-container { + position: relative; + touch-action: pan-y; + overflow: hidden; +} + +.view360-canvas { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + -ms-user-select: none; + user-select: none; + -webkit-user-drag: none; +} + +.view360-canvas.ctx-lost { + text-indent: 0.001px; +} + +.view360-container.is-square, .view360-container.is-1by1 { + padding-top: 100%; +} + +.view360-container.is-5by4 { + padding-top: 80%; +} + +.view360-container.is-4by3 { + padding-top: 75%; +} + +.view360-container.is-3by2 { + padding-top: 66.6666%; +} + +.view360-container.is-5by3 { + padding-top: 60%; +} + +.view360-container.is-16by9 { + padding-top: 56.25%; +} + +.view360-container.is-2by1 { + padding-top: 50%; +} + +.view360-container.is-3by1 { + padding-top: 33.3333%; +} + +.view360-container.is-4by5 { + padding-top: 125%; +} + +.view360-container.is-3by4 { + padding-top: 133.3333%; +} + +.view360-container.is-2by3 { + padding-top: 150%; +} + +.view360-container.is-3by5 { + padding-top: 166.6666%; +} + +.view360-container.is-9by16 { + padding-top: 177.7777%; +} + +.view360-container.is-1by2 { + padding-top: 200%; +} + +.view360-container.is-1by3 { + padding-top: 300%; +} + +.view360-container:-ms-fullscreen { + padding-top: 0%; +} + +.view360-container:fullscreen { + padding-top: 0%; +} + +.view360-controls { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + padding: 0; + margin: 0; + border: 0; + pointer-events: none; + -ms-user-select: none; + user-select: none; + -webkit-user-drag: none; + z-index: 1; +} + +.view360-main.view360-vr-presenting .view360-controls { + display: none; +} + +.view360-controls-float-left, +.view360-controls-float-right { + position: absolute; + display: flex; + flex-direction: column; +} + +.view360-controls-float-left { + left: 0px; + top: 0px; +} + +.view360-controls-float-right { + right: 0px; + top: 0px; +} + +.view360-controls-main { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + opacity: 1; + transition: none; +} + +.view360-controls-main.view360-controls-hidden { + opacity: 0; + transition: opacity 500ms; +} + +.view360-controls-main.view360-controls-hidden * { + pointer-events: none; +} + +.view360-controls-main.view360-controls-fixed { + opacity: 1; +} + +.view360-controls-background { + width: 100%; + height: calc(100% + 32px); + position: absolute; + left: 0; + bottom: 0; + background-image: linear-gradient(0deg, #323232, rgba(50, 50, 50, 0)); +} + +.view360-controls-background.view360-controls-hidden { + display: none; +} + +.view360-controls-mid { + display: flex; + flex-direction: row; + position: relative; +} + +.view360-controls-left { + display: flex; + flex: 1; + justify-content: flex-start; + align-items: center; + flex-direction: row; +} + +.view360-controls-right { + display: flex; + align-items: center; + flex-direction: row; +} + +.view360-controls-bottom { + display: flex; + align-items: center; + flex-direction: row; +} + +.view360-controls-button { + display: inline-block; + background-color: transparent; + cursor: pointer; + border: 0; + position: relative; + background-size: 24px 24px; + background-origin: content-box; + background-repeat: no-repeat; + box-sizing: border-box; + pointer-events: all; + border-radius: 20px; + transition: opacity 250ms; + width: 40px; + height: 40px; + margin: 6px; + padding: 8px; + opacity: 0.8; + /* + * Following background-image svgs are from tabler icons + * https://github.com/tabler/tabler-icons + * + * tabler icons is licensed under the MIT license + * https://github.com/tabler/tabler-icons/blob/master/LICENSE + */ + /* + * Following background-image svgs are from Google Material Icons + * https://fonts.google.com/icons + * + * Material Design Icons is licensed under the Apache License 2.0 + * https://github.com/google/material-design-icons/blob/master/LICENSE + */ +} + +.view360-controls-button:hover { + opacity: 1; +} + +.view360-controls-button.view360-controls-vr { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48' viewBox='0 0 100 100'%3E%3Cg%3E%3Cpath d='M5,30 L95,30 L95,80 L55,80 L50,70 L45,80 L5,80 L5,30' fill='transparent' stroke='%23fff' stroke-width='8' stroke-linejoin='round' stroke-linecap='round'/%3E%3Cpath d='M5,30 L15,10 L85,10 L95,30' fill='transparent' stroke='%23fff' stroke-width='8' stroke-linejoin='round' stroke-linecap='round'/%3E%3Ccircle cx='30' cy='55' r='10' stroke='%23fff' stroke-width='8' fill='transparent' /%3E%3Ccircle cx='70' cy='55' r='10' stroke='%23fff' stroke-width='8' fill='transparent' /%3E%3C/g%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-play { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M7 4v16l13 -8z'%3E%3C/path%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-pause { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Crect x='6' y='5' width='4' height='14' rx='1'%3E%3C/rect%3E%3Crect x='14' y='5' width='4' height='14' rx='1'%3E%3C/rect%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-unmuted { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M15 8a5 5 0 0 1 0 8'%3E%3C/path%3E%3Cpath d='M17.7 5a9 9 0 0 1 0 14'%3E%3C/path%3E%3Cpath d='M6 15h-2a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h2l3.5 -4.5a0.8 .8 0 0 1 1.5 .5v14a0.8 .8 0 0 1 -1.5 .5l-3.5 -4.5'%3E%3C/path%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-muted { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M6 15h-2a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h2l3.5 -4.5a0.8 .8 0 0 1 1.5 .5v14a0.8 .8 0 0 1 -1.5 .5l-3.5 -4.5'%3E%3C/path%3E%3Cpath d='M16 10l4 4m0 -4l-4 4'%3E%3C/path%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-fullscreen { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M4 8v-2a2 2 0 0 1 2 -2h2'%3E%3C/path%3E%3Cpath d='M4 16v2a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v2'%3E%3C/path%3E%3Cpath d='M16 20h2a2 2 0 0 0 2 -2v-2'%3E%3C/path%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-fullscreen-exit { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M15 19v-2a2 2 0 0 1 2 -2h2'%3E%3C/path%3E%3Cpath d='M15 5v2a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3Cpath d='M5 15h2a2 2 0 0 1 2 2v2'%3E%3C/path%3E%3Cpath d='M5 9h2a2 2 0 0 0 2 -2v-2'%3E%3C/path%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-gyro-enabled { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48'%3E%3Cpath fill='%23fff' d='M22.5 7.6v2.95q-1 .15-1.975.475-.975.325-1.875.825L16.5 9.7q1.35-.9 2.875-1.4 1.525-.5 3.125-.7Zm15.35 15.35q-.2 1.6-.7 3.125-.5 1.525-1.4 2.875L33.6 26.8q.5-.9.825-1.875.325-.975.475-1.975Zm3.8 20.45L1.3 3.05 3.45.9 43.8 41.25ZM7 41.4q-1.25 0-2.125-.875T4 38.4v-8.6h3v8.6h8.6v3ZM41 13V4.4h-8.6v-3H41q1.25 0 2.125.875T44 4.4V13ZM4 13V4.4q0-.55.2-1.1t.6-1l2.1 2.1V13Zm28.4 28.4v-3h8.5l2.1 2.1q-.4.45-.925.675-.525.225-1.075.225Zm-21.2-37-3-3h7.4v3ZM44 37.2l-3-3v-4.4h3ZM10.15 22.95h2.95q.5 3.7 3.1 6.3 2.6 2.6 6.3 3.1v2.95q-4.9-.55-8.35-4-3.45-3.45-4-8.35Zm4-11.35 2.1 2.05q-1.3 1.3-2.1 2.9-.8 1.6-1.05 3.4h-2.95q.25-2.4 1.275-4.525Q12.45 13.3 14.15 11.6ZM31.8 29.2l2.05 2.1q-1.7 1.7-3.825 2.725Q27.9 35.05 25.5 35.3v-2.95q1.8-.25 3.4-1.05 1.6-.8 2.9-2.1ZM25.5 7.6q4.9.55 8.35 4 3.45 3.45 4 8.35H34.9q-.5-3.7-3.1-6.3-2.6-2.6-6.3-3.1Z'/%3E%3C/svg%3E"); +} + +.view360-controls-button.view360-controls-gyro-disabled { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48'%3E%3Cpath fill='%23fff' d='M7 44q-1.2 0-2.1-.9Q4 42.2 4 41v-8.6h3V41h8.6v3ZM4 15.6V7q0-1.2.9-2.1Q5.8 4 7 4h8.6v3H7v8.6Zm18.5 22.25q-4.9-.55-8.35-4-3.45-3.45-4-8.35h2.95q.5 3.7 3.125 6.3 2.625 2.6 6.275 3.1ZM10.15 22.5q.55-4.9 4-8.35 3.45-3.45 8.35-4v2.95q-3.7.5-6.3 3.1-2.6 2.6-3.1 6.3Zm13.85 5q-1.45 0-2.475-1.025Q20.5 25.45 20.5 24q0-1.45 1.025-2.475Q22.55 20.5 24 20.5q1.45 0 2.475 1.025Q27.5 22.55 27.5 24q0 1.45-1.025 2.475Q25.45 27.5 24 27.5Zm1.5 10.35V34.9q3.7-.5 6.3-3.125 2.6-2.625 3.1-6.275h2.95q-.55 4.9-4 8.35-3.45 3.45-8.35 4Zm9.4-15.35q-.5-3.7-3.1-6.3-2.6-2.6-6.3-3.1v-2.95q4.9.55 8.35 4 3.45 3.45 4 8.35ZM32.4 44v-3H41v-8.6h3V41q0 1.2-.9 2.1-.9.9-2.1.9ZM41 15.6V7h-8.6V4H41q1.2 0 2.1.9.9.9.9 2.1v8.6Z'/%3E%3C/svg%3E"); +} + +.view360-controls-time { + display: inline-block; + vertical-align: top; + white-space: nowrap; + color: white; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-weight: normal; + font-size: 14px; + z-index: 1; +} + +.view360-controls-time:first-child { + padding: 0 16px; +} + +.view360-controls-progress { + flex: 1; + width: 100%; + padding: 0 16px; + box-sizing: border-box; +} + +.view360-controls-progress:not(:first-child) { + padding-left: 0; +} + +.view360-controls-bottom .view360-controls-progress { + padding-bottom: 20px; +} + +.view360-controls-volume { + display: inline-flex; + flex-direction: row; + align-items: center; + transition: width 250ms, background-color 250ms; + overflow: hidden; +} + +.view360-controls-volume:not(:disabled):hover, .view360-controls-volume:not(:disabled).view360-controls-fixed { + width: 112px; +} + +.view360-controls-volume .view360-range { + flex: 1; + height: 100%; + padding: 0; +} + +.view360-controls-volume .view360-range .view360-range-track { + width: calc(100% - 12px); + transform: translateX(-4px); +} + +.view360-controls-volume .view360-controls-button { + margin: 0; + padding: 0; + width: 24px; + height: 24px; + flex-shrink: 0; +} + +.view360-controls-volume:disabled { + opacity: 0.5; + pointer-events: none; +} + +.view360-controls-volume:disabled * { + pointer-events: none; +} + +.view360-controls-pie { + width: 36px; + height: 36px; + margin: 6px; + padding: 0; + border-radius: 18px; + opacity: 0.8; + pointer-events: all; + cursor: pointer; + color: #fff; + position: relative; + transition: opacity 250ms; +} + +.view360-controls-pie > svg { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.view360-controls-pie:hover { + opacity: 1; +} + +.view360-range { + position: relative; + cursor: pointer; + pointer-events: all; + display: flex; + justify-content: center; + align-items: center; + touch-action: pan-y; +} + +.view360-range:hover .view360-range-thumb { + opacity: 1; +} + +.view360-range-track { + width: 100%; + height: 4px; + border-radius: 4px; + position: relative; + background-color: rgba(230, 230, 230, 0.4); +} + +.view360-range-filler, +.view360-range-load { + position: absolute; + left: 0; + top: 0; + width: 0; + height: 100%; + border-radius: 4px; +} + +.view360-range-filler { + background-color: #fff; +} + +.view360-range-load { + background-color: #757575; +} + +.view360-range-thumb { + width: 13px; + height: 13px; + position: absolute; + top: -5px; + left: -6.5px; + border-radius: 50%; + background-color: #fff; + box-sizing: border-box; + transition: opacity 250ms; + opacity: 0; +} + +.view360-range-thumb.view360-controls-fixed { + opacity: 1; +} + +.view360-controls-unavailable { + display: none !important; +} + +@media screen and (max-width: 768px) { + .view360-controls-button { + background-size: 18px 18px; + width: 30px; + height: 30px; + margin: 4.5px; + padding: 6px; + border-radius: 15px; + } + .view360-controls-volume .view360-controls-button { + width: 18px; + height: 18px; + } + .view360-controls-volume:not(:disabled):hover, .view360-controls-volume:not(:disabled).view360-controls-fixed { + width: 84px; + } + .view360-controls-pie { + width: 27px; + height: 27px; + margin: 4.5px; + padding: 0; + border-radius: 13.5px; + } +} + +.view360-spinner { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + background-color: rgba(0, 0, 0, 0.15); +} + +.view360-spinner-ring { + top: 0; + left: 0; + padding: 0; + margin: 0; + width: 64px; + height: 64px; + box-sizing: content-box; + background-color: transparent; + border-style: solid; + border-radius: 50%; + border-width: 10px; + border-color: #fff; + border-bottom-color: transparent; + animation: view360-spin-animation 1.2s linear infinite; +} + +@keyframes view360-spin-animation { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} + +.view360-container.view360-vr-presenting { + width: 100vw; + height: 100vh; + position: fixed; + left: 0; + top: 0; + z-index: 9999; +} + +.view360-hotspots { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + pointer-events: none; +} + +.view360-hotspot { + pointer-events: none; + visibility: hidden; + position: absolute; + top: 0; + left: 0; +} + +.view360-hotspot-visible { + visibility: visible; + pointer-events: all; +} diff --git a/demo/release/latest/css/view360.min.css b/demo/release/latest/css/view360.min.css new file mode 100644 index 000000000..0f3bb2112 --- /dev/null +++ b/demo/release/latest/css/view360.min.css @@ -0,0 +1 @@ +.view360-container{position:relative;touch-action:pan-y;overflow:hidden}.view360-canvas{position:absolute;left:0;top:0;width:100%;height:100%;-ms-user-select:none;user-select:none;-webkit-user-drag:none}.view360-canvas.ctx-lost{text-indent:.001px}.view360-container.is-1by1,.view360-container.is-square{padding-top:100%}.view360-container.is-5by4{padding-top:80%}.view360-container.is-4by3{padding-top:75%}.view360-container.is-3by2{padding-top:66.6666%}.view360-container.is-5by3{padding-top:60%}.view360-container.is-16by9{padding-top:56.25%}.view360-container.is-2by1{padding-top:50%}.view360-container.is-3by1{padding-top:33.3333%}.view360-container.is-4by5{padding-top:125%}.view360-container.is-3by4{padding-top:133.3333%}.view360-container.is-2by3{padding-top:150%}.view360-container.is-3by5{padding-top:166.6666%}.view360-container.is-9by16{padding-top:177.7777%}.view360-container.is-1by2{padding-top:200%}.view360-container.is-1by3{padding-top:300%}.view360-container:-ms-fullscreen{padding-top:0}.view360-container:fullscreen{padding-top:0}.view360-controls{position:absolute;top:0;left:0;width:100%;height:100%;padding:0;margin:0;border:0;pointer-events:none;-ms-user-select:none;user-select:none;-webkit-user-drag:none;z-index:1}.view360-main.view360-vr-presenting .view360-controls{display:none}.view360-controls-float-left,.view360-controls-float-right{position:absolute;display:flex;flex-direction:column}.view360-controls-float-left{left:0;top:0}.view360-controls-float-right{right:0;top:0}.view360-controls-main{position:absolute;bottom:0;left:0;width:100%;opacity:1;transition:none}.view360-controls-main.view360-controls-hidden{opacity:0;transition:opacity .5s}.view360-controls-main.view360-controls-hidden *{pointer-events:none}.view360-controls-main.view360-controls-fixed{opacity:1}.view360-controls-background{width:100%;height:calc(100% + 32px);position:absolute;left:0;bottom:0;background-image:linear-gradient(0deg,#323232,rgba(50,50,50,0))}.view360-controls-background.view360-controls-hidden{display:none}.view360-controls-mid{display:flex;flex-direction:row;position:relative}.view360-controls-left{display:flex;flex:1;justify-content:flex-start;align-items:center;flex-direction:row}.view360-controls-right{display:flex;align-items:center;flex-direction:row}.view360-controls-bottom{display:flex;align-items:center;flex-direction:row}.view360-controls-button{display:inline-block;background-color:transparent;cursor:pointer;border:0;position:relative;background-size:24px 24px;background-origin:content-box;background-repeat:no-repeat;box-sizing:border-box;pointer-events:all;border-radius:20px;transition:opacity 250ms;width:40px;height:40px;margin:6px;padding:8px;opacity:.8}.view360-controls-button:hover{opacity:1}.view360-controls-button.view360-controls-vr{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48' viewBox='0 0 100 100'%3E%3Cg%3E%3Cpath d='M5,30 L95,30 L95,80 L55,80 L50,70 L45,80 L5,80 L5,30' fill='transparent' stroke='%23fff' stroke-width='8' stroke-linejoin='round' stroke-linecap='round'/%3E%3Cpath d='M5,30 L15,10 L85,10 L95,30' fill='transparent' stroke='%23fff' stroke-width='8' stroke-linejoin='round' stroke-linecap='round'/%3E%3Ccircle cx='30' cy='55' r='10' stroke='%23fff' stroke-width='8' fill='transparent' /%3E%3Ccircle cx='70' cy='55' r='10' stroke='%23fff' stroke-width='8' fill='transparent' /%3E%3C/g%3E%3C/svg%3E")}.view360-controls-button.view360-controls-play{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M7 4v16l13 -8z'%3E%3C/path%3E%3C/svg%3E")}.view360-controls-button.view360-controls-pause{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Crect x='6' y='5' width='4' height='14' rx='1'%3E%3C/rect%3E%3Crect x='14' y='5' width='4' height='14' rx='1'%3E%3C/rect%3E%3C/svg%3E")}.view360-controls-button.view360-controls-unmuted{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M15 8a5 5 0 0 1 0 8'%3E%3C/path%3E%3Cpath d='M17.7 5a9 9 0 0 1 0 14'%3E%3C/path%3E%3Cpath d='M6 15h-2a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h2l3.5 -4.5a0.8 .8 0 0 1 1.5 .5v14a0.8 .8 0 0 1 -1.5 .5l-3.5 -4.5'%3E%3C/path%3E%3C/svg%3E")}.view360-controls-button.view360-controls-muted{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M6 15h-2a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h2l3.5 -4.5a0.8 .8 0 0 1 1.5 .5v14a0.8 .8 0 0 1 -1.5 .5l-3.5 -4.5'%3E%3C/path%3E%3Cpath d='M16 10l4 4m0 -4l-4 4'%3E%3C/path%3E%3C/svg%3E")}.view360-controls-button.view360-controls-fullscreen{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M4 8v-2a2 2 0 0 1 2 -2h2'%3E%3C/path%3E%3Cpath d='M4 16v2a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v2'%3E%3C/path%3E%3Cpath d='M16 20h2a2 2 0 0 0 2 -2v-2'%3E%3C/path%3E%3C/svg%3E")}.view360-controls-button.view360-controls-fullscreen-exit{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M15 19v-2a2 2 0 0 1 2 -2h2'%3E%3C/path%3E%3Cpath d='M15 5v2a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3Cpath d='M5 15h2a2 2 0 0 1 2 2v2'%3E%3C/path%3E%3Cpath d='M5 9h2a2 2 0 0 0 2 -2v-2'%3E%3C/path%3E%3C/svg%3E")}.view360-controls-button.view360-controls-gyro-enabled{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48'%3E%3Cpath fill='%23fff' d='M22.5 7.6v2.95q-1 .15-1.975.475-.975.325-1.875.825L16.5 9.7q1.35-.9 2.875-1.4 1.525-.5 3.125-.7Zm15.35 15.35q-.2 1.6-.7 3.125-.5 1.525-1.4 2.875L33.6 26.8q.5-.9.825-1.875.325-.975.475-1.975Zm3.8 20.45L1.3 3.05 3.45.9 43.8 41.25ZM7 41.4q-1.25 0-2.125-.875T4 38.4v-8.6h3v8.6h8.6v3ZM41 13V4.4h-8.6v-3H41q1.25 0 2.125.875T44 4.4V13ZM4 13V4.4q0-.55.2-1.1t.6-1l2.1 2.1V13Zm28.4 28.4v-3h8.5l2.1 2.1q-.4.45-.925.675-.525.225-1.075.225Zm-21.2-37-3-3h7.4v3ZM44 37.2l-3-3v-4.4h3ZM10.15 22.95h2.95q.5 3.7 3.1 6.3 2.6 2.6 6.3 3.1v2.95q-4.9-.55-8.35-4-3.45-3.45-4-8.35Zm4-11.35 2.1 2.05q-1.3 1.3-2.1 2.9-.8 1.6-1.05 3.4h-2.95q.25-2.4 1.275-4.525Q12.45 13.3 14.15 11.6ZM31.8 29.2l2.05 2.1q-1.7 1.7-3.825 2.725Q27.9 35.05 25.5 35.3v-2.95q1.8-.25 3.4-1.05 1.6-.8 2.9-2.1ZM25.5 7.6q4.9.55 8.35 4 3.45 3.45 4 8.35H34.9q-.5-3.7-3.1-6.3-2.6-2.6-6.3-3.1Z'/%3E%3C/svg%3E")}.view360-controls-button.view360-controls-gyro-disabled{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48'%3E%3Cpath fill='%23fff' d='M7 44q-1.2 0-2.1-.9Q4 42.2 4 41v-8.6h3V41h8.6v3ZM4 15.6V7q0-1.2.9-2.1Q5.8 4 7 4h8.6v3H7v8.6Zm18.5 22.25q-4.9-.55-8.35-4-3.45-3.45-4-8.35h2.95q.5 3.7 3.125 6.3 2.625 2.6 6.275 3.1ZM10.15 22.5q.55-4.9 4-8.35 3.45-3.45 8.35-4v2.95q-3.7.5-6.3 3.1-2.6 2.6-3.1 6.3Zm13.85 5q-1.45 0-2.475-1.025Q20.5 25.45 20.5 24q0-1.45 1.025-2.475Q22.55 20.5 24 20.5q1.45 0 2.475 1.025Q27.5 22.55 27.5 24q0 1.45-1.025 2.475Q25.45 27.5 24 27.5Zm1.5 10.35V34.9q3.7-.5 6.3-3.125 2.6-2.625 3.1-6.275h2.95q-.55 4.9-4 8.35-3.45 3.45-8.35 4Zm9.4-15.35q-.5-3.7-3.1-6.3-2.6-2.6-6.3-3.1v-2.95q4.9.55 8.35 4 3.45 3.45 4 8.35ZM32.4 44v-3H41v-8.6h3V41q0 1.2-.9 2.1-.9.9-2.1.9ZM41 15.6V7h-8.6V4H41q1.2 0 2.1.9.9.9.9 2.1v8.6Z'/%3E%3C/svg%3E")}.view360-controls-time{display:inline-block;vertical-align:top;white-space:nowrap;color:#fff;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-weight:400;font-size:14px;z-index:1}.view360-controls-time:first-child{padding:0 16px}.view360-controls-progress{flex:1;width:100%;padding:0 16px;box-sizing:border-box}.view360-controls-progress:not(:first-child){padding-left:0}.view360-controls-bottom .view360-controls-progress{padding-bottom:20px}.view360-controls-volume{display:inline-flex;flex-direction:row;align-items:center;transition:width 250ms,background-color 250ms;overflow:hidden}.view360-controls-volume:not(:disabled).view360-controls-fixed,.view360-controls-volume:not(:disabled):hover{width:112px}.view360-controls-volume .view360-range{flex:1;height:100%;padding:0}.view360-controls-volume .view360-range .view360-range-track{width:calc(100% - 12px);transform:translateX(-4px)}.view360-controls-volume .view360-controls-button{margin:0;padding:0;width:24px;height:24px;flex-shrink:0}.view360-controls-volume:disabled{opacity:.5;pointer-events:none}.view360-controls-volume:disabled *{pointer-events:none}.view360-controls-pie{width:36px;height:36px;margin:6px;padding:0;border-radius:18px;opacity:.8;pointer-events:all;cursor:pointer;color:#fff;position:relative;transition:opacity 250ms}.view360-controls-pie>svg{position:absolute;top:0;left:0;width:100%;height:100%}.view360-controls-pie:hover{opacity:1}.view360-range{position:relative;cursor:pointer;pointer-events:all;display:flex;justify-content:center;align-items:center;touch-action:pan-y}.view360-range:hover .view360-range-thumb{opacity:1}.view360-range-track{width:100%;height:4px;border-radius:4px;position:relative;background-color:rgba(230,230,230,.4)}.view360-range-filler,.view360-range-load{position:absolute;left:0;top:0;width:0;height:100%;border-radius:4px}.view360-range-filler{background-color:#fff}.view360-range-load{background-color:#757575}.view360-range-thumb{width:13px;height:13px;position:absolute;top:-5px;left:-6.5px;border-radius:50%;background-color:#fff;box-sizing:border-box;transition:opacity 250ms;opacity:0}.view360-range-thumb.view360-controls-fixed{opacity:1}.view360-controls-unavailable{display:none!important}@media screen and (max-width:768px){.view360-controls-button{background-size:18px 18px;width:30px;height:30px;margin:4.5px;padding:6px;border-radius:15px}.view360-controls-volume .view360-controls-button{width:18px;height:18px}.view360-controls-volume:not(:disabled).view360-controls-fixed,.view360-controls-volume:not(:disabled):hover{width:84px}.view360-controls-pie{width:27px;height:27px;margin:4.5px;padding:0;border-radius:13.5px}}.view360-spinner{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;justify-content:center;align-items:center;background-color:rgba(0,0,0,.15)}.view360-spinner-ring{top:0;left:0;padding:0;margin:0;width:64px;height:64px;box-sizing:content-box;background-color:transparent;border-style:solid;border-radius:50%;border-width:10px;border-color:#fff;border-bottom-color:transparent;animation:view360-spin-animation 1.2s linear infinite}@keyframes view360-spin-animation{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.view360-container.view360-vr-presenting{width:100vw;height:100vh;position:fixed;left:0;top:0;z-index:9999}.view360-hotspots{width:100%;height:100%;position:absolute;top:0;left:0;pointer-events:none}.view360-hotspot{pointer-events:none;visibility:hidden;position:absolute;top:0;left:0}.view360-hotspot-visible{visibility:visible;pointer-events:all} \ No newline at end of file diff --git a/demo/release/latest/css/vr.css b/demo/release/latest/css/vr.css new file mode 100644 index 000000000..dd06d3eeb --- /dev/null +++ b/demo/release/latest/css/vr.css @@ -0,0 +1,8 @@ +.view360-container.view360-vr-presenting { + width: 100vw; + height: 100vh; + position: fixed; + left: 0; + top: 0; + z-index: 9999; +} diff --git a/demo/release/latest/css/vr.min.css b/demo/release/latest/css/vr.min.css new file mode 100644 index 000000000..a5d6c06b9 --- /dev/null +++ b/demo/release/latest/css/vr.min.css @@ -0,0 +1 @@ +.view360-container.view360-vr-presenting{width:100vw;height:100vh;position:fixed;left:0;top:0;z-index:9999} \ No newline at end of file diff --git a/demo/release/latest/dist/view360.esm.js b/demo/release/latest/dist/view360.esm.js new file mode 100644 index 000000000..8c80a5553 --- /dev/null +++ b/demo/release/latest/dist/view360.esm.js @@ -0,0 +1,7752 @@ +/* +Copyright (c) 2023-present NAVER Corp. +name: @egjs/view360 +license: MIT +author: NAVER Corp. +repository: https://github.com/naver/egjs-view360 +version: 4.0.0-beta.4 +*/ +import Component from '@egjs/component'; +import { quat, vec3, mat4, vec2 } from 'gl-matrix'; +import ImReady from '@egjs/imready'; + +/****************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function (resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Error thrown by {@link View360} + * @ko {@link View360}이 발생시킨 에러 + * @since 4.0.0 + */ +class View360Error extends Error { + /** + * Create new instance of View360Error + * @ko View360Error의 인스턴스를 생성합니다. + * @param message - Error message {@ko 에러 메시지} + * @param code - Error code {@ko 에러 코드} + */ + constructor(message, code) { + super(message); + Object.setPrototypeOf(this, View360Error.prototype); + this.name = "View360Error"; + this.code = code; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Error codes of {@link View360Error} + * @ko {@link View360Error}가 가질 수 있는 에러 코드 값들 + * @since 4.0.0 + */ +const ERROR_CODES = { + /** + * The given value's type is not expected + * @ko 주어진 값의 타입이 잘못되었을 경우 + * @since 4.0.0 + */ + WRONG_TYPE: 0, + /** + * The given value is not a supported option + * @ko 잘못된 옵션을 받았을 경우 + * @since 4.0.0 + */ + WRONG_OPTION: 1, + /** + * The element with given CSS selector does not exist + * @ko 주어진 CSS 셀렉터로 엘리먼트를 찾지 못했을 경우 + * @since 4.0.0 + */ + ELEMENT_NOT_FOUND: 2, + /** + * Couldn't find canvas element inside the given container element. + * @ko 컨테이너 엘리먼트 내부에서 캔버스 엘리먼트를 찾지 못했을 경우 + * @since 4.0.0 + */ + CANVAS_NOT_FOUND: 3, + /** + * The browser does not support WebGL + * @ko 브라우저가 WebGL을 지원하지 않는 경우 + * @since 4.0.0 + */ + WEBGL_NOT_SUPPORTED: 4, + /** + * Failed creating canvas 2D context + * @ko 캔버스 2D 컨텍스트를 생성하지 못한 경우 + * @since 4.0.0 + */ + FAILED_CREATE_CONTEXT_2D: 5, + /** + * `init()` is called before setting {@link View360Options#projection} + * @ko {@link View360Options#projection}을 설정하기 전에 `init()`이 호출된 경우 + * @since 4.0.0 + */ + PROVIDE_PROJECTION_FIRST: 6, + /** + * Failed linking WebGL program. Only can be thrown when {@link View360Options#debug} is `true`. + * @ko WebGL 프로그램 링크에 실패한 경우. {@link View360Options#debug}를 `true`로 설정한 경우에만 발생할 수 있습니다. + * @since 4.0.0 + */ + FAILED_LINKING_PROGRAM: 7, + /** + * Arguments are not sufficient for the given property. + * @ko 프로퍼티에 값이 충분히 주어지지 않았을 때 + * @since 4.0.0 + */ + INSUFFICIENT_ARGS: 8 +}; +const MESSAGES = { + WRONG_TYPE: (val, types) => `${typeof val} is not a ${types.map(type => `"${type}"`).join(" or ")}.`, + WRONG_OPTION: (val, optionName) => `Bad option: given "${val}" for option "${optionName}".`, + ELEMENT_NOT_FOUND: query => `Element with selector "${query}" not found.`, + CANVAS_NOT_FOUND: "The canvas element was not found inside the given root element.", + WEBGL_NOT_SUPPORTED: "WebGL is not supported on this browser.", + FAILED_CREATE_CONTEXT_2D: "Failed to create canvas 2D context", + PROVIDE_PROJECTION_FIRST: "\"projection\" should be provided before initialization.", + FAILED_LINKING_PROGRAM: (msg, shaderLog) => `Failed linking WebGL program - "${msg}\nShader compile Log: ${shaderLog}`, + INSUFFICIENT_ARGS: (val, name) => `Insufficient arguments: given "${val}" for "${name}".` +}; +var ERROR = { + CODES: ERROR_CODES, + MESSAGES +}; + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +const EVENTS$1 = { + MOUSE_DOWN: "mousedown", + MOUSE_MOVE: "mousemove", + MOUSE_UP: "mouseup", + TOUCH_START: "touchstart", + TOUCH_MOVE: "touchmove", + TOUCH_END: "touchend", + WHEEL: "wheel", + RESIZE: "resize", + CONTEXT_MENU: "contextmenu", + MOUSE_ENTER: "mouseenter", + MOUSE_LEAVE: "mouseleave", + POINTER_DOWN: "pointerdown", + POINTER_MOVE: "pointermove", + POINTER_UP: "pointerup", + POINTER_CANCEL: "pointercancel", + POINTER_ENTER: "pointerenter", + POINTER_LEAVE: "pointerleave", + KEY_DOWN: "keydown", + KEY_UP: "keyup", + LOAD: "load", + ERROR: "error", + CLICK: "click", + DOUBLE_CLICK: "dblclick", + CONTEXT_CREATE_ERROR: "webglcontextcreationerror", + CONTEXT_LOST: "webglcontextlost", + CONTEXT_RESTORED: "webglcontextrestored", + DEVICE_ORIENTATION: "deviceorientation", + DEVICE_MOTION: "devicemotion", + ORIENTATION_CHANGE: "orientationchange", + VIDEO_PLAY: "play", + VIDEO_PAUSE: "pause", + VIDEO_LOADED_DATA: "loadeddata", + VIDEO_VOLUME_CHANGE: "volumechange", + VIDEO_TIME_UPDATE: "timeupdate", + VIDEO_DURATION_CHANGE: "durationchange", + VIDEO_CAN_PLAYTHROUGH: "canplaythrough", + TRANSITION_END: "transitionend", + XR_END: "end" +}; +const EL_DIV = "div"; +const EL_BUTTON = "button"; +// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button +var MOUSE_BUTTON; +(function (MOUSE_BUTTON) { + MOUSE_BUTTON[MOUSE_BUTTON["LEFT"] = 0] = "LEFT"; + MOUSE_BUTTON[MOUSE_BUTTON["MIDDLE"] = 1] = "MIDDLE"; + MOUSE_BUTTON[MOUSE_BUTTON["RIGHT"] = 2] = "RIGHT"; +})(MOUSE_BUTTON || (MOUSE_BUTTON = {})); +const CURSOR = { + GRAB: "grab", + GRABBING: "grabbing", + NONE: "" +}; +const KEY_DIRECTION = ["LEFT", "UP", "RIGHT", "DOWN"]; +var DIRECTION_KEY_CODE; +(function (DIRECTION_KEY_CODE) { + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["LEFT"] = 37] = "LEFT"; + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["UP"] = 38] = "UP"; + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["RIGHT"] = 39] = "RIGHT"; + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["DOWN"] = 40] = "DOWN"; +})(DIRECTION_KEY_CODE || (DIRECTION_KEY_CODE = {})); +const SPACE_KEY_CODE = 32; +const DIRECTION_KEY_NAME = { + LEFT: "ArrowLeft", + UP: "ArrowUp", + RIGHT: "ArrowRight", + DOWN: "ArrowDown" +}; +const SPACE_KEY_NAME = " "; +const FULLSCREEN_REQUEST = ["requestFullscreen", "webkitRequestFullscreen", "webkitRequestFullScreen", "webkitCancelFullScreen", "mozRequestFullScreen", "msRequestFullscreen"]; +const FULLSCREEN_ELEMENT = ["fullscreenElement", "webkitFullscreenElement", "webkitCurrentFullScreenElement", "mozFullScreenElement", "msFullscreenElement"]; +const FULLSCREEN_EXIT = ["exitFullscreen", "webkitExitFullscreen", "webkitCancelFullScreen", "mozCancelFullScreen", "msExitFullscreen"]; +const FULLSCREEN_CHANGE = ["fullscreenchange", "webkitfullscreenchange", "mozfullscreenchange", "MSFullscreenChange"]; + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Default class names + * @ko 기본 클래스 이름들 + * @since 4.0.0 + */ +const DEFAULT_CLASS = { + CONTAINER: "view360-container", + CANVAS: "view360-canvas", + CTX_LOST: "view360-ctx-lost", + IN_VR: "view360-vr-presenting", + HOTSPOT_CONTAINER: "view360-hotspots", + HOTSPOT: "view360-hotspot", + HOTSPOT_VISIBLE: "view360-hotspot-visible", + HOTSPOT_FLIP_X: "view360-hotspot-flip-x", + HOTSPOT_FLIP_Y: "view360-hotspot-flip-y" +}; +/** + * Event names + * @ko 이벤트 이름들 + * @since 4.0.0 + * @example + * ```ts + * import View360, { EVENTS } from "@egjs/view360"; + * + * const viewer = new View360("#el_id"); + * + * viewer.on(EVENTS.READY, evt => { + * console.log("View360 is ready!"); + * }); + * ``` + */ +const EVENTS = { + READY: "ready", + LOAD_START: "loadStart", + LOAD: "load", + PROJECTION_CHANGE: "projectionChange", + RESIZE: "resize", + BEFORE_RENDER: "beforeRender", + RENDER: "render", + INPUT_START: "inputStart", + INPUT_END: "inputEnd", + VIEW_CHANGE: "viewChange", + STATIC_CLICK: "staticClick", + VR_START: "vrStart", + VR_END: "vrEnd" +}; +/** + * Collection of predefined easing functions + * @ko 미리 정의된 easing 함수들 + */ +const EASING = { + LINEAR: x => x, + SINE_WAVE: x => Math.sin(x * Math.PI * 2), + EASE_OUT_CUBIC: x => 1 - Math.pow(1 - x, 3), + EASE_OUT_BOUNCE: x => { + const n1 = 7.5625; + const d1 = 2.75; + if (x < 1 / d1) { + return n1 * x * x; + } else if (x < 2 / d1) { + return n1 * (x -= 1.5 / d1) * x + 0.75; + } else if (x < 2.5 / d1) { + return n1 * (x -= 2.25 / d1) * x + 0.9375; + } else { + return n1 * (x -= 2.625 / d1) * x + 0.984375; + } + } +}; + +var _a; +const CAMERA_EVENTS = { + CHANGE: "change", + ANIMATION_END: "animationEnd" +}; +const CONTROL_EVENTS = { + INPUT_START: "inputStart", + CHANGE: "change", + INPUT_END: "inputEnd", + ENABLE: "enable", + DISABLE: "disable", + STATIC_CLICK: "staticClick" +}; +const DEG_TO_RAD = Math.PI / 180; +const RAD_TO_DEG = 180 / Math.PI; +const DEFAULT_EASING = EASING.EASE_OUT_CUBIC; +const DEFAULT_ANIMATION_DURATION = 300; +const INFINITE_RANGE = { + min: -Infinity, + max: Infinity +}; +const DEFAULT_PITCH_RANGE = { + min: -90, + max: 90 +}; +const DEFAULT_ZOOM_RANGE = { + min: 0.6, + max: 10 +}; +var ROTATE; +(function (ROTATE) { + ROTATE[ROTATE["ZERO"] = 0] = "ZERO"; + ROTATE[ROTATE["CW_90"] = 1] = "CW_90"; + ROTATE[ROTATE["CCW_90"] = 2] = "CCW_90"; + ROTATE[ROTATE["CW_180"] = 3] = "CW_180"; +})(ROTATE || (ROTATE = {})); +// Custom event name for video time change +const VIDEO_TIME_CHANGE_EVENT = "view360videotimechange"; +const SVG_NAMESPACE = "http://www.w3.org/2000/svg"; +const SESSION_VR = "immersive-vr"; +const XR_REFERENCE_SPACE = "local"; +const EPSILON = (_a = Number.EPSILON) !== null && _a !== void 0 ? _a : 2.220446049250313e-16; + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +const isString = val => typeof val === "string"; +const isElement = val => !!val && val.nodeType === Node.ELEMENT_NODE; +const createElement = (className, tag = EL_DIV) => { + const el = document.createElement(tag); + el.classList.add(className); + return el; +}; +const getNullableElement = (el, parent) => { + let targetEl = null; + if (isString(el)) { + const parentEl = parent ? parent : document; + const queryResult = parentEl.querySelector(el); + if (!queryResult) { + return null; + } + targetEl = queryResult; + } else if (isElement(el)) { + targetEl = el; + } + return targetEl; +}; +const getElement = (el, parent) => { + const targetEl = getNullableElement(el, parent); + if (!targetEl) { + if (isString(el)) { + throw new View360Error(ERROR.MESSAGES.ELEMENT_NOT_FOUND(el), ERROR.CODES.ELEMENT_NOT_FOUND); + } else { + throw new View360Error(ERROR.MESSAGES.WRONG_TYPE(el, ["HTMLElement", "string"]), ERROR.CODES.WRONG_TYPE); + } + } + return targetEl; +}; +const findCanvas = (root, selector) => { + const canvas = root.querySelector(selector); + if (!canvas) { + throw new View360Error(ERROR.MESSAGES.CANVAS_NOT_FOUND, ERROR.CODES.CANVAS_NOT_FOUND); + } + return canvas; +}; +const range = end => { + if (!end || end <= 0) { + return []; + } + return Array.apply(0, Array(end)).map((undef, idx) => idx); +}; +const clamp = (x, min, max) => Math.max(Math.min(x, max), min); +// Linear interpolation between a and b +const lerp = (a, b, t) => { + return a * (1 - t) + b * t; +}; +const circulate = (val, min, max) => { + const size = Math.abs(max - min); + if (val < min) { + const offset = (min - val) % size; + val = max - offset; + } else if (val > max) { + const offset = (val - max) % size; + val = min + offset; + } + return val; +}; +const findIndex = (array, checker) => { + for (let idx = 0; idx < array.length; idx++) { + if (checker(array[idx])) { + return idx; + } + } + return -1; +}; +const getObjectOption = val => typeof val === "object" ? val : {}; +const toVerticalFov = (fovRadian, aspect) => { + return Math.atan(Math.tan(fovRadian * 0.5) / aspect) * 2; +}; +const reorderCube = (arr, order, defaultOrder = "RLUDFB") => { + return defaultOrder.split("").map(face => order.indexOf(face)).map(index => arr[index]); +}; +const isFullscreen = () => { + if (!document) return false; + for (const key of FULLSCREEN_ELEMENT) { + if (document[key]) return true; + } + return false; +}; +const sensorCanBeEnabledIOS = () => { + return !!DeviceMotionEvent && "requestPermission" in DeviceMotionEvent && window.isSecureContext; +}; +const hfovToZoom = (baseFov, fov) => { + const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5); + const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5); + return renderingWidth / zoomedWidth; +}; +const eulerToQuat = (out, yaw, pitch, roll) => { + quat.identity(out); + const pitchThreshold = 0.01; + const pitchClamped = clamp(pitch, -90 + pitchThreshold, 90 - pitchThreshold); + quat.rotateY(out, out, yaw * DEG_TO_RAD); + quat.rotateX(out, out, pitchClamped * DEG_TO_RAD); + quat.rotateZ(out, out, roll * DEG_TO_RAD); + return out; +}; +/** + * Extract euler angles from the quaternion, except roll(z-axis rotation) + * @hidden + */ +const quatToEuler = quaternion => { + const x = quaternion[0]; + const y = quaternion[1]; + const z = quaternion[2]; + const w = quaternion[3]; + const x2 = x * x; + const y2 = y * y; + const z2 = z * z; + const w2 = w * w; + const unit = x2 + y2 + z2 + w2; + const test = x * w - y * z; + let pitch, yaw; + if (test > 0.499995 * unit) { + // singularity at the north pole + pitch = Math.PI / 2; + yaw = 2 * Math.atan2(y, x); + } else if (test < -0.499995 * unit) { + // singularity at the south pole + pitch = -Math.PI / 2; + yaw = -2 * Math.atan2(y, x); + } else { + const view = vec3.fromValues(0, 0, 1); + const up = vec3.fromValues(0, 1, 0); + vec3.transformQuat(view, view, quaternion); + vec3.transformQuat(up, up, quaternion); + const viewXZ = Math.sqrt(view[0] * view[0] + view[2] * view[2]); + pitch = Math.atan2(-view[1], viewXZ); + yaw = Math.atan2(view[0], view[2]); + } + return { + pitch: clamp(pitch * RAD_TO_DEG, -90, 90), + yaw: circulate(yaw * RAD_TO_DEG, 0, 360) + }; +}; + +/* + * Copyright (c) 2020 NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Interpolator between two values with duration + * @ko 특정 시간동안 두 값을 보간해주는 보간기 + * @since 4.0.0 + */ +class Motion { + /** + * Current interpolated value + * @ko 현재 보간된 값 + * @since 4.0.0 + */ + get val() { + return this._val; + } + /** + * Start(from) value of interpolation + * @ko 보간 시작 값 + * @since 4.0.0 + */ + get start() { + return this._start; + } + /** + * End(to) value of interpolation + * @ko 보간 끝 값 + * @since 4.0.0 + */ + get end() { + return this._end; + } + /** + * Interpolation progress value (0 ~ 1) + * @ko 현재 보간 진행정도 (0 ~ 1) + * @since 4.0.0 + */ + get progress() { + return this._progress; + } + /** + * Whether the interpolation is in active state. + * @ko 보간 진행중인지 여부. `true`일 경우 보간이 진행중입니다. + * @since 4.0.0 + */ + get activated() { + return this._activated; + } + /** + * Duration of the interpolation + * @ko 보간할 시간 + * @since 4.0.0 + */ + get duration() { + return this._duration; + } + set duration(val) { + this._duration = val; + } + /** + * Whether to loop interpolation on finish + * @ko 보간이 끝난 이후에 다시 시작할지 여부 + * @since 4.0.0 + */ + get loop() { + return this._loop; + } + set loop(val) { + this._loop = val; + } + /** + * Range of the interpolation + * @ko 보간 범위 + * @since 4.0.0 + */ + get range() { + return this._range; + } + /** + * Easing function of the interpolation + * @ko 보간에 사용되는 easing function + * @since 4.0.0 + */ + get easing() { + return this._easing; + } + set easing(val) { + this._easing = val; + } + /** + * Create new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options Options {@ko 옵션들} + * @param options.duration Duration of the interpolation {@ko 보간할 시간} + * @param options.loop Whether to loop interpolation on finish {@ko 보간이 끝난 이후에 다시 시작할지 여부} + * @param options.range Range of the interpolation {@ko 보간 범위} + * @param options.loop Easing function of the interpolation {@ko 보간에 사용되는 easing function} + */ + constructor({ + duration = DEFAULT_ANIMATION_DURATION, + loop = false, + range = { + min: 0, + max: 1 + }, + easing = DEFAULT_EASING + } = {}) { + this._duration = duration; + this._loop = loop; + this._range = range; + this._easing = easing; + this._activated = false; + this.reset(0); + } + /** + * Update motion and progress it by given deltaTime + * @ko 주어진 deltaTime만큼 보간을 진행합니다. + * @param deltaTime - number of milisec to update motion {@ko 보간을 진행할 시간, 밀리초 단위} + * @returns Difference(delta) of the value from the last update. {@ko 지난 업데이트 이후의 값 변화량} + * @since 4.0.0 + */ + update(deltaTime) { + if (!this._activated) { + this._val = this._end; + return 0; + } + const start = this._start; + const end = this._end; + const duration = this._duration; + const prev = this._val; + const loop = this._loop; + const nextProgress = this._progress + deltaTime / duration; + this._progress = loop ? circulate(nextProgress, 0, 1) : clamp(nextProgress, 0, 1); + const easedProgress = this._easing(this._progress); + this._val = lerp(start, end, easedProgress); + if (!loop && this._progress >= 1) { + this._activated = false; + } + return this._val - prev; + } + /** + * Set `start`, `end` to the given value and set `progress` to 0. + * @ko 주어진 값으로 시작 지점, 끝 지점을 초기화하고 progress를 0으로 세팅합니다. + * @param defaultVal - Value to reset {@ko 초기화할 값} + * @since 4.0.0 + */ + reset(defaultVal) { + const range = this._range; + const val = clamp(defaultVal, range.min, range.max); + this._start = val; + this._end = val; + this._val = val; + this._progress = 0; + this._activated = false; + } + /** + * Add delta to start & end and current value. + * @ko 현재 & 끝 및 현재 값에 주어진 값을 더합니다. + * @param delta - Delta value to add {@ko 추가할 값} + */ + add(delta) { + const range = this._range; + this._start = clamp(this._start + delta, range.min, range.max); + this._end = clamp(this._end + delta, range.min, range.max); + this._val = clamp(this._val + delta, range.min, range.max); + } + /** + * Set current value to start, and end to current value + delta, then reset progress to 0. + * @ko 현재 값을 시작 지점으로, 그에서 delta만큼 추가된 값을 끝점으로 하고 progress를 0으로 갱신합니다. + * @param delta - Delta value to add {@ko 추가할 값} + */ + setNewEndByDelta(delta) { + const range = this._range; + this._start = this._val; + this._end = clamp(this._end + delta, range.min, range.max); + this._progress = 0; + this._activated = true; + } + /** + * Set new range of the interpolation. + * @ko 보간의 범위를 변경합니다. + * @param min - New minimum range {@ko 변경할 범위의 최소값} + * @param max - New maximum range {@ko 변경할 범위의 최대값} + */ + setRange(min, max) { + this._start = clamp(this._start, min, max); + this._end = clamp(this._end, min, max); + this._range = { + min, + max + }; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Animation of the {@link Camera} + * @internal + * @ko {@link Camera}의 애니메이션 + * @since 4.0.0 + */ +class CameraAnimation { + /** + * Duration of the animation + * @ko 애니메이션 재생시간 + * @since 4.0.0 + */ + get duration() { + return this._motion.duration; + } + set duration(val) { + this._motion.duration = val; + } + /** + * Easing function of the animation + * @ko 애니메이션의 easing function + * @since 4.0.0 + */ + get easing() { + return this._motion.easing; + } + set easing(val) { + this._motion.easing = val; + } + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param camera - Camera to animate {@ko 애니메이션을 적용할 카메라} + * @param from - Start pose {@ko 애니메이션이 시작 시점의 카메라의 회전 및 줌} + * @param to - End pose {@ko 애니메이션이 끝났을 때 카메라의 회전 및 줌} + * @param options - Options {@ko 옵션들} + * @param options.duration - Animation duration {@ko 애니메이션 재생 시간} + * @param options.easing - Animation easing function {@ko 애니메이션 easing function} + */ + constructor(camera, from, to, { + duration = DEFAULT_ANIMATION_DURATION, + easing = DEFAULT_EASING + } = {}) { + this._camera = camera; + this._motion = new Motion({ + duration, + easing, + range: { + min: 0, + max: 1 + } + }); + this._from = from; + this._to = to; + this._finishPromise = new Promise(resolve => { + this._finish = resolve; + }); + // Enable motion + this._motion.setNewEndByDelta(1); + } + /** + * Return a promise that resolved on animation end. + * @ko 애니메이션 재생이 끝났을 때 resolve되는 Promise를 반환합니다. + * @since 4.0.0 + */ + getFinishPromise() { + return this._finishPromise; + } + /** + * Update animation by given deltaTime. + * @ko 주어진 시간만큼 애니메이션을 업데이트합니다. + * @param deltaTime Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위} + * @since 4.0.0 + */ + update(deltaTime) { + const camera = this._camera; + const from = this._from; + const to = this._to; + const motion = this._motion; + motion.update(deltaTime); + // Progress that easing is applied + const progress = motion.val; + const rotation = quat.create(); + const zoom = lerp(from.zoom, to.zoom, progress); + quat.slerp(rotation, from.rotation, to.rotation, progress); + camera.rotate(rotation, zoom); + if (progress >= 1) { + this._finish(); + } + } +} + +/** + * Camera for View360 + * @ko View360용 카메라 구현체 + * @version 4.0.0 + */ +class Camera extends Component { + /** + * Camera's width / height ratio + * @ko 카메라의 가로 / 세로 비율 + * @readonly + */ + get aspect() { + return this._aspect; + } + /** + * Whether the camera's rotation changed from the last frame. + * @ko 마지막 프레임 이후로 카메라의 회전값이 변경되었는지 나타내는 플래그. + * @readonly + */ + get changed() { + return this._changed; + } + /** + * @copy View360#yawRange + */ + get yawRange() { + return this._initialYawRange; + } + set yawRange(val) { + this._initialYawRange = val; + } + /** + * @copy View360#pitchRange + */ + get pitchRange() { + return this._initialPitchRange; + } + set pitchRange(val) { + this._initialPitchRange = val; + } + /** + * @copy View360#zoomRange + */ + get zoomRange() { + return this._initialZoomRange; + } + set zoomRange(val) { + this._initialZoomRange = val; + } + /** + * Create new instance of Camera + * @param options - Camera options {@ko 카메라 옵션들} + */ + constructor({ + initialYaw, + initialPitch, + initialZoom, + yawRange, + pitchRange, + zoomRange, + fov + }) { + super(); + this.yaw = initialYaw; + this.pitch = initialPitch; + this.zoom = initialZoom; + this.rollOffset = 0; + this.initialYaw = initialYaw; + this.initialPitch = initialPitch; + this.initialZoom = initialZoom; + this.position = vec3.create(); + this.animation = null; + this._up = vec3.fromValues(0, 1, 0); + this._aspect = 1; + this._initialYawRange = yawRange; + this._initialPitchRange = pitchRange; + this._initialZoomRange = zoomRange; + this._yawRange = yawRange; + this._pitchRange = pitchRange; + this._zoomRange = zoomRange; + this.quaternion = quat.create(); + this._updateQuaternion(); + this.viewMatrix = mat4.create(); + this.projectionMatrix = mat4.create(); + this.fov = fov; + this._maxRenderHeight = -1; + } + /** + * Destroy instance and detach all event listeners + * @ko 인스턴스를 삭제하고 모든 이벤트 리스너를 삭제합니다. + * @since 4.0.0 + */ + destroy() { + this.off(); + } + /** + * Refresh internal size value. + * @ko 내부 크기값을 갱신합니다. + * @param width - New width {@ko 변경된 너비값} + * @param height - New height {@ko 변경된 높이값} + * @since 4.0.0 + */ + resize(width, height) { + const prevAspect = this._aspect; + this._aspect = width / height; + if (this._aspect !== prevAspect) { + this.updateMatrix(); + } + } + /** + * Change camera's rotation with euler values. + * @ko 카메라 회전을 오일러 각 방향으로 변경합니다. + * @param rotation - Rotation values {@ko 회전 값} + * @param rotation.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값} + * @param rotation.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값} + * @param rotation.zoom - zoom value to apply {@ko 적용할 카메라 줌 값} + * @since 4.0.0 + */ + lookAt({ + yaw = this.yaw, + pitch = this.pitch, + zoom = this.zoom + }) { + const prevQuaternion = quat.clone(this.quaternion); + const prevZoom = this.zoom; + this.yaw = circulate(yaw, 0, 360); + this.pitch = clamp(pitch, -90, 90); + this.zoom = zoom; + this._updateQuaternion(); + const zoomDiff = Math.abs(zoom - prevZoom); + if (!quat.equals(this.quaternion, prevQuaternion) || zoomDiff >= EPSILON * 10 // ignore small changes + ) { + this.updateMatrix(); + } + } + /** + * Change camera's rotation with quaternion. + * @ko 카메라 회전을 Quaternion을 이용해서 변경합니다. + * @param rotation - Quaternion to apply {@ko 적용할 Quaternion} + * @param zoom - zoom value to apply {@ko 적용할 카메라 줌 값} + * @since 4.0.0 + */ + rotate(rotation, zoom = this.zoom) { + const normalized = quat.normalize(quat.create(), rotation); + const isSameRotation = quat.equals(this.quaternion, normalized); + quat.copy(this.quaternion, normalized); + const prevZoom = this.zoom; + const { + yaw, + pitch + } = quatToEuler(normalized); + this.yaw = yaw; + this.pitch = pitch; + this.zoom = zoom; + const zoomDiff = Math.abs(zoom - prevZoom); + if (!isSameRotation || zoomDiff >= EPSILON * 10) { + this.updateMatrix(); + } + } + /** + * Change camera's rotation to given euler values by the given duration. + * @ko 카메라를 주어진 방향으로 주어진 시간동안 서서히 이동시킵니다. + * @param options - Animation parameters {@ko 애니메이션 패러미터} + * @param options.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값} + * @param options.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값} + * @param options.zoom - zoom value to apply {@ko 적용할 카메라 줌 값} + * @param options.duration - Duration of the animation {@ko 애니메이션 시간} + * @param options.easing - Easing function for the animation {@ko 애니메이션에 적용할 easing function} + */ + animateTo({ + yaw = this.yaw, + pitch = this.pitch, + zoom = this.zoom, + duration = 0, + easing = DEFAULT_EASING + } = {}) { + return __awaiter(this, void 0, void 0, function* () { + if (this.yaw === yaw && this.pitch === pitch && this.zoom === zoom) return; + const from = { + rotation: quat.clone(this.quaternion), + zoom: this.zoom + }; + const to = { + rotation: eulerToQuat(quat.create(), yaw, pitch, this.rollOffset), + zoom + }; + const animation = new CameraAnimation(this, from, to, { + duration, + easing + }); + const finishPromise = animation.getFinishPromise(); + this.animation = animation; + finishPromise.then(() => { + this.animation = null; + this.trigger(CAMERA_EVENTS.ANIMATION_END, { + animation + }); + }); + return finishPromise; + }); + } + /** + * @hidden + */ + restrictYawRange(min, max) { + this._yawRange = { + min, + max + }; + } + /** + * @hidden + */ + restrictPitchRange(min, max) { + this._pitchRange = { + min, + max + }; + } + /** + * @hidden + */ + restrictZoomRange(min, max) { + this._zoomRange = { + min, + max + }; + } + /** + * @hidden + */ + restrictRenderHeight(height) { + this._maxRenderHeight = height; + } + /** + * @hidden + */ + resetRange() { + this._yawRange = this._initialYawRange; + this._pitchRange = this._initialPitchRange; + this._zoomRange = this._initialZoomRange; + this._maxRenderHeight = -1; + } + /** + * Get actual yaw range by the given zoom value. + * @ko 주어진 zoom 값에 대한 실제 yaw 범위값을 반환합니다. + * @since 4.0.0 + */ + getYawRange(zoom) { + const yawLimit = this._yawRange; + const maxRenderHeight = this._maxRenderHeight; + if (!yawLimit) return INFINITE_RANGE; + const halfHFov = this.getHorizontalFov(zoom) * 0.5; + let minYaw = yawLimit.min; + let maxYaw = yawLimit.max; + if (maxRenderHeight > 0) { + const halfVFovRad = toVerticalFov(halfHFov * DEG_TO_RAD, this._aspect); + const h = maxRenderHeight * 0.5; + const t = Math.tan(halfVFovRad); + const d = Math.sqrt((1 + h * h) / (1 + t * t)); + const theta = Math.atan(Math.tan(halfHFov * DEG_TO_RAD) * d) * RAD_TO_DEG; + minYaw = yawLimit.min + theta; + maxYaw = yawLimit.max - theta; + } + if (minYaw > maxYaw) { + minYaw = 0; + maxYaw = 0; + } + return { + min: minYaw, + max: maxYaw + }; + } + /** + * Get actual pitch range by the given zoom value. + * @ko 주어진 zoom 값에 대한 실제 pitch 범위값을 반환합니다. + * @since 4.0.0 + */ + getPitchRange(zoom) { + const pitchLimit = this._pitchRange; + const maxRenderHeight = this._maxRenderHeight; + if (!pitchLimit) return DEFAULT_PITCH_RANGE; + let minPitch = pitchLimit.min; + let maxPitch = pitchLimit.max; + if (maxRenderHeight > 0) { + const halfVFov = this.getVerticalFov(zoom) * 0.5; + minPitch = pitchLimit.min + halfVFov; + maxPitch = pitchLimit.max - halfVFov; + } + if (minPitch > maxPitch) { + minPitch = 0; + maxPitch = 0; + } + return { + min: Math.max(minPitch, -90), + max: Math.min(maxPitch, 90) + }; + } + /** + * Get actual zoom range in fov degrees. + * @ko 실제 줌 범위를 fov각의 범위로 반환합니다. + * @since 4.0.0 + */ + getZoomRange() { + var _a; + const limit = (_a = this._zoomRange) !== null && _a !== void 0 ? _a : DEFAULT_ZOOM_RANGE; + // max (zoom in) -> minimum fov + const minFov = this.getHorizontalFov(limit.max); + const maxFov = this.getHorizontalFov(limit.min); + const currentFov = this.getHorizontalFov(this.zoom); + return { + min: Math.max(minFov, 1), + max: Math.min(maxFov, 180), + current: currentFov + }; + } + /** + * Return horizontal fov value when the given zoom is applied. (in degrees, °) + * @ko 주어진 zoom 값이 적용되었을 때의 수평 fov값을 반환합니다. (도 단위, °) + * @returns Zoomed horizontal FOV {@ko 줌이 적용된 수평 fov값} + * @since 4.0.0 + */ + getHorizontalFov(zoom = this.zoom) { + return this._getZoomedHorizontalFov(zoom) * RAD_TO_DEG; + } + /** + * Return vertical fov value when the given zoom is applied. (in degrees, °) + * @ko 주어진 zoom 값이 적용되었을 때의 수직 fov값을 반환합니다. (도 단위, °) + * @returns Zoomed vertical FOV {@ko 줌이 적용된 수직 fov값} + * @since 4.0.0 + */ + getVerticalFov(zoom = this.zoom) { + const aspect = this._aspect; + const hFov = this._getZoomedHorizontalFov(zoom); // In radians + const vFov = toVerticalFov(hFov, aspect); + return vFov * RAD_TO_DEG; + } + /** + * Calculate zoom value for the given fov. + * @ko 주어진 fov값을 zoom값으로 변환합니다. + * @param fov horizontal fov (in degrees, °) {@ko 수평 fov 값 (도 단위, °)} + * @since 4.0.0 + */ + fovToZoom(fov) { + const baseFov = this.fov; + const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5); + const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5); + return renderingWidth / zoomedWidth; + } + /** + * Update inner matrixes. + * @ko 내부 행렬들을 업데이트합니다. + * @internal + * @since 4.0.0 + */ + updateMatrix() { + const up = this._up; + const aspect = this._aspect; + const viewMatrix = this.viewMatrix; + const projMatrix = this.projectionMatrix; + const position = this.position; + const rotation = this.quaternion; + const upDir = vec3.create(); + const viewDir = vec3.fromValues(0, 0, -1); + vec3.transformQuat(viewDir, viewDir, rotation); + vec3.transformQuat(upDir, up, rotation); + const hFov = this._getZoomedHorizontalFov(); // In radians + const vFov = toVerticalFov(hFov, aspect); + mat4.lookAt(viewMatrix, position, viewDir, upDir); + mat4.perspective(projMatrix, vFov, aspect, 0.1, 100); + this._changed = true; + } + /** + * @hidden + */ + onFrameRender() { + this._changed = false; + } + _updateQuaternion() { + eulerToQuat(this.quaternion, this.yaw, this.pitch, this.rollOffset); + } + /** + * @param zoom Current zoom value + * @returns horizontal fov including zoom, in radian + */ + _getZoomedHorizontalFov(zoom = this.zoom) { + return 2 * Math.atan(Math.tan(DEG_TO_RAD * this.fov * 0.5) / zoom); + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +class MouseInput extends Component { + constructor() { + super(); + this._onMouseDown = evt => { + const el = this._el; + if (!el || evt.button !== MOUSE_BUTTON.LEFT) return; + evt.preventDefault(); + if (el.focus) { + el.focus(); + } else { + window.focus(); + } + this._prevPos[0] = evt.clientX; + this._prevPos[1] = evt.clientY; + window.addEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove, false); + window.addEventListener(EVENTS$1.MOUSE_UP, this._onMouseUp, false); + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: false, + isKeyboard: false + }); + }; + this._onMouseMove = evt => { + evt.preventDefault(); + const x = evt.clientX; + const y = evt.clientY; + const prevPos = this._prevPos; + const deltaX = x - prevPos[0]; + const deltaY = y - prevPos[1]; + this.trigger(CONTROL_EVENTS.CHANGE, { + delta: { + x: deltaX, + y: deltaY + }, + isTouch: false, + isKeyboard: false + }); + prevPos[0] = x; + prevPos[1] = y; + }; + this._onMouseUp = () => { + this._prevPos[0] = 0; + this._prevPos[1] = 0; + window.removeEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove, false); + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onMouseUp, false); + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: false, + isKeyboard: false, + scrolling: false + }); + }; + this._el = null; + this._prevPos = [0, 0]; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.MOUSE_DOWN, this._onMouseDown); + this._el = element; + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.MOUSE_DOWN, this._onMouseDown); + window.removeEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove, false); + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onMouseUp, false); + this._el = null; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +class TouchInput extends Component { + get scrollable() { + return this._scrollable; + } + set scrollable(val) { + this._scrollable = val; + } + constructor() { + super(); + this._onTouchStart = evt => { + if (evt.touches.length > 1 || this._scrolling) return; + const touch = evt.touches[0]; + this._isFirstTouch = true; + this._prevPos[0] = touch.clientX; + this._prevPos[1] = touch.clientY; + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: true, + isKeyboard: false + }); + }; + this._onTouchMove = evt => { + // Only the one finger motion should be considered + if (evt.touches.length > 1 || this._scrolling) return; + const touch = evt.touches[0]; + const scrollable = this._scrollable; + const prevPos = this._prevPos; + const x = touch.clientX; + const y = touch.clientY; + const deltaX = x - prevPos[0]; + const deltaY = y - prevPos[1]; + if (this._isFirstTouch) { + if (scrollable && !isFullscreen()) { + if (Math.abs(deltaY) > Math.abs(deltaX)) { + // Assume Scrolling + this._scrolling = true; + return; + } + } + this._isFirstTouch = false; + } + if (evt.cancelable !== false) { + evt.preventDefault(); + } + this.trigger(CONTROL_EVENTS.CHANGE, { + delta: { + x: deltaX, + y: deltaY + }, + isTouch: true, + isKeyboard: false + }); + prevPos[0] = x; + prevPos[1] = y; + }; + this._onTouchEnd = evt => { + if (evt.touches.length !== 0) return; + const touch = evt.touches[0]; + const prevPos = this._prevPos; + if (touch) { + prevPos[0] = touch.clientX; + prevPos[1] = touch.clientY; + } else { + prevPos[0] = 0; + prevPos[1] = 0; + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: true, + isKeyboard: false, + scrolling: this._scrolling + }); + } + if (evt.cancelable !== false) { + evt.preventDefault(); + } + this._scrolling = false; + }; + this._el = null; + this._prevPos = [0, 0]; + this._isFirstTouch = false; + this._scrolling = false; + this._scrollable = false; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.TOUCH_START, this._onTouchStart, { + passive: false + }); + element.addEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove, { + passive: false + }); + element.addEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = element; + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.TOUCH_START, this._onTouchStart); + element.removeEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove); + element.removeEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = null; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +class KeyboardInput extends Component { + get active() { + const pressed = this._pressed; + return pressed.LEFT || pressed.UP || pressed.RIGHT || pressed.DOWN; + } + constructor() { + super(); + this._onKeyDown = evt => { + // Ignore all other keypress except main arrow keys + if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return; + this._updateKeyPress(evt, true); + const pressedCount = this._getPressedKeyCount(); + if (pressedCount <= 0) return; + evt.preventDefault(); + if (pressedCount === 1 && !evt.repeat) { + // On first keydown + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: false, + isKeyboard: true + }); + } + }; + this._onKeyUp = evt => { + // Ignore all other keypress except main arrow keys + if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return; + this._updateKeyPress(evt, false); + const pressedCount = this._getPressedKeyCount(); + if (pressedCount > 0) return; + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: false, + isKeyboard: true, + scrolling: false + }); + }; + this._el = null; + this._clearPressedKeys(); + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown); + element.addEventListener(EVENTS$1.KEY_UP, this._onKeyUp); + this._el = element; + this._clearPressedKeys(); + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown); + element.removeEventListener(EVENTS$1.KEY_UP, this._onKeyUp); + this._el = null; + this._clearPressedKeys(); + } + update() { + const delta = this._getDeltaByPressedKeys(); + if (delta.x !== 0 || delta.y !== 0) { + this.trigger(CONTROL_EVENTS.CHANGE, { + delta, + isTouch: false, + isKeyboard: true + }); + } + } + _clearPressedKeys() { + this._pressed = KEY_DIRECTION.reduce((obj, keyName) => { + return Object.assign(Object.assign({}, obj), { + [keyName]: false + }); + }, {}); + } + _updateKeyPress(event, isEnable) { + const pressed = this._pressed; + const keyToUpdate = event.keyCode != null ? DIRECTION_KEY_CODE[event.keyCode] : DIRECTION_KEY_NAME[event.key]; + if (!keyToUpdate) return; + pressed[keyToUpdate] = isEnable; + } + _getPressedKeyCount() { + return KEY_DIRECTION.filter(key => this._pressed[key]).length; + } + _getDeltaByPressedKeys() { + const pressed = this._pressed; + let x = 0; + let y = 0; + if (pressed.LEFT) { + x += 1; + } + if (pressed.RIGHT) { + x -= 1; + } + if (pressed.UP) { + y += 1; + } + if (pressed.DOWN) { + y -= 1; + } + return { + x, + y + }; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Camera's rotation control + * @ko 카메라의 회전을 담당하는 컨트롤 + * @since 4.0.0 + */ +class RotateControl extends Component { + /** + * @copy CameraControl#enabled + */ + get enabled() { + return this._enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * @copy CameraControl#animating + */ + get animating() { + return this._keyboardInput.active || this._xMotion.activated || this._yMotion.activated; + } + /** + * Current yaw value + * @ko 현재 yaw 값 + * @readonly + * @since 4.0.0 + */ + get yaw() { + return this._xMotion; + } + /** + * Current pitch value + * @ko 현재 pitch 값 + * @readonly + * @since 4.0.0 + */ + get pitch() { + return this._yMotion; + } + /** + * @copy View360#scrollable + */ + get scrollable() { + return this._touchInput.scrollable; + } + set scrollable(val) { + this._touchInput.scrollable = val; + } + /** + * Scale factor for mouse/touch rotation + * @ko 마우스/터치를 통한 회전 배율 + * @default [1, 1] + * @since 4.0.0 + */ + get pointerScale() { + return this._pointerScale; + } + set pointerScale(val) { + this._pointerScale = val; + } + /** + * Scale factor for keyboard rotation + * @ko 키보드를 통한 회전 배율 + * @default [1, 1] + * @since 4.0.0 + */ + get keyboardScale() { + return this._keyboardScale; + } + set keyboardScale(val) { + this._keyboardScale = val; + } + /** + * Duration of the input animation (ms) + * @ko 회전 애니메이션의 시간 (ms) + * @default 300 + */ + get duration() { + return this._duration; + } + set duration(val) { + this._duration = val; + this._xMotion.duration = val; + this._yMotion.duration = val; + } + /** + * Easing function of the animation + * @ko 회전 애니메이션에 적용할 easing 함수 + * @default EASING.EASE_OUT_CUBIC + * @see EASING + */ + get easing() { + return this._easing; + } + set easing(val) { + this._easing = val; + this._xMotion.easing = val; + this._yMotion.easing = val; + } + /** + * Disable X-axis(pitch) rotation. + * @ko x축 회전(pitch)을 비활성화합니다. + * @default false + */ + get disablePitch() { + return this._disablePitch; + } + set disablePitch(val) { + this._disablePitch = val; + } + /** + * Disable Y-axis(yaw) rotation. + * @ko y축 회전(yaw)을 비활성화합니다. + * @default false + */ + get disableYaw() { + return this._disableYaw; + } + set disableYaw(val) { + this._disableYaw = val; + } + /** + * Disable rotation by keyboard. + * @ko 키보드를 이용한 회전을 비활성화합니다. + * @default false + */ + get disableKeyboard() { + return this._disableKeyboard; + } + set disableKeyboard(val) { + this._disableKeyboard = val; + } + /** + * Create new RotateControl instance + * @ko RotateControl의 인스턴스를 생성합니다. + * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트} + * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부} + * @param options - Options for control {@ko 컨트롤 옵션들} + */ + constructor(controlEl, enableBlocked, { + duration = DEFAULT_ANIMATION_DURATION, + easing = DEFAULT_EASING, + pointerScale = [1, 1], + keyboardScale = [1, 1], + disablePitch = false, + disableYaw = false, + disableKeyboard = false + } = {}) { + super(); + this._onInputStart = evt => { + this._changedWhileDragging = false; + this.trigger(CONTROL_EVENTS.INPUT_START, Object.assign(Object.assign({}, evt), { + inputType: "rotate" + })); + }; + this._onChange = evt => { + const delta = evt.delta; + const invZoomScale = 1 / this._zoomScale; // Reduce speed on zoom + const screenScale = this._screenScale; + const keyboardScale = this._keyboardScale; + const pointerScale = this._pointerScale; + let scale; + if (evt.isKeyboard) { + scale = [keyboardScale[0] * invZoomScale, keyboardScale[1] * invZoomScale]; + } else { + scale = [pointerScale[0] * screenScale[0] * invZoomScale, pointerScale[1] * screenScale[1] * invZoomScale]; + } + const scaledX = delta.x * scale[0]; + const scaledY = delta.y * scale[1]; + this._xMotion.setNewEndByDelta(scaledX); + this._yMotion.setNewEndByDelta(scaledY); + this._changedWhileDragging = true; + }; + this._onInputEnd = evt => { + this.trigger(CONTROL_EVENTS.INPUT_END, Object.assign(Object.assign({}, evt), { + inputType: "rotate" + })); + if (!this._changedWhileDragging && !evt.isKeyboard && !evt.scrolling) { + this.trigger(CONTROL_EVENTS.STATIC_CLICK, { + isTouch: evt.isTouch + }); + } + this._changedWhileDragging = false; + }; + this._controlEl = controlEl; + this._pointerScale = pointerScale; + this._keyboardScale = keyboardScale; + this._duration = duration; + this._easing = easing; + this._disablePitch = disablePitch; + this._disableYaw = disableYaw; + this._disableKeyboard = disableKeyboard; + this._enableBlocked = enableBlocked; + this._mouseInput = new MouseInput(); + this._touchInput = new TouchInput(); + this._keyboardInput = new KeyboardInput(); + this._xMotion = new Motion({ + duration, + range: INFINITE_RANGE, + easing + }); + this._yMotion = new Motion({ + duration, + range: DEFAULT_PITCH_RANGE, + easing + }); + this._screenScale = [1, 1]; + this._zoomScale = 1; + this._enabled = false; + this._changedWhileDragging = false; + this._bindInputs(); + } + destroy() { + this.disable(); + this._mouseInput.off(); + this._touchInput.off(); + this._keyboardInput.off(); + this.off(); + this._changedWhileDragging = false; + } + /** + * @hidden + */ + update(delta) { + if (!this._enabled) return; + const xMotion = this._xMotion; + const yMotion = this._yMotion; + const keyboardInput = this._keyboardInput; + if (!this._disableKeyboard) { + keyboardInput.update(); + } + if (!this._disablePitch) { + yMotion.update(delta); + } + if (!this._disableYaw) { + xMotion.update(delta); + } + } + /** + * @hidden + */ + updateRange(camera, zoom) { + const yawRange = camera.getYawRange(zoom); + const pitchRange = camera.getPitchRange(zoom); + this._xMotion.setRange(yawRange.min, yawRange.max); + this._yMotion.setRange(pitchRange.min, pitchRange.max); + } + /** + * @hidden + */ + setZoomScale(val) { + this._zoomScale = val; + } + /** + * Resize control to match target size. + * @ko 컨트롤의 내부 크기를 갱신합니다. + * @param hfov - Camera horizontal fov in degrees {@ko 카메라의 수평방향 fov값 (도 단위)} + * @param aspect - Camera aspect {@ko 카메라 가로/세로 비율} + * @param width - New width {@ko 갱신된 너비} + * @param height - New height {@ko 갱신된 높이} + */ + resize(hfov, aspect, width, height) { + const vfov = toVerticalFov(hfov * DEG_TO_RAD, aspect) * RAD_TO_DEG; + this._screenScale[0] = hfov / width; + this._screenScale[1] = vfov / height; + } + enable() { + if (this._enabled) return; + const element = this._controlEl; + this._mouseInput.enable(element); + this._touchInput.enable(element); + this._keyboardInput.enable(element); + this._enabled = true; + this._enableBlocked = false; + this.trigger(CONTROL_EVENTS.ENABLE, { + control: this, + updateCursor: true + }); + } + disable() { + if (!this._enabled) return; + this._mouseInput.disable(); + this._touchInput.disable(); + this._keyboardInput.disable(); + this._enabled = false; + this.trigger(CONTROL_EVENTS.DISABLE, { + updateCursor: true + }); + } + sync(camera) { + this.updateRange(camera, camera.zoom); + this._xMotion.reset(camera.yaw); + this._yMotion.reset(camera.pitch); + } + _bindInputs() { + const mouseInput = this._mouseInput; + const touchInput = this._touchInput; + const keyboardInput = this._keyboardInput; + mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + touchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + touchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + keyboardInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + keyboardInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + keyboardInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +class WheelInput extends Component { + get scrollable() { + return this._scrollable; + } + set scrollable(val) { + this._scrollable = val; + } + constructor() { + super(); + this._onWheel = evt => { + const scrollable = this._scrollable; + if (evt.deltaY === 0 || scrollable) return; + evt.preventDefault(); + evt.stopPropagation(); + if (this._inputTimer < 0) { + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: false, + isKeyboard: false + }); + } else { + this._clearTimer(); + } + const delta = this._baseScale * evt.deltaY; + this.trigger(CONTROL_EVENTS.CHANGE, { + delta, + isTouch: false, + isKeyboard: false + }); + this._inputTimer = window.setTimeout(() => { + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: false, + isKeyboard: false, + scrolling: false + }); + this._inputTimer = -1; + }, DEFAULT_ANIMATION_DURATION); + }; + this._el = null; + this._baseScale = 0.04; + this._scrollable = false; + this._inputTimer = -1; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.WHEEL, this._onWheel, { + passive: false, + capture: false + }); + this._el = element; + this._clearTimer(); + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.WHEEL, this._onWheel, false); + this._el = null; + this._clearTimer(); + } + _clearTimer() { + window.clearTimeout(this._inputTimer); + this._inputTimer = -1; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +class PinchInput extends Component { + constructor() { + super(); + this._onTouchMove = evt => { + const touches = evt.touches; + if (touches.length !== 2) return; + if (!evt.cancelable) return; + evt.preventDefault(); + evt.stopPropagation(); + const prevDistance = this._prevDistance; + const diff = [touches[0].pageX - touches[1].pageX, touches[0].pageY - touches[1].pageY]; + const distance = Math.sqrt(diff[0] * diff[0] + diff[1] * diff[1]) * this._baseScale; + const delta = this._isFirstTouch ? 0 : distance - prevDistance; + if (this._isFirstTouch) { + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: true, + isKeyboard: false + }); + } + this._prevDistance = distance; + this._isFirstTouch = false; + this.trigger(CONTROL_EVENTS.CHANGE, { + delta, + isTouch: true, + isKeyboard: false + }); + }; + this._onTouchEnd = evt => { + if (evt.touches.length !== 0) return; + if (!this._isFirstTouch) { + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: true, + isKeyboard: false, + scrolling: false + }); + } + this._prevDistance = -1; + this._isFirstTouch = true; + }; + this._el = null; + this._baseScale = -0.2; + this._prevDistance = -1; + this._isFirstTouch = true; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove, { + passive: false, + capture: false + }); + element.addEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = element; + this._prevDistance = -1; + this._isFirstTouch = true; + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove, false); + element.removeEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = null; + } +} + +/* +* Copyright (c) 2023-present NAVER Corp. +* egjs projects are licensed under the MIT license +*/ +/** + * Camera's zoom control + * @ko 카메라의 줌 값을 담당하는 컨트롤 + * @since 4.0.0 + */ +class ZoomControl extends Component { + /** + * @copy CameraControl#enabled + */ + get enabled() { + return this._enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * @copy CameraControl#animating + */ + get animating() { + return this._motion.activated; + } + /** + * Current zoom value + * @ko 현재 줌 값 + * @since 4.0.0 + * @readonly + */ + get zoom() { + return this._motion.val; + } + /** + * @copy View360#wheelScrollable + */ + get scrollable() { + return this._wheelInput.scrollable; + } + set scrollable(val) { + this._wheelInput.scrollable = val; + } + /** + * @hidden + */ + get range() { + return this._motion.range; + } + /** + * Scale factor of the zoom + * @ko 입력에 의한 줌 배율 + * @default 1 + * @since 4.0.0 + */ + get scale() { + return this._scale; + } + set scale(val) { + this._scale = val; + } + /** + * Duration of the input animation (ms) + * @ko 회전 애니메이션의 시간 (ms) + * @default 300 + * @since 4.0.0 + */ + get duration() { + return this._motion.duration; + } + /** + * Easing function of the animation + * @ko 회전 애니메이션에 적용할 easing 함수 + * @default EASING.EASE_OUT_CUBIC + * @see EASING + * @since 4.0.0 + */ + get easing() { + return this._motion.easing; + } + /** + * Create new ZoomControl instance + * @ko ZoomControl의 인스턴스를 생성합니다. + * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트} + * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부} + * @param options - Options for control {@ko 컨트롤 옵션들} + */ + constructor(controlEl, enableBlocked, { + scale = 1, + duration = DEFAULT_ANIMATION_DURATION, + easing = DEFAULT_EASING + } = {}) { + super(); + this._onInputStart = evt => { + this.trigger(CONTROL_EVENTS.INPUT_START, Object.assign(Object.assign({}, evt), { + inputType: "zoom" + })); + }; + this._onChange = ({ + delta + }) => { + const scale = this._scale; + const scaledDelta = delta * scale; + this._motion.setNewEndByDelta(scaledDelta); + }; + this._onInputEnd = evt => { + this.trigger(CONTROL_EVENTS.INPUT_END, Object.assign(Object.assign({}, evt), { + inputType: "zoom" + })); + }; + this._scale = scale; + this._controlEl = controlEl; + this._enableBlocked = enableBlocked; + this._wheelInput = new WheelInput(); + this._pinchInput = new PinchInput(); + this._motion = new Motion({ + duration, + easing, + range: INFINITE_RANGE + }); + this._enabled = false; + this._bindInputs(); + } + destroy() { + this.disable(); + this._wheelInput.off(); + this._pinchInput.off(); + this.off(); + } + /** + * @hidden + */ + update(delta) { + if (!this._enabled) return; + const motion = this._motion; + motion.update(delta); + } + enable() { + if (this._enabled) return; + const element = this._controlEl; + this._wheelInput.enable(element); + this._pinchInput.enable(element); + this._enabled = true; + this._enableBlocked = false; + this.trigger(CONTROL_EVENTS.ENABLE, { + control: this, + updateCursor: false + }); + } + disable() { + if (!this._enabled) return; + this._wheelInput.disable(); + this._pinchInput.disable(); + this._enabled = false; + this.trigger(CONTROL_EVENTS.DISABLE, { + updateCursor: false + }); + } + sync(camera) { + const motion = this._motion; + const range = camera.getZoomRange(); + motion.setRange(range.min, range.max); + motion.reset(range.current); + } + _bindInputs() { + const wheelInput = this._wheelInput; + const pinchInput = this._pinchInput; + wheelInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + wheelInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + wheelInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + pinchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + pinchInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + pinchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +const ROTATE_CONSTANT = { + PITCH_DELTA: 1, + YAW_DELTA_BY_ROLL: 2, + YAW_DELTA_BY_YAW: 3 +}; +ROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = { + targetAxis: [0, 1, 0], + meshPoint: [0, 0, 1] +}; +ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = { + targetAxis: [0, 1, 0], + meshPoint: [1, 0, 0] +}; +ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = { + targetAxis: [1, 0, 0], + meshPoint: [0, 0, 1] +}; +class GyroInput extends Component { + get enabled() { + return this._enabled; + } + get orientationUpdated() { + return this._orientationUpdated; + } + get ignoreRoll() { + return this._ignoreRoll; + } + set ignoreRoll(val) { + this._ignoreRoll = val; + } + constructor() { + super(); + this._onDeviceOrientation = evt => { + const prevOrientation = this._orientation; + const { + alpha, + beta, + gamma + } = evt; + if (alpha == null || beta == null || gamma == null) return; + prevOrientation.alpha = alpha; + prevOrientation.beta = beta; + prevOrientation.gamma = gamma; + this._orientationUpdated = true; + if (this._needsCalibrate) { + this._needsCalibrate = false; + this._calibrateSensor(); + } + }; + this._updateScreenOrientation = () => { + if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) { + this._screenOrientation = screen.orientation.angle; + } else if (window.orientation !== undefined) { + this._screenOrientation = window.orientation >= 0 ? window.orientation : 360 + window.orientation; + } else { + this._screenOrientation = 0; + } + }; + this.quaternion = quat.create(); + this._orientation = { + alpha: 0, + beta: 90, + gamma: 0 + }; + this._yawOrigin = 0; + this._yawOffset = 0; + this._orientationUpdated = false; + this._screenOrientation = 0; + this._needsCalibrate = true; + this._enabled = false; + } + enable() { + if (this._enabled) return; + window.addEventListener(EVENTS$1.DEVICE_ORIENTATION, this._onDeviceOrientation); + window.addEventListener(EVENTS$1.ORIENTATION_CHANGE, this._updateScreenOrientation); + this._updateScreenOrientation(); + this._orientationUpdated = false; + this._needsCalibrate = true; + this._enabled = true; + } + disable() { + if (!this._enabled) return; + window.removeEventListener(EVENTS$1.DEVICE_ORIENTATION, this._onDeviceOrientation); + window.removeEventListener(EVENTS$1.ORIENTATION_CHANGE, this._updateScreenOrientation); + this._enabled = false; + } + update() { + this._updateRotation(); + this._orientationUpdated = false; + } + collectDelta() { + if (!this._orientationUpdated) { + return { + pitch: 0, + yaw: 0 + }; + } + const prevRotation = quat.clone(this.quaternion); + this._updateRotation(); + this._orientationUpdated = false; + return this._toEulerDelta(prevRotation, this.quaternion); + } + setInitialRotation(yaw) { + this._yawOrigin = yaw; + } + _calibrateSensor() { + const yawOrigin = this._yawOrigin; + const rotation = this.quaternion; + this._yawOffset = 0; + this._updateRotation(); + const { + yaw: sensorYaw + } = quatToEuler(rotation); + this._yawOffset = sensorYaw - yawOrigin; + this._updateRotation(); + this._needsCalibrate = false; + } + _updateRotation() { + const rotation = this.quaternion; + const { + alpha, + beta, + gamma + } = this._orientation; + quat.identity(rotation); + quat.rotateY(rotation, rotation, (alpha - this._yawOffset) * DEG_TO_RAD); + quat.rotateX(rotation, rotation, beta * DEG_TO_RAD); + quat.rotateZ(rotation, rotation, -gamma * DEG_TO_RAD); + const screen = quat.create(); + const screenAngle = -this._screenOrientation * 0.5 * DEG_TO_RAD; + const world = quat.fromValues(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5)); + quat.set(screen, 0, Math.sin(screenAngle), 0, Math.cos(screenAngle)); + quat.multiply(rotation, rotation, screen); + quat.multiply(rotation, rotation, world); + quat.normalize(rotation, rotation); + } + _toEulerDelta(prevQuat, currentQuat) { + return { + yaw: this._getDeltaYaw(prevQuat, currentQuat), + pitch: this._getDeltaPitch(prevQuat, currentQuat) + }; + } + _getDeltaYaw(prvQ, curQ) { + const yawDeltaByYaw = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW); + const yawDeltaByRoll = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) * Math.sin(this._extractPitchFromQuat(curQ)); + return yawDeltaByRoll + yawDeltaByYaw; + } + _getDeltaPitch(prvQ, curQ) { + return this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA); + } + _getRotationDelta(prevQ, curQ, rotateKind) { + const targetAxis = vec3.fromValues(ROTATE_CONSTANT[rotateKind].targetAxis[0], ROTATE_CONSTANT[rotateKind].targetAxis[1], ROTATE_CONSTANT[rotateKind].targetAxis[2]); + const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint; + const prevQuaternion = quat.clone(prevQ); + const curQuaternion = quat.clone(curQ); + quat.normalize(prevQuaternion, prevQuaternion); + quat.normalize(curQuaternion, curQuaternion); + let prevPoint = vec3.fromValues(0, 0, 1); + let curPoint = vec3.fromValues(0, 0, 1); + vec3.transformQuat(prevPoint, prevPoint, prevQuaternion); + vec3.transformQuat(curPoint, curPoint, curQuaternion); + vec3.transformQuat(targetAxis, targetAxis, curQuaternion); + const rotateDistance = vec3.dot(targetAxis, vec3.cross(vec3.create(), prevPoint, curPoint)); + const rotateDirection = rotateDistance > 0 ? 1 : -1; + // when counter clock wise, use vec3.fromValues(0,1,0) + // when clock wise, use vec3.fromValues(0,-1,0) + // const meshPoint1 = vec3.fromValues(0, 0, 0); + const meshPoint2 = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + let meshPoint3; + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + meshPoint3 = vec3.fromValues(0, rotateDirection, 0); + } else { + meshPoint3 = vec3.fromValues(rotateDirection, 0, 0); + } + vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion); + vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion); + const vecU = meshPoint2; + const vecV = meshPoint3; + const vecN = vec3.create(); + vec3.cross(vecN, vecU, vecV); + vec3.normalize(vecN, vecN); + const coefficientA = vecN[0]; + const coefficientB = vecN[1]; + const coefficientC = vecN[2]; + // a point on the plane + curPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + vec3.transformQuat(curPoint, curPoint, curQuaternion); + // a point should project on the plane + prevPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + vec3.transformQuat(prevPoint, prevPoint, prevQuaternion); + // distance between prevPoint and the plane + let distance = Math.abs(prevPoint[0] * coefficientA + prevPoint[1] * coefficientB + prevPoint[2] * coefficientC); + const projectedPrevPoint = vec3.create(); + vec3.subtract(projectedPrevPoint, prevPoint, vec3.scale(vec3.create(), vecN, distance)); + let trigonometricRatio = (projectedPrevPoint[0] * curPoint[0] + projectedPrevPoint[1] * curPoint[1] + projectedPrevPoint[2] * curPoint[2]) / (vec3.length(projectedPrevPoint) * vec3.length(curPoint)); + // defensive block + if (trigonometricRatio > 1) { + trigonometricRatio = 1; + } + const theta = Math.acos(trigonometricRatio); + const crossVec = vec3.cross(vec3.create(), curPoint, projectedPrevPoint); + distance = coefficientA * crossVec[0] + coefficientB * crossVec[1] + coefficientC * crossVec[2]; + let thetaDirection; + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + thetaDirection = distance > 0 ? 1 : -1; + } else { + thetaDirection = distance < 0 ? 1 : -1; + } + const deltaRadian = theta * thetaDirection * rotateDirection; + return deltaRadian * RAD_TO_DEG; + } + _extractPitchFromQuat(quaternion) { + const baseV = vec3.fromValues(0, 0, 1); + vec3.transformQuat(baseV, baseV, quaternion); + return -1 * Math.atan2(baseV[1], Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2))); + } +} + +/** + * Camera's rotation control by gyroscope + * @ko 자이로스코프를 이용한 회전 컨트롤 + * @since 4.0.0 + */ +class GyroControl extends Component { + /** + * @copy CameraControl#enabled + */ + get enabled() { + return this._input.enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * @copy CameraControl#animating + */ + get animating() { + return this._input.enabled && this._input.orientationUpdated; + } + /** + * When `true`, ignore gyroscope's roll(z-axis rotation) value. + * :::caution + * Setting `false` will ignore camera's range limit. + * Options like {@link View360Options#yawRange}, {@link View360Options#pitchRange} are ignored, and {@link CylinderProjection} also can't force it's camera range limit. + * ::: + * @ko `true`일 경우 자이로스코프 입력의 roll(z축 회전)값을 무시합니다. + * :::caution + * 이 값을 `false`로 설정할 경우 카메라 범위 제약을 무시합니다. + * {@link View360Options#yawRange}, {@link View360Options#pitchRange}와 같은 값은 무시되며, {@link CylinderProjection} 사용시에도 범위를 벗어날 수 있습니다. + * ::: + * @default true + * @since 4.0.0 + */ + get ignoreRoll() { + return this._ignoreRoll; + } + set ignoreRoll(val) { + this._ignoreRoll = val; + } + /** + * Return availability of the gyroscope. + * :::caution + * This will always return false until user permission under environments like iOS which requires user permission when using gyroscope. + * ::: + * @ko 자이로스코프 사용 가능 여부를 반환합니다. + * :::caution + * iOS와 같이 GyroScope 사용시 사용자 Permission을 요구하는 환경에서는 사용자 Permission을 받기 전까지 항상 `false`입니다. + * ::: + * @example + * ```ts + * const gyroAvailable = await GyroControl.isAvailable(); + * ``` + */ + static isAvailable() { + return __awaiter(this, void 0, void 0, function* () { + if (!DeviceMotionEvent) { + return false; + } + let onDeviceMotionChange; + const listenDeviceMotion = () => new Promise(res => { + onDeviceMotionChange = evt => { + res(evt.rotationRate && evt.rotationRate.alpha != null); + }; + window.addEventListener(EVENTS$1.DEVICE_MOTION, onDeviceMotionChange); + }); + const timeout = () => new Promise(res => { + setTimeout(() => res(false), 1000); + }); + return Promise.race([listenDeviceMotion(), timeout()]).then(available => { + window.removeEventListener(EVENTS$1.DEVICE_MOTION, onDeviceMotionChange); + return available; + }); + }); + } + /** + * Request user permission for gyroscope sensor. + * This can be used in environments like iOS which requires user permission when using gyroscope sensors. + * @ko 사용자의 sensor permission 취득을 요청합니다. + * iOS와 같이 gyroscope 사용시 사용자 Permission을 요구하는 환경에서 사용 가능합니다. + * @returns Whether the permission is granted {@ko 사용자 permission 취득 여부} + */ + static requestSensorPermission() { + return __awaiter(this, void 0, void 0, function* () { + // Request sensor permission, on iOS13+ + if (sensorCanBeEnabledIOS()) { + return DeviceMotionEvent.requestPermission().then(permissionState => { + return permissionState === "granted"; + }).catch(() => false); + } + return true; + }); + } + /** + * Create new GyroControl instance + * @ko GyroControl의 인스턴스를 생성합니다. + * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부} + * @param options - Options for control {@ko 컨트롤 옵션들} + */ + constructor(enableBlocked, { + ignoreRoll = true + } = {}) { + super(); + this._enableBlocked = enableBlocked; + this._ignoreRoll = ignoreRoll; + this._input = new GyroInput(); + } + /** + * @copy CameraControl#destroy + */ + destroy() { + this.disable(); + this._input.off(); + this.off(); + } + /** + * @hidden + */ + update(camera, yaw, pitch, zoom) { + if (!this._ignoreRoll) { + this._updateQuaternion(camera, zoom); + } else { + this._updateYawPitch(camera, yaw, pitch, zoom); + } + } + /** + * @copy CameraControl#enable + */ + enable() { + if (this._input.enabled) return; + this._input.enable(); + this._enableBlocked = false; + this.trigger(CONTROL_EVENTS.ENABLE, { + control: this, + updateCursor: false + }); + } + /** + * @copy CameraControl#disable + */ + disable() { + if (!this._input.enabled) return; + this._input.disable(); + this.trigger(CONTROL_EVENTS.DISABLE, { + updateCursor: false + }); + } + /** + * @copy CameraControl#sync + */ + sync() {} // eslint-disable-line @typescript-eslint/no-empty-function + _updateYawPitch(camera, yaw, pitch, zoom) { + const input = this._input; + if (!input.enabled) return; + const { + yaw: yawDelta, + pitch: pitchDelta + } = input.collectDelta(); + yaw.add(yawDelta); + pitch.add(pitchDelta); + camera.lookAt({ + yaw: yaw.val, + pitch: pitch.val, + zoom + }); + } + _updateQuaternion(camera, zoom) { + const input = this._input; + if (!input.enabled) return; + input.update(); + camera.rotate(input.quaternion, zoom); + } +} + +/** + * Panorama control for View360 + * @ko View360용 파노라마 컨트롤 + * @since 4.0.0 + */ +class PanoControl { + /** + * @copy View360#useGrabCursor + */ + get useGrabCursor() { + return this._useGrabCursor; + } + set useGrabCursor(val) { + if (val === this._useGrabCursor) return; + this._useGrabCursor = val; + if (val && this._enabled) { + this._setCursor(CURSOR.GRAB); + } else if (!val) { + this._setCursor(CURSOR.NONE); + } + } + /** + * @copy View360#disableContextMenu + */ + get disableContextMenu() { + return this._disableContextMenu; + } + set disableContextMenu(val) { + if (val === this._disableContextMenu) return; + this._disableContextMenu = val; + if (val && this._enabled) { + this._blockContextMenu(); + } else if (!val) { + this._restoreContextMenu(); + } + } + /** + * @copy View360#disableContextMenu + */ + get scrollable() { + return this._rotateControl.scrollable; + } + set scrollable(val) { + this._rotateControl.scrollable = val; + } + /** + * @copy View360#disableContextMenu + */ + get wheelScrollable() { + return this._zoomControl.scrollable; + } + set wheelScrollable(val) { + this._zoomControl.scrollable = val; + } + /** + * When `true`, disables rotation slow-down by zoom-value. + * @ko `true`일 경우 줌 된 정도에 따라 회전속도를 늦추는 동작을 비활성화합니다. + * @since 4.0.0 + */ + get ignoreZoomScale() { + return this._ignoreZoomScale; + } + set ignoreZoomScale(val) { + this._ignoreZoomScale = val; + } + /** + * Whether the control is enabled or not + * @ko 컨트롤 활성화 여부를 가리키는 값 + * @readonly + * @since 4.0.0 + */ + get enabled() { + return this._enabled; + } + /** + * @copy View360#rotate + */ + get rotate() { + return this._rotateControl; + } + /** + * @copy View360#zoom + */ + get zoom() { + return this._zoomControl; + } + /** + * @copy View360#gyro + */ + get gyro() { + return this._gyroControl; + } + /** + * Whether one of the controls is animating at the moment + * @ko 현재 컨트롤 중 하나라도 동작중인지 여부를 나타내는 값 + * @readonly + * @since 4.0.0 + */ + get animating() { + return this._rotateControl.animating || this._zoomControl.animating || this._gyroControl.animating; + } + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param element - Canvas element {@ko 캔버스 엘리먼트} + * @param camera - Camera instance {@ko Camera 인스턴스} + * @param options - Options for PanoControl {@ko PanoControl 옵션들} + */ + constructor(element, camera, { + useGrabCursor, + scrollable, + wheelScrollable, + disableContextMenu, + rotate, + zoom, + gyro + }) { + this._preventContextMenu = evt => { + evt.preventDefault(); + }; + this._onInputStart = evt => { + if (this._useGrabCursor && !evt.isKeyboard) { + this._setCursor(CURSOR.GRABBING); + } + }; + this._onInputEnd = evt => { + if (this._useGrabCursor && !evt.isKeyboard) { + this._setCursor(CURSOR.GRAB); + } + }; + this._onEnable = ({ + control, + updateCursor + }) => { + if (updateCursor && this._useGrabCursor) { + this._setCursor(CURSOR.GRAB); + } + control.sync(this._camera); + }; + this._onDisable = ({ + updateCursor + }) => { + if (updateCursor) { + this._setCursor(CURSOR.NONE); + } + }; + this._onCameraAnimationEnd = ({ + animation + }) => { + animation.getFinishPromise().then(() => { + this.sync(); + }); + }; + // Bind Options + this._useGrabCursor = useGrabCursor; + this._disableContextMenu = disableContextMenu; + // Set internal values + this._camera = camera; + this._controlEl = element; + this._ignoreZoomScale = false; + this._enabled = false; + this._rotateControl = new RotateControl(element, !rotate, getObjectOption(rotate)); + this._zoomControl = new ZoomControl(element, !zoom, getObjectOption(zoom)); + this._gyroControl = new GyroControl(!gyro, getObjectOption(gyro)); + this._rotateControl.scrollable = scrollable; + this._zoomControl.scrollable = wheelScrollable; + this._bindEvents(); + } + /** + * Destroy the instance and remove all event listeners attached. + * This also will reset CSS cursor to initial. + * @ko 인스턴스를 삭제하고 부착된 모든 이벤트 리스너를 제거합니다. + * 또한, 캔버스에 적용된 CSS cursor도 제거합니다. + * @since 4.0.0 + */ + destroy() { + this.disable(); + this._rotateControl.destroy(); + this._zoomControl.destroy(); + this._setCursor(CURSOR.NONE); + } + /** + * Resize control to match target size. + * @ko 컨트롤이 내부에 캐시하고 있는 크기값을 갱신합니다. + * @param width New width {@ko 변경된 너비} + * @param height New height {@ko 변경된 높이} + * @since 4.0.0 + */ + resize(width, height) { + const camera = this._camera; + this._rotateControl.resize(camera.fov, camera.aspect, width, height); + } + /** + * Enable this control and add event listeners. + * @ko 컨트롤을 활성화하고 이벤트 리스너들을 추가합니다. + * @since 4.0.0 + */ + enable() { + return __awaiter(this, void 0, void 0, function* () { + if (this._enabled) return; + if (!this._rotateControl.enableBlocked) { + this._rotateControl.enable(); + } + if (!this._zoomControl.enableBlocked) { + this._zoomControl.enable(); + } + if (!this._gyroControl.enableBlocked) { + if (yield GyroControl.isAvailable()) { + this._gyroControl.enable(); + } + } + this.sync(); + if (this._disableContextMenu) { + this._blockContextMenu(); + } + this._enabled = true; + }); + } + /** + * Disable this control and remove all event listeners + * @ko 컨트롤을 비활성화하고 모든 이벤트 리스너들을 제거합니다. + * @since 4.0.0 + */ + disable() { + if (!this._enabled) return; + this._rotateControl.disable(); + this._zoomControl.disable(); + this._gyroControl.disable(); + this._restoreContextMenu(); + this._enabled = false; + } + /** + * Update control by given deltaTime + * @ko 컨트롤을 주어진 시간만큼 업데이트합니다. + * @param delta Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위} + * @since 4.0.0 + * @internal + */ + update(delta) { + const camera = this._camera; + const rotateControl = this._rotateControl; + const zoomControl = this._zoomControl; + const gyroControl = this._gyroControl; + zoomControl.update(delta); + const zoom = hfovToZoom(camera.fov, zoomControl.zoom); + // Slow down rotation on zoom-in + const zoomScale = this._ignoreZoomScale ? 1 : Math.max(zoom, 1); + rotateControl.setZoomScale(zoomScale); + rotateControl.updateRange(camera, zoom); + rotateControl.update(delta); + const yaw = rotateControl.yaw; + const pitch = rotateControl.pitch; + if (gyroControl.enabled) { + gyroControl.update(camera, yaw, pitch, zoom); + } else { + camera.lookAt({ + yaw: yaw.val, + pitch: pitch.val, + zoom + }); + } + } + /** + * Synchronize this control's state to current camera state + * @ko 컨트롤을 카메라의 현재 상태와 동기화합니다. + * @since 4.0.0 + */ + sync() { + const camera = this._camera; + this._zoomControl.sync(camera); + this._rotateControl.sync(camera); + } + _blockContextMenu() { + const el = this._controlEl; + el.addEventListener(EVENTS$1.CONTEXT_MENU, this._preventContextMenu); + } + _restoreContextMenu() { + const el = this._controlEl; + el.removeEventListener(EVENTS$1.CONTEXT_MENU, this._preventContextMenu); + } + _setCursor(newCursor) { + if (!this._useGrabCursor && newCursor !== CURSOR.NONE) return; + const targetEl = this._controlEl; + targetEl.style.cursor = newCursor; + } + _bindEvents() { + const rotateControl = this._rotateControl; + const zoomControl = this._zoomControl; + rotateControl.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + rotateControl.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + rotateControl.on(CONTROL_EVENTS.ENABLE, this._onEnable); + rotateControl.on(CONTROL_EVENTS.DISABLE, this._onDisable); + zoomControl.on(CONTROL_EVENTS.ENABLE, this._onEnable); + zoomControl.on(CONTROL_EVENTS.DISABLE, this._onDisable); + this._camera.on(CAMERA_EVENTS.ANIMATION_END, this._onCameraAnimationEnd); + } +} + +/** + * @hidden + */ +class Texture { + constructor({ + width, + height, + flipY + }) { + this.width = width; + this.height = height; + this.flipY = flipY; + this.wrapS = WebGLRenderingContext.CLAMP_TO_EDGE; + this.wrapT = WebGLRenderingContext.CLAMP_TO_EDGE; + } + destroy() { + // DO_NOTHING + } + isVideo() { + return false; + } + isCube() { + return false; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * @hidden + */ +class Texture2D extends Texture { + constructor({ + source, + width, + height, + flipY + }) { + super({ + width, + height, + flipY + }); + this.source = source; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * @hidden + */ +class TextureVideo extends Texture2D { + destroy() { + const video = this.source; + video.pause(); + video.removeAttribute("src"); + video.load(); + } + isVideo() { + return true; + } + isPaused() { + const video = this.source; + return video.paused || video.ended || video.readyState <= 2; + } + hasAudio() { + const video = this.source; + if (video.audioTracks) { + return video.audioTracks.length > 0; + } + if (video.webkitAudioDecodedByteCount != null) { + return video.webkitAudioDecodedByteCount > 0; + } + if (video.mozHasAudio != null) { + return video.mozHasAudio; + } + // We don't know whether the video has audio or not, return true + return true; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * @hidden + */ +class TextureCube extends Texture { + constructor({ + sources, + width, + height, + flipY + }) { + super({ + width, + height, + flipY + }); + this.sources = sources; + } + isCube() { + return true; + } +} + +/** + * @hidden + */ +class TextureLoader { + constructor() { + this._loadChecker = new ImReady(); + } + load(src, video) { + return __awaiter(this, void 0, void 0, function* () { + if (video) { + return this.loadVideo(src, getObjectOption(video)); + } else { + if (Array.isArray(src) && src.length > 1) { + return this.loadCubeImage(src); + } else { + const imgSrc = Array.isArray(src) ? src[0] : src; + return this.loadImage(imgSrc); + } + } + }); + } + loadImage(src) { + return __awaiter(this, void 0, void 0, function* () { + const images = this._toImageArray(src); + return this._load(images, resolve => { + const image = images[0]; + resolve(new Texture2D({ + source: image, + width: image.naturalWidth, + height: image.naturalHeight, + flipY: true + })); + }); + }); + } + loadCubeImage(src) { + return __awaiter(this, void 0, void 0, function* () { + const images = this._toImageArray(src); + return this._load(images, resolve => { + resolve(new TextureCube({ + sources: images, + width: images[0].naturalWidth, + height: images[0].naturalHeight, + flipY: false + })); + }); + }); + } + loadVideo(src, videoConfig) { + return __awaiter(this, void 0, void 0, function* () { + const config = Object.assign({ + autoplay: true, + muted: true, + loop: false, + volume: 1 + }, videoConfig); + const video = this._toVideoElement(src, config); + return this._load([video], resolve => { + const { + autoplay, + muted + } = config; + video.currentTime = 0; + if (autoplay && muted) { + video.play().catch(() => void 0); + } + resolve(new TextureVideo({ + source: video, + width: video.videoWidth, + height: video.videoHeight, + flipY: true + })); + }); + }); + } + _load(content, onLoad) { + const loader = this._loadChecker; + return new Promise((resolve, reject) => { + loader.once("ready", evt => { + if (evt.errorCount > 0) return; + onLoad(resolve); + }); + loader.once("error", reject); + loader.check(content); + }); + } + _toImageArray(src) { + const srcs = Array.isArray(src) ? src : [src]; + return srcs.map(source => { + if (isString(source)) { + const imgEl = new Image(); + imgEl.crossOrigin = "anonymous"; + imgEl.src = source; + return imgEl; + } else { + return source; + } + }); + } + _toVideoElement(src, { + muted, + loop, + volume + }) { + if (src instanceof HTMLVideoElement) { + return src; + } + const video = document.createElement("video"); + video.crossOrigin = "anonymous"; + video.playsInline = true; + video.setAttribute("webkit-playsinline", ""); + video.muted = muted; + video.volume = volume; + video.loop = loop; + if (Array.isArray(src)) { + src.forEach(source => this._appendSourceElement(video, source)); + } else { + this._appendSourceElement(video, src); + } + const sourceCount = video.querySelectorAll("source").length; + if (sourceCount > 0 && video.readyState < 1) { + video.load(); + } + return video; + } + _appendSourceElement(video, src) { + if (src instanceof HTMLSourceElement) { + return src; + } + const sourceEl = document.createElement("source"); + sourceEl.src = src; + video.appendChild(sourceEl); + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * @internal + */ +class FrameAnimator { + /** */ + constructor(maxDeltaTime, context = window) { + this.maxDeltaTime = maxDeltaTime; + this._context = context; + this._rafId = -1; + this._rafTimer = -1; + this._lastUpdateTime = -1; + } + start(callback) { + const context = this._context; + // No context / callback set + if (!context || !callback) return; + // Animation already started + if (this._rafId >= 0 || this._rafTimer >= 0) return; + const loop = (_time, frame) => { + const time = Date.now(); + const delta = Math.min(time - this._lastUpdateTime, this.maxDeltaTime * 1000); + callback(delta, frame); + this._lastUpdateTime = time; + this._rafId = context.requestAnimationFrame(loop); + }; + this._lastUpdateTime = Date.now(); + this._rafId = context.requestAnimationFrame(loop); + } + stop() { + if (this._rafId >= 0) { + this._context.cancelAnimationFrame(this._rafId); + } + if (this._rafTimer >= 0) { + clearTimeout(this._rafTimer); + } + this._rafId = -1; + this._rafTimer = -1; + } + changeContext(context) { + this.stop(); + this._context = context; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Automatic resizer that uses both ResizeObserver and window resize event + */ +class AutoResizer { + get useResizeObserver() { + return this._useResizeObserver; + } + /** + * Returns whether AutoResizer is enabled + */ + get enabled() { + return this._enabled; + } + /** */ + constructor(useResizeObserver, onResize) { + // eslint-disable-next-line @typescript-eslint/member-ordering + this._skipFirstResize = (() => { + let isFirstResize = true; + return () => { + if (isFirstResize) { + isFirstResize = false; + return; + } + this._onResize(); + }; + })(); + this._useResizeObserver = useResizeObserver; + this._enabled = false; + this._resizeObserver = null; + this._onResize = onResize; + } + /** + * Enable resizer + */ + enable(element) { + if (this._enabled) { + this.disable(); + } + if (this._useResizeObserver && !!window.ResizeObserver) { + const bbox = element.getBoundingClientRect(); + const resizeImmediate = bbox.width !== 0 || bbox.height !== 0; + const resizeObserver = new ResizeObserver(resizeImmediate ? this._skipFirstResize : this._onResize); + resizeObserver.observe(element); + this._resizeObserver = resizeObserver; + } else { + window.addEventListener(EVENTS$1.RESIZE, this._onResize); + } + this._enabled = true; + return this; + } + /** + * Disable resizer + */ + disable() { + if (!this._enabled) return this; + const resizeObserver = this._resizeObserver; + if (resizeObserver) { + resizeObserver.disconnect(); + this._resizeObserver = null; + } else { + window.removeEventListener(EVENTS$1.RESIZE, this._onResize); + } + this._enabled = false; + return this; + } +} + +/** + * A manager class for autoplay feature. + * @ko Autoplay 기능의 매니저 클래스. + * @since 4.0.0 + */ +class Autoplay { + /** + * Whether autoplay is enabled or not + * @ko 자동재생 활성화 여부를 나타내는 값 + * @readonly + * @since 4.0.0 + */ + get enabled() { + return this._enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * Whether autoplay is updating the camera at the moment + * @ko 현재 자동재생이 동작중인지 여부를 나타내는 값 + * @readonly + * @since 4.0.0 + */ + get playing() { + return this._enabled && !this._interrupted; + } + /** + * Reactivation delay after mouse input in milisecond. + * @ko 재활성화되기까지의 시간 (밀리초 단위) + * @default 2000 + * @since 4.0.0 + */ + get delay() { + return this._delay; + } + set delay(val) { + this._delay = val; + } + /** + * Reactivation delay after mouse leave when using {@link AutoplayOptions#pauseOnHover} + * @ko {@link AutoplayOptions#pauseOnHover} 사용시 마우스가 캔버스 영역을 떠난 뒤 자동재생이 다시 활성화되기까지의 시간 + * @default 0 + * @since 4.0.0 + */ + get delayOnMouseLeave() { + return this._delayOnMouseLeave; + } + set delayOnMouseLeave(val) { + this._delayOnMouseLeave = val; + } + /** + * Y-axis(yaw) rotation speed + * @ko Y-축 회전(yaw)의 속도 + * @default 1 + * @since 4.0.0 + */ + get speed() { + return this._speed; + } + set speed(val) { + this._speed = val; + } + /** + * Whether to pause rotation on mouse hover + * @ko 마우스가 캔버스 영역에 들어왔을 때 자동재생을 정지할지 여부 + * @default false + * @since 4.0.0 + */ + get pauseOnHover() { + return this._pauseOnHover; + } + set pauseOnHover(val) { + this._pauseOnHover = val; + } + /** + * Whether user can interrupt the rotation with click/wheel input + * @ko 클릭이나 휠같은 사용자 인터랙션시 자동재생을 멈출지 여부 + * @default true + * @since 4.0.0 + */ + get canInterrupt() { + return this._canInterrupt; + } + set canInterrupt(val) { + this._canInterrupt = val; + } + /** + * Whether to disable autoplay on user interrupt + * @ko 사용자 동작에 의해 자동재생이 정지할 때, {@link Autoplay#disable}을 호출하여 자동재생을 영구히 정지할지 여부 + * @default false + * @since 4.0.0 + */ + get disableOnInterrupt() { + return this._disableOnInterrupt; + } + set disableOnInterrupt(val) { + this._disableOnInterrupt = val; + } + /** + * Create new AutoPlayer instance + * @param camera - Instance of the {@link Camera} {@ko Camera의 인스턴스} + * @param element - Canvas element {@ko 캔버스 엘리먼트} + * @param options - Autoplay options {@ko 자동재생 옵션들} + * @since 4.0.0 + */ + constructor(viewer, element, options) { + this._onInputStart = () => { + if (!this._canInterrupt) return; + this._interrupted = true; + this._clearTimeout(); + }; + this._onInputEnd = () => { + this._setUninterruptedAfterDelay(this._delay); + }; + this._onGyroEnable = () => { + this.disable(); + }; + this._onMouseEnter = () => { + if (!this._pauseOnHover) return; + this._interrupted = true; + this._hovering = true; + }; + this._onMouseLeave = () => { + if (!this._pauseOnHover) return; + this._hovering = false; + this._setUninterruptedAfterDelay(this._delayOnMouseLeave); + }; + this._camera = viewer.camera; + this._control = viewer.control; + this._element = element; + this._enabled = false; + this._interrupted = false; + this._interruptionTimer = -1; + this._hovering = false; + const { + delay = 2000, + delayOnMouseLeave = 0, + speed = 1, + pauseOnHover = false, + canInterrupt = true, + disableOnInterrupt = false + } = getObjectOption(options); + this._enableBlocked = !options; + this._delay = delay; + this._delayOnMouseLeave = delayOnMouseLeave; + this._speed = speed; + this._pauseOnHover = pauseOnHover; + this._canInterrupt = canInterrupt; + this._disableOnInterrupt = disableOnInterrupt; + } + /** + * Destroy the instance and remove all event listeners attached + * @ko 인스턴스를 제거하고 연결된 모든 이벤트 핸들러를 삭제합니다. + * @since 4.0.0 + */ + destroy() { + this.disable(); + } + /** + * Rotate camera by given deltaTime + * @ko 주어진 deltaTime만큼 카메라를 회전시킵니다. + * @param deltaTime - Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위} + * @since 4.0.0 + */ + update(deltaTime) { + if (!this._enabled) return; + if (this._interrupted) { + if (this._disableOnInterrupt) { + this.disable(); + } + return; + } + const camera = this._camera; + const delta = -this._speed * deltaTime / 100; + camera.yaw = circulate(camera.yaw + delta, 0, 360); + } + /** + * Enable autoplay and add event listeners. + * @ko 자동재생을 활성화하고 이벤트리스너들을 추가합니다. + * @since 4.0.0 + */ + enable() { + const control = this._control; + const element = this._element; + if (this._enabled || control.gyro.enabled) return; + control.rotate.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.rotate.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.zoom.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.zoom.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.gyro.on(CONTROL_EVENTS.ENABLE, this._onGyroEnable); + element.addEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter, false); + element.addEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave, false); + this._enabled = true; + this._enableBlocked = false; + } + /** + * Enable autoplay after current `delay` value. + * @ko 현재의 `delay`값만큼 시간이 지난 다음에 자동재생을 활성화합니다. + * @since 4.0.0 + */ + enableAfterDelay() { + this.enable(); + this._interrupted = true; + this._setUninterruptedAfterDelay(this._delay); + } + /** + * Disable autoplay and remove all event handlers. + * @ko 자동재생을 비활성화하고 모든 이벤트 핸들러를 제거합니다. + * @since 4.0.0 + */ + disable() { + if (!this._enabled) return; + const control = this._control; + const element = this._element; + control.rotate.off(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.rotate.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.zoom.off(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.zoom.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.gyro.off(CONTROL_EVENTS.ENABLE, this._onGyroEnable); + element.removeEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter, false); + element.removeEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave, false); + this._enabled = false; + this._interrupted = false; + this._hovering = false; + this._clearTimeout(); + } + _setUninterruptedAfterDelay(delay) { + if (this._hovering) return; + this._clearTimeout(); + if (delay > 0) { + this._interruptionTimer = window.setTimeout(() => { + this._interrupted = false; + this._interruptionTimer = -1; + }, delay); + } else { + this._interrupted = false; + this._interruptionTimer = -1; + } + } + _clearTimeout() { + if (this._interruptionTimer >= 0) { + window.clearTimeout(this._interruptionTimer); + this._interruptionTimer = -1; + } + } +} + +/** + * WebXR manager class + * @ko WebXR 매니저 클래스 + * @since 4.0.0 + */ +class XRManager extends Component { + /** + * Create new instance. + * 새 인스턴스를 생성합니다. + * @param ctx - Instance of WebGL context helper {@ko WebGL 콘텍스트 헬퍼의 인스턴스} + * @param options - Options {@ko 옵션들} + */ + constructor(ctx, options = {}) { + super(); + /** + * Destroy instance and end XR session if there was any. + * @ko 인스턴스를 제거하고, XR 세션이 존재할 경우 종료합니다. + * @since 4.0.0 + */ + this.destroy = () => { + this.exit(); + this.off(); + }; + this._onSessionEnd = () => { + this.exit(); + this.trigger(EVENTS.VR_END); + }; + this._xrSession = null; + this._xrRefSpace = null; + this._ctx = ctx; + this._options = options; + } + /** + * Returns WebXR availability. + * @ko WebXR 사용 가능 여부를 반환합니다. + * @since 4.0.0 + */ + isAvailable() { + return __awaiter(this, void 0, void 0, function* () { + // eslint-disable-next-line compat/compat + const xr = window.navigator.xr; + if (!xr) return false; + return xr.isSessionSupported(SESSION_VR).then(available => { + return available; + }).catch(() => { + return false; + }); + }); + } + /** + * Enter VR session + * @ko VR 세션에 진입합니다. + * @since 4.0.0 + */ + enter() { + return __awaiter(this, void 0, void 0, function* () { + const ctx = this._ctx; + // eslint-disable-next-line compat/compat + const xr = window.navigator.xr; + if (!xr) return; + yield GyroControl.requestSensorPermission(); + const options = Object.assign({ + requiredFeatures: [XR_REFERENCE_SPACE] + }, this._options); + yield ctx.makeXRCompatible(); + const session = yield xr.requestSession(SESSION_VR, options); + ctx.bindXRLayer(session); + const refSpace = yield session.requestReferenceSpace(XR_REFERENCE_SPACE); + this._setSession(session, refSpace); + this.trigger(EVENTS.VR_START, { + session + }); + }); + } + /** + * Exit VR session + * @ko VR 세션에서 나갑니다. + * @since 4.0.0 + */ + exit() { + const xrSession = this._xrSession; + if (xrSession) { + xrSession.end().catch(() => void 0); + } + this._xrSession = null; + this._xrRefSpace = null; + } + /** + * @hidden + */ + canRender(frame) { + const refSpace = this._xrRefSpace; + if (!refSpace) return false; + const pose = frame.getViewerPose(refSpace); + return !!pose; + } + /** + * @hidden + */ + getEyeParams(frame) { + const session = frame.session; + const pose = frame.getViewerPose(this._xrRefSpace); + if (!pose) return null; + const glLayer = session.renderState.baseLayer; + if (!glLayer) return null; + return pose.views.map(view => { + const viewport = glLayer.getViewport(view); + const vMatrix = view.transform.inverse.matrix; + return { + viewport, + vMatrix, + pMatrix: view.projectionMatrix + }; + }); + } + _setSession(session, refSpace) { + this._xrSession = session; + this._xrRefSpace = refSpace; + session.addEventListener(EVENTS$1.XR_END, this._onSessionEnd); + } +} + +/** + * Hotspot data + * @ko 핫스팟 데이터 + * @since 4.0.0 + */ +class Hotspot { + constructor(element, position) { + this.element = element; + this.position = position; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Hotspot renderer + * @ko Hotspot 렌더러 + * @since 4.0.0 + */ +class HotspotRenderer { + /** + * Create new instance + * @ko 새 인스턴스를 생성합니다. + * @param rootEl - Container element for hotspots {@ko 핫스팟들의 컨테이너 엘리먼트} + * @param renderer - instance of WebGLRenderer {@ko WebGLRenderer의 인스턴스} + * @param options - Hotspot options {@ko Hotspot 옵션들 } + */ + constructor(rootEl, renderer, { + zoom = false + }) { + this._containerEl = getNullableElement(`.${DEFAULT_CLASS.HOTSPOT_CONTAINER}`, rootEl); + this._renderer = renderer; + this._hotspots = []; + this._zoom = zoom; + } + /** + * Refresh hotspots by collecting hotspot elements from current hotspot root element + * @ko 현재 핫스팟 루트 엘리먼트 내에서 핫스팟 엘리먼트들을 수집하여 갱신합니다. + * @throws {ERROR_CODES.INSUFFICIENT_ARGS} if data-position doesn't include all x, y, z values {@ko data-position이 x, y, z좌표를 전부 포함하고 있지 않을 때} + */ + refresh() { + const container = this._containerEl; + if (!container) return; + const hotspotEls = [].slice.apply(container.querySelectorAll(`.${DEFAULT_CLASS.HOTSPOT}`)); + this._hotspots = hotspotEls.map(el => this._parseHotspot(el)); + } + /** + * Render hotspots + * @ko 핫스팟들을 렌더링합니다. + * @param camera - Instance of Camera {@ko Camera의 인스턴스} + */ + render(camera) { + const hotspots = this._hotspots; + const halfWidth = this._renderer.width * 0.5; + const halfHeight = this._renderer.height * 0.5; + const zoom = camera.zoom; + const centerTransform = "translate(-50%, -50%)"; + const zoomTransform = this._zoom ? `scale(${zoom})` : ""; + hotspots.forEach(hotspot => { + const position = hotspot.position; + const relPos = vec3.create(); + vec3.copy(relPos, position); + vec3.transformMat4(relPos, relPos, camera.viewMatrix); + vec3.transformMat4(relPos, relPos, camera.projectionMatrix); + if (relPos[2] > 1 || relPos[2] < 0) { + hotspot.element.classList.remove(DEFAULT_CLASS.HOTSPOT_VISIBLE); + return; + } + const screenPos = vec2.fromValues(relPos[0] * halfWidth + halfWidth, -relPos[1] * halfHeight + halfHeight); + hotspot.element.classList.add(DEFAULT_CLASS.HOTSPOT_VISIBLE); + hotspot.element.style.transform = [centerTransform, `translate(${screenPos[0]}px, ${screenPos[1]}px)`, zoomTransform].join(" "); + }); + } + _parseHotspot(element) { + const yawStr = element.dataset.yaw; + const pitchStr = element.dataset.pitch; + const positionStr = element.dataset.position; + if (yawStr || pitchStr) { + const yaw = yawStr ? parseFloat(yawStr) : 0; + const pitch = pitchStr ? parseFloat(pitchStr) : 0; + const position = this._yawPitchToVec3(yaw, pitch); + return new Hotspot(element, position); + } else if (positionStr) { + const pos = positionStr.split(" ").map(val => parseFloat(val)); + if (pos.length < 3) { + throw new View360Error(ERROR.MESSAGES.INSUFFICIENT_ARGS(positionStr, "hotspot attribute \"data-position\""), ERROR.CODES.INSUFFICIENT_ARGS); + } + return new Hotspot(element, vec3.fromValues(pos[0], pos[1], pos[2])); + } else { + // Place hotspot at yaw: 0, pitch: 0 + const defaultPos = vec3.fromValues(0, 0, -1); + return new Hotspot(element, defaultPos); + } + } + _yawPitchToVec3(yaw, pitch) { + const yawRad = yaw * DEG_TO_RAD; + const pitchRad = pitch * DEG_TO_RAD; + const position = vec3.create(); + position[1] = Math.sin(pitchRad); + position[2] = Math.cos(pitchRad); + position[0] = position[2] * Math.sin(-yawRad); + position[2] = -position[2] * Math.cos(-yawRad); + return position; + } +} + +/** + * @hidden + */ +class VertexArrayObject { + get count() { + return this.geometry.indicies.count; + } + constructor(obj, geometry, buffers) { + this.obj = obj; + this.geometry = geometry; + this.buffers = buffers; + } +} + +/** + * @hidden + */ +class WebGLContext { + get canvas() { + return this._canvas; + } + get maxTextureSize() { + return this._maxTextureSize; + } + get isWebGL2() { + return this._isWebGL2; + } + get supportVAO() { + return this._isWebGL2 || !!this._extensions.vao; + } + get lost() { + return this._contextLost; + } + get debug() { + return this._debug; + } + constructor(canvas, debug) { + this._onContextLost = () => { + const canvas = this._canvas; + canvas.classList.add(DEFAULT_CLASS.CTX_LOST); + this._contextLost = true; + }; + this._onContextRestore = () => { + const canvas = this._canvas; + canvas.classList.remove(DEFAULT_CLASS.CTX_LOST); + this._contextLost = false; + }; + this._canvas = canvas; + this._contextLost = false; + this._debug = debug; + this._extensions = { + vao: null, + loseContext: null + }; + } + init() { + const canvas = this._canvas; + const { + gl, + isWebGL2 + } = this._getContext(canvas); + this._gl = gl; + this._maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); + this._isWebGL2 = isWebGL2; + if (!this._isWebGL2) { + this._extensions.vao = gl.getExtension("OES_vertex_array_object"); + } + this._extensions.loseContext = gl.getExtension("WEBGL_lose_context"); + canvas.addEventListener(EVENTS$1.CONTEXT_LOST, this._onContextLost); + canvas.addEventListener(EVENTS$1.CONTEXT_RESTORED, this._onContextRestore); + // gl.enable(gl.DEPTH_TEST); + } + + destroy() { + const gl = this._gl; + const canvas = this._canvas; + if (gl) { + // gl is not defined when destroy is called before init + gl.bindBuffer(gl.ARRAY_BUFFER, null); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + } + canvas.removeEventListener(EVENTS$1.CONTEXT_LOST, this._onContextLost); + canvas.removeEventListener(EVENTS$1.CONTEXT_RESTORED, this._onContextRestore); + } + forceLoseContext() { + const extension = this._extensions.loseContext; + if (!extension) return; + extension.loseContext(); + } + forceRestoreContext() { + const extension = this._extensions.loseContext; + if (!extension) return; + extension.restoreContext(); + } + clear() { + const gl = this._gl; + gl.clear(gl.COLOR_BUFFER_BIT); + } + resize() { + const gl = this._gl; + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + } + viewport(x, y, width, height) { + const gl = this._gl; + gl.viewport(x, y, width, height); + } + createVAO(geometry, shaderProgram) { + const nativeVAO = this._createNativeVAO(); + const vao = new VertexArrayObject(nativeVAO, geometry, { + indicies: this._createBuffer(), + position: this._createBuffer(), + uv: this._createBuffer() + }); + if (nativeVAO) { + this._bindNativeVAO(nativeVAO); + this._supplyGeometryData(vao, shaderProgram); + this._bindNativeVAO(null); + this._unbindBuffers(); + } + return vao; + } + draw(vao, shaderProgram) { + const gl = this._gl; + if (vao.obj) { + this._bindNativeVAO(vao.obj); + } else { + this._supplyGeometryData(vao, shaderProgram); + } + gl.drawElements(gl.TRIANGLES, vao.count, gl.UNSIGNED_SHORT, 0); + if (vao.obj) { + this._bindNativeVAO(null); + } else { + this._unbindBuffers(); + } + } + releaseVAO(vao) { + if (vao.obj) { + this._deleteNativeVAO(vao.obj); + } + this._deleteBuffer(vao.buffers.indicies); + this._deleteBuffer(vao.buffers.position); + this._deleteBuffer(vao.buffers.uv); + } + getUniformLocations(program, uniforms) { + const gl = this._gl; + const uniformLocations = Object.keys(uniforms).reduce((locations, key) => { + locations[key] = gl.getUniformLocation(program, key); + return locations; + }, {}); + return Object.assign(Object.assign({}, this._getCommonUniformLocations(program)), uniformLocations); + } + updateCommonUniforms(entity, camera, shaderProgram) { + const gl = this._gl; + const uniformLocations = shaderProgram.uniformLocations; + // We're using "matrix"(=local matrix) here for efficiency + // As projection doesn't require world matrix, as it doesn't have any parent or child + const matrix = entity.matrix; + const mvMatrix = mat4.create(); + mat4.multiply(mvMatrix, camera.viewMatrix, matrix); + gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix); + gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, camera.projectionMatrix); + } + updateVRUniforms(shaderProgram, mvMatrix, pMatrix, eyeIndex) { + const gl = this._gl; + const uniformLocations = shaderProgram.uniformLocations; + gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix); + gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, pMatrix); + if (uniformLocations.uEye) { + gl.uniform1f(uniformLocations.uEye, eyeIndex); + } + } + updateUniforms(shaderProgram) { + const gl = this._gl; + const uniforms = shaderProgram.uniforms; + const uniformLocations = shaderProgram.uniformLocations; + for (const key in uniforms) { + const uniform = uniforms[key]; + const location = uniformLocations[key]; + if (!uniform) continue; + if (uniform.needsUpdate) { + uniform.update(gl, location, this._isWebGL2); + } + } + } + releaseShaderResources(shaderProgram) { + const gl = this._gl; + const uniforms = shaderProgram.uniforms; + for (const key in uniforms) { + const uniform = uniforms[key]; + if (!uniform) continue; + if (uniform.needsUpdate) { + uniform.destroy(gl); + } + } + gl.deleteProgram(shaderProgram.program); + } + useProgram(shaderProgram) { + const gl = this._gl; + gl.useProgram(shaderProgram.program); + } + createProgram(vertexShader, fragmentShader) { + const gl = this._gl; + const program = gl.createProgram(); + const vs = this._compileShader(gl.VERTEX_SHADER, vertexShader); + const fs = this._compileShader(gl.FRAGMENT_SHADER, fragmentShader); + gl.attachShader(program, vs); + gl.attachShader(program, fs); + gl.bindAttribLocation(program, 0, "position"); + gl.bindAttribLocation(program, 1, "uv"); + gl.linkProgram(program); + if (this._debug && !gl.getProgramParameter(program, gl.LINK_STATUS)) { + let shaderLog = null; + if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) { + shaderLog = gl.getShaderInfoLog(vs); + } else if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) { + shaderLog = gl.getShaderInfoLog(fs); + } + throw new View360Error(ERROR.MESSAGES.FAILED_LINKING_PROGRAM(gl.getProgramInfoLog(program), shaderLog), ERROR.CODES.FAILED_LINKING_PROGRAM); + } + gl.deleteShader(vs); + gl.deleteShader(fs); + return program; + } + createWebGLTexture(texData) { + const gl = this._gl; + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texData.wrapS); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texData.wrapT); + if (!texData.isVideo() && this._isWebGL2) { + const gl2 = gl; + gl2.texStorage2D(gl2.TEXTURE_2D, 1, gl2.RGBA8, texData.width, texData.height); + } + return texture; + } + createWebGLCubeTexture(texData, size) { + const gl = this._gl; + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, texData.wrapS); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, texData.wrapT); + if (this._isWebGL2) { + const gl2 = gl; + gl2.texStorage2D(gl2.TEXTURE_CUBE_MAP, 1, gl2.RGBA8, size, size); + } + return texture; + } + makeXRCompatible() { + return __awaiter(this, void 0, void 0, function* () { + const gl = this._gl; + const attributes = gl.getContextAttributes(); + if (attributes && attributes.xrCompatible !== true) { + yield gl.makeXRCompatible(); + } + }); + } + bindXRLayer(session) { + const gl = this._gl; + const xrLayer = new XRWebGLLayer(session, gl); + session.updateRenderState({ + baseLayer: xrLayer + }); + } + bindXRFrame(frame) { + const gl = this._gl; + const session = frame.session; + const baseLayer = session.renderState.baseLayer; + gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer); + } + useDefaultFrameBuffer() { + const gl = this._gl; + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + } + _createBuffer() { + return this._gl.createBuffer(); + } + _deleteBuffer(buffer) { + return this._gl.deleteBuffer(buffer); + } + _createNativeVAO() { + const gl = this._gl; + if (this._isWebGL2) { + return gl.createVertexArray(); + } else { + const ext = this._extensions.vao; + return (ext === null || ext === void 0 ? void 0 : ext.createVertexArrayOES()) || null; + } + } + _bindNativeVAO(vao) { + const gl = this._gl; + if (this._isWebGL2) { + gl.bindVertexArray(vao); + } else { + const ext = this._extensions.vao; + ext === null || ext === void 0 ? void 0 : ext.bindVertexArrayOES(vao); + } + } + _deleteNativeVAO(vao) { + const gl = this._gl; + if (this._isWebGL2) { + gl.deleteVertexArray(vao); + } else { + const ext = this._extensions.vao; + ext === null || ext === void 0 ? void 0 : ext.deleteVertexArrayOES(vao); + } + } + _supplyGeometryData(vao, shaderProgram) { + const geometry = vao.geometry; + this._supplyIndiciesData(geometry.indicies, vao.buffers.indicies); + this._supplyAttributeData(geometry.vertices, shaderProgram.program, "position", vao.buffers.position); + this._supplyAttributeData(geometry.uvs, shaderProgram.program, "uv", vao.buffers.uv); + } + _unbindBuffers() { + const gl = this._gl; + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + gl.bindBuffer(gl.ARRAY_BUFFER, null); + } + _supplyIndiciesData(indicies, buffer) { + const gl = this._gl; + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicies.data, gl.STATIC_DRAW); + } + _supplyAttributeData(attribute, program, name, buffer) { + const gl = this._gl; + const attribLocation = gl.getAttribLocation(program, name); + // Attribute not used + if (attribLocation < 0) return; + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData(gl.ARRAY_BUFFER, attribute.data, gl.STATIC_DRAW); + gl.vertexAttribPointer(attribLocation, attribute.itemSize, gl.FLOAT, false, 0, 0); + gl.enableVertexAttribArray(attribLocation); + } + _compileShader(type, src) { + const gl = this._gl; + const shader = gl.createShader(type); + gl.shaderSource(shader, src); + gl.compileShader(shader); + return shader; + } + _getCommonUniformLocations(program) { + const gl = this._gl; + return { + uMVMatrix: gl.getUniformLocation(program, "uMVMatrix"), + uPMatrix: gl.getUniformLocation(program, "uPMatrix") + }; + } + _getContext(canvas) { + const webglIdentifiers = ["webgl2", "webgl", "experimental-webgl", "webkit-3d", "moz-webgl"]; + let context = null; + let isWebGL2 = false; + const contextAttributes = { + preserveDrawingBuffer: false, + antialias: false + }; + const onWebglContextCreationError = e => e.statusMessage; + canvas.addEventListener(EVENTS$1.CONTEXT_CREATE_ERROR, onWebglContextCreationError); + for (const identifier of webglIdentifiers) { + try { + context = canvas.getContext(identifier, contextAttributes); + isWebGL2 = identifier === "webgl2"; + } catch (t) {} // eslint-disable-line no-empty + if (context) { + break; + } + } + canvas.removeEventListener(EVENTS$1.CONTEXT_CREATE_ERROR, onWebglContextCreationError); + if (!context) { + throw new View360Error(ERROR.MESSAGES.WEBGL_NOT_SUPPORTED, ERROR.CODES.WEBGL_NOT_SUPPORTED); + } + return { + gl: context, + isWebGL2 + }; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Projection renderer, based on WebGL + * @ko WebGL 기반의 프로젝션 렌더러 + * @since 4.0.0 + */ +class WebGLRenderer { + /** + * Canvas element + * @ko 캔버스 엘리먼트 + * @since 4.0.0 + */ + get canvas() { + return this._canvas; + } + /** + * Canvas's width (`devicePixelRatio` is not applied) + * @ko 캔버스의 보이는 너비 (`devicePixelRatio`가 적용되지 않은) + * @since 4.0.0 + */ + get width() { + return this._elementSize.x; + } + /** + * Canvas's height (`devicePixelRatio` is not applied) + * @ko 캔버스의 높이 (`devicePixelRatio`가 적용되지 않은) + * @since 4.0.0 + */ + get height() { + return this._elementSize.y; + } + /** + * Current `devicePixelRatio` value. + * @ko 현재 `devicePixelRatio` 값. + * @since 4.0.0 + * @example + * ```js + * cosnt renderingWidth = view360.renderer.width * view360.renderer.pixelRatio; + * ``` + */ + get pixelRatio() { + return this._pixelRatio; + } + /** + * Width / height ratio (= width / height) + * @ko 너비 / 높이의 비율 (= width / height) + * @since 4.0.0 + * @example + * ```js + * const aspect = view360.renderer.width / view360.renderer.pixelRatio; + * assert(aspect === view360.renderer.aspect); + * ``` + */ + get aspect() { + return this._elementSize.x / this._elementSize.y; + } + /** + * Create new instance + * @ko 새 인스턴스를 생성합니다. + * @param canvas - Canvas element {@ko 캔버스 엘리먼트} + * @param debug - Whether to enable WebGL debugging {@ko WebGL debug 활성화 여부 } + */ + constructor(canvas, debug) { + this._canvas = canvas; + this._elementSize = { + x: 0, + y: 0 + }; + this._pixelRatio = 1; + this.ctx = new WebGLContext(canvas, debug); + } + /** + * Destroy instance and release all resources. + * @ko 인스턴스를 제거하고 사용된 리소스를 전부 해제합니다. + * @since 4.0.0 + */ + destroy() { + const canvas = this._canvas; + this.ctx.destroy(); + canvas.width = 1; + canvas.height = 1; + } + /** + * Resize canvas and renew inner size cache. + * @ko 캔버스의 크기를 재계산해서 내부의 사이즈 캐시값을 갱신합니다. + * @since 4.0.0 + */ + resize() { + const canvas = this._canvas; + const canvasSize = this._elementSize; + const devicePixelRatio = window.devicePixelRatio; + canvasSize.x = canvas.clientWidth; + canvasSize.y = canvas.clientHeight; + canvas.width = canvasSize.x * devicePixelRatio; + canvas.height = canvasSize.y * devicePixelRatio; + this._pixelRatio = devicePixelRatio; + this.ctx.resize(); + } + /** + * Render projection + * @ko 프로젝션을 렌더링합니다. + * @param projection - Projection to render {@ko 렌더링할 프로젝션} + * @param cameraa - Camera instance {@ko 카메라의 인스턴스} + * @since 4.0.0 + */ + render(projection, camera) { + const ctx = this.ctx; + const mesh = projection.getMesh(); + if (ctx.lost || !mesh) return; + ctx.clear(); + ctx.useProgram(mesh.program); + ctx.updateCommonUniforms(mesh, camera, mesh.program); + projection.update(camera); + ctx.updateUniforms(mesh.program); + ctx.draw(mesh.vao, mesh.program); + } + /** + * Render VR frame, only used for rendering frames inside VR sessions. + * @ko VR 프레임을 렌더링합니다. VR 세션 진입 도중에만 사용됩니다. + * @internal + * @param projection - Projection to render {@ko 렌더링할 프로젝션} + * @param vr - Instance of XRManager {@ko XRManager의 인스턴스} + * @param frame - VR frame {@ko VR 프레임} + * @since 4.0.0 + */ + renderVR(projection, vr, frame) { + const ctx = this.ctx; + const mesh = projection.getMesh(); + const eyeParams = vr.getEyeParams(frame); + if (!eyeParams || !mesh) return; + ctx.bindXRFrame(frame); + ctx.useProgram(mesh.program); + ctx.updateUniforms(mesh.program); + eyeParams.forEach((eye, eyeIndex) => { + const viewport = eye.viewport; + // We're using "mesh.matrix"(=local matrix) here for efficiency + // As projection doesn't require world matrix, as it doesn't have any parent or child + const mvMatrix = mat4.multiply(mat4.create(), eye.vMatrix, mesh.matrix); + ctx.viewport(viewport.x, viewport.y, viewport.width, viewport.height); + ctx.updateVRUniforms(mesh.program, mvMatrix, eye.pMatrix, eyeIndex); + ctx.draw(mesh.vao, mesh.program); + }); + } +} + +/** + * Panorama 360 image viewer + * @ko 파노라마 360 이미지 뷰어 + * @since 4.0.0 + * @see View360Options + * @see View360Events + */ +class View360 extends Component { + /** + * Root element (`.view360-container`) + * @ko 루트 엘리먼트 (`.view360-container`) + * @since 4.0.0 + * @readonly + * @example + * ```html + *
+ * + *
+ * ``` + * ```ts + * import View360 from "@egjs/view360"; + * + * const viewer = new View360("#viewer"); + * console.log(viewer.rootEl); // Element with id "viewer" + * ``` + */ + get rootEl() { + return this._rootEl; + } + /** + * Projection renderer. + * @ko 프로젝션 렌더러. + * @since 4.0.0 + * @readonly + */ + get renderer() { + return this._renderer; + } + /** + * Projection camera. + * @ko 프로젝션 카메라. + * @since 4.0.0 + * @readonly + */ + get camera() { + return this._camera; + } + /** + * Rotate/Zoom Controller. + * @ko 회전/줌 컨트롤러. + * @since 4.0.0 + * @readonly + */ + get control() { + return this._control; + } + /** + * WebXR-based VR manager. + * @ko WebXR 기반의 VR 기능 매니저 인스턴스. + * @since 4.0.0 + * @readonly + * @example + * ```ts + * // Example: Enter VR + * // This must be called on user interaction, else will be rejected. + * viewer.vr.enter(); + * ``` + */ + get vr() { + return this._vr; + } + /** + * Hotspot renderer. + * You can also change options of {@link View360Options#hotspot} with this. + * @ko 핫스팟 렌더러 인스턴스. + * {@link View360Options#hotspot} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get hotspot() { + return this._hotspot; + } + /** + * An array of plugins added. + * @ko 추가된 플러그인의 배열 + * @since 4.0.0 + * @readonly + * @example + * ```ts + * const viewer = new View360("#el_id", { + * plugins: [new ControlBar()] + * }); + * + * console.log(viewer.plugins); // [ControlBar] + * + * viewer.addPlugins(new LoadingSpinner()) // [ControlBar, LoadingSpinner]; + * ``` + */ + get plugins() { + return this._plugins; + } + /** + * A instance of {@link Projection} that currently enabled. `null` if not initialized yet. + * You should call {@link View360#load} to change panorama src or projection type. + * @ko 현재 사용중인 {@link Projection}의 인스턴스. 프로젝션을 활성화하지 않았을 경우 `null`입니다. + * 파노라마 이미지 소스나 프로젝션 타입을 변경하려면 {@link View360#load}를 호출하면 됩니다. + * @since 4.0.0 + * @readonly + * @example + * ```ts + * const viewer = new View360 + * ``` + */ + get projection() { + return this._projection; + } + set projection(val) { + if (this._initialized && val) { + this.load(val); + } else { + this._projection = val; + } + } + /** + * A boolean value whether {@link View360#init init()} is called before. + * @ko {@link View360#init init()}이 호출되었는지 여부를 가리키는 값 + * @since 4.0.0 + * @readonly + * @example + * ```ts + * const viewer = new View360("#el", { autoInit: false }); + * + * console.log(viewer.initialized); // false + * + * await viewer.init(); + * + * console.log(viewer.initialized); // true + * ``` + */ + get initialized() { + return this._initialized; + } + /** + * Instance of the Autoplay manager. + * You can also change {@link View360Options#autoplay} options with this. + * @ko Autoplay 기능의 매니저 인스턴스. + * 이 인스턴스를 통해 {@link View360Options#autoplay} 옵션을 변경하는 것도 가능합니다. + * @since 4.0.0 + * @readonly + * @example + * ```ts + * // Disable autoplay + * viewer.autoplay.disable(); + * ``` + */ + get autoplay() { + return this._autoplay; + } + /** + * When this value is `true` and {@link View360Options#projection} is set, {@link View360#init init()} will be called automatically when instance is created. + * @ko 이 값이 `true`이고, {@link View360Options#projection}이 설정되었으면, 인스턴스 생성 시점에 자동으로 {@link View360#init init()}을 호출합니다. + * @default true + * @since 4.0.0 + * @example + * ```ts + * import View360, { EquirectProjection, EVENTS } from "@egjs/view360"; + * + * // viewer.init() is called on instance creation + * // But as `init` is asynchronous, you should wait for "ready" event if you want to do something after initialization. + * const viewer = new View360("#el_id", { + * autoInit: true, + * projection: new EquirectProjection({ src: "SRC_TO_URL" }) + * }); + * + * console.log(viewer.initialized); // false, as `init` is asynchronous + * + * viewer.once(EVENTS.READY, () => { + * console.log(viewer.initialized); // true + * }); + * ``` + */ + get autoInit() { + return this._autoInit; + } + /** + * When `true`, {@link View360#resize} is called when the canvas size is changed. + * @ko `true`일 경우, 캔버스의 크기가 변경되었을 때 자동으로 {@link View360#resize}를 호출합니다. + * @default true + * @since 4.0.0 + * @see View360#useResizeObserver + * @example + * ```ts + * const viewer = new View360("#el_id", { + * autoResize: true + * }); + * + * // This can trigger `viewer.resize()` if the canvas size was not 400px + * const canvas = viewer.renderer.canvas; + * canvas.style.width = "400px"; + * ``` + */ + get autoResize() { + return this._autoResize; + } + /** + * CSS selector for canvas element to render panorama image/video. + * The canvas element should be placed inside the root element. (Dont' have to be direct child) + * @ko 파노라마 이미지/비디오를 렌더링할 canvas 엘리먼트의 CSS 선택자 + * 캔버스 엘리먼트는 루트 엘리먼트 내부에 있어야합니다. 루트 엘리먼트의 직계 자식 엘리먼트(Direct child element)일 필요는 없습니다. + * @default "canvas" + * @since 4.0.0 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * + * ```ts + * const viewer = new View360("#el_id", { + * canvasSelector: "#canvas_to_select" + * }); + * ``` + */ + get canvasSelector() { + return this._canvasSelector; + } + /** + * When `true`, it will use {@link ResizeObserver} API to detect canvas size change when {@link View360Options#autoResize} is enabled. + * @ko `true`일 때 {@link View360Options#autoResize}가 활성화되었으면, 사용 가능한 환경에서 {@link ResizeObserver} API를 사용해서 캔버스 크기 변화를 추적합니다. + * @default true + * @since 4.0.0 + */ + get useResizeObserver() { + return this._useResizeObserver; + } + /** + * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} attribute for the canvas element. + * This is necessary for the keyboard controls. + * By default, `0` will be assigned. `null` to disable. + * @ko 캔버스 엘리먼트에 적용할 {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} 어트리뷰트의 값. + * 이 값을 설정해야만 키보드 컨트롤을 사용 가능합니다. + * 기본값으로 `0`이 설정됩니다. `null`로 지정하면 `tabindex`를 설정하지 않습니다. + * @see RotateControlOptions#disableKeyboard + * @default 0 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * tabindex: 5 + * }); + * ``` + * + * ```html + * + *
+ * + *
+ * ``` + */ + get tabIndex() { + return this._tabIndex; + } + set tabIndex(val) { + const canvas = this._renderer.canvas; + this._tabIndex = val; + if (val != null) { + canvas.tabIndex = val; + } else { + canvas.removeAttribute("tabindex"); + } + } + /** + * A maximum delta time between frames in seconds. + * It can prevent camera or control changing too fast when frame being late. + * @ko 프레임간 시간 차이의 최대값. (초 단위) + * 퍼포먼스 등의 이유로 프레임 렌더링이 늦어졌을 때, 화면이 갑작스럽게 바뀌는 것을 막아줍니다. + * @default 1 / 30 + * @since 4.0.0 + */ + get maxDeltaTime() { + return this._animator.maxDeltaTime; + } + set maxDeltaTime(val) { + this._animator.maxDeltaTime = val; + } + /** + * Enable WebGL debugging. Setting this to `true` can decrease performance. + * This is used internally on developing View360. + * @ko WebGL 디버깅을 활성화합니다. 이 값을 `true`로 할 경우 성능이 하락할 수 있습니다. + * 이 옵션은 View360을 개발하기 위해 내부적으로 사용됩니다. + * @default false + */ + get debug() { + return this._debug; + } + set debug(val) { + this._debug = val; + } + // Camera options + /** + * Initial yaw (y-axis rotation) value for camera. (in degrees, °) + * As View360 uses right-handed coordinate system internally, camera will rotate counter-clockwise by this value. + * @ko 카메라의 초기 yaw(y축 회전)값 (도 단위, °) + * View360은 오른손 좌표계를 사용하기 때문에, 카메라가 해당 값만큼 시계 반대방향으로 회전합니다. + * @default 0 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * initialYaw: 30 + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.yaw); // 30 + * }); + * ``` + */ + get initialYaw() { + return this._camera.initialYaw; + } + set initialYaw(val) { + this._camera.initialYaw = val; + } + /** + * Initial pitch (x-axis rotation) value for camera. (in degrees, °) + * As View360 uses right-handed coordinate system internally, positive value will make camera to look upside, while negative value will look down. + * @ko 카메라의 초기 pitch(x축 회전)값 (도 단위, °) + * View360은 오른손 좌표계를 사용하기 때문에, 양(+)의 값은 카메라가 위를 보게 하고, 음(-)의 값은 카메라가 아래를 보게 합니다. + * @default 0 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * initialPitch: 60 + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.pitch); // 60 + * }); + * ``` + */ + get initialPitch() { + return this._camera.initialPitch; + } + set initialPitch(val) { + this._camera.initialPitch = val; + } + /** + * Initial zoom value for camera. + * Setting this value to `2` will enlarge panorama 200% by width. + * @ko 카메라의 초기 줌 값. + * 이 값을 `2`로 설정할 경우 파노라마 이미지를 가로 기준 200%만큼 확대합니다. + * @default 1 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * initialZoom: 2 + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.zoom); // 2 + * }); + * ``` + */ + get initialZoom() { + return this._camera.initialZoom; + } + set initialZoom(val) { + this._camera.initialZoom = val; + } + /** + * Restrict yaw(y-axis rotation) range. (in degrees, °) + * @ko yaw(y축 회전) 범위를 제한합니다. (도 단위, °) + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * yawRange: [-30, 30] + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.yaw); // 0 + * viewer.camera.lookAt({ yaw: 60 }); + * console.log(viewer.camera.yaw); // 30 + * }); + * ``` + */ + get yawRange() { + return this._camera.yawRange; + } + set yawRange(val) { + this._camera.yawRange = val; + if (this._projection) this._projection.updateCamera(this._camera); + } + /** + * Restrict pitch(x-axis rotation) range. (in degrees, °) + * @ko pitch(x축 회전) 범위를 제한합니다. (도 단위, °) + * @default null + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * pitchRange: [-45, 45] + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.pitch); // 0 + * viewer.camera.lookAt({ pitch: 60 }); + * console.log(viewer.camera.pitch); // 45 + * }); + * ``` + */ + get pitchRange() { + return this._camera.pitchRange; + } + set pitchRange(val) { + this._camera.pitchRange = val; + if (this._projection) this._projection.updateCamera(this._camera); + } + /** + * Restrict camera zoom range. + * If `null`, a default zoom range from `0.6` to `10` will be used. + * @ko 카메라 줌 범위를 제한합니다. + * `null`일 경우 기본값으로 `0.6`에서 `10`의 범위를 사용합니다. + * @default null + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * zoomRange: [0.5, 4] + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.zoom); // 1 + * viewer.camera.lookAt({ zoom: 6 }); + * console.log(viewer.camera.zoom); // 4 + * }); + * ``` + */ + get zoomRange() { + return this._camera.zoomRange; + } + set zoomRange(val) { + this._camera.zoomRange = val; + if (this._projection) this._projection.updateCamera(this._camera); + } + /** + * Camera's horizontal FOV(Field of View). (in degrees, °) + * @ko 카메라의 수평 FOV(Field of View) 값. (도 단위, °) + * @default 90 + * @since 4.0.0 + * @example + * ```ts + * // Init with fov: 120 + * const viewer = new View360("#el_id", { fov: 120 }); + * + * // Back to 90 + * viewer.fov = 90; + * ``` + */ + get fov() { + return this._camera.fov; + } + set fov(val) { + const camera = this._camera; + const control = this._control; + camera.fov = val; + camera.updateMatrix(); + control.sync(); + } + // Control options + /** + * A control for camera rotation. + * You can also change options of {@link View360Options#rotate} with this. + * @ko 카메라 회전을 담당하는 컨트롤. + * {@link View360Options#rotate} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get rotate() { + return this._control.rotate; + } + /** + * A control for camera zoom. + * You can also change options of {@link View360Options#zoom} with this. + * @ko 카메라 줌을 담당하는 컨트롤. + * {@link View360Options#zoom} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get zoom() { + return this._control.zoom; + } + /** + * A control for camera rotation with gyroscope input. + * You can also change options of {@link View360Options#gyro} with this. + * @ko 자이로스코프를 통한 카메라 회전을 담당하는 컨트롤. + * {@link View360Options#gyro} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get gyro() { + return this._control.gyro; + } + /** + * Apply CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor} by current state of input when using mouse. + * If `true`, this will add CSS style to canvas element. It'll apply `cursor: "grab"` by default and `cursor: "grabbing"` when holding the mouse button. + * @ko 마우스 사용시 CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor}값을 자동으로 변경할지 여부. + * `true`일 경우 기본 상태에서 `cursor: "grab"`을, 입력 도중에 `cursor: "grabbing"`을 캔버스에 적용합니다. + * @default true + * @since 4.0.0 + */ + get useGrabCursor() { + return this._control.useGrabCursor; + } + set useGrabCursor(val) { + this._control.useGrabCursor = val; + } + /** + * Disable context menu which pops up on mouse right click. + * @ko 마우스 우클릭시 표시되는 컨텍스트 메뉴를 비활성화합니다. + * @default false + * @since 4.0.0 + */ + get disableContextMenu() { + return this._control.disableContextMenu; + } + set disableContextMenu(val) { + this._control.disableContextMenu = val; + } + /** + * If `true`, enables scroll on mobile(touch) devices on canvas. + * :::caution + * When this option is enabled, users must swipe horizontally first then vertically to change view up or down. + * ::: + * @ko `true`로 설정할 경우, 모바일(터치) 환경의 캔버스 영역 내에서 스크롤을 가능하게 합니다. + * :::caution + * 이 값을 활성화할 경우, 사용자가 카메라 뷰를 위/아래로 바꾸기 위해서는 먼저 가로로 스와이프한 이후에 세로로 스와이프해야만 합니다. + * ::: + * @since 4.0.0 + * @default true + */ + get scrollable() { + return this._control.scrollable; + } + set scrollable(val) { + this._control.scrollable = val; + } + /** + * If `true`, enables scroll by mouse wheel on canvas. + * :::caution + * When this option is enabled, zoom by mouse wheel will be disabled. + * ::: + * @ko `true`로 설정할 경우, 캔버스 영역 내에서 마우스 휠을 이용한 페이지 스크롤이 가능해집니다. + * :::caution + * 이 값을 활성화할 경우, 마우스 휠을 통한 줌이 불가능하게 됩니다. + * ::: + * @since 4.0.0 + * @default false + */ + get wheelScrollable() { + return this._control.wheelScrollable; + } + set wheelScrollable(val) { + this._control.wheelScrollable = val; + } + /** + * Create new instance of View360 + * @ko View360의 새로운 인스턴스를 생성합니다 + * @param root - Root element(`.view360-container`) to mount View360 + * Can be either a CSS selector or HTMLElement. + * {@ko View360을 마운트할 루트 엘리먼트, CSS 셀렉터나 HTMLElement를 지정 가능합니다.} + * @param options - Options to apply + * {@ko 적용할 옵션들} + * @example + * ```ts + * import View360, { EquirectProjection } from "@egjs/view360"; + * + * // Create new View360 instance + * const viewer = new View360("#id-of-a-container", { + * projection: new EquirectProjection({ + * src: "URL_TO_PANORAMA_IMAGE_OR_VIDEO", + * }) + * }); + * ``` + */ + constructor(root, { + projection = null, + initialYaw = 0, + initialPitch = 0, + initialZoom = 1, + yawRange = null, + pitchRange = null, + zoomRange = null, + fov = 90, + useGrabCursor = true, + disableContextMenu = false, + rotate = true, + zoom = true, + gyro = false, + scrollable = true, + wheelScrollable = false, + autoplay = false, + hotspot = {}, + autoInit = true, + autoResize = true, + canvasSelector = "canvas", + useResizeObserver = true, + on = {}, + plugins = [], + maxDeltaTime = 1 / 30, + tabIndex = 0, + debug = false + } = {}) { + super(); + /** + * Render a single panorama image/video frame. + * Rendering is performed automatically on demand, so you usually don't have to call this. + * Call this when a frame is not renewed after changing options. + * @ko 파노라마 이미지/비디오의 한 프레임을 렌더링합니다. + * 프레임 갱신은 보통 필요한 때에만 자동적으로 이루어지기 때문에, 보통은 이 메소드를 호출할 필요는 없습니다. + * 옵션 변경 이후에도 프레임 갱신이 이루어지지 않는다면, 이 메소드를 호출해주세요. + * @param delta Delta time in milisec. {@ko 프레임간 시간 차이, 밀리초 단위} + * @since 4.0.0 + */ + this.renderFrame = delta => { + const camera = this._camera; + const renderer = this._renderer; + const control = this._control; + const hotspot = this._hotspot; + const autoPlayer = this._autoplay; + const projection = this._projection; + if (!projection) return; + this._emit(EVENTS.BEFORE_RENDER); + if (autoPlayer.playing) { + autoPlayer.update(delta); + control.sync(); + } + if (camera.animation) { + camera.animation.update(delta); + } else { + control.update(delta); + } + renderer.render(projection, camera); + hotspot.render(camera); + if (camera.changed) { + this._emit(EVENTS.VIEW_CHANGE, { + yaw: camera.yaw, + pitch: camera.pitch, + zoom: camera.zoom, + quaternion: [camera.quaternion[0], camera.quaternion[1], camera.quaternion[2], camera.quaternion[3]] + }); + } + camera.onFrameRender(); + this._emit(EVENTS.RENDER); + }; + this._renderFrameOnDemand = delta => { + var _a; + const camera = this._camera; + const control = this._control; + const autoplay = this._autoplay; + const texture = (_a = this._projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (!this._initialized || !texture) return; + if (!camera.animation && !control.animating && !autoplay.playing && !texture.isVideo()) return; + this.renderFrame(delta); + }; + this._renderVRFrame = (_delta, frame) => { + const vr = this._vr; + const projection = this._projection; + const renderer = this._renderer; + if (!projection) return; + this._emit(EVENTS.BEFORE_RENDER); + renderer.renderVR(projection, vr, frame); + this._emit(EVENTS.RENDER); + }; + this._rootEl = getElement(root); + this._plugins = plugins; + this._initialized = false; + // Options + this._autoInit = autoInit; + this._autoResize = autoResize; + this._canvasSelector = canvasSelector; + this._useResizeObserver = useResizeObserver; + this._tabIndex = tabIndex; + this._debug = debug; + // Core components + const canvas = findCanvas(this._rootEl, canvasSelector); + this._renderer = new WebGLRenderer(canvas, debug); + this._camera = new Camera({ + initialYaw, + initialPitch, + initialZoom, + fov, + yawRange, + pitchRange, + zoomRange + }); + this._control = new PanoControl(canvas, this._camera, { + useGrabCursor, + scrollable, + wheelScrollable, + disableContextMenu, + rotate, + zoom, + gyro + }); + this._animator = new FrameAnimator(maxDeltaTime); + this._autoplay = new Autoplay(this, canvas, autoplay); + this._projection = projection; + this._autoResizer = new AutoResizer(useResizeObserver, () => this.resize()); + this._vr = new XRManager(this._renderer.ctx); + this._hotspot = new HotspotRenderer(this._rootEl, this._renderer, hotspot); + this._addEventHandlers(on); + if (projection && autoInit) { + this.init(); + } + } + /** + * Destroy instance and release all resources. + * @ko 인스턴스를 제거하고 모든 리소스를 해제합니다. + * @since 4.0.0 + */ + destroy() { + this._camera.destroy(); + this._animator.stop(); + this._renderer.destroy(); + this._control.destroy(); + this._autoResizer.disable(); + if (this._projection) { + this._projection.releaseAllResources(this._renderer.ctx); + this._projection = null; + } + this._plugins.forEach(plugin => plugin.destroy(this)); + this._initialized = false; + } + /** + * Initialize inner components and load projection src. + * @ko 내부 컴포넌트들을 초기화하고 프로젝션 소스를 로드합니다. + * @since 4.0.0 + */ + init() { + return __awaiter(this, void 0, void 0, function* () { + if (!this._projection) { + throw new View360Error(ERROR.MESSAGES.PROVIDE_PROJECTION_FIRST, ERROR.CODES.PROVIDE_PROJECTION_FIRST); + } + const renderer = this._renderer; + const camera = this._camera; + const control = this._control; + const animator = this._animator; + const hotspot = this._hotspot; + const projection = this._projection; + const canvas = renderer.canvas; + this._bindComponentEvents(); + renderer.ctx.init(); + this._resizeComponents(); + camera.updateMatrix(); + if (this._autoResize) { + this._autoResizer.enable(canvas); + } + if (!this._autoplay.enableBlocked) { + this._autoplay.enable(); + } + this._plugins.forEach(plugin => { + plugin.init(this); + }); + const texture = yield this._loadTexture(projection); + this._applyProjection(projection, texture, null); + hotspot.refresh(); + animator.start(this._renderFrameOnDemand); + yield control.enable(); + if (this._tabIndex != null && !canvas.hasAttribute("tabIndex")) { + canvas.tabIndex = this._tabIndex; + } + this._initialized = true; + this.renderFrame(0); + this._emit(EVENTS.READY); + }); + } + /** + * Load new panorama image/video and display it. + * This will {@link View360#init init()} View360 if it's not initialized yet. + * @ko 새로운 파노라마 이미지 혹은 비디오를 로드하고 표시합니다. + * 만약 View360이 아직 초기화되지 않았다면, {@link View360#init init()}을 호출합니다. + * @param projection - Projection & video options for new source. {@ko 새로운 파노라마 이미지/비디오에 적용할 옵션들} + * @returns `Promise` if load was successful. {@ko 프로젝션 로드에 성공했을 경우 `Promise`를 반환합니다. } + * @since 4.0.0 + * @example + * ```ts + * // Change to video + * viewer.load({ + * src: "URL_TO_NEW_VIDEO", + * video: true + * }); + * ``` + */ + load(projection) { + return __awaiter(this, void 0, void 0, function* () { + if (!projection) return false; + if (this._initialized) { + const texture = yield this._loadTexture(projection); + this._applyProjection(projection, texture, this._projection); + this.renderFrame(0); + } else { + // Should update internal options before init + this._projection = projection; + this.init(); + } + return true; + }); + } + /** + * Refresh component's size by current + * @ko View360이 내부적으로 캐시하고 있는 엘리먼트 크기를 현재 크기로 갱신합니다. + * @since 4.0.0 + */ + resize() { + if (!this._initialized) return; + this._resizeComponents(); + // To prevent flickering, render immediately after resizing components + this.renderFrame(0); + const { + width, + height + } = this._renderer; + this._emit(EVENTS.RESIZE, { + width, + height + }); + } + /** + * Add new plugins + * @ko 새로운 플러그인을 추가합니다. + * @param plugins Plugins to add {@ko 추가할 플러그인들} + * @see View360Options#plugins + * @since 4.0.0 + * @example + * ```ts + * // Add a single plugin + * viewer.addPlugins(new ControlBar()); + * + * // Add multiple plugins + * viewer.addPlugins(new ControlBar(), new LoadingSpinner()); + * ``` + */ + addPlugins(...plugins) { + if (this._initialized) { + plugins.forEach(plugin => { + plugin.init(this); + }); + } + this._plugins.push(...plugins); + } + /** + * Remove plugins. + * @ko 플러그인을 제거합니다. + * @param plugins Plugins to remove {@ko 제거할 플러그인들} + * @since 4.0.0 + * @example + * ```ts + * // Remove a single plugin + * viewer.removePlugins(plugin1); + * + * // Remove multiple plugins + * viewer.removePlugins(plugin2, plugin3); + * ``` + */ + removePlugins(...plugins) { + plugins.forEach(plugin => { + const pluginIdx = this._plugins.indexOf(plugin); + if (pluginIdx < 0) return; + plugin.destroy(this); + this._plugins.splice(pluginIdx, 1); + }); + } + _emit(eventName, ...params) { + const evtParams = params ? params[0] : {}; + this.trigger(eventName, Object.assign({ + type: eventName, + target: this + }, evtParams)); + } + _applyProjection(projection, texture, prevProjection) { + const camera = this._camera; + const control = this._control; + const renderer = this._renderer; + // Remove previous projection + if (prevProjection) { + prevProjection.releaseAllResources(this._renderer.ctx); + } + projection.applyTexture(renderer.ctx, texture); + projection.updateCamera(camera); + projection.updateControl(control); + this._projection = projection; + this._emit(EVENTS.PROJECTION_CHANGE, { + projection + }); + } + _loadTexture(projection) { + return __awaiter(this, void 0, void 0, function* () { + const contentLoader = new TextureLoader(); + const { + src, + video + } = projection; + this._emit(EVENTS.LOAD_START, { + src, + video + }); + const texture = yield contentLoader.load(src, video); + this._emit(EVENTS.LOAD, { + src, + video + }); + return texture; + }); + } + _resizeComponents() { + const renderer = this._renderer; + const camera = this._camera; + const control = this._control; + renderer.resize(); + camera.resize(renderer.width, renderer.height); + control.resize(renderer.width, renderer.height); + } + _addEventHandlers(events) { + // Bind option "on" + Object.keys(events).forEach(evtName => { + this.on(evtName, events[evtName]); + }); + } + _bindComponentEvents() { + // Bind internal component events + const root = this._rootEl; + const control = this._control; + const animator = this._animator; + const renderer = this._renderer; + const vr = this._vr; + const controlEventsToPropagate = [CONTROL_EVENTS.STATIC_CLICK, CONTROL_EVENTS.INPUT_START, CONTROL_EVENTS.INPUT_END]; + controlEventsToPropagate.forEach(evtName => { + control.rotate.on(evtName, evt => { + this._emit(evtName, evt); + }); + control.zoom.on(evtName, evt => { + this._emit(evtName, evt); + }); + }); + vr.on(EVENTS.VR_START, evt => { + root.classList.add(DEFAULT_CLASS.IN_VR); + animator.changeContext(evt.session); + animator.start(this._renderVRFrame); + this._emit(EVENTS.VR_START); + }); + vr.on(EVENTS.VR_END, () => { + root.classList.remove(DEFAULT_CLASS.IN_VR); + renderer.ctx.useDefaultFrameBuffer(); + animator.changeContext(window); + animator.start(this._renderFrameOnDemand); + this.resize(); + this._emit(EVENTS.VR_END); + }); + } +} +/** + * Current version string of the View360 + * @ko View360의 현재 버젼 문자열 + * @since 4.0.0 + * @readonly + * @example + * ```ts + * // If the installed version of the View360 is v4.0.0, View360.VERSION is equal to "4.0.0" + * console.log(View360.VERSION) // 4.0.0 + * ``` + */ +View360.VERSION = "4.0.0-beta.4"; + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Base class for 3D objects + * @ko 3D 오브젝트의 베이스 클래스 + * @since 4.0.0 + * @internal + */ +class Object3D { + /** + * Create new instance. + * @ko 새로운 인스턴스를 생성합니다. + */ + constructor() { + this.matrix = mat4.create(); + this.rotation = quat.create(); + this.position = vec3.fromValues(0, 0, 0); + this.scale = vec3.fromValues(1, 1, 1); + } + /** + * Update local matrix of the object. + * @ko 오브젝트의 local matrix를 갱신합니다. + * @since 4.0.0 + */ + updateMatrix() { + mat4.fromRotationTranslationScale(this.matrix, this.rotation, this.position, this.scale); + } +} + +/** + * A plugin that displays loading spinner while loading the projection. + * @ko 프로젝션 로딩중에 로딩 스피너를 보여주는 플러그인 + * @since 4.0.0 + * @category Plugin + */ +class LoadingSpinner { + /** + * Create a new instance of LoadingSpinner. {@ko LoadingSpinner의 새 인스턴스를 생성합니다.} + * @param options Options {@ko 옵션들} + */ + constructor({ + className = {} + } = {}) { + this._startLoading = ({ + target: viewer + }) => { + viewer.rootEl.appendChild(this._container); + if (viewer.initialized) { + viewer.once(EVENTS.LOAD, this._detachElements); + } else { + viewer.once(EVENTS.READY, this._detachElements); + } + }; + this._detachElements = ({ + target: viewer + }) => { + const container = this._container; + if (!container) return; + if (container.parentElement === viewer.rootEl) { + viewer.rootEl.removeChild(container); + } + }; + this.className = className; + this._container = this._createElements(); + } + init(viewer) { + viewer.on(EVENTS.LOAD_START, this._startLoading); + } + destroy(viewer) { + viewer.off(EVENTS.LOAD_START, this._startLoading); + this._detachElements({ + target: viewer + }); + } + _createElements() { + const className = Object.assign(Object.assign({}, this.className), LoadingSpinner.DEFAULT_CLASS); + const container = createElement(className.CONTAINER); + const ring = createElement(className.RING); + container.appendChild(ring); + return container; + } +} +/** + * Default class names that LoadingSpinner uses + * @ko LoadingSpinner가 사용하는 디폴트 클래스 이름 + * @since 4.0.0 + */ +LoadingSpinner.DEFAULT_CLASS = { + /** + * A class name for the container element + * @ko 컨테이너 엘리먼트의 클래스 이름 + * @since 4.0.0 + */ + CONTAINER: "view360-spinner", + /** + * A class name for the spinning ring element + * @ko 돌아가는 링 엘리먼트의 클래스 이름 + * @since 4.0.0 + */ + RING: "view360-spinner-ring" +}; + +/** + * Interface of the ControlBar items + * @ko 컨트롤바 아이템의 인터페이스 + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ +class ControlBarItem { + /** + * Create new instance of the ControlBarItem + * @ko ControlBarItem의 새로운 인스턴스를 생성합니다. + * @param options Options {@ko 옵션들} + */ + constructor(options) { + this.position = options.position; + this.order = options.order; + } +} + +const CONTROL_BAR_DEFAULT_CLASS = { + CONTROLS_ROOT: "view360-controls", + CONTROLS_BG: "view360-controls-background", + CONTROLS_MAIN: "view360-controls-main", + CONTROLS_TOP: "view360-controls-top", + CONTROLS_BOTTOM: "view360-controls-bottom", + CONTROLS_MID: "view360-controls-mid", + CONTROLS_LEFT: "view360-controls-left", + CONTROLS_RIGHT: "view360-controls-right", + CONTROLS_FLOAT_LEFT: "view360-controls-float-left", + CONTROLS_FLOAT_RIGHT: "view360-controls-float-right", + CONTROLS_BUTTON: "view360-controls-button", + PROGRESS_ROOT: "view360-controls-progress", + VOLUME_ROOT: "view360-controls-volume", + RANGE_ROOT: "view360-range", + RANGE_TRACK: "view360-range-track", + RANGE_THUMB: "view360-range-thumb", + RANGE_FILLER: "view360-range-filler", + PLAY_BUTTON: "view360-controls-play", + PAUSE_BUTTON: "view360-controls-pause", + UNMUTED_BUTTON: "view360-controls-unmuted", + MUTED_BUTTON: "view360-controls-muted", + FULLSCREEN_BUTTON: "view360-controls-fullscreen", + FULLSCREEN_EXIT_BUTTON: "view360-controls-fullscreen-exit", + VR_BUTTON: "view360-controls-vr", + GYRO_ENABLED: "view360-controls-gyro-enabled", + GYRO_DISABLED: "view360-controls-gyro-disabled", + VIDEO_TIME_DISPLAY: "view360-controls-time", + PIEVIEW_ROOT: "view360-controls-pie", + FIXED: "view360-controls-fixed", + UNAVAILABLE: "view360-controls-unavailable", + HIDDEN: "view360-controls-hidden" +}; +const CONTROL_BAR_ITEM_POSITION = { + /** + * Place control bar item floating at top-left corner + * @ko 아이템을 왼쪽 위 구석에 표시합니다. + * @since 4.0.0 + */ + TOP_LEFT: "top-left", + /** + * Place control bar item floating at top-right corner + * @ko 아이템을 오른쪽 위 구석에 표시합니다. + * @since 4.0.0 + */ + TOP_RIGHT: "top-right", + /** + * Place control bar item at upper block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 위쪽 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_TOP: "main-top", + /** + * Place control bar item at lower block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 하단 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_BOTTOM: "main-bottom", + /** + * Place control bar item at center-left block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 왼쪽 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_LEFT: "main-left", + /** + * Place control bar item at center-right block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 오른쪽 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_RIGHT: "main-right" +}; + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +class RangeControl extends Component { + /** + * + */ + constructor() { + super(); + this._onHold = ({ + srcEvent, + isTouch + }) => { + var _a; + const bbox = this._bbox; + if (!bbox) return; + const x = isTouch ? srcEvent.touches[0].pageX : srcEvent.pageX; + const elX = bbox.x + ((_a = window.scrollX) !== null && _a !== void 0 ? _a : window.pageXOffset); + const clamepdX = clamp(x, elX, elX + bbox.width); + const progress = (clamepdX - elX) / bbox.width; + this._motion.reset(clamepdX); + this.thumbEl.classList.add(this._fixedClass); + this.trigger(CONTROL_EVENTS.INPUT_START, progress); + }; + this._onChange = ({ + delta + }) => { + var _a; + const motion = this._motion; + const bbox = this._bbox; + if (!bbox) return; + motion.setNewEndByDelta(delta.x); + motion.update(1); + const elX = bbox.x + ((_a = window.scrollX) !== null && _a !== void 0 ? _a : window.pageXOffset); + const clampedX = clamp(motion.val, elX, elX + bbox.width); + const progress = (clampedX - elX) / bbox.width; + this.trigger(CONTROL_EVENTS.CHANGE, progress); + }; + this._onRelease = () => { + const bbox = this._bbox; + if (!bbox) return; + this.thumbEl.classList.remove(this._fixedClass); + this.trigger(CONTROL_EVENTS.INPUT_END); + }; + const root = document.createElement(EL_DIV); + const track = document.createElement(EL_DIV); + const thumb = document.createElement(EL_DIV); + const filler = document.createElement(EL_DIV); + root.draggable = false; + track.appendChild(filler); + track.appendChild(thumb); + root.appendChild(track); + this.rootEl = root; + this.trackEl = track; + this.thumbEl = thumb; + this.fillerEl = filler; + this._mouseInput = new MouseInput(); + this._touchInput = new TouchInput(); + this._motion = new Motion({ + duration: 1, + range: INFINITE_RANGE, + easing: x => x + }); + this._bbox = { + x: 0, + y: 0, + width: 0, + height: 0, + left: 0, + right: 0, + bottom: 0, + top: 0 + }; + this._fixedClass = CONTROL_BAR_DEFAULT_CLASS.FIXED; + } + init(className) { + const mouseInput = this._mouseInput; + const touchInput = this._touchInput; + this.rootEl.classList.add(className.RANGE_ROOT); + this.trackEl.classList.add(className.RANGE_TRACK); + this.thumbEl.classList.add(className.RANGE_THUMB); + this.fillerEl.classList.add(className.RANGE_FILLER); + this._fixedClass = className.FIXED; + mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onHold); + touchInput.on(CONTROL_EVENTS.INPUT_START, this._onHold); + mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + touchInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + mouseInput.enable(this.rootEl); + touchInput.enable(this.rootEl); + this.resize(); + } + destroy() { + const mouseInput = this._mouseInput; + const touchInput = this._touchInput; + this.rootEl.className = ""; + this.trackEl.className = ""; + this.thumbEl.className = ""; + this.fillerEl.className = ""; + mouseInput.off(); + touchInput.off(); + mouseInput.disable(); + touchInput.disable(); + } + resize() { + this._bbox = this.trackEl.getBoundingClientRect(); + } + updateStyle(progress) { + const width = this._bbox.width; + const clampedProgress = clamp(progress, 0, 1); + this.fillerEl.style.width = `${clampedProgress * 100}%`; + this.thumbEl.style.transform = `translateX(${clampedProgress * width}px)`; + } +} + +/** + * Show video progress bar. + * @ko 비디오의 프로그레스 바를 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ +class ProgressBar extends ControlBarItem { + get element() { + return this._rangeControl.rootEl; + } + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_TOP, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onResize = () => { + this._rangeControl.resize(); + }; + this._onTimeUpdate = () => { + const video = this._video; + if (!video) return; + this._currentTime = video.source.currentTime; + this._rangeControl.updateStyle(this._currentTime / this._duration); + }; + this._onDurationChange = () => { + const video = this._video; + if (!video) return; + this._duration = video.source.duration; + this._rangeControl.updateStyle(this._currentTime / this._duration); + }; + this._onHold = progress => { + const video = this._video; + const controlBar = this._controlBar; + if (!video || !controlBar) return; + const paused = video.isPaused(); + video.source.pause(); + const time = video.source.duration * progress; + video.source.currentTime = time; + video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { + detail: { + time + } + })); + controlBar.rootEl.classList.add(controlBar.className.FIXED); + this._wasPaused = !this._playPromise && paused; + }; + this._onControl = progress => { + const video = this._video; + if (!video) return; + const time = video.source.duration * progress; + video.source.currentTime = time; + video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { + detail: { + time + } + })); + }; + this._onRelease = () => { + const video = this._video; + const controlBar = this._controlBar; + if (video && controlBar) { + if (!this._wasPaused && !this._playPromise) { + this._playPromise = video.source.play().catch(() => void 0); + // This should not be chained + this._playPromise.then(() => { + this._playPromise = null; + }); + controlBar.rootEl.classList.remove(controlBar.className.FIXED); + } + } + this._wasPaused = false; + }; + this.position = position; + this.order = order; + this._controlBar = null; + this._rangeControl = new RangeControl(); + this._video = null; + this._wasPaused = false; + this._currentTime = 0; + this._duration = 0; + this._playPromise = null; + } + init(viewer, controlBar) { + var _a; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const element = this.element; + const rangeControl = this._rangeControl; + const unavailableClass = controlBar.className.UNAVAILABLE; + if (!video || !video.isVideo()) { + element.classList.add(unavailableClass); + return; + } + element.classList.remove(unavailableClass); + element.classList.add(controlBar.className.PROGRESS_ROOT); + viewer.on(EVENTS.RESIZE, this._onResize); + video.source.addEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.addEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate); + rangeControl.init(controlBar.className); + rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold); + rangeControl.on(CONTROL_EVENTS.CHANGE, this._onControl); + rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + this._video = video; + this._currentTime = video.source.currentTime; + this._duration = video.source.duration; + this._controlBar = controlBar; + rangeControl.updateStyle(this._currentTime / this._duration); + } + destroy(viewer) { + const video = this._video; + viewer.off(EVENTS.RESIZE, this._onResize); + if (video) { + video.source.removeEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.removeEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate); + } + this._rangeControl.destroy(); + this._video = null; + this._playPromise = null; + } +} + +/** + * Show video play / pause button. + * @ko 비디오 재생 / 일시정지 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ +class PlayButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const video = this._video; + if (!video) return; + if (this._paused) { + video.source.play(); + } else { + video.source.pause(); + } + }; + this._onPlay = () => { + if (!this._controlBar) return; + const element = this.element; + const className = this._controlBar.className; + element.classList.add(className.PAUSE_BUTTON); + element.classList.remove(className.PLAY_BUTTON); + element.title = "Pause Video"; + this._paused = false; + }; + this._onPause = () => { + if (!this._controlBar) return; + const element = this.element; + const className = this._controlBar.className; + element.classList.add(className.PLAY_BUTTON); + element.classList.remove(className.PAUSE_BUTTON); + element.title = "Play Video"; + this._paused = true; + }; + this.element = document.createElement(EL_BUTTON); + this._video = null; + this._paused = true; + this._controlBar = null; + } + init(viewer, controlBar) { + var _a; + const element = this.element; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const className = controlBar.className; + const unavailableClass = className.UNAVAILABLE; + if (!video || !video.isVideo()) { + element.classList.add(unavailableClass); + return; + } + element.classList.add(className.CONTROLS_BUTTON); + element.classList.remove(unavailableClass); + const paused = video.isPaused(); + this._video = video; + this._paused = paused; + this._controlBar = controlBar; + if (paused) { + this._onPause(); + } else { + this._onPlay(); + } + element.addEventListener(EVENTS$1.CLICK, this._onClick); + video.source.addEventListener(EVENTS$1.VIDEO_PLAY, this._onPlay); + video.source.addEventListener(EVENTS$1.VIDEO_PAUSE, this._onPause); + } + destroy() { + const video = this._video; + const element = this.element; + if (!video) return; + element.className = ""; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + video.source.removeEventListener(EVENTS$1.VIDEO_PLAY, this._onPlay); + video.source.removeEventListener(EVENTS$1.VIDEO_PAUSE, this._onPause); + this._video = null; + this._paused = true; + this._controlBar = null; + } +} + +/** + * Show video volume control. + * @ko 비디오 볼륨 조절 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ +class VolumeControl extends ControlBarItem { + get element() { + return this._rootEl; + } + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onResize = () => { + this._rangeControl.resize(); + this._updateDisplay(); + }; + this._onClick = () => { + const video = this._video; + if (!video || this._rootEl.disabled) return; + video.source.muted = !video.source.muted; + }; + this._onVolumeChange = () => { + const button = this._buttonEl; + const video = this._video; + const controlBar = this._controlBar; + if (!video || !controlBar) return; + const className = controlBar.className; + if (video.source.muted || video.source.volume === 0) { + button.classList.add(className.MUTED_BUTTON); + button.classList.remove(className.UNMUTED_BUTTON); + } else { + button.classList.add(className.UNMUTED_BUTTON); + button.classList.remove(className.MUTED_BUTTON); + } + this._updateDisplay(); + }; + this._onHold = progress => { + const video = this._video; + const controlBar = this._controlBar; + if (!video || !controlBar) return; + const className = controlBar.className; + video.source.volume = progress; + this._rootEl.classList.add(className.FIXED); + controlBar.containerEl.classList.add(className.FIXED); + this._updateDisplay(); + }; + this._onChange = progress => { + const video = this._video; + if (!video) return; + video.source.volume = progress; + if (progress > 0) { + video.source.muted = false; + } else { + video.source.muted = true; + } + this._updateDisplay(); + }; + this._onRelease = () => { + const controlBar = this._controlBar; + if (!controlBar) return; + const className = controlBar.className; + this._rootEl.classList.remove(className.FIXED); + controlBar.containerEl.classList.remove(className.FIXED); + }; + this._updateDisplay = () => { + const video = this._video; + const root = this._rootEl; + if (!video) return; + if (!video.hasAudio()) { + root.disabled = true; + return; + } + root.disabled = false; + const volume = video.source.muted ? 0 : video.source.volume; + this._rangeControl.updateStyle(volume); + }; + this._controlBar = null; + this._rangeControl = new RangeControl(); + this._createElements(); + this._video = null; + } + init(viewer, controlBar) { + var _a; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const root = this._rootEl; + const button = this._buttonEl; + const rangeControl = this._rangeControl; + const className = controlBar.className; + const unavailableClass = className.UNAVAILABLE; + if (!video || !video.isVideo()) { + root.classList.add(unavailableClass); + return; + } + root.classList.remove(unavailableClass); + root.classList.add(className.CONTROLS_BUTTON); + root.classList.add(className.VOLUME_ROOT); + button.classList.add(className.CONTROLS_BUTTON); + if (video.source.muted) { + button.classList.add(className.MUTED_BUTTON); + } else { + button.classList.add(className.UNMUTED_BUTTON); + } + viewer.on(EVENTS.RESIZE, this._onResize); + root.addEventListener(EVENTS$1.TRANSITION_END, this._onResize); + button.addEventListener(EVENTS$1.CLICK, this._onClick); + video.source.addEventListener(EVENTS$1.VIDEO_VOLUME_CHANGE, this._onVolumeChange); + video.source.addEventListener(EVENTS$1.VIDEO_LOADED_DATA, this._updateDisplay); + video.source.addEventListener(EVENTS$1.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay); + rangeControl.init(className); + rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold); + rangeControl.on(CONTROL_EVENTS.CHANGE, this._onChange); + rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + this._controlBar = controlBar; + this._video = video; + this._updateDisplay(); + } + destroy(viewer) { + const video = this._video; + const button = this._buttonEl; + const root = this._rootEl; + root.className = ""; + button.className = ""; + viewer.off(EVENTS.RESIZE, this._onResize); + root.removeEventListener(EVENTS$1.TRANSITION_END, this._onResize); + button.removeEventListener(EVENTS$1.CLICK, this._onClick); + if (video) { + video.source.removeEventListener(EVENTS$1.VIDEO_VOLUME_CHANGE, this._onVolumeChange); + video.source.removeEventListener(EVENTS$1.VIDEO_LOADED_DATA, this._updateDisplay); + video.source.removeEventListener(EVENTS$1.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay); + } + this._controlBar = null; + this._rangeControl.destroy(); + this._video = null; + } + _createElements() { + const root = document.createElement(EL_BUTTON); + const buttonEl = document.createElement(EL_DIV); + root.appendChild(this._rangeControl.rootEl); + root.appendChild(buttonEl); + root.title = "Toggle Mute"; + this._rootEl = root; + this._buttonEl = buttonEl; + } +} + +/** + * Show fullscreen enter / exit button. + * @ko 풀스크린 진입 / 해제 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ +class FullscreenButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const target = this._targetEl; + if (!target) return; + if (isFullscreen()) { + this._exitFullscreen(); + } else { + this._requestFullscreen(target); + } + }; + this._onFullscreenChange = () => { + const element = this.element; + const controlBar = this._controlBar; + if (!controlBar) return; + const className = controlBar.className; + if (isFullscreen()) { + element.classList.add(className.FULLSCREEN_EXIT_BUTTON); + element.classList.remove(className.FULLSCREEN_BUTTON); + } else { + element.classList.add(className.FULLSCREEN_BUTTON); + element.classList.remove(className.FULLSCREEN_EXIT_BUTTON); + } + }; + this.element = document.createElement(EL_BUTTON); + this.element.title = "Toggle Fullscreen"; + this._controlBar = null; + this._targetEl = null; + } + init(viewer, controlBar) { + const element = this.element; + const className = controlBar.className; + if (!this._fullscreenAvailable()) { + element.classList.add(className.UNAVAILABLE); + return; + } + element.classList.add(className.CONTROLS_BUTTON); + element.classList.remove(className.UNAVAILABLE); + element.addEventListener(EVENTS$1.CLICK, this._onClick); + this._addFullscreenHandlers(); + if (isFullscreen()) { + element.classList.add(className.FULLSCREEN_EXIT_BUTTON); + } else { + element.classList.add(className.FULLSCREEN_BUTTON); + } + this._controlBar = controlBar; + this._targetEl = viewer.rootEl; + } + destroy() { + const element = this.element; + element.className = ""; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + this._removeFullscreenHandlers(); + this._controlBar = null; + this._targetEl = null; + } + _fullscreenAvailable() { + return FULLSCREEN_REQUEST.some(key => !!document[key]); + } + _requestFullscreen(el) { + for (const key of FULLSCREEN_REQUEST) { + const request = el[key]; + if (request) { + request.call(el); + return; + } + } + } + _exitFullscreen() { + for (const key of FULLSCREEN_EXIT) { + const exit = document[key]; + if (exit) { + exit.call(document); + return; + } + } + } + _addFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.addEventListener(evtName, this._onFullscreenChange); + }); + } + _removeFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.removeEventListener(evtName, this._onFullscreenChange); + }); + } +} + +/** + * Show video current / total time. + * @ko 비디오의 현재 / 총 재생시간을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ +class VideoTime extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onTimeUpdate = () => { + const video = this._video; + if (!video) return; + this._currentTime = video.source.currentTime; + this._updateDisplay(); + }; + this._onDurationChange = () => { + const video = this._video; + if (!video) return; + this._duration = video.source.duration; + this._updateDisplay(); + }; + this._onCustomTimeChange = evt => { + this._currentTime = evt.detail.time; + this._updateDisplay(); + }; + this.element = document.createElement(EL_DIV); + this._video = null; + this._currentTime = 0; + this._duration = 0; + } + init(viewer, controlBar) { + var _a; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const element = this.element; + const className = controlBar.className; + if (!video || !video.isVideo()) { + element.classList.add(className.UNAVAILABLE); + return; + } + element.classList.add(className.VIDEO_TIME_DISPLAY); + element.classList.remove(className.UNAVAILABLE); + video.source.addEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.addEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange); + this._video = video; + this._currentTime = video.source.currentTime; + this._duration = video.source.duration; + this._updateDisplay(); + } + destroy() { + const video = this._video; + if (!video) return; + this.element.className = ""; + video.source.removeEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.removeEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange); + this._video = null; + } + _updateDisplay() { + const time = this._currentTime; + const timeMinute = Math.floor(time / 60); + const timeSeconds = Math.floor(time - timeMinute * 60); + const timeSecondsFormatted = timeSeconds < 10 ? `0${timeSeconds}` : timeSeconds; + const duration = this._duration; + const durationMinute = Math.floor(duration / 60); + const durationSeconds = Math.floor(duration - durationMinute * 60); + const durationSecondsFormatted = durationSeconds < 10 ? `0${durationSeconds}` : durationSeconds; + this.element.innerText = `${timeMinute}:${timeSecondsFormatted} / ${durationMinute}:${durationSecondsFormatted}`; + } +} + +/** + * Show camera direction/fov indicator. + * @ko 카메라가 향하는 방향 및 FOV를 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ +class PieView extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + resetCamera = true, + position = CONTROL_BAR_ITEM_POSITION.TOP_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const viewer = this._viewer; + const resetCamera = this.resetCamera; + if (!viewer || !resetCamera) return; + const { + yaw = viewer.initialYaw, + pitch = viewer.initialPitch, + zoom = viewer.initialZoom, + duration = 500 + } = getObjectOption(resetCamera); + viewer.camera.animateTo({ + yaw, + pitch, + zoom, + duration + }); + }; + this._updatePie = ({ + target: viewer + }) => { + const piePath = this._piePathEl; + const rangeCircle = this._rangeCircleEl; + const camera = viewer.camera; + const fov = camera.getHorizontalFov(); + const yawRange = camera.getYawRange(camera.zoom); + const halfFov = fov * 0.5; + const pieRadius = 24 * Math.PI; + const pieDeg = pieRadius * fov / 360; + const pieOffset = pieRadius * (camera.yaw + halfFov + 90) / 360; + piePath.setAttribute("stroke-dasharray", `${pieDeg} ${pieRadius - pieDeg}`); + piePath.setAttribute("stroke-dashoffset", `${pieOffset}`); + if (isFinite(yawRange.min) && isFinite(yawRange.max)) { + const radius = 45 * Math.PI; // 2 * PI * r + const min = (circulate(yawRange.min, -180, 180) - halfFov) / 360; + const max = (circulate(yawRange.max, -180, 180) + halfFov) / 360; + const rangeDiff = radius * Math.abs(max - min); + const offset = -radius * (min - 0.25); + rangeCircle.setAttribute("stroke-dasharray", `${rangeDiff} ${radius - rangeDiff}`); + rangeCircle.setAttribute("stroke-dashoffset", `${offset}`); + } else { + rangeCircle.setAttribute("stroke-dasharray", ""); + rangeCircle.setAttribute("stroke-dashoffset", ""); + } + }; + this.element = document.createElement(EL_DIV); + this.element.title = "Reset view"; + this.resetCamera = resetCamera; + this._createPieElements(); + this._viewer = null; + } + init(viewer, controlBar) { + const element = this.element; + if (!viewer.initialized) { + viewer.once(EVENTS.READY, this._updatePie); + } else { + this._updatePie({ + target: viewer + }); + } + const rootClass = controlBar.className.PIEVIEW_ROOT; + element.classList.add(rootClass); + if (this.resetCamera) { + element.addEventListener(EVENTS$1.CLICK, this._onClick); + } + viewer.on(EVENTS.VIEW_CHANGE, this._updatePie); + this._viewer = viewer; + } + destroy(viewer) { + const element = this.element; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + element.className = ""; + viewer.off(EVENTS.READY, this._updatePie); + viewer.off(EVENTS.VIEW_CHANGE, this._updatePie); + this._viewer = null; + } + _createPieElements() { + const root = this.element; + const pieSVG = document.createElementNS(SVG_NAMESPACE, "svg"); + pieSVG.setAttribute("viewBox", "0 0 48 48"); + pieSVG.setAttribute("width", "100%"); + pieSVG.setAttribute("height", "100%"); + const piePath = document.createElementNS(SVG_NAMESPACE, "circle"); + piePath.setAttribute("stroke", "currentColor"); + piePath.setAttribute("fill", "transparent"); + piePath.setAttribute("cx", "24"); + piePath.setAttribute("cy", "24"); + piePath.setAttribute("r", "12"); + piePath.setAttribute("stroke-width", "24"); + pieSVG.appendChild(piePath); + const rangeCircle = document.createElementNS(SVG_NAMESPACE, "circle"); + rangeCircle.setAttribute("stroke", "currentColor"); + rangeCircle.setAttribute("fill", "transparent"); + rangeCircle.setAttribute("cx", "24"); + rangeCircle.setAttribute("cy", "24"); + rangeCircle.setAttribute("r", "22.5"); + rangeCircle.setAttribute("stroke-width", "3"); + pieSVG.appendChild(rangeCircle); + root.appendChild(pieSVG); + this._piePathEl = piePath; + this._rangeCircleEl = rangeCircle; + } +} + +/** + * Show VR enter button. + * @ko VR 진입 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ +class VRButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const viewer = this._viewer; + if (!viewer) return; + viewer.vr.enter(); + }; + this.element = document.createElement(EL_BUTTON); + this.element.title = "Enter VR"; + this._viewer = null; + } + init(viewer, controlBar) { + const element = this.element; + const className = controlBar.className; + element.classList.add(className.UNAVAILABLE); + element.classList.add(className.VR_BUTTON); + element.classList.add(className.CONTROLS_BUTTON); + viewer.vr.isAvailable().then(available => { + if (available) { + element.classList.remove(className.UNAVAILABLE); + } + }); + element.addEventListener(EVENTS$1.CLICK, this._onClick); + this._viewer = viewer; + } + destroy() { + const element = this.element; + element.className = ""; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + this._viewer = null; + } +} + +/** + * Show gyroscope control enable / disable button + * @ko 자이로스코프 컨트롤 활성화 / 비활성화 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ +class GyroButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const viewer = this._viewer; + const controlBar = this._controlBar; + if (!viewer || !controlBar) return; + const gyroControl = viewer.control.gyro; + if (gyroControl.enabled) { + gyroControl.disable(); + } else { + GyroControl.requestSensorPermission().then(available => { + if (available) { + gyroControl.enable(); + } else { + this.element.classList.add(controlBar.className.UNAVAILABLE); + } + }); + } + }; + this._updateStyle = () => { + const element = this.element; + const viewer = this._viewer; + const controlBar = this._controlBar; + if (!viewer || !controlBar) return; + const gyroControl = viewer.control.gyro; + const className = controlBar.className; + if (gyroControl.enabled) { + element.classList.add(className.GYRO_ENABLED); + element.classList.remove(className.GYRO_DISABLED); + } else { + element.classList.add(className.GYRO_DISABLED); + element.classList.remove(className.GYRO_ENABLED); + } + }; + this.element = document.createElement(EL_DIV); + this.element.title = "Toggle gyroscope control"; + } + init(viewer, controlBar) { + const element = this.element; + const className = controlBar.className; + element.addEventListener(EVENTS$1.CLICK, this._onClick); + element.classList.add(className.CONTROLS_BUTTON); + element.classList.add(className.UNAVAILABLE); + const enableButton = () => { + element.classList.remove(className.UNAVAILABLE); + viewer.control.gyro.on(CONTROL_EVENTS.ENABLE, this._updateStyle); + viewer.control.gyro.on(CONTROL_EVENTS.DISABLE, this._updateStyle); + }; + if (sensorCanBeEnabledIOS()) { + enableButton(); + } else { + GyroControl.isAvailable().then(available => { + if (!available) return; + enableButton(); + }); + } + this._controlBar = controlBar; + this._viewer = viewer; + this._updateStyle(); + } + destroy(viewer) { + const element = this.element; + viewer.control.gyro.off(CONTROL_EVENTS.ENABLE, this._updateStyle); + viewer.control.gyro.off(CONTROL_EVENTS.DISABLE, this._updateStyle); + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + element.className = ""; + this._controlBar = null; + this._viewer = null; + } +} + +class AutoHide { + get enabled() { + return !!this._targetEl; + } + get hidden() { + return this._controlBar.containerEl.classList.contains(this._hiddenClass); + } + get _hiddenClass() { + return this._controlBar.className.HIDDEN; + } + get _fixedClass() { + return this._controlBar.className.FIXED; + } + constructor(controlBar, { + initialDelay = 3000, + delay = 0, + idleDelay: activationDelay = 3000 + }) { + this._onMouseEnter = () => { + this._isCursorInside = true; + this.show(); + }; + this._onMouseLeave = () => { + this._isCursorInside = false; + this._hideAfterDelay(); + }; + this._onMouseMove = () => { + if (!this._isFullscreen) return; + this.showTemporaliy(); + }; + this._onHold = evt => { + this._isGrabbing = true; + if (evt.pointerType === "mouse") { + this._isCursorInside = true; + } + window.addEventListener(EVENTS$1.MOUSE_UP, this._onRelease); + this.show(); + }; + this._onRelease = () => { + this._isGrabbing = false; + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onRelease); + this._hideAfterDelay(); + }; + this._onVideoPlay = () => { + const root = this._targetEl; + if (!root) return; + this._controlBar.containerEl.classList.remove(this._fixedClass); + }; + this._onVideoPause = () => { + const root = this._targetEl; + if (!root) return; + this._controlBar.containerEl.classList.add(this._fixedClass); + }; + this._onFullscreenChange = () => { + this._isFullscreen = isFullscreen(); + if (this._isFullscreen) { + this._hideAfterDelay(); + } + }; + this._controlBar = controlBar; + this._initialDelay = initialDelay; + this._delay = delay; + this._idleDelay = activationDelay; + this._timer = -1; + this._isCursorInside = false; + this._isGrabbing = false; + this._isFullscreen = false; + this._video = null; + this._targetEl = null; + } + enable(viewer) { + var _a; + if (this._targetEl) { + this.disable(viewer); + } + const initialDelay = this._initialDelay; + const root = viewer.rootEl; + this._targetEl = viewer.rootEl; + this._timer = window.setTimeout(() => { + this.hide(); + }, initialDelay); + root.addEventListener(EVENTS$1.MOUSE_DOWN, this._onHold); + root.addEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter); + root.addEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove); + root.addEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave); + this._addFullscreenHandlers(); + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (!video || !video.isVideo()) { + return; + } + if (video.isPaused()) { + this._controlBar.containerEl.classList.add(this._fixedClass); + } + video.source.addEventListener(EVENTS$1.VIDEO_PLAY, this._onVideoPlay); + video.source.addEventListener(EVENTS$1.VIDEO_PAUSE, this._onVideoPause); + this._video = video; + } + disable(viewer) { + if (!this._targetEl) return; + const controlBar = this._controlBar; + const root = viewer.rootEl; + const video = this._video; + root.removeEventListener(EVENTS$1.MOUSE_DOWN, this._onHold); + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onRelease); + root.removeEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter); + root.removeEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove); + root.removeEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave); + this._removeFullscreenHandlers(); + window.clearTimeout(this._timer); + controlBar.containerEl.classList.remove(this._fixedClass); + if (video) { + video.source.removeEventListener(EVENTS$1.VIDEO_PLAY, this._onVideoPlay); + video.source.removeEventListener(EVENTS$1.VIDEO_PAUSE, this._onVideoPause); + } + this._isCursorInside = false; + this._isGrabbing = false; + this._video = null; + this._targetEl = null; + } + show() { + this._clearHideTimer(); + this._controlBar.containerEl.classList.remove(this._hiddenClass); + } + showTemporaliy() { + this.show(); + this._hideAfterDelay(this._idleDelay); + } + hide() { + this._clearHideTimer(); + this._controlBar.containerEl.classList.add(this._hiddenClass); + } + _clearHideTimer() { + if (this._timer) { + window.clearTimeout(this._timer); + this._timer = -1; + } + } + _hideAfterDelay(delay = this._delay) { + if (this._isGrabbing || !this._isFullscreen && this._isCursorInside) return; + this._clearHideTimer(); + if (delay <= 0) { + this.hide(); + } else { + this._timer = window.setTimeout(() => { + this.hide(); + }, delay); + } + } + _addFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.addEventListener(evtName, this._onFullscreenChange); + }); + } + _removeFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.removeEventListener(evtName, this._onFullscreenChange); + }); + } +} + +class VideoControl { + constructor() { + this._onKeyDown = event => { + const video = this._video; + if (!video) return; + event.preventDefault(); + event.stopPropagation(); + const videoEl = video.source; + const keyPressed = event.keyCode != null ? DIRECTION_KEY_CODE[event.keyCode] : DIRECTION_KEY_NAME[event.key]; + switch (keyPressed) { + case "LEFT": + case "RIGHT": + return this._changeVideoTime(videoEl, keyPressed === "RIGHT"); + case "UP": + case "DOWN": + return this._changeVideoVolume(videoEl, keyPressed === "UP"); + } + const spacePressed = event.keyCode === SPACE_KEY_CODE || event.key === SPACE_KEY_NAME; + if (spacePressed) { + this._toggleVideo(video); + } + }; + } + enable(root, video) { + this._video = video; + // capture is needed for resolving conflict with keyboard control + root.addEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown, true); + } + disable(root) { + this._video = null; + root.removeEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown, true); + } + _changeVideoTime(video, forward) { + const delta = forward ? 5 : -5; + video.currentTime += delta; + video.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { + detail: { + time: video.currentTime + } + })); + } + _changeVideoVolume(video, increase) { + const delta = increase ? 0.1 : -0.1; + if (video.muted) { + video.volume = clamp(delta, 0, 1); + } else { + video.volume = clamp(video.volume + delta, 0, 1); + } + if (video.volume > 0) { + video.muted = false; + } else { + video.muted = true; + } + } + _toggleVideo(video) { + if (video.isPaused()) { + video.source.play(); + } else { + video.source.pause(); + } + } +} + +/** + * A plugin that displays extra buttons & controls that controls {@link View360}. + * @ko {@link View360}에 부가적인 버튼과 컨트롤을 추가해주는 플러그인. + * @category Plugin + * @since 4.0.0 + */ +class ControlBar { + /** + * Root element of the control bar + * @ko 컨트롤바의 루트 엘리먼트 + * @since 4.0.0 + */ + get rootEl() { + return this._rootEl; + } + /** + * Container element of the control bar + * @ko 컨트롤바의 컨테이너 엘리먼트 + * @since 4.0.0 + */ + get containerEl() { + return this._containerEl; + } + /** + * Background element of the control bar + * @ko 컨트롤바의 배경 엘리먼트 + * @since 4.0.0 + */ + get backgroundEl() { + return this._bgEl; + } + /** + * Control bar's default items created by {@link ControlBarOptions} + * @ko 주어진 {@link ControlBarOptions}에 의해 생성된 디폴트 아이템들 + * @since 4.0.0 + */ + get items() { + return this._items; + } + /** + * Custom control bar items + * @ko 커스텀 컨트롤바 아이템들을 추가합니다. + * @since 4.0.0 + */ + get customItems() { + return this._customItems; + } + /** + * Create new instance of ControlBar. + * @ko ControlBar의 새 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + autoHide, + showBackground, + clickToPlay = true, + keyboardControls = true, + progressBar = true, + playButton = true, + volumeButton = true, + fullscreenButton = true, + videoTime = true, + pieView = true, + vrButton = true, + gyroButton = true, + className = {}, + customItems = [] + } = {}) { + var _a; + this._onStaticClick = ({ + target: viewer, + isTouch + }) => { + var _a; + const autoHider = this._autoHider; + if (isTouch) { + if (!autoHider.enabled) return; + if (autoHider.hidden) { + autoHider.showTemporaliy(); + } else { + autoHider.hide(); + } + } else { + if (!this.clickToPlay) return; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (!video || !video.isVideo()) return; + if (video.isPaused()) { + video.source.play(); + } else { + video.source.pause(); + } + } + }; + this._onNewSrcLoad = ({ + target: viewer + }) => { + const items = this._items; + this._updateBackground(viewer); + this._updateAutoHide(viewer); + this._updateKeyboardHandler(viewer); + Object.keys(items).forEach(key => { + const category = items[key]; + category.forEach(item => { + item.destroy(viewer, this); + item.init(viewer, this); + }); + }); + }; + this.autoHide = autoHide; + this.showBackground = showBackground; + this.clickToPlay = clickToPlay; + this.keyboardControls = keyboardControls; + this.progressBar = progressBar; + this.playButton = playButton; + this.volumeButton = volumeButton; + this.fullscreenButton = fullscreenButton; + this.videoTime = videoTime; + this.pieView = pieView; + this.vrButton = vrButton; + this.gyroButton = gyroButton; + this.className = Object.assign(Object.assign({}, ControlBar.DEFAULT_CLASS), className); + const rootClass = (_a = className.CONTROLS_ROOT) !== null && _a !== void 0 ? _a : ControlBar.DEFAULT_CLASS.CONTROLS_ROOT; + this._rootEl = createElement(rootClass); + this._createPositionWrappers(); + this._items = Object.keys(ControlBar.POSITION).reduce((items, key) => { + items[ControlBar.POSITION[key]] = []; + return items; + }, {}); + this._customItems = customItems; + this._autoHider = new AutoHide(this, getObjectOption(autoHide)); + this._videoControl = new VideoControl(); + customItems.forEach(item => { + this._items[item.position].push(item); + }); + } + init(viewer) { + const panoRoot = viewer.rootEl; + const controlsRoot = this._rootEl; + const defaultItems = this._createDefaultItems(); + this._updateBackground(viewer); + this._updateAutoHide(viewer); + this._updateKeyboardHandler(viewer); + panoRoot.appendChild(controlsRoot); + this._addItem(viewer, defaultItems); + this._addItem(viewer, this._customItems); + viewer.on(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad); + viewer.on(EVENTS.STATIC_CLICK, this._onStaticClick); + } + destroy(viewer) { + // Remove controls root from pano root + const panoRoot = viewer.rootEl; + const controlsRoot = this._rootEl; + const items = this._items; + if (controlsRoot.parentElement === panoRoot) { + panoRoot.removeChild(controlsRoot); + } + Object.keys(items).forEach(key => { + const category = items[key]; + category.forEach(item => { + item.destroy(viewer, this); + }); + items[key] = []; + }); + this._clearItemElements(); + this._autoHider.disable(viewer); + this._videoControl.disable(panoRoot); + viewer.off(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad); + viewer.off(EVENTS.STATIC_CLICK, this._onStaticClick); + } + _addItem(viewer, items) { + for (const item of items) { + const category = this._items[item.position]; + const wrapper = this._wrapperEl[item.position]; + const nextSiblingIndex = findIndex(category, sibling => sibling.order > item.order); + if (nextSiblingIndex >= 0) { + const nextSibling = category[nextSiblingIndex].element; + category.splice(nextSiblingIndex, 0, item); + wrapper.insertBefore(item.element, nextSibling); + } else { + category.push(item); + wrapper.appendChild(item.element); + } + item.init(viewer, this); + } + } + _createPositionWrappers() { + const className = Object.assign(Object.assign({}, ControlBar.DEFAULT_CLASS), this.className); + const rootEl = this._rootEl; + // BG & FLOATING CONTROLS + const backgroundEl = createElement(className.CONTROLS_BG); + const floatLeftEl = createElement(className.CONTROLS_FLOAT_LEFT); + const floatRightEl = createElement(className.CONTROLS_FLOAT_RIGHT); + rootEl.appendChild(floatLeftEl); + rootEl.appendChild(floatRightEl); + // BOTTOM CONTROLS + const container = createElement(className.CONTROLS_MAIN); + const topWrapper = createElement(className.CONTROLS_TOP); + const bottomWrapper = createElement(className.CONTROLS_BOTTOM); + const midWrapper = createElement(className.CONTROLS_MID); + const leftControlsWrapper = createElement(className.CONTROLS_LEFT); + const rightControlsWrapper = createElement(className.CONTROLS_RIGHT); + midWrapper.appendChild(leftControlsWrapper); + midWrapper.appendChild(rightControlsWrapper); + container.appendChild(backgroundEl); + container.appendChild(topWrapper); + container.appendChild(midWrapper); + container.appendChild(bottomWrapper); + rootEl.appendChild(container); + this._bgEl = backgroundEl; + this._containerEl = container; + this._wrapperEl = { + [ControlBar.POSITION.MAIN_TOP]: topWrapper, + [ControlBar.POSITION.MAIN_LEFT]: leftControlsWrapper, + [ControlBar.POSITION.MAIN_RIGHT]: rightControlsWrapper, + [ControlBar.POSITION.MAIN_BOTTOM]: bottomWrapper, + [ControlBar.POSITION.TOP_LEFT]: floatLeftEl, + [ControlBar.POSITION.TOP_RIGHT]: floatRightEl + }; + } + _clearItemElements() { + const wrappers = Object.keys(ControlBar.POSITION).map(key => ControlBar.POSITION[key]); + // Remove all elements inside wrappers + wrappers.forEach(wrapper => { + while (wrapper.firstChild) { + wrapper.removeChild(wrapper.firstChild); + } + }); + } + _updateAutoHide(viewer) { + var _a; + const autoHide = this.autoHide; + const autoHider = this._autoHider; + if (autoHide != null) { + if (autoHide) { + autoHider.enable(viewer); + } else { + autoHider.disable(viewer); + } + } else { + // Automatically choose whether to show background by content type + const texture = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (texture && texture.isVideo()) { + // Enable auto hide when content type is video + autoHider.enable(viewer); + } else { + autoHider.disable(viewer); + } + } + } + _updateBackground(viewer) { + var _a, _b; + const background = this._bgEl; + const showBackground = this.showBackground; + const hiddenClass = (_a = this.className.HIDDEN) !== null && _a !== void 0 ? _a : ControlBar.DEFAULT_CLASS.HIDDEN; + if (showBackground != null) { + if (showBackground) { + background.classList.remove(hiddenClass); + } else { + background.classList.add(hiddenClass); + } + } else { + // Automatically choose whether to show background by content type + const texture = (_b = viewer.projection) === null || _b === void 0 ? void 0 : _b.getTexture(); + if (texture && texture.isVideo()) { + // Show bg when content type is video + background.classList.remove(hiddenClass); + } else { + background.classList.add(hiddenClass); + } + } + } + _updateKeyboardHandler(viewer) { + var _a; + const panoRoot = viewer.rootEl; + const videoControl = this._videoControl; + const texture = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (this.keyboardControls && texture && texture.isVideo()) { + videoControl.enable(panoRoot, texture); + } else { + videoControl.disable(panoRoot); + } + } + _createDefaultItems() { + const items = []; + if (this.progressBar) { + items.push(new ProgressBar(getObjectOption(this.progressBar))); + } + if (this.playButton) { + items.push(new PlayButton(getObjectOption(this.playButton))); + } + if (this.volumeButton) { + items.push(new VolumeControl(getObjectOption(this.volumeButton))); + } + if (this.gyroButton) { + items.push(new GyroButton(getObjectOption(this.gyroButton))); + } + if (this.vrButton) { + items.push(new VRButton(getObjectOption(this.vrButton))); + } + if (this.fullscreenButton) { + items.push(new FullscreenButton(getObjectOption(this.fullscreenButton))); + } + if (this.videoTime) { + items.push(new VideoTime(getObjectOption(this.videoTime))); + } + if (this.pieView) { + items.push(new PieView(getObjectOption(this.pieView))); + } + return items; + } +} +/** + * Default class names that ControlBar uses + * @ko ControlBar가 사용하는 디폴트 클래스 이름들 + * @since 4.0.0 + */ +ControlBar.DEFAULT_CLASS = CONTROL_BAR_DEFAULT_CLASS; +/** + * Constants for {@link ControlBarItemOptions#position} + * @ko {@link ControlBarItemOptions#position}에 사용 가능한 값들 + */ +ControlBar.POSITION = CONTROL_BAR_ITEM_POSITION; + +/** + * Base class for projections. + * @ko 프로젝션 베이스 클래스. + * @category Projection + * @since 4.0.0 + */ +class Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + src, + video = false + }) { + this.src = src; + this.video = video; + this._mesh = null; + } + /** + * Release all resources projection has. + * This is automatically called on projection change & View360's destroy call + * @ko 현재 갖고 있는 모든 리소스를 반환합니다. + * 이 메소드는 프로젝션 변경 및 View360의 destroy 호출 시 자동으로 호출됩니다. + * @param ctx + */ + releaseAllResources(ctx) { + var _a; + (_a = this._mesh) === null || _a === void 0 ? void 0 : _a.destroy(ctx); + } + /** + * Update camera to match projection's settings. + * @ko 현재 프로젝션의 세팅으로 카메라를 업데이트합니다. + * @param camera - Instance of the camera to update {@ko 업데이트할 카메라의 인스턴스} + * @since 4.0.0 + */ + updateCamera(camera) { + // Use default mode & no view restriction + camera.resetRange(); + } + /** + * Update control to match projection's settings. + * @ko 현재 프로젝션의 세팅으로 컨트롤을 업데이트합니다. + * @param control - Instance of the control to update {@ko 업데이트할 컨트롤의 인스턴스} + * @since 4.0.0 + */ + updateControl(control) { + control.ignoreZoomScale = false; + } + /** + * Update projection. + * @ko 현재 프로젝션 정보를 갱신합니다. + * @param camera - Instance of the camera to reference {@ko 참조할 카메라의 인스턴스} + * @since 4.0.0 + */ + update(camera) {} // eslint-disable-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars + /** + * Return active texture. + * @ko 현재 활성화된 텍스쳐를 반환합니다. + * @internal + * @since 4.0.0 + */ + getTexture() { + if (!this._mesh) return null; + return this._mesh.program.uniforms.uTexture.texture; + } + /** + * A 3D triangle mesh for projection. It's `null` until loading the `src`. + * @ko Projection을 표시하기 위한 Mesh, src를 로드하기 전까지는 `null`입니다. + * @since 4.0.0 + */ + getMesh() { + return this._mesh; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +class Uniform { + constructor() { + this.needsUpdate = true; + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + destroy(gl) { + // DO_NOTHING + } +} + +class UniformTextureCube extends Uniform { + constructor(ctx, texture, cubemapOrder) { + super(); + this.texture = texture; + this._webglTexture = ctx.createWebGLCubeTexture(texture, texture.width); + this._cubemapOrder = cubemapOrder; + } + destroy(gl) { + this.texture.destroy(); + gl.deleteTexture(this._webglTexture); + } + update(gl, location, isWebGL2) { + const texture = this.texture; + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY); + gl.uniform1i(location, 0); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture); + const sources = reorderCube(texture.sources, this._cubemapOrder); + sources.forEach((src, idx) => { + if (isWebGL2) { + gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src); + } else { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src); + } + }); + if (!texture.isVideo()) { + this.needsUpdate = false; + } + } +} + +/** @hidden */ +class CubeTexturePainter { + get size() { + return this._size; + } + constructor(texture, cubemapOrder) { + this.texture = texture; + this._renderingOrder = reorderCube(range(6), cubemapOrder); + const canvas = document.createElement("canvas"); + this._calcRenderingSize(); + canvas.width = this._size; + canvas.height = this._size; + this._canvas = canvas; + this._ctx = canvas.getContext("2d"); + } + destroy() { + const canvas = this._canvas; + // release memories + canvas.width = 1; + canvas.height = 1; + this._canvas = null; + } + draw(gl, isWebGL2) { + const size = this._size; + const texture = this.texture; + let surfaceIdx = 0; + for (let row = 0; row < this._row; row++) { + for (let column = 0; column < this._column; column++) { + const x = size * column; + const y = size * row; + const renderingFace = this._renderingOrder[surfaceIdx]; + this._ctx.drawImage(texture.source, x, y, size, size, 0, 0, size, size); + if (isWebGL2) { + gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas); + } else { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas); + } + surfaceIdx++; + } + } + } + _calcRenderingSize() { + const { + width, + height + } = this.texture; + const aspect = width / height; + if (aspect === 1 / 6) { + this._size = width; + this._row = 6; + this._column = 1; + } else if (aspect === 6) { + this._size = height; + this._row = 1; + this._column = 6; + } else if (aspect === 2 / 3) { + this._size = width * 0.5; + this._row = 3; + this._column = 2; + } else { + this._size = width / 3; + this._row = 2; + this._column = 3; + } + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +class UniformCanvasCube extends Uniform { + get texture() { + return this._painter.texture; + } + constructor(ctx, texture, cubemapOrder) { + super(); + this._painter = new CubeTexturePainter(texture, cubemapOrder); + this._webglTexture = ctx.createWebGLCubeTexture(texture, this._painter.size); + } + destroy(gl) { + gl.deleteTexture(this._webglTexture); + this._painter.destroy(); + } + update(gl, location, isWebGL2) { + const texture = this.texture; + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + gl.uniform1i(location, 0); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture); + this._painter.draw(gl, isWebGL2); + if (!texture.isVideo()) { + this.needsUpdate = false; + } + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * @hidden + */ +class TriangleMesh extends Object3D { + constructor(vao, program) { + super(); + this.vao = vao; + this.program = program; + } + destroy(ctx) { + ctx.releaseVAO(this.vao); + ctx.releaseShaderResources(this.program); + } +} + +class ShaderProgram { + constructor(ctx, vertexShader, fragmentShader, uniforms) { + this.program = ctx.createProgram(vertexShader, fragmentShader); + this.uniforms = uniforms; + this.uniformLocations = ctx.getUniformLocations(this.program, uniforms); + } +} + +/** + * @hidden + */ +class VertexData { + /** */ + constructor(data, itemSize) { + this.data = data; + this.itemSize = itemSize; + this.count = data.length / itemSize; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * @hidden + */ +class Geometry { + /** */ + constructor(vertices, indicies, uvs) { + this.vertices = new VertexData(new Float32Array(vertices), 3); + this.indicies = new VertexData(new Uint16Array(indicies), 1); + this.uvs = new VertexData(new Float32Array(uvs), 2); + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * @hidden + */ +class CubeGeometry extends Geometry { + constructor({ + order, + rotateUV + }) { + const vertices = [ + // back + 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, + // front + -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, + // up + -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, + // down + -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, + // right + 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, + // left + -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1]; + const indicies = [0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23]; + const oneThird = 1 / 3; + const coords = []; + for (let r = 1; r >= 0; r--) { + for (let c = 0; c < 3; c++) { + const coord = [c * oneThird, r * 0.5, (c + 1) * oneThird, r * 0.5, (c + 1) * oneThird, (r + 1) * 0.5, c * oneThird, (r + 1) * 0.5]; + coords.push(coord); + } + } + if (rotateUV) { + rotateUV.forEach((degree, idx) => { + if (degree === ROTATE.ZERO) return; + const coord = coords[idx]; + let newOrder; + if (degree === ROTATE.CW_90) { + newOrder = [1, 2, 3, 0]; + } else if (degree === ROTATE.CCW_90) { + newOrder = [3, 0, 1, 2]; + } else { + newOrder = [2, 3, 0, 1]; + } + const newCoords = Array(coord.length); + for (let uvIdx = 0; uvIdx < coord.length / 2; uvIdx++) { + newCoords[uvIdx * 2 + 0] = coord[newOrder[uvIdx] * 2 + 0]; + newCoords[uvIdx * 2 + 1] = coord[newOrder[uvIdx] * 2 + 1]; + } + coords[idx] = newCoords; + }); + } + const uvs = reorderCube(coords, order, "BFUDRL").reduce((acc, val) => acc.concat(val), []); + super(vertices, indicies, uvs); + } +} + +var vs$3 = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec3 vPos;void main(){vPos=position;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}"; // eslint-disable-line + +var fs$3 = "#define GLSLIFY 1\nuniform samplerCube uTexture;varying highp vec3 vPos;void main(){gl_FragColor=textureCube(uTexture,vec3(vPos.x,vPos.y,-vPos.z));}"; // eslint-disable-line + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Projection based on cubemap images, accepts both multiple or single images. + * @ko 큐브맵 이미지 기반의 프로젝션, 단일 혹은 여러 장의 이미지를 모두 사용 가능합니다. + * @since 4.0.0 + * @category Projection + */ +class CubemapProjection extends Projection { + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param options Options {@ko Options} + */ + constructor(options) { + super(options); + const { + cubemapOrder = "RLUDFB", + cubemapFlipX = false + } = options; + this._cubemapOrder = cubemapOrder; + this._cubemapFlipX = cubemapFlipX; + } + applyTexture(ctx, texture) { + const cubemapOrder = this._cubemapOrder; + const cubemapFlipX = this._cubemapFlipX; + const uniforms = { + uTexture: texture.isCube() ? new UniformTextureCube(ctx, texture, cubemapOrder) : new UniformCanvasCube(ctx, texture, cubemapOrder) + }; + const geometry = new CubeGeometry({ + order: cubemapOrder + }); + const program = new ShaderProgram(ctx, vs$3, fs$3, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + if (cubemapFlipX) { + mesh.scale[0] = -1; + } + mesh.updateMatrix(); + this._mesh = mesh; + } +} + +class UniformTexture2D extends Uniform { + constructor(ctx, texture) { + super(); + this.texture = texture; + this._webglTexture = ctx.createWebGLTexture(texture); + } + destroy(gl) { + this.texture.destroy(); + gl.deleteTexture(this._webglTexture); + } + update(gl, location, isWebGL2) { + const texture = this.texture; + const isVideo = texture.isVideo(); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY); + gl.uniform1i(location, 0); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, this._webglTexture); + if (!isVideo && isWebGL2) { + gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); + } + if (!isVideo) { + this.needsUpdate = false; + } + } +} + +var vs$2 = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec2 vUV;void main(){vUV=uv;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}"; // eslint-disable-line + +var fs$2 = "#define GLSLIFY 1\nuniform sampler2D uTexture;varying highp vec2 vUV;void main(){gl_FragColor=texture2D(uTexture,vUV.st);}"; // eslint-disable-line + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Projection based on cubemap strip. + * Slightly more efficient than {@link CubemapProjection} as it doesn't copy cubemap image to canvas while rendering. + * Accepts only single image. + * @ko 큐브맵 스트립 기반의 프로젝션. + * {@link CubemapProjection}와 달리 렌더링하는 과정에 캔버스에 이미지를 복사하는 과정이 없기 때문에 살짝 더 효율적입니다. + * 단일 이미지만 사용 가능합니다. + * @since 4.0.0 + * @category Projection + */ +class CubestripProjection extends Projection { + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param options Options {@ko Options} + */ + constructor(options) { + super(options); + const { + cubemapOrder = "RLUDFB", + cubemapFlipX = false + } = options; + this._cubemapOrder = cubemapOrder; + this._cubemapFlipX = cubemapFlipX; + } + applyTexture(ctx, texture) { + const cubemapOrder = this._cubemapOrder; + const cubemapFlipX = this._cubemapFlipX; + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture) + }; + const geometry = new CubeGeometry({ + order: cubemapOrder + }); + const program = new ShaderProgram(ctx, vs$2, fs$2, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + if (cubemapFlipX) { + mesh.scale[0] = -1; + } + mesh.updateMatrix(); + this._mesh = mesh; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * @hidden + */ +class CylinderGeometry extends Geometry { + constructor(maxTheta) { + const vertices = []; + const indicies = []; + const uvs = []; + const height = 1; + const radialSegments = 60; + const halfHeight = height * 0.5; + const heightSegments = [-halfHeight, halfHeight]; + const invRadialSegments = 1 / radialSegments; + const angleConst = maxTheta * invRadialSegments; + for (let yIdx = 0; yIdx < 2; yIdx++) { + const y = heightSegments[yIdx]; + for (let lngIdx = 0; lngIdx <= radialSegments; lngIdx++) { + const angle = lngIdx * angleConst + Math.PI - maxTheta * 0.5; + const x = Math.cos(angle); + const z = Math.sin(angle); + const u = lngIdx * invRadialSegments; + const v = yIdx; + uvs.push(u, v); + vertices.push(x, y, z); + if (yIdx === 0 && lngIdx < radialSegments) { + const a = lngIdx; + const b = a + radialSegments + 1; + indicies.push(a, b, a + 1, b, b + 1, a + 1); + } + } + } + super(vertices, indicies, uvs); + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license +*/ +/** + * Projection based on cylindrical projection. + * This can show panorama images taken from smartphones. + * @ko 원통 투영법 기반의 프로젝션. + * 일반적인 스마트폰 파노라마 사진을 표시하는데 사용될 수 있습니다. + * @since 4.0.0 + * @category Projection + */ +class CylindricalProjection extends Projection { + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param options Options {@ko Options} + */ + constructor(options) { + super(options); + const { + partial = false + } = options; + this._partial = partial; + } + applyTexture(ctx, texture) { + const partial = this._partial; + const { + width, + height + } = texture; + const aspect = width / height; + const halfVFov = 180 / aspect; + const cylinderHeight = partial ? 1 : 2 * Math.tan(halfVFov * DEG_TO_RAD); + const cylinderTheta = partial ? aspect : 2 * Math.PI; + const geometry = new CylinderGeometry(cylinderTheta); + const program = new ShaderProgram(ctx, vs$2, fs$2, { + uTexture: new UniformTexture2D(ctx, texture) + }); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + mesh.scale[1] = cylinderHeight; + quat.identity(mesh.rotation); + quat.rotateY(mesh.rotation, mesh.rotation, -Math.PI / 2); + mesh.updateMatrix(); + this._mesh = mesh; + } + updateCamera(camera) { + super.updateCamera(camera); + const mesh = this._mesh; + if (!mesh) return; + const uTexture = mesh.program.uniforms.uTexture; + const texture = uTexture.texture; + const { + width, + height + } = texture; + const aspect = width / height; + const halfHeight = mesh.scale[1] * 0.5; + if (this._partial) { + const restrictedYaw = 0.5 * aspect * RAD_TO_DEG; + camera.restrictYawRange(-restrictedYaw, restrictedYaw); + } + const restrictedPitch = Math.atan2(halfHeight, 1) * RAD_TO_DEG; + const minZoom = Math.tan(camera.fov * DEG_TO_RAD * 0.5) / (halfHeight * camera.aspect); + camera.restrictPitchRange(-restrictedPitch, restrictedPitch); + camera.restrictZoomRange(minZoom, Infinity); + camera.restrictRenderHeight(halfHeight * 2); + } +} + +var fs$1 = "#define PI 3.14159265359\nprecision mediump float;\n#define GLSLIFY 1\nuniform sampler2D uTexture;varying highp vec2 vUV;const vec2 OPERATE_COORDS_RANGE=vec2(-1.0,1.0);const vec2 TEXTURE_COORDS_RANGE=vec2(0.0,1.0);const float ONE_THIRD=1.0/3.0;const float EAC_CONST=2.0/PI;float scale(vec2 domainRange,vec2 targetRange,float val){float unit=1.0/(domainRange[1]-domainRange[0]);return targetRange[0]+(targetRange[1]-targetRange[0])*(val-domainRange[0])*unit;}void main(void){float transformedCoordX;float transformedCoordY;float texRangeXStart=floor(vUV.s*3.)*ONE_THIRD;float texRangeYStart=floor(vUV.t*2.)*0.5;vec2 orgTextureRangeX=vec2(texRangeXStart,texRangeXStart+ONE_THIRD);vec2 orgTextureRangeY=vec2(texRangeYStart,texRangeYStart+0.5);float px=scale(orgTextureRangeX,OPERATE_COORDS_RANGE,vUV.s);float py=scale(orgTextureRangeY,OPERATE_COORDS_RANGE,vUV.t);float qu=EAC_CONST*atan(px)+0.5;float qv=EAC_CONST*atan(py)+0.5;transformedCoordX=scale(TEXTURE_COORDS_RANGE,orgTextureRangeX,qu);transformedCoordY=scale(TEXTURE_COORDS_RANGE,orgTextureRangeY,qv);gl_FragColor=texture2D(uTexture,vec2(transformedCoordX,transformedCoordY));}"; // eslint-disable-line + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Equi-Angular Cubemap Projection. + * This format is used by Youtube's 360 videos. + * @ko Equi-Angular Cubemap 프로젝션. + * 이 포맷은 주로 Youtube의 360 비디오에 사용됩니다. + * @since 4.0.0 + * @category Projection + */ +class EquiangularProjection extends Projection { + applyTexture(ctx, texture) { + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture) + }; + const geometry = new CubeGeometry({ + order: "LFRDBU", + rotateUV: [ROTATE.ZERO, ROTATE.ZERO, ROTATE.ZERO, ROTATE.CW_90, ROTATE.CCW_90, ROTATE.CW_90] + }); + const program = new ShaderProgram(ctx, vs$2, fs$1, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * @hidden + */ +class SphereGeometry extends Geometry { + /** */ + constructor() { + // const radius = 1; + const widthSegments = 60; + const heightSegments = 60; + const ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI; + const uvs = []; + const vertices = []; + const indicies = []; + let latIdx; + let lngIdx; + for (latIdx = 0; latIdx <= widthSegments; latIdx++) { + const theta = (latIdx / widthSegments - 0.5) * Math.PI; + const sinTheta = Math.sin(theta); + const cosTheta = Math.cos(theta); + for (lngIdx = 0; lngIdx <= heightSegments; lngIdx++) { + const phi = (lngIdx / heightSegments - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN; + const sinPhi = Math.sin(phi); + const cosPhi = Math.cos(phi); + const x = cosPhi * cosTheta; + const y = sinTheta; + const z = sinPhi * cosTheta; + const u = lngIdx / heightSegments; + const v = latIdx / widthSegments; + uvs.push(u, v); + vertices.push(x, y, z); + if (lngIdx !== heightSegments && latIdx !== widthSegments) { + const a = latIdx * (heightSegments + 1) + lngIdx; + const b = a + heightSegments + 1; + indicies.push(a, a + 1, b, b, a + 1, b + 1); + } + } + } + super(vertices, indicies, uvs); + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Projection based on equirectangular projection. + * @ko 등 장방형 도법(Equirectangular projection) 기반의 프로젝션 + * @since 4.0.0 + * @category Projection + */ +class EquirectProjection extends Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor(options) { + super(options); + } + applyTexture(ctx, texture) { + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture) + }; + const geometry = new SphereGeometry(); + const program = new ShaderProgram(ctx, vs$2, fs$2, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +class UniformFloat extends Uniform { + constructor(val) { + super(); + this.val = val; + } + update(gl, location) { + gl.uniform1f(location, this.val); + this.needsUpdate = false; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * @hidden + */ +class PlaneGeometry extends Geometry { + /** */ + constructor(width = 2, height = 2, z = -1) { + const halfWidth = width * 0.5; + const halfHeight = height * 0.5; + const vertices = [-halfWidth, -halfHeight, z, halfWidth, -halfHeight, z, -halfWidth, halfHeight, z, halfWidth, halfHeight, z]; + const indicies = [0, 1, 2, 2, 1, 3]; + const uvs = [0, 0, 1, 0, 0, 1, 1, 1]; + super(vertices, indicies, uvs); + } +} + +var vs$1 = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec2 vUV;void main(){vUV=uv;gl_Position=vec4(position,1.0);}"; // eslint-disable-line + +var fs = "precision mediump float;\n#define GLSLIFY 1\nuniform sampler2D uTexture;uniform float uYaw;uniform float uPitch;uniform float uZoom;varying highp vec2 vUV;const float PI=3.1415926536;const float PI_2=PI*0.5;vec2 toStereographicUV(in vec2 uv,in vec2 center){float R=1.*uZoom;vec2 texLatLon=(uv*2.-1.)*vec2(PI,PI_2);vec2 central=(center*2.-1.)*vec2(PI,PI_2)+vec2(PI,0);float x=texLatLon.x;float y=texLatLon.y;float rou=sqrt(x*x+y*y);float c=2.0*atan(rou,R*0.5);float sin_c=sin(c);float cos_c=cos(c);float sin_cy=sin(central.y);float cos_cy=cos(central.y);float lat=asin(cos_c*sin_cy+(y*sin_c*cos_cy)/rou);float lon=central.x+atan(x*sin_c,rou*cos_cy*cos_c-y*sin_cy*sin_c);float u=(lon/PI+1.0)*0.5;float v=(lat/PI_2+1.0)*0.5;return vec2(u,v);}void main(){vec2 central=vec2(uYaw,uPitch);vec2 uv=toStereographicUV(vUV,central);gl_FragColor=texture2D(uTexture,uv);}"; // eslint-disable-line + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Projection based on so-called "Little planet" or "Tiny planet" effect. + * @ko "Little planet" 혹은 "Tiny planet"로 불리는 이펙트 기반의 프로젝션 + * @since 4.0.0 + * @category Projection + */ +class LittlePlanetProjection extends Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor(options) { + super(options); + } + applyTexture(ctx, texture) { + texture.wrapS = WebGLRenderingContext.REPEAT; + texture.wrapT = WebGLRenderingContext.REPEAT; + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture), + uYaw: new UniformFloat(0), + uPitch: new UniformFloat(0.5), + uZoom: new UniformFloat(1) + }; + const geometry = new PlaneGeometry(); + const program = new ShaderProgram(ctx, vs$1, fs, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } + updateControl(control) { + control.ignoreZoomScale = true; + } + update(camera) { + const mesh = this._mesh; + if (!mesh) return; + const uniforms = mesh.program.uniforms; + uniforms.uYaw.val = camera.yaw / 360; + // Range from 0 ~ 1 + uniforms.uPitch.val = camera.pitch / 180 + 0.5; + uniforms.uZoom.val = camera.zoom; + uniforms.uYaw.needsUpdate = true; + uniforms.uPitch.needsUpdate = true; + uniforms.uZoom.needsUpdate = true; + } +} + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +class UniformVector4Array extends Uniform { + constructor(val) { + super(); + this.val = val; + } + update(gl, location) { + gl.uniform4fv(location, this.val.reduce((arr, vector) => [...arr, ...vector], [])); + this.needsUpdate = false; + } +} + +var vs = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;uniform vec4 uTexScaleOffset[2];uniform float uEye;varying highp vec2 vUV;void main(){vec4 scaleOffset=uTexScaleOffset[int(uEye)];vUV=uv.xy*scaleOffset.xy+scaleOffset.zw;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}"; // eslint-disable-line + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ +/** + * Projection based on stereo equirectangular images. + * @ko Stereo equirectangular 이미지 기반의 프로젝션 + * @since 4.0.0 + * @category Projection + */ +class StereoEquiProjection extends Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor(options) { + super(options); + this._mode = options.mode; + } + applyTexture(ctx, texture) { + let leftEye; + let rightEye; + switch (this._mode) { + case StereoEquiProjection.MODE.LEFT_RIGHT: + leftEye = [0.5, 1, 0, 0]; + rightEye = [0.5, 1, 0.5, 0]; + break; + default: + // Default, uses "top_bottom" + leftEye = [1, 0.5, 0, 0]; + rightEye = [1, 0.5, 0, 0.5]; + } + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture), + uEye: new UniformFloat(0), + uTexScaleOffset: new UniformVector4Array([leftEye, rightEye]) + }; + const geometry = new SphereGeometry(); + const program = new ShaderProgram(ctx, vs, fs$2, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } +} +/** + * Available stereoscopic modes + * @ko 사용가능한 스테레오스코픽 모드들 + * @since 4.0.0 + */ +StereoEquiProjection.MODE = { + /** + * @ko 이미지가 왼쪽/오른쪽으로 구성되어있을 경우 + * @since 4.0.0 + */ + LEFT_RIGHT: "left_right", + /** + * @ko 이미지가 위/아래로 구성되어있을 경우 + * @since 4.0.0 + */ + TOP_BOTTOM: "top_bottom" +}; + +/** + * @hidden + */ +const withMethods = (prototype, attr) => { + [Component.prototype, View360.prototype].forEach(proto => { + Object.getOwnPropertyNames(proto).filter(name => name.charAt(0) !== "_" && name !== "constructor").forEach(name => { + const descriptor = Object.getOwnPropertyDescriptor(proto, name); + if (descriptor.value) { + // Public Function + Object.defineProperty(prototype, name, { + value: function (...args) { + return descriptor.value.call(this[attr], ...args); + } + }); + } else { + const getterDescriptor = {}; + if (descriptor.get) { + getterDescriptor.get = function () { + var _a; + return this[attr] && ((_a = descriptor.get) === null || _a === void 0 ? void 0 : _a.call(this[attr])); + }; + } + if (descriptor.set) { + getterDescriptor.set = function (...args) { + var _a; + return (_a = descriptor.set) === null || _a === void 0 ? void 0 : _a.call(this[attr], ...args); + }; + } + Object.defineProperty(prototype, name, getterDescriptor); + } + }); + }); +}; + +/** + * @hidden + */ +const getValidProps = propsObj => { + return Object.keys(propsObj).reduce((props, propName) => { + if (propsObj[propName] != null) { + props[propName] = propsObj[propName]; + } + return props; + }, {}); +}; + +const VIEW360_METHODS = ["destroy", "init", "load", "resize", "addPlugins", "removePlugins", "renderFrame", +// @egjs/component methods +"on", "hasOn", "once", "off", "trigger"]; + +/* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + +export { AutoResizer, Autoplay, Camera, CameraAnimation, ControlBar, ControlBarItem, CubemapProjection, CubestripProjection, CylindricalProjection, DEFAULT_CLASS, EASING, ERROR_CODES, EVENTS, EquiangularProjection, EquirectProjection, FullscreenButton, GyroControl, Hotspot, HotspotRenderer, LittlePlanetProjection, LoadingSpinner, Motion, Object3D, PanoControl, PieView, PlayButton, ProgressBar, Projection, RotateControl, StereoEquiProjection, VIEW360_METHODS, VideoTime, View360Error, VolumeControl, WebGLRenderer, XRManager, ZoomControl, View360 as default, getValidProps, withMethods }; +//# sourceMappingURL=view360.esm.js.map diff --git a/demo/release/latest/dist/view360.esm.js.map b/demo/release/latest/dist/view360.esm.js.map new file mode 100644 index 000000000..86bd2e15a --- /dev/null +++ b/demo/release/latest/dist/view360.esm.js.map @@ -0,0 +1 @@ +{"version":3,"file":"view360.esm.js","sources":["../src/core/View360Error.ts","../src/const/error.ts","../src/const/browser.ts","../src/const/external.ts","../src/const/internal.ts","../src/utils.ts","../src/core/Motion.ts","../src/core/CameraAnimation.ts","../src/core/Camera.ts","../src/control/input/MouseInput.ts","../src/control/input/TouchInput.ts","../src/control/input/KeyboardInput.ts","../src/control/RotateControl.ts","../src/control/input/WheelInput.ts","../src/control/input/PinchInput.ts","../src/control/ZoomControl.ts","../src/control/input/GyroInput.ts","../src/control/GyroControl.ts","../src/control/PanoControl.ts","../src/texture/Texture.ts","../src/texture/Texture2D.ts","../src/texture/TextureVideo.ts","../src/texture/TextureCube.ts","../src/core/TextureLoader.ts","../src/core/FrameAnimator.ts","../src/core/AutoResizer.ts","../src/core/Autoplay.ts","../src/core/XRManager.ts","../src/hotspot/Hotspot.ts","../src/hotspot/HotspotRenderer.ts","../src/core/VertexArrayObject.ts","../src/core/WebGLContext.ts","../src/core/WebGLRenderer.ts","../src/View360.ts","../src/core/Object3D.ts","../src/plugin/LoadingSpinner/LoadingSpinner.ts","../src/plugin/ControlBar/ControlBarItem.ts","../src/plugin/ControlBar/const.ts","../src/plugin/ControlBar/RangeControl.ts","../src/plugin/ControlBar/ProgressBar.ts","../src/plugin/ControlBar/PlayButton.ts","../src/plugin/ControlBar/VolumeControl.ts","../src/plugin/ControlBar/FullscreenButton.ts","../src/plugin/ControlBar/VideoTime.ts","../src/plugin/ControlBar/PieView.ts","../src/plugin/ControlBar/VRButton.ts","../src/plugin/ControlBar/GyroButton.ts","../src/plugin/ControlBar/AutoHide.ts","../src/plugin/ControlBar/VideoControl.ts","../src/plugin/ControlBar/ControlBar.ts","../src/projection/Projection.ts","../src/uniform/Uniform.ts","../src/uniform/UniformTextureCube.ts","../src/core/CubeTexturePainter.ts","../src/uniform/UniformCanvasCube.ts","../src/core/TriangleMesh.ts","../src/core/ShaderProgram.ts","../src/core/VertexData.ts","../src/geometry/Geometry.ts","../src/geometry/CubeGeometry.ts","../src/projection/CubemapProjection.ts","../src/uniform/UniformTexture2D.ts","../src/projection/CubestripProjection.ts","../src/geometry/CylinderGeometry.ts","../src/projection/CylindricalProjection.ts","../src/projection/EquiangularProjection.ts","../src/geometry/SphereGeometry.ts","../src/projection/EquirectProjection.ts","../src/uniform/UniformFloat.ts","../src/geometry/PlaneGeometry.ts","../src/projection/LittlePlanetProjection.ts","../src/uniform/UniformVector4Array.ts","../src/projection/StereoEquiProjection.ts","../src/cfc/withMethods.ts","../src/cfc/utils.ts","../src/cfc/const.ts","../src/index.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * Error thrown by {@link View360}\n * @ko {@link View360}이 발생시킨 에러\n * @since 4.0.0\n */\nclass View360Error extends Error {\n /**\n * Error code\n * @ko 에러 코드\n * @see ERROR_CODES\n */\n public code: number;\n\n /**\n * Create new instance of View360Error\n * @ko View360Error의 인스턴스를 생성합니다.\n * @param message - Error message {@ko 에러 메시지}\n * @param code - Error code {@ko 에러 코드}\n */\n public constructor(message: string, code: number) {\n super(message);\n\n Object.setPrototypeOf(this, View360Error.prototype);\n\n this.name = \"View360Error\";\n this.code = code;\n }\n}\n\nexport default View360Error;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * Error codes of {@link View360Error}\n * @ko {@link View360Error}가 가질 수 있는 에러 코드 값들\n * @since 4.0.0\n */\nexport const ERROR_CODES = {\n /**\n * The given value's type is not expected\n * @ko 주어진 값의 타입이 잘못되었을 경우\n * @since 4.0.0\n */\n WRONG_TYPE: 0,\n /**\n * The given value is not a supported option\n * @ko 잘못된 옵션을 받았을 경우\n * @since 4.0.0\n */\n WRONG_OPTION: 1,\n /**\n * The element with given CSS selector does not exist\n * @ko 주어진 CSS 셀렉터로 엘리먼트를 찾지 못했을 경우\n * @since 4.0.0\n */\n ELEMENT_NOT_FOUND: 2,\n /**\n * Couldn't find canvas element inside the given container element.\n * @ko 컨테이너 엘리먼트 내부에서 캔버스 엘리먼트를 찾지 못했을 경우\n * @since 4.0.0\n */\n CANVAS_NOT_FOUND: 3,\n /**\n * The browser does not support WebGL\n * @ko 브라우저가 WebGL을 지원하지 않는 경우\n * @since 4.0.0\n */\n WEBGL_NOT_SUPPORTED: 4,\n /**\n * Failed creating canvas 2D context\n * @ko 캔버스 2D 컨텍스트를 생성하지 못한 경우\n * @since 4.0.0\n */\n FAILED_CREATE_CONTEXT_2D: 5,\n /**\n * `init()` is called before setting {@link View360Options#projection}\n * @ko {@link View360Options#projection}을 설정하기 전에 `init()`이 호출된 경우\n * @since 4.0.0\n */\n PROVIDE_PROJECTION_FIRST: 6,\n /**\n * Failed linking WebGL program. Only can be thrown when {@link View360Options#debug} is `true`.\n * @ko WebGL 프로그램 링크에 실패한 경우. {@link View360Options#debug}를 `true`로 설정한 경우에만 발생할 수 있습니다.\n * @since 4.0.0\n */\n FAILED_LINKING_PROGRAM: 7,\n /**\n * Arguments are not sufficient for the given property.\n * @ko 프로퍼티에 값이 충분히 주어지지 않았을 때\n * @since 4.0.0\n */\n INSUFFICIENT_ARGS: 8\n} as const;\n\nexport const MESSAGES = {\n WRONG_TYPE: (val: any, types: string[]) => `${typeof val} is not a ${types.map(type => `\"${type}\"`).join(\" or \")}.`,\n WRONG_OPTION: (val: any, optionName: string) => `Bad option: given \"${val}\" for option \"${optionName}\".`,\n ELEMENT_NOT_FOUND: (query: string) => `Element with selector \"${query}\" not found.`,\n CANVAS_NOT_FOUND: \"The canvas element was not found inside the given root element.\",\n WEBGL_NOT_SUPPORTED: \"WebGL is not supported on this browser.\",\n FAILED_CREATE_CONTEXT_2D: \"Failed to create canvas 2D context\",\n PROVIDE_PROJECTION_FIRST: \"\\\"projection\\\" should be provided before initialization.\",\n FAILED_LINKING_PROGRAM: (msg: string | null, shaderLog: string | null) => `Failed linking WebGL program - \"${msg}\\nShader compile Log: ${shaderLog}`,\n INSUFFICIENT_ARGS: (val: any, name: string) => `Insufficient arguments: given \"${val}\" for \"${name}\".`\n};\n\nexport default {\n CODES: ERROR_CODES,\n MESSAGES\n};\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nexport const EVENTS = {\n MOUSE_DOWN: \"mousedown\",\n MOUSE_MOVE: \"mousemove\",\n MOUSE_UP: \"mouseup\",\n TOUCH_START: \"touchstart\",\n TOUCH_MOVE: \"touchmove\",\n TOUCH_END: \"touchend\",\n WHEEL: \"wheel\",\n RESIZE: \"resize\",\n CONTEXT_MENU: \"contextmenu\",\n MOUSE_ENTER: \"mouseenter\",\n MOUSE_LEAVE: \"mouseleave\",\n POINTER_DOWN: \"pointerdown\",\n POINTER_MOVE: \"pointermove\",\n POINTER_UP: \"pointerup\",\n POINTER_CANCEL: \"pointercancel\",\n POINTER_ENTER: \"pointerenter\",\n POINTER_LEAVE: \"pointerleave\",\n KEY_DOWN: \"keydown\",\n KEY_UP: \"keyup\",\n LOAD: \"load\",\n ERROR: \"error\",\n CLICK: \"click\",\n DOUBLE_CLICK: \"dblclick\",\n CONTEXT_CREATE_ERROR: \"webglcontextcreationerror\",\n CONTEXT_LOST: \"webglcontextlost\",\n CONTEXT_RESTORED: \"webglcontextrestored\",\n DEVICE_ORIENTATION: \"deviceorientation\",\n DEVICE_MOTION: \"devicemotion\",\n ORIENTATION_CHANGE: \"orientationchange\",\n VIDEO_PLAY: \"play\",\n VIDEO_PAUSE: \"pause\",\n VIDEO_LOADED_DATA: \"loadeddata\",\n VIDEO_VOLUME_CHANGE: \"volumechange\",\n VIDEO_TIME_UPDATE: \"timeupdate\",\n VIDEO_DURATION_CHANGE: \"durationchange\",\n VIDEO_CAN_PLAYTHROUGH: \"canplaythrough\",\n TRANSITION_END: \"transitionend\",\n XR_END: \"end\"\n} as const;\n\nexport const EL_DIV = \"div\";\nexport const EL_BUTTON = \"button\";\n\n// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button\nexport enum MOUSE_BUTTON {\n LEFT,\n MIDDLE,\n RIGHT\n}\n\nexport const CURSOR = {\n GRAB: \"grab\",\n GRABBING: \"grabbing\",\n NONE: \"\"\n} as const;\n\nexport const KEY_DIRECTION = [\"LEFT\", \"UP\", \"RIGHT\", \"DOWN\"] as const;\nexport enum DIRECTION_KEY_CODE {\n LEFT = 37,\n UP = 38,\n RIGHT = 39,\n DOWN = 40\n}\nexport const SPACE_KEY_CODE = 32;\n\nexport const DIRECTION_KEY_NAME = {\n LEFT: \"ArrowLeft\",\n UP: \"ArrowUp\",\n RIGHT: \"ArrowRight\",\n DOWN: \"ArrowDown\"\n} as const;\nexport const SPACE_KEY_NAME = \" \";\n\nexport const FULLSCREEN_REQUEST = [\n \"requestFullscreen\",\n \"webkitRequestFullscreen\",\n \"webkitRequestFullScreen\",\n \"webkitCancelFullScreen\",\n \"mozRequestFullScreen\",\n \"msRequestFullscreen\"\n];\n\nexport const FULLSCREEN_ELEMENT = [\n \"fullscreenElement\",\n \"webkitFullscreenElement\",\n \"webkitCurrentFullScreenElement\",\n \"mozFullScreenElement\",\n \"msFullscreenElement\"\n];\n\nexport const FULLSCREEN_EXIT = [\n \"exitFullscreen\",\n \"webkitExitFullscreen\",\n \"webkitCancelFullScreen\",\n \"mozCancelFullScreen\",\n \"msExitFullscreen\"\n];\n\nexport const FULLSCREEN_CHANGE = [\n \"fullscreenchange\",\n \"webkitfullscreenchange\",\n \"mozfullscreenchange\",\n \"MSFullscreenChange\"\n];\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nexport { ERROR_CODES } from \"./error\";\n\n/**\n * Default class names\n * @ko 기본 클래스 이름들\n * @since 4.0.0\n */\nexport const DEFAULT_CLASS = {\n CONTAINER: \"view360-container\",\n CANVAS: \"view360-canvas\",\n CTX_LOST: \"view360-ctx-lost\",\n IN_VR: \"view360-vr-presenting\",\n HOTSPOT_CONTAINER: \"view360-hotspots\",\n HOTSPOT: \"view360-hotspot\",\n HOTSPOT_VISIBLE: \"view360-hotspot-visible\",\n HOTSPOT_FLIP_X: \"view360-hotspot-flip-x\",\n HOTSPOT_FLIP_Y: \"view360-hotspot-flip-y\",\n} as const;\n\n/**\n * Event names\n * @ko 이벤트 이름들\n * @since 4.0.0\n * @example\n * ```ts\n * import View360, { EVENTS } from \"@egjs/view360\";\n *\n * const viewer = new View360(\"#el_id\");\n *\n * viewer.on(EVENTS.READY, evt => {\n * console.log(\"View360 is ready!\");\n * });\n * ```\n */\nexport const EVENTS = {\n READY: \"ready\",\n LOAD_START: \"loadStart\",\n LOAD: \"load\",\n PROJECTION_CHANGE: \"projectionChange\",\n RESIZE: \"resize\",\n BEFORE_RENDER: \"beforeRender\",\n RENDER: \"render\",\n INPUT_START: \"inputStart\",\n INPUT_END: \"inputEnd\",\n VIEW_CHANGE: \"viewChange\",\n STATIC_CLICK: \"staticClick\",\n VR_START: \"vrStart\",\n VR_END: \"vrEnd\"\n} as const;\n\n/**\n * Collection of predefined easing functions\n * @ko 미리 정의된 easing 함수들\n */\nexport const EASING = {\n LINEAR: (x: number) => x,\n SINE_WAVE: (x: number) => Math.sin(x * Math.PI * 2),\n EASE_OUT_CUBIC: (x: number) => 1 - Math.pow(1 - x, 3),\n EASE_OUT_BOUNCE: (x: number): number => {\n const n1 = 7.5625;\n const d1 = 2.75;\n\n if (x < 1 / d1) {\n return n1 * x * x;\n } else if (x < 2 / d1) {\n return n1 * (x -= 1.5 / d1) * x + 0.75;\n } else if (x < 2.5 / d1) {\n return n1 * (x -= 2.25 / d1) * x + 0.9375;\n } else {\n return n1 * (x -= 2.625 / d1) * x + 0.984375;\n }\n }\n} as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { EASING } from \"./external\";\nimport { Range } from \"../type/utils\";\n\nexport const CAMERA_EVENTS = {\n CHANGE: \"change\",\n ANIMATION_END: \"animationEnd\"\n} as const;\n\nexport const CONTROL_EVENTS = {\n INPUT_START: \"inputStart\",\n CHANGE: \"change\",\n INPUT_END: \"inputEnd\",\n ENABLE: \"enable\",\n DISABLE: \"disable\",\n STATIC_CLICK: \"staticClick\"\n} as const;\n\nexport const DEG_TO_RAD = Math.PI / 180;\nexport const RAD_TO_DEG = 180 / Math.PI;\nexport const DEFAULT_EASING = EASING.EASE_OUT_CUBIC;\nexport const DEFAULT_ANIMATION_DURATION = 300;\nexport const INFINITE_RANGE: Readonly = {\n min: -Infinity, max: Infinity\n} as const;\nexport const DEFAULT_PITCH_RANGE: Readonly = {\n min: -90, max: 90\n} as const;\nexport const DEFAULT_ZOOM_RANGE: Readonly = {\n min: 0.6, max: 10\n} as const;\n\nexport enum ROTATE {\n ZERO,\n CW_90,\n CCW_90,\n CW_180\n}\n\n// Custom event name for video time change\nexport const VIDEO_TIME_CHANGE_EVENT = \"view360videotimechange\";\nexport const SVG_NAMESPACE = \"http://www.w3.org/2000/svg\";\nexport const SESSION_VR = \"immersive-vr\";\nexport const XR_REFERENCE_SPACE = \"local\";\n\nexport const EPSILON = Number.EPSILON ?? 2.220446049250313e-16;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { quat, vec3 } from \"gl-matrix\";\nimport View360Error from \"./core/View360Error\";\nimport ERROR from \"./const/error\";\nimport * as BROWSER from \"./const/browser\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"./const/internal\";\nimport { NoBoolean } from \"./type/utils\";\n\nexport const isString = (val: any): val is string => typeof val === \"string\";\nexport const isElement = (val: any): val is Element => !!val && val.nodeType === Node.ELEMENT_NODE;\n\nexport const createElement = (className: string, tag = BROWSER.EL_DIV) => {\n const el = document.createElement(tag);\n\n el.classList.add(className);\n\n return el;\n};\n\nexport const getNullableElement = (el: HTMLElement | string | null, parent?: HTMLElement): HTMLElement | null => {\n let targetEl: HTMLElement | null = null;\n\n if (isString(el)) {\n const parentEl = parent ? parent : document;\n const queryResult = parentEl.querySelector(el);\n\n if (!queryResult) {\n return null;\n }\n\n targetEl = queryResult as HTMLElement;\n } else if (isElement(el)) {\n targetEl = el;\n }\n\n return targetEl;\n};\n\nexport const getElement = (el: HTMLElement | string, parent?: HTMLElement): HTMLElement => {\n const targetEl = getNullableElement(el, parent);\n\n if (!targetEl) {\n if (isString(el)) {\n throw new View360Error(ERROR.MESSAGES.ELEMENT_NOT_FOUND(el), ERROR.CODES.ELEMENT_NOT_FOUND);\n } else {\n throw new View360Error(ERROR.MESSAGES.WRONG_TYPE(el, [\"HTMLElement\", \"string\"]), ERROR.CODES.WRONG_TYPE);\n }\n }\n\n return targetEl;\n};\n\nexport const findCanvas = (root: HTMLElement, selector: string): HTMLCanvasElement => {\n const canvas = root.querySelector(selector) as HTMLCanvasElement;\n\n if (!canvas) {\n throw new View360Error(ERROR.MESSAGES.CANVAS_NOT_FOUND, ERROR.CODES.CANVAS_NOT_FOUND);\n }\n\n return canvas;\n};\n\nexport const range = (end: number): number[] => {\n if (!end || end <= 0) {\n return [];\n }\n\n return Array.apply(0, Array(end)).map((undef, idx) => idx);\n};\n\nexport const clamp = (x: number, min: number, max: number) => Math.max(Math.min(x, max), min);\n\n// Linear interpolation between a and b\nexport const lerp = (a: number, b: number, t: number) => {\n return a * (1 - t) + b * t;\n};\n\nexport const circulate = (val: number, min: number, max: number) => {\n const size = Math.abs(max - min);\n\n if (val < min) {\n const offset = (min - val) % size;\n val = max - offset;\n } else if (val > max) {\n const offset = (val - max) % size;\n val = min + offset;\n }\n\n return val;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const merge = (target: object, ...srcs: object[]): object => {\n srcs.forEach(source => {\n Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n });\n });\n\n return target;\n};\n\nexport const findIndex = (array: T[], checker: (val: T) => boolean): number => {\n for (let idx = 0; idx < array.length; idx++) {\n if (checker(array[idx])) {\n return idx;\n }\n }\n\n return -1;\n};\n\nexport const getObjectOption = >(val?: T): NoBoolean => typeof val === \"object\" ? val : {} as any;\nexport const toVerticalFov = (fovRadian: number, aspect: number) => {\n return Math.atan(Math.tan(fovRadian * 0.5) / aspect) * 2;\n};\n\nexport const reorderCube = (arr: T[], order: string, defaultOrder = \"RLUDFB\"): T[] => {\n return defaultOrder.split(\"\")\n .map(face => order.indexOf(face))\n .map(index => arr[index]);\n};\n\nexport const isFullscreen = () => {\n if (!document) return false;\n\n for (const key of BROWSER.FULLSCREEN_ELEMENT) {\n if (document[key]) return true;\n }\n\n return false;\n};\n\nexport const sensorCanBeEnabledIOS = () => {\n return !!DeviceMotionEvent && \"requestPermission\" in DeviceMotionEvent && window.isSecureContext;\n};\n\nexport const hfovToZoom = (baseFov: number, fov: number) => {\n const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5);\n const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5);\n\n return renderingWidth / zoomedWidth;\n};\n\nexport const eulerToQuat = (out: quat, yaw: number, pitch: number, roll: number): quat => {\n quat.identity(out);\n\n const pitchThreshold = 0.01;\n const pitchClamped = clamp(pitch, -90 + pitchThreshold, 90 - pitchThreshold);\n\n quat.rotateY(out, out, yaw * DEG_TO_RAD);\n quat.rotateX(out, out, pitchClamped * DEG_TO_RAD);\n quat.rotateZ(out, out, roll * DEG_TO_RAD);\n\n return out;\n};\n\n/**\n * Extract euler angles from the quaternion, except roll(z-axis rotation)\n * @hidden\n */\nexport const quatToEuler = (quaternion: quat) => {\n const x = quaternion[0];\n const y = quaternion[1];\n const z = quaternion[2];\n const w = quaternion[3];\n const x2 = x * x;\n const y2 = y * y;\n const z2 = z * z;\n const w2 = w * w;\n\n const unit = x2 + y2 + z2 + w2;\n const test = x * w - y * z;\n\n let pitch: number, yaw: number;\n\n if (test > 0.499995 * unit) {\n // singularity at the north pole\n pitch = Math.PI / 2;\n yaw = 2 * Math.atan2(y, x);\n } else if (test < -0.499995 * unit) {\n // singularity at the south pole\n pitch = -Math.PI / 2;\n yaw = -2 * Math.atan2(y, x);\n } else {\n const view = vec3.fromValues(0, 0, 1);\n const up = vec3.fromValues(0, 1, 0);\n\n vec3.transformQuat(view, view, quaternion);\n vec3.transformQuat(up, up, quaternion);\n\n const viewXZ = Math.sqrt(view[0] * view[0] + view[2] * view[2]);\n\n pitch = Math.atan2(-view[1], viewXZ);\n yaw = Math.atan2(view[0], view[2]);\n }\n\n return {\n pitch: clamp(pitch * RAD_TO_DEG, -90, 90),\n yaw: circulate(yaw * RAD_TO_DEG, 0, 360)\n };\n};\n","/*\n * Copyright (c) 2020 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport { clamp, lerp, circulate } from \"../utils\";\nimport { Range } from \"../type/utils\";\nimport { DEFAULT_ANIMATION_DURATION, DEFAULT_EASING } from \"../const/internal\";\n\n/**\n * Interpolator between two values with duration\n * @ko 특정 시간동안 두 값을 보간해주는 보간기\n * @since 4.0.0\n */\nclass Motion {\n // Options\n private _duration: number;\n private _loop: boolean;\n private _range: Range;\n private _easing: (x: number) => number;\n\n // Internal states\n private _progress: number;\n private _val: number;\n private _start: number;\n private _end: number;\n private _activated: boolean;\n\n /**\n * Current interpolated value\n * @ko 현재 보간된 값\n * @since 4.0.0\n */\n public get val() { return this._val; }\n /**\n * Start(from) value of interpolation\n * @ko 보간 시작 값\n * @since 4.0.0\n */\n public get start() { return this._start; }\n /**\n * End(to) value of interpolation\n * @ko 보간 끝 값\n * @since 4.0.0\n */\n public get end() { return this._end; }\n /**\n * Interpolation progress value (0 ~ 1)\n * @ko 현재 보간 진행정도 (0 ~ 1)\n * @since 4.0.0\n */\n public get progress() { return this._progress; }\n /**\n * Whether the interpolation is in active state.\n * @ko 보간 진행중인지 여부. `true`일 경우 보간이 진행중입니다.\n * @since 4.0.0\n */\n public get activated() { return this._activated; }\n\n /**\n * Duration of the interpolation\n * @ko 보간할 시간\n * @since 4.0.0\n */\n public get duration() { return this._duration; }\n public set duration(val: number) { this._duration = val; }\n\n /**\n * Whether to loop interpolation on finish\n * @ko 보간이 끝난 이후에 다시 시작할지 여부\n * @since 4.0.0\n */\n public get loop() { return this._loop; }\n public set loop(val: boolean) { this._loop = val; }\n\n /**\n * Range of the interpolation\n * @ko 보간 범위\n * @since 4.0.0\n */\n public get range() { return this._range; }\n\n /**\n * Easing function of the interpolation\n * @ko 보간에 사용되는 easing function\n * @since 4.0.0\n */\n public get easing() { return this._easing; }\n public set easing(val: (x: number) => number) { this._easing = val; }\n\n /**\n * Create new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options Options {@ko 옵션들}\n * @param options.duration Duration of the interpolation {@ko 보간할 시간}\n * @param options.loop Whether to loop interpolation on finish {@ko 보간이 끝난 이후에 다시 시작할지 여부}\n * @param options.range Range of the interpolation {@ko 보간 범위}\n * @param options.loop Easing function of the interpolation {@ko 보간에 사용되는 easing function}\n */\n public constructor({\n duration = DEFAULT_ANIMATION_DURATION,\n loop = false,\n range = { min: 0, max: 1 },\n easing = DEFAULT_EASING\n } = {}) {\n this._duration = duration;\n this._loop = loop;\n this._range = range;\n this._easing = easing;\n this._activated = false;\n this.reset(0);\n }\n\n /**\n * Update motion and progress it by given deltaTime\n * @ko 주어진 deltaTime만큼 보간을 진행합니다.\n * @param deltaTime - number of milisec to update motion {@ko 보간을 진행할 시간, 밀리초 단위}\n * @returns Difference(delta) of the value from the last update. {@ko 지난 업데이트 이후의 값 변화량}\n * @since 4.0.0\n */\n public update(deltaTime: number): number {\n if (!this._activated) {\n this._val = this._end;\n return 0;\n }\n\n const start = this._start;\n const end = this._end;\n const duration = this._duration;\n const prev = this._val;\n const loop = this._loop;\n\n const nextProgress = this._progress + deltaTime / duration;\n\n this._progress = loop\n ? circulate(nextProgress, 0, 1)\n : clamp(nextProgress, 0, 1);\n\n const easedProgress = this._easing(this._progress);\n this._val = lerp(start, end, easedProgress);\n\n if (!loop && this._progress >= 1) {\n this._activated = false;\n }\n\n return this._val - prev;\n }\n\n /**\n * Set `start`, `end` to the given value and set `progress` to 0.\n * @ko 주어진 값으로 시작 지점, 끝 지점을 초기화하고 progress를 0으로 세팅합니다.\n * @param defaultVal - Value to reset {@ko 초기화할 값}\n * @since 4.0.0\n */\n public reset(defaultVal: number): void {\n const range = this._range;\n const val = clamp(defaultVal, range.min, range.max);\n this._start = val;\n this._end = val;\n this._val = val;\n this._progress = 0;\n this._activated = false;\n }\n\n /**\n * Add delta to start & end and current value.\n * @ko 현재 & 끝 및 현재 값에 주어진 값을 더합니다.\n * @param delta - Delta value to add {@ko 추가할 값}\n */\n public add(delta: number) {\n const range = this._range;\n\n this._start = clamp(this._start + delta, range.min, range.max);\n this._end = clamp(this._end + delta, range.min, range.max);\n this._val = clamp(this._val + delta, range.min, range.max);\n }\n\n /**\n * Set current value to start, and end to current value + delta, then reset progress to 0.\n * @ko 현재 값을 시작 지점으로, 그에서 delta만큼 추가된 값을 끝점으로 하고 progress를 0으로 갱신합니다.\n * @param delta - Delta value to add {@ko 추가할 값}\n */\n public setNewEndByDelta(delta: number): void {\n const range = this._range;\n\n this._start = this._val;\n this._end = clamp(this._end + delta, range.min, range.max);\n this._progress = 0;\n this._activated = true;\n }\n\n /**\n * Set new range of the interpolation.\n * @ko 보간의 범위를 변경합니다.\n * @param min - New minimum range {@ko 변경할 범위의 최소값}\n * @param max - New maximum range {@ko 변경할 범위의 최대값}\n */\n public setRange(min: number, max: number) {\n this._start = clamp(this._start, min, max);\n this._end = clamp(this._end, min, max);\n this._range = { min, max };\n }\n}\n\nexport default Motion;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { quat } from \"gl-matrix\";\nimport Camera from \"./Camera\";\nimport Motion from \"./Motion\";\nimport { DEFAULT_ANIMATION_DURATION, DEFAULT_EASING } from \"../const/internal\";\nimport { lerp } from \"../utils\";\n\ntype CameraPose = {\n rotation: quat;\n zoom: number;\n}\n\n/**\n * Animation of the {@link Camera}\n * @internal\n * @ko {@link Camera}의 애니메이션\n * @since 4.0.0\n */\nclass CameraAnimation {\n // Options\n private _camera: Camera;\n private _from: CameraPose;\n private _to: CameraPose;\n\n // Internal values\n private _motion: Motion;\n private _finishPromise: Promise;\n private _finish: () => void;\n\n /**\n * Duration of the animation\n * @ko 애니메이션 재생시간\n * @since 4.0.0\n */\n public get duration() { return this._motion.duration; }\n public set duration(val: number) { this._motion.duration = val; }\n /**\n * Easing function of the animation\n * @ko 애니메이션의 easing function\n * @since 4.0.0\n */\n public get easing() { return this._motion.easing; }\n public set easing(val: (x: number) => number) { this._motion.easing = val; }\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param camera - Camera to animate {@ko 애니메이션을 적용할 카메라}\n * @param from - Start pose {@ko 애니메이션이 시작 시점의 카메라의 회전 및 줌}\n * @param to - End pose {@ko 애니메이션이 끝났을 때 카메라의 회전 및 줌}\n * @param options - Options {@ko 옵션들}\n * @param options.duration - Animation duration {@ko 애니메이션 재생 시간}\n * @param options.easing - Animation easing function {@ko 애니메이션 easing function}\n */\n public constructor(camera: Camera, from: CameraPose, to: CameraPose, {\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING\n } = {}) {\n this._camera = camera;\n this._motion = new Motion({ duration, easing, range: { min: 0, max: 1 } });\n this._from = from;\n this._to = to;\n this._finishPromise = new Promise(resolve => {\n this._finish = resolve as () => void;\n });\n\n // Enable motion\n this._motion.setNewEndByDelta(1);\n }\n\n /**\n * Return a promise that resolved on animation end.\n * @ko 애니메이션 재생이 끝났을 때 resolve되는 Promise를 반환합니다.\n * @since 4.0.0\n */\n public getFinishPromise() {\n return this._finishPromise;\n }\n\n /**\n * Update animation by given deltaTime.\n * @ko 주어진 시간만큼 애니메이션을 업데이트합니다.\n * @param deltaTime Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n */\n public update(deltaTime: number): void {\n const camera = this._camera;\n const from = this._from;\n const to = this._to;\n const motion = this._motion;\n motion.update(deltaTime);\n\n // Progress that easing is applied\n const progress = motion.val;\n const rotation = quat.create();\n const zoom = lerp(from.zoom, to.zoom, progress);\n\n quat.slerp(rotation, from.rotation, to.rotation, progress);\n camera.rotate(rotation, zoom);\n\n if (progress >= 1) {\n this._finish();\n }\n }\n}\n\nexport default CameraAnimation;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { mat4, quat, vec3 } from \"gl-matrix\";\nimport CameraAnimation from \"./CameraAnimation\";\nimport {\n CAMERA_EVENTS,\n DEG_TO_RAD,\n INFINITE_RANGE,\n DEFAULT_PITCH_RANGE,\n RAD_TO_DEG,\n DEFAULT_ZOOM_RANGE,\n DEFAULT_EASING,\n EPSILON\n} from \"../const/internal\";\nimport {\n circulate,\n clamp,\n eulerToQuat,\n quatToEuler,\n toVerticalFov\n} from \"../utils\";\nimport { Range } from \"../type/utils\";\n\n/**\n * Events that {@link Camera} can trigger\n * @ko {@link Camera}가 트리거할 수 있는 이벤트들\n * @since 4.0.0\n */\nexport interface CameraEvents {\n /**\n * An event that fires when camera's animation stops\n * @ko 카메라 애니메이션이 멈췄을 때 트리거되는 이벤트\n * @eventName animationEnd\n * @eventOf Camera\n * @version 4.0.0\n */\n [CAMERA_EVENTS.ANIMATION_END]: {\n animation: CameraAnimation\n };\n}\n\n/**\n * Options for {@link Camera}\n * @ko {@link Camera}용 옵션들\n * @since 4.0.0\n */\nexport interface CameraOptions {\n /**\n * @copy View360#initialYaw\n */\n initialYaw: number;\n /**\n * @copy View360#initialPitch\n */\n initialPitch: number;\n /**\n * @copy View360#initialZoom\n */\n initialZoom: number;\n /**\n * @copy View360#yawRange\n */\n yawRange: Range | null;\n /**\n * @copy View360#pitchRange\n */\n pitchRange: Range | null;\n /**\n * @copy View360#zoomRange\n */\n zoomRange: Range | null;\n /**\n * @copy View360#fov\n */\n fov: number;\n}\n\n/**\n * Camera for View360\n * @ko View360용 카메라 구현체\n * @version 4.0.0\n */\nclass Camera extends Component {\n /**\n * Current yaw(y-axis rotation) value\n * @ko 현재 yaw(y축 회전) 값\n * @since 4.0.0\n */\n public yaw: number;\n /**\n * Current pitch(x-axis rotation) value\n * @ko 현재 pitch(x축 회전) 값\n * @since 4.0.0\n */\n public pitch: number;\n /**\n * Current zoom value\n * @ko 현재 줌 값\n * @since 4.0.0\n */\n public zoom: number;\n\n /**\n * @copy View360#initialYaw\n */\n public initialYaw: number;\n /**\n * @copy View360#initialPitch\n */\n public initialPitch: number;\n /**\n * @copy View360#initialPitch\n */\n public initialZoom: number;\n /**\n * @hidden\n * TODO: Please add comment for this when `rollOffset` is added\n */\n public rollOffset: number;\n\n /**\n * Current camera quaternion\n * @ko 현재 회전을 나타내는 quaternion 값\n * @since 4.0.0\n * @internal\n */\n public quaternion: quat;\n /**\n * Current camera position\n * @ko 현재 카메라 위치 좌표\n * @since 4.0.0\n * @internal\n */\n public position: vec3;\n /**\n * Active camera animation, `null` if there isn't.\n * @ko 현재 활성화된 카메라 애니메이션, 없을 경우 `null`값을 가집니다.\n * @since 4.0.0\n */\n public animation: CameraAnimation | null;\n /**\n * Camera's view matrix\n * @ko 카메라의 뷰 변환 행렬\n * @internal\n * @since 4.0.0\n */\n public viewMatrix: mat4;\n /**\n * Camera's projection matrix\n * @ko 카메라의 프로젝션 변환 행렬\n * @internal\n * @since 4.0.0\n */\n public projectionMatrix: mat4;\n\n /**\n * Camera's horizontal FOV(Field of View) value\n * @ko 카메라의 수평 FOV(Field of View) 값\n * @internal\n * @since 4.0.0\n */\n public fov: number;\n\n private _initialYawRange: Range | null;\n private _initialPitchRange: Range | null;\n private _initialZoomRange: Range | null;\n\n private _yawRange: Range | null;\n private _pitchRange: Range | null;\n private _zoomRange: Range | null;\n\n private _up: vec3;\n private _aspect: number;\n private _changed: boolean;\n private _maxRenderHeight: number;\n\n /**\n * Camera's width / height ratio\n * @ko 카메라의 가로 / 세로 비율\n * @readonly\n */\n public get aspect() { return this._aspect; }\n /**\n * Whether the camera's rotation changed from the last frame.\n * @ko 마지막 프레임 이후로 카메라의 회전값이 변경되었는지 나타내는 플래그.\n * @readonly\n */\n public get changed() { return this._changed; }\n /**\n * @copy View360#yawRange\n */\n public get yawRange() { return this._initialYawRange; }\n public set yawRange(val: Range | null) {\n this._initialYawRange = val;\n }\n /**\n * @copy View360#pitchRange\n */\n public get pitchRange() { return this._initialPitchRange; }\n public set pitchRange(val: Range | null) {\n this._initialPitchRange = val;\n }\n /**\n * @copy View360#zoomRange\n */\n public get zoomRange() { return this._initialZoomRange; }\n public set zoomRange(val: Range | null) {\n this._initialZoomRange = val;\n }\n\n /**\n * Create new instance of Camera\n * @param options - Camera options {@ko 카메라 옵션들}\n */\n public constructor({\n initialYaw,\n initialPitch,\n initialZoom,\n yawRange,\n pitchRange,\n zoomRange,\n fov\n }: CameraOptions) {\n super();\n\n this.yaw = initialYaw;\n this.pitch = initialPitch;\n this.zoom = initialZoom;\n this.rollOffset = 0;\n\n this.initialYaw = initialYaw;\n this.initialPitch = initialPitch;\n this.initialZoom = initialZoom;\n\n this.position = vec3.create();\n this.animation = null;\n\n this._up = vec3.fromValues(0, 1, 0);\n this._aspect = 1;\n\n this._initialYawRange = yawRange;\n this._initialPitchRange = pitchRange;\n this._initialZoomRange = zoomRange;\n\n this._yawRange = yawRange;\n this._pitchRange = pitchRange;\n this._zoomRange = zoomRange;\n\n this.quaternion = quat.create();\n this._updateQuaternion();\n\n this.viewMatrix = mat4.create();\n this.projectionMatrix = mat4.create();\n this.fov = fov;\n\n this._maxRenderHeight = -1;\n }\n\n /**\n * Destroy instance and detach all event listeners\n * @ko 인스턴스를 삭제하고 모든 이벤트 리스너를 삭제합니다.\n * @since 4.0.0\n */\n public destroy() {\n this.off();\n }\n\n /**\n * Refresh internal size value.\n * @ko 내부 크기값을 갱신합니다.\n * @param width - New width {@ko 변경된 너비값}\n * @param height - New height {@ko 변경된 높이값}\n * @since 4.0.0\n */\n public resize(width: number, height: number) {\n const prevAspect = this._aspect;\n\n this._aspect = width / height;\n\n if (this._aspect !== prevAspect) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation with euler values.\n * @ko 카메라 회전을 오일러 각 방향으로 변경합니다.\n * @param rotation - Rotation values {@ko 회전 값}\n * @param rotation.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값}\n * @param rotation.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값}\n * @param rotation.zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @since 4.0.0\n */\n public lookAt({\n yaw = this.yaw,\n pitch = this.pitch,\n zoom = this.zoom\n }: Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n }>) {\n const prevQuaternion = quat.clone(this.quaternion);\n const prevZoom = this.zoom;\n\n this.yaw = circulate(yaw, 0, 360);\n this.pitch = clamp(pitch, -90, 90);\n this.zoom = zoom;\n\n this._updateQuaternion();\n\n const zoomDiff = Math.abs(zoom - prevZoom);\n\n if (\n !quat.equals(this.quaternion, prevQuaternion)\n || zoomDiff >= EPSILON * 10 // ignore small changes\n ) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation with quaternion.\n * @ko 카메라 회전을 Quaternion을 이용해서 변경합니다.\n * @param rotation - Quaternion to apply {@ko 적용할 Quaternion}\n * @param zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @since 4.0.0\n */\n public rotate(rotation: quat, zoom: number = this.zoom) {\n const normalized = quat.normalize(quat.create(), rotation);\n const isSameRotation = quat.equals(this.quaternion, normalized);\n quat.copy(this.quaternion, normalized);\n\n const prevZoom = this.zoom;\n const { yaw, pitch } = quatToEuler(normalized);\n\n this.yaw = yaw;\n this.pitch = pitch;\n this.zoom = zoom;\n\n const zoomDiff = Math.abs(zoom - prevZoom);\n\n if (!isSameRotation || zoomDiff >= EPSILON * 10) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation to given euler values by the given duration.\n * @ko 카메라를 주어진 방향으로 주어진 시간동안 서서히 이동시킵니다.\n * @param options - Animation parameters {@ko 애니메이션 패러미터}\n * @param options.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값}\n * @param options.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값}\n * @param options.zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @param options.duration - Duration of the animation {@ko 애니메이션 시간}\n * @param options.easing - Easing function for the animation {@ko 애니메이션에 적용할 easing function}\n */\n public async animateTo({\n yaw = this.yaw,\n pitch = this.pitch,\n zoom = this.zoom,\n duration = 0,\n easing = DEFAULT_EASING\n }: Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n duration: number;\n easing: (x: number) => number;\n }> = {}): Promise {\n if (\n this.yaw === yaw\n && this.pitch === pitch\n && this.zoom === zoom\n ) return;\n\n const from = {\n rotation: quat.clone(this.quaternion),\n zoom: this.zoom\n };\n const to = {\n rotation: eulerToQuat(quat.create(), yaw, pitch, this.rollOffset),\n zoom\n };\n\n const animation = new CameraAnimation(this, from, to, {\n duration,\n easing\n });\n const finishPromise = animation.getFinishPromise();\n\n this.animation = animation;\n finishPromise.then(() => {\n this.animation = null;\n this.trigger(CAMERA_EVENTS.ANIMATION_END, { animation });\n });\n\n return finishPromise;\n }\n\n /**\n * @hidden\n */\n public restrictYawRange(min: number, max: number) {\n this._yawRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictPitchRange(min: number, max: number) {\n this._pitchRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictZoomRange(min: number, max: number) {\n this._zoomRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictRenderHeight(height: number) {\n this._maxRenderHeight = height;\n }\n\n /**\n * @hidden\n */\n public resetRange() {\n this._yawRange = this._initialYawRange;\n this._pitchRange = this._initialPitchRange;\n this._zoomRange = this._initialZoomRange;\n this._maxRenderHeight = -1;\n }\n\n /**\n * Get actual yaw range by the given zoom value.\n * @ko 주어진 zoom 값에 대한 실제 yaw 범위값을 반환합니다.\n * @since 4.0.0\n */\n public getYawRange(zoom: number) {\n const yawLimit = this._yawRange;\n const maxRenderHeight = this._maxRenderHeight;\n if (!yawLimit) return INFINITE_RANGE;\n\n const halfHFov = this.getHorizontalFov(zoom) * 0.5;\n let minYaw = yawLimit.min;\n let maxYaw = yawLimit.max;\n\n if (maxRenderHeight > 0) {\n const halfVFovRad = toVerticalFov(halfHFov * DEG_TO_RAD, this._aspect);\n const h = maxRenderHeight * 0.5;\n const t = Math.tan(halfVFovRad);\n const d = Math.sqrt((1 + h * h) / (1 + t * t));\n const theta = Math.atan(Math.tan(halfHFov * DEG_TO_RAD) * d) * RAD_TO_DEG;\n\n minYaw = yawLimit.min + theta;\n maxYaw = yawLimit.max - theta;\n }\n\n if (minYaw > maxYaw) {\n minYaw = 0;\n maxYaw = 0;\n }\n\n return {\n min: minYaw,\n max: maxYaw\n };\n }\n\n /**\n * Get actual pitch range by the given zoom value.\n * @ko 주어진 zoom 값에 대한 실제 pitch 범위값을 반환합니다.\n * @since 4.0.0\n */\n public getPitchRange(zoom: number) {\n const pitchLimit = this._pitchRange;\n const maxRenderHeight = this._maxRenderHeight;\n\n if (!pitchLimit) return DEFAULT_PITCH_RANGE;\n\n let minPitch = pitchLimit.min;\n let maxPitch = pitchLimit.max;\n\n if (maxRenderHeight > 0) {\n const halfVFov = this.getVerticalFov(zoom) * 0.5;\n\n minPitch = pitchLimit.min + halfVFov;\n maxPitch = pitchLimit.max - halfVFov;\n }\n\n if (minPitch > maxPitch) {\n minPitch = 0;\n maxPitch = 0;\n }\n\n return {\n min: Math.max(minPitch, -90),\n max: Math.min(maxPitch, 90)\n };\n }\n\n /**\n * Get actual zoom range in fov degrees.\n * @ko 실제 줌 범위를 fov각의 범위로 반환합니다.\n * @since 4.0.0\n */\n public getZoomRange() {\n const limit = this._zoomRange ?? DEFAULT_ZOOM_RANGE;\n\n // max (zoom in) -> minimum fov\n const minFov = this.getHorizontalFov(limit.max);\n const maxFov = this.getHorizontalFov(limit.min);\n const currentFov = this.getHorizontalFov(this.zoom);\n\n return {\n min: Math.max(minFov, 1),\n max: Math.min(maxFov, 180),\n current: currentFov\n };\n }\n\n /**\n * Return horizontal fov value when the given zoom is applied. (in degrees, °)\n * @ko 주어진 zoom 값이 적용되었을 때의 수평 fov값을 반환합니다. (도 단위, °)\n * @returns Zoomed horizontal FOV {@ko 줌이 적용된 수평 fov값}\n * @since 4.0.0\n */\n public getHorizontalFov(zoom = this.zoom) {\n return this._getZoomedHorizontalFov(zoom) * RAD_TO_DEG;\n }\n\n /**\n * Return vertical fov value when the given zoom is applied. (in degrees, °)\n * @ko 주어진 zoom 값이 적용되었을 때의 수직 fov값을 반환합니다. (도 단위, °)\n * @returns Zoomed vertical FOV {@ko 줌이 적용된 수직 fov값}\n * @since 4.0.0\n */\n public getVerticalFov(zoom = this.zoom) {\n const aspect = this._aspect;\n const hFov = this._getZoomedHorizontalFov(zoom); // In radians\n const vFov = toVerticalFov(hFov, aspect);\n\n return vFov * RAD_TO_DEG;\n }\n\n /**\n * Calculate zoom value for the given fov.\n * @ko 주어진 fov값을 zoom값으로 변환합니다.\n * @param fov horizontal fov (in degrees, °) {@ko 수평 fov 값 (도 단위, °)}\n * @since 4.0.0\n */\n public fovToZoom(fov: number) {\n const baseFov = this.fov;\n const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5);\n const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5);\n\n return renderingWidth / zoomedWidth;\n }\n\n /**\n * Update inner matrixes.\n * @ko 내부 행렬들을 업데이트합니다.\n * @internal\n * @since 4.0.0\n */\n public updateMatrix() {\n const up = this._up;\n const aspect = this._aspect;\n const viewMatrix = this.viewMatrix;\n const projMatrix = this.projectionMatrix;\n const position = this.position;\n const rotation = this.quaternion;\n\n const upDir = vec3.create();\n const viewDir = vec3.fromValues(0, 0, -1);\n vec3.transformQuat(viewDir, viewDir, rotation);\n vec3.transformQuat(upDir, up, rotation);\n\n const hFov = this._getZoomedHorizontalFov(); // In radians\n const vFov = toVerticalFov(hFov, aspect);\n\n mat4.lookAt(viewMatrix, position, viewDir, upDir);\n mat4.perspective(projMatrix, vFov, aspect, 0.1, 100);\n\n this._changed = true;\n }\n\n /**\n * @hidden\n */\n public onFrameRender() {\n this._changed = false;\n }\n\n private _updateQuaternion() {\n eulerToQuat(this.quaternion, this.yaw, this.pitch, this.rollOffset);\n }\n\n /**\n * @param zoom Current zoom value\n * @returns horizontal fov including zoom, in radian\n */\n private _getZoomedHorizontalFov(zoom = this.zoom) {\n return 2 * Math.atan(Math.tan(DEG_TO_RAD * this.fov * 0.5) / zoom);\n }\n}\n\nexport default Camera;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass MouseInput extends Component> {\n private _el: HTMLElement | null;\n private _prevPos: [number, number];\n\n public constructor() {\n super();\n\n this._el = null;\n this._prevPos = [0, 0];\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onMouseDown);\n\n this._el = element;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onMouseDown);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this._el = null;\n }\n\n private _onMouseDown = (evt: MouseEvent) => {\n const el = this._el;\n if (!el || evt.button !== BROWSER.MOUSE_BUTTON.LEFT) return;\n\n evt.preventDefault();\n\n if (el.focus) {\n el.focus();\n } else {\n window.focus();\n }\n\n this._prevPos[0] = evt.clientX;\n this._prevPos[1] = evt.clientY;\n\n window.addEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.addEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: false\n });\n }\n\n private _onMouseMove = (evt: MouseEvent) => {\n evt.preventDefault();\n\n const x = evt.clientX;\n const y = evt.clientY;\n const prevPos = this._prevPos;\n const deltaX = x - prevPos[0];\n const deltaY = y - prevPos[1];\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta: {\n x: deltaX,\n y: deltaY\n },\n isTouch: false,\n isKeyboard: false\n });\n\n prevPos[0] = x;\n prevPos[1] = y;\n }\n\n private _onMouseUp = () => {\n this._prevPos[0] = 0;\n this._prevPos[1] = 0;\n\n window.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: false,\n scrolling: false\n });\n }\n}\n\nexport default MouseInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\nimport { isFullscreen } from \"../../utils\";\n\nclass TouchInput extends Component> {\n private _el: HTMLElement | null;\n private _prevPos: [number, number];\n private _isFirstTouch: boolean;\n private _scrolling: boolean;\n private _scrollable: boolean;\n\n public get scrollable() { return this._scrollable; }\n public set scrollable(val: boolean) { this._scrollable = val; }\n\n public constructor() {\n super();\n\n this._el = null;\n this._prevPos = [0, 0];\n this._isFirstTouch = false;\n this._scrolling = false;\n this._scrollable = false;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.TOUCH_START, this._onTouchStart, { passive: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, { passive: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = element;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.TOUCH_START, this._onTouchStart);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = null;\n }\n\n private _onTouchStart = (evt: TouchEvent) => {\n if (evt.touches.length > 1 || this._scrolling) return;\n\n const touch = evt.touches[0];\n\n this._isFirstTouch = true;\n this._prevPos[0] = touch.clientX;\n this._prevPos[1] = touch.clientY;\n\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: true,\n isKeyboard: false\n });\n };\n\n private _onTouchMove = (evt: TouchEvent) => {\n // Only the one finger motion should be considered\n if (evt.touches.length > 1 || this._scrolling) return;\n\n const touch = evt.touches[0];\n const scrollable = this._scrollable;\n const prevPos = this._prevPos;\n\n const x = touch.clientX;\n const y = touch.clientY;\n const deltaX = x - prevPos[0];\n const deltaY = y - prevPos[1];\n\n if (this._isFirstTouch) {\n if (scrollable && !isFullscreen()) {\n if (Math.abs(deltaY) > Math.abs(deltaX)) {\n // Assume Scrolling\n this._scrolling = true;\n return;\n }\n }\n\n this._isFirstTouch = false;\n }\n\n if (evt.cancelable !== false) {\n evt.preventDefault();\n }\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta: {\n x: deltaX,\n y: deltaY\n },\n isTouch: true,\n isKeyboard: false\n });\n\n prevPos[0] = x;\n prevPos[1] = y;\n };\n\n private _onTouchEnd = (evt: TouchEvent) => {\n if (evt.touches.length !== 0) return;\n\n const touch = evt.touches[0];\n const prevPos = this._prevPos;\n\n if (touch) {\n prevPos[0] = touch.clientX;\n prevPos[1] = touch.clientY;\n } else {\n prevPos[0] = 0;\n prevPos[1] = 0;\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: true,\n isKeyboard: false,\n scrolling: this._scrolling\n });\n }\n\n if (evt.cancelable !== false) {\n evt.preventDefault();\n }\n\n this._scrolling = false;\n };\n}\n\nexport default TouchInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass KeyboardInput extends Component> {\n private _el: HTMLElement | null;\n private _pressed: {\n LEFT: boolean;\n UP: boolean;\n RIGHT: boolean;\n DOWN: boolean;\n };\n\n public get active() {\n const pressed = this._pressed;\n return pressed.LEFT || pressed.UP || pressed.RIGHT || pressed.DOWN;\n }\n\n public constructor() {\n super();\n\n this._el = null;\n this._clearPressedKeys();\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown);\n element.addEventListener(BROWSER.EVENTS.KEY_UP, this._onKeyUp);\n\n this._el = element;\n this._clearPressedKeys();\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown);\n element.removeEventListener(BROWSER.EVENTS.KEY_UP, this._onKeyUp);\n\n this._el = null;\n this._clearPressedKeys();\n }\n\n public update() {\n const delta = this._getDeltaByPressedKeys();\n\n if (delta.x !== 0 || delta.y !== 0) {\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: false,\n isKeyboard: true\n });\n }\n }\n\n private _clearPressedKeys() {\n this._pressed = BROWSER.KEY_DIRECTION.reduce((obj, keyName) => {\n return {\n ...obj,\n [keyName]: false\n };\n }, {} as KeyboardInput[\"_pressed\"]);\n }\n\n private _updateKeyPress(event: KeyboardEvent, isEnable: boolean): void {\n const pressed = this._pressed;\n const keyToUpdate = event.keyCode != null\n ? BROWSER.DIRECTION_KEY_CODE[event.keyCode]\n : BROWSER.DIRECTION_KEY_NAME[event.key];\n\n if (!keyToUpdate) return;\n\n pressed[keyToUpdate] = isEnable;\n }\n\n private _getPressedKeyCount() {\n return BROWSER.KEY_DIRECTION.filter(key => this._pressed[key]).length;\n }\n\n private _getDeltaByPressedKeys() {\n const pressed = this._pressed;\n let x = 0;\n let y = 0;\n\n if (pressed.LEFT) {\n x += 1;\n }\n\n if (pressed.RIGHT) {\n x -= 1;\n }\n\n if (pressed.UP) {\n y += 1;\n }\n\n if (pressed.DOWN) {\n y -= 1;\n }\n\n return {\n x, y\n };\n }\n\n private _onKeyDown = (evt: KeyboardEvent) => {\n // Ignore all other keypress except main arrow keys\n if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return;\n\n this._updateKeyPress(evt, true);\n\n const pressedCount = this._getPressedKeyCount();\n if (pressedCount <= 0) return;\n\n evt.preventDefault();\n if (pressedCount === 1 && !evt.repeat) {\n // On first keydown\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: true\n });\n }\n };\n\n private _onKeyUp = (evt: KeyboardEvent) => {\n // Ignore all other keypress except main arrow keys\n if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return;\n\n this._updateKeyPress(evt, false);\n\n const pressedCount = this._getPressedKeyCount();\n if (pressedCount > 0) return;\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: true,\n scrolling: false\n });\n };\n}\n\nexport default KeyboardInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport MouseInput from \"./input/MouseInput\";\nimport TouchInput from \"./input/TouchInput\";\nimport KeyboardInput from \"./input/KeyboardInput\";\nimport Camera from \"../core/Camera\";\nimport Motion from \"../core/Motion\";\nimport { CONTROL_EVENTS, INFINITE_RANGE, DEFAULT_PITCH_RANGE, DEFAULT_ANIMATION_DURATION, DEFAULT_EASING, DEG_TO_RAD, RAD_TO_DEG } from \"../const/internal\";\nimport { toVerticalFov } from \"../utils\";\nimport { ControlEvents, InputEvents } from \"../type/internal\";\n\n/**\n * Options for {@link RotateControl}\n * @ko {@link RotateControl}용 옵션들\n * @since 4.0.0\n */\nexport interface RotateControlOptions {\n /**\n * @copy RotateControl#pointerScale\n */\n pointerScale: [number, number];\n /**\n * @copy RotateControl#keyboardScale\n */\n keyboardScale: [number, number];\n /**\n * @copy RotateControl#duration\n */\n duration: number;\n /**\n * @copy RotateControl#easing\n */\n easing: (x: number) => number;\n /**\n * @copy RotateControl#disablePitch\n */\n disablePitch: boolean;\n /**\n * @copy RotateControl#disableYaw\n */\n disableYaw: boolean;\n /**\n * @copy RotateControl#disableKeyboard\n */\n disableKeyboard: boolean;\n}\n\ntype RotateDeltaType = { x: number; y: number; };\nexport type RotateControlEvents = ControlEvents;\n\n/**\n * Camera's rotation control\n * @ko 카메라의 회전을 담당하는 컨트롤\n * @since 4.0.0\n */\nclass RotateControl extends Component implements CameraControl {\n // Options\n private _pointerScale: RotateControlOptions[\"pointerScale\"];\n private _keyboardScale: RotateControlOptions[\"keyboardScale\"];\n private _duration: RotateControlOptions[\"duration\"];\n private _easing: RotateControlOptions[\"easing\"];\n private _disablePitch: RotateControlOptions[\"disablePitch\"];\n private _disableYaw: RotateControlOptions[\"disableYaw\"];\n private _disableKeyboard: RotateControlOptions[\"disableKeyboard\"];\n\n // Internal values\n private _controlEl: HTMLElement;\n private _enableBlocked: boolean;\n private _mouseInput: MouseInput;\n private _touchInput: TouchInput;\n private _keyboardInput: KeyboardInput;\n private _xMotion: Motion;\n private _yMotion: Motion;\n private _screenScale: [number, number];\n private _zoomScale: number;\n private _enabled: boolean;\n private _changedWhileDragging: boolean;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() {\n return this._keyboardInput.active\n || this._xMotion.activated\n || this._yMotion.activated;\n }\n /**\n * Current yaw value\n * @ko 현재 yaw 값\n * @readonly\n * @since 4.0.0\n */\n public get yaw() { return this._xMotion; }\n /**\n * Current pitch value\n * @ko 현재 pitch 값\n * @readonly\n * @since 4.0.0\n */\n public get pitch() { return this._yMotion; }\n /**\n * @copy View360#scrollable\n */\n public get scrollable() { return this._touchInput.scrollable; }\n public set scrollable(val: boolean) {\n this._touchInput.scrollable = val;\n }\n\n /**\n * Scale factor for mouse/touch rotation\n * @ko 마우스/터치를 통한 회전 배율\n * @default [1, 1]\n * @since 4.0.0\n */\n public get pointerScale() { return this._pointerScale; }\n public set pointerScale(val: RotateControlOptions[\"pointerScale\"]) {\n this._pointerScale = val;\n }\n\n /**\n * Scale factor for keyboard rotation\n * @ko 키보드를 통한 회전 배율\n * @default [1, 1]\n * @since 4.0.0\n */\n public get keyboardScale() { return this._keyboardScale; }\n public set keyboardScale(val: RotateControlOptions[\"keyboardScale\"]) {\n this._keyboardScale = val;\n }\n\n /**\n * Duration of the input animation (ms)\n * @ko 회전 애니메이션의 시간 (ms)\n * @default 300\n */\n public get duration() { return this._duration; }\n public set duration(val: RotateControlOptions[\"duration\"]) {\n this._duration = val;\n this._xMotion.duration = val;\n this._yMotion.duration = val;\n }\n\n /**\n * Easing function of the animation\n * @ko 회전 애니메이션에 적용할 easing 함수\n * @default EASING.EASE_OUT_CUBIC\n * @see EASING\n */\n public get easing() { return this._easing; }\n public set easing(val: RotateControlOptions[\"easing\"]) {\n this._easing = val;\n this._xMotion.easing = val;\n this._yMotion.easing = val;\n }\n\n /**\n * Disable X-axis(pitch) rotation.\n * @ko x축 회전(pitch)을 비활성화합니다.\n * @default false\n */\n public get disablePitch() { return this._disablePitch; }\n public set disablePitch(val: RotateControlOptions[\"disablePitch\"]) { this._disablePitch = val; }\n\n /**\n * Disable Y-axis(yaw) rotation.\n * @ko y축 회전(yaw)을 비활성화합니다.\n * @default false\n */\n public get disableYaw() { return this._disableYaw; }\n public set disableYaw(val: RotateControlOptions[\"disableYaw\"]) { this._disableYaw = val; }\n\n /**\n * Disable rotation by keyboard.\n * @ko 키보드를 이용한 회전을 비활성화합니다.\n * @default false\n */\n public get disableKeyboard() { return this._disableKeyboard; }\n public set disableKeyboard(val: RotateControlOptions[\"disableKeyboard\"]) { this._disableKeyboard = val; }\n\n /**\n * Create new RotateControl instance\n * @ko RotateControl의 인스턴스를 생성합니다.\n * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트}\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(controlEl: HTMLElement, enableBlocked: boolean, {\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING,\n pointerScale = [1, 1],\n keyboardScale = [1, 1],\n disablePitch = false,\n disableYaw = false,\n disableKeyboard = false\n }: Partial = {}) {\n super();\n\n this._controlEl = controlEl;\n this._pointerScale = pointerScale;\n this._keyboardScale = keyboardScale;\n this._duration = duration;\n this._easing = easing;\n this._disablePitch = disablePitch;\n this._disableYaw = disableYaw;\n this._disableKeyboard = disableKeyboard;\n\n this._enableBlocked = enableBlocked;\n this._mouseInput = new MouseInput();\n this._touchInput = new TouchInput();\n this._keyboardInput = new KeyboardInput();\n this._xMotion = new Motion({ duration, range: INFINITE_RANGE, easing });\n this._yMotion = new Motion({ duration, range: DEFAULT_PITCH_RANGE, easing });\n this._screenScale = [1, 1];\n this._zoomScale = 1;\n this._enabled = false;\n this._changedWhileDragging = false;\n this._bindInputs();\n }\n\n public destroy(): void {\n this.disable();\n this._mouseInput.off();\n this._touchInput.off();\n this._keyboardInput.off();\n this.off();\n this._changedWhileDragging = false;\n }\n\n /**\n * @hidden\n */\n public update(delta: number): void {\n if (!this._enabled) return;\n\n const xMotion = this._xMotion;\n const yMotion = this._yMotion;\n const keyboardInput = this._keyboardInput;\n\n if (!this._disableKeyboard) {\n keyboardInput.update();\n }\n\n if (!this._disablePitch) {\n yMotion.update(delta);\n }\n\n if (!this._disableYaw) {\n xMotion.update(delta);\n }\n }\n\n /**\n * @hidden\n */\n public updateRange(camera: Camera, zoom: number) {\n const yawRange = camera.getYawRange(zoom);\n const pitchRange = camera.getPitchRange(zoom);\n\n this._xMotion.setRange(yawRange.min, yawRange.max);\n this._yMotion.setRange(pitchRange.min, pitchRange.max);\n }\n\n /**\n * @hidden\n */\n public setZoomScale(val: number) {\n this._zoomScale = val;\n }\n\n /**\n * Resize control to match target size.\n * @ko 컨트롤의 내부 크기를 갱신합니다.\n * @param hfov - Camera horizontal fov in degrees {@ko 카메라의 수평방향 fov값 (도 단위)}\n * @param aspect - Camera aspect {@ko 카메라 가로/세로 비율}\n * @param width - New width {@ko 갱신된 너비}\n * @param height - New height {@ko 갱신된 높이}\n */\n public resize(hfov: number, aspect: number, width: number, height: number) {\n const vfov = toVerticalFov(hfov * DEG_TO_RAD, aspect) * RAD_TO_DEG;\n\n this._screenScale[0] = hfov / width;\n this._screenScale[1] = vfov / height;\n }\n\n public enable(): void {\n if (this._enabled) return;\n\n const element = this._controlEl;\n\n this._mouseInput.enable(element);\n this._touchInput.enable(element);\n this._keyboardInput.enable(element);\n\n this._enabled = true;\n this._enableBlocked = false;\n\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: true });\n }\n\n public disable(): void {\n if (!this._enabled) return;\n\n this._mouseInput.disable();\n this._touchInput.disable();\n this._keyboardInput.disable();\n\n this._enabled = false;\n\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: true });\n }\n\n public sync(camera: Camera): void {\n this.updateRange(camera, camera.zoom);\n\n this._xMotion.reset(camera.yaw);\n this._yMotion.reset(camera.pitch);\n }\n\n private _bindInputs() {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n const keyboardInput = this._keyboardInput;\n\n mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n touchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n touchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n keyboardInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n keyboardInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n keyboardInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n }\n\n private _onInputStart = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n this._changedWhileDragging = false;\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n ...evt,\n inputType: \"rotate\"\n });\n };\n\n private _onChange = (evt: InputEvents[typeof CONTROL_EVENTS.CHANGE]) => {\n const delta = evt.delta;\n const invZoomScale = 1 / this._zoomScale; // Reduce speed on zoom\n const screenScale = this._screenScale;\n const keyboardScale = this._keyboardScale;\n const pointerScale = this._pointerScale;\n\n let scale: [number, number];\n\n if (evt.isKeyboard) {\n scale = [\n keyboardScale[0] * invZoomScale,\n keyboardScale[1] * invZoomScale\n ];\n } else {\n scale = [\n pointerScale[0] * screenScale[0] * invZoomScale,\n pointerScale[1] * screenScale[1] * invZoomScale\n ];\n }\n\n const scaledX = delta.x * scale[0];\n const scaledY = delta.y * scale[1];\n\n this._xMotion.setNewEndByDelta(scaledX);\n this._yMotion.setNewEndByDelta(scaledY);\n\n this._changedWhileDragging = true;\n }\n\n private _onInputEnd = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n ...evt,\n inputType: \"rotate\"\n });\n\n if (!this._changedWhileDragging && !evt.isKeyboard && !evt.scrolling) {\n this.trigger(CONTROL_EVENTS.STATIC_CLICK, {\n isTouch: evt.isTouch\n });\n }\n\n this._changedWhileDragging = false;\n };\n}\n\nexport default RotateControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS, DEFAULT_ANIMATION_DURATION } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass WheelInput extends Component> {\n private _el: HTMLElement | null;\n private _scrollable: boolean;\n private _baseScale: number;\n private _inputTimer: number;\n\n public get scrollable() { return this._scrollable; }\n public set scrollable(val: boolean) { this._scrollable = val; }\n\n public constructor() {\n super();\n\n this._el = null;\n this._baseScale = 0.04;\n this._scrollable = false;\n this._inputTimer = -1;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.WHEEL, this._onWheel, { passive: false, capture: false });\n\n this._el = element;\n this._clearTimer();\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.WHEEL, this._onWheel, false);\n\n this._el = null;\n this._clearTimer();\n }\n\n private _onWheel = (evt: WheelEvent) => {\n const scrollable = this._scrollable;\n\n if (evt.deltaY === 0 || scrollable) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n\n if (this._inputTimer < 0) {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: false\n });\n } else {\n this._clearTimer();\n }\n\n const delta = this._baseScale * evt.deltaY;\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: false,\n isKeyboard: false\n });\n\n this._inputTimer = window.setTimeout(() => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: false,\n scrolling: false\n });\n this._inputTimer = -1;\n }, DEFAULT_ANIMATION_DURATION);\n };\n\n private _clearTimer() {\n window.clearTimeout(this._inputTimer);\n this._inputTimer = -1;\n }\n}\n\nexport default WheelInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass PinchInput extends Component> {\n private _el: HTMLElement | null;\n private _baseScale: number;\n private _prevDistance: number;\n private _isFirstTouch: boolean;\n\n public constructor() {\n super();\n\n this._el = null;\n this._baseScale = -0.2;\n this._prevDistance = -1;\n this._isFirstTouch = true;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, { passive: false, capture: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = element;\n this._prevDistance = -1;\n this._isFirstTouch = true;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, false);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = null;\n }\n\n private _onTouchMove = (evt: TouchEvent) => {\n const touches = evt.touches;\n if (touches.length !== 2) return;\n\n if (!evt.cancelable) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n\n const prevDistance = this._prevDistance;\n\n const diff = [\n touches[0].pageX - touches[1].pageX,\n touches[0].pageY - touches[1].pageY\n ];\n\n const distance = Math.sqrt(diff[0] * diff[0] + diff[1] * diff[1]) * this._baseScale;\n const delta = this._isFirstTouch\n ? 0\n : distance - prevDistance;\n\n if (this._isFirstTouch) {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: true,\n isKeyboard: false\n });\n }\n\n this._prevDistance = distance;\n this._isFirstTouch = false;\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: true,\n isKeyboard: false\n });\n };\n\n private _onTouchEnd = (evt: TouchEvent) => {\n if (evt.touches.length !== 0) return;\n\n if (!this._isFirstTouch) {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: true,\n isKeyboard: false,\n scrolling: false\n });\n }\n\n this._prevDistance = -1;\n this._isFirstTouch = true;\n };\n}\n\nexport default PinchInput;\n","/*\n* Copyright (c) 2023-present NAVER Corp.\n* egjs projects are licensed under the MIT license\n*/\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport WheelInput from \"./input/WheelInput\";\nimport PinchInput from \"./input/PinchInput\";\nimport Camera from \"../core/Camera\";\nimport Motion from \"../core/Motion\";\nimport {\n CONTROL_EVENTS,\n DEFAULT_ANIMATION_DURATION,\n DEFAULT_EASING,\n INFINITE_RANGE\n} from \"../const/internal\";\nimport { ControlEvents, InputEvents } from \"../type/internal\";\n\n/**\n * Options for {@link ZoomControl}\n * @ko {@link ZoomControl}용 옵션들\n * @since 4.0.0\n */\nexport interface ZoomControlOptions {\n /**\n * @copy ZoomControl#scale\n */\n scale: number;\n /**\n * @copy ZoomControl#duration\n */\n duration: number;\n /**\n * @copy ZoomControl#easing\n */\n easing: (x: number) => number;\n}\n\ntype ZoomControlEvents = ControlEvents;\n\n/**\n * Camera's zoom control\n * @ko 카메라의 줌 값을 담당하는 컨트롤\n * @since 4.0.0\n */\nclass ZoomControl extends Component implements CameraControl {\n // Options\n private _scale: ZoomControlOptions[\"scale\"];\n\n // Internal values\n private _controlEl: HTMLElement;\n private _enableBlocked: boolean;\n private _wheelInput: WheelInput;\n private _pinchInput: PinchInput;\n private _motion: Motion;\n private _enabled: boolean;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() { return this._motion.activated; }\n /**\n * Current zoom value\n * @ko 현재 줌 값\n * @since 4.0.0\n * @readonly\n */\n public get zoom() { return this._motion.val; }\n /**\n * @copy View360#wheelScrollable\n */\n public get scrollable() { return this._wheelInput.scrollable; }\n public set scrollable(val: boolean) {\n this._wheelInput.scrollable = val;\n }\n /**\n * @hidden\n */\n public get range() { return this._motion.range; }\n\n /**\n * Scale factor of the zoom\n * @ko 입력에 의한 줌 배율\n * @default 1\n * @since 4.0.0\n */\n public get scale() { return this._scale; }\n public set scale(val: ZoomControlOptions[\"scale\"]) { this._scale = val; }\n\n /**\n * Duration of the input animation (ms)\n * @ko 회전 애니메이션의 시간 (ms)\n * @default 300\n * @since 4.0.0\n */\n public get duration() { return this._motion.duration; }\n\n /**\n * Easing function of the animation\n * @ko 회전 애니메이션에 적용할 easing 함수\n * @default EASING.EASE_OUT_CUBIC\n * @see EASING\n * @since 4.0.0\n */\n public get easing() { return this._motion.easing; }\n\n /**\n * Create new ZoomControl instance\n * @ko ZoomControl의 인스턴스를 생성합니다.\n * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트}\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(controlEl: HTMLElement, enableBlocked: boolean, {\n scale = 1,\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING\n }: Partial = {}) {\n super();\n\n this._scale = scale;\n\n this._controlEl = controlEl;\n this._enableBlocked = enableBlocked;\n this._wheelInput = new WheelInput();\n this._pinchInput = new PinchInput();\n this._motion = new Motion({\n duration,\n easing,\n range: INFINITE_RANGE\n });\n this._enabled = false;\n\n this._bindInputs();\n }\n\n public destroy(): void {\n this.disable();\n this._wheelInput.off();\n this._pinchInput.off();\n this.off();\n }\n\n /**\n * @hidden\n */\n public update(delta: number): void {\n if (!this._enabled) return;\n\n const motion = this._motion;\n motion.update(delta);\n }\n\n public enable(): void {\n if (this._enabled) return;\n\n const element = this._controlEl;\n this._wheelInput.enable(element);\n this._pinchInput.enable(element);\n\n this._enabled = true;\n this._enableBlocked = false;\n\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: false });\n }\n\n public disable(): void {\n if (!this._enabled) return;\n\n this._wheelInput.disable();\n this._pinchInput.disable();\n\n this._enabled = false;\n\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: false });\n }\n\n public sync(camera: Camera): void {\n const motion = this._motion;\n const range = camera.getZoomRange();\n\n motion.setRange(range.min, range.max);\n motion.reset(range.current);\n }\n\n private _bindInputs() {\n const wheelInput = this._wheelInput;\n const pinchInput = this._pinchInput;\n\n wheelInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n wheelInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n wheelInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n pinchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n pinchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n pinchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n }\n\n private _onInputStart = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n ...evt,\n inputType: \"zoom\"\n });\n };\n\n private _onChange = ({ delta }: InputEvents[typeof CONTROL_EVENTS.CHANGE]) => {\n const scale = this._scale;\n const scaledDelta = delta * scale;\n\n this._motion.setNewEndByDelta(scaledDelta);\n };\n\n private _onInputEnd = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n ...evt,\n inputType: \"zoom\"\n });\n };\n}\n\nexport default ZoomControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { quat, vec3 } from \"gl-matrix\";\nimport * as BROWSER from \"../../const/browser\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\nimport { quatToEuler } from \"../../utils\";\n\nexport const ROTATE_CONSTANT = {\n PITCH_DELTA: 1,\n YAW_DELTA_BY_ROLL: 2,\n YAW_DELTA_BY_YAW: 3\n} as const;\n\nROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = {\n targetAxis: [0, 1, 0],\n meshPoint: [0, 0, 1]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = {\n targetAxis: [0, 1, 0],\n meshPoint: [1, 0, 0]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = {\n targetAxis: [1, 0, 0],\n meshPoint: [0, 0, 1]\n};\n\nclass GyroInput extends Component> {\n public quaternion: quat;\n\n private _ignoreRoll: boolean;\n\n private _yawOrigin: number;\n private _yawOffset: number;\n private _orientation: {\n alpha: number;\n beta: number;\n gamma: number;\n }\n private _orientationUpdated: boolean;\n private _needsCalibrate: boolean;\n private _screenOrientation: number;\n private _enabled: boolean;\n\n public get enabled() { return this._enabled; }\n public get orientationUpdated() { return this._orientationUpdated; }\n public get ignoreRoll() { return this._ignoreRoll; }\n public set ignoreRoll(val: boolean) { this._ignoreRoll = val; }\n\n public constructor() {\n super();\n\n this.quaternion = quat.create();\n\n this._orientation = {\n alpha: 0,\n beta: 90,\n gamma: 0\n };\n this._yawOrigin = 0;\n this._yawOffset = 0;\n this._orientationUpdated = false;\n this._screenOrientation = 0;\n this._needsCalibrate = true;\n this._enabled = false;\n }\n\n public enable() {\n if (this._enabled) return;\n\n window.addEventListener(BROWSER.EVENTS.DEVICE_ORIENTATION, this._onDeviceOrientation);\n window.addEventListener(BROWSER.EVENTS.ORIENTATION_CHANGE, this._updateScreenOrientation);\n\n this._updateScreenOrientation();\n this._orientationUpdated = false;\n this._needsCalibrate = true;\n this._enabled = true;\n }\n\n public disable() {\n if (!this._enabled) return;\n\n window.removeEventListener(BROWSER.EVENTS.DEVICE_ORIENTATION, this._onDeviceOrientation);\n window.removeEventListener(BROWSER.EVENTS.ORIENTATION_CHANGE, this._updateScreenOrientation);\n\n this._enabled = false;\n }\n\n public update() {\n this._updateRotation();\n this._orientationUpdated = false;\n }\n\n public collectDelta() {\n if (!this._orientationUpdated) {\n return {\n pitch: 0,\n yaw: 0\n };\n }\n\n const prevRotation = quat.clone(this.quaternion);\n\n this._updateRotation();\n this._orientationUpdated = false;\n\n return this._toEulerDelta(prevRotation, this.quaternion);\n }\n\n public setInitialRotation(yaw: number) {\n this._yawOrigin = yaw;\n }\n\n private _onDeviceOrientation = (evt: DeviceOrientationEvent) => {\n const prevOrientation = this._orientation;\n const { alpha, beta, gamma } = evt;\n\n if (\n alpha == null\n || beta == null\n || gamma == null\n ) return;\n\n prevOrientation.alpha = alpha;\n prevOrientation.beta = beta;\n prevOrientation.gamma = gamma;\n\n this._orientationUpdated = true;\n\n if (this._needsCalibrate) {\n this._needsCalibrate = false;\n this._calibrateSensor();\n }\n };\n\n private _calibrateSensor() {\n const yawOrigin = this._yawOrigin;\n const rotation = this.quaternion;\n\n this._yawOffset = 0;\n this._updateRotation();\n\n const { yaw: sensorYaw } = quatToEuler(rotation);\n this._yawOffset = sensorYaw - yawOrigin;\n this._updateRotation();\n\n this._needsCalibrate = false;\n }\n\n private _updateRotation() {\n const rotation = this.quaternion;\n const { alpha, beta, gamma } = this._orientation;\n\n quat.identity(rotation);\n quat.rotateY(rotation, rotation, (alpha - this._yawOffset) * DEG_TO_RAD);\n quat.rotateX(rotation, rotation, beta * DEG_TO_RAD);\n quat.rotateZ(rotation, rotation, -gamma * DEG_TO_RAD);\n\n const screen = quat.create();\n const screenAngle = -this._screenOrientation * 0.5 * DEG_TO_RAD;\n const world = quat.fromValues(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5));\n\n quat.set(screen, 0, Math.sin(screenAngle), 0, Math.cos(screenAngle));\n quat.multiply(rotation, rotation, screen);\n quat.multiply(rotation, rotation, world);\n\n quat.normalize(rotation, rotation);\n }\n\n private _updateScreenOrientation = () => {\n if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) {\n this._screenOrientation = screen.orientation.angle;\n } else if (window.orientation !== undefined) {\n this._screenOrientation = window.orientation >= 0 ?\n window.orientation : 360 + window.orientation;\n } else {\n this._screenOrientation = 0;\n }\n }\n\n private _toEulerDelta(prevQuat: quat, currentQuat: quat) {\n return {\n yaw: this._getDeltaYaw(prevQuat, currentQuat),\n pitch: this._getDeltaPitch(prevQuat, currentQuat),\n };\n }\n\n private _getDeltaYaw(prvQ: quat, curQ: quat): number {\n const yawDeltaByYaw = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW);\n const yawDeltaByRoll = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL)\n * Math.sin(this._extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n }\n\n private _getDeltaPitch(prvQ: quat, curQ: quat): number {\n return this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n }\n\n private _getRotationDelta(prevQ: quat, curQ: quat, rotateKind: typeof ROTATE_CONSTANT[keyof typeof ROTATE_CONSTANT]) {\n const targetAxis = vec3.fromValues(\n ROTATE_CONSTANT[rotateKind].targetAxis[0],\n ROTATE_CONSTANT[rotateKind].targetAxis[1],\n ROTATE_CONSTANT[rotateKind].targetAxis[2]\n );\n const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint;\n\n const prevQuaternion = quat.clone(prevQ);\n const curQuaternion = quat.clone(curQ);\n\n quat.normalize(prevQuaternion, prevQuaternion);\n quat.normalize(curQuaternion, curQuaternion);\n\n let prevPoint = vec3.fromValues(0, 0, 1);\n let curPoint = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n vec3.transformQuat(targetAxis, targetAxis, curQuaternion);\n\n const rotateDistance = vec3.dot(targetAxis, vec3.cross(vec3.create(), prevPoint, curPoint));\n const rotateDirection = rotateDistance > 0 ? 1 : -1;\n\n // when counter clock wise, use vec3.fromValues(0,1,0)\n // when clock wise, use vec3.fromValues(0,-1,0)\n // const meshPoint1 = vec3.fromValues(0, 0, 0);\n const meshPoint2 = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n\n let meshPoint3;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n meshPoint3 = vec3.fromValues(0, rotateDirection, 0);\n } else {\n meshPoint3 = vec3.fromValues(rotateDirection, 0, 0);\n }\n\n vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion);\n vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion);\n\n const vecU = meshPoint2;\n const vecV = meshPoint3;\n const vecN = vec3.create();\n\n vec3.cross(vecN, vecU, vecV);\n vec3.normalize(vecN, vecN);\n\n const coefficientA = vecN[0];\n const coefficientB = vecN[1];\n const coefficientC = vecN[2];\n\n // a point on the plane\n curPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n\n // a point should project on the plane\n prevPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n\n // distance between prevPoint and the plane\n let distance = Math.abs(\n prevPoint[0] * coefficientA +\n prevPoint[1] * coefficientB +\n prevPoint[2] * coefficientC\n );\n\n const projectedPrevPoint = vec3.create();\n\n vec3.subtract(projectedPrevPoint, prevPoint, vec3.scale(vec3.create(), vecN, distance));\n\n let trigonometricRatio =\n (projectedPrevPoint[0] * curPoint[0] +\n projectedPrevPoint[1] * curPoint[1] +\n projectedPrevPoint[2] * curPoint[2]) /\n (vec3.length(projectedPrevPoint) * vec3.length(curPoint));\n\n // defensive block\n if (trigonometricRatio > 1) {\n trigonometricRatio = 1;\n }\n\n const theta = Math.acos(trigonometricRatio);\n\n const crossVec = vec3.cross(vec3.create(), curPoint, projectedPrevPoint);\n\n distance = coefficientA * crossVec[0]\n + coefficientB * crossVec[1]\n + coefficientC * crossVec[2];\n\n let thetaDirection: number;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n thetaDirection = distance > 0 ? 1 : -1;\n } else {\n thetaDirection = distance < 0 ? 1 : -1;\n }\n\n const deltaRadian = theta * thetaDirection * rotateDirection;\n\n return deltaRadian * RAD_TO_DEG;\n }\n\n private _extractPitchFromQuat(quaternion: quat) {\n const baseV = vec3.fromValues(0, 0, 1);\n vec3.transformQuat(baseV, baseV, quaternion);\n\n return -1 * Math.atan2(\n baseV[1],\n Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2)));\n }\n}\n\nexport default GyroInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport GyroInput from \"./input/GyroInput\";\nimport Motion from \"../core/Motion\";\nimport Camera from \"../core/Camera\";\nimport * as BROWSER from \"../const/browser\";\nimport { CONTROL_EVENTS } from \"../const/internal\";\nimport { ControlEvents } from \"../type/internal\";\nimport { sensorCanBeEnabledIOS } from \"../utils\";\n\n/**\n * Options for {@link GyroControl}\n * @ko {@link GyroControl}용 옵션들\n * @since 4.0.0\n */\nexport interface GyroControlOptions {\n /**\n * @copy GyroControl#ignoreRoll\n */\n ignoreRoll: boolean;\n}\n\nexport type GyroControlEvents = ControlEvents;\n\n/**\n * Camera's rotation control by gyroscope\n * @ko 자이로스코프를 이용한 회전 컨트롤\n * @since 4.0.0\n */\nclass GyroControl extends Component implements CameraControl {\n // Options\n private _ignoreRoll: GyroControlOptions[\"ignoreRoll\"];\n\n // Internal values\n private _enableBlocked: boolean;\n private _input: GyroInput;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._input.enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() {\n return this._input.enabled && this._input.orientationUpdated;\n }\n\n /**\n * When `true`, ignore gyroscope's roll(z-axis rotation) value.\n * :::caution\n * Setting `false` will ignore camera's range limit.\n * Options like {@link View360Options#yawRange}, {@link View360Options#pitchRange} are ignored, and {@link CylinderProjection} also can't force it's camera range limit.\n * :::\n * @ko `true`일 경우 자이로스코프 입력의 roll(z축 회전)값을 무시합니다.\n * :::caution\n * 이 값을 `false`로 설정할 경우 카메라 범위 제약을 무시합니다.\n * {@link View360Options#yawRange}, {@link View360Options#pitchRange}와 같은 값은 무시되며, {@link CylinderProjection} 사용시에도 범위를 벗어날 수 있습니다.\n * :::\n * @default true\n * @since 4.0.0\n */\n public get ignoreRoll() { return this._ignoreRoll; }\n public set ignoreRoll(val: GyroControlOptions[\"ignoreRoll\"]) { this._ignoreRoll = val; }\n\n /**\n * Return availability of the gyroscope.\n * :::caution\n * This will always return false until user permission under environments like iOS which requires user permission when using gyroscope.\n * :::\n * @ko 자이로스코프 사용 가능 여부를 반환합니다.\n * :::caution\n * iOS와 같이 GyroScope 사용시 사용자 Permission을 요구하는 환경에서는 사용자 Permission을 받기 전까지 항상 `false`입니다.\n * :::\n * @example\n * ```ts\n * const gyroAvailable = await GyroControl.isAvailable();\n * ```\n */\n public static async isAvailable(): Promise {\n if (!DeviceMotionEvent) {\n return false;\n }\n\n let onDeviceMotionChange: (evt: DeviceMotionEvent) => void;\n\n const listenDeviceMotion = () => new Promise(res => {\n onDeviceMotionChange = (evt: DeviceMotionEvent) => {\n res(evt.rotationRate && evt.rotationRate.alpha != null);\n };\n\n window.addEventListener(BROWSER.EVENTS.DEVICE_MOTION, onDeviceMotionChange);\n });\n\n const timeout = () => new Promise(res => {\n setTimeout(() => res(false), 1000);\n });\n\n return Promise.race([listenDeviceMotion(), timeout()])\n .then((available: boolean) => {\n window.removeEventListener(BROWSER.EVENTS.DEVICE_MOTION, onDeviceMotionChange);\n\n return available;\n });\n }\n\n /**\n * Request user permission for gyroscope sensor.\n * This can be used in environments like iOS which requires user permission when using gyroscope sensors.\n * @ko 사용자의 sensor permission 취득을 요청합니다.\n * iOS와 같이 gyroscope 사용시 사용자 Permission을 요구하는 환경에서 사용 가능합니다.\n * @returns Whether the permission is granted {@ko 사용자 permission 취득 여부}\n */\n public static async requestSensorPermission(): Promise {\n // Request sensor permission, on iOS13+\n if (sensorCanBeEnabledIOS()) {\n return (DeviceMotionEvent as typeof DeviceMotionEvent & {\n requestPermission: () => Promise;\n }).requestPermission().then(permissionState => {\n return permissionState === \"granted\";\n }).catch(() => false);\n }\n\n return true;\n }\n\n /**\n * Create new GyroControl instance\n * @ko GyroControl의 인스턴스를 생성합니다.\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(enableBlocked: boolean, {\n ignoreRoll = true\n }: Partial = {}) {\n super();\n\n this._enableBlocked = enableBlocked;\n this._ignoreRoll = ignoreRoll;\n this._input = new GyroInput();\n }\n\n /**\n * @copy CameraControl#destroy\n */\n public destroy(): void {\n this.disable();\n this._input.off();\n this.off();\n }\n\n /**\n * @hidden\n */\n public update(camera: Camera, yaw: Motion, pitch: Motion, zoom: number) {\n if (!this._ignoreRoll) {\n this._updateQuaternion(camera, zoom);\n } else {\n this._updateYawPitch(camera, yaw, pitch, zoom);\n }\n }\n\n /**\n * @copy CameraControl#enable\n */\n public enable(): void {\n if (this._input.enabled) return;\n\n this._input.enable();\n this._enableBlocked = false;\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: false });\n }\n\n /**\n * @copy CameraControl#disable\n */\n public disable(): void {\n if (!this._input.enabled) return;\n\n this._input.disable();\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: false });\n }\n\n /**\n * @copy CameraControl#sync\n */\n public sync(): void {} // eslint-disable-line @typescript-eslint/no-empty-function\n\n private _updateYawPitch(camera: Camera, yaw: Motion, pitch: Motion, zoom: number) {\n const input = this._input;\n if (!input.enabled) return;\n\n const {\n yaw: yawDelta,\n pitch: pitchDelta\n } = input.collectDelta();\n\n yaw.add(yawDelta);\n pitch.add(pitchDelta);\n\n camera.lookAt({\n yaw: yaw.val,\n pitch: pitch.val,\n zoom\n });\n }\n\n private _updateQuaternion(camera: Camera, zoom: number) {\n const input = this._input;\n if (!input.enabled) return;\n\n input.update();\n camera.rotate(input.quaternion, zoom);\n }\n}\n\nexport default GyroControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport CameraControl from \"./CameraControl\";\nimport RotateControl, { RotateControlEvents, RotateControlOptions } from \"./RotateControl\";\nimport ZoomControl, { ZoomControlOptions } from \"./ZoomControl\";\nimport GyroControl, { GyroControlOptions } from \"./GyroControl\";\nimport Camera from \"../core/Camera\";\nimport CameraAnimation from \"../core/CameraAnimation\";\nimport * as BROWSER from \"../const/browser\";\nimport { CAMERA_EVENTS, CONTROL_EVENTS } from \"../const/internal\";\nimport { ValueOf } from \"../type/utils\";\nimport { getObjectOption, hfovToZoom } from \"../utils\";\n\n/**\n * Options for {@link PanoControl}\n * @ko {@link PanoControl}용 옵션들\n * @since 4.0.0\n */\nexport interface PanoControlOptions {\n /**\n * @copy View360#useGrabCursor\n */\n useGrabCursor: boolean;\n /**\n * @copy View360#scrollable\n */\n scrollable: boolean;\n /**\n * @copy View360#wheelScrollable\n */\n wheelScrollable: boolean;\n /**\n * @copy View360#disableContextMenu\n */\n disableContextMenu: boolean;\n /**\n * Options for {@link RotateControl}.\n * `false` to disable rotation.\n * @ko {@link RotateControl}용 옵션들.\n * `false`일 경우 회전이 비활성화됩니다.\n * @since 4.0.0\n */\n rotate: boolean | Partial;\n /**\n * Options for {@link ZoomControl}.\n * `false` to disable zoom.\n * @ko {@link ZoomControl}용 옵션들.\n * `false`일 경우 줌이 비활성화됩니다.\n * @since 4.0.0\n */\n zoom: boolean | Partial;\n /**\n * Options for {@link GyroControl}.\n * `false` to disable gyroscope control.\n * @ko {@link GyroControl}용 옵션들.\n * `false`일 경우 자이로스코프를 통한 컨트롤이 비활성화됩니다.\n * @since 4.0.0\n */\n gyro: boolean | Partial;\n}\n\n/**\n * Panorama control for View360\n * @ko View360용 파노라마 컨트롤\n * @since 4.0.0\n */\nclass PanoControl {\n // Options\n private _useGrabCursor: PanoControlOptions[\"useGrabCursor\"];\n private _disableContextMenu: PanoControlOptions[\"disableContextMenu\"];\n\n // Internal Values\n private _camera: Camera;\n private _controlEl: HTMLElement;\n private _rotateControl: RotateControl;\n private _zoomControl: ZoomControl;\n private _gyroControl: GyroControl;\n private _ignoreZoomScale: boolean;\n private _enabled: boolean;\n\n /**\n * @copy View360#useGrabCursor\n */\n public get useGrabCursor() { return this._useGrabCursor; }\n public set useGrabCursor(val: PanoControlOptions[\"useGrabCursor\"]) {\n if (val === this._useGrabCursor) return;\n\n this._useGrabCursor = val;\n\n if (val && this._enabled) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n } else if (!val) {\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n }\n\n /**\n * @copy View360#disableContextMenu\n */\n public get disableContextMenu() { return this._disableContextMenu; }\n public set disableContextMenu(val: PanoControlOptions[\"disableContextMenu\"]) {\n if (val === this._disableContextMenu) return;\n\n this._disableContextMenu = val;\n\n if (val && this._enabled) {\n this._blockContextMenu();\n } else if (!val) {\n this._restoreContextMenu();\n }\n }\n\n /**\n * @copy View360#disableContextMenu\n */\n public get scrollable() { return this._rotateControl.scrollable; }\n public set scrollable(val: PanoControlOptions[\"scrollable\"]) { this._rotateControl.scrollable = val; }\n /**\n * @copy View360#disableContextMenu\n */\n public get wheelScrollable() { return this._zoomControl.scrollable; }\n public set wheelScrollable(val: PanoControlOptions[\"wheelScrollable\"]) { this._zoomControl.scrollable = val; }\n /**\n * When `true`, disables rotation slow-down by zoom-value.\n * @ko `true`일 경우 줌 된 정도에 따라 회전속도를 늦추는 동작을 비활성화합니다.\n * @since 4.0.0\n */\n public get ignoreZoomScale() { return this._ignoreZoomScale; }\n public set ignoreZoomScale(val: boolean) { this._ignoreZoomScale = val; }\n\n /**\n * Whether the control is enabled or not\n * @ko 컨트롤 활성화 여부를 가리키는 값\n * @readonly\n * @since 4.0.0\n */\n public get enabled() { return this._enabled; }\n /**\n * @copy View360#rotate\n */\n public get rotate() { return this._rotateControl; }\n /**\n * @copy View360#zoom\n */\n public get zoom() { return this._zoomControl; }\n /**\n * @copy View360#gyro\n */\n public get gyro() { return this._gyroControl; }\n\n /**\n * Whether one of the controls is animating at the moment\n * @ko 현재 컨트롤 중 하나라도 동작중인지 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get animating() {\n return this._rotateControl.animating\n || this._zoomControl.animating\n || this._gyroControl.animating;\n }\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param element - Canvas element {@ko 캔버스 엘리먼트}\n * @param camera - Camera instance {@ko Camera 인스턴스}\n * @param options - Options for PanoControl {@ko PanoControl 옵션들}\n */\n public constructor(element: HTMLElement, camera: Camera, {\n useGrabCursor,\n scrollable,\n wheelScrollable,\n disableContextMenu,\n rotate,\n zoom,\n gyro\n }: PanoControlOptions) {\n // Bind Options\n this._useGrabCursor = useGrabCursor;\n this._disableContextMenu = disableContextMenu;\n\n // Set internal values\n this._camera = camera;\n this._controlEl = element;\n this._ignoreZoomScale = false;\n this._enabled = false;\n\n this._rotateControl = new RotateControl(element, !rotate, getObjectOption(rotate));\n this._zoomControl = new ZoomControl(element, !zoom, getObjectOption(zoom));\n this._gyroControl = new GyroControl(!gyro, getObjectOption(gyro));\n\n this._rotateControl.scrollable = scrollable;\n this._zoomControl.scrollable = wheelScrollable;\n\n this._bindEvents();\n }\n\n /**\n * Destroy the instance and remove all event listeners attached.\n * This also will reset CSS cursor to initial.\n * @ko 인스턴스를 삭제하고 부착된 모든 이벤트 리스너를 제거합니다.\n * 또한, 캔버스에 적용된 CSS cursor도 제거합니다.\n * @since 4.0.0\n */\n public destroy(): void {\n this.disable();\n this._rotateControl.destroy();\n this._zoomControl.destroy();\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n\n /**\n * Resize control to match target size.\n * @ko 컨트롤이 내부에 캐시하고 있는 크기값을 갱신합니다.\n * @param width New width {@ko 변경된 너비}\n * @param height New height {@ko 변경된 높이}\n * @since 4.0.0\n */\n public resize(width: number, height: number): void {\n const camera = this._camera;\n\n this._rotateControl.resize(camera.fov, camera.aspect, width, height);\n }\n\n /**\n * Enable this control and add event listeners.\n * @ko 컨트롤을 활성화하고 이벤트 리스너들을 추가합니다.\n * @since 4.0.0\n */\n public async enable(): Promise {\n if (this._enabled) return;\n\n if (!this._rotateControl.enableBlocked) {\n this._rotateControl.enable();\n }\n\n if (!this._zoomControl.enableBlocked) {\n this._zoomControl.enable();\n }\n\n if (!this._gyroControl.enableBlocked) {\n if (await GyroControl.isAvailable()) {\n this._gyroControl.enable();\n }\n }\n\n this.sync();\n\n if (this._disableContextMenu) {\n this._blockContextMenu();\n }\n\n this._enabled = true;\n }\n\n /**\n * Disable this control and remove all event listeners\n * @ko 컨트롤을 비활성화하고 모든 이벤트 리스너들을 제거합니다.\n * @since 4.0.0\n */\n public disable(): void {\n if (!this._enabled) return;\n\n this._rotateControl.disable();\n this._zoomControl.disable();\n this._gyroControl.disable();\n\n this._restoreContextMenu();\n\n this._enabled = false;\n }\n\n /**\n * Update control by given deltaTime\n * @ko 컨트롤을 주어진 시간만큼 업데이트합니다.\n * @param delta Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n * @internal\n */\n public update(delta: number): void {\n const camera = this._camera;\n const rotateControl = this._rotateControl;\n const zoomControl = this._zoomControl;\n const gyroControl = this._gyroControl;\n\n zoomControl.update(delta);\n const zoom = hfovToZoom(camera.fov, zoomControl.zoom);\n\n // Slow down rotation on zoom-in\n const zoomScale = this._ignoreZoomScale ? 1 : Math.max(zoom, 1);\n rotateControl.setZoomScale(zoomScale);\n rotateControl.updateRange(camera, zoom);\n rotateControl.update(delta);\n\n const yaw = rotateControl.yaw;\n const pitch = rotateControl.pitch;\n\n if (gyroControl.enabled) {\n gyroControl.update(camera, yaw, pitch, zoom);\n } else {\n camera.lookAt({\n yaw: yaw.val,\n pitch: pitch.val,\n zoom\n });\n }\n }\n\n /**\n * Synchronize this control's state to current camera state\n * @ko 컨트롤을 카메라의 현재 상태와 동기화합니다.\n * @since 4.0.0\n */\n public sync(): void {\n const camera = this._camera;\n\n this._zoomControl.sync(camera);\n this._rotateControl.sync(camera);\n }\n\n private _blockContextMenu() {\n const el = this._controlEl;\n\n el.addEventListener(BROWSER.EVENTS.CONTEXT_MENU, this._preventContextMenu);\n }\n\n private _restoreContextMenu() {\n const el = this._controlEl;\n\n el.removeEventListener(BROWSER.EVENTS.CONTEXT_MENU, this._preventContextMenu);\n }\n\n private _preventContextMenu = (evt: MouseEvent) => {\n evt.preventDefault();\n };\n\n private _setCursor(newCursor: ValueOf) {\n if (!this._useGrabCursor && newCursor !== BROWSER.CURSOR.NONE) return;\n\n const targetEl = this._controlEl;\n targetEl.style.cursor = newCursor;\n }\n\n private _bindEvents() {\n const rotateControl = this._rotateControl;\n const zoomControl = this._zoomControl;\n\n rotateControl.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n rotateControl.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n rotateControl.on(CONTROL_EVENTS.ENABLE, this._onEnable);\n rotateControl.on(CONTROL_EVENTS.DISABLE, this._onDisable);\n zoomControl.on(CONTROL_EVENTS.ENABLE, this._onEnable);\n zoomControl.on(CONTROL_EVENTS.DISABLE, this._onDisable);\n this._camera.on(CAMERA_EVENTS.ANIMATION_END, this._onCameraAnimationEnd);\n }\n\n private _onInputStart = (evt: RotateControlEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n if (this._useGrabCursor && !evt.isKeyboard) {\n this._setCursor(BROWSER.CURSOR.GRABBING);\n }\n };\n\n private _onInputEnd = (evt: RotateControlEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n if (this._useGrabCursor && !evt.isKeyboard) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n }\n };\n\n private _onEnable = ({\n control,\n updateCursor\n }: {\n control: CameraControl;\n updateCursor: boolean;\n }) => {\n if (updateCursor && this._useGrabCursor) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n }\n\n control.sync(this._camera);\n };\n\n private _onDisable = ({\n updateCursor\n }: {\n updateCursor: boolean\n }) => {\n if (updateCursor) {\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n };\n\n private _onCameraAnimationEnd = ({ animation }: { animation: CameraAnimation }) => {\n animation.getFinishPromise().then(() => {\n this.sync();\n });\n };\n}\n\nexport default PanoControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport TextureVideo from \"./TextureVideo\";\nimport TextureCube from \"./TextureCube\";\n\n/**\n * @hidden\n */\nabstract class Texture {\n public width: number;\n public height: number;\n public flipY: boolean;\n public wrapS: number;\n public wrapT: number;\n\n public constructor({\n width,\n height,\n flipY\n }: {\n width: number;\n height: number;\n flipY: boolean;\n }) {\n this.width = width;\n this.height = height;\n this.flipY = flipY;\n this.wrapS = WebGLRenderingContext.CLAMP_TO_EDGE;\n this.wrapT = WebGLRenderingContext.CLAMP_TO_EDGE;\n }\n\n public destroy() {\n // DO_NOTHING\n }\n\n public isVideo(): this is TextureVideo {\n return false;\n }\n\n public isCube(): this is TextureCube {\n return false;\n }\n}\n\nexport default Texture;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture from \"./Texture\";\n\n/**\n * @hidden\n */\nclass Texture2D extends Texture {\n public source: Exclude;\n\n public constructor({\n source,\n width,\n height,\n flipY\n }: {\n source: Exclude;\n width: number;\n height: number;\n flipY: boolean;\n }) {\n super({\n width,\n height,\n flipY\n });\n\n this.source = source;\n }\n}\n\nexport default Texture2D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"./Texture2D\";\n\n/**\n * @hidden\n */\nclass TextureVideo extends Texture2D {\n public source: HTMLVideoElement;\n\n public destroy() {\n const video = this.source;\n\n video.pause();\n video.removeAttribute(\"src\");\n video.load();\n }\n\n public isVideo(): this is TextureVideo { return true; }\n\n public isPaused() {\n const video = this.source;\n\n return video.paused || video.ended || video.readyState <= 2;\n }\n\n public hasAudio() {\n const video = this.source as any;\n\n if (video.audioTracks) {\n return video.audioTracks.length > 0;\n }\n\n if (video.webkitAudioDecodedByteCount != null) {\n return video.webkitAudioDecodedByteCount > 0;\n }\n\n if (video.mozHasAudio != null) {\n return video.mozHasAudio;\n }\n\n // We don't know whether the video has audio or not, return true\n return true;\n }\n}\n\nexport default TextureVideo;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture from \"./Texture\";\n\n/**\n * @hidden\n */\nclass TextureCube extends Texture {\n public sources: TexImageSource[];\n\n public constructor({\n sources,\n width,\n height,\n flipY\n }: {\n sources: TexImageSource[];\n width: number;\n height: number;\n flipY: boolean;\n }) {\n super({\n width,\n height,\n flipY\n });\n\n this.sources = sources;\n }\n\n public isCube(): this is TextureCube { return true; }\n}\n\nexport default TextureCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ImReady from \"@egjs/imready\";\nimport Texture from \"../texture/Texture\";\nimport Texture2D from \"../texture/Texture2D\";\nimport TextureVideo from \"../texture/TextureVideo\";\nimport TextureCube from \"../texture/TextureCube\";\nimport { getObjectOption, isString } from \"../utils\";\nimport { VideoConfig } from \"../type/external\";\nimport { ProjectionOptions } from \"../projection/Projection\";\n\n/**\n * @hidden\n */\nclass TextureLoader {\n private _loadChecker: ImReady;\n\n constructor() {\n this._loadChecker = new ImReady();\n }\n\n public async load(src: ProjectionOptions[\"src\"], video: ProjectionOptions[\"video\"]): Promise {\n if (video) {\n return this.loadVideo(src, getObjectOption(video));\n } else {\n if (Array.isArray(src) && src.length > 1) {\n return this.loadCubeImage(src);\n } else {\n const imgSrc = Array.isArray(src) ? src[0] : src;\n return this.loadImage(imgSrc);\n }\n }\n }\n\n public async loadImage(src: string | HTMLElement): Promise {\n const images = this._toImageArray(src);\n\n return this._load(images, resolve => {\n const image = images[0];\n\n resolve(new Texture2D({\n source: image,\n width: image.naturalWidth,\n height: image.naturalHeight,\n flipY: true\n }));\n });\n }\n\n public async loadCubeImage(src: Array): Promise {\n const images = this._toImageArray(src);\n\n return this._load(images, resolve => {\n resolve(new TextureCube({\n sources: images,\n width: images[0].naturalWidth,\n height: images[0].naturalHeight,\n flipY: false\n }));\n });\n }\n\n public async loadVideo(src: ProjectionOptions[\"src\"], videoConfig: Partial): Promise {\n const config: VideoConfig = {\n autoplay: true,\n muted: true,\n loop: false,\n volume: 1,\n ...videoConfig,\n };\n const video = this._toVideoElement(src, config);\n\n return this._load([video], resolve => {\n const { autoplay, muted } = config;\n\n video.currentTime = 0;\n if (autoplay && muted) {\n video.play().catch(() => void 0);\n }\n\n resolve(new TextureVideo({\n source: video,\n width: video.videoWidth,\n height: video.videoHeight,\n flipY: true\n }));\n });\n }\n\n private _load(content: HTMLElement[], onLoad: (resolve: (value: T) => void) => void): Promise {\n const loader = this._loadChecker;\n\n return new Promise((resolve, reject) => {\n loader.once(\"ready\", evt => {\n if (evt.errorCount > 0) return;\n\n onLoad(resolve);\n });\n\n loader.once(\"error\", reject);\n loader.check(content);\n });\n }\n\n private _toImageArray(src: ProjectionOptions[\"src\"]): HTMLImageElement[] {\n const srcs = Array.isArray(src) ? src : [src];\n\n return srcs.map(source => {\n if (isString(source)) {\n const imgEl = new Image();\n\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = source;\n\n return imgEl;\n } else {\n return source as HTMLImageElement;\n }\n });\n }\n\n private _toVideoElement(src: ProjectionOptions[\"src\"], {\n muted,\n loop,\n volume\n }: VideoConfig): HTMLVideoElement {\n if (src instanceof HTMLVideoElement) {\n return src;\n }\n\n const video = document.createElement(\"video\");\n\n video.crossOrigin = \"anonymous\";\n video.playsInline = true;\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.muted = muted;\n video.volume = volume;\n video.loop = loop;\n\n if (Array.isArray(src)) {\n src.forEach(source => this._appendSourceElement(video, source));\n } else {\n this._appendSourceElement(video, src);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0 && video.readyState < 1) {\n video.load();\n }\n\n return video;\n }\n\n private _appendSourceElement(video: HTMLMediaElement, src: string | HTMLElement) {\n if (src instanceof HTMLSourceElement) {\n return src;\n }\n\n const sourceEl = document.createElement(\"source\");\n sourceEl.src = src as string;\n video.appendChild(sourceEl);\n }\n}\n\nexport default TextureLoader;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * @internal\n */\nclass FrameAnimator {\n public maxDeltaTime: number;\n\n private _context: Window | XRSession;\n private _rafId: number;\n private _rafTimer: number;\n private _lastUpdateTime: number;\n\n /** */\n public constructor(maxDeltaTime: number, context: Window | XRSession = window) {\n this.maxDeltaTime = maxDeltaTime;\n\n this._context = context;\n this._rafId = -1;\n this._rafTimer = -1;\n this._lastUpdateTime = -1;\n }\n\n public start(callback: (delta: number, ...args: any[]) => any) {\n const context = this._context;\n\n // No context / callback set\n if (!context || !callback) return;\n\n // Animation already started\n if (this._rafId >= 0 || this._rafTimer >= 0) return;\n\n const loop = (_time: number, frame?: XRFrame) => {\n const time = Date.now();\n const delta = Math.min(time - this._lastUpdateTime, this.maxDeltaTime * 1000);\n\n callback(delta, frame);\n\n this._lastUpdateTime = time;\n this._rafId = context.requestAnimationFrame(loop);\n };\n\n this._lastUpdateTime = Date.now();\n this._rafId = context.requestAnimationFrame(loop);\n }\n\n public stop() {\n if (this._rafId >= 0) {\n this._context.cancelAnimationFrame(this._rafId);\n }\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n }\n\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n public changeContext(context: Window | XRSession) {\n this.stop();\n this._context = context;\n }\n}\n\nexport default FrameAnimator;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport * as BROWSER from \"../const/browser\";\n\n/**\n * Automatic resizer that uses both ResizeObserver and window resize event\n */\nclass AutoResizer {\n private _enabled: boolean;\n private _resizeObserver: ResizeObserver | null;\n private _useResizeObserver: boolean;\n private _onResize: () => any;\n\n public get useResizeObserver() { return this._useResizeObserver; }\n\n /**\n * Returns whether AutoResizer is enabled\n */\n public get enabled() { return this._enabled; }\n\n /** */\n public constructor(useResizeObserver: boolean, onResize: () => any) {\n this._useResizeObserver = useResizeObserver;\n\n this._enabled = false;\n this._resizeObserver = null;\n this._onResize = onResize;\n }\n\n /**\n * Enable resizer\n */\n public enable(element: HTMLElement): this {\n if (this._enabled) {\n this.disable();\n }\n\n if (this._useResizeObserver && !!window.ResizeObserver) {\n const bbox = element.getBoundingClientRect();\n const resizeImmediate = bbox.width !== 0 || bbox.height !== 0;\n\n const resizeObserver = new ResizeObserver(resizeImmediate ? this._skipFirstResize : this._onResize);\n\n resizeObserver.observe(element);\n\n this._resizeObserver = resizeObserver;\n } else {\n window.addEventListener(BROWSER.EVENTS.RESIZE, this._onResize);\n }\n\n this._enabled = true;\n\n return this;\n }\n\n /**\n * Disable resizer\n */\n public disable(): this {\n if (!this._enabled) return this;\n\n const resizeObserver = this._resizeObserver;\n if (resizeObserver) {\n resizeObserver.disconnect();\n this._resizeObserver = null;\n } else {\n window.removeEventListener(BROWSER.EVENTS.RESIZE, this._onResize);\n }\n\n this._enabled = false;\n\n return this;\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n private _skipFirstResize = (() => {\n let isFirstResize = true;\n\n return (() => {\n if (isFirstResize) {\n isFirstResize = false;\n\n return;\n }\n this._onResize();\n });\n })();\n}\n\nexport default AutoResizer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Camera from \"./Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport View360 from \"../View360\";\nimport * as BROWSER from \"../const/browser\";\nimport { CONTROL_EVENTS } from \"../const/internal\";\nimport { circulate, getObjectOption } from \"../utils\";\n\n/**\n * Options for {@link Autoplay}\n * @ko {@link Autoplay}용 옵션들\n * @since 4.0.0\n */\nexport interface AutoplayOptions {\n /**\n * @copy Autoplay#delay\n */\n delay: number;\n /**\n * @copy Autoplay#delayOnMouseLeave\n */\n delayOnMouseLeave: number;\n /**\n * @copy Autoplay#speed\n */\n speed: number;\n /**\n * @copy Autoplay#pauseOnHover\n */\n pauseOnHover: boolean;\n /**\n * @copy Autoplay#canInterrupt\n */\n canInterrupt: boolean;\n /**\n * @copy Autoplay#disableOnInterrupt\n */\n disableOnInterrupt: boolean;\n}\n\n/**\n * A manager class for autoplay feature.\n * @ko Autoplay 기능의 매니저 클래스.\n * @since 4.0.0\n */\nclass Autoplay {\n // Options\n private _delay: number;\n private _delayOnMouseLeave: number;\n private _speed: number;\n private _pauseOnHover: boolean;\n private _canInterrupt: boolean;\n private _disableOnInterrupt: boolean;\n\n // Internal values\n private _enableBlocked: boolean;\n private _camera: Camera;\n private _control: PanoControl;\n private _element: HTMLElement;\n private _enabled: boolean;\n private _interrupted: boolean;\n private _interruptionTimer: number;\n private _hovering: boolean;\n\n /**\n * Whether autoplay is enabled or not\n * @ko 자동재생 활성화 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * Whether autoplay is updating the camera at the moment\n * @ko 현재 자동재생이 동작중인지 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get playing() {\n return this._enabled && !this._interrupted;\n }\n\n /**\n * Reactivation delay after mouse input in milisecond.\n * @ko 재활성화되기까지의 시간 (밀리초 단위)\n * @default 2000\n * @since 4.0.0\n */\n public get delay() { return this._delay; }\n public set delay(val: number) { this._delay = val; }\n\n /**\n * Reactivation delay after mouse leave when using {@link AutoplayOptions#pauseOnHover}\n * @ko {@link AutoplayOptions#pauseOnHover} 사용시 마우스가 캔버스 영역을 떠난 뒤 자동재생이 다시 활성화되기까지의 시간\n * @default 0\n * @since 4.0.0\n */\n public get delayOnMouseLeave() { return this._delayOnMouseLeave; }\n public set delayOnMouseLeave(val: number) { this._delayOnMouseLeave = val; }\n\n /**\n * Y-axis(yaw) rotation speed\n * @ko Y-축 회전(yaw)의 속도\n * @default 1\n * @since 4.0.0\n */\n public get speed() { return this._speed; }\n public set speed(val: number) { this._speed = val; }\n\n /**\n * Whether to pause rotation on mouse hover\n * @ko 마우스가 캔버스 영역에 들어왔을 때 자동재생을 정지할지 여부\n * @default false\n * @since 4.0.0\n */\n public get pauseOnHover() { return this._pauseOnHover; }\n public set pauseOnHover(val: boolean) { this._pauseOnHover = val; }\n\n /**\n * Whether user can interrupt the rotation with click/wheel input\n * @ko 클릭이나 휠같은 사용자 인터랙션시 자동재생을 멈출지 여부\n * @default true\n * @since 4.0.0\n */\n public get canInterrupt() { return this._canInterrupt; }\n public set canInterrupt(val: boolean) { this._canInterrupt = val; }\n\n /**\n * Whether to disable autoplay on user interrupt\n * @ko 사용자 동작에 의해 자동재생이 정지할 때, {@link Autoplay#disable}을 호출하여 자동재생을 영구히 정지할지 여부\n * @default false\n * @since 4.0.0\n */\n public get disableOnInterrupt() { return this._disableOnInterrupt; }\n public set disableOnInterrupt(val: boolean) { this._disableOnInterrupt = val; }\n\n /**\n * Create new AutoPlayer instance\n * @param camera - Instance of the {@link Camera} {@ko Camera의 인스턴스}\n * @param element - Canvas element {@ko 캔버스 엘리먼트}\n * @param options - Autoplay options {@ko 자동재생 옵션들}\n * @since 4.0.0\n */\n public constructor(viewer: View360, element: HTMLElement, options: boolean | Partial) {\n this._camera = viewer.camera;\n this._control = viewer.control;\n this._element = element;\n\n this._enabled = false;\n this._interrupted = false;\n this._interruptionTimer = -1;\n this._hovering = false;\n\n const {\n delay = 2000,\n delayOnMouseLeave = 0,\n speed = 1,\n pauseOnHover = false,\n canInterrupt = true,\n disableOnInterrupt = false\n } = getObjectOption(options);\n\n this._enableBlocked = !options;\n this._delay = delay;\n this._delayOnMouseLeave = delayOnMouseLeave;\n this._speed = speed;\n this._pauseOnHover = pauseOnHover;\n this._canInterrupt = canInterrupt;\n this._disableOnInterrupt = disableOnInterrupt;\n }\n\n /**\n * Destroy the instance and remove all event listeners attached\n * @ko 인스턴스를 제거하고 연결된 모든 이벤트 핸들러를 삭제합니다.\n * @since 4.0.0\n */\n public destroy(): void {\n this.disable();\n }\n\n /**\n * Rotate camera by given deltaTime\n * @ko 주어진 deltaTime만큼 카메라를 회전시킵니다.\n * @param deltaTime - Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n */\n public update(deltaTime: number): void {\n if (!this._enabled) return;\n if (this._interrupted) {\n if (this._disableOnInterrupt) {\n this.disable();\n }\n\n return;\n }\n\n const camera = this._camera;\n const delta = -this._speed * deltaTime / 100;\n\n camera.yaw = circulate(camera.yaw + delta, 0, 360);\n }\n\n /**\n * Enable autoplay and add event listeners.\n * @ko 자동재생을 활성화하고 이벤트리스너들을 추가합니다.\n * @since 4.0.0\n */\n public enable(): void {\n const control = this._control;\n const element = this._element;\n\n if (this._enabled || control.gyro.enabled) return;\n\n control.rotate.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.rotate.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.zoom.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.zoom.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.gyro.on(CONTROL_EVENTS.ENABLE, this._onGyroEnable);\n\n element.addEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter, false);\n element.addEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave, false);\n\n this._enabled = true;\n this._enableBlocked = false;\n }\n\n /**\n * Enable autoplay after current `delay` value.\n * @ko 현재의 `delay`값만큼 시간이 지난 다음에 자동재생을 활성화합니다.\n * @since 4.0.0\n */\n public enableAfterDelay() {\n this.enable();\n this._interrupted = true;\n this._setUninterruptedAfterDelay(this._delay);\n }\n\n /**\n * Disable autoplay and remove all event handlers.\n * @ko 자동재생을 비활성화하고 모든 이벤트 핸들러를 제거합니다.\n * @since 4.0.0\n */\n public disable(): void {\n if (!this._enabled) return;\n\n const control = this._control;\n const element = this._element;\n\n control.rotate.off(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.rotate.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.zoom.off(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.zoom.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.gyro.off(CONTROL_EVENTS.ENABLE, this._onGyroEnable);\n\n element.removeEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter, false);\n element.removeEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave, false);\n\n this._enabled = false;\n this._interrupted = false;\n this._hovering = false;\n\n this._clearTimeout();\n }\n\n private _onInputStart = () => {\n if (!this._canInterrupt) return;\n\n this._interrupted = true;\n this._clearTimeout();\n };\n\n private _onInputEnd = () => {\n this._setUninterruptedAfterDelay(this._delay);\n };\n\n private _onGyroEnable = () => {\n this.disable();\n };\n\n private _onMouseEnter = () => {\n if (!this._pauseOnHover) return;\n this._interrupted = true;\n this._hovering = true;\n };\n\n private _onMouseLeave = () => {\n if (!this._pauseOnHover) return;\n this._hovering = false;\n this._setUninterruptedAfterDelay(this._delayOnMouseLeave);\n };\n\n private _setUninterruptedAfterDelay(delay: number): void {\n if (this._hovering) return;\n\n this._clearTimeout();\n\n if (delay > 0) {\n this._interruptionTimer = window.setTimeout(() => {\n this._interrupted = false;\n this._interruptionTimer = -1;\n }, delay);\n } else {\n this._interrupted = false;\n this._interruptionTimer = -1;\n }\n }\n\n private _clearTimeout(): void {\n if (this._interruptionTimer >= 0) {\n window.clearTimeout(this._interruptionTimer);\n this._interruptionTimer = -1;\n }\n }\n}\n\nexport default Autoplay;\n","import { mat4 } from \"gl-matrix\";\nimport Component from \"@egjs/component\";\nimport WebGLContext from \"./WebGLContext\";\nimport GyroControl from \"../control/GyroControl\";\nimport * as BROWSER from \"../const/browser\";\nimport { SESSION_VR, XR_REFERENCE_SPACE } from \"../const/internal\";\nimport { EVENTS } from \"../const/external\";\n\ninterface XRSessionOptions extends XRSessionInit {\n [key: string]: any;\n}\n\n/**\n * WebXR manager class\n * @ko WebXR 매니저 클래스\n * @since 4.0.0\n */\nclass XRManager extends Component<{\n /**\n * An event that fires on entering VR session\n * @ko VR 세션 진입시에 트리거되는 이벤트\n * @eventName vrStart\n * @eventOf XRManager\n * @version 4.0.0\n */\n [EVENTS.VR_START]: {\n session: XRSession;\n };\n /**\n * An event that fires on exiting VR session\n * @ko VR 세션에서 나갈 때 트리거되는 이벤트\n * @eventName vrEnd\n * @eventOf XRManager\n * @version 4.0.0\n */\n [EVENTS.VR_END]: void;\n}> {\n private _ctx: WebGLContext;\n private _xrSession: XRSession | null;\n private _xrRefSpace: XRReferenceSpace | null;\n private _options: XRSessionOptions;\n\n /**\n * Create new instance.\n * 새 인스턴스를 생성합니다.\n * @param ctx - Instance of WebGL context helper {@ko WebGL 콘텍스트 헬퍼의 인스턴스}\n * @param options - Options {@ko 옵션들}\n */\n public constructor(ctx: WebGLContext, options: XRSessionOptions = {}) {\n super();\n\n this._xrSession = null;\n this._xrRefSpace = null;\n this._ctx = ctx;\n this._options = options;\n }\n\n /**\n * Destroy instance and end XR session if there was any.\n * @ko 인스턴스를 제거하고, XR 세션이 존재할 경우 종료합니다.\n * @since 4.0.0\n */\n public destroy = () => {\n this.exit();\n this.off();\n };\n\n /**\n * Returns WebXR availability.\n * @ko WebXR 사용 가능 여부를 반환합니다.\n * @since 4.0.0\n */\n public async isAvailable(): Promise {\n // eslint-disable-next-line compat/compat\n const xr = window.navigator.xr;\n if (!xr) return false;\n\n return xr.isSessionSupported(SESSION_VR)\n .then(available => {\n return available;\n }).catch(() => {\n return false;\n });\n }\n\n /**\n * Enter VR session\n * @ko VR 세션에 진입합니다.\n * @since 4.0.0\n */\n public async enter() {\n const ctx = this._ctx;\n\n // eslint-disable-next-line compat/compat\n const xr = window.navigator.xr;\n if (!xr) return;\n\n await GyroControl.requestSensorPermission();\n\n const options = {\n ...{\n requiredFeatures: [XR_REFERENCE_SPACE]\n },\n ...this._options\n };\n\n await ctx.makeXRCompatible();\n\n const session = await xr.requestSession(SESSION_VR, options);\n ctx.bindXRLayer(session);\n\n const refSpace = await session.requestReferenceSpace(XR_REFERENCE_SPACE);\n\n this._setSession(session, refSpace);\n\n this.trigger(EVENTS.VR_START, {\n session\n });\n }\n\n /**\n * Exit VR session\n * @ko VR 세션에서 나갑니다.\n * @since 4.0.0\n */\n public exit() {\n const xrSession = this._xrSession;\n\n if (xrSession) {\n xrSession.end()\n .catch(() => void 0);\n }\n\n this._xrSession = null;\n this._xrRefSpace = null;\n }\n\n /**\n * @hidden\n */\n public canRender(frame: XRFrame) {\n const refSpace = this._xrRefSpace;\n\n if (!refSpace) return false;\n\n const pose = frame.getViewerPose(refSpace);\n\n return !!pose;\n }\n\n /**\n * @hidden\n */\n public getEyeParams(frame: XRFrame): Array<{\n viewport: XRViewport;\n vMatrix: mat4;\n pMatrix: mat4;\n }> | null {\n const session = frame.session;\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n if (!pose) return null;\n\n const glLayer = session.renderState.baseLayer;\n\n if (!glLayer) return null;\n\n return pose.views.map(view => {\n const viewport = glLayer.getViewport(view)!;\n const vMatrix = view.transform.inverse.matrix;\n\n return {\n viewport,\n vMatrix,\n pMatrix: view.projectionMatrix\n };\n });\n }\n\n private _setSession(session: XRSession, refSpace: XRReferenceSpace) {\n this._xrSession = session;\n this._xrRefSpace = refSpace;\n\n session.addEventListener(BROWSER.EVENTS.XR_END, this._onSessionEnd);\n }\n\n private _onSessionEnd = () => {\n this.exit();\n this.trigger(EVENTS.VR_END);\n }\n}\n\nexport default XRManager;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { vec3 } from \"gl-matrix\";\n\n/**\n * Hotspot data\n * @ko 핫스팟 데이터\n * @since 4.0.0\n */\nclass Hotspot {\n /**\n * HTMLElement of the hotspot\n * @ko 핫스팟의 HTMLElement\n * @since 4.0.0\n */\n public readonly element: HTMLElement;\n /**\n * Position to render hotspot\n * @ko 핫스팟을 렌더링할 위치\n * @since 4.0.0\n */\n public readonly position: vec3;\n\n public constructor(element: HTMLElement, position: vec3) {\n this.element = element;\n this.position = position;\n }\n}\n\nexport default Hotspot;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { vec2, vec3 } from \"gl-matrix\";\nimport Hotspot from \"./Hotspot\";\nimport Camera from \"../core/Camera\";\nimport WebGLRenderer from \"../core/WebGLRenderer\";\nimport View360Error from \"../core/View360Error\";\nimport { getNullableElement } from \"../utils\";\nimport ERROR from \"../const/error\";\nimport { DEFAULT_CLASS } from \"../const/external\";\nimport { DEG_TO_RAD } from \"../const/internal\";\n\n/**\n * Options for {@link HotspotRenderer}\n * @ko {@link HotspotRenderer}용 옵션들\n * @since 4.0.0\n */\nexport interface HotspotOptions {\n /**\n * Apply scale for hotspots, makes their size sync with background panorama image.\n * @ko 핫스팟에 스케일을 적용해서 배경 파노라마 이미지의 크기 변화와 동일하게 크기를 조절합니다.\n * @since 4.0.0\n */\n zoom: boolean;\n}\n\n/**\n * Hotspot renderer\n * @ko Hotspot 렌더러\n * @since 4.0.0\n */\nclass HotspotRenderer {\n // Options\n private _zoom: HotspotOptions[\"zoom\"];\n\n // Internal properties\n private _containerEl: HTMLElement | null;\n private _renderer: WebGLRenderer;\n private _hotspots: Hotspot[];\n\n /**\n * Create new instance\n * @ko 새 인스턴스를 생성합니다.\n * @param rootEl - Container element for hotspots {@ko 핫스팟들의 컨테이너 엘리먼트}\n * @param renderer - instance of WebGLRenderer {@ko WebGLRenderer의 인스턴스}\n * @param options - Hotspot options {@ko Hotspot 옵션들 }\n */\n public constructor(rootEl: HTMLElement, renderer: WebGLRenderer, {\n zoom = false\n }: Partial) {\n this._containerEl = getNullableElement(`.${DEFAULT_CLASS.HOTSPOT_CONTAINER}`, rootEl);\n this._renderer = renderer;\n this._hotspots = [];\n\n this._zoom = zoom;\n }\n\n /**\n * Refresh hotspots by collecting hotspot elements from current hotspot root element\n * @ko 현재 핫스팟 루트 엘리먼트 내에서 핫스팟 엘리먼트들을 수집하여 갱신합니다.\n * @throws {ERROR_CODES.INSUFFICIENT_ARGS} if data-position doesn't include all x, y, z values {@ko data-position이 x, y, z좌표를 전부 포함하고 있지 않을 때}\n */\n public refresh() {\n const container = this._containerEl;\n if (!container) return;\n\n const hotspotEls = [].slice.apply(container.querySelectorAll(`.${DEFAULT_CLASS.HOTSPOT}`)) as HTMLElement[];\n this._hotspots = hotspotEls.map(el => this._parseHotspot(el));\n }\n\n /**\n * Render hotspots\n * @ko 핫스팟들을 렌더링합니다.\n * @param camera - Instance of Camera {@ko Camera의 인스턴스}\n */\n public render(camera: Camera) {\n const hotspots = this._hotspots;\n const halfWidth = this._renderer.width * 0.5;\n const halfHeight = this._renderer.height * 0.5;\n const zoom = camera.zoom;\n const centerTransform = \"translate(-50%, -50%)\";\n const zoomTransform = this._zoom ? `scale(${zoom})` : \"\";\n\n hotspots.forEach(hotspot => {\n const position = hotspot.position;\n const relPos = vec3.create();\n\n vec3.copy(relPos, position);\n vec3.transformMat4(relPos, relPos, camera.viewMatrix);\n vec3.transformMat4(relPos, relPos, camera.projectionMatrix);\n\n if (relPos[2] > 1 || relPos[2] < 0) {\n hotspot.element.classList.remove(DEFAULT_CLASS.HOTSPOT_VISIBLE);\n return;\n }\n\n const screenPos = vec2.fromValues(\n relPos[0] * halfWidth + halfWidth,\n -relPos[1] * halfHeight + halfHeight\n );\n\n hotspot.element.classList.add(DEFAULT_CLASS.HOTSPOT_VISIBLE);\n hotspot.element.style.transform = [\n centerTransform,\n `translate(${screenPos[0]}px, ${screenPos[1]}px)`,\n zoomTransform\n ].join(\" \");\n });\n }\n\n private _parseHotspot(element: HTMLElement): Hotspot {\n const yawStr = element.dataset.yaw;\n const pitchStr = element.dataset.pitch;\n const positionStr = element.dataset.position;\n\n if (yawStr || pitchStr) {\n const yaw = yawStr ? parseFloat(yawStr) : 0;\n const pitch = pitchStr ? parseFloat(pitchStr) : 0;\n\n const position = this._yawPitchToVec3(yaw, pitch);\n\n return new Hotspot(element, position);\n } else if (positionStr) {\n const pos: number[] = positionStr.split(\" \").map(val => parseFloat(val));\n if (pos.length < 3) {\n throw new View360Error(ERROR.MESSAGES.INSUFFICIENT_ARGS(positionStr, \"hotspot attribute \\\"data-position\\\"\"), ERROR.CODES.INSUFFICIENT_ARGS);\n }\n\n return new Hotspot(element, vec3.fromValues(pos[0], pos[1], pos[2]));\n } else {\n // Place hotspot at yaw: 0, pitch: 0\n const defaultPos = vec3.fromValues(0, 0, -1);\n\n return new Hotspot(element, defaultPos);\n }\n }\n\n private _yawPitchToVec3(yaw: number, pitch: number) {\n const yawRad = yaw * DEG_TO_RAD;\n const pitchRad = pitch * DEG_TO_RAD;\n const position = vec3.create();\n\n position[1] = Math.sin(pitchRad);\n position[2] = Math.cos(pitchRad);\n\n position[0] = position[2] * Math.sin(-yawRad);\n position[2] = -position[2] * Math.cos(-yawRad);\n\n return position;\n }\n}\n\nexport default HotspotRenderer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"../geometry/Geometry\";\nimport { VAO } from \"../type/internal\";\n\n/**\n * @hidden\n */\nclass VertexArrayObject {\n public readonly obj: VAO | null;\n public readonly geometry: Geometry;\n public readonly buffers: {\n indicies: WebGLBuffer;\n position: WebGLBuffer;\n uv: WebGLBuffer;\n }\n\n public get count() { return this.geometry.indicies.count; }\n\n constructor(obj: VAO | null, geometry: Geometry, buffers: VertexArrayObject[\"buffers\"]) {\n this.obj = obj;\n this.geometry = geometry;\n this.buffers = buffers;\n }\n}\n\nexport default VertexArrayObject;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4 } from \"gl-matrix\";\nimport Uniform from \"../uniform/Uniform\";\nimport Camera from \"./Camera\";\nimport Object3D from \"./Object3D\";\nimport ShaderProgram from \"./ShaderProgram\";\nimport View360Error from \"./View360Error\";\nimport VertexArrayObject from \"./VertexArrayObject\";\nimport VertexData from \"./VertexData\";\nimport Texture from \"../texture/Texture\";\nimport Geometry from \"../geometry/Geometry\";\nimport * as BROWSER from \"../const/browser\";\nimport ERROR from \"../const/error\";\nimport { DEFAULT_CLASS } from \"../const/external\";\nimport { UniformLocations } from \"../type/internal\";\n\n/**\n * @hidden\n */\nclass WebGLContext {\n private _canvas: HTMLCanvasElement;\n private _gl: WebGLRenderingContext | WebGL2RenderingContext;\n private _contextLost: boolean;\n private _maxTextureSize: number;\n private _isWebGL2: boolean;\n private _debug: boolean;\n private _extensions: {\n vao: OES_vertex_array_object | null;\n loseContext: WEBGL_lose_context | null;\n };\n\n public get canvas() { return this._canvas; }\n public get maxTextureSize() { return this._maxTextureSize; }\n public get isWebGL2() { return this._isWebGL2; }\n public get supportVAO() { return this._isWebGL2 || !!this._extensions.vao; }\n public get lost() { return this._contextLost; }\n public get debug() { return this._debug; }\n\n public constructor(canvas: HTMLCanvasElement, debug: boolean) {\n this._canvas = canvas;\n this._contextLost = false;\n this._debug = debug;\n this._extensions = {\n vao: null,\n loseContext: null\n };\n }\n\n public init() {\n const canvas = this._canvas;\n\n const { gl, isWebGL2 } = this._getContext(canvas);\n\n this._gl = gl;\n this._maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n this._isWebGL2 = isWebGL2;\n\n if (!this._isWebGL2) {\n this._extensions.vao = gl.getExtension(\"OES_vertex_array_object\");\n }\n\n this._extensions.loseContext = gl.getExtension(\"WEBGL_lose_context\");\n\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_LOST, this._onContextLost);\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_RESTORED, this._onContextRestore);\n\n // gl.enable(gl.DEPTH_TEST);\n }\n\n public destroy() {\n const gl = this._gl;\n const canvas = this._canvas;\n\n if (gl) {\n // gl is not defined when destroy is called before init\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n }\n\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_LOST, this._onContextLost);\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_RESTORED, this._onContextRestore);\n }\n\n public forceLoseContext() {\n const extension = this._extensions.loseContext;\n\n if (!extension) return;\n\n extension.loseContext();\n }\n\n public forceRestoreContext() {\n const extension = this._extensions.loseContext;\n\n if (!extension) return;\n\n extension.restoreContext();\n }\n\n public clear() {\n const gl = this._gl;\n\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n\n public resize() {\n const gl = this._gl;\n\n gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n }\n\n public viewport(x: number, y: number, width: number, height: number) {\n const gl = this._gl;\n\n gl.viewport(x, y, width, height);\n }\n\n public createVAO(geometry: Geometry, shaderProgram: ShaderProgram) {\n const nativeVAO = this._createNativeVAO();\n\n const vao = new VertexArrayObject(nativeVAO, geometry, {\n indicies: this._createBuffer(),\n position: this._createBuffer(),\n uv: this._createBuffer()\n });\n\n if (nativeVAO) {\n this._bindNativeVAO(nativeVAO);\n this._supplyGeometryData(vao, shaderProgram);\n this._bindNativeVAO(null);\n this._unbindBuffers();\n }\n\n return vao;\n }\n\n public draw(vao: VertexArrayObject, shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n if (vao.obj) {\n this._bindNativeVAO(vao.obj);\n } else {\n this._supplyGeometryData(vao, shaderProgram);\n }\n\n gl.drawElements(gl.TRIANGLES, vao.count, gl.UNSIGNED_SHORT, 0);\n\n if (vao.obj) {\n this._bindNativeVAO(null);\n } else {\n this._unbindBuffers();\n }\n }\n\n public releaseVAO(vao: VertexArrayObject) {\n if (vao.obj) {\n this._deleteNativeVAO(vao.obj);\n }\n\n this._deleteBuffer(vao.buffers.indicies);\n this._deleteBuffer(vao.buffers.position);\n this._deleteBuffer(vao.buffers.uv);\n }\n\n public getUniformLocations>(program: WebGLProgram, uniforms: T): UniformLocations {\n const gl = this._gl;\n\n const uniformLocations = Object.keys(uniforms).reduce((locations, key) => {\n locations[key as keyof T] = gl.getUniformLocation(program, key)!;\n\n return locations;\n }, {} as UniformLocations);\n\n return {\n ...this._getCommonUniformLocations(program),\n ...uniformLocations\n };\n }\n\n public updateCommonUniforms(entity: Object3D, camera: Camera, shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniformLocations = shaderProgram.uniformLocations;\n\n // We're using \"matrix\"(=local matrix) here for efficiency\n // As projection doesn't require world matrix, as it doesn't have any parent or child\n const matrix = entity.matrix;\n const mvMatrix = mat4.create();\n mat4.multiply(mvMatrix, camera.viewMatrix, matrix);\n\n gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix);\n gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, camera.projectionMatrix);\n }\n\n public updateVRUniforms(shaderProgram: ShaderProgram, mvMatrix: mat4, pMatrix: mat4, eyeIndex: number) {\n const gl = this._gl;\n\n const uniformLocations = shaderProgram.uniformLocations;\n\n gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix);\n gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, pMatrix);\n\n if (uniformLocations.uEye) {\n gl.uniform1f(uniformLocations.uEye, eyeIndex);\n }\n }\n\n public updateUniforms(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniforms = shaderProgram.uniforms;\n const uniformLocations = shaderProgram.uniformLocations;\n\n for (const key in uniforms) {\n const uniform = uniforms[key];\n const location = uniformLocations[key];\n\n if (!uniform) continue;\n\n if (uniform.needsUpdate) {\n uniform.update(gl, location, this._isWebGL2);\n }\n }\n }\n\n public releaseShaderResources(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniforms = shaderProgram.uniforms;\n\n for (const key in uniforms) {\n const uniform = uniforms[key];\n\n if (!uniform) continue;\n\n if (uniform.needsUpdate) {\n uniform.destroy(gl);\n }\n }\n\n gl.deleteProgram(shaderProgram.program);\n }\n\n public useProgram(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n gl.useProgram(shaderProgram.program);\n }\n\n public createProgram(vertexShader: string, fragmentShader: string) {\n const gl = this._gl;\n const program = gl.createProgram()!;\n\n const vs = this._compileShader(gl.VERTEX_SHADER, vertexShader);\n const fs = this._compileShader(gl.FRAGMENT_SHADER, fragmentShader);\n\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.bindAttribLocation(program, 0, \"position\");\n gl.bindAttribLocation(program, 1, \"uv\");\n gl.linkProgram(program);\n\n if (this._debug && !gl.getProgramParameter(program, gl.LINK_STATUS)) {\n let shaderLog: string | null = null;\n\n if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {\n shaderLog = gl.getShaderInfoLog(vs);\n } else if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {\n shaderLog = gl.getShaderInfoLog(fs);\n }\n\n throw new View360Error(ERROR.MESSAGES.FAILED_LINKING_PROGRAM(gl.getProgramInfoLog(program), shaderLog), ERROR.CODES.FAILED_LINKING_PROGRAM);\n }\n\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n\n return program;\n }\n\n public createWebGLTexture(texData: Texture): WebGLTexture {\n const gl = this._gl;\n const texture = gl.createTexture()!;\n\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texData.wrapS);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texData.wrapT);\n\n if (!texData.isVideo() && this._isWebGL2) {\n const gl2 = gl as WebGL2RenderingContext;\n\n gl2.texStorage2D(gl2.TEXTURE_2D, 1, gl2.RGBA8, texData.width, texData.height);\n }\n\n return texture;\n }\n\n public createWebGLCubeTexture(texData: Texture, size: number): WebGLTexture {\n const gl = this._gl;\n const texture = gl.createTexture()!;\n\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, texData.wrapS);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, texData.wrapT);\n\n if (this._isWebGL2) {\n const gl2 = gl as WebGL2RenderingContext;\n\n gl2.texStorage2D(gl2.TEXTURE_CUBE_MAP, 1, gl2.RGBA8, size, size);\n }\n\n return texture;\n }\n\n public async makeXRCompatible() {\n const gl = this._gl;\n const attributes = gl.getContextAttributes();\n\n if (attributes && attributes.xrCompatible !== true) {\n await gl.makeXRCompatible();\n }\n }\n\n public bindXRLayer(session: XRSession) {\n const gl = this._gl;\n const xrLayer = new XRWebGLLayer(session, gl);\n session.updateRenderState({ baseLayer: xrLayer });\n }\n\n public bindXRFrame(frame: XRFrame) {\n const gl = this._gl;\n const session = frame.session;\n const baseLayer = session.renderState.baseLayer!;\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer);\n }\n\n public useDefaultFrameBuffer() {\n const gl = this._gl;\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n private _createBuffer(): WebGLBuffer {\n return this._gl.createBuffer()!;\n }\n\n private _deleteBuffer(buffer: WebGLBuffer) {\n return this._gl.deleteBuffer(buffer);\n }\n\n private _createNativeVAO() {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n return (gl as WebGL2RenderingContext).createVertexArray()!;\n } else {\n const ext = this._extensions.vao;\n\n return ext?.createVertexArrayOES() || null;\n }\n }\n\n private _bindNativeVAO(vao: WebGLVertexArrayObject | null) {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n (gl as WebGL2RenderingContext).bindVertexArray(vao);\n } else {\n const ext = this._extensions.vao;\n\n ext?.bindVertexArrayOES(vao);\n }\n }\n\n private _deleteNativeVAO(vao: WebGLVertexArrayObject | null) {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n (gl as WebGL2RenderingContext).deleteVertexArray(vao);\n } else {\n const ext = this._extensions.vao;\n\n ext?.deleteVertexArrayOES(vao);\n }\n }\n\n private _supplyGeometryData(vao: VertexArrayObject, shaderProgram: ShaderProgram) {\n const geometry = vao.geometry;\n\n this._supplyIndiciesData(geometry.indicies, vao.buffers.indicies);\n this._supplyAttributeData(geometry.vertices, shaderProgram.program, \"position\", vao.buffers.position);\n this._supplyAttributeData(geometry.uvs, shaderProgram.program, \"uv\", vao.buffers.uv);\n }\n\n private _unbindBuffers() {\n const gl = this._gl;\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n }\n\n private _supplyIndiciesData(indicies: VertexData, buffer: WebGLBuffer) {\n const gl = this._gl;\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicies.data, gl.STATIC_DRAW);\n }\n\n private _supplyAttributeData(attribute: VertexData, program: WebGLProgram, name: string, buffer: WebGLBuffer) {\n const gl = this._gl;\n const attribLocation = gl.getAttribLocation(program, name);\n\n // Attribute not used\n if (attribLocation < 0) return;\n\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ARRAY_BUFFER, attribute.data, gl.STATIC_DRAW);\n gl.vertexAttribPointer(attribLocation, attribute.itemSize, gl.FLOAT, false, 0, 0);\n gl.enableVertexAttribArray(attribLocation);\n }\n\n private _compileShader(type: number, src: string) {\n const gl = this._gl;\n const shader = gl.createShader(type)!;\n\n gl.shaderSource(shader, src);\n gl.compileShader(shader);\n\n return shader;\n }\n\n private _getCommonUniformLocations(program: WebGLProgram) {\n const gl = this._gl;\n\n return {\n uMVMatrix: gl.getUniformLocation(program, \"uMVMatrix\")!,\n uPMatrix: gl.getUniformLocation(program, \"uPMatrix\")!\n };\n }\n\n private _getContext(canvas: HTMLCanvasElement): {\n gl: WebGLRenderingContext | WebGL2RenderingContext;\n isWebGL2: boolean;\n } {\n const webglIdentifiers = [\"webgl2\", \"webgl\", \"experimental-webgl\", \"webkit-3d\", \"moz-webgl\"];\n let context: WebGLRenderingContext | null = null;\n let isWebGL2 = false;\n const contextAttributes = {\n preserveDrawingBuffer: false,\n antialias: false\n };\n\n const onWebglContextCreationError = e => e.statusMessage;\n\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_CREATE_ERROR, onWebglContextCreationError);\n\n for (const identifier of webglIdentifiers) {\n try {\n context = canvas.getContext(identifier, contextAttributes) as WebGLRenderingContext;\n isWebGL2 = identifier === \"webgl2\";\n } catch (t) {} // eslint-disable-line no-empty\n if (context) {\n break;\n }\n }\n\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_CREATE_ERROR, onWebglContextCreationError);\n\n if (!context) {\n throw new View360Error(ERROR.MESSAGES.WEBGL_NOT_SUPPORTED, ERROR.CODES.WEBGL_NOT_SUPPORTED);\n }\n\n return {\n gl: context,\n isWebGL2\n };\n }\n\n private _onContextLost = () => {\n const canvas = this._canvas;\n canvas.classList.add(DEFAULT_CLASS.CTX_LOST);\n this._contextLost = true;\n };\n\n private _onContextRestore = () => {\n const canvas = this._canvas;\n canvas.classList.remove(DEFAULT_CLASS.CTX_LOST);\n this._contextLost = false;\n };\n}\n\nexport default WebGLContext;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4 } from \"gl-matrix\";\nimport Camera from \"./Camera\";\nimport Projection from \"../projection/Projection\";\nimport WebGLContext from \"./WebGLContext\";\nimport XRManager from \"./XRManager\";\n\n/**\n * Projection renderer, based on WebGL\n * @ko WebGL 기반의 프로젝션 렌더러\n * @since 4.0.0\n */\nclass WebGLRenderer {\n private _canvas: HTMLCanvasElement;\n private _elementSize: { x: number, y: number };\n private _pixelRatio: number;\n\n public readonly ctx: WebGLContext;\n\n /**\n * Canvas element\n * @ko 캔버스 엘리먼트\n * @since 4.0.0\n */\n public get canvas() { return this._canvas; }\n /**\n * Canvas's width (`devicePixelRatio` is not applied)\n * @ko 캔버스의 보이는 너비 (`devicePixelRatio`가 적용되지 않은)\n * @since 4.0.0\n */\n public get width() { return this._elementSize.x; }\n /**\n * Canvas's height (`devicePixelRatio` is not applied)\n * @ko 캔버스의 높이 (`devicePixelRatio`가 적용되지 않은)\n * @since 4.0.0\n */\n public get height() { return this._elementSize.y; }\n /**\n * Current `devicePixelRatio` value.\n * @ko 현재 `devicePixelRatio` 값.\n * @since 4.0.0\n * @example\n * ```js\n * cosnt renderingWidth = view360.renderer.width * view360.renderer.pixelRatio;\n * ```\n */\n public get pixelRatio() { return this._pixelRatio; }\n /**\n * Width / height ratio (= width / height)\n * @ko 너비 / 높이의 비율 (= width / height)\n * @since 4.0.0\n * @example\n * ```js\n * const aspect = view360.renderer.width / view360.renderer.pixelRatio;\n * assert(aspect === view360.renderer.aspect);\n * ```\n */\n public get aspect() { return this._elementSize.x / this._elementSize.y; }\n\n /**\n * Create new instance\n * @ko 새 인스턴스를 생성합니다.\n * @param canvas - Canvas element {@ko 캔버스 엘리먼트}\n * @param debug - Whether to enable WebGL debugging {@ko WebGL debug 활성화 여부 }\n */\n public constructor(canvas: HTMLCanvasElement, debug: boolean) {\n this._canvas = canvas;\n this._elementSize = { x: 0, y: 0 };\n this._pixelRatio = 1;\n this.ctx = new WebGLContext(canvas, debug);\n }\n\n /**\n * Destroy instance and release all resources.\n * @ko 인스턴스를 제거하고 사용된 리소스를 전부 해제합니다.\n * @since 4.0.0\n */\n public destroy() {\n const canvas = this._canvas;\n\n this.ctx.destroy();\n canvas.width = 1;\n canvas.height = 1;\n }\n\n /**\n * Resize canvas and renew inner size cache.\n * @ko 캔버스의 크기를 재계산해서 내부의 사이즈 캐시값을 갱신합니다.\n * @since 4.0.0\n */\n public resize() {\n const canvas = this._canvas;\n const canvasSize = this._elementSize;\n const devicePixelRatio = window.devicePixelRatio;\n\n canvasSize.x = canvas.clientWidth;\n canvasSize.y = canvas.clientHeight;\n\n canvas.width = canvasSize.x * devicePixelRatio;\n canvas.height = canvasSize.y * devicePixelRatio;\n\n this._pixelRatio = devicePixelRatio;\n this.ctx.resize();\n }\n\n /**\n * Render projection\n * @ko 프로젝션을 렌더링합니다.\n * @param projection - Projection to render {@ko 렌더링할 프로젝션}\n * @param cameraa - Camera instance {@ko 카메라의 인스턴스}\n * @since 4.0.0\n */\n public render(projection: Projection, camera: Camera) {\n const ctx = this.ctx;\n const mesh = projection.getMesh();\n if (ctx.lost || !mesh) return;\n\n ctx.clear();\n ctx.useProgram(mesh.program);\n ctx.updateCommonUniforms(mesh, camera, mesh.program);\n projection.update(camera);\n ctx.updateUniforms(mesh.program);\n ctx.draw(mesh.vao, mesh.program);\n }\n\n /**\n * Render VR frame, only used for rendering frames inside VR sessions.\n * @ko VR 프레임을 렌더링합니다. VR 세션 진입 도중에만 사용됩니다.\n * @internal\n * @param projection - Projection to render {@ko 렌더링할 프로젝션}\n * @param vr - Instance of XRManager {@ko XRManager의 인스턴스}\n * @param frame - VR frame {@ko VR 프레임}\n * @since 4.0.0\n */\n public renderVR(projection: Projection, vr: XRManager, frame: XRFrame) {\n const ctx = this.ctx;\n const mesh = projection.getMesh();\n const eyeParams = vr.getEyeParams(frame);\n\n if (!eyeParams || !mesh) return;\n\n ctx.bindXRFrame(frame);\n ctx.useProgram(mesh.program);\n ctx.updateUniforms(mesh.program);\n\n eyeParams.forEach((eye, eyeIndex) => {\n const viewport = eye.viewport;\n // We're using \"mesh.matrix\"(=local matrix) here for efficiency\n // As projection doesn't require world matrix, as it doesn't have any parent or child\n const mvMatrix = mat4.multiply(mat4.create(), eye.vMatrix, mesh.matrix);\n\n ctx.viewport(viewport.x, viewport.y, viewport.width, viewport.height);\n ctx.updateVRUniforms(mesh.program, mvMatrix, eye.pMatrix, eyeIndex);\n ctx.draw(mesh.vao, mesh.program);\n });\n }\n}\n\nexport default WebGLRenderer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport Camera, { CameraOptions } from \"./core/Camera\";\nimport PanoControl, { PanoControlOptions } from \"./control/PanoControl\";\nimport TextureLoader from \"./core/TextureLoader\";\nimport FrameAnimator from \"./core/FrameAnimator\";\nimport AutoResizer from \"./core/AutoResizer\";\nimport Autoplay, { AutoplayOptions } from \"./core/Autoplay\";\nimport XRManager from \"./core/XRManager\";\nimport View360Error from \"./core/View360Error\";\nimport Projection from \"./projection/Projection\";\nimport HotspotRenderer, { HotspotOptions } from \"./hotspot/HotspotRenderer\";\nimport WebGLRenderer from \"./core/WebGLRenderer\";\nimport Texture from \"./texture/Texture\";\nimport View360Plugin from \"./plugin/View360Plugin\";\nimport ERROR from \"./const/error\";\nimport { CONTROL_EVENTS } from \"./const/internal\";\nimport { DEFAULT_CLASS, EVENTS } from \"./const/external\";\nimport { findCanvas, getElement } from \"./utils\";\nimport * as EVENT_TYPES from \"./type/events\";\nimport { EventParams } from \"./type/utils\";\n\n/**\n * Events that {@link View360} can trigger\n * @ko {@link View360}가 트리거할 수 있는 이벤트들\n * @see [Detailed Example](/docs/events/ready)\n * @since 4.0.0\n */\nexport interface View360Events {\n [EVENTS.READY]: EVENT_TYPES.ReadyEvent;\n [EVENTS.LOAD_START]: EVENT_TYPES.LoadStartEvent;\n [EVENTS.LOAD]: EVENT_TYPES.LoadEvent;\n [EVENTS.PROJECTION_CHANGE]: EVENT_TYPES.ProjectionChangeEvent;\n [EVENTS.RESIZE]: EVENT_TYPES.ResizeEvent;\n [EVENTS.BEFORE_RENDER]: EVENT_TYPES.BeforeRenderEvent;\n [EVENTS.RENDER]: EVENT_TYPES.RenderEvent;\n [EVENTS.INPUT_START]: EVENT_TYPES.InputStartEvent;\n [EVENTS.INPUT_END]: EVENT_TYPES.InputEndEvent;\n [EVENTS.VIEW_CHANGE]: EVENT_TYPES.ViewChangeEvent;\n [EVENTS.STATIC_CLICK]: EVENT_TYPES.StaticClickEvent;\n [EVENTS.VR_START]: EVENT_TYPES.VRStartEvent;\n [EVENTS.VR_END]: EVENT_TYPES.VREndEvent;\n}\n\n/**\n * Options for {@link View360}\n * @ko {@link View360}용 옵션들\n * @see [Detailed Example](/docs/options)\n * @since 4.0.0\n */\nexport interface View360Options extends CameraOptions, PanoControlOptions {\n projection: Projection | null;\n hotspot: Partial;\n autoplay: boolean | Partial;\n autoInit: boolean;\n autoResize: boolean;\n canvasSelector: string;\n useResizeObserver: boolean;\n tabIndex: number | null;\n on: Partial<{ [key in keyof View360Events]: (evt: View360Events[key]) => any }>;\n plugins: View360Plugin[];\n maxDeltaTime: number;\n debug: boolean;\n}\n\n/**\n * Panorama 360 image viewer\n * @ko 파노라마 360 이미지 뷰어\n * @since 4.0.0\n * @see View360Options\n * @see View360Events\n */\nclass View360 extends Component {\n /**\n * Current version string of the View360\n * @ko View360의 현재 버젼 문자열\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // If the installed version of the View360 is v4.0.0, View360.VERSION is equal to \"4.0.0\"\n * console.log(View360.VERSION) // 4.0.0\n * ```\n */\n public static readonly VERSION = \"#__VERSION__#\";\n\n private _rootEl: HTMLElement;\n private _renderer: WebGLRenderer;\n private _camera: Camera;\n private _control: PanoControl;\n private _animator: FrameAnimator;\n private _autoplay: Autoplay;\n private _hotspot: HotspotRenderer;\n private _projection: Projection | null;\n private _autoResizer: AutoResizer;\n private _vr: XRManager;\n private _plugins: View360Plugin[];\n private _initialized: boolean;\n\n private _autoInit: View360Options[\"autoInit\"];\n private _autoResize: View360Options[\"autoResize\"];\n private _canvasSelector: View360Options[\"canvasSelector\"];\n private _useResizeObserver: View360Options[\"useResizeObserver\"];\n private _tabIndex: View360Options[\"tabIndex\"];\n private _debug: View360Options[\"debug\"];\n\n /**\n * Root element (`.view360-container`)\n * @ko 루트 엘리먼트 (`.view360-container`)\n * @since 4.0.0\n * @readonly\n * @example\n * ```html\n *
\n * \n *
\n * ```\n * ```ts\n * import View360 from \"@egjs/view360\";\n *\n * const viewer = new View360(\"#viewer\");\n * console.log(viewer.rootEl); // Element with id \"viewer\"\n * ```\n */\n public get rootEl() { return this._rootEl; }\n /**\n * Projection renderer.\n * @ko 프로젝션 렌더러.\n * @since 4.0.0\n * @readonly\n */\n public get renderer() { return this._renderer; }\n /**\n * Projection camera.\n * @ko 프로젝션 카메라.\n * @since 4.0.0\n * @readonly\n */\n public get camera() { return this._camera; }\n /**\n * Rotate/Zoom Controller.\n * @ko 회전/줌 컨트롤러.\n * @since 4.0.0\n * @readonly\n */\n public get control() { return this._control; }\n /**\n * WebXR-based VR manager.\n * @ko WebXR 기반의 VR 기능 매니저 인스턴스.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // Example: Enter VR\n * // This must be called on user interaction, else will be rejected.\n * viewer.vr.enter();\n * ```\n */\n public get vr() { return this._vr; }\n /**\n * Hotspot renderer.\n * You can also change options of {@link View360Options#hotspot} with this.\n * @ko 핫스팟 렌더러 인스턴스.\n * {@link View360Options#hotspot} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get hotspot() { return this._hotspot; }\n /**\n * An array of plugins added.\n * @ko 추가된 플러그인의 배열\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * plugins: [new ControlBar()]\n * });\n *\n * console.log(viewer.plugins); // [ControlBar]\n *\n * viewer.addPlugins(new LoadingSpinner()) // [ControlBar, LoadingSpinner];\n * ```\n */\n public get plugins() { return this._plugins; }\n /**\n * A instance of {@link Projection} that currently enabled. `null` if not initialized yet.\n * You should call {@link View360#load} to change panorama src or projection type.\n * @ko 현재 사용중인 {@link Projection}의 인스턴스. 프로젝션을 활성화하지 않았을 경우 `null`입니다.\n * 파노라마 이미지 소스나 프로젝션 타입을 변경하려면 {@link View360#load}를 호출하면 됩니다.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360\n * ```\n */\n public get projection() { return this._projection; }\n public set projection(val: View360Options[\"projection\"]) {\n if (this._initialized && val) {\n this.load(val);\n } else {\n this._projection = val;\n }\n }\n /**\n * A boolean value whether {@link View360#init init()} is called before.\n * @ko {@link View360#init init()}이 호출되었는지 여부를 가리키는 값\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360(\"#el\", { autoInit: false });\n *\n * console.log(viewer.initialized); // false\n *\n * await viewer.init();\n *\n * console.log(viewer.initialized); // true\n * ```\n */\n public get initialized() { return this._initialized; }\n /**\n * Instance of the Autoplay manager.\n * You can also change {@link View360Options#autoplay} options with this.\n * @ko Autoplay 기능의 매니저 인스턴스.\n * 이 인스턴스를 통해 {@link View360Options#autoplay} 옵션을 변경하는 것도 가능합니다.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // Disable autoplay\n * viewer.autoplay.disable();\n * ```\n */\n public get autoplay() { return this._autoplay; }\n /**\n * When this value is `true` and {@link View360Options#projection} is set, {@link View360#init init()} will be called automatically when instance is created.\n * @ko 이 값이 `true`이고, {@link View360Options#projection}이 설정되었으면, 인스턴스 생성 시점에 자동으로 {@link View360#init init()}을 호출합니다.\n * @default true\n * @since 4.0.0\n * @example\n * ```ts\n * import View360, { EquirectProjection, EVENTS } from \"@egjs/view360\";\n *\n * // viewer.init() is called on instance creation\n * // But as `init` is asynchronous, you should wait for \"ready\" event if you want to do something after initialization.\n * const viewer = new View360(\"#el_id\", {\n * autoInit: true,\n * projection: new EquirectProjection({ src: \"SRC_TO_URL\" })\n * });\n *\n * console.log(viewer.initialized); // false, as `init` is asynchronous\n *\n * viewer.once(EVENTS.READY, () => {\n * console.log(viewer.initialized); // true\n * });\n * ```\n */\n public get autoInit() { return this._autoInit; }\n /**\n * When `true`, {@link View360#resize} is called when the canvas size is changed.\n * @ko `true`일 경우, 캔버스의 크기가 변경되었을 때 자동으로 {@link View360#resize}를 호출합니다.\n * @default true\n * @since 4.0.0\n * @see View360#useResizeObserver\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * autoResize: true\n * });\n *\n * // This can trigger `viewer.resize()` if the canvas size was not 400px\n * const canvas = viewer.renderer.canvas;\n * canvas.style.width = \"400px\";\n * ```\n */\n public get autoResize() { return this._autoResize; }\n /**\n * CSS selector for canvas element to render panorama image/video.\n * The canvas element should be placed inside the root element. (Dont' have to be direct child)\n * @ko 파노라마 이미지/비디오를 렌더링할 canvas 엘리먼트의 CSS 선택자\n * 캔버스 엘리먼트는 루트 엘리먼트 내부에 있어야합니다. 루트 엘리먼트의 직계 자식 엘리먼트(Direct child element)일 필요는 없습니다.\n * @default \"canvas\"\n * @since 4.0.0\n * @example\n * ```html\n *
\n * \n * \n * \n *
\n * ```\n *\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * canvasSelector: \"#canvas_to_select\"\n * });\n * ```\n */\n public get canvasSelector() { return this._canvasSelector; }\n /**\n * When `true`, it will use {@link ResizeObserver} API to detect canvas size change when {@link View360Options#autoResize} is enabled.\n * @ko `true`일 때 {@link View360Options#autoResize}가 활성화되었으면, 사용 가능한 환경에서 {@link ResizeObserver} API를 사용해서 캔버스 크기 변화를 추적합니다.\n * @default true\n * @since 4.0.0\n */\n public get useResizeObserver() { return this._useResizeObserver; }\n /**\n * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} attribute for the canvas element.\n * This is necessary for the keyboard controls.\n * By default, `0` will be assigned. `null` to disable.\n * @ko 캔버스 엘리먼트에 적용할 {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} 어트리뷰트의 값.\n * 이 값을 설정해야만 키보드 컨트롤을 사용 가능합니다.\n * 기본값으로 `0`이 설정됩니다. `null`로 지정하면 `tabindex`를 설정하지 않습니다.\n * @see RotateControlOptions#disableKeyboard\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * tabindex: 5\n * });\n * ```\n *\n * ```html\n * \n *
\n * \n *
\n * ```\n */\n public get tabIndex() { return this._tabIndex; }\n public set tabIndex(val: View360Options[\"tabIndex\"]) {\n const canvas = this._renderer.canvas;\n this._tabIndex = val;\n\n if (val != null) {\n canvas.tabIndex = val;\n } else {\n canvas.removeAttribute(\"tabindex\");\n }\n }\n /**\n * A maximum delta time between frames in seconds.\n * It can prevent camera or control changing too fast when frame being late.\n * @ko 프레임간 시간 차이의 최대값. (초 단위)\n * 퍼포먼스 등의 이유로 프레임 렌더링이 늦어졌을 때, 화면이 갑작스럽게 바뀌는 것을 막아줍니다.\n * @default 1 / 30\n * @since 4.0.0\n */\n public get maxDeltaTime() { return this._animator.maxDeltaTime; }\n public set maxDeltaTime(val: View360Options[\"maxDeltaTime\"]) { this._animator.maxDeltaTime = val; }\n /**\n * Enable WebGL debugging. Setting this to `true` can decrease performance.\n * This is used internally on developing View360.\n * @ko WebGL 디버깅을 활성화합니다. 이 값을 `true`로 할 경우 성능이 하락할 수 있습니다.\n * 이 옵션은 View360을 개발하기 위해 내부적으로 사용됩니다.\n * @default false\n */\n public get debug() { return this._debug; }\n public set debug(val: View360Options[\"debug\"]) { this._debug = val; }\n\n // Camera options\n /**\n * Initial yaw (y-axis rotation) value for camera. (in degrees, °)\n * As View360 uses right-handed coordinate system internally, camera will rotate counter-clockwise by this value.\n * @ko 카메라의 초기 yaw(y축 회전)값 (도 단위, °)\n * View360은 오른손 좌표계를 사용하기 때문에, 카메라가 해당 값만큼 시계 반대방향으로 회전합니다.\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialYaw: 30\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.yaw); // 30\n * });\n * ```\n */\n public get initialYaw() { return this._camera.initialYaw; }\n public set initialYaw(val: View360Options[\"initialYaw\"]) { this._camera.initialYaw = val; }\n /**\n * Initial pitch (x-axis rotation) value for camera. (in degrees, °)\n * As View360 uses right-handed coordinate system internally, positive value will make camera to look upside, while negative value will look down.\n * @ko 카메라의 초기 pitch(x축 회전)값 (도 단위, °)\n * View360은 오른손 좌표계를 사용하기 때문에, 양(+)의 값은 카메라가 위를 보게 하고, 음(-)의 값은 카메라가 아래를 보게 합니다.\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialPitch: 60\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.pitch); // 60\n * });\n * ```\n */\n public get initialPitch() { return this._camera.initialPitch; }\n public set initialPitch(val: View360Options[\"initialPitch\"]) { this._camera.initialPitch = val; }\n /**\n * Initial zoom value for camera.\n * Setting this value to `2` will enlarge panorama 200% by width.\n * @ko 카메라의 초기 줌 값.\n * 이 값을 `2`로 설정할 경우 파노라마 이미지를 가로 기준 200%만큼 확대합니다.\n * @default 1\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialZoom: 2\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.zoom); // 2\n * });\n * ```\n */\n public get initialZoom() { return this._camera.initialZoom; }\n public set initialZoom(val: View360Options[\"initialZoom\"]) { this._camera.initialZoom = val; }\n /**\n * Restrict yaw(y-axis rotation) range. (in degrees, °)\n * @ko yaw(y축 회전) 범위를 제한합니다. (도 단위, °)\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * yawRange: [-30, 30]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.yaw); // 0\n * viewer.camera.lookAt({ yaw: 60 });\n * console.log(viewer.camera.yaw); // 30\n * });\n * ```\n */\n public get yawRange() { return this._camera.yawRange; }\n public set yawRange(val: View360Options[\"yawRange\"]) {\n this._camera.yawRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Restrict pitch(x-axis rotation) range. (in degrees, °)\n * @ko pitch(x축 회전) 범위를 제한합니다. (도 단위, °)\n * @default null\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * pitchRange: [-45, 45]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.pitch); // 0\n * viewer.camera.lookAt({ pitch: 60 });\n * console.log(viewer.camera.pitch); // 45\n * });\n * ```\n */\n public get pitchRange() { return this._camera.pitchRange; }\n public set pitchRange(val: View360Options[\"pitchRange\"]) {\n this._camera.pitchRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Restrict camera zoom range.\n * If `null`, a default zoom range from `0.6` to `10` will be used.\n * @ko 카메라 줌 범위를 제한합니다.\n * `null`일 경우 기본값으로 `0.6`에서 `10`의 범위를 사용합니다.\n * @default null\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * zoomRange: [0.5, 4]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.zoom); // 1\n * viewer.camera.lookAt({ zoom: 6 });\n * console.log(viewer.camera.zoom); // 4\n * });\n * ```\n */\n public get zoomRange() { return this._camera.zoomRange; }\n public set zoomRange(val: View360Options[\"zoomRange\"]) {\n this._camera.zoomRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Camera's horizontal FOV(Field of View). (in degrees, °)\n * @ko 카메라의 수평 FOV(Field of View) 값. (도 단위, °)\n * @default 90\n * @since 4.0.0\n * @example\n * ```ts\n * // Init with fov: 120\n * const viewer = new View360(\"#el_id\", { fov: 120 });\n *\n * // Back to 90\n * viewer.fov = 90;\n * ```\n */\n public get fov() { return this._camera.fov; }\n public set fov(val: View360Options[\"fov\"]) {\n const camera = this._camera;\n const control = this._control;\n\n camera.fov = val;\n camera.updateMatrix();\n control.sync();\n }\n\n // Control options\n /**\n * A control for camera rotation.\n * You can also change options of {@link View360Options#rotate} with this.\n * @ko 카메라 회전을 담당하는 컨트롤.\n * {@link View360Options#rotate} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get rotate() { return this._control.rotate; }\n /**\n * A control for camera zoom.\n * You can also change options of {@link View360Options#zoom} with this.\n * @ko 카메라 줌을 담당하는 컨트롤.\n * {@link View360Options#zoom} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get zoom() { return this._control.zoom; }\n /**\n * A control for camera rotation with gyroscope input.\n * You can also change options of {@link View360Options#gyro} with this.\n * @ko 자이로스코프를 통한 카메라 회전을 담당하는 컨트롤.\n * {@link View360Options#gyro} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get gyro() { return this._control.gyro; }\n /**\n * Apply CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor} by current state of input when using mouse.\n * If `true`, this will add CSS style to canvas element. It'll apply `cursor: \"grab\"` by default and `cursor: \"grabbing\"` when holding the mouse button.\n * @ko 마우스 사용시 CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor}값을 자동으로 변경할지 여부.\n * `true`일 경우 기본 상태에서 `cursor: \"grab\"`을, 입력 도중에 `cursor: \"grabbing\"`을 캔버스에 적용합니다.\n * @default true\n * @since 4.0.0\n */\n public get useGrabCursor() { return this._control.useGrabCursor; }\n public set useGrabCursor(val: View360Options[\"useGrabCursor\"]) { this._control.useGrabCursor = val; }\n /**\n * Disable context menu which pops up on mouse right click.\n * @ko 마우스 우클릭시 표시되는 컨텍스트 메뉴를 비활성화합니다.\n * @default false\n * @since 4.0.0\n */\n public get disableContextMenu() { return this._control.disableContextMenu; }\n public set disableContextMenu(val: View360Options[\"disableContextMenu\"]) { this._control.disableContextMenu = val; }\n /**\n * If `true`, enables scroll on mobile(touch) devices on canvas.\n * :::caution\n * When this option is enabled, users must swipe horizontally first then vertically to change view up or down.\n * :::\n * @ko `true`로 설정할 경우, 모바일(터치) 환경의 캔버스 영역 내에서 스크롤을 가능하게 합니다.\n * :::caution\n * 이 값을 활성화할 경우, 사용자가 카메라 뷰를 위/아래로 바꾸기 위해서는 먼저 가로로 스와이프한 이후에 세로로 스와이프해야만 합니다.\n * :::\n * @since 4.0.0\n * @default true\n */\n public get scrollable() { return this._control.scrollable; }\n public set scrollable(val: View360Options[\"scrollable\"]) { this._control.scrollable = val; }\n /**\n * If `true`, enables scroll by mouse wheel on canvas.\n * :::caution\n * When this option is enabled, zoom by mouse wheel will be disabled.\n * :::\n * @ko `true`로 설정할 경우, 캔버스 영역 내에서 마우스 휠을 이용한 페이지 스크롤이 가능해집니다.\n * :::caution\n * 이 값을 활성화할 경우, 마우스 휠을 통한 줌이 불가능하게 됩니다.\n * :::\n * @since 4.0.0\n * @default false\n */\n public get wheelScrollable() { return this._control.wheelScrollable; }\n public set wheelScrollable(val: View360Options[\"wheelScrollable\"]) { this._control.wheelScrollable = val; }\n\n /**\n * Create new instance of View360\n * @ko View360의 새로운 인스턴스를 생성합니다\n * @param root - Root element(`.view360-container`) to mount View360\n * Can be either a CSS selector or HTMLElement.\n * {@ko View360을 마운트할 루트 엘리먼트, CSS 셀렉터나 HTMLElement를 지정 가능합니다.}\n * @param options - Options to apply\n * {@ko 적용할 옵션들}\n * @example\n * ```ts\n * import View360, { EquirectProjection } from \"@egjs/view360\";\n *\n * // Create new View360 instance\n * const viewer = new View360(\"#id-of-a-container\", {\n * projection: new EquirectProjection({\n * src: \"URL_TO_PANORAMA_IMAGE_OR_VIDEO\",\n * })\n * });\n * ```\n */\n public constructor(root: string | HTMLElement, {\n projection = null,\n initialYaw = 0,\n initialPitch = 0,\n initialZoom = 1,\n yawRange = null,\n pitchRange = null,\n zoomRange = null,\n fov = 90,\n useGrabCursor = true,\n disableContextMenu = false,\n rotate = true,\n zoom = true,\n gyro = false,\n scrollable = true,\n wheelScrollable = false,\n autoplay = false,\n hotspot = {},\n autoInit = true,\n autoResize = true,\n canvasSelector = \"canvas\",\n useResizeObserver = true,\n on = {},\n plugins = [],\n maxDeltaTime = 1 / 30,\n tabIndex = 0,\n debug = false\n }: Partial = {}) {\n super();\n\n this._rootEl = getElement(root);\n this._plugins = plugins;\n this._initialized = false;\n\n // Options\n this._autoInit = autoInit;\n this._autoResize = autoResize;\n this._canvasSelector = canvasSelector;\n this._useResizeObserver = useResizeObserver;\n this._tabIndex = tabIndex;\n this._debug = debug;\n\n // Core components\n const canvas = findCanvas(this._rootEl, canvasSelector);\n this._renderer = new WebGLRenderer(canvas, debug);\n this._camera = new Camera({\n initialYaw,\n initialPitch,\n initialZoom,\n fov,\n yawRange,\n pitchRange,\n zoomRange\n });\n this._control = new PanoControl(canvas, this._camera, {\n useGrabCursor,\n scrollable,\n wheelScrollable,\n disableContextMenu,\n rotate,\n zoom,\n gyro\n });\n this._animator = new FrameAnimator(maxDeltaTime);\n this._autoplay = new Autoplay(this, canvas, autoplay);\n this._projection = projection;\n this._autoResizer = new AutoResizer(useResizeObserver, () => this.resize());\n this._vr = new XRManager(this._renderer.ctx);\n this._hotspot = new HotspotRenderer(this._rootEl, this._renderer, hotspot);\n\n this._addEventHandlers(on);\n\n if (projection && autoInit) {\n this.init();\n }\n }\n\n /**\n * Destroy instance and release all resources.\n * @ko 인스턴스를 제거하고 모든 리소스를 해제합니다.\n * @since 4.0.0\n */\n public destroy() {\n this._camera.destroy();\n this._animator.stop();\n this._renderer.destroy();\n this._control.destroy();\n this._autoResizer.disable();\n\n if (this._projection) {\n this._projection.releaseAllResources(this._renderer.ctx);\n this._projection = null;\n }\n\n this._plugins.forEach(plugin => plugin.destroy(this));\n\n this._initialized = false;\n }\n\n /**\n * Initialize inner components and load projection src.\n * @ko 내부 컴포넌트들을 초기화하고 프로젝션 소스를 로드합니다.\n * @since 4.0.0\n */\n public async init() {\n if (!this._projection) {\n throw new View360Error(ERROR.MESSAGES.PROVIDE_PROJECTION_FIRST, ERROR.CODES.PROVIDE_PROJECTION_FIRST);\n }\n\n const renderer = this._renderer;\n const camera = this._camera;\n const control = this._control;\n const animator = this._animator;\n const hotspot = this._hotspot;\n const projection = this._projection;\n const canvas = renderer.canvas;\n\n this._bindComponentEvents();\n renderer.ctx.init();\n this._resizeComponents();\n camera.updateMatrix();\n\n if (this._autoResize) {\n this._autoResizer.enable(canvas);\n }\n\n if (!this._autoplay.enableBlocked) {\n this._autoplay.enable();\n }\n\n this._plugins.forEach(plugin => {\n plugin.init(this);\n });\n\n const texture = await this._loadTexture(projection);\n this._applyProjection(projection, texture, null);\n hotspot.refresh();\n animator.start(this._renderFrameOnDemand);\n await control.enable();\n\n if (this._tabIndex != null && !canvas.hasAttribute(\"tabIndex\")) {\n canvas.tabIndex = this._tabIndex;\n }\n\n this._initialized = true;\n this.renderFrame(0);\n\n this._emit(EVENTS.READY);\n }\n\n /**\n * Load new panorama image/video and display it.\n * This will {@link View360#init init()} View360 if it's not initialized yet.\n * @ko 새로운 파노라마 이미지 혹은 비디오를 로드하고 표시합니다.\n * 만약 View360이 아직 초기화되지 않았다면, {@link View360#init init()}을 호출합니다.\n * @param projection - Projection & video options for new source. {@ko 새로운 파노라마 이미지/비디오에 적용할 옵션들}\n * @returns `Promise` if load was successful. {@ko 프로젝션 로드에 성공했을 경우 `Promise`를 반환합니다. }\n * @since 4.0.0\n * @example\n * ```ts\n * // Change to video\n * viewer.load({\n * src: \"URL_TO_NEW_VIDEO\",\n * video: true\n * });\n * ```\n */\n public async load(projection: Projection): Promise {\n if (!projection) return false;\n\n if (this._initialized) {\n const texture = await this._loadTexture(projection);\n this._applyProjection(projection, texture, this._projection);\n this.renderFrame(0);\n } else {\n // Should update internal options before init\n this._projection = projection;\n this.init();\n }\n\n return true;\n }\n\n /**\n * Refresh component's size by current\n * @ko View360이 내부적으로 캐시하고 있는 엘리먼트 크기를 현재 크기로 갱신합니다.\n * @since 4.0.0\n */\n public resize() {\n if (!this._initialized) return;\n\n this._resizeComponents();\n\n // To prevent flickering, render immediately after resizing components\n this.renderFrame(0);\n\n const { width, height } = this._renderer;\n\n this._emit(EVENTS.RESIZE, {\n width,\n height\n });\n }\n\n /**\n * Add new plugins\n * @ko 새로운 플러그인을 추가합니다.\n * @param plugins Plugins to add {@ko 추가할 플러그인들}\n * @see View360Options#plugins\n * @since 4.0.0\n * @example\n * ```ts\n * // Add a single plugin\n * viewer.addPlugins(new ControlBar());\n *\n * // Add multiple plugins\n * viewer.addPlugins(new ControlBar(), new LoadingSpinner());\n * ```\n */\n public addPlugins(...plugins: View360Plugin[]) {\n if (this._initialized) {\n plugins.forEach(plugin => { plugin.init(this); });\n }\n\n this._plugins.push(...plugins);\n }\n\n /**\n * Remove plugins.\n * @ko 플러그인을 제거합니다.\n * @param plugins Plugins to remove {@ko 제거할 플러그인들}\n * @since 4.0.0\n * @example\n * ```ts\n * // Remove a single plugin\n * viewer.removePlugins(plugin1);\n *\n * // Remove multiple plugins\n * viewer.removePlugins(plugin2, plugin3);\n * ```\n */\n public removePlugins(...plugins: View360Plugin[]) {\n plugins.forEach(plugin => {\n const pluginIdx = this._plugins.indexOf(plugin);\n\n if (pluginIdx < 0) return;\n\n plugin.destroy(this);\n this._plugins.splice(pluginIdx, 1);\n });\n }\n\n /**\n * Render a single panorama image/video frame.\n * Rendering is performed automatically on demand, so you usually don't have to call this.\n * Call this when a frame is not renewed after changing options.\n * @ko 파노라마 이미지/비디오의 한 프레임을 렌더링합니다.\n * 프레임 갱신은 보통 필요한 때에만 자동적으로 이루어지기 때문에, 보통은 이 메소드를 호출할 필요는 없습니다.\n * 옵션 변경 이후에도 프레임 갱신이 이루어지지 않는다면, 이 메소드를 호출해주세요.\n * @param delta Delta time in milisec. {@ko 프레임간 시간 차이, 밀리초 단위}\n * @since 4.0.0\n */\n public renderFrame = (delta: number) => {\n const camera = this._camera;\n const renderer = this._renderer;\n const control = this._control;\n const hotspot = this._hotspot;\n const autoPlayer = this._autoplay;\n const projection = this._projection;\n\n if (!projection) return;\n\n this._emit(EVENTS.BEFORE_RENDER);\n\n if (autoPlayer.playing) {\n autoPlayer.update(delta);\n control.sync();\n }\n\n if (camera.animation) {\n camera.animation.update(delta);\n } else {\n control.update(delta);\n }\n\n renderer.render(projection, camera);\n hotspot.render(camera);\n\n if (camera.changed) {\n this._emit(EVENTS.VIEW_CHANGE, {\n yaw: camera.yaw,\n pitch: camera.pitch,\n zoom: camera.zoom,\n quaternion: [\n camera.quaternion[0],\n camera.quaternion[1],\n camera.quaternion[2],\n camera.quaternion[3]\n ]\n });\n }\n camera.onFrameRender();\n\n this._emit(EVENTS.RENDER);\n };\n\n private _emit(eventName: K, ...params: EventParams) {\n const evtParams = params ? params[0] : {};\n\n this.trigger(eventName as any, {\n type: eventName,\n target: this,\n ...evtParams\n });\n }\n\n private _renderFrameOnDemand = (delta: number) => {\n const camera = this._camera;\n const control = this._control;\n const autoplay = this._autoplay;\n const texture = this._projection?.getTexture();\n\n if (!this._initialized || !texture) return;\n if (\n !camera.animation\n && !control.animating\n && !autoplay.playing\n && !texture.isVideo()\n ) return;\n\n this.renderFrame(delta);\n };\n\n private _renderVRFrame = (_delta: number, frame: XRFrame) => {\n const vr = this._vr;\n const projection = this._projection;\n const renderer = this._renderer;\n\n if (!projection) return;\n\n this._emit(EVENTS.BEFORE_RENDER);\n\n renderer.renderVR(projection, vr, frame);\n\n this._emit(EVENTS.RENDER);\n }\n\n private _applyProjection(projection: Projection, texture: Texture, prevProjection: Projection | null) {\n const camera = this._camera;\n const control = this._control;\n const renderer = this._renderer;\n\n // Remove previous projection\n if (prevProjection) {\n prevProjection.releaseAllResources(this._renderer.ctx);\n }\n\n projection.applyTexture(renderer.ctx, texture);\n projection.updateCamera(camera);\n projection.updateControl(control);\n\n this._projection = projection;\n this._emit(EVENTS.PROJECTION_CHANGE, {\n projection\n });\n }\n\n private async _loadTexture(projection: Projection): Promise {\n const contentLoader = new TextureLoader();\n const { src, video } = projection;\n\n this._emit(EVENTS.LOAD_START, {\n src,\n video\n });\n\n const texture = await contentLoader.load(src, video);\n\n this._emit(EVENTS.LOAD, {\n src,\n video\n });\n\n return texture;\n }\n\n private _resizeComponents() {\n const renderer = this._renderer;\n const camera = this._camera;\n const control = this._control;\n\n renderer.resize();\n camera.resize(renderer.width, renderer.height);\n control.resize(renderer.width, renderer.height);\n }\n\n private _addEventHandlers(events: View360Options[\"on\"]) {\n // Bind option \"on\"\n Object.keys(events).forEach((evtName: keyof typeof EVENT_TYPES) => {\n this.on(evtName, events[evtName]);\n });\n }\n\n private _bindComponentEvents() {\n // Bind internal component events\n const root = this._rootEl;\n const control = this._control;\n const animator = this._animator;\n const renderer = this._renderer;\n const vr = this._vr;\n\n const controlEventsToPropagate = [\n CONTROL_EVENTS.STATIC_CLICK,\n CONTROL_EVENTS.INPUT_START,\n CONTROL_EVENTS.INPUT_END\n ];\n\n controlEventsToPropagate.forEach(evtName => {\n control.rotate.on(evtName, evt => {\n this._emit(evtName, evt);\n });\n\n control.zoom.on(evtName, evt => {\n this._emit(evtName, evt);\n });\n });\n\n vr.on(EVENTS.VR_START, evt => {\n root.classList.add(DEFAULT_CLASS.IN_VR);\n\n animator.changeContext(evt.session);\n animator.start(this._renderVRFrame);\n\n this._emit(EVENTS.VR_START);\n });\n\n vr.on(EVENTS.VR_END, () => {\n root.classList.remove(DEFAULT_CLASS.IN_VR);\n\n renderer.ctx.useDefaultFrameBuffer();\n animator.changeContext(window);\n animator.start(this._renderFrameOnDemand);\n\n this.resize();\n\n this._emit(EVENTS.VR_END);\n });\n }\n}\n\nexport default View360;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4, quat, vec3 } from \"gl-matrix\";\n\n/**\n * Base class for 3D objects\n * @ko 3D 오브젝트의 베이스 클래스\n * @since 4.0.0\n * @internal\n */\nclass Object3D {\n /**\n * Local matrix of the object\n * @ko 오브젝트의 local matrix\n * @since 4.0.0\n */\n public matrix: mat4;\n /**\n * Rotation quaternion\n * @ko 현재 오브젝트의 회전을 나타내는 사원수 값\n * @since 4.0.0\n */\n public rotation: quat;\n /**\n * Position of the object\n * @ko 오브젝트의 위치\n * @since 4.0.0\n */\n public position: vec3;\n /**\n * A scale vector of the object\n * @ko 오브젝트가 각 축으로 확대된 정도를 나타내는 벡터\n * @since 4.0.0\n */\n public scale: vec3;\n\n /**\n * Create new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n */\n public constructor() {\n this.matrix = mat4.create();\n this.rotation = quat.create();\n this.position = vec3.fromValues(0, 0, 0);\n this.scale = vec3.fromValues(1, 1, 1);\n }\n\n /**\n * Update local matrix of the object.\n * @ko 오브젝트의 local matrix를 갱신합니다.\n * @since 4.0.0\n */\n public updateMatrix() {\n mat4.fromRotationTranslationScale(this.matrix, this.rotation, this.position, this.scale);\n }\n}\n\nexport default Object3D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360Plugin from \"../View360Plugin\";\nimport View360 from \"../../View360\";\nimport { EVENTS } from \"../../const/external\";\nimport { createElement } from \"../../utils\";\nimport { LoadStartEvent } from \"../../type/events\";\n\n/**\n * Options for {@link LoadingSpinner}\n * @ko {@link LoadingSpinner}용 옵션들\n * @since 4.0.0\n * @category Plugin\n */\nexport interface LoadingSpinnerOptions {\n /**\n * Override default class names.\n * @ko 디폴트 클래스 이름들을 오버라이드합니다.\n * @since 4.0.0\n */\n className: Partial<{ -readonly [key in keyof typeof LoadingSpinner.DEFAULT_CLASS]: string }>;\n}\n\n/**\n * A plugin that displays loading spinner while loading the projection.\n * @ko 프로젝션 로딩중에 로딩 스피너를 보여주는 플러그인\n * @since 4.0.0\n * @category Plugin\n */\nclass LoadingSpinner implements View360Plugin {\n /**\n * Default class names that LoadingSpinner uses\n * @ko LoadingSpinner가 사용하는 디폴트 클래스 이름\n * @since 4.0.0\n */\n public static readonly DEFAULT_CLASS = {\n /**\n * A class name for the container element\n * @ko 컨테이너 엘리먼트의 클래스 이름\n * @since 4.0.0\n */\n CONTAINER: \"view360-spinner\",\n /**\n * A class name for the spinning ring element\n * @ko 돌아가는 링 엘리먼트의 클래스 이름\n * @since 4.0.0\n */\n RING: \"view360-spinner-ring\"\n } as const;\n\n /**\n * A class names overriding\n * @ko 현재 오버라이드 중인 클래스 이름\n * @since 4.0.0\n */\n public readonly className: LoadingSpinnerOptions[\"className\"];\n\n private _container: HTMLElement;\n\n /**\n * Create a new instance of LoadingSpinner. {@ko LoadingSpinner의 새 인스턴스를 생성합니다.}\n * @param options Options {@ko 옵션들}\n */\n public constructor({\n className = {}\n }: Partial = {}) {\n this.className = className;\n this._container = this._createElements();\n }\n\n public init(viewer: View360) {\n viewer.on(EVENTS.LOAD_START, this._startLoading);\n }\n\n public destroy(viewer: View360): void {\n viewer.off(EVENTS.LOAD_START, this._startLoading);\n this._detachElements({ target: viewer });\n }\n\n private _startLoading = ({ target: viewer }: LoadStartEvent) => {\n viewer.rootEl.appendChild(this._container);\n\n if (viewer.initialized) {\n viewer.once(EVENTS.LOAD, this._detachElements);\n } else {\n viewer.once(EVENTS.READY, this._detachElements);\n }\n };\n\n private _detachElements = ({ target: viewer }: { target: View360 }) => {\n const container = this._container;\n if (!container) return;\n\n if (container.parentElement === viewer.rootEl) {\n viewer.rootEl.removeChild(container);\n }\n };\n\n private _createElements() {\n const className = {\n ...this.className,\n ...LoadingSpinner.DEFAULT_CLASS\n };\n\n const container = createElement(className.CONTAINER);\n const ring = createElement(className.RING);\n\n container.appendChild(ring);\n\n return container;\n }\n}\n\nexport default LoadingSpinner;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n/* eslint-disable @typescript-eslint/no-empty-function */\n/* eslint-disable @typescript-eslint/no-unused-vars */\nimport ControlBar from \"./ControlBar\";\nimport View360 from \"../../View360\";\n\n/**\n * Common options for {@link ControlBarItem}\n * @ko {@link ControlBarItem}의 공통 옵션들\n * @category Plugin\n * @since 4.0.0\n */\nexport interface ControlBarItemOptions {\n /**\n * @copy ControlBarItem#position\n */\n position: typeof ControlBar.POSITION[keyof typeof ControlBar.POSITION];\n /**\n * @copy ControlBarItem#order\n */\n order: number;\n}\n\n/**\n * Interface of the ControlBar items\n * @ko 컨트롤바 아이템의 인터페이스\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nabstract class ControlBarItem {\n /**\n * Element of the item.\n * @ko 아이템의 엘리먼트\n * @since 4.0.0\n */\n public abstract element: HTMLElement;\n\n /**\n * Position to display item.\n * @ko 아이템을 표시할 위치.\n * @since 4.0.0\n */\n public position: ControlBarItemOptions[\"position\"];\n /**\n * Order within the same position.\n * The lowest one will be shown first.\n * @ko 동일한 position 내에서의 순서, 작을수록 먼저 표시됩니다.\n * @since 4.0.0\n */\n public order: ControlBarItemOptions[\"order\"];\n\n /**\n * Create new instance of the ControlBarItem\n * @ko ControlBarItem의 새로운 인스턴스를 생성합니다.\n * @param options Options {@ko 옵션들}\n */\n public constructor(options: ControlBarItemOptions) {\n this.position = options.position;\n this.order = options.order;\n }\n\n /**\n * Initialize item.\n * @ko 아이템을 초기화합니다.\n * @param viewer - A instance of viewer to attach item {@ko 아이템을 부착할 뷰어의 인스턴스}\n * @param controlBar - A instance of control bar to attach item {@ko 아이템을 부착할 컨트롤바의 인스턴스}\n * @since 4.0.0\n */\n public abstract init(viewer: View360, controlBar: ControlBar): any;\n /**\n * Destroy item and release all resources & event handlers.\n * @ko 아이템을 제거하고 할당된 모든 리소스 및 이벤트 핸들러를 제거합니다.\n * @param viewer - A instance of viewer to detach item {@ko 아이템을 떼어 낼 뷰어의 인스턴스}\n * @param controlBar - A instance of control bar to detach item {@ko 아이템을 떼어 낼 컨트롤바의 인스턴스}\n * @since 4.0.0\n */\n public abstract destroy(viewer: View360, controlBar: ControlBar): any;\n}\n\nexport default ControlBarItem;\n","export const CONTROL_BAR_DEFAULT_CLASS = {\n CONTROLS_ROOT: \"view360-controls\",\n CONTROLS_BG: \"view360-controls-background\",\n CONTROLS_MAIN: \"view360-controls-main\",\n CONTROLS_TOP: \"view360-controls-top\",\n CONTROLS_BOTTOM: \"view360-controls-bottom\",\n CONTROLS_MID: \"view360-controls-mid\",\n CONTROLS_LEFT: \"view360-controls-left\",\n CONTROLS_RIGHT: \"view360-controls-right\",\n CONTROLS_FLOAT_LEFT: \"view360-controls-float-left\",\n CONTROLS_FLOAT_RIGHT: \"view360-controls-float-right\",\n CONTROLS_BUTTON: \"view360-controls-button\",\n PROGRESS_ROOT: \"view360-controls-progress\",\n VOLUME_ROOT: \"view360-controls-volume\",\n RANGE_ROOT: \"view360-range\",\n RANGE_TRACK: \"view360-range-track\",\n RANGE_THUMB: \"view360-range-thumb\",\n RANGE_FILLER: \"view360-range-filler\",\n PLAY_BUTTON: \"view360-controls-play\",\n PAUSE_BUTTON: \"view360-controls-pause\",\n UNMUTED_BUTTON: \"view360-controls-unmuted\",\n MUTED_BUTTON: \"view360-controls-muted\",\n FULLSCREEN_BUTTON: \"view360-controls-fullscreen\",\n FULLSCREEN_EXIT_BUTTON: \"view360-controls-fullscreen-exit\",\n VR_BUTTON: \"view360-controls-vr\",\n GYRO_ENABLED: \"view360-controls-gyro-enabled\",\n GYRO_DISABLED: \"view360-controls-gyro-disabled\",\n VIDEO_TIME_DISPLAY: \"view360-controls-time\",\n PIEVIEW_ROOT: \"view360-controls-pie\",\n FIXED: \"view360-controls-fixed\",\n UNAVAILABLE: \"view360-controls-unavailable\",\n HIDDEN: \"view360-controls-hidden\"\n} as const;\n\nexport const CONTROL_BAR_ITEM_POSITION = {\n /**\n * Place control bar item floating at top-left corner\n * @ko 아이템을 왼쪽 위 구석에 표시합니다.\n * @since 4.0.0\n */\n TOP_LEFT: \"top-left\",\n /**\n * Place control bar item floating at top-right corner\n * @ko 아이템을 오른쪽 위 구석에 표시합니다.\n * @since 4.0.0\n */\n TOP_RIGHT: \"top-right\",\n /**\n * Place control bar item at upper block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 위쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_TOP: \"main-top\",\n /**\n * Place control bar item at lower block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 하단 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_BOTTOM: \"main-bottom\",\n /**\n * Place control bar item at center-left block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 왼쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_LEFT: \"main-left\",\n /**\n * Place control bar item at center-right block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 오른쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_RIGHT: \"main-right\"\n} as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { ControlBarOptions } from \"./ControlBar\";\nimport { CONTROL_BAR_DEFAULT_CLASS } from \"./const\";\nimport Motion from \"../../core/Motion\";\nimport MouseInput from \"../../control/input/MouseInput\";\nimport TouchInput from \"../../control/input/TouchInput\";\nimport { CONTROL_EVENTS, INFINITE_RANGE } from \"../../const/internal\";\nimport { clamp } from \"../../utils\";\nimport { InputEvents } from \"../../type/internal\";\nimport { EL_DIV } from \"../../const/browser\";\n\nclass RangeControl extends Component<{\n [CONTROL_EVENTS.INPUT_START]: number;\n [CONTROL_EVENTS.CHANGE]: number;\n [CONTROL_EVENTS.INPUT_END]: void;\n}> {\n public readonly rootEl: HTMLElement;\n public readonly thumbEl: HTMLElement;\n public readonly trackEl: HTMLElement;\n public readonly fillerEl: HTMLElement;\n\n private _motion: Motion;\n private _mouseInput: MouseInput;\n private _touchInput: TouchInput;\n private _fixedClass: string;\n private _bbox: DOMRect;\n\n /**\n *\n */\n public constructor() {\n super();\n\n const root = document.createElement(EL_DIV);\n const track = document.createElement(EL_DIV);\n const thumb = document.createElement(EL_DIV);\n const filler = document.createElement(EL_DIV);\n\n root.draggable = false;\n\n track.appendChild(filler);\n track.appendChild(thumb);\n root.appendChild(track);\n\n this.rootEl = root;\n this.trackEl = track;\n this.thumbEl = thumb;\n this.fillerEl = filler;\n\n this._mouseInput = new MouseInput();\n this._touchInput = new TouchInput();\n this._motion = new Motion({ duration: 1, range: INFINITE_RANGE, easing: x => x });\n this._bbox = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n left: 0,\n right: 0,\n bottom: 0,\n top: 0\n } as DOMRect;\n this._fixedClass = CONTROL_BAR_DEFAULT_CLASS.FIXED;\n }\n\n public init(className: Required) {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n\n this.rootEl.classList.add(className.RANGE_ROOT);\n this.trackEl.classList.add(className.RANGE_TRACK);\n this.thumbEl.classList.add(className.RANGE_THUMB);\n this.fillerEl.classList.add(className.RANGE_FILLER);\n this._fixedClass = className.FIXED;\n\n mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n touchInput.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n\n mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n touchInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n\n mouseInput.enable(this.rootEl);\n touchInput.enable(this.rootEl);\n\n this.resize();\n }\n\n public destroy() {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n\n this.rootEl.className = \"\";\n this.trackEl.className = \"\";\n this.thumbEl.className = \"\";\n this.fillerEl.className = \"\";\n\n mouseInput.off();\n touchInput.off();\n mouseInput.disable();\n touchInput.disable();\n }\n\n public resize() {\n this._bbox = this.trackEl.getBoundingClientRect();\n }\n\n public updateStyle(progress: number) {\n const width = this._bbox.width;\n const clampedProgress = clamp(progress, 0, 1);\n\n this.fillerEl.style.width = `${clampedProgress * 100}%`;\n this.thumbEl.style.transform = `translateX(${clampedProgress * width}px)`;\n }\n\n private _onHold = ({ srcEvent, isTouch }: InputEvents<{ x: number; y: number }>[typeof CONTROL_EVENTS.INPUT_START]) => {\n const bbox = this._bbox;\n if (!bbox) return;\n\n const x = isTouch\n ? (srcEvent as TouchEvent).touches[0].pageX\n : (srcEvent as MouseEvent).pageX;\n const elX = bbox.x + (window.scrollX ?? window.pageXOffset);\n\n const clamepdX = clamp(x, elX, elX + bbox.width);\n const progress = (clamepdX - elX) / bbox.width;\n\n this._motion.reset(clamepdX);\n this.thumbEl.classList.add(this._fixedClass);\n\n this.trigger(CONTROL_EVENTS.INPUT_START, progress);\n };\n\n private _onChange = ({ delta }: InputEvents<{ x: number; y: number }>[typeof CONTROL_EVENTS.CHANGE]) => {\n const motion = this._motion;\n const bbox = this._bbox;\n if (!bbox) return;\n\n motion.setNewEndByDelta(delta.x);\n motion.update(1);\n\n const elX = bbox.x + (window.scrollX ?? window.pageXOffset);\n const clampedX = clamp(motion.val, elX, elX + bbox.width);\n const progress = (clampedX - elX) / bbox.width;\n\n this.trigger(CONTROL_EVENTS.CHANGE, progress);\n };\n\n private _onRelease = () => {\n const bbox = this._bbox;\n if (!bbox) return;\n\n this.thumbEl.classList.remove(this._fixedClass);\n\n this.trigger(CONTROL_EVENTS.INPUT_END);\n };\n}\n\nexport default RangeControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport RangeControl from \"./RangeControl\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport { CONTROL_EVENTS, VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport { EVENTS } from \"../../const/external\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show video progress bar.\n * @ko 비디오의 프로그레스 바를 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass ProgressBar extends ControlBarItem {\n public get element() { return this._rangeControl.rootEl; }\n\n private _controlBar: ControlBar | null;\n private _video: TextureVideo | null;\n private _rangeControl: RangeControl;\n\n private _wasPaused: boolean;\n private _currentTime: number;\n private _duration: number;\n private _playPromise: Promise | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_TOP,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.position = position;\n this.order = order;\n\n this._controlBar = null;\n this._rangeControl = new RangeControl();\n\n this._video = null;\n this._wasPaused = false;\n this._currentTime = 0;\n this._duration = 0;\n this._playPromise = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const element = this.element;\n const rangeControl = this._rangeControl;\n const unavailableClass = controlBar.className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n element.classList.add(unavailableClass);\n return;\n }\n\n element.classList.remove(unavailableClass);\n element.classList.add(controlBar.className.PROGRESS_ROOT);\n viewer.on(EVENTS.RESIZE, this._onResize);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate);\n rangeControl.init(controlBar.className);\n rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n rangeControl.on(CONTROL_EVENTS.CHANGE, this._onControl);\n rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n this._video = video;\n this._currentTime = video.source.currentTime;\n this._duration = video.source.duration;\n this._controlBar = controlBar;\n\n rangeControl.updateStyle(this._currentTime / this._duration);\n }\n\n public destroy(viewer: View360) {\n const video = this._video;\n\n viewer.off(EVENTS.RESIZE, this._onResize);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate);\n }\n\n this._rangeControl.destroy();\n this._video = null;\n this._playPromise = null;\n }\n\n private _onResize = () => {\n this._rangeControl.resize();\n }\n\n private _onTimeUpdate = () => {\n const video = this._video;\n if (!video) return;\n\n this._currentTime = video.source.currentTime;\n this._rangeControl.updateStyle(this._currentTime / this._duration);\n };\n\n private _onDurationChange = () => {\n const video = this._video;\n if (!video) return;\n\n this._duration = video.source.duration;\n this._rangeControl.updateStyle(this._currentTime / this._duration);\n };\n\n private _onHold = (progress: number) => {\n const video = this._video;\n const controlBar = this._controlBar;\n if (!video || !controlBar) return;\n\n const paused = video.isPaused();\n\n video.source.pause();\n\n const time = video.source.duration * progress;\n video.source.currentTime = time;\n video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time }}));\n\n controlBar.rootEl.classList.add(controlBar.className.FIXED);\n this._wasPaused = !this._playPromise && paused;\n };\n\n private _onControl = (progress: number) => {\n const video = this._video;\n if (!video) return;\n\n const time = video.source.duration * progress;\n video.source.currentTime = time;\n video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time }}));\n };\n\n private _onRelease = () => {\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (video && controlBar) {\n if (!this._wasPaused && !this._playPromise) {\n this._playPromise = video.source.play()\n .catch(() => void 0);\n\n // This should not be chained\n this._playPromise.then(() => {\n this._playPromise = null;\n });\n\n controlBar.rootEl.classList.remove(controlBar.className.FIXED);\n }\n }\n\n this._wasPaused = false;\n };\n}\n\nexport default ProgressBar;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show video play / pause button.\n * @ko 비디오 재생 / 일시정지 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass PlayButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _controlBar: ControlBar | null;\n private _video: TextureVideo | null;\n private _paused: boolean;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n\n this._video = null;\n this._paused = true;\n this._controlBar = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const video = viewer.projection?.getTexture();\n const className = controlBar.className;\n const unavailableClass = className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n element.classList.add(unavailableClass);\n return;\n }\n\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.remove(unavailableClass);\n\n const paused = video.isPaused();\n this._video = video;\n this._paused = paused;\n this._controlBar = controlBar;\n\n if (paused) {\n this._onPause();\n } else {\n this._onPlay();\n }\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onPlay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onPause);\n }\n\n public destroy() {\n const video = this._video;\n const element = this.element;\n\n if (!video) return;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onPlay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onPause);\n\n this._video = null;\n this._paused = true;\n this._controlBar = null;\n }\n\n private _onClick = () => {\n const video = this._video;\n if (!video) return;\n\n if (this._paused) {\n video.source.play();\n } else {\n video.source.pause();\n }\n };\n\n private _onPlay = () => {\n if (!this._controlBar) return;\n\n const element = this.element;\n const className = this._controlBar.className;\n\n element.classList.add(className.PAUSE_BUTTON);\n element.classList.remove(className.PLAY_BUTTON);\n element.title = \"Pause Video\";\n\n this._paused = false;\n };\n\n private _onPause = () => {\n if (!this._controlBar) return;\n\n const element = this.element;\n const className = this._controlBar.className;\n\n element.classList.add(className.PLAY_BUTTON);\n element.classList.remove(className.PAUSE_BUTTON);\n element.title = \"Play Video\";\n\n this._paused = true;\n };\n}\n\nexport default PlayButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport RangeControl from \"./RangeControl\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { EVENTS } from \"../../const/external\";\n\n/**\n * Show video volume control.\n * @ko 비디오 볼륨 조절 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VolumeControl extends ControlBarItem {\n public get element() { return this._rootEl; }\n\n private _controlBar: ControlBar | null;\n private _rootEl: HTMLButtonElement;\n private _buttonEl: HTMLElement;\n private _rangeControl: RangeControl;\n private _video: TextureVideo | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this._controlBar = null;\n this._rangeControl = new RangeControl();\n this._createElements();\n\n this._video = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const root = this._rootEl;\n const button = this._buttonEl;\n const rangeControl = this._rangeControl;\n const className = controlBar.className;\n const unavailableClass = className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n root.classList.add(unavailableClass);\n return;\n }\n\n root.classList.remove(unavailableClass);\n root.classList.add(className.CONTROLS_BUTTON);\n root.classList.add(className.VOLUME_ROOT);\n button.classList.add(className.CONTROLS_BUTTON);\n\n if (video.source.muted) {\n button.classList.add(className.MUTED_BUTTON);\n } else {\n button.classList.add(className.UNMUTED_BUTTON);\n }\n\n viewer.on(EVENTS.RESIZE, this._onResize);\n root.addEventListener(BROWSER.EVENTS.TRANSITION_END, this._onResize);\n button.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_VOLUME_CHANGE, this._onVolumeChange);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_LOADED_DATA, this._updateDisplay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay);\n\n rangeControl.init(className);\n rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n rangeControl.on(CONTROL_EVENTS.CHANGE, this._onChange);\n rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n this._controlBar = controlBar;\n this._video = video;\n\n this._updateDisplay();\n }\n\n public destroy(viewer: View360) {\n const video = this._video;\n const button = this._buttonEl;\n const root = this._rootEl;\n\n root.className = \"\";\n button.className = \"\";\n\n viewer.off(EVENTS.RESIZE, this._onResize);\n root.removeEventListener(BROWSER.EVENTS.TRANSITION_END, this._onResize);\n button.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_VOLUME_CHANGE, this._onVolumeChange);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_LOADED_DATA, this._updateDisplay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay);\n }\n\n this._controlBar = null;\n this._rangeControl.destroy();\n this._video = null;\n }\n\n private _onResize = () => {\n this._rangeControl.resize();\n this._updateDisplay();\n }\n\n private _onClick = () => {\n const video = this._video;\n if (!video || this._rootEl.disabled) return;\n\n video.source.muted = !video.source.muted;\n };\n\n private _onVolumeChange = () => {\n const button = this._buttonEl;\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (!video || !controlBar) return;\n\n const className = controlBar.className;\n\n if (video.source.muted || video.source.volume === 0) {\n button.classList.add(className.MUTED_BUTTON);\n button.classList.remove(className.UNMUTED_BUTTON);\n } else {\n button.classList.add(className.UNMUTED_BUTTON);\n button.classList.remove(className.MUTED_BUTTON);\n }\n\n this._updateDisplay();\n };\n\n private _createElements() {\n const root = document.createElement(BROWSER.EL_BUTTON);\n const buttonEl = document.createElement(BROWSER.EL_DIV);\n\n root.appendChild(this._rangeControl.rootEl);\n root.appendChild(buttonEl);\n root.title = \"Toggle Mute\";\n\n this._rootEl = root;\n this._buttonEl = buttonEl;\n }\n\n private _onHold = (progress: number) => {\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (!video || !controlBar) return;\n\n const className = controlBar.className;\n\n video.source.volume = progress;\n\n this._rootEl.classList.add(className.FIXED);\n controlBar.containerEl.classList.add(className.FIXED);\n\n this._updateDisplay();\n };\n\n private _onChange = (progress: number) => {\n const video = this._video;\n if (!video) return;\n\n video.source.volume = progress;\n if (progress > 0) {\n video.source.muted = false;\n } else {\n video.source.muted = true;\n }\n\n this._updateDisplay();\n };\n\n private _onRelease = () => {\n const controlBar = this._controlBar;\n if (!controlBar) return;\n\n const className = controlBar.className;\n\n this._rootEl.classList.remove(className.FIXED);\n controlBar.containerEl.classList.remove(className.FIXED);\n };\n\n private _updateDisplay = () => {\n const video = this._video;\n const root = this._rootEl;\n if (!video) return;\n\n if (!video.hasAudio()) {\n root.disabled = true;\n return;\n }\n\n root.disabled = false;\n\n const volume = video.source.muted ? 0 : video.source.volume;\n\n this._rangeControl.updateStyle(volume);\n };\n}\n\nexport default VolumeControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport { isFullscreen } from \"../../utils\";\n\n/**\n * Show fullscreen enter / exit button.\n * @ko 풀스크린 진입 / 해제 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass FullscreenButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _controlBar: ControlBar | null;\n private _targetEl: HTMLElement | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n this.element.title = \"Toggle Fullscreen\";\n this._controlBar = null;\n this._targetEl = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n if (!this._fullscreenAvailable()) {\n element.classList.add(className.UNAVAILABLE);\n return;\n }\n\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.remove(className.UNAVAILABLE);\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._addFullscreenHandlers();\n\n if (isFullscreen()) {\n element.classList.add(className.FULLSCREEN_EXIT_BUTTON);\n } else {\n element.classList.add(className.FULLSCREEN_BUTTON);\n }\n\n this._controlBar = controlBar;\n this._targetEl = viewer.rootEl;\n }\n\n public destroy() {\n const element = this.element;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._removeFullscreenHandlers();\n\n this._controlBar = null;\n this._targetEl = null;\n }\n\n private _onClick = () => {\n const target = this._targetEl;\n if (!target) return;\n\n if (isFullscreen()) {\n this._exitFullscreen();\n } else {\n this._requestFullscreen(target);\n }\n };\n\n private _fullscreenAvailable() {\n return BROWSER.FULLSCREEN_REQUEST.some(key => !!document[key]);\n }\n\n private _requestFullscreen(el: HTMLElement) {\n for (const key of BROWSER.FULLSCREEN_REQUEST) {\n const request = el[key];\n if (request) {\n request.call(el);\n return;\n }\n }\n }\n\n private _exitFullscreen() {\n for (const key of BROWSER.FULLSCREEN_EXIT) {\n const exit = document[key];\n\n if (exit) {\n exit.call(document);\n return;\n }\n }\n }\n\n private _addFullscreenHandlers() {\n BROWSER.FULLSCREEN_CHANGE.forEach(evtName => {\n document.addEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _removeFullscreenHandlers() {\n BROWSER.FULLSCREEN_CHANGE.forEach(evtName => {\n document.removeEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _onFullscreenChange = () => {\n const element = this.element;\n const controlBar = this._controlBar;\n\n if (!controlBar) return;\n\n const className = controlBar.className;\n\n if (isFullscreen()) {\n element.classList.add(className.FULLSCREEN_EXIT_BUTTON);\n element.classList.remove(className.FULLSCREEN_BUTTON);\n } else {\n element.classList.add(className.FULLSCREEN_BUTTON);\n element.classList.remove(className.FULLSCREEN_EXIT_BUTTON);\n }\n };\n}\n\nexport default FullscreenButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\n\n/**\n * Show video current / total time.\n * @ko 비디오의 현재 / 총 재생시간을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VideoTime extends ControlBarItem {\n public readonly element: HTMLElement;\n private _video: TextureVideo | null;\n private _currentTime: number;\n private _duration: number;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n\n this._video = null;\n this._currentTime = 0;\n this._duration = 0;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const element = this.element;\n const className = controlBar.className;\n\n if (!video || !video.isVideo()) {\n element.classList.add(className.UNAVAILABLE);\n return;\n }\n\n element.classList.add(className.VIDEO_TIME_DISPLAY);\n element.classList.remove(className.UNAVAILABLE);\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange);\n\n this._video = video;\n this._currentTime = video.source.currentTime;\n this._duration = video.source.duration;\n\n this._updateDisplay();\n }\n\n public destroy() {\n const video = this._video;\n\n if (!video) return;\n\n this.element.className = \"\";\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange);\n\n this._video = null;\n }\n\n private _onTimeUpdate = () => {\n const video = this._video;\n if (!video) return;\n\n this._currentTime = video.source.currentTime;\n this._updateDisplay();\n };\n\n private _onDurationChange = () => {\n const video = this._video;\n if (!video) return;\n\n this._duration = video.source.duration;\n this._updateDisplay();\n };\n\n private _onCustomTimeChange = (evt: CustomEvent<{ time: number }>) => {\n this._currentTime = evt.detail.time;\n this._updateDisplay();\n };\n\n private _updateDisplay() {\n const time = this._currentTime;\n const timeMinute = Math.floor(time / 60);\n const timeSeconds = Math.floor(time - timeMinute * 60);\n const timeSecondsFormatted = timeSeconds < 10 ? `0${timeSeconds}` : timeSeconds;\n\n const duration = this._duration;\n const durationMinute = Math.floor(duration / 60);\n const durationSeconds = Math.floor(duration - durationMinute * 60);\n const durationSecondsFormatted = durationSeconds < 10 ? `0${durationSeconds}` : durationSeconds;\n\n this.element.innerText = `${timeMinute}:${timeSecondsFormatted} / ${durationMinute}:${durationSecondsFormatted}`;\n }\n}\n\nexport default VideoTime;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport { circulate, getObjectOption } from \"../../utils\";\nimport * as BROWSER from \"../../const/browser\";\nimport { EVENTS } from \"../../const/external\";\nimport { SVG_NAMESPACE } from \"../../const/internal\";\n\n/**\n * Options for {@link PieView}\n * @ko {@link PieView}용 옵션들\n * @category Plugin\n */\nexport interface PieViewOptions extends ControlBarItemOptions {\n /**\n * @copy PieView#resetCamera\n */\n resetCamera: boolean | Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n duration: number;\n easing: (x: number) => number;\n }>;\n}\n\n/**\n * Show camera direction/fov indicator.\n * @ko 카메라가 향하는 방향 및 FOV를 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass PieView extends ControlBarItem {\n public readonly element: HTMLElement;\n\n /**\n * Set rotation to reset camera to when PieView is clicked.\n * `false` will disable this value, and `true` will enable with default options.\n * @ko PieView가 클릭되었을 때 카메라를 리셋할 방향을 지정합니다.\n * `false`일 경우 이 동작을 비활성화하며, `true`일 경우 기본값을 사용합니다.\n * @since 4.0.0\n */\n public resetCamera: PieViewOptions[\"resetCamera\"];\n\n private _viewer: View360 | null;\n private _piePathEl: SVGPathElement;\n private _rangeCircleEl: SVGCircleElement;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n resetCamera = true,\n position = CONTROL_BAR_ITEM_POSITION.TOP_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n this.element.title = \"Reset view\";\n this.resetCamera = resetCamera;\n this._createPieElements();\n this._viewer = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n\n if (!viewer.initialized) {\n viewer.once(EVENTS.READY, this._updatePie);\n } else {\n this._updatePie({ target: viewer });\n }\n\n const rootClass = controlBar.className.PIEVIEW_ROOT;\n element.classList.add(rootClass);\n\n if (this.resetCamera) {\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n }\n\n viewer.on(EVENTS.VIEW_CHANGE, this._updatePie);\n\n this._viewer = viewer;\n }\n\n public destroy(viewer: View360) {\n const element = this.element;\n\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.className = \"\";\n viewer.off(EVENTS.READY, this._updatePie);\n viewer.off(EVENTS.VIEW_CHANGE, this._updatePie);\n\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n const resetCamera = this.resetCamera;\n\n if (!viewer || !resetCamera) return;\n\n const {\n yaw = viewer.initialYaw,\n pitch = viewer.initialPitch,\n zoom = viewer.initialZoom,\n duration = 500\n } = getObjectOption(resetCamera);\n\n viewer.camera.animateTo({\n yaw,\n pitch,\n zoom,\n duration\n });\n };\n\n private _createPieElements() {\n const root = this.element;\n const pieSVG = document.createElementNS(SVG_NAMESPACE, \"svg\");\n pieSVG.setAttribute(\"viewBox\", \"0 0 48 48\");\n pieSVG.setAttribute(\"width\", \"100%\");\n pieSVG.setAttribute(\"height\", \"100%\");\n\n const piePath = document.createElementNS(SVG_NAMESPACE, \"circle\");\n\n piePath.setAttribute(\"stroke\", \"currentColor\");\n piePath.setAttribute(\"fill\", \"transparent\");\n piePath.setAttribute(\"cx\", \"24\");\n piePath.setAttribute(\"cy\", \"24\");\n piePath.setAttribute(\"r\", \"12\");\n piePath.setAttribute(\"stroke-width\", \"24\");\n pieSVG.appendChild(piePath);\n\n const rangeCircle = document.createElementNS(SVG_NAMESPACE, \"circle\");\n\n rangeCircle.setAttribute(\"stroke\", \"currentColor\");\n rangeCircle.setAttribute(\"fill\", \"transparent\");\n rangeCircle.setAttribute(\"cx\", \"24\");\n rangeCircle.setAttribute(\"cy\", \"24\");\n rangeCircle.setAttribute(\"r\", \"22.5\");\n rangeCircle.setAttribute(\"stroke-width\", \"3\");\n pieSVG.appendChild(rangeCircle);\n\n root.appendChild(pieSVG);\n\n this._piePathEl = piePath;\n this._rangeCircleEl = rangeCircle;\n }\n\n private _updatePie = ({ target: viewer }: { target: View360 }) => {\n const piePath = this._piePathEl;\n const rangeCircle = this._rangeCircleEl;\n const camera = viewer.camera;\n const fov = camera.getHorizontalFov();\n const yawRange = camera.getYawRange(camera.zoom);\n const halfFov = fov * 0.5;\n\n const pieRadius = 24 * Math.PI;\n const pieDeg = pieRadius * fov / 360;\n const pieOffset = pieRadius * (camera.yaw + halfFov + 90) / 360;\n\n piePath.setAttribute(\"stroke-dasharray\", `${pieDeg} ${pieRadius - pieDeg}`);\n piePath.setAttribute(\"stroke-dashoffset\", `${pieOffset}`);\n\n if (isFinite(yawRange.min) && isFinite(yawRange.max)) {\n const radius = 45 * Math.PI; // 2 * PI * r\n const min = (circulate(yawRange.min, -180, 180) - halfFov) / 360;\n const max = (circulate(yawRange.max, -180, 180) + halfFov) / 360;\n\n const rangeDiff = radius * Math.abs(max - min);\n const offset = -radius * (min - 0.25);\n\n rangeCircle.setAttribute(\"stroke-dasharray\", `${rangeDiff} ${radius - rangeDiff}`);\n rangeCircle.setAttribute(\"stroke-dashoffset\", `${offset}`);\n } else {\n rangeCircle.setAttribute(\"stroke-dasharray\", \"\");\n rangeCircle.setAttribute(\"stroke-dashoffset\", \"\");\n }\n };\n}\n\nexport default PieView;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show VR enter button.\n * @ko VR 진입 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VRButton extends ControlBarItem {\n public readonly element: HTMLElement;\n\n private _viewer: View360 | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n this.element.title = \"Enter VR\";\n this._viewer = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n element.classList.add(className.UNAVAILABLE);\n element.classList.add(className.VR_BUTTON);\n element.classList.add(className.CONTROLS_BUTTON);\n\n viewer.vr.isAvailable()\n .then(available => {\n if (available) {\n element.classList.remove(className.UNAVAILABLE);\n }\n });\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._viewer = viewer;\n }\n\n public destroy() {\n const element = this.element;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n if (!viewer) return;\n\n viewer.vr.enter();\n };\n}\n\nexport default VRButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport GyroControl from \"../../control/GyroControl\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { sensorCanBeEnabledIOS } from \"../../utils\";\n\n/**\n * Show gyroscope control enable / disable button\n * @ko 자이로스코프 컨트롤 활성화 / 비활성화 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass GyroButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _viewer: View360 | null;\n private _controlBar: ControlBar | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n this.element.title = \"Toggle gyroscope control\";\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.add(className.UNAVAILABLE);\n\n const enableButton = () => {\n element.classList.remove(className.UNAVAILABLE);\n viewer.control.gyro.on(CONTROL_EVENTS.ENABLE, this._updateStyle);\n viewer.control.gyro.on(CONTROL_EVENTS.DISABLE, this._updateStyle);\n };\n\n if (sensorCanBeEnabledIOS()) {\n enableButton();\n } else {\n GyroControl.isAvailable().then(available => {\n if (!available) return;\n enableButton();\n });\n }\n\n this._controlBar = controlBar;\n this._viewer = viewer;\n this._updateStyle();\n }\n\n public destroy(viewer: View360) {\n const element = this.element;\n\n viewer.control.gyro.off(CONTROL_EVENTS.ENABLE, this._updateStyle);\n viewer.control.gyro.off(CONTROL_EVENTS.DISABLE, this._updateStyle);\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.className = \"\";\n\n this._controlBar = null;\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n const controlBar = this._controlBar;\n\n if (!viewer || !controlBar) return;\n\n const gyroControl = viewer.control.gyro;\n if (gyroControl.enabled) {\n gyroControl.disable();\n } else {\n GyroControl.requestSensorPermission().then(available => {\n if (available) {\n gyroControl.enable();\n } else {\n this.element.classList.add(controlBar.className.UNAVAILABLE);\n }\n });\n }\n };\n\n private _updateStyle = () => {\n const element = this.element;\n const viewer = this._viewer;\n const controlBar = this._controlBar;\n\n if (!viewer || !controlBar) return;\n\n const gyroControl = viewer.control.gyro;\n const className = controlBar.className;\n\n if (gyroControl.enabled) {\n element.classList.add(className.GYRO_ENABLED);\n element.classList.remove(className.GYRO_DISABLED);\n } else {\n element.classList.add(className.GYRO_DISABLED);\n element.classList.remove(className.GYRO_ENABLED);\n }\n };\n}\n\nexport default GyroButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport { FULLSCREEN_CHANGE } from \"../../const/browser\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport { isFullscreen } from \"../../utils\";\n\n/**\n * Options for ControlBar's {@link ControlBarOptions#autoHide}\n * @ko ControlBar의 {@link ControlBarOptions#autoHide}용 옵션\n * @category Plugin\n * @since 4.0.0\n */\nexport interface AutoHideOptions {\n /**\n * Initial delay before the control bar hides (ms)\n * @ko 컨트롤바가 처음으로 표시되고 사라지기까지 걸리는 시간 (ms)\n * @default 3000\n * @since 4.0.0\n */\n initialDelay: number;\n /**\n * Delay time before hiding the control bar after mouse leave (ms)\n * @ko 마우스가 컨트롤바 영역을 떠난 뒤 컨트롤바가 사라지기까지 걸리는 시간 (ms)\n * @default 0\n * @since 4.0.0\n */\n delay: number;\n /**\n * Delay time before hiding the control bar becomes active, like touch on mobile device or mouse move in fullscreen mode (ms)\n * @ko 모바일이나 풀스크린 환경 등에서 사용자 입력이 없을 때 컨트롤바가 사라지기까지 걸리는 시간 (ms)\n * @default 3000\n * @since 4.0.0\n */\n idleDelay: number;\n}\n\nclass AutoHide {\n private _initialDelay: AutoHideOptions[\"initialDelay\"];\n private _delay: AutoHideOptions[\"delay\"];\n private _idleDelay: AutoHideOptions[\"idleDelay\"];\n\n private _controlBar: ControlBar;\n private _timer: number;\n private _isGrabbing: boolean;\n private _isCursorInside: boolean;\n private _isFullscreen: boolean;\n private _targetEl: HTMLElement | null;\n private _video: TextureVideo | null;\n\n public get enabled() { return !!this._targetEl; }\n public get hidden() { return this._controlBar.containerEl.classList.contains(this._hiddenClass); }\n\n private get _hiddenClass() { return this._controlBar.className.HIDDEN; }\n private get _fixedClass() { return this._controlBar.className.FIXED; }\n\n public constructor(controlBar: ControlBar, {\n initialDelay = 3000,\n delay = 0,\n idleDelay: activationDelay = 3000\n }: Partial) {\n this._controlBar = controlBar;\n this._initialDelay = initialDelay;\n this._delay = delay;\n this._idleDelay = activationDelay;\n this._timer = -1;\n this._isCursorInside = false;\n this._isGrabbing = false;\n this._isFullscreen = false;\n this._video = null;\n this._targetEl = null;\n }\n\n public enable(viewer: View360) {\n if (this._targetEl) {\n this.disable(viewer);\n }\n\n const initialDelay = this._initialDelay;\n const root = viewer.rootEl;\n\n this._targetEl = viewer.rootEl;\n this._timer = window.setTimeout(() => {\n this.hide();\n }, initialDelay);\n\n root.addEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onHold);\n root.addEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter);\n root.addEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove);\n root.addEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave);\n this._addFullscreenHandlers();\n\n const video = viewer.projection?.getTexture();\n if (!video || !video.isVideo()) {\n return;\n }\n\n if (video.isPaused()) {\n this._controlBar.containerEl.classList.add(this._fixedClass);\n }\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onVideoPlay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onVideoPause);\n\n this._video = video;\n }\n\n public disable(viewer: View360) {\n if (!this._targetEl) return;\n\n const controlBar = this._controlBar;\n const root = viewer.rootEl;\n const video = this._video;\n\n root.removeEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onHold);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave);\n this._removeFullscreenHandlers();\n\n window.clearTimeout(this._timer);\n controlBar.containerEl.classList.remove(this._fixedClass);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onVideoPlay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onVideoPause);\n }\n\n this._isCursorInside = false;\n this._isGrabbing = false;\n this._video = null;\n this._targetEl = null;\n }\n\n public show() {\n this._clearHideTimer();\n this._controlBar.containerEl.classList.remove(this._hiddenClass);\n }\n\n public showTemporaliy() {\n this.show();\n this._hideAfterDelay(this._idleDelay);\n }\n\n public hide() {\n this._clearHideTimer();\n this._controlBar.containerEl.classList.add(this._hiddenClass);\n }\n\n private _clearHideTimer() {\n if (this._timer) {\n window.clearTimeout(this._timer);\n this._timer = -1;\n }\n }\n\n private _hideAfterDelay(delay = this._delay) {\n if (this._isGrabbing || (!this._isFullscreen && this._isCursorInside)) return;\n\n this._clearHideTimer();\n if (delay <= 0) {\n this.hide();\n } else {\n this._timer = window.setTimeout(() => {\n this.hide();\n }, delay);\n }\n }\n\n private _onMouseEnter = () => {\n this._isCursorInside = true;\n this.show();\n };\n\n private _onMouseLeave = () => {\n this._isCursorInside = false;\n this._hideAfterDelay();\n };\n\n private _onMouseMove = () => {\n if (!this._isFullscreen) return;\n\n this.showTemporaliy();\n }\n\n private _onHold = (evt: PointerEvent) => {\n this._isGrabbing = true;\n\n if (evt.pointerType === \"mouse\") {\n this._isCursorInside = true;\n }\n\n window.addEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n\n this.show();\n };\n\n private _onRelease = () => {\n this._isGrabbing = false;\n\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n\n this._hideAfterDelay();\n };\n\n private _onVideoPlay = () => {\n const root = this._targetEl;\n if (!root) return;\n\n this._controlBar.containerEl.classList.remove(this._fixedClass);\n };\n\n private _onVideoPause = () => {\n const root = this._targetEl;\n if (!root) return;\n\n this._controlBar.containerEl.classList.add(this._fixedClass);\n };\n\n private _addFullscreenHandlers() {\n FULLSCREEN_CHANGE.forEach(evtName => {\n document.addEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _removeFullscreenHandlers() {\n FULLSCREEN_CHANGE.forEach(evtName => {\n document.removeEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _onFullscreenChange = () => {\n this._isFullscreen = isFullscreen();\n\n if (this._isFullscreen) {\n this._hideAfterDelay();\n }\n };\n}\n\nexport default AutoHide;\n","import TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { clamp } from \"../../utils\";\nimport { VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\n\nclass VideoControl {\n private _video: TextureVideo | null;\n\n public enable(root: HTMLElement, video: TextureVideo) {\n this._video = video;\n // capture is needed for resolving conflict with keyboard control\n root.addEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown, true);\n }\n\n public disable(root: HTMLElement) {\n this._video = null;\n root.removeEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown, true);\n }\n\n private _onKeyDown = (event: KeyboardEvent) => {\n const video = this._video;\n if (!video) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n const videoEl = video.source;\n const keyPressed = event.keyCode != null\n ? BROWSER.DIRECTION_KEY_CODE[event.keyCode]\n : BROWSER.DIRECTION_KEY_NAME[event.key];\n\n switch (keyPressed) {\n case \"LEFT\":\n case \"RIGHT\":\n return this._changeVideoTime(videoEl, keyPressed === \"RIGHT\");\n case \"UP\":\n case \"DOWN\":\n return this._changeVideoVolume(videoEl, keyPressed === \"UP\");\n }\n\n const spacePressed = event.keyCode === BROWSER.SPACE_KEY_CODE || event.key === BROWSER.SPACE_KEY_NAME;\n if (spacePressed) {\n this._toggleVideo(video);\n }\n }\n\n private _changeVideoTime(video: HTMLVideoElement, forward: boolean) {\n const delta = forward ? 5 : -5;\n\n video.currentTime += delta;\n video.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time: video.currentTime }}));\n }\n\n private _changeVideoVolume(video: HTMLVideoElement, increase: boolean) {\n const delta = increase ? 0.1 : -0.1;\n\n if (video.muted) {\n video.volume = clamp(delta, 0, 1);\n } else {\n video.volume = clamp(video.volume + delta, 0, 1);\n }\n\n if (video.volume > 0) {\n video.muted = false;\n } else {\n video.muted = true;\n }\n }\n\n private _toggleVideo(video: TextureVideo) {\n if (video.isPaused()) {\n video.source.play();\n } else {\n video.source.pause();\n }\n }\n}\n\nexport default VideoControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport ProgressBar from \"./ProgressBar\";\nimport PlayButton from \"./PlayButton\";\nimport VolumeControl from \"./VolumeControl\";\nimport FullscreenButton from \"./FullscreenButton\";\nimport VideoTime from \"./VideoTime\";\nimport PieView, { PieViewOptions } from \"./PieView\";\nimport VRButton from \"./VRButton\";\nimport GyroButton from \"./GyroButton\";\nimport AutoHide, { AutoHideOptions } from \"./AutoHide\";\nimport VideoControl from \"./VideoControl\";\nimport View360, { View360Events } from \"../../View360\";\nimport View360Plugin from \"../View360Plugin\";\nimport { EVENTS } from \"../../const/external\";\nimport { createElement, findIndex, getObjectOption } from \"../../utils\";\nimport { ValueOf } from \"../../type/utils\";\nimport { StaticClickEvent } from \"../../type/events\";\nimport { CONTROL_BAR_DEFAULT_CLASS, CONTROL_BAR_ITEM_POSITION } from \"./const\";\n\n/**\n * Options for {@link ControlBar}\n * @ko {@link ControlBar}용 옵션들\n * @category Plugin\n * @since 4.0.0\n */\nexport interface ControlBarOptions {\n /**\n * @copy ControlBar#autoHide\n */\n autoHide: boolean | Partial;\n /**\n * @copy ControlBar#showBackground\n */\n showBackground: boolean;\n /**\n * @copy ControlBar#clickToPlay\n */\n clickToPlay: boolean;\n /**\n * @copy ControlBar#keyboardControls\n */\n keyboardControls: boolean;\n /**\n * @copy ControlBar#progressBar\n */\n progressBar: boolean | Partial;\n /**\n * @copy ControlBar#playButton\n */\n playButton: boolean | Partial;\n /**\n * @copy ControlBar#volumeButton\n */\n volumeButton: boolean | Partial;\n /**\n * @copy ControlBar#fullscreenButton\n */\n fullscreenButton: boolean | Partial;\n /**\n * @copy ControlBar#videoTime\n */\n videoTime: boolean | Partial;\n /**\n * @copy ControlBar#pieView\n */\n pieView: boolean | Partial;\n /**\n * @copy ControlBar#vrButton\n */\n vrButton: boolean | Partial;\n /**\n * @copy ControlBar#gyroButton\n */\n gyroButton: boolean | Partial;\n /**\n * @copy ControlBar#className\n */\n className: Partial<{ -readonly [key in keyof typeof ControlBar.DEFAULT_CLASS]: string }>;\n /**\n * @copy ControlBar#customItems\n */\n customItems: ControlBarItem[];\n}\n\n/**\n * A plugin that displays extra buttons & controls that controls {@link View360}.\n * @ko {@link View360}에 부가적인 버튼과 컨트롤을 추가해주는 플러그인.\n * @category Plugin\n * @since 4.0.0\n */\nclass ControlBar implements View360Plugin {\n /**\n * Default class names that ControlBar uses\n * @ko ControlBar가 사용하는 디폴트 클래스 이름들\n * @since 4.0.0\n */\n public static readonly DEFAULT_CLASS = CONTROL_BAR_DEFAULT_CLASS;\n\n /**\n * Constants for {@link ControlBarItemOptions#position}\n * @ko {@link ControlBarItemOptions#position}에 사용 가능한 값들\n */\n public static readonly POSITION = CONTROL_BAR_ITEM_POSITION;\n\n /**\n * Automatically hide control bar on video plays.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 재생시 자동으로 컨트롤바를 숨깁니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly autoHide?: ControlBarOptions[\"autoHide\"];\n /**\n * Show background element.\n * @ko 배경 엘리먼트를 표시합니다.\n * @since 4.0.0\n */\n public readonly showBackground?: ControlBarOptions[\"showBackground\"];\n /**\n * Whether to play / pause video on canvas click\n * @ko 캔버스 클릭시에 비디오를 재생 / 일시정지 토글합니다.\n * @since 4.0.0\n */\n public readonly clickToPlay: ControlBarOptions[\"clickToPlay\"];\n /**\n * Enable keyboard controls for video.\n * Pressing up / down arrow will control video volume, and pressing left / right arrow will control video time.\n * @ko 비디오 키보드 컨트롤을 활성화합니다.\n * 위 / 아래 화살표키를 누를 시 비디오 볼륨을, 왼쪽 / 오른쪽 화살표키를 누를 시 비디오 시간을 조정합니다.\n * @since 4.0.0\n */\n public readonly keyboardControls: ControlBarOptions[\"keyboardControls\"];\n /**\n * Show video progress bar.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 프로그레스 바를 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly progressBar: ControlBarOptions[\"progressBar\"];\n /**\n * Show video play / pause button.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 재생 / 일시정지 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly playButton: ControlBarOptions[\"playButton\"];\n /**\n * Show video volume control button.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 볼륨 조절 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly volumeButton: ControlBarOptions[\"volumeButton\"];\n /**\n * Show fullscreen button.\n * `true` to enable with default values, `false` to disable.\n * @ko 풀스크린 진입 / 해제 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly fullscreenButton: ControlBarOptions[\"fullscreenButton\"];\n /**\n * Show video current / total time\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오의 현재 시간 / 총 시간을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly videoTime: ControlBarOptions[\"videoTime\"];\n /**\n * Show camera pie view.\n * `true` to enable with default values, `false` to disable.\n * @ko 현재 카메라가 가리키는 방향을 표시하는 파이 뷰를 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly pieView: ControlBarOptions[\"pieView\"];\n /**\n * Show VR button.\n * `true` to enable with default values, `false` to disable.\n * @ko VR 진입버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly vrButton: ControlBarOptions[\"vrButton\"];\n /**\n * Show gyroscope control enable / disable button.\n * `true` to enable with default values, `false` to disable.\n * @ko 자이로스코프 컨트롤을 활성화 / 비활성화하는 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly gyroButton: ControlBarOptions[\"gyroButton\"];\n /**\n * Override default class names.\n * @ko 디폴트 클래스 이름들을 오버라이드합니다.\n * @since 4.0.0\n */\n public readonly className: Required;\n\n /**\n * Root element of the control bar\n * @ko 컨트롤바의 루트 엘리먼트\n * @since 4.0.0\n */\n public get rootEl() { return this._rootEl; }\n /**\n * Container element of the control bar\n * @ko 컨트롤바의 컨테이너 엘리먼트\n * @since 4.0.0\n */\n public get containerEl() { return this._containerEl; }\n /**\n * Background element of the control bar\n * @ko 컨트롤바의 배경 엘리먼트\n * @since 4.0.0\n */\n public get backgroundEl() { return this._bgEl; }\n /**\n * Control bar's default items created by {@link ControlBarOptions}\n * @ko 주어진 {@link ControlBarOptions}에 의해 생성된 디폴트 아이템들\n * @since 4.0.0\n */\n public get items() { return this._items; }\n /**\n * Custom control bar items\n * @ko 커스텀 컨트롤바 아이템들을 추가합니다.\n * @since 4.0.0\n */\n public get customItems() { return this._customItems; }\n\n private _rootEl: HTMLElement;\n private _containerEl: HTMLElement;\n private _bgEl: HTMLElement;\n private _wrapperEl: Record, HTMLElement>;\n private _items: Record, ControlBarItem[]>;\n private _customItems: ControlBarItem[];\n private _autoHider: AutoHide;\n private _videoControl: VideoControl;\n\n /**\n * Create new instance of ControlBar.\n * @ko ControlBar의 새 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n autoHide,\n showBackground,\n clickToPlay = true,\n keyboardControls = true,\n progressBar = true,\n playButton = true,\n volumeButton = true,\n fullscreenButton = true,\n videoTime = true,\n pieView = true,\n vrButton = true,\n gyroButton = true,\n className = {},\n customItems = []\n }: Partial = {}) {\n this.autoHide = autoHide;\n this.showBackground = showBackground;\n this.clickToPlay = clickToPlay;\n this.keyboardControls = keyboardControls;\n this.progressBar = progressBar;\n this.playButton = playButton;\n this.volumeButton = volumeButton;\n this.fullscreenButton = fullscreenButton;\n this.videoTime = videoTime;\n this.pieView = pieView;\n this.vrButton = vrButton;\n this.gyroButton = gyroButton;\n this.className = {\n ...ControlBar.DEFAULT_CLASS,\n ...className\n };\n\n const rootClass = className.CONTROLS_ROOT ?? ControlBar.DEFAULT_CLASS.CONTROLS_ROOT;\n\n this._rootEl = createElement(rootClass);\n this._createPositionWrappers();\n this._items = Object.keys(ControlBar.POSITION).reduce((items, key) => {\n items[ControlBar.POSITION[key]] = [];\n return items;\n }, {}) as Record, ControlBarItem[]>;\n this._customItems = customItems;\n this._autoHider = new AutoHide(this, getObjectOption(autoHide));\n this._videoControl = new VideoControl();\n\n customItems.forEach(item => {\n this._items[item.position].push(item);\n });\n }\n\n public init(viewer: View360) {\n const panoRoot = viewer.rootEl;\n const controlsRoot = this._rootEl;\n const defaultItems = this._createDefaultItems();\n\n this._updateBackground(viewer);\n this._updateAutoHide(viewer);\n this._updateKeyboardHandler(viewer);\n\n panoRoot.appendChild(controlsRoot);\n this._addItem(viewer, defaultItems);\n this._addItem(viewer, this._customItems);\n\n viewer.on(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad);\n viewer.on(EVENTS.STATIC_CLICK, this._onStaticClick);\n }\n\n public destroy(viewer: View360): void {\n // Remove controls root from pano root\n const panoRoot = viewer.rootEl;\n const controlsRoot = this._rootEl;\n const items = this._items;\n\n if (controlsRoot.parentElement === panoRoot) {\n panoRoot.removeChild(controlsRoot);\n }\n\n Object.keys(items).forEach((key: ValueOf) => {\n const category = items[key];\n\n category.forEach(item => {\n item.destroy(viewer, this);\n });\n\n items[key] = [];\n });\n\n this._clearItemElements();\n this._autoHider.disable(viewer);\n this._videoControl.disable(panoRoot);\n\n viewer.off(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad);\n viewer.off(EVENTS.STATIC_CLICK, this._onStaticClick);\n }\n\n private _addItem(viewer: View360, items: ControlBarItem[]) {\n for (const item of items) {\n const category = this._items[item.position];\n const wrapper = this._wrapperEl[item.position];\n\n const nextSiblingIndex = findIndex(category, sibling => sibling.order > item.order);\n\n if (nextSiblingIndex >= 0) {\n const nextSibling = category[nextSiblingIndex].element;\n category.splice(nextSiblingIndex, 0, item);\n wrapper.insertBefore(item.element, nextSibling);\n } else {\n category.push(item);\n wrapper.appendChild(item.element);\n }\n\n item.init(viewer, this);\n }\n }\n\n private _createPositionWrappers() {\n const className = {\n ...ControlBar.DEFAULT_CLASS,\n ...this.className\n };\n const rootEl = this._rootEl;\n\n // BG & FLOATING CONTROLS\n const backgroundEl = createElement(className.CONTROLS_BG);\n const floatLeftEl = createElement(className.CONTROLS_FLOAT_LEFT);\n const floatRightEl = createElement(className.CONTROLS_FLOAT_RIGHT);\n\n rootEl.appendChild(floatLeftEl);\n rootEl.appendChild(floatRightEl);\n\n // BOTTOM CONTROLS\n const container = createElement(className.CONTROLS_MAIN);\n const topWrapper = createElement(className.CONTROLS_TOP);\n const bottomWrapper = createElement(className.CONTROLS_BOTTOM);\n const midWrapper = createElement(className.CONTROLS_MID);\n const leftControlsWrapper = createElement(className.CONTROLS_LEFT);\n const rightControlsWrapper = createElement(className.CONTROLS_RIGHT);\n\n midWrapper.appendChild(leftControlsWrapper);\n midWrapper.appendChild(rightControlsWrapper);\n container.appendChild(backgroundEl);\n container.appendChild(topWrapper);\n container.appendChild(midWrapper);\n container.appendChild(bottomWrapper);\n rootEl.appendChild(container);\n\n this._bgEl = backgroundEl;\n this._containerEl = container;\n this._wrapperEl = {\n [ControlBar.POSITION.MAIN_TOP]: topWrapper,\n [ControlBar.POSITION.MAIN_LEFT]: leftControlsWrapper,\n [ControlBar.POSITION.MAIN_RIGHT]: rightControlsWrapper,\n [ControlBar.POSITION.MAIN_BOTTOM]: bottomWrapper,\n [ControlBar.POSITION.TOP_LEFT]: floatLeftEl,\n [ControlBar.POSITION.TOP_RIGHT]: floatRightEl\n };\n }\n\n private _clearItemElements() {\n const wrappers = Object.keys(ControlBar.POSITION).map(key => ControlBar.POSITION[key]);\n\n // Remove all elements inside wrappers\n wrappers.forEach(wrapper => {\n while (wrapper.firstChild) {\n wrapper.removeChild(wrapper.firstChild);\n }\n });\n }\n\n private _onStaticClick = ({ target: viewer, isTouch }: StaticClickEvent) => {\n const autoHider = this._autoHider;\n\n if (isTouch) {\n if (!autoHider.enabled) return;\n\n if (autoHider.hidden) {\n autoHider.showTemporaliy();\n } else {\n autoHider.hide();\n }\n } else {\n if (!this.clickToPlay) return;\n\n const video = viewer.projection?.getTexture();\n if (!video || !video.isVideo()) return;\n\n if (video.isPaused()) {\n video.source.play();\n } else {\n video.source.pause();\n }\n }\n };\n\n private _onNewSrcLoad = ({ target: viewer }: View360Events[\"projectionChange\"]) => {\n const items = this._items;\n\n this._updateBackground(viewer);\n this._updateAutoHide(viewer);\n this._updateKeyboardHandler(viewer);\n\n Object.keys(items).forEach((key: ValueOf) => {\n const category = items[key];\n\n category.forEach(item => {\n item.destroy(viewer, this);\n item.init(viewer, this);\n });\n });\n };\n\n private _updateAutoHide(viewer: View360) {\n const autoHide = this.autoHide;\n const autoHider = this._autoHider;\n\n if (autoHide != null) {\n if (autoHide) {\n autoHider.enable(viewer);\n } else {\n autoHider.disable(viewer);\n }\n } else {\n // Automatically choose whether to show background by content type\n const texture = viewer.projection?.getTexture();\n\n if (texture && texture.isVideo()) {\n // Enable auto hide when content type is video\n autoHider.enable(viewer);\n } else {\n autoHider.disable(viewer);\n }\n }\n }\n\n private _updateBackground(viewer: View360) {\n const background = this._bgEl;\n const showBackground = this.showBackground;\n const hiddenClass = this.className.HIDDEN ?? ControlBar.DEFAULT_CLASS.HIDDEN;\n\n if (showBackground != null) {\n if (showBackground) {\n background.classList.remove(hiddenClass);\n } else {\n background.classList.add(hiddenClass);\n }\n } else {\n // Automatically choose whether to show background by content type\n const texture = viewer.projection?.getTexture();\n\n if (texture && texture.isVideo()) {\n // Show bg when content type is video\n background.classList.remove(hiddenClass);\n } else {\n background.classList.add(hiddenClass);\n }\n }\n }\n\n private _updateKeyboardHandler(viewer: View360) {\n const panoRoot = viewer.rootEl;\n const videoControl = this._videoControl;\n const texture = viewer.projection?.getTexture();\n\n if (this.keyboardControls && texture && texture.isVideo()) {\n videoControl.enable(panoRoot, texture);\n } else {\n videoControl.disable(panoRoot);\n }\n }\n\n private _createDefaultItems(): ControlBarItem[] {\n const items: ControlBarItem[] = [];\n\n if (this.progressBar) {\n items.push(new ProgressBar(getObjectOption(this.progressBar)));\n }\n\n if (this.playButton) {\n items.push(new PlayButton(getObjectOption(this.playButton)));\n }\n\n if (this.volumeButton) {\n items.push(new VolumeControl(getObjectOption(this.volumeButton)));\n }\n\n if (this.gyroButton) {\n items.push(new GyroButton(getObjectOption(this.gyroButton)));\n }\n\n if (this.vrButton) {\n items.push(new VRButton(getObjectOption(this.vrButton)));\n }\n\n if (this.fullscreenButton) {\n items.push(new FullscreenButton(getObjectOption(this.fullscreenButton)));\n }\n\n if (this.videoTime) {\n items.push(new VideoTime(getObjectOption(this.videoTime)));\n }\n\n if (this.pieView) {\n items.push(new PieView(getObjectOption(this.pieView)));\n }\n\n return items;\n }\n}\n\nexport default ControlBar;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Camera from \"../core/Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport Texture from \"../texture/Texture\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport { VideoConfig } from \"../type/external\";\nimport UniformCanvasCube from \"../uniform/UniformCanvasCube\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport UniformTextureCube from \"../uniform/UniformTextureCube\";\n\ntype CommonProjectionUniforms = {\n uTexture: UniformTexture2D | UniformTextureCube | UniformCanvasCube;\n}\n\n/**\n * Common option for {@link Projection}s\n * @ko {@link Projection}을 위한 공통 옵션들\n * @category Projection\n * @since 4.0.0\n */\nexport interface ProjectionOptions {\n /**\n * @copy Projection#src\n */\n src: string | HTMLElement | Array;\n /**\n * @copy Projection#video\n */\n video?: boolean | Partial;\n}\n\n/**\n * Base class for projections.\n * @ko 프로젝션 베이스 클래스.\n * @category Projection\n * @since 4.0.0\n */\nabstract class Projection {\n /**\n * Source URL to panorama image/video.\n * @ko 파노라마 이미지/비디오의 URL\n * @since 4.0.0\n */\n public readonly src: ProjectionOptions[\"src\"];\n /**\n * Properties for the video element.\n * Setting `false` will treat panorama source as an image, `true` will use default properties.\n * @ko 비디오 엘리먼트에 설정할 프로퍼티를 담는 객체.\n * @since 4.0.0\n * @example\n * Default properties\n * ```ts\n * autoplay: true\n * muted: true\n * loop: false\n * volume: 1\n * ```\n */\n public readonly video: ProjectionOptions[\"video\"];\n\n protected _mesh: TriangleMesh | null;\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n src,\n video = false\n }: ProjectionOptions) {\n this.src = src;\n this.video = video;\n this._mesh = null;\n }\n\n /**\n * Apply texture to current projection.\n * @ko 주어진 텍스쳐를 현재 프로젝션에 적용합니다.\n * @param ctx - Instance of the WebGLContext helper {@ko WebGL context 헬퍼의 인스턴스}\n * @param texture - New texture to apply {@ko 새로 적용할 텍스쳐}\n * @internal\n * @since 4.0.0\n */\n public abstract applyTexture(ctx: WebGLContext, texture: Texture): void;\n\n /**\n * Release all resources projection has.\n * This is automatically called on projection change & View360's destroy call\n * @ko 현재 갖고 있는 모든 리소스를 반환합니다.\n * 이 메소드는 프로젝션 변경 및 View360의 destroy 호출 시 자동으로 호출됩니다.\n * @param ctx\n */\n public releaseAllResources(ctx: WebGLContext) {\n this._mesh?.destroy(ctx);\n }\n\n /**\n * Update camera to match projection's settings.\n * @ko 현재 프로젝션의 세팅으로 카메라를 업데이트합니다.\n * @param camera - Instance of the camera to update {@ko 업데이트할 카메라의 인스턴스}\n * @since 4.0.0\n */\n public updateCamera(camera: Camera) {\n // Use default mode & no view restriction\n camera.resetRange();\n }\n\n /**\n * Update control to match projection's settings.\n * @ko 현재 프로젝션의 세팅으로 컨트롤을 업데이트합니다.\n * @param control - Instance of the control to update {@ko 업데이트할 컨트롤의 인스턴스}\n * @since 4.0.0\n */\n public updateControl(control: PanoControl) {\n control.ignoreZoomScale = false;\n }\n\n /**\n * Update projection.\n * @ko 현재 프로젝션 정보를 갱신합니다.\n * @param camera - Instance of the camera to reference {@ko 참조할 카메라의 인스턴스}\n * @since 4.0.0\n */\n public update(camera: Camera) {} // eslint-disable-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars\n\n /**\n * Return active texture.\n * @ko 현재 활성화된 텍스쳐를 반환합니다.\n * @internal\n * @since 4.0.0\n */\n public getTexture() {\n if (!this._mesh) return null;\n\n return this._mesh.program.uniforms.uTexture.texture;\n }\n\n /**\n * A 3D triangle mesh for projection. It's `null` until loading the `src`.\n * @ko Projection을 표시하기 위한 Mesh, src를 로드하기 전까지는 `null`입니다.\n * @since 4.0.0\n */\n public getMesh(): TriangleMesh | null {\n return this._mesh;\n }\n}\n\nexport default Projection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nabstract class Uniform {\n public needsUpdate: boolean;\n\n public constructor() {\n this.needsUpdate = true;\n }\n\n public abstract update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean): void;\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext) {\n // DO_NOTHING\n }\n}\n\nexport default Uniform;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport TextureCube from \"../texture/TextureCube\";\nimport { reorderCube } from \"../utils\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformTextureCube extends Uniform {\n public readonly texture: TextureCube;\n private _webglTexture: WebGLTexture;\n private _cubemapOrder: string;\n\n public constructor(ctx: WebGLContext, texture: TextureCube, cubemapOrder: string) {\n super();\n\n this.texture = texture;\n this._webglTexture = ctx.createWebGLCubeTexture(texture, texture.width);\n this._cubemapOrder = cubemapOrder;\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext): void {\n this.texture.destroy();\n gl.deleteTexture(this._webglTexture);\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture);\n\n const sources = reorderCube(texture.sources, this._cubemapOrder);\n sources.forEach((src, idx) => {\n if (isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src);\n } else {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src);\n }\n });\n\n if (!texture.isVideo()) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformTextureCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"../texture/Texture2D\";\nimport { range, reorderCube } from \"../utils\";\n\n/** @hidden */\nclass CubeTexturePainter {\n public readonly texture: Texture2D;\n private _renderingOrder: number[];\n private _canvas: HTMLCanvasElement;\n private _ctx: CanvasRenderingContext2D;\n private _row: number;\n private _column: number;\n private _size: number;\n\n public get size() { return this._size; }\n\n public constructor(texture: Texture2D, cubemapOrder: string) {\n this.texture = texture;\n this._renderingOrder = reorderCube(range(6), cubemapOrder);\n\n const canvas = document.createElement(\"canvas\");\n\n this._calcRenderingSize();\n\n canvas.width = this._size;\n canvas.height = this._size;\n\n this._canvas = canvas;\n this._ctx = canvas.getContext(\"2d\")!;\n }\n\n public destroy() {\n const canvas = this._canvas;\n\n // release memories\n canvas.width = 1;\n canvas.height = 1;\n this._canvas = null as any;\n }\n\n public draw(gl: WebGLRenderingContext | WebGL2RenderingContext, isWebGL2: boolean) {\n const size = this._size;\n const texture = this.texture;\n let surfaceIdx = 0;\n\n for (let row = 0; row < this._row; row++) {\n for (let column = 0; column < this._column; column++) {\n const x = size * column;\n const y = size * row;\n const renderingFace = this._renderingOrder[surfaceIdx];\n\n this._ctx.drawImage(texture.source as CanvasImageSource, x, y, size, size, 0, 0, size, size);\n\n if (isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas);\n } else {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas);\n }\n\n surfaceIdx++;\n }\n }\n }\n\n private _calcRenderingSize() {\n const {\n width,\n height\n } = this.texture;\n const aspect = width / height;\n\n if (aspect === 1 / 6) {\n this._size = width;\n this._row = 6;\n this._column = 1;\n } else if (aspect === 6) {\n this._size = height;\n this._row = 1;\n this._column = 6;\n } else if (aspect === 2 / 3) {\n this._size = width * 0.5;\n this._row = 3;\n this._column = 2;\n } else {\n this._size = width / 3;\n this._row = 2;\n this._column = 3;\n }\n }\n}\n\nexport default CubeTexturePainter;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport CubeTexturePainter from \"../core/CubeTexturePainter\";\nimport Texture2D from \"../texture/Texture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformCanvasCube extends Uniform {\n private _webglTexture: WebGLTexture;\n private _painter: CubeTexturePainter;\n\n public get texture() { return this._painter.texture; }\n\n public constructor(ctx: WebGLContext, texture: Texture2D, cubemapOrder: string) {\n super();\n\n this._painter = new CubeTexturePainter(texture as Texture2D, cubemapOrder);\n this._webglTexture = ctx.createWebGLCubeTexture(texture, this._painter.size);\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext) {\n gl.deleteTexture(this._webglTexture);\n this._painter.destroy();\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture);\n\n this._painter.draw(gl, isWebGL2);\n\n if (!texture.isVideo()) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformCanvasCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Object3D from \"./Object3D\";\nimport ShaderProgram from \"./ShaderProgram\";\nimport VertexArrayObject from \"./VertexArrayObject\";\nimport Uniform from \"../uniform/Uniform\";\nimport WebGLContext from \"./WebGLContext\";\n\n/**\n * @hidden\n */\nclass TriangleMesh = Record> extends Object3D {\n /**\n * @internal\n * Geometry data for projection\n */\n public readonly vao: VertexArrayObject;\n /**\n * @internal\n * Material(shader) data for projection\n */\n public readonly program: ShaderProgram;\n\n public constructor(vao: VertexArrayObject, program: ShaderProgram) {\n super();\n\n this.vao = vao;\n this.program = program;\n }\n\n public destroy(ctx: WebGLContext) {\n ctx.releaseVAO(this.vao);\n ctx.releaseShaderResources(this.program);\n }\n}\n\nexport default TriangleMesh;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"../uniform/Uniform\";\nimport WebGLContext from \"./WebGLContext\";\nimport { UniformLocations } from \"../type/internal\";\n\nclass ShaderProgram = Record> {\n public readonly program: WebGLProgram;\n public readonly uniforms: T;\n public readonly uniformLocations: UniformLocations;\n\n public constructor(ctx: WebGLContext, vertexShader: string, fragmentShader: string, uniforms: T) {\n this.program = ctx.createProgram(vertexShader, fragmentShader);\n this.uniforms = uniforms;\n this.uniformLocations = ctx.getUniformLocations(this.program, uniforms);\n }\n}\n\nexport default ShaderProgram;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { TypedArray } from \"../type/utils\";\n\n/**\n * @hidden\n */\nclass VertexData {\n public readonly data: T;\n public itemSize: number;\n public count: number;\n\n /** */\n public constructor(data: T, itemSize: number) {\n this.data = data;\n this.itemSize = itemSize;\n this.count = data.length / itemSize;\n }\n}\n\nexport default VertexData;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport VertexData from \"../core/VertexData\";\n\n/**\n * @hidden\n */\nabstract class Geometry {\n public readonly vertices: VertexData;\n public readonly indicies: VertexData;\n public readonly uvs: VertexData;\n\n /** */\n public constructor(vertices: number[], indicies: number[], uvs: number[]) {\n this.vertices = new VertexData(new Float32Array(vertices), 3);\n this.indicies = new VertexData(new Uint16Array(indicies), 1);\n this.uvs = new VertexData(new Float32Array(uvs), 2);\n }\n}\n\nexport default Geometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\nimport { ROTATE } from \"../const/internal\";\nimport { reorderCube } from \"../utils\";\n\n/**\n * @hidden\n */\nclass CubeGeometry extends Geometry {\n public constructor({\n order,\n rotateUV\n }: {\n order: string;\n rotateUV?: ROTATE[]\n }) {\n const vertices = [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // up\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // down\n -1, -1, 1,\n 1, -1, 1,\n 1, -1, -1,\n -1, -1, -1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n\n const indicies = [\n 0, 1, 2,\n 0, 2, 3,\n 4, 5, 6,\n 4, 6, 7,\n 8, 9, 10,\n 8, 10, 11,\n 12, 13, 14,\n 12, 14, 15,\n 16, 17, 18,\n 16, 18, 19,\n 20, 21, 22,\n 20, 22, 23\n ];\n\n const oneThird = 1 / 3;\n const coords: number[][] = [];\n\n for (let r = 1; r >= 0; r--) {\n for (let c = 0; c < 3; c++) {\n const coord = [\n c * oneThird, r * 0.5,\n (c + 1) * oneThird, r * 0.5,\n (c + 1) * oneThird, (r + 1) * 0.5,\n c * oneThird, (r + 1) * 0.5\n ];\n\n coords.push(coord);\n }\n }\n\n if (rotateUV) {\n rotateUV.forEach((degree, idx) => {\n if (degree === ROTATE.ZERO) return;\n\n const coord = coords[idx];\n let newOrder: number[];\n\n if (degree === ROTATE.CW_90) {\n newOrder = [1, 2, 3, 0];\n } else if (degree === ROTATE.CCW_90) {\n newOrder = [3, 0, 1, 2];\n } else {\n newOrder = [2, 3, 0, 1];\n }\n\n const newCoords = Array(coord.length);\n for (let uvIdx = 0; uvIdx < coord.length / 2; uvIdx++) {\n newCoords[uvIdx * 2 + 0] = coord[newOrder[uvIdx] * 2 + 0];\n newCoords[uvIdx * 2 + 1] = coord[newOrder[uvIdx] * 2 + 1];\n }\n\n coords[idx] = newCoords;\n });\n }\n\n const uvs = reorderCube(coords, order, \"BFUDRL\")\n .reduce((acc, val) => acc.concat(val), []);\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default CubeGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTextureCube from \"../uniform/UniformTextureCube\";\nimport UniformCanvasCube from \"../uniform/UniformCanvasCube\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport TextureCube from \"../texture/TextureCube\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/cube.vert\";\nimport fs from \"../shader/cube.frag\";\n\n/**\n * Options for {@link CubemapProjection}\n * @ko {@link CubemapProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CubemapProjectionOptions extends ProjectionOptions {\n /**\n * Order of the cubemap images.\n * @ko 큐브맵 이미지의 순서.\n * @since 4.0.0\n * @default \"RLUDFB\" (Right - Left - Up - Down - Front - Back)\n */\n cubemapOrder?: string;\n /**\n * Whether to flip cubemap image horizontally.\n * @ko 큐브맵 이미지를 좌우대칭할지 여부.\n * @since 4.0.0\n * @default false\n */\n cubemapFlipX?: boolean;\n}\n\n/**\n * Projection based on cubemap images, accepts both multiple or single images.\n * @ko 큐브맵 이미지 기반의 프로젝션, 단일 혹은 여러 장의 이미지를 모두 사용 가능합니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CubemapProjection extends Projection<{\n uTexture: UniformTextureCube | UniformCanvasCube;\n}> {\n private _cubemapOrder: NonNullable;\n private _cubemapFlipX: NonNullable;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CubemapProjectionOptions) {\n super(options);\n\n const {\n cubemapOrder = \"RLUDFB\",\n cubemapFlipX = false\n } = options;\n\n this._cubemapOrder = cubemapOrder;\n this._cubemapFlipX = cubemapFlipX;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const cubemapOrder = this._cubemapOrder;\n const cubemapFlipX = this._cubemapFlipX;\n const uniforms = {\n uTexture: texture.isCube()\n ? new UniformTextureCube(ctx, texture as TextureCube, cubemapOrder)\n : new UniformCanvasCube(ctx, texture as Texture2D, cubemapOrder)\n };\n\n const geometry = new CubeGeometry({\n order: cubemapOrder\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n if (cubemapFlipX) {\n mesh.scale[0] = -1;\n }\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n}\n\nexport default CubemapProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"../texture/Texture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformTexture2D extends Uniform {\n public readonly texture: Texture2D;\n private _webglTexture: WebGLTexture;\n\n public constructor(ctx: WebGLContext, texture: Texture2D) {\n super();\n\n this.texture = texture;\n this._webglTexture = ctx.createWebGLTexture(texture);\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext): void {\n this.texture.destroy();\n gl.deleteTexture(this._webglTexture);\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n const isVideo = texture.isVideo();\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._webglTexture);\n\n if (!isVideo && isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n } else {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n }\n\n if (!isVideo) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformTexture2D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link CubestripProjection}\n * @ko {@link CubestripProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CubestripProjectionOptions extends ProjectionOptions {\n /**\n * @copy CubemapProjectionOptions#cubemapOrder\n */\n cubemapOrder?: string;\n /**\n * @copy CubemapProjectionOptions#cubemapFlipX\n */\n cubemapFlipX?: boolean;\n}\n\n/**\n * Projection based on cubemap strip.\n * Slightly more efficient than {@link CubemapProjection} as it doesn't copy cubemap image to canvas while rendering.\n * Accepts only single image.\n * @ko 큐브맵 스트립 기반의 프로젝션.\n * {@link CubemapProjection}와 달리 렌더링하는 과정에 캔버스에 이미지를 복사하는 과정이 없기 때문에 살짝 더 효율적입니다.\n * 단일 이미지만 사용 가능합니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CubestripProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n private _cubemapOrder: NonNullable;\n private _cubemapFlipX: NonNullable;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CubestripProjectionOptions) {\n super(options);\n\n const {\n cubemapOrder = \"RLUDFB\",\n cubemapFlipX = false\n } = options;\n\n this._cubemapOrder = cubemapOrder;\n this._cubemapFlipX = cubemapFlipX;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const cubemapOrder = this._cubemapOrder;\n const cubemapFlipX = this._cubemapFlipX;\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n const geometry = new CubeGeometry({\n order: cubemapOrder\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n if (cubemapFlipX) {\n mesh.scale[0] = -1;\n }\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n}\n\nexport default CubestripProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass CylinderGeometry extends Geometry {\n public constructor(maxTheta: number) {\n const vertices: number[] = [];\n const indicies: number[] = [];\n const uvs: number[] = [];\n\n const height = 1;\n const radialSegments = 60;\n const halfHeight = height * 0.5;\n const heightSegments = [-halfHeight, halfHeight];\n const invRadialSegments = 1 / radialSegments;\n const angleConst = maxTheta * invRadialSegments;\n\n for (let yIdx = 0; yIdx < 2; yIdx++) {\n const y = heightSegments[yIdx];\n\n for (let lngIdx = 0; lngIdx <= radialSegments; lngIdx++) {\n const angle = lngIdx * angleConst + Math.PI - maxTheta * 0.5;\n const x = Math.cos(angle);\n const z = Math.sin(angle);\n const u = lngIdx * invRadialSegments;\n const v = yIdx;\n\n uvs.push(u, v);\n vertices.push(x, y, z);\n\n if (yIdx === 0 && lngIdx < radialSegments) {\n const a = lngIdx;\n const b = a + radialSegments + 1;\n\n indicies.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n }\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default CylinderGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n*/\nimport { quat } from \"gl-matrix\";\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport CylinderGeometry from \"../geometry/CylinderGeometry\";\nimport Camera from \"../core/Camera\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"../const/internal\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\nimport TriangleMesh from \"../core/TriangleMesh\";\n\n/**\n * Options for {@link CylindricalProjection}\n * @ko {@link CylindricalProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CylindricalProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n /**\n * Whether the panorama image covers full 360 degrees.\n * @ko 파노라마 이미지가 360도를 전부 커버하는지 여부\n * @since 4.0.0\n * @default false\n */\n partial?: boolean;\n}\n\n/**\n * Projection based on cylindrical projection.\n * This can show panorama images taken from smartphones.\n * @ko 원통 투영법 기반의 프로젝션.\n * 일반적인 스마트폰 파노라마 사진을 표시하는데 사용될 수 있습니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CylindricalProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n private _partial: boolean;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CylindricalProjectionOptions) {\n super(options);\n\n const {\n partial = false\n } = options;\n\n this._partial = partial;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const partial = this._partial;\n const { width, height } = texture;\n const aspect = width / height;\n const halfVFov = 180 / aspect;\n const cylinderHeight = partial\n ? 1\n : 2 * Math.tan(halfVFov * DEG_TO_RAD);\n const cylinderTheta = partial\n ? aspect\n : 2 * Math.PI;\n\n const geometry = new CylinderGeometry(cylinderTheta);\n const program = new ShaderProgram(ctx, vs, fs, {\n uTexture: new UniformTexture2D(ctx, texture)\n });\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n mesh.scale[1] = cylinderHeight;\n quat.identity(mesh.rotation);\n quat.rotateY(mesh.rotation, mesh.rotation, -Math.PI / 2);\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n\n public updateCamera(camera: Camera) {\n super.updateCamera(camera);\n\n const mesh = this._mesh;\n if (!mesh) return;\n\n const uTexture = mesh.program.uniforms.uTexture;\n const texture = uTexture.texture;\n const { width, height } = texture;\n const aspect = width / height;\n const halfHeight = mesh.scale[1] * 0.5;\n\n if (this._partial) {\n const restrictedYaw = 0.5 * aspect * RAD_TO_DEG;\n camera.restrictYawRange(-restrictedYaw, restrictedYaw);\n }\n\n const restrictedPitch = Math.atan2(halfHeight, 1) * RAD_TO_DEG;\n const minZoom = Math.tan(camera.fov * DEG_TO_RAD * 0.5) / (halfHeight * camera.aspect);\n\n camera.restrictPitchRange(-restrictedPitch, restrictedPitch);\n camera.restrictZoomRange(minZoom, Infinity);\n camera.restrictRenderHeight(halfHeight * 2);\n }\n}\n\nexport default CylindricalProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/eac.frag\";\nimport { ROTATE } from \"../const/internal\";\n\n/**\n * Options for {@link EquiangularProjection}\n * @ko {@link EquiangularProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface EquiangularProjectionOptions extends ProjectionOptions {}\n\n/**\n * Equi-Angular Cubemap Projection.\n * This format is used by Youtube's 360 videos.\n * @ko Equi-Angular Cubemap 프로젝션.\n * 이 포맷은 주로 Youtube의 360 비디오에 사용됩니다.\n * @since 4.0.0\n * @category Projection\n */\nclass EquiangularProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n const geometry = new CubeGeometry({\n order: \"LFRDBU\",\n rotateUV: [\n ROTATE.ZERO, ROTATE.ZERO, ROTATE.ZERO,\n ROTATE.CW_90, ROTATE.CCW_90, ROTATE.CW_90\n ]\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default EquiangularProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass SphereGeometry extends Geometry {\n /** */\n public constructor() {\n // const radius = 1;\n const widthSegments = 60;\n const heightSegments = 60;\n const ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI;\n\n const uvs: number[] = [];\n const vertices: number[] = [];\n const indicies: number[] = [];\n let latIdx: number;\n let lngIdx: number;\n\n for (latIdx = 0; latIdx <= widthSegments; latIdx++) {\n const theta = (latIdx / widthSegments - 0.5) * Math.PI;\n const sinTheta = Math.sin(theta);\n const cosTheta = Math.cos(theta);\n\n for (lngIdx = 0; lngIdx <= heightSegments; lngIdx++) {\n const phi = (lngIdx / heightSegments - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN;\n const sinPhi = Math.sin(phi);\n const cosPhi = Math.cos(phi);\n const x = cosPhi * cosTheta;\n const y = sinTheta;\n const z = sinPhi * cosTheta;\n const u = lngIdx / heightSegments;\n const v = latIdx / widthSegments;\n\n uvs.push(u, v);\n vertices.push(x, y, z);\n\n if (lngIdx !== heightSegments && latIdx !== widthSegments) {\n const a = latIdx * (heightSegments + 1) + lngIdx;\n const b = a + heightSegments + 1;\n\n indicies.push(a, a + 1, b, b, a + 1, b + 1);\n }\n }\n }\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default SphereGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport Texture2D from \"../texture/Texture2D\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport SphereGeometry from \"../geometry/SphereGeometry\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link EquirectProjection}\n * @ko {@link EquirectProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface EquirectProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n}\n\n/**\n * Projection based on equirectangular projection.\n * @ko 등 장방형 도법(Equirectangular projection) 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass EquirectProjection extends Projection<{\n uTexture: UniformTexture2D\n}> {\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: EquirectProjectionOptions) {\n super(options);\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n\n const geometry = new SphereGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default EquirectProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"./Uniform\";\n\nclass UniformFloat extends Uniform {\n public val: number;\n\n public constructor(val: number) {\n super();\n\n this.val = val;\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation) {\n gl.uniform1f(location, this.val);\n\n this.needsUpdate = false;\n }\n}\n\nexport default UniformFloat;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass PlaneGeometry extends Geometry {\n /** */\n public constructor(width: number = 2, height: number = 2, z: number = -1) {\n const halfWidth = width * 0.5;\n const halfHeight = height * 0.5;\n const vertices = [\n -halfWidth, -halfHeight, z,\n halfWidth, -halfHeight, z,\n -halfWidth, halfHeight, z,\n halfWidth, halfHeight, z\n ];\n const indicies = [\n 0, 1, 2,\n 2, 1, 3\n ];\n const uvs = [\n 0, 0,\n 1, 0,\n 0, 1,\n 1, 1\n ];\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default PlaneGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport UniformFloat from \"../uniform/UniformFloat\";\nimport Camera from \"../core/Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport Texture2D from \"../texture/Texture2D\";\nimport PlaneGeometry from \"../geometry/PlaneGeometry\";\nimport vs from \"../shader/little-planet.vert\";\nimport fs from \"../shader/little-planet.frag\";\nimport TriangleMesh from \"../core/TriangleMesh\";\n\n/**\n * Options for {@link LittlePlanetProjection}\n * @ko {@link LittlePlanetProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface LittlePlanetProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n}\n\n/**\n * Projection based on so-called \"Little planet\" or \"Tiny planet\" effect.\n * @ko \"Little planet\" 혹은 \"Tiny planet\"로 불리는 이펙트 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass LittlePlanetProjection extends Projection<{\n uTexture: UniformTexture2D;\n uYaw: UniformFloat;\n uPitch: UniformFloat;\n uZoom: UniformFloat;\n}> {\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: LittlePlanetProjectionOptions) {\n super(options);\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n texture.wrapS = WebGLRenderingContext.REPEAT;\n texture.wrapT = WebGLRenderingContext.REPEAT;\n\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture),\n uYaw: new UniformFloat(0),\n uPitch: new UniformFloat(0.5),\n uZoom: new UniformFloat(1)\n };\n\n const geometry = new PlaneGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n\n public updateControl(control: PanoControl) {\n control.ignoreZoomScale = true;\n }\n\n public update(camera: Camera) {\n const mesh = this._mesh;\n if (!mesh) return;\n\n const uniforms = mesh.program.uniforms;\n\n uniforms.uYaw.val = camera.yaw / 360;\n // Range from 0 ~ 1\n uniforms.uPitch.val = (camera.pitch / 180) + 0.5;\n uniforms.uZoom.val = camera.zoom;\n\n uniforms.uYaw.needsUpdate = true;\n uniforms.uPitch.needsUpdate = true;\n uniforms.uZoom.needsUpdate = true;\n }\n}\n\nexport default LittlePlanetProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"./Uniform\";\n\nclass UniformVector4Array extends Uniform {\n public val: number[][];\n\n public constructor(val: number[][]) {\n super();\n\n this.val = val;\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation) {\n gl.uniform4fv(location, this.val.reduce((arr, vector) => [...arr, ...vector], []));\n\n this.needsUpdate = false;\n }\n}\n\nexport default UniformVector4Array;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport SphereGeometry from \"../geometry/SphereGeometry\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport UniformVector4Array from \"../uniform/UniformVector4Array\";\nimport UniformFloat from \"../uniform/UniformFloat\";\nimport vs from \"../shader/stereoequi.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link StereoEquiProjection}\n * @ko {@link StereoEquiProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface StereoEquiProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n /**\n * Stereoscopic mode of the image\n * @ko 이미지의 스테레오스코픽 모드\n * @since 4.0.0\n * @default \"top_bottom\"\n */\n mode: typeof StereoEquiProjection.MODE[keyof typeof StereoEquiProjection.MODE]\n}\n\n/**\n * Projection based on stereo equirectangular images.\n * @ko Stereo equirectangular 이미지 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass StereoEquiProjection extends Projection<{\n uTexture: UniformTexture2D;\n uEye: UniformFloat;\n uTexScaleOffset: UniformVector4Array;\n}> {\n /**\n * Available stereoscopic modes\n * @ko 사용가능한 스테레오스코픽 모드들\n * @since 4.0.0\n */\n public static MODE = {\n /**\n * @ko 이미지가 왼쪽/오른쪽으로 구성되어있을 경우\n * @since 4.0.0\n */\n LEFT_RIGHT: \"left_right\",\n /**\n * @ko 이미지가 위/아래로 구성되어있을 경우\n * @since 4.0.0\n */\n TOP_BOTTOM: \"top_bottom\",\n } as const;\n\n private _mode: StereoEquiProjectionOptions[\"mode\"];\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: StereoEquiProjectionOptions) {\n super(options);\n\n this._mode = options.mode;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n let leftEye: number[];\n let rightEye: number[];\n\n switch (this._mode) {\n case StereoEquiProjection.MODE.LEFT_RIGHT:\n leftEye = [0.5, 1, 0, 0];\n rightEye = [0.5, 1, 0.5, 0];\n break;\n default:\n // Default, uses \"top_bottom\"\n leftEye = [1, 0.5, 0, 0];\n rightEye = [1, 0.5, 0, 0.5];\n }\n\n\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture),\n uEye: new UniformFloat(0),\n uTexScaleOffset: new UniformVector4Array([leftEye, rightEye])\n };\n\n const geometry = new SphereGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default StereoEquiProjection;\n","import Component from \"@egjs/component\";\nimport View360 from \"../View360\";\n\n/**\n * @hidden\n */\nconst withMethods = (prototype: any, attr: string) => {\n [Component.prototype, View360.prototype].forEach(proto => {\n Object.getOwnPropertyNames(proto)\n .filter(name => name.charAt(0) !== \"_\" && name !== \"constructor\")\n .forEach((name: string) => {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name)!;\n\n if (descriptor.value) {\n // Public Function\n Object.defineProperty(prototype, name, {\n value: function(...args) {\n return descriptor.value.call(this[attr], ...args);\n }\n });\n } else {\n const getterDescriptor: { get?: () => any; set?: (val: any) => void } = {};\n if (descriptor.get) {\n getterDescriptor.get = function() {\n return this[attr] && descriptor.get?.call(this[attr]);\n };\n }\n if (descriptor.set) {\n getterDescriptor.set = function(...args) {\n return descriptor.set?.call(this[attr], ...args);\n };\n }\n\n Object.defineProperty(prototype, name, getterDescriptor);\n }\n });\n });\n};\n\nexport default withMethods;\n","/**\n * @hidden\n */\nexport const getValidProps = (propsObj: any) => {\n return Object.keys(propsObj).reduce((props, propName) => {\n if (propsObj[propName] != null) {\n props[propName] = propsObj[propName];\n }\n\n return props;\n }, {});\n};\n","export const VIEW360_METHODS = [\n \"destroy\",\n \"init\",\n \"load\",\n \"resize\",\n \"addPlugins\",\n \"removePlugins\",\n \"renderFrame\",\n // @egjs/component methods\n \"on\",\n \"hasOn\",\n \"once\",\n \"off\",\n \"trigger\"\n] as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360, { View360Options, View360Events } from \"./View360\";\n\nexport * from \"./core\";\nexport * from \"./control\";\nexport * from \"./plugin\";\nexport * from \"./projection\";\nexport * from \"./hotspot\";\nexport * from \"./const/external\";\nexport * from \"./type/external\";\nexport * from \"./cfc\";\n\nexport type {\n View360Options,\n View360Events\n};\n\nexport default View360;\n"],"names":["View360Error","Error","constructor","message","code","Object","setPrototypeOf","prototype","name","ERROR_CODES","WRONG_TYPE","WRONG_OPTION","ELEMENT_NOT_FOUND","CANVAS_NOT_FOUND","WEBGL_NOT_SUPPORTED","FAILED_CREATE_CONTEXT_2D","PROVIDE_PROJECTION_FIRST","FAILED_LINKING_PROGRAM","INSUFFICIENT_ARGS","MESSAGES","val","types","map","type","join","optionName","query","msg","shaderLog","CODES","EVENTS","MOUSE_DOWN","MOUSE_MOVE","MOUSE_UP","TOUCH_START","TOUCH_MOVE","TOUCH_END","WHEEL","RESIZE","CONTEXT_MENU","MOUSE_ENTER","MOUSE_LEAVE","POINTER_DOWN","POINTER_MOVE","POINTER_UP","POINTER_CANCEL","POINTER_ENTER","POINTER_LEAVE","KEY_DOWN","KEY_UP","LOAD","ERROR","CLICK","DOUBLE_CLICK","CONTEXT_CREATE_ERROR","CONTEXT_LOST","CONTEXT_RESTORED","DEVICE_ORIENTATION","DEVICE_MOTION","ORIENTATION_CHANGE","VIDEO_PLAY","VIDEO_PAUSE","VIDEO_LOADED_DATA","VIDEO_VOLUME_CHANGE","VIDEO_TIME_UPDATE","VIDEO_DURATION_CHANGE","VIDEO_CAN_PLAYTHROUGH","TRANSITION_END","XR_END","EL_DIV","EL_BUTTON","MOUSE_BUTTON","CURSOR","GRAB","GRABBING","NONE","KEY_DIRECTION","DIRECTION_KEY_CODE","SPACE_KEY_CODE","DIRECTION_KEY_NAME","LEFT","UP","RIGHT","DOWN","SPACE_KEY_NAME","FULLSCREEN_REQUEST","FULLSCREEN_ELEMENT","FULLSCREEN_EXIT","FULLSCREEN_CHANGE","DEFAULT_CLASS","CONTAINER","CANVAS","CTX_LOST","IN_VR","HOTSPOT_CONTAINER","HOTSPOT","HOTSPOT_VISIBLE","HOTSPOT_FLIP_X","HOTSPOT_FLIP_Y","READY","LOAD_START","PROJECTION_CHANGE","BEFORE_RENDER","RENDER","INPUT_START","INPUT_END","VIEW_CHANGE","STATIC_CLICK","VR_START","VR_END","EASING","LINEAR","x","SINE_WAVE","Math","sin","PI","EASE_OUT_CUBIC","pow","EASE_OUT_BOUNCE","n1","d1","CAMERA_EVENTS","CHANGE","ANIMATION_END","CONTROL_EVENTS","ENABLE","DISABLE","DEG_TO_RAD","RAD_TO_DEG","DEFAULT_EASING","DEFAULT_ANIMATION_DURATION","INFINITE_RANGE","min","Infinity","max","DEFAULT_PITCH_RANGE","DEFAULT_ZOOM_RANGE","ROTATE","VIDEO_TIME_CHANGE_EVENT","SVG_NAMESPACE","SESSION_VR","XR_REFERENCE_SPACE","EPSILON","_a","Number","isString","isElement","nodeType","Node","ELEMENT_NODE","createElement","className","tag","BROWSER","el","document","classList","add","getNullableElement","parent","targetEl","parentEl","queryResult","querySelector","getElement","findCanvas","root","selector","canvas","range","end","Array","apply","undef","idx","clamp","lerp","a","b","t","circulate","size","abs","offset","findIndex","array","checker","length","getObjectOption","toVerticalFov","fovRadian","aspect","atan","tan","reorderCube","arr","order","defaultOrder","split","face","indexOf","index","isFullscreen","key","sensorCanBeEnabledIOS","DeviceMotionEvent","window","isSecureContext","hfovToZoom","baseFov","fov","renderingWidth","zoomedWidth","eulerToQuat","out","yaw","pitch","roll","quat","identity","pitchThreshold","pitchClamped","rotateY","rotateX","rotateZ","quatToEuler","quaternion","y","z","w","x2","y2","z2","w2","unit","test","atan2","view","vec3","fromValues","up","transformQuat","viewXZ","sqrt","Motion","_val","start","_start","_end","progress","_progress","activated","_activated","duration","_duration","loop","_loop","_range","easing","_easing","reset","update","deltaTime","prev","nextProgress","easedProgress","defaultVal","delta","setNewEndByDelta","setRange","CameraAnimation","_motion","camera","from","to","_camera","_from","_to","_finishPromise","Promise","resolve","_finish","getFinishPromise","motion","rotation","create","zoom","slerp","rotate","Camera","Component","_aspect","changed","_changed","yawRange","_initialYawRange","pitchRange","_initialPitchRange","zoomRange","_initialZoomRange","initialYaw","initialPitch","initialZoom","rollOffset","position","animation","_up","_yawRange","_pitchRange","_zoomRange","_updateQuaternion","viewMatrix","mat4","projectionMatrix","_maxRenderHeight","destroy","off","resize","width","height","prevAspect","updateMatrix","lookAt","prevQuaternion","clone","prevZoom","zoomDiff","equals","normalized","normalize","isSameRotation","copy","animateTo","finishPromise","then","trigger","restrictYawRange","restrictPitchRange","restrictZoomRange","restrictRenderHeight","resetRange","getYawRange","yawLimit","maxRenderHeight","halfHFov","getHorizontalFov","minYaw","maxYaw","halfVFovRad","h","d","theta","getPitchRange","pitchLimit","minPitch","maxPitch","halfVFov","getVerticalFov","getZoomRange","limit","minFov","maxFov","currentFov","current","_getZoomedHorizontalFov","hFov","vFov","fovToZoom","projMatrix","upDir","viewDir","perspective","onFrameRender","MouseInput","_onMouseDown","evt","_el","button","preventDefault","focus","_prevPos","clientX","clientY","addEventListener","_onMouseMove","_onMouseUp","srcEvent","isTouch","isKeyboard","prevPos","deltaX","deltaY","removeEventListener","scrolling","enable","element","disable","TouchInput","scrollable","_scrollable","_onTouchStart","touches","_scrolling","touch","_isFirstTouch","_onTouchMove","cancelable","_onTouchEnd","passive","KeyboardInput","active","pressed","_pressed","_onKeyDown","location","KeyboardEvent","DOM_KEY_LOCATION_STANDARD","_updateKeyPress","pressedCount","_getPressedKeyCount","repeat","_onKeyUp","_clearPressedKeys","_getDeltaByPressedKeys","reduce","obj","keyName","assign","event","isEnable","keyToUpdate","keyCode","filter","RotateControl","enabled","_enabled","enableBlocked","_enableBlocked","animating","_keyboardInput","_xMotion","_yMotion","_touchInput","pointerScale","_pointerScale","keyboardScale","_keyboardScale","disablePitch","_disablePitch","disableYaw","_disableYaw","disableKeyboard","_disableKeyboard","controlEl","_onInputStart","_changedWhileDragging","inputType","_onChange","invZoomScale","_zoomScale","screenScale","_screenScale","scale","scaledX","scaledY","_onInputEnd","_controlEl","_mouseInput","_bindInputs","xMotion","yMotion","keyboardInput","updateRange","setZoomScale","hfov","vfov","control","updateCursor","sync","mouseInput","touchInput","on","WheelInput","_onWheel","stopPropagation","_inputTimer","_clearTimer","_baseScale","setTimeout","capture","clearTimeout","PinchInput","prevDistance","_prevDistance","diff","pageX","pageY","distance","ZoomControl","_wheelInput","_scale","scaledDelta","_pinchInput","wheelInput","pinchInput","ROTATE_CONSTANT","PITCH_DELTA","YAW_DELTA_BY_ROLL","YAW_DELTA_BY_YAW","targetAxis","meshPoint","GyroInput","orientationUpdated","_orientationUpdated","ignoreRoll","_ignoreRoll","_onDeviceOrientation","prevOrientation","_orientation","alpha","beta","gamma","_needsCalibrate","_calibrateSensor","_updateScreenOrientation","screen","orientation","angle","undefined","_screenOrientation","_yawOrigin","_yawOffset","_updateRotation","collectDelta","prevRotation","_toEulerDelta","setInitialRotation","yawOrigin","sensorYaw","screenAngle","world","set","cos","multiply","prevQuat","currentQuat","_getDeltaYaw","_getDeltaPitch","prvQ","curQ","yawDeltaByYaw","_getRotationDelta","yawDeltaByRoll","_extractPitchFromQuat","prevQ","rotateKind","curQuaternion","prevPoint","curPoint","rotateDistance","dot","cross","rotateDirection","meshPoint2","meshPoint3","vecU","vecV","vecN","coefficientA","coefficientB","coefficientC","projectedPrevPoint","subtract","trigonometricRatio","acos","crossVec","thetaDirection","deltaRadian","baseV","GyroControl","_input","isAvailable","onDeviceMotionChange","listenDeviceMotion","res","rotationRate","timeout","race","available","requestSensorPermission","requestPermission","permissionState","catch","_updateYawPitch","input","yawDelta","pitchDelta","PanoControl","useGrabCursor","_useGrabCursor","_setCursor","disableContextMenu","_disableContextMenu","_blockContextMenu","_restoreContextMenu","_rotateControl","wheelScrollable","_zoomControl","ignoreZoomScale","_ignoreZoomScale","gyro","_gyroControl","_preventContextMenu","_onEnable","_onDisable","_onCameraAnimationEnd","_bindEvents","rotateControl","zoomControl","gyroControl","zoomScale","newCursor","style","cursor","Texture","flipY","wrapS","WebGLRenderingContext","CLAMP_TO_EDGE","wrapT","isVideo","isCube","Texture2D","source","TextureVideo","video","pause","removeAttribute","load","isPaused","paused","ended","readyState","hasAudio","audioTracks","webkitAudioDecodedByteCount","mozHasAudio","TextureCube","sources","TextureLoader","_loadChecker","ImReady","src","loadVideo","isArray","loadCubeImage","imgSrc","loadImage","images","_toImageArray","_load","image","naturalWidth","naturalHeight","videoConfig","config","autoplay","muted","volume","_toVideoElement","currentTime","play","videoWidth","videoHeight","content","onLoad","loader","reject","once","errorCount","check","srcs","imgEl","Image","crossOrigin","HTMLVideoElement","playsInline","setAttribute","forEach","_appendSourceElement","sourceCount","querySelectorAll","HTMLSourceElement","sourceEl","appendChild","FrameAnimator","maxDeltaTime","context","_context","_rafId","_rafTimer","_lastUpdateTime","callback","_time","frame","time","Date","now","requestAnimationFrame","stop","cancelAnimationFrame","changeContext","AutoResizer","useResizeObserver","_useResizeObserver","onResize","_skipFirstResize","isFirstResize","_onResize","_resizeObserver","ResizeObserver","bbox","getBoundingClientRect","resizeImmediate","resizeObserver","observe","disconnect","Autoplay","playing","_interrupted","delay","_delay","delayOnMouseLeave","_delayOnMouseLeave","speed","_speed","pauseOnHover","_pauseOnHover","canInterrupt","_canInterrupt","disableOnInterrupt","_disableOnInterrupt","viewer","options","_clearTimeout","_setUninterruptedAfterDelay","_onGyroEnable","_onMouseEnter","_hovering","_onMouseLeave","_control","_element","_interruptionTimer","enableAfterDelay","XRManager","ctx","exit","_onSessionEnd","_xrSession","_xrRefSpace","_ctx","_options","xr","navigator","isSessionSupported","enter","requiredFeatures","makeXRCompatible","session","requestSession","bindXRLayer","refSpace","requestReferenceSpace","_setSession","xrSession","canRender","pose","getViewerPose","getEyeParams","glLayer","renderState","baseLayer","views","viewport","getViewport","vMatrix","transform","inverse","matrix","pMatrix","Hotspot","HotspotRenderer","rootEl","renderer","_containerEl","_renderer","_hotspots","_zoom","refresh","container","hotspotEls","slice","_parseHotspot","render","hotspots","halfWidth","halfHeight","centerTransform","zoomTransform","hotspot","relPos","transformMat4","remove","screenPos","vec2","yawStr","dataset","pitchStr","positionStr","parseFloat","_yawPitchToVec3","pos","defaultPos","yawRad","pitchRad","VertexArrayObject","count","geometry","indicies","buffers","WebGLContext","_canvas","maxTextureSize","_maxTextureSize","isWebGL2","_isWebGL2","supportVAO","_extensions","vao","lost","_contextLost","debug","_debug","_onContextLost","_onContextRestore","loseContext","init","gl","_getContext","_gl","getParameter","MAX_TEXTURE_SIZE","getExtension","bindBuffer","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","forceLoseContext","extension","forceRestoreContext","restoreContext","clear","COLOR_BUFFER_BIT","drawingBufferWidth","drawingBufferHeight","createVAO","shaderProgram","nativeVAO","_createNativeVAO","_createBuffer","uv","_bindNativeVAO","_supplyGeometryData","_unbindBuffers","draw","drawElements","TRIANGLES","UNSIGNED_SHORT","releaseVAO","_deleteNativeVAO","_deleteBuffer","getUniformLocations","program","uniforms","uniformLocations","keys","locations","getUniformLocation","_getCommonUniformLocations","updateCommonUniforms","entity","mvMatrix","uniformMatrix4fv","uMVMatrix","uPMatrix","updateVRUniforms","eyeIndex","uEye","uniform1f","updateUniforms","uniform","needsUpdate","releaseShaderResources","deleteProgram","useProgram","createProgram","vertexShader","fragmentShader","vs","_compileShader","VERTEX_SHADER","fs","FRAGMENT_SHADER","attachShader","bindAttribLocation","linkProgram","getProgramParameter","LINK_STATUS","getShaderParameter","COMPILE_STATUS","getShaderInfoLog","getProgramInfoLog","deleteShader","createWebGLTexture","texData","texture","createTexture","bindTexture","TEXTURE_2D","texParameteri","TEXTURE_MIN_FILTER","TEXTURE_MAG_FILTER","TEXTURE_WRAP_S","TEXTURE_WRAP_T","gl2","texStorage2D","RGBA8","createWebGLCubeTexture","TEXTURE_CUBE_MAP","attributes","getContextAttributes","xrCompatible","xrLayer","XRWebGLLayer","updateRenderState","bindXRFrame","bindFramebuffer","FRAMEBUFFER","framebuffer","useDefaultFrameBuffer","createBuffer","buffer","deleteBuffer","createVertexArray","ext","createVertexArrayOES","bindVertexArray","bindVertexArrayOES","deleteVertexArray","deleteVertexArrayOES","_supplyIndiciesData","_supplyAttributeData","vertices","uvs","bufferData","data","STATIC_DRAW","attribute","attribLocation","getAttribLocation","vertexAttribPointer","itemSize","FLOAT","enableVertexAttribArray","shader","createShader","shaderSource","compileShader","webglIdentifiers","contextAttributes","preserveDrawingBuffer","antialias","onWebglContextCreationError","e","statusMessage","identifier","getContext","WebGLRenderer","_elementSize","pixelRatio","_pixelRatio","canvasSize","devicePixelRatio","clientWidth","clientHeight","projection","mesh","getMesh","renderVR","vr","eyeParams","eye","View360","_rootEl","_vr","_hotspot","plugins","_plugins","_projection","_initialized","initialized","_autoplay","autoInit","_autoInit","autoResize","_autoResize","canvasSelector","_canvasSelector","tabIndex","_tabIndex","_animator","updateCamera","renderFrame","autoPlayer","_emit","_renderFrameOnDemand","getTexture","_renderVRFrame","_delta","_autoResizer","_addEventHandlers","releaseAllResources","plugin","animator","_bindComponentEvents","_resizeComponents","_loadTexture","_applyProjection","hasAttribute","addPlugins","push","removePlugins","pluginIdx","splice","eventName","params","evtParams","target","prevProjection","applyTexture","updateControl","contentLoader","events","evtName","controlEventsToPropagate","VERSION","Object3D","fromRotationTranslationScale","LoadingSpinner","_startLoading","_container","_detachElements","parentElement","removeChild","_createElements","ring","RING","ControlBarItem","CONTROL_BAR_DEFAULT_CLASS","CONTROLS_ROOT","CONTROLS_BG","CONTROLS_MAIN","CONTROLS_TOP","CONTROLS_BOTTOM","CONTROLS_MID","CONTROLS_LEFT","CONTROLS_RIGHT","CONTROLS_FLOAT_LEFT","CONTROLS_FLOAT_RIGHT","CONTROLS_BUTTON","PROGRESS_ROOT","VOLUME_ROOT","RANGE_ROOT","RANGE_TRACK","RANGE_THUMB","RANGE_FILLER","PLAY_BUTTON","PAUSE_BUTTON","UNMUTED_BUTTON","MUTED_BUTTON","FULLSCREEN_BUTTON","FULLSCREEN_EXIT_BUTTON","VR_BUTTON","GYRO_ENABLED","GYRO_DISABLED","VIDEO_TIME_DISPLAY","PIEVIEW_ROOT","FIXED","UNAVAILABLE","HIDDEN","CONTROL_BAR_ITEM_POSITION","TOP_LEFT","TOP_RIGHT","MAIN_TOP","MAIN_BOTTOM","MAIN_LEFT","MAIN_RIGHT","RangeControl","_onHold","_bbox","elX","scrollX","pageXOffset","clamepdX","thumbEl","_fixedClass","clampedX","_onRelease","track","thumb","filler","draggable","trackEl","fillerEl","left","right","bottom","top","updateStyle","clampedProgress","ProgressBar","_rangeControl","_onTimeUpdate","_video","_currentTime","_onDurationChange","controlBar","_controlBar","dispatchEvent","CustomEvent","detail","_wasPaused","_playPromise","_onControl","rangeControl","unavailableClass","PlayButton","_onClick","_paused","_onPlay","title","_onPause","VolumeControl","_updateDisplay","disabled","_onVolumeChange","_buttonEl","containerEl","buttonEl","FullscreenButton","_targetEl","_exitFullscreen","_requestFullscreen","_onFullscreenChange","_fullscreenAvailable","_addFullscreenHandlers","_removeFullscreenHandlers","some","request","call","VideoTime","_onCustomTimeChange","timeMinute","floor","timeSeconds","timeSecondsFormatted","durationMinute","durationSeconds","durationSecondsFormatted","innerText","PieView","resetCamera","_viewer","_updatePie","piePath","_piePathEl","rangeCircle","_rangeCircleEl","halfFov","pieRadius","pieDeg","pieOffset","isFinite","radius","rangeDiff","_createPieElements","rootClass","pieSVG","createElementNS","VRButton","GyroButton","_updateStyle","enableButton","AutoHide","hidden","contains","_hiddenClass","initialDelay","idleDelay","activationDelay","_isCursorInside","show","_hideAfterDelay","_isFullscreen","showTemporaliy","_isGrabbing","pointerType","_onVideoPlay","_onVideoPause","_initialDelay","_idleDelay","_timer","hide","_clearHideTimer","VideoControl","videoEl","keyPressed","_changeVideoTime","_changeVideoVolume","spacePressed","_toggleVideo","forward","increase","ControlBar","backgroundEl","_bgEl","items","_items","customItems","_customItems","autoHide","showBackground","clickToPlay","keyboardControls","progressBar","playButton","volumeButton","fullscreenButton","videoTime","pieView","vrButton","gyroButton","_onStaticClick","autoHider","_autoHider","_onNewSrcLoad","_updateBackground","_updateAutoHide","_updateKeyboardHandler","category","item","_createPositionWrappers","POSITION","_videoControl","panoRoot","controlsRoot","defaultItems","_createDefaultItems","_addItem","_clearItemElements","wrapper","_wrapperEl","nextSiblingIndex","sibling","nextSibling","insertBefore","floatLeftEl","floatRightEl","topWrapper","bottomWrapper","midWrapper","leftControlsWrapper","rightControlsWrapper","wrappers","firstChild","background","hiddenClass","_b","videoControl","Projection","_mesh","uTexture","Uniform","UniformTextureCube","cubemapOrder","_webglTexture","_cubemapOrder","deleteTexture","pixelStorei","UNPACK_FLIP_Y_WEBGL","uniform1i","activeTexture","TEXTURE0","texSubImage2D","TEXTURE_CUBE_MAP_POSITIVE_X","RGBA","UNSIGNED_BYTE","texImage2D","CubeTexturePainter","_size","_renderingOrder","_calcRenderingSize","surfaceIdx","row","_row","column","_column","renderingFace","drawImage","UniformCanvasCube","_painter","TriangleMesh","ShaderProgram","VertexData","Geometry","Float32Array","Uint16Array","CubeGeometry","rotateUV","oneThird","coords","r","c","coord","degree","ZERO","newOrder","CW_90","CCW_90","newCoords","uvIdx","acc","concat","CubemapProjection","cubemapFlipX","_cubemapFlipX","UniformTexture2D","CubestripProjection","CylinderGeometry","maxTheta","radialSegments","heightSegments","invRadialSegments","angleConst","yIdx","lngIdx","u","v","CylindricalProjection","partial","_partial","cylinderHeight","cylinderTheta","restrictedYaw","restrictedPitch","minZoom","EquiangularProjection","SphereGeometry","widthSegments","ANGLE_CORRECTION_FOR_CENTER_ALIGN","latIdx","sinTheta","cosTheta","phi","sinPhi","cosPhi","EquirectProjection","UniformFloat","PlaneGeometry","LittlePlanetProjection","REPEAT","uYaw","uPitch","uZoom","UniformVector4Array","uniform4fv","vector","StereoEquiProjection","_mode","mode","leftEye","rightEye","MODE","LEFT_RIGHT","uTexScaleOffset","TOP_BOTTOM","withMethods","attr","proto","getOwnPropertyNames","charAt","descriptor","getOwnPropertyDescriptor","value","defineProperty","args","getterDescriptor","get","getValidProps","propsObj","props","propName","VIEW360_METHODS"],"mappings":"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"} \ No newline at end of file diff --git a/demo/release/latest/dist/view360.js b/demo/release/latest/dist/view360.js new file mode 100644 index 000000000..eef9ec416 --- /dev/null +++ b/demo/release/latest/dist/view360.js @@ -0,0 +1,7825 @@ +/* +Copyright (c) 2023-present NAVER Corp. +name: @egjs/view360 +license: MIT +author: NAVER Corp. +repository: https://github.com/naver/egjs-view360 +version: 4.0.0-beta.4 +*/ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@egjs/component'), require('gl-matrix'), require('@egjs/imready')) : + typeof define === 'function' && define.amd ? define(['@egjs/component', 'gl-matrix', '@egjs/imready'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.View360 = factory(global.Component, global.glMatrix, global.eg.ImReady)); +})(this, (function (Component, glMatrix, ImReady) { 'use strict'; + + function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; } + + var Component__default = /*#__PURE__*/_interopDefault(Component); + var ImReady__default = /*#__PURE__*/_interopDefault(ImReady); + + /****************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function (resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Error thrown by {@link View360} + * @ko {@link View360}이 발생시킨 에러 + * @since 4.0.0 + */ + class View360Error extends Error { + /** + * Create new instance of View360Error + * @ko View360Error의 인스턴스를 생성합니다. + * @param message - Error message {@ko 에러 메시지} + * @param code - Error code {@ko 에러 코드} + */ + constructor(message, code) { + super(message); + Object.setPrototypeOf(this, View360Error.prototype); + this.name = "View360Error"; + this.code = code; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Error codes of {@link View360Error} + * @ko {@link View360Error}가 가질 수 있는 에러 코드 값들 + * @since 4.0.0 + */ + const ERROR_CODES = { + /** + * The given value's type is not expected + * @ko 주어진 값의 타입이 잘못되었을 경우 + * @since 4.0.0 + */ + WRONG_TYPE: 0, + /** + * The given value is not a supported option + * @ko 잘못된 옵션을 받았을 경우 + * @since 4.0.0 + */ + WRONG_OPTION: 1, + /** + * The element with given CSS selector does not exist + * @ko 주어진 CSS 셀렉터로 엘리먼트를 찾지 못했을 경우 + * @since 4.0.0 + */ + ELEMENT_NOT_FOUND: 2, + /** + * Couldn't find canvas element inside the given container element. + * @ko 컨테이너 엘리먼트 내부에서 캔버스 엘리먼트를 찾지 못했을 경우 + * @since 4.0.0 + */ + CANVAS_NOT_FOUND: 3, + /** + * The browser does not support WebGL + * @ko 브라우저가 WebGL을 지원하지 않는 경우 + * @since 4.0.0 + */ + WEBGL_NOT_SUPPORTED: 4, + /** + * Failed creating canvas 2D context + * @ko 캔버스 2D 컨텍스트를 생성하지 못한 경우 + * @since 4.0.0 + */ + FAILED_CREATE_CONTEXT_2D: 5, + /** + * `init()` is called before setting {@link View360Options#projection} + * @ko {@link View360Options#projection}을 설정하기 전에 `init()`이 호출된 경우 + * @since 4.0.0 + */ + PROVIDE_PROJECTION_FIRST: 6, + /** + * Failed linking WebGL program. Only can be thrown when {@link View360Options#debug} is `true`. + * @ko WebGL 프로그램 링크에 실패한 경우. {@link View360Options#debug}를 `true`로 설정한 경우에만 발생할 수 있습니다. + * @since 4.0.0 + */ + FAILED_LINKING_PROGRAM: 7, + /** + * Arguments are not sufficient for the given property. + * @ko 프로퍼티에 값이 충분히 주어지지 않았을 때 + * @since 4.0.0 + */ + INSUFFICIENT_ARGS: 8 + }; + const MESSAGES = { + WRONG_TYPE: (val, types) => `${typeof val} is not a ${types.map(type => `"${type}"`).join(" or ")}.`, + WRONG_OPTION: (val, optionName) => `Bad option: given "${val}" for option "${optionName}".`, + ELEMENT_NOT_FOUND: query => `Element with selector "${query}" not found.`, + CANVAS_NOT_FOUND: "The canvas element was not found inside the given root element.", + WEBGL_NOT_SUPPORTED: "WebGL is not supported on this browser.", + FAILED_CREATE_CONTEXT_2D: "Failed to create canvas 2D context", + PROVIDE_PROJECTION_FIRST: "\"projection\" should be provided before initialization.", + FAILED_LINKING_PROGRAM: (msg, shaderLog) => `Failed linking WebGL program - "${msg}\nShader compile Log: ${shaderLog}`, + INSUFFICIENT_ARGS: (val, name) => `Insufficient arguments: given "${val}" for "${name}".` + }; + var ERROR = { + CODES: ERROR_CODES, + MESSAGES + }; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + const EVENTS$1 = { + MOUSE_DOWN: "mousedown", + MOUSE_MOVE: "mousemove", + MOUSE_UP: "mouseup", + TOUCH_START: "touchstart", + TOUCH_MOVE: "touchmove", + TOUCH_END: "touchend", + WHEEL: "wheel", + RESIZE: "resize", + CONTEXT_MENU: "contextmenu", + MOUSE_ENTER: "mouseenter", + MOUSE_LEAVE: "mouseleave", + POINTER_DOWN: "pointerdown", + POINTER_MOVE: "pointermove", + POINTER_UP: "pointerup", + POINTER_CANCEL: "pointercancel", + POINTER_ENTER: "pointerenter", + POINTER_LEAVE: "pointerleave", + KEY_DOWN: "keydown", + KEY_UP: "keyup", + LOAD: "load", + ERROR: "error", + CLICK: "click", + DOUBLE_CLICK: "dblclick", + CONTEXT_CREATE_ERROR: "webglcontextcreationerror", + CONTEXT_LOST: "webglcontextlost", + CONTEXT_RESTORED: "webglcontextrestored", + DEVICE_ORIENTATION: "deviceorientation", + DEVICE_MOTION: "devicemotion", + ORIENTATION_CHANGE: "orientationchange", + VIDEO_PLAY: "play", + VIDEO_PAUSE: "pause", + VIDEO_LOADED_DATA: "loadeddata", + VIDEO_VOLUME_CHANGE: "volumechange", + VIDEO_TIME_UPDATE: "timeupdate", + VIDEO_DURATION_CHANGE: "durationchange", + VIDEO_CAN_PLAYTHROUGH: "canplaythrough", + TRANSITION_END: "transitionend", + XR_END: "end" + }; + const EL_DIV = "div"; + const EL_BUTTON = "button"; + // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button + var MOUSE_BUTTON; + (function (MOUSE_BUTTON) { + MOUSE_BUTTON[MOUSE_BUTTON["LEFT"] = 0] = "LEFT"; + MOUSE_BUTTON[MOUSE_BUTTON["MIDDLE"] = 1] = "MIDDLE"; + MOUSE_BUTTON[MOUSE_BUTTON["RIGHT"] = 2] = "RIGHT"; + })(MOUSE_BUTTON || (MOUSE_BUTTON = {})); + const CURSOR = { + GRAB: "grab", + GRABBING: "grabbing", + NONE: "" + }; + const KEY_DIRECTION = ["LEFT", "UP", "RIGHT", "DOWN"]; + var DIRECTION_KEY_CODE; + (function (DIRECTION_KEY_CODE) { + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["LEFT"] = 37] = "LEFT"; + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["UP"] = 38] = "UP"; + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["RIGHT"] = 39] = "RIGHT"; + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["DOWN"] = 40] = "DOWN"; + })(DIRECTION_KEY_CODE || (DIRECTION_KEY_CODE = {})); + const SPACE_KEY_CODE = 32; + const DIRECTION_KEY_NAME = { + LEFT: "ArrowLeft", + UP: "ArrowUp", + RIGHT: "ArrowRight", + DOWN: "ArrowDown" + }; + const SPACE_KEY_NAME = " "; + const FULLSCREEN_REQUEST = ["requestFullscreen", "webkitRequestFullscreen", "webkitRequestFullScreen", "webkitCancelFullScreen", "mozRequestFullScreen", "msRequestFullscreen"]; + const FULLSCREEN_ELEMENT = ["fullscreenElement", "webkitFullscreenElement", "webkitCurrentFullScreenElement", "mozFullScreenElement", "msFullscreenElement"]; + const FULLSCREEN_EXIT = ["exitFullscreen", "webkitExitFullscreen", "webkitCancelFullScreen", "mozCancelFullScreen", "msExitFullscreen"]; + const FULLSCREEN_CHANGE = ["fullscreenchange", "webkitfullscreenchange", "mozfullscreenchange", "MSFullscreenChange"]; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Default class names + * @ko 기본 클래스 이름들 + * @since 4.0.0 + */ + const DEFAULT_CLASS = { + CONTAINER: "view360-container", + CANVAS: "view360-canvas", + CTX_LOST: "view360-ctx-lost", + IN_VR: "view360-vr-presenting", + HOTSPOT_CONTAINER: "view360-hotspots", + HOTSPOT: "view360-hotspot", + HOTSPOT_VISIBLE: "view360-hotspot-visible", + HOTSPOT_FLIP_X: "view360-hotspot-flip-x", + HOTSPOT_FLIP_Y: "view360-hotspot-flip-y" + }; + /** + * Event names + * @ko 이벤트 이름들 + * @since 4.0.0 + * @example + * ```ts + * import View360, { EVENTS } from "@egjs/view360"; + * + * const viewer = new View360("#el_id"); + * + * viewer.on(EVENTS.READY, evt => { + * console.log("View360 is ready!"); + * }); + * ``` + */ + const EVENTS = { + READY: "ready", + LOAD_START: "loadStart", + LOAD: "load", + PROJECTION_CHANGE: "projectionChange", + RESIZE: "resize", + BEFORE_RENDER: "beforeRender", + RENDER: "render", + INPUT_START: "inputStart", + INPUT_END: "inputEnd", + VIEW_CHANGE: "viewChange", + STATIC_CLICK: "staticClick", + VR_START: "vrStart", + VR_END: "vrEnd" + }; + /** + * Collection of predefined easing functions + * @ko 미리 정의된 easing 함수들 + */ + const EASING = { + LINEAR: x => x, + SINE_WAVE: x => Math.sin(x * Math.PI * 2), + EASE_OUT_CUBIC: x => 1 - Math.pow(1 - x, 3), + EASE_OUT_BOUNCE: x => { + const n1 = 7.5625; + const d1 = 2.75; + if (x < 1 / d1) { + return n1 * x * x; + } else if (x < 2 / d1) { + return n1 * (x -= 1.5 / d1) * x + 0.75; + } else if (x < 2.5 / d1) { + return n1 * (x -= 2.25 / d1) * x + 0.9375; + } else { + return n1 * (x -= 2.625 / d1) * x + 0.984375; + } + } + }; + + var _a; + const CAMERA_EVENTS = { + CHANGE: "change", + ANIMATION_END: "animationEnd" + }; + const CONTROL_EVENTS = { + INPUT_START: "inputStart", + CHANGE: "change", + INPUT_END: "inputEnd", + ENABLE: "enable", + DISABLE: "disable", + STATIC_CLICK: "staticClick" + }; + const DEG_TO_RAD = Math.PI / 180; + const RAD_TO_DEG = 180 / Math.PI; + const DEFAULT_EASING = EASING.EASE_OUT_CUBIC; + const DEFAULT_ANIMATION_DURATION = 300; + const INFINITE_RANGE = { + min: -Infinity, + max: Infinity + }; + const DEFAULT_PITCH_RANGE = { + min: -90, + max: 90 + }; + const DEFAULT_ZOOM_RANGE = { + min: 0.6, + max: 10 + }; + var ROTATE; + (function (ROTATE) { + ROTATE[ROTATE["ZERO"] = 0] = "ZERO"; + ROTATE[ROTATE["CW_90"] = 1] = "CW_90"; + ROTATE[ROTATE["CCW_90"] = 2] = "CCW_90"; + ROTATE[ROTATE["CW_180"] = 3] = "CW_180"; + })(ROTATE || (ROTATE = {})); + // Custom event name for video time change + const VIDEO_TIME_CHANGE_EVENT = "view360videotimechange"; + const SVG_NAMESPACE = "http://www.w3.org/2000/svg"; + const SESSION_VR = "immersive-vr"; + const XR_REFERENCE_SPACE = "local"; + const EPSILON = (_a = Number.EPSILON) !== null && _a !== void 0 ? _a : 2.220446049250313e-16; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + const isString = val => typeof val === "string"; + const isElement = val => !!val && val.nodeType === Node.ELEMENT_NODE; + const createElement = (className, tag = EL_DIV) => { + const el = document.createElement(tag); + el.classList.add(className); + return el; + }; + const getNullableElement = (el, parent) => { + let targetEl = null; + if (isString(el)) { + const parentEl = parent ? parent : document; + const queryResult = parentEl.querySelector(el); + if (!queryResult) { + return null; + } + targetEl = queryResult; + } else if (isElement(el)) { + targetEl = el; + } + return targetEl; + }; + const getElement = (el, parent) => { + const targetEl = getNullableElement(el, parent); + if (!targetEl) { + if (isString(el)) { + throw new View360Error(ERROR.MESSAGES.ELEMENT_NOT_FOUND(el), ERROR.CODES.ELEMENT_NOT_FOUND); + } else { + throw new View360Error(ERROR.MESSAGES.WRONG_TYPE(el, ["HTMLElement", "string"]), ERROR.CODES.WRONG_TYPE); + } + } + return targetEl; + }; + const findCanvas = (root, selector) => { + const canvas = root.querySelector(selector); + if (!canvas) { + throw new View360Error(ERROR.MESSAGES.CANVAS_NOT_FOUND, ERROR.CODES.CANVAS_NOT_FOUND); + } + return canvas; + }; + const range = end => { + if (!end || end <= 0) { + return []; + } + return Array.apply(0, Array(end)).map((undef, idx) => idx); + }; + const clamp = (x, min, max) => Math.max(Math.min(x, max), min); + // Linear interpolation between a and b + const lerp = (a, b, t) => { + return a * (1 - t) + b * t; + }; + const circulate = (val, min, max) => { + const size = Math.abs(max - min); + if (val < min) { + const offset = (min - val) % size; + val = max - offset; + } else if (val > max) { + const offset = (val - max) % size; + val = min + offset; + } + return val; + }; + // eslint-disable-next-line @typescript-eslint/ban-types + const merge = (target, ...srcs) => { + srcs.forEach(source => { + Object.keys(source).forEach(key => { + const value = source[key]; + if (Array.isArray(target[key]) && Array.isArray(value)) { + target[key] = [...target[key], ...value]; + } else { + target[key] = value; + } + }); + }); + return target; + }; + const findIndex = (array, checker) => { + for (let idx = 0; idx < array.length; idx++) { + if (checker(array[idx])) { + return idx; + } + } + return -1; + }; + const getObjectOption = val => typeof val === "object" ? val : {}; + const toVerticalFov = (fovRadian, aspect) => { + return Math.atan(Math.tan(fovRadian * 0.5) / aspect) * 2; + }; + const reorderCube = (arr, order, defaultOrder = "RLUDFB") => { + return defaultOrder.split("").map(face => order.indexOf(face)).map(index => arr[index]); + }; + const isFullscreen = () => { + if (!document) return false; + for (const key of FULLSCREEN_ELEMENT) { + if (document[key]) return true; + } + return false; + }; + const sensorCanBeEnabledIOS = () => { + return !!DeviceMotionEvent && "requestPermission" in DeviceMotionEvent && window.isSecureContext; + }; + const hfovToZoom = (baseFov, fov) => { + const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5); + const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5); + return renderingWidth / zoomedWidth; + }; + const eulerToQuat = (out, yaw, pitch, roll) => { + glMatrix.quat.identity(out); + const pitchThreshold = 0.01; + const pitchClamped = clamp(pitch, -90 + pitchThreshold, 90 - pitchThreshold); + glMatrix.quat.rotateY(out, out, yaw * DEG_TO_RAD); + glMatrix.quat.rotateX(out, out, pitchClamped * DEG_TO_RAD); + glMatrix.quat.rotateZ(out, out, roll * DEG_TO_RAD); + return out; + }; + /** + * Extract euler angles from the quaternion, except roll(z-axis rotation) + * @hidden + */ + const quatToEuler = quaternion => { + const x = quaternion[0]; + const y = quaternion[1]; + const z = quaternion[2]; + const w = quaternion[3]; + const x2 = x * x; + const y2 = y * y; + const z2 = z * z; + const w2 = w * w; + const unit = x2 + y2 + z2 + w2; + const test = x * w - y * z; + let pitch, yaw; + if (test > 0.499995 * unit) { + // singularity at the north pole + pitch = Math.PI / 2; + yaw = 2 * Math.atan2(y, x); + } else if (test < -0.499995 * unit) { + // singularity at the south pole + pitch = -Math.PI / 2; + yaw = -2 * Math.atan2(y, x); + } else { + const view = glMatrix.vec3.fromValues(0, 0, 1); + const up = glMatrix.vec3.fromValues(0, 1, 0); + glMatrix.vec3.transformQuat(view, view, quaternion); + glMatrix.vec3.transformQuat(up, up, quaternion); + const viewXZ = Math.sqrt(view[0] * view[0] + view[2] * view[2]); + pitch = Math.atan2(-view[1], viewXZ); + yaw = Math.atan2(view[0], view[2]); + } + return { + pitch: clamp(pitch * RAD_TO_DEG, -90, 90), + yaw: circulate(yaw * RAD_TO_DEG, 0, 360) + }; + }; + + /* + * Copyright (c) 2020 NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Interpolator between two values with duration + * @ko 특정 시간동안 두 값을 보간해주는 보간기 + * @since 4.0.0 + */ + class Motion { + /** + * Current interpolated value + * @ko 현재 보간된 값 + * @since 4.0.0 + */ + get val() { + return this._val; + } + /** + * Start(from) value of interpolation + * @ko 보간 시작 값 + * @since 4.0.0 + */ + get start() { + return this._start; + } + /** + * End(to) value of interpolation + * @ko 보간 끝 값 + * @since 4.0.0 + */ + get end() { + return this._end; + } + /** + * Interpolation progress value (0 ~ 1) + * @ko 현재 보간 진행정도 (0 ~ 1) + * @since 4.0.0 + */ + get progress() { + return this._progress; + } + /** + * Whether the interpolation is in active state. + * @ko 보간 진행중인지 여부. `true`일 경우 보간이 진행중입니다. + * @since 4.0.0 + */ + get activated() { + return this._activated; + } + /** + * Duration of the interpolation + * @ko 보간할 시간 + * @since 4.0.0 + */ + get duration() { + return this._duration; + } + set duration(val) { + this._duration = val; + } + /** + * Whether to loop interpolation on finish + * @ko 보간이 끝난 이후에 다시 시작할지 여부 + * @since 4.0.0 + */ + get loop() { + return this._loop; + } + set loop(val) { + this._loop = val; + } + /** + * Range of the interpolation + * @ko 보간 범위 + * @since 4.0.0 + */ + get range() { + return this._range; + } + /** + * Easing function of the interpolation + * @ko 보간에 사용되는 easing function + * @since 4.0.0 + */ + get easing() { + return this._easing; + } + set easing(val) { + this._easing = val; + } + /** + * Create new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options Options {@ko 옵션들} + * @param options.duration Duration of the interpolation {@ko 보간할 시간} + * @param options.loop Whether to loop interpolation on finish {@ko 보간이 끝난 이후에 다시 시작할지 여부} + * @param options.range Range of the interpolation {@ko 보간 범위} + * @param options.loop Easing function of the interpolation {@ko 보간에 사용되는 easing function} + */ + constructor({ + duration = DEFAULT_ANIMATION_DURATION, + loop = false, + range = { + min: 0, + max: 1 + }, + easing = DEFAULT_EASING + } = {}) { + this._duration = duration; + this._loop = loop; + this._range = range; + this._easing = easing; + this._activated = false; + this.reset(0); + } + /** + * Update motion and progress it by given deltaTime + * @ko 주어진 deltaTime만큼 보간을 진행합니다. + * @param deltaTime - number of milisec to update motion {@ko 보간을 진행할 시간, 밀리초 단위} + * @returns Difference(delta) of the value from the last update. {@ko 지난 업데이트 이후의 값 변화량} + * @since 4.0.0 + */ + update(deltaTime) { + if (!this._activated) { + this._val = this._end; + return 0; + } + const start = this._start; + const end = this._end; + const duration = this._duration; + const prev = this._val; + const loop = this._loop; + const nextProgress = this._progress + deltaTime / duration; + this._progress = loop ? circulate(nextProgress, 0, 1) : clamp(nextProgress, 0, 1); + const easedProgress = this._easing(this._progress); + this._val = lerp(start, end, easedProgress); + if (!loop && this._progress >= 1) { + this._activated = false; + } + return this._val - prev; + } + /** + * Set `start`, `end` to the given value and set `progress` to 0. + * @ko 주어진 값으로 시작 지점, 끝 지점을 초기화하고 progress를 0으로 세팅합니다. + * @param defaultVal - Value to reset {@ko 초기화할 값} + * @since 4.0.0 + */ + reset(defaultVal) { + const range = this._range; + const val = clamp(defaultVal, range.min, range.max); + this._start = val; + this._end = val; + this._val = val; + this._progress = 0; + this._activated = false; + } + /** + * Add delta to start & end and current value. + * @ko 현재 & 끝 및 현재 값에 주어진 값을 더합니다. + * @param delta - Delta value to add {@ko 추가할 값} + */ + add(delta) { + const range = this._range; + this._start = clamp(this._start + delta, range.min, range.max); + this._end = clamp(this._end + delta, range.min, range.max); + this._val = clamp(this._val + delta, range.min, range.max); + } + /** + * Set current value to start, and end to current value + delta, then reset progress to 0. + * @ko 현재 값을 시작 지점으로, 그에서 delta만큼 추가된 값을 끝점으로 하고 progress를 0으로 갱신합니다. + * @param delta - Delta value to add {@ko 추가할 값} + */ + setNewEndByDelta(delta) { + const range = this._range; + this._start = this._val; + this._end = clamp(this._end + delta, range.min, range.max); + this._progress = 0; + this._activated = true; + } + /** + * Set new range of the interpolation. + * @ko 보간의 범위를 변경합니다. + * @param min - New minimum range {@ko 변경할 범위의 최소값} + * @param max - New maximum range {@ko 변경할 범위의 최대값} + */ + setRange(min, max) { + this._start = clamp(this._start, min, max); + this._end = clamp(this._end, min, max); + this._range = { + min, + max + }; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Animation of the {@link Camera} + * @internal + * @ko {@link Camera}의 애니메이션 + * @since 4.0.0 + */ + class CameraAnimation { + /** + * Duration of the animation + * @ko 애니메이션 재생시간 + * @since 4.0.0 + */ + get duration() { + return this._motion.duration; + } + set duration(val) { + this._motion.duration = val; + } + /** + * Easing function of the animation + * @ko 애니메이션의 easing function + * @since 4.0.0 + */ + get easing() { + return this._motion.easing; + } + set easing(val) { + this._motion.easing = val; + } + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param camera - Camera to animate {@ko 애니메이션을 적용할 카메라} + * @param from - Start pose {@ko 애니메이션이 시작 시점의 카메라의 회전 및 줌} + * @param to - End pose {@ko 애니메이션이 끝났을 때 카메라의 회전 및 줌} + * @param options - Options {@ko 옵션들} + * @param options.duration - Animation duration {@ko 애니메이션 재생 시간} + * @param options.easing - Animation easing function {@ko 애니메이션 easing function} + */ + constructor(camera, from, to, { + duration = DEFAULT_ANIMATION_DURATION, + easing = DEFAULT_EASING + } = {}) { + this._camera = camera; + this._motion = new Motion({ + duration, + easing, + range: { + min: 0, + max: 1 + } + }); + this._from = from; + this._to = to; + this._finishPromise = new Promise(resolve => { + this._finish = resolve; + }); + // Enable motion + this._motion.setNewEndByDelta(1); + } + /** + * Return a promise that resolved on animation end. + * @ko 애니메이션 재생이 끝났을 때 resolve되는 Promise를 반환합니다. + * @since 4.0.0 + */ + getFinishPromise() { + return this._finishPromise; + } + /** + * Update animation by given deltaTime. + * @ko 주어진 시간만큼 애니메이션을 업데이트합니다. + * @param deltaTime Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위} + * @since 4.0.0 + */ + update(deltaTime) { + const camera = this._camera; + const from = this._from; + const to = this._to; + const motion = this._motion; + motion.update(deltaTime); + // Progress that easing is applied + const progress = motion.val; + const rotation = glMatrix.quat.create(); + const zoom = lerp(from.zoom, to.zoom, progress); + glMatrix.quat.slerp(rotation, from.rotation, to.rotation, progress); + camera.rotate(rotation, zoom); + if (progress >= 1) { + this._finish(); + } + } + } + + /** + * Camera for View360 + * @ko View360용 카메라 구현체 + * @version 4.0.0 + */ + class Camera extends Component__default["default"] { + /** + * Camera's width / height ratio + * @ko 카메라의 가로 / 세로 비율 + * @readonly + */ + get aspect() { + return this._aspect; + } + /** + * Whether the camera's rotation changed from the last frame. + * @ko 마지막 프레임 이후로 카메라의 회전값이 변경되었는지 나타내는 플래그. + * @readonly + */ + get changed() { + return this._changed; + } + /** + * @copy View360#yawRange + */ + get yawRange() { + return this._initialYawRange; + } + set yawRange(val) { + this._initialYawRange = val; + } + /** + * @copy View360#pitchRange + */ + get pitchRange() { + return this._initialPitchRange; + } + set pitchRange(val) { + this._initialPitchRange = val; + } + /** + * @copy View360#zoomRange + */ + get zoomRange() { + return this._initialZoomRange; + } + set zoomRange(val) { + this._initialZoomRange = val; + } + /** + * Create new instance of Camera + * @param options - Camera options {@ko 카메라 옵션들} + */ + constructor({ + initialYaw, + initialPitch, + initialZoom, + yawRange, + pitchRange, + zoomRange, + fov + }) { + super(); + this.yaw = initialYaw; + this.pitch = initialPitch; + this.zoom = initialZoom; + this.rollOffset = 0; + this.initialYaw = initialYaw; + this.initialPitch = initialPitch; + this.initialZoom = initialZoom; + this.position = glMatrix.vec3.create(); + this.animation = null; + this._up = glMatrix.vec3.fromValues(0, 1, 0); + this._aspect = 1; + this._initialYawRange = yawRange; + this._initialPitchRange = pitchRange; + this._initialZoomRange = zoomRange; + this._yawRange = yawRange; + this._pitchRange = pitchRange; + this._zoomRange = zoomRange; + this.quaternion = glMatrix.quat.create(); + this._updateQuaternion(); + this.viewMatrix = glMatrix.mat4.create(); + this.projectionMatrix = glMatrix.mat4.create(); + this.fov = fov; + this._maxRenderHeight = -1; + } + /** + * Destroy instance and detach all event listeners + * @ko 인스턴스를 삭제하고 모든 이벤트 리스너를 삭제합니다. + * @since 4.0.0 + */ + destroy() { + this.off(); + } + /** + * Refresh internal size value. + * @ko 내부 크기값을 갱신합니다. + * @param width - New width {@ko 변경된 너비값} + * @param height - New height {@ko 변경된 높이값} + * @since 4.0.0 + */ + resize(width, height) { + const prevAspect = this._aspect; + this._aspect = width / height; + if (this._aspect !== prevAspect) { + this.updateMatrix(); + } + } + /** + * Change camera's rotation with euler values. + * @ko 카메라 회전을 오일러 각 방향으로 변경합니다. + * @param rotation - Rotation values {@ko 회전 값} + * @param rotation.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값} + * @param rotation.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값} + * @param rotation.zoom - zoom value to apply {@ko 적용할 카메라 줌 값} + * @since 4.0.0 + */ + lookAt({ + yaw = this.yaw, + pitch = this.pitch, + zoom = this.zoom + }) { + const prevQuaternion = glMatrix.quat.clone(this.quaternion); + const prevZoom = this.zoom; + this.yaw = circulate(yaw, 0, 360); + this.pitch = clamp(pitch, -90, 90); + this.zoom = zoom; + this._updateQuaternion(); + const zoomDiff = Math.abs(zoom - prevZoom); + if (!glMatrix.quat.equals(this.quaternion, prevQuaternion) || zoomDiff >= EPSILON * 10 // ignore small changes + ) { + this.updateMatrix(); + } + } + /** + * Change camera's rotation with quaternion. + * @ko 카메라 회전을 Quaternion을 이용해서 변경합니다. + * @param rotation - Quaternion to apply {@ko 적용할 Quaternion} + * @param zoom - zoom value to apply {@ko 적용할 카메라 줌 값} + * @since 4.0.0 + */ + rotate(rotation, zoom = this.zoom) { + const normalized = glMatrix.quat.normalize(glMatrix.quat.create(), rotation); + const isSameRotation = glMatrix.quat.equals(this.quaternion, normalized); + glMatrix.quat.copy(this.quaternion, normalized); + const prevZoom = this.zoom; + const { + yaw, + pitch + } = quatToEuler(normalized); + this.yaw = yaw; + this.pitch = pitch; + this.zoom = zoom; + const zoomDiff = Math.abs(zoom - prevZoom); + if (!isSameRotation || zoomDiff >= EPSILON * 10) { + this.updateMatrix(); + } + } + /** + * Change camera's rotation to given euler values by the given duration. + * @ko 카메라를 주어진 방향으로 주어진 시간동안 서서히 이동시킵니다. + * @param options - Animation parameters {@ko 애니메이션 패러미터} + * @param options.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값} + * @param options.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값} + * @param options.zoom - zoom value to apply {@ko 적용할 카메라 줌 값} + * @param options.duration - Duration of the animation {@ko 애니메이션 시간} + * @param options.easing - Easing function for the animation {@ko 애니메이션에 적용할 easing function} + */ + animateTo({ + yaw = this.yaw, + pitch = this.pitch, + zoom = this.zoom, + duration = 0, + easing = DEFAULT_EASING + } = {}) { + return __awaiter(this, void 0, void 0, function* () { + if (this.yaw === yaw && this.pitch === pitch && this.zoom === zoom) return; + const from = { + rotation: glMatrix.quat.clone(this.quaternion), + zoom: this.zoom + }; + const to = { + rotation: eulerToQuat(glMatrix.quat.create(), yaw, pitch, this.rollOffset), + zoom + }; + const animation = new CameraAnimation(this, from, to, { + duration, + easing + }); + const finishPromise = animation.getFinishPromise(); + this.animation = animation; + finishPromise.then(() => { + this.animation = null; + this.trigger(CAMERA_EVENTS.ANIMATION_END, { + animation + }); + }); + return finishPromise; + }); + } + /** + * @hidden + */ + restrictYawRange(min, max) { + this._yawRange = { + min, + max + }; + } + /** + * @hidden + */ + restrictPitchRange(min, max) { + this._pitchRange = { + min, + max + }; + } + /** + * @hidden + */ + restrictZoomRange(min, max) { + this._zoomRange = { + min, + max + }; + } + /** + * @hidden + */ + restrictRenderHeight(height) { + this._maxRenderHeight = height; + } + /** + * @hidden + */ + resetRange() { + this._yawRange = this._initialYawRange; + this._pitchRange = this._initialPitchRange; + this._zoomRange = this._initialZoomRange; + this._maxRenderHeight = -1; + } + /** + * Get actual yaw range by the given zoom value. + * @ko 주어진 zoom 값에 대한 실제 yaw 범위값을 반환합니다. + * @since 4.0.0 + */ + getYawRange(zoom) { + const yawLimit = this._yawRange; + const maxRenderHeight = this._maxRenderHeight; + if (!yawLimit) return INFINITE_RANGE; + const halfHFov = this.getHorizontalFov(zoom) * 0.5; + let minYaw = yawLimit.min; + let maxYaw = yawLimit.max; + if (maxRenderHeight > 0) { + const halfVFovRad = toVerticalFov(halfHFov * DEG_TO_RAD, this._aspect); + const h = maxRenderHeight * 0.5; + const t = Math.tan(halfVFovRad); + const d = Math.sqrt((1 + h * h) / (1 + t * t)); + const theta = Math.atan(Math.tan(halfHFov * DEG_TO_RAD) * d) * RAD_TO_DEG; + minYaw = yawLimit.min + theta; + maxYaw = yawLimit.max - theta; + } + if (minYaw > maxYaw) { + minYaw = 0; + maxYaw = 0; + } + return { + min: minYaw, + max: maxYaw + }; + } + /** + * Get actual pitch range by the given zoom value. + * @ko 주어진 zoom 값에 대한 실제 pitch 범위값을 반환합니다. + * @since 4.0.0 + */ + getPitchRange(zoom) { + const pitchLimit = this._pitchRange; + const maxRenderHeight = this._maxRenderHeight; + if (!pitchLimit) return DEFAULT_PITCH_RANGE; + let minPitch = pitchLimit.min; + let maxPitch = pitchLimit.max; + if (maxRenderHeight > 0) { + const halfVFov = this.getVerticalFov(zoom) * 0.5; + minPitch = pitchLimit.min + halfVFov; + maxPitch = pitchLimit.max - halfVFov; + } + if (minPitch > maxPitch) { + minPitch = 0; + maxPitch = 0; + } + return { + min: Math.max(minPitch, -90), + max: Math.min(maxPitch, 90) + }; + } + /** + * Get actual zoom range in fov degrees. + * @ko 실제 줌 범위를 fov각의 범위로 반환합니다. + * @since 4.0.0 + */ + getZoomRange() { + var _a; + const limit = (_a = this._zoomRange) !== null && _a !== void 0 ? _a : DEFAULT_ZOOM_RANGE; + // max (zoom in) -> minimum fov + const minFov = this.getHorizontalFov(limit.max); + const maxFov = this.getHorizontalFov(limit.min); + const currentFov = this.getHorizontalFov(this.zoom); + return { + min: Math.max(minFov, 1), + max: Math.min(maxFov, 180), + current: currentFov + }; + } + /** + * Return horizontal fov value when the given zoom is applied. (in degrees, °) + * @ko 주어진 zoom 값이 적용되었을 때의 수평 fov값을 반환합니다. (도 단위, °) + * @returns Zoomed horizontal FOV {@ko 줌이 적용된 수평 fov값} + * @since 4.0.0 + */ + getHorizontalFov(zoom = this.zoom) { + return this._getZoomedHorizontalFov(zoom) * RAD_TO_DEG; + } + /** + * Return vertical fov value when the given zoom is applied. (in degrees, °) + * @ko 주어진 zoom 값이 적용되었을 때의 수직 fov값을 반환합니다. (도 단위, °) + * @returns Zoomed vertical FOV {@ko 줌이 적용된 수직 fov값} + * @since 4.0.0 + */ + getVerticalFov(zoom = this.zoom) { + const aspect = this._aspect; + const hFov = this._getZoomedHorizontalFov(zoom); // In radians + const vFov = toVerticalFov(hFov, aspect); + return vFov * RAD_TO_DEG; + } + /** + * Calculate zoom value for the given fov. + * @ko 주어진 fov값을 zoom값으로 변환합니다. + * @param fov horizontal fov (in degrees, °) {@ko 수평 fov 값 (도 단위, °)} + * @since 4.0.0 + */ + fovToZoom(fov) { + const baseFov = this.fov; + const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5); + const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5); + return renderingWidth / zoomedWidth; + } + /** + * Update inner matrixes. + * @ko 내부 행렬들을 업데이트합니다. + * @internal + * @since 4.0.0 + */ + updateMatrix() { + const up = this._up; + const aspect = this._aspect; + const viewMatrix = this.viewMatrix; + const projMatrix = this.projectionMatrix; + const position = this.position; + const rotation = this.quaternion; + const upDir = glMatrix.vec3.create(); + const viewDir = glMatrix.vec3.fromValues(0, 0, -1); + glMatrix.vec3.transformQuat(viewDir, viewDir, rotation); + glMatrix.vec3.transformQuat(upDir, up, rotation); + const hFov = this._getZoomedHorizontalFov(); // In radians + const vFov = toVerticalFov(hFov, aspect); + glMatrix.mat4.lookAt(viewMatrix, position, viewDir, upDir); + glMatrix.mat4.perspective(projMatrix, vFov, aspect, 0.1, 100); + this._changed = true; + } + /** + * @hidden + */ + onFrameRender() { + this._changed = false; + } + _updateQuaternion() { + eulerToQuat(this.quaternion, this.yaw, this.pitch, this.rollOffset); + } + /** + * @param zoom Current zoom value + * @returns horizontal fov including zoom, in radian + */ + _getZoomedHorizontalFov(zoom = this.zoom) { + return 2 * Math.atan(Math.tan(DEG_TO_RAD * this.fov * 0.5) / zoom); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class MouseInput extends Component__default["default"] { + constructor() { + super(); + this._onMouseDown = evt => { + const el = this._el; + if (!el || evt.button !== MOUSE_BUTTON.LEFT) return; + evt.preventDefault(); + if (el.focus) { + el.focus(); + } else { + window.focus(); + } + this._prevPos[0] = evt.clientX; + this._prevPos[1] = evt.clientY; + window.addEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove, false); + window.addEventListener(EVENTS$1.MOUSE_UP, this._onMouseUp, false); + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: false, + isKeyboard: false + }); + }; + this._onMouseMove = evt => { + evt.preventDefault(); + const x = evt.clientX; + const y = evt.clientY; + const prevPos = this._prevPos; + const deltaX = x - prevPos[0]; + const deltaY = y - prevPos[1]; + this.trigger(CONTROL_EVENTS.CHANGE, { + delta: { + x: deltaX, + y: deltaY + }, + isTouch: false, + isKeyboard: false + }); + prevPos[0] = x; + prevPos[1] = y; + }; + this._onMouseUp = () => { + this._prevPos[0] = 0; + this._prevPos[1] = 0; + window.removeEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove, false); + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onMouseUp, false); + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: false, + isKeyboard: false, + scrolling: false + }); + }; + this._el = null; + this._prevPos = [0, 0]; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.MOUSE_DOWN, this._onMouseDown); + this._el = element; + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.MOUSE_DOWN, this._onMouseDown); + window.removeEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove, false); + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onMouseUp, false); + this._el = null; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class TouchInput extends Component__default["default"] { + get scrollable() { + return this._scrollable; + } + set scrollable(val) { + this._scrollable = val; + } + constructor() { + super(); + this._onTouchStart = evt => { + if (evt.touches.length > 1 || this._scrolling) return; + const touch = evt.touches[0]; + this._isFirstTouch = true; + this._prevPos[0] = touch.clientX; + this._prevPos[1] = touch.clientY; + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: true, + isKeyboard: false + }); + }; + this._onTouchMove = evt => { + // Only the one finger motion should be considered + if (evt.touches.length > 1 || this._scrolling) return; + const touch = evt.touches[0]; + const scrollable = this._scrollable; + const prevPos = this._prevPos; + const x = touch.clientX; + const y = touch.clientY; + const deltaX = x - prevPos[0]; + const deltaY = y - prevPos[1]; + if (this._isFirstTouch) { + if (scrollable && !isFullscreen()) { + if (Math.abs(deltaY) > Math.abs(deltaX)) { + // Assume Scrolling + this._scrolling = true; + return; + } + } + this._isFirstTouch = false; + } + if (evt.cancelable !== false) { + evt.preventDefault(); + } + this.trigger(CONTROL_EVENTS.CHANGE, { + delta: { + x: deltaX, + y: deltaY + }, + isTouch: true, + isKeyboard: false + }); + prevPos[0] = x; + prevPos[1] = y; + }; + this._onTouchEnd = evt => { + if (evt.touches.length !== 0) return; + const touch = evt.touches[0]; + const prevPos = this._prevPos; + if (touch) { + prevPos[0] = touch.clientX; + prevPos[1] = touch.clientY; + } else { + prevPos[0] = 0; + prevPos[1] = 0; + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: true, + isKeyboard: false, + scrolling: this._scrolling + }); + } + if (evt.cancelable !== false) { + evt.preventDefault(); + } + this._scrolling = false; + }; + this._el = null; + this._prevPos = [0, 0]; + this._isFirstTouch = false; + this._scrolling = false; + this._scrollable = false; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.TOUCH_START, this._onTouchStart, { + passive: false + }); + element.addEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove, { + passive: false + }); + element.addEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = element; + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.TOUCH_START, this._onTouchStart); + element.removeEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove); + element.removeEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = null; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class KeyboardInput extends Component__default["default"] { + get active() { + const pressed = this._pressed; + return pressed.LEFT || pressed.UP || pressed.RIGHT || pressed.DOWN; + } + constructor() { + super(); + this._onKeyDown = evt => { + // Ignore all other keypress except main arrow keys + if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return; + this._updateKeyPress(evt, true); + const pressedCount = this._getPressedKeyCount(); + if (pressedCount <= 0) return; + evt.preventDefault(); + if (pressedCount === 1 && !evt.repeat) { + // On first keydown + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: false, + isKeyboard: true + }); + } + }; + this._onKeyUp = evt => { + // Ignore all other keypress except main arrow keys + if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return; + this._updateKeyPress(evt, false); + const pressedCount = this._getPressedKeyCount(); + if (pressedCount > 0) return; + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: false, + isKeyboard: true, + scrolling: false + }); + }; + this._el = null; + this._clearPressedKeys(); + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown); + element.addEventListener(EVENTS$1.KEY_UP, this._onKeyUp); + this._el = element; + this._clearPressedKeys(); + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown); + element.removeEventListener(EVENTS$1.KEY_UP, this._onKeyUp); + this._el = null; + this._clearPressedKeys(); + } + update() { + const delta = this._getDeltaByPressedKeys(); + if (delta.x !== 0 || delta.y !== 0) { + this.trigger(CONTROL_EVENTS.CHANGE, { + delta, + isTouch: false, + isKeyboard: true + }); + } + } + _clearPressedKeys() { + this._pressed = KEY_DIRECTION.reduce((obj, keyName) => { + return Object.assign(Object.assign({}, obj), { + [keyName]: false + }); + }, {}); + } + _updateKeyPress(event, isEnable) { + const pressed = this._pressed; + const keyToUpdate = event.keyCode != null ? DIRECTION_KEY_CODE[event.keyCode] : DIRECTION_KEY_NAME[event.key]; + if (!keyToUpdate) return; + pressed[keyToUpdate] = isEnable; + } + _getPressedKeyCount() { + return KEY_DIRECTION.filter(key => this._pressed[key]).length; + } + _getDeltaByPressedKeys() { + const pressed = this._pressed; + let x = 0; + let y = 0; + if (pressed.LEFT) { + x += 1; + } + if (pressed.RIGHT) { + x -= 1; + } + if (pressed.UP) { + y += 1; + } + if (pressed.DOWN) { + y -= 1; + } + return { + x, + y + }; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Camera's rotation control + * @ko 카메라의 회전을 담당하는 컨트롤 + * @since 4.0.0 + */ + class RotateControl extends Component__default["default"] { + /** + * @copy CameraControl#enabled + */ + get enabled() { + return this._enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * @copy CameraControl#animating + */ + get animating() { + return this._keyboardInput.active || this._xMotion.activated || this._yMotion.activated; + } + /** + * Current yaw value + * @ko 현재 yaw 값 + * @readonly + * @since 4.0.0 + */ + get yaw() { + return this._xMotion; + } + /** + * Current pitch value + * @ko 현재 pitch 값 + * @readonly + * @since 4.0.0 + */ + get pitch() { + return this._yMotion; + } + /** + * @copy View360#scrollable + */ + get scrollable() { + return this._touchInput.scrollable; + } + set scrollable(val) { + this._touchInput.scrollable = val; + } + /** + * Scale factor for mouse/touch rotation + * @ko 마우스/터치를 통한 회전 배율 + * @default [1, 1] + * @since 4.0.0 + */ + get pointerScale() { + return this._pointerScale; + } + set pointerScale(val) { + this._pointerScale = val; + } + /** + * Scale factor for keyboard rotation + * @ko 키보드를 통한 회전 배율 + * @default [1, 1] + * @since 4.0.0 + */ + get keyboardScale() { + return this._keyboardScale; + } + set keyboardScale(val) { + this._keyboardScale = val; + } + /** + * Duration of the input animation (ms) + * @ko 회전 애니메이션의 시간 (ms) + * @default 300 + */ + get duration() { + return this._duration; + } + set duration(val) { + this._duration = val; + this._xMotion.duration = val; + this._yMotion.duration = val; + } + /** + * Easing function of the animation + * @ko 회전 애니메이션에 적용할 easing 함수 + * @default EASING.EASE_OUT_CUBIC + * @see EASING + */ + get easing() { + return this._easing; + } + set easing(val) { + this._easing = val; + this._xMotion.easing = val; + this._yMotion.easing = val; + } + /** + * Disable X-axis(pitch) rotation. + * @ko x축 회전(pitch)을 비활성화합니다. + * @default false + */ + get disablePitch() { + return this._disablePitch; + } + set disablePitch(val) { + this._disablePitch = val; + } + /** + * Disable Y-axis(yaw) rotation. + * @ko y축 회전(yaw)을 비활성화합니다. + * @default false + */ + get disableYaw() { + return this._disableYaw; + } + set disableYaw(val) { + this._disableYaw = val; + } + /** + * Disable rotation by keyboard. + * @ko 키보드를 이용한 회전을 비활성화합니다. + * @default false + */ + get disableKeyboard() { + return this._disableKeyboard; + } + set disableKeyboard(val) { + this._disableKeyboard = val; + } + /** + * Create new RotateControl instance + * @ko RotateControl의 인스턴스를 생성합니다. + * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트} + * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부} + * @param options - Options for control {@ko 컨트롤 옵션들} + */ + constructor(controlEl, enableBlocked, { + duration = DEFAULT_ANIMATION_DURATION, + easing = DEFAULT_EASING, + pointerScale = [1, 1], + keyboardScale = [1, 1], + disablePitch = false, + disableYaw = false, + disableKeyboard = false + } = {}) { + super(); + this._onInputStart = evt => { + this._changedWhileDragging = false; + this.trigger(CONTROL_EVENTS.INPUT_START, Object.assign(Object.assign({}, evt), { + inputType: "rotate" + })); + }; + this._onChange = evt => { + const delta = evt.delta; + const invZoomScale = 1 / this._zoomScale; // Reduce speed on zoom + const screenScale = this._screenScale; + const keyboardScale = this._keyboardScale; + const pointerScale = this._pointerScale; + let scale; + if (evt.isKeyboard) { + scale = [keyboardScale[0] * invZoomScale, keyboardScale[1] * invZoomScale]; + } else { + scale = [pointerScale[0] * screenScale[0] * invZoomScale, pointerScale[1] * screenScale[1] * invZoomScale]; + } + const scaledX = delta.x * scale[0]; + const scaledY = delta.y * scale[1]; + this._xMotion.setNewEndByDelta(scaledX); + this._yMotion.setNewEndByDelta(scaledY); + this._changedWhileDragging = true; + }; + this._onInputEnd = evt => { + this.trigger(CONTROL_EVENTS.INPUT_END, Object.assign(Object.assign({}, evt), { + inputType: "rotate" + })); + if (!this._changedWhileDragging && !evt.isKeyboard && !evt.scrolling) { + this.trigger(CONTROL_EVENTS.STATIC_CLICK, { + isTouch: evt.isTouch + }); + } + this._changedWhileDragging = false; + }; + this._controlEl = controlEl; + this._pointerScale = pointerScale; + this._keyboardScale = keyboardScale; + this._duration = duration; + this._easing = easing; + this._disablePitch = disablePitch; + this._disableYaw = disableYaw; + this._disableKeyboard = disableKeyboard; + this._enableBlocked = enableBlocked; + this._mouseInput = new MouseInput(); + this._touchInput = new TouchInput(); + this._keyboardInput = new KeyboardInput(); + this._xMotion = new Motion({ + duration, + range: INFINITE_RANGE, + easing + }); + this._yMotion = new Motion({ + duration, + range: DEFAULT_PITCH_RANGE, + easing + }); + this._screenScale = [1, 1]; + this._zoomScale = 1; + this._enabled = false; + this._changedWhileDragging = false; + this._bindInputs(); + } + destroy() { + this.disable(); + this._mouseInput.off(); + this._touchInput.off(); + this._keyboardInput.off(); + this.off(); + this._changedWhileDragging = false; + } + /** + * @hidden + */ + update(delta) { + if (!this._enabled) return; + const xMotion = this._xMotion; + const yMotion = this._yMotion; + const keyboardInput = this._keyboardInput; + if (!this._disableKeyboard) { + keyboardInput.update(); + } + if (!this._disablePitch) { + yMotion.update(delta); + } + if (!this._disableYaw) { + xMotion.update(delta); + } + } + /** + * @hidden + */ + updateRange(camera, zoom) { + const yawRange = camera.getYawRange(zoom); + const pitchRange = camera.getPitchRange(zoom); + this._xMotion.setRange(yawRange.min, yawRange.max); + this._yMotion.setRange(pitchRange.min, pitchRange.max); + } + /** + * @hidden + */ + setZoomScale(val) { + this._zoomScale = val; + } + /** + * Resize control to match target size. + * @ko 컨트롤의 내부 크기를 갱신합니다. + * @param hfov - Camera horizontal fov in degrees {@ko 카메라의 수평방향 fov값 (도 단위)} + * @param aspect - Camera aspect {@ko 카메라 가로/세로 비율} + * @param width - New width {@ko 갱신된 너비} + * @param height - New height {@ko 갱신된 높이} + */ + resize(hfov, aspect, width, height) { + const vfov = toVerticalFov(hfov * DEG_TO_RAD, aspect) * RAD_TO_DEG; + this._screenScale[0] = hfov / width; + this._screenScale[1] = vfov / height; + } + enable() { + if (this._enabled) return; + const element = this._controlEl; + this._mouseInput.enable(element); + this._touchInput.enable(element); + this._keyboardInput.enable(element); + this._enabled = true; + this._enableBlocked = false; + this.trigger(CONTROL_EVENTS.ENABLE, { + control: this, + updateCursor: true + }); + } + disable() { + if (!this._enabled) return; + this._mouseInput.disable(); + this._touchInput.disable(); + this._keyboardInput.disable(); + this._enabled = false; + this.trigger(CONTROL_EVENTS.DISABLE, { + updateCursor: true + }); + } + sync(camera) { + this.updateRange(camera, camera.zoom); + this._xMotion.reset(camera.yaw); + this._yMotion.reset(camera.pitch); + } + _bindInputs() { + const mouseInput = this._mouseInput; + const touchInput = this._touchInput; + const keyboardInput = this._keyboardInput; + mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + touchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + touchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + keyboardInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + keyboardInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + keyboardInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class WheelInput extends Component__default["default"] { + get scrollable() { + return this._scrollable; + } + set scrollable(val) { + this._scrollable = val; + } + constructor() { + super(); + this._onWheel = evt => { + const scrollable = this._scrollable; + if (evt.deltaY === 0 || scrollable) return; + evt.preventDefault(); + evt.stopPropagation(); + if (this._inputTimer < 0) { + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: false, + isKeyboard: false + }); + } else { + this._clearTimer(); + } + const delta = this._baseScale * evt.deltaY; + this.trigger(CONTROL_EVENTS.CHANGE, { + delta, + isTouch: false, + isKeyboard: false + }); + this._inputTimer = window.setTimeout(() => { + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: false, + isKeyboard: false, + scrolling: false + }); + this._inputTimer = -1; + }, DEFAULT_ANIMATION_DURATION); + }; + this._el = null; + this._baseScale = 0.04; + this._scrollable = false; + this._inputTimer = -1; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.WHEEL, this._onWheel, { + passive: false, + capture: false + }); + this._el = element; + this._clearTimer(); + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.WHEEL, this._onWheel, false); + this._el = null; + this._clearTimer(); + } + _clearTimer() { + window.clearTimeout(this._inputTimer); + this._inputTimer = -1; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class PinchInput extends Component__default["default"] { + constructor() { + super(); + this._onTouchMove = evt => { + const touches = evt.touches; + if (touches.length !== 2) return; + if (!evt.cancelable) return; + evt.preventDefault(); + evt.stopPropagation(); + const prevDistance = this._prevDistance; + const diff = [touches[0].pageX - touches[1].pageX, touches[0].pageY - touches[1].pageY]; + const distance = Math.sqrt(diff[0] * diff[0] + diff[1] * diff[1]) * this._baseScale; + const delta = this._isFirstTouch ? 0 : distance - prevDistance; + if (this._isFirstTouch) { + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: true, + isKeyboard: false + }); + } + this._prevDistance = distance; + this._isFirstTouch = false; + this.trigger(CONTROL_EVENTS.CHANGE, { + delta, + isTouch: true, + isKeyboard: false + }); + }; + this._onTouchEnd = evt => { + if (evt.touches.length !== 0) return; + if (!this._isFirstTouch) { + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: true, + isKeyboard: false, + scrolling: false + }); + } + this._prevDistance = -1; + this._isFirstTouch = true; + }; + this._el = null; + this._baseScale = -0.2; + this._prevDistance = -1; + this._isFirstTouch = true; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove, { + passive: false, + capture: false + }); + element.addEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = element; + this._prevDistance = -1; + this._isFirstTouch = true; + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove, false); + element.removeEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = null; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Camera's zoom control + * @ko 카메라의 줌 값을 담당하는 컨트롤 + * @since 4.0.0 + */ + class ZoomControl extends Component__default["default"] { + /** + * @copy CameraControl#enabled + */ + get enabled() { + return this._enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * @copy CameraControl#animating + */ + get animating() { + return this._motion.activated; + } + /** + * Current zoom value + * @ko 현재 줌 값 + * @since 4.0.0 + * @readonly + */ + get zoom() { + return this._motion.val; + } + /** + * @copy View360#wheelScrollable + */ + get scrollable() { + return this._wheelInput.scrollable; + } + set scrollable(val) { + this._wheelInput.scrollable = val; + } + /** + * @hidden + */ + get range() { + return this._motion.range; + } + /** + * Scale factor of the zoom + * @ko 입력에 의한 줌 배율 + * @default 1 + * @since 4.0.0 + */ + get scale() { + return this._scale; + } + set scale(val) { + this._scale = val; + } + /** + * Duration of the input animation (ms) + * @ko 회전 애니메이션의 시간 (ms) + * @default 300 + * @since 4.0.0 + */ + get duration() { + return this._motion.duration; + } + /** + * Easing function of the animation + * @ko 회전 애니메이션에 적용할 easing 함수 + * @default EASING.EASE_OUT_CUBIC + * @see EASING + * @since 4.0.0 + */ + get easing() { + return this._motion.easing; + } + /** + * Create new ZoomControl instance + * @ko ZoomControl의 인스턴스를 생성합니다. + * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트} + * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부} + * @param options - Options for control {@ko 컨트롤 옵션들} + */ + constructor(controlEl, enableBlocked, { + scale = 1, + duration = DEFAULT_ANIMATION_DURATION, + easing = DEFAULT_EASING + } = {}) { + super(); + this._onInputStart = evt => { + this.trigger(CONTROL_EVENTS.INPUT_START, Object.assign(Object.assign({}, evt), { + inputType: "zoom" + })); + }; + this._onChange = ({ + delta + }) => { + const scale = this._scale; + const scaledDelta = delta * scale; + this._motion.setNewEndByDelta(scaledDelta); + }; + this._onInputEnd = evt => { + this.trigger(CONTROL_EVENTS.INPUT_END, Object.assign(Object.assign({}, evt), { + inputType: "zoom" + })); + }; + this._scale = scale; + this._controlEl = controlEl; + this._enableBlocked = enableBlocked; + this._wheelInput = new WheelInput(); + this._pinchInput = new PinchInput(); + this._motion = new Motion({ + duration, + easing, + range: INFINITE_RANGE + }); + this._enabled = false; + this._bindInputs(); + } + destroy() { + this.disable(); + this._wheelInput.off(); + this._pinchInput.off(); + this.off(); + } + /** + * @hidden + */ + update(delta) { + if (!this._enabled) return; + const motion = this._motion; + motion.update(delta); + } + enable() { + if (this._enabled) return; + const element = this._controlEl; + this._wheelInput.enable(element); + this._pinchInput.enable(element); + this._enabled = true; + this._enableBlocked = false; + this.trigger(CONTROL_EVENTS.ENABLE, { + control: this, + updateCursor: false + }); + } + disable() { + if (!this._enabled) return; + this._wheelInput.disable(); + this._pinchInput.disable(); + this._enabled = false; + this.trigger(CONTROL_EVENTS.DISABLE, { + updateCursor: false + }); + } + sync(camera) { + const motion = this._motion; + const range = camera.getZoomRange(); + motion.setRange(range.min, range.max); + motion.reset(range.current); + } + _bindInputs() { + const wheelInput = this._wheelInput; + const pinchInput = this._pinchInput; + wheelInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + wheelInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + wheelInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + pinchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + pinchInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + pinchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + const ROTATE_CONSTANT = { + PITCH_DELTA: 1, + YAW_DELTA_BY_ROLL: 2, + YAW_DELTA_BY_YAW: 3 + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = { + targetAxis: [0, 1, 0], + meshPoint: [0, 0, 1] + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = { + targetAxis: [0, 1, 0], + meshPoint: [1, 0, 0] + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = { + targetAxis: [1, 0, 0], + meshPoint: [0, 0, 1] + }; + class GyroInput extends Component__default["default"] { + get enabled() { + return this._enabled; + } + get orientationUpdated() { + return this._orientationUpdated; + } + get ignoreRoll() { + return this._ignoreRoll; + } + set ignoreRoll(val) { + this._ignoreRoll = val; + } + constructor() { + super(); + this._onDeviceOrientation = evt => { + const prevOrientation = this._orientation; + const { + alpha, + beta, + gamma + } = evt; + if (alpha == null || beta == null || gamma == null) return; + prevOrientation.alpha = alpha; + prevOrientation.beta = beta; + prevOrientation.gamma = gamma; + this._orientationUpdated = true; + if (this._needsCalibrate) { + this._needsCalibrate = false; + this._calibrateSensor(); + } + }; + this._updateScreenOrientation = () => { + if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) { + this._screenOrientation = screen.orientation.angle; + } else if (window.orientation !== undefined) { + this._screenOrientation = window.orientation >= 0 ? window.orientation : 360 + window.orientation; + } else { + this._screenOrientation = 0; + } + }; + this.quaternion = glMatrix.quat.create(); + this._orientation = { + alpha: 0, + beta: 90, + gamma: 0 + }; + this._yawOrigin = 0; + this._yawOffset = 0; + this._orientationUpdated = false; + this._screenOrientation = 0; + this._needsCalibrate = true; + this._enabled = false; + } + enable() { + if (this._enabled) return; + window.addEventListener(EVENTS$1.DEVICE_ORIENTATION, this._onDeviceOrientation); + window.addEventListener(EVENTS$1.ORIENTATION_CHANGE, this._updateScreenOrientation); + this._updateScreenOrientation(); + this._orientationUpdated = false; + this._needsCalibrate = true; + this._enabled = true; + } + disable() { + if (!this._enabled) return; + window.removeEventListener(EVENTS$1.DEVICE_ORIENTATION, this._onDeviceOrientation); + window.removeEventListener(EVENTS$1.ORIENTATION_CHANGE, this._updateScreenOrientation); + this._enabled = false; + } + update() { + this._updateRotation(); + this._orientationUpdated = false; + } + collectDelta() { + if (!this._orientationUpdated) { + return { + pitch: 0, + yaw: 0 + }; + } + const prevRotation = glMatrix.quat.clone(this.quaternion); + this._updateRotation(); + this._orientationUpdated = false; + return this._toEulerDelta(prevRotation, this.quaternion); + } + setInitialRotation(yaw) { + this._yawOrigin = yaw; + } + _calibrateSensor() { + const yawOrigin = this._yawOrigin; + const rotation = this.quaternion; + this._yawOffset = 0; + this._updateRotation(); + const { + yaw: sensorYaw + } = quatToEuler(rotation); + this._yawOffset = sensorYaw - yawOrigin; + this._updateRotation(); + this._needsCalibrate = false; + } + _updateRotation() { + const rotation = this.quaternion; + const { + alpha, + beta, + gamma + } = this._orientation; + glMatrix.quat.identity(rotation); + glMatrix.quat.rotateY(rotation, rotation, (alpha - this._yawOffset) * DEG_TO_RAD); + glMatrix.quat.rotateX(rotation, rotation, beta * DEG_TO_RAD); + glMatrix.quat.rotateZ(rotation, rotation, -gamma * DEG_TO_RAD); + const screen = glMatrix.quat.create(); + const screenAngle = -this._screenOrientation * 0.5 * DEG_TO_RAD; + const world = glMatrix.quat.fromValues(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5)); + glMatrix.quat.set(screen, 0, Math.sin(screenAngle), 0, Math.cos(screenAngle)); + glMatrix.quat.multiply(rotation, rotation, screen); + glMatrix.quat.multiply(rotation, rotation, world); + glMatrix.quat.normalize(rotation, rotation); + } + _toEulerDelta(prevQuat, currentQuat) { + return { + yaw: this._getDeltaYaw(prevQuat, currentQuat), + pitch: this._getDeltaPitch(prevQuat, currentQuat) + }; + } + _getDeltaYaw(prvQ, curQ) { + const yawDeltaByYaw = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW); + const yawDeltaByRoll = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) * Math.sin(this._extractPitchFromQuat(curQ)); + return yawDeltaByRoll + yawDeltaByYaw; + } + _getDeltaPitch(prvQ, curQ) { + return this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA); + } + _getRotationDelta(prevQ, curQ, rotateKind) { + const targetAxis = glMatrix.vec3.fromValues(ROTATE_CONSTANT[rotateKind].targetAxis[0], ROTATE_CONSTANT[rotateKind].targetAxis[1], ROTATE_CONSTANT[rotateKind].targetAxis[2]); + const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint; + const prevQuaternion = glMatrix.quat.clone(prevQ); + const curQuaternion = glMatrix.quat.clone(curQ); + glMatrix.quat.normalize(prevQuaternion, prevQuaternion); + glMatrix.quat.normalize(curQuaternion, curQuaternion); + let prevPoint = glMatrix.vec3.fromValues(0, 0, 1); + let curPoint = glMatrix.vec3.fromValues(0, 0, 1); + glMatrix.vec3.transformQuat(prevPoint, prevPoint, prevQuaternion); + glMatrix.vec3.transformQuat(curPoint, curPoint, curQuaternion); + glMatrix.vec3.transformQuat(targetAxis, targetAxis, curQuaternion); + const rotateDistance = glMatrix.vec3.dot(targetAxis, glMatrix.vec3.cross(glMatrix.vec3.create(), prevPoint, curPoint)); + const rotateDirection = rotateDistance > 0 ? 1 : -1; + // when counter clock wise, use vec3.fromValues(0,1,0) + // when clock wise, use vec3.fromValues(0,-1,0) + // const meshPoint1 = vec3.fromValues(0, 0, 0); + const meshPoint2 = glMatrix.vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + let meshPoint3; + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + meshPoint3 = glMatrix.vec3.fromValues(0, rotateDirection, 0); + } else { + meshPoint3 = glMatrix.vec3.fromValues(rotateDirection, 0, 0); + } + glMatrix.vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion); + glMatrix.vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion); + const vecU = meshPoint2; + const vecV = meshPoint3; + const vecN = glMatrix.vec3.create(); + glMatrix.vec3.cross(vecN, vecU, vecV); + glMatrix.vec3.normalize(vecN, vecN); + const coefficientA = vecN[0]; + const coefficientB = vecN[1]; + const coefficientC = vecN[2]; + // a point on the plane + curPoint = glMatrix.vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + glMatrix.vec3.transformQuat(curPoint, curPoint, curQuaternion); + // a point should project on the plane + prevPoint = glMatrix.vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]); + glMatrix.vec3.transformQuat(prevPoint, prevPoint, prevQuaternion); + // distance between prevPoint and the plane + let distance = Math.abs(prevPoint[0] * coefficientA + prevPoint[1] * coefficientB + prevPoint[2] * coefficientC); + const projectedPrevPoint = glMatrix.vec3.create(); + glMatrix.vec3.subtract(projectedPrevPoint, prevPoint, glMatrix.vec3.scale(glMatrix.vec3.create(), vecN, distance)); + let trigonometricRatio = (projectedPrevPoint[0] * curPoint[0] + projectedPrevPoint[1] * curPoint[1] + projectedPrevPoint[2] * curPoint[2]) / (glMatrix.vec3.length(projectedPrevPoint) * glMatrix.vec3.length(curPoint)); + // defensive block + if (trigonometricRatio > 1) { + trigonometricRatio = 1; + } + const theta = Math.acos(trigonometricRatio); + const crossVec = glMatrix.vec3.cross(glMatrix.vec3.create(), curPoint, projectedPrevPoint); + distance = coefficientA * crossVec[0] + coefficientB * crossVec[1] + coefficientC * crossVec[2]; + let thetaDirection; + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + thetaDirection = distance > 0 ? 1 : -1; + } else { + thetaDirection = distance < 0 ? 1 : -1; + } + const deltaRadian = theta * thetaDirection * rotateDirection; + return deltaRadian * RAD_TO_DEG; + } + _extractPitchFromQuat(quaternion) { + const baseV = glMatrix.vec3.fromValues(0, 0, 1); + glMatrix.vec3.transformQuat(baseV, baseV, quaternion); + return -1 * Math.atan2(baseV[1], Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2))); + } + } + + /** + * Camera's rotation control by gyroscope + * @ko 자이로스코프를 이용한 회전 컨트롤 + * @since 4.0.0 + */ + class GyroControl extends Component__default["default"] { + /** + * @copy CameraControl#enabled + */ + get enabled() { + return this._input.enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * @copy CameraControl#animating + */ + get animating() { + return this._input.enabled && this._input.orientationUpdated; + } + /** + * When `true`, ignore gyroscope's roll(z-axis rotation) value. + * :::caution + * Setting `false` will ignore camera's range limit. + * Options like {@link View360Options#yawRange}, {@link View360Options#pitchRange} are ignored, and {@link CylinderProjection} also can't force it's camera range limit. + * ::: + * @ko `true`일 경우 자이로스코프 입력의 roll(z축 회전)값을 무시합니다. + * :::caution + * 이 값을 `false`로 설정할 경우 카메라 범위 제약을 무시합니다. + * {@link View360Options#yawRange}, {@link View360Options#pitchRange}와 같은 값은 무시되며, {@link CylinderProjection} 사용시에도 범위를 벗어날 수 있습니다. + * ::: + * @default true + * @since 4.0.0 + */ + get ignoreRoll() { + return this._ignoreRoll; + } + set ignoreRoll(val) { + this._ignoreRoll = val; + } + /** + * Return availability of the gyroscope. + * :::caution + * This will always return false until user permission under environments like iOS which requires user permission when using gyroscope. + * ::: + * @ko 자이로스코프 사용 가능 여부를 반환합니다. + * :::caution + * iOS와 같이 GyroScope 사용시 사용자 Permission을 요구하는 환경에서는 사용자 Permission을 받기 전까지 항상 `false`입니다. + * ::: + * @example + * ```ts + * const gyroAvailable = await GyroControl.isAvailable(); + * ``` + */ + static isAvailable() { + return __awaiter(this, void 0, void 0, function* () { + if (!DeviceMotionEvent) { + return false; + } + let onDeviceMotionChange; + const listenDeviceMotion = () => new Promise(res => { + onDeviceMotionChange = evt => { + res(evt.rotationRate && evt.rotationRate.alpha != null); + }; + window.addEventListener(EVENTS$1.DEVICE_MOTION, onDeviceMotionChange); + }); + const timeout = () => new Promise(res => { + setTimeout(() => res(false), 1000); + }); + return Promise.race([listenDeviceMotion(), timeout()]).then(available => { + window.removeEventListener(EVENTS$1.DEVICE_MOTION, onDeviceMotionChange); + return available; + }); + }); + } + /** + * Request user permission for gyroscope sensor. + * This can be used in environments like iOS which requires user permission when using gyroscope sensors. + * @ko 사용자의 sensor permission 취득을 요청합니다. + * iOS와 같이 gyroscope 사용시 사용자 Permission을 요구하는 환경에서 사용 가능합니다. + * @returns Whether the permission is granted {@ko 사용자 permission 취득 여부} + */ + static requestSensorPermission() { + return __awaiter(this, void 0, void 0, function* () { + // Request sensor permission, on iOS13+ + if (sensorCanBeEnabledIOS()) { + return DeviceMotionEvent.requestPermission().then(permissionState => { + return permissionState === "granted"; + }).catch(() => false); + } + return true; + }); + } + /** + * Create new GyroControl instance + * @ko GyroControl의 인스턴스를 생성합니다. + * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부} + * @param options - Options for control {@ko 컨트롤 옵션들} + */ + constructor(enableBlocked, { + ignoreRoll = true + } = {}) { + super(); + this._enableBlocked = enableBlocked; + this._ignoreRoll = ignoreRoll; + this._input = new GyroInput(); + } + /** + * @copy CameraControl#destroy + */ + destroy() { + this.disable(); + this._input.off(); + this.off(); + } + /** + * @hidden + */ + update(camera, yaw, pitch, zoom) { + if (!this._ignoreRoll) { + this._updateQuaternion(camera, zoom); + } else { + this._updateYawPitch(camera, yaw, pitch, zoom); + } + } + /** + * @copy CameraControl#enable + */ + enable() { + if (this._input.enabled) return; + this._input.enable(); + this._enableBlocked = false; + this.trigger(CONTROL_EVENTS.ENABLE, { + control: this, + updateCursor: false + }); + } + /** + * @copy CameraControl#disable + */ + disable() { + if (!this._input.enabled) return; + this._input.disable(); + this.trigger(CONTROL_EVENTS.DISABLE, { + updateCursor: false + }); + } + /** + * @copy CameraControl#sync + */ + sync() {} // eslint-disable-line @typescript-eslint/no-empty-function + _updateYawPitch(camera, yaw, pitch, zoom) { + const input = this._input; + if (!input.enabled) return; + const { + yaw: yawDelta, + pitch: pitchDelta + } = input.collectDelta(); + yaw.add(yawDelta); + pitch.add(pitchDelta); + camera.lookAt({ + yaw: yaw.val, + pitch: pitch.val, + zoom + }); + } + _updateQuaternion(camera, zoom) { + const input = this._input; + if (!input.enabled) return; + input.update(); + camera.rotate(input.quaternion, zoom); + } + } + + /** + * Panorama control for View360 + * @ko View360용 파노라마 컨트롤 + * @since 4.0.0 + */ + class PanoControl { + /** + * @copy View360#useGrabCursor + */ + get useGrabCursor() { + return this._useGrabCursor; + } + set useGrabCursor(val) { + if (val === this._useGrabCursor) return; + this._useGrabCursor = val; + if (val && this._enabled) { + this._setCursor(CURSOR.GRAB); + } else if (!val) { + this._setCursor(CURSOR.NONE); + } + } + /** + * @copy View360#disableContextMenu + */ + get disableContextMenu() { + return this._disableContextMenu; + } + set disableContextMenu(val) { + if (val === this._disableContextMenu) return; + this._disableContextMenu = val; + if (val && this._enabled) { + this._blockContextMenu(); + } else if (!val) { + this._restoreContextMenu(); + } + } + /** + * @copy View360#disableContextMenu + */ + get scrollable() { + return this._rotateControl.scrollable; + } + set scrollable(val) { + this._rotateControl.scrollable = val; + } + /** + * @copy View360#disableContextMenu + */ + get wheelScrollable() { + return this._zoomControl.scrollable; + } + set wheelScrollable(val) { + this._zoomControl.scrollable = val; + } + /** + * When `true`, disables rotation slow-down by zoom-value. + * @ko `true`일 경우 줌 된 정도에 따라 회전속도를 늦추는 동작을 비활성화합니다. + * @since 4.0.0 + */ + get ignoreZoomScale() { + return this._ignoreZoomScale; + } + set ignoreZoomScale(val) { + this._ignoreZoomScale = val; + } + /** + * Whether the control is enabled or not + * @ko 컨트롤 활성화 여부를 가리키는 값 + * @readonly + * @since 4.0.0 + */ + get enabled() { + return this._enabled; + } + /** + * @copy View360#rotate + */ + get rotate() { + return this._rotateControl; + } + /** + * @copy View360#zoom + */ + get zoom() { + return this._zoomControl; + } + /** + * @copy View360#gyro + */ + get gyro() { + return this._gyroControl; + } + /** + * Whether one of the controls is animating at the moment + * @ko 현재 컨트롤 중 하나라도 동작중인지 여부를 나타내는 값 + * @readonly + * @since 4.0.0 + */ + get animating() { + return this._rotateControl.animating || this._zoomControl.animating || this._gyroControl.animating; + } + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param element - Canvas element {@ko 캔버스 엘리먼트} + * @param camera - Camera instance {@ko Camera 인스턴스} + * @param options - Options for PanoControl {@ko PanoControl 옵션들} + */ + constructor(element, camera, { + useGrabCursor, + scrollable, + wheelScrollable, + disableContextMenu, + rotate, + zoom, + gyro + }) { + this._preventContextMenu = evt => { + evt.preventDefault(); + }; + this._onInputStart = evt => { + if (this._useGrabCursor && !evt.isKeyboard) { + this._setCursor(CURSOR.GRABBING); + } + }; + this._onInputEnd = evt => { + if (this._useGrabCursor && !evt.isKeyboard) { + this._setCursor(CURSOR.GRAB); + } + }; + this._onEnable = ({ + control, + updateCursor + }) => { + if (updateCursor && this._useGrabCursor) { + this._setCursor(CURSOR.GRAB); + } + control.sync(this._camera); + }; + this._onDisable = ({ + updateCursor + }) => { + if (updateCursor) { + this._setCursor(CURSOR.NONE); + } + }; + this._onCameraAnimationEnd = ({ + animation + }) => { + animation.getFinishPromise().then(() => { + this.sync(); + }); + }; + // Bind Options + this._useGrabCursor = useGrabCursor; + this._disableContextMenu = disableContextMenu; + // Set internal values + this._camera = camera; + this._controlEl = element; + this._ignoreZoomScale = false; + this._enabled = false; + this._rotateControl = new RotateControl(element, !rotate, getObjectOption(rotate)); + this._zoomControl = new ZoomControl(element, !zoom, getObjectOption(zoom)); + this._gyroControl = new GyroControl(!gyro, getObjectOption(gyro)); + this._rotateControl.scrollable = scrollable; + this._zoomControl.scrollable = wheelScrollable; + this._bindEvents(); + } + /** + * Destroy the instance and remove all event listeners attached. + * This also will reset CSS cursor to initial. + * @ko 인스턴스를 삭제하고 부착된 모든 이벤트 리스너를 제거합니다. + * 또한, 캔버스에 적용된 CSS cursor도 제거합니다. + * @since 4.0.0 + */ + destroy() { + this.disable(); + this._rotateControl.destroy(); + this._zoomControl.destroy(); + this._setCursor(CURSOR.NONE); + } + /** + * Resize control to match target size. + * @ko 컨트롤이 내부에 캐시하고 있는 크기값을 갱신합니다. + * @param width New width {@ko 변경된 너비} + * @param height New height {@ko 변경된 높이} + * @since 4.0.0 + */ + resize(width, height) { + const camera = this._camera; + this._rotateControl.resize(camera.fov, camera.aspect, width, height); + } + /** + * Enable this control and add event listeners. + * @ko 컨트롤을 활성화하고 이벤트 리스너들을 추가합니다. + * @since 4.0.0 + */ + enable() { + return __awaiter(this, void 0, void 0, function* () { + if (this._enabled) return; + if (!this._rotateControl.enableBlocked) { + this._rotateControl.enable(); + } + if (!this._zoomControl.enableBlocked) { + this._zoomControl.enable(); + } + if (!this._gyroControl.enableBlocked) { + if (yield GyroControl.isAvailable()) { + this._gyroControl.enable(); + } + } + this.sync(); + if (this._disableContextMenu) { + this._blockContextMenu(); + } + this._enabled = true; + }); + } + /** + * Disable this control and remove all event listeners + * @ko 컨트롤을 비활성화하고 모든 이벤트 리스너들을 제거합니다. + * @since 4.0.0 + */ + disable() { + if (!this._enabled) return; + this._rotateControl.disable(); + this._zoomControl.disable(); + this._gyroControl.disable(); + this._restoreContextMenu(); + this._enabled = false; + } + /** + * Update control by given deltaTime + * @ko 컨트롤을 주어진 시간만큼 업데이트합니다. + * @param delta Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위} + * @since 4.0.0 + * @internal + */ + update(delta) { + const camera = this._camera; + const rotateControl = this._rotateControl; + const zoomControl = this._zoomControl; + const gyroControl = this._gyroControl; + zoomControl.update(delta); + const zoom = hfovToZoom(camera.fov, zoomControl.zoom); + // Slow down rotation on zoom-in + const zoomScale = this._ignoreZoomScale ? 1 : Math.max(zoom, 1); + rotateControl.setZoomScale(zoomScale); + rotateControl.updateRange(camera, zoom); + rotateControl.update(delta); + const yaw = rotateControl.yaw; + const pitch = rotateControl.pitch; + if (gyroControl.enabled) { + gyroControl.update(camera, yaw, pitch, zoom); + } else { + camera.lookAt({ + yaw: yaw.val, + pitch: pitch.val, + zoom + }); + } + } + /** + * Synchronize this control's state to current camera state + * @ko 컨트롤을 카메라의 현재 상태와 동기화합니다. + * @since 4.0.0 + */ + sync() { + const camera = this._camera; + this._zoomControl.sync(camera); + this._rotateControl.sync(camera); + } + _blockContextMenu() { + const el = this._controlEl; + el.addEventListener(EVENTS$1.CONTEXT_MENU, this._preventContextMenu); + } + _restoreContextMenu() { + const el = this._controlEl; + el.removeEventListener(EVENTS$1.CONTEXT_MENU, this._preventContextMenu); + } + _setCursor(newCursor) { + if (!this._useGrabCursor && newCursor !== CURSOR.NONE) return; + const targetEl = this._controlEl; + targetEl.style.cursor = newCursor; + } + _bindEvents() { + const rotateControl = this._rotateControl; + const zoomControl = this._zoomControl; + rotateControl.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + rotateControl.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + rotateControl.on(CONTROL_EVENTS.ENABLE, this._onEnable); + rotateControl.on(CONTROL_EVENTS.DISABLE, this._onDisable); + zoomControl.on(CONTROL_EVENTS.ENABLE, this._onEnable); + zoomControl.on(CONTROL_EVENTS.DISABLE, this._onDisable); + this._camera.on(CAMERA_EVENTS.ANIMATION_END, this._onCameraAnimationEnd); + } + } + + /** + * @hidden + */ + class Texture { + constructor({ + width, + height, + flipY + }) { + this.width = width; + this.height = height; + this.flipY = flipY; + this.wrapS = WebGLRenderingContext.CLAMP_TO_EDGE; + this.wrapT = WebGLRenderingContext.CLAMP_TO_EDGE; + } + destroy() { + // DO_NOTHING + } + isVideo() { + return false; + } + isCube() { + return false; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class Texture2D extends Texture { + constructor({ + source, + width, + height, + flipY + }) { + super({ + width, + height, + flipY + }); + this.source = source; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class TextureVideo extends Texture2D { + destroy() { + const video = this.source; + video.pause(); + video.removeAttribute("src"); + video.load(); + } + isVideo() { + return true; + } + isPaused() { + const video = this.source; + return video.paused || video.ended || video.readyState <= 2; + } + hasAudio() { + const video = this.source; + if (video.audioTracks) { + return video.audioTracks.length > 0; + } + if (video.webkitAudioDecodedByteCount != null) { + return video.webkitAudioDecodedByteCount > 0; + } + if (video.mozHasAudio != null) { + return video.mozHasAudio; + } + // We don't know whether the video has audio or not, return true + return true; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class TextureCube extends Texture { + constructor({ + sources, + width, + height, + flipY + }) { + super({ + width, + height, + flipY + }); + this.sources = sources; + } + isCube() { + return true; + } + } + + /** + * @hidden + */ + class TextureLoader { + constructor() { + this._loadChecker = new ImReady__default["default"](); + } + load(src, video) { + return __awaiter(this, void 0, void 0, function* () { + if (video) { + return this.loadVideo(src, getObjectOption(video)); + } else { + if (Array.isArray(src) && src.length > 1) { + return this.loadCubeImage(src); + } else { + const imgSrc = Array.isArray(src) ? src[0] : src; + return this.loadImage(imgSrc); + } + } + }); + } + loadImage(src) { + return __awaiter(this, void 0, void 0, function* () { + const images = this._toImageArray(src); + return this._load(images, resolve => { + const image = images[0]; + resolve(new Texture2D({ + source: image, + width: image.naturalWidth, + height: image.naturalHeight, + flipY: true + })); + }); + }); + } + loadCubeImage(src) { + return __awaiter(this, void 0, void 0, function* () { + const images = this._toImageArray(src); + return this._load(images, resolve => { + resolve(new TextureCube({ + sources: images, + width: images[0].naturalWidth, + height: images[0].naturalHeight, + flipY: false + })); + }); + }); + } + loadVideo(src, videoConfig) { + return __awaiter(this, void 0, void 0, function* () { + const config = Object.assign({ + autoplay: true, + muted: true, + loop: false, + volume: 1 + }, videoConfig); + const video = this._toVideoElement(src, config); + return this._load([video], resolve => { + const { + autoplay, + muted + } = config; + video.currentTime = 0; + if (autoplay && muted) { + video.play().catch(() => void 0); + } + resolve(new TextureVideo({ + source: video, + width: video.videoWidth, + height: video.videoHeight, + flipY: true + })); + }); + }); + } + _load(content, onLoad) { + const loader = this._loadChecker; + return new Promise((resolve, reject) => { + loader.once("ready", evt => { + if (evt.errorCount > 0) return; + onLoad(resolve); + }); + loader.once("error", reject); + loader.check(content); + }); + } + _toImageArray(src) { + const srcs = Array.isArray(src) ? src : [src]; + return srcs.map(source => { + if (isString(source)) { + const imgEl = new Image(); + imgEl.crossOrigin = "anonymous"; + imgEl.src = source; + return imgEl; + } else { + return source; + } + }); + } + _toVideoElement(src, { + muted, + loop, + volume + }) { + if (src instanceof HTMLVideoElement) { + return src; + } + const video = document.createElement("video"); + video.crossOrigin = "anonymous"; + video.playsInline = true; + video.setAttribute("webkit-playsinline", ""); + video.muted = muted; + video.volume = volume; + video.loop = loop; + if (Array.isArray(src)) { + src.forEach(source => this._appendSourceElement(video, source)); + } else { + this._appendSourceElement(video, src); + } + const sourceCount = video.querySelectorAll("source").length; + if (sourceCount > 0 && video.readyState < 1) { + video.load(); + } + return video; + } + _appendSourceElement(video, src) { + if (src instanceof HTMLSourceElement) { + return src; + } + const sourceEl = document.createElement("source"); + sourceEl.src = src; + video.appendChild(sourceEl); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @internal + */ + class FrameAnimator { + /** */ + constructor(maxDeltaTime, context = window) { + this.maxDeltaTime = maxDeltaTime; + this._context = context; + this._rafId = -1; + this._rafTimer = -1; + this._lastUpdateTime = -1; + } + start(callback) { + const context = this._context; + // No context / callback set + if (!context || !callback) return; + // Animation already started + if (this._rafId >= 0 || this._rafTimer >= 0) return; + const loop = (_time, frame) => { + const time = Date.now(); + const delta = Math.min(time - this._lastUpdateTime, this.maxDeltaTime * 1000); + callback(delta, frame); + this._lastUpdateTime = time; + this._rafId = context.requestAnimationFrame(loop); + }; + this._lastUpdateTime = Date.now(); + this._rafId = context.requestAnimationFrame(loop); + } + stop() { + if (this._rafId >= 0) { + this._context.cancelAnimationFrame(this._rafId); + } + if (this._rafTimer >= 0) { + clearTimeout(this._rafTimer); + } + this._rafId = -1; + this._rafTimer = -1; + } + changeContext(context) { + this.stop(); + this._context = context; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Automatic resizer that uses both ResizeObserver and window resize event + */ + class AutoResizer { + get useResizeObserver() { + return this._useResizeObserver; + } + /** + * Returns whether AutoResizer is enabled + */ + get enabled() { + return this._enabled; + } + /** */ + constructor(useResizeObserver, onResize) { + // eslint-disable-next-line @typescript-eslint/member-ordering + this._skipFirstResize = (() => { + let isFirstResize = true; + return () => { + if (isFirstResize) { + isFirstResize = false; + return; + } + this._onResize(); + }; + })(); + this._useResizeObserver = useResizeObserver; + this._enabled = false; + this._resizeObserver = null; + this._onResize = onResize; + } + /** + * Enable resizer + */ + enable(element) { + if (this._enabled) { + this.disable(); + } + if (this._useResizeObserver && !!window.ResizeObserver) { + const bbox = element.getBoundingClientRect(); + const resizeImmediate = bbox.width !== 0 || bbox.height !== 0; + const resizeObserver = new ResizeObserver(resizeImmediate ? this._skipFirstResize : this._onResize); + resizeObserver.observe(element); + this._resizeObserver = resizeObserver; + } else { + window.addEventListener(EVENTS$1.RESIZE, this._onResize); + } + this._enabled = true; + return this; + } + /** + * Disable resizer + */ + disable() { + if (!this._enabled) return this; + const resizeObserver = this._resizeObserver; + if (resizeObserver) { + resizeObserver.disconnect(); + this._resizeObserver = null; + } else { + window.removeEventListener(EVENTS$1.RESIZE, this._onResize); + } + this._enabled = false; + return this; + } + } + + /** + * A manager class for autoplay feature. + * @ko Autoplay 기능의 매니저 클래스. + * @since 4.0.0 + */ + class Autoplay { + /** + * Whether autoplay is enabled or not + * @ko 자동재생 활성화 여부를 나타내는 값 + * @readonly + * @since 4.0.0 + */ + get enabled() { + return this._enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * Whether autoplay is updating the camera at the moment + * @ko 현재 자동재생이 동작중인지 여부를 나타내는 값 + * @readonly + * @since 4.0.0 + */ + get playing() { + return this._enabled && !this._interrupted; + } + /** + * Reactivation delay after mouse input in milisecond. + * @ko 재활성화되기까지의 시간 (밀리초 단위) + * @default 2000 + * @since 4.0.0 + */ + get delay() { + return this._delay; + } + set delay(val) { + this._delay = val; + } + /** + * Reactivation delay after mouse leave when using {@link AutoplayOptions#pauseOnHover} + * @ko {@link AutoplayOptions#pauseOnHover} 사용시 마우스가 캔버스 영역을 떠난 뒤 자동재생이 다시 활성화되기까지의 시간 + * @default 0 + * @since 4.0.0 + */ + get delayOnMouseLeave() { + return this._delayOnMouseLeave; + } + set delayOnMouseLeave(val) { + this._delayOnMouseLeave = val; + } + /** + * Y-axis(yaw) rotation speed + * @ko Y-축 회전(yaw)의 속도 + * @default 1 + * @since 4.0.0 + */ + get speed() { + return this._speed; + } + set speed(val) { + this._speed = val; + } + /** + * Whether to pause rotation on mouse hover + * @ko 마우스가 캔버스 영역에 들어왔을 때 자동재생을 정지할지 여부 + * @default false + * @since 4.0.0 + */ + get pauseOnHover() { + return this._pauseOnHover; + } + set pauseOnHover(val) { + this._pauseOnHover = val; + } + /** + * Whether user can interrupt the rotation with click/wheel input + * @ko 클릭이나 휠같은 사용자 인터랙션시 자동재생을 멈출지 여부 + * @default true + * @since 4.0.0 + */ + get canInterrupt() { + return this._canInterrupt; + } + set canInterrupt(val) { + this._canInterrupt = val; + } + /** + * Whether to disable autoplay on user interrupt + * @ko 사용자 동작에 의해 자동재생이 정지할 때, {@link Autoplay#disable}을 호출하여 자동재생을 영구히 정지할지 여부 + * @default false + * @since 4.0.0 + */ + get disableOnInterrupt() { + return this._disableOnInterrupt; + } + set disableOnInterrupt(val) { + this._disableOnInterrupt = val; + } + /** + * Create new AutoPlayer instance + * @param camera - Instance of the {@link Camera} {@ko Camera의 인스턴스} + * @param element - Canvas element {@ko 캔버스 엘리먼트} + * @param options - Autoplay options {@ko 자동재생 옵션들} + * @since 4.0.0 + */ + constructor(viewer, element, options) { + this._onInputStart = () => { + if (!this._canInterrupt) return; + this._interrupted = true; + this._clearTimeout(); + }; + this._onInputEnd = () => { + this._setUninterruptedAfterDelay(this._delay); + }; + this._onGyroEnable = () => { + this.disable(); + }; + this._onMouseEnter = () => { + if (!this._pauseOnHover) return; + this._interrupted = true; + this._hovering = true; + }; + this._onMouseLeave = () => { + if (!this._pauseOnHover) return; + this._hovering = false; + this._setUninterruptedAfterDelay(this._delayOnMouseLeave); + }; + this._camera = viewer.camera; + this._control = viewer.control; + this._element = element; + this._enabled = false; + this._interrupted = false; + this._interruptionTimer = -1; + this._hovering = false; + const { + delay = 2000, + delayOnMouseLeave = 0, + speed = 1, + pauseOnHover = false, + canInterrupt = true, + disableOnInterrupt = false + } = getObjectOption(options); + this._enableBlocked = !options; + this._delay = delay; + this._delayOnMouseLeave = delayOnMouseLeave; + this._speed = speed; + this._pauseOnHover = pauseOnHover; + this._canInterrupt = canInterrupt; + this._disableOnInterrupt = disableOnInterrupt; + } + /** + * Destroy the instance and remove all event listeners attached + * @ko 인스턴스를 제거하고 연결된 모든 이벤트 핸들러를 삭제합니다. + * @since 4.0.0 + */ + destroy() { + this.disable(); + } + /** + * Rotate camera by given deltaTime + * @ko 주어진 deltaTime만큼 카메라를 회전시킵니다. + * @param deltaTime - Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위} + * @since 4.0.0 + */ + update(deltaTime) { + if (!this._enabled) return; + if (this._interrupted) { + if (this._disableOnInterrupt) { + this.disable(); + } + return; + } + const camera = this._camera; + const delta = -this._speed * deltaTime / 100; + camera.yaw = circulate(camera.yaw + delta, 0, 360); + } + /** + * Enable autoplay and add event listeners. + * @ko 자동재생을 활성화하고 이벤트리스너들을 추가합니다. + * @since 4.0.0 + */ + enable() { + const control = this._control; + const element = this._element; + if (this._enabled || control.gyro.enabled) return; + control.rotate.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.rotate.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.zoom.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.zoom.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.gyro.on(CONTROL_EVENTS.ENABLE, this._onGyroEnable); + element.addEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter, false); + element.addEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave, false); + this._enabled = true; + this._enableBlocked = false; + } + /** + * Enable autoplay after current `delay` value. + * @ko 현재의 `delay`값만큼 시간이 지난 다음에 자동재생을 활성화합니다. + * @since 4.0.0 + */ + enableAfterDelay() { + this.enable(); + this._interrupted = true; + this._setUninterruptedAfterDelay(this._delay); + } + /** + * Disable autoplay and remove all event handlers. + * @ko 자동재생을 비활성화하고 모든 이벤트 핸들러를 제거합니다. + * @since 4.0.0 + */ + disable() { + if (!this._enabled) return; + const control = this._control; + const element = this._element; + control.rotate.off(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.rotate.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.zoom.off(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.zoom.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.gyro.off(CONTROL_EVENTS.ENABLE, this._onGyroEnable); + element.removeEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter, false); + element.removeEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave, false); + this._enabled = false; + this._interrupted = false; + this._hovering = false; + this._clearTimeout(); + } + _setUninterruptedAfterDelay(delay) { + if (this._hovering) return; + this._clearTimeout(); + if (delay > 0) { + this._interruptionTimer = window.setTimeout(() => { + this._interrupted = false; + this._interruptionTimer = -1; + }, delay); + } else { + this._interrupted = false; + this._interruptionTimer = -1; + } + } + _clearTimeout() { + if (this._interruptionTimer >= 0) { + window.clearTimeout(this._interruptionTimer); + this._interruptionTimer = -1; + } + } + } + + /** + * WebXR manager class + * @ko WebXR 매니저 클래스 + * @since 4.0.0 + */ + class XRManager extends Component__default["default"] { + /** + * Create new instance. + * 새 인스턴스를 생성합니다. + * @param ctx - Instance of WebGL context helper {@ko WebGL 콘텍스트 헬퍼의 인스턴스} + * @param options - Options {@ko 옵션들} + */ + constructor(ctx, options = {}) { + super(); + /** + * Destroy instance and end XR session if there was any. + * @ko 인스턴스를 제거하고, XR 세션이 존재할 경우 종료합니다. + * @since 4.0.0 + */ + this.destroy = () => { + this.exit(); + this.off(); + }; + this._onSessionEnd = () => { + this.exit(); + this.trigger(EVENTS.VR_END); + }; + this._xrSession = null; + this._xrRefSpace = null; + this._ctx = ctx; + this._options = options; + } + /** + * Returns WebXR availability. + * @ko WebXR 사용 가능 여부를 반환합니다. + * @since 4.0.0 + */ + isAvailable() { + return __awaiter(this, void 0, void 0, function* () { + // eslint-disable-next-line compat/compat + const xr = window.navigator.xr; + if (!xr) return false; + return xr.isSessionSupported(SESSION_VR).then(available => { + return available; + }).catch(() => { + return false; + }); + }); + } + /** + * Enter VR session + * @ko VR 세션에 진입합니다. + * @since 4.0.0 + */ + enter() { + return __awaiter(this, void 0, void 0, function* () { + const ctx = this._ctx; + // eslint-disable-next-line compat/compat + const xr = window.navigator.xr; + if (!xr) return; + yield GyroControl.requestSensorPermission(); + const options = Object.assign({ + requiredFeatures: [XR_REFERENCE_SPACE] + }, this._options); + yield ctx.makeXRCompatible(); + const session = yield xr.requestSession(SESSION_VR, options); + ctx.bindXRLayer(session); + const refSpace = yield session.requestReferenceSpace(XR_REFERENCE_SPACE); + this._setSession(session, refSpace); + this.trigger(EVENTS.VR_START, { + session + }); + }); + } + /** + * Exit VR session + * @ko VR 세션에서 나갑니다. + * @since 4.0.0 + */ + exit() { + const xrSession = this._xrSession; + if (xrSession) { + xrSession.end().catch(() => void 0); + } + this._xrSession = null; + this._xrRefSpace = null; + } + /** + * @hidden + */ + canRender(frame) { + const refSpace = this._xrRefSpace; + if (!refSpace) return false; + const pose = frame.getViewerPose(refSpace); + return !!pose; + } + /** + * @hidden + */ + getEyeParams(frame) { + const session = frame.session; + const pose = frame.getViewerPose(this._xrRefSpace); + if (!pose) return null; + const glLayer = session.renderState.baseLayer; + if (!glLayer) return null; + return pose.views.map(view => { + const viewport = glLayer.getViewport(view); + const vMatrix = view.transform.inverse.matrix; + return { + viewport, + vMatrix, + pMatrix: view.projectionMatrix + }; + }); + } + _setSession(session, refSpace) { + this._xrSession = session; + this._xrRefSpace = refSpace; + session.addEventListener(EVENTS$1.XR_END, this._onSessionEnd); + } + } + + /** + * Hotspot data + * @ko 핫스팟 데이터 + * @since 4.0.0 + */ + class Hotspot { + constructor(element, position) { + this.element = element; + this.position = position; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Hotspot renderer + * @ko Hotspot 렌더러 + * @since 4.0.0 + */ + class HotspotRenderer { + /** + * Create new instance + * @ko 새 인스턴스를 생성합니다. + * @param rootEl - Container element for hotspots {@ko 핫스팟들의 컨테이너 엘리먼트} + * @param renderer - instance of WebGLRenderer {@ko WebGLRenderer의 인스턴스} + * @param options - Hotspot options {@ko Hotspot 옵션들 } + */ + constructor(rootEl, renderer, { + zoom = false + }) { + this._containerEl = getNullableElement(`.${DEFAULT_CLASS.HOTSPOT_CONTAINER}`, rootEl); + this._renderer = renderer; + this._hotspots = []; + this._zoom = zoom; + } + /** + * Refresh hotspots by collecting hotspot elements from current hotspot root element + * @ko 현재 핫스팟 루트 엘리먼트 내에서 핫스팟 엘리먼트들을 수집하여 갱신합니다. + * @throws {ERROR_CODES.INSUFFICIENT_ARGS} if data-position doesn't include all x, y, z values {@ko data-position이 x, y, z좌표를 전부 포함하고 있지 않을 때} + */ + refresh() { + const container = this._containerEl; + if (!container) return; + const hotspotEls = [].slice.apply(container.querySelectorAll(`.${DEFAULT_CLASS.HOTSPOT}`)); + this._hotspots = hotspotEls.map(el => this._parseHotspot(el)); + } + /** + * Render hotspots + * @ko 핫스팟들을 렌더링합니다. + * @param camera - Instance of Camera {@ko Camera의 인스턴스} + */ + render(camera) { + const hotspots = this._hotspots; + const halfWidth = this._renderer.width * 0.5; + const halfHeight = this._renderer.height * 0.5; + const zoom = camera.zoom; + const centerTransform = "translate(-50%, -50%)"; + const zoomTransform = this._zoom ? `scale(${zoom})` : ""; + hotspots.forEach(hotspot => { + const position = hotspot.position; + const relPos = glMatrix.vec3.create(); + glMatrix.vec3.copy(relPos, position); + glMatrix.vec3.transformMat4(relPos, relPos, camera.viewMatrix); + glMatrix.vec3.transformMat4(relPos, relPos, camera.projectionMatrix); + if (relPos[2] > 1 || relPos[2] < 0) { + hotspot.element.classList.remove(DEFAULT_CLASS.HOTSPOT_VISIBLE); + return; + } + const screenPos = glMatrix.vec2.fromValues(relPos[0] * halfWidth + halfWidth, -relPos[1] * halfHeight + halfHeight); + hotspot.element.classList.add(DEFAULT_CLASS.HOTSPOT_VISIBLE); + hotspot.element.style.transform = [centerTransform, `translate(${screenPos[0]}px, ${screenPos[1]}px)`, zoomTransform].join(" "); + }); + } + _parseHotspot(element) { + const yawStr = element.dataset.yaw; + const pitchStr = element.dataset.pitch; + const positionStr = element.dataset.position; + if (yawStr || pitchStr) { + const yaw = yawStr ? parseFloat(yawStr) : 0; + const pitch = pitchStr ? parseFloat(pitchStr) : 0; + const position = this._yawPitchToVec3(yaw, pitch); + return new Hotspot(element, position); + } else if (positionStr) { + const pos = positionStr.split(" ").map(val => parseFloat(val)); + if (pos.length < 3) { + throw new View360Error(ERROR.MESSAGES.INSUFFICIENT_ARGS(positionStr, "hotspot attribute \"data-position\""), ERROR.CODES.INSUFFICIENT_ARGS); + } + return new Hotspot(element, glMatrix.vec3.fromValues(pos[0], pos[1], pos[2])); + } else { + // Place hotspot at yaw: 0, pitch: 0 + const defaultPos = glMatrix.vec3.fromValues(0, 0, -1); + return new Hotspot(element, defaultPos); + } + } + _yawPitchToVec3(yaw, pitch) { + const yawRad = yaw * DEG_TO_RAD; + const pitchRad = pitch * DEG_TO_RAD; + const position = glMatrix.vec3.create(); + position[1] = Math.sin(pitchRad); + position[2] = Math.cos(pitchRad); + position[0] = position[2] * Math.sin(-yawRad); + position[2] = -position[2] * Math.cos(-yawRad); + return position; + } + } + + /** + * @hidden + */ + class VertexArrayObject { + get count() { + return this.geometry.indicies.count; + } + constructor(obj, geometry, buffers) { + this.obj = obj; + this.geometry = geometry; + this.buffers = buffers; + } + } + + /** + * @hidden + */ + class WebGLContext { + get canvas() { + return this._canvas; + } + get maxTextureSize() { + return this._maxTextureSize; + } + get isWebGL2() { + return this._isWebGL2; + } + get supportVAO() { + return this._isWebGL2 || !!this._extensions.vao; + } + get lost() { + return this._contextLost; + } + get debug() { + return this._debug; + } + constructor(canvas, debug) { + this._onContextLost = () => { + const canvas = this._canvas; + canvas.classList.add(DEFAULT_CLASS.CTX_LOST); + this._contextLost = true; + }; + this._onContextRestore = () => { + const canvas = this._canvas; + canvas.classList.remove(DEFAULT_CLASS.CTX_LOST); + this._contextLost = false; + }; + this._canvas = canvas; + this._contextLost = false; + this._debug = debug; + this._extensions = { + vao: null, + loseContext: null + }; + } + init() { + const canvas = this._canvas; + const { + gl, + isWebGL2 + } = this._getContext(canvas); + this._gl = gl; + this._maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); + this._isWebGL2 = isWebGL2; + if (!this._isWebGL2) { + this._extensions.vao = gl.getExtension("OES_vertex_array_object"); + } + this._extensions.loseContext = gl.getExtension("WEBGL_lose_context"); + canvas.addEventListener(EVENTS$1.CONTEXT_LOST, this._onContextLost); + canvas.addEventListener(EVENTS$1.CONTEXT_RESTORED, this._onContextRestore); + // gl.enable(gl.DEPTH_TEST); + } + + destroy() { + const gl = this._gl; + const canvas = this._canvas; + if (gl) { + // gl is not defined when destroy is called before init + gl.bindBuffer(gl.ARRAY_BUFFER, null); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + } + canvas.removeEventListener(EVENTS$1.CONTEXT_LOST, this._onContextLost); + canvas.removeEventListener(EVENTS$1.CONTEXT_RESTORED, this._onContextRestore); + } + forceLoseContext() { + const extension = this._extensions.loseContext; + if (!extension) return; + extension.loseContext(); + } + forceRestoreContext() { + const extension = this._extensions.loseContext; + if (!extension) return; + extension.restoreContext(); + } + clear() { + const gl = this._gl; + gl.clear(gl.COLOR_BUFFER_BIT); + } + resize() { + const gl = this._gl; + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + } + viewport(x, y, width, height) { + const gl = this._gl; + gl.viewport(x, y, width, height); + } + createVAO(geometry, shaderProgram) { + const nativeVAO = this._createNativeVAO(); + const vao = new VertexArrayObject(nativeVAO, geometry, { + indicies: this._createBuffer(), + position: this._createBuffer(), + uv: this._createBuffer() + }); + if (nativeVAO) { + this._bindNativeVAO(nativeVAO); + this._supplyGeometryData(vao, shaderProgram); + this._bindNativeVAO(null); + this._unbindBuffers(); + } + return vao; + } + draw(vao, shaderProgram) { + const gl = this._gl; + if (vao.obj) { + this._bindNativeVAO(vao.obj); + } else { + this._supplyGeometryData(vao, shaderProgram); + } + gl.drawElements(gl.TRIANGLES, vao.count, gl.UNSIGNED_SHORT, 0); + if (vao.obj) { + this._bindNativeVAO(null); + } else { + this._unbindBuffers(); + } + } + releaseVAO(vao) { + if (vao.obj) { + this._deleteNativeVAO(vao.obj); + } + this._deleteBuffer(vao.buffers.indicies); + this._deleteBuffer(vao.buffers.position); + this._deleteBuffer(vao.buffers.uv); + } + getUniformLocations(program, uniforms) { + const gl = this._gl; + const uniformLocations = Object.keys(uniforms).reduce((locations, key) => { + locations[key] = gl.getUniformLocation(program, key); + return locations; + }, {}); + return Object.assign(Object.assign({}, this._getCommonUniformLocations(program)), uniformLocations); + } + updateCommonUniforms(entity, camera, shaderProgram) { + const gl = this._gl; + const uniformLocations = shaderProgram.uniformLocations; + // We're using "matrix"(=local matrix) here for efficiency + // As projection doesn't require world matrix, as it doesn't have any parent or child + const matrix = entity.matrix; + const mvMatrix = glMatrix.mat4.create(); + glMatrix.mat4.multiply(mvMatrix, camera.viewMatrix, matrix); + gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix); + gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, camera.projectionMatrix); + } + updateVRUniforms(shaderProgram, mvMatrix, pMatrix, eyeIndex) { + const gl = this._gl; + const uniformLocations = shaderProgram.uniformLocations; + gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix); + gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, pMatrix); + if (uniformLocations.uEye) { + gl.uniform1f(uniformLocations.uEye, eyeIndex); + } + } + updateUniforms(shaderProgram) { + const gl = this._gl; + const uniforms = shaderProgram.uniforms; + const uniformLocations = shaderProgram.uniformLocations; + for (const key in uniforms) { + const uniform = uniforms[key]; + const location = uniformLocations[key]; + if (!uniform) continue; + if (uniform.needsUpdate) { + uniform.update(gl, location, this._isWebGL2); + } + } + } + releaseShaderResources(shaderProgram) { + const gl = this._gl; + const uniforms = shaderProgram.uniforms; + for (const key in uniforms) { + const uniform = uniforms[key]; + if (!uniform) continue; + if (uniform.needsUpdate) { + uniform.destroy(gl); + } + } + gl.deleteProgram(shaderProgram.program); + } + useProgram(shaderProgram) { + const gl = this._gl; + gl.useProgram(shaderProgram.program); + } + createProgram(vertexShader, fragmentShader) { + const gl = this._gl; + const program = gl.createProgram(); + const vs = this._compileShader(gl.VERTEX_SHADER, vertexShader); + const fs = this._compileShader(gl.FRAGMENT_SHADER, fragmentShader); + gl.attachShader(program, vs); + gl.attachShader(program, fs); + gl.bindAttribLocation(program, 0, "position"); + gl.bindAttribLocation(program, 1, "uv"); + gl.linkProgram(program); + if (this._debug && !gl.getProgramParameter(program, gl.LINK_STATUS)) { + let shaderLog = null; + if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) { + shaderLog = gl.getShaderInfoLog(vs); + } else if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) { + shaderLog = gl.getShaderInfoLog(fs); + } + throw new View360Error(ERROR.MESSAGES.FAILED_LINKING_PROGRAM(gl.getProgramInfoLog(program), shaderLog), ERROR.CODES.FAILED_LINKING_PROGRAM); + } + gl.deleteShader(vs); + gl.deleteShader(fs); + return program; + } + createWebGLTexture(texData) { + const gl = this._gl; + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texData.wrapS); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texData.wrapT); + if (!texData.isVideo() && this._isWebGL2) { + const gl2 = gl; + gl2.texStorage2D(gl2.TEXTURE_2D, 1, gl2.RGBA8, texData.width, texData.height); + } + return texture; + } + createWebGLCubeTexture(texData, size) { + const gl = this._gl; + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, texData.wrapS); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, texData.wrapT); + if (this._isWebGL2) { + const gl2 = gl; + gl2.texStorage2D(gl2.TEXTURE_CUBE_MAP, 1, gl2.RGBA8, size, size); + } + return texture; + } + makeXRCompatible() { + return __awaiter(this, void 0, void 0, function* () { + const gl = this._gl; + const attributes = gl.getContextAttributes(); + if (attributes && attributes.xrCompatible !== true) { + yield gl.makeXRCompatible(); + } + }); + } + bindXRLayer(session) { + const gl = this._gl; + const xrLayer = new XRWebGLLayer(session, gl); + session.updateRenderState({ + baseLayer: xrLayer + }); + } + bindXRFrame(frame) { + const gl = this._gl; + const session = frame.session; + const baseLayer = session.renderState.baseLayer; + gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer); + } + useDefaultFrameBuffer() { + const gl = this._gl; + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + } + _createBuffer() { + return this._gl.createBuffer(); + } + _deleteBuffer(buffer) { + return this._gl.deleteBuffer(buffer); + } + _createNativeVAO() { + const gl = this._gl; + if (this._isWebGL2) { + return gl.createVertexArray(); + } else { + const ext = this._extensions.vao; + return (ext === null || ext === void 0 ? void 0 : ext.createVertexArrayOES()) || null; + } + } + _bindNativeVAO(vao) { + const gl = this._gl; + if (this._isWebGL2) { + gl.bindVertexArray(vao); + } else { + const ext = this._extensions.vao; + ext === null || ext === void 0 ? void 0 : ext.bindVertexArrayOES(vao); + } + } + _deleteNativeVAO(vao) { + const gl = this._gl; + if (this._isWebGL2) { + gl.deleteVertexArray(vao); + } else { + const ext = this._extensions.vao; + ext === null || ext === void 0 ? void 0 : ext.deleteVertexArrayOES(vao); + } + } + _supplyGeometryData(vao, shaderProgram) { + const geometry = vao.geometry; + this._supplyIndiciesData(geometry.indicies, vao.buffers.indicies); + this._supplyAttributeData(geometry.vertices, shaderProgram.program, "position", vao.buffers.position); + this._supplyAttributeData(geometry.uvs, shaderProgram.program, "uv", vao.buffers.uv); + } + _unbindBuffers() { + const gl = this._gl; + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + gl.bindBuffer(gl.ARRAY_BUFFER, null); + } + _supplyIndiciesData(indicies, buffer) { + const gl = this._gl; + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicies.data, gl.STATIC_DRAW); + } + _supplyAttributeData(attribute, program, name, buffer) { + const gl = this._gl; + const attribLocation = gl.getAttribLocation(program, name); + // Attribute not used + if (attribLocation < 0) return; + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData(gl.ARRAY_BUFFER, attribute.data, gl.STATIC_DRAW); + gl.vertexAttribPointer(attribLocation, attribute.itemSize, gl.FLOAT, false, 0, 0); + gl.enableVertexAttribArray(attribLocation); + } + _compileShader(type, src) { + const gl = this._gl; + const shader = gl.createShader(type); + gl.shaderSource(shader, src); + gl.compileShader(shader); + return shader; + } + _getCommonUniformLocations(program) { + const gl = this._gl; + return { + uMVMatrix: gl.getUniformLocation(program, "uMVMatrix"), + uPMatrix: gl.getUniformLocation(program, "uPMatrix") + }; + } + _getContext(canvas) { + const webglIdentifiers = ["webgl2", "webgl", "experimental-webgl", "webkit-3d", "moz-webgl"]; + let context = null; + let isWebGL2 = false; + const contextAttributes = { + preserveDrawingBuffer: false, + antialias: false + }; + const onWebglContextCreationError = e => e.statusMessage; + canvas.addEventListener(EVENTS$1.CONTEXT_CREATE_ERROR, onWebglContextCreationError); + for (const identifier of webglIdentifiers) { + try { + context = canvas.getContext(identifier, contextAttributes); + isWebGL2 = identifier === "webgl2"; + } catch (t) {} // eslint-disable-line no-empty + if (context) { + break; + } + } + canvas.removeEventListener(EVENTS$1.CONTEXT_CREATE_ERROR, onWebglContextCreationError); + if (!context) { + throw new View360Error(ERROR.MESSAGES.WEBGL_NOT_SUPPORTED, ERROR.CODES.WEBGL_NOT_SUPPORTED); + } + return { + gl: context, + isWebGL2 + }; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection renderer, based on WebGL + * @ko WebGL 기반의 프로젝션 렌더러 + * @since 4.0.0 + */ + class WebGLRenderer { + /** + * Canvas element + * @ko 캔버스 엘리먼트 + * @since 4.0.0 + */ + get canvas() { + return this._canvas; + } + /** + * Canvas's width (`devicePixelRatio` is not applied) + * @ko 캔버스의 보이는 너비 (`devicePixelRatio`가 적용되지 않은) + * @since 4.0.0 + */ + get width() { + return this._elementSize.x; + } + /** + * Canvas's height (`devicePixelRatio` is not applied) + * @ko 캔버스의 높이 (`devicePixelRatio`가 적용되지 않은) + * @since 4.0.0 + */ + get height() { + return this._elementSize.y; + } + /** + * Current `devicePixelRatio` value. + * @ko 현재 `devicePixelRatio` 값. + * @since 4.0.0 + * @example + * ```js + * cosnt renderingWidth = view360.renderer.width * view360.renderer.pixelRatio; + * ``` + */ + get pixelRatio() { + return this._pixelRatio; + } + /** + * Width / height ratio (= width / height) + * @ko 너비 / 높이의 비율 (= width / height) + * @since 4.0.0 + * @example + * ```js + * const aspect = view360.renderer.width / view360.renderer.pixelRatio; + * assert(aspect === view360.renderer.aspect); + * ``` + */ + get aspect() { + return this._elementSize.x / this._elementSize.y; + } + /** + * Create new instance + * @ko 새 인스턴스를 생성합니다. + * @param canvas - Canvas element {@ko 캔버스 엘리먼트} + * @param debug - Whether to enable WebGL debugging {@ko WebGL debug 활성화 여부 } + */ + constructor(canvas, debug) { + this._canvas = canvas; + this._elementSize = { + x: 0, + y: 0 + }; + this._pixelRatio = 1; + this.ctx = new WebGLContext(canvas, debug); + } + /** + * Destroy instance and release all resources. + * @ko 인스턴스를 제거하고 사용된 리소스를 전부 해제합니다. + * @since 4.0.0 + */ + destroy() { + const canvas = this._canvas; + this.ctx.destroy(); + canvas.width = 1; + canvas.height = 1; + } + /** + * Resize canvas and renew inner size cache. + * @ko 캔버스의 크기를 재계산해서 내부의 사이즈 캐시값을 갱신합니다. + * @since 4.0.0 + */ + resize() { + const canvas = this._canvas; + const canvasSize = this._elementSize; + const devicePixelRatio = window.devicePixelRatio; + canvasSize.x = canvas.clientWidth; + canvasSize.y = canvas.clientHeight; + canvas.width = canvasSize.x * devicePixelRatio; + canvas.height = canvasSize.y * devicePixelRatio; + this._pixelRatio = devicePixelRatio; + this.ctx.resize(); + } + /** + * Render projection + * @ko 프로젝션을 렌더링합니다. + * @param projection - Projection to render {@ko 렌더링할 프로젝션} + * @param cameraa - Camera instance {@ko 카메라의 인스턴스} + * @since 4.0.0 + */ + render(projection, camera) { + const ctx = this.ctx; + const mesh = projection.getMesh(); + if (ctx.lost || !mesh) return; + ctx.clear(); + ctx.useProgram(mesh.program); + ctx.updateCommonUniforms(mesh, camera, mesh.program); + projection.update(camera); + ctx.updateUniforms(mesh.program); + ctx.draw(mesh.vao, mesh.program); + } + /** + * Render VR frame, only used for rendering frames inside VR sessions. + * @ko VR 프레임을 렌더링합니다. VR 세션 진입 도중에만 사용됩니다. + * @internal + * @param projection - Projection to render {@ko 렌더링할 프로젝션} + * @param vr - Instance of XRManager {@ko XRManager의 인스턴스} + * @param frame - VR frame {@ko VR 프레임} + * @since 4.0.0 + */ + renderVR(projection, vr, frame) { + const ctx = this.ctx; + const mesh = projection.getMesh(); + const eyeParams = vr.getEyeParams(frame); + if (!eyeParams || !mesh) return; + ctx.bindXRFrame(frame); + ctx.useProgram(mesh.program); + ctx.updateUniforms(mesh.program); + eyeParams.forEach((eye, eyeIndex) => { + const viewport = eye.viewport; + // We're using "mesh.matrix"(=local matrix) here for efficiency + // As projection doesn't require world matrix, as it doesn't have any parent or child + const mvMatrix = glMatrix.mat4.multiply(glMatrix.mat4.create(), eye.vMatrix, mesh.matrix); + ctx.viewport(viewport.x, viewport.y, viewport.width, viewport.height); + ctx.updateVRUniforms(mesh.program, mvMatrix, eye.pMatrix, eyeIndex); + ctx.draw(mesh.vao, mesh.program); + }); + } + } + + /** + * Panorama 360 image viewer + * @ko 파노라마 360 이미지 뷰어 + * @since 4.0.0 + * @see View360Options + * @see View360Events + */ + class View360 extends Component__default["default"] { + /** + * Root element (`.view360-container`) + * @ko 루트 엘리먼트 (`.view360-container`) + * @since 4.0.0 + * @readonly + * @example + * ```html + *
+ * + *
+ * ``` + * ```ts + * import View360 from "@egjs/view360"; + * + * const viewer = new View360("#viewer"); + * console.log(viewer.rootEl); // Element with id "viewer" + * ``` + */ + get rootEl() { + return this._rootEl; + } + /** + * Projection renderer. + * @ko 프로젝션 렌더러. + * @since 4.0.0 + * @readonly + */ + get renderer() { + return this._renderer; + } + /** + * Projection camera. + * @ko 프로젝션 카메라. + * @since 4.0.0 + * @readonly + */ + get camera() { + return this._camera; + } + /** + * Rotate/Zoom Controller. + * @ko 회전/줌 컨트롤러. + * @since 4.0.0 + * @readonly + */ + get control() { + return this._control; + } + /** + * WebXR-based VR manager. + * @ko WebXR 기반의 VR 기능 매니저 인스턴스. + * @since 4.0.0 + * @readonly + * @example + * ```ts + * // Example: Enter VR + * // This must be called on user interaction, else will be rejected. + * viewer.vr.enter(); + * ``` + */ + get vr() { + return this._vr; + } + /** + * Hotspot renderer. + * You can also change options of {@link View360Options#hotspot} with this. + * @ko 핫스팟 렌더러 인스턴스. + * {@link View360Options#hotspot} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get hotspot() { + return this._hotspot; + } + /** + * An array of plugins added. + * @ko 추가된 플러그인의 배열 + * @since 4.0.0 + * @readonly + * @example + * ```ts + * const viewer = new View360("#el_id", { + * plugins: [new ControlBar()] + * }); + * + * console.log(viewer.plugins); // [ControlBar] + * + * viewer.addPlugins(new LoadingSpinner()) // [ControlBar, LoadingSpinner]; + * ``` + */ + get plugins() { + return this._plugins; + } + /** + * A instance of {@link Projection} that currently enabled. `null` if not initialized yet. + * You should call {@link View360#load} to change panorama src or projection type. + * @ko 현재 사용중인 {@link Projection}의 인스턴스. 프로젝션을 활성화하지 않았을 경우 `null`입니다. + * 파노라마 이미지 소스나 프로젝션 타입을 변경하려면 {@link View360#load}를 호출하면 됩니다. + * @since 4.0.0 + * @readonly + * @example + * ```ts + * const viewer = new View360 + * ``` + */ + get projection() { + return this._projection; + } + set projection(val) { + if (this._initialized && val) { + this.load(val); + } else { + this._projection = val; + } + } + /** + * A boolean value whether {@link View360#init init()} is called before. + * @ko {@link View360#init init()}이 호출되었는지 여부를 가리키는 값 + * @since 4.0.0 + * @readonly + * @example + * ```ts + * const viewer = new View360("#el", { autoInit: false }); + * + * console.log(viewer.initialized); // false + * + * await viewer.init(); + * + * console.log(viewer.initialized); // true + * ``` + */ + get initialized() { + return this._initialized; + } + /** + * Instance of the Autoplay manager. + * You can also change {@link View360Options#autoplay} options with this. + * @ko Autoplay 기능의 매니저 인스턴스. + * 이 인스턴스를 통해 {@link View360Options#autoplay} 옵션을 변경하는 것도 가능합니다. + * @since 4.0.0 + * @readonly + * @example + * ```ts + * // Disable autoplay + * viewer.autoplay.disable(); + * ``` + */ + get autoplay() { + return this._autoplay; + } + /** + * When this value is `true` and {@link View360Options#projection} is set, {@link View360#init init()} will be called automatically when instance is created. + * @ko 이 값이 `true`이고, {@link View360Options#projection}이 설정되었으면, 인스턴스 생성 시점에 자동으로 {@link View360#init init()}을 호출합니다. + * @default true + * @since 4.0.0 + * @example + * ```ts + * import View360, { EquirectProjection, EVENTS } from "@egjs/view360"; + * + * // viewer.init() is called on instance creation + * // But as `init` is asynchronous, you should wait for "ready" event if you want to do something after initialization. + * const viewer = new View360("#el_id", { + * autoInit: true, + * projection: new EquirectProjection({ src: "SRC_TO_URL" }) + * }); + * + * console.log(viewer.initialized); // false, as `init` is asynchronous + * + * viewer.once(EVENTS.READY, () => { + * console.log(viewer.initialized); // true + * }); + * ``` + */ + get autoInit() { + return this._autoInit; + } + /** + * When `true`, {@link View360#resize} is called when the canvas size is changed. + * @ko `true`일 경우, 캔버스의 크기가 변경되었을 때 자동으로 {@link View360#resize}를 호출합니다. + * @default true + * @since 4.0.0 + * @see View360#useResizeObserver + * @example + * ```ts + * const viewer = new View360("#el_id", { + * autoResize: true + * }); + * + * // This can trigger `viewer.resize()` if the canvas size was not 400px + * const canvas = viewer.renderer.canvas; + * canvas.style.width = "400px"; + * ``` + */ + get autoResize() { + return this._autoResize; + } + /** + * CSS selector for canvas element to render panorama image/video. + * The canvas element should be placed inside the root element. (Dont' have to be direct child) + * @ko 파노라마 이미지/비디오를 렌더링할 canvas 엘리먼트의 CSS 선택자 + * 캔버스 엘리먼트는 루트 엘리먼트 내부에 있어야합니다. 루트 엘리먼트의 직계 자식 엘리먼트(Direct child element)일 필요는 없습니다. + * @default "canvas" + * @since 4.0.0 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * + * ```ts + * const viewer = new View360("#el_id", { + * canvasSelector: "#canvas_to_select" + * }); + * ``` + */ + get canvasSelector() { + return this._canvasSelector; + } + /** + * When `true`, it will use {@link ResizeObserver} API to detect canvas size change when {@link View360Options#autoResize} is enabled. + * @ko `true`일 때 {@link View360Options#autoResize}가 활성화되었으면, 사용 가능한 환경에서 {@link ResizeObserver} API를 사용해서 캔버스 크기 변화를 추적합니다. + * @default true + * @since 4.0.0 + */ + get useResizeObserver() { + return this._useResizeObserver; + } + /** + * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} attribute for the canvas element. + * This is necessary for the keyboard controls. + * By default, `0` will be assigned. `null` to disable. + * @ko 캔버스 엘리먼트에 적용할 {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} 어트리뷰트의 값. + * 이 값을 설정해야만 키보드 컨트롤을 사용 가능합니다. + * 기본값으로 `0`이 설정됩니다. `null`로 지정하면 `tabindex`를 설정하지 않습니다. + * @see RotateControlOptions#disableKeyboard + * @default 0 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * tabindex: 5 + * }); + * ``` + * + * ```html + * + *
+ * + *
+ * ``` + */ + get tabIndex() { + return this._tabIndex; + } + set tabIndex(val) { + const canvas = this._renderer.canvas; + this._tabIndex = val; + if (val != null) { + canvas.tabIndex = val; + } else { + canvas.removeAttribute("tabindex"); + } + } + /** + * A maximum delta time between frames in seconds. + * It can prevent camera or control changing too fast when frame being late. + * @ko 프레임간 시간 차이의 최대값. (초 단위) + * 퍼포먼스 등의 이유로 프레임 렌더링이 늦어졌을 때, 화면이 갑작스럽게 바뀌는 것을 막아줍니다. + * @default 1 / 30 + * @since 4.0.0 + */ + get maxDeltaTime() { + return this._animator.maxDeltaTime; + } + set maxDeltaTime(val) { + this._animator.maxDeltaTime = val; + } + /** + * Enable WebGL debugging. Setting this to `true` can decrease performance. + * This is used internally on developing View360. + * @ko WebGL 디버깅을 활성화합니다. 이 값을 `true`로 할 경우 성능이 하락할 수 있습니다. + * 이 옵션은 View360을 개발하기 위해 내부적으로 사용됩니다. + * @default false + */ + get debug() { + return this._debug; + } + set debug(val) { + this._debug = val; + } + // Camera options + /** + * Initial yaw (y-axis rotation) value for camera. (in degrees, °) + * As View360 uses right-handed coordinate system internally, camera will rotate counter-clockwise by this value. + * @ko 카메라의 초기 yaw(y축 회전)값 (도 단위, °) + * View360은 오른손 좌표계를 사용하기 때문에, 카메라가 해당 값만큼 시계 반대방향으로 회전합니다. + * @default 0 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * initialYaw: 30 + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.yaw); // 30 + * }); + * ``` + */ + get initialYaw() { + return this._camera.initialYaw; + } + set initialYaw(val) { + this._camera.initialYaw = val; + } + /** + * Initial pitch (x-axis rotation) value for camera. (in degrees, °) + * As View360 uses right-handed coordinate system internally, positive value will make camera to look upside, while negative value will look down. + * @ko 카메라의 초기 pitch(x축 회전)값 (도 단위, °) + * View360은 오른손 좌표계를 사용하기 때문에, 양(+)의 값은 카메라가 위를 보게 하고, 음(-)의 값은 카메라가 아래를 보게 합니다. + * @default 0 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * initialPitch: 60 + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.pitch); // 60 + * }); + * ``` + */ + get initialPitch() { + return this._camera.initialPitch; + } + set initialPitch(val) { + this._camera.initialPitch = val; + } + /** + * Initial zoom value for camera. + * Setting this value to `2` will enlarge panorama 200% by width. + * @ko 카메라의 초기 줌 값. + * 이 값을 `2`로 설정할 경우 파노라마 이미지를 가로 기준 200%만큼 확대합니다. + * @default 1 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * initialZoom: 2 + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.zoom); // 2 + * }); + * ``` + */ + get initialZoom() { + return this._camera.initialZoom; + } + set initialZoom(val) { + this._camera.initialZoom = val; + } + /** + * Restrict yaw(y-axis rotation) range. (in degrees, °) + * @ko yaw(y축 회전) 범위를 제한합니다. (도 단위, °) + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * yawRange: [-30, 30] + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.yaw); // 0 + * viewer.camera.lookAt({ yaw: 60 }); + * console.log(viewer.camera.yaw); // 30 + * }); + * ``` + */ + get yawRange() { + return this._camera.yawRange; + } + set yawRange(val) { + this._camera.yawRange = val; + if (this._projection) this._projection.updateCamera(this._camera); + } + /** + * Restrict pitch(x-axis rotation) range. (in degrees, °) + * @ko pitch(x축 회전) 범위를 제한합니다. (도 단위, °) + * @default null + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * pitchRange: [-45, 45] + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.pitch); // 0 + * viewer.camera.lookAt({ pitch: 60 }); + * console.log(viewer.camera.pitch); // 45 + * }); + * ``` + */ + get pitchRange() { + return this._camera.pitchRange; + } + set pitchRange(val) { + this._camera.pitchRange = val; + if (this._projection) this._projection.updateCamera(this._camera); + } + /** + * Restrict camera zoom range. + * If `null`, a default zoom range from `0.6` to `10` will be used. + * @ko 카메라 줌 범위를 제한합니다. + * `null`일 경우 기본값으로 `0.6`에서 `10`의 범위를 사용합니다. + * @default null + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * zoomRange: [0.5, 4] + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.zoom); // 1 + * viewer.camera.lookAt({ zoom: 6 }); + * console.log(viewer.camera.zoom); // 4 + * }); + * ``` + */ + get zoomRange() { + return this._camera.zoomRange; + } + set zoomRange(val) { + this._camera.zoomRange = val; + if (this._projection) this._projection.updateCamera(this._camera); + } + /** + * Camera's horizontal FOV(Field of View). (in degrees, °) + * @ko 카메라의 수평 FOV(Field of View) 값. (도 단위, °) + * @default 90 + * @since 4.0.0 + * @example + * ```ts + * // Init with fov: 120 + * const viewer = new View360("#el_id", { fov: 120 }); + * + * // Back to 90 + * viewer.fov = 90; + * ``` + */ + get fov() { + return this._camera.fov; + } + set fov(val) { + const camera = this._camera; + const control = this._control; + camera.fov = val; + camera.updateMatrix(); + control.sync(); + } + // Control options + /** + * A control for camera rotation. + * You can also change options of {@link View360Options#rotate} with this. + * @ko 카메라 회전을 담당하는 컨트롤. + * {@link View360Options#rotate} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get rotate() { + return this._control.rotate; + } + /** + * A control for camera zoom. + * You can also change options of {@link View360Options#zoom} with this. + * @ko 카메라 줌을 담당하는 컨트롤. + * {@link View360Options#zoom} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get zoom() { + return this._control.zoom; + } + /** + * A control for camera rotation with gyroscope input. + * You can also change options of {@link View360Options#gyro} with this. + * @ko 자이로스코프를 통한 카메라 회전을 담당하는 컨트롤. + * {@link View360Options#gyro} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get gyro() { + return this._control.gyro; + } + /** + * Apply CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor} by current state of input when using mouse. + * If `true`, this will add CSS style to canvas element. It'll apply `cursor: "grab"` by default and `cursor: "grabbing"` when holding the mouse button. + * @ko 마우스 사용시 CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor}값을 자동으로 변경할지 여부. + * `true`일 경우 기본 상태에서 `cursor: "grab"`을, 입력 도중에 `cursor: "grabbing"`을 캔버스에 적용합니다. + * @default true + * @since 4.0.0 + */ + get useGrabCursor() { + return this._control.useGrabCursor; + } + set useGrabCursor(val) { + this._control.useGrabCursor = val; + } + /** + * Disable context menu which pops up on mouse right click. + * @ko 마우스 우클릭시 표시되는 컨텍스트 메뉴를 비활성화합니다. + * @default false + * @since 4.0.0 + */ + get disableContextMenu() { + return this._control.disableContextMenu; + } + set disableContextMenu(val) { + this._control.disableContextMenu = val; + } + /** + * If `true`, enables scroll on mobile(touch) devices on canvas. + * :::caution + * When this option is enabled, users must swipe horizontally first then vertically to change view up or down. + * ::: + * @ko `true`로 설정할 경우, 모바일(터치) 환경의 캔버스 영역 내에서 스크롤을 가능하게 합니다. + * :::caution + * 이 값을 활성화할 경우, 사용자가 카메라 뷰를 위/아래로 바꾸기 위해서는 먼저 가로로 스와이프한 이후에 세로로 스와이프해야만 합니다. + * ::: + * @since 4.0.0 + * @default true + */ + get scrollable() { + return this._control.scrollable; + } + set scrollable(val) { + this._control.scrollable = val; + } + /** + * If `true`, enables scroll by mouse wheel on canvas. + * :::caution + * When this option is enabled, zoom by mouse wheel will be disabled. + * ::: + * @ko `true`로 설정할 경우, 캔버스 영역 내에서 마우스 휠을 이용한 페이지 스크롤이 가능해집니다. + * :::caution + * 이 값을 활성화할 경우, 마우스 휠을 통한 줌이 불가능하게 됩니다. + * ::: + * @since 4.0.0 + * @default false + */ + get wheelScrollable() { + return this._control.wheelScrollable; + } + set wheelScrollable(val) { + this._control.wheelScrollable = val; + } + /** + * Create new instance of View360 + * @ko View360의 새로운 인스턴스를 생성합니다 + * @param root - Root element(`.view360-container`) to mount View360 + * Can be either a CSS selector or HTMLElement. + * {@ko View360을 마운트할 루트 엘리먼트, CSS 셀렉터나 HTMLElement를 지정 가능합니다.} + * @param options - Options to apply + * {@ko 적용할 옵션들} + * @example + * ```ts + * import View360, { EquirectProjection } from "@egjs/view360"; + * + * // Create new View360 instance + * const viewer = new View360("#id-of-a-container", { + * projection: new EquirectProjection({ + * src: "URL_TO_PANORAMA_IMAGE_OR_VIDEO", + * }) + * }); + * ``` + */ + constructor(root, { + projection = null, + initialYaw = 0, + initialPitch = 0, + initialZoom = 1, + yawRange = null, + pitchRange = null, + zoomRange = null, + fov = 90, + useGrabCursor = true, + disableContextMenu = false, + rotate = true, + zoom = true, + gyro = false, + scrollable = true, + wheelScrollable = false, + autoplay = false, + hotspot = {}, + autoInit = true, + autoResize = true, + canvasSelector = "canvas", + useResizeObserver = true, + on = {}, + plugins = [], + maxDeltaTime = 1 / 30, + tabIndex = 0, + debug = false + } = {}) { + super(); + /** + * Render a single panorama image/video frame. + * Rendering is performed automatically on demand, so you usually don't have to call this. + * Call this when a frame is not renewed after changing options. + * @ko 파노라마 이미지/비디오의 한 프레임을 렌더링합니다. + * 프레임 갱신은 보통 필요한 때에만 자동적으로 이루어지기 때문에, 보통은 이 메소드를 호출할 필요는 없습니다. + * 옵션 변경 이후에도 프레임 갱신이 이루어지지 않는다면, 이 메소드를 호출해주세요. + * @param delta Delta time in milisec. {@ko 프레임간 시간 차이, 밀리초 단위} + * @since 4.0.0 + */ + this.renderFrame = delta => { + const camera = this._camera; + const renderer = this._renderer; + const control = this._control; + const hotspot = this._hotspot; + const autoPlayer = this._autoplay; + const projection = this._projection; + if (!projection) return; + this._emit(EVENTS.BEFORE_RENDER); + if (autoPlayer.playing) { + autoPlayer.update(delta); + control.sync(); + } + if (camera.animation) { + camera.animation.update(delta); + } else { + control.update(delta); + } + renderer.render(projection, camera); + hotspot.render(camera); + if (camera.changed) { + this._emit(EVENTS.VIEW_CHANGE, { + yaw: camera.yaw, + pitch: camera.pitch, + zoom: camera.zoom, + quaternion: [camera.quaternion[0], camera.quaternion[1], camera.quaternion[2], camera.quaternion[3]] + }); + } + camera.onFrameRender(); + this._emit(EVENTS.RENDER); + }; + this._renderFrameOnDemand = delta => { + var _a; + const camera = this._camera; + const control = this._control; + const autoplay = this._autoplay; + const texture = (_a = this._projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (!this._initialized || !texture) return; + if (!camera.animation && !control.animating && !autoplay.playing && !texture.isVideo()) return; + this.renderFrame(delta); + }; + this._renderVRFrame = (_delta, frame) => { + const vr = this._vr; + const projection = this._projection; + const renderer = this._renderer; + if (!projection) return; + this._emit(EVENTS.BEFORE_RENDER); + renderer.renderVR(projection, vr, frame); + this._emit(EVENTS.RENDER); + }; + this._rootEl = getElement(root); + this._plugins = plugins; + this._initialized = false; + // Options + this._autoInit = autoInit; + this._autoResize = autoResize; + this._canvasSelector = canvasSelector; + this._useResizeObserver = useResizeObserver; + this._tabIndex = tabIndex; + this._debug = debug; + // Core components + const canvas = findCanvas(this._rootEl, canvasSelector); + this._renderer = new WebGLRenderer(canvas, debug); + this._camera = new Camera({ + initialYaw, + initialPitch, + initialZoom, + fov, + yawRange, + pitchRange, + zoomRange + }); + this._control = new PanoControl(canvas, this._camera, { + useGrabCursor, + scrollable, + wheelScrollable, + disableContextMenu, + rotate, + zoom, + gyro + }); + this._animator = new FrameAnimator(maxDeltaTime); + this._autoplay = new Autoplay(this, canvas, autoplay); + this._projection = projection; + this._autoResizer = new AutoResizer(useResizeObserver, () => this.resize()); + this._vr = new XRManager(this._renderer.ctx); + this._hotspot = new HotspotRenderer(this._rootEl, this._renderer, hotspot); + this._addEventHandlers(on); + if (projection && autoInit) { + this.init(); + } + } + /** + * Destroy instance and release all resources. + * @ko 인스턴스를 제거하고 모든 리소스를 해제합니다. + * @since 4.0.0 + */ + destroy() { + this._camera.destroy(); + this._animator.stop(); + this._renderer.destroy(); + this._control.destroy(); + this._autoResizer.disable(); + if (this._projection) { + this._projection.releaseAllResources(this._renderer.ctx); + this._projection = null; + } + this._plugins.forEach(plugin => plugin.destroy(this)); + this._initialized = false; + } + /** + * Initialize inner components and load projection src. + * @ko 내부 컴포넌트들을 초기화하고 프로젝션 소스를 로드합니다. + * @since 4.0.0 + */ + init() { + return __awaiter(this, void 0, void 0, function* () { + if (!this._projection) { + throw new View360Error(ERROR.MESSAGES.PROVIDE_PROJECTION_FIRST, ERROR.CODES.PROVIDE_PROJECTION_FIRST); + } + const renderer = this._renderer; + const camera = this._camera; + const control = this._control; + const animator = this._animator; + const hotspot = this._hotspot; + const projection = this._projection; + const canvas = renderer.canvas; + this._bindComponentEvents(); + renderer.ctx.init(); + this._resizeComponents(); + camera.updateMatrix(); + if (this._autoResize) { + this._autoResizer.enable(canvas); + } + if (!this._autoplay.enableBlocked) { + this._autoplay.enable(); + } + this._plugins.forEach(plugin => { + plugin.init(this); + }); + const texture = yield this._loadTexture(projection); + this._applyProjection(projection, texture, null); + hotspot.refresh(); + animator.start(this._renderFrameOnDemand); + yield control.enable(); + if (this._tabIndex != null && !canvas.hasAttribute("tabIndex")) { + canvas.tabIndex = this._tabIndex; + } + this._initialized = true; + this.renderFrame(0); + this._emit(EVENTS.READY); + }); + } + /** + * Load new panorama image/video and display it. + * This will {@link View360#init init()} View360 if it's not initialized yet. + * @ko 새로운 파노라마 이미지 혹은 비디오를 로드하고 표시합니다. + * 만약 View360이 아직 초기화되지 않았다면, {@link View360#init init()}을 호출합니다. + * @param projection - Projection & video options for new source. {@ko 새로운 파노라마 이미지/비디오에 적용할 옵션들} + * @returns `Promise` if load was successful. {@ko 프로젝션 로드에 성공했을 경우 `Promise`를 반환합니다. } + * @since 4.0.0 + * @example + * ```ts + * // Change to video + * viewer.load({ + * src: "URL_TO_NEW_VIDEO", + * video: true + * }); + * ``` + */ + load(projection) { + return __awaiter(this, void 0, void 0, function* () { + if (!projection) return false; + if (this._initialized) { + const texture = yield this._loadTexture(projection); + this._applyProjection(projection, texture, this._projection); + this.renderFrame(0); + } else { + // Should update internal options before init + this._projection = projection; + this.init(); + } + return true; + }); + } + /** + * Refresh component's size by current + * @ko View360이 내부적으로 캐시하고 있는 엘리먼트 크기를 현재 크기로 갱신합니다. + * @since 4.0.0 + */ + resize() { + if (!this._initialized) return; + this._resizeComponents(); + // To prevent flickering, render immediately after resizing components + this.renderFrame(0); + const { + width, + height + } = this._renderer; + this._emit(EVENTS.RESIZE, { + width, + height + }); + } + /** + * Add new plugins + * @ko 새로운 플러그인을 추가합니다. + * @param plugins Plugins to add {@ko 추가할 플러그인들} + * @see View360Options#plugins + * @since 4.0.0 + * @example + * ```ts + * // Add a single plugin + * viewer.addPlugins(new ControlBar()); + * + * // Add multiple plugins + * viewer.addPlugins(new ControlBar(), new LoadingSpinner()); + * ``` + */ + addPlugins(...plugins) { + if (this._initialized) { + plugins.forEach(plugin => { + plugin.init(this); + }); + } + this._plugins.push(...plugins); + } + /** + * Remove plugins. + * @ko 플러그인을 제거합니다. + * @param plugins Plugins to remove {@ko 제거할 플러그인들} + * @since 4.0.0 + * @example + * ```ts + * // Remove a single plugin + * viewer.removePlugins(plugin1); + * + * // Remove multiple plugins + * viewer.removePlugins(plugin2, plugin3); + * ``` + */ + removePlugins(...plugins) { + plugins.forEach(plugin => { + const pluginIdx = this._plugins.indexOf(plugin); + if (pluginIdx < 0) return; + plugin.destroy(this); + this._plugins.splice(pluginIdx, 1); + }); + } + _emit(eventName, ...params) { + const evtParams = params ? params[0] : {}; + this.trigger(eventName, Object.assign({ + type: eventName, + target: this + }, evtParams)); + } + _applyProjection(projection, texture, prevProjection) { + const camera = this._camera; + const control = this._control; + const renderer = this._renderer; + // Remove previous projection + if (prevProjection) { + prevProjection.releaseAllResources(this._renderer.ctx); + } + projection.applyTexture(renderer.ctx, texture); + projection.updateCamera(camera); + projection.updateControl(control); + this._projection = projection; + this._emit(EVENTS.PROJECTION_CHANGE, { + projection + }); + } + _loadTexture(projection) { + return __awaiter(this, void 0, void 0, function* () { + const contentLoader = new TextureLoader(); + const { + src, + video + } = projection; + this._emit(EVENTS.LOAD_START, { + src, + video + }); + const texture = yield contentLoader.load(src, video); + this._emit(EVENTS.LOAD, { + src, + video + }); + return texture; + }); + } + _resizeComponents() { + const renderer = this._renderer; + const camera = this._camera; + const control = this._control; + renderer.resize(); + camera.resize(renderer.width, renderer.height); + control.resize(renderer.width, renderer.height); + } + _addEventHandlers(events) { + // Bind option "on" + Object.keys(events).forEach(evtName => { + this.on(evtName, events[evtName]); + }); + } + _bindComponentEvents() { + // Bind internal component events + const root = this._rootEl; + const control = this._control; + const animator = this._animator; + const renderer = this._renderer; + const vr = this._vr; + const controlEventsToPropagate = [CONTROL_EVENTS.STATIC_CLICK, CONTROL_EVENTS.INPUT_START, CONTROL_EVENTS.INPUT_END]; + controlEventsToPropagate.forEach(evtName => { + control.rotate.on(evtName, evt => { + this._emit(evtName, evt); + }); + control.zoom.on(evtName, evt => { + this._emit(evtName, evt); + }); + }); + vr.on(EVENTS.VR_START, evt => { + root.classList.add(DEFAULT_CLASS.IN_VR); + animator.changeContext(evt.session); + animator.start(this._renderVRFrame); + this._emit(EVENTS.VR_START); + }); + vr.on(EVENTS.VR_END, () => { + root.classList.remove(DEFAULT_CLASS.IN_VR); + renderer.ctx.useDefaultFrameBuffer(); + animator.changeContext(window); + animator.start(this._renderFrameOnDemand); + this.resize(); + this._emit(EVENTS.VR_END); + }); + } + } + /** + * Current version string of the View360 + * @ko View360의 현재 버젼 문자열 + * @since 4.0.0 + * @readonly + * @example + * ```ts + * // If the installed version of the View360 is v4.0.0, View360.VERSION is equal to "4.0.0" + * console.log(View360.VERSION) // 4.0.0 + * ``` + */ + View360.VERSION = "4.0.0-beta.4"; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Base class for 3D objects + * @ko 3D 오브젝트의 베이스 클래스 + * @since 4.0.0 + * @internal + */ + class Object3D { + /** + * Create new instance. + * @ko 새로운 인스턴스를 생성합니다. + */ + constructor() { + this.matrix = glMatrix.mat4.create(); + this.rotation = glMatrix.quat.create(); + this.position = glMatrix.vec3.fromValues(0, 0, 0); + this.scale = glMatrix.vec3.fromValues(1, 1, 1); + } + /** + * Update local matrix of the object. + * @ko 오브젝트의 local matrix를 갱신합니다. + * @since 4.0.0 + */ + updateMatrix() { + glMatrix.mat4.fromRotationTranslationScale(this.matrix, this.rotation, this.position, this.scale); + } + } + + /** + * A plugin that displays loading spinner while loading the projection. + * @ko 프로젝션 로딩중에 로딩 스피너를 보여주는 플러그인 + * @since 4.0.0 + * @category Plugin + */ + class LoadingSpinner { + /** + * Create a new instance of LoadingSpinner. {@ko LoadingSpinner의 새 인스턴스를 생성합니다.} + * @param options Options {@ko 옵션들} + */ + constructor({ + className = {} + } = {}) { + this._startLoading = ({ + target: viewer + }) => { + viewer.rootEl.appendChild(this._container); + if (viewer.initialized) { + viewer.once(EVENTS.LOAD, this._detachElements); + } else { + viewer.once(EVENTS.READY, this._detachElements); + } + }; + this._detachElements = ({ + target: viewer + }) => { + const container = this._container; + if (!container) return; + if (container.parentElement === viewer.rootEl) { + viewer.rootEl.removeChild(container); + } + }; + this.className = className; + this._container = this._createElements(); + } + init(viewer) { + viewer.on(EVENTS.LOAD_START, this._startLoading); + } + destroy(viewer) { + viewer.off(EVENTS.LOAD_START, this._startLoading); + this._detachElements({ + target: viewer + }); + } + _createElements() { + const className = Object.assign(Object.assign({}, this.className), LoadingSpinner.DEFAULT_CLASS); + const container = createElement(className.CONTAINER); + const ring = createElement(className.RING); + container.appendChild(ring); + return container; + } + } + /** + * Default class names that LoadingSpinner uses + * @ko LoadingSpinner가 사용하는 디폴트 클래스 이름 + * @since 4.0.0 + */ + LoadingSpinner.DEFAULT_CLASS = { + /** + * A class name for the container element + * @ko 컨테이너 엘리먼트의 클래스 이름 + * @since 4.0.0 + */ + CONTAINER: "view360-spinner", + /** + * A class name for the spinning ring element + * @ko 돌아가는 링 엘리먼트의 클래스 이름 + * @since 4.0.0 + */ + RING: "view360-spinner-ring" + }; + + /** + * Interface of the ControlBar items + * @ko 컨트롤바 아이템의 인터페이스 + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class ControlBarItem { + /** + * Create new instance of the ControlBarItem + * @ko ControlBarItem의 새로운 인스턴스를 생성합니다. + * @param options Options {@ko 옵션들} + */ + constructor(options) { + this.position = options.position; + this.order = options.order; + } + } + + const CONTROL_BAR_DEFAULT_CLASS = { + CONTROLS_ROOT: "view360-controls", + CONTROLS_BG: "view360-controls-background", + CONTROLS_MAIN: "view360-controls-main", + CONTROLS_TOP: "view360-controls-top", + CONTROLS_BOTTOM: "view360-controls-bottom", + CONTROLS_MID: "view360-controls-mid", + CONTROLS_LEFT: "view360-controls-left", + CONTROLS_RIGHT: "view360-controls-right", + CONTROLS_FLOAT_LEFT: "view360-controls-float-left", + CONTROLS_FLOAT_RIGHT: "view360-controls-float-right", + CONTROLS_BUTTON: "view360-controls-button", + PROGRESS_ROOT: "view360-controls-progress", + VOLUME_ROOT: "view360-controls-volume", + RANGE_ROOT: "view360-range", + RANGE_TRACK: "view360-range-track", + RANGE_THUMB: "view360-range-thumb", + RANGE_FILLER: "view360-range-filler", + PLAY_BUTTON: "view360-controls-play", + PAUSE_BUTTON: "view360-controls-pause", + UNMUTED_BUTTON: "view360-controls-unmuted", + MUTED_BUTTON: "view360-controls-muted", + FULLSCREEN_BUTTON: "view360-controls-fullscreen", + FULLSCREEN_EXIT_BUTTON: "view360-controls-fullscreen-exit", + VR_BUTTON: "view360-controls-vr", + GYRO_ENABLED: "view360-controls-gyro-enabled", + GYRO_DISABLED: "view360-controls-gyro-disabled", + VIDEO_TIME_DISPLAY: "view360-controls-time", + PIEVIEW_ROOT: "view360-controls-pie", + FIXED: "view360-controls-fixed", + UNAVAILABLE: "view360-controls-unavailable", + HIDDEN: "view360-controls-hidden" + }; + const CONTROL_BAR_ITEM_POSITION = { + /** + * Place control bar item floating at top-left corner + * @ko 아이템을 왼쪽 위 구석에 표시합니다. + * @since 4.0.0 + */ + TOP_LEFT: "top-left", + /** + * Place control bar item floating at top-right corner + * @ko 아이템을 오른쪽 위 구석에 표시합니다. + * @since 4.0.0 + */ + TOP_RIGHT: "top-right", + /** + * Place control bar item at upper block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 위쪽 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_TOP: "main-top", + /** + * Place control bar item at lower block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 하단 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_BOTTOM: "main-bottom", + /** + * Place control bar item at center-left block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 왼쪽 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_LEFT: "main-left", + /** + * Place control bar item at center-right block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 오른쪽 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_RIGHT: "main-right" + }; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class RangeControl extends Component__default["default"] { + /** + * + */ + constructor() { + super(); + this._onHold = ({ + srcEvent, + isTouch + }) => { + var _a; + const bbox = this._bbox; + if (!bbox) return; + const x = isTouch ? srcEvent.touches[0].pageX : srcEvent.pageX; + const elX = bbox.x + ((_a = window.scrollX) !== null && _a !== void 0 ? _a : window.pageXOffset); + const clamepdX = clamp(x, elX, elX + bbox.width); + const progress = (clamepdX - elX) / bbox.width; + this._motion.reset(clamepdX); + this.thumbEl.classList.add(this._fixedClass); + this.trigger(CONTROL_EVENTS.INPUT_START, progress); + }; + this._onChange = ({ + delta + }) => { + var _a; + const motion = this._motion; + const bbox = this._bbox; + if (!bbox) return; + motion.setNewEndByDelta(delta.x); + motion.update(1); + const elX = bbox.x + ((_a = window.scrollX) !== null && _a !== void 0 ? _a : window.pageXOffset); + const clampedX = clamp(motion.val, elX, elX + bbox.width); + const progress = (clampedX - elX) / bbox.width; + this.trigger(CONTROL_EVENTS.CHANGE, progress); + }; + this._onRelease = () => { + const bbox = this._bbox; + if (!bbox) return; + this.thumbEl.classList.remove(this._fixedClass); + this.trigger(CONTROL_EVENTS.INPUT_END); + }; + const root = document.createElement(EL_DIV); + const track = document.createElement(EL_DIV); + const thumb = document.createElement(EL_DIV); + const filler = document.createElement(EL_DIV); + root.draggable = false; + track.appendChild(filler); + track.appendChild(thumb); + root.appendChild(track); + this.rootEl = root; + this.trackEl = track; + this.thumbEl = thumb; + this.fillerEl = filler; + this._mouseInput = new MouseInput(); + this._touchInput = new TouchInput(); + this._motion = new Motion({ + duration: 1, + range: INFINITE_RANGE, + easing: x => x + }); + this._bbox = { + x: 0, + y: 0, + width: 0, + height: 0, + left: 0, + right: 0, + bottom: 0, + top: 0 + }; + this._fixedClass = CONTROL_BAR_DEFAULT_CLASS.FIXED; + } + init(className) { + const mouseInput = this._mouseInput; + const touchInput = this._touchInput; + this.rootEl.classList.add(className.RANGE_ROOT); + this.trackEl.classList.add(className.RANGE_TRACK); + this.thumbEl.classList.add(className.RANGE_THUMB); + this.fillerEl.classList.add(className.RANGE_FILLER); + this._fixedClass = className.FIXED; + mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onHold); + touchInput.on(CONTROL_EVENTS.INPUT_START, this._onHold); + mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + touchInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + mouseInput.enable(this.rootEl); + touchInput.enable(this.rootEl); + this.resize(); + } + destroy() { + const mouseInput = this._mouseInput; + const touchInput = this._touchInput; + this.rootEl.className = ""; + this.trackEl.className = ""; + this.thumbEl.className = ""; + this.fillerEl.className = ""; + mouseInput.off(); + touchInput.off(); + mouseInput.disable(); + touchInput.disable(); + } + resize() { + this._bbox = this.trackEl.getBoundingClientRect(); + } + updateStyle(progress) { + const width = this._bbox.width; + const clampedProgress = clamp(progress, 0, 1); + this.fillerEl.style.width = `${clampedProgress * 100}%`; + this.thumbEl.style.transform = `translateX(${clampedProgress * width}px)`; + } + } + + /** + * Show video progress bar. + * @ko 비디오의 프로그레스 바를 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class ProgressBar extends ControlBarItem { + get element() { + return this._rangeControl.rootEl; + } + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_TOP, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onResize = () => { + this._rangeControl.resize(); + }; + this._onTimeUpdate = () => { + const video = this._video; + if (!video) return; + this._currentTime = video.source.currentTime; + this._rangeControl.updateStyle(this._currentTime / this._duration); + }; + this._onDurationChange = () => { + const video = this._video; + if (!video) return; + this._duration = video.source.duration; + this._rangeControl.updateStyle(this._currentTime / this._duration); + }; + this._onHold = progress => { + const video = this._video; + const controlBar = this._controlBar; + if (!video || !controlBar) return; + const paused = video.isPaused(); + video.source.pause(); + const time = video.source.duration * progress; + video.source.currentTime = time; + video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { + detail: { + time + } + })); + controlBar.rootEl.classList.add(controlBar.className.FIXED); + this._wasPaused = !this._playPromise && paused; + }; + this._onControl = progress => { + const video = this._video; + if (!video) return; + const time = video.source.duration * progress; + video.source.currentTime = time; + video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { + detail: { + time + } + })); + }; + this._onRelease = () => { + const video = this._video; + const controlBar = this._controlBar; + if (video && controlBar) { + if (!this._wasPaused && !this._playPromise) { + this._playPromise = video.source.play().catch(() => void 0); + // This should not be chained + this._playPromise.then(() => { + this._playPromise = null; + }); + controlBar.rootEl.classList.remove(controlBar.className.FIXED); + } + } + this._wasPaused = false; + }; + this.position = position; + this.order = order; + this._controlBar = null; + this._rangeControl = new RangeControl(); + this._video = null; + this._wasPaused = false; + this._currentTime = 0; + this._duration = 0; + this._playPromise = null; + } + init(viewer, controlBar) { + var _a; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const element = this.element; + const rangeControl = this._rangeControl; + const unavailableClass = controlBar.className.UNAVAILABLE; + if (!video || !video.isVideo()) { + element.classList.add(unavailableClass); + return; + } + element.classList.remove(unavailableClass); + element.classList.add(controlBar.className.PROGRESS_ROOT); + viewer.on(EVENTS.RESIZE, this._onResize); + video.source.addEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.addEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate); + rangeControl.init(controlBar.className); + rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold); + rangeControl.on(CONTROL_EVENTS.CHANGE, this._onControl); + rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + this._video = video; + this._currentTime = video.source.currentTime; + this._duration = video.source.duration; + this._controlBar = controlBar; + rangeControl.updateStyle(this._currentTime / this._duration); + } + destroy(viewer) { + const video = this._video; + viewer.off(EVENTS.RESIZE, this._onResize); + if (video) { + video.source.removeEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.removeEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate); + } + this._rangeControl.destroy(); + this._video = null; + this._playPromise = null; + } + } + + /** + * Show video play / pause button. + * @ko 비디오 재생 / 일시정지 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class PlayButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const video = this._video; + if (!video) return; + if (this._paused) { + video.source.play(); + } else { + video.source.pause(); + } + }; + this._onPlay = () => { + if (!this._controlBar) return; + const element = this.element; + const className = this._controlBar.className; + element.classList.add(className.PAUSE_BUTTON); + element.classList.remove(className.PLAY_BUTTON); + element.title = "Pause Video"; + this._paused = false; + }; + this._onPause = () => { + if (!this._controlBar) return; + const element = this.element; + const className = this._controlBar.className; + element.classList.add(className.PLAY_BUTTON); + element.classList.remove(className.PAUSE_BUTTON); + element.title = "Play Video"; + this._paused = true; + }; + this.element = document.createElement(EL_BUTTON); + this._video = null; + this._paused = true; + this._controlBar = null; + } + init(viewer, controlBar) { + var _a; + const element = this.element; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const className = controlBar.className; + const unavailableClass = className.UNAVAILABLE; + if (!video || !video.isVideo()) { + element.classList.add(unavailableClass); + return; + } + element.classList.add(className.CONTROLS_BUTTON); + element.classList.remove(unavailableClass); + const paused = video.isPaused(); + this._video = video; + this._paused = paused; + this._controlBar = controlBar; + if (paused) { + this._onPause(); + } else { + this._onPlay(); + } + element.addEventListener(EVENTS$1.CLICK, this._onClick); + video.source.addEventListener(EVENTS$1.VIDEO_PLAY, this._onPlay); + video.source.addEventListener(EVENTS$1.VIDEO_PAUSE, this._onPause); + } + destroy() { + const video = this._video; + const element = this.element; + if (!video) return; + element.className = ""; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + video.source.removeEventListener(EVENTS$1.VIDEO_PLAY, this._onPlay); + video.source.removeEventListener(EVENTS$1.VIDEO_PAUSE, this._onPause); + this._video = null; + this._paused = true; + this._controlBar = null; + } + } + + /** + * Show video volume control. + * @ko 비디오 볼륨 조절 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class VolumeControl extends ControlBarItem { + get element() { + return this._rootEl; + } + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onResize = () => { + this._rangeControl.resize(); + this._updateDisplay(); + }; + this._onClick = () => { + const video = this._video; + if (!video || this._rootEl.disabled) return; + video.source.muted = !video.source.muted; + }; + this._onVolumeChange = () => { + const button = this._buttonEl; + const video = this._video; + const controlBar = this._controlBar; + if (!video || !controlBar) return; + const className = controlBar.className; + if (video.source.muted || video.source.volume === 0) { + button.classList.add(className.MUTED_BUTTON); + button.classList.remove(className.UNMUTED_BUTTON); + } else { + button.classList.add(className.UNMUTED_BUTTON); + button.classList.remove(className.MUTED_BUTTON); + } + this._updateDisplay(); + }; + this._onHold = progress => { + const video = this._video; + const controlBar = this._controlBar; + if (!video || !controlBar) return; + const className = controlBar.className; + video.source.volume = progress; + this._rootEl.classList.add(className.FIXED); + controlBar.containerEl.classList.add(className.FIXED); + this._updateDisplay(); + }; + this._onChange = progress => { + const video = this._video; + if (!video) return; + video.source.volume = progress; + if (progress > 0) { + video.source.muted = false; + } else { + video.source.muted = true; + } + this._updateDisplay(); + }; + this._onRelease = () => { + const controlBar = this._controlBar; + if (!controlBar) return; + const className = controlBar.className; + this._rootEl.classList.remove(className.FIXED); + controlBar.containerEl.classList.remove(className.FIXED); + }; + this._updateDisplay = () => { + const video = this._video; + const root = this._rootEl; + if (!video) return; + if (!video.hasAudio()) { + root.disabled = true; + return; + } + root.disabled = false; + const volume = video.source.muted ? 0 : video.source.volume; + this._rangeControl.updateStyle(volume); + }; + this._controlBar = null; + this._rangeControl = new RangeControl(); + this._createElements(); + this._video = null; + } + init(viewer, controlBar) { + var _a; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const root = this._rootEl; + const button = this._buttonEl; + const rangeControl = this._rangeControl; + const className = controlBar.className; + const unavailableClass = className.UNAVAILABLE; + if (!video || !video.isVideo()) { + root.classList.add(unavailableClass); + return; + } + root.classList.remove(unavailableClass); + root.classList.add(className.CONTROLS_BUTTON); + root.classList.add(className.VOLUME_ROOT); + button.classList.add(className.CONTROLS_BUTTON); + if (video.source.muted) { + button.classList.add(className.MUTED_BUTTON); + } else { + button.classList.add(className.UNMUTED_BUTTON); + } + viewer.on(EVENTS.RESIZE, this._onResize); + root.addEventListener(EVENTS$1.TRANSITION_END, this._onResize); + button.addEventListener(EVENTS$1.CLICK, this._onClick); + video.source.addEventListener(EVENTS$1.VIDEO_VOLUME_CHANGE, this._onVolumeChange); + video.source.addEventListener(EVENTS$1.VIDEO_LOADED_DATA, this._updateDisplay); + video.source.addEventListener(EVENTS$1.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay); + rangeControl.init(className); + rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold); + rangeControl.on(CONTROL_EVENTS.CHANGE, this._onChange); + rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + this._controlBar = controlBar; + this._video = video; + this._updateDisplay(); + } + destroy(viewer) { + const video = this._video; + const button = this._buttonEl; + const root = this._rootEl; + root.className = ""; + button.className = ""; + viewer.off(EVENTS.RESIZE, this._onResize); + root.removeEventListener(EVENTS$1.TRANSITION_END, this._onResize); + button.removeEventListener(EVENTS$1.CLICK, this._onClick); + if (video) { + video.source.removeEventListener(EVENTS$1.VIDEO_VOLUME_CHANGE, this._onVolumeChange); + video.source.removeEventListener(EVENTS$1.VIDEO_LOADED_DATA, this._updateDisplay); + video.source.removeEventListener(EVENTS$1.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay); + } + this._controlBar = null; + this._rangeControl.destroy(); + this._video = null; + } + _createElements() { + const root = document.createElement(EL_BUTTON); + const buttonEl = document.createElement(EL_DIV); + root.appendChild(this._rangeControl.rootEl); + root.appendChild(buttonEl); + root.title = "Toggle Mute"; + this._rootEl = root; + this._buttonEl = buttonEl; + } + } + + /** + * Show fullscreen enter / exit button. + * @ko 풀스크린 진입 / 해제 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class FullscreenButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const target = this._targetEl; + if (!target) return; + if (isFullscreen()) { + this._exitFullscreen(); + } else { + this._requestFullscreen(target); + } + }; + this._onFullscreenChange = () => { + const element = this.element; + const controlBar = this._controlBar; + if (!controlBar) return; + const className = controlBar.className; + if (isFullscreen()) { + element.classList.add(className.FULLSCREEN_EXIT_BUTTON); + element.classList.remove(className.FULLSCREEN_BUTTON); + } else { + element.classList.add(className.FULLSCREEN_BUTTON); + element.classList.remove(className.FULLSCREEN_EXIT_BUTTON); + } + }; + this.element = document.createElement(EL_BUTTON); + this.element.title = "Toggle Fullscreen"; + this._controlBar = null; + this._targetEl = null; + } + init(viewer, controlBar) { + const element = this.element; + const className = controlBar.className; + if (!this._fullscreenAvailable()) { + element.classList.add(className.UNAVAILABLE); + return; + } + element.classList.add(className.CONTROLS_BUTTON); + element.classList.remove(className.UNAVAILABLE); + element.addEventListener(EVENTS$1.CLICK, this._onClick); + this._addFullscreenHandlers(); + if (isFullscreen()) { + element.classList.add(className.FULLSCREEN_EXIT_BUTTON); + } else { + element.classList.add(className.FULLSCREEN_BUTTON); + } + this._controlBar = controlBar; + this._targetEl = viewer.rootEl; + } + destroy() { + const element = this.element; + element.className = ""; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + this._removeFullscreenHandlers(); + this._controlBar = null; + this._targetEl = null; + } + _fullscreenAvailable() { + return FULLSCREEN_REQUEST.some(key => !!document[key]); + } + _requestFullscreen(el) { + for (const key of FULLSCREEN_REQUEST) { + const request = el[key]; + if (request) { + request.call(el); + return; + } + } + } + _exitFullscreen() { + for (const key of FULLSCREEN_EXIT) { + const exit = document[key]; + if (exit) { + exit.call(document); + return; + } + } + } + _addFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.addEventListener(evtName, this._onFullscreenChange); + }); + } + _removeFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.removeEventListener(evtName, this._onFullscreenChange); + }); + } + } + + /** + * Show video current / total time. + * @ko 비디오의 현재 / 총 재생시간을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class VideoTime extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onTimeUpdate = () => { + const video = this._video; + if (!video) return; + this._currentTime = video.source.currentTime; + this._updateDisplay(); + }; + this._onDurationChange = () => { + const video = this._video; + if (!video) return; + this._duration = video.source.duration; + this._updateDisplay(); + }; + this._onCustomTimeChange = evt => { + this._currentTime = evt.detail.time; + this._updateDisplay(); + }; + this.element = document.createElement(EL_DIV); + this._video = null; + this._currentTime = 0; + this._duration = 0; + } + init(viewer, controlBar) { + var _a; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const element = this.element; + const className = controlBar.className; + if (!video || !video.isVideo()) { + element.classList.add(className.UNAVAILABLE); + return; + } + element.classList.add(className.VIDEO_TIME_DISPLAY); + element.classList.remove(className.UNAVAILABLE); + video.source.addEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.addEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange); + this._video = video; + this._currentTime = video.source.currentTime; + this._duration = video.source.duration; + this._updateDisplay(); + } + destroy() { + const video = this._video; + if (!video) return; + this.element.className = ""; + video.source.removeEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.removeEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange); + this._video = null; + } + _updateDisplay() { + const time = this._currentTime; + const timeMinute = Math.floor(time / 60); + const timeSeconds = Math.floor(time - timeMinute * 60); + const timeSecondsFormatted = timeSeconds < 10 ? `0${timeSeconds}` : timeSeconds; + const duration = this._duration; + const durationMinute = Math.floor(duration / 60); + const durationSeconds = Math.floor(duration - durationMinute * 60); + const durationSecondsFormatted = durationSeconds < 10 ? `0${durationSeconds}` : durationSeconds; + this.element.innerText = `${timeMinute}:${timeSecondsFormatted} / ${durationMinute}:${durationSecondsFormatted}`; + } + } + + /** + * Show camera direction/fov indicator. + * @ko 카메라가 향하는 방향 및 FOV를 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class PieView extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + resetCamera = true, + position = CONTROL_BAR_ITEM_POSITION.TOP_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const viewer = this._viewer; + const resetCamera = this.resetCamera; + if (!viewer || !resetCamera) return; + const { + yaw = viewer.initialYaw, + pitch = viewer.initialPitch, + zoom = viewer.initialZoom, + duration = 500 + } = getObjectOption(resetCamera); + viewer.camera.animateTo({ + yaw, + pitch, + zoom, + duration + }); + }; + this._updatePie = ({ + target: viewer + }) => { + const piePath = this._piePathEl; + const rangeCircle = this._rangeCircleEl; + const camera = viewer.camera; + const fov = camera.getHorizontalFov(); + const yawRange = camera.getYawRange(camera.zoom); + const halfFov = fov * 0.5; + const pieRadius = 24 * Math.PI; + const pieDeg = pieRadius * fov / 360; + const pieOffset = pieRadius * (camera.yaw + halfFov + 90) / 360; + piePath.setAttribute("stroke-dasharray", `${pieDeg} ${pieRadius - pieDeg}`); + piePath.setAttribute("stroke-dashoffset", `${pieOffset}`); + if (isFinite(yawRange.min) && isFinite(yawRange.max)) { + const radius = 45 * Math.PI; // 2 * PI * r + const min = (circulate(yawRange.min, -180, 180) - halfFov) / 360; + const max = (circulate(yawRange.max, -180, 180) + halfFov) / 360; + const rangeDiff = radius * Math.abs(max - min); + const offset = -radius * (min - 0.25); + rangeCircle.setAttribute("stroke-dasharray", `${rangeDiff} ${radius - rangeDiff}`); + rangeCircle.setAttribute("stroke-dashoffset", `${offset}`); + } else { + rangeCircle.setAttribute("stroke-dasharray", ""); + rangeCircle.setAttribute("stroke-dashoffset", ""); + } + }; + this.element = document.createElement(EL_DIV); + this.element.title = "Reset view"; + this.resetCamera = resetCamera; + this._createPieElements(); + this._viewer = null; + } + init(viewer, controlBar) { + const element = this.element; + if (!viewer.initialized) { + viewer.once(EVENTS.READY, this._updatePie); + } else { + this._updatePie({ + target: viewer + }); + } + const rootClass = controlBar.className.PIEVIEW_ROOT; + element.classList.add(rootClass); + if (this.resetCamera) { + element.addEventListener(EVENTS$1.CLICK, this._onClick); + } + viewer.on(EVENTS.VIEW_CHANGE, this._updatePie); + this._viewer = viewer; + } + destroy(viewer) { + const element = this.element; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + element.className = ""; + viewer.off(EVENTS.READY, this._updatePie); + viewer.off(EVENTS.VIEW_CHANGE, this._updatePie); + this._viewer = null; + } + _createPieElements() { + const root = this.element; + const pieSVG = document.createElementNS(SVG_NAMESPACE, "svg"); + pieSVG.setAttribute("viewBox", "0 0 48 48"); + pieSVG.setAttribute("width", "100%"); + pieSVG.setAttribute("height", "100%"); + const piePath = document.createElementNS(SVG_NAMESPACE, "circle"); + piePath.setAttribute("stroke", "currentColor"); + piePath.setAttribute("fill", "transparent"); + piePath.setAttribute("cx", "24"); + piePath.setAttribute("cy", "24"); + piePath.setAttribute("r", "12"); + piePath.setAttribute("stroke-width", "24"); + pieSVG.appendChild(piePath); + const rangeCircle = document.createElementNS(SVG_NAMESPACE, "circle"); + rangeCircle.setAttribute("stroke", "currentColor"); + rangeCircle.setAttribute("fill", "transparent"); + rangeCircle.setAttribute("cx", "24"); + rangeCircle.setAttribute("cy", "24"); + rangeCircle.setAttribute("r", "22.5"); + rangeCircle.setAttribute("stroke-width", "3"); + pieSVG.appendChild(rangeCircle); + root.appendChild(pieSVG); + this._piePathEl = piePath; + this._rangeCircleEl = rangeCircle; + } + } + + /** + * Show VR enter button. + * @ko VR 진입 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class VRButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const viewer = this._viewer; + if (!viewer) return; + viewer.vr.enter(); + }; + this.element = document.createElement(EL_BUTTON); + this.element.title = "Enter VR"; + this._viewer = null; + } + init(viewer, controlBar) { + const element = this.element; + const className = controlBar.className; + element.classList.add(className.UNAVAILABLE); + element.classList.add(className.VR_BUTTON); + element.classList.add(className.CONTROLS_BUTTON); + viewer.vr.isAvailable().then(available => { + if (available) { + element.classList.remove(className.UNAVAILABLE); + } + }); + element.addEventListener(EVENTS$1.CLICK, this._onClick); + this._viewer = viewer; + } + destroy() { + const element = this.element; + element.className = ""; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + this._viewer = null; + } + } + + /** + * Show gyroscope control enable / disable button + * @ko 자이로스코프 컨트롤 활성화 / 비활성화 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class GyroButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const viewer = this._viewer; + const controlBar = this._controlBar; + if (!viewer || !controlBar) return; + const gyroControl = viewer.control.gyro; + if (gyroControl.enabled) { + gyroControl.disable(); + } else { + GyroControl.requestSensorPermission().then(available => { + if (available) { + gyroControl.enable(); + } else { + this.element.classList.add(controlBar.className.UNAVAILABLE); + } + }); + } + }; + this._updateStyle = () => { + const element = this.element; + const viewer = this._viewer; + const controlBar = this._controlBar; + if (!viewer || !controlBar) return; + const gyroControl = viewer.control.gyro; + const className = controlBar.className; + if (gyroControl.enabled) { + element.classList.add(className.GYRO_ENABLED); + element.classList.remove(className.GYRO_DISABLED); + } else { + element.classList.add(className.GYRO_DISABLED); + element.classList.remove(className.GYRO_ENABLED); + } + }; + this.element = document.createElement(EL_DIV); + this.element.title = "Toggle gyroscope control"; + } + init(viewer, controlBar) { + const element = this.element; + const className = controlBar.className; + element.addEventListener(EVENTS$1.CLICK, this._onClick); + element.classList.add(className.CONTROLS_BUTTON); + element.classList.add(className.UNAVAILABLE); + const enableButton = () => { + element.classList.remove(className.UNAVAILABLE); + viewer.control.gyro.on(CONTROL_EVENTS.ENABLE, this._updateStyle); + viewer.control.gyro.on(CONTROL_EVENTS.DISABLE, this._updateStyle); + }; + if (sensorCanBeEnabledIOS()) { + enableButton(); + } else { + GyroControl.isAvailable().then(available => { + if (!available) return; + enableButton(); + }); + } + this._controlBar = controlBar; + this._viewer = viewer; + this._updateStyle(); + } + destroy(viewer) { + const element = this.element; + viewer.control.gyro.off(CONTROL_EVENTS.ENABLE, this._updateStyle); + viewer.control.gyro.off(CONTROL_EVENTS.DISABLE, this._updateStyle); + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + element.className = ""; + this._controlBar = null; + this._viewer = null; + } + } + + class AutoHide { + get enabled() { + return !!this._targetEl; + } + get hidden() { + return this._controlBar.containerEl.classList.contains(this._hiddenClass); + } + get _hiddenClass() { + return this._controlBar.className.HIDDEN; + } + get _fixedClass() { + return this._controlBar.className.FIXED; + } + constructor(controlBar, { + initialDelay = 3000, + delay = 0, + idleDelay: activationDelay = 3000 + }) { + this._onMouseEnter = () => { + this._isCursorInside = true; + this.show(); + }; + this._onMouseLeave = () => { + this._isCursorInside = false; + this._hideAfterDelay(); + }; + this._onMouseMove = () => { + if (!this._isFullscreen) return; + this.showTemporaliy(); + }; + this._onHold = evt => { + this._isGrabbing = true; + if (evt.pointerType === "mouse") { + this._isCursorInside = true; + } + window.addEventListener(EVENTS$1.MOUSE_UP, this._onRelease); + this.show(); + }; + this._onRelease = () => { + this._isGrabbing = false; + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onRelease); + this._hideAfterDelay(); + }; + this._onVideoPlay = () => { + const root = this._targetEl; + if (!root) return; + this._controlBar.containerEl.classList.remove(this._fixedClass); + }; + this._onVideoPause = () => { + const root = this._targetEl; + if (!root) return; + this._controlBar.containerEl.classList.add(this._fixedClass); + }; + this._onFullscreenChange = () => { + this._isFullscreen = isFullscreen(); + if (this._isFullscreen) { + this._hideAfterDelay(); + } + }; + this._controlBar = controlBar; + this._initialDelay = initialDelay; + this._delay = delay; + this._idleDelay = activationDelay; + this._timer = -1; + this._isCursorInside = false; + this._isGrabbing = false; + this._isFullscreen = false; + this._video = null; + this._targetEl = null; + } + enable(viewer) { + var _a; + if (this._targetEl) { + this.disable(viewer); + } + const initialDelay = this._initialDelay; + const root = viewer.rootEl; + this._targetEl = viewer.rootEl; + this._timer = window.setTimeout(() => { + this.hide(); + }, initialDelay); + root.addEventListener(EVENTS$1.MOUSE_DOWN, this._onHold); + root.addEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter); + root.addEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove); + root.addEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave); + this._addFullscreenHandlers(); + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (!video || !video.isVideo()) { + return; + } + if (video.isPaused()) { + this._controlBar.containerEl.classList.add(this._fixedClass); + } + video.source.addEventListener(EVENTS$1.VIDEO_PLAY, this._onVideoPlay); + video.source.addEventListener(EVENTS$1.VIDEO_PAUSE, this._onVideoPause); + this._video = video; + } + disable(viewer) { + if (!this._targetEl) return; + const controlBar = this._controlBar; + const root = viewer.rootEl; + const video = this._video; + root.removeEventListener(EVENTS$1.MOUSE_DOWN, this._onHold); + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onRelease); + root.removeEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter); + root.removeEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove); + root.removeEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave); + this._removeFullscreenHandlers(); + window.clearTimeout(this._timer); + controlBar.containerEl.classList.remove(this._fixedClass); + if (video) { + video.source.removeEventListener(EVENTS$1.VIDEO_PLAY, this._onVideoPlay); + video.source.removeEventListener(EVENTS$1.VIDEO_PAUSE, this._onVideoPause); + } + this._isCursorInside = false; + this._isGrabbing = false; + this._video = null; + this._targetEl = null; + } + show() { + this._clearHideTimer(); + this._controlBar.containerEl.classList.remove(this._hiddenClass); + } + showTemporaliy() { + this.show(); + this._hideAfterDelay(this._idleDelay); + } + hide() { + this._clearHideTimer(); + this._controlBar.containerEl.classList.add(this._hiddenClass); + } + _clearHideTimer() { + if (this._timer) { + window.clearTimeout(this._timer); + this._timer = -1; + } + } + _hideAfterDelay(delay = this._delay) { + if (this._isGrabbing || !this._isFullscreen && this._isCursorInside) return; + this._clearHideTimer(); + if (delay <= 0) { + this.hide(); + } else { + this._timer = window.setTimeout(() => { + this.hide(); + }, delay); + } + } + _addFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.addEventListener(evtName, this._onFullscreenChange); + }); + } + _removeFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.removeEventListener(evtName, this._onFullscreenChange); + }); + } + } + + class VideoControl { + constructor() { + this._onKeyDown = event => { + const video = this._video; + if (!video) return; + event.preventDefault(); + event.stopPropagation(); + const videoEl = video.source; + const keyPressed = event.keyCode != null ? DIRECTION_KEY_CODE[event.keyCode] : DIRECTION_KEY_NAME[event.key]; + switch (keyPressed) { + case "LEFT": + case "RIGHT": + return this._changeVideoTime(videoEl, keyPressed === "RIGHT"); + case "UP": + case "DOWN": + return this._changeVideoVolume(videoEl, keyPressed === "UP"); + } + const spacePressed = event.keyCode === SPACE_KEY_CODE || event.key === SPACE_KEY_NAME; + if (spacePressed) { + this._toggleVideo(video); + } + }; + } + enable(root, video) { + this._video = video; + // capture is needed for resolving conflict with keyboard control + root.addEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown, true); + } + disable(root) { + this._video = null; + root.removeEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown, true); + } + _changeVideoTime(video, forward) { + const delta = forward ? 5 : -5; + video.currentTime += delta; + video.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { + detail: { + time: video.currentTime + } + })); + } + _changeVideoVolume(video, increase) { + const delta = increase ? 0.1 : -0.1; + if (video.muted) { + video.volume = clamp(delta, 0, 1); + } else { + video.volume = clamp(video.volume + delta, 0, 1); + } + if (video.volume > 0) { + video.muted = false; + } else { + video.muted = true; + } + } + _toggleVideo(video) { + if (video.isPaused()) { + video.source.play(); + } else { + video.source.pause(); + } + } + } + + /** + * A plugin that displays extra buttons & controls that controls {@link View360}. + * @ko {@link View360}에 부가적인 버튼과 컨트롤을 추가해주는 플러그인. + * @category Plugin + * @since 4.0.0 + */ + class ControlBar { + /** + * Root element of the control bar + * @ko 컨트롤바의 루트 엘리먼트 + * @since 4.0.0 + */ + get rootEl() { + return this._rootEl; + } + /** + * Container element of the control bar + * @ko 컨트롤바의 컨테이너 엘리먼트 + * @since 4.0.0 + */ + get containerEl() { + return this._containerEl; + } + /** + * Background element of the control bar + * @ko 컨트롤바의 배경 엘리먼트 + * @since 4.0.0 + */ + get backgroundEl() { + return this._bgEl; + } + /** + * Control bar's default items created by {@link ControlBarOptions} + * @ko 주어진 {@link ControlBarOptions}에 의해 생성된 디폴트 아이템들 + * @since 4.0.0 + */ + get items() { + return this._items; + } + /** + * Custom control bar items + * @ko 커스텀 컨트롤바 아이템들을 추가합니다. + * @since 4.0.0 + */ + get customItems() { + return this._customItems; + } + /** + * Create new instance of ControlBar. + * @ko ControlBar의 새 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + autoHide, + showBackground, + clickToPlay = true, + keyboardControls = true, + progressBar = true, + playButton = true, + volumeButton = true, + fullscreenButton = true, + videoTime = true, + pieView = true, + vrButton = true, + gyroButton = true, + className = {}, + customItems = [] + } = {}) { + var _a; + this._onStaticClick = ({ + target: viewer, + isTouch + }) => { + var _a; + const autoHider = this._autoHider; + if (isTouch) { + if (!autoHider.enabled) return; + if (autoHider.hidden) { + autoHider.showTemporaliy(); + } else { + autoHider.hide(); + } + } else { + if (!this.clickToPlay) return; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (!video || !video.isVideo()) return; + if (video.isPaused()) { + video.source.play(); + } else { + video.source.pause(); + } + } + }; + this._onNewSrcLoad = ({ + target: viewer + }) => { + const items = this._items; + this._updateBackground(viewer); + this._updateAutoHide(viewer); + this._updateKeyboardHandler(viewer); + Object.keys(items).forEach(key => { + const category = items[key]; + category.forEach(item => { + item.destroy(viewer, this); + item.init(viewer, this); + }); + }); + }; + this.autoHide = autoHide; + this.showBackground = showBackground; + this.clickToPlay = clickToPlay; + this.keyboardControls = keyboardControls; + this.progressBar = progressBar; + this.playButton = playButton; + this.volumeButton = volumeButton; + this.fullscreenButton = fullscreenButton; + this.videoTime = videoTime; + this.pieView = pieView; + this.vrButton = vrButton; + this.gyroButton = gyroButton; + this.className = Object.assign(Object.assign({}, ControlBar.DEFAULT_CLASS), className); + const rootClass = (_a = className.CONTROLS_ROOT) !== null && _a !== void 0 ? _a : ControlBar.DEFAULT_CLASS.CONTROLS_ROOT; + this._rootEl = createElement(rootClass); + this._createPositionWrappers(); + this._items = Object.keys(ControlBar.POSITION).reduce((items, key) => { + items[ControlBar.POSITION[key]] = []; + return items; + }, {}); + this._customItems = customItems; + this._autoHider = new AutoHide(this, getObjectOption(autoHide)); + this._videoControl = new VideoControl(); + customItems.forEach(item => { + this._items[item.position].push(item); + }); + } + init(viewer) { + const panoRoot = viewer.rootEl; + const controlsRoot = this._rootEl; + const defaultItems = this._createDefaultItems(); + this._updateBackground(viewer); + this._updateAutoHide(viewer); + this._updateKeyboardHandler(viewer); + panoRoot.appendChild(controlsRoot); + this._addItem(viewer, defaultItems); + this._addItem(viewer, this._customItems); + viewer.on(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad); + viewer.on(EVENTS.STATIC_CLICK, this._onStaticClick); + } + destroy(viewer) { + // Remove controls root from pano root + const panoRoot = viewer.rootEl; + const controlsRoot = this._rootEl; + const items = this._items; + if (controlsRoot.parentElement === panoRoot) { + panoRoot.removeChild(controlsRoot); + } + Object.keys(items).forEach(key => { + const category = items[key]; + category.forEach(item => { + item.destroy(viewer, this); + }); + items[key] = []; + }); + this._clearItemElements(); + this._autoHider.disable(viewer); + this._videoControl.disable(panoRoot); + viewer.off(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad); + viewer.off(EVENTS.STATIC_CLICK, this._onStaticClick); + } + _addItem(viewer, items) { + for (const item of items) { + const category = this._items[item.position]; + const wrapper = this._wrapperEl[item.position]; + const nextSiblingIndex = findIndex(category, sibling => sibling.order > item.order); + if (nextSiblingIndex >= 0) { + const nextSibling = category[nextSiblingIndex].element; + category.splice(nextSiblingIndex, 0, item); + wrapper.insertBefore(item.element, nextSibling); + } else { + category.push(item); + wrapper.appendChild(item.element); + } + item.init(viewer, this); + } + } + _createPositionWrappers() { + const className = Object.assign(Object.assign({}, ControlBar.DEFAULT_CLASS), this.className); + const rootEl = this._rootEl; + // BG & FLOATING CONTROLS + const backgroundEl = createElement(className.CONTROLS_BG); + const floatLeftEl = createElement(className.CONTROLS_FLOAT_LEFT); + const floatRightEl = createElement(className.CONTROLS_FLOAT_RIGHT); + rootEl.appendChild(floatLeftEl); + rootEl.appendChild(floatRightEl); + // BOTTOM CONTROLS + const container = createElement(className.CONTROLS_MAIN); + const topWrapper = createElement(className.CONTROLS_TOP); + const bottomWrapper = createElement(className.CONTROLS_BOTTOM); + const midWrapper = createElement(className.CONTROLS_MID); + const leftControlsWrapper = createElement(className.CONTROLS_LEFT); + const rightControlsWrapper = createElement(className.CONTROLS_RIGHT); + midWrapper.appendChild(leftControlsWrapper); + midWrapper.appendChild(rightControlsWrapper); + container.appendChild(backgroundEl); + container.appendChild(topWrapper); + container.appendChild(midWrapper); + container.appendChild(bottomWrapper); + rootEl.appendChild(container); + this._bgEl = backgroundEl; + this._containerEl = container; + this._wrapperEl = { + [ControlBar.POSITION.MAIN_TOP]: topWrapper, + [ControlBar.POSITION.MAIN_LEFT]: leftControlsWrapper, + [ControlBar.POSITION.MAIN_RIGHT]: rightControlsWrapper, + [ControlBar.POSITION.MAIN_BOTTOM]: bottomWrapper, + [ControlBar.POSITION.TOP_LEFT]: floatLeftEl, + [ControlBar.POSITION.TOP_RIGHT]: floatRightEl + }; + } + _clearItemElements() { + const wrappers = Object.keys(ControlBar.POSITION).map(key => ControlBar.POSITION[key]); + // Remove all elements inside wrappers + wrappers.forEach(wrapper => { + while (wrapper.firstChild) { + wrapper.removeChild(wrapper.firstChild); + } + }); + } + _updateAutoHide(viewer) { + var _a; + const autoHide = this.autoHide; + const autoHider = this._autoHider; + if (autoHide != null) { + if (autoHide) { + autoHider.enable(viewer); + } else { + autoHider.disable(viewer); + } + } else { + // Automatically choose whether to show background by content type + const texture = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (texture && texture.isVideo()) { + // Enable auto hide when content type is video + autoHider.enable(viewer); + } else { + autoHider.disable(viewer); + } + } + } + _updateBackground(viewer) { + var _a, _b; + const background = this._bgEl; + const showBackground = this.showBackground; + const hiddenClass = (_a = this.className.HIDDEN) !== null && _a !== void 0 ? _a : ControlBar.DEFAULT_CLASS.HIDDEN; + if (showBackground != null) { + if (showBackground) { + background.classList.remove(hiddenClass); + } else { + background.classList.add(hiddenClass); + } + } else { + // Automatically choose whether to show background by content type + const texture = (_b = viewer.projection) === null || _b === void 0 ? void 0 : _b.getTexture(); + if (texture && texture.isVideo()) { + // Show bg when content type is video + background.classList.remove(hiddenClass); + } else { + background.classList.add(hiddenClass); + } + } + } + _updateKeyboardHandler(viewer) { + var _a; + const panoRoot = viewer.rootEl; + const videoControl = this._videoControl; + const texture = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (this.keyboardControls && texture && texture.isVideo()) { + videoControl.enable(panoRoot, texture); + } else { + videoControl.disable(panoRoot); + } + } + _createDefaultItems() { + const items = []; + if (this.progressBar) { + items.push(new ProgressBar(getObjectOption(this.progressBar))); + } + if (this.playButton) { + items.push(new PlayButton(getObjectOption(this.playButton))); + } + if (this.volumeButton) { + items.push(new VolumeControl(getObjectOption(this.volumeButton))); + } + if (this.gyroButton) { + items.push(new GyroButton(getObjectOption(this.gyroButton))); + } + if (this.vrButton) { + items.push(new VRButton(getObjectOption(this.vrButton))); + } + if (this.fullscreenButton) { + items.push(new FullscreenButton(getObjectOption(this.fullscreenButton))); + } + if (this.videoTime) { + items.push(new VideoTime(getObjectOption(this.videoTime))); + } + if (this.pieView) { + items.push(new PieView(getObjectOption(this.pieView))); + } + return items; + } + } + /** + * Default class names that ControlBar uses + * @ko ControlBar가 사용하는 디폴트 클래스 이름들 + * @since 4.0.0 + */ + ControlBar.DEFAULT_CLASS = CONTROL_BAR_DEFAULT_CLASS; + /** + * Constants for {@link ControlBarItemOptions#position} + * @ko {@link ControlBarItemOptions#position}에 사용 가능한 값들 + */ + ControlBar.POSITION = CONTROL_BAR_ITEM_POSITION; + + /** + * Base class for projections. + * @ko 프로젝션 베이스 클래스. + * @category Projection + * @since 4.0.0 + */ + class Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + src, + video = false + }) { + this.src = src; + this.video = video; + this._mesh = null; + } + /** + * Release all resources projection has. + * This is automatically called on projection change & View360's destroy call + * @ko 현재 갖고 있는 모든 리소스를 반환합니다. + * 이 메소드는 프로젝션 변경 및 View360의 destroy 호출 시 자동으로 호출됩니다. + * @param ctx + */ + releaseAllResources(ctx) { + var _a; + (_a = this._mesh) === null || _a === void 0 ? void 0 : _a.destroy(ctx); + } + /** + * Update camera to match projection's settings. + * @ko 현재 프로젝션의 세팅으로 카메라를 업데이트합니다. + * @param camera - Instance of the camera to update {@ko 업데이트할 카메라의 인스턴스} + * @since 4.0.0 + */ + updateCamera(camera) { + // Use default mode & no view restriction + camera.resetRange(); + } + /** + * Update control to match projection's settings. + * @ko 현재 프로젝션의 세팅으로 컨트롤을 업데이트합니다. + * @param control - Instance of the control to update {@ko 업데이트할 컨트롤의 인스턴스} + * @since 4.0.0 + */ + updateControl(control) { + control.ignoreZoomScale = false; + } + /** + * Update projection. + * @ko 현재 프로젝션 정보를 갱신합니다. + * @param camera - Instance of the camera to reference {@ko 참조할 카메라의 인스턴스} + * @since 4.0.0 + */ + update(camera) {} // eslint-disable-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars + /** + * Return active texture. + * @ko 현재 활성화된 텍스쳐를 반환합니다. + * @internal + * @since 4.0.0 + */ + getTexture() { + if (!this._mesh) return null; + return this._mesh.program.uniforms.uTexture.texture; + } + /** + * A 3D triangle mesh for projection. It's `null` until loading the `src`. + * @ko Projection을 표시하기 위한 Mesh, src를 로드하기 전까지는 `null`입니다. + * @since 4.0.0 + */ + getMesh() { + return this._mesh; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class Uniform { + constructor() { + this.needsUpdate = true; + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + destroy(gl) { + // DO_NOTHING + } + } + + class UniformTextureCube extends Uniform { + constructor(ctx, texture, cubemapOrder) { + super(); + this.texture = texture; + this._webglTexture = ctx.createWebGLCubeTexture(texture, texture.width); + this._cubemapOrder = cubemapOrder; + } + destroy(gl) { + this.texture.destroy(); + gl.deleteTexture(this._webglTexture); + } + update(gl, location, isWebGL2) { + const texture = this.texture; + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY); + gl.uniform1i(location, 0); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture); + const sources = reorderCube(texture.sources, this._cubemapOrder); + sources.forEach((src, idx) => { + if (isWebGL2) { + gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src); + } else { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src); + } + }); + if (!texture.isVideo()) { + this.needsUpdate = false; + } + } + } + + /** @hidden */ + class CubeTexturePainter { + get size() { + return this._size; + } + constructor(texture, cubemapOrder) { + this.texture = texture; + this._renderingOrder = reorderCube(range(6), cubemapOrder); + const canvas = document.createElement("canvas"); + this._calcRenderingSize(); + canvas.width = this._size; + canvas.height = this._size; + this._canvas = canvas; + this._ctx = canvas.getContext("2d"); + } + destroy() { + const canvas = this._canvas; + // release memories + canvas.width = 1; + canvas.height = 1; + this._canvas = null; + } + draw(gl, isWebGL2) { + const size = this._size; + const texture = this.texture; + let surfaceIdx = 0; + for (let row = 0; row < this._row; row++) { + for (let column = 0; column < this._column; column++) { + const x = size * column; + const y = size * row; + const renderingFace = this._renderingOrder[surfaceIdx]; + this._ctx.drawImage(texture.source, x, y, size, size, 0, 0, size, size); + if (isWebGL2) { + gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas); + } else { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas); + } + surfaceIdx++; + } + } + } + _calcRenderingSize() { + const { + width, + height + } = this.texture; + const aspect = width / height; + if (aspect === 1 / 6) { + this._size = width; + this._row = 6; + this._column = 1; + } else if (aspect === 6) { + this._size = height; + this._row = 1; + this._column = 6; + } else if (aspect === 2 / 3) { + this._size = width * 0.5; + this._row = 3; + this._column = 2; + } else { + this._size = width / 3; + this._row = 2; + this._column = 3; + } + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class UniformCanvasCube extends Uniform { + get texture() { + return this._painter.texture; + } + constructor(ctx, texture, cubemapOrder) { + super(); + this._painter = new CubeTexturePainter(texture, cubemapOrder); + this._webglTexture = ctx.createWebGLCubeTexture(texture, this._painter.size); + } + destroy(gl) { + gl.deleteTexture(this._webglTexture); + this._painter.destroy(); + } + update(gl, location, isWebGL2) { + const texture = this.texture; + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + gl.uniform1i(location, 0); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture); + this._painter.draw(gl, isWebGL2); + if (!texture.isVideo()) { + this.needsUpdate = false; + } + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class TriangleMesh extends Object3D { + constructor(vao, program) { + super(); + this.vao = vao; + this.program = program; + } + destroy(ctx) { + ctx.releaseVAO(this.vao); + ctx.releaseShaderResources(this.program); + } + } + + class ShaderProgram { + constructor(ctx, vertexShader, fragmentShader, uniforms) { + this.program = ctx.createProgram(vertexShader, fragmentShader); + this.uniforms = uniforms; + this.uniformLocations = ctx.getUniformLocations(this.program, uniforms); + } + } + + /** + * @hidden + */ + class VertexData { + /** */ + constructor(data, itemSize) { + this.data = data; + this.itemSize = itemSize; + this.count = data.length / itemSize; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class Geometry { + /** */ + constructor(vertices, indicies, uvs) { + this.vertices = new VertexData(new Float32Array(vertices), 3); + this.indicies = new VertexData(new Uint16Array(indicies), 1); + this.uvs = new VertexData(new Float32Array(uvs), 2); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class CubeGeometry extends Geometry { + constructor({ + order, + rotateUV + }) { + const vertices = [ + // back + 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, + // front + -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, + // up + -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, + // down + -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, + // right + 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, + // left + -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1]; + const indicies = [0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23]; + const oneThird = 1 / 3; + const coords = []; + for (let r = 1; r >= 0; r--) { + for (let c = 0; c < 3; c++) { + const coord = [c * oneThird, r * 0.5, (c + 1) * oneThird, r * 0.5, (c + 1) * oneThird, (r + 1) * 0.5, c * oneThird, (r + 1) * 0.5]; + coords.push(coord); + } + } + if (rotateUV) { + rotateUV.forEach((degree, idx) => { + if (degree === ROTATE.ZERO) return; + const coord = coords[idx]; + let newOrder; + if (degree === ROTATE.CW_90) { + newOrder = [1, 2, 3, 0]; + } else if (degree === ROTATE.CCW_90) { + newOrder = [3, 0, 1, 2]; + } else { + newOrder = [2, 3, 0, 1]; + } + const newCoords = Array(coord.length); + for (let uvIdx = 0; uvIdx < coord.length / 2; uvIdx++) { + newCoords[uvIdx * 2 + 0] = coord[newOrder[uvIdx] * 2 + 0]; + newCoords[uvIdx * 2 + 1] = coord[newOrder[uvIdx] * 2 + 1]; + } + coords[idx] = newCoords; + }); + } + const uvs = reorderCube(coords, order, "BFUDRL").reduce((acc, val) => acc.concat(val), []); + super(vertices, indicies, uvs); + } + } + + var vs$3 = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec3 vPos;void main(){vPos=position;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}"; // eslint-disable-line + + var fs$3 = "#define GLSLIFY 1\nuniform samplerCube uTexture;varying highp vec3 vPos;void main(){gl_FragColor=textureCube(uTexture,vec3(vPos.x,vPos.y,-vPos.z));}"; // eslint-disable-line + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on cubemap images, accepts both multiple or single images. + * @ko 큐브맵 이미지 기반의 프로젝션, 단일 혹은 여러 장의 이미지를 모두 사용 가능합니다. + * @since 4.0.0 + * @category Projection + */ + class CubemapProjection extends Projection { + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param options Options {@ko Options} + */ + constructor(options) { + super(options); + const { + cubemapOrder = "RLUDFB", + cubemapFlipX = false + } = options; + this._cubemapOrder = cubemapOrder; + this._cubemapFlipX = cubemapFlipX; + } + applyTexture(ctx, texture) { + const cubemapOrder = this._cubemapOrder; + const cubemapFlipX = this._cubemapFlipX; + const uniforms = { + uTexture: texture.isCube() ? new UniformTextureCube(ctx, texture, cubemapOrder) : new UniformCanvasCube(ctx, texture, cubemapOrder) + }; + const geometry = new CubeGeometry({ + order: cubemapOrder + }); + const program = new ShaderProgram(ctx, vs$3, fs$3, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + if (cubemapFlipX) { + mesh.scale[0] = -1; + } + mesh.updateMatrix(); + this._mesh = mesh; + } + } + + class UniformTexture2D extends Uniform { + constructor(ctx, texture) { + super(); + this.texture = texture; + this._webglTexture = ctx.createWebGLTexture(texture); + } + destroy(gl) { + this.texture.destroy(); + gl.deleteTexture(this._webglTexture); + } + update(gl, location, isWebGL2) { + const texture = this.texture; + const isVideo = texture.isVideo(); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY); + gl.uniform1i(location, 0); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, this._webglTexture); + if (!isVideo && isWebGL2) { + gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); + } + if (!isVideo) { + this.needsUpdate = false; + } + } + } + + var vs$2 = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec2 vUV;void main(){vUV=uv;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}"; // eslint-disable-line + + var fs$2 = "#define GLSLIFY 1\nuniform sampler2D uTexture;varying highp vec2 vUV;void main(){gl_FragColor=texture2D(uTexture,vUV.st);}"; // eslint-disable-line + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on cubemap strip. + * Slightly more efficient than {@link CubemapProjection} as it doesn't copy cubemap image to canvas while rendering. + * Accepts only single image. + * @ko 큐브맵 스트립 기반의 프로젝션. + * {@link CubemapProjection}와 달리 렌더링하는 과정에 캔버스에 이미지를 복사하는 과정이 없기 때문에 살짝 더 효율적입니다. + * 단일 이미지만 사용 가능합니다. + * @since 4.0.0 + * @category Projection + */ + class CubestripProjection extends Projection { + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param options Options {@ko Options} + */ + constructor(options) { + super(options); + const { + cubemapOrder = "RLUDFB", + cubemapFlipX = false + } = options; + this._cubemapOrder = cubemapOrder; + this._cubemapFlipX = cubemapFlipX; + } + applyTexture(ctx, texture) { + const cubemapOrder = this._cubemapOrder; + const cubemapFlipX = this._cubemapFlipX; + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture) + }; + const geometry = new CubeGeometry({ + order: cubemapOrder + }); + const program = new ShaderProgram(ctx, vs$2, fs$2, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + if (cubemapFlipX) { + mesh.scale[0] = -1; + } + mesh.updateMatrix(); + this._mesh = mesh; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class CylinderGeometry extends Geometry { + constructor(maxTheta) { + const vertices = []; + const indicies = []; + const uvs = []; + const height = 1; + const radialSegments = 60; + const halfHeight = height * 0.5; + const heightSegments = [-halfHeight, halfHeight]; + const invRadialSegments = 1 / radialSegments; + const angleConst = maxTheta * invRadialSegments; + for (let yIdx = 0; yIdx < 2; yIdx++) { + const y = heightSegments[yIdx]; + for (let lngIdx = 0; lngIdx <= radialSegments; lngIdx++) { + const angle = lngIdx * angleConst + Math.PI - maxTheta * 0.5; + const x = Math.cos(angle); + const z = Math.sin(angle); + const u = lngIdx * invRadialSegments; + const v = yIdx; + uvs.push(u, v); + vertices.push(x, y, z); + if (yIdx === 0 && lngIdx < radialSegments) { + const a = lngIdx; + const b = a + radialSegments + 1; + indicies.push(a, b, a + 1, b, b + 1, a + 1); + } + } + } + super(vertices, indicies, uvs); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on cylindrical projection. + * This can show panorama images taken from smartphones. + * @ko 원통 투영법 기반의 프로젝션. + * 일반적인 스마트폰 파노라마 사진을 표시하는데 사용될 수 있습니다. + * @since 4.0.0 + * @category Projection + */ + class CylindricalProjection extends Projection { + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param options Options {@ko Options} + */ + constructor(options) { + super(options); + const { + partial = false + } = options; + this._partial = partial; + } + applyTexture(ctx, texture) { + const partial = this._partial; + const { + width, + height + } = texture; + const aspect = width / height; + const halfVFov = 180 / aspect; + const cylinderHeight = partial ? 1 : 2 * Math.tan(halfVFov * DEG_TO_RAD); + const cylinderTheta = partial ? aspect : 2 * Math.PI; + const geometry = new CylinderGeometry(cylinderTheta); + const program = new ShaderProgram(ctx, vs$2, fs$2, { + uTexture: new UniformTexture2D(ctx, texture) + }); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + mesh.scale[1] = cylinderHeight; + glMatrix.quat.identity(mesh.rotation); + glMatrix.quat.rotateY(mesh.rotation, mesh.rotation, -Math.PI / 2); + mesh.updateMatrix(); + this._mesh = mesh; + } + updateCamera(camera) { + super.updateCamera(camera); + const mesh = this._mesh; + if (!mesh) return; + const uTexture = mesh.program.uniforms.uTexture; + const texture = uTexture.texture; + const { + width, + height + } = texture; + const aspect = width / height; + const halfHeight = mesh.scale[1] * 0.5; + if (this._partial) { + const restrictedYaw = 0.5 * aspect * RAD_TO_DEG; + camera.restrictYawRange(-restrictedYaw, restrictedYaw); + } + const restrictedPitch = Math.atan2(halfHeight, 1) * RAD_TO_DEG; + const minZoom = Math.tan(camera.fov * DEG_TO_RAD * 0.5) / (halfHeight * camera.aspect); + camera.restrictPitchRange(-restrictedPitch, restrictedPitch); + camera.restrictZoomRange(minZoom, Infinity); + camera.restrictRenderHeight(halfHeight * 2); + } + } + + var fs$1 = "#define PI 3.14159265359\nprecision mediump float;\n#define GLSLIFY 1\nuniform sampler2D uTexture;varying highp vec2 vUV;const vec2 OPERATE_COORDS_RANGE=vec2(-1.0,1.0);const vec2 TEXTURE_COORDS_RANGE=vec2(0.0,1.0);const float ONE_THIRD=1.0/3.0;const float EAC_CONST=2.0/PI;float scale(vec2 domainRange,vec2 targetRange,float val){float unit=1.0/(domainRange[1]-domainRange[0]);return targetRange[0]+(targetRange[1]-targetRange[0])*(val-domainRange[0])*unit;}void main(void){float transformedCoordX;float transformedCoordY;float texRangeXStart=floor(vUV.s*3.)*ONE_THIRD;float texRangeYStart=floor(vUV.t*2.)*0.5;vec2 orgTextureRangeX=vec2(texRangeXStart,texRangeXStart+ONE_THIRD);vec2 orgTextureRangeY=vec2(texRangeYStart,texRangeYStart+0.5);float px=scale(orgTextureRangeX,OPERATE_COORDS_RANGE,vUV.s);float py=scale(orgTextureRangeY,OPERATE_COORDS_RANGE,vUV.t);float qu=EAC_CONST*atan(px)+0.5;float qv=EAC_CONST*atan(py)+0.5;transformedCoordX=scale(TEXTURE_COORDS_RANGE,orgTextureRangeX,qu);transformedCoordY=scale(TEXTURE_COORDS_RANGE,orgTextureRangeY,qv);gl_FragColor=texture2D(uTexture,vec2(transformedCoordX,transformedCoordY));}"; // eslint-disable-line + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Equi-Angular Cubemap Projection. + * This format is used by Youtube's 360 videos. + * @ko Equi-Angular Cubemap 프로젝션. + * 이 포맷은 주로 Youtube의 360 비디오에 사용됩니다. + * @since 4.0.0 + * @category Projection + */ + class EquiangularProjection extends Projection { + applyTexture(ctx, texture) { + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture) + }; + const geometry = new CubeGeometry({ + order: "LFRDBU", + rotateUV: [ROTATE.ZERO, ROTATE.ZERO, ROTATE.ZERO, ROTATE.CW_90, ROTATE.CCW_90, ROTATE.CW_90] + }); + const program = new ShaderProgram(ctx, vs$2, fs$1, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class SphereGeometry extends Geometry { + /** */ + constructor() { + // const radius = 1; + const widthSegments = 60; + const heightSegments = 60; + const ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI; + const uvs = []; + const vertices = []; + const indicies = []; + let latIdx; + let lngIdx; + for (latIdx = 0; latIdx <= widthSegments; latIdx++) { + const theta = (latIdx / widthSegments - 0.5) * Math.PI; + const sinTheta = Math.sin(theta); + const cosTheta = Math.cos(theta); + for (lngIdx = 0; lngIdx <= heightSegments; lngIdx++) { + const phi = (lngIdx / heightSegments - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN; + const sinPhi = Math.sin(phi); + const cosPhi = Math.cos(phi); + const x = cosPhi * cosTheta; + const y = sinTheta; + const z = sinPhi * cosTheta; + const u = lngIdx / heightSegments; + const v = latIdx / widthSegments; + uvs.push(u, v); + vertices.push(x, y, z); + if (lngIdx !== heightSegments && latIdx !== widthSegments) { + const a = latIdx * (heightSegments + 1) + lngIdx; + const b = a + heightSegments + 1; + indicies.push(a, a + 1, b, b, a + 1, b + 1); + } + } + } + super(vertices, indicies, uvs); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on equirectangular projection. + * @ko 등 장방형 도법(Equirectangular projection) 기반의 프로젝션 + * @since 4.0.0 + * @category Projection + */ + class EquirectProjection extends Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor(options) { + super(options); + } + applyTexture(ctx, texture) { + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture) + }; + const geometry = new SphereGeometry(); + const program = new ShaderProgram(ctx, vs$2, fs$2, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class UniformFloat extends Uniform { + constructor(val) { + super(); + this.val = val; + } + update(gl, location) { + gl.uniform1f(location, this.val); + this.needsUpdate = false; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class PlaneGeometry extends Geometry { + /** */ + constructor(width = 2, height = 2, z = -1) { + const halfWidth = width * 0.5; + const halfHeight = height * 0.5; + const vertices = [-halfWidth, -halfHeight, z, halfWidth, -halfHeight, z, -halfWidth, halfHeight, z, halfWidth, halfHeight, z]; + const indicies = [0, 1, 2, 2, 1, 3]; + const uvs = [0, 0, 1, 0, 0, 1, 1, 1]; + super(vertices, indicies, uvs); + } + } + + var vs$1 = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec2 vUV;void main(){vUV=uv;gl_Position=vec4(position,1.0);}"; // eslint-disable-line + + var fs = "precision mediump float;\n#define GLSLIFY 1\nuniform sampler2D uTexture;uniform float uYaw;uniform float uPitch;uniform float uZoom;varying highp vec2 vUV;const float PI=3.1415926536;const float PI_2=PI*0.5;vec2 toStereographicUV(in vec2 uv,in vec2 center){float R=1.*uZoom;vec2 texLatLon=(uv*2.-1.)*vec2(PI,PI_2);vec2 central=(center*2.-1.)*vec2(PI,PI_2)+vec2(PI,0);float x=texLatLon.x;float y=texLatLon.y;float rou=sqrt(x*x+y*y);float c=2.0*atan(rou,R*0.5);float sin_c=sin(c);float cos_c=cos(c);float sin_cy=sin(central.y);float cos_cy=cos(central.y);float lat=asin(cos_c*sin_cy+(y*sin_c*cos_cy)/rou);float lon=central.x+atan(x*sin_c,rou*cos_cy*cos_c-y*sin_cy*sin_c);float u=(lon/PI+1.0)*0.5;float v=(lat/PI_2+1.0)*0.5;return vec2(u,v);}void main(){vec2 central=vec2(uYaw,uPitch);vec2 uv=toStereographicUV(vUV,central);gl_FragColor=texture2D(uTexture,uv);}"; // eslint-disable-line + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on so-called "Little planet" or "Tiny planet" effect. + * @ko "Little planet" 혹은 "Tiny planet"로 불리는 이펙트 기반의 프로젝션 + * @since 4.0.0 + * @category Projection + */ + class LittlePlanetProjection extends Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor(options) { + super(options); + } + applyTexture(ctx, texture) { + texture.wrapS = WebGLRenderingContext.REPEAT; + texture.wrapT = WebGLRenderingContext.REPEAT; + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture), + uYaw: new UniformFloat(0), + uPitch: new UniformFloat(0.5), + uZoom: new UniformFloat(1) + }; + const geometry = new PlaneGeometry(); + const program = new ShaderProgram(ctx, vs$1, fs, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } + updateControl(control) { + control.ignoreZoomScale = true; + } + update(camera) { + const mesh = this._mesh; + if (!mesh) return; + const uniforms = mesh.program.uniforms; + uniforms.uYaw.val = camera.yaw / 360; + // Range from 0 ~ 1 + uniforms.uPitch.val = camera.pitch / 180 + 0.5; + uniforms.uZoom.val = camera.zoom; + uniforms.uYaw.needsUpdate = true; + uniforms.uPitch.needsUpdate = true; + uniforms.uZoom.needsUpdate = true; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class UniformVector4Array extends Uniform { + constructor(val) { + super(); + this.val = val; + } + update(gl, location) { + gl.uniform4fv(location, this.val.reduce((arr, vector) => [...arr, ...vector], [])); + this.needsUpdate = false; + } + } + + var vs = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;uniform vec4 uTexScaleOffset[2];uniform float uEye;varying highp vec2 vUV;void main(){vec4 scaleOffset=uTexScaleOffset[int(uEye)];vUV=uv.xy*scaleOffset.xy+scaleOffset.zw;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}"; // eslint-disable-line + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on stereo equirectangular images. + * @ko Stereo equirectangular 이미지 기반의 프로젝션 + * @since 4.0.0 + * @category Projection + */ + class StereoEquiProjection extends Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor(options) { + super(options); + this._mode = options.mode; + } + applyTexture(ctx, texture) { + let leftEye; + let rightEye; + switch (this._mode) { + case StereoEquiProjection.MODE.LEFT_RIGHT: + leftEye = [0.5, 1, 0, 0]; + rightEye = [0.5, 1, 0.5, 0]; + break; + default: + // Default, uses "top_bottom" + leftEye = [1, 0.5, 0, 0]; + rightEye = [1, 0.5, 0, 0.5]; + } + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture), + uEye: new UniformFloat(0), + uTexScaleOffset: new UniformVector4Array([leftEye, rightEye]) + }; + const geometry = new SphereGeometry(); + const program = new ShaderProgram(ctx, vs, fs$2, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } + } + /** + * Available stereoscopic modes + * @ko 사용가능한 스테레오스코픽 모드들 + * @since 4.0.0 + */ + StereoEquiProjection.MODE = { + /** + * @ko 이미지가 왼쪽/오른쪽으로 구성되어있을 경우 + * @since 4.0.0 + */ + LEFT_RIGHT: "left_right", + /** + * @ko 이미지가 위/아래로 구성되어있을 경우 + * @since 4.0.0 + */ + TOP_BOTTOM: "top_bottom" + }; + + /** + * @hidden + */ + const withMethods = (prototype, attr) => { + [Component__default["default"].prototype, View360.prototype].forEach(proto => { + Object.getOwnPropertyNames(proto).filter(name => name.charAt(0) !== "_" && name !== "constructor").forEach(name => { + const descriptor = Object.getOwnPropertyDescriptor(proto, name); + if (descriptor.value) { + // Public Function + Object.defineProperty(prototype, name, { + value: function (...args) { + return descriptor.value.call(this[attr], ...args); + } + }); + } else { + const getterDescriptor = {}; + if (descriptor.get) { + getterDescriptor.get = function () { + var _a; + return this[attr] && ((_a = descriptor.get) === null || _a === void 0 ? void 0 : _a.call(this[attr])); + }; + } + if (descriptor.set) { + getterDescriptor.set = function (...args) { + var _a; + return (_a = descriptor.set) === null || _a === void 0 ? void 0 : _a.call(this[attr], ...args); + }; + } + Object.defineProperty(prototype, name, getterDescriptor); + } + }); + }); + }; + + /** + * @hidden + */ + const getValidProps = propsObj => { + return Object.keys(propsObj).reduce((props, propName) => { + if (propsObj[propName] != null) { + props[propName] = propsObj[propName]; + } + return props; + }, {}); + }; + + const VIEW360_METHODS = ["destroy", "init", "load", "resize", "addPlugins", "removePlugins", "renderFrame", + // @egjs/component methods + "on", "hasOn", "once", "off", "trigger"]; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + + var modules = { + __proto__: null, + 'default': View360, + Autoplay: Autoplay, + AutoResizer: AutoResizer, + Camera: Camera, + CameraAnimation: CameraAnimation, + Motion: Motion, + Object3D: Object3D, + View360Error: View360Error, + WebGLRenderer: WebGLRenderer, + XRManager: XRManager, + PanoControl: PanoControl, + RotateControl: RotateControl, + ZoomControl: ZoomControl, + GyroControl: GyroControl, + ControlBar: ControlBar, + ControlBarItem: ControlBarItem, + FullscreenButton: FullscreenButton, + PieView: PieView, + PlayButton: PlayButton, + ProgressBar: ProgressBar, + VideoTime: VideoTime, + VolumeControl: VolumeControl, + LoadingSpinner: LoadingSpinner, + Projection: Projection, + CubemapProjection: CubemapProjection, + CubestripProjection: CubestripProjection, + CylindricalProjection: CylindricalProjection, + EquiangularProjection: EquiangularProjection, + EquirectProjection: EquirectProjection, + LittlePlanetProjection: LittlePlanetProjection, + StereoEquiProjection: StereoEquiProjection, + Hotspot: Hotspot, + HotspotRenderer: HotspotRenderer, + ERROR_CODES: ERROR_CODES, + DEFAULT_CLASS: DEFAULT_CLASS, + EVENTS: EVENTS, + EASING: EASING, + getValidProps: getValidProps, + VIEW360_METHODS: VIEW360_METHODS, + withMethods: withMethods + }; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + merge(View360, modules); + + return View360; + +})); +//# sourceMappingURL=view360.js.map diff --git a/demo/release/latest/dist/view360.js.map b/demo/release/latest/dist/view360.js.map new file mode 100644 index 000000000..b4dbf8b0d --- /dev/null +++ b/demo/release/latest/dist/view360.js.map @@ -0,0 +1 @@ +{"version":3,"file":"view360.js","sources":["../src/core/View360Error.ts","../src/const/error.ts","../src/const/browser.ts","../src/const/external.ts","../src/const/internal.ts","../src/utils.ts","../src/core/Motion.ts","../src/core/CameraAnimation.ts","../src/core/Camera.ts","../src/control/input/MouseInput.ts","../src/control/input/TouchInput.ts","../src/control/input/KeyboardInput.ts","../src/control/RotateControl.ts","../src/control/input/WheelInput.ts","../src/control/input/PinchInput.ts","../src/control/ZoomControl.ts","../src/control/input/GyroInput.ts","../src/control/GyroControl.ts","../src/control/PanoControl.ts","../src/texture/Texture.ts","../src/texture/Texture2D.ts","../src/texture/TextureVideo.ts","../src/texture/TextureCube.ts","../src/core/TextureLoader.ts","../src/core/FrameAnimator.ts","../src/core/AutoResizer.ts","../src/core/Autoplay.ts","../src/core/XRManager.ts","../src/hotspot/Hotspot.ts","../src/hotspot/HotspotRenderer.ts","../src/core/VertexArrayObject.ts","../src/core/WebGLContext.ts","../src/core/WebGLRenderer.ts","../src/View360.ts","../src/core/Object3D.ts","../src/plugin/LoadingSpinner/LoadingSpinner.ts","../src/plugin/ControlBar/ControlBarItem.ts","../src/plugin/ControlBar/const.ts","../src/plugin/ControlBar/RangeControl.ts","../src/plugin/ControlBar/ProgressBar.ts","../src/plugin/ControlBar/PlayButton.ts","../src/plugin/ControlBar/VolumeControl.ts","../src/plugin/ControlBar/FullscreenButton.ts","../src/plugin/ControlBar/VideoTime.ts","../src/plugin/ControlBar/PieView.ts","../src/plugin/ControlBar/VRButton.ts","../src/plugin/ControlBar/GyroButton.ts","../src/plugin/ControlBar/AutoHide.ts","../src/plugin/ControlBar/VideoControl.ts","../src/plugin/ControlBar/ControlBar.ts","../src/projection/Projection.ts","../src/uniform/Uniform.ts","../src/uniform/UniformTextureCube.ts","../src/core/CubeTexturePainter.ts","../src/uniform/UniformCanvasCube.ts","../src/core/TriangleMesh.ts","../src/core/ShaderProgram.ts","../src/core/VertexData.ts","../src/geometry/Geometry.ts","../src/geometry/CubeGeometry.ts","../src/projection/CubemapProjection.ts","../src/uniform/UniformTexture2D.ts","../src/projection/CubestripProjection.ts","../src/geometry/CylinderGeometry.ts","../src/projection/CylindricalProjection.ts","../src/projection/EquiangularProjection.ts","../src/geometry/SphereGeometry.ts","../src/projection/EquirectProjection.ts","../src/uniform/UniformFloat.ts","../src/geometry/PlaneGeometry.ts","../src/projection/LittlePlanetProjection.ts","../src/uniform/UniformVector4Array.ts","../src/projection/StereoEquiProjection.ts","../src/cfc/withMethods.ts","../src/cfc/utils.ts","../src/cfc/const.ts","../src/index.ts","../src/index.umd.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * Error thrown by {@link View360}\n * @ko {@link View360}이 발생시킨 에러\n * @since 4.0.0\n */\nclass View360Error extends Error {\n /**\n * Error code\n * @ko 에러 코드\n * @see ERROR_CODES\n */\n public code: number;\n\n /**\n * Create new instance of View360Error\n * @ko View360Error의 인스턴스를 생성합니다.\n * @param message - Error message {@ko 에러 메시지}\n * @param code - Error code {@ko 에러 코드}\n */\n public constructor(message: string, code: number) {\n super(message);\n\n Object.setPrototypeOf(this, View360Error.prototype);\n\n this.name = \"View360Error\";\n this.code = code;\n }\n}\n\nexport default View360Error;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * Error codes of {@link View360Error}\n * @ko {@link View360Error}가 가질 수 있는 에러 코드 값들\n * @since 4.0.0\n */\nexport const ERROR_CODES = {\n /**\n * The given value's type is not expected\n * @ko 주어진 값의 타입이 잘못되었을 경우\n * @since 4.0.0\n */\n WRONG_TYPE: 0,\n /**\n * The given value is not a supported option\n * @ko 잘못된 옵션을 받았을 경우\n * @since 4.0.0\n */\n WRONG_OPTION: 1,\n /**\n * The element with given CSS selector does not exist\n * @ko 주어진 CSS 셀렉터로 엘리먼트를 찾지 못했을 경우\n * @since 4.0.0\n */\n ELEMENT_NOT_FOUND: 2,\n /**\n * Couldn't find canvas element inside the given container element.\n * @ko 컨테이너 엘리먼트 내부에서 캔버스 엘리먼트를 찾지 못했을 경우\n * @since 4.0.0\n */\n CANVAS_NOT_FOUND: 3,\n /**\n * The browser does not support WebGL\n * @ko 브라우저가 WebGL을 지원하지 않는 경우\n * @since 4.0.0\n */\n WEBGL_NOT_SUPPORTED: 4,\n /**\n * Failed creating canvas 2D context\n * @ko 캔버스 2D 컨텍스트를 생성하지 못한 경우\n * @since 4.0.0\n */\n FAILED_CREATE_CONTEXT_2D: 5,\n /**\n * `init()` is called before setting {@link View360Options#projection}\n * @ko {@link View360Options#projection}을 설정하기 전에 `init()`이 호출된 경우\n * @since 4.0.0\n */\n PROVIDE_PROJECTION_FIRST: 6,\n /**\n * Failed linking WebGL program. Only can be thrown when {@link View360Options#debug} is `true`.\n * @ko WebGL 프로그램 링크에 실패한 경우. {@link View360Options#debug}를 `true`로 설정한 경우에만 발생할 수 있습니다.\n * @since 4.0.0\n */\n FAILED_LINKING_PROGRAM: 7,\n /**\n * Arguments are not sufficient for the given property.\n * @ko 프로퍼티에 값이 충분히 주어지지 않았을 때\n * @since 4.0.0\n */\n INSUFFICIENT_ARGS: 8\n} as const;\n\nexport const MESSAGES = {\n WRONG_TYPE: (val: any, types: string[]) => `${typeof val} is not a ${types.map(type => `\"${type}\"`).join(\" or \")}.`,\n WRONG_OPTION: (val: any, optionName: string) => `Bad option: given \"${val}\" for option \"${optionName}\".`,\n ELEMENT_NOT_FOUND: (query: string) => `Element with selector \"${query}\" not found.`,\n CANVAS_NOT_FOUND: \"The canvas element was not found inside the given root element.\",\n WEBGL_NOT_SUPPORTED: \"WebGL is not supported on this browser.\",\n FAILED_CREATE_CONTEXT_2D: \"Failed to create canvas 2D context\",\n PROVIDE_PROJECTION_FIRST: \"\\\"projection\\\" should be provided before initialization.\",\n FAILED_LINKING_PROGRAM: (msg: string | null, shaderLog: string | null) => `Failed linking WebGL program - \"${msg}\\nShader compile Log: ${shaderLog}`,\n INSUFFICIENT_ARGS: (val: any, name: string) => `Insufficient arguments: given \"${val}\" for \"${name}\".`\n};\n\nexport default {\n CODES: ERROR_CODES,\n MESSAGES\n};\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nexport const EVENTS = {\n MOUSE_DOWN: \"mousedown\",\n MOUSE_MOVE: \"mousemove\",\n MOUSE_UP: \"mouseup\",\n TOUCH_START: \"touchstart\",\n TOUCH_MOVE: \"touchmove\",\n TOUCH_END: \"touchend\",\n WHEEL: \"wheel\",\n RESIZE: \"resize\",\n CONTEXT_MENU: \"contextmenu\",\n MOUSE_ENTER: \"mouseenter\",\n MOUSE_LEAVE: \"mouseleave\",\n POINTER_DOWN: \"pointerdown\",\n POINTER_MOVE: \"pointermove\",\n POINTER_UP: \"pointerup\",\n POINTER_CANCEL: \"pointercancel\",\n POINTER_ENTER: \"pointerenter\",\n POINTER_LEAVE: \"pointerleave\",\n KEY_DOWN: \"keydown\",\n KEY_UP: \"keyup\",\n LOAD: \"load\",\n ERROR: \"error\",\n CLICK: \"click\",\n DOUBLE_CLICK: \"dblclick\",\n CONTEXT_CREATE_ERROR: \"webglcontextcreationerror\",\n CONTEXT_LOST: \"webglcontextlost\",\n CONTEXT_RESTORED: \"webglcontextrestored\",\n DEVICE_ORIENTATION: \"deviceorientation\",\n DEVICE_MOTION: \"devicemotion\",\n ORIENTATION_CHANGE: \"orientationchange\",\n VIDEO_PLAY: \"play\",\n VIDEO_PAUSE: \"pause\",\n VIDEO_LOADED_DATA: \"loadeddata\",\n VIDEO_VOLUME_CHANGE: \"volumechange\",\n VIDEO_TIME_UPDATE: \"timeupdate\",\n VIDEO_DURATION_CHANGE: \"durationchange\",\n VIDEO_CAN_PLAYTHROUGH: \"canplaythrough\",\n TRANSITION_END: \"transitionend\",\n XR_END: \"end\"\n} as const;\n\nexport const EL_DIV = \"div\";\nexport const EL_BUTTON = \"button\";\n\n// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button\nexport enum MOUSE_BUTTON {\n LEFT,\n MIDDLE,\n RIGHT\n}\n\nexport const CURSOR = {\n GRAB: \"grab\",\n GRABBING: \"grabbing\",\n NONE: \"\"\n} as const;\n\nexport const KEY_DIRECTION = [\"LEFT\", \"UP\", \"RIGHT\", \"DOWN\"] as const;\nexport enum DIRECTION_KEY_CODE {\n LEFT = 37,\n UP = 38,\n RIGHT = 39,\n DOWN = 40\n}\nexport const SPACE_KEY_CODE = 32;\n\nexport const DIRECTION_KEY_NAME = {\n LEFT: \"ArrowLeft\",\n UP: \"ArrowUp\",\n RIGHT: \"ArrowRight\",\n DOWN: \"ArrowDown\"\n} as const;\nexport const SPACE_KEY_NAME = \" \";\n\nexport const FULLSCREEN_REQUEST = [\n \"requestFullscreen\",\n \"webkitRequestFullscreen\",\n \"webkitRequestFullScreen\",\n \"webkitCancelFullScreen\",\n \"mozRequestFullScreen\",\n \"msRequestFullscreen\"\n];\n\nexport const FULLSCREEN_ELEMENT = [\n \"fullscreenElement\",\n \"webkitFullscreenElement\",\n \"webkitCurrentFullScreenElement\",\n \"mozFullScreenElement\",\n \"msFullscreenElement\"\n];\n\nexport const FULLSCREEN_EXIT = [\n \"exitFullscreen\",\n \"webkitExitFullscreen\",\n \"webkitCancelFullScreen\",\n \"mozCancelFullScreen\",\n \"msExitFullscreen\"\n];\n\nexport const FULLSCREEN_CHANGE = [\n \"fullscreenchange\",\n \"webkitfullscreenchange\",\n \"mozfullscreenchange\",\n \"MSFullscreenChange\"\n];\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nexport { ERROR_CODES } from \"./error\";\n\n/**\n * Default class names\n * @ko 기본 클래스 이름들\n * @since 4.0.0\n */\nexport const DEFAULT_CLASS = {\n CONTAINER: \"view360-container\",\n CANVAS: \"view360-canvas\",\n CTX_LOST: \"view360-ctx-lost\",\n IN_VR: \"view360-vr-presenting\",\n HOTSPOT_CONTAINER: \"view360-hotspots\",\n HOTSPOT: \"view360-hotspot\",\n HOTSPOT_VISIBLE: \"view360-hotspot-visible\",\n HOTSPOT_FLIP_X: \"view360-hotspot-flip-x\",\n HOTSPOT_FLIP_Y: \"view360-hotspot-flip-y\",\n} as const;\n\n/**\n * Event names\n * @ko 이벤트 이름들\n * @since 4.0.0\n * @example\n * ```ts\n * import View360, { EVENTS } from \"@egjs/view360\";\n *\n * const viewer = new View360(\"#el_id\");\n *\n * viewer.on(EVENTS.READY, evt => {\n * console.log(\"View360 is ready!\");\n * });\n * ```\n */\nexport const EVENTS = {\n READY: \"ready\",\n LOAD_START: \"loadStart\",\n LOAD: \"load\",\n PROJECTION_CHANGE: \"projectionChange\",\n RESIZE: \"resize\",\n BEFORE_RENDER: \"beforeRender\",\n RENDER: \"render\",\n INPUT_START: \"inputStart\",\n INPUT_END: \"inputEnd\",\n VIEW_CHANGE: \"viewChange\",\n STATIC_CLICK: \"staticClick\",\n VR_START: \"vrStart\",\n VR_END: \"vrEnd\"\n} as const;\n\n/**\n * Collection of predefined easing functions\n * @ko 미리 정의된 easing 함수들\n */\nexport const EASING = {\n LINEAR: (x: number) => x,\n SINE_WAVE: (x: number) => Math.sin(x * Math.PI * 2),\n EASE_OUT_CUBIC: (x: number) => 1 - Math.pow(1 - x, 3),\n EASE_OUT_BOUNCE: (x: number): number => {\n const n1 = 7.5625;\n const d1 = 2.75;\n\n if (x < 1 / d1) {\n return n1 * x * x;\n } else if (x < 2 / d1) {\n return n1 * (x -= 1.5 / d1) * x + 0.75;\n } else if (x < 2.5 / d1) {\n return n1 * (x -= 2.25 / d1) * x + 0.9375;\n } else {\n return n1 * (x -= 2.625 / d1) * x + 0.984375;\n }\n }\n} as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { EASING } from \"./external\";\nimport { Range } from \"../type/utils\";\n\nexport const CAMERA_EVENTS = {\n CHANGE: \"change\",\n ANIMATION_END: \"animationEnd\"\n} as const;\n\nexport const CONTROL_EVENTS = {\n INPUT_START: \"inputStart\",\n CHANGE: \"change\",\n INPUT_END: \"inputEnd\",\n ENABLE: \"enable\",\n DISABLE: \"disable\",\n STATIC_CLICK: \"staticClick\"\n} as const;\n\nexport const DEG_TO_RAD = Math.PI / 180;\nexport const RAD_TO_DEG = 180 / Math.PI;\nexport const DEFAULT_EASING = EASING.EASE_OUT_CUBIC;\nexport const DEFAULT_ANIMATION_DURATION = 300;\nexport const INFINITE_RANGE: Readonly = {\n min: -Infinity, max: Infinity\n} as const;\nexport const DEFAULT_PITCH_RANGE: Readonly = {\n min: -90, max: 90\n} as const;\nexport const DEFAULT_ZOOM_RANGE: Readonly = {\n min: 0.6, max: 10\n} as const;\n\nexport enum ROTATE {\n ZERO,\n CW_90,\n CCW_90,\n CW_180\n}\n\n// Custom event name for video time change\nexport const VIDEO_TIME_CHANGE_EVENT = \"view360videotimechange\";\nexport const SVG_NAMESPACE = \"http://www.w3.org/2000/svg\";\nexport const SESSION_VR = \"immersive-vr\";\nexport const XR_REFERENCE_SPACE = \"local\";\n\nexport const EPSILON = Number.EPSILON ?? 2.220446049250313e-16;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { quat, vec3 } from \"gl-matrix\";\nimport View360Error from \"./core/View360Error\";\nimport ERROR from \"./const/error\";\nimport * as BROWSER from \"./const/browser\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"./const/internal\";\nimport { NoBoolean } from \"./type/utils\";\n\nexport const isString = (val: any): val is string => typeof val === \"string\";\nexport const isElement = (val: any): val is Element => !!val && val.nodeType === Node.ELEMENT_NODE;\n\nexport const createElement = (className: string, tag = BROWSER.EL_DIV) => {\n const el = document.createElement(tag);\n\n el.classList.add(className);\n\n return el;\n};\n\nexport const getNullableElement = (el: HTMLElement | string | null, parent?: HTMLElement): HTMLElement | null => {\n let targetEl: HTMLElement | null = null;\n\n if (isString(el)) {\n const parentEl = parent ? parent : document;\n const queryResult = parentEl.querySelector(el);\n\n if (!queryResult) {\n return null;\n }\n\n targetEl = queryResult as HTMLElement;\n } else if (isElement(el)) {\n targetEl = el;\n }\n\n return targetEl;\n};\n\nexport const getElement = (el: HTMLElement | string, parent?: HTMLElement): HTMLElement => {\n const targetEl = getNullableElement(el, parent);\n\n if (!targetEl) {\n if (isString(el)) {\n throw new View360Error(ERROR.MESSAGES.ELEMENT_NOT_FOUND(el), ERROR.CODES.ELEMENT_NOT_FOUND);\n } else {\n throw new View360Error(ERROR.MESSAGES.WRONG_TYPE(el, [\"HTMLElement\", \"string\"]), ERROR.CODES.WRONG_TYPE);\n }\n }\n\n return targetEl;\n};\n\nexport const findCanvas = (root: HTMLElement, selector: string): HTMLCanvasElement => {\n const canvas = root.querySelector(selector) as HTMLCanvasElement;\n\n if (!canvas) {\n throw new View360Error(ERROR.MESSAGES.CANVAS_NOT_FOUND, ERROR.CODES.CANVAS_NOT_FOUND);\n }\n\n return canvas;\n};\n\nexport const range = (end: number): number[] => {\n if (!end || end <= 0) {\n return [];\n }\n\n return Array.apply(0, Array(end)).map((undef, idx) => idx);\n};\n\nexport const clamp = (x: number, min: number, max: number) => Math.max(Math.min(x, max), min);\n\n// Linear interpolation between a and b\nexport const lerp = (a: number, b: number, t: number) => {\n return a * (1 - t) + b * t;\n};\n\nexport const circulate = (val: number, min: number, max: number) => {\n const size = Math.abs(max - min);\n\n if (val < min) {\n const offset = (min - val) % size;\n val = max - offset;\n } else if (val > max) {\n const offset = (val - max) % size;\n val = min + offset;\n }\n\n return val;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const merge = (target: object, ...srcs: object[]): object => {\n srcs.forEach(source => {\n Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n });\n });\n\n return target;\n};\n\nexport const findIndex = (array: T[], checker: (val: T) => boolean): number => {\n for (let idx = 0; idx < array.length; idx++) {\n if (checker(array[idx])) {\n return idx;\n }\n }\n\n return -1;\n};\n\nexport const getObjectOption = >(val?: T): NoBoolean => typeof val === \"object\" ? val : {} as any;\nexport const toVerticalFov = (fovRadian: number, aspect: number) => {\n return Math.atan(Math.tan(fovRadian * 0.5) / aspect) * 2;\n};\n\nexport const reorderCube = (arr: T[], order: string, defaultOrder = \"RLUDFB\"): T[] => {\n return defaultOrder.split(\"\")\n .map(face => order.indexOf(face))\n .map(index => arr[index]);\n};\n\nexport const isFullscreen = () => {\n if (!document) return false;\n\n for (const key of BROWSER.FULLSCREEN_ELEMENT) {\n if (document[key]) return true;\n }\n\n return false;\n};\n\nexport const sensorCanBeEnabledIOS = () => {\n return !!DeviceMotionEvent && \"requestPermission\" in DeviceMotionEvent && window.isSecureContext;\n};\n\nexport const hfovToZoom = (baseFov: number, fov: number) => {\n const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5);\n const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5);\n\n return renderingWidth / zoomedWidth;\n};\n\nexport const eulerToQuat = (out: quat, yaw: number, pitch: number, roll: number): quat => {\n quat.identity(out);\n\n const pitchThreshold = 0.01;\n const pitchClamped = clamp(pitch, -90 + pitchThreshold, 90 - pitchThreshold);\n\n quat.rotateY(out, out, yaw * DEG_TO_RAD);\n quat.rotateX(out, out, pitchClamped * DEG_TO_RAD);\n quat.rotateZ(out, out, roll * DEG_TO_RAD);\n\n return out;\n};\n\n/**\n * Extract euler angles from the quaternion, except roll(z-axis rotation)\n * @hidden\n */\nexport const quatToEuler = (quaternion: quat) => {\n const x = quaternion[0];\n const y = quaternion[1];\n const z = quaternion[2];\n const w = quaternion[3];\n const x2 = x * x;\n const y2 = y * y;\n const z2 = z * z;\n const w2 = w * w;\n\n const unit = x2 + y2 + z2 + w2;\n const test = x * w - y * z;\n\n let pitch: number, yaw: number;\n\n if (test > 0.499995 * unit) {\n // singularity at the north pole\n pitch = Math.PI / 2;\n yaw = 2 * Math.atan2(y, x);\n } else if (test < -0.499995 * unit) {\n // singularity at the south pole\n pitch = -Math.PI / 2;\n yaw = -2 * Math.atan2(y, x);\n } else {\n const view = vec3.fromValues(0, 0, 1);\n const up = vec3.fromValues(0, 1, 0);\n\n vec3.transformQuat(view, view, quaternion);\n vec3.transformQuat(up, up, quaternion);\n\n const viewXZ = Math.sqrt(view[0] * view[0] + view[2] * view[2]);\n\n pitch = Math.atan2(-view[1], viewXZ);\n yaw = Math.atan2(view[0], view[2]);\n }\n\n return {\n pitch: clamp(pitch * RAD_TO_DEG, -90, 90),\n yaw: circulate(yaw * RAD_TO_DEG, 0, 360)\n };\n};\n","/*\n * Copyright (c) 2020 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport { clamp, lerp, circulate } from \"../utils\";\nimport { Range } from \"../type/utils\";\nimport { DEFAULT_ANIMATION_DURATION, DEFAULT_EASING } from \"../const/internal\";\n\n/**\n * Interpolator between two values with duration\n * @ko 특정 시간동안 두 값을 보간해주는 보간기\n * @since 4.0.0\n */\nclass Motion {\n // Options\n private _duration: number;\n private _loop: boolean;\n private _range: Range;\n private _easing: (x: number) => number;\n\n // Internal states\n private _progress: number;\n private _val: number;\n private _start: number;\n private _end: number;\n private _activated: boolean;\n\n /**\n * Current interpolated value\n * @ko 현재 보간된 값\n * @since 4.0.0\n */\n public get val() { return this._val; }\n /**\n * Start(from) value of interpolation\n * @ko 보간 시작 값\n * @since 4.0.0\n */\n public get start() { return this._start; }\n /**\n * End(to) value of interpolation\n * @ko 보간 끝 값\n * @since 4.0.0\n */\n public get end() { return this._end; }\n /**\n * Interpolation progress value (0 ~ 1)\n * @ko 현재 보간 진행정도 (0 ~ 1)\n * @since 4.0.0\n */\n public get progress() { return this._progress; }\n /**\n * Whether the interpolation is in active state.\n * @ko 보간 진행중인지 여부. `true`일 경우 보간이 진행중입니다.\n * @since 4.0.0\n */\n public get activated() { return this._activated; }\n\n /**\n * Duration of the interpolation\n * @ko 보간할 시간\n * @since 4.0.0\n */\n public get duration() { return this._duration; }\n public set duration(val: number) { this._duration = val; }\n\n /**\n * Whether to loop interpolation on finish\n * @ko 보간이 끝난 이후에 다시 시작할지 여부\n * @since 4.0.0\n */\n public get loop() { return this._loop; }\n public set loop(val: boolean) { this._loop = val; }\n\n /**\n * Range of the interpolation\n * @ko 보간 범위\n * @since 4.0.0\n */\n public get range() { return this._range; }\n\n /**\n * Easing function of the interpolation\n * @ko 보간에 사용되는 easing function\n * @since 4.0.0\n */\n public get easing() { return this._easing; }\n public set easing(val: (x: number) => number) { this._easing = val; }\n\n /**\n * Create new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options Options {@ko 옵션들}\n * @param options.duration Duration of the interpolation {@ko 보간할 시간}\n * @param options.loop Whether to loop interpolation on finish {@ko 보간이 끝난 이후에 다시 시작할지 여부}\n * @param options.range Range of the interpolation {@ko 보간 범위}\n * @param options.loop Easing function of the interpolation {@ko 보간에 사용되는 easing function}\n */\n public constructor({\n duration = DEFAULT_ANIMATION_DURATION,\n loop = false,\n range = { min: 0, max: 1 },\n easing = DEFAULT_EASING\n } = {}) {\n this._duration = duration;\n this._loop = loop;\n this._range = range;\n this._easing = easing;\n this._activated = false;\n this.reset(0);\n }\n\n /**\n * Update motion and progress it by given deltaTime\n * @ko 주어진 deltaTime만큼 보간을 진행합니다.\n * @param deltaTime - number of milisec to update motion {@ko 보간을 진행할 시간, 밀리초 단위}\n * @returns Difference(delta) of the value from the last update. {@ko 지난 업데이트 이후의 값 변화량}\n * @since 4.0.0\n */\n public update(deltaTime: number): number {\n if (!this._activated) {\n this._val = this._end;\n return 0;\n }\n\n const start = this._start;\n const end = this._end;\n const duration = this._duration;\n const prev = this._val;\n const loop = this._loop;\n\n const nextProgress = this._progress + deltaTime / duration;\n\n this._progress = loop\n ? circulate(nextProgress, 0, 1)\n : clamp(nextProgress, 0, 1);\n\n const easedProgress = this._easing(this._progress);\n this._val = lerp(start, end, easedProgress);\n\n if (!loop && this._progress >= 1) {\n this._activated = false;\n }\n\n return this._val - prev;\n }\n\n /**\n * Set `start`, `end` to the given value and set `progress` to 0.\n * @ko 주어진 값으로 시작 지점, 끝 지점을 초기화하고 progress를 0으로 세팅합니다.\n * @param defaultVal - Value to reset {@ko 초기화할 값}\n * @since 4.0.0\n */\n public reset(defaultVal: number): void {\n const range = this._range;\n const val = clamp(defaultVal, range.min, range.max);\n this._start = val;\n this._end = val;\n this._val = val;\n this._progress = 0;\n this._activated = false;\n }\n\n /**\n * Add delta to start & end and current value.\n * @ko 현재 & 끝 및 현재 값에 주어진 값을 더합니다.\n * @param delta - Delta value to add {@ko 추가할 값}\n */\n public add(delta: number) {\n const range = this._range;\n\n this._start = clamp(this._start + delta, range.min, range.max);\n this._end = clamp(this._end + delta, range.min, range.max);\n this._val = clamp(this._val + delta, range.min, range.max);\n }\n\n /**\n * Set current value to start, and end to current value + delta, then reset progress to 0.\n * @ko 현재 값을 시작 지점으로, 그에서 delta만큼 추가된 값을 끝점으로 하고 progress를 0으로 갱신합니다.\n * @param delta - Delta value to add {@ko 추가할 값}\n */\n public setNewEndByDelta(delta: number): void {\n const range = this._range;\n\n this._start = this._val;\n this._end = clamp(this._end + delta, range.min, range.max);\n this._progress = 0;\n this._activated = true;\n }\n\n /**\n * Set new range of the interpolation.\n * @ko 보간의 범위를 변경합니다.\n * @param min - New minimum range {@ko 변경할 범위의 최소값}\n * @param max - New maximum range {@ko 변경할 범위의 최대값}\n */\n public setRange(min: number, max: number) {\n this._start = clamp(this._start, min, max);\n this._end = clamp(this._end, min, max);\n this._range = { min, max };\n }\n}\n\nexport default Motion;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { quat } from \"gl-matrix\";\nimport Camera from \"./Camera\";\nimport Motion from \"./Motion\";\nimport { DEFAULT_ANIMATION_DURATION, DEFAULT_EASING } from \"../const/internal\";\nimport { lerp } from \"../utils\";\n\ntype CameraPose = {\n rotation: quat;\n zoom: number;\n}\n\n/**\n * Animation of the {@link Camera}\n * @internal\n * @ko {@link Camera}의 애니메이션\n * @since 4.0.0\n */\nclass CameraAnimation {\n // Options\n private _camera: Camera;\n private _from: CameraPose;\n private _to: CameraPose;\n\n // Internal values\n private _motion: Motion;\n private _finishPromise: Promise;\n private _finish: () => void;\n\n /**\n * Duration of the animation\n * @ko 애니메이션 재생시간\n * @since 4.0.0\n */\n public get duration() { return this._motion.duration; }\n public set duration(val: number) { this._motion.duration = val; }\n /**\n * Easing function of the animation\n * @ko 애니메이션의 easing function\n * @since 4.0.0\n */\n public get easing() { return this._motion.easing; }\n public set easing(val: (x: number) => number) { this._motion.easing = val; }\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param camera - Camera to animate {@ko 애니메이션을 적용할 카메라}\n * @param from - Start pose {@ko 애니메이션이 시작 시점의 카메라의 회전 및 줌}\n * @param to - End pose {@ko 애니메이션이 끝났을 때 카메라의 회전 및 줌}\n * @param options - Options {@ko 옵션들}\n * @param options.duration - Animation duration {@ko 애니메이션 재생 시간}\n * @param options.easing - Animation easing function {@ko 애니메이션 easing function}\n */\n public constructor(camera: Camera, from: CameraPose, to: CameraPose, {\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING\n } = {}) {\n this._camera = camera;\n this._motion = new Motion({ duration, easing, range: { min: 0, max: 1 } });\n this._from = from;\n this._to = to;\n this._finishPromise = new Promise(resolve => {\n this._finish = resolve as () => void;\n });\n\n // Enable motion\n this._motion.setNewEndByDelta(1);\n }\n\n /**\n * Return a promise that resolved on animation end.\n * @ko 애니메이션 재생이 끝났을 때 resolve되는 Promise를 반환합니다.\n * @since 4.0.0\n */\n public getFinishPromise() {\n return this._finishPromise;\n }\n\n /**\n * Update animation by given deltaTime.\n * @ko 주어진 시간만큼 애니메이션을 업데이트합니다.\n * @param deltaTime Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n */\n public update(deltaTime: number): void {\n const camera = this._camera;\n const from = this._from;\n const to = this._to;\n const motion = this._motion;\n motion.update(deltaTime);\n\n // Progress that easing is applied\n const progress = motion.val;\n const rotation = quat.create();\n const zoom = lerp(from.zoom, to.zoom, progress);\n\n quat.slerp(rotation, from.rotation, to.rotation, progress);\n camera.rotate(rotation, zoom);\n\n if (progress >= 1) {\n this._finish();\n }\n }\n}\n\nexport default CameraAnimation;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { mat4, quat, vec3 } from \"gl-matrix\";\nimport CameraAnimation from \"./CameraAnimation\";\nimport {\n CAMERA_EVENTS,\n DEG_TO_RAD,\n INFINITE_RANGE,\n DEFAULT_PITCH_RANGE,\n RAD_TO_DEG,\n DEFAULT_ZOOM_RANGE,\n DEFAULT_EASING,\n EPSILON\n} from \"../const/internal\";\nimport {\n circulate,\n clamp,\n eulerToQuat,\n quatToEuler,\n toVerticalFov\n} from \"../utils\";\nimport { Range } from \"../type/utils\";\n\n/**\n * Events that {@link Camera} can trigger\n * @ko {@link Camera}가 트리거할 수 있는 이벤트들\n * @since 4.0.0\n */\nexport interface CameraEvents {\n /**\n * An event that fires when camera's animation stops\n * @ko 카메라 애니메이션이 멈췄을 때 트리거되는 이벤트\n * @eventName animationEnd\n * @eventOf Camera\n * @version 4.0.0\n */\n [CAMERA_EVENTS.ANIMATION_END]: {\n animation: CameraAnimation\n };\n}\n\n/**\n * Options for {@link Camera}\n * @ko {@link Camera}용 옵션들\n * @since 4.0.0\n */\nexport interface CameraOptions {\n /**\n * @copy View360#initialYaw\n */\n initialYaw: number;\n /**\n * @copy View360#initialPitch\n */\n initialPitch: number;\n /**\n * @copy View360#initialZoom\n */\n initialZoom: number;\n /**\n * @copy View360#yawRange\n */\n yawRange: Range | null;\n /**\n * @copy View360#pitchRange\n */\n pitchRange: Range | null;\n /**\n * @copy View360#zoomRange\n */\n zoomRange: Range | null;\n /**\n * @copy View360#fov\n */\n fov: number;\n}\n\n/**\n * Camera for View360\n * @ko View360용 카메라 구현체\n * @version 4.0.0\n */\nclass Camera extends Component {\n /**\n * Current yaw(y-axis rotation) value\n * @ko 현재 yaw(y축 회전) 값\n * @since 4.0.0\n */\n public yaw: number;\n /**\n * Current pitch(x-axis rotation) value\n * @ko 현재 pitch(x축 회전) 값\n * @since 4.0.0\n */\n public pitch: number;\n /**\n * Current zoom value\n * @ko 현재 줌 값\n * @since 4.0.0\n */\n public zoom: number;\n\n /**\n * @copy View360#initialYaw\n */\n public initialYaw: number;\n /**\n * @copy View360#initialPitch\n */\n public initialPitch: number;\n /**\n * @copy View360#initialPitch\n */\n public initialZoom: number;\n /**\n * @hidden\n * TODO: Please add comment for this when `rollOffset` is added\n */\n public rollOffset: number;\n\n /**\n * Current camera quaternion\n * @ko 현재 회전을 나타내는 quaternion 값\n * @since 4.0.0\n * @internal\n */\n public quaternion: quat;\n /**\n * Current camera position\n * @ko 현재 카메라 위치 좌표\n * @since 4.0.0\n * @internal\n */\n public position: vec3;\n /**\n * Active camera animation, `null` if there isn't.\n * @ko 현재 활성화된 카메라 애니메이션, 없을 경우 `null`값을 가집니다.\n * @since 4.0.0\n */\n public animation: CameraAnimation | null;\n /**\n * Camera's view matrix\n * @ko 카메라의 뷰 변환 행렬\n * @internal\n * @since 4.0.0\n */\n public viewMatrix: mat4;\n /**\n * Camera's projection matrix\n * @ko 카메라의 프로젝션 변환 행렬\n * @internal\n * @since 4.0.0\n */\n public projectionMatrix: mat4;\n\n /**\n * Camera's horizontal FOV(Field of View) value\n * @ko 카메라의 수평 FOV(Field of View) 값\n * @internal\n * @since 4.0.0\n */\n public fov: number;\n\n private _initialYawRange: Range | null;\n private _initialPitchRange: Range | null;\n private _initialZoomRange: Range | null;\n\n private _yawRange: Range | null;\n private _pitchRange: Range | null;\n private _zoomRange: Range | null;\n\n private _up: vec3;\n private _aspect: number;\n private _changed: boolean;\n private _maxRenderHeight: number;\n\n /**\n * Camera's width / height ratio\n * @ko 카메라의 가로 / 세로 비율\n * @readonly\n */\n public get aspect() { return this._aspect; }\n /**\n * Whether the camera's rotation changed from the last frame.\n * @ko 마지막 프레임 이후로 카메라의 회전값이 변경되었는지 나타내는 플래그.\n * @readonly\n */\n public get changed() { return this._changed; }\n /**\n * @copy View360#yawRange\n */\n public get yawRange() { return this._initialYawRange; }\n public set yawRange(val: Range | null) {\n this._initialYawRange = val;\n }\n /**\n * @copy View360#pitchRange\n */\n public get pitchRange() { return this._initialPitchRange; }\n public set pitchRange(val: Range | null) {\n this._initialPitchRange = val;\n }\n /**\n * @copy View360#zoomRange\n */\n public get zoomRange() { return this._initialZoomRange; }\n public set zoomRange(val: Range | null) {\n this._initialZoomRange = val;\n }\n\n /**\n * Create new instance of Camera\n * @param options - Camera options {@ko 카메라 옵션들}\n */\n public constructor({\n initialYaw,\n initialPitch,\n initialZoom,\n yawRange,\n pitchRange,\n zoomRange,\n fov\n }: CameraOptions) {\n super();\n\n this.yaw = initialYaw;\n this.pitch = initialPitch;\n this.zoom = initialZoom;\n this.rollOffset = 0;\n\n this.initialYaw = initialYaw;\n this.initialPitch = initialPitch;\n this.initialZoom = initialZoom;\n\n this.position = vec3.create();\n this.animation = null;\n\n this._up = vec3.fromValues(0, 1, 0);\n this._aspect = 1;\n\n this._initialYawRange = yawRange;\n this._initialPitchRange = pitchRange;\n this._initialZoomRange = zoomRange;\n\n this._yawRange = yawRange;\n this._pitchRange = pitchRange;\n this._zoomRange = zoomRange;\n\n this.quaternion = quat.create();\n this._updateQuaternion();\n\n this.viewMatrix = mat4.create();\n this.projectionMatrix = mat4.create();\n this.fov = fov;\n\n this._maxRenderHeight = -1;\n }\n\n /**\n * Destroy instance and detach all event listeners\n * @ko 인스턴스를 삭제하고 모든 이벤트 리스너를 삭제합니다.\n * @since 4.0.0\n */\n public destroy() {\n this.off();\n }\n\n /**\n * Refresh internal size value.\n * @ko 내부 크기값을 갱신합니다.\n * @param width - New width {@ko 변경된 너비값}\n * @param height - New height {@ko 변경된 높이값}\n * @since 4.0.0\n */\n public resize(width: number, height: number) {\n const prevAspect = this._aspect;\n\n this._aspect = width / height;\n\n if (this._aspect !== prevAspect) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation with euler values.\n * @ko 카메라 회전을 오일러 각 방향으로 변경합니다.\n * @param rotation - Rotation values {@ko 회전 값}\n * @param rotation.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값}\n * @param rotation.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값}\n * @param rotation.zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @since 4.0.0\n */\n public lookAt({\n yaw = this.yaw,\n pitch = this.pitch,\n zoom = this.zoom\n }: Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n }>) {\n const prevQuaternion = quat.clone(this.quaternion);\n const prevZoom = this.zoom;\n\n this.yaw = circulate(yaw, 0, 360);\n this.pitch = clamp(pitch, -90, 90);\n this.zoom = zoom;\n\n this._updateQuaternion();\n\n const zoomDiff = Math.abs(zoom - prevZoom);\n\n if (\n !quat.equals(this.quaternion, prevQuaternion)\n || zoomDiff >= EPSILON * 10 // ignore small changes\n ) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation with quaternion.\n * @ko 카메라 회전을 Quaternion을 이용해서 변경합니다.\n * @param rotation - Quaternion to apply {@ko 적용할 Quaternion}\n * @param zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @since 4.0.0\n */\n public rotate(rotation: quat, zoom: number = this.zoom) {\n const normalized = quat.normalize(quat.create(), rotation);\n const isSameRotation = quat.equals(this.quaternion, normalized);\n quat.copy(this.quaternion, normalized);\n\n const prevZoom = this.zoom;\n const { yaw, pitch } = quatToEuler(normalized);\n\n this.yaw = yaw;\n this.pitch = pitch;\n this.zoom = zoom;\n\n const zoomDiff = Math.abs(zoom - prevZoom);\n\n if (!isSameRotation || zoomDiff >= EPSILON * 10) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation to given euler values by the given duration.\n * @ko 카메라를 주어진 방향으로 주어진 시간동안 서서히 이동시킵니다.\n * @param options - Animation parameters {@ko 애니메이션 패러미터}\n * @param options.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값}\n * @param options.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값}\n * @param options.zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @param options.duration - Duration of the animation {@ko 애니메이션 시간}\n * @param options.easing - Easing function for the animation {@ko 애니메이션에 적용할 easing function}\n */\n public async animateTo({\n yaw = this.yaw,\n pitch = this.pitch,\n zoom = this.zoom,\n duration = 0,\n easing = DEFAULT_EASING\n }: Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n duration: number;\n easing: (x: number) => number;\n }> = {}): Promise {\n if (\n this.yaw === yaw\n && this.pitch === pitch\n && this.zoom === zoom\n ) return;\n\n const from = {\n rotation: quat.clone(this.quaternion),\n zoom: this.zoom\n };\n const to = {\n rotation: eulerToQuat(quat.create(), yaw, pitch, this.rollOffset),\n zoom\n };\n\n const animation = new CameraAnimation(this, from, to, {\n duration,\n easing\n });\n const finishPromise = animation.getFinishPromise();\n\n this.animation = animation;\n finishPromise.then(() => {\n this.animation = null;\n this.trigger(CAMERA_EVENTS.ANIMATION_END, { animation });\n });\n\n return finishPromise;\n }\n\n /**\n * @hidden\n */\n public restrictYawRange(min: number, max: number) {\n this._yawRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictPitchRange(min: number, max: number) {\n this._pitchRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictZoomRange(min: number, max: number) {\n this._zoomRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictRenderHeight(height: number) {\n this._maxRenderHeight = height;\n }\n\n /**\n * @hidden\n */\n public resetRange() {\n this._yawRange = this._initialYawRange;\n this._pitchRange = this._initialPitchRange;\n this._zoomRange = this._initialZoomRange;\n this._maxRenderHeight = -1;\n }\n\n /**\n * Get actual yaw range by the given zoom value.\n * @ko 주어진 zoom 값에 대한 실제 yaw 범위값을 반환합니다.\n * @since 4.0.0\n */\n public getYawRange(zoom: number) {\n const yawLimit = this._yawRange;\n const maxRenderHeight = this._maxRenderHeight;\n if (!yawLimit) return INFINITE_RANGE;\n\n const halfHFov = this.getHorizontalFov(zoom) * 0.5;\n let minYaw = yawLimit.min;\n let maxYaw = yawLimit.max;\n\n if (maxRenderHeight > 0) {\n const halfVFovRad = toVerticalFov(halfHFov * DEG_TO_RAD, this._aspect);\n const h = maxRenderHeight * 0.5;\n const t = Math.tan(halfVFovRad);\n const d = Math.sqrt((1 + h * h) / (1 + t * t));\n const theta = Math.atan(Math.tan(halfHFov * DEG_TO_RAD) * d) * RAD_TO_DEG;\n\n minYaw = yawLimit.min + theta;\n maxYaw = yawLimit.max - theta;\n }\n\n if (minYaw > maxYaw) {\n minYaw = 0;\n maxYaw = 0;\n }\n\n return {\n min: minYaw,\n max: maxYaw\n };\n }\n\n /**\n * Get actual pitch range by the given zoom value.\n * @ko 주어진 zoom 값에 대한 실제 pitch 범위값을 반환합니다.\n * @since 4.0.0\n */\n public getPitchRange(zoom: number) {\n const pitchLimit = this._pitchRange;\n const maxRenderHeight = this._maxRenderHeight;\n\n if (!pitchLimit) return DEFAULT_PITCH_RANGE;\n\n let minPitch = pitchLimit.min;\n let maxPitch = pitchLimit.max;\n\n if (maxRenderHeight > 0) {\n const halfVFov = this.getVerticalFov(zoom) * 0.5;\n\n minPitch = pitchLimit.min + halfVFov;\n maxPitch = pitchLimit.max - halfVFov;\n }\n\n if (minPitch > maxPitch) {\n minPitch = 0;\n maxPitch = 0;\n }\n\n return {\n min: Math.max(minPitch, -90),\n max: Math.min(maxPitch, 90)\n };\n }\n\n /**\n * Get actual zoom range in fov degrees.\n * @ko 실제 줌 범위를 fov각의 범위로 반환합니다.\n * @since 4.0.0\n */\n public getZoomRange() {\n const limit = this._zoomRange ?? DEFAULT_ZOOM_RANGE;\n\n // max (zoom in) -> minimum fov\n const minFov = this.getHorizontalFov(limit.max);\n const maxFov = this.getHorizontalFov(limit.min);\n const currentFov = this.getHorizontalFov(this.zoom);\n\n return {\n min: Math.max(minFov, 1),\n max: Math.min(maxFov, 180),\n current: currentFov\n };\n }\n\n /**\n * Return horizontal fov value when the given zoom is applied. (in degrees, °)\n * @ko 주어진 zoom 값이 적용되었을 때의 수평 fov값을 반환합니다. (도 단위, °)\n * @returns Zoomed horizontal FOV {@ko 줌이 적용된 수평 fov값}\n * @since 4.0.0\n */\n public getHorizontalFov(zoom = this.zoom) {\n return this._getZoomedHorizontalFov(zoom) * RAD_TO_DEG;\n }\n\n /**\n * Return vertical fov value when the given zoom is applied. (in degrees, °)\n * @ko 주어진 zoom 값이 적용되었을 때의 수직 fov값을 반환합니다. (도 단위, °)\n * @returns Zoomed vertical FOV {@ko 줌이 적용된 수직 fov값}\n * @since 4.0.0\n */\n public getVerticalFov(zoom = this.zoom) {\n const aspect = this._aspect;\n const hFov = this._getZoomedHorizontalFov(zoom); // In radians\n const vFov = toVerticalFov(hFov, aspect);\n\n return vFov * RAD_TO_DEG;\n }\n\n /**\n * Calculate zoom value for the given fov.\n * @ko 주어진 fov값을 zoom값으로 변환합니다.\n * @param fov horizontal fov (in degrees, °) {@ko 수평 fov 값 (도 단위, °)}\n * @since 4.0.0\n */\n public fovToZoom(fov: number) {\n const baseFov = this.fov;\n const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5);\n const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5);\n\n return renderingWidth / zoomedWidth;\n }\n\n /**\n * Update inner matrixes.\n * @ko 내부 행렬들을 업데이트합니다.\n * @internal\n * @since 4.0.0\n */\n public updateMatrix() {\n const up = this._up;\n const aspect = this._aspect;\n const viewMatrix = this.viewMatrix;\n const projMatrix = this.projectionMatrix;\n const position = this.position;\n const rotation = this.quaternion;\n\n const upDir = vec3.create();\n const viewDir = vec3.fromValues(0, 0, -1);\n vec3.transformQuat(viewDir, viewDir, rotation);\n vec3.transformQuat(upDir, up, rotation);\n\n const hFov = this._getZoomedHorizontalFov(); // In radians\n const vFov = toVerticalFov(hFov, aspect);\n\n mat4.lookAt(viewMatrix, position, viewDir, upDir);\n mat4.perspective(projMatrix, vFov, aspect, 0.1, 100);\n\n this._changed = true;\n }\n\n /**\n * @hidden\n */\n public onFrameRender() {\n this._changed = false;\n }\n\n private _updateQuaternion() {\n eulerToQuat(this.quaternion, this.yaw, this.pitch, this.rollOffset);\n }\n\n /**\n * @param zoom Current zoom value\n * @returns horizontal fov including zoom, in radian\n */\n private _getZoomedHorizontalFov(zoom = this.zoom) {\n return 2 * Math.atan(Math.tan(DEG_TO_RAD * this.fov * 0.5) / zoom);\n }\n}\n\nexport default Camera;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass MouseInput extends Component> {\n private _el: HTMLElement | null;\n private _prevPos: [number, number];\n\n public constructor() {\n super();\n\n this._el = null;\n this._prevPos = [0, 0];\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onMouseDown);\n\n this._el = element;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onMouseDown);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this._el = null;\n }\n\n private _onMouseDown = (evt: MouseEvent) => {\n const el = this._el;\n if (!el || evt.button !== BROWSER.MOUSE_BUTTON.LEFT) return;\n\n evt.preventDefault();\n\n if (el.focus) {\n el.focus();\n } else {\n window.focus();\n }\n\n this._prevPos[0] = evt.clientX;\n this._prevPos[1] = evt.clientY;\n\n window.addEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.addEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: false\n });\n }\n\n private _onMouseMove = (evt: MouseEvent) => {\n evt.preventDefault();\n\n const x = evt.clientX;\n const y = evt.clientY;\n const prevPos = this._prevPos;\n const deltaX = x - prevPos[0];\n const deltaY = y - prevPos[1];\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta: {\n x: deltaX,\n y: deltaY\n },\n isTouch: false,\n isKeyboard: false\n });\n\n prevPos[0] = x;\n prevPos[1] = y;\n }\n\n private _onMouseUp = () => {\n this._prevPos[0] = 0;\n this._prevPos[1] = 0;\n\n window.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: false,\n scrolling: false\n });\n }\n}\n\nexport default MouseInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\nimport { isFullscreen } from \"../../utils\";\n\nclass TouchInput extends Component> {\n private _el: HTMLElement | null;\n private _prevPos: [number, number];\n private _isFirstTouch: boolean;\n private _scrolling: boolean;\n private _scrollable: boolean;\n\n public get scrollable() { return this._scrollable; }\n public set scrollable(val: boolean) { this._scrollable = val; }\n\n public constructor() {\n super();\n\n this._el = null;\n this._prevPos = [0, 0];\n this._isFirstTouch = false;\n this._scrolling = false;\n this._scrollable = false;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.TOUCH_START, this._onTouchStart, { passive: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, { passive: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = element;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.TOUCH_START, this._onTouchStart);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = null;\n }\n\n private _onTouchStart = (evt: TouchEvent) => {\n if (evt.touches.length > 1 || this._scrolling) return;\n\n const touch = evt.touches[0];\n\n this._isFirstTouch = true;\n this._prevPos[0] = touch.clientX;\n this._prevPos[1] = touch.clientY;\n\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: true,\n isKeyboard: false\n });\n };\n\n private _onTouchMove = (evt: TouchEvent) => {\n // Only the one finger motion should be considered\n if (evt.touches.length > 1 || this._scrolling) return;\n\n const touch = evt.touches[0];\n const scrollable = this._scrollable;\n const prevPos = this._prevPos;\n\n const x = touch.clientX;\n const y = touch.clientY;\n const deltaX = x - prevPos[0];\n const deltaY = y - prevPos[1];\n\n if (this._isFirstTouch) {\n if (scrollable && !isFullscreen()) {\n if (Math.abs(deltaY) > Math.abs(deltaX)) {\n // Assume Scrolling\n this._scrolling = true;\n return;\n }\n }\n\n this._isFirstTouch = false;\n }\n\n if (evt.cancelable !== false) {\n evt.preventDefault();\n }\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta: {\n x: deltaX,\n y: deltaY\n },\n isTouch: true,\n isKeyboard: false\n });\n\n prevPos[0] = x;\n prevPos[1] = y;\n };\n\n private _onTouchEnd = (evt: TouchEvent) => {\n if (evt.touches.length !== 0) return;\n\n const touch = evt.touches[0];\n const prevPos = this._prevPos;\n\n if (touch) {\n prevPos[0] = touch.clientX;\n prevPos[1] = touch.clientY;\n } else {\n prevPos[0] = 0;\n prevPos[1] = 0;\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: true,\n isKeyboard: false,\n scrolling: this._scrolling\n });\n }\n\n if (evt.cancelable !== false) {\n evt.preventDefault();\n }\n\n this._scrolling = false;\n };\n}\n\nexport default TouchInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass KeyboardInput extends Component> {\n private _el: HTMLElement | null;\n private _pressed: {\n LEFT: boolean;\n UP: boolean;\n RIGHT: boolean;\n DOWN: boolean;\n };\n\n public get active() {\n const pressed = this._pressed;\n return pressed.LEFT || pressed.UP || pressed.RIGHT || pressed.DOWN;\n }\n\n public constructor() {\n super();\n\n this._el = null;\n this._clearPressedKeys();\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown);\n element.addEventListener(BROWSER.EVENTS.KEY_UP, this._onKeyUp);\n\n this._el = element;\n this._clearPressedKeys();\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown);\n element.removeEventListener(BROWSER.EVENTS.KEY_UP, this._onKeyUp);\n\n this._el = null;\n this._clearPressedKeys();\n }\n\n public update() {\n const delta = this._getDeltaByPressedKeys();\n\n if (delta.x !== 0 || delta.y !== 0) {\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: false,\n isKeyboard: true\n });\n }\n }\n\n private _clearPressedKeys() {\n this._pressed = BROWSER.KEY_DIRECTION.reduce((obj, keyName) => {\n return {\n ...obj,\n [keyName]: false\n };\n }, {} as KeyboardInput[\"_pressed\"]);\n }\n\n private _updateKeyPress(event: KeyboardEvent, isEnable: boolean): void {\n const pressed = this._pressed;\n const keyToUpdate = event.keyCode != null\n ? BROWSER.DIRECTION_KEY_CODE[event.keyCode]\n : BROWSER.DIRECTION_KEY_NAME[event.key];\n\n if (!keyToUpdate) return;\n\n pressed[keyToUpdate] = isEnable;\n }\n\n private _getPressedKeyCount() {\n return BROWSER.KEY_DIRECTION.filter(key => this._pressed[key]).length;\n }\n\n private _getDeltaByPressedKeys() {\n const pressed = this._pressed;\n let x = 0;\n let y = 0;\n\n if (pressed.LEFT) {\n x += 1;\n }\n\n if (pressed.RIGHT) {\n x -= 1;\n }\n\n if (pressed.UP) {\n y += 1;\n }\n\n if (pressed.DOWN) {\n y -= 1;\n }\n\n return {\n x, y\n };\n }\n\n private _onKeyDown = (evt: KeyboardEvent) => {\n // Ignore all other keypress except main arrow keys\n if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return;\n\n this._updateKeyPress(evt, true);\n\n const pressedCount = this._getPressedKeyCount();\n if (pressedCount <= 0) return;\n\n evt.preventDefault();\n if (pressedCount === 1 && !evt.repeat) {\n // On first keydown\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: true\n });\n }\n };\n\n private _onKeyUp = (evt: KeyboardEvent) => {\n // Ignore all other keypress except main arrow keys\n if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return;\n\n this._updateKeyPress(evt, false);\n\n const pressedCount = this._getPressedKeyCount();\n if (pressedCount > 0) return;\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: true,\n scrolling: false\n });\n };\n}\n\nexport default KeyboardInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport MouseInput from \"./input/MouseInput\";\nimport TouchInput from \"./input/TouchInput\";\nimport KeyboardInput from \"./input/KeyboardInput\";\nimport Camera from \"../core/Camera\";\nimport Motion from \"../core/Motion\";\nimport { CONTROL_EVENTS, INFINITE_RANGE, DEFAULT_PITCH_RANGE, DEFAULT_ANIMATION_DURATION, DEFAULT_EASING, DEG_TO_RAD, RAD_TO_DEG } from \"../const/internal\";\nimport { toVerticalFov } from \"../utils\";\nimport { ControlEvents, InputEvents } from \"../type/internal\";\n\n/**\n * Options for {@link RotateControl}\n * @ko {@link RotateControl}용 옵션들\n * @since 4.0.0\n */\nexport interface RotateControlOptions {\n /**\n * @copy RotateControl#pointerScale\n */\n pointerScale: [number, number];\n /**\n * @copy RotateControl#keyboardScale\n */\n keyboardScale: [number, number];\n /**\n * @copy RotateControl#duration\n */\n duration: number;\n /**\n * @copy RotateControl#easing\n */\n easing: (x: number) => number;\n /**\n * @copy RotateControl#disablePitch\n */\n disablePitch: boolean;\n /**\n * @copy RotateControl#disableYaw\n */\n disableYaw: boolean;\n /**\n * @copy RotateControl#disableKeyboard\n */\n disableKeyboard: boolean;\n}\n\ntype RotateDeltaType = { x: number; y: number; };\nexport type RotateControlEvents = ControlEvents;\n\n/**\n * Camera's rotation control\n * @ko 카메라의 회전을 담당하는 컨트롤\n * @since 4.0.0\n */\nclass RotateControl extends Component implements CameraControl {\n // Options\n private _pointerScale: RotateControlOptions[\"pointerScale\"];\n private _keyboardScale: RotateControlOptions[\"keyboardScale\"];\n private _duration: RotateControlOptions[\"duration\"];\n private _easing: RotateControlOptions[\"easing\"];\n private _disablePitch: RotateControlOptions[\"disablePitch\"];\n private _disableYaw: RotateControlOptions[\"disableYaw\"];\n private _disableKeyboard: RotateControlOptions[\"disableKeyboard\"];\n\n // Internal values\n private _controlEl: HTMLElement;\n private _enableBlocked: boolean;\n private _mouseInput: MouseInput;\n private _touchInput: TouchInput;\n private _keyboardInput: KeyboardInput;\n private _xMotion: Motion;\n private _yMotion: Motion;\n private _screenScale: [number, number];\n private _zoomScale: number;\n private _enabled: boolean;\n private _changedWhileDragging: boolean;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() {\n return this._keyboardInput.active\n || this._xMotion.activated\n || this._yMotion.activated;\n }\n /**\n * Current yaw value\n * @ko 현재 yaw 값\n * @readonly\n * @since 4.0.0\n */\n public get yaw() { return this._xMotion; }\n /**\n * Current pitch value\n * @ko 현재 pitch 값\n * @readonly\n * @since 4.0.0\n */\n public get pitch() { return this._yMotion; }\n /**\n * @copy View360#scrollable\n */\n public get scrollable() { return this._touchInput.scrollable; }\n public set scrollable(val: boolean) {\n this._touchInput.scrollable = val;\n }\n\n /**\n * Scale factor for mouse/touch rotation\n * @ko 마우스/터치를 통한 회전 배율\n * @default [1, 1]\n * @since 4.0.0\n */\n public get pointerScale() { return this._pointerScale; }\n public set pointerScale(val: RotateControlOptions[\"pointerScale\"]) {\n this._pointerScale = val;\n }\n\n /**\n * Scale factor for keyboard rotation\n * @ko 키보드를 통한 회전 배율\n * @default [1, 1]\n * @since 4.0.0\n */\n public get keyboardScale() { return this._keyboardScale; }\n public set keyboardScale(val: RotateControlOptions[\"keyboardScale\"]) {\n this._keyboardScale = val;\n }\n\n /**\n * Duration of the input animation (ms)\n * @ko 회전 애니메이션의 시간 (ms)\n * @default 300\n */\n public get duration() { return this._duration; }\n public set duration(val: RotateControlOptions[\"duration\"]) {\n this._duration = val;\n this._xMotion.duration = val;\n this._yMotion.duration = val;\n }\n\n /**\n * Easing function of the animation\n * @ko 회전 애니메이션에 적용할 easing 함수\n * @default EASING.EASE_OUT_CUBIC\n * @see EASING\n */\n public get easing() { return this._easing; }\n public set easing(val: RotateControlOptions[\"easing\"]) {\n this._easing = val;\n this._xMotion.easing = val;\n this._yMotion.easing = val;\n }\n\n /**\n * Disable X-axis(pitch) rotation.\n * @ko x축 회전(pitch)을 비활성화합니다.\n * @default false\n */\n public get disablePitch() { return this._disablePitch; }\n public set disablePitch(val: RotateControlOptions[\"disablePitch\"]) { this._disablePitch = val; }\n\n /**\n * Disable Y-axis(yaw) rotation.\n * @ko y축 회전(yaw)을 비활성화합니다.\n * @default false\n */\n public get disableYaw() { return this._disableYaw; }\n public set disableYaw(val: RotateControlOptions[\"disableYaw\"]) { this._disableYaw = val; }\n\n /**\n * Disable rotation by keyboard.\n * @ko 키보드를 이용한 회전을 비활성화합니다.\n * @default false\n */\n public get disableKeyboard() { return this._disableKeyboard; }\n public set disableKeyboard(val: RotateControlOptions[\"disableKeyboard\"]) { this._disableKeyboard = val; }\n\n /**\n * Create new RotateControl instance\n * @ko RotateControl의 인스턴스를 생성합니다.\n * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트}\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(controlEl: HTMLElement, enableBlocked: boolean, {\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING,\n pointerScale = [1, 1],\n keyboardScale = [1, 1],\n disablePitch = false,\n disableYaw = false,\n disableKeyboard = false\n }: Partial = {}) {\n super();\n\n this._controlEl = controlEl;\n this._pointerScale = pointerScale;\n this._keyboardScale = keyboardScale;\n this._duration = duration;\n this._easing = easing;\n this._disablePitch = disablePitch;\n this._disableYaw = disableYaw;\n this._disableKeyboard = disableKeyboard;\n\n this._enableBlocked = enableBlocked;\n this._mouseInput = new MouseInput();\n this._touchInput = new TouchInput();\n this._keyboardInput = new KeyboardInput();\n this._xMotion = new Motion({ duration, range: INFINITE_RANGE, easing });\n this._yMotion = new Motion({ duration, range: DEFAULT_PITCH_RANGE, easing });\n this._screenScale = [1, 1];\n this._zoomScale = 1;\n this._enabled = false;\n this._changedWhileDragging = false;\n this._bindInputs();\n }\n\n public destroy(): void {\n this.disable();\n this._mouseInput.off();\n this._touchInput.off();\n this._keyboardInput.off();\n this.off();\n this._changedWhileDragging = false;\n }\n\n /**\n * @hidden\n */\n public update(delta: number): void {\n if (!this._enabled) return;\n\n const xMotion = this._xMotion;\n const yMotion = this._yMotion;\n const keyboardInput = this._keyboardInput;\n\n if (!this._disableKeyboard) {\n keyboardInput.update();\n }\n\n if (!this._disablePitch) {\n yMotion.update(delta);\n }\n\n if (!this._disableYaw) {\n xMotion.update(delta);\n }\n }\n\n /**\n * @hidden\n */\n public updateRange(camera: Camera, zoom: number) {\n const yawRange = camera.getYawRange(zoom);\n const pitchRange = camera.getPitchRange(zoom);\n\n this._xMotion.setRange(yawRange.min, yawRange.max);\n this._yMotion.setRange(pitchRange.min, pitchRange.max);\n }\n\n /**\n * @hidden\n */\n public setZoomScale(val: number) {\n this._zoomScale = val;\n }\n\n /**\n * Resize control to match target size.\n * @ko 컨트롤의 내부 크기를 갱신합니다.\n * @param hfov - Camera horizontal fov in degrees {@ko 카메라의 수평방향 fov값 (도 단위)}\n * @param aspect - Camera aspect {@ko 카메라 가로/세로 비율}\n * @param width - New width {@ko 갱신된 너비}\n * @param height - New height {@ko 갱신된 높이}\n */\n public resize(hfov: number, aspect: number, width: number, height: number) {\n const vfov = toVerticalFov(hfov * DEG_TO_RAD, aspect) * RAD_TO_DEG;\n\n this._screenScale[0] = hfov / width;\n this._screenScale[1] = vfov / height;\n }\n\n public enable(): void {\n if (this._enabled) return;\n\n const element = this._controlEl;\n\n this._mouseInput.enable(element);\n this._touchInput.enable(element);\n this._keyboardInput.enable(element);\n\n this._enabled = true;\n this._enableBlocked = false;\n\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: true });\n }\n\n public disable(): void {\n if (!this._enabled) return;\n\n this._mouseInput.disable();\n this._touchInput.disable();\n this._keyboardInput.disable();\n\n this._enabled = false;\n\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: true });\n }\n\n public sync(camera: Camera): void {\n this.updateRange(camera, camera.zoom);\n\n this._xMotion.reset(camera.yaw);\n this._yMotion.reset(camera.pitch);\n }\n\n private _bindInputs() {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n const keyboardInput = this._keyboardInput;\n\n mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n touchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n touchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n keyboardInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n keyboardInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n keyboardInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n }\n\n private _onInputStart = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n this._changedWhileDragging = false;\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n ...evt,\n inputType: \"rotate\"\n });\n };\n\n private _onChange = (evt: InputEvents[typeof CONTROL_EVENTS.CHANGE]) => {\n const delta = evt.delta;\n const invZoomScale = 1 / this._zoomScale; // Reduce speed on zoom\n const screenScale = this._screenScale;\n const keyboardScale = this._keyboardScale;\n const pointerScale = this._pointerScale;\n\n let scale: [number, number];\n\n if (evt.isKeyboard) {\n scale = [\n keyboardScale[0] * invZoomScale,\n keyboardScale[1] * invZoomScale\n ];\n } else {\n scale = [\n pointerScale[0] * screenScale[0] * invZoomScale,\n pointerScale[1] * screenScale[1] * invZoomScale\n ];\n }\n\n const scaledX = delta.x * scale[0];\n const scaledY = delta.y * scale[1];\n\n this._xMotion.setNewEndByDelta(scaledX);\n this._yMotion.setNewEndByDelta(scaledY);\n\n this._changedWhileDragging = true;\n }\n\n private _onInputEnd = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n ...evt,\n inputType: \"rotate\"\n });\n\n if (!this._changedWhileDragging && !evt.isKeyboard && !evt.scrolling) {\n this.trigger(CONTROL_EVENTS.STATIC_CLICK, {\n isTouch: evt.isTouch\n });\n }\n\n this._changedWhileDragging = false;\n };\n}\n\nexport default RotateControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS, DEFAULT_ANIMATION_DURATION } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass WheelInput extends Component> {\n private _el: HTMLElement | null;\n private _scrollable: boolean;\n private _baseScale: number;\n private _inputTimer: number;\n\n public get scrollable() { return this._scrollable; }\n public set scrollable(val: boolean) { this._scrollable = val; }\n\n public constructor() {\n super();\n\n this._el = null;\n this._baseScale = 0.04;\n this._scrollable = false;\n this._inputTimer = -1;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.WHEEL, this._onWheel, { passive: false, capture: false });\n\n this._el = element;\n this._clearTimer();\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.WHEEL, this._onWheel, false);\n\n this._el = null;\n this._clearTimer();\n }\n\n private _onWheel = (evt: WheelEvent) => {\n const scrollable = this._scrollable;\n\n if (evt.deltaY === 0 || scrollable) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n\n if (this._inputTimer < 0) {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: false\n });\n } else {\n this._clearTimer();\n }\n\n const delta = this._baseScale * evt.deltaY;\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: false,\n isKeyboard: false\n });\n\n this._inputTimer = window.setTimeout(() => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: false,\n scrolling: false\n });\n this._inputTimer = -1;\n }, DEFAULT_ANIMATION_DURATION);\n };\n\n private _clearTimer() {\n window.clearTimeout(this._inputTimer);\n this._inputTimer = -1;\n }\n}\n\nexport default WheelInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass PinchInput extends Component> {\n private _el: HTMLElement | null;\n private _baseScale: number;\n private _prevDistance: number;\n private _isFirstTouch: boolean;\n\n public constructor() {\n super();\n\n this._el = null;\n this._baseScale = -0.2;\n this._prevDistance = -1;\n this._isFirstTouch = true;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, { passive: false, capture: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = element;\n this._prevDistance = -1;\n this._isFirstTouch = true;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, false);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = null;\n }\n\n private _onTouchMove = (evt: TouchEvent) => {\n const touches = evt.touches;\n if (touches.length !== 2) return;\n\n if (!evt.cancelable) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n\n const prevDistance = this._prevDistance;\n\n const diff = [\n touches[0].pageX - touches[1].pageX,\n touches[0].pageY - touches[1].pageY\n ];\n\n const distance = Math.sqrt(diff[0] * diff[0] + diff[1] * diff[1]) * this._baseScale;\n const delta = this._isFirstTouch\n ? 0\n : distance - prevDistance;\n\n if (this._isFirstTouch) {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: true,\n isKeyboard: false\n });\n }\n\n this._prevDistance = distance;\n this._isFirstTouch = false;\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: true,\n isKeyboard: false\n });\n };\n\n private _onTouchEnd = (evt: TouchEvent) => {\n if (evt.touches.length !== 0) return;\n\n if (!this._isFirstTouch) {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: true,\n isKeyboard: false,\n scrolling: false\n });\n }\n\n this._prevDistance = -1;\n this._isFirstTouch = true;\n };\n}\n\nexport default PinchInput;\n","/*\n* Copyright (c) 2023-present NAVER Corp.\n* egjs projects are licensed under the MIT license\n*/\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport WheelInput from \"./input/WheelInput\";\nimport PinchInput from \"./input/PinchInput\";\nimport Camera from \"../core/Camera\";\nimport Motion from \"../core/Motion\";\nimport {\n CONTROL_EVENTS,\n DEFAULT_ANIMATION_DURATION,\n DEFAULT_EASING,\n INFINITE_RANGE\n} from \"../const/internal\";\nimport { ControlEvents, InputEvents } from \"../type/internal\";\n\n/**\n * Options for {@link ZoomControl}\n * @ko {@link ZoomControl}용 옵션들\n * @since 4.0.0\n */\nexport interface ZoomControlOptions {\n /**\n * @copy ZoomControl#scale\n */\n scale: number;\n /**\n * @copy ZoomControl#duration\n */\n duration: number;\n /**\n * @copy ZoomControl#easing\n */\n easing: (x: number) => number;\n}\n\ntype ZoomControlEvents = ControlEvents;\n\n/**\n * Camera's zoom control\n * @ko 카메라의 줌 값을 담당하는 컨트롤\n * @since 4.0.0\n */\nclass ZoomControl extends Component implements CameraControl {\n // Options\n private _scale: ZoomControlOptions[\"scale\"];\n\n // Internal values\n private _controlEl: HTMLElement;\n private _enableBlocked: boolean;\n private _wheelInput: WheelInput;\n private _pinchInput: PinchInput;\n private _motion: Motion;\n private _enabled: boolean;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() { return this._motion.activated; }\n /**\n * Current zoom value\n * @ko 현재 줌 값\n * @since 4.0.0\n * @readonly\n */\n public get zoom() { return this._motion.val; }\n /**\n * @copy View360#wheelScrollable\n */\n public get scrollable() { return this._wheelInput.scrollable; }\n public set scrollable(val: boolean) {\n this._wheelInput.scrollable = val;\n }\n /**\n * @hidden\n */\n public get range() { return this._motion.range; }\n\n /**\n * Scale factor of the zoom\n * @ko 입력에 의한 줌 배율\n * @default 1\n * @since 4.0.0\n */\n public get scale() { return this._scale; }\n public set scale(val: ZoomControlOptions[\"scale\"]) { this._scale = val; }\n\n /**\n * Duration of the input animation (ms)\n * @ko 회전 애니메이션의 시간 (ms)\n * @default 300\n * @since 4.0.0\n */\n public get duration() { return this._motion.duration; }\n\n /**\n * Easing function of the animation\n * @ko 회전 애니메이션에 적용할 easing 함수\n * @default EASING.EASE_OUT_CUBIC\n * @see EASING\n * @since 4.0.0\n */\n public get easing() { return this._motion.easing; }\n\n /**\n * Create new ZoomControl instance\n * @ko ZoomControl의 인스턴스를 생성합니다.\n * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트}\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(controlEl: HTMLElement, enableBlocked: boolean, {\n scale = 1,\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING\n }: Partial = {}) {\n super();\n\n this._scale = scale;\n\n this._controlEl = controlEl;\n this._enableBlocked = enableBlocked;\n this._wheelInput = new WheelInput();\n this._pinchInput = new PinchInput();\n this._motion = new Motion({\n duration,\n easing,\n range: INFINITE_RANGE\n });\n this._enabled = false;\n\n this._bindInputs();\n }\n\n public destroy(): void {\n this.disable();\n this._wheelInput.off();\n this._pinchInput.off();\n this.off();\n }\n\n /**\n * @hidden\n */\n public update(delta: number): void {\n if (!this._enabled) return;\n\n const motion = this._motion;\n motion.update(delta);\n }\n\n public enable(): void {\n if (this._enabled) return;\n\n const element = this._controlEl;\n this._wheelInput.enable(element);\n this._pinchInput.enable(element);\n\n this._enabled = true;\n this._enableBlocked = false;\n\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: false });\n }\n\n public disable(): void {\n if (!this._enabled) return;\n\n this._wheelInput.disable();\n this._pinchInput.disable();\n\n this._enabled = false;\n\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: false });\n }\n\n public sync(camera: Camera): void {\n const motion = this._motion;\n const range = camera.getZoomRange();\n\n motion.setRange(range.min, range.max);\n motion.reset(range.current);\n }\n\n private _bindInputs() {\n const wheelInput = this._wheelInput;\n const pinchInput = this._pinchInput;\n\n wheelInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n wheelInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n wheelInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n pinchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n pinchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n pinchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n }\n\n private _onInputStart = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n ...evt,\n inputType: \"zoom\"\n });\n };\n\n private _onChange = ({ delta }: InputEvents[typeof CONTROL_EVENTS.CHANGE]) => {\n const scale = this._scale;\n const scaledDelta = delta * scale;\n\n this._motion.setNewEndByDelta(scaledDelta);\n };\n\n private _onInputEnd = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n ...evt,\n inputType: \"zoom\"\n });\n };\n}\n\nexport default ZoomControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { quat, vec3 } from \"gl-matrix\";\nimport * as BROWSER from \"../../const/browser\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\nimport { quatToEuler } from \"../../utils\";\n\nexport const ROTATE_CONSTANT = {\n PITCH_DELTA: 1,\n YAW_DELTA_BY_ROLL: 2,\n YAW_DELTA_BY_YAW: 3\n} as const;\n\nROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = {\n targetAxis: [0, 1, 0],\n meshPoint: [0, 0, 1]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = {\n targetAxis: [0, 1, 0],\n meshPoint: [1, 0, 0]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = {\n targetAxis: [1, 0, 0],\n meshPoint: [0, 0, 1]\n};\n\nclass GyroInput extends Component> {\n public quaternion: quat;\n\n private _ignoreRoll: boolean;\n\n private _yawOrigin: number;\n private _yawOffset: number;\n private _orientation: {\n alpha: number;\n beta: number;\n gamma: number;\n }\n private _orientationUpdated: boolean;\n private _needsCalibrate: boolean;\n private _screenOrientation: number;\n private _enabled: boolean;\n\n public get enabled() { return this._enabled; }\n public get orientationUpdated() { return this._orientationUpdated; }\n public get ignoreRoll() { return this._ignoreRoll; }\n public set ignoreRoll(val: boolean) { this._ignoreRoll = val; }\n\n public constructor() {\n super();\n\n this.quaternion = quat.create();\n\n this._orientation = {\n alpha: 0,\n beta: 90,\n gamma: 0\n };\n this._yawOrigin = 0;\n this._yawOffset = 0;\n this._orientationUpdated = false;\n this._screenOrientation = 0;\n this._needsCalibrate = true;\n this._enabled = false;\n }\n\n public enable() {\n if (this._enabled) return;\n\n window.addEventListener(BROWSER.EVENTS.DEVICE_ORIENTATION, this._onDeviceOrientation);\n window.addEventListener(BROWSER.EVENTS.ORIENTATION_CHANGE, this._updateScreenOrientation);\n\n this._updateScreenOrientation();\n this._orientationUpdated = false;\n this._needsCalibrate = true;\n this._enabled = true;\n }\n\n public disable() {\n if (!this._enabled) return;\n\n window.removeEventListener(BROWSER.EVENTS.DEVICE_ORIENTATION, this._onDeviceOrientation);\n window.removeEventListener(BROWSER.EVENTS.ORIENTATION_CHANGE, this._updateScreenOrientation);\n\n this._enabled = false;\n }\n\n public update() {\n this._updateRotation();\n this._orientationUpdated = false;\n }\n\n public collectDelta() {\n if (!this._orientationUpdated) {\n return {\n pitch: 0,\n yaw: 0\n };\n }\n\n const prevRotation = quat.clone(this.quaternion);\n\n this._updateRotation();\n this._orientationUpdated = false;\n\n return this._toEulerDelta(prevRotation, this.quaternion);\n }\n\n public setInitialRotation(yaw: number) {\n this._yawOrigin = yaw;\n }\n\n private _onDeviceOrientation = (evt: DeviceOrientationEvent) => {\n const prevOrientation = this._orientation;\n const { alpha, beta, gamma } = evt;\n\n if (\n alpha == null\n || beta == null\n || gamma == null\n ) return;\n\n prevOrientation.alpha = alpha;\n prevOrientation.beta = beta;\n prevOrientation.gamma = gamma;\n\n this._orientationUpdated = true;\n\n if (this._needsCalibrate) {\n this._needsCalibrate = false;\n this._calibrateSensor();\n }\n };\n\n private _calibrateSensor() {\n const yawOrigin = this._yawOrigin;\n const rotation = this.quaternion;\n\n this._yawOffset = 0;\n this._updateRotation();\n\n const { yaw: sensorYaw } = quatToEuler(rotation);\n this._yawOffset = sensorYaw - yawOrigin;\n this._updateRotation();\n\n this._needsCalibrate = false;\n }\n\n private _updateRotation() {\n const rotation = this.quaternion;\n const { alpha, beta, gamma } = this._orientation;\n\n quat.identity(rotation);\n quat.rotateY(rotation, rotation, (alpha - this._yawOffset) * DEG_TO_RAD);\n quat.rotateX(rotation, rotation, beta * DEG_TO_RAD);\n quat.rotateZ(rotation, rotation, -gamma * DEG_TO_RAD);\n\n const screen = quat.create();\n const screenAngle = -this._screenOrientation * 0.5 * DEG_TO_RAD;\n const world = quat.fromValues(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5));\n\n quat.set(screen, 0, Math.sin(screenAngle), 0, Math.cos(screenAngle));\n quat.multiply(rotation, rotation, screen);\n quat.multiply(rotation, rotation, world);\n\n quat.normalize(rotation, rotation);\n }\n\n private _updateScreenOrientation = () => {\n if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) {\n this._screenOrientation = screen.orientation.angle;\n } else if (window.orientation !== undefined) {\n this._screenOrientation = window.orientation >= 0 ?\n window.orientation : 360 + window.orientation;\n } else {\n this._screenOrientation = 0;\n }\n }\n\n private _toEulerDelta(prevQuat: quat, currentQuat: quat) {\n return {\n yaw: this._getDeltaYaw(prevQuat, currentQuat),\n pitch: this._getDeltaPitch(prevQuat, currentQuat),\n };\n }\n\n private _getDeltaYaw(prvQ: quat, curQ: quat): number {\n const yawDeltaByYaw = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW);\n const yawDeltaByRoll = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL)\n * Math.sin(this._extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n }\n\n private _getDeltaPitch(prvQ: quat, curQ: quat): number {\n return this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n }\n\n private _getRotationDelta(prevQ: quat, curQ: quat, rotateKind: typeof ROTATE_CONSTANT[keyof typeof ROTATE_CONSTANT]) {\n const targetAxis = vec3.fromValues(\n ROTATE_CONSTANT[rotateKind].targetAxis[0],\n ROTATE_CONSTANT[rotateKind].targetAxis[1],\n ROTATE_CONSTANT[rotateKind].targetAxis[2]\n );\n const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint;\n\n const prevQuaternion = quat.clone(prevQ);\n const curQuaternion = quat.clone(curQ);\n\n quat.normalize(prevQuaternion, prevQuaternion);\n quat.normalize(curQuaternion, curQuaternion);\n\n let prevPoint = vec3.fromValues(0, 0, 1);\n let curPoint = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n vec3.transformQuat(targetAxis, targetAxis, curQuaternion);\n\n const rotateDistance = vec3.dot(targetAxis, vec3.cross(vec3.create(), prevPoint, curPoint));\n const rotateDirection = rotateDistance > 0 ? 1 : -1;\n\n // when counter clock wise, use vec3.fromValues(0,1,0)\n // when clock wise, use vec3.fromValues(0,-1,0)\n // const meshPoint1 = vec3.fromValues(0, 0, 0);\n const meshPoint2 = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n\n let meshPoint3;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n meshPoint3 = vec3.fromValues(0, rotateDirection, 0);\n } else {\n meshPoint3 = vec3.fromValues(rotateDirection, 0, 0);\n }\n\n vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion);\n vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion);\n\n const vecU = meshPoint2;\n const vecV = meshPoint3;\n const vecN = vec3.create();\n\n vec3.cross(vecN, vecU, vecV);\n vec3.normalize(vecN, vecN);\n\n const coefficientA = vecN[0];\n const coefficientB = vecN[1];\n const coefficientC = vecN[2];\n\n // a point on the plane\n curPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n\n // a point should project on the plane\n prevPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n\n // distance between prevPoint and the plane\n let distance = Math.abs(\n prevPoint[0] * coefficientA +\n prevPoint[1] * coefficientB +\n prevPoint[2] * coefficientC\n );\n\n const projectedPrevPoint = vec3.create();\n\n vec3.subtract(projectedPrevPoint, prevPoint, vec3.scale(vec3.create(), vecN, distance));\n\n let trigonometricRatio =\n (projectedPrevPoint[0] * curPoint[0] +\n projectedPrevPoint[1] * curPoint[1] +\n projectedPrevPoint[2] * curPoint[2]) /\n (vec3.length(projectedPrevPoint) * vec3.length(curPoint));\n\n // defensive block\n if (trigonometricRatio > 1) {\n trigonometricRatio = 1;\n }\n\n const theta = Math.acos(trigonometricRatio);\n\n const crossVec = vec3.cross(vec3.create(), curPoint, projectedPrevPoint);\n\n distance = coefficientA * crossVec[0]\n + coefficientB * crossVec[1]\n + coefficientC * crossVec[2];\n\n let thetaDirection: number;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n thetaDirection = distance > 0 ? 1 : -1;\n } else {\n thetaDirection = distance < 0 ? 1 : -1;\n }\n\n const deltaRadian = theta * thetaDirection * rotateDirection;\n\n return deltaRadian * RAD_TO_DEG;\n }\n\n private _extractPitchFromQuat(quaternion: quat) {\n const baseV = vec3.fromValues(0, 0, 1);\n vec3.transformQuat(baseV, baseV, quaternion);\n\n return -1 * Math.atan2(\n baseV[1],\n Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2)));\n }\n}\n\nexport default GyroInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport GyroInput from \"./input/GyroInput\";\nimport Motion from \"../core/Motion\";\nimport Camera from \"../core/Camera\";\nimport * as BROWSER from \"../const/browser\";\nimport { CONTROL_EVENTS } from \"../const/internal\";\nimport { ControlEvents } from \"../type/internal\";\nimport { sensorCanBeEnabledIOS } from \"../utils\";\n\n/**\n * Options for {@link GyroControl}\n * @ko {@link GyroControl}용 옵션들\n * @since 4.0.0\n */\nexport interface GyroControlOptions {\n /**\n * @copy GyroControl#ignoreRoll\n */\n ignoreRoll: boolean;\n}\n\nexport type GyroControlEvents = ControlEvents;\n\n/**\n * Camera's rotation control by gyroscope\n * @ko 자이로스코프를 이용한 회전 컨트롤\n * @since 4.0.0\n */\nclass GyroControl extends Component implements CameraControl {\n // Options\n private _ignoreRoll: GyroControlOptions[\"ignoreRoll\"];\n\n // Internal values\n private _enableBlocked: boolean;\n private _input: GyroInput;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._input.enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() {\n return this._input.enabled && this._input.orientationUpdated;\n }\n\n /**\n * When `true`, ignore gyroscope's roll(z-axis rotation) value.\n * :::caution\n * Setting `false` will ignore camera's range limit.\n * Options like {@link View360Options#yawRange}, {@link View360Options#pitchRange} are ignored, and {@link CylinderProjection} also can't force it's camera range limit.\n * :::\n * @ko `true`일 경우 자이로스코프 입력의 roll(z축 회전)값을 무시합니다.\n * :::caution\n * 이 값을 `false`로 설정할 경우 카메라 범위 제약을 무시합니다.\n * {@link View360Options#yawRange}, {@link View360Options#pitchRange}와 같은 값은 무시되며, {@link CylinderProjection} 사용시에도 범위를 벗어날 수 있습니다.\n * :::\n * @default true\n * @since 4.0.0\n */\n public get ignoreRoll() { return this._ignoreRoll; }\n public set ignoreRoll(val: GyroControlOptions[\"ignoreRoll\"]) { this._ignoreRoll = val; }\n\n /**\n * Return availability of the gyroscope.\n * :::caution\n * This will always return false until user permission under environments like iOS which requires user permission when using gyroscope.\n * :::\n * @ko 자이로스코프 사용 가능 여부를 반환합니다.\n * :::caution\n * iOS와 같이 GyroScope 사용시 사용자 Permission을 요구하는 환경에서는 사용자 Permission을 받기 전까지 항상 `false`입니다.\n * :::\n * @example\n * ```ts\n * const gyroAvailable = await GyroControl.isAvailable();\n * ```\n */\n public static async isAvailable(): Promise {\n if (!DeviceMotionEvent) {\n return false;\n }\n\n let onDeviceMotionChange: (evt: DeviceMotionEvent) => void;\n\n const listenDeviceMotion = () => new Promise(res => {\n onDeviceMotionChange = (evt: DeviceMotionEvent) => {\n res(evt.rotationRate && evt.rotationRate.alpha != null);\n };\n\n window.addEventListener(BROWSER.EVENTS.DEVICE_MOTION, onDeviceMotionChange);\n });\n\n const timeout = () => new Promise(res => {\n setTimeout(() => res(false), 1000);\n });\n\n return Promise.race([listenDeviceMotion(), timeout()])\n .then((available: boolean) => {\n window.removeEventListener(BROWSER.EVENTS.DEVICE_MOTION, onDeviceMotionChange);\n\n return available;\n });\n }\n\n /**\n * Request user permission for gyroscope sensor.\n * This can be used in environments like iOS which requires user permission when using gyroscope sensors.\n * @ko 사용자의 sensor permission 취득을 요청합니다.\n * iOS와 같이 gyroscope 사용시 사용자 Permission을 요구하는 환경에서 사용 가능합니다.\n * @returns Whether the permission is granted {@ko 사용자 permission 취득 여부}\n */\n public static async requestSensorPermission(): Promise {\n // Request sensor permission, on iOS13+\n if (sensorCanBeEnabledIOS()) {\n return (DeviceMotionEvent as typeof DeviceMotionEvent & {\n requestPermission: () => Promise;\n }).requestPermission().then(permissionState => {\n return permissionState === \"granted\";\n }).catch(() => false);\n }\n\n return true;\n }\n\n /**\n * Create new GyroControl instance\n * @ko GyroControl의 인스턴스를 생성합니다.\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(enableBlocked: boolean, {\n ignoreRoll = true\n }: Partial = {}) {\n super();\n\n this._enableBlocked = enableBlocked;\n this._ignoreRoll = ignoreRoll;\n this._input = new GyroInput();\n }\n\n /**\n * @copy CameraControl#destroy\n */\n public destroy(): void {\n this.disable();\n this._input.off();\n this.off();\n }\n\n /**\n * @hidden\n */\n public update(camera: Camera, yaw: Motion, pitch: Motion, zoom: number) {\n if (!this._ignoreRoll) {\n this._updateQuaternion(camera, zoom);\n } else {\n this._updateYawPitch(camera, yaw, pitch, zoom);\n }\n }\n\n /**\n * @copy CameraControl#enable\n */\n public enable(): void {\n if (this._input.enabled) return;\n\n this._input.enable();\n this._enableBlocked = false;\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: false });\n }\n\n /**\n * @copy CameraControl#disable\n */\n public disable(): void {\n if (!this._input.enabled) return;\n\n this._input.disable();\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: false });\n }\n\n /**\n * @copy CameraControl#sync\n */\n public sync(): void {} // eslint-disable-line @typescript-eslint/no-empty-function\n\n private _updateYawPitch(camera: Camera, yaw: Motion, pitch: Motion, zoom: number) {\n const input = this._input;\n if (!input.enabled) return;\n\n const {\n yaw: yawDelta,\n pitch: pitchDelta\n } = input.collectDelta();\n\n yaw.add(yawDelta);\n pitch.add(pitchDelta);\n\n camera.lookAt({\n yaw: yaw.val,\n pitch: pitch.val,\n zoom\n });\n }\n\n private _updateQuaternion(camera: Camera, zoom: number) {\n const input = this._input;\n if (!input.enabled) return;\n\n input.update();\n camera.rotate(input.quaternion, zoom);\n }\n}\n\nexport default GyroControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport CameraControl from \"./CameraControl\";\nimport RotateControl, { RotateControlEvents, RotateControlOptions } from \"./RotateControl\";\nimport ZoomControl, { ZoomControlOptions } from \"./ZoomControl\";\nimport GyroControl, { GyroControlOptions } from \"./GyroControl\";\nimport Camera from \"../core/Camera\";\nimport CameraAnimation from \"../core/CameraAnimation\";\nimport * as BROWSER from \"../const/browser\";\nimport { CAMERA_EVENTS, CONTROL_EVENTS } from \"../const/internal\";\nimport { ValueOf } from \"../type/utils\";\nimport { getObjectOption, hfovToZoom } from \"../utils\";\n\n/**\n * Options for {@link PanoControl}\n * @ko {@link PanoControl}용 옵션들\n * @since 4.0.0\n */\nexport interface PanoControlOptions {\n /**\n * @copy View360#useGrabCursor\n */\n useGrabCursor: boolean;\n /**\n * @copy View360#scrollable\n */\n scrollable: boolean;\n /**\n * @copy View360#wheelScrollable\n */\n wheelScrollable: boolean;\n /**\n * @copy View360#disableContextMenu\n */\n disableContextMenu: boolean;\n /**\n * Options for {@link RotateControl}.\n * `false` to disable rotation.\n * @ko {@link RotateControl}용 옵션들.\n * `false`일 경우 회전이 비활성화됩니다.\n * @since 4.0.0\n */\n rotate: boolean | Partial;\n /**\n * Options for {@link ZoomControl}.\n * `false` to disable zoom.\n * @ko {@link ZoomControl}용 옵션들.\n * `false`일 경우 줌이 비활성화됩니다.\n * @since 4.0.0\n */\n zoom: boolean | Partial;\n /**\n * Options for {@link GyroControl}.\n * `false` to disable gyroscope control.\n * @ko {@link GyroControl}용 옵션들.\n * `false`일 경우 자이로스코프를 통한 컨트롤이 비활성화됩니다.\n * @since 4.0.0\n */\n gyro: boolean | Partial;\n}\n\n/**\n * Panorama control for View360\n * @ko View360용 파노라마 컨트롤\n * @since 4.0.0\n */\nclass PanoControl {\n // Options\n private _useGrabCursor: PanoControlOptions[\"useGrabCursor\"];\n private _disableContextMenu: PanoControlOptions[\"disableContextMenu\"];\n\n // Internal Values\n private _camera: Camera;\n private _controlEl: HTMLElement;\n private _rotateControl: RotateControl;\n private _zoomControl: ZoomControl;\n private _gyroControl: GyroControl;\n private _ignoreZoomScale: boolean;\n private _enabled: boolean;\n\n /**\n * @copy View360#useGrabCursor\n */\n public get useGrabCursor() { return this._useGrabCursor; }\n public set useGrabCursor(val: PanoControlOptions[\"useGrabCursor\"]) {\n if (val === this._useGrabCursor) return;\n\n this._useGrabCursor = val;\n\n if (val && this._enabled) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n } else if (!val) {\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n }\n\n /**\n * @copy View360#disableContextMenu\n */\n public get disableContextMenu() { return this._disableContextMenu; }\n public set disableContextMenu(val: PanoControlOptions[\"disableContextMenu\"]) {\n if (val === this._disableContextMenu) return;\n\n this._disableContextMenu = val;\n\n if (val && this._enabled) {\n this._blockContextMenu();\n } else if (!val) {\n this._restoreContextMenu();\n }\n }\n\n /**\n * @copy View360#disableContextMenu\n */\n public get scrollable() { return this._rotateControl.scrollable; }\n public set scrollable(val: PanoControlOptions[\"scrollable\"]) { this._rotateControl.scrollable = val; }\n /**\n * @copy View360#disableContextMenu\n */\n public get wheelScrollable() { return this._zoomControl.scrollable; }\n public set wheelScrollable(val: PanoControlOptions[\"wheelScrollable\"]) { this._zoomControl.scrollable = val; }\n /**\n * When `true`, disables rotation slow-down by zoom-value.\n * @ko `true`일 경우 줌 된 정도에 따라 회전속도를 늦추는 동작을 비활성화합니다.\n * @since 4.0.0\n */\n public get ignoreZoomScale() { return this._ignoreZoomScale; }\n public set ignoreZoomScale(val: boolean) { this._ignoreZoomScale = val; }\n\n /**\n * Whether the control is enabled or not\n * @ko 컨트롤 활성화 여부를 가리키는 값\n * @readonly\n * @since 4.0.0\n */\n public get enabled() { return this._enabled; }\n /**\n * @copy View360#rotate\n */\n public get rotate() { return this._rotateControl; }\n /**\n * @copy View360#zoom\n */\n public get zoom() { return this._zoomControl; }\n /**\n * @copy View360#gyro\n */\n public get gyro() { return this._gyroControl; }\n\n /**\n * Whether one of the controls is animating at the moment\n * @ko 현재 컨트롤 중 하나라도 동작중인지 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get animating() {\n return this._rotateControl.animating\n || this._zoomControl.animating\n || this._gyroControl.animating;\n }\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param element - Canvas element {@ko 캔버스 엘리먼트}\n * @param camera - Camera instance {@ko Camera 인스턴스}\n * @param options - Options for PanoControl {@ko PanoControl 옵션들}\n */\n public constructor(element: HTMLElement, camera: Camera, {\n useGrabCursor,\n scrollable,\n wheelScrollable,\n disableContextMenu,\n rotate,\n zoom,\n gyro\n }: PanoControlOptions) {\n // Bind Options\n this._useGrabCursor = useGrabCursor;\n this._disableContextMenu = disableContextMenu;\n\n // Set internal values\n this._camera = camera;\n this._controlEl = element;\n this._ignoreZoomScale = false;\n this._enabled = false;\n\n this._rotateControl = new RotateControl(element, !rotate, getObjectOption(rotate));\n this._zoomControl = new ZoomControl(element, !zoom, getObjectOption(zoom));\n this._gyroControl = new GyroControl(!gyro, getObjectOption(gyro));\n\n this._rotateControl.scrollable = scrollable;\n this._zoomControl.scrollable = wheelScrollable;\n\n this._bindEvents();\n }\n\n /**\n * Destroy the instance and remove all event listeners attached.\n * This also will reset CSS cursor to initial.\n * @ko 인스턴스를 삭제하고 부착된 모든 이벤트 리스너를 제거합니다.\n * 또한, 캔버스에 적용된 CSS cursor도 제거합니다.\n * @since 4.0.0\n */\n public destroy(): void {\n this.disable();\n this._rotateControl.destroy();\n this._zoomControl.destroy();\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n\n /**\n * Resize control to match target size.\n * @ko 컨트롤이 내부에 캐시하고 있는 크기값을 갱신합니다.\n * @param width New width {@ko 변경된 너비}\n * @param height New height {@ko 변경된 높이}\n * @since 4.0.0\n */\n public resize(width: number, height: number): void {\n const camera = this._camera;\n\n this._rotateControl.resize(camera.fov, camera.aspect, width, height);\n }\n\n /**\n * Enable this control and add event listeners.\n * @ko 컨트롤을 활성화하고 이벤트 리스너들을 추가합니다.\n * @since 4.0.0\n */\n public async enable(): Promise {\n if (this._enabled) return;\n\n if (!this._rotateControl.enableBlocked) {\n this._rotateControl.enable();\n }\n\n if (!this._zoomControl.enableBlocked) {\n this._zoomControl.enable();\n }\n\n if (!this._gyroControl.enableBlocked) {\n if (await GyroControl.isAvailable()) {\n this._gyroControl.enable();\n }\n }\n\n this.sync();\n\n if (this._disableContextMenu) {\n this._blockContextMenu();\n }\n\n this._enabled = true;\n }\n\n /**\n * Disable this control and remove all event listeners\n * @ko 컨트롤을 비활성화하고 모든 이벤트 리스너들을 제거합니다.\n * @since 4.0.0\n */\n public disable(): void {\n if (!this._enabled) return;\n\n this._rotateControl.disable();\n this._zoomControl.disable();\n this._gyroControl.disable();\n\n this._restoreContextMenu();\n\n this._enabled = false;\n }\n\n /**\n * Update control by given deltaTime\n * @ko 컨트롤을 주어진 시간만큼 업데이트합니다.\n * @param delta Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n * @internal\n */\n public update(delta: number): void {\n const camera = this._camera;\n const rotateControl = this._rotateControl;\n const zoomControl = this._zoomControl;\n const gyroControl = this._gyroControl;\n\n zoomControl.update(delta);\n const zoom = hfovToZoom(camera.fov, zoomControl.zoom);\n\n // Slow down rotation on zoom-in\n const zoomScale = this._ignoreZoomScale ? 1 : Math.max(zoom, 1);\n rotateControl.setZoomScale(zoomScale);\n rotateControl.updateRange(camera, zoom);\n rotateControl.update(delta);\n\n const yaw = rotateControl.yaw;\n const pitch = rotateControl.pitch;\n\n if (gyroControl.enabled) {\n gyroControl.update(camera, yaw, pitch, zoom);\n } else {\n camera.lookAt({\n yaw: yaw.val,\n pitch: pitch.val,\n zoom\n });\n }\n }\n\n /**\n * Synchronize this control's state to current camera state\n * @ko 컨트롤을 카메라의 현재 상태와 동기화합니다.\n * @since 4.0.0\n */\n public sync(): void {\n const camera = this._camera;\n\n this._zoomControl.sync(camera);\n this._rotateControl.sync(camera);\n }\n\n private _blockContextMenu() {\n const el = this._controlEl;\n\n el.addEventListener(BROWSER.EVENTS.CONTEXT_MENU, this._preventContextMenu);\n }\n\n private _restoreContextMenu() {\n const el = this._controlEl;\n\n el.removeEventListener(BROWSER.EVENTS.CONTEXT_MENU, this._preventContextMenu);\n }\n\n private _preventContextMenu = (evt: MouseEvent) => {\n evt.preventDefault();\n };\n\n private _setCursor(newCursor: ValueOf) {\n if (!this._useGrabCursor && newCursor !== BROWSER.CURSOR.NONE) return;\n\n const targetEl = this._controlEl;\n targetEl.style.cursor = newCursor;\n }\n\n private _bindEvents() {\n const rotateControl = this._rotateControl;\n const zoomControl = this._zoomControl;\n\n rotateControl.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n rotateControl.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n rotateControl.on(CONTROL_EVENTS.ENABLE, this._onEnable);\n rotateControl.on(CONTROL_EVENTS.DISABLE, this._onDisable);\n zoomControl.on(CONTROL_EVENTS.ENABLE, this._onEnable);\n zoomControl.on(CONTROL_EVENTS.DISABLE, this._onDisable);\n this._camera.on(CAMERA_EVENTS.ANIMATION_END, this._onCameraAnimationEnd);\n }\n\n private _onInputStart = (evt: RotateControlEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n if (this._useGrabCursor && !evt.isKeyboard) {\n this._setCursor(BROWSER.CURSOR.GRABBING);\n }\n };\n\n private _onInputEnd = (evt: RotateControlEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n if (this._useGrabCursor && !evt.isKeyboard) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n }\n };\n\n private _onEnable = ({\n control,\n updateCursor\n }: {\n control: CameraControl;\n updateCursor: boolean;\n }) => {\n if (updateCursor && this._useGrabCursor) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n }\n\n control.sync(this._camera);\n };\n\n private _onDisable = ({\n updateCursor\n }: {\n updateCursor: boolean\n }) => {\n if (updateCursor) {\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n };\n\n private _onCameraAnimationEnd = ({ animation }: { animation: CameraAnimation }) => {\n animation.getFinishPromise().then(() => {\n this.sync();\n });\n };\n}\n\nexport default PanoControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport TextureVideo from \"./TextureVideo\";\nimport TextureCube from \"./TextureCube\";\n\n/**\n * @hidden\n */\nabstract class Texture {\n public width: number;\n public height: number;\n public flipY: boolean;\n public wrapS: number;\n public wrapT: number;\n\n public constructor({\n width,\n height,\n flipY\n }: {\n width: number;\n height: number;\n flipY: boolean;\n }) {\n this.width = width;\n this.height = height;\n this.flipY = flipY;\n this.wrapS = WebGLRenderingContext.CLAMP_TO_EDGE;\n this.wrapT = WebGLRenderingContext.CLAMP_TO_EDGE;\n }\n\n public destroy() {\n // DO_NOTHING\n }\n\n public isVideo(): this is TextureVideo {\n return false;\n }\n\n public isCube(): this is TextureCube {\n return false;\n }\n}\n\nexport default Texture;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture from \"./Texture\";\n\n/**\n * @hidden\n */\nclass Texture2D extends Texture {\n public source: Exclude;\n\n public constructor({\n source,\n width,\n height,\n flipY\n }: {\n source: Exclude;\n width: number;\n height: number;\n flipY: boolean;\n }) {\n super({\n width,\n height,\n flipY\n });\n\n this.source = source;\n }\n}\n\nexport default Texture2D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"./Texture2D\";\n\n/**\n * @hidden\n */\nclass TextureVideo extends Texture2D {\n public source: HTMLVideoElement;\n\n public destroy() {\n const video = this.source;\n\n video.pause();\n video.removeAttribute(\"src\");\n video.load();\n }\n\n public isVideo(): this is TextureVideo { return true; }\n\n public isPaused() {\n const video = this.source;\n\n return video.paused || video.ended || video.readyState <= 2;\n }\n\n public hasAudio() {\n const video = this.source as any;\n\n if (video.audioTracks) {\n return video.audioTracks.length > 0;\n }\n\n if (video.webkitAudioDecodedByteCount != null) {\n return video.webkitAudioDecodedByteCount > 0;\n }\n\n if (video.mozHasAudio != null) {\n return video.mozHasAudio;\n }\n\n // We don't know whether the video has audio or not, return true\n return true;\n }\n}\n\nexport default TextureVideo;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture from \"./Texture\";\n\n/**\n * @hidden\n */\nclass TextureCube extends Texture {\n public sources: TexImageSource[];\n\n public constructor({\n sources,\n width,\n height,\n flipY\n }: {\n sources: TexImageSource[];\n width: number;\n height: number;\n flipY: boolean;\n }) {\n super({\n width,\n height,\n flipY\n });\n\n this.sources = sources;\n }\n\n public isCube(): this is TextureCube { return true; }\n}\n\nexport default TextureCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ImReady from \"@egjs/imready\";\nimport Texture from \"../texture/Texture\";\nimport Texture2D from \"../texture/Texture2D\";\nimport TextureVideo from \"../texture/TextureVideo\";\nimport TextureCube from \"../texture/TextureCube\";\nimport { getObjectOption, isString } from \"../utils\";\nimport { VideoConfig } from \"../type/external\";\nimport { ProjectionOptions } from \"../projection/Projection\";\n\n/**\n * @hidden\n */\nclass TextureLoader {\n private _loadChecker: ImReady;\n\n constructor() {\n this._loadChecker = new ImReady();\n }\n\n public async load(src: ProjectionOptions[\"src\"], video: ProjectionOptions[\"video\"]): Promise {\n if (video) {\n return this.loadVideo(src, getObjectOption(video));\n } else {\n if (Array.isArray(src) && src.length > 1) {\n return this.loadCubeImage(src);\n } else {\n const imgSrc = Array.isArray(src) ? src[0] : src;\n return this.loadImage(imgSrc);\n }\n }\n }\n\n public async loadImage(src: string | HTMLElement): Promise {\n const images = this._toImageArray(src);\n\n return this._load(images, resolve => {\n const image = images[0];\n\n resolve(new Texture2D({\n source: image,\n width: image.naturalWidth,\n height: image.naturalHeight,\n flipY: true\n }));\n });\n }\n\n public async loadCubeImage(src: Array): Promise {\n const images = this._toImageArray(src);\n\n return this._load(images, resolve => {\n resolve(new TextureCube({\n sources: images,\n width: images[0].naturalWidth,\n height: images[0].naturalHeight,\n flipY: false\n }));\n });\n }\n\n public async loadVideo(src: ProjectionOptions[\"src\"], videoConfig: Partial): Promise {\n const config: VideoConfig = {\n autoplay: true,\n muted: true,\n loop: false,\n volume: 1,\n ...videoConfig,\n };\n const video = this._toVideoElement(src, config);\n\n return this._load([video], resolve => {\n const { autoplay, muted } = config;\n\n video.currentTime = 0;\n if (autoplay && muted) {\n video.play().catch(() => void 0);\n }\n\n resolve(new TextureVideo({\n source: video,\n width: video.videoWidth,\n height: video.videoHeight,\n flipY: true\n }));\n });\n }\n\n private _load(content: HTMLElement[], onLoad: (resolve: (value: T) => void) => void): Promise {\n const loader = this._loadChecker;\n\n return new Promise((resolve, reject) => {\n loader.once(\"ready\", evt => {\n if (evt.errorCount > 0) return;\n\n onLoad(resolve);\n });\n\n loader.once(\"error\", reject);\n loader.check(content);\n });\n }\n\n private _toImageArray(src: ProjectionOptions[\"src\"]): HTMLImageElement[] {\n const srcs = Array.isArray(src) ? src : [src];\n\n return srcs.map(source => {\n if (isString(source)) {\n const imgEl = new Image();\n\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = source;\n\n return imgEl;\n } else {\n return source as HTMLImageElement;\n }\n });\n }\n\n private _toVideoElement(src: ProjectionOptions[\"src\"], {\n muted,\n loop,\n volume\n }: VideoConfig): HTMLVideoElement {\n if (src instanceof HTMLVideoElement) {\n return src;\n }\n\n const video = document.createElement(\"video\");\n\n video.crossOrigin = \"anonymous\";\n video.playsInline = true;\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.muted = muted;\n video.volume = volume;\n video.loop = loop;\n\n if (Array.isArray(src)) {\n src.forEach(source => this._appendSourceElement(video, source));\n } else {\n this._appendSourceElement(video, src);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0 && video.readyState < 1) {\n video.load();\n }\n\n return video;\n }\n\n private _appendSourceElement(video: HTMLMediaElement, src: string | HTMLElement) {\n if (src instanceof HTMLSourceElement) {\n return src;\n }\n\n const sourceEl = document.createElement(\"source\");\n sourceEl.src = src as string;\n video.appendChild(sourceEl);\n }\n}\n\nexport default TextureLoader;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * @internal\n */\nclass FrameAnimator {\n public maxDeltaTime: number;\n\n private _context: Window | XRSession;\n private _rafId: number;\n private _rafTimer: number;\n private _lastUpdateTime: number;\n\n /** */\n public constructor(maxDeltaTime: number, context: Window | XRSession = window) {\n this.maxDeltaTime = maxDeltaTime;\n\n this._context = context;\n this._rafId = -1;\n this._rafTimer = -1;\n this._lastUpdateTime = -1;\n }\n\n public start(callback: (delta: number, ...args: any[]) => any) {\n const context = this._context;\n\n // No context / callback set\n if (!context || !callback) return;\n\n // Animation already started\n if (this._rafId >= 0 || this._rafTimer >= 0) return;\n\n const loop = (_time: number, frame?: XRFrame) => {\n const time = Date.now();\n const delta = Math.min(time - this._lastUpdateTime, this.maxDeltaTime * 1000);\n\n callback(delta, frame);\n\n this._lastUpdateTime = time;\n this._rafId = context.requestAnimationFrame(loop);\n };\n\n this._lastUpdateTime = Date.now();\n this._rafId = context.requestAnimationFrame(loop);\n }\n\n public stop() {\n if (this._rafId >= 0) {\n this._context.cancelAnimationFrame(this._rafId);\n }\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n }\n\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n public changeContext(context: Window | XRSession) {\n this.stop();\n this._context = context;\n }\n}\n\nexport default FrameAnimator;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport * as BROWSER from \"../const/browser\";\n\n/**\n * Automatic resizer that uses both ResizeObserver and window resize event\n */\nclass AutoResizer {\n private _enabled: boolean;\n private _resizeObserver: ResizeObserver | null;\n private _useResizeObserver: boolean;\n private _onResize: () => any;\n\n public get useResizeObserver() { return this._useResizeObserver; }\n\n /**\n * Returns whether AutoResizer is enabled\n */\n public get enabled() { return this._enabled; }\n\n /** */\n public constructor(useResizeObserver: boolean, onResize: () => any) {\n this._useResizeObserver = useResizeObserver;\n\n this._enabled = false;\n this._resizeObserver = null;\n this._onResize = onResize;\n }\n\n /**\n * Enable resizer\n */\n public enable(element: HTMLElement): this {\n if (this._enabled) {\n this.disable();\n }\n\n if (this._useResizeObserver && !!window.ResizeObserver) {\n const bbox = element.getBoundingClientRect();\n const resizeImmediate = bbox.width !== 0 || bbox.height !== 0;\n\n const resizeObserver = new ResizeObserver(resizeImmediate ? this._skipFirstResize : this._onResize);\n\n resizeObserver.observe(element);\n\n this._resizeObserver = resizeObserver;\n } else {\n window.addEventListener(BROWSER.EVENTS.RESIZE, this._onResize);\n }\n\n this._enabled = true;\n\n return this;\n }\n\n /**\n * Disable resizer\n */\n public disable(): this {\n if (!this._enabled) return this;\n\n const resizeObserver = this._resizeObserver;\n if (resizeObserver) {\n resizeObserver.disconnect();\n this._resizeObserver = null;\n } else {\n window.removeEventListener(BROWSER.EVENTS.RESIZE, this._onResize);\n }\n\n this._enabled = false;\n\n return this;\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n private _skipFirstResize = (() => {\n let isFirstResize = true;\n\n return (() => {\n if (isFirstResize) {\n isFirstResize = false;\n\n return;\n }\n this._onResize();\n });\n })();\n}\n\nexport default AutoResizer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Camera from \"./Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport View360 from \"../View360\";\nimport * as BROWSER from \"../const/browser\";\nimport { CONTROL_EVENTS } from \"../const/internal\";\nimport { circulate, getObjectOption } from \"../utils\";\n\n/**\n * Options for {@link Autoplay}\n * @ko {@link Autoplay}용 옵션들\n * @since 4.0.0\n */\nexport interface AutoplayOptions {\n /**\n * @copy Autoplay#delay\n */\n delay: number;\n /**\n * @copy Autoplay#delayOnMouseLeave\n */\n delayOnMouseLeave: number;\n /**\n * @copy Autoplay#speed\n */\n speed: number;\n /**\n * @copy Autoplay#pauseOnHover\n */\n pauseOnHover: boolean;\n /**\n * @copy Autoplay#canInterrupt\n */\n canInterrupt: boolean;\n /**\n * @copy Autoplay#disableOnInterrupt\n */\n disableOnInterrupt: boolean;\n}\n\n/**\n * A manager class for autoplay feature.\n * @ko Autoplay 기능의 매니저 클래스.\n * @since 4.0.0\n */\nclass Autoplay {\n // Options\n private _delay: number;\n private _delayOnMouseLeave: number;\n private _speed: number;\n private _pauseOnHover: boolean;\n private _canInterrupt: boolean;\n private _disableOnInterrupt: boolean;\n\n // Internal values\n private _enableBlocked: boolean;\n private _camera: Camera;\n private _control: PanoControl;\n private _element: HTMLElement;\n private _enabled: boolean;\n private _interrupted: boolean;\n private _interruptionTimer: number;\n private _hovering: boolean;\n\n /**\n * Whether autoplay is enabled or not\n * @ko 자동재생 활성화 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * Whether autoplay is updating the camera at the moment\n * @ko 현재 자동재생이 동작중인지 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get playing() {\n return this._enabled && !this._interrupted;\n }\n\n /**\n * Reactivation delay after mouse input in milisecond.\n * @ko 재활성화되기까지의 시간 (밀리초 단위)\n * @default 2000\n * @since 4.0.0\n */\n public get delay() { return this._delay; }\n public set delay(val: number) { this._delay = val; }\n\n /**\n * Reactivation delay after mouse leave when using {@link AutoplayOptions#pauseOnHover}\n * @ko {@link AutoplayOptions#pauseOnHover} 사용시 마우스가 캔버스 영역을 떠난 뒤 자동재생이 다시 활성화되기까지의 시간\n * @default 0\n * @since 4.0.0\n */\n public get delayOnMouseLeave() { return this._delayOnMouseLeave; }\n public set delayOnMouseLeave(val: number) { this._delayOnMouseLeave = val; }\n\n /**\n * Y-axis(yaw) rotation speed\n * @ko Y-축 회전(yaw)의 속도\n * @default 1\n * @since 4.0.0\n */\n public get speed() { return this._speed; }\n public set speed(val: number) { this._speed = val; }\n\n /**\n * Whether to pause rotation on mouse hover\n * @ko 마우스가 캔버스 영역에 들어왔을 때 자동재생을 정지할지 여부\n * @default false\n * @since 4.0.0\n */\n public get pauseOnHover() { return this._pauseOnHover; }\n public set pauseOnHover(val: boolean) { this._pauseOnHover = val; }\n\n /**\n * Whether user can interrupt the rotation with click/wheel input\n * @ko 클릭이나 휠같은 사용자 인터랙션시 자동재생을 멈출지 여부\n * @default true\n * @since 4.0.0\n */\n public get canInterrupt() { return this._canInterrupt; }\n public set canInterrupt(val: boolean) { this._canInterrupt = val; }\n\n /**\n * Whether to disable autoplay on user interrupt\n * @ko 사용자 동작에 의해 자동재생이 정지할 때, {@link Autoplay#disable}을 호출하여 자동재생을 영구히 정지할지 여부\n * @default false\n * @since 4.0.0\n */\n public get disableOnInterrupt() { return this._disableOnInterrupt; }\n public set disableOnInterrupt(val: boolean) { this._disableOnInterrupt = val; }\n\n /**\n * Create new AutoPlayer instance\n * @param camera - Instance of the {@link Camera} {@ko Camera의 인스턴스}\n * @param element - Canvas element {@ko 캔버스 엘리먼트}\n * @param options - Autoplay options {@ko 자동재생 옵션들}\n * @since 4.0.0\n */\n public constructor(viewer: View360, element: HTMLElement, options: boolean | Partial) {\n this._camera = viewer.camera;\n this._control = viewer.control;\n this._element = element;\n\n this._enabled = false;\n this._interrupted = false;\n this._interruptionTimer = -1;\n this._hovering = false;\n\n const {\n delay = 2000,\n delayOnMouseLeave = 0,\n speed = 1,\n pauseOnHover = false,\n canInterrupt = true,\n disableOnInterrupt = false\n } = getObjectOption(options);\n\n this._enableBlocked = !options;\n this._delay = delay;\n this._delayOnMouseLeave = delayOnMouseLeave;\n this._speed = speed;\n this._pauseOnHover = pauseOnHover;\n this._canInterrupt = canInterrupt;\n this._disableOnInterrupt = disableOnInterrupt;\n }\n\n /**\n * Destroy the instance and remove all event listeners attached\n * @ko 인스턴스를 제거하고 연결된 모든 이벤트 핸들러를 삭제합니다.\n * @since 4.0.0\n */\n public destroy(): void {\n this.disable();\n }\n\n /**\n * Rotate camera by given deltaTime\n * @ko 주어진 deltaTime만큼 카메라를 회전시킵니다.\n * @param deltaTime - Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n */\n public update(deltaTime: number): void {\n if (!this._enabled) return;\n if (this._interrupted) {\n if (this._disableOnInterrupt) {\n this.disable();\n }\n\n return;\n }\n\n const camera = this._camera;\n const delta = -this._speed * deltaTime / 100;\n\n camera.yaw = circulate(camera.yaw + delta, 0, 360);\n }\n\n /**\n * Enable autoplay and add event listeners.\n * @ko 자동재생을 활성화하고 이벤트리스너들을 추가합니다.\n * @since 4.0.0\n */\n public enable(): void {\n const control = this._control;\n const element = this._element;\n\n if (this._enabled || control.gyro.enabled) return;\n\n control.rotate.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.rotate.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.zoom.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.zoom.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.gyro.on(CONTROL_EVENTS.ENABLE, this._onGyroEnable);\n\n element.addEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter, false);\n element.addEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave, false);\n\n this._enabled = true;\n this._enableBlocked = false;\n }\n\n /**\n * Enable autoplay after current `delay` value.\n * @ko 현재의 `delay`값만큼 시간이 지난 다음에 자동재생을 활성화합니다.\n * @since 4.0.0\n */\n public enableAfterDelay() {\n this.enable();\n this._interrupted = true;\n this._setUninterruptedAfterDelay(this._delay);\n }\n\n /**\n * Disable autoplay and remove all event handlers.\n * @ko 자동재생을 비활성화하고 모든 이벤트 핸들러를 제거합니다.\n * @since 4.0.0\n */\n public disable(): void {\n if (!this._enabled) return;\n\n const control = this._control;\n const element = this._element;\n\n control.rotate.off(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.rotate.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.zoom.off(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.zoom.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.gyro.off(CONTROL_EVENTS.ENABLE, this._onGyroEnable);\n\n element.removeEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter, false);\n element.removeEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave, false);\n\n this._enabled = false;\n this._interrupted = false;\n this._hovering = false;\n\n this._clearTimeout();\n }\n\n private _onInputStart = () => {\n if (!this._canInterrupt) return;\n\n this._interrupted = true;\n this._clearTimeout();\n };\n\n private _onInputEnd = () => {\n this._setUninterruptedAfterDelay(this._delay);\n };\n\n private _onGyroEnable = () => {\n this.disable();\n };\n\n private _onMouseEnter = () => {\n if (!this._pauseOnHover) return;\n this._interrupted = true;\n this._hovering = true;\n };\n\n private _onMouseLeave = () => {\n if (!this._pauseOnHover) return;\n this._hovering = false;\n this._setUninterruptedAfterDelay(this._delayOnMouseLeave);\n };\n\n private _setUninterruptedAfterDelay(delay: number): void {\n if (this._hovering) return;\n\n this._clearTimeout();\n\n if (delay > 0) {\n this._interruptionTimer = window.setTimeout(() => {\n this._interrupted = false;\n this._interruptionTimer = -1;\n }, delay);\n } else {\n this._interrupted = false;\n this._interruptionTimer = -1;\n }\n }\n\n private _clearTimeout(): void {\n if (this._interruptionTimer >= 0) {\n window.clearTimeout(this._interruptionTimer);\n this._interruptionTimer = -1;\n }\n }\n}\n\nexport default Autoplay;\n","import { mat4 } from \"gl-matrix\";\nimport Component from \"@egjs/component\";\nimport WebGLContext from \"./WebGLContext\";\nimport GyroControl from \"../control/GyroControl\";\nimport * as BROWSER from \"../const/browser\";\nimport { SESSION_VR, XR_REFERENCE_SPACE } from \"../const/internal\";\nimport { EVENTS } from \"../const/external\";\n\ninterface XRSessionOptions extends XRSessionInit {\n [key: string]: any;\n}\n\n/**\n * WebXR manager class\n * @ko WebXR 매니저 클래스\n * @since 4.0.0\n */\nclass XRManager extends Component<{\n /**\n * An event that fires on entering VR session\n * @ko VR 세션 진입시에 트리거되는 이벤트\n * @eventName vrStart\n * @eventOf XRManager\n * @version 4.0.0\n */\n [EVENTS.VR_START]: {\n session: XRSession;\n };\n /**\n * An event that fires on exiting VR session\n * @ko VR 세션에서 나갈 때 트리거되는 이벤트\n * @eventName vrEnd\n * @eventOf XRManager\n * @version 4.0.0\n */\n [EVENTS.VR_END]: void;\n}> {\n private _ctx: WebGLContext;\n private _xrSession: XRSession | null;\n private _xrRefSpace: XRReferenceSpace | null;\n private _options: XRSessionOptions;\n\n /**\n * Create new instance.\n * 새 인스턴스를 생성합니다.\n * @param ctx - Instance of WebGL context helper {@ko WebGL 콘텍스트 헬퍼의 인스턴스}\n * @param options - Options {@ko 옵션들}\n */\n public constructor(ctx: WebGLContext, options: XRSessionOptions = {}) {\n super();\n\n this._xrSession = null;\n this._xrRefSpace = null;\n this._ctx = ctx;\n this._options = options;\n }\n\n /**\n * Destroy instance and end XR session if there was any.\n * @ko 인스턴스를 제거하고, XR 세션이 존재할 경우 종료합니다.\n * @since 4.0.0\n */\n public destroy = () => {\n this.exit();\n this.off();\n };\n\n /**\n * Returns WebXR availability.\n * @ko WebXR 사용 가능 여부를 반환합니다.\n * @since 4.0.0\n */\n public async isAvailable(): Promise {\n // eslint-disable-next-line compat/compat\n const xr = window.navigator.xr;\n if (!xr) return false;\n\n return xr.isSessionSupported(SESSION_VR)\n .then(available => {\n return available;\n }).catch(() => {\n return false;\n });\n }\n\n /**\n * Enter VR session\n * @ko VR 세션에 진입합니다.\n * @since 4.0.0\n */\n public async enter() {\n const ctx = this._ctx;\n\n // eslint-disable-next-line compat/compat\n const xr = window.navigator.xr;\n if (!xr) return;\n\n await GyroControl.requestSensorPermission();\n\n const options = {\n ...{\n requiredFeatures: [XR_REFERENCE_SPACE]\n },\n ...this._options\n };\n\n await ctx.makeXRCompatible();\n\n const session = await xr.requestSession(SESSION_VR, options);\n ctx.bindXRLayer(session);\n\n const refSpace = await session.requestReferenceSpace(XR_REFERENCE_SPACE);\n\n this._setSession(session, refSpace);\n\n this.trigger(EVENTS.VR_START, {\n session\n });\n }\n\n /**\n * Exit VR session\n * @ko VR 세션에서 나갑니다.\n * @since 4.0.0\n */\n public exit() {\n const xrSession = this._xrSession;\n\n if (xrSession) {\n xrSession.end()\n .catch(() => void 0);\n }\n\n this._xrSession = null;\n this._xrRefSpace = null;\n }\n\n /**\n * @hidden\n */\n public canRender(frame: XRFrame) {\n const refSpace = this._xrRefSpace;\n\n if (!refSpace) return false;\n\n const pose = frame.getViewerPose(refSpace);\n\n return !!pose;\n }\n\n /**\n * @hidden\n */\n public getEyeParams(frame: XRFrame): Array<{\n viewport: XRViewport;\n vMatrix: mat4;\n pMatrix: mat4;\n }> | null {\n const session = frame.session;\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n if (!pose) return null;\n\n const glLayer = session.renderState.baseLayer;\n\n if (!glLayer) return null;\n\n return pose.views.map(view => {\n const viewport = glLayer.getViewport(view)!;\n const vMatrix = view.transform.inverse.matrix;\n\n return {\n viewport,\n vMatrix,\n pMatrix: view.projectionMatrix\n };\n });\n }\n\n private _setSession(session: XRSession, refSpace: XRReferenceSpace) {\n this._xrSession = session;\n this._xrRefSpace = refSpace;\n\n session.addEventListener(BROWSER.EVENTS.XR_END, this._onSessionEnd);\n }\n\n private _onSessionEnd = () => {\n this.exit();\n this.trigger(EVENTS.VR_END);\n }\n}\n\nexport default XRManager;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { vec3 } from \"gl-matrix\";\n\n/**\n * Hotspot data\n * @ko 핫스팟 데이터\n * @since 4.0.0\n */\nclass Hotspot {\n /**\n * HTMLElement of the hotspot\n * @ko 핫스팟의 HTMLElement\n * @since 4.0.0\n */\n public readonly element: HTMLElement;\n /**\n * Position to render hotspot\n * @ko 핫스팟을 렌더링할 위치\n * @since 4.0.0\n */\n public readonly position: vec3;\n\n public constructor(element: HTMLElement, position: vec3) {\n this.element = element;\n this.position = position;\n }\n}\n\nexport default Hotspot;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { vec2, vec3 } from \"gl-matrix\";\nimport Hotspot from \"./Hotspot\";\nimport Camera from \"../core/Camera\";\nimport WebGLRenderer from \"../core/WebGLRenderer\";\nimport View360Error from \"../core/View360Error\";\nimport { getNullableElement } from \"../utils\";\nimport ERROR from \"../const/error\";\nimport { DEFAULT_CLASS } from \"../const/external\";\nimport { DEG_TO_RAD } from \"../const/internal\";\n\n/**\n * Options for {@link HotspotRenderer}\n * @ko {@link HotspotRenderer}용 옵션들\n * @since 4.0.0\n */\nexport interface HotspotOptions {\n /**\n * Apply scale for hotspots, makes their size sync with background panorama image.\n * @ko 핫스팟에 스케일을 적용해서 배경 파노라마 이미지의 크기 변화와 동일하게 크기를 조절합니다.\n * @since 4.0.0\n */\n zoom: boolean;\n}\n\n/**\n * Hotspot renderer\n * @ko Hotspot 렌더러\n * @since 4.0.0\n */\nclass HotspotRenderer {\n // Options\n private _zoom: HotspotOptions[\"zoom\"];\n\n // Internal properties\n private _containerEl: HTMLElement | null;\n private _renderer: WebGLRenderer;\n private _hotspots: Hotspot[];\n\n /**\n * Create new instance\n * @ko 새 인스턴스를 생성합니다.\n * @param rootEl - Container element for hotspots {@ko 핫스팟들의 컨테이너 엘리먼트}\n * @param renderer - instance of WebGLRenderer {@ko WebGLRenderer의 인스턴스}\n * @param options - Hotspot options {@ko Hotspot 옵션들 }\n */\n public constructor(rootEl: HTMLElement, renderer: WebGLRenderer, {\n zoom = false\n }: Partial) {\n this._containerEl = getNullableElement(`.${DEFAULT_CLASS.HOTSPOT_CONTAINER}`, rootEl);\n this._renderer = renderer;\n this._hotspots = [];\n\n this._zoom = zoom;\n }\n\n /**\n * Refresh hotspots by collecting hotspot elements from current hotspot root element\n * @ko 현재 핫스팟 루트 엘리먼트 내에서 핫스팟 엘리먼트들을 수집하여 갱신합니다.\n * @throws {ERROR_CODES.INSUFFICIENT_ARGS} if data-position doesn't include all x, y, z values {@ko data-position이 x, y, z좌표를 전부 포함하고 있지 않을 때}\n */\n public refresh() {\n const container = this._containerEl;\n if (!container) return;\n\n const hotspotEls = [].slice.apply(container.querySelectorAll(`.${DEFAULT_CLASS.HOTSPOT}`)) as HTMLElement[];\n this._hotspots = hotspotEls.map(el => this._parseHotspot(el));\n }\n\n /**\n * Render hotspots\n * @ko 핫스팟들을 렌더링합니다.\n * @param camera - Instance of Camera {@ko Camera의 인스턴스}\n */\n public render(camera: Camera) {\n const hotspots = this._hotspots;\n const halfWidth = this._renderer.width * 0.5;\n const halfHeight = this._renderer.height * 0.5;\n const zoom = camera.zoom;\n const centerTransform = \"translate(-50%, -50%)\";\n const zoomTransform = this._zoom ? `scale(${zoom})` : \"\";\n\n hotspots.forEach(hotspot => {\n const position = hotspot.position;\n const relPos = vec3.create();\n\n vec3.copy(relPos, position);\n vec3.transformMat4(relPos, relPos, camera.viewMatrix);\n vec3.transformMat4(relPos, relPos, camera.projectionMatrix);\n\n if (relPos[2] > 1 || relPos[2] < 0) {\n hotspot.element.classList.remove(DEFAULT_CLASS.HOTSPOT_VISIBLE);\n return;\n }\n\n const screenPos = vec2.fromValues(\n relPos[0] * halfWidth + halfWidth,\n -relPos[1] * halfHeight + halfHeight\n );\n\n hotspot.element.classList.add(DEFAULT_CLASS.HOTSPOT_VISIBLE);\n hotspot.element.style.transform = [\n centerTransform,\n `translate(${screenPos[0]}px, ${screenPos[1]}px)`,\n zoomTransform\n ].join(\" \");\n });\n }\n\n private _parseHotspot(element: HTMLElement): Hotspot {\n const yawStr = element.dataset.yaw;\n const pitchStr = element.dataset.pitch;\n const positionStr = element.dataset.position;\n\n if (yawStr || pitchStr) {\n const yaw = yawStr ? parseFloat(yawStr) : 0;\n const pitch = pitchStr ? parseFloat(pitchStr) : 0;\n\n const position = this._yawPitchToVec3(yaw, pitch);\n\n return new Hotspot(element, position);\n } else if (positionStr) {\n const pos: number[] = positionStr.split(\" \").map(val => parseFloat(val));\n if (pos.length < 3) {\n throw new View360Error(ERROR.MESSAGES.INSUFFICIENT_ARGS(positionStr, \"hotspot attribute \\\"data-position\\\"\"), ERROR.CODES.INSUFFICIENT_ARGS);\n }\n\n return new Hotspot(element, vec3.fromValues(pos[0], pos[1], pos[2]));\n } else {\n // Place hotspot at yaw: 0, pitch: 0\n const defaultPos = vec3.fromValues(0, 0, -1);\n\n return new Hotspot(element, defaultPos);\n }\n }\n\n private _yawPitchToVec3(yaw: number, pitch: number) {\n const yawRad = yaw * DEG_TO_RAD;\n const pitchRad = pitch * DEG_TO_RAD;\n const position = vec3.create();\n\n position[1] = Math.sin(pitchRad);\n position[2] = Math.cos(pitchRad);\n\n position[0] = position[2] * Math.sin(-yawRad);\n position[2] = -position[2] * Math.cos(-yawRad);\n\n return position;\n }\n}\n\nexport default HotspotRenderer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"../geometry/Geometry\";\nimport { VAO } from \"../type/internal\";\n\n/**\n * @hidden\n */\nclass VertexArrayObject {\n public readonly obj: VAO | null;\n public readonly geometry: Geometry;\n public readonly buffers: {\n indicies: WebGLBuffer;\n position: WebGLBuffer;\n uv: WebGLBuffer;\n }\n\n public get count() { return this.geometry.indicies.count; }\n\n constructor(obj: VAO | null, geometry: Geometry, buffers: VertexArrayObject[\"buffers\"]) {\n this.obj = obj;\n this.geometry = geometry;\n this.buffers = buffers;\n }\n}\n\nexport default VertexArrayObject;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4 } from \"gl-matrix\";\nimport Uniform from \"../uniform/Uniform\";\nimport Camera from \"./Camera\";\nimport Object3D from \"./Object3D\";\nimport ShaderProgram from \"./ShaderProgram\";\nimport View360Error from \"./View360Error\";\nimport VertexArrayObject from \"./VertexArrayObject\";\nimport VertexData from \"./VertexData\";\nimport Texture from \"../texture/Texture\";\nimport Geometry from \"../geometry/Geometry\";\nimport * as BROWSER from \"../const/browser\";\nimport ERROR from \"../const/error\";\nimport { DEFAULT_CLASS } from \"../const/external\";\nimport { UniformLocations } from \"../type/internal\";\n\n/**\n * @hidden\n */\nclass WebGLContext {\n private _canvas: HTMLCanvasElement;\n private _gl: WebGLRenderingContext | WebGL2RenderingContext;\n private _contextLost: boolean;\n private _maxTextureSize: number;\n private _isWebGL2: boolean;\n private _debug: boolean;\n private _extensions: {\n vao: OES_vertex_array_object | null;\n loseContext: WEBGL_lose_context | null;\n };\n\n public get canvas() { return this._canvas; }\n public get maxTextureSize() { return this._maxTextureSize; }\n public get isWebGL2() { return this._isWebGL2; }\n public get supportVAO() { return this._isWebGL2 || !!this._extensions.vao; }\n public get lost() { return this._contextLost; }\n public get debug() { return this._debug; }\n\n public constructor(canvas: HTMLCanvasElement, debug: boolean) {\n this._canvas = canvas;\n this._contextLost = false;\n this._debug = debug;\n this._extensions = {\n vao: null,\n loseContext: null\n };\n }\n\n public init() {\n const canvas = this._canvas;\n\n const { gl, isWebGL2 } = this._getContext(canvas);\n\n this._gl = gl;\n this._maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n this._isWebGL2 = isWebGL2;\n\n if (!this._isWebGL2) {\n this._extensions.vao = gl.getExtension(\"OES_vertex_array_object\");\n }\n\n this._extensions.loseContext = gl.getExtension(\"WEBGL_lose_context\");\n\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_LOST, this._onContextLost);\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_RESTORED, this._onContextRestore);\n\n // gl.enable(gl.DEPTH_TEST);\n }\n\n public destroy() {\n const gl = this._gl;\n const canvas = this._canvas;\n\n if (gl) {\n // gl is not defined when destroy is called before init\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n }\n\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_LOST, this._onContextLost);\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_RESTORED, this._onContextRestore);\n }\n\n public forceLoseContext() {\n const extension = this._extensions.loseContext;\n\n if (!extension) return;\n\n extension.loseContext();\n }\n\n public forceRestoreContext() {\n const extension = this._extensions.loseContext;\n\n if (!extension) return;\n\n extension.restoreContext();\n }\n\n public clear() {\n const gl = this._gl;\n\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n\n public resize() {\n const gl = this._gl;\n\n gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n }\n\n public viewport(x: number, y: number, width: number, height: number) {\n const gl = this._gl;\n\n gl.viewport(x, y, width, height);\n }\n\n public createVAO(geometry: Geometry, shaderProgram: ShaderProgram) {\n const nativeVAO = this._createNativeVAO();\n\n const vao = new VertexArrayObject(nativeVAO, geometry, {\n indicies: this._createBuffer(),\n position: this._createBuffer(),\n uv: this._createBuffer()\n });\n\n if (nativeVAO) {\n this._bindNativeVAO(nativeVAO);\n this._supplyGeometryData(vao, shaderProgram);\n this._bindNativeVAO(null);\n this._unbindBuffers();\n }\n\n return vao;\n }\n\n public draw(vao: VertexArrayObject, shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n if (vao.obj) {\n this._bindNativeVAO(vao.obj);\n } else {\n this._supplyGeometryData(vao, shaderProgram);\n }\n\n gl.drawElements(gl.TRIANGLES, vao.count, gl.UNSIGNED_SHORT, 0);\n\n if (vao.obj) {\n this._bindNativeVAO(null);\n } else {\n this._unbindBuffers();\n }\n }\n\n public releaseVAO(vao: VertexArrayObject) {\n if (vao.obj) {\n this._deleteNativeVAO(vao.obj);\n }\n\n this._deleteBuffer(vao.buffers.indicies);\n this._deleteBuffer(vao.buffers.position);\n this._deleteBuffer(vao.buffers.uv);\n }\n\n public getUniformLocations>(program: WebGLProgram, uniforms: T): UniformLocations {\n const gl = this._gl;\n\n const uniformLocations = Object.keys(uniforms).reduce((locations, key) => {\n locations[key as keyof T] = gl.getUniformLocation(program, key)!;\n\n return locations;\n }, {} as UniformLocations);\n\n return {\n ...this._getCommonUniformLocations(program),\n ...uniformLocations\n };\n }\n\n public updateCommonUniforms(entity: Object3D, camera: Camera, shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniformLocations = shaderProgram.uniformLocations;\n\n // We're using \"matrix\"(=local matrix) here for efficiency\n // As projection doesn't require world matrix, as it doesn't have any parent or child\n const matrix = entity.matrix;\n const mvMatrix = mat4.create();\n mat4.multiply(mvMatrix, camera.viewMatrix, matrix);\n\n gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix);\n gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, camera.projectionMatrix);\n }\n\n public updateVRUniforms(shaderProgram: ShaderProgram, mvMatrix: mat4, pMatrix: mat4, eyeIndex: number) {\n const gl = this._gl;\n\n const uniformLocations = shaderProgram.uniformLocations;\n\n gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix);\n gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, pMatrix);\n\n if (uniformLocations.uEye) {\n gl.uniform1f(uniformLocations.uEye, eyeIndex);\n }\n }\n\n public updateUniforms(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniforms = shaderProgram.uniforms;\n const uniformLocations = shaderProgram.uniformLocations;\n\n for (const key in uniforms) {\n const uniform = uniforms[key];\n const location = uniformLocations[key];\n\n if (!uniform) continue;\n\n if (uniform.needsUpdate) {\n uniform.update(gl, location, this._isWebGL2);\n }\n }\n }\n\n public releaseShaderResources(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniforms = shaderProgram.uniforms;\n\n for (const key in uniforms) {\n const uniform = uniforms[key];\n\n if (!uniform) continue;\n\n if (uniform.needsUpdate) {\n uniform.destroy(gl);\n }\n }\n\n gl.deleteProgram(shaderProgram.program);\n }\n\n public useProgram(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n gl.useProgram(shaderProgram.program);\n }\n\n public createProgram(vertexShader: string, fragmentShader: string) {\n const gl = this._gl;\n const program = gl.createProgram()!;\n\n const vs = this._compileShader(gl.VERTEX_SHADER, vertexShader);\n const fs = this._compileShader(gl.FRAGMENT_SHADER, fragmentShader);\n\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.bindAttribLocation(program, 0, \"position\");\n gl.bindAttribLocation(program, 1, \"uv\");\n gl.linkProgram(program);\n\n if (this._debug && !gl.getProgramParameter(program, gl.LINK_STATUS)) {\n let shaderLog: string | null = null;\n\n if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {\n shaderLog = gl.getShaderInfoLog(vs);\n } else if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {\n shaderLog = gl.getShaderInfoLog(fs);\n }\n\n throw new View360Error(ERROR.MESSAGES.FAILED_LINKING_PROGRAM(gl.getProgramInfoLog(program), shaderLog), ERROR.CODES.FAILED_LINKING_PROGRAM);\n }\n\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n\n return program;\n }\n\n public createWebGLTexture(texData: Texture): WebGLTexture {\n const gl = this._gl;\n const texture = gl.createTexture()!;\n\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texData.wrapS);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texData.wrapT);\n\n if (!texData.isVideo() && this._isWebGL2) {\n const gl2 = gl as WebGL2RenderingContext;\n\n gl2.texStorage2D(gl2.TEXTURE_2D, 1, gl2.RGBA8, texData.width, texData.height);\n }\n\n return texture;\n }\n\n public createWebGLCubeTexture(texData: Texture, size: number): WebGLTexture {\n const gl = this._gl;\n const texture = gl.createTexture()!;\n\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, texData.wrapS);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, texData.wrapT);\n\n if (this._isWebGL2) {\n const gl2 = gl as WebGL2RenderingContext;\n\n gl2.texStorage2D(gl2.TEXTURE_CUBE_MAP, 1, gl2.RGBA8, size, size);\n }\n\n return texture;\n }\n\n public async makeXRCompatible() {\n const gl = this._gl;\n const attributes = gl.getContextAttributes();\n\n if (attributes && attributes.xrCompatible !== true) {\n await gl.makeXRCompatible();\n }\n }\n\n public bindXRLayer(session: XRSession) {\n const gl = this._gl;\n const xrLayer = new XRWebGLLayer(session, gl);\n session.updateRenderState({ baseLayer: xrLayer });\n }\n\n public bindXRFrame(frame: XRFrame) {\n const gl = this._gl;\n const session = frame.session;\n const baseLayer = session.renderState.baseLayer!;\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer);\n }\n\n public useDefaultFrameBuffer() {\n const gl = this._gl;\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n private _createBuffer(): WebGLBuffer {\n return this._gl.createBuffer()!;\n }\n\n private _deleteBuffer(buffer: WebGLBuffer) {\n return this._gl.deleteBuffer(buffer);\n }\n\n private _createNativeVAO() {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n return (gl as WebGL2RenderingContext).createVertexArray()!;\n } else {\n const ext = this._extensions.vao;\n\n return ext?.createVertexArrayOES() || null;\n }\n }\n\n private _bindNativeVAO(vao: WebGLVertexArrayObject | null) {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n (gl as WebGL2RenderingContext).bindVertexArray(vao);\n } else {\n const ext = this._extensions.vao;\n\n ext?.bindVertexArrayOES(vao);\n }\n }\n\n private _deleteNativeVAO(vao: WebGLVertexArrayObject | null) {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n (gl as WebGL2RenderingContext).deleteVertexArray(vao);\n } else {\n const ext = this._extensions.vao;\n\n ext?.deleteVertexArrayOES(vao);\n }\n }\n\n private _supplyGeometryData(vao: VertexArrayObject, shaderProgram: ShaderProgram) {\n const geometry = vao.geometry;\n\n this._supplyIndiciesData(geometry.indicies, vao.buffers.indicies);\n this._supplyAttributeData(geometry.vertices, shaderProgram.program, \"position\", vao.buffers.position);\n this._supplyAttributeData(geometry.uvs, shaderProgram.program, \"uv\", vao.buffers.uv);\n }\n\n private _unbindBuffers() {\n const gl = this._gl;\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n }\n\n private _supplyIndiciesData(indicies: VertexData, buffer: WebGLBuffer) {\n const gl = this._gl;\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicies.data, gl.STATIC_DRAW);\n }\n\n private _supplyAttributeData(attribute: VertexData, program: WebGLProgram, name: string, buffer: WebGLBuffer) {\n const gl = this._gl;\n const attribLocation = gl.getAttribLocation(program, name);\n\n // Attribute not used\n if (attribLocation < 0) return;\n\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ARRAY_BUFFER, attribute.data, gl.STATIC_DRAW);\n gl.vertexAttribPointer(attribLocation, attribute.itemSize, gl.FLOAT, false, 0, 0);\n gl.enableVertexAttribArray(attribLocation);\n }\n\n private _compileShader(type: number, src: string) {\n const gl = this._gl;\n const shader = gl.createShader(type)!;\n\n gl.shaderSource(shader, src);\n gl.compileShader(shader);\n\n return shader;\n }\n\n private _getCommonUniformLocations(program: WebGLProgram) {\n const gl = this._gl;\n\n return {\n uMVMatrix: gl.getUniformLocation(program, \"uMVMatrix\")!,\n uPMatrix: gl.getUniformLocation(program, \"uPMatrix\")!\n };\n }\n\n private _getContext(canvas: HTMLCanvasElement): {\n gl: WebGLRenderingContext | WebGL2RenderingContext;\n isWebGL2: boolean;\n } {\n const webglIdentifiers = [\"webgl2\", \"webgl\", \"experimental-webgl\", \"webkit-3d\", \"moz-webgl\"];\n let context: WebGLRenderingContext | null = null;\n let isWebGL2 = false;\n const contextAttributes = {\n preserveDrawingBuffer: false,\n antialias: false\n };\n\n const onWebglContextCreationError = e => e.statusMessage;\n\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_CREATE_ERROR, onWebglContextCreationError);\n\n for (const identifier of webglIdentifiers) {\n try {\n context = canvas.getContext(identifier, contextAttributes) as WebGLRenderingContext;\n isWebGL2 = identifier === \"webgl2\";\n } catch (t) {} // eslint-disable-line no-empty\n if (context) {\n break;\n }\n }\n\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_CREATE_ERROR, onWebglContextCreationError);\n\n if (!context) {\n throw new View360Error(ERROR.MESSAGES.WEBGL_NOT_SUPPORTED, ERROR.CODES.WEBGL_NOT_SUPPORTED);\n }\n\n return {\n gl: context,\n isWebGL2\n };\n }\n\n private _onContextLost = () => {\n const canvas = this._canvas;\n canvas.classList.add(DEFAULT_CLASS.CTX_LOST);\n this._contextLost = true;\n };\n\n private _onContextRestore = () => {\n const canvas = this._canvas;\n canvas.classList.remove(DEFAULT_CLASS.CTX_LOST);\n this._contextLost = false;\n };\n}\n\nexport default WebGLContext;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4 } from \"gl-matrix\";\nimport Camera from \"./Camera\";\nimport Projection from \"../projection/Projection\";\nimport WebGLContext from \"./WebGLContext\";\nimport XRManager from \"./XRManager\";\n\n/**\n * Projection renderer, based on WebGL\n * @ko WebGL 기반의 프로젝션 렌더러\n * @since 4.0.0\n */\nclass WebGLRenderer {\n private _canvas: HTMLCanvasElement;\n private _elementSize: { x: number, y: number };\n private _pixelRatio: number;\n\n public readonly ctx: WebGLContext;\n\n /**\n * Canvas element\n * @ko 캔버스 엘리먼트\n * @since 4.0.0\n */\n public get canvas() { return this._canvas; }\n /**\n * Canvas's width (`devicePixelRatio` is not applied)\n * @ko 캔버스의 보이는 너비 (`devicePixelRatio`가 적용되지 않은)\n * @since 4.0.0\n */\n public get width() { return this._elementSize.x; }\n /**\n * Canvas's height (`devicePixelRatio` is not applied)\n * @ko 캔버스의 높이 (`devicePixelRatio`가 적용되지 않은)\n * @since 4.0.0\n */\n public get height() { return this._elementSize.y; }\n /**\n * Current `devicePixelRatio` value.\n * @ko 현재 `devicePixelRatio` 값.\n * @since 4.0.0\n * @example\n * ```js\n * cosnt renderingWidth = view360.renderer.width * view360.renderer.pixelRatio;\n * ```\n */\n public get pixelRatio() { return this._pixelRatio; }\n /**\n * Width / height ratio (= width / height)\n * @ko 너비 / 높이의 비율 (= width / height)\n * @since 4.0.0\n * @example\n * ```js\n * const aspect = view360.renderer.width / view360.renderer.pixelRatio;\n * assert(aspect === view360.renderer.aspect);\n * ```\n */\n public get aspect() { return this._elementSize.x / this._elementSize.y; }\n\n /**\n * Create new instance\n * @ko 새 인스턴스를 생성합니다.\n * @param canvas - Canvas element {@ko 캔버스 엘리먼트}\n * @param debug - Whether to enable WebGL debugging {@ko WebGL debug 활성화 여부 }\n */\n public constructor(canvas: HTMLCanvasElement, debug: boolean) {\n this._canvas = canvas;\n this._elementSize = { x: 0, y: 0 };\n this._pixelRatio = 1;\n this.ctx = new WebGLContext(canvas, debug);\n }\n\n /**\n * Destroy instance and release all resources.\n * @ko 인스턴스를 제거하고 사용된 리소스를 전부 해제합니다.\n * @since 4.0.0\n */\n public destroy() {\n const canvas = this._canvas;\n\n this.ctx.destroy();\n canvas.width = 1;\n canvas.height = 1;\n }\n\n /**\n * Resize canvas and renew inner size cache.\n * @ko 캔버스의 크기를 재계산해서 내부의 사이즈 캐시값을 갱신합니다.\n * @since 4.0.0\n */\n public resize() {\n const canvas = this._canvas;\n const canvasSize = this._elementSize;\n const devicePixelRatio = window.devicePixelRatio;\n\n canvasSize.x = canvas.clientWidth;\n canvasSize.y = canvas.clientHeight;\n\n canvas.width = canvasSize.x * devicePixelRatio;\n canvas.height = canvasSize.y * devicePixelRatio;\n\n this._pixelRatio = devicePixelRatio;\n this.ctx.resize();\n }\n\n /**\n * Render projection\n * @ko 프로젝션을 렌더링합니다.\n * @param projection - Projection to render {@ko 렌더링할 프로젝션}\n * @param cameraa - Camera instance {@ko 카메라의 인스턴스}\n * @since 4.0.0\n */\n public render(projection: Projection, camera: Camera) {\n const ctx = this.ctx;\n const mesh = projection.getMesh();\n if (ctx.lost || !mesh) return;\n\n ctx.clear();\n ctx.useProgram(mesh.program);\n ctx.updateCommonUniforms(mesh, camera, mesh.program);\n projection.update(camera);\n ctx.updateUniforms(mesh.program);\n ctx.draw(mesh.vao, mesh.program);\n }\n\n /**\n * Render VR frame, only used for rendering frames inside VR sessions.\n * @ko VR 프레임을 렌더링합니다. VR 세션 진입 도중에만 사용됩니다.\n * @internal\n * @param projection - Projection to render {@ko 렌더링할 프로젝션}\n * @param vr - Instance of XRManager {@ko XRManager의 인스턴스}\n * @param frame - VR frame {@ko VR 프레임}\n * @since 4.0.0\n */\n public renderVR(projection: Projection, vr: XRManager, frame: XRFrame) {\n const ctx = this.ctx;\n const mesh = projection.getMesh();\n const eyeParams = vr.getEyeParams(frame);\n\n if (!eyeParams || !mesh) return;\n\n ctx.bindXRFrame(frame);\n ctx.useProgram(mesh.program);\n ctx.updateUniforms(mesh.program);\n\n eyeParams.forEach((eye, eyeIndex) => {\n const viewport = eye.viewport;\n // We're using \"mesh.matrix\"(=local matrix) here for efficiency\n // As projection doesn't require world matrix, as it doesn't have any parent or child\n const mvMatrix = mat4.multiply(mat4.create(), eye.vMatrix, mesh.matrix);\n\n ctx.viewport(viewport.x, viewport.y, viewport.width, viewport.height);\n ctx.updateVRUniforms(mesh.program, mvMatrix, eye.pMatrix, eyeIndex);\n ctx.draw(mesh.vao, mesh.program);\n });\n }\n}\n\nexport default WebGLRenderer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport Camera, { CameraOptions } from \"./core/Camera\";\nimport PanoControl, { PanoControlOptions } from \"./control/PanoControl\";\nimport TextureLoader from \"./core/TextureLoader\";\nimport FrameAnimator from \"./core/FrameAnimator\";\nimport AutoResizer from \"./core/AutoResizer\";\nimport Autoplay, { AutoplayOptions } from \"./core/Autoplay\";\nimport XRManager from \"./core/XRManager\";\nimport View360Error from \"./core/View360Error\";\nimport Projection from \"./projection/Projection\";\nimport HotspotRenderer, { HotspotOptions } from \"./hotspot/HotspotRenderer\";\nimport WebGLRenderer from \"./core/WebGLRenderer\";\nimport Texture from \"./texture/Texture\";\nimport View360Plugin from \"./plugin/View360Plugin\";\nimport ERROR from \"./const/error\";\nimport { CONTROL_EVENTS } from \"./const/internal\";\nimport { DEFAULT_CLASS, EVENTS } from \"./const/external\";\nimport { findCanvas, getElement } from \"./utils\";\nimport * as EVENT_TYPES from \"./type/events\";\nimport { EventParams } from \"./type/utils\";\n\n/**\n * Events that {@link View360} can trigger\n * @ko {@link View360}가 트리거할 수 있는 이벤트들\n * @see [Detailed Example](/docs/events/ready)\n * @since 4.0.0\n */\nexport interface View360Events {\n [EVENTS.READY]: EVENT_TYPES.ReadyEvent;\n [EVENTS.LOAD_START]: EVENT_TYPES.LoadStartEvent;\n [EVENTS.LOAD]: EVENT_TYPES.LoadEvent;\n [EVENTS.PROJECTION_CHANGE]: EVENT_TYPES.ProjectionChangeEvent;\n [EVENTS.RESIZE]: EVENT_TYPES.ResizeEvent;\n [EVENTS.BEFORE_RENDER]: EVENT_TYPES.BeforeRenderEvent;\n [EVENTS.RENDER]: EVENT_TYPES.RenderEvent;\n [EVENTS.INPUT_START]: EVENT_TYPES.InputStartEvent;\n [EVENTS.INPUT_END]: EVENT_TYPES.InputEndEvent;\n [EVENTS.VIEW_CHANGE]: EVENT_TYPES.ViewChangeEvent;\n [EVENTS.STATIC_CLICK]: EVENT_TYPES.StaticClickEvent;\n [EVENTS.VR_START]: EVENT_TYPES.VRStartEvent;\n [EVENTS.VR_END]: EVENT_TYPES.VREndEvent;\n}\n\n/**\n * Options for {@link View360}\n * @ko {@link View360}용 옵션들\n * @see [Detailed Example](/docs/options)\n * @since 4.0.0\n */\nexport interface View360Options extends CameraOptions, PanoControlOptions {\n projection: Projection | null;\n hotspot: Partial;\n autoplay: boolean | Partial;\n autoInit: boolean;\n autoResize: boolean;\n canvasSelector: string;\n useResizeObserver: boolean;\n tabIndex: number | null;\n on: Partial<{ [key in keyof View360Events]: (evt: View360Events[key]) => any }>;\n plugins: View360Plugin[];\n maxDeltaTime: number;\n debug: boolean;\n}\n\n/**\n * Panorama 360 image viewer\n * @ko 파노라마 360 이미지 뷰어\n * @since 4.0.0\n * @see View360Options\n * @see View360Events\n */\nclass View360 extends Component {\n /**\n * Current version string of the View360\n * @ko View360의 현재 버젼 문자열\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // If the installed version of the View360 is v4.0.0, View360.VERSION is equal to \"4.0.0\"\n * console.log(View360.VERSION) // 4.0.0\n * ```\n */\n public static readonly VERSION = \"#__VERSION__#\";\n\n private _rootEl: HTMLElement;\n private _renderer: WebGLRenderer;\n private _camera: Camera;\n private _control: PanoControl;\n private _animator: FrameAnimator;\n private _autoplay: Autoplay;\n private _hotspot: HotspotRenderer;\n private _projection: Projection | null;\n private _autoResizer: AutoResizer;\n private _vr: XRManager;\n private _plugins: View360Plugin[];\n private _initialized: boolean;\n\n private _autoInit: View360Options[\"autoInit\"];\n private _autoResize: View360Options[\"autoResize\"];\n private _canvasSelector: View360Options[\"canvasSelector\"];\n private _useResizeObserver: View360Options[\"useResizeObserver\"];\n private _tabIndex: View360Options[\"tabIndex\"];\n private _debug: View360Options[\"debug\"];\n\n /**\n * Root element (`.view360-container`)\n * @ko 루트 엘리먼트 (`.view360-container`)\n * @since 4.0.0\n * @readonly\n * @example\n * ```html\n *
\n * \n *
\n * ```\n * ```ts\n * import View360 from \"@egjs/view360\";\n *\n * const viewer = new View360(\"#viewer\");\n * console.log(viewer.rootEl); // Element with id \"viewer\"\n * ```\n */\n public get rootEl() { return this._rootEl; }\n /**\n * Projection renderer.\n * @ko 프로젝션 렌더러.\n * @since 4.0.0\n * @readonly\n */\n public get renderer() { return this._renderer; }\n /**\n * Projection camera.\n * @ko 프로젝션 카메라.\n * @since 4.0.0\n * @readonly\n */\n public get camera() { return this._camera; }\n /**\n * Rotate/Zoom Controller.\n * @ko 회전/줌 컨트롤러.\n * @since 4.0.0\n * @readonly\n */\n public get control() { return this._control; }\n /**\n * WebXR-based VR manager.\n * @ko WebXR 기반의 VR 기능 매니저 인스턴스.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // Example: Enter VR\n * // This must be called on user interaction, else will be rejected.\n * viewer.vr.enter();\n * ```\n */\n public get vr() { return this._vr; }\n /**\n * Hotspot renderer.\n * You can also change options of {@link View360Options#hotspot} with this.\n * @ko 핫스팟 렌더러 인스턴스.\n * {@link View360Options#hotspot} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get hotspot() { return this._hotspot; }\n /**\n * An array of plugins added.\n * @ko 추가된 플러그인의 배열\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * plugins: [new ControlBar()]\n * });\n *\n * console.log(viewer.plugins); // [ControlBar]\n *\n * viewer.addPlugins(new LoadingSpinner()) // [ControlBar, LoadingSpinner];\n * ```\n */\n public get plugins() { return this._plugins; }\n /**\n * A instance of {@link Projection} that currently enabled. `null` if not initialized yet.\n * You should call {@link View360#load} to change panorama src or projection type.\n * @ko 현재 사용중인 {@link Projection}의 인스턴스. 프로젝션을 활성화하지 않았을 경우 `null`입니다.\n * 파노라마 이미지 소스나 프로젝션 타입을 변경하려면 {@link View360#load}를 호출하면 됩니다.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360\n * ```\n */\n public get projection() { return this._projection; }\n public set projection(val: View360Options[\"projection\"]) {\n if (this._initialized && val) {\n this.load(val);\n } else {\n this._projection = val;\n }\n }\n /**\n * A boolean value whether {@link View360#init init()} is called before.\n * @ko {@link View360#init init()}이 호출되었는지 여부를 가리키는 값\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360(\"#el\", { autoInit: false });\n *\n * console.log(viewer.initialized); // false\n *\n * await viewer.init();\n *\n * console.log(viewer.initialized); // true\n * ```\n */\n public get initialized() { return this._initialized; }\n /**\n * Instance of the Autoplay manager.\n * You can also change {@link View360Options#autoplay} options with this.\n * @ko Autoplay 기능의 매니저 인스턴스.\n * 이 인스턴스를 통해 {@link View360Options#autoplay} 옵션을 변경하는 것도 가능합니다.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // Disable autoplay\n * viewer.autoplay.disable();\n * ```\n */\n public get autoplay() { return this._autoplay; }\n /**\n * When this value is `true` and {@link View360Options#projection} is set, {@link View360#init init()} will be called automatically when instance is created.\n * @ko 이 값이 `true`이고, {@link View360Options#projection}이 설정되었으면, 인스턴스 생성 시점에 자동으로 {@link View360#init init()}을 호출합니다.\n * @default true\n * @since 4.0.0\n * @example\n * ```ts\n * import View360, { EquirectProjection, EVENTS } from \"@egjs/view360\";\n *\n * // viewer.init() is called on instance creation\n * // But as `init` is asynchronous, you should wait for \"ready\" event if you want to do something after initialization.\n * const viewer = new View360(\"#el_id\", {\n * autoInit: true,\n * projection: new EquirectProjection({ src: \"SRC_TO_URL\" })\n * });\n *\n * console.log(viewer.initialized); // false, as `init` is asynchronous\n *\n * viewer.once(EVENTS.READY, () => {\n * console.log(viewer.initialized); // true\n * });\n * ```\n */\n public get autoInit() { return this._autoInit; }\n /**\n * When `true`, {@link View360#resize} is called when the canvas size is changed.\n * @ko `true`일 경우, 캔버스의 크기가 변경되었을 때 자동으로 {@link View360#resize}를 호출합니다.\n * @default true\n * @since 4.0.0\n * @see View360#useResizeObserver\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * autoResize: true\n * });\n *\n * // This can trigger `viewer.resize()` if the canvas size was not 400px\n * const canvas = viewer.renderer.canvas;\n * canvas.style.width = \"400px\";\n * ```\n */\n public get autoResize() { return this._autoResize; }\n /**\n * CSS selector for canvas element to render panorama image/video.\n * The canvas element should be placed inside the root element. (Dont' have to be direct child)\n * @ko 파노라마 이미지/비디오를 렌더링할 canvas 엘리먼트의 CSS 선택자\n * 캔버스 엘리먼트는 루트 엘리먼트 내부에 있어야합니다. 루트 엘리먼트의 직계 자식 엘리먼트(Direct child element)일 필요는 없습니다.\n * @default \"canvas\"\n * @since 4.0.0\n * @example\n * ```html\n *
\n * \n * \n * \n *
\n * ```\n *\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * canvasSelector: \"#canvas_to_select\"\n * });\n * ```\n */\n public get canvasSelector() { return this._canvasSelector; }\n /**\n * When `true`, it will use {@link ResizeObserver} API to detect canvas size change when {@link View360Options#autoResize} is enabled.\n * @ko `true`일 때 {@link View360Options#autoResize}가 활성화되었으면, 사용 가능한 환경에서 {@link ResizeObserver} API를 사용해서 캔버스 크기 변화를 추적합니다.\n * @default true\n * @since 4.0.0\n */\n public get useResizeObserver() { return this._useResizeObserver; }\n /**\n * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} attribute for the canvas element.\n * This is necessary for the keyboard controls.\n * By default, `0` will be assigned. `null` to disable.\n * @ko 캔버스 엘리먼트에 적용할 {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} 어트리뷰트의 값.\n * 이 값을 설정해야만 키보드 컨트롤을 사용 가능합니다.\n * 기본값으로 `0`이 설정됩니다. `null`로 지정하면 `tabindex`를 설정하지 않습니다.\n * @see RotateControlOptions#disableKeyboard\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * tabindex: 5\n * });\n * ```\n *\n * ```html\n * \n *
\n * \n *
\n * ```\n */\n public get tabIndex() { return this._tabIndex; }\n public set tabIndex(val: View360Options[\"tabIndex\"]) {\n const canvas = this._renderer.canvas;\n this._tabIndex = val;\n\n if (val != null) {\n canvas.tabIndex = val;\n } else {\n canvas.removeAttribute(\"tabindex\");\n }\n }\n /**\n * A maximum delta time between frames in seconds.\n * It can prevent camera or control changing too fast when frame being late.\n * @ko 프레임간 시간 차이의 최대값. (초 단위)\n * 퍼포먼스 등의 이유로 프레임 렌더링이 늦어졌을 때, 화면이 갑작스럽게 바뀌는 것을 막아줍니다.\n * @default 1 / 30\n * @since 4.0.0\n */\n public get maxDeltaTime() { return this._animator.maxDeltaTime; }\n public set maxDeltaTime(val: View360Options[\"maxDeltaTime\"]) { this._animator.maxDeltaTime = val; }\n /**\n * Enable WebGL debugging. Setting this to `true` can decrease performance.\n * This is used internally on developing View360.\n * @ko WebGL 디버깅을 활성화합니다. 이 값을 `true`로 할 경우 성능이 하락할 수 있습니다.\n * 이 옵션은 View360을 개발하기 위해 내부적으로 사용됩니다.\n * @default false\n */\n public get debug() { return this._debug; }\n public set debug(val: View360Options[\"debug\"]) { this._debug = val; }\n\n // Camera options\n /**\n * Initial yaw (y-axis rotation) value for camera. (in degrees, °)\n * As View360 uses right-handed coordinate system internally, camera will rotate counter-clockwise by this value.\n * @ko 카메라의 초기 yaw(y축 회전)값 (도 단위, °)\n * View360은 오른손 좌표계를 사용하기 때문에, 카메라가 해당 값만큼 시계 반대방향으로 회전합니다.\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialYaw: 30\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.yaw); // 30\n * });\n * ```\n */\n public get initialYaw() { return this._camera.initialYaw; }\n public set initialYaw(val: View360Options[\"initialYaw\"]) { this._camera.initialYaw = val; }\n /**\n * Initial pitch (x-axis rotation) value for camera. (in degrees, °)\n * As View360 uses right-handed coordinate system internally, positive value will make camera to look upside, while negative value will look down.\n * @ko 카메라의 초기 pitch(x축 회전)값 (도 단위, °)\n * View360은 오른손 좌표계를 사용하기 때문에, 양(+)의 값은 카메라가 위를 보게 하고, 음(-)의 값은 카메라가 아래를 보게 합니다.\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialPitch: 60\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.pitch); // 60\n * });\n * ```\n */\n public get initialPitch() { return this._camera.initialPitch; }\n public set initialPitch(val: View360Options[\"initialPitch\"]) { this._camera.initialPitch = val; }\n /**\n * Initial zoom value for camera.\n * Setting this value to `2` will enlarge panorama 200% by width.\n * @ko 카메라의 초기 줌 값.\n * 이 값을 `2`로 설정할 경우 파노라마 이미지를 가로 기준 200%만큼 확대합니다.\n * @default 1\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialZoom: 2\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.zoom); // 2\n * });\n * ```\n */\n public get initialZoom() { return this._camera.initialZoom; }\n public set initialZoom(val: View360Options[\"initialZoom\"]) { this._camera.initialZoom = val; }\n /**\n * Restrict yaw(y-axis rotation) range. (in degrees, °)\n * @ko yaw(y축 회전) 범위를 제한합니다. (도 단위, °)\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * yawRange: [-30, 30]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.yaw); // 0\n * viewer.camera.lookAt({ yaw: 60 });\n * console.log(viewer.camera.yaw); // 30\n * });\n * ```\n */\n public get yawRange() { return this._camera.yawRange; }\n public set yawRange(val: View360Options[\"yawRange\"]) {\n this._camera.yawRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Restrict pitch(x-axis rotation) range. (in degrees, °)\n * @ko pitch(x축 회전) 범위를 제한합니다. (도 단위, °)\n * @default null\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * pitchRange: [-45, 45]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.pitch); // 0\n * viewer.camera.lookAt({ pitch: 60 });\n * console.log(viewer.camera.pitch); // 45\n * });\n * ```\n */\n public get pitchRange() { return this._camera.pitchRange; }\n public set pitchRange(val: View360Options[\"pitchRange\"]) {\n this._camera.pitchRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Restrict camera zoom range.\n * If `null`, a default zoom range from `0.6` to `10` will be used.\n * @ko 카메라 줌 범위를 제한합니다.\n * `null`일 경우 기본값으로 `0.6`에서 `10`의 범위를 사용합니다.\n * @default null\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * zoomRange: [0.5, 4]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.zoom); // 1\n * viewer.camera.lookAt({ zoom: 6 });\n * console.log(viewer.camera.zoom); // 4\n * });\n * ```\n */\n public get zoomRange() { return this._camera.zoomRange; }\n public set zoomRange(val: View360Options[\"zoomRange\"]) {\n this._camera.zoomRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Camera's horizontal FOV(Field of View). (in degrees, °)\n * @ko 카메라의 수평 FOV(Field of View) 값. (도 단위, °)\n * @default 90\n * @since 4.0.0\n * @example\n * ```ts\n * // Init with fov: 120\n * const viewer = new View360(\"#el_id\", { fov: 120 });\n *\n * // Back to 90\n * viewer.fov = 90;\n * ```\n */\n public get fov() { return this._camera.fov; }\n public set fov(val: View360Options[\"fov\"]) {\n const camera = this._camera;\n const control = this._control;\n\n camera.fov = val;\n camera.updateMatrix();\n control.sync();\n }\n\n // Control options\n /**\n * A control for camera rotation.\n * You can also change options of {@link View360Options#rotate} with this.\n * @ko 카메라 회전을 담당하는 컨트롤.\n * {@link View360Options#rotate} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get rotate() { return this._control.rotate; }\n /**\n * A control for camera zoom.\n * You can also change options of {@link View360Options#zoom} with this.\n * @ko 카메라 줌을 담당하는 컨트롤.\n * {@link View360Options#zoom} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get zoom() { return this._control.zoom; }\n /**\n * A control for camera rotation with gyroscope input.\n * You can also change options of {@link View360Options#gyro} with this.\n * @ko 자이로스코프를 통한 카메라 회전을 담당하는 컨트롤.\n * {@link View360Options#gyro} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get gyro() { return this._control.gyro; }\n /**\n * Apply CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor} by current state of input when using mouse.\n * If `true`, this will add CSS style to canvas element. It'll apply `cursor: \"grab\"` by default and `cursor: \"grabbing\"` when holding the mouse button.\n * @ko 마우스 사용시 CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor}값을 자동으로 변경할지 여부.\n * `true`일 경우 기본 상태에서 `cursor: \"grab\"`을, 입력 도중에 `cursor: \"grabbing\"`을 캔버스에 적용합니다.\n * @default true\n * @since 4.0.0\n */\n public get useGrabCursor() { return this._control.useGrabCursor; }\n public set useGrabCursor(val: View360Options[\"useGrabCursor\"]) { this._control.useGrabCursor = val; }\n /**\n * Disable context menu which pops up on mouse right click.\n * @ko 마우스 우클릭시 표시되는 컨텍스트 메뉴를 비활성화합니다.\n * @default false\n * @since 4.0.0\n */\n public get disableContextMenu() { return this._control.disableContextMenu; }\n public set disableContextMenu(val: View360Options[\"disableContextMenu\"]) { this._control.disableContextMenu = val; }\n /**\n * If `true`, enables scroll on mobile(touch) devices on canvas.\n * :::caution\n * When this option is enabled, users must swipe horizontally first then vertically to change view up or down.\n * :::\n * @ko `true`로 설정할 경우, 모바일(터치) 환경의 캔버스 영역 내에서 스크롤을 가능하게 합니다.\n * :::caution\n * 이 값을 활성화할 경우, 사용자가 카메라 뷰를 위/아래로 바꾸기 위해서는 먼저 가로로 스와이프한 이후에 세로로 스와이프해야만 합니다.\n * :::\n * @since 4.0.0\n * @default true\n */\n public get scrollable() { return this._control.scrollable; }\n public set scrollable(val: View360Options[\"scrollable\"]) { this._control.scrollable = val; }\n /**\n * If `true`, enables scroll by mouse wheel on canvas.\n * :::caution\n * When this option is enabled, zoom by mouse wheel will be disabled.\n * :::\n * @ko `true`로 설정할 경우, 캔버스 영역 내에서 마우스 휠을 이용한 페이지 스크롤이 가능해집니다.\n * :::caution\n * 이 값을 활성화할 경우, 마우스 휠을 통한 줌이 불가능하게 됩니다.\n * :::\n * @since 4.0.0\n * @default false\n */\n public get wheelScrollable() { return this._control.wheelScrollable; }\n public set wheelScrollable(val: View360Options[\"wheelScrollable\"]) { this._control.wheelScrollable = val; }\n\n /**\n * Create new instance of View360\n * @ko View360의 새로운 인스턴스를 생성합니다\n * @param root - Root element(`.view360-container`) to mount View360\n * Can be either a CSS selector or HTMLElement.\n * {@ko View360을 마운트할 루트 엘리먼트, CSS 셀렉터나 HTMLElement를 지정 가능합니다.}\n * @param options - Options to apply\n * {@ko 적용할 옵션들}\n * @example\n * ```ts\n * import View360, { EquirectProjection } from \"@egjs/view360\";\n *\n * // Create new View360 instance\n * const viewer = new View360(\"#id-of-a-container\", {\n * projection: new EquirectProjection({\n * src: \"URL_TO_PANORAMA_IMAGE_OR_VIDEO\",\n * })\n * });\n * ```\n */\n public constructor(root: string | HTMLElement, {\n projection = null,\n initialYaw = 0,\n initialPitch = 0,\n initialZoom = 1,\n yawRange = null,\n pitchRange = null,\n zoomRange = null,\n fov = 90,\n useGrabCursor = true,\n disableContextMenu = false,\n rotate = true,\n zoom = true,\n gyro = false,\n scrollable = true,\n wheelScrollable = false,\n autoplay = false,\n hotspot = {},\n autoInit = true,\n autoResize = true,\n canvasSelector = \"canvas\",\n useResizeObserver = true,\n on = {},\n plugins = [],\n maxDeltaTime = 1 / 30,\n tabIndex = 0,\n debug = false\n }: Partial = {}) {\n super();\n\n this._rootEl = getElement(root);\n this._plugins = plugins;\n this._initialized = false;\n\n // Options\n this._autoInit = autoInit;\n this._autoResize = autoResize;\n this._canvasSelector = canvasSelector;\n this._useResizeObserver = useResizeObserver;\n this._tabIndex = tabIndex;\n this._debug = debug;\n\n // Core components\n const canvas = findCanvas(this._rootEl, canvasSelector);\n this._renderer = new WebGLRenderer(canvas, debug);\n this._camera = new Camera({\n initialYaw,\n initialPitch,\n initialZoom,\n fov,\n yawRange,\n pitchRange,\n zoomRange\n });\n this._control = new PanoControl(canvas, this._camera, {\n useGrabCursor,\n scrollable,\n wheelScrollable,\n disableContextMenu,\n rotate,\n zoom,\n gyro\n });\n this._animator = new FrameAnimator(maxDeltaTime);\n this._autoplay = new Autoplay(this, canvas, autoplay);\n this._projection = projection;\n this._autoResizer = new AutoResizer(useResizeObserver, () => this.resize());\n this._vr = new XRManager(this._renderer.ctx);\n this._hotspot = new HotspotRenderer(this._rootEl, this._renderer, hotspot);\n\n this._addEventHandlers(on);\n\n if (projection && autoInit) {\n this.init();\n }\n }\n\n /**\n * Destroy instance and release all resources.\n * @ko 인스턴스를 제거하고 모든 리소스를 해제합니다.\n * @since 4.0.0\n */\n public destroy() {\n this._camera.destroy();\n this._animator.stop();\n this._renderer.destroy();\n this._control.destroy();\n this._autoResizer.disable();\n\n if (this._projection) {\n this._projection.releaseAllResources(this._renderer.ctx);\n this._projection = null;\n }\n\n this._plugins.forEach(plugin => plugin.destroy(this));\n\n this._initialized = false;\n }\n\n /**\n * Initialize inner components and load projection src.\n * @ko 내부 컴포넌트들을 초기화하고 프로젝션 소스를 로드합니다.\n * @since 4.0.0\n */\n public async init() {\n if (!this._projection) {\n throw new View360Error(ERROR.MESSAGES.PROVIDE_PROJECTION_FIRST, ERROR.CODES.PROVIDE_PROJECTION_FIRST);\n }\n\n const renderer = this._renderer;\n const camera = this._camera;\n const control = this._control;\n const animator = this._animator;\n const hotspot = this._hotspot;\n const projection = this._projection;\n const canvas = renderer.canvas;\n\n this._bindComponentEvents();\n renderer.ctx.init();\n this._resizeComponents();\n camera.updateMatrix();\n\n if (this._autoResize) {\n this._autoResizer.enable(canvas);\n }\n\n if (!this._autoplay.enableBlocked) {\n this._autoplay.enable();\n }\n\n this._plugins.forEach(plugin => {\n plugin.init(this);\n });\n\n const texture = await this._loadTexture(projection);\n this._applyProjection(projection, texture, null);\n hotspot.refresh();\n animator.start(this._renderFrameOnDemand);\n await control.enable();\n\n if (this._tabIndex != null && !canvas.hasAttribute(\"tabIndex\")) {\n canvas.tabIndex = this._tabIndex;\n }\n\n this._initialized = true;\n this.renderFrame(0);\n\n this._emit(EVENTS.READY);\n }\n\n /**\n * Load new panorama image/video and display it.\n * This will {@link View360#init init()} View360 if it's not initialized yet.\n * @ko 새로운 파노라마 이미지 혹은 비디오를 로드하고 표시합니다.\n * 만약 View360이 아직 초기화되지 않았다면, {@link View360#init init()}을 호출합니다.\n * @param projection - Projection & video options for new source. {@ko 새로운 파노라마 이미지/비디오에 적용할 옵션들}\n * @returns `Promise` if load was successful. {@ko 프로젝션 로드에 성공했을 경우 `Promise`를 반환합니다. }\n * @since 4.0.0\n * @example\n * ```ts\n * // Change to video\n * viewer.load({\n * src: \"URL_TO_NEW_VIDEO\",\n * video: true\n * });\n * ```\n */\n public async load(projection: Projection): Promise {\n if (!projection) return false;\n\n if (this._initialized) {\n const texture = await this._loadTexture(projection);\n this._applyProjection(projection, texture, this._projection);\n this.renderFrame(0);\n } else {\n // Should update internal options before init\n this._projection = projection;\n this.init();\n }\n\n return true;\n }\n\n /**\n * Refresh component's size by current\n * @ko View360이 내부적으로 캐시하고 있는 엘리먼트 크기를 현재 크기로 갱신합니다.\n * @since 4.0.0\n */\n public resize() {\n if (!this._initialized) return;\n\n this._resizeComponents();\n\n // To prevent flickering, render immediately after resizing components\n this.renderFrame(0);\n\n const { width, height } = this._renderer;\n\n this._emit(EVENTS.RESIZE, {\n width,\n height\n });\n }\n\n /**\n * Add new plugins\n * @ko 새로운 플러그인을 추가합니다.\n * @param plugins Plugins to add {@ko 추가할 플러그인들}\n * @see View360Options#plugins\n * @since 4.0.0\n * @example\n * ```ts\n * // Add a single plugin\n * viewer.addPlugins(new ControlBar());\n *\n * // Add multiple plugins\n * viewer.addPlugins(new ControlBar(), new LoadingSpinner());\n * ```\n */\n public addPlugins(...plugins: View360Plugin[]) {\n if (this._initialized) {\n plugins.forEach(plugin => { plugin.init(this); });\n }\n\n this._plugins.push(...plugins);\n }\n\n /**\n * Remove plugins.\n * @ko 플러그인을 제거합니다.\n * @param plugins Plugins to remove {@ko 제거할 플러그인들}\n * @since 4.0.0\n * @example\n * ```ts\n * // Remove a single plugin\n * viewer.removePlugins(plugin1);\n *\n * // Remove multiple plugins\n * viewer.removePlugins(plugin2, plugin3);\n * ```\n */\n public removePlugins(...plugins: View360Plugin[]) {\n plugins.forEach(plugin => {\n const pluginIdx = this._plugins.indexOf(plugin);\n\n if (pluginIdx < 0) return;\n\n plugin.destroy(this);\n this._plugins.splice(pluginIdx, 1);\n });\n }\n\n /**\n * Render a single panorama image/video frame.\n * Rendering is performed automatically on demand, so you usually don't have to call this.\n * Call this when a frame is not renewed after changing options.\n * @ko 파노라마 이미지/비디오의 한 프레임을 렌더링합니다.\n * 프레임 갱신은 보통 필요한 때에만 자동적으로 이루어지기 때문에, 보통은 이 메소드를 호출할 필요는 없습니다.\n * 옵션 변경 이후에도 프레임 갱신이 이루어지지 않는다면, 이 메소드를 호출해주세요.\n * @param delta Delta time in milisec. {@ko 프레임간 시간 차이, 밀리초 단위}\n * @since 4.0.0\n */\n public renderFrame = (delta: number) => {\n const camera = this._camera;\n const renderer = this._renderer;\n const control = this._control;\n const hotspot = this._hotspot;\n const autoPlayer = this._autoplay;\n const projection = this._projection;\n\n if (!projection) return;\n\n this._emit(EVENTS.BEFORE_RENDER);\n\n if (autoPlayer.playing) {\n autoPlayer.update(delta);\n control.sync();\n }\n\n if (camera.animation) {\n camera.animation.update(delta);\n } else {\n control.update(delta);\n }\n\n renderer.render(projection, camera);\n hotspot.render(camera);\n\n if (camera.changed) {\n this._emit(EVENTS.VIEW_CHANGE, {\n yaw: camera.yaw,\n pitch: camera.pitch,\n zoom: camera.zoom,\n quaternion: [\n camera.quaternion[0],\n camera.quaternion[1],\n camera.quaternion[2],\n camera.quaternion[3]\n ]\n });\n }\n camera.onFrameRender();\n\n this._emit(EVENTS.RENDER);\n };\n\n private _emit(eventName: K, ...params: EventParams) {\n const evtParams = params ? params[0] : {};\n\n this.trigger(eventName as any, {\n type: eventName,\n target: this,\n ...evtParams\n });\n }\n\n private _renderFrameOnDemand = (delta: number) => {\n const camera = this._camera;\n const control = this._control;\n const autoplay = this._autoplay;\n const texture = this._projection?.getTexture();\n\n if (!this._initialized || !texture) return;\n if (\n !camera.animation\n && !control.animating\n && !autoplay.playing\n && !texture.isVideo()\n ) return;\n\n this.renderFrame(delta);\n };\n\n private _renderVRFrame = (_delta: number, frame: XRFrame) => {\n const vr = this._vr;\n const projection = this._projection;\n const renderer = this._renderer;\n\n if (!projection) return;\n\n this._emit(EVENTS.BEFORE_RENDER);\n\n renderer.renderVR(projection, vr, frame);\n\n this._emit(EVENTS.RENDER);\n }\n\n private _applyProjection(projection: Projection, texture: Texture, prevProjection: Projection | null) {\n const camera = this._camera;\n const control = this._control;\n const renderer = this._renderer;\n\n // Remove previous projection\n if (prevProjection) {\n prevProjection.releaseAllResources(this._renderer.ctx);\n }\n\n projection.applyTexture(renderer.ctx, texture);\n projection.updateCamera(camera);\n projection.updateControl(control);\n\n this._projection = projection;\n this._emit(EVENTS.PROJECTION_CHANGE, {\n projection\n });\n }\n\n private async _loadTexture(projection: Projection): Promise {\n const contentLoader = new TextureLoader();\n const { src, video } = projection;\n\n this._emit(EVENTS.LOAD_START, {\n src,\n video\n });\n\n const texture = await contentLoader.load(src, video);\n\n this._emit(EVENTS.LOAD, {\n src,\n video\n });\n\n return texture;\n }\n\n private _resizeComponents() {\n const renderer = this._renderer;\n const camera = this._camera;\n const control = this._control;\n\n renderer.resize();\n camera.resize(renderer.width, renderer.height);\n control.resize(renderer.width, renderer.height);\n }\n\n private _addEventHandlers(events: View360Options[\"on\"]) {\n // Bind option \"on\"\n Object.keys(events).forEach((evtName: keyof typeof EVENT_TYPES) => {\n this.on(evtName, events[evtName]);\n });\n }\n\n private _bindComponentEvents() {\n // Bind internal component events\n const root = this._rootEl;\n const control = this._control;\n const animator = this._animator;\n const renderer = this._renderer;\n const vr = this._vr;\n\n const controlEventsToPropagate = [\n CONTROL_EVENTS.STATIC_CLICK,\n CONTROL_EVENTS.INPUT_START,\n CONTROL_EVENTS.INPUT_END\n ];\n\n controlEventsToPropagate.forEach(evtName => {\n control.rotate.on(evtName, evt => {\n this._emit(evtName, evt);\n });\n\n control.zoom.on(evtName, evt => {\n this._emit(evtName, evt);\n });\n });\n\n vr.on(EVENTS.VR_START, evt => {\n root.classList.add(DEFAULT_CLASS.IN_VR);\n\n animator.changeContext(evt.session);\n animator.start(this._renderVRFrame);\n\n this._emit(EVENTS.VR_START);\n });\n\n vr.on(EVENTS.VR_END, () => {\n root.classList.remove(DEFAULT_CLASS.IN_VR);\n\n renderer.ctx.useDefaultFrameBuffer();\n animator.changeContext(window);\n animator.start(this._renderFrameOnDemand);\n\n this.resize();\n\n this._emit(EVENTS.VR_END);\n });\n }\n}\n\nexport default View360;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4, quat, vec3 } from \"gl-matrix\";\n\n/**\n * Base class for 3D objects\n * @ko 3D 오브젝트의 베이스 클래스\n * @since 4.0.0\n * @internal\n */\nclass Object3D {\n /**\n * Local matrix of the object\n * @ko 오브젝트의 local matrix\n * @since 4.0.0\n */\n public matrix: mat4;\n /**\n * Rotation quaternion\n * @ko 현재 오브젝트의 회전을 나타내는 사원수 값\n * @since 4.0.0\n */\n public rotation: quat;\n /**\n * Position of the object\n * @ko 오브젝트의 위치\n * @since 4.0.0\n */\n public position: vec3;\n /**\n * A scale vector of the object\n * @ko 오브젝트가 각 축으로 확대된 정도를 나타내는 벡터\n * @since 4.0.0\n */\n public scale: vec3;\n\n /**\n * Create new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n */\n public constructor() {\n this.matrix = mat4.create();\n this.rotation = quat.create();\n this.position = vec3.fromValues(0, 0, 0);\n this.scale = vec3.fromValues(1, 1, 1);\n }\n\n /**\n * Update local matrix of the object.\n * @ko 오브젝트의 local matrix를 갱신합니다.\n * @since 4.0.0\n */\n public updateMatrix() {\n mat4.fromRotationTranslationScale(this.matrix, this.rotation, this.position, this.scale);\n }\n}\n\nexport default Object3D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360Plugin from \"../View360Plugin\";\nimport View360 from \"../../View360\";\nimport { EVENTS } from \"../../const/external\";\nimport { createElement } from \"../../utils\";\nimport { LoadStartEvent } from \"../../type/events\";\n\n/**\n * Options for {@link LoadingSpinner}\n * @ko {@link LoadingSpinner}용 옵션들\n * @since 4.0.0\n * @category Plugin\n */\nexport interface LoadingSpinnerOptions {\n /**\n * Override default class names.\n * @ko 디폴트 클래스 이름들을 오버라이드합니다.\n * @since 4.0.0\n */\n className: Partial<{ -readonly [key in keyof typeof LoadingSpinner.DEFAULT_CLASS]: string }>;\n}\n\n/**\n * A plugin that displays loading spinner while loading the projection.\n * @ko 프로젝션 로딩중에 로딩 스피너를 보여주는 플러그인\n * @since 4.0.0\n * @category Plugin\n */\nclass LoadingSpinner implements View360Plugin {\n /**\n * Default class names that LoadingSpinner uses\n * @ko LoadingSpinner가 사용하는 디폴트 클래스 이름\n * @since 4.0.0\n */\n public static readonly DEFAULT_CLASS = {\n /**\n * A class name for the container element\n * @ko 컨테이너 엘리먼트의 클래스 이름\n * @since 4.0.0\n */\n CONTAINER: \"view360-spinner\",\n /**\n * A class name for the spinning ring element\n * @ko 돌아가는 링 엘리먼트의 클래스 이름\n * @since 4.0.0\n */\n RING: \"view360-spinner-ring\"\n } as const;\n\n /**\n * A class names overriding\n * @ko 현재 오버라이드 중인 클래스 이름\n * @since 4.0.0\n */\n public readonly className: LoadingSpinnerOptions[\"className\"];\n\n private _container: HTMLElement;\n\n /**\n * Create a new instance of LoadingSpinner. {@ko LoadingSpinner의 새 인스턴스를 생성합니다.}\n * @param options Options {@ko 옵션들}\n */\n public constructor({\n className = {}\n }: Partial = {}) {\n this.className = className;\n this._container = this._createElements();\n }\n\n public init(viewer: View360) {\n viewer.on(EVENTS.LOAD_START, this._startLoading);\n }\n\n public destroy(viewer: View360): void {\n viewer.off(EVENTS.LOAD_START, this._startLoading);\n this._detachElements({ target: viewer });\n }\n\n private _startLoading = ({ target: viewer }: LoadStartEvent) => {\n viewer.rootEl.appendChild(this._container);\n\n if (viewer.initialized) {\n viewer.once(EVENTS.LOAD, this._detachElements);\n } else {\n viewer.once(EVENTS.READY, this._detachElements);\n }\n };\n\n private _detachElements = ({ target: viewer }: { target: View360 }) => {\n const container = this._container;\n if (!container) return;\n\n if (container.parentElement === viewer.rootEl) {\n viewer.rootEl.removeChild(container);\n }\n };\n\n private _createElements() {\n const className = {\n ...this.className,\n ...LoadingSpinner.DEFAULT_CLASS\n };\n\n const container = createElement(className.CONTAINER);\n const ring = createElement(className.RING);\n\n container.appendChild(ring);\n\n return container;\n }\n}\n\nexport default LoadingSpinner;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n/* eslint-disable @typescript-eslint/no-empty-function */\n/* eslint-disable @typescript-eslint/no-unused-vars */\nimport ControlBar from \"./ControlBar\";\nimport View360 from \"../../View360\";\n\n/**\n * Common options for {@link ControlBarItem}\n * @ko {@link ControlBarItem}의 공통 옵션들\n * @category Plugin\n * @since 4.0.0\n */\nexport interface ControlBarItemOptions {\n /**\n * @copy ControlBarItem#position\n */\n position: typeof ControlBar.POSITION[keyof typeof ControlBar.POSITION];\n /**\n * @copy ControlBarItem#order\n */\n order: number;\n}\n\n/**\n * Interface of the ControlBar items\n * @ko 컨트롤바 아이템의 인터페이스\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nabstract class ControlBarItem {\n /**\n * Element of the item.\n * @ko 아이템의 엘리먼트\n * @since 4.0.0\n */\n public abstract element: HTMLElement;\n\n /**\n * Position to display item.\n * @ko 아이템을 표시할 위치.\n * @since 4.0.0\n */\n public position: ControlBarItemOptions[\"position\"];\n /**\n * Order within the same position.\n * The lowest one will be shown first.\n * @ko 동일한 position 내에서의 순서, 작을수록 먼저 표시됩니다.\n * @since 4.0.0\n */\n public order: ControlBarItemOptions[\"order\"];\n\n /**\n * Create new instance of the ControlBarItem\n * @ko ControlBarItem의 새로운 인스턴스를 생성합니다.\n * @param options Options {@ko 옵션들}\n */\n public constructor(options: ControlBarItemOptions) {\n this.position = options.position;\n this.order = options.order;\n }\n\n /**\n * Initialize item.\n * @ko 아이템을 초기화합니다.\n * @param viewer - A instance of viewer to attach item {@ko 아이템을 부착할 뷰어의 인스턴스}\n * @param controlBar - A instance of control bar to attach item {@ko 아이템을 부착할 컨트롤바의 인스턴스}\n * @since 4.0.0\n */\n public abstract init(viewer: View360, controlBar: ControlBar): any;\n /**\n * Destroy item and release all resources & event handlers.\n * @ko 아이템을 제거하고 할당된 모든 리소스 및 이벤트 핸들러를 제거합니다.\n * @param viewer - A instance of viewer to detach item {@ko 아이템을 떼어 낼 뷰어의 인스턴스}\n * @param controlBar - A instance of control bar to detach item {@ko 아이템을 떼어 낼 컨트롤바의 인스턴스}\n * @since 4.0.0\n */\n public abstract destroy(viewer: View360, controlBar: ControlBar): any;\n}\n\nexport default ControlBarItem;\n","export const CONTROL_BAR_DEFAULT_CLASS = {\n CONTROLS_ROOT: \"view360-controls\",\n CONTROLS_BG: \"view360-controls-background\",\n CONTROLS_MAIN: \"view360-controls-main\",\n CONTROLS_TOP: \"view360-controls-top\",\n CONTROLS_BOTTOM: \"view360-controls-bottom\",\n CONTROLS_MID: \"view360-controls-mid\",\n CONTROLS_LEFT: \"view360-controls-left\",\n CONTROLS_RIGHT: \"view360-controls-right\",\n CONTROLS_FLOAT_LEFT: \"view360-controls-float-left\",\n CONTROLS_FLOAT_RIGHT: \"view360-controls-float-right\",\n CONTROLS_BUTTON: \"view360-controls-button\",\n PROGRESS_ROOT: \"view360-controls-progress\",\n VOLUME_ROOT: \"view360-controls-volume\",\n RANGE_ROOT: \"view360-range\",\n RANGE_TRACK: \"view360-range-track\",\n RANGE_THUMB: \"view360-range-thumb\",\n RANGE_FILLER: \"view360-range-filler\",\n PLAY_BUTTON: \"view360-controls-play\",\n PAUSE_BUTTON: \"view360-controls-pause\",\n UNMUTED_BUTTON: \"view360-controls-unmuted\",\n MUTED_BUTTON: \"view360-controls-muted\",\n FULLSCREEN_BUTTON: \"view360-controls-fullscreen\",\n FULLSCREEN_EXIT_BUTTON: \"view360-controls-fullscreen-exit\",\n VR_BUTTON: \"view360-controls-vr\",\n GYRO_ENABLED: \"view360-controls-gyro-enabled\",\n GYRO_DISABLED: \"view360-controls-gyro-disabled\",\n VIDEO_TIME_DISPLAY: \"view360-controls-time\",\n PIEVIEW_ROOT: \"view360-controls-pie\",\n FIXED: \"view360-controls-fixed\",\n UNAVAILABLE: \"view360-controls-unavailable\",\n HIDDEN: \"view360-controls-hidden\"\n} as const;\n\nexport const CONTROL_BAR_ITEM_POSITION = {\n /**\n * Place control bar item floating at top-left corner\n * @ko 아이템을 왼쪽 위 구석에 표시합니다.\n * @since 4.0.0\n */\n TOP_LEFT: \"top-left\",\n /**\n * Place control bar item floating at top-right corner\n * @ko 아이템을 오른쪽 위 구석에 표시합니다.\n * @since 4.0.0\n */\n TOP_RIGHT: \"top-right\",\n /**\n * Place control bar item at upper block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 위쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_TOP: \"main-top\",\n /**\n * Place control bar item at lower block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 하단 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_BOTTOM: \"main-bottom\",\n /**\n * Place control bar item at center-left block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 왼쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_LEFT: \"main-left\",\n /**\n * Place control bar item at center-right block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 오른쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_RIGHT: \"main-right\"\n} as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { ControlBarOptions } from \"./ControlBar\";\nimport { CONTROL_BAR_DEFAULT_CLASS } from \"./const\";\nimport Motion from \"../../core/Motion\";\nimport MouseInput from \"../../control/input/MouseInput\";\nimport TouchInput from \"../../control/input/TouchInput\";\nimport { CONTROL_EVENTS, INFINITE_RANGE } from \"../../const/internal\";\nimport { clamp } from \"../../utils\";\nimport { InputEvents } from \"../../type/internal\";\nimport { EL_DIV } from \"../../const/browser\";\n\nclass RangeControl extends Component<{\n [CONTROL_EVENTS.INPUT_START]: number;\n [CONTROL_EVENTS.CHANGE]: number;\n [CONTROL_EVENTS.INPUT_END]: void;\n}> {\n public readonly rootEl: HTMLElement;\n public readonly thumbEl: HTMLElement;\n public readonly trackEl: HTMLElement;\n public readonly fillerEl: HTMLElement;\n\n private _motion: Motion;\n private _mouseInput: MouseInput;\n private _touchInput: TouchInput;\n private _fixedClass: string;\n private _bbox: DOMRect;\n\n /**\n *\n */\n public constructor() {\n super();\n\n const root = document.createElement(EL_DIV);\n const track = document.createElement(EL_DIV);\n const thumb = document.createElement(EL_DIV);\n const filler = document.createElement(EL_DIV);\n\n root.draggable = false;\n\n track.appendChild(filler);\n track.appendChild(thumb);\n root.appendChild(track);\n\n this.rootEl = root;\n this.trackEl = track;\n this.thumbEl = thumb;\n this.fillerEl = filler;\n\n this._mouseInput = new MouseInput();\n this._touchInput = new TouchInput();\n this._motion = new Motion({ duration: 1, range: INFINITE_RANGE, easing: x => x });\n this._bbox = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n left: 0,\n right: 0,\n bottom: 0,\n top: 0\n } as DOMRect;\n this._fixedClass = CONTROL_BAR_DEFAULT_CLASS.FIXED;\n }\n\n public init(className: Required) {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n\n this.rootEl.classList.add(className.RANGE_ROOT);\n this.trackEl.classList.add(className.RANGE_TRACK);\n this.thumbEl.classList.add(className.RANGE_THUMB);\n this.fillerEl.classList.add(className.RANGE_FILLER);\n this._fixedClass = className.FIXED;\n\n mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n touchInput.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n\n mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n touchInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n\n mouseInput.enable(this.rootEl);\n touchInput.enable(this.rootEl);\n\n this.resize();\n }\n\n public destroy() {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n\n this.rootEl.className = \"\";\n this.trackEl.className = \"\";\n this.thumbEl.className = \"\";\n this.fillerEl.className = \"\";\n\n mouseInput.off();\n touchInput.off();\n mouseInput.disable();\n touchInput.disable();\n }\n\n public resize() {\n this._bbox = this.trackEl.getBoundingClientRect();\n }\n\n public updateStyle(progress: number) {\n const width = this._bbox.width;\n const clampedProgress = clamp(progress, 0, 1);\n\n this.fillerEl.style.width = `${clampedProgress * 100}%`;\n this.thumbEl.style.transform = `translateX(${clampedProgress * width}px)`;\n }\n\n private _onHold = ({ srcEvent, isTouch }: InputEvents<{ x: number; y: number }>[typeof CONTROL_EVENTS.INPUT_START]) => {\n const bbox = this._bbox;\n if (!bbox) return;\n\n const x = isTouch\n ? (srcEvent as TouchEvent).touches[0].pageX\n : (srcEvent as MouseEvent).pageX;\n const elX = bbox.x + (window.scrollX ?? window.pageXOffset);\n\n const clamepdX = clamp(x, elX, elX + bbox.width);\n const progress = (clamepdX - elX) / bbox.width;\n\n this._motion.reset(clamepdX);\n this.thumbEl.classList.add(this._fixedClass);\n\n this.trigger(CONTROL_EVENTS.INPUT_START, progress);\n };\n\n private _onChange = ({ delta }: InputEvents<{ x: number; y: number }>[typeof CONTROL_EVENTS.CHANGE]) => {\n const motion = this._motion;\n const bbox = this._bbox;\n if (!bbox) return;\n\n motion.setNewEndByDelta(delta.x);\n motion.update(1);\n\n const elX = bbox.x + (window.scrollX ?? window.pageXOffset);\n const clampedX = clamp(motion.val, elX, elX + bbox.width);\n const progress = (clampedX - elX) / bbox.width;\n\n this.trigger(CONTROL_EVENTS.CHANGE, progress);\n };\n\n private _onRelease = () => {\n const bbox = this._bbox;\n if (!bbox) return;\n\n this.thumbEl.classList.remove(this._fixedClass);\n\n this.trigger(CONTROL_EVENTS.INPUT_END);\n };\n}\n\nexport default RangeControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport RangeControl from \"./RangeControl\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport { CONTROL_EVENTS, VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport { EVENTS } from \"../../const/external\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show video progress bar.\n * @ko 비디오의 프로그레스 바를 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass ProgressBar extends ControlBarItem {\n public get element() { return this._rangeControl.rootEl; }\n\n private _controlBar: ControlBar | null;\n private _video: TextureVideo | null;\n private _rangeControl: RangeControl;\n\n private _wasPaused: boolean;\n private _currentTime: number;\n private _duration: number;\n private _playPromise: Promise | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_TOP,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.position = position;\n this.order = order;\n\n this._controlBar = null;\n this._rangeControl = new RangeControl();\n\n this._video = null;\n this._wasPaused = false;\n this._currentTime = 0;\n this._duration = 0;\n this._playPromise = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const element = this.element;\n const rangeControl = this._rangeControl;\n const unavailableClass = controlBar.className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n element.classList.add(unavailableClass);\n return;\n }\n\n element.classList.remove(unavailableClass);\n element.classList.add(controlBar.className.PROGRESS_ROOT);\n viewer.on(EVENTS.RESIZE, this._onResize);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate);\n rangeControl.init(controlBar.className);\n rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n rangeControl.on(CONTROL_EVENTS.CHANGE, this._onControl);\n rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n this._video = video;\n this._currentTime = video.source.currentTime;\n this._duration = video.source.duration;\n this._controlBar = controlBar;\n\n rangeControl.updateStyle(this._currentTime / this._duration);\n }\n\n public destroy(viewer: View360) {\n const video = this._video;\n\n viewer.off(EVENTS.RESIZE, this._onResize);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate);\n }\n\n this._rangeControl.destroy();\n this._video = null;\n this._playPromise = null;\n }\n\n private _onResize = () => {\n this._rangeControl.resize();\n }\n\n private _onTimeUpdate = () => {\n const video = this._video;\n if (!video) return;\n\n this._currentTime = video.source.currentTime;\n this._rangeControl.updateStyle(this._currentTime / this._duration);\n };\n\n private _onDurationChange = () => {\n const video = this._video;\n if (!video) return;\n\n this._duration = video.source.duration;\n this._rangeControl.updateStyle(this._currentTime / this._duration);\n };\n\n private _onHold = (progress: number) => {\n const video = this._video;\n const controlBar = this._controlBar;\n if (!video || !controlBar) return;\n\n const paused = video.isPaused();\n\n video.source.pause();\n\n const time = video.source.duration * progress;\n video.source.currentTime = time;\n video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time }}));\n\n controlBar.rootEl.classList.add(controlBar.className.FIXED);\n this._wasPaused = !this._playPromise && paused;\n };\n\n private _onControl = (progress: number) => {\n const video = this._video;\n if (!video) return;\n\n const time = video.source.duration * progress;\n video.source.currentTime = time;\n video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time }}));\n };\n\n private _onRelease = () => {\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (video && controlBar) {\n if (!this._wasPaused && !this._playPromise) {\n this._playPromise = video.source.play()\n .catch(() => void 0);\n\n // This should not be chained\n this._playPromise.then(() => {\n this._playPromise = null;\n });\n\n controlBar.rootEl.classList.remove(controlBar.className.FIXED);\n }\n }\n\n this._wasPaused = false;\n };\n}\n\nexport default ProgressBar;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show video play / pause button.\n * @ko 비디오 재생 / 일시정지 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass PlayButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _controlBar: ControlBar | null;\n private _video: TextureVideo | null;\n private _paused: boolean;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n\n this._video = null;\n this._paused = true;\n this._controlBar = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const video = viewer.projection?.getTexture();\n const className = controlBar.className;\n const unavailableClass = className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n element.classList.add(unavailableClass);\n return;\n }\n\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.remove(unavailableClass);\n\n const paused = video.isPaused();\n this._video = video;\n this._paused = paused;\n this._controlBar = controlBar;\n\n if (paused) {\n this._onPause();\n } else {\n this._onPlay();\n }\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onPlay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onPause);\n }\n\n public destroy() {\n const video = this._video;\n const element = this.element;\n\n if (!video) return;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onPlay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onPause);\n\n this._video = null;\n this._paused = true;\n this._controlBar = null;\n }\n\n private _onClick = () => {\n const video = this._video;\n if (!video) return;\n\n if (this._paused) {\n video.source.play();\n } else {\n video.source.pause();\n }\n };\n\n private _onPlay = () => {\n if (!this._controlBar) return;\n\n const element = this.element;\n const className = this._controlBar.className;\n\n element.classList.add(className.PAUSE_BUTTON);\n element.classList.remove(className.PLAY_BUTTON);\n element.title = \"Pause Video\";\n\n this._paused = false;\n };\n\n private _onPause = () => {\n if (!this._controlBar) return;\n\n const element = this.element;\n const className = this._controlBar.className;\n\n element.classList.add(className.PLAY_BUTTON);\n element.classList.remove(className.PAUSE_BUTTON);\n element.title = \"Play Video\";\n\n this._paused = true;\n };\n}\n\nexport default PlayButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport RangeControl from \"./RangeControl\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { EVENTS } from \"../../const/external\";\n\n/**\n * Show video volume control.\n * @ko 비디오 볼륨 조절 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VolumeControl extends ControlBarItem {\n public get element() { return this._rootEl; }\n\n private _controlBar: ControlBar | null;\n private _rootEl: HTMLButtonElement;\n private _buttonEl: HTMLElement;\n private _rangeControl: RangeControl;\n private _video: TextureVideo | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this._controlBar = null;\n this._rangeControl = new RangeControl();\n this._createElements();\n\n this._video = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const root = this._rootEl;\n const button = this._buttonEl;\n const rangeControl = this._rangeControl;\n const className = controlBar.className;\n const unavailableClass = className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n root.classList.add(unavailableClass);\n return;\n }\n\n root.classList.remove(unavailableClass);\n root.classList.add(className.CONTROLS_BUTTON);\n root.classList.add(className.VOLUME_ROOT);\n button.classList.add(className.CONTROLS_BUTTON);\n\n if (video.source.muted) {\n button.classList.add(className.MUTED_BUTTON);\n } else {\n button.classList.add(className.UNMUTED_BUTTON);\n }\n\n viewer.on(EVENTS.RESIZE, this._onResize);\n root.addEventListener(BROWSER.EVENTS.TRANSITION_END, this._onResize);\n button.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_VOLUME_CHANGE, this._onVolumeChange);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_LOADED_DATA, this._updateDisplay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay);\n\n rangeControl.init(className);\n rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n rangeControl.on(CONTROL_EVENTS.CHANGE, this._onChange);\n rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n this._controlBar = controlBar;\n this._video = video;\n\n this._updateDisplay();\n }\n\n public destroy(viewer: View360) {\n const video = this._video;\n const button = this._buttonEl;\n const root = this._rootEl;\n\n root.className = \"\";\n button.className = \"\";\n\n viewer.off(EVENTS.RESIZE, this._onResize);\n root.removeEventListener(BROWSER.EVENTS.TRANSITION_END, this._onResize);\n button.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_VOLUME_CHANGE, this._onVolumeChange);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_LOADED_DATA, this._updateDisplay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay);\n }\n\n this._controlBar = null;\n this._rangeControl.destroy();\n this._video = null;\n }\n\n private _onResize = () => {\n this._rangeControl.resize();\n this._updateDisplay();\n }\n\n private _onClick = () => {\n const video = this._video;\n if (!video || this._rootEl.disabled) return;\n\n video.source.muted = !video.source.muted;\n };\n\n private _onVolumeChange = () => {\n const button = this._buttonEl;\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (!video || !controlBar) return;\n\n const className = controlBar.className;\n\n if (video.source.muted || video.source.volume === 0) {\n button.classList.add(className.MUTED_BUTTON);\n button.classList.remove(className.UNMUTED_BUTTON);\n } else {\n button.classList.add(className.UNMUTED_BUTTON);\n button.classList.remove(className.MUTED_BUTTON);\n }\n\n this._updateDisplay();\n };\n\n private _createElements() {\n const root = document.createElement(BROWSER.EL_BUTTON);\n const buttonEl = document.createElement(BROWSER.EL_DIV);\n\n root.appendChild(this._rangeControl.rootEl);\n root.appendChild(buttonEl);\n root.title = \"Toggle Mute\";\n\n this._rootEl = root;\n this._buttonEl = buttonEl;\n }\n\n private _onHold = (progress: number) => {\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (!video || !controlBar) return;\n\n const className = controlBar.className;\n\n video.source.volume = progress;\n\n this._rootEl.classList.add(className.FIXED);\n controlBar.containerEl.classList.add(className.FIXED);\n\n this._updateDisplay();\n };\n\n private _onChange = (progress: number) => {\n const video = this._video;\n if (!video) return;\n\n video.source.volume = progress;\n if (progress > 0) {\n video.source.muted = false;\n } else {\n video.source.muted = true;\n }\n\n this._updateDisplay();\n };\n\n private _onRelease = () => {\n const controlBar = this._controlBar;\n if (!controlBar) return;\n\n const className = controlBar.className;\n\n this._rootEl.classList.remove(className.FIXED);\n controlBar.containerEl.classList.remove(className.FIXED);\n };\n\n private _updateDisplay = () => {\n const video = this._video;\n const root = this._rootEl;\n if (!video) return;\n\n if (!video.hasAudio()) {\n root.disabled = true;\n return;\n }\n\n root.disabled = false;\n\n const volume = video.source.muted ? 0 : video.source.volume;\n\n this._rangeControl.updateStyle(volume);\n };\n}\n\nexport default VolumeControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport { isFullscreen } from \"../../utils\";\n\n/**\n * Show fullscreen enter / exit button.\n * @ko 풀스크린 진입 / 해제 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass FullscreenButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _controlBar: ControlBar | null;\n private _targetEl: HTMLElement | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n this.element.title = \"Toggle Fullscreen\";\n this._controlBar = null;\n this._targetEl = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n if (!this._fullscreenAvailable()) {\n element.classList.add(className.UNAVAILABLE);\n return;\n }\n\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.remove(className.UNAVAILABLE);\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._addFullscreenHandlers();\n\n if (isFullscreen()) {\n element.classList.add(className.FULLSCREEN_EXIT_BUTTON);\n } else {\n element.classList.add(className.FULLSCREEN_BUTTON);\n }\n\n this._controlBar = controlBar;\n this._targetEl = viewer.rootEl;\n }\n\n public destroy() {\n const element = this.element;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._removeFullscreenHandlers();\n\n this._controlBar = null;\n this._targetEl = null;\n }\n\n private _onClick = () => {\n const target = this._targetEl;\n if (!target) return;\n\n if (isFullscreen()) {\n this._exitFullscreen();\n } else {\n this._requestFullscreen(target);\n }\n };\n\n private _fullscreenAvailable() {\n return BROWSER.FULLSCREEN_REQUEST.some(key => !!document[key]);\n }\n\n private _requestFullscreen(el: HTMLElement) {\n for (const key of BROWSER.FULLSCREEN_REQUEST) {\n const request = el[key];\n if (request) {\n request.call(el);\n return;\n }\n }\n }\n\n private _exitFullscreen() {\n for (const key of BROWSER.FULLSCREEN_EXIT) {\n const exit = document[key];\n\n if (exit) {\n exit.call(document);\n return;\n }\n }\n }\n\n private _addFullscreenHandlers() {\n BROWSER.FULLSCREEN_CHANGE.forEach(evtName => {\n document.addEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _removeFullscreenHandlers() {\n BROWSER.FULLSCREEN_CHANGE.forEach(evtName => {\n document.removeEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _onFullscreenChange = () => {\n const element = this.element;\n const controlBar = this._controlBar;\n\n if (!controlBar) return;\n\n const className = controlBar.className;\n\n if (isFullscreen()) {\n element.classList.add(className.FULLSCREEN_EXIT_BUTTON);\n element.classList.remove(className.FULLSCREEN_BUTTON);\n } else {\n element.classList.add(className.FULLSCREEN_BUTTON);\n element.classList.remove(className.FULLSCREEN_EXIT_BUTTON);\n }\n };\n}\n\nexport default FullscreenButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\n\n/**\n * Show video current / total time.\n * @ko 비디오의 현재 / 총 재생시간을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VideoTime extends ControlBarItem {\n public readonly element: HTMLElement;\n private _video: TextureVideo | null;\n private _currentTime: number;\n private _duration: number;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n\n this._video = null;\n this._currentTime = 0;\n this._duration = 0;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const element = this.element;\n const className = controlBar.className;\n\n if (!video || !video.isVideo()) {\n element.classList.add(className.UNAVAILABLE);\n return;\n }\n\n element.classList.add(className.VIDEO_TIME_DISPLAY);\n element.classList.remove(className.UNAVAILABLE);\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange);\n\n this._video = video;\n this._currentTime = video.source.currentTime;\n this._duration = video.source.duration;\n\n this._updateDisplay();\n }\n\n public destroy() {\n const video = this._video;\n\n if (!video) return;\n\n this.element.className = \"\";\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange);\n\n this._video = null;\n }\n\n private _onTimeUpdate = () => {\n const video = this._video;\n if (!video) return;\n\n this._currentTime = video.source.currentTime;\n this._updateDisplay();\n };\n\n private _onDurationChange = () => {\n const video = this._video;\n if (!video) return;\n\n this._duration = video.source.duration;\n this._updateDisplay();\n };\n\n private _onCustomTimeChange = (evt: CustomEvent<{ time: number }>) => {\n this._currentTime = evt.detail.time;\n this._updateDisplay();\n };\n\n private _updateDisplay() {\n const time = this._currentTime;\n const timeMinute = Math.floor(time / 60);\n const timeSeconds = Math.floor(time - timeMinute * 60);\n const timeSecondsFormatted = timeSeconds < 10 ? `0${timeSeconds}` : timeSeconds;\n\n const duration = this._duration;\n const durationMinute = Math.floor(duration / 60);\n const durationSeconds = Math.floor(duration - durationMinute * 60);\n const durationSecondsFormatted = durationSeconds < 10 ? `0${durationSeconds}` : durationSeconds;\n\n this.element.innerText = `${timeMinute}:${timeSecondsFormatted} / ${durationMinute}:${durationSecondsFormatted}`;\n }\n}\n\nexport default VideoTime;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport { circulate, getObjectOption } from \"../../utils\";\nimport * as BROWSER from \"../../const/browser\";\nimport { EVENTS } from \"../../const/external\";\nimport { SVG_NAMESPACE } from \"../../const/internal\";\n\n/**\n * Options for {@link PieView}\n * @ko {@link PieView}용 옵션들\n * @category Plugin\n */\nexport interface PieViewOptions extends ControlBarItemOptions {\n /**\n * @copy PieView#resetCamera\n */\n resetCamera: boolean | Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n duration: number;\n easing: (x: number) => number;\n }>;\n}\n\n/**\n * Show camera direction/fov indicator.\n * @ko 카메라가 향하는 방향 및 FOV를 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass PieView extends ControlBarItem {\n public readonly element: HTMLElement;\n\n /**\n * Set rotation to reset camera to when PieView is clicked.\n * `false` will disable this value, and `true` will enable with default options.\n * @ko PieView가 클릭되었을 때 카메라를 리셋할 방향을 지정합니다.\n * `false`일 경우 이 동작을 비활성화하며, `true`일 경우 기본값을 사용합니다.\n * @since 4.0.0\n */\n public resetCamera: PieViewOptions[\"resetCamera\"];\n\n private _viewer: View360 | null;\n private _piePathEl: SVGPathElement;\n private _rangeCircleEl: SVGCircleElement;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n resetCamera = true,\n position = CONTROL_BAR_ITEM_POSITION.TOP_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n this.element.title = \"Reset view\";\n this.resetCamera = resetCamera;\n this._createPieElements();\n this._viewer = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n\n if (!viewer.initialized) {\n viewer.once(EVENTS.READY, this._updatePie);\n } else {\n this._updatePie({ target: viewer });\n }\n\n const rootClass = controlBar.className.PIEVIEW_ROOT;\n element.classList.add(rootClass);\n\n if (this.resetCamera) {\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n }\n\n viewer.on(EVENTS.VIEW_CHANGE, this._updatePie);\n\n this._viewer = viewer;\n }\n\n public destroy(viewer: View360) {\n const element = this.element;\n\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.className = \"\";\n viewer.off(EVENTS.READY, this._updatePie);\n viewer.off(EVENTS.VIEW_CHANGE, this._updatePie);\n\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n const resetCamera = this.resetCamera;\n\n if (!viewer || !resetCamera) return;\n\n const {\n yaw = viewer.initialYaw,\n pitch = viewer.initialPitch,\n zoom = viewer.initialZoom,\n duration = 500\n } = getObjectOption(resetCamera);\n\n viewer.camera.animateTo({\n yaw,\n pitch,\n zoom,\n duration\n });\n };\n\n private _createPieElements() {\n const root = this.element;\n const pieSVG = document.createElementNS(SVG_NAMESPACE, \"svg\");\n pieSVG.setAttribute(\"viewBox\", \"0 0 48 48\");\n pieSVG.setAttribute(\"width\", \"100%\");\n pieSVG.setAttribute(\"height\", \"100%\");\n\n const piePath = document.createElementNS(SVG_NAMESPACE, \"circle\");\n\n piePath.setAttribute(\"stroke\", \"currentColor\");\n piePath.setAttribute(\"fill\", \"transparent\");\n piePath.setAttribute(\"cx\", \"24\");\n piePath.setAttribute(\"cy\", \"24\");\n piePath.setAttribute(\"r\", \"12\");\n piePath.setAttribute(\"stroke-width\", \"24\");\n pieSVG.appendChild(piePath);\n\n const rangeCircle = document.createElementNS(SVG_NAMESPACE, \"circle\");\n\n rangeCircle.setAttribute(\"stroke\", \"currentColor\");\n rangeCircle.setAttribute(\"fill\", \"transparent\");\n rangeCircle.setAttribute(\"cx\", \"24\");\n rangeCircle.setAttribute(\"cy\", \"24\");\n rangeCircle.setAttribute(\"r\", \"22.5\");\n rangeCircle.setAttribute(\"stroke-width\", \"3\");\n pieSVG.appendChild(rangeCircle);\n\n root.appendChild(pieSVG);\n\n this._piePathEl = piePath;\n this._rangeCircleEl = rangeCircle;\n }\n\n private _updatePie = ({ target: viewer }: { target: View360 }) => {\n const piePath = this._piePathEl;\n const rangeCircle = this._rangeCircleEl;\n const camera = viewer.camera;\n const fov = camera.getHorizontalFov();\n const yawRange = camera.getYawRange(camera.zoom);\n const halfFov = fov * 0.5;\n\n const pieRadius = 24 * Math.PI;\n const pieDeg = pieRadius * fov / 360;\n const pieOffset = pieRadius * (camera.yaw + halfFov + 90) / 360;\n\n piePath.setAttribute(\"stroke-dasharray\", `${pieDeg} ${pieRadius - pieDeg}`);\n piePath.setAttribute(\"stroke-dashoffset\", `${pieOffset}`);\n\n if (isFinite(yawRange.min) && isFinite(yawRange.max)) {\n const radius = 45 * Math.PI; // 2 * PI * r\n const min = (circulate(yawRange.min, -180, 180) - halfFov) / 360;\n const max = (circulate(yawRange.max, -180, 180) + halfFov) / 360;\n\n const rangeDiff = radius * Math.abs(max - min);\n const offset = -radius * (min - 0.25);\n\n rangeCircle.setAttribute(\"stroke-dasharray\", `${rangeDiff} ${radius - rangeDiff}`);\n rangeCircle.setAttribute(\"stroke-dashoffset\", `${offset}`);\n } else {\n rangeCircle.setAttribute(\"stroke-dasharray\", \"\");\n rangeCircle.setAttribute(\"stroke-dashoffset\", \"\");\n }\n };\n}\n\nexport default PieView;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show VR enter button.\n * @ko VR 진입 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VRButton extends ControlBarItem {\n public readonly element: HTMLElement;\n\n private _viewer: View360 | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n this.element.title = \"Enter VR\";\n this._viewer = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n element.classList.add(className.UNAVAILABLE);\n element.classList.add(className.VR_BUTTON);\n element.classList.add(className.CONTROLS_BUTTON);\n\n viewer.vr.isAvailable()\n .then(available => {\n if (available) {\n element.classList.remove(className.UNAVAILABLE);\n }\n });\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._viewer = viewer;\n }\n\n public destroy() {\n const element = this.element;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n if (!viewer) return;\n\n viewer.vr.enter();\n };\n}\n\nexport default VRButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport GyroControl from \"../../control/GyroControl\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { sensorCanBeEnabledIOS } from \"../../utils\";\n\n/**\n * Show gyroscope control enable / disable button\n * @ko 자이로스코프 컨트롤 활성화 / 비활성화 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass GyroButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _viewer: View360 | null;\n private _controlBar: ControlBar | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n this.element.title = \"Toggle gyroscope control\";\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.add(className.UNAVAILABLE);\n\n const enableButton = () => {\n element.classList.remove(className.UNAVAILABLE);\n viewer.control.gyro.on(CONTROL_EVENTS.ENABLE, this._updateStyle);\n viewer.control.gyro.on(CONTROL_EVENTS.DISABLE, this._updateStyle);\n };\n\n if (sensorCanBeEnabledIOS()) {\n enableButton();\n } else {\n GyroControl.isAvailable().then(available => {\n if (!available) return;\n enableButton();\n });\n }\n\n this._controlBar = controlBar;\n this._viewer = viewer;\n this._updateStyle();\n }\n\n public destroy(viewer: View360) {\n const element = this.element;\n\n viewer.control.gyro.off(CONTROL_EVENTS.ENABLE, this._updateStyle);\n viewer.control.gyro.off(CONTROL_EVENTS.DISABLE, this._updateStyle);\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.className = \"\";\n\n this._controlBar = null;\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n const controlBar = this._controlBar;\n\n if (!viewer || !controlBar) return;\n\n const gyroControl = viewer.control.gyro;\n if (gyroControl.enabled) {\n gyroControl.disable();\n } else {\n GyroControl.requestSensorPermission().then(available => {\n if (available) {\n gyroControl.enable();\n } else {\n this.element.classList.add(controlBar.className.UNAVAILABLE);\n }\n });\n }\n };\n\n private _updateStyle = () => {\n const element = this.element;\n const viewer = this._viewer;\n const controlBar = this._controlBar;\n\n if (!viewer || !controlBar) return;\n\n const gyroControl = viewer.control.gyro;\n const className = controlBar.className;\n\n if (gyroControl.enabled) {\n element.classList.add(className.GYRO_ENABLED);\n element.classList.remove(className.GYRO_DISABLED);\n } else {\n element.classList.add(className.GYRO_DISABLED);\n element.classList.remove(className.GYRO_ENABLED);\n }\n };\n}\n\nexport default GyroButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport { FULLSCREEN_CHANGE } from \"../../const/browser\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport { isFullscreen } from \"../../utils\";\n\n/**\n * Options for ControlBar's {@link ControlBarOptions#autoHide}\n * @ko ControlBar의 {@link ControlBarOptions#autoHide}용 옵션\n * @category Plugin\n * @since 4.0.0\n */\nexport interface AutoHideOptions {\n /**\n * Initial delay before the control bar hides (ms)\n * @ko 컨트롤바가 처음으로 표시되고 사라지기까지 걸리는 시간 (ms)\n * @default 3000\n * @since 4.0.0\n */\n initialDelay: number;\n /**\n * Delay time before hiding the control bar after mouse leave (ms)\n * @ko 마우스가 컨트롤바 영역을 떠난 뒤 컨트롤바가 사라지기까지 걸리는 시간 (ms)\n * @default 0\n * @since 4.0.0\n */\n delay: number;\n /**\n * Delay time before hiding the control bar becomes active, like touch on mobile device or mouse move in fullscreen mode (ms)\n * @ko 모바일이나 풀스크린 환경 등에서 사용자 입력이 없을 때 컨트롤바가 사라지기까지 걸리는 시간 (ms)\n * @default 3000\n * @since 4.0.0\n */\n idleDelay: number;\n}\n\nclass AutoHide {\n private _initialDelay: AutoHideOptions[\"initialDelay\"];\n private _delay: AutoHideOptions[\"delay\"];\n private _idleDelay: AutoHideOptions[\"idleDelay\"];\n\n private _controlBar: ControlBar;\n private _timer: number;\n private _isGrabbing: boolean;\n private _isCursorInside: boolean;\n private _isFullscreen: boolean;\n private _targetEl: HTMLElement | null;\n private _video: TextureVideo | null;\n\n public get enabled() { return !!this._targetEl; }\n public get hidden() { return this._controlBar.containerEl.classList.contains(this._hiddenClass); }\n\n private get _hiddenClass() { return this._controlBar.className.HIDDEN; }\n private get _fixedClass() { return this._controlBar.className.FIXED; }\n\n public constructor(controlBar: ControlBar, {\n initialDelay = 3000,\n delay = 0,\n idleDelay: activationDelay = 3000\n }: Partial) {\n this._controlBar = controlBar;\n this._initialDelay = initialDelay;\n this._delay = delay;\n this._idleDelay = activationDelay;\n this._timer = -1;\n this._isCursorInside = false;\n this._isGrabbing = false;\n this._isFullscreen = false;\n this._video = null;\n this._targetEl = null;\n }\n\n public enable(viewer: View360) {\n if (this._targetEl) {\n this.disable(viewer);\n }\n\n const initialDelay = this._initialDelay;\n const root = viewer.rootEl;\n\n this._targetEl = viewer.rootEl;\n this._timer = window.setTimeout(() => {\n this.hide();\n }, initialDelay);\n\n root.addEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onHold);\n root.addEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter);\n root.addEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove);\n root.addEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave);\n this._addFullscreenHandlers();\n\n const video = viewer.projection?.getTexture();\n if (!video || !video.isVideo()) {\n return;\n }\n\n if (video.isPaused()) {\n this._controlBar.containerEl.classList.add(this._fixedClass);\n }\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onVideoPlay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onVideoPause);\n\n this._video = video;\n }\n\n public disable(viewer: View360) {\n if (!this._targetEl) return;\n\n const controlBar = this._controlBar;\n const root = viewer.rootEl;\n const video = this._video;\n\n root.removeEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onHold);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave);\n this._removeFullscreenHandlers();\n\n window.clearTimeout(this._timer);\n controlBar.containerEl.classList.remove(this._fixedClass);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onVideoPlay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onVideoPause);\n }\n\n this._isCursorInside = false;\n this._isGrabbing = false;\n this._video = null;\n this._targetEl = null;\n }\n\n public show() {\n this._clearHideTimer();\n this._controlBar.containerEl.classList.remove(this._hiddenClass);\n }\n\n public showTemporaliy() {\n this.show();\n this._hideAfterDelay(this._idleDelay);\n }\n\n public hide() {\n this._clearHideTimer();\n this._controlBar.containerEl.classList.add(this._hiddenClass);\n }\n\n private _clearHideTimer() {\n if (this._timer) {\n window.clearTimeout(this._timer);\n this._timer = -1;\n }\n }\n\n private _hideAfterDelay(delay = this._delay) {\n if (this._isGrabbing || (!this._isFullscreen && this._isCursorInside)) return;\n\n this._clearHideTimer();\n if (delay <= 0) {\n this.hide();\n } else {\n this._timer = window.setTimeout(() => {\n this.hide();\n }, delay);\n }\n }\n\n private _onMouseEnter = () => {\n this._isCursorInside = true;\n this.show();\n };\n\n private _onMouseLeave = () => {\n this._isCursorInside = false;\n this._hideAfterDelay();\n };\n\n private _onMouseMove = () => {\n if (!this._isFullscreen) return;\n\n this.showTemporaliy();\n }\n\n private _onHold = (evt: PointerEvent) => {\n this._isGrabbing = true;\n\n if (evt.pointerType === \"mouse\") {\n this._isCursorInside = true;\n }\n\n window.addEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n\n this.show();\n };\n\n private _onRelease = () => {\n this._isGrabbing = false;\n\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n\n this._hideAfterDelay();\n };\n\n private _onVideoPlay = () => {\n const root = this._targetEl;\n if (!root) return;\n\n this._controlBar.containerEl.classList.remove(this._fixedClass);\n };\n\n private _onVideoPause = () => {\n const root = this._targetEl;\n if (!root) return;\n\n this._controlBar.containerEl.classList.add(this._fixedClass);\n };\n\n private _addFullscreenHandlers() {\n FULLSCREEN_CHANGE.forEach(evtName => {\n document.addEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _removeFullscreenHandlers() {\n FULLSCREEN_CHANGE.forEach(evtName => {\n document.removeEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _onFullscreenChange = () => {\n this._isFullscreen = isFullscreen();\n\n if (this._isFullscreen) {\n this._hideAfterDelay();\n }\n };\n}\n\nexport default AutoHide;\n","import TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { clamp } from \"../../utils\";\nimport { VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\n\nclass VideoControl {\n private _video: TextureVideo | null;\n\n public enable(root: HTMLElement, video: TextureVideo) {\n this._video = video;\n // capture is needed for resolving conflict with keyboard control\n root.addEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown, true);\n }\n\n public disable(root: HTMLElement) {\n this._video = null;\n root.removeEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown, true);\n }\n\n private _onKeyDown = (event: KeyboardEvent) => {\n const video = this._video;\n if (!video) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n const videoEl = video.source;\n const keyPressed = event.keyCode != null\n ? BROWSER.DIRECTION_KEY_CODE[event.keyCode]\n : BROWSER.DIRECTION_KEY_NAME[event.key];\n\n switch (keyPressed) {\n case \"LEFT\":\n case \"RIGHT\":\n return this._changeVideoTime(videoEl, keyPressed === \"RIGHT\");\n case \"UP\":\n case \"DOWN\":\n return this._changeVideoVolume(videoEl, keyPressed === \"UP\");\n }\n\n const spacePressed = event.keyCode === BROWSER.SPACE_KEY_CODE || event.key === BROWSER.SPACE_KEY_NAME;\n if (spacePressed) {\n this._toggleVideo(video);\n }\n }\n\n private _changeVideoTime(video: HTMLVideoElement, forward: boolean) {\n const delta = forward ? 5 : -5;\n\n video.currentTime += delta;\n video.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time: video.currentTime }}));\n }\n\n private _changeVideoVolume(video: HTMLVideoElement, increase: boolean) {\n const delta = increase ? 0.1 : -0.1;\n\n if (video.muted) {\n video.volume = clamp(delta, 0, 1);\n } else {\n video.volume = clamp(video.volume + delta, 0, 1);\n }\n\n if (video.volume > 0) {\n video.muted = false;\n } else {\n video.muted = true;\n }\n }\n\n private _toggleVideo(video: TextureVideo) {\n if (video.isPaused()) {\n video.source.play();\n } else {\n video.source.pause();\n }\n }\n}\n\nexport default VideoControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport ProgressBar from \"./ProgressBar\";\nimport PlayButton from \"./PlayButton\";\nimport VolumeControl from \"./VolumeControl\";\nimport FullscreenButton from \"./FullscreenButton\";\nimport VideoTime from \"./VideoTime\";\nimport PieView, { PieViewOptions } from \"./PieView\";\nimport VRButton from \"./VRButton\";\nimport GyroButton from \"./GyroButton\";\nimport AutoHide, { AutoHideOptions } from \"./AutoHide\";\nimport VideoControl from \"./VideoControl\";\nimport View360, { View360Events } from \"../../View360\";\nimport View360Plugin from \"../View360Plugin\";\nimport { EVENTS } from \"../../const/external\";\nimport { createElement, findIndex, getObjectOption } from \"../../utils\";\nimport { ValueOf } from \"../../type/utils\";\nimport { StaticClickEvent } from \"../../type/events\";\nimport { CONTROL_BAR_DEFAULT_CLASS, CONTROL_BAR_ITEM_POSITION } from \"./const\";\n\n/**\n * Options for {@link ControlBar}\n * @ko {@link ControlBar}용 옵션들\n * @category Plugin\n * @since 4.0.0\n */\nexport interface ControlBarOptions {\n /**\n * @copy ControlBar#autoHide\n */\n autoHide: boolean | Partial;\n /**\n * @copy ControlBar#showBackground\n */\n showBackground: boolean;\n /**\n * @copy ControlBar#clickToPlay\n */\n clickToPlay: boolean;\n /**\n * @copy ControlBar#keyboardControls\n */\n keyboardControls: boolean;\n /**\n * @copy ControlBar#progressBar\n */\n progressBar: boolean | Partial;\n /**\n * @copy ControlBar#playButton\n */\n playButton: boolean | Partial;\n /**\n * @copy ControlBar#volumeButton\n */\n volumeButton: boolean | Partial;\n /**\n * @copy ControlBar#fullscreenButton\n */\n fullscreenButton: boolean | Partial;\n /**\n * @copy ControlBar#videoTime\n */\n videoTime: boolean | Partial;\n /**\n * @copy ControlBar#pieView\n */\n pieView: boolean | Partial;\n /**\n * @copy ControlBar#vrButton\n */\n vrButton: boolean | Partial;\n /**\n * @copy ControlBar#gyroButton\n */\n gyroButton: boolean | Partial;\n /**\n * @copy ControlBar#className\n */\n className: Partial<{ -readonly [key in keyof typeof ControlBar.DEFAULT_CLASS]: string }>;\n /**\n * @copy ControlBar#customItems\n */\n customItems: ControlBarItem[];\n}\n\n/**\n * A plugin that displays extra buttons & controls that controls {@link View360}.\n * @ko {@link View360}에 부가적인 버튼과 컨트롤을 추가해주는 플러그인.\n * @category Plugin\n * @since 4.0.0\n */\nclass ControlBar implements View360Plugin {\n /**\n * Default class names that ControlBar uses\n * @ko ControlBar가 사용하는 디폴트 클래스 이름들\n * @since 4.0.0\n */\n public static readonly DEFAULT_CLASS = CONTROL_BAR_DEFAULT_CLASS;\n\n /**\n * Constants for {@link ControlBarItemOptions#position}\n * @ko {@link ControlBarItemOptions#position}에 사용 가능한 값들\n */\n public static readonly POSITION = CONTROL_BAR_ITEM_POSITION;\n\n /**\n * Automatically hide control bar on video plays.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 재생시 자동으로 컨트롤바를 숨깁니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly autoHide?: ControlBarOptions[\"autoHide\"];\n /**\n * Show background element.\n * @ko 배경 엘리먼트를 표시합니다.\n * @since 4.0.0\n */\n public readonly showBackground?: ControlBarOptions[\"showBackground\"];\n /**\n * Whether to play / pause video on canvas click\n * @ko 캔버스 클릭시에 비디오를 재생 / 일시정지 토글합니다.\n * @since 4.0.0\n */\n public readonly clickToPlay: ControlBarOptions[\"clickToPlay\"];\n /**\n * Enable keyboard controls for video.\n * Pressing up / down arrow will control video volume, and pressing left / right arrow will control video time.\n * @ko 비디오 키보드 컨트롤을 활성화합니다.\n * 위 / 아래 화살표키를 누를 시 비디오 볼륨을, 왼쪽 / 오른쪽 화살표키를 누를 시 비디오 시간을 조정합니다.\n * @since 4.0.0\n */\n public readonly keyboardControls: ControlBarOptions[\"keyboardControls\"];\n /**\n * Show video progress bar.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 프로그레스 바를 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly progressBar: ControlBarOptions[\"progressBar\"];\n /**\n * Show video play / pause button.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 재생 / 일시정지 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly playButton: ControlBarOptions[\"playButton\"];\n /**\n * Show video volume control button.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 볼륨 조절 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly volumeButton: ControlBarOptions[\"volumeButton\"];\n /**\n * Show fullscreen button.\n * `true` to enable with default values, `false` to disable.\n * @ko 풀스크린 진입 / 해제 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly fullscreenButton: ControlBarOptions[\"fullscreenButton\"];\n /**\n * Show video current / total time\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오의 현재 시간 / 총 시간을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly videoTime: ControlBarOptions[\"videoTime\"];\n /**\n * Show camera pie view.\n * `true` to enable with default values, `false` to disable.\n * @ko 현재 카메라가 가리키는 방향을 표시하는 파이 뷰를 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly pieView: ControlBarOptions[\"pieView\"];\n /**\n * Show VR button.\n * `true` to enable with default values, `false` to disable.\n * @ko VR 진입버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly vrButton: ControlBarOptions[\"vrButton\"];\n /**\n * Show gyroscope control enable / disable button.\n * `true` to enable with default values, `false` to disable.\n * @ko 자이로스코프 컨트롤을 활성화 / 비활성화하는 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly gyroButton: ControlBarOptions[\"gyroButton\"];\n /**\n * Override default class names.\n * @ko 디폴트 클래스 이름들을 오버라이드합니다.\n * @since 4.0.0\n */\n public readonly className: Required;\n\n /**\n * Root element of the control bar\n * @ko 컨트롤바의 루트 엘리먼트\n * @since 4.0.0\n */\n public get rootEl() { return this._rootEl; }\n /**\n * Container element of the control bar\n * @ko 컨트롤바의 컨테이너 엘리먼트\n * @since 4.0.0\n */\n public get containerEl() { return this._containerEl; }\n /**\n * Background element of the control bar\n * @ko 컨트롤바의 배경 엘리먼트\n * @since 4.0.0\n */\n public get backgroundEl() { return this._bgEl; }\n /**\n * Control bar's default items created by {@link ControlBarOptions}\n * @ko 주어진 {@link ControlBarOptions}에 의해 생성된 디폴트 아이템들\n * @since 4.0.0\n */\n public get items() { return this._items; }\n /**\n * Custom control bar items\n * @ko 커스텀 컨트롤바 아이템들을 추가합니다.\n * @since 4.0.0\n */\n public get customItems() { return this._customItems; }\n\n private _rootEl: HTMLElement;\n private _containerEl: HTMLElement;\n private _bgEl: HTMLElement;\n private _wrapperEl: Record, HTMLElement>;\n private _items: Record, ControlBarItem[]>;\n private _customItems: ControlBarItem[];\n private _autoHider: AutoHide;\n private _videoControl: VideoControl;\n\n /**\n * Create new instance of ControlBar.\n * @ko ControlBar의 새 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n autoHide,\n showBackground,\n clickToPlay = true,\n keyboardControls = true,\n progressBar = true,\n playButton = true,\n volumeButton = true,\n fullscreenButton = true,\n videoTime = true,\n pieView = true,\n vrButton = true,\n gyroButton = true,\n className = {},\n customItems = []\n }: Partial = {}) {\n this.autoHide = autoHide;\n this.showBackground = showBackground;\n this.clickToPlay = clickToPlay;\n this.keyboardControls = keyboardControls;\n this.progressBar = progressBar;\n this.playButton = playButton;\n this.volumeButton = volumeButton;\n this.fullscreenButton = fullscreenButton;\n this.videoTime = videoTime;\n this.pieView = pieView;\n this.vrButton = vrButton;\n this.gyroButton = gyroButton;\n this.className = {\n ...ControlBar.DEFAULT_CLASS,\n ...className\n };\n\n const rootClass = className.CONTROLS_ROOT ?? ControlBar.DEFAULT_CLASS.CONTROLS_ROOT;\n\n this._rootEl = createElement(rootClass);\n this._createPositionWrappers();\n this._items = Object.keys(ControlBar.POSITION).reduce((items, key) => {\n items[ControlBar.POSITION[key]] = [];\n return items;\n }, {}) as Record, ControlBarItem[]>;\n this._customItems = customItems;\n this._autoHider = new AutoHide(this, getObjectOption(autoHide));\n this._videoControl = new VideoControl();\n\n customItems.forEach(item => {\n this._items[item.position].push(item);\n });\n }\n\n public init(viewer: View360) {\n const panoRoot = viewer.rootEl;\n const controlsRoot = this._rootEl;\n const defaultItems = this._createDefaultItems();\n\n this._updateBackground(viewer);\n this._updateAutoHide(viewer);\n this._updateKeyboardHandler(viewer);\n\n panoRoot.appendChild(controlsRoot);\n this._addItem(viewer, defaultItems);\n this._addItem(viewer, this._customItems);\n\n viewer.on(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad);\n viewer.on(EVENTS.STATIC_CLICK, this._onStaticClick);\n }\n\n public destroy(viewer: View360): void {\n // Remove controls root from pano root\n const panoRoot = viewer.rootEl;\n const controlsRoot = this._rootEl;\n const items = this._items;\n\n if (controlsRoot.parentElement === panoRoot) {\n panoRoot.removeChild(controlsRoot);\n }\n\n Object.keys(items).forEach((key: ValueOf) => {\n const category = items[key];\n\n category.forEach(item => {\n item.destroy(viewer, this);\n });\n\n items[key] = [];\n });\n\n this._clearItemElements();\n this._autoHider.disable(viewer);\n this._videoControl.disable(panoRoot);\n\n viewer.off(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad);\n viewer.off(EVENTS.STATIC_CLICK, this._onStaticClick);\n }\n\n private _addItem(viewer: View360, items: ControlBarItem[]) {\n for (const item of items) {\n const category = this._items[item.position];\n const wrapper = this._wrapperEl[item.position];\n\n const nextSiblingIndex = findIndex(category, sibling => sibling.order > item.order);\n\n if (nextSiblingIndex >= 0) {\n const nextSibling = category[nextSiblingIndex].element;\n category.splice(nextSiblingIndex, 0, item);\n wrapper.insertBefore(item.element, nextSibling);\n } else {\n category.push(item);\n wrapper.appendChild(item.element);\n }\n\n item.init(viewer, this);\n }\n }\n\n private _createPositionWrappers() {\n const className = {\n ...ControlBar.DEFAULT_CLASS,\n ...this.className\n };\n const rootEl = this._rootEl;\n\n // BG & FLOATING CONTROLS\n const backgroundEl = createElement(className.CONTROLS_BG);\n const floatLeftEl = createElement(className.CONTROLS_FLOAT_LEFT);\n const floatRightEl = createElement(className.CONTROLS_FLOAT_RIGHT);\n\n rootEl.appendChild(floatLeftEl);\n rootEl.appendChild(floatRightEl);\n\n // BOTTOM CONTROLS\n const container = createElement(className.CONTROLS_MAIN);\n const topWrapper = createElement(className.CONTROLS_TOP);\n const bottomWrapper = createElement(className.CONTROLS_BOTTOM);\n const midWrapper = createElement(className.CONTROLS_MID);\n const leftControlsWrapper = createElement(className.CONTROLS_LEFT);\n const rightControlsWrapper = createElement(className.CONTROLS_RIGHT);\n\n midWrapper.appendChild(leftControlsWrapper);\n midWrapper.appendChild(rightControlsWrapper);\n container.appendChild(backgroundEl);\n container.appendChild(topWrapper);\n container.appendChild(midWrapper);\n container.appendChild(bottomWrapper);\n rootEl.appendChild(container);\n\n this._bgEl = backgroundEl;\n this._containerEl = container;\n this._wrapperEl = {\n [ControlBar.POSITION.MAIN_TOP]: topWrapper,\n [ControlBar.POSITION.MAIN_LEFT]: leftControlsWrapper,\n [ControlBar.POSITION.MAIN_RIGHT]: rightControlsWrapper,\n [ControlBar.POSITION.MAIN_BOTTOM]: bottomWrapper,\n [ControlBar.POSITION.TOP_LEFT]: floatLeftEl,\n [ControlBar.POSITION.TOP_RIGHT]: floatRightEl\n };\n }\n\n private _clearItemElements() {\n const wrappers = Object.keys(ControlBar.POSITION).map(key => ControlBar.POSITION[key]);\n\n // Remove all elements inside wrappers\n wrappers.forEach(wrapper => {\n while (wrapper.firstChild) {\n wrapper.removeChild(wrapper.firstChild);\n }\n });\n }\n\n private _onStaticClick = ({ target: viewer, isTouch }: StaticClickEvent) => {\n const autoHider = this._autoHider;\n\n if (isTouch) {\n if (!autoHider.enabled) return;\n\n if (autoHider.hidden) {\n autoHider.showTemporaliy();\n } else {\n autoHider.hide();\n }\n } else {\n if (!this.clickToPlay) return;\n\n const video = viewer.projection?.getTexture();\n if (!video || !video.isVideo()) return;\n\n if (video.isPaused()) {\n video.source.play();\n } else {\n video.source.pause();\n }\n }\n };\n\n private _onNewSrcLoad = ({ target: viewer }: View360Events[\"projectionChange\"]) => {\n const items = this._items;\n\n this._updateBackground(viewer);\n this._updateAutoHide(viewer);\n this._updateKeyboardHandler(viewer);\n\n Object.keys(items).forEach((key: ValueOf) => {\n const category = items[key];\n\n category.forEach(item => {\n item.destroy(viewer, this);\n item.init(viewer, this);\n });\n });\n };\n\n private _updateAutoHide(viewer: View360) {\n const autoHide = this.autoHide;\n const autoHider = this._autoHider;\n\n if (autoHide != null) {\n if (autoHide) {\n autoHider.enable(viewer);\n } else {\n autoHider.disable(viewer);\n }\n } else {\n // Automatically choose whether to show background by content type\n const texture = viewer.projection?.getTexture();\n\n if (texture && texture.isVideo()) {\n // Enable auto hide when content type is video\n autoHider.enable(viewer);\n } else {\n autoHider.disable(viewer);\n }\n }\n }\n\n private _updateBackground(viewer: View360) {\n const background = this._bgEl;\n const showBackground = this.showBackground;\n const hiddenClass = this.className.HIDDEN ?? ControlBar.DEFAULT_CLASS.HIDDEN;\n\n if (showBackground != null) {\n if (showBackground) {\n background.classList.remove(hiddenClass);\n } else {\n background.classList.add(hiddenClass);\n }\n } else {\n // Automatically choose whether to show background by content type\n const texture = viewer.projection?.getTexture();\n\n if (texture && texture.isVideo()) {\n // Show bg when content type is video\n background.classList.remove(hiddenClass);\n } else {\n background.classList.add(hiddenClass);\n }\n }\n }\n\n private _updateKeyboardHandler(viewer: View360) {\n const panoRoot = viewer.rootEl;\n const videoControl = this._videoControl;\n const texture = viewer.projection?.getTexture();\n\n if (this.keyboardControls && texture && texture.isVideo()) {\n videoControl.enable(panoRoot, texture);\n } else {\n videoControl.disable(panoRoot);\n }\n }\n\n private _createDefaultItems(): ControlBarItem[] {\n const items: ControlBarItem[] = [];\n\n if (this.progressBar) {\n items.push(new ProgressBar(getObjectOption(this.progressBar)));\n }\n\n if (this.playButton) {\n items.push(new PlayButton(getObjectOption(this.playButton)));\n }\n\n if (this.volumeButton) {\n items.push(new VolumeControl(getObjectOption(this.volumeButton)));\n }\n\n if (this.gyroButton) {\n items.push(new GyroButton(getObjectOption(this.gyroButton)));\n }\n\n if (this.vrButton) {\n items.push(new VRButton(getObjectOption(this.vrButton)));\n }\n\n if (this.fullscreenButton) {\n items.push(new FullscreenButton(getObjectOption(this.fullscreenButton)));\n }\n\n if (this.videoTime) {\n items.push(new VideoTime(getObjectOption(this.videoTime)));\n }\n\n if (this.pieView) {\n items.push(new PieView(getObjectOption(this.pieView)));\n }\n\n return items;\n }\n}\n\nexport default ControlBar;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Camera from \"../core/Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport Texture from \"../texture/Texture\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport { VideoConfig } from \"../type/external\";\nimport UniformCanvasCube from \"../uniform/UniformCanvasCube\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport UniformTextureCube from \"../uniform/UniformTextureCube\";\n\ntype CommonProjectionUniforms = {\n uTexture: UniformTexture2D | UniformTextureCube | UniformCanvasCube;\n}\n\n/**\n * Common option for {@link Projection}s\n * @ko {@link Projection}을 위한 공통 옵션들\n * @category Projection\n * @since 4.0.0\n */\nexport interface ProjectionOptions {\n /**\n * @copy Projection#src\n */\n src: string | HTMLElement | Array;\n /**\n * @copy Projection#video\n */\n video?: boolean | Partial;\n}\n\n/**\n * Base class for projections.\n * @ko 프로젝션 베이스 클래스.\n * @category Projection\n * @since 4.0.0\n */\nabstract class Projection {\n /**\n * Source URL to panorama image/video.\n * @ko 파노라마 이미지/비디오의 URL\n * @since 4.0.0\n */\n public readonly src: ProjectionOptions[\"src\"];\n /**\n * Properties for the video element.\n * Setting `false` will treat panorama source as an image, `true` will use default properties.\n * @ko 비디오 엘리먼트에 설정할 프로퍼티를 담는 객체.\n * @since 4.0.0\n * @example\n * Default properties\n * ```ts\n * autoplay: true\n * muted: true\n * loop: false\n * volume: 1\n * ```\n */\n public readonly video: ProjectionOptions[\"video\"];\n\n protected _mesh: TriangleMesh | null;\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n src,\n video = false\n }: ProjectionOptions) {\n this.src = src;\n this.video = video;\n this._mesh = null;\n }\n\n /**\n * Apply texture to current projection.\n * @ko 주어진 텍스쳐를 현재 프로젝션에 적용합니다.\n * @param ctx - Instance of the WebGLContext helper {@ko WebGL context 헬퍼의 인스턴스}\n * @param texture - New texture to apply {@ko 새로 적용할 텍스쳐}\n * @internal\n * @since 4.0.0\n */\n public abstract applyTexture(ctx: WebGLContext, texture: Texture): void;\n\n /**\n * Release all resources projection has.\n * This is automatically called on projection change & View360's destroy call\n * @ko 현재 갖고 있는 모든 리소스를 반환합니다.\n * 이 메소드는 프로젝션 변경 및 View360의 destroy 호출 시 자동으로 호출됩니다.\n * @param ctx\n */\n public releaseAllResources(ctx: WebGLContext) {\n this._mesh?.destroy(ctx);\n }\n\n /**\n * Update camera to match projection's settings.\n * @ko 현재 프로젝션의 세팅으로 카메라를 업데이트합니다.\n * @param camera - Instance of the camera to update {@ko 업데이트할 카메라의 인스턴스}\n * @since 4.0.0\n */\n public updateCamera(camera: Camera) {\n // Use default mode & no view restriction\n camera.resetRange();\n }\n\n /**\n * Update control to match projection's settings.\n * @ko 현재 프로젝션의 세팅으로 컨트롤을 업데이트합니다.\n * @param control - Instance of the control to update {@ko 업데이트할 컨트롤의 인스턴스}\n * @since 4.0.0\n */\n public updateControl(control: PanoControl) {\n control.ignoreZoomScale = false;\n }\n\n /**\n * Update projection.\n * @ko 현재 프로젝션 정보를 갱신합니다.\n * @param camera - Instance of the camera to reference {@ko 참조할 카메라의 인스턴스}\n * @since 4.0.0\n */\n public update(camera: Camera) {} // eslint-disable-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars\n\n /**\n * Return active texture.\n * @ko 현재 활성화된 텍스쳐를 반환합니다.\n * @internal\n * @since 4.0.0\n */\n public getTexture() {\n if (!this._mesh) return null;\n\n return this._mesh.program.uniforms.uTexture.texture;\n }\n\n /**\n * A 3D triangle mesh for projection. It's `null` until loading the `src`.\n * @ko Projection을 표시하기 위한 Mesh, src를 로드하기 전까지는 `null`입니다.\n * @since 4.0.0\n */\n public getMesh(): TriangleMesh | null {\n return this._mesh;\n }\n}\n\nexport default Projection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nabstract class Uniform {\n public needsUpdate: boolean;\n\n public constructor() {\n this.needsUpdate = true;\n }\n\n public abstract update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean): void;\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext) {\n // DO_NOTHING\n }\n}\n\nexport default Uniform;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport TextureCube from \"../texture/TextureCube\";\nimport { reorderCube } from \"../utils\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformTextureCube extends Uniform {\n public readonly texture: TextureCube;\n private _webglTexture: WebGLTexture;\n private _cubemapOrder: string;\n\n public constructor(ctx: WebGLContext, texture: TextureCube, cubemapOrder: string) {\n super();\n\n this.texture = texture;\n this._webglTexture = ctx.createWebGLCubeTexture(texture, texture.width);\n this._cubemapOrder = cubemapOrder;\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext): void {\n this.texture.destroy();\n gl.deleteTexture(this._webglTexture);\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture);\n\n const sources = reorderCube(texture.sources, this._cubemapOrder);\n sources.forEach((src, idx) => {\n if (isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src);\n } else {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src);\n }\n });\n\n if (!texture.isVideo()) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformTextureCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"../texture/Texture2D\";\nimport { range, reorderCube } from \"../utils\";\n\n/** @hidden */\nclass CubeTexturePainter {\n public readonly texture: Texture2D;\n private _renderingOrder: number[];\n private _canvas: HTMLCanvasElement;\n private _ctx: CanvasRenderingContext2D;\n private _row: number;\n private _column: number;\n private _size: number;\n\n public get size() { return this._size; }\n\n public constructor(texture: Texture2D, cubemapOrder: string) {\n this.texture = texture;\n this._renderingOrder = reorderCube(range(6), cubemapOrder);\n\n const canvas = document.createElement(\"canvas\");\n\n this._calcRenderingSize();\n\n canvas.width = this._size;\n canvas.height = this._size;\n\n this._canvas = canvas;\n this._ctx = canvas.getContext(\"2d\")!;\n }\n\n public destroy() {\n const canvas = this._canvas;\n\n // release memories\n canvas.width = 1;\n canvas.height = 1;\n this._canvas = null as any;\n }\n\n public draw(gl: WebGLRenderingContext | WebGL2RenderingContext, isWebGL2: boolean) {\n const size = this._size;\n const texture = this.texture;\n let surfaceIdx = 0;\n\n for (let row = 0; row < this._row; row++) {\n for (let column = 0; column < this._column; column++) {\n const x = size * column;\n const y = size * row;\n const renderingFace = this._renderingOrder[surfaceIdx];\n\n this._ctx.drawImage(texture.source as CanvasImageSource, x, y, size, size, 0, 0, size, size);\n\n if (isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas);\n } else {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas);\n }\n\n surfaceIdx++;\n }\n }\n }\n\n private _calcRenderingSize() {\n const {\n width,\n height\n } = this.texture;\n const aspect = width / height;\n\n if (aspect === 1 / 6) {\n this._size = width;\n this._row = 6;\n this._column = 1;\n } else if (aspect === 6) {\n this._size = height;\n this._row = 1;\n this._column = 6;\n } else if (aspect === 2 / 3) {\n this._size = width * 0.5;\n this._row = 3;\n this._column = 2;\n } else {\n this._size = width / 3;\n this._row = 2;\n this._column = 3;\n }\n }\n}\n\nexport default CubeTexturePainter;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport CubeTexturePainter from \"../core/CubeTexturePainter\";\nimport Texture2D from \"../texture/Texture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformCanvasCube extends Uniform {\n private _webglTexture: WebGLTexture;\n private _painter: CubeTexturePainter;\n\n public get texture() { return this._painter.texture; }\n\n public constructor(ctx: WebGLContext, texture: Texture2D, cubemapOrder: string) {\n super();\n\n this._painter = new CubeTexturePainter(texture as Texture2D, cubemapOrder);\n this._webglTexture = ctx.createWebGLCubeTexture(texture, this._painter.size);\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext) {\n gl.deleteTexture(this._webglTexture);\n this._painter.destroy();\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture);\n\n this._painter.draw(gl, isWebGL2);\n\n if (!texture.isVideo()) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformCanvasCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Object3D from \"./Object3D\";\nimport ShaderProgram from \"./ShaderProgram\";\nimport VertexArrayObject from \"./VertexArrayObject\";\nimport Uniform from \"../uniform/Uniform\";\nimport WebGLContext from \"./WebGLContext\";\n\n/**\n * @hidden\n */\nclass TriangleMesh = Record> extends Object3D {\n /**\n * @internal\n * Geometry data for projection\n */\n public readonly vao: VertexArrayObject;\n /**\n * @internal\n * Material(shader) data for projection\n */\n public readonly program: ShaderProgram;\n\n public constructor(vao: VertexArrayObject, program: ShaderProgram) {\n super();\n\n this.vao = vao;\n this.program = program;\n }\n\n public destroy(ctx: WebGLContext) {\n ctx.releaseVAO(this.vao);\n ctx.releaseShaderResources(this.program);\n }\n}\n\nexport default TriangleMesh;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"../uniform/Uniform\";\nimport WebGLContext from \"./WebGLContext\";\nimport { UniformLocations } from \"../type/internal\";\n\nclass ShaderProgram = Record> {\n public readonly program: WebGLProgram;\n public readonly uniforms: T;\n public readonly uniformLocations: UniformLocations;\n\n public constructor(ctx: WebGLContext, vertexShader: string, fragmentShader: string, uniforms: T) {\n this.program = ctx.createProgram(vertexShader, fragmentShader);\n this.uniforms = uniforms;\n this.uniformLocations = ctx.getUniformLocations(this.program, uniforms);\n }\n}\n\nexport default ShaderProgram;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { TypedArray } from \"../type/utils\";\n\n/**\n * @hidden\n */\nclass VertexData {\n public readonly data: T;\n public itemSize: number;\n public count: number;\n\n /** */\n public constructor(data: T, itemSize: number) {\n this.data = data;\n this.itemSize = itemSize;\n this.count = data.length / itemSize;\n }\n}\n\nexport default VertexData;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport VertexData from \"../core/VertexData\";\n\n/**\n * @hidden\n */\nabstract class Geometry {\n public readonly vertices: VertexData;\n public readonly indicies: VertexData;\n public readonly uvs: VertexData;\n\n /** */\n public constructor(vertices: number[], indicies: number[], uvs: number[]) {\n this.vertices = new VertexData(new Float32Array(vertices), 3);\n this.indicies = new VertexData(new Uint16Array(indicies), 1);\n this.uvs = new VertexData(new Float32Array(uvs), 2);\n }\n}\n\nexport default Geometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\nimport { ROTATE } from \"../const/internal\";\nimport { reorderCube } from \"../utils\";\n\n/**\n * @hidden\n */\nclass CubeGeometry extends Geometry {\n public constructor({\n order,\n rotateUV\n }: {\n order: string;\n rotateUV?: ROTATE[]\n }) {\n const vertices = [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // up\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // down\n -1, -1, 1,\n 1, -1, 1,\n 1, -1, -1,\n -1, -1, -1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n\n const indicies = [\n 0, 1, 2,\n 0, 2, 3,\n 4, 5, 6,\n 4, 6, 7,\n 8, 9, 10,\n 8, 10, 11,\n 12, 13, 14,\n 12, 14, 15,\n 16, 17, 18,\n 16, 18, 19,\n 20, 21, 22,\n 20, 22, 23\n ];\n\n const oneThird = 1 / 3;\n const coords: number[][] = [];\n\n for (let r = 1; r >= 0; r--) {\n for (let c = 0; c < 3; c++) {\n const coord = [\n c * oneThird, r * 0.5,\n (c + 1) * oneThird, r * 0.5,\n (c + 1) * oneThird, (r + 1) * 0.5,\n c * oneThird, (r + 1) * 0.5\n ];\n\n coords.push(coord);\n }\n }\n\n if (rotateUV) {\n rotateUV.forEach((degree, idx) => {\n if (degree === ROTATE.ZERO) return;\n\n const coord = coords[idx];\n let newOrder: number[];\n\n if (degree === ROTATE.CW_90) {\n newOrder = [1, 2, 3, 0];\n } else if (degree === ROTATE.CCW_90) {\n newOrder = [3, 0, 1, 2];\n } else {\n newOrder = [2, 3, 0, 1];\n }\n\n const newCoords = Array(coord.length);\n for (let uvIdx = 0; uvIdx < coord.length / 2; uvIdx++) {\n newCoords[uvIdx * 2 + 0] = coord[newOrder[uvIdx] * 2 + 0];\n newCoords[uvIdx * 2 + 1] = coord[newOrder[uvIdx] * 2 + 1];\n }\n\n coords[idx] = newCoords;\n });\n }\n\n const uvs = reorderCube(coords, order, \"BFUDRL\")\n .reduce((acc, val) => acc.concat(val), []);\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default CubeGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTextureCube from \"../uniform/UniformTextureCube\";\nimport UniformCanvasCube from \"../uniform/UniformCanvasCube\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport TextureCube from \"../texture/TextureCube\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/cube.vert\";\nimport fs from \"../shader/cube.frag\";\n\n/**\n * Options for {@link CubemapProjection}\n * @ko {@link CubemapProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CubemapProjectionOptions extends ProjectionOptions {\n /**\n * Order of the cubemap images.\n * @ko 큐브맵 이미지의 순서.\n * @since 4.0.0\n * @default \"RLUDFB\" (Right - Left - Up - Down - Front - Back)\n */\n cubemapOrder?: string;\n /**\n * Whether to flip cubemap image horizontally.\n * @ko 큐브맵 이미지를 좌우대칭할지 여부.\n * @since 4.0.0\n * @default false\n */\n cubemapFlipX?: boolean;\n}\n\n/**\n * Projection based on cubemap images, accepts both multiple or single images.\n * @ko 큐브맵 이미지 기반의 프로젝션, 단일 혹은 여러 장의 이미지를 모두 사용 가능합니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CubemapProjection extends Projection<{\n uTexture: UniformTextureCube | UniformCanvasCube;\n}> {\n private _cubemapOrder: NonNullable;\n private _cubemapFlipX: NonNullable;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CubemapProjectionOptions) {\n super(options);\n\n const {\n cubemapOrder = \"RLUDFB\",\n cubemapFlipX = false\n } = options;\n\n this._cubemapOrder = cubemapOrder;\n this._cubemapFlipX = cubemapFlipX;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const cubemapOrder = this._cubemapOrder;\n const cubemapFlipX = this._cubemapFlipX;\n const uniforms = {\n uTexture: texture.isCube()\n ? new UniformTextureCube(ctx, texture as TextureCube, cubemapOrder)\n : new UniformCanvasCube(ctx, texture as Texture2D, cubemapOrder)\n };\n\n const geometry = new CubeGeometry({\n order: cubemapOrder\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n if (cubemapFlipX) {\n mesh.scale[0] = -1;\n }\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n}\n\nexport default CubemapProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"../texture/Texture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformTexture2D extends Uniform {\n public readonly texture: Texture2D;\n private _webglTexture: WebGLTexture;\n\n public constructor(ctx: WebGLContext, texture: Texture2D) {\n super();\n\n this.texture = texture;\n this._webglTexture = ctx.createWebGLTexture(texture);\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext): void {\n this.texture.destroy();\n gl.deleteTexture(this._webglTexture);\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n const isVideo = texture.isVideo();\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._webglTexture);\n\n if (!isVideo && isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n } else {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n }\n\n if (!isVideo) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformTexture2D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link CubestripProjection}\n * @ko {@link CubestripProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CubestripProjectionOptions extends ProjectionOptions {\n /**\n * @copy CubemapProjectionOptions#cubemapOrder\n */\n cubemapOrder?: string;\n /**\n * @copy CubemapProjectionOptions#cubemapFlipX\n */\n cubemapFlipX?: boolean;\n}\n\n/**\n * Projection based on cubemap strip.\n * Slightly more efficient than {@link CubemapProjection} as it doesn't copy cubemap image to canvas while rendering.\n * Accepts only single image.\n * @ko 큐브맵 스트립 기반의 프로젝션.\n * {@link CubemapProjection}와 달리 렌더링하는 과정에 캔버스에 이미지를 복사하는 과정이 없기 때문에 살짝 더 효율적입니다.\n * 단일 이미지만 사용 가능합니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CubestripProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n private _cubemapOrder: NonNullable;\n private _cubemapFlipX: NonNullable;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CubestripProjectionOptions) {\n super(options);\n\n const {\n cubemapOrder = \"RLUDFB\",\n cubemapFlipX = false\n } = options;\n\n this._cubemapOrder = cubemapOrder;\n this._cubemapFlipX = cubemapFlipX;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const cubemapOrder = this._cubemapOrder;\n const cubemapFlipX = this._cubemapFlipX;\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n const geometry = new CubeGeometry({\n order: cubemapOrder\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n if (cubemapFlipX) {\n mesh.scale[0] = -1;\n }\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n}\n\nexport default CubestripProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass CylinderGeometry extends Geometry {\n public constructor(maxTheta: number) {\n const vertices: number[] = [];\n const indicies: number[] = [];\n const uvs: number[] = [];\n\n const height = 1;\n const radialSegments = 60;\n const halfHeight = height * 0.5;\n const heightSegments = [-halfHeight, halfHeight];\n const invRadialSegments = 1 / radialSegments;\n const angleConst = maxTheta * invRadialSegments;\n\n for (let yIdx = 0; yIdx < 2; yIdx++) {\n const y = heightSegments[yIdx];\n\n for (let lngIdx = 0; lngIdx <= radialSegments; lngIdx++) {\n const angle = lngIdx * angleConst + Math.PI - maxTheta * 0.5;\n const x = Math.cos(angle);\n const z = Math.sin(angle);\n const u = lngIdx * invRadialSegments;\n const v = yIdx;\n\n uvs.push(u, v);\n vertices.push(x, y, z);\n\n if (yIdx === 0 && lngIdx < radialSegments) {\n const a = lngIdx;\n const b = a + radialSegments + 1;\n\n indicies.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n }\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default CylinderGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n*/\nimport { quat } from \"gl-matrix\";\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport CylinderGeometry from \"../geometry/CylinderGeometry\";\nimport Camera from \"../core/Camera\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"../const/internal\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\nimport TriangleMesh from \"../core/TriangleMesh\";\n\n/**\n * Options for {@link CylindricalProjection}\n * @ko {@link CylindricalProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CylindricalProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n /**\n * Whether the panorama image covers full 360 degrees.\n * @ko 파노라마 이미지가 360도를 전부 커버하는지 여부\n * @since 4.0.0\n * @default false\n */\n partial?: boolean;\n}\n\n/**\n * Projection based on cylindrical projection.\n * This can show panorama images taken from smartphones.\n * @ko 원통 투영법 기반의 프로젝션.\n * 일반적인 스마트폰 파노라마 사진을 표시하는데 사용될 수 있습니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CylindricalProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n private _partial: boolean;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CylindricalProjectionOptions) {\n super(options);\n\n const {\n partial = false\n } = options;\n\n this._partial = partial;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const partial = this._partial;\n const { width, height } = texture;\n const aspect = width / height;\n const halfVFov = 180 / aspect;\n const cylinderHeight = partial\n ? 1\n : 2 * Math.tan(halfVFov * DEG_TO_RAD);\n const cylinderTheta = partial\n ? aspect\n : 2 * Math.PI;\n\n const geometry = new CylinderGeometry(cylinderTheta);\n const program = new ShaderProgram(ctx, vs, fs, {\n uTexture: new UniformTexture2D(ctx, texture)\n });\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n mesh.scale[1] = cylinderHeight;\n quat.identity(mesh.rotation);\n quat.rotateY(mesh.rotation, mesh.rotation, -Math.PI / 2);\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n\n public updateCamera(camera: Camera) {\n super.updateCamera(camera);\n\n const mesh = this._mesh;\n if (!mesh) return;\n\n const uTexture = mesh.program.uniforms.uTexture;\n const texture = uTexture.texture;\n const { width, height } = texture;\n const aspect = width / height;\n const halfHeight = mesh.scale[1] * 0.5;\n\n if (this._partial) {\n const restrictedYaw = 0.5 * aspect * RAD_TO_DEG;\n camera.restrictYawRange(-restrictedYaw, restrictedYaw);\n }\n\n const restrictedPitch = Math.atan2(halfHeight, 1) * RAD_TO_DEG;\n const minZoom = Math.tan(camera.fov * DEG_TO_RAD * 0.5) / (halfHeight * camera.aspect);\n\n camera.restrictPitchRange(-restrictedPitch, restrictedPitch);\n camera.restrictZoomRange(minZoom, Infinity);\n camera.restrictRenderHeight(halfHeight * 2);\n }\n}\n\nexport default CylindricalProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/eac.frag\";\nimport { ROTATE } from \"../const/internal\";\n\n/**\n * Options for {@link EquiangularProjection}\n * @ko {@link EquiangularProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface EquiangularProjectionOptions extends ProjectionOptions {}\n\n/**\n * Equi-Angular Cubemap Projection.\n * This format is used by Youtube's 360 videos.\n * @ko Equi-Angular Cubemap 프로젝션.\n * 이 포맷은 주로 Youtube의 360 비디오에 사용됩니다.\n * @since 4.0.0\n * @category Projection\n */\nclass EquiangularProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n const geometry = new CubeGeometry({\n order: \"LFRDBU\",\n rotateUV: [\n ROTATE.ZERO, ROTATE.ZERO, ROTATE.ZERO,\n ROTATE.CW_90, ROTATE.CCW_90, ROTATE.CW_90\n ]\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default EquiangularProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass SphereGeometry extends Geometry {\n /** */\n public constructor() {\n // const radius = 1;\n const widthSegments = 60;\n const heightSegments = 60;\n const ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI;\n\n const uvs: number[] = [];\n const vertices: number[] = [];\n const indicies: number[] = [];\n let latIdx: number;\n let lngIdx: number;\n\n for (latIdx = 0; latIdx <= widthSegments; latIdx++) {\n const theta = (latIdx / widthSegments - 0.5) * Math.PI;\n const sinTheta = Math.sin(theta);\n const cosTheta = Math.cos(theta);\n\n for (lngIdx = 0; lngIdx <= heightSegments; lngIdx++) {\n const phi = (lngIdx / heightSegments - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN;\n const sinPhi = Math.sin(phi);\n const cosPhi = Math.cos(phi);\n const x = cosPhi * cosTheta;\n const y = sinTheta;\n const z = sinPhi * cosTheta;\n const u = lngIdx / heightSegments;\n const v = latIdx / widthSegments;\n\n uvs.push(u, v);\n vertices.push(x, y, z);\n\n if (lngIdx !== heightSegments && latIdx !== widthSegments) {\n const a = latIdx * (heightSegments + 1) + lngIdx;\n const b = a + heightSegments + 1;\n\n indicies.push(a, a + 1, b, b, a + 1, b + 1);\n }\n }\n }\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default SphereGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport Texture2D from \"../texture/Texture2D\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport SphereGeometry from \"../geometry/SphereGeometry\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link EquirectProjection}\n * @ko {@link EquirectProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface EquirectProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n}\n\n/**\n * Projection based on equirectangular projection.\n * @ko 등 장방형 도법(Equirectangular projection) 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass EquirectProjection extends Projection<{\n uTexture: UniformTexture2D\n}> {\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: EquirectProjectionOptions) {\n super(options);\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n\n const geometry = new SphereGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default EquirectProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"./Uniform\";\n\nclass UniformFloat extends Uniform {\n public val: number;\n\n public constructor(val: number) {\n super();\n\n this.val = val;\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation) {\n gl.uniform1f(location, this.val);\n\n this.needsUpdate = false;\n }\n}\n\nexport default UniformFloat;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass PlaneGeometry extends Geometry {\n /** */\n public constructor(width: number = 2, height: number = 2, z: number = -1) {\n const halfWidth = width * 0.5;\n const halfHeight = height * 0.5;\n const vertices = [\n -halfWidth, -halfHeight, z,\n halfWidth, -halfHeight, z,\n -halfWidth, halfHeight, z,\n halfWidth, halfHeight, z\n ];\n const indicies = [\n 0, 1, 2,\n 2, 1, 3\n ];\n const uvs = [\n 0, 0,\n 1, 0,\n 0, 1,\n 1, 1\n ];\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default PlaneGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport UniformFloat from \"../uniform/UniformFloat\";\nimport Camera from \"../core/Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport Texture2D from \"../texture/Texture2D\";\nimport PlaneGeometry from \"../geometry/PlaneGeometry\";\nimport vs from \"../shader/little-planet.vert\";\nimport fs from \"../shader/little-planet.frag\";\nimport TriangleMesh from \"../core/TriangleMesh\";\n\n/**\n * Options for {@link LittlePlanetProjection}\n * @ko {@link LittlePlanetProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface LittlePlanetProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n}\n\n/**\n * Projection based on so-called \"Little planet\" or \"Tiny planet\" effect.\n * @ko \"Little planet\" 혹은 \"Tiny planet\"로 불리는 이펙트 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass LittlePlanetProjection extends Projection<{\n uTexture: UniformTexture2D;\n uYaw: UniformFloat;\n uPitch: UniformFloat;\n uZoom: UniformFloat;\n}> {\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: LittlePlanetProjectionOptions) {\n super(options);\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n texture.wrapS = WebGLRenderingContext.REPEAT;\n texture.wrapT = WebGLRenderingContext.REPEAT;\n\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture),\n uYaw: new UniformFloat(0),\n uPitch: new UniformFloat(0.5),\n uZoom: new UniformFloat(1)\n };\n\n const geometry = new PlaneGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n\n public updateControl(control: PanoControl) {\n control.ignoreZoomScale = true;\n }\n\n public update(camera: Camera) {\n const mesh = this._mesh;\n if (!mesh) return;\n\n const uniforms = mesh.program.uniforms;\n\n uniforms.uYaw.val = camera.yaw / 360;\n // Range from 0 ~ 1\n uniforms.uPitch.val = (camera.pitch / 180) + 0.5;\n uniforms.uZoom.val = camera.zoom;\n\n uniforms.uYaw.needsUpdate = true;\n uniforms.uPitch.needsUpdate = true;\n uniforms.uZoom.needsUpdate = true;\n }\n}\n\nexport default LittlePlanetProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"./Uniform\";\n\nclass UniformVector4Array extends Uniform {\n public val: number[][];\n\n public constructor(val: number[][]) {\n super();\n\n this.val = val;\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation) {\n gl.uniform4fv(location, this.val.reduce((arr, vector) => [...arr, ...vector], []));\n\n this.needsUpdate = false;\n }\n}\n\nexport default UniformVector4Array;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport SphereGeometry from \"../geometry/SphereGeometry\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport UniformVector4Array from \"../uniform/UniformVector4Array\";\nimport UniformFloat from \"../uniform/UniformFloat\";\nimport vs from \"../shader/stereoequi.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link StereoEquiProjection}\n * @ko {@link StereoEquiProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface StereoEquiProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n /**\n * Stereoscopic mode of the image\n * @ko 이미지의 스테레오스코픽 모드\n * @since 4.0.0\n * @default \"top_bottom\"\n */\n mode: typeof StereoEquiProjection.MODE[keyof typeof StereoEquiProjection.MODE]\n}\n\n/**\n * Projection based on stereo equirectangular images.\n * @ko Stereo equirectangular 이미지 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass StereoEquiProjection extends Projection<{\n uTexture: UniformTexture2D;\n uEye: UniformFloat;\n uTexScaleOffset: UniformVector4Array;\n}> {\n /**\n * Available stereoscopic modes\n * @ko 사용가능한 스테레오스코픽 모드들\n * @since 4.0.0\n */\n public static MODE = {\n /**\n * @ko 이미지가 왼쪽/오른쪽으로 구성되어있을 경우\n * @since 4.0.0\n */\n LEFT_RIGHT: \"left_right\",\n /**\n * @ko 이미지가 위/아래로 구성되어있을 경우\n * @since 4.0.0\n */\n TOP_BOTTOM: \"top_bottom\",\n } as const;\n\n private _mode: StereoEquiProjectionOptions[\"mode\"];\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: StereoEquiProjectionOptions) {\n super(options);\n\n this._mode = options.mode;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n let leftEye: number[];\n let rightEye: number[];\n\n switch (this._mode) {\n case StereoEquiProjection.MODE.LEFT_RIGHT:\n leftEye = [0.5, 1, 0, 0];\n rightEye = [0.5, 1, 0.5, 0];\n break;\n default:\n // Default, uses \"top_bottom\"\n leftEye = [1, 0.5, 0, 0];\n rightEye = [1, 0.5, 0, 0.5];\n }\n\n\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture),\n uEye: new UniformFloat(0),\n uTexScaleOffset: new UniformVector4Array([leftEye, rightEye])\n };\n\n const geometry = new SphereGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default StereoEquiProjection;\n","import Component from \"@egjs/component\";\nimport View360 from \"../View360\";\n\n/**\n * @hidden\n */\nconst withMethods = (prototype: any, attr: string) => {\n [Component.prototype, View360.prototype].forEach(proto => {\n Object.getOwnPropertyNames(proto)\n .filter(name => name.charAt(0) !== \"_\" && name !== \"constructor\")\n .forEach((name: string) => {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name)!;\n\n if (descriptor.value) {\n // Public Function\n Object.defineProperty(prototype, name, {\n value: function(...args) {\n return descriptor.value.call(this[attr], ...args);\n }\n });\n } else {\n const getterDescriptor: { get?: () => any; set?: (val: any) => void } = {};\n if (descriptor.get) {\n getterDescriptor.get = function() {\n return this[attr] && descriptor.get?.call(this[attr]);\n };\n }\n if (descriptor.set) {\n getterDescriptor.set = function(...args) {\n return descriptor.set?.call(this[attr], ...args);\n };\n }\n\n Object.defineProperty(prototype, name, getterDescriptor);\n }\n });\n });\n};\n\nexport default withMethods;\n","/**\n * @hidden\n */\nexport const getValidProps = (propsObj: any) => {\n return Object.keys(propsObj).reduce((props, propName) => {\n if (propsObj[propName] != null) {\n props[propName] = propsObj[propName];\n }\n\n return props;\n }, {});\n};\n","export const VIEW360_METHODS = [\n \"destroy\",\n \"init\",\n \"load\",\n \"resize\",\n \"addPlugins\",\n \"removePlugins\",\n \"renderFrame\",\n // @egjs/component methods\n \"on\",\n \"hasOn\",\n \"once\",\n \"off\",\n \"trigger\"\n] as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360, { View360Options, View360Events } from \"./View360\";\n\nexport * from \"./core\";\nexport * from \"./control\";\nexport * from \"./plugin\";\nexport * from \"./projection\";\nexport * from \"./hotspot\";\nexport * from \"./const/external\";\nexport * from \"./type/external\";\nexport * from \"./cfc\";\n\nexport type {\n View360Options,\n View360Events\n};\n\nexport default View360;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360, * as modules from \"./index\";\nimport { merge } from \"./utils\";\n\nmerge(View360, modules);\n\nexport default View360;\n"],"names":["View360Error","Error","constructor","message","code","Object","setPrototypeOf","prototype","name","ERROR_CODES","WRONG_TYPE","WRONG_OPTION","ELEMENT_NOT_FOUND","CANVAS_NOT_FOUND","WEBGL_NOT_SUPPORTED","FAILED_CREATE_CONTEXT_2D","PROVIDE_PROJECTION_FIRST","FAILED_LINKING_PROGRAM","INSUFFICIENT_ARGS","MESSAGES","val","types","map","type","join","optionName","query","msg","shaderLog","CODES","EVENTS","MOUSE_DOWN","MOUSE_MOVE","MOUSE_UP","TOUCH_START","TOUCH_MOVE","TOUCH_END","WHEEL","RESIZE","CONTEXT_MENU","MOUSE_ENTER","MOUSE_LEAVE","POINTER_DOWN","POINTER_MOVE","POINTER_UP","POINTER_CANCEL","POINTER_ENTER","POINTER_LEAVE","KEY_DOWN","KEY_UP","LOAD","ERROR","CLICK","DOUBLE_CLICK","CONTEXT_CREATE_ERROR","CONTEXT_LOST","CONTEXT_RESTORED","DEVICE_ORIENTATION","DEVICE_MOTION","ORIENTATION_CHANGE","VIDEO_PLAY","VIDEO_PAUSE","VIDEO_LOADED_DATA","VIDEO_VOLUME_CHANGE","VIDEO_TIME_UPDATE","VIDEO_DURATION_CHANGE","VIDEO_CAN_PLAYTHROUGH","TRANSITION_END","XR_END","EL_DIV","EL_BUTTON","MOUSE_BUTTON","CURSOR","GRAB","GRABBING","NONE","KEY_DIRECTION","DIRECTION_KEY_CODE","SPACE_KEY_CODE","DIRECTION_KEY_NAME","LEFT","UP","RIGHT","DOWN","SPACE_KEY_NAME","FULLSCREEN_REQUEST","FULLSCREEN_ELEMENT","FULLSCREEN_EXIT","FULLSCREEN_CHANGE","DEFAULT_CLASS","CONTAINER","CANVAS","CTX_LOST","IN_VR","HOTSPOT_CONTAINER","HOTSPOT","HOTSPOT_VISIBLE","HOTSPOT_FLIP_X","HOTSPOT_FLIP_Y","READY","LOAD_START","PROJECTION_CHANGE","BEFORE_RENDER","RENDER","INPUT_START","INPUT_END","VIEW_CHANGE","STATIC_CLICK","VR_START","VR_END","EASING","LINEAR","x","SINE_WAVE","Math","sin","PI","EASE_OUT_CUBIC","pow","EASE_OUT_BOUNCE","n1","d1","CAMERA_EVENTS","CHANGE","ANIMATION_END","CONTROL_EVENTS","ENABLE","DISABLE","DEG_TO_RAD","RAD_TO_DEG","DEFAULT_EASING","DEFAULT_ANIMATION_DURATION","INFINITE_RANGE","min","Infinity","max","DEFAULT_PITCH_RANGE","DEFAULT_ZOOM_RANGE","ROTATE","VIDEO_TIME_CHANGE_EVENT","SVG_NAMESPACE","SESSION_VR","XR_REFERENCE_SPACE","EPSILON","_a","Number","isString","isElement","nodeType","Node","ELEMENT_NODE","createElement","className","tag","BROWSER","el","document","classList","add","getNullableElement","parent","targetEl","parentEl","queryResult","querySelector","getElement","findCanvas","root","selector","canvas","range","end","Array","apply","undef","idx","clamp","lerp","a","b","t","circulate","size","abs","offset","merge","target","srcs","forEach","source","keys","key","value","isArray","findIndex","array","checker","length","getObjectOption","toVerticalFov","fovRadian","aspect","atan","tan","reorderCube","arr","order","defaultOrder","split","face","indexOf","index","isFullscreen","sensorCanBeEnabledIOS","DeviceMotionEvent","window","isSecureContext","hfovToZoom","baseFov","fov","renderingWidth","zoomedWidth","eulerToQuat","out","yaw","pitch","roll","quat","identity","pitchThreshold","pitchClamped","rotateY","rotateX","rotateZ","quatToEuler","quaternion","y","z","w","x2","y2","z2","w2","unit","test","atan2","view","vec3","fromValues","up","transformQuat","viewXZ","sqrt","Motion","_val","start","_start","_end","progress","_progress","activated","_activated","duration","_duration","loop","_loop","_range","easing","_easing","reset","update","deltaTime","prev","nextProgress","easedProgress","defaultVal","delta","setNewEndByDelta","setRange","CameraAnimation","_motion","camera","from","to","_camera","_from","_to","_finishPromise","Promise","resolve","_finish","getFinishPromise","motion","rotation","create","zoom","slerp","rotate","Camera","Component","_aspect","changed","_changed","yawRange","_initialYawRange","pitchRange","_initialPitchRange","zoomRange","_initialZoomRange","initialYaw","initialPitch","initialZoom","rollOffset","position","animation","_up","_yawRange","_pitchRange","_zoomRange","_updateQuaternion","viewMatrix","mat4","projectionMatrix","_maxRenderHeight","destroy","off","resize","width","height","prevAspect","updateMatrix","lookAt","prevQuaternion","clone","prevZoom","zoomDiff","equals","normalized","normalize","isSameRotation","copy","animateTo","finishPromise","then","trigger","restrictYawRange","restrictPitchRange","restrictZoomRange","restrictRenderHeight","resetRange","getYawRange","yawLimit","maxRenderHeight","halfHFov","getHorizontalFov","minYaw","maxYaw","halfVFovRad","h","d","theta","getPitchRange","pitchLimit","minPitch","maxPitch","halfVFov","getVerticalFov","getZoomRange","limit","minFov","maxFov","currentFov","current","_getZoomedHorizontalFov","hFov","vFov","fovToZoom","projMatrix","upDir","viewDir","perspective","onFrameRender","MouseInput","_onMouseDown","evt","_el","button","preventDefault","focus","_prevPos","clientX","clientY","addEventListener","_onMouseMove","_onMouseUp","srcEvent","isTouch","isKeyboard","prevPos","deltaX","deltaY","removeEventListener","scrolling","enable","element","disable","TouchInput","scrollable","_scrollable","_onTouchStart","touches","_scrolling","touch","_isFirstTouch","_onTouchMove","cancelable","_onTouchEnd","passive","KeyboardInput","active","pressed","_pressed","_onKeyDown","location","KeyboardEvent","DOM_KEY_LOCATION_STANDARD","_updateKeyPress","pressedCount","_getPressedKeyCount","repeat","_onKeyUp","_clearPressedKeys","_getDeltaByPressedKeys","reduce","obj","keyName","assign","event","isEnable","keyToUpdate","keyCode","filter","RotateControl","enabled","_enabled","enableBlocked","_enableBlocked","animating","_keyboardInput","_xMotion","_yMotion","_touchInput","pointerScale","_pointerScale","keyboardScale","_keyboardScale","disablePitch","_disablePitch","disableYaw","_disableYaw","disableKeyboard","_disableKeyboard","controlEl","_onInputStart","_changedWhileDragging","inputType","_onChange","invZoomScale","_zoomScale","screenScale","_screenScale","scale","scaledX","scaledY","_onInputEnd","_controlEl","_mouseInput","_bindInputs","xMotion","yMotion","keyboardInput","updateRange","setZoomScale","hfov","vfov","control","updateCursor","sync","mouseInput","touchInput","on","WheelInput","_onWheel","stopPropagation","_inputTimer","_clearTimer","_baseScale","setTimeout","capture","clearTimeout","PinchInput","prevDistance","_prevDistance","diff","pageX","pageY","distance","ZoomControl","_wheelInput","_scale","scaledDelta","_pinchInput","wheelInput","pinchInput","ROTATE_CONSTANT","PITCH_DELTA","YAW_DELTA_BY_ROLL","YAW_DELTA_BY_YAW","targetAxis","meshPoint","GyroInput","orientationUpdated","_orientationUpdated","ignoreRoll","_ignoreRoll","_onDeviceOrientation","prevOrientation","_orientation","alpha","beta","gamma","_needsCalibrate","_calibrateSensor","_updateScreenOrientation","screen","orientation","angle","undefined","_screenOrientation","_yawOrigin","_yawOffset","_updateRotation","collectDelta","prevRotation","_toEulerDelta","setInitialRotation","yawOrigin","sensorYaw","screenAngle","world","set","cos","multiply","prevQuat","currentQuat","_getDeltaYaw","_getDeltaPitch","prvQ","curQ","yawDeltaByYaw","_getRotationDelta","yawDeltaByRoll","_extractPitchFromQuat","prevQ","rotateKind","curQuaternion","prevPoint","curPoint","rotateDistance","dot","cross","rotateDirection","meshPoint2","meshPoint3","vecU","vecV","vecN","coefficientA","coefficientB","coefficientC","projectedPrevPoint","subtract","trigonometricRatio","acos","crossVec","thetaDirection","deltaRadian","baseV","GyroControl","_input","isAvailable","onDeviceMotionChange","listenDeviceMotion","res","rotationRate","timeout","race","available","requestSensorPermission","requestPermission","permissionState","catch","_updateYawPitch","input","yawDelta","pitchDelta","PanoControl","useGrabCursor","_useGrabCursor","_setCursor","disableContextMenu","_disableContextMenu","_blockContextMenu","_restoreContextMenu","_rotateControl","wheelScrollable","_zoomControl","ignoreZoomScale","_ignoreZoomScale","gyro","_gyroControl","_preventContextMenu","_onEnable","_onDisable","_onCameraAnimationEnd","_bindEvents","rotateControl","zoomControl","gyroControl","zoomScale","newCursor","style","cursor","Texture","flipY","wrapS","WebGLRenderingContext","CLAMP_TO_EDGE","wrapT","isVideo","isCube","Texture2D","TextureVideo","video","pause","removeAttribute","load","isPaused","paused","ended","readyState","hasAudio","audioTracks","webkitAudioDecodedByteCount","mozHasAudio","TextureCube","sources","TextureLoader","_loadChecker","ImReady","src","loadVideo","loadCubeImage","imgSrc","loadImage","images","_toImageArray","_load","image","naturalWidth","naturalHeight","videoConfig","config","autoplay","muted","volume","_toVideoElement","currentTime","play","videoWidth","videoHeight","content","onLoad","loader","reject","once","errorCount","check","imgEl","Image","crossOrigin","HTMLVideoElement","playsInline","setAttribute","_appendSourceElement","sourceCount","querySelectorAll","HTMLSourceElement","sourceEl","appendChild","FrameAnimator","maxDeltaTime","context","_context","_rafId","_rafTimer","_lastUpdateTime","callback","_time","frame","time","Date","now","requestAnimationFrame","stop","cancelAnimationFrame","changeContext","AutoResizer","useResizeObserver","_useResizeObserver","onResize","_skipFirstResize","isFirstResize","_onResize","_resizeObserver","ResizeObserver","bbox","getBoundingClientRect","resizeImmediate","resizeObserver","observe","disconnect","Autoplay","playing","_interrupted","delay","_delay","delayOnMouseLeave","_delayOnMouseLeave","speed","_speed","pauseOnHover","_pauseOnHover","canInterrupt","_canInterrupt","disableOnInterrupt","_disableOnInterrupt","viewer","options","_clearTimeout","_setUninterruptedAfterDelay","_onGyroEnable","_onMouseEnter","_hovering","_onMouseLeave","_control","_element","_interruptionTimer","enableAfterDelay","XRManager","ctx","exit","_onSessionEnd","_xrSession","_xrRefSpace","_ctx","_options","xr","navigator","isSessionSupported","enter","requiredFeatures","makeXRCompatible","session","requestSession","bindXRLayer","refSpace","requestReferenceSpace","_setSession","xrSession","canRender","pose","getViewerPose","getEyeParams","glLayer","renderState","baseLayer","views","viewport","getViewport","vMatrix","transform","inverse","matrix","pMatrix","Hotspot","HotspotRenderer","rootEl","renderer","_containerEl","_renderer","_hotspots","_zoom","refresh","container","hotspotEls","slice","_parseHotspot","render","hotspots","halfWidth","halfHeight","centerTransform","zoomTransform","hotspot","relPos","transformMat4","remove","screenPos","vec2","yawStr","dataset","pitchStr","positionStr","parseFloat","_yawPitchToVec3","pos","defaultPos","yawRad","pitchRad","VertexArrayObject","count","geometry","indicies","buffers","WebGLContext","_canvas","maxTextureSize","_maxTextureSize","isWebGL2","_isWebGL2","supportVAO","_extensions","vao","lost","_contextLost","debug","_debug","_onContextLost","_onContextRestore","loseContext","init","gl","_getContext","_gl","getParameter","MAX_TEXTURE_SIZE","getExtension","bindBuffer","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","forceLoseContext","extension","forceRestoreContext","restoreContext","clear","COLOR_BUFFER_BIT","drawingBufferWidth","drawingBufferHeight","createVAO","shaderProgram","nativeVAO","_createNativeVAO","_createBuffer","uv","_bindNativeVAO","_supplyGeometryData","_unbindBuffers","draw","drawElements","TRIANGLES","UNSIGNED_SHORT","releaseVAO","_deleteNativeVAO","_deleteBuffer","getUniformLocations","program","uniforms","uniformLocations","locations","getUniformLocation","_getCommonUniformLocations","updateCommonUniforms","entity","mvMatrix","uniformMatrix4fv","uMVMatrix","uPMatrix","updateVRUniforms","eyeIndex","uEye","uniform1f","updateUniforms","uniform","needsUpdate","releaseShaderResources","deleteProgram","useProgram","createProgram","vertexShader","fragmentShader","vs","_compileShader","VERTEX_SHADER","fs","FRAGMENT_SHADER","attachShader","bindAttribLocation","linkProgram","getProgramParameter","LINK_STATUS","getShaderParameter","COMPILE_STATUS","getShaderInfoLog","getProgramInfoLog","deleteShader","createWebGLTexture","texData","texture","createTexture","bindTexture","TEXTURE_2D","texParameteri","TEXTURE_MIN_FILTER","TEXTURE_MAG_FILTER","TEXTURE_WRAP_S","TEXTURE_WRAP_T","gl2","texStorage2D","RGBA8","createWebGLCubeTexture","TEXTURE_CUBE_MAP","attributes","getContextAttributes","xrCompatible","xrLayer","XRWebGLLayer","updateRenderState","bindXRFrame","bindFramebuffer","FRAMEBUFFER","framebuffer","useDefaultFrameBuffer","createBuffer","buffer","deleteBuffer","createVertexArray","ext","createVertexArrayOES","bindVertexArray","bindVertexArrayOES","deleteVertexArray","deleteVertexArrayOES","_supplyIndiciesData","_supplyAttributeData","vertices","uvs","bufferData","data","STATIC_DRAW","attribute","attribLocation","getAttribLocation","vertexAttribPointer","itemSize","FLOAT","enableVertexAttribArray","shader","createShader","shaderSource","compileShader","webglIdentifiers","contextAttributes","preserveDrawingBuffer","antialias","onWebglContextCreationError","e","statusMessage","identifier","getContext","WebGLRenderer","_elementSize","pixelRatio","_pixelRatio","canvasSize","devicePixelRatio","clientWidth","clientHeight","projection","mesh","getMesh","renderVR","vr","eyeParams","eye","View360","_rootEl","_vr","_hotspot","plugins","_plugins","_projection","_initialized","initialized","_autoplay","autoInit","_autoInit","autoResize","_autoResize","canvasSelector","_canvasSelector","tabIndex","_tabIndex","_animator","updateCamera","renderFrame","autoPlayer","_emit","_renderFrameOnDemand","getTexture","_renderVRFrame","_delta","_autoResizer","_addEventHandlers","releaseAllResources","plugin","animator","_bindComponentEvents","_resizeComponents","_loadTexture","_applyProjection","hasAttribute","addPlugins","push","removePlugins","pluginIdx","splice","eventName","params","evtParams","prevProjection","applyTexture","updateControl","contentLoader","events","evtName","controlEventsToPropagate","VERSION","Object3D","fromRotationTranslationScale","LoadingSpinner","_startLoading","_container","_detachElements","parentElement","removeChild","_createElements","ring","RING","ControlBarItem","CONTROL_BAR_DEFAULT_CLASS","CONTROLS_ROOT","CONTROLS_BG","CONTROLS_MAIN","CONTROLS_TOP","CONTROLS_BOTTOM","CONTROLS_MID","CONTROLS_LEFT","CONTROLS_RIGHT","CONTROLS_FLOAT_LEFT","CONTROLS_FLOAT_RIGHT","CONTROLS_BUTTON","PROGRESS_ROOT","VOLUME_ROOT","RANGE_ROOT","RANGE_TRACK","RANGE_THUMB","RANGE_FILLER","PLAY_BUTTON","PAUSE_BUTTON","UNMUTED_BUTTON","MUTED_BUTTON","FULLSCREEN_BUTTON","FULLSCREEN_EXIT_BUTTON","VR_BUTTON","GYRO_ENABLED","GYRO_DISABLED","VIDEO_TIME_DISPLAY","PIEVIEW_ROOT","FIXED","UNAVAILABLE","HIDDEN","CONTROL_BAR_ITEM_POSITION","TOP_LEFT","TOP_RIGHT","MAIN_TOP","MAIN_BOTTOM","MAIN_LEFT","MAIN_RIGHT","RangeControl","_onHold","_bbox","elX","scrollX","pageXOffset","clamepdX","thumbEl","_fixedClass","clampedX","_onRelease","track","thumb","filler","draggable","trackEl","fillerEl","left","right","bottom","top","updateStyle","clampedProgress","ProgressBar","_rangeControl","_onTimeUpdate","_video","_currentTime","_onDurationChange","controlBar","_controlBar","dispatchEvent","CustomEvent","detail","_wasPaused","_playPromise","_onControl","rangeControl","unavailableClass","PlayButton","_onClick","_paused","_onPlay","title","_onPause","VolumeControl","_updateDisplay","disabled","_onVolumeChange","_buttonEl","containerEl","buttonEl","FullscreenButton","_targetEl","_exitFullscreen","_requestFullscreen","_onFullscreenChange","_fullscreenAvailable","_addFullscreenHandlers","_removeFullscreenHandlers","some","request","call","VideoTime","_onCustomTimeChange","timeMinute","floor","timeSeconds","timeSecondsFormatted","durationMinute","durationSeconds","durationSecondsFormatted","innerText","PieView","resetCamera","_viewer","_updatePie","piePath","_piePathEl","rangeCircle","_rangeCircleEl","halfFov","pieRadius","pieDeg","pieOffset","isFinite","radius","rangeDiff","_createPieElements","rootClass","pieSVG","createElementNS","VRButton","GyroButton","_updateStyle","enableButton","AutoHide","hidden","contains","_hiddenClass","initialDelay","idleDelay","activationDelay","_isCursorInside","show","_hideAfterDelay","_isFullscreen","showTemporaliy","_isGrabbing","pointerType","_onVideoPlay","_onVideoPause","_initialDelay","_idleDelay","_timer","hide","_clearHideTimer","VideoControl","videoEl","keyPressed","_changeVideoTime","_changeVideoVolume","spacePressed","_toggleVideo","forward","increase","ControlBar","backgroundEl","_bgEl","items","_items","customItems","_customItems","autoHide","showBackground","clickToPlay","keyboardControls","progressBar","playButton","volumeButton","fullscreenButton","videoTime","pieView","vrButton","gyroButton","_onStaticClick","autoHider","_autoHider","_onNewSrcLoad","_updateBackground","_updateAutoHide","_updateKeyboardHandler","category","item","_createPositionWrappers","POSITION","_videoControl","panoRoot","controlsRoot","defaultItems","_createDefaultItems","_addItem","_clearItemElements","wrapper","_wrapperEl","nextSiblingIndex","sibling","nextSibling","insertBefore","floatLeftEl","floatRightEl","topWrapper","bottomWrapper","midWrapper","leftControlsWrapper","rightControlsWrapper","wrappers","firstChild","background","hiddenClass","_b","videoControl","Projection","_mesh","uTexture","Uniform","UniformTextureCube","cubemapOrder","_webglTexture","_cubemapOrder","deleteTexture","pixelStorei","UNPACK_FLIP_Y_WEBGL","uniform1i","activeTexture","TEXTURE0","texSubImage2D","TEXTURE_CUBE_MAP_POSITIVE_X","RGBA","UNSIGNED_BYTE","texImage2D","CubeTexturePainter","_size","_renderingOrder","_calcRenderingSize","surfaceIdx","row","_row","column","_column","renderingFace","drawImage","UniformCanvasCube","_painter","TriangleMesh","ShaderProgram","VertexData","Geometry","Float32Array","Uint16Array","CubeGeometry","rotateUV","oneThird","coords","r","c","coord","degree","ZERO","newOrder","CW_90","CCW_90","newCoords","uvIdx","acc","concat","CubemapProjection","cubemapFlipX","_cubemapFlipX","UniformTexture2D","CubestripProjection","CylinderGeometry","maxTheta","radialSegments","heightSegments","invRadialSegments","angleConst","yIdx","lngIdx","u","v","CylindricalProjection","partial","_partial","cylinderHeight","cylinderTheta","restrictedYaw","restrictedPitch","minZoom","EquiangularProjection","SphereGeometry","widthSegments","ANGLE_CORRECTION_FOR_CENTER_ALIGN","latIdx","sinTheta","cosTheta","phi","sinPhi","cosPhi","EquirectProjection","UniformFloat","PlaneGeometry","LittlePlanetProjection","REPEAT","uYaw","uPitch","uZoom","UniformVector4Array","uniform4fv","vector","StereoEquiProjection","_mode","mode","leftEye","rightEye","MODE","LEFT_RIGHT","uTexScaleOffset","TOP_BOTTOM","withMethods","attr","proto","getOwnPropertyNames","charAt","descriptor","getOwnPropertyDescriptor","defineProperty","args","getterDescriptor","get","getValidProps","propsObj","props","propName","VIEW360_METHODS","modules"],"mappings":"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"} \ No newline at end of file diff --git a/demo/release/latest/dist/view360.min.js b/demo/release/latest/dist/view360.min.js new file mode 100644 index 000000000..734ac56a5 --- /dev/null +++ b/demo/release/latest/dist/view360.min.js @@ -0,0 +1,2 @@ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("@egjs/component"),require("gl-matrix"),require("@egjs/imready")):"function"==typeof define&&define.amd?define(["@egjs/component","gl-matrix","@egjs/imready"],e):(t="undefined"!=typeof globalThis?globalThis:t||self).View360=e(t.Component,t.glMatrix,t.eg.ImReady)}(this,(function(t,e,i){"use strict";function s(t){return t&&t.__esModule?t:{default:t}}var n=s(t),o=s(i);function r(t,e,i,s){return new(i||(i=Promise))((function(n,o){function r(t){try{h(s.next(t))}catch(t){o(t)}}function a(t){try{h(s.throw(t))}catch(t){o(t)}}function h(t){var e;t.done?n(t.value):(e=t.value,e instanceof i?e:new i((function(t){t(e)}))).then(r,a)}h((s=s.apply(t,e||[])).next())}))}class a extends Error{constructor(t,e){super(t),Object.setPrototypeOf(this,a.prototype),this.name="View360Error",this.code=e}}const h={WRONG_TYPE:0,WRONG_OPTION:1,ELEMENT_NOT_FOUND:2,CANVAS_NOT_FOUND:3,WEBGL_NOT_SUPPORTED:4,FAILED_CREATE_CONTEXT_2D:5,PROVIDE_PROJECTION_FIRST:6,FAILED_LINKING_PROGRAM:7,INSUFFICIENT_ARGS:8};var l=h,c={WRONG_TYPE:(t,e)=>`${typeof t} is not a ${e.map((t=>`"${t}"`)).join(" or ")}.`,WRONG_OPTION:(t,e)=>`Bad option: given "${t}" for option "${e}".`,ELEMENT_NOT_FOUND:t=>`Element with selector "${t}" not found.`,CANVAS_NOT_FOUND:"The canvas element was not found inside the given root element.",WEBGL_NOT_SUPPORTED:"WebGL is not supported on this browser.",FAILED_CREATE_CONTEXT_2D:"Failed to create canvas 2D context",PROVIDE_PROJECTION_FIRST:'"projection" should be provided before initialization.',FAILED_LINKING_PROGRAM:(t,e)=>`Failed linking WebGL program - "${t}\nShader compile Log: ${e}`,INSUFFICIENT_ARGS:(t,e)=>`Insufficient arguments: given "${t}" for "${e}".`};const u="mousedown",_="mousemove",d="mouseup",m="touchstart",p="touchmove",g="touchend",v="wheel",E="resize",T="contextmenu",b="mouseenter",f="mouseleave",R="keydown",y="keyup",w="click",L="webglcontextcreationerror",C="webglcontextlost",x="webglcontextrestored",O="deviceorientation",I="devicemotion",A="orientationchange",S="play",P="pause",N="loadeddata",M="volumechange",D="timeupdate",U="durationchange",B="canplaythrough",F="transitionend",z="end",V="div",G="button";var k;!function(t){t[t.LEFT=0]="LEFT",t[t.MIDDLE=1]="MIDDLE",t[t.RIGHT=2]="RIGHT"}(k||(k={}));const Y="grab",H="grabbing",X="",j=["LEFT","UP","RIGHT","DOWN"];var W;!function(t){t[t.LEFT=37]="LEFT",t[t.UP=38]="UP",t[t.RIGHT=39]="RIGHT",t[t.DOWN=40]="DOWN"}(W||(W={}));const q={LEFT:"ArrowLeft",UP:"ArrowUp",RIGHT:"ArrowRight",DOWN:"ArrowDown"},K=["requestFullscreen","webkitRequestFullscreen","webkitRequestFullScreen","webkitCancelFullScreen","mozRequestFullScreen","msRequestFullscreen"],Z=["fullscreenElement","webkitFullscreenElement","webkitCurrentFullScreenElement","mozFullScreenElement","msFullscreenElement"],$=["exitFullscreen","webkitExitFullscreen","webkitCancelFullScreen","mozCancelFullScreen","msExitFullscreen"],Q=["fullscreenchange","webkitfullscreenchange","mozfullscreenchange","MSFullscreenChange"],J={CONTAINER:"view360-container",CANVAS:"view360-canvas",CTX_LOST:"view360-ctx-lost",IN_VR:"view360-vr-presenting",HOTSPOT_CONTAINER:"view360-hotspots",HOTSPOT:"view360-hotspot",HOTSPOT_VISIBLE:"view360-hotspot-visible",HOTSPOT_FLIP_X:"view360-hotspot-flip-x",HOTSPOT_FLIP_Y:"view360-hotspot-flip-y"},tt={READY:"ready",LOAD_START:"loadStart",LOAD:"load",PROJECTION_CHANGE:"projectionChange",RESIZE:"resize",BEFORE_RENDER:"beforeRender",RENDER:"render",INPUT_START:"inputStart",INPUT_END:"inputEnd",VIEW_CHANGE:"viewChange",STATIC_CLICK:"staticClick",VR_START:"vrStart",VR_END:"vrEnd"},et={LINEAR:t=>t,SINE_WAVE:t=>Math.sin(t*Math.PI*2),EASE_OUT_CUBIC:t=>1-Math.pow(1-t,3),EASE_OUT_BOUNCE:t=>{const e=7.5625,i=2.75;return t<1/i?e*t*t:t<2/i?e*(t-=1.5/i)*t+.75:t<2.5/i?e*(t-=2.25/i)*t+.9375:e*(t-=2.625/i)*t+.984375}};var it;const st="animationEnd",nt="inputStart",ot="change",rt="inputEnd",at="enable",ht="disable",lt="staticClick",ct=Math.PI/180,ut=180/Math.PI,_t=et.EASE_OUT_CUBIC,dt=300,mt={min:-1/0,max:1/0},pt={min:-90,max:90},gt={min:.6,max:10};var vt;!function(t){t[t.ZERO=0]="ZERO",t[t.CW_90=1]="CW_90",t[t.CCW_90=2]="CCW_90",t[t.CW_180=3]="CW_180"}(vt||(vt={}));const Et="view360videotimechange",Tt="http://www.w3.org/2000/svg",bt="immersive-vr",ft="local",Rt=null!==(it=Number.EPSILON)&&void 0!==it?it:2220446049250313e-31,yt=t=>"string"==typeof t,wt=(t,e=V)=>{const i=document.createElement(e);return i.classList.add(t),i},Lt=(t,e)=>{let i=null;if(yt(t)){const s=(e||document).querySelector(t);if(!s)return null;i=s}else(s=t)&&s.nodeType===Node.ELEMENT_NODE&&(i=t);var s;return i},Ct=(t,e,i)=>Math.max(Math.min(t,i),e),xt=(t,e,i)=>t*(1-i)+e*i,Ot=(t,e,i)=>{const s=Math.abs(i-e);if(ti){t=e+(t-i)%s}return t},It=(t,e)=>{for(let i=0;i"object"==typeof t?t:{},St=(t,e)=>2*Math.atan(Math.tan(.5*t)/e),Pt=(t,e,i="RLUDFB")=>i.split("").map((t=>e.indexOf(t))).map((e=>t[e])),Nt=()=>{if(!document)return!1;for(const t of Z)if(document[t])return!0;return!1},Mt=()=>!!DeviceMotionEvent&&"requestPermission"in DeviceMotionEvent&&window.isSecureContext,Dt=(t,i,s,n)=>{e.quat.identity(t);const o=Ct(s,-89.99,89.99);return e.quat.rotateY(t,t,i*ct),e.quat.rotateX(t,t,o*ct),e.quat.rotateZ(t,t,n*ct),t},Ut=t=>{const i=t[0],s=t[1],n=t[2],o=t[3],r=i*i+s*s+n*n+o*o,a=i*o-s*n;let h,l;if(a>.499995*r)h=Math.PI/2,l=2*Math.atan2(s,i);else if(a<-.499995*r)h=-Math.PI/2,l=-2*Math.atan2(s,i);else{const i=e.vec3.fromValues(0,0,1),s=e.vec3.fromValues(0,1,0);e.vec3.transformQuat(i,i,t),e.vec3.transformQuat(s,s,t);const n=Math.sqrt(i[0]*i[0]+i[2]*i[2]);h=Math.atan2(-i[1],n),l=Math.atan2(i[0],i[2])}return{pitch:Ct(h*ut,-90,90),yaw:Ot(l*ut,0,360)}};class Bt{get val(){return this._val}get start(){return this._start}get end(){return this._end}get progress(){return this._progress}get activated(){return this._activated}get duration(){return this._duration}set duration(t){this._duration=t}get loop(){return this._loop}set loop(t){this._loop=t}get range(){return this._range}get easing(){return this._easing}set easing(t){this._easing=t}constructor({duration:t=300,loop:e=!1,range:i={min:0,max:1},easing:s=_t}={}){this._duration=t,this._loop=e,this._range=i,this._easing=s,this._activated=!1,this.reset(0)}update(t){if(!this._activated)return this._val=this._end,0;const e=this._start,i=this._end,s=this._duration,n=this._val,o=this._loop,r=this._progress+t/s;this._progress=o?Ot(r,0,1):Ct(r,0,1);const a=this._easing(this._progress);return this._val=xt(e,i,a),!o&&this._progress>=1&&(this._activated=!1),this._val-n}reset(t){const e=this._range,i=Ct(t,e.min,e.max);this._start=i,this._end=i,this._val=i,this._progress=0,this._activated=!1}add(t){const e=this._range;this._start=Ct(this._start+t,e.min,e.max),this._end=Ct(this._end+t,e.min,e.max),this._val=Ct(this._val+t,e.min,e.max)}setNewEndByDelta(t){const e=this._range;this._start=this._val,this._end=Ct(this._end+t,e.min,e.max),this._progress=0,this._activated=!0}setRange(t,e){this._start=Ct(this._start,t,e),this._end=Ct(this._end,t,e),this._range={min:t,max:e}}}class Ft{get duration(){return this._motion.duration}set duration(t){this._motion.duration=t}get easing(){return this._motion.easing}set easing(t){this._motion.easing=t}constructor(t,e,i,{duration:s=300,easing:n=_t}={}){this._camera=t,this._motion=new Bt({duration:s,easing:n,range:{min:0,max:1}}),this._from=e,this._to=i,this._finishPromise=new Promise((t=>{this._finish=t})),this._motion.setNewEndByDelta(1)}getFinishPromise(){return this._finishPromise}update(t){const i=this._camera,s=this._from,n=this._to,o=this._motion;o.update(t);const r=o.val,a=e.quat.create(),h=xt(s.zoom,n.zoom,r);e.quat.slerp(a,s.rotation,n.rotation,r),i.rotate(a,h),r>=1&&this._finish()}}class zt extends n.default{get aspect(){return this._aspect}get changed(){return this._changed}get yawRange(){return this._initialYawRange}set yawRange(t){this._initialYawRange=t}get pitchRange(){return this._initialPitchRange}set pitchRange(t){this._initialPitchRange=t}get zoomRange(){return this._initialZoomRange}set zoomRange(t){this._initialZoomRange=t}constructor({initialYaw:t,initialPitch:i,initialZoom:s,yawRange:n,pitchRange:o,zoomRange:r,fov:a}){super(),this.yaw=t,this.pitch=i,this.zoom=s,this.rollOffset=0,this.initialYaw=t,this.initialPitch=i,this.initialZoom=s,this.position=e.vec3.create(),this.animation=null,this._up=e.vec3.fromValues(0,1,0),this._aspect=1,this._initialYawRange=n,this._initialPitchRange=o,this._initialZoomRange=r,this._yawRange=n,this._pitchRange=o,this._zoomRange=r,this.quaternion=e.quat.create(),this._updateQuaternion(),this.viewMatrix=e.mat4.create(),this.projectionMatrix=e.mat4.create(),this.fov=a,this._maxRenderHeight=-1}destroy(){this.off()}resize(t,e){const i=this._aspect;this._aspect=t/e,this._aspect!==i&&this.updateMatrix()}lookAt({yaw:t=this.yaw,pitch:i=this.pitch,zoom:s=this.zoom}){const n=e.quat.clone(this.quaternion),o=this.zoom;this.yaw=Ot(t,0,360),this.pitch=Ct(i,-90,90),this.zoom=s,this._updateQuaternion();const r=Math.abs(s-o);(!e.quat.equals(this.quaternion,n)||r>=10*Rt)&&this.updateMatrix()}rotate(t,i=this.zoom){const s=e.quat.normalize(e.quat.create(),t),n=e.quat.equals(this.quaternion,s);e.quat.copy(this.quaternion,s);const o=this.zoom,{yaw:r,pitch:a}=Ut(s);this.yaw=r,this.pitch=a,this.zoom=i;const h=Math.abs(i-o);(!n||h>=10*Rt)&&this.updateMatrix()}animateTo({yaw:t=this.yaw,pitch:i=this.pitch,zoom:s=this.zoom,duration:n=0,easing:o=_t}={}){return r(this,void 0,void 0,(function*(){if(this.yaw===t&&this.pitch===i&&this.zoom===s)return;const r={rotation:e.quat.clone(this.quaternion),zoom:this.zoom},a={rotation:Dt(e.quat.create(),t,i,this.rollOffset),zoom:s},h=new Ft(this,r,a,{duration:n,easing:o}),l=h.getFinishPromise();return this.animation=h,l.then((()=>{this.animation=null,this.trigger(st,{animation:h})})),l}))}restrictYawRange(t,e){this._yawRange={min:t,max:e}}restrictPitchRange(t,e){this._pitchRange={min:t,max:e}}restrictZoomRange(t,e){this._zoomRange={min:t,max:e}}restrictRenderHeight(t){this._maxRenderHeight=t}resetRange(){this._yawRange=this._initialYawRange,this._pitchRange=this._initialPitchRange,this._zoomRange=this._initialZoomRange,this._maxRenderHeight=-1}getYawRange(t){const e=this._yawRange,i=this._maxRenderHeight;if(!e)return mt;const s=.5*this.getHorizontalFov(t);let n=e.min,o=e.max;if(i>0){const t=St(s*ct,this._aspect),r=.5*i,a=Math.tan(t),h=Math.sqrt((1+r*r)/(1+a*a)),l=Math.atan(Math.tan(s*ct)*h)*ut;n=e.min+l,o=e.max-l}return n>o&&(n=0,o=0),{min:n,max:o}}getPitchRange(t){const e=this._pitchRange,i=this._maxRenderHeight;if(!e)return pt;let s=e.min,n=e.max;if(i>0){const i=.5*this.getVerticalFov(t);s=e.min+i,n=e.max-i}return s>n&&(s=0,n=0),{min:Math.max(s,-90),max:Math.min(n,90)}}getZoomRange(){var t;const e=null!==(t=this._zoomRange)&&void 0!==t?t:gt,i=this.getHorizontalFov(e.max),s=this.getHorizontalFov(e.min),n=this.getHorizontalFov(this.zoom);return{min:Math.max(i,1),max:Math.min(s,180),current:n}}getHorizontalFov(t=this.zoom){return this._getZoomedHorizontalFov(t)*ut}getVerticalFov(t=this.zoom){const e=this._aspect,i=this._getZoomedHorizontalFov(t);return St(i,e)*ut}fovToZoom(t){const e=this.fov;return Math.tan(ct*e*.5)/Math.tan(ct*t*.5)}updateMatrix(){const t=this._up,i=this._aspect,s=this.viewMatrix,n=this.projectionMatrix,o=this.position,r=this.quaternion,a=e.vec3.create(),h=e.vec3.fromValues(0,0,-1);e.vec3.transformQuat(h,h,r),e.vec3.transformQuat(a,t,r);const l=this._getZoomedHorizontalFov(),c=St(l,i);e.mat4.lookAt(s,o,h,a),e.mat4.perspective(n,c,i,.1,100),this._changed=!0}onFrameRender(){this._changed=!1}_updateQuaternion(){Dt(this.quaternion,this.yaw,this.pitch,this.rollOffset)}_getZoomedHorizontalFov(t=this.zoom){return 2*Math.atan(Math.tan(ct*this.fov*.5)/t)}}class Vt extends n.default{constructor(){super(),this._onMouseDown=t=>{const e=this._el;e&&t.button===k.LEFT&&(t.preventDefault(),e.focus?e.focus():window.focus(),this._prevPos[0]=t.clientX,this._prevPos[1]=t.clientY,window.addEventListener(_,this._onMouseMove,!1),window.addEventListener(d,this._onMouseUp,!1),this.trigger(nt,{srcEvent:t,isTouch:!1,isKeyboard:!1}))},this._onMouseMove=t=>{t.preventDefault();const e=t.clientX,i=t.clientY,s=this._prevPos,n=e-s[0],o=i-s[1];this.trigger(ot,{delta:{x:n,y:o},isTouch:!1,isKeyboard:!1}),s[0]=e,s[1]=i},this._onMouseUp=()=>{this._prevPos[0]=0,this._prevPos[1]=0,window.removeEventListener(_,this._onMouseMove,!1),window.removeEventListener(d,this._onMouseUp,!1),this.trigger(rt,{isTouch:!1,isKeyboard:!1,scrolling:!1})},this._el=null,this._prevPos=[0,0]}enable(t){this._el||(t.addEventListener(u,this._onMouseDown),this._el=t)}disable(){const t=this._el;t&&(t.removeEventListener(u,this._onMouseDown),window.removeEventListener(_,this._onMouseMove,!1),window.removeEventListener(d,this._onMouseUp,!1),this._el=null)}}class Gt extends n.default{get scrollable(){return this._scrollable}set scrollable(t){this._scrollable=t}constructor(){super(),this._onTouchStart=t=>{if(t.touches.length>1||this._scrolling)return;const e=t.touches[0];this._isFirstTouch=!0,this._prevPos[0]=e.clientX,this._prevPos[1]=e.clientY,this.trigger(nt,{srcEvent:t,isTouch:!0,isKeyboard:!1})},this._onTouchMove=t=>{if(t.touches.length>1||this._scrolling)return;const e=t.touches[0],i=this._scrollable,s=this._prevPos,n=e.clientX,o=e.clientY,r=n-s[0],a=o-s[1];if(this._isFirstTouch){if(i&&!Nt()&&Math.abs(a)>Math.abs(r))return void(this._scrolling=!0);this._isFirstTouch=!1}!1!==t.cancelable&&t.preventDefault(),this.trigger(ot,{delta:{x:r,y:a},isTouch:!0,isKeyboard:!1}),s[0]=n,s[1]=o},this._onTouchEnd=t=>{if(0!==t.touches.length)return;const e=t.touches[0],i=this._prevPos;e?(i[0]=e.clientX,i[1]=e.clientY):(i[0]=0,i[1]=0,this.trigger(rt,{isTouch:!0,isKeyboard:!1,scrolling:this._scrolling})),!1!==t.cancelable&&t.preventDefault(),this._scrolling=!1},this._el=null,this._prevPos=[0,0],this._isFirstTouch=!1,this._scrolling=!1,this._scrollable=!1}enable(t){this._el||(t.addEventListener(m,this._onTouchStart,{passive:!1}),t.addEventListener(p,this._onTouchMove,{passive:!1}),t.addEventListener(g,this._onTouchEnd),this._el=t)}disable(){const t=this._el;t&&(t.removeEventListener(m,this._onTouchStart),t.removeEventListener(p,this._onTouchMove),t.removeEventListener(g,this._onTouchEnd),this._el=null)}}class kt extends n.default{get active(){const t=this._pressed;return t.LEFT||t.UP||t.RIGHT||t.DOWN}constructor(){super(),this._onKeyDown=t=>{if(t.location!==KeyboardEvent.DOM_KEY_LOCATION_STANDARD)return;this._updateKeyPress(t,!0);const e=this._getPressedKeyCount();e<=0||(t.preventDefault(),1!==e||t.repeat||this.trigger(nt,{srcEvent:t,isTouch:!1,isKeyboard:!0}))},this._onKeyUp=t=>{if(t.location!==KeyboardEvent.DOM_KEY_LOCATION_STANDARD)return;this._updateKeyPress(t,!1);this._getPressedKeyCount()>0||this.trigger(rt,{isTouch:!1,isKeyboard:!0,scrolling:!1})},this._el=null,this._clearPressedKeys()}enable(t){this._el||(t.addEventListener(R,this._onKeyDown),t.addEventListener(y,this._onKeyUp),this._el=t,this._clearPressedKeys())}disable(){const t=this._el;t&&(t.removeEventListener(R,this._onKeyDown),t.removeEventListener(y,this._onKeyUp),this._el=null,this._clearPressedKeys())}update(){const t=this._getDeltaByPressedKeys();0===t.x&&0===t.y||this.trigger(ot,{delta:t,isTouch:!1,isKeyboard:!0})}_clearPressedKeys(){this._pressed=j.reduce(((t,e)=>Object.assign(Object.assign({},t),{[e]:!1})),{})}_updateKeyPress(t,e){const i=this._pressed,s=null!=t.keyCode?W[t.keyCode]:q[t.key];s&&(i[s]=e)}_getPressedKeyCount(){return j.filter((t=>this._pressed[t])).length}_getDeltaByPressedKeys(){const t=this._pressed;let e=0,i=0;return t.LEFT&&(e+=1),t.RIGHT&&(e-=1),t.UP&&(i+=1),t.DOWN&&(i-=1),{x:e,y:i}}}class Yt extends n.default{get enabled(){return this._enabled}get enableBlocked(){return this._enableBlocked}get animating(){return this._keyboardInput.active||this._xMotion.activated||this._yMotion.activated}get yaw(){return this._xMotion}get pitch(){return this._yMotion}get scrollable(){return this._touchInput.scrollable}set scrollable(t){this._touchInput.scrollable=t}get pointerScale(){return this._pointerScale}set pointerScale(t){this._pointerScale=t}get keyboardScale(){return this._keyboardScale}set keyboardScale(t){this._keyboardScale=t}get duration(){return this._duration}set duration(t){this._duration=t,this._xMotion.duration=t,this._yMotion.duration=t}get easing(){return this._easing}set easing(t){this._easing=t,this._xMotion.easing=t,this._yMotion.easing=t}get disablePitch(){return this._disablePitch}set disablePitch(t){this._disablePitch=t}get disableYaw(){return this._disableYaw}set disableYaw(t){this._disableYaw=t}get disableKeyboard(){return this._disableKeyboard}set disableKeyboard(t){this._disableKeyboard=t}constructor(t,e,{duration:i=300,easing:s=_t,pointerScale:n=[1,1],keyboardScale:o=[1,1],disablePitch:r=!1,disableYaw:a=!1,disableKeyboard:h=!1}={}){super(),this._onInputStart=t=>{this._changedWhileDragging=!1,this.trigger(nt,Object.assign(Object.assign({},t),{inputType:"rotate"}))},this._onChange=t=>{const e=t.delta,i=1/this._zoomScale,s=this._screenScale,n=this._keyboardScale,o=this._pointerScale;let r;r=t.isKeyboard?[n[0]*i,n[1]*i]:[o[0]*s[0]*i,o[1]*s[1]*i];const a=e.x*r[0],h=e.y*r[1];this._xMotion.setNewEndByDelta(a),this._yMotion.setNewEndByDelta(h),this._changedWhileDragging=!0},this._onInputEnd=t=>{this.trigger(rt,Object.assign(Object.assign({},t),{inputType:"rotate"})),this._changedWhileDragging||t.isKeyboard||t.scrolling||this.trigger(lt,{isTouch:t.isTouch}),this._changedWhileDragging=!1},this._controlEl=t,this._pointerScale=n,this._keyboardScale=o,this._duration=i,this._easing=s,this._disablePitch=r,this._disableYaw=a,this._disableKeyboard=h,this._enableBlocked=e,this._mouseInput=new Vt,this._touchInput=new Gt,this._keyboardInput=new kt,this._xMotion=new Bt({duration:i,range:mt,easing:s}),this._yMotion=new Bt({duration:i,range:pt,easing:s}),this._screenScale=[1,1],this._zoomScale=1,this._enabled=!1,this._changedWhileDragging=!1,this._bindInputs()}destroy(){this.disable(),this._mouseInput.off(),this._touchInput.off(),this._keyboardInput.off(),this.off(),this._changedWhileDragging=!1}update(t){if(!this._enabled)return;const e=this._xMotion,i=this._yMotion,s=this._keyboardInput;this._disableKeyboard||s.update(),this._disablePitch||i.update(t),this._disableYaw||e.update(t)}updateRange(t,e){const i=t.getYawRange(e),s=t.getPitchRange(e);this._xMotion.setRange(i.min,i.max),this._yMotion.setRange(s.min,s.max)}setZoomScale(t){this._zoomScale=t}resize(t,e,i,s){const n=St(t*ct,e)*ut;this._screenScale[0]=t/i,this._screenScale[1]=n/s}enable(){if(this._enabled)return;const t=this._controlEl;this._mouseInput.enable(t),this._touchInput.enable(t),this._keyboardInput.enable(t),this._enabled=!0,this._enableBlocked=!1,this.trigger(at,{control:this,updateCursor:!0})}disable(){this._enabled&&(this._mouseInput.disable(),this._touchInput.disable(),this._keyboardInput.disable(),this._enabled=!1,this.trigger(ht,{updateCursor:!0}))}sync(t){this.updateRange(t,t.zoom),this._xMotion.reset(t.yaw),this._yMotion.reset(t.pitch)}_bindInputs(){const t=this._mouseInput,e=this._touchInput,i=this._keyboardInput;t.on(nt,this._onInputStart),t.on(ot,this._onChange),t.on(rt,this._onInputEnd),e.on(nt,this._onInputStart),e.on(ot,this._onChange),e.on(rt,this._onInputEnd),i.on(nt,this._onInputStart),i.on(ot,this._onChange),i.on(rt,this._onInputEnd)}}class Ht extends n.default{get scrollable(){return this._scrollable}set scrollable(t){this._scrollable=t}constructor(){super(),this._onWheel=t=>{const e=this._scrollable;if(0===t.deltaY||e)return;t.preventDefault(),t.stopPropagation(),this._inputTimer<0?this.trigger(nt,{srcEvent:t,isTouch:!1,isKeyboard:!1}):this._clearTimer();const i=this._baseScale*t.deltaY;this.trigger(ot,{delta:i,isTouch:!1,isKeyboard:!1}),this._inputTimer=window.setTimeout((()=>{this.trigger(rt,{isTouch:!1,isKeyboard:!1,scrolling:!1}),this._inputTimer=-1}),dt)},this._el=null,this._baseScale=.04,this._scrollable=!1,this._inputTimer=-1}enable(t){this._el||(t.addEventListener(v,this._onWheel,{passive:!1,capture:!1}),this._el=t,this._clearTimer())}disable(){const t=this._el;t&&(t.removeEventListener(v,this._onWheel,!1),this._el=null,this._clearTimer())}_clearTimer(){window.clearTimeout(this._inputTimer),this._inputTimer=-1}}class Xt extends n.default{constructor(){super(),this._onTouchMove=t=>{const e=t.touches;if(2!==e.length)return;if(!t.cancelable)return;t.preventDefault(),t.stopPropagation();const i=this._prevDistance,s=[e[0].pageX-e[1].pageX,e[0].pageY-e[1].pageY],n=Math.sqrt(s[0]*s[0]+s[1]*s[1])*this._baseScale,o=this._isFirstTouch?0:n-i;this._isFirstTouch&&this.trigger(nt,{srcEvent:t,isTouch:!0,isKeyboard:!1}),this._prevDistance=n,this._isFirstTouch=!1,this.trigger(ot,{delta:o,isTouch:!0,isKeyboard:!1})},this._onTouchEnd=t=>{0===t.touches.length&&(this._isFirstTouch||this.trigger(rt,{isTouch:!0,isKeyboard:!1,scrolling:!1}),this._prevDistance=-1,this._isFirstTouch=!0)},this._el=null,this._baseScale=-.2,this._prevDistance=-1,this._isFirstTouch=!0}enable(t){this._el||(t.addEventListener(p,this._onTouchMove,{passive:!1,capture:!1}),t.addEventListener(g,this._onTouchEnd),this._el=t,this._prevDistance=-1,this._isFirstTouch=!0)}disable(){const t=this._el;t&&(t.removeEventListener(p,this._onTouchMove,!1),t.removeEventListener(g,this._onTouchEnd),this._el=null)}}class jt extends n.default{get enabled(){return this._enabled}get enableBlocked(){return this._enableBlocked}get animating(){return this._motion.activated}get zoom(){return this._motion.val}get scrollable(){return this._wheelInput.scrollable}set scrollable(t){this._wheelInput.scrollable=t}get range(){return this._motion.range}get scale(){return this._scale}set scale(t){this._scale=t}get duration(){return this._motion.duration}get easing(){return this._motion.easing}constructor(t,e,{scale:i=1,duration:s=300,easing:n=_t}={}){super(),this._onInputStart=t=>{this.trigger(nt,Object.assign(Object.assign({},t),{inputType:"zoom"}))},this._onChange=({delta:t})=>{const e=t*this._scale;this._motion.setNewEndByDelta(e)},this._onInputEnd=t=>{this.trigger(rt,Object.assign(Object.assign({},t),{inputType:"zoom"}))},this._scale=i,this._controlEl=t,this._enableBlocked=e,this._wheelInput=new Ht,this._pinchInput=new Xt,this._motion=new Bt({duration:s,easing:n,range:mt}),this._enabled=!1,this._bindInputs()}destroy(){this.disable(),this._wheelInput.off(),this._pinchInput.off(),this.off()}update(t){if(!this._enabled)return;this._motion.update(t)}enable(){if(this._enabled)return;const t=this._controlEl;this._wheelInput.enable(t),this._pinchInput.enable(t),this._enabled=!0,this._enableBlocked=!1,this.trigger(at,{control:this,updateCursor:!1})}disable(){this._enabled&&(this._wheelInput.disable(),this._pinchInput.disable(),this._enabled=!1,this.trigger(ht,{updateCursor:!1}))}sync(t){const e=this._motion,i=t.getZoomRange();e.setRange(i.min,i.max),e.reset(i.current)}_bindInputs(){const t=this._wheelInput,e=this._pinchInput;t.on(nt,this._onInputStart),t.on(ot,this._onChange),t.on(rt,this._onInputEnd),e.on(nt,this._onInputStart),e.on(ot,this._onChange),e.on(rt,this._onInputEnd)}}const Wt={PITCH_DELTA:1,YAW_DELTA_BY_ROLL:2,YAW_DELTA_BY_YAW:3};Wt[Wt.PITCH_DELTA]={targetAxis:[0,1,0],meshPoint:[0,0,1]},Wt[Wt.YAW_DELTA_BY_ROLL]={targetAxis:[0,1,0],meshPoint:[1,0,0]},Wt[Wt.YAW_DELTA_BY_YAW]={targetAxis:[1,0,0],meshPoint:[0,0,1]};class qt extends n.default{get enabled(){return this._enabled}get orientationUpdated(){return this._orientationUpdated}get ignoreRoll(){return this._ignoreRoll}set ignoreRoll(t){this._ignoreRoll=t}constructor(){super(),this._onDeviceOrientation=t=>{const e=this._orientation,{alpha:i,beta:s,gamma:n}=t;null!=i&&null!=s&&null!=n&&(e.alpha=i,e.beta=s,e.gamma=n,this._orientationUpdated=!0,this._needsCalibrate&&(this._needsCalibrate=!1,this._calibrateSensor()))},this._updateScreenOrientation=()=>{window.screen&&window.screen.orientation&&void 0!==window.screen.orientation.angle?this._screenOrientation=screen.orientation.angle:void 0!==window.orientation?this._screenOrientation=window.orientation>=0?window.orientation:360+window.orientation:this._screenOrientation=0},this.quaternion=e.quat.create(),this._orientation={alpha:0,beta:90,gamma:0},this._yawOrigin=0,this._yawOffset=0,this._orientationUpdated=!1,this._screenOrientation=0,this._needsCalibrate=!0,this._enabled=!1}enable(){this._enabled||(window.addEventListener(O,this._onDeviceOrientation),window.addEventListener(A,this._updateScreenOrientation),this._updateScreenOrientation(),this._orientationUpdated=!1,this._needsCalibrate=!0,this._enabled=!0)}disable(){this._enabled&&(window.removeEventListener(O,this._onDeviceOrientation),window.removeEventListener(A,this._updateScreenOrientation),this._enabled=!1)}update(){this._updateRotation(),this._orientationUpdated=!1}collectDelta(){if(!this._orientationUpdated)return{pitch:0,yaw:0};const t=e.quat.clone(this.quaternion);return this._updateRotation(),this._orientationUpdated=!1,this._toEulerDelta(t,this.quaternion)}setInitialRotation(t){this._yawOrigin=t}_calibrateSensor(){const t=this._yawOrigin,e=this.quaternion;this._yawOffset=0,this._updateRotation();const{yaw:i}=Ut(e);this._yawOffset=i-t,this._updateRotation(),this._needsCalibrate=!1}_updateRotation(){const t=this.quaternion,{alpha:i,beta:s,gamma:n}=this._orientation;e.quat.identity(t),e.quat.rotateY(t,t,(i-this._yawOffset)*ct),e.quat.rotateX(t,t,s*ct),e.quat.rotateZ(t,t,-n*ct);const o=e.quat.create(),r=.5*-this._screenOrientation*ct,a=e.quat.fromValues(-Math.sqrt(.5),0,0,Math.sqrt(.5));e.quat.set(o,0,Math.sin(r),0,Math.cos(r)),e.quat.multiply(t,t,o),e.quat.multiply(t,t,a),e.quat.normalize(t,t)}_toEulerDelta(t,e){return{yaw:this._getDeltaYaw(t,e),pitch:this._getDeltaPitch(t,e)}}_getDeltaYaw(t,e){const i=this._getRotationDelta(t,e,Wt.YAW_DELTA_BY_YAW);return this._getRotationDelta(t,e,Wt.YAW_DELTA_BY_ROLL)*Math.sin(this._extractPitchFromQuat(e))+i}_getDeltaPitch(t,e){return this._getRotationDelta(t,e,Wt.PITCH_DELTA)}_getRotationDelta(t,i,s){const n=e.vec3.fromValues(Wt[s].targetAxis[0],Wt[s].targetAxis[1],Wt[s].targetAxis[2]),o=Wt[s].meshPoint,r=e.quat.clone(t),a=e.quat.clone(i);e.quat.normalize(r,r),e.quat.normalize(a,a);let h=e.vec3.fromValues(0,0,1),l=e.vec3.fromValues(0,0,1);e.vec3.transformQuat(h,h,r),e.vec3.transformQuat(l,l,a),e.vec3.transformQuat(n,n,a);const c=e.vec3.dot(n,e.vec3.cross(e.vec3.create(),h,l))>0?1:-1,u=e.vec3.fromValues(o[0],o[1],o[2]);let _;_=s!==Wt.YAW_DELTA_BY_YAW?e.vec3.fromValues(0,c,0):e.vec3.fromValues(c,0,0),e.vec3.transformQuat(u,u,a),e.vec3.transformQuat(_,_,a);const d=u,m=_,p=e.vec3.create();e.vec3.cross(p,d,m),e.vec3.normalize(p,p);const g=p[0],v=p[1],E=p[2];l=e.vec3.fromValues(o[0],o[1],o[2]),e.vec3.transformQuat(l,l,a),h=e.vec3.fromValues(o[0],o[1],o[2]),e.vec3.transformQuat(h,h,r);let T=Math.abs(h[0]*g+h[1]*v+h[2]*E);const b=e.vec3.create();e.vec3.subtract(b,h,e.vec3.scale(e.vec3.create(),p,T));let f=(b[0]*l[0]+b[1]*l[1]+b[2]*l[2])/(e.vec3.length(b)*e.vec3.length(l));f>1&&(f=1);const R=Math.acos(f),y=e.vec3.cross(e.vec3.create(),l,b);let w;T=g*y[0]+v*y[1]+E*y[2],w=s!==Wt.YAW_DELTA_BY_YAW?T>0?1:-1:T<0?1:-1;return R*w*c*ut}_extractPitchFromQuat(t){const i=e.vec3.fromValues(0,0,1);return e.vec3.transformQuat(i,i,t),-1*Math.atan2(i[1],Math.sqrt(Math.pow(i[0],2)+Math.pow(i[2],2)))}}class Kt extends n.default{get enabled(){return this._input.enabled}get enableBlocked(){return this._enableBlocked}get animating(){return this._input.enabled&&this._input.orientationUpdated}get ignoreRoll(){return this._ignoreRoll}set ignoreRoll(t){this._ignoreRoll=t}static isAvailable(){return r(this,void 0,void 0,(function*(){if(!DeviceMotionEvent)return!1;let t;return Promise.race([new Promise((e=>{t=t=>{e(t.rotationRate&&null!=t.rotationRate.alpha)},window.addEventListener(I,t)})),new Promise((t=>{setTimeout((()=>t(!1)),1e3)}))]).then((e=>(window.removeEventListener(I,t),e)))}))}static requestSensorPermission(){return r(this,void 0,void 0,(function*(){return!Mt()||DeviceMotionEvent.requestPermission().then((t=>"granted"===t)).catch((()=>!1))}))}constructor(t,{ignoreRoll:e=!0}={}){super(),this._enableBlocked=t,this._ignoreRoll=e,this._input=new qt}destroy(){this.disable(),this._input.off(),this.off()}update(t,e,i,s){this._ignoreRoll?this._updateYawPitch(t,e,i,s):this._updateQuaternion(t,s)}enable(){this._input.enabled||(this._input.enable(),this._enableBlocked=!1,this.trigger(at,{control:this,updateCursor:!1}))}disable(){this._input.enabled&&(this._input.disable(),this.trigger(ht,{updateCursor:!1}))}sync(){}_updateYawPitch(t,e,i,s){const n=this._input;if(!n.enabled)return;const{yaw:o,pitch:r}=n.collectDelta();e.add(o),i.add(r),t.lookAt({yaw:e.val,pitch:i.val,zoom:s})}_updateQuaternion(t,e){const i=this._input;i.enabled&&(i.update(),t.rotate(i.quaternion,e))}}class Zt{get useGrabCursor(){return this._useGrabCursor}set useGrabCursor(t){t!==this._useGrabCursor&&(this._useGrabCursor=t,t&&this._enabled?this._setCursor(Y):t||this._setCursor(X))}get disableContextMenu(){return this._disableContextMenu}set disableContextMenu(t){t!==this._disableContextMenu&&(this._disableContextMenu=t,t&&this._enabled?this._blockContextMenu():t||this._restoreContextMenu())}get scrollable(){return this._rotateControl.scrollable}set scrollable(t){this._rotateControl.scrollable=t}get wheelScrollable(){return this._zoomControl.scrollable}set wheelScrollable(t){this._zoomControl.scrollable=t}get ignoreZoomScale(){return this._ignoreZoomScale}set ignoreZoomScale(t){this._ignoreZoomScale=t}get enabled(){return this._enabled}get rotate(){return this._rotateControl}get zoom(){return this._zoomControl}get gyro(){return this._gyroControl}get animating(){return this._rotateControl.animating||this._zoomControl.animating||this._gyroControl.animating}constructor(t,e,{useGrabCursor:i,scrollable:s,wheelScrollable:n,disableContextMenu:o,rotate:r,zoom:a,gyro:h}){this._preventContextMenu=t=>{t.preventDefault()},this._onInputStart=t=>{this._useGrabCursor&&!t.isKeyboard&&this._setCursor(H)},this._onInputEnd=t=>{this._useGrabCursor&&!t.isKeyboard&&this._setCursor(Y)},this._onEnable=({control:t,updateCursor:e})=>{e&&this._useGrabCursor&&this._setCursor(Y),t.sync(this._camera)},this._onDisable=({updateCursor:t})=>{t&&this._setCursor(X)},this._onCameraAnimationEnd=({animation:t})=>{t.getFinishPromise().then((()=>{this.sync()}))},this._useGrabCursor=i,this._disableContextMenu=o,this._camera=e,this._controlEl=t,this._ignoreZoomScale=!1,this._enabled=!1,this._rotateControl=new Yt(t,!r,At(r)),this._zoomControl=new jt(t,!a,At(a)),this._gyroControl=new Kt(!h,At(h)),this._rotateControl.scrollable=s,this._zoomControl.scrollable=n,this._bindEvents()}destroy(){this.disable(),this._rotateControl.destroy(),this._zoomControl.destroy(),this._setCursor(X)}resize(t,e){const i=this._camera;this._rotateControl.resize(i.fov,i.aspect,t,e)}enable(){return r(this,void 0,void 0,(function*(){this._enabled||(this._rotateControl.enableBlocked||this._rotateControl.enable(),this._zoomControl.enableBlocked||this._zoomControl.enable(),this._gyroControl.enableBlocked||(yield Kt.isAvailable())&&this._gyroControl.enable(),this.sync(),this._disableContextMenu&&this._blockContextMenu(),this._enabled=!0)}))}disable(){this._enabled&&(this._rotateControl.disable(),this._zoomControl.disable(),this._gyroControl.disable(),this._restoreContextMenu(),this._enabled=!1)}update(t){const e=this._camera,i=this._rotateControl,s=this._zoomControl,n=this._gyroControl;s.update(t);const o=(r=e.fov,a=s.zoom,Math.tan(ct*r*.5)/Math.tan(ct*a*.5));var r,a;const h=this._ignoreZoomScale?1:Math.max(o,1);i.setZoomScale(h),i.updateRange(e,o),i.update(t);const l=i.yaw,c=i.pitch;n.enabled?n.update(e,l,c,o):e.lookAt({yaw:l.val,pitch:c.val,zoom:o})}sync(){const t=this._camera;this._zoomControl.sync(t),this._rotateControl.sync(t)}_blockContextMenu(){this._controlEl.addEventListener(T,this._preventContextMenu)}_restoreContextMenu(){this._controlEl.removeEventListener(T,this._preventContextMenu)}_setCursor(t){if(!this._useGrabCursor&&t!==X)return;this._controlEl.style.cursor=t}_bindEvents(){const t=this._rotateControl,e=this._zoomControl;t.on(nt,this._onInputStart),t.on(rt,this._onInputEnd),t.on(at,this._onEnable),t.on(ht,this._onDisable),e.on(at,this._onEnable),e.on(ht,this._onDisable),this._camera.on(st,this._onCameraAnimationEnd)}}class $t{constructor({width:t,height:e,flipY:i}){this.width=t,this.height=e,this.flipY=i,this.wrapS=WebGLRenderingContext.CLAMP_TO_EDGE,this.wrapT=WebGLRenderingContext.CLAMP_TO_EDGE}destroy(){}isVideo(){return!1}isCube(){return!1}}class Qt extends $t{constructor({source:t,width:e,height:i,flipY:s}){super({width:e,height:i,flipY:s}),this.source=t}}class Jt extends Qt{destroy(){const t=this.source;t.pause(),t.removeAttribute("src"),t.load()}isVideo(){return!0}isPaused(){const t=this.source;return t.paused||t.ended||t.readyState<=2}hasAudio(){const t=this.source;return t.audioTracks?t.audioTracks.length>0:null!=t.webkitAudioDecodedByteCount?t.webkitAudioDecodedByteCount>0:null==t.mozHasAudio||t.mozHasAudio}}class te extends $t{constructor({sources:t,width:e,height:i,flipY:s}){super({width:e,height:i,flipY:s}),this.sources=t}isCube(){return!0}}class ee{constructor(){this._loadChecker=new o.default}load(t,e){return r(this,void 0,void 0,(function*(){if(e)return this.loadVideo(t,At(e));if(Array.isArray(t)&&t.length>1)return this.loadCubeImage(t);{const e=Array.isArray(t)?t[0]:t;return this.loadImage(e)}}))}loadImage(t){return r(this,void 0,void 0,(function*(){const e=this._toImageArray(t);return this._load(e,(t=>{const i=e[0];t(new Qt({source:i,width:i.naturalWidth,height:i.naturalHeight,flipY:!0}))}))}))}loadCubeImage(t){return r(this,void 0,void 0,(function*(){const e=this._toImageArray(t);return this._load(e,(t=>{t(new te({sources:e,width:e[0].naturalWidth,height:e[0].naturalHeight,flipY:!1}))}))}))}loadVideo(t,e){return r(this,void 0,void 0,(function*(){const i=Object.assign({autoplay:!0,muted:!0,loop:!1,volume:1},e),s=this._toVideoElement(t,i);return this._load([s],(t=>{const{autoplay:e,muted:n}=i;s.currentTime=0,e&&n&&s.play().catch((()=>{})),t(new Jt({source:s,width:s.videoWidth,height:s.videoHeight,flipY:!0}))}))}))}_load(t,e){const i=this._loadChecker;return new Promise(((s,n)=>{i.once("ready",(t=>{t.errorCount>0||e(s)})),i.once("error",n),i.check(t)}))}_toImageArray(t){return(Array.isArray(t)?t:[t]).map((t=>{if(yt(t)){const e=new Image;return e.crossOrigin="anonymous",e.src=t,e}return t}))}_toVideoElement(t,{muted:e,loop:i,volume:s}){if(t instanceof HTMLVideoElement)return t;const n=document.createElement("video");n.crossOrigin="anonymous",n.playsInline=!0,n.setAttribute("webkit-playsinline",""),n.muted=e,n.volume=s,n.loop=i,Array.isArray(t)?t.forEach((t=>this._appendSourceElement(n,t))):this._appendSourceElement(n,t);return n.querySelectorAll("source").length>0&&n.readyState<1&&n.load(),n}_appendSourceElement(t,e){if(e instanceof HTMLSourceElement)return e;const i=document.createElement("source");i.src=e,t.appendChild(i)}}class ie{constructor(t,e=window){this.maxDeltaTime=t,this._context=e,this._rafId=-1,this._rafTimer=-1,this._lastUpdateTime=-1}start(t){const e=this._context;if(!e||!t)return;if(this._rafId>=0||this._rafTimer>=0)return;const i=(s,n)=>{const o=Date.now(),r=Math.min(o-this._lastUpdateTime,1e3*this.maxDeltaTime);t(r,n),this._lastUpdateTime=o,this._rafId=e.requestAnimationFrame(i)};this._lastUpdateTime=Date.now(),this._rafId=e.requestAnimationFrame(i)}stop(){this._rafId>=0&&this._context.cancelAnimationFrame(this._rafId),this._rafTimer>=0&&clearTimeout(this._rafTimer),this._rafId=-1,this._rafTimer=-1}changeContext(t){this.stop(),this._context=t}}class se{get useResizeObserver(){return this._useResizeObserver}get enabled(){return this._enabled}constructor(t,e){this._skipFirstResize=(()=>{let t=!0;return()=>{t?t=!1:this._onResize()}})(),this._useResizeObserver=t,this._enabled=!1,this._resizeObserver=null,this._onResize=e}enable(t){if(this._enabled&&this.disable(),this._useResizeObserver&&window.ResizeObserver){const e=t.getBoundingClientRect(),i=0!==e.width||0!==e.height,s=new ResizeObserver(i?this._skipFirstResize:this._onResize);s.observe(t),this._resizeObserver=s}else window.addEventListener(E,this._onResize);return this._enabled=!0,this}disable(){if(!this._enabled)return this;const t=this._resizeObserver;return t?(t.disconnect(),this._resizeObserver=null):window.removeEventListener(E,this._onResize),this._enabled=!1,this}}class ne{get enabled(){return this._enabled}get enableBlocked(){return this._enableBlocked}get playing(){return this._enabled&&!this._interrupted}get delay(){return this._delay}set delay(t){this._delay=t}get delayOnMouseLeave(){return this._delayOnMouseLeave}set delayOnMouseLeave(t){this._delayOnMouseLeave=t}get speed(){return this._speed}set speed(t){this._speed=t}get pauseOnHover(){return this._pauseOnHover}set pauseOnHover(t){this._pauseOnHover=t}get canInterrupt(){return this._canInterrupt}set canInterrupt(t){this._canInterrupt=t}get disableOnInterrupt(){return this._disableOnInterrupt}set disableOnInterrupt(t){this._disableOnInterrupt=t}constructor(t,e,i){this._onInputStart=()=>{this._canInterrupt&&(this._interrupted=!0,this._clearTimeout())},this._onInputEnd=()=>{this._setUninterruptedAfterDelay(this._delay)},this._onGyroEnable=()=>{this.disable()},this._onMouseEnter=()=>{this._pauseOnHover&&(this._interrupted=!0,this._hovering=!0)},this._onMouseLeave=()=>{this._pauseOnHover&&(this._hovering=!1,this._setUninterruptedAfterDelay(this._delayOnMouseLeave))},this._camera=t.camera,this._control=t.control,this._element=e,this._enabled=!1,this._interrupted=!1,this._interruptionTimer=-1,this._hovering=!1;const{delay:s=2e3,delayOnMouseLeave:n=0,speed:o=1,pauseOnHover:r=!1,canInterrupt:a=!0,disableOnInterrupt:h=!1}=At(i);this._enableBlocked=!i,this._delay=s,this._delayOnMouseLeave=n,this._speed=o,this._pauseOnHover=r,this._canInterrupt=a,this._disableOnInterrupt=h}destroy(){this.disable()}update(t){if(!this._enabled)return;if(this._interrupted)return void(this._disableOnInterrupt&&this.disable());const e=this._camera,i=-this._speed*t/100;e.yaw=Ot(e.yaw+i,0,360)}enable(){const t=this._control,e=this._element;this._enabled||t.gyro.enabled||(t.rotate.on(nt,this._onInputStart),t.rotate.on(rt,this._onInputEnd),t.zoom.on(nt,this._onInputStart),t.zoom.on(rt,this._onInputEnd),t.gyro.on(at,this._onGyroEnable),e.addEventListener(b,this._onMouseEnter,!1),e.addEventListener(f,this._onMouseLeave,!1),this._enabled=!0,this._enableBlocked=!1)}enableAfterDelay(){this.enable(),this._interrupted=!0,this._setUninterruptedAfterDelay(this._delay)}disable(){if(!this._enabled)return;const t=this._control,e=this._element;t.rotate.off(nt,this._onInputStart),t.rotate.off(rt,this._onInputEnd),t.zoom.off(nt,this._onInputStart),t.zoom.off(rt,this._onInputEnd),t.gyro.off(at,this._onGyroEnable),e.removeEventListener(b,this._onMouseEnter,!1),e.removeEventListener(f,this._onMouseLeave,!1),this._enabled=!1,this._interrupted=!1,this._hovering=!1,this._clearTimeout()}_setUninterruptedAfterDelay(t){this._hovering||(this._clearTimeout(),t>0?this._interruptionTimer=window.setTimeout((()=>{this._interrupted=!1,this._interruptionTimer=-1}),t):(this._interrupted=!1,this._interruptionTimer=-1))}_clearTimeout(){this._interruptionTimer>=0&&(window.clearTimeout(this._interruptionTimer),this._interruptionTimer=-1)}}class oe extends n.default{constructor(t,e={}){super(),this.destroy=()=>{this.exit(),this.off()},this._onSessionEnd=()=>{this.exit(),this.trigger(tt.VR_END)},this._xrSession=null,this._xrRefSpace=null,this._ctx=t,this._options=e}isAvailable(){return r(this,void 0,void 0,(function*(){const t=window.navigator.xr;return!!t&&t.isSessionSupported(bt).then((t=>t)).catch((()=>!1))}))}enter(){return r(this,void 0,void 0,(function*(){const t=this._ctx,e=window.navigator.xr;if(!e)return;yield Kt.requestSensorPermission();const i=Object.assign({requiredFeatures:[ft]},this._options);yield t.makeXRCompatible();const s=yield e.requestSession(bt,i);t.bindXRLayer(s);const n=yield s.requestReferenceSpace(ft);this._setSession(s,n),this.trigger(tt.VR_START,{session:s})}))}exit(){const t=this._xrSession;t&&t.end().catch((()=>{})),this._xrSession=null,this._xrRefSpace=null}canRender(t){const e=this._xrRefSpace;if(!e)return!1;return!!t.getViewerPose(e)}getEyeParams(t){const e=t.session,i=t.getViewerPose(this._xrRefSpace);if(!i)return null;const s=e.renderState.baseLayer;return s?i.views.map((t=>({viewport:s.getViewport(t),vMatrix:t.transform.inverse.matrix,pMatrix:t.projectionMatrix}))):null}_setSession(t,e){this._xrSession=t,this._xrRefSpace=e,t.addEventListener(z,this._onSessionEnd)}}class re{constructor(t,e){this.element=t,this.position=e}}class ae{constructor(t,e,{zoom:i=!1}){this._containerEl=Lt(`.${J.HOTSPOT_CONTAINER}`,t),this._renderer=e,this._hotspots=[],this._zoom=i}refresh(){const t=this._containerEl;if(!t)return;const e=[].slice.apply(t.querySelectorAll(`.${J.HOTSPOT}`));this._hotspots=e.map((t=>this._parseHotspot(t)))}render(t){const i=this._hotspots,s=.5*this._renderer.width,n=.5*this._renderer.height,o=t.zoom,r="translate(-50%, -50%)",a=this._zoom?`scale(${o})`:"";i.forEach((i=>{const o=i.position,h=e.vec3.create();if(e.vec3.copy(h,o),e.vec3.transformMat4(h,h,t.viewMatrix),e.vec3.transformMat4(h,h,t.projectionMatrix),h[2]>1||h[2]<0)return void i.element.classList.remove(J.HOTSPOT_VISIBLE);const l=e.vec2.fromValues(h[0]*s+s,-h[1]*n+n);i.element.classList.add(J.HOTSPOT_VISIBLE),i.element.style.transform=[r,`translate(${l[0]}px, ${l[1]}px)`,a].join(" ")}))}_parseHotspot(t){const i=t.dataset.yaw,s=t.dataset.pitch,n=t.dataset.position;if(i||s){const e=i?parseFloat(i):0,n=s?parseFloat(s):0,o=this._yawPitchToVec3(e,n);return new re(t,o)}if(n){const i=n.split(" ").map((t=>parseFloat(t)));if(i.length<3)throw new a(c.INSUFFICIENT_ARGS(n,'hotspot attribute "data-position"'),l.INSUFFICIENT_ARGS);return new re(t,e.vec3.fromValues(i[0],i[1],i[2]))}{const i=e.vec3.fromValues(0,0,-1);return new re(t,i)}}_yawPitchToVec3(t,i){const s=t*ct,n=i*ct,o=e.vec3.create();return o[1]=Math.sin(n),o[2]=Math.cos(n),o[0]=o[2]*Math.sin(-s),o[2]=-o[2]*Math.cos(-s),o}}class he{get count(){return this.geometry.indicies.count}constructor(t,e,i){this.obj=t,this.geometry=e,this.buffers=i}}class le{get canvas(){return this._canvas}get maxTextureSize(){return this._maxTextureSize}get isWebGL2(){return this._isWebGL2}get supportVAO(){return this._isWebGL2||!!this._extensions.vao}get lost(){return this._contextLost}get debug(){return this._debug}constructor(t,e){this._onContextLost=()=>{this._canvas.classList.add(J.CTX_LOST),this._contextLost=!0},this._onContextRestore=()=>{this._canvas.classList.remove(J.CTX_LOST),this._contextLost=!1},this._canvas=t,this._contextLost=!1,this._debug=e,this._extensions={vao:null,loseContext:null}}init(){const t=this._canvas,{gl:e,isWebGL2:i}=this._getContext(t);this._gl=e,this._maxTextureSize=e.getParameter(e.MAX_TEXTURE_SIZE),this._isWebGL2=i,this._isWebGL2||(this._extensions.vao=e.getExtension("OES_vertex_array_object")),this._extensions.loseContext=e.getExtension("WEBGL_lose_context"),t.addEventListener(C,this._onContextLost),t.addEventListener(x,this._onContextRestore)}destroy(){const t=this._gl,e=this._canvas;t&&(t.bindBuffer(t.ARRAY_BUFFER,null),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,null)),e.removeEventListener(C,this._onContextLost),e.removeEventListener(x,this._onContextRestore)}forceLoseContext(){const t=this._extensions.loseContext;t&&t.loseContext()}forceRestoreContext(){const t=this._extensions.loseContext;t&&t.restoreContext()}clear(){const t=this._gl;t.clear(t.COLOR_BUFFER_BIT)}resize(){const t=this._gl;t.viewport(0,0,t.drawingBufferWidth,t.drawingBufferHeight)}viewport(t,e,i,s){this._gl.viewport(t,e,i,s)}createVAO(t,e){const i=this._createNativeVAO(),s=new he(i,t,{indicies:this._createBuffer(),position:this._createBuffer(),uv:this._createBuffer()});return i&&(this._bindNativeVAO(i),this._supplyGeometryData(s,e),this._bindNativeVAO(null),this._unbindBuffers()),s}draw(t,e){const i=this._gl;t.obj?this._bindNativeVAO(t.obj):this._supplyGeometryData(t,e),i.drawElements(i.TRIANGLES,t.count,i.UNSIGNED_SHORT,0),t.obj?this._bindNativeVAO(null):this._unbindBuffers()}releaseVAO(t){t.obj&&this._deleteNativeVAO(t.obj),this._deleteBuffer(t.buffers.indicies),this._deleteBuffer(t.buffers.position),this._deleteBuffer(t.buffers.uv)}getUniformLocations(t,e){const i=this._gl,s=Object.keys(e).reduce(((e,s)=>(e[s]=i.getUniformLocation(t,s),e)),{});return Object.assign(Object.assign({},this._getCommonUniformLocations(t)),s)}updateCommonUniforms(t,i,s){const n=this._gl,o=s.uniformLocations,r=t.matrix,a=e.mat4.create();e.mat4.multiply(a,i.viewMatrix,r),n.uniformMatrix4fv(o.uMVMatrix,!1,a),n.uniformMatrix4fv(o.uPMatrix,!1,i.projectionMatrix)}updateVRUniforms(t,e,i,s){const n=this._gl,o=t.uniformLocations;n.uniformMatrix4fv(o.uMVMatrix,!1,e),n.uniformMatrix4fv(o.uPMatrix,!1,i),o.uEye&&n.uniform1f(o.uEye,s)}updateUniforms(t){const e=this._gl,i=t.uniforms,s=t.uniformLocations;for(const t in i){const n=i[t],o=s[t];n&&(n.needsUpdate&&n.update(e,o,this._isWebGL2))}}releaseShaderResources(t){const e=this._gl,i=t.uniforms;for(const t in i){const s=i[t];s&&(s.needsUpdate&&s.destroy(e))}e.deleteProgram(t.program)}useProgram(t){this._gl.useProgram(t.program)}createProgram(t,e){const i=this._gl,s=i.createProgram(),n=this._compileShader(i.VERTEX_SHADER,t),o=this._compileShader(i.FRAGMENT_SHADER,e);if(i.attachShader(s,n),i.attachShader(s,o),i.bindAttribLocation(s,0,"position"),i.bindAttribLocation(s,1,"uv"),i.linkProgram(s),this._debug&&!i.getProgramParameter(s,i.LINK_STATUS)){let t=null;throw i.getShaderParameter(n,i.COMPILE_STATUS)?i.getShaderParameter(o,i.COMPILE_STATUS)||(t=i.getShaderInfoLog(o)):t=i.getShaderInfoLog(n),new a(c.FAILED_LINKING_PROGRAM(i.getProgramInfoLog(s),t),l.FAILED_LINKING_PROGRAM)}return i.deleteShader(n),i.deleteShader(o),s}createWebGLTexture(t){const e=this._gl,i=e.createTexture();if(e.bindTexture(e.TEXTURE_2D,i),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,t.wrapS),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,t.wrapT),!t.isVideo()&&this._isWebGL2){const i=e;i.texStorage2D(i.TEXTURE_2D,1,i.RGBA8,t.width,t.height)}return i}createWebGLCubeTexture(t,e){const i=this._gl,s=i.createTexture();if(i.bindTexture(i.TEXTURE_CUBE_MAP,s),i.texParameteri(i.TEXTURE_CUBE_MAP,i.TEXTURE_MIN_FILTER,i.LINEAR),i.texParameteri(i.TEXTURE_CUBE_MAP,i.TEXTURE_MAG_FILTER,i.LINEAR),i.texParameteri(i.TEXTURE_CUBE_MAP,i.TEXTURE_WRAP_S,t.wrapS),i.texParameteri(i.TEXTURE_CUBE_MAP,i.TEXTURE_WRAP_T,t.wrapT),this._isWebGL2){const t=i;t.texStorage2D(t.TEXTURE_CUBE_MAP,1,t.RGBA8,e,e)}return s}makeXRCompatible(){return r(this,void 0,void 0,(function*(){const t=this._gl,e=t.getContextAttributes();e&&!0!==e.xrCompatible&&(yield t.makeXRCompatible())}))}bindXRLayer(t){const e=this._gl,i=new XRWebGLLayer(t,e);t.updateRenderState({baseLayer:i})}bindXRFrame(t){const e=this._gl,i=t.session.renderState.baseLayer;e.bindFramebuffer(e.FRAMEBUFFER,i.framebuffer)}useDefaultFrameBuffer(){const t=this._gl;t.bindFramebuffer(t.FRAMEBUFFER,null)}_createBuffer(){return this._gl.createBuffer()}_deleteBuffer(t){return this._gl.deleteBuffer(t)}_createNativeVAO(){const t=this._gl;if(this._isWebGL2)return t.createVertexArray();{const t=this._extensions.vao;return(null==t?void 0:t.createVertexArrayOES())||null}}_bindNativeVAO(t){const e=this._gl;if(this._isWebGL2)e.bindVertexArray(t);else{const e=this._extensions.vao;null==e||e.bindVertexArrayOES(t)}}_deleteNativeVAO(t){const e=this._gl;if(this._isWebGL2)e.deleteVertexArray(t);else{const e=this._extensions.vao;null==e||e.deleteVertexArrayOES(t)}}_supplyGeometryData(t,e){const i=t.geometry;this._supplyIndiciesData(i.indicies,t.buffers.indicies),this._supplyAttributeData(i.vertices,e.program,"position",t.buffers.position),this._supplyAttributeData(i.uvs,e.program,"uv",t.buffers.uv)}_unbindBuffers(){const t=this._gl;t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,null),t.bindBuffer(t.ARRAY_BUFFER,null)}_supplyIndiciesData(t,e){const i=this._gl;i.bindBuffer(i.ELEMENT_ARRAY_BUFFER,e),i.bufferData(i.ELEMENT_ARRAY_BUFFER,t.data,i.STATIC_DRAW)}_supplyAttributeData(t,e,i,s){const n=this._gl,o=n.getAttribLocation(e,i);o<0||(n.bindBuffer(n.ARRAY_BUFFER,s),n.bufferData(n.ARRAY_BUFFER,t.data,n.STATIC_DRAW),n.vertexAttribPointer(o,t.itemSize,n.FLOAT,!1,0,0),n.enableVertexAttribArray(o))}_compileShader(t,e){const i=this._gl,s=i.createShader(t);return i.shaderSource(s,e),i.compileShader(s),s}_getCommonUniformLocations(t){const e=this._gl;return{uMVMatrix:e.getUniformLocation(t,"uMVMatrix"),uPMatrix:e.getUniformLocation(t,"uPMatrix")}}_getContext(t){const e=["webgl2","webgl","experimental-webgl","webkit-3d","moz-webgl"];let i=null,s=!1;const n={preserveDrawingBuffer:!1,antialias:!1},o=t=>t.statusMessage;t.addEventListener(L,o);for(const o of e){try{i=t.getContext(o,n),s="webgl2"===o}catch(t){}if(i)break}if(t.removeEventListener(L,o),!i)throw new a(c.WEBGL_NOT_SUPPORTED,l.WEBGL_NOT_SUPPORTED);return{gl:i,isWebGL2:s}}}class ce{get canvas(){return this._canvas}get width(){return this._elementSize.x}get height(){return this._elementSize.y}get pixelRatio(){return this._pixelRatio}get aspect(){return this._elementSize.x/this._elementSize.y}constructor(t,e){this._canvas=t,this._elementSize={x:0,y:0},this._pixelRatio=1,this.ctx=new le(t,e)}destroy(){const t=this._canvas;this.ctx.destroy(),t.width=1,t.height=1}resize(){const t=this._canvas,e=this._elementSize,i=window.devicePixelRatio;e.x=t.clientWidth,e.y=t.clientHeight,t.width=e.x*i,t.height=e.y*i,this._pixelRatio=i,this.ctx.resize()}render(t,e){const i=this.ctx,s=t.getMesh();!i.lost&&s&&(i.clear(),i.useProgram(s.program),i.updateCommonUniforms(s,e,s.program),t.update(e),i.updateUniforms(s.program),i.draw(s.vao,s.program))}renderVR(t,i,s){const n=this.ctx,o=t.getMesh(),r=i.getEyeParams(s);r&&o&&(n.bindXRFrame(s),n.useProgram(o.program),n.updateUniforms(o.program),r.forEach(((t,i)=>{const s=t.viewport,r=e.mat4.multiply(e.mat4.create(),t.vMatrix,o.matrix);n.viewport(s.x,s.y,s.width,s.height),n.updateVRUniforms(o.program,r,t.pMatrix,i),n.draw(o.vao,o.program)})))}}class ue extends n.default{get rootEl(){return this._rootEl}get renderer(){return this._renderer}get camera(){return this._camera}get control(){return this._control}get vr(){return this._vr}get hotspot(){return this._hotspot}get plugins(){return this._plugins}get projection(){return this._projection}set projection(t){this._initialized&&t?this.load(t):this._projection=t}get initialized(){return this._initialized}get autoplay(){return this._autoplay}get autoInit(){return this._autoInit}get autoResize(){return this._autoResize}get canvasSelector(){return this._canvasSelector}get useResizeObserver(){return this._useResizeObserver}get tabIndex(){return this._tabIndex}set tabIndex(t){const e=this._renderer.canvas;this._tabIndex=t,null!=t?e.tabIndex=t:e.removeAttribute("tabindex")}get maxDeltaTime(){return this._animator.maxDeltaTime}set maxDeltaTime(t){this._animator.maxDeltaTime=t}get debug(){return this._debug}set debug(t){this._debug=t}get initialYaw(){return this._camera.initialYaw}set initialYaw(t){this._camera.initialYaw=t}get initialPitch(){return this._camera.initialPitch}set initialPitch(t){this._camera.initialPitch=t}get initialZoom(){return this._camera.initialZoom}set initialZoom(t){this._camera.initialZoom=t}get yawRange(){return this._camera.yawRange}set yawRange(t){this._camera.yawRange=t,this._projection&&this._projection.updateCamera(this._camera)}get pitchRange(){return this._camera.pitchRange}set pitchRange(t){this._camera.pitchRange=t,this._projection&&this._projection.updateCamera(this._camera)}get zoomRange(){return this._camera.zoomRange}set zoomRange(t){this._camera.zoomRange=t,this._projection&&this._projection.updateCamera(this._camera)}get fov(){return this._camera.fov}set fov(t){const e=this._camera,i=this._control;e.fov=t,e.updateMatrix(),i.sync()}get rotate(){return this._control.rotate}get zoom(){return this._control.zoom}get gyro(){return this._control.gyro}get useGrabCursor(){return this._control.useGrabCursor}set useGrabCursor(t){this._control.useGrabCursor=t}get disableContextMenu(){return this._control.disableContextMenu}set disableContextMenu(t){this._control.disableContextMenu=t}get scrollable(){return this._control.scrollable}set scrollable(t){this._control.scrollable=t}get wheelScrollable(){return this._control.wheelScrollable}set wheelScrollable(t){this._control.wheelScrollable=t}constructor(t,{projection:e=null,initialYaw:i=0,initialPitch:s=0,initialZoom:n=1,yawRange:o=null,pitchRange:r=null,zoomRange:h=null,fov:u=90,useGrabCursor:_=!0,disableContextMenu:d=!1,rotate:m=!0,zoom:p=!0,gyro:g=!1,scrollable:v=!0,wheelScrollable:E=!1,autoplay:T=!1,hotspot:b={},autoInit:f=!0,autoResize:R=!0,canvasSelector:y="canvas",useResizeObserver:w=!0,on:L={},plugins:C=[],maxDeltaTime:x=1/30,tabIndex:O=0,debug:I=!1}={}){super(),this.renderFrame=t=>{const e=this._camera,i=this._renderer,s=this._control,n=this._hotspot,o=this._autoplay,r=this._projection;r&&(this._emit(tt.BEFORE_RENDER),o.playing&&(o.update(t),s.sync()),e.animation?e.animation.update(t):s.update(t),i.render(r,e),n.render(e),e.changed&&this._emit(tt.VIEW_CHANGE,{yaw:e.yaw,pitch:e.pitch,zoom:e.zoom,quaternion:[e.quaternion[0],e.quaternion[1],e.quaternion[2],e.quaternion[3]]}),e.onFrameRender(),this._emit(tt.RENDER))},this._renderFrameOnDemand=t=>{var e;const i=this._camera,s=this._control,n=this._autoplay,o=null===(e=this._projection)||void 0===e?void 0:e.getTexture();this._initialized&&o&&(i.animation||s.animating||n.playing||o.isVideo())&&this.renderFrame(t)},this._renderVRFrame=(t,e)=>{const i=this._vr,s=this._projection,n=this._renderer;s&&(this._emit(tt.BEFORE_RENDER),n.renderVR(s,i,e),this._emit(tt.RENDER))},this._rootEl=((t,e)=>{const i=Lt(t,e);if(!i)throw yt(t)?new a(c.ELEMENT_NOT_FOUND(t),l.ELEMENT_NOT_FOUND):new a(c.WRONG_TYPE(t,["HTMLElement","string"]),l.WRONG_TYPE);return i})(t),this._plugins=C,this._initialized=!1,this._autoInit=f,this._autoResize=R,this._canvasSelector=y,this._useResizeObserver=w,this._tabIndex=O,this._debug=I;const A=((t,e)=>{const i=t.querySelector(e);if(!i)throw new a(c.CANVAS_NOT_FOUND,l.CANVAS_NOT_FOUND);return i})(this._rootEl,y);this._renderer=new ce(A,I),this._camera=new zt({initialYaw:i,initialPitch:s,initialZoom:n,fov:u,yawRange:o,pitchRange:r,zoomRange:h}),this._control=new Zt(A,this._camera,{useGrabCursor:_,scrollable:v,wheelScrollable:E,disableContextMenu:d,rotate:m,zoom:p,gyro:g}),this._animator=new ie(x),this._autoplay=new ne(this,A,T),this._projection=e,this._autoResizer=new se(w,(()=>this.resize())),this._vr=new oe(this._renderer.ctx),this._hotspot=new ae(this._rootEl,this._renderer,b),this._addEventHandlers(L),e&&f&&this.init()}destroy(){this._camera.destroy(),this._animator.stop(),this._renderer.destroy(),this._control.destroy(),this._autoResizer.disable(),this._projection&&(this._projection.releaseAllResources(this._renderer.ctx),this._projection=null),this._plugins.forEach((t=>t.destroy(this))),this._initialized=!1}init(){return r(this,void 0,void 0,(function*(){if(!this._projection)throw new a(c.PROVIDE_PROJECTION_FIRST,l.PROVIDE_PROJECTION_FIRST);const t=this._renderer,e=this._camera,i=this._control,s=this._animator,n=this._hotspot,o=this._projection,r=t.canvas;this._bindComponentEvents(),t.ctx.init(),this._resizeComponents(),e.updateMatrix(),this._autoResize&&this._autoResizer.enable(r),this._autoplay.enableBlocked||this._autoplay.enable(),this._plugins.forEach((t=>{t.init(this)}));const h=yield this._loadTexture(o);this._applyProjection(o,h,null),n.refresh(),s.start(this._renderFrameOnDemand),yield i.enable(),null==this._tabIndex||r.hasAttribute("tabIndex")||(r.tabIndex=this._tabIndex),this._initialized=!0,this.renderFrame(0),this._emit(tt.READY)}))}load(t){return r(this,void 0,void 0,(function*(){if(!t)return!1;if(this._initialized){const e=yield this._loadTexture(t);this._applyProjection(t,e,this._projection),this.renderFrame(0)}else this._projection=t,this.init();return!0}))}resize(){if(!this._initialized)return;this._resizeComponents(),this.renderFrame(0);const{width:t,height:e}=this._renderer;this._emit(tt.RESIZE,{width:t,height:e})}addPlugins(...t){this._initialized&&t.forEach((t=>{t.init(this)})),this._plugins.push(...t)}removePlugins(...t){t.forEach((t=>{const e=this._plugins.indexOf(t);e<0||(t.destroy(this),this._plugins.splice(e,1))}))}_emit(t,...e){const i=e?e[0]:{};this.trigger(t,Object.assign({type:t,target:this},i))}_applyProjection(t,e,i){const s=this._camera,n=this._control,o=this._renderer;i&&i.releaseAllResources(this._renderer.ctx),t.applyTexture(o.ctx,e),t.updateCamera(s),t.updateControl(n),this._projection=t,this._emit(tt.PROJECTION_CHANGE,{projection:t})}_loadTexture(t){return r(this,void 0,void 0,(function*(){const e=new ee,{src:i,video:s}=t;this._emit(tt.LOAD_START,{src:i,video:s});const n=yield e.load(i,s);return this._emit(tt.LOAD,{src:i,video:s}),n}))}_resizeComponents(){const t=this._renderer,e=this._camera,i=this._control;t.resize(),e.resize(t.width,t.height),i.resize(t.width,t.height)}_addEventHandlers(t){Object.keys(t).forEach((e=>{this.on(e,t[e])}))}_bindComponentEvents(){const t=this._rootEl,e=this._control,i=this._animator,s=this._renderer,n=this._vr;[lt,nt,rt].forEach((t=>{e.rotate.on(t,(e=>{this._emit(t,e)})),e.zoom.on(t,(e=>{this._emit(t,e)}))})),n.on(tt.VR_START,(e=>{t.classList.add(J.IN_VR),i.changeContext(e.session),i.start(this._renderVRFrame),this._emit(tt.VR_START)})),n.on(tt.VR_END,(()=>{t.classList.remove(J.IN_VR),s.ctx.useDefaultFrameBuffer(),i.changeContext(window),i.start(this._renderFrameOnDemand),this.resize(),this._emit(tt.VR_END)}))}}ue.VERSION="4.0.0-beta.4";class _e{constructor(){this.matrix=e.mat4.create(),this.rotation=e.quat.create(),this.position=e.vec3.fromValues(0,0,0),this.scale=e.vec3.fromValues(1,1,1)}updateMatrix(){e.mat4.fromRotationTranslationScale(this.matrix,this.rotation,this.position,this.scale)}}class de{constructor({className:t={}}={}){this._startLoading=({target:t})=>{t.rootEl.appendChild(this._container),t.initialized?t.once(tt.LOAD,this._detachElements):t.once(tt.READY,this._detachElements)},this._detachElements=({target:t})=>{const e=this._container;e&&e.parentElement===t.rootEl&&t.rootEl.removeChild(e)},this.className=t,this._container=this._createElements()}init(t){t.on(tt.LOAD_START,this._startLoading)}destroy(t){t.off(tt.LOAD_START,this._startLoading),this._detachElements({target:t})}_createElements(){const t=Object.assign(Object.assign({},this.className),de.DEFAULT_CLASS),e=wt(t.CONTAINER),i=wt(t.RING);return e.appendChild(i),e}}de.DEFAULT_CLASS={CONTAINER:"view360-spinner",RING:"view360-spinner-ring"};class me{constructor(t){this.position=t.position,this.order=t.order}}const pe={CONTROLS_ROOT:"view360-controls",CONTROLS_BG:"view360-controls-background",CONTROLS_MAIN:"view360-controls-main",CONTROLS_TOP:"view360-controls-top",CONTROLS_BOTTOM:"view360-controls-bottom",CONTROLS_MID:"view360-controls-mid",CONTROLS_LEFT:"view360-controls-left",CONTROLS_RIGHT:"view360-controls-right",CONTROLS_FLOAT_LEFT:"view360-controls-float-left",CONTROLS_FLOAT_RIGHT:"view360-controls-float-right",CONTROLS_BUTTON:"view360-controls-button",PROGRESS_ROOT:"view360-controls-progress",VOLUME_ROOT:"view360-controls-volume",RANGE_ROOT:"view360-range",RANGE_TRACK:"view360-range-track",RANGE_THUMB:"view360-range-thumb",RANGE_FILLER:"view360-range-filler",PLAY_BUTTON:"view360-controls-play",PAUSE_BUTTON:"view360-controls-pause",UNMUTED_BUTTON:"view360-controls-unmuted",MUTED_BUTTON:"view360-controls-muted",FULLSCREEN_BUTTON:"view360-controls-fullscreen",FULLSCREEN_EXIT_BUTTON:"view360-controls-fullscreen-exit",VR_BUTTON:"view360-controls-vr",GYRO_ENABLED:"view360-controls-gyro-enabled",GYRO_DISABLED:"view360-controls-gyro-disabled",VIDEO_TIME_DISPLAY:"view360-controls-time",PIEVIEW_ROOT:"view360-controls-pie",FIXED:"view360-controls-fixed",UNAVAILABLE:"view360-controls-unavailable",HIDDEN:"view360-controls-hidden"},ge={TOP_LEFT:"top-left",TOP_RIGHT:"top-right",MAIN_TOP:"main-top",MAIN_BOTTOM:"main-bottom",MAIN_LEFT:"main-left",MAIN_RIGHT:"main-right"};class ve extends n.default{constructor(){super(),this._onHold=({srcEvent:t,isTouch:e})=>{var i;const s=this._bbox;if(!s)return;const n=e?t.touches[0].pageX:t.pageX,o=s.x+(null!==(i=window.scrollX)&&void 0!==i?i:window.pageXOffset),r=Ct(n,o,o+s.width),a=(r-o)/s.width;this._motion.reset(r),this.thumbEl.classList.add(this._fixedClass),this.trigger(nt,a)},this._onChange=({delta:t})=>{var e;const i=this._motion,s=this._bbox;if(!s)return;i.setNewEndByDelta(t.x),i.update(1);const n=s.x+(null!==(e=window.scrollX)&&void 0!==e?e:window.pageXOffset),o=(Ct(i.val,n,n+s.width)-n)/s.width;this.trigger(ot,o)},this._onRelease=()=>{this._bbox&&(this.thumbEl.classList.remove(this._fixedClass),this.trigger(rt))};const t=document.createElement(V),e=document.createElement(V),i=document.createElement(V),s=document.createElement(V);t.draggable=!1,e.appendChild(s),e.appendChild(i),t.appendChild(e),this.rootEl=t,this.trackEl=e,this.thumbEl=i,this.fillerEl=s,this._mouseInput=new Vt,this._touchInput=new Gt,this._motion=new Bt({duration:1,range:mt,easing:t=>t}),this._bbox={x:0,y:0,width:0,height:0,left:0,right:0,bottom:0,top:0},this._fixedClass=pe.FIXED}init(t){const e=this._mouseInput,i=this._touchInput;this.rootEl.classList.add(t.RANGE_ROOT),this.trackEl.classList.add(t.RANGE_TRACK),this.thumbEl.classList.add(t.RANGE_THUMB),this.fillerEl.classList.add(t.RANGE_FILLER),this._fixedClass=t.FIXED,e.on(nt,this._onHold),i.on(nt,this._onHold),e.on(rt,this._onRelease),i.on(rt,this._onRelease),e.on(ot,this._onChange),i.on(ot,this._onChange),e.enable(this.rootEl),i.enable(this.rootEl),this.resize()}destroy(){const t=this._mouseInput,e=this._touchInput;this.rootEl.className="",this.trackEl.className="",this.thumbEl.className="",this.fillerEl.className="",t.off(),e.off(),t.disable(),e.disable()}resize(){this._bbox=this.trackEl.getBoundingClientRect()}updateStyle(t){const e=this._bbox.width,i=Ct(t,0,1);this.fillerEl.style.width=100*i+"%",this.thumbEl.style.transform=`translateX(${i*e}px)`}}class Ee extends me{get element(){return this._rangeControl.rootEl}constructor({position:t=ge.MAIN_TOP,order:e=9999}={}){super({position:t,order:e}),this._onResize=()=>{this._rangeControl.resize()},this._onTimeUpdate=()=>{const t=this._video;t&&(this._currentTime=t.source.currentTime,this._rangeControl.updateStyle(this._currentTime/this._duration))},this._onDurationChange=()=>{const t=this._video;t&&(this._duration=t.source.duration,this._rangeControl.updateStyle(this._currentTime/this._duration))},this._onHold=t=>{const e=this._video,i=this._controlBar;if(!e||!i)return;const s=e.isPaused();e.source.pause();const n=e.source.duration*t;e.source.currentTime=n,e.source.dispatchEvent(new CustomEvent(Et,{detail:{time:n}})),i.rootEl.classList.add(i.className.FIXED),this._wasPaused=!this._playPromise&&s},this._onControl=t=>{const e=this._video;if(!e)return;const i=e.source.duration*t;e.source.currentTime=i,e.source.dispatchEvent(new CustomEvent(Et,{detail:{time:i}}))},this._onRelease=()=>{const t=this._video,e=this._controlBar;t&&e&&(this._wasPaused||this._playPromise||(this._playPromise=t.source.play().catch((()=>{})),this._playPromise.then((()=>{this._playPromise=null})),e.rootEl.classList.remove(e.className.FIXED))),this._wasPaused=!1},this.position=t,this.order=e,this._controlBar=null,this._rangeControl=new ve,this._video=null,this._wasPaused=!1,this._currentTime=0,this._duration=0,this._playPromise=null}init(t,e){var i;const s=null===(i=t.projection)||void 0===i?void 0:i.getTexture(),n=this.element,o=this._rangeControl,r=e.className.UNAVAILABLE;s&&s.isVideo()?(n.classList.remove(r),n.classList.add(e.className.PROGRESS_ROOT),t.on(tt.RESIZE,this._onResize),s.source.addEventListener(D,this._onTimeUpdate),s.source.addEventListener(U,this._onDurationChange),s.source.addEventListener(Et,this._onTimeUpdate),o.init(e.className),o.on(nt,this._onHold),o.on(ot,this._onControl),o.on(rt,this._onRelease),this._video=s,this._currentTime=s.source.currentTime,this._duration=s.source.duration,this._controlBar=e,o.updateStyle(this._currentTime/this._duration)):n.classList.add(r)}destroy(t){const e=this._video;t.off(tt.RESIZE,this._onResize),e&&(e.source.removeEventListener(D,this._onTimeUpdate),e.source.removeEventListener(U,this._onDurationChange),e.source.removeEventListener(Et,this._onTimeUpdate)),this._rangeControl.destroy(),this._video=null,this._playPromise=null}}class Te extends me{constructor({position:t=ge.MAIN_LEFT,order:e=9999}={}){super({position:t,order:e}),this._onClick=()=>{const t=this._video;t&&(this._paused?t.source.play():t.source.pause())},this._onPlay=()=>{if(!this._controlBar)return;const t=this.element,e=this._controlBar.className;t.classList.add(e.PAUSE_BUTTON),t.classList.remove(e.PLAY_BUTTON),t.title="Pause Video",this._paused=!1},this._onPause=()=>{if(!this._controlBar)return;const t=this.element,e=this._controlBar.className;t.classList.add(e.PLAY_BUTTON),t.classList.remove(e.PAUSE_BUTTON),t.title="Play Video",this._paused=!0},this.element=document.createElement(G),this._video=null,this._paused=!0,this._controlBar=null}init(t,e){var i;const s=this.element,n=null===(i=t.projection)||void 0===i?void 0:i.getTexture(),o=e.className,r=o.UNAVAILABLE;if(!n||!n.isVideo())return void s.classList.add(r);s.classList.add(o.CONTROLS_BUTTON),s.classList.remove(r);const a=n.isPaused();this._video=n,this._paused=a,this._controlBar=e,a?this._onPause():this._onPlay(),s.addEventListener(w,this._onClick),n.source.addEventListener(S,this._onPlay),n.source.addEventListener(P,this._onPause)}destroy(){const t=this._video,e=this.element;t&&(e.className="",e.removeEventListener(w,this._onClick),t.source.removeEventListener(S,this._onPlay),t.source.removeEventListener(P,this._onPause),this._video=null,this._paused=!0,this._controlBar=null)}}class be extends me{get element(){return this._rootEl}constructor({position:t=ge.MAIN_RIGHT,order:e=9999}={}){super({position:t,order:e}),this._onResize=()=>{this._rangeControl.resize(),this._updateDisplay()},this._onClick=()=>{const t=this._video;t&&!this._rootEl.disabled&&(t.source.muted=!t.source.muted)},this._onVolumeChange=()=>{const t=this._buttonEl,e=this._video,i=this._controlBar;if(!e||!i)return;const s=i.className;e.source.muted||0===e.source.volume?(t.classList.add(s.MUTED_BUTTON),t.classList.remove(s.UNMUTED_BUTTON)):(t.classList.add(s.UNMUTED_BUTTON),t.classList.remove(s.MUTED_BUTTON)),this._updateDisplay()},this._onHold=t=>{const e=this._video,i=this._controlBar;if(!e||!i)return;const s=i.className;e.source.volume=t,this._rootEl.classList.add(s.FIXED),i.containerEl.classList.add(s.FIXED),this._updateDisplay()},this._onChange=t=>{const e=this._video;e&&(e.source.volume=t,e.source.muted=!(t>0),this._updateDisplay())},this._onRelease=()=>{const t=this._controlBar;if(!t)return;const e=t.className;this._rootEl.classList.remove(e.FIXED),t.containerEl.classList.remove(e.FIXED)},this._updateDisplay=()=>{const t=this._video,e=this._rootEl;if(!t)return;if(!t.hasAudio())return void(e.disabled=!0);e.disabled=!1;const i=t.source.muted?0:t.source.volume;this._rangeControl.updateStyle(i)},this._controlBar=null,this._rangeControl=new ve,this._createElements(),this._video=null}init(t,e){var i;const s=null===(i=t.projection)||void 0===i?void 0:i.getTexture(),n=this._rootEl,o=this._buttonEl,r=this._rangeControl,a=e.className,h=a.UNAVAILABLE;s&&s.isVideo()?(n.classList.remove(h),n.classList.add(a.CONTROLS_BUTTON),n.classList.add(a.VOLUME_ROOT),o.classList.add(a.CONTROLS_BUTTON),s.source.muted?o.classList.add(a.MUTED_BUTTON):o.classList.add(a.UNMUTED_BUTTON),t.on(tt.RESIZE,this._onResize),n.addEventListener(F,this._onResize),o.addEventListener(w,this._onClick),s.source.addEventListener(M,this._onVolumeChange),s.source.addEventListener(N,this._updateDisplay),s.source.addEventListener(B,this._updateDisplay),r.init(a),r.on(nt,this._onHold),r.on(ot,this._onChange),r.on(rt,this._onRelease),this._controlBar=e,this._video=s,this._updateDisplay()):n.classList.add(h)}destroy(t){const e=this._video,i=this._buttonEl,s=this._rootEl;s.className="",i.className="",t.off(tt.RESIZE,this._onResize),s.removeEventListener(F,this._onResize),i.removeEventListener(w,this._onClick),e&&(e.source.removeEventListener(M,this._onVolumeChange),e.source.removeEventListener(N,this._updateDisplay),e.source.removeEventListener(B,this._updateDisplay)),this._controlBar=null,this._rangeControl.destroy(),this._video=null}_createElements(){const t=document.createElement(G),e=document.createElement(V);t.appendChild(this._rangeControl.rootEl),t.appendChild(e),t.title="Toggle Mute",this._rootEl=t,this._buttonEl=e}}class fe extends me{constructor({position:t=ge.MAIN_RIGHT,order:e=9999}={}){super({position:t,order:e}),this._onClick=()=>{const t=this._targetEl;t&&(Nt()?this._exitFullscreen():this._requestFullscreen(t))},this._onFullscreenChange=()=>{const t=this.element,e=this._controlBar;if(!e)return;const i=e.className;Nt()?(t.classList.add(i.FULLSCREEN_EXIT_BUTTON),t.classList.remove(i.FULLSCREEN_BUTTON)):(t.classList.add(i.FULLSCREEN_BUTTON),t.classList.remove(i.FULLSCREEN_EXIT_BUTTON))},this.element=document.createElement(G),this.element.title="Toggle Fullscreen",this._controlBar=null,this._targetEl=null}init(t,e){const i=this.element,s=e.className;this._fullscreenAvailable()?(i.classList.add(s.CONTROLS_BUTTON),i.classList.remove(s.UNAVAILABLE),i.addEventListener(w,this._onClick),this._addFullscreenHandlers(),Nt()?i.classList.add(s.FULLSCREEN_EXIT_BUTTON):i.classList.add(s.FULLSCREEN_BUTTON),this._controlBar=e,this._targetEl=t.rootEl):i.classList.add(s.UNAVAILABLE)}destroy(){const t=this.element;t.className="",t.removeEventListener(w,this._onClick),this._removeFullscreenHandlers(),this._controlBar=null,this._targetEl=null}_fullscreenAvailable(){return K.some((t=>!!document[t]))}_requestFullscreen(t){for(const e of K){const i=t[e];if(i)return void i.call(t)}}_exitFullscreen(){for(const t of $){const e=document[t];if(e)return void e.call(document)}}_addFullscreenHandlers(){Q.forEach((t=>{document.addEventListener(t,this._onFullscreenChange)}))}_removeFullscreenHandlers(){Q.forEach((t=>{document.removeEventListener(t,this._onFullscreenChange)}))}}class Re extends me{constructor({position:t=ge.MAIN_LEFT,order:e=9999}={}){super({position:t,order:e}),this._onTimeUpdate=()=>{const t=this._video;t&&(this._currentTime=t.source.currentTime,this._updateDisplay())},this._onDurationChange=()=>{const t=this._video;t&&(this._duration=t.source.duration,this._updateDisplay())},this._onCustomTimeChange=t=>{this._currentTime=t.detail.time,this._updateDisplay()},this.element=document.createElement(V),this._video=null,this._currentTime=0,this._duration=0}init(t,e){var i;const s=null===(i=t.projection)||void 0===i?void 0:i.getTexture(),n=this.element,o=e.className;s&&s.isVideo()?(n.classList.add(o.VIDEO_TIME_DISPLAY),n.classList.remove(o.UNAVAILABLE),s.source.addEventListener(D,this._onTimeUpdate),s.source.addEventListener(U,this._onDurationChange),s.source.addEventListener(Et,this._onCustomTimeChange),this._video=s,this._currentTime=s.source.currentTime,this._duration=s.source.duration,this._updateDisplay()):n.classList.add(o.UNAVAILABLE)}destroy(){const t=this._video;t&&(this.element.className="",t.source.removeEventListener(D,this._onTimeUpdate),t.source.removeEventListener(U,this._onDurationChange),t.source.removeEventListener(Et,this._onCustomTimeChange),this._video=null)}_updateDisplay(){const t=this._currentTime,e=Math.floor(t/60),i=Math.floor(t-60*e),s=i<10?`0${i}`:i,n=this._duration,o=Math.floor(n/60),r=Math.floor(n-60*o),a=r<10?`0${r}`:r;this.element.innerText=`${e}:${s} / ${o}:${a}`}}class ye extends me{constructor({resetCamera:t=!0,position:e=ge.TOP_RIGHT,order:i=9999}={}){super({position:e,order:i}),this._onClick=()=>{const t=this._viewer,e=this.resetCamera;if(!t||!e)return;const{yaw:i=t.initialYaw,pitch:s=t.initialPitch,zoom:n=t.initialZoom,duration:o=500}=At(e);t.camera.animateTo({yaw:i,pitch:s,zoom:n,duration:o})},this._updatePie=({target:t})=>{const e=this._piePathEl,i=this._rangeCircleEl,s=t.camera,n=s.getHorizontalFov(),o=s.getYawRange(s.zoom),r=.5*n,a=24*Math.PI,h=a*n/360,l=a*(s.yaw+r+90)/360;if(e.setAttribute("stroke-dasharray",`${h} ${a-h}`),e.setAttribute("stroke-dashoffset",`${l}`),isFinite(o.min)&&isFinite(o.max)){const t=45*Math.PI,e=(Ot(o.min,-180,180)-r)/360,s=(Ot(o.max,-180,180)+r)/360,n=t*Math.abs(s-e),a=-t*(e-.25);i.setAttribute("stroke-dasharray",`${n} ${t-n}`),i.setAttribute("stroke-dashoffset",`${a}`)}else i.setAttribute("stroke-dasharray",""),i.setAttribute("stroke-dashoffset","")},this.element=document.createElement(V),this.element.title="Reset view",this.resetCamera=t,this._createPieElements(),this._viewer=null}init(t,e){const i=this.element;t.initialized?this._updatePie({target:t}):t.once(tt.READY,this._updatePie);const s=e.className.PIEVIEW_ROOT;i.classList.add(s),this.resetCamera&&i.addEventListener(w,this._onClick),t.on(tt.VIEW_CHANGE,this._updatePie),this._viewer=t}destroy(t){const e=this.element;e.removeEventListener(w,this._onClick),e.className="",t.off(tt.READY,this._updatePie),t.off(tt.VIEW_CHANGE,this._updatePie),this._viewer=null}_createPieElements(){const t=this.element,e=document.createElementNS(Tt,"svg");e.setAttribute("viewBox","0 0 48 48"),e.setAttribute("width","100%"),e.setAttribute("height","100%");const i=document.createElementNS(Tt,"circle");i.setAttribute("stroke","currentColor"),i.setAttribute("fill","transparent"),i.setAttribute("cx","24"),i.setAttribute("cy","24"),i.setAttribute("r","12"),i.setAttribute("stroke-width","24"),e.appendChild(i);const s=document.createElementNS(Tt,"circle");s.setAttribute("stroke","currentColor"),s.setAttribute("fill","transparent"),s.setAttribute("cx","24"),s.setAttribute("cy","24"),s.setAttribute("r","22.5"),s.setAttribute("stroke-width","3"),e.appendChild(s),t.appendChild(e),this._piePathEl=i,this._rangeCircleEl=s}}class we extends me{constructor({position:t=ge.MAIN_RIGHT,order:e=9999}={}){super({position:t,order:e}),this._onClick=()=>{const t=this._viewer;t&&t.vr.enter()},this.element=document.createElement(G),this.element.title="Enter VR",this._viewer=null}init(t,e){const i=this.element,s=e.className;i.classList.add(s.UNAVAILABLE),i.classList.add(s.VR_BUTTON),i.classList.add(s.CONTROLS_BUTTON),t.vr.isAvailable().then((t=>{t&&i.classList.remove(s.UNAVAILABLE)})),i.addEventListener(w,this._onClick),this._viewer=t}destroy(){const t=this.element;t.className="",t.removeEventListener(w,this._onClick),this._viewer=null}}class Le extends me{constructor({position:t=ge.MAIN_RIGHT,order:e=9999}={}){super({position:t,order:e}),this._onClick=()=>{const t=this._viewer,e=this._controlBar;if(!t||!e)return;const i=t.control.gyro;i.enabled?i.disable():Kt.requestSensorPermission().then((t=>{t?i.enable():this.element.classList.add(e.className.UNAVAILABLE)}))},this._updateStyle=()=>{const t=this.element,e=this._viewer,i=this._controlBar;if(!e||!i)return;const s=e.control.gyro,n=i.className;s.enabled?(t.classList.add(n.GYRO_ENABLED),t.classList.remove(n.GYRO_DISABLED)):(t.classList.add(n.GYRO_DISABLED),t.classList.remove(n.GYRO_ENABLED))},this.element=document.createElement(V),this.element.title="Toggle gyroscope control"}init(t,e){const i=this.element,s=e.className;i.addEventListener(w,this._onClick),i.classList.add(s.CONTROLS_BUTTON),i.classList.add(s.UNAVAILABLE);const n=()=>{i.classList.remove(s.UNAVAILABLE),t.control.gyro.on(at,this._updateStyle),t.control.gyro.on(ht,this._updateStyle)};Mt()?n():Kt.isAvailable().then((t=>{t&&n()})),this._controlBar=e,this._viewer=t,this._updateStyle()}destroy(t){const e=this.element;t.control.gyro.off(at,this._updateStyle),t.control.gyro.off(ht,this._updateStyle),e.removeEventListener(w,this._onClick),e.className="",this._controlBar=null,this._viewer=null}}class Ce{get enabled(){return!!this._targetEl}get hidden(){return this._controlBar.containerEl.classList.contains(this._hiddenClass)}get _hiddenClass(){return this._controlBar.className.HIDDEN}get _fixedClass(){return this._controlBar.className.FIXED}constructor(t,{initialDelay:e=3e3,delay:i=0,idleDelay:s=3e3}){this._onMouseEnter=()=>{this._isCursorInside=!0,this.show()},this._onMouseLeave=()=>{this._isCursorInside=!1,this._hideAfterDelay()},this._onMouseMove=()=>{this._isFullscreen&&this.showTemporaliy()},this._onHold=t=>{this._isGrabbing=!0,"mouse"===t.pointerType&&(this._isCursorInside=!0),window.addEventListener(d,this._onRelease),this.show()},this._onRelease=()=>{this._isGrabbing=!1,window.removeEventListener(d,this._onRelease),this._hideAfterDelay()},this._onVideoPlay=()=>{this._targetEl&&this._controlBar.containerEl.classList.remove(this._fixedClass)},this._onVideoPause=()=>{this._targetEl&&this._controlBar.containerEl.classList.add(this._fixedClass)},this._onFullscreenChange=()=>{this._isFullscreen=Nt(),this._isFullscreen&&this._hideAfterDelay()},this._controlBar=t,this._initialDelay=e,this._delay=i,this._idleDelay=s,this._timer=-1,this._isCursorInside=!1,this._isGrabbing=!1,this._isFullscreen=!1,this._video=null,this._targetEl=null}enable(t){var e;this._targetEl&&this.disable(t);const i=this._initialDelay,s=t.rootEl;this._targetEl=t.rootEl,this._timer=window.setTimeout((()=>{this.hide()}),i),s.addEventListener(u,this._onHold),s.addEventListener(b,this._onMouseEnter),s.addEventListener(_,this._onMouseMove),s.addEventListener(f,this._onMouseLeave),this._addFullscreenHandlers();const n=null===(e=t.projection)||void 0===e?void 0:e.getTexture();n&&n.isVideo()&&(n.isPaused()&&this._controlBar.containerEl.classList.add(this._fixedClass),n.source.addEventListener(S,this._onVideoPlay),n.source.addEventListener(P,this._onVideoPause),this._video=n)}disable(t){if(!this._targetEl)return;const e=this._controlBar,i=t.rootEl,s=this._video;i.removeEventListener(u,this._onHold),window.removeEventListener(d,this._onRelease),i.removeEventListener(b,this._onMouseEnter),i.removeEventListener(_,this._onMouseMove),i.removeEventListener(f,this._onMouseLeave),this._removeFullscreenHandlers(),window.clearTimeout(this._timer),e.containerEl.classList.remove(this._fixedClass),s&&(s.source.removeEventListener(S,this._onVideoPlay),s.source.removeEventListener(P,this._onVideoPause)),this._isCursorInside=!1,this._isGrabbing=!1,this._video=null,this._targetEl=null}show(){this._clearHideTimer(),this._controlBar.containerEl.classList.remove(this._hiddenClass)}showTemporaliy(){this.show(),this._hideAfterDelay(this._idleDelay)}hide(){this._clearHideTimer(),this._controlBar.containerEl.classList.add(this._hiddenClass)}_clearHideTimer(){this._timer&&(window.clearTimeout(this._timer),this._timer=-1)}_hideAfterDelay(t=this._delay){this._isGrabbing||!this._isFullscreen&&this._isCursorInside||(this._clearHideTimer(),t<=0?this.hide():this._timer=window.setTimeout((()=>{this.hide()}),t))}_addFullscreenHandlers(){Q.forEach((t=>{document.addEventListener(t,this._onFullscreenChange)}))}_removeFullscreenHandlers(){Q.forEach((t=>{document.removeEventListener(t,this._onFullscreenChange)}))}}class xe{constructor(){this._onKeyDown=t=>{const e=this._video;if(!e)return;t.preventDefault(),t.stopPropagation();const i=e.source,s=null!=t.keyCode?W[t.keyCode]:q[t.key];switch(s){case"LEFT":case"RIGHT":return this._changeVideoTime(i,"RIGHT"===s);case"UP":case"DOWN":return this._changeVideoVolume(i,"UP"===s)}(32===t.keyCode||" "===t.key)&&this._toggleVideo(e)}}enable(t,e){this._video=e,t.addEventListener(R,this._onKeyDown,!0)}disable(t){this._video=null,t.removeEventListener(R,this._onKeyDown,!0)}_changeVideoTime(t,e){const i=e?5:-5;t.currentTime+=i,t.dispatchEvent(new CustomEvent(Et,{detail:{time:t.currentTime}}))}_changeVideoVolume(t,e){const i=e?.1:-.1;t.muted?t.volume=Ct(i,0,1):t.volume=Ct(t.volume+i,0,1),t.volume>0?t.muted=!1:t.muted=!0}_toggleVideo(t){t.isPaused()?t.source.play():t.source.pause()}}class Oe{get rootEl(){return this._rootEl}get containerEl(){return this._containerEl}get backgroundEl(){return this._bgEl}get items(){return this._items}get customItems(){return this._customItems}constructor({autoHide:t,showBackground:e,clickToPlay:i=!0,keyboardControls:s=!0,progressBar:n=!0,playButton:o=!0,volumeButton:r=!0,fullscreenButton:a=!0,videoTime:h=!0,pieView:l=!0,vrButton:c=!0,gyroButton:u=!0,className:_={},customItems:d=[]}={}){var m;this._onStaticClick=({target:t,isTouch:e})=>{var i;const s=this._autoHider;if(e){if(!s.enabled)return;s.hidden?s.showTemporaliy():s.hide()}else{if(!this.clickToPlay)return;const e=null===(i=t.projection)||void 0===i?void 0:i.getTexture();if(!e||!e.isVideo())return;e.isPaused()?e.source.play():e.source.pause()}},this._onNewSrcLoad=({target:t})=>{const e=this._items;this._updateBackground(t),this._updateAutoHide(t),this._updateKeyboardHandler(t),Object.keys(e).forEach((i=>{e[i].forEach((e=>{e.destroy(t,this),e.init(t,this)}))}))},this.autoHide=t,this.showBackground=e,this.clickToPlay=i,this.keyboardControls=s,this.progressBar=n,this.playButton=o,this.volumeButton=r,this.fullscreenButton=a,this.videoTime=h,this.pieView=l,this.vrButton=c,this.gyroButton=u,this.className=Object.assign(Object.assign({},Oe.DEFAULT_CLASS),_);const p=null!==(m=_.CONTROLS_ROOT)&&void 0!==m?m:Oe.DEFAULT_CLASS.CONTROLS_ROOT;this._rootEl=wt(p),this._createPositionWrappers(),this._items=Object.keys(Oe.POSITION).reduce(((t,e)=>(t[Oe.POSITION[e]]=[],t)),{}),this._customItems=d,this._autoHider=new Ce(this,At(t)),this._videoControl=new xe,d.forEach((t=>{this._items[t.position].push(t)}))}init(t){const e=t.rootEl,i=this._rootEl,s=this._createDefaultItems();this._updateBackground(t),this._updateAutoHide(t),this._updateKeyboardHandler(t),e.appendChild(i),this._addItem(t,s),this._addItem(t,this._customItems),t.on(tt.PROJECTION_CHANGE,this._onNewSrcLoad),t.on(tt.STATIC_CLICK,this._onStaticClick)}destroy(t){const e=t.rootEl,i=this._rootEl,s=this._items;i.parentElement===e&&e.removeChild(i),Object.keys(s).forEach((e=>{s[e].forEach((e=>{e.destroy(t,this)})),s[e]=[]})),this._clearItemElements(),this._autoHider.disable(t),this._videoControl.disable(e),t.off(tt.PROJECTION_CHANGE,this._onNewSrcLoad),t.off(tt.STATIC_CLICK,this._onStaticClick)}_addItem(t,e){for(const i of e){const e=this._items[i.position],s=this._wrapperEl[i.position],n=It(e,(t=>t.order>i.order));if(n>=0){const t=e[n].element;e.splice(n,0,i),s.insertBefore(i.element,t)}else e.push(i),s.appendChild(i.element);i.init(t,this)}}_createPositionWrappers(){const t=Object.assign(Object.assign({},Oe.DEFAULT_CLASS),this.className),e=this._rootEl,i=wt(t.CONTROLS_BG),s=wt(t.CONTROLS_FLOAT_LEFT),n=wt(t.CONTROLS_FLOAT_RIGHT);e.appendChild(s),e.appendChild(n);const o=wt(t.CONTROLS_MAIN),r=wt(t.CONTROLS_TOP),a=wt(t.CONTROLS_BOTTOM),h=wt(t.CONTROLS_MID),l=wt(t.CONTROLS_LEFT),c=wt(t.CONTROLS_RIGHT);h.appendChild(l),h.appendChild(c),o.appendChild(i),o.appendChild(r),o.appendChild(h),o.appendChild(a),e.appendChild(o),this._bgEl=i,this._containerEl=o,this._wrapperEl={[Oe.POSITION.MAIN_TOP]:r,[Oe.POSITION.MAIN_LEFT]:l,[Oe.POSITION.MAIN_RIGHT]:c,[Oe.POSITION.MAIN_BOTTOM]:a,[Oe.POSITION.TOP_LEFT]:s,[Oe.POSITION.TOP_RIGHT]:n}}_clearItemElements(){Object.keys(Oe.POSITION).map((t=>Oe.POSITION[t])).forEach((t=>{for(;t.firstChild;)t.removeChild(t.firstChild)}))}_updateAutoHide(t){var e;const i=this.autoHide,s=this._autoHider;if(null!=i)i?s.enable(t):s.disable(t);else{const i=null===(e=t.projection)||void 0===e?void 0:e.getTexture();i&&i.isVideo()?s.enable(t):s.disable(t)}}_updateBackground(t){var e,i;const s=this._bgEl,n=this.showBackground,o=null!==(e=this.className.HIDDEN)&&void 0!==e?e:Oe.DEFAULT_CLASS.HIDDEN;if(null!=n)n?s.classList.remove(o):s.classList.add(o);else{const e=null===(i=t.projection)||void 0===i?void 0:i.getTexture();e&&e.isVideo()?s.classList.remove(o):s.classList.add(o)}}_updateKeyboardHandler(t){var e;const i=t.rootEl,s=this._videoControl,n=null===(e=t.projection)||void 0===e?void 0:e.getTexture();this.keyboardControls&&n&&n.isVideo()?s.enable(i,n):s.disable(i)}_createDefaultItems(){const t=[];return this.progressBar&&t.push(new Ee(At(this.progressBar))),this.playButton&&t.push(new Te(At(this.playButton))),this.volumeButton&&t.push(new be(At(this.volumeButton))),this.gyroButton&&t.push(new Le(At(this.gyroButton))),this.vrButton&&t.push(new we(At(this.vrButton))),this.fullscreenButton&&t.push(new fe(At(this.fullscreenButton))),this.videoTime&&t.push(new Re(At(this.videoTime))),this.pieView&&t.push(new ye(At(this.pieView))),t}}Oe.DEFAULT_CLASS=pe,Oe.POSITION=ge;class Ie{constructor({src:t,video:e=!1}){this.src=t,this.video=e,this._mesh=null}releaseAllResources(t){var e;null===(e=this._mesh)||void 0===e||e.destroy(t)}updateCamera(t){t.resetRange()}updateControl(t){t.ignoreZoomScale=!1}update(t){}getTexture(){return this._mesh?this._mesh.program.uniforms.uTexture.texture:null}getMesh(){return this._mesh}}class Ae{constructor(){this.needsUpdate=!0}destroy(t){}}class Se extends Ae{constructor(t,e,i){super(),this.texture=e,this._webglTexture=t.createWebGLCubeTexture(e,e.width),this._cubemapOrder=i}destroy(t){this.texture.destroy(),t.deleteTexture(this._webglTexture)}update(t,e,i){const s=this.texture;t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,s.flipY),t.uniform1i(e,0),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_CUBE_MAP,this._webglTexture);Pt(s.sources,this._cubemapOrder).forEach(((e,s)=>{i?t.texSubImage2D(t.TEXTURE_CUBE_MAP_POSITIVE_X+s,0,0,0,t.RGBA,t.UNSIGNED_BYTE,e):t.texImage2D(t.TEXTURE_CUBE_MAP_POSITIVE_X+s,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e)})),s.isVideo()||(this.needsUpdate=!1)}}class Pe{get size(){return this._size}constructor(t,e){var i;this.texture=t,this._renderingOrder=Pt(!(i=6)||i<=0?[]:Array.apply(0,Array(i)).map(((t,e)=>e)),e);const s=document.createElement("canvas");this._calcRenderingSize(),s.width=this._size,s.height=this._size,this._canvas=s,this._ctx=s.getContext("2d")}destroy(){const t=this._canvas;t.width=1,t.height=1,this._canvas=null}draw(t,e){const i=this._size,s=this.texture;let n=0;for(let o=0;o=0;t--)for(let e=0;e<3;e++){const n=[e*i,.5*t,(e+1)*i,.5*t,(e+1)*i,.5*(t+1),e*i,.5*(t+1)];s.push(n)}e&&e.forEach(((t,e)=>{if(t===vt.ZERO)return;const i=s[e];let n;n=t===vt.CW_90?[1,2,3,0]:t===vt.CCW_90?[3,0,1,2]:[2,3,0,1];const o=Array(i.length);for(let t=0;tt.concat(e)),[]))}}class ze extends Ae{constructor(t,e){super(),this.texture=e,this._webglTexture=t.createWebGLTexture(e)}destroy(t){this.texture.destroy(),t.deleteTexture(this._webglTexture)}update(t,e,i){const s=this.texture,n=s.isVideo();t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,s.flipY),t.uniform1i(e,0),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this._webglTexture),!n&&i?t.texSubImage2D(t.TEXTURE_2D,0,0,0,t.RGBA,t.UNSIGNED_BYTE,s.source):t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,s.source),n||(this.needsUpdate=!1)}}var Ve="#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec2 vUV;void main(){vUV=uv;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}",Ge="#define GLSLIFY 1\nuniform sampler2D uTexture;varying highp vec2 vUV;void main(){gl_FragColor=texture2D(uTexture,vUV.st);}";class ke extends Be{constructor(t){const e=[],i=[],s=[],n=[-.5,.5],o=1/60,r=t*o;for(let a=0;a<2;a++){const h=n[a];for(let n=0;n<=60;n++){const l=n*r+Math.PI-.5*t,c=Math.cos(l),u=Math.sin(l),_=n*o,d=a;if(s.push(_,d),e.push(c,h,u),0===a&&n<60){const t=n,e=t+60+1;i.push(t,e,t+1,e,e+1,t+1)}}}super(e,i,s)}}class Ye extends Be{constructor(){const t=60,e=-.5*Math.PI,i=[],s=[],n=[];let o,r;for(o=0;o<=60;o++){const a=(o/60-.5)*Math.PI,h=Math.sin(a),l=Math.cos(a);for(r=0;r<=t;r++){const a=2*(r/t-.5)*Math.PI+e,c=Math.sin(a),u=Math.cos(a)*l,_=h,d=c*l,m=r/t,p=o/60;if(i.push(m,p),s.push(u,_,d),r!==t&&60!==o){const e=61*o+r,i=e+t+1;n.push(e,e+1,i,i,e+1,i+1)}}}super(s,n,i)}}class He extends Ae{constructor(t){super(),this.val=t}update(t,e){t.uniform1f(e,this.val),this.needsUpdate=!1}}class Xe extends Be{constructor(t=2,e=2,i=-1){const s=.5*t,n=.5*e;super([-s,-n,i,s,-n,i,-s,n,i,s,n,i],[0,1,2,2,1,3],[0,0,1,0,0,1,1,1])}}class je extends Ae{constructor(t){super(),this.val=t}update(t,e){t.uniform4fv(e,this.val.reduce(((t,e)=>[...t,...e]),[])),this.needsUpdate=!1}}class We extends Ie{constructor(t){super(t),this._mode=t.mode}applyTexture(t,e){let i,s;if(this._mode===We.MODE.LEFT_RIGHT)i=[.5,1,0,0],s=[.5,1,.5,0];else i=[1,.5,0,0],s=[1,.5,0,.5];const n={uTexture:new ze(t,e),uEye:new He(0),uTexScaleOffset:new je([i,s])},o=new Ye,r=new De(t,"#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;uniform vec4 uTexScaleOffset[2];uniform float uEye;varying highp vec2 vUV;void main(){vec4 scaleOffset=uTexScaleOffset[int(uEye)];vUV=uv.xy*scaleOffset.xy+scaleOffset.zw;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}",Ge,n),a=t.createVAO(o,r),h=new Me(a,r);this._mesh=h}}We.MODE={LEFT_RIGHT:"left_right",TOP_BOTTOM:"top_bottom"};var qe={__proto__:null,default:ue,Autoplay:ne,AutoResizer:se,Camera:zt,CameraAnimation:Ft,Motion:Bt,Object3D:_e,View360Error:a,WebGLRenderer:ce,XRManager:oe,PanoControl:Zt,RotateControl:Yt,ZoomControl:jt,GyroControl:Kt,ControlBar:Oe,ControlBarItem:me,FullscreenButton:fe,PieView:ye,PlayButton:Te,ProgressBar:Ee,VideoTime:Re,VolumeControl:be,LoadingSpinner:de,Projection:Ie,CubemapProjection:class extends Ie{constructor(t){super(t);const{cubemapOrder:e="RLUDFB",cubemapFlipX:i=!1}=t;this._cubemapOrder=e,this._cubemapFlipX=i}applyTexture(t,e){const i=this._cubemapOrder,s=this._cubemapFlipX,n={uTexture:e.isCube()?new Se(t,e,i):new Ne(t,e,i)},o=new Fe({order:i}),r=new De(t,"#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec3 vPos;void main(){vPos=position;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}","#define GLSLIFY 1\nuniform samplerCube uTexture;varying highp vec3 vPos;void main(){gl_FragColor=textureCube(uTexture,vec3(vPos.x,vPos.y,-vPos.z));}",n),a=t.createVAO(o,r),h=new Me(a,r);s&&(h.scale[0]=-1),h.updateMatrix(),this._mesh=h}},CubestripProjection:class extends Ie{constructor(t){super(t);const{cubemapOrder:e="RLUDFB",cubemapFlipX:i=!1}=t;this._cubemapOrder=e,this._cubemapFlipX=i}applyTexture(t,e){const i=this._cubemapOrder,s=this._cubemapFlipX,n={uTexture:new ze(t,e)},o=new Fe({order:i}),r=new De(t,Ve,Ge,n),a=t.createVAO(o,r),h=new Me(a,r);s&&(h.scale[0]=-1),h.updateMatrix(),this._mesh=h}},CylindricalProjection:class extends Ie{constructor(t){super(t);const{partial:e=!1}=t;this._partial=e}applyTexture(t,i){const s=this._partial,{width:n,height:o}=i,r=n/o,a=180/r,h=s?1:2*Math.tan(a*ct),l=s?r:2*Math.PI,c=new ke(l),u=new De(t,Ve,Ge,{uTexture:new ze(t,i)}),_=t.createVAO(c,u),d=new Me(_,u);d.scale[1]=h,e.quat.identity(d.rotation),e.quat.rotateY(d.rotation,d.rotation,-Math.PI/2),d.updateMatrix(),this._mesh=d}updateCamera(t){super.updateCamera(t);const e=this._mesh;if(!e)return;const i=e.program.uniforms.uTexture.texture,{width:s,height:n}=i,o=s/n,r=.5*e.scale[1];if(this._partial){const e=.5*o*ut;t.restrictYawRange(-e,e)}const a=Math.atan2(r,1)*ut,h=Math.tan(t.fov*ct*.5)/(r*t.aspect);t.restrictPitchRange(-a,a),t.restrictZoomRange(h,1/0),t.restrictRenderHeight(2*r)}},EquiangularProjection:class extends Ie{applyTexture(t,e){const i={uTexture:new ze(t,e)},s=new Fe({order:"LFRDBU",rotateUV:[vt.ZERO,vt.ZERO,vt.ZERO,vt.CW_90,vt.CCW_90,vt.CW_90]}),n=new De(t,Ve,"#define PI 3.14159265359\nprecision mediump float;\n#define GLSLIFY 1\nuniform sampler2D uTexture;varying highp vec2 vUV;const vec2 OPERATE_COORDS_RANGE=vec2(-1.0,1.0);const vec2 TEXTURE_COORDS_RANGE=vec2(0.0,1.0);const float ONE_THIRD=1.0/3.0;const float EAC_CONST=2.0/PI;float scale(vec2 domainRange,vec2 targetRange,float val){float unit=1.0/(domainRange[1]-domainRange[0]);return targetRange[0]+(targetRange[1]-targetRange[0])*(val-domainRange[0])*unit;}void main(void){float transformedCoordX;float transformedCoordY;float texRangeXStart=floor(vUV.s*3.)*ONE_THIRD;float texRangeYStart=floor(vUV.t*2.)*0.5;vec2 orgTextureRangeX=vec2(texRangeXStart,texRangeXStart+ONE_THIRD);vec2 orgTextureRangeY=vec2(texRangeYStart,texRangeYStart+0.5);float px=scale(orgTextureRangeX,OPERATE_COORDS_RANGE,vUV.s);float py=scale(orgTextureRangeY,OPERATE_COORDS_RANGE,vUV.t);float qu=EAC_CONST*atan(px)+0.5;float qv=EAC_CONST*atan(py)+0.5;transformedCoordX=scale(TEXTURE_COORDS_RANGE,orgTextureRangeX,qu);transformedCoordY=scale(TEXTURE_COORDS_RANGE,orgTextureRangeY,qv);gl_FragColor=texture2D(uTexture,vec2(transformedCoordX,transformedCoordY));}",i),o=t.createVAO(s,n),r=new Me(o,n);this._mesh=r}},EquirectProjection:class extends Ie{constructor(t){super(t)}applyTexture(t,e){const i={uTexture:new ze(t,e)},s=new Ye,n=new De(t,Ve,Ge,i),o=t.createVAO(s,n),r=new Me(o,n);this._mesh=r}},LittlePlanetProjection:class extends Ie{constructor(t){super(t)}applyTexture(t,e){e.wrapS=WebGLRenderingContext.REPEAT,e.wrapT=WebGLRenderingContext.REPEAT;const i={uTexture:new ze(t,e),uYaw:new He(0),uPitch:new He(.5),uZoom:new He(1)},s=new Xe,n=new De(t,"#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec2 vUV;void main(){vUV=uv;gl_Position=vec4(position,1.0);}","precision mediump float;\n#define GLSLIFY 1\nuniform sampler2D uTexture;uniform float uYaw;uniform float uPitch;uniform float uZoom;varying highp vec2 vUV;const float PI=3.1415926536;const float PI_2=PI*0.5;vec2 toStereographicUV(in vec2 uv,in vec2 center){float R=1.*uZoom;vec2 texLatLon=(uv*2.-1.)*vec2(PI,PI_2);vec2 central=(center*2.-1.)*vec2(PI,PI_2)+vec2(PI,0);float x=texLatLon.x;float y=texLatLon.y;float rou=sqrt(x*x+y*y);float c=2.0*atan(rou,R*0.5);float sin_c=sin(c);float cos_c=cos(c);float sin_cy=sin(central.y);float cos_cy=cos(central.y);float lat=asin(cos_c*sin_cy+(y*sin_c*cos_cy)/rou);float lon=central.x+atan(x*sin_c,rou*cos_cy*cos_c-y*sin_cy*sin_c);float u=(lon/PI+1.0)*0.5;float v=(lat/PI_2+1.0)*0.5;return vec2(u,v);}void main(){vec2 central=vec2(uYaw,uPitch);vec2 uv=toStereographicUV(vUV,central);gl_FragColor=texture2D(uTexture,uv);}",i),o=t.createVAO(s,n),r=new Me(o,n);this._mesh=r}updateControl(t){t.ignoreZoomScale=!0}update(t){const e=this._mesh;if(!e)return;const i=e.program.uniforms;i.uYaw.val=t.yaw/360,i.uPitch.val=t.pitch/180+.5,i.uZoom.val=t.zoom,i.uYaw.needsUpdate=!0,i.uPitch.needsUpdate=!0,i.uZoom.needsUpdate=!0}},StereoEquiProjection:We,Hotspot:re,HotspotRenderer:ae,ERROR_CODES:h,DEFAULT_CLASS:J,EVENTS:tt,EASING:et,getValidProps:t=>Object.keys(t).reduce(((e,i)=>(null!=t[i]&&(e[i]=t[i]),e)),{}),VIEW360_METHODS:["destroy","init","load","resize","addPlugins","removePlugins","renderFrame","on","hasOn","once","off","trigger"],withMethods:(t,e)=>{[n.default.prototype,ue.prototype].forEach((i=>{Object.getOwnPropertyNames(i).filter((t=>"_"!==t.charAt(0)&&"constructor"!==t)).forEach((s=>{const n=Object.getOwnPropertyDescriptor(i,s);if(n.value)Object.defineProperty(t,s,{value:function(...t){return n.value.call(this[e],...t)}});else{const i={};n.get&&(i.get=function(){var t;return this[e]&&(null===(t=n.get)||void 0===t?void 0:t.call(this[e]))}),n.set&&(i.set=function(...t){var i;return null===(i=n.set)||void 0===i?void 0:i.call(this[e],...t)}),Object.defineProperty(t,s,i)}}))}))}};return((t,...e)=>{e.forEach((e=>{Object.keys(e).forEach((i=>{const s=e[i];Array.isArray(t[i])&&Array.isArray(s)?t[i]=[...t[i],...s]:t[i]=s}))}))})(ue,qe),ue})); +//# sourceMappingURL=view360.min.js.map diff --git a/demo/release/latest/dist/view360.min.js.map b/demo/release/latest/dist/view360.min.js.map new file mode 100644 index 000000000..d048a9773 --- /dev/null +++ b/demo/release/latest/dist/view360.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"view360.min.js","sources":["../src/core/View360Error.ts","../src/const/error.ts","../src/const/browser.ts","../src/const/external.ts","../src/const/internal.ts","../src/utils.ts","../src/core/Motion.ts","../src/core/CameraAnimation.ts","../src/core/Camera.ts","../src/control/input/MouseInput.ts","../src/control/input/TouchInput.ts","../src/control/input/KeyboardInput.ts","../src/control/RotateControl.ts","../src/control/input/WheelInput.ts","../src/control/input/PinchInput.ts","../src/control/ZoomControl.ts","../src/control/input/GyroInput.ts","../src/control/GyroControl.ts","../src/control/PanoControl.ts","../src/texture/Texture.ts","../src/texture/Texture2D.ts","../src/texture/TextureVideo.ts","../src/texture/TextureCube.ts","../src/core/TextureLoader.ts","../src/core/FrameAnimator.ts","../src/core/AutoResizer.ts","../src/core/Autoplay.ts","../src/core/XRManager.ts","../src/hotspot/Hotspot.ts","../src/hotspot/HotspotRenderer.ts","../src/core/VertexArrayObject.ts","../src/core/WebGLContext.ts","../src/core/WebGLRenderer.ts","../src/View360.ts","../src/core/Object3D.ts","../src/plugin/LoadingSpinner/LoadingSpinner.ts","../src/plugin/ControlBar/ControlBarItem.ts","../src/plugin/ControlBar/const.ts","../src/plugin/ControlBar/RangeControl.ts","../src/plugin/ControlBar/ProgressBar.ts","../src/plugin/ControlBar/PlayButton.ts","../src/plugin/ControlBar/VolumeControl.ts","../src/plugin/ControlBar/FullscreenButton.ts","../src/plugin/ControlBar/VideoTime.ts","../src/plugin/ControlBar/PieView.ts","../src/plugin/ControlBar/VRButton.ts","../src/plugin/ControlBar/GyroButton.ts","../src/plugin/ControlBar/AutoHide.ts","../src/plugin/ControlBar/VideoControl.ts","../src/plugin/ControlBar/ControlBar.ts","../src/projection/Projection.ts","../src/uniform/Uniform.ts","../src/uniform/UniformTextureCube.ts","../src/core/CubeTexturePainter.ts","../src/uniform/UniformCanvasCube.ts","../src/core/TriangleMesh.ts","../src/core/ShaderProgram.ts","../src/core/VertexData.ts","../src/geometry/Geometry.ts","../src/geometry/CubeGeometry.ts","../src/uniform/UniformTexture2D.ts","../src/geometry/CylinderGeometry.ts","../src/geometry/SphereGeometry.ts","../src/uniform/UniformFloat.ts","../src/geometry/PlaneGeometry.ts","../src/uniform/UniformVector4Array.ts","../src/projection/StereoEquiProjection.ts","../src/projection/CubemapProjection.ts","../src/projection/CubestripProjection.ts","../src/projection/CylindricalProjection.ts","../src/projection/EquiangularProjection.ts","../src/projection/EquirectProjection.ts","../src/projection/LittlePlanetProjection.ts","../src/cfc/utils.ts","../src/cfc/const.ts","../src/cfc/withMethods.ts","../src/index.umd.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * Error thrown by {@link View360}\n * @ko {@link View360}이 발생시킨 에러\n * @since 4.0.0\n */\nclass View360Error extends Error {\n /**\n * Error code\n * @ko 에러 코드\n * @see ERROR_CODES\n */\n public code: number;\n\n /**\n * Create new instance of View360Error\n * @ko View360Error의 인스턴스를 생성합니다.\n * @param message - Error message {@ko 에러 메시지}\n * @param code - Error code {@ko 에러 코드}\n */\n public constructor(message: string, code: number) {\n super(message);\n\n Object.setPrototypeOf(this, View360Error.prototype);\n\n this.name = \"View360Error\";\n this.code = code;\n }\n}\n\nexport default View360Error;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * Error codes of {@link View360Error}\n * @ko {@link View360Error}가 가질 수 있는 에러 코드 값들\n * @since 4.0.0\n */\nexport const ERROR_CODES = {\n /**\n * The given value's type is not expected\n * @ko 주어진 값의 타입이 잘못되었을 경우\n * @since 4.0.0\n */\n WRONG_TYPE: 0,\n /**\n * The given value is not a supported option\n * @ko 잘못된 옵션을 받았을 경우\n * @since 4.0.0\n */\n WRONG_OPTION: 1,\n /**\n * The element with given CSS selector does not exist\n * @ko 주어진 CSS 셀렉터로 엘리먼트를 찾지 못했을 경우\n * @since 4.0.0\n */\n ELEMENT_NOT_FOUND: 2,\n /**\n * Couldn't find canvas element inside the given container element.\n * @ko 컨테이너 엘리먼트 내부에서 캔버스 엘리먼트를 찾지 못했을 경우\n * @since 4.0.0\n */\n CANVAS_NOT_FOUND: 3,\n /**\n * The browser does not support WebGL\n * @ko 브라우저가 WebGL을 지원하지 않는 경우\n * @since 4.0.0\n */\n WEBGL_NOT_SUPPORTED: 4,\n /**\n * Failed creating canvas 2D context\n * @ko 캔버스 2D 컨텍스트를 생성하지 못한 경우\n * @since 4.0.0\n */\n FAILED_CREATE_CONTEXT_2D: 5,\n /**\n * `init()` is called before setting {@link View360Options#projection}\n * @ko {@link View360Options#projection}을 설정하기 전에 `init()`이 호출된 경우\n * @since 4.0.0\n */\n PROVIDE_PROJECTION_FIRST: 6,\n /**\n * Failed linking WebGL program. Only can be thrown when {@link View360Options#debug} is `true`.\n * @ko WebGL 프로그램 링크에 실패한 경우. {@link View360Options#debug}를 `true`로 설정한 경우에만 발생할 수 있습니다.\n * @since 4.0.0\n */\n FAILED_LINKING_PROGRAM: 7,\n /**\n * Arguments are not sufficient for the given property.\n * @ko 프로퍼티에 값이 충분히 주어지지 않았을 때\n * @since 4.0.0\n */\n INSUFFICIENT_ARGS: 8\n} as const;\n\nexport const MESSAGES = {\n WRONG_TYPE: (val: any, types: string[]) => `${typeof val} is not a ${types.map(type => `\"${type}\"`).join(\" or \")}.`,\n WRONG_OPTION: (val: any, optionName: string) => `Bad option: given \"${val}\" for option \"${optionName}\".`,\n ELEMENT_NOT_FOUND: (query: string) => `Element with selector \"${query}\" not found.`,\n CANVAS_NOT_FOUND: \"The canvas element was not found inside the given root element.\",\n WEBGL_NOT_SUPPORTED: \"WebGL is not supported on this browser.\",\n FAILED_CREATE_CONTEXT_2D: \"Failed to create canvas 2D context\",\n PROVIDE_PROJECTION_FIRST: \"\\\"projection\\\" should be provided before initialization.\",\n FAILED_LINKING_PROGRAM: (msg: string | null, shaderLog: string | null) => `Failed linking WebGL program - \"${msg}\\nShader compile Log: ${shaderLog}`,\n INSUFFICIENT_ARGS: (val: any, name: string) => `Insufficient arguments: given \"${val}\" for \"${name}\".`\n};\n\nexport default {\n CODES: ERROR_CODES,\n MESSAGES\n};\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nexport const EVENTS = {\n MOUSE_DOWN: \"mousedown\",\n MOUSE_MOVE: \"mousemove\",\n MOUSE_UP: \"mouseup\",\n TOUCH_START: \"touchstart\",\n TOUCH_MOVE: \"touchmove\",\n TOUCH_END: \"touchend\",\n WHEEL: \"wheel\",\n RESIZE: \"resize\",\n CONTEXT_MENU: \"contextmenu\",\n MOUSE_ENTER: \"mouseenter\",\n MOUSE_LEAVE: \"mouseleave\",\n POINTER_DOWN: \"pointerdown\",\n POINTER_MOVE: \"pointermove\",\n POINTER_UP: \"pointerup\",\n POINTER_CANCEL: \"pointercancel\",\n POINTER_ENTER: \"pointerenter\",\n POINTER_LEAVE: \"pointerleave\",\n KEY_DOWN: \"keydown\",\n KEY_UP: \"keyup\",\n LOAD: \"load\",\n ERROR: \"error\",\n CLICK: \"click\",\n DOUBLE_CLICK: \"dblclick\",\n CONTEXT_CREATE_ERROR: \"webglcontextcreationerror\",\n CONTEXT_LOST: \"webglcontextlost\",\n CONTEXT_RESTORED: \"webglcontextrestored\",\n DEVICE_ORIENTATION: \"deviceorientation\",\n DEVICE_MOTION: \"devicemotion\",\n ORIENTATION_CHANGE: \"orientationchange\",\n VIDEO_PLAY: \"play\",\n VIDEO_PAUSE: \"pause\",\n VIDEO_LOADED_DATA: \"loadeddata\",\n VIDEO_VOLUME_CHANGE: \"volumechange\",\n VIDEO_TIME_UPDATE: \"timeupdate\",\n VIDEO_DURATION_CHANGE: \"durationchange\",\n VIDEO_CAN_PLAYTHROUGH: \"canplaythrough\",\n TRANSITION_END: \"transitionend\",\n XR_END: \"end\"\n} as const;\n\nexport const EL_DIV = \"div\";\nexport const EL_BUTTON = \"button\";\n\n// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button\nexport enum MOUSE_BUTTON {\n LEFT,\n MIDDLE,\n RIGHT\n}\n\nexport const CURSOR = {\n GRAB: \"grab\",\n GRABBING: \"grabbing\",\n NONE: \"\"\n} as const;\n\nexport const KEY_DIRECTION = [\"LEFT\", \"UP\", \"RIGHT\", \"DOWN\"] as const;\nexport enum DIRECTION_KEY_CODE {\n LEFT = 37,\n UP = 38,\n RIGHT = 39,\n DOWN = 40\n}\nexport const SPACE_KEY_CODE = 32;\n\nexport const DIRECTION_KEY_NAME = {\n LEFT: \"ArrowLeft\",\n UP: \"ArrowUp\",\n RIGHT: \"ArrowRight\",\n DOWN: \"ArrowDown\"\n} as const;\nexport const SPACE_KEY_NAME = \" \";\n\nexport const FULLSCREEN_REQUEST = [\n \"requestFullscreen\",\n \"webkitRequestFullscreen\",\n \"webkitRequestFullScreen\",\n \"webkitCancelFullScreen\",\n \"mozRequestFullScreen\",\n \"msRequestFullscreen\"\n];\n\nexport const FULLSCREEN_ELEMENT = [\n \"fullscreenElement\",\n \"webkitFullscreenElement\",\n \"webkitCurrentFullScreenElement\",\n \"mozFullScreenElement\",\n \"msFullscreenElement\"\n];\n\nexport const FULLSCREEN_EXIT = [\n \"exitFullscreen\",\n \"webkitExitFullscreen\",\n \"webkitCancelFullScreen\",\n \"mozCancelFullScreen\",\n \"msExitFullscreen\"\n];\n\nexport const FULLSCREEN_CHANGE = [\n \"fullscreenchange\",\n \"webkitfullscreenchange\",\n \"mozfullscreenchange\",\n \"MSFullscreenChange\"\n];\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nexport { ERROR_CODES } from \"./error\";\n\n/**\n * Default class names\n * @ko 기본 클래스 이름들\n * @since 4.0.0\n */\nexport const DEFAULT_CLASS = {\n CONTAINER: \"view360-container\",\n CANVAS: \"view360-canvas\",\n CTX_LOST: \"view360-ctx-lost\",\n IN_VR: \"view360-vr-presenting\",\n HOTSPOT_CONTAINER: \"view360-hotspots\",\n HOTSPOT: \"view360-hotspot\",\n HOTSPOT_VISIBLE: \"view360-hotspot-visible\",\n HOTSPOT_FLIP_X: \"view360-hotspot-flip-x\",\n HOTSPOT_FLIP_Y: \"view360-hotspot-flip-y\",\n} as const;\n\n/**\n * Event names\n * @ko 이벤트 이름들\n * @since 4.0.0\n * @example\n * ```ts\n * import View360, { EVENTS } from \"@egjs/view360\";\n *\n * const viewer = new View360(\"#el_id\");\n *\n * viewer.on(EVENTS.READY, evt => {\n * console.log(\"View360 is ready!\");\n * });\n * ```\n */\nexport const EVENTS = {\n READY: \"ready\",\n LOAD_START: \"loadStart\",\n LOAD: \"load\",\n PROJECTION_CHANGE: \"projectionChange\",\n RESIZE: \"resize\",\n BEFORE_RENDER: \"beforeRender\",\n RENDER: \"render\",\n INPUT_START: \"inputStart\",\n INPUT_END: \"inputEnd\",\n VIEW_CHANGE: \"viewChange\",\n STATIC_CLICK: \"staticClick\",\n VR_START: \"vrStart\",\n VR_END: \"vrEnd\"\n} as const;\n\n/**\n * Collection of predefined easing functions\n * @ko 미리 정의된 easing 함수들\n */\nexport const EASING = {\n LINEAR: (x: number) => x,\n SINE_WAVE: (x: number) => Math.sin(x * Math.PI * 2),\n EASE_OUT_CUBIC: (x: number) => 1 - Math.pow(1 - x, 3),\n EASE_OUT_BOUNCE: (x: number): number => {\n const n1 = 7.5625;\n const d1 = 2.75;\n\n if (x < 1 / d1) {\n return n1 * x * x;\n } else if (x < 2 / d1) {\n return n1 * (x -= 1.5 / d1) * x + 0.75;\n } else if (x < 2.5 / d1) {\n return n1 * (x -= 2.25 / d1) * x + 0.9375;\n } else {\n return n1 * (x -= 2.625 / d1) * x + 0.984375;\n }\n }\n} as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { EASING } from \"./external\";\nimport { Range } from \"../type/utils\";\n\nexport const CAMERA_EVENTS = {\n CHANGE: \"change\",\n ANIMATION_END: \"animationEnd\"\n} as const;\n\nexport const CONTROL_EVENTS = {\n INPUT_START: \"inputStart\",\n CHANGE: \"change\",\n INPUT_END: \"inputEnd\",\n ENABLE: \"enable\",\n DISABLE: \"disable\",\n STATIC_CLICK: \"staticClick\"\n} as const;\n\nexport const DEG_TO_RAD = Math.PI / 180;\nexport const RAD_TO_DEG = 180 / Math.PI;\nexport const DEFAULT_EASING = EASING.EASE_OUT_CUBIC;\nexport const DEFAULT_ANIMATION_DURATION = 300;\nexport const INFINITE_RANGE: Readonly = {\n min: -Infinity, max: Infinity\n} as const;\nexport const DEFAULT_PITCH_RANGE: Readonly = {\n min: -90, max: 90\n} as const;\nexport const DEFAULT_ZOOM_RANGE: Readonly = {\n min: 0.6, max: 10\n} as const;\n\nexport enum ROTATE {\n ZERO,\n CW_90,\n CCW_90,\n CW_180\n}\n\n// Custom event name for video time change\nexport const VIDEO_TIME_CHANGE_EVENT = \"view360videotimechange\";\nexport const SVG_NAMESPACE = \"http://www.w3.org/2000/svg\";\nexport const SESSION_VR = \"immersive-vr\";\nexport const XR_REFERENCE_SPACE = \"local\";\n\nexport const EPSILON = Number.EPSILON ?? 2.220446049250313e-16;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { quat, vec3 } from \"gl-matrix\";\nimport View360Error from \"./core/View360Error\";\nimport ERROR from \"./const/error\";\nimport * as BROWSER from \"./const/browser\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"./const/internal\";\nimport { NoBoolean } from \"./type/utils\";\n\nexport const isString = (val: any): val is string => typeof val === \"string\";\nexport const isElement = (val: any): val is Element => !!val && val.nodeType === Node.ELEMENT_NODE;\n\nexport const createElement = (className: string, tag = BROWSER.EL_DIV) => {\n const el = document.createElement(tag);\n\n el.classList.add(className);\n\n return el;\n};\n\nexport const getNullableElement = (el: HTMLElement | string | null, parent?: HTMLElement): HTMLElement | null => {\n let targetEl: HTMLElement | null = null;\n\n if (isString(el)) {\n const parentEl = parent ? parent : document;\n const queryResult = parentEl.querySelector(el);\n\n if (!queryResult) {\n return null;\n }\n\n targetEl = queryResult as HTMLElement;\n } else if (isElement(el)) {\n targetEl = el;\n }\n\n return targetEl;\n};\n\nexport const getElement = (el: HTMLElement | string, parent?: HTMLElement): HTMLElement => {\n const targetEl = getNullableElement(el, parent);\n\n if (!targetEl) {\n if (isString(el)) {\n throw new View360Error(ERROR.MESSAGES.ELEMENT_NOT_FOUND(el), ERROR.CODES.ELEMENT_NOT_FOUND);\n } else {\n throw new View360Error(ERROR.MESSAGES.WRONG_TYPE(el, [\"HTMLElement\", \"string\"]), ERROR.CODES.WRONG_TYPE);\n }\n }\n\n return targetEl;\n};\n\nexport const findCanvas = (root: HTMLElement, selector: string): HTMLCanvasElement => {\n const canvas = root.querySelector(selector) as HTMLCanvasElement;\n\n if (!canvas) {\n throw new View360Error(ERROR.MESSAGES.CANVAS_NOT_FOUND, ERROR.CODES.CANVAS_NOT_FOUND);\n }\n\n return canvas;\n};\n\nexport const range = (end: number): number[] => {\n if (!end || end <= 0) {\n return [];\n }\n\n return Array.apply(0, Array(end)).map((undef, idx) => idx);\n};\n\nexport const clamp = (x: number, min: number, max: number) => Math.max(Math.min(x, max), min);\n\n// Linear interpolation between a and b\nexport const lerp = (a: number, b: number, t: number) => {\n return a * (1 - t) + b * t;\n};\n\nexport const circulate = (val: number, min: number, max: number) => {\n const size = Math.abs(max - min);\n\n if (val < min) {\n const offset = (min - val) % size;\n val = max - offset;\n } else if (val > max) {\n const offset = (val - max) % size;\n val = min + offset;\n }\n\n return val;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const merge = (target: object, ...srcs: object[]): object => {\n srcs.forEach(source => {\n Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n });\n });\n\n return target;\n};\n\nexport const findIndex = (array: T[], checker: (val: T) => boolean): number => {\n for (let idx = 0; idx < array.length; idx++) {\n if (checker(array[idx])) {\n return idx;\n }\n }\n\n return -1;\n};\n\nexport const getObjectOption = >(val?: T): NoBoolean => typeof val === \"object\" ? val : {} as any;\nexport const toVerticalFov = (fovRadian: number, aspect: number) => {\n return Math.atan(Math.tan(fovRadian * 0.5) / aspect) * 2;\n};\n\nexport const reorderCube = (arr: T[], order: string, defaultOrder = \"RLUDFB\"): T[] => {\n return defaultOrder.split(\"\")\n .map(face => order.indexOf(face))\n .map(index => arr[index]);\n};\n\nexport const isFullscreen = () => {\n if (!document) return false;\n\n for (const key of BROWSER.FULLSCREEN_ELEMENT) {\n if (document[key]) return true;\n }\n\n return false;\n};\n\nexport const sensorCanBeEnabledIOS = () => {\n return !!DeviceMotionEvent && \"requestPermission\" in DeviceMotionEvent && window.isSecureContext;\n};\n\nexport const hfovToZoom = (baseFov: number, fov: number) => {\n const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5);\n const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5);\n\n return renderingWidth / zoomedWidth;\n};\n\nexport const eulerToQuat = (out: quat, yaw: number, pitch: number, roll: number): quat => {\n quat.identity(out);\n\n const pitchThreshold = 0.01;\n const pitchClamped = clamp(pitch, -90 + pitchThreshold, 90 - pitchThreshold);\n\n quat.rotateY(out, out, yaw * DEG_TO_RAD);\n quat.rotateX(out, out, pitchClamped * DEG_TO_RAD);\n quat.rotateZ(out, out, roll * DEG_TO_RAD);\n\n return out;\n};\n\n/**\n * Extract euler angles from the quaternion, except roll(z-axis rotation)\n * @hidden\n */\nexport const quatToEuler = (quaternion: quat) => {\n const x = quaternion[0];\n const y = quaternion[1];\n const z = quaternion[2];\n const w = quaternion[3];\n const x2 = x * x;\n const y2 = y * y;\n const z2 = z * z;\n const w2 = w * w;\n\n const unit = x2 + y2 + z2 + w2;\n const test = x * w - y * z;\n\n let pitch: number, yaw: number;\n\n if (test > 0.499995 * unit) {\n // singularity at the north pole\n pitch = Math.PI / 2;\n yaw = 2 * Math.atan2(y, x);\n } else if (test < -0.499995 * unit) {\n // singularity at the south pole\n pitch = -Math.PI / 2;\n yaw = -2 * Math.atan2(y, x);\n } else {\n const view = vec3.fromValues(0, 0, 1);\n const up = vec3.fromValues(0, 1, 0);\n\n vec3.transformQuat(view, view, quaternion);\n vec3.transformQuat(up, up, quaternion);\n\n const viewXZ = Math.sqrt(view[0] * view[0] + view[2] * view[2]);\n\n pitch = Math.atan2(-view[1], viewXZ);\n yaw = Math.atan2(view[0], view[2]);\n }\n\n return {\n pitch: clamp(pitch * RAD_TO_DEG, -90, 90),\n yaw: circulate(yaw * RAD_TO_DEG, 0, 360)\n };\n};\n","/*\n * Copyright (c) 2020 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport { clamp, lerp, circulate } from \"../utils\";\nimport { Range } from \"../type/utils\";\nimport { DEFAULT_ANIMATION_DURATION, DEFAULT_EASING } from \"../const/internal\";\n\n/**\n * Interpolator between two values with duration\n * @ko 특정 시간동안 두 값을 보간해주는 보간기\n * @since 4.0.0\n */\nclass Motion {\n // Options\n private _duration: number;\n private _loop: boolean;\n private _range: Range;\n private _easing: (x: number) => number;\n\n // Internal states\n private _progress: number;\n private _val: number;\n private _start: number;\n private _end: number;\n private _activated: boolean;\n\n /**\n * Current interpolated value\n * @ko 현재 보간된 값\n * @since 4.0.0\n */\n public get val() { return this._val; }\n /**\n * Start(from) value of interpolation\n * @ko 보간 시작 값\n * @since 4.0.0\n */\n public get start() { return this._start; }\n /**\n * End(to) value of interpolation\n * @ko 보간 끝 값\n * @since 4.0.0\n */\n public get end() { return this._end; }\n /**\n * Interpolation progress value (0 ~ 1)\n * @ko 현재 보간 진행정도 (0 ~ 1)\n * @since 4.0.0\n */\n public get progress() { return this._progress; }\n /**\n * Whether the interpolation is in active state.\n * @ko 보간 진행중인지 여부. `true`일 경우 보간이 진행중입니다.\n * @since 4.0.0\n */\n public get activated() { return this._activated; }\n\n /**\n * Duration of the interpolation\n * @ko 보간할 시간\n * @since 4.0.0\n */\n public get duration() { return this._duration; }\n public set duration(val: number) { this._duration = val; }\n\n /**\n * Whether to loop interpolation on finish\n * @ko 보간이 끝난 이후에 다시 시작할지 여부\n * @since 4.0.0\n */\n public get loop() { return this._loop; }\n public set loop(val: boolean) { this._loop = val; }\n\n /**\n * Range of the interpolation\n * @ko 보간 범위\n * @since 4.0.0\n */\n public get range() { return this._range; }\n\n /**\n * Easing function of the interpolation\n * @ko 보간에 사용되는 easing function\n * @since 4.0.0\n */\n public get easing() { return this._easing; }\n public set easing(val: (x: number) => number) { this._easing = val; }\n\n /**\n * Create new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options Options {@ko 옵션들}\n * @param options.duration Duration of the interpolation {@ko 보간할 시간}\n * @param options.loop Whether to loop interpolation on finish {@ko 보간이 끝난 이후에 다시 시작할지 여부}\n * @param options.range Range of the interpolation {@ko 보간 범위}\n * @param options.loop Easing function of the interpolation {@ko 보간에 사용되는 easing function}\n */\n public constructor({\n duration = DEFAULT_ANIMATION_DURATION,\n loop = false,\n range = { min: 0, max: 1 },\n easing = DEFAULT_EASING\n } = {}) {\n this._duration = duration;\n this._loop = loop;\n this._range = range;\n this._easing = easing;\n this._activated = false;\n this.reset(0);\n }\n\n /**\n * Update motion and progress it by given deltaTime\n * @ko 주어진 deltaTime만큼 보간을 진행합니다.\n * @param deltaTime - number of milisec to update motion {@ko 보간을 진행할 시간, 밀리초 단위}\n * @returns Difference(delta) of the value from the last update. {@ko 지난 업데이트 이후의 값 변화량}\n * @since 4.0.0\n */\n public update(deltaTime: number): number {\n if (!this._activated) {\n this._val = this._end;\n return 0;\n }\n\n const start = this._start;\n const end = this._end;\n const duration = this._duration;\n const prev = this._val;\n const loop = this._loop;\n\n const nextProgress = this._progress + deltaTime / duration;\n\n this._progress = loop\n ? circulate(nextProgress, 0, 1)\n : clamp(nextProgress, 0, 1);\n\n const easedProgress = this._easing(this._progress);\n this._val = lerp(start, end, easedProgress);\n\n if (!loop && this._progress >= 1) {\n this._activated = false;\n }\n\n return this._val - prev;\n }\n\n /**\n * Set `start`, `end` to the given value and set `progress` to 0.\n * @ko 주어진 값으로 시작 지점, 끝 지점을 초기화하고 progress를 0으로 세팅합니다.\n * @param defaultVal - Value to reset {@ko 초기화할 값}\n * @since 4.0.0\n */\n public reset(defaultVal: number): void {\n const range = this._range;\n const val = clamp(defaultVal, range.min, range.max);\n this._start = val;\n this._end = val;\n this._val = val;\n this._progress = 0;\n this._activated = false;\n }\n\n /**\n * Add delta to start & end and current value.\n * @ko 현재 & 끝 및 현재 값에 주어진 값을 더합니다.\n * @param delta - Delta value to add {@ko 추가할 값}\n */\n public add(delta: number) {\n const range = this._range;\n\n this._start = clamp(this._start + delta, range.min, range.max);\n this._end = clamp(this._end + delta, range.min, range.max);\n this._val = clamp(this._val + delta, range.min, range.max);\n }\n\n /**\n * Set current value to start, and end to current value + delta, then reset progress to 0.\n * @ko 현재 값을 시작 지점으로, 그에서 delta만큼 추가된 값을 끝점으로 하고 progress를 0으로 갱신합니다.\n * @param delta - Delta value to add {@ko 추가할 값}\n */\n public setNewEndByDelta(delta: number): void {\n const range = this._range;\n\n this._start = this._val;\n this._end = clamp(this._end + delta, range.min, range.max);\n this._progress = 0;\n this._activated = true;\n }\n\n /**\n * Set new range of the interpolation.\n * @ko 보간의 범위를 변경합니다.\n * @param min - New minimum range {@ko 변경할 범위의 최소값}\n * @param max - New maximum range {@ko 변경할 범위의 최대값}\n */\n public setRange(min: number, max: number) {\n this._start = clamp(this._start, min, max);\n this._end = clamp(this._end, min, max);\n this._range = { min, max };\n }\n}\n\nexport default Motion;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { quat } from \"gl-matrix\";\nimport Camera from \"./Camera\";\nimport Motion from \"./Motion\";\nimport { DEFAULT_ANIMATION_DURATION, DEFAULT_EASING } from \"../const/internal\";\nimport { lerp } from \"../utils\";\n\ntype CameraPose = {\n rotation: quat;\n zoom: number;\n}\n\n/**\n * Animation of the {@link Camera}\n * @internal\n * @ko {@link Camera}의 애니메이션\n * @since 4.0.0\n */\nclass CameraAnimation {\n // Options\n private _camera: Camera;\n private _from: CameraPose;\n private _to: CameraPose;\n\n // Internal values\n private _motion: Motion;\n private _finishPromise: Promise;\n private _finish: () => void;\n\n /**\n * Duration of the animation\n * @ko 애니메이션 재생시간\n * @since 4.0.0\n */\n public get duration() { return this._motion.duration; }\n public set duration(val: number) { this._motion.duration = val; }\n /**\n * Easing function of the animation\n * @ko 애니메이션의 easing function\n * @since 4.0.0\n */\n public get easing() { return this._motion.easing; }\n public set easing(val: (x: number) => number) { this._motion.easing = val; }\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param camera - Camera to animate {@ko 애니메이션을 적용할 카메라}\n * @param from - Start pose {@ko 애니메이션이 시작 시점의 카메라의 회전 및 줌}\n * @param to - End pose {@ko 애니메이션이 끝났을 때 카메라의 회전 및 줌}\n * @param options - Options {@ko 옵션들}\n * @param options.duration - Animation duration {@ko 애니메이션 재생 시간}\n * @param options.easing - Animation easing function {@ko 애니메이션 easing function}\n */\n public constructor(camera: Camera, from: CameraPose, to: CameraPose, {\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING\n } = {}) {\n this._camera = camera;\n this._motion = new Motion({ duration, easing, range: { min: 0, max: 1 } });\n this._from = from;\n this._to = to;\n this._finishPromise = new Promise(resolve => {\n this._finish = resolve as () => void;\n });\n\n // Enable motion\n this._motion.setNewEndByDelta(1);\n }\n\n /**\n * Return a promise that resolved on animation end.\n * @ko 애니메이션 재생이 끝났을 때 resolve되는 Promise를 반환합니다.\n * @since 4.0.0\n */\n public getFinishPromise() {\n return this._finishPromise;\n }\n\n /**\n * Update animation by given deltaTime.\n * @ko 주어진 시간만큼 애니메이션을 업데이트합니다.\n * @param deltaTime Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n */\n public update(deltaTime: number): void {\n const camera = this._camera;\n const from = this._from;\n const to = this._to;\n const motion = this._motion;\n motion.update(deltaTime);\n\n // Progress that easing is applied\n const progress = motion.val;\n const rotation = quat.create();\n const zoom = lerp(from.zoom, to.zoom, progress);\n\n quat.slerp(rotation, from.rotation, to.rotation, progress);\n camera.rotate(rotation, zoom);\n\n if (progress >= 1) {\n this._finish();\n }\n }\n}\n\nexport default CameraAnimation;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { mat4, quat, vec3 } from \"gl-matrix\";\nimport CameraAnimation from \"./CameraAnimation\";\nimport {\n CAMERA_EVENTS,\n DEG_TO_RAD,\n INFINITE_RANGE,\n DEFAULT_PITCH_RANGE,\n RAD_TO_DEG,\n DEFAULT_ZOOM_RANGE,\n DEFAULT_EASING,\n EPSILON\n} from \"../const/internal\";\nimport {\n circulate,\n clamp,\n eulerToQuat,\n quatToEuler,\n toVerticalFov\n} from \"../utils\";\nimport { Range } from \"../type/utils\";\n\n/**\n * Events that {@link Camera} can trigger\n * @ko {@link Camera}가 트리거할 수 있는 이벤트들\n * @since 4.0.0\n */\nexport interface CameraEvents {\n /**\n * An event that fires when camera's animation stops\n * @ko 카메라 애니메이션이 멈췄을 때 트리거되는 이벤트\n * @eventName animationEnd\n * @eventOf Camera\n * @version 4.0.0\n */\n [CAMERA_EVENTS.ANIMATION_END]: {\n animation: CameraAnimation\n };\n}\n\n/**\n * Options for {@link Camera}\n * @ko {@link Camera}용 옵션들\n * @since 4.0.0\n */\nexport interface CameraOptions {\n /**\n * @copy View360#initialYaw\n */\n initialYaw: number;\n /**\n * @copy View360#initialPitch\n */\n initialPitch: number;\n /**\n * @copy View360#initialZoom\n */\n initialZoom: number;\n /**\n * @copy View360#yawRange\n */\n yawRange: Range | null;\n /**\n * @copy View360#pitchRange\n */\n pitchRange: Range | null;\n /**\n * @copy View360#zoomRange\n */\n zoomRange: Range | null;\n /**\n * @copy View360#fov\n */\n fov: number;\n}\n\n/**\n * Camera for View360\n * @ko View360용 카메라 구현체\n * @version 4.0.0\n */\nclass Camera extends Component {\n /**\n * Current yaw(y-axis rotation) value\n * @ko 현재 yaw(y축 회전) 값\n * @since 4.0.0\n */\n public yaw: number;\n /**\n * Current pitch(x-axis rotation) value\n * @ko 현재 pitch(x축 회전) 값\n * @since 4.0.0\n */\n public pitch: number;\n /**\n * Current zoom value\n * @ko 현재 줌 값\n * @since 4.0.0\n */\n public zoom: number;\n\n /**\n * @copy View360#initialYaw\n */\n public initialYaw: number;\n /**\n * @copy View360#initialPitch\n */\n public initialPitch: number;\n /**\n * @copy View360#initialPitch\n */\n public initialZoom: number;\n /**\n * @hidden\n * TODO: Please add comment for this when `rollOffset` is added\n */\n public rollOffset: number;\n\n /**\n * Current camera quaternion\n * @ko 현재 회전을 나타내는 quaternion 값\n * @since 4.0.0\n * @internal\n */\n public quaternion: quat;\n /**\n * Current camera position\n * @ko 현재 카메라 위치 좌표\n * @since 4.0.0\n * @internal\n */\n public position: vec3;\n /**\n * Active camera animation, `null` if there isn't.\n * @ko 현재 활성화된 카메라 애니메이션, 없을 경우 `null`값을 가집니다.\n * @since 4.0.0\n */\n public animation: CameraAnimation | null;\n /**\n * Camera's view matrix\n * @ko 카메라의 뷰 변환 행렬\n * @internal\n * @since 4.0.0\n */\n public viewMatrix: mat4;\n /**\n * Camera's projection matrix\n * @ko 카메라의 프로젝션 변환 행렬\n * @internal\n * @since 4.0.0\n */\n public projectionMatrix: mat4;\n\n /**\n * Camera's horizontal FOV(Field of View) value\n * @ko 카메라의 수평 FOV(Field of View) 값\n * @internal\n * @since 4.0.0\n */\n public fov: number;\n\n private _initialYawRange: Range | null;\n private _initialPitchRange: Range | null;\n private _initialZoomRange: Range | null;\n\n private _yawRange: Range | null;\n private _pitchRange: Range | null;\n private _zoomRange: Range | null;\n\n private _up: vec3;\n private _aspect: number;\n private _changed: boolean;\n private _maxRenderHeight: number;\n\n /**\n * Camera's width / height ratio\n * @ko 카메라의 가로 / 세로 비율\n * @readonly\n */\n public get aspect() { return this._aspect; }\n /**\n * Whether the camera's rotation changed from the last frame.\n * @ko 마지막 프레임 이후로 카메라의 회전값이 변경되었는지 나타내는 플래그.\n * @readonly\n */\n public get changed() { return this._changed; }\n /**\n * @copy View360#yawRange\n */\n public get yawRange() { return this._initialYawRange; }\n public set yawRange(val: Range | null) {\n this._initialYawRange = val;\n }\n /**\n * @copy View360#pitchRange\n */\n public get pitchRange() { return this._initialPitchRange; }\n public set pitchRange(val: Range | null) {\n this._initialPitchRange = val;\n }\n /**\n * @copy View360#zoomRange\n */\n public get zoomRange() { return this._initialZoomRange; }\n public set zoomRange(val: Range | null) {\n this._initialZoomRange = val;\n }\n\n /**\n * Create new instance of Camera\n * @param options - Camera options {@ko 카메라 옵션들}\n */\n public constructor({\n initialYaw,\n initialPitch,\n initialZoom,\n yawRange,\n pitchRange,\n zoomRange,\n fov\n }: CameraOptions) {\n super();\n\n this.yaw = initialYaw;\n this.pitch = initialPitch;\n this.zoom = initialZoom;\n this.rollOffset = 0;\n\n this.initialYaw = initialYaw;\n this.initialPitch = initialPitch;\n this.initialZoom = initialZoom;\n\n this.position = vec3.create();\n this.animation = null;\n\n this._up = vec3.fromValues(0, 1, 0);\n this._aspect = 1;\n\n this._initialYawRange = yawRange;\n this._initialPitchRange = pitchRange;\n this._initialZoomRange = zoomRange;\n\n this._yawRange = yawRange;\n this._pitchRange = pitchRange;\n this._zoomRange = zoomRange;\n\n this.quaternion = quat.create();\n this._updateQuaternion();\n\n this.viewMatrix = mat4.create();\n this.projectionMatrix = mat4.create();\n this.fov = fov;\n\n this._maxRenderHeight = -1;\n }\n\n /**\n * Destroy instance and detach all event listeners\n * @ko 인스턴스를 삭제하고 모든 이벤트 리스너를 삭제합니다.\n * @since 4.0.0\n */\n public destroy() {\n this.off();\n }\n\n /**\n * Refresh internal size value.\n * @ko 내부 크기값을 갱신합니다.\n * @param width - New width {@ko 변경된 너비값}\n * @param height - New height {@ko 변경된 높이값}\n * @since 4.0.0\n */\n public resize(width: number, height: number) {\n const prevAspect = this._aspect;\n\n this._aspect = width / height;\n\n if (this._aspect !== prevAspect) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation with euler values.\n * @ko 카메라 회전을 오일러 각 방향으로 변경합니다.\n * @param rotation - Rotation values {@ko 회전 값}\n * @param rotation.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값}\n * @param rotation.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값}\n * @param rotation.zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @since 4.0.0\n */\n public lookAt({\n yaw = this.yaw,\n pitch = this.pitch,\n zoom = this.zoom\n }: Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n }>) {\n const prevQuaternion = quat.clone(this.quaternion);\n const prevZoom = this.zoom;\n\n this.yaw = circulate(yaw, 0, 360);\n this.pitch = clamp(pitch, -90, 90);\n this.zoom = zoom;\n\n this._updateQuaternion();\n\n const zoomDiff = Math.abs(zoom - prevZoom);\n\n if (\n !quat.equals(this.quaternion, prevQuaternion)\n || zoomDiff >= EPSILON * 10 // ignore small changes\n ) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation with quaternion.\n * @ko 카메라 회전을 Quaternion을 이용해서 변경합니다.\n * @param rotation - Quaternion to apply {@ko 적용할 Quaternion}\n * @param zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @since 4.0.0\n */\n public rotate(rotation: quat, zoom: number = this.zoom) {\n const normalized = quat.normalize(quat.create(), rotation);\n const isSameRotation = quat.equals(this.quaternion, normalized);\n quat.copy(this.quaternion, normalized);\n\n const prevZoom = this.zoom;\n const { yaw, pitch } = quatToEuler(normalized);\n\n this.yaw = yaw;\n this.pitch = pitch;\n this.zoom = zoom;\n\n const zoomDiff = Math.abs(zoom - prevZoom);\n\n if (!isSameRotation || zoomDiff >= EPSILON * 10) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation to given euler values by the given duration.\n * @ko 카메라를 주어진 방향으로 주어진 시간동안 서서히 이동시킵니다.\n * @param options - Animation parameters {@ko 애니메이션 패러미터}\n * @param options.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값}\n * @param options.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값}\n * @param options.zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @param options.duration - Duration of the animation {@ko 애니메이션 시간}\n * @param options.easing - Easing function for the animation {@ko 애니메이션에 적용할 easing function}\n */\n public async animateTo({\n yaw = this.yaw,\n pitch = this.pitch,\n zoom = this.zoom,\n duration = 0,\n easing = DEFAULT_EASING\n }: Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n duration: number;\n easing: (x: number) => number;\n }> = {}): Promise {\n if (\n this.yaw === yaw\n && this.pitch === pitch\n && this.zoom === zoom\n ) return;\n\n const from = {\n rotation: quat.clone(this.quaternion),\n zoom: this.zoom\n };\n const to = {\n rotation: eulerToQuat(quat.create(), yaw, pitch, this.rollOffset),\n zoom\n };\n\n const animation = new CameraAnimation(this, from, to, {\n duration,\n easing\n });\n const finishPromise = animation.getFinishPromise();\n\n this.animation = animation;\n finishPromise.then(() => {\n this.animation = null;\n this.trigger(CAMERA_EVENTS.ANIMATION_END, { animation });\n });\n\n return finishPromise;\n }\n\n /**\n * @hidden\n */\n public restrictYawRange(min: number, max: number) {\n this._yawRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictPitchRange(min: number, max: number) {\n this._pitchRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictZoomRange(min: number, max: number) {\n this._zoomRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictRenderHeight(height: number) {\n this._maxRenderHeight = height;\n }\n\n /**\n * @hidden\n */\n public resetRange() {\n this._yawRange = this._initialYawRange;\n this._pitchRange = this._initialPitchRange;\n this._zoomRange = this._initialZoomRange;\n this._maxRenderHeight = -1;\n }\n\n /**\n * Get actual yaw range by the given zoom value.\n * @ko 주어진 zoom 값에 대한 실제 yaw 범위값을 반환합니다.\n * @since 4.0.0\n */\n public getYawRange(zoom: number) {\n const yawLimit = this._yawRange;\n const maxRenderHeight = this._maxRenderHeight;\n if (!yawLimit) return INFINITE_RANGE;\n\n const halfHFov = this.getHorizontalFov(zoom) * 0.5;\n let minYaw = yawLimit.min;\n let maxYaw = yawLimit.max;\n\n if (maxRenderHeight > 0) {\n const halfVFovRad = toVerticalFov(halfHFov * DEG_TO_RAD, this._aspect);\n const h = maxRenderHeight * 0.5;\n const t = Math.tan(halfVFovRad);\n const d = Math.sqrt((1 + h * h) / (1 + t * t));\n const theta = Math.atan(Math.tan(halfHFov * DEG_TO_RAD) * d) * RAD_TO_DEG;\n\n minYaw = yawLimit.min + theta;\n maxYaw = yawLimit.max - theta;\n }\n\n if (minYaw > maxYaw) {\n minYaw = 0;\n maxYaw = 0;\n }\n\n return {\n min: minYaw,\n max: maxYaw\n };\n }\n\n /**\n * Get actual pitch range by the given zoom value.\n * @ko 주어진 zoom 값에 대한 실제 pitch 범위값을 반환합니다.\n * @since 4.0.0\n */\n public getPitchRange(zoom: number) {\n const pitchLimit = this._pitchRange;\n const maxRenderHeight = this._maxRenderHeight;\n\n if (!pitchLimit) return DEFAULT_PITCH_RANGE;\n\n let minPitch = pitchLimit.min;\n let maxPitch = pitchLimit.max;\n\n if (maxRenderHeight > 0) {\n const halfVFov = this.getVerticalFov(zoom) * 0.5;\n\n minPitch = pitchLimit.min + halfVFov;\n maxPitch = pitchLimit.max - halfVFov;\n }\n\n if (minPitch > maxPitch) {\n minPitch = 0;\n maxPitch = 0;\n }\n\n return {\n min: Math.max(minPitch, -90),\n max: Math.min(maxPitch, 90)\n };\n }\n\n /**\n * Get actual zoom range in fov degrees.\n * @ko 실제 줌 범위를 fov각의 범위로 반환합니다.\n * @since 4.0.0\n */\n public getZoomRange() {\n const limit = this._zoomRange ?? DEFAULT_ZOOM_RANGE;\n\n // max (zoom in) -> minimum fov\n const minFov = this.getHorizontalFov(limit.max);\n const maxFov = this.getHorizontalFov(limit.min);\n const currentFov = this.getHorizontalFov(this.zoom);\n\n return {\n min: Math.max(minFov, 1),\n max: Math.min(maxFov, 180),\n current: currentFov\n };\n }\n\n /**\n * Return horizontal fov value when the given zoom is applied. (in degrees, °)\n * @ko 주어진 zoom 값이 적용되었을 때의 수평 fov값을 반환합니다. (도 단위, °)\n * @returns Zoomed horizontal FOV {@ko 줌이 적용된 수평 fov값}\n * @since 4.0.0\n */\n public getHorizontalFov(zoom = this.zoom) {\n return this._getZoomedHorizontalFov(zoom) * RAD_TO_DEG;\n }\n\n /**\n * Return vertical fov value when the given zoom is applied. (in degrees, °)\n * @ko 주어진 zoom 값이 적용되었을 때의 수직 fov값을 반환합니다. (도 단위, °)\n * @returns Zoomed vertical FOV {@ko 줌이 적용된 수직 fov값}\n * @since 4.0.0\n */\n public getVerticalFov(zoom = this.zoom) {\n const aspect = this._aspect;\n const hFov = this._getZoomedHorizontalFov(zoom); // In radians\n const vFov = toVerticalFov(hFov, aspect);\n\n return vFov * RAD_TO_DEG;\n }\n\n /**\n * Calculate zoom value for the given fov.\n * @ko 주어진 fov값을 zoom값으로 변환합니다.\n * @param fov horizontal fov (in degrees, °) {@ko 수평 fov 값 (도 단위, °)}\n * @since 4.0.0\n */\n public fovToZoom(fov: number) {\n const baseFov = this.fov;\n const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5);\n const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5);\n\n return renderingWidth / zoomedWidth;\n }\n\n /**\n * Update inner matrixes.\n * @ko 내부 행렬들을 업데이트합니다.\n * @internal\n * @since 4.0.0\n */\n public updateMatrix() {\n const up = this._up;\n const aspect = this._aspect;\n const viewMatrix = this.viewMatrix;\n const projMatrix = this.projectionMatrix;\n const position = this.position;\n const rotation = this.quaternion;\n\n const upDir = vec3.create();\n const viewDir = vec3.fromValues(0, 0, -1);\n vec3.transformQuat(viewDir, viewDir, rotation);\n vec3.transformQuat(upDir, up, rotation);\n\n const hFov = this._getZoomedHorizontalFov(); // In radians\n const vFov = toVerticalFov(hFov, aspect);\n\n mat4.lookAt(viewMatrix, position, viewDir, upDir);\n mat4.perspective(projMatrix, vFov, aspect, 0.1, 100);\n\n this._changed = true;\n }\n\n /**\n * @hidden\n */\n public onFrameRender() {\n this._changed = false;\n }\n\n private _updateQuaternion() {\n eulerToQuat(this.quaternion, this.yaw, this.pitch, this.rollOffset);\n }\n\n /**\n * @param zoom Current zoom value\n * @returns horizontal fov including zoom, in radian\n */\n private _getZoomedHorizontalFov(zoom = this.zoom) {\n return 2 * Math.atan(Math.tan(DEG_TO_RAD * this.fov * 0.5) / zoom);\n }\n}\n\nexport default Camera;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass MouseInput extends Component> {\n private _el: HTMLElement | null;\n private _prevPos: [number, number];\n\n public constructor() {\n super();\n\n this._el = null;\n this._prevPos = [0, 0];\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onMouseDown);\n\n this._el = element;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onMouseDown);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this._el = null;\n }\n\n private _onMouseDown = (evt: MouseEvent) => {\n const el = this._el;\n if (!el || evt.button !== BROWSER.MOUSE_BUTTON.LEFT) return;\n\n evt.preventDefault();\n\n if (el.focus) {\n el.focus();\n } else {\n window.focus();\n }\n\n this._prevPos[0] = evt.clientX;\n this._prevPos[1] = evt.clientY;\n\n window.addEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.addEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: false\n });\n }\n\n private _onMouseMove = (evt: MouseEvent) => {\n evt.preventDefault();\n\n const x = evt.clientX;\n const y = evt.clientY;\n const prevPos = this._prevPos;\n const deltaX = x - prevPos[0];\n const deltaY = y - prevPos[1];\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta: {\n x: deltaX,\n y: deltaY\n },\n isTouch: false,\n isKeyboard: false\n });\n\n prevPos[0] = x;\n prevPos[1] = y;\n }\n\n private _onMouseUp = () => {\n this._prevPos[0] = 0;\n this._prevPos[1] = 0;\n\n window.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: false,\n scrolling: false\n });\n }\n}\n\nexport default MouseInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\nimport { isFullscreen } from \"../../utils\";\n\nclass TouchInput extends Component> {\n private _el: HTMLElement | null;\n private _prevPos: [number, number];\n private _isFirstTouch: boolean;\n private _scrolling: boolean;\n private _scrollable: boolean;\n\n public get scrollable() { return this._scrollable; }\n public set scrollable(val: boolean) { this._scrollable = val; }\n\n public constructor() {\n super();\n\n this._el = null;\n this._prevPos = [0, 0];\n this._isFirstTouch = false;\n this._scrolling = false;\n this._scrollable = false;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.TOUCH_START, this._onTouchStart, { passive: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, { passive: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = element;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.TOUCH_START, this._onTouchStart);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = null;\n }\n\n private _onTouchStart = (evt: TouchEvent) => {\n if (evt.touches.length > 1 || this._scrolling) return;\n\n const touch = evt.touches[0];\n\n this._isFirstTouch = true;\n this._prevPos[0] = touch.clientX;\n this._prevPos[1] = touch.clientY;\n\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: true,\n isKeyboard: false\n });\n };\n\n private _onTouchMove = (evt: TouchEvent) => {\n // Only the one finger motion should be considered\n if (evt.touches.length > 1 || this._scrolling) return;\n\n const touch = evt.touches[0];\n const scrollable = this._scrollable;\n const prevPos = this._prevPos;\n\n const x = touch.clientX;\n const y = touch.clientY;\n const deltaX = x - prevPos[0];\n const deltaY = y - prevPos[1];\n\n if (this._isFirstTouch) {\n if (scrollable && !isFullscreen()) {\n if (Math.abs(deltaY) > Math.abs(deltaX)) {\n // Assume Scrolling\n this._scrolling = true;\n return;\n }\n }\n\n this._isFirstTouch = false;\n }\n\n if (evt.cancelable !== false) {\n evt.preventDefault();\n }\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta: {\n x: deltaX,\n y: deltaY\n },\n isTouch: true,\n isKeyboard: false\n });\n\n prevPos[0] = x;\n prevPos[1] = y;\n };\n\n private _onTouchEnd = (evt: TouchEvent) => {\n if (evt.touches.length !== 0) return;\n\n const touch = evt.touches[0];\n const prevPos = this._prevPos;\n\n if (touch) {\n prevPos[0] = touch.clientX;\n prevPos[1] = touch.clientY;\n } else {\n prevPos[0] = 0;\n prevPos[1] = 0;\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: true,\n isKeyboard: false,\n scrolling: this._scrolling\n });\n }\n\n if (evt.cancelable !== false) {\n evt.preventDefault();\n }\n\n this._scrolling = false;\n };\n}\n\nexport default TouchInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass KeyboardInput extends Component> {\n private _el: HTMLElement | null;\n private _pressed: {\n LEFT: boolean;\n UP: boolean;\n RIGHT: boolean;\n DOWN: boolean;\n };\n\n public get active() {\n const pressed = this._pressed;\n return pressed.LEFT || pressed.UP || pressed.RIGHT || pressed.DOWN;\n }\n\n public constructor() {\n super();\n\n this._el = null;\n this._clearPressedKeys();\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown);\n element.addEventListener(BROWSER.EVENTS.KEY_UP, this._onKeyUp);\n\n this._el = element;\n this._clearPressedKeys();\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown);\n element.removeEventListener(BROWSER.EVENTS.KEY_UP, this._onKeyUp);\n\n this._el = null;\n this._clearPressedKeys();\n }\n\n public update() {\n const delta = this._getDeltaByPressedKeys();\n\n if (delta.x !== 0 || delta.y !== 0) {\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: false,\n isKeyboard: true\n });\n }\n }\n\n private _clearPressedKeys() {\n this._pressed = BROWSER.KEY_DIRECTION.reduce((obj, keyName) => {\n return {\n ...obj,\n [keyName]: false\n };\n }, {} as KeyboardInput[\"_pressed\"]);\n }\n\n private _updateKeyPress(event: KeyboardEvent, isEnable: boolean): void {\n const pressed = this._pressed;\n const keyToUpdate = event.keyCode != null\n ? BROWSER.DIRECTION_KEY_CODE[event.keyCode]\n : BROWSER.DIRECTION_KEY_NAME[event.key];\n\n if (!keyToUpdate) return;\n\n pressed[keyToUpdate] = isEnable;\n }\n\n private _getPressedKeyCount() {\n return BROWSER.KEY_DIRECTION.filter(key => this._pressed[key]).length;\n }\n\n private _getDeltaByPressedKeys() {\n const pressed = this._pressed;\n let x = 0;\n let y = 0;\n\n if (pressed.LEFT) {\n x += 1;\n }\n\n if (pressed.RIGHT) {\n x -= 1;\n }\n\n if (pressed.UP) {\n y += 1;\n }\n\n if (pressed.DOWN) {\n y -= 1;\n }\n\n return {\n x, y\n };\n }\n\n private _onKeyDown = (evt: KeyboardEvent) => {\n // Ignore all other keypress except main arrow keys\n if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return;\n\n this._updateKeyPress(evt, true);\n\n const pressedCount = this._getPressedKeyCount();\n if (pressedCount <= 0) return;\n\n evt.preventDefault();\n if (pressedCount === 1 && !evt.repeat) {\n // On first keydown\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: true\n });\n }\n };\n\n private _onKeyUp = (evt: KeyboardEvent) => {\n // Ignore all other keypress except main arrow keys\n if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return;\n\n this._updateKeyPress(evt, false);\n\n const pressedCount = this._getPressedKeyCount();\n if (pressedCount > 0) return;\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: true,\n scrolling: false\n });\n };\n}\n\nexport default KeyboardInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport MouseInput from \"./input/MouseInput\";\nimport TouchInput from \"./input/TouchInput\";\nimport KeyboardInput from \"./input/KeyboardInput\";\nimport Camera from \"../core/Camera\";\nimport Motion from \"../core/Motion\";\nimport { CONTROL_EVENTS, INFINITE_RANGE, DEFAULT_PITCH_RANGE, DEFAULT_ANIMATION_DURATION, DEFAULT_EASING, DEG_TO_RAD, RAD_TO_DEG } from \"../const/internal\";\nimport { toVerticalFov } from \"../utils\";\nimport { ControlEvents, InputEvents } from \"../type/internal\";\n\n/**\n * Options for {@link RotateControl}\n * @ko {@link RotateControl}용 옵션들\n * @since 4.0.0\n */\nexport interface RotateControlOptions {\n /**\n * @copy RotateControl#pointerScale\n */\n pointerScale: [number, number];\n /**\n * @copy RotateControl#keyboardScale\n */\n keyboardScale: [number, number];\n /**\n * @copy RotateControl#duration\n */\n duration: number;\n /**\n * @copy RotateControl#easing\n */\n easing: (x: number) => number;\n /**\n * @copy RotateControl#disablePitch\n */\n disablePitch: boolean;\n /**\n * @copy RotateControl#disableYaw\n */\n disableYaw: boolean;\n /**\n * @copy RotateControl#disableKeyboard\n */\n disableKeyboard: boolean;\n}\n\ntype RotateDeltaType = { x: number; y: number; };\nexport type RotateControlEvents = ControlEvents;\n\n/**\n * Camera's rotation control\n * @ko 카메라의 회전을 담당하는 컨트롤\n * @since 4.0.0\n */\nclass RotateControl extends Component implements CameraControl {\n // Options\n private _pointerScale: RotateControlOptions[\"pointerScale\"];\n private _keyboardScale: RotateControlOptions[\"keyboardScale\"];\n private _duration: RotateControlOptions[\"duration\"];\n private _easing: RotateControlOptions[\"easing\"];\n private _disablePitch: RotateControlOptions[\"disablePitch\"];\n private _disableYaw: RotateControlOptions[\"disableYaw\"];\n private _disableKeyboard: RotateControlOptions[\"disableKeyboard\"];\n\n // Internal values\n private _controlEl: HTMLElement;\n private _enableBlocked: boolean;\n private _mouseInput: MouseInput;\n private _touchInput: TouchInput;\n private _keyboardInput: KeyboardInput;\n private _xMotion: Motion;\n private _yMotion: Motion;\n private _screenScale: [number, number];\n private _zoomScale: number;\n private _enabled: boolean;\n private _changedWhileDragging: boolean;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() {\n return this._keyboardInput.active\n || this._xMotion.activated\n || this._yMotion.activated;\n }\n /**\n * Current yaw value\n * @ko 현재 yaw 값\n * @readonly\n * @since 4.0.0\n */\n public get yaw() { return this._xMotion; }\n /**\n * Current pitch value\n * @ko 현재 pitch 값\n * @readonly\n * @since 4.0.0\n */\n public get pitch() { return this._yMotion; }\n /**\n * @copy View360#scrollable\n */\n public get scrollable() { return this._touchInput.scrollable; }\n public set scrollable(val: boolean) {\n this._touchInput.scrollable = val;\n }\n\n /**\n * Scale factor for mouse/touch rotation\n * @ko 마우스/터치를 통한 회전 배율\n * @default [1, 1]\n * @since 4.0.0\n */\n public get pointerScale() { return this._pointerScale; }\n public set pointerScale(val: RotateControlOptions[\"pointerScale\"]) {\n this._pointerScale = val;\n }\n\n /**\n * Scale factor for keyboard rotation\n * @ko 키보드를 통한 회전 배율\n * @default [1, 1]\n * @since 4.0.0\n */\n public get keyboardScale() { return this._keyboardScale; }\n public set keyboardScale(val: RotateControlOptions[\"keyboardScale\"]) {\n this._keyboardScale = val;\n }\n\n /**\n * Duration of the input animation (ms)\n * @ko 회전 애니메이션의 시간 (ms)\n * @default 300\n */\n public get duration() { return this._duration; }\n public set duration(val: RotateControlOptions[\"duration\"]) {\n this._duration = val;\n this._xMotion.duration = val;\n this._yMotion.duration = val;\n }\n\n /**\n * Easing function of the animation\n * @ko 회전 애니메이션에 적용할 easing 함수\n * @default EASING.EASE_OUT_CUBIC\n * @see EASING\n */\n public get easing() { return this._easing; }\n public set easing(val: RotateControlOptions[\"easing\"]) {\n this._easing = val;\n this._xMotion.easing = val;\n this._yMotion.easing = val;\n }\n\n /**\n * Disable X-axis(pitch) rotation.\n * @ko x축 회전(pitch)을 비활성화합니다.\n * @default false\n */\n public get disablePitch() { return this._disablePitch; }\n public set disablePitch(val: RotateControlOptions[\"disablePitch\"]) { this._disablePitch = val; }\n\n /**\n * Disable Y-axis(yaw) rotation.\n * @ko y축 회전(yaw)을 비활성화합니다.\n * @default false\n */\n public get disableYaw() { return this._disableYaw; }\n public set disableYaw(val: RotateControlOptions[\"disableYaw\"]) { this._disableYaw = val; }\n\n /**\n * Disable rotation by keyboard.\n * @ko 키보드를 이용한 회전을 비활성화합니다.\n * @default false\n */\n public get disableKeyboard() { return this._disableKeyboard; }\n public set disableKeyboard(val: RotateControlOptions[\"disableKeyboard\"]) { this._disableKeyboard = val; }\n\n /**\n * Create new RotateControl instance\n * @ko RotateControl의 인스턴스를 생성합니다.\n * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트}\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(controlEl: HTMLElement, enableBlocked: boolean, {\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING,\n pointerScale = [1, 1],\n keyboardScale = [1, 1],\n disablePitch = false,\n disableYaw = false,\n disableKeyboard = false\n }: Partial = {}) {\n super();\n\n this._controlEl = controlEl;\n this._pointerScale = pointerScale;\n this._keyboardScale = keyboardScale;\n this._duration = duration;\n this._easing = easing;\n this._disablePitch = disablePitch;\n this._disableYaw = disableYaw;\n this._disableKeyboard = disableKeyboard;\n\n this._enableBlocked = enableBlocked;\n this._mouseInput = new MouseInput();\n this._touchInput = new TouchInput();\n this._keyboardInput = new KeyboardInput();\n this._xMotion = new Motion({ duration, range: INFINITE_RANGE, easing });\n this._yMotion = new Motion({ duration, range: DEFAULT_PITCH_RANGE, easing });\n this._screenScale = [1, 1];\n this._zoomScale = 1;\n this._enabled = false;\n this._changedWhileDragging = false;\n this._bindInputs();\n }\n\n public destroy(): void {\n this.disable();\n this._mouseInput.off();\n this._touchInput.off();\n this._keyboardInput.off();\n this.off();\n this._changedWhileDragging = false;\n }\n\n /**\n * @hidden\n */\n public update(delta: number): void {\n if (!this._enabled) return;\n\n const xMotion = this._xMotion;\n const yMotion = this._yMotion;\n const keyboardInput = this._keyboardInput;\n\n if (!this._disableKeyboard) {\n keyboardInput.update();\n }\n\n if (!this._disablePitch) {\n yMotion.update(delta);\n }\n\n if (!this._disableYaw) {\n xMotion.update(delta);\n }\n }\n\n /**\n * @hidden\n */\n public updateRange(camera: Camera, zoom: number) {\n const yawRange = camera.getYawRange(zoom);\n const pitchRange = camera.getPitchRange(zoom);\n\n this._xMotion.setRange(yawRange.min, yawRange.max);\n this._yMotion.setRange(pitchRange.min, pitchRange.max);\n }\n\n /**\n * @hidden\n */\n public setZoomScale(val: number) {\n this._zoomScale = val;\n }\n\n /**\n * Resize control to match target size.\n * @ko 컨트롤의 내부 크기를 갱신합니다.\n * @param hfov - Camera horizontal fov in degrees {@ko 카메라의 수평방향 fov값 (도 단위)}\n * @param aspect - Camera aspect {@ko 카메라 가로/세로 비율}\n * @param width - New width {@ko 갱신된 너비}\n * @param height - New height {@ko 갱신된 높이}\n */\n public resize(hfov: number, aspect: number, width: number, height: number) {\n const vfov = toVerticalFov(hfov * DEG_TO_RAD, aspect) * RAD_TO_DEG;\n\n this._screenScale[0] = hfov / width;\n this._screenScale[1] = vfov / height;\n }\n\n public enable(): void {\n if (this._enabled) return;\n\n const element = this._controlEl;\n\n this._mouseInput.enable(element);\n this._touchInput.enable(element);\n this._keyboardInput.enable(element);\n\n this._enabled = true;\n this._enableBlocked = false;\n\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: true });\n }\n\n public disable(): void {\n if (!this._enabled) return;\n\n this._mouseInput.disable();\n this._touchInput.disable();\n this._keyboardInput.disable();\n\n this._enabled = false;\n\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: true });\n }\n\n public sync(camera: Camera): void {\n this.updateRange(camera, camera.zoom);\n\n this._xMotion.reset(camera.yaw);\n this._yMotion.reset(camera.pitch);\n }\n\n private _bindInputs() {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n const keyboardInput = this._keyboardInput;\n\n mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n touchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n touchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n keyboardInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n keyboardInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n keyboardInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n }\n\n private _onInputStart = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n this._changedWhileDragging = false;\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n ...evt,\n inputType: \"rotate\"\n });\n };\n\n private _onChange = (evt: InputEvents[typeof CONTROL_EVENTS.CHANGE]) => {\n const delta = evt.delta;\n const invZoomScale = 1 / this._zoomScale; // Reduce speed on zoom\n const screenScale = this._screenScale;\n const keyboardScale = this._keyboardScale;\n const pointerScale = this._pointerScale;\n\n let scale: [number, number];\n\n if (evt.isKeyboard) {\n scale = [\n keyboardScale[0] * invZoomScale,\n keyboardScale[1] * invZoomScale\n ];\n } else {\n scale = [\n pointerScale[0] * screenScale[0] * invZoomScale,\n pointerScale[1] * screenScale[1] * invZoomScale\n ];\n }\n\n const scaledX = delta.x * scale[0];\n const scaledY = delta.y * scale[1];\n\n this._xMotion.setNewEndByDelta(scaledX);\n this._yMotion.setNewEndByDelta(scaledY);\n\n this._changedWhileDragging = true;\n }\n\n private _onInputEnd = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n ...evt,\n inputType: \"rotate\"\n });\n\n if (!this._changedWhileDragging && !evt.isKeyboard && !evt.scrolling) {\n this.trigger(CONTROL_EVENTS.STATIC_CLICK, {\n isTouch: evt.isTouch\n });\n }\n\n this._changedWhileDragging = false;\n };\n}\n\nexport default RotateControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS, DEFAULT_ANIMATION_DURATION } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass WheelInput extends Component> {\n private _el: HTMLElement | null;\n private _scrollable: boolean;\n private _baseScale: number;\n private _inputTimer: number;\n\n public get scrollable() { return this._scrollable; }\n public set scrollable(val: boolean) { this._scrollable = val; }\n\n public constructor() {\n super();\n\n this._el = null;\n this._baseScale = 0.04;\n this._scrollable = false;\n this._inputTimer = -1;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.WHEEL, this._onWheel, { passive: false, capture: false });\n\n this._el = element;\n this._clearTimer();\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.WHEEL, this._onWheel, false);\n\n this._el = null;\n this._clearTimer();\n }\n\n private _onWheel = (evt: WheelEvent) => {\n const scrollable = this._scrollable;\n\n if (evt.deltaY === 0 || scrollable) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n\n if (this._inputTimer < 0) {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: false\n });\n } else {\n this._clearTimer();\n }\n\n const delta = this._baseScale * evt.deltaY;\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: false,\n isKeyboard: false\n });\n\n this._inputTimer = window.setTimeout(() => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: false,\n scrolling: false\n });\n this._inputTimer = -1;\n }, DEFAULT_ANIMATION_DURATION);\n };\n\n private _clearTimer() {\n window.clearTimeout(this._inputTimer);\n this._inputTimer = -1;\n }\n}\n\nexport default WheelInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass PinchInput extends Component> {\n private _el: HTMLElement | null;\n private _baseScale: number;\n private _prevDistance: number;\n private _isFirstTouch: boolean;\n\n public constructor() {\n super();\n\n this._el = null;\n this._baseScale = -0.2;\n this._prevDistance = -1;\n this._isFirstTouch = true;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, { passive: false, capture: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = element;\n this._prevDistance = -1;\n this._isFirstTouch = true;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, false);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = null;\n }\n\n private _onTouchMove = (evt: TouchEvent) => {\n const touches = evt.touches;\n if (touches.length !== 2) return;\n\n if (!evt.cancelable) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n\n const prevDistance = this._prevDistance;\n\n const diff = [\n touches[0].pageX - touches[1].pageX,\n touches[0].pageY - touches[1].pageY\n ];\n\n const distance = Math.sqrt(diff[0] * diff[0] + diff[1] * diff[1]) * this._baseScale;\n const delta = this._isFirstTouch\n ? 0\n : distance - prevDistance;\n\n if (this._isFirstTouch) {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: true,\n isKeyboard: false\n });\n }\n\n this._prevDistance = distance;\n this._isFirstTouch = false;\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: true,\n isKeyboard: false\n });\n };\n\n private _onTouchEnd = (evt: TouchEvent) => {\n if (evt.touches.length !== 0) return;\n\n if (!this._isFirstTouch) {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: true,\n isKeyboard: false,\n scrolling: false\n });\n }\n\n this._prevDistance = -1;\n this._isFirstTouch = true;\n };\n}\n\nexport default PinchInput;\n","/*\n* Copyright (c) 2023-present NAVER Corp.\n* egjs projects are licensed under the MIT license\n*/\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport WheelInput from \"./input/WheelInput\";\nimport PinchInput from \"./input/PinchInput\";\nimport Camera from \"../core/Camera\";\nimport Motion from \"../core/Motion\";\nimport {\n CONTROL_EVENTS,\n DEFAULT_ANIMATION_DURATION,\n DEFAULT_EASING,\n INFINITE_RANGE\n} from \"../const/internal\";\nimport { ControlEvents, InputEvents } from \"../type/internal\";\n\n/**\n * Options for {@link ZoomControl}\n * @ko {@link ZoomControl}용 옵션들\n * @since 4.0.0\n */\nexport interface ZoomControlOptions {\n /**\n * @copy ZoomControl#scale\n */\n scale: number;\n /**\n * @copy ZoomControl#duration\n */\n duration: number;\n /**\n * @copy ZoomControl#easing\n */\n easing: (x: number) => number;\n}\n\ntype ZoomControlEvents = ControlEvents;\n\n/**\n * Camera's zoom control\n * @ko 카메라의 줌 값을 담당하는 컨트롤\n * @since 4.0.0\n */\nclass ZoomControl extends Component implements CameraControl {\n // Options\n private _scale: ZoomControlOptions[\"scale\"];\n\n // Internal values\n private _controlEl: HTMLElement;\n private _enableBlocked: boolean;\n private _wheelInput: WheelInput;\n private _pinchInput: PinchInput;\n private _motion: Motion;\n private _enabled: boolean;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() { return this._motion.activated; }\n /**\n * Current zoom value\n * @ko 현재 줌 값\n * @since 4.0.0\n * @readonly\n */\n public get zoom() { return this._motion.val; }\n /**\n * @copy View360#wheelScrollable\n */\n public get scrollable() { return this._wheelInput.scrollable; }\n public set scrollable(val: boolean) {\n this._wheelInput.scrollable = val;\n }\n /**\n * @hidden\n */\n public get range() { return this._motion.range; }\n\n /**\n * Scale factor of the zoom\n * @ko 입력에 의한 줌 배율\n * @default 1\n * @since 4.0.0\n */\n public get scale() { return this._scale; }\n public set scale(val: ZoomControlOptions[\"scale\"]) { this._scale = val; }\n\n /**\n * Duration of the input animation (ms)\n * @ko 회전 애니메이션의 시간 (ms)\n * @default 300\n * @since 4.0.0\n */\n public get duration() { return this._motion.duration; }\n\n /**\n * Easing function of the animation\n * @ko 회전 애니메이션에 적용할 easing 함수\n * @default EASING.EASE_OUT_CUBIC\n * @see EASING\n * @since 4.0.0\n */\n public get easing() { return this._motion.easing; }\n\n /**\n * Create new ZoomControl instance\n * @ko ZoomControl의 인스턴스를 생성합니다.\n * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트}\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(controlEl: HTMLElement, enableBlocked: boolean, {\n scale = 1,\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING\n }: Partial = {}) {\n super();\n\n this._scale = scale;\n\n this._controlEl = controlEl;\n this._enableBlocked = enableBlocked;\n this._wheelInput = new WheelInput();\n this._pinchInput = new PinchInput();\n this._motion = new Motion({\n duration,\n easing,\n range: INFINITE_RANGE\n });\n this._enabled = false;\n\n this._bindInputs();\n }\n\n public destroy(): void {\n this.disable();\n this._wheelInput.off();\n this._pinchInput.off();\n this.off();\n }\n\n /**\n * @hidden\n */\n public update(delta: number): void {\n if (!this._enabled) return;\n\n const motion = this._motion;\n motion.update(delta);\n }\n\n public enable(): void {\n if (this._enabled) return;\n\n const element = this._controlEl;\n this._wheelInput.enable(element);\n this._pinchInput.enable(element);\n\n this._enabled = true;\n this._enableBlocked = false;\n\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: false });\n }\n\n public disable(): void {\n if (!this._enabled) return;\n\n this._wheelInput.disable();\n this._pinchInput.disable();\n\n this._enabled = false;\n\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: false });\n }\n\n public sync(camera: Camera): void {\n const motion = this._motion;\n const range = camera.getZoomRange();\n\n motion.setRange(range.min, range.max);\n motion.reset(range.current);\n }\n\n private _bindInputs() {\n const wheelInput = this._wheelInput;\n const pinchInput = this._pinchInput;\n\n wheelInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n wheelInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n wheelInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n pinchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n pinchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n pinchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n }\n\n private _onInputStart = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n ...evt,\n inputType: \"zoom\"\n });\n };\n\n private _onChange = ({ delta }: InputEvents[typeof CONTROL_EVENTS.CHANGE]) => {\n const scale = this._scale;\n const scaledDelta = delta * scale;\n\n this._motion.setNewEndByDelta(scaledDelta);\n };\n\n private _onInputEnd = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n ...evt,\n inputType: \"zoom\"\n });\n };\n}\n\nexport default ZoomControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { quat, vec3 } from \"gl-matrix\";\nimport * as BROWSER from \"../../const/browser\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\nimport { quatToEuler } from \"../../utils\";\n\nexport const ROTATE_CONSTANT = {\n PITCH_DELTA: 1,\n YAW_DELTA_BY_ROLL: 2,\n YAW_DELTA_BY_YAW: 3\n} as const;\n\nROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = {\n targetAxis: [0, 1, 0],\n meshPoint: [0, 0, 1]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = {\n targetAxis: [0, 1, 0],\n meshPoint: [1, 0, 0]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = {\n targetAxis: [1, 0, 0],\n meshPoint: [0, 0, 1]\n};\n\nclass GyroInput extends Component> {\n public quaternion: quat;\n\n private _ignoreRoll: boolean;\n\n private _yawOrigin: number;\n private _yawOffset: number;\n private _orientation: {\n alpha: number;\n beta: number;\n gamma: number;\n }\n private _orientationUpdated: boolean;\n private _needsCalibrate: boolean;\n private _screenOrientation: number;\n private _enabled: boolean;\n\n public get enabled() { return this._enabled; }\n public get orientationUpdated() { return this._orientationUpdated; }\n public get ignoreRoll() { return this._ignoreRoll; }\n public set ignoreRoll(val: boolean) { this._ignoreRoll = val; }\n\n public constructor() {\n super();\n\n this.quaternion = quat.create();\n\n this._orientation = {\n alpha: 0,\n beta: 90,\n gamma: 0\n };\n this._yawOrigin = 0;\n this._yawOffset = 0;\n this._orientationUpdated = false;\n this._screenOrientation = 0;\n this._needsCalibrate = true;\n this._enabled = false;\n }\n\n public enable() {\n if (this._enabled) return;\n\n window.addEventListener(BROWSER.EVENTS.DEVICE_ORIENTATION, this._onDeviceOrientation);\n window.addEventListener(BROWSER.EVENTS.ORIENTATION_CHANGE, this._updateScreenOrientation);\n\n this._updateScreenOrientation();\n this._orientationUpdated = false;\n this._needsCalibrate = true;\n this._enabled = true;\n }\n\n public disable() {\n if (!this._enabled) return;\n\n window.removeEventListener(BROWSER.EVENTS.DEVICE_ORIENTATION, this._onDeviceOrientation);\n window.removeEventListener(BROWSER.EVENTS.ORIENTATION_CHANGE, this._updateScreenOrientation);\n\n this._enabled = false;\n }\n\n public update() {\n this._updateRotation();\n this._orientationUpdated = false;\n }\n\n public collectDelta() {\n if (!this._orientationUpdated) {\n return {\n pitch: 0,\n yaw: 0\n };\n }\n\n const prevRotation = quat.clone(this.quaternion);\n\n this._updateRotation();\n this._orientationUpdated = false;\n\n return this._toEulerDelta(prevRotation, this.quaternion);\n }\n\n public setInitialRotation(yaw: number) {\n this._yawOrigin = yaw;\n }\n\n private _onDeviceOrientation = (evt: DeviceOrientationEvent) => {\n const prevOrientation = this._orientation;\n const { alpha, beta, gamma } = evt;\n\n if (\n alpha == null\n || beta == null\n || gamma == null\n ) return;\n\n prevOrientation.alpha = alpha;\n prevOrientation.beta = beta;\n prevOrientation.gamma = gamma;\n\n this._orientationUpdated = true;\n\n if (this._needsCalibrate) {\n this._needsCalibrate = false;\n this._calibrateSensor();\n }\n };\n\n private _calibrateSensor() {\n const yawOrigin = this._yawOrigin;\n const rotation = this.quaternion;\n\n this._yawOffset = 0;\n this._updateRotation();\n\n const { yaw: sensorYaw } = quatToEuler(rotation);\n this._yawOffset = sensorYaw - yawOrigin;\n this._updateRotation();\n\n this._needsCalibrate = false;\n }\n\n private _updateRotation() {\n const rotation = this.quaternion;\n const { alpha, beta, gamma } = this._orientation;\n\n quat.identity(rotation);\n quat.rotateY(rotation, rotation, (alpha - this._yawOffset) * DEG_TO_RAD);\n quat.rotateX(rotation, rotation, beta * DEG_TO_RAD);\n quat.rotateZ(rotation, rotation, -gamma * DEG_TO_RAD);\n\n const screen = quat.create();\n const screenAngle = -this._screenOrientation * 0.5 * DEG_TO_RAD;\n const world = quat.fromValues(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5));\n\n quat.set(screen, 0, Math.sin(screenAngle), 0, Math.cos(screenAngle));\n quat.multiply(rotation, rotation, screen);\n quat.multiply(rotation, rotation, world);\n\n quat.normalize(rotation, rotation);\n }\n\n private _updateScreenOrientation = () => {\n if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) {\n this._screenOrientation = screen.orientation.angle;\n } else if (window.orientation !== undefined) {\n this._screenOrientation = window.orientation >= 0 ?\n window.orientation : 360 + window.orientation;\n } else {\n this._screenOrientation = 0;\n }\n }\n\n private _toEulerDelta(prevQuat: quat, currentQuat: quat) {\n return {\n yaw: this._getDeltaYaw(prevQuat, currentQuat),\n pitch: this._getDeltaPitch(prevQuat, currentQuat),\n };\n }\n\n private _getDeltaYaw(prvQ: quat, curQ: quat): number {\n const yawDeltaByYaw = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW);\n const yawDeltaByRoll = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL)\n * Math.sin(this._extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n }\n\n private _getDeltaPitch(prvQ: quat, curQ: quat): number {\n return this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n }\n\n private _getRotationDelta(prevQ: quat, curQ: quat, rotateKind: typeof ROTATE_CONSTANT[keyof typeof ROTATE_CONSTANT]) {\n const targetAxis = vec3.fromValues(\n ROTATE_CONSTANT[rotateKind].targetAxis[0],\n ROTATE_CONSTANT[rotateKind].targetAxis[1],\n ROTATE_CONSTANT[rotateKind].targetAxis[2]\n );\n const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint;\n\n const prevQuaternion = quat.clone(prevQ);\n const curQuaternion = quat.clone(curQ);\n\n quat.normalize(prevQuaternion, prevQuaternion);\n quat.normalize(curQuaternion, curQuaternion);\n\n let prevPoint = vec3.fromValues(0, 0, 1);\n let curPoint = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n vec3.transformQuat(targetAxis, targetAxis, curQuaternion);\n\n const rotateDistance = vec3.dot(targetAxis, vec3.cross(vec3.create(), prevPoint, curPoint));\n const rotateDirection = rotateDistance > 0 ? 1 : -1;\n\n // when counter clock wise, use vec3.fromValues(0,1,0)\n // when clock wise, use vec3.fromValues(0,-1,0)\n // const meshPoint1 = vec3.fromValues(0, 0, 0);\n const meshPoint2 = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n\n let meshPoint3;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n meshPoint3 = vec3.fromValues(0, rotateDirection, 0);\n } else {\n meshPoint3 = vec3.fromValues(rotateDirection, 0, 0);\n }\n\n vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion);\n vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion);\n\n const vecU = meshPoint2;\n const vecV = meshPoint3;\n const vecN = vec3.create();\n\n vec3.cross(vecN, vecU, vecV);\n vec3.normalize(vecN, vecN);\n\n const coefficientA = vecN[0];\n const coefficientB = vecN[1];\n const coefficientC = vecN[2];\n\n // a point on the plane\n curPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n\n // a point should project on the plane\n prevPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n\n // distance between prevPoint and the plane\n let distance = Math.abs(\n prevPoint[0] * coefficientA +\n prevPoint[1] * coefficientB +\n prevPoint[2] * coefficientC\n );\n\n const projectedPrevPoint = vec3.create();\n\n vec3.subtract(projectedPrevPoint, prevPoint, vec3.scale(vec3.create(), vecN, distance));\n\n let trigonometricRatio =\n (projectedPrevPoint[0] * curPoint[0] +\n projectedPrevPoint[1] * curPoint[1] +\n projectedPrevPoint[2] * curPoint[2]) /\n (vec3.length(projectedPrevPoint) * vec3.length(curPoint));\n\n // defensive block\n if (trigonometricRatio > 1) {\n trigonometricRatio = 1;\n }\n\n const theta = Math.acos(trigonometricRatio);\n\n const crossVec = vec3.cross(vec3.create(), curPoint, projectedPrevPoint);\n\n distance = coefficientA * crossVec[0]\n + coefficientB * crossVec[1]\n + coefficientC * crossVec[2];\n\n let thetaDirection: number;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n thetaDirection = distance > 0 ? 1 : -1;\n } else {\n thetaDirection = distance < 0 ? 1 : -1;\n }\n\n const deltaRadian = theta * thetaDirection * rotateDirection;\n\n return deltaRadian * RAD_TO_DEG;\n }\n\n private _extractPitchFromQuat(quaternion: quat) {\n const baseV = vec3.fromValues(0, 0, 1);\n vec3.transformQuat(baseV, baseV, quaternion);\n\n return -1 * Math.atan2(\n baseV[1],\n Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2)));\n }\n}\n\nexport default GyroInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport GyroInput from \"./input/GyroInput\";\nimport Motion from \"../core/Motion\";\nimport Camera from \"../core/Camera\";\nimport * as BROWSER from \"../const/browser\";\nimport { CONTROL_EVENTS } from \"../const/internal\";\nimport { ControlEvents } from \"../type/internal\";\nimport { sensorCanBeEnabledIOS } from \"../utils\";\n\n/**\n * Options for {@link GyroControl}\n * @ko {@link GyroControl}용 옵션들\n * @since 4.0.0\n */\nexport interface GyroControlOptions {\n /**\n * @copy GyroControl#ignoreRoll\n */\n ignoreRoll: boolean;\n}\n\nexport type GyroControlEvents = ControlEvents;\n\n/**\n * Camera's rotation control by gyroscope\n * @ko 자이로스코프를 이용한 회전 컨트롤\n * @since 4.0.0\n */\nclass GyroControl extends Component implements CameraControl {\n // Options\n private _ignoreRoll: GyroControlOptions[\"ignoreRoll\"];\n\n // Internal values\n private _enableBlocked: boolean;\n private _input: GyroInput;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._input.enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() {\n return this._input.enabled && this._input.orientationUpdated;\n }\n\n /**\n * When `true`, ignore gyroscope's roll(z-axis rotation) value.\n * :::caution\n * Setting `false` will ignore camera's range limit.\n * Options like {@link View360Options#yawRange}, {@link View360Options#pitchRange} are ignored, and {@link CylinderProjection} also can't force it's camera range limit.\n * :::\n * @ko `true`일 경우 자이로스코프 입력의 roll(z축 회전)값을 무시합니다.\n * :::caution\n * 이 값을 `false`로 설정할 경우 카메라 범위 제약을 무시합니다.\n * {@link View360Options#yawRange}, {@link View360Options#pitchRange}와 같은 값은 무시되며, {@link CylinderProjection} 사용시에도 범위를 벗어날 수 있습니다.\n * :::\n * @default true\n * @since 4.0.0\n */\n public get ignoreRoll() { return this._ignoreRoll; }\n public set ignoreRoll(val: GyroControlOptions[\"ignoreRoll\"]) { this._ignoreRoll = val; }\n\n /**\n * Return availability of the gyroscope.\n * :::caution\n * This will always return false until user permission under environments like iOS which requires user permission when using gyroscope.\n * :::\n * @ko 자이로스코프 사용 가능 여부를 반환합니다.\n * :::caution\n * iOS와 같이 GyroScope 사용시 사용자 Permission을 요구하는 환경에서는 사용자 Permission을 받기 전까지 항상 `false`입니다.\n * :::\n * @example\n * ```ts\n * const gyroAvailable = await GyroControl.isAvailable();\n * ```\n */\n public static async isAvailable(): Promise {\n if (!DeviceMotionEvent) {\n return false;\n }\n\n let onDeviceMotionChange: (evt: DeviceMotionEvent) => void;\n\n const listenDeviceMotion = () => new Promise(res => {\n onDeviceMotionChange = (evt: DeviceMotionEvent) => {\n res(evt.rotationRate && evt.rotationRate.alpha != null);\n };\n\n window.addEventListener(BROWSER.EVENTS.DEVICE_MOTION, onDeviceMotionChange);\n });\n\n const timeout = () => new Promise(res => {\n setTimeout(() => res(false), 1000);\n });\n\n return Promise.race([listenDeviceMotion(), timeout()])\n .then((available: boolean) => {\n window.removeEventListener(BROWSER.EVENTS.DEVICE_MOTION, onDeviceMotionChange);\n\n return available;\n });\n }\n\n /**\n * Request user permission for gyroscope sensor.\n * This can be used in environments like iOS which requires user permission when using gyroscope sensors.\n * @ko 사용자의 sensor permission 취득을 요청합니다.\n * iOS와 같이 gyroscope 사용시 사용자 Permission을 요구하는 환경에서 사용 가능합니다.\n * @returns Whether the permission is granted {@ko 사용자 permission 취득 여부}\n */\n public static async requestSensorPermission(): Promise {\n // Request sensor permission, on iOS13+\n if (sensorCanBeEnabledIOS()) {\n return (DeviceMotionEvent as typeof DeviceMotionEvent & {\n requestPermission: () => Promise;\n }).requestPermission().then(permissionState => {\n return permissionState === \"granted\";\n }).catch(() => false);\n }\n\n return true;\n }\n\n /**\n * Create new GyroControl instance\n * @ko GyroControl의 인스턴스를 생성합니다.\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(enableBlocked: boolean, {\n ignoreRoll = true\n }: Partial = {}) {\n super();\n\n this._enableBlocked = enableBlocked;\n this._ignoreRoll = ignoreRoll;\n this._input = new GyroInput();\n }\n\n /**\n * @copy CameraControl#destroy\n */\n public destroy(): void {\n this.disable();\n this._input.off();\n this.off();\n }\n\n /**\n * @hidden\n */\n public update(camera: Camera, yaw: Motion, pitch: Motion, zoom: number) {\n if (!this._ignoreRoll) {\n this._updateQuaternion(camera, zoom);\n } else {\n this._updateYawPitch(camera, yaw, pitch, zoom);\n }\n }\n\n /**\n * @copy CameraControl#enable\n */\n public enable(): void {\n if (this._input.enabled) return;\n\n this._input.enable();\n this._enableBlocked = false;\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: false });\n }\n\n /**\n * @copy CameraControl#disable\n */\n public disable(): void {\n if (!this._input.enabled) return;\n\n this._input.disable();\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: false });\n }\n\n /**\n * @copy CameraControl#sync\n */\n public sync(): void {} // eslint-disable-line @typescript-eslint/no-empty-function\n\n private _updateYawPitch(camera: Camera, yaw: Motion, pitch: Motion, zoom: number) {\n const input = this._input;\n if (!input.enabled) return;\n\n const {\n yaw: yawDelta,\n pitch: pitchDelta\n } = input.collectDelta();\n\n yaw.add(yawDelta);\n pitch.add(pitchDelta);\n\n camera.lookAt({\n yaw: yaw.val,\n pitch: pitch.val,\n zoom\n });\n }\n\n private _updateQuaternion(camera: Camera, zoom: number) {\n const input = this._input;\n if (!input.enabled) return;\n\n input.update();\n camera.rotate(input.quaternion, zoom);\n }\n}\n\nexport default GyroControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport CameraControl from \"./CameraControl\";\nimport RotateControl, { RotateControlEvents, RotateControlOptions } from \"./RotateControl\";\nimport ZoomControl, { ZoomControlOptions } from \"./ZoomControl\";\nimport GyroControl, { GyroControlOptions } from \"./GyroControl\";\nimport Camera from \"../core/Camera\";\nimport CameraAnimation from \"../core/CameraAnimation\";\nimport * as BROWSER from \"../const/browser\";\nimport { CAMERA_EVENTS, CONTROL_EVENTS } from \"../const/internal\";\nimport { ValueOf } from \"../type/utils\";\nimport { getObjectOption, hfovToZoom } from \"../utils\";\n\n/**\n * Options for {@link PanoControl}\n * @ko {@link PanoControl}용 옵션들\n * @since 4.0.0\n */\nexport interface PanoControlOptions {\n /**\n * @copy View360#useGrabCursor\n */\n useGrabCursor: boolean;\n /**\n * @copy View360#scrollable\n */\n scrollable: boolean;\n /**\n * @copy View360#wheelScrollable\n */\n wheelScrollable: boolean;\n /**\n * @copy View360#disableContextMenu\n */\n disableContextMenu: boolean;\n /**\n * Options for {@link RotateControl}.\n * `false` to disable rotation.\n * @ko {@link RotateControl}용 옵션들.\n * `false`일 경우 회전이 비활성화됩니다.\n * @since 4.0.0\n */\n rotate: boolean | Partial;\n /**\n * Options for {@link ZoomControl}.\n * `false` to disable zoom.\n * @ko {@link ZoomControl}용 옵션들.\n * `false`일 경우 줌이 비활성화됩니다.\n * @since 4.0.0\n */\n zoom: boolean | Partial;\n /**\n * Options for {@link GyroControl}.\n * `false` to disable gyroscope control.\n * @ko {@link GyroControl}용 옵션들.\n * `false`일 경우 자이로스코프를 통한 컨트롤이 비활성화됩니다.\n * @since 4.0.0\n */\n gyro: boolean | Partial;\n}\n\n/**\n * Panorama control for View360\n * @ko View360용 파노라마 컨트롤\n * @since 4.0.0\n */\nclass PanoControl {\n // Options\n private _useGrabCursor: PanoControlOptions[\"useGrabCursor\"];\n private _disableContextMenu: PanoControlOptions[\"disableContextMenu\"];\n\n // Internal Values\n private _camera: Camera;\n private _controlEl: HTMLElement;\n private _rotateControl: RotateControl;\n private _zoomControl: ZoomControl;\n private _gyroControl: GyroControl;\n private _ignoreZoomScale: boolean;\n private _enabled: boolean;\n\n /**\n * @copy View360#useGrabCursor\n */\n public get useGrabCursor() { return this._useGrabCursor; }\n public set useGrabCursor(val: PanoControlOptions[\"useGrabCursor\"]) {\n if (val === this._useGrabCursor) return;\n\n this._useGrabCursor = val;\n\n if (val && this._enabled) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n } else if (!val) {\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n }\n\n /**\n * @copy View360#disableContextMenu\n */\n public get disableContextMenu() { return this._disableContextMenu; }\n public set disableContextMenu(val: PanoControlOptions[\"disableContextMenu\"]) {\n if (val === this._disableContextMenu) return;\n\n this._disableContextMenu = val;\n\n if (val && this._enabled) {\n this._blockContextMenu();\n } else if (!val) {\n this._restoreContextMenu();\n }\n }\n\n /**\n * @copy View360#disableContextMenu\n */\n public get scrollable() { return this._rotateControl.scrollable; }\n public set scrollable(val: PanoControlOptions[\"scrollable\"]) { this._rotateControl.scrollable = val; }\n /**\n * @copy View360#disableContextMenu\n */\n public get wheelScrollable() { return this._zoomControl.scrollable; }\n public set wheelScrollable(val: PanoControlOptions[\"wheelScrollable\"]) { this._zoomControl.scrollable = val; }\n /**\n * When `true`, disables rotation slow-down by zoom-value.\n * @ko `true`일 경우 줌 된 정도에 따라 회전속도를 늦추는 동작을 비활성화합니다.\n * @since 4.0.0\n */\n public get ignoreZoomScale() { return this._ignoreZoomScale; }\n public set ignoreZoomScale(val: boolean) { this._ignoreZoomScale = val; }\n\n /**\n * Whether the control is enabled or not\n * @ko 컨트롤 활성화 여부를 가리키는 값\n * @readonly\n * @since 4.0.0\n */\n public get enabled() { return this._enabled; }\n /**\n * @copy View360#rotate\n */\n public get rotate() { return this._rotateControl; }\n /**\n * @copy View360#zoom\n */\n public get zoom() { return this._zoomControl; }\n /**\n * @copy View360#gyro\n */\n public get gyro() { return this._gyroControl; }\n\n /**\n * Whether one of the controls is animating at the moment\n * @ko 현재 컨트롤 중 하나라도 동작중인지 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get animating() {\n return this._rotateControl.animating\n || this._zoomControl.animating\n || this._gyroControl.animating;\n }\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param element - Canvas element {@ko 캔버스 엘리먼트}\n * @param camera - Camera instance {@ko Camera 인스턴스}\n * @param options - Options for PanoControl {@ko PanoControl 옵션들}\n */\n public constructor(element: HTMLElement, camera: Camera, {\n useGrabCursor,\n scrollable,\n wheelScrollable,\n disableContextMenu,\n rotate,\n zoom,\n gyro\n }: PanoControlOptions) {\n // Bind Options\n this._useGrabCursor = useGrabCursor;\n this._disableContextMenu = disableContextMenu;\n\n // Set internal values\n this._camera = camera;\n this._controlEl = element;\n this._ignoreZoomScale = false;\n this._enabled = false;\n\n this._rotateControl = new RotateControl(element, !rotate, getObjectOption(rotate));\n this._zoomControl = new ZoomControl(element, !zoom, getObjectOption(zoom));\n this._gyroControl = new GyroControl(!gyro, getObjectOption(gyro));\n\n this._rotateControl.scrollable = scrollable;\n this._zoomControl.scrollable = wheelScrollable;\n\n this._bindEvents();\n }\n\n /**\n * Destroy the instance and remove all event listeners attached.\n * This also will reset CSS cursor to initial.\n * @ko 인스턴스를 삭제하고 부착된 모든 이벤트 리스너를 제거합니다.\n * 또한, 캔버스에 적용된 CSS cursor도 제거합니다.\n * @since 4.0.0\n */\n public destroy(): void {\n this.disable();\n this._rotateControl.destroy();\n this._zoomControl.destroy();\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n\n /**\n * Resize control to match target size.\n * @ko 컨트롤이 내부에 캐시하고 있는 크기값을 갱신합니다.\n * @param width New width {@ko 변경된 너비}\n * @param height New height {@ko 변경된 높이}\n * @since 4.0.0\n */\n public resize(width: number, height: number): void {\n const camera = this._camera;\n\n this._rotateControl.resize(camera.fov, camera.aspect, width, height);\n }\n\n /**\n * Enable this control and add event listeners.\n * @ko 컨트롤을 활성화하고 이벤트 리스너들을 추가합니다.\n * @since 4.0.0\n */\n public async enable(): Promise {\n if (this._enabled) return;\n\n if (!this._rotateControl.enableBlocked) {\n this._rotateControl.enable();\n }\n\n if (!this._zoomControl.enableBlocked) {\n this._zoomControl.enable();\n }\n\n if (!this._gyroControl.enableBlocked) {\n if (await GyroControl.isAvailable()) {\n this._gyroControl.enable();\n }\n }\n\n this.sync();\n\n if (this._disableContextMenu) {\n this._blockContextMenu();\n }\n\n this._enabled = true;\n }\n\n /**\n * Disable this control and remove all event listeners\n * @ko 컨트롤을 비활성화하고 모든 이벤트 리스너들을 제거합니다.\n * @since 4.0.0\n */\n public disable(): void {\n if (!this._enabled) return;\n\n this._rotateControl.disable();\n this._zoomControl.disable();\n this._gyroControl.disable();\n\n this._restoreContextMenu();\n\n this._enabled = false;\n }\n\n /**\n * Update control by given deltaTime\n * @ko 컨트롤을 주어진 시간만큼 업데이트합니다.\n * @param delta Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n * @internal\n */\n public update(delta: number): void {\n const camera = this._camera;\n const rotateControl = this._rotateControl;\n const zoomControl = this._zoomControl;\n const gyroControl = this._gyroControl;\n\n zoomControl.update(delta);\n const zoom = hfovToZoom(camera.fov, zoomControl.zoom);\n\n // Slow down rotation on zoom-in\n const zoomScale = this._ignoreZoomScale ? 1 : Math.max(zoom, 1);\n rotateControl.setZoomScale(zoomScale);\n rotateControl.updateRange(camera, zoom);\n rotateControl.update(delta);\n\n const yaw = rotateControl.yaw;\n const pitch = rotateControl.pitch;\n\n if (gyroControl.enabled) {\n gyroControl.update(camera, yaw, pitch, zoom);\n } else {\n camera.lookAt({\n yaw: yaw.val,\n pitch: pitch.val,\n zoom\n });\n }\n }\n\n /**\n * Synchronize this control's state to current camera state\n * @ko 컨트롤을 카메라의 현재 상태와 동기화합니다.\n * @since 4.0.0\n */\n public sync(): void {\n const camera = this._camera;\n\n this._zoomControl.sync(camera);\n this._rotateControl.sync(camera);\n }\n\n private _blockContextMenu() {\n const el = this._controlEl;\n\n el.addEventListener(BROWSER.EVENTS.CONTEXT_MENU, this._preventContextMenu);\n }\n\n private _restoreContextMenu() {\n const el = this._controlEl;\n\n el.removeEventListener(BROWSER.EVENTS.CONTEXT_MENU, this._preventContextMenu);\n }\n\n private _preventContextMenu = (evt: MouseEvent) => {\n evt.preventDefault();\n };\n\n private _setCursor(newCursor: ValueOf) {\n if (!this._useGrabCursor && newCursor !== BROWSER.CURSOR.NONE) return;\n\n const targetEl = this._controlEl;\n targetEl.style.cursor = newCursor;\n }\n\n private _bindEvents() {\n const rotateControl = this._rotateControl;\n const zoomControl = this._zoomControl;\n\n rotateControl.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n rotateControl.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n rotateControl.on(CONTROL_EVENTS.ENABLE, this._onEnable);\n rotateControl.on(CONTROL_EVENTS.DISABLE, this._onDisable);\n zoomControl.on(CONTROL_EVENTS.ENABLE, this._onEnable);\n zoomControl.on(CONTROL_EVENTS.DISABLE, this._onDisable);\n this._camera.on(CAMERA_EVENTS.ANIMATION_END, this._onCameraAnimationEnd);\n }\n\n private _onInputStart = (evt: RotateControlEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n if (this._useGrabCursor && !evt.isKeyboard) {\n this._setCursor(BROWSER.CURSOR.GRABBING);\n }\n };\n\n private _onInputEnd = (evt: RotateControlEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n if (this._useGrabCursor && !evt.isKeyboard) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n }\n };\n\n private _onEnable = ({\n control,\n updateCursor\n }: {\n control: CameraControl;\n updateCursor: boolean;\n }) => {\n if (updateCursor && this._useGrabCursor) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n }\n\n control.sync(this._camera);\n };\n\n private _onDisable = ({\n updateCursor\n }: {\n updateCursor: boolean\n }) => {\n if (updateCursor) {\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n };\n\n private _onCameraAnimationEnd = ({ animation }: { animation: CameraAnimation }) => {\n animation.getFinishPromise().then(() => {\n this.sync();\n });\n };\n}\n\nexport default PanoControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport TextureVideo from \"./TextureVideo\";\nimport TextureCube from \"./TextureCube\";\n\n/**\n * @hidden\n */\nabstract class Texture {\n public width: number;\n public height: number;\n public flipY: boolean;\n public wrapS: number;\n public wrapT: number;\n\n public constructor({\n width,\n height,\n flipY\n }: {\n width: number;\n height: number;\n flipY: boolean;\n }) {\n this.width = width;\n this.height = height;\n this.flipY = flipY;\n this.wrapS = WebGLRenderingContext.CLAMP_TO_EDGE;\n this.wrapT = WebGLRenderingContext.CLAMP_TO_EDGE;\n }\n\n public destroy() {\n // DO_NOTHING\n }\n\n public isVideo(): this is TextureVideo {\n return false;\n }\n\n public isCube(): this is TextureCube {\n return false;\n }\n}\n\nexport default Texture;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture from \"./Texture\";\n\n/**\n * @hidden\n */\nclass Texture2D extends Texture {\n public source: Exclude;\n\n public constructor({\n source,\n width,\n height,\n flipY\n }: {\n source: Exclude;\n width: number;\n height: number;\n flipY: boolean;\n }) {\n super({\n width,\n height,\n flipY\n });\n\n this.source = source;\n }\n}\n\nexport default Texture2D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"./Texture2D\";\n\n/**\n * @hidden\n */\nclass TextureVideo extends Texture2D {\n public source: HTMLVideoElement;\n\n public destroy() {\n const video = this.source;\n\n video.pause();\n video.removeAttribute(\"src\");\n video.load();\n }\n\n public isVideo(): this is TextureVideo { return true; }\n\n public isPaused() {\n const video = this.source;\n\n return video.paused || video.ended || video.readyState <= 2;\n }\n\n public hasAudio() {\n const video = this.source as any;\n\n if (video.audioTracks) {\n return video.audioTracks.length > 0;\n }\n\n if (video.webkitAudioDecodedByteCount != null) {\n return video.webkitAudioDecodedByteCount > 0;\n }\n\n if (video.mozHasAudio != null) {\n return video.mozHasAudio;\n }\n\n // We don't know whether the video has audio or not, return true\n return true;\n }\n}\n\nexport default TextureVideo;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture from \"./Texture\";\n\n/**\n * @hidden\n */\nclass TextureCube extends Texture {\n public sources: TexImageSource[];\n\n public constructor({\n sources,\n width,\n height,\n flipY\n }: {\n sources: TexImageSource[];\n width: number;\n height: number;\n flipY: boolean;\n }) {\n super({\n width,\n height,\n flipY\n });\n\n this.sources = sources;\n }\n\n public isCube(): this is TextureCube { return true; }\n}\n\nexport default TextureCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ImReady from \"@egjs/imready\";\nimport Texture from \"../texture/Texture\";\nimport Texture2D from \"../texture/Texture2D\";\nimport TextureVideo from \"../texture/TextureVideo\";\nimport TextureCube from \"../texture/TextureCube\";\nimport { getObjectOption, isString } from \"../utils\";\nimport { VideoConfig } from \"../type/external\";\nimport { ProjectionOptions } from \"../projection/Projection\";\n\n/**\n * @hidden\n */\nclass TextureLoader {\n private _loadChecker: ImReady;\n\n constructor() {\n this._loadChecker = new ImReady();\n }\n\n public async load(src: ProjectionOptions[\"src\"], video: ProjectionOptions[\"video\"]): Promise {\n if (video) {\n return this.loadVideo(src, getObjectOption(video));\n } else {\n if (Array.isArray(src) && src.length > 1) {\n return this.loadCubeImage(src);\n } else {\n const imgSrc = Array.isArray(src) ? src[0] : src;\n return this.loadImage(imgSrc);\n }\n }\n }\n\n public async loadImage(src: string | HTMLElement): Promise {\n const images = this._toImageArray(src);\n\n return this._load(images, resolve => {\n const image = images[0];\n\n resolve(new Texture2D({\n source: image,\n width: image.naturalWidth,\n height: image.naturalHeight,\n flipY: true\n }));\n });\n }\n\n public async loadCubeImage(src: Array): Promise {\n const images = this._toImageArray(src);\n\n return this._load(images, resolve => {\n resolve(new TextureCube({\n sources: images,\n width: images[0].naturalWidth,\n height: images[0].naturalHeight,\n flipY: false\n }));\n });\n }\n\n public async loadVideo(src: ProjectionOptions[\"src\"], videoConfig: Partial): Promise {\n const config: VideoConfig = {\n autoplay: true,\n muted: true,\n loop: false,\n volume: 1,\n ...videoConfig,\n };\n const video = this._toVideoElement(src, config);\n\n return this._load([video], resolve => {\n const { autoplay, muted } = config;\n\n video.currentTime = 0;\n if (autoplay && muted) {\n video.play().catch(() => void 0);\n }\n\n resolve(new TextureVideo({\n source: video,\n width: video.videoWidth,\n height: video.videoHeight,\n flipY: true\n }));\n });\n }\n\n private _load(content: HTMLElement[], onLoad: (resolve: (value: T) => void) => void): Promise {\n const loader = this._loadChecker;\n\n return new Promise((resolve, reject) => {\n loader.once(\"ready\", evt => {\n if (evt.errorCount > 0) return;\n\n onLoad(resolve);\n });\n\n loader.once(\"error\", reject);\n loader.check(content);\n });\n }\n\n private _toImageArray(src: ProjectionOptions[\"src\"]): HTMLImageElement[] {\n const srcs = Array.isArray(src) ? src : [src];\n\n return srcs.map(source => {\n if (isString(source)) {\n const imgEl = new Image();\n\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = source;\n\n return imgEl;\n } else {\n return source as HTMLImageElement;\n }\n });\n }\n\n private _toVideoElement(src: ProjectionOptions[\"src\"], {\n muted,\n loop,\n volume\n }: VideoConfig): HTMLVideoElement {\n if (src instanceof HTMLVideoElement) {\n return src;\n }\n\n const video = document.createElement(\"video\");\n\n video.crossOrigin = \"anonymous\";\n video.playsInline = true;\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.muted = muted;\n video.volume = volume;\n video.loop = loop;\n\n if (Array.isArray(src)) {\n src.forEach(source => this._appendSourceElement(video, source));\n } else {\n this._appendSourceElement(video, src);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0 && video.readyState < 1) {\n video.load();\n }\n\n return video;\n }\n\n private _appendSourceElement(video: HTMLMediaElement, src: string | HTMLElement) {\n if (src instanceof HTMLSourceElement) {\n return src;\n }\n\n const sourceEl = document.createElement(\"source\");\n sourceEl.src = src as string;\n video.appendChild(sourceEl);\n }\n}\n\nexport default TextureLoader;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * @internal\n */\nclass FrameAnimator {\n public maxDeltaTime: number;\n\n private _context: Window | XRSession;\n private _rafId: number;\n private _rafTimer: number;\n private _lastUpdateTime: number;\n\n /** */\n public constructor(maxDeltaTime: number, context: Window | XRSession = window) {\n this.maxDeltaTime = maxDeltaTime;\n\n this._context = context;\n this._rafId = -1;\n this._rafTimer = -1;\n this._lastUpdateTime = -1;\n }\n\n public start(callback: (delta: number, ...args: any[]) => any) {\n const context = this._context;\n\n // No context / callback set\n if (!context || !callback) return;\n\n // Animation already started\n if (this._rafId >= 0 || this._rafTimer >= 0) return;\n\n const loop = (_time: number, frame?: XRFrame) => {\n const time = Date.now();\n const delta = Math.min(time - this._lastUpdateTime, this.maxDeltaTime * 1000);\n\n callback(delta, frame);\n\n this._lastUpdateTime = time;\n this._rafId = context.requestAnimationFrame(loop);\n };\n\n this._lastUpdateTime = Date.now();\n this._rafId = context.requestAnimationFrame(loop);\n }\n\n public stop() {\n if (this._rafId >= 0) {\n this._context.cancelAnimationFrame(this._rafId);\n }\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n }\n\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n public changeContext(context: Window | XRSession) {\n this.stop();\n this._context = context;\n }\n}\n\nexport default FrameAnimator;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport * as BROWSER from \"../const/browser\";\n\n/**\n * Automatic resizer that uses both ResizeObserver and window resize event\n */\nclass AutoResizer {\n private _enabled: boolean;\n private _resizeObserver: ResizeObserver | null;\n private _useResizeObserver: boolean;\n private _onResize: () => any;\n\n public get useResizeObserver() { return this._useResizeObserver; }\n\n /**\n * Returns whether AutoResizer is enabled\n */\n public get enabled() { return this._enabled; }\n\n /** */\n public constructor(useResizeObserver: boolean, onResize: () => any) {\n this._useResizeObserver = useResizeObserver;\n\n this._enabled = false;\n this._resizeObserver = null;\n this._onResize = onResize;\n }\n\n /**\n * Enable resizer\n */\n public enable(element: HTMLElement): this {\n if (this._enabled) {\n this.disable();\n }\n\n if (this._useResizeObserver && !!window.ResizeObserver) {\n const bbox = element.getBoundingClientRect();\n const resizeImmediate = bbox.width !== 0 || bbox.height !== 0;\n\n const resizeObserver = new ResizeObserver(resizeImmediate ? this._skipFirstResize : this._onResize);\n\n resizeObserver.observe(element);\n\n this._resizeObserver = resizeObserver;\n } else {\n window.addEventListener(BROWSER.EVENTS.RESIZE, this._onResize);\n }\n\n this._enabled = true;\n\n return this;\n }\n\n /**\n * Disable resizer\n */\n public disable(): this {\n if (!this._enabled) return this;\n\n const resizeObserver = this._resizeObserver;\n if (resizeObserver) {\n resizeObserver.disconnect();\n this._resizeObserver = null;\n } else {\n window.removeEventListener(BROWSER.EVENTS.RESIZE, this._onResize);\n }\n\n this._enabled = false;\n\n return this;\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n private _skipFirstResize = (() => {\n let isFirstResize = true;\n\n return (() => {\n if (isFirstResize) {\n isFirstResize = false;\n\n return;\n }\n this._onResize();\n });\n })();\n}\n\nexport default AutoResizer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Camera from \"./Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport View360 from \"../View360\";\nimport * as BROWSER from \"../const/browser\";\nimport { CONTROL_EVENTS } from \"../const/internal\";\nimport { circulate, getObjectOption } from \"../utils\";\n\n/**\n * Options for {@link Autoplay}\n * @ko {@link Autoplay}용 옵션들\n * @since 4.0.0\n */\nexport interface AutoplayOptions {\n /**\n * @copy Autoplay#delay\n */\n delay: number;\n /**\n * @copy Autoplay#delayOnMouseLeave\n */\n delayOnMouseLeave: number;\n /**\n * @copy Autoplay#speed\n */\n speed: number;\n /**\n * @copy Autoplay#pauseOnHover\n */\n pauseOnHover: boolean;\n /**\n * @copy Autoplay#canInterrupt\n */\n canInterrupt: boolean;\n /**\n * @copy Autoplay#disableOnInterrupt\n */\n disableOnInterrupt: boolean;\n}\n\n/**\n * A manager class for autoplay feature.\n * @ko Autoplay 기능의 매니저 클래스.\n * @since 4.0.0\n */\nclass Autoplay {\n // Options\n private _delay: number;\n private _delayOnMouseLeave: number;\n private _speed: number;\n private _pauseOnHover: boolean;\n private _canInterrupt: boolean;\n private _disableOnInterrupt: boolean;\n\n // Internal values\n private _enableBlocked: boolean;\n private _camera: Camera;\n private _control: PanoControl;\n private _element: HTMLElement;\n private _enabled: boolean;\n private _interrupted: boolean;\n private _interruptionTimer: number;\n private _hovering: boolean;\n\n /**\n * Whether autoplay is enabled or not\n * @ko 자동재생 활성화 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * Whether autoplay is updating the camera at the moment\n * @ko 현재 자동재생이 동작중인지 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get playing() {\n return this._enabled && !this._interrupted;\n }\n\n /**\n * Reactivation delay after mouse input in milisecond.\n * @ko 재활성화되기까지의 시간 (밀리초 단위)\n * @default 2000\n * @since 4.0.0\n */\n public get delay() { return this._delay; }\n public set delay(val: number) { this._delay = val; }\n\n /**\n * Reactivation delay after mouse leave when using {@link AutoplayOptions#pauseOnHover}\n * @ko {@link AutoplayOptions#pauseOnHover} 사용시 마우스가 캔버스 영역을 떠난 뒤 자동재생이 다시 활성화되기까지의 시간\n * @default 0\n * @since 4.0.0\n */\n public get delayOnMouseLeave() { return this._delayOnMouseLeave; }\n public set delayOnMouseLeave(val: number) { this._delayOnMouseLeave = val; }\n\n /**\n * Y-axis(yaw) rotation speed\n * @ko Y-축 회전(yaw)의 속도\n * @default 1\n * @since 4.0.0\n */\n public get speed() { return this._speed; }\n public set speed(val: number) { this._speed = val; }\n\n /**\n * Whether to pause rotation on mouse hover\n * @ko 마우스가 캔버스 영역에 들어왔을 때 자동재생을 정지할지 여부\n * @default false\n * @since 4.0.0\n */\n public get pauseOnHover() { return this._pauseOnHover; }\n public set pauseOnHover(val: boolean) { this._pauseOnHover = val; }\n\n /**\n * Whether user can interrupt the rotation with click/wheel input\n * @ko 클릭이나 휠같은 사용자 인터랙션시 자동재생을 멈출지 여부\n * @default true\n * @since 4.0.0\n */\n public get canInterrupt() { return this._canInterrupt; }\n public set canInterrupt(val: boolean) { this._canInterrupt = val; }\n\n /**\n * Whether to disable autoplay on user interrupt\n * @ko 사용자 동작에 의해 자동재생이 정지할 때, {@link Autoplay#disable}을 호출하여 자동재생을 영구히 정지할지 여부\n * @default false\n * @since 4.0.0\n */\n public get disableOnInterrupt() { return this._disableOnInterrupt; }\n public set disableOnInterrupt(val: boolean) { this._disableOnInterrupt = val; }\n\n /**\n * Create new AutoPlayer instance\n * @param camera - Instance of the {@link Camera} {@ko Camera의 인스턴스}\n * @param element - Canvas element {@ko 캔버스 엘리먼트}\n * @param options - Autoplay options {@ko 자동재생 옵션들}\n * @since 4.0.0\n */\n public constructor(viewer: View360, element: HTMLElement, options: boolean | Partial) {\n this._camera = viewer.camera;\n this._control = viewer.control;\n this._element = element;\n\n this._enabled = false;\n this._interrupted = false;\n this._interruptionTimer = -1;\n this._hovering = false;\n\n const {\n delay = 2000,\n delayOnMouseLeave = 0,\n speed = 1,\n pauseOnHover = false,\n canInterrupt = true,\n disableOnInterrupt = false\n } = getObjectOption(options);\n\n this._enableBlocked = !options;\n this._delay = delay;\n this._delayOnMouseLeave = delayOnMouseLeave;\n this._speed = speed;\n this._pauseOnHover = pauseOnHover;\n this._canInterrupt = canInterrupt;\n this._disableOnInterrupt = disableOnInterrupt;\n }\n\n /**\n * Destroy the instance and remove all event listeners attached\n * @ko 인스턴스를 제거하고 연결된 모든 이벤트 핸들러를 삭제합니다.\n * @since 4.0.0\n */\n public destroy(): void {\n this.disable();\n }\n\n /**\n * Rotate camera by given deltaTime\n * @ko 주어진 deltaTime만큼 카메라를 회전시킵니다.\n * @param deltaTime - Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n */\n public update(deltaTime: number): void {\n if (!this._enabled) return;\n if (this._interrupted) {\n if (this._disableOnInterrupt) {\n this.disable();\n }\n\n return;\n }\n\n const camera = this._camera;\n const delta = -this._speed * deltaTime / 100;\n\n camera.yaw = circulate(camera.yaw + delta, 0, 360);\n }\n\n /**\n * Enable autoplay and add event listeners.\n * @ko 자동재생을 활성화하고 이벤트리스너들을 추가합니다.\n * @since 4.0.0\n */\n public enable(): void {\n const control = this._control;\n const element = this._element;\n\n if (this._enabled || control.gyro.enabled) return;\n\n control.rotate.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.rotate.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.zoom.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.zoom.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.gyro.on(CONTROL_EVENTS.ENABLE, this._onGyroEnable);\n\n element.addEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter, false);\n element.addEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave, false);\n\n this._enabled = true;\n this._enableBlocked = false;\n }\n\n /**\n * Enable autoplay after current `delay` value.\n * @ko 현재의 `delay`값만큼 시간이 지난 다음에 자동재생을 활성화합니다.\n * @since 4.0.0\n */\n public enableAfterDelay() {\n this.enable();\n this._interrupted = true;\n this._setUninterruptedAfterDelay(this._delay);\n }\n\n /**\n * Disable autoplay and remove all event handlers.\n * @ko 자동재생을 비활성화하고 모든 이벤트 핸들러를 제거합니다.\n * @since 4.0.0\n */\n public disable(): void {\n if (!this._enabled) return;\n\n const control = this._control;\n const element = this._element;\n\n control.rotate.off(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.rotate.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.zoom.off(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.zoom.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.gyro.off(CONTROL_EVENTS.ENABLE, this._onGyroEnable);\n\n element.removeEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter, false);\n element.removeEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave, false);\n\n this._enabled = false;\n this._interrupted = false;\n this._hovering = false;\n\n this._clearTimeout();\n }\n\n private _onInputStart = () => {\n if (!this._canInterrupt) return;\n\n this._interrupted = true;\n this._clearTimeout();\n };\n\n private _onInputEnd = () => {\n this._setUninterruptedAfterDelay(this._delay);\n };\n\n private _onGyroEnable = () => {\n this.disable();\n };\n\n private _onMouseEnter = () => {\n if (!this._pauseOnHover) return;\n this._interrupted = true;\n this._hovering = true;\n };\n\n private _onMouseLeave = () => {\n if (!this._pauseOnHover) return;\n this._hovering = false;\n this._setUninterruptedAfterDelay(this._delayOnMouseLeave);\n };\n\n private _setUninterruptedAfterDelay(delay: number): void {\n if (this._hovering) return;\n\n this._clearTimeout();\n\n if (delay > 0) {\n this._interruptionTimer = window.setTimeout(() => {\n this._interrupted = false;\n this._interruptionTimer = -1;\n }, delay);\n } else {\n this._interrupted = false;\n this._interruptionTimer = -1;\n }\n }\n\n private _clearTimeout(): void {\n if (this._interruptionTimer >= 0) {\n window.clearTimeout(this._interruptionTimer);\n this._interruptionTimer = -1;\n }\n }\n}\n\nexport default Autoplay;\n","import { mat4 } from \"gl-matrix\";\nimport Component from \"@egjs/component\";\nimport WebGLContext from \"./WebGLContext\";\nimport GyroControl from \"../control/GyroControl\";\nimport * as BROWSER from \"../const/browser\";\nimport { SESSION_VR, XR_REFERENCE_SPACE } from \"../const/internal\";\nimport { EVENTS } from \"../const/external\";\n\ninterface XRSessionOptions extends XRSessionInit {\n [key: string]: any;\n}\n\n/**\n * WebXR manager class\n * @ko WebXR 매니저 클래스\n * @since 4.0.0\n */\nclass XRManager extends Component<{\n /**\n * An event that fires on entering VR session\n * @ko VR 세션 진입시에 트리거되는 이벤트\n * @eventName vrStart\n * @eventOf XRManager\n * @version 4.0.0\n */\n [EVENTS.VR_START]: {\n session: XRSession;\n };\n /**\n * An event that fires on exiting VR session\n * @ko VR 세션에서 나갈 때 트리거되는 이벤트\n * @eventName vrEnd\n * @eventOf XRManager\n * @version 4.0.0\n */\n [EVENTS.VR_END]: void;\n}> {\n private _ctx: WebGLContext;\n private _xrSession: XRSession | null;\n private _xrRefSpace: XRReferenceSpace | null;\n private _options: XRSessionOptions;\n\n /**\n * Create new instance.\n * 새 인스턴스를 생성합니다.\n * @param ctx - Instance of WebGL context helper {@ko WebGL 콘텍스트 헬퍼의 인스턴스}\n * @param options - Options {@ko 옵션들}\n */\n public constructor(ctx: WebGLContext, options: XRSessionOptions = {}) {\n super();\n\n this._xrSession = null;\n this._xrRefSpace = null;\n this._ctx = ctx;\n this._options = options;\n }\n\n /**\n * Destroy instance and end XR session if there was any.\n * @ko 인스턴스를 제거하고, XR 세션이 존재할 경우 종료합니다.\n * @since 4.0.0\n */\n public destroy = () => {\n this.exit();\n this.off();\n };\n\n /**\n * Returns WebXR availability.\n * @ko WebXR 사용 가능 여부를 반환합니다.\n * @since 4.0.0\n */\n public async isAvailable(): Promise {\n // eslint-disable-next-line compat/compat\n const xr = window.navigator.xr;\n if (!xr) return false;\n\n return xr.isSessionSupported(SESSION_VR)\n .then(available => {\n return available;\n }).catch(() => {\n return false;\n });\n }\n\n /**\n * Enter VR session\n * @ko VR 세션에 진입합니다.\n * @since 4.0.0\n */\n public async enter() {\n const ctx = this._ctx;\n\n // eslint-disable-next-line compat/compat\n const xr = window.navigator.xr;\n if (!xr) return;\n\n await GyroControl.requestSensorPermission();\n\n const options = {\n ...{\n requiredFeatures: [XR_REFERENCE_SPACE]\n },\n ...this._options\n };\n\n await ctx.makeXRCompatible();\n\n const session = await xr.requestSession(SESSION_VR, options);\n ctx.bindXRLayer(session);\n\n const refSpace = await session.requestReferenceSpace(XR_REFERENCE_SPACE);\n\n this._setSession(session, refSpace);\n\n this.trigger(EVENTS.VR_START, {\n session\n });\n }\n\n /**\n * Exit VR session\n * @ko VR 세션에서 나갑니다.\n * @since 4.0.0\n */\n public exit() {\n const xrSession = this._xrSession;\n\n if (xrSession) {\n xrSession.end()\n .catch(() => void 0);\n }\n\n this._xrSession = null;\n this._xrRefSpace = null;\n }\n\n /**\n * @hidden\n */\n public canRender(frame: XRFrame) {\n const refSpace = this._xrRefSpace;\n\n if (!refSpace) return false;\n\n const pose = frame.getViewerPose(refSpace);\n\n return !!pose;\n }\n\n /**\n * @hidden\n */\n public getEyeParams(frame: XRFrame): Array<{\n viewport: XRViewport;\n vMatrix: mat4;\n pMatrix: mat4;\n }> | null {\n const session = frame.session;\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n if (!pose) return null;\n\n const glLayer = session.renderState.baseLayer;\n\n if (!glLayer) return null;\n\n return pose.views.map(view => {\n const viewport = glLayer.getViewport(view)!;\n const vMatrix = view.transform.inverse.matrix;\n\n return {\n viewport,\n vMatrix,\n pMatrix: view.projectionMatrix\n };\n });\n }\n\n private _setSession(session: XRSession, refSpace: XRReferenceSpace) {\n this._xrSession = session;\n this._xrRefSpace = refSpace;\n\n session.addEventListener(BROWSER.EVENTS.XR_END, this._onSessionEnd);\n }\n\n private _onSessionEnd = () => {\n this.exit();\n this.trigger(EVENTS.VR_END);\n }\n}\n\nexport default XRManager;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { vec3 } from \"gl-matrix\";\n\n/**\n * Hotspot data\n * @ko 핫스팟 데이터\n * @since 4.0.0\n */\nclass Hotspot {\n /**\n * HTMLElement of the hotspot\n * @ko 핫스팟의 HTMLElement\n * @since 4.0.0\n */\n public readonly element: HTMLElement;\n /**\n * Position to render hotspot\n * @ko 핫스팟을 렌더링할 위치\n * @since 4.0.0\n */\n public readonly position: vec3;\n\n public constructor(element: HTMLElement, position: vec3) {\n this.element = element;\n this.position = position;\n }\n}\n\nexport default Hotspot;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { vec2, vec3 } from \"gl-matrix\";\nimport Hotspot from \"./Hotspot\";\nimport Camera from \"../core/Camera\";\nimport WebGLRenderer from \"../core/WebGLRenderer\";\nimport View360Error from \"../core/View360Error\";\nimport { getNullableElement } from \"../utils\";\nimport ERROR from \"../const/error\";\nimport { DEFAULT_CLASS } from \"../const/external\";\nimport { DEG_TO_RAD } from \"../const/internal\";\n\n/**\n * Options for {@link HotspotRenderer}\n * @ko {@link HotspotRenderer}용 옵션들\n * @since 4.0.0\n */\nexport interface HotspotOptions {\n /**\n * Apply scale for hotspots, makes their size sync with background panorama image.\n * @ko 핫스팟에 스케일을 적용해서 배경 파노라마 이미지의 크기 변화와 동일하게 크기를 조절합니다.\n * @since 4.0.0\n */\n zoom: boolean;\n}\n\n/**\n * Hotspot renderer\n * @ko Hotspot 렌더러\n * @since 4.0.0\n */\nclass HotspotRenderer {\n // Options\n private _zoom: HotspotOptions[\"zoom\"];\n\n // Internal properties\n private _containerEl: HTMLElement | null;\n private _renderer: WebGLRenderer;\n private _hotspots: Hotspot[];\n\n /**\n * Create new instance\n * @ko 새 인스턴스를 생성합니다.\n * @param rootEl - Container element for hotspots {@ko 핫스팟들의 컨테이너 엘리먼트}\n * @param renderer - instance of WebGLRenderer {@ko WebGLRenderer의 인스턴스}\n * @param options - Hotspot options {@ko Hotspot 옵션들 }\n */\n public constructor(rootEl: HTMLElement, renderer: WebGLRenderer, {\n zoom = false\n }: Partial) {\n this._containerEl = getNullableElement(`.${DEFAULT_CLASS.HOTSPOT_CONTAINER}`, rootEl);\n this._renderer = renderer;\n this._hotspots = [];\n\n this._zoom = zoom;\n }\n\n /**\n * Refresh hotspots by collecting hotspot elements from current hotspot root element\n * @ko 현재 핫스팟 루트 엘리먼트 내에서 핫스팟 엘리먼트들을 수집하여 갱신합니다.\n * @throws {ERROR_CODES.INSUFFICIENT_ARGS} if data-position doesn't include all x, y, z values {@ko data-position이 x, y, z좌표를 전부 포함하고 있지 않을 때}\n */\n public refresh() {\n const container = this._containerEl;\n if (!container) return;\n\n const hotspotEls = [].slice.apply(container.querySelectorAll(`.${DEFAULT_CLASS.HOTSPOT}`)) as HTMLElement[];\n this._hotspots = hotspotEls.map(el => this._parseHotspot(el));\n }\n\n /**\n * Render hotspots\n * @ko 핫스팟들을 렌더링합니다.\n * @param camera - Instance of Camera {@ko Camera의 인스턴스}\n */\n public render(camera: Camera) {\n const hotspots = this._hotspots;\n const halfWidth = this._renderer.width * 0.5;\n const halfHeight = this._renderer.height * 0.5;\n const zoom = camera.zoom;\n const centerTransform = \"translate(-50%, -50%)\";\n const zoomTransform = this._zoom ? `scale(${zoom})` : \"\";\n\n hotspots.forEach(hotspot => {\n const position = hotspot.position;\n const relPos = vec3.create();\n\n vec3.copy(relPos, position);\n vec3.transformMat4(relPos, relPos, camera.viewMatrix);\n vec3.transformMat4(relPos, relPos, camera.projectionMatrix);\n\n if (relPos[2] > 1 || relPos[2] < 0) {\n hotspot.element.classList.remove(DEFAULT_CLASS.HOTSPOT_VISIBLE);\n return;\n }\n\n const screenPos = vec2.fromValues(\n relPos[0] * halfWidth + halfWidth,\n -relPos[1] * halfHeight + halfHeight\n );\n\n hotspot.element.classList.add(DEFAULT_CLASS.HOTSPOT_VISIBLE);\n hotspot.element.style.transform = [\n centerTransform,\n `translate(${screenPos[0]}px, ${screenPos[1]}px)`,\n zoomTransform\n ].join(\" \");\n });\n }\n\n private _parseHotspot(element: HTMLElement): Hotspot {\n const yawStr = element.dataset.yaw;\n const pitchStr = element.dataset.pitch;\n const positionStr = element.dataset.position;\n\n if (yawStr || pitchStr) {\n const yaw = yawStr ? parseFloat(yawStr) : 0;\n const pitch = pitchStr ? parseFloat(pitchStr) : 0;\n\n const position = this._yawPitchToVec3(yaw, pitch);\n\n return new Hotspot(element, position);\n } else if (positionStr) {\n const pos: number[] = positionStr.split(\" \").map(val => parseFloat(val));\n if (pos.length < 3) {\n throw new View360Error(ERROR.MESSAGES.INSUFFICIENT_ARGS(positionStr, \"hotspot attribute \\\"data-position\\\"\"), ERROR.CODES.INSUFFICIENT_ARGS);\n }\n\n return new Hotspot(element, vec3.fromValues(pos[0], pos[1], pos[2]));\n } else {\n // Place hotspot at yaw: 0, pitch: 0\n const defaultPos = vec3.fromValues(0, 0, -1);\n\n return new Hotspot(element, defaultPos);\n }\n }\n\n private _yawPitchToVec3(yaw: number, pitch: number) {\n const yawRad = yaw * DEG_TO_RAD;\n const pitchRad = pitch * DEG_TO_RAD;\n const position = vec3.create();\n\n position[1] = Math.sin(pitchRad);\n position[2] = Math.cos(pitchRad);\n\n position[0] = position[2] * Math.sin(-yawRad);\n position[2] = -position[2] * Math.cos(-yawRad);\n\n return position;\n }\n}\n\nexport default HotspotRenderer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"../geometry/Geometry\";\nimport { VAO } from \"../type/internal\";\n\n/**\n * @hidden\n */\nclass VertexArrayObject {\n public readonly obj: VAO | null;\n public readonly geometry: Geometry;\n public readonly buffers: {\n indicies: WebGLBuffer;\n position: WebGLBuffer;\n uv: WebGLBuffer;\n }\n\n public get count() { return this.geometry.indicies.count; }\n\n constructor(obj: VAO | null, geometry: Geometry, buffers: VertexArrayObject[\"buffers\"]) {\n this.obj = obj;\n this.geometry = geometry;\n this.buffers = buffers;\n }\n}\n\nexport default VertexArrayObject;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4 } from \"gl-matrix\";\nimport Uniform from \"../uniform/Uniform\";\nimport Camera from \"./Camera\";\nimport Object3D from \"./Object3D\";\nimport ShaderProgram from \"./ShaderProgram\";\nimport View360Error from \"./View360Error\";\nimport VertexArrayObject from \"./VertexArrayObject\";\nimport VertexData from \"./VertexData\";\nimport Texture from \"../texture/Texture\";\nimport Geometry from \"../geometry/Geometry\";\nimport * as BROWSER from \"../const/browser\";\nimport ERROR from \"../const/error\";\nimport { DEFAULT_CLASS } from \"../const/external\";\nimport { UniformLocations } from \"../type/internal\";\n\n/**\n * @hidden\n */\nclass WebGLContext {\n private _canvas: HTMLCanvasElement;\n private _gl: WebGLRenderingContext | WebGL2RenderingContext;\n private _contextLost: boolean;\n private _maxTextureSize: number;\n private _isWebGL2: boolean;\n private _debug: boolean;\n private _extensions: {\n vao: OES_vertex_array_object | null;\n loseContext: WEBGL_lose_context | null;\n };\n\n public get canvas() { return this._canvas; }\n public get maxTextureSize() { return this._maxTextureSize; }\n public get isWebGL2() { return this._isWebGL2; }\n public get supportVAO() { return this._isWebGL2 || !!this._extensions.vao; }\n public get lost() { return this._contextLost; }\n public get debug() { return this._debug; }\n\n public constructor(canvas: HTMLCanvasElement, debug: boolean) {\n this._canvas = canvas;\n this._contextLost = false;\n this._debug = debug;\n this._extensions = {\n vao: null,\n loseContext: null\n };\n }\n\n public init() {\n const canvas = this._canvas;\n\n const { gl, isWebGL2 } = this._getContext(canvas);\n\n this._gl = gl;\n this._maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n this._isWebGL2 = isWebGL2;\n\n if (!this._isWebGL2) {\n this._extensions.vao = gl.getExtension(\"OES_vertex_array_object\");\n }\n\n this._extensions.loseContext = gl.getExtension(\"WEBGL_lose_context\");\n\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_LOST, this._onContextLost);\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_RESTORED, this._onContextRestore);\n\n // gl.enable(gl.DEPTH_TEST);\n }\n\n public destroy() {\n const gl = this._gl;\n const canvas = this._canvas;\n\n if (gl) {\n // gl is not defined when destroy is called before init\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n }\n\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_LOST, this._onContextLost);\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_RESTORED, this._onContextRestore);\n }\n\n public forceLoseContext() {\n const extension = this._extensions.loseContext;\n\n if (!extension) return;\n\n extension.loseContext();\n }\n\n public forceRestoreContext() {\n const extension = this._extensions.loseContext;\n\n if (!extension) return;\n\n extension.restoreContext();\n }\n\n public clear() {\n const gl = this._gl;\n\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n\n public resize() {\n const gl = this._gl;\n\n gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n }\n\n public viewport(x: number, y: number, width: number, height: number) {\n const gl = this._gl;\n\n gl.viewport(x, y, width, height);\n }\n\n public createVAO(geometry: Geometry, shaderProgram: ShaderProgram) {\n const nativeVAO = this._createNativeVAO();\n\n const vao = new VertexArrayObject(nativeVAO, geometry, {\n indicies: this._createBuffer(),\n position: this._createBuffer(),\n uv: this._createBuffer()\n });\n\n if (nativeVAO) {\n this._bindNativeVAO(nativeVAO);\n this._supplyGeometryData(vao, shaderProgram);\n this._bindNativeVAO(null);\n this._unbindBuffers();\n }\n\n return vao;\n }\n\n public draw(vao: VertexArrayObject, shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n if (vao.obj) {\n this._bindNativeVAO(vao.obj);\n } else {\n this._supplyGeometryData(vao, shaderProgram);\n }\n\n gl.drawElements(gl.TRIANGLES, vao.count, gl.UNSIGNED_SHORT, 0);\n\n if (vao.obj) {\n this._bindNativeVAO(null);\n } else {\n this._unbindBuffers();\n }\n }\n\n public releaseVAO(vao: VertexArrayObject) {\n if (vao.obj) {\n this._deleteNativeVAO(vao.obj);\n }\n\n this._deleteBuffer(vao.buffers.indicies);\n this._deleteBuffer(vao.buffers.position);\n this._deleteBuffer(vao.buffers.uv);\n }\n\n public getUniformLocations>(program: WebGLProgram, uniforms: T): UniformLocations {\n const gl = this._gl;\n\n const uniformLocations = Object.keys(uniforms).reduce((locations, key) => {\n locations[key as keyof T] = gl.getUniformLocation(program, key)!;\n\n return locations;\n }, {} as UniformLocations);\n\n return {\n ...this._getCommonUniformLocations(program),\n ...uniformLocations\n };\n }\n\n public updateCommonUniforms(entity: Object3D, camera: Camera, shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniformLocations = shaderProgram.uniformLocations;\n\n // We're using \"matrix\"(=local matrix) here for efficiency\n // As projection doesn't require world matrix, as it doesn't have any parent or child\n const matrix = entity.matrix;\n const mvMatrix = mat4.create();\n mat4.multiply(mvMatrix, camera.viewMatrix, matrix);\n\n gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix);\n gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, camera.projectionMatrix);\n }\n\n public updateVRUniforms(shaderProgram: ShaderProgram, mvMatrix: mat4, pMatrix: mat4, eyeIndex: number) {\n const gl = this._gl;\n\n const uniformLocations = shaderProgram.uniformLocations;\n\n gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix);\n gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, pMatrix);\n\n if (uniformLocations.uEye) {\n gl.uniform1f(uniformLocations.uEye, eyeIndex);\n }\n }\n\n public updateUniforms(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniforms = shaderProgram.uniforms;\n const uniformLocations = shaderProgram.uniformLocations;\n\n for (const key in uniforms) {\n const uniform = uniforms[key];\n const location = uniformLocations[key];\n\n if (!uniform) continue;\n\n if (uniform.needsUpdate) {\n uniform.update(gl, location, this._isWebGL2);\n }\n }\n }\n\n public releaseShaderResources(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniforms = shaderProgram.uniforms;\n\n for (const key in uniforms) {\n const uniform = uniforms[key];\n\n if (!uniform) continue;\n\n if (uniform.needsUpdate) {\n uniform.destroy(gl);\n }\n }\n\n gl.deleteProgram(shaderProgram.program);\n }\n\n public useProgram(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n gl.useProgram(shaderProgram.program);\n }\n\n public createProgram(vertexShader: string, fragmentShader: string) {\n const gl = this._gl;\n const program = gl.createProgram()!;\n\n const vs = this._compileShader(gl.VERTEX_SHADER, vertexShader);\n const fs = this._compileShader(gl.FRAGMENT_SHADER, fragmentShader);\n\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.bindAttribLocation(program, 0, \"position\");\n gl.bindAttribLocation(program, 1, \"uv\");\n gl.linkProgram(program);\n\n if (this._debug && !gl.getProgramParameter(program, gl.LINK_STATUS)) {\n let shaderLog: string | null = null;\n\n if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {\n shaderLog = gl.getShaderInfoLog(vs);\n } else if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {\n shaderLog = gl.getShaderInfoLog(fs);\n }\n\n throw new View360Error(ERROR.MESSAGES.FAILED_LINKING_PROGRAM(gl.getProgramInfoLog(program), shaderLog), ERROR.CODES.FAILED_LINKING_PROGRAM);\n }\n\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n\n return program;\n }\n\n public createWebGLTexture(texData: Texture): WebGLTexture {\n const gl = this._gl;\n const texture = gl.createTexture()!;\n\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texData.wrapS);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texData.wrapT);\n\n if (!texData.isVideo() && this._isWebGL2) {\n const gl2 = gl as WebGL2RenderingContext;\n\n gl2.texStorage2D(gl2.TEXTURE_2D, 1, gl2.RGBA8, texData.width, texData.height);\n }\n\n return texture;\n }\n\n public createWebGLCubeTexture(texData: Texture, size: number): WebGLTexture {\n const gl = this._gl;\n const texture = gl.createTexture()!;\n\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, texData.wrapS);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, texData.wrapT);\n\n if (this._isWebGL2) {\n const gl2 = gl as WebGL2RenderingContext;\n\n gl2.texStorage2D(gl2.TEXTURE_CUBE_MAP, 1, gl2.RGBA8, size, size);\n }\n\n return texture;\n }\n\n public async makeXRCompatible() {\n const gl = this._gl;\n const attributes = gl.getContextAttributes();\n\n if (attributes && attributes.xrCompatible !== true) {\n await gl.makeXRCompatible();\n }\n }\n\n public bindXRLayer(session: XRSession) {\n const gl = this._gl;\n const xrLayer = new XRWebGLLayer(session, gl);\n session.updateRenderState({ baseLayer: xrLayer });\n }\n\n public bindXRFrame(frame: XRFrame) {\n const gl = this._gl;\n const session = frame.session;\n const baseLayer = session.renderState.baseLayer!;\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer);\n }\n\n public useDefaultFrameBuffer() {\n const gl = this._gl;\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n private _createBuffer(): WebGLBuffer {\n return this._gl.createBuffer()!;\n }\n\n private _deleteBuffer(buffer: WebGLBuffer) {\n return this._gl.deleteBuffer(buffer);\n }\n\n private _createNativeVAO() {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n return (gl as WebGL2RenderingContext).createVertexArray()!;\n } else {\n const ext = this._extensions.vao;\n\n return ext?.createVertexArrayOES() || null;\n }\n }\n\n private _bindNativeVAO(vao: WebGLVertexArrayObject | null) {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n (gl as WebGL2RenderingContext).bindVertexArray(vao);\n } else {\n const ext = this._extensions.vao;\n\n ext?.bindVertexArrayOES(vao);\n }\n }\n\n private _deleteNativeVAO(vao: WebGLVertexArrayObject | null) {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n (gl as WebGL2RenderingContext).deleteVertexArray(vao);\n } else {\n const ext = this._extensions.vao;\n\n ext?.deleteVertexArrayOES(vao);\n }\n }\n\n private _supplyGeometryData(vao: VertexArrayObject, shaderProgram: ShaderProgram) {\n const geometry = vao.geometry;\n\n this._supplyIndiciesData(geometry.indicies, vao.buffers.indicies);\n this._supplyAttributeData(geometry.vertices, shaderProgram.program, \"position\", vao.buffers.position);\n this._supplyAttributeData(geometry.uvs, shaderProgram.program, \"uv\", vao.buffers.uv);\n }\n\n private _unbindBuffers() {\n const gl = this._gl;\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n }\n\n private _supplyIndiciesData(indicies: VertexData, buffer: WebGLBuffer) {\n const gl = this._gl;\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicies.data, gl.STATIC_DRAW);\n }\n\n private _supplyAttributeData(attribute: VertexData, program: WebGLProgram, name: string, buffer: WebGLBuffer) {\n const gl = this._gl;\n const attribLocation = gl.getAttribLocation(program, name);\n\n // Attribute not used\n if (attribLocation < 0) return;\n\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ARRAY_BUFFER, attribute.data, gl.STATIC_DRAW);\n gl.vertexAttribPointer(attribLocation, attribute.itemSize, gl.FLOAT, false, 0, 0);\n gl.enableVertexAttribArray(attribLocation);\n }\n\n private _compileShader(type: number, src: string) {\n const gl = this._gl;\n const shader = gl.createShader(type)!;\n\n gl.shaderSource(shader, src);\n gl.compileShader(shader);\n\n return shader;\n }\n\n private _getCommonUniformLocations(program: WebGLProgram) {\n const gl = this._gl;\n\n return {\n uMVMatrix: gl.getUniformLocation(program, \"uMVMatrix\")!,\n uPMatrix: gl.getUniformLocation(program, \"uPMatrix\")!\n };\n }\n\n private _getContext(canvas: HTMLCanvasElement): {\n gl: WebGLRenderingContext | WebGL2RenderingContext;\n isWebGL2: boolean;\n } {\n const webglIdentifiers = [\"webgl2\", \"webgl\", \"experimental-webgl\", \"webkit-3d\", \"moz-webgl\"];\n let context: WebGLRenderingContext | null = null;\n let isWebGL2 = false;\n const contextAttributes = {\n preserveDrawingBuffer: false,\n antialias: false\n };\n\n const onWebglContextCreationError = e => e.statusMessage;\n\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_CREATE_ERROR, onWebglContextCreationError);\n\n for (const identifier of webglIdentifiers) {\n try {\n context = canvas.getContext(identifier, contextAttributes) as WebGLRenderingContext;\n isWebGL2 = identifier === \"webgl2\";\n } catch (t) {} // eslint-disable-line no-empty\n if (context) {\n break;\n }\n }\n\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_CREATE_ERROR, onWebglContextCreationError);\n\n if (!context) {\n throw new View360Error(ERROR.MESSAGES.WEBGL_NOT_SUPPORTED, ERROR.CODES.WEBGL_NOT_SUPPORTED);\n }\n\n return {\n gl: context,\n isWebGL2\n };\n }\n\n private _onContextLost = () => {\n const canvas = this._canvas;\n canvas.classList.add(DEFAULT_CLASS.CTX_LOST);\n this._contextLost = true;\n };\n\n private _onContextRestore = () => {\n const canvas = this._canvas;\n canvas.classList.remove(DEFAULT_CLASS.CTX_LOST);\n this._contextLost = false;\n };\n}\n\nexport default WebGLContext;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4 } from \"gl-matrix\";\nimport Camera from \"./Camera\";\nimport Projection from \"../projection/Projection\";\nimport WebGLContext from \"./WebGLContext\";\nimport XRManager from \"./XRManager\";\n\n/**\n * Projection renderer, based on WebGL\n * @ko WebGL 기반의 프로젝션 렌더러\n * @since 4.0.0\n */\nclass WebGLRenderer {\n private _canvas: HTMLCanvasElement;\n private _elementSize: { x: number, y: number };\n private _pixelRatio: number;\n\n public readonly ctx: WebGLContext;\n\n /**\n * Canvas element\n * @ko 캔버스 엘리먼트\n * @since 4.0.0\n */\n public get canvas() { return this._canvas; }\n /**\n * Canvas's width (`devicePixelRatio` is not applied)\n * @ko 캔버스의 보이는 너비 (`devicePixelRatio`가 적용되지 않은)\n * @since 4.0.0\n */\n public get width() { return this._elementSize.x; }\n /**\n * Canvas's height (`devicePixelRatio` is not applied)\n * @ko 캔버스의 높이 (`devicePixelRatio`가 적용되지 않은)\n * @since 4.0.0\n */\n public get height() { return this._elementSize.y; }\n /**\n * Current `devicePixelRatio` value.\n * @ko 현재 `devicePixelRatio` 값.\n * @since 4.0.0\n * @example\n * ```js\n * cosnt renderingWidth = view360.renderer.width * view360.renderer.pixelRatio;\n * ```\n */\n public get pixelRatio() { return this._pixelRatio; }\n /**\n * Width / height ratio (= width / height)\n * @ko 너비 / 높이의 비율 (= width / height)\n * @since 4.0.0\n * @example\n * ```js\n * const aspect = view360.renderer.width / view360.renderer.pixelRatio;\n * assert(aspect === view360.renderer.aspect);\n * ```\n */\n public get aspect() { return this._elementSize.x / this._elementSize.y; }\n\n /**\n * Create new instance\n * @ko 새 인스턴스를 생성합니다.\n * @param canvas - Canvas element {@ko 캔버스 엘리먼트}\n * @param debug - Whether to enable WebGL debugging {@ko WebGL debug 활성화 여부 }\n */\n public constructor(canvas: HTMLCanvasElement, debug: boolean) {\n this._canvas = canvas;\n this._elementSize = { x: 0, y: 0 };\n this._pixelRatio = 1;\n this.ctx = new WebGLContext(canvas, debug);\n }\n\n /**\n * Destroy instance and release all resources.\n * @ko 인스턴스를 제거하고 사용된 리소스를 전부 해제합니다.\n * @since 4.0.0\n */\n public destroy() {\n const canvas = this._canvas;\n\n this.ctx.destroy();\n canvas.width = 1;\n canvas.height = 1;\n }\n\n /**\n * Resize canvas and renew inner size cache.\n * @ko 캔버스의 크기를 재계산해서 내부의 사이즈 캐시값을 갱신합니다.\n * @since 4.0.0\n */\n public resize() {\n const canvas = this._canvas;\n const canvasSize = this._elementSize;\n const devicePixelRatio = window.devicePixelRatio;\n\n canvasSize.x = canvas.clientWidth;\n canvasSize.y = canvas.clientHeight;\n\n canvas.width = canvasSize.x * devicePixelRatio;\n canvas.height = canvasSize.y * devicePixelRatio;\n\n this._pixelRatio = devicePixelRatio;\n this.ctx.resize();\n }\n\n /**\n * Render projection\n * @ko 프로젝션을 렌더링합니다.\n * @param projection - Projection to render {@ko 렌더링할 프로젝션}\n * @param cameraa - Camera instance {@ko 카메라의 인스턴스}\n * @since 4.0.0\n */\n public render(projection: Projection, camera: Camera) {\n const ctx = this.ctx;\n const mesh = projection.getMesh();\n if (ctx.lost || !mesh) return;\n\n ctx.clear();\n ctx.useProgram(mesh.program);\n ctx.updateCommonUniforms(mesh, camera, mesh.program);\n projection.update(camera);\n ctx.updateUniforms(mesh.program);\n ctx.draw(mesh.vao, mesh.program);\n }\n\n /**\n * Render VR frame, only used for rendering frames inside VR sessions.\n * @ko VR 프레임을 렌더링합니다. VR 세션 진입 도중에만 사용됩니다.\n * @internal\n * @param projection - Projection to render {@ko 렌더링할 프로젝션}\n * @param vr - Instance of XRManager {@ko XRManager의 인스턴스}\n * @param frame - VR frame {@ko VR 프레임}\n * @since 4.0.0\n */\n public renderVR(projection: Projection, vr: XRManager, frame: XRFrame) {\n const ctx = this.ctx;\n const mesh = projection.getMesh();\n const eyeParams = vr.getEyeParams(frame);\n\n if (!eyeParams || !mesh) return;\n\n ctx.bindXRFrame(frame);\n ctx.useProgram(mesh.program);\n ctx.updateUniforms(mesh.program);\n\n eyeParams.forEach((eye, eyeIndex) => {\n const viewport = eye.viewport;\n // We're using \"mesh.matrix\"(=local matrix) here for efficiency\n // As projection doesn't require world matrix, as it doesn't have any parent or child\n const mvMatrix = mat4.multiply(mat4.create(), eye.vMatrix, mesh.matrix);\n\n ctx.viewport(viewport.x, viewport.y, viewport.width, viewport.height);\n ctx.updateVRUniforms(mesh.program, mvMatrix, eye.pMatrix, eyeIndex);\n ctx.draw(mesh.vao, mesh.program);\n });\n }\n}\n\nexport default WebGLRenderer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport Camera, { CameraOptions } from \"./core/Camera\";\nimport PanoControl, { PanoControlOptions } from \"./control/PanoControl\";\nimport TextureLoader from \"./core/TextureLoader\";\nimport FrameAnimator from \"./core/FrameAnimator\";\nimport AutoResizer from \"./core/AutoResizer\";\nimport Autoplay, { AutoplayOptions } from \"./core/Autoplay\";\nimport XRManager from \"./core/XRManager\";\nimport View360Error from \"./core/View360Error\";\nimport Projection from \"./projection/Projection\";\nimport HotspotRenderer, { HotspotOptions } from \"./hotspot/HotspotRenderer\";\nimport WebGLRenderer from \"./core/WebGLRenderer\";\nimport Texture from \"./texture/Texture\";\nimport View360Plugin from \"./plugin/View360Plugin\";\nimport ERROR from \"./const/error\";\nimport { CONTROL_EVENTS } from \"./const/internal\";\nimport { DEFAULT_CLASS, EVENTS } from \"./const/external\";\nimport { findCanvas, getElement } from \"./utils\";\nimport * as EVENT_TYPES from \"./type/events\";\nimport { EventParams } from \"./type/utils\";\n\n/**\n * Events that {@link View360} can trigger\n * @ko {@link View360}가 트리거할 수 있는 이벤트들\n * @see [Detailed Example](/docs/events/ready)\n * @since 4.0.0\n */\nexport interface View360Events {\n [EVENTS.READY]: EVENT_TYPES.ReadyEvent;\n [EVENTS.LOAD_START]: EVENT_TYPES.LoadStartEvent;\n [EVENTS.LOAD]: EVENT_TYPES.LoadEvent;\n [EVENTS.PROJECTION_CHANGE]: EVENT_TYPES.ProjectionChangeEvent;\n [EVENTS.RESIZE]: EVENT_TYPES.ResizeEvent;\n [EVENTS.BEFORE_RENDER]: EVENT_TYPES.BeforeRenderEvent;\n [EVENTS.RENDER]: EVENT_TYPES.RenderEvent;\n [EVENTS.INPUT_START]: EVENT_TYPES.InputStartEvent;\n [EVENTS.INPUT_END]: EVENT_TYPES.InputEndEvent;\n [EVENTS.VIEW_CHANGE]: EVENT_TYPES.ViewChangeEvent;\n [EVENTS.STATIC_CLICK]: EVENT_TYPES.StaticClickEvent;\n [EVENTS.VR_START]: EVENT_TYPES.VRStartEvent;\n [EVENTS.VR_END]: EVENT_TYPES.VREndEvent;\n}\n\n/**\n * Options for {@link View360}\n * @ko {@link View360}용 옵션들\n * @see [Detailed Example](/docs/options)\n * @since 4.0.0\n */\nexport interface View360Options extends CameraOptions, PanoControlOptions {\n projection: Projection | null;\n hotspot: Partial;\n autoplay: boolean | Partial;\n autoInit: boolean;\n autoResize: boolean;\n canvasSelector: string;\n useResizeObserver: boolean;\n tabIndex: number | null;\n on: Partial<{ [key in keyof View360Events]: (evt: View360Events[key]) => any }>;\n plugins: View360Plugin[];\n maxDeltaTime: number;\n debug: boolean;\n}\n\n/**\n * Panorama 360 image viewer\n * @ko 파노라마 360 이미지 뷰어\n * @since 4.0.0\n * @see View360Options\n * @see View360Events\n */\nclass View360 extends Component {\n /**\n * Current version string of the View360\n * @ko View360의 현재 버젼 문자열\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // If the installed version of the View360 is v4.0.0, View360.VERSION is equal to \"4.0.0\"\n * console.log(View360.VERSION) // 4.0.0\n * ```\n */\n public static readonly VERSION = \"#__VERSION__#\";\n\n private _rootEl: HTMLElement;\n private _renderer: WebGLRenderer;\n private _camera: Camera;\n private _control: PanoControl;\n private _animator: FrameAnimator;\n private _autoplay: Autoplay;\n private _hotspot: HotspotRenderer;\n private _projection: Projection | null;\n private _autoResizer: AutoResizer;\n private _vr: XRManager;\n private _plugins: View360Plugin[];\n private _initialized: boolean;\n\n private _autoInit: View360Options[\"autoInit\"];\n private _autoResize: View360Options[\"autoResize\"];\n private _canvasSelector: View360Options[\"canvasSelector\"];\n private _useResizeObserver: View360Options[\"useResizeObserver\"];\n private _tabIndex: View360Options[\"tabIndex\"];\n private _debug: View360Options[\"debug\"];\n\n /**\n * Root element (`.view360-container`)\n * @ko 루트 엘리먼트 (`.view360-container`)\n * @since 4.0.0\n * @readonly\n * @example\n * ```html\n *
\n * \n *
\n * ```\n * ```ts\n * import View360 from \"@egjs/view360\";\n *\n * const viewer = new View360(\"#viewer\");\n * console.log(viewer.rootEl); // Element with id \"viewer\"\n * ```\n */\n public get rootEl() { return this._rootEl; }\n /**\n * Projection renderer.\n * @ko 프로젝션 렌더러.\n * @since 4.0.0\n * @readonly\n */\n public get renderer() { return this._renderer; }\n /**\n * Projection camera.\n * @ko 프로젝션 카메라.\n * @since 4.0.0\n * @readonly\n */\n public get camera() { return this._camera; }\n /**\n * Rotate/Zoom Controller.\n * @ko 회전/줌 컨트롤러.\n * @since 4.0.0\n * @readonly\n */\n public get control() { return this._control; }\n /**\n * WebXR-based VR manager.\n * @ko WebXR 기반의 VR 기능 매니저 인스턴스.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // Example: Enter VR\n * // This must be called on user interaction, else will be rejected.\n * viewer.vr.enter();\n * ```\n */\n public get vr() { return this._vr; }\n /**\n * Hotspot renderer.\n * You can also change options of {@link View360Options#hotspot} with this.\n * @ko 핫스팟 렌더러 인스턴스.\n * {@link View360Options#hotspot} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get hotspot() { return this._hotspot; }\n /**\n * An array of plugins added.\n * @ko 추가된 플러그인의 배열\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * plugins: [new ControlBar()]\n * });\n *\n * console.log(viewer.plugins); // [ControlBar]\n *\n * viewer.addPlugins(new LoadingSpinner()) // [ControlBar, LoadingSpinner];\n * ```\n */\n public get plugins() { return this._plugins; }\n /**\n * A instance of {@link Projection} that currently enabled. `null` if not initialized yet.\n * You should call {@link View360#load} to change panorama src or projection type.\n * @ko 현재 사용중인 {@link Projection}의 인스턴스. 프로젝션을 활성화하지 않았을 경우 `null`입니다.\n * 파노라마 이미지 소스나 프로젝션 타입을 변경하려면 {@link View360#load}를 호출하면 됩니다.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360\n * ```\n */\n public get projection() { return this._projection; }\n public set projection(val: View360Options[\"projection\"]) {\n if (this._initialized && val) {\n this.load(val);\n } else {\n this._projection = val;\n }\n }\n /**\n * A boolean value whether {@link View360#init init()} is called before.\n * @ko {@link View360#init init()}이 호출되었는지 여부를 가리키는 값\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360(\"#el\", { autoInit: false });\n *\n * console.log(viewer.initialized); // false\n *\n * await viewer.init();\n *\n * console.log(viewer.initialized); // true\n * ```\n */\n public get initialized() { return this._initialized; }\n /**\n * Instance of the Autoplay manager.\n * You can also change {@link View360Options#autoplay} options with this.\n * @ko Autoplay 기능의 매니저 인스턴스.\n * 이 인스턴스를 통해 {@link View360Options#autoplay} 옵션을 변경하는 것도 가능합니다.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // Disable autoplay\n * viewer.autoplay.disable();\n * ```\n */\n public get autoplay() { return this._autoplay; }\n /**\n * When this value is `true` and {@link View360Options#projection} is set, {@link View360#init init()} will be called automatically when instance is created.\n * @ko 이 값이 `true`이고, {@link View360Options#projection}이 설정되었으면, 인스턴스 생성 시점에 자동으로 {@link View360#init init()}을 호출합니다.\n * @default true\n * @since 4.0.0\n * @example\n * ```ts\n * import View360, { EquirectProjection, EVENTS } from \"@egjs/view360\";\n *\n * // viewer.init() is called on instance creation\n * // But as `init` is asynchronous, you should wait for \"ready\" event if you want to do something after initialization.\n * const viewer = new View360(\"#el_id\", {\n * autoInit: true,\n * projection: new EquirectProjection({ src: \"SRC_TO_URL\" })\n * });\n *\n * console.log(viewer.initialized); // false, as `init` is asynchronous\n *\n * viewer.once(EVENTS.READY, () => {\n * console.log(viewer.initialized); // true\n * });\n * ```\n */\n public get autoInit() { return this._autoInit; }\n /**\n * When `true`, {@link View360#resize} is called when the canvas size is changed.\n * @ko `true`일 경우, 캔버스의 크기가 변경되었을 때 자동으로 {@link View360#resize}를 호출합니다.\n * @default true\n * @since 4.0.0\n * @see View360#useResizeObserver\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * autoResize: true\n * });\n *\n * // This can trigger `viewer.resize()` if the canvas size was not 400px\n * const canvas = viewer.renderer.canvas;\n * canvas.style.width = \"400px\";\n * ```\n */\n public get autoResize() { return this._autoResize; }\n /**\n * CSS selector for canvas element to render panorama image/video.\n * The canvas element should be placed inside the root element. (Dont' have to be direct child)\n * @ko 파노라마 이미지/비디오를 렌더링할 canvas 엘리먼트의 CSS 선택자\n * 캔버스 엘리먼트는 루트 엘리먼트 내부에 있어야합니다. 루트 엘리먼트의 직계 자식 엘리먼트(Direct child element)일 필요는 없습니다.\n * @default \"canvas\"\n * @since 4.0.0\n * @example\n * ```html\n *
\n * \n * \n * \n *
\n * ```\n *\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * canvasSelector: \"#canvas_to_select\"\n * });\n * ```\n */\n public get canvasSelector() { return this._canvasSelector; }\n /**\n * When `true`, it will use {@link ResizeObserver} API to detect canvas size change when {@link View360Options#autoResize} is enabled.\n * @ko `true`일 때 {@link View360Options#autoResize}가 활성화되었으면, 사용 가능한 환경에서 {@link ResizeObserver} API를 사용해서 캔버스 크기 변화를 추적합니다.\n * @default true\n * @since 4.0.0\n */\n public get useResizeObserver() { return this._useResizeObserver; }\n /**\n * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} attribute for the canvas element.\n * This is necessary for the keyboard controls.\n * By default, `0` will be assigned. `null` to disable.\n * @ko 캔버스 엘리먼트에 적용할 {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} 어트리뷰트의 값.\n * 이 값을 설정해야만 키보드 컨트롤을 사용 가능합니다.\n * 기본값으로 `0`이 설정됩니다. `null`로 지정하면 `tabindex`를 설정하지 않습니다.\n * @see RotateControlOptions#disableKeyboard\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * tabindex: 5\n * });\n * ```\n *\n * ```html\n * \n *
\n * \n *
\n * ```\n */\n public get tabIndex() { return this._tabIndex; }\n public set tabIndex(val: View360Options[\"tabIndex\"]) {\n const canvas = this._renderer.canvas;\n this._tabIndex = val;\n\n if (val != null) {\n canvas.tabIndex = val;\n } else {\n canvas.removeAttribute(\"tabindex\");\n }\n }\n /**\n * A maximum delta time between frames in seconds.\n * It can prevent camera or control changing too fast when frame being late.\n * @ko 프레임간 시간 차이의 최대값. (초 단위)\n * 퍼포먼스 등의 이유로 프레임 렌더링이 늦어졌을 때, 화면이 갑작스럽게 바뀌는 것을 막아줍니다.\n * @default 1 / 30\n * @since 4.0.0\n */\n public get maxDeltaTime() { return this._animator.maxDeltaTime; }\n public set maxDeltaTime(val: View360Options[\"maxDeltaTime\"]) { this._animator.maxDeltaTime = val; }\n /**\n * Enable WebGL debugging. Setting this to `true` can decrease performance.\n * This is used internally on developing View360.\n * @ko WebGL 디버깅을 활성화합니다. 이 값을 `true`로 할 경우 성능이 하락할 수 있습니다.\n * 이 옵션은 View360을 개발하기 위해 내부적으로 사용됩니다.\n * @default false\n */\n public get debug() { return this._debug; }\n public set debug(val: View360Options[\"debug\"]) { this._debug = val; }\n\n // Camera options\n /**\n * Initial yaw (y-axis rotation) value for camera. (in degrees, °)\n * As View360 uses right-handed coordinate system internally, camera will rotate counter-clockwise by this value.\n * @ko 카메라의 초기 yaw(y축 회전)값 (도 단위, °)\n * View360은 오른손 좌표계를 사용하기 때문에, 카메라가 해당 값만큼 시계 반대방향으로 회전합니다.\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialYaw: 30\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.yaw); // 30\n * });\n * ```\n */\n public get initialYaw() { return this._camera.initialYaw; }\n public set initialYaw(val: View360Options[\"initialYaw\"]) { this._camera.initialYaw = val; }\n /**\n * Initial pitch (x-axis rotation) value for camera. (in degrees, °)\n * As View360 uses right-handed coordinate system internally, positive value will make camera to look upside, while negative value will look down.\n * @ko 카메라의 초기 pitch(x축 회전)값 (도 단위, °)\n * View360은 오른손 좌표계를 사용하기 때문에, 양(+)의 값은 카메라가 위를 보게 하고, 음(-)의 값은 카메라가 아래를 보게 합니다.\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialPitch: 60\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.pitch); // 60\n * });\n * ```\n */\n public get initialPitch() { return this._camera.initialPitch; }\n public set initialPitch(val: View360Options[\"initialPitch\"]) { this._camera.initialPitch = val; }\n /**\n * Initial zoom value for camera.\n * Setting this value to `2` will enlarge panorama 200% by width.\n * @ko 카메라의 초기 줌 값.\n * 이 값을 `2`로 설정할 경우 파노라마 이미지를 가로 기준 200%만큼 확대합니다.\n * @default 1\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialZoom: 2\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.zoom); // 2\n * });\n * ```\n */\n public get initialZoom() { return this._camera.initialZoom; }\n public set initialZoom(val: View360Options[\"initialZoom\"]) { this._camera.initialZoom = val; }\n /**\n * Restrict yaw(y-axis rotation) range. (in degrees, °)\n * @ko yaw(y축 회전) 범위를 제한합니다. (도 단위, °)\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * yawRange: [-30, 30]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.yaw); // 0\n * viewer.camera.lookAt({ yaw: 60 });\n * console.log(viewer.camera.yaw); // 30\n * });\n * ```\n */\n public get yawRange() { return this._camera.yawRange; }\n public set yawRange(val: View360Options[\"yawRange\"]) {\n this._camera.yawRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Restrict pitch(x-axis rotation) range. (in degrees, °)\n * @ko pitch(x축 회전) 범위를 제한합니다. (도 단위, °)\n * @default null\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * pitchRange: [-45, 45]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.pitch); // 0\n * viewer.camera.lookAt({ pitch: 60 });\n * console.log(viewer.camera.pitch); // 45\n * });\n * ```\n */\n public get pitchRange() { return this._camera.pitchRange; }\n public set pitchRange(val: View360Options[\"pitchRange\"]) {\n this._camera.pitchRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Restrict camera zoom range.\n * If `null`, a default zoom range from `0.6` to `10` will be used.\n * @ko 카메라 줌 범위를 제한합니다.\n * `null`일 경우 기본값으로 `0.6`에서 `10`의 범위를 사용합니다.\n * @default null\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * zoomRange: [0.5, 4]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.zoom); // 1\n * viewer.camera.lookAt({ zoom: 6 });\n * console.log(viewer.camera.zoom); // 4\n * });\n * ```\n */\n public get zoomRange() { return this._camera.zoomRange; }\n public set zoomRange(val: View360Options[\"zoomRange\"]) {\n this._camera.zoomRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Camera's horizontal FOV(Field of View). (in degrees, °)\n * @ko 카메라의 수평 FOV(Field of View) 값. (도 단위, °)\n * @default 90\n * @since 4.0.0\n * @example\n * ```ts\n * // Init with fov: 120\n * const viewer = new View360(\"#el_id\", { fov: 120 });\n *\n * // Back to 90\n * viewer.fov = 90;\n * ```\n */\n public get fov() { return this._camera.fov; }\n public set fov(val: View360Options[\"fov\"]) {\n const camera = this._camera;\n const control = this._control;\n\n camera.fov = val;\n camera.updateMatrix();\n control.sync();\n }\n\n // Control options\n /**\n * A control for camera rotation.\n * You can also change options of {@link View360Options#rotate} with this.\n * @ko 카메라 회전을 담당하는 컨트롤.\n * {@link View360Options#rotate} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get rotate() { return this._control.rotate; }\n /**\n * A control for camera zoom.\n * You can also change options of {@link View360Options#zoom} with this.\n * @ko 카메라 줌을 담당하는 컨트롤.\n * {@link View360Options#zoom} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get zoom() { return this._control.zoom; }\n /**\n * A control for camera rotation with gyroscope input.\n * You can also change options of {@link View360Options#gyro} with this.\n * @ko 자이로스코프를 통한 카메라 회전을 담당하는 컨트롤.\n * {@link View360Options#gyro} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get gyro() { return this._control.gyro; }\n /**\n * Apply CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor} by current state of input when using mouse.\n * If `true`, this will add CSS style to canvas element. It'll apply `cursor: \"grab\"` by default and `cursor: \"grabbing\"` when holding the mouse button.\n * @ko 마우스 사용시 CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor}값을 자동으로 변경할지 여부.\n * `true`일 경우 기본 상태에서 `cursor: \"grab\"`을, 입력 도중에 `cursor: \"grabbing\"`을 캔버스에 적용합니다.\n * @default true\n * @since 4.0.0\n */\n public get useGrabCursor() { return this._control.useGrabCursor; }\n public set useGrabCursor(val: View360Options[\"useGrabCursor\"]) { this._control.useGrabCursor = val; }\n /**\n * Disable context menu which pops up on mouse right click.\n * @ko 마우스 우클릭시 표시되는 컨텍스트 메뉴를 비활성화합니다.\n * @default false\n * @since 4.0.0\n */\n public get disableContextMenu() { return this._control.disableContextMenu; }\n public set disableContextMenu(val: View360Options[\"disableContextMenu\"]) { this._control.disableContextMenu = val; }\n /**\n * If `true`, enables scroll on mobile(touch) devices on canvas.\n * :::caution\n * When this option is enabled, users must swipe horizontally first then vertically to change view up or down.\n * :::\n * @ko `true`로 설정할 경우, 모바일(터치) 환경의 캔버스 영역 내에서 스크롤을 가능하게 합니다.\n * :::caution\n * 이 값을 활성화할 경우, 사용자가 카메라 뷰를 위/아래로 바꾸기 위해서는 먼저 가로로 스와이프한 이후에 세로로 스와이프해야만 합니다.\n * :::\n * @since 4.0.0\n * @default true\n */\n public get scrollable() { return this._control.scrollable; }\n public set scrollable(val: View360Options[\"scrollable\"]) { this._control.scrollable = val; }\n /**\n * If `true`, enables scroll by mouse wheel on canvas.\n * :::caution\n * When this option is enabled, zoom by mouse wheel will be disabled.\n * :::\n * @ko `true`로 설정할 경우, 캔버스 영역 내에서 마우스 휠을 이용한 페이지 스크롤이 가능해집니다.\n * :::caution\n * 이 값을 활성화할 경우, 마우스 휠을 통한 줌이 불가능하게 됩니다.\n * :::\n * @since 4.0.0\n * @default false\n */\n public get wheelScrollable() { return this._control.wheelScrollable; }\n public set wheelScrollable(val: View360Options[\"wheelScrollable\"]) { this._control.wheelScrollable = val; }\n\n /**\n * Create new instance of View360\n * @ko View360의 새로운 인스턴스를 생성합니다\n * @param root - Root element(`.view360-container`) to mount View360\n * Can be either a CSS selector or HTMLElement.\n * {@ko View360을 마운트할 루트 엘리먼트, CSS 셀렉터나 HTMLElement를 지정 가능합니다.}\n * @param options - Options to apply\n * {@ko 적용할 옵션들}\n * @example\n * ```ts\n * import View360, { EquirectProjection } from \"@egjs/view360\";\n *\n * // Create new View360 instance\n * const viewer = new View360(\"#id-of-a-container\", {\n * projection: new EquirectProjection({\n * src: \"URL_TO_PANORAMA_IMAGE_OR_VIDEO\",\n * })\n * });\n * ```\n */\n public constructor(root: string | HTMLElement, {\n projection = null,\n initialYaw = 0,\n initialPitch = 0,\n initialZoom = 1,\n yawRange = null,\n pitchRange = null,\n zoomRange = null,\n fov = 90,\n useGrabCursor = true,\n disableContextMenu = false,\n rotate = true,\n zoom = true,\n gyro = false,\n scrollable = true,\n wheelScrollable = false,\n autoplay = false,\n hotspot = {},\n autoInit = true,\n autoResize = true,\n canvasSelector = \"canvas\",\n useResizeObserver = true,\n on = {},\n plugins = [],\n maxDeltaTime = 1 / 30,\n tabIndex = 0,\n debug = false\n }: Partial = {}) {\n super();\n\n this._rootEl = getElement(root);\n this._plugins = plugins;\n this._initialized = false;\n\n // Options\n this._autoInit = autoInit;\n this._autoResize = autoResize;\n this._canvasSelector = canvasSelector;\n this._useResizeObserver = useResizeObserver;\n this._tabIndex = tabIndex;\n this._debug = debug;\n\n // Core components\n const canvas = findCanvas(this._rootEl, canvasSelector);\n this._renderer = new WebGLRenderer(canvas, debug);\n this._camera = new Camera({\n initialYaw,\n initialPitch,\n initialZoom,\n fov,\n yawRange,\n pitchRange,\n zoomRange\n });\n this._control = new PanoControl(canvas, this._camera, {\n useGrabCursor,\n scrollable,\n wheelScrollable,\n disableContextMenu,\n rotate,\n zoom,\n gyro\n });\n this._animator = new FrameAnimator(maxDeltaTime);\n this._autoplay = new Autoplay(this, canvas, autoplay);\n this._projection = projection;\n this._autoResizer = new AutoResizer(useResizeObserver, () => this.resize());\n this._vr = new XRManager(this._renderer.ctx);\n this._hotspot = new HotspotRenderer(this._rootEl, this._renderer, hotspot);\n\n this._addEventHandlers(on);\n\n if (projection && autoInit) {\n this.init();\n }\n }\n\n /**\n * Destroy instance and release all resources.\n * @ko 인스턴스를 제거하고 모든 리소스를 해제합니다.\n * @since 4.0.0\n */\n public destroy() {\n this._camera.destroy();\n this._animator.stop();\n this._renderer.destroy();\n this._control.destroy();\n this._autoResizer.disable();\n\n if (this._projection) {\n this._projection.releaseAllResources(this._renderer.ctx);\n this._projection = null;\n }\n\n this._plugins.forEach(plugin => plugin.destroy(this));\n\n this._initialized = false;\n }\n\n /**\n * Initialize inner components and load projection src.\n * @ko 내부 컴포넌트들을 초기화하고 프로젝션 소스를 로드합니다.\n * @since 4.0.0\n */\n public async init() {\n if (!this._projection) {\n throw new View360Error(ERROR.MESSAGES.PROVIDE_PROJECTION_FIRST, ERROR.CODES.PROVIDE_PROJECTION_FIRST);\n }\n\n const renderer = this._renderer;\n const camera = this._camera;\n const control = this._control;\n const animator = this._animator;\n const hotspot = this._hotspot;\n const projection = this._projection;\n const canvas = renderer.canvas;\n\n this._bindComponentEvents();\n renderer.ctx.init();\n this._resizeComponents();\n camera.updateMatrix();\n\n if (this._autoResize) {\n this._autoResizer.enable(canvas);\n }\n\n if (!this._autoplay.enableBlocked) {\n this._autoplay.enable();\n }\n\n this._plugins.forEach(plugin => {\n plugin.init(this);\n });\n\n const texture = await this._loadTexture(projection);\n this._applyProjection(projection, texture, null);\n hotspot.refresh();\n animator.start(this._renderFrameOnDemand);\n await control.enable();\n\n if (this._tabIndex != null && !canvas.hasAttribute(\"tabIndex\")) {\n canvas.tabIndex = this._tabIndex;\n }\n\n this._initialized = true;\n this.renderFrame(0);\n\n this._emit(EVENTS.READY);\n }\n\n /**\n * Load new panorama image/video and display it.\n * This will {@link View360#init init()} View360 if it's not initialized yet.\n * @ko 새로운 파노라마 이미지 혹은 비디오를 로드하고 표시합니다.\n * 만약 View360이 아직 초기화되지 않았다면, {@link View360#init init()}을 호출합니다.\n * @param projection - Projection & video options for new source. {@ko 새로운 파노라마 이미지/비디오에 적용할 옵션들}\n * @returns `Promise` if load was successful. {@ko 프로젝션 로드에 성공했을 경우 `Promise`를 반환합니다. }\n * @since 4.0.0\n * @example\n * ```ts\n * // Change to video\n * viewer.load({\n * src: \"URL_TO_NEW_VIDEO\",\n * video: true\n * });\n * ```\n */\n public async load(projection: Projection): Promise {\n if (!projection) return false;\n\n if (this._initialized) {\n const texture = await this._loadTexture(projection);\n this._applyProjection(projection, texture, this._projection);\n this.renderFrame(0);\n } else {\n // Should update internal options before init\n this._projection = projection;\n this.init();\n }\n\n return true;\n }\n\n /**\n * Refresh component's size by current\n * @ko View360이 내부적으로 캐시하고 있는 엘리먼트 크기를 현재 크기로 갱신합니다.\n * @since 4.0.0\n */\n public resize() {\n if (!this._initialized) return;\n\n this._resizeComponents();\n\n // To prevent flickering, render immediately after resizing components\n this.renderFrame(0);\n\n const { width, height } = this._renderer;\n\n this._emit(EVENTS.RESIZE, {\n width,\n height\n });\n }\n\n /**\n * Add new plugins\n * @ko 새로운 플러그인을 추가합니다.\n * @param plugins Plugins to add {@ko 추가할 플러그인들}\n * @see View360Options#plugins\n * @since 4.0.0\n * @example\n * ```ts\n * // Add a single plugin\n * viewer.addPlugins(new ControlBar());\n *\n * // Add multiple plugins\n * viewer.addPlugins(new ControlBar(), new LoadingSpinner());\n * ```\n */\n public addPlugins(...plugins: View360Plugin[]) {\n if (this._initialized) {\n plugins.forEach(plugin => { plugin.init(this); });\n }\n\n this._plugins.push(...plugins);\n }\n\n /**\n * Remove plugins.\n * @ko 플러그인을 제거합니다.\n * @param plugins Plugins to remove {@ko 제거할 플러그인들}\n * @since 4.0.0\n * @example\n * ```ts\n * // Remove a single plugin\n * viewer.removePlugins(plugin1);\n *\n * // Remove multiple plugins\n * viewer.removePlugins(plugin2, plugin3);\n * ```\n */\n public removePlugins(...plugins: View360Plugin[]) {\n plugins.forEach(plugin => {\n const pluginIdx = this._plugins.indexOf(plugin);\n\n if (pluginIdx < 0) return;\n\n plugin.destroy(this);\n this._plugins.splice(pluginIdx, 1);\n });\n }\n\n /**\n * Render a single panorama image/video frame.\n * Rendering is performed automatically on demand, so you usually don't have to call this.\n * Call this when a frame is not renewed after changing options.\n * @ko 파노라마 이미지/비디오의 한 프레임을 렌더링합니다.\n * 프레임 갱신은 보통 필요한 때에만 자동적으로 이루어지기 때문에, 보통은 이 메소드를 호출할 필요는 없습니다.\n * 옵션 변경 이후에도 프레임 갱신이 이루어지지 않는다면, 이 메소드를 호출해주세요.\n * @param delta Delta time in milisec. {@ko 프레임간 시간 차이, 밀리초 단위}\n * @since 4.0.0\n */\n public renderFrame = (delta: number) => {\n const camera = this._camera;\n const renderer = this._renderer;\n const control = this._control;\n const hotspot = this._hotspot;\n const autoPlayer = this._autoplay;\n const projection = this._projection;\n\n if (!projection) return;\n\n this._emit(EVENTS.BEFORE_RENDER);\n\n if (autoPlayer.playing) {\n autoPlayer.update(delta);\n control.sync();\n }\n\n if (camera.animation) {\n camera.animation.update(delta);\n } else {\n control.update(delta);\n }\n\n renderer.render(projection, camera);\n hotspot.render(camera);\n\n if (camera.changed) {\n this._emit(EVENTS.VIEW_CHANGE, {\n yaw: camera.yaw,\n pitch: camera.pitch,\n zoom: camera.zoom,\n quaternion: [\n camera.quaternion[0],\n camera.quaternion[1],\n camera.quaternion[2],\n camera.quaternion[3]\n ]\n });\n }\n camera.onFrameRender();\n\n this._emit(EVENTS.RENDER);\n };\n\n private _emit(eventName: K, ...params: EventParams) {\n const evtParams = params ? params[0] : {};\n\n this.trigger(eventName as any, {\n type: eventName,\n target: this,\n ...evtParams\n });\n }\n\n private _renderFrameOnDemand = (delta: number) => {\n const camera = this._camera;\n const control = this._control;\n const autoplay = this._autoplay;\n const texture = this._projection?.getTexture();\n\n if (!this._initialized || !texture) return;\n if (\n !camera.animation\n && !control.animating\n && !autoplay.playing\n && !texture.isVideo()\n ) return;\n\n this.renderFrame(delta);\n };\n\n private _renderVRFrame = (_delta: number, frame: XRFrame) => {\n const vr = this._vr;\n const projection = this._projection;\n const renderer = this._renderer;\n\n if (!projection) return;\n\n this._emit(EVENTS.BEFORE_RENDER);\n\n renderer.renderVR(projection, vr, frame);\n\n this._emit(EVENTS.RENDER);\n }\n\n private _applyProjection(projection: Projection, texture: Texture, prevProjection: Projection | null) {\n const camera = this._camera;\n const control = this._control;\n const renderer = this._renderer;\n\n // Remove previous projection\n if (prevProjection) {\n prevProjection.releaseAllResources(this._renderer.ctx);\n }\n\n projection.applyTexture(renderer.ctx, texture);\n projection.updateCamera(camera);\n projection.updateControl(control);\n\n this._projection = projection;\n this._emit(EVENTS.PROJECTION_CHANGE, {\n projection\n });\n }\n\n private async _loadTexture(projection: Projection): Promise {\n const contentLoader = new TextureLoader();\n const { src, video } = projection;\n\n this._emit(EVENTS.LOAD_START, {\n src,\n video\n });\n\n const texture = await contentLoader.load(src, video);\n\n this._emit(EVENTS.LOAD, {\n src,\n video\n });\n\n return texture;\n }\n\n private _resizeComponents() {\n const renderer = this._renderer;\n const camera = this._camera;\n const control = this._control;\n\n renderer.resize();\n camera.resize(renderer.width, renderer.height);\n control.resize(renderer.width, renderer.height);\n }\n\n private _addEventHandlers(events: View360Options[\"on\"]) {\n // Bind option \"on\"\n Object.keys(events).forEach((evtName: keyof typeof EVENT_TYPES) => {\n this.on(evtName, events[evtName]);\n });\n }\n\n private _bindComponentEvents() {\n // Bind internal component events\n const root = this._rootEl;\n const control = this._control;\n const animator = this._animator;\n const renderer = this._renderer;\n const vr = this._vr;\n\n const controlEventsToPropagate = [\n CONTROL_EVENTS.STATIC_CLICK,\n CONTROL_EVENTS.INPUT_START,\n CONTROL_EVENTS.INPUT_END\n ];\n\n controlEventsToPropagate.forEach(evtName => {\n control.rotate.on(evtName, evt => {\n this._emit(evtName, evt);\n });\n\n control.zoom.on(evtName, evt => {\n this._emit(evtName, evt);\n });\n });\n\n vr.on(EVENTS.VR_START, evt => {\n root.classList.add(DEFAULT_CLASS.IN_VR);\n\n animator.changeContext(evt.session);\n animator.start(this._renderVRFrame);\n\n this._emit(EVENTS.VR_START);\n });\n\n vr.on(EVENTS.VR_END, () => {\n root.classList.remove(DEFAULT_CLASS.IN_VR);\n\n renderer.ctx.useDefaultFrameBuffer();\n animator.changeContext(window);\n animator.start(this._renderFrameOnDemand);\n\n this.resize();\n\n this._emit(EVENTS.VR_END);\n });\n }\n}\n\nexport default View360;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4, quat, vec3 } from \"gl-matrix\";\n\n/**\n * Base class for 3D objects\n * @ko 3D 오브젝트의 베이스 클래스\n * @since 4.0.0\n * @internal\n */\nclass Object3D {\n /**\n * Local matrix of the object\n * @ko 오브젝트의 local matrix\n * @since 4.0.0\n */\n public matrix: mat4;\n /**\n * Rotation quaternion\n * @ko 현재 오브젝트의 회전을 나타내는 사원수 값\n * @since 4.0.0\n */\n public rotation: quat;\n /**\n * Position of the object\n * @ko 오브젝트의 위치\n * @since 4.0.0\n */\n public position: vec3;\n /**\n * A scale vector of the object\n * @ko 오브젝트가 각 축으로 확대된 정도를 나타내는 벡터\n * @since 4.0.0\n */\n public scale: vec3;\n\n /**\n * Create new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n */\n public constructor() {\n this.matrix = mat4.create();\n this.rotation = quat.create();\n this.position = vec3.fromValues(0, 0, 0);\n this.scale = vec3.fromValues(1, 1, 1);\n }\n\n /**\n * Update local matrix of the object.\n * @ko 오브젝트의 local matrix를 갱신합니다.\n * @since 4.0.0\n */\n public updateMatrix() {\n mat4.fromRotationTranslationScale(this.matrix, this.rotation, this.position, this.scale);\n }\n}\n\nexport default Object3D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360Plugin from \"../View360Plugin\";\nimport View360 from \"../../View360\";\nimport { EVENTS } from \"../../const/external\";\nimport { createElement } from \"../../utils\";\nimport { LoadStartEvent } from \"../../type/events\";\n\n/**\n * Options for {@link LoadingSpinner}\n * @ko {@link LoadingSpinner}용 옵션들\n * @since 4.0.0\n * @category Plugin\n */\nexport interface LoadingSpinnerOptions {\n /**\n * Override default class names.\n * @ko 디폴트 클래스 이름들을 오버라이드합니다.\n * @since 4.0.0\n */\n className: Partial<{ -readonly [key in keyof typeof LoadingSpinner.DEFAULT_CLASS]: string }>;\n}\n\n/**\n * A plugin that displays loading spinner while loading the projection.\n * @ko 프로젝션 로딩중에 로딩 스피너를 보여주는 플러그인\n * @since 4.0.0\n * @category Plugin\n */\nclass LoadingSpinner implements View360Plugin {\n /**\n * Default class names that LoadingSpinner uses\n * @ko LoadingSpinner가 사용하는 디폴트 클래스 이름\n * @since 4.0.0\n */\n public static readonly DEFAULT_CLASS = {\n /**\n * A class name for the container element\n * @ko 컨테이너 엘리먼트의 클래스 이름\n * @since 4.0.0\n */\n CONTAINER: \"view360-spinner\",\n /**\n * A class name for the spinning ring element\n * @ko 돌아가는 링 엘리먼트의 클래스 이름\n * @since 4.0.0\n */\n RING: \"view360-spinner-ring\"\n } as const;\n\n /**\n * A class names overriding\n * @ko 현재 오버라이드 중인 클래스 이름\n * @since 4.0.0\n */\n public readonly className: LoadingSpinnerOptions[\"className\"];\n\n private _container: HTMLElement;\n\n /**\n * Create a new instance of LoadingSpinner. {@ko LoadingSpinner의 새 인스턴스를 생성합니다.}\n * @param options Options {@ko 옵션들}\n */\n public constructor({\n className = {}\n }: Partial = {}) {\n this.className = className;\n this._container = this._createElements();\n }\n\n public init(viewer: View360) {\n viewer.on(EVENTS.LOAD_START, this._startLoading);\n }\n\n public destroy(viewer: View360): void {\n viewer.off(EVENTS.LOAD_START, this._startLoading);\n this._detachElements({ target: viewer });\n }\n\n private _startLoading = ({ target: viewer }: LoadStartEvent) => {\n viewer.rootEl.appendChild(this._container);\n\n if (viewer.initialized) {\n viewer.once(EVENTS.LOAD, this._detachElements);\n } else {\n viewer.once(EVENTS.READY, this._detachElements);\n }\n };\n\n private _detachElements = ({ target: viewer }: { target: View360 }) => {\n const container = this._container;\n if (!container) return;\n\n if (container.parentElement === viewer.rootEl) {\n viewer.rootEl.removeChild(container);\n }\n };\n\n private _createElements() {\n const className = {\n ...this.className,\n ...LoadingSpinner.DEFAULT_CLASS\n };\n\n const container = createElement(className.CONTAINER);\n const ring = createElement(className.RING);\n\n container.appendChild(ring);\n\n return container;\n }\n}\n\nexport default LoadingSpinner;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n/* eslint-disable @typescript-eslint/no-empty-function */\n/* eslint-disable @typescript-eslint/no-unused-vars */\nimport ControlBar from \"./ControlBar\";\nimport View360 from \"../../View360\";\n\n/**\n * Common options for {@link ControlBarItem}\n * @ko {@link ControlBarItem}의 공통 옵션들\n * @category Plugin\n * @since 4.0.0\n */\nexport interface ControlBarItemOptions {\n /**\n * @copy ControlBarItem#position\n */\n position: typeof ControlBar.POSITION[keyof typeof ControlBar.POSITION];\n /**\n * @copy ControlBarItem#order\n */\n order: number;\n}\n\n/**\n * Interface of the ControlBar items\n * @ko 컨트롤바 아이템의 인터페이스\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nabstract class ControlBarItem {\n /**\n * Element of the item.\n * @ko 아이템의 엘리먼트\n * @since 4.0.0\n */\n public abstract element: HTMLElement;\n\n /**\n * Position to display item.\n * @ko 아이템을 표시할 위치.\n * @since 4.0.0\n */\n public position: ControlBarItemOptions[\"position\"];\n /**\n * Order within the same position.\n * The lowest one will be shown first.\n * @ko 동일한 position 내에서의 순서, 작을수록 먼저 표시됩니다.\n * @since 4.0.0\n */\n public order: ControlBarItemOptions[\"order\"];\n\n /**\n * Create new instance of the ControlBarItem\n * @ko ControlBarItem의 새로운 인스턴스를 생성합니다.\n * @param options Options {@ko 옵션들}\n */\n public constructor(options: ControlBarItemOptions) {\n this.position = options.position;\n this.order = options.order;\n }\n\n /**\n * Initialize item.\n * @ko 아이템을 초기화합니다.\n * @param viewer - A instance of viewer to attach item {@ko 아이템을 부착할 뷰어의 인스턴스}\n * @param controlBar - A instance of control bar to attach item {@ko 아이템을 부착할 컨트롤바의 인스턴스}\n * @since 4.0.0\n */\n public abstract init(viewer: View360, controlBar: ControlBar): any;\n /**\n * Destroy item and release all resources & event handlers.\n * @ko 아이템을 제거하고 할당된 모든 리소스 및 이벤트 핸들러를 제거합니다.\n * @param viewer - A instance of viewer to detach item {@ko 아이템을 떼어 낼 뷰어의 인스턴스}\n * @param controlBar - A instance of control bar to detach item {@ko 아이템을 떼어 낼 컨트롤바의 인스턴스}\n * @since 4.0.0\n */\n public abstract destroy(viewer: View360, controlBar: ControlBar): any;\n}\n\nexport default ControlBarItem;\n","export const CONTROL_BAR_DEFAULT_CLASS = {\n CONTROLS_ROOT: \"view360-controls\",\n CONTROLS_BG: \"view360-controls-background\",\n CONTROLS_MAIN: \"view360-controls-main\",\n CONTROLS_TOP: \"view360-controls-top\",\n CONTROLS_BOTTOM: \"view360-controls-bottom\",\n CONTROLS_MID: \"view360-controls-mid\",\n CONTROLS_LEFT: \"view360-controls-left\",\n CONTROLS_RIGHT: \"view360-controls-right\",\n CONTROLS_FLOAT_LEFT: \"view360-controls-float-left\",\n CONTROLS_FLOAT_RIGHT: \"view360-controls-float-right\",\n CONTROLS_BUTTON: \"view360-controls-button\",\n PROGRESS_ROOT: \"view360-controls-progress\",\n VOLUME_ROOT: \"view360-controls-volume\",\n RANGE_ROOT: \"view360-range\",\n RANGE_TRACK: \"view360-range-track\",\n RANGE_THUMB: \"view360-range-thumb\",\n RANGE_FILLER: \"view360-range-filler\",\n PLAY_BUTTON: \"view360-controls-play\",\n PAUSE_BUTTON: \"view360-controls-pause\",\n UNMUTED_BUTTON: \"view360-controls-unmuted\",\n MUTED_BUTTON: \"view360-controls-muted\",\n FULLSCREEN_BUTTON: \"view360-controls-fullscreen\",\n FULLSCREEN_EXIT_BUTTON: \"view360-controls-fullscreen-exit\",\n VR_BUTTON: \"view360-controls-vr\",\n GYRO_ENABLED: \"view360-controls-gyro-enabled\",\n GYRO_DISABLED: \"view360-controls-gyro-disabled\",\n VIDEO_TIME_DISPLAY: \"view360-controls-time\",\n PIEVIEW_ROOT: \"view360-controls-pie\",\n FIXED: \"view360-controls-fixed\",\n UNAVAILABLE: \"view360-controls-unavailable\",\n HIDDEN: \"view360-controls-hidden\"\n} as const;\n\nexport const CONTROL_BAR_ITEM_POSITION = {\n /**\n * Place control bar item floating at top-left corner\n * @ko 아이템을 왼쪽 위 구석에 표시합니다.\n * @since 4.0.0\n */\n TOP_LEFT: \"top-left\",\n /**\n * Place control bar item floating at top-right corner\n * @ko 아이템을 오른쪽 위 구석에 표시합니다.\n * @since 4.0.0\n */\n TOP_RIGHT: \"top-right\",\n /**\n * Place control bar item at upper block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 위쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_TOP: \"main-top\",\n /**\n * Place control bar item at lower block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 하단 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_BOTTOM: \"main-bottom\",\n /**\n * Place control bar item at center-left block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 왼쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_LEFT: \"main-left\",\n /**\n * Place control bar item at center-right block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 오른쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_RIGHT: \"main-right\"\n} as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { ControlBarOptions } from \"./ControlBar\";\nimport { CONTROL_BAR_DEFAULT_CLASS } from \"./const\";\nimport Motion from \"../../core/Motion\";\nimport MouseInput from \"../../control/input/MouseInput\";\nimport TouchInput from \"../../control/input/TouchInput\";\nimport { CONTROL_EVENTS, INFINITE_RANGE } from \"../../const/internal\";\nimport { clamp } from \"../../utils\";\nimport { InputEvents } from \"../../type/internal\";\nimport { EL_DIV } from \"../../const/browser\";\n\nclass RangeControl extends Component<{\n [CONTROL_EVENTS.INPUT_START]: number;\n [CONTROL_EVENTS.CHANGE]: number;\n [CONTROL_EVENTS.INPUT_END]: void;\n}> {\n public readonly rootEl: HTMLElement;\n public readonly thumbEl: HTMLElement;\n public readonly trackEl: HTMLElement;\n public readonly fillerEl: HTMLElement;\n\n private _motion: Motion;\n private _mouseInput: MouseInput;\n private _touchInput: TouchInput;\n private _fixedClass: string;\n private _bbox: DOMRect;\n\n /**\n *\n */\n public constructor() {\n super();\n\n const root = document.createElement(EL_DIV);\n const track = document.createElement(EL_DIV);\n const thumb = document.createElement(EL_DIV);\n const filler = document.createElement(EL_DIV);\n\n root.draggable = false;\n\n track.appendChild(filler);\n track.appendChild(thumb);\n root.appendChild(track);\n\n this.rootEl = root;\n this.trackEl = track;\n this.thumbEl = thumb;\n this.fillerEl = filler;\n\n this._mouseInput = new MouseInput();\n this._touchInput = new TouchInput();\n this._motion = new Motion({ duration: 1, range: INFINITE_RANGE, easing: x => x });\n this._bbox = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n left: 0,\n right: 0,\n bottom: 0,\n top: 0\n } as DOMRect;\n this._fixedClass = CONTROL_BAR_DEFAULT_CLASS.FIXED;\n }\n\n public init(className: Required) {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n\n this.rootEl.classList.add(className.RANGE_ROOT);\n this.trackEl.classList.add(className.RANGE_TRACK);\n this.thumbEl.classList.add(className.RANGE_THUMB);\n this.fillerEl.classList.add(className.RANGE_FILLER);\n this._fixedClass = className.FIXED;\n\n mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n touchInput.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n\n mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n touchInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n\n mouseInput.enable(this.rootEl);\n touchInput.enable(this.rootEl);\n\n this.resize();\n }\n\n public destroy() {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n\n this.rootEl.className = \"\";\n this.trackEl.className = \"\";\n this.thumbEl.className = \"\";\n this.fillerEl.className = \"\";\n\n mouseInput.off();\n touchInput.off();\n mouseInput.disable();\n touchInput.disable();\n }\n\n public resize() {\n this._bbox = this.trackEl.getBoundingClientRect();\n }\n\n public updateStyle(progress: number) {\n const width = this._bbox.width;\n const clampedProgress = clamp(progress, 0, 1);\n\n this.fillerEl.style.width = `${clampedProgress * 100}%`;\n this.thumbEl.style.transform = `translateX(${clampedProgress * width}px)`;\n }\n\n private _onHold = ({ srcEvent, isTouch }: InputEvents<{ x: number; y: number }>[typeof CONTROL_EVENTS.INPUT_START]) => {\n const bbox = this._bbox;\n if (!bbox) return;\n\n const x = isTouch\n ? (srcEvent as TouchEvent).touches[0].pageX\n : (srcEvent as MouseEvent).pageX;\n const elX = bbox.x + (window.scrollX ?? window.pageXOffset);\n\n const clamepdX = clamp(x, elX, elX + bbox.width);\n const progress = (clamepdX - elX) / bbox.width;\n\n this._motion.reset(clamepdX);\n this.thumbEl.classList.add(this._fixedClass);\n\n this.trigger(CONTROL_EVENTS.INPUT_START, progress);\n };\n\n private _onChange = ({ delta }: InputEvents<{ x: number; y: number }>[typeof CONTROL_EVENTS.CHANGE]) => {\n const motion = this._motion;\n const bbox = this._bbox;\n if (!bbox) return;\n\n motion.setNewEndByDelta(delta.x);\n motion.update(1);\n\n const elX = bbox.x + (window.scrollX ?? window.pageXOffset);\n const clampedX = clamp(motion.val, elX, elX + bbox.width);\n const progress = (clampedX - elX) / bbox.width;\n\n this.trigger(CONTROL_EVENTS.CHANGE, progress);\n };\n\n private _onRelease = () => {\n const bbox = this._bbox;\n if (!bbox) return;\n\n this.thumbEl.classList.remove(this._fixedClass);\n\n this.trigger(CONTROL_EVENTS.INPUT_END);\n };\n}\n\nexport default RangeControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport RangeControl from \"./RangeControl\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport { CONTROL_EVENTS, VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport { EVENTS } from \"../../const/external\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show video progress bar.\n * @ko 비디오의 프로그레스 바를 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass ProgressBar extends ControlBarItem {\n public get element() { return this._rangeControl.rootEl; }\n\n private _controlBar: ControlBar | null;\n private _video: TextureVideo | null;\n private _rangeControl: RangeControl;\n\n private _wasPaused: boolean;\n private _currentTime: number;\n private _duration: number;\n private _playPromise: Promise | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_TOP,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.position = position;\n this.order = order;\n\n this._controlBar = null;\n this._rangeControl = new RangeControl();\n\n this._video = null;\n this._wasPaused = false;\n this._currentTime = 0;\n this._duration = 0;\n this._playPromise = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const element = this.element;\n const rangeControl = this._rangeControl;\n const unavailableClass = controlBar.className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n element.classList.add(unavailableClass);\n return;\n }\n\n element.classList.remove(unavailableClass);\n element.classList.add(controlBar.className.PROGRESS_ROOT);\n viewer.on(EVENTS.RESIZE, this._onResize);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate);\n rangeControl.init(controlBar.className);\n rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n rangeControl.on(CONTROL_EVENTS.CHANGE, this._onControl);\n rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n this._video = video;\n this._currentTime = video.source.currentTime;\n this._duration = video.source.duration;\n this._controlBar = controlBar;\n\n rangeControl.updateStyle(this._currentTime / this._duration);\n }\n\n public destroy(viewer: View360) {\n const video = this._video;\n\n viewer.off(EVENTS.RESIZE, this._onResize);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate);\n }\n\n this._rangeControl.destroy();\n this._video = null;\n this._playPromise = null;\n }\n\n private _onResize = () => {\n this._rangeControl.resize();\n }\n\n private _onTimeUpdate = () => {\n const video = this._video;\n if (!video) return;\n\n this._currentTime = video.source.currentTime;\n this._rangeControl.updateStyle(this._currentTime / this._duration);\n };\n\n private _onDurationChange = () => {\n const video = this._video;\n if (!video) return;\n\n this._duration = video.source.duration;\n this._rangeControl.updateStyle(this._currentTime / this._duration);\n };\n\n private _onHold = (progress: number) => {\n const video = this._video;\n const controlBar = this._controlBar;\n if (!video || !controlBar) return;\n\n const paused = video.isPaused();\n\n video.source.pause();\n\n const time = video.source.duration * progress;\n video.source.currentTime = time;\n video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time }}));\n\n controlBar.rootEl.classList.add(controlBar.className.FIXED);\n this._wasPaused = !this._playPromise && paused;\n };\n\n private _onControl = (progress: number) => {\n const video = this._video;\n if (!video) return;\n\n const time = video.source.duration * progress;\n video.source.currentTime = time;\n video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time }}));\n };\n\n private _onRelease = () => {\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (video && controlBar) {\n if (!this._wasPaused && !this._playPromise) {\n this._playPromise = video.source.play()\n .catch(() => void 0);\n\n // This should not be chained\n this._playPromise.then(() => {\n this._playPromise = null;\n });\n\n controlBar.rootEl.classList.remove(controlBar.className.FIXED);\n }\n }\n\n this._wasPaused = false;\n };\n}\n\nexport default ProgressBar;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show video play / pause button.\n * @ko 비디오 재생 / 일시정지 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass PlayButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _controlBar: ControlBar | null;\n private _video: TextureVideo | null;\n private _paused: boolean;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n\n this._video = null;\n this._paused = true;\n this._controlBar = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const video = viewer.projection?.getTexture();\n const className = controlBar.className;\n const unavailableClass = className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n element.classList.add(unavailableClass);\n return;\n }\n\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.remove(unavailableClass);\n\n const paused = video.isPaused();\n this._video = video;\n this._paused = paused;\n this._controlBar = controlBar;\n\n if (paused) {\n this._onPause();\n } else {\n this._onPlay();\n }\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onPlay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onPause);\n }\n\n public destroy() {\n const video = this._video;\n const element = this.element;\n\n if (!video) return;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onPlay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onPause);\n\n this._video = null;\n this._paused = true;\n this._controlBar = null;\n }\n\n private _onClick = () => {\n const video = this._video;\n if (!video) return;\n\n if (this._paused) {\n video.source.play();\n } else {\n video.source.pause();\n }\n };\n\n private _onPlay = () => {\n if (!this._controlBar) return;\n\n const element = this.element;\n const className = this._controlBar.className;\n\n element.classList.add(className.PAUSE_BUTTON);\n element.classList.remove(className.PLAY_BUTTON);\n element.title = \"Pause Video\";\n\n this._paused = false;\n };\n\n private _onPause = () => {\n if (!this._controlBar) return;\n\n const element = this.element;\n const className = this._controlBar.className;\n\n element.classList.add(className.PLAY_BUTTON);\n element.classList.remove(className.PAUSE_BUTTON);\n element.title = \"Play Video\";\n\n this._paused = true;\n };\n}\n\nexport default PlayButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport RangeControl from \"./RangeControl\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { EVENTS } from \"../../const/external\";\n\n/**\n * Show video volume control.\n * @ko 비디오 볼륨 조절 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VolumeControl extends ControlBarItem {\n public get element() { return this._rootEl; }\n\n private _controlBar: ControlBar | null;\n private _rootEl: HTMLButtonElement;\n private _buttonEl: HTMLElement;\n private _rangeControl: RangeControl;\n private _video: TextureVideo | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this._controlBar = null;\n this._rangeControl = new RangeControl();\n this._createElements();\n\n this._video = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const root = this._rootEl;\n const button = this._buttonEl;\n const rangeControl = this._rangeControl;\n const className = controlBar.className;\n const unavailableClass = className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n root.classList.add(unavailableClass);\n return;\n }\n\n root.classList.remove(unavailableClass);\n root.classList.add(className.CONTROLS_BUTTON);\n root.classList.add(className.VOLUME_ROOT);\n button.classList.add(className.CONTROLS_BUTTON);\n\n if (video.source.muted) {\n button.classList.add(className.MUTED_BUTTON);\n } else {\n button.classList.add(className.UNMUTED_BUTTON);\n }\n\n viewer.on(EVENTS.RESIZE, this._onResize);\n root.addEventListener(BROWSER.EVENTS.TRANSITION_END, this._onResize);\n button.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_VOLUME_CHANGE, this._onVolumeChange);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_LOADED_DATA, this._updateDisplay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay);\n\n rangeControl.init(className);\n rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n rangeControl.on(CONTROL_EVENTS.CHANGE, this._onChange);\n rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n this._controlBar = controlBar;\n this._video = video;\n\n this._updateDisplay();\n }\n\n public destroy(viewer: View360) {\n const video = this._video;\n const button = this._buttonEl;\n const root = this._rootEl;\n\n root.className = \"\";\n button.className = \"\";\n\n viewer.off(EVENTS.RESIZE, this._onResize);\n root.removeEventListener(BROWSER.EVENTS.TRANSITION_END, this._onResize);\n button.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_VOLUME_CHANGE, this._onVolumeChange);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_LOADED_DATA, this._updateDisplay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay);\n }\n\n this._controlBar = null;\n this._rangeControl.destroy();\n this._video = null;\n }\n\n private _onResize = () => {\n this._rangeControl.resize();\n this._updateDisplay();\n }\n\n private _onClick = () => {\n const video = this._video;\n if (!video || this._rootEl.disabled) return;\n\n video.source.muted = !video.source.muted;\n };\n\n private _onVolumeChange = () => {\n const button = this._buttonEl;\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (!video || !controlBar) return;\n\n const className = controlBar.className;\n\n if (video.source.muted || video.source.volume === 0) {\n button.classList.add(className.MUTED_BUTTON);\n button.classList.remove(className.UNMUTED_BUTTON);\n } else {\n button.classList.add(className.UNMUTED_BUTTON);\n button.classList.remove(className.MUTED_BUTTON);\n }\n\n this._updateDisplay();\n };\n\n private _createElements() {\n const root = document.createElement(BROWSER.EL_BUTTON);\n const buttonEl = document.createElement(BROWSER.EL_DIV);\n\n root.appendChild(this._rangeControl.rootEl);\n root.appendChild(buttonEl);\n root.title = \"Toggle Mute\";\n\n this._rootEl = root;\n this._buttonEl = buttonEl;\n }\n\n private _onHold = (progress: number) => {\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (!video || !controlBar) return;\n\n const className = controlBar.className;\n\n video.source.volume = progress;\n\n this._rootEl.classList.add(className.FIXED);\n controlBar.containerEl.classList.add(className.FIXED);\n\n this._updateDisplay();\n };\n\n private _onChange = (progress: number) => {\n const video = this._video;\n if (!video) return;\n\n video.source.volume = progress;\n if (progress > 0) {\n video.source.muted = false;\n } else {\n video.source.muted = true;\n }\n\n this._updateDisplay();\n };\n\n private _onRelease = () => {\n const controlBar = this._controlBar;\n if (!controlBar) return;\n\n const className = controlBar.className;\n\n this._rootEl.classList.remove(className.FIXED);\n controlBar.containerEl.classList.remove(className.FIXED);\n };\n\n private _updateDisplay = () => {\n const video = this._video;\n const root = this._rootEl;\n if (!video) return;\n\n if (!video.hasAudio()) {\n root.disabled = true;\n return;\n }\n\n root.disabled = false;\n\n const volume = video.source.muted ? 0 : video.source.volume;\n\n this._rangeControl.updateStyle(volume);\n };\n}\n\nexport default VolumeControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport { isFullscreen } from \"../../utils\";\n\n/**\n * Show fullscreen enter / exit button.\n * @ko 풀스크린 진입 / 해제 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass FullscreenButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _controlBar: ControlBar | null;\n private _targetEl: HTMLElement | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n this.element.title = \"Toggle Fullscreen\";\n this._controlBar = null;\n this._targetEl = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n if (!this._fullscreenAvailable()) {\n element.classList.add(className.UNAVAILABLE);\n return;\n }\n\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.remove(className.UNAVAILABLE);\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._addFullscreenHandlers();\n\n if (isFullscreen()) {\n element.classList.add(className.FULLSCREEN_EXIT_BUTTON);\n } else {\n element.classList.add(className.FULLSCREEN_BUTTON);\n }\n\n this._controlBar = controlBar;\n this._targetEl = viewer.rootEl;\n }\n\n public destroy() {\n const element = this.element;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._removeFullscreenHandlers();\n\n this._controlBar = null;\n this._targetEl = null;\n }\n\n private _onClick = () => {\n const target = this._targetEl;\n if (!target) return;\n\n if (isFullscreen()) {\n this._exitFullscreen();\n } else {\n this._requestFullscreen(target);\n }\n };\n\n private _fullscreenAvailable() {\n return BROWSER.FULLSCREEN_REQUEST.some(key => !!document[key]);\n }\n\n private _requestFullscreen(el: HTMLElement) {\n for (const key of BROWSER.FULLSCREEN_REQUEST) {\n const request = el[key];\n if (request) {\n request.call(el);\n return;\n }\n }\n }\n\n private _exitFullscreen() {\n for (const key of BROWSER.FULLSCREEN_EXIT) {\n const exit = document[key];\n\n if (exit) {\n exit.call(document);\n return;\n }\n }\n }\n\n private _addFullscreenHandlers() {\n BROWSER.FULLSCREEN_CHANGE.forEach(evtName => {\n document.addEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _removeFullscreenHandlers() {\n BROWSER.FULLSCREEN_CHANGE.forEach(evtName => {\n document.removeEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _onFullscreenChange = () => {\n const element = this.element;\n const controlBar = this._controlBar;\n\n if (!controlBar) return;\n\n const className = controlBar.className;\n\n if (isFullscreen()) {\n element.classList.add(className.FULLSCREEN_EXIT_BUTTON);\n element.classList.remove(className.FULLSCREEN_BUTTON);\n } else {\n element.classList.add(className.FULLSCREEN_BUTTON);\n element.classList.remove(className.FULLSCREEN_EXIT_BUTTON);\n }\n };\n}\n\nexport default FullscreenButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\n\n/**\n * Show video current / total time.\n * @ko 비디오의 현재 / 총 재생시간을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VideoTime extends ControlBarItem {\n public readonly element: HTMLElement;\n private _video: TextureVideo | null;\n private _currentTime: number;\n private _duration: number;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n\n this._video = null;\n this._currentTime = 0;\n this._duration = 0;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const element = this.element;\n const className = controlBar.className;\n\n if (!video || !video.isVideo()) {\n element.classList.add(className.UNAVAILABLE);\n return;\n }\n\n element.classList.add(className.VIDEO_TIME_DISPLAY);\n element.classList.remove(className.UNAVAILABLE);\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange);\n\n this._video = video;\n this._currentTime = video.source.currentTime;\n this._duration = video.source.duration;\n\n this._updateDisplay();\n }\n\n public destroy() {\n const video = this._video;\n\n if (!video) return;\n\n this.element.className = \"\";\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange);\n\n this._video = null;\n }\n\n private _onTimeUpdate = () => {\n const video = this._video;\n if (!video) return;\n\n this._currentTime = video.source.currentTime;\n this._updateDisplay();\n };\n\n private _onDurationChange = () => {\n const video = this._video;\n if (!video) return;\n\n this._duration = video.source.duration;\n this._updateDisplay();\n };\n\n private _onCustomTimeChange = (evt: CustomEvent<{ time: number }>) => {\n this._currentTime = evt.detail.time;\n this._updateDisplay();\n };\n\n private _updateDisplay() {\n const time = this._currentTime;\n const timeMinute = Math.floor(time / 60);\n const timeSeconds = Math.floor(time - timeMinute * 60);\n const timeSecondsFormatted = timeSeconds < 10 ? `0${timeSeconds}` : timeSeconds;\n\n const duration = this._duration;\n const durationMinute = Math.floor(duration / 60);\n const durationSeconds = Math.floor(duration - durationMinute * 60);\n const durationSecondsFormatted = durationSeconds < 10 ? `0${durationSeconds}` : durationSeconds;\n\n this.element.innerText = `${timeMinute}:${timeSecondsFormatted} / ${durationMinute}:${durationSecondsFormatted}`;\n }\n}\n\nexport default VideoTime;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport { circulate, getObjectOption } from \"../../utils\";\nimport * as BROWSER from \"../../const/browser\";\nimport { EVENTS } from \"../../const/external\";\nimport { SVG_NAMESPACE } from \"../../const/internal\";\n\n/**\n * Options for {@link PieView}\n * @ko {@link PieView}용 옵션들\n * @category Plugin\n */\nexport interface PieViewOptions extends ControlBarItemOptions {\n /**\n * @copy PieView#resetCamera\n */\n resetCamera: boolean | Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n duration: number;\n easing: (x: number) => number;\n }>;\n}\n\n/**\n * Show camera direction/fov indicator.\n * @ko 카메라가 향하는 방향 및 FOV를 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass PieView extends ControlBarItem {\n public readonly element: HTMLElement;\n\n /**\n * Set rotation to reset camera to when PieView is clicked.\n * `false` will disable this value, and `true` will enable with default options.\n * @ko PieView가 클릭되었을 때 카메라를 리셋할 방향을 지정합니다.\n * `false`일 경우 이 동작을 비활성화하며, `true`일 경우 기본값을 사용합니다.\n * @since 4.0.0\n */\n public resetCamera: PieViewOptions[\"resetCamera\"];\n\n private _viewer: View360 | null;\n private _piePathEl: SVGPathElement;\n private _rangeCircleEl: SVGCircleElement;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n resetCamera = true,\n position = CONTROL_BAR_ITEM_POSITION.TOP_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n this.element.title = \"Reset view\";\n this.resetCamera = resetCamera;\n this._createPieElements();\n this._viewer = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n\n if (!viewer.initialized) {\n viewer.once(EVENTS.READY, this._updatePie);\n } else {\n this._updatePie({ target: viewer });\n }\n\n const rootClass = controlBar.className.PIEVIEW_ROOT;\n element.classList.add(rootClass);\n\n if (this.resetCamera) {\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n }\n\n viewer.on(EVENTS.VIEW_CHANGE, this._updatePie);\n\n this._viewer = viewer;\n }\n\n public destroy(viewer: View360) {\n const element = this.element;\n\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.className = \"\";\n viewer.off(EVENTS.READY, this._updatePie);\n viewer.off(EVENTS.VIEW_CHANGE, this._updatePie);\n\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n const resetCamera = this.resetCamera;\n\n if (!viewer || !resetCamera) return;\n\n const {\n yaw = viewer.initialYaw,\n pitch = viewer.initialPitch,\n zoom = viewer.initialZoom,\n duration = 500\n } = getObjectOption(resetCamera);\n\n viewer.camera.animateTo({\n yaw,\n pitch,\n zoom,\n duration\n });\n };\n\n private _createPieElements() {\n const root = this.element;\n const pieSVG = document.createElementNS(SVG_NAMESPACE, \"svg\");\n pieSVG.setAttribute(\"viewBox\", \"0 0 48 48\");\n pieSVG.setAttribute(\"width\", \"100%\");\n pieSVG.setAttribute(\"height\", \"100%\");\n\n const piePath = document.createElementNS(SVG_NAMESPACE, \"circle\");\n\n piePath.setAttribute(\"stroke\", \"currentColor\");\n piePath.setAttribute(\"fill\", \"transparent\");\n piePath.setAttribute(\"cx\", \"24\");\n piePath.setAttribute(\"cy\", \"24\");\n piePath.setAttribute(\"r\", \"12\");\n piePath.setAttribute(\"stroke-width\", \"24\");\n pieSVG.appendChild(piePath);\n\n const rangeCircle = document.createElementNS(SVG_NAMESPACE, \"circle\");\n\n rangeCircle.setAttribute(\"stroke\", \"currentColor\");\n rangeCircle.setAttribute(\"fill\", \"transparent\");\n rangeCircle.setAttribute(\"cx\", \"24\");\n rangeCircle.setAttribute(\"cy\", \"24\");\n rangeCircle.setAttribute(\"r\", \"22.5\");\n rangeCircle.setAttribute(\"stroke-width\", \"3\");\n pieSVG.appendChild(rangeCircle);\n\n root.appendChild(pieSVG);\n\n this._piePathEl = piePath;\n this._rangeCircleEl = rangeCircle;\n }\n\n private _updatePie = ({ target: viewer }: { target: View360 }) => {\n const piePath = this._piePathEl;\n const rangeCircle = this._rangeCircleEl;\n const camera = viewer.camera;\n const fov = camera.getHorizontalFov();\n const yawRange = camera.getYawRange(camera.zoom);\n const halfFov = fov * 0.5;\n\n const pieRadius = 24 * Math.PI;\n const pieDeg = pieRadius * fov / 360;\n const pieOffset = pieRadius * (camera.yaw + halfFov + 90) / 360;\n\n piePath.setAttribute(\"stroke-dasharray\", `${pieDeg} ${pieRadius - pieDeg}`);\n piePath.setAttribute(\"stroke-dashoffset\", `${pieOffset}`);\n\n if (isFinite(yawRange.min) && isFinite(yawRange.max)) {\n const radius = 45 * Math.PI; // 2 * PI * r\n const min = (circulate(yawRange.min, -180, 180) - halfFov) / 360;\n const max = (circulate(yawRange.max, -180, 180) + halfFov) / 360;\n\n const rangeDiff = radius * Math.abs(max - min);\n const offset = -radius * (min - 0.25);\n\n rangeCircle.setAttribute(\"stroke-dasharray\", `${rangeDiff} ${radius - rangeDiff}`);\n rangeCircle.setAttribute(\"stroke-dashoffset\", `${offset}`);\n } else {\n rangeCircle.setAttribute(\"stroke-dasharray\", \"\");\n rangeCircle.setAttribute(\"stroke-dashoffset\", \"\");\n }\n };\n}\n\nexport default PieView;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show VR enter button.\n * @ko VR 진입 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VRButton extends ControlBarItem {\n public readonly element: HTMLElement;\n\n private _viewer: View360 | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n this.element.title = \"Enter VR\";\n this._viewer = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n element.classList.add(className.UNAVAILABLE);\n element.classList.add(className.VR_BUTTON);\n element.classList.add(className.CONTROLS_BUTTON);\n\n viewer.vr.isAvailable()\n .then(available => {\n if (available) {\n element.classList.remove(className.UNAVAILABLE);\n }\n });\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._viewer = viewer;\n }\n\n public destroy() {\n const element = this.element;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n if (!viewer) return;\n\n viewer.vr.enter();\n };\n}\n\nexport default VRButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport GyroControl from \"../../control/GyroControl\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { sensorCanBeEnabledIOS } from \"../../utils\";\n\n/**\n * Show gyroscope control enable / disable button\n * @ko 자이로스코프 컨트롤 활성화 / 비활성화 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass GyroButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _viewer: View360 | null;\n private _controlBar: ControlBar | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n this.element.title = \"Toggle gyroscope control\";\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.add(className.UNAVAILABLE);\n\n const enableButton = () => {\n element.classList.remove(className.UNAVAILABLE);\n viewer.control.gyro.on(CONTROL_EVENTS.ENABLE, this._updateStyle);\n viewer.control.gyro.on(CONTROL_EVENTS.DISABLE, this._updateStyle);\n };\n\n if (sensorCanBeEnabledIOS()) {\n enableButton();\n } else {\n GyroControl.isAvailable().then(available => {\n if (!available) return;\n enableButton();\n });\n }\n\n this._controlBar = controlBar;\n this._viewer = viewer;\n this._updateStyle();\n }\n\n public destroy(viewer: View360) {\n const element = this.element;\n\n viewer.control.gyro.off(CONTROL_EVENTS.ENABLE, this._updateStyle);\n viewer.control.gyro.off(CONTROL_EVENTS.DISABLE, this._updateStyle);\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.className = \"\";\n\n this._controlBar = null;\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n const controlBar = this._controlBar;\n\n if (!viewer || !controlBar) return;\n\n const gyroControl = viewer.control.gyro;\n if (gyroControl.enabled) {\n gyroControl.disable();\n } else {\n GyroControl.requestSensorPermission().then(available => {\n if (available) {\n gyroControl.enable();\n } else {\n this.element.classList.add(controlBar.className.UNAVAILABLE);\n }\n });\n }\n };\n\n private _updateStyle = () => {\n const element = this.element;\n const viewer = this._viewer;\n const controlBar = this._controlBar;\n\n if (!viewer || !controlBar) return;\n\n const gyroControl = viewer.control.gyro;\n const className = controlBar.className;\n\n if (gyroControl.enabled) {\n element.classList.add(className.GYRO_ENABLED);\n element.classList.remove(className.GYRO_DISABLED);\n } else {\n element.classList.add(className.GYRO_DISABLED);\n element.classList.remove(className.GYRO_ENABLED);\n }\n };\n}\n\nexport default GyroButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport { FULLSCREEN_CHANGE } from \"../../const/browser\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport { isFullscreen } from \"../../utils\";\n\n/**\n * Options for ControlBar's {@link ControlBarOptions#autoHide}\n * @ko ControlBar의 {@link ControlBarOptions#autoHide}용 옵션\n * @category Plugin\n * @since 4.0.0\n */\nexport interface AutoHideOptions {\n /**\n * Initial delay before the control bar hides (ms)\n * @ko 컨트롤바가 처음으로 표시되고 사라지기까지 걸리는 시간 (ms)\n * @default 3000\n * @since 4.0.0\n */\n initialDelay: number;\n /**\n * Delay time before hiding the control bar after mouse leave (ms)\n * @ko 마우스가 컨트롤바 영역을 떠난 뒤 컨트롤바가 사라지기까지 걸리는 시간 (ms)\n * @default 0\n * @since 4.0.0\n */\n delay: number;\n /**\n * Delay time before hiding the control bar becomes active, like touch on mobile device or mouse move in fullscreen mode (ms)\n * @ko 모바일이나 풀스크린 환경 등에서 사용자 입력이 없을 때 컨트롤바가 사라지기까지 걸리는 시간 (ms)\n * @default 3000\n * @since 4.0.0\n */\n idleDelay: number;\n}\n\nclass AutoHide {\n private _initialDelay: AutoHideOptions[\"initialDelay\"];\n private _delay: AutoHideOptions[\"delay\"];\n private _idleDelay: AutoHideOptions[\"idleDelay\"];\n\n private _controlBar: ControlBar;\n private _timer: number;\n private _isGrabbing: boolean;\n private _isCursorInside: boolean;\n private _isFullscreen: boolean;\n private _targetEl: HTMLElement | null;\n private _video: TextureVideo | null;\n\n public get enabled() { return !!this._targetEl; }\n public get hidden() { return this._controlBar.containerEl.classList.contains(this._hiddenClass); }\n\n private get _hiddenClass() { return this._controlBar.className.HIDDEN; }\n private get _fixedClass() { return this._controlBar.className.FIXED; }\n\n public constructor(controlBar: ControlBar, {\n initialDelay = 3000,\n delay = 0,\n idleDelay: activationDelay = 3000\n }: Partial) {\n this._controlBar = controlBar;\n this._initialDelay = initialDelay;\n this._delay = delay;\n this._idleDelay = activationDelay;\n this._timer = -1;\n this._isCursorInside = false;\n this._isGrabbing = false;\n this._isFullscreen = false;\n this._video = null;\n this._targetEl = null;\n }\n\n public enable(viewer: View360) {\n if (this._targetEl) {\n this.disable(viewer);\n }\n\n const initialDelay = this._initialDelay;\n const root = viewer.rootEl;\n\n this._targetEl = viewer.rootEl;\n this._timer = window.setTimeout(() => {\n this.hide();\n }, initialDelay);\n\n root.addEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onHold);\n root.addEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter);\n root.addEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove);\n root.addEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave);\n this._addFullscreenHandlers();\n\n const video = viewer.projection?.getTexture();\n if (!video || !video.isVideo()) {\n return;\n }\n\n if (video.isPaused()) {\n this._controlBar.containerEl.classList.add(this._fixedClass);\n }\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onVideoPlay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onVideoPause);\n\n this._video = video;\n }\n\n public disable(viewer: View360) {\n if (!this._targetEl) return;\n\n const controlBar = this._controlBar;\n const root = viewer.rootEl;\n const video = this._video;\n\n root.removeEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onHold);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave);\n this._removeFullscreenHandlers();\n\n window.clearTimeout(this._timer);\n controlBar.containerEl.classList.remove(this._fixedClass);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onVideoPlay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onVideoPause);\n }\n\n this._isCursorInside = false;\n this._isGrabbing = false;\n this._video = null;\n this._targetEl = null;\n }\n\n public show() {\n this._clearHideTimer();\n this._controlBar.containerEl.classList.remove(this._hiddenClass);\n }\n\n public showTemporaliy() {\n this.show();\n this._hideAfterDelay(this._idleDelay);\n }\n\n public hide() {\n this._clearHideTimer();\n this._controlBar.containerEl.classList.add(this._hiddenClass);\n }\n\n private _clearHideTimer() {\n if (this._timer) {\n window.clearTimeout(this._timer);\n this._timer = -1;\n }\n }\n\n private _hideAfterDelay(delay = this._delay) {\n if (this._isGrabbing || (!this._isFullscreen && this._isCursorInside)) return;\n\n this._clearHideTimer();\n if (delay <= 0) {\n this.hide();\n } else {\n this._timer = window.setTimeout(() => {\n this.hide();\n }, delay);\n }\n }\n\n private _onMouseEnter = () => {\n this._isCursorInside = true;\n this.show();\n };\n\n private _onMouseLeave = () => {\n this._isCursorInside = false;\n this._hideAfterDelay();\n };\n\n private _onMouseMove = () => {\n if (!this._isFullscreen) return;\n\n this.showTemporaliy();\n }\n\n private _onHold = (evt: PointerEvent) => {\n this._isGrabbing = true;\n\n if (evt.pointerType === \"mouse\") {\n this._isCursorInside = true;\n }\n\n window.addEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n\n this.show();\n };\n\n private _onRelease = () => {\n this._isGrabbing = false;\n\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n\n this._hideAfterDelay();\n };\n\n private _onVideoPlay = () => {\n const root = this._targetEl;\n if (!root) return;\n\n this._controlBar.containerEl.classList.remove(this._fixedClass);\n };\n\n private _onVideoPause = () => {\n const root = this._targetEl;\n if (!root) return;\n\n this._controlBar.containerEl.classList.add(this._fixedClass);\n };\n\n private _addFullscreenHandlers() {\n FULLSCREEN_CHANGE.forEach(evtName => {\n document.addEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _removeFullscreenHandlers() {\n FULLSCREEN_CHANGE.forEach(evtName => {\n document.removeEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _onFullscreenChange = () => {\n this._isFullscreen = isFullscreen();\n\n if (this._isFullscreen) {\n this._hideAfterDelay();\n }\n };\n}\n\nexport default AutoHide;\n","import TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { clamp } from \"../../utils\";\nimport { VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\n\nclass VideoControl {\n private _video: TextureVideo | null;\n\n public enable(root: HTMLElement, video: TextureVideo) {\n this._video = video;\n // capture is needed for resolving conflict with keyboard control\n root.addEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown, true);\n }\n\n public disable(root: HTMLElement) {\n this._video = null;\n root.removeEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown, true);\n }\n\n private _onKeyDown = (event: KeyboardEvent) => {\n const video = this._video;\n if (!video) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n const videoEl = video.source;\n const keyPressed = event.keyCode != null\n ? BROWSER.DIRECTION_KEY_CODE[event.keyCode]\n : BROWSER.DIRECTION_KEY_NAME[event.key];\n\n switch (keyPressed) {\n case \"LEFT\":\n case \"RIGHT\":\n return this._changeVideoTime(videoEl, keyPressed === \"RIGHT\");\n case \"UP\":\n case \"DOWN\":\n return this._changeVideoVolume(videoEl, keyPressed === \"UP\");\n }\n\n const spacePressed = event.keyCode === BROWSER.SPACE_KEY_CODE || event.key === BROWSER.SPACE_KEY_NAME;\n if (spacePressed) {\n this._toggleVideo(video);\n }\n }\n\n private _changeVideoTime(video: HTMLVideoElement, forward: boolean) {\n const delta = forward ? 5 : -5;\n\n video.currentTime += delta;\n video.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time: video.currentTime }}));\n }\n\n private _changeVideoVolume(video: HTMLVideoElement, increase: boolean) {\n const delta = increase ? 0.1 : -0.1;\n\n if (video.muted) {\n video.volume = clamp(delta, 0, 1);\n } else {\n video.volume = clamp(video.volume + delta, 0, 1);\n }\n\n if (video.volume > 0) {\n video.muted = false;\n } else {\n video.muted = true;\n }\n }\n\n private _toggleVideo(video: TextureVideo) {\n if (video.isPaused()) {\n video.source.play();\n } else {\n video.source.pause();\n }\n }\n}\n\nexport default VideoControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport ProgressBar from \"./ProgressBar\";\nimport PlayButton from \"./PlayButton\";\nimport VolumeControl from \"./VolumeControl\";\nimport FullscreenButton from \"./FullscreenButton\";\nimport VideoTime from \"./VideoTime\";\nimport PieView, { PieViewOptions } from \"./PieView\";\nimport VRButton from \"./VRButton\";\nimport GyroButton from \"./GyroButton\";\nimport AutoHide, { AutoHideOptions } from \"./AutoHide\";\nimport VideoControl from \"./VideoControl\";\nimport View360, { View360Events } from \"../../View360\";\nimport View360Plugin from \"../View360Plugin\";\nimport { EVENTS } from \"../../const/external\";\nimport { createElement, findIndex, getObjectOption } from \"../../utils\";\nimport { ValueOf } from \"../../type/utils\";\nimport { StaticClickEvent } from \"../../type/events\";\nimport { CONTROL_BAR_DEFAULT_CLASS, CONTROL_BAR_ITEM_POSITION } from \"./const\";\n\n/**\n * Options for {@link ControlBar}\n * @ko {@link ControlBar}용 옵션들\n * @category Plugin\n * @since 4.0.0\n */\nexport interface ControlBarOptions {\n /**\n * @copy ControlBar#autoHide\n */\n autoHide: boolean | Partial;\n /**\n * @copy ControlBar#showBackground\n */\n showBackground: boolean;\n /**\n * @copy ControlBar#clickToPlay\n */\n clickToPlay: boolean;\n /**\n * @copy ControlBar#keyboardControls\n */\n keyboardControls: boolean;\n /**\n * @copy ControlBar#progressBar\n */\n progressBar: boolean | Partial;\n /**\n * @copy ControlBar#playButton\n */\n playButton: boolean | Partial;\n /**\n * @copy ControlBar#volumeButton\n */\n volumeButton: boolean | Partial;\n /**\n * @copy ControlBar#fullscreenButton\n */\n fullscreenButton: boolean | Partial;\n /**\n * @copy ControlBar#videoTime\n */\n videoTime: boolean | Partial;\n /**\n * @copy ControlBar#pieView\n */\n pieView: boolean | Partial;\n /**\n * @copy ControlBar#vrButton\n */\n vrButton: boolean | Partial;\n /**\n * @copy ControlBar#gyroButton\n */\n gyroButton: boolean | Partial;\n /**\n * @copy ControlBar#className\n */\n className: Partial<{ -readonly [key in keyof typeof ControlBar.DEFAULT_CLASS]: string }>;\n /**\n * @copy ControlBar#customItems\n */\n customItems: ControlBarItem[];\n}\n\n/**\n * A plugin that displays extra buttons & controls that controls {@link View360}.\n * @ko {@link View360}에 부가적인 버튼과 컨트롤을 추가해주는 플러그인.\n * @category Plugin\n * @since 4.0.0\n */\nclass ControlBar implements View360Plugin {\n /**\n * Default class names that ControlBar uses\n * @ko ControlBar가 사용하는 디폴트 클래스 이름들\n * @since 4.0.0\n */\n public static readonly DEFAULT_CLASS = CONTROL_BAR_DEFAULT_CLASS;\n\n /**\n * Constants for {@link ControlBarItemOptions#position}\n * @ko {@link ControlBarItemOptions#position}에 사용 가능한 값들\n */\n public static readonly POSITION = CONTROL_BAR_ITEM_POSITION;\n\n /**\n * Automatically hide control bar on video plays.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 재생시 자동으로 컨트롤바를 숨깁니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly autoHide?: ControlBarOptions[\"autoHide\"];\n /**\n * Show background element.\n * @ko 배경 엘리먼트를 표시합니다.\n * @since 4.0.0\n */\n public readonly showBackground?: ControlBarOptions[\"showBackground\"];\n /**\n * Whether to play / pause video on canvas click\n * @ko 캔버스 클릭시에 비디오를 재생 / 일시정지 토글합니다.\n * @since 4.0.0\n */\n public readonly clickToPlay: ControlBarOptions[\"clickToPlay\"];\n /**\n * Enable keyboard controls for video.\n * Pressing up / down arrow will control video volume, and pressing left / right arrow will control video time.\n * @ko 비디오 키보드 컨트롤을 활성화합니다.\n * 위 / 아래 화살표키를 누를 시 비디오 볼륨을, 왼쪽 / 오른쪽 화살표키를 누를 시 비디오 시간을 조정합니다.\n * @since 4.0.0\n */\n public readonly keyboardControls: ControlBarOptions[\"keyboardControls\"];\n /**\n * Show video progress bar.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 프로그레스 바를 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly progressBar: ControlBarOptions[\"progressBar\"];\n /**\n * Show video play / pause button.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 재생 / 일시정지 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly playButton: ControlBarOptions[\"playButton\"];\n /**\n * Show video volume control button.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 볼륨 조절 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly volumeButton: ControlBarOptions[\"volumeButton\"];\n /**\n * Show fullscreen button.\n * `true` to enable with default values, `false` to disable.\n * @ko 풀스크린 진입 / 해제 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly fullscreenButton: ControlBarOptions[\"fullscreenButton\"];\n /**\n * Show video current / total time\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오의 현재 시간 / 총 시간을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly videoTime: ControlBarOptions[\"videoTime\"];\n /**\n * Show camera pie view.\n * `true` to enable with default values, `false` to disable.\n * @ko 현재 카메라가 가리키는 방향을 표시하는 파이 뷰를 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly pieView: ControlBarOptions[\"pieView\"];\n /**\n * Show VR button.\n * `true` to enable with default values, `false` to disable.\n * @ko VR 진입버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly vrButton: ControlBarOptions[\"vrButton\"];\n /**\n * Show gyroscope control enable / disable button.\n * `true` to enable with default values, `false` to disable.\n * @ko 자이로스코프 컨트롤을 활성화 / 비활성화하는 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly gyroButton: ControlBarOptions[\"gyroButton\"];\n /**\n * Override default class names.\n * @ko 디폴트 클래스 이름들을 오버라이드합니다.\n * @since 4.0.0\n */\n public readonly className: Required;\n\n /**\n * Root element of the control bar\n * @ko 컨트롤바의 루트 엘리먼트\n * @since 4.0.0\n */\n public get rootEl() { return this._rootEl; }\n /**\n * Container element of the control bar\n * @ko 컨트롤바의 컨테이너 엘리먼트\n * @since 4.0.0\n */\n public get containerEl() { return this._containerEl; }\n /**\n * Background element of the control bar\n * @ko 컨트롤바의 배경 엘리먼트\n * @since 4.0.0\n */\n public get backgroundEl() { return this._bgEl; }\n /**\n * Control bar's default items created by {@link ControlBarOptions}\n * @ko 주어진 {@link ControlBarOptions}에 의해 생성된 디폴트 아이템들\n * @since 4.0.0\n */\n public get items() { return this._items; }\n /**\n * Custom control bar items\n * @ko 커스텀 컨트롤바 아이템들을 추가합니다.\n * @since 4.0.0\n */\n public get customItems() { return this._customItems; }\n\n private _rootEl: HTMLElement;\n private _containerEl: HTMLElement;\n private _bgEl: HTMLElement;\n private _wrapperEl: Record, HTMLElement>;\n private _items: Record, ControlBarItem[]>;\n private _customItems: ControlBarItem[];\n private _autoHider: AutoHide;\n private _videoControl: VideoControl;\n\n /**\n * Create new instance of ControlBar.\n * @ko ControlBar의 새 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n autoHide,\n showBackground,\n clickToPlay = true,\n keyboardControls = true,\n progressBar = true,\n playButton = true,\n volumeButton = true,\n fullscreenButton = true,\n videoTime = true,\n pieView = true,\n vrButton = true,\n gyroButton = true,\n className = {},\n customItems = []\n }: Partial = {}) {\n this.autoHide = autoHide;\n this.showBackground = showBackground;\n this.clickToPlay = clickToPlay;\n this.keyboardControls = keyboardControls;\n this.progressBar = progressBar;\n this.playButton = playButton;\n this.volumeButton = volumeButton;\n this.fullscreenButton = fullscreenButton;\n this.videoTime = videoTime;\n this.pieView = pieView;\n this.vrButton = vrButton;\n this.gyroButton = gyroButton;\n this.className = {\n ...ControlBar.DEFAULT_CLASS,\n ...className\n };\n\n const rootClass = className.CONTROLS_ROOT ?? ControlBar.DEFAULT_CLASS.CONTROLS_ROOT;\n\n this._rootEl = createElement(rootClass);\n this._createPositionWrappers();\n this._items = Object.keys(ControlBar.POSITION).reduce((items, key) => {\n items[ControlBar.POSITION[key]] = [];\n return items;\n }, {}) as Record, ControlBarItem[]>;\n this._customItems = customItems;\n this._autoHider = new AutoHide(this, getObjectOption(autoHide));\n this._videoControl = new VideoControl();\n\n customItems.forEach(item => {\n this._items[item.position].push(item);\n });\n }\n\n public init(viewer: View360) {\n const panoRoot = viewer.rootEl;\n const controlsRoot = this._rootEl;\n const defaultItems = this._createDefaultItems();\n\n this._updateBackground(viewer);\n this._updateAutoHide(viewer);\n this._updateKeyboardHandler(viewer);\n\n panoRoot.appendChild(controlsRoot);\n this._addItem(viewer, defaultItems);\n this._addItem(viewer, this._customItems);\n\n viewer.on(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad);\n viewer.on(EVENTS.STATIC_CLICK, this._onStaticClick);\n }\n\n public destroy(viewer: View360): void {\n // Remove controls root from pano root\n const panoRoot = viewer.rootEl;\n const controlsRoot = this._rootEl;\n const items = this._items;\n\n if (controlsRoot.parentElement === panoRoot) {\n panoRoot.removeChild(controlsRoot);\n }\n\n Object.keys(items).forEach((key: ValueOf) => {\n const category = items[key];\n\n category.forEach(item => {\n item.destroy(viewer, this);\n });\n\n items[key] = [];\n });\n\n this._clearItemElements();\n this._autoHider.disable(viewer);\n this._videoControl.disable(panoRoot);\n\n viewer.off(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad);\n viewer.off(EVENTS.STATIC_CLICK, this._onStaticClick);\n }\n\n private _addItem(viewer: View360, items: ControlBarItem[]) {\n for (const item of items) {\n const category = this._items[item.position];\n const wrapper = this._wrapperEl[item.position];\n\n const nextSiblingIndex = findIndex(category, sibling => sibling.order > item.order);\n\n if (nextSiblingIndex >= 0) {\n const nextSibling = category[nextSiblingIndex].element;\n category.splice(nextSiblingIndex, 0, item);\n wrapper.insertBefore(item.element, nextSibling);\n } else {\n category.push(item);\n wrapper.appendChild(item.element);\n }\n\n item.init(viewer, this);\n }\n }\n\n private _createPositionWrappers() {\n const className = {\n ...ControlBar.DEFAULT_CLASS,\n ...this.className\n };\n const rootEl = this._rootEl;\n\n // BG & FLOATING CONTROLS\n const backgroundEl = createElement(className.CONTROLS_BG);\n const floatLeftEl = createElement(className.CONTROLS_FLOAT_LEFT);\n const floatRightEl = createElement(className.CONTROLS_FLOAT_RIGHT);\n\n rootEl.appendChild(floatLeftEl);\n rootEl.appendChild(floatRightEl);\n\n // BOTTOM CONTROLS\n const container = createElement(className.CONTROLS_MAIN);\n const topWrapper = createElement(className.CONTROLS_TOP);\n const bottomWrapper = createElement(className.CONTROLS_BOTTOM);\n const midWrapper = createElement(className.CONTROLS_MID);\n const leftControlsWrapper = createElement(className.CONTROLS_LEFT);\n const rightControlsWrapper = createElement(className.CONTROLS_RIGHT);\n\n midWrapper.appendChild(leftControlsWrapper);\n midWrapper.appendChild(rightControlsWrapper);\n container.appendChild(backgroundEl);\n container.appendChild(topWrapper);\n container.appendChild(midWrapper);\n container.appendChild(bottomWrapper);\n rootEl.appendChild(container);\n\n this._bgEl = backgroundEl;\n this._containerEl = container;\n this._wrapperEl = {\n [ControlBar.POSITION.MAIN_TOP]: topWrapper,\n [ControlBar.POSITION.MAIN_LEFT]: leftControlsWrapper,\n [ControlBar.POSITION.MAIN_RIGHT]: rightControlsWrapper,\n [ControlBar.POSITION.MAIN_BOTTOM]: bottomWrapper,\n [ControlBar.POSITION.TOP_LEFT]: floatLeftEl,\n [ControlBar.POSITION.TOP_RIGHT]: floatRightEl\n };\n }\n\n private _clearItemElements() {\n const wrappers = Object.keys(ControlBar.POSITION).map(key => ControlBar.POSITION[key]);\n\n // Remove all elements inside wrappers\n wrappers.forEach(wrapper => {\n while (wrapper.firstChild) {\n wrapper.removeChild(wrapper.firstChild);\n }\n });\n }\n\n private _onStaticClick = ({ target: viewer, isTouch }: StaticClickEvent) => {\n const autoHider = this._autoHider;\n\n if (isTouch) {\n if (!autoHider.enabled) return;\n\n if (autoHider.hidden) {\n autoHider.showTemporaliy();\n } else {\n autoHider.hide();\n }\n } else {\n if (!this.clickToPlay) return;\n\n const video = viewer.projection?.getTexture();\n if (!video || !video.isVideo()) return;\n\n if (video.isPaused()) {\n video.source.play();\n } else {\n video.source.pause();\n }\n }\n };\n\n private _onNewSrcLoad = ({ target: viewer }: View360Events[\"projectionChange\"]) => {\n const items = this._items;\n\n this._updateBackground(viewer);\n this._updateAutoHide(viewer);\n this._updateKeyboardHandler(viewer);\n\n Object.keys(items).forEach((key: ValueOf) => {\n const category = items[key];\n\n category.forEach(item => {\n item.destroy(viewer, this);\n item.init(viewer, this);\n });\n });\n };\n\n private _updateAutoHide(viewer: View360) {\n const autoHide = this.autoHide;\n const autoHider = this._autoHider;\n\n if (autoHide != null) {\n if (autoHide) {\n autoHider.enable(viewer);\n } else {\n autoHider.disable(viewer);\n }\n } else {\n // Automatically choose whether to show background by content type\n const texture = viewer.projection?.getTexture();\n\n if (texture && texture.isVideo()) {\n // Enable auto hide when content type is video\n autoHider.enable(viewer);\n } else {\n autoHider.disable(viewer);\n }\n }\n }\n\n private _updateBackground(viewer: View360) {\n const background = this._bgEl;\n const showBackground = this.showBackground;\n const hiddenClass = this.className.HIDDEN ?? ControlBar.DEFAULT_CLASS.HIDDEN;\n\n if (showBackground != null) {\n if (showBackground) {\n background.classList.remove(hiddenClass);\n } else {\n background.classList.add(hiddenClass);\n }\n } else {\n // Automatically choose whether to show background by content type\n const texture = viewer.projection?.getTexture();\n\n if (texture && texture.isVideo()) {\n // Show bg when content type is video\n background.classList.remove(hiddenClass);\n } else {\n background.classList.add(hiddenClass);\n }\n }\n }\n\n private _updateKeyboardHandler(viewer: View360) {\n const panoRoot = viewer.rootEl;\n const videoControl = this._videoControl;\n const texture = viewer.projection?.getTexture();\n\n if (this.keyboardControls && texture && texture.isVideo()) {\n videoControl.enable(panoRoot, texture);\n } else {\n videoControl.disable(panoRoot);\n }\n }\n\n private _createDefaultItems(): ControlBarItem[] {\n const items: ControlBarItem[] = [];\n\n if (this.progressBar) {\n items.push(new ProgressBar(getObjectOption(this.progressBar)));\n }\n\n if (this.playButton) {\n items.push(new PlayButton(getObjectOption(this.playButton)));\n }\n\n if (this.volumeButton) {\n items.push(new VolumeControl(getObjectOption(this.volumeButton)));\n }\n\n if (this.gyroButton) {\n items.push(new GyroButton(getObjectOption(this.gyroButton)));\n }\n\n if (this.vrButton) {\n items.push(new VRButton(getObjectOption(this.vrButton)));\n }\n\n if (this.fullscreenButton) {\n items.push(new FullscreenButton(getObjectOption(this.fullscreenButton)));\n }\n\n if (this.videoTime) {\n items.push(new VideoTime(getObjectOption(this.videoTime)));\n }\n\n if (this.pieView) {\n items.push(new PieView(getObjectOption(this.pieView)));\n }\n\n return items;\n }\n}\n\nexport default ControlBar;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Camera from \"../core/Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport Texture from \"../texture/Texture\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport { VideoConfig } from \"../type/external\";\nimport UniformCanvasCube from \"../uniform/UniformCanvasCube\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport UniformTextureCube from \"../uniform/UniformTextureCube\";\n\ntype CommonProjectionUniforms = {\n uTexture: UniformTexture2D | UniformTextureCube | UniformCanvasCube;\n}\n\n/**\n * Common option for {@link Projection}s\n * @ko {@link Projection}을 위한 공통 옵션들\n * @category Projection\n * @since 4.0.0\n */\nexport interface ProjectionOptions {\n /**\n * @copy Projection#src\n */\n src: string | HTMLElement | Array;\n /**\n * @copy Projection#video\n */\n video?: boolean | Partial;\n}\n\n/**\n * Base class for projections.\n * @ko 프로젝션 베이스 클래스.\n * @category Projection\n * @since 4.0.0\n */\nabstract class Projection {\n /**\n * Source URL to panorama image/video.\n * @ko 파노라마 이미지/비디오의 URL\n * @since 4.0.0\n */\n public readonly src: ProjectionOptions[\"src\"];\n /**\n * Properties for the video element.\n * Setting `false` will treat panorama source as an image, `true` will use default properties.\n * @ko 비디오 엘리먼트에 설정할 프로퍼티를 담는 객체.\n * @since 4.0.0\n * @example\n * Default properties\n * ```ts\n * autoplay: true\n * muted: true\n * loop: false\n * volume: 1\n * ```\n */\n public readonly video: ProjectionOptions[\"video\"];\n\n protected _mesh: TriangleMesh | null;\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n src,\n video = false\n }: ProjectionOptions) {\n this.src = src;\n this.video = video;\n this._mesh = null;\n }\n\n /**\n * Apply texture to current projection.\n * @ko 주어진 텍스쳐를 현재 프로젝션에 적용합니다.\n * @param ctx - Instance of the WebGLContext helper {@ko WebGL context 헬퍼의 인스턴스}\n * @param texture - New texture to apply {@ko 새로 적용할 텍스쳐}\n * @internal\n * @since 4.0.0\n */\n public abstract applyTexture(ctx: WebGLContext, texture: Texture): void;\n\n /**\n * Release all resources projection has.\n * This is automatically called on projection change & View360's destroy call\n * @ko 현재 갖고 있는 모든 리소스를 반환합니다.\n * 이 메소드는 프로젝션 변경 및 View360의 destroy 호출 시 자동으로 호출됩니다.\n * @param ctx\n */\n public releaseAllResources(ctx: WebGLContext) {\n this._mesh?.destroy(ctx);\n }\n\n /**\n * Update camera to match projection's settings.\n * @ko 현재 프로젝션의 세팅으로 카메라를 업데이트합니다.\n * @param camera - Instance of the camera to update {@ko 업데이트할 카메라의 인스턴스}\n * @since 4.0.0\n */\n public updateCamera(camera: Camera) {\n // Use default mode & no view restriction\n camera.resetRange();\n }\n\n /**\n * Update control to match projection's settings.\n * @ko 현재 프로젝션의 세팅으로 컨트롤을 업데이트합니다.\n * @param control - Instance of the control to update {@ko 업데이트할 컨트롤의 인스턴스}\n * @since 4.0.0\n */\n public updateControl(control: PanoControl) {\n control.ignoreZoomScale = false;\n }\n\n /**\n * Update projection.\n * @ko 현재 프로젝션 정보를 갱신합니다.\n * @param camera - Instance of the camera to reference {@ko 참조할 카메라의 인스턴스}\n * @since 4.0.0\n */\n public update(camera: Camera) {} // eslint-disable-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars\n\n /**\n * Return active texture.\n * @ko 현재 활성화된 텍스쳐를 반환합니다.\n * @internal\n * @since 4.0.0\n */\n public getTexture() {\n if (!this._mesh) return null;\n\n return this._mesh.program.uniforms.uTexture.texture;\n }\n\n /**\n * A 3D triangle mesh for projection. It's `null` until loading the `src`.\n * @ko Projection을 표시하기 위한 Mesh, src를 로드하기 전까지는 `null`입니다.\n * @since 4.0.0\n */\n public getMesh(): TriangleMesh | null {\n return this._mesh;\n }\n}\n\nexport default Projection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nabstract class Uniform {\n public needsUpdate: boolean;\n\n public constructor() {\n this.needsUpdate = true;\n }\n\n public abstract update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean): void;\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext) {\n // DO_NOTHING\n }\n}\n\nexport default Uniform;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport TextureCube from \"../texture/TextureCube\";\nimport { reorderCube } from \"../utils\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformTextureCube extends Uniform {\n public readonly texture: TextureCube;\n private _webglTexture: WebGLTexture;\n private _cubemapOrder: string;\n\n public constructor(ctx: WebGLContext, texture: TextureCube, cubemapOrder: string) {\n super();\n\n this.texture = texture;\n this._webglTexture = ctx.createWebGLCubeTexture(texture, texture.width);\n this._cubemapOrder = cubemapOrder;\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext): void {\n this.texture.destroy();\n gl.deleteTexture(this._webglTexture);\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture);\n\n const sources = reorderCube(texture.sources, this._cubemapOrder);\n sources.forEach((src, idx) => {\n if (isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src);\n } else {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src);\n }\n });\n\n if (!texture.isVideo()) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformTextureCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"../texture/Texture2D\";\nimport { range, reorderCube } from \"../utils\";\n\n/** @hidden */\nclass CubeTexturePainter {\n public readonly texture: Texture2D;\n private _renderingOrder: number[];\n private _canvas: HTMLCanvasElement;\n private _ctx: CanvasRenderingContext2D;\n private _row: number;\n private _column: number;\n private _size: number;\n\n public get size() { return this._size; }\n\n public constructor(texture: Texture2D, cubemapOrder: string) {\n this.texture = texture;\n this._renderingOrder = reorderCube(range(6), cubemapOrder);\n\n const canvas = document.createElement(\"canvas\");\n\n this._calcRenderingSize();\n\n canvas.width = this._size;\n canvas.height = this._size;\n\n this._canvas = canvas;\n this._ctx = canvas.getContext(\"2d\")!;\n }\n\n public destroy() {\n const canvas = this._canvas;\n\n // release memories\n canvas.width = 1;\n canvas.height = 1;\n this._canvas = null as any;\n }\n\n public draw(gl: WebGLRenderingContext | WebGL2RenderingContext, isWebGL2: boolean) {\n const size = this._size;\n const texture = this.texture;\n let surfaceIdx = 0;\n\n for (let row = 0; row < this._row; row++) {\n for (let column = 0; column < this._column; column++) {\n const x = size * column;\n const y = size * row;\n const renderingFace = this._renderingOrder[surfaceIdx];\n\n this._ctx.drawImage(texture.source as CanvasImageSource, x, y, size, size, 0, 0, size, size);\n\n if (isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas);\n } else {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas);\n }\n\n surfaceIdx++;\n }\n }\n }\n\n private _calcRenderingSize() {\n const {\n width,\n height\n } = this.texture;\n const aspect = width / height;\n\n if (aspect === 1 / 6) {\n this._size = width;\n this._row = 6;\n this._column = 1;\n } else if (aspect === 6) {\n this._size = height;\n this._row = 1;\n this._column = 6;\n } else if (aspect === 2 / 3) {\n this._size = width * 0.5;\n this._row = 3;\n this._column = 2;\n } else {\n this._size = width / 3;\n this._row = 2;\n this._column = 3;\n }\n }\n}\n\nexport default CubeTexturePainter;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport CubeTexturePainter from \"../core/CubeTexturePainter\";\nimport Texture2D from \"../texture/Texture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformCanvasCube extends Uniform {\n private _webglTexture: WebGLTexture;\n private _painter: CubeTexturePainter;\n\n public get texture() { return this._painter.texture; }\n\n public constructor(ctx: WebGLContext, texture: Texture2D, cubemapOrder: string) {\n super();\n\n this._painter = new CubeTexturePainter(texture as Texture2D, cubemapOrder);\n this._webglTexture = ctx.createWebGLCubeTexture(texture, this._painter.size);\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext) {\n gl.deleteTexture(this._webglTexture);\n this._painter.destroy();\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture);\n\n this._painter.draw(gl, isWebGL2);\n\n if (!texture.isVideo()) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformCanvasCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Object3D from \"./Object3D\";\nimport ShaderProgram from \"./ShaderProgram\";\nimport VertexArrayObject from \"./VertexArrayObject\";\nimport Uniform from \"../uniform/Uniform\";\nimport WebGLContext from \"./WebGLContext\";\n\n/**\n * @hidden\n */\nclass TriangleMesh = Record> extends Object3D {\n /**\n * @internal\n * Geometry data for projection\n */\n public readonly vao: VertexArrayObject;\n /**\n * @internal\n * Material(shader) data for projection\n */\n public readonly program: ShaderProgram;\n\n public constructor(vao: VertexArrayObject, program: ShaderProgram) {\n super();\n\n this.vao = vao;\n this.program = program;\n }\n\n public destroy(ctx: WebGLContext) {\n ctx.releaseVAO(this.vao);\n ctx.releaseShaderResources(this.program);\n }\n}\n\nexport default TriangleMesh;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"../uniform/Uniform\";\nimport WebGLContext from \"./WebGLContext\";\nimport { UniformLocations } from \"../type/internal\";\n\nclass ShaderProgram = Record> {\n public readonly program: WebGLProgram;\n public readonly uniforms: T;\n public readonly uniformLocations: UniformLocations;\n\n public constructor(ctx: WebGLContext, vertexShader: string, fragmentShader: string, uniforms: T) {\n this.program = ctx.createProgram(vertexShader, fragmentShader);\n this.uniforms = uniforms;\n this.uniformLocations = ctx.getUniformLocations(this.program, uniforms);\n }\n}\n\nexport default ShaderProgram;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { TypedArray } from \"../type/utils\";\n\n/**\n * @hidden\n */\nclass VertexData {\n public readonly data: T;\n public itemSize: number;\n public count: number;\n\n /** */\n public constructor(data: T, itemSize: number) {\n this.data = data;\n this.itemSize = itemSize;\n this.count = data.length / itemSize;\n }\n}\n\nexport default VertexData;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport VertexData from \"../core/VertexData\";\n\n/**\n * @hidden\n */\nabstract class Geometry {\n public readonly vertices: VertexData;\n public readonly indicies: VertexData;\n public readonly uvs: VertexData;\n\n /** */\n public constructor(vertices: number[], indicies: number[], uvs: number[]) {\n this.vertices = new VertexData(new Float32Array(vertices), 3);\n this.indicies = new VertexData(new Uint16Array(indicies), 1);\n this.uvs = new VertexData(new Float32Array(uvs), 2);\n }\n}\n\nexport default Geometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\nimport { ROTATE } from \"../const/internal\";\nimport { reorderCube } from \"../utils\";\n\n/**\n * @hidden\n */\nclass CubeGeometry extends Geometry {\n public constructor({\n order,\n rotateUV\n }: {\n order: string;\n rotateUV?: ROTATE[]\n }) {\n const vertices = [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // up\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // down\n -1, -1, 1,\n 1, -1, 1,\n 1, -1, -1,\n -1, -1, -1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n\n const indicies = [\n 0, 1, 2,\n 0, 2, 3,\n 4, 5, 6,\n 4, 6, 7,\n 8, 9, 10,\n 8, 10, 11,\n 12, 13, 14,\n 12, 14, 15,\n 16, 17, 18,\n 16, 18, 19,\n 20, 21, 22,\n 20, 22, 23\n ];\n\n const oneThird = 1 / 3;\n const coords: number[][] = [];\n\n for (let r = 1; r >= 0; r--) {\n for (let c = 0; c < 3; c++) {\n const coord = [\n c * oneThird, r * 0.5,\n (c + 1) * oneThird, r * 0.5,\n (c + 1) * oneThird, (r + 1) * 0.5,\n c * oneThird, (r + 1) * 0.5\n ];\n\n coords.push(coord);\n }\n }\n\n if (rotateUV) {\n rotateUV.forEach((degree, idx) => {\n if (degree === ROTATE.ZERO) return;\n\n const coord = coords[idx];\n let newOrder: number[];\n\n if (degree === ROTATE.CW_90) {\n newOrder = [1, 2, 3, 0];\n } else if (degree === ROTATE.CCW_90) {\n newOrder = [3, 0, 1, 2];\n } else {\n newOrder = [2, 3, 0, 1];\n }\n\n const newCoords = Array(coord.length);\n for (let uvIdx = 0; uvIdx < coord.length / 2; uvIdx++) {\n newCoords[uvIdx * 2 + 0] = coord[newOrder[uvIdx] * 2 + 0];\n newCoords[uvIdx * 2 + 1] = coord[newOrder[uvIdx] * 2 + 1];\n }\n\n coords[idx] = newCoords;\n });\n }\n\n const uvs = reorderCube(coords, order, \"BFUDRL\")\n .reduce((acc, val) => acc.concat(val), []);\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default CubeGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"../texture/Texture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformTexture2D extends Uniform {\n public readonly texture: Texture2D;\n private _webglTexture: WebGLTexture;\n\n public constructor(ctx: WebGLContext, texture: Texture2D) {\n super();\n\n this.texture = texture;\n this._webglTexture = ctx.createWebGLTexture(texture);\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext): void {\n this.texture.destroy();\n gl.deleteTexture(this._webglTexture);\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n const isVideo = texture.isVideo();\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._webglTexture);\n\n if (!isVideo && isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n } else {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n }\n\n if (!isVideo) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformTexture2D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass CylinderGeometry extends Geometry {\n public constructor(maxTheta: number) {\n const vertices: number[] = [];\n const indicies: number[] = [];\n const uvs: number[] = [];\n\n const height = 1;\n const radialSegments = 60;\n const halfHeight = height * 0.5;\n const heightSegments = [-halfHeight, halfHeight];\n const invRadialSegments = 1 / radialSegments;\n const angleConst = maxTheta * invRadialSegments;\n\n for (let yIdx = 0; yIdx < 2; yIdx++) {\n const y = heightSegments[yIdx];\n\n for (let lngIdx = 0; lngIdx <= radialSegments; lngIdx++) {\n const angle = lngIdx * angleConst + Math.PI - maxTheta * 0.5;\n const x = Math.cos(angle);\n const z = Math.sin(angle);\n const u = lngIdx * invRadialSegments;\n const v = yIdx;\n\n uvs.push(u, v);\n vertices.push(x, y, z);\n\n if (yIdx === 0 && lngIdx < radialSegments) {\n const a = lngIdx;\n const b = a + radialSegments + 1;\n\n indicies.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n }\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default CylinderGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass SphereGeometry extends Geometry {\n /** */\n public constructor() {\n // const radius = 1;\n const widthSegments = 60;\n const heightSegments = 60;\n const ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI;\n\n const uvs: number[] = [];\n const vertices: number[] = [];\n const indicies: number[] = [];\n let latIdx: number;\n let lngIdx: number;\n\n for (latIdx = 0; latIdx <= widthSegments; latIdx++) {\n const theta = (latIdx / widthSegments - 0.5) * Math.PI;\n const sinTheta = Math.sin(theta);\n const cosTheta = Math.cos(theta);\n\n for (lngIdx = 0; lngIdx <= heightSegments; lngIdx++) {\n const phi = (lngIdx / heightSegments - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN;\n const sinPhi = Math.sin(phi);\n const cosPhi = Math.cos(phi);\n const x = cosPhi * cosTheta;\n const y = sinTheta;\n const z = sinPhi * cosTheta;\n const u = lngIdx / heightSegments;\n const v = latIdx / widthSegments;\n\n uvs.push(u, v);\n vertices.push(x, y, z);\n\n if (lngIdx !== heightSegments && latIdx !== widthSegments) {\n const a = latIdx * (heightSegments + 1) + lngIdx;\n const b = a + heightSegments + 1;\n\n indicies.push(a, a + 1, b, b, a + 1, b + 1);\n }\n }\n }\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default SphereGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"./Uniform\";\n\nclass UniformFloat extends Uniform {\n public val: number;\n\n public constructor(val: number) {\n super();\n\n this.val = val;\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation) {\n gl.uniform1f(location, this.val);\n\n this.needsUpdate = false;\n }\n}\n\nexport default UniformFloat;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass PlaneGeometry extends Geometry {\n /** */\n public constructor(width: number = 2, height: number = 2, z: number = -1) {\n const halfWidth = width * 0.5;\n const halfHeight = height * 0.5;\n const vertices = [\n -halfWidth, -halfHeight, z,\n halfWidth, -halfHeight, z,\n -halfWidth, halfHeight, z,\n halfWidth, halfHeight, z\n ];\n const indicies = [\n 0, 1, 2,\n 2, 1, 3\n ];\n const uvs = [\n 0, 0,\n 1, 0,\n 0, 1,\n 1, 1\n ];\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default PlaneGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"./Uniform\";\n\nclass UniformVector4Array extends Uniform {\n public val: number[][];\n\n public constructor(val: number[][]) {\n super();\n\n this.val = val;\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation) {\n gl.uniform4fv(location, this.val.reduce((arr, vector) => [...arr, ...vector], []));\n\n this.needsUpdate = false;\n }\n}\n\nexport default UniformVector4Array;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport SphereGeometry from \"../geometry/SphereGeometry\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport UniformVector4Array from \"../uniform/UniformVector4Array\";\nimport UniformFloat from \"../uniform/UniformFloat\";\nimport vs from \"../shader/stereoequi.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link StereoEquiProjection}\n * @ko {@link StereoEquiProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface StereoEquiProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n /**\n * Stereoscopic mode of the image\n * @ko 이미지의 스테레오스코픽 모드\n * @since 4.0.0\n * @default \"top_bottom\"\n */\n mode: typeof StereoEquiProjection.MODE[keyof typeof StereoEquiProjection.MODE]\n}\n\n/**\n * Projection based on stereo equirectangular images.\n * @ko Stereo equirectangular 이미지 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass StereoEquiProjection extends Projection<{\n uTexture: UniformTexture2D;\n uEye: UniformFloat;\n uTexScaleOffset: UniformVector4Array;\n}> {\n /**\n * Available stereoscopic modes\n * @ko 사용가능한 스테레오스코픽 모드들\n * @since 4.0.0\n */\n public static MODE = {\n /**\n * @ko 이미지가 왼쪽/오른쪽으로 구성되어있을 경우\n * @since 4.0.0\n */\n LEFT_RIGHT: \"left_right\",\n /**\n * @ko 이미지가 위/아래로 구성되어있을 경우\n * @since 4.0.0\n */\n TOP_BOTTOM: \"top_bottom\",\n } as const;\n\n private _mode: StereoEquiProjectionOptions[\"mode\"];\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: StereoEquiProjectionOptions) {\n super(options);\n\n this._mode = options.mode;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n let leftEye: number[];\n let rightEye: number[];\n\n switch (this._mode) {\n case StereoEquiProjection.MODE.LEFT_RIGHT:\n leftEye = [0.5, 1, 0, 0];\n rightEye = [0.5, 1, 0.5, 0];\n break;\n default:\n // Default, uses \"top_bottom\"\n leftEye = [1, 0.5, 0, 0];\n rightEye = [1, 0.5, 0, 0.5];\n }\n\n\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture),\n uEye: new UniformFloat(0),\n uTexScaleOffset: new UniformVector4Array([leftEye, rightEye])\n };\n\n const geometry = new SphereGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default StereoEquiProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTextureCube from \"../uniform/UniformTextureCube\";\nimport UniformCanvasCube from \"../uniform/UniformCanvasCube\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport TextureCube from \"../texture/TextureCube\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/cube.vert\";\nimport fs from \"../shader/cube.frag\";\n\n/**\n * Options for {@link CubemapProjection}\n * @ko {@link CubemapProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CubemapProjectionOptions extends ProjectionOptions {\n /**\n * Order of the cubemap images.\n * @ko 큐브맵 이미지의 순서.\n * @since 4.0.0\n * @default \"RLUDFB\" (Right - Left - Up - Down - Front - Back)\n */\n cubemapOrder?: string;\n /**\n * Whether to flip cubemap image horizontally.\n * @ko 큐브맵 이미지를 좌우대칭할지 여부.\n * @since 4.0.0\n * @default false\n */\n cubemapFlipX?: boolean;\n}\n\n/**\n * Projection based on cubemap images, accepts both multiple or single images.\n * @ko 큐브맵 이미지 기반의 프로젝션, 단일 혹은 여러 장의 이미지를 모두 사용 가능합니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CubemapProjection extends Projection<{\n uTexture: UniformTextureCube | UniformCanvasCube;\n}> {\n private _cubemapOrder: NonNullable;\n private _cubemapFlipX: NonNullable;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CubemapProjectionOptions) {\n super(options);\n\n const {\n cubemapOrder = \"RLUDFB\",\n cubemapFlipX = false\n } = options;\n\n this._cubemapOrder = cubemapOrder;\n this._cubemapFlipX = cubemapFlipX;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const cubemapOrder = this._cubemapOrder;\n const cubemapFlipX = this._cubemapFlipX;\n const uniforms = {\n uTexture: texture.isCube()\n ? new UniformTextureCube(ctx, texture as TextureCube, cubemapOrder)\n : new UniformCanvasCube(ctx, texture as Texture2D, cubemapOrder)\n };\n\n const geometry = new CubeGeometry({\n order: cubemapOrder\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n if (cubemapFlipX) {\n mesh.scale[0] = -1;\n }\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n}\n\nexport default CubemapProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link CubestripProjection}\n * @ko {@link CubestripProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CubestripProjectionOptions extends ProjectionOptions {\n /**\n * @copy CubemapProjectionOptions#cubemapOrder\n */\n cubemapOrder?: string;\n /**\n * @copy CubemapProjectionOptions#cubemapFlipX\n */\n cubemapFlipX?: boolean;\n}\n\n/**\n * Projection based on cubemap strip.\n * Slightly more efficient than {@link CubemapProjection} as it doesn't copy cubemap image to canvas while rendering.\n * Accepts only single image.\n * @ko 큐브맵 스트립 기반의 프로젝션.\n * {@link CubemapProjection}와 달리 렌더링하는 과정에 캔버스에 이미지를 복사하는 과정이 없기 때문에 살짝 더 효율적입니다.\n * 단일 이미지만 사용 가능합니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CubestripProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n private _cubemapOrder: NonNullable;\n private _cubemapFlipX: NonNullable;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CubestripProjectionOptions) {\n super(options);\n\n const {\n cubemapOrder = \"RLUDFB\",\n cubemapFlipX = false\n } = options;\n\n this._cubemapOrder = cubemapOrder;\n this._cubemapFlipX = cubemapFlipX;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const cubemapOrder = this._cubemapOrder;\n const cubemapFlipX = this._cubemapFlipX;\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n const geometry = new CubeGeometry({\n order: cubemapOrder\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n if (cubemapFlipX) {\n mesh.scale[0] = -1;\n }\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n}\n\nexport default CubestripProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n*/\nimport { quat } from \"gl-matrix\";\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport CylinderGeometry from \"../geometry/CylinderGeometry\";\nimport Camera from \"../core/Camera\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"../const/internal\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\nimport TriangleMesh from \"../core/TriangleMesh\";\n\n/**\n * Options for {@link CylindricalProjection}\n * @ko {@link CylindricalProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CylindricalProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n /**\n * Whether the panorama image covers full 360 degrees.\n * @ko 파노라마 이미지가 360도를 전부 커버하는지 여부\n * @since 4.0.0\n * @default false\n */\n partial?: boolean;\n}\n\n/**\n * Projection based on cylindrical projection.\n * This can show panorama images taken from smartphones.\n * @ko 원통 투영법 기반의 프로젝션.\n * 일반적인 스마트폰 파노라마 사진을 표시하는데 사용될 수 있습니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CylindricalProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n private _partial: boolean;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CylindricalProjectionOptions) {\n super(options);\n\n const {\n partial = false\n } = options;\n\n this._partial = partial;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const partial = this._partial;\n const { width, height } = texture;\n const aspect = width / height;\n const halfVFov = 180 / aspect;\n const cylinderHeight = partial\n ? 1\n : 2 * Math.tan(halfVFov * DEG_TO_RAD);\n const cylinderTheta = partial\n ? aspect\n : 2 * Math.PI;\n\n const geometry = new CylinderGeometry(cylinderTheta);\n const program = new ShaderProgram(ctx, vs, fs, {\n uTexture: new UniformTexture2D(ctx, texture)\n });\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n mesh.scale[1] = cylinderHeight;\n quat.identity(mesh.rotation);\n quat.rotateY(mesh.rotation, mesh.rotation, -Math.PI / 2);\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n\n public updateCamera(camera: Camera) {\n super.updateCamera(camera);\n\n const mesh = this._mesh;\n if (!mesh) return;\n\n const uTexture = mesh.program.uniforms.uTexture;\n const texture = uTexture.texture;\n const { width, height } = texture;\n const aspect = width / height;\n const halfHeight = mesh.scale[1] * 0.5;\n\n if (this._partial) {\n const restrictedYaw = 0.5 * aspect * RAD_TO_DEG;\n camera.restrictYawRange(-restrictedYaw, restrictedYaw);\n }\n\n const restrictedPitch = Math.atan2(halfHeight, 1) * RAD_TO_DEG;\n const minZoom = Math.tan(camera.fov * DEG_TO_RAD * 0.5) / (halfHeight * camera.aspect);\n\n camera.restrictPitchRange(-restrictedPitch, restrictedPitch);\n camera.restrictZoomRange(minZoom, Infinity);\n camera.restrictRenderHeight(halfHeight * 2);\n }\n}\n\nexport default CylindricalProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/eac.frag\";\nimport { ROTATE } from \"../const/internal\";\n\n/**\n * Options for {@link EquiangularProjection}\n * @ko {@link EquiangularProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface EquiangularProjectionOptions extends ProjectionOptions {}\n\n/**\n * Equi-Angular Cubemap Projection.\n * This format is used by Youtube's 360 videos.\n * @ko Equi-Angular Cubemap 프로젝션.\n * 이 포맷은 주로 Youtube의 360 비디오에 사용됩니다.\n * @since 4.0.0\n * @category Projection\n */\nclass EquiangularProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n const geometry = new CubeGeometry({\n order: \"LFRDBU\",\n rotateUV: [\n ROTATE.ZERO, ROTATE.ZERO, ROTATE.ZERO,\n ROTATE.CW_90, ROTATE.CCW_90, ROTATE.CW_90\n ]\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default EquiangularProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport Texture2D from \"../texture/Texture2D\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport SphereGeometry from \"../geometry/SphereGeometry\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link EquirectProjection}\n * @ko {@link EquirectProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface EquirectProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n}\n\n/**\n * Projection based on equirectangular projection.\n * @ko 등 장방형 도법(Equirectangular projection) 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass EquirectProjection extends Projection<{\n uTexture: UniformTexture2D\n}> {\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: EquirectProjectionOptions) {\n super(options);\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n\n const geometry = new SphereGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default EquirectProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport UniformFloat from \"../uniform/UniformFloat\";\nimport Camera from \"../core/Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport Texture2D from \"../texture/Texture2D\";\nimport PlaneGeometry from \"../geometry/PlaneGeometry\";\nimport vs from \"../shader/little-planet.vert\";\nimport fs from \"../shader/little-planet.frag\";\nimport TriangleMesh from \"../core/TriangleMesh\";\n\n/**\n * Options for {@link LittlePlanetProjection}\n * @ko {@link LittlePlanetProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface LittlePlanetProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n}\n\n/**\n * Projection based on so-called \"Little planet\" or \"Tiny planet\" effect.\n * @ko \"Little planet\" 혹은 \"Tiny planet\"로 불리는 이펙트 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass LittlePlanetProjection extends Projection<{\n uTexture: UniformTexture2D;\n uYaw: UniformFloat;\n uPitch: UniformFloat;\n uZoom: UniformFloat;\n}> {\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: LittlePlanetProjectionOptions) {\n super(options);\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n texture.wrapS = WebGLRenderingContext.REPEAT;\n texture.wrapT = WebGLRenderingContext.REPEAT;\n\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture),\n uYaw: new UniformFloat(0),\n uPitch: new UniformFloat(0.5),\n uZoom: new UniformFloat(1)\n };\n\n const geometry = new PlaneGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n\n public updateControl(control: PanoControl) {\n control.ignoreZoomScale = true;\n }\n\n public update(camera: Camera) {\n const mesh = this._mesh;\n if (!mesh) return;\n\n const uniforms = mesh.program.uniforms;\n\n uniforms.uYaw.val = camera.yaw / 360;\n // Range from 0 ~ 1\n uniforms.uPitch.val = (camera.pitch / 180) + 0.5;\n uniforms.uZoom.val = camera.zoom;\n\n uniforms.uYaw.needsUpdate = true;\n uniforms.uPitch.needsUpdate = true;\n uniforms.uZoom.needsUpdate = true;\n }\n}\n\nexport default LittlePlanetProjection;\n","/**\n * @hidden\n */\nexport const getValidProps = (propsObj: any) => {\n return Object.keys(propsObj).reduce((props, propName) => {\n if (propsObj[propName] != null) {\n props[propName] = propsObj[propName];\n }\n\n return props;\n }, {});\n};\n","export const VIEW360_METHODS = [\n \"destroy\",\n \"init\",\n \"load\",\n \"resize\",\n \"addPlugins\",\n \"removePlugins\",\n \"renderFrame\",\n // @egjs/component methods\n \"on\",\n \"hasOn\",\n \"once\",\n \"off\",\n \"trigger\"\n] as const;\n","import Component from \"@egjs/component\";\nimport View360 from \"../View360\";\n\n/**\n * @hidden\n */\nconst withMethods = (prototype: any, attr: string) => {\n [Component.prototype, View360.prototype].forEach(proto => {\n Object.getOwnPropertyNames(proto)\n .filter(name => name.charAt(0) !== \"_\" && name !== \"constructor\")\n .forEach((name: string) => {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name)!;\n\n if (descriptor.value) {\n // Public Function\n Object.defineProperty(prototype, name, {\n value: function(...args) {\n return descriptor.value.call(this[attr], ...args);\n }\n });\n } else {\n const getterDescriptor: { get?: () => any; set?: (val: any) => void } = {};\n if (descriptor.get) {\n getterDescriptor.get = function() {\n return this[attr] && descriptor.get?.call(this[attr]);\n };\n }\n if (descriptor.set) {\n getterDescriptor.set = function(...args) {\n return descriptor.set?.call(this[attr], ...args);\n };\n }\n\n Object.defineProperty(prototype, name, getterDescriptor);\n }\n });\n });\n};\n\nexport default withMethods;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360, * as modules from \"./index\";\nimport { merge } from \"./utils\";\n\nmerge(View360, modules);\n\nexport default View360;\n"],"names":["View360Error","Error","constructor","message","code","super","Object","setPrototypeOf","this","prototype","name","ERROR_CODES","WRONG_TYPE","WRONG_OPTION","ELEMENT_NOT_FOUND","CANVAS_NOT_FOUND","WEBGL_NOT_SUPPORTED","FAILED_CREATE_CONTEXT_2D","PROVIDE_PROJECTION_FIRST","FAILED_LINKING_PROGRAM","INSUFFICIENT_ARGS","ERROR","val","types","map","type","join","optionName","query","msg","shaderLog","EVENTS","EL_DIV","EL_BUTTON","MOUSE_BUTTON","CURSOR","KEY_DIRECTION","DIRECTION_KEY_CODE","DIRECTION_KEY_NAME","LEFT","UP","RIGHT","DOWN","FULLSCREEN_REQUEST","FULLSCREEN_ELEMENT","FULLSCREEN_EXIT","FULLSCREEN_CHANGE","DEFAULT_CLASS","CONTAINER","CANVAS","CTX_LOST","IN_VR","HOTSPOT_CONTAINER","HOTSPOT","HOTSPOT_VISIBLE","HOTSPOT_FLIP_X","HOTSPOT_FLIP_Y","READY","LOAD_START","LOAD","PROJECTION_CHANGE","RESIZE","BEFORE_RENDER","RENDER","INPUT_START","INPUT_END","VIEW_CHANGE","STATIC_CLICK","VR_START","VR_END","EASING","LINEAR","x","SINE_WAVE","Math","sin","PI","EASE_OUT_CUBIC","pow","EASE_OUT_BOUNCE","n1","d1","CAMERA_EVENTS","CONTROL_EVENTS","DEG_TO_RAD","RAD_TO_DEG","DEFAULT_EASING","DEFAULT_ANIMATION_DURATION","INFINITE_RANGE","min","Infinity","max","DEFAULT_PITCH_RANGE","DEFAULT_ZOOM_RANGE","ROTATE","VIDEO_TIME_CHANGE_EVENT","SVG_NAMESPACE","SESSION_VR","XR_REFERENCE_SPACE","EPSILON","_a","Number","isString","createElement","className","tag","BROWSER","el","document","classList","add","getNullableElement","parent","targetEl","queryResult","querySelector","nodeType","Node","ELEMENT_NODE","clamp","lerp","a","b","t","circulate","size","abs","findIndex","array","checker","idx","length","getObjectOption","toVerticalFov","fovRadian","aspect","atan","tan","reorderCube","arr","order","defaultOrder","split","face","indexOf","index","isFullscreen","key","sensorCanBeEnabledIOS","DeviceMotionEvent","window","isSecureContext","eulerToQuat","out","yaw","pitch","roll","quat","identity","pitchClamped","rotateY","rotateX","rotateZ","quatToEuler","quaternion","y","z","w","unit","test","atan2","view","vec3","fromValues","up","transformQuat","viewXZ","sqrt","Motion","_val","start","_start","end","_end","progress","_progress","activated","_activated","duration","_duration","loop","_loop","range","_range","easing","_easing","reset","update","deltaTime","prev","nextProgress","easedProgress","defaultVal","delta","setNewEndByDelta","setRange","CameraAnimation","_motion","camera","from","to","_camera","_from","_to","_finishPromise","Promise","resolve","_finish","getFinishPromise","motion","rotation","create","zoom","slerp","rotate","Camera","Component","_aspect","changed","_changed","yawRange","_initialYawRange","pitchRange","_initialPitchRange","zoomRange","_initialZoomRange","initialYaw","initialPitch","initialZoom","fov","rollOffset","position","animation","_up","_yawRange","_pitchRange","_zoomRange","_updateQuaternion","viewMatrix","mat4","projectionMatrix","_maxRenderHeight","destroy","off","resize","width","height","prevAspect","updateMatrix","lookAt","prevQuaternion","clone","prevZoom","zoomDiff","equals","normalized","normalize","isSameRotation","copy","animateTo","finishPromise","then","trigger","restrictYawRange","restrictPitchRange","restrictZoomRange","restrictRenderHeight","resetRange","getYawRange","yawLimit","maxRenderHeight","halfHFov","getHorizontalFov","minYaw","maxYaw","halfVFovRad","h","d","theta","getPitchRange","pitchLimit","minPitch","maxPitch","halfVFov","getVerticalFov","getZoomRange","limit","minFov","maxFov","currentFov","current","_getZoomedHorizontalFov","hFov","fovToZoom","baseFov","projMatrix","upDir","viewDir","vFov","perspective","onFrameRender","MouseInput","_onMouseDown","evt","_el","button","preventDefault","focus","_prevPos","clientX","clientY","addEventListener","_onMouseMove","_onMouseUp","srcEvent","isTouch","isKeyboard","prevPos","deltaX","deltaY","removeEventListener","scrolling","enable","element","disable","TouchInput","scrollable","_scrollable","_onTouchStart","touches","_scrolling","touch","_isFirstTouch","_onTouchMove","cancelable","_onTouchEnd","passive","KeyboardInput","active","pressed","_pressed","_onKeyDown","location","KeyboardEvent","DOM_KEY_LOCATION_STANDARD","_updateKeyPress","pressedCount","_getPressedKeyCount","repeat","_onKeyUp","_clearPressedKeys","_getDeltaByPressedKeys","reduce","obj","keyName","assign","event","isEnable","keyToUpdate","keyCode","filter","RotateControl","enabled","_enabled","enableBlocked","_enableBlocked","animating","_keyboardInput","_xMotion","_yMotion","_touchInput","pointerScale","_pointerScale","keyboardScale","_keyboardScale","disablePitch","_disablePitch","disableYaw","_disableYaw","disableKeyboard","_disableKeyboard","controlEl","_onInputStart","_changedWhileDragging","inputType","_onChange","invZoomScale","_zoomScale","screenScale","_screenScale","scale","scaledX","scaledY","_onInputEnd","_controlEl","_mouseInput","_bindInputs","xMotion","yMotion","keyboardInput","updateRange","setZoomScale","hfov","vfov","control","updateCursor","sync","mouseInput","touchInput","on","WheelInput","_onWheel","stopPropagation","_inputTimer","_clearTimer","_baseScale","setTimeout","capture","clearTimeout","PinchInput","prevDistance","_prevDistance","diff","pageX","pageY","distance","ZoomControl","_wheelInput","_scale","scaledDelta","_pinchInput","wheelInput","pinchInput","ROTATE_CONSTANT","PITCH_DELTA","YAW_DELTA_BY_ROLL","YAW_DELTA_BY_YAW","targetAxis","meshPoint","GyroInput","orientationUpdated","_orientationUpdated","ignoreRoll","_ignoreRoll","_onDeviceOrientation","prevOrientation","_orientation","alpha","beta","gamma","_needsCalibrate","_calibrateSensor","_updateScreenOrientation","screen","orientation","undefined","angle","_screenOrientation","_yawOrigin","_yawOffset","_updateRotation","collectDelta","prevRotation","_toEulerDelta","setInitialRotation","yawOrigin","sensorYaw","screenAngle","world","set","cos","multiply","prevQuat","currentQuat","_getDeltaYaw","_getDeltaPitch","prvQ","curQ","yawDeltaByYaw","_getRotationDelta","_extractPitchFromQuat","prevQ","rotateKind","curQuaternion","prevPoint","curPoint","rotateDirection","dot","cross","meshPoint2","meshPoint3","vecU","vecV","vecN","coefficientA","coefficientB","coefficientC","projectedPrevPoint","subtract","trigonometricRatio","acos","crossVec","thetaDirection","baseV","GyroControl","_input","static","onDeviceMotionChange","race","res","rotationRate","available","requestPermission","permissionState","catch","_updateYawPitch","input","yawDelta","pitchDelta","PanoControl","useGrabCursor","_useGrabCursor","_setCursor","disableContextMenu","_disableContextMenu","_blockContextMenu","_restoreContextMenu","_rotateControl","wheelScrollable","_zoomControl","ignoreZoomScale","_ignoreZoomScale","gyro","_gyroControl","_preventContextMenu","_onEnable","_onDisable","_onCameraAnimationEnd","_bindEvents","isAvailable","rotateControl","zoomControl","gyroControl","hfovToZoom","zoomScale","newCursor","style","cursor","Texture","flipY","wrapS","WebGLRenderingContext","CLAMP_TO_EDGE","wrapT","isVideo","isCube","Texture2D","source","TextureVideo","video","pause","removeAttribute","load","isPaused","paused","ended","readyState","hasAudio","audioTracks","webkitAudioDecodedByteCount","mozHasAudio","TextureCube","sources","TextureLoader","_loadChecker","ImReady","src","loadVideo","Array","isArray","loadCubeImage","imgSrc","loadImage","images","_toImageArray","_load","image","naturalWidth","naturalHeight","videoConfig","config","autoplay","muted","volume","_toVideoElement","currentTime","play","videoWidth","videoHeight","content","onLoad","loader","reject","once","errorCount","check","imgEl","Image","crossOrigin","HTMLVideoElement","playsInline","setAttribute","forEach","_appendSourceElement","querySelectorAll","HTMLSourceElement","sourceEl","appendChild","FrameAnimator","maxDeltaTime","context","_context","_rafId","_rafTimer","_lastUpdateTime","callback","_time","frame","time","Date","now","requestAnimationFrame","stop","cancelAnimationFrame","changeContext","AutoResizer","useResizeObserver","_useResizeObserver","onResize","_skipFirstResize","isFirstResize","_onResize","_resizeObserver","ResizeObserver","bbox","getBoundingClientRect","resizeImmediate","resizeObserver","observe","disconnect","Autoplay","playing","_interrupted","delay","_delay","delayOnMouseLeave","_delayOnMouseLeave","speed","_speed","pauseOnHover","_pauseOnHover","canInterrupt","_canInterrupt","disableOnInterrupt","_disableOnInterrupt","viewer","options","_clearTimeout","_setUninterruptedAfterDelay","_onGyroEnable","_onMouseEnter","_hovering","_onMouseLeave","_control","_element","_interruptionTimer","enableAfterDelay","XRManager","ctx","exit","_onSessionEnd","_xrSession","_xrRefSpace","_ctx","_options","xr","navigator","isSessionSupported","enter","requestSensorPermission","requiredFeatures","makeXRCompatible","session","requestSession","bindXRLayer","refSpace","requestReferenceSpace","_setSession","xrSession","canRender","getViewerPose","getEyeParams","pose","glLayer","renderState","baseLayer","views","viewport","getViewport","vMatrix","transform","inverse","matrix","pMatrix","Hotspot","HotspotRenderer","rootEl","renderer","_containerEl","_renderer","_hotspots","_zoom","refresh","container","hotspotEls","slice","apply","_parseHotspot","render","hotspots","halfWidth","halfHeight","centerTransform","zoomTransform","hotspot","relPos","transformMat4","remove","screenPos","vec2","yawStr","dataset","pitchStr","positionStr","parseFloat","_yawPitchToVec3","pos","defaultPos","yawRad","pitchRad","VertexArrayObject","count","geometry","indicies","buffers","WebGLContext","canvas","_canvas","maxTextureSize","_maxTextureSize","isWebGL2","_isWebGL2","supportVAO","_extensions","vao","lost","_contextLost","debug","_debug","_onContextLost","_onContextRestore","loseContext","init","gl","_getContext","_gl","getParameter","MAX_TEXTURE_SIZE","getExtension","bindBuffer","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","forceLoseContext","extension","forceRestoreContext","restoreContext","clear","COLOR_BUFFER_BIT","drawingBufferWidth","drawingBufferHeight","createVAO","shaderProgram","nativeVAO","_createNativeVAO","_createBuffer","uv","_bindNativeVAO","_supplyGeometryData","_unbindBuffers","draw","drawElements","TRIANGLES","UNSIGNED_SHORT","releaseVAO","_deleteNativeVAO","_deleteBuffer","getUniformLocations","program","uniforms","uniformLocations","keys","locations","getUniformLocation","_getCommonUniformLocations","updateCommonUniforms","entity","mvMatrix","uniformMatrix4fv","uMVMatrix","uPMatrix","updateVRUniforms","eyeIndex","uEye","uniform1f","updateUniforms","uniform","needsUpdate","releaseShaderResources","deleteProgram","useProgram","createProgram","vertexShader","fragmentShader","vs","_compileShader","VERTEX_SHADER","fs","FRAGMENT_SHADER","attachShader","bindAttribLocation","linkProgram","getProgramParameter","LINK_STATUS","getShaderParameter","COMPILE_STATUS","getShaderInfoLog","getProgramInfoLog","deleteShader","createWebGLTexture","texData","texture","createTexture","bindTexture","TEXTURE_2D","texParameteri","TEXTURE_MIN_FILTER","TEXTURE_MAG_FILTER","TEXTURE_WRAP_S","TEXTURE_WRAP_T","gl2","texStorage2D","RGBA8","createWebGLCubeTexture","TEXTURE_CUBE_MAP","attributes","getContextAttributes","xrCompatible","xrLayer","XRWebGLLayer","updateRenderState","bindXRFrame","bindFramebuffer","FRAMEBUFFER","framebuffer","useDefaultFrameBuffer","createBuffer","buffer","deleteBuffer","createVertexArray","ext","createVertexArrayOES","bindVertexArray","bindVertexArrayOES","deleteVertexArray","deleteVertexArrayOES","_supplyIndiciesData","_supplyAttributeData","vertices","uvs","bufferData","data","STATIC_DRAW","attribute","attribLocation","getAttribLocation","vertexAttribPointer","itemSize","FLOAT","enableVertexAttribArray","shader","createShader","shaderSource","compileShader","webglIdentifiers","contextAttributes","preserveDrawingBuffer","antialias","onWebglContextCreationError","e","statusMessage","identifier","getContext","WebGLRenderer","_elementSize","pixelRatio","_pixelRatio","canvasSize","devicePixelRatio","clientWidth","clientHeight","projection","mesh","getMesh","renderVR","vr","eyeParams","eye","View360","_rootEl","_vr","_hotspot","plugins","_plugins","_projection","_initialized","initialized","_autoplay","autoInit","_autoInit","autoResize","_autoResize","canvasSelector","_canvasSelector","tabIndex","_tabIndex","_animator","updateCamera","root","renderFrame","autoPlayer","_emit","_renderFrameOnDemand","getTexture","_renderVRFrame","_delta","getElement","findCanvas","selector","_autoResizer","_addEventHandlers","releaseAllResources","plugin","animator","_bindComponentEvents","_resizeComponents","_loadTexture","_applyProjection","hasAttribute","addPlugins","push","removePlugins","pluginIdx","splice","eventName","params","evtParams","target","prevProjection","applyTexture","updateControl","contentLoader","events","evtName","VERSION","Object3D","fromRotationTranslationScale","LoadingSpinner","_startLoading","_container","_detachElements","parentElement","removeChild","_createElements","ring","RING","ControlBarItem","CONTROL_BAR_DEFAULT_CLASS","CONTROLS_ROOT","CONTROLS_BG","CONTROLS_MAIN","CONTROLS_TOP","CONTROLS_BOTTOM","CONTROLS_MID","CONTROLS_LEFT","CONTROLS_RIGHT","CONTROLS_FLOAT_LEFT","CONTROLS_FLOAT_RIGHT","CONTROLS_BUTTON","PROGRESS_ROOT","VOLUME_ROOT","RANGE_ROOT","RANGE_TRACK","RANGE_THUMB","RANGE_FILLER","PLAY_BUTTON","PAUSE_BUTTON","UNMUTED_BUTTON","MUTED_BUTTON","FULLSCREEN_BUTTON","FULLSCREEN_EXIT_BUTTON","VR_BUTTON","GYRO_ENABLED","GYRO_DISABLED","VIDEO_TIME_DISPLAY","PIEVIEW_ROOT","FIXED","UNAVAILABLE","HIDDEN","CONTROL_BAR_ITEM_POSITION","TOP_LEFT","TOP_RIGHT","MAIN_TOP","MAIN_BOTTOM","MAIN_LEFT","MAIN_RIGHT","RangeControl","_onHold","_bbox","elX","scrollX","pageXOffset","clamepdX","thumbEl","_fixedClass","_onRelease","track","thumb","filler","draggable","trackEl","fillerEl","left","right","bottom","top","updateStyle","clampedProgress","ProgressBar","_rangeControl","_onTimeUpdate","_video","_currentTime","_onDurationChange","controlBar","_controlBar","dispatchEvent","CustomEvent","detail","_wasPaused","_playPromise","_onControl","rangeControl","unavailableClass","PlayButton","_onClick","_paused","_onPlay","title","_onPause","VolumeControl","_updateDisplay","disabled","_onVolumeChange","_buttonEl","containerEl","buttonEl","FullscreenButton","_targetEl","_exitFullscreen","_requestFullscreen","_onFullscreenChange","_fullscreenAvailable","_addFullscreenHandlers","_removeFullscreenHandlers","some","request","call","VideoTime","_onCustomTimeChange","timeMinute","floor","timeSeconds","timeSecondsFormatted","durationMinute","durationSeconds","durationSecondsFormatted","innerText","PieView","resetCamera","_viewer","_updatePie","piePath","_piePathEl","rangeCircle","_rangeCircleEl","halfFov","pieRadius","pieDeg","pieOffset","isFinite","radius","rangeDiff","offset","_createPieElements","rootClass","pieSVG","createElementNS","VRButton","GyroButton","_updateStyle","enableButton","AutoHide","hidden","contains","_hiddenClass","initialDelay","idleDelay","activationDelay","_isCursorInside","show","_hideAfterDelay","_isFullscreen","showTemporaliy","_isGrabbing","pointerType","_onVideoPlay","_onVideoPause","_initialDelay","_idleDelay","_timer","hide","_clearHideTimer","VideoControl","videoEl","keyPressed","_changeVideoTime","_changeVideoVolume","_toggleVideo","forward","increase","ControlBar","backgroundEl","_bgEl","items","_items","customItems","_customItems","autoHide","showBackground","clickToPlay","keyboardControls","progressBar","playButton","volumeButton","fullscreenButton","videoTime","pieView","vrButton","gyroButton","_onStaticClick","autoHider","_autoHider","_onNewSrcLoad","_updateBackground","_updateAutoHide","_updateKeyboardHandler","item","_createPositionWrappers","POSITION","_videoControl","panoRoot","controlsRoot","defaultItems","_createDefaultItems","_addItem","_clearItemElements","category","wrapper","_wrapperEl","nextSiblingIndex","sibling","nextSibling","insertBefore","floatLeftEl","floatRightEl","topWrapper","bottomWrapper","midWrapper","leftControlsWrapper","rightControlsWrapper","firstChild","background","hiddenClass","_b","videoControl","Projection","_mesh","uTexture","Uniform","UniformTextureCube","cubemapOrder","_webglTexture","_cubemapOrder","deleteTexture","pixelStorei","UNPACK_FLIP_Y_WEBGL","uniform1i","activeTexture","TEXTURE0","texSubImage2D","TEXTURE_CUBE_MAP_POSITIVE_X","RGBA","UNSIGNED_BYTE","texImage2D","CubeTexturePainter","_size","_renderingOrder","undef","_calcRenderingSize","surfaceIdx","row","_row","column","_column","renderingFace","drawImage","UniformCanvasCube","_painter","TriangleMesh","ShaderProgram","VertexData","Geometry","Float32Array","Uint16Array","CubeGeometry","rotateUV","oneThird","coords","r","c","coord","degree","ZERO","newOrder","CW_90","CCW_90","newCoords","uvIdx","acc","concat","UniformTexture2D","CylinderGeometry","maxTheta","heightSegments","invRadialSegments","angleConst","yIdx","lngIdx","u","v","SphereGeometry","ANGLE_CORRECTION_FOR_CENTER_ALIGN","latIdx","sinTheta","cosTheta","phi","sinPhi","UniformFloat","PlaneGeometry","UniformVector4Array","uniform4fv","vector","StereoEquiProjection","_mode","mode","leftEye","rightEye","MODE","LEFT_RIGHT","uTexScaleOffset","TOP_BOTTOM","cubemapFlipX","_cubemapFlipX","partial","_partial","cylinderHeight","cylinderTheta","restrictedYaw","restrictedPitch","minZoom","REPEAT","uYaw","uPitch","uZoom","propsObj","props","propName","withMethods","attr","proto","getOwnPropertyNames","charAt","descriptor","getOwnPropertyDescriptor","value","defineProperty","args","getterDescriptor","get","merge","srcs","modules"],"mappings":"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"} \ No newline at end of file diff --git a/demo/release/latest/dist/view360.pkgd.js b/demo/release/latest/dist/view360.pkgd.js new file mode 100644 index 000000000..1670f4248 --- /dev/null +++ b/demo/release/latest/dist/view360.pkgd.js @@ -0,0 +1,10532 @@ +/* +Copyright (c) 2023-present NAVER Corp. +name: @egjs/view360 +license: MIT +author: NAVER Corp. +repository: https://github.com/naver/egjs-view360 +version: 4.0.0-beta.4 +*/ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.View360 = factory()); +})(this, (function () { 'use strict'; + + /****************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function (resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + } + + /* + Copyright (c) NAVER Corp. + name: @egjs/component + license: MIT + author: NAVER Corp. + repository: https://github.com/naver/egjs-component + version: 3.0.4 + */ + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + function __values(o) { + var s = typeof Symbol === "function" && Symbol.iterator, + m = s && o[s], + i = 0; + if (m) return m.call(o); + if (o && typeof o.length === "number") return { + next: function () { + if (o && i >= o.length) o = void 0; + return { + value: o && o[i++], + done: !o + }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); + } + function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), + r, + ar = [], + e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } catch (error) { + e = { + error: error + }; + } finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } finally { + if (e) throw e.error; + } + } + return ar; + } + function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); + return ar; + } + + /* + * Copyright (c) 2015 NAVER Corp. + * egjs projects are licensed under the MIT license + */ + var isUndefined = function (value) { + return typeof value === "undefined"; + }; + + // This class name is not matched to file name intentionally + /** + * Event class to provide additional properties + * @ko Component에서 추가적인 프로퍼티를 제공하는 이벤트 클래스 + */ + var ComponentEvent = /*#__PURE__*/function () { + /** + * Create a new instance of ComponentEvent. + * @ko ComponentEvent의 새로운 인스턴스를 생성한다. + * @param eventType The name of the event.이벤트 이름. + * @param props An object that contains additional event properties.추가적인 이벤트 프로퍼티 오브젝트. + */ + function ComponentEvent(eventType, props) { + var e_1, _a; + this._canceled = false; + if (props) { + try { + for (var _b = __values(Object.keys(props)), _c = _b.next(); !_c.done; _c = _b.next()) { + var key = _c.value; + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + this[key] = props[key]; + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (_c && !_c.done && (_a = _b.return)) _a.call(_b); + } finally { + if (e_1) throw e_1.error; + } + } + } + this.eventType = eventType; + } + /** + * Stop the event. {@link ComponentEvent#isCanceled} will return `true` after. + * @ko 이벤트를 중단한다. 이후 {@link ComponentEvent#isCanceled}가 `true`를 반환한다. + */ + var __proto = ComponentEvent.prototype; + __proto.stop = function () { + this._canceled = true; + }; + /** + * Returns a boolean value that indicates whether {@link ComponentEvent#stop} is called before. + * @ko {@link ComponentEvent#stop}이 호출되었는지 여부를 반환한다. + * @return {boolean} A boolean value that indicates whether {@link ComponentEvent#stop} is called before.이전에 {@link ComponentEvent#stop}이 불려졌는지 여부를 반환한다. + */ + __proto.isCanceled = function () { + return this._canceled; + }; + return ComponentEvent; + }(); + + /** + * A class used to manage events in a component + * @ko 컴포넌트의 이벤트을 관리할 수 있게 하는 클래스 + */ + var Component = /*#__PURE__*/function () { + /** + * @support {"ie": "7+", "ch" : "latest", "ff" : "latest", "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.1+ (except 3.x)"} + */ + function Component() { + this._eventHandler = {}; + } + /** + * Trigger a custom event. + * @ko 커스텀 이벤트를 발생시킨다 + * @param {string | ComponentEvent} event The name of the custom event to be triggered or an instance of the ComponentEvent발생할 커스텀 이벤트의 이름 또는 ComponentEvent의 인스턴스 + * @param {any[]} params Event data to be sent when triggering a custom event 커스텀 이벤트가 발생할 때 전달할 데이터 + * @return An instance of the component itself컴포넌트 자신의 인스턴스 + * @example + * ```ts + * import Component, { ComponentEvent } from "@egjs/component"; + * + * class Some extends Component<{ + * beforeHi: ComponentEvent<{ foo: number; bar: string }>; + * hi: { foo: { a: number; b: boolean } }; + * someEvent: (foo: number, bar: string) => void; + * someOtherEvent: void; // When there's no event argument + * }> { + * some(){ + * if(this.trigger("beforeHi")){ // When event call to stop return false. + * this.trigger("hi");// fire hi event. + * } + * } + * } + * + * const some = new Some(); + * some.on("beforeHi", e => { + * if(condition){ + * e.stop(); // When event call to stop, `hi` event not call. + * } + * // `currentTarget` is component instance. + * console.log(some === e.currentTarget); // true + * + * typeof e.foo; // number + * typeof e.bar; // string + * }); + * some.on("hi", e => { + * typeof e.foo.b; // boolean + * }); + * // If you want to more know event design. You can see article. + * // https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F + * ``` + */ + var __proto = Component.prototype; + __proto.trigger = function (event) { + var params = []; + for (var _i = 1; _i < arguments.length; _i++) { + params[_i - 1] = arguments[_i]; + } + var eventName = event instanceof ComponentEvent ? event.eventType : event; + var handlers = __spread(this._eventHandler[eventName] || []); + if (handlers.length <= 0) { + return this; + } + if (event instanceof ComponentEvent) { + event.currentTarget = this; + handlers.forEach(function (handler) { + handler(event); + }); + } else { + handlers.forEach(function (handler) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + handler.apply(void 0, __spread(params)); + }); + } + return this; + }; + /** + * Executed event just one time. + * @ko 이벤트가 한번만 실행된다. + * @param {string} eventName The name of the event to be attached or an event name - event handler mapped object.등록할 이벤트의 이름 또는 이벤트 이름-핸들러 오브젝트 + * @param {function} handlerToAttach The handler function of the event to be attached 등록할 이벤트의 핸들러 함수 + * @return An instance of the component itself컴포넌트 자신의 인스턴스 + * @example + * ```ts + * import Component, { ComponentEvent } from "@egjs/component"; + * + * class Some extends Component<{ + * hi: ComponentEvent; + * }> { + * hi() { + * alert("hi"); + * } + * thing() { + * this.once("hi", this.hi); + * } + * } + * + * var some = new Some(); + * some.thing(); + * some.trigger(new ComponentEvent("hi")); + * // fire alert("hi"); + * some.trigger(new ComponentEvent("hi")); + * // Nothing happens + * ``` + */ + __proto.once = function (eventName, handlerToAttach) { + var _this = this; + if (typeof eventName === "object" && isUndefined(handlerToAttach)) { + var eventHash = eventName; + for (var key in eventHash) { + this.once(key, eventHash[key]); + } + return this; + } else if (typeof eventName === "string" && typeof handlerToAttach === "function") { + var listener_1 = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + handlerToAttach.apply(void 0, __spread(args)); + _this.off(eventName, listener_1); + }; + this.on(eventName, listener_1); + } + return this; + }; + /** + * Checks whether an event has been attached to a component. + * @ko 컴포넌트에 이벤트가 등록됐는지 확인한다. + * @param {string} eventName The name of the event to be attached 등록 여부를 확인할 이벤트의 이름 + * @return {boolean} Indicates whether the event is attached. 이벤트 등록 여부 + * @example + * ```ts + * import Component from "@egjs/component"; + * + * class Some extends Component<{ + * hi: void; + * }> { + * some() { + * this.hasOn("hi");// check hi event. + * } + * } + * ``` + */ + __proto.hasOn = function (eventName) { + return !!this._eventHandler[eventName]; + }; + /** + * Attaches an event to a component. + * @ko 컴포넌트에 이벤트를 등록한다. + * @param {string} eventName The name of the event to be attached or an event name - event handler mapped object.등록할 이벤트의 이름 또는 이벤트 이름-핸들러 오브젝트 + * @param {function} handlerToAttach The handler function of the event to be attached 등록할 이벤트의 핸들러 함수 + * @return An instance of a component itself컴포넌트 자신의 인스턴스 + * @example + * ```ts + * import Component, { ComponentEvent } from "@egjs/component"; + * + * class Some extends Component<{ + * hi: void; + * }> { + * hi() { + * console.log("hi"); + * } + * some() { + * this.on("hi",this.hi); //attach event + * } + * } + * ``` + */ + __proto.on = function (eventName, handlerToAttach) { + if (typeof eventName === "object" && isUndefined(handlerToAttach)) { + var eventHash = eventName; + for (var name in eventHash) { + this.on(name, eventHash[name]); + } + return this; + } else if (typeof eventName === "string" && typeof handlerToAttach === "function") { + var handlerList = this._eventHandler[eventName]; + if (isUndefined(handlerList)) { + this._eventHandler[eventName] = []; + handlerList = this._eventHandler[eventName]; + } + handlerList.push(handlerToAttach); + } + return this; + }; + /** + * Detaches an event from the component.
If the `eventName` is not given this will detach all event handlers attached.
If the `handlerToDetach` is not given, this will detach all event handlers for `eventName`. + * @ko 컴포넌트에 등록된 이벤트를 해제한다.
`eventName`이 주어지지 않았을 경우 모든 이벤트 핸들러를 제거한다.
`handlerToAttach`가 주어지지 않았을 경우 `eventName`에 해당하는 모든 이벤트 핸들러를 제거한다. + * @param {string?} eventName The name of the event to be detached 해제할 이벤트의 이름 + * @param {function?} handlerToDetach The handler function of the event to be detached 해제할 이벤트의 핸들러 함수 + * @return An instance of a component itself 컴포넌트 자신의 인스턴스 + * @example + * ```ts + * import Component, { ComponentEvent } from "@egjs/component"; + * + * class Some extends Component<{ + * hi: void; + * }> { + * hi() { + * console.log("hi"); + * } + * some() { + * this.off("hi",this.hi); //detach event + * } + * } + * ``` + */ + __proto.off = function (eventName, handlerToDetach) { + var e_1, _a; + // Detach all event handlers. + if (isUndefined(eventName)) { + this._eventHandler = {}; + return this; + } + // Detach all handlers for eventname or detach event handlers by object. + if (isUndefined(handlerToDetach)) { + if (typeof eventName === "string") { + delete this._eventHandler[eventName]; + return this; + } else { + var eventHash = eventName; + for (var name in eventHash) { + this.off(name, eventHash[name]); + } + return this; + } + } + // Detach single event handler + var handlerList = this._eventHandler[eventName]; + if (handlerList) { + var idx = 0; + try { + for (var handlerList_1 = __values(handlerList), handlerList_1_1 = handlerList_1.next(); !handlerList_1_1.done; handlerList_1_1 = handlerList_1.next()) { + var handlerFunction = handlerList_1_1.value; + if (handlerFunction === handlerToDetach) { + handlerList.splice(idx, 1); + if (handlerList.length <= 0) { + delete this._eventHandler[eventName]; + } + break; + } + idx++; + } + } catch (e_1_1) { + e_1 = { + error: e_1_1 + }; + } finally { + try { + if (handlerList_1_1 && !handlerList_1_1.done && (_a = handlerList_1.return)) _a.call(handlerList_1); + } finally { + if (e_1) throw e_1.error; + } + } + } + return this; + }; + /** + * Version info string + * @ko 버전정보 문자열 + * @name VERSION + * @static + * @example + * Component.VERSION; // ex) 3.0.0 + * @memberof Component + */ + Component.VERSION = "3.0.4"; + return Component; + }(); + + /* + * Copyright (c) 2015 NAVER Corp. + * egjs projects are licensed under the MIT license + */ + // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-unsafe-assignment + var ComponentEvent$1 = ComponentEvent; + + /** + * Common utilities + * @module glMatrix + */ + // Configuration Constants + var EPSILON$1 = 0.000001; + var ARRAY_TYPE = typeof Float32Array !== 'undefined' ? Float32Array : Array; + if (!Math.hypot) Math.hypot = function () { + var y = 0, + i = arguments.length; + + while (i--) { + y += arguments[i] * arguments[i]; + } + + return Math.sqrt(y); + }; + + /** + * 3x3 Matrix + * @module mat3 + */ + + /** + * Creates a new identity mat3 + * + * @returns {mat3} a new 3x3 matrix + */ + + function create$5() { + var out = new ARRAY_TYPE(9); + + if (ARRAY_TYPE != Float32Array) { + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[5] = 0; + out[6] = 0; + out[7] = 0; + } + + out[0] = 1; + out[4] = 1; + out[8] = 1; + return out; + } + + /** + * 4x4 Matrix
Format: column-major, when typed out it looks like row-major
The matrices are being post multiplied. + * @module mat4 + */ + + /** + * Creates a new identity mat4 + * + * @returns {mat4} a new 4x4 matrix + */ + + function create$4() { + var out = new ARRAY_TYPE(16); + + if (ARRAY_TYPE != Float32Array) { + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + } + + out[0] = 1; + out[5] = 1; + out[10] = 1; + out[15] = 1; + return out; + } + /** + * Set a mat4 to the identity matrix + * + * @param {mat4} out the receiving matrix + * @returns {mat4} out + */ + + function identity$1(out) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = 1; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = 1; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Multiplies two mat4s + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the first operand + * @param {ReadonlyMat4} b the second operand + * @returns {mat4} out + */ + + function multiply$1(out, a, b) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a03 = a[3]; + var a10 = a[4], + a11 = a[5], + a12 = a[6], + a13 = a[7]; + var a20 = a[8], + a21 = a[9], + a22 = a[10], + a23 = a[11]; + var a30 = a[12], + a31 = a[13], + a32 = a[14], + a33 = a[15]; // Cache only the current line of the second matrix + + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3]; + out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + b0 = b[4]; + b1 = b[5]; + b2 = b[6]; + b3 = b[7]; + out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + b0 = b[8]; + b1 = b[9]; + b2 = b[10]; + b3 = b[11]; + out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + b0 = b[12]; + b1 = b[13]; + b2 = b[14]; + b3 = b[15]; + out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + return out; + } + /** + * Creates a matrix from a quaternion rotation, vector translation and vector scale + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.translate(dest, vec); + * let quatMat = mat4.create(); + * quat4.toMat4(quat, quatMat); + * mat4.multiply(dest, quatMat); + * mat4.scale(dest, scale) + * + * @param {mat4} out mat4 receiving operation result + * @param {quat4} q Rotation quaternion + * @param {ReadonlyVec3} v Translation vector + * @param {ReadonlyVec3} s Scaling vector + * @returns {mat4} out + */ + + function fromRotationTranslationScale(out, q, v, s) { + // Quaternion math + var x = q[0], + y = q[1], + z = q[2], + w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var xy = x * y2; + var xz = x * z2; + var yy = y * y2; + var yz = y * z2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + var sx = s[0]; + var sy = s[1]; + var sz = s[2]; + out[0] = (1 - (yy + zz)) * sx; + out[1] = (xy + wz) * sx; + out[2] = (xz - wy) * sx; + out[3] = 0; + out[4] = (xy - wz) * sy; + out[5] = (1 - (xx + zz)) * sy; + out[6] = (yz + wx) * sy; + out[7] = 0; + out[8] = (xz + wy) * sz; + out[9] = (yz - wx) * sz; + out[10] = (1 - (xx + yy)) * sz; + out[11] = 0; + out[12] = v[0]; + out[13] = v[1]; + out[14] = v[2]; + out[15] = 1; + return out; + } + /** + * Generates a perspective projection matrix with the given bounds. + * The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1], + * which matches WebGL/OpenGL's clip volume. + * Passing null/undefined/no value for far will generate infinite projection matrix. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {number} fovy Vertical field of view in radians + * @param {number} aspect Aspect ratio. typically viewport width/height + * @param {number} near Near bound of the frustum + * @param {number} far Far bound of the frustum, can be null or Infinity + * @returns {mat4} out + */ + + function perspectiveNO(out, fovy, aspect, near, far) { + var f = 1.0 / Math.tan(fovy / 2), + nf; + out[0] = f / aspect; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = f; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[11] = -1; + out[12] = 0; + out[13] = 0; + out[15] = 0; + + if (far != null && far !== Infinity) { + nf = 1 / (near - far); + out[10] = (far + near) * nf; + out[14] = 2 * far * near * nf; + } else { + out[10] = -1; + out[14] = -2 * near; + } + + return out; + } + /** + * Alias for {@link mat4.perspectiveNO} + * @function + */ + + var perspective = perspectiveNO; + /** + * Generates a look-at matrix with the given eye position, focal point, and up axis. + * If you want a matrix that actually makes an object look at another object, you should use targetTo instead. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {ReadonlyVec3} eye Position of the viewer + * @param {ReadonlyVec3} center Point the viewer is looking at + * @param {ReadonlyVec3} up vec3 pointing up + * @returns {mat4} out + */ + + function lookAt(out, eye, center, up) { + var x0, x1, x2, y0, y1, y2, z0, z1, z2, len; + var eyex = eye[0]; + var eyey = eye[1]; + var eyez = eye[2]; + var upx = up[0]; + var upy = up[1]; + var upz = up[2]; + var centerx = center[0]; + var centery = center[1]; + var centerz = center[2]; + + if (Math.abs(eyex - centerx) < EPSILON$1 && Math.abs(eyey - centery) < EPSILON$1 && Math.abs(eyez - centerz) < EPSILON$1) { + return identity$1(out); + } + + z0 = eyex - centerx; + z1 = eyey - centery; + z2 = eyez - centerz; + len = 1 / Math.hypot(z0, z1, z2); + z0 *= len; + z1 *= len; + z2 *= len; + x0 = upy * z2 - upz * z1; + x1 = upz * z0 - upx * z2; + x2 = upx * z1 - upy * z0; + len = Math.hypot(x0, x1, x2); + + if (!len) { + x0 = 0; + x1 = 0; + x2 = 0; + } else { + len = 1 / len; + x0 *= len; + x1 *= len; + x2 *= len; + } + + y0 = z1 * x2 - z2 * x1; + y1 = z2 * x0 - z0 * x2; + y2 = z0 * x1 - z1 * x0; + len = Math.hypot(y0, y1, y2); + + if (!len) { + y0 = 0; + y1 = 0; + y2 = 0; + } else { + len = 1 / len; + y0 *= len; + y1 *= len; + y2 *= len; + } + + out[0] = x0; + out[1] = y0; + out[2] = z0; + out[3] = 0; + out[4] = x1; + out[5] = y1; + out[6] = z1; + out[7] = 0; + out[8] = x2; + out[9] = y2; + out[10] = z2; + out[11] = 0; + out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez); + out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez); + out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez); + out[15] = 1; + return out; + } + + /** + * 3 Dimensional Vector + * @module vec3 + */ + + /** + * Creates a new, empty vec3 + * + * @returns {vec3} a new 3D vector + */ + + function create$3() { + var out = new ARRAY_TYPE(3); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + } + + return out; + } + /** + * Calculates the length of a vec3 + * + * @param {ReadonlyVec3} a vector to calculate length of + * @returns {Number} length of a + */ + + function length(a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + return Math.hypot(x, y, z); + } + /** + * Creates a new vec3 initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @returns {vec3} a new 3D vector + */ + + function fromValues$3(x, y, z) { + var out = new ARRAY_TYPE(3); + out[0] = x; + out[1] = y; + out[2] = z; + return out; + } + /** + * Copy the values from one vec3 to another + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the source vector + * @returns {vec3} out + */ + + function copy$2(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + return out; + } + /** + * Subtracts vector b from vector a + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function subtract(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + return out; + } + /** + * Scales a vec3 by a scalar number + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to scale + * @param {Number} b amount to scale the vector by + * @returns {vec3} out + */ + + function scale(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + return out; + } + /** + * Normalize a vec3 + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a vector to normalize + * @returns {vec3} out + */ + + function normalize$2(out, a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + var len = x * x + y * y + z * z; + + if (len > 0) { + //TODO: evaluate use of glm_invsqrt here? + len = 1 / Math.sqrt(len); + } + + out[0] = a[0] * len; + out[1] = a[1] * len; + out[2] = a[2] * len; + return out; + } + /** + * Calculates the dot product of two vec3's + * + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {Number} dot product of a and b + */ + + function dot(a, b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; + } + /** + * Computes the cross product of two vec3's + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function cross(out, a, b) { + var ax = a[0], + ay = a[1], + az = a[2]; + var bx = b[0], + by = b[1], + bz = b[2]; + out[0] = ay * bz - az * by; + out[1] = az * bx - ax * bz; + out[2] = ax * by - ay * bx; + return out; + } + /** + * Transforms the vec3 with a mat4. + * 4th vector component is implicitly '1' + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to transform + * @param {ReadonlyMat4} m matrix to transform with + * @returns {vec3} out + */ + + function transformMat4(out, a, m) { + var x = a[0], + y = a[1], + z = a[2]; + var w = m[3] * x + m[7] * y + m[11] * z + m[15]; + w = w || 1.0; + out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w; + out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w; + out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w; + return out; + } + /** + * Transforms the vec3 with a quat + * Can also be used for dual quaternions. (Multiply it with the real part) + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to transform + * @param {ReadonlyQuat} q quaternion to transform with + * @returns {vec3} out + */ + + function transformQuat(out, a, q) { + // benchmarks: https://jsperf.com/quaternion-transform-vec3-implementations-fixed + var qx = q[0], + qy = q[1], + qz = q[2], + qw = q[3]; + var x = a[0], + y = a[1], + z = a[2]; // var qvec = [qx, qy, qz]; + // var uv = vec3.cross([], qvec, a); + + var uvx = qy * z - qz * y, + uvy = qz * x - qx * z, + uvz = qx * y - qy * x; // var uuv = vec3.cross([], qvec, uv); + + var uuvx = qy * uvz - qz * uvy, + uuvy = qz * uvx - qx * uvz, + uuvz = qx * uvy - qy * uvx; // vec3.scale(uv, uv, 2 * w); + + var w2 = qw * 2; + uvx *= w2; + uvy *= w2; + uvz *= w2; // vec3.scale(uuv, uuv, 2); + + uuvx *= 2; + uuvy *= 2; + uuvz *= 2; // return vec3.add(out, a, vec3.add(out, uv, uuv)); + + out[0] = x + uvx + uuvx; + out[1] = y + uvy + uuvy; + out[2] = z + uvz + uuvz; + return out; + } + /** + * Alias for {@link vec3.length} + * @function + */ + + var len = length; + /** + * Perform some operation over an array of vec3s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ + + (function () { + var vec = create$3(); + return function (a, stride, offset, count, fn, arg) { + var i, l; + + if (!stride) { + stride = 3; + } + + if (!offset) { + offset = 0; + } + + if (count) { + l = Math.min(count * stride + offset, a.length); + } else { + l = a.length; + } + + for (i = offset; i < l; i += stride) { + vec[0] = a[i]; + vec[1] = a[i + 1]; + vec[2] = a[i + 2]; + fn(vec, vec, arg); + a[i] = vec[0]; + a[i + 1] = vec[1]; + a[i + 2] = vec[2]; + } + + return a; + }; + })(); + + /** + * 4 Dimensional Vector + * @module vec4 + */ + + /** + * Creates a new, empty vec4 + * + * @returns {vec4} a new 4D vector + */ + + function create$2() { + var out = new ARRAY_TYPE(4); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 0; + } + + return out; + } + /** + * Creates a new vec4 initialized with values from an existing vector + * + * @param {ReadonlyVec4} a vector to clone + * @returns {vec4} a new 4D vector + */ + + function clone$1(a) { + var out = new ARRAY_TYPE(4); + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + return out; + } + /** + * Creates a new vec4 initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {vec4} a new 4D vector + */ + + function fromValues$2(x, y, z, w) { + var out = new ARRAY_TYPE(4); + out[0] = x; + out[1] = y; + out[2] = z; + out[3] = w; + return out; + } + /** + * Copy the values from one vec4 to another + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the source vector + * @returns {vec4} out + */ + + function copy$1(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + return out; + } + /** + * Set the components of a vec4 to the given values + * + * @param {vec4} out the receiving vector + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {vec4} out + */ + + function set$1(out, x, y, z, w) { + out[0] = x; + out[1] = y; + out[2] = z; + out[3] = w; + return out; + } + /** + * Normalize a vec4 + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a vector to normalize + * @returns {vec4} out + */ + + function normalize$1(out, a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + var w = a[3]; + var len = x * x + y * y + z * z + w * w; + + if (len > 0) { + len = 1 / Math.sqrt(len); + } + + out[0] = x * len; + out[1] = y * len; + out[2] = z * len; + out[3] = w * len; + return out; + } + /** + * Returns whether or not the vectors have approximately the same elements in the same position. + * + * @param {ReadonlyVec4} a The first vector. + * @param {ReadonlyVec4} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + function equals$1(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3]; + return Math.abs(a0 - b0) <= EPSILON$1 * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON$1 * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON$1 * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON$1 * Math.max(1.0, Math.abs(a3), Math.abs(b3)); + } + /** + * Perform some operation over an array of vec4s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ + + (function () { + var vec = create$2(); + return function (a, stride, offset, count, fn, arg) { + var i, l; + + if (!stride) { + stride = 4; + } + + if (!offset) { + offset = 0; + } + + if (count) { + l = Math.min(count * stride + offset, a.length); + } else { + l = a.length; + } + + for (i = offset; i < l; i += stride) { + vec[0] = a[i]; + vec[1] = a[i + 1]; + vec[2] = a[i + 2]; + vec[3] = a[i + 3]; + fn(vec, vec, arg); + a[i] = vec[0]; + a[i + 1] = vec[1]; + a[i + 2] = vec[2]; + a[i + 3] = vec[3]; + } + + return a; + }; + })(); + + /** + * Quaternion + * @module quat + */ + + /** + * Creates a new identity quat + * + * @returns {quat} a new quaternion + */ + + function create$1() { + var out = new ARRAY_TYPE(4); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + } + + out[3] = 1; + return out; + } + /** + * Set a quat to the identity quaternion + * + * @param {quat} out the receiving quaternion + * @returns {quat} out + */ + + function identity(out) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 1; + return out; + } + /** + * Sets a quat from the given angle and rotation axis, + * then returns it. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyVec3} axis the axis around which to rotate + * @param {Number} rad the angle in radians + * @returns {quat} out + **/ + + function setAxisAngle(out, axis, rad) { + rad = rad * 0.5; + var s = Math.sin(rad); + out[0] = s * axis[0]; + out[1] = s * axis[1]; + out[2] = s * axis[2]; + out[3] = Math.cos(rad); + return out; + } + /** + * Multiplies two quat's + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @returns {quat} out + */ + + function multiply(out, a, b) { + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bx = b[0], + by = b[1], + bz = b[2], + bw = b[3]; + out[0] = ax * bw + aw * bx + ay * bz - az * by; + out[1] = ay * bw + aw * by + az * bx - ax * bz; + out[2] = az * bw + aw * bz + ax * by - ay * bx; + out[3] = aw * bw - ax * bx - ay * by - az * bz; + return out; + } + /** + * Rotates a quaternion by the given angle about the X axis + * + * @param {quat} out quat receiving operation result + * @param {ReadonlyQuat} a quat to rotate + * @param {number} rad angle (in radians) to rotate + * @returns {quat} out + */ + + function rotateX(out, a, rad) { + rad *= 0.5; + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bx = Math.sin(rad), + bw = Math.cos(rad); + out[0] = ax * bw + aw * bx; + out[1] = ay * bw + az * bx; + out[2] = az * bw - ay * bx; + out[3] = aw * bw - ax * bx; + return out; + } + /** + * Rotates a quaternion by the given angle about the Y axis + * + * @param {quat} out quat receiving operation result + * @param {ReadonlyQuat} a quat to rotate + * @param {number} rad angle (in radians) to rotate + * @returns {quat} out + */ + + function rotateY(out, a, rad) { + rad *= 0.5; + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var by = Math.sin(rad), + bw = Math.cos(rad); + out[0] = ax * bw - az * by; + out[1] = ay * bw + aw * by; + out[2] = az * bw + ax * by; + out[3] = aw * bw - ay * by; + return out; + } + /** + * Rotates a quaternion by the given angle about the Z axis + * + * @param {quat} out quat receiving operation result + * @param {ReadonlyQuat} a quat to rotate + * @param {number} rad angle (in radians) to rotate + * @returns {quat} out + */ + + function rotateZ(out, a, rad) { + rad *= 0.5; + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bz = Math.sin(rad), + bw = Math.cos(rad); + out[0] = ax * bw + ay * bz; + out[1] = ay * bw - ax * bz; + out[2] = az * bw + aw * bz; + out[3] = aw * bw - az * bz; + return out; + } + /** + * Performs a spherical linear interpolation between two quat + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {quat} out + */ + + function slerp(out, a, b, t) { + // benchmarks: + // http://jsperf.com/quaternion-slerp-implementations + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bx = b[0], + by = b[1], + bz = b[2], + bw = b[3]; + var omega, cosom, sinom, scale0, scale1; // calc cosine + + cosom = ax * bx + ay * by + az * bz + aw * bw; // adjust signs (if necessary) + + if (cosom < 0.0) { + cosom = -cosom; + bx = -bx; + by = -by; + bz = -bz; + bw = -bw; + } // calculate coefficients + + + if (1.0 - cosom > EPSILON$1) { + // standard case (slerp) + omega = Math.acos(cosom); + sinom = Math.sin(omega); + scale0 = Math.sin((1.0 - t) * omega) / sinom; + scale1 = Math.sin(t * omega) / sinom; + } else { + // "from" and "to" quaternions are very close + // ... so we can do a linear interpolation + scale0 = 1.0 - t; + scale1 = t; + } // calculate final values + + + out[0] = scale0 * ax + scale1 * bx; + out[1] = scale0 * ay + scale1 * by; + out[2] = scale0 * az + scale1 * bz; + out[3] = scale0 * aw + scale1 * bw; + return out; + } + /** + * Creates a quaternion from the given 3x3 rotation matrix. + * + * NOTE: The resultant quaternion is not normalized, so you should be sure + * to renormalize the quaternion yourself where necessary. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyMat3} m rotation matrix + * @returns {quat} out + * @function + */ + + function fromMat3(out, m) { + // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes + // article "Quaternion Calculus and Fast Animation". + var fTrace = m[0] + m[4] + m[8]; + var fRoot; + + if (fTrace > 0.0) { + // |w| > 1/2, may as well choose w > 1/2 + fRoot = Math.sqrt(fTrace + 1.0); // 2w + + out[3] = 0.5 * fRoot; + fRoot = 0.5 / fRoot; // 1/(4w) + + out[0] = (m[5] - m[7]) * fRoot; + out[1] = (m[6] - m[2]) * fRoot; + out[2] = (m[1] - m[3]) * fRoot; + } else { + // |w| <= 1/2 + var i = 0; + if (m[4] > m[0]) i = 1; + if (m[8] > m[i * 3 + i]) i = 2; + var j = (i + 1) % 3; + var k = (i + 2) % 3; + fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1.0); + out[i] = 0.5 * fRoot; + fRoot = 0.5 / fRoot; + out[3] = (m[j * 3 + k] - m[k * 3 + j]) * fRoot; + out[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot; + out[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot; + } + + return out; + } + /** + * Creates a new quat initialized with values from an existing quaternion + * + * @param {ReadonlyQuat} a quaternion to clone + * @returns {quat} a new quaternion + * @function + */ + + var clone = clone$1; + /** + * Creates a new quat initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {quat} a new quaternion + * @function + */ + + var fromValues$1 = fromValues$2; + /** + * Copy the values from one quat to another + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the source quaternion + * @returns {quat} out + * @function + */ + + var copy = copy$1; + /** + * Set the components of a quat to the given values + * + * @param {quat} out the receiving quaternion + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {quat} out + * @function + */ + + var set = set$1; + /** + * Normalize a quat + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a quaternion to normalize + * @returns {quat} out + * @function + */ + + var normalize = normalize$1; + /** + * Returns whether or not the quaternions have approximately the same elements in the same position. + * + * @param {ReadonlyQuat} a The first vector. + * @param {ReadonlyQuat} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + var equals = equals$1; + /** + * Sets a quaternion to represent the shortest rotation from one + * vector to another. + * + * Both vectors are assumed to be unit length. + * + * @param {quat} out the receiving quaternion. + * @param {ReadonlyVec3} a the initial vector + * @param {ReadonlyVec3} b the destination vector + * @returns {quat} out + */ + + (function () { + var tmpvec3 = create$3(); + var xUnitVec3 = fromValues$3(1, 0, 0); + var yUnitVec3 = fromValues$3(0, 1, 0); + return function (out, a, b) { + var dot$1 = dot(a, b); + + if (dot$1 < -0.999999) { + cross(tmpvec3, xUnitVec3, a); + if (len(tmpvec3) < 0.000001) cross(tmpvec3, yUnitVec3, a); + normalize$2(tmpvec3, tmpvec3); + setAxisAngle(out, tmpvec3, Math.PI); + return out; + } else if (dot$1 > 0.999999) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 1; + return out; + } else { + cross(tmpvec3, a, b); + out[0] = tmpvec3[0]; + out[1] = tmpvec3[1]; + out[2] = tmpvec3[2]; + out[3] = 1 + dot$1; + return normalize(out, out); + } + }; + })(); + /** + * Performs a spherical linear interpolation with two control points + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @param {ReadonlyQuat} c the third operand + * @param {ReadonlyQuat} d the fourth operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {quat} out + */ + + (function () { + var temp1 = create$1(); + var temp2 = create$1(); + return function (out, a, b, c, d, t) { + slerp(temp1, a, d, t); + slerp(temp2, b, c, t); + slerp(out, temp1, temp2, 2 * t * (1 - t)); + return out; + }; + })(); + /** + * Sets the specified quaternion with values corresponding to the given + * axes. Each axis is a vec3 and is expected to be unit length and + * perpendicular to all other specified axes. + * + * @param {ReadonlyVec3} view the vector representing the viewing direction + * @param {ReadonlyVec3} right the vector representing the local "right" direction + * @param {ReadonlyVec3} up the vector representing the local "up" direction + * @returns {quat} out + */ + + (function () { + var matr = create$5(); + return function (out, view, right, up) { + matr[0] = right[0]; + matr[3] = right[1]; + matr[6] = right[2]; + matr[1] = up[0]; + matr[4] = up[1]; + matr[7] = up[2]; + matr[2] = -view[0]; + matr[5] = -view[1]; + matr[8] = -view[2]; + return normalize(out, fromMat3(out, matr)); + }; + })(); + + /** + * 2 Dimensional Vector + * @module vec2 + */ + + /** + * Creates a new, empty vec2 + * + * @returns {vec2} a new 2D vector + */ + + function create() { + var out = new ARRAY_TYPE(2); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + } + + return out; + } + /** + * Creates a new vec2 initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @returns {vec2} a new 2D vector + */ + + function fromValues(x, y) { + var out = new ARRAY_TYPE(2); + out[0] = x; + out[1] = y; + return out; + } + /** + * Perform some operation over an array of vec2s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ + + (function () { + var vec = create(); + return function (a, stride, offset, count, fn, arg) { + var i, l; + + if (!stride) { + stride = 2; + } + + if (!offset) { + offset = 0; + } + + if (count) { + l = Math.min(count * stride + offset, a.length); + } else { + l = a.length; + } + + for (i = offset; i < l; i += stride) { + vec[0] = a[i]; + vec[1] = a[i + 1]; + fn(vec, vec, arg); + a[i] = vec[0]; + a[i + 1] = vec[1]; + } + + return a; + }; + })(); + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Error thrown by {@link View360} + * @ko {@link View360}이 발생시킨 에러 + * @since 4.0.0 + */ + class View360Error extends Error { + /** + * Create new instance of View360Error + * @ko View360Error의 인스턴스를 생성합니다. + * @param message - Error message {@ko 에러 메시지} + * @param code - Error code {@ko 에러 코드} + */ + constructor(message, code) { + super(message); + Object.setPrototypeOf(this, View360Error.prototype); + this.name = "View360Error"; + this.code = code; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Error codes of {@link View360Error} + * @ko {@link View360Error}가 가질 수 있는 에러 코드 값들 + * @since 4.0.0 + */ + const ERROR_CODES = { + /** + * The given value's type is not expected + * @ko 주어진 값의 타입이 잘못되었을 경우 + * @since 4.0.0 + */ + WRONG_TYPE: 0, + /** + * The given value is not a supported option + * @ko 잘못된 옵션을 받았을 경우 + * @since 4.0.0 + */ + WRONG_OPTION: 1, + /** + * The element with given CSS selector does not exist + * @ko 주어진 CSS 셀렉터로 엘리먼트를 찾지 못했을 경우 + * @since 4.0.0 + */ + ELEMENT_NOT_FOUND: 2, + /** + * Couldn't find canvas element inside the given container element. + * @ko 컨테이너 엘리먼트 내부에서 캔버스 엘리먼트를 찾지 못했을 경우 + * @since 4.0.0 + */ + CANVAS_NOT_FOUND: 3, + /** + * The browser does not support WebGL + * @ko 브라우저가 WebGL을 지원하지 않는 경우 + * @since 4.0.0 + */ + WEBGL_NOT_SUPPORTED: 4, + /** + * Failed creating canvas 2D context + * @ko 캔버스 2D 컨텍스트를 생성하지 못한 경우 + * @since 4.0.0 + */ + FAILED_CREATE_CONTEXT_2D: 5, + /** + * `init()` is called before setting {@link View360Options#projection} + * @ko {@link View360Options#projection}을 설정하기 전에 `init()`이 호출된 경우 + * @since 4.0.0 + */ + PROVIDE_PROJECTION_FIRST: 6, + /** + * Failed linking WebGL program. Only can be thrown when {@link View360Options#debug} is `true`. + * @ko WebGL 프로그램 링크에 실패한 경우. {@link View360Options#debug}를 `true`로 설정한 경우에만 발생할 수 있습니다. + * @since 4.0.0 + */ + FAILED_LINKING_PROGRAM: 7, + /** + * Arguments are not sufficient for the given property. + * @ko 프로퍼티에 값이 충분히 주어지지 않았을 때 + * @since 4.0.0 + */ + INSUFFICIENT_ARGS: 8 + }; + const MESSAGES = { + WRONG_TYPE: (val, types) => `${typeof val} is not a ${types.map(type => `"${type}"`).join(" or ")}.`, + WRONG_OPTION: (val, optionName) => `Bad option: given "${val}" for option "${optionName}".`, + ELEMENT_NOT_FOUND: query => `Element with selector "${query}" not found.`, + CANVAS_NOT_FOUND: "The canvas element was not found inside the given root element.", + WEBGL_NOT_SUPPORTED: "WebGL is not supported on this browser.", + FAILED_CREATE_CONTEXT_2D: "Failed to create canvas 2D context", + PROVIDE_PROJECTION_FIRST: "\"projection\" should be provided before initialization.", + FAILED_LINKING_PROGRAM: (msg, shaderLog) => `Failed linking WebGL program - "${msg}\nShader compile Log: ${shaderLog}`, + INSUFFICIENT_ARGS: (val, name) => `Insufficient arguments: given "${val}" for "${name}".` + }; + var ERROR = { + CODES: ERROR_CODES, + MESSAGES + }; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + const EVENTS$1 = { + MOUSE_DOWN: "mousedown", + MOUSE_MOVE: "mousemove", + MOUSE_UP: "mouseup", + TOUCH_START: "touchstart", + TOUCH_MOVE: "touchmove", + TOUCH_END: "touchend", + WHEEL: "wheel", + RESIZE: "resize", + CONTEXT_MENU: "contextmenu", + MOUSE_ENTER: "mouseenter", + MOUSE_LEAVE: "mouseleave", + POINTER_DOWN: "pointerdown", + POINTER_MOVE: "pointermove", + POINTER_UP: "pointerup", + POINTER_CANCEL: "pointercancel", + POINTER_ENTER: "pointerenter", + POINTER_LEAVE: "pointerleave", + KEY_DOWN: "keydown", + KEY_UP: "keyup", + LOAD: "load", + ERROR: "error", + CLICK: "click", + DOUBLE_CLICK: "dblclick", + CONTEXT_CREATE_ERROR: "webglcontextcreationerror", + CONTEXT_LOST: "webglcontextlost", + CONTEXT_RESTORED: "webglcontextrestored", + DEVICE_ORIENTATION: "deviceorientation", + DEVICE_MOTION: "devicemotion", + ORIENTATION_CHANGE: "orientationchange", + VIDEO_PLAY: "play", + VIDEO_PAUSE: "pause", + VIDEO_LOADED_DATA: "loadeddata", + VIDEO_VOLUME_CHANGE: "volumechange", + VIDEO_TIME_UPDATE: "timeupdate", + VIDEO_DURATION_CHANGE: "durationchange", + VIDEO_CAN_PLAYTHROUGH: "canplaythrough", + TRANSITION_END: "transitionend", + XR_END: "end" + }; + const EL_DIV = "div"; + const EL_BUTTON = "button"; + // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button + var MOUSE_BUTTON; + (function (MOUSE_BUTTON) { + MOUSE_BUTTON[MOUSE_BUTTON["LEFT"] = 0] = "LEFT"; + MOUSE_BUTTON[MOUSE_BUTTON["MIDDLE"] = 1] = "MIDDLE"; + MOUSE_BUTTON[MOUSE_BUTTON["RIGHT"] = 2] = "RIGHT"; + })(MOUSE_BUTTON || (MOUSE_BUTTON = {})); + const CURSOR = { + GRAB: "grab", + GRABBING: "grabbing", + NONE: "" + }; + const KEY_DIRECTION = ["LEFT", "UP", "RIGHT", "DOWN"]; + var DIRECTION_KEY_CODE; + (function (DIRECTION_KEY_CODE) { + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["LEFT"] = 37] = "LEFT"; + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["UP"] = 38] = "UP"; + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["RIGHT"] = 39] = "RIGHT"; + DIRECTION_KEY_CODE[DIRECTION_KEY_CODE["DOWN"] = 40] = "DOWN"; + })(DIRECTION_KEY_CODE || (DIRECTION_KEY_CODE = {})); + const SPACE_KEY_CODE = 32; + const DIRECTION_KEY_NAME = { + LEFT: "ArrowLeft", + UP: "ArrowUp", + RIGHT: "ArrowRight", + DOWN: "ArrowDown" + }; + const SPACE_KEY_NAME = " "; + const FULLSCREEN_REQUEST = ["requestFullscreen", "webkitRequestFullscreen", "webkitRequestFullScreen", "webkitCancelFullScreen", "mozRequestFullScreen", "msRequestFullscreen"]; + const FULLSCREEN_ELEMENT = ["fullscreenElement", "webkitFullscreenElement", "webkitCurrentFullScreenElement", "mozFullScreenElement", "msFullscreenElement"]; + const FULLSCREEN_EXIT = ["exitFullscreen", "webkitExitFullscreen", "webkitCancelFullScreen", "mozCancelFullScreen", "msExitFullscreen"]; + const FULLSCREEN_CHANGE = ["fullscreenchange", "webkitfullscreenchange", "mozfullscreenchange", "MSFullscreenChange"]; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Default class names + * @ko 기본 클래스 이름들 + * @since 4.0.0 + */ + const DEFAULT_CLASS = { + CONTAINER: "view360-container", + CANVAS: "view360-canvas", + CTX_LOST: "view360-ctx-lost", + IN_VR: "view360-vr-presenting", + HOTSPOT_CONTAINER: "view360-hotspots", + HOTSPOT: "view360-hotspot", + HOTSPOT_VISIBLE: "view360-hotspot-visible", + HOTSPOT_FLIP_X: "view360-hotspot-flip-x", + HOTSPOT_FLIP_Y: "view360-hotspot-flip-y" + }; + /** + * Event names + * @ko 이벤트 이름들 + * @since 4.0.0 + * @example + * ```ts + * import View360, { EVENTS } from "@egjs/view360"; + * + * const viewer = new View360("#el_id"); + * + * viewer.on(EVENTS.READY, evt => { + * console.log("View360 is ready!"); + * }); + * ``` + */ + const EVENTS = { + READY: "ready", + LOAD_START: "loadStart", + LOAD: "load", + PROJECTION_CHANGE: "projectionChange", + RESIZE: "resize", + BEFORE_RENDER: "beforeRender", + RENDER: "render", + INPUT_START: "inputStart", + INPUT_END: "inputEnd", + VIEW_CHANGE: "viewChange", + STATIC_CLICK: "staticClick", + VR_START: "vrStart", + VR_END: "vrEnd" + }; + /** + * Collection of predefined easing functions + * @ko 미리 정의된 easing 함수들 + */ + const EASING = { + LINEAR: x => x, + SINE_WAVE: x => Math.sin(x * Math.PI * 2), + EASE_OUT_CUBIC: x => 1 - Math.pow(1 - x, 3), + EASE_OUT_BOUNCE: x => { + const n1 = 7.5625; + const d1 = 2.75; + if (x < 1 / d1) { + return n1 * x * x; + } else if (x < 2 / d1) { + return n1 * (x -= 1.5 / d1) * x + 0.75; + } else if (x < 2.5 / d1) { + return n1 * (x -= 2.25 / d1) * x + 0.9375; + } else { + return n1 * (x -= 2.625 / d1) * x + 0.984375; + } + } + }; + + var _a; + const CAMERA_EVENTS = { + CHANGE: "change", + ANIMATION_END: "animationEnd" + }; + const CONTROL_EVENTS = { + INPUT_START: "inputStart", + CHANGE: "change", + INPUT_END: "inputEnd", + ENABLE: "enable", + DISABLE: "disable", + STATIC_CLICK: "staticClick" + }; + const DEG_TO_RAD = Math.PI / 180; + const RAD_TO_DEG = 180 / Math.PI; + const DEFAULT_EASING = EASING.EASE_OUT_CUBIC; + const DEFAULT_ANIMATION_DURATION = 300; + const INFINITE_RANGE = { + min: -Infinity, + max: Infinity + }; + const DEFAULT_PITCH_RANGE = { + min: -90, + max: 90 + }; + const DEFAULT_ZOOM_RANGE = { + min: 0.6, + max: 10 + }; + var ROTATE; + (function (ROTATE) { + ROTATE[ROTATE["ZERO"] = 0] = "ZERO"; + ROTATE[ROTATE["CW_90"] = 1] = "CW_90"; + ROTATE[ROTATE["CCW_90"] = 2] = "CCW_90"; + ROTATE[ROTATE["CW_180"] = 3] = "CW_180"; + })(ROTATE || (ROTATE = {})); + // Custom event name for video time change + const VIDEO_TIME_CHANGE_EVENT = "view360videotimechange"; + const SVG_NAMESPACE = "http://www.w3.org/2000/svg"; + const SESSION_VR = "immersive-vr"; + const XR_REFERENCE_SPACE = "local"; + const EPSILON = (_a = Number.EPSILON) !== null && _a !== void 0 ? _a : 2.220446049250313e-16; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + const isString = val => typeof val === "string"; + const isElement = val => !!val && val.nodeType === Node.ELEMENT_NODE; + const createElement = (className, tag = EL_DIV) => { + const el = document.createElement(tag); + el.classList.add(className); + return el; + }; + const getNullableElement = (el, parent) => { + let targetEl = null; + if (isString(el)) { + const parentEl = parent ? parent : document; + const queryResult = parentEl.querySelector(el); + if (!queryResult) { + return null; + } + targetEl = queryResult; + } else if (isElement(el)) { + targetEl = el; + } + return targetEl; + }; + const getElement = (el, parent) => { + const targetEl = getNullableElement(el, parent); + if (!targetEl) { + if (isString(el)) { + throw new View360Error(ERROR.MESSAGES.ELEMENT_NOT_FOUND(el), ERROR.CODES.ELEMENT_NOT_FOUND); + } else { + throw new View360Error(ERROR.MESSAGES.WRONG_TYPE(el, ["HTMLElement", "string"]), ERROR.CODES.WRONG_TYPE); + } + } + return targetEl; + }; + const findCanvas = (root, selector) => { + const canvas = root.querySelector(selector); + if (!canvas) { + throw new View360Error(ERROR.MESSAGES.CANVAS_NOT_FOUND, ERROR.CODES.CANVAS_NOT_FOUND); + } + return canvas; + }; + const range = end => { + if (!end || end <= 0) { + return []; + } + return Array.apply(0, Array(end)).map((undef, idx) => idx); + }; + const clamp = (x, min, max) => Math.max(Math.min(x, max), min); + // Linear interpolation between a and b + const lerp = (a, b, t) => { + return a * (1 - t) + b * t; + }; + const circulate = (val, min, max) => { + const size = Math.abs(max - min); + if (val < min) { + const offset = (min - val) % size; + val = max - offset; + } else if (val > max) { + const offset = (val - max) % size; + val = min + offset; + } + return val; + }; + // eslint-disable-next-line @typescript-eslint/ban-types + const merge = (target, ...srcs) => { + srcs.forEach(source => { + Object.keys(source).forEach(key => { + const value = source[key]; + if (Array.isArray(target[key]) && Array.isArray(value)) { + target[key] = [...target[key], ...value]; + } else { + target[key] = value; + } + }); + }); + return target; + }; + const findIndex = (array, checker) => { + for (let idx = 0; idx < array.length; idx++) { + if (checker(array[idx])) { + return idx; + } + } + return -1; + }; + const getObjectOption = val => typeof val === "object" ? val : {}; + const toVerticalFov = (fovRadian, aspect) => { + return Math.atan(Math.tan(fovRadian * 0.5) / aspect) * 2; + }; + const reorderCube = (arr, order, defaultOrder = "RLUDFB") => { + return defaultOrder.split("").map(face => order.indexOf(face)).map(index => arr[index]); + }; + const isFullscreen = () => { + if (!document) return false; + for (const key of FULLSCREEN_ELEMENT) { + if (document[key]) return true; + } + return false; + }; + const sensorCanBeEnabledIOS = () => { + return !!DeviceMotionEvent && "requestPermission" in DeviceMotionEvent && window.isSecureContext; + }; + const hfovToZoom = (baseFov, fov) => { + const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5); + const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5); + return renderingWidth / zoomedWidth; + }; + const eulerToQuat = (out, yaw, pitch, roll) => { + identity(out); + const pitchThreshold = 0.01; + const pitchClamped = clamp(pitch, -90 + pitchThreshold, 90 - pitchThreshold); + rotateY(out, out, yaw * DEG_TO_RAD); + rotateX(out, out, pitchClamped * DEG_TO_RAD); + rotateZ(out, out, roll * DEG_TO_RAD); + return out; + }; + /** + * Extract euler angles from the quaternion, except roll(z-axis rotation) + * @hidden + */ + const quatToEuler = quaternion => { + const x = quaternion[0]; + const y = quaternion[1]; + const z = quaternion[2]; + const w = quaternion[3]; + const x2 = x * x; + const y2 = y * y; + const z2 = z * z; + const w2 = w * w; + const unit = x2 + y2 + z2 + w2; + const test = x * w - y * z; + let pitch, yaw; + if (test > 0.499995 * unit) { + // singularity at the north pole + pitch = Math.PI / 2; + yaw = 2 * Math.atan2(y, x); + } else if (test < -0.499995 * unit) { + // singularity at the south pole + pitch = -Math.PI / 2; + yaw = -2 * Math.atan2(y, x); + } else { + const view = fromValues$3(0, 0, 1); + const up = fromValues$3(0, 1, 0); + transformQuat(view, view, quaternion); + transformQuat(up, up, quaternion); + const viewXZ = Math.sqrt(view[0] * view[0] + view[2] * view[2]); + pitch = Math.atan2(-view[1], viewXZ); + yaw = Math.atan2(view[0], view[2]); + } + return { + pitch: clamp(pitch * RAD_TO_DEG, -90, 90), + yaw: circulate(yaw * RAD_TO_DEG, 0, 360) + }; + }; + + /* + * Copyright (c) 2020 NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Interpolator between two values with duration + * @ko 특정 시간동안 두 값을 보간해주는 보간기 + * @since 4.0.0 + */ + class Motion { + /** + * Current interpolated value + * @ko 현재 보간된 값 + * @since 4.0.0 + */ + get val() { + return this._val; + } + /** + * Start(from) value of interpolation + * @ko 보간 시작 값 + * @since 4.0.0 + */ + get start() { + return this._start; + } + /** + * End(to) value of interpolation + * @ko 보간 끝 값 + * @since 4.0.0 + */ + get end() { + return this._end; + } + /** + * Interpolation progress value (0 ~ 1) + * @ko 현재 보간 진행정도 (0 ~ 1) + * @since 4.0.0 + */ + get progress() { + return this._progress; + } + /** + * Whether the interpolation is in active state. + * @ko 보간 진행중인지 여부. `true`일 경우 보간이 진행중입니다. + * @since 4.0.0 + */ + get activated() { + return this._activated; + } + /** + * Duration of the interpolation + * @ko 보간할 시간 + * @since 4.0.0 + */ + get duration() { + return this._duration; + } + set duration(val) { + this._duration = val; + } + /** + * Whether to loop interpolation on finish + * @ko 보간이 끝난 이후에 다시 시작할지 여부 + * @since 4.0.0 + */ + get loop() { + return this._loop; + } + set loop(val) { + this._loop = val; + } + /** + * Range of the interpolation + * @ko 보간 범위 + * @since 4.0.0 + */ + get range() { + return this._range; + } + /** + * Easing function of the interpolation + * @ko 보간에 사용되는 easing function + * @since 4.0.0 + */ + get easing() { + return this._easing; + } + set easing(val) { + this._easing = val; + } + /** + * Create new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options Options {@ko 옵션들} + * @param options.duration Duration of the interpolation {@ko 보간할 시간} + * @param options.loop Whether to loop interpolation on finish {@ko 보간이 끝난 이후에 다시 시작할지 여부} + * @param options.range Range of the interpolation {@ko 보간 범위} + * @param options.loop Easing function of the interpolation {@ko 보간에 사용되는 easing function} + */ + constructor({ + duration = DEFAULT_ANIMATION_DURATION, + loop = false, + range = { + min: 0, + max: 1 + }, + easing = DEFAULT_EASING + } = {}) { + this._duration = duration; + this._loop = loop; + this._range = range; + this._easing = easing; + this._activated = false; + this.reset(0); + } + /** + * Update motion and progress it by given deltaTime + * @ko 주어진 deltaTime만큼 보간을 진행합니다. + * @param deltaTime - number of milisec to update motion {@ko 보간을 진행할 시간, 밀리초 단위} + * @returns Difference(delta) of the value from the last update. {@ko 지난 업데이트 이후의 값 변화량} + * @since 4.0.0 + */ + update(deltaTime) { + if (!this._activated) { + this._val = this._end; + return 0; + } + const start = this._start; + const end = this._end; + const duration = this._duration; + const prev = this._val; + const loop = this._loop; + const nextProgress = this._progress + deltaTime / duration; + this._progress = loop ? circulate(nextProgress, 0, 1) : clamp(nextProgress, 0, 1); + const easedProgress = this._easing(this._progress); + this._val = lerp(start, end, easedProgress); + if (!loop && this._progress >= 1) { + this._activated = false; + } + return this._val - prev; + } + /** + * Set `start`, `end` to the given value and set `progress` to 0. + * @ko 주어진 값으로 시작 지점, 끝 지점을 초기화하고 progress를 0으로 세팅합니다. + * @param defaultVal - Value to reset {@ko 초기화할 값} + * @since 4.0.0 + */ + reset(defaultVal) { + const range = this._range; + const val = clamp(defaultVal, range.min, range.max); + this._start = val; + this._end = val; + this._val = val; + this._progress = 0; + this._activated = false; + } + /** + * Add delta to start & end and current value. + * @ko 현재 & 끝 및 현재 값에 주어진 값을 더합니다. + * @param delta - Delta value to add {@ko 추가할 값} + */ + add(delta) { + const range = this._range; + this._start = clamp(this._start + delta, range.min, range.max); + this._end = clamp(this._end + delta, range.min, range.max); + this._val = clamp(this._val + delta, range.min, range.max); + } + /** + * Set current value to start, and end to current value + delta, then reset progress to 0. + * @ko 현재 값을 시작 지점으로, 그에서 delta만큼 추가된 값을 끝점으로 하고 progress를 0으로 갱신합니다. + * @param delta - Delta value to add {@ko 추가할 값} + */ + setNewEndByDelta(delta) { + const range = this._range; + this._start = this._val; + this._end = clamp(this._end + delta, range.min, range.max); + this._progress = 0; + this._activated = true; + } + /** + * Set new range of the interpolation. + * @ko 보간의 범위를 변경합니다. + * @param min - New minimum range {@ko 변경할 범위의 최소값} + * @param max - New maximum range {@ko 변경할 범위의 최대값} + */ + setRange(min, max) { + this._start = clamp(this._start, min, max); + this._end = clamp(this._end, min, max); + this._range = { + min, + max + }; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Animation of the {@link Camera} + * @internal + * @ko {@link Camera}의 애니메이션 + * @since 4.0.0 + */ + class CameraAnimation { + /** + * Duration of the animation + * @ko 애니메이션 재생시간 + * @since 4.0.0 + */ + get duration() { + return this._motion.duration; + } + set duration(val) { + this._motion.duration = val; + } + /** + * Easing function of the animation + * @ko 애니메이션의 easing function + * @since 4.0.0 + */ + get easing() { + return this._motion.easing; + } + set easing(val) { + this._motion.easing = val; + } + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param camera - Camera to animate {@ko 애니메이션을 적용할 카메라} + * @param from - Start pose {@ko 애니메이션이 시작 시점의 카메라의 회전 및 줌} + * @param to - End pose {@ko 애니메이션이 끝났을 때 카메라의 회전 및 줌} + * @param options - Options {@ko 옵션들} + * @param options.duration - Animation duration {@ko 애니메이션 재생 시간} + * @param options.easing - Animation easing function {@ko 애니메이션 easing function} + */ + constructor(camera, from, to, { + duration = DEFAULT_ANIMATION_DURATION, + easing = DEFAULT_EASING + } = {}) { + this._camera = camera; + this._motion = new Motion({ + duration, + easing, + range: { + min: 0, + max: 1 + } + }); + this._from = from; + this._to = to; + this._finishPromise = new Promise(resolve => { + this._finish = resolve; + }); + // Enable motion + this._motion.setNewEndByDelta(1); + } + /** + * Return a promise that resolved on animation end. + * @ko 애니메이션 재생이 끝났을 때 resolve되는 Promise를 반환합니다. + * @since 4.0.0 + */ + getFinishPromise() { + return this._finishPromise; + } + /** + * Update animation by given deltaTime. + * @ko 주어진 시간만큼 애니메이션을 업데이트합니다. + * @param deltaTime Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위} + * @since 4.0.0 + */ + update(deltaTime) { + const camera = this._camera; + const from = this._from; + const to = this._to; + const motion = this._motion; + motion.update(deltaTime); + // Progress that easing is applied + const progress = motion.val; + const rotation = create$1(); + const zoom = lerp(from.zoom, to.zoom, progress); + slerp(rotation, from.rotation, to.rotation, progress); + camera.rotate(rotation, zoom); + if (progress >= 1) { + this._finish(); + } + } + } + + /** + * Camera for View360 + * @ko View360용 카메라 구현체 + * @version 4.0.0 + */ + class Camera extends Component { + /** + * Camera's width / height ratio + * @ko 카메라의 가로 / 세로 비율 + * @readonly + */ + get aspect() { + return this._aspect; + } + /** + * Whether the camera's rotation changed from the last frame. + * @ko 마지막 프레임 이후로 카메라의 회전값이 변경되었는지 나타내는 플래그. + * @readonly + */ + get changed() { + return this._changed; + } + /** + * @copy View360#yawRange + */ + get yawRange() { + return this._initialYawRange; + } + set yawRange(val) { + this._initialYawRange = val; + } + /** + * @copy View360#pitchRange + */ + get pitchRange() { + return this._initialPitchRange; + } + set pitchRange(val) { + this._initialPitchRange = val; + } + /** + * @copy View360#zoomRange + */ + get zoomRange() { + return this._initialZoomRange; + } + set zoomRange(val) { + this._initialZoomRange = val; + } + /** + * Create new instance of Camera + * @param options - Camera options {@ko 카메라 옵션들} + */ + constructor({ + initialYaw, + initialPitch, + initialZoom, + yawRange, + pitchRange, + zoomRange, + fov + }) { + super(); + this.yaw = initialYaw; + this.pitch = initialPitch; + this.zoom = initialZoom; + this.rollOffset = 0; + this.initialYaw = initialYaw; + this.initialPitch = initialPitch; + this.initialZoom = initialZoom; + this.position = create$3(); + this.animation = null; + this._up = fromValues$3(0, 1, 0); + this._aspect = 1; + this._initialYawRange = yawRange; + this._initialPitchRange = pitchRange; + this._initialZoomRange = zoomRange; + this._yawRange = yawRange; + this._pitchRange = pitchRange; + this._zoomRange = zoomRange; + this.quaternion = create$1(); + this._updateQuaternion(); + this.viewMatrix = create$4(); + this.projectionMatrix = create$4(); + this.fov = fov; + this._maxRenderHeight = -1; + } + /** + * Destroy instance and detach all event listeners + * @ko 인스턴스를 삭제하고 모든 이벤트 리스너를 삭제합니다. + * @since 4.0.0 + */ + destroy() { + this.off(); + } + /** + * Refresh internal size value. + * @ko 내부 크기값을 갱신합니다. + * @param width - New width {@ko 변경된 너비값} + * @param height - New height {@ko 변경된 높이값} + * @since 4.0.0 + */ + resize(width, height) { + const prevAspect = this._aspect; + this._aspect = width / height; + if (this._aspect !== prevAspect) { + this.updateMatrix(); + } + } + /** + * Change camera's rotation with euler values. + * @ko 카메라 회전을 오일러 각 방향으로 변경합니다. + * @param rotation - Rotation values {@ko 회전 값} + * @param rotation.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값} + * @param rotation.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값} + * @param rotation.zoom - zoom value to apply {@ko 적용할 카메라 줌 값} + * @since 4.0.0 + */ + lookAt({ + yaw = this.yaw, + pitch = this.pitch, + zoom = this.zoom + }) { + const prevQuaternion = clone(this.quaternion); + const prevZoom = this.zoom; + this.yaw = circulate(yaw, 0, 360); + this.pitch = clamp(pitch, -90, 90); + this.zoom = zoom; + this._updateQuaternion(); + const zoomDiff = Math.abs(zoom - prevZoom); + if (!equals(this.quaternion, prevQuaternion) || zoomDiff >= EPSILON * 10 // ignore small changes + ) { + this.updateMatrix(); + } + } + /** + * Change camera's rotation with quaternion. + * @ko 카메라 회전을 Quaternion을 이용해서 변경합니다. + * @param rotation - Quaternion to apply {@ko 적용할 Quaternion} + * @param zoom - zoom value to apply {@ko 적용할 카메라 줌 값} + * @since 4.0.0 + */ + rotate(rotation, zoom = this.zoom) { + const normalized = normalize(create$1(), rotation); + const isSameRotation = equals(this.quaternion, normalized); + copy(this.quaternion, normalized); + const prevZoom = this.zoom; + const { + yaw, + pitch + } = quatToEuler(normalized); + this.yaw = yaw; + this.pitch = pitch; + this.zoom = zoom; + const zoomDiff = Math.abs(zoom - prevZoom); + if (!isSameRotation || zoomDiff >= EPSILON * 10) { + this.updateMatrix(); + } + } + /** + * Change camera's rotation to given euler values by the given duration. + * @ko 카메라를 주어진 방향으로 주어진 시간동안 서서히 이동시킵니다. + * @param options - Animation parameters {@ko 애니메이션 패러미터} + * @param options.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값} + * @param options.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값} + * @param options.zoom - zoom value to apply {@ko 적용할 카메라 줌 값} + * @param options.duration - Duration of the animation {@ko 애니메이션 시간} + * @param options.easing - Easing function for the animation {@ko 애니메이션에 적용할 easing function} + */ + animateTo({ + yaw = this.yaw, + pitch = this.pitch, + zoom = this.zoom, + duration = 0, + easing = DEFAULT_EASING + } = {}) { + return __awaiter(this, void 0, void 0, function* () { + if (this.yaw === yaw && this.pitch === pitch && this.zoom === zoom) return; + const from = { + rotation: clone(this.quaternion), + zoom: this.zoom + }; + const to = { + rotation: eulerToQuat(create$1(), yaw, pitch, this.rollOffset), + zoom + }; + const animation = new CameraAnimation(this, from, to, { + duration, + easing + }); + const finishPromise = animation.getFinishPromise(); + this.animation = animation; + finishPromise.then(() => { + this.animation = null; + this.trigger(CAMERA_EVENTS.ANIMATION_END, { + animation + }); + }); + return finishPromise; + }); + } + /** + * @hidden + */ + restrictYawRange(min, max) { + this._yawRange = { + min, + max + }; + } + /** + * @hidden + */ + restrictPitchRange(min, max) { + this._pitchRange = { + min, + max + }; + } + /** + * @hidden + */ + restrictZoomRange(min, max) { + this._zoomRange = { + min, + max + }; + } + /** + * @hidden + */ + restrictRenderHeight(height) { + this._maxRenderHeight = height; + } + /** + * @hidden + */ + resetRange() { + this._yawRange = this._initialYawRange; + this._pitchRange = this._initialPitchRange; + this._zoomRange = this._initialZoomRange; + this._maxRenderHeight = -1; + } + /** + * Get actual yaw range by the given zoom value. + * @ko 주어진 zoom 값에 대한 실제 yaw 범위값을 반환합니다. + * @since 4.0.0 + */ + getYawRange(zoom) { + const yawLimit = this._yawRange; + const maxRenderHeight = this._maxRenderHeight; + if (!yawLimit) return INFINITE_RANGE; + const halfHFov = this.getHorizontalFov(zoom) * 0.5; + let minYaw = yawLimit.min; + let maxYaw = yawLimit.max; + if (maxRenderHeight > 0) { + const halfVFovRad = toVerticalFov(halfHFov * DEG_TO_RAD, this._aspect); + const h = maxRenderHeight * 0.5; + const t = Math.tan(halfVFovRad); + const d = Math.sqrt((1 + h * h) / (1 + t * t)); + const theta = Math.atan(Math.tan(halfHFov * DEG_TO_RAD) * d) * RAD_TO_DEG; + minYaw = yawLimit.min + theta; + maxYaw = yawLimit.max - theta; + } + if (minYaw > maxYaw) { + minYaw = 0; + maxYaw = 0; + } + return { + min: minYaw, + max: maxYaw + }; + } + /** + * Get actual pitch range by the given zoom value. + * @ko 주어진 zoom 값에 대한 실제 pitch 범위값을 반환합니다. + * @since 4.0.0 + */ + getPitchRange(zoom) { + const pitchLimit = this._pitchRange; + const maxRenderHeight = this._maxRenderHeight; + if (!pitchLimit) return DEFAULT_PITCH_RANGE; + let minPitch = pitchLimit.min; + let maxPitch = pitchLimit.max; + if (maxRenderHeight > 0) { + const halfVFov = this.getVerticalFov(zoom) * 0.5; + minPitch = pitchLimit.min + halfVFov; + maxPitch = pitchLimit.max - halfVFov; + } + if (minPitch > maxPitch) { + minPitch = 0; + maxPitch = 0; + } + return { + min: Math.max(minPitch, -90), + max: Math.min(maxPitch, 90) + }; + } + /** + * Get actual zoom range in fov degrees. + * @ko 실제 줌 범위를 fov각의 범위로 반환합니다. + * @since 4.0.0 + */ + getZoomRange() { + var _a; + const limit = (_a = this._zoomRange) !== null && _a !== void 0 ? _a : DEFAULT_ZOOM_RANGE; + // max (zoom in) -> minimum fov + const minFov = this.getHorizontalFov(limit.max); + const maxFov = this.getHorizontalFov(limit.min); + const currentFov = this.getHorizontalFov(this.zoom); + return { + min: Math.max(minFov, 1), + max: Math.min(maxFov, 180), + current: currentFov + }; + } + /** + * Return horizontal fov value when the given zoom is applied. (in degrees, °) + * @ko 주어진 zoom 값이 적용되었을 때의 수평 fov값을 반환합니다. (도 단위, °) + * @returns Zoomed horizontal FOV {@ko 줌이 적용된 수평 fov값} + * @since 4.0.0 + */ + getHorizontalFov(zoom = this.zoom) { + return this._getZoomedHorizontalFov(zoom) * RAD_TO_DEG; + } + /** + * Return vertical fov value when the given zoom is applied. (in degrees, °) + * @ko 주어진 zoom 값이 적용되었을 때의 수직 fov값을 반환합니다. (도 단위, °) + * @returns Zoomed vertical FOV {@ko 줌이 적용된 수직 fov값} + * @since 4.0.0 + */ + getVerticalFov(zoom = this.zoom) { + const aspect = this._aspect; + const hFov = this._getZoomedHorizontalFov(zoom); // In radians + const vFov = toVerticalFov(hFov, aspect); + return vFov * RAD_TO_DEG; + } + /** + * Calculate zoom value for the given fov. + * @ko 주어진 fov값을 zoom값으로 변환합니다. + * @param fov horizontal fov (in degrees, °) {@ko 수평 fov 값 (도 단위, °)} + * @since 4.0.0 + */ + fovToZoom(fov) { + const baseFov = this.fov; + const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5); + const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5); + return renderingWidth / zoomedWidth; + } + /** + * Update inner matrixes. + * @ko 내부 행렬들을 업데이트합니다. + * @internal + * @since 4.0.0 + */ + updateMatrix() { + const up = this._up; + const aspect = this._aspect; + const viewMatrix = this.viewMatrix; + const projMatrix = this.projectionMatrix; + const position = this.position; + const rotation = this.quaternion; + const upDir = create$3(); + const viewDir = fromValues$3(0, 0, -1); + transformQuat(viewDir, viewDir, rotation); + transformQuat(upDir, up, rotation); + const hFov = this._getZoomedHorizontalFov(); // In radians + const vFov = toVerticalFov(hFov, aspect); + lookAt(viewMatrix, position, viewDir, upDir); + perspective(projMatrix, vFov, aspect, 0.1, 100); + this._changed = true; + } + /** + * @hidden + */ + onFrameRender() { + this._changed = false; + } + _updateQuaternion() { + eulerToQuat(this.quaternion, this.yaw, this.pitch, this.rollOffset); + } + /** + * @param zoom Current zoom value + * @returns horizontal fov including zoom, in radian + */ + _getZoomedHorizontalFov(zoom = this.zoom) { + return 2 * Math.atan(Math.tan(DEG_TO_RAD * this.fov * 0.5) / zoom); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class MouseInput extends Component { + constructor() { + super(); + this._onMouseDown = evt => { + const el = this._el; + if (!el || evt.button !== MOUSE_BUTTON.LEFT) return; + evt.preventDefault(); + if (el.focus) { + el.focus(); + } else { + window.focus(); + } + this._prevPos[0] = evt.clientX; + this._prevPos[1] = evt.clientY; + window.addEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove, false); + window.addEventListener(EVENTS$1.MOUSE_UP, this._onMouseUp, false); + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: false, + isKeyboard: false + }); + }; + this._onMouseMove = evt => { + evt.preventDefault(); + const x = evt.clientX; + const y = evt.clientY; + const prevPos = this._prevPos; + const deltaX = x - prevPos[0]; + const deltaY = y - prevPos[1]; + this.trigger(CONTROL_EVENTS.CHANGE, { + delta: { + x: deltaX, + y: deltaY + }, + isTouch: false, + isKeyboard: false + }); + prevPos[0] = x; + prevPos[1] = y; + }; + this._onMouseUp = () => { + this._prevPos[0] = 0; + this._prevPos[1] = 0; + window.removeEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove, false); + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onMouseUp, false); + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: false, + isKeyboard: false, + scrolling: false + }); + }; + this._el = null; + this._prevPos = [0, 0]; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.MOUSE_DOWN, this._onMouseDown); + this._el = element; + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.MOUSE_DOWN, this._onMouseDown); + window.removeEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove, false); + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onMouseUp, false); + this._el = null; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class TouchInput extends Component { + get scrollable() { + return this._scrollable; + } + set scrollable(val) { + this._scrollable = val; + } + constructor() { + super(); + this._onTouchStart = evt => { + if (evt.touches.length > 1 || this._scrolling) return; + const touch = evt.touches[0]; + this._isFirstTouch = true; + this._prevPos[0] = touch.clientX; + this._prevPos[1] = touch.clientY; + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: true, + isKeyboard: false + }); + }; + this._onTouchMove = evt => { + // Only the one finger motion should be considered + if (evt.touches.length > 1 || this._scrolling) return; + const touch = evt.touches[0]; + const scrollable = this._scrollable; + const prevPos = this._prevPos; + const x = touch.clientX; + const y = touch.clientY; + const deltaX = x - prevPos[0]; + const deltaY = y - prevPos[1]; + if (this._isFirstTouch) { + if (scrollable && !isFullscreen()) { + if (Math.abs(deltaY) > Math.abs(deltaX)) { + // Assume Scrolling + this._scrolling = true; + return; + } + } + this._isFirstTouch = false; + } + if (evt.cancelable !== false) { + evt.preventDefault(); + } + this.trigger(CONTROL_EVENTS.CHANGE, { + delta: { + x: deltaX, + y: deltaY + }, + isTouch: true, + isKeyboard: false + }); + prevPos[0] = x; + prevPos[1] = y; + }; + this._onTouchEnd = evt => { + if (evt.touches.length !== 0) return; + const touch = evt.touches[0]; + const prevPos = this._prevPos; + if (touch) { + prevPos[0] = touch.clientX; + prevPos[1] = touch.clientY; + } else { + prevPos[0] = 0; + prevPos[1] = 0; + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: true, + isKeyboard: false, + scrolling: this._scrolling + }); + } + if (evt.cancelable !== false) { + evt.preventDefault(); + } + this._scrolling = false; + }; + this._el = null; + this._prevPos = [0, 0]; + this._isFirstTouch = false; + this._scrolling = false; + this._scrollable = false; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.TOUCH_START, this._onTouchStart, { + passive: false + }); + element.addEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove, { + passive: false + }); + element.addEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = element; + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.TOUCH_START, this._onTouchStart); + element.removeEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove); + element.removeEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = null; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class KeyboardInput extends Component { + get active() { + const pressed = this._pressed; + return pressed.LEFT || pressed.UP || pressed.RIGHT || pressed.DOWN; + } + constructor() { + super(); + this._onKeyDown = evt => { + // Ignore all other keypress except main arrow keys + if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return; + this._updateKeyPress(evt, true); + const pressedCount = this._getPressedKeyCount(); + if (pressedCount <= 0) return; + evt.preventDefault(); + if (pressedCount === 1 && !evt.repeat) { + // On first keydown + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: false, + isKeyboard: true + }); + } + }; + this._onKeyUp = evt => { + // Ignore all other keypress except main arrow keys + if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return; + this._updateKeyPress(evt, false); + const pressedCount = this._getPressedKeyCount(); + if (pressedCount > 0) return; + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: false, + isKeyboard: true, + scrolling: false + }); + }; + this._el = null; + this._clearPressedKeys(); + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown); + element.addEventListener(EVENTS$1.KEY_UP, this._onKeyUp); + this._el = element; + this._clearPressedKeys(); + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown); + element.removeEventListener(EVENTS$1.KEY_UP, this._onKeyUp); + this._el = null; + this._clearPressedKeys(); + } + update() { + const delta = this._getDeltaByPressedKeys(); + if (delta.x !== 0 || delta.y !== 0) { + this.trigger(CONTROL_EVENTS.CHANGE, { + delta, + isTouch: false, + isKeyboard: true + }); + } + } + _clearPressedKeys() { + this._pressed = KEY_DIRECTION.reduce((obj, keyName) => { + return Object.assign(Object.assign({}, obj), { + [keyName]: false + }); + }, {}); + } + _updateKeyPress(event, isEnable) { + const pressed = this._pressed; + const keyToUpdate = event.keyCode != null ? DIRECTION_KEY_CODE[event.keyCode] : DIRECTION_KEY_NAME[event.key]; + if (!keyToUpdate) return; + pressed[keyToUpdate] = isEnable; + } + _getPressedKeyCount() { + return KEY_DIRECTION.filter(key => this._pressed[key]).length; + } + _getDeltaByPressedKeys() { + const pressed = this._pressed; + let x = 0; + let y = 0; + if (pressed.LEFT) { + x += 1; + } + if (pressed.RIGHT) { + x -= 1; + } + if (pressed.UP) { + y += 1; + } + if (pressed.DOWN) { + y -= 1; + } + return { + x, + y + }; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Camera's rotation control + * @ko 카메라의 회전을 담당하는 컨트롤 + * @since 4.0.0 + */ + class RotateControl extends Component { + /** + * @copy CameraControl#enabled + */ + get enabled() { + return this._enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * @copy CameraControl#animating + */ + get animating() { + return this._keyboardInput.active || this._xMotion.activated || this._yMotion.activated; + } + /** + * Current yaw value + * @ko 현재 yaw 값 + * @readonly + * @since 4.0.0 + */ + get yaw() { + return this._xMotion; + } + /** + * Current pitch value + * @ko 현재 pitch 값 + * @readonly + * @since 4.0.0 + */ + get pitch() { + return this._yMotion; + } + /** + * @copy View360#scrollable + */ + get scrollable() { + return this._touchInput.scrollable; + } + set scrollable(val) { + this._touchInput.scrollable = val; + } + /** + * Scale factor for mouse/touch rotation + * @ko 마우스/터치를 통한 회전 배율 + * @default [1, 1] + * @since 4.0.0 + */ + get pointerScale() { + return this._pointerScale; + } + set pointerScale(val) { + this._pointerScale = val; + } + /** + * Scale factor for keyboard rotation + * @ko 키보드를 통한 회전 배율 + * @default [1, 1] + * @since 4.0.0 + */ + get keyboardScale() { + return this._keyboardScale; + } + set keyboardScale(val) { + this._keyboardScale = val; + } + /** + * Duration of the input animation (ms) + * @ko 회전 애니메이션의 시간 (ms) + * @default 300 + */ + get duration() { + return this._duration; + } + set duration(val) { + this._duration = val; + this._xMotion.duration = val; + this._yMotion.duration = val; + } + /** + * Easing function of the animation + * @ko 회전 애니메이션에 적용할 easing 함수 + * @default EASING.EASE_OUT_CUBIC + * @see EASING + */ + get easing() { + return this._easing; + } + set easing(val) { + this._easing = val; + this._xMotion.easing = val; + this._yMotion.easing = val; + } + /** + * Disable X-axis(pitch) rotation. + * @ko x축 회전(pitch)을 비활성화합니다. + * @default false + */ + get disablePitch() { + return this._disablePitch; + } + set disablePitch(val) { + this._disablePitch = val; + } + /** + * Disable Y-axis(yaw) rotation. + * @ko y축 회전(yaw)을 비활성화합니다. + * @default false + */ + get disableYaw() { + return this._disableYaw; + } + set disableYaw(val) { + this._disableYaw = val; + } + /** + * Disable rotation by keyboard. + * @ko 키보드를 이용한 회전을 비활성화합니다. + * @default false + */ + get disableKeyboard() { + return this._disableKeyboard; + } + set disableKeyboard(val) { + this._disableKeyboard = val; + } + /** + * Create new RotateControl instance + * @ko RotateControl의 인스턴스를 생성합니다. + * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트} + * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부} + * @param options - Options for control {@ko 컨트롤 옵션들} + */ + constructor(controlEl, enableBlocked, { + duration = DEFAULT_ANIMATION_DURATION, + easing = DEFAULT_EASING, + pointerScale = [1, 1], + keyboardScale = [1, 1], + disablePitch = false, + disableYaw = false, + disableKeyboard = false + } = {}) { + super(); + this._onInputStart = evt => { + this._changedWhileDragging = false; + this.trigger(CONTROL_EVENTS.INPUT_START, Object.assign(Object.assign({}, evt), { + inputType: "rotate" + })); + }; + this._onChange = evt => { + const delta = evt.delta; + const invZoomScale = 1 / this._zoomScale; // Reduce speed on zoom + const screenScale = this._screenScale; + const keyboardScale = this._keyboardScale; + const pointerScale = this._pointerScale; + let scale; + if (evt.isKeyboard) { + scale = [keyboardScale[0] * invZoomScale, keyboardScale[1] * invZoomScale]; + } else { + scale = [pointerScale[0] * screenScale[0] * invZoomScale, pointerScale[1] * screenScale[1] * invZoomScale]; + } + const scaledX = delta.x * scale[0]; + const scaledY = delta.y * scale[1]; + this._xMotion.setNewEndByDelta(scaledX); + this._yMotion.setNewEndByDelta(scaledY); + this._changedWhileDragging = true; + }; + this._onInputEnd = evt => { + this.trigger(CONTROL_EVENTS.INPUT_END, Object.assign(Object.assign({}, evt), { + inputType: "rotate" + })); + if (!this._changedWhileDragging && !evt.isKeyboard && !evt.scrolling) { + this.trigger(CONTROL_EVENTS.STATIC_CLICK, { + isTouch: evt.isTouch + }); + } + this._changedWhileDragging = false; + }; + this._controlEl = controlEl; + this._pointerScale = pointerScale; + this._keyboardScale = keyboardScale; + this._duration = duration; + this._easing = easing; + this._disablePitch = disablePitch; + this._disableYaw = disableYaw; + this._disableKeyboard = disableKeyboard; + this._enableBlocked = enableBlocked; + this._mouseInput = new MouseInput(); + this._touchInput = new TouchInput(); + this._keyboardInput = new KeyboardInput(); + this._xMotion = new Motion({ + duration, + range: INFINITE_RANGE, + easing + }); + this._yMotion = new Motion({ + duration, + range: DEFAULT_PITCH_RANGE, + easing + }); + this._screenScale = [1, 1]; + this._zoomScale = 1; + this._enabled = false; + this._changedWhileDragging = false; + this._bindInputs(); + } + destroy() { + this.disable(); + this._mouseInput.off(); + this._touchInput.off(); + this._keyboardInput.off(); + this.off(); + this._changedWhileDragging = false; + } + /** + * @hidden + */ + update(delta) { + if (!this._enabled) return; + const xMotion = this._xMotion; + const yMotion = this._yMotion; + const keyboardInput = this._keyboardInput; + if (!this._disableKeyboard) { + keyboardInput.update(); + } + if (!this._disablePitch) { + yMotion.update(delta); + } + if (!this._disableYaw) { + xMotion.update(delta); + } + } + /** + * @hidden + */ + updateRange(camera, zoom) { + const yawRange = camera.getYawRange(zoom); + const pitchRange = camera.getPitchRange(zoom); + this._xMotion.setRange(yawRange.min, yawRange.max); + this._yMotion.setRange(pitchRange.min, pitchRange.max); + } + /** + * @hidden + */ + setZoomScale(val) { + this._zoomScale = val; + } + /** + * Resize control to match target size. + * @ko 컨트롤의 내부 크기를 갱신합니다. + * @param hfov - Camera horizontal fov in degrees {@ko 카메라의 수평방향 fov값 (도 단위)} + * @param aspect - Camera aspect {@ko 카메라 가로/세로 비율} + * @param width - New width {@ko 갱신된 너비} + * @param height - New height {@ko 갱신된 높이} + */ + resize(hfov, aspect, width, height) { + const vfov = toVerticalFov(hfov * DEG_TO_RAD, aspect) * RAD_TO_DEG; + this._screenScale[0] = hfov / width; + this._screenScale[1] = vfov / height; + } + enable() { + if (this._enabled) return; + const element = this._controlEl; + this._mouseInput.enable(element); + this._touchInput.enable(element); + this._keyboardInput.enable(element); + this._enabled = true; + this._enableBlocked = false; + this.trigger(CONTROL_EVENTS.ENABLE, { + control: this, + updateCursor: true + }); + } + disable() { + if (!this._enabled) return; + this._mouseInput.disable(); + this._touchInput.disable(); + this._keyboardInput.disable(); + this._enabled = false; + this.trigger(CONTROL_EVENTS.DISABLE, { + updateCursor: true + }); + } + sync(camera) { + this.updateRange(camera, camera.zoom); + this._xMotion.reset(camera.yaw); + this._yMotion.reset(camera.pitch); + } + _bindInputs() { + const mouseInput = this._mouseInput; + const touchInput = this._touchInput; + const keyboardInput = this._keyboardInput; + mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + touchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + touchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + keyboardInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + keyboardInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + keyboardInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class WheelInput extends Component { + get scrollable() { + return this._scrollable; + } + set scrollable(val) { + this._scrollable = val; + } + constructor() { + super(); + this._onWheel = evt => { + const scrollable = this._scrollable; + if (evt.deltaY === 0 || scrollable) return; + evt.preventDefault(); + evt.stopPropagation(); + if (this._inputTimer < 0) { + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: false, + isKeyboard: false + }); + } else { + this._clearTimer(); + } + const delta = this._baseScale * evt.deltaY; + this.trigger(CONTROL_EVENTS.CHANGE, { + delta, + isTouch: false, + isKeyboard: false + }); + this._inputTimer = window.setTimeout(() => { + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: false, + isKeyboard: false, + scrolling: false + }); + this._inputTimer = -1; + }, DEFAULT_ANIMATION_DURATION); + }; + this._el = null; + this._baseScale = 0.04; + this._scrollable = false; + this._inputTimer = -1; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.WHEEL, this._onWheel, { + passive: false, + capture: false + }); + this._el = element; + this._clearTimer(); + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.WHEEL, this._onWheel, false); + this._el = null; + this._clearTimer(); + } + _clearTimer() { + window.clearTimeout(this._inputTimer); + this._inputTimer = -1; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class PinchInput extends Component { + constructor() { + super(); + this._onTouchMove = evt => { + const touches = evt.touches; + if (touches.length !== 2) return; + if (!evt.cancelable) return; + evt.preventDefault(); + evt.stopPropagation(); + const prevDistance = this._prevDistance; + const diff = [touches[0].pageX - touches[1].pageX, touches[0].pageY - touches[1].pageY]; + const distance = Math.sqrt(diff[0] * diff[0] + diff[1] * diff[1]) * this._baseScale; + const delta = this._isFirstTouch ? 0 : distance - prevDistance; + if (this._isFirstTouch) { + this.trigger(CONTROL_EVENTS.INPUT_START, { + srcEvent: evt, + isTouch: true, + isKeyboard: false + }); + } + this._prevDistance = distance; + this._isFirstTouch = false; + this.trigger(CONTROL_EVENTS.CHANGE, { + delta, + isTouch: true, + isKeyboard: false + }); + }; + this._onTouchEnd = evt => { + if (evt.touches.length !== 0) return; + if (!this._isFirstTouch) { + this.trigger(CONTROL_EVENTS.INPUT_END, { + isTouch: true, + isKeyboard: false, + scrolling: false + }); + } + this._prevDistance = -1; + this._isFirstTouch = true; + }; + this._el = null; + this._baseScale = -0.2; + this._prevDistance = -1; + this._isFirstTouch = true; + } + enable(element) { + if (this._el) return; + element.addEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove, { + passive: false, + capture: false + }); + element.addEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = element; + this._prevDistance = -1; + this._isFirstTouch = true; + } + disable() { + const element = this._el; + if (!element) return; + element.removeEventListener(EVENTS$1.TOUCH_MOVE, this._onTouchMove, false); + element.removeEventListener(EVENTS$1.TOUCH_END, this._onTouchEnd); + this._el = null; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Camera's zoom control + * @ko 카메라의 줌 값을 담당하는 컨트롤 + * @since 4.0.0 + */ + class ZoomControl extends Component { + /** + * @copy CameraControl#enabled + */ + get enabled() { + return this._enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * @copy CameraControl#animating + */ + get animating() { + return this._motion.activated; + } + /** + * Current zoom value + * @ko 현재 줌 값 + * @since 4.0.0 + * @readonly + */ + get zoom() { + return this._motion.val; + } + /** + * @copy View360#wheelScrollable + */ + get scrollable() { + return this._wheelInput.scrollable; + } + set scrollable(val) { + this._wheelInput.scrollable = val; + } + /** + * @hidden + */ + get range() { + return this._motion.range; + } + /** + * Scale factor of the zoom + * @ko 입력에 의한 줌 배율 + * @default 1 + * @since 4.0.0 + */ + get scale() { + return this._scale; + } + set scale(val) { + this._scale = val; + } + /** + * Duration of the input animation (ms) + * @ko 회전 애니메이션의 시간 (ms) + * @default 300 + * @since 4.0.0 + */ + get duration() { + return this._motion.duration; + } + /** + * Easing function of the animation + * @ko 회전 애니메이션에 적용할 easing 함수 + * @default EASING.EASE_OUT_CUBIC + * @see EASING + * @since 4.0.0 + */ + get easing() { + return this._motion.easing; + } + /** + * Create new ZoomControl instance + * @ko ZoomControl의 인스턴스를 생성합니다. + * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트} + * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부} + * @param options - Options for control {@ko 컨트롤 옵션들} + */ + constructor(controlEl, enableBlocked, { + scale = 1, + duration = DEFAULT_ANIMATION_DURATION, + easing = DEFAULT_EASING + } = {}) { + super(); + this._onInputStart = evt => { + this.trigger(CONTROL_EVENTS.INPUT_START, Object.assign(Object.assign({}, evt), { + inputType: "zoom" + })); + }; + this._onChange = ({ + delta + }) => { + const scale = this._scale; + const scaledDelta = delta * scale; + this._motion.setNewEndByDelta(scaledDelta); + }; + this._onInputEnd = evt => { + this.trigger(CONTROL_EVENTS.INPUT_END, Object.assign(Object.assign({}, evt), { + inputType: "zoom" + })); + }; + this._scale = scale; + this._controlEl = controlEl; + this._enableBlocked = enableBlocked; + this._wheelInput = new WheelInput(); + this._pinchInput = new PinchInput(); + this._motion = new Motion({ + duration, + easing, + range: INFINITE_RANGE + }); + this._enabled = false; + this._bindInputs(); + } + destroy() { + this.disable(); + this._wheelInput.off(); + this._pinchInput.off(); + this.off(); + } + /** + * @hidden + */ + update(delta) { + if (!this._enabled) return; + const motion = this._motion; + motion.update(delta); + } + enable() { + if (this._enabled) return; + const element = this._controlEl; + this._wheelInput.enable(element); + this._pinchInput.enable(element); + this._enabled = true; + this._enableBlocked = false; + this.trigger(CONTROL_EVENTS.ENABLE, { + control: this, + updateCursor: false + }); + } + disable() { + if (!this._enabled) return; + this._wheelInput.disable(); + this._pinchInput.disable(); + this._enabled = false; + this.trigger(CONTROL_EVENTS.DISABLE, { + updateCursor: false + }); + } + sync(camera) { + const motion = this._motion; + const range = camera.getZoomRange(); + motion.setRange(range.min, range.max); + motion.reset(range.current); + } + _bindInputs() { + const wheelInput = this._wheelInput; + const pinchInput = this._pinchInput; + wheelInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + wheelInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + wheelInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + pinchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + pinchInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + pinchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + const ROTATE_CONSTANT = { + PITCH_DELTA: 1, + YAW_DELTA_BY_ROLL: 2, + YAW_DELTA_BY_YAW: 3 + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = { + targetAxis: [0, 1, 0], + meshPoint: [0, 0, 1] + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = { + targetAxis: [0, 1, 0], + meshPoint: [1, 0, 0] + }; + ROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = { + targetAxis: [1, 0, 0], + meshPoint: [0, 0, 1] + }; + class GyroInput extends Component { + get enabled() { + return this._enabled; + } + get orientationUpdated() { + return this._orientationUpdated; + } + get ignoreRoll() { + return this._ignoreRoll; + } + set ignoreRoll(val) { + this._ignoreRoll = val; + } + constructor() { + super(); + this._onDeviceOrientation = evt => { + const prevOrientation = this._orientation; + const { + alpha, + beta, + gamma + } = evt; + if (alpha == null || beta == null || gamma == null) return; + prevOrientation.alpha = alpha; + prevOrientation.beta = beta; + prevOrientation.gamma = gamma; + this._orientationUpdated = true; + if (this._needsCalibrate) { + this._needsCalibrate = false; + this._calibrateSensor(); + } + }; + this._updateScreenOrientation = () => { + if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) { + this._screenOrientation = screen.orientation.angle; + } else if (window.orientation !== undefined) { + this._screenOrientation = window.orientation >= 0 ? window.orientation : 360 + window.orientation; + } else { + this._screenOrientation = 0; + } + }; + this.quaternion = create$1(); + this._orientation = { + alpha: 0, + beta: 90, + gamma: 0 + }; + this._yawOrigin = 0; + this._yawOffset = 0; + this._orientationUpdated = false; + this._screenOrientation = 0; + this._needsCalibrate = true; + this._enabled = false; + } + enable() { + if (this._enabled) return; + window.addEventListener(EVENTS$1.DEVICE_ORIENTATION, this._onDeviceOrientation); + window.addEventListener(EVENTS$1.ORIENTATION_CHANGE, this._updateScreenOrientation); + this._updateScreenOrientation(); + this._orientationUpdated = false; + this._needsCalibrate = true; + this._enabled = true; + } + disable() { + if (!this._enabled) return; + window.removeEventListener(EVENTS$1.DEVICE_ORIENTATION, this._onDeviceOrientation); + window.removeEventListener(EVENTS$1.ORIENTATION_CHANGE, this._updateScreenOrientation); + this._enabled = false; + } + update() { + this._updateRotation(); + this._orientationUpdated = false; + } + collectDelta() { + if (!this._orientationUpdated) { + return { + pitch: 0, + yaw: 0 + }; + } + const prevRotation = clone(this.quaternion); + this._updateRotation(); + this._orientationUpdated = false; + return this._toEulerDelta(prevRotation, this.quaternion); + } + setInitialRotation(yaw) { + this._yawOrigin = yaw; + } + _calibrateSensor() { + const yawOrigin = this._yawOrigin; + const rotation = this.quaternion; + this._yawOffset = 0; + this._updateRotation(); + const { + yaw: sensorYaw + } = quatToEuler(rotation); + this._yawOffset = sensorYaw - yawOrigin; + this._updateRotation(); + this._needsCalibrate = false; + } + _updateRotation() { + const rotation = this.quaternion; + const { + alpha, + beta, + gamma + } = this._orientation; + identity(rotation); + rotateY(rotation, rotation, (alpha - this._yawOffset) * DEG_TO_RAD); + rotateX(rotation, rotation, beta * DEG_TO_RAD); + rotateZ(rotation, rotation, -gamma * DEG_TO_RAD); + const screen = create$1(); + const screenAngle = -this._screenOrientation * 0.5 * DEG_TO_RAD; + const world = fromValues$1(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5)); + set(screen, 0, Math.sin(screenAngle), 0, Math.cos(screenAngle)); + multiply(rotation, rotation, screen); + multiply(rotation, rotation, world); + normalize(rotation, rotation); + } + _toEulerDelta(prevQuat, currentQuat) { + return { + yaw: this._getDeltaYaw(prevQuat, currentQuat), + pitch: this._getDeltaPitch(prevQuat, currentQuat) + }; + } + _getDeltaYaw(prvQ, curQ) { + const yawDeltaByYaw = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW); + const yawDeltaByRoll = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL) * Math.sin(this._extractPitchFromQuat(curQ)); + return yawDeltaByRoll + yawDeltaByYaw; + } + _getDeltaPitch(prvQ, curQ) { + return this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA); + } + _getRotationDelta(prevQ, curQ, rotateKind) { + const targetAxis = fromValues$3(ROTATE_CONSTANT[rotateKind].targetAxis[0], ROTATE_CONSTANT[rotateKind].targetAxis[1], ROTATE_CONSTANT[rotateKind].targetAxis[2]); + const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint; + const prevQuaternion = clone(prevQ); + const curQuaternion = clone(curQ); + normalize(prevQuaternion, prevQuaternion); + normalize(curQuaternion, curQuaternion); + let prevPoint = fromValues$3(0, 0, 1); + let curPoint = fromValues$3(0, 0, 1); + transformQuat(prevPoint, prevPoint, prevQuaternion); + transformQuat(curPoint, curPoint, curQuaternion); + transformQuat(targetAxis, targetAxis, curQuaternion); + const rotateDistance = dot(targetAxis, cross(create$3(), prevPoint, curPoint)); + const rotateDirection = rotateDistance > 0 ? 1 : -1; + // when counter clock wise, use vec3.fromValues(0,1,0) + // when clock wise, use vec3.fromValues(0,-1,0) + // const meshPoint1 = vec3.fromValues(0, 0, 0); + const meshPoint2 = fromValues$3(meshPoint[0], meshPoint[1], meshPoint[2]); + let meshPoint3; + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + meshPoint3 = fromValues$3(0, rotateDirection, 0); + } else { + meshPoint3 = fromValues$3(rotateDirection, 0, 0); + } + transformQuat(meshPoint2, meshPoint2, curQuaternion); + transformQuat(meshPoint3, meshPoint3, curQuaternion); + const vecU = meshPoint2; + const vecV = meshPoint3; + const vecN = create$3(); + cross(vecN, vecU, vecV); + normalize$2(vecN, vecN); + const coefficientA = vecN[0]; + const coefficientB = vecN[1]; + const coefficientC = vecN[2]; + // a point on the plane + curPoint = fromValues$3(meshPoint[0], meshPoint[1], meshPoint[2]); + transformQuat(curPoint, curPoint, curQuaternion); + // a point should project on the plane + prevPoint = fromValues$3(meshPoint[0], meshPoint[1], meshPoint[2]); + transformQuat(prevPoint, prevPoint, prevQuaternion); + // distance between prevPoint and the plane + let distance = Math.abs(prevPoint[0] * coefficientA + prevPoint[1] * coefficientB + prevPoint[2] * coefficientC); + const projectedPrevPoint = create$3(); + subtract(projectedPrevPoint, prevPoint, scale(create$3(), vecN, distance)); + let trigonometricRatio = (projectedPrevPoint[0] * curPoint[0] + projectedPrevPoint[1] * curPoint[1] + projectedPrevPoint[2] * curPoint[2]) / (length(projectedPrevPoint) * length(curPoint)); + // defensive block + if (trigonometricRatio > 1) { + trigonometricRatio = 1; + } + const theta = Math.acos(trigonometricRatio); + const crossVec = cross(create$3(), curPoint, projectedPrevPoint); + distance = coefficientA * crossVec[0] + coefficientB * crossVec[1] + coefficientC * crossVec[2]; + let thetaDirection; + if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) { + thetaDirection = distance > 0 ? 1 : -1; + } else { + thetaDirection = distance < 0 ? 1 : -1; + } + const deltaRadian = theta * thetaDirection * rotateDirection; + return deltaRadian * RAD_TO_DEG; + } + _extractPitchFromQuat(quaternion) { + const baseV = fromValues$3(0, 0, 1); + transformQuat(baseV, baseV, quaternion); + return -1 * Math.atan2(baseV[1], Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2))); + } + } + + /** + * Camera's rotation control by gyroscope + * @ko 자이로스코프를 이용한 회전 컨트롤 + * @since 4.0.0 + */ + class GyroControl extends Component { + /** + * @copy CameraControl#enabled + */ + get enabled() { + return this._input.enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * @copy CameraControl#animating + */ + get animating() { + return this._input.enabled && this._input.orientationUpdated; + } + /** + * When `true`, ignore gyroscope's roll(z-axis rotation) value. + * :::caution + * Setting `false` will ignore camera's range limit. + * Options like {@link View360Options#yawRange}, {@link View360Options#pitchRange} are ignored, and {@link CylinderProjection} also can't force it's camera range limit. + * ::: + * @ko `true`일 경우 자이로스코프 입력의 roll(z축 회전)값을 무시합니다. + * :::caution + * 이 값을 `false`로 설정할 경우 카메라 범위 제약을 무시합니다. + * {@link View360Options#yawRange}, {@link View360Options#pitchRange}와 같은 값은 무시되며, {@link CylinderProjection} 사용시에도 범위를 벗어날 수 있습니다. + * ::: + * @default true + * @since 4.0.0 + */ + get ignoreRoll() { + return this._ignoreRoll; + } + set ignoreRoll(val) { + this._ignoreRoll = val; + } + /** + * Return availability of the gyroscope. + * :::caution + * This will always return false until user permission under environments like iOS which requires user permission when using gyroscope. + * ::: + * @ko 자이로스코프 사용 가능 여부를 반환합니다. + * :::caution + * iOS와 같이 GyroScope 사용시 사용자 Permission을 요구하는 환경에서는 사용자 Permission을 받기 전까지 항상 `false`입니다. + * ::: + * @example + * ```ts + * const gyroAvailable = await GyroControl.isAvailable(); + * ``` + */ + static isAvailable() { + return __awaiter(this, void 0, void 0, function* () { + if (!DeviceMotionEvent) { + return false; + } + let onDeviceMotionChange; + const listenDeviceMotion = () => new Promise(res => { + onDeviceMotionChange = evt => { + res(evt.rotationRate && evt.rotationRate.alpha != null); + }; + window.addEventListener(EVENTS$1.DEVICE_MOTION, onDeviceMotionChange); + }); + const timeout = () => new Promise(res => { + setTimeout(() => res(false), 1000); + }); + return Promise.race([listenDeviceMotion(), timeout()]).then(available => { + window.removeEventListener(EVENTS$1.DEVICE_MOTION, onDeviceMotionChange); + return available; + }); + }); + } + /** + * Request user permission for gyroscope sensor. + * This can be used in environments like iOS which requires user permission when using gyroscope sensors. + * @ko 사용자의 sensor permission 취득을 요청합니다. + * iOS와 같이 gyroscope 사용시 사용자 Permission을 요구하는 환경에서 사용 가능합니다. + * @returns Whether the permission is granted {@ko 사용자 permission 취득 여부} + */ + static requestSensorPermission() { + return __awaiter(this, void 0, void 0, function* () { + // Request sensor permission, on iOS13+ + if (sensorCanBeEnabledIOS()) { + return DeviceMotionEvent.requestPermission().then(permissionState => { + return permissionState === "granted"; + }).catch(() => false); + } + return true; + }); + } + /** + * Create new GyroControl instance + * @ko GyroControl의 인스턴스를 생성합니다. + * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부} + * @param options - Options for control {@ko 컨트롤 옵션들} + */ + constructor(enableBlocked, { + ignoreRoll = true + } = {}) { + super(); + this._enableBlocked = enableBlocked; + this._ignoreRoll = ignoreRoll; + this._input = new GyroInput(); + } + /** + * @copy CameraControl#destroy + */ + destroy() { + this.disable(); + this._input.off(); + this.off(); + } + /** + * @hidden + */ + update(camera, yaw, pitch, zoom) { + if (!this._ignoreRoll) { + this._updateQuaternion(camera, zoom); + } else { + this._updateYawPitch(camera, yaw, pitch, zoom); + } + } + /** + * @copy CameraControl#enable + */ + enable() { + if (this._input.enabled) return; + this._input.enable(); + this._enableBlocked = false; + this.trigger(CONTROL_EVENTS.ENABLE, { + control: this, + updateCursor: false + }); + } + /** + * @copy CameraControl#disable + */ + disable() { + if (!this._input.enabled) return; + this._input.disable(); + this.trigger(CONTROL_EVENTS.DISABLE, { + updateCursor: false + }); + } + /** + * @copy CameraControl#sync + */ + sync() {} // eslint-disable-line @typescript-eslint/no-empty-function + _updateYawPitch(camera, yaw, pitch, zoom) { + const input = this._input; + if (!input.enabled) return; + const { + yaw: yawDelta, + pitch: pitchDelta + } = input.collectDelta(); + yaw.add(yawDelta); + pitch.add(pitchDelta); + camera.lookAt({ + yaw: yaw.val, + pitch: pitch.val, + zoom + }); + } + _updateQuaternion(camera, zoom) { + const input = this._input; + if (!input.enabled) return; + input.update(); + camera.rotate(input.quaternion, zoom); + } + } + + /** + * Panorama control for View360 + * @ko View360용 파노라마 컨트롤 + * @since 4.0.0 + */ + class PanoControl { + /** + * @copy View360#useGrabCursor + */ + get useGrabCursor() { + return this._useGrabCursor; + } + set useGrabCursor(val) { + if (val === this._useGrabCursor) return; + this._useGrabCursor = val; + if (val && this._enabled) { + this._setCursor(CURSOR.GRAB); + } else if (!val) { + this._setCursor(CURSOR.NONE); + } + } + /** + * @copy View360#disableContextMenu + */ + get disableContextMenu() { + return this._disableContextMenu; + } + set disableContextMenu(val) { + if (val === this._disableContextMenu) return; + this._disableContextMenu = val; + if (val && this._enabled) { + this._blockContextMenu(); + } else if (!val) { + this._restoreContextMenu(); + } + } + /** + * @copy View360#disableContextMenu + */ + get scrollable() { + return this._rotateControl.scrollable; + } + set scrollable(val) { + this._rotateControl.scrollable = val; + } + /** + * @copy View360#disableContextMenu + */ + get wheelScrollable() { + return this._zoomControl.scrollable; + } + set wheelScrollable(val) { + this._zoomControl.scrollable = val; + } + /** + * When `true`, disables rotation slow-down by zoom-value. + * @ko `true`일 경우 줌 된 정도에 따라 회전속도를 늦추는 동작을 비활성화합니다. + * @since 4.0.0 + */ + get ignoreZoomScale() { + return this._ignoreZoomScale; + } + set ignoreZoomScale(val) { + this._ignoreZoomScale = val; + } + /** + * Whether the control is enabled or not + * @ko 컨트롤 활성화 여부를 가리키는 값 + * @readonly + * @since 4.0.0 + */ + get enabled() { + return this._enabled; + } + /** + * @copy View360#rotate + */ + get rotate() { + return this._rotateControl; + } + /** + * @copy View360#zoom + */ + get zoom() { + return this._zoomControl; + } + /** + * @copy View360#gyro + */ + get gyro() { + return this._gyroControl; + } + /** + * Whether one of the controls is animating at the moment + * @ko 현재 컨트롤 중 하나라도 동작중인지 여부를 나타내는 값 + * @readonly + * @since 4.0.0 + */ + get animating() { + return this._rotateControl.animating || this._zoomControl.animating || this._gyroControl.animating; + } + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param element - Canvas element {@ko 캔버스 엘리먼트} + * @param camera - Camera instance {@ko Camera 인스턴스} + * @param options - Options for PanoControl {@ko PanoControl 옵션들} + */ + constructor(element, camera, { + useGrabCursor, + scrollable, + wheelScrollable, + disableContextMenu, + rotate, + zoom, + gyro + }) { + this._preventContextMenu = evt => { + evt.preventDefault(); + }; + this._onInputStart = evt => { + if (this._useGrabCursor && !evt.isKeyboard) { + this._setCursor(CURSOR.GRABBING); + } + }; + this._onInputEnd = evt => { + if (this._useGrabCursor && !evt.isKeyboard) { + this._setCursor(CURSOR.GRAB); + } + }; + this._onEnable = ({ + control, + updateCursor + }) => { + if (updateCursor && this._useGrabCursor) { + this._setCursor(CURSOR.GRAB); + } + control.sync(this._camera); + }; + this._onDisable = ({ + updateCursor + }) => { + if (updateCursor) { + this._setCursor(CURSOR.NONE); + } + }; + this._onCameraAnimationEnd = ({ + animation + }) => { + animation.getFinishPromise().then(() => { + this.sync(); + }); + }; + // Bind Options + this._useGrabCursor = useGrabCursor; + this._disableContextMenu = disableContextMenu; + // Set internal values + this._camera = camera; + this._controlEl = element; + this._ignoreZoomScale = false; + this._enabled = false; + this._rotateControl = new RotateControl(element, !rotate, getObjectOption(rotate)); + this._zoomControl = new ZoomControl(element, !zoom, getObjectOption(zoom)); + this._gyroControl = new GyroControl(!gyro, getObjectOption(gyro)); + this._rotateControl.scrollable = scrollable; + this._zoomControl.scrollable = wheelScrollable; + this._bindEvents(); + } + /** + * Destroy the instance and remove all event listeners attached. + * This also will reset CSS cursor to initial. + * @ko 인스턴스를 삭제하고 부착된 모든 이벤트 리스너를 제거합니다. + * 또한, 캔버스에 적용된 CSS cursor도 제거합니다. + * @since 4.0.0 + */ + destroy() { + this.disable(); + this._rotateControl.destroy(); + this._zoomControl.destroy(); + this._setCursor(CURSOR.NONE); + } + /** + * Resize control to match target size. + * @ko 컨트롤이 내부에 캐시하고 있는 크기값을 갱신합니다. + * @param width New width {@ko 변경된 너비} + * @param height New height {@ko 변경된 높이} + * @since 4.0.0 + */ + resize(width, height) { + const camera = this._camera; + this._rotateControl.resize(camera.fov, camera.aspect, width, height); + } + /** + * Enable this control and add event listeners. + * @ko 컨트롤을 활성화하고 이벤트 리스너들을 추가합니다. + * @since 4.0.0 + */ + enable() { + return __awaiter(this, void 0, void 0, function* () { + if (this._enabled) return; + if (!this._rotateControl.enableBlocked) { + this._rotateControl.enable(); + } + if (!this._zoomControl.enableBlocked) { + this._zoomControl.enable(); + } + if (!this._gyroControl.enableBlocked) { + if (yield GyroControl.isAvailable()) { + this._gyroControl.enable(); + } + } + this.sync(); + if (this._disableContextMenu) { + this._blockContextMenu(); + } + this._enabled = true; + }); + } + /** + * Disable this control and remove all event listeners + * @ko 컨트롤을 비활성화하고 모든 이벤트 리스너들을 제거합니다. + * @since 4.0.0 + */ + disable() { + if (!this._enabled) return; + this._rotateControl.disable(); + this._zoomControl.disable(); + this._gyroControl.disable(); + this._restoreContextMenu(); + this._enabled = false; + } + /** + * Update control by given deltaTime + * @ko 컨트롤을 주어진 시간만큼 업데이트합니다. + * @param delta Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위} + * @since 4.0.0 + * @internal + */ + update(delta) { + const camera = this._camera; + const rotateControl = this._rotateControl; + const zoomControl = this._zoomControl; + const gyroControl = this._gyroControl; + zoomControl.update(delta); + const zoom = hfovToZoom(camera.fov, zoomControl.zoom); + // Slow down rotation on zoom-in + const zoomScale = this._ignoreZoomScale ? 1 : Math.max(zoom, 1); + rotateControl.setZoomScale(zoomScale); + rotateControl.updateRange(camera, zoom); + rotateControl.update(delta); + const yaw = rotateControl.yaw; + const pitch = rotateControl.pitch; + if (gyroControl.enabled) { + gyroControl.update(camera, yaw, pitch, zoom); + } else { + camera.lookAt({ + yaw: yaw.val, + pitch: pitch.val, + zoom + }); + } + } + /** + * Synchronize this control's state to current camera state + * @ko 컨트롤을 카메라의 현재 상태와 동기화합니다. + * @since 4.0.0 + */ + sync() { + const camera = this._camera; + this._zoomControl.sync(camera); + this._rotateControl.sync(camera); + } + _blockContextMenu() { + const el = this._controlEl; + el.addEventListener(EVENTS$1.CONTEXT_MENU, this._preventContextMenu); + } + _restoreContextMenu() { + const el = this._controlEl; + el.removeEventListener(EVENTS$1.CONTEXT_MENU, this._preventContextMenu); + } + _setCursor(newCursor) { + if (!this._useGrabCursor && newCursor !== CURSOR.NONE) return; + const targetEl = this._controlEl; + targetEl.style.cursor = newCursor; + } + _bindEvents() { + const rotateControl = this._rotateControl; + const zoomControl = this._zoomControl; + rotateControl.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + rotateControl.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + rotateControl.on(CONTROL_EVENTS.ENABLE, this._onEnable); + rotateControl.on(CONTROL_EVENTS.DISABLE, this._onDisable); + zoomControl.on(CONTROL_EVENTS.ENABLE, this._onEnable); + zoomControl.on(CONTROL_EVENTS.DISABLE, this._onDisable); + this._camera.on(CAMERA_EVENTS.ANIMATION_END, this._onCameraAnimationEnd); + } + } + + /* + Copyright (c) 2020-present NAVER Corp. + name: @egjs/imready + license: MIT + author: NAVER Corp. + repository: https://github.com/naver/egjs-imready + version: 1.3.1 + */ + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + + /* global Reflect, Promise */ + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || { + __proto__: [] + } instanceof Array && function (d, b) { + d.__proto__ = b; + } || function (d, b) { + for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; + }; + + return extendStatics(d, b); + }; + + function __extends(d, b) { + extendStatics(d, b); + + function __() { + this.constructor = d; + } + + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + var __assign = function () { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + + return t; + }; + + return __assign.apply(this, arguments); + }; + function __spreadArrays() { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + + for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; + + return r; + } + + /* + egjs-imready + Copyright (c) 2020-present NAVER Corp. + MIT license + */ + var isWindow = typeof window !== "undefined"; + var ua = isWindow ? window.navigator.userAgent : ""; + var SUPPORT_COMPUTEDSTYLE = isWindow ? !!("getComputedStyle" in window) : false; + var IS_IE = /MSIE|Trident|Windows Phone|Edge/.test(ua); + var SUPPORT_ADDEVENTLISTENER = isWindow ? !!("addEventListener" in document) : false; + var WIDTH = "width"; + var HEIGHT = "height"; + + function getAttribute(el, name) { + return el.getAttribute(name) || ""; + } + function toArray(arr) { + return [].slice.call(arr); + } + function hasSizeAttribute(target, prefix) { + if (prefix === void 0) { + prefix = "data-"; + } + + return !!target.getAttribute(prefix + "width"); + } + function hasLoadingAttribute(target, prefix) { + if (prefix === void 0) { + prefix = "data-"; + } + + return "loading" in target && target.getAttribute("loading") === "lazy" || !!target.getAttribute(prefix + "lazy"); + } + function hasSkipAttribute(target, prefix) { + if (prefix === void 0) { + prefix = "data-"; + } + + return !!target.getAttribute(prefix + "skip"); + } + function addEvent(element, type, handler) { + if (SUPPORT_ADDEVENTLISTENER) { + element.addEventListener(type, handler, false); + } else if (element.attachEvent) { + element.attachEvent("on" + type, handler); + } else { + element["on" + type] = handler; + } + } + function removeEvent(element, type, handler) { + if (element.removeEventListener) { + element.removeEventListener(type, handler, false); + } else if (element.detachEvent) { + element.detachEvent("on" + type, handler); + } else { + element["on" + type] = null; + } + } + function innerWidth(el) { + return getSize(el, "Width"); + } + function innerHeight(el) { + return getSize(el, "Height"); + } + function getStyles(el) { + return (SUPPORT_COMPUTEDSTYLE ? window.getComputedStyle(el) : el.currentStyle) || {}; + } + + function getSize(el, name) { + var size = el["client" + name] || el["offset" + name]; + return parseFloat(size || getStyles(el)[name.toLowerCase()]) || 0; + } + + function getContentElements(element, tags, prefix) { + var skipElements = toArray(element.querySelectorAll(__spreadArrays(["[" + prefix + "skip] [" + prefix + "width]"], tags.map(function (tag) { + return ["[" + prefix + "skip] " + tag, tag + "[" + prefix + "skip]", "[" + prefix + "width] " + tag].join(", "); + })).join(", "))); + return toArray(element.querySelectorAll("[" + prefix + "width], " + tags.join(", "))).filter(function (el) { + return skipElements.indexOf(el) === -1; + }); + } + + /* + egjs-imready + Copyright (c) 2020-present NAVER Corp. + MIT license + */ + var elements = []; + function addAutoSizer(element, prefix) { + !elements.length && addEvent(window, "resize", resizeAllAutoSizers); + element.__PREFIX__ = prefix; + elements.push(element); + resize(element); + } + function removeAutoSizer(element, prefix) { + var index = elements.indexOf(element); + + if (index < 0) { + return; + } + + var fixed = getAttribute(element, prefix + "fixed"); + delete element.__PREFIX__; + element.style[fixed === HEIGHT ? WIDTH : HEIGHT] = ""; + elements.splice(index, 1); + !elements.length && removeEvent(window, "resize", resizeAllAutoSizers); + } + + function resize(element, prefix) { + if (prefix === void 0) { + prefix = "data-"; + } + + var elementPrefix = element.__PREFIX__ || prefix; + var dataWidth = parseInt(getAttribute(element, "" + elementPrefix + WIDTH), 10) || 0; + var dataHeight = parseInt(getAttribute(element, "" + elementPrefix + HEIGHT), 10) || 0; + var fixed = getAttribute(element, elementPrefix + "fixed"); + + if (fixed === HEIGHT) { + var size = innerHeight(element) || dataHeight; + element.style[WIDTH] = dataWidth / dataHeight * size + "px"; + } else { + var size = innerWidth(element) || dataWidth; + element.style[HEIGHT] = dataHeight / dataWidth * size + "px"; + } + } + + function resizeAllAutoSizers() { + elements.forEach(function (element) { + resize(element); + }); + } + + var Loader = + /*#__PURE__*/ + function (_super) { + __extends(Loader, _super); + + function Loader(element, options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + _this.isReady = false; + _this.isPreReady = false; + _this.hasDataSize = false; + _this.hasLoading = false; + _this.isSkip = false; + + _this.onCheck = function (e) { + _this.clear(); + + if (e && e.type === "error") { + _this.onError(_this.element); + } + + if (_this.hasLoading && _this.checkElement()) { + // I'm not ready + return; + } // I'm pre-ready and ready! + + + var withPreReady = !_this.hasDataSize && !_this.hasLoading; + + _this.onReady(withPreReady); + }; + + _this.options = __assign({ + prefix: "data-" + }, options); + _this.element = element; + var prefix = _this.options.prefix; + _this.hasDataSize = hasSizeAttribute(element, prefix); + _this.isSkip = hasSkipAttribute(element, prefix); + _this.hasLoading = hasLoadingAttribute(element, prefix); + return _this; + } + + var __proto = Loader.prototype; + + __proto.check = function () { + if (this.isSkip || !this.checkElement()) { + // I'm Ready + this.onAlreadyReady(true); + return false; + } + + if (this.hasDataSize) { + addAutoSizer(this.element, this.options.prefix); + } + + if (this.hasDataSize || this.hasLoading) { + // I'm Pre Ready + this.onAlreadyPreReady(); + } // Wati Pre Ready, Ready + + + return true; + }; + + __proto.addEvents = function () { + var _this = this; + + var element = this.element; + this.constructor.EVENTS.forEach(function (name) { + addEvent(element, name, _this.onCheck); + }); + }; + + __proto.clear = function () { + var _this = this; + + var element = this.element; + this.constructor.EVENTS.forEach(function (name) { + removeEvent(element, name, _this.onCheck); + }); + this.removeAutoSizer(); + }; + + __proto.destroy = function () { + this.clear(); + this.off(); + }; + + __proto.removeAutoSizer = function () { + if (this.hasDataSize) { + // I'm already ready. + var prefix = this.options.prefix; + removeAutoSizer(this.element, prefix); + } + }; + + __proto.onError = function (target) { + this.trigger("error", { + element: this.element, + target: target + }); + }; + + __proto.onPreReady = function () { + if (this.isPreReady) { + return; + } + + this.isPreReady = true; + this.trigger("preReady", { + element: this.element, + hasLoading: this.hasLoading, + isSkip: this.isSkip + }); + }; + + __proto.onReady = function (withPreReady) { + if (this.isReady) { + return; + } + + withPreReady = !this.isPreReady && withPreReady; + + if (withPreReady) { + this.isPreReady = true; + } + + this.removeAutoSizer(); + this.isReady = true; + this.trigger("ready", { + element: this.element, + withPreReady: withPreReady, + hasLoading: this.hasLoading, + isSkip: this.isSkip + }); + }; + + __proto.onAlreadyError = function (target) { + var _this = this; + + setTimeout(function () { + _this.onError(target); + }); + }; + + __proto.onAlreadyPreReady = function () { + var _this = this; + + setTimeout(function () { + _this.onPreReady(); + }); + }; + + __proto.onAlreadyReady = function (withPreReady) { + var _this = this; + + setTimeout(function () { + _this.onReady(withPreReady); + }); + }; + + Loader.EVENTS = []; + return Loader; + }(Component); + + var ElementLoader = + /*#__PURE__*/ + function (_super) { + __extends(ElementLoader, _super); + + function ElementLoader() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = ElementLoader.prototype; + + __proto.setHasLoading = function (hasLoading) { + this.hasLoading = hasLoading; + }; + + __proto.check = function () { + if (this.isSkip) { + // I'm Ready + this.onAlreadyReady(true); + return false; + } + + if (this.hasDataSize) { + addAutoSizer(this.element, this.options.prefix); + this.onAlreadyPreReady(); + } else { + // has not data size + this.trigger("requestChildren"); + } + + return true; + }; + + __proto.checkElement = function () { + return true; + }; + + __proto.destroy = function () { + this.clear(); + this.trigger("requestDestroy"); + this.off(); + }; + + __proto.onAlreadyPreReady = function () { + // has data size + _super.prototype.onAlreadyPreReady.call(this); + + this.trigger("reqeustReadyChildren"); + }; + + ElementLoader.EVENTS = []; + return ElementLoader; + }(Loader); + + /** + * @alias eg.ImReady + * @extends eg.Component + */ + + var ImReadyManager = + /*#__PURE__*/ + function (_super) { + __extends(ImReadyManager, _super); + /** + * @param - ImReady's options + */ + + + function ImReadyManager(options) { + if (options === void 0) { + options = {}; + } + + var _this = _super.call(this) || this; + + _this.readyCount = 0; + _this.preReadyCount = 0; + _this.totalCount = 0; + _this.totalErrorCount = 0; + _this.isPreReadyOver = true; + _this.elementInfos = []; + _this.options = __assign({ + loaders: {}, + prefix: "data-" + }, options); + return _this; + } + /** + * Checks whether elements are in the ready state. + * @ko 엘리먼트가 준비 상태인지 체크한다. + * @elements - Elements to check ready status. 준비 상태를 체크할 엘리먼트들. + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check(document.querySelectorAll("img")).on({ + * preReadyElement: e => { + * // 1, 3 + * // 2, 3 + * // 3, 3 + * console.log(e.preReadyCount, e.totalCount), + * }, + * }); + * ``` + */ + + + var __proto = ImReadyManager.prototype; + + __proto.check = function (elements) { + var _this = this; + + var prefix = this.options.prefix; + this.clear(); + this.elementInfos = toArray(elements).map(function (element, index) { + var loader = _this.getLoader(element, { + prefix: prefix + }); + + loader.check(); + loader.on("error", function (e) { + _this.onError(index, e.target); + }).on("preReady", function (e) { + var info = _this.elementInfos[index]; + info.hasLoading = e.hasLoading; + info.isSkip = e.isSkip; + + var isPreReady = _this.checkPreReady(index); + + _this.onPreReadyElement(index); + + isPreReady && _this.onPreReady(); + }).on("ready", function (_a) { + var withPreReady = _a.withPreReady, + hasLoading = _a.hasLoading, + isSkip = _a.isSkip; + var info = _this.elementInfos[index]; + info.hasLoading = hasLoading; + info.isSkip = isSkip; + + var isPreReady = withPreReady && _this.checkPreReady(index); + + var isReady = _this.checkReady(index); // Pre-ready and ready occur simultaneously + + + withPreReady && _this.onPreReadyElement(index); + + _this.onReadyElement(index); + + isPreReady && _this.onPreReady(); + isReady && _this.onReady(); + }); + return { + loader: loader, + element: element, + hasLoading: false, + hasError: false, + isPreReady: false, + isReady: false, + isSkip: false + }; + }); + var length = this.elementInfos.length; + this.totalCount = length; + + if (!length) { + setTimeout(function () { + _this.onPreReady(); + + _this.onReady(); + }); + } + + return this; + }; + /** + * Gets the total count of elements to be checked. + * @ko 체크하는 element의 총 개수를 가져온다. + */ + + + __proto.getTotalCount = function () { + return this.totalCount; + }; + /** + * Whether the elements are all pre-ready. (all sizes are known) + * @ko 엘리먼트들이 모두 사전 준비가 됐는지 (사이즈를 전부 알 수 있는지) 여부. + */ + + + __proto.isPreReady = function () { + return this.elementInfos.every(function (info) { + return info.isPreReady; + }); + }; + /** + * Whether the elements are all ready. + * @ko 엘리먼트들이 모두 준비가 됐는지 여부. + */ + + + __proto.isReady = function () { + return this.elementInfos.every(function (info) { + return info.isReady; + }); + }; + /** + * Whether an error has occurred in the elements in the current state. + * @ko 현재 상태에서 엘리먼트들이 에러가 발생했는지 여부. + */ + + + __proto.hasError = function () { + return this.totalErrorCount > 0; + }; + /** + * Clears events of elements being checked. + * @ko 체크 중인 엘리먼트들의 이벤트를 해제 한다. + */ + + + __proto.clear = function () { + this.isPreReadyOver = false; + this.totalCount = 0; + this.preReadyCount = 0; + this.readyCount = 0; + this.totalErrorCount = 0; + this.elementInfos.forEach(function (info) { + if (info.loader) { + info.loader.destroy(); + } + }); + this.elementInfos = []; + }; + /** + * Destory all events. + * @ko 모든 이벤트를 해제 한다. + */ + + + __proto.destroy = function () { + this.clear(); + this.off(); + }; + + __proto.getLoader = function (element, options) { + var _this = this; + + var tagName = element.tagName.toLowerCase(); + var loaders = this.options.loaders; + var prefix = options.prefix; + var tags = Object.keys(loaders); + + if (loaders[tagName]) { + return new loaders[tagName](element, options); + } + + var loader = new ElementLoader(element, options); + var children = toArray(element.querySelectorAll(tags.join(", "))); + loader.setHasLoading(children.some(function (el) { + return hasLoadingAttribute(el, prefix); + })); + var withPreReady = false; + var childrenImReady = this.clone().on("error", function (e) { + loader.onError(e.target); + }).on("ready", function () { + loader.onReady(withPreReady); + }); + loader.on("requestChildren", function () { + // has not data size + var contentElements = getContentElements(element, tags, _this.options.prefix); + childrenImReady.check(contentElements).on("preReady", function (e) { + withPreReady = e.isReady; + + if (!withPreReady) { + loader.onPreReady(); + } + }); + }).on("reqeustReadyChildren", function () { + // has data size + // loader call preReady + // check only video, image elements + childrenImReady.check(children); + }).on("requestDestroy", function () { + childrenImReady.destroy(); + }); + return loader; + }; + + __proto.clone = function () { + return new ImReadyManager(__assign({}, this.options)); + }; + + __proto.checkPreReady = function (index) { + this.elementInfos[index].isPreReady = true; + ++this.preReadyCount; + + if (this.preReadyCount < this.totalCount) { + return false; + } + + return true; + }; + + __proto.checkReady = function (index) { + this.elementInfos[index].isReady = true; + ++this.readyCount; + + if (this.readyCount < this.totalCount) { + return false; + } + + return true; + }; + + __proto.onError = function (index, target) { + var info = this.elementInfos[index]; + info.hasError = true; + /** + * An event occurs if the image, video fails to load. + * @ko 이미지, 비디오가 로딩에 실패하면 이벤트가 발생한다. + * @event eg.ImReady#error + * @param {eg.ImReady.OnError} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check([document.querySelector("div")]).on({ + * error: e => { + * //
...
, 0, + * console.log(e.element, e.index, e.target), + * }, + * }); + * ``` + */ + + this.trigger(new ComponentEvent$1("error", { + element: info.element, + index: index, + target: target, + errorCount: this.getErrorCount(), + totalErrorCount: ++this.totalErrorCount + })); + }; + + __proto.onPreReadyElement = function (index) { + var info = this.elementInfos[index]; + /** + * An event occurs when the element is pre-ready (when the loading attribute is applied or the size is known) + * @ko 해당 엘리먼트가 사전 준비되었을 때(loading 속성이 적용되었거나 사이즈를 알 수 있을 때) 이벤트가 발생한다. + * @event eg.ImReady#preReadyElement + * @param {eg.ImReady.OnPreReadyElement} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check(document.querySelectorAll("img")).on({ + * preReadyElement: e => { + * // 1, 3 + * // 2, 3 + * // 3, 3 + * console.log(e.preReadyCount, e.totalCount), + * }, + * }); + * ``` + */ + + this.trigger(new ComponentEvent$1("preReadyElement", { + element: info.element, + index: index, + preReadyCount: this.preReadyCount, + readyCount: this.readyCount, + totalCount: this.totalCount, + isPreReady: this.isPreReady(), + isReady: this.isReady(), + hasLoading: info.hasLoading, + isSkip: info.isSkip + })); + }; + + __proto.onPreReady = function () { + this.isPreReadyOver = true; + /** + * An event occurs when all element are pre-ready (When all elements have the loading attribute applied or the size is known) + * @ko 모든 엘리먼트들이 사전 준비된 경우 (모든 엘리먼트들이 loading 속성이 적용되었거나 사이즈를 알 수 있는 경우) 이벤트가 발생한다. + * @event eg.ImReady#preReady + * @param {eg.ImReady.OnPreReady} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check(document.querySelectorAll("img")).on({ + * preReady: e => { + * // 0, 3 + * console.log(e.readyCount, e.totalCount), + * }, + * }); + * ``` + */ + + this.trigger(new ComponentEvent$1("preReady", { + readyCount: this.readyCount, + totalCount: this.totalCount, + isReady: this.isReady(), + hasLoading: this.hasLoading() + })); + }; + + __proto.onReadyElement = function (index) { + var info = this.elementInfos[index]; + /** + * An event occurs when the element is ready + * @ko 해당 엘리먼트가 준비가 되었을 때 이벤트가 발생한다. + * @event eg.ImReady#readyElement + * @param {eg.ImReady.OnReadyElement} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check(document.querySelectorAll("img")).on({ + * readyElement: e => { + * // 1, 0, false, 3 + * // 2, 1, false, 3 + * // 3, 2, true, 3 + * console.log(e.readyCount, e.index, e.hasError, e.totalCount), + * }, + * }); + * ``` + */ + + this.trigger(new ComponentEvent$1("readyElement", { + index: index, + element: info.element, + hasError: info.hasError, + errorCount: this.getErrorCount(), + totalErrorCount: this.totalErrorCount, + preReadyCount: this.preReadyCount, + readyCount: this.readyCount, + totalCount: this.totalCount, + isPreReady: this.isPreReady(), + isReady: this.isReady(), + hasLoading: info.hasLoading, + isPreReadyOver: this.isPreReadyOver, + isSkip: info.isSkip + })); + }; + + __proto.onReady = function () { + /** + * An event occurs when all element are ready + * @ko 모든 엘리먼트들이 준비된 경우 이벤트가 발생한다. + * @event eg.ImReady#ready + * @param {eg.ImReady.OnReady} e - The object of data to be sent to an event 이벤트에 전달되는 데이터 객체 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * ## Javascript + * ```js + * import ImReady from "@egjs/imready"; + * + * const im = new ImReady(); // umd: eg.ImReady + * im.check(document.querySelectorAll("img")).on({ + * preReady: e => { + * // 0, 3 + * console.log(e.readyCount, e.totalCount), + * }, + * ready: e => { + * // 1, 3 + * console.log(e.errorCount, e.totalCount), + * }, + * }); + * ``` + */ + this.trigger(new ComponentEvent$1("ready", { + errorCount: this.getErrorCount(), + totalErrorCount: this.totalErrorCount, + totalCount: this.totalCount + })); + }; + + __proto.getErrorCount = function () { + return this.elementInfos.filter(function (info) { + return info.hasError; + }).length; + }; + + __proto.hasLoading = function () { + return this.elementInfos.some(function (info) { + return info.hasLoading; + }); + }; + + return ImReadyManager; + }(Component); + + var ImageLoader = + /*#__PURE__*/ + function (_super) { + __extends(ImageLoader, _super); + + function ImageLoader() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = ImageLoader.prototype; + + __proto.checkElement = function () { + var element = this.element; + var src = element.getAttribute("src"); + + if (element.complete) { + if (src) { + // complete + if (!element.naturalWidth) { + this.onAlreadyError(element); + } + + return false; + } else { + // Using an external lazy loading module + this.onAlreadyPreReady(); + } + } + + this.addEvents(); + IS_IE && element.setAttribute("src", src); + return true; + }; + + ImageLoader.EVENTS = ["load", "error"]; + return ImageLoader; + }(Loader); + + var VideoLoader = + /*#__PURE__*/ + function (_super) { + __extends(VideoLoader, _super); + + function VideoLoader() { + return _super !== null && _super.apply(this, arguments) || this; + } + + var __proto = VideoLoader.prototype; + + __proto.checkElement = function () { + var element = this.element; // HAVE_NOTHING: 0, no information whether or not the audio/video is ready + // HAVE_METADATA: 1, HAVE_METADATA - metadata for the audio/video is ready + // HAVE_CURRENT_DATA: 2, data for the current playback position is available, but not enough data to play next frame/millisecond + // HAVE_FUTURE_DATA: 3, data for the current and at least the next frame is available + // HAVE_ENOUGH_DATA: 4, enough data available to start playing + + if (element.readyState >= 1) { + return false; + } + + if (element.error) { + this.onAlreadyError(element); + return false; + } + + this.addEvents(); + return true; + }; + + VideoLoader.EVENTS = ["loadedmetadata", "error"]; + return VideoLoader; + }(Loader); + + var ImReady = + /*#__PURE__*/ + function (_super) { + __extends(ImReady, _super); + + function ImReady(options) { + if (options === void 0) { + options = {}; + } + + return _super.call(this, __assign({ + loaders: { + img: ImageLoader, + video: VideoLoader + } + }, options)) || this; + } + + return ImReady; + }(ImReadyManager); + + /* + egjs-imready + Copyright (c) 2020-present NAVER Corp. + MIT license + */ + + var ImReady$1 = ImReady; + + /** + * @hidden + */ + class Texture { + constructor({ + width, + height, + flipY + }) { + this.width = width; + this.height = height; + this.flipY = flipY; + this.wrapS = WebGLRenderingContext.CLAMP_TO_EDGE; + this.wrapT = WebGLRenderingContext.CLAMP_TO_EDGE; + } + destroy() { + // DO_NOTHING + } + isVideo() { + return false; + } + isCube() { + return false; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class Texture2D extends Texture { + constructor({ + source, + width, + height, + flipY + }) { + super({ + width, + height, + flipY + }); + this.source = source; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class TextureVideo extends Texture2D { + destroy() { + const video = this.source; + video.pause(); + video.removeAttribute("src"); + video.load(); + } + isVideo() { + return true; + } + isPaused() { + const video = this.source; + return video.paused || video.ended || video.readyState <= 2; + } + hasAudio() { + const video = this.source; + if (video.audioTracks) { + return video.audioTracks.length > 0; + } + if (video.webkitAudioDecodedByteCount != null) { + return video.webkitAudioDecodedByteCount > 0; + } + if (video.mozHasAudio != null) { + return video.mozHasAudio; + } + // We don't know whether the video has audio or not, return true + return true; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class TextureCube extends Texture { + constructor({ + sources, + width, + height, + flipY + }) { + super({ + width, + height, + flipY + }); + this.sources = sources; + } + isCube() { + return true; + } + } + + /** + * @hidden + */ + class TextureLoader { + constructor() { + this._loadChecker = new ImReady$1(); + } + load(src, video) { + return __awaiter(this, void 0, void 0, function* () { + if (video) { + return this.loadVideo(src, getObjectOption(video)); + } else { + if (Array.isArray(src) && src.length > 1) { + return this.loadCubeImage(src); + } else { + const imgSrc = Array.isArray(src) ? src[0] : src; + return this.loadImage(imgSrc); + } + } + }); + } + loadImage(src) { + return __awaiter(this, void 0, void 0, function* () { + const images = this._toImageArray(src); + return this._load(images, resolve => { + const image = images[0]; + resolve(new Texture2D({ + source: image, + width: image.naturalWidth, + height: image.naturalHeight, + flipY: true + })); + }); + }); + } + loadCubeImage(src) { + return __awaiter(this, void 0, void 0, function* () { + const images = this._toImageArray(src); + return this._load(images, resolve => { + resolve(new TextureCube({ + sources: images, + width: images[0].naturalWidth, + height: images[0].naturalHeight, + flipY: false + })); + }); + }); + } + loadVideo(src, videoConfig) { + return __awaiter(this, void 0, void 0, function* () { + const config = Object.assign({ + autoplay: true, + muted: true, + loop: false, + volume: 1 + }, videoConfig); + const video = this._toVideoElement(src, config); + return this._load([video], resolve => { + const { + autoplay, + muted + } = config; + video.currentTime = 0; + if (autoplay && muted) { + video.play().catch(() => void 0); + } + resolve(new TextureVideo({ + source: video, + width: video.videoWidth, + height: video.videoHeight, + flipY: true + })); + }); + }); + } + _load(content, onLoad) { + const loader = this._loadChecker; + return new Promise((resolve, reject) => { + loader.once("ready", evt => { + if (evt.errorCount > 0) return; + onLoad(resolve); + }); + loader.once("error", reject); + loader.check(content); + }); + } + _toImageArray(src) { + const srcs = Array.isArray(src) ? src : [src]; + return srcs.map(source => { + if (isString(source)) { + const imgEl = new Image(); + imgEl.crossOrigin = "anonymous"; + imgEl.src = source; + return imgEl; + } else { + return source; + } + }); + } + _toVideoElement(src, { + muted, + loop, + volume + }) { + if (src instanceof HTMLVideoElement) { + return src; + } + const video = document.createElement("video"); + video.crossOrigin = "anonymous"; + video.playsInline = true; + video.setAttribute("webkit-playsinline", ""); + video.muted = muted; + video.volume = volume; + video.loop = loop; + if (Array.isArray(src)) { + src.forEach(source => this._appendSourceElement(video, source)); + } else { + this._appendSourceElement(video, src); + } + const sourceCount = video.querySelectorAll("source").length; + if (sourceCount > 0 && video.readyState < 1) { + video.load(); + } + return video; + } + _appendSourceElement(video, src) { + if (src instanceof HTMLSourceElement) { + return src; + } + const sourceEl = document.createElement("source"); + sourceEl.src = src; + video.appendChild(sourceEl); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @internal + */ + class FrameAnimator { + /** */ + constructor(maxDeltaTime, context = window) { + this.maxDeltaTime = maxDeltaTime; + this._context = context; + this._rafId = -1; + this._rafTimer = -1; + this._lastUpdateTime = -1; + } + start(callback) { + const context = this._context; + // No context / callback set + if (!context || !callback) return; + // Animation already started + if (this._rafId >= 0 || this._rafTimer >= 0) return; + const loop = (_time, frame) => { + const time = Date.now(); + const delta = Math.min(time - this._lastUpdateTime, this.maxDeltaTime * 1000); + callback(delta, frame); + this._lastUpdateTime = time; + this._rafId = context.requestAnimationFrame(loop); + }; + this._lastUpdateTime = Date.now(); + this._rafId = context.requestAnimationFrame(loop); + } + stop() { + if (this._rafId >= 0) { + this._context.cancelAnimationFrame(this._rafId); + } + if (this._rafTimer >= 0) { + clearTimeout(this._rafTimer); + } + this._rafId = -1; + this._rafTimer = -1; + } + changeContext(context) { + this.stop(); + this._context = context; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Automatic resizer that uses both ResizeObserver and window resize event + */ + class AutoResizer { + get useResizeObserver() { + return this._useResizeObserver; + } + /** + * Returns whether AutoResizer is enabled + */ + get enabled() { + return this._enabled; + } + /** */ + constructor(useResizeObserver, onResize) { + // eslint-disable-next-line @typescript-eslint/member-ordering + this._skipFirstResize = (() => { + let isFirstResize = true; + return () => { + if (isFirstResize) { + isFirstResize = false; + return; + } + this._onResize(); + }; + })(); + this._useResizeObserver = useResizeObserver; + this._enabled = false; + this._resizeObserver = null; + this._onResize = onResize; + } + /** + * Enable resizer + */ + enable(element) { + if (this._enabled) { + this.disable(); + } + if (this._useResizeObserver && !!window.ResizeObserver) { + const bbox = element.getBoundingClientRect(); + const resizeImmediate = bbox.width !== 0 || bbox.height !== 0; + const resizeObserver = new ResizeObserver(resizeImmediate ? this._skipFirstResize : this._onResize); + resizeObserver.observe(element); + this._resizeObserver = resizeObserver; + } else { + window.addEventListener(EVENTS$1.RESIZE, this._onResize); + } + this._enabled = true; + return this; + } + /** + * Disable resizer + */ + disable() { + if (!this._enabled) return this; + const resizeObserver = this._resizeObserver; + if (resizeObserver) { + resizeObserver.disconnect(); + this._resizeObserver = null; + } else { + window.removeEventListener(EVENTS$1.RESIZE, this._onResize); + } + this._enabled = false; + return this; + } + } + + /** + * A manager class for autoplay feature. + * @ko Autoplay 기능의 매니저 클래스. + * @since 4.0.0 + */ + class Autoplay { + /** + * Whether autoplay is enabled or not + * @ko 자동재생 활성화 여부를 나타내는 값 + * @readonly + * @since 4.0.0 + */ + get enabled() { + return this._enabled; + } + /** + * @hidden + */ + get enableBlocked() { + return this._enableBlocked; + } + /** + * Whether autoplay is updating the camera at the moment + * @ko 현재 자동재생이 동작중인지 여부를 나타내는 값 + * @readonly + * @since 4.0.0 + */ + get playing() { + return this._enabled && !this._interrupted; + } + /** + * Reactivation delay after mouse input in milisecond. + * @ko 재활성화되기까지의 시간 (밀리초 단위) + * @default 2000 + * @since 4.0.0 + */ + get delay() { + return this._delay; + } + set delay(val) { + this._delay = val; + } + /** + * Reactivation delay after mouse leave when using {@link AutoplayOptions#pauseOnHover} + * @ko {@link AutoplayOptions#pauseOnHover} 사용시 마우스가 캔버스 영역을 떠난 뒤 자동재생이 다시 활성화되기까지의 시간 + * @default 0 + * @since 4.0.0 + */ + get delayOnMouseLeave() { + return this._delayOnMouseLeave; + } + set delayOnMouseLeave(val) { + this._delayOnMouseLeave = val; + } + /** + * Y-axis(yaw) rotation speed + * @ko Y-축 회전(yaw)의 속도 + * @default 1 + * @since 4.0.0 + */ + get speed() { + return this._speed; + } + set speed(val) { + this._speed = val; + } + /** + * Whether to pause rotation on mouse hover + * @ko 마우스가 캔버스 영역에 들어왔을 때 자동재생을 정지할지 여부 + * @default false + * @since 4.0.0 + */ + get pauseOnHover() { + return this._pauseOnHover; + } + set pauseOnHover(val) { + this._pauseOnHover = val; + } + /** + * Whether user can interrupt the rotation with click/wheel input + * @ko 클릭이나 휠같은 사용자 인터랙션시 자동재생을 멈출지 여부 + * @default true + * @since 4.0.0 + */ + get canInterrupt() { + return this._canInterrupt; + } + set canInterrupt(val) { + this._canInterrupt = val; + } + /** + * Whether to disable autoplay on user interrupt + * @ko 사용자 동작에 의해 자동재생이 정지할 때, {@link Autoplay#disable}을 호출하여 자동재생을 영구히 정지할지 여부 + * @default false + * @since 4.0.0 + */ + get disableOnInterrupt() { + return this._disableOnInterrupt; + } + set disableOnInterrupt(val) { + this._disableOnInterrupt = val; + } + /** + * Create new AutoPlayer instance + * @param camera - Instance of the {@link Camera} {@ko Camera의 인스턴스} + * @param element - Canvas element {@ko 캔버스 엘리먼트} + * @param options - Autoplay options {@ko 자동재생 옵션들} + * @since 4.0.0 + */ + constructor(viewer, element, options) { + this._onInputStart = () => { + if (!this._canInterrupt) return; + this._interrupted = true; + this._clearTimeout(); + }; + this._onInputEnd = () => { + this._setUninterruptedAfterDelay(this._delay); + }; + this._onGyroEnable = () => { + this.disable(); + }; + this._onMouseEnter = () => { + if (!this._pauseOnHover) return; + this._interrupted = true; + this._hovering = true; + }; + this._onMouseLeave = () => { + if (!this._pauseOnHover) return; + this._hovering = false; + this._setUninterruptedAfterDelay(this._delayOnMouseLeave); + }; + this._camera = viewer.camera; + this._control = viewer.control; + this._element = element; + this._enabled = false; + this._interrupted = false; + this._interruptionTimer = -1; + this._hovering = false; + const { + delay = 2000, + delayOnMouseLeave = 0, + speed = 1, + pauseOnHover = false, + canInterrupt = true, + disableOnInterrupt = false + } = getObjectOption(options); + this._enableBlocked = !options; + this._delay = delay; + this._delayOnMouseLeave = delayOnMouseLeave; + this._speed = speed; + this._pauseOnHover = pauseOnHover; + this._canInterrupt = canInterrupt; + this._disableOnInterrupt = disableOnInterrupt; + } + /** + * Destroy the instance and remove all event listeners attached + * @ko 인스턴스를 제거하고 연결된 모든 이벤트 핸들러를 삭제합니다. + * @since 4.0.0 + */ + destroy() { + this.disable(); + } + /** + * Rotate camera by given deltaTime + * @ko 주어진 deltaTime만큼 카메라를 회전시킵니다. + * @param deltaTime - Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위} + * @since 4.0.0 + */ + update(deltaTime) { + if (!this._enabled) return; + if (this._interrupted) { + if (this._disableOnInterrupt) { + this.disable(); + } + return; + } + const camera = this._camera; + const delta = -this._speed * deltaTime / 100; + camera.yaw = circulate(camera.yaw + delta, 0, 360); + } + /** + * Enable autoplay and add event listeners. + * @ko 자동재생을 활성화하고 이벤트리스너들을 추가합니다. + * @since 4.0.0 + */ + enable() { + const control = this._control; + const element = this._element; + if (this._enabled || control.gyro.enabled) return; + control.rotate.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.rotate.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.zoom.on(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.zoom.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.gyro.on(CONTROL_EVENTS.ENABLE, this._onGyroEnable); + element.addEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter, false); + element.addEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave, false); + this._enabled = true; + this._enableBlocked = false; + } + /** + * Enable autoplay after current `delay` value. + * @ko 현재의 `delay`값만큼 시간이 지난 다음에 자동재생을 활성화합니다. + * @since 4.0.0 + */ + enableAfterDelay() { + this.enable(); + this._interrupted = true; + this._setUninterruptedAfterDelay(this._delay); + } + /** + * Disable autoplay and remove all event handlers. + * @ko 자동재생을 비활성화하고 모든 이벤트 핸들러를 제거합니다. + * @since 4.0.0 + */ + disable() { + if (!this._enabled) return; + const control = this._control; + const element = this._element; + control.rotate.off(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.rotate.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.zoom.off(CONTROL_EVENTS.INPUT_START, this._onInputStart); + control.zoom.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd); + control.gyro.off(CONTROL_EVENTS.ENABLE, this._onGyroEnable); + element.removeEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter, false); + element.removeEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave, false); + this._enabled = false; + this._interrupted = false; + this._hovering = false; + this._clearTimeout(); + } + _setUninterruptedAfterDelay(delay) { + if (this._hovering) return; + this._clearTimeout(); + if (delay > 0) { + this._interruptionTimer = window.setTimeout(() => { + this._interrupted = false; + this._interruptionTimer = -1; + }, delay); + } else { + this._interrupted = false; + this._interruptionTimer = -1; + } + } + _clearTimeout() { + if (this._interruptionTimer >= 0) { + window.clearTimeout(this._interruptionTimer); + this._interruptionTimer = -1; + } + } + } + + /** + * WebXR manager class + * @ko WebXR 매니저 클래스 + * @since 4.0.0 + */ + class XRManager extends Component { + /** + * Create new instance. + * 새 인스턴스를 생성합니다. + * @param ctx - Instance of WebGL context helper {@ko WebGL 콘텍스트 헬퍼의 인스턴스} + * @param options - Options {@ko 옵션들} + */ + constructor(ctx, options = {}) { + super(); + /** + * Destroy instance and end XR session if there was any. + * @ko 인스턴스를 제거하고, XR 세션이 존재할 경우 종료합니다. + * @since 4.0.0 + */ + this.destroy = () => { + this.exit(); + this.off(); + }; + this._onSessionEnd = () => { + this.exit(); + this.trigger(EVENTS.VR_END); + }; + this._xrSession = null; + this._xrRefSpace = null; + this._ctx = ctx; + this._options = options; + } + /** + * Returns WebXR availability. + * @ko WebXR 사용 가능 여부를 반환합니다. + * @since 4.0.0 + */ + isAvailable() { + return __awaiter(this, void 0, void 0, function* () { + // eslint-disable-next-line compat/compat + const xr = window.navigator.xr; + if (!xr) return false; + return xr.isSessionSupported(SESSION_VR).then(available => { + return available; + }).catch(() => { + return false; + }); + }); + } + /** + * Enter VR session + * @ko VR 세션에 진입합니다. + * @since 4.0.0 + */ + enter() { + return __awaiter(this, void 0, void 0, function* () { + const ctx = this._ctx; + // eslint-disable-next-line compat/compat + const xr = window.navigator.xr; + if (!xr) return; + yield GyroControl.requestSensorPermission(); + const options = Object.assign({ + requiredFeatures: [XR_REFERENCE_SPACE] + }, this._options); + yield ctx.makeXRCompatible(); + const session = yield xr.requestSession(SESSION_VR, options); + ctx.bindXRLayer(session); + const refSpace = yield session.requestReferenceSpace(XR_REFERENCE_SPACE); + this._setSession(session, refSpace); + this.trigger(EVENTS.VR_START, { + session + }); + }); + } + /** + * Exit VR session + * @ko VR 세션에서 나갑니다. + * @since 4.0.0 + */ + exit() { + const xrSession = this._xrSession; + if (xrSession) { + xrSession.end().catch(() => void 0); + } + this._xrSession = null; + this._xrRefSpace = null; + } + /** + * @hidden + */ + canRender(frame) { + const refSpace = this._xrRefSpace; + if (!refSpace) return false; + const pose = frame.getViewerPose(refSpace); + return !!pose; + } + /** + * @hidden + */ + getEyeParams(frame) { + const session = frame.session; + const pose = frame.getViewerPose(this._xrRefSpace); + if (!pose) return null; + const glLayer = session.renderState.baseLayer; + if (!glLayer) return null; + return pose.views.map(view => { + const viewport = glLayer.getViewport(view); + const vMatrix = view.transform.inverse.matrix; + return { + viewport, + vMatrix, + pMatrix: view.projectionMatrix + }; + }); + } + _setSession(session, refSpace) { + this._xrSession = session; + this._xrRefSpace = refSpace; + session.addEventListener(EVENTS$1.XR_END, this._onSessionEnd); + } + } + + /** + * Hotspot data + * @ko 핫스팟 데이터 + * @since 4.0.0 + */ + class Hotspot { + constructor(element, position) { + this.element = element; + this.position = position; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Hotspot renderer + * @ko Hotspot 렌더러 + * @since 4.0.0 + */ + class HotspotRenderer { + /** + * Create new instance + * @ko 새 인스턴스를 생성합니다. + * @param rootEl - Container element for hotspots {@ko 핫스팟들의 컨테이너 엘리먼트} + * @param renderer - instance of WebGLRenderer {@ko WebGLRenderer의 인스턴스} + * @param options - Hotspot options {@ko Hotspot 옵션들 } + */ + constructor(rootEl, renderer, { + zoom = false + }) { + this._containerEl = getNullableElement(`.${DEFAULT_CLASS.HOTSPOT_CONTAINER}`, rootEl); + this._renderer = renderer; + this._hotspots = []; + this._zoom = zoom; + } + /** + * Refresh hotspots by collecting hotspot elements from current hotspot root element + * @ko 현재 핫스팟 루트 엘리먼트 내에서 핫스팟 엘리먼트들을 수집하여 갱신합니다. + * @throws {ERROR_CODES.INSUFFICIENT_ARGS} if data-position doesn't include all x, y, z values {@ko data-position이 x, y, z좌표를 전부 포함하고 있지 않을 때} + */ + refresh() { + const container = this._containerEl; + if (!container) return; + const hotspotEls = [].slice.apply(container.querySelectorAll(`.${DEFAULT_CLASS.HOTSPOT}`)); + this._hotspots = hotspotEls.map(el => this._parseHotspot(el)); + } + /** + * Render hotspots + * @ko 핫스팟들을 렌더링합니다. + * @param camera - Instance of Camera {@ko Camera의 인스턴스} + */ + render(camera) { + const hotspots = this._hotspots; + const halfWidth = this._renderer.width * 0.5; + const halfHeight = this._renderer.height * 0.5; + const zoom = camera.zoom; + const centerTransform = "translate(-50%, -50%)"; + const zoomTransform = this._zoom ? `scale(${zoom})` : ""; + hotspots.forEach(hotspot => { + const position = hotspot.position; + const relPos = create$3(); + copy$2(relPos, position); + transformMat4(relPos, relPos, camera.viewMatrix); + transformMat4(relPos, relPos, camera.projectionMatrix); + if (relPos[2] > 1 || relPos[2] < 0) { + hotspot.element.classList.remove(DEFAULT_CLASS.HOTSPOT_VISIBLE); + return; + } + const screenPos = fromValues(relPos[0] * halfWidth + halfWidth, -relPos[1] * halfHeight + halfHeight); + hotspot.element.classList.add(DEFAULT_CLASS.HOTSPOT_VISIBLE); + hotspot.element.style.transform = [centerTransform, `translate(${screenPos[0]}px, ${screenPos[1]}px)`, zoomTransform].join(" "); + }); + } + _parseHotspot(element) { + const yawStr = element.dataset.yaw; + const pitchStr = element.dataset.pitch; + const positionStr = element.dataset.position; + if (yawStr || pitchStr) { + const yaw = yawStr ? parseFloat(yawStr) : 0; + const pitch = pitchStr ? parseFloat(pitchStr) : 0; + const position = this._yawPitchToVec3(yaw, pitch); + return new Hotspot(element, position); + } else if (positionStr) { + const pos = positionStr.split(" ").map(val => parseFloat(val)); + if (pos.length < 3) { + throw new View360Error(ERROR.MESSAGES.INSUFFICIENT_ARGS(positionStr, "hotspot attribute \"data-position\""), ERROR.CODES.INSUFFICIENT_ARGS); + } + return new Hotspot(element, fromValues$3(pos[0], pos[1], pos[2])); + } else { + // Place hotspot at yaw: 0, pitch: 0 + const defaultPos = fromValues$3(0, 0, -1); + return new Hotspot(element, defaultPos); + } + } + _yawPitchToVec3(yaw, pitch) { + const yawRad = yaw * DEG_TO_RAD; + const pitchRad = pitch * DEG_TO_RAD; + const position = create$3(); + position[1] = Math.sin(pitchRad); + position[2] = Math.cos(pitchRad); + position[0] = position[2] * Math.sin(-yawRad); + position[2] = -position[2] * Math.cos(-yawRad); + return position; + } + } + + /** + * @hidden + */ + class VertexArrayObject { + get count() { + return this.geometry.indicies.count; + } + constructor(obj, geometry, buffers) { + this.obj = obj; + this.geometry = geometry; + this.buffers = buffers; + } + } + + /** + * @hidden + */ + class WebGLContext { + get canvas() { + return this._canvas; + } + get maxTextureSize() { + return this._maxTextureSize; + } + get isWebGL2() { + return this._isWebGL2; + } + get supportVAO() { + return this._isWebGL2 || !!this._extensions.vao; + } + get lost() { + return this._contextLost; + } + get debug() { + return this._debug; + } + constructor(canvas, debug) { + this._onContextLost = () => { + const canvas = this._canvas; + canvas.classList.add(DEFAULT_CLASS.CTX_LOST); + this._contextLost = true; + }; + this._onContextRestore = () => { + const canvas = this._canvas; + canvas.classList.remove(DEFAULT_CLASS.CTX_LOST); + this._contextLost = false; + }; + this._canvas = canvas; + this._contextLost = false; + this._debug = debug; + this._extensions = { + vao: null, + loseContext: null + }; + } + init() { + const canvas = this._canvas; + const { + gl, + isWebGL2 + } = this._getContext(canvas); + this._gl = gl; + this._maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); + this._isWebGL2 = isWebGL2; + if (!this._isWebGL2) { + this._extensions.vao = gl.getExtension("OES_vertex_array_object"); + } + this._extensions.loseContext = gl.getExtension("WEBGL_lose_context"); + canvas.addEventListener(EVENTS$1.CONTEXT_LOST, this._onContextLost); + canvas.addEventListener(EVENTS$1.CONTEXT_RESTORED, this._onContextRestore); + // gl.enable(gl.DEPTH_TEST); + } + + destroy() { + const gl = this._gl; + const canvas = this._canvas; + if (gl) { + // gl is not defined when destroy is called before init + gl.bindBuffer(gl.ARRAY_BUFFER, null); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + } + canvas.removeEventListener(EVENTS$1.CONTEXT_LOST, this._onContextLost); + canvas.removeEventListener(EVENTS$1.CONTEXT_RESTORED, this._onContextRestore); + } + forceLoseContext() { + const extension = this._extensions.loseContext; + if (!extension) return; + extension.loseContext(); + } + forceRestoreContext() { + const extension = this._extensions.loseContext; + if (!extension) return; + extension.restoreContext(); + } + clear() { + const gl = this._gl; + gl.clear(gl.COLOR_BUFFER_BIT); + } + resize() { + const gl = this._gl; + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + } + viewport(x, y, width, height) { + const gl = this._gl; + gl.viewport(x, y, width, height); + } + createVAO(geometry, shaderProgram) { + const nativeVAO = this._createNativeVAO(); + const vao = new VertexArrayObject(nativeVAO, geometry, { + indicies: this._createBuffer(), + position: this._createBuffer(), + uv: this._createBuffer() + }); + if (nativeVAO) { + this._bindNativeVAO(nativeVAO); + this._supplyGeometryData(vao, shaderProgram); + this._bindNativeVAO(null); + this._unbindBuffers(); + } + return vao; + } + draw(vao, shaderProgram) { + const gl = this._gl; + if (vao.obj) { + this._bindNativeVAO(vao.obj); + } else { + this._supplyGeometryData(vao, shaderProgram); + } + gl.drawElements(gl.TRIANGLES, vao.count, gl.UNSIGNED_SHORT, 0); + if (vao.obj) { + this._bindNativeVAO(null); + } else { + this._unbindBuffers(); + } + } + releaseVAO(vao) { + if (vao.obj) { + this._deleteNativeVAO(vao.obj); + } + this._deleteBuffer(vao.buffers.indicies); + this._deleteBuffer(vao.buffers.position); + this._deleteBuffer(vao.buffers.uv); + } + getUniformLocations(program, uniforms) { + const gl = this._gl; + const uniformLocations = Object.keys(uniforms).reduce((locations, key) => { + locations[key] = gl.getUniformLocation(program, key); + return locations; + }, {}); + return Object.assign(Object.assign({}, this._getCommonUniformLocations(program)), uniformLocations); + } + updateCommonUniforms(entity, camera, shaderProgram) { + const gl = this._gl; + const uniformLocations = shaderProgram.uniformLocations; + // We're using "matrix"(=local matrix) here for efficiency + // As projection doesn't require world matrix, as it doesn't have any parent or child + const matrix = entity.matrix; + const mvMatrix = create$4(); + multiply$1(mvMatrix, camera.viewMatrix, matrix); + gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix); + gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, camera.projectionMatrix); + } + updateVRUniforms(shaderProgram, mvMatrix, pMatrix, eyeIndex) { + const gl = this._gl; + const uniformLocations = shaderProgram.uniformLocations; + gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix); + gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, pMatrix); + if (uniformLocations.uEye) { + gl.uniform1f(uniformLocations.uEye, eyeIndex); + } + } + updateUniforms(shaderProgram) { + const gl = this._gl; + const uniforms = shaderProgram.uniforms; + const uniformLocations = shaderProgram.uniformLocations; + for (const key in uniforms) { + const uniform = uniforms[key]; + const location = uniformLocations[key]; + if (!uniform) continue; + if (uniform.needsUpdate) { + uniform.update(gl, location, this._isWebGL2); + } + } + } + releaseShaderResources(shaderProgram) { + const gl = this._gl; + const uniforms = shaderProgram.uniforms; + for (const key in uniforms) { + const uniform = uniforms[key]; + if (!uniform) continue; + if (uniform.needsUpdate) { + uniform.destroy(gl); + } + } + gl.deleteProgram(shaderProgram.program); + } + useProgram(shaderProgram) { + const gl = this._gl; + gl.useProgram(shaderProgram.program); + } + createProgram(vertexShader, fragmentShader) { + const gl = this._gl; + const program = gl.createProgram(); + const vs = this._compileShader(gl.VERTEX_SHADER, vertexShader); + const fs = this._compileShader(gl.FRAGMENT_SHADER, fragmentShader); + gl.attachShader(program, vs); + gl.attachShader(program, fs); + gl.bindAttribLocation(program, 0, "position"); + gl.bindAttribLocation(program, 1, "uv"); + gl.linkProgram(program); + if (this._debug && !gl.getProgramParameter(program, gl.LINK_STATUS)) { + let shaderLog = null; + if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) { + shaderLog = gl.getShaderInfoLog(vs); + } else if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) { + shaderLog = gl.getShaderInfoLog(fs); + } + throw new View360Error(ERROR.MESSAGES.FAILED_LINKING_PROGRAM(gl.getProgramInfoLog(program), shaderLog), ERROR.CODES.FAILED_LINKING_PROGRAM); + } + gl.deleteShader(vs); + gl.deleteShader(fs); + return program; + } + createWebGLTexture(texData) { + const gl = this._gl; + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texData.wrapS); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texData.wrapT); + if (!texData.isVideo() && this._isWebGL2) { + const gl2 = gl; + gl2.texStorage2D(gl2.TEXTURE_2D, 1, gl2.RGBA8, texData.width, texData.height); + } + return texture; + } + createWebGLCubeTexture(texData, size) { + const gl = this._gl; + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, texData.wrapS); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, texData.wrapT); + if (this._isWebGL2) { + const gl2 = gl; + gl2.texStorage2D(gl2.TEXTURE_CUBE_MAP, 1, gl2.RGBA8, size, size); + } + return texture; + } + makeXRCompatible() { + return __awaiter(this, void 0, void 0, function* () { + const gl = this._gl; + const attributes = gl.getContextAttributes(); + if (attributes && attributes.xrCompatible !== true) { + yield gl.makeXRCompatible(); + } + }); + } + bindXRLayer(session) { + const gl = this._gl; + const xrLayer = new XRWebGLLayer(session, gl); + session.updateRenderState({ + baseLayer: xrLayer + }); + } + bindXRFrame(frame) { + const gl = this._gl; + const session = frame.session; + const baseLayer = session.renderState.baseLayer; + gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer); + } + useDefaultFrameBuffer() { + const gl = this._gl; + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + } + _createBuffer() { + return this._gl.createBuffer(); + } + _deleteBuffer(buffer) { + return this._gl.deleteBuffer(buffer); + } + _createNativeVAO() { + const gl = this._gl; + if (this._isWebGL2) { + return gl.createVertexArray(); + } else { + const ext = this._extensions.vao; + return (ext === null || ext === void 0 ? void 0 : ext.createVertexArrayOES()) || null; + } + } + _bindNativeVAO(vao) { + const gl = this._gl; + if (this._isWebGL2) { + gl.bindVertexArray(vao); + } else { + const ext = this._extensions.vao; + ext === null || ext === void 0 ? void 0 : ext.bindVertexArrayOES(vao); + } + } + _deleteNativeVAO(vao) { + const gl = this._gl; + if (this._isWebGL2) { + gl.deleteVertexArray(vao); + } else { + const ext = this._extensions.vao; + ext === null || ext === void 0 ? void 0 : ext.deleteVertexArrayOES(vao); + } + } + _supplyGeometryData(vao, shaderProgram) { + const geometry = vao.geometry; + this._supplyIndiciesData(geometry.indicies, vao.buffers.indicies); + this._supplyAttributeData(geometry.vertices, shaderProgram.program, "position", vao.buffers.position); + this._supplyAttributeData(geometry.uvs, shaderProgram.program, "uv", vao.buffers.uv); + } + _unbindBuffers() { + const gl = this._gl; + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + gl.bindBuffer(gl.ARRAY_BUFFER, null); + } + _supplyIndiciesData(indicies, buffer) { + const gl = this._gl; + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicies.data, gl.STATIC_DRAW); + } + _supplyAttributeData(attribute, program, name, buffer) { + const gl = this._gl; + const attribLocation = gl.getAttribLocation(program, name); + // Attribute not used + if (attribLocation < 0) return; + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData(gl.ARRAY_BUFFER, attribute.data, gl.STATIC_DRAW); + gl.vertexAttribPointer(attribLocation, attribute.itemSize, gl.FLOAT, false, 0, 0); + gl.enableVertexAttribArray(attribLocation); + } + _compileShader(type, src) { + const gl = this._gl; + const shader = gl.createShader(type); + gl.shaderSource(shader, src); + gl.compileShader(shader); + return shader; + } + _getCommonUniformLocations(program) { + const gl = this._gl; + return { + uMVMatrix: gl.getUniformLocation(program, "uMVMatrix"), + uPMatrix: gl.getUniformLocation(program, "uPMatrix") + }; + } + _getContext(canvas) { + const webglIdentifiers = ["webgl2", "webgl", "experimental-webgl", "webkit-3d", "moz-webgl"]; + let context = null; + let isWebGL2 = false; + const contextAttributes = { + preserveDrawingBuffer: false, + antialias: false + }; + const onWebglContextCreationError = e => e.statusMessage; + canvas.addEventListener(EVENTS$1.CONTEXT_CREATE_ERROR, onWebglContextCreationError); + for (const identifier of webglIdentifiers) { + try { + context = canvas.getContext(identifier, contextAttributes); + isWebGL2 = identifier === "webgl2"; + } catch (t) {} // eslint-disable-line no-empty + if (context) { + break; + } + } + canvas.removeEventListener(EVENTS$1.CONTEXT_CREATE_ERROR, onWebglContextCreationError); + if (!context) { + throw new View360Error(ERROR.MESSAGES.WEBGL_NOT_SUPPORTED, ERROR.CODES.WEBGL_NOT_SUPPORTED); + } + return { + gl: context, + isWebGL2 + }; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection renderer, based on WebGL + * @ko WebGL 기반의 프로젝션 렌더러 + * @since 4.0.0 + */ + class WebGLRenderer { + /** + * Canvas element + * @ko 캔버스 엘리먼트 + * @since 4.0.0 + */ + get canvas() { + return this._canvas; + } + /** + * Canvas's width (`devicePixelRatio` is not applied) + * @ko 캔버스의 보이는 너비 (`devicePixelRatio`가 적용되지 않은) + * @since 4.0.0 + */ + get width() { + return this._elementSize.x; + } + /** + * Canvas's height (`devicePixelRatio` is not applied) + * @ko 캔버스의 높이 (`devicePixelRatio`가 적용되지 않은) + * @since 4.0.0 + */ + get height() { + return this._elementSize.y; + } + /** + * Current `devicePixelRatio` value. + * @ko 현재 `devicePixelRatio` 값. + * @since 4.0.0 + * @example + * ```js + * cosnt renderingWidth = view360.renderer.width * view360.renderer.pixelRatio; + * ``` + */ + get pixelRatio() { + return this._pixelRatio; + } + /** + * Width / height ratio (= width / height) + * @ko 너비 / 높이의 비율 (= width / height) + * @since 4.0.0 + * @example + * ```js + * const aspect = view360.renderer.width / view360.renderer.pixelRatio; + * assert(aspect === view360.renderer.aspect); + * ``` + */ + get aspect() { + return this._elementSize.x / this._elementSize.y; + } + /** + * Create new instance + * @ko 새 인스턴스를 생성합니다. + * @param canvas - Canvas element {@ko 캔버스 엘리먼트} + * @param debug - Whether to enable WebGL debugging {@ko WebGL debug 활성화 여부 } + */ + constructor(canvas, debug) { + this._canvas = canvas; + this._elementSize = { + x: 0, + y: 0 + }; + this._pixelRatio = 1; + this.ctx = new WebGLContext(canvas, debug); + } + /** + * Destroy instance and release all resources. + * @ko 인스턴스를 제거하고 사용된 리소스를 전부 해제합니다. + * @since 4.0.0 + */ + destroy() { + const canvas = this._canvas; + this.ctx.destroy(); + canvas.width = 1; + canvas.height = 1; + } + /** + * Resize canvas and renew inner size cache. + * @ko 캔버스의 크기를 재계산해서 내부의 사이즈 캐시값을 갱신합니다. + * @since 4.0.0 + */ + resize() { + const canvas = this._canvas; + const canvasSize = this._elementSize; + const devicePixelRatio = window.devicePixelRatio; + canvasSize.x = canvas.clientWidth; + canvasSize.y = canvas.clientHeight; + canvas.width = canvasSize.x * devicePixelRatio; + canvas.height = canvasSize.y * devicePixelRatio; + this._pixelRatio = devicePixelRatio; + this.ctx.resize(); + } + /** + * Render projection + * @ko 프로젝션을 렌더링합니다. + * @param projection - Projection to render {@ko 렌더링할 프로젝션} + * @param cameraa - Camera instance {@ko 카메라의 인스턴스} + * @since 4.0.0 + */ + render(projection, camera) { + const ctx = this.ctx; + const mesh = projection.getMesh(); + if (ctx.lost || !mesh) return; + ctx.clear(); + ctx.useProgram(mesh.program); + ctx.updateCommonUniforms(mesh, camera, mesh.program); + projection.update(camera); + ctx.updateUniforms(mesh.program); + ctx.draw(mesh.vao, mesh.program); + } + /** + * Render VR frame, only used for rendering frames inside VR sessions. + * @ko VR 프레임을 렌더링합니다. VR 세션 진입 도중에만 사용됩니다. + * @internal + * @param projection - Projection to render {@ko 렌더링할 프로젝션} + * @param vr - Instance of XRManager {@ko XRManager의 인스턴스} + * @param frame - VR frame {@ko VR 프레임} + * @since 4.0.0 + */ + renderVR(projection, vr, frame) { + const ctx = this.ctx; + const mesh = projection.getMesh(); + const eyeParams = vr.getEyeParams(frame); + if (!eyeParams || !mesh) return; + ctx.bindXRFrame(frame); + ctx.useProgram(mesh.program); + ctx.updateUniforms(mesh.program); + eyeParams.forEach((eye, eyeIndex) => { + const viewport = eye.viewport; + // We're using "mesh.matrix"(=local matrix) here for efficiency + // As projection doesn't require world matrix, as it doesn't have any parent or child + const mvMatrix = multiply$1(create$4(), eye.vMatrix, mesh.matrix); + ctx.viewport(viewport.x, viewport.y, viewport.width, viewport.height); + ctx.updateVRUniforms(mesh.program, mvMatrix, eye.pMatrix, eyeIndex); + ctx.draw(mesh.vao, mesh.program); + }); + } + } + + /** + * Panorama 360 image viewer + * @ko 파노라마 360 이미지 뷰어 + * @since 4.0.0 + * @see View360Options + * @see View360Events + */ + class View360 extends Component { + /** + * Root element (`.view360-container`) + * @ko 루트 엘리먼트 (`.view360-container`) + * @since 4.0.0 + * @readonly + * @example + * ```html + *
+ * + *
+ * ``` + * ```ts + * import View360 from "@egjs/view360"; + * + * const viewer = new View360("#viewer"); + * console.log(viewer.rootEl); // Element with id "viewer" + * ``` + */ + get rootEl() { + return this._rootEl; + } + /** + * Projection renderer. + * @ko 프로젝션 렌더러. + * @since 4.0.0 + * @readonly + */ + get renderer() { + return this._renderer; + } + /** + * Projection camera. + * @ko 프로젝션 카메라. + * @since 4.0.0 + * @readonly + */ + get camera() { + return this._camera; + } + /** + * Rotate/Zoom Controller. + * @ko 회전/줌 컨트롤러. + * @since 4.0.0 + * @readonly + */ + get control() { + return this._control; + } + /** + * WebXR-based VR manager. + * @ko WebXR 기반의 VR 기능 매니저 인스턴스. + * @since 4.0.0 + * @readonly + * @example + * ```ts + * // Example: Enter VR + * // This must be called on user interaction, else will be rejected. + * viewer.vr.enter(); + * ``` + */ + get vr() { + return this._vr; + } + /** + * Hotspot renderer. + * You can also change options of {@link View360Options#hotspot} with this. + * @ko 핫스팟 렌더러 인스턴스. + * {@link View360Options#hotspot} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get hotspot() { + return this._hotspot; + } + /** + * An array of plugins added. + * @ko 추가된 플러그인의 배열 + * @since 4.0.0 + * @readonly + * @example + * ```ts + * const viewer = new View360("#el_id", { + * plugins: [new ControlBar()] + * }); + * + * console.log(viewer.plugins); // [ControlBar] + * + * viewer.addPlugins(new LoadingSpinner()) // [ControlBar, LoadingSpinner]; + * ``` + */ + get plugins() { + return this._plugins; + } + /** + * A instance of {@link Projection} that currently enabled. `null` if not initialized yet. + * You should call {@link View360#load} to change panorama src or projection type. + * @ko 현재 사용중인 {@link Projection}의 인스턴스. 프로젝션을 활성화하지 않았을 경우 `null`입니다. + * 파노라마 이미지 소스나 프로젝션 타입을 변경하려면 {@link View360#load}를 호출하면 됩니다. + * @since 4.0.0 + * @readonly + * @example + * ```ts + * const viewer = new View360 + * ``` + */ + get projection() { + return this._projection; + } + set projection(val) { + if (this._initialized && val) { + this.load(val); + } else { + this._projection = val; + } + } + /** + * A boolean value whether {@link View360#init init()} is called before. + * @ko {@link View360#init init()}이 호출되었는지 여부를 가리키는 값 + * @since 4.0.0 + * @readonly + * @example + * ```ts + * const viewer = new View360("#el", { autoInit: false }); + * + * console.log(viewer.initialized); // false + * + * await viewer.init(); + * + * console.log(viewer.initialized); // true + * ``` + */ + get initialized() { + return this._initialized; + } + /** + * Instance of the Autoplay manager. + * You can also change {@link View360Options#autoplay} options with this. + * @ko Autoplay 기능의 매니저 인스턴스. + * 이 인스턴스를 통해 {@link View360Options#autoplay} 옵션을 변경하는 것도 가능합니다. + * @since 4.0.0 + * @readonly + * @example + * ```ts + * // Disable autoplay + * viewer.autoplay.disable(); + * ``` + */ + get autoplay() { + return this._autoplay; + } + /** + * When this value is `true` and {@link View360Options#projection} is set, {@link View360#init init()} will be called automatically when instance is created. + * @ko 이 값이 `true`이고, {@link View360Options#projection}이 설정되었으면, 인스턴스 생성 시점에 자동으로 {@link View360#init init()}을 호출합니다. + * @default true + * @since 4.0.0 + * @example + * ```ts + * import View360, { EquirectProjection, EVENTS } from "@egjs/view360"; + * + * // viewer.init() is called on instance creation + * // But as `init` is asynchronous, you should wait for "ready" event if you want to do something after initialization. + * const viewer = new View360("#el_id", { + * autoInit: true, + * projection: new EquirectProjection({ src: "SRC_TO_URL" }) + * }); + * + * console.log(viewer.initialized); // false, as `init` is asynchronous + * + * viewer.once(EVENTS.READY, () => { + * console.log(viewer.initialized); // true + * }); + * ``` + */ + get autoInit() { + return this._autoInit; + } + /** + * When `true`, {@link View360#resize} is called when the canvas size is changed. + * @ko `true`일 경우, 캔버스의 크기가 변경되었을 때 자동으로 {@link View360#resize}를 호출합니다. + * @default true + * @since 4.0.0 + * @see View360#useResizeObserver + * @example + * ```ts + * const viewer = new View360("#el_id", { + * autoResize: true + * }); + * + * // This can trigger `viewer.resize()` if the canvas size was not 400px + * const canvas = viewer.renderer.canvas; + * canvas.style.width = "400px"; + * ``` + */ + get autoResize() { + return this._autoResize; + } + /** + * CSS selector for canvas element to render panorama image/video. + * The canvas element should be placed inside the root element. (Dont' have to be direct child) + * @ko 파노라마 이미지/비디오를 렌더링할 canvas 엘리먼트의 CSS 선택자 + * 캔버스 엘리먼트는 루트 엘리먼트 내부에 있어야합니다. 루트 엘리먼트의 직계 자식 엘리먼트(Direct child element)일 필요는 없습니다. + * @default "canvas" + * @since 4.0.0 + * @example + * ```html + *
+ * + * + * + *
+ * ``` + * + * ```ts + * const viewer = new View360("#el_id", { + * canvasSelector: "#canvas_to_select" + * }); + * ``` + */ + get canvasSelector() { + return this._canvasSelector; + } + /** + * When `true`, it will use {@link ResizeObserver} API to detect canvas size change when {@link View360Options#autoResize} is enabled. + * @ko `true`일 때 {@link View360Options#autoResize}가 활성화되었으면, 사용 가능한 환경에서 {@link ResizeObserver} API를 사용해서 캔버스 크기 변화를 추적합니다. + * @default true + * @since 4.0.0 + */ + get useResizeObserver() { + return this._useResizeObserver; + } + /** + * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} attribute for the canvas element. + * This is necessary for the keyboard controls. + * By default, `0` will be assigned. `null` to disable. + * @ko 캔버스 엘리먼트에 적용할 {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} 어트리뷰트의 값. + * 이 값을 설정해야만 키보드 컨트롤을 사용 가능합니다. + * 기본값으로 `0`이 설정됩니다. `null`로 지정하면 `tabindex`를 설정하지 않습니다. + * @see RotateControlOptions#disableKeyboard + * @default 0 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * tabindex: 5 + * }); + * ``` + * + * ```html + * + *
+ * + *
+ * ``` + */ + get tabIndex() { + return this._tabIndex; + } + set tabIndex(val) { + const canvas = this._renderer.canvas; + this._tabIndex = val; + if (val != null) { + canvas.tabIndex = val; + } else { + canvas.removeAttribute("tabindex"); + } + } + /** + * A maximum delta time between frames in seconds. + * It can prevent camera or control changing too fast when frame being late. + * @ko 프레임간 시간 차이의 최대값. (초 단위) + * 퍼포먼스 등의 이유로 프레임 렌더링이 늦어졌을 때, 화면이 갑작스럽게 바뀌는 것을 막아줍니다. + * @default 1 / 30 + * @since 4.0.0 + */ + get maxDeltaTime() { + return this._animator.maxDeltaTime; + } + set maxDeltaTime(val) { + this._animator.maxDeltaTime = val; + } + /** + * Enable WebGL debugging. Setting this to `true` can decrease performance. + * This is used internally on developing View360. + * @ko WebGL 디버깅을 활성화합니다. 이 값을 `true`로 할 경우 성능이 하락할 수 있습니다. + * 이 옵션은 View360을 개발하기 위해 내부적으로 사용됩니다. + * @default false + */ + get debug() { + return this._debug; + } + set debug(val) { + this._debug = val; + } + // Camera options + /** + * Initial yaw (y-axis rotation) value for camera. (in degrees, °) + * As View360 uses right-handed coordinate system internally, camera will rotate counter-clockwise by this value. + * @ko 카메라의 초기 yaw(y축 회전)값 (도 단위, °) + * View360은 오른손 좌표계를 사용하기 때문에, 카메라가 해당 값만큼 시계 반대방향으로 회전합니다. + * @default 0 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * initialYaw: 30 + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.yaw); // 30 + * }); + * ``` + */ + get initialYaw() { + return this._camera.initialYaw; + } + set initialYaw(val) { + this._camera.initialYaw = val; + } + /** + * Initial pitch (x-axis rotation) value for camera. (in degrees, °) + * As View360 uses right-handed coordinate system internally, positive value will make camera to look upside, while negative value will look down. + * @ko 카메라의 초기 pitch(x축 회전)값 (도 단위, °) + * View360은 오른손 좌표계를 사용하기 때문에, 양(+)의 값은 카메라가 위를 보게 하고, 음(-)의 값은 카메라가 아래를 보게 합니다. + * @default 0 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * initialPitch: 60 + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.pitch); // 60 + * }); + * ``` + */ + get initialPitch() { + return this._camera.initialPitch; + } + set initialPitch(val) { + this._camera.initialPitch = val; + } + /** + * Initial zoom value for camera. + * Setting this value to `2` will enlarge panorama 200% by width. + * @ko 카메라의 초기 줌 값. + * 이 값을 `2`로 설정할 경우 파노라마 이미지를 가로 기준 200%만큼 확대합니다. + * @default 1 + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * initialZoom: 2 + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.zoom); // 2 + * }); + * ``` + */ + get initialZoom() { + return this._camera.initialZoom; + } + set initialZoom(val) { + this._camera.initialZoom = val; + } + /** + * Restrict yaw(y-axis rotation) range. (in degrees, °) + * @ko yaw(y축 회전) 범위를 제한합니다. (도 단위, °) + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * yawRange: [-30, 30] + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.yaw); // 0 + * viewer.camera.lookAt({ yaw: 60 }); + * console.log(viewer.camera.yaw); // 30 + * }); + * ``` + */ + get yawRange() { + return this._camera.yawRange; + } + set yawRange(val) { + this._camera.yawRange = val; + if (this._projection) this._projection.updateCamera(this._camera); + } + /** + * Restrict pitch(x-axis rotation) range. (in degrees, °) + * @ko pitch(x축 회전) 범위를 제한합니다. (도 단위, °) + * @default null + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * pitchRange: [-45, 45] + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.pitch); // 0 + * viewer.camera.lookAt({ pitch: 60 }); + * console.log(viewer.camera.pitch); // 45 + * }); + * ``` + */ + get pitchRange() { + return this._camera.pitchRange; + } + set pitchRange(val) { + this._camera.pitchRange = val; + if (this._projection) this._projection.updateCamera(this._camera); + } + /** + * Restrict camera zoom range. + * If `null`, a default zoom range from `0.6` to `10` will be used. + * @ko 카메라 줌 범위를 제한합니다. + * `null`일 경우 기본값으로 `0.6`에서 `10`의 범위를 사용합니다. + * @default null + * @since 4.0.0 + * @example + * ```ts + * const viewer = new View360("#el_id", { + * zoomRange: [0.5, 4] + * }); + * + * viewer.on("ready", () => { + * console.log(viewer.camera.zoom); // 1 + * viewer.camera.lookAt({ zoom: 6 }); + * console.log(viewer.camera.zoom); // 4 + * }); + * ``` + */ + get zoomRange() { + return this._camera.zoomRange; + } + set zoomRange(val) { + this._camera.zoomRange = val; + if (this._projection) this._projection.updateCamera(this._camera); + } + /** + * Camera's horizontal FOV(Field of View). (in degrees, °) + * @ko 카메라의 수평 FOV(Field of View) 값. (도 단위, °) + * @default 90 + * @since 4.0.0 + * @example + * ```ts + * // Init with fov: 120 + * const viewer = new View360("#el_id", { fov: 120 }); + * + * // Back to 90 + * viewer.fov = 90; + * ``` + */ + get fov() { + return this._camera.fov; + } + set fov(val) { + const camera = this._camera; + const control = this._control; + camera.fov = val; + camera.updateMatrix(); + control.sync(); + } + // Control options + /** + * A control for camera rotation. + * You can also change options of {@link View360Options#rotate} with this. + * @ko 카메라 회전을 담당하는 컨트롤. + * {@link View360Options#rotate} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get rotate() { + return this._control.rotate; + } + /** + * A control for camera zoom. + * You can also change options of {@link View360Options#zoom} with this. + * @ko 카메라 줌을 담당하는 컨트롤. + * {@link View360Options#zoom} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get zoom() { + return this._control.zoom; + } + /** + * A control for camera rotation with gyroscope input. + * You can also change options of {@link View360Options#gyro} with this. + * @ko 자이로스코프를 통한 카메라 회전을 담당하는 컨트롤. + * {@link View360Options#gyro} 옵션 변경도 가능합니다. + * @since 4.0.0 + * @readonly + */ + get gyro() { + return this._control.gyro; + } + /** + * Apply CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor} by current state of input when using mouse. + * If `true`, this will add CSS style to canvas element. It'll apply `cursor: "grab"` by default and `cursor: "grabbing"` when holding the mouse button. + * @ko 마우스 사용시 CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor}값을 자동으로 변경할지 여부. + * `true`일 경우 기본 상태에서 `cursor: "grab"`을, 입력 도중에 `cursor: "grabbing"`을 캔버스에 적용합니다. + * @default true + * @since 4.0.0 + */ + get useGrabCursor() { + return this._control.useGrabCursor; + } + set useGrabCursor(val) { + this._control.useGrabCursor = val; + } + /** + * Disable context menu which pops up on mouse right click. + * @ko 마우스 우클릭시 표시되는 컨텍스트 메뉴를 비활성화합니다. + * @default false + * @since 4.0.0 + */ + get disableContextMenu() { + return this._control.disableContextMenu; + } + set disableContextMenu(val) { + this._control.disableContextMenu = val; + } + /** + * If `true`, enables scroll on mobile(touch) devices on canvas. + * :::caution + * When this option is enabled, users must swipe horizontally first then vertically to change view up or down. + * ::: + * @ko `true`로 설정할 경우, 모바일(터치) 환경의 캔버스 영역 내에서 스크롤을 가능하게 합니다. + * :::caution + * 이 값을 활성화할 경우, 사용자가 카메라 뷰를 위/아래로 바꾸기 위해서는 먼저 가로로 스와이프한 이후에 세로로 스와이프해야만 합니다. + * ::: + * @since 4.0.0 + * @default true + */ + get scrollable() { + return this._control.scrollable; + } + set scrollable(val) { + this._control.scrollable = val; + } + /** + * If `true`, enables scroll by mouse wheel on canvas. + * :::caution + * When this option is enabled, zoom by mouse wheel will be disabled. + * ::: + * @ko `true`로 설정할 경우, 캔버스 영역 내에서 마우스 휠을 이용한 페이지 스크롤이 가능해집니다. + * :::caution + * 이 값을 활성화할 경우, 마우스 휠을 통한 줌이 불가능하게 됩니다. + * ::: + * @since 4.0.0 + * @default false + */ + get wheelScrollable() { + return this._control.wheelScrollable; + } + set wheelScrollable(val) { + this._control.wheelScrollable = val; + } + /** + * Create new instance of View360 + * @ko View360의 새로운 인스턴스를 생성합니다 + * @param root - Root element(`.view360-container`) to mount View360 + * Can be either a CSS selector or HTMLElement. + * {@ko View360을 마운트할 루트 엘리먼트, CSS 셀렉터나 HTMLElement를 지정 가능합니다.} + * @param options - Options to apply + * {@ko 적용할 옵션들} + * @example + * ```ts + * import View360, { EquirectProjection } from "@egjs/view360"; + * + * // Create new View360 instance + * const viewer = new View360("#id-of-a-container", { + * projection: new EquirectProjection({ + * src: "URL_TO_PANORAMA_IMAGE_OR_VIDEO", + * }) + * }); + * ``` + */ + constructor(root, { + projection = null, + initialYaw = 0, + initialPitch = 0, + initialZoom = 1, + yawRange = null, + pitchRange = null, + zoomRange = null, + fov = 90, + useGrabCursor = true, + disableContextMenu = false, + rotate = true, + zoom = true, + gyro = false, + scrollable = true, + wheelScrollable = false, + autoplay = false, + hotspot = {}, + autoInit = true, + autoResize = true, + canvasSelector = "canvas", + useResizeObserver = true, + on = {}, + plugins = [], + maxDeltaTime = 1 / 30, + tabIndex = 0, + debug = false + } = {}) { + super(); + /** + * Render a single panorama image/video frame. + * Rendering is performed automatically on demand, so you usually don't have to call this. + * Call this when a frame is not renewed after changing options. + * @ko 파노라마 이미지/비디오의 한 프레임을 렌더링합니다. + * 프레임 갱신은 보통 필요한 때에만 자동적으로 이루어지기 때문에, 보통은 이 메소드를 호출할 필요는 없습니다. + * 옵션 변경 이후에도 프레임 갱신이 이루어지지 않는다면, 이 메소드를 호출해주세요. + * @param delta Delta time in milisec. {@ko 프레임간 시간 차이, 밀리초 단위} + * @since 4.0.0 + */ + this.renderFrame = delta => { + const camera = this._camera; + const renderer = this._renderer; + const control = this._control; + const hotspot = this._hotspot; + const autoPlayer = this._autoplay; + const projection = this._projection; + if (!projection) return; + this._emit(EVENTS.BEFORE_RENDER); + if (autoPlayer.playing) { + autoPlayer.update(delta); + control.sync(); + } + if (camera.animation) { + camera.animation.update(delta); + } else { + control.update(delta); + } + renderer.render(projection, camera); + hotspot.render(camera); + if (camera.changed) { + this._emit(EVENTS.VIEW_CHANGE, { + yaw: camera.yaw, + pitch: camera.pitch, + zoom: camera.zoom, + quaternion: [camera.quaternion[0], camera.quaternion[1], camera.quaternion[2], camera.quaternion[3]] + }); + } + camera.onFrameRender(); + this._emit(EVENTS.RENDER); + }; + this._renderFrameOnDemand = delta => { + var _a; + const camera = this._camera; + const control = this._control; + const autoplay = this._autoplay; + const texture = (_a = this._projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (!this._initialized || !texture) return; + if (!camera.animation && !control.animating && !autoplay.playing && !texture.isVideo()) return; + this.renderFrame(delta); + }; + this._renderVRFrame = (_delta, frame) => { + const vr = this._vr; + const projection = this._projection; + const renderer = this._renderer; + if (!projection) return; + this._emit(EVENTS.BEFORE_RENDER); + renderer.renderVR(projection, vr, frame); + this._emit(EVENTS.RENDER); + }; + this._rootEl = getElement(root); + this._plugins = plugins; + this._initialized = false; + // Options + this._autoInit = autoInit; + this._autoResize = autoResize; + this._canvasSelector = canvasSelector; + this._useResizeObserver = useResizeObserver; + this._tabIndex = tabIndex; + this._debug = debug; + // Core components + const canvas = findCanvas(this._rootEl, canvasSelector); + this._renderer = new WebGLRenderer(canvas, debug); + this._camera = new Camera({ + initialYaw, + initialPitch, + initialZoom, + fov, + yawRange, + pitchRange, + zoomRange + }); + this._control = new PanoControl(canvas, this._camera, { + useGrabCursor, + scrollable, + wheelScrollable, + disableContextMenu, + rotate, + zoom, + gyro + }); + this._animator = new FrameAnimator(maxDeltaTime); + this._autoplay = new Autoplay(this, canvas, autoplay); + this._projection = projection; + this._autoResizer = new AutoResizer(useResizeObserver, () => this.resize()); + this._vr = new XRManager(this._renderer.ctx); + this._hotspot = new HotspotRenderer(this._rootEl, this._renderer, hotspot); + this._addEventHandlers(on); + if (projection && autoInit) { + this.init(); + } + } + /** + * Destroy instance and release all resources. + * @ko 인스턴스를 제거하고 모든 리소스를 해제합니다. + * @since 4.0.0 + */ + destroy() { + this._camera.destroy(); + this._animator.stop(); + this._renderer.destroy(); + this._control.destroy(); + this._autoResizer.disable(); + if (this._projection) { + this._projection.releaseAllResources(this._renderer.ctx); + this._projection = null; + } + this._plugins.forEach(plugin => plugin.destroy(this)); + this._initialized = false; + } + /** + * Initialize inner components and load projection src. + * @ko 내부 컴포넌트들을 초기화하고 프로젝션 소스를 로드합니다. + * @since 4.0.0 + */ + init() { + return __awaiter(this, void 0, void 0, function* () { + if (!this._projection) { + throw new View360Error(ERROR.MESSAGES.PROVIDE_PROJECTION_FIRST, ERROR.CODES.PROVIDE_PROJECTION_FIRST); + } + const renderer = this._renderer; + const camera = this._camera; + const control = this._control; + const animator = this._animator; + const hotspot = this._hotspot; + const projection = this._projection; + const canvas = renderer.canvas; + this._bindComponentEvents(); + renderer.ctx.init(); + this._resizeComponents(); + camera.updateMatrix(); + if (this._autoResize) { + this._autoResizer.enable(canvas); + } + if (!this._autoplay.enableBlocked) { + this._autoplay.enable(); + } + this._plugins.forEach(plugin => { + plugin.init(this); + }); + const texture = yield this._loadTexture(projection); + this._applyProjection(projection, texture, null); + hotspot.refresh(); + animator.start(this._renderFrameOnDemand); + yield control.enable(); + if (this._tabIndex != null && !canvas.hasAttribute("tabIndex")) { + canvas.tabIndex = this._tabIndex; + } + this._initialized = true; + this.renderFrame(0); + this._emit(EVENTS.READY); + }); + } + /** + * Load new panorama image/video and display it. + * This will {@link View360#init init()} View360 if it's not initialized yet. + * @ko 새로운 파노라마 이미지 혹은 비디오를 로드하고 표시합니다. + * 만약 View360이 아직 초기화되지 않았다면, {@link View360#init init()}을 호출합니다. + * @param projection - Projection & video options for new source. {@ko 새로운 파노라마 이미지/비디오에 적용할 옵션들} + * @returns `Promise` if load was successful. {@ko 프로젝션 로드에 성공했을 경우 `Promise`를 반환합니다. } + * @since 4.0.0 + * @example + * ```ts + * // Change to video + * viewer.load({ + * src: "URL_TO_NEW_VIDEO", + * video: true + * }); + * ``` + */ + load(projection) { + return __awaiter(this, void 0, void 0, function* () { + if (!projection) return false; + if (this._initialized) { + const texture = yield this._loadTexture(projection); + this._applyProjection(projection, texture, this._projection); + this.renderFrame(0); + } else { + // Should update internal options before init + this._projection = projection; + this.init(); + } + return true; + }); + } + /** + * Refresh component's size by current + * @ko View360이 내부적으로 캐시하고 있는 엘리먼트 크기를 현재 크기로 갱신합니다. + * @since 4.0.0 + */ + resize() { + if (!this._initialized) return; + this._resizeComponents(); + // To prevent flickering, render immediately after resizing components + this.renderFrame(0); + const { + width, + height + } = this._renderer; + this._emit(EVENTS.RESIZE, { + width, + height + }); + } + /** + * Add new plugins + * @ko 새로운 플러그인을 추가합니다. + * @param plugins Plugins to add {@ko 추가할 플러그인들} + * @see View360Options#plugins + * @since 4.0.0 + * @example + * ```ts + * // Add a single plugin + * viewer.addPlugins(new ControlBar()); + * + * // Add multiple plugins + * viewer.addPlugins(new ControlBar(), new LoadingSpinner()); + * ``` + */ + addPlugins(...plugins) { + if (this._initialized) { + plugins.forEach(plugin => { + plugin.init(this); + }); + } + this._plugins.push(...plugins); + } + /** + * Remove plugins. + * @ko 플러그인을 제거합니다. + * @param plugins Plugins to remove {@ko 제거할 플러그인들} + * @since 4.0.0 + * @example + * ```ts + * // Remove a single plugin + * viewer.removePlugins(plugin1); + * + * // Remove multiple plugins + * viewer.removePlugins(plugin2, plugin3); + * ``` + */ + removePlugins(...plugins) { + plugins.forEach(plugin => { + const pluginIdx = this._plugins.indexOf(plugin); + if (pluginIdx < 0) return; + plugin.destroy(this); + this._plugins.splice(pluginIdx, 1); + }); + } + _emit(eventName, ...params) { + const evtParams = params ? params[0] : {}; + this.trigger(eventName, Object.assign({ + type: eventName, + target: this + }, evtParams)); + } + _applyProjection(projection, texture, prevProjection) { + const camera = this._camera; + const control = this._control; + const renderer = this._renderer; + // Remove previous projection + if (prevProjection) { + prevProjection.releaseAllResources(this._renderer.ctx); + } + projection.applyTexture(renderer.ctx, texture); + projection.updateCamera(camera); + projection.updateControl(control); + this._projection = projection; + this._emit(EVENTS.PROJECTION_CHANGE, { + projection + }); + } + _loadTexture(projection) { + return __awaiter(this, void 0, void 0, function* () { + const contentLoader = new TextureLoader(); + const { + src, + video + } = projection; + this._emit(EVENTS.LOAD_START, { + src, + video + }); + const texture = yield contentLoader.load(src, video); + this._emit(EVENTS.LOAD, { + src, + video + }); + return texture; + }); + } + _resizeComponents() { + const renderer = this._renderer; + const camera = this._camera; + const control = this._control; + renderer.resize(); + camera.resize(renderer.width, renderer.height); + control.resize(renderer.width, renderer.height); + } + _addEventHandlers(events) { + // Bind option "on" + Object.keys(events).forEach(evtName => { + this.on(evtName, events[evtName]); + }); + } + _bindComponentEvents() { + // Bind internal component events + const root = this._rootEl; + const control = this._control; + const animator = this._animator; + const renderer = this._renderer; + const vr = this._vr; + const controlEventsToPropagate = [CONTROL_EVENTS.STATIC_CLICK, CONTROL_EVENTS.INPUT_START, CONTROL_EVENTS.INPUT_END]; + controlEventsToPropagate.forEach(evtName => { + control.rotate.on(evtName, evt => { + this._emit(evtName, evt); + }); + control.zoom.on(evtName, evt => { + this._emit(evtName, evt); + }); + }); + vr.on(EVENTS.VR_START, evt => { + root.classList.add(DEFAULT_CLASS.IN_VR); + animator.changeContext(evt.session); + animator.start(this._renderVRFrame); + this._emit(EVENTS.VR_START); + }); + vr.on(EVENTS.VR_END, () => { + root.classList.remove(DEFAULT_CLASS.IN_VR); + renderer.ctx.useDefaultFrameBuffer(); + animator.changeContext(window); + animator.start(this._renderFrameOnDemand); + this.resize(); + this._emit(EVENTS.VR_END); + }); + } + } + /** + * Current version string of the View360 + * @ko View360의 현재 버젼 문자열 + * @since 4.0.0 + * @readonly + * @example + * ```ts + * // If the installed version of the View360 is v4.0.0, View360.VERSION is equal to "4.0.0" + * console.log(View360.VERSION) // 4.0.0 + * ``` + */ + View360.VERSION = "4.0.0-beta.4"; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Base class for 3D objects + * @ko 3D 오브젝트의 베이스 클래스 + * @since 4.0.0 + * @internal + */ + class Object3D { + /** + * Create new instance. + * @ko 새로운 인스턴스를 생성합니다. + */ + constructor() { + this.matrix = create$4(); + this.rotation = create$1(); + this.position = fromValues$3(0, 0, 0); + this.scale = fromValues$3(1, 1, 1); + } + /** + * Update local matrix of the object. + * @ko 오브젝트의 local matrix를 갱신합니다. + * @since 4.0.0 + */ + updateMatrix() { + fromRotationTranslationScale(this.matrix, this.rotation, this.position, this.scale); + } + } + + /** + * A plugin that displays loading spinner while loading the projection. + * @ko 프로젝션 로딩중에 로딩 스피너를 보여주는 플러그인 + * @since 4.0.0 + * @category Plugin + */ + class LoadingSpinner { + /** + * Create a new instance of LoadingSpinner. {@ko LoadingSpinner의 새 인스턴스를 생성합니다.} + * @param options Options {@ko 옵션들} + */ + constructor({ + className = {} + } = {}) { + this._startLoading = ({ + target: viewer + }) => { + viewer.rootEl.appendChild(this._container); + if (viewer.initialized) { + viewer.once(EVENTS.LOAD, this._detachElements); + } else { + viewer.once(EVENTS.READY, this._detachElements); + } + }; + this._detachElements = ({ + target: viewer + }) => { + const container = this._container; + if (!container) return; + if (container.parentElement === viewer.rootEl) { + viewer.rootEl.removeChild(container); + } + }; + this.className = className; + this._container = this._createElements(); + } + init(viewer) { + viewer.on(EVENTS.LOAD_START, this._startLoading); + } + destroy(viewer) { + viewer.off(EVENTS.LOAD_START, this._startLoading); + this._detachElements({ + target: viewer + }); + } + _createElements() { + const className = Object.assign(Object.assign({}, this.className), LoadingSpinner.DEFAULT_CLASS); + const container = createElement(className.CONTAINER); + const ring = createElement(className.RING); + container.appendChild(ring); + return container; + } + } + /** + * Default class names that LoadingSpinner uses + * @ko LoadingSpinner가 사용하는 디폴트 클래스 이름 + * @since 4.0.0 + */ + LoadingSpinner.DEFAULT_CLASS = { + /** + * A class name for the container element + * @ko 컨테이너 엘리먼트의 클래스 이름 + * @since 4.0.0 + */ + CONTAINER: "view360-spinner", + /** + * A class name for the spinning ring element + * @ko 돌아가는 링 엘리먼트의 클래스 이름 + * @since 4.0.0 + */ + RING: "view360-spinner-ring" + }; + + /** + * Interface of the ControlBar items + * @ko 컨트롤바 아이템의 인터페이스 + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class ControlBarItem { + /** + * Create new instance of the ControlBarItem + * @ko ControlBarItem의 새로운 인스턴스를 생성합니다. + * @param options Options {@ko 옵션들} + */ + constructor(options) { + this.position = options.position; + this.order = options.order; + } + } + + const CONTROL_BAR_DEFAULT_CLASS = { + CONTROLS_ROOT: "view360-controls", + CONTROLS_BG: "view360-controls-background", + CONTROLS_MAIN: "view360-controls-main", + CONTROLS_TOP: "view360-controls-top", + CONTROLS_BOTTOM: "view360-controls-bottom", + CONTROLS_MID: "view360-controls-mid", + CONTROLS_LEFT: "view360-controls-left", + CONTROLS_RIGHT: "view360-controls-right", + CONTROLS_FLOAT_LEFT: "view360-controls-float-left", + CONTROLS_FLOAT_RIGHT: "view360-controls-float-right", + CONTROLS_BUTTON: "view360-controls-button", + PROGRESS_ROOT: "view360-controls-progress", + VOLUME_ROOT: "view360-controls-volume", + RANGE_ROOT: "view360-range", + RANGE_TRACK: "view360-range-track", + RANGE_THUMB: "view360-range-thumb", + RANGE_FILLER: "view360-range-filler", + PLAY_BUTTON: "view360-controls-play", + PAUSE_BUTTON: "view360-controls-pause", + UNMUTED_BUTTON: "view360-controls-unmuted", + MUTED_BUTTON: "view360-controls-muted", + FULLSCREEN_BUTTON: "view360-controls-fullscreen", + FULLSCREEN_EXIT_BUTTON: "view360-controls-fullscreen-exit", + VR_BUTTON: "view360-controls-vr", + GYRO_ENABLED: "view360-controls-gyro-enabled", + GYRO_DISABLED: "view360-controls-gyro-disabled", + VIDEO_TIME_DISPLAY: "view360-controls-time", + PIEVIEW_ROOT: "view360-controls-pie", + FIXED: "view360-controls-fixed", + UNAVAILABLE: "view360-controls-unavailable", + HIDDEN: "view360-controls-hidden" + }; + const CONTROL_BAR_ITEM_POSITION = { + /** + * Place control bar item floating at top-left corner + * @ko 아이템을 왼쪽 위 구석에 표시합니다. + * @since 4.0.0 + */ + TOP_LEFT: "top-left", + /** + * Place control bar item floating at top-right corner + * @ko 아이템을 오른쪽 위 구석에 표시합니다. + * @since 4.0.0 + */ + TOP_RIGHT: "top-right", + /** + * Place control bar item at upper block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 위쪽 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_TOP: "main-top", + /** + * Place control bar item at lower block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 하단 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_BOTTOM: "main-bottom", + /** + * Place control bar item at center-left block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 왼쪽 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_LEFT: "main-left", + /** + * Place control bar item at center-right block inside the bottom control bar. + * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 오른쪽 블럭에 표시합니다. + * @since 4.0.0 + */ + MAIN_RIGHT: "main-right" + }; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class RangeControl extends Component { + /** + * + */ + constructor() { + super(); + this._onHold = ({ + srcEvent, + isTouch + }) => { + var _a; + const bbox = this._bbox; + if (!bbox) return; + const x = isTouch ? srcEvent.touches[0].pageX : srcEvent.pageX; + const elX = bbox.x + ((_a = window.scrollX) !== null && _a !== void 0 ? _a : window.pageXOffset); + const clamepdX = clamp(x, elX, elX + bbox.width); + const progress = (clamepdX - elX) / bbox.width; + this._motion.reset(clamepdX); + this.thumbEl.classList.add(this._fixedClass); + this.trigger(CONTROL_EVENTS.INPUT_START, progress); + }; + this._onChange = ({ + delta + }) => { + var _a; + const motion = this._motion; + const bbox = this._bbox; + if (!bbox) return; + motion.setNewEndByDelta(delta.x); + motion.update(1); + const elX = bbox.x + ((_a = window.scrollX) !== null && _a !== void 0 ? _a : window.pageXOffset); + const clampedX = clamp(motion.val, elX, elX + bbox.width); + const progress = (clampedX - elX) / bbox.width; + this.trigger(CONTROL_EVENTS.CHANGE, progress); + }; + this._onRelease = () => { + const bbox = this._bbox; + if (!bbox) return; + this.thumbEl.classList.remove(this._fixedClass); + this.trigger(CONTROL_EVENTS.INPUT_END); + }; + const root = document.createElement(EL_DIV); + const track = document.createElement(EL_DIV); + const thumb = document.createElement(EL_DIV); + const filler = document.createElement(EL_DIV); + root.draggable = false; + track.appendChild(filler); + track.appendChild(thumb); + root.appendChild(track); + this.rootEl = root; + this.trackEl = track; + this.thumbEl = thumb; + this.fillerEl = filler; + this._mouseInput = new MouseInput(); + this._touchInput = new TouchInput(); + this._motion = new Motion({ + duration: 1, + range: INFINITE_RANGE, + easing: x => x + }); + this._bbox = { + x: 0, + y: 0, + width: 0, + height: 0, + left: 0, + right: 0, + bottom: 0, + top: 0 + }; + this._fixedClass = CONTROL_BAR_DEFAULT_CLASS.FIXED; + } + init(className) { + const mouseInput = this._mouseInput; + const touchInput = this._touchInput; + this.rootEl.classList.add(className.RANGE_ROOT); + this.trackEl.classList.add(className.RANGE_TRACK); + this.thumbEl.classList.add(className.RANGE_THUMB); + this.fillerEl.classList.add(className.RANGE_FILLER); + this._fixedClass = className.FIXED; + mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onHold); + touchInput.on(CONTROL_EVENTS.INPUT_START, this._onHold); + mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + touchInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange); + mouseInput.enable(this.rootEl); + touchInput.enable(this.rootEl); + this.resize(); + } + destroy() { + const mouseInput = this._mouseInput; + const touchInput = this._touchInput; + this.rootEl.className = ""; + this.trackEl.className = ""; + this.thumbEl.className = ""; + this.fillerEl.className = ""; + mouseInput.off(); + touchInput.off(); + mouseInput.disable(); + touchInput.disable(); + } + resize() { + this._bbox = this.trackEl.getBoundingClientRect(); + } + updateStyle(progress) { + const width = this._bbox.width; + const clampedProgress = clamp(progress, 0, 1); + this.fillerEl.style.width = `${clampedProgress * 100}%`; + this.thumbEl.style.transform = `translateX(${clampedProgress * width}px)`; + } + } + + /** + * Show video progress bar. + * @ko 비디오의 프로그레스 바를 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class ProgressBar extends ControlBarItem { + get element() { + return this._rangeControl.rootEl; + } + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_TOP, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onResize = () => { + this._rangeControl.resize(); + }; + this._onTimeUpdate = () => { + const video = this._video; + if (!video) return; + this._currentTime = video.source.currentTime; + this._rangeControl.updateStyle(this._currentTime / this._duration); + }; + this._onDurationChange = () => { + const video = this._video; + if (!video) return; + this._duration = video.source.duration; + this._rangeControl.updateStyle(this._currentTime / this._duration); + }; + this._onHold = progress => { + const video = this._video; + const controlBar = this._controlBar; + if (!video || !controlBar) return; + const paused = video.isPaused(); + video.source.pause(); + const time = video.source.duration * progress; + video.source.currentTime = time; + video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { + detail: { + time + } + })); + controlBar.rootEl.classList.add(controlBar.className.FIXED); + this._wasPaused = !this._playPromise && paused; + }; + this._onControl = progress => { + const video = this._video; + if (!video) return; + const time = video.source.duration * progress; + video.source.currentTime = time; + video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { + detail: { + time + } + })); + }; + this._onRelease = () => { + const video = this._video; + const controlBar = this._controlBar; + if (video && controlBar) { + if (!this._wasPaused && !this._playPromise) { + this._playPromise = video.source.play().catch(() => void 0); + // This should not be chained + this._playPromise.then(() => { + this._playPromise = null; + }); + controlBar.rootEl.classList.remove(controlBar.className.FIXED); + } + } + this._wasPaused = false; + }; + this.position = position; + this.order = order; + this._controlBar = null; + this._rangeControl = new RangeControl(); + this._video = null; + this._wasPaused = false; + this._currentTime = 0; + this._duration = 0; + this._playPromise = null; + } + init(viewer, controlBar) { + var _a; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const element = this.element; + const rangeControl = this._rangeControl; + const unavailableClass = controlBar.className.UNAVAILABLE; + if (!video || !video.isVideo()) { + element.classList.add(unavailableClass); + return; + } + element.classList.remove(unavailableClass); + element.classList.add(controlBar.className.PROGRESS_ROOT); + viewer.on(EVENTS.RESIZE, this._onResize); + video.source.addEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.addEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate); + rangeControl.init(controlBar.className); + rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold); + rangeControl.on(CONTROL_EVENTS.CHANGE, this._onControl); + rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + this._video = video; + this._currentTime = video.source.currentTime; + this._duration = video.source.duration; + this._controlBar = controlBar; + rangeControl.updateStyle(this._currentTime / this._duration); + } + destroy(viewer) { + const video = this._video; + viewer.off(EVENTS.RESIZE, this._onResize); + if (video) { + video.source.removeEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.removeEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate); + } + this._rangeControl.destroy(); + this._video = null; + this._playPromise = null; + } + } + + /** + * Show video play / pause button. + * @ko 비디오 재생 / 일시정지 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class PlayButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const video = this._video; + if (!video) return; + if (this._paused) { + video.source.play(); + } else { + video.source.pause(); + } + }; + this._onPlay = () => { + if (!this._controlBar) return; + const element = this.element; + const className = this._controlBar.className; + element.classList.add(className.PAUSE_BUTTON); + element.classList.remove(className.PLAY_BUTTON); + element.title = "Pause Video"; + this._paused = false; + }; + this._onPause = () => { + if (!this._controlBar) return; + const element = this.element; + const className = this._controlBar.className; + element.classList.add(className.PLAY_BUTTON); + element.classList.remove(className.PAUSE_BUTTON); + element.title = "Play Video"; + this._paused = true; + }; + this.element = document.createElement(EL_BUTTON); + this._video = null; + this._paused = true; + this._controlBar = null; + } + init(viewer, controlBar) { + var _a; + const element = this.element; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const className = controlBar.className; + const unavailableClass = className.UNAVAILABLE; + if (!video || !video.isVideo()) { + element.classList.add(unavailableClass); + return; + } + element.classList.add(className.CONTROLS_BUTTON); + element.classList.remove(unavailableClass); + const paused = video.isPaused(); + this._video = video; + this._paused = paused; + this._controlBar = controlBar; + if (paused) { + this._onPause(); + } else { + this._onPlay(); + } + element.addEventListener(EVENTS$1.CLICK, this._onClick); + video.source.addEventListener(EVENTS$1.VIDEO_PLAY, this._onPlay); + video.source.addEventListener(EVENTS$1.VIDEO_PAUSE, this._onPause); + } + destroy() { + const video = this._video; + const element = this.element; + if (!video) return; + element.className = ""; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + video.source.removeEventListener(EVENTS$1.VIDEO_PLAY, this._onPlay); + video.source.removeEventListener(EVENTS$1.VIDEO_PAUSE, this._onPause); + this._video = null; + this._paused = true; + this._controlBar = null; + } + } + + /** + * Show video volume control. + * @ko 비디오 볼륨 조절 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class VolumeControl extends ControlBarItem { + get element() { + return this._rootEl; + } + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onResize = () => { + this._rangeControl.resize(); + this._updateDisplay(); + }; + this._onClick = () => { + const video = this._video; + if (!video || this._rootEl.disabled) return; + video.source.muted = !video.source.muted; + }; + this._onVolumeChange = () => { + const button = this._buttonEl; + const video = this._video; + const controlBar = this._controlBar; + if (!video || !controlBar) return; + const className = controlBar.className; + if (video.source.muted || video.source.volume === 0) { + button.classList.add(className.MUTED_BUTTON); + button.classList.remove(className.UNMUTED_BUTTON); + } else { + button.classList.add(className.UNMUTED_BUTTON); + button.classList.remove(className.MUTED_BUTTON); + } + this._updateDisplay(); + }; + this._onHold = progress => { + const video = this._video; + const controlBar = this._controlBar; + if (!video || !controlBar) return; + const className = controlBar.className; + video.source.volume = progress; + this._rootEl.classList.add(className.FIXED); + controlBar.containerEl.classList.add(className.FIXED); + this._updateDisplay(); + }; + this._onChange = progress => { + const video = this._video; + if (!video) return; + video.source.volume = progress; + if (progress > 0) { + video.source.muted = false; + } else { + video.source.muted = true; + } + this._updateDisplay(); + }; + this._onRelease = () => { + const controlBar = this._controlBar; + if (!controlBar) return; + const className = controlBar.className; + this._rootEl.classList.remove(className.FIXED); + controlBar.containerEl.classList.remove(className.FIXED); + }; + this._updateDisplay = () => { + const video = this._video; + const root = this._rootEl; + if (!video) return; + if (!video.hasAudio()) { + root.disabled = true; + return; + } + root.disabled = false; + const volume = video.source.muted ? 0 : video.source.volume; + this._rangeControl.updateStyle(volume); + }; + this._controlBar = null; + this._rangeControl = new RangeControl(); + this._createElements(); + this._video = null; + } + init(viewer, controlBar) { + var _a; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const root = this._rootEl; + const button = this._buttonEl; + const rangeControl = this._rangeControl; + const className = controlBar.className; + const unavailableClass = className.UNAVAILABLE; + if (!video || !video.isVideo()) { + root.classList.add(unavailableClass); + return; + } + root.classList.remove(unavailableClass); + root.classList.add(className.CONTROLS_BUTTON); + root.classList.add(className.VOLUME_ROOT); + button.classList.add(className.CONTROLS_BUTTON); + if (video.source.muted) { + button.classList.add(className.MUTED_BUTTON); + } else { + button.classList.add(className.UNMUTED_BUTTON); + } + viewer.on(EVENTS.RESIZE, this._onResize); + root.addEventListener(EVENTS$1.TRANSITION_END, this._onResize); + button.addEventListener(EVENTS$1.CLICK, this._onClick); + video.source.addEventListener(EVENTS$1.VIDEO_VOLUME_CHANGE, this._onVolumeChange); + video.source.addEventListener(EVENTS$1.VIDEO_LOADED_DATA, this._updateDisplay); + video.source.addEventListener(EVENTS$1.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay); + rangeControl.init(className); + rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold); + rangeControl.on(CONTROL_EVENTS.CHANGE, this._onChange); + rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease); + this._controlBar = controlBar; + this._video = video; + this._updateDisplay(); + } + destroy(viewer) { + const video = this._video; + const button = this._buttonEl; + const root = this._rootEl; + root.className = ""; + button.className = ""; + viewer.off(EVENTS.RESIZE, this._onResize); + root.removeEventListener(EVENTS$1.TRANSITION_END, this._onResize); + button.removeEventListener(EVENTS$1.CLICK, this._onClick); + if (video) { + video.source.removeEventListener(EVENTS$1.VIDEO_VOLUME_CHANGE, this._onVolumeChange); + video.source.removeEventListener(EVENTS$1.VIDEO_LOADED_DATA, this._updateDisplay); + video.source.removeEventListener(EVENTS$1.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay); + } + this._controlBar = null; + this._rangeControl.destroy(); + this._video = null; + } + _createElements() { + const root = document.createElement(EL_BUTTON); + const buttonEl = document.createElement(EL_DIV); + root.appendChild(this._rangeControl.rootEl); + root.appendChild(buttonEl); + root.title = "Toggle Mute"; + this._rootEl = root; + this._buttonEl = buttonEl; + } + } + + /** + * Show fullscreen enter / exit button. + * @ko 풀스크린 진입 / 해제 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class FullscreenButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const target = this._targetEl; + if (!target) return; + if (isFullscreen()) { + this._exitFullscreen(); + } else { + this._requestFullscreen(target); + } + }; + this._onFullscreenChange = () => { + const element = this.element; + const controlBar = this._controlBar; + if (!controlBar) return; + const className = controlBar.className; + if (isFullscreen()) { + element.classList.add(className.FULLSCREEN_EXIT_BUTTON); + element.classList.remove(className.FULLSCREEN_BUTTON); + } else { + element.classList.add(className.FULLSCREEN_BUTTON); + element.classList.remove(className.FULLSCREEN_EXIT_BUTTON); + } + }; + this.element = document.createElement(EL_BUTTON); + this.element.title = "Toggle Fullscreen"; + this._controlBar = null; + this._targetEl = null; + } + init(viewer, controlBar) { + const element = this.element; + const className = controlBar.className; + if (!this._fullscreenAvailable()) { + element.classList.add(className.UNAVAILABLE); + return; + } + element.classList.add(className.CONTROLS_BUTTON); + element.classList.remove(className.UNAVAILABLE); + element.addEventListener(EVENTS$1.CLICK, this._onClick); + this._addFullscreenHandlers(); + if (isFullscreen()) { + element.classList.add(className.FULLSCREEN_EXIT_BUTTON); + } else { + element.classList.add(className.FULLSCREEN_BUTTON); + } + this._controlBar = controlBar; + this._targetEl = viewer.rootEl; + } + destroy() { + const element = this.element; + element.className = ""; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + this._removeFullscreenHandlers(); + this._controlBar = null; + this._targetEl = null; + } + _fullscreenAvailable() { + return FULLSCREEN_REQUEST.some(key => !!document[key]); + } + _requestFullscreen(el) { + for (const key of FULLSCREEN_REQUEST) { + const request = el[key]; + if (request) { + request.call(el); + return; + } + } + } + _exitFullscreen() { + for (const key of FULLSCREEN_EXIT) { + const exit = document[key]; + if (exit) { + exit.call(document); + return; + } + } + } + _addFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.addEventListener(evtName, this._onFullscreenChange); + }); + } + _removeFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.removeEventListener(evtName, this._onFullscreenChange); + }); + } + } + + /** + * Show video current / total time. + * @ko 비디오의 현재 / 총 재생시간을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class VideoTime extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onTimeUpdate = () => { + const video = this._video; + if (!video) return; + this._currentTime = video.source.currentTime; + this._updateDisplay(); + }; + this._onDurationChange = () => { + const video = this._video; + if (!video) return; + this._duration = video.source.duration; + this._updateDisplay(); + }; + this._onCustomTimeChange = evt => { + this._currentTime = evt.detail.time; + this._updateDisplay(); + }; + this.element = document.createElement(EL_DIV); + this._video = null; + this._currentTime = 0; + this._duration = 0; + } + init(viewer, controlBar) { + var _a; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + const element = this.element; + const className = controlBar.className; + if (!video || !video.isVideo()) { + element.classList.add(className.UNAVAILABLE); + return; + } + element.classList.add(className.VIDEO_TIME_DISPLAY); + element.classList.remove(className.UNAVAILABLE); + video.source.addEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.addEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange); + this._video = video; + this._currentTime = video.source.currentTime; + this._duration = video.source.duration; + this._updateDisplay(); + } + destroy() { + const video = this._video; + if (!video) return; + this.element.className = ""; + video.source.removeEventListener(EVENTS$1.VIDEO_TIME_UPDATE, this._onTimeUpdate); + video.source.removeEventListener(EVENTS$1.VIDEO_DURATION_CHANGE, this._onDurationChange); + video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange); + this._video = null; + } + _updateDisplay() { + const time = this._currentTime; + const timeMinute = Math.floor(time / 60); + const timeSeconds = Math.floor(time - timeMinute * 60); + const timeSecondsFormatted = timeSeconds < 10 ? `0${timeSeconds}` : timeSeconds; + const duration = this._duration; + const durationMinute = Math.floor(duration / 60); + const durationSeconds = Math.floor(duration - durationMinute * 60); + const durationSecondsFormatted = durationSeconds < 10 ? `0${durationSeconds}` : durationSeconds; + this.element.innerText = `${timeMinute}:${timeSecondsFormatted} / ${durationMinute}:${durationSecondsFormatted}`; + } + } + + /** + * Show camera direction/fov indicator. + * @ko 카메라가 향하는 방향 및 FOV를 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class PieView extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + resetCamera = true, + position = CONTROL_BAR_ITEM_POSITION.TOP_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const viewer = this._viewer; + const resetCamera = this.resetCamera; + if (!viewer || !resetCamera) return; + const { + yaw = viewer.initialYaw, + pitch = viewer.initialPitch, + zoom = viewer.initialZoom, + duration = 500 + } = getObjectOption(resetCamera); + viewer.camera.animateTo({ + yaw, + pitch, + zoom, + duration + }); + }; + this._updatePie = ({ + target: viewer + }) => { + const piePath = this._piePathEl; + const rangeCircle = this._rangeCircleEl; + const camera = viewer.camera; + const fov = camera.getHorizontalFov(); + const yawRange = camera.getYawRange(camera.zoom); + const halfFov = fov * 0.5; + const pieRadius = 24 * Math.PI; + const pieDeg = pieRadius * fov / 360; + const pieOffset = pieRadius * (camera.yaw + halfFov + 90) / 360; + piePath.setAttribute("stroke-dasharray", `${pieDeg} ${pieRadius - pieDeg}`); + piePath.setAttribute("stroke-dashoffset", `${pieOffset}`); + if (isFinite(yawRange.min) && isFinite(yawRange.max)) { + const radius = 45 * Math.PI; // 2 * PI * r + const min = (circulate(yawRange.min, -180, 180) - halfFov) / 360; + const max = (circulate(yawRange.max, -180, 180) + halfFov) / 360; + const rangeDiff = radius * Math.abs(max - min); + const offset = -radius * (min - 0.25); + rangeCircle.setAttribute("stroke-dasharray", `${rangeDiff} ${radius - rangeDiff}`); + rangeCircle.setAttribute("stroke-dashoffset", `${offset}`); + } else { + rangeCircle.setAttribute("stroke-dasharray", ""); + rangeCircle.setAttribute("stroke-dashoffset", ""); + } + }; + this.element = document.createElement(EL_DIV); + this.element.title = "Reset view"; + this.resetCamera = resetCamera; + this._createPieElements(); + this._viewer = null; + } + init(viewer, controlBar) { + const element = this.element; + if (!viewer.initialized) { + viewer.once(EVENTS.READY, this._updatePie); + } else { + this._updatePie({ + target: viewer + }); + } + const rootClass = controlBar.className.PIEVIEW_ROOT; + element.classList.add(rootClass); + if (this.resetCamera) { + element.addEventListener(EVENTS$1.CLICK, this._onClick); + } + viewer.on(EVENTS.VIEW_CHANGE, this._updatePie); + this._viewer = viewer; + } + destroy(viewer) { + const element = this.element; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + element.className = ""; + viewer.off(EVENTS.READY, this._updatePie); + viewer.off(EVENTS.VIEW_CHANGE, this._updatePie); + this._viewer = null; + } + _createPieElements() { + const root = this.element; + const pieSVG = document.createElementNS(SVG_NAMESPACE, "svg"); + pieSVG.setAttribute("viewBox", "0 0 48 48"); + pieSVG.setAttribute("width", "100%"); + pieSVG.setAttribute("height", "100%"); + const piePath = document.createElementNS(SVG_NAMESPACE, "circle"); + piePath.setAttribute("stroke", "currentColor"); + piePath.setAttribute("fill", "transparent"); + piePath.setAttribute("cx", "24"); + piePath.setAttribute("cy", "24"); + piePath.setAttribute("r", "12"); + piePath.setAttribute("stroke-width", "24"); + pieSVG.appendChild(piePath); + const rangeCircle = document.createElementNS(SVG_NAMESPACE, "circle"); + rangeCircle.setAttribute("stroke", "currentColor"); + rangeCircle.setAttribute("fill", "transparent"); + rangeCircle.setAttribute("cx", "24"); + rangeCircle.setAttribute("cy", "24"); + rangeCircle.setAttribute("r", "22.5"); + rangeCircle.setAttribute("stroke-width", "3"); + pieSVG.appendChild(rangeCircle); + root.appendChild(pieSVG); + this._piePathEl = piePath; + this._rangeCircleEl = rangeCircle; + } + } + + /** + * Show VR enter button. + * @ko VR 진입 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class VRButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const viewer = this._viewer; + if (!viewer) return; + viewer.vr.enter(); + }; + this.element = document.createElement(EL_BUTTON); + this.element.title = "Enter VR"; + this._viewer = null; + } + init(viewer, controlBar) { + const element = this.element; + const className = controlBar.className; + element.classList.add(className.UNAVAILABLE); + element.classList.add(className.VR_BUTTON); + element.classList.add(className.CONTROLS_BUTTON); + viewer.vr.isAvailable().then(available => { + if (available) { + element.classList.remove(className.UNAVAILABLE); + } + }); + element.addEventListener(EVENTS$1.CLICK, this._onClick); + this._viewer = viewer; + } + destroy() { + const element = this.element; + element.className = ""; + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + this._viewer = null; + } + } + + /** + * Show gyroscope control enable / disable button + * @ko 자이로스코프 컨트롤 활성화 / 비활성화 버튼을 표시합니다. + * @category Plugin + * @group ControlBar + * @since 4.0.0 + */ + class GyroButton extends ControlBarItem { + /** + * Create a new instance. + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT, + order = 9999 + } = {}) { + super({ + position, + order + }); + this._onClick = () => { + const viewer = this._viewer; + const controlBar = this._controlBar; + if (!viewer || !controlBar) return; + const gyroControl = viewer.control.gyro; + if (gyroControl.enabled) { + gyroControl.disable(); + } else { + GyroControl.requestSensorPermission().then(available => { + if (available) { + gyroControl.enable(); + } else { + this.element.classList.add(controlBar.className.UNAVAILABLE); + } + }); + } + }; + this._updateStyle = () => { + const element = this.element; + const viewer = this._viewer; + const controlBar = this._controlBar; + if (!viewer || !controlBar) return; + const gyroControl = viewer.control.gyro; + const className = controlBar.className; + if (gyroControl.enabled) { + element.classList.add(className.GYRO_ENABLED); + element.classList.remove(className.GYRO_DISABLED); + } else { + element.classList.add(className.GYRO_DISABLED); + element.classList.remove(className.GYRO_ENABLED); + } + }; + this.element = document.createElement(EL_DIV); + this.element.title = "Toggle gyroscope control"; + } + init(viewer, controlBar) { + const element = this.element; + const className = controlBar.className; + element.addEventListener(EVENTS$1.CLICK, this._onClick); + element.classList.add(className.CONTROLS_BUTTON); + element.classList.add(className.UNAVAILABLE); + const enableButton = () => { + element.classList.remove(className.UNAVAILABLE); + viewer.control.gyro.on(CONTROL_EVENTS.ENABLE, this._updateStyle); + viewer.control.gyro.on(CONTROL_EVENTS.DISABLE, this._updateStyle); + }; + if (sensorCanBeEnabledIOS()) { + enableButton(); + } else { + GyroControl.isAvailable().then(available => { + if (!available) return; + enableButton(); + }); + } + this._controlBar = controlBar; + this._viewer = viewer; + this._updateStyle(); + } + destroy(viewer) { + const element = this.element; + viewer.control.gyro.off(CONTROL_EVENTS.ENABLE, this._updateStyle); + viewer.control.gyro.off(CONTROL_EVENTS.DISABLE, this._updateStyle); + element.removeEventListener(EVENTS$1.CLICK, this._onClick); + element.className = ""; + this._controlBar = null; + this._viewer = null; + } + } + + class AutoHide { + get enabled() { + return !!this._targetEl; + } + get hidden() { + return this._controlBar.containerEl.classList.contains(this._hiddenClass); + } + get _hiddenClass() { + return this._controlBar.className.HIDDEN; + } + get _fixedClass() { + return this._controlBar.className.FIXED; + } + constructor(controlBar, { + initialDelay = 3000, + delay = 0, + idleDelay: activationDelay = 3000 + }) { + this._onMouseEnter = () => { + this._isCursorInside = true; + this.show(); + }; + this._onMouseLeave = () => { + this._isCursorInside = false; + this._hideAfterDelay(); + }; + this._onMouseMove = () => { + if (!this._isFullscreen) return; + this.showTemporaliy(); + }; + this._onHold = evt => { + this._isGrabbing = true; + if (evt.pointerType === "mouse") { + this._isCursorInside = true; + } + window.addEventListener(EVENTS$1.MOUSE_UP, this._onRelease); + this.show(); + }; + this._onRelease = () => { + this._isGrabbing = false; + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onRelease); + this._hideAfterDelay(); + }; + this._onVideoPlay = () => { + const root = this._targetEl; + if (!root) return; + this._controlBar.containerEl.classList.remove(this._fixedClass); + }; + this._onVideoPause = () => { + const root = this._targetEl; + if (!root) return; + this._controlBar.containerEl.classList.add(this._fixedClass); + }; + this._onFullscreenChange = () => { + this._isFullscreen = isFullscreen(); + if (this._isFullscreen) { + this._hideAfterDelay(); + } + }; + this._controlBar = controlBar; + this._initialDelay = initialDelay; + this._delay = delay; + this._idleDelay = activationDelay; + this._timer = -1; + this._isCursorInside = false; + this._isGrabbing = false; + this._isFullscreen = false; + this._video = null; + this._targetEl = null; + } + enable(viewer) { + var _a; + if (this._targetEl) { + this.disable(viewer); + } + const initialDelay = this._initialDelay; + const root = viewer.rootEl; + this._targetEl = viewer.rootEl; + this._timer = window.setTimeout(() => { + this.hide(); + }, initialDelay); + root.addEventListener(EVENTS$1.MOUSE_DOWN, this._onHold); + root.addEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter); + root.addEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove); + root.addEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave); + this._addFullscreenHandlers(); + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (!video || !video.isVideo()) { + return; + } + if (video.isPaused()) { + this._controlBar.containerEl.classList.add(this._fixedClass); + } + video.source.addEventListener(EVENTS$1.VIDEO_PLAY, this._onVideoPlay); + video.source.addEventListener(EVENTS$1.VIDEO_PAUSE, this._onVideoPause); + this._video = video; + } + disable(viewer) { + if (!this._targetEl) return; + const controlBar = this._controlBar; + const root = viewer.rootEl; + const video = this._video; + root.removeEventListener(EVENTS$1.MOUSE_DOWN, this._onHold); + window.removeEventListener(EVENTS$1.MOUSE_UP, this._onRelease); + root.removeEventListener(EVENTS$1.MOUSE_ENTER, this._onMouseEnter); + root.removeEventListener(EVENTS$1.MOUSE_MOVE, this._onMouseMove); + root.removeEventListener(EVENTS$1.MOUSE_LEAVE, this._onMouseLeave); + this._removeFullscreenHandlers(); + window.clearTimeout(this._timer); + controlBar.containerEl.classList.remove(this._fixedClass); + if (video) { + video.source.removeEventListener(EVENTS$1.VIDEO_PLAY, this._onVideoPlay); + video.source.removeEventListener(EVENTS$1.VIDEO_PAUSE, this._onVideoPause); + } + this._isCursorInside = false; + this._isGrabbing = false; + this._video = null; + this._targetEl = null; + } + show() { + this._clearHideTimer(); + this._controlBar.containerEl.classList.remove(this._hiddenClass); + } + showTemporaliy() { + this.show(); + this._hideAfterDelay(this._idleDelay); + } + hide() { + this._clearHideTimer(); + this._controlBar.containerEl.classList.add(this._hiddenClass); + } + _clearHideTimer() { + if (this._timer) { + window.clearTimeout(this._timer); + this._timer = -1; + } + } + _hideAfterDelay(delay = this._delay) { + if (this._isGrabbing || !this._isFullscreen && this._isCursorInside) return; + this._clearHideTimer(); + if (delay <= 0) { + this.hide(); + } else { + this._timer = window.setTimeout(() => { + this.hide(); + }, delay); + } + } + _addFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.addEventListener(evtName, this._onFullscreenChange); + }); + } + _removeFullscreenHandlers() { + FULLSCREEN_CHANGE.forEach(evtName => { + document.removeEventListener(evtName, this._onFullscreenChange); + }); + } + } + + class VideoControl { + constructor() { + this._onKeyDown = event => { + const video = this._video; + if (!video) return; + event.preventDefault(); + event.stopPropagation(); + const videoEl = video.source; + const keyPressed = event.keyCode != null ? DIRECTION_KEY_CODE[event.keyCode] : DIRECTION_KEY_NAME[event.key]; + switch (keyPressed) { + case "LEFT": + case "RIGHT": + return this._changeVideoTime(videoEl, keyPressed === "RIGHT"); + case "UP": + case "DOWN": + return this._changeVideoVolume(videoEl, keyPressed === "UP"); + } + const spacePressed = event.keyCode === SPACE_KEY_CODE || event.key === SPACE_KEY_NAME; + if (spacePressed) { + this._toggleVideo(video); + } + }; + } + enable(root, video) { + this._video = video; + // capture is needed for resolving conflict with keyboard control + root.addEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown, true); + } + disable(root) { + this._video = null; + root.removeEventListener(EVENTS$1.KEY_DOWN, this._onKeyDown, true); + } + _changeVideoTime(video, forward) { + const delta = forward ? 5 : -5; + video.currentTime += delta; + video.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { + detail: { + time: video.currentTime + } + })); + } + _changeVideoVolume(video, increase) { + const delta = increase ? 0.1 : -0.1; + if (video.muted) { + video.volume = clamp(delta, 0, 1); + } else { + video.volume = clamp(video.volume + delta, 0, 1); + } + if (video.volume > 0) { + video.muted = false; + } else { + video.muted = true; + } + } + _toggleVideo(video) { + if (video.isPaused()) { + video.source.play(); + } else { + video.source.pause(); + } + } + } + + /** + * A plugin that displays extra buttons & controls that controls {@link View360}. + * @ko {@link View360}에 부가적인 버튼과 컨트롤을 추가해주는 플러그인. + * @category Plugin + * @since 4.0.0 + */ + class ControlBar { + /** + * Root element of the control bar + * @ko 컨트롤바의 루트 엘리먼트 + * @since 4.0.0 + */ + get rootEl() { + return this._rootEl; + } + /** + * Container element of the control bar + * @ko 컨트롤바의 컨테이너 엘리먼트 + * @since 4.0.0 + */ + get containerEl() { + return this._containerEl; + } + /** + * Background element of the control bar + * @ko 컨트롤바의 배경 엘리먼트 + * @since 4.0.0 + */ + get backgroundEl() { + return this._bgEl; + } + /** + * Control bar's default items created by {@link ControlBarOptions} + * @ko 주어진 {@link ControlBarOptions}에 의해 생성된 디폴트 아이템들 + * @since 4.0.0 + */ + get items() { + return this._items; + } + /** + * Custom control bar items + * @ko 커스텀 컨트롤바 아이템들을 추가합니다. + * @since 4.0.0 + */ + get customItems() { + return this._customItems; + } + /** + * Create new instance of ControlBar. + * @ko ControlBar의 새 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + autoHide, + showBackground, + clickToPlay = true, + keyboardControls = true, + progressBar = true, + playButton = true, + volumeButton = true, + fullscreenButton = true, + videoTime = true, + pieView = true, + vrButton = true, + gyroButton = true, + className = {}, + customItems = [] + } = {}) { + var _a; + this._onStaticClick = ({ + target: viewer, + isTouch + }) => { + var _a; + const autoHider = this._autoHider; + if (isTouch) { + if (!autoHider.enabled) return; + if (autoHider.hidden) { + autoHider.showTemporaliy(); + } else { + autoHider.hide(); + } + } else { + if (!this.clickToPlay) return; + const video = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (!video || !video.isVideo()) return; + if (video.isPaused()) { + video.source.play(); + } else { + video.source.pause(); + } + } + }; + this._onNewSrcLoad = ({ + target: viewer + }) => { + const items = this._items; + this._updateBackground(viewer); + this._updateAutoHide(viewer); + this._updateKeyboardHandler(viewer); + Object.keys(items).forEach(key => { + const category = items[key]; + category.forEach(item => { + item.destroy(viewer, this); + item.init(viewer, this); + }); + }); + }; + this.autoHide = autoHide; + this.showBackground = showBackground; + this.clickToPlay = clickToPlay; + this.keyboardControls = keyboardControls; + this.progressBar = progressBar; + this.playButton = playButton; + this.volumeButton = volumeButton; + this.fullscreenButton = fullscreenButton; + this.videoTime = videoTime; + this.pieView = pieView; + this.vrButton = vrButton; + this.gyroButton = gyroButton; + this.className = Object.assign(Object.assign({}, ControlBar.DEFAULT_CLASS), className); + const rootClass = (_a = className.CONTROLS_ROOT) !== null && _a !== void 0 ? _a : ControlBar.DEFAULT_CLASS.CONTROLS_ROOT; + this._rootEl = createElement(rootClass); + this._createPositionWrappers(); + this._items = Object.keys(ControlBar.POSITION).reduce((items, key) => { + items[ControlBar.POSITION[key]] = []; + return items; + }, {}); + this._customItems = customItems; + this._autoHider = new AutoHide(this, getObjectOption(autoHide)); + this._videoControl = new VideoControl(); + customItems.forEach(item => { + this._items[item.position].push(item); + }); + } + init(viewer) { + const panoRoot = viewer.rootEl; + const controlsRoot = this._rootEl; + const defaultItems = this._createDefaultItems(); + this._updateBackground(viewer); + this._updateAutoHide(viewer); + this._updateKeyboardHandler(viewer); + panoRoot.appendChild(controlsRoot); + this._addItem(viewer, defaultItems); + this._addItem(viewer, this._customItems); + viewer.on(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad); + viewer.on(EVENTS.STATIC_CLICK, this._onStaticClick); + } + destroy(viewer) { + // Remove controls root from pano root + const panoRoot = viewer.rootEl; + const controlsRoot = this._rootEl; + const items = this._items; + if (controlsRoot.parentElement === panoRoot) { + panoRoot.removeChild(controlsRoot); + } + Object.keys(items).forEach(key => { + const category = items[key]; + category.forEach(item => { + item.destroy(viewer, this); + }); + items[key] = []; + }); + this._clearItemElements(); + this._autoHider.disable(viewer); + this._videoControl.disable(panoRoot); + viewer.off(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad); + viewer.off(EVENTS.STATIC_CLICK, this._onStaticClick); + } + _addItem(viewer, items) { + for (const item of items) { + const category = this._items[item.position]; + const wrapper = this._wrapperEl[item.position]; + const nextSiblingIndex = findIndex(category, sibling => sibling.order > item.order); + if (nextSiblingIndex >= 0) { + const nextSibling = category[nextSiblingIndex].element; + category.splice(nextSiblingIndex, 0, item); + wrapper.insertBefore(item.element, nextSibling); + } else { + category.push(item); + wrapper.appendChild(item.element); + } + item.init(viewer, this); + } + } + _createPositionWrappers() { + const className = Object.assign(Object.assign({}, ControlBar.DEFAULT_CLASS), this.className); + const rootEl = this._rootEl; + // BG & FLOATING CONTROLS + const backgroundEl = createElement(className.CONTROLS_BG); + const floatLeftEl = createElement(className.CONTROLS_FLOAT_LEFT); + const floatRightEl = createElement(className.CONTROLS_FLOAT_RIGHT); + rootEl.appendChild(floatLeftEl); + rootEl.appendChild(floatRightEl); + // BOTTOM CONTROLS + const container = createElement(className.CONTROLS_MAIN); + const topWrapper = createElement(className.CONTROLS_TOP); + const bottomWrapper = createElement(className.CONTROLS_BOTTOM); + const midWrapper = createElement(className.CONTROLS_MID); + const leftControlsWrapper = createElement(className.CONTROLS_LEFT); + const rightControlsWrapper = createElement(className.CONTROLS_RIGHT); + midWrapper.appendChild(leftControlsWrapper); + midWrapper.appendChild(rightControlsWrapper); + container.appendChild(backgroundEl); + container.appendChild(topWrapper); + container.appendChild(midWrapper); + container.appendChild(bottomWrapper); + rootEl.appendChild(container); + this._bgEl = backgroundEl; + this._containerEl = container; + this._wrapperEl = { + [ControlBar.POSITION.MAIN_TOP]: topWrapper, + [ControlBar.POSITION.MAIN_LEFT]: leftControlsWrapper, + [ControlBar.POSITION.MAIN_RIGHT]: rightControlsWrapper, + [ControlBar.POSITION.MAIN_BOTTOM]: bottomWrapper, + [ControlBar.POSITION.TOP_LEFT]: floatLeftEl, + [ControlBar.POSITION.TOP_RIGHT]: floatRightEl + }; + } + _clearItemElements() { + const wrappers = Object.keys(ControlBar.POSITION).map(key => ControlBar.POSITION[key]); + // Remove all elements inside wrappers + wrappers.forEach(wrapper => { + while (wrapper.firstChild) { + wrapper.removeChild(wrapper.firstChild); + } + }); + } + _updateAutoHide(viewer) { + var _a; + const autoHide = this.autoHide; + const autoHider = this._autoHider; + if (autoHide != null) { + if (autoHide) { + autoHider.enable(viewer); + } else { + autoHider.disable(viewer); + } + } else { + // Automatically choose whether to show background by content type + const texture = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (texture && texture.isVideo()) { + // Enable auto hide when content type is video + autoHider.enable(viewer); + } else { + autoHider.disable(viewer); + } + } + } + _updateBackground(viewer) { + var _a, _b; + const background = this._bgEl; + const showBackground = this.showBackground; + const hiddenClass = (_a = this.className.HIDDEN) !== null && _a !== void 0 ? _a : ControlBar.DEFAULT_CLASS.HIDDEN; + if (showBackground != null) { + if (showBackground) { + background.classList.remove(hiddenClass); + } else { + background.classList.add(hiddenClass); + } + } else { + // Automatically choose whether to show background by content type + const texture = (_b = viewer.projection) === null || _b === void 0 ? void 0 : _b.getTexture(); + if (texture && texture.isVideo()) { + // Show bg when content type is video + background.classList.remove(hiddenClass); + } else { + background.classList.add(hiddenClass); + } + } + } + _updateKeyboardHandler(viewer) { + var _a; + const panoRoot = viewer.rootEl; + const videoControl = this._videoControl; + const texture = (_a = viewer.projection) === null || _a === void 0 ? void 0 : _a.getTexture(); + if (this.keyboardControls && texture && texture.isVideo()) { + videoControl.enable(panoRoot, texture); + } else { + videoControl.disable(panoRoot); + } + } + _createDefaultItems() { + const items = []; + if (this.progressBar) { + items.push(new ProgressBar(getObjectOption(this.progressBar))); + } + if (this.playButton) { + items.push(new PlayButton(getObjectOption(this.playButton))); + } + if (this.volumeButton) { + items.push(new VolumeControl(getObjectOption(this.volumeButton))); + } + if (this.gyroButton) { + items.push(new GyroButton(getObjectOption(this.gyroButton))); + } + if (this.vrButton) { + items.push(new VRButton(getObjectOption(this.vrButton))); + } + if (this.fullscreenButton) { + items.push(new FullscreenButton(getObjectOption(this.fullscreenButton))); + } + if (this.videoTime) { + items.push(new VideoTime(getObjectOption(this.videoTime))); + } + if (this.pieView) { + items.push(new PieView(getObjectOption(this.pieView))); + } + return items; + } + } + /** + * Default class names that ControlBar uses + * @ko ControlBar가 사용하는 디폴트 클래스 이름들 + * @since 4.0.0 + */ + ControlBar.DEFAULT_CLASS = CONTROL_BAR_DEFAULT_CLASS; + /** + * Constants for {@link ControlBarItemOptions#position} + * @ko {@link ControlBarItemOptions#position}에 사용 가능한 값들 + */ + ControlBar.POSITION = CONTROL_BAR_ITEM_POSITION; + + /** + * Base class for projections. + * @ko 프로젝션 베이스 클래스. + * @category Projection + * @since 4.0.0 + */ + class Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor({ + src, + video = false + }) { + this.src = src; + this.video = video; + this._mesh = null; + } + /** + * Release all resources projection has. + * This is automatically called on projection change & View360's destroy call + * @ko 현재 갖고 있는 모든 리소스를 반환합니다. + * 이 메소드는 프로젝션 변경 및 View360의 destroy 호출 시 자동으로 호출됩니다. + * @param ctx + */ + releaseAllResources(ctx) { + var _a; + (_a = this._mesh) === null || _a === void 0 ? void 0 : _a.destroy(ctx); + } + /** + * Update camera to match projection's settings. + * @ko 현재 프로젝션의 세팅으로 카메라를 업데이트합니다. + * @param camera - Instance of the camera to update {@ko 업데이트할 카메라의 인스턴스} + * @since 4.0.0 + */ + updateCamera(camera) { + // Use default mode & no view restriction + camera.resetRange(); + } + /** + * Update control to match projection's settings. + * @ko 현재 프로젝션의 세팅으로 컨트롤을 업데이트합니다. + * @param control - Instance of the control to update {@ko 업데이트할 컨트롤의 인스턴스} + * @since 4.0.0 + */ + updateControl(control) { + control.ignoreZoomScale = false; + } + /** + * Update projection. + * @ko 현재 프로젝션 정보를 갱신합니다. + * @param camera - Instance of the camera to reference {@ko 참조할 카메라의 인스턴스} + * @since 4.0.0 + */ + update(camera) {} // eslint-disable-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars + /** + * Return active texture. + * @ko 현재 활성화된 텍스쳐를 반환합니다. + * @internal + * @since 4.0.0 + */ + getTexture() { + if (!this._mesh) return null; + return this._mesh.program.uniforms.uTexture.texture; + } + /** + * A 3D triangle mesh for projection. It's `null` until loading the `src`. + * @ko Projection을 표시하기 위한 Mesh, src를 로드하기 전까지는 `null`입니다. + * @since 4.0.0 + */ + getMesh() { + return this._mesh; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class Uniform { + constructor() { + this.needsUpdate = true; + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + destroy(gl) { + // DO_NOTHING + } + } + + class UniformTextureCube extends Uniform { + constructor(ctx, texture, cubemapOrder) { + super(); + this.texture = texture; + this._webglTexture = ctx.createWebGLCubeTexture(texture, texture.width); + this._cubemapOrder = cubemapOrder; + } + destroy(gl) { + this.texture.destroy(); + gl.deleteTexture(this._webglTexture); + } + update(gl, location, isWebGL2) { + const texture = this.texture; + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY); + gl.uniform1i(location, 0); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture); + const sources = reorderCube(texture.sources, this._cubemapOrder); + sources.forEach((src, idx) => { + if (isWebGL2) { + gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src); + } else { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src); + } + }); + if (!texture.isVideo()) { + this.needsUpdate = false; + } + } + } + + /** @hidden */ + class CubeTexturePainter { + get size() { + return this._size; + } + constructor(texture, cubemapOrder) { + this.texture = texture; + this._renderingOrder = reorderCube(range(6), cubemapOrder); + const canvas = document.createElement("canvas"); + this._calcRenderingSize(); + canvas.width = this._size; + canvas.height = this._size; + this._canvas = canvas; + this._ctx = canvas.getContext("2d"); + } + destroy() { + const canvas = this._canvas; + // release memories + canvas.width = 1; + canvas.height = 1; + this._canvas = null; + } + draw(gl, isWebGL2) { + const size = this._size; + const texture = this.texture; + let surfaceIdx = 0; + for (let row = 0; row < this._row; row++) { + for (let column = 0; column < this._column; column++) { + const x = size * column; + const y = size * row; + const renderingFace = this._renderingOrder[surfaceIdx]; + this._ctx.drawImage(texture.source, x, y, size, size, 0, 0, size, size); + if (isWebGL2) { + gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas); + } else { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas); + } + surfaceIdx++; + } + } + } + _calcRenderingSize() { + const { + width, + height + } = this.texture; + const aspect = width / height; + if (aspect === 1 / 6) { + this._size = width; + this._row = 6; + this._column = 1; + } else if (aspect === 6) { + this._size = height; + this._row = 1; + this._column = 6; + } else if (aspect === 2 / 3) { + this._size = width * 0.5; + this._row = 3; + this._column = 2; + } else { + this._size = width / 3; + this._row = 2; + this._column = 3; + } + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class UniformCanvasCube extends Uniform { + get texture() { + return this._painter.texture; + } + constructor(ctx, texture, cubemapOrder) { + super(); + this._painter = new CubeTexturePainter(texture, cubemapOrder); + this._webglTexture = ctx.createWebGLCubeTexture(texture, this._painter.size); + } + destroy(gl) { + gl.deleteTexture(this._webglTexture); + this._painter.destroy(); + } + update(gl, location, isWebGL2) { + const texture = this.texture; + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + gl.uniform1i(location, 0); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture); + this._painter.draw(gl, isWebGL2); + if (!texture.isVideo()) { + this.needsUpdate = false; + } + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class TriangleMesh extends Object3D { + constructor(vao, program) { + super(); + this.vao = vao; + this.program = program; + } + destroy(ctx) { + ctx.releaseVAO(this.vao); + ctx.releaseShaderResources(this.program); + } + } + + class ShaderProgram { + constructor(ctx, vertexShader, fragmentShader, uniforms) { + this.program = ctx.createProgram(vertexShader, fragmentShader); + this.uniforms = uniforms; + this.uniformLocations = ctx.getUniformLocations(this.program, uniforms); + } + } + + /** + * @hidden + */ + class VertexData { + /** */ + constructor(data, itemSize) { + this.data = data; + this.itemSize = itemSize; + this.count = data.length / itemSize; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class Geometry { + /** */ + constructor(vertices, indicies, uvs) { + this.vertices = new VertexData(new Float32Array(vertices), 3); + this.indicies = new VertexData(new Uint16Array(indicies), 1); + this.uvs = new VertexData(new Float32Array(uvs), 2); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class CubeGeometry extends Geometry { + constructor({ + order, + rotateUV + }) { + const vertices = [ + // back + 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, + // front + -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, + // up + -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, + // down + -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, + // right + 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, + // left + -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1]; + const indicies = [0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23]; + const oneThird = 1 / 3; + const coords = []; + for (let r = 1; r >= 0; r--) { + for (let c = 0; c < 3; c++) { + const coord = [c * oneThird, r * 0.5, (c + 1) * oneThird, r * 0.5, (c + 1) * oneThird, (r + 1) * 0.5, c * oneThird, (r + 1) * 0.5]; + coords.push(coord); + } + } + if (rotateUV) { + rotateUV.forEach((degree, idx) => { + if (degree === ROTATE.ZERO) return; + const coord = coords[idx]; + let newOrder; + if (degree === ROTATE.CW_90) { + newOrder = [1, 2, 3, 0]; + } else if (degree === ROTATE.CCW_90) { + newOrder = [3, 0, 1, 2]; + } else { + newOrder = [2, 3, 0, 1]; + } + const newCoords = Array(coord.length); + for (let uvIdx = 0; uvIdx < coord.length / 2; uvIdx++) { + newCoords[uvIdx * 2 + 0] = coord[newOrder[uvIdx] * 2 + 0]; + newCoords[uvIdx * 2 + 1] = coord[newOrder[uvIdx] * 2 + 1]; + } + coords[idx] = newCoords; + }); + } + const uvs = reorderCube(coords, order, "BFUDRL").reduce((acc, val) => acc.concat(val), []); + super(vertices, indicies, uvs); + } + } + + var vs$3 = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec3 vPos;void main(){vPos=position;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}"; // eslint-disable-line + + var fs$3 = "#define GLSLIFY 1\nuniform samplerCube uTexture;varying highp vec3 vPos;void main(){gl_FragColor=textureCube(uTexture,vec3(vPos.x,vPos.y,-vPos.z));}"; // eslint-disable-line + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on cubemap images, accepts both multiple or single images. + * @ko 큐브맵 이미지 기반의 프로젝션, 단일 혹은 여러 장의 이미지를 모두 사용 가능합니다. + * @since 4.0.0 + * @category Projection + */ + class CubemapProjection extends Projection { + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param options Options {@ko Options} + */ + constructor(options) { + super(options); + const { + cubemapOrder = "RLUDFB", + cubemapFlipX = false + } = options; + this._cubemapOrder = cubemapOrder; + this._cubemapFlipX = cubemapFlipX; + } + applyTexture(ctx, texture) { + const cubemapOrder = this._cubemapOrder; + const cubemapFlipX = this._cubemapFlipX; + const uniforms = { + uTexture: texture.isCube() ? new UniformTextureCube(ctx, texture, cubemapOrder) : new UniformCanvasCube(ctx, texture, cubemapOrder) + }; + const geometry = new CubeGeometry({ + order: cubemapOrder + }); + const program = new ShaderProgram(ctx, vs$3, fs$3, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + if (cubemapFlipX) { + mesh.scale[0] = -1; + } + mesh.updateMatrix(); + this._mesh = mesh; + } + } + + class UniformTexture2D extends Uniform { + constructor(ctx, texture) { + super(); + this.texture = texture; + this._webglTexture = ctx.createWebGLTexture(texture); + } + destroy(gl) { + this.texture.destroy(); + gl.deleteTexture(this._webglTexture); + } + update(gl, location, isWebGL2) { + const texture = this.texture; + const isVideo = texture.isVideo(); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY); + gl.uniform1i(location, 0); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, this._webglTexture); + if (!isVideo && isWebGL2) { + gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); + } + if (!isVideo) { + this.needsUpdate = false; + } + } + } + + var vs$2 = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec2 vUV;void main(){vUV=uv;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}"; // eslint-disable-line + + var fs$2 = "#define GLSLIFY 1\nuniform sampler2D uTexture;varying highp vec2 vUV;void main(){gl_FragColor=texture2D(uTexture,vUV.st);}"; // eslint-disable-line + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on cubemap strip. + * Slightly more efficient than {@link CubemapProjection} as it doesn't copy cubemap image to canvas while rendering. + * Accepts only single image. + * @ko 큐브맵 스트립 기반의 프로젝션. + * {@link CubemapProjection}와 달리 렌더링하는 과정에 캔버스에 이미지를 복사하는 과정이 없기 때문에 살짝 더 효율적입니다. + * 단일 이미지만 사용 가능합니다. + * @since 4.0.0 + * @category Projection + */ + class CubestripProjection extends Projection { + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param options Options {@ko Options} + */ + constructor(options) { + super(options); + const { + cubemapOrder = "RLUDFB", + cubemapFlipX = false + } = options; + this._cubemapOrder = cubemapOrder; + this._cubemapFlipX = cubemapFlipX; + } + applyTexture(ctx, texture) { + const cubemapOrder = this._cubemapOrder; + const cubemapFlipX = this._cubemapFlipX; + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture) + }; + const geometry = new CubeGeometry({ + order: cubemapOrder + }); + const program = new ShaderProgram(ctx, vs$2, fs$2, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + if (cubemapFlipX) { + mesh.scale[0] = -1; + } + mesh.updateMatrix(); + this._mesh = mesh; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class CylinderGeometry extends Geometry { + constructor(maxTheta) { + const vertices = []; + const indicies = []; + const uvs = []; + const height = 1; + const radialSegments = 60; + const halfHeight = height * 0.5; + const heightSegments = [-halfHeight, halfHeight]; + const invRadialSegments = 1 / radialSegments; + const angleConst = maxTheta * invRadialSegments; + for (let yIdx = 0; yIdx < 2; yIdx++) { + const y = heightSegments[yIdx]; + for (let lngIdx = 0; lngIdx <= radialSegments; lngIdx++) { + const angle = lngIdx * angleConst + Math.PI - maxTheta * 0.5; + const x = Math.cos(angle); + const z = Math.sin(angle); + const u = lngIdx * invRadialSegments; + const v = yIdx; + uvs.push(u, v); + vertices.push(x, y, z); + if (yIdx === 0 && lngIdx < radialSegments) { + const a = lngIdx; + const b = a + radialSegments + 1; + indicies.push(a, b, a + 1, b, b + 1, a + 1); + } + } + } + super(vertices, indicies, uvs); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on cylindrical projection. + * This can show panorama images taken from smartphones. + * @ko 원통 투영법 기반의 프로젝션. + * 일반적인 스마트폰 파노라마 사진을 표시하는데 사용될 수 있습니다. + * @since 4.0.0 + * @category Projection + */ + class CylindricalProjection extends Projection { + /** + * Create new instance. + * @ko 새 인스턴스를 생성합니다. + * @param options Options {@ko Options} + */ + constructor(options) { + super(options); + const { + partial = false + } = options; + this._partial = partial; + } + applyTexture(ctx, texture) { + const partial = this._partial; + const { + width, + height + } = texture; + const aspect = width / height; + const halfVFov = 180 / aspect; + const cylinderHeight = partial ? 1 : 2 * Math.tan(halfVFov * DEG_TO_RAD); + const cylinderTheta = partial ? aspect : 2 * Math.PI; + const geometry = new CylinderGeometry(cylinderTheta); + const program = new ShaderProgram(ctx, vs$2, fs$2, { + uTexture: new UniformTexture2D(ctx, texture) + }); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + mesh.scale[1] = cylinderHeight; + identity(mesh.rotation); + rotateY(mesh.rotation, mesh.rotation, -Math.PI / 2); + mesh.updateMatrix(); + this._mesh = mesh; + } + updateCamera(camera) { + super.updateCamera(camera); + const mesh = this._mesh; + if (!mesh) return; + const uTexture = mesh.program.uniforms.uTexture; + const texture = uTexture.texture; + const { + width, + height + } = texture; + const aspect = width / height; + const halfHeight = mesh.scale[1] * 0.5; + if (this._partial) { + const restrictedYaw = 0.5 * aspect * RAD_TO_DEG; + camera.restrictYawRange(-restrictedYaw, restrictedYaw); + } + const restrictedPitch = Math.atan2(halfHeight, 1) * RAD_TO_DEG; + const minZoom = Math.tan(camera.fov * DEG_TO_RAD * 0.5) / (halfHeight * camera.aspect); + camera.restrictPitchRange(-restrictedPitch, restrictedPitch); + camera.restrictZoomRange(minZoom, Infinity); + camera.restrictRenderHeight(halfHeight * 2); + } + } + + var fs$1 = "#define PI 3.14159265359\nprecision mediump float;\n#define GLSLIFY 1\nuniform sampler2D uTexture;varying highp vec2 vUV;const vec2 OPERATE_COORDS_RANGE=vec2(-1.0,1.0);const vec2 TEXTURE_COORDS_RANGE=vec2(0.0,1.0);const float ONE_THIRD=1.0/3.0;const float EAC_CONST=2.0/PI;float scale(vec2 domainRange,vec2 targetRange,float val){float unit=1.0/(domainRange[1]-domainRange[0]);return targetRange[0]+(targetRange[1]-targetRange[0])*(val-domainRange[0])*unit;}void main(void){float transformedCoordX;float transformedCoordY;float texRangeXStart=floor(vUV.s*3.)*ONE_THIRD;float texRangeYStart=floor(vUV.t*2.)*0.5;vec2 orgTextureRangeX=vec2(texRangeXStart,texRangeXStart+ONE_THIRD);vec2 orgTextureRangeY=vec2(texRangeYStart,texRangeYStart+0.5);float px=scale(orgTextureRangeX,OPERATE_COORDS_RANGE,vUV.s);float py=scale(orgTextureRangeY,OPERATE_COORDS_RANGE,vUV.t);float qu=EAC_CONST*atan(px)+0.5;float qv=EAC_CONST*atan(py)+0.5;transformedCoordX=scale(TEXTURE_COORDS_RANGE,orgTextureRangeX,qu);transformedCoordY=scale(TEXTURE_COORDS_RANGE,orgTextureRangeY,qv);gl_FragColor=texture2D(uTexture,vec2(transformedCoordX,transformedCoordY));}"; // eslint-disable-line + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Equi-Angular Cubemap Projection. + * This format is used by Youtube's 360 videos. + * @ko Equi-Angular Cubemap 프로젝션. + * 이 포맷은 주로 Youtube의 360 비디오에 사용됩니다. + * @since 4.0.0 + * @category Projection + */ + class EquiangularProjection extends Projection { + applyTexture(ctx, texture) { + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture) + }; + const geometry = new CubeGeometry({ + order: "LFRDBU", + rotateUV: [ROTATE.ZERO, ROTATE.ZERO, ROTATE.ZERO, ROTATE.CW_90, ROTATE.CCW_90, ROTATE.CW_90] + }); + const program = new ShaderProgram(ctx, vs$2, fs$1, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class SphereGeometry extends Geometry { + /** */ + constructor() { + // const radius = 1; + const widthSegments = 60; + const heightSegments = 60; + const ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI; + const uvs = []; + const vertices = []; + const indicies = []; + let latIdx; + let lngIdx; + for (latIdx = 0; latIdx <= widthSegments; latIdx++) { + const theta = (latIdx / widthSegments - 0.5) * Math.PI; + const sinTheta = Math.sin(theta); + const cosTheta = Math.cos(theta); + for (lngIdx = 0; lngIdx <= heightSegments; lngIdx++) { + const phi = (lngIdx / heightSegments - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN; + const sinPhi = Math.sin(phi); + const cosPhi = Math.cos(phi); + const x = cosPhi * cosTheta; + const y = sinTheta; + const z = sinPhi * cosTheta; + const u = lngIdx / heightSegments; + const v = latIdx / widthSegments; + uvs.push(u, v); + vertices.push(x, y, z); + if (lngIdx !== heightSegments && latIdx !== widthSegments) { + const a = latIdx * (heightSegments + 1) + lngIdx; + const b = a + heightSegments + 1; + indicies.push(a, a + 1, b, b, a + 1, b + 1); + } + } + } + super(vertices, indicies, uvs); + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on equirectangular projection. + * @ko 등 장방형 도법(Equirectangular projection) 기반의 프로젝션 + * @since 4.0.0 + * @category Projection + */ + class EquirectProjection extends Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor(options) { + super(options); + } + applyTexture(ctx, texture) { + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture) + }; + const geometry = new SphereGeometry(); + const program = new ShaderProgram(ctx, vs$2, fs$2, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class UniformFloat extends Uniform { + constructor(val) { + super(); + this.val = val; + } + update(gl, location) { + gl.uniform1f(location, this.val); + this.needsUpdate = false; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * @hidden + */ + class PlaneGeometry extends Geometry { + /** */ + constructor(width = 2, height = 2, z = -1) { + const halfWidth = width * 0.5; + const halfHeight = height * 0.5; + const vertices = [-halfWidth, -halfHeight, z, halfWidth, -halfHeight, z, -halfWidth, halfHeight, z, halfWidth, halfHeight, z]; + const indicies = [0, 1, 2, 2, 1, 3]; + const uvs = [0, 0, 1, 0, 0, 1, 1, 1]; + super(vertices, indicies, uvs); + } + } + + var vs$1 = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec2 vUV;void main(){vUV=uv;gl_Position=vec4(position,1.0);}"; // eslint-disable-line + + var fs = "precision mediump float;\n#define GLSLIFY 1\nuniform sampler2D uTexture;uniform float uYaw;uniform float uPitch;uniform float uZoom;varying highp vec2 vUV;const float PI=3.1415926536;const float PI_2=PI*0.5;vec2 toStereographicUV(in vec2 uv,in vec2 center){float R=1.*uZoom;vec2 texLatLon=(uv*2.-1.)*vec2(PI,PI_2);vec2 central=(center*2.-1.)*vec2(PI,PI_2)+vec2(PI,0);float x=texLatLon.x;float y=texLatLon.y;float rou=sqrt(x*x+y*y);float c=2.0*atan(rou,R*0.5);float sin_c=sin(c);float cos_c=cos(c);float sin_cy=sin(central.y);float cos_cy=cos(central.y);float lat=asin(cos_c*sin_cy+(y*sin_c*cos_cy)/rou);float lon=central.x+atan(x*sin_c,rou*cos_cy*cos_c-y*sin_cy*sin_c);float u=(lon/PI+1.0)*0.5;float v=(lat/PI_2+1.0)*0.5;return vec2(u,v);}void main(){vec2 central=vec2(uYaw,uPitch);vec2 uv=toStereographicUV(vUV,central);gl_FragColor=texture2D(uTexture,uv);}"; // eslint-disable-line + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on so-called "Little planet" or "Tiny planet" effect. + * @ko "Little planet" 혹은 "Tiny planet"로 불리는 이펙트 기반의 프로젝션 + * @since 4.0.0 + * @category Projection + */ + class LittlePlanetProjection extends Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor(options) { + super(options); + } + applyTexture(ctx, texture) { + texture.wrapS = WebGLRenderingContext.REPEAT; + texture.wrapT = WebGLRenderingContext.REPEAT; + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture), + uYaw: new UniformFloat(0), + uPitch: new UniformFloat(0.5), + uZoom: new UniformFloat(1) + }; + const geometry = new PlaneGeometry(); + const program = new ShaderProgram(ctx, vs$1, fs, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } + updateControl(control) { + control.ignoreZoomScale = true; + } + update(camera) { + const mesh = this._mesh; + if (!mesh) return; + const uniforms = mesh.program.uniforms; + uniforms.uYaw.val = camera.yaw / 360; + // Range from 0 ~ 1 + uniforms.uPitch.val = camera.pitch / 180 + 0.5; + uniforms.uZoom.val = camera.zoom; + uniforms.uYaw.needsUpdate = true; + uniforms.uPitch.needsUpdate = true; + uniforms.uZoom.needsUpdate = true; + } + } + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + class UniformVector4Array extends Uniform { + constructor(val) { + super(); + this.val = val; + } + update(gl, location) { + gl.uniform4fv(location, this.val.reduce((arr, vector) => [...arr, ...vector], [])); + this.needsUpdate = false; + } + } + + var vs = "#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;uniform vec4 uTexScaleOffset[2];uniform float uEye;varying highp vec2 vUV;void main(){vec4 scaleOffset=uTexScaleOffset[int(uEye)];vUV=uv.xy*scaleOffset.xy+scaleOffset.zw;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}"; // eslint-disable-line + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + /** + * Projection based on stereo equirectangular images. + * @ko Stereo equirectangular 이미지 기반의 프로젝션 + * @since 4.0.0 + * @category Projection + */ + class StereoEquiProjection extends Projection { + /** + * Create new instance + * @ko 새로운 인스턴스를 생성합니다. + * @param options - Options {@ko 옵션들} + */ + constructor(options) { + super(options); + this._mode = options.mode; + } + applyTexture(ctx, texture) { + let leftEye; + let rightEye; + switch (this._mode) { + case StereoEquiProjection.MODE.LEFT_RIGHT: + leftEye = [0.5, 1, 0, 0]; + rightEye = [0.5, 1, 0.5, 0]; + break; + default: + // Default, uses "top_bottom" + leftEye = [1, 0.5, 0, 0]; + rightEye = [1, 0.5, 0, 0.5]; + } + const uniforms = { + uTexture: new UniformTexture2D(ctx, texture), + uEye: new UniformFloat(0), + uTexScaleOffset: new UniformVector4Array([leftEye, rightEye]) + }; + const geometry = new SphereGeometry(); + const program = new ShaderProgram(ctx, vs, fs$2, uniforms); + const vao = ctx.createVAO(geometry, program); + const mesh = new TriangleMesh(vao, program); + this._mesh = mesh; + } + } + /** + * Available stereoscopic modes + * @ko 사용가능한 스테레오스코픽 모드들 + * @since 4.0.0 + */ + StereoEquiProjection.MODE = { + /** + * @ko 이미지가 왼쪽/오른쪽으로 구성되어있을 경우 + * @since 4.0.0 + */ + LEFT_RIGHT: "left_right", + /** + * @ko 이미지가 위/아래로 구성되어있을 경우 + * @since 4.0.0 + */ + TOP_BOTTOM: "top_bottom" + }; + + /** + * @hidden + */ + const withMethods = (prototype, attr) => { + [Component.prototype, View360.prototype].forEach(proto => { + Object.getOwnPropertyNames(proto).filter(name => name.charAt(0) !== "_" && name !== "constructor").forEach(name => { + const descriptor = Object.getOwnPropertyDescriptor(proto, name); + if (descriptor.value) { + // Public Function + Object.defineProperty(prototype, name, { + value: function (...args) { + return descriptor.value.call(this[attr], ...args); + } + }); + } else { + const getterDescriptor = {}; + if (descriptor.get) { + getterDescriptor.get = function () { + var _a; + return this[attr] && ((_a = descriptor.get) === null || _a === void 0 ? void 0 : _a.call(this[attr])); + }; + } + if (descriptor.set) { + getterDescriptor.set = function (...args) { + var _a; + return (_a = descriptor.set) === null || _a === void 0 ? void 0 : _a.call(this[attr], ...args); + }; + } + Object.defineProperty(prototype, name, getterDescriptor); + } + }); + }); + }; + + /** + * @hidden + */ + const getValidProps = propsObj => { + return Object.keys(propsObj).reduce((props, propName) => { + if (propsObj[propName] != null) { + props[propName] = propsObj[propName]; + } + return props; + }, {}); + }; + + const VIEW360_METHODS = ["destroy", "init", "load", "resize", "addPlugins", "removePlugins", "renderFrame", + // @egjs/component methods + "on", "hasOn", "once", "off", "trigger"]; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + + var modules = { + __proto__: null, + 'default': View360, + Autoplay: Autoplay, + AutoResizer: AutoResizer, + Camera: Camera, + CameraAnimation: CameraAnimation, + Motion: Motion, + Object3D: Object3D, + View360Error: View360Error, + WebGLRenderer: WebGLRenderer, + XRManager: XRManager, + PanoControl: PanoControl, + RotateControl: RotateControl, + ZoomControl: ZoomControl, + GyroControl: GyroControl, + ControlBar: ControlBar, + ControlBarItem: ControlBarItem, + FullscreenButton: FullscreenButton, + PieView: PieView, + PlayButton: PlayButton, + ProgressBar: ProgressBar, + VideoTime: VideoTime, + VolumeControl: VolumeControl, + LoadingSpinner: LoadingSpinner, + Projection: Projection, + CubemapProjection: CubemapProjection, + CubestripProjection: CubestripProjection, + CylindricalProjection: CylindricalProjection, + EquiangularProjection: EquiangularProjection, + EquirectProjection: EquirectProjection, + LittlePlanetProjection: LittlePlanetProjection, + StereoEquiProjection: StereoEquiProjection, + Hotspot: Hotspot, + HotspotRenderer: HotspotRenderer, + ERROR_CODES: ERROR_CODES, + DEFAULT_CLASS: DEFAULT_CLASS, + EVENTS: EVENTS, + EASING: EASING, + getValidProps: getValidProps, + VIEW360_METHODS: VIEW360_METHODS, + withMethods: withMethods + }; + + /* + * Copyright (c) 2023-present NAVER Corp. + * egjs projects are licensed under the MIT license + */ + merge(View360, modules); + + return View360; + +})); +//# sourceMappingURL=view360.pkgd.js.map diff --git a/demo/release/latest/dist/view360.pkgd.js.map b/demo/release/latest/dist/view360.pkgd.js.map new file mode 100644 index 000000000..3e34446c5 --- /dev/null +++ b/demo/release/latest/dist/view360.pkgd.js.map @@ -0,0 +1 @@ +{"version":3,"file":"view360.pkgd.js","sources":["../src/core/View360Error.ts","../src/const/error.ts","../src/const/browser.ts","../src/const/external.ts","../src/const/internal.ts","../src/utils.ts","../src/core/Motion.ts","../src/core/CameraAnimation.ts","../src/core/Camera.ts","../src/control/input/MouseInput.ts","../src/control/input/TouchInput.ts","../src/control/input/KeyboardInput.ts","../src/control/RotateControl.ts","../src/control/input/WheelInput.ts","../src/control/input/PinchInput.ts","../src/control/ZoomControl.ts","../src/control/input/GyroInput.ts","../src/control/GyroControl.ts","../src/control/PanoControl.ts","../src/texture/Texture.ts","../src/texture/Texture2D.ts","../src/texture/TextureVideo.ts","../src/texture/TextureCube.ts","../src/core/TextureLoader.ts","../src/core/FrameAnimator.ts","../src/core/AutoResizer.ts","../src/core/Autoplay.ts","../src/core/XRManager.ts","../src/hotspot/Hotspot.ts","../src/hotspot/HotspotRenderer.ts","../src/core/VertexArrayObject.ts","../src/core/WebGLContext.ts","../src/core/WebGLRenderer.ts","../src/View360.ts","../src/core/Object3D.ts","../src/plugin/LoadingSpinner/LoadingSpinner.ts","../src/plugin/ControlBar/ControlBarItem.ts","../src/plugin/ControlBar/const.ts","../src/plugin/ControlBar/RangeControl.ts","../src/plugin/ControlBar/ProgressBar.ts","../src/plugin/ControlBar/PlayButton.ts","../src/plugin/ControlBar/VolumeControl.ts","../src/plugin/ControlBar/FullscreenButton.ts","../src/plugin/ControlBar/VideoTime.ts","../src/plugin/ControlBar/PieView.ts","../src/plugin/ControlBar/VRButton.ts","../src/plugin/ControlBar/GyroButton.ts","../src/plugin/ControlBar/AutoHide.ts","../src/plugin/ControlBar/VideoControl.ts","../src/plugin/ControlBar/ControlBar.ts","../src/projection/Projection.ts","../src/uniform/Uniform.ts","../src/uniform/UniformTextureCube.ts","../src/core/CubeTexturePainter.ts","../src/uniform/UniformCanvasCube.ts","../src/core/TriangleMesh.ts","../src/core/ShaderProgram.ts","../src/core/VertexData.ts","../src/geometry/Geometry.ts","../src/geometry/CubeGeometry.ts","../src/projection/CubemapProjection.ts","../src/uniform/UniformTexture2D.ts","../src/projection/CubestripProjection.ts","../src/geometry/CylinderGeometry.ts","../src/projection/CylindricalProjection.ts","../src/projection/EquiangularProjection.ts","../src/geometry/SphereGeometry.ts","../src/projection/EquirectProjection.ts","../src/uniform/UniformFloat.ts","../src/geometry/PlaneGeometry.ts","../src/projection/LittlePlanetProjection.ts","../src/uniform/UniformVector4Array.ts","../src/projection/StereoEquiProjection.ts","../src/cfc/withMethods.ts","../src/cfc/utils.ts","../src/cfc/const.ts","../src/index.ts","../src/index.umd.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * Error thrown by {@link View360}\n * @ko {@link View360}이 발생시킨 에러\n * @since 4.0.0\n */\nclass View360Error extends Error {\n /**\n * Error code\n * @ko 에러 코드\n * @see ERROR_CODES\n */\n public code: number;\n\n /**\n * Create new instance of View360Error\n * @ko View360Error의 인스턴스를 생성합니다.\n * @param message - Error message {@ko 에러 메시지}\n * @param code - Error code {@ko 에러 코드}\n */\n public constructor(message: string, code: number) {\n super(message);\n\n Object.setPrototypeOf(this, View360Error.prototype);\n\n this.name = \"View360Error\";\n this.code = code;\n }\n}\n\nexport default View360Error;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * Error codes of {@link View360Error}\n * @ko {@link View360Error}가 가질 수 있는 에러 코드 값들\n * @since 4.0.0\n */\nexport const ERROR_CODES = {\n /**\n * The given value's type is not expected\n * @ko 주어진 값의 타입이 잘못되었을 경우\n * @since 4.0.0\n */\n WRONG_TYPE: 0,\n /**\n * The given value is not a supported option\n * @ko 잘못된 옵션을 받았을 경우\n * @since 4.0.0\n */\n WRONG_OPTION: 1,\n /**\n * The element with given CSS selector does not exist\n * @ko 주어진 CSS 셀렉터로 엘리먼트를 찾지 못했을 경우\n * @since 4.0.0\n */\n ELEMENT_NOT_FOUND: 2,\n /**\n * Couldn't find canvas element inside the given container element.\n * @ko 컨테이너 엘리먼트 내부에서 캔버스 엘리먼트를 찾지 못했을 경우\n * @since 4.0.0\n */\n CANVAS_NOT_FOUND: 3,\n /**\n * The browser does not support WebGL\n * @ko 브라우저가 WebGL을 지원하지 않는 경우\n * @since 4.0.0\n */\n WEBGL_NOT_SUPPORTED: 4,\n /**\n * Failed creating canvas 2D context\n * @ko 캔버스 2D 컨텍스트를 생성하지 못한 경우\n * @since 4.0.0\n */\n FAILED_CREATE_CONTEXT_2D: 5,\n /**\n * `init()` is called before setting {@link View360Options#projection}\n * @ko {@link View360Options#projection}을 설정하기 전에 `init()`이 호출된 경우\n * @since 4.0.0\n */\n PROVIDE_PROJECTION_FIRST: 6,\n /**\n * Failed linking WebGL program. Only can be thrown when {@link View360Options#debug} is `true`.\n * @ko WebGL 프로그램 링크에 실패한 경우. {@link View360Options#debug}를 `true`로 설정한 경우에만 발생할 수 있습니다.\n * @since 4.0.0\n */\n FAILED_LINKING_PROGRAM: 7,\n /**\n * Arguments are not sufficient for the given property.\n * @ko 프로퍼티에 값이 충분히 주어지지 않았을 때\n * @since 4.0.0\n */\n INSUFFICIENT_ARGS: 8\n} as const;\n\nexport const MESSAGES = {\n WRONG_TYPE: (val: any, types: string[]) => `${typeof val} is not a ${types.map(type => `\"${type}\"`).join(\" or \")}.`,\n WRONG_OPTION: (val: any, optionName: string) => `Bad option: given \"${val}\" for option \"${optionName}\".`,\n ELEMENT_NOT_FOUND: (query: string) => `Element with selector \"${query}\" not found.`,\n CANVAS_NOT_FOUND: \"The canvas element was not found inside the given root element.\",\n WEBGL_NOT_SUPPORTED: \"WebGL is not supported on this browser.\",\n FAILED_CREATE_CONTEXT_2D: \"Failed to create canvas 2D context\",\n PROVIDE_PROJECTION_FIRST: \"\\\"projection\\\" should be provided before initialization.\",\n FAILED_LINKING_PROGRAM: (msg: string | null, shaderLog: string | null) => `Failed linking WebGL program - \"${msg}\\nShader compile Log: ${shaderLog}`,\n INSUFFICIENT_ARGS: (val: any, name: string) => `Insufficient arguments: given \"${val}\" for \"${name}\".`\n};\n\nexport default {\n CODES: ERROR_CODES,\n MESSAGES\n};\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nexport const EVENTS = {\n MOUSE_DOWN: \"mousedown\",\n MOUSE_MOVE: \"mousemove\",\n MOUSE_UP: \"mouseup\",\n TOUCH_START: \"touchstart\",\n TOUCH_MOVE: \"touchmove\",\n TOUCH_END: \"touchend\",\n WHEEL: \"wheel\",\n RESIZE: \"resize\",\n CONTEXT_MENU: \"contextmenu\",\n MOUSE_ENTER: \"mouseenter\",\n MOUSE_LEAVE: \"mouseleave\",\n POINTER_DOWN: \"pointerdown\",\n POINTER_MOVE: \"pointermove\",\n POINTER_UP: \"pointerup\",\n POINTER_CANCEL: \"pointercancel\",\n POINTER_ENTER: \"pointerenter\",\n POINTER_LEAVE: \"pointerleave\",\n KEY_DOWN: \"keydown\",\n KEY_UP: \"keyup\",\n LOAD: \"load\",\n ERROR: \"error\",\n CLICK: \"click\",\n DOUBLE_CLICK: \"dblclick\",\n CONTEXT_CREATE_ERROR: \"webglcontextcreationerror\",\n CONTEXT_LOST: \"webglcontextlost\",\n CONTEXT_RESTORED: \"webglcontextrestored\",\n DEVICE_ORIENTATION: \"deviceorientation\",\n DEVICE_MOTION: \"devicemotion\",\n ORIENTATION_CHANGE: \"orientationchange\",\n VIDEO_PLAY: \"play\",\n VIDEO_PAUSE: \"pause\",\n VIDEO_LOADED_DATA: \"loadeddata\",\n VIDEO_VOLUME_CHANGE: \"volumechange\",\n VIDEO_TIME_UPDATE: \"timeupdate\",\n VIDEO_DURATION_CHANGE: \"durationchange\",\n VIDEO_CAN_PLAYTHROUGH: \"canplaythrough\",\n TRANSITION_END: \"transitionend\",\n XR_END: \"end\"\n} as const;\n\nexport const EL_DIV = \"div\";\nexport const EL_BUTTON = \"button\";\n\n// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button\nexport enum MOUSE_BUTTON {\n LEFT,\n MIDDLE,\n RIGHT\n}\n\nexport const CURSOR = {\n GRAB: \"grab\",\n GRABBING: \"grabbing\",\n NONE: \"\"\n} as const;\n\nexport const KEY_DIRECTION = [\"LEFT\", \"UP\", \"RIGHT\", \"DOWN\"] as const;\nexport enum DIRECTION_KEY_CODE {\n LEFT = 37,\n UP = 38,\n RIGHT = 39,\n DOWN = 40\n}\nexport const SPACE_KEY_CODE = 32;\n\nexport const DIRECTION_KEY_NAME = {\n LEFT: \"ArrowLeft\",\n UP: \"ArrowUp\",\n RIGHT: \"ArrowRight\",\n DOWN: \"ArrowDown\"\n} as const;\nexport const SPACE_KEY_NAME = \" \";\n\nexport const FULLSCREEN_REQUEST = [\n \"requestFullscreen\",\n \"webkitRequestFullscreen\",\n \"webkitRequestFullScreen\",\n \"webkitCancelFullScreen\",\n \"mozRequestFullScreen\",\n \"msRequestFullscreen\"\n];\n\nexport const FULLSCREEN_ELEMENT = [\n \"fullscreenElement\",\n \"webkitFullscreenElement\",\n \"webkitCurrentFullScreenElement\",\n \"mozFullScreenElement\",\n \"msFullscreenElement\"\n];\n\nexport const FULLSCREEN_EXIT = [\n \"exitFullscreen\",\n \"webkitExitFullscreen\",\n \"webkitCancelFullScreen\",\n \"mozCancelFullScreen\",\n \"msExitFullscreen\"\n];\n\nexport const FULLSCREEN_CHANGE = [\n \"fullscreenchange\",\n \"webkitfullscreenchange\",\n \"mozfullscreenchange\",\n \"MSFullscreenChange\"\n];\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nexport { ERROR_CODES } from \"./error\";\n\n/**\n * Default class names\n * @ko 기본 클래스 이름들\n * @since 4.0.0\n */\nexport const DEFAULT_CLASS = {\n CONTAINER: \"view360-container\",\n CANVAS: \"view360-canvas\",\n CTX_LOST: \"view360-ctx-lost\",\n IN_VR: \"view360-vr-presenting\",\n HOTSPOT_CONTAINER: \"view360-hotspots\",\n HOTSPOT: \"view360-hotspot\",\n HOTSPOT_VISIBLE: \"view360-hotspot-visible\",\n HOTSPOT_FLIP_X: \"view360-hotspot-flip-x\",\n HOTSPOT_FLIP_Y: \"view360-hotspot-flip-y\",\n} as const;\n\n/**\n * Event names\n * @ko 이벤트 이름들\n * @since 4.0.0\n * @example\n * ```ts\n * import View360, { EVENTS } from \"@egjs/view360\";\n *\n * const viewer = new View360(\"#el_id\");\n *\n * viewer.on(EVENTS.READY, evt => {\n * console.log(\"View360 is ready!\");\n * });\n * ```\n */\nexport const EVENTS = {\n READY: \"ready\",\n LOAD_START: \"loadStart\",\n LOAD: \"load\",\n PROJECTION_CHANGE: \"projectionChange\",\n RESIZE: \"resize\",\n BEFORE_RENDER: \"beforeRender\",\n RENDER: \"render\",\n INPUT_START: \"inputStart\",\n INPUT_END: \"inputEnd\",\n VIEW_CHANGE: \"viewChange\",\n STATIC_CLICK: \"staticClick\",\n VR_START: \"vrStart\",\n VR_END: \"vrEnd\"\n} as const;\n\n/**\n * Collection of predefined easing functions\n * @ko 미리 정의된 easing 함수들\n */\nexport const EASING = {\n LINEAR: (x: number) => x,\n SINE_WAVE: (x: number) => Math.sin(x * Math.PI * 2),\n EASE_OUT_CUBIC: (x: number) => 1 - Math.pow(1 - x, 3),\n EASE_OUT_BOUNCE: (x: number): number => {\n const n1 = 7.5625;\n const d1 = 2.75;\n\n if (x < 1 / d1) {\n return n1 * x * x;\n } else if (x < 2 / d1) {\n return n1 * (x -= 1.5 / d1) * x + 0.75;\n } else if (x < 2.5 / d1) {\n return n1 * (x -= 2.25 / d1) * x + 0.9375;\n } else {\n return n1 * (x -= 2.625 / d1) * x + 0.984375;\n }\n }\n} as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { EASING } from \"./external\";\nimport { Range } from \"../type/utils\";\n\nexport const CAMERA_EVENTS = {\n CHANGE: \"change\",\n ANIMATION_END: \"animationEnd\"\n} as const;\n\nexport const CONTROL_EVENTS = {\n INPUT_START: \"inputStart\",\n CHANGE: \"change\",\n INPUT_END: \"inputEnd\",\n ENABLE: \"enable\",\n DISABLE: \"disable\",\n STATIC_CLICK: \"staticClick\"\n} as const;\n\nexport const DEG_TO_RAD = Math.PI / 180;\nexport const RAD_TO_DEG = 180 / Math.PI;\nexport const DEFAULT_EASING = EASING.EASE_OUT_CUBIC;\nexport const DEFAULT_ANIMATION_DURATION = 300;\nexport const INFINITE_RANGE: Readonly = {\n min: -Infinity, max: Infinity\n} as const;\nexport const DEFAULT_PITCH_RANGE: Readonly = {\n min: -90, max: 90\n} as const;\nexport const DEFAULT_ZOOM_RANGE: Readonly = {\n min: 0.6, max: 10\n} as const;\n\nexport enum ROTATE {\n ZERO,\n CW_90,\n CCW_90,\n CW_180\n}\n\n// Custom event name for video time change\nexport const VIDEO_TIME_CHANGE_EVENT = \"view360videotimechange\";\nexport const SVG_NAMESPACE = \"http://www.w3.org/2000/svg\";\nexport const SESSION_VR = \"immersive-vr\";\nexport const XR_REFERENCE_SPACE = \"local\";\n\nexport const EPSILON = Number.EPSILON ?? 2.220446049250313e-16;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { quat, vec3 } from \"gl-matrix\";\nimport View360Error from \"./core/View360Error\";\nimport ERROR from \"./const/error\";\nimport * as BROWSER from \"./const/browser\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"./const/internal\";\nimport { NoBoolean } from \"./type/utils\";\n\nexport const isString = (val: any): val is string => typeof val === \"string\";\nexport const isElement = (val: any): val is Element => !!val && val.nodeType === Node.ELEMENT_NODE;\n\nexport const createElement = (className: string, tag = BROWSER.EL_DIV) => {\n const el = document.createElement(tag);\n\n el.classList.add(className);\n\n return el;\n};\n\nexport const getNullableElement = (el: HTMLElement | string | null, parent?: HTMLElement): HTMLElement | null => {\n let targetEl: HTMLElement | null = null;\n\n if (isString(el)) {\n const parentEl = parent ? parent : document;\n const queryResult = parentEl.querySelector(el);\n\n if (!queryResult) {\n return null;\n }\n\n targetEl = queryResult as HTMLElement;\n } else if (isElement(el)) {\n targetEl = el;\n }\n\n return targetEl;\n};\n\nexport const getElement = (el: HTMLElement | string, parent?: HTMLElement): HTMLElement => {\n const targetEl = getNullableElement(el, parent);\n\n if (!targetEl) {\n if (isString(el)) {\n throw new View360Error(ERROR.MESSAGES.ELEMENT_NOT_FOUND(el), ERROR.CODES.ELEMENT_NOT_FOUND);\n } else {\n throw new View360Error(ERROR.MESSAGES.WRONG_TYPE(el, [\"HTMLElement\", \"string\"]), ERROR.CODES.WRONG_TYPE);\n }\n }\n\n return targetEl;\n};\n\nexport const findCanvas = (root: HTMLElement, selector: string): HTMLCanvasElement => {\n const canvas = root.querySelector(selector) as HTMLCanvasElement;\n\n if (!canvas) {\n throw new View360Error(ERROR.MESSAGES.CANVAS_NOT_FOUND, ERROR.CODES.CANVAS_NOT_FOUND);\n }\n\n return canvas;\n};\n\nexport const range = (end: number): number[] => {\n if (!end || end <= 0) {\n return [];\n }\n\n return Array.apply(0, Array(end)).map((undef, idx) => idx);\n};\n\nexport const clamp = (x: number, min: number, max: number) => Math.max(Math.min(x, max), min);\n\n// Linear interpolation between a and b\nexport const lerp = (a: number, b: number, t: number) => {\n return a * (1 - t) + b * t;\n};\n\nexport const circulate = (val: number, min: number, max: number) => {\n const size = Math.abs(max - min);\n\n if (val < min) {\n const offset = (min - val) % size;\n val = max - offset;\n } else if (val > max) {\n const offset = (val - max) % size;\n val = min + offset;\n }\n\n return val;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const merge = (target: object, ...srcs: object[]): object => {\n srcs.forEach(source => {\n Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n });\n });\n\n return target;\n};\n\nexport const findIndex = (array: T[], checker: (val: T) => boolean): number => {\n for (let idx = 0; idx < array.length; idx++) {\n if (checker(array[idx])) {\n return idx;\n }\n }\n\n return -1;\n};\n\nexport const getObjectOption = >(val?: T): NoBoolean => typeof val === \"object\" ? val : {} as any;\nexport const toVerticalFov = (fovRadian: number, aspect: number) => {\n return Math.atan(Math.tan(fovRadian * 0.5) / aspect) * 2;\n};\n\nexport const reorderCube = (arr: T[], order: string, defaultOrder = \"RLUDFB\"): T[] => {\n return defaultOrder.split(\"\")\n .map(face => order.indexOf(face))\n .map(index => arr[index]);\n};\n\nexport const isFullscreen = () => {\n if (!document) return false;\n\n for (const key of BROWSER.FULLSCREEN_ELEMENT) {\n if (document[key]) return true;\n }\n\n return false;\n};\n\nexport const sensorCanBeEnabledIOS = () => {\n return !!DeviceMotionEvent && \"requestPermission\" in DeviceMotionEvent && window.isSecureContext;\n};\n\nexport const hfovToZoom = (baseFov: number, fov: number) => {\n const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5);\n const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5);\n\n return renderingWidth / zoomedWidth;\n};\n\nexport const eulerToQuat = (out: quat, yaw: number, pitch: number, roll: number): quat => {\n quat.identity(out);\n\n const pitchThreshold = 0.01;\n const pitchClamped = clamp(pitch, -90 + pitchThreshold, 90 - pitchThreshold);\n\n quat.rotateY(out, out, yaw * DEG_TO_RAD);\n quat.rotateX(out, out, pitchClamped * DEG_TO_RAD);\n quat.rotateZ(out, out, roll * DEG_TO_RAD);\n\n return out;\n};\n\n/**\n * Extract euler angles from the quaternion, except roll(z-axis rotation)\n * @hidden\n */\nexport const quatToEuler = (quaternion: quat) => {\n const x = quaternion[0];\n const y = quaternion[1];\n const z = quaternion[2];\n const w = quaternion[3];\n const x2 = x * x;\n const y2 = y * y;\n const z2 = z * z;\n const w2 = w * w;\n\n const unit = x2 + y2 + z2 + w2;\n const test = x * w - y * z;\n\n let pitch: number, yaw: number;\n\n if (test > 0.499995 * unit) {\n // singularity at the north pole\n pitch = Math.PI / 2;\n yaw = 2 * Math.atan2(y, x);\n } else if (test < -0.499995 * unit) {\n // singularity at the south pole\n pitch = -Math.PI / 2;\n yaw = -2 * Math.atan2(y, x);\n } else {\n const view = vec3.fromValues(0, 0, 1);\n const up = vec3.fromValues(0, 1, 0);\n\n vec3.transformQuat(view, view, quaternion);\n vec3.transformQuat(up, up, quaternion);\n\n const viewXZ = Math.sqrt(view[0] * view[0] + view[2] * view[2]);\n\n pitch = Math.atan2(-view[1], viewXZ);\n yaw = Math.atan2(view[0], view[2]);\n }\n\n return {\n pitch: clamp(pitch * RAD_TO_DEG, -90, 90),\n yaw: circulate(yaw * RAD_TO_DEG, 0, 360)\n };\n};\n","/*\n * Copyright (c) 2020 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport { clamp, lerp, circulate } from \"../utils\";\nimport { Range } from \"../type/utils\";\nimport { DEFAULT_ANIMATION_DURATION, DEFAULT_EASING } from \"../const/internal\";\n\n/**\n * Interpolator between two values with duration\n * @ko 특정 시간동안 두 값을 보간해주는 보간기\n * @since 4.0.0\n */\nclass Motion {\n // Options\n private _duration: number;\n private _loop: boolean;\n private _range: Range;\n private _easing: (x: number) => number;\n\n // Internal states\n private _progress: number;\n private _val: number;\n private _start: number;\n private _end: number;\n private _activated: boolean;\n\n /**\n * Current interpolated value\n * @ko 현재 보간된 값\n * @since 4.0.0\n */\n public get val() { return this._val; }\n /**\n * Start(from) value of interpolation\n * @ko 보간 시작 값\n * @since 4.0.0\n */\n public get start() { return this._start; }\n /**\n * End(to) value of interpolation\n * @ko 보간 끝 값\n * @since 4.0.0\n */\n public get end() { return this._end; }\n /**\n * Interpolation progress value (0 ~ 1)\n * @ko 현재 보간 진행정도 (0 ~ 1)\n * @since 4.0.0\n */\n public get progress() { return this._progress; }\n /**\n * Whether the interpolation is in active state.\n * @ko 보간 진행중인지 여부. `true`일 경우 보간이 진행중입니다.\n * @since 4.0.0\n */\n public get activated() { return this._activated; }\n\n /**\n * Duration of the interpolation\n * @ko 보간할 시간\n * @since 4.0.0\n */\n public get duration() { return this._duration; }\n public set duration(val: number) { this._duration = val; }\n\n /**\n * Whether to loop interpolation on finish\n * @ko 보간이 끝난 이후에 다시 시작할지 여부\n * @since 4.0.0\n */\n public get loop() { return this._loop; }\n public set loop(val: boolean) { this._loop = val; }\n\n /**\n * Range of the interpolation\n * @ko 보간 범위\n * @since 4.0.0\n */\n public get range() { return this._range; }\n\n /**\n * Easing function of the interpolation\n * @ko 보간에 사용되는 easing function\n * @since 4.0.0\n */\n public get easing() { return this._easing; }\n public set easing(val: (x: number) => number) { this._easing = val; }\n\n /**\n * Create new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options Options {@ko 옵션들}\n * @param options.duration Duration of the interpolation {@ko 보간할 시간}\n * @param options.loop Whether to loop interpolation on finish {@ko 보간이 끝난 이후에 다시 시작할지 여부}\n * @param options.range Range of the interpolation {@ko 보간 범위}\n * @param options.loop Easing function of the interpolation {@ko 보간에 사용되는 easing function}\n */\n public constructor({\n duration = DEFAULT_ANIMATION_DURATION,\n loop = false,\n range = { min: 0, max: 1 },\n easing = DEFAULT_EASING\n } = {}) {\n this._duration = duration;\n this._loop = loop;\n this._range = range;\n this._easing = easing;\n this._activated = false;\n this.reset(0);\n }\n\n /**\n * Update motion and progress it by given deltaTime\n * @ko 주어진 deltaTime만큼 보간을 진행합니다.\n * @param deltaTime - number of milisec to update motion {@ko 보간을 진행할 시간, 밀리초 단위}\n * @returns Difference(delta) of the value from the last update. {@ko 지난 업데이트 이후의 값 변화량}\n * @since 4.0.0\n */\n public update(deltaTime: number): number {\n if (!this._activated) {\n this._val = this._end;\n return 0;\n }\n\n const start = this._start;\n const end = this._end;\n const duration = this._duration;\n const prev = this._val;\n const loop = this._loop;\n\n const nextProgress = this._progress + deltaTime / duration;\n\n this._progress = loop\n ? circulate(nextProgress, 0, 1)\n : clamp(nextProgress, 0, 1);\n\n const easedProgress = this._easing(this._progress);\n this._val = lerp(start, end, easedProgress);\n\n if (!loop && this._progress >= 1) {\n this._activated = false;\n }\n\n return this._val - prev;\n }\n\n /**\n * Set `start`, `end` to the given value and set `progress` to 0.\n * @ko 주어진 값으로 시작 지점, 끝 지점을 초기화하고 progress를 0으로 세팅합니다.\n * @param defaultVal - Value to reset {@ko 초기화할 값}\n * @since 4.0.0\n */\n public reset(defaultVal: number): void {\n const range = this._range;\n const val = clamp(defaultVal, range.min, range.max);\n this._start = val;\n this._end = val;\n this._val = val;\n this._progress = 0;\n this._activated = false;\n }\n\n /**\n * Add delta to start & end and current value.\n * @ko 현재 & 끝 및 현재 값에 주어진 값을 더합니다.\n * @param delta - Delta value to add {@ko 추가할 값}\n */\n public add(delta: number) {\n const range = this._range;\n\n this._start = clamp(this._start + delta, range.min, range.max);\n this._end = clamp(this._end + delta, range.min, range.max);\n this._val = clamp(this._val + delta, range.min, range.max);\n }\n\n /**\n * Set current value to start, and end to current value + delta, then reset progress to 0.\n * @ko 현재 값을 시작 지점으로, 그에서 delta만큼 추가된 값을 끝점으로 하고 progress를 0으로 갱신합니다.\n * @param delta - Delta value to add {@ko 추가할 값}\n */\n public setNewEndByDelta(delta: number): void {\n const range = this._range;\n\n this._start = this._val;\n this._end = clamp(this._end + delta, range.min, range.max);\n this._progress = 0;\n this._activated = true;\n }\n\n /**\n * Set new range of the interpolation.\n * @ko 보간의 범위를 변경합니다.\n * @param min - New minimum range {@ko 변경할 범위의 최소값}\n * @param max - New maximum range {@ko 변경할 범위의 최대값}\n */\n public setRange(min: number, max: number) {\n this._start = clamp(this._start, min, max);\n this._end = clamp(this._end, min, max);\n this._range = { min, max };\n }\n}\n\nexport default Motion;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { quat } from \"gl-matrix\";\nimport Camera from \"./Camera\";\nimport Motion from \"./Motion\";\nimport { DEFAULT_ANIMATION_DURATION, DEFAULT_EASING } from \"../const/internal\";\nimport { lerp } from \"../utils\";\n\ntype CameraPose = {\n rotation: quat;\n zoom: number;\n}\n\n/**\n * Animation of the {@link Camera}\n * @internal\n * @ko {@link Camera}의 애니메이션\n * @since 4.0.0\n */\nclass CameraAnimation {\n // Options\n private _camera: Camera;\n private _from: CameraPose;\n private _to: CameraPose;\n\n // Internal values\n private _motion: Motion;\n private _finishPromise: Promise;\n private _finish: () => void;\n\n /**\n * Duration of the animation\n * @ko 애니메이션 재생시간\n * @since 4.0.0\n */\n public get duration() { return this._motion.duration; }\n public set duration(val: number) { this._motion.duration = val; }\n /**\n * Easing function of the animation\n * @ko 애니메이션의 easing function\n * @since 4.0.0\n */\n public get easing() { return this._motion.easing; }\n public set easing(val: (x: number) => number) { this._motion.easing = val; }\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param camera - Camera to animate {@ko 애니메이션을 적용할 카메라}\n * @param from - Start pose {@ko 애니메이션이 시작 시점의 카메라의 회전 및 줌}\n * @param to - End pose {@ko 애니메이션이 끝났을 때 카메라의 회전 및 줌}\n * @param options - Options {@ko 옵션들}\n * @param options.duration - Animation duration {@ko 애니메이션 재생 시간}\n * @param options.easing - Animation easing function {@ko 애니메이션 easing function}\n */\n public constructor(camera: Camera, from: CameraPose, to: CameraPose, {\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING\n } = {}) {\n this._camera = camera;\n this._motion = new Motion({ duration, easing, range: { min: 0, max: 1 } });\n this._from = from;\n this._to = to;\n this._finishPromise = new Promise(resolve => {\n this._finish = resolve as () => void;\n });\n\n // Enable motion\n this._motion.setNewEndByDelta(1);\n }\n\n /**\n * Return a promise that resolved on animation end.\n * @ko 애니메이션 재생이 끝났을 때 resolve되는 Promise를 반환합니다.\n * @since 4.0.0\n */\n public getFinishPromise() {\n return this._finishPromise;\n }\n\n /**\n * Update animation by given deltaTime.\n * @ko 주어진 시간만큼 애니메이션을 업데이트합니다.\n * @param deltaTime Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n */\n public update(deltaTime: number): void {\n const camera = this._camera;\n const from = this._from;\n const to = this._to;\n const motion = this._motion;\n motion.update(deltaTime);\n\n // Progress that easing is applied\n const progress = motion.val;\n const rotation = quat.create();\n const zoom = lerp(from.zoom, to.zoom, progress);\n\n quat.slerp(rotation, from.rotation, to.rotation, progress);\n camera.rotate(rotation, zoom);\n\n if (progress >= 1) {\n this._finish();\n }\n }\n}\n\nexport default CameraAnimation;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { mat4, quat, vec3 } from \"gl-matrix\";\nimport CameraAnimation from \"./CameraAnimation\";\nimport {\n CAMERA_EVENTS,\n DEG_TO_RAD,\n INFINITE_RANGE,\n DEFAULT_PITCH_RANGE,\n RAD_TO_DEG,\n DEFAULT_ZOOM_RANGE,\n DEFAULT_EASING,\n EPSILON\n} from \"../const/internal\";\nimport {\n circulate,\n clamp,\n eulerToQuat,\n quatToEuler,\n toVerticalFov\n} from \"../utils\";\nimport { Range } from \"../type/utils\";\n\n/**\n * Events that {@link Camera} can trigger\n * @ko {@link Camera}가 트리거할 수 있는 이벤트들\n * @since 4.0.0\n */\nexport interface CameraEvents {\n /**\n * An event that fires when camera's animation stops\n * @ko 카메라 애니메이션이 멈췄을 때 트리거되는 이벤트\n * @eventName animationEnd\n * @eventOf Camera\n * @version 4.0.0\n */\n [CAMERA_EVENTS.ANIMATION_END]: {\n animation: CameraAnimation\n };\n}\n\n/**\n * Options for {@link Camera}\n * @ko {@link Camera}용 옵션들\n * @since 4.0.0\n */\nexport interface CameraOptions {\n /**\n * @copy View360#initialYaw\n */\n initialYaw: number;\n /**\n * @copy View360#initialPitch\n */\n initialPitch: number;\n /**\n * @copy View360#initialZoom\n */\n initialZoom: number;\n /**\n * @copy View360#yawRange\n */\n yawRange: Range | null;\n /**\n * @copy View360#pitchRange\n */\n pitchRange: Range | null;\n /**\n * @copy View360#zoomRange\n */\n zoomRange: Range | null;\n /**\n * @copy View360#fov\n */\n fov: number;\n}\n\n/**\n * Camera for View360\n * @ko View360용 카메라 구현체\n * @version 4.0.0\n */\nclass Camera extends Component {\n /**\n * Current yaw(y-axis rotation) value\n * @ko 현재 yaw(y축 회전) 값\n * @since 4.0.0\n */\n public yaw: number;\n /**\n * Current pitch(x-axis rotation) value\n * @ko 현재 pitch(x축 회전) 값\n * @since 4.0.0\n */\n public pitch: number;\n /**\n * Current zoom value\n * @ko 현재 줌 값\n * @since 4.0.0\n */\n public zoom: number;\n\n /**\n * @copy View360#initialYaw\n */\n public initialYaw: number;\n /**\n * @copy View360#initialPitch\n */\n public initialPitch: number;\n /**\n * @copy View360#initialPitch\n */\n public initialZoom: number;\n /**\n * @hidden\n * TODO: Please add comment for this when `rollOffset` is added\n */\n public rollOffset: number;\n\n /**\n * Current camera quaternion\n * @ko 현재 회전을 나타내는 quaternion 값\n * @since 4.0.0\n * @internal\n */\n public quaternion: quat;\n /**\n * Current camera position\n * @ko 현재 카메라 위치 좌표\n * @since 4.0.0\n * @internal\n */\n public position: vec3;\n /**\n * Active camera animation, `null` if there isn't.\n * @ko 현재 활성화된 카메라 애니메이션, 없을 경우 `null`값을 가집니다.\n * @since 4.0.0\n */\n public animation: CameraAnimation | null;\n /**\n * Camera's view matrix\n * @ko 카메라의 뷰 변환 행렬\n * @internal\n * @since 4.0.0\n */\n public viewMatrix: mat4;\n /**\n * Camera's projection matrix\n * @ko 카메라의 프로젝션 변환 행렬\n * @internal\n * @since 4.0.0\n */\n public projectionMatrix: mat4;\n\n /**\n * Camera's horizontal FOV(Field of View) value\n * @ko 카메라의 수평 FOV(Field of View) 값\n * @internal\n * @since 4.0.0\n */\n public fov: number;\n\n private _initialYawRange: Range | null;\n private _initialPitchRange: Range | null;\n private _initialZoomRange: Range | null;\n\n private _yawRange: Range | null;\n private _pitchRange: Range | null;\n private _zoomRange: Range | null;\n\n private _up: vec3;\n private _aspect: number;\n private _changed: boolean;\n private _maxRenderHeight: number;\n\n /**\n * Camera's width / height ratio\n * @ko 카메라의 가로 / 세로 비율\n * @readonly\n */\n public get aspect() { return this._aspect; }\n /**\n * Whether the camera's rotation changed from the last frame.\n * @ko 마지막 프레임 이후로 카메라의 회전값이 변경되었는지 나타내는 플래그.\n * @readonly\n */\n public get changed() { return this._changed; }\n /**\n * @copy View360#yawRange\n */\n public get yawRange() { return this._initialYawRange; }\n public set yawRange(val: Range | null) {\n this._initialYawRange = val;\n }\n /**\n * @copy View360#pitchRange\n */\n public get pitchRange() { return this._initialPitchRange; }\n public set pitchRange(val: Range | null) {\n this._initialPitchRange = val;\n }\n /**\n * @copy View360#zoomRange\n */\n public get zoomRange() { return this._initialZoomRange; }\n public set zoomRange(val: Range | null) {\n this._initialZoomRange = val;\n }\n\n /**\n * Create new instance of Camera\n * @param options - Camera options {@ko 카메라 옵션들}\n */\n public constructor({\n initialYaw,\n initialPitch,\n initialZoom,\n yawRange,\n pitchRange,\n zoomRange,\n fov\n }: CameraOptions) {\n super();\n\n this.yaw = initialYaw;\n this.pitch = initialPitch;\n this.zoom = initialZoom;\n this.rollOffset = 0;\n\n this.initialYaw = initialYaw;\n this.initialPitch = initialPitch;\n this.initialZoom = initialZoom;\n\n this.position = vec3.create();\n this.animation = null;\n\n this._up = vec3.fromValues(0, 1, 0);\n this._aspect = 1;\n\n this._initialYawRange = yawRange;\n this._initialPitchRange = pitchRange;\n this._initialZoomRange = zoomRange;\n\n this._yawRange = yawRange;\n this._pitchRange = pitchRange;\n this._zoomRange = zoomRange;\n\n this.quaternion = quat.create();\n this._updateQuaternion();\n\n this.viewMatrix = mat4.create();\n this.projectionMatrix = mat4.create();\n this.fov = fov;\n\n this._maxRenderHeight = -1;\n }\n\n /**\n * Destroy instance and detach all event listeners\n * @ko 인스턴스를 삭제하고 모든 이벤트 리스너를 삭제합니다.\n * @since 4.0.0\n */\n public destroy() {\n this.off();\n }\n\n /**\n * Refresh internal size value.\n * @ko 내부 크기값을 갱신합니다.\n * @param width - New width {@ko 변경된 너비값}\n * @param height - New height {@ko 변경된 높이값}\n * @since 4.0.0\n */\n public resize(width: number, height: number) {\n const prevAspect = this._aspect;\n\n this._aspect = width / height;\n\n if (this._aspect !== prevAspect) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation with euler values.\n * @ko 카메라 회전을 오일러 각 방향으로 변경합니다.\n * @param rotation - Rotation values {@ko 회전 값}\n * @param rotation.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값}\n * @param rotation.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값}\n * @param rotation.zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @since 4.0.0\n */\n public lookAt({\n yaw = this.yaw,\n pitch = this.pitch,\n zoom = this.zoom\n }: Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n }>) {\n const prevQuaternion = quat.clone(this.quaternion);\n const prevZoom = this.zoom;\n\n this.yaw = circulate(yaw, 0, 360);\n this.pitch = clamp(pitch, -90, 90);\n this.zoom = zoom;\n\n this._updateQuaternion();\n\n const zoomDiff = Math.abs(zoom - prevZoom);\n\n if (\n !quat.equals(this.quaternion, prevQuaternion)\n || zoomDiff >= EPSILON * 10 // ignore small changes\n ) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation with quaternion.\n * @ko 카메라 회전을 Quaternion을 이용해서 변경합니다.\n * @param rotation - Quaternion to apply {@ko 적용할 Quaternion}\n * @param zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @since 4.0.0\n */\n public rotate(rotation: quat, zoom: number = this.zoom) {\n const normalized = quat.normalize(quat.create(), rotation);\n const isSameRotation = quat.equals(this.quaternion, normalized);\n quat.copy(this.quaternion, normalized);\n\n const prevZoom = this.zoom;\n const { yaw, pitch } = quatToEuler(normalized);\n\n this.yaw = yaw;\n this.pitch = pitch;\n this.zoom = zoom;\n\n const zoomDiff = Math.abs(zoom - prevZoom);\n\n if (!isSameRotation || zoomDiff >= EPSILON * 10) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation to given euler values by the given duration.\n * @ko 카메라를 주어진 방향으로 주어진 시간동안 서서히 이동시킵니다.\n * @param options - Animation parameters {@ko 애니메이션 패러미터}\n * @param options.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값}\n * @param options.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값}\n * @param options.zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @param options.duration - Duration of the animation {@ko 애니메이션 시간}\n * @param options.easing - Easing function for the animation {@ko 애니메이션에 적용할 easing function}\n */\n public async animateTo({\n yaw = this.yaw,\n pitch = this.pitch,\n zoom = this.zoom,\n duration = 0,\n easing = DEFAULT_EASING\n }: Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n duration: number;\n easing: (x: number) => number;\n }> = {}): Promise {\n if (\n this.yaw === yaw\n && this.pitch === pitch\n && this.zoom === zoom\n ) return;\n\n const from = {\n rotation: quat.clone(this.quaternion),\n zoom: this.zoom\n };\n const to = {\n rotation: eulerToQuat(quat.create(), yaw, pitch, this.rollOffset),\n zoom\n };\n\n const animation = new CameraAnimation(this, from, to, {\n duration,\n easing\n });\n const finishPromise = animation.getFinishPromise();\n\n this.animation = animation;\n finishPromise.then(() => {\n this.animation = null;\n this.trigger(CAMERA_EVENTS.ANIMATION_END, { animation });\n });\n\n return finishPromise;\n }\n\n /**\n * @hidden\n */\n public restrictYawRange(min: number, max: number) {\n this._yawRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictPitchRange(min: number, max: number) {\n this._pitchRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictZoomRange(min: number, max: number) {\n this._zoomRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictRenderHeight(height: number) {\n this._maxRenderHeight = height;\n }\n\n /**\n * @hidden\n */\n public resetRange() {\n this._yawRange = this._initialYawRange;\n this._pitchRange = this._initialPitchRange;\n this._zoomRange = this._initialZoomRange;\n this._maxRenderHeight = -1;\n }\n\n /**\n * Get actual yaw range by the given zoom value.\n * @ko 주어진 zoom 값에 대한 실제 yaw 범위값을 반환합니다.\n * @since 4.0.0\n */\n public getYawRange(zoom: number) {\n const yawLimit = this._yawRange;\n const maxRenderHeight = this._maxRenderHeight;\n if (!yawLimit) return INFINITE_RANGE;\n\n const halfHFov = this.getHorizontalFov(zoom) * 0.5;\n let minYaw = yawLimit.min;\n let maxYaw = yawLimit.max;\n\n if (maxRenderHeight > 0) {\n const halfVFovRad = toVerticalFov(halfHFov * DEG_TO_RAD, this._aspect);\n const h = maxRenderHeight * 0.5;\n const t = Math.tan(halfVFovRad);\n const d = Math.sqrt((1 + h * h) / (1 + t * t));\n const theta = Math.atan(Math.tan(halfHFov * DEG_TO_RAD) * d) * RAD_TO_DEG;\n\n minYaw = yawLimit.min + theta;\n maxYaw = yawLimit.max - theta;\n }\n\n if (minYaw > maxYaw) {\n minYaw = 0;\n maxYaw = 0;\n }\n\n return {\n min: minYaw,\n max: maxYaw\n };\n }\n\n /**\n * Get actual pitch range by the given zoom value.\n * @ko 주어진 zoom 값에 대한 실제 pitch 범위값을 반환합니다.\n * @since 4.0.0\n */\n public getPitchRange(zoom: number) {\n const pitchLimit = this._pitchRange;\n const maxRenderHeight = this._maxRenderHeight;\n\n if (!pitchLimit) return DEFAULT_PITCH_RANGE;\n\n let minPitch = pitchLimit.min;\n let maxPitch = pitchLimit.max;\n\n if (maxRenderHeight > 0) {\n const halfVFov = this.getVerticalFov(zoom) * 0.5;\n\n minPitch = pitchLimit.min + halfVFov;\n maxPitch = pitchLimit.max - halfVFov;\n }\n\n if (minPitch > maxPitch) {\n minPitch = 0;\n maxPitch = 0;\n }\n\n return {\n min: Math.max(minPitch, -90),\n max: Math.min(maxPitch, 90)\n };\n }\n\n /**\n * Get actual zoom range in fov degrees.\n * @ko 실제 줌 범위를 fov각의 범위로 반환합니다.\n * @since 4.0.0\n */\n public getZoomRange() {\n const limit = this._zoomRange ?? DEFAULT_ZOOM_RANGE;\n\n // max (zoom in) -> minimum fov\n const minFov = this.getHorizontalFov(limit.max);\n const maxFov = this.getHorizontalFov(limit.min);\n const currentFov = this.getHorizontalFov(this.zoom);\n\n return {\n min: Math.max(minFov, 1),\n max: Math.min(maxFov, 180),\n current: currentFov\n };\n }\n\n /**\n * Return horizontal fov value when the given zoom is applied. (in degrees, °)\n * @ko 주어진 zoom 값이 적용되었을 때의 수평 fov값을 반환합니다. (도 단위, °)\n * @returns Zoomed horizontal FOV {@ko 줌이 적용된 수평 fov값}\n * @since 4.0.0\n */\n public getHorizontalFov(zoom = this.zoom) {\n return this._getZoomedHorizontalFov(zoom) * RAD_TO_DEG;\n }\n\n /**\n * Return vertical fov value when the given zoom is applied. (in degrees, °)\n * @ko 주어진 zoom 값이 적용되었을 때의 수직 fov값을 반환합니다. (도 단위, °)\n * @returns Zoomed vertical FOV {@ko 줌이 적용된 수직 fov값}\n * @since 4.0.0\n */\n public getVerticalFov(zoom = this.zoom) {\n const aspect = this._aspect;\n const hFov = this._getZoomedHorizontalFov(zoom); // In radians\n const vFov = toVerticalFov(hFov, aspect);\n\n return vFov * RAD_TO_DEG;\n }\n\n /**\n * Calculate zoom value for the given fov.\n * @ko 주어진 fov값을 zoom값으로 변환합니다.\n * @param fov horizontal fov (in degrees, °) {@ko 수평 fov 값 (도 단위, °)}\n * @since 4.0.0\n */\n public fovToZoom(fov: number) {\n const baseFov = this.fov;\n const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5);\n const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5);\n\n return renderingWidth / zoomedWidth;\n }\n\n /**\n * Update inner matrixes.\n * @ko 내부 행렬들을 업데이트합니다.\n * @internal\n * @since 4.0.0\n */\n public updateMatrix() {\n const up = this._up;\n const aspect = this._aspect;\n const viewMatrix = this.viewMatrix;\n const projMatrix = this.projectionMatrix;\n const position = this.position;\n const rotation = this.quaternion;\n\n const upDir = vec3.create();\n const viewDir = vec3.fromValues(0, 0, -1);\n vec3.transformQuat(viewDir, viewDir, rotation);\n vec3.transformQuat(upDir, up, rotation);\n\n const hFov = this._getZoomedHorizontalFov(); // In radians\n const vFov = toVerticalFov(hFov, aspect);\n\n mat4.lookAt(viewMatrix, position, viewDir, upDir);\n mat4.perspective(projMatrix, vFov, aspect, 0.1, 100);\n\n this._changed = true;\n }\n\n /**\n * @hidden\n */\n public onFrameRender() {\n this._changed = false;\n }\n\n private _updateQuaternion() {\n eulerToQuat(this.quaternion, this.yaw, this.pitch, this.rollOffset);\n }\n\n /**\n * @param zoom Current zoom value\n * @returns horizontal fov including zoom, in radian\n */\n private _getZoomedHorizontalFov(zoom = this.zoom) {\n return 2 * Math.atan(Math.tan(DEG_TO_RAD * this.fov * 0.5) / zoom);\n }\n}\n\nexport default Camera;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass MouseInput extends Component> {\n private _el: HTMLElement | null;\n private _prevPos: [number, number];\n\n public constructor() {\n super();\n\n this._el = null;\n this._prevPos = [0, 0];\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onMouseDown);\n\n this._el = element;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onMouseDown);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this._el = null;\n }\n\n private _onMouseDown = (evt: MouseEvent) => {\n const el = this._el;\n if (!el || evt.button !== BROWSER.MOUSE_BUTTON.LEFT) return;\n\n evt.preventDefault();\n\n if (el.focus) {\n el.focus();\n } else {\n window.focus();\n }\n\n this._prevPos[0] = evt.clientX;\n this._prevPos[1] = evt.clientY;\n\n window.addEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.addEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: false\n });\n }\n\n private _onMouseMove = (evt: MouseEvent) => {\n evt.preventDefault();\n\n const x = evt.clientX;\n const y = evt.clientY;\n const prevPos = this._prevPos;\n const deltaX = x - prevPos[0];\n const deltaY = y - prevPos[1];\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta: {\n x: deltaX,\n y: deltaY\n },\n isTouch: false,\n isKeyboard: false\n });\n\n prevPos[0] = x;\n prevPos[1] = y;\n }\n\n private _onMouseUp = () => {\n this._prevPos[0] = 0;\n this._prevPos[1] = 0;\n\n window.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: false,\n scrolling: false\n });\n }\n}\n\nexport default MouseInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\nimport { isFullscreen } from \"../../utils\";\n\nclass TouchInput extends Component> {\n private _el: HTMLElement | null;\n private _prevPos: [number, number];\n private _isFirstTouch: boolean;\n private _scrolling: boolean;\n private _scrollable: boolean;\n\n public get scrollable() { return this._scrollable; }\n public set scrollable(val: boolean) { this._scrollable = val; }\n\n public constructor() {\n super();\n\n this._el = null;\n this._prevPos = [0, 0];\n this._isFirstTouch = false;\n this._scrolling = false;\n this._scrollable = false;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.TOUCH_START, this._onTouchStart, { passive: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, { passive: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = element;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.TOUCH_START, this._onTouchStart);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = null;\n }\n\n private _onTouchStart = (evt: TouchEvent) => {\n if (evt.touches.length > 1 || this._scrolling) return;\n\n const touch = evt.touches[0];\n\n this._isFirstTouch = true;\n this._prevPos[0] = touch.clientX;\n this._prevPos[1] = touch.clientY;\n\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: true,\n isKeyboard: false\n });\n };\n\n private _onTouchMove = (evt: TouchEvent) => {\n // Only the one finger motion should be considered\n if (evt.touches.length > 1 || this._scrolling) return;\n\n const touch = evt.touches[0];\n const scrollable = this._scrollable;\n const prevPos = this._prevPos;\n\n const x = touch.clientX;\n const y = touch.clientY;\n const deltaX = x - prevPos[0];\n const deltaY = y - prevPos[1];\n\n if (this._isFirstTouch) {\n if (scrollable && !isFullscreen()) {\n if (Math.abs(deltaY) > Math.abs(deltaX)) {\n // Assume Scrolling\n this._scrolling = true;\n return;\n }\n }\n\n this._isFirstTouch = false;\n }\n\n if (evt.cancelable !== false) {\n evt.preventDefault();\n }\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta: {\n x: deltaX,\n y: deltaY\n },\n isTouch: true,\n isKeyboard: false\n });\n\n prevPos[0] = x;\n prevPos[1] = y;\n };\n\n private _onTouchEnd = (evt: TouchEvent) => {\n if (evt.touches.length !== 0) return;\n\n const touch = evt.touches[0];\n const prevPos = this._prevPos;\n\n if (touch) {\n prevPos[0] = touch.clientX;\n prevPos[1] = touch.clientY;\n } else {\n prevPos[0] = 0;\n prevPos[1] = 0;\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: true,\n isKeyboard: false,\n scrolling: this._scrolling\n });\n }\n\n if (evt.cancelable !== false) {\n evt.preventDefault();\n }\n\n this._scrolling = false;\n };\n}\n\nexport default TouchInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass KeyboardInput extends Component> {\n private _el: HTMLElement | null;\n private _pressed: {\n LEFT: boolean;\n UP: boolean;\n RIGHT: boolean;\n DOWN: boolean;\n };\n\n public get active() {\n const pressed = this._pressed;\n return pressed.LEFT || pressed.UP || pressed.RIGHT || pressed.DOWN;\n }\n\n public constructor() {\n super();\n\n this._el = null;\n this._clearPressedKeys();\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown);\n element.addEventListener(BROWSER.EVENTS.KEY_UP, this._onKeyUp);\n\n this._el = element;\n this._clearPressedKeys();\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown);\n element.removeEventListener(BROWSER.EVENTS.KEY_UP, this._onKeyUp);\n\n this._el = null;\n this._clearPressedKeys();\n }\n\n public update() {\n const delta = this._getDeltaByPressedKeys();\n\n if (delta.x !== 0 || delta.y !== 0) {\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: false,\n isKeyboard: true\n });\n }\n }\n\n private _clearPressedKeys() {\n this._pressed = BROWSER.KEY_DIRECTION.reduce((obj, keyName) => {\n return {\n ...obj,\n [keyName]: false\n };\n }, {} as KeyboardInput[\"_pressed\"]);\n }\n\n private _updateKeyPress(event: KeyboardEvent, isEnable: boolean): void {\n const pressed = this._pressed;\n const keyToUpdate = event.keyCode != null\n ? BROWSER.DIRECTION_KEY_CODE[event.keyCode]\n : BROWSER.DIRECTION_KEY_NAME[event.key];\n\n if (!keyToUpdate) return;\n\n pressed[keyToUpdate] = isEnable;\n }\n\n private _getPressedKeyCount() {\n return BROWSER.KEY_DIRECTION.filter(key => this._pressed[key]).length;\n }\n\n private _getDeltaByPressedKeys() {\n const pressed = this._pressed;\n let x = 0;\n let y = 0;\n\n if (pressed.LEFT) {\n x += 1;\n }\n\n if (pressed.RIGHT) {\n x -= 1;\n }\n\n if (pressed.UP) {\n y += 1;\n }\n\n if (pressed.DOWN) {\n y -= 1;\n }\n\n return {\n x, y\n };\n }\n\n private _onKeyDown = (evt: KeyboardEvent) => {\n // Ignore all other keypress except main arrow keys\n if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return;\n\n this._updateKeyPress(evt, true);\n\n const pressedCount = this._getPressedKeyCount();\n if (pressedCount <= 0) return;\n\n evt.preventDefault();\n if (pressedCount === 1 && !evt.repeat) {\n // On first keydown\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: true\n });\n }\n };\n\n private _onKeyUp = (evt: KeyboardEvent) => {\n // Ignore all other keypress except main arrow keys\n if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return;\n\n this._updateKeyPress(evt, false);\n\n const pressedCount = this._getPressedKeyCount();\n if (pressedCount > 0) return;\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: true,\n scrolling: false\n });\n };\n}\n\nexport default KeyboardInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport MouseInput from \"./input/MouseInput\";\nimport TouchInput from \"./input/TouchInput\";\nimport KeyboardInput from \"./input/KeyboardInput\";\nimport Camera from \"../core/Camera\";\nimport Motion from \"../core/Motion\";\nimport { CONTROL_EVENTS, INFINITE_RANGE, DEFAULT_PITCH_RANGE, DEFAULT_ANIMATION_DURATION, DEFAULT_EASING, DEG_TO_RAD, RAD_TO_DEG } from \"../const/internal\";\nimport { toVerticalFov } from \"../utils\";\nimport { ControlEvents, InputEvents } from \"../type/internal\";\n\n/**\n * Options for {@link RotateControl}\n * @ko {@link RotateControl}용 옵션들\n * @since 4.0.0\n */\nexport interface RotateControlOptions {\n /**\n * @copy RotateControl#pointerScale\n */\n pointerScale: [number, number];\n /**\n * @copy RotateControl#keyboardScale\n */\n keyboardScale: [number, number];\n /**\n * @copy RotateControl#duration\n */\n duration: number;\n /**\n * @copy RotateControl#easing\n */\n easing: (x: number) => number;\n /**\n * @copy RotateControl#disablePitch\n */\n disablePitch: boolean;\n /**\n * @copy RotateControl#disableYaw\n */\n disableYaw: boolean;\n /**\n * @copy RotateControl#disableKeyboard\n */\n disableKeyboard: boolean;\n}\n\ntype RotateDeltaType = { x: number; y: number; };\nexport type RotateControlEvents = ControlEvents;\n\n/**\n * Camera's rotation control\n * @ko 카메라의 회전을 담당하는 컨트롤\n * @since 4.0.0\n */\nclass RotateControl extends Component implements CameraControl {\n // Options\n private _pointerScale: RotateControlOptions[\"pointerScale\"];\n private _keyboardScale: RotateControlOptions[\"keyboardScale\"];\n private _duration: RotateControlOptions[\"duration\"];\n private _easing: RotateControlOptions[\"easing\"];\n private _disablePitch: RotateControlOptions[\"disablePitch\"];\n private _disableYaw: RotateControlOptions[\"disableYaw\"];\n private _disableKeyboard: RotateControlOptions[\"disableKeyboard\"];\n\n // Internal values\n private _controlEl: HTMLElement;\n private _enableBlocked: boolean;\n private _mouseInput: MouseInput;\n private _touchInput: TouchInput;\n private _keyboardInput: KeyboardInput;\n private _xMotion: Motion;\n private _yMotion: Motion;\n private _screenScale: [number, number];\n private _zoomScale: number;\n private _enabled: boolean;\n private _changedWhileDragging: boolean;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() {\n return this._keyboardInput.active\n || this._xMotion.activated\n || this._yMotion.activated;\n }\n /**\n * Current yaw value\n * @ko 현재 yaw 값\n * @readonly\n * @since 4.0.0\n */\n public get yaw() { return this._xMotion; }\n /**\n * Current pitch value\n * @ko 현재 pitch 값\n * @readonly\n * @since 4.0.0\n */\n public get pitch() { return this._yMotion; }\n /**\n * @copy View360#scrollable\n */\n public get scrollable() { return this._touchInput.scrollable; }\n public set scrollable(val: boolean) {\n this._touchInput.scrollable = val;\n }\n\n /**\n * Scale factor for mouse/touch rotation\n * @ko 마우스/터치를 통한 회전 배율\n * @default [1, 1]\n * @since 4.0.0\n */\n public get pointerScale() { return this._pointerScale; }\n public set pointerScale(val: RotateControlOptions[\"pointerScale\"]) {\n this._pointerScale = val;\n }\n\n /**\n * Scale factor for keyboard rotation\n * @ko 키보드를 통한 회전 배율\n * @default [1, 1]\n * @since 4.0.0\n */\n public get keyboardScale() { return this._keyboardScale; }\n public set keyboardScale(val: RotateControlOptions[\"keyboardScale\"]) {\n this._keyboardScale = val;\n }\n\n /**\n * Duration of the input animation (ms)\n * @ko 회전 애니메이션의 시간 (ms)\n * @default 300\n */\n public get duration() { return this._duration; }\n public set duration(val: RotateControlOptions[\"duration\"]) {\n this._duration = val;\n this._xMotion.duration = val;\n this._yMotion.duration = val;\n }\n\n /**\n * Easing function of the animation\n * @ko 회전 애니메이션에 적용할 easing 함수\n * @default EASING.EASE_OUT_CUBIC\n * @see EASING\n */\n public get easing() { return this._easing; }\n public set easing(val: RotateControlOptions[\"easing\"]) {\n this._easing = val;\n this._xMotion.easing = val;\n this._yMotion.easing = val;\n }\n\n /**\n * Disable X-axis(pitch) rotation.\n * @ko x축 회전(pitch)을 비활성화합니다.\n * @default false\n */\n public get disablePitch() { return this._disablePitch; }\n public set disablePitch(val: RotateControlOptions[\"disablePitch\"]) { this._disablePitch = val; }\n\n /**\n * Disable Y-axis(yaw) rotation.\n * @ko y축 회전(yaw)을 비활성화합니다.\n * @default false\n */\n public get disableYaw() { return this._disableYaw; }\n public set disableYaw(val: RotateControlOptions[\"disableYaw\"]) { this._disableYaw = val; }\n\n /**\n * Disable rotation by keyboard.\n * @ko 키보드를 이용한 회전을 비활성화합니다.\n * @default false\n */\n public get disableKeyboard() { return this._disableKeyboard; }\n public set disableKeyboard(val: RotateControlOptions[\"disableKeyboard\"]) { this._disableKeyboard = val; }\n\n /**\n * Create new RotateControl instance\n * @ko RotateControl의 인스턴스를 생성합니다.\n * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트}\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(controlEl: HTMLElement, enableBlocked: boolean, {\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING,\n pointerScale = [1, 1],\n keyboardScale = [1, 1],\n disablePitch = false,\n disableYaw = false,\n disableKeyboard = false\n }: Partial = {}) {\n super();\n\n this._controlEl = controlEl;\n this._pointerScale = pointerScale;\n this._keyboardScale = keyboardScale;\n this._duration = duration;\n this._easing = easing;\n this._disablePitch = disablePitch;\n this._disableYaw = disableYaw;\n this._disableKeyboard = disableKeyboard;\n\n this._enableBlocked = enableBlocked;\n this._mouseInput = new MouseInput();\n this._touchInput = new TouchInput();\n this._keyboardInput = new KeyboardInput();\n this._xMotion = new Motion({ duration, range: INFINITE_RANGE, easing });\n this._yMotion = new Motion({ duration, range: DEFAULT_PITCH_RANGE, easing });\n this._screenScale = [1, 1];\n this._zoomScale = 1;\n this._enabled = false;\n this._changedWhileDragging = false;\n this._bindInputs();\n }\n\n public destroy(): void {\n this.disable();\n this._mouseInput.off();\n this._touchInput.off();\n this._keyboardInput.off();\n this.off();\n this._changedWhileDragging = false;\n }\n\n /**\n * @hidden\n */\n public update(delta: number): void {\n if (!this._enabled) return;\n\n const xMotion = this._xMotion;\n const yMotion = this._yMotion;\n const keyboardInput = this._keyboardInput;\n\n if (!this._disableKeyboard) {\n keyboardInput.update();\n }\n\n if (!this._disablePitch) {\n yMotion.update(delta);\n }\n\n if (!this._disableYaw) {\n xMotion.update(delta);\n }\n }\n\n /**\n * @hidden\n */\n public updateRange(camera: Camera, zoom: number) {\n const yawRange = camera.getYawRange(zoom);\n const pitchRange = camera.getPitchRange(zoom);\n\n this._xMotion.setRange(yawRange.min, yawRange.max);\n this._yMotion.setRange(pitchRange.min, pitchRange.max);\n }\n\n /**\n * @hidden\n */\n public setZoomScale(val: number) {\n this._zoomScale = val;\n }\n\n /**\n * Resize control to match target size.\n * @ko 컨트롤의 내부 크기를 갱신합니다.\n * @param hfov - Camera horizontal fov in degrees {@ko 카메라의 수평방향 fov값 (도 단위)}\n * @param aspect - Camera aspect {@ko 카메라 가로/세로 비율}\n * @param width - New width {@ko 갱신된 너비}\n * @param height - New height {@ko 갱신된 높이}\n */\n public resize(hfov: number, aspect: number, width: number, height: number) {\n const vfov = toVerticalFov(hfov * DEG_TO_RAD, aspect) * RAD_TO_DEG;\n\n this._screenScale[0] = hfov / width;\n this._screenScale[1] = vfov / height;\n }\n\n public enable(): void {\n if (this._enabled) return;\n\n const element = this._controlEl;\n\n this._mouseInput.enable(element);\n this._touchInput.enable(element);\n this._keyboardInput.enable(element);\n\n this._enabled = true;\n this._enableBlocked = false;\n\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: true });\n }\n\n public disable(): void {\n if (!this._enabled) return;\n\n this._mouseInput.disable();\n this._touchInput.disable();\n this._keyboardInput.disable();\n\n this._enabled = false;\n\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: true });\n }\n\n public sync(camera: Camera): void {\n this.updateRange(camera, camera.zoom);\n\n this._xMotion.reset(camera.yaw);\n this._yMotion.reset(camera.pitch);\n }\n\n private _bindInputs() {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n const keyboardInput = this._keyboardInput;\n\n mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n touchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n touchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n keyboardInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n keyboardInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n keyboardInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n }\n\n private _onInputStart = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n this._changedWhileDragging = false;\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n ...evt,\n inputType: \"rotate\"\n });\n };\n\n private _onChange = (evt: InputEvents[typeof CONTROL_EVENTS.CHANGE]) => {\n const delta = evt.delta;\n const invZoomScale = 1 / this._zoomScale; // Reduce speed on zoom\n const screenScale = this._screenScale;\n const keyboardScale = this._keyboardScale;\n const pointerScale = this._pointerScale;\n\n let scale: [number, number];\n\n if (evt.isKeyboard) {\n scale = [\n keyboardScale[0] * invZoomScale,\n keyboardScale[1] * invZoomScale\n ];\n } else {\n scale = [\n pointerScale[0] * screenScale[0] * invZoomScale,\n pointerScale[1] * screenScale[1] * invZoomScale\n ];\n }\n\n const scaledX = delta.x * scale[0];\n const scaledY = delta.y * scale[1];\n\n this._xMotion.setNewEndByDelta(scaledX);\n this._yMotion.setNewEndByDelta(scaledY);\n\n this._changedWhileDragging = true;\n }\n\n private _onInputEnd = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n ...evt,\n inputType: \"rotate\"\n });\n\n if (!this._changedWhileDragging && !evt.isKeyboard && !evt.scrolling) {\n this.trigger(CONTROL_EVENTS.STATIC_CLICK, {\n isTouch: evt.isTouch\n });\n }\n\n this._changedWhileDragging = false;\n };\n}\n\nexport default RotateControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS, DEFAULT_ANIMATION_DURATION } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass WheelInput extends Component> {\n private _el: HTMLElement | null;\n private _scrollable: boolean;\n private _baseScale: number;\n private _inputTimer: number;\n\n public get scrollable() { return this._scrollable; }\n public set scrollable(val: boolean) { this._scrollable = val; }\n\n public constructor() {\n super();\n\n this._el = null;\n this._baseScale = 0.04;\n this._scrollable = false;\n this._inputTimer = -1;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.WHEEL, this._onWheel, { passive: false, capture: false });\n\n this._el = element;\n this._clearTimer();\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.WHEEL, this._onWheel, false);\n\n this._el = null;\n this._clearTimer();\n }\n\n private _onWheel = (evt: WheelEvent) => {\n const scrollable = this._scrollable;\n\n if (evt.deltaY === 0 || scrollable) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n\n if (this._inputTimer < 0) {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: false\n });\n } else {\n this._clearTimer();\n }\n\n const delta = this._baseScale * evt.deltaY;\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: false,\n isKeyboard: false\n });\n\n this._inputTimer = window.setTimeout(() => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: false,\n scrolling: false\n });\n this._inputTimer = -1;\n }, DEFAULT_ANIMATION_DURATION);\n };\n\n private _clearTimer() {\n window.clearTimeout(this._inputTimer);\n this._inputTimer = -1;\n }\n}\n\nexport default WheelInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass PinchInput extends Component> {\n private _el: HTMLElement | null;\n private _baseScale: number;\n private _prevDistance: number;\n private _isFirstTouch: boolean;\n\n public constructor() {\n super();\n\n this._el = null;\n this._baseScale = -0.2;\n this._prevDistance = -1;\n this._isFirstTouch = true;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, { passive: false, capture: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = element;\n this._prevDistance = -1;\n this._isFirstTouch = true;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, false);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = null;\n }\n\n private _onTouchMove = (evt: TouchEvent) => {\n const touches = evt.touches;\n if (touches.length !== 2) return;\n\n if (!evt.cancelable) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n\n const prevDistance = this._prevDistance;\n\n const diff = [\n touches[0].pageX - touches[1].pageX,\n touches[0].pageY - touches[1].pageY\n ];\n\n const distance = Math.sqrt(diff[0] * diff[0] + diff[1] * diff[1]) * this._baseScale;\n const delta = this._isFirstTouch\n ? 0\n : distance - prevDistance;\n\n if (this._isFirstTouch) {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: true,\n isKeyboard: false\n });\n }\n\n this._prevDistance = distance;\n this._isFirstTouch = false;\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: true,\n isKeyboard: false\n });\n };\n\n private _onTouchEnd = (evt: TouchEvent) => {\n if (evt.touches.length !== 0) return;\n\n if (!this._isFirstTouch) {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: true,\n isKeyboard: false,\n scrolling: false\n });\n }\n\n this._prevDistance = -1;\n this._isFirstTouch = true;\n };\n}\n\nexport default PinchInput;\n","/*\n* Copyright (c) 2023-present NAVER Corp.\n* egjs projects are licensed under the MIT license\n*/\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport WheelInput from \"./input/WheelInput\";\nimport PinchInput from \"./input/PinchInput\";\nimport Camera from \"../core/Camera\";\nimport Motion from \"../core/Motion\";\nimport {\n CONTROL_EVENTS,\n DEFAULT_ANIMATION_DURATION,\n DEFAULT_EASING,\n INFINITE_RANGE\n} from \"../const/internal\";\nimport { ControlEvents, InputEvents } from \"../type/internal\";\n\n/**\n * Options for {@link ZoomControl}\n * @ko {@link ZoomControl}용 옵션들\n * @since 4.0.0\n */\nexport interface ZoomControlOptions {\n /**\n * @copy ZoomControl#scale\n */\n scale: number;\n /**\n * @copy ZoomControl#duration\n */\n duration: number;\n /**\n * @copy ZoomControl#easing\n */\n easing: (x: number) => number;\n}\n\ntype ZoomControlEvents = ControlEvents;\n\n/**\n * Camera's zoom control\n * @ko 카메라의 줌 값을 담당하는 컨트롤\n * @since 4.0.0\n */\nclass ZoomControl extends Component implements CameraControl {\n // Options\n private _scale: ZoomControlOptions[\"scale\"];\n\n // Internal values\n private _controlEl: HTMLElement;\n private _enableBlocked: boolean;\n private _wheelInput: WheelInput;\n private _pinchInput: PinchInput;\n private _motion: Motion;\n private _enabled: boolean;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() { return this._motion.activated; }\n /**\n * Current zoom value\n * @ko 현재 줌 값\n * @since 4.0.0\n * @readonly\n */\n public get zoom() { return this._motion.val; }\n /**\n * @copy View360#wheelScrollable\n */\n public get scrollable() { return this._wheelInput.scrollable; }\n public set scrollable(val: boolean) {\n this._wheelInput.scrollable = val;\n }\n /**\n * @hidden\n */\n public get range() { return this._motion.range; }\n\n /**\n * Scale factor of the zoom\n * @ko 입력에 의한 줌 배율\n * @default 1\n * @since 4.0.0\n */\n public get scale() { return this._scale; }\n public set scale(val: ZoomControlOptions[\"scale\"]) { this._scale = val; }\n\n /**\n * Duration of the input animation (ms)\n * @ko 회전 애니메이션의 시간 (ms)\n * @default 300\n * @since 4.0.0\n */\n public get duration() { return this._motion.duration; }\n\n /**\n * Easing function of the animation\n * @ko 회전 애니메이션에 적용할 easing 함수\n * @default EASING.EASE_OUT_CUBIC\n * @see EASING\n * @since 4.0.0\n */\n public get easing() { return this._motion.easing; }\n\n /**\n * Create new ZoomControl instance\n * @ko ZoomControl의 인스턴스를 생성합니다.\n * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트}\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(controlEl: HTMLElement, enableBlocked: boolean, {\n scale = 1,\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING\n }: Partial = {}) {\n super();\n\n this._scale = scale;\n\n this._controlEl = controlEl;\n this._enableBlocked = enableBlocked;\n this._wheelInput = new WheelInput();\n this._pinchInput = new PinchInput();\n this._motion = new Motion({\n duration,\n easing,\n range: INFINITE_RANGE\n });\n this._enabled = false;\n\n this._bindInputs();\n }\n\n public destroy(): void {\n this.disable();\n this._wheelInput.off();\n this._pinchInput.off();\n this.off();\n }\n\n /**\n * @hidden\n */\n public update(delta: number): void {\n if (!this._enabled) return;\n\n const motion = this._motion;\n motion.update(delta);\n }\n\n public enable(): void {\n if (this._enabled) return;\n\n const element = this._controlEl;\n this._wheelInput.enable(element);\n this._pinchInput.enable(element);\n\n this._enabled = true;\n this._enableBlocked = false;\n\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: false });\n }\n\n public disable(): void {\n if (!this._enabled) return;\n\n this._wheelInput.disable();\n this._pinchInput.disable();\n\n this._enabled = false;\n\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: false });\n }\n\n public sync(camera: Camera): void {\n const motion = this._motion;\n const range = camera.getZoomRange();\n\n motion.setRange(range.min, range.max);\n motion.reset(range.current);\n }\n\n private _bindInputs() {\n const wheelInput = this._wheelInput;\n const pinchInput = this._pinchInput;\n\n wheelInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n wheelInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n wheelInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n pinchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n pinchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n pinchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n }\n\n private _onInputStart = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n ...evt,\n inputType: \"zoom\"\n });\n };\n\n private _onChange = ({ delta }: InputEvents[typeof CONTROL_EVENTS.CHANGE]) => {\n const scale = this._scale;\n const scaledDelta = delta * scale;\n\n this._motion.setNewEndByDelta(scaledDelta);\n };\n\n private _onInputEnd = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n ...evt,\n inputType: \"zoom\"\n });\n };\n}\n\nexport default ZoomControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { quat, vec3 } from \"gl-matrix\";\nimport * as BROWSER from \"../../const/browser\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\nimport { quatToEuler } from \"../../utils\";\n\nexport const ROTATE_CONSTANT = {\n PITCH_DELTA: 1,\n YAW_DELTA_BY_ROLL: 2,\n YAW_DELTA_BY_YAW: 3\n} as const;\n\nROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = {\n targetAxis: [0, 1, 0],\n meshPoint: [0, 0, 1]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = {\n targetAxis: [0, 1, 0],\n meshPoint: [1, 0, 0]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = {\n targetAxis: [1, 0, 0],\n meshPoint: [0, 0, 1]\n};\n\nclass GyroInput extends Component> {\n public quaternion: quat;\n\n private _ignoreRoll: boolean;\n\n private _yawOrigin: number;\n private _yawOffset: number;\n private _orientation: {\n alpha: number;\n beta: number;\n gamma: number;\n }\n private _orientationUpdated: boolean;\n private _needsCalibrate: boolean;\n private _screenOrientation: number;\n private _enabled: boolean;\n\n public get enabled() { return this._enabled; }\n public get orientationUpdated() { return this._orientationUpdated; }\n public get ignoreRoll() { return this._ignoreRoll; }\n public set ignoreRoll(val: boolean) { this._ignoreRoll = val; }\n\n public constructor() {\n super();\n\n this.quaternion = quat.create();\n\n this._orientation = {\n alpha: 0,\n beta: 90,\n gamma: 0\n };\n this._yawOrigin = 0;\n this._yawOffset = 0;\n this._orientationUpdated = false;\n this._screenOrientation = 0;\n this._needsCalibrate = true;\n this._enabled = false;\n }\n\n public enable() {\n if (this._enabled) return;\n\n window.addEventListener(BROWSER.EVENTS.DEVICE_ORIENTATION, this._onDeviceOrientation);\n window.addEventListener(BROWSER.EVENTS.ORIENTATION_CHANGE, this._updateScreenOrientation);\n\n this._updateScreenOrientation();\n this._orientationUpdated = false;\n this._needsCalibrate = true;\n this._enabled = true;\n }\n\n public disable() {\n if (!this._enabled) return;\n\n window.removeEventListener(BROWSER.EVENTS.DEVICE_ORIENTATION, this._onDeviceOrientation);\n window.removeEventListener(BROWSER.EVENTS.ORIENTATION_CHANGE, this._updateScreenOrientation);\n\n this._enabled = false;\n }\n\n public update() {\n this._updateRotation();\n this._orientationUpdated = false;\n }\n\n public collectDelta() {\n if (!this._orientationUpdated) {\n return {\n pitch: 0,\n yaw: 0\n };\n }\n\n const prevRotation = quat.clone(this.quaternion);\n\n this._updateRotation();\n this._orientationUpdated = false;\n\n return this._toEulerDelta(prevRotation, this.quaternion);\n }\n\n public setInitialRotation(yaw: number) {\n this._yawOrigin = yaw;\n }\n\n private _onDeviceOrientation = (evt: DeviceOrientationEvent) => {\n const prevOrientation = this._orientation;\n const { alpha, beta, gamma } = evt;\n\n if (\n alpha == null\n || beta == null\n || gamma == null\n ) return;\n\n prevOrientation.alpha = alpha;\n prevOrientation.beta = beta;\n prevOrientation.gamma = gamma;\n\n this._orientationUpdated = true;\n\n if (this._needsCalibrate) {\n this._needsCalibrate = false;\n this._calibrateSensor();\n }\n };\n\n private _calibrateSensor() {\n const yawOrigin = this._yawOrigin;\n const rotation = this.quaternion;\n\n this._yawOffset = 0;\n this._updateRotation();\n\n const { yaw: sensorYaw } = quatToEuler(rotation);\n this._yawOffset = sensorYaw - yawOrigin;\n this._updateRotation();\n\n this._needsCalibrate = false;\n }\n\n private _updateRotation() {\n const rotation = this.quaternion;\n const { alpha, beta, gamma } = this._orientation;\n\n quat.identity(rotation);\n quat.rotateY(rotation, rotation, (alpha - this._yawOffset) * DEG_TO_RAD);\n quat.rotateX(rotation, rotation, beta * DEG_TO_RAD);\n quat.rotateZ(rotation, rotation, -gamma * DEG_TO_RAD);\n\n const screen = quat.create();\n const screenAngle = -this._screenOrientation * 0.5 * DEG_TO_RAD;\n const world = quat.fromValues(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5));\n\n quat.set(screen, 0, Math.sin(screenAngle), 0, Math.cos(screenAngle));\n quat.multiply(rotation, rotation, screen);\n quat.multiply(rotation, rotation, world);\n\n quat.normalize(rotation, rotation);\n }\n\n private _updateScreenOrientation = () => {\n if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) {\n this._screenOrientation = screen.orientation.angle;\n } else if (window.orientation !== undefined) {\n this._screenOrientation = window.orientation >= 0 ?\n window.orientation : 360 + window.orientation;\n } else {\n this._screenOrientation = 0;\n }\n }\n\n private _toEulerDelta(prevQuat: quat, currentQuat: quat) {\n return {\n yaw: this._getDeltaYaw(prevQuat, currentQuat),\n pitch: this._getDeltaPitch(prevQuat, currentQuat),\n };\n }\n\n private _getDeltaYaw(prvQ: quat, curQ: quat): number {\n const yawDeltaByYaw = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW);\n const yawDeltaByRoll = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL)\n * Math.sin(this._extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n }\n\n private _getDeltaPitch(prvQ: quat, curQ: quat): number {\n return this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n }\n\n private _getRotationDelta(prevQ: quat, curQ: quat, rotateKind: typeof ROTATE_CONSTANT[keyof typeof ROTATE_CONSTANT]) {\n const targetAxis = vec3.fromValues(\n ROTATE_CONSTANT[rotateKind].targetAxis[0],\n ROTATE_CONSTANT[rotateKind].targetAxis[1],\n ROTATE_CONSTANT[rotateKind].targetAxis[2]\n );\n const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint;\n\n const prevQuaternion = quat.clone(prevQ);\n const curQuaternion = quat.clone(curQ);\n\n quat.normalize(prevQuaternion, prevQuaternion);\n quat.normalize(curQuaternion, curQuaternion);\n\n let prevPoint = vec3.fromValues(0, 0, 1);\n let curPoint = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n vec3.transformQuat(targetAxis, targetAxis, curQuaternion);\n\n const rotateDistance = vec3.dot(targetAxis, vec3.cross(vec3.create(), prevPoint, curPoint));\n const rotateDirection = rotateDistance > 0 ? 1 : -1;\n\n // when counter clock wise, use vec3.fromValues(0,1,0)\n // when clock wise, use vec3.fromValues(0,-1,0)\n // const meshPoint1 = vec3.fromValues(0, 0, 0);\n const meshPoint2 = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n\n let meshPoint3;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n meshPoint3 = vec3.fromValues(0, rotateDirection, 0);\n } else {\n meshPoint3 = vec3.fromValues(rotateDirection, 0, 0);\n }\n\n vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion);\n vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion);\n\n const vecU = meshPoint2;\n const vecV = meshPoint3;\n const vecN = vec3.create();\n\n vec3.cross(vecN, vecU, vecV);\n vec3.normalize(vecN, vecN);\n\n const coefficientA = vecN[0];\n const coefficientB = vecN[1];\n const coefficientC = vecN[2];\n\n // a point on the plane\n curPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n\n // a point should project on the plane\n prevPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n\n // distance between prevPoint and the plane\n let distance = Math.abs(\n prevPoint[0] * coefficientA +\n prevPoint[1] * coefficientB +\n prevPoint[2] * coefficientC\n );\n\n const projectedPrevPoint = vec3.create();\n\n vec3.subtract(projectedPrevPoint, prevPoint, vec3.scale(vec3.create(), vecN, distance));\n\n let trigonometricRatio =\n (projectedPrevPoint[0] * curPoint[0] +\n projectedPrevPoint[1] * curPoint[1] +\n projectedPrevPoint[2] * curPoint[2]) /\n (vec3.length(projectedPrevPoint) * vec3.length(curPoint));\n\n // defensive block\n if (trigonometricRatio > 1) {\n trigonometricRatio = 1;\n }\n\n const theta = Math.acos(trigonometricRatio);\n\n const crossVec = vec3.cross(vec3.create(), curPoint, projectedPrevPoint);\n\n distance = coefficientA * crossVec[0]\n + coefficientB * crossVec[1]\n + coefficientC * crossVec[2];\n\n let thetaDirection: number;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n thetaDirection = distance > 0 ? 1 : -1;\n } else {\n thetaDirection = distance < 0 ? 1 : -1;\n }\n\n const deltaRadian = theta * thetaDirection * rotateDirection;\n\n return deltaRadian * RAD_TO_DEG;\n }\n\n private _extractPitchFromQuat(quaternion: quat) {\n const baseV = vec3.fromValues(0, 0, 1);\n vec3.transformQuat(baseV, baseV, quaternion);\n\n return -1 * Math.atan2(\n baseV[1],\n Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2)));\n }\n}\n\nexport default GyroInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport GyroInput from \"./input/GyroInput\";\nimport Motion from \"../core/Motion\";\nimport Camera from \"../core/Camera\";\nimport * as BROWSER from \"../const/browser\";\nimport { CONTROL_EVENTS } from \"../const/internal\";\nimport { ControlEvents } from \"../type/internal\";\nimport { sensorCanBeEnabledIOS } from \"../utils\";\n\n/**\n * Options for {@link GyroControl}\n * @ko {@link GyroControl}용 옵션들\n * @since 4.0.0\n */\nexport interface GyroControlOptions {\n /**\n * @copy GyroControl#ignoreRoll\n */\n ignoreRoll: boolean;\n}\n\nexport type GyroControlEvents = ControlEvents;\n\n/**\n * Camera's rotation control by gyroscope\n * @ko 자이로스코프를 이용한 회전 컨트롤\n * @since 4.0.0\n */\nclass GyroControl extends Component implements CameraControl {\n // Options\n private _ignoreRoll: GyroControlOptions[\"ignoreRoll\"];\n\n // Internal values\n private _enableBlocked: boolean;\n private _input: GyroInput;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._input.enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() {\n return this._input.enabled && this._input.orientationUpdated;\n }\n\n /**\n * When `true`, ignore gyroscope's roll(z-axis rotation) value.\n * :::caution\n * Setting `false` will ignore camera's range limit.\n * Options like {@link View360Options#yawRange}, {@link View360Options#pitchRange} are ignored, and {@link CylinderProjection} also can't force it's camera range limit.\n * :::\n * @ko `true`일 경우 자이로스코프 입력의 roll(z축 회전)값을 무시합니다.\n * :::caution\n * 이 값을 `false`로 설정할 경우 카메라 범위 제약을 무시합니다.\n * {@link View360Options#yawRange}, {@link View360Options#pitchRange}와 같은 값은 무시되며, {@link CylinderProjection} 사용시에도 범위를 벗어날 수 있습니다.\n * :::\n * @default true\n * @since 4.0.0\n */\n public get ignoreRoll() { return this._ignoreRoll; }\n public set ignoreRoll(val: GyroControlOptions[\"ignoreRoll\"]) { this._ignoreRoll = val; }\n\n /**\n * Return availability of the gyroscope.\n * :::caution\n * This will always return false until user permission under environments like iOS which requires user permission when using gyroscope.\n * :::\n * @ko 자이로스코프 사용 가능 여부를 반환합니다.\n * :::caution\n * iOS와 같이 GyroScope 사용시 사용자 Permission을 요구하는 환경에서는 사용자 Permission을 받기 전까지 항상 `false`입니다.\n * :::\n * @example\n * ```ts\n * const gyroAvailable = await GyroControl.isAvailable();\n * ```\n */\n public static async isAvailable(): Promise {\n if (!DeviceMotionEvent) {\n return false;\n }\n\n let onDeviceMotionChange: (evt: DeviceMotionEvent) => void;\n\n const listenDeviceMotion = () => new Promise(res => {\n onDeviceMotionChange = (evt: DeviceMotionEvent) => {\n res(evt.rotationRate && evt.rotationRate.alpha != null);\n };\n\n window.addEventListener(BROWSER.EVENTS.DEVICE_MOTION, onDeviceMotionChange);\n });\n\n const timeout = () => new Promise(res => {\n setTimeout(() => res(false), 1000);\n });\n\n return Promise.race([listenDeviceMotion(), timeout()])\n .then((available: boolean) => {\n window.removeEventListener(BROWSER.EVENTS.DEVICE_MOTION, onDeviceMotionChange);\n\n return available;\n });\n }\n\n /**\n * Request user permission for gyroscope sensor.\n * This can be used in environments like iOS which requires user permission when using gyroscope sensors.\n * @ko 사용자의 sensor permission 취득을 요청합니다.\n * iOS와 같이 gyroscope 사용시 사용자 Permission을 요구하는 환경에서 사용 가능합니다.\n * @returns Whether the permission is granted {@ko 사용자 permission 취득 여부}\n */\n public static async requestSensorPermission(): Promise {\n // Request sensor permission, on iOS13+\n if (sensorCanBeEnabledIOS()) {\n return (DeviceMotionEvent as typeof DeviceMotionEvent & {\n requestPermission: () => Promise;\n }).requestPermission().then(permissionState => {\n return permissionState === \"granted\";\n }).catch(() => false);\n }\n\n return true;\n }\n\n /**\n * Create new GyroControl instance\n * @ko GyroControl의 인스턴스를 생성합니다.\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(enableBlocked: boolean, {\n ignoreRoll = true\n }: Partial = {}) {\n super();\n\n this._enableBlocked = enableBlocked;\n this._ignoreRoll = ignoreRoll;\n this._input = new GyroInput();\n }\n\n /**\n * @copy CameraControl#destroy\n */\n public destroy(): void {\n this.disable();\n this._input.off();\n this.off();\n }\n\n /**\n * @hidden\n */\n public update(camera: Camera, yaw: Motion, pitch: Motion, zoom: number) {\n if (!this._ignoreRoll) {\n this._updateQuaternion(camera, zoom);\n } else {\n this._updateYawPitch(camera, yaw, pitch, zoom);\n }\n }\n\n /**\n * @copy CameraControl#enable\n */\n public enable(): void {\n if (this._input.enabled) return;\n\n this._input.enable();\n this._enableBlocked = false;\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: false });\n }\n\n /**\n * @copy CameraControl#disable\n */\n public disable(): void {\n if (!this._input.enabled) return;\n\n this._input.disable();\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: false });\n }\n\n /**\n * @copy CameraControl#sync\n */\n public sync(): void {} // eslint-disable-line @typescript-eslint/no-empty-function\n\n private _updateYawPitch(camera: Camera, yaw: Motion, pitch: Motion, zoom: number) {\n const input = this._input;\n if (!input.enabled) return;\n\n const {\n yaw: yawDelta,\n pitch: pitchDelta\n } = input.collectDelta();\n\n yaw.add(yawDelta);\n pitch.add(pitchDelta);\n\n camera.lookAt({\n yaw: yaw.val,\n pitch: pitch.val,\n zoom\n });\n }\n\n private _updateQuaternion(camera: Camera, zoom: number) {\n const input = this._input;\n if (!input.enabled) return;\n\n input.update();\n camera.rotate(input.quaternion, zoom);\n }\n}\n\nexport default GyroControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport CameraControl from \"./CameraControl\";\nimport RotateControl, { RotateControlEvents, RotateControlOptions } from \"./RotateControl\";\nimport ZoomControl, { ZoomControlOptions } from \"./ZoomControl\";\nimport GyroControl, { GyroControlOptions } from \"./GyroControl\";\nimport Camera from \"../core/Camera\";\nimport CameraAnimation from \"../core/CameraAnimation\";\nimport * as BROWSER from \"../const/browser\";\nimport { CAMERA_EVENTS, CONTROL_EVENTS } from \"../const/internal\";\nimport { ValueOf } from \"../type/utils\";\nimport { getObjectOption, hfovToZoom } from \"../utils\";\n\n/**\n * Options for {@link PanoControl}\n * @ko {@link PanoControl}용 옵션들\n * @since 4.0.0\n */\nexport interface PanoControlOptions {\n /**\n * @copy View360#useGrabCursor\n */\n useGrabCursor: boolean;\n /**\n * @copy View360#scrollable\n */\n scrollable: boolean;\n /**\n * @copy View360#wheelScrollable\n */\n wheelScrollable: boolean;\n /**\n * @copy View360#disableContextMenu\n */\n disableContextMenu: boolean;\n /**\n * Options for {@link RotateControl}.\n * `false` to disable rotation.\n * @ko {@link RotateControl}용 옵션들.\n * `false`일 경우 회전이 비활성화됩니다.\n * @since 4.0.0\n */\n rotate: boolean | Partial;\n /**\n * Options for {@link ZoomControl}.\n * `false` to disable zoom.\n * @ko {@link ZoomControl}용 옵션들.\n * `false`일 경우 줌이 비활성화됩니다.\n * @since 4.0.0\n */\n zoom: boolean | Partial;\n /**\n * Options for {@link GyroControl}.\n * `false` to disable gyroscope control.\n * @ko {@link GyroControl}용 옵션들.\n * `false`일 경우 자이로스코프를 통한 컨트롤이 비활성화됩니다.\n * @since 4.0.0\n */\n gyro: boolean | Partial;\n}\n\n/**\n * Panorama control for View360\n * @ko View360용 파노라마 컨트롤\n * @since 4.0.0\n */\nclass PanoControl {\n // Options\n private _useGrabCursor: PanoControlOptions[\"useGrabCursor\"];\n private _disableContextMenu: PanoControlOptions[\"disableContextMenu\"];\n\n // Internal Values\n private _camera: Camera;\n private _controlEl: HTMLElement;\n private _rotateControl: RotateControl;\n private _zoomControl: ZoomControl;\n private _gyroControl: GyroControl;\n private _ignoreZoomScale: boolean;\n private _enabled: boolean;\n\n /**\n * @copy View360#useGrabCursor\n */\n public get useGrabCursor() { return this._useGrabCursor; }\n public set useGrabCursor(val: PanoControlOptions[\"useGrabCursor\"]) {\n if (val === this._useGrabCursor) return;\n\n this._useGrabCursor = val;\n\n if (val && this._enabled) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n } else if (!val) {\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n }\n\n /**\n * @copy View360#disableContextMenu\n */\n public get disableContextMenu() { return this._disableContextMenu; }\n public set disableContextMenu(val: PanoControlOptions[\"disableContextMenu\"]) {\n if (val === this._disableContextMenu) return;\n\n this._disableContextMenu = val;\n\n if (val && this._enabled) {\n this._blockContextMenu();\n } else if (!val) {\n this._restoreContextMenu();\n }\n }\n\n /**\n * @copy View360#disableContextMenu\n */\n public get scrollable() { return this._rotateControl.scrollable; }\n public set scrollable(val: PanoControlOptions[\"scrollable\"]) { this._rotateControl.scrollable = val; }\n /**\n * @copy View360#disableContextMenu\n */\n public get wheelScrollable() { return this._zoomControl.scrollable; }\n public set wheelScrollable(val: PanoControlOptions[\"wheelScrollable\"]) { this._zoomControl.scrollable = val; }\n /**\n * When `true`, disables rotation slow-down by zoom-value.\n * @ko `true`일 경우 줌 된 정도에 따라 회전속도를 늦추는 동작을 비활성화합니다.\n * @since 4.0.0\n */\n public get ignoreZoomScale() { return this._ignoreZoomScale; }\n public set ignoreZoomScale(val: boolean) { this._ignoreZoomScale = val; }\n\n /**\n * Whether the control is enabled or not\n * @ko 컨트롤 활성화 여부를 가리키는 값\n * @readonly\n * @since 4.0.0\n */\n public get enabled() { return this._enabled; }\n /**\n * @copy View360#rotate\n */\n public get rotate() { return this._rotateControl; }\n /**\n * @copy View360#zoom\n */\n public get zoom() { return this._zoomControl; }\n /**\n * @copy View360#gyro\n */\n public get gyro() { return this._gyroControl; }\n\n /**\n * Whether one of the controls is animating at the moment\n * @ko 현재 컨트롤 중 하나라도 동작중인지 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get animating() {\n return this._rotateControl.animating\n || this._zoomControl.animating\n || this._gyroControl.animating;\n }\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param element - Canvas element {@ko 캔버스 엘리먼트}\n * @param camera - Camera instance {@ko Camera 인스턴스}\n * @param options - Options for PanoControl {@ko PanoControl 옵션들}\n */\n public constructor(element: HTMLElement, camera: Camera, {\n useGrabCursor,\n scrollable,\n wheelScrollable,\n disableContextMenu,\n rotate,\n zoom,\n gyro\n }: PanoControlOptions) {\n // Bind Options\n this._useGrabCursor = useGrabCursor;\n this._disableContextMenu = disableContextMenu;\n\n // Set internal values\n this._camera = camera;\n this._controlEl = element;\n this._ignoreZoomScale = false;\n this._enabled = false;\n\n this._rotateControl = new RotateControl(element, !rotate, getObjectOption(rotate));\n this._zoomControl = new ZoomControl(element, !zoom, getObjectOption(zoom));\n this._gyroControl = new GyroControl(!gyro, getObjectOption(gyro));\n\n this._rotateControl.scrollable = scrollable;\n this._zoomControl.scrollable = wheelScrollable;\n\n this._bindEvents();\n }\n\n /**\n * Destroy the instance and remove all event listeners attached.\n * This also will reset CSS cursor to initial.\n * @ko 인스턴스를 삭제하고 부착된 모든 이벤트 리스너를 제거합니다.\n * 또한, 캔버스에 적용된 CSS cursor도 제거합니다.\n * @since 4.0.0\n */\n public destroy(): void {\n this.disable();\n this._rotateControl.destroy();\n this._zoomControl.destroy();\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n\n /**\n * Resize control to match target size.\n * @ko 컨트롤이 내부에 캐시하고 있는 크기값을 갱신합니다.\n * @param width New width {@ko 변경된 너비}\n * @param height New height {@ko 변경된 높이}\n * @since 4.0.0\n */\n public resize(width: number, height: number): void {\n const camera = this._camera;\n\n this._rotateControl.resize(camera.fov, camera.aspect, width, height);\n }\n\n /**\n * Enable this control and add event listeners.\n * @ko 컨트롤을 활성화하고 이벤트 리스너들을 추가합니다.\n * @since 4.0.0\n */\n public async enable(): Promise {\n if (this._enabled) return;\n\n if (!this._rotateControl.enableBlocked) {\n this._rotateControl.enable();\n }\n\n if (!this._zoomControl.enableBlocked) {\n this._zoomControl.enable();\n }\n\n if (!this._gyroControl.enableBlocked) {\n if (await GyroControl.isAvailable()) {\n this._gyroControl.enable();\n }\n }\n\n this.sync();\n\n if (this._disableContextMenu) {\n this._blockContextMenu();\n }\n\n this._enabled = true;\n }\n\n /**\n * Disable this control and remove all event listeners\n * @ko 컨트롤을 비활성화하고 모든 이벤트 리스너들을 제거합니다.\n * @since 4.0.0\n */\n public disable(): void {\n if (!this._enabled) return;\n\n this._rotateControl.disable();\n this._zoomControl.disable();\n this._gyroControl.disable();\n\n this._restoreContextMenu();\n\n this._enabled = false;\n }\n\n /**\n * Update control by given deltaTime\n * @ko 컨트롤을 주어진 시간만큼 업데이트합니다.\n * @param delta Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n * @internal\n */\n public update(delta: number): void {\n const camera = this._camera;\n const rotateControl = this._rotateControl;\n const zoomControl = this._zoomControl;\n const gyroControl = this._gyroControl;\n\n zoomControl.update(delta);\n const zoom = hfovToZoom(camera.fov, zoomControl.zoom);\n\n // Slow down rotation on zoom-in\n const zoomScale = this._ignoreZoomScale ? 1 : Math.max(zoom, 1);\n rotateControl.setZoomScale(zoomScale);\n rotateControl.updateRange(camera, zoom);\n rotateControl.update(delta);\n\n const yaw = rotateControl.yaw;\n const pitch = rotateControl.pitch;\n\n if (gyroControl.enabled) {\n gyroControl.update(camera, yaw, pitch, zoom);\n } else {\n camera.lookAt({\n yaw: yaw.val,\n pitch: pitch.val,\n zoom\n });\n }\n }\n\n /**\n * Synchronize this control's state to current camera state\n * @ko 컨트롤을 카메라의 현재 상태와 동기화합니다.\n * @since 4.0.0\n */\n public sync(): void {\n const camera = this._camera;\n\n this._zoomControl.sync(camera);\n this._rotateControl.sync(camera);\n }\n\n private _blockContextMenu() {\n const el = this._controlEl;\n\n el.addEventListener(BROWSER.EVENTS.CONTEXT_MENU, this._preventContextMenu);\n }\n\n private _restoreContextMenu() {\n const el = this._controlEl;\n\n el.removeEventListener(BROWSER.EVENTS.CONTEXT_MENU, this._preventContextMenu);\n }\n\n private _preventContextMenu = (evt: MouseEvent) => {\n evt.preventDefault();\n };\n\n private _setCursor(newCursor: ValueOf) {\n if (!this._useGrabCursor && newCursor !== BROWSER.CURSOR.NONE) return;\n\n const targetEl = this._controlEl;\n targetEl.style.cursor = newCursor;\n }\n\n private _bindEvents() {\n const rotateControl = this._rotateControl;\n const zoomControl = this._zoomControl;\n\n rotateControl.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n rotateControl.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n rotateControl.on(CONTROL_EVENTS.ENABLE, this._onEnable);\n rotateControl.on(CONTROL_EVENTS.DISABLE, this._onDisable);\n zoomControl.on(CONTROL_EVENTS.ENABLE, this._onEnable);\n zoomControl.on(CONTROL_EVENTS.DISABLE, this._onDisable);\n this._camera.on(CAMERA_EVENTS.ANIMATION_END, this._onCameraAnimationEnd);\n }\n\n private _onInputStart = (evt: RotateControlEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n if (this._useGrabCursor && !evt.isKeyboard) {\n this._setCursor(BROWSER.CURSOR.GRABBING);\n }\n };\n\n private _onInputEnd = (evt: RotateControlEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n if (this._useGrabCursor && !evt.isKeyboard) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n }\n };\n\n private _onEnable = ({\n control,\n updateCursor\n }: {\n control: CameraControl;\n updateCursor: boolean;\n }) => {\n if (updateCursor && this._useGrabCursor) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n }\n\n control.sync(this._camera);\n };\n\n private _onDisable = ({\n updateCursor\n }: {\n updateCursor: boolean\n }) => {\n if (updateCursor) {\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n };\n\n private _onCameraAnimationEnd = ({ animation }: { animation: CameraAnimation }) => {\n animation.getFinishPromise().then(() => {\n this.sync();\n });\n };\n}\n\nexport default PanoControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport TextureVideo from \"./TextureVideo\";\nimport TextureCube from \"./TextureCube\";\n\n/**\n * @hidden\n */\nabstract class Texture {\n public width: number;\n public height: number;\n public flipY: boolean;\n public wrapS: number;\n public wrapT: number;\n\n public constructor({\n width,\n height,\n flipY\n }: {\n width: number;\n height: number;\n flipY: boolean;\n }) {\n this.width = width;\n this.height = height;\n this.flipY = flipY;\n this.wrapS = WebGLRenderingContext.CLAMP_TO_EDGE;\n this.wrapT = WebGLRenderingContext.CLAMP_TO_EDGE;\n }\n\n public destroy() {\n // DO_NOTHING\n }\n\n public isVideo(): this is TextureVideo {\n return false;\n }\n\n public isCube(): this is TextureCube {\n return false;\n }\n}\n\nexport default Texture;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture from \"./Texture\";\n\n/**\n * @hidden\n */\nclass Texture2D extends Texture {\n public source: Exclude;\n\n public constructor({\n source,\n width,\n height,\n flipY\n }: {\n source: Exclude;\n width: number;\n height: number;\n flipY: boolean;\n }) {\n super({\n width,\n height,\n flipY\n });\n\n this.source = source;\n }\n}\n\nexport default Texture2D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"./Texture2D\";\n\n/**\n * @hidden\n */\nclass TextureVideo extends Texture2D {\n public source: HTMLVideoElement;\n\n public destroy() {\n const video = this.source;\n\n video.pause();\n video.removeAttribute(\"src\");\n video.load();\n }\n\n public isVideo(): this is TextureVideo { return true; }\n\n public isPaused() {\n const video = this.source;\n\n return video.paused || video.ended || video.readyState <= 2;\n }\n\n public hasAudio() {\n const video = this.source as any;\n\n if (video.audioTracks) {\n return video.audioTracks.length > 0;\n }\n\n if (video.webkitAudioDecodedByteCount != null) {\n return video.webkitAudioDecodedByteCount > 0;\n }\n\n if (video.mozHasAudio != null) {\n return video.mozHasAudio;\n }\n\n // We don't know whether the video has audio or not, return true\n return true;\n }\n}\n\nexport default TextureVideo;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture from \"./Texture\";\n\n/**\n * @hidden\n */\nclass TextureCube extends Texture {\n public sources: TexImageSource[];\n\n public constructor({\n sources,\n width,\n height,\n flipY\n }: {\n sources: TexImageSource[];\n width: number;\n height: number;\n flipY: boolean;\n }) {\n super({\n width,\n height,\n flipY\n });\n\n this.sources = sources;\n }\n\n public isCube(): this is TextureCube { return true; }\n}\n\nexport default TextureCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ImReady from \"@egjs/imready\";\nimport Texture from \"../texture/Texture\";\nimport Texture2D from \"../texture/Texture2D\";\nimport TextureVideo from \"../texture/TextureVideo\";\nimport TextureCube from \"../texture/TextureCube\";\nimport { getObjectOption, isString } from \"../utils\";\nimport { VideoConfig } from \"../type/external\";\nimport { ProjectionOptions } from \"../projection/Projection\";\n\n/**\n * @hidden\n */\nclass TextureLoader {\n private _loadChecker: ImReady;\n\n constructor() {\n this._loadChecker = new ImReady();\n }\n\n public async load(src: ProjectionOptions[\"src\"], video: ProjectionOptions[\"video\"]): Promise {\n if (video) {\n return this.loadVideo(src, getObjectOption(video));\n } else {\n if (Array.isArray(src) && src.length > 1) {\n return this.loadCubeImage(src);\n } else {\n const imgSrc = Array.isArray(src) ? src[0] : src;\n return this.loadImage(imgSrc);\n }\n }\n }\n\n public async loadImage(src: string | HTMLElement): Promise {\n const images = this._toImageArray(src);\n\n return this._load(images, resolve => {\n const image = images[0];\n\n resolve(new Texture2D({\n source: image,\n width: image.naturalWidth,\n height: image.naturalHeight,\n flipY: true\n }));\n });\n }\n\n public async loadCubeImage(src: Array): Promise {\n const images = this._toImageArray(src);\n\n return this._load(images, resolve => {\n resolve(new TextureCube({\n sources: images,\n width: images[0].naturalWidth,\n height: images[0].naturalHeight,\n flipY: false\n }));\n });\n }\n\n public async loadVideo(src: ProjectionOptions[\"src\"], videoConfig: Partial): Promise {\n const config: VideoConfig = {\n autoplay: true,\n muted: true,\n loop: false,\n volume: 1,\n ...videoConfig,\n };\n const video = this._toVideoElement(src, config);\n\n return this._load([video], resolve => {\n const { autoplay, muted } = config;\n\n video.currentTime = 0;\n if (autoplay && muted) {\n video.play().catch(() => void 0);\n }\n\n resolve(new TextureVideo({\n source: video,\n width: video.videoWidth,\n height: video.videoHeight,\n flipY: true\n }));\n });\n }\n\n private _load(content: HTMLElement[], onLoad: (resolve: (value: T) => void) => void): Promise {\n const loader = this._loadChecker;\n\n return new Promise((resolve, reject) => {\n loader.once(\"ready\", evt => {\n if (evt.errorCount > 0) return;\n\n onLoad(resolve);\n });\n\n loader.once(\"error\", reject);\n loader.check(content);\n });\n }\n\n private _toImageArray(src: ProjectionOptions[\"src\"]): HTMLImageElement[] {\n const srcs = Array.isArray(src) ? src : [src];\n\n return srcs.map(source => {\n if (isString(source)) {\n const imgEl = new Image();\n\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = source;\n\n return imgEl;\n } else {\n return source as HTMLImageElement;\n }\n });\n }\n\n private _toVideoElement(src: ProjectionOptions[\"src\"], {\n muted,\n loop,\n volume\n }: VideoConfig): HTMLVideoElement {\n if (src instanceof HTMLVideoElement) {\n return src;\n }\n\n const video = document.createElement(\"video\");\n\n video.crossOrigin = \"anonymous\";\n video.playsInline = true;\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.muted = muted;\n video.volume = volume;\n video.loop = loop;\n\n if (Array.isArray(src)) {\n src.forEach(source => this._appendSourceElement(video, source));\n } else {\n this._appendSourceElement(video, src);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0 && video.readyState < 1) {\n video.load();\n }\n\n return video;\n }\n\n private _appendSourceElement(video: HTMLMediaElement, src: string | HTMLElement) {\n if (src instanceof HTMLSourceElement) {\n return src;\n }\n\n const sourceEl = document.createElement(\"source\");\n sourceEl.src = src as string;\n video.appendChild(sourceEl);\n }\n}\n\nexport default TextureLoader;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * @internal\n */\nclass FrameAnimator {\n public maxDeltaTime: number;\n\n private _context: Window | XRSession;\n private _rafId: number;\n private _rafTimer: number;\n private _lastUpdateTime: number;\n\n /** */\n public constructor(maxDeltaTime: number, context: Window | XRSession = window) {\n this.maxDeltaTime = maxDeltaTime;\n\n this._context = context;\n this._rafId = -1;\n this._rafTimer = -1;\n this._lastUpdateTime = -1;\n }\n\n public start(callback: (delta: number, ...args: any[]) => any) {\n const context = this._context;\n\n // No context / callback set\n if (!context || !callback) return;\n\n // Animation already started\n if (this._rafId >= 0 || this._rafTimer >= 0) return;\n\n const loop = (_time: number, frame?: XRFrame) => {\n const time = Date.now();\n const delta = Math.min(time - this._lastUpdateTime, this.maxDeltaTime * 1000);\n\n callback(delta, frame);\n\n this._lastUpdateTime = time;\n this._rafId = context.requestAnimationFrame(loop);\n };\n\n this._lastUpdateTime = Date.now();\n this._rafId = context.requestAnimationFrame(loop);\n }\n\n public stop() {\n if (this._rafId >= 0) {\n this._context.cancelAnimationFrame(this._rafId);\n }\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n }\n\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n public changeContext(context: Window | XRSession) {\n this.stop();\n this._context = context;\n }\n}\n\nexport default FrameAnimator;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport * as BROWSER from \"../const/browser\";\n\n/**\n * Automatic resizer that uses both ResizeObserver and window resize event\n */\nclass AutoResizer {\n private _enabled: boolean;\n private _resizeObserver: ResizeObserver | null;\n private _useResizeObserver: boolean;\n private _onResize: () => any;\n\n public get useResizeObserver() { return this._useResizeObserver; }\n\n /**\n * Returns whether AutoResizer is enabled\n */\n public get enabled() { return this._enabled; }\n\n /** */\n public constructor(useResizeObserver: boolean, onResize: () => any) {\n this._useResizeObserver = useResizeObserver;\n\n this._enabled = false;\n this._resizeObserver = null;\n this._onResize = onResize;\n }\n\n /**\n * Enable resizer\n */\n public enable(element: HTMLElement): this {\n if (this._enabled) {\n this.disable();\n }\n\n if (this._useResizeObserver && !!window.ResizeObserver) {\n const bbox = element.getBoundingClientRect();\n const resizeImmediate = bbox.width !== 0 || bbox.height !== 0;\n\n const resizeObserver = new ResizeObserver(resizeImmediate ? this._skipFirstResize : this._onResize);\n\n resizeObserver.observe(element);\n\n this._resizeObserver = resizeObserver;\n } else {\n window.addEventListener(BROWSER.EVENTS.RESIZE, this._onResize);\n }\n\n this._enabled = true;\n\n return this;\n }\n\n /**\n * Disable resizer\n */\n public disable(): this {\n if (!this._enabled) return this;\n\n const resizeObserver = this._resizeObserver;\n if (resizeObserver) {\n resizeObserver.disconnect();\n this._resizeObserver = null;\n } else {\n window.removeEventListener(BROWSER.EVENTS.RESIZE, this._onResize);\n }\n\n this._enabled = false;\n\n return this;\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n private _skipFirstResize = (() => {\n let isFirstResize = true;\n\n return (() => {\n if (isFirstResize) {\n isFirstResize = false;\n\n return;\n }\n this._onResize();\n });\n })();\n}\n\nexport default AutoResizer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Camera from \"./Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport View360 from \"../View360\";\nimport * as BROWSER from \"../const/browser\";\nimport { CONTROL_EVENTS } from \"../const/internal\";\nimport { circulate, getObjectOption } from \"../utils\";\n\n/**\n * Options for {@link Autoplay}\n * @ko {@link Autoplay}용 옵션들\n * @since 4.0.0\n */\nexport interface AutoplayOptions {\n /**\n * @copy Autoplay#delay\n */\n delay: number;\n /**\n * @copy Autoplay#delayOnMouseLeave\n */\n delayOnMouseLeave: number;\n /**\n * @copy Autoplay#speed\n */\n speed: number;\n /**\n * @copy Autoplay#pauseOnHover\n */\n pauseOnHover: boolean;\n /**\n * @copy Autoplay#canInterrupt\n */\n canInterrupt: boolean;\n /**\n * @copy Autoplay#disableOnInterrupt\n */\n disableOnInterrupt: boolean;\n}\n\n/**\n * A manager class for autoplay feature.\n * @ko Autoplay 기능의 매니저 클래스.\n * @since 4.0.0\n */\nclass Autoplay {\n // Options\n private _delay: number;\n private _delayOnMouseLeave: number;\n private _speed: number;\n private _pauseOnHover: boolean;\n private _canInterrupt: boolean;\n private _disableOnInterrupt: boolean;\n\n // Internal values\n private _enableBlocked: boolean;\n private _camera: Camera;\n private _control: PanoControl;\n private _element: HTMLElement;\n private _enabled: boolean;\n private _interrupted: boolean;\n private _interruptionTimer: number;\n private _hovering: boolean;\n\n /**\n * Whether autoplay is enabled or not\n * @ko 자동재생 활성화 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * Whether autoplay is updating the camera at the moment\n * @ko 현재 자동재생이 동작중인지 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get playing() {\n return this._enabled && !this._interrupted;\n }\n\n /**\n * Reactivation delay after mouse input in milisecond.\n * @ko 재활성화되기까지의 시간 (밀리초 단위)\n * @default 2000\n * @since 4.0.0\n */\n public get delay() { return this._delay; }\n public set delay(val: number) { this._delay = val; }\n\n /**\n * Reactivation delay after mouse leave when using {@link AutoplayOptions#pauseOnHover}\n * @ko {@link AutoplayOptions#pauseOnHover} 사용시 마우스가 캔버스 영역을 떠난 뒤 자동재생이 다시 활성화되기까지의 시간\n * @default 0\n * @since 4.0.0\n */\n public get delayOnMouseLeave() { return this._delayOnMouseLeave; }\n public set delayOnMouseLeave(val: number) { this._delayOnMouseLeave = val; }\n\n /**\n * Y-axis(yaw) rotation speed\n * @ko Y-축 회전(yaw)의 속도\n * @default 1\n * @since 4.0.0\n */\n public get speed() { return this._speed; }\n public set speed(val: number) { this._speed = val; }\n\n /**\n * Whether to pause rotation on mouse hover\n * @ko 마우스가 캔버스 영역에 들어왔을 때 자동재생을 정지할지 여부\n * @default false\n * @since 4.0.0\n */\n public get pauseOnHover() { return this._pauseOnHover; }\n public set pauseOnHover(val: boolean) { this._pauseOnHover = val; }\n\n /**\n * Whether user can interrupt the rotation with click/wheel input\n * @ko 클릭이나 휠같은 사용자 인터랙션시 자동재생을 멈출지 여부\n * @default true\n * @since 4.0.0\n */\n public get canInterrupt() { return this._canInterrupt; }\n public set canInterrupt(val: boolean) { this._canInterrupt = val; }\n\n /**\n * Whether to disable autoplay on user interrupt\n * @ko 사용자 동작에 의해 자동재생이 정지할 때, {@link Autoplay#disable}을 호출하여 자동재생을 영구히 정지할지 여부\n * @default false\n * @since 4.0.0\n */\n public get disableOnInterrupt() { return this._disableOnInterrupt; }\n public set disableOnInterrupt(val: boolean) { this._disableOnInterrupt = val; }\n\n /**\n * Create new AutoPlayer instance\n * @param camera - Instance of the {@link Camera} {@ko Camera의 인스턴스}\n * @param element - Canvas element {@ko 캔버스 엘리먼트}\n * @param options - Autoplay options {@ko 자동재생 옵션들}\n * @since 4.0.0\n */\n public constructor(viewer: View360, element: HTMLElement, options: boolean | Partial) {\n this._camera = viewer.camera;\n this._control = viewer.control;\n this._element = element;\n\n this._enabled = false;\n this._interrupted = false;\n this._interruptionTimer = -1;\n this._hovering = false;\n\n const {\n delay = 2000,\n delayOnMouseLeave = 0,\n speed = 1,\n pauseOnHover = false,\n canInterrupt = true,\n disableOnInterrupt = false\n } = getObjectOption(options);\n\n this._enableBlocked = !options;\n this._delay = delay;\n this._delayOnMouseLeave = delayOnMouseLeave;\n this._speed = speed;\n this._pauseOnHover = pauseOnHover;\n this._canInterrupt = canInterrupt;\n this._disableOnInterrupt = disableOnInterrupt;\n }\n\n /**\n * Destroy the instance and remove all event listeners attached\n * @ko 인스턴스를 제거하고 연결된 모든 이벤트 핸들러를 삭제합니다.\n * @since 4.0.0\n */\n public destroy(): void {\n this.disable();\n }\n\n /**\n * Rotate camera by given deltaTime\n * @ko 주어진 deltaTime만큼 카메라를 회전시킵니다.\n * @param deltaTime - Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n */\n public update(deltaTime: number): void {\n if (!this._enabled) return;\n if (this._interrupted) {\n if (this._disableOnInterrupt) {\n this.disable();\n }\n\n return;\n }\n\n const camera = this._camera;\n const delta = -this._speed * deltaTime / 100;\n\n camera.yaw = circulate(camera.yaw + delta, 0, 360);\n }\n\n /**\n * Enable autoplay and add event listeners.\n * @ko 자동재생을 활성화하고 이벤트리스너들을 추가합니다.\n * @since 4.0.0\n */\n public enable(): void {\n const control = this._control;\n const element = this._element;\n\n if (this._enabled || control.gyro.enabled) return;\n\n control.rotate.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.rotate.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.zoom.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.zoom.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.gyro.on(CONTROL_EVENTS.ENABLE, this._onGyroEnable);\n\n element.addEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter, false);\n element.addEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave, false);\n\n this._enabled = true;\n this._enableBlocked = false;\n }\n\n /**\n * Enable autoplay after current `delay` value.\n * @ko 현재의 `delay`값만큼 시간이 지난 다음에 자동재생을 활성화합니다.\n * @since 4.0.0\n */\n public enableAfterDelay() {\n this.enable();\n this._interrupted = true;\n this._setUninterruptedAfterDelay(this._delay);\n }\n\n /**\n * Disable autoplay and remove all event handlers.\n * @ko 자동재생을 비활성화하고 모든 이벤트 핸들러를 제거합니다.\n * @since 4.0.0\n */\n public disable(): void {\n if (!this._enabled) return;\n\n const control = this._control;\n const element = this._element;\n\n control.rotate.off(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.rotate.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.zoom.off(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.zoom.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.gyro.off(CONTROL_EVENTS.ENABLE, this._onGyroEnable);\n\n element.removeEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter, false);\n element.removeEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave, false);\n\n this._enabled = false;\n this._interrupted = false;\n this._hovering = false;\n\n this._clearTimeout();\n }\n\n private _onInputStart = () => {\n if (!this._canInterrupt) return;\n\n this._interrupted = true;\n this._clearTimeout();\n };\n\n private _onInputEnd = () => {\n this._setUninterruptedAfterDelay(this._delay);\n };\n\n private _onGyroEnable = () => {\n this.disable();\n };\n\n private _onMouseEnter = () => {\n if (!this._pauseOnHover) return;\n this._interrupted = true;\n this._hovering = true;\n };\n\n private _onMouseLeave = () => {\n if (!this._pauseOnHover) return;\n this._hovering = false;\n this._setUninterruptedAfterDelay(this._delayOnMouseLeave);\n };\n\n private _setUninterruptedAfterDelay(delay: number): void {\n if (this._hovering) return;\n\n this._clearTimeout();\n\n if (delay > 0) {\n this._interruptionTimer = window.setTimeout(() => {\n this._interrupted = false;\n this._interruptionTimer = -1;\n }, delay);\n } else {\n this._interrupted = false;\n this._interruptionTimer = -1;\n }\n }\n\n private _clearTimeout(): void {\n if (this._interruptionTimer >= 0) {\n window.clearTimeout(this._interruptionTimer);\n this._interruptionTimer = -1;\n }\n }\n}\n\nexport default Autoplay;\n","import { mat4 } from \"gl-matrix\";\nimport Component from \"@egjs/component\";\nimport WebGLContext from \"./WebGLContext\";\nimport GyroControl from \"../control/GyroControl\";\nimport * as BROWSER from \"../const/browser\";\nimport { SESSION_VR, XR_REFERENCE_SPACE } from \"../const/internal\";\nimport { EVENTS } from \"../const/external\";\n\ninterface XRSessionOptions extends XRSessionInit {\n [key: string]: any;\n}\n\n/**\n * WebXR manager class\n * @ko WebXR 매니저 클래스\n * @since 4.0.0\n */\nclass XRManager extends Component<{\n /**\n * An event that fires on entering VR session\n * @ko VR 세션 진입시에 트리거되는 이벤트\n * @eventName vrStart\n * @eventOf XRManager\n * @version 4.0.0\n */\n [EVENTS.VR_START]: {\n session: XRSession;\n };\n /**\n * An event that fires on exiting VR session\n * @ko VR 세션에서 나갈 때 트리거되는 이벤트\n * @eventName vrEnd\n * @eventOf XRManager\n * @version 4.0.0\n */\n [EVENTS.VR_END]: void;\n}> {\n private _ctx: WebGLContext;\n private _xrSession: XRSession | null;\n private _xrRefSpace: XRReferenceSpace | null;\n private _options: XRSessionOptions;\n\n /**\n * Create new instance.\n * 새 인스턴스를 생성합니다.\n * @param ctx - Instance of WebGL context helper {@ko WebGL 콘텍스트 헬퍼의 인스턴스}\n * @param options - Options {@ko 옵션들}\n */\n public constructor(ctx: WebGLContext, options: XRSessionOptions = {}) {\n super();\n\n this._xrSession = null;\n this._xrRefSpace = null;\n this._ctx = ctx;\n this._options = options;\n }\n\n /**\n * Destroy instance and end XR session if there was any.\n * @ko 인스턴스를 제거하고, XR 세션이 존재할 경우 종료합니다.\n * @since 4.0.0\n */\n public destroy = () => {\n this.exit();\n this.off();\n };\n\n /**\n * Returns WebXR availability.\n * @ko WebXR 사용 가능 여부를 반환합니다.\n * @since 4.0.0\n */\n public async isAvailable(): Promise {\n // eslint-disable-next-line compat/compat\n const xr = window.navigator.xr;\n if (!xr) return false;\n\n return xr.isSessionSupported(SESSION_VR)\n .then(available => {\n return available;\n }).catch(() => {\n return false;\n });\n }\n\n /**\n * Enter VR session\n * @ko VR 세션에 진입합니다.\n * @since 4.0.0\n */\n public async enter() {\n const ctx = this._ctx;\n\n // eslint-disable-next-line compat/compat\n const xr = window.navigator.xr;\n if (!xr) return;\n\n await GyroControl.requestSensorPermission();\n\n const options = {\n ...{\n requiredFeatures: [XR_REFERENCE_SPACE]\n },\n ...this._options\n };\n\n await ctx.makeXRCompatible();\n\n const session = await xr.requestSession(SESSION_VR, options);\n ctx.bindXRLayer(session);\n\n const refSpace = await session.requestReferenceSpace(XR_REFERENCE_SPACE);\n\n this._setSession(session, refSpace);\n\n this.trigger(EVENTS.VR_START, {\n session\n });\n }\n\n /**\n * Exit VR session\n * @ko VR 세션에서 나갑니다.\n * @since 4.0.0\n */\n public exit() {\n const xrSession = this._xrSession;\n\n if (xrSession) {\n xrSession.end()\n .catch(() => void 0);\n }\n\n this._xrSession = null;\n this._xrRefSpace = null;\n }\n\n /**\n * @hidden\n */\n public canRender(frame: XRFrame) {\n const refSpace = this._xrRefSpace;\n\n if (!refSpace) return false;\n\n const pose = frame.getViewerPose(refSpace);\n\n return !!pose;\n }\n\n /**\n * @hidden\n */\n public getEyeParams(frame: XRFrame): Array<{\n viewport: XRViewport;\n vMatrix: mat4;\n pMatrix: mat4;\n }> | null {\n const session = frame.session;\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n if (!pose) return null;\n\n const glLayer = session.renderState.baseLayer;\n\n if (!glLayer) return null;\n\n return pose.views.map(view => {\n const viewport = glLayer.getViewport(view)!;\n const vMatrix = view.transform.inverse.matrix;\n\n return {\n viewport,\n vMatrix,\n pMatrix: view.projectionMatrix\n };\n });\n }\n\n private _setSession(session: XRSession, refSpace: XRReferenceSpace) {\n this._xrSession = session;\n this._xrRefSpace = refSpace;\n\n session.addEventListener(BROWSER.EVENTS.XR_END, this._onSessionEnd);\n }\n\n private _onSessionEnd = () => {\n this.exit();\n this.trigger(EVENTS.VR_END);\n }\n}\n\nexport default XRManager;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { vec3 } from \"gl-matrix\";\n\n/**\n * Hotspot data\n * @ko 핫스팟 데이터\n * @since 4.0.0\n */\nclass Hotspot {\n /**\n * HTMLElement of the hotspot\n * @ko 핫스팟의 HTMLElement\n * @since 4.0.0\n */\n public readonly element: HTMLElement;\n /**\n * Position to render hotspot\n * @ko 핫스팟을 렌더링할 위치\n * @since 4.0.0\n */\n public readonly position: vec3;\n\n public constructor(element: HTMLElement, position: vec3) {\n this.element = element;\n this.position = position;\n }\n}\n\nexport default Hotspot;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { vec2, vec3 } from \"gl-matrix\";\nimport Hotspot from \"./Hotspot\";\nimport Camera from \"../core/Camera\";\nimport WebGLRenderer from \"../core/WebGLRenderer\";\nimport View360Error from \"../core/View360Error\";\nimport { getNullableElement } from \"../utils\";\nimport ERROR from \"../const/error\";\nimport { DEFAULT_CLASS } from \"../const/external\";\nimport { DEG_TO_RAD } from \"../const/internal\";\n\n/**\n * Options for {@link HotspotRenderer}\n * @ko {@link HotspotRenderer}용 옵션들\n * @since 4.0.0\n */\nexport interface HotspotOptions {\n /**\n * Apply scale for hotspots, makes their size sync with background panorama image.\n * @ko 핫스팟에 스케일을 적용해서 배경 파노라마 이미지의 크기 변화와 동일하게 크기를 조절합니다.\n * @since 4.0.0\n */\n zoom: boolean;\n}\n\n/**\n * Hotspot renderer\n * @ko Hotspot 렌더러\n * @since 4.0.0\n */\nclass HotspotRenderer {\n // Options\n private _zoom: HotspotOptions[\"zoom\"];\n\n // Internal properties\n private _containerEl: HTMLElement | null;\n private _renderer: WebGLRenderer;\n private _hotspots: Hotspot[];\n\n /**\n * Create new instance\n * @ko 새 인스턴스를 생성합니다.\n * @param rootEl - Container element for hotspots {@ko 핫스팟들의 컨테이너 엘리먼트}\n * @param renderer - instance of WebGLRenderer {@ko WebGLRenderer의 인스턴스}\n * @param options - Hotspot options {@ko Hotspot 옵션들 }\n */\n public constructor(rootEl: HTMLElement, renderer: WebGLRenderer, {\n zoom = false\n }: Partial) {\n this._containerEl = getNullableElement(`.${DEFAULT_CLASS.HOTSPOT_CONTAINER}`, rootEl);\n this._renderer = renderer;\n this._hotspots = [];\n\n this._zoom = zoom;\n }\n\n /**\n * Refresh hotspots by collecting hotspot elements from current hotspot root element\n * @ko 현재 핫스팟 루트 엘리먼트 내에서 핫스팟 엘리먼트들을 수집하여 갱신합니다.\n * @throws {ERROR_CODES.INSUFFICIENT_ARGS} if data-position doesn't include all x, y, z values {@ko data-position이 x, y, z좌표를 전부 포함하고 있지 않을 때}\n */\n public refresh() {\n const container = this._containerEl;\n if (!container) return;\n\n const hotspotEls = [].slice.apply(container.querySelectorAll(`.${DEFAULT_CLASS.HOTSPOT}`)) as HTMLElement[];\n this._hotspots = hotspotEls.map(el => this._parseHotspot(el));\n }\n\n /**\n * Render hotspots\n * @ko 핫스팟들을 렌더링합니다.\n * @param camera - Instance of Camera {@ko Camera의 인스턴스}\n */\n public render(camera: Camera) {\n const hotspots = this._hotspots;\n const halfWidth = this._renderer.width * 0.5;\n const halfHeight = this._renderer.height * 0.5;\n const zoom = camera.zoom;\n const centerTransform = \"translate(-50%, -50%)\";\n const zoomTransform = this._zoom ? `scale(${zoom})` : \"\";\n\n hotspots.forEach(hotspot => {\n const position = hotspot.position;\n const relPos = vec3.create();\n\n vec3.copy(relPos, position);\n vec3.transformMat4(relPos, relPos, camera.viewMatrix);\n vec3.transformMat4(relPos, relPos, camera.projectionMatrix);\n\n if (relPos[2] > 1 || relPos[2] < 0) {\n hotspot.element.classList.remove(DEFAULT_CLASS.HOTSPOT_VISIBLE);\n return;\n }\n\n const screenPos = vec2.fromValues(\n relPos[0] * halfWidth + halfWidth,\n -relPos[1] * halfHeight + halfHeight\n );\n\n hotspot.element.classList.add(DEFAULT_CLASS.HOTSPOT_VISIBLE);\n hotspot.element.style.transform = [\n centerTransform,\n `translate(${screenPos[0]}px, ${screenPos[1]}px)`,\n zoomTransform\n ].join(\" \");\n });\n }\n\n private _parseHotspot(element: HTMLElement): Hotspot {\n const yawStr = element.dataset.yaw;\n const pitchStr = element.dataset.pitch;\n const positionStr = element.dataset.position;\n\n if (yawStr || pitchStr) {\n const yaw = yawStr ? parseFloat(yawStr) : 0;\n const pitch = pitchStr ? parseFloat(pitchStr) : 0;\n\n const position = this._yawPitchToVec3(yaw, pitch);\n\n return new Hotspot(element, position);\n } else if (positionStr) {\n const pos: number[] = positionStr.split(\" \").map(val => parseFloat(val));\n if (pos.length < 3) {\n throw new View360Error(ERROR.MESSAGES.INSUFFICIENT_ARGS(positionStr, \"hotspot attribute \\\"data-position\\\"\"), ERROR.CODES.INSUFFICIENT_ARGS);\n }\n\n return new Hotspot(element, vec3.fromValues(pos[0], pos[1], pos[2]));\n } else {\n // Place hotspot at yaw: 0, pitch: 0\n const defaultPos = vec3.fromValues(0, 0, -1);\n\n return new Hotspot(element, defaultPos);\n }\n }\n\n private _yawPitchToVec3(yaw: number, pitch: number) {\n const yawRad = yaw * DEG_TO_RAD;\n const pitchRad = pitch * DEG_TO_RAD;\n const position = vec3.create();\n\n position[1] = Math.sin(pitchRad);\n position[2] = Math.cos(pitchRad);\n\n position[0] = position[2] * Math.sin(-yawRad);\n position[2] = -position[2] * Math.cos(-yawRad);\n\n return position;\n }\n}\n\nexport default HotspotRenderer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"../geometry/Geometry\";\nimport { VAO } from \"../type/internal\";\n\n/**\n * @hidden\n */\nclass VertexArrayObject {\n public readonly obj: VAO | null;\n public readonly geometry: Geometry;\n public readonly buffers: {\n indicies: WebGLBuffer;\n position: WebGLBuffer;\n uv: WebGLBuffer;\n }\n\n public get count() { return this.geometry.indicies.count; }\n\n constructor(obj: VAO | null, geometry: Geometry, buffers: VertexArrayObject[\"buffers\"]) {\n this.obj = obj;\n this.geometry = geometry;\n this.buffers = buffers;\n }\n}\n\nexport default VertexArrayObject;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4 } from \"gl-matrix\";\nimport Uniform from \"../uniform/Uniform\";\nimport Camera from \"./Camera\";\nimport Object3D from \"./Object3D\";\nimport ShaderProgram from \"./ShaderProgram\";\nimport View360Error from \"./View360Error\";\nimport VertexArrayObject from \"./VertexArrayObject\";\nimport VertexData from \"./VertexData\";\nimport Texture from \"../texture/Texture\";\nimport Geometry from \"../geometry/Geometry\";\nimport * as BROWSER from \"../const/browser\";\nimport ERROR from \"../const/error\";\nimport { DEFAULT_CLASS } from \"../const/external\";\nimport { UniformLocations } from \"../type/internal\";\n\n/**\n * @hidden\n */\nclass WebGLContext {\n private _canvas: HTMLCanvasElement;\n private _gl: WebGLRenderingContext | WebGL2RenderingContext;\n private _contextLost: boolean;\n private _maxTextureSize: number;\n private _isWebGL2: boolean;\n private _debug: boolean;\n private _extensions: {\n vao: OES_vertex_array_object | null;\n loseContext: WEBGL_lose_context | null;\n };\n\n public get canvas() { return this._canvas; }\n public get maxTextureSize() { return this._maxTextureSize; }\n public get isWebGL2() { return this._isWebGL2; }\n public get supportVAO() { return this._isWebGL2 || !!this._extensions.vao; }\n public get lost() { return this._contextLost; }\n public get debug() { return this._debug; }\n\n public constructor(canvas: HTMLCanvasElement, debug: boolean) {\n this._canvas = canvas;\n this._contextLost = false;\n this._debug = debug;\n this._extensions = {\n vao: null,\n loseContext: null\n };\n }\n\n public init() {\n const canvas = this._canvas;\n\n const { gl, isWebGL2 } = this._getContext(canvas);\n\n this._gl = gl;\n this._maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n this._isWebGL2 = isWebGL2;\n\n if (!this._isWebGL2) {\n this._extensions.vao = gl.getExtension(\"OES_vertex_array_object\");\n }\n\n this._extensions.loseContext = gl.getExtension(\"WEBGL_lose_context\");\n\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_LOST, this._onContextLost);\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_RESTORED, this._onContextRestore);\n\n // gl.enable(gl.DEPTH_TEST);\n }\n\n public destroy() {\n const gl = this._gl;\n const canvas = this._canvas;\n\n if (gl) {\n // gl is not defined when destroy is called before init\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n }\n\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_LOST, this._onContextLost);\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_RESTORED, this._onContextRestore);\n }\n\n public forceLoseContext() {\n const extension = this._extensions.loseContext;\n\n if (!extension) return;\n\n extension.loseContext();\n }\n\n public forceRestoreContext() {\n const extension = this._extensions.loseContext;\n\n if (!extension) return;\n\n extension.restoreContext();\n }\n\n public clear() {\n const gl = this._gl;\n\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n\n public resize() {\n const gl = this._gl;\n\n gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n }\n\n public viewport(x: number, y: number, width: number, height: number) {\n const gl = this._gl;\n\n gl.viewport(x, y, width, height);\n }\n\n public createVAO(geometry: Geometry, shaderProgram: ShaderProgram) {\n const nativeVAO = this._createNativeVAO();\n\n const vao = new VertexArrayObject(nativeVAO, geometry, {\n indicies: this._createBuffer(),\n position: this._createBuffer(),\n uv: this._createBuffer()\n });\n\n if (nativeVAO) {\n this._bindNativeVAO(nativeVAO);\n this._supplyGeometryData(vao, shaderProgram);\n this._bindNativeVAO(null);\n this._unbindBuffers();\n }\n\n return vao;\n }\n\n public draw(vao: VertexArrayObject, shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n if (vao.obj) {\n this._bindNativeVAO(vao.obj);\n } else {\n this._supplyGeometryData(vao, shaderProgram);\n }\n\n gl.drawElements(gl.TRIANGLES, vao.count, gl.UNSIGNED_SHORT, 0);\n\n if (vao.obj) {\n this._bindNativeVAO(null);\n } else {\n this._unbindBuffers();\n }\n }\n\n public releaseVAO(vao: VertexArrayObject) {\n if (vao.obj) {\n this._deleteNativeVAO(vao.obj);\n }\n\n this._deleteBuffer(vao.buffers.indicies);\n this._deleteBuffer(vao.buffers.position);\n this._deleteBuffer(vao.buffers.uv);\n }\n\n public getUniformLocations>(program: WebGLProgram, uniforms: T): UniformLocations {\n const gl = this._gl;\n\n const uniformLocations = Object.keys(uniforms).reduce((locations, key) => {\n locations[key as keyof T] = gl.getUniformLocation(program, key)!;\n\n return locations;\n }, {} as UniformLocations);\n\n return {\n ...this._getCommonUniformLocations(program),\n ...uniformLocations\n };\n }\n\n public updateCommonUniforms(entity: Object3D, camera: Camera, shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniformLocations = shaderProgram.uniformLocations;\n\n // We're using \"matrix\"(=local matrix) here for efficiency\n // As projection doesn't require world matrix, as it doesn't have any parent or child\n const matrix = entity.matrix;\n const mvMatrix = mat4.create();\n mat4.multiply(mvMatrix, camera.viewMatrix, matrix);\n\n gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix);\n gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, camera.projectionMatrix);\n }\n\n public updateVRUniforms(shaderProgram: ShaderProgram, mvMatrix: mat4, pMatrix: mat4, eyeIndex: number) {\n const gl = this._gl;\n\n const uniformLocations = shaderProgram.uniformLocations;\n\n gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix);\n gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, pMatrix);\n\n if (uniformLocations.uEye) {\n gl.uniform1f(uniformLocations.uEye, eyeIndex);\n }\n }\n\n public updateUniforms(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniforms = shaderProgram.uniforms;\n const uniformLocations = shaderProgram.uniformLocations;\n\n for (const key in uniforms) {\n const uniform = uniforms[key];\n const location = uniformLocations[key];\n\n if (!uniform) continue;\n\n if (uniform.needsUpdate) {\n uniform.update(gl, location, this._isWebGL2);\n }\n }\n }\n\n public releaseShaderResources(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniforms = shaderProgram.uniforms;\n\n for (const key in uniforms) {\n const uniform = uniforms[key];\n\n if (!uniform) continue;\n\n if (uniform.needsUpdate) {\n uniform.destroy(gl);\n }\n }\n\n gl.deleteProgram(shaderProgram.program);\n }\n\n public useProgram(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n gl.useProgram(shaderProgram.program);\n }\n\n public createProgram(vertexShader: string, fragmentShader: string) {\n const gl = this._gl;\n const program = gl.createProgram()!;\n\n const vs = this._compileShader(gl.VERTEX_SHADER, vertexShader);\n const fs = this._compileShader(gl.FRAGMENT_SHADER, fragmentShader);\n\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.bindAttribLocation(program, 0, \"position\");\n gl.bindAttribLocation(program, 1, \"uv\");\n gl.linkProgram(program);\n\n if (this._debug && !gl.getProgramParameter(program, gl.LINK_STATUS)) {\n let shaderLog: string | null = null;\n\n if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {\n shaderLog = gl.getShaderInfoLog(vs);\n } else if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {\n shaderLog = gl.getShaderInfoLog(fs);\n }\n\n throw new View360Error(ERROR.MESSAGES.FAILED_LINKING_PROGRAM(gl.getProgramInfoLog(program), shaderLog), ERROR.CODES.FAILED_LINKING_PROGRAM);\n }\n\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n\n return program;\n }\n\n public createWebGLTexture(texData: Texture): WebGLTexture {\n const gl = this._gl;\n const texture = gl.createTexture()!;\n\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texData.wrapS);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texData.wrapT);\n\n if (!texData.isVideo() && this._isWebGL2) {\n const gl2 = gl as WebGL2RenderingContext;\n\n gl2.texStorage2D(gl2.TEXTURE_2D, 1, gl2.RGBA8, texData.width, texData.height);\n }\n\n return texture;\n }\n\n public createWebGLCubeTexture(texData: Texture, size: number): WebGLTexture {\n const gl = this._gl;\n const texture = gl.createTexture()!;\n\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, texData.wrapS);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, texData.wrapT);\n\n if (this._isWebGL2) {\n const gl2 = gl as WebGL2RenderingContext;\n\n gl2.texStorage2D(gl2.TEXTURE_CUBE_MAP, 1, gl2.RGBA8, size, size);\n }\n\n return texture;\n }\n\n public async makeXRCompatible() {\n const gl = this._gl;\n const attributes = gl.getContextAttributes();\n\n if (attributes && attributes.xrCompatible !== true) {\n await gl.makeXRCompatible();\n }\n }\n\n public bindXRLayer(session: XRSession) {\n const gl = this._gl;\n const xrLayer = new XRWebGLLayer(session, gl);\n session.updateRenderState({ baseLayer: xrLayer });\n }\n\n public bindXRFrame(frame: XRFrame) {\n const gl = this._gl;\n const session = frame.session;\n const baseLayer = session.renderState.baseLayer!;\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer);\n }\n\n public useDefaultFrameBuffer() {\n const gl = this._gl;\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n private _createBuffer(): WebGLBuffer {\n return this._gl.createBuffer()!;\n }\n\n private _deleteBuffer(buffer: WebGLBuffer) {\n return this._gl.deleteBuffer(buffer);\n }\n\n private _createNativeVAO() {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n return (gl as WebGL2RenderingContext).createVertexArray()!;\n } else {\n const ext = this._extensions.vao;\n\n return ext?.createVertexArrayOES() || null;\n }\n }\n\n private _bindNativeVAO(vao: WebGLVertexArrayObject | null) {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n (gl as WebGL2RenderingContext).bindVertexArray(vao);\n } else {\n const ext = this._extensions.vao;\n\n ext?.bindVertexArrayOES(vao);\n }\n }\n\n private _deleteNativeVAO(vao: WebGLVertexArrayObject | null) {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n (gl as WebGL2RenderingContext).deleteVertexArray(vao);\n } else {\n const ext = this._extensions.vao;\n\n ext?.deleteVertexArrayOES(vao);\n }\n }\n\n private _supplyGeometryData(vao: VertexArrayObject, shaderProgram: ShaderProgram) {\n const geometry = vao.geometry;\n\n this._supplyIndiciesData(geometry.indicies, vao.buffers.indicies);\n this._supplyAttributeData(geometry.vertices, shaderProgram.program, \"position\", vao.buffers.position);\n this._supplyAttributeData(geometry.uvs, shaderProgram.program, \"uv\", vao.buffers.uv);\n }\n\n private _unbindBuffers() {\n const gl = this._gl;\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n }\n\n private _supplyIndiciesData(indicies: VertexData, buffer: WebGLBuffer) {\n const gl = this._gl;\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicies.data, gl.STATIC_DRAW);\n }\n\n private _supplyAttributeData(attribute: VertexData, program: WebGLProgram, name: string, buffer: WebGLBuffer) {\n const gl = this._gl;\n const attribLocation = gl.getAttribLocation(program, name);\n\n // Attribute not used\n if (attribLocation < 0) return;\n\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ARRAY_BUFFER, attribute.data, gl.STATIC_DRAW);\n gl.vertexAttribPointer(attribLocation, attribute.itemSize, gl.FLOAT, false, 0, 0);\n gl.enableVertexAttribArray(attribLocation);\n }\n\n private _compileShader(type: number, src: string) {\n const gl = this._gl;\n const shader = gl.createShader(type)!;\n\n gl.shaderSource(shader, src);\n gl.compileShader(shader);\n\n return shader;\n }\n\n private _getCommonUniformLocations(program: WebGLProgram) {\n const gl = this._gl;\n\n return {\n uMVMatrix: gl.getUniformLocation(program, \"uMVMatrix\")!,\n uPMatrix: gl.getUniformLocation(program, \"uPMatrix\")!\n };\n }\n\n private _getContext(canvas: HTMLCanvasElement): {\n gl: WebGLRenderingContext | WebGL2RenderingContext;\n isWebGL2: boolean;\n } {\n const webglIdentifiers = [\"webgl2\", \"webgl\", \"experimental-webgl\", \"webkit-3d\", \"moz-webgl\"];\n let context: WebGLRenderingContext | null = null;\n let isWebGL2 = false;\n const contextAttributes = {\n preserveDrawingBuffer: false,\n antialias: false\n };\n\n const onWebglContextCreationError = e => e.statusMessage;\n\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_CREATE_ERROR, onWebglContextCreationError);\n\n for (const identifier of webglIdentifiers) {\n try {\n context = canvas.getContext(identifier, contextAttributes) as WebGLRenderingContext;\n isWebGL2 = identifier === \"webgl2\";\n } catch (t) {} // eslint-disable-line no-empty\n if (context) {\n break;\n }\n }\n\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_CREATE_ERROR, onWebglContextCreationError);\n\n if (!context) {\n throw new View360Error(ERROR.MESSAGES.WEBGL_NOT_SUPPORTED, ERROR.CODES.WEBGL_NOT_SUPPORTED);\n }\n\n return {\n gl: context,\n isWebGL2\n };\n }\n\n private _onContextLost = () => {\n const canvas = this._canvas;\n canvas.classList.add(DEFAULT_CLASS.CTX_LOST);\n this._contextLost = true;\n };\n\n private _onContextRestore = () => {\n const canvas = this._canvas;\n canvas.classList.remove(DEFAULT_CLASS.CTX_LOST);\n this._contextLost = false;\n };\n}\n\nexport default WebGLContext;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4 } from \"gl-matrix\";\nimport Camera from \"./Camera\";\nimport Projection from \"../projection/Projection\";\nimport WebGLContext from \"./WebGLContext\";\nimport XRManager from \"./XRManager\";\n\n/**\n * Projection renderer, based on WebGL\n * @ko WebGL 기반의 프로젝션 렌더러\n * @since 4.0.0\n */\nclass WebGLRenderer {\n private _canvas: HTMLCanvasElement;\n private _elementSize: { x: number, y: number };\n private _pixelRatio: number;\n\n public readonly ctx: WebGLContext;\n\n /**\n * Canvas element\n * @ko 캔버스 엘리먼트\n * @since 4.0.0\n */\n public get canvas() { return this._canvas; }\n /**\n * Canvas's width (`devicePixelRatio` is not applied)\n * @ko 캔버스의 보이는 너비 (`devicePixelRatio`가 적용되지 않은)\n * @since 4.0.0\n */\n public get width() { return this._elementSize.x; }\n /**\n * Canvas's height (`devicePixelRatio` is not applied)\n * @ko 캔버스의 높이 (`devicePixelRatio`가 적용되지 않은)\n * @since 4.0.0\n */\n public get height() { return this._elementSize.y; }\n /**\n * Current `devicePixelRatio` value.\n * @ko 현재 `devicePixelRatio` 값.\n * @since 4.0.0\n * @example\n * ```js\n * cosnt renderingWidth = view360.renderer.width * view360.renderer.pixelRatio;\n * ```\n */\n public get pixelRatio() { return this._pixelRatio; }\n /**\n * Width / height ratio (= width / height)\n * @ko 너비 / 높이의 비율 (= width / height)\n * @since 4.0.0\n * @example\n * ```js\n * const aspect = view360.renderer.width / view360.renderer.pixelRatio;\n * assert(aspect === view360.renderer.aspect);\n * ```\n */\n public get aspect() { return this._elementSize.x / this._elementSize.y; }\n\n /**\n * Create new instance\n * @ko 새 인스턴스를 생성합니다.\n * @param canvas - Canvas element {@ko 캔버스 엘리먼트}\n * @param debug - Whether to enable WebGL debugging {@ko WebGL debug 활성화 여부 }\n */\n public constructor(canvas: HTMLCanvasElement, debug: boolean) {\n this._canvas = canvas;\n this._elementSize = { x: 0, y: 0 };\n this._pixelRatio = 1;\n this.ctx = new WebGLContext(canvas, debug);\n }\n\n /**\n * Destroy instance and release all resources.\n * @ko 인스턴스를 제거하고 사용된 리소스를 전부 해제합니다.\n * @since 4.0.0\n */\n public destroy() {\n const canvas = this._canvas;\n\n this.ctx.destroy();\n canvas.width = 1;\n canvas.height = 1;\n }\n\n /**\n * Resize canvas and renew inner size cache.\n * @ko 캔버스의 크기를 재계산해서 내부의 사이즈 캐시값을 갱신합니다.\n * @since 4.0.0\n */\n public resize() {\n const canvas = this._canvas;\n const canvasSize = this._elementSize;\n const devicePixelRatio = window.devicePixelRatio;\n\n canvasSize.x = canvas.clientWidth;\n canvasSize.y = canvas.clientHeight;\n\n canvas.width = canvasSize.x * devicePixelRatio;\n canvas.height = canvasSize.y * devicePixelRatio;\n\n this._pixelRatio = devicePixelRatio;\n this.ctx.resize();\n }\n\n /**\n * Render projection\n * @ko 프로젝션을 렌더링합니다.\n * @param projection - Projection to render {@ko 렌더링할 프로젝션}\n * @param cameraa - Camera instance {@ko 카메라의 인스턴스}\n * @since 4.0.0\n */\n public render(projection: Projection, camera: Camera) {\n const ctx = this.ctx;\n const mesh = projection.getMesh();\n if (ctx.lost || !mesh) return;\n\n ctx.clear();\n ctx.useProgram(mesh.program);\n ctx.updateCommonUniforms(mesh, camera, mesh.program);\n projection.update(camera);\n ctx.updateUniforms(mesh.program);\n ctx.draw(mesh.vao, mesh.program);\n }\n\n /**\n * Render VR frame, only used for rendering frames inside VR sessions.\n * @ko VR 프레임을 렌더링합니다. VR 세션 진입 도중에만 사용됩니다.\n * @internal\n * @param projection - Projection to render {@ko 렌더링할 프로젝션}\n * @param vr - Instance of XRManager {@ko XRManager의 인스턴스}\n * @param frame - VR frame {@ko VR 프레임}\n * @since 4.0.0\n */\n public renderVR(projection: Projection, vr: XRManager, frame: XRFrame) {\n const ctx = this.ctx;\n const mesh = projection.getMesh();\n const eyeParams = vr.getEyeParams(frame);\n\n if (!eyeParams || !mesh) return;\n\n ctx.bindXRFrame(frame);\n ctx.useProgram(mesh.program);\n ctx.updateUniforms(mesh.program);\n\n eyeParams.forEach((eye, eyeIndex) => {\n const viewport = eye.viewport;\n // We're using \"mesh.matrix\"(=local matrix) here for efficiency\n // As projection doesn't require world matrix, as it doesn't have any parent or child\n const mvMatrix = mat4.multiply(mat4.create(), eye.vMatrix, mesh.matrix);\n\n ctx.viewport(viewport.x, viewport.y, viewport.width, viewport.height);\n ctx.updateVRUniforms(mesh.program, mvMatrix, eye.pMatrix, eyeIndex);\n ctx.draw(mesh.vao, mesh.program);\n });\n }\n}\n\nexport default WebGLRenderer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport Camera, { CameraOptions } from \"./core/Camera\";\nimport PanoControl, { PanoControlOptions } from \"./control/PanoControl\";\nimport TextureLoader from \"./core/TextureLoader\";\nimport FrameAnimator from \"./core/FrameAnimator\";\nimport AutoResizer from \"./core/AutoResizer\";\nimport Autoplay, { AutoplayOptions } from \"./core/Autoplay\";\nimport XRManager from \"./core/XRManager\";\nimport View360Error from \"./core/View360Error\";\nimport Projection from \"./projection/Projection\";\nimport HotspotRenderer, { HotspotOptions } from \"./hotspot/HotspotRenderer\";\nimport WebGLRenderer from \"./core/WebGLRenderer\";\nimport Texture from \"./texture/Texture\";\nimport View360Plugin from \"./plugin/View360Plugin\";\nimport ERROR from \"./const/error\";\nimport { CONTROL_EVENTS } from \"./const/internal\";\nimport { DEFAULT_CLASS, EVENTS } from \"./const/external\";\nimport { findCanvas, getElement } from \"./utils\";\nimport * as EVENT_TYPES from \"./type/events\";\nimport { EventParams } from \"./type/utils\";\n\n/**\n * Events that {@link View360} can trigger\n * @ko {@link View360}가 트리거할 수 있는 이벤트들\n * @see [Detailed Example](/docs/events/ready)\n * @since 4.0.0\n */\nexport interface View360Events {\n [EVENTS.READY]: EVENT_TYPES.ReadyEvent;\n [EVENTS.LOAD_START]: EVENT_TYPES.LoadStartEvent;\n [EVENTS.LOAD]: EVENT_TYPES.LoadEvent;\n [EVENTS.PROJECTION_CHANGE]: EVENT_TYPES.ProjectionChangeEvent;\n [EVENTS.RESIZE]: EVENT_TYPES.ResizeEvent;\n [EVENTS.BEFORE_RENDER]: EVENT_TYPES.BeforeRenderEvent;\n [EVENTS.RENDER]: EVENT_TYPES.RenderEvent;\n [EVENTS.INPUT_START]: EVENT_TYPES.InputStartEvent;\n [EVENTS.INPUT_END]: EVENT_TYPES.InputEndEvent;\n [EVENTS.VIEW_CHANGE]: EVENT_TYPES.ViewChangeEvent;\n [EVENTS.STATIC_CLICK]: EVENT_TYPES.StaticClickEvent;\n [EVENTS.VR_START]: EVENT_TYPES.VRStartEvent;\n [EVENTS.VR_END]: EVENT_TYPES.VREndEvent;\n}\n\n/**\n * Options for {@link View360}\n * @ko {@link View360}용 옵션들\n * @see [Detailed Example](/docs/options)\n * @since 4.0.0\n */\nexport interface View360Options extends CameraOptions, PanoControlOptions {\n projection: Projection | null;\n hotspot: Partial;\n autoplay: boolean | Partial;\n autoInit: boolean;\n autoResize: boolean;\n canvasSelector: string;\n useResizeObserver: boolean;\n tabIndex: number | null;\n on: Partial<{ [key in keyof View360Events]: (evt: View360Events[key]) => any }>;\n plugins: View360Plugin[];\n maxDeltaTime: number;\n debug: boolean;\n}\n\n/**\n * Panorama 360 image viewer\n * @ko 파노라마 360 이미지 뷰어\n * @since 4.0.0\n * @see View360Options\n * @see View360Events\n */\nclass View360 extends Component {\n /**\n * Current version string of the View360\n * @ko View360의 현재 버젼 문자열\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // If the installed version of the View360 is v4.0.0, View360.VERSION is equal to \"4.0.0\"\n * console.log(View360.VERSION) // 4.0.0\n * ```\n */\n public static readonly VERSION = \"#__VERSION__#\";\n\n private _rootEl: HTMLElement;\n private _renderer: WebGLRenderer;\n private _camera: Camera;\n private _control: PanoControl;\n private _animator: FrameAnimator;\n private _autoplay: Autoplay;\n private _hotspot: HotspotRenderer;\n private _projection: Projection | null;\n private _autoResizer: AutoResizer;\n private _vr: XRManager;\n private _plugins: View360Plugin[];\n private _initialized: boolean;\n\n private _autoInit: View360Options[\"autoInit\"];\n private _autoResize: View360Options[\"autoResize\"];\n private _canvasSelector: View360Options[\"canvasSelector\"];\n private _useResizeObserver: View360Options[\"useResizeObserver\"];\n private _tabIndex: View360Options[\"tabIndex\"];\n private _debug: View360Options[\"debug\"];\n\n /**\n * Root element (`.view360-container`)\n * @ko 루트 엘리먼트 (`.view360-container`)\n * @since 4.0.0\n * @readonly\n * @example\n * ```html\n *
\n * \n *
\n * ```\n * ```ts\n * import View360 from \"@egjs/view360\";\n *\n * const viewer = new View360(\"#viewer\");\n * console.log(viewer.rootEl); // Element with id \"viewer\"\n * ```\n */\n public get rootEl() { return this._rootEl; }\n /**\n * Projection renderer.\n * @ko 프로젝션 렌더러.\n * @since 4.0.0\n * @readonly\n */\n public get renderer() { return this._renderer; }\n /**\n * Projection camera.\n * @ko 프로젝션 카메라.\n * @since 4.0.0\n * @readonly\n */\n public get camera() { return this._camera; }\n /**\n * Rotate/Zoom Controller.\n * @ko 회전/줌 컨트롤러.\n * @since 4.0.0\n * @readonly\n */\n public get control() { return this._control; }\n /**\n * WebXR-based VR manager.\n * @ko WebXR 기반의 VR 기능 매니저 인스턴스.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // Example: Enter VR\n * // This must be called on user interaction, else will be rejected.\n * viewer.vr.enter();\n * ```\n */\n public get vr() { return this._vr; }\n /**\n * Hotspot renderer.\n * You can also change options of {@link View360Options#hotspot} with this.\n * @ko 핫스팟 렌더러 인스턴스.\n * {@link View360Options#hotspot} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get hotspot() { return this._hotspot; }\n /**\n * An array of plugins added.\n * @ko 추가된 플러그인의 배열\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * plugins: [new ControlBar()]\n * });\n *\n * console.log(viewer.plugins); // [ControlBar]\n *\n * viewer.addPlugins(new LoadingSpinner()) // [ControlBar, LoadingSpinner];\n * ```\n */\n public get plugins() { return this._plugins; }\n /**\n * A instance of {@link Projection} that currently enabled. `null` if not initialized yet.\n * You should call {@link View360#load} to change panorama src or projection type.\n * @ko 현재 사용중인 {@link Projection}의 인스턴스. 프로젝션을 활성화하지 않았을 경우 `null`입니다.\n * 파노라마 이미지 소스나 프로젝션 타입을 변경하려면 {@link View360#load}를 호출하면 됩니다.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360\n * ```\n */\n public get projection() { return this._projection; }\n public set projection(val: View360Options[\"projection\"]) {\n if (this._initialized && val) {\n this.load(val);\n } else {\n this._projection = val;\n }\n }\n /**\n * A boolean value whether {@link View360#init init()} is called before.\n * @ko {@link View360#init init()}이 호출되었는지 여부를 가리키는 값\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360(\"#el\", { autoInit: false });\n *\n * console.log(viewer.initialized); // false\n *\n * await viewer.init();\n *\n * console.log(viewer.initialized); // true\n * ```\n */\n public get initialized() { return this._initialized; }\n /**\n * Instance of the Autoplay manager.\n * You can also change {@link View360Options#autoplay} options with this.\n * @ko Autoplay 기능의 매니저 인스턴스.\n * 이 인스턴스를 통해 {@link View360Options#autoplay} 옵션을 변경하는 것도 가능합니다.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // Disable autoplay\n * viewer.autoplay.disable();\n * ```\n */\n public get autoplay() { return this._autoplay; }\n /**\n * When this value is `true` and {@link View360Options#projection} is set, {@link View360#init init()} will be called automatically when instance is created.\n * @ko 이 값이 `true`이고, {@link View360Options#projection}이 설정되었으면, 인스턴스 생성 시점에 자동으로 {@link View360#init init()}을 호출합니다.\n * @default true\n * @since 4.0.0\n * @example\n * ```ts\n * import View360, { EquirectProjection, EVENTS } from \"@egjs/view360\";\n *\n * // viewer.init() is called on instance creation\n * // But as `init` is asynchronous, you should wait for \"ready\" event if you want to do something after initialization.\n * const viewer = new View360(\"#el_id\", {\n * autoInit: true,\n * projection: new EquirectProjection({ src: \"SRC_TO_URL\" })\n * });\n *\n * console.log(viewer.initialized); // false, as `init` is asynchronous\n *\n * viewer.once(EVENTS.READY, () => {\n * console.log(viewer.initialized); // true\n * });\n * ```\n */\n public get autoInit() { return this._autoInit; }\n /**\n * When `true`, {@link View360#resize} is called when the canvas size is changed.\n * @ko `true`일 경우, 캔버스의 크기가 변경되었을 때 자동으로 {@link View360#resize}를 호출합니다.\n * @default true\n * @since 4.0.0\n * @see View360#useResizeObserver\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * autoResize: true\n * });\n *\n * // This can trigger `viewer.resize()` if the canvas size was not 400px\n * const canvas = viewer.renderer.canvas;\n * canvas.style.width = \"400px\";\n * ```\n */\n public get autoResize() { return this._autoResize; }\n /**\n * CSS selector for canvas element to render panorama image/video.\n * The canvas element should be placed inside the root element. (Dont' have to be direct child)\n * @ko 파노라마 이미지/비디오를 렌더링할 canvas 엘리먼트의 CSS 선택자\n * 캔버스 엘리먼트는 루트 엘리먼트 내부에 있어야합니다. 루트 엘리먼트의 직계 자식 엘리먼트(Direct child element)일 필요는 없습니다.\n * @default \"canvas\"\n * @since 4.0.0\n * @example\n * ```html\n *
\n * \n * \n * \n *
\n * ```\n *\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * canvasSelector: \"#canvas_to_select\"\n * });\n * ```\n */\n public get canvasSelector() { return this._canvasSelector; }\n /**\n * When `true`, it will use {@link ResizeObserver} API to detect canvas size change when {@link View360Options#autoResize} is enabled.\n * @ko `true`일 때 {@link View360Options#autoResize}가 활성화되었으면, 사용 가능한 환경에서 {@link ResizeObserver} API를 사용해서 캔버스 크기 변화를 추적합니다.\n * @default true\n * @since 4.0.0\n */\n public get useResizeObserver() { return this._useResizeObserver; }\n /**\n * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} attribute for the canvas element.\n * This is necessary for the keyboard controls.\n * By default, `0` will be assigned. `null` to disable.\n * @ko 캔버스 엘리먼트에 적용할 {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} 어트리뷰트의 값.\n * 이 값을 설정해야만 키보드 컨트롤을 사용 가능합니다.\n * 기본값으로 `0`이 설정됩니다. `null`로 지정하면 `tabindex`를 설정하지 않습니다.\n * @see RotateControlOptions#disableKeyboard\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * tabindex: 5\n * });\n * ```\n *\n * ```html\n * \n *
\n * \n *
\n * ```\n */\n public get tabIndex() { return this._tabIndex; }\n public set tabIndex(val: View360Options[\"tabIndex\"]) {\n const canvas = this._renderer.canvas;\n this._tabIndex = val;\n\n if (val != null) {\n canvas.tabIndex = val;\n } else {\n canvas.removeAttribute(\"tabindex\");\n }\n }\n /**\n * A maximum delta time between frames in seconds.\n * It can prevent camera or control changing too fast when frame being late.\n * @ko 프레임간 시간 차이의 최대값. (초 단위)\n * 퍼포먼스 등의 이유로 프레임 렌더링이 늦어졌을 때, 화면이 갑작스럽게 바뀌는 것을 막아줍니다.\n * @default 1 / 30\n * @since 4.0.0\n */\n public get maxDeltaTime() { return this._animator.maxDeltaTime; }\n public set maxDeltaTime(val: View360Options[\"maxDeltaTime\"]) { this._animator.maxDeltaTime = val; }\n /**\n * Enable WebGL debugging. Setting this to `true` can decrease performance.\n * This is used internally on developing View360.\n * @ko WebGL 디버깅을 활성화합니다. 이 값을 `true`로 할 경우 성능이 하락할 수 있습니다.\n * 이 옵션은 View360을 개발하기 위해 내부적으로 사용됩니다.\n * @default false\n */\n public get debug() { return this._debug; }\n public set debug(val: View360Options[\"debug\"]) { this._debug = val; }\n\n // Camera options\n /**\n * Initial yaw (y-axis rotation) value for camera. (in degrees, °)\n * As View360 uses right-handed coordinate system internally, camera will rotate counter-clockwise by this value.\n * @ko 카메라의 초기 yaw(y축 회전)값 (도 단위, °)\n * View360은 오른손 좌표계를 사용하기 때문에, 카메라가 해당 값만큼 시계 반대방향으로 회전합니다.\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialYaw: 30\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.yaw); // 30\n * });\n * ```\n */\n public get initialYaw() { return this._camera.initialYaw; }\n public set initialYaw(val: View360Options[\"initialYaw\"]) { this._camera.initialYaw = val; }\n /**\n * Initial pitch (x-axis rotation) value for camera. (in degrees, °)\n * As View360 uses right-handed coordinate system internally, positive value will make camera to look upside, while negative value will look down.\n * @ko 카메라의 초기 pitch(x축 회전)값 (도 단위, °)\n * View360은 오른손 좌표계를 사용하기 때문에, 양(+)의 값은 카메라가 위를 보게 하고, 음(-)의 값은 카메라가 아래를 보게 합니다.\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialPitch: 60\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.pitch); // 60\n * });\n * ```\n */\n public get initialPitch() { return this._camera.initialPitch; }\n public set initialPitch(val: View360Options[\"initialPitch\"]) { this._camera.initialPitch = val; }\n /**\n * Initial zoom value for camera.\n * Setting this value to `2` will enlarge panorama 200% by width.\n * @ko 카메라의 초기 줌 값.\n * 이 값을 `2`로 설정할 경우 파노라마 이미지를 가로 기준 200%만큼 확대합니다.\n * @default 1\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialZoom: 2\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.zoom); // 2\n * });\n * ```\n */\n public get initialZoom() { return this._camera.initialZoom; }\n public set initialZoom(val: View360Options[\"initialZoom\"]) { this._camera.initialZoom = val; }\n /**\n * Restrict yaw(y-axis rotation) range. (in degrees, °)\n * @ko yaw(y축 회전) 범위를 제한합니다. (도 단위, °)\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * yawRange: [-30, 30]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.yaw); // 0\n * viewer.camera.lookAt({ yaw: 60 });\n * console.log(viewer.camera.yaw); // 30\n * });\n * ```\n */\n public get yawRange() { return this._camera.yawRange; }\n public set yawRange(val: View360Options[\"yawRange\"]) {\n this._camera.yawRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Restrict pitch(x-axis rotation) range. (in degrees, °)\n * @ko pitch(x축 회전) 범위를 제한합니다. (도 단위, °)\n * @default null\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * pitchRange: [-45, 45]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.pitch); // 0\n * viewer.camera.lookAt({ pitch: 60 });\n * console.log(viewer.camera.pitch); // 45\n * });\n * ```\n */\n public get pitchRange() { return this._camera.pitchRange; }\n public set pitchRange(val: View360Options[\"pitchRange\"]) {\n this._camera.pitchRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Restrict camera zoom range.\n * If `null`, a default zoom range from `0.6` to `10` will be used.\n * @ko 카메라 줌 범위를 제한합니다.\n * `null`일 경우 기본값으로 `0.6`에서 `10`의 범위를 사용합니다.\n * @default null\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * zoomRange: [0.5, 4]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.zoom); // 1\n * viewer.camera.lookAt({ zoom: 6 });\n * console.log(viewer.camera.zoom); // 4\n * });\n * ```\n */\n public get zoomRange() { return this._camera.zoomRange; }\n public set zoomRange(val: View360Options[\"zoomRange\"]) {\n this._camera.zoomRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Camera's horizontal FOV(Field of View). (in degrees, °)\n * @ko 카메라의 수평 FOV(Field of View) 값. (도 단위, °)\n * @default 90\n * @since 4.0.0\n * @example\n * ```ts\n * // Init with fov: 120\n * const viewer = new View360(\"#el_id\", { fov: 120 });\n *\n * // Back to 90\n * viewer.fov = 90;\n * ```\n */\n public get fov() { return this._camera.fov; }\n public set fov(val: View360Options[\"fov\"]) {\n const camera = this._camera;\n const control = this._control;\n\n camera.fov = val;\n camera.updateMatrix();\n control.sync();\n }\n\n // Control options\n /**\n * A control for camera rotation.\n * You can also change options of {@link View360Options#rotate} with this.\n * @ko 카메라 회전을 담당하는 컨트롤.\n * {@link View360Options#rotate} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get rotate() { return this._control.rotate; }\n /**\n * A control for camera zoom.\n * You can also change options of {@link View360Options#zoom} with this.\n * @ko 카메라 줌을 담당하는 컨트롤.\n * {@link View360Options#zoom} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get zoom() { return this._control.zoom; }\n /**\n * A control for camera rotation with gyroscope input.\n * You can also change options of {@link View360Options#gyro} with this.\n * @ko 자이로스코프를 통한 카메라 회전을 담당하는 컨트롤.\n * {@link View360Options#gyro} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get gyro() { return this._control.gyro; }\n /**\n * Apply CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor} by current state of input when using mouse.\n * If `true`, this will add CSS style to canvas element. It'll apply `cursor: \"grab\"` by default and `cursor: \"grabbing\"` when holding the mouse button.\n * @ko 마우스 사용시 CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor}값을 자동으로 변경할지 여부.\n * `true`일 경우 기본 상태에서 `cursor: \"grab\"`을, 입력 도중에 `cursor: \"grabbing\"`을 캔버스에 적용합니다.\n * @default true\n * @since 4.0.0\n */\n public get useGrabCursor() { return this._control.useGrabCursor; }\n public set useGrabCursor(val: View360Options[\"useGrabCursor\"]) { this._control.useGrabCursor = val; }\n /**\n * Disable context menu which pops up on mouse right click.\n * @ko 마우스 우클릭시 표시되는 컨텍스트 메뉴를 비활성화합니다.\n * @default false\n * @since 4.0.0\n */\n public get disableContextMenu() { return this._control.disableContextMenu; }\n public set disableContextMenu(val: View360Options[\"disableContextMenu\"]) { this._control.disableContextMenu = val; }\n /**\n * If `true`, enables scroll on mobile(touch) devices on canvas.\n * :::caution\n * When this option is enabled, users must swipe horizontally first then vertically to change view up or down.\n * :::\n * @ko `true`로 설정할 경우, 모바일(터치) 환경의 캔버스 영역 내에서 스크롤을 가능하게 합니다.\n * :::caution\n * 이 값을 활성화할 경우, 사용자가 카메라 뷰를 위/아래로 바꾸기 위해서는 먼저 가로로 스와이프한 이후에 세로로 스와이프해야만 합니다.\n * :::\n * @since 4.0.0\n * @default true\n */\n public get scrollable() { return this._control.scrollable; }\n public set scrollable(val: View360Options[\"scrollable\"]) { this._control.scrollable = val; }\n /**\n * If `true`, enables scroll by mouse wheel on canvas.\n * :::caution\n * When this option is enabled, zoom by mouse wheel will be disabled.\n * :::\n * @ko `true`로 설정할 경우, 캔버스 영역 내에서 마우스 휠을 이용한 페이지 스크롤이 가능해집니다.\n * :::caution\n * 이 값을 활성화할 경우, 마우스 휠을 통한 줌이 불가능하게 됩니다.\n * :::\n * @since 4.0.0\n * @default false\n */\n public get wheelScrollable() { return this._control.wheelScrollable; }\n public set wheelScrollable(val: View360Options[\"wheelScrollable\"]) { this._control.wheelScrollable = val; }\n\n /**\n * Create new instance of View360\n * @ko View360의 새로운 인스턴스를 생성합니다\n * @param root - Root element(`.view360-container`) to mount View360\n * Can be either a CSS selector or HTMLElement.\n * {@ko View360을 마운트할 루트 엘리먼트, CSS 셀렉터나 HTMLElement를 지정 가능합니다.}\n * @param options - Options to apply\n * {@ko 적용할 옵션들}\n * @example\n * ```ts\n * import View360, { EquirectProjection } from \"@egjs/view360\";\n *\n * // Create new View360 instance\n * const viewer = new View360(\"#id-of-a-container\", {\n * projection: new EquirectProjection({\n * src: \"URL_TO_PANORAMA_IMAGE_OR_VIDEO\",\n * })\n * });\n * ```\n */\n public constructor(root: string | HTMLElement, {\n projection = null,\n initialYaw = 0,\n initialPitch = 0,\n initialZoom = 1,\n yawRange = null,\n pitchRange = null,\n zoomRange = null,\n fov = 90,\n useGrabCursor = true,\n disableContextMenu = false,\n rotate = true,\n zoom = true,\n gyro = false,\n scrollable = true,\n wheelScrollable = false,\n autoplay = false,\n hotspot = {},\n autoInit = true,\n autoResize = true,\n canvasSelector = \"canvas\",\n useResizeObserver = true,\n on = {},\n plugins = [],\n maxDeltaTime = 1 / 30,\n tabIndex = 0,\n debug = false\n }: Partial = {}) {\n super();\n\n this._rootEl = getElement(root);\n this._plugins = plugins;\n this._initialized = false;\n\n // Options\n this._autoInit = autoInit;\n this._autoResize = autoResize;\n this._canvasSelector = canvasSelector;\n this._useResizeObserver = useResizeObserver;\n this._tabIndex = tabIndex;\n this._debug = debug;\n\n // Core components\n const canvas = findCanvas(this._rootEl, canvasSelector);\n this._renderer = new WebGLRenderer(canvas, debug);\n this._camera = new Camera({\n initialYaw,\n initialPitch,\n initialZoom,\n fov,\n yawRange,\n pitchRange,\n zoomRange\n });\n this._control = new PanoControl(canvas, this._camera, {\n useGrabCursor,\n scrollable,\n wheelScrollable,\n disableContextMenu,\n rotate,\n zoom,\n gyro\n });\n this._animator = new FrameAnimator(maxDeltaTime);\n this._autoplay = new Autoplay(this, canvas, autoplay);\n this._projection = projection;\n this._autoResizer = new AutoResizer(useResizeObserver, () => this.resize());\n this._vr = new XRManager(this._renderer.ctx);\n this._hotspot = new HotspotRenderer(this._rootEl, this._renderer, hotspot);\n\n this._addEventHandlers(on);\n\n if (projection && autoInit) {\n this.init();\n }\n }\n\n /**\n * Destroy instance and release all resources.\n * @ko 인스턴스를 제거하고 모든 리소스를 해제합니다.\n * @since 4.0.0\n */\n public destroy() {\n this._camera.destroy();\n this._animator.stop();\n this._renderer.destroy();\n this._control.destroy();\n this._autoResizer.disable();\n\n if (this._projection) {\n this._projection.releaseAllResources(this._renderer.ctx);\n this._projection = null;\n }\n\n this._plugins.forEach(plugin => plugin.destroy(this));\n\n this._initialized = false;\n }\n\n /**\n * Initialize inner components and load projection src.\n * @ko 내부 컴포넌트들을 초기화하고 프로젝션 소스를 로드합니다.\n * @since 4.0.0\n */\n public async init() {\n if (!this._projection) {\n throw new View360Error(ERROR.MESSAGES.PROVIDE_PROJECTION_FIRST, ERROR.CODES.PROVIDE_PROJECTION_FIRST);\n }\n\n const renderer = this._renderer;\n const camera = this._camera;\n const control = this._control;\n const animator = this._animator;\n const hotspot = this._hotspot;\n const projection = this._projection;\n const canvas = renderer.canvas;\n\n this._bindComponentEvents();\n renderer.ctx.init();\n this._resizeComponents();\n camera.updateMatrix();\n\n if (this._autoResize) {\n this._autoResizer.enable(canvas);\n }\n\n if (!this._autoplay.enableBlocked) {\n this._autoplay.enable();\n }\n\n this._plugins.forEach(plugin => {\n plugin.init(this);\n });\n\n const texture = await this._loadTexture(projection);\n this._applyProjection(projection, texture, null);\n hotspot.refresh();\n animator.start(this._renderFrameOnDemand);\n await control.enable();\n\n if (this._tabIndex != null && !canvas.hasAttribute(\"tabIndex\")) {\n canvas.tabIndex = this._tabIndex;\n }\n\n this._initialized = true;\n this.renderFrame(0);\n\n this._emit(EVENTS.READY);\n }\n\n /**\n * Load new panorama image/video and display it.\n * This will {@link View360#init init()} View360 if it's not initialized yet.\n * @ko 새로운 파노라마 이미지 혹은 비디오를 로드하고 표시합니다.\n * 만약 View360이 아직 초기화되지 않았다면, {@link View360#init init()}을 호출합니다.\n * @param projection - Projection & video options for new source. {@ko 새로운 파노라마 이미지/비디오에 적용할 옵션들}\n * @returns `Promise` if load was successful. {@ko 프로젝션 로드에 성공했을 경우 `Promise`를 반환합니다. }\n * @since 4.0.0\n * @example\n * ```ts\n * // Change to video\n * viewer.load({\n * src: \"URL_TO_NEW_VIDEO\",\n * video: true\n * });\n * ```\n */\n public async load(projection: Projection): Promise {\n if (!projection) return false;\n\n if (this._initialized) {\n const texture = await this._loadTexture(projection);\n this._applyProjection(projection, texture, this._projection);\n this.renderFrame(0);\n } else {\n // Should update internal options before init\n this._projection = projection;\n this.init();\n }\n\n return true;\n }\n\n /**\n * Refresh component's size by current\n * @ko View360이 내부적으로 캐시하고 있는 엘리먼트 크기를 현재 크기로 갱신합니다.\n * @since 4.0.0\n */\n public resize() {\n if (!this._initialized) return;\n\n this._resizeComponents();\n\n // To prevent flickering, render immediately after resizing components\n this.renderFrame(0);\n\n const { width, height } = this._renderer;\n\n this._emit(EVENTS.RESIZE, {\n width,\n height\n });\n }\n\n /**\n * Add new plugins\n * @ko 새로운 플러그인을 추가합니다.\n * @param plugins Plugins to add {@ko 추가할 플러그인들}\n * @see View360Options#plugins\n * @since 4.0.0\n * @example\n * ```ts\n * // Add a single plugin\n * viewer.addPlugins(new ControlBar());\n *\n * // Add multiple plugins\n * viewer.addPlugins(new ControlBar(), new LoadingSpinner());\n * ```\n */\n public addPlugins(...plugins: View360Plugin[]) {\n if (this._initialized) {\n plugins.forEach(plugin => { plugin.init(this); });\n }\n\n this._plugins.push(...plugins);\n }\n\n /**\n * Remove plugins.\n * @ko 플러그인을 제거합니다.\n * @param plugins Plugins to remove {@ko 제거할 플러그인들}\n * @since 4.0.0\n * @example\n * ```ts\n * // Remove a single plugin\n * viewer.removePlugins(plugin1);\n *\n * // Remove multiple plugins\n * viewer.removePlugins(plugin2, plugin3);\n * ```\n */\n public removePlugins(...plugins: View360Plugin[]) {\n plugins.forEach(plugin => {\n const pluginIdx = this._plugins.indexOf(plugin);\n\n if (pluginIdx < 0) return;\n\n plugin.destroy(this);\n this._plugins.splice(pluginIdx, 1);\n });\n }\n\n /**\n * Render a single panorama image/video frame.\n * Rendering is performed automatically on demand, so you usually don't have to call this.\n * Call this when a frame is not renewed after changing options.\n * @ko 파노라마 이미지/비디오의 한 프레임을 렌더링합니다.\n * 프레임 갱신은 보통 필요한 때에만 자동적으로 이루어지기 때문에, 보통은 이 메소드를 호출할 필요는 없습니다.\n * 옵션 변경 이후에도 프레임 갱신이 이루어지지 않는다면, 이 메소드를 호출해주세요.\n * @param delta Delta time in milisec. {@ko 프레임간 시간 차이, 밀리초 단위}\n * @since 4.0.0\n */\n public renderFrame = (delta: number) => {\n const camera = this._camera;\n const renderer = this._renderer;\n const control = this._control;\n const hotspot = this._hotspot;\n const autoPlayer = this._autoplay;\n const projection = this._projection;\n\n if (!projection) return;\n\n this._emit(EVENTS.BEFORE_RENDER);\n\n if (autoPlayer.playing) {\n autoPlayer.update(delta);\n control.sync();\n }\n\n if (camera.animation) {\n camera.animation.update(delta);\n } else {\n control.update(delta);\n }\n\n renderer.render(projection, camera);\n hotspot.render(camera);\n\n if (camera.changed) {\n this._emit(EVENTS.VIEW_CHANGE, {\n yaw: camera.yaw,\n pitch: camera.pitch,\n zoom: camera.zoom,\n quaternion: [\n camera.quaternion[0],\n camera.quaternion[1],\n camera.quaternion[2],\n camera.quaternion[3]\n ]\n });\n }\n camera.onFrameRender();\n\n this._emit(EVENTS.RENDER);\n };\n\n private _emit(eventName: K, ...params: EventParams) {\n const evtParams = params ? params[0] : {};\n\n this.trigger(eventName as any, {\n type: eventName,\n target: this,\n ...evtParams\n });\n }\n\n private _renderFrameOnDemand = (delta: number) => {\n const camera = this._camera;\n const control = this._control;\n const autoplay = this._autoplay;\n const texture = this._projection?.getTexture();\n\n if (!this._initialized || !texture) return;\n if (\n !camera.animation\n && !control.animating\n && !autoplay.playing\n && !texture.isVideo()\n ) return;\n\n this.renderFrame(delta);\n };\n\n private _renderVRFrame = (_delta: number, frame: XRFrame) => {\n const vr = this._vr;\n const projection = this._projection;\n const renderer = this._renderer;\n\n if (!projection) return;\n\n this._emit(EVENTS.BEFORE_RENDER);\n\n renderer.renderVR(projection, vr, frame);\n\n this._emit(EVENTS.RENDER);\n }\n\n private _applyProjection(projection: Projection, texture: Texture, prevProjection: Projection | null) {\n const camera = this._camera;\n const control = this._control;\n const renderer = this._renderer;\n\n // Remove previous projection\n if (prevProjection) {\n prevProjection.releaseAllResources(this._renderer.ctx);\n }\n\n projection.applyTexture(renderer.ctx, texture);\n projection.updateCamera(camera);\n projection.updateControl(control);\n\n this._projection = projection;\n this._emit(EVENTS.PROJECTION_CHANGE, {\n projection\n });\n }\n\n private async _loadTexture(projection: Projection): Promise {\n const contentLoader = new TextureLoader();\n const { src, video } = projection;\n\n this._emit(EVENTS.LOAD_START, {\n src,\n video\n });\n\n const texture = await contentLoader.load(src, video);\n\n this._emit(EVENTS.LOAD, {\n src,\n video\n });\n\n return texture;\n }\n\n private _resizeComponents() {\n const renderer = this._renderer;\n const camera = this._camera;\n const control = this._control;\n\n renderer.resize();\n camera.resize(renderer.width, renderer.height);\n control.resize(renderer.width, renderer.height);\n }\n\n private _addEventHandlers(events: View360Options[\"on\"]) {\n // Bind option \"on\"\n Object.keys(events).forEach((evtName: keyof typeof EVENT_TYPES) => {\n this.on(evtName, events[evtName]);\n });\n }\n\n private _bindComponentEvents() {\n // Bind internal component events\n const root = this._rootEl;\n const control = this._control;\n const animator = this._animator;\n const renderer = this._renderer;\n const vr = this._vr;\n\n const controlEventsToPropagate = [\n CONTROL_EVENTS.STATIC_CLICK,\n CONTROL_EVENTS.INPUT_START,\n CONTROL_EVENTS.INPUT_END\n ];\n\n controlEventsToPropagate.forEach(evtName => {\n control.rotate.on(evtName, evt => {\n this._emit(evtName, evt);\n });\n\n control.zoom.on(evtName, evt => {\n this._emit(evtName, evt);\n });\n });\n\n vr.on(EVENTS.VR_START, evt => {\n root.classList.add(DEFAULT_CLASS.IN_VR);\n\n animator.changeContext(evt.session);\n animator.start(this._renderVRFrame);\n\n this._emit(EVENTS.VR_START);\n });\n\n vr.on(EVENTS.VR_END, () => {\n root.classList.remove(DEFAULT_CLASS.IN_VR);\n\n renderer.ctx.useDefaultFrameBuffer();\n animator.changeContext(window);\n animator.start(this._renderFrameOnDemand);\n\n this.resize();\n\n this._emit(EVENTS.VR_END);\n });\n }\n}\n\nexport default View360;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4, quat, vec3 } from \"gl-matrix\";\n\n/**\n * Base class for 3D objects\n * @ko 3D 오브젝트의 베이스 클래스\n * @since 4.0.0\n * @internal\n */\nclass Object3D {\n /**\n * Local matrix of the object\n * @ko 오브젝트의 local matrix\n * @since 4.0.0\n */\n public matrix: mat4;\n /**\n * Rotation quaternion\n * @ko 현재 오브젝트의 회전을 나타내는 사원수 값\n * @since 4.0.0\n */\n public rotation: quat;\n /**\n * Position of the object\n * @ko 오브젝트의 위치\n * @since 4.0.0\n */\n public position: vec3;\n /**\n * A scale vector of the object\n * @ko 오브젝트가 각 축으로 확대된 정도를 나타내는 벡터\n * @since 4.0.0\n */\n public scale: vec3;\n\n /**\n * Create new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n */\n public constructor() {\n this.matrix = mat4.create();\n this.rotation = quat.create();\n this.position = vec3.fromValues(0, 0, 0);\n this.scale = vec3.fromValues(1, 1, 1);\n }\n\n /**\n * Update local matrix of the object.\n * @ko 오브젝트의 local matrix를 갱신합니다.\n * @since 4.0.0\n */\n public updateMatrix() {\n mat4.fromRotationTranslationScale(this.matrix, this.rotation, this.position, this.scale);\n }\n}\n\nexport default Object3D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360Plugin from \"../View360Plugin\";\nimport View360 from \"../../View360\";\nimport { EVENTS } from \"../../const/external\";\nimport { createElement } from \"../../utils\";\nimport { LoadStartEvent } from \"../../type/events\";\n\n/**\n * Options for {@link LoadingSpinner}\n * @ko {@link LoadingSpinner}용 옵션들\n * @since 4.0.0\n * @category Plugin\n */\nexport interface LoadingSpinnerOptions {\n /**\n * Override default class names.\n * @ko 디폴트 클래스 이름들을 오버라이드합니다.\n * @since 4.0.0\n */\n className: Partial<{ -readonly [key in keyof typeof LoadingSpinner.DEFAULT_CLASS]: string }>;\n}\n\n/**\n * A plugin that displays loading spinner while loading the projection.\n * @ko 프로젝션 로딩중에 로딩 스피너를 보여주는 플러그인\n * @since 4.0.0\n * @category Plugin\n */\nclass LoadingSpinner implements View360Plugin {\n /**\n * Default class names that LoadingSpinner uses\n * @ko LoadingSpinner가 사용하는 디폴트 클래스 이름\n * @since 4.0.0\n */\n public static readonly DEFAULT_CLASS = {\n /**\n * A class name for the container element\n * @ko 컨테이너 엘리먼트의 클래스 이름\n * @since 4.0.0\n */\n CONTAINER: \"view360-spinner\",\n /**\n * A class name for the spinning ring element\n * @ko 돌아가는 링 엘리먼트의 클래스 이름\n * @since 4.0.0\n */\n RING: \"view360-spinner-ring\"\n } as const;\n\n /**\n * A class names overriding\n * @ko 현재 오버라이드 중인 클래스 이름\n * @since 4.0.0\n */\n public readonly className: LoadingSpinnerOptions[\"className\"];\n\n private _container: HTMLElement;\n\n /**\n * Create a new instance of LoadingSpinner. {@ko LoadingSpinner의 새 인스턴스를 생성합니다.}\n * @param options Options {@ko 옵션들}\n */\n public constructor({\n className = {}\n }: Partial = {}) {\n this.className = className;\n this._container = this._createElements();\n }\n\n public init(viewer: View360) {\n viewer.on(EVENTS.LOAD_START, this._startLoading);\n }\n\n public destroy(viewer: View360): void {\n viewer.off(EVENTS.LOAD_START, this._startLoading);\n this._detachElements({ target: viewer });\n }\n\n private _startLoading = ({ target: viewer }: LoadStartEvent) => {\n viewer.rootEl.appendChild(this._container);\n\n if (viewer.initialized) {\n viewer.once(EVENTS.LOAD, this._detachElements);\n } else {\n viewer.once(EVENTS.READY, this._detachElements);\n }\n };\n\n private _detachElements = ({ target: viewer }: { target: View360 }) => {\n const container = this._container;\n if (!container) return;\n\n if (container.parentElement === viewer.rootEl) {\n viewer.rootEl.removeChild(container);\n }\n };\n\n private _createElements() {\n const className = {\n ...this.className,\n ...LoadingSpinner.DEFAULT_CLASS\n };\n\n const container = createElement(className.CONTAINER);\n const ring = createElement(className.RING);\n\n container.appendChild(ring);\n\n return container;\n }\n}\n\nexport default LoadingSpinner;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n/* eslint-disable @typescript-eslint/no-empty-function */\n/* eslint-disable @typescript-eslint/no-unused-vars */\nimport ControlBar from \"./ControlBar\";\nimport View360 from \"../../View360\";\n\n/**\n * Common options for {@link ControlBarItem}\n * @ko {@link ControlBarItem}의 공통 옵션들\n * @category Plugin\n * @since 4.0.0\n */\nexport interface ControlBarItemOptions {\n /**\n * @copy ControlBarItem#position\n */\n position: typeof ControlBar.POSITION[keyof typeof ControlBar.POSITION];\n /**\n * @copy ControlBarItem#order\n */\n order: number;\n}\n\n/**\n * Interface of the ControlBar items\n * @ko 컨트롤바 아이템의 인터페이스\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nabstract class ControlBarItem {\n /**\n * Element of the item.\n * @ko 아이템의 엘리먼트\n * @since 4.0.0\n */\n public abstract element: HTMLElement;\n\n /**\n * Position to display item.\n * @ko 아이템을 표시할 위치.\n * @since 4.0.0\n */\n public position: ControlBarItemOptions[\"position\"];\n /**\n * Order within the same position.\n * The lowest one will be shown first.\n * @ko 동일한 position 내에서의 순서, 작을수록 먼저 표시됩니다.\n * @since 4.0.0\n */\n public order: ControlBarItemOptions[\"order\"];\n\n /**\n * Create new instance of the ControlBarItem\n * @ko ControlBarItem의 새로운 인스턴스를 생성합니다.\n * @param options Options {@ko 옵션들}\n */\n public constructor(options: ControlBarItemOptions) {\n this.position = options.position;\n this.order = options.order;\n }\n\n /**\n * Initialize item.\n * @ko 아이템을 초기화합니다.\n * @param viewer - A instance of viewer to attach item {@ko 아이템을 부착할 뷰어의 인스턴스}\n * @param controlBar - A instance of control bar to attach item {@ko 아이템을 부착할 컨트롤바의 인스턴스}\n * @since 4.0.0\n */\n public abstract init(viewer: View360, controlBar: ControlBar): any;\n /**\n * Destroy item and release all resources & event handlers.\n * @ko 아이템을 제거하고 할당된 모든 리소스 및 이벤트 핸들러를 제거합니다.\n * @param viewer - A instance of viewer to detach item {@ko 아이템을 떼어 낼 뷰어의 인스턴스}\n * @param controlBar - A instance of control bar to detach item {@ko 아이템을 떼어 낼 컨트롤바의 인스턴스}\n * @since 4.0.0\n */\n public abstract destroy(viewer: View360, controlBar: ControlBar): any;\n}\n\nexport default ControlBarItem;\n","export const CONTROL_BAR_DEFAULT_CLASS = {\n CONTROLS_ROOT: \"view360-controls\",\n CONTROLS_BG: \"view360-controls-background\",\n CONTROLS_MAIN: \"view360-controls-main\",\n CONTROLS_TOP: \"view360-controls-top\",\n CONTROLS_BOTTOM: \"view360-controls-bottom\",\n CONTROLS_MID: \"view360-controls-mid\",\n CONTROLS_LEFT: \"view360-controls-left\",\n CONTROLS_RIGHT: \"view360-controls-right\",\n CONTROLS_FLOAT_LEFT: \"view360-controls-float-left\",\n CONTROLS_FLOAT_RIGHT: \"view360-controls-float-right\",\n CONTROLS_BUTTON: \"view360-controls-button\",\n PROGRESS_ROOT: \"view360-controls-progress\",\n VOLUME_ROOT: \"view360-controls-volume\",\n RANGE_ROOT: \"view360-range\",\n RANGE_TRACK: \"view360-range-track\",\n RANGE_THUMB: \"view360-range-thumb\",\n RANGE_FILLER: \"view360-range-filler\",\n PLAY_BUTTON: \"view360-controls-play\",\n PAUSE_BUTTON: \"view360-controls-pause\",\n UNMUTED_BUTTON: \"view360-controls-unmuted\",\n MUTED_BUTTON: \"view360-controls-muted\",\n FULLSCREEN_BUTTON: \"view360-controls-fullscreen\",\n FULLSCREEN_EXIT_BUTTON: \"view360-controls-fullscreen-exit\",\n VR_BUTTON: \"view360-controls-vr\",\n GYRO_ENABLED: \"view360-controls-gyro-enabled\",\n GYRO_DISABLED: \"view360-controls-gyro-disabled\",\n VIDEO_TIME_DISPLAY: \"view360-controls-time\",\n PIEVIEW_ROOT: \"view360-controls-pie\",\n FIXED: \"view360-controls-fixed\",\n UNAVAILABLE: \"view360-controls-unavailable\",\n HIDDEN: \"view360-controls-hidden\"\n} as const;\n\nexport const CONTROL_BAR_ITEM_POSITION = {\n /**\n * Place control bar item floating at top-left corner\n * @ko 아이템을 왼쪽 위 구석에 표시합니다.\n * @since 4.0.0\n */\n TOP_LEFT: \"top-left\",\n /**\n * Place control bar item floating at top-right corner\n * @ko 아이템을 오른쪽 위 구석에 표시합니다.\n * @since 4.0.0\n */\n TOP_RIGHT: \"top-right\",\n /**\n * Place control bar item at upper block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 위쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_TOP: \"main-top\",\n /**\n * Place control bar item at lower block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 하단 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_BOTTOM: \"main-bottom\",\n /**\n * Place control bar item at center-left block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 왼쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_LEFT: \"main-left\",\n /**\n * Place control bar item at center-right block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 오른쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_RIGHT: \"main-right\"\n} as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { ControlBarOptions } from \"./ControlBar\";\nimport { CONTROL_BAR_DEFAULT_CLASS } from \"./const\";\nimport Motion from \"../../core/Motion\";\nimport MouseInput from \"../../control/input/MouseInput\";\nimport TouchInput from \"../../control/input/TouchInput\";\nimport { CONTROL_EVENTS, INFINITE_RANGE } from \"../../const/internal\";\nimport { clamp } from \"../../utils\";\nimport { InputEvents } from \"../../type/internal\";\nimport { EL_DIV } from \"../../const/browser\";\n\nclass RangeControl extends Component<{\n [CONTROL_EVENTS.INPUT_START]: number;\n [CONTROL_EVENTS.CHANGE]: number;\n [CONTROL_EVENTS.INPUT_END]: void;\n}> {\n public readonly rootEl: HTMLElement;\n public readonly thumbEl: HTMLElement;\n public readonly trackEl: HTMLElement;\n public readonly fillerEl: HTMLElement;\n\n private _motion: Motion;\n private _mouseInput: MouseInput;\n private _touchInput: TouchInput;\n private _fixedClass: string;\n private _bbox: DOMRect;\n\n /**\n *\n */\n public constructor() {\n super();\n\n const root = document.createElement(EL_DIV);\n const track = document.createElement(EL_DIV);\n const thumb = document.createElement(EL_DIV);\n const filler = document.createElement(EL_DIV);\n\n root.draggable = false;\n\n track.appendChild(filler);\n track.appendChild(thumb);\n root.appendChild(track);\n\n this.rootEl = root;\n this.trackEl = track;\n this.thumbEl = thumb;\n this.fillerEl = filler;\n\n this._mouseInput = new MouseInput();\n this._touchInput = new TouchInput();\n this._motion = new Motion({ duration: 1, range: INFINITE_RANGE, easing: x => x });\n this._bbox = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n left: 0,\n right: 0,\n bottom: 0,\n top: 0\n } as DOMRect;\n this._fixedClass = CONTROL_BAR_DEFAULT_CLASS.FIXED;\n }\n\n public init(className: Required) {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n\n this.rootEl.classList.add(className.RANGE_ROOT);\n this.trackEl.classList.add(className.RANGE_TRACK);\n this.thumbEl.classList.add(className.RANGE_THUMB);\n this.fillerEl.classList.add(className.RANGE_FILLER);\n this._fixedClass = className.FIXED;\n\n mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n touchInput.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n\n mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n touchInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n\n mouseInput.enable(this.rootEl);\n touchInput.enable(this.rootEl);\n\n this.resize();\n }\n\n public destroy() {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n\n this.rootEl.className = \"\";\n this.trackEl.className = \"\";\n this.thumbEl.className = \"\";\n this.fillerEl.className = \"\";\n\n mouseInput.off();\n touchInput.off();\n mouseInput.disable();\n touchInput.disable();\n }\n\n public resize() {\n this._bbox = this.trackEl.getBoundingClientRect();\n }\n\n public updateStyle(progress: number) {\n const width = this._bbox.width;\n const clampedProgress = clamp(progress, 0, 1);\n\n this.fillerEl.style.width = `${clampedProgress * 100}%`;\n this.thumbEl.style.transform = `translateX(${clampedProgress * width}px)`;\n }\n\n private _onHold = ({ srcEvent, isTouch }: InputEvents<{ x: number; y: number }>[typeof CONTROL_EVENTS.INPUT_START]) => {\n const bbox = this._bbox;\n if (!bbox) return;\n\n const x = isTouch\n ? (srcEvent as TouchEvent).touches[0].pageX\n : (srcEvent as MouseEvent).pageX;\n const elX = bbox.x + (window.scrollX ?? window.pageXOffset);\n\n const clamepdX = clamp(x, elX, elX + bbox.width);\n const progress = (clamepdX - elX) / bbox.width;\n\n this._motion.reset(clamepdX);\n this.thumbEl.classList.add(this._fixedClass);\n\n this.trigger(CONTROL_EVENTS.INPUT_START, progress);\n };\n\n private _onChange = ({ delta }: InputEvents<{ x: number; y: number }>[typeof CONTROL_EVENTS.CHANGE]) => {\n const motion = this._motion;\n const bbox = this._bbox;\n if (!bbox) return;\n\n motion.setNewEndByDelta(delta.x);\n motion.update(1);\n\n const elX = bbox.x + (window.scrollX ?? window.pageXOffset);\n const clampedX = clamp(motion.val, elX, elX + bbox.width);\n const progress = (clampedX - elX) / bbox.width;\n\n this.trigger(CONTROL_EVENTS.CHANGE, progress);\n };\n\n private _onRelease = () => {\n const bbox = this._bbox;\n if (!bbox) return;\n\n this.thumbEl.classList.remove(this._fixedClass);\n\n this.trigger(CONTROL_EVENTS.INPUT_END);\n };\n}\n\nexport default RangeControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport RangeControl from \"./RangeControl\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport { CONTROL_EVENTS, VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport { EVENTS } from \"../../const/external\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show video progress bar.\n * @ko 비디오의 프로그레스 바를 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass ProgressBar extends ControlBarItem {\n public get element() { return this._rangeControl.rootEl; }\n\n private _controlBar: ControlBar | null;\n private _video: TextureVideo | null;\n private _rangeControl: RangeControl;\n\n private _wasPaused: boolean;\n private _currentTime: number;\n private _duration: number;\n private _playPromise: Promise | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_TOP,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.position = position;\n this.order = order;\n\n this._controlBar = null;\n this._rangeControl = new RangeControl();\n\n this._video = null;\n this._wasPaused = false;\n this._currentTime = 0;\n this._duration = 0;\n this._playPromise = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const element = this.element;\n const rangeControl = this._rangeControl;\n const unavailableClass = controlBar.className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n element.classList.add(unavailableClass);\n return;\n }\n\n element.classList.remove(unavailableClass);\n element.classList.add(controlBar.className.PROGRESS_ROOT);\n viewer.on(EVENTS.RESIZE, this._onResize);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate);\n rangeControl.init(controlBar.className);\n rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n rangeControl.on(CONTROL_EVENTS.CHANGE, this._onControl);\n rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n this._video = video;\n this._currentTime = video.source.currentTime;\n this._duration = video.source.duration;\n this._controlBar = controlBar;\n\n rangeControl.updateStyle(this._currentTime / this._duration);\n }\n\n public destroy(viewer: View360) {\n const video = this._video;\n\n viewer.off(EVENTS.RESIZE, this._onResize);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate);\n }\n\n this._rangeControl.destroy();\n this._video = null;\n this._playPromise = null;\n }\n\n private _onResize = () => {\n this._rangeControl.resize();\n }\n\n private _onTimeUpdate = () => {\n const video = this._video;\n if (!video) return;\n\n this._currentTime = video.source.currentTime;\n this._rangeControl.updateStyle(this._currentTime / this._duration);\n };\n\n private _onDurationChange = () => {\n const video = this._video;\n if (!video) return;\n\n this._duration = video.source.duration;\n this._rangeControl.updateStyle(this._currentTime / this._duration);\n };\n\n private _onHold = (progress: number) => {\n const video = this._video;\n const controlBar = this._controlBar;\n if (!video || !controlBar) return;\n\n const paused = video.isPaused();\n\n video.source.pause();\n\n const time = video.source.duration * progress;\n video.source.currentTime = time;\n video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time }}));\n\n controlBar.rootEl.classList.add(controlBar.className.FIXED);\n this._wasPaused = !this._playPromise && paused;\n };\n\n private _onControl = (progress: number) => {\n const video = this._video;\n if (!video) return;\n\n const time = video.source.duration * progress;\n video.source.currentTime = time;\n video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time }}));\n };\n\n private _onRelease = () => {\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (video && controlBar) {\n if (!this._wasPaused && !this._playPromise) {\n this._playPromise = video.source.play()\n .catch(() => void 0);\n\n // This should not be chained\n this._playPromise.then(() => {\n this._playPromise = null;\n });\n\n controlBar.rootEl.classList.remove(controlBar.className.FIXED);\n }\n }\n\n this._wasPaused = false;\n };\n}\n\nexport default ProgressBar;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show video play / pause button.\n * @ko 비디오 재생 / 일시정지 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass PlayButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _controlBar: ControlBar | null;\n private _video: TextureVideo | null;\n private _paused: boolean;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n\n this._video = null;\n this._paused = true;\n this._controlBar = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const video = viewer.projection?.getTexture();\n const className = controlBar.className;\n const unavailableClass = className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n element.classList.add(unavailableClass);\n return;\n }\n\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.remove(unavailableClass);\n\n const paused = video.isPaused();\n this._video = video;\n this._paused = paused;\n this._controlBar = controlBar;\n\n if (paused) {\n this._onPause();\n } else {\n this._onPlay();\n }\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onPlay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onPause);\n }\n\n public destroy() {\n const video = this._video;\n const element = this.element;\n\n if (!video) return;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onPlay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onPause);\n\n this._video = null;\n this._paused = true;\n this._controlBar = null;\n }\n\n private _onClick = () => {\n const video = this._video;\n if (!video) return;\n\n if (this._paused) {\n video.source.play();\n } else {\n video.source.pause();\n }\n };\n\n private _onPlay = () => {\n if (!this._controlBar) return;\n\n const element = this.element;\n const className = this._controlBar.className;\n\n element.classList.add(className.PAUSE_BUTTON);\n element.classList.remove(className.PLAY_BUTTON);\n element.title = \"Pause Video\";\n\n this._paused = false;\n };\n\n private _onPause = () => {\n if (!this._controlBar) return;\n\n const element = this.element;\n const className = this._controlBar.className;\n\n element.classList.add(className.PLAY_BUTTON);\n element.classList.remove(className.PAUSE_BUTTON);\n element.title = \"Play Video\";\n\n this._paused = true;\n };\n}\n\nexport default PlayButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport RangeControl from \"./RangeControl\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { EVENTS } from \"../../const/external\";\n\n/**\n * Show video volume control.\n * @ko 비디오 볼륨 조절 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VolumeControl extends ControlBarItem {\n public get element() { return this._rootEl; }\n\n private _controlBar: ControlBar | null;\n private _rootEl: HTMLButtonElement;\n private _buttonEl: HTMLElement;\n private _rangeControl: RangeControl;\n private _video: TextureVideo | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this._controlBar = null;\n this._rangeControl = new RangeControl();\n this._createElements();\n\n this._video = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const root = this._rootEl;\n const button = this._buttonEl;\n const rangeControl = this._rangeControl;\n const className = controlBar.className;\n const unavailableClass = className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n root.classList.add(unavailableClass);\n return;\n }\n\n root.classList.remove(unavailableClass);\n root.classList.add(className.CONTROLS_BUTTON);\n root.classList.add(className.VOLUME_ROOT);\n button.classList.add(className.CONTROLS_BUTTON);\n\n if (video.source.muted) {\n button.classList.add(className.MUTED_BUTTON);\n } else {\n button.classList.add(className.UNMUTED_BUTTON);\n }\n\n viewer.on(EVENTS.RESIZE, this._onResize);\n root.addEventListener(BROWSER.EVENTS.TRANSITION_END, this._onResize);\n button.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_VOLUME_CHANGE, this._onVolumeChange);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_LOADED_DATA, this._updateDisplay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay);\n\n rangeControl.init(className);\n rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n rangeControl.on(CONTROL_EVENTS.CHANGE, this._onChange);\n rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n this._controlBar = controlBar;\n this._video = video;\n\n this._updateDisplay();\n }\n\n public destroy(viewer: View360) {\n const video = this._video;\n const button = this._buttonEl;\n const root = this._rootEl;\n\n root.className = \"\";\n button.className = \"\";\n\n viewer.off(EVENTS.RESIZE, this._onResize);\n root.removeEventListener(BROWSER.EVENTS.TRANSITION_END, this._onResize);\n button.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_VOLUME_CHANGE, this._onVolumeChange);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_LOADED_DATA, this._updateDisplay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay);\n }\n\n this._controlBar = null;\n this._rangeControl.destroy();\n this._video = null;\n }\n\n private _onResize = () => {\n this._rangeControl.resize();\n this._updateDisplay();\n }\n\n private _onClick = () => {\n const video = this._video;\n if (!video || this._rootEl.disabled) return;\n\n video.source.muted = !video.source.muted;\n };\n\n private _onVolumeChange = () => {\n const button = this._buttonEl;\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (!video || !controlBar) return;\n\n const className = controlBar.className;\n\n if (video.source.muted || video.source.volume === 0) {\n button.classList.add(className.MUTED_BUTTON);\n button.classList.remove(className.UNMUTED_BUTTON);\n } else {\n button.classList.add(className.UNMUTED_BUTTON);\n button.classList.remove(className.MUTED_BUTTON);\n }\n\n this._updateDisplay();\n };\n\n private _createElements() {\n const root = document.createElement(BROWSER.EL_BUTTON);\n const buttonEl = document.createElement(BROWSER.EL_DIV);\n\n root.appendChild(this._rangeControl.rootEl);\n root.appendChild(buttonEl);\n root.title = \"Toggle Mute\";\n\n this._rootEl = root;\n this._buttonEl = buttonEl;\n }\n\n private _onHold = (progress: number) => {\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (!video || !controlBar) return;\n\n const className = controlBar.className;\n\n video.source.volume = progress;\n\n this._rootEl.classList.add(className.FIXED);\n controlBar.containerEl.classList.add(className.FIXED);\n\n this._updateDisplay();\n };\n\n private _onChange = (progress: number) => {\n const video = this._video;\n if (!video) return;\n\n video.source.volume = progress;\n if (progress > 0) {\n video.source.muted = false;\n } else {\n video.source.muted = true;\n }\n\n this._updateDisplay();\n };\n\n private _onRelease = () => {\n const controlBar = this._controlBar;\n if (!controlBar) return;\n\n const className = controlBar.className;\n\n this._rootEl.classList.remove(className.FIXED);\n controlBar.containerEl.classList.remove(className.FIXED);\n };\n\n private _updateDisplay = () => {\n const video = this._video;\n const root = this._rootEl;\n if (!video) return;\n\n if (!video.hasAudio()) {\n root.disabled = true;\n return;\n }\n\n root.disabled = false;\n\n const volume = video.source.muted ? 0 : video.source.volume;\n\n this._rangeControl.updateStyle(volume);\n };\n}\n\nexport default VolumeControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport { isFullscreen } from \"../../utils\";\n\n/**\n * Show fullscreen enter / exit button.\n * @ko 풀스크린 진입 / 해제 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass FullscreenButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _controlBar: ControlBar | null;\n private _targetEl: HTMLElement | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n this.element.title = \"Toggle Fullscreen\";\n this._controlBar = null;\n this._targetEl = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n if (!this._fullscreenAvailable()) {\n element.classList.add(className.UNAVAILABLE);\n return;\n }\n\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.remove(className.UNAVAILABLE);\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._addFullscreenHandlers();\n\n if (isFullscreen()) {\n element.classList.add(className.FULLSCREEN_EXIT_BUTTON);\n } else {\n element.classList.add(className.FULLSCREEN_BUTTON);\n }\n\n this._controlBar = controlBar;\n this._targetEl = viewer.rootEl;\n }\n\n public destroy() {\n const element = this.element;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._removeFullscreenHandlers();\n\n this._controlBar = null;\n this._targetEl = null;\n }\n\n private _onClick = () => {\n const target = this._targetEl;\n if (!target) return;\n\n if (isFullscreen()) {\n this._exitFullscreen();\n } else {\n this._requestFullscreen(target);\n }\n };\n\n private _fullscreenAvailable() {\n return BROWSER.FULLSCREEN_REQUEST.some(key => !!document[key]);\n }\n\n private _requestFullscreen(el: HTMLElement) {\n for (const key of BROWSER.FULLSCREEN_REQUEST) {\n const request = el[key];\n if (request) {\n request.call(el);\n return;\n }\n }\n }\n\n private _exitFullscreen() {\n for (const key of BROWSER.FULLSCREEN_EXIT) {\n const exit = document[key];\n\n if (exit) {\n exit.call(document);\n return;\n }\n }\n }\n\n private _addFullscreenHandlers() {\n BROWSER.FULLSCREEN_CHANGE.forEach(evtName => {\n document.addEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _removeFullscreenHandlers() {\n BROWSER.FULLSCREEN_CHANGE.forEach(evtName => {\n document.removeEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _onFullscreenChange = () => {\n const element = this.element;\n const controlBar = this._controlBar;\n\n if (!controlBar) return;\n\n const className = controlBar.className;\n\n if (isFullscreen()) {\n element.classList.add(className.FULLSCREEN_EXIT_BUTTON);\n element.classList.remove(className.FULLSCREEN_BUTTON);\n } else {\n element.classList.add(className.FULLSCREEN_BUTTON);\n element.classList.remove(className.FULLSCREEN_EXIT_BUTTON);\n }\n };\n}\n\nexport default FullscreenButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\n\n/**\n * Show video current / total time.\n * @ko 비디오의 현재 / 총 재생시간을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VideoTime extends ControlBarItem {\n public readonly element: HTMLElement;\n private _video: TextureVideo | null;\n private _currentTime: number;\n private _duration: number;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n\n this._video = null;\n this._currentTime = 0;\n this._duration = 0;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const element = this.element;\n const className = controlBar.className;\n\n if (!video || !video.isVideo()) {\n element.classList.add(className.UNAVAILABLE);\n return;\n }\n\n element.classList.add(className.VIDEO_TIME_DISPLAY);\n element.classList.remove(className.UNAVAILABLE);\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange);\n\n this._video = video;\n this._currentTime = video.source.currentTime;\n this._duration = video.source.duration;\n\n this._updateDisplay();\n }\n\n public destroy() {\n const video = this._video;\n\n if (!video) return;\n\n this.element.className = \"\";\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange);\n\n this._video = null;\n }\n\n private _onTimeUpdate = () => {\n const video = this._video;\n if (!video) return;\n\n this._currentTime = video.source.currentTime;\n this._updateDisplay();\n };\n\n private _onDurationChange = () => {\n const video = this._video;\n if (!video) return;\n\n this._duration = video.source.duration;\n this._updateDisplay();\n };\n\n private _onCustomTimeChange = (evt: CustomEvent<{ time: number }>) => {\n this._currentTime = evt.detail.time;\n this._updateDisplay();\n };\n\n private _updateDisplay() {\n const time = this._currentTime;\n const timeMinute = Math.floor(time / 60);\n const timeSeconds = Math.floor(time - timeMinute * 60);\n const timeSecondsFormatted = timeSeconds < 10 ? `0${timeSeconds}` : timeSeconds;\n\n const duration = this._duration;\n const durationMinute = Math.floor(duration / 60);\n const durationSeconds = Math.floor(duration - durationMinute * 60);\n const durationSecondsFormatted = durationSeconds < 10 ? `0${durationSeconds}` : durationSeconds;\n\n this.element.innerText = `${timeMinute}:${timeSecondsFormatted} / ${durationMinute}:${durationSecondsFormatted}`;\n }\n}\n\nexport default VideoTime;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport { circulate, getObjectOption } from \"../../utils\";\nimport * as BROWSER from \"../../const/browser\";\nimport { EVENTS } from \"../../const/external\";\nimport { SVG_NAMESPACE } from \"../../const/internal\";\n\n/**\n * Options for {@link PieView}\n * @ko {@link PieView}용 옵션들\n * @category Plugin\n */\nexport interface PieViewOptions extends ControlBarItemOptions {\n /**\n * @copy PieView#resetCamera\n */\n resetCamera: boolean | Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n duration: number;\n easing: (x: number) => number;\n }>;\n}\n\n/**\n * Show camera direction/fov indicator.\n * @ko 카메라가 향하는 방향 및 FOV를 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass PieView extends ControlBarItem {\n public readonly element: HTMLElement;\n\n /**\n * Set rotation to reset camera to when PieView is clicked.\n * `false` will disable this value, and `true` will enable with default options.\n * @ko PieView가 클릭되었을 때 카메라를 리셋할 방향을 지정합니다.\n * `false`일 경우 이 동작을 비활성화하며, `true`일 경우 기본값을 사용합니다.\n * @since 4.0.0\n */\n public resetCamera: PieViewOptions[\"resetCamera\"];\n\n private _viewer: View360 | null;\n private _piePathEl: SVGPathElement;\n private _rangeCircleEl: SVGCircleElement;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n resetCamera = true,\n position = CONTROL_BAR_ITEM_POSITION.TOP_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n this.element.title = \"Reset view\";\n this.resetCamera = resetCamera;\n this._createPieElements();\n this._viewer = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n\n if (!viewer.initialized) {\n viewer.once(EVENTS.READY, this._updatePie);\n } else {\n this._updatePie({ target: viewer });\n }\n\n const rootClass = controlBar.className.PIEVIEW_ROOT;\n element.classList.add(rootClass);\n\n if (this.resetCamera) {\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n }\n\n viewer.on(EVENTS.VIEW_CHANGE, this._updatePie);\n\n this._viewer = viewer;\n }\n\n public destroy(viewer: View360) {\n const element = this.element;\n\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.className = \"\";\n viewer.off(EVENTS.READY, this._updatePie);\n viewer.off(EVENTS.VIEW_CHANGE, this._updatePie);\n\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n const resetCamera = this.resetCamera;\n\n if (!viewer || !resetCamera) return;\n\n const {\n yaw = viewer.initialYaw,\n pitch = viewer.initialPitch,\n zoom = viewer.initialZoom,\n duration = 500\n } = getObjectOption(resetCamera);\n\n viewer.camera.animateTo({\n yaw,\n pitch,\n zoom,\n duration\n });\n };\n\n private _createPieElements() {\n const root = this.element;\n const pieSVG = document.createElementNS(SVG_NAMESPACE, \"svg\");\n pieSVG.setAttribute(\"viewBox\", \"0 0 48 48\");\n pieSVG.setAttribute(\"width\", \"100%\");\n pieSVG.setAttribute(\"height\", \"100%\");\n\n const piePath = document.createElementNS(SVG_NAMESPACE, \"circle\");\n\n piePath.setAttribute(\"stroke\", \"currentColor\");\n piePath.setAttribute(\"fill\", \"transparent\");\n piePath.setAttribute(\"cx\", \"24\");\n piePath.setAttribute(\"cy\", \"24\");\n piePath.setAttribute(\"r\", \"12\");\n piePath.setAttribute(\"stroke-width\", \"24\");\n pieSVG.appendChild(piePath);\n\n const rangeCircle = document.createElementNS(SVG_NAMESPACE, \"circle\");\n\n rangeCircle.setAttribute(\"stroke\", \"currentColor\");\n rangeCircle.setAttribute(\"fill\", \"transparent\");\n rangeCircle.setAttribute(\"cx\", \"24\");\n rangeCircle.setAttribute(\"cy\", \"24\");\n rangeCircle.setAttribute(\"r\", \"22.5\");\n rangeCircle.setAttribute(\"stroke-width\", \"3\");\n pieSVG.appendChild(rangeCircle);\n\n root.appendChild(pieSVG);\n\n this._piePathEl = piePath;\n this._rangeCircleEl = rangeCircle;\n }\n\n private _updatePie = ({ target: viewer }: { target: View360 }) => {\n const piePath = this._piePathEl;\n const rangeCircle = this._rangeCircleEl;\n const camera = viewer.camera;\n const fov = camera.getHorizontalFov();\n const yawRange = camera.getYawRange(camera.zoom);\n const halfFov = fov * 0.5;\n\n const pieRadius = 24 * Math.PI;\n const pieDeg = pieRadius * fov / 360;\n const pieOffset = pieRadius * (camera.yaw + halfFov + 90) / 360;\n\n piePath.setAttribute(\"stroke-dasharray\", `${pieDeg} ${pieRadius - pieDeg}`);\n piePath.setAttribute(\"stroke-dashoffset\", `${pieOffset}`);\n\n if (isFinite(yawRange.min) && isFinite(yawRange.max)) {\n const radius = 45 * Math.PI; // 2 * PI * r\n const min = (circulate(yawRange.min, -180, 180) - halfFov) / 360;\n const max = (circulate(yawRange.max, -180, 180) + halfFov) / 360;\n\n const rangeDiff = radius * Math.abs(max - min);\n const offset = -radius * (min - 0.25);\n\n rangeCircle.setAttribute(\"stroke-dasharray\", `${rangeDiff} ${radius - rangeDiff}`);\n rangeCircle.setAttribute(\"stroke-dashoffset\", `${offset}`);\n } else {\n rangeCircle.setAttribute(\"stroke-dasharray\", \"\");\n rangeCircle.setAttribute(\"stroke-dashoffset\", \"\");\n }\n };\n}\n\nexport default PieView;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show VR enter button.\n * @ko VR 진입 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VRButton extends ControlBarItem {\n public readonly element: HTMLElement;\n\n private _viewer: View360 | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n this.element.title = \"Enter VR\";\n this._viewer = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n element.classList.add(className.UNAVAILABLE);\n element.classList.add(className.VR_BUTTON);\n element.classList.add(className.CONTROLS_BUTTON);\n\n viewer.vr.isAvailable()\n .then(available => {\n if (available) {\n element.classList.remove(className.UNAVAILABLE);\n }\n });\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._viewer = viewer;\n }\n\n public destroy() {\n const element = this.element;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n if (!viewer) return;\n\n viewer.vr.enter();\n };\n}\n\nexport default VRButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport GyroControl from \"../../control/GyroControl\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { sensorCanBeEnabledIOS } from \"../../utils\";\n\n/**\n * Show gyroscope control enable / disable button\n * @ko 자이로스코프 컨트롤 활성화 / 비활성화 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass GyroButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _viewer: View360 | null;\n private _controlBar: ControlBar | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n this.element.title = \"Toggle gyroscope control\";\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.add(className.UNAVAILABLE);\n\n const enableButton = () => {\n element.classList.remove(className.UNAVAILABLE);\n viewer.control.gyro.on(CONTROL_EVENTS.ENABLE, this._updateStyle);\n viewer.control.gyro.on(CONTROL_EVENTS.DISABLE, this._updateStyle);\n };\n\n if (sensorCanBeEnabledIOS()) {\n enableButton();\n } else {\n GyroControl.isAvailable().then(available => {\n if (!available) return;\n enableButton();\n });\n }\n\n this._controlBar = controlBar;\n this._viewer = viewer;\n this._updateStyle();\n }\n\n public destroy(viewer: View360) {\n const element = this.element;\n\n viewer.control.gyro.off(CONTROL_EVENTS.ENABLE, this._updateStyle);\n viewer.control.gyro.off(CONTROL_EVENTS.DISABLE, this._updateStyle);\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.className = \"\";\n\n this._controlBar = null;\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n const controlBar = this._controlBar;\n\n if (!viewer || !controlBar) return;\n\n const gyroControl = viewer.control.gyro;\n if (gyroControl.enabled) {\n gyroControl.disable();\n } else {\n GyroControl.requestSensorPermission().then(available => {\n if (available) {\n gyroControl.enable();\n } else {\n this.element.classList.add(controlBar.className.UNAVAILABLE);\n }\n });\n }\n };\n\n private _updateStyle = () => {\n const element = this.element;\n const viewer = this._viewer;\n const controlBar = this._controlBar;\n\n if (!viewer || !controlBar) return;\n\n const gyroControl = viewer.control.gyro;\n const className = controlBar.className;\n\n if (gyroControl.enabled) {\n element.classList.add(className.GYRO_ENABLED);\n element.classList.remove(className.GYRO_DISABLED);\n } else {\n element.classList.add(className.GYRO_DISABLED);\n element.classList.remove(className.GYRO_ENABLED);\n }\n };\n}\n\nexport default GyroButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport { FULLSCREEN_CHANGE } from \"../../const/browser\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport { isFullscreen } from \"../../utils\";\n\n/**\n * Options for ControlBar's {@link ControlBarOptions#autoHide}\n * @ko ControlBar의 {@link ControlBarOptions#autoHide}용 옵션\n * @category Plugin\n * @since 4.0.0\n */\nexport interface AutoHideOptions {\n /**\n * Initial delay before the control bar hides (ms)\n * @ko 컨트롤바가 처음으로 표시되고 사라지기까지 걸리는 시간 (ms)\n * @default 3000\n * @since 4.0.0\n */\n initialDelay: number;\n /**\n * Delay time before hiding the control bar after mouse leave (ms)\n * @ko 마우스가 컨트롤바 영역을 떠난 뒤 컨트롤바가 사라지기까지 걸리는 시간 (ms)\n * @default 0\n * @since 4.0.0\n */\n delay: number;\n /**\n * Delay time before hiding the control bar becomes active, like touch on mobile device or mouse move in fullscreen mode (ms)\n * @ko 모바일이나 풀스크린 환경 등에서 사용자 입력이 없을 때 컨트롤바가 사라지기까지 걸리는 시간 (ms)\n * @default 3000\n * @since 4.0.0\n */\n idleDelay: number;\n}\n\nclass AutoHide {\n private _initialDelay: AutoHideOptions[\"initialDelay\"];\n private _delay: AutoHideOptions[\"delay\"];\n private _idleDelay: AutoHideOptions[\"idleDelay\"];\n\n private _controlBar: ControlBar;\n private _timer: number;\n private _isGrabbing: boolean;\n private _isCursorInside: boolean;\n private _isFullscreen: boolean;\n private _targetEl: HTMLElement | null;\n private _video: TextureVideo | null;\n\n public get enabled() { return !!this._targetEl; }\n public get hidden() { return this._controlBar.containerEl.classList.contains(this._hiddenClass); }\n\n private get _hiddenClass() { return this._controlBar.className.HIDDEN; }\n private get _fixedClass() { return this._controlBar.className.FIXED; }\n\n public constructor(controlBar: ControlBar, {\n initialDelay = 3000,\n delay = 0,\n idleDelay: activationDelay = 3000\n }: Partial) {\n this._controlBar = controlBar;\n this._initialDelay = initialDelay;\n this._delay = delay;\n this._idleDelay = activationDelay;\n this._timer = -1;\n this._isCursorInside = false;\n this._isGrabbing = false;\n this._isFullscreen = false;\n this._video = null;\n this._targetEl = null;\n }\n\n public enable(viewer: View360) {\n if (this._targetEl) {\n this.disable(viewer);\n }\n\n const initialDelay = this._initialDelay;\n const root = viewer.rootEl;\n\n this._targetEl = viewer.rootEl;\n this._timer = window.setTimeout(() => {\n this.hide();\n }, initialDelay);\n\n root.addEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onHold);\n root.addEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter);\n root.addEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove);\n root.addEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave);\n this._addFullscreenHandlers();\n\n const video = viewer.projection?.getTexture();\n if (!video || !video.isVideo()) {\n return;\n }\n\n if (video.isPaused()) {\n this._controlBar.containerEl.classList.add(this._fixedClass);\n }\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onVideoPlay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onVideoPause);\n\n this._video = video;\n }\n\n public disable(viewer: View360) {\n if (!this._targetEl) return;\n\n const controlBar = this._controlBar;\n const root = viewer.rootEl;\n const video = this._video;\n\n root.removeEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onHold);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave);\n this._removeFullscreenHandlers();\n\n window.clearTimeout(this._timer);\n controlBar.containerEl.classList.remove(this._fixedClass);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onVideoPlay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onVideoPause);\n }\n\n this._isCursorInside = false;\n this._isGrabbing = false;\n this._video = null;\n this._targetEl = null;\n }\n\n public show() {\n this._clearHideTimer();\n this._controlBar.containerEl.classList.remove(this._hiddenClass);\n }\n\n public showTemporaliy() {\n this.show();\n this._hideAfterDelay(this._idleDelay);\n }\n\n public hide() {\n this._clearHideTimer();\n this._controlBar.containerEl.classList.add(this._hiddenClass);\n }\n\n private _clearHideTimer() {\n if (this._timer) {\n window.clearTimeout(this._timer);\n this._timer = -1;\n }\n }\n\n private _hideAfterDelay(delay = this._delay) {\n if (this._isGrabbing || (!this._isFullscreen && this._isCursorInside)) return;\n\n this._clearHideTimer();\n if (delay <= 0) {\n this.hide();\n } else {\n this._timer = window.setTimeout(() => {\n this.hide();\n }, delay);\n }\n }\n\n private _onMouseEnter = () => {\n this._isCursorInside = true;\n this.show();\n };\n\n private _onMouseLeave = () => {\n this._isCursorInside = false;\n this._hideAfterDelay();\n };\n\n private _onMouseMove = () => {\n if (!this._isFullscreen) return;\n\n this.showTemporaliy();\n }\n\n private _onHold = (evt: PointerEvent) => {\n this._isGrabbing = true;\n\n if (evt.pointerType === \"mouse\") {\n this._isCursorInside = true;\n }\n\n window.addEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n\n this.show();\n };\n\n private _onRelease = () => {\n this._isGrabbing = false;\n\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n\n this._hideAfterDelay();\n };\n\n private _onVideoPlay = () => {\n const root = this._targetEl;\n if (!root) return;\n\n this._controlBar.containerEl.classList.remove(this._fixedClass);\n };\n\n private _onVideoPause = () => {\n const root = this._targetEl;\n if (!root) return;\n\n this._controlBar.containerEl.classList.add(this._fixedClass);\n };\n\n private _addFullscreenHandlers() {\n FULLSCREEN_CHANGE.forEach(evtName => {\n document.addEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _removeFullscreenHandlers() {\n FULLSCREEN_CHANGE.forEach(evtName => {\n document.removeEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _onFullscreenChange = () => {\n this._isFullscreen = isFullscreen();\n\n if (this._isFullscreen) {\n this._hideAfterDelay();\n }\n };\n}\n\nexport default AutoHide;\n","import TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { clamp } from \"../../utils\";\nimport { VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\n\nclass VideoControl {\n private _video: TextureVideo | null;\n\n public enable(root: HTMLElement, video: TextureVideo) {\n this._video = video;\n // capture is needed for resolving conflict with keyboard control\n root.addEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown, true);\n }\n\n public disable(root: HTMLElement) {\n this._video = null;\n root.removeEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown, true);\n }\n\n private _onKeyDown = (event: KeyboardEvent) => {\n const video = this._video;\n if (!video) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n const videoEl = video.source;\n const keyPressed = event.keyCode != null\n ? BROWSER.DIRECTION_KEY_CODE[event.keyCode]\n : BROWSER.DIRECTION_KEY_NAME[event.key];\n\n switch (keyPressed) {\n case \"LEFT\":\n case \"RIGHT\":\n return this._changeVideoTime(videoEl, keyPressed === \"RIGHT\");\n case \"UP\":\n case \"DOWN\":\n return this._changeVideoVolume(videoEl, keyPressed === \"UP\");\n }\n\n const spacePressed = event.keyCode === BROWSER.SPACE_KEY_CODE || event.key === BROWSER.SPACE_KEY_NAME;\n if (spacePressed) {\n this._toggleVideo(video);\n }\n }\n\n private _changeVideoTime(video: HTMLVideoElement, forward: boolean) {\n const delta = forward ? 5 : -5;\n\n video.currentTime += delta;\n video.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time: video.currentTime }}));\n }\n\n private _changeVideoVolume(video: HTMLVideoElement, increase: boolean) {\n const delta = increase ? 0.1 : -0.1;\n\n if (video.muted) {\n video.volume = clamp(delta, 0, 1);\n } else {\n video.volume = clamp(video.volume + delta, 0, 1);\n }\n\n if (video.volume > 0) {\n video.muted = false;\n } else {\n video.muted = true;\n }\n }\n\n private _toggleVideo(video: TextureVideo) {\n if (video.isPaused()) {\n video.source.play();\n } else {\n video.source.pause();\n }\n }\n}\n\nexport default VideoControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport ProgressBar from \"./ProgressBar\";\nimport PlayButton from \"./PlayButton\";\nimport VolumeControl from \"./VolumeControl\";\nimport FullscreenButton from \"./FullscreenButton\";\nimport VideoTime from \"./VideoTime\";\nimport PieView, { PieViewOptions } from \"./PieView\";\nimport VRButton from \"./VRButton\";\nimport GyroButton from \"./GyroButton\";\nimport AutoHide, { AutoHideOptions } from \"./AutoHide\";\nimport VideoControl from \"./VideoControl\";\nimport View360, { View360Events } from \"../../View360\";\nimport View360Plugin from \"../View360Plugin\";\nimport { EVENTS } from \"../../const/external\";\nimport { createElement, findIndex, getObjectOption } from \"../../utils\";\nimport { ValueOf } from \"../../type/utils\";\nimport { StaticClickEvent } from \"../../type/events\";\nimport { CONTROL_BAR_DEFAULT_CLASS, CONTROL_BAR_ITEM_POSITION } from \"./const\";\n\n/**\n * Options for {@link ControlBar}\n * @ko {@link ControlBar}용 옵션들\n * @category Plugin\n * @since 4.0.0\n */\nexport interface ControlBarOptions {\n /**\n * @copy ControlBar#autoHide\n */\n autoHide: boolean | Partial;\n /**\n * @copy ControlBar#showBackground\n */\n showBackground: boolean;\n /**\n * @copy ControlBar#clickToPlay\n */\n clickToPlay: boolean;\n /**\n * @copy ControlBar#keyboardControls\n */\n keyboardControls: boolean;\n /**\n * @copy ControlBar#progressBar\n */\n progressBar: boolean | Partial;\n /**\n * @copy ControlBar#playButton\n */\n playButton: boolean | Partial;\n /**\n * @copy ControlBar#volumeButton\n */\n volumeButton: boolean | Partial;\n /**\n * @copy ControlBar#fullscreenButton\n */\n fullscreenButton: boolean | Partial;\n /**\n * @copy ControlBar#videoTime\n */\n videoTime: boolean | Partial;\n /**\n * @copy ControlBar#pieView\n */\n pieView: boolean | Partial;\n /**\n * @copy ControlBar#vrButton\n */\n vrButton: boolean | Partial;\n /**\n * @copy ControlBar#gyroButton\n */\n gyroButton: boolean | Partial;\n /**\n * @copy ControlBar#className\n */\n className: Partial<{ -readonly [key in keyof typeof ControlBar.DEFAULT_CLASS]: string }>;\n /**\n * @copy ControlBar#customItems\n */\n customItems: ControlBarItem[];\n}\n\n/**\n * A plugin that displays extra buttons & controls that controls {@link View360}.\n * @ko {@link View360}에 부가적인 버튼과 컨트롤을 추가해주는 플러그인.\n * @category Plugin\n * @since 4.0.0\n */\nclass ControlBar implements View360Plugin {\n /**\n * Default class names that ControlBar uses\n * @ko ControlBar가 사용하는 디폴트 클래스 이름들\n * @since 4.0.0\n */\n public static readonly DEFAULT_CLASS = CONTROL_BAR_DEFAULT_CLASS;\n\n /**\n * Constants for {@link ControlBarItemOptions#position}\n * @ko {@link ControlBarItemOptions#position}에 사용 가능한 값들\n */\n public static readonly POSITION = CONTROL_BAR_ITEM_POSITION;\n\n /**\n * Automatically hide control bar on video plays.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 재생시 자동으로 컨트롤바를 숨깁니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly autoHide?: ControlBarOptions[\"autoHide\"];\n /**\n * Show background element.\n * @ko 배경 엘리먼트를 표시합니다.\n * @since 4.0.0\n */\n public readonly showBackground?: ControlBarOptions[\"showBackground\"];\n /**\n * Whether to play / pause video on canvas click\n * @ko 캔버스 클릭시에 비디오를 재생 / 일시정지 토글합니다.\n * @since 4.0.0\n */\n public readonly clickToPlay: ControlBarOptions[\"clickToPlay\"];\n /**\n * Enable keyboard controls for video.\n * Pressing up / down arrow will control video volume, and pressing left / right arrow will control video time.\n * @ko 비디오 키보드 컨트롤을 활성화합니다.\n * 위 / 아래 화살표키를 누를 시 비디오 볼륨을, 왼쪽 / 오른쪽 화살표키를 누를 시 비디오 시간을 조정합니다.\n * @since 4.0.0\n */\n public readonly keyboardControls: ControlBarOptions[\"keyboardControls\"];\n /**\n * Show video progress bar.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 프로그레스 바를 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly progressBar: ControlBarOptions[\"progressBar\"];\n /**\n * Show video play / pause button.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 재생 / 일시정지 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly playButton: ControlBarOptions[\"playButton\"];\n /**\n * Show video volume control button.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 볼륨 조절 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly volumeButton: ControlBarOptions[\"volumeButton\"];\n /**\n * Show fullscreen button.\n * `true` to enable with default values, `false` to disable.\n * @ko 풀스크린 진입 / 해제 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly fullscreenButton: ControlBarOptions[\"fullscreenButton\"];\n /**\n * Show video current / total time\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오의 현재 시간 / 총 시간을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly videoTime: ControlBarOptions[\"videoTime\"];\n /**\n * Show camera pie view.\n * `true` to enable with default values, `false` to disable.\n * @ko 현재 카메라가 가리키는 방향을 표시하는 파이 뷰를 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly pieView: ControlBarOptions[\"pieView\"];\n /**\n * Show VR button.\n * `true` to enable with default values, `false` to disable.\n * @ko VR 진입버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly vrButton: ControlBarOptions[\"vrButton\"];\n /**\n * Show gyroscope control enable / disable button.\n * `true` to enable with default values, `false` to disable.\n * @ko 자이로스코프 컨트롤을 활성화 / 비활성화하는 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly gyroButton: ControlBarOptions[\"gyroButton\"];\n /**\n * Override default class names.\n * @ko 디폴트 클래스 이름들을 오버라이드합니다.\n * @since 4.0.0\n */\n public readonly className: Required;\n\n /**\n * Root element of the control bar\n * @ko 컨트롤바의 루트 엘리먼트\n * @since 4.0.0\n */\n public get rootEl() { return this._rootEl; }\n /**\n * Container element of the control bar\n * @ko 컨트롤바의 컨테이너 엘리먼트\n * @since 4.0.0\n */\n public get containerEl() { return this._containerEl; }\n /**\n * Background element of the control bar\n * @ko 컨트롤바의 배경 엘리먼트\n * @since 4.0.0\n */\n public get backgroundEl() { return this._bgEl; }\n /**\n * Control bar's default items created by {@link ControlBarOptions}\n * @ko 주어진 {@link ControlBarOptions}에 의해 생성된 디폴트 아이템들\n * @since 4.0.0\n */\n public get items() { return this._items; }\n /**\n * Custom control bar items\n * @ko 커스텀 컨트롤바 아이템들을 추가합니다.\n * @since 4.0.0\n */\n public get customItems() { return this._customItems; }\n\n private _rootEl: HTMLElement;\n private _containerEl: HTMLElement;\n private _bgEl: HTMLElement;\n private _wrapperEl: Record, HTMLElement>;\n private _items: Record, ControlBarItem[]>;\n private _customItems: ControlBarItem[];\n private _autoHider: AutoHide;\n private _videoControl: VideoControl;\n\n /**\n * Create new instance of ControlBar.\n * @ko ControlBar의 새 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n autoHide,\n showBackground,\n clickToPlay = true,\n keyboardControls = true,\n progressBar = true,\n playButton = true,\n volumeButton = true,\n fullscreenButton = true,\n videoTime = true,\n pieView = true,\n vrButton = true,\n gyroButton = true,\n className = {},\n customItems = []\n }: Partial = {}) {\n this.autoHide = autoHide;\n this.showBackground = showBackground;\n this.clickToPlay = clickToPlay;\n this.keyboardControls = keyboardControls;\n this.progressBar = progressBar;\n this.playButton = playButton;\n this.volumeButton = volumeButton;\n this.fullscreenButton = fullscreenButton;\n this.videoTime = videoTime;\n this.pieView = pieView;\n this.vrButton = vrButton;\n this.gyroButton = gyroButton;\n this.className = {\n ...ControlBar.DEFAULT_CLASS,\n ...className\n };\n\n const rootClass = className.CONTROLS_ROOT ?? ControlBar.DEFAULT_CLASS.CONTROLS_ROOT;\n\n this._rootEl = createElement(rootClass);\n this._createPositionWrappers();\n this._items = Object.keys(ControlBar.POSITION).reduce((items, key) => {\n items[ControlBar.POSITION[key]] = [];\n return items;\n }, {}) as Record, ControlBarItem[]>;\n this._customItems = customItems;\n this._autoHider = new AutoHide(this, getObjectOption(autoHide));\n this._videoControl = new VideoControl();\n\n customItems.forEach(item => {\n this._items[item.position].push(item);\n });\n }\n\n public init(viewer: View360) {\n const panoRoot = viewer.rootEl;\n const controlsRoot = this._rootEl;\n const defaultItems = this._createDefaultItems();\n\n this._updateBackground(viewer);\n this._updateAutoHide(viewer);\n this._updateKeyboardHandler(viewer);\n\n panoRoot.appendChild(controlsRoot);\n this._addItem(viewer, defaultItems);\n this._addItem(viewer, this._customItems);\n\n viewer.on(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad);\n viewer.on(EVENTS.STATIC_CLICK, this._onStaticClick);\n }\n\n public destroy(viewer: View360): void {\n // Remove controls root from pano root\n const panoRoot = viewer.rootEl;\n const controlsRoot = this._rootEl;\n const items = this._items;\n\n if (controlsRoot.parentElement === panoRoot) {\n panoRoot.removeChild(controlsRoot);\n }\n\n Object.keys(items).forEach((key: ValueOf) => {\n const category = items[key];\n\n category.forEach(item => {\n item.destroy(viewer, this);\n });\n\n items[key] = [];\n });\n\n this._clearItemElements();\n this._autoHider.disable(viewer);\n this._videoControl.disable(panoRoot);\n\n viewer.off(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad);\n viewer.off(EVENTS.STATIC_CLICK, this._onStaticClick);\n }\n\n private _addItem(viewer: View360, items: ControlBarItem[]) {\n for (const item of items) {\n const category = this._items[item.position];\n const wrapper = this._wrapperEl[item.position];\n\n const nextSiblingIndex = findIndex(category, sibling => sibling.order > item.order);\n\n if (nextSiblingIndex >= 0) {\n const nextSibling = category[nextSiblingIndex].element;\n category.splice(nextSiblingIndex, 0, item);\n wrapper.insertBefore(item.element, nextSibling);\n } else {\n category.push(item);\n wrapper.appendChild(item.element);\n }\n\n item.init(viewer, this);\n }\n }\n\n private _createPositionWrappers() {\n const className = {\n ...ControlBar.DEFAULT_CLASS,\n ...this.className\n };\n const rootEl = this._rootEl;\n\n // BG & FLOATING CONTROLS\n const backgroundEl = createElement(className.CONTROLS_BG);\n const floatLeftEl = createElement(className.CONTROLS_FLOAT_LEFT);\n const floatRightEl = createElement(className.CONTROLS_FLOAT_RIGHT);\n\n rootEl.appendChild(floatLeftEl);\n rootEl.appendChild(floatRightEl);\n\n // BOTTOM CONTROLS\n const container = createElement(className.CONTROLS_MAIN);\n const topWrapper = createElement(className.CONTROLS_TOP);\n const bottomWrapper = createElement(className.CONTROLS_BOTTOM);\n const midWrapper = createElement(className.CONTROLS_MID);\n const leftControlsWrapper = createElement(className.CONTROLS_LEFT);\n const rightControlsWrapper = createElement(className.CONTROLS_RIGHT);\n\n midWrapper.appendChild(leftControlsWrapper);\n midWrapper.appendChild(rightControlsWrapper);\n container.appendChild(backgroundEl);\n container.appendChild(topWrapper);\n container.appendChild(midWrapper);\n container.appendChild(bottomWrapper);\n rootEl.appendChild(container);\n\n this._bgEl = backgroundEl;\n this._containerEl = container;\n this._wrapperEl = {\n [ControlBar.POSITION.MAIN_TOP]: topWrapper,\n [ControlBar.POSITION.MAIN_LEFT]: leftControlsWrapper,\n [ControlBar.POSITION.MAIN_RIGHT]: rightControlsWrapper,\n [ControlBar.POSITION.MAIN_BOTTOM]: bottomWrapper,\n [ControlBar.POSITION.TOP_LEFT]: floatLeftEl,\n [ControlBar.POSITION.TOP_RIGHT]: floatRightEl\n };\n }\n\n private _clearItemElements() {\n const wrappers = Object.keys(ControlBar.POSITION).map(key => ControlBar.POSITION[key]);\n\n // Remove all elements inside wrappers\n wrappers.forEach(wrapper => {\n while (wrapper.firstChild) {\n wrapper.removeChild(wrapper.firstChild);\n }\n });\n }\n\n private _onStaticClick = ({ target: viewer, isTouch }: StaticClickEvent) => {\n const autoHider = this._autoHider;\n\n if (isTouch) {\n if (!autoHider.enabled) return;\n\n if (autoHider.hidden) {\n autoHider.showTemporaliy();\n } else {\n autoHider.hide();\n }\n } else {\n if (!this.clickToPlay) return;\n\n const video = viewer.projection?.getTexture();\n if (!video || !video.isVideo()) return;\n\n if (video.isPaused()) {\n video.source.play();\n } else {\n video.source.pause();\n }\n }\n };\n\n private _onNewSrcLoad = ({ target: viewer }: View360Events[\"projectionChange\"]) => {\n const items = this._items;\n\n this._updateBackground(viewer);\n this._updateAutoHide(viewer);\n this._updateKeyboardHandler(viewer);\n\n Object.keys(items).forEach((key: ValueOf) => {\n const category = items[key];\n\n category.forEach(item => {\n item.destroy(viewer, this);\n item.init(viewer, this);\n });\n });\n };\n\n private _updateAutoHide(viewer: View360) {\n const autoHide = this.autoHide;\n const autoHider = this._autoHider;\n\n if (autoHide != null) {\n if (autoHide) {\n autoHider.enable(viewer);\n } else {\n autoHider.disable(viewer);\n }\n } else {\n // Automatically choose whether to show background by content type\n const texture = viewer.projection?.getTexture();\n\n if (texture && texture.isVideo()) {\n // Enable auto hide when content type is video\n autoHider.enable(viewer);\n } else {\n autoHider.disable(viewer);\n }\n }\n }\n\n private _updateBackground(viewer: View360) {\n const background = this._bgEl;\n const showBackground = this.showBackground;\n const hiddenClass = this.className.HIDDEN ?? ControlBar.DEFAULT_CLASS.HIDDEN;\n\n if (showBackground != null) {\n if (showBackground) {\n background.classList.remove(hiddenClass);\n } else {\n background.classList.add(hiddenClass);\n }\n } else {\n // Automatically choose whether to show background by content type\n const texture = viewer.projection?.getTexture();\n\n if (texture && texture.isVideo()) {\n // Show bg when content type is video\n background.classList.remove(hiddenClass);\n } else {\n background.classList.add(hiddenClass);\n }\n }\n }\n\n private _updateKeyboardHandler(viewer: View360) {\n const panoRoot = viewer.rootEl;\n const videoControl = this._videoControl;\n const texture = viewer.projection?.getTexture();\n\n if (this.keyboardControls && texture && texture.isVideo()) {\n videoControl.enable(panoRoot, texture);\n } else {\n videoControl.disable(panoRoot);\n }\n }\n\n private _createDefaultItems(): ControlBarItem[] {\n const items: ControlBarItem[] = [];\n\n if (this.progressBar) {\n items.push(new ProgressBar(getObjectOption(this.progressBar)));\n }\n\n if (this.playButton) {\n items.push(new PlayButton(getObjectOption(this.playButton)));\n }\n\n if (this.volumeButton) {\n items.push(new VolumeControl(getObjectOption(this.volumeButton)));\n }\n\n if (this.gyroButton) {\n items.push(new GyroButton(getObjectOption(this.gyroButton)));\n }\n\n if (this.vrButton) {\n items.push(new VRButton(getObjectOption(this.vrButton)));\n }\n\n if (this.fullscreenButton) {\n items.push(new FullscreenButton(getObjectOption(this.fullscreenButton)));\n }\n\n if (this.videoTime) {\n items.push(new VideoTime(getObjectOption(this.videoTime)));\n }\n\n if (this.pieView) {\n items.push(new PieView(getObjectOption(this.pieView)));\n }\n\n return items;\n }\n}\n\nexport default ControlBar;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Camera from \"../core/Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport Texture from \"../texture/Texture\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport { VideoConfig } from \"../type/external\";\nimport UniformCanvasCube from \"../uniform/UniformCanvasCube\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport UniformTextureCube from \"../uniform/UniformTextureCube\";\n\ntype CommonProjectionUniforms = {\n uTexture: UniformTexture2D | UniformTextureCube | UniformCanvasCube;\n}\n\n/**\n * Common option for {@link Projection}s\n * @ko {@link Projection}을 위한 공통 옵션들\n * @category Projection\n * @since 4.0.0\n */\nexport interface ProjectionOptions {\n /**\n * @copy Projection#src\n */\n src: string | HTMLElement | Array;\n /**\n * @copy Projection#video\n */\n video?: boolean | Partial;\n}\n\n/**\n * Base class for projections.\n * @ko 프로젝션 베이스 클래스.\n * @category Projection\n * @since 4.0.0\n */\nabstract class Projection {\n /**\n * Source URL to panorama image/video.\n * @ko 파노라마 이미지/비디오의 URL\n * @since 4.0.0\n */\n public readonly src: ProjectionOptions[\"src\"];\n /**\n * Properties for the video element.\n * Setting `false` will treat panorama source as an image, `true` will use default properties.\n * @ko 비디오 엘리먼트에 설정할 프로퍼티를 담는 객체.\n * @since 4.0.0\n * @example\n * Default properties\n * ```ts\n * autoplay: true\n * muted: true\n * loop: false\n * volume: 1\n * ```\n */\n public readonly video: ProjectionOptions[\"video\"];\n\n protected _mesh: TriangleMesh | null;\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n src,\n video = false\n }: ProjectionOptions) {\n this.src = src;\n this.video = video;\n this._mesh = null;\n }\n\n /**\n * Apply texture to current projection.\n * @ko 주어진 텍스쳐를 현재 프로젝션에 적용합니다.\n * @param ctx - Instance of the WebGLContext helper {@ko WebGL context 헬퍼의 인스턴스}\n * @param texture - New texture to apply {@ko 새로 적용할 텍스쳐}\n * @internal\n * @since 4.0.0\n */\n public abstract applyTexture(ctx: WebGLContext, texture: Texture): void;\n\n /**\n * Release all resources projection has.\n * This is automatically called on projection change & View360's destroy call\n * @ko 현재 갖고 있는 모든 리소스를 반환합니다.\n * 이 메소드는 프로젝션 변경 및 View360의 destroy 호출 시 자동으로 호출됩니다.\n * @param ctx\n */\n public releaseAllResources(ctx: WebGLContext) {\n this._mesh?.destroy(ctx);\n }\n\n /**\n * Update camera to match projection's settings.\n * @ko 현재 프로젝션의 세팅으로 카메라를 업데이트합니다.\n * @param camera - Instance of the camera to update {@ko 업데이트할 카메라의 인스턴스}\n * @since 4.0.0\n */\n public updateCamera(camera: Camera) {\n // Use default mode & no view restriction\n camera.resetRange();\n }\n\n /**\n * Update control to match projection's settings.\n * @ko 현재 프로젝션의 세팅으로 컨트롤을 업데이트합니다.\n * @param control - Instance of the control to update {@ko 업데이트할 컨트롤의 인스턴스}\n * @since 4.0.0\n */\n public updateControl(control: PanoControl) {\n control.ignoreZoomScale = false;\n }\n\n /**\n * Update projection.\n * @ko 현재 프로젝션 정보를 갱신합니다.\n * @param camera - Instance of the camera to reference {@ko 참조할 카메라의 인스턴스}\n * @since 4.0.0\n */\n public update(camera: Camera) {} // eslint-disable-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars\n\n /**\n * Return active texture.\n * @ko 현재 활성화된 텍스쳐를 반환합니다.\n * @internal\n * @since 4.0.0\n */\n public getTexture() {\n if (!this._mesh) return null;\n\n return this._mesh.program.uniforms.uTexture.texture;\n }\n\n /**\n * A 3D triangle mesh for projection. It's `null` until loading the `src`.\n * @ko Projection을 표시하기 위한 Mesh, src를 로드하기 전까지는 `null`입니다.\n * @since 4.0.0\n */\n public getMesh(): TriangleMesh | null {\n return this._mesh;\n }\n}\n\nexport default Projection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nabstract class Uniform {\n public needsUpdate: boolean;\n\n public constructor() {\n this.needsUpdate = true;\n }\n\n public abstract update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean): void;\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext) {\n // DO_NOTHING\n }\n}\n\nexport default Uniform;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport TextureCube from \"../texture/TextureCube\";\nimport { reorderCube } from \"../utils\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformTextureCube extends Uniform {\n public readonly texture: TextureCube;\n private _webglTexture: WebGLTexture;\n private _cubemapOrder: string;\n\n public constructor(ctx: WebGLContext, texture: TextureCube, cubemapOrder: string) {\n super();\n\n this.texture = texture;\n this._webglTexture = ctx.createWebGLCubeTexture(texture, texture.width);\n this._cubemapOrder = cubemapOrder;\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext): void {\n this.texture.destroy();\n gl.deleteTexture(this._webglTexture);\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture);\n\n const sources = reorderCube(texture.sources, this._cubemapOrder);\n sources.forEach((src, idx) => {\n if (isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src);\n } else {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src);\n }\n });\n\n if (!texture.isVideo()) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformTextureCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"../texture/Texture2D\";\nimport { range, reorderCube } from \"../utils\";\n\n/** @hidden */\nclass CubeTexturePainter {\n public readonly texture: Texture2D;\n private _renderingOrder: number[];\n private _canvas: HTMLCanvasElement;\n private _ctx: CanvasRenderingContext2D;\n private _row: number;\n private _column: number;\n private _size: number;\n\n public get size() { return this._size; }\n\n public constructor(texture: Texture2D, cubemapOrder: string) {\n this.texture = texture;\n this._renderingOrder = reorderCube(range(6), cubemapOrder);\n\n const canvas = document.createElement(\"canvas\");\n\n this._calcRenderingSize();\n\n canvas.width = this._size;\n canvas.height = this._size;\n\n this._canvas = canvas;\n this._ctx = canvas.getContext(\"2d\")!;\n }\n\n public destroy() {\n const canvas = this._canvas;\n\n // release memories\n canvas.width = 1;\n canvas.height = 1;\n this._canvas = null as any;\n }\n\n public draw(gl: WebGLRenderingContext | WebGL2RenderingContext, isWebGL2: boolean) {\n const size = this._size;\n const texture = this.texture;\n let surfaceIdx = 0;\n\n for (let row = 0; row < this._row; row++) {\n for (let column = 0; column < this._column; column++) {\n const x = size * column;\n const y = size * row;\n const renderingFace = this._renderingOrder[surfaceIdx];\n\n this._ctx.drawImage(texture.source as CanvasImageSource, x, y, size, size, 0, 0, size, size);\n\n if (isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas);\n } else {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas);\n }\n\n surfaceIdx++;\n }\n }\n }\n\n private _calcRenderingSize() {\n const {\n width,\n height\n } = this.texture;\n const aspect = width / height;\n\n if (aspect === 1 / 6) {\n this._size = width;\n this._row = 6;\n this._column = 1;\n } else if (aspect === 6) {\n this._size = height;\n this._row = 1;\n this._column = 6;\n } else if (aspect === 2 / 3) {\n this._size = width * 0.5;\n this._row = 3;\n this._column = 2;\n } else {\n this._size = width / 3;\n this._row = 2;\n this._column = 3;\n }\n }\n}\n\nexport default CubeTexturePainter;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport CubeTexturePainter from \"../core/CubeTexturePainter\";\nimport Texture2D from \"../texture/Texture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformCanvasCube extends Uniform {\n private _webglTexture: WebGLTexture;\n private _painter: CubeTexturePainter;\n\n public get texture() { return this._painter.texture; }\n\n public constructor(ctx: WebGLContext, texture: Texture2D, cubemapOrder: string) {\n super();\n\n this._painter = new CubeTexturePainter(texture as Texture2D, cubemapOrder);\n this._webglTexture = ctx.createWebGLCubeTexture(texture, this._painter.size);\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext) {\n gl.deleteTexture(this._webglTexture);\n this._painter.destroy();\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture);\n\n this._painter.draw(gl, isWebGL2);\n\n if (!texture.isVideo()) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformCanvasCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Object3D from \"./Object3D\";\nimport ShaderProgram from \"./ShaderProgram\";\nimport VertexArrayObject from \"./VertexArrayObject\";\nimport Uniform from \"../uniform/Uniform\";\nimport WebGLContext from \"./WebGLContext\";\n\n/**\n * @hidden\n */\nclass TriangleMesh = Record> extends Object3D {\n /**\n * @internal\n * Geometry data for projection\n */\n public readonly vao: VertexArrayObject;\n /**\n * @internal\n * Material(shader) data for projection\n */\n public readonly program: ShaderProgram;\n\n public constructor(vao: VertexArrayObject, program: ShaderProgram) {\n super();\n\n this.vao = vao;\n this.program = program;\n }\n\n public destroy(ctx: WebGLContext) {\n ctx.releaseVAO(this.vao);\n ctx.releaseShaderResources(this.program);\n }\n}\n\nexport default TriangleMesh;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"../uniform/Uniform\";\nimport WebGLContext from \"./WebGLContext\";\nimport { UniformLocations } from \"../type/internal\";\n\nclass ShaderProgram = Record> {\n public readonly program: WebGLProgram;\n public readonly uniforms: T;\n public readonly uniformLocations: UniformLocations;\n\n public constructor(ctx: WebGLContext, vertexShader: string, fragmentShader: string, uniforms: T) {\n this.program = ctx.createProgram(vertexShader, fragmentShader);\n this.uniforms = uniforms;\n this.uniformLocations = ctx.getUniformLocations(this.program, uniforms);\n }\n}\n\nexport default ShaderProgram;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { TypedArray } from \"../type/utils\";\n\n/**\n * @hidden\n */\nclass VertexData {\n public readonly data: T;\n public itemSize: number;\n public count: number;\n\n /** */\n public constructor(data: T, itemSize: number) {\n this.data = data;\n this.itemSize = itemSize;\n this.count = data.length / itemSize;\n }\n}\n\nexport default VertexData;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport VertexData from \"../core/VertexData\";\n\n/**\n * @hidden\n */\nabstract class Geometry {\n public readonly vertices: VertexData;\n public readonly indicies: VertexData;\n public readonly uvs: VertexData;\n\n /** */\n public constructor(vertices: number[], indicies: number[], uvs: number[]) {\n this.vertices = new VertexData(new Float32Array(vertices), 3);\n this.indicies = new VertexData(new Uint16Array(indicies), 1);\n this.uvs = new VertexData(new Float32Array(uvs), 2);\n }\n}\n\nexport default Geometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\nimport { ROTATE } from \"../const/internal\";\nimport { reorderCube } from \"../utils\";\n\n/**\n * @hidden\n */\nclass CubeGeometry extends Geometry {\n public constructor({\n order,\n rotateUV\n }: {\n order: string;\n rotateUV?: ROTATE[]\n }) {\n const vertices = [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // up\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // down\n -1, -1, 1,\n 1, -1, 1,\n 1, -1, -1,\n -1, -1, -1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n\n const indicies = [\n 0, 1, 2,\n 0, 2, 3,\n 4, 5, 6,\n 4, 6, 7,\n 8, 9, 10,\n 8, 10, 11,\n 12, 13, 14,\n 12, 14, 15,\n 16, 17, 18,\n 16, 18, 19,\n 20, 21, 22,\n 20, 22, 23\n ];\n\n const oneThird = 1 / 3;\n const coords: number[][] = [];\n\n for (let r = 1; r >= 0; r--) {\n for (let c = 0; c < 3; c++) {\n const coord = [\n c * oneThird, r * 0.5,\n (c + 1) * oneThird, r * 0.5,\n (c + 1) * oneThird, (r + 1) * 0.5,\n c * oneThird, (r + 1) * 0.5\n ];\n\n coords.push(coord);\n }\n }\n\n if (rotateUV) {\n rotateUV.forEach((degree, idx) => {\n if (degree === ROTATE.ZERO) return;\n\n const coord = coords[idx];\n let newOrder: number[];\n\n if (degree === ROTATE.CW_90) {\n newOrder = [1, 2, 3, 0];\n } else if (degree === ROTATE.CCW_90) {\n newOrder = [3, 0, 1, 2];\n } else {\n newOrder = [2, 3, 0, 1];\n }\n\n const newCoords = Array(coord.length);\n for (let uvIdx = 0; uvIdx < coord.length / 2; uvIdx++) {\n newCoords[uvIdx * 2 + 0] = coord[newOrder[uvIdx] * 2 + 0];\n newCoords[uvIdx * 2 + 1] = coord[newOrder[uvIdx] * 2 + 1];\n }\n\n coords[idx] = newCoords;\n });\n }\n\n const uvs = reorderCube(coords, order, \"BFUDRL\")\n .reduce((acc, val) => acc.concat(val), []);\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default CubeGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTextureCube from \"../uniform/UniformTextureCube\";\nimport UniformCanvasCube from \"../uniform/UniformCanvasCube\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport TextureCube from \"../texture/TextureCube\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/cube.vert\";\nimport fs from \"../shader/cube.frag\";\n\n/**\n * Options for {@link CubemapProjection}\n * @ko {@link CubemapProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CubemapProjectionOptions extends ProjectionOptions {\n /**\n * Order of the cubemap images.\n * @ko 큐브맵 이미지의 순서.\n * @since 4.0.0\n * @default \"RLUDFB\" (Right - Left - Up - Down - Front - Back)\n */\n cubemapOrder?: string;\n /**\n * Whether to flip cubemap image horizontally.\n * @ko 큐브맵 이미지를 좌우대칭할지 여부.\n * @since 4.0.0\n * @default false\n */\n cubemapFlipX?: boolean;\n}\n\n/**\n * Projection based on cubemap images, accepts both multiple or single images.\n * @ko 큐브맵 이미지 기반의 프로젝션, 단일 혹은 여러 장의 이미지를 모두 사용 가능합니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CubemapProjection extends Projection<{\n uTexture: UniformTextureCube | UniformCanvasCube;\n}> {\n private _cubemapOrder: NonNullable;\n private _cubemapFlipX: NonNullable;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CubemapProjectionOptions) {\n super(options);\n\n const {\n cubemapOrder = \"RLUDFB\",\n cubemapFlipX = false\n } = options;\n\n this._cubemapOrder = cubemapOrder;\n this._cubemapFlipX = cubemapFlipX;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const cubemapOrder = this._cubemapOrder;\n const cubemapFlipX = this._cubemapFlipX;\n const uniforms = {\n uTexture: texture.isCube()\n ? new UniformTextureCube(ctx, texture as TextureCube, cubemapOrder)\n : new UniformCanvasCube(ctx, texture as Texture2D, cubemapOrder)\n };\n\n const geometry = new CubeGeometry({\n order: cubemapOrder\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n if (cubemapFlipX) {\n mesh.scale[0] = -1;\n }\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n}\n\nexport default CubemapProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"../texture/Texture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformTexture2D extends Uniform {\n public readonly texture: Texture2D;\n private _webglTexture: WebGLTexture;\n\n public constructor(ctx: WebGLContext, texture: Texture2D) {\n super();\n\n this.texture = texture;\n this._webglTexture = ctx.createWebGLTexture(texture);\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext): void {\n this.texture.destroy();\n gl.deleteTexture(this._webglTexture);\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n const isVideo = texture.isVideo();\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._webglTexture);\n\n if (!isVideo && isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n } else {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n }\n\n if (!isVideo) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformTexture2D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link CubestripProjection}\n * @ko {@link CubestripProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CubestripProjectionOptions extends ProjectionOptions {\n /**\n * @copy CubemapProjectionOptions#cubemapOrder\n */\n cubemapOrder?: string;\n /**\n * @copy CubemapProjectionOptions#cubemapFlipX\n */\n cubemapFlipX?: boolean;\n}\n\n/**\n * Projection based on cubemap strip.\n * Slightly more efficient than {@link CubemapProjection} as it doesn't copy cubemap image to canvas while rendering.\n * Accepts only single image.\n * @ko 큐브맵 스트립 기반의 프로젝션.\n * {@link CubemapProjection}와 달리 렌더링하는 과정에 캔버스에 이미지를 복사하는 과정이 없기 때문에 살짝 더 효율적입니다.\n * 단일 이미지만 사용 가능합니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CubestripProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n private _cubemapOrder: NonNullable;\n private _cubemapFlipX: NonNullable;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CubestripProjectionOptions) {\n super(options);\n\n const {\n cubemapOrder = \"RLUDFB\",\n cubemapFlipX = false\n } = options;\n\n this._cubemapOrder = cubemapOrder;\n this._cubemapFlipX = cubemapFlipX;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const cubemapOrder = this._cubemapOrder;\n const cubemapFlipX = this._cubemapFlipX;\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n const geometry = new CubeGeometry({\n order: cubemapOrder\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n if (cubemapFlipX) {\n mesh.scale[0] = -1;\n }\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n}\n\nexport default CubestripProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass CylinderGeometry extends Geometry {\n public constructor(maxTheta: number) {\n const vertices: number[] = [];\n const indicies: number[] = [];\n const uvs: number[] = [];\n\n const height = 1;\n const radialSegments = 60;\n const halfHeight = height * 0.5;\n const heightSegments = [-halfHeight, halfHeight];\n const invRadialSegments = 1 / radialSegments;\n const angleConst = maxTheta * invRadialSegments;\n\n for (let yIdx = 0; yIdx < 2; yIdx++) {\n const y = heightSegments[yIdx];\n\n for (let lngIdx = 0; lngIdx <= radialSegments; lngIdx++) {\n const angle = lngIdx * angleConst + Math.PI - maxTheta * 0.5;\n const x = Math.cos(angle);\n const z = Math.sin(angle);\n const u = lngIdx * invRadialSegments;\n const v = yIdx;\n\n uvs.push(u, v);\n vertices.push(x, y, z);\n\n if (yIdx === 0 && lngIdx < radialSegments) {\n const a = lngIdx;\n const b = a + radialSegments + 1;\n\n indicies.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n }\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default CylinderGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n*/\nimport { quat } from \"gl-matrix\";\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport CylinderGeometry from \"../geometry/CylinderGeometry\";\nimport Camera from \"../core/Camera\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"../const/internal\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\nimport TriangleMesh from \"../core/TriangleMesh\";\n\n/**\n * Options for {@link CylindricalProjection}\n * @ko {@link CylindricalProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CylindricalProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n /**\n * Whether the panorama image covers full 360 degrees.\n * @ko 파노라마 이미지가 360도를 전부 커버하는지 여부\n * @since 4.0.0\n * @default false\n */\n partial?: boolean;\n}\n\n/**\n * Projection based on cylindrical projection.\n * This can show panorama images taken from smartphones.\n * @ko 원통 투영법 기반의 프로젝션.\n * 일반적인 스마트폰 파노라마 사진을 표시하는데 사용될 수 있습니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CylindricalProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n private _partial: boolean;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CylindricalProjectionOptions) {\n super(options);\n\n const {\n partial = false\n } = options;\n\n this._partial = partial;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const partial = this._partial;\n const { width, height } = texture;\n const aspect = width / height;\n const halfVFov = 180 / aspect;\n const cylinderHeight = partial\n ? 1\n : 2 * Math.tan(halfVFov * DEG_TO_RAD);\n const cylinderTheta = partial\n ? aspect\n : 2 * Math.PI;\n\n const geometry = new CylinderGeometry(cylinderTheta);\n const program = new ShaderProgram(ctx, vs, fs, {\n uTexture: new UniformTexture2D(ctx, texture)\n });\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n mesh.scale[1] = cylinderHeight;\n quat.identity(mesh.rotation);\n quat.rotateY(mesh.rotation, mesh.rotation, -Math.PI / 2);\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n\n public updateCamera(camera: Camera) {\n super.updateCamera(camera);\n\n const mesh = this._mesh;\n if (!mesh) return;\n\n const uTexture = mesh.program.uniforms.uTexture;\n const texture = uTexture.texture;\n const { width, height } = texture;\n const aspect = width / height;\n const halfHeight = mesh.scale[1] * 0.5;\n\n if (this._partial) {\n const restrictedYaw = 0.5 * aspect * RAD_TO_DEG;\n camera.restrictYawRange(-restrictedYaw, restrictedYaw);\n }\n\n const restrictedPitch = Math.atan2(halfHeight, 1) * RAD_TO_DEG;\n const minZoom = Math.tan(camera.fov * DEG_TO_RAD * 0.5) / (halfHeight * camera.aspect);\n\n camera.restrictPitchRange(-restrictedPitch, restrictedPitch);\n camera.restrictZoomRange(minZoom, Infinity);\n camera.restrictRenderHeight(halfHeight * 2);\n }\n}\n\nexport default CylindricalProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/eac.frag\";\nimport { ROTATE } from \"../const/internal\";\n\n/**\n * Options for {@link EquiangularProjection}\n * @ko {@link EquiangularProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface EquiangularProjectionOptions extends ProjectionOptions {}\n\n/**\n * Equi-Angular Cubemap Projection.\n * This format is used by Youtube's 360 videos.\n * @ko Equi-Angular Cubemap 프로젝션.\n * 이 포맷은 주로 Youtube의 360 비디오에 사용됩니다.\n * @since 4.0.0\n * @category Projection\n */\nclass EquiangularProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n const geometry = new CubeGeometry({\n order: \"LFRDBU\",\n rotateUV: [\n ROTATE.ZERO, ROTATE.ZERO, ROTATE.ZERO,\n ROTATE.CW_90, ROTATE.CCW_90, ROTATE.CW_90\n ]\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default EquiangularProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass SphereGeometry extends Geometry {\n /** */\n public constructor() {\n // const radius = 1;\n const widthSegments = 60;\n const heightSegments = 60;\n const ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI;\n\n const uvs: number[] = [];\n const vertices: number[] = [];\n const indicies: number[] = [];\n let latIdx: number;\n let lngIdx: number;\n\n for (latIdx = 0; latIdx <= widthSegments; latIdx++) {\n const theta = (latIdx / widthSegments - 0.5) * Math.PI;\n const sinTheta = Math.sin(theta);\n const cosTheta = Math.cos(theta);\n\n for (lngIdx = 0; lngIdx <= heightSegments; lngIdx++) {\n const phi = (lngIdx / heightSegments - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN;\n const sinPhi = Math.sin(phi);\n const cosPhi = Math.cos(phi);\n const x = cosPhi * cosTheta;\n const y = sinTheta;\n const z = sinPhi * cosTheta;\n const u = lngIdx / heightSegments;\n const v = latIdx / widthSegments;\n\n uvs.push(u, v);\n vertices.push(x, y, z);\n\n if (lngIdx !== heightSegments && latIdx !== widthSegments) {\n const a = latIdx * (heightSegments + 1) + lngIdx;\n const b = a + heightSegments + 1;\n\n indicies.push(a, a + 1, b, b, a + 1, b + 1);\n }\n }\n }\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default SphereGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport Texture2D from \"../texture/Texture2D\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport SphereGeometry from \"../geometry/SphereGeometry\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link EquirectProjection}\n * @ko {@link EquirectProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface EquirectProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n}\n\n/**\n * Projection based on equirectangular projection.\n * @ko 등 장방형 도법(Equirectangular projection) 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass EquirectProjection extends Projection<{\n uTexture: UniformTexture2D\n}> {\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: EquirectProjectionOptions) {\n super(options);\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n\n const geometry = new SphereGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default EquirectProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"./Uniform\";\n\nclass UniformFloat extends Uniform {\n public val: number;\n\n public constructor(val: number) {\n super();\n\n this.val = val;\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation) {\n gl.uniform1f(location, this.val);\n\n this.needsUpdate = false;\n }\n}\n\nexport default UniformFloat;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass PlaneGeometry extends Geometry {\n /** */\n public constructor(width: number = 2, height: number = 2, z: number = -1) {\n const halfWidth = width * 0.5;\n const halfHeight = height * 0.5;\n const vertices = [\n -halfWidth, -halfHeight, z,\n halfWidth, -halfHeight, z,\n -halfWidth, halfHeight, z,\n halfWidth, halfHeight, z\n ];\n const indicies = [\n 0, 1, 2,\n 2, 1, 3\n ];\n const uvs = [\n 0, 0,\n 1, 0,\n 0, 1,\n 1, 1\n ];\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default PlaneGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport UniformFloat from \"../uniform/UniformFloat\";\nimport Camera from \"../core/Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport Texture2D from \"../texture/Texture2D\";\nimport PlaneGeometry from \"../geometry/PlaneGeometry\";\nimport vs from \"../shader/little-planet.vert\";\nimport fs from \"../shader/little-planet.frag\";\nimport TriangleMesh from \"../core/TriangleMesh\";\n\n/**\n * Options for {@link LittlePlanetProjection}\n * @ko {@link LittlePlanetProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface LittlePlanetProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n}\n\n/**\n * Projection based on so-called \"Little planet\" or \"Tiny planet\" effect.\n * @ko \"Little planet\" 혹은 \"Tiny planet\"로 불리는 이펙트 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass LittlePlanetProjection extends Projection<{\n uTexture: UniformTexture2D;\n uYaw: UniformFloat;\n uPitch: UniformFloat;\n uZoom: UniformFloat;\n}> {\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: LittlePlanetProjectionOptions) {\n super(options);\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n texture.wrapS = WebGLRenderingContext.REPEAT;\n texture.wrapT = WebGLRenderingContext.REPEAT;\n\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture),\n uYaw: new UniformFloat(0),\n uPitch: new UniformFloat(0.5),\n uZoom: new UniformFloat(1)\n };\n\n const geometry = new PlaneGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n\n public updateControl(control: PanoControl) {\n control.ignoreZoomScale = true;\n }\n\n public update(camera: Camera) {\n const mesh = this._mesh;\n if (!mesh) return;\n\n const uniforms = mesh.program.uniforms;\n\n uniforms.uYaw.val = camera.yaw / 360;\n // Range from 0 ~ 1\n uniforms.uPitch.val = (camera.pitch / 180) + 0.5;\n uniforms.uZoom.val = camera.zoom;\n\n uniforms.uYaw.needsUpdate = true;\n uniforms.uPitch.needsUpdate = true;\n uniforms.uZoom.needsUpdate = true;\n }\n}\n\nexport default LittlePlanetProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"./Uniform\";\n\nclass UniformVector4Array extends Uniform {\n public val: number[][];\n\n public constructor(val: number[][]) {\n super();\n\n this.val = val;\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation) {\n gl.uniform4fv(location, this.val.reduce((arr, vector) => [...arr, ...vector], []));\n\n this.needsUpdate = false;\n }\n}\n\nexport default UniformVector4Array;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport SphereGeometry from \"../geometry/SphereGeometry\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport UniformVector4Array from \"../uniform/UniformVector4Array\";\nimport UniformFloat from \"../uniform/UniformFloat\";\nimport vs from \"../shader/stereoequi.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link StereoEquiProjection}\n * @ko {@link StereoEquiProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface StereoEquiProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n /**\n * Stereoscopic mode of the image\n * @ko 이미지의 스테레오스코픽 모드\n * @since 4.0.0\n * @default \"top_bottom\"\n */\n mode: typeof StereoEquiProjection.MODE[keyof typeof StereoEquiProjection.MODE]\n}\n\n/**\n * Projection based on stereo equirectangular images.\n * @ko Stereo equirectangular 이미지 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass StereoEquiProjection extends Projection<{\n uTexture: UniformTexture2D;\n uEye: UniformFloat;\n uTexScaleOffset: UniformVector4Array;\n}> {\n /**\n * Available stereoscopic modes\n * @ko 사용가능한 스테레오스코픽 모드들\n * @since 4.0.0\n */\n public static MODE = {\n /**\n * @ko 이미지가 왼쪽/오른쪽으로 구성되어있을 경우\n * @since 4.0.0\n */\n LEFT_RIGHT: \"left_right\",\n /**\n * @ko 이미지가 위/아래로 구성되어있을 경우\n * @since 4.0.0\n */\n TOP_BOTTOM: \"top_bottom\",\n } as const;\n\n private _mode: StereoEquiProjectionOptions[\"mode\"];\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: StereoEquiProjectionOptions) {\n super(options);\n\n this._mode = options.mode;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n let leftEye: number[];\n let rightEye: number[];\n\n switch (this._mode) {\n case StereoEquiProjection.MODE.LEFT_RIGHT:\n leftEye = [0.5, 1, 0, 0];\n rightEye = [0.5, 1, 0.5, 0];\n break;\n default:\n // Default, uses \"top_bottom\"\n leftEye = [1, 0.5, 0, 0];\n rightEye = [1, 0.5, 0, 0.5];\n }\n\n\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture),\n uEye: new UniformFloat(0),\n uTexScaleOffset: new UniformVector4Array([leftEye, rightEye])\n };\n\n const geometry = new SphereGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default StereoEquiProjection;\n","import Component from \"@egjs/component\";\nimport View360 from \"../View360\";\n\n/**\n * @hidden\n */\nconst withMethods = (prototype: any, attr: string) => {\n [Component.prototype, View360.prototype].forEach(proto => {\n Object.getOwnPropertyNames(proto)\n .filter(name => name.charAt(0) !== \"_\" && name !== \"constructor\")\n .forEach((name: string) => {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name)!;\n\n if (descriptor.value) {\n // Public Function\n Object.defineProperty(prototype, name, {\n value: function(...args) {\n return descriptor.value.call(this[attr], ...args);\n }\n });\n } else {\n const getterDescriptor: { get?: () => any; set?: (val: any) => void } = {};\n if (descriptor.get) {\n getterDescriptor.get = function() {\n return this[attr] && descriptor.get?.call(this[attr]);\n };\n }\n if (descriptor.set) {\n getterDescriptor.set = function(...args) {\n return descriptor.set?.call(this[attr], ...args);\n };\n }\n\n Object.defineProperty(prototype, name, getterDescriptor);\n }\n });\n });\n};\n\nexport default withMethods;\n","/**\n * @hidden\n */\nexport const getValidProps = (propsObj: any) => {\n return Object.keys(propsObj).reduce((props, propName) => {\n if (propsObj[propName] != null) {\n props[propName] = propsObj[propName];\n }\n\n return props;\n }, {});\n};\n","export const VIEW360_METHODS = [\n \"destroy\",\n \"init\",\n \"load\",\n \"resize\",\n \"addPlugins\",\n \"removePlugins\",\n \"renderFrame\",\n // @egjs/component methods\n \"on\",\n \"hasOn\",\n \"once\",\n \"off\",\n \"trigger\"\n] as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360, { View360Options, View360Events } from \"./View360\";\n\nexport * from \"./core\";\nexport * from \"./control\";\nexport * from \"./plugin\";\nexport * from \"./projection\";\nexport * from \"./hotspot\";\nexport * from \"./const/external\";\nexport * from \"./type/external\";\nexport * from \"./cfc\";\n\nexport type {\n View360Options,\n View360Events\n};\n\nexport default View360;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360, * as modules from \"./index\";\nimport { merge } from \"./utils\";\n\nmerge(View360, modules);\n\nexport default View360;\n"],"names":["View360Error","Error","constructor","message","code","Object","setPrototypeOf","prototype","name","ERROR_CODES","WRONG_TYPE","WRONG_OPTION","ELEMENT_NOT_FOUND","CANVAS_NOT_FOUND","WEBGL_NOT_SUPPORTED","FAILED_CREATE_CONTEXT_2D","PROVIDE_PROJECTION_FIRST","FAILED_LINKING_PROGRAM","INSUFFICIENT_ARGS","MESSAGES","val","types","map","type","join","optionName","query","msg","shaderLog","CODES","EVENTS","MOUSE_DOWN","MOUSE_MOVE","MOUSE_UP","TOUCH_START","TOUCH_MOVE","TOUCH_END","WHEEL","RESIZE","CONTEXT_MENU","MOUSE_ENTER","MOUSE_LEAVE","POINTER_DOWN","POINTER_MOVE","POINTER_UP","POINTER_CANCEL","POINTER_ENTER","POINTER_LEAVE","KEY_DOWN","KEY_UP","LOAD","ERROR","CLICK","DOUBLE_CLICK","CONTEXT_CREATE_ERROR","CONTEXT_LOST","CONTEXT_RESTORED","DEVICE_ORIENTATION","DEVICE_MOTION","ORIENTATION_CHANGE","VIDEO_PLAY","VIDEO_PAUSE","VIDEO_LOADED_DATA","VIDEO_VOLUME_CHANGE","VIDEO_TIME_UPDATE","VIDEO_DURATION_CHANGE","VIDEO_CAN_PLAYTHROUGH","TRANSITION_END","XR_END","EL_DIV","EL_BUTTON","MOUSE_BUTTON","CURSOR","GRAB","GRABBING","NONE","KEY_DIRECTION","DIRECTION_KEY_CODE","SPACE_KEY_CODE","DIRECTION_KEY_NAME","LEFT","UP","RIGHT","DOWN","SPACE_KEY_NAME","FULLSCREEN_REQUEST","FULLSCREEN_ELEMENT","FULLSCREEN_EXIT","FULLSCREEN_CHANGE","DEFAULT_CLASS","CONTAINER","CANVAS","CTX_LOST","IN_VR","HOTSPOT_CONTAINER","HOTSPOT","HOTSPOT_VISIBLE","HOTSPOT_FLIP_X","HOTSPOT_FLIP_Y","READY","LOAD_START","PROJECTION_CHANGE","BEFORE_RENDER","RENDER","INPUT_START","INPUT_END","VIEW_CHANGE","STATIC_CLICK","VR_START","VR_END","EASING","LINEAR","x","SINE_WAVE","Math","sin","PI","EASE_OUT_CUBIC","pow","EASE_OUT_BOUNCE","n1","d1","CAMERA_EVENTS","CHANGE","ANIMATION_END","CONTROL_EVENTS","ENABLE","DISABLE","DEG_TO_RAD","RAD_TO_DEG","DEFAULT_EASING","DEFAULT_ANIMATION_DURATION","INFINITE_RANGE","min","Infinity","max","DEFAULT_PITCH_RANGE","DEFAULT_ZOOM_RANGE","ROTATE","VIDEO_TIME_CHANGE_EVENT","SVG_NAMESPACE","SESSION_VR","XR_REFERENCE_SPACE","EPSILON","_a","Number","isString","isElement","nodeType","Node","ELEMENT_NODE","createElement","className","tag","BROWSER","el","document","classList","add","getNullableElement","parent","targetEl","parentEl","queryResult","querySelector","getElement","findCanvas","root","selector","canvas","range","end","Array","apply","undef","idx","clamp","lerp","a","b","t","circulate","size","abs","offset","merge","target","srcs","forEach","source","keys","key","value","isArray","findIndex","array","checker","length","getObjectOption","toVerticalFov","fovRadian","aspect","atan","tan","reorderCube","arr","order","defaultOrder","split","face","indexOf","index","isFullscreen","sensorCanBeEnabledIOS","DeviceMotionEvent","window","isSecureContext","hfovToZoom","baseFov","fov","renderingWidth","zoomedWidth","eulerToQuat","out","yaw","pitch","roll","quat","pitchThreshold","pitchClamped","quatToEuler","quaternion","y","z","w","x2","y2","z2","w2","unit","test","atan2","view","vec3","up","viewXZ","sqrt","Motion","_val","start","_start","_end","progress","_progress","activated","_activated","duration","_duration","loop","_loop","_range","easing","_easing","reset","update","deltaTime","prev","nextProgress","easedProgress","defaultVal","delta","setNewEndByDelta","setRange","CameraAnimation","_motion","camera","from","to","_camera","_from","_to","_finishPromise","Promise","resolve","_finish","getFinishPromise","motion","rotation","zoom","rotate","Camera","Component","_aspect","changed","_changed","yawRange","_initialYawRange","pitchRange","_initialPitchRange","zoomRange","_initialZoomRange","initialYaw","initialPitch","initialZoom","rollOffset","position","animation","_up","_yawRange","_pitchRange","_zoomRange","_updateQuaternion","viewMatrix","mat4","projectionMatrix","_maxRenderHeight","destroy","off","resize","width","height","prevAspect","updateMatrix","lookAt","prevQuaternion","prevZoom","zoomDiff","normalized","isSameRotation","animateTo","finishPromise","then","trigger","restrictYawRange","restrictPitchRange","restrictZoomRange","restrictRenderHeight","resetRange","getYawRange","yawLimit","maxRenderHeight","halfHFov","getHorizontalFov","minYaw","maxYaw","halfVFovRad","h","d","theta","getPitchRange","pitchLimit","minPitch","maxPitch","halfVFov","getVerticalFov","getZoomRange","limit","minFov","maxFov","currentFov","current","_getZoomedHorizontalFov","hFov","vFov","fovToZoom","projMatrix","upDir","viewDir","onFrameRender","MouseInput","_onMouseDown","evt","_el","button","preventDefault","focus","_prevPos","clientX","clientY","addEventListener","_onMouseMove","_onMouseUp","srcEvent","isTouch","isKeyboard","prevPos","deltaX","deltaY","removeEventListener","scrolling","enable","element","disable","TouchInput","scrollable","_scrollable","_onTouchStart","touches","_scrolling","touch","_isFirstTouch","_onTouchMove","cancelable","_onTouchEnd","passive","KeyboardInput","active","pressed","_pressed","_onKeyDown","location","KeyboardEvent","DOM_KEY_LOCATION_STANDARD","_updateKeyPress","pressedCount","_getPressedKeyCount","repeat","_onKeyUp","_clearPressedKeys","_getDeltaByPressedKeys","reduce","obj","keyName","assign","event","isEnable","keyToUpdate","keyCode","filter","RotateControl","enabled","_enabled","enableBlocked","_enableBlocked","animating","_keyboardInput","_xMotion","_yMotion","_touchInput","pointerScale","_pointerScale","keyboardScale","_keyboardScale","disablePitch","_disablePitch","disableYaw","_disableYaw","disableKeyboard","_disableKeyboard","controlEl","_onInputStart","_changedWhileDragging","inputType","_onChange","invZoomScale","_zoomScale","screenScale","_screenScale","scale","scaledX","scaledY","_onInputEnd","_controlEl","_mouseInput","_bindInputs","xMotion","yMotion","keyboardInput","updateRange","setZoomScale","hfov","vfov","control","updateCursor","sync","mouseInput","touchInput","on","WheelInput","_onWheel","stopPropagation","_inputTimer","_clearTimer","_baseScale","setTimeout","capture","clearTimeout","PinchInput","prevDistance","_prevDistance","diff","pageX","pageY","distance","ZoomControl","_wheelInput","_scale","scaledDelta","_pinchInput","wheelInput","pinchInput","ROTATE_CONSTANT","PITCH_DELTA","YAW_DELTA_BY_ROLL","YAW_DELTA_BY_YAW","targetAxis","meshPoint","GyroInput","orientationUpdated","_orientationUpdated","ignoreRoll","_ignoreRoll","_onDeviceOrientation","prevOrientation","_orientation","alpha","beta","gamma","_needsCalibrate","_calibrateSensor","_updateScreenOrientation","screen","orientation","angle","undefined","_screenOrientation","_yawOrigin","_yawOffset","_updateRotation","collectDelta","prevRotation","_toEulerDelta","setInitialRotation","yawOrigin","sensorYaw","screenAngle","world","cos","prevQuat","currentQuat","_getDeltaYaw","_getDeltaPitch","prvQ","curQ","yawDeltaByYaw","_getRotationDelta","yawDeltaByRoll","_extractPitchFromQuat","prevQ","rotateKind","curQuaternion","prevPoint","curPoint","rotateDistance","rotateDirection","meshPoint2","meshPoint3","vecU","vecV","vecN","coefficientA","coefficientB","coefficientC","projectedPrevPoint","trigonometricRatio","acos","crossVec","thetaDirection","deltaRadian","baseV","GyroControl","_input","isAvailable","onDeviceMotionChange","listenDeviceMotion","res","rotationRate","timeout","race","available","requestSensorPermission","requestPermission","permissionState","catch","_updateYawPitch","input","yawDelta","pitchDelta","PanoControl","useGrabCursor","_useGrabCursor","_setCursor","disableContextMenu","_disableContextMenu","_blockContextMenu","_restoreContextMenu","_rotateControl","wheelScrollable","_zoomControl","ignoreZoomScale","_ignoreZoomScale","gyro","_gyroControl","_preventContextMenu","_onEnable","_onDisable","_onCameraAnimationEnd","_bindEvents","rotateControl","zoomControl","gyroControl","zoomScale","newCursor","style","cursor","Texture","flipY","wrapS","WebGLRenderingContext","CLAMP_TO_EDGE","wrapT","isVideo","isCube","Texture2D","TextureVideo","video","pause","removeAttribute","load","isPaused","paused","ended","readyState","hasAudio","audioTracks","webkitAudioDecodedByteCount","mozHasAudio","TextureCube","sources","TextureLoader","_loadChecker","ImReady","src","loadVideo","loadCubeImage","imgSrc","loadImage","images","_toImageArray","_load","image","naturalWidth","naturalHeight","videoConfig","config","autoplay","muted","volume","_toVideoElement","currentTime","play","videoWidth","videoHeight","content","onLoad","loader","reject","once","errorCount","check","imgEl","Image","crossOrigin","HTMLVideoElement","playsInline","setAttribute","_appendSourceElement","sourceCount","querySelectorAll","HTMLSourceElement","sourceEl","appendChild","FrameAnimator","maxDeltaTime","context","_context","_rafId","_rafTimer","_lastUpdateTime","callback","_time","frame","time","Date","now","requestAnimationFrame","stop","cancelAnimationFrame","changeContext","AutoResizer","useResizeObserver","_useResizeObserver","onResize","_skipFirstResize","isFirstResize","_onResize","_resizeObserver","ResizeObserver","bbox","getBoundingClientRect","resizeImmediate","resizeObserver","observe","disconnect","Autoplay","playing","_interrupted","delay","_delay","delayOnMouseLeave","_delayOnMouseLeave","speed","_speed","pauseOnHover","_pauseOnHover","canInterrupt","_canInterrupt","disableOnInterrupt","_disableOnInterrupt","viewer","options","_clearTimeout","_setUninterruptedAfterDelay","_onGyroEnable","_onMouseEnter","_hovering","_onMouseLeave","_control","_element","_interruptionTimer","enableAfterDelay","XRManager","ctx","exit","_onSessionEnd","_xrSession","_xrRefSpace","_ctx","_options","xr","navigator","isSessionSupported","enter","requiredFeatures","makeXRCompatible","session","requestSession","bindXRLayer","refSpace","requestReferenceSpace","_setSession","xrSession","canRender","pose","getViewerPose","getEyeParams","glLayer","renderState","baseLayer","views","viewport","getViewport","vMatrix","transform","inverse","matrix","pMatrix","Hotspot","HotspotRenderer","rootEl","renderer","_containerEl","_renderer","_hotspots","_zoom","refresh","container","hotspotEls","slice","_parseHotspot","render","hotspots","halfWidth","halfHeight","centerTransform","zoomTransform","hotspot","relPos","remove","screenPos","vec2","yawStr","dataset","pitchStr","positionStr","parseFloat","_yawPitchToVec3","pos","defaultPos","yawRad","pitchRad","VertexArrayObject","count","geometry","indicies","buffers","WebGLContext","_canvas","maxTextureSize","_maxTextureSize","isWebGL2","_isWebGL2","supportVAO","_extensions","vao","lost","_contextLost","debug","_debug","_onContextLost","_onContextRestore","loseContext","init","gl","_getContext","_gl","getParameter","MAX_TEXTURE_SIZE","getExtension","bindBuffer","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","forceLoseContext","extension","forceRestoreContext","restoreContext","clear","COLOR_BUFFER_BIT","drawingBufferWidth","drawingBufferHeight","createVAO","shaderProgram","nativeVAO","_createNativeVAO","_createBuffer","uv","_bindNativeVAO","_supplyGeometryData","_unbindBuffers","draw","drawElements","TRIANGLES","UNSIGNED_SHORT","releaseVAO","_deleteNativeVAO","_deleteBuffer","getUniformLocations","program","uniforms","uniformLocations","locations","getUniformLocation","_getCommonUniformLocations","updateCommonUniforms","entity","mvMatrix","uniformMatrix4fv","uMVMatrix","uPMatrix","updateVRUniforms","eyeIndex","uEye","uniform1f","updateUniforms","uniform","needsUpdate","releaseShaderResources","deleteProgram","useProgram","createProgram","vertexShader","fragmentShader","vs","_compileShader","VERTEX_SHADER","fs","FRAGMENT_SHADER","attachShader","bindAttribLocation","linkProgram","getProgramParameter","LINK_STATUS","getShaderParameter","COMPILE_STATUS","getShaderInfoLog","getProgramInfoLog","deleteShader","createWebGLTexture","texData","texture","createTexture","bindTexture","TEXTURE_2D","texParameteri","TEXTURE_MIN_FILTER","TEXTURE_MAG_FILTER","TEXTURE_WRAP_S","TEXTURE_WRAP_T","gl2","texStorage2D","RGBA8","createWebGLCubeTexture","TEXTURE_CUBE_MAP","attributes","getContextAttributes","xrCompatible","xrLayer","XRWebGLLayer","updateRenderState","bindXRFrame","bindFramebuffer","FRAMEBUFFER","framebuffer","useDefaultFrameBuffer","createBuffer","buffer","deleteBuffer","createVertexArray","ext","createVertexArrayOES","bindVertexArray","bindVertexArrayOES","deleteVertexArray","deleteVertexArrayOES","_supplyIndiciesData","_supplyAttributeData","vertices","uvs","bufferData","data","STATIC_DRAW","attribute","attribLocation","getAttribLocation","vertexAttribPointer","itemSize","FLOAT","enableVertexAttribArray","shader","createShader","shaderSource","compileShader","webglIdentifiers","contextAttributes","preserveDrawingBuffer","antialias","onWebglContextCreationError","e","statusMessage","identifier","getContext","WebGLRenderer","_elementSize","pixelRatio","_pixelRatio","canvasSize","devicePixelRatio","clientWidth","clientHeight","projection","mesh","getMesh","renderVR","vr","eyeParams","eye","View360","_rootEl","_vr","_hotspot","plugins","_plugins","_projection","_initialized","initialized","_autoplay","autoInit","_autoInit","autoResize","_autoResize","canvasSelector","_canvasSelector","tabIndex","_tabIndex","_animator","updateCamera","renderFrame","autoPlayer","_emit","_renderFrameOnDemand","getTexture","_renderVRFrame","_delta","_autoResizer","_addEventHandlers","releaseAllResources","plugin","animator","_bindComponentEvents","_resizeComponents","_loadTexture","_applyProjection","hasAttribute","addPlugins","push","removePlugins","pluginIdx","splice","eventName","params","evtParams","prevProjection","applyTexture","updateControl","contentLoader","events","evtName","controlEventsToPropagate","VERSION","Object3D","LoadingSpinner","_startLoading","_container","_detachElements","parentElement","removeChild","_createElements","ring","RING","ControlBarItem","CONTROL_BAR_DEFAULT_CLASS","CONTROLS_ROOT","CONTROLS_BG","CONTROLS_MAIN","CONTROLS_TOP","CONTROLS_BOTTOM","CONTROLS_MID","CONTROLS_LEFT","CONTROLS_RIGHT","CONTROLS_FLOAT_LEFT","CONTROLS_FLOAT_RIGHT","CONTROLS_BUTTON","PROGRESS_ROOT","VOLUME_ROOT","RANGE_ROOT","RANGE_TRACK","RANGE_THUMB","RANGE_FILLER","PLAY_BUTTON","PAUSE_BUTTON","UNMUTED_BUTTON","MUTED_BUTTON","FULLSCREEN_BUTTON","FULLSCREEN_EXIT_BUTTON","VR_BUTTON","GYRO_ENABLED","GYRO_DISABLED","VIDEO_TIME_DISPLAY","PIEVIEW_ROOT","FIXED","UNAVAILABLE","HIDDEN","CONTROL_BAR_ITEM_POSITION","TOP_LEFT","TOP_RIGHT","MAIN_TOP","MAIN_BOTTOM","MAIN_LEFT","MAIN_RIGHT","RangeControl","_onHold","_bbox","elX","scrollX","pageXOffset","clamepdX","thumbEl","_fixedClass","clampedX","_onRelease","track","thumb","filler","draggable","trackEl","fillerEl","left","right","bottom","top","updateStyle","clampedProgress","ProgressBar","_rangeControl","_onTimeUpdate","_video","_currentTime","_onDurationChange","controlBar","_controlBar","dispatchEvent","CustomEvent","detail","_wasPaused","_playPromise","_onControl","rangeControl","unavailableClass","PlayButton","_onClick","_paused","_onPlay","title","_onPause","VolumeControl","_updateDisplay","disabled","_onVolumeChange","_buttonEl","containerEl","buttonEl","FullscreenButton","_targetEl","_exitFullscreen","_requestFullscreen","_onFullscreenChange","_fullscreenAvailable","_addFullscreenHandlers","_removeFullscreenHandlers","some","request","call","VideoTime","_onCustomTimeChange","timeMinute","floor","timeSeconds","timeSecondsFormatted","durationMinute","durationSeconds","durationSecondsFormatted","innerText","PieView","resetCamera","_viewer","_updatePie","piePath","_piePathEl","rangeCircle","_rangeCircleEl","halfFov","pieRadius","pieDeg","pieOffset","isFinite","radius","rangeDiff","_createPieElements","rootClass","pieSVG","createElementNS","VRButton","GyroButton","_updateStyle","enableButton","AutoHide","hidden","contains","_hiddenClass","initialDelay","idleDelay","activationDelay","_isCursorInside","show","_hideAfterDelay","_isFullscreen","showTemporaliy","_isGrabbing","pointerType","_onVideoPlay","_onVideoPause","_initialDelay","_idleDelay","_timer","hide","_clearHideTimer","VideoControl","videoEl","keyPressed","_changeVideoTime","_changeVideoVolume","spacePressed","_toggleVideo","forward","increase","ControlBar","backgroundEl","_bgEl","items","_items","customItems","_customItems","autoHide","showBackground","clickToPlay","keyboardControls","progressBar","playButton","volumeButton","fullscreenButton","videoTime","pieView","vrButton","gyroButton","_onStaticClick","autoHider","_autoHider","_onNewSrcLoad","_updateBackground","_updateAutoHide","_updateKeyboardHandler","category","item","_createPositionWrappers","POSITION","_videoControl","panoRoot","controlsRoot","defaultItems","_createDefaultItems","_addItem","_clearItemElements","wrapper","_wrapperEl","nextSiblingIndex","sibling","nextSibling","insertBefore","floatLeftEl","floatRightEl","topWrapper","bottomWrapper","midWrapper","leftControlsWrapper","rightControlsWrapper","wrappers","firstChild","background","hiddenClass","_b","videoControl","Projection","_mesh","uTexture","Uniform","UniformTextureCube","cubemapOrder","_webglTexture","_cubemapOrder","deleteTexture","pixelStorei","UNPACK_FLIP_Y_WEBGL","uniform1i","activeTexture","TEXTURE0","texSubImage2D","TEXTURE_CUBE_MAP_POSITIVE_X","RGBA","UNSIGNED_BYTE","texImage2D","CubeTexturePainter","_size","_renderingOrder","_calcRenderingSize","surfaceIdx","row","_row","column","_column","renderingFace","drawImage","UniformCanvasCube","_painter","TriangleMesh","ShaderProgram","VertexData","Geometry","Float32Array","Uint16Array","CubeGeometry","rotateUV","oneThird","coords","r","c","coord","degree","ZERO","newOrder","CW_90","CCW_90","newCoords","uvIdx","acc","concat","CubemapProjection","cubemapFlipX","_cubemapFlipX","UniformTexture2D","CubestripProjection","CylinderGeometry","maxTheta","radialSegments","heightSegments","invRadialSegments","angleConst","yIdx","lngIdx","u","v","CylindricalProjection","partial","_partial","cylinderHeight","cylinderTheta","restrictedYaw","restrictedPitch","minZoom","EquiangularProjection","SphereGeometry","widthSegments","ANGLE_CORRECTION_FOR_CENTER_ALIGN","latIdx","sinTheta","cosTheta","phi","sinPhi","cosPhi","EquirectProjection","UniformFloat","PlaneGeometry","LittlePlanetProjection","REPEAT","uYaw","uPitch","uZoom","UniformVector4Array","uniform4fv","vector","StereoEquiProjection","_mode","mode","leftEye","rightEye","MODE","LEFT_RIGHT","uTexScaleOffset","TOP_BOTTOM","withMethods","attr","proto","getOwnPropertyNames","charAt","descriptor","getOwnPropertyDescriptor","defineProperty","args","getterDescriptor","get","set","getValidProps","propsObj","props","propName","VIEW360_METHODS","modules"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"} \ No newline at end of file diff --git a/demo/release/latest/dist/view360.pkgd.min.js b/demo/release/latest/dist/view360.pkgd.min.js new file mode 100644 index 000000000..bdec0cabd --- /dev/null +++ b/demo/release/latest/dist/view360.pkgd.min.js @@ -0,0 +1,30 @@ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).View360=e()}(this,(function(){"use strict";function t(t,e,i,s){return new(i||(i=Promise))((function(n,r){function o(t){try{h(s.next(t))}catch(t){r(t)}}function a(t){try{h(s.throw(t))}catch(t){r(t)}}function h(t){var e;t.done?n(t.value):(e=t.value,e instanceof i?e:new i((function(t){t(e)}))).then(o,a)}h((s=s.apply(t,e||[])).next())}))} +/*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */function e(t){var e="function"==typeof Symbol&&Symbol.iterator,i=e&&t[e],s=0;if(i)return i.call(t);if(t&&"number"==typeof t.length)return{next:function(){return t&&s>=t.length&&(t=void 0),{value:t&&t[s++],done:!t}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}function i(t,e){var i="function"==typeof Symbol&&t[Symbol.iterator];if(!i)return t;var s,n,r=i.call(t),o=[];try{for(;(void 0===e||e-- >0)&&!(s=r.next()).done;)o.push(s.value)}catch(t){n={error:t}}finally{try{s&&!s.done&&(i=r.return)&&i.call(r)}finally{if(n)throw n.error}}return o}function s(){for(var t=[],e=0;e0&&(r=1/Math.sqrt(r)),t[0]=e[0]*r,t[1]=e[1]*r,t[2]=e[2]*r,t}function v(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function E(t,e,i){var s=e[0],n=e[1],r=e[2],o=i[0],a=i[1],h=i[2];return t[0]=n*h-r*a,t[1]=r*o-s*h,t[2]=s*a-n*o,t}function f(t,e,i){var s=e[0],n=e[1],r=e[2],o=i[3]*s+i[7]*n+i[11]*r+i[15];return o=o||1,t[0]=(i[0]*s+i[4]*n+i[8]*r+i[12])/o,t[1]=(i[1]*s+i[5]*n+i[9]*r+i[13])/o,t[2]=(i[2]*s+i[6]*n+i[10]*r+i[14])/o,t}function y(t,e,i){var s=i[0],n=i[1],r=i[2],o=i[3],a=e[0],h=e[1],l=e[2],c=n*l-r*h,u=r*a-s*l,_=s*h-n*a,d=n*_-r*u,m=r*c-s*_,p=s*u-n*c,g=2*o;return c*=g,u*=g,_*=g,d*=2,m*=2,p*=2,t[0]=a+c+d,t[1]=h+u+m,t[2]=l+_+p,t}function b(){var t=new l(4);return l!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t[3]=1,t}function T(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t}function R(t,e,i){var s=e[0],n=e[1],r=e[2],o=e[3],a=i[0],h=i[1],l=i[2],c=i[3];return t[0]=s*c+o*a+n*l-r*h,t[1]=n*c+o*h+r*a-s*l,t[2]=r*c+o*l+s*h-n*a,t[3]=o*c-s*a-n*h-r*l,t}function w(t,e,i){i*=.5;var s=e[0],n=e[1],r=e[2],o=e[3],a=Math.sin(i),h=Math.cos(i);return t[0]=s*h+o*a,t[1]=n*h+r*a,t[2]=r*h-n*a,t[3]=o*h-s*a,t}function C(t,e,i){i*=.5;var s=e[0],n=e[1],r=e[2],o=e[3],a=Math.sin(i),h=Math.cos(i);return t[0]=s*h-r*a,t[1]=n*h+o*a,t[2]=r*h+s*a,t[3]=o*h-n*a,t}function L(t,e,i){i*=.5;var s=e[0],n=e[1],r=e[2],o=e[3],a=Math.sin(i),h=Math.cos(i);return t[0]=s*h+n*a,t[1]=n*h-s*a,t[2]=r*h+o*a,t[3]=o*h-r*a,t}function x(t,e,i,s){var n,r,o,a,l,c=e[0],u=e[1],_=e[2],d=e[3],m=i[0],p=i[1],g=i[2],v=i[3];return(r=c*m+u*p+_*g+d*v)<0&&(r=-r,m=-m,p=-p,g=-g,v=-v),1-r>h?(n=Math.acos(r),o=Math.sin(n),a=Math.sin((1-s)*n)/o,l=Math.sin(s*n)/o):(a=1-s,l=s),t[0]=a*c+l*m,t[1]=a*u+l*p,t[2]=a*_+l*g,t[3]=a*d+l*v,t}d(),function(){var t,e=(t=new l(4),l!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0,t[3]=0),t)}();var O,A=function(t){var e=new l(4);return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e},I=function(t,e,i,s){var n=new l(4);return n[0]=t,n[1]=e,n[2]=i,n[3]=s,n},S=function(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t},P=function(t,e,i,s,n){return t[0]=e,t[1]=i,t[2]=s,t[3]=n,t},N=function(t,e){var i=e[0],s=e[1],n=e[2],r=e[3],o=i*i+s*s+n*n+r*r;return o>0&&(o=1/Math.sqrt(o)),t[0]=i*o,t[1]=s*o,t[2]=n*o,t[3]=r*o,t},M=function(t,e){var i=t[0],s=t[1],n=t[2],r=t[3],o=e[0],a=e[1],l=e[2],c=e[3];return Math.abs(i-o)<=h*Math.max(1,Math.abs(i),Math.abs(o))&&Math.abs(s-a)<=h*Math.max(1,Math.abs(s),Math.abs(a))&&Math.abs(n-l)<=h*Math.max(1,Math.abs(n),Math.abs(l))&&Math.abs(r-c)<=h*Math.max(1,Math.abs(r),Math.abs(c))};d(),p(1,0,0),p(0,1,0),b(),b(),O=new l(9),l!=Float32Array&&(O[1]=0,O[2]=0,O[3]=0,O[5]=0,O[6]=0,O[7]=0),O[0]=1,O[4]=1,O[8]=1,function(){var t=function(){var t=new l(2);return l!=Float32Array&&(t[0]=0,t[1]=0),t}()}();class D extends Error{constructor(t,e){super(t),Object.setPrototypeOf(this,D.prototype),this.name="View360Error",this.code=e}}const U={WRONG_TYPE:0,WRONG_OPTION:1,ELEMENT_NOT_FOUND:2,CANVAS_NOT_FOUND:3,WEBGL_NOT_SUPPORTED:4,FAILED_CREATE_CONTEXT_2D:5,PROVIDE_PROJECTION_FIRST:6,FAILED_LINKING_PROGRAM:7,INSUFFICIENT_ARGS:8};var B=U,F={WRONG_TYPE:(t,e)=>`${typeof t} is not a ${e.map((t=>`"${t}"`)).join(" or ")}.`,WRONG_OPTION:(t,e)=>`Bad option: given "${t}" for option "${e}".`,ELEMENT_NOT_FOUND:t=>`Element with selector "${t}" not found.`,CANVAS_NOT_FOUND:"The canvas element was not found inside the given root element.",WEBGL_NOT_SUPPORTED:"WebGL is not supported on this browser.",FAILED_CREATE_CONTEXT_2D:"Failed to create canvas 2D context",PROVIDE_PROJECTION_FIRST:'"projection" should be provided before initialization.',FAILED_LINKING_PROGRAM:(t,e)=>`Failed linking WebGL program - "${t}\nShader compile Log: ${e}`,INSUFFICIENT_ARGS:(t,e)=>`Insufficient arguments: given "${t}" for "${e}".`};const z="mousedown",V="mousemove",k="mouseup",G="touchstart",H="touchmove",Y="touchend",j="wheel",W="resize",X="contextmenu",K="mouseenter",q="mouseleave",Z="keydown",$="keyup",J="click",Q="webglcontextcreationerror",tt="webglcontextlost",et="webglcontextrestored",it="deviceorientation",st="devicemotion",nt="orientationchange",rt="play",ot="pause",at="loadeddata",ht="volumechange",lt="timeupdate",ct="durationchange",ut="canplaythrough",_t="transitionend",dt="end",mt="div",pt="button";var gt;!function(t){t[t.LEFT=0]="LEFT",t[t.MIDDLE=1]="MIDDLE",t[t.RIGHT=2]="RIGHT"}(gt||(gt={}));const vt="grab",Et="grabbing",ft="",yt=["LEFT","UP","RIGHT","DOWN"];var bt;!function(t){t[t.LEFT=37]="LEFT",t[t.UP=38]="UP",t[t.RIGHT=39]="RIGHT",t[t.DOWN=40]="DOWN"}(bt||(bt={}));const Tt={LEFT:"ArrowLeft",UP:"ArrowUp",RIGHT:"ArrowRight",DOWN:"ArrowDown"},Rt=["requestFullscreen","webkitRequestFullscreen","webkitRequestFullScreen","webkitCancelFullScreen","mozRequestFullScreen","msRequestFullscreen"],wt=["fullscreenElement","webkitFullscreenElement","webkitCurrentFullScreenElement","mozFullScreenElement","msFullscreenElement"],Ct=["exitFullscreen","webkitExitFullscreen","webkitCancelFullScreen","mozCancelFullScreen","msExitFullscreen"],Lt=["fullscreenchange","webkitfullscreenchange","mozfullscreenchange","MSFullscreenChange"],xt={CONTAINER:"view360-container",CANVAS:"view360-canvas",CTX_LOST:"view360-ctx-lost",IN_VR:"view360-vr-presenting",HOTSPOT_CONTAINER:"view360-hotspots",HOTSPOT:"view360-hotspot",HOTSPOT_VISIBLE:"view360-hotspot-visible",HOTSPOT_FLIP_X:"view360-hotspot-flip-x",HOTSPOT_FLIP_Y:"view360-hotspot-flip-y"},Ot={READY:"ready",LOAD_START:"loadStart",LOAD:"load",PROJECTION_CHANGE:"projectionChange",RESIZE:"resize",BEFORE_RENDER:"beforeRender",RENDER:"render",INPUT_START:"inputStart",INPUT_END:"inputEnd",VIEW_CHANGE:"viewChange",STATIC_CLICK:"staticClick",VR_START:"vrStart",VR_END:"vrEnd"},At={LINEAR:t=>t,SINE_WAVE:t=>Math.sin(t*Math.PI*2),EASE_OUT_CUBIC:t=>1-Math.pow(1-t,3),EASE_OUT_BOUNCE:t=>{const e=7.5625,i=2.75;return t<1/i?e*t*t:t<2/i?e*(t-=1.5/i)*t+.75:t<2.5/i?e*(t-=2.25/i)*t+.9375:e*(t-=2.625/i)*t+.984375}};var It;const St="animationEnd",Pt="inputStart",Nt="change",Mt="inputEnd",Dt="enable",Ut="disable",Bt="staticClick",Ft=Math.PI/180,zt=180/Math.PI,Vt=At.EASE_OUT_CUBIC,kt=300,Gt={min:-1/0,max:1/0},Ht={min:-90,max:90},Yt={min:.6,max:10};var jt;!function(t){t[t.ZERO=0]="ZERO",t[t.CW_90=1]="CW_90",t[t.CCW_90=2]="CCW_90",t[t.CW_180=3]="CW_180"}(jt||(jt={}));const Wt="view360videotimechange",Xt="http://www.w3.org/2000/svg",Kt="immersive-vr",qt="local",Zt=null!==(It=Number.EPSILON)&&void 0!==It?It:2220446049250313e-31,$t=t=>"string"==typeof t,Jt=(t,e=mt)=>{const i=document.createElement(e);return i.classList.add(t),i},Qt=(t,e)=>{let i=null;if($t(t)){const s=(e||document).querySelector(t);if(!s)return null;i=s}else(s=t)&&s.nodeType===Node.ELEMENT_NODE&&(i=t);var s;return i},te=(t,e,i)=>Math.max(Math.min(t,i),e),ee=(t,e,i)=>t*(1-i)+e*i,ie=(t,e,i)=>{const s=Math.abs(i-e);if(ti){t=e+(t-i)%s}return t},se=(t,e)=>{for(let i=0;i"object"==typeof t?t:{},re=(t,e)=>2*Math.atan(Math.tan(.5*t)/e),oe=(t,e,i="RLUDFB")=>i.split("").map((t=>e.indexOf(t))).map((e=>t[e])),ae=()=>{if(!document)return!1;for(const t of wt)if(document[t])return!0;return!1},he=()=>!!DeviceMotionEvent&&"requestPermission"in DeviceMotionEvent&&window.isSecureContext,le=(t,e,i,s)=>{T(t);const n=te(i,-89.99,89.99);return C(t,t,e*Ft),w(t,t,n*Ft),L(t,t,s*Ft),t},ce=t=>{const e=t[0],i=t[1],s=t[2],n=t[3],r=e*e+i*i+s*s+n*n,o=e*n-i*s;let a,h;if(o>.499995*r)a=Math.PI/2,h=2*Math.atan2(i,e);else if(o<-.499995*r)a=-Math.PI/2,h=-2*Math.atan2(i,e);else{const e=p(0,0,1),i=p(0,1,0);y(e,e,t),y(i,i,t);const s=Math.sqrt(e[0]*e[0]+e[2]*e[2]);a=Math.atan2(-e[1],s),h=Math.atan2(e[0],e[2])}return{pitch:te(a*zt,-90,90),yaw:ie(h*zt,0,360)}};class ue{get val(){return this._val}get start(){return this._start}get end(){return this._end}get progress(){return this._progress}get activated(){return this._activated}get duration(){return this._duration}set duration(t){this._duration=t}get loop(){return this._loop}set loop(t){this._loop=t}get range(){return this._range}get easing(){return this._easing}set easing(t){this._easing=t}constructor({duration:t=300,loop:e=!1,range:i={min:0,max:1},easing:s=Vt}={}){this._duration=t,this._loop=e,this._range=i,this._easing=s,this._activated=!1,this.reset(0)}update(t){if(!this._activated)return this._val=this._end,0;const e=this._start,i=this._end,s=this._duration,n=this._val,r=this._loop,o=this._progress+t/s;this._progress=r?ie(o,0,1):te(o,0,1);const a=this._easing(this._progress);return this._val=ee(e,i,a),!r&&this._progress>=1&&(this._activated=!1),this._val-n}reset(t){const e=this._range,i=te(t,e.min,e.max);this._start=i,this._end=i,this._val=i,this._progress=0,this._activated=!1}add(t){const e=this._range;this._start=te(this._start+t,e.min,e.max),this._end=te(this._end+t,e.min,e.max),this._val=te(this._val+t,e.min,e.max)}setNewEndByDelta(t){const e=this._range;this._start=this._val,this._end=te(this._end+t,e.min,e.max),this._progress=0,this._activated=!0}setRange(t,e){this._start=te(this._start,t,e),this._end=te(this._end,t,e),this._range={min:t,max:e}}}class _e{get duration(){return this._motion.duration}set duration(t){this._motion.duration=t}get easing(){return this._motion.easing}set easing(t){this._motion.easing=t}constructor(t,e,i,{duration:s=300,easing:n=Vt}={}){this._camera=t,this._motion=new ue({duration:s,easing:n,range:{min:0,max:1}}),this._from=e,this._to=i,this._finishPromise=new Promise((t=>{this._finish=t})),this._motion.setNewEndByDelta(1)}getFinishPromise(){return this._finishPromise}update(t){const e=this._camera,i=this._from,s=this._to,n=this._motion;n.update(t);const r=n.val,o=b(),a=ee(i.zoom,s.zoom,r);x(o,i.rotation,s.rotation,r),e.rotate(o,a),r>=1&&this._finish()}}class de extends o{get aspect(){return this._aspect}get changed(){return this._changed}get yawRange(){return this._initialYawRange}set yawRange(t){this._initialYawRange=t}get pitchRange(){return this._initialPitchRange}set pitchRange(t){this._initialPitchRange=t}get zoomRange(){return this._initialZoomRange}set zoomRange(t){this._initialZoomRange=t}constructor({initialYaw:t,initialPitch:e,initialZoom:i,yawRange:s,pitchRange:n,zoomRange:r,fov:o}){super(),this.yaw=t,this.pitch=e,this.zoom=i,this.rollOffset=0,this.initialYaw=t,this.initialPitch=e,this.initialZoom=i,this.position=d(),this.animation=null,this._up=p(0,1,0),this._aspect=1,this._initialYawRange=s,this._initialPitchRange=n,this._initialZoomRange=r,this._yawRange=s,this._pitchRange=n,this._zoomRange=r,this.quaternion=b(),this._updateQuaternion(),this.viewMatrix=c(),this.projectionMatrix=c(),this.fov=o,this._maxRenderHeight=-1}destroy(){this.off()}resize(t,e){const i=this._aspect;this._aspect=t/e,this._aspect!==i&&this.updateMatrix()}lookAt({yaw:t=this.yaw,pitch:e=this.pitch,zoom:i=this.zoom}){const s=A(this.quaternion),n=this.zoom;this.yaw=ie(t,0,360),this.pitch=te(e,-90,90),this.zoom=i,this._updateQuaternion();const r=Math.abs(i-n);(!M(this.quaternion,s)||r>=10*Zt)&&this.updateMatrix()}rotate(t,e=this.zoom){const i=N(b(),t),s=M(this.quaternion,i);S(this.quaternion,i);const n=this.zoom,{yaw:r,pitch:o}=ce(i);this.yaw=r,this.pitch=o,this.zoom=e;const a=Math.abs(e-n);(!s||a>=10*Zt)&&this.updateMatrix()}animateTo({yaw:e=this.yaw,pitch:i=this.pitch,zoom:s=this.zoom,duration:n=0,easing:r=Vt}={}){return t(this,void 0,void 0,(function*(){if(this.yaw===e&&this.pitch===i&&this.zoom===s)return;const t={rotation:A(this.quaternion),zoom:this.zoom},o={rotation:le(b(),e,i,this.rollOffset),zoom:s},a=new _e(this,t,o,{duration:n,easing:r}),h=a.getFinishPromise();return this.animation=a,h.then((()=>{this.animation=null,this.trigger(St,{animation:a})})),h}))}restrictYawRange(t,e){this._yawRange={min:t,max:e}}restrictPitchRange(t,e){this._pitchRange={min:t,max:e}}restrictZoomRange(t,e){this._zoomRange={min:t,max:e}}restrictRenderHeight(t){this._maxRenderHeight=t}resetRange(){this._yawRange=this._initialYawRange,this._pitchRange=this._initialPitchRange,this._zoomRange=this._initialZoomRange,this._maxRenderHeight=-1}getYawRange(t){const e=this._yawRange,i=this._maxRenderHeight;if(!e)return Gt;const s=.5*this.getHorizontalFov(t);let n=e.min,r=e.max;if(i>0){const t=re(s*Ft,this._aspect),o=.5*i,a=Math.tan(t),h=Math.sqrt((1+o*o)/(1+a*a)),l=Math.atan(Math.tan(s*Ft)*h)*zt;n=e.min+l,r=e.max-l}return n>r&&(n=0,r=0),{min:n,max:r}}getPitchRange(t){const e=this._pitchRange,i=this._maxRenderHeight;if(!e)return Ht;let s=e.min,n=e.max;if(i>0){const i=.5*this.getVerticalFov(t);s=e.min+i,n=e.max-i}return s>n&&(s=0,n=0),{min:Math.max(s,-90),max:Math.min(n,90)}}getZoomRange(){var t;const e=null!==(t=this._zoomRange)&&void 0!==t?t:Yt,i=this.getHorizontalFov(e.max),s=this.getHorizontalFov(e.min),n=this.getHorizontalFov(this.zoom);return{min:Math.max(i,1),max:Math.min(s,180),current:n}}getHorizontalFov(t=this.zoom){return this._getZoomedHorizontalFov(t)*zt}getVerticalFov(t=this.zoom){const e=this._aspect,i=this._getZoomedHorizontalFov(t);return re(i,e)*zt}fovToZoom(t){const e=this.fov;return Math.tan(Ft*e*.5)/Math.tan(Ft*t*.5)}updateMatrix(){const t=this._up,e=this._aspect,i=this.viewMatrix,s=this.projectionMatrix,n=this.position,r=this.quaternion,o=d(),a=p(0,0,-1);y(a,a,r),y(o,t,r);const l=this._getZoomedHorizontalFov(),c=re(l,e);!function(t,e,i,s){var n,r,o,a,l,c,u,_,d,m,p=e[0],g=e[1],v=e[2],E=s[0],f=s[1],y=s[2],b=i[0],T=i[1],R=i[2];Math.abs(p-b){const e=this._el;e&&t.button===gt.LEFT&&(t.preventDefault(),e.focus?e.focus():window.focus(),this._prevPos[0]=t.clientX,this._prevPos[1]=t.clientY,window.addEventListener(V,this._onMouseMove,!1),window.addEventListener(k,this._onMouseUp,!1),this.trigger(Pt,{srcEvent:t,isTouch:!1,isKeyboard:!1}))},this._onMouseMove=t=>{t.preventDefault();const e=t.clientX,i=t.clientY,s=this._prevPos,n=e-s[0],r=i-s[1];this.trigger(Nt,{delta:{x:n,y:r},isTouch:!1,isKeyboard:!1}),s[0]=e,s[1]=i},this._onMouseUp=()=>{this._prevPos[0]=0,this._prevPos[1]=0,window.removeEventListener(V,this._onMouseMove,!1),window.removeEventListener(k,this._onMouseUp,!1),this.trigger(Mt,{isTouch:!1,isKeyboard:!1,scrolling:!1})},this._el=null,this._prevPos=[0,0]}enable(t){this._el||(t.addEventListener(z,this._onMouseDown),this._el=t)}disable(){const t=this._el;t&&(t.removeEventListener(z,this._onMouseDown),window.removeEventListener(V,this._onMouseMove,!1),window.removeEventListener(k,this._onMouseUp,!1),this._el=null)}}class pe extends o{get scrollable(){return this._scrollable}set scrollable(t){this._scrollable=t}constructor(){super(),this._onTouchStart=t=>{if(t.touches.length>1||this._scrolling)return;const e=t.touches[0];this._isFirstTouch=!0,this._prevPos[0]=e.clientX,this._prevPos[1]=e.clientY,this.trigger(Pt,{srcEvent:t,isTouch:!0,isKeyboard:!1})},this._onTouchMove=t=>{if(t.touches.length>1||this._scrolling)return;const e=t.touches[0],i=this._scrollable,s=this._prevPos,n=e.clientX,r=e.clientY,o=n-s[0],a=r-s[1];if(this._isFirstTouch){if(i&&!ae()&&Math.abs(a)>Math.abs(o))return void(this._scrolling=!0);this._isFirstTouch=!1}!1!==t.cancelable&&t.preventDefault(),this.trigger(Nt,{delta:{x:o,y:a},isTouch:!0,isKeyboard:!1}),s[0]=n,s[1]=r},this._onTouchEnd=t=>{if(0!==t.touches.length)return;const e=t.touches[0],i=this._prevPos;e?(i[0]=e.clientX,i[1]=e.clientY):(i[0]=0,i[1]=0,this.trigger(Mt,{isTouch:!0,isKeyboard:!1,scrolling:this._scrolling})),!1!==t.cancelable&&t.preventDefault(),this._scrolling=!1},this._el=null,this._prevPos=[0,0],this._isFirstTouch=!1,this._scrolling=!1,this._scrollable=!1}enable(t){this._el||(t.addEventListener(G,this._onTouchStart,{passive:!1}),t.addEventListener(H,this._onTouchMove,{passive:!1}),t.addEventListener(Y,this._onTouchEnd),this._el=t)}disable(){const t=this._el;t&&(t.removeEventListener(G,this._onTouchStart),t.removeEventListener(H,this._onTouchMove),t.removeEventListener(Y,this._onTouchEnd),this._el=null)}}class ge extends o{get active(){const t=this._pressed;return t.LEFT||t.UP||t.RIGHT||t.DOWN}constructor(){super(),this._onKeyDown=t=>{if(t.location!==KeyboardEvent.DOM_KEY_LOCATION_STANDARD)return;this._updateKeyPress(t,!0);const e=this._getPressedKeyCount();e<=0||(t.preventDefault(),1!==e||t.repeat||this.trigger(Pt,{srcEvent:t,isTouch:!1,isKeyboard:!0}))},this._onKeyUp=t=>{if(t.location!==KeyboardEvent.DOM_KEY_LOCATION_STANDARD)return;this._updateKeyPress(t,!1);this._getPressedKeyCount()>0||this.trigger(Mt,{isTouch:!1,isKeyboard:!0,scrolling:!1})},this._el=null,this._clearPressedKeys()}enable(t){this._el||(t.addEventListener(Z,this._onKeyDown),t.addEventListener($,this._onKeyUp),this._el=t,this._clearPressedKeys())}disable(){const t=this._el;t&&(t.removeEventListener(Z,this._onKeyDown),t.removeEventListener($,this._onKeyUp),this._el=null,this._clearPressedKeys())}update(){const t=this._getDeltaByPressedKeys();0===t.x&&0===t.y||this.trigger(Nt,{delta:t,isTouch:!1,isKeyboard:!0})}_clearPressedKeys(){this._pressed=yt.reduce(((t,e)=>Object.assign(Object.assign({},t),{[e]:!1})),{})}_updateKeyPress(t,e){const i=this._pressed,s=null!=t.keyCode?bt[t.keyCode]:Tt[t.key];s&&(i[s]=e)}_getPressedKeyCount(){return yt.filter((t=>this._pressed[t])).length}_getDeltaByPressedKeys(){const t=this._pressed;let e=0,i=0;return t.LEFT&&(e+=1),t.RIGHT&&(e-=1),t.UP&&(i+=1),t.DOWN&&(i-=1),{x:e,y:i}}}class ve extends o{get enabled(){return this._enabled}get enableBlocked(){return this._enableBlocked}get animating(){return this._keyboardInput.active||this._xMotion.activated||this._yMotion.activated}get yaw(){return this._xMotion}get pitch(){return this._yMotion}get scrollable(){return this._touchInput.scrollable}set scrollable(t){this._touchInput.scrollable=t}get pointerScale(){return this._pointerScale}set pointerScale(t){this._pointerScale=t}get keyboardScale(){return this._keyboardScale}set keyboardScale(t){this._keyboardScale=t}get duration(){return this._duration}set duration(t){this._duration=t,this._xMotion.duration=t,this._yMotion.duration=t}get easing(){return this._easing}set easing(t){this._easing=t,this._xMotion.easing=t,this._yMotion.easing=t}get disablePitch(){return this._disablePitch}set disablePitch(t){this._disablePitch=t}get disableYaw(){return this._disableYaw}set disableYaw(t){this._disableYaw=t}get disableKeyboard(){return this._disableKeyboard}set disableKeyboard(t){this._disableKeyboard=t}constructor(t,e,{duration:i=300,easing:s=Vt,pointerScale:n=[1,1],keyboardScale:r=[1,1],disablePitch:o=!1,disableYaw:a=!1,disableKeyboard:h=!1}={}){super(),this._onInputStart=t=>{this._changedWhileDragging=!1,this.trigger(Pt,Object.assign(Object.assign({},t),{inputType:"rotate"}))},this._onChange=t=>{const e=t.delta,i=1/this._zoomScale,s=this._screenScale,n=this._keyboardScale,r=this._pointerScale;let o;o=t.isKeyboard?[n[0]*i,n[1]*i]:[r[0]*s[0]*i,r[1]*s[1]*i];const a=e.x*o[0],h=e.y*o[1];this._xMotion.setNewEndByDelta(a),this._yMotion.setNewEndByDelta(h),this._changedWhileDragging=!0},this._onInputEnd=t=>{this.trigger(Mt,Object.assign(Object.assign({},t),{inputType:"rotate"})),this._changedWhileDragging||t.isKeyboard||t.scrolling||this.trigger(Bt,{isTouch:t.isTouch}),this._changedWhileDragging=!1},this._controlEl=t,this._pointerScale=n,this._keyboardScale=r,this._duration=i,this._easing=s,this._disablePitch=o,this._disableYaw=a,this._disableKeyboard=h,this._enableBlocked=e,this._mouseInput=new me,this._touchInput=new pe,this._keyboardInput=new ge,this._xMotion=new ue({duration:i,range:Gt,easing:s}),this._yMotion=new ue({duration:i,range:Ht,easing:s}),this._screenScale=[1,1],this._zoomScale=1,this._enabled=!1,this._changedWhileDragging=!1,this._bindInputs()}destroy(){this.disable(),this._mouseInput.off(),this._touchInput.off(),this._keyboardInput.off(),this.off(),this._changedWhileDragging=!1}update(t){if(!this._enabled)return;const e=this._xMotion,i=this._yMotion,s=this._keyboardInput;this._disableKeyboard||s.update(),this._disablePitch||i.update(t),this._disableYaw||e.update(t)}updateRange(t,e){const i=t.getYawRange(e),s=t.getPitchRange(e);this._xMotion.setRange(i.min,i.max),this._yMotion.setRange(s.min,s.max)}setZoomScale(t){this._zoomScale=t}resize(t,e,i,s){const n=re(t*Ft,e)*zt;this._screenScale[0]=t/i,this._screenScale[1]=n/s}enable(){if(this._enabled)return;const t=this._controlEl;this._mouseInput.enable(t),this._touchInput.enable(t),this._keyboardInput.enable(t),this._enabled=!0,this._enableBlocked=!1,this.trigger(Dt,{control:this,updateCursor:!0})}disable(){this._enabled&&(this._mouseInput.disable(),this._touchInput.disable(),this._keyboardInput.disable(),this._enabled=!1,this.trigger(Ut,{updateCursor:!0}))}sync(t){this.updateRange(t,t.zoom),this._xMotion.reset(t.yaw),this._yMotion.reset(t.pitch)}_bindInputs(){const t=this._mouseInput,e=this._touchInput,i=this._keyboardInput;t.on(Pt,this._onInputStart),t.on(Nt,this._onChange),t.on(Mt,this._onInputEnd),e.on(Pt,this._onInputStart),e.on(Nt,this._onChange),e.on(Mt,this._onInputEnd),i.on(Pt,this._onInputStart),i.on(Nt,this._onChange),i.on(Mt,this._onInputEnd)}}class Ee extends o{get scrollable(){return this._scrollable}set scrollable(t){this._scrollable=t}constructor(){super(),this._onWheel=t=>{const e=this._scrollable;if(0===t.deltaY||e)return;t.preventDefault(),t.stopPropagation(),this._inputTimer<0?this.trigger(Pt,{srcEvent:t,isTouch:!1,isKeyboard:!1}):this._clearTimer();const i=this._baseScale*t.deltaY;this.trigger(Nt,{delta:i,isTouch:!1,isKeyboard:!1}),this._inputTimer=window.setTimeout((()=>{this.trigger(Mt,{isTouch:!1,isKeyboard:!1,scrolling:!1}),this._inputTimer=-1}),kt)},this._el=null,this._baseScale=.04,this._scrollable=!1,this._inputTimer=-1}enable(t){this._el||(t.addEventListener(j,this._onWheel,{passive:!1,capture:!1}),this._el=t,this._clearTimer())}disable(){const t=this._el;t&&(t.removeEventListener(j,this._onWheel,!1),this._el=null,this._clearTimer())}_clearTimer(){window.clearTimeout(this._inputTimer),this._inputTimer=-1}}class fe extends o{constructor(){super(),this._onTouchMove=t=>{const e=t.touches;if(2!==e.length)return;if(!t.cancelable)return;t.preventDefault(),t.stopPropagation();const i=this._prevDistance,s=[e[0].pageX-e[1].pageX,e[0].pageY-e[1].pageY],n=Math.sqrt(s[0]*s[0]+s[1]*s[1])*this._baseScale,r=this._isFirstTouch?0:n-i;this._isFirstTouch&&this.trigger(Pt,{srcEvent:t,isTouch:!0,isKeyboard:!1}),this._prevDistance=n,this._isFirstTouch=!1,this.trigger(Nt,{delta:r,isTouch:!0,isKeyboard:!1})},this._onTouchEnd=t=>{0===t.touches.length&&(this._isFirstTouch||this.trigger(Mt,{isTouch:!0,isKeyboard:!1,scrolling:!1}),this._prevDistance=-1,this._isFirstTouch=!0)},this._el=null,this._baseScale=-.2,this._prevDistance=-1,this._isFirstTouch=!0}enable(t){this._el||(t.addEventListener(H,this._onTouchMove,{passive:!1,capture:!1}),t.addEventListener(Y,this._onTouchEnd),this._el=t,this._prevDistance=-1,this._isFirstTouch=!0)}disable(){const t=this._el;t&&(t.removeEventListener(H,this._onTouchMove,!1),t.removeEventListener(Y,this._onTouchEnd),this._el=null)}}class ye extends o{get enabled(){return this._enabled}get enableBlocked(){return this._enableBlocked}get animating(){return this._motion.activated}get zoom(){return this._motion.val}get scrollable(){return this._wheelInput.scrollable}set scrollable(t){this._wheelInput.scrollable=t}get range(){return this._motion.range}get scale(){return this._scale}set scale(t){this._scale=t}get duration(){return this._motion.duration}get easing(){return this._motion.easing}constructor(t,e,{scale:i=1,duration:s=300,easing:n=Vt}={}){super(),this._onInputStart=t=>{this.trigger(Pt,Object.assign(Object.assign({},t),{inputType:"zoom"}))},this._onChange=({delta:t})=>{const e=t*this._scale;this._motion.setNewEndByDelta(e)},this._onInputEnd=t=>{this.trigger(Mt,Object.assign(Object.assign({},t),{inputType:"zoom"}))},this._scale=i,this._controlEl=t,this._enableBlocked=e,this._wheelInput=new Ee,this._pinchInput=new fe,this._motion=new ue({duration:s,easing:n,range:Gt}),this._enabled=!1,this._bindInputs()}destroy(){this.disable(),this._wheelInput.off(),this._pinchInput.off(),this.off()}update(t){if(!this._enabled)return;this._motion.update(t)}enable(){if(this._enabled)return;const t=this._controlEl;this._wheelInput.enable(t),this._pinchInput.enable(t),this._enabled=!0,this._enableBlocked=!1,this.trigger(Dt,{control:this,updateCursor:!1})}disable(){this._enabled&&(this._wheelInput.disable(),this._pinchInput.disable(),this._enabled=!1,this.trigger(Ut,{updateCursor:!1}))}sync(t){const e=this._motion,i=t.getZoomRange();e.setRange(i.min,i.max),e.reset(i.current)}_bindInputs(){const t=this._wheelInput,e=this._pinchInput;t.on(Pt,this._onInputStart),t.on(Nt,this._onChange),t.on(Mt,this._onInputEnd),e.on(Pt,this._onInputStart),e.on(Nt,this._onChange),e.on(Mt,this._onInputEnd)}}const be={PITCH_DELTA:1,YAW_DELTA_BY_ROLL:2,YAW_DELTA_BY_YAW:3};be[be.PITCH_DELTA]={targetAxis:[0,1,0],meshPoint:[0,0,1]},be[be.YAW_DELTA_BY_ROLL]={targetAxis:[0,1,0],meshPoint:[1,0,0]},be[be.YAW_DELTA_BY_YAW]={targetAxis:[1,0,0],meshPoint:[0,0,1]};class Te extends o{get enabled(){return this._enabled}get orientationUpdated(){return this._orientationUpdated}get ignoreRoll(){return this._ignoreRoll}set ignoreRoll(t){this._ignoreRoll=t}constructor(){super(),this._onDeviceOrientation=t=>{const e=this._orientation,{alpha:i,beta:s,gamma:n}=t;null!=i&&null!=s&&null!=n&&(e.alpha=i,e.beta=s,e.gamma=n,this._orientationUpdated=!0,this._needsCalibrate&&(this._needsCalibrate=!1,this._calibrateSensor()))},this._updateScreenOrientation=()=>{window.screen&&window.screen.orientation&&void 0!==window.screen.orientation.angle?this._screenOrientation=screen.orientation.angle:void 0!==window.orientation?this._screenOrientation=window.orientation>=0?window.orientation:360+window.orientation:this._screenOrientation=0},this.quaternion=b(),this._orientation={alpha:0,beta:90,gamma:0},this._yawOrigin=0,this._yawOffset=0,this._orientationUpdated=!1,this._screenOrientation=0,this._needsCalibrate=!0,this._enabled=!1}enable(){this._enabled||(window.addEventListener(it,this._onDeviceOrientation),window.addEventListener(nt,this._updateScreenOrientation),this._updateScreenOrientation(),this._orientationUpdated=!1,this._needsCalibrate=!0,this._enabled=!0)}disable(){this._enabled&&(window.removeEventListener(it,this._onDeviceOrientation),window.removeEventListener(nt,this._updateScreenOrientation),this._enabled=!1)}update(){this._updateRotation(),this._orientationUpdated=!1}collectDelta(){if(!this._orientationUpdated)return{pitch:0,yaw:0};const t=A(this.quaternion);return this._updateRotation(),this._orientationUpdated=!1,this._toEulerDelta(t,this.quaternion)}setInitialRotation(t){this._yawOrigin=t}_calibrateSensor(){const t=this._yawOrigin,e=this.quaternion;this._yawOffset=0,this._updateRotation();const{yaw:i}=ce(e);this._yawOffset=i-t,this._updateRotation(),this._needsCalibrate=!1}_updateRotation(){const t=this.quaternion,{alpha:e,beta:i,gamma:s}=this._orientation;T(t),C(t,t,(e-this._yawOffset)*Ft),w(t,t,i*Ft),L(t,t,-s*Ft);const n=b(),r=.5*-this._screenOrientation*Ft,o=I(-Math.sqrt(.5),0,0,Math.sqrt(.5));P(n,0,Math.sin(r),0,Math.cos(r)),R(t,t,n),R(t,t,o),N(t,t)}_toEulerDelta(t,e){return{yaw:this._getDeltaYaw(t,e),pitch:this._getDeltaPitch(t,e)}}_getDeltaYaw(t,e){const i=this._getRotationDelta(t,e,be.YAW_DELTA_BY_YAW);return this._getRotationDelta(t,e,be.YAW_DELTA_BY_ROLL)*Math.sin(this._extractPitchFromQuat(e))+i}_getDeltaPitch(t,e){return this._getRotationDelta(t,e,be.PITCH_DELTA)}_getRotationDelta(t,e,i){const s=p(be[i].targetAxis[0],be[i].targetAxis[1],be[i].targetAxis[2]),n=be[i].meshPoint,r=A(t),o=A(e);N(r,r),N(o,o);let a=p(0,0,1),h=p(0,0,1);y(a,a,r),y(h,h,o),y(s,s,o);const l=v(s,E(d(),a,h))>0?1:-1,c=p(n[0],n[1],n[2]);let u;u=i!==be.YAW_DELTA_BY_YAW?p(0,l,0):p(l,0,0),y(c,c,o),y(u,u,o);const _=c,f=u,b=d();E(b,_,f),g(b,b);const T=b[0],R=b[1],w=b[2];h=p(n[0],n[1],n[2]),y(h,h,o),a=p(n[0],n[1],n[2]),y(a,a,r);let C=Math.abs(a[0]*T+a[1]*R+a[2]*w);const L=d();!function(t,e,i){t[0]=e[0]-i[0],t[1]=e[1]-i[1],t[2]=e[2]-i[2]}(L,a,function(t,e,i){return t[0]=e[0]*i,t[1]=e[1]*i,t[2]=e[2]*i,t}(d(),b,C));let x=(L[0]*h[0]+L[1]*h[1]+L[2]*h[2])/(m(L)*m(h));x>1&&(x=1);const O=Math.acos(x),I=E(d(),h,L);let S;C=T*I[0]+R*I[1]+w*I[2],S=i!==be.YAW_DELTA_BY_YAW?C>0?1:-1:C<0?1:-1;return O*S*l*zt}_extractPitchFromQuat(t){const e=p(0,0,1);return y(e,e,t),-1*Math.atan2(e[1],Math.sqrt(Math.pow(e[0],2)+Math.pow(e[2],2)))}}class Re extends o{get enabled(){return this._input.enabled}get enableBlocked(){return this._enableBlocked}get animating(){return this._input.enabled&&this._input.orientationUpdated}get ignoreRoll(){return this._ignoreRoll}set ignoreRoll(t){this._ignoreRoll=t}static isAvailable(){return t(this,void 0,void 0,(function*(){if(!DeviceMotionEvent)return!1;let t;return Promise.race([new Promise((e=>{t=t=>{e(t.rotationRate&&null!=t.rotationRate.alpha)},window.addEventListener(st,t)})),new Promise((t=>{setTimeout((()=>t(!1)),1e3)}))]).then((e=>(window.removeEventListener(st,t),e)))}))}static requestSensorPermission(){return t(this,void 0,void 0,(function*(){return!he()||DeviceMotionEvent.requestPermission().then((t=>"granted"===t)).catch((()=>!1))}))}constructor(t,{ignoreRoll:e=!0}={}){super(),this._enableBlocked=t,this._ignoreRoll=e,this._input=new Te}destroy(){this.disable(),this._input.off(),this.off()}update(t,e,i,s){this._ignoreRoll?this._updateYawPitch(t,e,i,s):this._updateQuaternion(t,s)}enable(){this._input.enabled||(this._input.enable(),this._enableBlocked=!1,this.trigger(Dt,{control:this,updateCursor:!1}))}disable(){this._input.enabled&&(this._input.disable(),this.trigger(Ut,{updateCursor:!1}))}sync(){}_updateYawPitch(t,e,i,s){const n=this._input;if(!n.enabled)return;const{yaw:r,pitch:o}=n.collectDelta();e.add(r),i.add(o),t.lookAt({yaw:e.val,pitch:i.val,zoom:s})}_updateQuaternion(t,e){const i=this._input;i.enabled&&(i.update(),t.rotate(i.quaternion,e))}}class we{get useGrabCursor(){return this._useGrabCursor}set useGrabCursor(t){t!==this._useGrabCursor&&(this._useGrabCursor=t,t&&this._enabled?this._setCursor(vt):t||this._setCursor(ft))}get disableContextMenu(){return this._disableContextMenu}set disableContextMenu(t){t!==this._disableContextMenu&&(this._disableContextMenu=t,t&&this._enabled?this._blockContextMenu():t||this._restoreContextMenu())}get scrollable(){return this._rotateControl.scrollable}set scrollable(t){this._rotateControl.scrollable=t}get wheelScrollable(){return this._zoomControl.scrollable}set wheelScrollable(t){this._zoomControl.scrollable=t}get ignoreZoomScale(){return this._ignoreZoomScale}set ignoreZoomScale(t){this._ignoreZoomScale=t}get enabled(){return this._enabled}get rotate(){return this._rotateControl}get zoom(){return this._zoomControl}get gyro(){return this._gyroControl}get animating(){return this._rotateControl.animating||this._zoomControl.animating||this._gyroControl.animating}constructor(t,e,{useGrabCursor:i,scrollable:s,wheelScrollable:n,disableContextMenu:r,rotate:o,zoom:a,gyro:h}){this._preventContextMenu=t=>{t.preventDefault()},this._onInputStart=t=>{this._useGrabCursor&&!t.isKeyboard&&this._setCursor(Et)},this._onInputEnd=t=>{this._useGrabCursor&&!t.isKeyboard&&this._setCursor(vt)},this._onEnable=({control:t,updateCursor:e})=>{e&&this._useGrabCursor&&this._setCursor(vt),t.sync(this._camera)},this._onDisable=({updateCursor:t})=>{t&&this._setCursor(ft)},this._onCameraAnimationEnd=({animation:t})=>{t.getFinishPromise().then((()=>{this.sync()}))},this._useGrabCursor=i,this._disableContextMenu=r,this._camera=e,this._controlEl=t,this._ignoreZoomScale=!1,this._enabled=!1,this._rotateControl=new ve(t,!o,ne(o)),this._zoomControl=new ye(t,!a,ne(a)),this._gyroControl=new Re(!h,ne(h)),this._rotateControl.scrollable=s,this._zoomControl.scrollable=n,this._bindEvents()}destroy(){this.disable(),this._rotateControl.destroy(),this._zoomControl.destroy(),this._setCursor(ft)}resize(t,e){const i=this._camera;this._rotateControl.resize(i.fov,i.aspect,t,e)}enable(){return t(this,void 0,void 0,(function*(){this._enabled||(this._rotateControl.enableBlocked||this._rotateControl.enable(),this._zoomControl.enableBlocked||this._zoomControl.enable(),this._gyroControl.enableBlocked||(yield Re.isAvailable())&&this._gyroControl.enable(),this.sync(),this._disableContextMenu&&this._blockContextMenu(),this._enabled=!0)}))}disable(){this._enabled&&(this._rotateControl.disable(),this._zoomControl.disable(),this._gyroControl.disable(),this._restoreContextMenu(),this._enabled=!1)}update(t){const e=this._camera,i=this._rotateControl,s=this._zoomControl,n=this._gyroControl;s.update(t);const r=(o=e.fov,a=s.zoom,Math.tan(Ft*o*.5)/Math.tan(Ft*a*.5));var o,a;const h=this._ignoreZoomScale?1:Math.max(r,1);i.setZoomScale(h),i.updateRange(e,r),i.update(t);const l=i.yaw,c=i.pitch;n.enabled?n.update(e,l,c,r):e.lookAt({yaw:l.val,pitch:c.val,zoom:r})}sync(){const t=this._camera;this._zoomControl.sync(t),this._rotateControl.sync(t)}_blockContextMenu(){this._controlEl.addEventListener(X,this._preventContextMenu)}_restoreContextMenu(){this._controlEl.removeEventListener(X,this._preventContextMenu)}_setCursor(t){if(!this._useGrabCursor&&t!==ft)return;this._controlEl.style.cursor=t}_bindEvents(){const t=this._rotateControl,e=this._zoomControl;t.on(Pt,this._onInputStart),t.on(Mt,this._onInputEnd),t.on(Dt,this._onEnable),t.on(Ut,this._onDisable),e.on(Dt,this._onEnable),e.on(Ut,this._onDisable),this._camera.on(St,this._onCameraAnimationEnd)}} +/*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */var Ce=function(t,e){return Ce=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i])},Ce(t,e)};function Le(t,e){function i(){this.constructor=t}Ce(t,e),t.prototype=null===e?Object.create(e):(i.prototype=e.prototype,new i)}var xe=function(){return xe=Object.assign||function(t){for(var e,i=1,s=arguments.length;i0},i.clear=function(){this.isPreReadyOver=!1,this.totalCount=0,this.preReadyCount=0,this.readyCount=0,this.totalErrorCount=0,this.elementInfos.forEach((function(t){t.loader&&t.loader.destroy()})),this.elementInfos=[]},i.destroy=function(){this.clear(),this.off()},i.getLoader=function(t,e){var i=this,s=t.tagName.toLowerCase(),n=this.options.loaders,r=e.prefix,o=Object.keys(n);if(n[s])return new n[s](t,e);var a=new Xe(t,e),h=Ue(t.querySelectorAll(o.join(", ")));a.setHasLoading(h.some((function(t){return Be(t,r)})));var l=!1,c=this.clone().on("error",(function(t){a.onError(t.target)})).on("ready",(function(){a.onReady(l)}));return a.on("requestChildren",(function(){var e=ke(t,o,i.options.prefix);c.check(e).on("preReady",(function(t){(l=t.isReady)||a.onPreReady()}))})).on("reqeustReadyChildren",(function(){c.check(h)})).on("requestDestroy",(function(){c.destroy()})),a},i.clone=function(){return new e(xe({},this.options))},i.checkPreReady=function(t){return this.elementInfos[t].isPreReady=!0,++this.preReadyCount,!(this.preReadyCount=1)&&(t.error?(this.onAlreadyError(t),!1):(this.addEvents(),!0))},e.EVENTS=["loadedmetadata","error"],e}(We),$e=function(t){function e(e){return void 0===e&&(e={}),t.call(this,xe({loaders:{img:qe,video:Ze}},e))||this}return Le(e,t),e}(Ke);class Je{constructor({width:t,height:e,flipY:i}){this.width=t,this.height=e,this.flipY=i,this.wrapS=WebGLRenderingContext.CLAMP_TO_EDGE,this.wrapT=WebGLRenderingContext.CLAMP_TO_EDGE}destroy(){}isVideo(){return!1}isCube(){return!1}}class Qe extends Je{constructor({source:t,width:e,height:i,flipY:s}){super({width:e,height:i,flipY:s}),this.source=t}}class ti extends Qe{destroy(){const t=this.source;t.pause(),t.removeAttribute("src"),t.load()}isVideo(){return!0}isPaused(){const t=this.source;return t.paused||t.ended||t.readyState<=2}hasAudio(){const t=this.source;return t.audioTracks?t.audioTracks.length>0:null!=t.webkitAudioDecodedByteCount?t.webkitAudioDecodedByteCount>0:null==t.mozHasAudio||t.mozHasAudio}}class ei extends Je{constructor({sources:t,width:e,height:i,flipY:s}){super({width:e,height:i,flipY:s}),this.sources=t}isCube(){return!0}}class ii{constructor(){this._loadChecker=new $e}load(e,i){return t(this,void 0,void 0,(function*(){if(i)return this.loadVideo(e,ne(i));if(Array.isArray(e)&&e.length>1)return this.loadCubeImage(e);{const t=Array.isArray(e)?e[0]:e;return this.loadImage(t)}}))}loadImage(e){return t(this,void 0,void 0,(function*(){const t=this._toImageArray(e);return this._load(t,(e=>{const i=t[0];e(new Qe({source:i,width:i.naturalWidth,height:i.naturalHeight,flipY:!0}))}))}))}loadCubeImage(e){return t(this,void 0,void 0,(function*(){const t=this._toImageArray(e);return this._load(t,(e=>{e(new ei({sources:t,width:t[0].naturalWidth,height:t[0].naturalHeight,flipY:!1}))}))}))}loadVideo(e,i){return t(this,void 0,void 0,(function*(){const t=Object.assign({autoplay:!0,muted:!0,loop:!1,volume:1},i),s=this._toVideoElement(e,t);return this._load([s],(e=>{const{autoplay:i,muted:n}=t;s.currentTime=0,i&&n&&s.play().catch((()=>{})),e(new ti({source:s,width:s.videoWidth,height:s.videoHeight,flipY:!0}))}))}))}_load(t,e){const i=this._loadChecker;return new Promise(((s,n)=>{i.once("ready",(t=>{t.errorCount>0||e(s)})),i.once("error",n),i.check(t)}))}_toImageArray(t){return(Array.isArray(t)?t:[t]).map((t=>{if($t(t)){const e=new Image;return e.crossOrigin="anonymous",e.src=t,e}return t}))}_toVideoElement(t,{muted:e,loop:i,volume:s}){if(t instanceof HTMLVideoElement)return t;const n=document.createElement("video");n.crossOrigin="anonymous",n.playsInline=!0,n.setAttribute("webkit-playsinline",""),n.muted=e,n.volume=s,n.loop=i,Array.isArray(t)?t.forEach((t=>this._appendSourceElement(n,t))):this._appendSourceElement(n,t);return n.querySelectorAll("source").length>0&&n.readyState<1&&n.load(),n}_appendSourceElement(t,e){if(e instanceof HTMLSourceElement)return e;const i=document.createElement("source");i.src=e,t.appendChild(i)}}class si{constructor(t,e=window){this.maxDeltaTime=t,this._context=e,this._rafId=-1,this._rafTimer=-1,this._lastUpdateTime=-1}start(t){const e=this._context;if(!e||!t)return;if(this._rafId>=0||this._rafTimer>=0)return;const i=(s,n)=>{const r=Date.now(),o=Math.min(r-this._lastUpdateTime,1e3*this.maxDeltaTime);t(o,n),this._lastUpdateTime=r,this._rafId=e.requestAnimationFrame(i)};this._lastUpdateTime=Date.now(),this._rafId=e.requestAnimationFrame(i)}stop(){this._rafId>=0&&this._context.cancelAnimationFrame(this._rafId),this._rafTimer>=0&&clearTimeout(this._rafTimer),this._rafId=-1,this._rafTimer=-1}changeContext(t){this.stop(),this._context=t}}class ni{get useResizeObserver(){return this._useResizeObserver}get enabled(){return this._enabled}constructor(t,e){this._skipFirstResize=(()=>{let t=!0;return()=>{t?t=!1:this._onResize()}})(),this._useResizeObserver=t,this._enabled=!1,this._resizeObserver=null,this._onResize=e}enable(t){if(this._enabled&&this.disable(),this._useResizeObserver&&window.ResizeObserver){const e=t.getBoundingClientRect(),i=0!==e.width||0!==e.height,s=new ResizeObserver(i?this._skipFirstResize:this._onResize);s.observe(t),this._resizeObserver=s}else window.addEventListener(W,this._onResize);return this._enabled=!0,this}disable(){if(!this._enabled)return this;const t=this._resizeObserver;return t?(t.disconnect(),this._resizeObserver=null):window.removeEventListener(W,this._onResize),this._enabled=!1,this}}class ri{get enabled(){return this._enabled}get enableBlocked(){return this._enableBlocked}get playing(){return this._enabled&&!this._interrupted}get delay(){return this._delay}set delay(t){this._delay=t}get delayOnMouseLeave(){return this._delayOnMouseLeave}set delayOnMouseLeave(t){this._delayOnMouseLeave=t}get speed(){return this._speed}set speed(t){this._speed=t}get pauseOnHover(){return this._pauseOnHover}set pauseOnHover(t){this._pauseOnHover=t}get canInterrupt(){return this._canInterrupt}set canInterrupt(t){this._canInterrupt=t}get disableOnInterrupt(){return this._disableOnInterrupt}set disableOnInterrupt(t){this._disableOnInterrupt=t}constructor(t,e,i){this._onInputStart=()=>{this._canInterrupt&&(this._interrupted=!0,this._clearTimeout())},this._onInputEnd=()=>{this._setUninterruptedAfterDelay(this._delay)},this._onGyroEnable=()=>{this.disable()},this._onMouseEnter=()=>{this._pauseOnHover&&(this._interrupted=!0,this._hovering=!0)},this._onMouseLeave=()=>{this._pauseOnHover&&(this._hovering=!1,this._setUninterruptedAfterDelay(this._delayOnMouseLeave))},this._camera=t.camera,this._control=t.control,this._element=e,this._enabled=!1,this._interrupted=!1,this._interruptionTimer=-1,this._hovering=!1;const{delay:s=2e3,delayOnMouseLeave:n=0,speed:r=1,pauseOnHover:o=!1,canInterrupt:a=!0,disableOnInterrupt:h=!1}=ne(i);this._enableBlocked=!i,this._delay=s,this._delayOnMouseLeave=n,this._speed=r,this._pauseOnHover=o,this._canInterrupt=a,this._disableOnInterrupt=h}destroy(){this.disable()}update(t){if(!this._enabled)return;if(this._interrupted)return void(this._disableOnInterrupt&&this.disable());const e=this._camera,i=-this._speed*t/100;e.yaw=ie(e.yaw+i,0,360)}enable(){const t=this._control,e=this._element;this._enabled||t.gyro.enabled||(t.rotate.on(Pt,this._onInputStart),t.rotate.on(Mt,this._onInputEnd),t.zoom.on(Pt,this._onInputStart),t.zoom.on(Mt,this._onInputEnd),t.gyro.on(Dt,this._onGyroEnable),e.addEventListener(K,this._onMouseEnter,!1),e.addEventListener(q,this._onMouseLeave,!1),this._enabled=!0,this._enableBlocked=!1)}enableAfterDelay(){this.enable(),this._interrupted=!0,this._setUninterruptedAfterDelay(this._delay)}disable(){if(!this._enabled)return;const t=this._control,e=this._element;t.rotate.off(Pt,this._onInputStart),t.rotate.off(Mt,this._onInputEnd),t.zoom.off(Pt,this._onInputStart),t.zoom.off(Mt,this._onInputEnd),t.gyro.off(Dt,this._onGyroEnable),e.removeEventListener(K,this._onMouseEnter,!1),e.removeEventListener(q,this._onMouseLeave,!1),this._enabled=!1,this._interrupted=!1,this._hovering=!1,this._clearTimeout()}_setUninterruptedAfterDelay(t){this._hovering||(this._clearTimeout(),t>0?this._interruptionTimer=window.setTimeout((()=>{this._interrupted=!1,this._interruptionTimer=-1}),t):(this._interrupted=!1,this._interruptionTimer=-1))}_clearTimeout(){this._interruptionTimer>=0&&(window.clearTimeout(this._interruptionTimer),this._interruptionTimer=-1)}}class oi extends o{constructor(t,e={}){super(),this.destroy=()=>{this.exit(),this.off()},this._onSessionEnd=()=>{this.exit(),this.trigger(Ot.VR_END)},this._xrSession=null,this._xrRefSpace=null,this._ctx=t,this._options=e}isAvailable(){return t(this,void 0,void 0,(function*(){const t=window.navigator.xr;return!!t&&t.isSessionSupported(Kt).then((t=>t)).catch((()=>!1))}))}enter(){return t(this,void 0,void 0,(function*(){const t=this._ctx,e=window.navigator.xr;if(!e)return;yield Re.requestSensorPermission();const i=Object.assign({requiredFeatures:[qt]},this._options);yield t.makeXRCompatible();const s=yield e.requestSession(Kt,i);t.bindXRLayer(s);const n=yield s.requestReferenceSpace(qt);this._setSession(s,n),this.trigger(Ot.VR_START,{session:s})}))}exit(){const t=this._xrSession;t&&t.end().catch((()=>{})),this._xrSession=null,this._xrRefSpace=null}canRender(t){const e=this._xrRefSpace;if(!e)return!1;return!!t.getViewerPose(e)}getEyeParams(t){const e=t.session,i=t.getViewerPose(this._xrRefSpace);if(!i)return null;const s=e.renderState.baseLayer;return s?i.views.map((t=>({viewport:s.getViewport(t),vMatrix:t.transform.inverse.matrix,pMatrix:t.projectionMatrix}))):null}_setSession(t,e){this._xrSession=t,this._xrRefSpace=e,t.addEventListener(dt,this._onSessionEnd)}}class ai{constructor(t,e){this.element=t,this.position=e}}class hi{constructor(t,e,{zoom:i=!1}){this._containerEl=Qt(`.${xt.HOTSPOT_CONTAINER}`,t),this._renderer=e,this._hotspots=[],this._zoom=i}refresh(){const t=this._containerEl;if(!t)return;const e=[].slice.apply(t.querySelectorAll(`.${xt.HOTSPOT}`));this._hotspots=e.map((t=>this._parseHotspot(t)))}render(t){const e=this._hotspots,i=.5*this._renderer.width,s=.5*this._renderer.height,n=t.zoom,r="translate(-50%, -50%)",o=this._zoom?`scale(${n})`:"";e.forEach((e=>{const n=e.position,a=d();if(function(t,e){t[0]=e[0],t[1]=e[1],t[2]=e[2]}(a,n),f(a,a,t.viewMatrix),f(a,a,t.projectionMatrix),a[2]>1||a[2]<0)return void e.element.classList.remove(xt.HOTSPOT_VISIBLE);const h=function(t,e){var i=new l(2);return i[0]=t,i[1]=e,i}(a[0]*i+i,-a[1]*s+s);e.element.classList.add(xt.HOTSPOT_VISIBLE),e.element.style.transform=[r,`translate(${h[0]}px, ${h[1]}px)`,o].join(" ")}))}_parseHotspot(t){const e=t.dataset.yaw,i=t.dataset.pitch,s=t.dataset.position;if(e||i){const s=e?parseFloat(e):0,n=i?parseFloat(i):0,r=this._yawPitchToVec3(s,n);return new ai(t,r)}if(s){const e=s.split(" ").map((t=>parseFloat(t)));if(e.length<3)throw new D(F.INSUFFICIENT_ARGS(s,'hotspot attribute "data-position"'),B.INSUFFICIENT_ARGS);return new ai(t,p(e[0],e[1],e[2]))}{const e=p(0,0,-1);return new ai(t,e)}}_yawPitchToVec3(t,e){const i=t*Ft,s=e*Ft,n=d();return n[1]=Math.sin(s),n[2]=Math.cos(s),n[0]=n[2]*Math.sin(-i),n[2]=-n[2]*Math.cos(-i),n}}class li{get count(){return this.geometry.indicies.count}constructor(t,e,i){this.obj=t,this.geometry=e,this.buffers=i}}class ci{get canvas(){return this._canvas}get maxTextureSize(){return this._maxTextureSize}get isWebGL2(){return this._isWebGL2}get supportVAO(){return this._isWebGL2||!!this._extensions.vao}get lost(){return this._contextLost}get debug(){return this._debug}constructor(t,e){this._onContextLost=()=>{this._canvas.classList.add(xt.CTX_LOST),this._contextLost=!0},this._onContextRestore=()=>{this._canvas.classList.remove(xt.CTX_LOST),this._contextLost=!1},this._canvas=t,this._contextLost=!1,this._debug=e,this._extensions={vao:null,loseContext:null}}init(){const t=this._canvas,{gl:e,isWebGL2:i}=this._getContext(t);this._gl=e,this._maxTextureSize=e.getParameter(e.MAX_TEXTURE_SIZE),this._isWebGL2=i,this._isWebGL2||(this._extensions.vao=e.getExtension("OES_vertex_array_object")),this._extensions.loseContext=e.getExtension("WEBGL_lose_context"),t.addEventListener(tt,this._onContextLost),t.addEventListener(et,this._onContextRestore)}destroy(){const t=this._gl,e=this._canvas;t&&(t.bindBuffer(t.ARRAY_BUFFER,null),t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,null)),e.removeEventListener(tt,this._onContextLost),e.removeEventListener(et,this._onContextRestore)}forceLoseContext(){const t=this._extensions.loseContext;t&&t.loseContext()}forceRestoreContext(){const t=this._extensions.loseContext;t&&t.restoreContext()}clear(){const t=this._gl;t.clear(t.COLOR_BUFFER_BIT)}resize(){const t=this._gl;t.viewport(0,0,t.drawingBufferWidth,t.drawingBufferHeight)}viewport(t,e,i,s){this._gl.viewport(t,e,i,s)}createVAO(t,e){const i=this._createNativeVAO(),s=new li(i,t,{indicies:this._createBuffer(),position:this._createBuffer(),uv:this._createBuffer()});return i&&(this._bindNativeVAO(i),this._supplyGeometryData(s,e),this._bindNativeVAO(null),this._unbindBuffers()),s}draw(t,e){const i=this._gl;t.obj?this._bindNativeVAO(t.obj):this._supplyGeometryData(t,e),i.drawElements(i.TRIANGLES,t.count,i.UNSIGNED_SHORT,0),t.obj?this._bindNativeVAO(null):this._unbindBuffers()}releaseVAO(t){t.obj&&this._deleteNativeVAO(t.obj),this._deleteBuffer(t.buffers.indicies),this._deleteBuffer(t.buffers.position),this._deleteBuffer(t.buffers.uv)}getUniformLocations(t,e){const i=this._gl,s=Object.keys(e).reduce(((e,s)=>(e[s]=i.getUniformLocation(t,s),e)),{});return Object.assign(Object.assign({},this._getCommonUniformLocations(t)),s)}updateCommonUniforms(t,e,i){const s=this._gl,n=i.uniformLocations,r=t.matrix,o=c();u(o,e.viewMatrix,r),s.uniformMatrix4fv(n.uMVMatrix,!1,o),s.uniformMatrix4fv(n.uPMatrix,!1,e.projectionMatrix)}updateVRUniforms(t,e,i,s){const n=this._gl,r=t.uniformLocations;n.uniformMatrix4fv(r.uMVMatrix,!1,e),n.uniformMatrix4fv(r.uPMatrix,!1,i),r.uEye&&n.uniform1f(r.uEye,s)}updateUniforms(t){const e=this._gl,i=t.uniforms,s=t.uniformLocations;for(const t in i){const n=i[t],r=s[t];n&&(n.needsUpdate&&n.update(e,r,this._isWebGL2))}}releaseShaderResources(t){const e=this._gl,i=t.uniforms;for(const t in i){const s=i[t];s&&(s.needsUpdate&&s.destroy(e))}e.deleteProgram(t.program)}useProgram(t){this._gl.useProgram(t.program)}createProgram(t,e){const i=this._gl,s=i.createProgram(),n=this._compileShader(i.VERTEX_SHADER,t),r=this._compileShader(i.FRAGMENT_SHADER,e);if(i.attachShader(s,n),i.attachShader(s,r),i.bindAttribLocation(s,0,"position"),i.bindAttribLocation(s,1,"uv"),i.linkProgram(s),this._debug&&!i.getProgramParameter(s,i.LINK_STATUS)){let t=null;throw i.getShaderParameter(n,i.COMPILE_STATUS)?i.getShaderParameter(r,i.COMPILE_STATUS)||(t=i.getShaderInfoLog(r)):t=i.getShaderInfoLog(n),new D(F.FAILED_LINKING_PROGRAM(i.getProgramInfoLog(s),t),B.FAILED_LINKING_PROGRAM)}return i.deleteShader(n),i.deleteShader(r),s}createWebGLTexture(t){const e=this._gl,i=e.createTexture();if(e.bindTexture(e.TEXTURE_2D,i),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,t.wrapS),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,t.wrapT),!t.isVideo()&&this._isWebGL2){const i=e;i.texStorage2D(i.TEXTURE_2D,1,i.RGBA8,t.width,t.height)}return i}createWebGLCubeTexture(t,e){const i=this._gl,s=i.createTexture();if(i.bindTexture(i.TEXTURE_CUBE_MAP,s),i.texParameteri(i.TEXTURE_CUBE_MAP,i.TEXTURE_MIN_FILTER,i.LINEAR),i.texParameteri(i.TEXTURE_CUBE_MAP,i.TEXTURE_MAG_FILTER,i.LINEAR),i.texParameteri(i.TEXTURE_CUBE_MAP,i.TEXTURE_WRAP_S,t.wrapS),i.texParameteri(i.TEXTURE_CUBE_MAP,i.TEXTURE_WRAP_T,t.wrapT),this._isWebGL2){const t=i;t.texStorage2D(t.TEXTURE_CUBE_MAP,1,t.RGBA8,e,e)}return s}makeXRCompatible(){return t(this,void 0,void 0,(function*(){const t=this._gl,e=t.getContextAttributes();e&&!0!==e.xrCompatible&&(yield t.makeXRCompatible())}))}bindXRLayer(t){const e=this._gl,i=new XRWebGLLayer(t,e);t.updateRenderState({baseLayer:i})}bindXRFrame(t){const e=this._gl,i=t.session.renderState.baseLayer;e.bindFramebuffer(e.FRAMEBUFFER,i.framebuffer)}useDefaultFrameBuffer(){const t=this._gl;t.bindFramebuffer(t.FRAMEBUFFER,null)}_createBuffer(){return this._gl.createBuffer()}_deleteBuffer(t){return this._gl.deleteBuffer(t)}_createNativeVAO(){const t=this._gl;if(this._isWebGL2)return t.createVertexArray();{const t=this._extensions.vao;return(null==t?void 0:t.createVertexArrayOES())||null}}_bindNativeVAO(t){const e=this._gl;if(this._isWebGL2)e.bindVertexArray(t);else{const e=this._extensions.vao;null==e||e.bindVertexArrayOES(t)}}_deleteNativeVAO(t){const e=this._gl;if(this._isWebGL2)e.deleteVertexArray(t);else{const e=this._extensions.vao;null==e||e.deleteVertexArrayOES(t)}}_supplyGeometryData(t,e){const i=t.geometry;this._supplyIndiciesData(i.indicies,t.buffers.indicies),this._supplyAttributeData(i.vertices,e.program,"position",t.buffers.position),this._supplyAttributeData(i.uvs,e.program,"uv",t.buffers.uv)}_unbindBuffers(){const t=this._gl;t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,null),t.bindBuffer(t.ARRAY_BUFFER,null)}_supplyIndiciesData(t,e){const i=this._gl;i.bindBuffer(i.ELEMENT_ARRAY_BUFFER,e),i.bufferData(i.ELEMENT_ARRAY_BUFFER,t.data,i.STATIC_DRAW)}_supplyAttributeData(t,e,i,s){const n=this._gl,r=n.getAttribLocation(e,i);r<0||(n.bindBuffer(n.ARRAY_BUFFER,s),n.bufferData(n.ARRAY_BUFFER,t.data,n.STATIC_DRAW),n.vertexAttribPointer(r,t.itemSize,n.FLOAT,!1,0,0),n.enableVertexAttribArray(r))}_compileShader(t,e){const i=this._gl,s=i.createShader(t);return i.shaderSource(s,e),i.compileShader(s),s}_getCommonUniformLocations(t){const e=this._gl;return{uMVMatrix:e.getUniformLocation(t,"uMVMatrix"),uPMatrix:e.getUniformLocation(t,"uPMatrix")}}_getContext(t){const e=["webgl2","webgl","experimental-webgl","webkit-3d","moz-webgl"];let i=null,s=!1;const n={preserveDrawingBuffer:!1,antialias:!1},r=t=>t.statusMessage;t.addEventListener(Q,r);for(const r of e){try{i=t.getContext(r,n),s="webgl2"===r}catch(t){}if(i)break}if(t.removeEventListener(Q,r),!i)throw new D(F.WEBGL_NOT_SUPPORTED,B.WEBGL_NOT_SUPPORTED);return{gl:i,isWebGL2:s}}}class ui{get canvas(){return this._canvas}get width(){return this._elementSize.x}get height(){return this._elementSize.y}get pixelRatio(){return this._pixelRatio}get aspect(){return this._elementSize.x/this._elementSize.y}constructor(t,e){this._canvas=t,this._elementSize={x:0,y:0},this._pixelRatio=1,this.ctx=new ci(t,e)}destroy(){const t=this._canvas;this.ctx.destroy(),t.width=1,t.height=1}resize(){const t=this._canvas,e=this._elementSize,i=window.devicePixelRatio;e.x=t.clientWidth,e.y=t.clientHeight,t.width=e.x*i,t.height=e.y*i,this._pixelRatio=i,this.ctx.resize()}render(t,e){const i=this.ctx,s=t.getMesh();!i.lost&&s&&(i.clear(),i.useProgram(s.program),i.updateCommonUniforms(s,e,s.program),t.update(e),i.updateUniforms(s.program),i.draw(s.vao,s.program))}renderVR(t,e,i){const s=this.ctx,n=t.getMesh(),r=e.getEyeParams(i);r&&n&&(s.bindXRFrame(i),s.useProgram(n.program),s.updateUniforms(n.program),r.forEach(((t,e)=>{const i=t.viewport,r=u(c(),t.vMatrix,n.matrix);s.viewport(i.x,i.y,i.width,i.height),s.updateVRUniforms(n.program,r,t.pMatrix,e),s.draw(n.vao,n.program)})))}}class _i extends o{get rootEl(){return this._rootEl}get renderer(){return this._renderer}get camera(){return this._camera}get control(){return this._control}get vr(){return this._vr}get hotspot(){return this._hotspot}get plugins(){return this._plugins}get projection(){return this._projection}set projection(t){this._initialized&&t?this.load(t):this._projection=t}get initialized(){return this._initialized}get autoplay(){return this._autoplay}get autoInit(){return this._autoInit}get autoResize(){return this._autoResize}get canvasSelector(){return this._canvasSelector}get useResizeObserver(){return this._useResizeObserver}get tabIndex(){return this._tabIndex}set tabIndex(t){const e=this._renderer.canvas;this._tabIndex=t,null!=t?e.tabIndex=t:e.removeAttribute("tabindex")}get maxDeltaTime(){return this._animator.maxDeltaTime}set maxDeltaTime(t){this._animator.maxDeltaTime=t}get debug(){return this._debug}set debug(t){this._debug=t}get initialYaw(){return this._camera.initialYaw}set initialYaw(t){this._camera.initialYaw=t}get initialPitch(){return this._camera.initialPitch}set initialPitch(t){this._camera.initialPitch=t}get initialZoom(){return this._camera.initialZoom}set initialZoom(t){this._camera.initialZoom=t}get yawRange(){return this._camera.yawRange}set yawRange(t){this._camera.yawRange=t,this._projection&&this._projection.updateCamera(this._camera)}get pitchRange(){return this._camera.pitchRange}set pitchRange(t){this._camera.pitchRange=t,this._projection&&this._projection.updateCamera(this._camera)}get zoomRange(){return this._camera.zoomRange}set zoomRange(t){this._camera.zoomRange=t,this._projection&&this._projection.updateCamera(this._camera)}get fov(){return this._camera.fov}set fov(t){const e=this._camera,i=this._control;e.fov=t,e.updateMatrix(),i.sync()}get rotate(){return this._control.rotate}get zoom(){return this._control.zoom}get gyro(){return this._control.gyro}get useGrabCursor(){return this._control.useGrabCursor}set useGrabCursor(t){this._control.useGrabCursor=t}get disableContextMenu(){return this._control.disableContextMenu}set disableContextMenu(t){this._control.disableContextMenu=t}get scrollable(){return this._control.scrollable}set scrollable(t){this._control.scrollable=t}get wheelScrollable(){return this._control.wheelScrollable}set wheelScrollable(t){this._control.wheelScrollable=t}constructor(t,{projection:e=null,initialYaw:i=0,initialPitch:s=0,initialZoom:n=1,yawRange:r=null,pitchRange:o=null,zoomRange:a=null,fov:h=90,useGrabCursor:l=!0,disableContextMenu:c=!1,rotate:u=!0,zoom:_=!0,gyro:d=!1,scrollable:m=!0,wheelScrollable:p=!1,autoplay:g=!1,hotspot:v={},autoInit:E=!0,autoResize:f=!0,canvasSelector:y="canvas",useResizeObserver:b=!0,on:T={},plugins:R=[],maxDeltaTime:w=1/30,tabIndex:C=0,debug:L=!1}={}){super(),this.renderFrame=t=>{const e=this._camera,i=this._renderer,s=this._control,n=this._hotspot,r=this._autoplay,o=this._projection;o&&(this._emit(Ot.BEFORE_RENDER),r.playing&&(r.update(t),s.sync()),e.animation?e.animation.update(t):s.update(t),i.render(o,e),n.render(e),e.changed&&this._emit(Ot.VIEW_CHANGE,{yaw:e.yaw,pitch:e.pitch,zoom:e.zoom,quaternion:[e.quaternion[0],e.quaternion[1],e.quaternion[2],e.quaternion[3]]}),e.onFrameRender(),this._emit(Ot.RENDER))},this._renderFrameOnDemand=t=>{var e;const i=this._camera,s=this._control,n=this._autoplay,r=null===(e=this._projection)||void 0===e?void 0:e.getTexture();this._initialized&&r&&(i.animation||s.animating||n.playing||r.isVideo())&&this.renderFrame(t)},this._renderVRFrame=(t,e)=>{const i=this._vr,s=this._projection,n=this._renderer;s&&(this._emit(Ot.BEFORE_RENDER),n.renderVR(s,i,e),this._emit(Ot.RENDER))},this._rootEl=((t,e)=>{const i=Qt(t,e);if(!i)throw $t(t)?new D(F.ELEMENT_NOT_FOUND(t),B.ELEMENT_NOT_FOUND):new D(F.WRONG_TYPE(t,["HTMLElement","string"]),B.WRONG_TYPE);return i})(t),this._plugins=R,this._initialized=!1,this._autoInit=E,this._autoResize=f,this._canvasSelector=y,this._useResizeObserver=b,this._tabIndex=C,this._debug=L;const x=((t,e)=>{const i=t.querySelector(e);if(!i)throw new D(F.CANVAS_NOT_FOUND,B.CANVAS_NOT_FOUND);return i})(this._rootEl,y);this._renderer=new ui(x,L),this._camera=new de({initialYaw:i,initialPitch:s,initialZoom:n,fov:h,yawRange:r,pitchRange:o,zoomRange:a}),this._control=new we(x,this._camera,{useGrabCursor:l,scrollable:m,wheelScrollable:p,disableContextMenu:c,rotate:u,zoom:_,gyro:d}),this._animator=new si(w),this._autoplay=new ri(this,x,g),this._projection=e,this._autoResizer=new ni(b,(()=>this.resize())),this._vr=new oi(this._renderer.ctx),this._hotspot=new hi(this._rootEl,this._renderer,v),this._addEventHandlers(T),e&&E&&this.init()}destroy(){this._camera.destroy(),this._animator.stop(),this._renderer.destroy(),this._control.destroy(),this._autoResizer.disable(),this._projection&&(this._projection.releaseAllResources(this._renderer.ctx),this._projection=null),this._plugins.forEach((t=>t.destroy(this))),this._initialized=!1}init(){return t(this,void 0,void 0,(function*(){if(!this._projection)throw new D(F.PROVIDE_PROJECTION_FIRST,B.PROVIDE_PROJECTION_FIRST);const t=this._renderer,e=this._camera,i=this._control,s=this._animator,n=this._hotspot,r=this._projection,o=t.canvas;this._bindComponentEvents(),t.ctx.init(),this._resizeComponents(),e.updateMatrix(),this._autoResize&&this._autoResizer.enable(o),this._autoplay.enableBlocked||this._autoplay.enable(),this._plugins.forEach((t=>{t.init(this)}));const a=yield this._loadTexture(r);this._applyProjection(r,a,null),n.refresh(),s.start(this._renderFrameOnDemand),yield i.enable(),null==this._tabIndex||o.hasAttribute("tabIndex")||(o.tabIndex=this._tabIndex),this._initialized=!0,this.renderFrame(0),this._emit(Ot.READY)}))}load(e){return t(this,void 0,void 0,(function*(){if(!e)return!1;if(this._initialized){const t=yield this._loadTexture(e);this._applyProjection(e,t,this._projection),this.renderFrame(0)}else this._projection=e,this.init();return!0}))}resize(){if(!this._initialized)return;this._resizeComponents(),this.renderFrame(0);const{width:t,height:e}=this._renderer;this._emit(Ot.RESIZE,{width:t,height:e})}addPlugins(...t){this._initialized&&t.forEach((t=>{t.init(this)})),this._plugins.push(...t)}removePlugins(...t){t.forEach((t=>{const e=this._plugins.indexOf(t);e<0||(t.destroy(this),this._plugins.splice(e,1))}))}_emit(t,...e){const i=e?e[0]:{};this.trigger(t,Object.assign({type:t,target:this},i))}_applyProjection(t,e,i){const s=this._camera,n=this._control,r=this._renderer;i&&i.releaseAllResources(this._renderer.ctx),t.applyTexture(r.ctx,e),t.updateCamera(s),t.updateControl(n),this._projection=t,this._emit(Ot.PROJECTION_CHANGE,{projection:t})}_loadTexture(e){return t(this,void 0,void 0,(function*(){const t=new ii,{src:i,video:s}=e;this._emit(Ot.LOAD_START,{src:i,video:s});const n=yield t.load(i,s);return this._emit(Ot.LOAD,{src:i,video:s}),n}))}_resizeComponents(){const t=this._renderer,e=this._camera,i=this._control;t.resize(),e.resize(t.width,t.height),i.resize(t.width,t.height)}_addEventHandlers(t){Object.keys(t).forEach((e=>{this.on(e,t[e])}))}_bindComponentEvents(){const t=this._rootEl,e=this._control,i=this._animator,s=this._renderer,n=this._vr;[Bt,Pt,Mt].forEach((t=>{e.rotate.on(t,(e=>{this._emit(t,e)})),e.zoom.on(t,(e=>{this._emit(t,e)}))})),n.on(Ot.VR_START,(e=>{t.classList.add(xt.IN_VR),i.changeContext(e.session),i.start(this._renderVRFrame),this._emit(Ot.VR_START)})),n.on(Ot.VR_END,(()=>{t.classList.remove(xt.IN_VR),s.ctx.useDefaultFrameBuffer(),i.changeContext(window),i.start(this._renderFrameOnDemand),this.resize(),this._emit(Ot.VR_END)}))}}_i.VERSION="4.0.0-beta.4";class di{constructor(){this.matrix=c(),this.rotation=b(),this.position=p(0,0,0),this.scale=p(1,1,1)}updateMatrix(){!function(t,e,i,s){var n=e[0],r=e[1],o=e[2],a=e[3],h=n+n,l=r+r,c=o+o,u=n*h,_=n*l,d=n*c,m=r*l,p=r*c,g=o*c,v=a*h,E=a*l,f=a*c,y=s[0],b=s[1],T=s[2];t[0]=(1-(m+g))*y,t[1]=(_+f)*y,t[2]=(d-E)*y,t[3]=0,t[4]=(_-f)*b,t[5]=(1-(u+g))*b,t[6]=(p+v)*b,t[7]=0,t[8]=(d+E)*T,t[9]=(p-v)*T,t[10]=(1-(u+m))*T,t[11]=0,t[12]=i[0],t[13]=i[1],t[14]=i[2],t[15]=1}(this.matrix,this.rotation,this.position,this.scale)}}class mi{constructor({className:t={}}={}){this._startLoading=({target:t})=>{t.rootEl.appendChild(this._container),t.initialized?t.once(Ot.LOAD,this._detachElements):t.once(Ot.READY,this._detachElements)},this._detachElements=({target:t})=>{const e=this._container;e&&e.parentElement===t.rootEl&&t.rootEl.removeChild(e)},this.className=t,this._container=this._createElements()}init(t){t.on(Ot.LOAD_START,this._startLoading)}destroy(t){t.off(Ot.LOAD_START,this._startLoading),this._detachElements({target:t})}_createElements(){const t=Object.assign(Object.assign({},this.className),mi.DEFAULT_CLASS),e=Jt(t.CONTAINER),i=Jt(t.RING);return e.appendChild(i),e}}mi.DEFAULT_CLASS={CONTAINER:"view360-spinner",RING:"view360-spinner-ring"};class pi{constructor(t){this.position=t.position,this.order=t.order}}const gi={CONTROLS_ROOT:"view360-controls",CONTROLS_BG:"view360-controls-background",CONTROLS_MAIN:"view360-controls-main",CONTROLS_TOP:"view360-controls-top",CONTROLS_BOTTOM:"view360-controls-bottom",CONTROLS_MID:"view360-controls-mid",CONTROLS_LEFT:"view360-controls-left",CONTROLS_RIGHT:"view360-controls-right",CONTROLS_FLOAT_LEFT:"view360-controls-float-left",CONTROLS_FLOAT_RIGHT:"view360-controls-float-right",CONTROLS_BUTTON:"view360-controls-button",PROGRESS_ROOT:"view360-controls-progress",VOLUME_ROOT:"view360-controls-volume",RANGE_ROOT:"view360-range",RANGE_TRACK:"view360-range-track",RANGE_THUMB:"view360-range-thumb",RANGE_FILLER:"view360-range-filler",PLAY_BUTTON:"view360-controls-play",PAUSE_BUTTON:"view360-controls-pause",UNMUTED_BUTTON:"view360-controls-unmuted",MUTED_BUTTON:"view360-controls-muted",FULLSCREEN_BUTTON:"view360-controls-fullscreen",FULLSCREEN_EXIT_BUTTON:"view360-controls-fullscreen-exit",VR_BUTTON:"view360-controls-vr",GYRO_ENABLED:"view360-controls-gyro-enabled",GYRO_DISABLED:"view360-controls-gyro-disabled",VIDEO_TIME_DISPLAY:"view360-controls-time",PIEVIEW_ROOT:"view360-controls-pie",FIXED:"view360-controls-fixed",UNAVAILABLE:"view360-controls-unavailable",HIDDEN:"view360-controls-hidden"},vi={TOP_LEFT:"top-left",TOP_RIGHT:"top-right",MAIN_TOP:"main-top",MAIN_BOTTOM:"main-bottom",MAIN_LEFT:"main-left",MAIN_RIGHT:"main-right"};class Ei extends o{constructor(){super(),this._onHold=({srcEvent:t,isTouch:e})=>{var i;const s=this._bbox;if(!s)return;const n=e?t.touches[0].pageX:t.pageX,r=s.x+(null!==(i=window.scrollX)&&void 0!==i?i:window.pageXOffset),o=te(n,r,r+s.width),a=(o-r)/s.width;this._motion.reset(o),this.thumbEl.classList.add(this._fixedClass),this.trigger(Pt,a)},this._onChange=({delta:t})=>{var e;const i=this._motion,s=this._bbox;if(!s)return;i.setNewEndByDelta(t.x),i.update(1);const n=s.x+(null!==(e=window.scrollX)&&void 0!==e?e:window.pageXOffset),r=(te(i.val,n,n+s.width)-n)/s.width;this.trigger(Nt,r)},this._onRelease=()=>{this._bbox&&(this.thumbEl.classList.remove(this._fixedClass),this.trigger(Mt))};const t=document.createElement(mt),e=document.createElement(mt),i=document.createElement(mt),s=document.createElement(mt);t.draggable=!1,e.appendChild(s),e.appendChild(i),t.appendChild(e),this.rootEl=t,this.trackEl=e,this.thumbEl=i,this.fillerEl=s,this._mouseInput=new me,this._touchInput=new pe,this._motion=new ue({duration:1,range:Gt,easing:t=>t}),this._bbox={x:0,y:0,width:0,height:0,left:0,right:0,bottom:0,top:0},this._fixedClass=gi.FIXED}init(t){const e=this._mouseInput,i=this._touchInput;this.rootEl.classList.add(t.RANGE_ROOT),this.trackEl.classList.add(t.RANGE_TRACK),this.thumbEl.classList.add(t.RANGE_THUMB),this.fillerEl.classList.add(t.RANGE_FILLER),this._fixedClass=t.FIXED,e.on(Pt,this._onHold),i.on(Pt,this._onHold),e.on(Mt,this._onRelease),i.on(Mt,this._onRelease),e.on(Nt,this._onChange),i.on(Nt,this._onChange),e.enable(this.rootEl),i.enable(this.rootEl),this.resize()}destroy(){const t=this._mouseInput,e=this._touchInput;this.rootEl.className="",this.trackEl.className="",this.thumbEl.className="",this.fillerEl.className="",t.off(),e.off(),t.disable(),e.disable()}resize(){this._bbox=this.trackEl.getBoundingClientRect()}updateStyle(t){const e=this._bbox.width,i=te(t,0,1);this.fillerEl.style.width=100*i+"%",this.thumbEl.style.transform=`translateX(${i*e}px)`}}class fi extends pi{get element(){return this._rangeControl.rootEl}constructor({position:t=vi.MAIN_TOP,order:e=9999}={}){super({position:t,order:e}),this._onResize=()=>{this._rangeControl.resize()},this._onTimeUpdate=()=>{const t=this._video;t&&(this._currentTime=t.source.currentTime,this._rangeControl.updateStyle(this._currentTime/this._duration))},this._onDurationChange=()=>{const t=this._video;t&&(this._duration=t.source.duration,this._rangeControl.updateStyle(this._currentTime/this._duration))},this._onHold=t=>{const e=this._video,i=this._controlBar;if(!e||!i)return;const s=e.isPaused();e.source.pause();const n=e.source.duration*t;e.source.currentTime=n,e.source.dispatchEvent(new CustomEvent(Wt,{detail:{time:n}})),i.rootEl.classList.add(i.className.FIXED),this._wasPaused=!this._playPromise&&s},this._onControl=t=>{const e=this._video;if(!e)return;const i=e.source.duration*t;e.source.currentTime=i,e.source.dispatchEvent(new CustomEvent(Wt,{detail:{time:i}}))},this._onRelease=()=>{const t=this._video,e=this._controlBar;t&&e&&(this._wasPaused||this._playPromise||(this._playPromise=t.source.play().catch((()=>{})),this._playPromise.then((()=>{this._playPromise=null})),e.rootEl.classList.remove(e.className.FIXED))),this._wasPaused=!1},this.position=t,this.order=e,this._controlBar=null,this._rangeControl=new Ei,this._video=null,this._wasPaused=!1,this._currentTime=0,this._duration=0,this._playPromise=null}init(t,e){var i;const s=null===(i=t.projection)||void 0===i?void 0:i.getTexture(),n=this.element,r=this._rangeControl,o=e.className.UNAVAILABLE;s&&s.isVideo()?(n.classList.remove(o),n.classList.add(e.className.PROGRESS_ROOT),t.on(Ot.RESIZE,this._onResize),s.source.addEventListener(lt,this._onTimeUpdate),s.source.addEventListener(ct,this._onDurationChange),s.source.addEventListener(Wt,this._onTimeUpdate),r.init(e.className),r.on(Pt,this._onHold),r.on(Nt,this._onControl),r.on(Mt,this._onRelease),this._video=s,this._currentTime=s.source.currentTime,this._duration=s.source.duration,this._controlBar=e,r.updateStyle(this._currentTime/this._duration)):n.classList.add(o)}destroy(t){const e=this._video;t.off(Ot.RESIZE,this._onResize),e&&(e.source.removeEventListener(lt,this._onTimeUpdate),e.source.removeEventListener(ct,this._onDurationChange),e.source.removeEventListener(Wt,this._onTimeUpdate)),this._rangeControl.destroy(),this._video=null,this._playPromise=null}}class yi extends pi{constructor({position:t=vi.MAIN_LEFT,order:e=9999}={}){super({position:t,order:e}),this._onClick=()=>{const t=this._video;t&&(this._paused?t.source.play():t.source.pause())},this._onPlay=()=>{if(!this._controlBar)return;const t=this.element,e=this._controlBar.className;t.classList.add(e.PAUSE_BUTTON),t.classList.remove(e.PLAY_BUTTON),t.title="Pause Video",this._paused=!1},this._onPause=()=>{if(!this._controlBar)return;const t=this.element,e=this._controlBar.className;t.classList.add(e.PLAY_BUTTON),t.classList.remove(e.PAUSE_BUTTON),t.title="Play Video",this._paused=!0},this.element=document.createElement(pt),this._video=null,this._paused=!0,this._controlBar=null}init(t,e){var i;const s=this.element,n=null===(i=t.projection)||void 0===i?void 0:i.getTexture(),r=e.className,o=r.UNAVAILABLE;if(!n||!n.isVideo())return void s.classList.add(o);s.classList.add(r.CONTROLS_BUTTON),s.classList.remove(o);const a=n.isPaused();this._video=n,this._paused=a,this._controlBar=e,a?this._onPause():this._onPlay(),s.addEventListener(J,this._onClick),n.source.addEventListener(rt,this._onPlay),n.source.addEventListener(ot,this._onPause)}destroy(){const t=this._video,e=this.element;t&&(e.className="",e.removeEventListener(J,this._onClick),t.source.removeEventListener(rt,this._onPlay),t.source.removeEventListener(ot,this._onPause),this._video=null,this._paused=!0,this._controlBar=null)}}class bi extends pi{get element(){return this._rootEl}constructor({position:t=vi.MAIN_RIGHT,order:e=9999}={}){super({position:t,order:e}),this._onResize=()=>{this._rangeControl.resize(),this._updateDisplay()},this._onClick=()=>{const t=this._video;t&&!this._rootEl.disabled&&(t.source.muted=!t.source.muted)},this._onVolumeChange=()=>{const t=this._buttonEl,e=this._video,i=this._controlBar;if(!e||!i)return;const s=i.className;e.source.muted||0===e.source.volume?(t.classList.add(s.MUTED_BUTTON),t.classList.remove(s.UNMUTED_BUTTON)):(t.classList.add(s.UNMUTED_BUTTON),t.classList.remove(s.MUTED_BUTTON)),this._updateDisplay()},this._onHold=t=>{const e=this._video,i=this._controlBar;if(!e||!i)return;const s=i.className;e.source.volume=t,this._rootEl.classList.add(s.FIXED),i.containerEl.classList.add(s.FIXED),this._updateDisplay()},this._onChange=t=>{const e=this._video;e&&(e.source.volume=t,e.source.muted=!(t>0),this._updateDisplay())},this._onRelease=()=>{const t=this._controlBar;if(!t)return;const e=t.className;this._rootEl.classList.remove(e.FIXED),t.containerEl.classList.remove(e.FIXED)},this._updateDisplay=()=>{const t=this._video,e=this._rootEl;if(!t)return;if(!t.hasAudio())return void(e.disabled=!0);e.disabled=!1;const i=t.source.muted?0:t.source.volume;this._rangeControl.updateStyle(i)},this._controlBar=null,this._rangeControl=new Ei,this._createElements(),this._video=null}init(t,e){var i;const s=null===(i=t.projection)||void 0===i?void 0:i.getTexture(),n=this._rootEl,r=this._buttonEl,o=this._rangeControl,a=e.className,h=a.UNAVAILABLE;s&&s.isVideo()?(n.classList.remove(h),n.classList.add(a.CONTROLS_BUTTON),n.classList.add(a.VOLUME_ROOT),r.classList.add(a.CONTROLS_BUTTON),s.source.muted?r.classList.add(a.MUTED_BUTTON):r.classList.add(a.UNMUTED_BUTTON),t.on(Ot.RESIZE,this._onResize),n.addEventListener(_t,this._onResize),r.addEventListener(J,this._onClick),s.source.addEventListener(ht,this._onVolumeChange),s.source.addEventListener(at,this._updateDisplay),s.source.addEventListener(ut,this._updateDisplay),o.init(a),o.on(Pt,this._onHold),o.on(Nt,this._onChange),o.on(Mt,this._onRelease),this._controlBar=e,this._video=s,this._updateDisplay()):n.classList.add(h)}destroy(t){const e=this._video,i=this._buttonEl,s=this._rootEl;s.className="",i.className="",t.off(Ot.RESIZE,this._onResize),s.removeEventListener(_t,this._onResize),i.removeEventListener(J,this._onClick),e&&(e.source.removeEventListener(ht,this._onVolumeChange),e.source.removeEventListener(at,this._updateDisplay),e.source.removeEventListener(ut,this._updateDisplay)),this._controlBar=null,this._rangeControl.destroy(),this._video=null}_createElements(){const t=document.createElement(pt),e=document.createElement(mt);t.appendChild(this._rangeControl.rootEl),t.appendChild(e),t.title="Toggle Mute",this._rootEl=t,this._buttonEl=e}}class Ti extends pi{constructor({position:t=vi.MAIN_RIGHT,order:e=9999}={}){super({position:t,order:e}),this._onClick=()=>{const t=this._targetEl;t&&(ae()?this._exitFullscreen():this._requestFullscreen(t))},this._onFullscreenChange=()=>{const t=this.element,e=this._controlBar;if(!e)return;const i=e.className;ae()?(t.classList.add(i.FULLSCREEN_EXIT_BUTTON),t.classList.remove(i.FULLSCREEN_BUTTON)):(t.classList.add(i.FULLSCREEN_BUTTON),t.classList.remove(i.FULLSCREEN_EXIT_BUTTON))},this.element=document.createElement(pt),this.element.title="Toggle Fullscreen",this._controlBar=null,this._targetEl=null}init(t,e){const i=this.element,s=e.className;this._fullscreenAvailable()?(i.classList.add(s.CONTROLS_BUTTON),i.classList.remove(s.UNAVAILABLE),i.addEventListener(J,this._onClick),this._addFullscreenHandlers(),ae()?i.classList.add(s.FULLSCREEN_EXIT_BUTTON):i.classList.add(s.FULLSCREEN_BUTTON),this._controlBar=e,this._targetEl=t.rootEl):i.classList.add(s.UNAVAILABLE)}destroy(){const t=this.element;t.className="",t.removeEventListener(J,this._onClick),this._removeFullscreenHandlers(),this._controlBar=null,this._targetEl=null}_fullscreenAvailable(){return Rt.some((t=>!!document[t]))}_requestFullscreen(t){for(const e of Rt){const i=t[e];if(i)return void i.call(t)}}_exitFullscreen(){for(const t of Ct){const e=document[t];if(e)return void e.call(document)}}_addFullscreenHandlers(){Lt.forEach((t=>{document.addEventListener(t,this._onFullscreenChange)}))}_removeFullscreenHandlers(){Lt.forEach((t=>{document.removeEventListener(t,this._onFullscreenChange)}))}}class Ri extends pi{constructor({position:t=vi.MAIN_LEFT,order:e=9999}={}){super({position:t,order:e}),this._onTimeUpdate=()=>{const t=this._video;t&&(this._currentTime=t.source.currentTime,this._updateDisplay())},this._onDurationChange=()=>{const t=this._video;t&&(this._duration=t.source.duration,this._updateDisplay())},this._onCustomTimeChange=t=>{this._currentTime=t.detail.time,this._updateDisplay()},this.element=document.createElement(mt),this._video=null,this._currentTime=0,this._duration=0}init(t,e){var i;const s=null===(i=t.projection)||void 0===i?void 0:i.getTexture(),n=this.element,r=e.className;s&&s.isVideo()?(n.classList.add(r.VIDEO_TIME_DISPLAY),n.classList.remove(r.UNAVAILABLE),s.source.addEventListener(lt,this._onTimeUpdate),s.source.addEventListener(ct,this._onDurationChange),s.source.addEventListener(Wt,this._onCustomTimeChange),this._video=s,this._currentTime=s.source.currentTime,this._duration=s.source.duration,this._updateDisplay()):n.classList.add(r.UNAVAILABLE)}destroy(){const t=this._video;t&&(this.element.className="",t.source.removeEventListener(lt,this._onTimeUpdate),t.source.removeEventListener(ct,this._onDurationChange),t.source.removeEventListener(Wt,this._onCustomTimeChange),this._video=null)}_updateDisplay(){const t=this._currentTime,e=Math.floor(t/60),i=Math.floor(t-60*e),s=i<10?`0${i}`:i,n=this._duration,r=Math.floor(n/60),o=Math.floor(n-60*r),a=o<10?`0${o}`:o;this.element.innerText=`${e}:${s} / ${r}:${a}`}}class wi extends pi{constructor({resetCamera:t=!0,position:e=vi.TOP_RIGHT,order:i=9999}={}){super({position:e,order:i}),this._onClick=()=>{const t=this._viewer,e=this.resetCamera;if(!t||!e)return;const{yaw:i=t.initialYaw,pitch:s=t.initialPitch,zoom:n=t.initialZoom,duration:r=500}=ne(e);t.camera.animateTo({yaw:i,pitch:s,zoom:n,duration:r})},this._updatePie=({target:t})=>{const e=this._piePathEl,i=this._rangeCircleEl,s=t.camera,n=s.getHorizontalFov(),r=s.getYawRange(s.zoom),o=.5*n,a=24*Math.PI,h=a*n/360,l=a*(s.yaw+o+90)/360;if(e.setAttribute("stroke-dasharray",`${h} ${a-h}`),e.setAttribute("stroke-dashoffset",`${l}`),isFinite(r.min)&&isFinite(r.max)){const t=45*Math.PI,e=(ie(r.min,-180,180)-o)/360,s=(ie(r.max,-180,180)+o)/360,n=t*Math.abs(s-e),a=-t*(e-.25);i.setAttribute("stroke-dasharray",`${n} ${t-n}`),i.setAttribute("stroke-dashoffset",`${a}`)}else i.setAttribute("stroke-dasharray",""),i.setAttribute("stroke-dashoffset","")},this.element=document.createElement(mt),this.element.title="Reset view",this.resetCamera=t,this._createPieElements(),this._viewer=null}init(t,e){const i=this.element;t.initialized?this._updatePie({target:t}):t.once(Ot.READY,this._updatePie);const s=e.className.PIEVIEW_ROOT;i.classList.add(s),this.resetCamera&&i.addEventListener(J,this._onClick),t.on(Ot.VIEW_CHANGE,this._updatePie),this._viewer=t}destroy(t){const e=this.element;e.removeEventListener(J,this._onClick),e.className="",t.off(Ot.READY,this._updatePie),t.off(Ot.VIEW_CHANGE,this._updatePie),this._viewer=null}_createPieElements(){const t=this.element,e=document.createElementNS(Xt,"svg");e.setAttribute("viewBox","0 0 48 48"),e.setAttribute("width","100%"),e.setAttribute("height","100%");const i=document.createElementNS(Xt,"circle");i.setAttribute("stroke","currentColor"),i.setAttribute("fill","transparent"),i.setAttribute("cx","24"),i.setAttribute("cy","24"),i.setAttribute("r","12"),i.setAttribute("stroke-width","24"),e.appendChild(i);const s=document.createElementNS(Xt,"circle");s.setAttribute("stroke","currentColor"),s.setAttribute("fill","transparent"),s.setAttribute("cx","24"),s.setAttribute("cy","24"),s.setAttribute("r","22.5"),s.setAttribute("stroke-width","3"),e.appendChild(s),t.appendChild(e),this._piePathEl=i,this._rangeCircleEl=s}}class Ci extends pi{constructor({position:t=vi.MAIN_RIGHT,order:e=9999}={}){super({position:t,order:e}),this._onClick=()=>{const t=this._viewer;t&&t.vr.enter()},this.element=document.createElement(pt),this.element.title="Enter VR",this._viewer=null}init(t,e){const i=this.element,s=e.className;i.classList.add(s.UNAVAILABLE),i.classList.add(s.VR_BUTTON),i.classList.add(s.CONTROLS_BUTTON),t.vr.isAvailable().then((t=>{t&&i.classList.remove(s.UNAVAILABLE)})),i.addEventListener(J,this._onClick),this._viewer=t}destroy(){const t=this.element;t.className="",t.removeEventListener(J,this._onClick),this._viewer=null}}class Li extends pi{constructor({position:t=vi.MAIN_RIGHT,order:e=9999}={}){super({position:t,order:e}),this._onClick=()=>{const t=this._viewer,e=this._controlBar;if(!t||!e)return;const i=t.control.gyro;i.enabled?i.disable():Re.requestSensorPermission().then((t=>{t?i.enable():this.element.classList.add(e.className.UNAVAILABLE)}))},this._updateStyle=()=>{const t=this.element,e=this._viewer,i=this._controlBar;if(!e||!i)return;const s=e.control.gyro,n=i.className;s.enabled?(t.classList.add(n.GYRO_ENABLED),t.classList.remove(n.GYRO_DISABLED)):(t.classList.add(n.GYRO_DISABLED),t.classList.remove(n.GYRO_ENABLED))},this.element=document.createElement(mt),this.element.title="Toggle gyroscope control"}init(t,e){const i=this.element,s=e.className;i.addEventListener(J,this._onClick),i.classList.add(s.CONTROLS_BUTTON),i.classList.add(s.UNAVAILABLE);const n=()=>{i.classList.remove(s.UNAVAILABLE),t.control.gyro.on(Dt,this._updateStyle),t.control.gyro.on(Ut,this._updateStyle)};he()?n():Re.isAvailable().then((t=>{t&&n()})),this._controlBar=e,this._viewer=t,this._updateStyle()}destroy(t){const e=this.element;t.control.gyro.off(Dt,this._updateStyle),t.control.gyro.off(Ut,this._updateStyle),e.removeEventListener(J,this._onClick),e.className="",this._controlBar=null,this._viewer=null}}class xi{get enabled(){return!!this._targetEl}get hidden(){return this._controlBar.containerEl.classList.contains(this._hiddenClass)}get _hiddenClass(){return this._controlBar.className.HIDDEN}get _fixedClass(){return this._controlBar.className.FIXED}constructor(t,{initialDelay:e=3e3,delay:i=0,idleDelay:s=3e3}){this._onMouseEnter=()=>{this._isCursorInside=!0,this.show()},this._onMouseLeave=()=>{this._isCursorInside=!1,this._hideAfterDelay()},this._onMouseMove=()=>{this._isFullscreen&&this.showTemporaliy()},this._onHold=t=>{this._isGrabbing=!0,"mouse"===t.pointerType&&(this._isCursorInside=!0),window.addEventListener(k,this._onRelease),this.show()},this._onRelease=()=>{this._isGrabbing=!1,window.removeEventListener(k,this._onRelease),this._hideAfterDelay()},this._onVideoPlay=()=>{this._targetEl&&this._controlBar.containerEl.classList.remove(this._fixedClass)},this._onVideoPause=()=>{this._targetEl&&this._controlBar.containerEl.classList.add(this._fixedClass)},this._onFullscreenChange=()=>{this._isFullscreen=ae(),this._isFullscreen&&this._hideAfterDelay()},this._controlBar=t,this._initialDelay=e,this._delay=i,this._idleDelay=s,this._timer=-1,this._isCursorInside=!1,this._isGrabbing=!1,this._isFullscreen=!1,this._video=null,this._targetEl=null}enable(t){var e;this._targetEl&&this.disable(t);const i=this._initialDelay,s=t.rootEl;this._targetEl=t.rootEl,this._timer=window.setTimeout((()=>{this.hide()}),i),s.addEventListener(z,this._onHold),s.addEventListener(K,this._onMouseEnter),s.addEventListener(V,this._onMouseMove),s.addEventListener(q,this._onMouseLeave),this._addFullscreenHandlers();const n=null===(e=t.projection)||void 0===e?void 0:e.getTexture();n&&n.isVideo()&&(n.isPaused()&&this._controlBar.containerEl.classList.add(this._fixedClass),n.source.addEventListener(rt,this._onVideoPlay),n.source.addEventListener(ot,this._onVideoPause),this._video=n)}disable(t){if(!this._targetEl)return;const e=this._controlBar,i=t.rootEl,s=this._video;i.removeEventListener(z,this._onHold),window.removeEventListener(k,this._onRelease),i.removeEventListener(K,this._onMouseEnter),i.removeEventListener(V,this._onMouseMove),i.removeEventListener(q,this._onMouseLeave),this._removeFullscreenHandlers(),window.clearTimeout(this._timer),e.containerEl.classList.remove(this._fixedClass),s&&(s.source.removeEventListener(rt,this._onVideoPlay),s.source.removeEventListener(ot,this._onVideoPause)),this._isCursorInside=!1,this._isGrabbing=!1,this._video=null,this._targetEl=null}show(){this._clearHideTimer(),this._controlBar.containerEl.classList.remove(this._hiddenClass)}showTemporaliy(){this.show(),this._hideAfterDelay(this._idleDelay)}hide(){this._clearHideTimer(),this._controlBar.containerEl.classList.add(this._hiddenClass)}_clearHideTimer(){this._timer&&(window.clearTimeout(this._timer),this._timer=-1)}_hideAfterDelay(t=this._delay){this._isGrabbing||!this._isFullscreen&&this._isCursorInside||(this._clearHideTimer(),t<=0?this.hide():this._timer=window.setTimeout((()=>{this.hide()}),t))}_addFullscreenHandlers(){Lt.forEach((t=>{document.addEventListener(t,this._onFullscreenChange)}))}_removeFullscreenHandlers(){Lt.forEach((t=>{document.removeEventListener(t,this._onFullscreenChange)}))}}class Oi{constructor(){this._onKeyDown=t=>{const e=this._video;if(!e)return;t.preventDefault(),t.stopPropagation();const i=e.source,s=null!=t.keyCode?bt[t.keyCode]:Tt[t.key];switch(s){case"LEFT":case"RIGHT":return this._changeVideoTime(i,"RIGHT"===s);case"UP":case"DOWN":return this._changeVideoVolume(i,"UP"===s)}(32===t.keyCode||" "===t.key)&&this._toggleVideo(e)}}enable(t,e){this._video=e,t.addEventListener(Z,this._onKeyDown,!0)}disable(t){this._video=null,t.removeEventListener(Z,this._onKeyDown,!0)}_changeVideoTime(t,e){const i=e?5:-5;t.currentTime+=i,t.dispatchEvent(new CustomEvent(Wt,{detail:{time:t.currentTime}}))}_changeVideoVolume(t,e){const i=e?.1:-.1;t.muted?t.volume=te(i,0,1):t.volume=te(t.volume+i,0,1),t.volume>0?t.muted=!1:t.muted=!0}_toggleVideo(t){t.isPaused()?t.source.play():t.source.pause()}}class Ai{get rootEl(){return this._rootEl}get containerEl(){return this._containerEl}get backgroundEl(){return this._bgEl}get items(){return this._items}get customItems(){return this._customItems}constructor({autoHide:t,showBackground:e,clickToPlay:i=!0,keyboardControls:s=!0,progressBar:n=!0,playButton:r=!0,volumeButton:o=!0,fullscreenButton:a=!0,videoTime:h=!0,pieView:l=!0,vrButton:c=!0,gyroButton:u=!0,className:_={},customItems:d=[]}={}){var m;this._onStaticClick=({target:t,isTouch:e})=>{var i;const s=this._autoHider;if(e){if(!s.enabled)return;s.hidden?s.showTemporaliy():s.hide()}else{if(!this.clickToPlay)return;const e=null===(i=t.projection)||void 0===i?void 0:i.getTexture();if(!e||!e.isVideo())return;e.isPaused()?e.source.play():e.source.pause()}},this._onNewSrcLoad=({target:t})=>{const e=this._items;this._updateBackground(t),this._updateAutoHide(t),this._updateKeyboardHandler(t),Object.keys(e).forEach((i=>{e[i].forEach((e=>{e.destroy(t,this),e.init(t,this)}))}))},this.autoHide=t,this.showBackground=e,this.clickToPlay=i,this.keyboardControls=s,this.progressBar=n,this.playButton=r,this.volumeButton=o,this.fullscreenButton=a,this.videoTime=h,this.pieView=l,this.vrButton=c,this.gyroButton=u,this.className=Object.assign(Object.assign({},Ai.DEFAULT_CLASS),_);const p=null!==(m=_.CONTROLS_ROOT)&&void 0!==m?m:Ai.DEFAULT_CLASS.CONTROLS_ROOT;this._rootEl=Jt(p),this._createPositionWrappers(),this._items=Object.keys(Ai.POSITION).reduce(((t,e)=>(t[Ai.POSITION[e]]=[],t)),{}),this._customItems=d,this._autoHider=new xi(this,ne(t)),this._videoControl=new Oi,d.forEach((t=>{this._items[t.position].push(t)}))}init(t){const e=t.rootEl,i=this._rootEl,s=this._createDefaultItems();this._updateBackground(t),this._updateAutoHide(t),this._updateKeyboardHandler(t),e.appendChild(i),this._addItem(t,s),this._addItem(t,this._customItems),t.on(Ot.PROJECTION_CHANGE,this._onNewSrcLoad),t.on(Ot.STATIC_CLICK,this._onStaticClick)}destroy(t){const e=t.rootEl,i=this._rootEl,s=this._items;i.parentElement===e&&e.removeChild(i),Object.keys(s).forEach((e=>{s[e].forEach((e=>{e.destroy(t,this)})),s[e]=[]})),this._clearItemElements(),this._autoHider.disable(t),this._videoControl.disable(e),t.off(Ot.PROJECTION_CHANGE,this._onNewSrcLoad),t.off(Ot.STATIC_CLICK,this._onStaticClick)}_addItem(t,e){for(const i of e){const e=this._items[i.position],s=this._wrapperEl[i.position],n=se(e,(t=>t.order>i.order));if(n>=0){const t=e[n].element;e.splice(n,0,i),s.insertBefore(i.element,t)}else e.push(i),s.appendChild(i.element);i.init(t,this)}}_createPositionWrappers(){const t=Object.assign(Object.assign({},Ai.DEFAULT_CLASS),this.className),e=this._rootEl,i=Jt(t.CONTROLS_BG),s=Jt(t.CONTROLS_FLOAT_LEFT),n=Jt(t.CONTROLS_FLOAT_RIGHT);e.appendChild(s),e.appendChild(n);const r=Jt(t.CONTROLS_MAIN),o=Jt(t.CONTROLS_TOP),a=Jt(t.CONTROLS_BOTTOM),h=Jt(t.CONTROLS_MID),l=Jt(t.CONTROLS_LEFT),c=Jt(t.CONTROLS_RIGHT);h.appendChild(l),h.appendChild(c),r.appendChild(i),r.appendChild(o),r.appendChild(h),r.appendChild(a),e.appendChild(r),this._bgEl=i,this._containerEl=r,this._wrapperEl={[Ai.POSITION.MAIN_TOP]:o,[Ai.POSITION.MAIN_LEFT]:l,[Ai.POSITION.MAIN_RIGHT]:c,[Ai.POSITION.MAIN_BOTTOM]:a,[Ai.POSITION.TOP_LEFT]:s,[Ai.POSITION.TOP_RIGHT]:n}}_clearItemElements(){Object.keys(Ai.POSITION).map((t=>Ai.POSITION[t])).forEach((t=>{for(;t.firstChild;)t.removeChild(t.firstChild)}))}_updateAutoHide(t){var e;const i=this.autoHide,s=this._autoHider;if(null!=i)i?s.enable(t):s.disable(t);else{const i=null===(e=t.projection)||void 0===e?void 0:e.getTexture();i&&i.isVideo()?s.enable(t):s.disable(t)}}_updateBackground(t){var e,i;const s=this._bgEl,n=this.showBackground,r=null!==(e=this.className.HIDDEN)&&void 0!==e?e:Ai.DEFAULT_CLASS.HIDDEN;if(null!=n)n?s.classList.remove(r):s.classList.add(r);else{const e=null===(i=t.projection)||void 0===i?void 0:i.getTexture();e&&e.isVideo()?s.classList.remove(r):s.classList.add(r)}}_updateKeyboardHandler(t){var e;const i=t.rootEl,s=this._videoControl,n=null===(e=t.projection)||void 0===e?void 0:e.getTexture();this.keyboardControls&&n&&n.isVideo()?s.enable(i,n):s.disable(i)}_createDefaultItems(){const t=[];return this.progressBar&&t.push(new fi(ne(this.progressBar))),this.playButton&&t.push(new yi(ne(this.playButton))),this.volumeButton&&t.push(new bi(ne(this.volumeButton))),this.gyroButton&&t.push(new Li(ne(this.gyroButton))),this.vrButton&&t.push(new Ci(ne(this.vrButton))),this.fullscreenButton&&t.push(new Ti(ne(this.fullscreenButton))),this.videoTime&&t.push(new Ri(ne(this.videoTime))),this.pieView&&t.push(new wi(ne(this.pieView))),t}}Ai.DEFAULT_CLASS=gi,Ai.POSITION=vi;class Ii{constructor({src:t,video:e=!1}){this.src=t,this.video=e,this._mesh=null}releaseAllResources(t){var e;null===(e=this._mesh)||void 0===e||e.destroy(t)}updateCamera(t){t.resetRange()}updateControl(t){t.ignoreZoomScale=!1}update(t){}getTexture(){return this._mesh?this._mesh.program.uniforms.uTexture.texture:null}getMesh(){return this._mesh}}class Si{constructor(){this.needsUpdate=!0}destroy(t){}}class Pi extends Si{constructor(t,e,i){super(),this.texture=e,this._webglTexture=t.createWebGLCubeTexture(e,e.width),this._cubemapOrder=i}destroy(t){this.texture.destroy(),t.deleteTexture(this._webglTexture)}update(t,e,i){const s=this.texture;t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,s.flipY),t.uniform1i(e,0),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_CUBE_MAP,this._webglTexture);oe(s.sources,this._cubemapOrder).forEach(((e,s)=>{i?t.texSubImage2D(t.TEXTURE_CUBE_MAP_POSITIVE_X+s,0,0,0,t.RGBA,t.UNSIGNED_BYTE,e):t.texImage2D(t.TEXTURE_CUBE_MAP_POSITIVE_X+s,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e)})),s.isVideo()||(this.needsUpdate=!1)}}class Ni{get size(){return this._size}constructor(t,e){var i;this.texture=t,this._renderingOrder=oe(!(i=6)||i<=0?[]:Array.apply(0,Array(i)).map(((t,e)=>e)),e);const s=document.createElement("canvas");this._calcRenderingSize(),s.width=this._size,s.height=this._size,this._canvas=s,this._ctx=s.getContext("2d")}destroy(){const t=this._canvas;t.width=1,t.height=1,this._canvas=null}draw(t,e){const i=this._size,s=this.texture;let n=0;for(let r=0;r=0;t--)for(let e=0;e<3;e++){const n=[e*i,.5*t,(e+1)*i,.5*t,(e+1)*i,.5*(t+1),e*i,.5*(t+1)];s.push(n)}e&&e.forEach(((t,e)=>{if(t===jt.ZERO)return;const i=s[e];let n;n=t===jt.CW_90?[1,2,3,0]:t===jt.CCW_90?[3,0,1,2]:[2,3,0,1];const r=Array(i.length);for(let t=0;tt.concat(e)),[]))}}class Vi extends Si{constructor(t,e){super(),this.texture=e,this._webglTexture=t.createWebGLTexture(e)}destroy(t){this.texture.destroy(),t.deleteTexture(this._webglTexture)}update(t,e,i){const s=this.texture,n=s.isVideo();t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,s.flipY),t.uniform1i(e,0),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this._webglTexture),!n&&i?t.texSubImage2D(t.TEXTURE_2D,0,0,0,t.RGBA,t.UNSIGNED_BYTE,s.source):t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,s.source),n||(this.needsUpdate=!1)}}var ki="#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec2 vUV;void main(){vUV=uv;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}",Gi="#define GLSLIFY 1\nuniform sampler2D uTexture;varying highp vec2 vUV;void main(){gl_FragColor=texture2D(uTexture,vUV.st);}";class Hi extends Fi{constructor(t){const e=[],i=[],s=[],n=[-.5,.5],r=1/60,o=t*r;for(let a=0;a<2;a++){const h=n[a];for(let n=0;n<=60;n++){const l=n*o+Math.PI-.5*t,c=Math.cos(l),u=Math.sin(l),_=n*r,d=a;if(s.push(_,d),e.push(c,h,u),0===a&&n<60){const t=n,e=t+60+1;i.push(t,e,t+1,e,e+1,t+1)}}}super(e,i,s)}}class Yi extends Fi{constructor(){const t=60,e=-.5*Math.PI,i=[],s=[],n=[];let r,o;for(r=0;r<=60;r++){const a=(r/60-.5)*Math.PI,h=Math.sin(a),l=Math.cos(a);for(o=0;o<=t;o++){const a=2*(o/t-.5)*Math.PI+e,c=Math.sin(a),u=Math.cos(a)*l,_=h,d=c*l,m=o/t,p=r/60;if(i.push(m,p),s.push(u,_,d),o!==t&&60!==r){const e=61*r+o,i=e+t+1;n.push(e,e+1,i,i,e+1,i+1)}}}super(s,n,i)}}class ji extends Si{constructor(t){super(),this.val=t}update(t,e){t.uniform1f(e,this.val),this.needsUpdate=!1}}class Wi extends Fi{constructor(t=2,e=2,i=-1){const s=.5*t,n=.5*e;super([-s,-n,i,s,-n,i,-s,n,i,s,n,i],[0,1,2,2,1,3],[0,0,1,0,0,1,1,1])}}class Xi extends Si{constructor(t){super(),this.val=t}update(t,e){t.uniform4fv(e,this.val.reduce(((t,e)=>[...t,...e]),[])),this.needsUpdate=!1}}class Ki extends Ii{constructor(t){super(t),this._mode=t.mode}applyTexture(t,e){let i,s;if(this._mode===Ki.MODE.LEFT_RIGHT)i=[.5,1,0,0],s=[.5,1,.5,0];else i=[1,.5,0,0],s=[1,.5,0,.5];const n={uTexture:new Vi(t,e),uEye:new ji(0),uTexScaleOffset:new Xi([i,s])},r=new Yi,o=new Ui(t,"#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;uniform vec4 uTexScaleOffset[2];uniform float uEye;varying highp vec2 vUV;void main(){vec4 scaleOffset=uTexScaleOffset[int(uEye)];vUV=uv.xy*scaleOffset.xy+scaleOffset.zw;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}",Gi,n),a=t.createVAO(r,o),h=new Di(a,o);this._mesh=h}}Ki.MODE={LEFT_RIGHT:"left_right",TOP_BOTTOM:"top_bottom"};var qi={__proto__:null,default:_i,Autoplay:ri,AutoResizer:ni,Camera:de,CameraAnimation:_e,Motion:ue,Object3D:di,View360Error:D,WebGLRenderer:ui,XRManager:oi,PanoControl:we,RotateControl:ve,ZoomControl:ye,GyroControl:Re,ControlBar:Ai,ControlBarItem:pi,FullscreenButton:Ti,PieView:wi,PlayButton:yi,ProgressBar:fi,VideoTime:Ri,VolumeControl:bi,LoadingSpinner:mi,Projection:Ii,CubemapProjection:class extends Ii{constructor(t){super(t);const{cubemapOrder:e="RLUDFB",cubemapFlipX:i=!1}=t;this._cubemapOrder=e,this._cubemapFlipX=i}applyTexture(t,e){const i=this._cubemapOrder,s=this._cubemapFlipX,n={uTexture:e.isCube()?new Pi(t,e,i):new Mi(t,e,i)},r=new zi({order:i}),o=new Ui(t,"#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec3 vPos;void main(){vPos=position;gl_Position=uPMatrix*uMVMatrix*vec4(position,1.0);}","#define GLSLIFY 1\nuniform samplerCube uTexture;varying highp vec3 vPos;void main(){gl_FragColor=textureCube(uTexture,vec3(vPos.x,vPos.y,-vPos.z));}",n),a=t.createVAO(r,o),h=new Di(a,o);s&&(h.scale[0]=-1),h.updateMatrix(),this._mesh=h}},CubestripProjection:class extends Ii{constructor(t){super(t);const{cubemapOrder:e="RLUDFB",cubemapFlipX:i=!1}=t;this._cubemapOrder=e,this._cubemapFlipX=i}applyTexture(t,e){const i=this._cubemapOrder,s=this._cubemapFlipX,n={uTexture:new Vi(t,e)},r=new zi({order:i}),o=new Ui(t,ki,Gi,n),a=t.createVAO(r,o),h=new Di(a,o);s&&(h.scale[0]=-1),h.updateMatrix(),this._mesh=h}},CylindricalProjection:class extends Ii{constructor(t){super(t);const{partial:e=!1}=t;this._partial=e}applyTexture(t,e){const i=this._partial,{width:s,height:n}=e,r=s/n,o=180/r,a=i?1:2*Math.tan(o*Ft),h=i?r:2*Math.PI,l=new Hi(h),c=new Ui(t,ki,Gi,{uTexture:new Vi(t,e)}),u=t.createVAO(l,c),_=new Di(u,c);_.scale[1]=a,T(_.rotation),C(_.rotation,_.rotation,-Math.PI/2),_.updateMatrix(),this._mesh=_}updateCamera(t){super.updateCamera(t);const e=this._mesh;if(!e)return;const i=e.program.uniforms.uTexture.texture,{width:s,height:n}=i,r=s/n,o=.5*e.scale[1];if(this._partial){const e=.5*r*zt;t.restrictYawRange(-e,e)}const a=Math.atan2(o,1)*zt,h=Math.tan(t.fov*Ft*.5)/(o*t.aspect);t.restrictPitchRange(-a,a),t.restrictZoomRange(h,1/0),t.restrictRenderHeight(2*o)}},EquiangularProjection:class extends Ii{applyTexture(t,e){const i={uTexture:new Vi(t,e)},s=new zi({order:"LFRDBU",rotateUV:[jt.ZERO,jt.ZERO,jt.ZERO,jt.CW_90,jt.CCW_90,jt.CW_90]}),n=new Ui(t,ki,"#define PI 3.14159265359\nprecision mediump float;\n#define GLSLIFY 1\nuniform sampler2D uTexture;varying highp vec2 vUV;const vec2 OPERATE_COORDS_RANGE=vec2(-1.0,1.0);const vec2 TEXTURE_COORDS_RANGE=vec2(0.0,1.0);const float ONE_THIRD=1.0/3.0;const float EAC_CONST=2.0/PI;float scale(vec2 domainRange,vec2 targetRange,float val){float unit=1.0/(domainRange[1]-domainRange[0]);return targetRange[0]+(targetRange[1]-targetRange[0])*(val-domainRange[0])*unit;}void main(void){float transformedCoordX;float transformedCoordY;float texRangeXStart=floor(vUV.s*3.)*ONE_THIRD;float texRangeYStart=floor(vUV.t*2.)*0.5;vec2 orgTextureRangeX=vec2(texRangeXStart,texRangeXStart+ONE_THIRD);vec2 orgTextureRangeY=vec2(texRangeYStart,texRangeYStart+0.5);float px=scale(orgTextureRangeX,OPERATE_COORDS_RANGE,vUV.s);float py=scale(orgTextureRangeY,OPERATE_COORDS_RANGE,vUV.t);float qu=EAC_CONST*atan(px)+0.5;float qv=EAC_CONST*atan(py)+0.5;transformedCoordX=scale(TEXTURE_COORDS_RANGE,orgTextureRangeX,qu);transformedCoordY=scale(TEXTURE_COORDS_RANGE,orgTextureRangeY,qv);gl_FragColor=texture2D(uTexture,vec2(transformedCoordX,transformedCoordY));}",i),r=t.createVAO(s,n),o=new Di(r,n);this._mesh=o}},EquirectProjection:class extends Ii{constructor(t){super(t)}applyTexture(t,e){const i={uTexture:new Vi(t,e)},s=new Yi,n=new Ui(t,ki,Gi,i),r=t.createVAO(s,n),o=new Di(r,n);this._mesh=o}},LittlePlanetProjection:class extends Ii{constructor(t){super(t)}applyTexture(t,e){e.wrapS=WebGLRenderingContext.REPEAT,e.wrapT=WebGLRenderingContext.REPEAT;const i={uTexture:new Vi(t,e),uYaw:new ji(0),uPitch:new ji(.5),uZoom:new ji(1)},s=new Wi,n=new Ui(t,"#define GLSLIFY 1\nattribute vec3 position;attribute vec2 uv;uniform mat4 uMVMatrix;uniform mat4 uPMatrix;varying highp vec2 vUV;void main(){vUV=uv;gl_Position=vec4(position,1.0);}","precision mediump float;\n#define GLSLIFY 1\nuniform sampler2D uTexture;uniform float uYaw;uniform float uPitch;uniform float uZoom;varying highp vec2 vUV;const float PI=3.1415926536;const float PI_2=PI*0.5;vec2 toStereographicUV(in vec2 uv,in vec2 center){float R=1.*uZoom;vec2 texLatLon=(uv*2.-1.)*vec2(PI,PI_2);vec2 central=(center*2.-1.)*vec2(PI,PI_2)+vec2(PI,0);float x=texLatLon.x;float y=texLatLon.y;float rou=sqrt(x*x+y*y);float c=2.0*atan(rou,R*0.5);float sin_c=sin(c);float cos_c=cos(c);float sin_cy=sin(central.y);float cos_cy=cos(central.y);float lat=asin(cos_c*sin_cy+(y*sin_c*cos_cy)/rou);float lon=central.x+atan(x*sin_c,rou*cos_cy*cos_c-y*sin_cy*sin_c);float u=(lon/PI+1.0)*0.5;float v=(lat/PI_2+1.0)*0.5;return vec2(u,v);}void main(){vec2 central=vec2(uYaw,uPitch);vec2 uv=toStereographicUV(vUV,central);gl_FragColor=texture2D(uTexture,uv);}",i),r=t.createVAO(s,n),o=new Di(r,n);this._mesh=o}updateControl(t){t.ignoreZoomScale=!0}update(t){const e=this._mesh;if(!e)return;const i=e.program.uniforms;i.uYaw.val=t.yaw/360,i.uPitch.val=t.pitch/180+.5,i.uZoom.val=t.zoom,i.uYaw.needsUpdate=!0,i.uPitch.needsUpdate=!0,i.uZoom.needsUpdate=!0}},StereoEquiProjection:Ki,Hotspot:ai,HotspotRenderer:hi,ERROR_CODES:U,DEFAULT_CLASS:xt,EVENTS:Ot,EASING:At,getValidProps:t=>Object.keys(t).reduce(((e,i)=>(null!=t[i]&&(e[i]=t[i]),e)),{}),VIEW360_METHODS:["destroy","init","load","resize","addPlugins","removePlugins","renderFrame","on","hasOn","once","off","trigger"],withMethods:(t,e)=>{[o.prototype,_i.prototype].forEach((i=>{Object.getOwnPropertyNames(i).filter((t=>"_"!==t.charAt(0)&&"constructor"!==t)).forEach((s=>{const n=Object.getOwnPropertyDescriptor(i,s);if(n.value)Object.defineProperty(t,s,{value:function(...t){return n.value.call(this[e],...t)}});else{const i={};n.get&&(i.get=function(){var t;return this[e]&&(null===(t=n.get)||void 0===t?void 0:t.call(this[e]))}),n.set&&(i.set=function(...t){var i;return null===(i=n.set)||void 0===i?void 0:i.call(this[e],...t)}),Object.defineProperty(t,s,i)}}))}))}};return((t,...e)=>{e.forEach((e=>{Object.keys(e).forEach((i=>{const s=e[i];Array.isArray(t[i])&&Array.isArray(s)?t[i]=[...t[i],...s]:t[i]=s}))}))})(_i,qi),_i})); +//# sourceMappingURL=view360.pkgd.min.js.map diff --git a/demo/release/latest/dist/view360.pkgd.min.js.map b/demo/release/latest/dist/view360.pkgd.min.js.map new file mode 100644 index 000000000..3e5ef0a23 --- /dev/null +++ b/demo/release/latest/dist/view360.pkgd.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"view360.pkgd.min.js","sources":["../src/core/View360Error.ts","../src/const/error.ts","../src/const/browser.ts","../src/const/external.ts","../src/const/internal.ts","../src/utils.ts","../src/core/Motion.ts","../src/core/CameraAnimation.ts","../src/core/Camera.ts","../src/control/input/MouseInput.ts","../src/control/input/TouchInput.ts","../src/control/input/KeyboardInput.ts","../src/control/RotateControl.ts","../src/control/input/WheelInput.ts","../src/control/input/PinchInput.ts","../src/control/ZoomControl.ts","../src/control/input/GyroInput.ts","../src/control/GyroControl.ts","../src/control/PanoControl.ts","../src/texture/Texture.ts","../src/texture/Texture2D.ts","../src/texture/TextureVideo.ts","../src/texture/TextureCube.ts","../src/core/TextureLoader.ts","../src/core/FrameAnimator.ts","../src/core/AutoResizer.ts","../src/core/Autoplay.ts","../src/core/XRManager.ts","../src/hotspot/Hotspot.ts","../src/hotspot/HotspotRenderer.ts","../src/core/VertexArrayObject.ts","../src/core/WebGLContext.ts","../src/core/WebGLRenderer.ts","../src/View360.ts","../src/core/Object3D.ts","../src/plugin/LoadingSpinner/LoadingSpinner.ts","../src/plugin/ControlBar/ControlBarItem.ts","../src/plugin/ControlBar/const.ts","../src/plugin/ControlBar/RangeControl.ts","../src/plugin/ControlBar/ProgressBar.ts","../src/plugin/ControlBar/PlayButton.ts","../src/plugin/ControlBar/VolumeControl.ts","../src/plugin/ControlBar/FullscreenButton.ts","../src/plugin/ControlBar/VideoTime.ts","../src/plugin/ControlBar/PieView.ts","../src/plugin/ControlBar/VRButton.ts","../src/plugin/ControlBar/GyroButton.ts","../src/plugin/ControlBar/AutoHide.ts","../src/plugin/ControlBar/VideoControl.ts","../src/plugin/ControlBar/ControlBar.ts","../src/projection/Projection.ts","../src/uniform/Uniform.ts","../src/uniform/UniformTextureCube.ts","../src/core/CubeTexturePainter.ts","../src/uniform/UniformCanvasCube.ts","../src/core/TriangleMesh.ts","../src/core/ShaderProgram.ts","../src/core/VertexData.ts","../src/geometry/Geometry.ts","../src/geometry/CubeGeometry.ts","../src/uniform/UniformTexture2D.ts","../src/geometry/CylinderGeometry.ts","../src/geometry/SphereGeometry.ts","../src/uniform/UniformFloat.ts","../src/geometry/PlaneGeometry.ts","../src/uniform/UniformVector4Array.ts","../src/projection/StereoEquiProjection.ts","../src/projection/CubemapProjection.ts","../src/projection/CubestripProjection.ts","../src/projection/CylindricalProjection.ts","../src/projection/EquiangularProjection.ts","../src/projection/EquirectProjection.ts","../src/projection/LittlePlanetProjection.ts","../src/cfc/utils.ts","../src/cfc/const.ts","../src/cfc/withMethods.ts","../src/index.umd.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * Error thrown by {@link View360}\n * @ko {@link View360}이 발생시킨 에러\n * @since 4.0.0\n */\nclass View360Error extends Error {\n /**\n * Error code\n * @ko 에러 코드\n * @see ERROR_CODES\n */\n public code: number;\n\n /**\n * Create new instance of View360Error\n * @ko View360Error의 인스턴스를 생성합니다.\n * @param message - Error message {@ko 에러 메시지}\n * @param code - Error code {@ko 에러 코드}\n */\n public constructor(message: string, code: number) {\n super(message);\n\n Object.setPrototypeOf(this, View360Error.prototype);\n\n this.name = \"View360Error\";\n this.code = code;\n }\n}\n\nexport default View360Error;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * Error codes of {@link View360Error}\n * @ko {@link View360Error}가 가질 수 있는 에러 코드 값들\n * @since 4.0.0\n */\nexport const ERROR_CODES = {\n /**\n * The given value's type is not expected\n * @ko 주어진 값의 타입이 잘못되었을 경우\n * @since 4.0.0\n */\n WRONG_TYPE: 0,\n /**\n * The given value is not a supported option\n * @ko 잘못된 옵션을 받았을 경우\n * @since 4.0.0\n */\n WRONG_OPTION: 1,\n /**\n * The element with given CSS selector does not exist\n * @ko 주어진 CSS 셀렉터로 엘리먼트를 찾지 못했을 경우\n * @since 4.0.0\n */\n ELEMENT_NOT_FOUND: 2,\n /**\n * Couldn't find canvas element inside the given container element.\n * @ko 컨테이너 엘리먼트 내부에서 캔버스 엘리먼트를 찾지 못했을 경우\n * @since 4.0.0\n */\n CANVAS_NOT_FOUND: 3,\n /**\n * The browser does not support WebGL\n * @ko 브라우저가 WebGL을 지원하지 않는 경우\n * @since 4.0.0\n */\n WEBGL_NOT_SUPPORTED: 4,\n /**\n * Failed creating canvas 2D context\n * @ko 캔버스 2D 컨텍스트를 생성하지 못한 경우\n * @since 4.0.0\n */\n FAILED_CREATE_CONTEXT_2D: 5,\n /**\n * `init()` is called before setting {@link View360Options#projection}\n * @ko {@link View360Options#projection}을 설정하기 전에 `init()`이 호출된 경우\n * @since 4.0.0\n */\n PROVIDE_PROJECTION_FIRST: 6,\n /**\n * Failed linking WebGL program. Only can be thrown when {@link View360Options#debug} is `true`.\n * @ko WebGL 프로그램 링크에 실패한 경우. {@link View360Options#debug}를 `true`로 설정한 경우에만 발생할 수 있습니다.\n * @since 4.0.0\n */\n FAILED_LINKING_PROGRAM: 7,\n /**\n * Arguments are not sufficient for the given property.\n * @ko 프로퍼티에 값이 충분히 주어지지 않았을 때\n * @since 4.0.0\n */\n INSUFFICIENT_ARGS: 8\n} as const;\n\nexport const MESSAGES = {\n WRONG_TYPE: (val: any, types: string[]) => `${typeof val} is not a ${types.map(type => `\"${type}\"`).join(\" or \")}.`,\n WRONG_OPTION: (val: any, optionName: string) => `Bad option: given \"${val}\" for option \"${optionName}\".`,\n ELEMENT_NOT_FOUND: (query: string) => `Element with selector \"${query}\" not found.`,\n CANVAS_NOT_FOUND: \"The canvas element was not found inside the given root element.\",\n WEBGL_NOT_SUPPORTED: \"WebGL is not supported on this browser.\",\n FAILED_CREATE_CONTEXT_2D: \"Failed to create canvas 2D context\",\n PROVIDE_PROJECTION_FIRST: \"\\\"projection\\\" should be provided before initialization.\",\n FAILED_LINKING_PROGRAM: (msg: string | null, shaderLog: string | null) => `Failed linking WebGL program - \"${msg}\\nShader compile Log: ${shaderLog}`,\n INSUFFICIENT_ARGS: (val: any, name: string) => `Insufficient arguments: given \"${val}\" for \"${name}\".`\n};\n\nexport default {\n CODES: ERROR_CODES,\n MESSAGES\n};\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nexport const EVENTS = {\n MOUSE_DOWN: \"mousedown\",\n MOUSE_MOVE: \"mousemove\",\n MOUSE_UP: \"mouseup\",\n TOUCH_START: \"touchstart\",\n TOUCH_MOVE: \"touchmove\",\n TOUCH_END: \"touchend\",\n WHEEL: \"wheel\",\n RESIZE: \"resize\",\n CONTEXT_MENU: \"contextmenu\",\n MOUSE_ENTER: \"mouseenter\",\n MOUSE_LEAVE: \"mouseleave\",\n POINTER_DOWN: \"pointerdown\",\n POINTER_MOVE: \"pointermove\",\n POINTER_UP: \"pointerup\",\n POINTER_CANCEL: \"pointercancel\",\n POINTER_ENTER: \"pointerenter\",\n POINTER_LEAVE: \"pointerleave\",\n KEY_DOWN: \"keydown\",\n KEY_UP: \"keyup\",\n LOAD: \"load\",\n ERROR: \"error\",\n CLICK: \"click\",\n DOUBLE_CLICK: \"dblclick\",\n CONTEXT_CREATE_ERROR: \"webglcontextcreationerror\",\n CONTEXT_LOST: \"webglcontextlost\",\n CONTEXT_RESTORED: \"webglcontextrestored\",\n DEVICE_ORIENTATION: \"deviceorientation\",\n DEVICE_MOTION: \"devicemotion\",\n ORIENTATION_CHANGE: \"orientationchange\",\n VIDEO_PLAY: \"play\",\n VIDEO_PAUSE: \"pause\",\n VIDEO_LOADED_DATA: \"loadeddata\",\n VIDEO_VOLUME_CHANGE: \"volumechange\",\n VIDEO_TIME_UPDATE: \"timeupdate\",\n VIDEO_DURATION_CHANGE: \"durationchange\",\n VIDEO_CAN_PLAYTHROUGH: \"canplaythrough\",\n TRANSITION_END: \"transitionend\",\n XR_END: \"end\"\n} as const;\n\nexport const EL_DIV = \"div\";\nexport const EL_BUTTON = \"button\";\n\n// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button\nexport enum MOUSE_BUTTON {\n LEFT,\n MIDDLE,\n RIGHT\n}\n\nexport const CURSOR = {\n GRAB: \"grab\",\n GRABBING: \"grabbing\",\n NONE: \"\"\n} as const;\n\nexport const KEY_DIRECTION = [\"LEFT\", \"UP\", \"RIGHT\", \"DOWN\"] as const;\nexport enum DIRECTION_KEY_CODE {\n LEFT = 37,\n UP = 38,\n RIGHT = 39,\n DOWN = 40\n}\nexport const SPACE_KEY_CODE = 32;\n\nexport const DIRECTION_KEY_NAME = {\n LEFT: \"ArrowLeft\",\n UP: \"ArrowUp\",\n RIGHT: \"ArrowRight\",\n DOWN: \"ArrowDown\"\n} as const;\nexport const SPACE_KEY_NAME = \" \";\n\nexport const FULLSCREEN_REQUEST = [\n \"requestFullscreen\",\n \"webkitRequestFullscreen\",\n \"webkitRequestFullScreen\",\n \"webkitCancelFullScreen\",\n \"mozRequestFullScreen\",\n \"msRequestFullscreen\"\n];\n\nexport const FULLSCREEN_ELEMENT = [\n \"fullscreenElement\",\n \"webkitFullscreenElement\",\n \"webkitCurrentFullScreenElement\",\n \"mozFullScreenElement\",\n \"msFullscreenElement\"\n];\n\nexport const FULLSCREEN_EXIT = [\n \"exitFullscreen\",\n \"webkitExitFullscreen\",\n \"webkitCancelFullScreen\",\n \"mozCancelFullScreen\",\n \"msExitFullscreen\"\n];\n\nexport const FULLSCREEN_CHANGE = [\n \"fullscreenchange\",\n \"webkitfullscreenchange\",\n \"mozfullscreenchange\",\n \"MSFullscreenChange\"\n];\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nexport { ERROR_CODES } from \"./error\";\n\n/**\n * Default class names\n * @ko 기본 클래스 이름들\n * @since 4.0.0\n */\nexport const DEFAULT_CLASS = {\n CONTAINER: \"view360-container\",\n CANVAS: \"view360-canvas\",\n CTX_LOST: \"view360-ctx-lost\",\n IN_VR: \"view360-vr-presenting\",\n HOTSPOT_CONTAINER: \"view360-hotspots\",\n HOTSPOT: \"view360-hotspot\",\n HOTSPOT_VISIBLE: \"view360-hotspot-visible\",\n HOTSPOT_FLIP_X: \"view360-hotspot-flip-x\",\n HOTSPOT_FLIP_Y: \"view360-hotspot-flip-y\",\n} as const;\n\n/**\n * Event names\n * @ko 이벤트 이름들\n * @since 4.0.0\n * @example\n * ```ts\n * import View360, { EVENTS } from \"@egjs/view360\";\n *\n * const viewer = new View360(\"#el_id\");\n *\n * viewer.on(EVENTS.READY, evt => {\n * console.log(\"View360 is ready!\");\n * });\n * ```\n */\nexport const EVENTS = {\n READY: \"ready\",\n LOAD_START: \"loadStart\",\n LOAD: \"load\",\n PROJECTION_CHANGE: \"projectionChange\",\n RESIZE: \"resize\",\n BEFORE_RENDER: \"beforeRender\",\n RENDER: \"render\",\n INPUT_START: \"inputStart\",\n INPUT_END: \"inputEnd\",\n VIEW_CHANGE: \"viewChange\",\n STATIC_CLICK: \"staticClick\",\n VR_START: \"vrStart\",\n VR_END: \"vrEnd\"\n} as const;\n\n/**\n * Collection of predefined easing functions\n * @ko 미리 정의된 easing 함수들\n */\nexport const EASING = {\n LINEAR: (x: number) => x,\n SINE_WAVE: (x: number) => Math.sin(x * Math.PI * 2),\n EASE_OUT_CUBIC: (x: number) => 1 - Math.pow(1 - x, 3),\n EASE_OUT_BOUNCE: (x: number): number => {\n const n1 = 7.5625;\n const d1 = 2.75;\n\n if (x < 1 / d1) {\n return n1 * x * x;\n } else if (x < 2 / d1) {\n return n1 * (x -= 1.5 / d1) * x + 0.75;\n } else if (x < 2.5 / d1) {\n return n1 * (x -= 2.25 / d1) * x + 0.9375;\n } else {\n return n1 * (x -= 2.625 / d1) * x + 0.984375;\n }\n }\n} as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { EASING } from \"./external\";\nimport { Range } from \"../type/utils\";\n\nexport const CAMERA_EVENTS = {\n CHANGE: \"change\",\n ANIMATION_END: \"animationEnd\"\n} as const;\n\nexport const CONTROL_EVENTS = {\n INPUT_START: \"inputStart\",\n CHANGE: \"change\",\n INPUT_END: \"inputEnd\",\n ENABLE: \"enable\",\n DISABLE: \"disable\",\n STATIC_CLICK: \"staticClick\"\n} as const;\n\nexport const DEG_TO_RAD = Math.PI / 180;\nexport const RAD_TO_DEG = 180 / Math.PI;\nexport const DEFAULT_EASING = EASING.EASE_OUT_CUBIC;\nexport const DEFAULT_ANIMATION_DURATION = 300;\nexport const INFINITE_RANGE: Readonly = {\n min: -Infinity, max: Infinity\n} as const;\nexport const DEFAULT_PITCH_RANGE: Readonly = {\n min: -90, max: 90\n} as const;\nexport const DEFAULT_ZOOM_RANGE: Readonly = {\n min: 0.6, max: 10\n} as const;\n\nexport enum ROTATE {\n ZERO,\n CW_90,\n CCW_90,\n CW_180\n}\n\n// Custom event name for video time change\nexport const VIDEO_TIME_CHANGE_EVENT = \"view360videotimechange\";\nexport const SVG_NAMESPACE = \"http://www.w3.org/2000/svg\";\nexport const SESSION_VR = \"immersive-vr\";\nexport const XR_REFERENCE_SPACE = \"local\";\n\nexport const EPSILON = Number.EPSILON ?? 2.220446049250313e-16;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { quat, vec3 } from \"gl-matrix\";\nimport View360Error from \"./core/View360Error\";\nimport ERROR from \"./const/error\";\nimport * as BROWSER from \"./const/browser\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"./const/internal\";\nimport { NoBoolean } from \"./type/utils\";\n\nexport const isString = (val: any): val is string => typeof val === \"string\";\nexport const isElement = (val: any): val is Element => !!val && val.nodeType === Node.ELEMENT_NODE;\n\nexport const createElement = (className: string, tag = BROWSER.EL_DIV) => {\n const el = document.createElement(tag);\n\n el.classList.add(className);\n\n return el;\n};\n\nexport const getNullableElement = (el: HTMLElement | string | null, parent?: HTMLElement): HTMLElement | null => {\n let targetEl: HTMLElement | null = null;\n\n if (isString(el)) {\n const parentEl = parent ? parent : document;\n const queryResult = parentEl.querySelector(el);\n\n if (!queryResult) {\n return null;\n }\n\n targetEl = queryResult as HTMLElement;\n } else if (isElement(el)) {\n targetEl = el;\n }\n\n return targetEl;\n};\n\nexport const getElement = (el: HTMLElement | string, parent?: HTMLElement): HTMLElement => {\n const targetEl = getNullableElement(el, parent);\n\n if (!targetEl) {\n if (isString(el)) {\n throw new View360Error(ERROR.MESSAGES.ELEMENT_NOT_FOUND(el), ERROR.CODES.ELEMENT_NOT_FOUND);\n } else {\n throw new View360Error(ERROR.MESSAGES.WRONG_TYPE(el, [\"HTMLElement\", \"string\"]), ERROR.CODES.WRONG_TYPE);\n }\n }\n\n return targetEl;\n};\n\nexport const findCanvas = (root: HTMLElement, selector: string): HTMLCanvasElement => {\n const canvas = root.querySelector(selector) as HTMLCanvasElement;\n\n if (!canvas) {\n throw new View360Error(ERROR.MESSAGES.CANVAS_NOT_FOUND, ERROR.CODES.CANVAS_NOT_FOUND);\n }\n\n return canvas;\n};\n\nexport const range = (end: number): number[] => {\n if (!end || end <= 0) {\n return [];\n }\n\n return Array.apply(0, Array(end)).map((undef, idx) => idx);\n};\n\nexport const clamp = (x: number, min: number, max: number) => Math.max(Math.min(x, max), min);\n\n// Linear interpolation between a and b\nexport const lerp = (a: number, b: number, t: number) => {\n return a * (1 - t) + b * t;\n};\n\nexport const circulate = (val: number, min: number, max: number) => {\n const size = Math.abs(max - min);\n\n if (val < min) {\n const offset = (min - val) % size;\n val = max - offset;\n } else if (val > max) {\n const offset = (val - max) % size;\n val = min + offset;\n }\n\n return val;\n};\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const merge = (target: object, ...srcs: object[]): object => {\n srcs.forEach(source => {\n Object.keys(source).forEach(key => {\n const value = source[key];\n if (Array.isArray(target[key]) && Array.isArray(value)) {\n target[key] = [...target[key], ...value];\n } else {\n target[key] = value;\n }\n });\n });\n\n return target;\n};\n\nexport const findIndex = (array: T[], checker: (val: T) => boolean): number => {\n for (let idx = 0; idx < array.length; idx++) {\n if (checker(array[idx])) {\n return idx;\n }\n }\n\n return -1;\n};\n\nexport const getObjectOption = >(val?: T): NoBoolean => typeof val === \"object\" ? val : {} as any;\nexport const toVerticalFov = (fovRadian: number, aspect: number) => {\n return Math.atan(Math.tan(fovRadian * 0.5) / aspect) * 2;\n};\n\nexport const reorderCube = (arr: T[], order: string, defaultOrder = \"RLUDFB\"): T[] => {\n return defaultOrder.split(\"\")\n .map(face => order.indexOf(face))\n .map(index => arr[index]);\n};\n\nexport const isFullscreen = () => {\n if (!document) return false;\n\n for (const key of BROWSER.FULLSCREEN_ELEMENT) {\n if (document[key]) return true;\n }\n\n return false;\n};\n\nexport const sensorCanBeEnabledIOS = () => {\n return !!DeviceMotionEvent && \"requestPermission\" in DeviceMotionEvent && window.isSecureContext;\n};\n\nexport const hfovToZoom = (baseFov: number, fov: number) => {\n const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5);\n const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5);\n\n return renderingWidth / zoomedWidth;\n};\n\nexport const eulerToQuat = (out: quat, yaw: number, pitch: number, roll: number): quat => {\n quat.identity(out);\n\n const pitchThreshold = 0.01;\n const pitchClamped = clamp(pitch, -90 + pitchThreshold, 90 - pitchThreshold);\n\n quat.rotateY(out, out, yaw * DEG_TO_RAD);\n quat.rotateX(out, out, pitchClamped * DEG_TO_RAD);\n quat.rotateZ(out, out, roll * DEG_TO_RAD);\n\n return out;\n};\n\n/**\n * Extract euler angles from the quaternion, except roll(z-axis rotation)\n * @hidden\n */\nexport const quatToEuler = (quaternion: quat) => {\n const x = quaternion[0];\n const y = quaternion[1];\n const z = quaternion[2];\n const w = quaternion[3];\n const x2 = x * x;\n const y2 = y * y;\n const z2 = z * z;\n const w2 = w * w;\n\n const unit = x2 + y2 + z2 + w2;\n const test = x * w - y * z;\n\n let pitch: number, yaw: number;\n\n if (test > 0.499995 * unit) {\n // singularity at the north pole\n pitch = Math.PI / 2;\n yaw = 2 * Math.atan2(y, x);\n } else if (test < -0.499995 * unit) {\n // singularity at the south pole\n pitch = -Math.PI / 2;\n yaw = -2 * Math.atan2(y, x);\n } else {\n const view = vec3.fromValues(0, 0, 1);\n const up = vec3.fromValues(0, 1, 0);\n\n vec3.transformQuat(view, view, quaternion);\n vec3.transformQuat(up, up, quaternion);\n\n const viewXZ = Math.sqrt(view[0] * view[0] + view[2] * view[2]);\n\n pitch = Math.atan2(-view[1], viewXZ);\n yaw = Math.atan2(view[0], view[2]);\n }\n\n return {\n pitch: clamp(pitch * RAD_TO_DEG, -90, 90),\n yaw: circulate(yaw * RAD_TO_DEG, 0, 360)\n };\n};\n","/*\n * Copyright (c) 2020 NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\nimport { clamp, lerp, circulate } from \"../utils\";\nimport { Range } from \"../type/utils\";\nimport { DEFAULT_ANIMATION_DURATION, DEFAULT_EASING } from \"../const/internal\";\n\n/**\n * Interpolator between two values with duration\n * @ko 특정 시간동안 두 값을 보간해주는 보간기\n * @since 4.0.0\n */\nclass Motion {\n // Options\n private _duration: number;\n private _loop: boolean;\n private _range: Range;\n private _easing: (x: number) => number;\n\n // Internal states\n private _progress: number;\n private _val: number;\n private _start: number;\n private _end: number;\n private _activated: boolean;\n\n /**\n * Current interpolated value\n * @ko 현재 보간된 값\n * @since 4.0.0\n */\n public get val() { return this._val; }\n /**\n * Start(from) value of interpolation\n * @ko 보간 시작 값\n * @since 4.0.0\n */\n public get start() { return this._start; }\n /**\n * End(to) value of interpolation\n * @ko 보간 끝 값\n * @since 4.0.0\n */\n public get end() { return this._end; }\n /**\n * Interpolation progress value (0 ~ 1)\n * @ko 현재 보간 진행정도 (0 ~ 1)\n * @since 4.0.0\n */\n public get progress() { return this._progress; }\n /**\n * Whether the interpolation is in active state.\n * @ko 보간 진행중인지 여부. `true`일 경우 보간이 진행중입니다.\n * @since 4.0.0\n */\n public get activated() { return this._activated; }\n\n /**\n * Duration of the interpolation\n * @ko 보간할 시간\n * @since 4.0.0\n */\n public get duration() { return this._duration; }\n public set duration(val: number) { this._duration = val; }\n\n /**\n * Whether to loop interpolation on finish\n * @ko 보간이 끝난 이후에 다시 시작할지 여부\n * @since 4.0.0\n */\n public get loop() { return this._loop; }\n public set loop(val: boolean) { this._loop = val; }\n\n /**\n * Range of the interpolation\n * @ko 보간 범위\n * @since 4.0.0\n */\n public get range() { return this._range; }\n\n /**\n * Easing function of the interpolation\n * @ko 보간에 사용되는 easing function\n * @since 4.0.0\n */\n public get easing() { return this._easing; }\n public set easing(val: (x: number) => number) { this._easing = val; }\n\n /**\n * Create new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options Options {@ko 옵션들}\n * @param options.duration Duration of the interpolation {@ko 보간할 시간}\n * @param options.loop Whether to loop interpolation on finish {@ko 보간이 끝난 이후에 다시 시작할지 여부}\n * @param options.range Range of the interpolation {@ko 보간 범위}\n * @param options.loop Easing function of the interpolation {@ko 보간에 사용되는 easing function}\n */\n public constructor({\n duration = DEFAULT_ANIMATION_DURATION,\n loop = false,\n range = { min: 0, max: 1 },\n easing = DEFAULT_EASING\n } = {}) {\n this._duration = duration;\n this._loop = loop;\n this._range = range;\n this._easing = easing;\n this._activated = false;\n this.reset(0);\n }\n\n /**\n * Update motion and progress it by given deltaTime\n * @ko 주어진 deltaTime만큼 보간을 진행합니다.\n * @param deltaTime - number of milisec to update motion {@ko 보간을 진행할 시간, 밀리초 단위}\n * @returns Difference(delta) of the value from the last update. {@ko 지난 업데이트 이후의 값 변화량}\n * @since 4.0.0\n */\n public update(deltaTime: number): number {\n if (!this._activated) {\n this._val = this._end;\n return 0;\n }\n\n const start = this._start;\n const end = this._end;\n const duration = this._duration;\n const prev = this._val;\n const loop = this._loop;\n\n const nextProgress = this._progress + deltaTime / duration;\n\n this._progress = loop\n ? circulate(nextProgress, 0, 1)\n : clamp(nextProgress, 0, 1);\n\n const easedProgress = this._easing(this._progress);\n this._val = lerp(start, end, easedProgress);\n\n if (!loop && this._progress >= 1) {\n this._activated = false;\n }\n\n return this._val - prev;\n }\n\n /**\n * Set `start`, `end` to the given value and set `progress` to 0.\n * @ko 주어진 값으로 시작 지점, 끝 지점을 초기화하고 progress를 0으로 세팅합니다.\n * @param defaultVal - Value to reset {@ko 초기화할 값}\n * @since 4.0.0\n */\n public reset(defaultVal: number): void {\n const range = this._range;\n const val = clamp(defaultVal, range.min, range.max);\n this._start = val;\n this._end = val;\n this._val = val;\n this._progress = 0;\n this._activated = false;\n }\n\n /**\n * Add delta to start & end and current value.\n * @ko 현재 & 끝 및 현재 값에 주어진 값을 더합니다.\n * @param delta - Delta value to add {@ko 추가할 값}\n */\n public add(delta: number) {\n const range = this._range;\n\n this._start = clamp(this._start + delta, range.min, range.max);\n this._end = clamp(this._end + delta, range.min, range.max);\n this._val = clamp(this._val + delta, range.min, range.max);\n }\n\n /**\n * Set current value to start, and end to current value + delta, then reset progress to 0.\n * @ko 현재 값을 시작 지점으로, 그에서 delta만큼 추가된 값을 끝점으로 하고 progress를 0으로 갱신합니다.\n * @param delta - Delta value to add {@ko 추가할 값}\n */\n public setNewEndByDelta(delta: number): void {\n const range = this._range;\n\n this._start = this._val;\n this._end = clamp(this._end + delta, range.min, range.max);\n this._progress = 0;\n this._activated = true;\n }\n\n /**\n * Set new range of the interpolation.\n * @ko 보간의 범위를 변경합니다.\n * @param min - New minimum range {@ko 변경할 범위의 최소값}\n * @param max - New maximum range {@ko 변경할 범위의 최대값}\n */\n public setRange(min: number, max: number) {\n this._start = clamp(this._start, min, max);\n this._end = clamp(this._end, min, max);\n this._range = { min, max };\n }\n}\n\nexport default Motion;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { quat } from \"gl-matrix\";\nimport Camera from \"./Camera\";\nimport Motion from \"./Motion\";\nimport { DEFAULT_ANIMATION_DURATION, DEFAULT_EASING } from \"../const/internal\";\nimport { lerp } from \"../utils\";\n\ntype CameraPose = {\n rotation: quat;\n zoom: number;\n}\n\n/**\n * Animation of the {@link Camera}\n * @internal\n * @ko {@link Camera}의 애니메이션\n * @since 4.0.0\n */\nclass CameraAnimation {\n // Options\n private _camera: Camera;\n private _from: CameraPose;\n private _to: CameraPose;\n\n // Internal values\n private _motion: Motion;\n private _finishPromise: Promise;\n private _finish: () => void;\n\n /**\n * Duration of the animation\n * @ko 애니메이션 재생시간\n * @since 4.0.0\n */\n public get duration() { return this._motion.duration; }\n public set duration(val: number) { this._motion.duration = val; }\n /**\n * Easing function of the animation\n * @ko 애니메이션의 easing function\n * @since 4.0.0\n */\n public get easing() { return this._motion.easing; }\n public set easing(val: (x: number) => number) { this._motion.easing = val; }\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param camera - Camera to animate {@ko 애니메이션을 적용할 카메라}\n * @param from - Start pose {@ko 애니메이션이 시작 시점의 카메라의 회전 및 줌}\n * @param to - End pose {@ko 애니메이션이 끝났을 때 카메라의 회전 및 줌}\n * @param options - Options {@ko 옵션들}\n * @param options.duration - Animation duration {@ko 애니메이션 재생 시간}\n * @param options.easing - Animation easing function {@ko 애니메이션 easing function}\n */\n public constructor(camera: Camera, from: CameraPose, to: CameraPose, {\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING\n } = {}) {\n this._camera = camera;\n this._motion = new Motion({ duration, easing, range: { min: 0, max: 1 } });\n this._from = from;\n this._to = to;\n this._finishPromise = new Promise(resolve => {\n this._finish = resolve as () => void;\n });\n\n // Enable motion\n this._motion.setNewEndByDelta(1);\n }\n\n /**\n * Return a promise that resolved on animation end.\n * @ko 애니메이션 재생이 끝났을 때 resolve되는 Promise를 반환합니다.\n * @since 4.0.0\n */\n public getFinishPromise() {\n return this._finishPromise;\n }\n\n /**\n * Update animation by given deltaTime.\n * @ko 주어진 시간만큼 애니메이션을 업데이트합니다.\n * @param deltaTime Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n */\n public update(deltaTime: number): void {\n const camera = this._camera;\n const from = this._from;\n const to = this._to;\n const motion = this._motion;\n motion.update(deltaTime);\n\n // Progress that easing is applied\n const progress = motion.val;\n const rotation = quat.create();\n const zoom = lerp(from.zoom, to.zoom, progress);\n\n quat.slerp(rotation, from.rotation, to.rotation, progress);\n camera.rotate(rotation, zoom);\n\n if (progress >= 1) {\n this._finish();\n }\n }\n}\n\nexport default CameraAnimation;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { mat4, quat, vec3 } from \"gl-matrix\";\nimport CameraAnimation from \"./CameraAnimation\";\nimport {\n CAMERA_EVENTS,\n DEG_TO_RAD,\n INFINITE_RANGE,\n DEFAULT_PITCH_RANGE,\n RAD_TO_DEG,\n DEFAULT_ZOOM_RANGE,\n DEFAULT_EASING,\n EPSILON\n} from \"../const/internal\";\nimport {\n circulate,\n clamp,\n eulerToQuat,\n quatToEuler,\n toVerticalFov\n} from \"../utils\";\nimport { Range } from \"../type/utils\";\n\n/**\n * Events that {@link Camera} can trigger\n * @ko {@link Camera}가 트리거할 수 있는 이벤트들\n * @since 4.0.0\n */\nexport interface CameraEvents {\n /**\n * An event that fires when camera's animation stops\n * @ko 카메라 애니메이션이 멈췄을 때 트리거되는 이벤트\n * @eventName animationEnd\n * @eventOf Camera\n * @version 4.0.0\n */\n [CAMERA_EVENTS.ANIMATION_END]: {\n animation: CameraAnimation\n };\n}\n\n/**\n * Options for {@link Camera}\n * @ko {@link Camera}용 옵션들\n * @since 4.0.0\n */\nexport interface CameraOptions {\n /**\n * @copy View360#initialYaw\n */\n initialYaw: number;\n /**\n * @copy View360#initialPitch\n */\n initialPitch: number;\n /**\n * @copy View360#initialZoom\n */\n initialZoom: number;\n /**\n * @copy View360#yawRange\n */\n yawRange: Range | null;\n /**\n * @copy View360#pitchRange\n */\n pitchRange: Range | null;\n /**\n * @copy View360#zoomRange\n */\n zoomRange: Range | null;\n /**\n * @copy View360#fov\n */\n fov: number;\n}\n\n/**\n * Camera for View360\n * @ko View360용 카메라 구현체\n * @version 4.0.0\n */\nclass Camera extends Component {\n /**\n * Current yaw(y-axis rotation) value\n * @ko 현재 yaw(y축 회전) 값\n * @since 4.0.0\n */\n public yaw: number;\n /**\n * Current pitch(x-axis rotation) value\n * @ko 현재 pitch(x축 회전) 값\n * @since 4.0.0\n */\n public pitch: number;\n /**\n * Current zoom value\n * @ko 현재 줌 값\n * @since 4.0.0\n */\n public zoom: number;\n\n /**\n * @copy View360#initialYaw\n */\n public initialYaw: number;\n /**\n * @copy View360#initialPitch\n */\n public initialPitch: number;\n /**\n * @copy View360#initialPitch\n */\n public initialZoom: number;\n /**\n * @hidden\n * TODO: Please add comment for this when `rollOffset` is added\n */\n public rollOffset: number;\n\n /**\n * Current camera quaternion\n * @ko 현재 회전을 나타내는 quaternion 값\n * @since 4.0.0\n * @internal\n */\n public quaternion: quat;\n /**\n * Current camera position\n * @ko 현재 카메라 위치 좌표\n * @since 4.0.0\n * @internal\n */\n public position: vec3;\n /**\n * Active camera animation, `null` if there isn't.\n * @ko 현재 활성화된 카메라 애니메이션, 없을 경우 `null`값을 가집니다.\n * @since 4.0.0\n */\n public animation: CameraAnimation | null;\n /**\n * Camera's view matrix\n * @ko 카메라의 뷰 변환 행렬\n * @internal\n * @since 4.0.0\n */\n public viewMatrix: mat4;\n /**\n * Camera's projection matrix\n * @ko 카메라의 프로젝션 변환 행렬\n * @internal\n * @since 4.0.0\n */\n public projectionMatrix: mat4;\n\n /**\n * Camera's horizontal FOV(Field of View) value\n * @ko 카메라의 수평 FOV(Field of View) 값\n * @internal\n * @since 4.0.0\n */\n public fov: number;\n\n private _initialYawRange: Range | null;\n private _initialPitchRange: Range | null;\n private _initialZoomRange: Range | null;\n\n private _yawRange: Range | null;\n private _pitchRange: Range | null;\n private _zoomRange: Range | null;\n\n private _up: vec3;\n private _aspect: number;\n private _changed: boolean;\n private _maxRenderHeight: number;\n\n /**\n * Camera's width / height ratio\n * @ko 카메라의 가로 / 세로 비율\n * @readonly\n */\n public get aspect() { return this._aspect; }\n /**\n * Whether the camera's rotation changed from the last frame.\n * @ko 마지막 프레임 이후로 카메라의 회전값이 변경되었는지 나타내는 플래그.\n * @readonly\n */\n public get changed() { return this._changed; }\n /**\n * @copy View360#yawRange\n */\n public get yawRange() { return this._initialYawRange; }\n public set yawRange(val: Range | null) {\n this._initialYawRange = val;\n }\n /**\n * @copy View360#pitchRange\n */\n public get pitchRange() { return this._initialPitchRange; }\n public set pitchRange(val: Range | null) {\n this._initialPitchRange = val;\n }\n /**\n * @copy View360#zoomRange\n */\n public get zoomRange() { return this._initialZoomRange; }\n public set zoomRange(val: Range | null) {\n this._initialZoomRange = val;\n }\n\n /**\n * Create new instance of Camera\n * @param options - Camera options {@ko 카메라 옵션들}\n */\n public constructor({\n initialYaw,\n initialPitch,\n initialZoom,\n yawRange,\n pitchRange,\n zoomRange,\n fov\n }: CameraOptions) {\n super();\n\n this.yaw = initialYaw;\n this.pitch = initialPitch;\n this.zoom = initialZoom;\n this.rollOffset = 0;\n\n this.initialYaw = initialYaw;\n this.initialPitch = initialPitch;\n this.initialZoom = initialZoom;\n\n this.position = vec3.create();\n this.animation = null;\n\n this._up = vec3.fromValues(0, 1, 0);\n this._aspect = 1;\n\n this._initialYawRange = yawRange;\n this._initialPitchRange = pitchRange;\n this._initialZoomRange = zoomRange;\n\n this._yawRange = yawRange;\n this._pitchRange = pitchRange;\n this._zoomRange = zoomRange;\n\n this.quaternion = quat.create();\n this._updateQuaternion();\n\n this.viewMatrix = mat4.create();\n this.projectionMatrix = mat4.create();\n this.fov = fov;\n\n this._maxRenderHeight = -1;\n }\n\n /**\n * Destroy instance and detach all event listeners\n * @ko 인스턴스를 삭제하고 모든 이벤트 리스너를 삭제합니다.\n * @since 4.0.0\n */\n public destroy() {\n this.off();\n }\n\n /**\n * Refresh internal size value.\n * @ko 내부 크기값을 갱신합니다.\n * @param width - New width {@ko 변경된 너비값}\n * @param height - New height {@ko 변경된 높이값}\n * @since 4.0.0\n */\n public resize(width: number, height: number) {\n const prevAspect = this._aspect;\n\n this._aspect = width / height;\n\n if (this._aspect !== prevAspect) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation with euler values.\n * @ko 카메라 회전을 오일러 각 방향으로 변경합니다.\n * @param rotation - Rotation values {@ko 회전 값}\n * @param rotation.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값}\n * @param rotation.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값}\n * @param rotation.zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @since 4.0.0\n */\n public lookAt({\n yaw = this.yaw,\n pitch = this.pitch,\n zoom = this.zoom\n }: Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n }>) {\n const prevQuaternion = quat.clone(this.quaternion);\n const prevZoom = this.zoom;\n\n this.yaw = circulate(yaw, 0, 360);\n this.pitch = clamp(pitch, -90, 90);\n this.zoom = zoom;\n\n this._updateQuaternion();\n\n const zoomDiff = Math.abs(zoom - prevZoom);\n\n if (\n !quat.equals(this.quaternion, prevQuaternion)\n || zoomDiff >= EPSILON * 10 // ignore small changes\n ) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation with quaternion.\n * @ko 카메라 회전을 Quaternion을 이용해서 변경합니다.\n * @param rotation - Quaternion to apply {@ko 적용할 Quaternion}\n * @param zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @since 4.0.0\n */\n public rotate(rotation: quat, zoom: number = this.zoom) {\n const normalized = quat.normalize(quat.create(), rotation);\n const isSameRotation = quat.equals(this.quaternion, normalized);\n quat.copy(this.quaternion, normalized);\n\n const prevZoom = this.zoom;\n const { yaw, pitch } = quatToEuler(normalized);\n\n this.yaw = yaw;\n this.pitch = pitch;\n this.zoom = zoom;\n\n const zoomDiff = Math.abs(zoom - prevZoom);\n\n if (!isSameRotation || zoomDiff >= EPSILON * 10) {\n this.updateMatrix();\n }\n }\n\n /**\n * Change camera's rotation to given euler values by the given duration.\n * @ko 카메라를 주어진 방향으로 주어진 시간동안 서서히 이동시킵니다.\n * @param options - Animation parameters {@ko 애니메이션 패러미터}\n * @param options.yaw - yaw(y-axis rotation) to look at {@ko 바라볼 yaw(y축 회전) 값}\n * @param options.pitch - pitch(x-axis rotation) to look at {@ko 바라볼 pitch(x축 회전) 값}\n * @param options.zoom - zoom value to apply {@ko 적용할 카메라 줌 값}\n * @param options.duration - Duration of the animation {@ko 애니메이션 시간}\n * @param options.easing - Easing function for the animation {@ko 애니메이션에 적용할 easing function}\n */\n public async animateTo({\n yaw = this.yaw,\n pitch = this.pitch,\n zoom = this.zoom,\n duration = 0,\n easing = DEFAULT_EASING\n }: Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n duration: number;\n easing: (x: number) => number;\n }> = {}): Promise {\n if (\n this.yaw === yaw\n && this.pitch === pitch\n && this.zoom === zoom\n ) return;\n\n const from = {\n rotation: quat.clone(this.quaternion),\n zoom: this.zoom\n };\n const to = {\n rotation: eulerToQuat(quat.create(), yaw, pitch, this.rollOffset),\n zoom\n };\n\n const animation = new CameraAnimation(this, from, to, {\n duration,\n easing\n });\n const finishPromise = animation.getFinishPromise();\n\n this.animation = animation;\n finishPromise.then(() => {\n this.animation = null;\n this.trigger(CAMERA_EVENTS.ANIMATION_END, { animation });\n });\n\n return finishPromise;\n }\n\n /**\n * @hidden\n */\n public restrictYawRange(min: number, max: number) {\n this._yawRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictPitchRange(min: number, max: number) {\n this._pitchRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictZoomRange(min: number, max: number) {\n this._zoomRange = { min, max };\n }\n\n /**\n * @hidden\n */\n public restrictRenderHeight(height: number) {\n this._maxRenderHeight = height;\n }\n\n /**\n * @hidden\n */\n public resetRange() {\n this._yawRange = this._initialYawRange;\n this._pitchRange = this._initialPitchRange;\n this._zoomRange = this._initialZoomRange;\n this._maxRenderHeight = -1;\n }\n\n /**\n * Get actual yaw range by the given zoom value.\n * @ko 주어진 zoom 값에 대한 실제 yaw 범위값을 반환합니다.\n * @since 4.0.0\n */\n public getYawRange(zoom: number) {\n const yawLimit = this._yawRange;\n const maxRenderHeight = this._maxRenderHeight;\n if (!yawLimit) return INFINITE_RANGE;\n\n const halfHFov = this.getHorizontalFov(zoom) * 0.5;\n let minYaw = yawLimit.min;\n let maxYaw = yawLimit.max;\n\n if (maxRenderHeight > 0) {\n const halfVFovRad = toVerticalFov(halfHFov * DEG_TO_RAD, this._aspect);\n const h = maxRenderHeight * 0.5;\n const t = Math.tan(halfVFovRad);\n const d = Math.sqrt((1 + h * h) / (1 + t * t));\n const theta = Math.atan(Math.tan(halfHFov * DEG_TO_RAD) * d) * RAD_TO_DEG;\n\n minYaw = yawLimit.min + theta;\n maxYaw = yawLimit.max - theta;\n }\n\n if (minYaw > maxYaw) {\n minYaw = 0;\n maxYaw = 0;\n }\n\n return {\n min: minYaw,\n max: maxYaw\n };\n }\n\n /**\n * Get actual pitch range by the given zoom value.\n * @ko 주어진 zoom 값에 대한 실제 pitch 범위값을 반환합니다.\n * @since 4.0.0\n */\n public getPitchRange(zoom: number) {\n const pitchLimit = this._pitchRange;\n const maxRenderHeight = this._maxRenderHeight;\n\n if (!pitchLimit) return DEFAULT_PITCH_RANGE;\n\n let minPitch = pitchLimit.min;\n let maxPitch = pitchLimit.max;\n\n if (maxRenderHeight > 0) {\n const halfVFov = this.getVerticalFov(zoom) * 0.5;\n\n minPitch = pitchLimit.min + halfVFov;\n maxPitch = pitchLimit.max - halfVFov;\n }\n\n if (minPitch > maxPitch) {\n minPitch = 0;\n maxPitch = 0;\n }\n\n return {\n min: Math.max(minPitch, -90),\n max: Math.min(maxPitch, 90)\n };\n }\n\n /**\n * Get actual zoom range in fov degrees.\n * @ko 실제 줌 범위를 fov각의 범위로 반환합니다.\n * @since 4.0.0\n */\n public getZoomRange() {\n const limit = this._zoomRange ?? DEFAULT_ZOOM_RANGE;\n\n // max (zoom in) -> minimum fov\n const minFov = this.getHorizontalFov(limit.max);\n const maxFov = this.getHorizontalFov(limit.min);\n const currentFov = this.getHorizontalFov(this.zoom);\n\n return {\n min: Math.max(minFov, 1),\n max: Math.min(maxFov, 180),\n current: currentFov\n };\n }\n\n /**\n * Return horizontal fov value when the given zoom is applied. (in degrees, °)\n * @ko 주어진 zoom 값이 적용되었을 때의 수평 fov값을 반환합니다. (도 단위, °)\n * @returns Zoomed horizontal FOV {@ko 줌이 적용된 수평 fov값}\n * @since 4.0.0\n */\n public getHorizontalFov(zoom = this.zoom) {\n return this._getZoomedHorizontalFov(zoom) * RAD_TO_DEG;\n }\n\n /**\n * Return vertical fov value when the given zoom is applied. (in degrees, °)\n * @ko 주어진 zoom 값이 적용되었을 때의 수직 fov값을 반환합니다. (도 단위, °)\n * @returns Zoomed vertical FOV {@ko 줌이 적용된 수직 fov값}\n * @since 4.0.0\n */\n public getVerticalFov(zoom = this.zoom) {\n const aspect = this._aspect;\n const hFov = this._getZoomedHorizontalFov(zoom); // In radians\n const vFov = toVerticalFov(hFov, aspect);\n\n return vFov * RAD_TO_DEG;\n }\n\n /**\n * Calculate zoom value for the given fov.\n * @ko 주어진 fov값을 zoom값으로 변환합니다.\n * @param fov horizontal fov (in degrees, °) {@ko 수평 fov 값 (도 단위, °)}\n * @since 4.0.0\n */\n public fovToZoom(fov: number) {\n const baseFov = this.fov;\n const renderingWidth = Math.tan(DEG_TO_RAD * baseFov * 0.5);\n const zoomedWidth = Math.tan(DEG_TO_RAD * fov * 0.5);\n\n return renderingWidth / zoomedWidth;\n }\n\n /**\n * Update inner matrixes.\n * @ko 내부 행렬들을 업데이트합니다.\n * @internal\n * @since 4.0.0\n */\n public updateMatrix() {\n const up = this._up;\n const aspect = this._aspect;\n const viewMatrix = this.viewMatrix;\n const projMatrix = this.projectionMatrix;\n const position = this.position;\n const rotation = this.quaternion;\n\n const upDir = vec3.create();\n const viewDir = vec3.fromValues(0, 0, -1);\n vec3.transformQuat(viewDir, viewDir, rotation);\n vec3.transformQuat(upDir, up, rotation);\n\n const hFov = this._getZoomedHorizontalFov(); // In radians\n const vFov = toVerticalFov(hFov, aspect);\n\n mat4.lookAt(viewMatrix, position, viewDir, upDir);\n mat4.perspective(projMatrix, vFov, aspect, 0.1, 100);\n\n this._changed = true;\n }\n\n /**\n * @hidden\n */\n public onFrameRender() {\n this._changed = false;\n }\n\n private _updateQuaternion() {\n eulerToQuat(this.quaternion, this.yaw, this.pitch, this.rollOffset);\n }\n\n /**\n * @param zoom Current zoom value\n * @returns horizontal fov including zoom, in radian\n */\n private _getZoomedHorizontalFov(zoom = this.zoom) {\n return 2 * Math.atan(Math.tan(DEG_TO_RAD * this.fov * 0.5) / zoom);\n }\n}\n\nexport default Camera;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass MouseInput extends Component> {\n private _el: HTMLElement | null;\n private _prevPos: [number, number];\n\n public constructor() {\n super();\n\n this._el = null;\n this._prevPos = [0, 0];\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onMouseDown);\n\n this._el = element;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onMouseDown);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this._el = null;\n }\n\n private _onMouseDown = (evt: MouseEvent) => {\n const el = this._el;\n if (!el || evt.button !== BROWSER.MOUSE_BUTTON.LEFT) return;\n\n evt.preventDefault();\n\n if (el.focus) {\n el.focus();\n } else {\n window.focus();\n }\n\n this._prevPos[0] = evt.clientX;\n this._prevPos[1] = evt.clientY;\n\n window.addEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.addEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: false\n });\n }\n\n private _onMouseMove = (evt: MouseEvent) => {\n evt.preventDefault();\n\n const x = evt.clientX;\n const y = evt.clientY;\n const prevPos = this._prevPos;\n const deltaX = x - prevPos[0];\n const deltaY = y - prevPos[1];\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta: {\n x: deltaX,\n y: deltaY\n },\n isTouch: false,\n isKeyboard: false\n });\n\n prevPos[0] = x;\n prevPos[1] = y;\n }\n\n private _onMouseUp = () => {\n this._prevPos[0] = 0;\n this._prevPos[1] = 0;\n\n window.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove, false);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onMouseUp, false);\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: false,\n scrolling: false\n });\n }\n}\n\nexport default MouseInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\nimport { isFullscreen } from \"../../utils\";\n\nclass TouchInput extends Component> {\n private _el: HTMLElement | null;\n private _prevPos: [number, number];\n private _isFirstTouch: boolean;\n private _scrolling: boolean;\n private _scrollable: boolean;\n\n public get scrollable() { return this._scrollable; }\n public set scrollable(val: boolean) { this._scrollable = val; }\n\n public constructor() {\n super();\n\n this._el = null;\n this._prevPos = [0, 0];\n this._isFirstTouch = false;\n this._scrolling = false;\n this._scrollable = false;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.TOUCH_START, this._onTouchStart, { passive: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, { passive: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = element;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.TOUCH_START, this._onTouchStart);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = null;\n }\n\n private _onTouchStart = (evt: TouchEvent) => {\n if (evt.touches.length > 1 || this._scrolling) return;\n\n const touch = evt.touches[0];\n\n this._isFirstTouch = true;\n this._prevPos[0] = touch.clientX;\n this._prevPos[1] = touch.clientY;\n\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: true,\n isKeyboard: false\n });\n };\n\n private _onTouchMove = (evt: TouchEvent) => {\n // Only the one finger motion should be considered\n if (evt.touches.length > 1 || this._scrolling) return;\n\n const touch = evt.touches[0];\n const scrollable = this._scrollable;\n const prevPos = this._prevPos;\n\n const x = touch.clientX;\n const y = touch.clientY;\n const deltaX = x - prevPos[0];\n const deltaY = y - prevPos[1];\n\n if (this._isFirstTouch) {\n if (scrollable && !isFullscreen()) {\n if (Math.abs(deltaY) > Math.abs(deltaX)) {\n // Assume Scrolling\n this._scrolling = true;\n return;\n }\n }\n\n this._isFirstTouch = false;\n }\n\n if (evt.cancelable !== false) {\n evt.preventDefault();\n }\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta: {\n x: deltaX,\n y: deltaY\n },\n isTouch: true,\n isKeyboard: false\n });\n\n prevPos[0] = x;\n prevPos[1] = y;\n };\n\n private _onTouchEnd = (evt: TouchEvent) => {\n if (evt.touches.length !== 0) return;\n\n const touch = evt.touches[0];\n const prevPos = this._prevPos;\n\n if (touch) {\n prevPos[0] = touch.clientX;\n prevPos[1] = touch.clientY;\n } else {\n prevPos[0] = 0;\n prevPos[1] = 0;\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: true,\n isKeyboard: false,\n scrolling: this._scrolling\n });\n }\n\n if (evt.cancelable !== false) {\n evt.preventDefault();\n }\n\n this._scrolling = false;\n };\n}\n\nexport default TouchInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass KeyboardInput extends Component> {\n private _el: HTMLElement | null;\n private _pressed: {\n LEFT: boolean;\n UP: boolean;\n RIGHT: boolean;\n DOWN: boolean;\n };\n\n public get active() {\n const pressed = this._pressed;\n return pressed.LEFT || pressed.UP || pressed.RIGHT || pressed.DOWN;\n }\n\n public constructor() {\n super();\n\n this._el = null;\n this._clearPressedKeys();\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown);\n element.addEventListener(BROWSER.EVENTS.KEY_UP, this._onKeyUp);\n\n this._el = element;\n this._clearPressedKeys();\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown);\n element.removeEventListener(BROWSER.EVENTS.KEY_UP, this._onKeyUp);\n\n this._el = null;\n this._clearPressedKeys();\n }\n\n public update() {\n const delta = this._getDeltaByPressedKeys();\n\n if (delta.x !== 0 || delta.y !== 0) {\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: false,\n isKeyboard: true\n });\n }\n }\n\n private _clearPressedKeys() {\n this._pressed = BROWSER.KEY_DIRECTION.reduce((obj, keyName) => {\n return {\n ...obj,\n [keyName]: false\n };\n }, {} as KeyboardInput[\"_pressed\"]);\n }\n\n private _updateKeyPress(event: KeyboardEvent, isEnable: boolean): void {\n const pressed = this._pressed;\n const keyToUpdate = event.keyCode != null\n ? BROWSER.DIRECTION_KEY_CODE[event.keyCode]\n : BROWSER.DIRECTION_KEY_NAME[event.key];\n\n if (!keyToUpdate) return;\n\n pressed[keyToUpdate] = isEnable;\n }\n\n private _getPressedKeyCount() {\n return BROWSER.KEY_DIRECTION.filter(key => this._pressed[key]).length;\n }\n\n private _getDeltaByPressedKeys() {\n const pressed = this._pressed;\n let x = 0;\n let y = 0;\n\n if (pressed.LEFT) {\n x += 1;\n }\n\n if (pressed.RIGHT) {\n x -= 1;\n }\n\n if (pressed.UP) {\n y += 1;\n }\n\n if (pressed.DOWN) {\n y -= 1;\n }\n\n return {\n x, y\n };\n }\n\n private _onKeyDown = (evt: KeyboardEvent) => {\n // Ignore all other keypress except main arrow keys\n if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return;\n\n this._updateKeyPress(evt, true);\n\n const pressedCount = this._getPressedKeyCount();\n if (pressedCount <= 0) return;\n\n evt.preventDefault();\n if (pressedCount === 1 && !evt.repeat) {\n // On first keydown\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: true\n });\n }\n };\n\n private _onKeyUp = (evt: KeyboardEvent) => {\n // Ignore all other keypress except main arrow keys\n if (evt.location !== KeyboardEvent.DOM_KEY_LOCATION_STANDARD) return;\n\n this._updateKeyPress(evt, false);\n\n const pressedCount = this._getPressedKeyCount();\n if (pressedCount > 0) return;\n\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: true,\n scrolling: false\n });\n };\n}\n\nexport default KeyboardInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport MouseInput from \"./input/MouseInput\";\nimport TouchInput from \"./input/TouchInput\";\nimport KeyboardInput from \"./input/KeyboardInput\";\nimport Camera from \"../core/Camera\";\nimport Motion from \"../core/Motion\";\nimport { CONTROL_EVENTS, INFINITE_RANGE, DEFAULT_PITCH_RANGE, DEFAULT_ANIMATION_DURATION, DEFAULT_EASING, DEG_TO_RAD, RAD_TO_DEG } from \"../const/internal\";\nimport { toVerticalFov } from \"../utils\";\nimport { ControlEvents, InputEvents } from \"../type/internal\";\n\n/**\n * Options for {@link RotateControl}\n * @ko {@link RotateControl}용 옵션들\n * @since 4.0.0\n */\nexport interface RotateControlOptions {\n /**\n * @copy RotateControl#pointerScale\n */\n pointerScale: [number, number];\n /**\n * @copy RotateControl#keyboardScale\n */\n keyboardScale: [number, number];\n /**\n * @copy RotateControl#duration\n */\n duration: number;\n /**\n * @copy RotateControl#easing\n */\n easing: (x: number) => number;\n /**\n * @copy RotateControl#disablePitch\n */\n disablePitch: boolean;\n /**\n * @copy RotateControl#disableYaw\n */\n disableYaw: boolean;\n /**\n * @copy RotateControl#disableKeyboard\n */\n disableKeyboard: boolean;\n}\n\ntype RotateDeltaType = { x: number; y: number; };\nexport type RotateControlEvents = ControlEvents;\n\n/**\n * Camera's rotation control\n * @ko 카메라의 회전을 담당하는 컨트롤\n * @since 4.0.0\n */\nclass RotateControl extends Component implements CameraControl {\n // Options\n private _pointerScale: RotateControlOptions[\"pointerScale\"];\n private _keyboardScale: RotateControlOptions[\"keyboardScale\"];\n private _duration: RotateControlOptions[\"duration\"];\n private _easing: RotateControlOptions[\"easing\"];\n private _disablePitch: RotateControlOptions[\"disablePitch\"];\n private _disableYaw: RotateControlOptions[\"disableYaw\"];\n private _disableKeyboard: RotateControlOptions[\"disableKeyboard\"];\n\n // Internal values\n private _controlEl: HTMLElement;\n private _enableBlocked: boolean;\n private _mouseInput: MouseInput;\n private _touchInput: TouchInput;\n private _keyboardInput: KeyboardInput;\n private _xMotion: Motion;\n private _yMotion: Motion;\n private _screenScale: [number, number];\n private _zoomScale: number;\n private _enabled: boolean;\n private _changedWhileDragging: boolean;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() {\n return this._keyboardInput.active\n || this._xMotion.activated\n || this._yMotion.activated;\n }\n /**\n * Current yaw value\n * @ko 현재 yaw 값\n * @readonly\n * @since 4.0.0\n */\n public get yaw() { return this._xMotion; }\n /**\n * Current pitch value\n * @ko 현재 pitch 값\n * @readonly\n * @since 4.0.0\n */\n public get pitch() { return this._yMotion; }\n /**\n * @copy View360#scrollable\n */\n public get scrollable() { return this._touchInput.scrollable; }\n public set scrollable(val: boolean) {\n this._touchInput.scrollable = val;\n }\n\n /**\n * Scale factor for mouse/touch rotation\n * @ko 마우스/터치를 통한 회전 배율\n * @default [1, 1]\n * @since 4.0.0\n */\n public get pointerScale() { return this._pointerScale; }\n public set pointerScale(val: RotateControlOptions[\"pointerScale\"]) {\n this._pointerScale = val;\n }\n\n /**\n * Scale factor for keyboard rotation\n * @ko 키보드를 통한 회전 배율\n * @default [1, 1]\n * @since 4.0.0\n */\n public get keyboardScale() { return this._keyboardScale; }\n public set keyboardScale(val: RotateControlOptions[\"keyboardScale\"]) {\n this._keyboardScale = val;\n }\n\n /**\n * Duration of the input animation (ms)\n * @ko 회전 애니메이션의 시간 (ms)\n * @default 300\n */\n public get duration() { return this._duration; }\n public set duration(val: RotateControlOptions[\"duration\"]) {\n this._duration = val;\n this._xMotion.duration = val;\n this._yMotion.duration = val;\n }\n\n /**\n * Easing function of the animation\n * @ko 회전 애니메이션에 적용할 easing 함수\n * @default EASING.EASE_OUT_CUBIC\n * @see EASING\n */\n public get easing() { return this._easing; }\n public set easing(val: RotateControlOptions[\"easing\"]) {\n this._easing = val;\n this._xMotion.easing = val;\n this._yMotion.easing = val;\n }\n\n /**\n * Disable X-axis(pitch) rotation.\n * @ko x축 회전(pitch)을 비활성화합니다.\n * @default false\n */\n public get disablePitch() { return this._disablePitch; }\n public set disablePitch(val: RotateControlOptions[\"disablePitch\"]) { this._disablePitch = val; }\n\n /**\n * Disable Y-axis(yaw) rotation.\n * @ko y축 회전(yaw)을 비활성화합니다.\n * @default false\n */\n public get disableYaw() { return this._disableYaw; }\n public set disableYaw(val: RotateControlOptions[\"disableYaw\"]) { this._disableYaw = val; }\n\n /**\n * Disable rotation by keyboard.\n * @ko 키보드를 이용한 회전을 비활성화합니다.\n * @default false\n */\n public get disableKeyboard() { return this._disableKeyboard; }\n public set disableKeyboard(val: RotateControlOptions[\"disableKeyboard\"]) { this._disableKeyboard = val; }\n\n /**\n * Create new RotateControl instance\n * @ko RotateControl의 인스턴스를 생성합니다.\n * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트}\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(controlEl: HTMLElement, enableBlocked: boolean, {\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING,\n pointerScale = [1, 1],\n keyboardScale = [1, 1],\n disablePitch = false,\n disableYaw = false,\n disableKeyboard = false\n }: Partial = {}) {\n super();\n\n this._controlEl = controlEl;\n this._pointerScale = pointerScale;\n this._keyboardScale = keyboardScale;\n this._duration = duration;\n this._easing = easing;\n this._disablePitch = disablePitch;\n this._disableYaw = disableYaw;\n this._disableKeyboard = disableKeyboard;\n\n this._enableBlocked = enableBlocked;\n this._mouseInput = new MouseInput();\n this._touchInput = new TouchInput();\n this._keyboardInput = new KeyboardInput();\n this._xMotion = new Motion({ duration, range: INFINITE_RANGE, easing });\n this._yMotion = new Motion({ duration, range: DEFAULT_PITCH_RANGE, easing });\n this._screenScale = [1, 1];\n this._zoomScale = 1;\n this._enabled = false;\n this._changedWhileDragging = false;\n this._bindInputs();\n }\n\n public destroy(): void {\n this.disable();\n this._mouseInput.off();\n this._touchInput.off();\n this._keyboardInput.off();\n this.off();\n this._changedWhileDragging = false;\n }\n\n /**\n * @hidden\n */\n public update(delta: number): void {\n if (!this._enabled) return;\n\n const xMotion = this._xMotion;\n const yMotion = this._yMotion;\n const keyboardInput = this._keyboardInput;\n\n if (!this._disableKeyboard) {\n keyboardInput.update();\n }\n\n if (!this._disablePitch) {\n yMotion.update(delta);\n }\n\n if (!this._disableYaw) {\n xMotion.update(delta);\n }\n }\n\n /**\n * @hidden\n */\n public updateRange(camera: Camera, zoom: number) {\n const yawRange = camera.getYawRange(zoom);\n const pitchRange = camera.getPitchRange(zoom);\n\n this._xMotion.setRange(yawRange.min, yawRange.max);\n this._yMotion.setRange(pitchRange.min, pitchRange.max);\n }\n\n /**\n * @hidden\n */\n public setZoomScale(val: number) {\n this._zoomScale = val;\n }\n\n /**\n * Resize control to match target size.\n * @ko 컨트롤의 내부 크기를 갱신합니다.\n * @param hfov - Camera horizontal fov in degrees {@ko 카메라의 수평방향 fov값 (도 단위)}\n * @param aspect - Camera aspect {@ko 카메라 가로/세로 비율}\n * @param width - New width {@ko 갱신된 너비}\n * @param height - New height {@ko 갱신된 높이}\n */\n public resize(hfov: number, aspect: number, width: number, height: number) {\n const vfov = toVerticalFov(hfov * DEG_TO_RAD, aspect) * RAD_TO_DEG;\n\n this._screenScale[0] = hfov / width;\n this._screenScale[1] = vfov / height;\n }\n\n public enable(): void {\n if (this._enabled) return;\n\n const element = this._controlEl;\n\n this._mouseInput.enable(element);\n this._touchInput.enable(element);\n this._keyboardInput.enable(element);\n\n this._enabled = true;\n this._enableBlocked = false;\n\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: true });\n }\n\n public disable(): void {\n if (!this._enabled) return;\n\n this._mouseInput.disable();\n this._touchInput.disable();\n this._keyboardInput.disable();\n\n this._enabled = false;\n\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: true });\n }\n\n public sync(camera: Camera): void {\n this.updateRange(camera, camera.zoom);\n\n this._xMotion.reset(camera.yaw);\n this._yMotion.reset(camera.pitch);\n }\n\n private _bindInputs() {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n const keyboardInput = this._keyboardInput;\n\n mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n touchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n touchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n keyboardInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n keyboardInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n keyboardInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n }\n\n private _onInputStart = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n this._changedWhileDragging = false;\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n ...evt,\n inputType: \"rotate\"\n });\n };\n\n private _onChange = (evt: InputEvents[typeof CONTROL_EVENTS.CHANGE]) => {\n const delta = evt.delta;\n const invZoomScale = 1 / this._zoomScale; // Reduce speed on zoom\n const screenScale = this._screenScale;\n const keyboardScale = this._keyboardScale;\n const pointerScale = this._pointerScale;\n\n let scale: [number, number];\n\n if (evt.isKeyboard) {\n scale = [\n keyboardScale[0] * invZoomScale,\n keyboardScale[1] * invZoomScale\n ];\n } else {\n scale = [\n pointerScale[0] * screenScale[0] * invZoomScale,\n pointerScale[1] * screenScale[1] * invZoomScale\n ];\n }\n\n const scaledX = delta.x * scale[0];\n const scaledY = delta.y * scale[1];\n\n this._xMotion.setNewEndByDelta(scaledX);\n this._yMotion.setNewEndByDelta(scaledY);\n\n this._changedWhileDragging = true;\n }\n\n private _onInputEnd = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n ...evt,\n inputType: \"rotate\"\n });\n\n if (!this._changedWhileDragging && !evt.isKeyboard && !evt.scrolling) {\n this.trigger(CONTROL_EVENTS.STATIC_CLICK, {\n isTouch: evt.isTouch\n });\n }\n\n this._changedWhileDragging = false;\n };\n}\n\nexport default RotateControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS, DEFAULT_ANIMATION_DURATION } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass WheelInput extends Component> {\n private _el: HTMLElement | null;\n private _scrollable: boolean;\n private _baseScale: number;\n private _inputTimer: number;\n\n public get scrollable() { return this._scrollable; }\n public set scrollable(val: boolean) { this._scrollable = val; }\n\n public constructor() {\n super();\n\n this._el = null;\n this._baseScale = 0.04;\n this._scrollable = false;\n this._inputTimer = -1;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.WHEEL, this._onWheel, { passive: false, capture: false });\n\n this._el = element;\n this._clearTimer();\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.WHEEL, this._onWheel, false);\n\n this._el = null;\n this._clearTimer();\n }\n\n private _onWheel = (evt: WheelEvent) => {\n const scrollable = this._scrollable;\n\n if (evt.deltaY === 0 || scrollable) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n\n if (this._inputTimer < 0) {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: false,\n isKeyboard: false\n });\n } else {\n this._clearTimer();\n }\n\n const delta = this._baseScale * evt.deltaY;\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: false,\n isKeyboard: false\n });\n\n this._inputTimer = window.setTimeout(() => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: false,\n isKeyboard: false,\n scrolling: false\n });\n this._inputTimer = -1;\n }, DEFAULT_ANIMATION_DURATION);\n };\n\n private _clearTimer() {\n window.clearTimeout(this._inputTimer);\n this._inputTimer = -1;\n }\n}\n\nexport default WheelInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\n\nclass PinchInput extends Component> {\n private _el: HTMLElement | null;\n private _baseScale: number;\n private _prevDistance: number;\n private _isFirstTouch: boolean;\n\n public constructor() {\n super();\n\n this._el = null;\n this._baseScale = -0.2;\n this._prevDistance = -1;\n this._isFirstTouch = true;\n }\n\n public enable(element: HTMLElement) {\n if (this._el) return;\n\n element.addEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, { passive: false, capture: false });\n element.addEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = element;\n this._prevDistance = -1;\n this._isFirstTouch = true;\n }\n\n public disable() {\n const element = this._el;\n if (!element) return;\n\n element.removeEventListener(BROWSER.EVENTS.TOUCH_MOVE, this._onTouchMove, false);\n element.removeEventListener(BROWSER.EVENTS.TOUCH_END, this._onTouchEnd);\n\n this._el = null;\n }\n\n private _onTouchMove = (evt: TouchEvent) => {\n const touches = evt.touches;\n if (touches.length !== 2) return;\n\n if (!evt.cancelable) return;\n\n evt.preventDefault();\n evt.stopPropagation();\n\n const prevDistance = this._prevDistance;\n\n const diff = [\n touches[0].pageX - touches[1].pageX,\n touches[0].pageY - touches[1].pageY\n ];\n\n const distance = Math.sqrt(diff[0] * diff[0] + diff[1] * diff[1]) * this._baseScale;\n const delta = this._isFirstTouch\n ? 0\n : distance - prevDistance;\n\n if (this._isFirstTouch) {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n srcEvent: evt,\n isTouch: true,\n isKeyboard: false\n });\n }\n\n this._prevDistance = distance;\n this._isFirstTouch = false;\n\n this.trigger(CONTROL_EVENTS.CHANGE, {\n delta,\n isTouch: true,\n isKeyboard: false\n });\n };\n\n private _onTouchEnd = (evt: TouchEvent) => {\n if (evt.touches.length !== 0) return;\n\n if (!this._isFirstTouch) {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n isTouch: true,\n isKeyboard: false,\n scrolling: false\n });\n }\n\n this._prevDistance = -1;\n this._isFirstTouch = true;\n };\n}\n\nexport default PinchInput;\n","/*\n* Copyright (c) 2023-present NAVER Corp.\n* egjs projects are licensed under the MIT license\n*/\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport WheelInput from \"./input/WheelInput\";\nimport PinchInput from \"./input/PinchInput\";\nimport Camera from \"../core/Camera\";\nimport Motion from \"../core/Motion\";\nimport {\n CONTROL_EVENTS,\n DEFAULT_ANIMATION_DURATION,\n DEFAULT_EASING,\n INFINITE_RANGE\n} from \"../const/internal\";\nimport { ControlEvents, InputEvents } from \"../type/internal\";\n\n/**\n * Options for {@link ZoomControl}\n * @ko {@link ZoomControl}용 옵션들\n * @since 4.0.0\n */\nexport interface ZoomControlOptions {\n /**\n * @copy ZoomControl#scale\n */\n scale: number;\n /**\n * @copy ZoomControl#duration\n */\n duration: number;\n /**\n * @copy ZoomControl#easing\n */\n easing: (x: number) => number;\n}\n\ntype ZoomControlEvents = ControlEvents;\n\n/**\n * Camera's zoom control\n * @ko 카메라의 줌 값을 담당하는 컨트롤\n * @since 4.0.0\n */\nclass ZoomControl extends Component implements CameraControl {\n // Options\n private _scale: ZoomControlOptions[\"scale\"];\n\n // Internal values\n private _controlEl: HTMLElement;\n private _enableBlocked: boolean;\n private _wheelInput: WheelInput;\n private _pinchInput: PinchInput;\n private _motion: Motion;\n private _enabled: boolean;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() { return this._motion.activated; }\n /**\n * Current zoom value\n * @ko 현재 줌 값\n * @since 4.0.0\n * @readonly\n */\n public get zoom() { return this._motion.val; }\n /**\n * @copy View360#wheelScrollable\n */\n public get scrollable() { return this._wheelInput.scrollable; }\n public set scrollable(val: boolean) {\n this._wheelInput.scrollable = val;\n }\n /**\n * @hidden\n */\n public get range() { return this._motion.range; }\n\n /**\n * Scale factor of the zoom\n * @ko 입력에 의한 줌 배율\n * @default 1\n * @since 4.0.0\n */\n public get scale() { return this._scale; }\n public set scale(val: ZoomControlOptions[\"scale\"]) { this._scale = val; }\n\n /**\n * Duration of the input animation (ms)\n * @ko 회전 애니메이션의 시간 (ms)\n * @default 300\n * @since 4.0.0\n */\n public get duration() { return this._motion.duration; }\n\n /**\n * Easing function of the animation\n * @ko 회전 애니메이션에 적용할 easing 함수\n * @default EASING.EASE_OUT_CUBIC\n * @see EASING\n * @since 4.0.0\n */\n public get easing() { return this._motion.easing; }\n\n /**\n * Create new ZoomControl instance\n * @ko ZoomControl의 인스턴스를 생성합니다.\n * @param controlEl - Element to attach handlers {@ko 입력을 받을 엘리먼트}\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(controlEl: HTMLElement, enableBlocked: boolean, {\n scale = 1,\n duration = DEFAULT_ANIMATION_DURATION,\n easing = DEFAULT_EASING\n }: Partial = {}) {\n super();\n\n this._scale = scale;\n\n this._controlEl = controlEl;\n this._enableBlocked = enableBlocked;\n this._wheelInput = new WheelInput();\n this._pinchInput = new PinchInput();\n this._motion = new Motion({\n duration,\n easing,\n range: INFINITE_RANGE\n });\n this._enabled = false;\n\n this._bindInputs();\n }\n\n public destroy(): void {\n this.disable();\n this._wheelInput.off();\n this._pinchInput.off();\n this.off();\n }\n\n /**\n * @hidden\n */\n public update(delta: number): void {\n if (!this._enabled) return;\n\n const motion = this._motion;\n motion.update(delta);\n }\n\n public enable(): void {\n if (this._enabled) return;\n\n const element = this._controlEl;\n this._wheelInput.enable(element);\n this._pinchInput.enable(element);\n\n this._enabled = true;\n this._enableBlocked = false;\n\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: false });\n }\n\n public disable(): void {\n if (!this._enabled) return;\n\n this._wheelInput.disable();\n this._pinchInput.disable();\n\n this._enabled = false;\n\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: false });\n }\n\n public sync(camera: Camera): void {\n const motion = this._motion;\n const range = camera.getZoomRange();\n\n motion.setRange(range.min, range.max);\n motion.reset(range.current);\n }\n\n private _bindInputs() {\n const wheelInput = this._wheelInput;\n const pinchInput = this._pinchInput;\n\n wheelInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n wheelInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n wheelInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n pinchInput.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n pinchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n pinchInput.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n }\n\n private _onInputStart = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n this.trigger(CONTROL_EVENTS.INPUT_START, {\n ...evt,\n inputType: \"zoom\"\n });\n };\n\n private _onChange = ({ delta }: InputEvents[typeof CONTROL_EVENTS.CHANGE]) => {\n const scale = this._scale;\n const scaledDelta = delta * scale;\n\n this._motion.setNewEndByDelta(scaledDelta);\n };\n\n private _onInputEnd = (evt: InputEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n this.trigger(CONTROL_EVENTS.INPUT_END, {\n ...evt,\n inputType: \"zoom\"\n });\n };\n}\n\nexport default ZoomControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { quat, vec3 } from \"gl-matrix\";\nimport * as BROWSER from \"../../const/browser\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"../../const/internal\";\nimport { InputEvents } from \"../../type/internal\";\nimport { quatToEuler } from \"../../utils\";\n\nexport const ROTATE_CONSTANT = {\n PITCH_DELTA: 1,\n YAW_DELTA_BY_ROLL: 2,\n YAW_DELTA_BY_YAW: 3\n} as const;\n\nROTATE_CONSTANT[ROTATE_CONSTANT.PITCH_DELTA] = {\n targetAxis: [0, 1, 0],\n meshPoint: [0, 0, 1]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_ROLL] = {\n targetAxis: [0, 1, 0],\n meshPoint: [1, 0, 0]\n};\nROTATE_CONSTANT[ROTATE_CONSTANT.YAW_DELTA_BY_YAW] = {\n targetAxis: [1, 0, 0],\n meshPoint: [0, 0, 1]\n};\n\nclass GyroInput extends Component> {\n public quaternion: quat;\n\n private _ignoreRoll: boolean;\n\n private _yawOrigin: number;\n private _yawOffset: number;\n private _orientation: {\n alpha: number;\n beta: number;\n gamma: number;\n }\n private _orientationUpdated: boolean;\n private _needsCalibrate: boolean;\n private _screenOrientation: number;\n private _enabled: boolean;\n\n public get enabled() { return this._enabled; }\n public get orientationUpdated() { return this._orientationUpdated; }\n public get ignoreRoll() { return this._ignoreRoll; }\n public set ignoreRoll(val: boolean) { this._ignoreRoll = val; }\n\n public constructor() {\n super();\n\n this.quaternion = quat.create();\n\n this._orientation = {\n alpha: 0,\n beta: 90,\n gamma: 0\n };\n this._yawOrigin = 0;\n this._yawOffset = 0;\n this._orientationUpdated = false;\n this._screenOrientation = 0;\n this._needsCalibrate = true;\n this._enabled = false;\n }\n\n public enable() {\n if (this._enabled) return;\n\n window.addEventListener(BROWSER.EVENTS.DEVICE_ORIENTATION, this._onDeviceOrientation);\n window.addEventListener(BROWSER.EVENTS.ORIENTATION_CHANGE, this._updateScreenOrientation);\n\n this._updateScreenOrientation();\n this._orientationUpdated = false;\n this._needsCalibrate = true;\n this._enabled = true;\n }\n\n public disable() {\n if (!this._enabled) return;\n\n window.removeEventListener(BROWSER.EVENTS.DEVICE_ORIENTATION, this._onDeviceOrientation);\n window.removeEventListener(BROWSER.EVENTS.ORIENTATION_CHANGE, this._updateScreenOrientation);\n\n this._enabled = false;\n }\n\n public update() {\n this._updateRotation();\n this._orientationUpdated = false;\n }\n\n public collectDelta() {\n if (!this._orientationUpdated) {\n return {\n pitch: 0,\n yaw: 0\n };\n }\n\n const prevRotation = quat.clone(this.quaternion);\n\n this._updateRotation();\n this._orientationUpdated = false;\n\n return this._toEulerDelta(prevRotation, this.quaternion);\n }\n\n public setInitialRotation(yaw: number) {\n this._yawOrigin = yaw;\n }\n\n private _onDeviceOrientation = (evt: DeviceOrientationEvent) => {\n const prevOrientation = this._orientation;\n const { alpha, beta, gamma } = evt;\n\n if (\n alpha == null\n || beta == null\n || gamma == null\n ) return;\n\n prevOrientation.alpha = alpha;\n prevOrientation.beta = beta;\n prevOrientation.gamma = gamma;\n\n this._orientationUpdated = true;\n\n if (this._needsCalibrate) {\n this._needsCalibrate = false;\n this._calibrateSensor();\n }\n };\n\n private _calibrateSensor() {\n const yawOrigin = this._yawOrigin;\n const rotation = this.quaternion;\n\n this._yawOffset = 0;\n this._updateRotation();\n\n const { yaw: sensorYaw } = quatToEuler(rotation);\n this._yawOffset = sensorYaw - yawOrigin;\n this._updateRotation();\n\n this._needsCalibrate = false;\n }\n\n private _updateRotation() {\n const rotation = this.quaternion;\n const { alpha, beta, gamma } = this._orientation;\n\n quat.identity(rotation);\n quat.rotateY(rotation, rotation, (alpha - this._yawOffset) * DEG_TO_RAD);\n quat.rotateX(rotation, rotation, beta * DEG_TO_RAD);\n quat.rotateZ(rotation, rotation, -gamma * DEG_TO_RAD);\n\n const screen = quat.create();\n const screenAngle = -this._screenOrientation * 0.5 * DEG_TO_RAD;\n const world = quat.fromValues(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5));\n\n quat.set(screen, 0, Math.sin(screenAngle), 0, Math.cos(screenAngle));\n quat.multiply(rotation, rotation, screen);\n quat.multiply(rotation, rotation, world);\n\n quat.normalize(rotation, rotation);\n }\n\n private _updateScreenOrientation = () => {\n if (window.screen && window.screen.orientation && window.screen.orientation.angle !== undefined) {\n this._screenOrientation = screen.orientation.angle;\n } else if (window.orientation !== undefined) {\n this._screenOrientation = window.orientation >= 0 ?\n window.orientation : 360 + window.orientation;\n } else {\n this._screenOrientation = 0;\n }\n }\n\n private _toEulerDelta(prevQuat: quat, currentQuat: quat) {\n return {\n yaw: this._getDeltaYaw(prevQuat, currentQuat),\n pitch: this._getDeltaPitch(prevQuat, currentQuat),\n };\n }\n\n private _getDeltaYaw(prvQ: quat, curQ: quat): number {\n const yawDeltaByYaw = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_YAW);\n const yawDeltaByRoll = this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.YAW_DELTA_BY_ROLL)\n * Math.sin(this._extractPitchFromQuat(curQ));\n\n return yawDeltaByRoll + yawDeltaByYaw;\n }\n\n private _getDeltaPitch(prvQ: quat, curQ: quat): number {\n return this._getRotationDelta(prvQ, curQ, ROTATE_CONSTANT.PITCH_DELTA);\n }\n\n private _getRotationDelta(prevQ: quat, curQ: quat, rotateKind: typeof ROTATE_CONSTANT[keyof typeof ROTATE_CONSTANT]) {\n const targetAxis = vec3.fromValues(\n ROTATE_CONSTANT[rotateKind].targetAxis[0],\n ROTATE_CONSTANT[rotateKind].targetAxis[1],\n ROTATE_CONSTANT[rotateKind].targetAxis[2]\n );\n const meshPoint = ROTATE_CONSTANT[rotateKind].meshPoint;\n\n const prevQuaternion = quat.clone(prevQ);\n const curQuaternion = quat.clone(curQ);\n\n quat.normalize(prevQuaternion, prevQuaternion);\n quat.normalize(curQuaternion, curQuaternion);\n\n let prevPoint = vec3.fromValues(0, 0, 1);\n let curPoint = vec3.fromValues(0, 0, 1);\n\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n vec3.transformQuat(targetAxis, targetAxis, curQuaternion);\n\n const rotateDistance = vec3.dot(targetAxis, vec3.cross(vec3.create(), prevPoint, curPoint));\n const rotateDirection = rotateDistance > 0 ? 1 : -1;\n\n // when counter clock wise, use vec3.fromValues(0,1,0)\n // when clock wise, use vec3.fromValues(0,-1,0)\n // const meshPoint1 = vec3.fromValues(0, 0, 0);\n const meshPoint2 = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n\n let meshPoint3;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n meshPoint3 = vec3.fromValues(0, rotateDirection, 0);\n } else {\n meshPoint3 = vec3.fromValues(rotateDirection, 0, 0);\n }\n\n vec3.transformQuat(meshPoint2, meshPoint2, curQuaternion);\n vec3.transformQuat(meshPoint3, meshPoint3, curQuaternion);\n\n const vecU = meshPoint2;\n const vecV = meshPoint3;\n const vecN = vec3.create();\n\n vec3.cross(vecN, vecU, vecV);\n vec3.normalize(vecN, vecN);\n\n const coefficientA = vecN[0];\n const coefficientB = vecN[1];\n const coefficientC = vecN[2];\n\n // a point on the plane\n curPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(curPoint, curPoint, curQuaternion);\n\n // a point should project on the plane\n prevPoint = vec3.fromValues(meshPoint[0], meshPoint[1], meshPoint[2]);\n vec3.transformQuat(prevPoint, prevPoint, prevQuaternion);\n\n // distance between prevPoint and the plane\n let distance = Math.abs(\n prevPoint[0] * coefficientA +\n prevPoint[1] * coefficientB +\n prevPoint[2] * coefficientC\n );\n\n const projectedPrevPoint = vec3.create();\n\n vec3.subtract(projectedPrevPoint, prevPoint, vec3.scale(vec3.create(), vecN, distance));\n\n let trigonometricRatio =\n (projectedPrevPoint[0] * curPoint[0] +\n projectedPrevPoint[1] * curPoint[1] +\n projectedPrevPoint[2] * curPoint[2]) /\n (vec3.length(projectedPrevPoint) * vec3.length(curPoint));\n\n // defensive block\n if (trigonometricRatio > 1) {\n trigonometricRatio = 1;\n }\n\n const theta = Math.acos(trigonometricRatio);\n\n const crossVec = vec3.cross(vec3.create(), curPoint, projectedPrevPoint);\n\n distance = coefficientA * crossVec[0]\n + coefficientB * crossVec[1]\n + coefficientC * crossVec[2];\n\n let thetaDirection: number;\n\n if (rotateKind !== ROTATE_CONSTANT.YAW_DELTA_BY_YAW) {\n thetaDirection = distance > 0 ? 1 : -1;\n } else {\n thetaDirection = distance < 0 ? 1 : -1;\n }\n\n const deltaRadian = theta * thetaDirection * rotateDirection;\n\n return deltaRadian * RAD_TO_DEG;\n }\n\n private _extractPitchFromQuat(quaternion: quat) {\n const baseV = vec3.fromValues(0, 0, 1);\n vec3.transformQuat(baseV, baseV, quaternion);\n\n return -1 * Math.atan2(\n baseV[1],\n Math.sqrt(Math.pow(baseV[0], 2) + Math.pow(baseV[2], 2)));\n }\n}\n\nexport default GyroInput;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport CameraControl from \"./CameraControl\";\nimport GyroInput from \"./input/GyroInput\";\nimport Motion from \"../core/Motion\";\nimport Camera from \"../core/Camera\";\nimport * as BROWSER from \"../const/browser\";\nimport { CONTROL_EVENTS } from \"../const/internal\";\nimport { ControlEvents } from \"../type/internal\";\nimport { sensorCanBeEnabledIOS } from \"../utils\";\n\n/**\n * Options for {@link GyroControl}\n * @ko {@link GyroControl}용 옵션들\n * @since 4.0.0\n */\nexport interface GyroControlOptions {\n /**\n * @copy GyroControl#ignoreRoll\n */\n ignoreRoll: boolean;\n}\n\nexport type GyroControlEvents = ControlEvents;\n\n/**\n * Camera's rotation control by gyroscope\n * @ko 자이로스코프를 이용한 회전 컨트롤\n * @since 4.0.0\n */\nclass GyroControl extends Component implements CameraControl {\n // Options\n private _ignoreRoll: GyroControlOptions[\"ignoreRoll\"];\n\n // Internal values\n private _enableBlocked: boolean;\n private _input: GyroInput;\n\n /**\n * @copy CameraControl#enabled\n */\n public get enabled() { return this._input.enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * @copy CameraControl#animating\n */\n public get animating() {\n return this._input.enabled && this._input.orientationUpdated;\n }\n\n /**\n * When `true`, ignore gyroscope's roll(z-axis rotation) value.\n * :::caution\n * Setting `false` will ignore camera's range limit.\n * Options like {@link View360Options#yawRange}, {@link View360Options#pitchRange} are ignored, and {@link CylinderProjection} also can't force it's camera range limit.\n * :::\n * @ko `true`일 경우 자이로스코프 입력의 roll(z축 회전)값을 무시합니다.\n * :::caution\n * 이 값을 `false`로 설정할 경우 카메라 범위 제약을 무시합니다.\n * {@link View360Options#yawRange}, {@link View360Options#pitchRange}와 같은 값은 무시되며, {@link CylinderProjection} 사용시에도 범위를 벗어날 수 있습니다.\n * :::\n * @default true\n * @since 4.0.0\n */\n public get ignoreRoll() { return this._ignoreRoll; }\n public set ignoreRoll(val: GyroControlOptions[\"ignoreRoll\"]) { this._ignoreRoll = val; }\n\n /**\n * Return availability of the gyroscope.\n * :::caution\n * This will always return false until user permission under environments like iOS which requires user permission when using gyroscope.\n * :::\n * @ko 자이로스코프 사용 가능 여부를 반환합니다.\n * :::caution\n * iOS와 같이 GyroScope 사용시 사용자 Permission을 요구하는 환경에서는 사용자 Permission을 받기 전까지 항상 `false`입니다.\n * :::\n * @example\n * ```ts\n * const gyroAvailable = await GyroControl.isAvailable();\n * ```\n */\n public static async isAvailable(): Promise {\n if (!DeviceMotionEvent) {\n return false;\n }\n\n let onDeviceMotionChange: (evt: DeviceMotionEvent) => void;\n\n const listenDeviceMotion = () => new Promise(res => {\n onDeviceMotionChange = (evt: DeviceMotionEvent) => {\n res(evt.rotationRate && evt.rotationRate.alpha != null);\n };\n\n window.addEventListener(BROWSER.EVENTS.DEVICE_MOTION, onDeviceMotionChange);\n });\n\n const timeout = () => new Promise(res => {\n setTimeout(() => res(false), 1000);\n });\n\n return Promise.race([listenDeviceMotion(), timeout()])\n .then((available: boolean) => {\n window.removeEventListener(BROWSER.EVENTS.DEVICE_MOTION, onDeviceMotionChange);\n\n return available;\n });\n }\n\n /**\n * Request user permission for gyroscope sensor.\n * This can be used in environments like iOS which requires user permission when using gyroscope sensors.\n * @ko 사용자의 sensor permission 취득을 요청합니다.\n * iOS와 같이 gyroscope 사용시 사용자 Permission을 요구하는 환경에서 사용 가능합니다.\n * @returns Whether the permission is granted {@ko 사용자 permission 취득 여부}\n */\n public static async requestSensorPermission(): Promise {\n // Request sensor permission, on iOS13+\n if (sensorCanBeEnabledIOS()) {\n return (DeviceMotionEvent as typeof DeviceMotionEvent & {\n requestPermission: () => Promise;\n }).requestPermission().then(permissionState => {\n return permissionState === \"granted\";\n }).catch(() => false);\n }\n\n return true;\n }\n\n /**\n * Create new GyroControl instance\n * @ko GyroControl의 인스턴스를 생성합니다.\n * @param enableBlocked - Whether to disable control on init {@ko 초기화 과정에서 컨트롤 활성화 여부}\n * @param options - Options for control {@ko 컨트롤 옵션들}\n */\n public constructor(enableBlocked: boolean, {\n ignoreRoll = true\n }: Partial = {}) {\n super();\n\n this._enableBlocked = enableBlocked;\n this._ignoreRoll = ignoreRoll;\n this._input = new GyroInput();\n }\n\n /**\n * @copy CameraControl#destroy\n */\n public destroy(): void {\n this.disable();\n this._input.off();\n this.off();\n }\n\n /**\n * @hidden\n */\n public update(camera: Camera, yaw: Motion, pitch: Motion, zoom: number) {\n if (!this._ignoreRoll) {\n this._updateQuaternion(camera, zoom);\n } else {\n this._updateYawPitch(camera, yaw, pitch, zoom);\n }\n }\n\n /**\n * @copy CameraControl#enable\n */\n public enable(): void {\n if (this._input.enabled) return;\n\n this._input.enable();\n this._enableBlocked = false;\n this.trigger(CONTROL_EVENTS.ENABLE, { control: this, updateCursor: false });\n }\n\n /**\n * @copy CameraControl#disable\n */\n public disable(): void {\n if (!this._input.enabled) return;\n\n this._input.disable();\n this.trigger(CONTROL_EVENTS.DISABLE, { updateCursor: false });\n }\n\n /**\n * @copy CameraControl#sync\n */\n public sync(): void {} // eslint-disable-line @typescript-eslint/no-empty-function\n\n private _updateYawPitch(camera: Camera, yaw: Motion, pitch: Motion, zoom: number) {\n const input = this._input;\n if (!input.enabled) return;\n\n const {\n yaw: yawDelta,\n pitch: pitchDelta\n } = input.collectDelta();\n\n yaw.add(yawDelta);\n pitch.add(pitchDelta);\n\n camera.lookAt({\n yaw: yaw.val,\n pitch: pitch.val,\n zoom\n });\n }\n\n private _updateQuaternion(camera: Camera, zoom: number) {\n const input = this._input;\n if (!input.enabled) return;\n\n input.update();\n camera.rotate(input.quaternion, zoom);\n }\n}\n\nexport default GyroControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport CameraControl from \"./CameraControl\";\nimport RotateControl, { RotateControlEvents, RotateControlOptions } from \"./RotateControl\";\nimport ZoomControl, { ZoomControlOptions } from \"./ZoomControl\";\nimport GyroControl, { GyroControlOptions } from \"./GyroControl\";\nimport Camera from \"../core/Camera\";\nimport CameraAnimation from \"../core/CameraAnimation\";\nimport * as BROWSER from \"../const/browser\";\nimport { CAMERA_EVENTS, CONTROL_EVENTS } from \"../const/internal\";\nimport { ValueOf } from \"../type/utils\";\nimport { getObjectOption, hfovToZoom } from \"../utils\";\n\n/**\n * Options for {@link PanoControl}\n * @ko {@link PanoControl}용 옵션들\n * @since 4.0.0\n */\nexport interface PanoControlOptions {\n /**\n * @copy View360#useGrabCursor\n */\n useGrabCursor: boolean;\n /**\n * @copy View360#scrollable\n */\n scrollable: boolean;\n /**\n * @copy View360#wheelScrollable\n */\n wheelScrollable: boolean;\n /**\n * @copy View360#disableContextMenu\n */\n disableContextMenu: boolean;\n /**\n * Options for {@link RotateControl}.\n * `false` to disable rotation.\n * @ko {@link RotateControl}용 옵션들.\n * `false`일 경우 회전이 비활성화됩니다.\n * @since 4.0.0\n */\n rotate: boolean | Partial;\n /**\n * Options for {@link ZoomControl}.\n * `false` to disable zoom.\n * @ko {@link ZoomControl}용 옵션들.\n * `false`일 경우 줌이 비활성화됩니다.\n * @since 4.0.0\n */\n zoom: boolean | Partial;\n /**\n * Options for {@link GyroControl}.\n * `false` to disable gyroscope control.\n * @ko {@link GyroControl}용 옵션들.\n * `false`일 경우 자이로스코프를 통한 컨트롤이 비활성화됩니다.\n * @since 4.0.0\n */\n gyro: boolean | Partial;\n}\n\n/**\n * Panorama control for View360\n * @ko View360용 파노라마 컨트롤\n * @since 4.0.0\n */\nclass PanoControl {\n // Options\n private _useGrabCursor: PanoControlOptions[\"useGrabCursor\"];\n private _disableContextMenu: PanoControlOptions[\"disableContextMenu\"];\n\n // Internal Values\n private _camera: Camera;\n private _controlEl: HTMLElement;\n private _rotateControl: RotateControl;\n private _zoomControl: ZoomControl;\n private _gyroControl: GyroControl;\n private _ignoreZoomScale: boolean;\n private _enabled: boolean;\n\n /**\n * @copy View360#useGrabCursor\n */\n public get useGrabCursor() { return this._useGrabCursor; }\n public set useGrabCursor(val: PanoControlOptions[\"useGrabCursor\"]) {\n if (val === this._useGrabCursor) return;\n\n this._useGrabCursor = val;\n\n if (val && this._enabled) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n } else if (!val) {\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n }\n\n /**\n * @copy View360#disableContextMenu\n */\n public get disableContextMenu() { return this._disableContextMenu; }\n public set disableContextMenu(val: PanoControlOptions[\"disableContextMenu\"]) {\n if (val === this._disableContextMenu) return;\n\n this._disableContextMenu = val;\n\n if (val && this._enabled) {\n this._blockContextMenu();\n } else if (!val) {\n this._restoreContextMenu();\n }\n }\n\n /**\n * @copy View360#disableContextMenu\n */\n public get scrollable() { return this._rotateControl.scrollable; }\n public set scrollable(val: PanoControlOptions[\"scrollable\"]) { this._rotateControl.scrollable = val; }\n /**\n * @copy View360#disableContextMenu\n */\n public get wheelScrollable() { return this._zoomControl.scrollable; }\n public set wheelScrollable(val: PanoControlOptions[\"wheelScrollable\"]) { this._zoomControl.scrollable = val; }\n /**\n * When `true`, disables rotation slow-down by zoom-value.\n * @ko `true`일 경우 줌 된 정도에 따라 회전속도를 늦추는 동작을 비활성화합니다.\n * @since 4.0.0\n */\n public get ignoreZoomScale() { return this._ignoreZoomScale; }\n public set ignoreZoomScale(val: boolean) { this._ignoreZoomScale = val; }\n\n /**\n * Whether the control is enabled or not\n * @ko 컨트롤 활성화 여부를 가리키는 값\n * @readonly\n * @since 4.0.0\n */\n public get enabled() { return this._enabled; }\n /**\n * @copy View360#rotate\n */\n public get rotate() { return this._rotateControl; }\n /**\n * @copy View360#zoom\n */\n public get zoom() { return this._zoomControl; }\n /**\n * @copy View360#gyro\n */\n public get gyro() { return this._gyroControl; }\n\n /**\n * Whether one of the controls is animating at the moment\n * @ko 현재 컨트롤 중 하나라도 동작중인지 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get animating() {\n return this._rotateControl.animating\n || this._zoomControl.animating\n || this._gyroControl.animating;\n }\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param element - Canvas element {@ko 캔버스 엘리먼트}\n * @param camera - Camera instance {@ko Camera 인스턴스}\n * @param options - Options for PanoControl {@ko PanoControl 옵션들}\n */\n public constructor(element: HTMLElement, camera: Camera, {\n useGrabCursor,\n scrollable,\n wheelScrollable,\n disableContextMenu,\n rotate,\n zoom,\n gyro\n }: PanoControlOptions) {\n // Bind Options\n this._useGrabCursor = useGrabCursor;\n this._disableContextMenu = disableContextMenu;\n\n // Set internal values\n this._camera = camera;\n this._controlEl = element;\n this._ignoreZoomScale = false;\n this._enabled = false;\n\n this._rotateControl = new RotateControl(element, !rotate, getObjectOption(rotate));\n this._zoomControl = new ZoomControl(element, !zoom, getObjectOption(zoom));\n this._gyroControl = new GyroControl(!gyro, getObjectOption(gyro));\n\n this._rotateControl.scrollable = scrollable;\n this._zoomControl.scrollable = wheelScrollable;\n\n this._bindEvents();\n }\n\n /**\n * Destroy the instance and remove all event listeners attached.\n * This also will reset CSS cursor to initial.\n * @ko 인스턴스를 삭제하고 부착된 모든 이벤트 리스너를 제거합니다.\n * 또한, 캔버스에 적용된 CSS cursor도 제거합니다.\n * @since 4.0.0\n */\n public destroy(): void {\n this.disable();\n this._rotateControl.destroy();\n this._zoomControl.destroy();\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n\n /**\n * Resize control to match target size.\n * @ko 컨트롤이 내부에 캐시하고 있는 크기값을 갱신합니다.\n * @param width New width {@ko 변경된 너비}\n * @param height New height {@ko 변경된 높이}\n * @since 4.0.0\n */\n public resize(width: number, height: number): void {\n const camera = this._camera;\n\n this._rotateControl.resize(camera.fov, camera.aspect, width, height);\n }\n\n /**\n * Enable this control and add event listeners.\n * @ko 컨트롤을 활성화하고 이벤트 리스너들을 추가합니다.\n * @since 4.0.0\n */\n public async enable(): Promise {\n if (this._enabled) return;\n\n if (!this._rotateControl.enableBlocked) {\n this._rotateControl.enable();\n }\n\n if (!this._zoomControl.enableBlocked) {\n this._zoomControl.enable();\n }\n\n if (!this._gyroControl.enableBlocked) {\n if (await GyroControl.isAvailable()) {\n this._gyroControl.enable();\n }\n }\n\n this.sync();\n\n if (this._disableContextMenu) {\n this._blockContextMenu();\n }\n\n this._enabled = true;\n }\n\n /**\n * Disable this control and remove all event listeners\n * @ko 컨트롤을 비활성화하고 모든 이벤트 리스너들을 제거합니다.\n * @since 4.0.0\n */\n public disable(): void {\n if (!this._enabled) return;\n\n this._rotateControl.disable();\n this._zoomControl.disable();\n this._gyroControl.disable();\n\n this._restoreContextMenu();\n\n this._enabled = false;\n }\n\n /**\n * Update control by given deltaTime\n * @ko 컨트롤을 주어진 시간만큼 업데이트합니다.\n * @param delta Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n * @internal\n */\n public update(delta: number): void {\n const camera = this._camera;\n const rotateControl = this._rotateControl;\n const zoomControl = this._zoomControl;\n const gyroControl = this._gyroControl;\n\n zoomControl.update(delta);\n const zoom = hfovToZoom(camera.fov, zoomControl.zoom);\n\n // Slow down rotation on zoom-in\n const zoomScale = this._ignoreZoomScale ? 1 : Math.max(zoom, 1);\n rotateControl.setZoomScale(zoomScale);\n rotateControl.updateRange(camera, zoom);\n rotateControl.update(delta);\n\n const yaw = rotateControl.yaw;\n const pitch = rotateControl.pitch;\n\n if (gyroControl.enabled) {\n gyroControl.update(camera, yaw, pitch, zoom);\n } else {\n camera.lookAt({\n yaw: yaw.val,\n pitch: pitch.val,\n zoom\n });\n }\n }\n\n /**\n * Synchronize this control's state to current camera state\n * @ko 컨트롤을 카메라의 현재 상태와 동기화합니다.\n * @since 4.0.0\n */\n public sync(): void {\n const camera = this._camera;\n\n this._zoomControl.sync(camera);\n this._rotateControl.sync(camera);\n }\n\n private _blockContextMenu() {\n const el = this._controlEl;\n\n el.addEventListener(BROWSER.EVENTS.CONTEXT_MENU, this._preventContextMenu);\n }\n\n private _restoreContextMenu() {\n const el = this._controlEl;\n\n el.removeEventListener(BROWSER.EVENTS.CONTEXT_MENU, this._preventContextMenu);\n }\n\n private _preventContextMenu = (evt: MouseEvent) => {\n evt.preventDefault();\n };\n\n private _setCursor(newCursor: ValueOf) {\n if (!this._useGrabCursor && newCursor !== BROWSER.CURSOR.NONE) return;\n\n const targetEl = this._controlEl;\n targetEl.style.cursor = newCursor;\n }\n\n private _bindEvents() {\n const rotateControl = this._rotateControl;\n const zoomControl = this._zoomControl;\n\n rotateControl.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n rotateControl.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n rotateControl.on(CONTROL_EVENTS.ENABLE, this._onEnable);\n rotateControl.on(CONTROL_EVENTS.DISABLE, this._onDisable);\n zoomControl.on(CONTROL_EVENTS.ENABLE, this._onEnable);\n zoomControl.on(CONTROL_EVENTS.DISABLE, this._onDisable);\n this._camera.on(CAMERA_EVENTS.ANIMATION_END, this._onCameraAnimationEnd);\n }\n\n private _onInputStart = (evt: RotateControlEvents[typeof CONTROL_EVENTS.INPUT_START]) => {\n if (this._useGrabCursor && !evt.isKeyboard) {\n this._setCursor(BROWSER.CURSOR.GRABBING);\n }\n };\n\n private _onInputEnd = (evt: RotateControlEvents[typeof CONTROL_EVENTS.INPUT_END]) => {\n if (this._useGrabCursor && !evt.isKeyboard) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n }\n };\n\n private _onEnable = ({\n control,\n updateCursor\n }: {\n control: CameraControl;\n updateCursor: boolean;\n }) => {\n if (updateCursor && this._useGrabCursor) {\n this._setCursor(BROWSER.CURSOR.GRAB);\n }\n\n control.sync(this._camera);\n };\n\n private _onDisable = ({\n updateCursor\n }: {\n updateCursor: boolean\n }) => {\n if (updateCursor) {\n this._setCursor(BROWSER.CURSOR.NONE);\n }\n };\n\n private _onCameraAnimationEnd = ({ animation }: { animation: CameraAnimation }) => {\n animation.getFinishPromise().then(() => {\n this.sync();\n });\n };\n}\n\nexport default PanoControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport TextureVideo from \"./TextureVideo\";\nimport TextureCube from \"./TextureCube\";\n\n/**\n * @hidden\n */\nabstract class Texture {\n public width: number;\n public height: number;\n public flipY: boolean;\n public wrapS: number;\n public wrapT: number;\n\n public constructor({\n width,\n height,\n flipY\n }: {\n width: number;\n height: number;\n flipY: boolean;\n }) {\n this.width = width;\n this.height = height;\n this.flipY = flipY;\n this.wrapS = WebGLRenderingContext.CLAMP_TO_EDGE;\n this.wrapT = WebGLRenderingContext.CLAMP_TO_EDGE;\n }\n\n public destroy() {\n // DO_NOTHING\n }\n\n public isVideo(): this is TextureVideo {\n return false;\n }\n\n public isCube(): this is TextureCube {\n return false;\n }\n}\n\nexport default Texture;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture from \"./Texture\";\n\n/**\n * @hidden\n */\nclass Texture2D extends Texture {\n public source: Exclude;\n\n public constructor({\n source,\n width,\n height,\n flipY\n }: {\n source: Exclude;\n width: number;\n height: number;\n flipY: boolean;\n }) {\n super({\n width,\n height,\n flipY\n });\n\n this.source = source;\n }\n}\n\nexport default Texture2D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"./Texture2D\";\n\n/**\n * @hidden\n */\nclass TextureVideo extends Texture2D {\n public source: HTMLVideoElement;\n\n public destroy() {\n const video = this.source;\n\n video.pause();\n video.removeAttribute(\"src\");\n video.load();\n }\n\n public isVideo(): this is TextureVideo { return true; }\n\n public isPaused() {\n const video = this.source;\n\n return video.paused || video.ended || video.readyState <= 2;\n }\n\n public hasAudio() {\n const video = this.source as any;\n\n if (video.audioTracks) {\n return video.audioTracks.length > 0;\n }\n\n if (video.webkitAudioDecodedByteCount != null) {\n return video.webkitAudioDecodedByteCount > 0;\n }\n\n if (video.mozHasAudio != null) {\n return video.mozHasAudio;\n }\n\n // We don't know whether the video has audio or not, return true\n return true;\n }\n}\n\nexport default TextureVideo;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture from \"./Texture\";\n\n/**\n * @hidden\n */\nclass TextureCube extends Texture {\n public sources: TexImageSource[];\n\n public constructor({\n sources,\n width,\n height,\n flipY\n }: {\n sources: TexImageSource[];\n width: number;\n height: number;\n flipY: boolean;\n }) {\n super({\n width,\n height,\n flipY\n });\n\n this.sources = sources;\n }\n\n public isCube(): this is TextureCube { return true; }\n}\n\nexport default TextureCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ImReady from \"@egjs/imready\";\nimport Texture from \"../texture/Texture\";\nimport Texture2D from \"../texture/Texture2D\";\nimport TextureVideo from \"../texture/TextureVideo\";\nimport TextureCube from \"../texture/TextureCube\";\nimport { getObjectOption, isString } from \"../utils\";\nimport { VideoConfig } from \"../type/external\";\nimport { ProjectionOptions } from \"../projection/Projection\";\n\n/**\n * @hidden\n */\nclass TextureLoader {\n private _loadChecker: ImReady;\n\n constructor() {\n this._loadChecker = new ImReady();\n }\n\n public async load(src: ProjectionOptions[\"src\"], video: ProjectionOptions[\"video\"]): Promise {\n if (video) {\n return this.loadVideo(src, getObjectOption(video));\n } else {\n if (Array.isArray(src) && src.length > 1) {\n return this.loadCubeImage(src);\n } else {\n const imgSrc = Array.isArray(src) ? src[0] : src;\n return this.loadImage(imgSrc);\n }\n }\n }\n\n public async loadImage(src: string | HTMLElement): Promise {\n const images = this._toImageArray(src);\n\n return this._load(images, resolve => {\n const image = images[0];\n\n resolve(new Texture2D({\n source: image,\n width: image.naturalWidth,\n height: image.naturalHeight,\n flipY: true\n }));\n });\n }\n\n public async loadCubeImage(src: Array): Promise {\n const images = this._toImageArray(src);\n\n return this._load(images, resolve => {\n resolve(new TextureCube({\n sources: images,\n width: images[0].naturalWidth,\n height: images[0].naturalHeight,\n flipY: false\n }));\n });\n }\n\n public async loadVideo(src: ProjectionOptions[\"src\"], videoConfig: Partial): Promise {\n const config: VideoConfig = {\n autoplay: true,\n muted: true,\n loop: false,\n volume: 1,\n ...videoConfig,\n };\n const video = this._toVideoElement(src, config);\n\n return this._load([video], resolve => {\n const { autoplay, muted } = config;\n\n video.currentTime = 0;\n if (autoplay && muted) {\n video.play().catch(() => void 0);\n }\n\n resolve(new TextureVideo({\n source: video,\n width: video.videoWidth,\n height: video.videoHeight,\n flipY: true\n }));\n });\n }\n\n private _load(content: HTMLElement[], onLoad: (resolve: (value: T) => void) => void): Promise {\n const loader = this._loadChecker;\n\n return new Promise((resolve, reject) => {\n loader.once(\"ready\", evt => {\n if (evt.errorCount > 0) return;\n\n onLoad(resolve);\n });\n\n loader.once(\"error\", reject);\n loader.check(content);\n });\n }\n\n private _toImageArray(src: ProjectionOptions[\"src\"]): HTMLImageElement[] {\n const srcs = Array.isArray(src) ? src : [src];\n\n return srcs.map(source => {\n if (isString(source)) {\n const imgEl = new Image();\n\n imgEl.crossOrigin = \"anonymous\";\n imgEl.src = source;\n\n return imgEl;\n } else {\n return source as HTMLImageElement;\n }\n });\n }\n\n private _toVideoElement(src: ProjectionOptions[\"src\"], {\n muted,\n loop,\n volume\n }: VideoConfig): HTMLVideoElement {\n if (src instanceof HTMLVideoElement) {\n return src;\n }\n\n const video = document.createElement(\"video\");\n\n video.crossOrigin = \"anonymous\";\n video.playsInline = true;\n video.setAttribute(\"webkit-playsinline\", \"\");\n video.muted = muted;\n video.volume = volume;\n video.loop = loop;\n\n if (Array.isArray(src)) {\n src.forEach(source => this._appendSourceElement(video, source));\n } else {\n this._appendSourceElement(video, src);\n }\n\n const sourceCount = video.querySelectorAll(\"source\").length;\n if (sourceCount > 0 && video.readyState < 1) {\n video.load();\n }\n\n return video;\n }\n\n private _appendSourceElement(video: HTMLMediaElement, src: string | HTMLElement) {\n if (src instanceof HTMLSourceElement) {\n return src;\n }\n\n const sourceEl = document.createElement(\"source\");\n sourceEl.src = src as string;\n video.appendChild(sourceEl);\n }\n}\n\nexport default TextureLoader;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n\n/**\n * @internal\n */\nclass FrameAnimator {\n public maxDeltaTime: number;\n\n private _context: Window | XRSession;\n private _rafId: number;\n private _rafTimer: number;\n private _lastUpdateTime: number;\n\n /** */\n public constructor(maxDeltaTime: number, context: Window | XRSession = window) {\n this.maxDeltaTime = maxDeltaTime;\n\n this._context = context;\n this._rafId = -1;\n this._rafTimer = -1;\n this._lastUpdateTime = -1;\n }\n\n public start(callback: (delta: number, ...args: any[]) => any) {\n const context = this._context;\n\n // No context / callback set\n if (!context || !callback) return;\n\n // Animation already started\n if (this._rafId >= 0 || this._rafTimer >= 0) return;\n\n const loop = (_time: number, frame?: XRFrame) => {\n const time = Date.now();\n const delta = Math.min(time - this._lastUpdateTime, this.maxDeltaTime * 1000);\n\n callback(delta, frame);\n\n this._lastUpdateTime = time;\n this._rafId = context.requestAnimationFrame(loop);\n };\n\n this._lastUpdateTime = Date.now();\n this._rafId = context.requestAnimationFrame(loop);\n }\n\n public stop() {\n if (this._rafId >= 0) {\n this._context.cancelAnimationFrame(this._rafId);\n }\n\n if (this._rafTimer >= 0) {\n clearTimeout(this._rafTimer);\n }\n\n this._rafId = -1;\n this._rafTimer = -1;\n }\n\n public changeContext(context: Window | XRSession) {\n this.stop();\n this._context = context;\n }\n}\n\nexport default FrameAnimator;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport * as BROWSER from \"../const/browser\";\n\n/**\n * Automatic resizer that uses both ResizeObserver and window resize event\n */\nclass AutoResizer {\n private _enabled: boolean;\n private _resizeObserver: ResizeObserver | null;\n private _useResizeObserver: boolean;\n private _onResize: () => any;\n\n public get useResizeObserver() { return this._useResizeObserver; }\n\n /**\n * Returns whether AutoResizer is enabled\n */\n public get enabled() { return this._enabled; }\n\n /** */\n public constructor(useResizeObserver: boolean, onResize: () => any) {\n this._useResizeObserver = useResizeObserver;\n\n this._enabled = false;\n this._resizeObserver = null;\n this._onResize = onResize;\n }\n\n /**\n * Enable resizer\n */\n public enable(element: HTMLElement): this {\n if (this._enabled) {\n this.disable();\n }\n\n if (this._useResizeObserver && !!window.ResizeObserver) {\n const bbox = element.getBoundingClientRect();\n const resizeImmediate = bbox.width !== 0 || bbox.height !== 0;\n\n const resizeObserver = new ResizeObserver(resizeImmediate ? this._skipFirstResize : this._onResize);\n\n resizeObserver.observe(element);\n\n this._resizeObserver = resizeObserver;\n } else {\n window.addEventListener(BROWSER.EVENTS.RESIZE, this._onResize);\n }\n\n this._enabled = true;\n\n return this;\n }\n\n /**\n * Disable resizer\n */\n public disable(): this {\n if (!this._enabled) return this;\n\n const resizeObserver = this._resizeObserver;\n if (resizeObserver) {\n resizeObserver.disconnect();\n this._resizeObserver = null;\n } else {\n window.removeEventListener(BROWSER.EVENTS.RESIZE, this._onResize);\n }\n\n this._enabled = false;\n\n return this;\n }\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n private _skipFirstResize = (() => {\n let isFirstResize = true;\n\n return (() => {\n if (isFirstResize) {\n isFirstResize = false;\n\n return;\n }\n this._onResize();\n });\n })();\n}\n\nexport default AutoResizer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Camera from \"./Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport View360 from \"../View360\";\nimport * as BROWSER from \"../const/browser\";\nimport { CONTROL_EVENTS } from \"../const/internal\";\nimport { circulate, getObjectOption } from \"../utils\";\n\n/**\n * Options for {@link Autoplay}\n * @ko {@link Autoplay}용 옵션들\n * @since 4.0.0\n */\nexport interface AutoplayOptions {\n /**\n * @copy Autoplay#delay\n */\n delay: number;\n /**\n * @copy Autoplay#delayOnMouseLeave\n */\n delayOnMouseLeave: number;\n /**\n * @copy Autoplay#speed\n */\n speed: number;\n /**\n * @copy Autoplay#pauseOnHover\n */\n pauseOnHover: boolean;\n /**\n * @copy Autoplay#canInterrupt\n */\n canInterrupt: boolean;\n /**\n * @copy Autoplay#disableOnInterrupt\n */\n disableOnInterrupt: boolean;\n}\n\n/**\n * A manager class for autoplay feature.\n * @ko Autoplay 기능의 매니저 클래스.\n * @since 4.0.0\n */\nclass Autoplay {\n // Options\n private _delay: number;\n private _delayOnMouseLeave: number;\n private _speed: number;\n private _pauseOnHover: boolean;\n private _canInterrupt: boolean;\n private _disableOnInterrupt: boolean;\n\n // Internal values\n private _enableBlocked: boolean;\n private _camera: Camera;\n private _control: PanoControl;\n private _element: HTMLElement;\n private _enabled: boolean;\n private _interrupted: boolean;\n private _interruptionTimer: number;\n private _hovering: boolean;\n\n /**\n * Whether autoplay is enabled or not\n * @ko 자동재생 활성화 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get enabled() { return this._enabled; }\n /**\n * @hidden\n */\n public get enableBlocked() { return this._enableBlocked; }\n /**\n * Whether autoplay is updating the camera at the moment\n * @ko 현재 자동재생이 동작중인지 여부를 나타내는 값\n * @readonly\n * @since 4.0.0\n */\n public get playing() {\n return this._enabled && !this._interrupted;\n }\n\n /**\n * Reactivation delay after mouse input in milisecond.\n * @ko 재활성화되기까지의 시간 (밀리초 단위)\n * @default 2000\n * @since 4.0.0\n */\n public get delay() { return this._delay; }\n public set delay(val: number) { this._delay = val; }\n\n /**\n * Reactivation delay after mouse leave when using {@link AutoplayOptions#pauseOnHover}\n * @ko {@link AutoplayOptions#pauseOnHover} 사용시 마우스가 캔버스 영역을 떠난 뒤 자동재생이 다시 활성화되기까지의 시간\n * @default 0\n * @since 4.0.0\n */\n public get delayOnMouseLeave() { return this._delayOnMouseLeave; }\n public set delayOnMouseLeave(val: number) { this._delayOnMouseLeave = val; }\n\n /**\n * Y-axis(yaw) rotation speed\n * @ko Y-축 회전(yaw)의 속도\n * @default 1\n * @since 4.0.0\n */\n public get speed() { return this._speed; }\n public set speed(val: number) { this._speed = val; }\n\n /**\n * Whether to pause rotation on mouse hover\n * @ko 마우스가 캔버스 영역에 들어왔을 때 자동재생을 정지할지 여부\n * @default false\n * @since 4.0.0\n */\n public get pauseOnHover() { return this._pauseOnHover; }\n public set pauseOnHover(val: boolean) { this._pauseOnHover = val; }\n\n /**\n * Whether user can interrupt the rotation with click/wheel input\n * @ko 클릭이나 휠같은 사용자 인터랙션시 자동재생을 멈출지 여부\n * @default true\n * @since 4.0.0\n */\n public get canInterrupt() { return this._canInterrupt; }\n public set canInterrupt(val: boolean) { this._canInterrupt = val; }\n\n /**\n * Whether to disable autoplay on user interrupt\n * @ko 사용자 동작에 의해 자동재생이 정지할 때, {@link Autoplay#disable}을 호출하여 자동재생을 영구히 정지할지 여부\n * @default false\n * @since 4.0.0\n */\n public get disableOnInterrupt() { return this._disableOnInterrupt; }\n public set disableOnInterrupt(val: boolean) { this._disableOnInterrupt = val; }\n\n /**\n * Create new AutoPlayer instance\n * @param camera - Instance of the {@link Camera} {@ko Camera의 인스턴스}\n * @param element - Canvas element {@ko 캔버스 엘리먼트}\n * @param options - Autoplay options {@ko 자동재생 옵션들}\n * @since 4.0.0\n */\n public constructor(viewer: View360, element: HTMLElement, options: boolean | Partial) {\n this._camera = viewer.camera;\n this._control = viewer.control;\n this._element = element;\n\n this._enabled = false;\n this._interrupted = false;\n this._interruptionTimer = -1;\n this._hovering = false;\n\n const {\n delay = 2000,\n delayOnMouseLeave = 0,\n speed = 1,\n pauseOnHover = false,\n canInterrupt = true,\n disableOnInterrupt = false\n } = getObjectOption(options);\n\n this._enableBlocked = !options;\n this._delay = delay;\n this._delayOnMouseLeave = delayOnMouseLeave;\n this._speed = speed;\n this._pauseOnHover = pauseOnHover;\n this._canInterrupt = canInterrupt;\n this._disableOnInterrupt = disableOnInterrupt;\n }\n\n /**\n * Destroy the instance and remove all event listeners attached\n * @ko 인스턴스를 제거하고 연결된 모든 이벤트 핸들러를 삭제합니다.\n * @since 4.0.0\n */\n public destroy(): void {\n this.disable();\n }\n\n /**\n * Rotate camera by given deltaTime\n * @ko 주어진 deltaTime만큼 카메라를 회전시킵니다.\n * @param deltaTime - Number of milisec to update {@ko 업데이트할 시간, 밀리초 단위}\n * @since 4.0.0\n */\n public update(deltaTime: number): void {\n if (!this._enabled) return;\n if (this._interrupted) {\n if (this._disableOnInterrupt) {\n this.disable();\n }\n\n return;\n }\n\n const camera = this._camera;\n const delta = -this._speed * deltaTime / 100;\n\n camera.yaw = circulate(camera.yaw + delta, 0, 360);\n }\n\n /**\n * Enable autoplay and add event listeners.\n * @ko 자동재생을 활성화하고 이벤트리스너들을 추가합니다.\n * @since 4.0.0\n */\n public enable(): void {\n const control = this._control;\n const element = this._element;\n\n if (this._enabled || control.gyro.enabled) return;\n\n control.rotate.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.rotate.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.zoom.on(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.zoom.on(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.gyro.on(CONTROL_EVENTS.ENABLE, this._onGyroEnable);\n\n element.addEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter, false);\n element.addEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave, false);\n\n this._enabled = true;\n this._enableBlocked = false;\n }\n\n /**\n * Enable autoplay after current `delay` value.\n * @ko 현재의 `delay`값만큼 시간이 지난 다음에 자동재생을 활성화합니다.\n * @since 4.0.0\n */\n public enableAfterDelay() {\n this.enable();\n this._interrupted = true;\n this._setUninterruptedAfterDelay(this._delay);\n }\n\n /**\n * Disable autoplay and remove all event handlers.\n * @ko 자동재생을 비활성화하고 모든 이벤트 핸들러를 제거합니다.\n * @since 4.0.0\n */\n public disable(): void {\n if (!this._enabled) return;\n\n const control = this._control;\n const element = this._element;\n\n control.rotate.off(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.rotate.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.zoom.off(CONTROL_EVENTS.INPUT_START, this._onInputStart);\n control.zoom.off(CONTROL_EVENTS.INPUT_END, this._onInputEnd);\n\n control.gyro.off(CONTROL_EVENTS.ENABLE, this._onGyroEnable);\n\n element.removeEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter, false);\n element.removeEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave, false);\n\n this._enabled = false;\n this._interrupted = false;\n this._hovering = false;\n\n this._clearTimeout();\n }\n\n private _onInputStart = () => {\n if (!this._canInterrupt) return;\n\n this._interrupted = true;\n this._clearTimeout();\n };\n\n private _onInputEnd = () => {\n this._setUninterruptedAfterDelay(this._delay);\n };\n\n private _onGyroEnable = () => {\n this.disable();\n };\n\n private _onMouseEnter = () => {\n if (!this._pauseOnHover) return;\n this._interrupted = true;\n this._hovering = true;\n };\n\n private _onMouseLeave = () => {\n if (!this._pauseOnHover) return;\n this._hovering = false;\n this._setUninterruptedAfterDelay(this._delayOnMouseLeave);\n };\n\n private _setUninterruptedAfterDelay(delay: number): void {\n if (this._hovering) return;\n\n this._clearTimeout();\n\n if (delay > 0) {\n this._interruptionTimer = window.setTimeout(() => {\n this._interrupted = false;\n this._interruptionTimer = -1;\n }, delay);\n } else {\n this._interrupted = false;\n this._interruptionTimer = -1;\n }\n }\n\n private _clearTimeout(): void {\n if (this._interruptionTimer >= 0) {\n window.clearTimeout(this._interruptionTimer);\n this._interruptionTimer = -1;\n }\n }\n}\n\nexport default Autoplay;\n","import { mat4 } from \"gl-matrix\";\nimport Component from \"@egjs/component\";\nimport WebGLContext from \"./WebGLContext\";\nimport GyroControl from \"../control/GyroControl\";\nimport * as BROWSER from \"../const/browser\";\nimport { SESSION_VR, XR_REFERENCE_SPACE } from \"../const/internal\";\nimport { EVENTS } from \"../const/external\";\n\ninterface XRSessionOptions extends XRSessionInit {\n [key: string]: any;\n}\n\n/**\n * WebXR manager class\n * @ko WebXR 매니저 클래스\n * @since 4.0.0\n */\nclass XRManager extends Component<{\n /**\n * An event that fires on entering VR session\n * @ko VR 세션 진입시에 트리거되는 이벤트\n * @eventName vrStart\n * @eventOf XRManager\n * @version 4.0.0\n */\n [EVENTS.VR_START]: {\n session: XRSession;\n };\n /**\n * An event that fires on exiting VR session\n * @ko VR 세션에서 나갈 때 트리거되는 이벤트\n * @eventName vrEnd\n * @eventOf XRManager\n * @version 4.0.0\n */\n [EVENTS.VR_END]: void;\n}> {\n private _ctx: WebGLContext;\n private _xrSession: XRSession | null;\n private _xrRefSpace: XRReferenceSpace | null;\n private _options: XRSessionOptions;\n\n /**\n * Create new instance.\n * 새 인스턴스를 생성합니다.\n * @param ctx - Instance of WebGL context helper {@ko WebGL 콘텍스트 헬퍼의 인스턴스}\n * @param options - Options {@ko 옵션들}\n */\n public constructor(ctx: WebGLContext, options: XRSessionOptions = {}) {\n super();\n\n this._xrSession = null;\n this._xrRefSpace = null;\n this._ctx = ctx;\n this._options = options;\n }\n\n /**\n * Destroy instance and end XR session if there was any.\n * @ko 인스턴스를 제거하고, XR 세션이 존재할 경우 종료합니다.\n * @since 4.0.0\n */\n public destroy = () => {\n this.exit();\n this.off();\n };\n\n /**\n * Returns WebXR availability.\n * @ko WebXR 사용 가능 여부를 반환합니다.\n * @since 4.0.0\n */\n public async isAvailable(): Promise {\n // eslint-disable-next-line compat/compat\n const xr = window.navigator.xr;\n if (!xr) return false;\n\n return xr.isSessionSupported(SESSION_VR)\n .then(available => {\n return available;\n }).catch(() => {\n return false;\n });\n }\n\n /**\n * Enter VR session\n * @ko VR 세션에 진입합니다.\n * @since 4.0.0\n */\n public async enter() {\n const ctx = this._ctx;\n\n // eslint-disable-next-line compat/compat\n const xr = window.navigator.xr;\n if (!xr) return;\n\n await GyroControl.requestSensorPermission();\n\n const options = {\n ...{\n requiredFeatures: [XR_REFERENCE_SPACE]\n },\n ...this._options\n };\n\n await ctx.makeXRCompatible();\n\n const session = await xr.requestSession(SESSION_VR, options);\n ctx.bindXRLayer(session);\n\n const refSpace = await session.requestReferenceSpace(XR_REFERENCE_SPACE);\n\n this._setSession(session, refSpace);\n\n this.trigger(EVENTS.VR_START, {\n session\n });\n }\n\n /**\n * Exit VR session\n * @ko VR 세션에서 나갑니다.\n * @since 4.0.0\n */\n public exit() {\n const xrSession = this._xrSession;\n\n if (xrSession) {\n xrSession.end()\n .catch(() => void 0);\n }\n\n this._xrSession = null;\n this._xrRefSpace = null;\n }\n\n /**\n * @hidden\n */\n public canRender(frame: XRFrame) {\n const refSpace = this._xrRefSpace;\n\n if (!refSpace) return false;\n\n const pose = frame.getViewerPose(refSpace);\n\n return !!pose;\n }\n\n /**\n * @hidden\n */\n public getEyeParams(frame: XRFrame): Array<{\n viewport: XRViewport;\n vMatrix: mat4;\n pMatrix: mat4;\n }> | null {\n const session = frame.session;\n const pose = frame.getViewerPose(this._xrRefSpace!);\n\n if (!pose) return null;\n\n const glLayer = session.renderState.baseLayer;\n\n if (!glLayer) return null;\n\n return pose.views.map(view => {\n const viewport = glLayer.getViewport(view)!;\n const vMatrix = view.transform.inverse.matrix;\n\n return {\n viewport,\n vMatrix,\n pMatrix: view.projectionMatrix\n };\n });\n }\n\n private _setSession(session: XRSession, refSpace: XRReferenceSpace) {\n this._xrSession = session;\n this._xrRefSpace = refSpace;\n\n session.addEventListener(BROWSER.EVENTS.XR_END, this._onSessionEnd);\n }\n\n private _onSessionEnd = () => {\n this.exit();\n this.trigger(EVENTS.VR_END);\n }\n}\n\nexport default XRManager;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { vec3 } from \"gl-matrix\";\n\n/**\n * Hotspot data\n * @ko 핫스팟 데이터\n * @since 4.0.0\n */\nclass Hotspot {\n /**\n * HTMLElement of the hotspot\n * @ko 핫스팟의 HTMLElement\n * @since 4.0.0\n */\n public readonly element: HTMLElement;\n /**\n * Position to render hotspot\n * @ko 핫스팟을 렌더링할 위치\n * @since 4.0.0\n */\n public readonly position: vec3;\n\n public constructor(element: HTMLElement, position: vec3) {\n this.element = element;\n this.position = position;\n }\n}\n\nexport default Hotspot;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { vec2, vec3 } from \"gl-matrix\";\nimport Hotspot from \"./Hotspot\";\nimport Camera from \"../core/Camera\";\nimport WebGLRenderer from \"../core/WebGLRenderer\";\nimport View360Error from \"../core/View360Error\";\nimport { getNullableElement } from \"../utils\";\nimport ERROR from \"../const/error\";\nimport { DEFAULT_CLASS } from \"../const/external\";\nimport { DEG_TO_RAD } from \"../const/internal\";\n\n/**\n * Options for {@link HotspotRenderer}\n * @ko {@link HotspotRenderer}용 옵션들\n * @since 4.0.0\n */\nexport interface HotspotOptions {\n /**\n * Apply scale for hotspots, makes their size sync with background panorama image.\n * @ko 핫스팟에 스케일을 적용해서 배경 파노라마 이미지의 크기 변화와 동일하게 크기를 조절합니다.\n * @since 4.0.0\n */\n zoom: boolean;\n}\n\n/**\n * Hotspot renderer\n * @ko Hotspot 렌더러\n * @since 4.0.0\n */\nclass HotspotRenderer {\n // Options\n private _zoom: HotspotOptions[\"zoom\"];\n\n // Internal properties\n private _containerEl: HTMLElement | null;\n private _renderer: WebGLRenderer;\n private _hotspots: Hotspot[];\n\n /**\n * Create new instance\n * @ko 새 인스턴스를 생성합니다.\n * @param rootEl - Container element for hotspots {@ko 핫스팟들의 컨테이너 엘리먼트}\n * @param renderer - instance of WebGLRenderer {@ko WebGLRenderer의 인스턴스}\n * @param options - Hotspot options {@ko Hotspot 옵션들 }\n */\n public constructor(rootEl: HTMLElement, renderer: WebGLRenderer, {\n zoom = false\n }: Partial) {\n this._containerEl = getNullableElement(`.${DEFAULT_CLASS.HOTSPOT_CONTAINER}`, rootEl);\n this._renderer = renderer;\n this._hotspots = [];\n\n this._zoom = zoom;\n }\n\n /**\n * Refresh hotspots by collecting hotspot elements from current hotspot root element\n * @ko 현재 핫스팟 루트 엘리먼트 내에서 핫스팟 엘리먼트들을 수집하여 갱신합니다.\n * @throws {ERROR_CODES.INSUFFICIENT_ARGS} if data-position doesn't include all x, y, z values {@ko data-position이 x, y, z좌표를 전부 포함하고 있지 않을 때}\n */\n public refresh() {\n const container = this._containerEl;\n if (!container) return;\n\n const hotspotEls = [].slice.apply(container.querySelectorAll(`.${DEFAULT_CLASS.HOTSPOT}`)) as HTMLElement[];\n this._hotspots = hotspotEls.map(el => this._parseHotspot(el));\n }\n\n /**\n * Render hotspots\n * @ko 핫스팟들을 렌더링합니다.\n * @param camera - Instance of Camera {@ko Camera의 인스턴스}\n */\n public render(camera: Camera) {\n const hotspots = this._hotspots;\n const halfWidth = this._renderer.width * 0.5;\n const halfHeight = this._renderer.height * 0.5;\n const zoom = camera.zoom;\n const centerTransform = \"translate(-50%, -50%)\";\n const zoomTransform = this._zoom ? `scale(${zoom})` : \"\";\n\n hotspots.forEach(hotspot => {\n const position = hotspot.position;\n const relPos = vec3.create();\n\n vec3.copy(relPos, position);\n vec3.transformMat4(relPos, relPos, camera.viewMatrix);\n vec3.transformMat4(relPos, relPos, camera.projectionMatrix);\n\n if (relPos[2] > 1 || relPos[2] < 0) {\n hotspot.element.classList.remove(DEFAULT_CLASS.HOTSPOT_VISIBLE);\n return;\n }\n\n const screenPos = vec2.fromValues(\n relPos[0] * halfWidth + halfWidth,\n -relPos[1] * halfHeight + halfHeight\n );\n\n hotspot.element.classList.add(DEFAULT_CLASS.HOTSPOT_VISIBLE);\n hotspot.element.style.transform = [\n centerTransform,\n `translate(${screenPos[0]}px, ${screenPos[1]}px)`,\n zoomTransform\n ].join(\" \");\n });\n }\n\n private _parseHotspot(element: HTMLElement): Hotspot {\n const yawStr = element.dataset.yaw;\n const pitchStr = element.dataset.pitch;\n const positionStr = element.dataset.position;\n\n if (yawStr || pitchStr) {\n const yaw = yawStr ? parseFloat(yawStr) : 0;\n const pitch = pitchStr ? parseFloat(pitchStr) : 0;\n\n const position = this._yawPitchToVec3(yaw, pitch);\n\n return new Hotspot(element, position);\n } else if (positionStr) {\n const pos: number[] = positionStr.split(\" \").map(val => parseFloat(val));\n if (pos.length < 3) {\n throw new View360Error(ERROR.MESSAGES.INSUFFICIENT_ARGS(positionStr, \"hotspot attribute \\\"data-position\\\"\"), ERROR.CODES.INSUFFICIENT_ARGS);\n }\n\n return new Hotspot(element, vec3.fromValues(pos[0], pos[1], pos[2]));\n } else {\n // Place hotspot at yaw: 0, pitch: 0\n const defaultPos = vec3.fromValues(0, 0, -1);\n\n return new Hotspot(element, defaultPos);\n }\n }\n\n private _yawPitchToVec3(yaw: number, pitch: number) {\n const yawRad = yaw * DEG_TO_RAD;\n const pitchRad = pitch * DEG_TO_RAD;\n const position = vec3.create();\n\n position[1] = Math.sin(pitchRad);\n position[2] = Math.cos(pitchRad);\n\n position[0] = position[2] * Math.sin(-yawRad);\n position[2] = -position[2] * Math.cos(-yawRad);\n\n return position;\n }\n}\n\nexport default HotspotRenderer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"../geometry/Geometry\";\nimport { VAO } from \"../type/internal\";\n\n/**\n * @hidden\n */\nclass VertexArrayObject {\n public readonly obj: VAO | null;\n public readonly geometry: Geometry;\n public readonly buffers: {\n indicies: WebGLBuffer;\n position: WebGLBuffer;\n uv: WebGLBuffer;\n }\n\n public get count() { return this.geometry.indicies.count; }\n\n constructor(obj: VAO | null, geometry: Geometry, buffers: VertexArrayObject[\"buffers\"]) {\n this.obj = obj;\n this.geometry = geometry;\n this.buffers = buffers;\n }\n}\n\nexport default VertexArrayObject;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4 } from \"gl-matrix\";\nimport Uniform from \"../uniform/Uniform\";\nimport Camera from \"./Camera\";\nimport Object3D from \"./Object3D\";\nimport ShaderProgram from \"./ShaderProgram\";\nimport View360Error from \"./View360Error\";\nimport VertexArrayObject from \"./VertexArrayObject\";\nimport VertexData from \"./VertexData\";\nimport Texture from \"../texture/Texture\";\nimport Geometry from \"../geometry/Geometry\";\nimport * as BROWSER from \"../const/browser\";\nimport ERROR from \"../const/error\";\nimport { DEFAULT_CLASS } from \"../const/external\";\nimport { UniformLocations } from \"../type/internal\";\n\n/**\n * @hidden\n */\nclass WebGLContext {\n private _canvas: HTMLCanvasElement;\n private _gl: WebGLRenderingContext | WebGL2RenderingContext;\n private _contextLost: boolean;\n private _maxTextureSize: number;\n private _isWebGL2: boolean;\n private _debug: boolean;\n private _extensions: {\n vao: OES_vertex_array_object | null;\n loseContext: WEBGL_lose_context | null;\n };\n\n public get canvas() { return this._canvas; }\n public get maxTextureSize() { return this._maxTextureSize; }\n public get isWebGL2() { return this._isWebGL2; }\n public get supportVAO() { return this._isWebGL2 || !!this._extensions.vao; }\n public get lost() { return this._contextLost; }\n public get debug() { return this._debug; }\n\n public constructor(canvas: HTMLCanvasElement, debug: boolean) {\n this._canvas = canvas;\n this._contextLost = false;\n this._debug = debug;\n this._extensions = {\n vao: null,\n loseContext: null\n };\n }\n\n public init() {\n const canvas = this._canvas;\n\n const { gl, isWebGL2 } = this._getContext(canvas);\n\n this._gl = gl;\n this._maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n this._isWebGL2 = isWebGL2;\n\n if (!this._isWebGL2) {\n this._extensions.vao = gl.getExtension(\"OES_vertex_array_object\");\n }\n\n this._extensions.loseContext = gl.getExtension(\"WEBGL_lose_context\");\n\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_LOST, this._onContextLost);\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_RESTORED, this._onContextRestore);\n\n // gl.enable(gl.DEPTH_TEST);\n }\n\n public destroy() {\n const gl = this._gl;\n const canvas = this._canvas;\n\n if (gl) {\n // gl is not defined when destroy is called before init\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n }\n\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_LOST, this._onContextLost);\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_RESTORED, this._onContextRestore);\n }\n\n public forceLoseContext() {\n const extension = this._extensions.loseContext;\n\n if (!extension) return;\n\n extension.loseContext();\n }\n\n public forceRestoreContext() {\n const extension = this._extensions.loseContext;\n\n if (!extension) return;\n\n extension.restoreContext();\n }\n\n public clear() {\n const gl = this._gl;\n\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n\n public resize() {\n const gl = this._gl;\n\n gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n }\n\n public viewport(x: number, y: number, width: number, height: number) {\n const gl = this._gl;\n\n gl.viewport(x, y, width, height);\n }\n\n public createVAO(geometry: Geometry, shaderProgram: ShaderProgram) {\n const nativeVAO = this._createNativeVAO();\n\n const vao = new VertexArrayObject(nativeVAO, geometry, {\n indicies: this._createBuffer(),\n position: this._createBuffer(),\n uv: this._createBuffer()\n });\n\n if (nativeVAO) {\n this._bindNativeVAO(nativeVAO);\n this._supplyGeometryData(vao, shaderProgram);\n this._bindNativeVAO(null);\n this._unbindBuffers();\n }\n\n return vao;\n }\n\n public draw(vao: VertexArrayObject, shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n if (vao.obj) {\n this._bindNativeVAO(vao.obj);\n } else {\n this._supplyGeometryData(vao, shaderProgram);\n }\n\n gl.drawElements(gl.TRIANGLES, vao.count, gl.UNSIGNED_SHORT, 0);\n\n if (vao.obj) {\n this._bindNativeVAO(null);\n } else {\n this._unbindBuffers();\n }\n }\n\n public releaseVAO(vao: VertexArrayObject) {\n if (vao.obj) {\n this._deleteNativeVAO(vao.obj);\n }\n\n this._deleteBuffer(vao.buffers.indicies);\n this._deleteBuffer(vao.buffers.position);\n this._deleteBuffer(vao.buffers.uv);\n }\n\n public getUniformLocations>(program: WebGLProgram, uniforms: T): UniformLocations {\n const gl = this._gl;\n\n const uniformLocations = Object.keys(uniforms).reduce((locations, key) => {\n locations[key as keyof T] = gl.getUniformLocation(program, key)!;\n\n return locations;\n }, {} as UniformLocations);\n\n return {\n ...this._getCommonUniformLocations(program),\n ...uniformLocations\n };\n }\n\n public updateCommonUniforms(entity: Object3D, camera: Camera, shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniformLocations = shaderProgram.uniformLocations;\n\n // We're using \"matrix\"(=local matrix) here for efficiency\n // As projection doesn't require world matrix, as it doesn't have any parent or child\n const matrix = entity.matrix;\n const mvMatrix = mat4.create();\n mat4.multiply(mvMatrix, camera.viewMatrix, matrix);\n\n gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix);\n gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, camera.projectionMatrix);\n }\n\n public updateVRUniforms(shaderProgram: ShaderProgram, mvMatrix: mat4, pMatrix: mat4, eyeIndex: number) {\n const gl = this._gl;\n\n const uniformLocations = shaderProgram.uniformLocations;\n\n gl.uniformMatrix4fv(uniformLocations.uMVMatrix, false, mvMatrix);\n gl.uniformMatrix4fv(uniformLocations.uPMatrix, false, pMatrix);\n\n if (uniformLocations.uEye) {\n gl.uniform1f(uniformLocations.uEye, eyeIndex);\n }\n }\n\n public updateUniforms(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniforms = shaderProgram.uniforms;\n const uniformLocations = shaderProgram.uniformLocations;\n\n for (const key in uniforms) {\n const uniform = uniforms[key];\n const location = uniformLocations[key];\n\n if (!uniform) continue;\n\n if (uniform.needsUpdate) {\n uniform.update(gl, location, this._isWebGL2);\n }\n }\n }\n\n public releaseShaderResources(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n const uniforms = shaderProgram.uniforms;\n\n for (const key in uniforms) {\n const uniform = uniforms[key];\n\n if (!uniform) continue;\n\n if (uniform.needsUpdate) {\n uniform.destroy(gl);\n }\n }\n\n gl.deleteProgram(shaderProgram.program);\n }\n\n public useProgram(shaderProgram: ShaderProgram) {\n const gl = this._gl;\n\n gl.useProgram(shaderProgram.program);\n }\n\n public createProgram(vertexShader: string, fragmentShader: string) {\n const gl = this._gl;\n const program = gl.createProgram()!;\n\n const vs = this._compileShader(gl.VERTEX_SHADER, vertexShader);\n const fs = this._compileShader(gl.FRAGMENT_SHADER, fragmentShader);\n\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.bindAttribLocation(program, 0, \"position\");\n gl.bindAttribLocation(program, 1, \"uv\");\n gl.linkProgram(program);\n\n if (this._debug && !gl.getProgramParameter(program, gl.LINK_STATUS)) {\n let shaderLog: string | null = null;\n\n if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {\n shaderLog = gl.getShaderInfoLog(vs);\n } else if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {\n shaderLog = gl.getShaderInfoLog(fs);\n }\n\n throw new View360Error(ERROR.MESSAGES.FAILED_LINKING_PROGRAM(gl.getProgramInfoLog(program), shaderLog), ERROR.CODES.FAILED_LINKING_PROGRAM);\n }\n\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n\n return program;\n }\n\n public createWebGLTexture(texData: Texture): WebGLTexture {\n const gl = this._gl;\n const texture = gl.createTexture()!;\n\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texData.wrapS);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texData.wrapT);\n\n if (!texData.isVideo() && this._isWebGL2) {\n const gl2 = gl as WebGL2RenderingContext;\n\n gl2.texStorage2D(gl2.TEXTURE_2D, 1, gl2.RGBA8, texData.width, texData.height);\n }\n\n return texture;\n }\n\n public createWebGLCubeTexture(texData: Texture, size: number): WebGLTexture {\n const gl = this._gl;\n const texture = gl.createTexture()!;\n\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, texData.wrapS);\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, texData.wrapT);\n\n if (this._isWebGL2) {\n const gl2 = gl as WebGL2RenderingContext;\n\n gl2.texStorage2D(gl2.TEXTURE_CUBE_MAP, 1, gl2.RGBA8, size, size);\n }\n\n return texture;\n }\n\n public async makeXRCompatible() {\n const gl = this._gl;\n const attributes = gl.getContextAttributes();\n\n if (attributes && attributes.xrCompatible !== true) {\n await gl.makeXRCompatible();\n }\n }\n\n public bindXRLayer(session: XRSession) {\n const gl = this._gl;\n const xrLayer = new XRWebGLLayer(session, gl);\n session.updateRenderState({ baseLayer: xrLayer });\n }\n\n public bindXRFrame(frame: XRFrame) {\n const gl = this._gl;\n const session = frame.session;\n const baseLayer = session.renderState.baseLayer!;\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer);\n }\n\n public useDefaultFrameBuffer() {\n const gl = this._gl;\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n private _createBuffer(): WebGLBuffer {\n return this._gl.createBuffer()!;\n }\n\n private _deleteBuffer(buffer: WebGLBuffer) {\n return this._gl.deleteBuffer(buffer);\n }\n\n private _createNativeVAO() {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n return (gl as WebGL2RenderingContext).createVertexArray()!;\n } else {\n const ext = this._extensions.vao;\n\n return ext?.createVertexArrayOES() || null;\n }\n }\n\n private _bindNativeVAO(vao: WebGLVertexArrayObject | null) {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n (gl as WebGL2RenderingContext).bindVertexArray(vao);\n } else {\n const ext = this._extensions.vao;\n\n ext?.bindVertexArrayOES(vao);\n }\n }\n\n private _deleteNativeVAO(vao: WebGLVertexArrayObject | null) {\n const gl = this._gl;\n\n if (this._isWebGL2) {\n (gl as WebGL2RenderingContext).deleteVertexArray(vao);\n } else {\n const ext = this._extensions.vao;\n\n ext?.deleteVertexArrayOES(vao);\n }\n }\n\n private _supplyGeometryData(vao: VertexArrayObject, shaderProgram: ShaderProgram) {\n const geometry = vao.geometry;\n\n this._supplyIndiciesData(geometry.indicies, vao.buffers.indicies);\n this._supplyAttributeData(geometry.vertices, shaderProgram.program, \"position\", vao.buffers.position);\n this._supplyAttributeData(geometry.uvs, shaderProgram.program, \"uv\", vao.buffers.uv);\n }\n\n private _unbindBuffers() {\n const gl = this._gl;\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n }\n\n private _supplyIndiciesData(indicies: VertexData, buffer: WebGLBuffer) {\n const gl = this._gl;\n\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicies.data, gl.STATIC_DRAW);\n }\n\n private _supplyAttributeData(attribute: VertexData, program: WebGLProgram, name: string, buffer: WebGLBuffer) {\n const gl = this._gl;\n const attribLocation = gl.getAttribLocation(program, name);\n\n // Attribute not used\n if (attribLocation < 0) return;\n\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ARRAY_BUFFER, attribute.data, gl.STATIC_DRAW);\n gl.vertexAttribPointer(attribLocation, attribute.itemSize, gl.FLOAT, false, 0, 0);\n gl.enableVertexAttribArray(attribLocation);\n }\n\n private _compileShader(type: number, src: string) {\n const gl = this._gl;\n const shader = gl.createShader(type)!;\n\n gl.shaderSource(shader, src);\n gl.compileShader(shader);\n\n return shader;\n }\n\n private _getCommonUniformLocations(program: WebGLProgram) {\n const gl = this._gl;\n\n return {\n uMVMatrix: gl.getUniformLocation(program, \"uMVMatrix\")!,\n uPMatrix: gl.getUniformLocation(program, \"uPMatrix\")!\n };\n }\n\n private _getContext(canvas: HTMLCanvasElement): {\n gl: WebGLRenderingContext | WebGL2RenderingContext;\n isWebGL2: boolean;\n } {\n const webglIdentifiers = [\"webgl2\", \"webgl\", \"experimental-webgl\", \"webkit-3d\", \"moz-webgl\"];\n let context: WebGLRenderingContext | null = null;\n let isWebGL2 = false;\n const contextAttributes = {\n preserveDrawingBuffer: false,\n antialias: false\n };\n\n const onWebglContextCreationError = e => e.statusMessage;\n\n canvas.addEventListener(BROWSER.EVENTS.CONTEXT_CREATE_ERROR, onWebglContextCreationError);\n\n for (const identifier of webglIdentifiers) {\n try {\n context = canvas.getContext(identifier, contextAttributes) as WebGLRenderingContext;\n isWebGL2 = identifier === \"webgl2\";\n } catch (t) {} // eslint-disable-line no-empty\n if (context) {\n break;\n }\n }\n\n canvas.removeEventListener(BROWSER.EVENTS.CONTEXT_CREATE_ERROR, onWebglContextCreationError);\n\n if (!context) {\n throw new View360Error(ERROR.MESSAGES.WEBGL_NOT_SUPPORTED, ERROR.CODES.WEBGL_NOT_SUPPORTED);\n }\n\n return {\n gl: context,\n isWebGL2\n };\n }\n\n private _onContextLost = () => {\n const canvas = this._canvas;\n canvas.classList.add(DEFAULT_CLASS.CTX_LOST);\n this._contextLost = true;\n };\n\n private _onContextRestore = () => {\n const canvas = this._canvas;\n canvas.classList.remove(DEFAULT_CLASS.CTX_LOST);\n this._contextLost = false;\n };\n}\n\nexport default WebGLContext;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4 } from \"gl-matrix\";\nimport Camera from \"./Camera\";\nimport Projection from \"../projection/Projection\";\nimport WebGLContext from \"./WebGLContext\";\nimport XRManager from \"./XRManager\";\n\n/**\n * Projection renderer, based on WebGL\n * @ko WebGL 기반의 프로젝션 렌더러\n * @since 4.0.0\n */\nclass WebGLRenderer {\n private _canvas: HTMLCanvasElement;\n private _elementSize: { x: number, y: number };\n private _pixelRatio: number;\n\n public readonly ctx: WebGLContext;\n\n /**\n * Canvas element\n * @ko 캔버스 엘리먼트\n * @since 4.0.0\n */\n public get canvas() { return this._canvas; }\n /**\n * Canvas's width (`devicePixelRatio` is not applied)\n * @ko 캔버스의 보이는 너비 (`devicePixelRatio`가 적용되지 않은)\n * @since 4.0.0\n */\n public get width() { return this._elementSize.x; }\n /**\n * Canvas's height (`devicePixelRatio` is not applied)\n * @ko 캔버스의 높이 (`devicePixelRatio`가 적용되지 않은)\n * @since 4.0.0\n */\n public get height() { return this._elementSize.y; }\n /**\n * Current `devicePixelRatio` value.\n * @ko 현재 `devicePixelRatio` 값.\n * @since 4.0.0\n * @example\n * ```js\n * cosnt renderingWidth = view360.renderer.width * view360.renderer.pixelRatio;\n * ```\n */\n public get pixelRatio() { return this._pixelRatio; }\n /**\n * Width / height ratio (= width / height)\n * @ko 너비 / 높이의 비율 (= width / height)\n * @since 4.0.0\n * @example\n * ```js\n * const aspect = view360.renderer.width / view360.renderer.pixelRatio;\n * assert(aspect === view360.renderer.aspect);\n * ```\n */\n public get aspect() { return this._elementSize.x / this._elementSize.y; }\n\n /**\n * Create new instance\n * @ko 새 인스턴스를 생성합니다.\n * @param canvas - Canvas element {@ko 캔버스 엘리먼트}\n * @param debug - Whether to enable WebGL debugging {@ko WebGL debug 활성화 여부 }\n */\n public constructor(canvas: HTMLCanvasElement, debug: boolean) {\n this._canvas = canvas;\n this._elementSize = { x: 0, y: 0 };\n this._pixelRatio = 1;\n this.ctx = new WebGLContext(canvas, debug);\n }\n\n /**\n * Destroy instance and release all resources.\n * @ko 인스턴스를 제거하고 사용된 리소스를 전부 해제합니다.\n * @since 4.0.0\n */\n public destroy() {\n const canvas = this._canvas;\n\n this.ctx.destroy();\n canvas.width = 1;\n canvas.height = 1;\n }\n\n /**\n * Resize canvas and renew inner size cache.\n * @ko 캔버스의 크기를 재계산해서 내부의 사이즈 캐시값을 갱신합니다.\n * @since 4.0.0\n */\n public resize() {\n const canvas = this._canvas;\n const canvasSize = this._elementSize;\n const devicePixelRatio = window.devicePixelRatio;\n\n canvasSize.x = canvas.clientWidth;\n canvasSize.y = canvas.clientHeight;\n\n canvas.width = canvasSize.x * devicePixelRatio;\n canvas.height = canvasSize.y * devicePixelRatio;\n\n this._pixelRatio = devicePixelRatio;\n this.ctx.resize();\n }\n\n /**\n * Render projection\n * @ko 프로젝션을 렌더링합니다.\n * @param projection - Projection to render {@ko 렌더링할 프로젝션}\n * @param cameraa - Camera instance {@ko 카메라의 인스턴스}\n * @since 4.0.0\n */\n public render(projection: Projection, camera: Camera) {\n const ctx = this.ctx;\n const mesh = projection.getMesh();\n if (ctx.lost || !mesh) return;\n\n ctx.clear();\n ctx.useProgram(mesh.program);\n ctx.updateCommonUniforms(mesh, camera, mesh.program);\n projection.update(camera);\n ctx.updateUniforms(mesh.program);\n ctx.draw(mesh.vao, mesh.program);\n }\n\n /**\n * Render VR frame, only used for rendering frames inside VR sessions.\n * @ko VR 프레임을 렌더링합니다. VR 세션 진입 도중에만 사용됩니다.\n * @internal\n * @param projection - Projection to render {@ko 렌더링할 프로젝션}\n * @param vr - Instance of XRManager {@ko XRManager의 인스턴스}\n * @param frame - VR frame {@ko VR 프레임}\n * @since 4.0.0\n */\n public renderVR(projection: Projection, vr: XRManager, frame: XRFrame) {\n const ctx = this.ctx;\n const mesh = projection.getMesh();\n const eyeParams = vr.getEyeParams(frame);\n\n if (!eyeParams || !mesh) return;\n\n ctx.bindXRFrame(frame);\n ctx.useProgram(mesh.program);\n ctx.updateUniforms(mesh.program);\n\n eyeParams.forEach((eye, eyeIndex) => {\n const viewport = eye.viewport;\n // We're using \"mesh.matrix\"(=local matrix) here for efficiency\n // As projection doesn't require world matrix, as it doesn't have any parent or child\n const mvMatrix = mat4.multiply(mat4.create(), eye.vMatrix, mesh.matrix);\n\n ctx.viewport(viewport.x, viewport.y, viewport.width, viewport.height);\n ctx.updateVRUniforms(mesh.program, mvMatrix, eye.pMatrix, eyeIndex);\n ctx.draw(mesh.vao, mesh.program);\n });\n }\n}\n\nexport default WebGLRenderer;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport Camera, { CameraOptions } from \"./core/Camera\";\nimport PanoControl, { PanoControlOptions } from \"./control/PanoControl\";\nimport TextureLoader from \"./core/TextureLoader\";\nimport FrameAnimator from \"./core/FrameAnimator\";\nimport AutoResizer from \"./core/AutoResizer\";\nimport Autoplay, { AutoplayOptions } from \"./core/Autoplay\";\nimport XRManager from \"./core/XRManager\";\nimport View360Error from \"./core/View360Error\";\nimport Projection from \"./projection/Projection\";\nimport HotspotRenderer, { HotspotOptions } from \"./hotspot/HotspotRenderer\";\nimport WebGLRenderer from \"./core/WebGLRenderer\";\nimport Texture from \"./texture/Texture\";\nimport View360Plugin from \"./plugin/View360Plugin\";\nimport ERROR from \"./const/error\";\nimport { CONTROL_EVENTS } from \"./const/internal\";\nimport { DEFAULT_CLASS, EVENTS } from \"./const/external\";\nimport { findCanvas, getElement } from \"./utils\";\nimport * as EVENT_TYPES from \"./type/events\";\nimport { EventParams } from \"./type/utils\";\n\n/**\n * Events that {@link View360} can trigger\n * @ko {@link View360}가 트리거할 수 있는 이벤트들\n * @see [Detailed Example](/docs/events/ready)\n * @since 4.0.0\n */\nexport interface View360Events {\n [EVENTS.READY]: EVENT_TYPES.ReadyEvent;\n [EVENTS.LOAD_START]: EVENT_TYPES.LoadStartEvent;\n [EVENTS.LOAD]: EVENT_TYPES.LoadEvent;\n [EVENTS.PROJECTION_CHANGE]: EVENT_TYPES.ProjectionChangeEvent;\n [EVENTS.RESIZE]: EVENT_TYPES.ResizeEvent;\n [EVENTS.BEFORE_RENDER]: EVENT_TYPES.BeforeRenderEvent;\n [EVENTS.RENDER]: EVENT_TYPES.RenderEvent;\n [EVENTS.INPUT_START]: EVENT_TYPES.InputStartEvent;\n [EVENTS.INPUT_END]: EVENT_TYPES.InputEndEvent;\n [EVENTS.VIEW_CHANGE]: EVENT_TYPES.ViewChangeEvent;\n [EVENTS.STATIC_CLICK]: EVENT_TYPES.StaticClickEvent;\n [EVENTS.VR_START]: EVENT_TYPES.VRStartEvent;\n [EVENTS.VR_END]: EVENT_TYPES.VREndEvent;\n}\n\n/**\n * Options for {@link View360}\n * @ko {@link View360}용 옵션들\n * @see [Detailed Example](/docs/options)\n * @since 4.0.0\n */\nexport interface View360Options extends CameraOptions, PanoControlOptions {\n projection: Projection | null;\n hotspot: Partial;\n autoplay: boolean | Partial;\n autoInit: boolean;\n autoResize: boolean;\n canvasSelector: string;\n useResizeObserver: boolean;\n tabIndex: number | null;\n on: Partial<{ [key in keyof View360Events]: (evt: View360Events[key]) => any }>;\n plugins: View360Plugin[];\n maxDeltaTime: number;\n debug: boolean;\n}\n\n/**\n * Panorama 360 image viewer\n * @ko 파노라마 360 이미지 뷰어\n * @since 4.0.0\n * @see View360Options\n * @see View360Events\n */\nclass View360 extends Component {\n /**\n * Current version string of the View360\n * @ko View360의 현재 버젼 문자열\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // If the installed version of the View360 is v4.0.0, View360.VERSION is equal to \"4.0.0\"\n * console.log(View360.VERSION) // 4.0.0\n * ```\n */\n public static readonly VERSION = \"#__VERSION__#\";\n\n private _rootEl: HTMLElement;\n private _renderer: WebGLRenderer;\n private _camera: Camera;\n private _control: PanoControl;\n private _animator: FrameAnimator;\n private _autoplay: Autoplay;\n private _hotspot: HotspotRenderer;\n private _projection: Projection | null;\n private _autoResizer: AutoResizer;\n private _vr: XRManager;\n private _plugins: View360Plugin[];\n private _initialized: boolean;\n\n private _autoInit: View360Options[\"autoInit\"];\n private _autoResize: View360Options[\"autoResize\"];\n private _canvasSelector: View360Options[\"canvasSelector\"];\n private _useResizeObserver: View360Options[\"useResizeObserver\"];\n private _tabIndex: View360Options[\"tabIndex\"];\n private _debug: View360Options[\"debug\"];\n\n /**\n * Root element (`.view360-container`)\n * @ko 루트 엘리먼트 (`.view360-container`)\n * @since 4.0.0\n * @readonly\n * @example\n * ```html\n *
\n * \n *
\n * ```\n * ```ts\n * import View360 from \"@egjs/view360\";\n *\n * const viewer = new View360(\"#viewer\");\n * console.log(viewer.rootEl); // Element with id \"viewer\"\n * ```\n */\n public get rootEl() { return this._rootEl; }\n /**\n * Projection renderer.\n * @ko 프로젝션 렌더러.\n * @since 4.0.0\n * @readonly\n */\n public get renderer() { return this._renderer; }\n /**\n * Projection camera.\n * @ko 프로젝션 카메라.\n * @since 4.0.0\n * @readonly\n */\n public get camera() { return this._camera; }\n /**\n * Rotate/Zoom Controller.\n * @ko 회전/줌 컨트롤러.\n * @since 4.0.0\n * @readonly\n */\n public get control() { return this._control; }\n /**\n * WebXR-based VR manager.\n * @ko WebXR 기반의 VR 기능 매니저 인스턴스.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // Example: Enter VR\n * // This must be called on user interaction, else will be rejected.\n * viewer.vr.enter();\n * ```\n */\n public get vr() { return this._vr; }\n /**\n * Hotspot renderer.\n * You can also change options of {@link View360Options#hotspot} with this.\n * @ko 핫스팟 렌더러 인스턴스.\n * {@link View360Options#hotspot} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get hotspot() { return this._hotspot; }\n /**\n * An array of plugins added.\n * @ko 추가된 플러그인의 배열\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * plugins: [new ControlBar()]\n * });\n *\n * console.log(viewer.plugins); // [ControlBar]\n *\n * viewer.addPlugins(new LoadingSpinner()) // [ControlBar, LoadingSpinner];\n * ```\n */\n public get plugins() { return this._plugins; }\n /**\n * A instance of {@link Projection} that currently enabled. `null` if not initialized yet.\n * You should call {@link View360#load} to change panorama src or projection type.\n * @ko 현재 사용중인 {@link Projection}의 인스턴스. 프로젝션을 활성화하지 않았을 경우 `null`입니다.\n * 파노라마 이미지 소스나 프로젝션 타입을 변경하려면 {@link View360#load}를 호출하면 됩니다.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360\n * ```\n */\n public get projection() { return this._projection; }\n public set projection(val: View360Options[\"projection\"]) {\n if (this._initialized && val) {\n this.load(val);\n } else {\n this._projection = val;\n }\n }\n /**\n * A boolean value whether {@link View360#init init()} is called before.\n * @ko {@link View360#init init()}이 호출되었는지 여부를 가리키는 값\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * const viewer = new View360(\"#el\", { autoInit: false });\n *\n * console.log(viewer.initialized); // false\n *\n * await viewer.init();\n *\n * console.log(viewer.initialized); // true\n * ```\n */\n public get initialized() { return this._initialized; }\n /**\n * Instance of the Autoplay manager.\n * You can also change {@link View360Options#autoplay} options with this.\n * @ko Autoplay 기능의 매니저 인스턴스.\n * 이 인스턴스를 통해 {@link View360Options#autoplay} 옵션을 변경하는 것도 가능합니다.\n * @since 4.0.0\n * @readonly\n * @example\n * ```ts\n * // Disable autoplay\n * viewer.autoplay.disable();\n * ```\n */\n public get autoplay() { return this._autoplay; }\n /**\n * When this value is `true` and {@link View360Options#projection} is set, {@link View360#init init()} will be called automatically when instance is created.\n * @ko 이 값이 `true`이고, {@link View360Options#projection}이 설정되었으면, 인스턴스 생성 시점에 자동으로 {@link View360#init init()}을 호출합니다.\n * @default true\n * @since 4.0.0\n * @example\n * ```ts\n * import View360, { EquirectProjection, EVENTS } from \"@egjs/view360\";\n *\n * // viewer.init() is called on instance creation\n * // But as `init` is asynchronous, you should wait for \"ready\" event if you want to do something after initialization.\n * const viewer = new View360(\"#el_id\", {\n * autoInit: true,\n * projection: new EquirectProjection({ src: \"SRC_TO_URL\" })\n * });\n *\n * console.log(viewer.initialized); // false, as `init` is asynchronous\n *\n * viewer.once(EVENTS.READY, () => {\n * console.log(viewer.initialized); // true\n * });\n * ```\n */\n public get autoInit() { return this._autoInit; }\n /**\n * When `true`, {@link View360#resize} is called when the canvas size is changed.\n * @ko `true`일 경우, 캔버스의 크기가 변경되었을 때 자동으로 {@link View360#resize}를 호출합니다.\n * @default true\n * @since 4.0.0\n * @see View360#useResizeObserver\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * autoResize: true\n * });\n *\n * // This can trigger `viewer.resize()` if the canvas size was not 400px\n * const canvas = viewer.renderer.canvas;\n * canvas.style.width = \"400px\";\n * ```\n */\n public get autoResize() { return this._autoResize; }\n /**\n * CSS selector for canvas element to render panorama image/video.\n * The canvas element should be placed inside the root element. (Dont' have to be direct child)\n * @ko 파노라마 이미지/비디오를 렌더링할 canvas 엘리먼트의 CSS 선택자\n * 캔버스 엘리먼트는 루트 엘리먼트 내부에 있어야합니다. 루트 엘리먼트의 직계 자식 엘리먼트(Direct child element)일 필요는 없습니다.\n * @default \"canvas\"\n * @since 4.0.0\n * @example\n * ```html\n *
\n * \n * \n * \n *
\n * ```\n *\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * canvasSelector: \"#canvas_to_select\"\n * });\n * ```\n */\n public get canvasSelector() { return this._canvasSelector; }\n /**\n * When `true`, it will use {@link ResizeObserver} API to detect canvas size change when {@link View360Options#autoResize} is enabled.\n * @ko `true`일 때 {@link View360Options#autoResize}가 활성화되었으면, 사용 가능한 환경에서 {@link ResizeObserver} API를 사용해서 캔버스 크기 변화를 추적합니다.\n * @default true\n * @since 4.0.0\n */\n public get useResizeObserver() { return this._useResizeObserver; }\n /**\n * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} attribute for the canvas element.\n * This is necessary for the keyboard controls.\n * By default, `0` will be assigned. `null` to disable.\n * @ko 캔버스 엘리먼트에 적용할 {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex tabindex} 어트리뷰트의 값.\n * 이 값을 설정해야만 키보드 컨트롤을 사용 가능합니다.\n * 기본값으로 `0`이 설정됩니다. `null`로 지정하면 `tabindex`를 설정하지 않습니다.\n * @see RotateControlOptions#disableKeyboard\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * tabindex: 5\n * });\n * ```\n *\n * ```html\n * \n *
\n * \n *
\n * ```\n */\n public get tabIndex() { return this._tabIndex; }\n public set tabIndex(val: View360Options[\"tabIndex\"]) {\n const canvas = this._renderer.canvas;\n this._tabIndex = val;\n\n if (val != null) {\n canvas.tabIndex = val;\n } else {\n canvas.removeAttribute(\"tabindex\");\n }\n }\n /**\n * A maximum delta time between frames in seconds.\n * It can prevent camera or control changing too fast when frame being late.\n * @ko 프레임간 시간 차이의 최대값. (초 단위)\n * 퍼포먼스 등의 이유로 프레임 렌더링이 늦어졌을 때, 화면이 갑작스럽게 바뀌는 것을 막아줍니다.\n * @default 1 / 30\n * @since 4.0.0\n */\n public get maxDeltaTime() { return this._animator.maxDeltaTime; }\n public set maxDeltaTime(val: View360Options[\"maxDeltaTime\"]) { this._animator.maxDeltaTime = val; }\n /**\n * Enable WebGL debugging. Setting this to `true` can decrease performance.\n * This is used internally on developing View360.\n * @ko WebGL 디버깅을 활성화합니다. 이 값을 `true`로 할 경우 성능이 하락할 수 있습니다.\n * 이 옵션은 View360을 개발하기 위해 내부적으로 사용됩니다.\n * @default false\n */\n public get debug() { return this._debug; }\n public set debug(val: View360Options[\"debug\"]) { this._debug = val; }\n\n // Camera options\n /**\n * Initial yaw (y-axis rotation) value for camera. (in degrees, °)\n * As View360 uses right-handed coordinate system internally, camera will rotate counter-clockwise by this value.\n * @ko 카메라의 초기 yaw(y축 회전)값 (도 단위, °)\n * View360은 오른손 좌표계를 사용하기 때문에, 카메라가 해당 값만큼 시계 반대방향으로 회전합니다.\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialYaw: 30\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.yaw); // 30\n * });\n * ```\n */\n public get initialYaw() { return this._camera.initialYaw; }\n public set initialYaw(val: View360Options[\"initialYaw\"]) { this._camera.initialYaw = val; }\n /**\n * Initial pitch (x-axis rotation) value for camera. (in degrees, °)\n * As View360 uses right-handed coordinate system internally, positive value will make camera to look upside, while negative value will look down.\n * @ko 카메라의 초기 pitch(x축 회전)값 (도 단위, °)\n * View360은 오른손 좌표계를 사용하기 때문에, 양(+)의 값은 카메라가 위를 보게 하고, 음(-)의 값은 카메라가 아래를 보게 합니다.\n * @default 0\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialPitch: 60\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.pitch); // 60\n * });\n * ```\n */\n public get initialPitch() { return this._camera.initialPitch; }\n public set initialPitch(val: View360Options[\"initialPitch\"]) { this._camera.initialPitch = val; }\n /**\n * Initial zoom value for camera.\n * Setting this value to `2` will enlarge panorama 200% by width.\n * @ko 카메라의 초기 줌 값.\n * 이 값을 `2`로 설정할 경우 파노라마 이미지를 가로 기준 200%만큼 확대합니다.\n * @default 1\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * initialZoom: 2\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.zoom); // 2\n * });\n * ```\n */\n public get initialZoom() { return this._camera.initialZoom; }\n public set initialZoom(val: View360Options[\"initialZoom\"]) { this._camera.initialZoom = val; }\n /**\n * Restrict yaw(y-axis rotation) range. (in degrees, °)\n * @ko yaw(y축 회전) 범위를 제한합니다. (도 단위, °)\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * yawRange: [-30, 30]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.yaw); // 0\n * viewer.camera.lookAt({ yaw: 60 });\n * console.log(viewer.camera.yaw); // 30\n * });\n * ```\n */\n public get yawRange() { return this._camera.yawRange; }\n public set yawRange(val: View360Options[\"yawRange\"]) {\n this._camera.yawRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Restrict pitch(x-axis rotation) range. (in degrees, °)\n * @ko pitch(x축 회전) 범위를 제한합니다. (도 단위, °)\n * @default null\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * pitchRange: [-45, 45]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.pitch); // 0\n * viewer.camera.lookAt({ pitch: 60 });\n * console.log(viewer.camera.pitch); // 45\n * });\n * ```\n */\n public get pitchRange() { return this._camera.pitchRange; }\n public set pitchRange(val: View360Options[\"pitchRange\"]) {\n this._camera.pitchRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Restrict camera zoom range.\n * If `null`, a default zoom range from `0.6` to `10` will be used.\n * @ko 카메라 줌 범위를 제한합니다.\n * `null`일 경우 기본값으로 `0.6`에서 `10`의 범위를 사용합니다.\n * @default null\n * @since 4.0.0\n * @example\n * ```ts\n * const viewer = new View360(\"#el_id\", {\n * zoomRange: [0.5, 4]\n * });\n *\n * viewer.on(\"ready\", () => {\n * console.log(viewer.camera.zoom); // 1\n * viewer.camera.lookAt({ zoom: 6 });\n * console.log(viewer.camera.zoom); // 4\n * });\n * ```\n */\n public get zoomRange() { return this._camera.zoomRange; }\n public set zoomRange(val: View360Options[\"zoomRange\"]) {\n this._camera.zoomRange = val;\n if (this._projection) this._projection.updateCamera(this._camera);\n }\n /**\n * Camera's horizontal FOV(Field of View). (in degrees, °)\n * @ko 카메라의 수평 FOV(Field of View) 값. (도 단위, °)\n * @default 90\n * @since 4.0.0\n * @example\n * ```ts\n * // Init with fov: 120\n * const viewer = new View360(\"#el_id\", { fov: 120 });\n *\n * // Back to 90\n * viewer.fov = 90;\n * ```\n */\n public get fov() { return this._camera.fov; }\n public set fov(val: View360Options[\"fov\"]) {\n const camera = this._camera;\n const control = this._control;\n\n camera.fov = val;\n camera.updateMatrix();\n control.sync();\n }\n\n // Control options\n /**\n * A control for camera rotation.\n * You can also change options of {@link View360Options#rotate} with this.\n * @ko 카메라 회전을 담당하는 컨트롤.\n * {@link View360Options#rotate} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get rotate() { return this._control.rotate; }\n /**\n * A control for camera zoom.\n * You can also change options of {@link View360Options#zoom} with this.\n * @ko 카메라 줌을 담당하는 컨트롤.\n * {@link View360Options#zoom} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get zoom() { return this._control.zoom; }\n /**\n * A control for camera rotation with gyroscope input.\n * You can also change options of {@link View360Options#gyro} with this.\n * @ko 자이로스코프를 통한 카메라 회전을 담당하는 컨트롤.\n * {@link View360Options#gyro} 옵션 변경도 가능합니다.\n * @since 4.0.0\n * @readonly\n */\n public get gyro() { return this._control.gyro; }\n /**\n * Apply CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor} by current state of input when using mouse.\n * If `true`, this will add CSS style to canvas element. It'll apply `cursor: \"grab\"` by default and `cursor: \"grabbing\"` when holding the mouse button.\n * @ko 마우스 사용시 CSS {@link https://developer.mozilla.org/en-US/docs/Web/CSS/cursor cursor}값을 자동으로 변경할지 여부.\n * `true`일 경우 기본 상태에서 `cursor: \"grab\"`을, 입력 도중에 `cursor: \"grabbing\"`을 캔버스에 적용합니다.\n * @default true\n * @since 4.0.0\n */\n public get useGrabCursor() { return this._control.useGrabCursor; }\n public set useGrabCursor(val: View360Options[\"useGrabCursor\"]) { this._control.useGrabCursor = val; }\n /**\n * Disable context menu which pops up on mouse right click.\n * @ko 마우스 우클릭시 표시되는 컨텍스트 메뉴를 비활성화합니다.\n * @default false\n * @since 4.0.0\n */\n public get disableContextMenu() { return this._control.disableContextMenu; }\n public set disableContextMenu(val: View360Options[\"disableContextMenu\"]) { this._control.disableContextMenu = val; }\n /**\n * If `true`, enables scroll on mobile(touch) devices on canvas.\n * :::caution\n * When this option is enabled, users must swipe horizontally first then vertically to change view up or down.\n * :::\n * @ko `true`로 설정할 경우, 모바일(터치) 환경의 캔버스 영역 내에서 스크롤을 가능하게 합니다.\n * :::caution\n * 이 값을 활성화할 경우, 사용자가 카메라 뷰를 위/아래로 바꾸기 위해서는 먼저 가로로 스와이프한 이후에 세로로 스와이프해야만 합니다.\n * :::\n * @since 4.0.0\n * @default true\n */\n public get scrollable() { return this._control.scrollable; }\n public set scrollable(val: View360Options[\"scrollable\"]) { this._control.scrollable = val; }\n /**\n * If `true`, enables scroll by mouse wheel on canvas.\n * :::caution\n * When this option is enabled, zoom by mouse wheel will be disabled.\n * :::\n * @ko `true`로 설정할 경우, 캔버스 영역 내에서 마우스 휠을 이용한 페이지 스크롤이 가능해집니다.\n * :::caution\n * 이 값을 활성화할 경우, 마우스 휠을 통한 줌이 불가능하게 됩니다.\n * :::\n * @since 4.0.0\n * @default false\n */\n public get wheelScrollable() { return this._control.wheelScrollable; }\n public set wheelScrollable(val: View360Options[\"wheelScrollable\"]) { this._control.wheelScrollable = val; }\n\n /**\n * Create new instance of View360\n * @ko View360의 새로운 인스턴스를 생성합니다\n * @param root - Root element(`.view360-container`) to mount View360\n * Can be either a CSS selector or HTMLElement.\n * {@ko View360을 마운트할 루트 엘리먼트, CSS 셀렉터나 HTMLElement를 지정 가능합니다.}\n * @param options - Options to apply\n * {@ko 적용할 옵션들}\n * @example\n * ```ts\n * import View360, { EquirectProjection } from \"@egjs/view360\";\n *\n * // Create new View360 instance\n * const viewer = new View360(\"#id-of-a-container\", {\n * projection: new EquirectProjection({\n * src: \"URL_TO_PANORAMA_IMAGE_OR_VIDEO\",\n * })\n * });\n * ```\n */\n public constructor(root: string | HTMLElement, {\n projection = null,\n initialYaw = 0,\n initialPitch = 0,\n initialZoom = 1,\n yawRange = null,\n pitchRange = null,\n zoomRange = null,\n fov = 90,\n useGrabCursor = true,\n disableContextMenu = false,\n rotate = true,\n zoom = true,\n gyro = false,\n scrollable = true,\n wheelScrollable = false,\n autoplay = false,\n hotspot = {},\n autoInit = true,\n autoResize = true,\n canvasSelector = \"canvas\",\n useResizeObserver = true,\n on = {},\n plugins = [],\n maxDeltaTime = 1 / 30,\n tabIndex = 0,\n debug = false\n }: Partial = {}) {\n super();\n\n this._rootEl = getElement(root);\n this._plugins = plugins;\n this._initialized = false;\n\n // Options\n this._autoInit = autoInit;\n this._autoResize = autoResize;\n this._canvasSelector = canvasSelector;\n this._useResizeObserver = useResizeObserver;\n this._tabIndex = tabIndex;\n this._debug = debug;\n\n // Core components\n const canvas = findCanvas(this._rootEl, canvasSelector);\n this._renderer = new WebGLRenderer(canvas, debug);\n this._camera = new Camera({\n initialYaw,\n initialPitch,\n initialZoom,\n fov,\n yawRange,\n pitchRange,\n zoomRange\n });\n this._control = new PanoControl(canvas, this._camera, {\n useGrabCursor,\n scrollable,\n wheelScrollable,\n disableContextMenu,\n rotate,\n zoom,\n gyro\n });\n this._animator = new FrameAnimator(maxDeltaTime);\n this._autoplay = new Autoplay(this, canvas, autoplay);\n this._projection = projection;\n this._autoResizer = new AutoResizer(useResizeObserver, () => this.resize());\n this._vr = new XRManager(this._renderer.ctx);\n this._hotspot = new HotspotRenderer(this._rootEl, this._renderer, hotspot);\n\n this._addEventHandlers(on);\n\n if (projection && autoInit) {\n this.init();\n }\n }\n\n /**\n * Destroy instance and release all resources.\n * @ko 인스턴스를 제거하고 모든 리소스를 해제합니다.\n * @since 4.0.0\n */\n public destroy() {\n this._camera.destroy();\n this._animator.stop();\n this._renderer.destroy();\n this._control.destroy();\n this._autoResizer.disable();\n\n if (this._projection) {\n this._projection.releaseAllResources(this._renderer.ctx);\n this._projection = null;\n }\n\n this._plugins.forEach(plugin => plugin.destroy(this));\n\n this._initialized = false;\n }\n\n /**\n * Initialize inner components and load projection src.\n * @ko 내부 컴포넌트들을 초기화하고 프로젝션 소스를 로드합니다.\n * @since 4.0.0\n */\n public async init() {\n if (!this._projection) {\n throw new View360Error(ERROR.MESSAGES.PROVIDE_PROJECTION_FIRST, ERROR.CODES.PROVIDE_PROJECTION_FIRST);\n }\n\n const renderer = this._renderer;\n const camera = this._camera;\n const control = this._control;\n const animator = this._animator;\n const hotspot = this._hotspot;\n const projection = this._projection;\n const canvas = renderer.canvas;\n\n this._bindComponentEvents();\n renderer.ctx.init();\n this._resizeComponents();\n camera.updateMatrix();\n\n if (this._autoResize) {\n this._autoResizer.enable(canvas);\n }\n\n if (!this._autoplay.enableBlocked) {\n this._autoplay.enable();\n }\n\n this._plugins.forEach(plugin => {\n plugin.init(this);\n });\n\n const texture = await this._loadTexture(projection);\n this._applyProjection(projection, texture, null);\n hotspot.refresh();\n animator.start(this._renderFrameOnDemand);\n await control.enable();\n\n if (this._tabIndex != null && !canvas.hasAttribute(\"tabIndex\")) {\n canvas.tabIndex = this._tabIndex;\n }\n\n this._initialized = true;\n this.renderFrame(0);\n\n this._emit(EVENTS.READY);\n }\n\n /**\n * Load new panorama image/video and display it.\n * This will {@link View360#init init()} View360 if it's not initialized yet.\n * @ko 새로운 파노라마 이미지 혹은 비디오를 로드하고 표시합니다.\n * 만약 View360이 아직 초기화되지 않았다면, {@link View360#init init()}을 호출합니다.\n * @param projection - Projection & video options for new source. {@ko 새로운 파노라마 이미지/비디오에 적용할 옵션들}\n * @returns `Promise` if load was successful. {@ko 프로젝션 로드에 성공했을 경우 `Promise`를 반환합니다. }\n * @since 4.0.0\n * @example\n * ```ts\n * // Change to video\n * viewer.load({\n * src: \"URL_TO_NEW_VIDEO\",\n * video: true\n * });\n * ```\n */\n public async load(projection: Projection): Promise {\n if (!projection) return false;\n\n if (this._initialized) {\n const texture = await this._loadTexture(projection);\n this._applyProjection(projection, texture, this._projection);\n this.renderFrame(0);\n } else {\n // Should update internal options before init\n this._projection = projection;\n this.init();\n }\n\n return true;\n }\n\n /**\n * Refresh component's size by current\n * @ko View360이 내부적으로 캐시하고 있는 엘리먼트 크기를 현재 크기로 갱신합니다.\n * @since 4.0.0\n */\n public resize() {\n if (!this._initialized) return;\n\n this._resizeComponents();\n\n // To prevent flickering, render immediately after resizing components\n this.renderFrame(0);\n\n const { width, height } = this._renderer;\n\n this._emit(EVENTS.RESIZE, {\n width,\n height\n });\n }\n\n /**\n * Add new plugins\n * @ko 새로운 플러그인을 추가합니다.\n * @param plugins Plugins to add {@ko 추가할 플러그인들}\n * @see View360Options#plugins\n * @since 4.0.0\n * @example\n * ```ts\n * // Add a single plugin\n * viewer.addPlugins(new ControlBar());\n *\n * // Add multiple plugins\n * viewer.addPlugins(new ControlBar(), new LoadingSpinner());\n * ```\n */\n public addPlugins(...plugins: View360Plugin[]) {\n if (this._initialized) {\n plugins.forEach(plugin => { plugin.init(this); });\n }\n\n this._plugins.push(...plugins);\n }\n\n /**\n * Remove plugins.\n * @ko 플러그인을 제거합니다.\n * @param plugins Plugins to remove {@ko 제거할 플러그인들}\n * @since 4.0.0\n * @example\n * ```ts\n * // Remove a single plugin\n * viewer.removePlugins(plugin1);\n *\n * // Remove multiple plugins\n * viewer.removePlugins(plugin2, plugin3);\n * ```\n */\n public removePlugins(...plugins: View360Plugin[]) {\n plugins.forEach(plugin => {\n const pluginIdx = this._plugins.indexOf(plugin);\n\n if (pluginIdx < 0) return;\n\n plugin.destroy(this);\n this._plugins.splice(pluginIdx, 1);\n });\n }\n\n /**\n * Render a single panorama image/video frame.\n * Rendering is performed automatically on demand, so you usually don't have to call this.\n * Call this when a frame is not renewed after changing options.\n * @ko 파노라마 이미지/비디오의 한 프레임을 렌더링합니다.\n * 프레임 갱신은 보통 필요한 때에만 자동적으로 이루어지기 때문에, 보통은 이 메소드를 호출할 필요는 없습니다.\n * 옵션 변경 이후에도 프레임 갱신이 이루어지지 않는다면, 이 메소드를 호출해주세요.\n * @param delta Delta time in milisec. {@ko 프레임간 시간 차이, 밀리초 단위}\n * @since 4.0.0\n */\n public renderFrame = (delta: number) => {\n const camera = this._camera;\n const renderer = this._renderer;\n const control = this._control;\n const hotspot = this._hotspot;\n const autoPlayer = this._autoplay;\n const projection = this._projection;\n\n if (!projection) return;\n\n this._emit(EVENTS.BEFORE_RENDER);\n\n if (autoPlayer.playing) {\n autoPlayer.update(delta);\n control.sync();\n }\n\n if (camera.animation) {\n camera.animation.update(delta);\n } else {\n control.update(delta);\n }\n\n renderer.render(projection, camera);\n hotspot.render(camera);\n\n if (camera.changed) {\n this._emit(EVENTS.VIEW_CHANGE, {\n yaw: camera.yaw,\n pitch: camera.pitch,\n zoom: camera.zoom,\n quaternion: [\n camera.quaternion[0],\n camera.quaternion[1],\n camera.quaternion[2],\n camera.quaternion[3]\n ]\n });\n }\n camera.onFrameRender();\n\n this._emit(EVENTS.RENDER);\n };\n\n private _emit(eventName: K, ...params: EventParams) {\n const evtParams = params ? params[0] : {};\n\n this.trigger(eventName as any, {\n type: eventName,\n target: this,\n ...evtParams\n });\n }\n\n private _renderFrameOnDemand = (delta: number) => {\n const camera = this._camera;\n const control = this._control;\n const autoplay = this._autoplay;\n const texture = this._projection?.getTexture();\n\n if (!this._initialized || !texture) return;\n if (\n !camera.animation\n && !control.animating\n && !autoplay.playing\n && !texture.isVideo()\n ) return;\n\n this.renderFrame(delta);\n };\n\n private _renderVRFrame = (_delta: number, frame: XRFrame) => {\n const vr = this._vr;\n const projection = this._projection;\n const renderer = this._renderer;\n\n if (!projection) return;\n\n this._emit(EVENTS.BEFORE_RENDER);\n\n renderer.renderVR(projection, vr, frame);\n\n this._emit(EVENTS.RENDER);\n }\n\n private _applyProjection(projection: Projection, texture: Texture, prevProjection: Projection | null) {\n const camera = this._camera;\n const control = this._control;\n const renderer = this._renderer;\n\n // Remove previous projection\n if (prevProjection) {\n prevProjection.releaseAllResources(this._renderer.ctx);\n }\n\n projection.applyTexture(renderer.ctx, texture);\n projection.updateCamera(camera);\n projection.updateControl(control);\n\n this._projection = projection;\n this._emit(EVENTS.PROJECTION_CHANGE, {\n projection\n });\n }\n\n private async _loadTexture(projection: Projection): Promise {\n const contentLoader = new TextureLoader();\n const { src, video } = projection;\n\n this._emit(EVENTS.LOAD_START, {\n src,\n video\n });\n\n const texture = await contentLoader.load(src, video);\n\n this._emit(EVENTS.LOAD, {\n src,\n video\n });\n\n return texture;\n }\n\n private _resizeComponents() {\n const renderer = this._renderer;\n const camera = this._camera;\n const control = this._control;\n\n renderer.resize();\n camera.resize(renderer.width, renderer.height);\n control.resize(renderer.width, renderer.height);\n }\n\n private _addEventHandlers(events: View360Options[\"on\"]) {\n // Bind option \"on\"\n Object.keys(events).forEach((evtName: keyof typeof EVENT_TYPES) => {\n this.on(evtName, events[evtName]);\n });\n }\n\n private _bindComponentEvents() {\n // Bind internal component events\n const root = this._rootEl;\n const control = this._control;\n const animator = this._animator;\n const renderer = this._renderer;\n const vr = this._vr;\n\n const controlEventsToPropagate = [\n CONTROL_EVENTS.STATIC_CLICK,\n CONTROL_EVENTS.INPUT_START,\n CONTROL_EVENTS.INPUT_END\n ];\n\n controlEventsToPropagate.forEach(evtName => {\n control.rotate.on(evtName, evt => {\n this._emit(evtName, evt);\n });\n\n control.zoom.on(evtName, evt => {\n this._emit(evtName, evt);\n });\n });\n\n vr.on(EVENTS.VR_START, evt => {\n root.classList.add(DEFAULT_CLASS.IN_VR);\n\n animator.changeContext(evt.session);\n animator.start(this._renderVRFrame);\n\n this._emit(EVENTS.VR_START);\n });\n\n vr.on(EVENTS.VR_END, () => {\n root.classList.remove(DEFAULT_CLASS.IN_VR);\n\n renderer.ctx.useDefaultFrameBuffer();\n animator.changeContext(window);\n animator.start(this._renderFrameOnDemand);\n\n this.resize();\n\n this._emit(EVENTS.VR_END);\n });\n }\n}\n\nexport default View360;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { mat4, quat, vec3 } from \"gl-matrix\";\n\n/**\n * Base class for 3D objects\n * @ko 3D 오브젝트의 베이스 클래스\n * @since 4.0.0\n * @internal\n */\nclass Object3D {\n /**\n * Local matrix of the object\n * @ko 오브젝트의 local matrix\n * @since 4.0.0\n */\n public matrix: mat4;\n /**\n * Rotation quaternion\n * @ko 현재 오브젝트의 회전을 나타내는 사원수 값\n * @since 4.0.0\n */\n public rotation: quat;\n /**\n * Position of the object\n * @ko 오브젝트의 위치\n * @since 4.0.0\n */\n public position: vec3;\n /**\n * A scale vector of the object\n * @ko 오브젝트가 각 축으로 확대된 정도를 나타내는 벡터\n * @since 4.0.0\n */\n public scale: vec3;\n\n /**\n * Create new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n */\n public constructor() {\n this.matrix = mat4.create();\n this.rotation = quat.create();\n this.position = vec3.fromValues(0, 0, 0);\n this.scale = vec3.fromValues(1, 1, 1);\n }\n\n /**\n * Update local matrix of the object.\n * @ko 오브젝트의 local matrix를 갱신합니다.\n * @since 4.0.0\n */\n public updateMatrix() {\n mat4.fromRotationTranslationScale(this.matrix, this.rotation, this.position, this.scale);\n }\n}\n\nexport default Object3D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360Plugin from \"../View360Plugin\";\nimport View360 from \"../../View360\";\nimport { EVENTS } from \"../../const/external\";\nimport { createElement } from \"../../utils\";\nimport { LoadStartEvent } from \"../../type/events\";\n\n/**\n * Options for {@link LoadingSpinner}\n * @ko {@link LoadingSpinner}용 옵션들\n * @since 4.0.0\n * @category Plugin\n */\nexport interface LoadingSpinnerOptions {\n /**\n * Override default class names.\n * @ko 디폴트 클래스 이름들을 오버라이드합니다.\n * @since 4.0.0\n */\n className: Partial<{ -readonly [key in keyof typeof LoadingSpinner.DEFAULT_CLASS]: string }>;\n}\n\n/**\n * A plugin that displays loading spinner while loading the projection.\n * @ko 프로젝션 로딩중에 로딩 스피너를 보여주는 플러그인\n * @since 4.0.0\n * @category Plugin\n */\nclass LoadingSpinner implements View360Plugin {\n /**\n * Default class names that LoadingSpinner uses\n * @ko LoadingSpinner가 사용하는 디폴트 클래스 이름\n * @since 4.0.0\n */\n public static readonly DEFAULT_CLASS = {\n /**\n * A class name for the container element\n * @ko 컨테이너 엘리먼트의 클래스 이름\n * @since 4.0.0\n */\n CONTAINER: \"view360-spinner\",\n /**\n * A class name for the spinning ring element\n * @ko 돌아가는 링 엘리먼트의 클래스 이름\n * @since 4.0.0\n */\n RING: \"view360-spinner-ring\"\n } as const;\n\n /**\n * A class names overriding\n * @ko 현재 오버라이드 중인 클래스 이름\n * @since 4.0.0\n */\n public readonly className: LoadingSpinnerOptions[\"className\"];\n\n private _container: HTMLElement;\n\n /**\n * Create a new instance of LoadingSpinner. {@ko LoadingSpinner의 새 인스턴스를 생성합니다.}\n * @param options Options {@ko 옵션들}\n */\n public constructor({\n className = {}\n }: Partial = {}) {\n this.className = className;\n this._container = this._createElements();\n }\n\n public init(viewer: View360) {\n viewer.on(EVENTS.LOAD_START, this._startLoading);\n }\n\n public destroy(viewer: View360): void {\n viewer.off(EVENTS.LOAD_START, this._startLoading);\n this._detachElements({ target: viewer });\n }\n\n private _startLoading = ({ target: viewer }: LoadStartEvent) => {\n viewer.rootEl.appendChild(this._container);\n\n if (viewer.initialized) {\n viewer.once(EVENTS.LOAD, this._detachElements);\n } else {\n viewer.once(EVENTS.READY, this._detachElements);\n }\n };\n\n private _detachElements = ({ target: viewer }: { target: View360 }) => {\n const container = this._container;\n if (!container) return;\n\n if (container.parentElement === viewer.rootEl) {\n viewer.rootEl.removeChild(container);\n }\n };\n\n private _createElements() {\n const className = {\n ...this.className,\n ...LoadingSpinner.DEFAULT_CLASS\n };\n\n const container = createElement(className.CONTAINER);\n const ring = createElement(className.RING);\n\n container.appendChild(ring);\n\n return container;\n }\n}\n\nexport default LoadingSpinner;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\n/* eslint-disable @typescript-eslint/no-empty-function */\n/* eslint-disable @typescript-eslint/no-unused-vars */\nimport ControlBar from \"./ControlBar\";\nimport View360 from \"../../View360\";\n\n/**\n * Common options for {@link ControlBarItem}\n * @ko {@link ControlBarItem}의 공통 옵션들\n * @category Plugin\n * @since 4.0.0\n */\nexport interface ControlBarItemOptions {\n /**\n * @copy ControlBarItem#position\n */\n position: typeof ControlBar.POSITION[keyof typeof ControlBar.POSITION];\n /**\n * @copy ControlBarItem#order\n */\n order: number;\n}\n\n/**\n * Interface of the ControlBar items\n * @ko 컨트롤바 아이템의 인터페이스\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nabstract class ControlBarItem {\n /**\n * Element of the item.\n * @ko 아이템의 엘리먼트\n * @since 4.0.0\n */\n public abstract element: HTMLElement;\n\n /**\n * Position to display item.\n * @ko 아이템을 표시할 위치.\n * @since 4.0.0\n */\n public position: ControlBarItemOptions[\"position\"];\n /**\n * Order within the same position.\n * The lowest one will be shown first.\n * @ko 동일한 position 내에서의 순서, 작을수록 먼저 표시됩니다.\n * @since 4.0.0\n */\n public order: ControlBarItemOptions[\"order\"];\n\n /**\n * Create new instance of the ControlBarItem\n * @ko ControlBarItem의 새로운 인스턴스를 생성합니다.\n * @param options Options {@ko 옵션들}\n */\n public constructor(options: ControlBarItemOptions) {\n this.position = options.position;\n this.order = options.order;\n }\n\n /**\n * Initialize item.\n * @ko 아이템을 초기화합니다.\n * @param viewer - A instance of viewer to attach item {@ko 아이템을 부착할 뷰어의 인스턴스}\n * @param controlBar - A instance of control bar to attach item {@ko 아이템을 부착할 컨트롤바의 인스턴스}\n * @since 4.0.0\n */\n public abstract init(viewer: View360, controlBar: ControlBar): any;\n /**\n * Destroy item and release all resources & event handlers.\n * @ko 아이템을 제거하고 할당된 모든 리소스 및 이벤트 핸들러를 제거합니다.\n * @param viewer - A instance of viewer to detach item {@ko 아이템을 떼어 낼 뷰어의 인스턴스}\n * @param controlBar - A instance of control bar to detach item {@ko 아이템을 떼어 낼 컨트롤바의 인스턴스}\n * @since 4.0.0\n */\n public abstract destroy(viewer: View360, controlBar: ControlBar): any;\n}\n\nexport default ControlBarItem;\n","export const CONTROL_BAR_DEFAULT_CLASS = {\n CONTROLS_ROOT: \"view360-controls\",\n CONTROLS_BG: \"view360-controls-background\",\n CONTROLS_MAIN: \"view360-controls-main\",\n CONTROLS_TOP: \"view360-controls-top\",\n CONTROLS_BOTTOM: \"view360-controls-bottom\",\n CONTROLS_MID: \"view360-controls-mid\",\n CONTROLS_LEFT: \"view360-controls-left\",\n CONTROLS_RIGHT: \"view360-controls-right\",\n CONTROLS_FLOAT_LEFT: \"view360-controls-float-left\",\n CONTROLS_FLOAT_RIGHT: \"view360-controls-float-right\",\n CONTROLS_BUTTON: \"view360-controls-button\",\n PROGRESS_ROOT: \"view360-controls-progress\",\n VOLUME_ROOT: \"view360-controls-volume\",\n RANGE_ROOT: \"view360-range\",\n RANGE_TRACK: \"view360-range-track\",\n RANGE_THUMB: \"view360-range-thumb\",\n RANGE_FILLER: \"view360-range-filler\",\n PLAY_BUTTON: \"view360-controls-play\",\n PAUSE_BUTTON: \"view360-controls-pause\",\n UNMUTED_BUTTON: \"view360-controls-unmuted\",\n MUTED_BUTTON: \"view360-controls-muted\",\n FULLSCREEN_BUTTON: \"view360-controls-fullscreen\",\n FULLSCREEN_EXIT_BUTTON: \"view360-controls-fullscreen-exit\",\n VR_BUTTON: \"view360-controls-vr\",\n GYRO_ENABLED: \"view360-controls-gyro-enabled\",\n GYRO_DISABLED: \"view360-controls-gyro-disabled\",\n VIDEO_TIME_DISPLAY: \"view360-controls-time\",\n PIEVIEW_ROOT: \"view360-controls-pie\",\n FIXED: \"view360-controls-fixed\",\n UNAVAILABLE: \"view360-controls-unavailable\",\n HIDDEN: \"view360-controls-hidden\"\n} as const;\n\nexport const CONTROL_BAR_ITEM_POSITION = {\n /**\n * Place control bar item floating at top-left corner\n * @ko 아이템을 왼쪽 위 구석에 표시합니다.\n * @since 4.0.0\n */\n TOP_LEFT: \"top-left\",\n /**\n * Place control bar item floating at top-right corner\n * @ko 아이템을 오른쪽 위 구석에 표시합니다.\n * @since 4.0.0\n */\n TOP_RIGHT: \"top-right\",\n /**\n * Place control bar item at upper block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 위쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_TOP: \"main-top\",\n /**\n * Place control bar item at lower block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 하단 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_BOTTOM: \"main-bottom\",\n /**\n * Place control bar item at center-left block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 왼쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_LEFT: \"main-left\",\n /**\n * Place control bar item at center-right block inside the bottom control bar.\n * @ko 아이템을 하단에 표시되는 컨트롤바 내에서 중간 오른쪽 블럭에 표시합니다.\n * @since 4.0.0\n */\n MAIN_RIGHT: \"main-right\"\n} as const;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Component from \"@egjs/component\";\nimport { ControlBarOptions } from \"./ControlBar\";\nimport { CONTROL_BAR_DEFAULT_CLASS } from \"./const\";\nimport Motion from \"../../core/Motion\";\nimport MouseInput from \"../../control/input/MouseInput\";\nimport TouchInput from \"../../control/input/TouchInput\";\nimport { CONTROL_EVENTS, INFINITE_RANGE } from \"../../const/internal\";\nimport { clamp } from \"../../utils\";\nimport { InputEvents } from \"../../type/internal\";\nimport { EL_DIV } from \"../../const/browser\";\n\nclass RangeControl extends Component<{\n [CONTROL_EVENTS.INPUT_START]: number;\n [CONTROL_EVENTS.CHANGE]: number;\n [CONTROL_EVENTS.INPUT_END]: void;\n}> {\n public readonly rootEl: HTMLElement;\n public readonly thumbEl: HTMLElement;\n public readonly trackEl: HTMLElement;\n public readonly fillerEl: HTMLElement;\n\n private _motion: Motion;\n private _mouseInput: MouseInput;\n private _touchInput: TouchInput;\n private _fixedClass: string;\n private _bbox: DOMRect;\n\n /**\n *\n */\n public constructor() {\n super();\n\n const root = document.createElement(EL_DIV);\n const track = document.createElement(EL_DIV);\n const thumb = document.createElement(EL_DIV);\n const filler = document.createElement(EL_DIV);\n\n root.draggable = false;\n\n track.appendChild(filler);\n track.appendChild(thumb);\n root.appendChild(track);\n\n this.rootEl = root;\n this.trackEl = track;\n this.thumbEl = thumb;\n this.fillerEl = filler;\n\n this._mouseInput = new MouseInput();\n this._touchInput = new TouchInput();\n this._motion = new Motion({ duration: 1, range: INFINITE_RANGE, easing: x => x });\n this._bbox = {\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n left: 0,\n right: 0,\n bottom: 0,\n top: 0\n } as DOMRect;\n this._fixedClass = CONTROL_BAR_DEFAULT_CLASS.FIXED;\n }\n\n public init(className: Required) {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n\n this.rootEl.classList.add(className.RANGE_ROOT);\n this.trackEl.classList.add(className.RANGE_TRACK);\n this.thumbEl.classList.add(className.RANGE_THUMB);\n this.fillerEl.classList.add(className.RANGE_FILLER);\n this._fixedClass = className.FIXED;\n\n mouseInput.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n touchInput.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n\n mouseInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n touchInput.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n mouseInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n touchInput.on(CONTROL_EVENTS.CHANGE, this._onChange);\n\n mouseInput.enable(this.rootEl);\n touchInput.enable(this.rootEl);\n\n this.resize();\n }\n\n public destroy() {\n const mouseInput = this._mouseInput;\n const touchInput = this._touchInput;\n\n this.rootEl.className = \"\";\n this.trackEl.className = \"\";\n this.thumbEl.className = \"\";\n this.fillerEl.className = \"\";\n\n mouseInput.off();\n touchInput.off();\n mouseInput.disable();\n touchInput.disable();\n }\n\n public resize() {\n this._bbox = this.trackEl.getBoundingClientRect();\n }\n\n public updateStyle(progress: number) {\n const width = this._bbox.width;\n const clampedProgress = clamp(progress, 0, 1);\n\n this.fillerEl.style.width = `${clampedProgress * 100}%`;\n this.thumbEl.style.transform = `translateX(${clampedProgress * width}px)`;\n }\n\n private _onHold = ({ srcEvent, isTouch }: InputEvents<{ x: number; y: number }>[typeof CONTROL_EVENTS.INPUT_START]) => {\n const bbox = this._bbox;\n if (!bbox) return;\n\n const x = isTouch\n ? (srcEvent as TouchEvent).touches[0].pageX\n : (srcEvent as MouseEvent).pageX;\n const elX = bbox.x + (window.scrollX ?? window.pageXOffset);\n\n const clamepdX = clamp(x, elX, elX + bbox.width);\n const progress = (clamepdX - elX) / bbox.width;\n\n this._motion.reset(clamepdX);\n this.thumbEl.classList.add(this._fixedClass);\n\n this.trigger(CONTROL_EVENTS.INPUT_START, progress);\n };\n\n private _onChange = ({ delta }: InputEvents<{ x: number; y: number }>[typeof CONTROL_EVENTS.CHANGE]) => {\n const motion = this._motion;\n const bbox = this._bbox;\n if (!bbox) return;\n\n motion.setNewEndByDelta(delta.x);\n motion.update(1);\n\n const elX = bbox.x + (window.scrollX ?? window.pageXOffset);\n const clampedX = clamp(motion.val, elX, elX + bbox.width);\n const progress = (clampedX - elX) / bbox.width;\n\n this.trigger(CONTROL_EVENTS.CHANGE, progress);\n };\n\n private _onRelease = () => {\n const bbox = this._bbox;\n if (!bbox) return;\n\n this.thumbEl.classList.remove(this._fixedClass);\n\n this.trigger(CONTROL_EVENTS.INPUT_END);\n };\n}\n\nexport default RangeControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport RangeControl from \"./RangeControl\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport { CONTROL_EVENTS, VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport { EVENTS } from \"../../const/external\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show video progress bar.\n * @ko 비디오의 프로그레스 바를 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass ProgressBar extends ControlBarItem {\n public get element() { return this._rangeControl.rootEl; }\n\n private _controlBar: ControlBar | null;\n private _video: TextureVideo | null;\n private _rangeControl: RangeControl;\n\n private _wasPaused: boolean;\n private _currentTime: number;\n private _duration: number;\n private _playPromise: Promise | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_TOP,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.position = position;\n this.order = order;\n\n this._controlBar = null;\n this._rangeControl = new RangeControl();\n\n this._video = null;\n this._wasPaused = false;\n this._currentTime = 0;\n this._duration = 0;\n this._playPromise = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const element = this.element;\n const rangeControl = this._rangeControl;\n const unavailableClass = controlBar.className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n element.classList.add(unavailableClass);\n return;\n }\n\n element.classList.remove(unavailableClass);\n element.classList.add(controlBar.className.PROGRESS_ROOT);\n viewer.on(EVENTS.RESIZE, this._onResize);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate);\n rangeControl.init(controlBar.className);\n rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n rangeControl.on(CONTROL_EVENTS.CHANGE, this._onControl);\n rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n this._video = video;\n this._currentTime = video.source.currentTime;\n this._duration = video.source.duration;\n this._controlBar = controlBar;\n\n rangeControl.updateStyle(this._currentTime / this._duration);\n }\n\n public destroy(viewer: View360) {\n const video = this._video;\n\n viewer.off(EVENTS.RESIZE, this._onResize);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onTimeUpdate);\n }\n\n this._rangeControl.destroy();\n this._video = null;\n this._playPromise = null;\n }\n\n private _onResize = () => {\n this._rangeControl.resize();\n }\n\n private _onTimeUpdate = () => {\n const video = this._video;\n if (!video) return;\n\n this._currentTime = video.source.currentTime;\n this._rangeControl.updateStyle(this._currentTime / this._duration);\n };\n\n private _onDurationChange = () => {\n const video = this._video;\n if (!video) return;\n\n this._duration = video.source.duration;\n this._rangeControl.updateStyle(this._currentTime / this._duration);\n };\n\n private _onHold = (progress: number) => {\n const video = this._video;\n const controlBar = this._controlBar;\n if (!video || !controlBar) return;\n\n const paused = video.isPaused();\n\n video.source.pause();\n\n const time = video.source.duration * progress;\n video.source.currentTime = time;\n video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time }}));\n\n controlBar.rootEl.classList.add(controlBar.className.FIXED);\n this._wasPaused = !this._playPromise && paused;\n };\n\n private _onControl = (progress: number) => {\n const video = this._video;\n if (!video) return;\n\n const time = video.source.duration * progress;\n video.source.currentTime = time;\n video.source.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time }}));\n };\n\n private _onRelease = () => {\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (video && controlBar) {\n if (!this._wasPaused && !this._playPromise) {\n this._playPromise = video.source.play()\n .catch(() => void 0);\n\n // This should not be chained\n this._playPromise.then(() => {\n this._playPromise = null;\n });\n\n controlBar.rootEl.classList.remove(controlBar.className.FIXED);\n }\n }\n\n this._wasPaused = false;\n };\n}\n\nexport default ProgressBar;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show video play / pause button.\n * @ko 비디오 재생 / 일시정지 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass PlayButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _controlBar: ControlBar | null;\n private _video: TextureVideo | null;\n private _paused: boolean;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n\n this._video = null;\n this._paused = true;\n this._controlBar = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const video = viewer.projection?.getTexture();\n const className = controlBar.className;\n const unavailableClass = className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n element.classList.add(unavailableClass);\n return;\n }\n\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.remove(unavailableClass);\n\n const paused = video.isPaused();\n this._video = video;\n this._paused = paused;\n this._controlBar = controlBar;\n\n if (paused) {\n this._onPause();\n } else {\n this._onPlay();\n }\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onPlay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onPause);\n }\n\n public destroy() {\n const video = this._video;\n const element = this.element;\n\n if (!video) return;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onPlay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onPause);\n\n this._video = null;\n this._paused = true;\n this._controlBar = null;\n }\n\n private _onClick = () => {\n const video = this._video;\n if (!video) return;\n\n if (this._paused) {\n video.source.play();\n } else {\n video.source.pause();\n }\n };\n\n private _onPlay = () => {\n if (!this._controlBar) return;\n\n const element = this.element;\n const className = this._controlBar.className;\n\n element.classList.add(className.PAUSE_BUTTON);\n element.classList.remove(className.PLAY_BUTTON);\n element.title = \"Pause Video\";\n\n this._paused = false;\n };\n\n private _onPause = () => {\n if (!this._controlBar) return;\n\n const element = this.element;\n const className = this._controlBar.className;\n\n element.classList.add(className.PLAY_BUTTON);\n element.classList.remove(className.PAUSE_BUTTON);\n element.title = \"Play Video\";\n\n this._paused = true;\n };\n}\n\nexport default PlayButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport RangeControl from \"./RangeControl\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { EVENTS } from \"../../const/external\";\n\n/**\n * Show video volume control.\n * @ko 비디오 볼륨 조절 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VolumeControl extends ControlBarItem {\n public get element() { return this._rootEl; }\n\n private _controlBar: ControlBar | null;\n private _rootEl: HTMLButtonElement;\n private _buttonEl: HTMLElement;\n private _rangeControl: RangeControl;\n private _video: TextureVideo | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this._controlBar = null;\n this._rangeControl = new RangeControl();\n this._createElements();\n\n this._video = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const root = this._rootEl;\n const button = this._buttonEl;\n const rangeControl = this._rangeControl;\n const className = controlBar.className;\n const unavailableClass = className.UNAVAILABLE;\n\n if (!video || !video.isVideo()) {\n root.classList.add(unavailableClass);\n return;\n }\n\n root.classList.remove(unavailableClass);\n root.classList.add(className.CONTROLS_BUTTON);\n root.classList.add(className.VOLUME_ROOT);\n button.classList.add(className.CONTROLS_BUTTON);\n\n if (video.source.muted) {\n button.classList.add(className.MUTED_BUTTON);\n } else {\n button.classList.add(className.UNMUTED_BUTTON);\n }\n\n viewer.on(EVENTS.RESIZE, this._onResize);\n root.addEventListener(BROWSER.EVENTS.TRANSITION_END, this._onResize);\n button.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_VOLUME_CHANGE, this._onVolumeChange);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_LOADED_DATA, this._updateDisplay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay);\n\n rangeControl.init(className);\n rangeControl.on(CONTROL_EVENTS.INPUT_START, this._onHold);\n rangeControl.on(CONTROL_EVENTS.CHANGE, this._onChange);\n rangeControl.on(CONTROL_EVENTS.INPUT_END, this._onRelease);\n\n this._controlBar = controlBar;\n this._video = video;\n\n this._updateDisplay();\n }\n\n public destroy(viewer: View360) {\n const video = this._video;\n const button = this._buttonEl;\n const root = this._rootEl;\n\n root.className = \"\";\n button.className = \"\";\n\n viewer.off(EVENTS.RESIZE, this._onResize);\n root.removeEventListener(BROWSER.EVENTS.TRANSITION_END, this._onResize);\n button.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_VOLUME_CHANGE, this._onVolumeChange);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_LOADED_DATA, this._updateDisplay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_CAN_PLAYTHROUGH, this._updateDisplay);\n }\n\n this._controlBar = null;\n this._rangeControl.destroy();\n this._video = null;\n }\n\n private _onResize = () => {\n this._rangeControl.resize();\n this._updateDisplay();\n }\n\n private _onClick = () => {\n const video = this._video;\n if (!video || this._rootEl.disabled) return;\n\n video.source.muted = !video.source.muted;\n };\n\n private _onVolumeChange = () => {\n const button = this._buttonEl;\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (!video || !controlBar) return;\n\n const className = controlBar.className;\n\n if (video.source.muted || video.source.volume === 0) {\n button.classList.add(className.MUTED_BUTTON);\n button.classList.remove(className.UNMUTED_BUTTON);\n } else {\n button.classList.add(className.UNMUTED_BUTTON);\n button.classList.remove(className.MUTED_BUTTON);\n }\n\n this._updateDisplay();\n };\n\n private _createElements() {\n const root = document.createElement(BROWSER.EL_BUTTON);\n const buttonEl = document.createElement(BROWSER.EL_DIV);\n\n root.appendChild(this._rangeControl.rootEl);\n root.appendChild(buttonEl);\n root.title = \"Toggle Mute\";\n\n this._rootEl = root;\n this._buttonEl = buttonEl;\n }\n\n private _onHold = (progress: number) => {\n const video = this._video;\n const controlBar = this._controlBar;\n\n if (!video || !controlBar) return;\n\n const className = controlBar.className;\n\n video.source.volume = progress;\n\n this._rootEl.classList.add(className.FIXED);\n controlBar.containerEl.classList.add(className.FIXED);\n\n this._updateDisplay();\n };\n\n private _onChange = (progress: number) => {\n const video = this._video;\n if (!video) return;\n\n video.source.volume = progress;\n if (progress > 0) {\n video.source.muted = false;\n } else {\n video.source.muted = true;\n }\n\n this._updateDisplay();\n };\n\n private _onRelease = () => {\n const controlBar = this._controlBar;\n if (!controlBar) return;\n\n const className = controlBar.className;\n\n this._rootEl.classList.remove(className.FIXED);\n controlBar.containerEl.classList.remove(className.FIXED);\n };\n\n private _updateDisplay = () => {\n const video = this._video;\n const root = this._rootEl;\n if (!video) return;\n\n if (!video.hasAudio()) {\n root.disabled = true;\n return;\n }\n\n root.disabled = false;\n\n const volume = video.source.muted ? 0 : video.source.volume;\n\n this._rangeControl.updateStyle(volume);\n };\n}\n\nexport default VolumeControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport { isFullscreen } from \"../../utils\";\n\n/**\n * Show fullscreen enter / exit button.\n * @ko 풀스크린 진입 / 해제 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass FullscreenButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _controlBar: ControlBar | null;\n private _targetEl: HTMLElement | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n this.element.title = \"Toggle Fullscreen\";\n this._controlBar = null;\n this._targetEl = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n if (!this._fullscreenAvailable()) {\n element.classList.add(className.UNAVAILABLE);\n return;\n }\n\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.remove(className.UNAVAILABLE);\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._addFullscreenHandlers();\n\n if (isFullscreen()) {\n element.classList.add(className.FULLSCREEN_EXIT_BUTTON);\n } else {\n element.classList.add(className.FULLSCREEN_BUTTON);\n }\n\n this._controlBar = controlBar;\n this._targetEl = viewer.rootEl;\n }\n\n public destroy() {\n const element = this.element;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._removeFullscreenHandlers();\n\n this._controlBar = null;\n this._targetEl = null;\n }\n\n private _onClick = () => {\n const target = this._targetEl;\n if (!target) return;\n\n if (isFullscreen()) {\n this._exitFullscreen();\n } else {\n this._requestFullscreen(target);\n }\n };\n\n private _fullscreenAvailable() {\n return BROWSER.FULLSCREEN_REQUEST.some(key => !!document[key]);\n }\n\n private _requestFullscreen(el: HTMLElement) {\n for (const key of BROWSER.FULLSCREEN_REQUEST) {\n const request = el[key];\n if (request) {\n request.call(el);\n return;\n }\n }\n }\n\n private _exitFullscreen() {\n for (const key of BROWSER.FULLSCREEN_EXIT) {\n const exit = document[key];\n\n if (exit) {\n exit.call(document);\n return;\n }\n }\n }\n\n private _addFullscreenHandlers() {\n BROWSER.FULLSCREEN_CHANGE.forEach(evtName => {\n document.addEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _removeFullscreenHandlers() {\n BROWSER.FULLSCREEN_CHANGE.forEach(evtName => {\n document.removeEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _onFullscreenChange = () => {\n const element = this.element;\n const controlBar = this._controlBar;\n\n if (!controlBar) return;\n\n const className = controlBar.className;\n\n if (isFullscreen()) {\n element.classList.add(className.FULLSCREEN_EXIT_BUTTON);\n element.classList.remove(className.FULLSCREEN_BUTTON);\n } else {\n element.classList.add(className.FULLSCREEN_BUTTON);\n element.classList.remove(className.FULLSCREEN_EXIT_BUTTON);\n }\n };\n}\n\nexport default FullscreenButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\n\n/**\n * Show video current / total time.\n * @ko 비디오의 현재 / 총 재생시간을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VideoTime extends ControlBarItem {\n public readonly element: HTMLElement;\n private _video: TextureVideo | null;\n private _currentTime: number;\n private _duration: number;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_LEFT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n\n this._video = null;\n this._currentTime = 0;\n this._duration = 0;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const video = viewer.projection?.getTexture();\n const element = this.element;\n const className = controlBar.className;\n\n if (!video || !video.isVideo()) {\n element.classList.add(className.UNAVAILABLE);\n return;\n }\n\n element.classList.add(className.VIDEO_TIME_DISPLAY);\n element.classList.remove(className.UNAVAILABLE);\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.addEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange);\n\n this._video = video;\n this._currentTime = video.source.currentTime;\n this._duration = video.source.duration;\n\n this._updateDisplay();\n }\n\n public destroy() {\n const video = this._video;\n\n if (!video) return;\n\n this.element.className = \"\";\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_TIME_UPDATE, this._onTimeUpdate);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_DURATION_CHANGE, this._onDurationChange);\n video.source.removeEventListener(VIDEO_TIME_CHANGE_EVENT, this._onCustomTimeChange);\n\n this._video = null;\n }\n\n private _onTimeUpdate = () => {\n const video = this._video;\n if (!video) return;\n\n this._currentTime = video.source.currentTime;\n this._updateDisplay();\n };\n\n private _onDurationChange = () => {\n const video = this._video;\n if (!video) return;\n\n this._duration = video.source.duration;\n this._updateDisplay();\n };\n\n private _onCustomTimeChange = (evt: CustomEvent<{ time: number }>) => {\n this._currentTime = evt.detail.time;\n this._updateDisplay();\n };\n\n private _updateDisplay() {\n const time = this._currentTime;\n const timeMinute = Math.floor(time / 60);\n const timeSeconds = Math.floor(time - timeMinute * 60);\n const timeSecondsFormatted = timeSeconds < 10 ? `0${timeSeconds}` : timeSeconds;\n\n const duration = this._duration;\n const durationMinute = Math.floor(duration / 60);\n const durationSeconds = Math.floor(duration - durationMinute * 60);\n const durationSecondsFormatted = durationSeconds < 10 ? `0${durationSeconds}` : durationSeconds;\n\n this.element.innerText = `${timeMinute}:${timeSecondsFormatted} / ${durationMinute}:${durationSecondsFormatted}`;\n }\n}\n\nexport default VideoTime;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport { circulate, getObjectOption } from \"../../utils\";\nimport * as BROWSER from \"../../const/browser\";\nimport { EVENTS } from \"../../const/external\";\nimport { SVG_NAMESPACE } from \"../../const/internal\";\n\n/**\n * Options for {@link PieView}\n * @ko {@link PieView}용 옵션들\n * @category Plugin\n */\nexport interface PieViewOptions extends ControlBarItemOptions {\n /**\n * @copy PieView#resetCamera\n */\n resetCamera: boolean | Partial<{\n yaw: number;\n pitch: number;\n zoom: number;\n duration: number;\n easing: (x: number) => number;\n }>;\n}\n\n/**\n * Show camera direction/fov indicator.\n * @ko 카메라가 향하는 방향 및 FOV를 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass PieView extends ControlBarItem {\n public readonly element: HTMLElement;\n\n /**\n * Set rotation to reset camera to when PieView is clicked.\n * `false` will disable this value, and `true` will enable with default options.\n * @ko PieView가 클릭되었을 때 카메라를 리셋할 방향을 지정합니다.\n * `false`일 경우 이 동작을 비활성화하며, `true`일 경우 기본값을 사용합니다.\n * @since 4.0.0\n */\n public resetCamera: PieViewOptions[\"resetCamera\"];\n\n private _viewer: View360 | null;\n private _piePathEl: SVGPathElement;\n private _rangeCircleEl: SVGCircleElement;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n resetCamera = true,\n position = CONTROL_BAR_ITEM_POSITION.TOP_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n this.element.title = \"Reset view\";\n this.resetCamera = resetCamera;\n this._createPieElements();\n this._viewer = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n\n if (!viewer.initialized) {\n viewer.once(EVENTS.READY, this._updatePie);\n } else {\n this._updatePie({ target: viewer });\n }\n\n const rootClass = controlBar.className.PIEVIEW_ROOT;\n element.classList.add(rootClass);\n\n if (this.resetCamera) {\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n }\n\n viewer.on(EVENTS.VIEW_CHANGE, this._updatePie);\n\n this._viewer = viewer;\n }\n\n public destroy(viewer: View360) {\n const element = this.element;\n\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.className = \"\";\n viewer.off(EVENTS.READY, this._updatePie);\n viewer.off(EVENTS.VIEW_CHANGE, this._updatePie);\n\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n const resetCamera = this.resetCamera;\n\n if (!viewer || !resetCamera) return;\n\n const {\n yaw = viewer.initialYaw,\n pitch = viewer.initialPitch,\n zoom = viewer.initialZoom,\n duration = 500\n } = getObjectOption(resetCamera);\n\n viewer.camera.animateTo({\n yaw,\n pitch,\n zoom,\n duration\n });\n };\n\n private _createPieElements() {\n const root = this.element;\n const pieSVG = document.createElementNS(SVG_NAMESPACE, \"svg\");\n pieSVG.setAttribute(\"viewBox\", \"0 0 48 48\");\n pieSVG.setAttribute(\"width\", \"100%\");\n pieSVG.setAttribute(\"height\", \"100%\");\n\n const piePath = document.createElementNS(SVG_NAMESPACE, \"circle\");\n\n piePath.setAttribute(\"stroke\", \"currentColor\");\n piePath.setAttribute(\"fill\", \"transparent\");\n piePath.setAttribute(\"cx\", \"24\");\n piePath.setAttribute(\"cy\", \"24\");\n piePath.setAttribute(\"r\", \"12\");\n piePath.setAttribute(\"stroke-width\", \"24\");\n pieSVG.appendChild(piePath);\n\n const rangeCircle = document.createElementNS(SVG_NAMESPACE, \"circle\");\n\n rangeCircle.setAttribute(\"stroke\", \"currentColor\");\n rangeCircle.setAttribute(\"fill\", \"transparent\");\n rangeCircle.setAttribute(\"cx\", \"24\");\n rangeCircle.setAttribute(\"cy\", \"24\");\n rangeCircle.setAttribute(\"r\", \"22.5\");\n rangeCircle.setAttribute(\"stroke-width\", \"3\");\n pieSVG.appendChild(rangeCircle);\n\n root.appendChild(pieSVG);\n\n this._piePathEl = piePath;\n this._rangeCircleEl = rangeCircle;\n }\n\n private _updatePie = ({ target: viewer }: { target: View360 }) => {\n const piePath = this._piePathEl;\n const rangeCircle = this._rangeCircleEl;\n const camera = viewer.camera;\n const fov = camera.getHorizontalFov();\n const yawRange = camera.getYawRange(camera.zoom);\n const halfFov = fov * 0.5;\n\n const pieRadius = 24 * Math.PI;\n const pieDeg = pieRadius * fov / 360;\n const pieOffset = pieRadius * (camera.yaw + halfFov + 90) / 360;\n\n piePath.setAttribute(\"stroke-dasharray\", `${pieDeg} ${pieRadius - pieDeg}`);\n piePath.setAttribute(\"stroke-dashoffset\", `${pieOffset}`);\n\n if (isFinite(yawRange.min) && isFinite(yawRange.max)) {\n const radius = 45 * Math.PI; // 2 * PI * r\n const min = (circulate(yawRange.min, -180, 180) - halfFov) / 360;\n const max = (circulate(yawRange.max, -180, 180) + halfFov) / 360;\n\n const rangeDiff = radius * Math.abs(max - min);\n const offset = -radius * (min - 0.25);\n\n rangeCircle.setAttribute(\"stroke-dasharray\", `${rangeDiff} ${radius - rangeDiff}`);\n rangeCircle.setAttribute(\"stroke-dashoffset\", `${offset}`);\n } else {\n rangeCircle.setAttribute(\"stroke-dasharray\", \"\");\n rangeCircle.setAttribute(\"stroke-dashoffset\", \"\");\n }\n };\n}\n\nexport default PieView;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\n\n/**\n * Show VR enter button.\n * @ko VR 진입 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass VRButton extends ControlBarItem {\n public readonly element: HTMLElement;\n\n private _viewer: View360 | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_BUTTON);\n this.element.title = \"Enter VR\";\n this._viewer = null;\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n element.classList.add(className.UNAVAILABLE);\n element.classList.add(className.VR_BUTTON);\n element.classList.add(className.CONTROLS_BUTTON);\n\n viewer.vr.isAvailable()\n .then(available => {\n if (available) {\n element.classList.remove(className.UNAVAILABLE);\n }\n });\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n this._viewer = viewer;\n }\n\n public destroy() {\n const element = this.element;\n\n element.className = \"\";\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n if (!viewer) return;\n\n viewer.vr.enter();\n };\n}\n\nexport default VRButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport { CONTROL_BAR_ITEM_POSITION } from \"./const\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport GyroControl from \"../../control/GyroControl\";\nimport { CONTROL_EVENTS } from \"../../const/internal\";\nimport { sensorCanBeEnabledIOS } from \"../../utils\";\n\n/**\n * Show gyroscope control enable / disable button\n * @ko 자이로스코프 컨트롤 활성화 / 비활성화 버튼을 표시합니다.\n * @category Plugin\n * @group ControlBar\n * @since 4.0.0\n */\nclass GyroButton extends ControlBarItem {\n public readonly element: HTMLElement;\n private _viewer: View360 | null;\n private _controlBar: ControlBar | null;\n\n /**\n * Create a new instance.\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n position = CONTROL_BAR_ITEM_POSITION.MAIN_RIGHT,\n order = 9999\n }: Partial = {}) {\n super({\n position,\n order\n });\n\n this.element = document.createElement(BROWSER.EL_DIV);\n this.element.title = \"Toggle gyroscope control\";\n }\n\n public init(viewer: View360, controlBar: ControlBar) {\n const element = this.element;\n const className = controlBar.className;\n\n element.addEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.classList.add(className.CONTROLS_BUTTON);\n element.classList.add(className.UNAVAILABLE);\n\n const enableButton = () => {\n element.classList.remove(className.UNAVAILABLE);\n viewer.control.gyro.on(CONTROL_EVENTS.ENABLE, this._updateStyle);\n viewer.control.gyro.on(CONTROL_EVENTS.DISABLE, this._updateStyle);\n };\n\n if (sensorCanBeEnabledIOS()) {\n enableButton();\n } else {\n GyroControl.isAvailable().then(available => {\n if (!available) return;\n enableButton();\n });\n }\n\n this._controlBar = controlBar;\n this._viewer = viewer;\n this._updateStyle();\n }\n\n public destroy(viewer: View360) {\n const element = this.element;\n\n viewer.control.gyro.off(CONTROL_EVENTS.ENABLE, this._updateStyle);\n viewer.control.gyro.off(CONTROL_EVENTS.DISABLE, this._updateStyle);\n element.removeEventListener(BROWSER.EVENTS.CLICK, this._onClick);\n element.className = \"\";\n\n this._controlBar = null;\n this._viewer = null;\n }\n\n private _onClick = () => {\n const viewer = this._viewer;\n const controlBar = this._controlBar;\n\n if (!viewer || !controlBar) return;\n\n const gyroControl = viewer.control.gyro;\n if (gyroControl.enabled) {\n gyroControl.disable();\n } else {\n GyroControl.requestSensorPermission().then(available => {\n if (available) {\n gyroControl.enable();\n } else {\n this.element.classList.add(controlBar.className.UNAVAILABLE);\n }\n });\n }\n };\n\n private _updateStyle = () => {\n const element = this.element;\n const viewer = this._viewer;\n const controlBar = this._controlBar;\n\n if (!viewer || !controlBar) return;\n\n const gyroControl = viewer.control.gyro;\n const className = controlBar.className;\n\n if (gyroControl.enabled) {\n element.classList.add(className.GYRO_ENABLED);\n element.classList.remove(className.GYRO_DISABLED);\n } else {\n element.classList.add(className.GYRO_DISABLED);\n element.classList.remove(className.GYRO_ENABLED);\n }\n };\n}\n\nexport default GyroButton;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBar from \"./ControlBar\";\nimport View360 from \"../../View360\";\nimport * as BROWSER from \"../../const/browser\";\nimport { FULLSCREEN_CHANGE } from \"../../const/browser\";\nimport TextureVideo from \"../../texture/TextureVideo\";\nimport { isFullscreen } from \"../../utils\";\n\n/**\n * Options for ControlBar's {@link ControlBarOptions#autoHide}\n * @ko ControlBar의 {@link ControlBarOptions#autoHide}용 옵션\n * @category Plugin\n * @since 4.0.0\n */\nexport interface AutoHideOptions {\n /**\n * Initial delay before the control bar hides (ms)\n * @ko 컨트롤바가 처음으로 표시되고 사라지기까지 걸리는 시간 (ms)\n * @default 3000\n * @since 4.0.0\n */\n initialDelay: number;\n /**\n * Delay time before hiding the control bar after mouse leave (ms)\n * @ko 마우스가 컨트롤바 영역을 떠난 뒤 컨트롤바가 사라지기까지 걸리는 시간 (ms)\n * @default 0\n * @since 4.0.0\n */\n delay: number;\n /**\n * Delay time before hiding the control bar becomes active, like touch on mobile device or mouse move in fullscreen mode (ms)\n * @ko 모바일이나 풀스크린 환경 등에서 사용자 입력이 없을 때 컨트롤바가 사라지기까지 걸리는 시간 (ms)\n * @default 3000\n * @since 4.0.0\n */\n idleDelay: number;\n}\n\nclass AutoHide {\n private _initialDelay: AutoHideOptions[\"initialDelay\"];\n private _delay: AutoHideOptions[\"delay\"];\n private _idleDelay: AutoHideOptions[\"idleDelay\"];\n\n private _controlBar: ControlBar;\n private _timer: number;\n private _isGrabbing: boolean;\n private _isCursorInside: boolean;\n private _isFullscreen: boolean;\n private _targetEl: HTMLElement | null;\n private _video: TextureVideo | null;\n\n public get enabled() { return !!this._targetEl; }\n public get hidden() { return this._controlBar.containerEl.classList.contains(this._hiddenClass); }\n\n private get _hiddenClass() { return this._controlBar.className.HIDDEN; }\n private get _fixedClass() { return this._controlBar.className.FIXED; }\n\n public constructor(controlBar: ControlBar, {\n initialDelay = 3000,\n delay = 0,\n idleDelay: activationDelay = 3000\n }: Partial) {\n this._controlBar = controlBar;\n this._initialDelay = initialDelay;\n this._delay = delay;\n this._idleDelay = activationDelay;\n this._timer = -1;\n this._isCursorInside = false;\n this._isGrabbing = false;\n this._isFullscreen = false;\n this._video = null;\n this._targetEl = null;\n }\n\n public enable(viewer: View360) {\n if (this._targetEl) {\n this.disable(viewer);\n }\n\n const initialDelay = this._initialDelay;\n const root = viewer.rootEl;\n\n this._targetEl = viewer.rootEl;\n this._timer = window.setTimeout(() => {\n this.hide();\n }, initialDelay);\n\n root.addEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onHold);\n root.addEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter);\n root.addEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove);\n root.addEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave);\n this._addFullscreenHandlers();\n\n const video = viewer.projection?.getTexture();\n if (!video || !video.isVideo()) {\n return;\n }\n\n if (video.isPaused()) {\n this._controlBar.containerEl.classList.add(this._fixedClass);\n }\n\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onVideoPlay);\n video.source.addEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onVideoPause);\n\n this._video = video;\n }\n\n public disable(viewer: View360) {\n if (!this._targetEl) return;\n\n const controlBar = this._controlBar;\n const root = viewer.rootEl;\n const video = this._video;\n\n root.removeEventListener(BROWSER.EVENTS.MOUSE_DOWN, this._onHold);\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_ENTER, this._onMouseEnter);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_MOVE, this._onMouseMove);\n root.removeEventListener(BROWSER.EVENTS.MOUSE_LEAVE, this._onMouseLeave);\n this._removeFullscreenHandlers();\n\n window.clearTimeout(this._timer);\n controlBar.containerEl.classList.remove(this._fixedClass);\n\n if (video) {\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PLAY, this._onVideoPlay);\n video.source.removeEventListener(BROWSER.EVENTS.VIDEO_PAUSE, this._onVideoPause);\n }\n\n this._isCursorInside = false;\n this._isGrabbing = false;\n this._video = null;\n this._targetEl = null;\n }\n\n public show() {\n this._clearHideTimer();\n this._controlBar.containerEl.classList.remove(this._hiddenClass);\n }\n\n public showTemporaliy() {\n this.show();\n this._hideAfterDelay(this._idleDelay);\n }\n\n public hide() {\n this._clearHideTimer();\n this._controlBar.containerEl.classList.add(this._hiddenClass);\n }\n\n private _clearHideTimer() {\n if (this._timer) {\n window.clearTimeout(this._timer);\n this._timer = -1;\n }\n }\n\n private _hideAfterDelay(delay = this._delay) {\n if (this._isGrabbing || (!this._isFullscreen && this._isCursorInside)) return;\n\n this._clearHideTimer();\n if (delay <= 0) {\n this.hide();\n } else {\n this._timer = window.setTimeout(() => {\n this.hide();\n }, delay);\n }\n }\n\n private _onMouseEnter = () => {\n this._isCursorInside = true;\n this.show();\n };\n\n private _onMouseLeave = () => {\n this._isCursorInside = false;\n this._hideAfterDelay();\n };\n\n private _onMouseMove = () => {\n if (!this._isFullscreen) return;\n\n this.showTemporaliy();\n }\n\n private _onHold = (evt: PointerEvent) => {\n this._isGrabbing = true;\n\n if (evt.pointerType === \"mouse\") {\n this._isCursorInside = true;\n }\n\n window.addEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n\n this.show();\n };\n\n private _onRelease = () => {\n this._isGrabbing = false;\n\n window.removeEventListener(BROWSER.EVENTS.MOUSE_UP, this._onRelease);\n\n this._hideAfterDelay();\n };\n\n private _onVideoPlay = () => {\n const root = this._targetEl;\n if (!root) return;\n\n this._controlBar.containerEl.classList.remove(this._fixedClass);\n };\n\n private _onVideoPause = () => {\n const root = this._targetEl;\n if (!root) return;\n\n this._controlBar.containerEl.classList.add(this._fixedClass);\n };\n\n private _addFullscreenHandlers() {\n FULLSCREEN_CHANGE.forEach(evtName => {\n document.addEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _removeFullscreenHandlers() {\n FULLSCREEN_CHANGE.forEach(evtName => {\n document.removeEventListener(evtName, this._onFullscreenChange);\n });\n }\n\n private _onFullscreenChange = () => {\n this._isFullscreen = isFullscreen();\n\n if (this._isFullscreen) {\n this._hideAfterDelay();\n }\n };\n}\n\nexport default AutoHide;\n","import TextureVideo from \"../../texture/TextureVideo\";\nimport * as BROWSER from \"../../const/browser\";\nimport { clamp } from \"../../utils\";\nimport { VIDEO_TIME_CHANGE_EVENT } from \"../../const/internal\";\n\nclass VideoControl {\n private _video: TextureVideo | null;\n\n public enable(root: HTMLElement, video: TextureVideo) {\n this._video = video;\n // capture is needed for resolving conflict with keyboard control\n root.addEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown, true);\n }\n\n public disable(root: HTMLElement) {\n this._video = null;\n root.removeEventListener(BROWSER.EVENTS.KEY_DOWN, this._onKeyDown, true);\n }\n\n private _onKeyDown = (event: KeyboardEvent) => {\n const video = this._video;\n if (!video) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n const videoEl = video.source;\n const keyPressed = event.keyCode != null\n ? BROWSER.DIRECTION_KEY_CODE[event.keyCode]\n : BROWSER.DIRECTION_KEY_NAME[event.key];\n\n switch (keyPressed) {\n case \"LEFT\":\n case \"RIGHT\":\n return this._changeVideoTime(videoEl, keyPressed === \"RIGHT\");\n case \"UP\":\n case \"DOWN\":\n return this._changeVideoVolume(videoEl, keyPressed === \"UP\");\n }\n\n const spacePressed = event.keyCode === BROWSER.SPACE_KEY_CODE || event.key === BROWSER.SPACE_KEY_NAME;\n if (spacePressed) {\n this._toggleVideo(video);\n }\n }\n\n private _changeVideoTime(video: HTMLVideoElement, forward: boolean) {\n const delta = forward ? 5 : -5;\n\n video.currentTime += delta;\n video.dispatchEvent(new CustomEvent(VIDEO_TIME_CHANGE_EVENT, { detail: { time: video.currentTime }}));\n }\n\n private _changeVideoVolume(video: HTMLVideoElement, increase: boolean) {\n const delta = increase ? 0.1 : -0.1;\n\n if (video.muted) {\n video.volume = clamp(delta, 0, 1);\n } else {\n video.volume = clamp(video.volume + delta, 0, 1);\n }\n\n if (video.volume > 0) {\n video.muted = false;\n } else {\n video.muted = true;\n }\n }\n\n private _toggleVideo(video: TextureVideo) {\n if (video.isPaused()) {\n video.source.play();\n } else {\n video.source.pause();\n }\n }\n}\n\nexport default VideoControl;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport ControlBarItem, { ControlBarItemOptions } from \"./ControlBarItem\";\nimport ProgressBar from \"./ProgressBar\";\nimport PlayButton from \"./PlayButton\";\nimport VolumeControl from \"./VolumeControl\";\nimport FullscreenButton from \"./FullscreenButton\";\nimport VideoTime from \"./VideoTime\";\nimport PieView, { PieViewOptions } from \"./PieView\";\nimport VRButton from \"./VRButton\";\nimport GyroButton from \"./GyroButton\";\nimport AutoHide, { AutoHideOptions } from \"./AutoHide\";\nimport VideoControl from \"./VideoControl\";\nimport View360, { View360Events } from \"../../View360\";\nimport View360Plugin from \"../View360Plugin\";\nimport { EVENTS } from \"../../const/external\";\nimport { createElement, findIndex, getObjectOption } from \"../../utils\";\nimport { ValueOf } from \"../../type/utils\";\nimport { StaticClickEvent } from \"../../type/events\";\nimport { CONTROL_BAR_DEFAULT_CLASS, CONTROL_BAR_ITEM_POSITION } from \"./const\";\n\n/**\n * Options for {@link ControlBar}\n * @ko {@link ControlBar}용 옵션들\n * @category Plugin\n * @since 4.0.0\n */\nexport interface ControlBarOptions {\n /**\n * @copy ControlBar#autoHide\n */\n autoHide: boolean | Partial;\n /**\n * @copy ControlBar#showBackground\n */\n showBackground: boolean;\n /**\n * @copy ControlBar#clickToPlay\n */\n clickToPlay: boolean;\n /**\n * @copy ControlBar#keyboardControls\n */\n keyboardControls: boolean;\n /**\n * @copy ControlBar#progressBar\n */\n progressBar: boolean | Partial;\n /**\n * @copy ControlBar#playButton\n */\n playButton: boolean | Partial;\n /**\n * @copy ControlBar#volumeButton\n */\n volumeButton: boolean | Partial;\n /**\n * @copy ControlBar#fullscreenButton\n */\n fullscreenButton: boolean | Partial;\n /**\n * @copy ControlBar#videoTime\n */\n videoTime: boolean | Partial;\n /**\n * @copy ControlBar#pieView\n */\n pieView: boolean | Partial;\n /**\n * @copy ControlBar#vrButton\n */\n vrButton: boolean | Partial;\n /**\n * @copy ControlBar#gyroButton\n */\n gyroButton: boolean | Partial;\n /**\n * @copy ControlBar#className\n */\n className: Partial<{ -readonly [key in keyof typeof ControlBar.DEFAULT_CLASS]: string }>;\n /**\n * @copy ControlBar#customItems\n */\n customItems: ControlBarItem[];\n}\n\n/**\n * A plugin that displays extra buttons & controls that controls {@link View360}.\n * @ko {@link View360}에 부가적인 버튼과 컨트롤을 추가해주는 플러그인.\n * @category Plugin\n * @since 4.0.0\n */\nclass ControlBar implements View360Plugin {\n /**\n * Default class names that ControlBar uses\n * @ko ControlBar가 사용하는 디폴트 클래스 이름들\n * @since 4.0.0\n */\n public static readonly DEFAULT_CLASS = CONTROL_BAR_DEFAULT_CLASS;\n\n /**\n * Constants for {@link ControlBarItemOptions#position}\n * @ko {@link ControlBarItemOptions#position}에 사용 가능한 값들\n */\n public static readonly POSITION = CONTROL_BAR_ITEM_POSITION;\n\n /**\n * Automatically hide control bar on video plays.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 재생시 자동으로 컨트롤바를 숨깁니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly autoHide?: ControlBarOptions[\"autoHide\"];\n /**\n * Show background element.\n * @ko 배경 엘리먼트를 표시합니다.\n * @since 4.0.0\n */\n public readonly showBackground?: ControlBarOptions[\"showBackground\"];\n /**\n * Whether to play / pause video on canvas click\n * @ko 캔버스 클릭시에 비디오를 재생 / 일시정지 토글합니다.\n * @since 4.0.0\n */\n public readonly clickToPlay: ControlBarOptions[\"clickToPlay\"];\n /**\n * Enable keyboard controls for video.\n * Pressing up / down arrow will control video volume, and pressing left / right arrow will control video time.\n * @ko 비디오 키보드 컨트롤을 활성화합니다.\n * 위 / 아래 화살표키를 누를 시 비디오 볼륨을, 왼쪽 / 오른쪽 화살표키를 누를 시 비디오 시간을 조정합니다.\n * @since 4.0.0\n */\n public readonly keyboardControls: ControlBarOptions[\"keyboardControls\"];\n /**\n * Show video progress bar.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 프로그레스 바를 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly progressBar: ControlBarOptions[\"progressBar\"];\n /**\n * Show video play / pause button.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 재생 / 일시정지 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly playButton: ControlBarOptions[\"playButton\"];\n /**\n * Show video volume control button.\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오 볼륨 조절 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly volumeButton: ControlBarOptions[\"volumeButton\"];\n /**\n * Show fullscreen button.\n * `true` to enable with default values, `false` to disable.\n * @ko 풀스크린 진입 / 해제 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly fullscreenButton: ControlBarOptions[\"fullscreenButton\"];\n /**\n * Show video current / total time\n * `true` to enable with default values, `false` to disable.\n * @ko 비디오의 현재 시간 / 총 시간을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly videoTime: ControlBarOptions[\"videoTime\"];\n /**\n * Show camera pie view.\n * `true` to enable with default values, `false` to disable.\n * @ko 현재 카메라가 가리키는 방향을 표시하는 파이 뷰를 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly pieView: ControlBarOptions[\"pieView\"];\n /**\n * Show VR button.\n * `true` to enable with default values, `false` to disable.\n * @ko VR 진입버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly vrButton: ControlBarOptions[\"vrButton\"];\n /**\n * Show gyroscope control enable / disable button.\n * `true` to enable with default values, `false` to disable.\n * @ko 자이로스코프 컨트롤을 활성화 / 비활성화하는 버튼을 표시합니다.\n * `true`일 경우 기본값을 적용하고, `false`일 경우 비활성화합니다.\n * @since 4.0.0\n */\n public readonly gyroButton: ControlBarOptions[\"gyroButton\"];\n /**\n * Override default class names.\n * @ko 디폴트 클래스 이름들을 오버라이드합니다.\n * @since 4.0.0\n */\n public readonly className: Required;\n\n /**\n * Root element of the control bar\n * @ko 컨트롤바의 루트 엘리먼트\n * @since 4.0.0\n */\n public get rootEl() { return this._rootEl; }\n /**\n * Container element of the control bar\n * @ko 컨트롤바의 컨테이너 엘리먼트\n * @since 4.0.0\n */\n public get containerEl() { return this._containerEl; }\n /**\n * Background element of the control bar\n * @ko 컨트롤바의 배경 엘리먼트\n * @since 4.0.0\n */\n public get backgroundEl() { return this._bgEl; }\n /**\n * Control bar's default items created by {@link ControlBarOptions}\n * @ko 주어진 {@link ControlBarOptions}에 의해 생성된 디폴트 아이템들\n * @since 4.0.0\n */\n public get items() { return this._items; }\n /**\n * Custom control bar items\n * @ko 커스텀 컨트롤바 아이템들을 추가합니다.\n * @since 4.0.0\n */\n public get customItems() { return this._customItems; }\n\n private _rootEl: HTMLElement;\n private _containerEl: HTMLElement;\n private _bgEl: HTMLElement;\n private _wrapperEl: Record, HTMLElement>;\n private _items: Record, ControlBarItem[]>;\n private _customItems: ControlBarItem[];\n private _autoHider: AutoHide;\n private _videoControl: VideoControl;\n\n /**\n * Create new instance of ControlBar.\n * @ko ControlBar의 새 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n autoHide,\n showBackground,\n clickToPlay = true,\n keyboardControls = true,\n progressBar = true,\n playButton = true,\n volumeButton = true,\n fullscreenButton = true,\n videoTime = true,\n pieView = true,\n vrButton = true,\n gyroButton = true,\n className = {},\n customItems = []\n }: Partial = {}) {\n this.autoHide = autoHide;\n this.showBackground = showBackground;\n this.clickToPlay = clickToPlay;\n this.keyboardControls = keyboardControls;\n this.progressBar = progressBar;\n this.playButton = playButton;\n this.volumeButton = volumeButton;\n this.fullscreenButton = fullscreenButton;\n this.videoTime = videoTime;\n this.pieView = pieView;\n this.vrButton = vrButton;\n this.gyroButton = gyroButton;\n this.className = {\n ...ControlBar.DEFAULT_CLASS,\n ...className\n };\n\n const rootClass = className.CONTROLS_ROOT ?? ControlBar.DEFAULT_CLASS.CONTROLS_ROOT;\n\n this._rootEl = createElement(rootClass);\n this._createPositionWrappers();\n this._items = Object.keys(ControlBar.POSITION).reduce((items, key) => {\n items[ControlBar.POSITION[key]] = [];\n return items;\n }, {}) as Record, ControlBarItem[]>;\n this._customItems = customItems;\n this._autoHider = new AutoHide(this, getObjectOption(autoHide));\n this._videoControl = new VideoControl();\n\n customItems.forEach(item => {\n this._items[item.position].push(item);\n });\n }\n\n public init(viewer: View360) {\n const panoRoot = viewer.rootEl;\n const controlsRoot = this._rootEl;\n const defaultItems = this._createDefaultItems();\n\n this._updateBackground(viewer);\n this._updateAutoHide(viewer);\n this._updateKeyboardHandler(viewer);\n\n panoRoot.appendChild(controlsRoot);\n this._addItem(viewer, defaultItems);\n this._addItem(viewer, this._customItems);\n\n viewer.on(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad);\n viewer.on(EVENTS.STATIC_CLICK, this._onStaticClick);\n }\n\n public destroy(viewer: View360): void {\n // Remove controls root from pano root\n const panoRoot = viewer.rootEl;\n const controlsRoot = this._rootEl;\n const items = this._items;\n\n if (controlsRoot.parentElement === panoRoot) {\n panoRoot.removeChild(controlsRoot);\n }\n\n Object.keys(items).forEach((key: ValueOf) => {\n const category = items[key];\n\n category.forEach(item => {\n item.destroy(viewer, this);\n });\n\n items[key] = [];\n });\n\n this._clearItemElements();\n this._autoHider.disable(viewer);\n this._videoControl.disable(panoRoot);\n\n viewer.off(EVENTS.PROJECTION_CHANGE, this._onNewSrcLoad);\n viewer.off(EVENTS.STATIC_CLICK, this._onStaticClick);\n }\n\n private _addItem(viewer: View360, items: ControlBarItem[]) {\n for (const item of items) {\n const category = this._items[item.position];\n const wrapper = this._wrapperEl[item.position];\n\n const nextSiblingIndex = findIndex(category, sibling => sibling.order > item.order);\n\n if (nextSiblingIndex >= 0) {\n const nextSibling = category[nextSiblingIndex].element;\n category.splice(nextSiblingIndex, 0, item);\n wrapper.insertBefore(item.element, nextSibling);\n } else {\n category.push(item);\n wrapper.appendChild(item.element);\n }\n\n item.init(viewer, this);\n }\n }\n\n private _createPositionWrappers() {\n const className = {\n ...ControlBar.DEFAULT_CLASS,\n ...this.className\n };\n const rootEl = this._rootEl;\n\n // BG & FLOATING CONTROLS\n const backgroundEl = createElement(className.CONTROLS_BG);\n const floatLeftEl = createElement(className.CONTROLS_FLOAT_LEFT);\n const floatRightEl = createElement(className.CONTROLS_FLOAT_RIGHT);\n\n rootEl.appendChild(floatLeftEl);\n rootEl.appendChild(floatRightEl);\n\n // BOTTOM CONTROLS\n const container = createElement(className.CONTROLS_MAIN);\n const topWrapper = createElement(className.CONTROLS_TOP);\n const bottomWrapper = createElement(className.CONTROLS_BOTTOM);\n const midWrapper = createElement(className.CONTROLS_MID);\n const leftControlsWrapper = createElement(className.CONTROLS_LEFT);\n const rightControlsWrapper = createElement(className.CONTROLS_RIGHT);\n\n midWrapper.appendChild(leftControlsWrapper);\n midWrapper.appendChild(rightControlsWrapper);\n container.appendChild(backgroundEl);\n container.appendChild(topWrapper);\n container.appendChild(midWrapper);\n container.appendChild(bottomWrapper);\n rootEl.appendChild(container);\n\n this._bgEl = backgroundEl;\n this._containerEl = container;\n this._wrapperEl = {\n [ControlBar.POSITION.MAIN_TOP]: topWrapper,\n [ControlBar.POSITION.MAIN_LEFT]: leftControlsWrapper,\n [ControlBar.POSITION.MAIN_RIGHT]: rightControlsWrapper,\n [ControlBar.POSITION.MAIN_BOTTOM]: bottomWrapper,\n [ControlBar.POSITION.TOP_LEFT]: floatLeftEl,\n [ControlBar.POSITION.TOP_RIGHT]: floatRightEl\n };\n }\n\n private _clearItemElements() {\n const wrappers = Object.keys(ControlBar.POSITION).map(key => ControlBar.POSITION[key]);\n\n // Remove all elements inside wrappers\n wrappers.forEach(wrapper => {\n while (wrapper.firstChild) {\n wrapper.removeChild(wrapper.firstChild);\n }\n });\n }\n\n private _onStaticClick = ({ target: viewer, isTouch }: StaticClickEvent) => {\n const autoHider = this._autoHider;\n\n if (isTouch) {\n if (!autoHider.enabled) return;\n\n if (autoHider.hidden) {\n autoHider.showTemporaliy();\n } else {\n autoHider.hide();\n }\n } else {\n if (!this.clickToPlay) return;\n\n const video = viewer.projection?.getTexture();\n if (!video || !video.isVideo()) return;\n\n if (video.isPaused()) {\n video.source.play();\n } else {\n video.source.pause();\n }\n }\n };\n\n private _onNewSrcLoad = ({ target: viewer }: View360Events[\"projectionChange\"]) => {\n const items = this._items;\n\n this._updateBackground(viewer);\n this._updateAutoHide(viewer);\n this._updateKeyboardHandler(viewer);\n\n Object.keys(items).forEach((key: ValueOf) => {\n const category = items[key];\n\n category.forEach(item => {\n item.destroy(viewer, this);\n item.init(viewer, this);\n });\n });\n };\n\n private _updateAutoHide(viewer: View360) {\n const autoHide = this.autoHide;\n const autoHider = this._autoHider;\n\n if (autoHide != null) {\n if (autoHide) {\n autoHider.enable(viewer);\n } else {\n autoHider.disable(viewer);\n }\n } else {\n // Automatically choose whether to show background by content type\n const texture = viewer.projection?.getTexture();\n\n if (texture && texture.isVideo()) {\n // Enable auto hide when content type is video\n autoHider.enable(viewer);\n } else {\n autoHider.disable(viewer);\n }\n }\n }\n\n private _updateBackground(viewer: View360) {\n const background = this._bgEl;\n const showBackground = this.showBackground;\n const hiddenClass = this.className.HIDDEN ?? ControlBar.DEFAULT_CLASS.HIDDEN;\n\n if (showBackground != null) {\n if (showBackground) {\n background.classList.remove(hiddenClass);\n } else {\n background.classList.add(hiddenClass);\n }\n } else {\n // Automatically choose whether to show background by content type\n const texture = viewer.projection?.getTexture();\n\n if (texture && texture.isVideo()) {\n // Show bg when content type is video\n background.classList.remove(hiddenClass);\n } else {\n background.classList.add(hiddenClass);\n }\n }\n }\n\n private _updateKeyboardHandler(viewer: View360) {\n const panoRoot = viewer.rootEl;\n const videoControl = this._videoControl;\n const texture = viewer.projection?.getTexture();\n\n if (this.keyboardControls && texture && texture.isVideo()) {\n videoControl.enable(panoRoot, texture);\n } else {\n videoControl.disable(panoRoot);\n }\n }\n\n private _createDefaultItems(): ControlBarItem[] {\n const items: ControlBarItem[] = [];\n\n if (this.progressBar) {\n items.push(new ProgressBar(getObjectOption(this.progressBar)));\n }\n\n if (this.playButton) {\n items.push(new PlayButton(getObjectOption(this.playButton)));\n }\n\n if (this.volumeButton) {\n items.push(new VolumeControl(getObjectOption(this.volumeButton)));\n }\n\n if (this.gyroButton) {\n items.push(new GyroButton(getObjectOption(this.gyroButton)));\n }\n\n if (this.vrButton) {\n items.push(new VRButton(getObjectOption(this.vrButton)));\n }\n\n if (this.fullscreenButton) {\n items.push(new FullscreenButton(getObjectOption(this.fullscreenButton)));\n }\n\n if (this.videoTime) {\n items.push(new VideoTime(getObjectOption(this.videoTime)));\n }\n\n if (this.pieView) {\n items.push(new PieView(getObjectOption(this.pieView)));\n }\n\n return items;\n }\n}\n\nexport default ControlBar;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Camera from \"../core/Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport Texture from \"../texture/Texture\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport { VideoConfig } from \"../type/external\";\nimport UniformCanvasCube from \"../uniform/UniformCanvasCube\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport UniformTextureCube from \"../uniform/UniformTextureCube\";\n\ntype CommonProjectionUniforms = {\n uTexture: UniformTexture2D | UniformTextureCube | UniformCanvasCube;\n}\n\n/**\n * Common option for {@link Projection}s\n * @ko {@link Projection}을 위한 공통 옵션들\n * @category Projection\n * @since 4.0.0\n */\nexport interface ProjectionOptions {\n /**\n * @copy Projection#src\n */\n src: string | HTMLElement | Array;\n /**\n * @copy Projection#video\n */\n video?: boolean | Partial;\n}\n\n/**\n * Base class for projections.\n * @ko 프로젝션 베이스 클래스.\n * @category Projection\n * @since 4.0.0\n */\nabstract class Projection {\n /**\n * Source URL to panorama image/video.\n * @ko 파노라마 이미지/비디오의 URL\n * @since 4.0.0\n */\n public readonly src: ProjectionOptions[\"src\"];\n /**\n * Properties for the video element.\n * Setting `false` will treat panorama source as an image, `true` will use default properties.\n * @ko 비디오 엘리먼트에 설정할 프로퍼티를 담는 객체.\n * @since 4.0.0\n * @example\n * Default properties\n * ```ts\n * autoplay: true\n * muted: true\n * loop: false\n * volume: 1\n * ```\n */\n public readonly video: ProjectionOptions[\"video\"];\n\n protected _mesh: TriangleMesh | null;\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor({\n src,\n video = false\n }: ProjectionOptions) {\n this.src = src;\n this.video = video;\n this._mesh = null;\n }\n\n /**\n * Apply texture to current projection.\n * @ko 주어진 텍스쳐를 현재 프로젝션에 적용합니다.\n * @param ctx - Instance of the WebGLContext helper {@ko WebGL context 헬퍼의 인스턴스}\n * @param texture - New texture to apply {@ko 새로 적용할 텍스쳐}\n * @internal\n * @since 4.0.0\n */\n public abstract applyTexture(ctx: WebGLContext, texture: Texture): void;\n\n /**\n * Release all resources projection has.\n * This is automatically called on projection change & View360's destroy call\n * @ko 현재 갖고 있는 모든 리소스를 반환합니다.\n * 이 메소드는 프로젝션 변경 및 View360의 destroy 호출 시 자동으로 호출됩니다.\n * @param ctx\n */\n public releaseAllResources(ctx: WebGLContext) {\n this._mesh?.destroy(ctx);\n }\n\n /**\n * Update camera to match projection's settings.\n * @ko 현재 프로젝션의 세팅으로 카메라를 업데이트합니다.\n * @param camera - Instance of the camera to update {@ko 업데이트할 카메라의 인스턴스}\n * @since 4.0.0\n */\n public updateCamera(camera: Camera) {\n // Use default mode & no view restriction\n camera.resetRange();\n }\n\n /**\n * Update control to match projection's settings.\n * @ko 현재 프로젝션의 세팅으로 컨트롤을 업데이트합니다.\n * @param control - Instance of the control to update {@ko 업데이트할 컨트롤의 인스턴스}\n * @since 4.0.0\n */\n public updateControl(control: PanoControl) {\n control.ignoreZoomScale = false;\n }\n\n /**\n * Update projection.\n * @ko 현재 프로젝션 정보를 갱신합니다.\n * @param camera - Instance of the camera to reference {@ko 참조할 카메라의 인스턴스}\n * @since 4.0.0\n */\n public update(camera: Camera) {} // eslint-disable-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars\n\n /**\n * Return active texture.\n * @ko 현재 활성화된 텍스쳐를 반환합니다.\n * @internal\n * @since 4.0.0\n */\n public getTexture() {\n if (!this._mesh) return null;\n\n return this._mesh.program.uniforms.uTexture.texture;\n }\n\n /**\n * A 3D triangle mesh for projection. It's `null` until loading the `src`.\n * @ko Projection을 표시하기 위한 Mesh, src를 로드하기 전까지는 `null`입니다.\n * @since 4.0.0\n */\n public getMesh(): TriangleMesh | null {\n return this._mesh;\n }\n}\n\nexport default Projection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nabstract class Uniform {\n public needsUpdate: boolean;\n\n public constructor() {\n this.needsUpdate = true;\n }\n\n public abstract update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean): void;\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext) {\n // DO_NOTHING\n }\n}\n\nexport default Uniform;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport TextureCube from \"../texture/TextureCube\";\nimport { reorderCube } from \"../utils\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformTextureCube extends Uniform {\n public readonly texture: TextureCube;\n private _webglTexture: WebGLTexture;\n private _cubemapOrder: string;\n\n public constructor(ctx: WebGLContext, texture: TextureCube, cubemapOrder: string) {\n super();\n\n this.texture = texture;\n this._webglTexture = ctx.createWebGLCubeTexture(texture, texture.width);\n this._cubemapOrder = cubemapOrder;\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext): void {\n this.texture.destroy();\n gl.deleteTexture(this._webglTexture);\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture);\n\n const sources = reorderCube(texture.sources, this._cubemapOrder);\n sources.forEach((src, idx) => {\n if (isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src);\n } else {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + idx, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src);\n }\n });\n\n if (!texture.isVideo()) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformTextureCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"../texture/Texture2D\";\nimport { range, reorderCube } from \"../utils\";\n\n/** @hidden */\nclass CubeTexturePainter {\n public readonly texture: Texture2D;\n private _renderingOrder: number[];\n private _canvas: HTMLCanvasElement;\n private _ctx: CanvasRenderingContext2D;\n private _row: number;\n private _column: number;\n private _size: number;\n\n public get size() { return this._size; }\n\n public constructor(texture: Texture2D, cubemapOrder: string) {\n this.texture = texture;\n this._renderingOrder = reorderCube(range(6), cubemapOrder);\n\n const canvas = document.createElement(\"canvas\");\n\n this._calcRenderingSize();\n\n canvas.width = this._size;\n canvas.height = this._size;\n\n this._canvas = canvas;\n this._ctx = canvas.getContext(\"2d\")!;\n }\n\n public destroy() {\n const canvas = this._canvas;\n\n // release memories\n canvas.width = 1;\n canvas.height = 1;\n this._canvas = null as any;\n }\n\n public draw(gl: WebGLRenderingContext | WebGL2RenderingContext, isWebGL2: boolean) {\n const size = this._size;\n const texture = this.texture;\n let surfaceIdx = 0;\n\n for (let row = 0; row < this._row; row++) {\n for (let column = 0; column < this._column; column++) {\n const x = size * column;\n const y = size * row;\n const renderingFace = this._renderingOrder[surfaceIdx];\n\n this._ctx.drawImage(texture.source as CanvasImageSource, x, y, size, size, 0, 0, size, size);\n\n if (isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas);\n } else {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderingFace, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._canvas);\n }\n\n surfaceIdx++;\n }\n }\n }\n\n private _calcRenderingSize() {\n const {\n width,\n height\n } = this.texture;\n const aspect = width / height;\n\n if (aspect === 1 / 6) {\n this._size = width;\n this._row = 6;\n this._column = 1;\n } else if (aspect === 6) {\n this._size = height;\n this._row = 1;\n this._column = 6;\n } else if (aspect === 2 / 3) {\n this._size = width * 0.5;\n this._row = 3;\n this._column = 2;\n } else {\n this._size = width / 3;\n this._row = 2;\n this._column = 3;\n }\n }\n}\n\nexport default CubeTexturePainter;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport CubeTexturePainter from \"../core/CubeTexturePainter\";\nimport Texture2D from \"../texture/Texture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformCanvasCube extends Uniform {\n private _webglTexture: WebGLTexture;\n private _painter: CubeTexturePainter;\n\n public get texture() { return this._painter.texture; }\n\n public constructor(ctx: WebGLContext, texture: Texture2D, cubemapOrder: string) {\n super();\n\n this._painter = new CubeTexturePainter(texture as Texture2D, cubemapOrder);\n this._webglTexture = ctx.createWebGLCubeTexture(texture, this._painter.size);\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext) {\n gl.deleteTexture(this._webglTexture);\n this._painter.destroy();\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_CUBE_MAP, this._webglTexture);\n\n this._painter.draw(gl, isWebGL2);\n\n if (!texture.isVideo()) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformCanvasCube;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Object3D from \"./Object3D\";\nimport ShaderProgram from \"./ShaderProgram\";\nimport VertexArrayObject from \"./VertexArrayObject\";\nimport Uniform from \"../uniform/Uniform\";\nimport WebGLContext from \"./WebGLContext\";\n\n/**\n * @hidden\n */\nclass TriangleMesh = Record> extends Object3D {\n /**\n * @internal\n * Geometry data for projection\n */\n public readonly vao: VertexArrayObject;\n /**\n * @internal\n * Material(shader) data for projection\n */\n public readonly program: ShaderProgram;\n\n public constructor(vao: VertexArrayObject, program: ShaderProgram) {\n super();\n\n this.vao = vao;\n this.program = program;\n }\n\n public destroy(ctx: WebGLContext) {\n ctx.releaseVAO(this.vao);\n ctx.releaseShaderResources(this.program);\n }\n}\n\nexport default TriangleMesh;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"../uniform/Uniform\";\nimport WebGLContext from \"./WebGLContext\";\nimport { UniformLocations } from \"../type/internal\";\n\nclass ShaderProgram = Record> {\n public readonly program: WebGLProgram;\n public readonly uniforms: T;\n public readonly uniformLocations: UniformLocations;\n\n public constructor(ctx: WebGLContext, vertexShader: string, fragmentShader: string, uniforms: T) {\n this.program = ctx.createProgram(vertexShader, fragmentShader);\n this.uniforms = uniforms;\n this.uniformLocations = ctx.getUniformLocations(this.program, uniforms);\n }\n}\n\nexport default ShaderProgram;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport { TypedArray } from \"../type/utils\";\n\n/**\n * @hidden\n */\nclass VertexData {\n public readonly data: T;\n public itemSize: number;\n public count: number;\n\n /** */\n public constructor(data: T, itemSize: number) {\n this.data = data;\n this.itemSize = itemSize;\n this.count = data.length / itemSize;\n }\n}\n\nexport default VertexData;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport VertexData from \"../core/VertexData\";\n\n/**\n * @hidden\n */\nabstract class Geometry {\n public readonly vertices: VertexData;\n public readonly indicies: VertexData;\n public readonly uvs: VertexData;\n\n /** */\n public constructor(vertices: number[], indicies: number[], uvs: number[]) {\n this.vertices = new VertexData(new Float32Array(vertices), 3);\n this.indicies = new VertexData(new Uint16Array(indicies), 1);\n this.uvs = new VertexData(new Float32Array(uvs), 2);\n }\n}\n\nexport default Geometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\nimport { ROTATE } from \"../const/internal\";\nimport { reorderCube } from \"../utils\";\n\n/**\n * @hidden\n */\nclass CubeGeometry extends Geometry {\n public constructor({\n order,\n rotateUV\n }: {\n order: string;\n rotateUV?: ROTATE[]\n }) {\n const vertices = [\n // back\n 1, -1, 1,\n -1, -1, 1,\n -1, 1, 1,\n 1, 1, 1,\n\n // front\n -1, -1, -1,\n 1, -1, -1,\n 1, 1, -1,\n -1, 1, -1,\n\n // up\n -1, 1, -1,\n 1, 1, -1,\n 1, 1, 1,\n -1, 1, 1,\n\n // down\n -1, -1, 1,\n 1, -1, 1,\n 1, -1, -1,\n -1, -1, -1,\n\n // right\n 1, -1, -1,\n 1, -1, 1,\n 1, 1, 1,\n 1, 1, -1,\n\n // left\n -1, -1, 1,\n -1, -1, -1,\n -1, 1, -1,\n -1, 1, 1\n ];\n\n const indicies = [\n 0, 1, 2,\n 0, 2, 3,\n 4, 5, 6,\n 4, 6, 7,\n 8, 9, 10,\n 8, 10, 11,\n 12, 13, 14,\n 12, 14, 15,\n 16, 17, 18,\n 16, 18, 19,\n 20, 21, 22,\n 20, 22, 23\n ];\n\n const oneThird = 1 / 3;\n const coords: number[][] = [];\n\n for (let r = 1; r >= 0; r--) {\n for (let c = 0; c < 3; c++) {\n const coord = [\n c * oneThird, r * 0.5,\n (c + 1) * oneThird, r * 0.5,\n (c + 1) * oneThird, (r + 1) * 0.5,\n c * oneThird, (r + 1) * 0.5\n ];\n\n coords.push(coord);\n }\n }\n\n if (rotateUV) {\n rotateUV.forEach((degree, idx) => {\n if (degree === ROTATE.ZERO) return;\n\n const coord = coords[idx];\n let newOrder: number[];\n\n if (degree === ROTATE.CW_90) {\n newOrder = [1, 2, 3, 0];\n } else if (degree === ROTATE.CCW_90) {\n newOrder = [3, 0, 1, 2];\n } else {\n newOrder = [2, 3, 0, 1];\n }\n\n const newCoords = Array(coord.length);\n for (let uvIdx = 0; uvIdx < coord.length / 2; uvIdx++) {\n newCoords[uvIdx * 2 + 0] = coord[newOrder[uvIdx] * 2 + 0];\n newCoords[uvIdx * 2 + 1] = coord[newOrder[uvIdx] * 2 + 1];\n }\n\n coords[idx] = newCoords;\n });\n }\n\n const uvs = reorderCube(coords, order, \"BFUDRL\")\n .reduce((acc, val) => acc.concat(val), []);\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default CubeGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Texture2D from \"../texture/Texture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Uniform from \"./Uniform\";\n\nclass UniformTexture2D extends Uniform {\n public readonly texture: Texture2D;\n private _webglTexture: WebGLTexture;\n\n public constructor(ctx: WebGLContext, texture: Texture2D) {\n super();\n\n this.texture = texture;\n this._webglTexture = ctx.createWebGLTexture(texture);\n }\n\n public destroy(gl: WebGLRenderingContext | WebGL2RenderingContext): void {\n this.texture.destroy();\n gl.deleteTexture(this._webglTexture);\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation, isWebGL2: boolean) {\n const texture = this.texture;\n const isVideo = texture.isVideo();\n\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);\n gl.uniform1i(location, 0);\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._webglTexture);\n\n if (!isVideo && isWebGL2) {\n gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n } else {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);\n }\n\n if (!isVideo) {\n this.needsUpdate = false;\n }\n }\n}\n\nexport default UniformTexture2D;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass CylinderGeometry extends Geometry {\n public constructor(maxTheta: number) {\n const vertices: number[] = [];\n const indicies: number[] = [];\n const uvs: number[] = [];\n\n const height = 1;\n const radialSegments = 60;\n const halfHeight = height * 0.5;\n const heightSegments = [-halfHeight, halfHeight];\n const invRadialSegments = 1 / radialSegments;\n const angleConst = maxTheta * invRadialSegments;\n\n for (let yIdx = 0; yIdx < 2; yIdx++) {\n const y = heightSegments[yIdx];\n\n for (let lngIdx = 0; lngIdx <= radialSegments; lngIdx++) {\n const angle = lngIdx * angleConst + Math.PI - maxTheta * 0.5;\n const x = Math.cos(angle);\n const z = Math.sin(angle);\n const u = lngIdx * invRadialSegments;\n const v = yIdx;\n\n uvs.push(u, v);\n vertices.push(x, y, z);\n\n if (yIdx === 0 && lngIdx < radialSegments) {\n const a = lngIdx;\n const b = a + radialSegments + 1;\n\n indicies.push(a, b, a + 1, b, b + 1, a + 1);\n }\n }\n }\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default CylinderGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass SphereGeometry extends Geometry {\n /** */\n public constructor() {\n // const radius = 1;\n const widthSegments = 60;\n const heightSegments = 60;\n const ANGLE_CORRECTION_FOR_CENTER_ALIGN = -0.5 * Math.PI;\n\n const uvs: number[] = [];\n const vertices: number[] = [];\n const indicies: number[] = [];\n let latIdx: number;\n let lngIdx: number;\n\n for (latIdx = 0; latIdx <= widthSegments; latIdx++) {\n const theta = (latIdx / widthSegments - 0.5) * Math.PI;\n const sinTheta = Math.sin(theta);\n const cosTheta = Math.cos(theta);\n\n for (lngIdx = 0; lngIdx <= heightSegments; lngIdx++) {\n const phi = (lngIdx / heightSegments - 0.5) * 2 * Math.PI + ANGLE_CORRECTION_FOR_CENTER_ALIGN;\n const sinPhi = Math.sin(phi);\n const cosPhi = Math.cos(phi);\n const x = cosPhi * cosTheta;\n const y = sinTheta;\n const z = sinPhi * cosTheta;\n const u = lngIdx / heightSegments;\n const v = latIdx / widthSegments;\n\n uvs.push(u, v);\n vertices.push(x, y, z);\n\n if (lngIdx !== heightSegments && latIdx !== widthSegments) {\n const a = latIdx * (heightSegments + 1) + lngIdx;\n const b = a + heightSegments + 1;\n\n indicies.push(a, a + 1, b, b, a + 1, b + 1);\n }\n }\n }\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default SphereGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"./Uniform\";\n\nclass UniformFloat extends Uniform {\n public val: number;\n\n public constructor(val: number) {\n super();\n\n this.val = val;\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation) {\n gl.uniform1f(location, this.val);\n\n this.needsUpdate = false;\n }\n}\n\nexport default UniformFloat;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Geometry from \"./Geometry\";\n\n/**\n * @hidden\n */\nclass PlaneGeometry extends Geometry {\n /** */\n public constructor(width: number = 2, height: number = 2, z: number = -1) {\n const halfWidth = width * 0.5;\n const halfHeight = height * 0.5;\n const vertices = [\n -halfWidth, -halfHeight, z,\n halfWidth, -halfHeight, z,\n -halfWidth, halfHeight, z,\n halfWidth, halfHeight, z\n ];\n const indicies = [\n 0, 1, 2,\n 2, 1, 3\n ];\n const uvs = [\n 0, 0,\n 1, 0,\n 0, 1,\n 1, 1\n ];\n\n super(vertices, indicies, uvs);\n }\n}\n\nexport default PlaneGeometry;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Uniform from \"./Uniform\";\n\nclass UniformVector4Array extends Uniform {\n public val: number[][];\n\n public constructor(val: number[][]) {\n super();\n\n this.val = val;\n }\n\n public update(gl: WebGLRenderingContext | WebGL2RenderingContext, location: WebGLUniformLocation) {\n gl.uniform4fv(location, this.val.reduce((arr, vector) => [...arr, ...vector], []));\n\n this.needsUpdate = false;\n }\n}\n\nexport default UniformVector4Array;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport SphereGeometry from \"../geometry/SphereGeometry\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport UniformVector4Array from \"../uniform/UniformVector4Array\";\nimport UniformFloat from \"../uniform/UniformFloat\";\nimport vs from \"../shader/stereoequi.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link StereoEquiProjection}\n * @ko {@link StereoEquiProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface StereoEquiProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n /**\n * Stereoscopic mode of the image\n * @ko 이미지의 스테레오스코픽 모드\n * @since 4.0.0\n * @default \"top_bottom\"\n */\n mode: typeof StereoEquiProjection.MODE[keyof typeof StereoEquiProjection.MODE]\n}\n\n/**\n * Projection based on stereo equirectangular images.\n * @ko Stereo equirectangular 이미지 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass StereoEquiProjection extends Projection<{\n uTexture: UniformTexture2D;\n uEye: UniformFloat;\n uTexScaleOffset: UniformVector4Array;\n}> {\n /**\n * Available stereoscopic modes\n * @ko 사용가능한 스테레오스코픽 모드들\n * @since 4.0.0\n */\n public static MODE = {\n /**\n * @ko 이미지가 왼쪽/오른쪽으로 구성되어있을 경우\n * @since 4.0.0\n */\n LEFT_RIGHT: \"left_right\",\n /**\n * @ko 이미지가 위/아래로 구성되어있을 경우\n * @since 4.0.0\n */\n TOP_BOTTOM: \"top_bottom\",\n } as const;\n\n private _mode: StereoEquiProjectionOptions[\"mode\"];\n\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: StereoEquiProjectionOptions) {\n super(options);\n\n this._mode = options.mode;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n let leftEye: number[];\n let rightEye: number[];\n\n switch (this._mode) {\n case StereoEquiProjection.MODE.LEFT_RIGHT:\n leftEye = [0.5, 1, 0, 0];\n rightEye = [0.5, 1, 0.5, 0];\n break;\n default:\n // Default, uses \"top_bottom\"\n leftEye = [1, 0.5, 0, 0];\n rightEye = [1, 0.5, 0, 0.5];\n }\n\n\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture),\n uEye: new UniformFloat(0),\n uTexScaleOffset: new UniformVector4Array([leftEye, rightEye])\n };\n\n const geometry = new SphereGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default StereoEquiProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTextureCube from \"../uniform/UniformTextureCube\";\nimport UniformCanvasCube from \"../uniform/UniformCanvasCube\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport TextureCube from \"../texture/TextureCube\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/cube.vert\";\nimport fs from \"../shader/cube.frag\";\n\n/**\n * Options for {@link CubemapProjection}\n * @ko {@link CubemapProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CubemapProjectionOptions extends ProjectionOptions {\n /**\n * Order of the cubemap images.\n * @ko 큐브맵 이미지의 순서.\n * @since 4.0.0\n * @default \"RLUDFB\" (Right - Left - Up - Down - Front - Back)\n */\n cubemapOrder?: string;\n /**\n * Whether to flip cubemap image horizontally.\n * @ko 큐브맵 이미지를 좌우대칭할지 여부.\n * @since 4.0.0\n * @default false\n */\n cubemapFlipX?: boolean;\n}\n\n/**\n * Projection based on cubemap images, accepts both multiple or single images.\n * @ko 큐브맵 이미지 기반의 프로젝션, 단일 혹은 여러 장의 이미지를 모두 사용 가능합니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CubemapProjection extends Projection<{\n uTexture: UniformTextureCube | UniformCanvasCube;\n}> {\n private _cubemapOrder: NonNullable;\n private _cubemapFlipX: NonNullable;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CubemapProjectionOptions) {\n super(options);\n\n const {\n cubemapOrder = \"RLUDFB\",\n cubemapFlipX = false\n } = options;\n\n this._cubemapOrder = cubemapOrder;\n this._cubemapFlipX = cubemapFlipX;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const cubemapOrder = this._cubemapOrder;\n const cubemapFlipX = this._cubemapFlipX;\n const uniforms = {\n uTexture: texture.isCube()\n ? new UniformTextureCube(ctx, texture as TextureCube, cubemapOrder)\n : new UniformCanvasCube(ctx, texture as Texture2D, cubemapOrder)\n };\n\n const geometry = new CubeGeometry({\n order: cubemapOrder\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n if (cubemapFlipX) {\n mesh.scale[0] = -1;\n }\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n}\n\nexport default CubemapProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link CubestripProjection}\n * @ko {@link CubestripProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CubestripProjectionOptions extends ProjectionOptions {\n /**\n * @copy CubemapProjectionOptions#cubemapOrder\n */\n cubemapOrder?: string;\n /**\n * @copy CubemapProjectionOptions#cubemapFlipX\n */\n cubemapFlipX?: boolean;\n}\n\n/**\n * Projection based on cubemap strip.\n * Slightly more efficient than {@link CubemapProjection} as it doesn't copy cubemap image to canvas while rendering.\n * Accepts only single image.\n * @ko 큐브맵 스트립 기반의 프로젝션.\n * {@link CubemapProjection}와 달리 렌더링하는 과정에 캔버스에 이미지를 복사하는 과정이 없기 때문에 살짝 더 효율적입니다.\n * 단일 이미지만 사용 가능합니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CubestripProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n private _cubemapOrder: NonNullable;\n private _cubemapFlipX: NonNullable;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CubestripProjectionOptions) {\n super(options);\n\n const {\n cubemapOrder = \"RLUDFB\",\n cubemapFlipX = false\n } = options;\n\n this._cubemapOrder = cubemapOrder;\n this._cubemapFlipX = cubemapFlipX;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const cubemapOrder = this._cubemapOrder;\n const cubemapFlipX = this._cubemapFlipX;\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n const geometry = new CubeGeometry({\n order: cubemapOrder\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n if (cubemapFlipX) {\n mesh.scale[0] = -1;\n }\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n}\n\nexport default CubestripProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n*/\nimport { quat } from \"gl-matrix\";\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport CylinderGeometry from \"../geometry/CylinderGeometry\";\nimport Camera from \"../core/Camera\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport { DEG_TO_RAD, RAD_TO_DEG } from \"../const/internal\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\nimport TriangleMesh from \"../core/TriangleMesh\";\n\n/**\n * Options for {@link CylindricalProjection}\n * @ko {@link CylindricalProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface CylindricalProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n /**\n * Whether the panorama image covers full 360 degrees.\n * @ko 파노라마 이미지가 360도를 전부 커버하는지 여부\n * @since 4.0.0\n * @default false\n */\n partial?: boolean;\n}\n\n/**\n * Projection based on cylindrical projection.\n * This can show panorama images taken from smartphones.\n * @ko 원통 투영법 기반의 프로젝션.\n * 일반적인 스마트폰 파노라마 사진을 표시하는데 사용될 수 있습니다.\n * @since 4.0.0\n * @category Projection\n */\nclass CylindricalProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n private _partial: boolean;\n\n /**\n * Create new instance.\n * @ko 새 인스턴스를 생성합니다.\n * @param options Options {@ko Options}\n */\n public constructor(options: CylindricalProjectionOptions) {\n super(options);\n\n const {\n partial = false\n } = options;\n\n this._partial = partial;\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const partial = this._partial;\n const { width, height } = texture;\n const aspect = width / height;\n const halfVFov = 180 / aspect;\n const cylinderHeight = partial\n ? 1\n : 2 * Math.tan(halfVFov * DEG_TO_RAD);\n const cylinderTheta = partial\n ? aspect\n : 2 * Math.PI;\n\n const geometry = new CylinderGeometry(cylinderTheta);\n const program = new ShaderProgram(ctx, vs, fs, {\n uTexture: new UniformTexture2D(ctx, texture)\n });\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n mesh.scale[1] = cylinderHeight;\n quat.identity(mesh.rotation);\n quat.rotateY(mesh.rotation, mesh.rotation, -Math.PI / 2);\n mesh.updateMatrix();\n\n this._mesh = mesh;\n }\n\n public updateCamera(camera: Camera) {\n super.updateCamera(camera);\n\n const mesh = this._mesh;\n if (!mesh) return;\n\n const uTexture = mesh.program.uniforms.uTexture;\n const texture = uTexture.texture;\n const { width, height } = texture;\n const aspect = width / height;\n const halfHeight = mesh.scale[1] * 0.5;\n\n if (this._partial) {\n const restrictedYaw = 0.5 * aspect * RAD_TO_DEG;\n camera.restrictYawRange(-restrictedYaw, restrictedYaw);\n }\n\n const restrictedPitch = Math.atan2(halfHeight, 1) * RAD_TO_DEG;\n const minZoom = Math.tan(camera.fov * DEG_TO_RAD * 0.5) / (halfHeight * camera.aspect);\n\n camera.restrictPitchRange(-restrictedPitch, restrictedPitch);\n camera.restrictZoomRange(minZoom, Infinity);\n camera.restrictRenderHeight(halfHeight * 2);\n }\n}\n\nexport default CylindricalProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport Texture2D from \"../texture/Texture2D\";\nimport CubeGeometry from \"../geometry/CubeGeometry\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/eac.frag\";\nimport { ROTATE } from \"../const/internal\";\n\n/**\n * Options for {@link EquiangularProjection}\n * @ko {@link EquiangularProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface EquiangularProjectionOptions extends ProjectionOptions {}\n\n/**\n * Equi-Angular Cubemap Projection.\n * This format is used by Youtube's 360 videos.\n * @ko Equi-Angular Cubemap 프로젝션.\n * 이 포맷은 주로 Youtube의 360 비디오에 사용됩니다.\n * @since 4.0.0\n * @category Projection\n */\nclass EquiangularProjection extends Projection<{\n uTexture: UniformTexture2D;\n}> {\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n const geometry = new CubeGeometry({\n order: \"LFRDBU\",\n rotateUV: [\n ROTATE.ZERO, ROTATE.ZERO, ROTATE.ZERO,\n ROTATE.CW_90, ROTATE.CCW_90, ROTATE.CW_90\n ]\n });\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default EquiangularProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport Texture2D from \"../texture/Texture2D\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport SphereGeometry from \"../geometry/SphereGeometry\";\nimport TriangleMesh from \"../core/TriangleMesh\";\nimport vs from \"../shader/common.vert\";\nimport fs from \"../shader/common.frag\";\n\n/**\n * Options for {@link EquirectProjection}\n * @ko {@link EquirectProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface EquirectProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n}\n\n/**\n * Projection based on equirectangular projection.\n * @ko 등 장방형 도법(Equirectangular projection) 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass EquirectProjection extends Projection<{\n uTexture: UniformTexture2D\n}> {\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: EquirectProjectionOptions) {\n super(options);\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture)\n };\n\n const geometry = new SphereGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n}\n\nexport default EquirectProjection;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport Projection, { ProjectionOptions } from \"./Projection\";\nimport WebGLContext from \"../core/WebGLContext\";\nimport UniformTexture2D from \"../uniform/UniformTexture2D\";\nimport UniformFloat from \"../uniform/UniformFloat\";\nimport Camera from \"../core/Camera\";\nimport PanoControl from \"../control/PanoControl\";\nimport ShaderProgram from \"../core/ShaderProgram\";\nimport Texture2D from \"../texture/Texture2D\";\nimport PlaneGeometry from \"../geometry/PlaneGeometry\";\nimport vs from \"../shader/little-planet.vert\";\nimport fs from \"../shader/little-planet.frag\";\nimport TriangleMesh from \"../core/TriangleMesh\";\n\n/**\n * Options for {@link LittlePlanetProjection}\n * @ko {@link LittlePlanetProjection}의 옵션들\n * @since 4.0.0\n * @category Projection\n */\nexport interface LittlePlanetProjectionOptions extends ProjectionOptions {\n src: string | HTMLElement;\n}\n\n/**\n * Projection based on so-called \"Little planet\" or \"Tiny planet\" effect.\n * @ko \"Little planet\" 혹은 \"Tiny planet\"로 불리는 이펙트 기반의 프로젝션\n * @since 4.0.0\n * @category Projection\n */\nclass LittlePlanetProjection extends Projection<{\n uTexture: UniformTexture2D;\n uYaw: UniformFloat;\n uPitch: UniformFloat;\n uZoom: UniformFloat;\n}> {\n /**\n * Create new instance\n * @ko 새로운 인스턴스를 생성합니다.\n * @param options - Options {@ko 옵션들}\n */\n public constructor(options: LittlePlanetProjectionOptions) {\n super(options);\n }\n\n public applyTexture(ctx: WebGLContext, texture: Texture2D) {\n texture.wrapS = WebGLRenderingContext.REPEAT;\n texture.wrapT = WebGLRenderingContext.REPEAT;\n\n const uniforms = {\n uTexture: new UniformTexture2D(ctx, texture),\n uYaw: new UniformFloat(0),\n uPitch: new UniformFloat(0.5),\n uZoom: new UniformFloat(1)\n };\n\n const geometry = new PlaneGeometry();\n const program = new ShaderProgram(ctx, vs, fs, uniforms);\n\n const vao = ctx.createVAO(geometry, program);\n const mesh = new TriangleMesh(vao, program);\n\n this._mesh = mesh;\n }\n\n public updateControl(control: PanoControl) {\n control.ignoreZoomScale = true;\n }\n\n public update(camera: Camera) {\n const mesh = this._mesh;\n if (!mesh) return;\n\n const uniforms = mesh.program.uniforms;\n\n uniforms.uYaw.val = camera.yaw / 360;\n // Range from 0 ~ 1\n uniforms.uPitch.val = (camera.pitch / 180) + 0.5;\n uniforms.uZoom.val = camera.zoom;\n\n uniforms.uYaw.needsUpdate = true;\n uniforms.uPitch.needsUpdate = true;\n uniforms.uZoom.needsUpdate = true;\n }\n}\n\nexport default LittlePlanetProjection;\n","/**\n * @hidden\n */\nexport const getValidProps = (propsObj: any) => {\n return Object.keys(propsObj).reduce((props, propName) => {\n if (propsObj[propName] != null) {\n props[propName] = propsObj[propName];\n }\n\n return props;\n }, {});\n};\n","export const VIEW360_METHODS = [\n \"destroy\",\n \"init\",\n \"load\",\n \"resize\",\n \"addPlugins\",\n \"removePlugins\",\n \"renderFrame\",\n // @egjs/component methods\n \"on\",\n \"hasOn\",\n \"once\",\n \"off\",\n \"trigger\"\n] as const;\n","import Component from \"@egjs/component\";\nimport View360 from \"../View360\";\n\n/**\n * @hidden\n */\nconst withMethods = (prototype: any, attr: string) => {\n [Component.prototype, View360.prototype].forEach(proto => {\n Object.getOwnPropertyNames(proto)\n .filter(name => name.charAt(0) !== \"_\" && name !== \"constructor\")\n .forEach((name: string) => {\n const descriptor = Object.getOwnPropertyDescriptor(proto, name)!;\n\n if (descriptor.value) {\n // Public Function\n Object.defineProperty(prototype, name, {\n value: function(...args) {\n return descriptor.value.call(this[attr], ...args);\n }\n });\n } else {\n const getterDescriptor: { get?: () => any; set?: (val: any) => void } = {};\n if (descriptor.get) {\n getterDescriptor.get = function() {\n return this[attr] && descriptor.get?.call(this[attr]);\n };\n }\n if (descriptor.set) {\n getterDescriptor.set = function(...args) {\n return descriptor.set?.call(this[attr], ...args);\n };\n }\n\n Object.defineProperty(prototype, name, getterDescriptor);\n }\n });\n });\n};\n\nexport default withMethods;\n","/*\n * Copyright (c) 2023-present NAVER Corp.\n * egjs projects are licensed under the MIT license\n */\nimport View360, * as modules from \"./index\";\nimport { merge } from \"./utils\";\n\nmerge(View360, modules);\n\nexport default View360;\n"],"names":["View360Error","Error","constructor","message","code","super","Object","setPrototypeOf","this","prototype","name","ERROR_CODES","WRONG_TYPE","WRONG_OPTION","ELEMENT_NOT_FOUND","CANVAS_NOT_FOUND","WEBGL_NOT_SUPPORTED","FAILED_CREATE_CONTEXT_2D","PROVIDE_PROJECTION_FIRST","FAILED_LINKING_PROGRAM","INSUFFICIENT_ARGS","ERROR","val","types","map","type","join","optionName","query","msg","shaderLog","EVENTS","EL_DIV","EL_BUTTON","MOUSE_BUTTON","CURSOR","KEY_DIRECTION","DIRECTION_KEY_CODE","DIRECTION_KEY_NAME","LEFT","UP","RIGHT","DOWN","FULLSCREEN_REQUEST","FULLSCREEN_ELEMENT","FULLSCREEN_EXIT","FULLSCREEN_CHANGE","DEFAULT_CLASS","CONTAINER","CANVAS","CTX_LOST","IN_VR","HOTSPOT_CONTAINER","HOTSPOT","HOTSPOT_VISIBLE","HOTSPOT_FLIP_X","HOTSPOT_FLIP_Y","READY","LOAD_START","LOAD","PROJECTION_CHANGE","RESIZE","BEFORE_RENDER","RENDER","INPUT_START","INPUT_END","VIEW_CHANGE","STATIC_CLICK","VR_START","VR_END","EASING","LINEAR","x","SINE_WAVE","Math","sin","PI","EASE_OUT_CUBIC","pow","EASE_OUT_BOUNCE","n1","d1","CAMERA_EVENTS","CONTROL_EVENTS","DEG_TO_RAD","RAD_TO_DEG","DEFAULT_EASING","DEFAULT_ANIMATION_DURATION","INFINITE_RANGE","min","Infinity","max","DEFAULT_PITCH_RANGE","DEFAULT_ZOOM_RANGE","ROTATE","VIDEO_TIME_CHANGE_EVENT","SVG_NAMESPACE","SESSION_VR","XR_REFERENCE_SPACE","EPSILON","_a","Number","isString","createElement","className","tag","BROWSER","el","document","classList","add","getNullableElement","parent","targetEl","queryResult","querySelector","nodeType","Node","ELEMENT_NODE","clamp","lerp","a","b","t","circulate","size","abs","findIndex","array","checker","idx","length","getObjectOption","toVerticalFov","fovRadian","aspect","atan","tan","reorderCube","arr","order","defaultOrder","split","face","indexOf","index","isFullscreen","key","sensorCanBeEnabledIOS","DeviceMotionEvent","window","isSecureContext","eulerToQuat","out","yaw","pitch","roll","quat","pitchClamped","quatToEuler","quaternion","y","z","w","unit","test","atan2","view","vec3","up","viewXZ","sqrt","Motion","_val","start","_start","end","_end","progress","_progress","activated","_activated","duration","_duration","loop","_loop","range","_range","easing","_easing","reset","update","deltaTime","prev","nextProgress","easedProgress","defaultVal","delta","setNewEndByDelta","setRange","CameraAnimation","_motion","camera","from","to","_camera","_from","_to","_finishPromise","Promise","resolve","_finish","getFinishPromise","motion","rotation","zoom","rotate","Camera","Component","_aspect","changed","_changed","yawRange","_initialYawRange","pitchRange","_initialPitchRange","zoomRange","_initialZoomRange","initialYaw","initialPitch","initialZoom","fov","rollOffset","position","animation","_up","_yawRange","_pitchRange","_zoomRange","_updateQuaternion","viewMatrix","mat4","projectionMatrix","_maxRenderHeight","destroy","off","resize","width","height","prevAspect","updateMatrix","lookAt","prevQuaternion","prevZoom","zoomDiff","normalized","isSameRotation","animateTo","finishPromise","then","trigger","restrictYawRange","restrictPitchRange","restrictZoomRange","restrictRenderHeight","resetRange","getYawRange","yawLimit","maxRenderHeight","halfHFov","getHorizontalFov","minYaw","maxYaw","halfVFovRad","h","d","theta","getPitchRange","pitchLimit","minPitch","maxPitch","halfVFov","getVerticalFov","getZoomRange","limit","minFov","maxFov","currentFov","current","_getZoomedHorizontalFov","hFov","fovToZoom","baseFov","projMatrix","upDir","viewDir","vFov","onFrameRender","MouseInput","_onMouseDown","evt","_el","button","preventDefault","focus","_prevPos","clientX","clientY","addEventListener","_onMouseMove","_onMouseUp","srcEvent","isTouch","isKeyboard","prevPos","deltaX","deltaY","removeEventListener","scrolling","enable","element","disable","TouchInput","scrollable","_scrollable","_onTouchStart","touches","_scrolling","touch","_isFirstTouch","_onTouchMove","cancelable","_onTouchEnd","passive","KeyboardInput","active","pressed","_pressed","_onKeyDown","location","KeyboardEvent","DOM_KEY_LOCATION_STANDARD","_updateKeyPress","pressedCount","_getPressedKeyCount","repeat","_onKeyUp","_clearPressedKeys","_getDeltaByPressedKeys","reduce","obj","keyName","assign","event","isEnable","keyToUpdate","keyCode","filter","RotateControl","enabled","_enabled","enableBlocked","_enableBlocked","animating","_keyboardInput","_xMotion","_yMotion","_touchInput","pointerScale","_pointerScale","keyboardScale","_keyboardScale","disablePitch","_disablePitch","disableYaw","_disableYaw","disableKeyboard","_disableKeyboard","controlEl","_onInputStart","_changedWhileDragging","inputType","_onChange","invZoomScale","_zoomScale","screenScale","_screenScale","scale","scaledX","scaledY","_onInputEnd","_controlEl","_mouseInput","_bindInputs","xMotion","yMotion","keyboardInput","updateRange","setZoomScale","hfov","vfov","control","updateCursor","sync","mouseInput","touchInput","on","WheelInput","_onWheel","stopPropagation","_inputTimer","_clearTimer","_baseScale","setTimeout","capture","clearTimeout","PinchInput","prevDistance","_prevDistance","diff","pageX","pageY","distance","ZoomControl","_wheelInput","_scale","scaledDelta","_pinchInput","wheelInput","pinchInput","ROTATE_CONSTANT","PITCH_DELTA","YAW_DELTA_BY_ROLL","YAW_DELTA_BY_YAW","targetAxis","meshPoint","GyroInput","orientationUpdated","_orientationUpdated","ignoreRoll","_ignoreRoll","_onDeviceOrientation","prevOrientation","_orientation","alpha","beta","gamma","_needsCalibrate","_calibrateSensor","_updateScreenOrientation","screen","orientation","undefined","angle","_screenOrientation","_yawOrigin","_yawOffset","_updateRotation","collectDelta","prevRotation","_toEulerDelta","setInitialRotation","yawOrigin","sensorYaw","screenAngle","world","cos","prevQuat","currentQuat","_getDeltaYaw","_getDeltaPitch","prvQ","curQ","yawDeltaByYaw","_getRotationDelta","_extractPitchFromQuat","prevQ","rotateKind","curQuaternion","prevPoint","curPoint","rotateDirection","meshPoint2","meshPoint3","vecU","vecV","vecN","coefficientA","coefficientB","coefficientC","projectedPrevPoint","trigonometricRatio","acos","crossVec","thetaDirection","baseV","GyroControl","_input","static","onDeviceMotionChange","race","res","rotationRate","available","requestPermission","permissionState","catch","_updateYawPitch","input","yawDelta","pitchDelta","PanoControl","useGrabCursor","_useGrabCursor","_setCursor","disableContextMenu","_disableContextMenu","_blockContextMenu","_restoreContextMenu","_rotateControl","wheelScrollable","_zoomControl","ignoreZoomScale","_ignoreZoomScale","gyro","_gyroControl","_preventContextMenu","_onEnable","_onDisable","_onCameraAnimationEnd","_bindEvents","isAvailable","rotateControl","zoomControl","gyroControl","hfovToZoom","zoomScale","newCursor","style","cursor","Texture","flipY","wrapS","WebGLRenderingContext","CLAMP_TO_EDGE","wrapT","isVideo","isCube","Texture2D","source","TextureVideo","video","pause","removeAttribute","load","isPaused","paused","ended","readyState","hasAudio","audioTracks","webkitAudioDecodedByteCount","mozHasAudio","TextureCube","sources","TextureLoader","_loadChecker","ImReady","src","loadVideo","Array","isArray","loadCubeImage","imgSrc","loadImage","images","_toImageArray","_load","image","naturalWidth","naturalHeight","videoConfig","config","autoplay","muted","volume","_toVideoElement","currentTime","play","videoWidth","videoHeight","content","onLoad","loader","reject","once","errorCount","check","imgEl","Image","crossOrigin","HTMLVideoElement","playsInline","setAttribute","forEach","_appendSourceElement","querySelectorAll","HTMLSourceElement","sourceEl","appendChild","FrameAnimator","maxDeltaTime","context","_context","_rafId","_rafTimer","_lastUpdateTime","callback","_time","frame","time","Date","now","requestAnimationFrame","stop","cancelAnimationFrame","changeContext","AutoResizer","useResizeObserver","_useResizeObserver","onResize","_skipFirstResize","isFirstResize","_onResize","_resizeObserver","ResizeObserver","bbox","getBoundingClientRect","resizeImmediate","resizeObserver","observe","disconnect","Autoplay","playing","_interrupted","delay","_delay","delayOnMouseLeave","_delayOnMouseLeave","speed","_speed","pauseOnHover","_pauseOnHover","canInterrupt","_canInterrupt","disableOnInterrupt","_disableOnInterrupt","viewer","options","_clearTimeout","_setUninterruptedAfterDelay","_onGyroEnable","_onMouseEnter","_hovering","_onMouseLeave","_control","_element","_interruptionTimer","enableAfterDelay","XRManager","ctx","exit","_onSessionEnd","_xrSession","_xrRefSpace","_ctx","_options","xr","navigator","isSessionSupported","enter","requestSensorPermission","requiredFeatures","makeXRCompatible","session","requestSession","bindXRLayer","refSpace","requestReferenceSpace","_setSession","xrSession","canRender","getViewerPose","getEyeParams","pose","glLayer","renderState","baseLayer","views","viewport","getViewport","vMatrix","transform","inverse","matrix","pMatrix","Hotspot","HotspotRenderer","rootEl","renderer","_containerEl","_renderer","_hotspots","_zoom","refresh","container","hotspotEls","slice","apply","_parseHotspot","render","hotspots","halfWidth","halfHeight","centerTransform","zoomTransform","hotspot","relPos","remove","screenPos","vec2","yawStr","dataset","pitchStr","positionStr","parseFloat","_yawPitchToVec3","pos","defaultPos","yawRad","pitchRad","VertexArrayObject","count","geometry","indicies","buffers","WebGLContext","canvas","_canvas","maxTextureSize","_maxTextureSize","isWebGL2","_isWebGL2","supportVAO","_extensions","vao","lost","_contextLost","debug","_debug","_onContextLost","_onContextRestore","loseContext","init","gl","_getContext","_gl","getParameter","MAX_TEXTURE_SIZE","getExtension","bindBuffer","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","forceLoseContext","extension","forceRestoreContext","restoreContext","clear","COLOR_BUFFER_BIT","drawingBufferWidth","drawingBufferHeight","createVAO","shaderProgram","nativeVAO","_createNativeVAO","_createBuffer","uv","_bindNativeVAO","_supplyGeometryData","_unbindBuffers","draw","drawElements","TRIANGLES","UNSIGNED_SHORT","releaseVAO","_deleteNativeVAO","_deleteBuffer","getUniformLocations","program","uniforms","uniformLocations","keys","locations","getUniformLocation","_getCommonUniformLocations","updateCommonUniforms","entity","mvMatrix","uniformMatrix4fv","uMVMatrix","uPMatrix","updateVRUniforms","eyeIndex","uEye","uniform1f","updateUniforms","uniform","needsUpdate","releaseShaderResources","deleteProgram","useProgram","createProgram","vertexShader","fragmentShader","vs","_compileShader","VERTEX_SHADER","fs","FRAGMENT_SHADER","attachShader","bindAttribLocation","linkProgram","getProgramParameter","LINK_STATUS","getShaderParameter","COMPILE_STATUS","getShaderInfoLog","getProgramInfoLog","deleteShader","createWebGLTexture","texData","texture","createTexture","bindTexture","TEXTURE_2D","texParameteri","TEXTURE_MIN_FILTER","TEXTURE_MAG_FILTER","TEXTURE_WRAP_S","TEXTURE_WRAP_T","gl2","texStorage2D","RGBA8","createWebGLCubeTexture","TEXTURE_CUBE_MAP","attributes","getContextAttributes","xrCompatible","xrLayer","XRWebGLLayer","updateRenderState","bindXRFrame","bindFramebuffer","FRAMEBUFFER","framebuffer","useDefaultFrameBuffer","createBuffer","buffer","deleteBuffer","createVertexArray","ext","createVertexArrayOES","bindVertexArray","bindVertexArrayOES","deleteVertexArray","deleteVertexArrayOES","_supplyIndiciesData","_supplyAttributeData","vertices","uvs","bufferData","data","STATIC_DRAW","attribute","attribLocation","getAttribLocation","vertexAttribPointer","itemSize","FLOAT","enableVertexAttribArray","shader","createShader","shaderSource","compileShader","webglIdentifiers","contextAttributes","preserveDrawingBuffer","antialias","onWebglContextCreationError","e","statusMessage","identifier","getContext","WebGLRenderer","_elementSize","pixelRatio","_pixelRatio","canvasSize","devicePixelRatio","clientWidth","clientHeight","projection","mesh","getMesh","renderVR","vr","eyeParams","eye","View360","_rootEl","_vr","_hotspot","plugins","_plugins","_projection","_initialized","initialized","_autoplay","autoInit","_autoInit","autoResize","_autoResize","canvasSelector","_canvasSelector","tabIndex","_tabIndex","_animator","updateCamera","root","renderFrame","autoPlayer","_emit","_renderFrameOnDemand","getTexture","_renderVRFrame","_delta","getElement","findCanvas","selector","_autoResizer","_addEventHandlers","releaseAllResources","plugin","animator","_bindComponentEvents","_resizeComponents","_loadTexture","_applyProjection","hasAttribute","addPlugins","push","removePlugins","pluginIdx","splice","eventName","params","evtParams","target","prevProjection","applyTexture","updateControl","contentLoader","events","evtName","VERSION","Object3D","LoadingSpinner","_startLoading","_container","_detachElements","parentElement","removeChild","_createElements","ring","RING","ControlBarItem","CONTROL_BAR_DEFAULT_CLASS","CONTROLS_ROOT","CONTROLS_BG","CONTROLS_MAIN","CONTROLS_TOP","CONTROLS_BOTTOM","CONTROLS_MID","CONTROLS_LEFT","CONTROLS_RIGHT","CONTROLS_FLOAT_LEFT","CONTROLS_FLOAT_RIGHT","CONTROLS_BUTTON","PROGRESS_ROOT","VOLUME_ROOT","RANGE_ROOT","RANGE_TRACK","RANGE_THUMB","RANGE_FILLER","PLAY_BUTTON","PAUSE_BUTTON","UNMUTED_BUTTON","MUTED_BUTTON","FULLSCREEN_BUTTON","FULLSCREEN_EXIT_BUTTON","VR_BUTTON","GYRO_ENABLED","GYRO_DISABLED","VIDEO_TIME_DISPLAY","PIEVIEW_ROOT","FIXED","UNAVAILABLE","HIDDEN","CONTROL_BAR_ITEM_POSITION","TOP_LEFT","TOP_RIGHT","MAIN_TOP","MAIN_BOTTOM","MAIN_LEFT","MAIN_RIGHT","RangeControl","_onHold","_bbox","elX","scrollX","pageXOffset","clamepdX","thumbEl","_fixedClass","_onRelease","track","thumb","filler","draggable","trackEl","fillerEl","left","right","bottom","top","updateStyle","clampedProgress","ProgressBar","_rangeControl","_onTimeUpdate","_video","_currentTime","_onDurationChange","controlBar","_controlBar","dispatchEvent","CustomEvent","detail","_wasPaused","_playPromise","_onControl","rangeControl","unavailableClass","PlayButton","_onClick","_paused","_onPlay","title","_onPause","VolumeControl","_updateDisplay","disabled","_onVolumeChange","_buttonEl","containerEl","buttonEl","FullscreenButton","_targetEl","_exitFullscreen","_requestFullscreen","_onFullscreenChange","_fullscreenAvailable","_addFullscreenHandlers","_removeFullscreenHandlers","some","request","call","VideoTime","_onCustomTimeChange","timeMinute","floor","timeSeconds","timeSecondsFormatted","durationMinute","durationSeconds","durationSecondsFormatted","innerText","PieView","resetCamera","_viewer","_updatePie","piePath","_piePathEl","rangeCircle","_rangeCircleEl","halfFov","pieRadius","pieDeg","pieOffset","isFinite","radius","rangeDiff","offset","_createPieElements","rootClass","pieSVG","createElementNS","VRButton","GyroButton","_updateStyle","enableButton","AutoHide","hidden","contains","_hiddenClass","initialDelay","idleDelay","activationDelay","_isCursorInside","show","_hideAfterDelay","_isFullscreen","showTemporaliy","_isGrabbing","pointerType","_onVideoPlay","_onVideoPause","_initialDelay","_idleDelay","_timer","hide","_clearHideTimer","VideoControl","videoEl","keyPressed","_changeVideoTime","_changeVideoVolume","_toggleVideo","forward","increase","ControlBar","backgroundEl","_bgEl","items","_items","customItems","_customItems","autoHide","showBackground","clickToPlay","keyboardControls","progressBar","playButton","volumeButton","fullscreenButton","videoTime","pieView","vrButton","gyroButton","_onStaticClick","autoHider","_autoHider","_onNewSrcLoad","_updateBackground","_updateAutoHide","_updateKeyboardHandler","item","_createPositionWrappers","POSITION","_videoControl","panoRoot","controlsRoot","defaultItems","_createDefaultItems","_addItem","_clearItemElements","category","wrapper","_wrapperEl","nextSiblingIndex","sibling","nextSibling","insertBefore","floatLeftEl","floatRightEl","topWrapper","bottomWrapper","midWrapper","leftControlsWrapper","rightControlsWrapper","firstChild","background","hiddenClass","_b","videoControl","Projection","_mesh","uTexture","Uniform","UniformTextureCube","cubemapOrder","_webglTexture","_cubemapOrder","deleteTexture","pixelStorei","UNPACK_FLIP_Y_WEBGL","uniform1i","activeTexture","TEXTURE0","texSubImage2D","TEXTURE_CUBE_MAP_POSITIVE_X","RGBA","UNSIGNED_BYTE","texImage2D","CubeTexturePainter","_size","_renderingOrder","undef","_calcRenderingSize","surfaceIdx","row","_row","column","_column","renderingFace","drawImage","UniformCanvasCube","_painter","TriangleMesh","ShaderProgram","VertexData","Geometry","Float32Array","Uint16Array","CubeGeometry","rotateUV","oneThird","coords","r","c","coord","degree","ZERO","newOrder","CW_90","CCW_90","newCoords","uvIdx","acc","concat","UniformTexture2D","CylinderGeometry","maxTheta","heightSegments","invRadialSegments","angleConst","yIdx","lngIdx","u","v","SphereGeometry","ANGLE_CORRECTION_FOR_CENTER_ALIGN","latIdx","sinTheta","cosTheta","phi","sinPhi","UniformFloat","PlaneGeometry","UniformVector4Array","uniform4fv","vector","StereoEquiProjection","_mode","mode","leftEye","rightEye","MODE","LEFT_RIGHT","uTexScaleOffset","TOP_BOTTOM","cubemapFlipX","_cubemapFlipX","partial","_partial","cylinderHeight","cylinderTheta","restrictedYaw","restrictedPitch","minZoom","REPEAT","uYaw","uPitch","uZoom","propsObj","props","propName","withMethods","attr","proto","getOwnPropertyNames","charAt","descriptor","getOwnPropertyDescriptor","value","defineProperty","args","getterDescriptor","get","set","merge","srcs","modules"],"mappings":"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"} \ No newline at end of file diff --git a/demo/release/latest/sass/base.sass b/demo/release/latest/sass/base.sass new file mode 100644 index 000000000..5160e86d7 --- /dev/null +++ b/demo/release/latest/sass/base.sass @@ -0,0 +1,17 @@ +@import variable + +.#{$view360-prefix}-container + position: relative + touch-action: pan-y + overflow: hidden + +.#{$view360-prefix}-canvas + position: absolute + left: 0 + top: 0 + width: 100% + height: 100% + user-select: none + -webkit-user-drag: none + &.ctx-lost + text-indent: 0.001px diff --git a/demo/release/latest/sass/control-bar.sass b/demo/release/latest/sass/control-bar.sass new file mode 100644 index 000000000..97806b111 --- /dev/null +++ b/demo/release/latest/sass/control-bar.sass @@ -0,0 +1,284 @@ +@import variable + +.#{$view360-prefix}-controls + position: absolute + top: 0 + left: 0 + width: 100% + height: 100% + padding: 0 + margin: 0 + border: 0 + pointer-events: none + user-select: none + -webkit-user-drag: none + z-index: 1 +.#{$view360-prefix}-main + &.#{$view360-prefix}-vr-presenting + .#{$view360-prefix}-controls + display: none + +.#{$view360-prefix}-controls-float-left, +.#{$view360-prefix}-controls-float-right + position: absolute + display: flex + flex-direction: column + +.#{$view360-prefix}-controls-float-left + left: 0px + top: 0px + +.#{$view360-prefix}-controls-float-right + right: 0px + top: 0px + +.#{$view360-prefix}-controls-main + position: absolute + bottom: 0 + left: 0 + width: 100% + opacity: 1 + transition: none + &.#{$view360-prefix}-controls-hidden + opacity: 0 + transition: opacity 500ms + * + pointer-events: none + &.#{$view360-prefix}-controls-fixed + opacity: 1 + +.#{$view360-prefix}-controls-background + width: 100% + height: calc(100% + 32px) + position: absolute + left: 0 + bottom: 0 + background-image: linear-gradient(0deg, rgba(50, 50, 50, 1), rgba(50, 50, 50, 0)) + &.#{$view360-prefix}-controls-hidden + display: none + +.#{$view360-prefix}-controls-mid + display: flex + flex-direction: row + position: relative + +.#{$view360-prefix}-controls-left + display: flex + flex: 1 + justify-content: flex-start + align-items: center + flex-direction: row + +.#{$view360-prefix}-controls-right + display: flex + align-items: center + flex-direction: row + +.#{$view360-prefix}-controls-bottom + display: flex + align-items: center + flex-direction: row + +.#{$view360-prefix}-controls-button + display: inline-block + background-color: transparent + cursor: pointer + border: 0 + position: relative + background-size: 24px 24px + background-origin: content-box + background-repeat: no-repeat + box-sizing: border-box + pointer-events: all + border-radius: 20px + transition: opacity 250ms + width: 40px + height: 40px + margin: 6px + padding: 8px + opacity: 0.8 + &:hover + opacity: 1 + &.#{$view360-prefix}-controls-vr + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48' viewBox='0 0 100 100'%3E%3Cg%3E%3Cpath d='M5,30 L95,30 L95,80 L55,80 L50,70 L45,80 L5,80 L5,30' fill='transparent' stroke='%23fff' stroke-width='8' stroke-linejoin='round' stroke-linecap='round'/%3E%3Cpath d='M5,30 L15,10 L85,10 L95,30' fill='transparent' stroke='%23fff' stroke-width='8' stroke-linejoin='round' stroke-linecap='round'/%3E%3Ccircle cx='30' cy='55' r='10' stroke='%23fff' stroke-width='8' fill='transparent' /%3E%3Ccircle cx='70' cy='55' r='10' stroke='%23fff' stroke-width='8' fill='transparent' /%3E%3C/g%3E%3C/svg%3E") + /* + * Following background-image svgs are from tabler icons + * https://github.com/tabler/tabler-icons + * + * tabler icons is licensed under the MIT license + * https://github.com/tabler/tabler-icons/blob/master/LICENSE + */ + &.#{$view360-prefix}-controls-play + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M7 4v16l13 -8z'%3E%3C/path%3E%3C/svg%3E") + &.#{$view360-prefix}-controls-pause + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Crect x='6' y='5' width='4' height='14' rx='1'%3E%3C/rect%3E%3Crect x='14' y='5' width='4' height='14' rx='1'%3E%3C/rect%3E%3C/svg%3E") + &.#{$view360-prefix}-controls-unmuted + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M15 8a5 5 0 0 1 0 8'%3E%3C/path%3E%3Cpath d='M17.7 5a9 9 0 0 1 0 14'%3E%3C/path%3E%3Cpath d='M6 15h-2a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h2l3.5 -4.5a0.8 .8 0 0 1 1.5 .5v14a0.8 .8 0 0 1 -1.5 .5l-3.5 -4.5'%3E%3C/path%3E%3C/svg%3E") + &.#{$view360-prefix}-controls-muted + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M6 15h-2a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h2l3.5 -4.5a0.8 .8 0 0 1 1.5 .5v14a0.8 .8 0 0 1 -1.5 .5l-3.5 -4.5'%3E%3C/path%3E%3Cpath d='M16 10l4 4m0 -4l-4 4'%3E%3C/path%3E%3C/svg%3E") + &.#{$view360-prefix}-controls-fullscreen + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M4 8v-2a2 2 0 0 1 2 -2h2'%3E%3C/path%3E%3Cpath d='M4 16v2a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v2'%3E%3C/path%3E%3Cpath d='M16 20h2a2 2 0 0 0 2 -2v-2'%3E%3C/path%3E%3C/svg%3E") + &.#{$view360-prefix}-controls-fullscreen-exit + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' stroke-width='2' stroke='%23fff' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M15 19v-2a2 2 0 0 1 2 -2h2'%3E%3C/path%3E%3Cpath d='M15 5v2a2 2 0 0 0 2 2h2'%3E%3C/path%3E%3Cpath d='M5 15h2a2 2 0 0 1 2 2v2'%3E%3C/path%3E%3Cpath d='M5 9h2a2 2 0 0 0 2 -2v-2'%3E%3C/path%3E%3C/svg%3E") + /* + * Following background-image svgs are from Google Material Icons + * https://fonts.google.com/icons + * + * Material Design Icons is licensed under the Apache License 2.0 + * https://github.com/google/material-design-icons/blob/master/LICENSE + */ + &.#{$view360-prefix}-controls-gyro-enabled + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48'%3E%3Cpath fill='%23fff' d='M22.5 7.6v2.95q-1 .15-1.975.475-.975.325-1.875.825L16.5 9.7q1.35-.9 2.875-1.4 1.525-.5 3.125-.7Zm15.35 15.35q-.2 1.6-.7 3.125-.5 1.525-1.4 2.875L33.6 26.8q.5-.9.825-1.875.325-.975.475-1.975Zm3.8 20.45L1.3 3.05 3.45.9 43.8 41.25ZM7 41.4q-1.25 0-2.125-.875T4 38.4v-8.6h3v8.6h8.6v3ZM41 13V4.4h-8.6v-3H41q1.25 0 2.125.875T44 4.4V13ZM4 13V4.4q0-.55.2-1.1t.6-1l2.1 2.1V13Zm28.4 28.4v-3h8.5l2.1 2.1q-.4.45-.925.675-.525.225-1.075.225Zm-21.2-37-3-3h7.4v3ZM44 37.2l-3-3v-4.4h3ZM10.15 22.95h2.95q.5 3.7 3.1 6.3 2.6 2.6 6.3 3.1v2.95q-4.9-.55-8.35-4-3.45-3.45-4-8.35Zm4-11.35 2.1 2.05q-1.3 1.3-2.1 2.9-.8 1.6-1.05 3.4h-2.95q.25-2.4 1.275-4.525Q12.45 13.3 14.15 11.6ZM31.8 29.2l2.05 2.1q-1.7 1.7-3.825 2.725Q27.9 35.05 25.5 35.3v-2.95q1.8-.25 3.4-1.05 1.6-.8 2.9-2.1ZM25.5 7.6q4.9.55 8.35 4 3.45 3.45 4 8.35H34.9q-.5-3.7-3.1-6.3-2.6-2.6-6.3-3.1Z'/%3E%3C/svg%3E") + &.#{$view360-prefix}-controls-gyro-disabled + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='48' width='48'%3E%3Cpath fill='%23fff' d='M7 44q-1.2 0-2.1-.9Q4 42.2 4 41v-8.6h3V41h8.6v3ZM4 15.6V7q0-1.2.9-2.1Q5.8 4 7 4h8.6v3H7v8.6Zm18.5 22.25q-4.9-.55-8.35-4-3.45-3.45-4-8.35h2.95q.5 3.7 3.125 6.3 2.625 2.6 6.275 3.1ZM10.15 22.5q.55-4.9 4-8.35 3.45-3.45 8.35-4v2.95q-3.7.5-6.3 3.1-2.6 2.6-3.1 6.3Zm13.85 5q-1.45 0-2.475-1.025Q20.5 25.45 20.5 24q0-1.45 1.025-2.475Q22.55 20.5 24 20.5q1.45 0 2.475 1.025Q27.5 22.55 27.5 24q0 1.45-1.025 2.475Q25.45 27.5 24 27.5Zm1.5 10.35V34.9q3.7-.5 6.3-3.125 2.6-2.625 3.1-6.275h2.95q-.55 4.9-4 8.35-3.45 3.45-8.35 4Zm9.4-15.35q-.5-3.7-3.1-6.3-2.6-2.6-6.3-3.1v-2.95q4.9.55 8.35 4 3.45 3.45 4 8.35ZM32.4 44v-3H41v-8.6h3V41q0 1.2-.9 2.1-.9.9-2.1.9ZM41 15.6V7h-8.6V4H41q1.2 0 2.1.9.9.9.9 2.1v8.6Z'/%3E%3C/svg%3E") + +.#{$view360-prefix}-controls-time + display: inline-block + vertical-align: top + white-space: nowrap + color: white + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" + font-weight: normal + font-size: 14px + z-index: 1 + &:first-child + padding: 0 16px + +.#{$view360-prefix}-controls-progress + flex: 1 + width: 100% + padding: 0 16px + box-sizing: border-box + &:not(:first-child) + padding-left: 0 +.#{$view360-prefix}-controls-bottom + .#{$view360-prefix}-controls-progress + padding-bottom: 20px + +.#{$view360-prefix}-controls-volume + display: inline-flex + flex-direction: row + align-items: center + transition: width 250ms, background-color 250ms + overflow: hidden + &:not(:disabled) + &:hover, + &.#{$view360-prefix}-controls-fixed + width: 112px + .#{$view360-prefix}-range + flex: 1 + height: 100% + padding: 0 + .#{$view360-prefix}-range-track + width: calc(100% - 12px) + transform: translateX(-4px) + .#{$view360-prefix}-controls-button + margin: 0 + padding: 0 + width: 24px + height: 24px + flex-shrink: 0 + &:disabled + opacity: 0.5 + pointer-events: none + * + pointer-events: none + +.#{$view360-prefix}-controls-pie + width: 36px + height: 36px + margin: 6px + padding: 0 + border-radius: 18px + opacity: 0.8 + pointer-events: all + cursor: pointer + color: #fff + position: relative + transition: opacity 250ms + > svg + position: absolute + top: 0 + left: 0 + width: 100% + height: 100% + &:hover + opacity: 1 + +.#{$view360-prefix}-range + position: relative + cursor: pointer + pointer-events: all + display: flex + justify-content: center + align-items: center + touch-action: pan-y + &:hover + .#{$view360-prefix}-range-thumb + opacity: 1 + +.#{$view360-prefix}-range-track + width: 100% + height: 4px + border-radius: 4px + position: relative + background-color: rgba(230, 230, 230, 0.4) + +.#{$view360-prefix}-range-filler, +.#{$view360-prefix}-range-load + position: absolute + left: 0 + top: 0 + width: 0 + height: 100% + border-radius: 4px + +.#{$view360-prefix}-range-filler + background-color: #fff + +.#{$view360-prefix}-range-load + background-color: #757575 + +.#{$view360-prefix}-range-thumb + width: 13px + height: 13px + position: absolute + top: -5px + left: -6.5px + border-radius: 50% + background-color: #fff + box-sizing: border-box + transition: opacity 250ms + opacity: 0 + &.#{$view360-prefix}-controls-fixed + opacity: 1 + +.#{$view360-prefix}-controls-unavailable + display: none !important + +@media screen and (max-width: 768px) + .#{$view360-prefix}-controls-button + background-size: 18px 18px + width: 30px + height: 30px + margin: 4.5px + padding: 6px + border-radius: 15px + + .#{$view360-prefix}-controls-volume + .#{$view360-prefix}-controls-button + width: 18px + height: 18px + + .#{$view360-prefix}-controls-volume + &:not(:disabled) + &:hover, + &.#{$view360-prefix}-controls-fixed + width: 84px + + .#{$view360-prefix}-controls-pie + width: 27px + height: 27px + margin: 4.5px + padding: 0 + border-radius: 13.5px diff --git a/demo/release/latest/sass/helper.sass b/demo/release/latest/sass/helper.sass new file mode 100644 index 000000000..1b6e364de --- /dev/null +++ b/demo/release/latest/sass/helper.sass @@ -0,0 +1,51 @@ +@import variable + +.#{$view360-prefix}-container + &.#{$view360-helper-prefix}-square, + &.#{$view360-helper-prefix}-1by1 + padding-top: 100% + + &.#{$view360-helper-prefix}-5by4 + padding-top: 80% + + &.#{$view360-helper-prefix}-4by3 + padding-top: 75% + + &.#{$view360-helper-prefix}-3by2 + padding-top: 66.6666% + + &.#{$view360-helper-prefix}-5by3 + padding-top: 60% + + &.#{$view360-helper-prefix}-16by9 + padding-top: 56.25% + + &.#{$view360-helper-prefix}-2by1 + padding-top: 50% + + &.#{$view360-helper-prefix}-3by1 + padding-top: 33.3333% + + &.#{$view360-helper-prefix}-4by5 + padding-top: 125% + + &.#{$view360-helper-prefix}-3by4 + padding-top: 133.3333% + + &.#{$view360-helper-prefix}-2by3 + padding-top: 150% + + &.#{$view360-helper-prefix}-3by5 + padding-top: 166.6666% + + &.#{$view360-helper-prefix}-9by16 + padding-top: 177.7777% + + &.#{$view360-helper-prefix}-1by2 + padding-top: 200% + + &.#{$view360-helper-prefix}-1by3 + padding-top: 300% + + &:fullscreen + padding-top: 0% diff --git a/demo/release/latest/sass/hotspot.sass b/demo/release/latest/sass/hotspot.sass new file mode 100644 index 000000000..74e235d9e --- /dev/null +++ b/demo/release/latest/sass/hotspot.sass @@ -0,0 +1,20 @@ +@import variable + +.#{$view360-prefix}-hotspots + width: 100% + height: 100% + position: absolute + top: 0 + left: 0 + pointer-events: none + +.#{$view360-prefix}-hotspot + pointer-events: none + visibility: hidden + position: absolute + top: 0 + left: 0 + +.#{$view360-prefix}-hotspot-visible + visibility: visible + pointer-events: all diff --git a/demo/release/latest/sass/loading-spinner.sass b/demo/release/latest/sass/loading-spinner.sass new file mode 100644 index 000000000..89612c129 --- /dev/null +++ b/demo/release/latest/sass/loading-spinner.sass @@ -0,0 +1,34 @@ +@import variable + +.#{$view360-prefix}-spinner + position: absolute + top: 0 + left: 0 + width: 100% + height: 100% + display: flex + justify-content: center + align-items: center + background-color: rgba(0, 0, 0, 0.15) + +.#{$view360-prefix}-spinner-ring + top: 0 + left: 0 + padding: 0 + margin: 0 + width: 64px + height: 64px + box-sizing: content-box + background-color: transparent + border-style: solid + border-radius: 50% + border-width: 10px + border-color: #fff + border-bottom-color: transparent + animation: view360-spin-animation 1.2s linear infinite + +@keyframes view360-spin-animation + 0% + transform: rotate(0deg) + 100% + transform: rotate(360deg) diff --git a/demo/release/latest/sass/variable.sass b/demo/release/latest/sass/variable.sass new file mode 100644 index 000000000..9ba2beb24 --- /dev/null +++ b/demo/release/latest/sass/variable.sass @@ -0,0 +1,2 @@ +$view360-prefix: view360 !default +$view360-helper-prefix: is !default diff --git a/demo/release/latest/sass/view360.sass b/demo/release/latest/sass/view360.sass new file mode 100644 index 000000000..ae3545abe --- /dev/null +++ b/demo/release/latest/sass/view360.sass @@ -0,0 +1,6 @@ +@import 'base' +@import 'helper' +@import 'control-bar' +@import 'loading-spinner' +@import 'vr' +@import 'hotspot' diff --git a/demo/release/latest/sass/vr.sass b/demo/release/latest/sass/vr.sass new file mode 100644 index 000000000..3a1581b72 --- /dev/null +++ b/demo/release/latest/sass/vr.sass @@ -0,0 +1,10 @@ +@import variable + +.#{$view360-prefix}-container + &.#{$view360-prefix}-vr-presenting + width: 100vw + height: 100vh + position: fixed + left: 0 + top: 0 + z-index: 9999 diff --git a/packages/ngx-view360/projects/ngx-view360/CHANGELOG.md b/packages/ngx-view360/projects/ngx-view360/CHANGELOG.md index 9c675d204..25b2b455d 100644 --- a/packages/ngx-view360/projects/ngx-view360/CHANGELOG.md +++ b/packages/ngx-view360/projects/ngx-view360/CHANGELOG.md @@ -3,6 +3,15 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.0.0-beta.4](https://github.com/naver/egjs-view360/compare/@egjs/ngx-view360@4.0.0-beta.0...@egjs/ngx-view360@4.0.0-beta.4) (2023-02-27) + + +### :mega: Other + +* update packages versions ([64d704d](https://github.com/naver/egjs-view360/commit/64d704dde25002931fb7422a817a6322542b66eb)) + + + ## 4.0.0-beta.0 (2023-02-17) diff --git a/packages/react-view360/CHANGELOG.md b/packages/react-view360/CHANGELOG.md index 656b6294d..aa07ca90d 100644 --- a/packages/react-view360/CHANGELOG.md +++ b/packages/react-view360/CHANGELOG.md @@ -3,6 +3,15 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.0.0-beta.4](https://github.com/naver/egjs-view360/compare/@egjs/react-view360@4.0.0-beta.0...@egjs/react-view360@4.0.0-beta.4) (2023-02-27) + + +### :mega: Other + +* update packages versions ([64d704d](https://github.com/naver/egjs-view360/commit/64d704dde25002931fb7422a817a6322542b66eb)) + + + ## 4.0.0-beta.0 (2023-02-17) diff --git a/packages/svelte-view360/CHANGELOG.md b/packages/svelte-view360/CHANGELOG.md index 6f27681d5..3716d4796 100644 --- a/packages/svelte-view360/CHANGELOG.md +++ b/packages/svelte-view360/CHANGELOG.md @@ -3,6 +3,15 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.0.0-beta.4](https://github.com/naver/egjs-view360/compare/@egjs/svelte-view360@4.0.0-beta.0...@egjs/svelte-view360@4.0.0-beta.4) (2023-02-27) + + +### :mega: Other + +* update packages versions ([64d704d](https://github.com/naver/egjs-view360/commit/64d704dde25002931fb7422a817a6322542b66eb)) + + + ## 4.0.0-beta.0 (2023-02-17) diff --git a/packages/view360/CHANGELOG.md b/packages/view360/CHANGELOG.md index 0b0ce99cd..6a026d376 100644 --- a/packages/view360/CHANGELOG.md +++ b/packages/view360/CHANGELOG.md @@ -3,6 +3,15 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.0.0-beta.4](https://github.com/naver/egjs-view360/compare/@egjs/view360@4.0.0-beta.0...@egjs/view360@4.0.0-beta.4) (2023-02-27) + + +### :mega: Other + +* update packages versions ([64d704d](https://github.com/naver/egjs-view360/commit/64d704dde25002931fb7422a817a6322542b66eb)) + + + ## 4.0.0-beta.0 (2023-02-17) diff --git a/packages/vue-view360/CHANGELOG.md b/packages/vue-view360/CHANGELOG.md index 656b6294d..64f95da98 100644 --- a/packages/vue-view360/CHANGELOG.md +++ b/packages/vue-view360/CHANGELOG.md @@ -3,6 +3,15 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.0.0-beta.4](https://github.com/naver/egjs-view360/compare/@egjs/vue-view360@4.0.0-beta.0...@egjs/vue-view360@4.0.0-beta.4) (2023-02-27) + + +### :mega: Other + +* update packages versions ([64d704d](https://github.com/naver/egjs-view360/commit/64d704dde25002931fb7422a817a6322542b66eb)) + + + ## 4.0.0-beta.0 (2023-02-17) diff --git a/packages/vue3-view360/CHANGELOG.md b/packages/vue3-view360/CHANGELOG.md index 19b73a664..5af21ec9a 100644 --- a/packages/vue3-view360/CHANGELOG.md +++ b/packages/vue3-view360/CHANGELOG.md @@ -3,6 +3,15 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.0.0-beta.4](https://github.com/naver/egjs-view360/compare/@egjs/vue3-view360@4.0.0-beta.0...@egjs/vue3-view360@4.0.0-beta.4) (2023-02-27) + + +### :mega: Other + +* update packages versions ([64d704d](https://github.com/naver/egjs-view360/commit/64d704dde25002931fb7422a817a6322542b66eb)) + + + ## 4.0.0-beta.0 (2023-02-17)