UNPKG

@photo-sphere-viewer/core

Version:

A JavaScript library to display 360° panoramas

1,619 lines (1,592 loc) 200 kB
/*! * Photo Sphere Viewer 5.14.1 * @copyright 2014-2015 Jérémy Heleine * @copyright 2015-2026 Damien "Mistic" Sorel * @licence MIT (https://opensource.org/licenses/MIT) */ "use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { AbstractAdapter: () => AbstractAdapter, AbstractButton: () => AbstractButton, AbstractComponent: () => AbstractComponent, AbstractConfigurablePlugin: () => AbstractConfigurablePlugin, AbstractPlugin: () => AbstractPlugin, CONSTANTS: () => constants_exports, Cache: () => Cache, DEFAULTS: () => DEFAULTS, DualFisheyeAdapter: () => DualFisheyeAdapter, EquirectangularAdapter: () => EquirectangularAdapter, PSVError: () => PSVError, SYSTEM: () => SYSTEM, TypedEvent: () => TypedEvent, VERSION: () => VERSION, Viewer: () => Viewer, events: () => events_exports, registerButton: () => registerButton, utils: () => utils_exports }); module.exports = __toCommonJS(index_exports); // src/data/constants.ts var constants_exports = {}; __export(constants_exports, { ACTIONS: () => ACTIONS, ANIMATION_MIN_DURATION: () => ANIMATION_MIN_DURATION, CAPTURE_EVENTS_CLASS: () => CAPTURE_EVENTS_CLASS, CTRLZOOM_TIMEOUT: () => CTRLZOOM_TIMEOUT, DBLCLICK_DELAY: () => DBLCLICK_DELAY, EASINGS: () => EASINGS, ICONS: () => ICONS, IDS: () => IDS, KEY_CODES: () => KEY_CODES, LONGTOUCH_DELAY: () => LONGTOUCH_DELAY, MOVE_THRESHOLD: () => MOVE_THRESHOLD, SPHERE_RADIUS: () => SPHERE_RADIUS, TWOFINGERSOVERLAY_DELAY: () => TWOFINGERSOVERLAY_DELAY, VIEWER_DATA: () => VIEWER_DATA }); // src/icons/arrow.svg var arrow_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="40 40 432 432"><g transform="rotate(0, 256, 256)"><path fill="currentColor" d="M425.23 210.55H227.39a5 5 0 01-3.53-8.53l56.56-56.57a45.5 45.5 0 000-64.28 45.15 45.15 0 00-32.13-13.3 45.15 45.15 0 00-32.14 13.3L41.32 256l174.83 174.83a45.15 45.15 0 0032.14 13.3 45.15 45.15 0 0032.13-13.3 45.5 45.5 0 000-64.28l-56.57-56.57a5 5 0 013.54-8.53h197.84c25.06 0 45.45-20.39 45.45-45.45s-20.4-45.45-45.45-45.45z"/></g><!-- Created by Flatart from the Noun Project --></svg>\n'; // src/icons/close.svg var close_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><g fill="currentColor" transform=" translate(50, 50) rotate(45)"><rect x="-5" y="-65" width="10" height="130"/><rect x="-65" y="-5" width="130" height="10"/></g></svg>'; // src/icons/download.svg var download_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path fill="currentColor" d="M83.3 35.6h-17V3H32.2v32.6H16.6l33.6 32.7 33-32.7z"/><path fill="currentColor" d="M83.3 64.2v16.3H16.6V64.2H-.1v32.6H100V64.2H83.3z"/><!--Created by Michael Zenaty from the Noun Project--></svg>\n'; // src/icons/fullscreen-in.svg var fullscreen_in_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path fill="currentColor" d="M100 40H87.1V18.8h-21V6H100zM100 93.2H66V80.3h21.1v-21H100zM34 93.2H0v-34h12.9v21.1h21zM12.9 40H0V6h34v12.9H12.8z"/><!--Created by Garrett Knoll from the Noun Project--></svg>\n'; // src/icons/fullscreen-out.svg var fullscreen_out_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path fill="currentColor" d="M66 7h13v21h21v13H66zM66 60.3h34v12.9H79v21H66zM0 60.3h34v34H21V73.1H0zM21 7h13v34H0V28h21z"/><!--Created by Garrett Knoll from the Noun Project--></svg>\n'; // src/icons/info.svg var info_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><path fill="currentColor" d="M28.3 26.1c-1 2.6-1.9 4.8-2.6 7-2.5 7.4-5 14.7-7.2 22-1.3 4.4.5 7.2 4.3 7.8 1.3.2 2.8.2 4.2-.1 8.2-2 11.9-8.6 15.7-15.2l-2.2 2a18.8 18.8 0 0 1-7.4 5.2 2 2 0 0 1-1.6-.2c-.2-.1 0-1 0-1.4l.8-1.8L41.9 28c.5-1.4.9-3 .7-4.4-.2-2.6-3-4.4-6.3-4.4-8.8.2-15 4.5-19.5 11.8-.2.3-.2.6-.3 1.3 3.7-2.8 6.8-6.1 11.8-6.2z"/><circle fill="currentColor" cx="39.3" cy="9.2" r="8.2"/><!--Created by Arafat Uddin from the Noun Project--></svg>\n'; // src/icons/menu.svg var menu_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="10 10 80 80"><g fill="currentColor"><circle r="10" cx="20" cy="20"/><circle r="10" cx="50" cy="20"/><circle r="10" cx="80" cy="20"/><circle r="10" cx="20" cy="50"/><circle r="10" cx="50" cy="50"/><circle r="10" cx="80" cy="50"/><circle r="10" cx="20" cy="80"/><circle r="10" cx="50" cy="80"/><circle r="10" cx="80" cy="80"/></g><!-- Created by Richard Kun\xE1k from the Noun Project--></svg>\n'; // src/icons/zoom-in.svg var zoom_in_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path fill="currentColor" d="M14.043 12.22a7.738 7.738 0 1 0-1.823 1.822l4.985 4.985c.503.504 1.32.504 1.822 0a1.285 1.285 0 0 0 0-1.822l-4.984-4.985zm-6.305 1.043a5.527 5.527 0 1 1 0-11.053 5.527 5.527 0 0 1 0 11.053z"/><path fill="currentColor" d="M8.728 4.009H6.744v2.737H4.006V8.73h2.738v2.736h1.984V8.73h2.737V6.746H8.728z"/><!--Created by Ryan Canning from the Noun Project--></svg>\n'; // src/icons/zoom-out.svg var zoom_out_default = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path fill="currentColor" d="M14.043 12.22a7.738 7.738 0 1 0-1.823 1.822l4.985 4.985c.503.504 1.32.504 1.822 0a1.285 1.285 0 0 0 0-1.822l-4.984-4.985zm-6.305 1.043a5.527 5.527 0 1 1 0-11.053 5.527 5.527 0 0 1 0 11.053z"/><path fill="currentColor" d="M4.006 6.746h7.459V8.73H4.006z"/><!--Created by Ryan Canning from the Noun Project--></svg>\n'; // src/data/constants.ts var ANIMATION_MIN_DURATION = 500; var MOVE_THRESHOLD = 4; var DBLCLICK_DELAY = 300; var LONGTOUCH_DELAY = 500; var TWOFINGERSOVERLAY_DELAY = 100; var CTRLZOOM_TIMEOUT = 2e3; var SPHERE_RADIUS = 10; var VIEWER_DATA = "photoSphereViewer"; var CAPTURE_EVENTS_CLASS = "psv--capture-event"; var ACTIONS = /* @__PURE__ */ ((ACTIONS2) => { ACTIONS2["ROTATE_UP"] = "ROTATE_UP"; ACTIONS2["ROTATE_DOWN"] = "ROTATE_DOWN"; ACTIONS2["ROTATE_RIGHT"] = "ROTATE_RIGHT"; ACTIONS2["ROTATE_LEFT"] = "ROTATE_LEFT"; ACTIONS2["ZOOM_IN"] = "ZOOM_IN"; ACTIONS2["ZOOM_OUT"] = "ZOOM_OUT"; return ACTIONS2; })(ACTIONS || {}); var IDS = { MENU: "menu", TWO_FINGERS: "twoFingers", CTRL_ZOOM: "ctrlZoom", ERROR: "error", DESCRIPTION: "description" }; var KEY_CODES = { Enter: "Enter", Control: "Control", Escape: "Escape", Space: " ", PageUp: "PageUp", PageDown: "PageDown", ArrowLeft: "ArrowLeft", ArrowUp: "ArrowUp", ArrowRight: "ArrowRight", ArrowDown: "ArrowDown", Delete: "Delete", Plus: "+", Minus: "-" }; var ICONS = { arrow: arrow_default, close: close_default, download: download_default, fullscreenIn: fullscreen_in_default, fullscreenOut: fullscreen_out_default, info: info_default, menu: menu_default, zoomIn: zoom_in_default, zoomOut: zoom_out_default }; var EASINGS = { linear: (t) => t, inQuad: (t) => t * t, outQuad: (t) => t * (2 - t), inOutQuad: (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t, inCubic: (t) => t * t * t, outCubic: (t) => --t * t * t + 1, inOutCubic: (t) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1, inQuart: (t) => t * t * t * t, outQuart: (t) => 1 - --t * t * t * t, inOutQuart: (t) => t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t, inQuint: (t) => t * t * t * t * t, outQuint: (t) => 1 + --t * t * t * t * t, inOutQuint: (t) => t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t, inSine: (t) => 1 - Math.cos(t * (Math.PI / 2)), outSine: (t) => Math.sin(t * (Math.PI / 2)), inOutSine: (t) => 0.5 - 0.5 * Math.cos(Math.PI * t), inExpo: (t) => Math.pow(2, 10 * (t - 1)), outExpo: (t) => 1 - Math.pow(2, -10 * t), inOutExpo: (t) => (t = t * 2 - 1) < 0 ? 0.5 * Math.pow(2, 10 * t) : 1 - 0.5 * Math.pow(2, -10 * t), inCirc: (t) => 1 - Math.sqrt(1 - t * t), outCirc: (t) => Math.sqrt(1 - (t - 1) * (t - 1)), inOutCirc: (t) => (t *= 2) < 1 ? 0.5 - 0.5 * Math.sqrt(1 - t * t) : 0.5 + 0.5 * Math.sqrt(1 - (t -= 2) * t) }; // src/utils/index.ts var utils_exports = {}; __export(utils_exports, { Animation: () => Animation, Dynamic: () => Dynamic, MultiDynamic: () => MultiDynamic, PressHandler: () => PressHandler, Slider: () => Slider, SliderDirection: () => SliderDirection, addClasses: () => addClasses, angle: () => angle, applyEulerInverse: () => applyEulerInverse, checkClosedShadowDom: () => checkClosedShadowDom, checkStylesheet: () => checkStylesheet, checkVersion: () => checkVersion, cleanCssPosition: () => cleanCssPosition, clone: () => clone, createTexture: () => createTexture, cssPositionIsOrdered: () => cssPositionIsOrdered, dasherize: () => dasherize, deepEqual: () => deepEqual, deepmerge: () => deepmerge, distance: () => distance, exitFullscreen: () => exitFullscreen, firstNonNull: () => firstNonNull, getAbortError: () => getAbortError, getAngle: () => getAngle, getClosest: () => getClosest, getConfigParser: () => getConfigParser, getElement: () => getElement, getEventTarget: () => getEventTarget, getMatchingTarget: () => getMatchingTarget, getPosition: () => getPosition, getShortestArc: () => getShortestArc, getStyleProperty: () => getStyleProperty, getTouchData: () => getTouchData, getXMPValue: () => getXMPValue, greatArcDistance: () => greatArcDistance, hasParent: () => hasParent, invertResolvableBoolean: () => invertResolvableBoolean, isAbortError: () => isAbortError, isEmpty: () => isEmpty, isExtendedPosition: () => isExtendedPosition, isFullscreenEnabled: () => isFullscreenEnabled, isNil: () => isNil, isPlainObject: () => isPlainObject, keyPressMatch: () => keyPressMatch, logWarn: () => logWarn, mergePanoData: () => mergePanoData, parseAngle: () => parseAngle, parsePoint: () => parsePoint, parseSpeed: () => parseSpeed, removeClasses: () => removeClasses, requestFullscreen: () => requestFullscreen, resolveBoolean: () => resolveBoolean, speedToDuration: () => speedToDuration, sum: () => sum, throttle: () => throttle, toggleClass: () => toggleClass, wrap: () => wrap }); // src/utils/math.ts function wrap(value, max) { let result = value % max; if (result < 0) { result += max; } return result; } function sum(array) { return array.reduce((a, b) => a + b, 0); } function distance(p1, p2) { return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2)); } function angle(p1, p2) { return Math.atan2(p2.y - p1.y, p2.x - p1.x); } function getShortestArc(from, to) { const candidates = [ 0, // direct Math.PI * 2, // clock-wise cross zero -Math.PI * 2 // counter-clock-wise cross zero ]; return candidates.reduce((value, candidate) => { const newCandidate = to - from + candidate; return Math.abs(newCandidate) < Math.abs(value) ? newCandidate : value; }, Infinity); } function getAngle(position1, position2) { return Math.acos( Math.cos(position1.pitch) * Math.cos(position2.pitch) * Math.cos(position1.yaw - position2.yaw) + Math.sin(position1.pitch) * Math.sin(position2.pitch) ); } function greatArcDistance([yaw1, pitch1], [yaw2, pitch2]) { if (yaw1 - yaw2 > Math.PI) { yaw1 -= 2 * Math.PI; } else if (yaw1 - yaw2 < -Math.PI) { yaw1 += 2 * Math.PI; } const x = (yaw2 - yaw1) * Math.cos((pitch1 + pitch2) / 2); const y = pitch2 - pitch1; return Math.sqrt(x * x + y * y); } // src/utils/browser.ts function getElement(selector) { if (typeof selector === "string") { return selector.match(/^[a-z]/i) ? document.getElementById(selector) : document.querySelector(selector); } else { return selector; } } function toggleClass(element, className, active) { if (active === void 0) { element.classList.toggle(className); } else if (active) { element.classList.add(className); } else if (!active) { element.classList.remove(className); } } function addClasses(element, className) { element.classList.add(...className.split(" ").filter((c) => !!c)); } function removeClasses(element, className) { element.classList.remove(...className.split(" ").filter((c) => !!c)); } function hasParent(el, parent) { let test = el; do { if (test === parent) { return true; } test = test.parentElement; } while (test); return false; } function getClosest(el, selector) { if (!el?.matches) { return null; } let test = el; do { if (test.matches(selector)) { return test; } test = test.parentElement; } while (test); return null; } function getEventTarget(e) { return e?.composedPath()[0] || null; } function getMatchingTarget(e, selector) { if (!e) { return null; } return e.composedPath().find((el) => { if (!(el instanceof HTMLElement) && !(el instanceof SVGElement)) { return false; } return el.matches(selector); }); } function getPosition(el) { let x = 0; let y = 0; let test = el; while (test) { x += test.offsetLeft - test.scrollLeft + test.clientLeft; y += test.offsetTop - test.scrollTop + test.clientTop; test = test.offsetParent; } x -= window.scrollX; y -= window.scrollY; return { x, y }; } function getStyleProperty(elt, varname) { return window.getComputedStyle(elt).getPropertyValue(varname); } function getTouchData(e) { if (e.touches.length < 2) { return null; } const p1 = { x: e.touches[0].clientX, y: e.touches[0].clientY }; const p2 = { x: e.touches[1].clientX, y: e.touches[1].clientY }; return { distance: distance(p1, p2), angle: angle(p1, p2), center: { x: (p1.x + p2.x) / 2, y: (p1.y + p2.y) / 2 } }; } var fullscreenElement; function isFullscreenEnabled(elt, isIphone = false) { if (isIphone) { return elt === fullscreenElement; } else { return document.fullscreenElement === elt; } } function requestFullscreen(elt, isIphone = false) { if (isIphone) { fullscreenElement = elt; elt.classList.add("psv-fullscreen-emulation"); document.dispatchEvent(new Event("fullscreenchange")); } else { elt.requestFullscreen(); } } function exitFullscreen(isIphone = false) { if (isIphone) { fullscreenElement.classList.remove("psv-fullscreen-emulation"); fullscreenElement = null; document.dispatchEvent(new Event("fullscreenchange")); } else { document.exitFullscreen(); } } function keyPressMatch(e, pattern) { let key; let shift = false; let ctrl = false; let alt = false; let meta = false; if (pattern === "+") { key = pattern; } else { pattern.split("+").forEach((p) => { switch (p) { case "Shift": shift = true; break; case "Ctrl": ctrl = true; break; case "Alt": alt = true; break; case "Meta": meta = true; break; case "Space": key = " "; break; case "Plus": key = "+"; break; case "Minus": key = "-"; break; default: key = p; break; } }); } return shift === e.shiftKey && ctrl === e.ctrlKey && alt === e.altKey && meta === e.metaKey && key === e.key; } // src/utils/misc.ts function dasherize(str) { return str.replace(/[A-Z](?:(?=[^A-Z])|[A-Z]*(?=[A-Z][^A-Z]|$))/g, (s, i) => { return (i > 0 ? "-" : "") + s.toLowerCase(); }); } function throttle(callback, wait) { let paused = false; return function(...args) { if (!paused) { paused = true; setTimeout(() => { callback.apply(this, args); paused = false; }, wait); } }; } function isPlainObject(value) { if (typeof value !== "object" || value === null || Object.prototype.toString.call(value) !== "[object Object]") { return false; } if (Object.getPrototypeOf(value) === null) { return true; } let proto = value; while (Object.getPrototypeOf(proto) !== null) { proto = Object.getPrototypeOf(proto); } return Object.getPrototypeOf(value) === proto; } function deepmerge(target, src) { const first = src; return function merge(target2, src2) { if (Array.isArray(src2)) { if (!target2 || !Array.isArray(target2)) { target2 = []; } else { target2.length = 0; } src2.forEach((e, i) => { target2[i] = merge(null, e); }); } else if (typeof src2 === "object") { if (!target2 || Array.isArray(target2)) { target2 = {}; } Object.keys(src2).forEach((key) => { if (key === "__proto__") { return; } if (typeof src2[key] !== "object" || !src2[key] || !isPlainObject(src2[key])) { target2[key] = src2[key]; } else if (src2[key] !== first) { if (!target2[key]) { target2[key] = merge(null, src2[key]); } else { merge(target2[key], src2[key]); } } }); } else { target2 = src2; } return target2; }(target, src); } function clone(src) { return deepmerge(null, src); } function isEmpty(obj) { return !obj || Object.keys(obj).length === 0 && obj.constructor === Object; } function isNil(val) { return val === null || val === void 0; } function firstNonNull(...values) { for (const val of values) { if (!isNil(val)) { return val; } } return null; } function deepEqual(obj1, obj2) { if (obj1 === obj2) { return true; } else if (isObject(obj1) && isObject(obj2)) { if (Object.keys(obj1).length !== Object.keys(obj2).length) { return false; } for (const prop of Object.keys(obj1)) { if (!deepEqual(obj1[prop], obj2[prop])) { return false; } } return true; } else { return false; } } function isObject(obj) { return typeof obj === "object" && obj !== null; } // src/utils/psv.ts var import_three = require("three"); // src/PSVError.ts var PSVError = class _PSVError extends Error { constructor(message, reason) { super(reason && reason instanceof Error ? `${message}: ${reason.message}` : message); this.name = "PSVError"; Error.captureStackTrace?.(this, _PSVError); } }; // src/utils/psv.ts function resolveBoolean(value, cb) { if (isPlainObject(value)) { cb(value.initial, true); value.promise.then((res) => cb(res, false)); } else { cb(value, true); } } function invertResolvableBoolean(value) { return { initial: !value.initial, promise: value.promise.then((res) => !res) }; } function getAbortError() { const error = new Error("Loading was aborted."); error.name = "AbortError"; return error; } function isAbortError(err) { return err?.name === "AbortError"; } function logWarn(message) { console.warn(`PhotoSphereViewer: ${message}`); } function isExtendedPosition(object) { if (!object || Array.isArray(object)) { return false; } return [ ["textureX", "textureY"], ["yaw", "pitch"] ].some(([key1, key2]) => { return object[key1] !== void 0 && object[key2] !== void 0; }); } function getXMPValue(data, attr, intVal = true) { let result = data.match("<GPano:" + attr + ">(.*)</GPano:" + attr + ">"); if (result !== null) { const val = intVal ? parseInt(result[1], 10) : parseFloat(result[1]); return isNaN(val) ? null : val; } result = data.match("GPano:" + attr + '="(.*?)"'); if (result !== null) { const val = intVal ? parseInt(result[1], 10) : parseFloat(result[1]); return isNaN(val) ? null : val; } return null; } var CSS_POSITIONS = { top: "0%", bottom: "100%", left: "0%", right: "100%", center: "50%" }; var X_VALUES = ["left", "center", "right"]; var Y_VALUES = ["top", "center", "bottom"]; var POS_VALUES = [...X_VALUES, ...Y_VALUES]; var CENTER = "center"; function parsePoint(value) { if (!value) { return { x: 0.5, y: 0.5 }; } if (typeof value === "object") { return value; } let tokens = value.toLocaleLowerCase().split(" ").slice(0, 2); if (tokens.length === 1) { if (CSS_POSITIONS[tokens[0]]) { tokens = [tokens[0], CENTER]; } else { tokens = [tokens[0], tokens[0]]; } } const xFirst = tokens[1] !== "left" && tokens[1] !== "right" && tokens[0] !== "top" && tokens[0] !== "bottom"; tokens = tokens.map((token) => CSS_POSITIONS[token] || token); if (!xFirst) { tokens.reverse(); } const parsed = tokens.join(" ").match(/^([0-9.]+)% ([0-9.]+)%$/); if (parsed) { return { x: parseFloat(parsed[1]) / 100, y: parseFloat(parsed[2]) / 100 }; } else { return { x: 0.5, y: 0.5 }; } } function cleanCssPosition(value, { allowCenter, cssOrder } = { allowCenter: true, cssOrder: true }) { if (!value) { return null; } if (typeof value === "string") { value = value.split(" "); } if (value.length === 1) { if (value[0] === CENTER) { value = [CENTER, CENTER]; } else if (X_VALUES.indexOf(value[0]) !== -1) { value = [CENTER, value[0]]; } else if (Y_VALUES.indexOf(value[0]) !== -1) { value = [value[0], CENTER]; } } if (value.length !== 2 || POS_VALUES.indexOf(value[0]) === -1 || POS_VALUES.indexOf(value[1]) === -1) { logWarn(`Unparsable position ${value}`); return null; } if (!allowCenter && value[0] === CENTER && value[1] === CENTER) { logWarn(`Invalid position center center`); return null; } if (cssOrder && !cssPositionIsOrdered(value)) { value = [value[1], value[0]]; } if (value[1] === CENTER && X_VALUES.indexOf(value[0]) !== -1) { value = [CENTER, value[0]]; } if (value[0] === CENTER && Y_VALUES.indexOf(value[1]) !== -1) { value = [value[1], CENTER]; } return value; } function cssPositionIsOrdered(value) { return Y_VALUES.indexOf(value[0]) !== -1 && X_VALUES.indexOf(value[1]) !== -1; } function parseSpeed(speed) { let parsed; if (typeof speed === "string") { const speedStr = speed.toString().trim(); let speedValue = parseFloat(speedStr.replace(/^(-?[0-9]+(?:\.[0-9]*)?).*$/, "$1")); const speedUnit = speedStr.replace(/^-?[0-9]+(?:\.[0-9]*)?(.*)$/, "$1").trim(); if (speedUnit.match(/(pm|per minute)$/)) { speedValue /= 60; } switch (speedUnit) { // Degrees per minute / second case "dpm": case "degrees per minute": case "dps": case "degrees per second": parsed = import_three.MathUtils.degToRad(speedValue); break; // Radians per minute / second case "rdpm": case "radians per minute": case "rdps": case "radians per second": parsed = speedValue; break; // Revolutions per minute / second case "rpm": case "revolutions per minute": case "rps": case "revolutions per second": parsed = speedValue * Math.PI * 2; break; // Unknown unit default: throw new PSVError(`Unknown speed unit "${speedUnit}"`); } } else { parsed = speed; } return parsed; } function speedToDuration(value, angle2) { if (typeof value !== "number") { const speed = parseSpeed(value); return angle2 / Math.abs(speed) * 1e3; } else { return Math.abs(value); } } function parseAngle(angle2, zeroCenter = false, halfCircle = zeroCenter) { let parsed; if (typeof angle2 === "string") { const match = angle2.toLowerCase().trim().match(/^(-?[0-9]+(?:\.[0-9]*)?)(.*)$/); if (!match) { throw new PSVError(`Unknown angle "${angle2}"`); } const value = parseFloat(match[1]); const unit = match[2]; if (unit) { switch (unit) { case "deg": case "degs": parsed = import_three.MathUtils.degToRad(value); break; case "rad": case "rads": parsed = value; break; default: throw new PSVError(`Unknown angle unit "${unit}"`); } } else { parsed = value; } } else if (typeof angle2 === "number" && !isNaN(angle2)) { parsed = angle2; } else { throw new PSVError(`Unknown angle "${angle2}"`); } parsed = wrap(zeroCenter ? parsed + Math.PI : parsed, Math.PI * 2); return zeroCenter ? import_three.MathUtils.clamp(parsed - Math.PI, -Math.PI / (halfCircle ? 2 : 1), Math.PI / (halfCircle ? 2 : 1)) : parsed; } function createTexture(img, mimaps = false) { const texture = new import_three.Texture(img); texture.needsUpdate = true; texture.minFilter = mimaps ? import_three.LinearMipmapLinearFilter : import_three.LinearFilter; texture.generateMipmaps = mimaps; texture.anisotropy = mimaps ? 2 : 1; return texture; } var quaternion = new import_three.Quaternion(); function applyEulerInverse(vector, euler) { quaternion.setFromEuler(euler).invert(); vector.applyQuaternion(quaternion); } function getConfigParser(defaults, parsers) { const parser = function(userConfig) { const rawConfig = clone({ ...defaults, ...userConfig }); const config = {}; for (let [key, value] of Object.entries(rawConfig)) { if (parsers && key in parsers) { value = parsers[key](value, { rawConfig, defValue: defaults[key] }); } else if (!(key in defaults)) { logWarn(`Unknown option ${key}`); continue; } config[key] = value; } return config; }; parser.defaults = defaults; parser.parsers = parsers || {}; return parser; } function checkStylesheet(element, name) { if (getStyleProperty(element, `--psv-${name}-loaded`) !== "true") { console.error(`PhotoSphereViewer: stylesheet "@photo-sphere-viewer/${name}/index.css" is not loaded`); } } function checkVersion(name, version, coreVersion) { if (version && version !== coreVersion) { console.error(`PhotoSphereViewer: @photo-sphere-viewer/${name} is in version ${version} but @photo-sphere-viewer/core is in version ${coreVersion}`); } } function checkClosedShadowDom(el) { do { if (el instanceof ShadowRoot && el.mode === "closed") { console.error(`PhotoSphereViewer: closed shadow DOM detected, the viewer might not work as expected`); return; } el = el.parentNode; } while (el); } function mergePanoData(width, height, newPanoData, xmpPanoData) { const panoData = { isEquirectangular: true, fullWidth: firstNonNull(newPanoData?.fullWidth, xmpPanoData?.fullWidth), fullHeight: firstNonNull(newPanoData?.fullHeight, xmpPanoData?.fullHeight), croppedWidth: firstNonNull(newPanoData?.croppedWidth, xmpPanoData?.croppedWidth, width), croppedHeight: firstNonNull(newPanoData?.croppedHeight, xmpPanoData?.croppedHeight, height), croppedX: firstNonNull(newPanoData?.croppedX, xmpPanoData?.croppedX), croppedY: firstNonNull(newPanoData?.croppedY, xmpPanoData?.croppedY), poseHeading: firstNonNull(newPanoData?.poseHeading, xmpPanoData?.poseHeading, 0), posePitch: firstNonNull(newPanoData?.posePitch, xmpPanoData?.posePitch, 0), poseRoll: firstNonNull(newPanoData?.poseRoll, xmpPanoData?.poseRoll, 0), initialHeading: xmpPanoData?.initialHeading, initialPitch: xmpPanoData?.initialPitch, initialFov: xmpPanoData?.initialFov }; if (panoData.croppedWidth !== width) { const ratio = width / panoData.croppedWidth; [ "fullWidth", "fullHeight", "croppedWidth", "croppedHeight", "croppedX", "croppedY" ].forEach((key) => { if (panoData[key]) { panoData[key] = Math.round(panoData[key] * ratio); } }); } if (!panoData.fullWidth && !panoData.fullHeight) { panoData.fullWidth = Math.max(panoData.croppedWidth, panoData.croppedHeight * 2); panoData.fullHeight = Math.round(panoData.fullWidth / 2); } if (!panoData.fullWidth) { panoData.fullWidth = panoData.fullHeight * 2; } if (!panoData.fullHeight) { panoData.fullHeight = Math.round(panoData.fullWidth / 2); } if (panoData.croppedX === null) { panoData.croppedX = Math.round((panoData.fullWidth - width) / 2); } if (panoData.croppedY === null) { panoData.croppedY = Math.round((panoData.fullHeight - height) / 2); } if (Math.abs(panoData.fullWidth - panoData.fullHeight * 2) > 1) { logWarn("Invalid panoData, fullWidth should be twice fullHeight"); panoData.fullHeight = Math.round(panoData.fullWidth / 2); } if (panoData.croppedX + panoData.croppedWidth > panoData.fullWidth) { logWarn("Invalid panoData, croppedX + croppedWidth > fullWidth"); panoData.croppedX = panoData.fullWidth - panoData.croppedWidth; } if (panoData.croppedY + panoData.croppedHeight > panoData.fullHeight) { logWarn("Invalid panoData, croppedY + croppedHeight > fullHeight"); panoData.croppedY = panoData.fullHeight - panoData.croppedHeight; } if (panoData.croppedX < 0) { logWarn("Invalid panoData, croppedX < 0"); panoData.croppedX = 0; } if (panoData.croppedY < 0) { logWarn("Invalid panoData, croppedY < 0"); panoData.croppedY = 0; } return panoData; } // src/utils/Animation.ts var Animation = class { constructor(options) { this.easing = EASINGS["linear"]; this.callbacks = []; this.resolved = false; this.cancelled = false; this.options = options; if (options) { if (options.easing) { this.easing = typeof options.easing === "function" ? options.easing : EASINGS[options.easing] || EASINGS["linear"]; } this.delayTimeout = setTimeout(() => { this.delayTimeout = void 0; this.animationFrame = window.requestAnimationFrame((t) => this.__run(t)); }, options.delay || 0); } else { this.resolved = true; } } __run(timestamp) { if (this.cancelled) { return; } if (!this.start) { this.start = timestamp; } const progress = (timestamp - this.start) / this.options.duration; const current = {}; if (progress < 1) { for (const [name, prop] of Object.entries(this.options.properties)) { if (prop) { const value = prop.start + (prop.end - prop.start) * this.easing(progress); current[name] = value; } } this.options.onTick(current, progress); this.animationFrame = window.requestAnimationFrame((t) => this.__run(t)); } else { for (const [name, prop] of Object.entries(this.options.properties)) { if (prop) { current[name] = prop.end; } } this.options.onTick(current, 1); this.__resolve(true); this.animationFrame = void 0; } } __resolve(value) { if (value) { this.resolved = true; } else { this.cancelled = true; } this.callbacks.forEach((cb) => cb(value)); this.callbacks.length = 0; } /** * Promise chaining * @param [onFulfilled] - Called when the animation is complete (true) or cancelled (false) */ then(onFulfilled) { if (this.resolved || this.cancelled) { return Promise.resolve(this.resolved).then(onFulfilled); } return new Promise((resolve) => { this.callbacks.push(resolve); }).then(onFulfilled); } /** * Cancels the animation */ cancel() { if (!this.cancelled && !this.resolved) { this.__resolve(false); if (this.delayTimeout) { window.clearTimeout(this.delayTimeout); this.delayTimeout = void 0; } if (this.animationFrame) { window.cancelAnimationFrame(this.animationFrame); this.animationFrame = void 0; } } } }; // src/utils/Dynamic.ts var import_three2 = require("three"); var Dynamic = class { constructor(fn, config) { this.fn = fn; this.mode = 0 /* STOP */; this.speed = 0; this.speedMult = 0; this.currentSpeed = 0; this.target = 0; this.__current = 0; this.min = config.min; this.max = config.max; this.wrap = config.wrap; this.current = config.defaultValue; if (this.wrap && this.min !== 0) { throw new PSVError("invalid config"); } if (this.fn) { this.fn(this.current); } } get current() { return this.__current; } set current(current) { this.__current = current; } /** * Changes base speed */ setSpeed(speed) { this.speed = speed; } /** * Defines the target position */ goto(position, speedMult = 1) { this.mode = 2 /* POSITION */; this.target = this.wrap ? wrap(position, this.max) : import_three2.MathUtils.clamp(position, this.min, this.max); this.speedMult = speedMult; } /** * Increases/decreases the target position */ step(step, speedMult = 1) { if (speedMult === 0) { this.setValue(this.current + step); } else { if (this.mode !== 2 /* POSITION */) { this.target = this.current; } this.goto(this.target + step, speedMult); } } /** * Starts infinite movement */ roll(invert = false, speedMult = 1) { this.mode = 1 /* INFINITE */; this.target = invert ? -Infinity : Infinity; this.speedMult = speedMult; } /** * Stops movement */ stop() { this.mode = 0 /* STOP */; } /** * Defines the current position and immediately stops movement * @param {number} value */ setValue(value) { this.target = this.wrap ? wrap(value, this.max) : import_three2.MathUtils.clamp(value, this.min, this.max); this.mode = 0 /* STOP */; this.currentSpeed = 0; if (this.target !== this.current) { this.current = this.target; if (this.fn) { this.fn(this.current); } return true; } return false; } /** * @internal */ update(elapsed) { if (this.mode === 2 /* POSITION */) { if (this.wrap && Math.abs(this.target - this.current) > this.max / 2) { this.current = this.current < this.target ? this.current + this.max : this.current - this.max; } const dstStop = this.currentSpeed * this.currentSpeed / (this.speed * this.speedMult * 4); if (Math.abs(this.target - this.current) <= dstStop) { this.mode = 0 /* STOP */; } } let targetSpeed = this.mode === 0 /* STOP */ ? 0 : this.speed * this.speedMult; if (this.target < this.current) { targetSpeed = -targetSpeed; } if (this.currentSpeed < targetSpeed) { this.currentSpeed = Math.min( targetSpeed, this.currentSpeed + elapsed / 1e3 * this.speed * this.speedMult * 2 ); } else if (this.currentSpeed > targetSpeed) { this.currentSpeed = Math.max( targetSpeed, this.currentSpeed - elapsed / 1e3 * this.speed * this.speedMult * 2 ); } let next = null; if (this.current > this.target && this.currentSpeed) { next = Math.max(this.target, this.current + this.currentSpeed * elapsed / 1e3); } else if (this.current < this.target && this.currentSpeed) { next = Math.min(this.target, this.current + this.currentSpeed * elapsed / 1e3); } if (next !== null) { next = this.wrap ? wrap(next, this.max) : import_three2.MathUtils.clamp(next, this.min, this.max); if (next !== this.current) { this.current = next; if (this.fn) { this.fn(this.current); } return true; } } return false; } }; // src/utils/MultiDynamic.ts var MultiDynamic = class { constructor(fn, dynamics) { this.fn = fn; this.dynamics = dynamics; if (this.fn) { this.fn(this.current); } } get current() { return Object.entries(this.dynamics).reduce( (values, [name, dynamic]) => { values[name] = dynamic.current; return values; }, {} ); } /** * Changes base speed */ setSpeed(speed) { for (const d of Object.values(this.dynamics)) { d.setSpeed(speed); } } /** * Defines the target positions */ goto(positions, speedMult = 1) { for (const [name, position] of Object.entries(positions)) { this.dynamics[name].goto(position, speedMult); } } /** * Increase/decrease the target positions */ step(steps, speedMult = 1) { if (speedMult === 0) { this.setValue( Object.keys(steps).reduce( (values, name) => { values[name] = steps[name] + this.dynamics[name].current; return values; }, {} ) ); } else { for (const [name, step] of Object.entries(steps)) { this.dynamics[name].step(step, speedMult); } } } /** * Starts infinite movements */ roll(rolls, speedMult = 1) { for (const [name, roll] of Object.entries(rolls)) { this.dynamics[name].roll(roll, speedMult); } } /** * Stops movements */ stop() { for (const d of Object.values(this.dynamics)) { d.stop(); } } /** * Defines the current positions and immediately stops movements */ setValue(values) { let hasUpdates = false; for (const [name, value] of Object.entries(values)) { hasUpdates = this.dynamics[name].setValue(value) || hasUpdates; } if (hasUpdates && this.fn) { this.fn(this.current); } return hasUpdates; } /** * @internal */ update(elapsed) { let hasUpdates = false; for (const d of Object.values(this.dynamics)) { hasUpdates = d.update(elapsed) || hasUpdates; } if (hasUpdates && this.fn) { this.fn(this.current); } return hasUpdates; } }; // src/utils/PressHandler.ts var PressHandler = class { constructor(delay = 200) { this.delay = delay; this.time = 0; this.delay = delay; } get pending() { return this.time !== 0; } down(data) { if (this.timeout) { clearTimeout(this.timeout); this.timeout = void 0; } this.time = (/* @__PURE__ */ new Date()).getTime(); this.data = data; } up(cb) { if (!this.time) { return; } const elapsed = Date.now() - this.time; if (elapsed < this.delay) { this.timeout = setTimeout(() => { cb(this.data); this.timeout = void 0; this.time = 0; this.data = void 0; }, this.delay); } else { cb(this.data); this.time = 0; this.data = void 0; } } }; // src/utils/Slider.ts var import_three3 = require("three"); var SliderDirection = /* @__PURE__ */ ((SliderDirection2) => { SliderDirection2["VERTICAL"] = "VERTICAL"; SliderDirection2["HORIZONTAL"] = "HORIZONTAL"; return SliderDirection2; })(SliderDirection || {}); var Slider = class { constructor(container, direction, listener) { this.container = container; this.direction = direction; this.listener = listener; this.mousedown = false; this.mouseover = false; this.container.addEventListener("click", this); this.container.addEventListener("mousedown", this); this.container.addEventListener("mouseenter", this); this.container.addEventListener("mouseleave", this); this.container.addEventListener("touchstart", this); this.container.addEventListener("mousemove", this, true); this.container.addEventListener("touchmove", this, true); window.addEventListener("mouseup", this); window.addEventListener("touchend", this); } get isVertical() { return this.direction === "VERTICAL" /* VERTICAL */; } get isHorizontal() { return this.direction === "HORIZONTAL" /* HORIZONTAL */; } destroy() { window.removeEventListener("mouseup", this); window.removeEventListener("touchend", this); } /** * @internal */ handleEvent(e) { switch (e.type) { case "click": e.stopPropagation(); break; case "mousedown": this.__onMouseDown(e); break; case "mouseenter": this.__onMouseEnter(e); break; case "mouseleave": this.__onMouseLeave(e); break; case "touchstart": this.__onTouchStart(e); break; case "mousemove": this.__onMouseMove(e); break; case "touchmove": this.__onTouchMove(e); break; case "mouseup": this.__onMouseUp(e); break; case "touchend": this.__onTouchEnd(e); break; } } __onMouseDown(evt) { this.mousedown = true; this.__update(evt.clientX, evt.clientY, true); } __onMouseEnter(evt) { this.mouseover = true; this.__update(evt.clientX, evt.clientY, true); } __onTouchStart(evt) { this.mouseover = true; this.mousedown = true; const touch = evt.changedTouches[0]; this.__update(touch.clientX, touch.clientY, true); } __onMouseMove(evt) { if (this.mousedown || this.mouseover) { evt.stopPropagation(); this.__update(evt.clientX, evt.clientY, true); } } __onTouchMove(evt) { if (this.mousedown || this.mouseover) { evt.stopPropagation(); const touch = evt.changedTouches[0]; this.__update(touch.clientX, touch.clientY, true); } } __onMouseUp(evt) { if (this.mousedown) { this.mousedown = false; this.__update(evt.clientX, evt.clientY, false); } } __onMouseLeave(evt) { if (this.mouseover) { this.mouseover = false; this.__update(evt.clientX, evt.clientY, true); } } __onTouchEnd(evt) { if (this.mousedown) { this.mouseover = false; this.mousedown = false; const touch = evt.changedTouches[0]; this.__update(touch.clientX, touch.clientY, false); } } __update(clientX, clientY, moving) { const boundingClientRect = this.container.getBoundingClientRect(); let val; if (this.isVertical) { val = import_three3.MathUtils.clamp((boundingClientRect.bottom - clientY) / boundingClientRect.height, 0, 1); } else { val = import_three3.MathUtils.clamp((clientX - boundingClientRect.left) / boundingClientRect.width, 0, 1); } this.listener({ value: val, click: !moving, mousedown: this.mousedown, mouseover: this.mouseover, cursor: { clientX, clientY } }); } }; // src/events.ts var events_exports = {}; __export(events_exports, { BeforeAnimateEvent: () => BeforeAnimateEvent, BeforeRenderEvent: () => BeforeRenderEvent, BeforeRotateEvent: () => BeforeRotateEvent, ClickEvent: () => ClickEvent, ConfigChangedEvent: () => ConfigChangedEvent, DoubleClickEvent: () => DoubleClickEvent, FullscreenEvent: () => FullscreenEvent, HideNotificationEvent: () => HideNotificationEvent, HideOverlayEvent: () => HideOverlayEvent, HidePanelEvent: () => HidePanelEvent, HideTooltipEvent: () => HideTooltipEvent, KeypressEvent: () => KeypressEvent, LoadProgressEvent: () => LoadProgressEvent, ObjectEnterEvent: () => ObjectEnterEvent, ObjectEvent: () => ObjectEvent, ObjectHoverEvent: () => ObjectHoverEvent, ObjectLeaveEvent: () => ObjectLeaveEvent, PanoramaErrorEvent: () => PanoramaErrorEvent, PanoramaLoadEvent: () => PanoramaLoadEvent, PanoramaLoadedEvent: () => PanoramaLoadedEvent, PositionUpdatedEvent: () => PositionUpdatedEvent, ReadyEvent: () => ReadyEvent, RenderEvent: () => RenderEvent, RollUpdatedEvent: () => RollUpdatedEvent, ShowNotificationEvent: () => ShowNotificationEvent, ShowOverlayEvent: () => ShowOverlayEvent, ShowPanelEvent: () => ShowPanelEvent, ShowTooltipEvent: () => ShowTooltipEvent, SizeUpdatedEvent: () => SizeUpdatedEvent, StopAllEvent: () => StopAllEvent, TransitionDoneEvent: () => TransitionDoneEvent, ViewerEvent: () => ViewerEvent, ZoomUpdatedEvent: () => ZoomUpdatedEvent }); // src/lib/TypedEventTarget.ts var TypedEvent = class extends Event { constructor(type, cancelable = false) { super(type, { cancelable }); } }; var TypedEventTarget = class extends EventTarget { dispatchEvent(e) { return super.dispatchEvent(e); } /** * @template T the name of event * @template E the class of the event */ addEventListener(type, callback, options) { super.addEventListener(type, callback, options); } /** * @template T the name of event * @template E the class of the event */ removeEventListener(type, callback, options) { super.removeEventListener(type, callback, options); } }; // src/events.ts var ViewerEvent = class extends TypedEvent { }; var _BeforeAnimateEvent = class _BeforeAnimateEvent extends ViewerEvent { /** @internal */ constructor(position, zoomLevel) { super(_BeforeAnimateEvent.type, true); this.position = position; this.zoomLevel = zoomLevel; } }; _BeforeAnimateEvent.type = "before-animate"; var BeforeAnimateEvent = _BeforeAnimateEvent; var _BeforeRenderEvent = class _BeforeRenderEvent extends ViewerEvent { /** @internal */ constructor(timestamp, elapsed) { super(_BeforeRenderEvent.type); this.timestamp = timestamp; this.elapsed = elapsed; } }; _BeforeRenderEvent.type = "before-render"; var BeforeRenderEvent = _BeforeRenderEvent; var _BeforeRotateEvent = class _BeforeRotateEvent extends ViewerEvent { /** @internal */ constructor(position) { super(_BeforeRotateEvent.type, true); this.position = position; } }; _BeforeRotateEvent.type = "before-rotate"; var BeforeRotateEvent = _BeforeRotateEvent; var _ClickEvent = class _ClickEvent extends ViewerEvent { /** @internal */ constructor(data) { super(_ClickEvent.type); this.data = data; } }; _ClickEvent.type = "click"; var ClickEvent = _ClickEvent; var _ConfigChangedEvent = class _ConfigChangedEvent extends ViewerEvent { /** @internal */ constructor(options) { super(_ConfigChangedEvent.type); this.options = options; } /** * Checks if at least one of the `options` has been modified */ containsOptions(...options) { return options.some((option) => this.options.includes(option)); } }; _ConfigChangedEvent.type = "config-changed"; var ConfigChangedEvent = _ConfigChangedEvent; var _DoubleClickEvent = class _DoubleClickEvent extends ViewerEvent { /** @internal */ constructor(data) { super(_DoubleClickEvent.type); this.data = data; } }; _DoubleClickEvent.type = "dblclick"; var DoubleClickEvent = _DoubleClickEvent; var _FullscreenEvent = class _FullscreenEvent extends ViewerEvent { /** @internal */ constructor(fullscreenEnabled) { super(_FullscreenEvent.type); this.fullscreenEnabled = fullscreenEnabled; } }; _FullscreenEvent.type = "fullscreen"; var FullscreenEvent = _FullscreenEvent; var _HideNotificationEvent = class _HideNotificationEvent extends ViewerEvent { /** @internal */ constructor(notificationId) { super(_HideNotificationEvent.type); this.notificationId = notificationId; } }; _HideNotificationEvent.type = "hide-notification"; var HideNotificationEvent = _HideNotificationEvent; var _HideOverlayEvent = class _HideOverlayEvent extends ViewerEvent { /** @internal */ constructor(overlayId) { super(_HideOverlayEvent.type); this.overlayId = overlayId; } }; _HideOverlayEvent.type = "hide-overlay"; var HideOverlayEvent = _HideOverlayEvent; var _HidePanelEvent = class _HidePanelEvent extends ViewerEvent { /** @internal */ constructor(panelId) { super(_HidePanelEvent.type); this.panelId = panelId; } }; _HidePanelEvent.type = "hide-panel"; var HidePanelEvent = _HidePanelEvent; var _HideTooltipEvent = class _HideTooltipEvent extends ViewerEvent { /** @internal */ constructor(tooltipData) { super(_HideTooltipEvent.type); this.tooltipData = tooltipData; } }; _HideTooltipEvent.type = "hide-tooltip"; var HideTooltipEvent = _HideTooltipEvent; var _KeypressEvent = class _KeypressEvent extends ViewerEvent { /** @internal */ constructor(key, originalEvent) { super(_KeypressEvent.type, true); this.key = key; this.originalEvent = originalEvent; } /** * Checks if the key events matches the given pattern */ matches(pattern) { return keyPressMatch(this.originalEvent, pattern); } }; _KeypressEvent.type = "key-press"; var KeypressEvent = _KeypressEvent; var _LoadProgressEvent = class _LoadProgressEvent extends ViewerEvent { /** @internal */ constructor(progress) { super(_LoadProgressEvent.type); this.progress = progress; } }; _LoadProgressEvent.type = "load-progress"; var LoadProgressEvent = _LoadProgressEvent; var _PanoramaLoadEvent = class _PanoramaLoadEvent extends ViewerEvent { /** @internal */ constructor(panorama) { super(_PanoramaLoadEvent.type); this.panorama = panorama; } }; _PanoramaLoadEvent.type = "panorama-load"; var PanoramaLoadEvent = _PanoramaLoadEvent; var _PanoramaLoadedEvent = class _PanoramaLoadedEvent extends ViewerEvent { /** @internal */ constructor(data) { super(_PanoramaLoadedEvent.type); this.data = data; } }; _PanoramaLoadedEvent.type = "panorama-loaded"; var PanoramaLoadedEvent = _PanoramaLoadedEvent; var _PanoramaErrorEvent = class _PanoramaErrorEvent extends ViewerEvent { /** @internal */ constructor(panorama, error) { super(_PanoramaErrorEvent.type); this.panorama = panorama; this.error = error; } }; _PanoramaErrorEvent.type = "panorama-error"; var PanoramaErrorEvent = _PanoramaErrorEvent; var _TransitionDoneEvent = class _TransitionDoneEvent extends ViewerEvent { /** @internal */ constructor(completed) { super(_TransitionDoneEvent.type); this.completed = completed; } }; _TransitionDoneE